/ Check-in [8a048423]
Login

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

Overview
Comment:Pull all the latest trunk changes over into the apple-osx branch.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | apple-osx
Files: files | file ages | folders
SHA1: 8a048423f0e409d2332558cb5148e5a1d251ae30
User & Date: drh 2012-01-03 21:54:09
Context
2012-01-14
14:13
Merge the latest trunk changes into the apple-osx branch. check-in: 2cc414cd user: drh tags: apple-osx
2012-01-03
21:54
Pull all the latest trunk changes over into the apple-osx branch. check-in: 8a048423 user: drh tags: apple-osx
14:50
Make sure filenames passed into sqlite3OsOpen() always have the extra zero-terminators needed by sqlite3_uri_parameter(). check-in: d73e93cf user: drh tags: trunk
2011-12-08
21:08
Merge the latest trunk changes into the apple-osx branch. check-in: 59e0d4f3 user: drh tags: apple-osx
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 ext/fts3/fts3_write.c.

  1382   1382     sqlite3_int64 iStartLeaf,       /* First leaf to traverse */
  1383   1383     sqlite3_int64 iEndLeaf,         /* Final leaf to traverse */
  1384   1384     sqlite3_int64 iEndBlock,        /* Final block of segment */
  1385   1385     const char *zRoot,              /* Buffer containing root node */
  1386   1386     int nRoot,                      /* Size of buffer containing root node */
  1387   1387     Fts3SegReader **ppReader        /* OUT: Allocated Fts3SegReader */
  1388   1388   ){
  1389         -  int rc = SQLITE_OK;             /* Return code */
  1390   1389     Fts3SegReader *pReader;         /* Newly allocated SegReader object */
  1391   1390     int nExtra = 0;                 /* Bytes to allocate segment root node */
  1392   1391   
  1393   1392     assert( iStartLeaf<=iEndLeaf );
  1394   1393     if( iStartLeaf==0 ){
  1395   1394       nExtra = nRoot + FTS3_NODE_PADDING;
  1396   1395     }
................................................................................
  1410   1409       pReader->aNode = (char *)&pReader[1];
  1411   1410       pReader->nNode = nRoot;
  1412   1411       memcpy(pReader->aNode, zRoot, nRoot);
  1413   1412       memset(&pReader->aNode[nRoot], 0, FTS3_NODE_PADDING);
  1414   1413     }else{
  1415   1414       pReader->iCurrentBlock = iStartLeaf-1;
  1416   1415     }
  1417         -
  1418         -  if( rc==SQLITE_OK ){
  1419         -    *ppReader = pReader;
  1420         -  }else{
  1421         -    sqlite3Fts3SegReaderFree(pReader);
  1422         -  }
  1423         -  return rc;
         1416  +  *ppReader = pReader;
         1417  +  return SQLITE_OK;
  1424   1418   }
  1425   1419   
  1426   1420   /*
  1427   1421   ** This is a comparison function used as a qsort() callback when sorting
  1428   1422   ** an array of pending terms by term. This occurs as part of flushing
  1429   1423   ** the contents of the pending-terms hash table to the database.
  1430   1424   */
................................................................................
  1466   1460     int iIndex,                     /* Index for p->aIndex */
  1467   1461     const char *zTerm,              /* Term to search for */
  1468   1462     int nTerm,                      /* Size of buffer zTerm */
  1469   1463     int bPrefix,                    /* True for a prefix iterator */
  1470   1464     Fts3SegReader **ppReader        /* OUT: SegReader for pending-terms */
  1471   1465   ){
  1472   1466     Fts3SegReader *pReader = 0;     /* Fts3SegReader object to return */
         1467  +  Fts3HashElem *pE;               /* Iterator variable */
  1473   1468     Fts3HashElem **aElem = 0;       /* Array of term hash entries to scan */
  1474   1469     int nElem = 0;                  /* Size of array at aElem */
  1475   1470     int rc = SQLITE_OK;             /* Return Code */
  1476   1471     Fts3Hash *pHash;
  1477   1472   
  1478   1473     pHash = &p->aIndex[iIndex].hPending;
  1479   1474     if( bPrefix ){
  1480   1475       int nAlloc = 0;               /* Size of allocated array at aElem */
  1481         -    Fts3HashElem *pE = 0;         /* Iterator variable */
  1482   1476   
  1483   1477       for(pE=fts3HashFirst(pHash); pE; pE=fts3HashNext(pE)){
  1484   1478         char *zKey = (char *)fts3HashKey(pE);
  1485   1479         int nKey = fts3HashKeysize(pE);
  1486   1480         if( nTerm==0 || (nKey>=nTerm && 0==memcmp(zKey, zTerm, nTerm)) ){
  1487   1481           if( nElem==nAlloc ){
  1488   1482             Fts3HashElem **aElem2;
................................................................................
  1508   1502       */
  1509   1503       if( nElem>1 ){
  1510   1504         qsort(aElem, nElem, sizeof(Fts3HashElem *), fts3CompareElemByTerm);
  1511   1505       }
  1512   1506   
  1513   1507     }else{
  1514   1508       /* The query is a simple term lookup that matches at most one term in
  1515         -    ** the index. All that is required is a straight hash-lookup. */
  1516         -    Fts3HashElem *pE = fts3HashFindElem(pHash, zTerm, nTerm);
         1509  +    ** the index. All that is required is a straight hash-lookup. 
         1510  +    **
         1511  +    ** Because the stack address of pE may be accessed via the aElem pointer
         1512  +    ** below, the "Fts3HashElem *pE" must be declared so that it is valid
         1513  +    ** within this entire function, not just this "else{...}" block.
         1514  +    */
         1515  +    pE = fts3HashFindElem(pHash, zTerm, nTerm);
  1517   1516       if( pE ){
  1518   1517         aElem = &pE;
  1519   1518         nElem = 1;
  1520   1519       }
  1521   1520     }
  1522   1521   
  1523   1522     if( nElem>0 ){

Changes to ext/rtree/rtree.c.

  1190   1190   */
  1191   1191   static int deserializeGeometry(sqlite3_value *pValue, RtreeConstraint *pCons){
  1192   1192     RtreeMatchArg *p;
  1193   1193     sqlite3_rtree_geometry *pGeom;
  1194   1194     int nBlob;
  1195   1195   
  1196   1196     /* Check that value is actually a blob. */
  1197         -  if( !sqlite3_value_type(pValue)==SQLITE_BLOB ) return SQLITE_ERROR;
         1197  +  if( sqlite3_value_type(pValue)!=SQLITE_BLOB ) return SQLITE_ERROR;
  1198   1198   
  1199   1199     /* Check that the blob is roughly the right size. */
  1200   1200     nBlob = sqlite3_value_bytes(pValue);
  1201   1201     if( nBlob<(int)sizeof(RtreeMatchArg) 
  1202   1202      || ((nBlob-sizeof(RtreeMatchArg))%sizeof(double))!=0
  1203   1203     ){
  1204   1204       return SQLITE_ERROR;

Changes to src/analyze.c.

   525    525         sqlite3OpenTable(pParse, iTabCur, iDb, pTab, OP_OpenRead);
   526    526       }
   527    527       sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regCount);
   528    528       sqlite3VdbeAddOp2(v, OP_Integer, SQLITE_STAT3_SAMPLES, regTemp1);
   529    529       sqlite3VdbeAddOp2(v, OP_Integer, 0, regNumEq);
   530    530       sqlite3VdbeAddOp2(v, OP_Integer, 0, regNumLt);
   531    531       sqlite3VdbeAddOp2(v, OP_Integer, -1, regNumDLt);
          532  +    sqlite3VdbeAddOp3(v, OP_Null, 0, regSample, regAccum);
   532    533       sqlite3VdbeAddOp4(v, OP_Function, 1, regCount, regAccum,
   533    534                         (char*)&stat3InitFuncdef, P4_FUNCDEF);
   534    535       sqlite3VdbeChangeP5(v, 2);
   535    536   #endif /* SQLITE_ENABLE_STAT3 */
   536    537   
   537    538       /* The block of memory cells initialized here is used as follows.
   538    539       **

Changes to src/backup.c.

   674    674     sqlite3BtreeEnter(pTo);
   675    675     sqlite3BtreeEnter(pFrom);
   676    676   
   677    677     assert( sqlite3BtreeIsInTrans(pTo) );
   678    678     pFd = sqlite3PagerFile(sqlite3BtreePager(pTo));
   679    679     if( pFd->pMethods ){
   680    680       i64 nByte = sqlite3BtreeGetPageSize(pFrom)*(i64)sqlite3BtreeLastPage(pFrom);
          681  +    sqlite3BeginBenignMalloc();
   681    682       sqlite3OsFileControl(pFd, SQLITE_FCNTL_OVERWRITE, &nByte);
          683  +    sqlite3EndBenignMalloc();
   682    684     }
   683    685   
   684    686     /* Set up an sqlite3_backup object. sqlite3_backup.pDestDb must be set
   685    687     ** to 0. This is used by the implementations of sqlite3_backup_step()
   686    688     ** and sqlite3_backup_finish() to detect that they are being called
   687    689     ** from this function, not directly by the user.
   688    690     */

Changes to src/btree.c.

  4002   4002            && pBt->inTransaction==TRANS_READ                     /* (4) */
  4003   4003            && (fd = sqlite3PagerFile(pBt->pPager))->pMethods     /* (3) */
  4004   4004            && pBt->pPage1->aData[19]==0x01                       /* (5) */
  4005   4005           ){
  4006   4006             u8 aSave[4];
  4007   4007             u8 *aWrite = &pBuf[-4];
  4008   4008             memcpy(aSave, aWrite, 4);
  4009         -          rc = sqlite3OsRead(fd, aWrite, a+4, pBt->pageSize * (nextPage-1));
         4009  +          rc = sqlite3OsRead(fd, aWrite, a+4, (i64)pBt->pageSize*(nextPage-1));
  4010   4010             nextPage = get4byte(aWrite);
  4011   4011             memcpy(aWrite, aSave, 4);
  4012   4012           }else
  4013   4013   #endif
  4014   4014   
  4015   4015           {
  4016   4016             DbPage *pDbPage;
................................................................................
  6226   6226       szNew[i] = szRight;
  6227   6227       szNew[i-1] = szLeft;
  6228   6228     }
  6229   6229   
  6230   6230     /* Either we found one or more cells (cntnew[0])>0) or pPage is
  6231   6231     ** a virtual root page.  A virtual root page is when the real root
  6232   6232     ** page is page 1 and we are the only child of that page.
         6233  +  **
         6234  +  ** UPDATE:  The assert() below is not necessarily true if the database
         6235  +  ** file is corrupt.  The corruption will be detected and reported later
         6236  +  ** in this procedure so there is no need to act upon it now.
  6233   6237     */
         6238  +#if 0
  6234   6239     assert( cntNew[0]>0 || (pParent->pgno==1 && pParent->nCell==0) );
         6240  +#endif
  6235   6241   
  6236   6242     TRACE(("BALANCE: old: %d %d %d  ",
  6237   6243       apOld[0]->pgno, 
  6238   6244       nOld>=2 ? apOld[1]->pgno : 0,
  6239   6245       nOld>=3 ? apOld[2]->pgno : 0
  6240   6246     ));
  6241   6247   

Changes to src/btreeInt.h.

   366    366   #define TRANS_NONE  0
   367    367   #define TRANS_READ  1
   368    368   #define TRANS_WRITE 2
   369    369   
   370    370   /*
   371    371   ** An instance of this object represents a single database file.
   372    372   ** 
   373         -** A single database file can be in use as the same time by two
          373  +** A single database file can be in use at the same time by two
   374    374   ** or more database connections.  When two or more connections are
   375    375   ** sharing the same database file, each connection has it own
   376    376   ** private Btree object for the file and each of those Btrees points
   377    377   ** to this one BtShared object.  BtShared.nRef is the number of
   378    378   ** connections currently sharing this database file.
   379    379   **
   380    380   ** Fields in this structure are accessed under the BtShared.mutex
................................................................................
   472    472   /*
   473    473   ** A cursor is a pointer to a particular entry within a particular
   474    474   ** b-tree within a database file.
   475    475   **
   476    476   ** The entry is identified by its MemPage and the index in
   477    477   ** MemPage.aCell[] of the entry.
   478    478   **
   479         -** A single database file can shared by two more database connections,
          479  +** A single database file can be shared by two more database connections,
   480    480   ** but cursors cannot be shared.  Each cursor is associated with a
   481    481   ** particular database connection identified BtCursor.pBtree.db.
   482    482   **
   483    483   ** Fields in this structure are accessed under the BtShared.mutex
   484    484   ** found at self->pBt->mutex. 
   485    485   */
   486    486   struct BtCursor {
................................................................................
   633    633     int mxErr;        /* Stop accumulating errors when this reaches zero */
   634    634     int nErr;         /* Number of messages written to zErrMsg so far */
   635    635     int mallocFailed; /* A memory allocation error has occurred */
   636    636     StrAccum errMsg;  /* Accumulate the error message text here */
   637    637   };
   638    638   
   639    639   /*
   640         -** Read or write a two- and four-byte big-endian integer values.
          640  +** Routines to read or write a two- and four-byte big-endian integer values.
   641    641   */
   642    642   #define get2byte(x)   ((x)[0]<<8 | (x)[1])
   643    643   #define put2byte(p,v) ((p)[0] = (u8)((v)>>8), (p)[1] = (u8)(v))
   644    644   #define get4byte sqlite3Get4byte
   645    645   #define put4byte sqlite3Put4byte

Changes to src/expr.c.

   866    866     for(i=0; i<p->nExpr; i++, pItem++, pOldItem++){
   867    867       Expr *pOldExpr = pOldItem->pExpr;
   868    868       pItem->pExpr = sqlite3ExprDup(db, pOldExpr, flags);
   869    869       pItem->zName = sqlite3DbStrDup(db, pOldItem->zName);
   870    870       pItem->zSpan = sqlite3DbStrDup(db, pOldItem->zSpan);
   871    871       pItem->sortOrder = pOldItem->sortOrder;
   872    872       pItem->done = 0;
   873         -    pItem->iCol = pOldItem->iCol;
          873  +    pItem->iOrderByCol = pOldItem->iOrderByCol;
   874    874       pItem->iAlias = pOldItem->iAlias;
   875    875     }
   876    876     return pNew;
   877    877   }
   878    878   
   879    879   /*
   880    880   ** If cursors, triggers, views and subqueries are all omitted from
................................................................................
  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
................................................................................
  2936   2944       sqlite3VdbeAddOp2(v, OP_Copy, inReg, iMem);
  2937   2945       pExpr->iTable = iMem;
  2938   2946       pExpr->op2 = pExpr->op;
  2939   2947       pExpr->op = TK_REGISTER;
  2940   2948     }
  2941   2949     return inReg;
  2942   2950   }
         2951  +
         2952  +#if defined(SQLITE_ENABLE_TREE_EXPLAIN)
         2953  +/*
         2954  +** Generate a human-readable explanation of an expression tree.
         2955  +*/
         2956  +void sqlite3ExplainExpr(Vdbe *pOut, Expr *pExpr){
         2957  +  int op;                   /* The opcode being coded */
         2958  +  const char *zBinOp = 0;   /* Binary operator */
         2959  +  const char *zUniOp = 0;   /* Unary operator */
         2960  +  if( pExpr==0 ){
         2961  +    op = TK_NULL;
         2962  +  }else{
         2963  +    op = pExpr->op;
         2964  +  }
         2965  +  switch( op ){
         2966  +    case TK_AGG_COLUMN: {
         2967  +      sqlite3ExplainPrintf(pOut, "AGG{%d:%d}",
         2968  +            pExpr->iTable, pExpr->iColumn);
         2969  +      break;
         2970  +    }
         2971  +    case TK_COLUMN: {
         2972  +      if( pExpr->iTable<0 ){
         2973  +        /* This only happens when coding check constraints */
         2974  +        sqlite3ExplainPrintf(pOut, "COLUMN(%d)", pExpr->iColumn);
         2975  +      }else{
         2976  +        sqlite3ExplainPrintf(pOut, "{%d:%d}",
         2977  +                             pExpr->iTable, pExpr->iColumn);
         2978  +      }
         2979  +      break;
         2980  +    }
         2981  +    case TK_INTEGER: {
         2982  +      if( pExpr->flags & EP_IntValue ){
         2983  +        sqlite3ExplainPrintf(pOut, "%d", pExpr->u.iValue);
         2984  +      }else{
         2985  +        sqlite3ExplainPrintf(pOut, "%s", pExpr->u.zToken);
         2986  +      }
         2987  +      break;
         2988  +    }
         2989  +#ifndef SQLITE_OMIT_FLOATING_POINT
         2990  +    case TK_FLOAT: {
         2991  +      sqlite3ExplainPrintf(pOut,"%s", pExpr->u.zToken);
         2992  +      break;
         2993  +    }
         2994  +#endif
         2995  +    case TK_STRING: {
         2996  +      sqlite3ExplainPrintf(pOut,"%Q", pExpr->u.zToken);
         2997  +      break;
         2998  +    }
         2999  +    case TK_NULL: {
         3000  +      sqlite3ExplainPrintf(pOut,"NULL");
         3001  +      break;
         3002  +    }
         3003  +#ifndef SQLITE_OMIT_BLOB_LITERAL
         3004  +    case TK_BLOB: {
         3005  +      sqlite3ExplainPrintf(pOut,"%s", pExpr->u.zToken);
         3006  +      break;
         3007  +    }
         3008  +#endif
         3009  +    case TK_VARIABLE: {
         3010  +      sqlite3ExplainPrintf(pOut,"VARIABLE(%s,%d)",
         3011  +                           pExpr->u.zToken, pExpr->iColumn);
         3012  +      break;
         3013  +    }
         3014  +    case TK_REGISTER: {
         3015  +      sqlite3ExplainPrintf(pOut,"REGISTER(%d)", pExpr->iTable);
         3016  +      break;
         3017  +    }
         3018  +    case TK_AS: {
         3019  +      sqlite3ExplainExpr(pOut, pExpr->pLeft);
         3020  +      break;
         3021  +    }
         3022  +#ifndef SQLITE_OMIT_CAST
         3023  +    case TK_CAST: {
         3024  +      /* Expressions of the form:   CAST(pLeft AS token) */
         3025  +      const char *zAff = "unk";
         3026  +      switch( sqlite3AffinityType(pExpr->u.zToken) ){
         3027  +        case SQLITE_AFF_TEXT:    zAff = "TEXT";     break;
         3028  +        case SQLITE_AFF_NONE:    zAff = "NONE";     break;
         3029  +        case SQLITE_AFF_NUMERIC: zAff = "NUMERIC";  break;
         3030  +        case SQLITE_AFF_INTEGER: zAff = "INTEGER";  break;
         3031  +        case SQLITE_AFF_REAL:    zAff = "REAL";     break;
         3032  +      }
         3033  +      sqlite3ExplainPrintf(pOut, "CAST-%s(", zAff);
         3034  +      sqlite3ExplainExpr(pOut, pExpr->pLeft);
         3035  +      sqlite3ExplainPrintf(pOut, ")");
         3036  +      break;
         3037  +    }
         3038  +#endif /* SQLITE_OMIT_CAST */
         3039  +    case TK_LT:      zBinOp = "LT";     break;
         3040  +    case TK_LE:      zBinOp = "LE";     break;
         3041  +    case TK_GT:      zBinOp = "GT";     break;
         3042  +    case TK_GE:      zBinOp = "GE";     break;
         3043  +    case TK_NE:      zBinOp = "NE";     break;
         3044  +    case TK_EQ:      zBinOp = "EQ";     break;
         3045  +    case TK_IS:      zBinOp = "IS";     break;
         3046  +    case TK_ISNOT:   zBinOp = "ISNOT";  break;
         3047  +    case TK_AND:     zBinOp = "AND";    break;
         3048  +    case TK_OR:      zBinOp = "OR";     break;
         3049  +    case TK_PLUS:    zBinOp = "ADD";    break;
         3050  +    case TK_STAR:    zBinOp = "MUL";    break;
         3051  +    case TK_MINUS:   zBinOp = "SUB";    break;
         3052  +    case TK_REM:     zBinOp = "REM";    break;
         3053  +    case TK_BITAND:  zBinOp = "BITAND"; break;
         3054  +    case TK_BITOR:   zBinOp = "BITOR";  break;
         3055  +    case TK_SLASH:   zBinOp = "DIV";    break;
         3056  +    case TK_LSHIFT:  zBinOp = "LSHIFT"; break;
         3057  +    case TK_RSHIFT:  zBinOp = "RSHIFT"; break;
         3058  +    case TK_CONCAT:  zBinOp = "CONCAT"; break;
         3059  +
         3060  +    case TK_UMINUS:  zUniOp = "UMINUS"; break;
         3061  +    case TK_UPLUS:   zUniOp = "UPLUS";  break;
         3062  +    case TK_BITNOT:  zUniOp = "BITNOT"; break;
         3063  +    case TK_NOT:     zUniOp = "NOT";    break;
         3064  +    case TK_ISNULL:  zUniOp = "ISNULL"; break;
         3065  +    case TK_NOTNULL: zUniOp = "NOTNULL"; break;
         3066  +
         3067  +    case TK_AGG_FUNCTION:
         3068  +    case TK_CONST_FUNC:
         3069  +    case TK_FUNCTION: {
         3070  +      ExprList *pFarg;       /* List of function arguments */
         3071  +      if( ExprHasAnyProperty(pExpr, EP_TokenOnly) ){
         3072  +        pFarg = 0;
         3073  +      }else{
         3074  +        pFarg = pExpr->x.pList;
         3075  +      }
         3076  +      sqlite3ExplainPrintf(pOut, "%sFUNCTION:%s(",
         3077  +                           op==TK_AGG_FUNCTION ? "AGG_" : "",
         3078  +                           pExpr->u.zToken);
         3079  +      if( pFarg ){
         3080  +        sqlite3ExplainExprList(pOut, pFarg);
         3081  +      }
         3082  +      sqlite3ExplainPrintf(pOut, ")");
         3083  +      break;
         3084  +    }
         3085  +#ifndef SQLITE_OMIT_SUBQUERY
         3086  +    case TK_EXISTS: {
         3087  +      sqlite3ExplainPrintf(pOut, "EXISTS(");
         3088  +      sqlite3ExplainSelect(pOut, pExpr->x.pSelect);
         3089  +      sqlite3ExplainPrintf(pOut,")");
         3090  +      break;
         3091  +    }
         3092  +    case TK_SELECT: {
         3093  +      sqlite3ExplainPrintf(pOut, "(");
         3094  +      sqlite3ExplainSelect(pOut, pExpr->x.pSelect);
         3095  +      sqlite3ExplainPrintf(pOut, ")");
         3096  +      break;
         3097  +    }
         3098  +    case TK_IN: {
         3099  +      sqlite3ExplainPrintf(pOut, "IN(");
         3100  +      sqlite3ExplainExpr(pOut, pExpr->pLeft);
         3101  +      sqlite3ExplainPrintf(pOut, ",");
         3102  +      if( ExprHasProperty(pExpr, EP_xIsSelect) ){
         3103  +        sqlite3ExplainSelect(pOut, pExpr->x.pSelect);
         3104  +      }else{
         3105  +        sqlite3ExplainExprList(pOut, pExpr->x.pList);
         3106  +      }
         3107  +      sqlite3ExplainPrintf(pOut, ")");
         3108  +      break;
         3109  +    }
         3110  +#endif /* SQLITE_OMIT_SUBQUERY */
         3111  +
         3112  +    /*
         3113  +    **    x BETWEEN y AND z
         3114  +    **
         3115  +    ** This is equivalent to
         3116  +    **
         3117  +    **    x>=y AND x<=z
         3118  +    **
         3119  +    ** X is stored in pExpr->pLeft.
         3120  +    ** Y is stored in pExpr->pList->a[0].pExpr.
         3121  +    ** Z is stored in pExpr->pList->a[1].pExpr.
         3122  +    */
         3123  +    case TK_BETWEEN: {
         3124  +      Expr *pX = pExpr->pLeft;
         3125  +      Expr *pY = pExpr->x.pList->a[0].pExpr;
         3126  +      Expr *pZ = pExpr->x.pList->a[1].pExpr;
         3127  +      sqlite3ExplainPrintf(pOut, "BETWEEN(");
         3128  +      sqlite3ExplainExpr(pOut, pX);
         3129  +      sqlite3ExplainPrintf(pOut, ",");
         3130  +      sqlite3ExplainExpr(pOut, pY);
         3131  +      sqlite3ExplainPrintf(pOut, ",");
         3132  +      sqlite3ExplainExpr(pOut, pZ);
         3133  +      sqlite3ExplainPrintf(pOut, ")");
         3134  +      break;
         3135  +    }
         3136  +    case TK_TRIGGER: {
         3137  +      /* If the opcode is TK_TRIGGER, then the expression is a reference
         3138  +      ** to a column in the new.* or old.* pseudo-tables available to
         3139  +      ** trigger programs. In this case Expr.iTable is set to 1 for the
         3140  +      ** new.* pseudo-table, or 0 for the old.* pseudo-table. Expr.iColumn
         3141  +      ** is set to the column of the pseudo-table to read, or to -1 to
         3142  +      ** read the rowid field.
         3143  +      */
         3144  +      sqlite3ExplainPrintf(pOut, "%s(%d)", 
         3145  +          pExpr->iTable ? "NEW" : "OLD", pExpr->iColumn);
         3146  +      break;
         3147  +    }
         3148  +    case TK_CASE: {
         3149  +      sqlite3ExplainPrintf(pOut, "CASE(");
         3150  +      sqlite3ExplainExpr(pOut, pExpr->pLeft);
         3151  +      sqlite3ExplainPrintf(pOut, ",");
         3152  +      sqlite3ExplainExprList(pOut, pExpr->x.pList);
         3153  +      break;
         3154  +    }
         3155  +#ifndef SQLITE_OMIT_TRIGGER
         3156  +    case TK_RAISE: {
         3157  +      const char *zType = "unk";
         3158  +      switch( pExpr->affinity ){
         3159  +        case OE_Rollback:   zType = "rollback";  break;
         3160  +        case OE_Abort:      zType = "abort";     break;
         3161  +        case OE_Fail:       zType = "fail";      break;
         3162  +        case OE_Ignore:     zType = "ignore";    break;
         3163  +      }
         3164  +      sqlite3ExplainPrintf(pOut, "RAISE-%s(%s)", zType, pExpr->u.zToken);
         3165  +      break;
         3166  +    }
         3167  +#endif
         3168  +  }
         3169  +  if( zBinOp ){
         3170  +    sqlite3ExplainPrintf(pOut,"%s(", zBinOp);
         3171  +    sqlite3ExplainExpr(pOut, pExpr->pLeft);
         3172  +    sqlite3ExplainPrintf(pOut,",");
         3173  +    sqlite3ExplainExpr(pOut, pExpr->pRight);
         3174  +    sqlite3ExplainPrintf(pOut,")");
         3175  +  }else if( zUniOp ){
         3176  +    sqlite3ExplainPrintf(pOut,"%s(", zUniOp);
         3177  +    sqlite3ExplainExpr(pOut, pExpr->pLeft);
         3178  +    sqlite3ExplainPrintf(pOut,")");
         3179  +  }
         3180  +}
         3181  +#endif /* defined(SQLITE_ENABLE_TREE_EXPLAIN) */
         3182  +
         3183  +#if defined(SQLITE_ENABLE_TREE_EXPLAIN)
         3184  +/*
         3185  +** Generate a human-readable explanation of an expression list.
         3186  +*/
         3187  +void sqlite3ExplainExprList(Vdbe *pOut, ExprList *pList){
         3188  +  int i;
         3189  +  if( pList==0 || pList->nExpr==0 ){
         3190  +    sqlite3ExplainPrintf(pOut, "(empty-list)");
         3191  +    return;
         3192  +  }else if( pList->nExpr==1 ){
         3193  +    sqlite3ExplainExpr(pOut, pList->a[0].pExpr);
         3194  +  }else{
         3195  +    sqlite3ExplainPush(pOut);
         3196  +    for(i=0; i<pList->nExpr; i++){
         3197  +      sqlite3ExplainPrintf(pOut, "item[%d] = ", i);
         3198  +      sqlite3ExplainPush(pOut);
         3199  +      sqlite3ExplainExpr(pOut, pList->a[i].pExpr);
         3200  +      sqlite3ExplainPop(pOut);
         3201  +      if( i<pList->nExpr-1 ){
         3202  +        sqlite3ExplainNL(pOut);
         3203  +      }
         3204  +    }
         3205  +    sqlite3ExplainPop(pOut);
         3206  +  }
         3207  +}
         3208  +#endif /* SQLITE_DEBUG */
  2943   3209   
  2944   3210   /*
  2945   3211   ** Return TRUE if pExpr is an constant expression that is appropriate
  2946   3212   ** for factoring out of a loop.  Appropriate expressions are:
  2947   3213   **
  2948   3214   **    *  Any expression that evaluates to two or more opcodes.
  2949   3215   **

Changes to src/global.c.

   143    143      SQLITE_THREADSAFE==1,      /* bFullMutex */
   144    144      SQLITE_USE_URI,            /* bOpenUri */
   145    145      0x7ffffffe,                /* mxStrlen */
   146    146      128,                       /* szLookaside */
   147    147      500,                       /* nLookaside */
   148    148      {0,0,0,0,0,0,0,0},         /* m */
   149    149      {0,0,0,0,0,0,0,0,0},       /* mutex */
   150         -   {0,0,0,0,0,0,0,0,0,0,0},   /* pcache2 */
          150  +   {0,0,0,0,0,0,0,0,0,0,0,0,0},/* pcache2 */
   151    151      (void*)0,                  /* pHeap */
   152    152      0,                         /* nHeap */
   153    153      0, 0,                      /* mnHeap, mxHeap */
   154    154      (void*)0,                  /* pScratch */
   155    155      0,                         /* szScratch */
   156    156      0,                         /* nScratch */
   157    157      (void*)0,                  /* pPage */

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/loadext.c.

   621    621   ** Load all automatic extensions.
   622    622   **
   623    623   ** If anything goes wrong, set an error in the database connection.
   624    624   */
   625    625   void sqlite3AutoLoadExtensions(sqlite3 *db){
   626    626     int i;
   627    627     int go = 1;
          628  +  int rc;
   628    629     int (*xInit)(sqlite3*,char**,const sqlite3_api_routines*);
   629    630   
   630    631     wsdAutoextInit;
   631    632     if( wsdAutoext.nExt==0 ){
   632    633       /* Common case: early out without every having to acquire a mutex */
   633    634       return;
   634    635     }
................................................................................
   643    644         go = 0;
   644    645       }else{
   645    646         xInit = (int(*)(sqlite3*,char**,const sqlite3_api_routines*))
   646    647                 wsdAutoext.aExt[i];
   647    648       }
   648    649       sqlite3_mutex_leave(mutex);
   649    650       zErrmsg = 0;
   650         -    if( xInit && xInit(db, &zErrmsg, &sqlite3Apis) ){
   651         -      sqlite3Error(db, SQLITE_ERROR,
          651  +    if( xInit && (rc = xInit(db, &zErrmsg, &sqlite3Apis))!=0 ){
          652  +      sqlite3Error(db, rc,
   652    653               "automatic extension loading failed: %s", zErrmsg);
   653    654         go = 0;
   654    655       }
   655    656       sqlite3_free(zErrmsg);
   656    657     }
   657    658   }

Changes to src/main.c.

    48     48   const char *sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; }
    49     49   
    50     50   /* IMPLEMENTATION-OF: R-35210-63508 The sqlite3_libversion_number() function
    51     51   ** returns an integer equal to SQLITE_VERSION_NUMBER.
    52     52   */
    53     53   int sqlite3_libversion_number(void){ return SQLITE_VERSION_NUMBER; }
    54     54   
    55         -/* IMPLEMENTATION-OF: R-54823-41343 The sqlite3_threadsafe() function returns
    56         -** zero if and only if SQLite was compiled mutexing code omitted due to
           55  +/* IMPLEMENTATION-OF: R-20790-14025 The sqlite3_threadsafe() function returns
           56  +** zero if and only if SQLite was compiled with mutexing code omitted due to
    57     57   ** the SQLITE_THREADSAFE compile-time option being set to 0.
    58     58   */
    59     59   int sqlite3_threadsafe(void){ return SQLITE_THREADSAFE; }
    60     60   
    61     61   #if !defined(SQLITE_OMIT_TRACE) && defined(SQLITE_ENABLE_IOTRACE)
    62     62   /*
    63     63   ** If the following function pointer is not NULL and if
................................................................................
   238    238   #endif
   239    239   
   240    240     /* Do extra initialization steps requested by the SQLITE_EXTRA_INIT
   241    241     ** compile-time option.
   242    242     */
   243    243   #ifdef SQLITE_EXTRA_INIT
   244    244     if( rc==SQLITE_OK && sqlite3GlobalConfig.isInit ){
   245         -    int SQLITE_EXTRA_INIT(void);
   246         -    rc = SQLITE_EXTRA_INIT();
          245  +    int SQLITE_EXTRA_INIT(const char*);
          246  +    rc = SQLITE_EXTRA_INIT(0);
   247    247     }
   248    248   #endif
   249    249   
   250    250     return rc;
   251    251   }
   252    252   
   253    253   /*
................................................................................
   256    256   ** while any part of SQLite is otherwise in use in any thread.  This
   257    257   ** routine is not threadsafe.  But it is safe to invoke this routine
   258    258   ** on when SQLite is already shut down.  If SQLite is already shut down
   259    259   ** when this routine is invoked, then this routine is a harmless no-op.
   260    260   */
   261    261   int sqlite3_shutdown(void){
   262    262     if( sqlite3GlobalConfig.isInit ){
          263  +#ifdef SQLITE_EXTRA_SHUTDOWN
          264  +    void SQLITE_EXTRA_SHUTDOWN(void);
          265  +    SQLITE_EXTRA_SHUTDOWN();
          266  +#endif
   263    267       sqlite3_os_end();
   264    268       sqlite3_reset_auto_extension();
   265    269       sqlite3GlobalConfig.isInit = 0;
   266    270     }
   267    271     if( sqlite3GlobalConfig.isPCacheInit ){
   268    272       sqlite3PcacheShutdown();
   269    273       sqlite3GlobalConfig.isPCacheInit = 0;
................................................................................
   535    539   
   536    540   /*
   537    541   ** Free up as much memory as we can from the given database
   538    542   ** connection.
   539    543   */
   540    544   int sqlite3_db_release_memory(sqlite3 *db){
   541    545     int i;
          546  +  sqlite3_mutex_enter(db->mutex);
   542    547     sqlite3BtreeEnterAll(db);
   543    548     for(i=0; i<db->nDb; i++){
   544    549       Btree *pBt = db->aDb[i].pBt;
   545    550       if( pBt ){
   546    551         Pager *pPager = sqlite3BtreePager(pBt);
   547    552         sqlite3PagerShrink(pPager);
   548    553       }
   549    554     }
   550    555     sqlite3BtreeLeaveAll(db);
          556  +  sqlite3_mutex_leave(db->mutex);
   551    557     return SQLITE_OK;
   552    558   }
   553    559   
   554    560   /*
   555    561   ** Configuration settings for an individual database connection
   556    562   */
   557    563   int sqlite3_db_config(sqlite3 *db, int op, ...){
................................................................................
  2256   2262     */
  2257   2263     sqlite3Error(db, SQLITE_OK, 0);
  2258   2264     sqlite3RegisterBuiltinFunctions(db);
  2259   2265   
  2260   2266     /* Load automatic extensions - extensions that have been registered
  2261   2267     ** using the sqlite3_automatic_extension() API.
  2262   2268     */
  2263         -  sqlite3AutoLoadExtensions(db);
  2264   2269     rc = sqlite3_errcode(db);
  2265         -  if( rc!=SQLITE_OK ){
  2266         -    goto opendb_out;
         2270  +  if( rc==SQLITE_OK ){
         2271  +    sqlite3AutoLoadExtensions(db);
         2272  +    rc = sqlite3_errcode(db);
         2273  +    if( rc!=SQLITE_OK ){
         2274  +      goto opendb_out;
         2275  +    }
  2267   2276     }
  2268   2277   
  2269   2278   #ifdef SQLITE_ENABLE_FTS1
  2270   2279     if( !db->mallocFailed ){
  2271   2280       extern int sqlite3Fts1Init(sqlite3*);
  2272   2281       rc = sqlite3Fts1Init(db);
  2273   2282     }
................................................................................
  2969   2978       ** undo this setting.
  2970   2979       */
  2971   2980       case SQLITE_TESTCTRL_LOCALTIME_FAULT: {
  2972   2981         sqlite3GlobalConfig.bLocaltimeFault = va_arg(ap, int);
  2973   2982         break;
  2974   2983       }
  2975   2984   
         2985  +#if defined(SQLITE_ENABLE_TREE_EXPLAIN)
         2986  +    /*   sqlite3_test_control(SQLITE_TESTCTRL_EXPLAIN_STMT,
         2987  +    **                        sqlite3_stmt*,const char**);
         2988  +    **
         2989  +    ** If compiled with SQLITE_ENABLE_TREE_EXPLAIN, each sqlite3_stmt holds
         2990  +    ** a string that describes the optimized parse tree.  This test-control
         2991  +    ** returns a pointer to that string.
         2992  +    */
         2993  +    case SQLITE_TESTCTRL_EXPLAIN_STMT: {
         2994  +      sqlite3_stmt *pStmt = va_arg(ap, sqlite3_stmt*);
         2995  +      const char **pzRet = va_arg(ap, const char**);
         2996  +      *pzRet = sqlite3VdbeExplanation((Vdbe*)pStmt);
         2997  +      break;
         2998  +    }
         2999  +#endif
         3000  +
  2976   3001     }
  2977   3002     va_end(ap);
  2978   3003   #endif /* SQLITE_OMIT_BUILTIN_TEST */
  2979   3004     return rc;
  2980   3005   }
  2981   3006   
  2982   3007   /*
................................................................................
  2987   3012   ** The zFilename argument is the filename pointer passed into the xOpen()
  2988   3013   ** method of a VFS implementation.  The zParam argument is the name of the
  2989   3014   ** query parameter we seek.  This routine returns the value of the zParam
  2990   3015   ** parameter if it exists.  If the parameter does not exist, this routine
  2991   3016   ** returns a NULL pointer.
  2992   3017   */
  2993   3018   const char *sqlite3_uri_parameter(const char *zFilename, const char *zParam){
         3019  +  if( zFilename==0 ) return 0;
  2994   3020     zFilename += sqlite3Strlen30(zFilename) + 1;
  2995   3021     while( zFilename[0] ){
  2996   3022       int x = strcmp(zFilename, zParam);
  2997   3023       zFilename += sqlite3Strlen30(zFilename) + 1;
  2998   3024       if( x==0 ) return zFilename;
  2999   3025       zFilename += sqlite3Strlen30(zFilename) + 1;
  3000   3026     }
  3001   3027     return 0;
  3002   3028   }
         3029  +
         3030  +/*
         3031  +** Return a boolean value for a query parameter.
         3032  +*/
         3033  +int sqlite3_uri_boolean(const char *zFilename, const char *zParam, int bDflt){
         3034  +  const char *z = sqlite3_uri_parameter(zFilename, zParam);
         3035  +  return z ? sqlite3GetBoolean(z) : (bDflt!=0);
         3036  +}
         3037  +
         3038  +/*
         3039  +** Return a 64-bit integer value for a query parameter.
         3040  +*/
         3041  +sqlite3_int64 sqlite3_uri_int64(
         3042  +  const char *zFilename,    /* Filename as passed to xOpen */
         3043  +  const char *zParam,       /* URI parameter sought */
         3044  +  sqlite3_int64 bDflt       /* return if parameter is missing */
         3045  +){
         3046  +  const char *z = sqlite3_uri_parameter(zFilename, zParam);
         3047  +  sqlite3_int64 v;
         3048  +  if( z && sqlite3Atoi64(z, &v, sqlite3Strlen30(z), SQLITE_UTF8)==SQLITE_OK ){
         3049  +    bDflt = v;
         3050  +  }
         3051  +  return bDflt;
         3052  +}
  3003   3053   
  3004   3054   /*
  3005   3055   ** Return the filename of the database associated with a database
  3006   3056   ** connection.
  3007   3057   */
  3008   3058   const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName){
  3009   3059     int i;

Changes to src/malloc.c.

   126    126   ** Set the soft heap-size limit for the library. Passing a zero or 
   127    127   ** negative value indicates no limit.
   128    128   */
   129    129   sqlite3_int64 sqlite3_soft_heap_limit64(sqlite3_int64 n){
   130    130     sqlite3_int64 priorLimit;
   131    131     sqlite3_int64 excess;
   132    132   #ifndef SQLITE_OMIT_AUTOINIT
   133         -  sqlite3_initialize();
          133  +  int rc = sqlite3_initialize();
          134  +  if( rc ) return -1;
   134    135   #endif
   135    136     sqlite3_mutex_enter(mem0.mutex);
   136    137     priorLimit = mem0.alarmThreshold;
   137    138     sqlite3_mutex_leave(mem0.mutex);
   138    139     if( n<0 ) return priorLimit;
   139    140     if( n>0 ){
   140    141       sqlite3MemoryAlarm(softHeapLimitEnforcer, 0, n);

Changes to src/mem1.c.

    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     29   #if (!defined(__APPLE__))
    30     30   
           31  +/*
           32  +** Windows systems have malloc_usable_size() but it is called _msize()
           33  +*/
           34  +#if !defined(HAVE_MALLOC_USABLE_SIZE) && SQLITE_OS_WIN
           35  +# define HAVE_MALLOC_USABLE_SIZE 1
           36  +# define malloc_usable_size _msize
           37  +#endif
           38  +
    31     39   #define SQLITE_MALLOC(x) malloc(x)
    32     40   #define SQLITE_FREE(x) free(x)
    33     41   #define SQLITE_REALLOC(x,y) realloc((x),(y))
    34     42   
    35     43   #else
    36     44   
    37     45   

Changes to src/os.c.

   138    138     sqlite3_file *pFile, 
   139    139     int flags, 
   140    140     int *pFlagsOut
   141    141   ){
   142    142     int rc;
   143    143     int openFlags;
   144    144     DO_OS_MALLOC_TEST(0);
   145         -  /* 0x87f3f is a mask of SQLITE_OPEN_ flags that are valid to be passed
          145  +  /* 0x87f7f is a mask of SQLITE_OPEN_ flags that are valid to be passed
   146    146     ** down into the VFS layer.  Some SQLITE_OPEN_ flags (for example,
   147    147     ** SQLITE_OPEN_FULLMUTEX or SQLITE_OPEN_SHAREDCACHE) are blocked before
   148    148     ** reaching the VFS. */
   149    149   #if SQLITE_ENABLE_DATA_PROTECTION
   150    150     openFlags = flags & (0x87f7f | SQLITE_OPEN_FILEPROTECTION_MASK);
   151    151   #else
   152    152     openFlags = flags & 0x87f7f;

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 Windows NT.
    70         -*/
    71         -#if defined(_WIN32_WINNT)
    72         -# define SQLITE_OS_WINNT 1
    73         -#else
    74         -# define SQLITE_OS_WINNT 0
    75         -#endif
    76         -
    77         -/*
    78         -** Determine if we are dealing with WindowsCE - which has a much
    79         -** reduced API.
    80         -*/
    81         -#if defined(_WIN32_WCE)
    82         -# define SQLITE_OS_WINCE 1
    83         -#else
    84         -# define SQLITE_OS_WINCE 0
    85         -#endif
    86         -
    87     67   
    88     68   /*
    89     69   ** Define the maximum size of a temporary filename
    90     70   */
    91     71   #if SQLITE_OS_WIN
    92     72   # include <windows.h>
    93     73   # define SQLITE_TEMPNAME_SIZE (MAX_PATH+50)
................................................................................
   105     85   # include <os2.h>
   106     86   # include <uconv.h>
   107     87   # define SQLITE_TEMPNAME_SIZE (CCHMAXPATHCOMP)
   108     88   #else
   109     89   # define SQLITE_TEMPNAME_SIZE 200
   110     90   #endif
   111     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  +
   112    111   /* If the SET_FULLSYNC macro is not defined above, then make it
   113    112   ** a no-op
   114    113   */
   115    114   #ifndef SET_FULLSYNC
   116    115   # define SET_FULLSYNC(x,y)
   117    116   #endif
   118    117   
   119    118   /*
   120    119   ** The default size of a disk sector
   121    120   */
   122    121   #ifndef SQLITE_DEFAULT_SECTOR_SIZE
   123         -# define SQLITE_DEFAULT_SECTOR_SIZE 512
          122  +# define SQLITE_DEFAULT_SECTOR_SIZE 4096
   124    123   #endif
   125    124   
   126    125   /*
   127    126   ** Temporary files are named starting with this prefix followed by 16 random
   128    127   ** alphanumeric characters, and no file extension. They are stored in the
   129    128   ** OS's standard temporary file directory, and are deleted prior to exit.
   130    129   ** If sqlite is being embedded in another program, you may wish to change the

Changes to src/os_unix.c.

   121    121   #include <unistd.h>
   122    122   #include <time.h>
   123    123   #include <sys/time.h>
   124    124   #include <errno.h>
   125    125   #ifndef SQLITE_OMIT_WAL
   126    126   #include <sys/mman.h>
   127    127   #endif
          128  +
   128    129   
   129    130   #if SQLITE_ENABLE_LOCKING_STYLE
   130    131   # include <sys/ioctl.h>
   131    132   # include <uuid/uuid.h>
   132    133   # if defined(__APPLE__) && ((__MAC_OS_X_VERSION_MIN_REQUIRED > 1050) || \
   133    134                               (__IPHONE_OS_VERSION_MIN_REQUIRED > 2000))
   134    135   #  define HAVE_GETHOSTUUID 1
................................................................................
   210    211   /*
   211    212   ** The unixFile structure is subclass of sqlite3_file specific to the unix
   212    213   ** VFS implementations.
   213    214   */
   214    215   typedef struct unixFile unixFile;
   215    216   struct unixFile {
   216    217     sqlite3_io_methods const *pMethod;  /* Always the first entry */
          218  +  sqlite3_vfs *pVfs;                  /* The VFS that created this unixFile */
   217    219     unixInodeInfo *pInode;              /* Info about locks on this inode */
   218    220     int h;                              /* The file descriptor */
   219    221     unsigned char eFileLock;            /* The type of lock held on this fd */
   220    222     unsigned char ctrlFlags;            /* Behavioral bits.  UNIXFILE_* flags */
   221    223     int lastErrno;                      /* The unix errno from last I/O error */
   222    224     void *lockingContext;               /* Locking style specific state */
   223    225     UnixUnusedFd *pUnused;              /* Pre-allocated UnixUnusedFd */
................................................................................
   264    266   #define UNIXFILE_RDONLY      0x02     /* Connection is read only */
   265    267   #define UNIXFILE_PERSIST_WAL 0x04     /* Persistent WAL mode */
   266    268   #ifndef SQLITE_DISABLE_DIRSYNC
   267    269   # define UNIXFILE_DIRSYNC    0x08     /* Directory sync needed */
   268    270   #else
   269    271   # define UNIXFILE_DIRSYNC    0x00
   270    272   #endif
          273  +#define UNIXFILE_PSOW        0x10     /* SQLITE_IOCAP_POWERSAFE_OVERWRITE */
   271    274   
   272    275   /*
   273    276   ** Include code that is common to all os_*.c files
   274    277   */
   275    278   #include "os_common.h"
   276    279   
   277    280   /*
................................................................................
  2371   2374     }
  2372   2375     
  2373   2376     /* To fully unlock the database, delete the lock file */
  2374   2377     assert( eFileLock==NO_LOCK );
  2375   2378     rc = osRmdir(zLockFile);
  2376   2379     if( rc<0 && errno==ENOTDIR ) rc = osUnlink(zLockFile);
  2377   2380     if( rc<0 ){
  2378         -    int rc = 0;
  2379   2381       int tErrno = errno;
         2382  +    rc = 0;
  2380   2383       if( ENOENT != tErrno ){
  2381   2384   #if OSLOCKING_CHECK_BUSY_IOERR
  2382   2385         rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_UNLOCK);
  2383   2386   #else
  2384   2387         rc = SQLITE_IOERR_UNLOCK;
  2385   2388   #endif
  2386   2389       }
................................................................................
  4303   4306       *pLockstate = SQLITE_LOCKSTATE_OFF;
  4304   4307     }
  4305   4308     return SQLITE_OK;
  4306   4309   }
  4307   4310   
  4308   4311   #endif /* (SQLITE_ENABLE_APPLE_SPI>0) && defined(__APPLE__) */
  4309   4312   
         4313  +
         4314  +/*
         4315  +** If *pArg is inititially negative then this is a query.  Set *pArg to
         4316  +** 1 or 0 depending on whether or not bit mask of pFile->ctrlFlags is set.
         4317  +**
         4318  +** If *pArg is 0 or 1, then clear or set the mask bit of pFile->ctrlFlags.
         4319  +*/
         4320  +static void unixModeBit(unixFile *pFile, unsigned char mask, int *pArg){
         4321  +  if( *pArg<0 ){
         4322  +    *pArg = (pFile->ctrlFlags & mask)!=0;
         4323  +  }else if( (*pArg)==0 ){
         4324  +    pFile->ctrlFlags &= ~mask;
         4325  +  }else{
         4326  +    pFile->ctrlFlags |= mask;
         4327  +  }
         4328  +}
  4310   4329   
  4311   4330   /*
  4312   4331   ** Information and control of an open file handle.
  4313   4332   */
  4314   4333   static int unixFileControl(sqlite3_file *id, int op, void *pArg){
  4315   4334     unixFile *pFile = (unixFile*)id;
  4316   4335     switch( op ){
................................................................................
  4330   4349         int rc;
  4331   4350         SimulateIOErrorBenign(1);
  4332   4351         rc = fcntlSizeHint(pFile, *(i64 *)pArg);
  4333   4352         SimulateIOErrorBenign(0);
  4334   4353         return rc;
  4335   4354       }
  4336   4355       case SQLITE_FCNTL_PERSIST_WAL: {
  4337         -      int bPersist = *(int*)pArg;
  4338         -      if( bPersist<0 ){
  4339         -        *(int*)pArg = (pFile->ctrlFlags & UNIXFILE_PERSIST_WAL)!=0;
  4340         -      }else if( bPersist==0 ){
  4341         -        pFile->ctrlFlags &= ~UNIXFILE_PERSIST_WAL;
  4342         -      }else{
  4343         -        pFile->ctrlFlags |= UNIXFILE_PERSIST_WAL;
  4344         -      }
         4356  +      unixModeBit(pFile, UNIXFILE_PERSIST_WAL, (int*)pArg);
         4357  +      return SQLITE_OK;
         4358  +    }
         4359  +    case SQLITE_FCNTL_POWERSAFE_OVERWRITE: {
         4360  +      unixModeBit(pFile, UNIXFILE_PSOW, (int*)pArg);
         4361  +      return SQLITE_OK;
         4362  +    }
         4363  +    case SQLITE_FCNTL_VFSNAME: {
         4364  +      *(char**)pArg = sqlite3_mprintf("%s", pFile->pVfs->zName);
  4345   4365         return SQLITE_OK;
  4346   4366       }
  4347   4367   #ifndef NDEBUG
  4348   4368       /* The pager calls this method to signal that it has done
  4349   4369       ** a rollback and that the database is therefore unchanged and
  4350   4370       ** it hence it is OK for the transaction change counter to be
  4351   4371       ** unchanged.
................................................................................
  4394   4414   ** larger for some devices.
  4395   4415   **
  4396   4416   ** SQLite code assumes this function cannot fail. It also assumes that
  4397   4417   ** if two files are created in the same file-system directory (i.e.
  4398   4418   ** a database and its journal file) that the sector size will be the
  4399   4419   ** same for both.
  4400   4420   */
  4401         -static int unixSectorSize(sqlite3_file *NotUsed){
  4402         -  UNUSED_PARAMETER(NotUsed);
         4421  +static int unixSectorSize(sqlite3_file *pFile){
         4422  +  (void)pFile;
  4403   4423     return SQLITE_DEFAULT_SECTOR_SIZE;
  4404   4424   }
  4405   4425   
  4406   4426   /*
  4407         -** Return the device characteristics for the file. This is always 0 for unix.
         4427  +** Return the device characteristics for the file.
         4428  +**
         4429  +** This VFS is set up to return SQLITE_IOCAP_POWERSAFE_OVERWRITE by default.
         4430  +** However, that choice is contraversial since technically the underlying
         4431  +** file system does not always provide powersafe overwrites.  (In other
         4432  +** words, after a power-loss event, parts of the file that were never
         4433  +** written might end up being altered.)  However, non-PSOW behavior is very,
         4434  +** very rare.  And asserting PSOW makes a large reduction in the amount
         4435  +** of required I/O for journaling, since a lot of padding is eliminated.
         4436  +**  Hence, while POWERSAFE_OVERWRITE is on by default, there is a file-control
         4437  +** available to turn it off and URI query parameter available to turn it off.
  4408   4438   */
  4409         -static int unixDeviceCharacteristics(sqlite3_file *NotUsed){
  4410         -  UNUSED_PARAMETER(NotUsed);
  4411         -  return 0;
         4439  +static int unixDeviceCharacteristics(sqlite3_file *id){
         4440  +  unixFile *p = (unixFile*)id;
         4441  +  if( p->ctrlFlags & UNIXFILE_PSOW ){
         4442  +    return SQLITE_IOCAP_POWERSAFE_OVERWRITE;
         4443  +  }else{
         4444  +    return 0;
         4445  +  }
  4412   4446   }
  4413   4447   
  4414   4448   #ifndef SQLITE_OMIT_WAL
  4415   4449   
  4416   4450   
  4417   4451   /*
  4418   4452   ** Object used to represent an shared memory buffer.  
................................................................................
  4675   4709           rc = SQLITE_CANTOPEN_BKPT;
  4676   4710           goto shm_open_err;
  4677   4711         }
  4678   4712       }
  4679   4713   #endif
  4680   4714       
  4681   4715   #ifdef SQLITE_SHM_DIRECTORY
  4682         -    nShmFilename = sizeof(SQLITE_SHM_DIRECTORY) + 30;
         4716  +    nShmFilename = sizeof(SQLITE_SHM_DIRECTORY) + 31;
  4683   4717   #else
  4684         -    nShmFilename = 5 + (int)strlen(zBasePath);
         4718  +    nShmFilename = 6 + (int)strlen(zBasePath);
  4685   4719   #endif
  4686   4720       pShmNode = sqlite3_malloc( sizeof(*pShmNode) + nShmFilename );
  4687   4721       if( pShmNode==0 ){
  4688   4722         rc = SQLITE_NOMEM;
  4689   4723         goto shm_open_err;
  4690   4724       }
  4691   4725       memset(pShmNode, 0, sizeof(*pShmNode));
................................................................................
  4704   4738       pShmNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
  4705   4739       if( pShmNode->mutex==0 ){
  4706   4740         rc = SQLITE_NOMEM;
  4707   4741         goto shm_open_err;
  4708   4742       }
  4709   4743   
  4710   4744       if( pInode->bProcessLock==0 ){
  4711         -      const char *zRO;
  4712   4745         int openFlags = O_RDWR | O_CREAT;
  4713         -      zRO = sqlite3_uri_parameter(pDbFd->zPath, "readonly_shm");
  4714         -      if( zRO && sqlite3GetBoolean(zRO) ){
         4746  +      if( sqlite3_uri_boolean(pDbFd->zPath, "readonly_shm", 0) ){
  4715   4747           openFlags = O_RDONLY;
  4716   4748           pShmNode->isReadonly = 1;
  4717   4749         }
  4718   4750         pShmNode->h = robust_open(zShmFilename, openFlags, (sStat.st_mode&0777));
  4719   4751         if( pShmNode->h<0 ){
  4720   4752           rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zShmFilename);
  4721   4753           goto shm_open_err;
................................................................................
  5409   5441   #endif
  5410   5442   
  5411   5443     /* No locking occurs in temporary files */
  5412   5444     assert( zFilename!=0 || noLock );
  5413   5445   
  5414   5446     OSTRACE(("OPEN    %-3d %s\n", h, zFilename));
  5415   5447     pNew->h = h;
         5448  +  pNew->pVfs = pVfs;
  5416   5449     pNew->zPath = zFilename;
         5450  +  pNew->ctrlFlags = 0;
         5451  +  if( sqlite3_uri_boolean(zFilename, "psow", SQLITE_POWERSAFE_OVERWRITE) ){
         5452  +    pNew->ctrlFlags |= UNIXFILE_PSOW;
         5453  +  }
  5417   5454     if( memcmp(pVfs->zName,"unix-excl",10)==0 ){
  5418         -    pNew->ctrlFlags = UNIXFILE_EXCL;
  5419         -  }else{
  5420         -    pNew->ctrlFlags = 0;
         5455  +    pNew->ctrlFlags |= UNIXFILE_EXCL;
  5421   5456     }
  5422   5457     if( isReadOnly ){
  5423   5458       pNew->ctrlFlags |= UNIXFILE_RDONLY;
  5424   5459     }
  5425   5460     if( syncDir ){
  5426   5461       pNew->ctrlFlags |= UNIXFILE_DIRSYNC;
  5427   5462     }
................................................................................
  5750   5785       **   "<path to db>-walNN"
  5751   5786       **
  5752   5787       ** where NN is a decimal number. The NN naming schemes are 
  5753   5788       ** used by the test_multiplex.c module.
  5754   5789       */
  5755   5790       nDb = sqlite3Strlen30(zPath) - 1; 
  5756   5791   #ifdef SQLITE_ENABLE_8_3_NAMES
  5757         -    while( nDb>0 && !sqlite3Isalnum(zPath[nDb]) ) nDb--;
         5792  +    while( nDb>0 && sqlite3Isalnum(zPath[nDb]) ) nDb--;
  5758   5793       if( nDb==0 || zPath[nDb]!='-' ) return SQLITE_OK;
  5759   5794   #else
  5760   5795       while( zPath[nDb]!='-' ){
  5761   5796         assert( nDb>0 );
  5762   5797         assert( zPath[nDb]!='\n' );
  5763   5798         nDb--;
  5764   5799       }

Changes to src/os_win.c.

    55     55   typedef struct winFile winFile;
    56     56   struct winFile {
    57     57     const sqlite3_io_methods *pMethod; /*** Must be first ***/
    58     58     sqlite3_vfs *pVfs;      /* The VFS used to open this file */
    59     59     HANDLE h;               /* Handle for accessing the file */
    60     60     u8 locktype;            /* Type of lock currently held on this file */
    61     61     short sharedLockByte;   /* Randomly chosen byte used as a shared lock */
    62         -  u8 bPersistWal;         /* True to persist WAL files */
           62  +  u8 ctrlFlags;           /* Flags.  See WINFILE_* below */
    63     63     DWORD lastErrno;        /* The Windows errno from the last I/O error */
    64         -  DWORD sectorSize;       /* Sector size of the device file is on */
    65     64     winShm *pShm;           /* Instance of shared memory on this file */
    66     65     const char *zPath;      /* Full pathname of this file */
    67     66     int szChunk;            /* Chunk size configured by FCNTL_CHUNK_SIZE */
    68     67   #if SQLITE_OS_WINCE
    69     68     LPWSTR zDeleteOnClose;  /* Name of file to delete when closing */
    70     69     HANDLE hMutex;          /* Mutex used to control access to shared lock */  
    71     70     HANDLE hShared;         /* Shared memory segment used for locking */
    72     71     winceLock local;        /* Locks obtained by this instance of winFile */
    73     72     winceLock *shared;      /* Global shared lock memory for the file  */
    74     73   #endif
    75     74   };
    76     75   
           76  +/*
           77  +** Allowed values for winFile.ctrlFlags
           78  +*/
           79  +#define WINFILE_PERSIST_WAL     0x04   /* Persistent WAL mode */
           80  +#define WINFILE_PSOW            0x10   /* SQLITE_IOCAP_POWERSAFE_OVERWRITE */
           81  +
    77     82   /*
    78     83    * If compiled with SQLITE_WIN32_MALLOC on Windows, we will use the
    79     84    * various Win32 API heap functions instead of our own.
    80     85    */
    81     86   #ifdef SQLITE_WIN32_MALLOC
    82     87   /*
    83     88    * The initial size of the Win32-specific heap.  This value may be zero.
................................................................................
   141    146   static int winMemRoundup(int n);
   142    147   static int winMemInit(void *pAppData);
   143    148   static void winMemShutdown(void *pAppData);
   144    149   
   145    150   const sqlite3_mem_methods *sqlite3MemGetWin32(void);
   146    151   #endif /* SQLITE_WIN32_MALLOC */
   147    152   
   148         -/*
   149         -** Forward prototypes.
   150         -*/
   151         -static int getSectorSize(
   152         -    sqlite3_vfs *pVfs,
   153         -    const char *zRelative     /* UTF-8 file name */
   154         -);
   155         -
   156    153   /*
   157    154   ** The following variable is (normally) set once and never changes
   158    155   ** thereafter.  It records whether the operating system is Win9x
   159    156   ** or WinNT.
   160    157   **
   161    158   ** 0:   Operating system unknown.
   162    159   ** 1:   Operating system is Win9x.
................................................................................
   914    911   ** Space to hold the returned string is obtained from malloc.
   915    912   */
   916    913   static LPWSTR utf8ToUnicode(const char *zFilename){
   917    914     int nChar;
   918    915     LPWSTR zWideFilename;
   919    916   
   920    917     nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0);
          918  +  if( nChar==0 ){
          919  +    return 0;
          920  +  }
   921    921     zWideFilename = sqlite3_malloc( nChar*sizeof(zWideFilename[0]) );
   922    922     if( zWideFilename==0 ){
   923    923       return 0;
   924    924     }
   925    925     nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, zWideFilename,
   926    926                                   nChar);
   927    927     if( nChar==0 ){
................................................................................
   936    936   ** obtained from sqlite3_malloc().
   937    937   */
   938    938   static char *unicodeToUtf8(LPCWSTR zWideFilename){
   939    939     int nByte;
   940    940     char *zFilename;
   941    941   
   942    942     nByte = osWideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, 0, 0, 0, 0);
          943  +  if( nByte == 0 ){
          944  +    return 0;
          945  +  }
   943    946     zFilename = sqlite3_malloc( nByte );
   944    947     if( zFilename==0 ){
   945    948       return 0;
   946    949     }
   947    950     nByte = osWideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, zFilename, nByte,
   948    951                                   0, 0);
   949    952     if( nByte == 0 ){
................................................................................
   963    966   static LPWSTR mbcsToUnicode(const char *zFilename){
   964    967     int nByte;
   965    968     LPWSTR zMbcsFilename;
   966    969     int codepage = osAreFileApisANSI() ? CP_ACP : CP_OEMCP;
   967    970   
   968    971     nByte = osMultiByteToWideChar(codepage, 0, zFilename, -1, NULL,
   969    972                                   0)*sizeof(WCHAR);
          973  +  if( nByte==0 ){
          974  +    return 0;
          975  +  }
   970    976     zMbcsFilename = sqlite3_malloc( nByte*sizeof(zMbcsFilename[0]) );
   971    977     if( zMbcsFilename==0 ){
   972    978       return 0;
   973    979     }
   974    980     nByte = osMultiByteToWideChar(codepage, 0, zFilename, -1, zMbcsFilename,
   975    981                                   nByte);
   976    982     if( nByte==0 ){
................................................................................
   989    995   */
   990    996   static char *unicodeToMbcs(LPCWSTR zWideFilename){
   991    997     int nByte;
   992    998     char *zFilename;
   993    999     int codepage = osAreFileApisANSI() ? CP_ACP : CP_OEMCP;
   994   1000   
   995   1001     nByte = osWideCharToMultiByte(codepage, 0, zWideFilename, -1, 0, 0, 0, 0);
         1002  +  if( nByte == 0 ){
         1003  +    return 0;
         1004  +  }
   996   1005     zFilename = sqlite3_malloc( nByte );
   997   1006     if( zFilename==0 ){
   998   1007       return 0;
   999   1008     }
  1000   1009     nByte = osWideCharToMultiByte(codepage, 0, zWideFilename, -1, zFilename,
  1001   1010                                   nByte, 0, 0);
  1002   1011     if( nByte == 0 ){
................................................................................
  2108   2117     }
  2109   2118     if( type>=PENDING_LOCK ){
  2110   2119       osUnlockFile(pFile->h, PENDING_BYTE, 0, 1, 0);
  2111   2120     }
  2112   2121     pFile->locktype = (u8)locktype;
  2113   2122     return rc;
  2114   2123   }
         2124  +
         2125  +/*
         2126  +** If *pArg is inititially negative then this is a query.  Set *pArg to
         2127  +** 1 or 0 depending on whether or not bit mask of pFile->ctrlFlags is set.
         2128  +**
         2129  +** If *pArg is 0 or 1, then clear or set the mask bit of pFile->ctrlFlags.
         2130  +*/
         2131  +static void winModeBit(winFile *pFile, unsigned char mask, int *pArg){
         2132  +  if( *pArg<0 ){
         2133  +    *pArg = (pFile->ctrlFlags & mask)!=0;
         2134  +  }else if( (*pArg)==0 ){
         2135  +    pFile->ctrlFlags &= ~mask;
         2136  +  }else{
         2137  +    pFile->ctrlFlags |= mask;
         2138  +  }
         2139  +}
  2115   2140   
  2116   2141   /*
  2117   2142   ** Control and query of the open file handle.
  2118   2143   */
  2119   2144   static int winFileControl(sqlite3_file *id, int op, void *pArg){
  2120   2145     winFile *pFile = (winFile*)id;
  2121   2146     switch( op ){
................................................................................
  2153   2178           *(int*)pArg = pFile->bPersistWal;
  2154   2179         }else{
  2155   2180           pFile->bPersistWal = bPersist!=0;
  2156   2181         }
  2157   2182         return SQLITE_OK;
  2158   2183       }
  2159   2184       case SQLITE_FCNTL_PERSIST_WAL: {
  2160         -      int bPersist = *(int*)pArg;
  2161         -      if( bPersist<0 ){
  2162         -        *(int*)pArg = pFile->bPersistWal;
  2163         -      }else{
  2164         -        pFile->bPersistWal = bPersist!=0;
  2165         -      }
         2185  +      winModeBit(pFile, WINFILE_PERSIST_WAL, (int*)pArg);
         2186  +      return SQLITE_OK;
         2187  +    }
         2188  +    case SQLITE_FCNTL_POWERSAFE_OVERWRITE: {
         2189  +      winModeBit(pFile, WINFILE_PSOW, (int*)pArg);
         2190  +      return SQLITE_OK;
         2191  +    }
         2192  +    case SQLITE_FCNTL_VFSNAME: {
         2193  +      *(char**)pArg = sqlite3_mprintf("win32");
  2166   2194         return SQLITE_OK;
  2167   2195       }
  2168   2196       case SQLITE_FCNTL_SYNC_OMITTED: {
  2169   2197         return SQLITE_OK;
  2170   2198       }
  2171   2199       case SQLITE_FCNTL_WIN32_AV_RETRY: {
  2172   2200         int *a = (int*)pArg;
................................................................................
  2193   2221   **
  2194   2222   ** SQLite code assumes this function cannot fail. It also assumes that
  2195   2223   ** if two files are created in the same file-system directory (i.e.
  2196   2224   ** a database and its journal file) that the sector size will be the
  2197   2225   ** same for both.
  2198   2226   */
  2199   2227   static int winSectorSize(sqlite3_file *id){
  2200         -  assert( id!=0 );
  2201         -  return (int)(((winFile*)id)->sectorSize);
         2228  +  (void)id;
         2229  +  return SQLITE_DEFAULT_SECTOR_SIZE;
  2202   2230   }
  2203   2231   
  2204   2232   /*
  2205   2233   ** Return a vector of device characteristics.
  2206   2234   */
  2207   2235   static int winDeviceCharacteristics(sqlite3_file *id){
  2208         -  UNUSED_PARAMETER(id);
  2209         -  return SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN;
         2236  +  winFile *p = (winFile*)id;
         2237  +  return SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN |
         2238  +         ((p->ctrlFlags & WINFILE_PSOW)?SQLITE_IOCAP_POWERSAFE_OVERWRITE:0);
  2210   2239   }
  2211   2240   
  2212   2241   #ifndef SQLITE_OMIT_WAL
  2213   2242   
  2214   2243   /* 
  2215   2244   ** Windows will only let you create file view mappings
  2216   2245   ** on allocation size granularity boundaries.
................................................................................
  2442   2471     /* Allocate space for the new sqlite3_shm object.  Also speculatively
  2443   2472     ** allocate space for a new winShmNode and filename.
  2444   2473     */
  2445   2474     p = sqlite3_malloc( sizeof(*p) );
  2446   2475     if( p==0 ) return SQLITE_IOERR_NOMEM;
  2447   2476     memset(p, 0, sizeof(*p));
  2448   2477     nName = sqlite3Strlen30(pDbFd->zPath);
  2449         -  pNew = sqlite3_malloc( sizeof(*pShmNode) + nName + 15 );
         2478  +  pNew = sqlite3_malloc( sizeof(*pShmNode) + nName + 16 );
  2450   2479     if( pNew==0 ){
  2451   2480       sqlite3_free(p);
  2452   2481       return SQLITE_IOERR_NOMEM;
  2453   2482     }
  2454   2483     memset(pNew, 0, sizeof(*pNew));
  2455   2484     pNew->zFilename = (char*)&pNew[1];
  2456   2485     sqlite3_snprintf(nName+15, pNew->zFilename, "%s-shm", pDbFd->zPath);
................................................................................
  3167   3196     memset(pFile, 0, sizeof(*pFile));
  3168   3197     pFile->pMethod = &winIoMethod;
  3169   3198     pFile->h = h;
  3170   3199     pFile->lastErrno = NO_ERROR;
  3171   3200     pFile->pVfs = pVfs;
  3172   3201     pFile->pShm = 0;
  3173   3202     pFile->zPath = zName;
  3174         -  pFile->sectorSize = getSectorSize(pVfs, zUtf8Name);
         3203  +  if( sqlite3_uri_boolean(zName, "psow", SQLITE_POWERSAFE_OVERWRITE) ){
         3204  +    pFile->ctrlFlags |= WINFILE_PSOW;
         3205  +  }
  3175   3206   
  3176   3207   #if SQLITE_OS_WINCE
  3177   3208     if( isReadWrite && eType==SQLITE_OPEN_MAIN_DB
  3178   3209          && !winceCreateLock(zName, pFile)
  3179   3210     ){
  3180   3211       osCloseHandle(h);
  3181   3212       sqlite3_free(zConverted);
................................................................................
  3412   3443       return SQLITE_OK;
  3413   3444     }else{
  3414   3445       return SQLITE_IOERR_NOMEM;
  3415   3446     }
  3416   3447   #endif
  3417   3448   }
  3418   3449   
  3419         -/*
  3420         -** Get the sector size of the device used to store
  3421         -** file.
  3422         -*/
  3423         -static int getSectorSize(
  3424         -    sqlite3_vfs *pVfs,
  3425         -    const char *zRelative     /* UTF-8 file name */
  3426         -){
  3427         -  DWORD bytesPerSector = SQLITE_DEFAULT_SECTOR_SIZE;
  3428         -  /* GetDiskFreeSpace is not supported under WINCE */
  3429         -#if SQLITE_OS_WINCE
  3430         -  UNUSED_PARAMETER(pVfs);
  3431         -  UNUSED_PARAMETER(zRelative);
  3432         -#else
  3433         -  char zFullpath[MAX_PATH+1];
  3434         -  int rc;
  3435         -  DWORD dwRet = 0;
  3436         -  DWORD dwDummy;
  3437         -
  3438         -  /*
  3439         -  ** We need to get the full path name of the file
  3440         -  ** to get the drive letter to look up the sector
  3441         -  ** size.
  3442         -  */
  3443         -  SimulateIOErrorBenign(1);
  3444         -  sqlite3BeginBenignMalloc();
  3445         -  rc = winFullPathname(pVfs, zRelative, MAX_PATH, zFullpath);
  3446         -  sqlite3EndBenignMalloc();
  3447         -  SimulateIOErrorBenign(0);
  3448         -  if( rc == SQLITE_OK )
  3449         -  {
  3450         -    void *zConverted;
  3451         -    sqlite3BeginBenignMalloc();
  3452         -    zConverted = convertUtf8Filename(zFullpath);
  3453         -    sqlite3EndBenignMalloc();
  3454         -    if( zConverted ){
  3455         -      if( isNT() ){
  3456         -        /* trim path to just drive reference */
  3457         -        LPWSTR p = zConverted;
  3458         -        for(;*p;p++){
  3459         -          if( *p == '\\' ){
  3460         -            *p = '\0';
  3461         -            break;
  3462         -          }
  3463         -        }
  3464         -        dwRet = osGetDiskFreeSpaceW((LPCWSTR)zConverted,
  3465         -                                    &dwDummy,
  3466         -                                    &bytesPerSector,
  3467         -                                    &dwDummy,
  3468         -                                    &dwDummy);
  3469         -      }else{
  3470         -        /* trim path to just drive reference */
  3471         -        char *p = (char *)zConverted;
  3472         -        for(;*p;p++){
  3473         -          if( *p == '\\' ){
  3474         -            *p = '\0';
  3475         -            break;
  3476         -          }
  3477         -        }
  3478         -        dwRet = osGetDiskFreeSpaceA((char*)zConverted,
  3479         -                                    &dwDummy,
  3480         -                                    &bytesPerSector,
  3481         -                                    &dwDummy,
  3482         -                                    &dwDummy);
  3483         -      }
  3484         -      sqlite3_free(zConverted);
  3485         -    }
  3486         -    if( !dwRet ){
  3487         -      bytesPerSector = SQLITE_DEFAULT_SECTOR_SIZE;
  3488         -    }
  3489         -  }
  3490         -#endif
  3491         -  return (int) bytesPerSector; 
  3492         -}
  3493         -
  3494   3450   #ifndef SQLITE_OMIT_LOAD_EXTENSION
  3495   3451   /*
  3496   3452   ** Interfaces for opening a shared library, finding entry points
  3497   3453   ** within the shared library, and closing the shared library.
  3498   3454   */
  3499   3455   /*
  3500   3456   ** Interfaces for opening a shared library, finding entry points

Changes to src/pager.c.

   612    612     u8 exclusiveMode;           /* Boolean. True if locking_mode==EXCLUSIVE */
   613    613     u8 journalMode;             /* One of the PAGER_JOURNALMODE_* values */
   614    614     u8 useJournal;              /* Use a rollback journal on this file */
   615    615     u8 noReadlock;              /* Do not bother to obtain readlocks */
   616    616     u8 noSync;                  /* Do not sync the journal if true */
   617    617     u8 fullSync;                /* Do extra syncs of the journal for robustness */
   618    618     u8 ckptSyncFlags;           /* SYNC_NORMAL or SYNC_FULL for checkpoint */
          619  +  u8 walSyncFlags;            /* SYNC_NORMAL or SYNC_FULL for wal writes */
   619    620     u8 syncFlags;               /* SYNC_NORMAL or SYNC_FULL otherwise */
   620    621     u8 tempFile;                /* zFilename is a temporary file */
   621    622     u8 readOnly;                /* True for a read-only database */
   622    623     u8 memDb;                   /* True to inhibit all file I/O */
   623    624   
   624    625     /**************************************************************************
   625    626     ** The following block contains those class members that change during
................................................................................
   782    783   #ifndef SQLITE_OMIT_WAL
   783    784   static int pagerUseWal(Pager *pPager){
   784    785     return (pPager->pWal!=0);
   785    786   }
   786    787   #else
   787    788   # define pagerUseWal(x) 0
   788    789   # define pagerRollbackWal(x) 0
   789         -# define pagerWalFrames(v,w,x,y,z) 0
          790  +# define pagerWalFrames(v,w,x,y) 0
   790    791   # define pagerOpenWalIfPresent(z) SQLITE_OK
   791    792   # define pagerBeginReadTransaction(z) SQLITE_OK
   792    793   #endif
   793    794   
   794    795   #ifndef NDEBUG 
   795    796   /*
   796    797   ** Usage:
................................................................................
  2518   2519   **
  2519   2520   ** For temporary files the effective sector size is always 512 bytes.
  2520   2521   **
  2521   2522   ** Otherwise, for non-temporary files, the effective sector size is
  2522   2523   ** the value returned by the xSectorSize() method rounded up to 32 if
  2523   2524   ** it is less than 32, or rounded down to MAX_SECTOR_SIZE if it
  2524   2525   ** is greater than MAX_SECTOR_SIZE.
         2526  +**
         2527  +** If the file has the SQLITE_IOCAP_POWERSAFE_OVERWRITE property, then set
         2528  +** the effective sector size to its minimum value (512).  The purpose of
         2529  +** pPager->sectorSize is to define the "blast radius" of bytes that
         2530  +** might change if a crash occurs while writing to a single byte in
         2531  +** that range.  But with POWERSAFE_OVERWRITE, the blast radius is zero
         2532  +** (that is what POWERSAFE_OVERWRITE means), so we minimize the sector
         2533  +** size.  For backwards compatibility of the rollback journal file format,
         2534  +** we cannot reduce the effective sector size below 512.
  2525   2535   */
  2526   2536   static void setSectorSize(Pager *pPager){
  2527   2537     assert( isOpen(pPager->fd) || pPager->tempFile );
  2528   2538   
  2529         -  if( !pPager->tempFile ){
         2539  +  if( pPager->tempFile
         2540  +   || (sqlite3OsDeviceCharacteristics(pPager->fd) & 
         2541  +              SQLITE_IOCAP_POWERSAFE_OVERWRITE)!=0
         2542  +  ){
  2530   2543       /* Sector size doesn't matter for temporary files. Also, the file
  2531   2544       ** may not have been opened yet, in which case the OsSectorSize()
  2532         -    ** call will segfault.
  2533         -    */
         2545  +    ** call will segfault. */
         2546  +    pPager->sectorSize = 512;
         2547  +  }else{
  2534   2548       pPager->sectorSize = sqlite3OsSectorSize(pPager->fd);
  2535         -  }
  2536         -  if( pPager->sectorSize<32 ){
  2537         -    pPager->sectorSize = 512;
  2538         -  }
  2539         -  if( pPager->sectorSize>MAX_SECTOR_SIZE ){
  2540         -    assert( MAX_SECTOR_SIZE>=512 );
  2541         -    pPager->sectorSize = MAX_SECTOR_SIZE;
         2549  +    if( pPager->sectorSize<32 ){
         2550  +      pPager->sectorSize = 512;
         2551  +    }
         2552  +    if( pPager->sectorSize>MAX_SECTOR_SIZE ){
         2553  +      assert( MAX_SECTOR_SIZE>=512 );
         2554  +      pPager->sectorSize = MAX_SECTOR_SIZE;
         2555  +    }
  2542   2556     }
  2543   2557   }
  2544   2558   
  2545   2559   /*
  2546   2560   ** Playback the journal and thus restore the database file to
  2547   2561   ** the state it was in before we started making changes.  
  2548   2562   **
................................................................................
  2959   2973   ** The list of pages passed into this routine is always sorted by page number.
  2960   2974   ** Hence, if page 1 appears anywhere on the list, it will be the first page.
  2961   2975   */ 
  2962   2976   static int pagerWalFrames(
  2963   2977     Pager *pPager,                  /* Pager object */
  2964   2978     PgHdr *pList,                   /* List of frames to log */
  2965   2979     Pgno nTruncate,                 /* Database size after this commit */
  2966         -  int isCommit,                   /* True if this is a commit */
  2967         -  int syncFlags                   /* Flags to pass to OsSync() (or 0) */
         2980  +  int isCommit                    /* True if this is a commit */
  2968   2981   ){
  2969   2982     int rc;                         /* Return code */
  2970   2983   #if defined(SQLITE_DEBUG) || defined(SQLITE_CHECK_PAGES)
  2971   2984     PgHdr *p;                       /* For looping over pages */
  2972   2985   #endif
  2973   2986   
  2974   2987     assert( pPager->pWal );
................................................................................
  2991   3004         if( p->pgno<=nTruncate ) ppNext = &p->pDirty;
  2992   3005       }
  2993   3006       assert( pList );
  2994   3007     }
  2995   3008   
  2996   3009     if( pList->pgno==1 ) pager_write_changecounter(pList);
  2997   3010     rc = sqlite3WalFrames(pPager->pWal, 
  2998         -      pPager->pageSize, pList, nTruncate, isCommit, syncFlags
         3011  +      pPager->pageSize, pList, nTruncate, isCommit, pPager->walSyncFlags
  2999   3012     );
  3000   3013     if( rc==SQLITE_OK && pPager->pBackup ){
  3001   3014       PgHdr *p;
  3002   3015       for(p=pList; p; p=p->pDirty){
  3003   3016         sqlite3BackupUpdate(pPager->pBackup, p->pgno, (u8 *)p->pData);
  3004   3017       }
  3005   3018     }
................................................................................
  3271   3284   
  3272   3285     /* Finally,  rollback pages from the sub-journal.  Page that were
  3273   3286     ** previously rolled back out of the main journal (and are hence in pDone)
  3274   3287     ** will be skipped.  Out-of-range pages are also skipped.
  3275   3288     */
  3276   3289     if( pSavepoint ){
  3277   3290       u32 ii;            /* Loop counter */
  3278         -    i64 offset = pSavepoint->iSubRec*(4+pPager->pageSize);
         3291  +    i64 offset = (i64)pSavepoint->iSubRec*(4+pPager->pageSize);
  3279   3292   
  3280   3293       if( pagerUseWal(pPager) ){
  3281   3294         rc = sqlite3WalSavepointUndo(pPager->pWal, pSavepoint->aWalData);
  3282   3295       }
  3283   3296       for(ii=pSavepoint->iSubRec; rc==SQLITE_OK && ii<pPager->nSubRec; ii++){
  3284         -      assert( offset==ii*(4+pPager->pageSize) );
         3297  +      assert( offset==(i64)ii*(4+pPager->pageSize) );
  3285   3298         rc = pager_playback_one_page(pPager, &offset, pDone, 0, 1);
  3286   3299       }
  3287   3300       assert( rc!=SQLITE_DONE );
  3288   3301     }
  3289   3302   
  3290   3303     sqlite3BitvecDestroy(pDone);
  3291   3304     if( rc==SQLITE_OK ){
................................................................................
  3371   3384     }else if( bCkptFullFsync ){
  3372   3385       pPager->syncFlags = SQLITE_SYNC_NORMAL;
  3373   3386       pPager->ckptSyncFlags = SQLITE_SYNC_FULL;
  3374   3387     }else{
  3375   3388       pPager->syncFlags = SQLITE_SYNC_NORMAL;
  3376   3389       pPager->ckptSyncFlags = SQLITE_SYNC_NORMAL;
  3377   3390     }
         3391  +  pPager->walSyncFlags = pPager->syncFlags;
         3392  +  if( pPager->fullSync ){
         3393  +    pPager->walSyncFlags |= WAL_SYNC_TRANSACTIONS;
         3394  +  }
  3378   3395   }
  3379   3396   #endif
  3380   3397   
  3381   3398   /*
  3382   3399   ** The following global variable is incremented whenever the library
  3383   3400   ** attempts to open a temporary file.  This information is used for
  3384   3401   ** testing and analysis only.  
................................................................................
  4020   4037   
  4021   4038     /* Before the first write, give the VFS a hint of what the final
  4022   4039     ** file size will be.
  4023   4040     */
  4024   4041     assert( rc!=SQLITE_OK || isOpen(pPager->fd) );
  4025   4042     if( rc==SQLITE_OK && pPager->dbSize>pPager->dbHintSize ){
  4026   4043       sqlite3_int64 szFile = pPager->pageSize * (sqlite3_int64)pPager->dbSize;
         4044  +    sqlite3BeginBenignMalloc();
  4027   4045       sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_SIZE_HINT, &szFile);
         4046  +    sqlite3EndBenignMalloc();
  4028   4047       pPager->dbHintSize = pPager->dbSize;
  4029   4048     }
  4030   4049   
  4031   4050     while( rc==SQLITE_OK && pList ){
  4032   4051       Pgno pgno = pList->pgno;
  4033   4052   
  4034   4053       /* If there are dirty pages in the page cache with page numbers greater
................................................................................
  4129   4148       );
  4130   4149       rc = openSubJournal(pPager);
  4131   4150   
  4132   4151       /* If the sub-journal was opened successfully (or was already open),
  4133   4152       ** write the journal record into the file.  */
  4134   4153       if( rc==SQLITE_OK ){
  4135   4154         void *pData = pPg->pData;
  4136         -      i64 offset = pPager->nSubRec*(4+pPager->pageSize);
         4155  +      i64 offset = (i64)pPager->nSubRec*(4+pPager->pageSize);
  4137   4156         char *pData2;
  4138   4157     
  4139   4158         CODEC2(pPager, pData, pPg->pgno, 7, return SQLITE_NOMEM, pData2);
  4140   4159         PAGERTRACE(("STMT-JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno));
  4141   4160         rc = write32bits(pPager->sjfd, offset, pPg->pgno);
  4142   4161         if( rc==SQLITE_OK ){
  4143   4162           rc = sqlite3OsWrite(pPager->sjfd, pData2, pPager->pageSize, offset+4);
................................................................................
  4202   4221     pPg->pDirty = 0;
  4203   4222     if( pagerUseWal(pPager) ){
  4204   4223       /* Write a single frame for this page to the log. */
  4205   4224       if( subjRequiresPage(pPg) ){ 
  4206   4225         rc = subjournalPage(pPg); 
  4207   4226       }
  4208   4227       if( rc==SQLITE_OK ){
  4209         -      rc = pagerWalFrames(pPager, pPg, 0, 0, 0);
         4228  +      rc = pagerWalFrames(pPager, pPg, 0, 0);
  4210   4229       }
  4211   4230     }else{
  4212   4231     
  4213   4232       /* Sync the journal file if required. */
  4214   4233       if( pPg->flags&PGHDR_NEED_SYNC 
  4215   4234        || pPager->eState==PAGER_WRITER_CACHEMOD
  4216   4235       ){
................................................................................
  4361   4380       rc = sqlite3OsFullPathname(pVfs, zFilename, nPathname, zPathname);
  4362   4381       nPathname = sqlite3Strlen30(zPathname);
  4363   4382       z = zUri = &zFilename[sqlite3Strlen30(zFilename)+1];
  4364   4383       while( *z ){
  4365   4384         z += sqlite3Strlen30(z)+1;
  4366   4385         z += sqlite3Strlen30(z)+1;
  4367   4386       }
  4368         -    nUri = &z[1] - zUri;
         4387  +    nUri = (int)(&z[1] - zUri);
         4388  +    assert( nUri>=0 );
  4369   4389       if( rc==SQLITE_OK && nPathname+8>pVfs->mxPathname ){
  4370   4390         /* This branch is taken when the journal path required by
  4371   4391         ** the database being opened will be more than pVfs->mxPathname
  4372   4392         ** bytes in length. This means the database cannot be opened,
  4373   4393         ** as it will not be possible to open the journal file or even
  4374   4394         ** check for a hot-journal before reading.
  4375   4395         */
................................................................................
  4395   4415     */
  4396   4416     pPtr = (u8 *)sqlite3MallocZero(
  4397   4417       ROUND8(sizeof(*pPager)) +      /* Pager structure */
  4398   4418       ROUND8(pcacheSize) +           /* PCache object */
  4399   4419       ROUND8(pVfs->szOsFile) +       /* The main db file */
  4400   4420       journalFileSize * 2 +          /* The two journal files */ 
  4401   4421       nPathname + 1 + nUri +         /* zFilename */
  4402         -    nPathname + 8 + 1              /* zJournal */
         4422  +    nPathname + 8 + 2              /* zJournal */
  4403   4423   #ifndef SQLITE_OMIT_WAL
  4404         -    + nPathname + 4 + 1              /* zWal */
         4424  +    + nPathname + 4 + 2            /* zWal */
  4405   4425   #endif
  4406   4426     );
  4407   4427     assert( EIGHT_BYTE_ALIGNMENT(SQLITE_INT_TO_PTR(journalFileSize)) );
  4408   4428     if( !pPtr ){
  4409   4429       sqlite3_free(zPathname);
  4410   4430       return SQLITE_NOMEM;
  4411   4431     }
................................................................................
  4420   4440     /* Fill in the Pager.zFilename and Pager.zJournal buffers, if required. */
  4421   4441     if( zPathname ){
  4422   4442       assert( nPathname>0 );
  4423   4443       pPager->zJournal =   (char*)(pPtr += nPathname + 1 + nUri);
  4424   4444       memcpy(pPager->zFilename, zPathname, nPathname);
  4425   4445       memcpy(&pPager->zFilename[nPathname+1], zUri, nUri);
  4426   4446       memcpy(pPager->zJournal, zPathname, nPathname);
  4427         -    memcpy(&pPager->zJournal[nPathname], "-journal", 8);
         4447  +    memcpy(&pPager->zJournal[nPathname], "-journal\000", 8+1);
  4428   4448       sqlite3FileSuffix3(pPager->zFilename, pPager->zJournal);
  4429   4449   #ifndef SQLITE_OMIT_WAL
  4430   4450       pPager->zWal = &pPager->zJournal[nPathname+8+1];
  4431   4451       memcpy(pPager->zWal, zPathname, nPathname);
  4432         -    memcpy(&pPager->zWal[nPathname], "-wal", 4);
         4452  +    memcpy(&pPager->zWal[nPathname], "-wal\000", 4+1);
  4433   4453       sqlite3FileSuffix3(pPager->zFilename, pPager->zWal);
  4434   4454   #endif
  4435   4455       sqlite3_free(zPathname);
  4436   4456     }
  4437   4457     pPager->pVfs = pVfs;
  4438   4458     pPager->vfsFlags = vfsFlags;
  4439   4459   
................................................................................
  4543   4563     pPager->changeCountDone = pPager->tempFile;
  4544   4564     pPager->memDb = (u8)memDb;
  4545   4565     pPager->readOnly = (u8)readOnly;
  4546   4566     assert( useJournal || pPager->tempFile );
  4547   4567     pPager->noSync = pPager->tempFile;
  4548   4568     pPager->fullSync = pPager->noSync ?0:1;
  4549   4569     pPager->syncFlags = pPager->noSync ? 0 : SQLITE_SYNC_NORMAL;
  4550         -#if SQLITE_DEFAULT_CKPTFULLFSYNC
  4551         -  pPager->ckptSyncFlags = pPager->noSync ? 0 : SQLITE_SYNC_FULL;
  4552         -#else
  4553   4570     pPager->ckptSyncFlags = pPager->syncFlags;
  4554         -#endif
         4571  +  if( pPager->noSync ){
         4572  +    assert( pPager->fullSync==0 );
         4573  +    assert( pPager->syncFlags==0 );
         4574  +    assert( pPager->walSyncFlags==0 );
         4575  +    assert( pPager->ckptSyncFlags==0 );
         4576  +  }else{
         4577  +    pPager->fullSync = 1;
         4578  +    pPager->syncFlags = SQLITE_SYNC_NORMAL;
         4579  +    pPager->walSyncFlags = SQLITE_SYNC_NORMAL | WAL_SYNC_TRANSACTIONS;
         4580  +    pPager->ckptSyncFlags = SQLITE_SYNC_NORMAL;
         4581  +  }
  4555   4582     /* pPager->pFirst = 0; */
  4556   4583     /* pPager->pFirstSynced = 0; */
  4557   4584     /* pPager->pLast = 0; */
  4558   4585     pPager->nExtra = (u16)nExtra;
  4559   4586     pPager->journalSizeLimit = SQLITE_DEFAULT_JOURNAL_SIZE_LIMIT;
  4560   4587     assert( isOpen(pPager->fd) || tempFile );
  4561   4588     setSectorSize(pPager);
................................................................................
  5691   5718   int sqlite3PagerSync(Pager *pPager){
  5692   5719     int rc = SQLITE_OK;
  5693   5720     if( !pPager->noSync ){
  5694   5721       assert( !MEMDB );
  5695   5722       rc = sqlite3OsSync(pPager->fd, pPager->syncFlags);
  5696   5723     }else if( isOpen(pPager->fd) ){
  5697   5724       assert( !MEMDB );
  5698         -    sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_SYNC_OMITTED, (void *)&rc);
         5725  +    rc = sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_SYNC_OMITTED, 0);
         5726  +    if( rc==SQLITE_NOTFOUND ){
         5727  +      rc = SQLITE_OK;
         5728  +    }
  5699   5729     }
  5700   5730     return rc;
  5701   5731   }
  5702   5732   
  5703   5733   /*
  5704   5734   ** This function may only be called while a write-transaction is active in
  5705   5735   ** rollback. If the connection is in WAL mode, this call is a no-op. 
................................................................................
  5788   5818           ** Ticket [2d1a5c67dfc2363e44f29d9bbd57f] 2011-05-18 */
  5789   5819           rc = sqlite3PagerGet(pPager, 1, &pPageOne);
  5790   5820           pList = pPageOne;
  5791   5821           pList->pDirty = 0;
  5792   5822         }
  5793   5823         assert( rc==SQLITE_OK );
  5794   5824         if( ALWAYS(pList) ){
  5795         -        rc = pagerWalFrames(pPager, pList, pPager->dbSize, 1, 
  5796         -            (pPager->fullSync ? pPager->syncFlags : 0)
  5797         -        );
         5825  +        rc = pagerWalFrames(pPager, pList, pPager->dbSize, 1);
  5798   5826         }
  5799   5827         sqlite3PagerUnref(pPageOne);
  5800   5828         if( rc==SQLITE_OK ){
  5801   5829           sqlite3PcacheCleanAll(pPager->pPCache);
  5802   5830         }
  5803   5831       }else{
  5804   5832         /* The following block updates the change-counter. Exactly how it

Changes to src/parse.y.

   390    390   %endif  SQLITE_OMIT_VIEW
   391    391   
   392    392   //////////////////////// The SELECT statement /////////////////////////////////
   393    393   //
   394    394   cmd ::= select(X).  {
   395    395     SelectDest dest = {SRT_Output, 0, 0, 0, 0};
   396    396     sqlite3Select(pParse, X, &dest);
          397  +  sqlite3ExplainBegin(pParse->pVdbe);
          398  +  sqlite3ExplainSelect(pParse->pVdbe, X);
          399  +  sqlite3ExplainFinish(pParse->pVdbe);
   397    400     sqlite3SelectDelete(pParse->db, X);
   398    401   }
   399    402   
   400    403   %type select {Select*}
   401    404   %destructor select {sqlite3SelectDelete(pParse->db, $$);}
   402    405   %type oneselect {Select*}
   403    406   %destructor oneselect {sqlite3SelectDelete(pParse->db, $$);}

Changes to src/pcache.c.

   201    201   /*
   202    202   ** Compute the number of pages of cache requested.
   203    203   */
   204    204   static int numberOfCachePages(PCache *p){
   205    205     if( p->szCache>=0 ){
   206    206       return p->szCache;
   207    207     }else{
   208         -    return (-1024*p->szCache)/(p->szPage+p->szExtra);
          208  +    return (int)((-1024*(i64)p->szCache)/(p->szPage+p->szExtra));
   209    209     }
   210    210   }
   211    211   
   212    212   /*
   213    213   ** Try to obtain a page from the cache.
   214    214   */
   215    215   int sqlite3PcacheFetch(

Changes to src/pcache1.c.

    44     44   **
    45     45   ** For mode (1), PGroup.mutex is NULL.  For mode (2) there is only a single
    46     46   ** PGroup which is the pcache1.grp global variable and its mutex is
    47     47   ** SQLITE_MUTEX_STATIC_LRU.
    48     48   */
    49     49   struct PGroup {
    50     50     sqlite3_mutex *mutex;          /* MUTEX_STATIC_LRU or NULL */
    51         -  int nMaxPage;                  /* Sum of nMax for purgeable caches */
    52         -  int nMinPage;                  /* Sum of nMin for purgeable caches */
    53         -  int mxPinned;                  /* nMaxpage + 10 - nMinPage */
    54         -  int nCurrentPage;              /* Number of purgeable pages allocated */
           51  +  unsigned int nMaxPage;         /* Sum of nMax for purgeable caches */
           52  +  unsigned int nMinPage;         /* Sum of nMin for purgeable caches */
           53  +  unsigned int mxPinned;         /* nMaxpage + 10 - nMinPage */
           54  +  unsigned int nCurrentPage;     /* Number of purgeable pages allocated */
    55     55     PgHdr1 *pLruHead, *pLruTail;   /* LRU list of unpinned pages */
    56     56   };
    57     57   
    58     58   /* Each page cache is an instance of the following object.  Every
    59     59   ** open database file (including each in-memory database and each
    60     60   ** temporary or transient database) has a single page cache which
    61     61   ** is an instance of this object.
................................................................................
   710    710   **   5. Otherwise, allocate and return a new page buffer.
   711    711   */
   712    712   static sqlite3_pcache_page *pcache1Fetch(
   713    713     sqlite3_pcache *p, 
   714    714     unsigned int iKey, 
   715    715     int createFlag
   716    716   ){
   717         -  int nPinned;
          717  +  unsigned int nPinned;
   718    718     PCache1 *pCache = (PCache1 *)p;
   719    719     PGroup *pGroup;
   720    720     PgHdr1 *pPage = 0;
   721    721   
   722    722     assert( pCache->bPurgeable || createFlag!=1 );
   723    723     assert( pCache->bPurgeable || pCache->nMin==0 );
   724    724     assert( pCache->bPurgeable==0 || pCache->nMin==10 );
................................................................................
   745    745     ** this point.
   746    746     */
   747    747   #ifdef SQLITE_MUTEX_OMIT
   748    748     pGroup = pCache->pGroup;
   749    749   #endif
   750    750   
   751    751     /* Step 3: Abort if createFlag is 1 but the cache is nearly full */
          752  +  assert( pCache->nPage >= pCache->nRecyclable );
   752    753     nPinned = pCache->nPage - pCache->nRecyclable;
   753         -  assert( nPinned>=0 );
   754    754     assert( pGroup->mxPinned == pGroup->nMaxPage + 10 - pGroup->nMinPage );
   755    755     assert( pCache->n90pct == pCache->nMax*9/10 );
   756    756     if( createFlag==1 && (
   757    757           nPinned>=pGroup->mxPinned
   758         -     || nPinned>=(int)pCache->n90pct
          758  +     || nPinned>=pCache->n90pct
   759    759        || pcache1UnderMemoryPressure(pCache)
   760    760     )){
   761    761       goto fetch_out;
   762    762     }
   763    763   
   764    764     if( pCache->nPage>=pCache->nHash && pcache1ResizeHash(pCache) ){
   765    765       goto fetch_out;
................................................................................
   924    924   */
   925    925   static void pcache1Destroy(sqlite3_pcache *p){
   926    926     PCache1 *pCache = (PCache1 *)p;
   927    927     PGroup *pGroup = pCache->pGroup;
   928    928     assert( pCache->bPurgeable || (pCache->nMax==0 && pCache->nMin==0) );
   929    929     pcache1EnterMutex(pGroup);
   930    930     pcache1TruncateUnsafe(pCache, 0);
          931  +  assert( pGroup->nMaxPage >= pCache->nMax );
   931    932     pGroup->nMaxPage -= pCache->nMax;
          933  +  assert( pGroup->nMinPage >= pCache->nMin );
   932    934     pGroup->nMinPage -= pCache->nMin;
   933    935     pGroup->mxPinned = pGroup->nMaxPage + 10 - pGroup->nMinPage;
   934    936     pcache1EnforceMaxPage(pGroup);
   935    937     pcache1LeaveMutex(pGroup);
   936    938     sqlite3_free(pCache->apHash);
   937    939     sqlite3_free(pCache);
   938    940   }
................................................................................
  1006   1008   ){
  1007   1009     PgHdr1 *p;
  1008   1010     int nRecyclable = 0;
  1009   1011     for(p=pcache1.grp.pLruHead; p; p=p->pLruNext){
  1010   1012       nRecyclable++;
  1011   1013     }
  1012   1014     *pnCurrent = pcache1.grp.nCurrentPage;
  1013         -  *pnMax = pcache1.grp.nMaxPage;
  1014         -  *pnMin = pcache1.grp.nMinPage;
         1015  +  *pnMax = (int)pcache1.grp.nMaxPage;
         1016  +  *pnMin = (int)pcache1.grp.nMinPage;
  1015   1017     *pnRecyclable = nRecyclable;
  1016   1018   }
  1017   1019   #endif

Changes to src/printf.c.

   132    132     return (char)digit;
   133    133   }
   134    134   #endif /* SQLITE_OMIT_FLOATING_POINT */
   135    135   
   136    136   /*
   137    137   ** Append N space characters to the given string buffer.
   138    138   */
   139         -static void appendSpace(StrAccum *pAccum, int N){
          139  +void sqlite3AppendSpace(StrAccum *pAccum, int N){
   140    140     static const char zSpaces[] = "                             ";
   141    141     while( N>=(int)sizeof(zSpaces)-1 ){
   142    142       sqlite3StrAccumAppend(pAccum, zSpaces, sizeof(zSpaces)-1);
   143    143       N -= sizeof(zSpaces)-1;
   144    144     }
   145    145     if( N>0 ){
   146    146       sqlite3StrAccumAppend(pAccum, zSpaces, N);
................................................................................
   660    660       ** "length" characters long.  The field width is "width".  Do
   661    661       ** the output.
   662    662       */
   663    663       if( !flag_leftjustify ){
   664    664         register int nspace;
   665    665         nspace = width-length;
   666    666         if( nspace>0 ){
   667         -        appendSpace(pAccum, nspace);
          667  +        sqlite3AppendSpace(pAccum, nspace);
   668    668         }
   669    669       }
   670    670       if( length>0 ){
   671    671         sqlite3StrAccumAppend(pAccum, bufpt, length);
   672    672       }
   673    673       if( flag_leftjustify ){
   674    674         register int nspace;
   675    675         nspace = width-length;
   676    676         if( nspace>0 ){
   677         -        appendSpace(pAccum, nspace);
          677  +        sqlite3AppendSpace(pAccum, nspace);
   678    678         }
   679    679       }
   680    680       sqlite3_free(zExtra);
   681    681     }/* End for loop over the format string */
   682    682   } /* End of function */
   683    683   
   684    684   /*

Changes to src/resolve.c.

   795    795           int flags = pE->flags & EP_ExpCollate;
   796    796           sqlite3ExprDelete(db, pE);
   797    797           pItem->pExpr = pE = sqlite3Expr(db, TK_INTEGER, 0);
   798    798           if( pE==0 ) return 1;
   799    799           pE->pColl = pColl;
   800    800           pE->flags |= EP_IntValue | flags;
   801    801           pE->u.iValue = iCol;
   802         -        pItem->iCol = (u16)iCol;
          802  +        pItem->iOrderByCol = (u16)iCol;
   803    803           pItem->done = 1;
   804    804         }else{
   805    805           moreToDo = 1;
   806    806         }
   807    807       }
   808    808       pSelect = pSelect->pNext;
   809    809     }
................................................................................
   844    844       sqlite3ErrorMsg(pParse, "too many terms in %s BY clause", zType);
   845    845       return 1;
   846    846     }
   847    847   #endif
   848    848     pEList = pSelect->pEList;
   849    849     assert( pEList!=0 );  /* sqlite3SelectNew() guarantees this */
   850    850     for(i=0, pItem=pOrderBy->a; i<pOrderBy->nExpr; i++, pItem++){
   851         -    if( pItem->iCol ){
   852         -      if( pItem->iCol>pEList->nExpr ){
          851  +    if( pItem->iOrderByCol ){
          852  +      if( pItem->iOrderByCol>pEList->nExpr ){
   853    853           resolveOutOfRangeError(pParse, zType, i+1, pEList->nExpr);
   854    854           return 1;
   855    855         }
   856         -      resolveAlias(pParse, pEList, pItem->iCol-1, pItem->pExpr, zType);
          856  +      resolveAlias(pParse, pEList, pItem->iOrderByCol-1, pItem->pExpr, zType);
   857    857       }
   858    858     }
   859    859     return 0;
   860    860   }
   861    861   
   862    862   /*
   863    863   ** pOrderBy is an ORDER BY or GROUP BY clause in SELECT statement pSelect.
................................................................................
   896    896       Expr *pE = pItem->pExpr;
   897    897       iCol = resolveAsName(pParse, pSelect->pEList, pE);
   898    898       if( iCol>0 ){
   899    899         /* If an AS-name match is found, mark this ORDER BY column as being
   900    900         ** a copy of the iCol-th result-set column.  The subsequent call to
   901    901         ** sqlite3ResolveOrderGroupBy() will convert the expression to a
   902    902         ** copy of the iCol-th result-set expression. */
   903         -      pItem->iCol = (u16)iCol;
          903  +      pItem->iOrderByCol = (u16)iCol;
   904    904         continue;
   905    905       }
   906    906       if( sqlite3ExprIsInteger(pE, &iCol) ){
   907    907         /* The ORDER BY term is an integer constant.  Again, set the column
   908    908         ** number so that sqlite3ResolveOrderGroupBy() will convert the
   909    909         ** order-by term to a copy of the result-set expression */
   910    910         if( iCol<1 ){
   911    911           resolveOutOfRangeError(pParse, zType, i+1, nResult);
   912    912           return 1;
   913    913         }
   914         -      pItem->iCol = (u16)iCol;
          914  +      pItem->iOrderByCol = (u16)iCol;
   915    915         continue;
   916    916       }
   917    917   
   918    918       /* Otherwise, treat the ORDER BY term as an ordinary expression */
   919         -    pItem->iCol = 0;
          919  +    pItem->iOrderByCol = 0;
   920    920       if( sqlite3ResolveExprNames(pNC, pE) ){
   921    921         return 1;
   922    922       }
   923    923     }
   924    924     return sqlite3ResolveOrderGroupBy(pParse, pSelect, pOrderBy, zType);
   925    925   }
   926    926   

Changes to src/select.c.

  2215   2215     ** the ORDER BY clause covers every term of the result set.  Add
  2216   2216     ** terms to the ORDER BY clause as necessary.
  2217   2217     */
  2218   2218     if( op!=TK_ALL ){
  2219   2219       for(i=1; db->mallocFailed==0 && i<=p->pEList->nExpr; i++){
  2220   2220         struct ExprList_item *pItem;
  2221   2221         for(j=0, pItem=pOrderBy->a; j<nOrderBy; j++, pItem++){
  2222         -        assert( pItem->iCol>0 );
  2223         -        if( pItem->iCol==i ) break;
         2222  +        assert( pItem->iOrderByCol>0 );
         2223  +        if( pItem->iOrderByCol==i ) break;
  2224   2224         }
  2225   2225         if( j==nOrderBy ){
  2226   2226           Expr *pNew = sqlite3Expr(db, TK_INTEGER, 0);
  2227   2227           if( pNew==0 ) return SQLITE_NOMEM;
  2228   2228           pNew->flags |= EP_IntValue;
  2229   2229           pNew->u.iValue = i;
  2230   2230           pOrderBy = sqlite3ExprListAppend(pParse, pOrderBy, pNew);
  2231         -        pOrderBy->a[nOrderBy++].iCol = (u16)i;
         2231  +        pOrderBy->a[nOrderBy++].iOrderByCol = (u16)i;
  2232   2232         }
  2233   2233       }
  2234   2234     }
  2235   2235   
  2236   2236     /* Compute the comparison permutation and keyinfo that is used with
  2237   2237     ** the permutation used to determine if the next
  2238   2238     ** row of results comes from selectA or selectB.  Also add explicit
................................................................................
  2240   2240     ** to the right and the left are evaluated, they use the correct
  2241   2241     ** collation.
  2242   2242     */
  2243   2243     aPermute = sqlite3DbMallocRaw(db, sizeof(int)*nOrderBy);
  2244   2244     if( aPermute ){
  2245   2245       struct ExprList_item *pItem;
  2246   2246       for(i=0, pItem=pOrderBy->a; i<nOrderBy; i++, pItem++){
  2247         -      assert( pItem->iCol>0  && pItem->iCol<=p->pEList->nExpr );
  2248         -      aPermute[i] = pItem->iCol - 1;
         2247  +      assert( pItem->iOrderByCol>0  && pItem->iOrderByCol<=p->pEList->nExpr );
         2248  +      aPermute[i] = pItem->iOrderByCol - 1;
  2249   2249       }
  2250   2250       pKeyMerge =
  2251   2251         sqlite3DbMallocRaw(db, sizeof(*pKeyMerge)+nOrderBy*(sizeof(CollSeq*)+1));
  2252   2252       if( pKeyMerge ){
  2253   2253         pKeyMerge->aSortOrder = (u8*)&pKeyMerge->aColl[nOrderBy];
  2254   2254         pKeyMerge->nField = (u16)nOrderBy;
  2255   2255         pKeyMerge->enc = ENC(db);
................................................................................
  2584   2584       }
  2585   2585     }
  2586   2586   }
  2587   2587   #endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */
  2588   2588   
  2589   2589   #if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
  2590   2590   /*
  2591         -** This routine attempts to flatten subqueries in order to speed
  2592         -** execution.  It returns 1 if it makes changes and 0 if no flattening
  2593         -** occurs.
         2591  +** This routine attempts to flatten subqueries as a performance optimization.
         2592  +** This routine returns 1 if it makes changes and 0 if no flattening occurs.
  2594   2593   **
  2595   2594   ** To understand the concept of flattening, consider the following
  2596   2595   ** query:
  2597   2596   **
  2598   2597   **     SELECT a FROM (SELECT x+y AS a FROM t1 WHERE z<100) WHERE a>5
  2599   2598   **
  2600   2599   ** The default way of implementing this query is to execute the
................................................................................
  2628   2627   **  (**)  At one point restrictions (4) and (5) defined a subset of DISTINCT
  2629   2628   **        sub-queries that were excluded from this optimization. Restriction 
  2630   2629   **        (4) has since been expanded to exclude all DISTINCT subqueries.
  2631   2630   **
  2632   2631   **   (6)  The subquery does not use aggregates or the outer query is not
  2633   2632   **        DISTINCT.
  2634   2633   **
  2635         -**   (7)  The subquery has a FROM clause.
         2634  +**   (7)  The subquery has a FROM clause.  TODO:  For subqueries without
         2635  +**        A FROM clause, consider adding a FROM close with the special
         2636  +**        table sqlite_once that consists of a single row containing a
         2637  +**        single NULL.
  2636   2638   **
  2637   2639   **   (8)  The subquery does not use LIMIT or the outer query is not a join.
  2638   2640   **
  2639   2641   **   (9)  The subquery does not use LIMIT or the outer query does not use
  2640   2642   **        aggregates.
  2641   2643   **
  2642   2644   **  (10)  The subquery does not use aggregates or the outer query does not
................................................................................
  2661   2663   **
  2662   2664   **  (17)  The sub-query is not a compound select, or it is a UNION ALL 
  2663   2665   **        compound clause made up entirely of non-aggregate queries, and 
  2664   2666   **        the parent query:
  2665   2667   **
  2666   2668   **          * is not itself part of a compound select,
  2667   2669   **          * is not an aggregate or DISTINCT query, and
  2668         -**          * has no other tables or sub-selects in the FROM clause.
         2670  +**          * is not a join
  2669   2671   **
  2670   2672   **        The parent and sub-query may contain WHERE clauses. Subject to
  2671   2673   **        rules (11), (13) and (14), they may also contain ORDER BY,
  2672         -**        LIMIT and OFFSET clauses.
         2674  +**        LIMIT and OFFSET clauses.  The subquery cannot use any compound
         2675  +**        operator other than UNION ALL because all the other compound
         2676  +**        operators have an implied DISTINCT which is disallowed by
         2677  +**        restriction (4).
  2673   2678   **
  2674   2679   **  (18)  If the sub-query is a compound select, then all terms of the
  2675   2680   **        ORDER by clause of the parent must be simple references to 
  2676   2681   **        columns of the sub-query.
  2677   2682   **
  2678   2683   **  (19)  The subquery does not use LIMIT or the outer query does not
  2679   2684   **        have a WHERE clause.
  2680   2685   **
  2681   2686   **  (20)  If the sub-query is a compound select, then it must not use
  2682   2687   **        an ORDER BY clause.  Ticket #3773.  We could relax this constraint
  2683   2688   **        somewhat by saying that the terms of the ORDER BY clause must
  2684         -**        appear as unmodified result columns in the outer query.  But
         2689  +**        appear as unmodified result columns in the outer query.  But we
  2685   2690   **        have other optimizations in mind to deal with that case.
  2686   2691   **
  2687   2692   **  (21)  The subquery does not use LIMIT or the outer query is not
  2688   2693   **        DISTINCT.  (See ticket [752e1646fc]).
  2689   2694   **
  2690   2695   ** In this routine, the "p" parameter is a pointer to the outer query.
  2691   2696   ** The subquery is p->pSrc->a[iFrom].  isAgg is true if the outer query
................................................................................
  2806   2811       }
  2807   2812       if( isAgg || (p->selFlags & SF_Distinct)!=0 || pSrc->nSrc!=1 ){
  2808   2813         return 0;
  2809   2814       }
  2810   2815       for(pSub1=pSub; pSub1; pSub1=pSub1->pPrior){
  2811   2816         testcase( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct );
  2812   2817         testcase( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))==SF_Aggregate );
         2818  +      assert( pSub->pSrc!=0 );
  2813   2819         if( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))!=0
  2814   2820          || (pSub1->pPrior && pSub1->op!=TK_ALL) 
  2815         -       || NEVER(pSub1->pSrc==0) || pSub1->pSrc->nSrc!=1
         2821  +       || pSub1->pSrc->nSrc<1
  2816   2822         ){
  2817   2823           return 0;
  2818   2824         }
         2825  +      testcase( pSub1->pSrc->nSrc>1 );
  2819   2826       }
  2820   2827   
  2821   2828       /* Restriction 18. */
  2822   2829       if( p->pOrderBy ){
  2823   2830         int ii;
  2824   2831         for(ii=0; ii<p->pOrderBy->nExpr; ii++){
  2825         -        if( p->pOrderBy->a[ii].iCol==0 ) return 0;
         2832  +        if( p->pOrderBy->a[ii].iOrderByCol==0 ) return 0;
  2826   2833         }
  2827   2834       }
  2828   2835     }
  2829   2836   
  2830   2837     /***** If we reach this point, flattening is permitted. *****/
  2831   2838   
  2832   2839     /* Authorize the subquery */
................................................................................
  3841   3848         int onceAddr = 0;
  3842   3849         int retAddr;
  3843   3850         assert( pItem->addrFillSub==0 );
  3844   3851         pItem->regReturn = ++pParse->nMem;
  3845   3852         topAddr = sqlite3VdbeAddOp2(v, OP_Integer, 0, pItem->regReturn);
  3846   3853         pItem->addrFillSub = topAddr+1;
  3847   3854         VdbeNoopComment((v, "materialize %s", pItem->pTab->zName));
  3848         -      if( pItem->isCorrelated==0 && pParse->pTriggerTab==0 ){
         3855  +      if( pItem->isCorrelated==0 ){
  3849   3856           /* If the subquery is no correlated and if we are not inside of
  3850   3857           ** a trigger, then we only need to compute the value of the subquery
  3851   3858           ** once. */
  3852         -        int regOnce = ++pParse->nMem;
  3853         -        onceAddr = sqlite3VdbeAddOp1(v, OP_Once, regOnce);
         3859  +        onceAddr = sqlite3CodeOnce(pParse);
  3854   3860         }
  3855   3861         sqlite3SelectDestInit(&dest, SRT_EphemTab, pItem->iCursor);
  3856   3862         explainSetInteger(pItem->iSelectId, (u8)pParse->iNextSelectId);
  3857   3863         sqlite3Select(pParse, pSub, &dest);
  3858   3864         pItem->pTab->nRowEst = (unsigned)pSub->nSelectRow;
  3859   3865         if( onceAddr ) sqlite3VdbeJumpHere(v, onceAddr);
  3860   3866         retAddr = sqlite3VdbeAddOp1(v, OP_Return, pItem->regReturn);
................................................................................
  4151   4157         pParse->nMem += pGroupBy->nExpr;
  4152   4158         iBMem = pParse->nMem + 1;
  4153   4159         pParse->nMem += pGroupBy->nExpr;
  4154   4160         sqlite3VdbeAddOp2(v, OP_Integer, 0, iAbortFlag);
  4155   4161         VdbeComment((v, "clear abort flag"));
  4156   4162         sqlite3VdbeAddOp2(v, OP_Integer, 0, iUseFlag);
  4157   4163         VdbeComment((v, "indicate accumulator empty"));
         4164  +      sqlite3VdbeAddOp3(v, OP_Null, 0, iAMem, iAMem+pGroupBy->nExpr-1);
  4158   4165   
  4159   4166         /* Begin a loop that will extract all source rows in GROUP BY order.
  4160   4167         ** This might involve two separate loops with an OP_Sort in between, or
  4161   4168         ** it might be a single loop that uses an index to extract information
  4162   4169         ** in the right order to begin with.
  4163   4170         */
  4164   4171         sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset);
................................................................................
  4490   4497     }
  4491   4498   
  4492   4499     sqlite3DbFree(db, sAggInfo.aCol);
  4493   4500     sqlite3DbFree(db, sAggInfo.aFunc);
  4494   4501     return rc;
  4495   4502   }
  4496   4503   
  4497         -#if defined(SQLITE_DEBUG)
         4504  +#if defined(SQLITE_ENABLE_TREE_EXPLAIN)
  4498   4505   void sqlite3PrintExpr(Expr *p);
  4499   4506   void sqlite3PrintExprList(ExprList *pList);
  4500   4507   void sqlite3PrintSelect(Select *p, int indent);
  4501   4508   /*
  4502         -*******************************************************************************
  4503         -** The following code is used for testing and debugging only.  The code
  4504         -** that follows does not appear in normal builds.
  4505         -**
  4506         -** These routines are used to print out the content of all or part of a 
  4507         -** parse structures such as Select or Expr.  Such printouts are useful
  4508         -** for helping to understand what is happening inside the code generator
  4509         -** during the execution of complex SELECT statements.
  4510         -**
  4511         -** These routine are not called anywhere from within the normal
  4512         -** code base.  Then are intended to be called from within the debugger
  4513         -** or from temporary "printf" statements inserted for debugging.
         4509  +** Generate a human-readable description of a the Select object.
  4514   4510   */
  4515         -void sqlite3PrintExpr(Expr *p){
  4516         -  if( !ExprHasProperty(p, EP_IntValue) && p->u.zToken ){
  4517         -    sqlite3DebugPrintf("(%s", p->u.zToken);
  4518         -  }else{
  4519         -    sqlite3DebugPrintf("(%d", p->op);
         4511  +static void explainOneSelect(Vdbe *pVdbe, Select *p){
         4512  +  sqlite3ExplainPrintf(pVdbe, "SELECT ");
         4513  +  if( p->selFlags & (SF_Distinct|SF_Aggregate) ){
         4514  +    if( p->selFlags & SF_Distinct ){
         4515  +      sqlite3ExplainPrintf(pVdbe, "DISTINCT ");
         4516  +    }
         4517  +    if( p->selFlags & SF_Aggregate ){
         4518  +      sqlite3ExplainPrintf(pVdbe, "agg_flag ");
         4519  +    }
         4520  +    sqlite3ExplainNL(pVdbe);
         4521  +    sqlite3ExplainPrintf(pVdbe, "   ");
  4520   4522     }
  4521         -  if( p->pLeft ){
  4522         -    sqlite3DebugPrintf(" ");
  4523         -    sqlite3PrintExpr(p->pLeft);
  4524         -  }
  4525         -  if( p->pRight ){
  4526         -    sqlite3DebugPrintf(" ");
  4527         -    sqlite3PrintExpr(p->pRight);
  4528         -  }
  4529         -  sqlite3DebugPrintf(")");
  4530         -}
  4531         -void sqlite3PrintExprList(ExprList *pList){
  4532         -  int i;
  4533         -  for(i=0; i<pList->nExpr; i++){
  4534         -    sqlite3PrintExpr(pList->a[i].pExpr);
  4535         -    if( i<pList->nExpr-1 ){
  4536         -      sqlite3DebugPrintf(", ");
  4537         -    }
  4538         -  }
  4539         -}
  4540         -void sqlite3PrintSelect(Select *p, int indent){
  4541         -  sqlite3DebugPrintf("%*sSELECT(%p) ", indent, "", p);
  4542         -  sqlite3PrintExprList(p->pEList);
  4543         -  sqlite3DebugPrintf("\n");
  4544         -  if( p->pSrc ){
  4545         -    char *zPrefix;
         4523  +  sqlite3ExplainExprList(pVdbe, p->pEList);
         4524  +  sqlite3ExplainNL(pVdbe);
         4525  +  if( p->pSrc && p->pSrc->nSrc ){
  4546   4526       int i;
  4547         -    zPrefix = "FROM";
         4527  +    sqlite3ExplainPrintf(pVdbe, "FROM ");
         4528  +    sqlite3ExplainPush(pVdbe);
  4548   4529       for(i=0; i<p->pSrc->nSrc; i++){
  4549   4530         struct SrcList_item *pItem = &p->pSrc->a[i];
  4550         -      sqlite3DebugPrintf("%*s ", indent+6, zPrefix);
  4551         -      zPrefix = "";
         4531  +      sqlite3ExplainPrintf(pVdbe, "{%d,*} = ", pItem->iCursor);
  4552   4532         if( pItem->pSelect ){
  4553         -        sqlite3DebugPrintf("(\n");
  4554         -        sqlite3PrintSelect(pItem->pSelect, indent+10);
  4555         -        sqlite3DebugPrintf("%*s)", indent+8, "");
         4533  +        sqlite3ExplainSelect(pVdbe, pItem->pSelect);
         4534  +        if( pItem->pTab ){
         4535  +          sqlite3ExplainPrintf(pVdbe, " (tabname=%s)", pItem->pTab->zName);
         4536  +        }
  4556   4537         }else if( pItem->zName ){
  4557         -        sqlite3DebugPrintf("%s", pItem->zName);
  4558         -      }
  4559         -      if( pItem->pTab ){
  4560         -        sqlite3DebugPrintf("(table: %s)", pItem->pTab->zName);
         4538  +        sqlite3ExplainPrintf(pVdbe, "%s", pItem->zName);
  4561   4539         }
  4562   4540         if( pItem->zAlias ){
  4563         -        sqlite3DebugPrintf(" AS %s", pItem->zAlias);
         4541  +        sqlite3ExplainPrintf(pVdbe, " (AS %s)", pItem->zAlias);
  4564   4542         }
  4565         -      if( i<p->pSrc->nSrc-1 ){
  4566         -        sqlite3DebugPrintf(",");
         4543  +      if( pItem->jointype & JT_LEFT ){
         4544  +        sqlite3ExplainPrintf(pVdbe, " LEFT-JOIN");
  4567   4545         }
  4568         -      sqlite3DebugPrintf("\n");
         4546  +      sqlite3ExplainNL(pVdbe);
  4569   4547       }
         4548  +    sqlite3ExplainPop(pVdbe);
  4570   4549     }
  4571   4550     if( p->pWhere ){
  4572         -    sqlite3DebugPrintf("%*s WHERE ", indent, "");
  4573         -    sqlite3PrintExpr(p->pWhere);
  4574         -    sqlite3DebugPrintf("\n");
         4551  +    sqlite3ExplainPrintf(pVdbe, "WHERE ");
         4552  +    sqlite3ExplainExpr(pVdbe, p->pWhere);
         4553  +    sqlite3ExplainNL(pVdbe);
  4575   4554     }
  4576   4555     if( p->pGroupBy ){
  4577         -    sqlite3DebugPrintf("%*s GROUP BY ", indent, "");
  4578         -    sqlite3PrintExprList(p->pGroupBy);
  4579         -    sqlite3DebugPrintf("\n");
         4556  +    sqlite3ExplainPrintf(pVdbe, "GROUPBY ");
         4557  +    sqlite3ExplainExprList(pVdbe, p->pGroupBy);
         4558  +    sqlite3ExplainNL(pVdbe);
  4580   4559     }
  4581   4560     if( p->pHaving ){
  4582         -    sqlite3DebugPrintf("%*s HAVING ", indent, "");
  4583         -    sqlite3PrintExpr(p->pHaving);
  4584         -    sqlite3DebugPrintf("\n");
         4561  +    sqlite3ExplainPrintf(pVdbe, "HAVING ");
         4562  +    sqlite3ExplainExpr(pVdbe, p->pHaving);
         4563  +    sqlite3ExplainNL(pVdbe);
  4585   4564     }
  4586   4565     if( p->pOrderBy ){
  4587         -    sqlite3DebugPrintf("%*s ORDER BY ", indent, "");
  4588         -    sqlite3PrintExprList(p->pOrderBy);
  4589         -    sqlite3DebugPrintf("\n");
         4566  +    sqlite3ExplainPrintf(pVdbe, "ORDERBY ");
         4567  +    sqlite3ExplainExprList(pVdbe, p->pOrderBy);
         4568  +    sqlite3ExplainNL(pVdbe);
         4569  +  }
         4570  +  if( p->pLimit ){
         4571  +    sqlite3ExplainPrintf(pVdbe, "LIMIT ");
         4572  +    sqlite3ExplainExpr(pVdbe, p->pLimit);
         4573  +    sqlite3ExplainNL(pVdbe);
         4574  +  }
         4575  +  if( p->pOffset ){
         4576  +    sqlite3ExplainPrintf(pVdbe, "OFFSET ");
         4577  +    sqlite3ExplainExpr(pVdbe, p->pOffset);
         4578  +    sqlite3ExplainNL(pVdbe);
         4579  +  }
         4580  +}
         4581  +void sqlite3ExplainSelect(Vdbe *pVdbe, Select *p){
         4582  +  if( p==0 ){
         4583  +    sqlite3ExplainPrintf(pVdbe, "(null-select)");
         4584  +    return;
         4585  +  }
         4586  +  while( p->pPrior ) p = p->pPrior;
         4587  +  sqlite3ExplainPush(pVdbe);
         4588  +  while( p ){
         4589  +    explainOneSelect(pVdbe, p);
         4590  +    p = p->pNext;
         4591  +    if( p==0 ) break;
         4592  +    sqlite3ExplainNL(pVdbe);
         4593  +    sqlite3ExplainPrintf(pVdbe, "%s\n", selectOpName(p->op));
  4590   4594     }
         4595  +  sqlite3ExplainPrintf(pVdbe, "END");
         4596  +  sqlite3ExplainPop(pVdbe);
  4591   4597   }
         4598  +
  4592   4599   /* End of the structure debug printing code
  4593   4600   *****************************************************************************/
  4594   4601   #endif /* defined(SQLITE_TEST) || defined(SQLITE_DEBUG) */

Changes to src/shell.c.

  1122   1122         }
  1123   1123   
  1124   1124         /* echo the sql statement if echo on */
  1125   1125         if( pArg && pArg->echoOn ){
  1126   1126           const char *zStmtSql = sqlite3_sql(pStmt);
  1127   1127           fprintf(pArg->out, "%s\n", zStmtSql ? zStmtSql : zSql);
  1128   1128         }
         1129  +
         1130  +      /* Output TESTCTRL_EXPLAIN text of requested */
         1131  +      if( pArg && pArg->mode==MODE_Explain ){
         1132  +        const char *zExplain = 0;
         1133  +        sqlite3_test_control(SQLITE_TESTCTRL_EXPLAIN_STMT, pStmt, &zExplain);
         1134  +        if( zExplain && zExplain[0] ){
         1135  +          fprintf(pArg->out, "%s", zExplain);
         1136  +        }
         1137  +      }
  1129   1138   
  1130   1139         /* perform the first step.  this will tell us if we
  1131   1140         ** have a result set or not and how wide it is.
  1132   1141         */
  1133   1142         rc = sqlite3_step(pStmt);
  1134   1143         /* if we have a result set... */
  1135   1144         if( SQLITE_ROW == rc ){
................................................................................
  1392   1401     ".separator STRING      Change separator used by output mode and .import\n"
  1393   1402     ".show                  Show the current values for various settings\n"
  1394   1403     ".stats ON|OFF          Turn stats on or off\n"
  1395   1404     ".tables ?TABLE?        List names of tables\n"
  1396   1405     "                         If TABLE specified, only list tables matching\n"
  1397   1406     "                         LIKE pattern TABLE.\n"
  1398   1407     ".timeout MS            Try opening locked tables for MS milliseconds\n"
         1408  +  ".vfsname ?AUX?         Print the name of the VFS stack\n"
  1399   1409     ".width NUM1 NUM2 ...   Set column widths for \"column\" mode\n"
  1400   1410   ;
  1401   1411   
  1402   1412   static char zTimerHelp[] =
  1403   1413     ".timer ON|OFF          Turn the CPU timer measurement on or off\n"
  1404   1414   ;
  1405   1415   
................................................................................
  2331   2341     if( HAS_TIMER && c=='t' && n>=5 && strncmp(azArg[0], "timer", n)==0
  2332   2342      && nArg==2
  2333   2343     ){
  2334   2344       enableTimer = booleanValue(azArg[1]);
  2335   2345     }else
  2336   2346     
  2337   2347     if( c=='v' && strncmp(azArg[0], "version", n)==0 ){
  2338         -    printf("SQLite %s %s\n",
         2348  +    printf("SQLite %s %s\n" /*extra-version-info*/,
  2339   2349           sqlite3_libversion(), sqlite3_sourceid());
  2340   2350     }else
         2351  +
         2352  +  if( c=='v' && strncmp(azArg[0], "vfsname", n)==0 ){
         2353  +    const char *zDbName = nArg==2 ? azArg[1] : "main";
         2354  +    char *zVfsName = 0;
         2355  +    if( p->db ){
         2356  +      sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFSNAME, &zVfsName);
         2357  +      if( zVfsName ){
         2358  +        printf("%s\n", zVfsName);
         2359  +        sqlite3_free(zVfsName);
         2360  +      }
         2361  +    }
         2362  +  }else
  2341   2363   
  2342   2364     if( c=='w' && strncmp(azArg[0], "width", n)==0 && nArg>1 ){
  2343   2365       int j;
  2344   2366       assert( nArg<=ArraySize(azArg) );
  2345   2367       for(j=1; j<nArg && j<ArraySize(p->colWidth); j++){
  2346   2368         p->colWidth[j-1] = atoi(azArg[j]);
  2347   2369       }
................................................................................
  2928   2950       /* Run commands received from standard input
  2929   2951       */
  2930   2952       if( stdin_is_interactive ){
  2931   2953         char *zHome;
  2932   2954         char *zHistory = 0;
  2933   2955         int nHistory;
  2934   2956         printf(
  2935         -        "SQLite version %s %.19s\n"
         2957  +        "SQLite version %s %.19s\n" /*extra-version-info*/
  2936   2958           "Enter \".help\" for instructions\n"
  2937   2959           "Enter SQL statements terminated with a \";\"\n",
  2938   2960           sqlite3_libversion(), sqlite3_sourceid()
  2939   2961         );
  2940   2962         zHome = find_home_dir();
  2941   2963         if( zHome ){
  2942   2964           nHistory = strlen30(zHome) + 20;

Changes to src/sqlite.h.in.

   168    168   const char *sqlite3_compileoption_get(int N);
   169    169   #endif
   170    170   
   171    171   /*
   172    172   ** CAPI3REF: Test To See If The Library Is Threadsafe
   173    173   **
   174    174   ** ^The sqlite3_threadsafe() function returns zero if and only if
   175         -** SQLite was compiled mutexing code omitted due to the
          175  +** SQLite was compiled with mutexing code omitted due to the
   176    176   ** [SQLITE_THREADSAFE] compile-time option being set to 0.
   177    177   **
   178    178   ** SQLite can be compiled with or without mutexes.  When
   179    179   ** the [SQLITE_THREADSAFE] C preprocessor macro is 1 or 2, mutexes
   180    180   ** are enabled and SQLite is threadsafe.  When the
   181    181   ** [SQLITE_THREADSAFE] macro is 0, 
   182    182   ** the mutexes are omitted.  Without the mutexes, it is not safe
................................................................................
   362    362   
   363    363   /*
   364    364   ** CAPI3REF: Result Codes
   365    365   ** KEYWORDS: SQLITE_OK {error code} {error codes}
   366    366   ** KEYWORDS: {result code} {result codes}
   367    367   **
   368    368   ** Many SQLite functions return an integer result code from the set shown
   369         -** here in order to indicates success or failure.
          369  +** here in order to indicate success or failure.
   370    370   **
   371    371   ** New error codes may be added in future versions of SQLite.
   372    372   **
   373    373   ** See also: [SQLITE_IOERR_READ | extended result codes],
   374    374   ** [sqlite3_vtab_on_conflict()] [SQLITE_ROLLBACK | result codes].
   375    375   */
   376    376   #define SQLITE_OK           0   /* Successful result */
................................................................................
   501    501   ** mean that writes of blocks that are nnn bytes in size and
   502    502   ** are aligned to an address which is an integer multiple of
   503    503   ** nnn are atomic.  The SQLITE_IOCAP_SAFE_APPEND value means
   504    504   ** that when data is appended to a file, the data is appended
   505    505   ** first then the size of the file is extended, never the other
   506    506   ** way around.  The SQLITE_IOCAP_SEQUENTIAL property means that
   507    507   ** information is written to disk in the same order as calls
   508         -** to xWrite().
          508  +** to xWrite().  The SQLITE_IOCAP_POWERSAFE_OVERWRITE property means that
          509  +** after reboot following a crash or power loss, the only bytes in a
          510  +** file that were written at the application level might have changed
          511  +** and that adjacent bytes, even bytes within the same sector are
          512  +** guaranteed to be unchanged.
   509    513   */
   510    514   #define SQLITE_IOCAP_ATOMIC                 0x00000001
   511    515   #define SQLITE_IOCAP_ATOMIC512              0x00000002
   512    516   #define SQLITE_IOCAP_ATOMIC1K               0x00000004
   513    517   #define SQLITE_IOCAP_ATOMIC2K               0x00000008
   514    518   #define SQLITE_IOCAP_ATOMIC4K               0x00000010
   515    519   #define SQLITE_IOCAP_ATOMIC8K               0x00000020
   516    520   #define SQLITE_IOCAP_ATOMIC16K              0x00000040
   517    521   #define SQLITE_IOCAP_ATOMIC32K              0x00000080
   518    522   #define SQLITE_IOCAP_ATOMIC64K              0x00000100
   519    523   #define SQLITE_IOCAP_SAFE_APPEND            0x00000200
   520    524   #define SQLITE_IOCAP_SEQUENTIAL             0x00000400
   521    525   #define SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN  0x00000800
          526  +#define SQLITE_IOCAP_POWERSAFE_OVERWRITE    0x00001000
   522    527   
   523    528   /*
   524    529   ** CAPI3REF: File Locking Levels
   525    530   **
   526    531   ** SQLite uses one of these integer values as the second
   527    532   ** argument to calls it makes to the xLock() and xUnlock() methods
   528    533   ** of an [sqlite3_io_methods] object.
................................................................................
   736    741   ** VFSes do not need this signal and should silently ignore this opcode.
   737    742   ** Applications should not call [sqlite3_file_control()] with this
   738    743   ** opcode as doing so may disrupt the operation of the specialized VFSes
   739    744   ** that do require it.  
   740    745   **
   741    746   ** ^The [SQLITE_FCNTL_WIN32_AV_RETRY] opcode is used to configure automatic
   742    747   ** retry counts and intervals for certain disk I/O operations for the
   743         -** windows [VFS] in order to work to provide robustness against
          748  +** windows [VFS] in order to provide robustness in the presence of
   744    749   ** anti-virus programs.  By default, the windows VFS will retry file read,
   745    750   ** file write, and file delete operations up to 10 times, with a delay
   746    751   ** of 25 milliseconds before the first retry and with the delay increasing
   747    752   ** by an additional 25 milliseconds with each subsequent retry.  This
   748         -** opcode allows those to values (10 retries and 25 milliseconds of delay)
          753  +** opcode allows these two values (10 retries and 25 milliseconds of delay)
   749    754   ** to be adjusted.  The values are changed for all database connections
   750    755   ** within the same process.  The argument is a pointer to an array of two
   751    756   ** integers where the first integer i the new retry count and the second
   752    757   ** integer is the delay.  If either integer is negative, then the setting
   753    758   ** is not changed but instead the prior value of that setting is written
   754    759   ** into the array entry, allowing the current retry settings to be
   755    760   ** interrogated.  The zDbName parameter is ignored.
................................................................................
   763    768   ** have write permission on the directory containing the database file want
   764    769   ** to read the database file, as the WAL and shared memory files must exist
   765    770   ** in order for the database to be readable.  The fourth parameter to
   766    771   ** [sqlite3_file_control()] for this opcode should be a pointer to an integer.
   767    772   ** That integer is 0 to disable persistent WAL mode or 1 to enable persistent
   768    773   ** WAL mode.  If the integer is -1, then it is overwritten with the current
   769    774   ** WAL persistence setting.
          775  +**
          776  +** ^The [SQLITE_FCNTL_POWERSAFE_OVERWRITE] opcode is used to set or query the
          777  +** persistent "powersafe-overwrite" or "PSOW" setting.  The PSOW setting
          778  +** determines the [SQLITE_IOCAP_POWERSAFE_OVERWRITE] bit of the
          779  +** xDeviceCharacteristics methods. The fourth parameter to
          780  +** [sqlite3_file_control()] for this opcode should be a pointer to an integer.
          781  +** That integer is 0 to disable zero-damage mode or 1 to enable zero-damage
          782  +** mode.  If the integer is -1, then it is overwritten with the current
          783  +** zero-damage mode setting.
   770    784   **
   771    785   ** ^The [SQLITE_FCNTL_OVERWRITE] opcode is invoked by SQLite after opening
   772    786   ** a write transaction to indicate that, unless it is rolled back for some
   773    787   ** reason, the entire database file will be overwritten by the current 
   774    788   ** transaction. This is used by VACUUM operations.
   775         -*/
   776         -#define SQLITE_FCNTL_LOCKSTATE           1
   777         -#define SQLITE_FCNTL_GET_LOCKPROXYFILE   2
   778         -#define SQLITE_FCNTL_SET_LOCKPROXYFILE   3
   779         -#define SQLITE_FCNTL_LAST_ERRNO          4
   780         -#define SQLITE_FCNTL_SIZE_HINT           5
   781         -#define SQLITE_FCNTL_CHUNK_SIZE          6
   782         -#define SQLITE_FCNTL_FILE_POINTER        7
   783         -#define SQLITE_FCNTL_SYNC_OMITTED        8
   784         -#define SQLITE_FCNTL_WIN32_AV_RETRY      9
   785         -#define SQLITE_FCNTL_PERSIST_WAL        10
   786         -#define SQLITE_FCNTL_OVERWRITE          11
   787         -
   788         -/* deprecated names */
   789         -#define SQLITE_GET_LOCKPROXYFILE      SQLITE_FCNTL_GET_LOCKPROXYFILE
   790         -#define SQLITE_SET_LOCKPROXYFILE      SQLITE_FCNTL_SET_LOCKPROXYFILE
   791         -#define SQLITE_LAST_ERRNO             SQLITE_FCNTL_LAST_ERRNO
          789  +**
          790  +** ^The [SQLITE_FCNTL_VFSNAME] opcode can be used to obtain the names of
          791  +** all [VFSes] in the VFS stack.  The names are of all VFS shims and the
          792  +** final bottom-level VFS are written into memory obtained from 
          793  +** [sqlite3_malloc()] and the result is stored in the char* variable
          794  +** that the fourth parameter of [sqlite3_file_control()] points to.
          795  +** The caller is responsible for freeing the memory when done.  As with
          796  +** all file-control actions, there is no guarantee that this will actually
          797  +** do anything.  Callers should initialize the char* variable to a NULL
          798  +** pointer in case this file-control is not implemented.  This file-control
          799  +** is intended for diagnostic use only.
          800  +*/
          801  +#define SQLITE_FCNTL_LOCKSTATE               1
          802  +#define SQLITE_GET_LOCKPROXYFILE             2
          803  +#define SQLITE_SET_LOCKPROXYFILE             3
          804  +#define SQLITE_LAST_ERRNO                    4
          805  +#define SQLITE_FCNTL_SIZE_HINT               5
          806  +#define SQLITE_FCNTL_CHUNK_SIZE              6
          807  +#define SQLITE_FCNTL_FILE_POINTER            7
          808  +#define SQLITE_FCNTL_SYNC_OMITTED            8
          809  +#define SQLITE_FCNTL_WIN32_AV_RETRY          9
          810  +#define SQLITE_FCNTL_PERSIST_WAL            10
          811  +#define SQLITE_FCNTL_OVERWRITE              11
          812  +#define SQLITE_FCNTL_VFSNAME                12
          813  +#define SQLITE_FCNTL_POWERSAFE_OVERWRITE    13
   792    814   
   793    815   /*
   794    816   ** CAPI3REF: Mutex Handle
   795    817   **
   796    818   ** The mutex module within SQLite defines [sqlite3_mutex] to be an
   797    819   ** abstract type for a mutex object.  The SQLite core never looks
   798    820   ** at the internal representation of an [sqlite3_mutex].  It only
................................................................................
   839    861   **
   840    862   ** [[sqlite3_vfs.xOpen]]
   841    863   ** ^SQLite guarantees that the zFilename parameter to xOpen
   842    864   ** is either a NULL pointer or string obtained
   843    865   ** from xFullPathname() with an optional suffix added.
   844    866   ** ^If a suffix is added to the zFilename parameter, it will
   845    867   ** consist of a single "-" character followed by no more than
   846         -** 10 alphanumeric and/or "-" characters.
          868  +** 11 alphanumeric and/or "-" characters.
   847    869   ** ^SQLite further guarantees that
   848    870   ** the string will be valid and unchanged until xClose() is
   849    871   ** called. Because of the previous sentence,
   850    872   ** the [sqlite3_file] can safely store a pointer to the
   851    873   ** filename if it needs to remember the filename for some reason.
   852    874   ** If the zFilename parameter to xOpen is a NULL pointer then xOpen
   853    875   ** must invent its own temporary name for the file.  ^Whenever the 
................................................................................
  1990   2012   ** ^The sqlite3_vsnprintf() routine is a varargs version of sqlite3_snprintf().
  1991   2013   **
  1992   2014   ** These routines all implement some additional formatting
  1993   2015   ** options that are useful for constructing SQL statements.
  1994   2016   ** All of the usual printf() formatting options apply.  In addition, there
  1995   2017   ** is are "%q", "%Q", and "%z" options.
  1996   2018   **
  1997         -** ^(The %q option works like %s in that it substitutes a null-terminated
         2019  +** ^(The %q option works like %s in that it substitutes a nul-terminated
  1998   2020   ** string from the argument list.  But %q also doubles every '\'' character.
  1999   2021   ** %q is designed for use inside a string literal.)^  By doubling each '\''
  2000   2022   ** character it escapes that character and allows it to be inserted into
  2001   2023   ** the string.
  2002   2024   **
  2003   2025   ** For example, assume the string variable zText contains text as follows:
  2004   2026   **
................................................................................
  2598   2620     int flags,              /* Flags */
  2599   2621     const char *zVfs        /* Name of VFS module to use */
  2600   2622   );
  2601   2623   
  2602   2624   /*
  2603   2625   ** CAPI3REF: Obtain Values For URI Parameters
  2604   2626   **
  2605         -** This is a utility routine, useful to VFS implementations, that checks
         2627  +** These are utility routines, useful to VFS implementations, that check
  2606   2628   ** to see if a database file was a URI that contained a specific query 
  2607         -** parameter, and if so obtains the value of the query parameter.
         2629  +** parameter, and if so obtains the value of that query parameter.
  2608   2630   **
  2609         -** The zFilename argument is the filename pointer passed into the xOpen()
  2610         -** method of a VFS implementation.  The zParam argument is the name of the
  2611         -** query parameter we seek.  This routine returns the value of the zParam
  2612         -** parameter if it exists.  If the parameter does not exist, this routine
  2613         -** returns a NULL pointer.
         2631  +** If F is the filename pointer passed into the xOpen() method of a VFS
         2632  +** implementation and P is the name of the query parameter, then
         2633  +** sqlite3_uri_parameter(F,P) returns the value of the P
         2634  +** parameter if it exists or a NULL pointer if P does not appear as a 
         2635  +** query parameter on F.  If P is a query parameter of F
         2636  +** has no explicit value, then sqlite3_uri_parameter(F,P) returns
         2637  +** a pointer to an empty string.
  2614   2638   **
  2615         -** If the zFilename argument to this function is not a pointer that SQLite
  2616         -** passed into the xOpen VFS method, then the behavior of this routine
  2617         -** is undefined and probably undesirable.
         2639  +** The sqlite3_uri_boolean(F,P,B) routine assumes that P is a boolean
         2640  +** parameter and returns true (1) or false (0) according to the value
         2641  +** of P.  The value of P is true if it is "yes" or "true" or "on" or 
         2642  +** a non-zero number and is false otherwise.  If P is not a query parameter
         2643  +** on F then sqlite3_uri_boolean(F,P,B) returns (B!=0).
         2644  +**
         2645  +** The sqlite3_uri_int64(F,P,D) routine converts the value of P into a
         2646  +** 64-bit signed integer and returns that integer, or D if P does not
         2647  +** exist.  If the value of P is something other than an integer, then
         2648  +** zero is returned.
         2649  +** 
         2650  +** If F is a NULL pointer, then sqlite3_uri_parameter(F,P) returns NULL and
         2651  +** sqlite3_uri_boolean(F,P,B) returns B.  If F is not a NULL pointer and
         2652  +** is not a pathname pointer that SQLite passed into the xOpen VFS method,
         2653  +** then the behavior of this routine is undefined and probably undesirable.
  2618   2654   */
  2619   2655   const char *sqlite3_uri_parameter(const char *zFilename, const char *zParam);
         2656  +int sqlite3_uri_boolean(const char *zFile, const char *zParam, int bDefault);
         2657  +sqlite3_int64 sqlite3_uri_int64(const char*, const char*, sqlite3_int64);
  2620   2658   
  2621   2659   
  2622   2660   /*
  2623   2661   ** CAPI3REF: Error Codes And Messages
  2624   2662   **
  2625   2663   ** ^The sqlite3_errcode() interface returns the numeric [result code] or
  2626   2664   ** [extended result code] for the most recent failed sqlite3_* API call
................................................................................
  3494   3532   ** ^The values returned by [sqlite3_column_bytes()] and 
  3495   3533   ** [sqlite3_column_bytes16()] do not include the zero terminators at the end
  3496   3534   ** of the string.  ^For clarity: the values returned by
  3497   3535   ** [sqlite3_column_bytes()] and [sqlite3_column_bytes16()] are the number of
  3498   3536   ** bytes in the string, not the number of characters.
  3499   3537   **
  3500   3538   ** ^Strings returned by sqlite3_column_text() and sqlite3_column_text16(),
  3501         -** even empty strings, are always zero terminated.  ^The return
         3539  +** even empty strings, are always zero-terminated.  ^The return
  3502   3540   ** value from sqlite3_column_blob() for a zero-length BLOB is a NULL pointer.
  3503   3541   **
  3504   3542   ** ^The object returned by [sqlite3_column_value()] is an
  3505   3543   ** [unprotected sqlite3_value] object.  An unprotected sqlite3_value object
  3506   3544   ** may only be used with [sqlite3_bind_value()] and [sqlite3_result_value()].
  3507   3545   ** If the [unprotected sqlite3_value] object returned by
  3508   3546   ** [sqlite3_column_value()] is used in any other way, including calls
................................................................................
  4579   4617   ** See also: [sqlite3_db_release_memory()]
  4580   4618   */
  4581   4619   int sqlite3_release_memory(int);
  4582   4620   
  4583   4621   /*
  4584   4622   ** CAPI3REF: Free Memory Used By A Database Connection
  4585   4623   **
  4586         -** ^The sqlite3_db_shrink(D) interface attempts to free as much heap
         4624  +** ^The sqlite3_db_release_memory(D) interface attempts to free as much heap
  4587   4625   ** memory as possible from database connection D. Unlike the
  4588   4626   ** [sqlite3_release_memory()] interface, this interface is effect even
  4589   4627   ** when then [SQLITE_ENABLE_MEMORY_MANAGEMENT] compile-time option is
  4590   4628   ** omitted.
  4591   4629   **
  4592   4630   ** See also: [sqlite3_release_memory()]
  4593   4631   */
................................................................................
  4603   4641   ** as heap memory usages approaches the limit.
  4604   4642   ** ^The soft heap limit is "soft" because even though SQLite strives to stay
  4605   4643   ** below the limit, it will exceed the limit rather than generate
  4606   4644   ** an [SQLITE_NOMEM] error.  In other words, the soft heap limit 
  4607   4645   ** is advisory only.
  4608   4646   **
  4609   4647   ** ^The return value from sqlite3_soft_heap_limit64() is the size of
  4610         -** the soft heap limit prior to the call.  ^If the argument N is negative
         4648  +** the soft heap limit prior to the call, or negative in the case of an
         4649  +** error.  ^If the argument N is negative
  4611   4650   ** then no change is made to the soft heap limit.  Hence, the current
  4612   4651   ** size of the soft heap limit can be determined by invoking
  4613   4652   ** sqlite3_soft_heap_limit64() with a negative argument.
  4614   4653   **
  4615   4654   ** ^If the argument N is zero then the soft heap limit is disabled.
  4616   4655   **
  4617   4656   ** ^(The soft heap limit is not enforced in the current implementation
................................................................................
  5559   5598   ** with the SQLITE_DEBUG flag.  ^External mutex implementations
  5560   5599   ** are only required to provide these routines if SQLITE_DEBUG is
  5561   5600   ** defined and if NDEBUG is not defined.
  5562   5601   **
  5563   5602   ** ^These routines should return true if the mutex in their argument
  5564   5603   ** is held or not held, respectively, by the calling thread.
  5565   5604   **
  5566         -** ^The implementation is not required to provided versions of these
         5605  +** ^The implementation is not required to provide versions of these
  5567   5606   ** routines that actually work. If the implementation does not provide working
  5568   5607   ** versions of these routines, it should at least provide stubs that always
  5569   5608   ** return true so that one does not get spurious assertion failures.
  5570   5609   **
  5571   5610   ** ^If the argument to sqlite3_mutex_held() is a NULL pointer then
  5572   5611   ** the routine should return 1.   This seems counter-intuitive since
  5573   5612   ** clearly the mutex cannot be held if it does not exist.  But
................................................................................
  5689   5728   #define SQLITE_TESTCTRL_ASSERT                  12
  5690   5729   #define SQLITE_TESTCTRL_ALWAYS                  13
  5691   5730   #define SQLITE_TESTCTRL_RESERVE                 14
  5692   5731   #define SQLITE_TESTCTRL_OPTIMIZATIONS           15
  5693   5732   #define SQLITE_TESTCTRL_ISKEYWORD               16
  5694   5733   #define SQLITE_TESTCTRL_SCRATCHMALLOC           17
  5695   5734   #define SQLITE_TESTCTRL_LOCALTIME_FAULT         18
  5696         -#define SQLITE_TESTCTRL_LAST                    18
         5735  +#define SQLITE_TESTCTRL_EXPLAIN_STMT            19
         5736  +#define SQLITE_TESTCTRL_LAST                    19
  5697   5737   
  5698   5738   /*
  5699   5739   ** CAPI3REF: SQLite Runtime Status
  5700   5740   **
  5701   5741   ** ^This interface is used to retrieve runtime status information
  5702   5742   ** about the performance of SQLite, and optionally to reset various
  5703   5743   ** highwater marks.  ^The first argument is an integer code for
................................................................................
  6040   6080   ** the application may discard the parameter after the call to
  6041   6081   ** [sqlite3_config()] returns.)^
  6042   6082   **
  6043   6083   ** [[the xInit() page cache method]]
  6044   6084   ** ^(The xInit() method is called once for each effective 
  6045   6085   ** call to [sqlite3_initialize()])^
  6046   6086   ** (usually only once during the lifetime of the process). ^(The xInit()
  6047         -** method is passed a copy of the sqlite3_pcache_methods.pArg value.)^
         6087  +** method is passed a copy of the sqlite3_pcache_methods2.pArg value.)^
  6048   6088   ** The intent of the xInit() method is to set up global data structures 
  6049   6089   ** required by the custom page cache implementation. 
  6050   6090   ** ^(If the xInit() method is NULL, then the 
  6051   6091   ** built-in default page cache is used instead of the application defined
  6052   6092   ** page cache.)^
  6053   6093   **
  6054   6094   ** [[the xShutdown() page cache method]]
................................................................................
  6066   6106   ** ^SQLite will never invoke xInit() more than once without an intervening
  6067   6107   ** call to xShutdown().
  6068   6108   **
  6069   6109   ** [[the xCreate() page cache methods]]
  6070   6110   ** ^SQLite invokes the xCreate() method to construct a new cache instance.
  6071   6111   ** SQLite will typically create one cache instance for each open database file,
  6072   6112   ** though this is not guaranteed. ^The
  6073         -** parameter parameter, szPage, is the size in bytes of the pages that must
         6113  +** first parameter, szPage, is the size in bytes of the pages that must
  6074   6114   ** be allocated by the cache.  ^szPage will always a power of two.  ^The
  6075   6115   ** second parameter szExtra is a number of bytes of extra storage 
  6076   6116   ** associated with each page cache entry.  ^The szExtra parameter will
  6077   6117   ** a number less than 250.  SQLite will use the
  6078   6118   ** extra szExtra bytes on each page to store metadata about the underlying
  6079   6119   ** database page on disk.  The value passed into szExtra depends
  6080   6120   ** on the SQLite version, the target platform, and how SQLite was compiled.
................................................................................
  6161   6201   ** of these pages are pinned, they are implicitly unpinned, meaning that
  6162   6202   ** they can be safely discarded.
  6163   6203   **
  6164   6204   ** [[the xDestroy() page cache method]]
  6165   6205   ** ^The xDestroy() method is used to delete a cache allocated by xCreate().
  6166   6206   ** All resources associated with the specified cache should be freed. ^After
  6167   6207   ** calling the xDestroy() method, SQLite considers the [sqlite3_pcache*]
  6168         -** handle invalid, and will not use it with any other sqlite3_pcache_methods
         6208  +** handle invalid, and will not use it with any other sqlite3_pcache_methods2
  6169   6209   ** functions.
  6170   6210   **
  6171   6211   ** [[the xShrink() page cache method]]
  6172   6212   ** ^SQLite invokes the xShrink() method when it wants the page cache to
  6173   6213   ** free up as much of heap memory as possible.  The page cache implementation
  6174   6214   ** is not obligated to free any memory, but well-behaved implementions should
  6175   6215   ** do their best.

Changes to src/sqliteInt.h.

   121    121   #if defined(THREADSAFE)
   122    122   # define SQLITE_THREADSAFE THREADSAFE
   123    123   #else
   124    124   # define SQLITE_THREADSAFE 1 /* IMP: R-07272-22309 */
   125    125   #endif
   126    126   #endif
   127    127   
          128  +/*
          129  +** Powersafe overwrite is on by default.  But can be turned off using
          130  +** the -DSQLITE_POWERSAFE_OVERWRITE=0 command-line option.
          131  +*/
          132  +#ifndef SQLITE_POWERSAFE_OVERWRITE
          133  +# define SQLITE_POWERSAFE_OVERWRITE 1
          134  +#endif
          135  +
   128    136   /*
   129    137   ** The SQLITE_DEFAULT_MEMSTATUS macro must be defined as either 0 or 1.
   130    138   ** It determines whether or not the features related to 
   131    139   ** SQLITE_CONFIG_MEMSTATUS are available by default or not. This value can
   132    140   ** be overridden at runtime using the sqlite3_config() API.
   133    141   */
   134    142   #if !defined(SQLITE_DEFAULT_MEMSTATUS)
................................................................................
  1713   1721   #define EP_VarSelect  0x0020  /* pSelect is correlated, not constant */
  1714   1722   #define EP_DblQuoted  0x0040  /* token.z was originally in "..." */
  1715   1723   #define EP_InfixFunc  0x0080  /* True for an infix function: LIKE, GLOB, etc */
  1716   1724   #define EP_ExpCollate 0x0100  /* Collating sequence specified explicitly */
  1717   1725   #define EP_FixedDest  0x0200  /* Result needed in a specific register */
  1718   1726   #define EP_IntValue   0x0400  /* Integer value contained in u.iValue */
  1719   1727   #define EP_xIsSelect  0x0800  /* x.pSelect is valid (otherwise x.pList is) */
  1720         -
  1721         -#define EP_Reduced    0x1000  /* Expr struct is EXPR_REDUCEDSIZE bytes only */
  1722         -#define EP_TokenOnly  0x2000  /* Expr struct is EXPR_TOKENONLYSIZE bytes only */
  1723         -#define EP_Static     0x4000  /* Held in memory not obtained from malloc() */
         1728  +#define EP_Hint       0x1000  /* Optimizer hint. Not required for correctness */
         1729  +#define EP_Reduced    0x2000  /* Expr struct is EXPR_REDUCEDSIZE bytes only */
         1730  +#define EP_TokenOnly  0x4000  /* Expr struct is EXPR_TOKENONLYSIZE bytes only */
         1731  +#define EP_Static     0x8000  /* Held in memory not obtained from malloc() */
  1724   1732   
  1725   1733   /*
  1726   1734   ** The following are the meanings of bits in the Expr.flags2 field.
  1727   1735   */
  1728   1736   #define EP2_MallocedToken  0x0001  /* Need to sqlite3DbFree() Expr.zToken */
  1729   1737   #define EP2_Irreducible    0x0002  /* Cannot EXPRDUP_REDUCE this Expr */
  1730   1738   
................................................................................
  1778   1786     int iECursor;          /* VDBE Cursor associated with this ExprList */
  1779   1787     struct ExprList_item {
  1780   1788       Expr *pExpr;           /* The list of expressions */
  1781   1789       char *zName;           /* Token associated with this expression */
  1782   1790       char *zSpan;           /* Original text of the expression */
  1783   1791       u8 sortOrder;          /* 1 for DESC or 0 for ASC */
  1784   1792       u8 done;               /* A flag to indicate when processing is finished */
  1785         -    u16 iCol;              /* For ORDER BY, column number in result set */
         1793  +    u16 iOrderByCol;       /* For ORDER BY, column number in result set */
  1786   1794       u16 iAlias;            /* Index into Parse.aAlias[] for zName */
  1787   1795     } *a;                  /* One entry for each expression */
  1788   1796   };
  1789   1797   
  1790   1798   /*
  1791   1799   ** An instance of this structure is used by the parser to record both
  1792   1800   ** the parse tree for an expression and the span of input text for an
................................................................................
  2210   2218     int aTempReg[8];     /* Holding area for temporary registers */
  2211   2219     int nRangeReg;       /* Size of the temporary register block */
  2212   2220     int iRangeReg;       /* First register in temporary register block */
  2213   2221     int nErr;            /* Number of errors seen */
  2214   2222     int nTab;            /* Number of previously allocated VDBE cursors */
  2215   2223     int nMem;            /* Number of memory cells used so far */
  2216   2224     int nSet;            /* Number of sets used so far */
         2225  +  int nOnce;           /* Number of OP_Once instructions so far */
  2217   2226     int ckBase;          /* Base register of data during check constraints */
  2218   2227     int iCacheLevel;     /* ColCache valid when aColCache[].iLevel<=iCacheLevel */
  2219   2228     int iCacheCnt;       /* Counter used to generate aColCache[].lru values */
  2220   2229     u8 nColCache;        /* Number of entries in aColCache[] */
  2221   2230     u8 iColCache;        /* Next entry in aColCache[] to replace */
  2222   2231     struct yColCache {
  2223   2232       int iTable;           /* Table cursor number */
................................................................................
  2656   2665   char *sqlite3MAppendf(sqlite3*,char*,const char*,...);
  2657   2666   #if defined(SQLITE_TEST) || defined(SQLITE_DEBUG)
  2658   2667     void sqlite3DebugPrintf(const char*, ...);
  2659   2668   #endif
  2660   2669   #if defined(SQLITE_TEST)
  2661   2670     void *sqlite3TestTextToPtr(const char*);
  2662   2671   #endif
         2672  +
         2673  +/* Output formatting for SQLITE_TESTCTRL_EXPLAIN */
         2674  +#if defined(SQLITE_ENABLE_TREE_EXPLAIN)
         2675  +  void sqlite3ExplainBegin(Vdbe*);
         2676  +  void sqlite3ExplainPrintf(Vdbe*, const char*, ...);
         2677  +  void sqlite3ExplainNL(Vdbe*);
         2678  +  void sqlite3ExplainPush(Vdbe*);
         2679  +  void sqlite3ExplainPop(Vdbe*);
         2680  +  void sqlite3ExplainFinish(Vdbe*);
         2681  +  void sqlite3ExplainSelect(Vdbe*, Select*);
         2682  +  void sqlite3ExplainExpr(Vdbe*, Expr*);
         2683  +  void sqlite3ExplainExprList(Vdbe*, ExprList*);
         2684  +  const char *sqlite3VdbeExplanation(Vdbe*);
         2685  +#else
         2686  +# define sqlite3ExplainBegin(X)
         2687  +# define sqlite3ExplainSelect(A,B)
         2688  +# define sqlite3ExplainExpr(A,B)
         2689  +# define sqlite3ExplainExprList(A,B)
         2690  +# define sqlite3ExplainFinish(X)
         2691  +# define sqlite3VdbeExplanation(X) 0
         2692  +#endif
         2693  +
         2694  +
  2663   2695   void sqlite3SetString(char **, sqlite3*, const char*, ...);
  2664   2696   void sqlite3ErrorMsg(Parse*, const char*, ...);
  2665   2697   int sqlite3Dequote(char*);
  2666   2698   int sqlite3KeywordCode(const unsigned char*, int);
  2667   2699   int sqlite3RunParser(Parse*, const char*, char **);
  2668   2700   void sqlite3FinishCoding(Parse*);
  2669   2701   int sqlite3GetTempReg(Parse*);
................................................................................
  2698   2730   void sqlite3AddCheckConstraint(Parse*, Expr*);
  2699   2731   void sqlite3AddColumnType(Parse*,Token*);
  2700   2732   void sqlite3AddDefaultValue(Parse*,ExprSpan*);
  2701   2733   void sqlite3AddCollateType(Parse*, Token*);
  2702   2734   void sqlite3EndTable(Parse*,Token*,Token*,Select*);
  2703   2735   int sqlite3ParseUri(const char*,const char*,unsigned int*,
  2704   2736                       sqlite3_vfs**,char**,char **);
         2737  +int sqlite3CodeOnce(Parse *);
  2705   2738   
  2706   2739   Bitvec *sqlite3BitvecCreate(u32);
  2707   2740   int sqlite3BitvecTest(Bitvec*, u32);
  2708   2741   int sqlite3BitvecSet(Bitvec*, u32);
  2709   2742   void sqlite3BitvecClear(Bitvec*, u32, void*);
  2710   2743   void sqlite3BitvecDestroy(Bitvec*);
  2711   2744   u32 sqlite3BitvecSize(Bitvec*);
................................................................................
  3036   3069     FuncDestructor *pDestructor
  3037   3070   );
  3038   3071   int sqlite3ApiExit(sqlite3 *db, int);
  3039   3072   int sqlite3OpenTempDatabase(Parse *);
  3040   3073   
  3041   3074   void sqlite3StrAccumInit(StrAccum*, char*, int, int);
  3042   3075   void sqlite3StrAccumAppend(StrAccum*,const char*,int);
         3076  +void sqlite3AppendSpace(StrAccum*,int);
  3043   3077   char *sqlite3StrAccumFinish(StrAccum*);
  3044   3078   void sqlite3StrAccumReset(StrAccum*);
  3045   3079   void sqlite3SelectDestInit(SelectDest*,int,int);
  3046   3080   Expr *sqlite3CreateColumnExpr(sqlite3 *, SrcList *, int, int);
  3047   3081   
  3048   3082   void sqlite3BackupRestart(sqlite3_backup *);
  3049   3083   void sqlite3BackupUpdate(sqlite3_backup *, Pgno, const u8 *);

Changes to src/tclsqlite.c.

  2996   2996         int b;
  2997   2997         if( Tcl_GetBooleanFromObj(interp, objv[i+1], &b) ) return TCL_ERROR;
  2998   2998         if( b ){
  2999   2999           flags |= SQLITE_OPEN_FULLMUTEX;
  3000   3000           flags &= ~SQLITE_OPEN_NOMUTEX;
  3001   3001         }else{
  3002   3002           flags &= ~SQLITE_OPEN_FULLMUTEX;
         3003  +      }
         3004  +    }else if( strcmp(zArg, "-uri")==0 ){
         3005  +      int b;
         3006  +      if( Tcl_GetBooleanFromObj(interp, objv[i+1], &b) ) return TCL_ERROR;
         3007  +      if( b ){
         3008  +        flags |= SQLITE_OPEN_URI;
         3009  +      }else{
         3010  +        flags &= ~SQLITE_OPEN_URI;
  3003   3011         }
  3004   3012       }else{
  3005   3013         Tcl_AppendResult(interp, "unknown option: ", zArg, (char*)0);
  3006   3014         return TCL_ERROR;
  3007   3015       }
  3008   3016     }
  3009   3017     if( objc<3 || (objc&1)!=1 ){

Changes to src/test1.c.

  5419   5419     }
  5420   5420     if( Tcl_GetIntFromObj(interp, objv[2], &bPersist) ) return TCL_ERROR;
  5421   5421     rc = sqlite3_file_control(db, NULL, SQLITE_FCNTL_PERSIST_WAL, (void*)&bPersist);
  5422   5422     sqlite3_snprintf(sizeof(z), z, "%d %d", rc, bPersist);
  5423   5423     Tcl_AppendResult(interp, z, (char*)0);
  5424   5424     return TCL_OK;  
  5425   5425   }
         5426  +/*
         5427  +** tclcmd:   file_control_powersafe_overwrite DB PSOW-FLAG
         5428  +**
         5429  +** This TCL command runs the sqlite3_file_control interface with
         5430  +** the SQLITE_FCNTL_POWERSAFE_OVERWRITE opcode.
         5431  +*/
         5432  +static int file_control_powersafe_overwrite(
         5433  +  ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
         5434  +  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
         5435  +  int objc,              /* Number of arguments */
         5436  +  Tcl_Obj *CONST objv[]  /* Command arguments */
         5437  +){
         5438  +  sqlite3 *db;
         5439  +  int rc;
         5440  +  int b;
         5441  +  char z[100];
         5442  +
         5443  +  if( objc!=3 ){
         5444  +    Tcl_AppendResult(interp, "wrong # args: should be \"",
         5445  +        Tcl_GetStringFromObj(objv[0], 0), " DB FLAG", 0);
         5446  +    return TCL_ERROR;
         5447  +  }
         5448  +  if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ){
         5449  +    return TCL_ERROR;
         5450  +  }
         5451  +  if( Tcl_GetIntFromObj(interp, objv[2], &b) ) return TCL_ERROR;
         5452  +  rc = sqlite3_file_control(db,NULL,SQLITE_FCNTL_POWERSAFE_OVERWRITE,(void*)&b);
         5453  +  sqlite3_snprintf(sizeof(z), z, "%d %d", rc, b);
         5454  +  Tcl_AppendResult(interp, z, (char*)0);
         5455  +  return TCL_OK;  
         5456  +}
         5457  +
         5458  +
         5459  +/*
         5460  +** tclcmd:   file_control_vfsname DB ?AUXDB?
         5461  +**
         5462  +** Return a string that describes the stack of VFSes.
         5463  +*/
         5464  +static int file_control_vfsname(
         5465  +  ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
         5466  +  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
         5467  +  int objc,              /* Number of arguments */
         5468  +  Tcl_Obj *CONST objv[]  /* Command arguments */
         5469  +){
         5470  +  sqlite3 *db;
         5471  +  const char *zDbName = "main";
         5472  +  char *zVfsName = 0;
         5473  +
         5474  +  if( objc!=2 && objc!=3 ){
         5475  +    Tcl_AppendResult(interp, "wrong # args: should be \"",
         5476  +        Tcl_GetStringFromObj(objv[0], 0), " DB ?AUXDB?", 0);
         5477  +    return TCL_ERROR;
         5478  +  }
         5479  +  if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ){
         5480  +    return TCL_ERROR;
         5481  +  }
         5482  +  if( objc==3 ){
         5483  +    zDbName = Tcl_GetString(objv[2]);
         5484  +  }
         5485  +  sqlite3_file_control(db, zDbName, SQLITE_FCNTL_VFSNAME,(void*)&zVfsName);
         5486  +  Tcl_AppendResult(interp, zVfsName, (char*)0);
         5487  +  sqlite3_free(zVfsName);
         5488  +  return TCL_OK;  
         5489  +}
         5490  +
  5426   5491   
  5427   5492   /*
  5428   5493   ** tclcmd:   sqlite3_vfs_list
  5429   5494   **
  5430   5495   **   Return a tcl list containing the names of all registered vfs's.
  5431   5496   */
  5432   5497   static int vfs_list(
................................................................................
  6249   6314        { "file_control_truncate_test", file_control_truncate_test,  0   },
  6250   6315        { "file_control_replace_test", file_control_replace_test,  0   },
  6251   6316   #endif 
  6252   6317        { "file_control_chunksize_test", file_control_chunksize_test,  0   },
  6253   6318        { "file_control_sizehint_test",  file_control_sizehint_test,   0   },
  6254   6319        { "file_control_win32_av_retry", file_control_win32_av_retry,  0   },
  6255   6320        { "file_control_persist_wal",    file_control_persist_wal,     0   },
  6256         -     { "file_control_persist_wal",    file_control_persist_wal,     0   },
         6321  +     { "file_control_powersafe_overwrite",file_control_powersafe_overwrite,0},
         6322  +     { "file_control_vfsname",        file_control_vfsname,         0   },
  6257   6323        { "sqlite3_vfs_list",           vfs_list,     0   },
  6258   6324        { "sqlite3_create_function_v2", test_create_function_v2, 0 },
  6259   6325        { "path_is_local",              path_is_local,  0   },
  6260   6326        { "path_is_dos",                path_is_dos,  0   },
  6261   6327   
  6262   6328        /* Functions from os.h */
  6263   6329   #ifndef SQLITE_OMIT_UTF16

Changes to src/test6.c.

   701    701     int *piDeviceChar,
   702    702     int *piSectorSize
   703    703   ){
   704    704     struct DeviceFlag {
   705    705       char *zName;
   706    706       int iValue;
   707    707     } aFlag[] = {
   708         -    { "atomic",      SQLITE_IOCAP_ATOMIC      },
   709         -    { "atomic512",   SQLITE_IOCAP_ATOMIC512   },
   710         -    { "atomic1k",    SQLITE_IOCAP_ATOMIC1K    },
   711         -    { "atomic2k",    SQLITE_IOCAP_ATOMIC2K    },
   712         -    { "atomic4k",    SQLITE_IOCAP_ATOMIC4K    },
   713         -    { "atomic8k",    SQLITE_IOCAP_ATOMIC8K    },
   714         -    { "atomic16k",   SQLITE_IOCAP_ATOMIC16K   },
   715         -    { "atomic32k",   SQLITE_IOCAP_ATOMIC32K   },
   716         -    { "atomic64k",   SQLITE_IOCAP_ATOMIC64K   },
   717         -    { "sequential",  SQLITE_IOCAP_SEQUENTIAL  },
   718         -    { "safe_append", SQLITE_IOCAP_SAFE_APPEND },
          708  +    { "atomic",              SQLITE_IOCAP_ATOMIC                },
          709  +    { "atomic512",           SQLITE_IOCAP_ATOMIC512             },
          710  +    { "atomic1k",            SQLITE_IOCAP_ATOMIC1K              },
          711  +    { "atomic2k",            SQLITE_IOCAP_ATOMIC2K              },
          712  +    { "atomic4k",            SQLITE_IOCAP_ATOMIC4K              },
          713  +    { "atomic8k",            SQLITE_IOCAP_ATOMIC8K              },
          714  +    { "atomic16k",           SQLITE_IOCAP_ATOMIC16K             },
          715  +    { "atomic32k",           SQLITE_IOCAP_ATOMIC32K             },
          716  +    { "atomic64k",           SQLITE_IOCAP_ATOMIC64K             },
          717  +    { "sequential",          SQLITE_IOCAP_SEQUENTIAL            },
          718  +    { "safe_append",         SQLITE_IOCAP_SAFE_APPEND           },
          719  +    { "powersafe_overwrite", SQLITE_IOCAP_POWERSAFE_OVERWRITE   },
   719    720       { 0, 0 }
   720    721     };
   721    722   
   722    723     int i;
   723    724     int iDc = 0;
   724    725     int iSectorSize = 0;
   725    726     int setSectorsize = 0;

Changes to src/test_journal.c.

   387    387           }
   388    388         }
   389    389       }
   390    390       iTrunk = decodeUint32(&aData[32]);
   391    391       while( rc==SQLITE_OK && iTrunk>0 ){
   392    392         u32 nLeaf;
   393    393         u32 iLeaf;
   394         -      sqlite3_int64 iOff = (iTrunk-1)*pMain->nPagesize;
          394  +      sqlite3_int64 iOff = (i64)(iTrunk-1)*pMain->nPagesize;
   395    395         rc = sqlite3OsRead(p, aData, pMain->nPagesize, iOff);
   396    396         nLeaf = decodeUint32(&aData[4]);
   397    397         for(iLeaf=0; rc==SQLITE_OK && iLeaf<nLeaf; iLeaf++){
   398    398           u32 pgno = decodeUint32(&aData[8+4*iLeaf]);
   399    399           sqlite3BitvecSet(pMain->pWritable, pgno);
   400    400         }
   401    401         iTrunk = decodeUint32(aData);

Changes to src/test_multiplex.c.

    77     77   #define sqlite3_mutex_enter(X)
    78     78   #define sqlite3_mutex_try(X)      SQLITE_OK
    79     79   #define sqlite3_mutex_leave(X)
    80     80   #define sqlite3_mutex_held(X)     ((void)(X),1)
    81     81   #define sqlite3_mutex_notheld(X)  ((void)(X),1)
    82     82   #endif /* SQLITE_THREADSAFE==0 */
    83     83   
           84  +/* First chunk for rollback journal files */
           85  +#define SQLITE_MULTIPLEX_JOURNAL_8_3_OFFSET 400
           86  +
    84     87   
    85     88   /************************ Shim Definitions ******************************/
    86     89   
    87     90   #ifndef SQLITE_MULTIPLEX_VFS_NAME
    88     91   # define SQLITE_MULTIPLEX_VFS_NAME "multiplex"
    89     92   #endif
    90     93   
................................................................................
    93     96   ** multiple of MAX_PAGE_SIZE.  We default it here to 2GiB less 64KiB.
    94     97   */
    95     98   #ifndef SQLITE_MULTIPLEX_CHUNK_SIZE
    96     99   # define SQLITE_MULTIPLEX_CHUNK_SIZE 2147418112
    97    100   #endif
    98    101   
    99    102   /* This used to be the default limit on number of chunks, but
   100         -** it is no longer enforced.  There is currently no limit to the
          103  +** it is no longer enforced. There is currently no limit to the
   101    104   ** number of chunks.
   102    105   **
   103    106   ** May be changed by calling the xFileControl() interface.
   104    107   */
   105    108   #ifndef SQLITE_MULTIPLEX_MAX_CHUNKS
   106    109   # define SQLITE_MULTIPLEX_MAX_CHUNKS 12
   107    110   #endif
................................................................................
   126    129       char *z;                          /* Name of this chunk */
   127    130     } *aReal;                        /* list of all chunks */
   128    131     int nReal;                       /* Number of chunks */
   129    132     char *zName;                     /* Base filename of this group */
   130    133     int nName;                       /* Length of base filename */
   131    134     int flags;                       /* Flags used for original opening */
   132    135     unsigned int szChunk;            /* Chunk size used for this group */
   133         -  int bEnabled;                    /* TRUE to use Multiplex VFS for this file */
          136  +  unsigned char bEnabled;          /* TRUE to use Multiplex VFS for this file */
          137  +  unsigned char bTruncate;         /* TRUE to enable truncation of databases */
   134    138     multiplexGroup *pNext, *pPrev;   /* Doubly linked list of all group objects */
   135    139   };
   136    140   
   137    141   /*
   138    142   ** An instance of the following object represents each open connection
   139    143   ** to a file that is multiplex'ed.  This object is a 
   140    144   ** subclass of sqlite3_file.  The sqlite3_file object for the underlying
................................................................................
   210    214     const char *z2 = z;
   211    215     if( z==0 ) return 0;
   212    216     while( *z2 ){ z2++; }
   213    217     return 0x3fffffff & (int)(z2 - z);
   214    218   }
   215    219   
   216    220   /*
   217         -** Create a temporary file name in zBuf.  zBuf must be big enough to
   218         -** hold at pOrigVfs->mxPathname characters.  This function departs
   219         -** from the traditional temporary name generation in the os_win
   220         -** and os_unix VFS in several ways, but is necessary so that 
   221         -** the file name is known for temporary files (like those used 
   222         -** during vacuum.)
   223         -**
   224         -** N.B. This routine assumes your underlying VFS is ok with using
   225         -** "/" as a directory seperator.  This is the default for UNIXs
   226         -** and is allowed (even mixed) for most versions of Windows.
   227         -*/
   228         -static int multiplexGetTempname(sqlite3_vfs *pOrigVfs, int nBuf, char *zBuf){
   229         -  static char zChars[] =
   230         -    "abcdefghijklmnopqrstuvwxyz"
   231         -    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
   232         -    "0123456789";
   233         -  int i,j;
   234         -  int attempts = 0;
   235         -  int exists = 0;
   236         -  int rc = SQLITE_ERROR;
   237         -
   238         -  /* Check that the output buffer is large enough for 
   239         -  ** pVfs->mxPathname characters.
   240         -  */
   241         -  if( pOrigVfs->mxPathname <= nBuf ){
   242         -    char *zTmp = sqlite3_malloc(pOrigVfs->mxPathname);
   243         -    if( zTmp==0 ) return SQLITE_NOMEM;
   244         -
   245         -    /* sqlite3_temp_directory should always be less than
   246         -    ** pVfs->mxPathname characters.
   247         -    */
   248         -    sqlite3_snprintf(pOrigVfs->mxPathname,
   249         -                     zTmp,
   250         -                     "%s/",
   251         -                     sqlite3_temp_directory ? sqlite3_temp_directory : ".");
   252         -    rc = pOrigVfs->xFullPathname(pOrigVfs, zTmp, nBuf, zBuf);
   253         -    sqlite3_free(zTmp);
   254         -    if( rc ) return rc;
   255         -
   256         -    /* Check that the output buffer is large enough for the temporary file 
   257         -    ** name.
   258         -    */
   259         -    j = multiplexStrlen30(zBuf);
   260         -    if( (j + 8 + 1 + 3 + 1) <= nBuf ){
   261         -      /* Make 3 attempts to generate a unique name. */
   262         -      do {
   263         -        attempts++;
   264         -        sqlite3_randomness(8, &zBuf[j]);
   265         -        for(i=0; i<8; i++){
   266         -          unsigned char uc = (unsigned char)zBuf[j+i];
   267         -          zBuf[j+i] = (char)zChars[uc%(sizeof(zChars)-1)];
   268         -        }
   269         -        memcpy(&zBuf[j+i], ".tmp", 5);
   270         -        rc = pOrigVfs->xAccess(pOrigVfs, zBuf, SQLITE_ACCESS_EXISTS, &exists);
   271         -      } while ( (rc==SQLITE_OK) && exists && (attempts<3) );
   272         -      if( rc==SQLITE_OK && exists ){
   273         -        rc = SQLITE_ERROR;
   274         -      }
   275         -    }
   276         -  }
   277         -
   278         -  return rc;
          221  +** Generate the file-name for chunk iChunk of the group with base name
          222  +** zBase. The file-name is written to buffer zOut before returning. Buffer
          223  +** zOut must be allocated by the caller so that it is at least (nBase+4)
          224  +** bytes in size, where nBase is the length of zBase, not including the
          225  +** nul-terminator.
          226  +*/
          227  +static void multiplexFilename(
          228  +  const char *zBase,              /* Filename for chunk 0 */
          229  +  int nBase,                      /* Size of zBase in bytes (without \0) */
          230  +  int flags,                      /* Flags used to open file */
          231  +  int iChunk,                     /* Chunk to generate filename for */
          232  +  char *zOut                      /* Buffer to write generated name to */
          233  +){
          234  +  memcpy(zOut, zBase, nBase+1);
          235  +  if( iChunk!=0 && iChunk!=SQLITE_MULTIPLEX_JOURNAL_8_3_OFFSET ){
          236  +    int n = nBase;
          237  +#ifdef SQLITE_ENABLE_8_3_NAMES
          238  +    int i;
          239  +    for(i=n-1; i>0 && i>=n-4 && zOut[i]!='.'; i--){}
          240  +    if( i>=n-4 ) n = i+1;
          241  +    if( flags & SQLITE_OPEN_MAIN_JOURNAL ){
          242  +      /* The extensions on overflow files for main databases are 001, 002,
          243  +       ** 003 and so forth.  To avoid name collisions, add 400 to the 
          244  +       ** extensions of journal files so that they are 401, 402, 403, ....
          245  +       */
          246  +      iChunk += SQLITE_MULTIPLEX_JOURNAL_8_3_OFFSET;
          247  +    }
          248  +#endif
          249  +    sqlite3_snprintf(4,&zOut[n],"%03d",iChunk);
          250  +  }
   279    251   }
   280    252   
   281    253   /* Compute the filename for the iChunk-th chunk
   282    254   */
   283    255   static int multiplexSubFilename(multiplexGroup *pGroup, int iChunk){
   284    256     if( iChunk>=pGroup->nReal ){
   285    257       struct multiplexReal *p;
................................................................................
   287    259       if( p==0 ){
   288    260         return SQLITE_NOMEM;
   289    261       }
   290    262       memset(&p[pGroup->nReal], 0, sizeof(p[0])*(iChunk+1-pGroup->nReal));
   291    263       pGroup->aReal = p;
   292    264       pGroup->nReal = iChunk+1;
   293    265     }
   294         -  if( pGroup->aReal[iChunk].z==0 ){
          266  +  if( pGroup->zName && pGroup->aReal[iChunk].z==0 ){
   295    267       char *z;
   296    268       int n = pGroup->nName;
   297    269       pGroup->aReal[iChunk].z = z = sqlite3_malloc( n+4 );
   298    270       if( z==0 ){
   299    271         return SQLITE_NOMEM;
   300    272       }
   301         -    memcpy(z, pGroup->zName, n+1);
   302         -    if( iChunk>0 ){
   303         -#ifdef SQLITE_ENABLE_8_3_NAMES
   304         -      int i;
   305         -      for(i=n-1; i>0 && i>=n-4 && z[i]!='.'; i--){}
   306         -      if( i>=n-4 ) n = i+1;
   307         -#endif
   308         -      sqlite3_snprintf(4,&z[n],"%03d",iChunk);
   309         -    }
          273  +    multiplexFilename(pGroup->zName, pGroup->nName, pGroup->flags, iChunk, z);
   310    274     }
   311    275     return SQLITE_OK;
   312    276   }
   313    277   
   314    278   /* Translate an sqlite3_file* that is really a multiplexGroup* into
   315    279   ** the sqlite3_file* for the underlying original VFS.
          280  +**
          281  +** For chunk 0, the pGroup->flags determines whether or not a new file
          282  +** is created if it does not already exist.  For chunks 1 and higher, the
          283  +** file is created only if createFlag is 1.
   316    284   */
   317    285   static sqlite3_file *multiplexSubOpen(
   318         -  multiplexGroup *pGroup,
   319         -  int iChunk,
   320         -  int *rc,
   321         -  int *pOutFlags
          286  +  multiplexGroup *pGroup,    /* The multiplexor group */
          287  +  int iChunk,                /* Which chunk to open.  0==original file */
          288  +  int *rc,                   /* Result code in and out */
          289  +  int *pOutFlags,            /* Output flags */
          290  +  int createFlag             /* True to create if iChunk>0 */
   322    291   ){
   323    292     sqlite3_file *pSubOpen = 0;
   324    293     sqlite3_vfs *pOrigVfs = gMultiplex.pOrigVfs;        /* Real VFS */
          294  +
          295  +#ifdef SQLITE_ENABLE_8_3_NAMES
          296  +  /* If JOURNAL_8_3_OFFSET is set to (say) 400, then any overflow files are 
          297  +  ** part of a database journal are named db.401, db.402, and so on. A 
          298  +  ** database may therefore not grow to larger than 400 chunks. Attempting
          299  +  ** to open chunk 401 indicates the database is full. */
          300  +  if( iChunk>=SQLITE_MULTIPLEX_JOURNAL_8_3_OFFSET ){
          301  +    *rc = SQLITE_FULL;
          302  +    return 0;
          303  +  }
          304  +#endif
          305  +
   325    306     *rc = multiplexSubFilename(pGroup, iChunk);
   326    307     if( (*rc)==SQLITE_OK && (pSubOpen = pGroup->aReal[iChunk].p)==0 ){
          308  +    int flags, bExists;
          309  +    createFlag = (pGroup->flags & SQLITE_OPEN_CREATE)!=0;
          310  +    flags = pGroup->flags;
          311  +    if( createFlag ){
          312  +      flags |= SQLITE_OPEN_CREATE;
          313  +    }else if( iChunk==0 ){
          314  +      /* Fall through */
          315  +    }else if( pGroup->aReal[iChunk].z==0 ){
          316  +      return 0;
          317  +    }else{
          318  +      *rc = pOrigVfs->xAccess(pOrigVfs, pGroup->aReal[iChunk].z,
          319  +                              SQLITE_ACCESS_EXISTS, &bExists);
          320  +      if( *rc || !bExists ) return 0;
          321  +      flags &= ~SQLITE_OPEN_CREATE;
          322  +    }
   327    323       pSubOpen = sqlite3_malloc( pOrigVfs->szOsFile );
   328    324       if( pSubOpen==0 ){
   329         -      *rc = SQLITE_NOMEM;
          325  +      *rc = SQLITE_IOERR_NOMEM;
   330    326         return 0;
   331    327       }
   332    328       pGroup->aReal[iChunk].p = pSubOpen;
   333    329       *rc = pOrigVfs->xOpen(pOrigVfs, pGroup->aReal[iChunk].z, pSubOpen,
   334         -                          pGroup->flags, pOutFlags);
   335         -    if( *rc!=SQLITE_OK ){
          330  +                          flags, pOutFlags);
          331  +    if( (*rc)!=SQLITE_OK ){
   336    332         sqlite3_free(pSubOpen);
   337    333         pGroup->aReal[iChunk].p = 0;
   338    334         return 0;
   339    335       }
   340    336     }
   341    337     return pSubOpen;
   342    338   }
   343    339   
          340  +/*
          341  +** Return the size, in bytes, of chunk number iChunk.  If that chunk
          342  +** does not exist, then return 0.  This function does not distingish between
          343  +** non-existant files and zero-length files.
          344  +*/
          345  +static sqlite3_int64 multiplexSubSize(
          346  +  multiplexGroup *pGroup,    /* The multiplexor group */
          347  +  int iChunk,                /* Which chunk to open.  0==original file */
          348  +  int *rc                    /* Result code in and out */
          349  +){
          350  +  sqlite3_file *pSub;
          351  +  sqlite3_int64 sz = 0;
          352  +
          353  +  pSub = multiplexSubOpen(pGroup, iChunk, rc, NULL, 0);
          354  +  if( pSub==0 ) return 0;
          355  +  *rc = pSub->pMethods->xFileSize(pSub, &sz);
          356  +  return sz;
          357  +}    
          358  +
   344    359   /*
   345    360   ** This is the implementation of the multiplex_control() SQL function.
   346    361   */
   347    362   static void multiplexControlFunc(
   348    363     sqlite3_context *context,
   349    364     int argc,
   350    365     sqlite3_value **argv
................................................................................
   404    419     multiplexGroup *pGroup,
   405    420     int iChunk,
   406    421     sqlite3_vfs *pOrigVfs
   407    422   ){
   408    423     sqlite3_file *pSubOpen = pGroup->aReal[iChunk].p;
   409    424     if( pSubOpen ){
   410    425       pSubOpen->pMethods->xClose(pSubOpen);
   411         -    if( pOrigVfs ) pOrigVfs->xDelete(pOrigVfs, pGroup->aReal[iChunk].z, 0);
          426  +    if( pOrigVfs && pGroup->aReal[iChunk].z ){
          427  +      pOrigVfs->xDelete(pOrigVfs, pGroup->aReal[iChunk].z, 0);
          428  +    }
   412    429       sqlite3_free(pGroup->aReal[iChunk].p);
   413    430     }
   414    431     sqlite3_free(pGroup->aReal[iChunk].z);
   415    432     memset(&pGroup->aReal[iChunk], 0, sizeof(pGroup->aReal[iChunk]));
   416    433   }
   417    434   
   418    435   /*
................................................................................
   450    467     sqlite3_vfs *pOrigVfs = gMultiplex.pOrigVfs;   /* Real VFS */
   451    468     int nName;
   452    469     int sz;
   453    470     char *zToFree = 0;
   454    471   
   455    472     UNUSED_PARAMETER(pVfs);
   456    473     memset(pConn, 0, pVfs->szOsFile);
          474  +  assert( zName || (flags & SQLITE_OPEN_DELETEONCLOSE) );
   457    475   
   458    476     /* We need to create a group structure and manage
   459    477     ** access to this group of files.
   460    478     */
   461    479     multiplexEnter();
   462    480     pMultiplexOpen = (multiplexConn*)pConn;
   463    481   
   464         -  /* If the second argument to this function is NULL, generate a 
   465         -  ** temporary file name to use.  This will be handled by the
   466         -  ** original xOpen method.  We just need to allocate space for
   467         -  ** it.
   468         -  */
   469         -  if( !zName ){
   470         -    zName = zToFree = sqlite3_malloc( pOrigVfs->mxPathname + 10 );
   471         -    if( zName==0 ){
   472         -      rc = SQLITE_NOMEM;
   473         -    }else{
   474         -      rc = multiplexGetTempname(pOrigVfs, pOrigVfs->mxPathname, zToFree);
   475         -    }
   476         -  }
   477         -
   478    482     if( rc==SQLITE_OK ){
   479    483       /* allocate space for group */
   480         -    nName = multiplexStrlen30(zName);
          484  +    nName = zName ? multiplexStrlen30(zName) : 0;
   481    485       sz = sizeof(multiplexGroup)                             /* multiplexGroup */
   482    486          + nName + 1;                                         /* zName */
   483    487       pGroup = sqlite3_malloc( sz );
   484    488       if( pGroup==0 ){
   485    489         rc = SQLITE_NOMEM;
   486    490       }
   487    491     }
   488    492   
   489    493     if( rc==SQLITE_OK ){
   490    494       /* assign pointers to extra space allocated */
   491         -    char *p = (char *)&pGroup[1];
   492         -    pMultiplexOpen->pGroup = pGroup;
   493    495       memset(pGroup, 0, sz);
          496  +    pMultiplexOpen->pGroup = pGroup;
   494    497       pGroup->bEnabled = -1;
   495         -    pGroup->szChunk = SQLITE_MULTIPLEX_CHUNK_SIZE;
   496         -    if( flags & SQLITE_OPEN_URI ){
   497         -      const char *zChunkSize;
   498         -      zChunkSize = sqlite3_uri_parameter(zName, "chunksize");
   499         -      if( zChunkSize ){
   500         -        unsigned int n = 0;
   501         -        int i;
   502         -        for(i=0; zChunkSize[i]>='0' && zChunkSize[i]<='9'; i++){
   503         -          n = n*10 + zChunkSize[i] - '0';
   504         -        }
   505         -        if( n>0 ){
   506         -          pGroup->szChunk = (n+0xffff)&~0xffff;
   507         -        }else{
   508         -          /* A zero or negative chunksize disabled the multiplexor */
   509         -          pGroup->bEnabled = 0;
   510         -        }
   511         -      }
   512         -    }
   513         -    pGroup->zName = p;
   514         -    /* save off base filename, name length, and original open flags  */
   515         -    memcpy(pGroup->zName, zName, nName+1);
   516         -    pGroup->nName = nName;
          498  +    pGroup->bTruncate = sqlite3_uri_boolean(zName, "truncate", 
          499  +                                 (flags & SQLITE_OPEN_MAIN_DB)==0);
          500  +    pGroup->szChunk = sqlite3_uri_int64(zName, "chunksize",
          501  +                                        SQLITE_MULTIPLEX_CHUNK_SIZE);
          502  +    pGroup->szChunk = (pGroup->szChunk+0xffff)&~0xffff;
          503  +    if( zName ){
          504  +      char *p = (char *)&pGroup[1];
          505  +      pGroup->zName = p;
          506  +      memcpy(pGroup->zName, zName, nName+1);
          507  +      pGroup->nName = nName;
          508  +    }
          509  +    if( pGroup->bEnabled ){
          510  +      /* Make sure that the chunksize is such that the pending byte does not
          511  +      ** falls at the end of a chunk.  A region of up to 64K following
          512  +      ** the pending byte is never written, so if the pending byte occurs
          513  +      ** near the end of a chunk, that chunk will be too small. */
          514  +#ifndef SQLITE_OMIT_WSD
          515  +      extern int sqlite3PendingByte;
          516  +#else
          517  +      int sqlite3PendingByte = 0x40000000;
          518  +#endif
          519  +      while( (sqlite3PendingByte % pGroup->szChunk)>=(pGroup->szChunk-65536) ){
          520  +        pGroup->szChunk += 65536;
          521  +      }
          522  +    }
   517    523       pGroup->flags = flags;
   518    524       rc = multiplexSubFilename(pGroup, 1);
   519    525       if( rc==SQLITE_OK ){
   520         -      pSubOpen = multiplexSubOpen(pGroup, 0, &rc, pOutFlags);
          526  +      pSubOpen = multiplexSubOpen(pGroup, 0, &rc, pOutFlags, 0);
          527  +      if( pSubOpen==0 && rc==SQLITE_OK ) rc = SQLITE_CANTOPEN;
   521    528       }
   522         -    if( pSubOpen ){
   523         -      int exists, rc2, rc3;
          529  +    if( rc==SQLITE_OK ){
   524    530         sqlite3_int64 sz;
   525    531   
   526         -      rc2 = pSubOpen->pMethods->xFileSize(pSubOpen, &sz);
   527         -      if( rc2==SQLITE_OK ){
   528         -        /* If the first overflow file exists and if the size of the main file
   529         -        ** is different from the chunk size, that means the chunk size is set
   530         -        ** set incorrectly.  So fix it.
   531         -        **
   532         -        ** Or, if the first overflow file does not exist and the main file is
   533         -        ** larger than the chunk size, that means the chunk size is too small.
   534         -        ** But we have no way of determining the intended chunk size, so 
   535         -        ** just disable the multiplexor all togethre.
   536         -        */
   537         -        rc3 = pOrigVfs->xAccess(pOrigVfs, pGroup->aReal[1].z,
   538         -            SQLITE_ACCESS_EXISTS, &exists);
   539         -        if( rc3==SQLITE_OK && exists && sz==(sz&0xffff0000) && sz>0
   540         -            && sz!=pGroup->szChunk ){
   541         -          pGroup->szChunk = sz;
   542         -        }else if( rc3==SQLITE_OK && !exists && sz>pGroup->szChunk ){
   543         -          pGroup->bEnabled = 0;
          532  +      rc = pSubOpen->pMethods->xFileSize(pSubOpen, &sz);
          533  +      if( rc==SQLITE_OK && zName ){
          534  +        int bExists;
          535  +        if( sz==0 ){
          536  +          if( flags & SQLITE_OPEN_MAIN_JOURNAL ){
          537  +            /* If opening a main journal file and the first chunk is zero
          538  +            ** bytes in size, delete any subsequent chunks from the 
          539  +            ** file-system. */
          540  +            int iChunk = 1;
          541  +            do {
          542  +              rc = pOrigVfs->xAccess(pOrigVfs, 
          543  +                  pGroup->aReal[iChunk].z, SQLITE_ACCESS_EXISTS, &bExists
          544  +              );
          545  +              if( rc==SQLITE_OK && bExists ){
          546  +                rc = pOrigVfs->xDelete(pOrigVfs, pGroup->aReal[iChunk].z, 0);
          547  +                if( rc==SQLITE_OK ){
          548  +                  rc = multiplexSubFilename(pGroup, ++iChunk);
          549  +                }
          550  +              }
          551  +            }while( rc==SQLITE_OK && bExists );
          552  +          }
          553  +        }else{
          554  +          /* If the first overflow file exists and if the size of the main file
          555  +          ** is different from the chunk size, that means the chunk size is set
          556  +          ** set incorrectly.  So fix it.
          557  +          **
          558  +          ** Or, if the first overflow file does not exist and the main file is
          559  +          ** larger than the chunk size, that means the chunk size is too small.
          560  +          ** But we have no way of determining the intended chunk size, so 
          561  +          ** just disable the multiplexor all togethre.
          562  +          */
          563  +          rc = pOrigVfs->xAccess(pOrigVfs, pGroup->aReal[1].z,
          564  +              SQLITE_ACCESS_EXISTS, &bExists);
          565  +          bExists = multiplexSubSize(pGroup, 1, &rc)>0;
          566  +          if( rc==SQLITE_OK && bExists  && sz==(sz&0xffff0000) && sz>0
          567  +              && sz!=pGroup->szChunk ){
          568  +            pGroup->szChunk = sz;
          569  +          }else if( rc==SQLITE_OK && !bExists && sz>pGroup->szChunk ){
          570  +            pGroup->bEnabled = 0;
          571  +          }
   544    572           }
   545    573         }
          574  +    }
   546    575   
          576  +    if( rc==SQLITE_OK ){
   547    577         if( pSubOpen->pMethods->iVersion==1 ){
   548    578           pMultiplexOpen->base.pMethods = &gMultiplex.sIoMethodsV1;
   549    579         }else{
   550    580           pMultiplexOpen->base.pMethods = &gMultiplex.sIoMethodsV2;
   551    581         }
   552    582         /* place this group at the head of our list */
   553    583         pGroup->pNext = gMultiplex.pGroups;
................................................................................
   568    598   ** It attempts to delete the filename specified.
   569    599   */
   570    600   static int multiplexDelete(
   571    601     sqlite3_vfs *pVfs,         /* The multiplex VFS */
   572    602     const char *zName,         /* Name of file to delete */
   573    603     int syncDir
   574    604   ){
          605  +  int rc;
   575    606     sqlite3_vfs *pOrigVfs = gMultiplex.pOrigVfs;   /* Real VFS */
   576         -  return pOrigVfs->xDelete(pOrigVfs, zName, syncDir);
          607  +  rc = pOrigVfs->xDelete(pOrigVfs, zName, syncDir);
          608  +  if( rc==SQLITE_OK ){
          609  +    /* If the main chunk was deleted successfully, also delete any subsequent
          610  +    ** chunks - starting with the last (highest numbered). 
          611  +    */
          612  +    int nName = strlen(zName);
          613  +    char *z;
          614  +    z = sqlite3_malloc(nName + 4);
          615  +    if( z==0 ){
          616  +      rc = SQLITE_IOERR_NOMEM;
          617  +    }else{
          618  +      int iChunk = 0;
          619  +      int bExists;
          620  +      do{
          621  +        multiplexFilename(zName, nName, SQLITE_OPEN_MAIN_JOURNAL, ++iChunk, z);
          622  +        rc = pOrigVfs->xAccess(pOrigVfs, z, SQLITE_ACCESS_EXISTS, &bExists);
          623  +      }while( rc==SQLITE_OK && bExists );
          624  +      while( rc==SQLITE_OK && iChunk>1 ){
          625  +        multiplexFilename(zName, nName, SQLITE_OPEN_MAIN_JOURNAL, --iChunk, z);
          626  +        rc = pOrigVfs->xDelete(pOrigVfs, z, syncDir);
          627  +      }
          628  +    }
          629  +    sqlite3_free(z);
          630  +  }
          631  +  return rc;
   577    632   }
   578    633   
   579    634   static int multiplexAccess(sqlite3_vfs *a, const char *b, int c, int *d){
   580    635     return gMultiplex.pOrigVfs->xAccess(gMultiplex.pOrigVfs, b, c, d);
   581    636   }
   582    637   static int multiplexFullPathname(sqlite3_vfs *a, const char *b, int c, char *d){
   583    638     return gMultiplex.pOrigVfs->xFullPathname(gMultiplex.pOrigVfs, b, c, d);
................................................................................
   646    701     sqlite3_int64 iOfst
   647    702   ){
   648    703     multiplexConn *p = (multiplexConn*)pConn;
   649    704     multiplexGroup *pGroup = p->pGroup;
   650    705     int rc = SQLITE_OK;
   651    706     multiplexEnter();
   652    707     if( !pGroup->bEnabled ){
   653         -    sqlite3_file *pSubOpen = multiplexSubOpen(pGroup, 0, &rc, NULL);
          708  +    sqlite3_file *pSubOpen = multiplexSubOpen(pGroup, 0, &rc, NULL, 0);
   654    709       if( pSubOpen==0 ){
   655    710         rc = SQLITE_IOERR_READ;
   656    711       }else{
   657    712         rc = pSubOpen->pMethods->xRead(pSubOpen, pBuf, iAmt, iOfst);
   658    713       }
   659    714     }else{
   660    715       while( iAmt > 0 ){
   661    716         int i = (int)(iOfst / pGroup->szChunk);
   662         -      sqlite3_file *pSubOpen = multiplexSubOpen(pGroup, i, &rc, NULL);
          717  +      sqlite3_file *pSubOpen = multiplexSubOpen(pGroup, i, &rc, NULL, 1);
   663    718         if( pSubOpen ){
   664    719           int extra = ((int)(iOfst % pGroup->szChunk) + iAmt) - pGroup->szChunk;
   665    720           if( extra<0 ) extra = 0;
   666    721           iAmt -= extra;
   667    722           rc = pSubOpen->pMethods->xRead(pSubOpen, pBuf, iAmt,
   668    723                                          iOfst % pGroup->szChunk);
   669    724           if( rc!=SQLITE_OK ) break;
................................................................................
   691    746     sqlite3_int64 iOfst
   692    747   ){
   693    748     multiplexConn *p = (multiplexConn*)pConn;
   694    749     multiplexGroup *pGroup = p->pGroup;
   695    750     int rc = SQLITE_OK;
   696    751     multiplexEnter();
   697    752     if( !pGroup->bEnabled ){
   698         -    sqlite3_file *pSubOpen = multiplexSubOpen(pGroup, 0, &rc, NULL);
          753  +    sqlite3_file *pSubOpen = multiplexSubOpen(pGroup, 0, &rc, NULL, 0);
   699    754       if( pSubOpen==0 ){
   700    755         rc = SQLITE_IOERR_WRITE;
   701    756       }else{
   702    757         rc = pSubOpen->pMethods->xWrite(pSubOpen, pBuf, iAmt, iOfst);
   703    758       }
   704    759     }else{
   705         -    while( iAmt > 0 ){
          760  +    while( rc==SQLITE_OK && iAmt>0 ){
   706    761         int i = (int)(iOfst / pGroup->szChunk);
   707         -      sqlite3_file *pSubOpen = multiplexSubOpen(pGroup, i, &rc, NULL);
          762  +      sqlite3_file *pSubOpen = multiplexSubOpen(pGroup, i, &rc, NULL, 1);
   708    763         if( pSubOpen ){
   709    764           int extra = ((int)(iOfst % pGroup->szChunk) + iAmt) -
   710    765                       pGroup->szChunk;
   711    766           if( extra<0 ) extra = 0;
   712    767           iAmt -= extra;
   713    768           rc = pSubOpen->pMethods->xWrite(pSubOpen, pBuf, iAmt,
   714    769                                           iOfst % pGroup->szChunk);
   715         -        if( rc!=SQLITE_OK ) break;
   716    770           pBuf = (char *)pBuf + iAmt;
   717    771           iOfst += iAmt;
   718    772           iAmt = extra;
   719         -      }else{
   720         -        rc = SQLITE_IOERR_WRITE;
   721         -        break;
   722    773         }
   723    774       }
   724    775     }
   725    776     multiplexLeave();
   726    777     return rc;
   727    778   }
   728    779   
................................................................................
   732    783   */
   733    784   static int multiplexTruncate(sqlite3_file *pConn, sqlite3_int64 size){
   734    785     multiplexConn *p = (multiplexConn*)pConn;
   735    786     multiplexGroup *pGroup = p->pGroup;
   736    787     int rc = SQLITE_OK;
   737    788     multiplexEnter();
   738    789     if( !pGroup->bEnabled ){
   739         -    sqlite3_file *pSubOpen = multiplexSubOpen(pGroup, 0, &rc, NULL);
          790  +    sqlite3_file *pSubOpen = multiplexSubOpen(pGroup, 0, &rc, NULL, 0);
   740    791       if( pSubOpen==0 ){
   741    792         rc = SQLITE_IOERR_TRUNCATE;
   742    793       }else{
   743    794         rc = pSubOpen->pMethods->xTruncate(pSubOpen, size);
   744    795       }
   745    796     }else{
   746         -    int rc2;
   747    797       int i;
          798  +    int iBaseGroup = (int)(size / pGroup->szChunk);
   748    799       sqlite3_file *pSubOpen;
   749    800       sqlite3_vfs *pOrigVfs = gMultiplex.pOrigVfs;   /* Real VFS */
   750    801       /* delete the chunks above the truncate limit */
   751         -    for(i=(int)(size / pGroup->szChunk)+1; i<pGroup->nReal; i++){
   752         -      multiplexSubClose(pGroup, i, pOrigVfs);
          802  +    for(i = pGroup->nReal-1; i>iBaseGroup && rc==SQLITE_OK; i--){
          803  +      if( pGroup->bTruncate ){
          804  +        multiplexSubClose(pGroup, i, pOrigVfs);
          805  +      }else{
          806  +        pSubOpen = multiplexSubOpen(pGroup, i, &rc, 0, 0);
          807  +        if( pSubOpen ){
          808  +          rc = pSubOpen->pMethods->xTruncate(pSubOpen, 0);
          809  +        }
          810  +      }
   753    811       }
   754         -    pSubOpen = multiplexSubOpen(pGroup, (int)(size/pGroup->szChunk), &rc2,0);
   755         -    if( pSubOpen ){
   756         -      rc2 = pSubOpen->pMethods->xTruncate(pSubOpen, size % pGroup->szChunk);
   757         -      if( rc2!=SQLITE_OK ) rc = rc2;
   758         -    }else{
   759         -      rc = SQLITE_IOERR_TRUNCATE;
          812  +    if( rc==SQLITE_OK ){
          813  +      pSubOpen = multiplexSubOpen(pGroup, iBaseGroup, &rc, 0, 0);
          814  +      if( pSubOpen ){
          815  +        rc = pSubOpen->pMethods->xTruncate(pSubOpen, size % pGroup->szChunk);
          816  +      }
   760    817       }
          818  +    if( rc ) rc = SQLITE_IOERR_TRUNCATE;
   761    819     }
   762    820     multiplexLeave();
   763    821     return rc;
   764    822   }
   765    823   
   766    824   /* Pass xSync requests through to the original VFS without change
   767    825   */
................................................................................
   785    843   /* Pass xFileSize requests through to the original VFS.
   786    844   ** Aggregate the size of all the chunks before returning.
   787    845   */
   788    846   static int multiplexFileSize(sqlite3_file *pConn, sqlite3_int64 *pSize){
   789    847     multiplexConn *p = (multiplexConn*)pConn;
   790    848     multiplexGroup *pGroup = p->pGroup;
   791    849     int rc = SQLITE_OK;
   792         -  int rc2;
   793    850     int i;
   794    851     multiplexEnter();
   795    852     if( !pGroup->bEnabled ){
   796         -    sqlite3_file *pSubOpen = multiplexSubOpen(pGroup, 0, &rc, NULL);
          853  +    sqlite3_file *pSubOpen = multiplexSubOpen(pGroup, 0, &rc, NULL, 0);
   797    854       if( pSubOpen==0 ){
   798    855         rc = SQLITE_IOERR_FSTAT;
   799    856       }else{
   800    857         rc = pSubOpen->pMethods->xFileSize(pSubOpen, pSize);
   801    858       }
   802    859     }else{
   803         -    sqlite3_vfs *pOrigVfs = gMultiplex.pOrigVfs;
   804    860       *pSize = 0;
   805         -    for(i=0; 1; i++){
   806         -      sqlite3_file *pSubOpen = 0;
   807         -      int exists = 0;
   808         -      rc = multiplexSubFilename(pGroup, i);
   809         -      if( rc ) break;
   810         -      rc2 = pOrigVfs->xAccess(pOrigVfs, pGroup->aReal[i].z,
   811         -          SQLITE_ACCESS_EXISTS, &exists);
   812         -      if( rc2==SQLITE_OK && exists){
   813         -        /* if it exists, open it */
   814         -        pSubOpen = multiplexSubOpen(pGroup, i, &rc, NULL);
   815         -      }else{
   816         -        /* stop at first "gap" */
   817         -        break;
   818         -      }
   819         -      if( pSubOpen ){
   820         -        sqlite3_int64 sz;
   821         -        rc2 = pSubOpen->pMethods->xFileSize(pSubOpen, &sz);
   822         -        if( rc2!=SQLITE_OK ){
   823         -          rc = rc2;
   824         -        }else{
   825         -          if( sz>pGroup->szChunk ){
   826         -            rc = SQLITE_IOERR_FSTAT;
   827         -          }
   828         -          *pSize += sz;
   829         -        }
   830         -      }else{
   831         -        break;
   832         -      }
          861  +    for(i=0; rc==SQLITE_OK; i++){
          862  +      sqlite3_int64 sz = multiplexSubSize(pGroup, i, &rc);
          863  +      if( sz==0 ) break;
          864  +      *pSize = i*(sqlite3_int64)pGroup->szChunk + sz;
   833    865       }
   834    866     }
   835    867     multiplexLeave();
   836    868     return rc;
   837    869   }
   838    870   
   839    871   /* Pass xLock requests through to the original VFS unchanged.
   840    872   */
   841    873   static int multiplexLock(sqlite3_file *pConn, int lock){
   842    874     multiplexConn *p = (multiplexConn*)pConn;
   843    875     int rc;
   844         -  sqlite3_file *pSubOpen = multiplexSubOpen(p->pGroup, 0, &rc, NULL);
          876  +  sqlite3_file *pSubOpen = multiplexSubOpen(p->pGroup, 0, &rc, NULL, 0);
   845    877     if( pSubOpen ){
   846    878       return pSubOpen->pMethods->xLock(pSubOpen, lock);
   847    879     }
   848    880     return SQLITE_BUSY;
   849    881   }
   850    882   
   851    883   /* Pass xUnlock requests through to the original VFS unchanged.
   852    884   */
   853    885   static int multiplexUnlock(sqlite3_file *pConn, int lock){
   854    886     multiplexConn *p = (multiplexConn*)pConn;
   855    887     int rc;
   856         -  sqlite3_file *pSubOpen = multiplexSubOpen(p->pGroup, 0, &rc, NULL);
          888  +  sqlite3_file *pSubOpen = multiplexSubOpen(p->pGroup, 0, &rc, NULL, 0);
   857    889     if( pSubOpen ){
   858    890       return pSubOpen->pMethods->xUnlock(pSubOpen, lock);
   859    891     }
   860    892     return SQLITE_IOERR_UNLOCK;
   861    893   }
   862    894   
   863    895   /* Pass xCheckReservedLock requests through to the original VFS unchanged.
   864    896   */
   865    897   static int multiplexCheckReservedLock(sqlite3_file *pConn, int *pResOut){
   866    898     multiplexConn *p = (multiplexConn*)pConn;
   867    899     int rc;
   868         -  sqlite3_file *pSubOpen = multiplexSubOpen(p->pGroup, 0, &rc, NULL);
          900  +  sqlite3_file *pSubOpen = multiplexSubOpen(p->pGroup, 0, &rc, NULL, 0);
   869    901     if( pSubOpen ){
   870    902       return pSubOpen->pMethods->xCheckReservedLock(pSubOpen, pResOut);
   871    903     }
   872    904     return SQLITE_IOERR_CHECKRESERVEDLOCK;
   873    905   }
   874    906   
   875    907   /* Pass xFileControl requests through to the original VFS unchanged,
................................................................................
   909    941         break;
   910    942       case SQLITE_FCNTL_SIZE_HINT:
   911    943       case SQLITE_FCNTL_CHUNK_SIZE:
   912    944         /* no-op these */
   913    945         rc = SQLITE_OK;
   914    946         break;
   915    947       default:
   916         -      pSubOpen = multiplexSubOpen(pGroup, 0, &rc, NULL);
          948  +      pSubOpen = multiplexSubOpen(pGroup, 0, &rc, NULL, 0);
   917    949         if( pSubOpen ){
   918    950           rc = pSubOpen->pMethods->xFileControl(pSubOpen, op, pArg);
          951  +        if( op==SQLITE_FCNTL_VFSNAME && rc==SQLITE_OK ){
          952  +         *(char**)pArg = sqlite3_mprintf("multiplex/%z", *(char**)pArg);
          953  +        }
   919    954         }
   920    955         break;
   921    956     }
   922    957     return rc;
   923    958   }
   924    959   
   925    960   /* Pass xSectorSize requests through to the original VFS unchanged.
   926    961   */
   927    962   static int multiplexSectorSize(sqlite3_file *pConn){
   928    963     multiplexConn *p = (multiplexConn*)pConn;
   929    964     int rc;
   930         -  sqlite3_file *pSubOpen = multiplexSubOpen(p->pGroup, 0, &rc, NULL);
   931         -  if( pSubOpen ){
          965  +  sqlite3_file *pSubOpen = multiplexSubOpen(p->pGroup, 0, &rc, NULL, 0);
          966  +  if( pSubOpen && pSubOpen->pMethods->xSectorSize ){
   932    967       return pSubOpen->pMethods->xSectorSize(pSubOpen);
   933    968     }
   934    969     return DEFAULT_SECTOR_SIZE;
   935    970   }
   936    971   
   937    972   /* Pass xDeviceCharacteristics requests through to the original VFS unchanged.
   938    973   */
   939    974   static int multiplexDeviceCharacteristics(sqlite3_file *pConn){
   940    975     multiplexConn *p = (multiplexConn*)pConn;
   941    976     int rc;
   942         -  sqlite3_file *pSubOpen = multiplexSubOpen(p->pGroup, 0, &rc, NULL);
          977  +  sqlite3_file *pSubOpen = multiplexSubOpen(p->pGroup, 0, &rc, NULL, 0);
   943    978     if( pSubOpen ){
   944    979       return pSubOpen->pMethods->xDeviceCharacteristics(pSubOpen);
   945    980     }
   946    981     return 0;
   947    982   }
   948    983   
   949    984   /* Pass xShmMap requests through to the original VFS unchanged.
................................................................................
   953    988     int iRegion,                    /* Region to retrieve */
   954    989     int szRegion,                   /* Size of regions */
   955    990     int bExtend,                    /* True to extend file if necessary */
   956    991     void volatile **pp              /* OUT: Mapped memory */
   957    992   ){
   958    993     multiplexConn *p = (multiplexConn*)pConn;
   959    994     int rc;
   960         -  sqlite3_file *pSubOpen = multiplexSubOpen(p->pGroup, 0, &rc, NULL);
          995  +  sqlite3_file *pSubOpen = multiplexSubOpen(p->pGroup, 0, &rc, NULL, 0);
   961    996     if( pSubOpen ){
   962    997       return pSubOpen->pMethods->xShmMap(pSubOpen, iRegion, szRegion, bExtend,pp);
   963    998     }
   964    999     return SQLITE_IOERR;
   965   1000   }
   966   1001   
   967   1002   /* Pass xShmLock requests through to the original VFS unchanged.
................................................................................
   970   1005     sqlite3_file *pConn,       /* Database file holding the shared memory */
   971   1006     int ofst,                  /* First lock to acquire or release */
   972   1007     int n,                     /* Number of locks to acquire or release */
   973   1008     int flags                  /* What to do with the lock */
   974   1009   ){
   975   1010     multiplexConn *p = (multiplexConn*)pConn;
   976   1011     int rc;
   977         -  sqlite3_file *pSubOpen = multiplexSubOpen(p->pGroup, 0, &rc, NULL);
         1012  +  sqlite3_file *pSubOpen = multiplexSubOpen(p->pGroup, 0, &rc, NULL, 0);
   978   1013     if( pSubOpen ){
   979   1014       return pSubOpen->pMethods->xShmLock(pSubOpen, ofst, n, flags);
   980   1015     }
   981   1016     return SQLITE_BUSY;
   982   1017   }
   983   1018   
   984   1019   /* Pass xShmBarrier requests through to the original VFS unchanged.
   985   1020   */
   986   1021   static void multiplexShmBarrier(sqlite3_file *pConn){
   987   1022     multiplexConn *p = (multiplexConn*)pConn;
   988   1023     int rc;
   989         -  sqlite3_file *pSubOpen = multiplexSubOpen(p->pGroup, 0, &rc, NULL);
         1024  +  sqlite3_file *pSubOpen = multiplexSubOpen(p->pGroup, 0, &rc, NULL, 0);
   990   1025     if( pSubOpen ){
   991   1026       pSubOpen->pMethods->xShmBarrier(pSubOpen);
   992   1027     }
   993   1028   }
   994   1029   
   995   1030   /* Pass xShmUnmap requests through to the original VFS unchanged.
   996   1031   */
   997   1032   static int multiplexShmUnmap(sqlite3_file *pConn, int deleteFlag){
   998   1033     multiplexConn *p = (multiplexConn*)pConn;
   999   1034     int rc;
  1000         -  sqlite3_file *pSubOpen = multiplexSubOpen(p->pGroup, 0, &rc, NULL);
         1035  +  sqlite3_file *pSubOpen = multiplexSubOpen(p->pGroup, 0, &rc, NULL, 0);
  1001   1036     if( pSubOpen ){
  1002   1037       return pSubOpen->pMethods->xShmUnmap(pSubOpen, deleteFlag);
  1003   1038     }
  1004   1039     return SQLITE_OK;
  1005   1040   }
  1006   1041   
  1007   1042   /************************** Public Interfaces *****************************/
................................................................................
  1175   1210     UNUSED_PARAMETER(objv);
  1176   1211   
  1177   1212     pResult = Tcl_NewObj();
  1178   1213     multiplexEnter();
  1179   1214     for(pGroup=gMultiplex.pGroups; pGroup; pGroup=pGroup->pNext){
  1180   1215       pGroupTerm = Tcl_NewObj();
  1181   1216   
  1182         -    pGroup->zName[pGroup->nName] = '\0';
  1183         -    Tcl_ListObjAppendElement(interp, pGroupTerm,
         1217  +    if( pGroup->zName ){
         1218  +      pGroup->zName[pGroup->nName] = '\0';
         1219  +      Tcl_ListObjAppendElement(interp, pGroupTerm,
  1184   1220             Tcl_NewStringObj(pGroup->zName, -1));
         1221  +    }else{
         1222  +      Tcl_ListObjAppendElement(interp, pGroupTerm, Tcl_NewObj());
         1223  +    }
  1185   1224       Tcl_ListObjAppendElement(interp, pGroupTerm,
  1186   1225             Tcl_NewIntObj(pGroup->nName));
  1187   1226       Tcl_ListObjAppendElement(interp, pGroupTerm,
  1188   1227             Tcl_NewIntObj(pGroup->flags));
  1189   1228   
  1190   1229       /* count number of chunks with open handles */
  1191   1230       for(i=0; i<pGroup->nReal; i++){

Changes to src/test_osinst.c.

   385    385   }
   386    386   
   387    387   /*
   388    388   ** File control method. For custom operations on an vfslog-file.
   389    389   */
   390    390   static int vfslogFileControl(sqlite3_file *pFile, int op, void *pArg){
   391    391     VfslogFile *p = (VfslogFile *)pFile;
   392         -  return p->pReal->pMethods->xFileControl(p->pReal, op, pArg);
          392  +  int rc = p->pReal->pMethods->xFileControl(p->pReal, op, pArg);
          393  +  if( op==SQLITE_FCNTL_VFSNAME && rc==SQLITE_OK ){
          394  +    *(char**)pArg = sqlite3_mprintf("vfslog/%z", *(char**)pArg);
          395  +  }
          396  +  return rc;
   393    397   }
   394    398   
   395    399   /*
   396    400   ** Return the sector-size in bytes for an vfslog-file.
   397    401   */
   398    402   static int vfslogSectorSize(sqlite3_file *pFile){
   399    403     int rc;

Changes to src/test_quota.c.

    23     23   ** However, before returning SQLITE_FULL, the write requests invoke
    24     24   ** a callback function that is configurable for each quota group.
    25     25   ** This callback has the opportunity to enlarge the quota.  If the
    26     26   ** callback does enlarge the quota such that the total size of all
    27     27   ** files within the group is less than the new quota, then the write
    28     28   ** continues as if nothing had happened.
    29     29   */
    30         -#include "sqlite3.h"
           30  +#include "test_quota.h"
    31     31   #include <string.h>
    32     32   #include <assert.h>
    33     33   
    34     34   /*
    35     35   ** For an build without mutexes, no-op the mutex calls.
    36     36   */
    37     37   #if defined(SQLITE_THREADSAFE) && SQLITE_THREADSAFE==0
................................................................................
   106    106   ** VFS is appended to this structure.
   107    107   */
   108    108   struct quotaConn {
   109    109     sqlite3_file base;              /* Base class - must be first */
   110    110     quotaFile *pFile;               /* The underlying file */
   111    111     /* The underlying VFS sqlite3_file is appended to this object */
   112    112   };
          113  +
          114  +/*
          115  +** An instance of the following object records the state of an
          116  +** open file.  This object is opaque to all users - the internal
          117  +** structure is only visible to the functions below.
          118  +*/
          119  +struct quota_FILE {
          120  +  FILE *f;                /* Open stdio file pointer */
          121  +  sqlite3_int64 iOfst;    /* Current offset into the file */
          122  +  quotaFile *pFile;       /* The file record in the quota system */
          123  +};
          124  +
   113    125   
   114    126   /************************* Global Variables **********************************/
   115    127   /*
   116    128   ** All global variables used by this file are containing within the following
   117    129   ** gQuota structure.
   118    130   */
   119    131   static struct {
................................................................................
   221    233   **      '?'       Matches exactly one character.
   222    234   **
   223    235   **     [...]      Matches one character from the enclosed list of
   224    236   **                characters.
   225    237   **
   226    238   **     [^...]     Matches one character not in the enclosed list.
   227    239   **
          240  +**     /          Matches "/" or "\\"
          241  +**
   228    242   */
   229    243   static int quotaStrglob(const char *zGlob, const char *z){
   230         -  int c, c2;
          244  +  int c, c2, cx;
   231    245     int invert;
   232    246     int seen;
   233    247   
   234    248     while( (c = (*(zGlob++)))!=0 ){
   235    249       if( c=='*' ){
   236    250         while( (c=(*(zGlob++))) == '*' || c=='?' ){
   237    251           if( c=='?' && (*(z++))==0 ) return 0;
................................................................................
   240    254           return 1;
   241    255         }else if( c=='[' ){
   242    256           while( *z && quotaStrglob(zGlob-1,z)==0 ){
   243    257             z++;
   244    258           }
   245    259           return (*z)!=0;
   246    260         }
          261  +      cx = (c=='/') ? '\\' : c;
   247    262         while( (c2 = (*(z++)))!=0 ){
   248         -        while( c2!=c ){
          263  +        while( c2!=c && c2!=cx ){
   249    264             c2 = *(z++);
   250    265             if( c2==0 ) return 0;
   251    266           }
   252    267           if( quotaStrglob(zGlob,z) ) return 1;
   253    268         }
   254    269         return 0;
   255    270       }else if( c=='?' ){
................................................................................
   279    294               seen = 1;
   280    295             }
   281    296             prior_c = c2;
   282    297           }
   283    298           c2 = *(zGlob++);
   284    299         }
   285    300         if( c2==0 || (seen ^ invert)==0 ) return 0;
          301  +    }else if( c=='/' ){
          302  +      if( z[0]!='/' && z[0]!='\\' ) return 0;
          303  +      z++;
   286    304       }else{
   287    305         if( c!=(*(z++)) ) return 0;
   288    306       }
   289    307     }
   290    308     return *z==0;
   291    309   }
   292    310   
................................................................................
   309    327     quotaConn *p = (quotaConn*)pConn;
   310    328     return (sqlite3_file*)&p[1];
   311    329   }
   312    330   
   313    331   /* Find a file in a quota group and return a pointer to that file.
   314    332   ** Return NULL if the file is not in the group.
   315    333   */
   316         -static quotaFile *quotaFindFile(quotaGroup *pGroup, const char *zName){
          334  +static quotaFile *quotaFindFile(
          335  +  quotaGroup *pGroup,     /* Group in which to look for the file */
          336  +  const char *zName,      /* Full pathname of the file */
          337  +  int createFlag          /* Try to create the file if not found */
          338  +){
   317    339     quotaFile *pFile = pGroup->pFiles;
   318    340     while( pFile && strcmp(pFile->zFilename, zName)!=0 ){
   319    341       pFile = pFile->pNext;
          342  +  }
          343  +  if( pFile==0 && createFlag ){
          344  +    int nName = strlen(zName);
          345  +    pFile = (quotaFile *)sqlite3_malloc( sizeof(*pFile) + nName + 1 );
          346  +    if( pFile ){
          347  +      memset(pFile, 0, sizeof(*pFile));
          348  +      pFile->zFilename = (char*)&pFile[1];
          349  +      memcpy(pFile->zFilename, zName, nName+1);
          350  +      pFile->pNext = pGroup->pFiles;
          351  +      if( pGroup->pFiles ) pGroup->pFiles->ppPrev = &pFile->pNext;
          352  +      pFile->ppPrev = &pGroup->pFiles;
          353  +      pGroup->pFiles = pFile;
          354  +      pFile->pGroup = pGroup;
          355  +    }
   320    356     }
   321    357     return pFile;
   322    358   }
          359  +
          360  +/*
          361  +** Figure out if we are dealing with Unix, Windows, or some other
          362  +** operating system.  After the following block of preprocess macros,
          363  +** all of SQLITE_OS_UNIX, SQLITE_OS_WIN, SQLITE_OS_OS2, and SQLITE_OS_OTHER 
          364  +** will defined to either 1 or 0.  One of the four will be 1.  The other 
          365  +** three will be 0.
          366  +*/
          367  +#if defined(SQLITE_OS_OTHER)
          368  +# if SQLITE_OS_OTHER==1
          369  +#   undef SQLITE_OS_UNIX
          370  +#   define SQLITE_OS_UNIX 0
          371  +#   undef SQLITE_OS_WIN
          372  +#   define SQLITE_OS_WIN 0
          373  +#   undef SQLITE_OS_OS2
          374  +#   define SQLITE_OS_OS2 0
          375  +# else
          376  +#   undef SQLITE_OS_OTHER
          377  +# endif
          378  +#endif
          379  +#if !defined(SQLITE_OS_UNIX) && !defined(SQLITE_OS_OTHER)
          380  +# define SQLITE_OS_OTHER 0
          381  +# ifndef SQLITE_OS_WIN
          382  +#   if defined(_WIN32) || defined(WIN32) || defined(__CYGWIN__) \
          383  +                       || defined(__MINGW32__) || defined(__BORLANDC__)
          384  +#     define SQLITE_OS_WIN 1
          385  +#     define SQLITE_OS_UNIX 0
          386  +#     define SQLITE_OS_OS2 0
          387  +#   elif defined(__EMX__) || defined(_OS2) || defined(OS2) \
          388  +                          || defined(_OS2_) || defined(__OS2__)
          389  +#     define SQLITE_OS_WIN 0
          390  +#     define SQLITE_OS_UNIX 0
          391  +#     define SQLITE_OS_OS2 1
          392  +#   else
          393  +#     define SQLITE_OS_WIN 0
          394  +#     define SQLITE_OS_UNIX 1
          395  +#     define SQLITE_OS_OS2 0
          396  +#  endif
          397  +# else
          398  +#  define SQLITE_OS_UNIX 0
          399  +#  define SQLITE_OS_OS2 0
          400  +# endif
          401  +#else
          402  +# ifndef SQLITE_OS_WIN
          403  +#  define SQLITE_OS_WIN 0
          404  +# endif
          405  +#endif
          406  +
          407  +#if SQLITE_OS_UNIX
          408  +# include <unistd.h>
          409  +#endif
          410  +#if SQLITE_OS_WIN
          411  +# include <windows.h>
          412  +# include <io.h>
          413  +#endif
          414  +
          415  +/*
          416  +** Translate UTF8 to MBCS for use in fopen() calls.  Return a pointer to the
          417  +** translated text..  Call quota_mbcs_free() to deallocate any memory
          418  +** used to store the returned pointer when done.
          419  +*/
          420  +static char *quota_utf8_to_mbcs(const char *zUtf8){
          421  +#if SQLITE_OS_WIN
          422  +  int n;             /* Bytes in zUtf8 */
          423  +  int nWide;         /* number of UTF-16 characters */
          424  +  int nMbcs;         /* Bytes of MBCS */
          425  +  LPWSTR zTmpWide;   /* The UTF16 text */
          426  +  char *zMbcs;       /* The MBCS text */
          427  +  int codepage;      /* Code page used by fopen() */
          428  +
          429  +  n = strlen(zUtf8);
          430  +  nWide = MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, NULL, 0);
          431  +  if( nWide==0 ) return 0;
          432  +  zTmpWide = (LPWSTR)sqlite3_malloc( (nWide+1)*sizeof(zTmpWide[0]) );
          433  +  if( zTmpWide==0 ) return 0;
          434  +  MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, zTmpWide, nWide);
          435  +  codepage = AreFileApisANSI() ? CP_ACP : CP_OEMCP;
          436  +  nMbcs = WideCharToMultiByte(codepage, 0, zTmpWide, nWide, 0, 0, 0, 0);
          437  +  zMbcs = nMbcs ? (char*)sqlite3_malloc( nMbcs+1 ) : 0;
          438  +  if( zMbcs ){
          439  +    WideCharToMultiByte(codepage, 0, zTmpWide, nWide, zMbcs, nMbcs, 0, 0);
          440  +  }
          441  +  sqlite3_free(zTmpWide);
          442  +  return zMbcs;
          443  +#else
          444  +  return (char*)zUtf8;  /* No-op on unix */
          445  +#endif  
          446  +}
          447  +
          448  +/*
          449  +** Deallocate any memory allocated by quota_utf8_to_mbcs().
          450  +*/
          451  +static void quota_mbcs_free(char *zOld){
          452  +#if SQLITE_OS_WIN
          453  +  sqlite3_free(zOld);
          454  +#else
          455  +  /* No-op on unix */
          456  +#endif  
          457  +}
   323    458   
   324    459   /************************* VFS Method Wrappers *****************************/
   325    460   /*
   326    461   ** This is the xOpen method used for the "quota" VFS.
   327    462   **
   328    463   ** Most of the work is done by the underlying original VFS.  This method
   329    464   ** simply links the new file into the appropriate quota group if it is a
................................................................................
   360    495     }else{
   361    496       /* If we get to this point, it means the file needs to be quota tracked.
   362    497       */
   363    498       pQuotaOpen = (quotaConn*)pConn;
   364    499       pSubOpen = quotaSubOpen(pConn);
   365    500       rc = pOrigVfs->xOpen(pOrigVfs, zName, pSubOpen, flags, pOutFlags);
   366    501       if( rc==SQLITE_OK ){
   367         -      pFile = quotaFindFile(pGroup, zName);
          502  +      pFile = quotaFindFile(pGroup, zName, 1);
   368    503         if( pFile==0 ){
   369         -        int nName = strlen(zName);
   370         -        pFile = (quotaFile *)sqlite3_malloc( sizeof(*pFile) + nName + 1 );
   371         -        if( pFile==0 ){
   372         -          quotaLeave();
   373         -          pSubOpen->pMethods->xClose(pSubOpen);
   374         -          return SQLITE_NOMEM;
   375         -        }
   376         -        memset(pFile, 0, sizeof(*pFile));
   377         -        pFile->zFilename = (char*)&pFile[1];
   378         -        memcpy(pFile->zFilename, zName, nName+1);
   379         -        pFile->pNext = pGroup->pFiles;
   380         -        if( pGroup->pFiles ) pGroup->pFiles->ppPrev = &pFile->pNext;
   381         -        pFile->ppPrev = &pGroup->pFiles;
   382         -        pGroup->pFiles = pFile;
   383         -        pFile->pGroup = pGroup;
   384         -        pFile->deleteOnClose = (flags & SQLITE_OPEN_DELETEONCLOSE)!=0;
          504  +        quotaLeave();
          505  +        pSubOpen->pMethods->xClose(pSubOpen);
          506  +        return SQLITE_NOMEM;
   385    507         }
          508  +      pFile->deleteOnClose = (flags & SQLITE_OPEN_DELETEONCLOSE)!=0;
   386    509         pFile->nRef++;
   387    510         pQuotaOpen->pFile = pFile;
   388    511         if( pSubOpen->pMethods->iVersion==1 ){
   389    512           pQuotaOpen->base.pMethods = &gQuota.sIoMethodsV1;
   390    513         }else{
   391    514           pQuotaOpen->base.pMethods = &gQuota.sIoMethodsV2;
   392    515         }
................................................................................
   419    542     /* If the file just deleted is a member of a quota group, then remove
   420    543     ** it from that quota group.
   421    544     */
   422    545     if( rc==SQLITE_OK ){
   423    546       quotaEnter();
   424    547       pGroup = quotaGroupFind(zName);
   425    548       if( pGroup ){
   426         -      pFile = quotaFindFile(pGroup, zName);
          549  +      pFile = quotaFindFile(pGroup, zName, 0);
   427    550         if( pFile ){
   428    551           if( pFile->nRef ){
   429    552             pFile->deleteOnClose = 1;
   430    553           }else{
   431    554             quotaRemoveFile(pFile);
   432    555             quotaGroupDeref(pGroup);
   433    556           }
................................................................................
   451    574     sqlite3_file *pSubOpen = quotaSubOpen(pConn);
   452    575     int rc;
   453    576     rc = pSubOpen->pMethods->xClose(pSubOpen);
   454    577     quotaEnter();
   455    578     pFile->nRef--;
   456    579     if( pFile->nRef==0 ){
   457    580       quotaGroup *pGroup = pFile->pGroup;
   458         -    if( pFile->deleteOnClose ) quotaRemoveFile(pFile);
          581  +    if( pFile->deleteOnClose ){
          582  +      gQuota.pOrigVfs->xDelete(gQuota.pOrigVfs, pFile->zFilename, 0);
          583  +      quotaRemoveFile(pFile);
          584  +    }
   459    585       quotaGroupDeref(pGroup);
   460    586     }
   461    587     quotaLeave();
   462    588     return rc;
   463    589   }
   464    590   
   465    591   /* Pass xRead requests directory thru to the original VFS without
................................................................................
   585    711     return pSubOpen->pMethods->xCheckReservedLock(pSubOpen, pResOut);
   586    712   }
   587    713   
   588    714   /* Pass xFileControl requests through to the original VFS unchanged.
   589    715   */
   590    716   static int quotaFileControl(sqlite3_file *pConn, int op, void *pArg){
   591    717     sqlite3_file *pSubOpen = quotaSubOpen(pConn);
   592         -  return pSubOpen->pMethods->xFileControl(pSubOpen, op, pArg);
          718  +  int rc = pSubOpen->pMethods->xFileControl(pSubOpen, op, pArg);
          719  +#if defined(SQLITE_FCNTL_VFSNAME)
          720  +  if( op==SQLITE_FCNTL_VFSNAME && rc==SQLITE_OK ){
          721  +    *(char**)pArg = sqlite3_mprintf("quota/%z", *(char**)pArg);
          722  +  }
          723  +#endif
          724  +  return rc;
   593    725   }
   594    726   
   595    727   /* Pass xSectorSize requests through to the original VFS unchanged.
   596    728   */
   597    729   static int quotaSectorSize(sqlite3_file *pConn){
   598    730     sqlite3_file *pSubOpen = quotaSubOpen(pConn);
   599    731     return pSubOpen->pMethods->xSectorSize(pSubOpen);
................................................................................
   801    933   */
   802    934   int sqlite3_quota_file(const char *zFilename){
   803    935     char *zFull;
   804    936     sqlite3_file *fd;
   805    937     int rc;
   806    938     int outFlags = 0;
   807    939     sqlite3_int64 iSize;
   808         -  fd = sqlite3_malloc(gQuota.sThisVfs.szOsFile + gQuota.sThisVfs.mxPathname+1);
          940  +  fd = (sqlite3_file*)sqlite3_malloc(gQuota.sThisVfs.szOsFile +
          941  +                                     gQuota.sThisVfs.mxPathname+1);
   809    942     if( fd==0 ) return SQLITE_NOMEM;
   810    943     zFull = gQuota.sThisVfs.szOsFile + (char*)fd;
   811    944     rc = gQuota.pOrigVfs->xFullPathname(gQuota.pOrigVfs, zFilename,
   812    945                                         gQuota.sThisVfs.mxPathname+1, zFull);
   813    946     if( rc==SQLITE_OK ){
   814    947       rc = quotaOpen(&gQuota.sThisVfs, zFull, fd, 
   815    948                      SQLITE_OPEN_READONLY | SQLITE_OPEN_MAIN_DB, &outFlags);
................................................................................
   819    952       fd->pMethods->xClose(fd);
   820    953     }else if( rc==SQLITE_CANTOPEN ){
   821    954       quotaGroup *pGroup;
   822    955       quotaFile *pFile;
   823    956       quotaEnter();
   824    957       pGroup = quotaGroupFind(zFull);
   825    958       if( pGroup ){
   826         -      pFile = quotaFindFile(pGroup, zFull);
          959  +      pFile = quotaFindFile(pGroup, zFull, 0);
   827    960         if( pFile ) quotaRemoveFile(pFile);
   828    961       }
   829    962       quotaLeave();
   830    963     }
   831    964     sqlite3_free(fd);
   832    965     return rc;
   833    966   }
   834    967   
          968  +/*
          969  +** Open a potentially quotaed file for I/O.
          970  +*/
          971  +quota_FILE *sqlite3_quota_fopen(const char *zFilename, const char *zMode){
          972  +  quota_FILE *p = 0;
          973  +  char *zFull = 0;
          974  +  char *zFullTranslated;
          975  +  int rc;
          976  +  quotaGroup *pGroup;
          977  +  quotaFile *pFile;
          978  +
          979  +  zFull = (char*)sqlite3_malloc(gQuota.sThisVfs.mxPathname + 1);
          980  +  if( zFull==0 ) return 0;
          981  +  rc = gQuota.pOrigVfs->xFullPathname(gQuota.pOrigVfs, zFilename,
          982  +                                      gQuota.sThisVfs.mxPathname+1, zFull);
          983  +  if( rc ) goto quota_fopen_error;
          984  +  p = (quota_FILE*)sqlite3_malloc(sizeof(*p));
          985  +  if( p==0 ) goto quota_fopen_error;
          986  +  memset(p, 0, sizeof(*p));
          987  +  zFullTranslated = quota_utf8_to_mbcs(zFull);
          988  +  if( zFullTranslated==0 ) goto quota_fopen_error;
          989  +  p->f = fopen(zFullTranslated, zMode);
          990  +  quota_mbcs_free(zFullTranslated);
          991  +  if( p->f==0 ) goto quota_fopen_error;
          992  +  quotaEnter();
          993  +  pGroup = quotaGroupFind(zFull);
          994  +  if( pGroup ){
          995  +    pFile = quotaFindFile(pGroup, zFull, 1);
          996  +    if( pFile==0 ){
          997  +      quotaLeave();
          998  +      goto quota_fopen_error;
          999  +    }
         1000  +    pFile->nRef++;
         1001  +    p->pFile = pFile;
         1002  +  }
         1003  +  quotaLeave();
         1004  +  sqlite3_free(zFull);
         1005  +  return p;
         1006  +
         1007  +quota_fopen_error:
         1008  +  sqlite3_free(zFull);
         1009  +  if( p && p->f ) fclose(p->f);
         1010  +  sqlite3_free(p);
         1011  +  return 0;
         1012  +}
         1013  +
         1014  +/*
         1015  +** Read content from a quota_FILE
         1016  +*/
         1017  +size_t sqlite3_quota_fread(
         1018  +  void *pBuf,            /* Store the content here */
         1019  +  size_t size,           /* Size of each element */
         1020  +  size_t nmemb,          /* Number of elements to read */
         1021  +  quota_FILE *p          /* Read from this quota_FILE object */
         1022  +){
         1023  +  return fread(pBuf, size, nmemb, p->f);
         1024  +}
         1025  +
         1026  +/*
         1027  +** Write content into a quota_FILE.  Invoke the quota callback and block
         1028  +** the write if we exceed quota.
         1029  +*/
         1030  +size_t sqlite3_quota_fwrite(
         1031  +  void *pBuf,            /* Take content to write from here */
         1032  +  size_t size,           /* Size of each element */
         1033  +  size_t nmemb,          /* Number of elements */
         1034  +  quota_FILE *p          /* Write to this quota_FILE objecct */
         1035  +){
         1036  +  sqlite3_int64 iOfst;
         1037  +  sqlite3_int64 iEnd;
         1038  +  sqlite3_int64 szNew;
         1039  +  quotaFile *pFile;
         1040  +  
         1041  +  iOfst = ftell(p->f);
         1042  +  iEnd = iOfst + size*nmemb;
         1043  +  pFile = p->pFile;
         1044  +  if( pFile && pFile->iSize<iEnd ){
         1045  +    quotaGroup *pGroup = pFile->pGroup;
         1046  +    quotaEnter();
         1047  +    szNew = pGroup->iSize - pFile->iSize + iEnd;
         1048  +    if( szNew>pGroup->iLimit && pGroup->iLimit>0 ){
         1049  +      if( pGroup->xCallback ){
         1050  +        pGroup->xCallback(pFile->zFilename, &pGroup->iLimit, szNew, 
         1051  +                          pGroup->pArg);
         1052  +      }
         1053  +      if( szNew>pGroup->iLimit && pGroup->iLimit>0 ){
         1054  +        iEnd = pGroup->iLimit - pGroup->iSize + pFile->iSize;
         1055  +        nmemb = (iEnd - iOfst)/size;
         1056  +        iEnd = iOfst + size*nmemb;
         1057  +        szNew = pGroup->iSize - pFile->iSize + iEnd;
         1058  +      }
         1059  +    }
         1060  +    pGroup->iSize = szNew;
         1061  +    pFile->iSize = iEnd;
         1062  +    quotaLeave();
         1063  +  }
         1064  +  return fwrite(pBuf, size, nmemb, p->f);
         1065  +}
         1066  +
         1067  +/*
         1068  +** Close an open quota_FILE stream.
         1069  +*/
         1070  +int sqlite3_quota_fclose(quota_FILE *p){
         1071  +  int rc;
         1072  +  quotaFile *pFile;
         1073  +  rc = fclose(p->f);
         1074  +  pFile = p->pFile;
         1075  +  if( pFile ){
         1076  +    quotaEnter();
         1077  +    pFile->nRef--;
         1078  +    if( pFile->nRef==0 ){
         1079  +      quotaGroup *pGroup = pFile->pGroup;
         1080  +      if( pFile->deleteOnClose ){
         1081  +        gQuota.pOrigVfs->xDelete(gQuota.pOrigVfs, pFile->zFilename, 0);
         1082  +        quotaRemoveFile(pFile);
         1083  +      }
         1084  +      quotaGroupDeref(pGroup);
         1085  +    }
         1086  +    quotaLeave();
         1087  +  }
         1088  +  sqlite3_free(p);
         1089  +  return rc;
         1090  +}
         1091  +
         1092  +/*
         1093  +** Flush memory buffers for a quota_FILE to disk.
         1094  +*/
         1095  +int sqlite3_quota_fflush(quota_FILE *p, int doFsync){
         1096  +  int rc;
         1097  +  rc = fflush(p->f);
         1098  +  if( rc==0 && doFsync ){
         1099  +#if SQLITE_OS_UNIX
         1100  +    rc = fsync(fileno(p->f));
         1101  +#endif
         1102  +#if SQLITE_OS_WIN
         1103  +    rc = _commit(_fileno(p->f));
         1104  +#endif
         1105  +  }
         1106  +  return rc!=0;
         1107  +}
         1108  +
         1109  +/*
         1110  +** Seek on a quota_FILE stream.
         1111  +*/
         1112  +int sqlite3_quota_fseek(quota_FILE *p, long offset, int whence){
         1113  +  return fseek(p->f, offset, whence);
         1114  +}
         1115  +
         1116  +/*
         1117  +** rewind a quota_FILE stream.
         1118  +*/
         1119  +void sqlite3_quota_rewind(quota_FILE *p){
         1120  +  rewind(p->f);
         1121  +}
         1122  +
         1123  +/*
         1124  +** Tell the current location of a quota_FILE stream.
         1125  +*/
         1126  +long sqlite3_quota_ftell(quota_FILE *p){
         1127  +  return ftell(p->f);
         1128  +}
         1129  +
         1130  +/*
         1131  +** Remove a managed file.  Update quotas accordingly.
         1132  +*/
         1133  +int sqlite3_quota_remove(const char *zFilename){
         1134  +  char *zFull;            /* Full pathname for zFilename */
         1135  +  int nFull;              /* Number of bytes in zFilename */
         1136  +  int rc;                 /* Result code */
         1137  +  quotaGroup *pGroup;     /* Group containing zFilename */
         1138  +  quotaFile *pFile;       /* A file in the group */
         1139  +  quotaFile *pNextFile;   /* next file in the group */
         1140  +  int diff;               /* Difference between filenames */
         1141  +  char c;                 /* First character past end of pattern */
         1142  +
         1143  +  zFull = (char*)sqlite3_malloc(gQuota.sThisVfs.mxPathname + 1);
         1144  +  if( zFull==0 ) return SQLITE_NOMEM;
         1145  +  rc = gQuota.pOrigVfs->xFullPathname(gQuota.pOrigVfs, zFilename,
         1146  +                                      gQuota.sThisVfs.mxPathname+1, zFull);
         1147  +  if( rc ){
         1148  +    sqlite3_free(zFull);
         1149  +    return rc;
         1150  +  }
         1151  +
         1152  +  /* Figure out the length of the full pathname.  If the name ends with
         1153  +  ** / (or \ on windows) then remove the trailing /.
         1154  +  */
         1155  +  nFull = strlen(zFull);
         1156  +  if( nFull>0 && (zFull[nFull-1]=='/' || zFull[nFull-1]=='\\') ){
         1157  +    nFull--;
         1158  +    zFull[nFull] = 0;
         1159  +  }
         1160  +
         1161  +  quotaEnter();
         1162  +  pGroup = quotaGroupFind(zFull);
         1163  +  if( pGroup ){
         1164  +    for(pFile=pGroup->pFiles; pFile && rc==SQLITE_OK; pFile=pNextFile){
         1165  +      pNextFile = pFile->pNext;
         1166  +      diff = memcmp(zFull, pFile->zFilename, nFull);
         1167  +      if( diff==0 && ((c = pFile->zFilename[nFull])==0 || c=='/' || c=='\\') ){
         1168  +        if( pFile->nRef ){
         1169  +          pFile->deleteOnClose = 1;
         1170  +        }else{
         1171  +          rc = gQuota.pOrigVfs->xDelete(gQuota.pOrigVfs, pFile->zFilename, 0);
         1172  +          quotaRemoveFile(pFile);
         1173  +          quotaGroupDeref(pGroup);
         1174  +        }
         1175  +      }
         1176  +    }
         1177  +  }
         1178  +  quotaLeave();
         1179  +  sqlite3_free(zFull);
         1180  +  return rc;
         1181  +}
   835   1182     
   836   1183   /***************************** Test Code ***********************************/
   837   1184   #ifdef SQLITE_TEST
   838   1185   #include <tcl.h>
   839   1186   
   840   1187   /*
   841   1188   ** Argument passed to a TCL quota-over-limit callback.
................................................................................
  1056   1403       Tcl_ListObjAppendElement(interp, pGroupTerm,
  1057   1404             Tcl_NewStringObj(pGroup->zPattern, -1));
  1058   1405       Tcl_ListObjAppendElement(interp, pGroupTerm,
  1059   1406             Tcl_NewWideIntObj(pGroup->iLimit));
  1060   1407       Tcl_ListObjAppendElement(interp, pGroupTerm,
  1061   1408             Tcl_NewWideIntObj(pGroup->iSize));
  1062   1409       for(pFile=pGroup->pFiles; pFile; pFile=pFile->pNext){
         1410  +      int i;
         1411  +      char zTemp[1000];
  1063   1412         pFileTerm = Tcl_NewObj();
         1413  +      sqlite3_snprintf(sizeof(zTemp), zTemp, "%s", pFile->zFilename);
         1414  +      for(i=0; zTemp[i]; i++){ if( zTemp[i]=='\\' ) zTemp[i] = '/'; }
  1064   1415         Tcl_ListObjAppendElement(interp, pFileTerm,
  1065         -            Tcl_NewStringObj(pFile->zFilename, -1));
         1416  +            Tcl_NewStringObj(zTemp, -1));
  1066   1417         Tcl_ListObjAppendElement(interp, pFileTerm,
  1067   1418               Tcl_NewWideIntObj(pFile->iSize));
  1068   1419         Tcl_ListObjAppendElement(interp, pFileTerm,
  1069   1420               Tcl_NewWideIntObj(pFile->nRef));
  1070   1421         Tcl_ListObjAppendElement(interp, pFileTerm,
  1071   1422               Tcl_NewWideIntObj(pFile->deleteOnClose));
  1072   1423         Tcl_ListObjAppendElement(interp, pGroupTerm, pFileTerm);
................................................................................
  1073   1424       }
  1074   1425       Tcl_ListObjAppendElement(interp, pResult, pGroupTerm);
  1075   1426     }
  1076   1427     quotaLeave();
  1077   1428     Tcl_SetObjResult(interp, pResult);
  1078   1429     return TCL_OK;
  1079   1430   }
         1431  +
         1432  +/*
         1433  +** tclcmd: sqlite3_quota_fopen FILENAME MODE
         1434  +*/
         1435  +static int test_quota_fopen(
         1436  +  void * clientData,
         1437  +  Tcl_Interp *interp,
         1438  +  int objc,
         1439  +  Tcl_Obj *CONST objv[]
         1440  +){
         1441  +  const char *zFilename;          /* File pattern to configure */
         1442  +  const char *zMode;              /* Mode string */
         1443  +  quota_FILE *p;                  /* Open string object */
         1444  +  char zReturn[50];               /* Name of pointer to return */
         1445  +
         1446  +  /* Process arguments */
         1447  +  if( objc!=3 ){
         1448  +    Tcl_WrongNumArgs(interp, 1, objv, "FILENAME MODE");
         1449  +    return TCL_ERROR;
         1450  +  }
         1451  +  zFilename = Tcl_GetString(objv[1]);
         1452  +  zMode = Tcl_GetString(objv[2]);
         1453  +  p = sqlite3_quota_fopen(zFilename, zMode);
         1454  +  sqlite3_snprintf(sizeof(zReturn), zReturn, "%p", p);
         1455  +  Tcl_SetResult(interp, zReturn, TCL_VOLATILE);
         1456  +  return TCL_OK;
         1457  +}
         1458  +
         1459  +/* Defined in test1.c */
         1460  +extern void *sqlite3TestTextToPtr(const char*);
         1461  +
         1462  +/*
         1463  +** tclcmd: sqlite3_quota_fread HANDLE SIZE NELEM
         1464  +*/
         1465  +static int test_quota_fread(
         1466  +  void * clientData,
         1467  +  Tcl_Interp *interp,
         1468  +  int objc,
         1469  +  Tcl_Obj *CONST objv[]
         1470  +){
         1471  +  quota_FILE *p;
         1472  +  char *zBuf;
         1473  +  int sz;
         1474  +  int nElem;
         1475  +  int got;
         1476  +
         1477  +  if( objc!=4 ){
         1478  +    Tcl_WrongNumArgs(interp, 1, objv, "HANDLE SIZE NELEM");
         1479  +    return TCL_ERROR;
         1480  +  }
         1481  +  p = sqlite3TestTextToPtr(Tcl_GetString(objv[1]));
         1482  +  if( Tcl_GetIntFromObj(interp, objv[2], &sz) ) return TCL_ERROR;
         1483  +  if( Tcl_GetIntFromObj(interp, objv[3], &nElem) ) return TCL_ERROR;
         1484  +  zBuf = (char*)sqlite3_malloc( sz*nElem + 1 );
         1485  +  if( zBuf==0 ){
         1486  +    Tcl_SetResult(interp, "out of memory", TCL_STATIC);
         1487  +    return TCL_ERROR;
         1488  +  }
         1489  +  got = sqlite3_quota_fread(zBuf, sz, nElem, p);
         1490  +  if( got<0 ) got = 0;
         1491  +  zBuf[got*sz] = 0;
         1492  +  Tcl_SetResult(interp, zBuf, TCL_VOLATILE);
         1493  +  sqlite3_free(zBuf);
         1494  +  return TCL_OK;
         1495  +}
         1496  +
         1497  +/*
         1498  +** tclcmd: sqlite3_quota_fwrite HANDLE SIZE NELEM CONTENT
         1499  +*/
         1500  +static int test_quota_fwrite(
         1501  +  void * clientData,
         1502  +  Tcl_Interp *interp,
         1503  +  int objc,
         1504  +  Tcl_Obj *CONST objv[]
         1505  +){
         1506  +  quota_FILE *p;
         1507  +  char *zBuf;
         1508  +  int sz;
         1509  +  int nElem;
         1510  +  int got;
         1511  +
         1512  +  if( objc!=5 ){
         1513  +    Tcl_WrongNumArgs(interp, 1, objv, "HANDLE SIZE NELEM CONTENT");
         1514  +    return TCL_ERROR;
         1515  +  }
         1516  +  p = sqlite3TestTextToPtr(Tcl_GetString(objv[1]));
         1517  +  if( Tcl_GetIntFromObj(interp, objv[2], &sz) ) return TCL_ERROR;
         1518  +  if( Tcl_GetIntFromObj(interp, objv[3], &nElem) ) return TCL_ERROR;
         1519  +  zBuf = Tcl_GetString(objv[4]);
         1520  +  got = sqlite3_quota_fwrite(zBuf, sz, nElem, p);
         1521  +  Tcl_SetObjResult(interp, Tcl_NewIntObj(got));
         1522  +  return TCL_OK;
         1523  +}
         1524  +
         1525  +/*
         1526  +** tclcmd: sqlite3_quota_fclose HANDLE
         1527  +*/
         1528  +static int test_quota_fclose(
         1529  +  void * clientData,
         1530  +  Tcl_Interp *interp,
         1531  +  int objc,
         1532  +  Tcl_Obj *CONST objv[]
         1533  +){
         1534  +  quota_FILE *p;
         1535  +  int rc;
         1536  +
         1537  +  if( objc!=2 ){
         1538  +    Tcl_WrongNumArgs(interp, 1, objv, "HANDLE");
         1539  +    return TCL_ERROR;
         1540  +  }
         1541  +  p = sqlite3TestTextToPtr(Tcl_GetString(objv[1]));
         1542  +  rc = sqlite3_quota_fclose(p);
         1543  +  Tcl_SetObjResult(interp, Tcl_NewIntObj(rc));
         1544  +  return TCL_OK;
         1545  +}
         1546  +
         1547  +/*
         1548  +** tclcmd: sqlite3_quota_fflush HANDLE ?HARDSYNC?
         1549  +*/
         1550  +static int test_quota_fflush(
         1551  +  void * clientData,
         1552  +  Tcl_Interp *interp,
         1553  +  int objc,
         1554  +  Tcl_Obj *CONST objv[]
         1555  +){
         1556  +  quota_FILE *p;
         1557  +  int rc;
         1558  +  int doSync = 0;
         1559  +
         1560  +  if( objc!=2 && objc!=3 ){
         1561  +    Tcl_WrongNumArgs(interp, 1, objv, "HANDLE ?HARDSYNC?");
         1562  +    return TCL_ERROR;
         1563  +  }
         1564  +  p = sqlite3TestTextToPtr(Tcl_GetString(objv[1]));
         1565  +  if( objc==3 ){
         1566  +    if( Tcl_GetBooleanFromObj(interp, objv[2], &doSync) ) return TCL_ERROR;
         1567  +  }
         1568  +  rc = sqlite3_quota_fflush(p, doSync);
         1569  +  Tcl_SetObjResult(interp, Tcl_NewIntObj(rc));
         1570  +  return TCL_OK;
         1571  +}
         1572  +
         1573  +/*
         1574  +** tclcmd: sqlite3_quota_fseek HANDLE OFFSET WHENCE
         1575  +*/
         1576  +static int test_quota_fseek(
         1577  +  void * clientData,
         1578  +  Tcl_Interp *interp,
         1579  +  int objc,
         1580  +  Tcl_Obj *CONST objv[]
         1581  +){
         1582  +  quota_FILE *p;
         1583  +  int ofst;
         1584  +  const char *zWhence;
         1585  +  int whence;
         1586  +  int rc;
         1587  +
         1588  +  if( objc!=4 ){
         1589  +    Tcl_WrongNumArgs(interp, 1, objv, "HANDLE OFFSET WHENCE");
         1590  +    return TCL_ERROR;
         1591  +  }
         1592  +  p = sqlite3TestTextToPtr(Tcl_GetString(objv[1]));
         1593  +  if( Tcl_GetIntFromObj(interp, objv[2], &ofst) ) return TCL_ERROR;
         1594  +  zWhence = Tcl_GetString(objv[3]);
         1595  +  if( strcmp(zWhence, "SEEK_SET")==0 ){
         1596  +    whence = SEEK_SET;
         1597  +  }else if( strcmp(zWhence, "SEEK_CUR")==0 ){
         1598  +    whence = SEEK_CUR;
         1599  +  }else if( strcmp(zWhence, "SEEK_END")==0 ){
         1600  +    whence = SEEK_END;
         1601  +  }else{
         1602  +    Tcl_AppendResult(interp,
         1603  +           "WHENCE should be SEEK_SET, SEEK_CUR, or SEEK_END", (char*)0);
         1604  +    return TCL_ERROR;
         1605  +  }
         1606  +  rc = sqlite3_quota_fseek(p, ofst, whence);
         1607  +  Tcl_SetObjResult(interp, Tcl_NewIntObj(rc));
         1608  +  return TCL_OK;
         1609  +}
         1610  +
         1611  +/*
         1612  +** tclcmd: sqlite3_quota_rewind HANDLE
         1613  +*/
         1614  +static int test_quota_rewind(
         1615  +  void * clientData,
         1616  +  Tcl_Interp *interp,
         1617  +  int objc,
         1618  +  Tcl_Obj *CONST objv[]
         1619  +){
         1620  +  quota_FILE *p;
         1621  +  if( objc!=2 ){
         1622  +    Tcl_WrongNumArgs(interp, 1, objv, "HANDLE");
         1623  +    return TCL_ERROR;
         1624  +  }
         1625  +  p = sqlite3TestTextToPtr(Tcl_GetString(objv[1]));
         1626  +  sqlite3_quota_rewind(p);
         1627  +  return TCL_OK;
         1628  +}
         1629  +
         1630  +/*
         1631  +** tclcmd: sqlite3_quota_ftell HANDLE
         1632  +*/
         1633  +static int test_quota_ftell(
         1634  +  void * clientData,
         1635  +  Tcl_Interp *interp,
         1636  +  int objc,
         1637  +  Tcl_Obj *CONST objv[]
         1638  +){
         1639  +  quota_FILE *p;
         1640  +  sqlite3_int64 x;
         1641  +  if( objc!=2 ){
         1642  +    Tcl_WrongNumArgs(interp, 1, objv, "HANDLE");
         1643  +    return TCL_ERROR;
         1644  +  }
         1645  +  p = sqlite3TestTextToPtr(Tcl_GetString(objv[1]));
         1646  +  x = sqlite3_quota_ftell(p);
         1647  +  Tcl_SetObjResult(interp, Tcl_NewWideIntObj(x));
         1648  +  return TCL_OK;
         1649  +}
         1650  +
         1651  +/*
         1652  +** tclcmd: sqlite3_quota_remove FILENAME
         1653  +*/
         1654  +static int test_quota_remove(
         1655  +  void * clientData,
         1656  +  Tcl_Interp *interp,
         1657  +  int objc,
         1658  +  Tcl_Obj *CONST objv[]
         1659  +){
         1660  +  const char *zFilename;          /* File pattern to configure */
         1661  +  int rc;
         1662  +  if( objc!=2 ){
         1663  +    Tcl_WrongNumArgs(interp, 1, objv, "FILENAME");
         1664  +    return TCL_ERROR;
         1665  +  }
         1666  +  zFilename = Tcl_GetString(objv[1]);
         1667  +  rc = sqlite3_quota_remove(zFilename);
         1668  +  Tcl_SetObjResult(interp, Tcl_NewIntObj(rc));
         1669  +  return TCL_OK;
         1670  +}
         1671  +
         1672  +/*
         1673  +** tclcmd: sqlite3_quota_glob PATTERN TEXT
         1674  +**
         1675  +** Test the glob pattern matching.  Return 1 if TEXT matches PATTERN
         1676  +** and return 0 if it does not.
         1677  +*/
         1678  +static int test_quota_glob(
         1679  +  void * clientData,
         1680  +  Tcl_Interp *interp,
         1681  +  int objc,
         1682  +  Tcl_Obj *CONST objv[]
         1683  +){
         1684  +  const char *zPattern;          /* The glob pattern */
         1685  +  const char *zText;             /* Text to compare agains the pattern */
         1686  +  int rc;
         1687  +  if( objc!=3 ){
         1688  +    Tcl_WrongNumArgs(interp, 1, objv, "PATTERN TEXT");
         1689  +    return TCL_ERROR;
         1690  +  }
         1691  +  zPattern = Tcl_GetString(objv[1]);
         1692  +  zText = Tcl_GetString(objv[2]);
         1693  +  rc = quotaStrglob(zPattern, zText);
         1694  +  Tcl_SetObjResult(interp, Tcl_NewIntObj(rc));
         1695  +  return TCL_OK;
         1696  +}
  1080   1697   
  1081   1698   /*
  1082   1699   ** This routine registers the custom TCL commands defined in this
  1083   1700   ** module.  This should be the only procedure visible from outside
  1084   1701   ** of this module.
  1085   1702   */
  1086   1703   int Sqlitequota_Init(Tcl_Interp *interp){
  1087   1704     static struct {
  1088   1705        char *zName;
  1089   1706        Tcl_ObjCmdProc *xProc;
  1090   1707     } aCmd[] = {
  1091   1708       { "sqlite3_quota_initialize", test_quota_initialize },
  1092         -    { "sqlite3_quota_shutdown", test_quota_shutdown },
  1093         -    { "sqlite3_quota_set", test_quota_set },
  1094         -    { "sqlite3_quota_file", test_quota_file },
  1095         -    { "sqlite3_quota_dump", test_quota_dump },
         1709  +    { "sqlite3_quota_shutdown",   test_quota_shutdown },
         1710  +    { "sqlite3_quota_set",        test_quota_set },
         1711  +    { "sqlite3_quota_file",       test_quota_file },
         1712  +    { "sqlite3_quota_dump",       test_quota_dump },
         1713  +    { "sqlite3_quota_fopen",      test_quota_fopen },
         1714  +    { "sqlite3_quota_fread",      test_quota_fread },
         1715  +    { "sqlite3_quota_fwrite",     test_quota_fwrite },
         1716  +    { "sqlite3_quota_fclose",     test_quota_fclose },
         1717  +    { "sqlite3_quota_fflush",     test_quota_fflush },
         1718  +    { "sqlite3_quota_fseek",      test_quota_fseek },
         1719  +    { "sqlite3_quota_rewind",     test_quota_rewind },
         1720  +    { "sqlite3_quota_ftell",      test_quota_ftell },
         1721  +    { "sqlite3_quota_remove",     test_quota_remove },
         1722  +    { "sqlite3_quota_glob",       test_quota_glob },
  1096   1723     };
  1097   1724     int i;
  1098   1725   
  1099   1726     for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){
  1100   1727       Tcl_CreateObjCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0);
  1101   1728     }
  1102   1729   
  1103   1730     return TCL_OK;
  1104   1731   }
  1105   1732   #endif

Added src/test_quota.h.

            1  +/*
            2  +** 2011 December 1
            3  +**
            4  +** The author disclaims copyright to this source code.  In place of
            5  +** a legal notice, here is a blessing:
            6  +**
            7  +**    May you do good and not evil.
            8  +**    May you find forgiveness for yourself and forgive others.
            9  +**    May you share freely, never taking more than you give.
           10  +**
           11  +*************************************************************************
           12  +**
           13  +** This file contains the interface definition for the quota a VFS shim.
           14  +**
           15  +** This particular shim enforces a quota system on files.  One or more
           16  +** database files are in a "quota group" that is defined by a GLOB
           17  +** pattern.  A quota is set for the combined size of all files in the
           18  +** the group.  A quota of zero means "no limit".  If the total size
           19  +** of all files in the quota group is greater than the limit, then
           20  +** write requests that attempt to enlarge a file fail with SQLITE_FULL.
           21  +**
           22  +** However, before returning SQLITE_FULL, the write requests invoke
           23  +** a callback function that is configurable for each quota group.
           24  +** This callback has the opportunity to enlarge the quota.  If the
           25  +** callback does enlarge the quota such that the total size of all
           26  +** files within the group is less than the new quota, then the write
           27  +** continues as if nothing had happened.
           28  +*/
           29  +#ifndef _QUOTA_H_
           30  +#include "sqlite3.h"
           31  +#include <stdio.h>
           32  +
           33  +/* Make this callable from C++ */
           34  +#ifdef __cplusplus
           35  +extern "C" {
           36  +#endif
           37  +
           38  +/*
           39  +** Initialize the quota VFS shim.  Use the VFS named zOrigVfsName
           40  +** as the VFS that does the actual work.  Use the default if
           41  +** zOrigVfsName==NULL.  
           42  +**
           43  +** The quota VFS shim is named "quota".  It will become the default
           44  +** VFS if makeDefault is non-zero.
           45  +**
           46  +** THIS ROUTINE IS NOT THREADSAFE.  Call this routine exactly once
           47  +** during start-up.
           48  +*/
           49  +int sqlite3_quota_initialize(const char *zOrigVfsName, int makeDefault);
           50  +
           51  +/*
           52  +** Shutdown the quota system.
           53  +**
           54  +** All SQLite database connections must be closed before calling this
           55  +** routine.
           56  +**
           57  +** THIS ROUTINE IS NOT THREADSAFE.  Call this routine exactly once while
           58  +** shutting down in order to free all remaining quota groups.
           59  +*/
           60  +int sqlite3_quota_shutdown(void);
           61  +
           62  +/*
           63  +** Create or destroy a quota group.
           64  +**
           65  +** The quota group is defined by the zPattern.  When calling this routine
           66  +** with a zPattern for a quota group that already exists, this routine
           67  +** merely updates the iLimit, xCallback, and pArg values for that quota
           68  +** group.  If zPattern is new, then a new quota group is created.
           69  +**
           70  +** The zPattern is always compared against the full pathname of the file.
           71  +** Even if APIs are called with relative pathnames, SQLite converts the
           72  +** name to a full pathname before comparing it against zPattern.  zPattern
           73  +** is a glob pattern with the following matching rules:
           74  +**
           75  +**      '*'       Matches any sequence of zero or more characters.
           76  +**
           77  +**      '?'       Matches exactly one character.
           78  +**
           79  +**     [...]      Matches one character from the enclosed list of
           80  +**                characters.  "]" can be part of the list if it is
           81  +**                the first character.  Within the list "X-Y" matches
           82  +**                characters X or Y or any character in between the
           83  +**                two.  Ex:  "[0-9]" matches any digit.
           84  +**
           85  +**     [^...]     Matches one character not in the enclosed list.
           86  +**
           87  +**     /          Matches either / or \.  This allows glob patterns
           88  +**                containing / to work on both unix and windows.
           89  +**
           90  +** Note that, unlike unix shell globbing, the directory separator "/"
           91  +** can match a wildcard.  So, for example, the pattern "/abc/xyz/" "*"
           92  +** matches any files anywhere in the directory hierarchy beneath
           93  +** /abc/xyz.
           94  +**
           95  +** The glob algorithm works on bytes.  Multi-byte UTF8 characters are
           96  +** matched as if each byte were a separate character.
           97  +**
           98  +** If the iLimit for a quota group is set to zero, then the quota group
           99  +** is disabled and will be deleted when the last database connection using
          100  +** the quota group is closed.
          101  +**
          102  +** Calling this routine on a zPattern that does not exist and with a
          103  +** zero iLimit is a no-op.
          104  +**
          105  +** A quota group must exist with a non-zero iLimit prior to opening
          106  +** database connections if those connections are to participate in the
          107  +** quota group.  Creating a quota group does not affect database connections
          108  +** that are already open.
          109  +**
          110  +** The patterns that define the various quota groups should be distinct.
          111  +** If the same filename matches more than one quota group pattern, then
          112  +** the behavior of this package is undefined.
          113  +*/
          114  +int sqlite3_quota_set(
          115  +  const char *zPattern,           /* The filename pattern */
          116  +  sqlite3_int64 iLimit,           /* New quota to set for this quota group */
          117  +  void (*xCallback)(              /* Callback invoked when going over quota */
          118  +     const char *zFilename,         /* Name of file whose size increases */
          119  +     sqlite3_int64 *piLimit,        /* IN/OUT: The current limit */
          120  +     sqlite3_int64 iSize,           /* Total size of all files in the group */
          121  +     void *pArg                     /* Client data */
          122  +  ),
          123  +  void *pArg,                     /* client data passed thru to callback */
          124  +  void (*xDestroy)(void*)         /* Optional destructor for pArg */
          125  +);
          126  +
          127  +/*
          128  +** Bring the named file under quota management, assuming its name matches
          129  +** the glob pattern of some quota group.  Or if it is already under
          130  +** management, update its size.  If zFilename does not match the glob
          131  +** pattern of any quota group, this routine is a no-op.
          132  +*/
          133  +int sqlite3_quota_file(const char *zFilename);
          134  +
          135  +/*
          136  +** The following object serves the same role as FILE in the standard C
          137  +** library.  It represents an open connection to a file on disk for I/O.
          138  +**
          139  +** A single quota_FILE should not be used by two or more threads at the
          140  +** same time.  Multiple threads can be using different quota_FILE objects
          141  +** simultaneously, but not the same quota_FILE object.
          142  +*/
          143  +typedef struct quota_FILE quota_FILE;
          144  +
          145  +/*
          146  +** Create a new quota_FILE object used to read and/or write to the
          147  +** file zFilename.  The zMode parameter is as with standard library zMode.
          148  +*/
          149  +quota_FILE *sqlite3_quota_fopen(const char *zFilename, const char *zMode);
          150  +
          151  +/*
          152  +** Perform I/O against a quota_FILE object.  When doing writes, the
          153  +** quota mechanism may result in a short write, in order to prevent
          154  +** the sum of sizes of all files from going over quota.
          155  +*/
          156  +size_t sqlite3_quota_fread(void*, size_t, size_t, quota_FILE*);
          157  +size_t sqlite3_quota_fwrite(void*, size_t, size_t, quota_FILE*);
          158  +
          159  +/*
          160  +** Flush all written content held in memory buffers out to disk.
          161  +** This is the equivalent of fflush() in the standard library.
          162  +**
          163  +** If the hardSync parameter is true (non-zero) then this routine
          164  +** also forces OS buffers to disk - the equivalent of fsync().
          165  +**
          166  +** This routine return zero on success and non-zero if something goes
          167  +** wrong.
          168  +*/
          169  +int sqlite3_quota_fflush(quota_FILE*, int hardSync);
          170  +
          171  +/*
          172  +** Close a quota_FILE object and free all associated resources.  The
          173  +** file remains under quota management.
          174  +*/
          175  +int sqlite3_quota_fclose(quota_FILE*);
          176  +
          177  +/*
          178  +** Move the read/write pointer for a quota_FILE object.  Or tell the
          179  +** current location of the read/write pointer.
          180  +*/
          181  +int sqlite3_quota_fseek(quota_FILE*, long, int);
          182  +void sqlite3_quota_rewind(quota_FILE*);
          183  +long sqlite3_quota_ftell(quota_FILE*);
          184  +
          185  +/*
          186  +** Delete a file from the disk, if that file is under quota management.
          187  +** Adjust quotas accordingly.
          188  +**
          189  +** If zFilename is the name of a directory that matches one of the
          190  +** quota glob patterns, then all files under quota management that
          191  +** are contained within that directory are deleted.
          192  +**
          193  +** A standard SQLite result code is returned (SQLITE_OK, SQLITE_NOMEM, etc.)
          194  +** When deleting a directory of files, if the deletion of any one
          195  +** file fails (for example due to an I/O error), then this routine
          196  +** returns immediately, with the error code, and does not try to 
          197  +** delete any of the other files in the specified directory.
          198  +**
          199  +** All files are removed from quota management and deleted from disk.
          200  +** However, no attempt is made to remove empty directories.
          201  +**
          202  +** This routine is a no-op for files that are not under quota management.
          203  +*/
          204  +int sqlite3_quota_remove(const char *zFilename);
          205  +
          206  +#ifdef __cplusplus
          207  +}  /* end of the 'extern "C"' block */
          208  +#endif
          209  +#endif /* _QUOTA_H_ */

Changes to src/test_stat.c.

   365    365     Btree *pBt = pTab->db->aDb[0].pBt;
   366    366     Pager *pPager = sqlite3BtreePager(pBt);
   367    367     sqlite3_file *fd;
   368    368     sqlite3_int64 x[2];
   369    369   
   370    370     /* The default page size and offset */
   371    371     pCsr->szPage = sqlite3BtreeGetPageSize(pBt);
   372         -  pCsr->iOffset = pCsr->szPage * (pCsr->iPageno - 1);
          372  +  pCsr->iOffset = (i64)pCsr->szPage * (pCsr->iPageno - 1);
   373    373   
   374    374     /* If connected to a ZIPVFS backend, override the page size and
   375    375     ** offset with actual values obtained from ZIPVFS.
   376    376     */
   377    377     fd = sqlite3PagerFile(pPager);
   378    378     x[0] = pCsr->iPageno;
   379    379     if( sqlite3OsFileControl(fd, 230440, &x)==SQLITE_OK ){

Changes to src/test_vfs.c.

  1158   1158   
  1159   1159       case CMD_DEVCHAR: {
  1160   1160         struct DeviceFlag {
  1161   1161           char *zName;
  1162   1162           int iValue;
  1163   1163         } aFlag[] = {
  1164   1164           { "default",               -1 },
  1165         -        { "atomic",                SQLITE_IOCAP_ATOMIC      },
  1166         -        { "atomic512",             SQLITE_IOCAP_ATOMIC512   },
  1167         -        { "atomic1k",              SQLITE_IOCAP_ATOMIC1K    },
  1168         -        { "atomic2k",              SQLITE_IOCAP_ATOMIC2K    },
  1169         -        { "atomic4k",              SQLITE_IOCAP_ATOMIC4K    },
  1170         -        { "atomic8k",              SQLITE_IOCAP_ATOMIC8K    },
  1171         -        { "atomic16k",             SQLITE_IOCAP_ATOMIC16K   },
  1172         -        { "atomic32k",             SQLITE_IOCAP_ATOMIC32K   },
  1173         -        { "atomic64k",             SQLITE_IOCAP_ATOMIC64K   },
  1174         -        { "sequential",            SQLITE_IOCAP_SEQUENTIAL  },
  1175         -        { "safe_append",           SQLITE_IOCAP_SAFE_APPEND },
         1165  +        { "atomic",                SQLITE_IOCAP_ATOMIC                },
         1166  +        { "atomic512",             SQLITE_IOCAP_ATOMIC512             },
         1167  +        { "atomic1k",              SQLITE_IOCAP_ATOMIC1K              },
         1168  +        { "atomic2k",              SQLITE_IOCAP_ATOMIC2K              },
         1169  +        { "atomic4k",              SQLITE_IOCAP_ATOMIC4K              },
         1170  +        { "atomic8k",              SQLITE_IOCAP_ATOMIC8K              },
         1171  +        { "atomic16k",             SQLITE_IOCAP_ATOMIC16K             },
         1172  +        { "atomic32k",             SQLITE_IOCAP_ATOMIC32K             },
         1173  +        { "atomic64k",             SQLITE_IOCAP_ATOMIC64K             },
         1174  +        { "sequential",            SQLITE_IOCAP_SEQUENTIAL            },
         1175  +        { "safe_append",           SQLITE_IOCAP_SAFE_APPEND           },
  1176   1176           { "undeletable_when_open", SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN },
         1177  +        { "powersafe_overwrite",   SQLITE_IOCAP_POWERSAFE_OVERWRITE   },
  1177   1178           { 0, 0 }
  1178   1179         };
  1179   1180         Tcl_Obj *pRet;
  1180   1181         int iFlag;
  1181   1182   
  1182   1183         if( objc>3 ){
  1183   1184           Tcl_WrongNumArgs(interp, 2, objv, "?ATTR-LIST?");
................................................................................
  1203   1204             if( aFlag[idx].iValue<0 && nFlags>1 ){
  1204   1205               Tcl_AppendResult(interp, "bad flags: ", Tcl_GetString(objv[2]), 0);
  1205   1206               return TCL_ERROR;
  1206   1207             }
  1207   1208             iNew |= aFlag[idx].iValue;
  1208   1209           }
  1209   1210   
  1210         -        p->iDevchar = iNew;
         1211  +        p->iDevchar = iNew| 0x10000000;
  1211   1212         }
  1212   1213   
  1213   1214         pRet = Tcl_NewObj();
  1214   1215         for(iFlag=0; iFlag<sizeof(aFlag)/sizeof(aFlag[0]); iFlag++){
  1215   1216           if( p->iDevchar & aFlag[iFlag].iValue ){
  1216   1217             Tcl_ListObjAppendElement(
  1217   1218                 interp, pRet, Tcl_NewStringObj(aFlag[iFlag].zName, -1)

Changes to src/test_vfstrace.c.

   467    467       case SQLITE_FCNTL_CHUNK_SIZE: {
   468    468         sqlite3_snprintf(sizeof(zBuf), zBuf, "CHUNK_SIZE,%d", *(int*)pArg);
   469    469         zOp = zBuf;
   470    470         break;
   471    471       }
   472    472       case SQLITE_FCNTL_FILE_POINTER: zOp = "FILE_POINTER";       break;
   473    473       case SQLITE_FCNTL_SYNC_OMITTED: zOp = "SYNC_OMITTED";       break;
          474  +    case SQLITE_FCNTL_WIN32_AV_RETRY: zOp = "WIN32_AV_RETRY";   break;
          475  +    case SQLITE_FCNTL_PERSIST_WAL:  zOp = "PERSIST_WAL";        break;
          476  +    case SQLITE_FCNTL_OVERWRITE:    zOp = "OVERWRITE";          break;
          477  +    case SQLITE_FCNTL_VFSNAME:      zOp = "VFSNAME";            break;
   474    478       case 0xca093fa0:                zOp = "DB_UNCHANGED";       break;
   475    479       default: {
   476    480         sqlite3_snprintf(sizeof zBuf, zBuf, "%d", op);
   477    481         zOp = zBuf;
   478    482         break;
   479    483       }
   480    484     }
   481    485     vfstrace_printf(pInfo, "%s.xFileControl(%s,%s)",
   482    486                     pInfo->zVfsName, p->zFName, zOp);
   483    487     rc = p->pReal->pMethods->xFileControl(p->pReal, op, pArg);
   484    488     vfstrace_print_errcode(pInfo, " -> %s\n", rc);
          489  +  if( op==SQLITE_FCNTL_VFSNAME && rc==SQLITE_OK ){
          490  +    *(char**)pArg = sqlite3_mprintf("vfstrace.%s/%z",
          491  +                                    pInfo->zVfsName, *(char**)pArg);
          492  +  }
   485    493     return rc;
   486    494   }
   487    495   
   488    496   /*
   489    497   ** Return the sector-size in bytes for an vfstrace-file.
   490    498   */
   491    499   static int vfstraceSectorSize(sqlite3_file *pFile){

Changes to src/tokenize.c.

   119    119         testcase( z[0]=='\r' );
   120    120         for(i=1; sqlite3Isspace(z[i]); i++){}
   121    121         *tokenType = TK_SPACE;
   122    122         return i;
   123    123       }
   124    124       case '-': {
   125    125         if( z[1]=='-' ){
   126         -        /* IMP: R-15891-05542 -- syntax diagram for comments */
          126  +        /* IMP: R-50417-27976 -- syntax diagram for comments */
   127    127           for(i=2; (c=z[i])!=0 && c!='\n'; i++){}
   128    128           *tokenType = TK_SPACE;   /* IMP: R-22934-25134 */
   129    129           return i;
   130    130         }
   131    131         *tokenType = TK_MINUS;
   132    132         return 1;
   133    133       }
................................................................................
   152    152         return 1;
   153    153       }
   154    154       case '/': {
   155    155         if( z[1]!='*' || z[2]==0 ){
   156    156           *tokenType = TK_SLASH;
   157    157           return 1;
   158    158         }
   159         -      /* IMP: R-15891-05542 -- syntax diagram for comments */
          159  +      /* IMP: R-50417-27976 -- syntax diagram for comments */
   160    160         for(i=3, c=z[2]; (c!='*' || z[i]!='/') && (c=z[i])!=0; i++){}
   161    161         if( c ) i++;
   162    162         *tokenType = TK_SPACE;   /* IMP: R-22934-25134 */
   163    163         return i;
   164    164       }
   165    165       case '%': {
   166    166         *tokenType = TK_REM;

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/util.c.

  1160   1160   ** if filename in z[] has a suffix (a.k.a. "extension") that is longer than
  1161   1161   ** three characters, then shorten the suffix on z[] to be the last three
  1162   1162   ** characters of the original suffix.
  1163   1163   **
  1164   1164   ** If SQLITE_ENABLE_8_3_NAMES is set to 2 at compile-time, then always
  1165   1165   ** do the suffix shortening regardless of URI parameter.
  1166   1166   **
         1167  +** Assume that zBaseFilename contains two \000 terminator bytes (so that
         1168  +** it can be harmlessly passed into sqlite3_uri_parameter()) and copy both
         1169  +** zero terminator bytes into the end of the revised name.
         1170  +**
  1167   1171   ** Examples:
  1168   1172   **
  1169   1173   **     test.db-journal    =>   test.nal
  1170   1174   **     test.db-wal        =>   test.wal
  1171   1175   **     test.db-shm        =>   test.shm
         1176  +**     test.db-mj7f3319fa =>   test.9fa
  1172   1177   */
  1173   1178   void sqlite3FileSuffix3(const char *zBaseFilename, char *z){
         1179  +  assert( zBaseFilename[strlen(zBaseFilename)+1]==0 );
  1174   1180   #if SQLITE_ENABLE_8_3_NAMES<2
  1175         -  const char *zOk;
  1176         -  zOk = sqlite3_uri_parameter(zBaseFilename, "8_3_names");
  1177         -  if( zOk && sqlite3GetBoolean(zOk) )
         1181  +  if( sqlite3_uri_boolean(zBaseFilename, "8_3_names", 0) )
  1178   1182   #endif
  1179   1183     {
  1180   1184       int i, sz;
  1181   1185       sz = sqlite3Strlen30(z);
  1182   1186       for(i=sz-1; i>0 && z[i]!='/' && z[i]!='.'; i--){}
  1183         -    if( z[i]=='.' && ALWAYS(sz>i+4) ) memmove(&z[i+1], &z[sz-3], 4);
         1187  +    if( z[i]=='.' && ALWAYS(sz>i+4) ) memmove(&z[i+1], &z[sz-3], 5);
  1184   1188     }
  1185   1189   }
  1186   1190   #endif

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
................................................................................
  1134   1148     }
  1135   1149   
  1136   1150     /* Invalidate all ephemeral cursor row caches */
  1137   1151     p->cacheCtr = (p->cacheCtr + 2)|1;
  1138   1152   
  1139   1153     /* Make sure the results of the current row are \000 terminated
  1140   1154     ** and have an assigned type.  The results are de-ephemeralized as
  1141         -  ** as side effect.
         1155  +  ** a side effect.
  1142   1156     */
  1143   1157     pMem = p->pResultSet = &aMem[pOp->p1];
  1144   1158     for(i=0; i<pOp->p2; i++){
  1145   1159       assert( memIsValid(&pMem[i]) );
  1146   1160       Deephemeralize(&pMem[i]);
  1147   1161       assert( (pMem[i].flags & MEM_Ephem)==0
  1148   1162               || (pMem[i].flags & (MEM_Str|MEM_Blob))==0 );
................................................................................
  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.

    29     29   ** Boolean values
    30     30   */
    31     31   typedef unsigned char Bool;
    32     32   
    33     33   /* Opaque type used by code in vdbesort.c */
    34     34   typedef struct VdbeSorter VdbeSorter;
    35     35   
           36  +/* Opaque type used by the explainer */
           37  +typedef struct Explain Explain;
           38  +
    36     39   /*
    37     40   ** A cursor is a pointer into a single BTree within a database file.
    38     41   ** The cursor can seek to a BTree entry with a particular key, or
    39     42   ** loop over all entries of the Btree.  You can also insert new BTree
    40     43   ** entries or retrieve the key or data from the entry that the cursor
    41     44   ** is currently pointing to.
    42     45   ** 
................................................................................
   113    116   struct VdbeFrame {
   114    117     Vdbe *v;                /* VM this frame belongs to */
   115    118     int pc;                 /* Program Counter in parent (calling) frame */
   116    119     Op *aOp;                /* Program instructions for parent frame */
   117    120     int nOp;                /* Size of aOp array */
   118    121     Mem *aMem;              /* Array of memory cells for parent frame */
   119    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 */
   120    125     VdbeCursor **apCsr;     /* Array of Vdbe cursors for parent frame */
   121    126     u16 nCursor;            /* Number of entries in apCsr */
   122    127     void *token;            /* Copy of SubProgram.token */
   123    128     int nChildMem;          /* Number of memory cells for child frame */
   124    129     int nChildCsr;          /* Number of cursors for child frame */
   125    130     i64 lastRowid;          /* Last insert rowid (sqlite3.lastRowid) */
   126    131     int nChange;            /* Statement changes (Vdbe.nChanges)     */
................................................................................
   251    256     VdbeFunc *pVdbeFunc;  /* Auxilary data, if created. */
   252    257     Mem s;                /* The return value is stored here */
   253    258     Mem *pMem;            /* Memory cell used to store aggregate context */
   254    259     int isError;          /* Error code returned by the function. */
   255    260     CollSeq *pColl;       /* Collating sequence */
   256    261   };
   257    262   
          263  +/*
          264  +** An Explain object accumulates indented output which is helpful
          265  +** in describing recursive data structures.
          266  +*/
          267  +struct Explain {
          268  +  Vdbe *pVdbe;       /* Attach the explanation to this Vdbe */
          269  +  StrAccum str;      /* The string being accumulated */
          270  +  int nIndent;       /* Number of elements in aIndent */
          271  +  u16 aIndent[100];  /* Levels of indentation */
          272  +  char zBase[100];   /* Initial space */
          273  +};
          274  +
   258    275   /*
   259    276   ** An instance of the virtual machine.  This structure contains the complete
   260    277   ** state of the virtual machine.
   261    278   **
   262    279   ** The "sqlite3_stmt" structure pointer that is returned by sqlite3_prepare()
   263    280   ** is really a pointer to an instance of this structure.
   264    281   **
................................................................................
   317    334     i64 nFkConstraint;      /* Number of imm. FK constraints this VM */
   318    335     i64 nStmtDefCons;       /* Number of def. constraints when stmt started */
   319    336     char *zSql;             /* Text of the SQL statement that generated this */
   320    337     void *pFree;            /* Free this when deleting the vdbe */
   321    338   #ifdef SQLITE_DEBUG
   322    339     FILE *trace;            /* Write an execution trace here, if not NULL */
   323    340   #endif
          341  +#ifdef SQLITE_ENABLE_TREE_EXPLAIN
          342  +  Explain *pExplain;      /* The explainer */
          343  +  char *zExplain;         /* Explanation of data structures */
          344  +#endif
   324    345     VdbeFrame *pFrame;      /* Parent frame */
   325    346     VdbeFrame *pDelFrame;   /* List of frame objects to free on VM reset */
   326    347     int nFrame;             /* Number of frames in pFrame list */
   327    348     u32 expmask;            /* Binding to these vars invalidates VM */
   328    349     SubProgram *pProgram;   /* Linked list of all sub-programs used by VM */
          350  +  int nOnceFlag;          /* Size of array aOnceFlag[] */
          351  +  u8 *aOnceFlag;          /* Flags for OP_Once */
   329    352   };
   330    353   
   331    354   /*
   332    355   ** The following are allowed values for Vdbe.magic
   333    356   */
   334    357   #define VDBE_MAGIC_INIT     0x26bceaa5    /* Building a VDBE program */
   335    358   #define VDBE_MAGIC_RUN      0xbdf20da3    /* VDBE is ready to execute */

Changes to src/vdbeapi.c.

   367    367       ** be called automatically instead of throwing the SQLITE_MISUSE error.
   368    368       ** This "automatic-reset" change is not technically an incompatibility, 
   369    369       ** since any application that receives an SQLITE_MISUSE is broken by
   370    370       ** definition.
   371    371       **
   372    372       ** Nevertheless, some published applications that were originally written
   373    373       ** for version 3.6.23 or earlier do in fact depend on SQLITE_MISUSE 
   374         -    ** returns, and the so were broken by the automatic-reset change.  As a
          374  +    ** returns, and those were broken by the automatic-reset change.  As a
   375    375       ** a work-around, the SQLITE_OMIT_AUTORESET compile-time restores the
   376    376       ** legacy behavior of returning SQLITE_MISUSE for cases where the 
   377    377       ** previous sqlite3_step() returned something other than a SQLITE_LOCKED
   378    378       ** or SQLITE_BUSY error.
   379    379       */
   380    380   #ifdef SQLITE_OMIT_AUTORESET
   381    381       if( p->rc==SQLITE_BUSY || p->rc==SQLITE_LOCKED ){
................................................................................
   713    713     if( pVm && pVm->pResultSet!=0 && i<pVm->nResColumn && i>=0 ){
   714    714       sqlite3_mutex_enter(pVm->db->mutex);
   715    715       pOut = &pVm->pResultSet[i];
   716    716     }else{
   717    717       /* If the value passed as the second argument is out of range, return
   718    718       ** a pointer to the following static Mem object which contains the
   719    719       ** value SQL NULL. Even though the Mem structure contains an element
   720         -    ** of type i64, on certain architecture (x86) with certain compiler
          720  +    ** of type i64, on certain architectures (x86) with certain compiler
   721    721       ** switches (-Os), gcc may align this Mem object on a 4-byte boundary
   722    722       ** instead of an 8-byte one. This all works fine, except that when
   723    723       ** running with SQLITE_DEBUG defined the SQLite code sometimes assert()s
   724    724       ** that a Mem structure is located on an 8-byte boundary. To prevent
   725         -    ** this assert() from failing, when building with SQLITE_DEBUG defined
   726         -    ** using gcc, force nullMem to be 8-byte aligned using the magical
          725  +    ** these assert()s from failing, when building with SQLITE_DEBUG defined
          726  +    ** using gcc, we force nullMem to be 8-byte aligned using the magical
   727    727       ** __attribute__((aligned(8))) macro.  */
   728    728       static const Mem nullMem 
   729    729   #if defined(SQLITE_DEBUG) && defined(__GNUC__)
   730    730         __attribute__((aligned(8))) 
   731    731   #endif
   732    732         = {0, "", (double)0, {0}, 0, MEM_Null, SQLITE_NULL, 0,
   733    733   #ifdef SQLITE_DEBUG

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;
         1490  +  if( nOnce==0 ) nOnce = 1; /* Ensure at least one byte in p->aOnceFlag[] */
  1487   1491     
  1488   1492     /* For each cursor required, also allocate a memory cell. Memory
  1489   1493     ** cells (nMem+1-nCursor)..nMem, inclusive, will never be used by
  1490   1494     ** the vdbe program. Instead they are used to allocate space for
  1491   1495     ** VdbeCursor/BtCursor structures. The blob of memory associated with 
  1492   1496     ** cursor 0 is stored in memory cell nMem. Memory cell (nMem-1)
  1493   1497     ** stores the blob of memory associated with cursor 1, etc.
................................................................................
  1528   1532       nByte = 0;
  1529   1533       p->aMem = allocSpace(p->aMem, nMem*sizeof(Mem), &zCsr, zEnd, &nByte);
  1530   1534       p->aVar = allocSpace(p->aVar, nVar*sizeof(Mem), &zCsr, zEnd, &nByte);
  1531   1535       p->apArg = allocSpace(p->apArg, nArg*sizeof(Mem*), &zCsr, zEnd, &nByte);
  1532   1536       p->azVar = allocSpace(p->azVar, nVar*sizeof(char*), &zCsr, zEnd, &nByte);
  1533   1537       p->apCsr = allocSpace(p->apCsr, nCursor*sizeof(VdbeCursor*),
  1534   1538                             &zCsr, zEnd, &nByte);
         1539  +    p->aOnceFlag = allocSpace(p->aOnceFlag, nOnce, &zCsr, zEnd, &nByte);
  1535   1540       if( nByte ){
  1536   1541         p->pFree = sqlite3DbMallocZero(db, nByte);
  1537   1542       }
  1538   1543       zCsr = p->pFree;
  1539   1544       zEnd = &zCsr[nByte];
  1540   1545     }while( nByte && !db->mallocFailed );
  1541   1546   
  1542   1547     p->nCursor = (u16)nCursor;
         1548  +  p->nOnceFlag = nOnce;
  1543   1549     if( p->aVar ){
  1544   1550       p->nVar = (ynVar)nVar;
  1545   1551       for(n=0; n<nVar; n++){
  1546   1552         p->aVar[n].flags = MEM_Null;
  1547   1553         p->aVar[n].db = db;
  1548   1554       }
  1549   1555     }
................................................................................
  1552   1558       memcpy(p->azVar, pParse->azVar, p->nzVar*sizeof(p->azVar[0]));
  1553   1559       memset(pParse->azVar, 0, pParse->nzVar*sizeof(pParse->azVar[0]));
  1554   1560     }
  1555   1561     if( p->aMem ){
  1556   1562       p->aMem--;                      /* aMem[] goes from 1..nMem */
  1557   1563       p->nMem = nMem;                 /*       not from 0..nMem-1 */
  1558   1564       for(n=1; n<=nMem; n++){
  1559         -      p->aMem[n].flags = MEM_Null;
         1565  +      p->aMem[n].flags = MEM_Invalid;
  1560   1566         p->aMem[n].db = db;
  1561   1567       }
  1562   1568     }
  1563   1569     p->explain = pParse->explain;
  1564   1570     sqlite3VdbeRewind(p);
  1565   1571   }
  1566   1572   
................................................................................
  1594   1600   /*
  1595   1601   ** Copy the values stored in the VdbeFrame structure to its Vdbe. This
  1596   1602   ** is used, for example, when a trigger sub-program is halted to restore
  1597   1603   ** control to the main program.
  1598   1604   */
  1599   1605   int sqlite3VdbeFrameRestore(VdbeFrame *pFrame){
  1600   1606     Vdbe *v = pFrame->v;
         1607  +  v->aOnceFlag = pFrame->aOnceFlag;
         1608  +  v->nOnceFlag = pFrame->nOnceFlag;
  1601   1609     v->aOp = pFrame->aOp;
  1602   1610     v->nOp = pFrame->nOp;
  1603   1611     v->aMem = pFrame->aMem;
  1604   1612     v->nMem = pFrame->nMem;
  1605   1613     v->apCsr = pFrame->apCsr;
  1606   1614     v->nCursor = pFrame->nCursor;
  1607   1615     v->db->lastRowid = pFrame->lastRowid;
................................................................................
  1656   1664   static void Cleanup(Vdbe *p){
  1657   1665     sqlite3 *db = p->db;
  1658   1666   
  1659   1667   #ifdef SQLITE_DEBUG
  1660   1668     /* Execute assert() statements to ensure that the Vdbe.apCsr[] and 
  1661   1669     ** Vdbe.aMem[] arrays have already been cleaned up.  */
  1662   1670     int i;
  1663         -  for(i=0; i<p->nCursor; i++) assert( p->apCsr==0 || p->apCsr[i]==0 );
  1664         -  for(i=1; i<=p->nMem; i++) assert( p->aMem==0 || p->aMem[i].flags==MEM_Null );
         1671  +  if( p->apCsr ) for(i=0; i<p->nCursor; i++) assert( p->apCsr[i]==0 );
         1672  +  if( p->aMem ){
         1673  +    for(i=1; i<=p->nMem; i++) assert( p->aMem[i].flags==MEM_Invalid );
         1674  +  }
  1665   1675   #endif
  1666   1676   
  1667   1677     sqlite3DbFree(db, p->zErrMsg);
  1668   1678     p->zErrMsg = 0;
  1669   1679     p->pResultSet = 0;
  1670   1680   }
  1671   1681   
................................................................................
  1822   1832       sqlite3_vfs *pVfs = db->pVfs;
  1823   1833       int needSync = 0;
  1824   1834       char *zMaster = 0;   /* File-name for the master journal */
  1825   1835       char const *zMainFile = sqlite3BtreeGetFilename(db->aDb[0].pBt);
  1826   1836       sqlite3_file *pMaster = 0;
  1827   1837       i64 offset = 0;
  1828   1838       int res;
         1839  +    int retryCount = 0;
         1840  +    int nMainFile;
  1829   1841   
  1830   1842       /* Select a master journal file name */
         1843  +    nMainFile = sqlite3Strlen30(zMainFile);
         1844  +    zMaster = sqlite3MPrintf(db, "%s-mjXXXXXX9XXz", zMainFile);
         1845  +    if( zMaster==0 ) return SQLITE_NOMEM;
  1831   1846       do {
  1832   1847         u32 iRandom;
  1833         -      sqlite3DbFree(db, zMaster);
         1848  +      if( retryCount ){
         1849  +        if( retryCount>100 ){
         1850  +          sqlite3_log(SQLITE_FULL, "MJ delete: %s", zMaster);
         1851  +          sqlite3OsDelete(pVfs, zMaster, 0);
         1852  +          break;
         1853  +        }else if( retryCount==1 ){
         1854  +          sqlite3_log(SQLITE_FULL, "MJ collide: %s", zMaster);
         1855  +        }
         1856  +      }
         1857  +      retryCount++;
  1834   1858         sqlite3_randomness(sizeof(iRandom), &iRandom);
  1835         -      zMaster = sqlite3MPrintf(db, "%s-mj%08X", zMainFile, iRandom&0x7fffffff);
  1836         -      if( !zMaster ){
  1837         -        return SQLITE_NOMEM;
  1838         -      }
         1859  +      sqlite3_snprintf(13, &zMaster[nMainFile], "-mj%06X9%02X",
         1860  +                               (iRandom>>8)&0xffffff, iRandom&0xff);
         1861  +      /* The antipenultimate character of the master journal name must
         1862  +      ** be "9" to avoid name collisions when using 8+3 filenames. */
         1863  +      assert( zMaster[sqlite3Strlen30(zMaster)-3]=='9' );
  1839   1864         sqlite3FileSuffix3(zMainFile, zMaster);
  1840   1865         rc = sqlite3OsAccess(pVfs, zMaster, SQLITE_ACCESS_EXISTS, &res);
  1841   1866       }while( rc==SQLITE_OK && res );
  1842   1867       if( rc==SQLITE_OK ){
  1843   1868         /* Open the master journal. */
  1844   1869         rc = sqlite3OsOpenMalloc(pVfs, zMaster, &pMaster, 
  1845   1870             SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|
................................................................................
  2125   2150     ** state.  We need to rollback the statement transaction, if there is
  2126   2151     ** one, or the complete transaction if there is no statement transaction.
  2127   2152     */
  2128   2153   
  2129   2154     if( p->db->mallocFailed ){
  2130   2155       p->rc = SQLITE_NOMEM;
  2131   2156     }
         2157  +  if( p->aOnceFlag ) memset(p->aOnceFlag, 0, p->nOnceFlag);
  2132   2158     closeAllCursors(p);
  2133   2159     if( p->magic!=VDBE_MAGIC_RUN ){
  2134   2160       return SQLITE_OK;
  2135   2161     }
  2136   2162     checkActiveVdbeCnt(db);
  2137   2163   
  2138   2164     /* No commit or rollback needed if the program never started */
................................................................................
  2462   2488     }
  2463   2489     for(i=p->nzVar-1; i>=0; i--) sqlite3DbFree(db, p->azVar[i]);
  2464   2490     vdbeFreeOpArray(db, p->aOp, p->nOp);
  2465   2491     sqlite3DbFree(db, p->aLabel);
  2466   2492     sqlite3DbFree(db, p->aColName);
  2467   2493     sqlite3DbFree(db, p->zSql);
  2468   2494     sqlite3DbFree(db, p->pFree);
         2495  +#if defined(SQLITE_ENABLE_TREE_EXPLAIN)
         2496  +  sqlite3DbFree(db, p->zExplain);
         2497  +  sqlite3DbFree(db, p->pExplain);
         2498  +#endif
  2469   2499     sqlite3DbFree(db, p);
  2470   2500   }
  2471   2501   
  2472   2502   /*
  2473   2503   ** Delete an entire VDBE.
  2474   2504   */
  2475   2505   void sqlite3VdbeDelete(Vdbe *p){

Changes to src/vdbemem.c.

   965    965       sqlite3VdbeChangeEncoding(pVal, enc & ~SQLITE_UTF16_ALIGNED);
   966    966       if( (enc & SQLITE_UTF16_ALIGNED)!=0 && 1==(1&SQLITE_PTR_TO_INT(pVal->z)) ){
   967    967         assert( (pVal->flags & (MEM_Ephem|MEM_Static))!=0 );
   968    968         if( sqlite3VdbeMemMakeWriteable(pVal)!=SQLITE_OK ){
   969    969           return 0;
   970    970         }
   971    971       }
   972         -    sqlite3VdbeMemNulTerminate(pVal); /* IMP: R-59893-45467 */
          972  +    sqlite3VdbeMemNulTerminate(pVal); /* IMP: R-31275-44060 */
   973    973     }else{
   974    974       assert( (pVal->flags&MEM_Blob)==0 );
   975    975       sqlite3VdbeMemStringify(pVal, enc);
   976    976       assert( 0==(1&SQLITE_PTR_TO_INT(pVal->z)) );
   977    977     }
   978    978     assert(pVal->enc==(enc & ~SQLITE_UTF16_ALIGNED) || pVal->db==0
   979    979                 || pVal->db->mallocFailed );

Changes to src/vdbetrace.c.

     8      8   **    May you find forgiveness for yourself and forgive others.
     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   **
    13     13   ** This file contains code used to insert the values of host parameters
    14     14   ** (aka "wildcards") into the SQL text output by sqlite3_trace().
           15  +**
           16  +** The Vdbe parse-tree explainer is also found here.
    15     17   */
    16     18   #include "sqliteInt.h"
    17     19   #include "vdbeInt.h"
    18     20   
    19     21   #ifndef SQLITE_OMIT_TRACE
    20     22   
    21     23   /*
................................................................................
   151    153         }
   152    154       }
   153    155     }
   154    156     return sqlite3StrAccumFinish(&out);
   155    157   }
   156    158   
   157    159   #endif /* #ifndef SQLITE_OMIT_TRACE */
          160  +
          161  +/*****************************************************************************
          162  +** The following code implements the data-structure explaining logic
          163  +** for the Vdbe.
          164  +*/
          165  +
          166  +#if defined(SQLITE_ENABLE_TREE_EXPLAIN)
          167  +
          168  +/*
          169  +** Allocate a new Explain object
          170  +*/
          171  +void sqlite3ExplainBegin(Vdbe *pVdbe){
          172  +  if( pVdbe ){
          173  +    sqlite3BeginBenignMalloc();
          174  +    Explain *p = sqlite3_malloc( sizeof(Explain) );
          175  +    if( p ){
          176  +      memset(p, 0, sizeof(*p));
          177  +      p->pVdbe = pVdbe;
          178  +      sqlite3_free(pVdbe->pExplain);
          179  +      pVdbe->pExplain = p;
          180  +      sqlite3StrAccumInit(&p->str, p->zBase, sizeof(p->zBase),
          181  +                          SQLITE_MAX_LENGTH);
          182  +      p->str.useMalloc = 2;
          183  +    }else{
          184  +      sqlite3EndBenignMalloc();
          185  +    }
          186  +  }
          187  +}
          188  +
          189  +/*
          190  +** Return true if the Explain ends with a new-line.
          191  +*/
          192  +static int endsWithNL(Explain *p){
          193  +  return p && p->str.zText && p->str.nChar
          194  +           && p->str.zText[p->str.nChar-1]=='\n';
          195  +}
          196  +    
          197  +/*
          198  +** Append text to the indentation
          199  +*/
          200  +void sqlite3ExplainPrintf(Vdbe *pVdbe, const char *zFormat, ...){
          201  +  Explain *p;
          202  +  if( pVdbe && (p = pVdbe->pExplain)!=0 ){
          203  +    va_list ap;
          204  +    if( p->nIndent && endsWithNL(p) ){
          205  +      int n = p->nIndent;
          206  +      if( n>ArraySize(p->aIndent) ) n = ArraySize(p->aIndent);
          207  +      sqlite3AppendSpace(&p->str, p->aIndent[n-1]);
          208  +    }   
          209  +    va_start(ap, zFormat);
          210  +    sqlite3VXPrintf(&p->str, 1, zFormat, ap);
          211  +    va_end(ap);
          212  +  }
          213  +}
          214  +
          215  +/*
          216  +** Append a '\n' if there is not already one.
          217  +*/
          218  +void sqlite3ExplainNL(Vdbe *pVdbe){
          219  +  Explain *p;
          220  +  if( pVdbe && (p = pVdbe->pExplain)!=0 && !endsWithNL(p) ){
          221  +    sqlite3StrAccumAppend(&p->str, "\n", 1);
          222  +  }
          223  +}
          224  +
          225  +/*
          226  +** Push a new indentation level.  Subsequent lines will be indented
          227  +** so that they begin at the current cursor position.
          228  +*/
          229  +void sqlite3ExplainPush(Vdbe *pVdbe){
          230  +  Explain *p;
          231  +  if( pVdbe && (p = pVdbe->pExplain)!=0 ){
          232  +    if( p->str.zText && p->nIndent<ArraySize(p->aIndent) ){
          233  +      const char *z = p->str.zText;
          234  +      int i = p->str.nChar-1;
          235  +      int x;
          236  +      while( i>=0 && z[i]!='\n' ){ i--; }
          237  +      x = (p->str.nChar - 1) - i;
          238  +      if( p->nIndent && x<p->aIndent[p->nIndent-1] ){
          239  +        x = p->aIndent[p->nIndent-1];
          240  +      }
          241  +      p->aIndent[p->nIndent] = x;
          242  +    }
          243  +    p->nIndent++;
          244  +  }
          245  +}
          246  +
          247  +/*
          248  +** Pop the indentation stack by one level.
          249  +*/
          250  +void sqlite3ExplainPop(Vdbe *p){
          251  +  if( p && p->pExplain ) p->pExplain->nIndent--;
          252  +}
          253  +
          254  +/*
          255  +** Free the indentation structure
          256  +*/
          257  +void sqlite3ExplainFinish(Vdbe *pVdbe){
          258  +  if( pVdbe && pVdbe->pExplain ){
          259  +    sqlite3_free(pVdbe->zExplain);
          260  +    sqlite3ExplainNL(pVdbe);
          261  +    pVdbe->zExplain = sqlite3StrAccumFinish(&pVdbe->pExplain->str);
          262  +    sqlite3_free(pVdbe->pExplain);
          263  +    pVdbe->pExplain = 0;
          264  +    sqlite3EndBenignMalloc();
          265  +  }
          266  +}
          267  +
          268  +/*
          269  +** Return the explanation of a virtual machine.
          270  +*/
          271  +const char *sqlite3VdbeExplanation(Vdbe *pVdbe){
          272  +  return (pVdbe && pVdbe->zExplain) ? pVdbe->zExplain : 0;
          273  +}
          274  +#endif /* defined(SQLITE_DEBUG) */

Changes to src/wal.c.

   410    410   struct Wal {
   411    411     sqlite3_vfs *pVfs;         /* The VFS used to create pDbFd */
   412    412     sqlite3_file *pDbFd;       /* File handle for the database file */
   413    413     sqlite3_file *pWalFd;      /* File handle for WAL file */
   414    414     u32 iCallback;             /* Value to pass to log callback (or 0) */
   415    415     i64 mxWalSize;             /* Truncate WAL to this size upon reset */
   416    416     int nWiData;               /* Size of array apWiData */
          417  +  int szFirstBlock;          /* Size of first block written to WAL file */
   417    418     volatile u32 **apWiData;   /* Pointer to wal-index content in memory */
   418    419     u32 szPage;                /* Database page size */
   419    420     i16 readLock;              /* Which read lock is being held.  -1 for none */
          421  +  u8 syncFlags;              /* Flags to use to sync header writes */
   420    422     u8 exclusiveMode;          /* Non-zero if connection is in exclusive mode */
   421    423     u8 writeLock;              /* True if in a write transaction */
   422    424     u8 ckptLock;               /* True if holding a checkpoint lock */
   423    425     u8 readOnly;               /* WAL_RDWR, WAL_RDONLY, or WAL_SHM_RDONLY */
          426  +  u8 truncateOnCommit;       /* True to truncate WAL file on commit */
          427  +  u8 syncHeader;             /* Fsync the WAL header if true */
          428  +  u8 padToSectorBoundary;    /* Pad transactions out to the next sector */
   424    429     WalIndexHdr hdr;           /* Wal-index header for current transaction */
   425    430     const char *zWalName;      /* Name of WAL file */
   426    431     u32 nCkpt;                 /* Checkpoint sequence counter in the wal-header */
   427    432   #ifdef SQLITE_DEBUG
   428    433     u8 lockError;              /* True if a locking error has occurred */
   429    434   #endif
   430    435   };
................................................................................
  1089   1094       int szFrame;                  /* Number of bytes in buffer aFrame[] */
  1090   1095       u8 *aData;                    /* Pointer to data part of aFrame buffer */
  1091   1096       int iFrame;                   /* Index of last frame read */
  1092   1097       i64 iOffset;                  /* Next offset to read from log file */
  1093   1098       int szPage;                   /* Page size according to the log */
  1094   1099       u32 magic;                    /* Magic value read from WAL header */
  1095   1100       u32 version;                  /* Magic value read from WAL header */
         1101  +    int isValid;                  /* True if this frame is valid */
  1096   1102   
  1097   1103       /* Read in the WAL header. */
  1098   1104       rc = sqlite3OsRead(pWal->pWalFd, aBuf, WAL_HDRSIZE, 0);
  1099   1105       if( rc!=SQLITE_OK ){
  1100   1106         goto recovery_error;
  1101   1107       }
  1102   1108   
................................................................................
  1147   1153       aData = &aFrame[WAL_FRAME_HDRSIZE];
  1148   1154   
  1149   1155       /* Read all frames from the log file. */
  1150   1156       iFrame = 0;
  1151   1157       for(iOffset=WAL_HDRSIZE; (iOffset+szFrame)<=nSize; iOffset+=szFrame){
  1152   1158         u32 pgno;                   /* Database page number for frame */
  1153   1159         u32 nTruncate;              /* dbsize field from frame header */
  1154         -      int isValid;                /* True if this frame is valid */
  1155   1160   
  1156   1161         /* Read and decode the next log frame. */
         1162  +      iFrame++;
  1157   1163         rc = sqlite3OsRead(pWal->pWalFd, aFrame, szFrame, iOffset);
  1158   1164         if( rc!=SQLITE_OK ) break;
  1159   1165         isValid = walDecodeFrame(pWal, &pgno, &nTruncate, aData, aFrame);
  1160   1166         if( !isValid ) break;
  1161         -      rc = walIndexAppend(pWal, ++iFrame, pgno);
         1167  +      rc = walIndexAppend(pWal, iFrame, pgno);
  1162   1168         if( rc!=SQLITE_OK ) break;
  1163   1169   
  1164   1170         /* If nTruncate is non-zero, this is a commit record. */
  1165   1171         if( nTruncate ){
  1166   1172           pWal->hdr.mxFrame = iFrame;
  1167   1173           pWal->hdr.nPage = nTruncate;
  1168   1174           pWal->hdr.szPage = (u16)((szPage&0xff00) | (szPage>>16));
................................................................................
  1278   1284   
  1279   1285     pRet->pVfs = pVfs;
  1280   1286     pRet->pWalFd = (sqlite3_file *)&pRet[1];
  1281   1287     pRet->pDbFd = pDbFd;
  1282   1288     pRet->readLock = -1;
  1283   1289     pRet->mxWalSize = mxWalSize;
  1284   1290     pRet->zWalName = zWalName;
         1291  +  pRet->syncHeader = 1;
         1292  +  pRet->padToSectorBoundary = 1;
  1285   1293     pRet->exclusiveMode = (bNoShm ? WAL_HEAPMEMORY_MODE: WAL_NORMAL_MODE);
  1286   1294   
  1287   1295     /* Open file handle on the write-ahead log file. */
  1288   1296     if( flags&SQLITE_OPEN_READONLY ){
  1289   1297       vfsFlags = flags | SQLITE_OPEN_WAL;
  1290   1298     } else {
  1291   1299       vfsFlags = flags | (SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|SQLITE_OPEN_WAL);
................................................................................
  1296   1304     }
  1297   1305   
  1298   1306     if( rc!=SQLITE_OK ){
  1299   1307       walIndexClose(pRet, 0);
  1300   1308       sqlite3OsClose(pRet->pWalFd);
  1301   1309       sqlite3_free(pRet);
  1302   1310     }else{
         1311  +    int iDC = sqlite3OsDeviceCharacteristics(pRet->pWalFd);
         1312  +    if( iDC & SQLITE_IOCAP_SEQUENTIAL ){ pRet->syncHeader = 0; }
         1313  +    if( iDC & SQLITE_IOCAP_POWERSAFE_OVERWRITE ){
         1314  +      pRet->padToSectorBoundary = 0;
         1315  +    }
  1303   1316       *ppWal = pRet;
  1304   1317       WALTRACE(("WAL%d: opened\n", pRet));
  1305   1318     }
  1306   1319     return rc;
  1307   1320   }
  1308   1321   
  1309   1322   /*
................................................................................
  1783   1796   
  1784   1797    walcheckpoint_out:
  1785   1798     walIteratorFree(pIter);
  1786   1799     return rc;
  1787   1800   }
  1788   1801   
  1789   1802   /*
  1790         -** Attempt to limit the WAL size to the size limit defined by
  1791         -** PRAGMA journal_size_limit.
         1803  +** If the WAL file is currently larger than nMax bytes in size, truncate
         1804  +** it to exactly nMax bytes. If an error occurs while doing so, ignore it.
  1792   1805   */
  1793         -static void walLimitSize(Wal *pWal){
  1794         -  if( pWal->mxWalSize>=0 ){
  1795         -    i64 sz;
  1796         -    int rx;
  1797         -    sqlite3BeginBenignMalloc();
  1798         -    rx = sqlite3OsFileSize(pWal->pWalFd, &sz);
  1799         -    if( rx==SQLITE_OK && (sz > pWal->mxWalSize) ){
  1800         -      rx = sqlite3OsTruncate(pWal->pWalFd, pWal->mxWalSize);
  1801         -    }
  1802         -    sqlite3EndBenignMalloc();
  1803         -    if( rx ){
  1804         -      sqlite3_log(rx, "cannot limit WAL size: %s", pWal->zWalName);
  1805         -    }
         1806  +static void walLimitSize(Wal *pWal, i64 nMax){
         1807  +  i64 sz;
         1808  +  int rx;
         1809  +  sqlite3BeginBenignMalloc();
         1810  +  rx = sqlite3OsFileSize(pWal->pWalFd, &sz);
         1811  +  if( rx==SQLITE_OK && (sz > nMax ) ){
         1812  +    rx = sqlite3OsTruncate(pWal->pWalFd, nMax);
         1813  +  }
         1814  +  sqlite3EndBenignMalloc();
         1815  +  if( rx ){
         1816  +    sqlite3_log(rx, "cannot limit WAL size: %s", pWal->zWalName);
  1806   1817     }
  1807   1818   }
  1808   1819   
  1809   1820   /*
  1810   1821   ** Close a connection to a log file.
  1811   1822   */
  1812   1823   int sqlite3WalClose(
................................................................................
  1825   1836       ** the database. In this case checkpoint the database and unlink both
  1826   1837       ** the wal and wal-index files.
  1827   1838       **
  1828   1839       ** The EXCLUSIVE lock is not released before returning.
  1829   1840       */
  1830   1841       rc = sqlite3OsLock(pWal->pDbFd, SQLITE_LOCK_EXCLUSIVE);
  1831   1842       if( rc==SQLITE_OK ){
  1832         -      int bPersistWal = -1;
  1833   1843         if( pWal->exclusiveMode==WAL_NORMAL_MODE ){
  1834   1844           pWal->exclusiveMode = WAL_EXCLUSIVE_MODE;
  1835   1845         }
  1836   1846         rc = sqlite3WalCheckpoint(
  1837   1847             pWal, SQLITE_CHECKPOINT_PASSIVE, 0, 0, sync_flags, nBuf, zBuf, 0, 0
  1838   1848         );
  1839         -      sqlite3OsFileControl(pWal->pDbFd, SQLITE_FCNTL_PERSIST_WAL, &bPersistWal);
  1840         -      if( rc==SQLITE_OK && bPersistWal!=1 ){
  1841         -        isDelete = 1;
  1842         -      }else{
  1843         -        walLimitSize(pWal);
         1849  +      if( rc==SQLITE_OK ){
         1850  +        int bPersist = -1;
         1851  +        sqlite3OsFileControl(pWal->pDbFd, SQLITE_FCNTL_PERSIST_WAL, &bPersist);
         1852  +        if( bPersist!=1 ){
         1853  +          /* Try to delete the WAL file if the checkpoint completed and
         1854  +          ** fsyned (rc==SQLITE_OK) and if we are not in persistent-wal
         1855  +          ** mode (!bPersist) */
         1856  +          isDelete = 1;
         1857  +        }else if( pWal->mxWalSize>=0 ){
         1858  +          /* Try to truncate the WAL file to zero bytes if the checkpoint
         1859  +          ** completed and fsynced (rc==SQLITE_OK) and we are in persistent
         1860  +          ** WAL mode (bPersist) and if the PRAGMA journal_size_limit is a
         1861  +          ** non-negative value (pWal->mxWalSize>=0).  Note that we truncate
         1862  +          ** to zero bytes as truncating to the journal_size_limit might
         1863  +          ** leave a corrupt WAL file on disk. */
         1864  +          walLimitSize(pWal, 0);
         1865  +        }
  1844   1866         }
  1845   1867       }
  1846   1868   
  1847   1869       walIndexClose(pWal, isDelete);
  1848   1870       sqlite3OsClose(pWal->pWalFd);
  1849   1871       if( isDelete ){
  1850   1872         sqlite3OsDelete(pWal->pVfs, pWal->zWalName, 0);
................................................................................
  2448   2470   ** End a write transaction.  The commit has already been done.  This
  2449   2471   ** routine merely releases the lock.
  2450   2472   */
  2451   2473   int sqlite3WalEndWriteTransaction(Wal *pWal){
  2452   2474     if( pWal->writeLock ){
  2453   2475       walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1);
  2454   2476       pWal->writeLock = 0;
         2477  +    pWal->truncateOnCommit = 0;
  2455   2478     }
  2456   2479     return SQLITE_OK;
  2457   2480   }
  2458   2481   
  2459   2482   /*
  2460   2483   ** If any data has been written (but not committed) to the log file, this
  2461   2484   ** function moves the write-pointer back to the start of the transaction.
................................................................................
  2582   2605           ** at this point. But updating the actual wal-index header is also
  2583   2606           ** safe and means there is no special case for sqlite3WalUndo()
  2584   2607           ** to handle if this transaction is rolled back.
  2585   2608           */
  2586   2609           int i;                    /* Loop counter */
  2587   2610           u32 *aSalt = pWal->hdr.aSalt;       /* Big-endian salt values */
  2588   2611   
  2589         -        walLimitSize(pWal);
  2590   2612           pWal->nCkpt++;
  2591   2613           pWal->hdr.mxFrame = 0;
  2592   2614           sqlite3Put4byte((u8*)&aSalt[0], 1 + sqlite3Get4byte((u8*)&aSalt[0]));
  2593   2615           aSalt[1] = salt1;
  2594   2616           walIndexWriteHdr(pWal);
  2595   2617           pInfo->nBackfill = 0;
  2596   2618           for(i=1; i<WAL_NREADER; i++) pInfo->aReadMark[i] = READMARK_NOT_USED;
................................................................................
  2610   2632       assert( (rc&0xff)!=SQLITE_BUSY ); /* BUSY not possible when useWal==1 */
  2611   2633       testcase( (rc&0xff)==SQLITE_IOERR );
  2612   2634       testcase( rc==SQLITE_PROTOCOL );
  2613   2635       testcase( rc==SQLITE_OK );
  2614   2636     }
  2615   2637     return rc;
  2616   2638   }
         2639  +
         2640  +/*
         2641  +** Information about the current state of the WAL file and where
         2642  +** the next fsync should occur - passed from sqlite3WalFrames() into
         2643  +** walWriteToLog().
         2644  +*/
         2645  +typedef struct WalWriter {
         2646  +  Wal *pWal;                   /* The complete WAL information */
         2647  +  sqlite3_file *pFd;           /* The WAL file to which we write */
         2648  +  sqlite3_int64 iSyncPoint;    /* Fsync at this offset */
         2649  +  int syncFlags;               /* Flags for the fsync */
         2650  +  int szPage;                  /* Size of one page */
         2651  +} WalWriter;
         2652  +
         2653  +/*
         2654  +** Write iAmt bytes of content into the WAL file beginning at iOffset.
         2655  +** Do a sync when crossing the p->iSyncPoint boundary.
         2656  +**
         2657  +** In other words, if iSyncPoint is in between iOffset and iOffset+iAmt,
         2658  +** first write the part before iSyncPoint, then sync, then write the
         2659  +** rest.
         2660  +*/
         2661  +static int walWriteToLog(
         2662  +  WalWriter *p,              /* WAL to write to */
         2663  +  void *pContent,            /* Content to be written */
         2664  +  int iAmt,                  /* Number of bytes to write */
         2665  +  sqlite3_int64 iOffset      /* Start writing at this offset */
         2666  +){
         2667  +  int rc;
         2668  +  if( iOffset<p->iSyncPoint && iOffset+iAmt>=p->iSyncPoint ){
         2669  +    int iFirstAmt = (int)(p->iSyncPoint - iOffset);
         2670  +    rc = sqlite3OsWrite(p->pFd, pContent, iFirstAmt, iOffset);
         2671  +    if( rc ) return rc;
         2672  +    iOffset += iFirstAmt;
         2673  +    iAmt -= iFirstAmt;
         2674  +    pContent = (void*)(iFirstAmt + (char*)pContent);
         2675  +    assert( p->syncFlags & (SQLITE_SYNC_NORMAL|SQLITE_SYNC_FULL) );
         2676  +    rc = sqlite3OsSync(p->pFd, p->syncFlags);
         2677  +    if( iAmt==0 || rc ) return rc;
         2678  +  }
         2679  +  rc = sqlite3OsWrite(p->pFd, pContent, iAmt, iOffset);
         2680  +  return rc;
         2681  +}
         2682  +
         2683  +/*
         2684  +** Write out a single frame of the WAL
         2685  +*/
         2686  +static int walWriteOneFrame(
         2687  +  WalWriter *p,               /* Where to write the frame */
         2688  +  PgHdr *pPage,               /* The page of the frame to be written */
         2689  +  int nTruncate,              /* The commit flag.  Usually 0.  >0 for commit */
         2690  +  sqlite3_int64 iOffset       /* Byte offset at which to write */
         2691  +){
         2692  +  int rc;                         /* Result code from subfunctions */
         2693  +  void *pData;                    /* Data actually written */
         2694  +  u8 aFrame[WAL_FRAME_HDRSIZE];   /* Buffer to assemble frame-header in */
         2695  +#if defined(SQLITE_HAS_CODEC)
         2696  +  if( (pData = sqlite3PagerCodec(pPage))==0 ) return SQLITE_NOMEM;
         2697  +#else
         2698  +  pData = pPage->pData;
         2699  +#endif
         2700  +  walEncodeFrame(p->pWal, pPage->pgno, nTruncate, pData, aFrame);
         2701  +  rc = walWriteToLog(p, aFrame, sizeof(aFrame), iOffset);
         2702  +  if( rc ) return rc;
         2703  +  /* Write the page data */
         2704  +  rc = walWriteToLog(p, pData, p->szPage, iOffset+sizeof(aFrame));
         2705  +  return rc;
         2706  +}
  2617   2707   
  2618   2708   /* 
  2619   2709   ** Write a set of frames to the log. The caller must hold the write-lock
  2620   2710   ** on the log file (obtained using sqlite3WalBeginWriteTransaction()).
  2621   2711   */
  2622   2712   int sqlite3WalFrames(
  2623   2713     Wal *pWal,                      /* Wal handle to write to */
................................................................................
  2625   2715     PgHdr *pList,                   /* List of dirty pages to write */
  2626   2716     Pgno nTruncate,                 /* Database size after this commit */
  2627   2717     int isCommit,                   /* True if this is a commit */
  2628   2718     int sync_flags                  /* Flags to pass to OsSync() (or 0) */
  2629   2719   ){
  2630   2720     int rc;                         /* Used to catch return codes */
  2631   2721     u32 iFrame;                     /* Next frame address */
  2632         -  u8 aFrame[WAL_FRAME_HDRSIZE];   /* Buffer to assemble frame-header in */
  2633   2722     PgHdr *p;                       /* Iterator to run through pList with. */
  2634   2723     PgHdr *pLast = 0;               /* Last frame in list */
  2635         -  int nLast = 0;                  /* Number of extra copies of last page */
         2724  +  int nExtra = 0;                 /* Number of extra copies of last page */
         2725  +  int szFrame;                    /* The size of a single frame */
         2726  +  i64 iOffset;                    /* Next byte to write in WAL file */
         2727  +  WalWriter w;                    /* The writer */
  2636   2728   
  2637   2729     assert( pList );
  2638   2730     assert( pWal->writeLock );
         2731  +
         2732  +  /* If this frame set completes a transaction, then nTruncate>0.  If
         2733  +  ** nTruncate==0 then this frame set does not complete the transaction. */
         2734  +  assert( (isCommit!=0)==(nTruncate!=0) );
  2639   2735   
  2640   2736   #if defined(SQLITE_TEST) && defined(SQLITE_DEBUG)
  2641   2737     { int cnt; for(cnt=0, p=pList; p; p=p->pDirty, cnt++){}
  2642   2738       WALTRACE(("WAL%p: frame write begin. %d frames. mxFrame=%d. %s\n",
  2643   2739                 pWal, cnt, pWal->hdr.mxFrame, isCommit ? "Commit" : "Spill"));
  2644   2740     }
  2645   2741   #endif
................................................................................
  2660   2756       u8 aWalHdr[WAL_HDRSIZE];      /* Buffer to assemble wal-header in */
  2661   2757       u32 aCksum[2];                /* Checksum for wal-header */
  2662   2758   
  2663   2759       sqlite3Put4byte(&aWalHdr[0], (WAL_MAGIC | SQLITE_BIGENDIAN));
  2664   2760       sqlite3Put4byte(&aWalHdr[4], WAL_MAX_VERSION);
  2665   2761       sqlite3Put4byte(&aWalHdr[8], szPage);
  2666   2762       sqlite3Put4byte(&aWalHdr[12], pWal->nCkpt);
  2667         -    sqlite3_randomness(8, pWal->hdr.aSalt);
         2763  +    if( pWal->nCkpt==0 ) sqlite3_randomness(8, pWal->hdr.aSalt);
  2668   2764       memcpy(&aWalHdr[16], pWal->hdr.aSalt, 8);
  2669   2765       walChecksumBytes(1, aWalHdr, WAL_HDRSIZE-2*4, 0, aCksum);
  2670   2766       sqlite3Put4byte(&aWalHdr[24], aCksum[0]);
  2671   2767       sqlite3Put4byte(&aWalHdr[28], aCksum[1]);
  2672   2768       
  2673   2769       pWal->szPage = szPage;
  2674   2770       pWal->hdr.bigEndCksum = SQLITE_BIGENDIAN;
  2675   2771       pWal->hdr.aFrameCksum[0] = aCksum[0];
  2676   2772       pWal->hdr.aFrameCksum[1] = aCksum[1];
         2773  +    pWal->truncateOnCommit = 1;
  2677   2774   
  2678   2775       rc = sqlite3OsWrite(pWal->pWalFd, aWalHdr, sizeof(aWalHdr), 0);
  2679   2776       WALTRACE(("WAL%p: wal-header write %s\n", pWal, rc ? "failed" : "ok"));
  2680   2777       if( rc!=SQLITE_OK ){
  2681   2778         return rc;
  2682   2779       }
         2780  +
         2781  +    /* Sync the header (unless SQLITE_IOCAP_SEQUENTIAL is true or unless
         2782  +    ** all syncing is turned off by PRAGMA synchronous=OFF).  Otherwise
         2783  +    ** an out-of-order write following a WAL restart could result in
         2784  +    ** database corruption.  See the ticket:
         2785  +    **
         2786  +    **     http://localhost:591/sqlite/info/ff5be73dee
         2787  +    */
         2788  +    if( pWal->syncHeader && sync_flags ){
         2789  +      rc = sqlite3OsSync(pWal->pWalFd, sync_flags & SQLITE_SYNC_MASK);
         2790  +      if( rc ) return rc;
         2791  +    }
  2683   2792     }
  2684   2793     assert( (int)pWal->szPage==szPage );
  2685   2794   
  2686         -  /* Write the log file. */
         2795  +  /* Setup information needed to write frames into the WAL */
         2796  +  w.pWal = pWal;
         2797  +  w.pFd = pWal->pWalFd;
         2798  +  w.iSyncPoint = 0;
         2799  +  w.syncFlags = sync_flags;
         2800  +  w.szPage = szPage;
         2801  +  iOffset = walFrameOffset(iFrame+1, szPage);
         2802  +  szFrame = szPage + WAL_FRAME_HDRSIZE;
         2803  +
         2804  +  /* Write all frames into the log file exactly once */
  2687   2805     for(p=pList; p; p=p->pDirty){
  2688         -    u32 nDbsize;                  /* Db-size field for frame header */
  2689         -    i64 iOffset;                  /* Write offset in log file */
  2690         -    void *pData;
  2691         -   
  2692         -    iOffset = walFrameOffset(++iFrame, szPage);
  2693         -    /* testcase( IS_BIG_INT(iOffset) ); // requires a 4GiB WAL */
  2694         -    
  2695         -    /* Populate and write the frame header */
  2696         -    nDbsize = (isCommit && p->pDirty==0) ? nTruncate : 0;
  2697         -#if defined(SQLITE_HAS_CODEC)
  2698         -    if( (pData = sqlite3PagerCodec(p))==0 ) return SQLITE_NOMEM;
  2699         -#else
  2700         -    pData = p->pData;
  2701         -#endif
  2702         -    walEncodeFrame(pWal, p->pgno, nDbsize, pData, aFrame);
  2703         -    rc = sqlite3OsWrite(pWal->pWalFd, aFrame, sizeof(aFrame), iOffset);
  2704         -    if( rc!=SQLITE_OK ){
  2705         -      return rc;
  2706         -    }
  2707         -
  2708         -    /* Write the page data */
  2709         -    rc = sqlite3OsWrite(pWal->pWalFd, pData, szPage, iOffset+sizeof(aFrame));
  2710         -    if( rc!=SQLITE_OK ){
  2711         -      return rc;
  2712         -    }
         2806  +    int nDbSize;   /* 0 normally.  Positive == commit flag */
         2807  +    iFrame++;
         2808  +    assert( iOffset==walFrameOffset(iFrame, szPage) );
         2809  +    nDbSize = (isCommit && p->pDirty==0) ? nTruncate : 0;
         2810  +    rc = walWriteOneFrame(&w, p, nDbSize, iOffset);
         2811  +    if( rc ) return rc;
  2713   2812       pLast = p;
         2813  +    iOffset += szFrame;
         2814  +  }
         2815  +
         2816  +  /* If this is the end of a transaction, then we might need to pad
         2817  +  ** the transaction and/or sync the WAL file.
         2818  +  **
         2819  +  ** Padding and syncing only occur if this set of frames complete a
         2820  +  ** transaction and if PRAGMA synchronous=FULL.  If synchronous==NORMAL
         2821  +  ** or synchonous==OFF, then no padding or syncing are needed.
         2822  +  **
         2823  +  ** If SQLITE_IOCAP_POWERSAFE_OVERWRITE is defined, then padding is not
         2824  +  ** needed and only the sync is done.  If padding is needed, then the
         2825  +  ** final frame is repeated (with its commit mark) until the next sector
         2826  +  ** boundary is crossed.  Only the part of the WAL prior to the last
         2827  +  ** sector boundary is synced; the part of the last frame that extends
         2828  +  ** past the sector boundary is written after the sync.
         2829  +  */
         2830  +  if( isCommit && (sync_flags & WAL_SYNC_TRANSACTIONS)!=0 ){
         2831  +    if( pWal->padToSectorBoundary ){
         2832  +      int sectorSize = sqlite3OsSectorSize(pWal->pWalFd);
         2833  +      w.iSyncPoint = ((iOffset+sectorSize-1)/sectorSize)*sectorSize;
         2834  +      while( iOffset<w.iSyncPoint ){
         2835  +        rc = walWriteOneFrame(&w, pLast, nTruncate, iOffset);
         2836  +        if( rc ) return rc;
         2837  +        iOffset += szFrame;
         2838  +        nExtra++;
         2839  +      }
         2840  +    }else{
         2841  +      rc = sqlite3OsSync(w.pFd, sync_flags & SQLITE_SYNC_MASK);
         2842  +    }
  2714   2843     }
  2715   2844   
  2716         -  /* Sync the log file if the 'isSync' flag was specified. */
  2717         -  if( sync_flags ){
  2718         -    i64 iSegment = sqlite3OsSectorSize(pWal->pWalFd);
  2719         -    i64 iOffset = walFrameOffset(iFrame+1, szPage);
  2720         -
  2721         -    assert( isCommit );
  2722         -    assert( iSegment>0 );
  2723         -
  2724         -    iSegment = (((iOffset+iSegment-1)/iSegment) * iSegment);
  2725         -    while( iOffset<iSegment ){
  2726         -      void *pData;
  2727         -#if defined(SQLITE_HAS_CODEC)
  2728         -      if( (pData = sqlite3PagerCodec(pLast))==0 ) return SQLITE_NOMEM;
  2729         -#else
  2730         -      pData = pLast->pData;
  2731         -#endif
  2732         -      walEncodeFrame(pWal, pLast->pgno, nTruncate, pData, aFrame);
  2733         -      /* testcase( IS_BIG_INT(iOffset) ); // requires a 4GiB WAL */
  2734         -      rc = sqlite3OsWrite(pWal->pWalFd, aFrame, sizeof(aFrame), iOffset);
  2735         -      if( rc!=SQLITE_OK ){
  2736         -        return rc;
  2737         -      }
  2738         -      iOffset += WAL_FRAME_HDRSIZE;
  2739         -      rc = sqlite3OsWrite(pWal->pWalFd, pData, szPage, iOffset); 
  2740         -      if( rc!=SQLITE_OK ){
  2741         -        return rc;
  2742         -      }
  2743         -      nLast++;
  2744         -      iOffset += szPage;
         2845  +  /* If this frame set completes the first transaction in the WAL and
         2846  +  ** if PRAGMA journal_size_limit is set, then truncate the WAL to the
         2847  +  ** journal size limit, if possible.
         2848  +  */
         2849  +  if( isCommit && pWal->truncateOnCommit && pWal->mxWalSize>=0 ){
         2850  +    i64 sz = pWal->mxWalSize;
         2851  +    if( walFrameOffset(iFrame+nExtra+1, szPage)>pWal->mxWalSize ){
         2852  +      sz = walFrameOffset(iFrame+nExtra+1, szPage);
  2745   2853       }
  2746         -
  2747         -    rc = sqlite3OsSync(pWal->pWalFd, sync_flags);
         2854  +    walLimitSize(pWal, sz);
         2855  +    pWal->truncateOnCommit = 0;
  2748   2856     }
  2749   2857   
  2750   2858     /* Append data to the wal-index. It is not necessary to lock the 
  2751   2859     ** wal-index to do this as the SQLITE_SHM_WRITE lock held on the wal-index
  2752   2860     ** guarantees that there are no other writers, and no data that may
  2753   2861     ** be in use by existing readers is being overwritten.
  2754   2862     */
  2755   2863     iFrame = pWal->hdr.mxFrame;
  2756   2864     for(p=pList; p && rc==SQLITE_OK; p=p->pDirty){
  2757   2865       iFrame++;
  2758   2866       rc = walIndexAppend(pWal, iFrame, p->pgno);
  2759   2867     }
  2760         -  while( nLast>0 && rc==SQLITE_OK ){
         2868  +  while( rc==SQLITE_OK && nExtra>0 ){
  2761   2869       iFrame++;
  2762         -    nLast--;
         2870  +    nExtra--;
  2763   2871       rc = walIndexAppend(pWal, iFrame, pLast->pgno);
  2764   2872     }
  2765   2873   
  2766   2874     if( rc==SQLITE_OK ){
  2767   2875       /* Update the private copy of the header. */
  2768   2876       pWal->hdr.szPage = (u16)((szPage&0xff00) | (szPage>>16));
  2769   2877       testcase( szPage<=32768 );

Changes to src/wal.h.

    15     15   */
    16     16   
    17     17   #ifndef _WAL_H_
    18     18   #define _WAL_H_
    19     19   
    20     20   #include "sqliteInt.h"
    21     21   
           22  +/* Additional values that can be added to the sync_flags argument of
           23  +** sqlite3WalFrames():
           24  +*/
           25  +#define WAL_SYNC_TRANSACTIONS  0x20   /* Sync at the end of each transaction */
           26  +#define SQLITE_SYNC_MASK       0x13   /* Mask off the SQLITE_SYNC_* values */
           27  +
    22     28   #ifdef SQLITE_OMIT_WAL
    23     29   # define sqlite3WalOpen(x,y,z)                   0
    24     30   # define sqlite3WalLimit(x,y)
    25     31   # define sqlite3WalClose(w,x,y,z)                0
    26     32   # define sqlite3WalBeginReadTransaction(y,z)     0
    27     33   # define sqlite3WalEndReadTransaction(z)
    28     34   # define sqlite3WalRead(v,w,x,y,z)               0

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/bigfile2.test.

            1  +# 2011 December 20
            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.  The
           12  +# focus of this script testing the ability of SQLite to handle database
           13  +# files larger than 4GB.
           14  +#
           15  +
           16  +set testdir [file dirname $argv0]
           17  +source $testdir/tester.tcl
           18  +set testprefix bigfile2
           19  +
           20  +# Create a small database.
           21  +#
           22  +do_execsql_test 1.1 {
           23  +  CREATE TABLE t1(a, b);
           24  +  INSERT INTO t1 VALUES(1, 2);
           25  +}
           26  +
           27  +# Pad the file out to 4GB in size. Then clear the file-size field in the
           28  +# db header. This will cause SQLite to assume that the first 4GB of pages
           29  +# are actually in use and new pages will be appended to the file.
           30  +#
           31  +db close
           32  +if {[catch {fake_big_file 4096 [pwd]/test.db} msg]} {
           33  +  puts "**** Unable to create a file larger than 4096 MB. *****"
           34  +  finish_test
           35  +  return
           36  +}
           37  +hexio_write test.db 28 00000000
           38  +
           39  +do_test 1.2 {
           40  +  file size test.db
           41  +} [expr 14 + 4096 * (1<<20)]
           42  +
           43  +# Now insert a large row. The overflow pages will be located past the 4GB
           44  +# boundary. Then, after opening and closing the database, test that the row
           45  +# can be read back in. 
           46  +# 
           47  +set str [string repeat k 30000]
           48  +do_test 1.3 {
           49  +  sqlite3 db test.db
           50  +  execsql { INSERT INTO t1 VALUES(3, $str) }
           51  +  db close
           52  +  sqlite3 db test.db
           53  +  db one { SELECT b FROM t1 WHERE a = 3 }
           54  +} $str
           55  +
           56  +db close
           57  +file delete test.db
           58  +
           59  +finish_test

Changes to test/dbstatus.test.

   207    207       # Additionally, in auto-vacuum mode, dropping tables and indexes causes
   208    208       # the page-cache to shrink. So the amount of memory freed is always
   209    209       # much greater than just that reported by DBSTATUS_SCHEMA_USED in this
   210    210       # case.
   211    211       #
   212    212       # Some of the memory used for sqlite_stat3 is unaccounted for by
   213    213       # dbstatus.
          214  +    #
          215  +    # Finally, on osx the estimate of memory used by the schema may be
          216  +    # slightly low. 
   214    217       #
   215    218       if {[string match *x $tn] || $AUTOVACUUM
   216         -         || ([string match *y $tn] && $STAT3)} {
          219  +         || ([string match *y $tn] && $STAT3)
          220  +         || ($::tcl_platform(os) == "Darwin")
          221  +    } {
   217    222         do_test dbstatus-2.$tn.ax { expr {($nSchema1-$nSchema2)<=$nFree} } 1
   218    223       } else {
   219    224         do_test dbstatus-2.$tn.a { expr {$nSchema1-$nSchema2} } $nFree
   220    225       }
   221    226     
   222    227       do_test dbstatus-2.$tn.b { list $nAlloc1 $nSchema1 } "$nAlloc3 $nSchema3"
   223    228       do_test dbstatus-2.$tn.c { list $nAlloc2 $nSchema2 } "$nAlloc4 $nSchema4"

Changes to test/e_createtable.test.

    54     54         db eval "SELECT DISTINCT tbl_name FROM $master ORDER BY tbl_name"
    55     55       ]
    56     56     }
    57     57     set res
    58     58   }
    59     59   
    60     60   
    61         -# EVIDENCE-OF: R-25262-01881 -- syntax diagram type-name
           61  +# EVIDENCE-OF: R-47266-09114 -- syntax diagram type-name
    62     62   #
    63     63   do_createtable_tests 0.1.1 -repair {
    64     64     drop_all_tables
    65     65   } {
    66     66     1   "CREATE TABLE t1(c1 one)"                        {}
    67     67     2   "CREATE TABLE t1(c1 one two)"                    {}
    68     68     3   "CREATE TABLE t1(c1 one two three)"              {}
................................................................................
    75     75   do_createtable_tests 0.1.2 -error {
    76     76     near "%s": syntax error
    77     77   } {
    78     78     1   "CREATE TABLE t1(c1 one(number))"                {number}
    79     79   }
    80     80   
    81     81   
    82         -# EVIDENCE-OF: R-18762-12428 -- syntax diagram column-constraint
    83         -#
    84         -#   Note: Not shown in the syntax diagram is the "NULL" constraint. This
    85         -#         is the opposite of "NOT NULL" - it implies that the column may
    86         -#         take a NULL value. This is the default anyway, so this type of
    87         -#         constraint is rarely used.
           82  +# EVIDENCE-OF: R-60689-48779 -- syntax diagram column-constraint
    88     83   #
    89     84   do_createtable_tests 0.2.1 -repair {
    90     85     drop_all_tables 
    91     86     execsql { CREATE TABLE t2(x PRIMARY KEY) }
    92     87   } {
    93     88     1.1   "CREATE TABLE t1(c1 text PRIMARY KEY)"                         {}
    94     89     1.2   "CREATE TABLE t1(c1 text PRIMARY KEY ASC)"                     {}
................................................................................
   127    122     8.2   {
   128    123       CREATE TABLE t1(c1 
   129    124         REFERENCES t1 DEFAULT 123 CHECK(c1 IS 'ten') UNIQUE NOT NULL PRIMARY KEY 
   130    125       );
   131    126     } {}
   132    127   }
   133    128   
   134         -# EVIDENCE-OF: R-17905-31923 -- syntax diagram table-constraint
          129  +# EVIDENCE-OF: R-58169-51804 -- syntax diagram table-constraint
   135    130   #
   136    131   do_createtable_tests 0.3.1 -repair {
   137    132     drop_all_tables 
   138    133     execsql { CREATE TABLE t2(x PRIMARY KEY) }
   139    134   } {
   140    135     1.1   "CREATE TABLE t1(c1, c2, PRIMARY KEY(c1))"                         {}
   141    136     1.2   "CREATE TABLE t1(c1, c2, PRIMARY KEY(c1, c2))"                     {}
................................................................................
   146    141     2.3   "CREATE TABLE t1(c1, c2, UNIQUE(c1, c2) ON CONFLICT IGNORE)"       {}
   147    142   
   148    143     3.1   "CREATE TABLE t1(c1, c2, CHECK(c1 IS NOT c2))"                     {}
   149    144   
   150    145     4.1   "CREATE TABLE t1(c1, c2, FOREIGN KEY(c1) REFERENCES t2)"           {}
   151    146   }
   152    147   
   153         -# EVIDENCE-OF: R-18765-31171 -- syntax diagram column-def
          148  +# EVIDENCE-OF: R-44826-22243 -- syntax diagram column-def
   154    149   #
   155    150   do_createtable_tests 0.4.1 -repair {
   156    151     drop_all_tables 
   157    152   } {
   158    153     1     {CREATE TABLE t1(
   159    154              col1,
   160    155              col2 TEXT,
................................................................................
   161    156              col3 INTEGER UNIQUE,
   162    157              col4 VARCHAR(10, 10) PRIMARY KEY,
   163    158              "name with spaces" REFERENCES t1
   164    159            );
   165    160           } {}
   166    161   }
   167    162   
   168         -# EVIDENCE-OF: R-59573-11075 -- syntax diagram create-table-stmt
          163  +# EVIDENCE-OF: R-45698-45677 -- syntax diagram create-table-stmt
   169    164   #
   170    165   do_createtable_tests 0.5.1 -repair {
   171    166     drop_all_tables 
   172    167     execsql { CREATE TABLE t2(a, b, c) }
   173    168   } {
   174    169     1     "CREATE TABLE t1(a, b, c)"                                    {}
   175    170     2     "CREATE TEMP TABLE t1(a, b, c)"                               {}
................................................................................
   186    181     12    "CREATE TEMPORARY TABLE IF NOT EXISTS temp.t1(a, b, c)"       {}
   187    182   
   188    183     13    "CREATE TABLE t1 AS SELECT * FROM t2"                         {}
   189    184     14    "CREATE TEMP TABLE t1 AS SELECT c, b, a FROM t2"              {}
   190    185     15    "CREATE TABLE t1 AS SELECT count(*), max(b), min(a) FROM t2"  {}
   191    186   }
   192    187   
   193         -# EVIDENCE-OF: R-32138-02228 -- syntax diagram foreign-key-clause
          188  +# EVIDENCE-OF: R-24369-11919 -- syntax diagram foreign-key-clause
   194    189   #
   195    190   #   1:         Explicit parent-key columns.
   196    191   #   2:         Implicit child-key columns.
   197    192   #
   198    193   #   1:         MATCH FULL
   199    194   #   2:         MATCH PARTIAL
   200    195   #   3:         MATCH SIMPLE

Changes to test/e_delete.test.

    20     20   }
    21     21   
    22     22   do_execsql_test e_delete-0.0 {
    23     23     CREATE TABLE t1(a, b);
    24     24     CREATE INDEX i1 ON t1(a);
    25     25   } {}
    26     26   
    27         -# EVIDENCE-OF: R-24177-52883 -- syntax diagram delete-stmt
           27  +# EVIDENCE-OF: R-62077-19799 -- syntax diagram delete-stmt
    28     28   #
    29         -# EVIDENCE-OF: R-12802-60464 -- syntax diagram qualified-table-name
           29  +# EVIDENCE-OF: R-60796-31013 -- syntax diagram qualified-table-name
    30     30   #
    31     31   do_delete_tests e_delete-0.1 {
    32     32     1  "DELETE FROM t1"                              {}
    33     33     2  "DELETE FROM t1 INDEXED BY i1"                {}
    34     34     3  "DELETE FROM t1 NOT INDEXED"                  {}
    35     35     4  "DELETE FROM main.t1"                         {}
    36     36     5  "DELETE FROM main.t1 INDEXED BY i1"           {}
................................................................................
   283    283   }
   284    284   
   285    285   # EVIDENCE-OF: R-40026-10531 If SQLite is compiled with the
   286    286   # SQLITE_ENABLE_UPDATE_DELETE_LIMIT compile-time option, then the syntax
   287    287   # of the DELETE statement is extended by the addition of optional ORDER
   288    288   # BY and LIMIT clauses:
   289    289   #
   290         -# EVIDENCE-OF: R-45897-01670 -- syntax diagram delete-stmt-limited
          290  +# EVIDENCE-OF: R-52694-53361 -- syntax diagram delete-stmt-limited
   291    291   #
   292    292   do_delete_tests e_delete-3.1 {
   293    293     1   "DELETE FROM t1 LIMIT 5"                                    {}
   294    294     2   "DELETE FROM t1 LIMIT 5-1 OFFSET 2+2"                       {}
   295    295     3   "DELETE FROM t1 LIMIT 2+2, 16/4"                            {}
   296    296     4   "DELETE FROM t1 ORDER BY x LIMIT 5"                         {}
   297    297     5   "DELETE FROM t1 ORDER BY x LIMIT 5-1 OFFSET 2+2"            {}

Changes to test/e_droptrigger.test.

    65     65       CREATE TRIGGER aux.tr1 BEFORE $event ON t3 BEGIN SELECT r('aux.tr1') ; END;
    66     66       CREATE TRIGGER aux.tr2 AFTER  $event ON t3 BEGIN SELECT r('aux.tr2') ; END;
    67     67       CREATE TRIGGER aux.tr3 AFTER  $event ON t3 BEGIN SELECT r('aux.tr3') ; END;
    68     68     "
    69     69   }
    70     70   
    71     71   
    72         -# EVIDENCE-OF: R-52650-16855 -- syntax diagram drop-trigger-stmt
           72  +# EVIDENCE-OF: R-27975-10951 -- syntax diagram drop-trigger-stmt
    73     73   #
    74     74   do_droptrigger_tests 1.1 -repair {
    75     75     droptrigger_reopen_db
    76     76   } -tclquery {
    77     77     list_all_triggers 
    78     78   } {
    79     79     1   "DROP TRIGGER main.tr1"            

Changes to test/e_dropview.test.

    66     66     set res
    67     67   }
    68     68   
    69     69   proc do_dropview_tests {nm args} {
    70     70     uplevel do_select_tests $nm $args
    71     71   }
    72     72   
    73         -# EVIDENCE-OF: R-21739-51207 -- syntax diagram drop-view-stmt
           73  +# EVIDENCE-OF: R-53136-36436 -- syntax diagram drop-view-stmt
    74     74   #
    75     75   # All paths in the syntax diagram for DROP VIEW are tested by tests 1.*.
    76     76   #
    77     77   do_dropview_tests 1 -repair {
    78     78     dropview_reopen_db
    79     79   } -tclquery {
    80     80     list_all_views

Changes to test/e_expr.test.

   623    623          [sqlite3_column_type $stmt 3] 
   624    624   } {NULL NULL NULL NULL}
   625    625   do_test e_expr-11.7.1 { sqlite3_finalize $stmt } SQLITE_OK
   626    626   
   627    627   #-------------------------------------------------------------------------
   628    628   # "Test" the syntax diagrams in lang_expr.html.
   629    629   #
   630         -# EVIDENCE-OF: R-62067-43884 -- syntax diagram signed-number
          630  +# EVIDENCE-OF: R-02989-21050 -- syntax diagram signed-number
   631    631   #
   632    632   do_execsql_test e_expr-12.1.1 { SELECT 0, +0, -0 } {0 0 0}
   633    633   do_execsql_test e_expr-12.1.2 { SELECT 1, +1, -1 } {1 1 -1}
   634    634   do_execsql_test e_expr-12.1.3 { SELECT 2, +2, -2 } {2 2 -2}
   635    635   do_execsql_test e_expr-12.1.4 { 
   636    636     SELECT 1.4, +1.4, -1.4 
   637    637   } {1.4 1.4 -1.4}
................................................................................
   638    638   do_execsql_test e_expr-12.1.5 { 
   639    639     SELECT 1.5e+5, +1.5e+5, -1.5e+5 
   640    640   } {150000.0 150000.0 -150000.0}
   641    641   do_execsql_test e_expr-12.1.6 { 
   642    642     SELECT 0.0001, +0.0001, -0.0001 
   643    643   } {0.0001 0.0001 -0.0001}
   644    644   
   645         -# EVIDENCE-OF: R-21258-25489 -- syntax diagram literal-value
          645  +# EVIDENCE-OF: R-43188-60852 -- syntax diagram literal-value
   646    646   #
   647    647   set sqlite_current_time 1
   648    648   do_execsql_test e_expr-12.2.1 {SELECT 123}               {123}
   649    649   do_execsql_test e_expr-12.2.2 {SELECT 123.4e05}          {12340000.0}
   650    650   do_execsql_test e_expr-12.2.3 {SELECT 'abcde'}           {abcde}
   651    651   do_execsql_test e_expr-12.2.4 {SELECT X'414243'}         {ABC}
   652    652   do_execsql_test e_expr-12.2.5 {SELECT NULL}              {{}}
   653    653   do_execsql_test e_expr-12.2.6 {SELECT CURRENT_TIME}      {00:00:01}
   654    654   do_execsql_test e_expr-12.2.7 {SELECT CURRENT_DATE}      {1970-01-01}
   655    655   do_execsql_test e_expr-12.2.8 {SELECT CURRENT_TIMESTAMP} {{1970-01-01 00:00:01}}
   656    656   set sqlite_current_time 0
   657    657   
   658         -# EVIDENCE-OF: R-57598-59332 -- syntax diagram expr
          658  +# EVIDENCE-OF: R-50544-32159 -- syntax diagram expr
   659    659   #
   660    660   forcedelete test.db2
   661    661   execsql {
   662    662     ATTACH 'test.db2' AS dbname;
   663    663     CREATE TABLE dbname.tblname(cname);
   664    664   }
   665    665   
................................................................................
   808    808       incr x
   809    809       do_test e_expr-12.3.$tn.$x { 
   810    810         set rc [catch { execsql "SELECT $e FROM tblname" } msg]
   811    811       } {0}
   812    812     }
   813    813   }
   814    814   
   815         -# EVIDENCE-OF: R-49462-56079 -- syntax diagram raise-function
          815  +# EVIDENCE-OF: R-39820-63916 -- syntax diagram raise-function
   816    816   #
   817    817   foreach {tn raiseexpr} {
   818    818     1 "RAISE(IGNORE)"
   819    819     2 "RAISE(ROLLBACK, 'error message')"
   820    820     3 "RAISE(ABORT, 'error message')"
   821    821     4 "RAISE(FAIL, 'error message')"
   822    822   } {

Changes to test/e_insert.test.

    41     41     CREATE TABLE a4(c UNIQUE, d);
    42     42   } {}
    43     43   
    44     44   proc do_insert_tests {args} {
    45     45     uplevel do_select_tests $args
    46     46   }
    47     47   
    48         -# EVIDENCE-OF: R-41448-54465 -- syntax diagram insert-stmt
           48  +# EVIDENCE-OF: R-55375-41353 -- syntax diagram insert-stmt
    49     49   #
    50     50   do_insert_tests e_insert-0 {
    51     51        1  "INSERT             INTO a1 DEFAULT VALUES"                   {}
    52     52        2  "INSERT             INTO main.a1 DEFAULT VALUES"              {}
    53     53        3  "INSERT OR ROLLBACK INTO main.a1 DEFAULT VALUES"              {}
    54     54        4  "INSERT OR ROLLBACK INTO a1 DEFAULT VALUES"                   {}
    55     55        5  "INSERT OR ABORT    INTO main.a1 DEFAULT VALUES"              {}

Changes to test/e_reindex.test.

    22     22   
    23     23   do_execsql_test e_reindex-0.0 {
    24     24     CREATE TABLE t1(a, b);
    25     25     CREATE INDEX i1 ON t1(a, b);
    26     26     CREATE INDEX i2 ON t1(b, a);
    27     27   } {}
    28     28   
    29         -# EVIDENCE-OF: R-57021-15304 -- syntax diagram reindex-stmt
           29  +# EVIDENCE-OF: R-51477-38549 -- syntax diagram reindex-stmt
    30     30   #
    31     31   do_reindex_tests e_reindex-0.1 {
    32     32     1   "REINDEX"           {}
    33     33     2   "REINDEX nocase"    {}
    34     34     3   "REINDEX binary"    {}
    35     35     4   "REINDEX t1"        {}
    36     36     5   "REINDEX main.t1"   {}
    37         -  4   "REINDEX i1"        {}
    38         -  5   "REINDEX main.i1"   {}
           37  +  6   "REINDEX i1"        {}
           38  +  7   "REINDEX main.i1"   {}
    39     39   }
    40     40   
    41     41   # EVIDENCE-OF: R-52173-44778 The REINDEX command is used to delete and
    42     42   # recreate indices from scratch.
    43     43   #
    44     44   #    Test this by corrupting some database indexes, running REINDEX, and
    45     45   #    observing that the corruption is gone.

Changes to test/e_select.test.

    74     74     }
    75     75   }
    76     76   
    77     77   #-------------------------------------------------------------------------
    78     78   # The following tests check that all paths on the syntax diagrams on
    79     79   # the lang_select.html page may be taken.
    80     80   #
    81         -# EVIDENCE-OF: R-18428-22111 -- syntax diagram join-constraint
           81  +# EVIDENCE-OF: R-11353-33501 -- syntax diagram join-constraint
    82     82   #
    83     83   do_join_test e_select-0.1.1 {
    84     84     SELECT count(*) FROM t1 %JOIN% t2 ON (t1.a=t2.a)
    85     85   } {3}
    86     86   do_join_test e_select-0.1.2 {
    87     87     SELECT count(*) FROM t1 %JOIN% t2 USING (a)
    88     88   } {3}
................................................................................
    92     92   do_catchsql_test e_select-0.1.4 {
    93     93     SELECT count(*) FROM t1, t2 ON (t1.a=t2.a) USING (a)
    94     94   } {1 {cannot have both ON and USING clauses in the same join}}
    95     95   do_catchsql_test e_select-0.1.5 {
    96     96     SELECT count(*) FROM t1, t2 USING (a) ON (t1.a=t2.a)
    97     97   } {1 {near "ON": syntax error}}
    98     98   
    99         -# EVIDENCE-OF: R-44854-11739 -- syntax diagram select-core
           99  +# EVIDENCE-OF: R-40919-40941 -- syntax diagram select-core
   100    100   #
   101    101   #   0: SELECT ...
   102    102   #   1: SELECT DISTINCT ...
   103    103   #   2: SELECT ALL ...
   104    104   #
   105    105   #   0: No FROM clause
   106    106   #   1: Has FROM clause
................................................................................
   217    217       1 a 1 c
   218    218     }
   219    219     2112.2  "SELECT ALL count(*), max(a) FROM t1 
   220    220              WHERE 0 GROUP BY b HAVING count(*)=2" { }
   221    221   }
   222    222   
   223    223   
   224         -# EVIDENCE-OF: R-23316-20169 -- syntax diagram result-column
          224  +# EVIDENCE-OF: R-41378-26734 -- syntax diagram result-column
   225    225   #
   226    226   do_select_tests e_select-0.3 {
   227    227     1  "SELECT * FROM t1" {a one b two c three}
   228    228     2  "SELECT t1.* FROM t1" {a one b two c three}
   229    229     3  "SELECT 'x'||a||'x' FROM t1" {xax xbx xcx}
   230    230     4  "SELECT 'x'||a||'x' alias FROM t1" {xax xbx xcx}
   231    231     5  "SELECT 'x'||a||'x' AS alias FROM t1" {xax xbx xcx}
   232    232   }
   233    233   
   234         -# EVIDENCE-OF: R-41233-21397 -- syntax diagram join-source
          234  +# EVIDENCE-OF: R-43129-35648 -- syntax diagram join-source
   235    235   #
   236         -# EVIDENCE-OF: R-45040-11121 -- syntax diagram join-op
          236  +# EVIDENCE-OF: R-36683-37460 -- syntax diagram join-op
   237    237   #
   238    238   do_select_tests e_select-0.4 {
   239    239     1  "SELECT t1.rowid FROM t1" {1 2 3}
   240    240     2  "SELECT t1.rowid FROM t1,t2" {1 1 1 2 2 2 3 3 3}
   241    241     3  "SELECT t1.rowid FROM t1,t2,t3" {1 1 1 1 1 1 2 2 2 2 2 2 3 3 3 3 3 3}
   242    242   
   243    243     4  "SELECT t1.rowid FROM t1" {1 2 3}
................................................................................
   254    254     12 "SELECT t1.rowid FROM t1 JOIN t3" {1 1 2 2 3 3}
   255    255     13 "SELECT t1.rowid FROM t1 LEFT OUTER JOIN t3" {1 1 2 2 3 3}
   256    256     14 "SELECT t1.rowid FROM t1 LEFT JOIN t3" {1 1 2 2 3 3}
   257    257     15 "SELECT t1.rowid FROM t1 INNER JOIN t3" {1 1 2 2 3 3}
   258    258     16 "SELECT t1.rowid FROM t1 CROSS JOIN t3" {1 1 2 2 3 3}
   259    259   }
   260    260   
   261         -# EVIDENCE-OF: R-56911-63533 -- syntax diagram compound-operator
          261  +# EVIDENCE-OF: R-28308-37813 -- syntax diagram compound-operator
   262    262   #
   263    263   do_select_tests e_select-0.5 {
   264    264     1  "SELECT rowid FROM t1 UNION ALL SELECT rowid+2 FROM t4" {1 2 3 3 4}
   265    265     2  "SELECT rowid FROM t1 UNION     SELECT rowid+2 FROM t4" {1 2 3 4}
   266    266     3  "SELECT rowid FROM t1 INTERSECT SELECT rowid+2 FROM t4" {3}
   267    267     4  "SELECT rowid FROM t1 EXCEPT    SELECT rowid+2 FROM t4" {1 2}
   268    268   }
   269    269   
   270         -# EVIDENCE-OF: R-60388-27458 -- syntax diagram ordering-term
          270  +# EVIDENCE-OF: R-06480-34950 -- syntax diagram ordering-term
   271    271   #
   272    272   do_select_tests e_select-0.6 {
   273    273     1  "SELECT b||a FROM t1 ORDER BY b||a"                  {onea threec twob}
   274    274     2  "SELECT b||a FROM t1 ORDER BY (b||a) COLLATE nocase" {onea threec twob}
   275    275     3  "SELECT b||a FROM t1 ORDER BY (b||a) ASC"            {onea threec twob}
   276    276     4  "SELECT b||a FROM t1 ORDER BY (b||a) DESC"           {twob threec onea}
   277    277   }
   278    278   
   279         -# EVIDENCE-OF: R-36494-33519 -- syntax diagram select-stmt
          279  +# EVIDENCE-OF: R-23926-36668 -- syntax diagram select-stmt
   280    280   #
   281    281   do_select_tests e_select-0.7 {
   282    282     1  "SELECT * FROM t1" {a one b two c three}
   283    283     2  "SELECT * FROM t1 ORDER BY b" {a one c three b two}
   284    284     3  "SELECT * FROM t1 ORDER BY b, a" {a one c three b two}
   285    285   
   286    286     4  "SELECT * FROM t1 LIMIT 10" {a one b two c three}

Changes to test/e_update.test.

    45     45     CREATE TABLE aux.t5(a, b);
    46     46   } {}
    47     47   
    48     48   proc do_update_tests {args} {
    49     49     uplevel do_select_tests $args
    50     50   }
    51     51   
    52         -# EVIDENCE-OF: R-05685-44205 -- syntax diagram update-stmt
           52  +# EVIDENCE-OF: R-62337-45828 -- syntax diagram update-stmt
    53     53   #
    54     54   do_update_tests e_update-0 {
    55     55     1    "UPDATE t1 SET a=10" {}
    56     56     2    "UPDATE t1 SET a=10, b=5" {}
    57     57     3    "UPDATE t1 SET a=10 WHERE b=5" {}
    58     58     4    "UPDATE t1 SET b=5,a=10 WHERE 1" {}
    59     59     5    "UPDATE main.t1 SET a=10" {}
................................................................................
   491    491   }
   492    492   
   493    493   # EVIDENCE-OF: R-59581-44104 If SQLite is built with the
   494    494   # SQLITE_ENABLE_UPDATE_DELETE_LIMIT compile-time option then the syntax
   495    495   # of the UPDATE statement is extended with optional ORDER BY and LIMIT
   496    496   # clauses
   497    497   #
   498         -# EVIDENCE-OF: R-08948-01887 -- syntax diagram update-stmt-limited
          498  +# EVIDENCE-OF: R-45169-39597 -- syntax diagram update-stmt-limited
   499    499   #
   500    500   do_update_tests e_update-3.0 {
   501    501     1   "UPDATE t1 SET a=b LIMIT 5"                                    {}
   502    502     2   "UPDATE t1 SET a=b LIMIT 5-1 OFFSET 2+2"                       {}
   503    503     3   "UPDATE t1 SET a=b LIMIT 2+2, 16/4"                            {}
   504    504     4   "UPDATE t1 SET a=b ORDER BY a LIMIT 5"                         {}
   505    505     5   "UPDATE t1 SET a=b ORDER BY a LIMIT 5-1 OFFSET 2+2"            {}

Changes to test/e_vacuum.test.

    61     61       set prevpageno $pageno
    62     62     }
    63     63     execsql { DROP TABLE temp.stat }
    64     64     set nFrag
    65     65   }
    66     66   
    67     67   
    68         -# EVIDENCE-OF: R-63707-33375 -- syntax diagram vacuum-stmt
           68  +# EVIDENCE-OF: R-45173-45977 -- syntax diagram vacuum-stmt
    69     69   #
    70     70   do_execsql_test e_vacuum-0.1 { VACUUM } {}
    71     71   
    72     72   # EVIDENCE-OF: R-51469-36013 Unless SQLite is running in
    73     73   # "auto_vacuum=FULL" mode, when a large amount of data is deleted from
    74     74   # the database file it leaves behind empty space, or "free" database
    75     75   # pages.

Changes to test/incrvacuum2.test.

   190    190         PRAGMA journal_mode = WAL;
   191    191         PRAGMA incremental_vacuum(1);
   192    192       }
   193    193     } {wal}
   194    194     do_test 4.2.1 {
   195    195       execsql { PRAGMA wal_checkpoint }
   196    196       file size test.db-wal
   197         -  } [wal_file_size [wal_frames db 2 1] 512]
          197  +  } [expr {32+2*(512+24)}]
   198    198   
   199    199     do_test 4.3 {
   200    200       db close
   201    201       sqlite3 db test.db
   202    202       set maxsz 0
   203    203       while {[file size test.db] > [expr 512*3]} {
   204    204         execsql { PRAGMA journal_mode = WAL }
   205    205         execsql { PRAGMA wal_checkpoint }
   206    206         execsql { PRAGMA incremental_vacuum(1) }
   207    207         set newsz [file size test.db-wal]
   208    208         if {$newsz>$maxsz} {set maxsz $newsz}
   209    209       }
   210    210       set maxsz 
   211         -  } [wal_file_size [wal_frames db 3 1] 512]
          211  +  } [expr {32+3*(512+24)}]
   212    212   }
   213    213   
   214    214   finish_test

Changes to test/journal2.test.

    30     30     string range [string repeat "${a_string_counter}." $n] 1 $n
    31     31   }
    32     32   
    33     33   # Create a [testvfs] and install it as the default VFS. Set the device
    34     34   # characteristics flags to "SAFE_DELETE".
    35     35   #
    36     36   testvfs tvfs -default 1
    37         -tvfs devchar undeletable_when_open
           37  +tvfs devchar {undeletable_when_open powersafe_overwrite}
    38     38   
    39     39   # Set up a hook so that each time a journal file is opened, closed or
    40     40   # deleted, the method name ("xOpen", "xClose" or "xDelete") and the final
    41     41   # segment of the journal file-name (i.e. "test.db-journal") are appended to
    42     42   # global list variable $::oplog.
    43     43   #
    44     44   tvfs filter {xOpen xClose xDelete}
................................................................................
   227    227       set ::oplog
   228    228     } {xClose test.db-journal xDelete test.db-journal}
   229    229     db close
   230    230   }
   231    231   
   232    232   tvfs delete
   233    233   finish_test
   234         -

Changes to test/multiplex.test.

    15     15   source $testdir/malloc_common.tcl
    16     16   
    17     17   # AFP doesn't like multiplex db tests
    18     18   if { ![path_is_local "."] } {
    19     19     finish_test 
    20     20     return 
    21     21   }
           22  +
           23  +# The tests in this file assume that SQLite is compiled without
           24  +# ENABLE_8_3_NAMES.
           25  +#
           26  +ifcapable 8_3_names {
           27  +  puts -nonewline "SQLite compiled with SQLITE_ENABLE_8_3_NAMES. "
           28  +  puts            "Skipping tests multiplex-*."
           29  +  finish_test
           30  +  return
           31  +}
    22     32   
    23     33   set g_chunk_size [ expr ($::SQLITE_MAX_PAGE_SIZE*16384) ]
    24     34   set g_max_chunks 32
    25     35   
    26     36   # This handles appending the chunk number
    27     37   # to the end of the filename.  if 
    28     38   # SQLITE_MULTIPLEX_EXT_OVWR is defined, then

Added test/multiplex2.test.

            1  +# 2010 October 29
            2  +#
            3  +# The author disclaims copyright to this source code.  In place of
            4  +# a legal notice, here is a blessing:
            5  +#
            6  +#    May you do good and not evil.
            7  +#    May you find forgiveness for yourself and forgive others.
            8  +#    May you share freely, never taking more than you give.
            9  +#
           10  +#***********************************************************************
           11  +#
           12  +
           13  +set testdir [file dirname $argv0]
           14  +source $testdir/tester.tcl
           15  +source $testdir/malloc_common.tcl
           16  +source $testdir/lock_common.tcl
           17  +
           18  +
           19  +do_multiclient_test tn {
           20  +  code1 { catch { sqlite3_multiplex_initialize "" 0 } }
           21  +  code2 { catch { sqlite3_multiplex_initialize "" 0 } }
           22  +
           23  +  code1 { db close }
           24  +  code2 { db2 close }
           25  +
           26  +  code1 { sqlite3 db test.db -vfs multiplex }
           27  +  code2 { sqlite3 db2 test.db -vfs multiplex }
           28  +
           29  +  code1 { sqlite3_multiplex_control db main chunk_size [expr 1024*1024] }
           30  +  code2 { sqlite3_multiplex_control db2 main chunk_size [expr 1024*1024] }
           31  +
           32  +  sql1 {
           33  +    CREATE TABLE t1(a, b);
           34  +    INSERT INTO t1 VALUES(randomblob(10), randomblob(4000));          --    1
           35  +    INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1;   --    2
           36  +    INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1;   --    4
           37  +    INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1;   --    8
           38  +    INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1;   --   16
           39  +    INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1;   --   32
           40  +    INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1;   --   64
           41  +    INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1;   --  128
           42  +    INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1;   --  256
           43  +    INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1;   --  512
           44  +    SELECT count(*) FROM t1;
           45  +  } 
           46  +
           47  +  do_test multiplex-1.$tn.1 { sql1 { SELECT count(*) FROM t1 } } 512
           48  +  do_test multiplex-1.$tn.2 { sql2 { SELECT count(*) FROM t1 } } 512
           49  +  sql2 { DELETE FROM t1 ; VACUUM }
           50  +  do_test multiplex-1.$tn.3 { sql1 { SELECT count(*) FROM t1 } } 0
           51  +
           52  +  sql1 {
           53  +    INSERT INTO t1 VALUES(randomblob(10), randomblob(4000));          --    1
           54  +    INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1;   --    2
           55  +    INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1;   --    4
           56  +    INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1;   --    8
           57  +    INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1;   --   16
           58  +    INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1;   --   32
           59  +    INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1;   --   64
           60  +    INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1;   --  128
           61  +    INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1;   --  256
           62  +    INSERT INTO t1 SELECT randomblob(10), randomblob(4000) FROM t1;   --  512
           63  +    SELECT count(*) FROM t1;
           64  +  }
           65  +
           66  +  do_test multiplex-1.$tn.4 { sql2 { SELECT count(*) FROM t1 } } 512
           67  +}
           68  +
           69  +catch { sqlite3_multiplex_shutdown }
           70  +finish_test

Added test/multiplex3.test.

            1  +
            2  +# 2011 December 13
            3  +#
            4  +# The author disclaims copyright to this source code.  In place of
            5  +# a legal notice, here is a blessing:
            6  +#
            7  +#    May you do good and not evil.
            8  +#    May you find forgiveness for yourself and forgive others.
            9  +#    May you share freely, never taking more than you give.
           10  +#
           11  +#***********************************************************************
           12  +#
           13  +# This file contains tests for error (IO, OOM etc.) handling when using
           14  +# the multiplexor extension with 8.3 filenames.
           15  +#
           16  +
           17  +set testdir [file dirname $argv0]
           18  +source $testdir/tester.tcl
           19  +source $testdir/malloc_common.tcl
           20  +set ::testprefix multiplex3
           21  +
           22  +ifcapable !8_3_names {
           23  +  puts -nonewline "SQLite compiled without SQLITE_ENABLE_8_3_NAMES. "
           24  +  puts            "Skipping tests multiplex3-*."
           25  +  finish_test
           26  +  return
           27  +}
           28  +
           29  +db close
           30  +sqlite3_shutdown
           31  +sqlite3_config_uri 1
           32  +autoinstall_test_functions
           33  +
           34  +sqlite3_multiplex_initialize "" 1
           35  +
           36  +proc destroy_vfs_stack {} {
           37  +  generic_unregister stack
           38  +  sqlite3_multiplex_shutdown
           39  +}
           40  +
           41  +proc multiplex_delete_db {} {
           42  +  forcedelete test.db
           43  +  for {set i 1} {$i <= 1000} {incr i} {
           44  +    forcedelete test.[format %03d $i]
           45  +  }
           46  +}
           47  +
           48  +# Procs to save and restore the current muliplexed database.
           49  +#
           50  +proc multiplex_save_db {} {
           51  +  foreach f [glob -nocomplain sv_test.*] { forcedelete $f }
           52  +  foreach f [glob -nocomplain test.*]    { forcecopy $f "sv_$f" }
           53  +}
           54  +proc multiplex_restore_db {} {
           55  +  foreach f [glob -nocomplain test.*]    {forcedelete $f}
           56  +  foreach f [glob -nocomplain sv_test.*] {forcecopy $f [string range $f 3 end]} }
           57  +
           58  +proc setup_and_save_db {} {
           59  +  multiplex_delete_db
           60  +  sqlite3 db file:test.db?8_3_names=1
           61  +  sqlite3_multiplex_control db main chunk_size [expr 256*1024]
           62  +  execsql {
           63  +    CREATE TABLE t1(a PRIMARY KEY, b);
           64  +    INSERT INTO t1 VALUES(randomblob(15), randomblob(2000));
           65  +    INSERT INTO t1 SELECT randomblob(15), randomblob(2000) FROM t1;    --   2
           66  +    INSERT INTO t1 SELECT randomblob(15), randomblob(2000) FROM t1;    --   4
           67  +    INSERT INTO t1 SELECT randomblob(15), randomblob(2000) FROM t1;    --   8
           68  +    INSERT INTO t1 SELECT randomblob(15), randomblob(2000) FROM t1;    --  16
           69  +    INSERT INTO t1 SELECT randomblob(15), randomblob(2000) FROM t1;    --  32
           70  +    INSERT INTO t1 SELECT randomblob(15), randomblob(2000) FROM t1;    --  64
           71  +    INSERT INTO t1 SELECT randomblob(15), randomblob(2000) FROM t1;    -- 128
           72  +    INSERT INTO t1 SELECT randomblob(15), randomblob(2000) FROM t1;    -- 256
           73  +    INSERT INTO t1 SELECT randomblob(15), randomblob(2000) FROM t1;    -- 512
           74  +  }
           75  +  set ::cksum1 [execsql {SELECT md5sum(a, b) FROM t1 ORDER BY a}]
           76  +  db close
           77  +  multiplex_save_db
           78  +}
           79  +
           80  +do_test 1.0 { setup_and_save_db } {}
           81  +do_faultsim_test 1 -prep {
           82  +  multiplex_restore_db
           83  +  sqlite3 db file:test.db?8_3_names=1
           84  +  sqlite3_multiplex_control db main chunk_size [expr 256*1024]
           85  +} -body {
           86  +  execsql {
           87  +    UPDATE t1 SET a=randomblob(12), b=randomblob(1500) WHERE (rowid%32)=0
           88  +  }
           89  +} -test {
           90  +  faultsim_test_result {0 {}}
           91  +  if {$testrc!=0} {
           92  +    set cksum2 [execsql {SELECT md5sum(a, b) FROM t1 ORDER BY a}]
           93  +    if {$cksum2 != $::cksum1} { error "data mismatch" }
           94  +  }
           95  +}
           96  +
           97  +#-------------------------------------------------------------------------
           98  +# The following tests verify that hot-journal rollback works. As follows:
           99  +#
          100  +#   1. Create a large database.
          101  +#   2. Set the pager cache to be very small.
          102  +#   3. Open a transaction. 
          103  +#   4. Run the following 100 times:
          104  +#      a. Update a row.
          105  +#      b. Copy all files on disk to a new db location, including the journal.
          106  +#      c. Verify that the new db can be opened and that the content matches
          107  +#         the database created in step 1 (proving the journal was rolled
          108  +#         back).
          109  +
          110  +do_test 2.0 { 
          111  +  setup_and_save_db
          112  +  multiplex_restore_db
          113  +  sqlite3 db file:test.db?8_3_names=1
          114  +  execsql { PRAGMA cache_size = 10 }
          115  +  execsql { BEGIN }
          116  +} {}
          117  +
          118  +for {set iTest 1} {$iTest<=100} {incr iTest} {
          119  +  do_test 2.$iTest {
          120  +    execsql { 
          121  +      UPDATE t1 SET a=randomblob(12), b=randomblob(1400) WHERE rowid=5*$iTest
          122  +    }
          123  +    foreach f [glob -nocomplain test.*] {forcecopy $f "xx_$f"}
          124  +    sqlite3 db2 file:xx_test.db?8_3_names=1
          125  +    execsql {SELECT md5sum(a, b) FROM t1 ORDER BY a} db2
          126  +  } $::cksum1
          127  +
          128  +  db2 close
          129  +}
          130  +
          131  +catch { db close }
          132  +sqlite3_multiplex_shutdown
          133  +finish_test

Changes to test/pager1.test.

   989    989       PRAGMA journal_mode = DELETE;
   990    990       PRAGMA synchronous = NORMAL;
   991    991       BEGIN;
   992    992         INSERT INTO t1 VALUES(85, 'Gorbachev');
   993    993         INSERT INTO t2 VALUES(85, 'Gorbachev');
   994    994       COMMIT;
   995    995     }
   996         -  set ::max_journal
   997         -} [expr 2615+[string length [pwd]]]
          996  +
          997  +  # The size of the journal file is now:
          998  +  # 
          999  +  #   1) 512 byte header +
         1000  +  #   2) 2 * (1024+8) byte records +
         1001  +  #   3) 20+N bytes of master-journal pointer, where N is the size of 
         1002  +  #      the master-journal name encoded as utf-8 with no nul term.
         1003  +  #
         1004  +  set mj_pointer [expr {
         1005  +    20 + [string length [pwd]] + [string length "/test.db-mjXXXXXX9XX"]
         1006  +  }]
         1007  +  expr {$::max_journal==(512+2*(1024+8)+$mj_pointer)}
         1008  +} 1
   998   1009   do_test pager1-5.4.2 {
   999   1010     set ::max_journal 0
  1000   1011     execsql {
  1001   1012       PRAGMA synchronous = full;
  1002   1013       BEGIN;
  1003   1014         DELETE FROM t1 WHERE b = 'Lenin';
  1004   1015         DELETE FROM t2 WHERE b = 'Lenin';
  1005   1016       COMMIT;
  1006   1017     }
  1007         -  set ::max_journal
  1008         -} [expr 3111+[string length [pwd]]]
         1018  +
         1019  +  # In synchronous=full mode, the master-journal pointer is not written
         1020  +  # directly after the last record in the journal file. Instead, it is
         1021  +  # written starting at the next (in this case 512 byte) sector boundary.
         1022  +  #
         1023  +  set mj_pointer [expr {
         1024  +    20 + [string length [pwd]] + [string length "/test.db-mjXXXXXX9XX"]
         1025  +  }]
         1026  +  expr {$::max_journal==(((512+2*(1024+8)+511)/512)*512 + $mj_pointer)}
         1027  +} 1
  1009   1028   db close
  1010   1029   tv delete
  1011   1030   
  1012   1031   do_test pager1-5.5.1 {
  1013   1032     sqlite3 db test.db
  1014   1033     execsql { 
  1015   1034       ATTACH 'test.db2' AS aux;
................................................................................
  1311   1330   #
  1312   1331   testvfs tv -default 1
  1313   1332   foreach sectorsize {
  1314   1333       32   64   128   256   512   1024   2048 
  1315   1334       4096 8192 16384 32768 65536 131072 262144
  1316   1335   } {
  1317   1336     tv sectorsize $sectorsize
         1337  +  tv devchar {}
  1318   1338     set eff $sectorsize
  1319   1339     if {$sectorsize < 512}   { set eff 512 }
  1320   1340     if {$sectorsize > 65536} { set eff 65536 }
  1321   1341   
  1322   1342     do_test pager1-10.$sectorsize.1 {
  1323   1343       faultsim_delete_and_reopen
  1324   1344       db func a_string a_string

Changes to test/permutations.test.

   106    106     fkey_malloc.test fuzz.test fuzz3.test fuzz_malloc.test in2.test loadext.test
   107    107     misc7.test mutex2.test notify2.test onefile.test pagerfault2.test 
   108    108     savepoint4.test savepoint6.test select9.test 
   109    109     speed1.test speed1p.test speed2.test speed3.test speed4.test 
   110    110     speed4p.test sqllimits1.test tkt2686.test thread001.test thread002.test
   111    111     thread003.test thread004.test thread005.test trans2.test vacuum3.test 
   112    112     incrvacuum_ioerr.test autovacuum_crash.test btree8.test shared_err.test
   113         -  vtab_err.test walslow.test walcrash.test 
   114         -  walthread.test rtree3.test indexfault.test
          113  +  vtab_err.test walslow.test walcrash.test walcrash3.test
          114  +  walthread.test rtree3.test indexfault.test 
   115    115   }]
   116    116   if {[info exists ::env(QUICKTEST_INCLUDE)]} {
   117    117     set allquicktests [concat $allquicktests $::env(QUICKTEST_INCLUDE)]
   118    118   }
   119    119   
   120    120   #############################################################################
   121    121   # Start of tests

Added test/quota-glob.test.

            1  +# 2011 December 1
            2  +#
            3  +# The author disclaims copyright to this source code.  In place of
            4  +# a legal notice, here is a blessing:
            5  +#
            6  +#    May you do good and not evil.
            7  +#    May you find forgiveness for yourself and forgive others.
            8  +#    May you share freely, never taking more than you give.
            9  +#
           10  +#***********************************************************************
           11  +#
           12  +# Tests for the glob-style string compare operator embedded in the
           13  +# quota shim.
           14  +#
           15  +
           16  +set testdir [file dirname $argv0]
           17  +source $testdir/tester.tcl
           18  +
           19  +catch { unset testnum }
           20  +catch { unset pattern }
           21  +catch { unset text }
           22  +catch { unset ans }
           23  +
           24  +foreach {testnum pattern text ans} {
           25  +   1  abcdefg   abcdefg   1
           26  +   2  abcdefG   abcdefg   0
           27  +   3  abcdef    abcdefg   0
           28  +   4  abcdefgh  abcdefg   0
           29  +   5  abcdef?   abcdefg   1
           30  +   6  abcdef?   abcdef    0
           31  +   7  abcdef?   abcdefgh  0
           32  +   8  abcdefg   abcdef?   0
           33  +   9  abcdef?   abcdef?   1
           34  +  10  abc/def   abc/def   1
           35  +  11  abc//def  abc/def   0
           36  +  12  */abc/*   x/abc/y   1
           37  +  13  */abc/*   /abc/     1
           38  +  16  */abc/*   x///a/ab/abc   0
           39  +  17  */abc/*   x//a/ab/abc/   1
           40  +  16  */abc/*   x///a/ab/abc   0
           41  +  17  */abc/*   x//a/ab/abc/   1
           42  +  18  **/abc/** x//a/ab/abc/   1
           43  +  19  *?/abc/*? x//a/ab/abc/y  1
           44  +  20  ?*/abc/?* x//a/ab/abc/y  1
           45  +  21  {abc[cde]efg}   abcbefg  0
           46  +  22  {abc[cde]efg}   abccefg  1
           47  +  23  {abc[cde]efg}   abcdefg  1
           48  +  24  {abc[cde]efg}   abceefg  1
           49  +  25  {abc[cde]efg}   abcfefg  0
           50  +  26  {abc[^cde]efg}  abcbefg  1
           51  +  27  {abc[^cde]efg}  abccefg  0
           52  +  28  {abc[^cde]efg}  abcdefg  0
           53  +  29  {abc[^cde]efg}  abceefg  0
           54  +  30  {abc[^cde]efg}  abcfefg  1
           55  +  31  {abc[c-e]efg}   abcbefg  0
           56  +  32  {abc[c-e]efg}   abccefg  1
           57  +  33  {abc[c-e]efg}   abcdefg  1
           58  +  34  {abc[c-e]efg}   abceefg  1
           59  +  35  {abc[c-e]efg}   abcfefg  0
           60  +  36  {abc[^c-e]efg}  abcbefg  1
           61  +  37  {abc[^c-e]efg}  abccefg  0
           62  +  38  {abc[^c-e]efg}  abcdefg  0
           63  +  39  {abc[^c-e]efg}  abceefg  0
           64  +  40  {abc[^c-e]efg}  abcfefg  1
           65  +  41  {abc[c-e]efg}   abc-efg  0
           66  +  42  {abc[-ce]efg}   abc-efg  1
           67  +  43  {abc[ce-]efg}   abc-efg  1
           68  +  44  {abc[][*?]efg}  {abc]efg} 1
           69  +  45  {abc[][*?]efg}  {abc*efg} 1
           70  +  46  {abc[][*?]efg}  {abc?efg} 1
           71  +  47  {abc[][*?]efg}  {abc[efg} 1
           72  +  48  {abc[^][*?]efg} {abc]efg} 0
           73  +  49  {abc[^][*?]efg} {abc*efg} 0
           74  +  50  {abc[^][*?]efg} {abc?efg} 0
           75  +  51  {abc[^][*?]efg} {abc[efg} 0
           76  +  52  {abc[^][*?]efg} {abcdefg} 1
           77  +  53  {*[xyz]efg}     {abcxefg} 1
           78  +  54  {*[xyz]efg}     {abcwefg} 0
           79  +} {
           80  +  do_test quota-glob-$testnum.1 {
           81  +    sqlite3_quota_glob $::pattern $::text
           82  +  } $::ans
           83  +  do_test quota-glob-$testnum.2 {
           84  +    sqlite3_quota_glob $::pattern [string map {/ \\} $::text]
           85  +  } $::ans
           86  +}
           87  +finish_test

Changes to test/quota.test.

    10     10   #***********************************************************************
    11     11   #
    12     12   
    13     13   set testdir [file dirname $argv0]
    14     14   source $testdir/tester.tcl
    15     15   source $testdir/malloc_common.tcl
    16     16   
           17  +unset -nocomplain defaultVfs
           18  +set defaultVfs [file_control_vfsname db]
    17     19   db close
    18     20   
    19     21   do_test quota-1.1 { sqlite3_quota_initialize nosuchvfs 1 } {SQLITE_ERROR}
    20     22   do_test quota-1.2 { sqlite3_quota_initialize "" 1 }        {SQLITE_OK}
    21     23   do_test quota-1.3 { sqlite3_quota_initialize "" 1 }        {SQLITE_MISUSE}
    22     24   do_test quota-1.4 { sqlite3_quota_shutdown }               {SQLITE_OK}
    23     25   
................................................................................
    44     46   #   quota-2.4.*: Try to shutdown the quota system before closing the db
    45     47   #                file. Check that this fails and the quota system still works
    46     48   #                afterwards. Then close the database and successfully shut
    47     49   #                down the quota system.
    48     50   #   
    49     51   sqlite3_quota_initialize "" 1
    50     52   
           53  +unset -nocomplain quota_request_ok
    51     54   proc quota_check {filename limitvar size} {
    52     55     upvar $limitvar limit
    53     56   
    54     57     lappend ::quota [set limit] $size
    55     58     if {[info exists ::quota_request_ok]} { set limit $size }
    56     59   }
    57     60   
................................................................................
    69     72     execsql {
    70     73       CREATE TABLE t1(a, b);
    71     74       INSERT INTO t1 VALUES(1, randomblob(1100));
    72     75       INSERT INTO t1 VALUES(2, randomblob(1100));
    73     76     }
    74     77     set ::quota
    75     78   } {}
           79  +do_test quota-2.1.2.1 {
           80  +  file_control_vfsname db
           81  +} quota/$defaultVfs
    76     82   do_test quota-2.1.3 { file size test.db } {4096}
    77     83   do_test quota-2.1.4 {
    78     84     catchsql { INSERT INTO t1 VALUES(3, randomblob(1100)) }
    79     85   } {1 {database or disk is full}}
    80     86   do_test quota-2.1.5 { set ::quota } {4096 5120}
    81     87   
    82     88   set ::quota_request_ok 1

Added test/quota2.test.

            1  +# 2011 December 1
            2  +#
            3  +# The author disclaims copyright to this source code.  In place of
            4  +# a legal notice, here is a blessing:
            5  +#
            6  +#    May you do good and not evil.
            7  +#    May you find forgiveness for yourself and forgive others.
            8  +#    May you share freely, never taking more than you give.
            9  +#
           10  +#***********************************************************************
           11  +#
           12  +
           13  +set testdir [file dirname $argv0]
           14  +source $testdir/tester.tcl
           15  +source $testdir/malloc_common.tcl
           16  +
           17  +db close
           18  +sqlite3_quota_initialize "" 1
           19  +
           20  +foreach dir {quota2a/x1 quota2a/x2 quota2a quota2b quota2c} {
           21  +  file delete -force $dir
           22  +}
           23  +foreach dir {quota2a quota2a/x1 quota2a/x2 quota2b quota2c} {
           24  +  file mkdir $dir
           25  +}
           26  +
           27  +# The standard_path procedure converts a pathname into a standard format
           28  +# that is the same across platforms.
           29  +#
           30  +unset -nocomplain ::quota_pwd ::quota_mapping
           31  +set ::quota_pwd [string map {\\ /} [pwd]]
           32  +set ::quota_mapping [list $::quota_pwd PWD]
           33  +proc standard_path {x} {
           34  +  set x [string map {\\ /} $x]
           35  +  return [string map $::quota_mapping $x]
           36  +}
           37  +
           38  +# The quota_check procedure is a callback from the quota handler.
           39  +# It has three arguments which are (1) the full pathname of the file
           40  +# that has gone over quota, (2) the quota limit, (3) the requested
           41  +# new quota size to cover the last write.  These three values are
           42  +# appended to the global variable $::quota.  The filename is processed
           43  +# to convert every \ character into / and to change the name of the
           44  +# working directory to PWD.  
           45  +#
           46  +# The quota is increased to the request if the ::quota_request_ok 
           47  +# global variable is true.
           48  +#
           49  +set ::quota {}
           50  +set ::quota_request_ok 0
           51  +
           52  +proc quota_check {filename limitvar size} {
           53  +  upvar $limitvar limit
           54  +  lappend ::quota [standard_path $filename] [set limit] $size
           55  +  if {$::quota_request_ok} {set limit $size}
           56  +}
           57  +
           58  +sqlite3_quota_set */quota2a/* 4000 quota_check
           59  +sqlite3_quota_set */quota2b/* 5000 quota_check
           60  +
           61  +unset -nocomplain bigtext
           62  +for {set i 1} {$i<=1000} {incr i} {
           63  +  if {$i%10==0} {
           64  +    append bigtext [format "%06d\n" $i]
           65  +  } else {
           66  +    append bigtext [format "%06d " $i]
           67  +  }
           68  +}
           69  +
           70  +catch { unset h1 }
           71  +catch { unset x }
           72  +do_test quota2-1.1 {
           73  +  set ::h1 [sqlite3_quota_fopen quota2a/xyz.txt w+b]
           74  +  sqlite3_quota_fwrite $::h1 1 7000 $bigtext
           75  +} {4000}
           76  +do_test quota2-1.2 {
           77  +  set ::quota
           78  +} {PWD/quota2a/xyz.txt 4000 7000}
           79  +do_test quota2-1.3 {
           80  +  sqlite3_quota_rewind $::h1
           81  +  set ::x [sqlite3_quota_fread $::h1 1001 7]
           82  +  string length $::x
           83  +} {3003}
           84  +do_test quota2-1.4 {
           85  +  string match $::x [string range $::bigtext 0 3002]
           86  +} {1}
           87  +do_test quota2-1.5 {
           88  +  sqlite3_quota_fseek $::h1 0 SEEK_END
           89  +  sqlite3_quota_ftell $::h1
           90  +} {4000}
           91  +do_test quota2-1.6 {
           92  +  sqlite3_quota_fseek $::h1 -100 SEEK_END
           93  +  sqlite3_quota_ftell $::h1
           94  +} {3900}
           95  +do_test quota2-1.7 {
           96  +  sqlite3_quota_fseek $::h1 -100 SEEK_CUR
           97  +  sqlite3_quota_ftell $::h1
           98  +} {3800}
           99  +do_test quota2-1.8 {
          100  +  sqlite3_quota_fseek $::h1 50 SEEK_CUR
          101  +  sqlite3_quota_ftell $::h1
          102  +} {3850}
          103  +do_test quota2-1.9 {
          104  +  sqlite3_quota_fseek $::h1 50 SEEK_SET
          105  +  sqlite3_quota_ftell $::h1
          106  +} {50}
          107  +do_test quota2-1.10 {
          108  +  sqlite3_quota_rewind $::h1
          109  +  sqlite3_quota_ftell $::h1
          110  +} {0}
          111  +do_test quota2-1.11 {
          112  +  standard_path [sqlite3_quota_dump]
          113  +} {{*/quota2b/* 5000 0} {*/quota2a/* 4000 4000 {PWD/quota2a/xyz.txt 4000 1 0}}}
          114  +do_test quota2-1.12 {
          115  +  sqlite3_quota_fclose $::h1
          116  +  standard_path [sqlite3_quota_dump]
          117  +} {{*/quota2b/* 5000 0} {*/quota2a/* 4000 4000 {PWD/quota2a/xyz.txt 4000 0 0}}}
          118  +do_test quota2-1.13 {
          119  +  sqlite3_quota_remove quota2a/xyz.txt
          120  +  standard_path [sqlite3_quota_dump]
          121  +} {{*/quota2b/* 5000 0} {*/quota2a/* 4000 0}}
          122  +
          123  +
          124  +set quota {}
          125  +do_test quota2-2.1 {
          126  +  set ::h1 [sqlite3_quota_fopen quota2c/xyz.txt w+b]
          127  +  sqlite3_quota_fwrite $::h1 1 7000 $bigtext
          128  +} {7000}
          129  +do_test quota2-2.2 {
          130  +  set ::quota
          131  +} {}
          132  +do_test quota2-2.3 {
          133  +  sqlite3_quota_rewind $::h1
          134  +  set ::x [sqlite3_quota_fread $::h1 1001 7]
          135  +  string length $::x
          136  +} {6006}
          137  +do_test quota2-2.4 {
          138  +  string match $::x [string range $::bigtext 0 6005]
          139  +} {1}
          140  +do_test quota2-2.5 {
          141  +  sqlite3_quota_fseek $::h1 0 SEEK_END
          142  +  sqlite3_quota_ftell $::h1
          143  +} {7000}
          144  +do_test quota2-2.6 {
          145  +  sqlite3_quota_fseek $::h1 -100 SEEK_END
          146  +  sqlite3_quota_ftell $::h1
          147  +} {6900}
          148  +do_test quota2-2.7 {
          149  +  sqlite3_quota_fseek $::h1 -100 SEEK_CUR
          150  +  sqlite3_quota_ftell $::h1
          151  +} {6800}
          152  +do_test quota2-2.8 {
          153  +  sqlite3_quota_fseek $::h1 50 SEEK_CUR
          154  +  sqlite3_quota_ftell $::h1
          155  +} {6850}
          156  +do_test quota2-2.9 {
          157  +  sqlite3_quota_fseek $::h1 50 SEEK_SET
          158  +  sqlite3_quota_ftell $::h1
          159  +} {50}
          160  +do_test quota2-2.10 {
          161  +  sqlite3_quota_rewind $::h1
          162  +  sqlite3_quota_ftell $::h1
          163  +} {0}
          164  +do_test quota2-2.11 {
          165  +  standard_path [sqlite3_quota_dump]
          166  +} {{*/quota2b/* 5000 0} {*/quota2a/* 4000 0}}
          167  +do_test quota2-2.12 {
          168  +  sqlite3_quota_fclose $::h1
          169  +  standard_path [sqlite3_quota_dump]
          170  +} {{*/quota2b/* 5000 0} {*/quota2a/* 4000 0}}
          171  +
          172  +do_test quota2-3.1 {
          173  +  sqlite3_quota_set */quota2b/* 0 quota_check
          174  +  set ::h1 [sqlite3_quota_fopen quota2a/x1/a.txt a]
          175  +  sqlite3_quota_fwrite $::h1 10 10 $bigtext
          176  +} {10}
          177  +do_test quota2-3.2 {
          178  +  standard_path [sqlite3_quota_dump]
          179  +} {{*/quota2a/* 4000 100 {PWD/quota2a/x1/a.txt 100 1 0}}}
          180  +do_test quota2-3.3a {
          181  +  sqlite3_quota_fflush $::h1 0
          182  +  standard_path [sqlite3_quota_dump]
          183  +} {{*/quota2a/* 4000 100 {PWD/quota2a/x1/a.txt 100 1 0}}}
          184  +do_test quota2-3.3b {
          185  +  sqlite3_quota_fflush $::h1 1
          186  +  standard_path [sqlite3_quota_dump]
          187  +} {{*/quota2a/* 4000 100 {PWD/quota2a/x1/a.txt 100 1 0}}}
          188  +do_test quota2-3.3c {
          189  +  sqlite3_quota_fflush $::h1
          190  +  standard_path [sqlite3_quota_dump]
          191  +} {{*/quota2a/* 4000 100 {PWD/quota2a/x1/a.txt 100 1 0}}}
          192  +do_test quota2-3.4 {
          193  +  sqlite3_quota_fclose $::h1
          194  +  standard_path [sqlite3_quota_dump]
          195  +} {{*/quota2a/* 4000 100 {PWD/quota2a/x1/a.txt 100 0 0}}}
          196  +do_test quota2-3.5 {
          197  +  set ::h2 [sqlite3_quota_fopen quota2a/x2/b.txt a]
          198  +  sqlite3_quota_fwrite $::h2 10 20 $bigtext
          199  +  standard_path [sqlite3_quota_dump]
          200  +} {{*/quota2a/* 4000 300 {PWD/quota2a/x2/b.txt 200 1 0} {PWD/quota2a/x1/a.txt 100 0 0}}}
          201  +do_test quota2-3.6 {
          202  +  set ::h3 [sqlite3_quota_fopen quota2a/x1/c.txt a]
          203  +  sqlite3_quota_fwrite $::h3 10 50 $bigtext
          204  +  standard_path [sqlite3_quota_dump]
          205  +} {{*/quota2a/* 4000 800 {PWD/quota2a/x1/c.txt 500 1 0} {PWD/quota2a/x2/b.txt 200 1 0} {PWD/quota2a/x1/a.txt 100 0 0}}}
          206  +do_test quota2-3.7 {
          207  +  file exists quota2a/x1/a.txt
          208  +} {1}
          209  +do_test quota2-3.8 {
          210  +  file exists quota2a/x2/b.txt
          211  +} {1}
          212  +do_test quota2-3.9 {
          213  +  file exists quota2a/x1/c.txt
          214  +} {1}
          215  +do_test quota2-3.10 {
          216  +  sqlite3_quota_remove quota2a/x1
          217  +  standard_path [sqlite3_quota_dump]
          218  +} {{*/quota2a/* 4000 700 {PWD/quota2a/x1/c.txt 500 1 1} {PWD/quota2a/x2/b.txt 200 1 0}}}
          219  +do_test quota2-3.11 {
          220  +  sqlite3_quota_fclose $::h2
          221  +  sqlite3_quota_fclose $::h3
          222  +  standard_path [sqlite3_quota_dump]
          223  +} {{*/quota2a/* 4000 200 {PWD/quota2a/x2/b.txt 200 0 0}}}
          224  +do_test quota2-3.12 {
          225  +  file exists quota2a/x1/a.txt
          226  +} {0}
          227  +do_test quota2-3.13 {
          228  +  file exists quota2a/x2/b.txt
          229  +} {1}
          230  +do_test quota2-3.14 {
          231  +  file exists quota2a/x1/c.txt
          232  +} {0}
          233  +
          234  +catch { sqlite3_quota_shutdown }
          235  +catch { unset quota_request_ok }
          236  +finish_test

Changes to test/selectB.test.

   190    190   do_test selectB-3.0 {
   191    191     execsql {
   192    192       DROP INDEX i1;
   193    193       DROP INDEX i2;
   194    194     }
   195    195   } {}
   196    196   
   197         -for {set ii 3} {$ii <= 4} {incr ii} {
          197  +for {set ii 3} {$ii <= 6} {incr ii} {
   198    198   
   199         -  if {$ii == 4} {
   200         -    do_test selectB-4.0 {
   201         -      execsql {
   202         -        CREATE INDEX i1 ON t1(a);
   203         -        CREATE INDEX i2 ON t1(b);
   204         -        CREATE INDEX i3 ON t1(c);
   205         -        CREATE INDEX i4 ON t2(d);
   206         -        CREATE INDEX i5 ON t2(e);
   207         -        CREATE INDEX i6 ON t2(f);
   208         -      }
   209         -    } {}
          199  +  switch $ii {
          200  +    4 {
          201  +      optimization_control db query-flattener off
          202  +    }
          203  +    5 {
          204  +      optimization_control db query-flattener on
          205  +      do_test selectB-5.0 {
          206  +        execsql {
          207  +          CREATE INDEX i1 ON t1(a);
          208  +          CREATE INDEX i2 ON t1(b);
          209  +          CREATE INDEX i3 ON t1(c);
          210  +          CREATE INDEX i4 ON t2(d);
          211  +          CREATE INDEX i5 ON t2(e);
          212  +          CREATE INDEX i6 ON t2(f);
          213  +        }
          214  +      } {}
          215  +    }
          216  +    6 {
          217  +      optimization_control db query-flattener off
          218  +    }
   210    219     }
   211    220   
   212    221     do_test selectB-$ii.1 {
   213    222       execsql {
   214    223         SELECT DISTINCT * FROM 
   215    224           (SELECT c FROM t1 UNION ALL SELECT e FROM t2) 
   216    225         ORDER BY 1;
................................................................................
   367    376   
   368    377     do_test selectB-$ii.21 {
   369    378       execsql {
   370    379         SELECT * FROM (SELECT * FROM t1 UNION ALL SELECT * FROM t2) ORDER BY a+b
   371    380       }
   372    381     } {2 4 6 3 6 9 8 10 12 12 15 18 14 16 18 21 24 27}
   373    382   
   374         -  do_test selectB-$ii.21 {
          383  +  do_test selectB-$ii.22 {
   375    384       execsql {
   376    385         SELECT * FROM (SELECT 345 UNION ALL SELECT d FROM t2) ORDER BY 1;
   377    386       }
   378    387     } {3 12 21 345}
          388  +
          389  +  do_test selectB-$ii.23 {
          390  +    execsql {
          391  +      SELECT x, y FROM (
          392  +        SELECT a AS x, b AS y FROM t1
          393  +        UNION ALL
          394  +        SELECT a*10 + 0.1, f*10 + 0.1 FROM t1 JOIN t2 ON (c=d)
          395  +        UNION ALL
          396  +        SELECT a*100, b*100 FROM t1
          397  +      ) ORDER BY 1;
          398  +    }
          399  +  } {2 4 8 10 14 16 80.1 180.1 200 400 800 1000 1400 1600}
          400  +
          401  +  do_test selectB-$ii.24 {
          402  +    execsql {
          403  +      SELECT x, y FROM (
          404  +        SELECT a AS x, b AS y FROM t1
          405  +        UNION ALL
          406  +        SELECT a*10 + 0.1, f*10 + 0.1 FROM t1 LEFT JOIN t2 ON (c=d)
          407  +        UNION ALL
          408  +        SELECT a*100, b*100 FROM t1
          409  +      ) ORDER BY 1;
          410  +    }
          411  +  } {2 4 8 10 14 16 20.1 {} 80.1 180.1 140.1 {} 200 400 800 1000 1400 1600}
          412  +
          413  +  do_test selectB-$ii.25 {
          414  +    execsql {
          415  +      SELECT x+y FROM (
          416  +        SELECT a AS x, b AS y FROM t1
          417  +        UNION ALL
          418  +        SELECT a*10 + 0.1, f*10 + 0.1 FROM t1 LEFT JOIN t2 ON (c=d)
          419  +        UNION ALL
          420  +        SELECT a*100, b*100 FROM t1
          421  +      ) WHERE y+x NOT NULL ORDER BY 1;
          422  +    }
          423  +  } {6 18 30 260.2 600 1800 3000}
   379    424   }
   380    425   
   381    426   finish_test

Changes to test/superlock.test.

    79     79   
    80     80   do_test 3.2 { sqlite3demo_superlock unlock test.db } {unlock}
    81     81   do_catchsql_test 3.3 { SELECT * FROM t1 }           {1 {database is locked}}
    82     82   do_catchsql_test 3.4 { INSERT INTO t1 VALUES(5, 6)} {1 {database is locked}}
    83     83   do_catchsql_test 3.5 { PRAGMA wal_checkpoint }      {0 {1 -1 -1}}
    84     84   do_test 3.6 { unlock } {}
    85     85   
    86         -do_execsql_test 4.1 { PRAGMA wal_checkpoint } [
    87         -  list 0 [wal_frames db 1 1] [wal_frames db 1 1]
    88         -]
           86  +# At this point the WAL file consists of a single frame only - written
           87  +# by test case 3.1. If the ZERO_DAMAGE flag were not set, it would consist
           88  +# of two frames - the frame written by 3.1 and a padding frame.
           89  +do_execsql_test 4.1 { PRAGMA wal_checkpoint } {0 1 1}
    89     90   
    90     91   do_test 4.2 { sqlite3demo_superlock unlock test.db } {unlock}
    91     92   do_catchsql_test 4.3 { SELECT * FROM t1 }           {1 {database is locked}}
    92     93   do_catchsql_test 4.4 { INSERT INTO t1 VALUES(5, 6)} {1 {database is locked}}
    93     94   do_catchsql_test 4.5 { PRAGMA wal_checkpoint }      {0 {1 -1 -1}}
    94     95   do_test 4.6 { unlock } {}
    95     96   

Changes to test/syscall.test.

    55     55   
    56     56   #-------------------------------------------------------------------------
    57     57   # Tests for the xNextSystemCall method.
    58     58   #
    59     59   foreach s {
    60     60       open close access getcwd stat fstat ftruncate
    61     61       fcntl read pread write pwrite fchmod fallocate
    62         -    pread64 pwrite64 unlink openDirectory mkdir rmdir
           62  +    pread64 pwrite64 unlink openDirectory mkdir rmdir 
           63  +    statvfs
    63     64   } {
    64     65     if {[test_syscall exists $s]} {lappend syscall_list $s}
    65     66   }
    66     67   do_test 3.1 { lsort [test_syscall list] } [lsort $syscall_list]
    67     68   
    68     69   #-------------------------------------------------------------------------
    69     70   # This test verifies that if a call to open() fails and errno is set to

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/unixexcl.test.

    75     75         db eval { SELECT * FROM t1 }
    76     76       }
    77     77     } {hello world}
    78     78     do_test unixexcl-2.$tn.4 { 
    79     79       csql2 { SELECT * FROM t1 } 
    80     80     } {0 {hello world}}
    81     81   }
           82  +
           83  +do_multiclient_test tn {
           84  +  do_test unixexcl-3.$tn.1 {
           85  +    code1 { db close; sqlite3 db file:test.db?psow=0 -vfs unix-excl -uri 1 }
           86  +    code2 { db2 close; sqlite3 db2 file:test.db?psow=0 -vfs unix-excl -uri 1 }
           87  +    sql1 {
           88  +      PRAGMA journal_mode = WAL;
           89  +      CREATE TABLE t1(a, b);
           90  +      INSERT INTO t1 VALUES(1, 2);
           91  +    }
           92  +  } {wal}
           93  +
           94  +  if {$tn==1} {
           95  +    do_test unixexcl-3.$tn.1.multiproc {
           96  +      csql2 { SELECT * FROM t1; }
           97  +    } {1 {database is locked}}
           98  +  } else {
           99  +    do_test unixexcl-3.$tn.1.singleproc {
          100  +      sql2 { SELECT * FROM t1; }
          101  +    } {1 2}
          102  +
          103  +    do_test unixexcl-3.$tn.2 {
          104  +      sql2 { 
          105  +        BEGIN;
          106  +          SELECT * FROM t1;
          107  +      }
          108  +    } {1 2}
          109  +    do_test unixexcl-3.$tn.3 {
          110  +      sql1 { PRAGMA wal_checkpoint; INSERT INTO t1 VALUES(3, 4); }
          111  +    } {0 3 3}
          112  +    do_test unixexcl-3.$tn.4 {
          113  +      sql2 { SELECT * FROM t1; }
          114  +    } {1 2}
          115  +    do_test unixexcl-3.$tn.5 {
          116  +      sql1 { SELECT * FROM t1; }
          117  +    } {1 2 3 4}
          118  +    do_test unixexcl-3.$tn.6 {
          119  +      sql2 { COMMIT; SELECT * FROM t1; }
          120  +    } {1 2 3 4}
          121  +    do_test unixexcl-3.$tn.7 {
          122  +      sql1 { PRAGMA wal_checkpoint; }
          123  +    } {0 4 4}
          124  +  }
          125  +}
    82    126   
    83    127   finish_test

Changes to test/wal.test.

   545    545     # Open a read transaction with [db2]. Check that this prevents [db] from
   546    546     # checkpointing the database. But not from writing to it.
   547    547     #
   548    548     do_test wal-10.$tn.11 {
   549    549       sql2 { BEGIN; SELECT * FROM t1 }
   550    550     } {1 2 3 4 5 6 7 8 9 10}
   551    551     do_test wal-10.$tn.12 {
   552         -    # Reader no longer blocks checkpoint:
   553         -    execsql { PRAGMA wal_checkpoint } 
   554         -  } [list 0 [wal_frames db 8 5] [wal_frames db 8 5]] 
          552  +    catchsql { PRAGMA wal_checkpoint } 
          553  +  } {0 {0 7 7}}   ;# Reader no longer block checkpoints
   555    554     do_test wal-10.$tn.13 {
   556    555       execsql { INSERT INTO t1 VALUES(11, 12) }
   557    556       sql2 {SELECT * FROM t1}
   558    557     } {1 2 3 4 5 6 7 8 9 10}
   559    558   
   560    559     # Writers do not block checkpoints any more either.
   561    560     #
   562    561     do_test wal-10.$tn.14 {
   563         -    execsql { PRAGMA wal_checkpoint } 
   564         -  } [list 0 [wal_frames db 9 6] [wal_frames db 8 5]]
          562  +    catchsql { PRAGMA wal_checkpoint } 
          563  +  } {0 {0 8 7}}
   565    564   
   566    565     # The following series of test cases used to verify another blocking
   567    566     # case in WAL - a case which no longer blocks.
   568    567     #
   569    568     do_test wal-10.$tn.15 {
   570    569       sql2 { COMMIT; BEGIN; SELECT * FROM t1; }
   571    570     } {1 2 3 4 5 6 7 8 9 10 11 12}
   572    571     do_test wal-10.$tn.16 {
   573         -    execsql { PRAGMA wal_checkpoint } 
   574         -  } [list 0 [wal_frames db 9 6] [wal_frames db 9 6]]
          572  +    catchsql { PRAGMA wal_checkpoint } 
          573  +  } {0 {0 8 8}}
   575    574     do_test wal-10.$tn.17 {
   576    575       execsql { PRAGMA wal_checkpoint } 
   577         -  } [list 0 [wal_frames db 9 6] [wal_frames db 9 6]]
          576  +  } {0 8 8}
   578    577     do_test wal-10.$tn.18 {
   579    578       sql3 { BEGIN; SELECT * FROM t1 }
   580    579     } {1 2 3 4 5 6 7 8 9 10 11 12}
   581    580     do_test wal-10.$tn.19 {
   582    581       catchsql { INSERT INTO t1 VALUES(13, 14) }
   583    582     } {0 {}}
   584    583     do_test wal-10.$tn.20 {
................................................................................
   593    592     } {1 2 3 4 5 6 7 8 9 10 11 12 13 14}
   594    593   
   595    594     # Another series of tests that used to demonstrate blocking behavior
   596    595     # but which now work.
   597    596     #
   598    597     do_test wal-10.$tn.23 {
   599    598       execsql { PRAGMA wal_checkpoint }
   600         -  } [list 0 [wal_frames db 10 7] [wal_frames db 10 7]]
          599  +  } {0 9 9}
   601    600     do_test wal-10.$tn.24 {
   602    601       sql2 { BEGIN; SELECT * FROM t1; }
   603    602     } {1 2 3 4 5 6 7 8 9 10 11 12 13 14}
   604    603     do_test wal-10.$tn.25 {
   605    604       execsql { PRAGMA wal_checkpoint }
   606         -  } [list 0 [wal_frames db 10 7] [wal_frames db 10 7]]
          605  +  } {0 9 9}
   607    606     do_test wal-10.$tn.26 {
   608    607       catchsql { INSERT INTO t1 VALUES(15, 16) }
   609    608     } {0 {}}
   610    609     do_test wal-10.$tn.27 {
   611    610       sql3 { INSERT INTO t1 VALUES(17, 18) }
   612    611     } {}
   613    612     do_test wal-10.$tn.28 {
................................................................................
   615    614         set ::STMT [sqlite3_prepare db3 "SELECT * FROM t1" -1 TAIL]
   616    615         sqlite3_step $::STMT
   617    616       }
   618    617       execsql { SELECT * FROM t1 }
   619    618     } {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18}
   620    619     do_test wal-10.$tn.29 {
   621    620       execsql { INSERT INTO t1 VALUES(19, 20) }
   622         -    execsql { PRAGMA wal_checkpoint }
   623         -  } [list 0 [wal_frames db 4 2] 0]
          621  +    catchsql { PRAGMA wal_checkpoint }
          622  +  } {0 {0 3 0}}
   624    623     do_test wal-10.$tn.30 {
   625    624       code3 { sqlite3_finalize $::STMT }
   626    625       execsql { PRAGMA wal_checkpoint }
   627         -  } [list 0 [wal_frames db 4 2] 0]
          626  +  } {0 3 0}
   628    627   
   629    628     # At one point, if a reader failed to upgrade to a writer because it
   630    629     # was reading an old snapshot, the write-locks were not being released.
   631    630     # Test that this bug has been fixed.
   632    631     #
   633    632     do_test wal-10.$tn.31 {
   634    633       sql2 COMMIT
................................................................................
   658    657       }
   659    658       sql2 {
   660    659         BEGIN;
   661    660           SELECT * FROM t1;
   662    661       }
   663    662     } {a b c d}
   664    663     do_test wal-10.$tn.36 {
   665         -    execsql { PRAGMA wal_checkpoint }
   666         -  } [list 0 [wal_frames db 11 5] [wal_frames db 11 5]]
          664  +    catchsql { PRAGMA wal_checkpoint }
          665  +  } {0 {0 8 8}}
   667    666     do_test wal-10.$tn.36 {
   668    667       sql3 { INSERT INTO t1 VALUES('e', 'f') }
   669    668       sql2 { SELECT * FROM t1 }
   670    669     } {a b c d}
   671    670     do_test wal-10.$tn.37 {
   672    671       sql2 COMMIT
   673    672       execsql { PRAGMA wal_checkpoint }
   674         -  } [list 0 [wal_frames db 13 5] [wal_frames db 13 5]]
          673  +  } {0 9 9}
   675    674   }
   676    675   
   677    676   #-------------------------------------------------------------------------
   678    677   # This block of tests, wal-11.*, test that nothing goes terribly wrong
   679    678   # if frames must be written to the log file before a transaction is
   680    679   # committed (in order to free up memory).
   681    680   #
................................................................................
  1041   1040     2 {sqlite3_wal_checkpoint db ""}           SQLITE_OK     1 1
  1042   1041     3 {db eval "PRAGMA wal_checkpoint"}        {0 10 10}     1 1
  1043   1042   
  1044   1043     4 {sqlite3_wal_checkpoint db main}         SQLITE_OK     1 0
  1045   1044     5 {sqlite3_wal_checkpoint db aux}          SQLITE_OK     0 1
  1046   1045     6 {sqlite3_wal_checkpoint db temp}         SQLITE_OK     0 0
  1047   1046     7 {db eval "PRAGMA main.wal_checkpoint"}   {0 10 10}     1 0
  1048         -  8 {db eval "PRAGMA aux.wal_checkpoint"}    {0 16 16}     0 1
         1047  +  8 {db eval "PRAGMA aux.wal_checkpoint"}    {0 13 13}     0 1
  1049   1048     9 {db eval "PRAGMA temp.wal_checkpoint"}   {0 -1 -1}     0 0
  1050   1049   } {
  1051   1050     do_test wal-16.$tn.1 {
  1052   1051       forcedelete test2.db test2.db-wal test2.db-journal
  1053   1052       forcedelete test.db test.db-wal test.db-journal
  1054   1053   
  1055   1054       sqlite3 db test.db
................................................................................
  1056   1055       execsql {
  1057   1056         ATTACH 'test2.db' AS aux;
  1058   1057         PRAGMA main.auto_vacuum = 0;
  1059   1058         PRAGMA aux.auto_vacuum = 0;
  1060   1059         PRAGMA main.journal_mode = WAL;
  1061   1060         PRAGMA aux.journal_mode = WAL;
  1062   1061         SELECT count(*) FROM main.sqlite_master, aux.sqlite_master;
  1063         -      PRAGMA synchronous = NORMAL;
         1062  +      PRAGMA main.synchronous = NORMAL;
         1063  +      PRAGMA aux.synchronous = NORMAL;
  1064   1064         PRAGMA aux.synchronous = FULL;
  1065   1065       }
  1066   1066     } {wal wal 0}
  1067   1067   
  1068   1068     do_test wal-16.$tn.2 {
  1069   1069       execsql {
  1070   1070         CREATE TABLE main.t1(a, b, PRIMARY KEY(a, b));
................................................................................
  1075   1075         INSERT INTO t1 SELECT * FROM t2;
  1076   1076       }
  1077   1077     
  1078   1078       list [file size test.db] [file size test.db-wal]
  1079   1079     } [list [expr 1*1024] [wal_file_size 10 1024]]
  1080   1080     do_test wal-16.$tn.3 {
  1081   1081       list [file size test2.db] [file size test2.db-wal]
  1082         -  } [list [expr 1*1024] [wal_file_size 16 1024]]
         1082  +  } [list [expr 1*1024] [wal_file_size 13 1024]]
  1083   1083     
  1084   1084     do_test wal-16.$tn.4 [list eval $ckpt_cmd] $ckpt_res
  1085   1085     
  1086   1086     do_test wal-16.$tn.5 {
  1087   1087       list [file size test.db] [file size test.db-wal]
  1088   1088     } [list [expr ($ckpt_main ? 7 : 1)*1024] [wal_file_size 10 1024]]
  1089   1089   
  1090   1090     do_test wal-16.$tn.6 {
  1091   1091       list [file size test2.db] [file size test2.db-wal]
  1092         -  } [list [expr ($ckpt_aux ? 7 : 1)*1024] [wal_file_size 16 1024]]
         1092  +  } [list [expr ($ckpt_aux ? 7 : 1)*1024] [wal_file_size 13 1024]]
  1093   1093   
  1094   1094     catch { db close }
  1095   1095   }
  1096   1096   
  1097   1097   #-------------------------------------------------------------------------
  1098   1098   # The following tests - wal-17.* - attempt to verify that the correct
  1099   1099   # number of "padding" frames are appended to the log file when a transaction
................................................................................
  1556   1556       execsql { 
  1557   1557         PRAGMA cache_size = 200;
  1558   1558         PRAGMA incremental_vacuum;
  1559   1559         PRAGMA wal_checkpoint;
  1560   1560       }
  1561   1561       file size test.db
  1562   1562     } [expr 3 * 1024]
         1563  +
         1564  +  # WAL file now contains a single frame - the new root page for table t1.
         1565  +  # It would be two frames (the new root page and a padding frame) if the
         1566  +  # ZERO_DAMAGE flag were not set.
  1563   1567     do_test 24.5 {
  1564   1568       file size test.db-wal
  1565         -  } [wal_file_size [wal_frames db 1 1] 1024]
         1569  +  } [wal_file_size 1 1024]
  1566   1570   }
  1567   1571   
  1568   1572   db close
  1569   1573   sqlite3_shutdown
  1570   1574   test_sqlite3_log
  1571   1575   sqlite3_initialize
  1572   1576   
  1573   1577   finish_test

Changes to test/wal2.test.

    18     18   source $testdir/lock_common.tcl
    19     19   source $testdir/malloc_common.tcl
    20     20   source $testdir/wal_common.tcl
    21     21   
    22     22   set testprefix wal2
    23     23   
    24     24   ifcapable !wal {finish_test ; return }
    25         -if { ![wal_is_ok] || [path_is_dos "."]} {
    26         -  finish_test 
    27         -  return 
    28         -}
    29     25   
    30     26   set sqlite_sync_count 0
    31     27   proc cond_incr_sync_count {adj} {
    32     28     global sqlite_sync_count
    33     29     if {$::tcl_platform(platform) == "windows"} {
    34     30       incr sqlite_sync_count $adj
    35     31     } {
................................................................................
   352    348   
   353    349   }
   354    350   
   355    351   #-------------------------------------------------------------------------
   356    352   # Test that a database connection using a VFS that does not support the
   357    353   # xShmXXX interfaces cannot open a WAL database.
   358    354   #
   359         -do_test wal2-4.1.1 {
          355  +do_test wal2-4.1 {
   360    356     sqlite3 db test.db
   361    357     execsql {
   362    358       PRAGMA auto_vacuum = 0;
   363    359       PRAGMA journal_mode = WAL;
   364    360       CREATE TABLE data(x);
   365    361       INSERT INTO data VALUES('need xShmOpen to see this');
   366         -  }
   367         -} {wal}
   368         -do_test wal2-4.1.2 {
   369         -  execsql {
   370    362       PRAGMA wal_checkpoint;
   371    363     }
   372         -} [list 0 [wal_frames db 3 2] [wal_frames db 3 2]]
          364  +  # Three pages in the WAL file at this point: One copy of page 1 and two
          365  +  # of the root page for table "data".
          366  +} {wal 0 3 3}
   373    367   do_test wal2-4.2 {
   374    368     db close
   375    369     testvfs tvfs -noshm 1
   376    370     sqlite3 db test.db -vfs tvfs
   377    371     catchsql { SELECT * FROM data }
   378    372   } {1 {unable to open database file}}
   379    373   do_test wal2-4.3 {
................................................................................
   723    717     do_test wal2-6.4.$tn.1 { execsql $S } $res
   724    718     do_test wal2-6.4.$tn.2 { set ::locks  } $L
   725    719   }
   726    720   
   727    721   db close
   728    722   tvfs delete
   729    723   
   730         -do_test wal2-6.5.1.1 {
          724  +do_test wal2-6.5.1 {
   731    725     sqlite3 db test.db
   732    726     execsql {
   733    727       PRAGMA auto_vacuum = 0;
   734    728       PRAGMA journal_mode = wal;
   735    729       PRAGMA locking_mode = exclusive;
   736    730       CREATE TABLE t2(a, b);
   737         -  }
   738         -} {wal exclusive}
   739         -do_test wal2-6.5.1.2 {
   740         -  execsql {
   741    731       PRAGMA wal_checkpoint;
   742    732       INSERT INTO t2 VALUES('I', 'II');
   743    733       PRAGMA journal_mode;
   744    734     }
   745         -} [list 0 [wal_frames db 2 1] [wal_frames db 2 1] wal]
          735  +} {wal exclusive 0 2 2 wal}
   746    736   do_test wal2-6.5.2 {
   747    737     execsql {
   748    738       PRAGMA locking_mode = normal;
   749    739       INSERT INTO t2 VALUES('III', 'IV');
   750    740       PRAGMA locking_mode = exclusive;
   751    741       SELECT * FROM t2;
   752    742     }
   753    743   } {normal exclusive I II III IV}
   754    744   do_test wal2-6.5.3 {
   755    745     execsql { PRAGMA wal_checkpoint }
   756         -} [list 0 [wal_frames db 2 2] [wal_frames db 2 2]]
          746  +} {0 2 2}
   757    747   db close
   758    748   
   759    749   proc lock_control {method filename handle spec} {
   760    750     foreach {start n op type} $spec break
   761    751     if {$op == "lock"} { return SQLITE_IOERR }
   762    752     return SQLITE_OK
   763    753   }
................................................................................
  1183   1173       catch { db close }
  1184   1174     }
  1185   1175   }
  1186   1176   
  1187   1177   #-------------------------------------------------------------------------
  1188   1178   # Test that "PRAGMA checkpoint_fullsync" appears to be working.
  1189   1179   #
  1190         -foreach {tn sql} {
  1191         -  1 { } 
  1192         -  2 { PRAGMA checkpoint_fullfsync = 1 }
  1193         -  3 { PRAGMA checkpoint_fullfsync = 0 }
         1180  +foreach {tn sql reslist} {
         1181  +  1 { }                                 {10 0 4 0 6 0}
         1182  +  2 { PRAGMA checkpoint_fullfsync = 1 } {10 4 4 2 6 2}
         1183  +  3 { PRAGMA checkpoint_fullfsync = 0 } {10 0 4 0 6 0}
  1194   1184   } {
  1195   1185     faultsim_delete_and_reopen
  1196   1186   
  1197   1187     execsql {PRAGMA auto_vacuum = 0}
  1198   1188     execsql $sql
  1199         -  do_execsql_test wal2-14.$tn.1 { 
  1200         -    PRAGMA journal_mode = WAL;
  1201         -    PRAGMA wal_autocheckpoint = 10;
  1202         -  } {wal 10}
  1203         -
  1204         -  unset -nocomplain res
  1205         -  set res(0,1) {5 0 2 0 2 0}      ;# checkpoint_fullfsync=0 sync=NORMAL
  1206         -  set res(0,2) {8 0 3 0 5 0}      ;# checkpoint_fullfsync=0 sync=FULL
  1207         -  set res(1,1) {5 4 2 2 2 2}      ;# checkpoint_fullfsync=1 sync=NORMAL
  1208         -  set res(1,2) {8 4 3 2 5 2}      ;# checkpoint_fullfsync=1 sync=FULL
  1209         -
  1210         -  set key1 [db one {PRAGMA checkpoint_fullfsync}]
  1211         -  set key2 [db one {PRAGMA main.synchronous}]
  1212         -  set reslist $res($key1,$key2)
         1189  +  do_execsql_test wal2-14.$tn.0 { PRAGMA page_size = 4096 }   {}
         1190  +  do_execsql_test wal2-14.$tn.1 { PRAGMA journal_mode = WAL } {wal}
  1213   1191   
  1214   1192     set sqlite_sync_count 0
  1215   1193     set sqlite_fullsync_count 0
  1216   1194   
  1217   1195     do_execsql_test wal2-14.$tn.2 {
         1196  +    PRAGMA wal_autocheckpoint = 10;
  1218   1197       CREATE TABLE t1(a, b);                -- 2 wal syncs
  1219         -    INSERT INTO t1 VALUES(1, 2);          -- 1 wal sync
         1198  +    INSERT INTO t1 VALUES(1, 2);          -- 2 wal sync
  1220   1199       PRAGMA wal_checkpoint;                -- 1 wal sync, 1 db sync
  1221   1200       BEGIN;
  1222   1201         INSERT INTO t1 VALUES(3, 4);
  1223   1202         INSERT INTO t1 VALUES(5, 6);
  1224         -    COMMIT;                               -- 1 wal sync
         1203  +    COMMIT;                               -- 2 wal sync
  1225   1204       PRAGMA wal_checkpoint;                -- 1 wal sync, 1 db sync
  1226         -  } [list 0 [wal_frames db 3 2] [wal_frames db 3 2] \
  1227         -          0 [wal_frames db 1 1] [wal_frames db 1 1] \
  1228         -  ]
         1205  +  } {10 0 3 3 0 1 1}
  1229   1206   
  1230   1207     do_test wal2-14.$tn.3 {
  1231   1208       cond_incr_sync_count 1
  1232   1209       list $sqlite_sync_count $sqlite_fullsync_count
  1233   1210     } [lrange $reslist 0 1]
  1234   1211   
  1235   1212     set sqlite_sync_count 0
................................................................................
  1255   1232   
  1256   1233   catch { db close }
  1257   1234   
  1258   1235   # PRAGMA checkpoint_fullsync
  1259   1236   # PRAGMA fullfsync
  1260   1237   # PRAGMA synchronous
  1261   1238   #
  1262         -foreach {tn settings} {
  1263         -  1  {0 0 off}    
  1264         -  2  {0 0 normal}
  1265         -  3  {0 0 full} 
         1239  +foreach {tn settings restart_sync commit_sync ckpt_sync} {
         1240  +  1  {0 0 off}     {0 0}  {0 0}  {0 0}
         1241  +  2  {0 0 normal}  {1 0}  {0 0}  {2 0}
         1242  +  3  {0 0 full}    {2 0}  {1 0}  {2 0}
         1243  +
         1244  +  4  {0 1 off}     {0 0}  {0 0}  {0 0}
         1245  +  5  {0 1 normal}  {0 1}  {0 0}  {0 2}
         1246  +  6  {0 1 full}    {0 2}  {0 1}  {0 2}
  1266   1247   
  1267         -  4  {0 1 off} 
  1268         -  5  {0 1 normal} 
  1269         -  6  {0 1 full}  
         1248  +  7  {1 0 off}     {0 0}  {0 0}  {0 0}
         1249  +  8  {1 0 normal}  {1 0}  {0 0}  {0 2}
         1250  +  9  {1 0 full}    {2 0}  {1 0}  {0 2}
  1270   1251   
  1271         -  7  {1 0 off}  
  1272         -  8  {1 0 normal}
  1273         -  9  {1 0 full} 
  1274         -
  1275         -  10 {1 1 off} 
  1276         -  11 {1 1 normal}
  1277         -  12 {1 1 full} 
         1252  +  10 {1 1 off}     {0 0}  {0 0}  {0 0}
         1253  +  11 {1 1 normal}  {0 1}  {0 0}  {0 2}
         1254  +  12 {1 1 full}    {0 2}  {0 1}  {0 2}
  1278   1255   } {
  1279   1256     forcedelete test.db
  1280   1257   
  1281   1258     testvfs tvfs -default 1
  1282   1259     tvfs filter xSync
  1283   1260     tvfs script xSyncCb
  1284   1261     proc xSyncCb {method file fileid flags} {
  1285   1262       incr ::sync($flags)
  1286   1263     }
  1287   1264   
  1288   1265     sqlite3 db test.db
  1289   1266     do_execsql_test 15.$tn.1 "
         1267  +    PRAGMA page_size = 4096;
  1290   1268       CREATE TABLE t1(x);
         1269  +    PRAGMA wal_autocheckpoint = OFF;
  1291   1270       PRAGMA journal_mode = WAL;
  1292   1271       PRAGMA checkpoint_fullfsync = [lindex $settings 0];
  1293   1272       PRAGMA fullfsync = [lindex $settings 1];
  1294   1273       PRAGMA synchronous = [lindex $settings 2];
  1295         -    SELECT count(*) FROM sqlite_master;
  1296         -  " {wal 1}
         1274  +  " {0 wal}
  1297   1275   
  1298         -  unset -nocomplain res
  1299         -  set res(0,0,0) {{0 0}  {0 0}}
  1300         -  set res(0,0,1) {{0 0}  {2 0}}
  1301         -  set res(0,0,2) {{1 0}  {2 0}}
  1302         -  set res(0,1,0) {{0 0}  {0 0}}
  1303         -  set res(0,1,1) {{0 0}  {0 2}}
  1304         -  set res(0,1,2) {{0 1}  {0 2}}
  1305         -  set res(1,0,0) {{0 0}  {0 0}}
  1306         -  set res(1,0,1) {{0 0}  {0 2}}
  1307         -  set res(1,0,2) {{1 0}  {0 2}}
  1308         -  set res(1,1,0) {{0 0}  {0 0}}
  1309         -  set res(1,1,1) {{0 0}  {0 2}}
  1310         -  set res(1,1,2) {{0 1}  {0 2}}
         1276  +if { $tn==2} breakpoint
         1277  +  do_test 15.$tn.2 {
         1278  +    set sync(normal) 0
         1279  +    set sync(full) 0
         1280  +    execsql { INSERT INTO t1 VALUES('abc') }
         1281  +    list $::sync(normal) $::sync(full)
         1282  +  } $restart_sync
  1311   1283   
  1312         -  set key1 [db one {PRAGMA checkpoint_fullfsync}]
  1313         -  set key2 [db one {PRAGMA fullfsync}]
  1314         -  set key3 [db one {PRAGMA synchronous}]
  1315         -
  1316         -  set commit_sync [lindex $res($key1,$key2,$key3) 0]
  1317         -  set ckpt_sync   [lindex $res($key1,$key2,$key3) 1]
  1318         -
  1319         -  do_test 15.$tn.2 {
         1284  +  do_test 15.$tn.3 {
  1320   1285       set sync(normal) 0
  1321   1286       set sync(full) 0
  1322   1287       execsql { INSERT INTO t1 VALUES('abc') }
  1323   1288       list $::sync(normal) $::sync(full)
  1324   1289     } $commit_sync
  1325   1290   
  1326         -  do_test 15.$tn.3 {
         1291  +  do_test 15.$tn.4 {
  1327   1292       set sync(normal) 0
  1328   1293       set sync(full) 0
  1329   1294       execsql { INSERT INTO t1 VALUES('def') }
  1330   1295       list $::sync(normal) $::sync(full)
  1331   1296     } $commit_sync
  1332   1297   
  1333         -  do_test 15.$tn.4 {
         1298  +  do_test 15.$tn.5 {
  1334   1299       set sync(normal) 0
  1335   1300       set sync(full) 0
  1336   1301       execsql { PRAGMA wal_checkpoint }
  1337   1302       list $::sync(normal) $::sync(full)
  1338   1303     } $ckpt_sync
  1339   1304     
  1340   1305     db close
  1341   1306     tvfs delete
  1342   1307   }
  1343   1308   
  1344   1309   
  1345   1310   
  1346   1311   finish_test

Changes to test/wal3.test.

    15     15   
    16     16   set testdir [file dirname $argv0]
    17     17   source $testdir/tester.tcl
    18     18   source $testdir/lock_common.tcl
    19     19   source $testdir/wal_common.tcl
    20     20   source $testdir/malloc_common.tcl
    21     21   ifcapable !wal {finish_test ; return }
    22         -if { ![wal_is_ok] } {
    23         -  finish_test 
    24         -  return 
    25         -}
    26     22   
    27     23   set a_string_counter 1
    28     24   proc a_string {n} {
    29     25     global a_string_counter
    30     26     incr a_string_counter
    31     27     string range [string repeat "${a_string_counter}." $n] 1 $n
    32     28   }
................................................................................
   203    199       {}
   204    200     2 normal  
   205    201       {test.db-wal normal test.db normal}
   206    202     3 full    
   207    203       {test.db-wal normal test.db-wal normal test.db-wal normal test.db normal}
   208    204   } {
   209    205   
   210         -  if { $::sqlite_options(default_ckptfullfsync) } {
   211         -    # checkpoint_fullfsync on by default
   212         -    if { $tn == 2} {
   213         -      set synccount {test.db-wal full test.db full}
   214         -    }
   215         -    if { $tn == 3} {
   216         -      set synccount {test.db-wal normal test.db-wal normal test.db-wal full test.db full}
   217         -    }
   218         -  }
   219         -
   220    206     proc sync_counter {args} { 
   221    207       foreach {method filename id flags} $args break
   222    208       lappend ::syncs [file tail $filename] $flags
   223    209     }
   224    210     do_test wal3-3.$tn {
   225    211       forcedelete test.db test.db-wal test.db-journal
   226    212     
   227    213       testvfs T
   228    214       T filter {} 
   229    215       T script sync_counter
   230    216       sqlite3 db test.db -vfs T
   231    217     
          218  +    execsql "PRAGMA synchronous = $syncmode"
   232    219       execsql { PRAGMA journal_mode = WAL }
   233         -    execsql { SELECT * FROM sqlite_master }
   234         -    execsql "PRAGMA synchronous = $syncmode"
          220  +    execsql { CREATE TABLE filler(a,b,c); }
   235    221   
   236    222       set ::syncs [list]
   237    223       T filter xSync
   238    224       execsql {
   239    225         CREATE TABLE x(y);
   240    226         INSERT INTO x VALUES('z');
   241    227         PRAGMA wal_checkpoint;
................................................................................
   439    425   do_test wal3-6.1.2 {
   440    426     sqlite3 db2 test.db
   441    427     sqlite3 db3 test.db
   442    428     execsql { BEGIN ; SELECT * FROM t1 } db3
   443    429   } {o t t f}
   444    430   do_test wal3-6.1.3 {
   445    431     execsql { PRAGMA wal_checkpoint } db2
   446         -} [list 0 [wal_frames db 4 3] [wal_frames db 4 3]]
          432  +} {0 4 4}
   447    433   
   448    434   # At this point the log file has been fully checkpointed. However, 
   449    435   # connection [db3] holds a lock that prevents the log from being wrapped.
   450    436   # Test case 3.6.1.4 has [db] attempt a read-lock on aReadMark[0]. But
   451    437   # as it is obtaining the lock, [db2] appends to the log file.
   452    438   #
   453    439   T filter xShmLock
................................................................................
   528    514         BEGIN;
   529    515         SELECT * FROM t1;
   530    516       }]
   531    517     }
   532    518   }
   533    519   do_test wal3-6.2.2 {
   534    520     execsql { PRAGMA wal_checkpoint }
   535         -} [list 0 [wal_frames db 4 3] [wal_frames db 4 3]]
          521  +} {0 4 4}
   536    522   do_test wal3-6.2.3 {
   537    523     set ::R
   538    524   } {h h l b}
   539    525   do_test wal3-6.2.4 {
   540    526     set sz1 [file size test.db-wal]
   541    527     execsql { INSERT INTO t1 VALUES('b', 'c'); }
   542    528     set sz2 [file size test.db-wal]
................................................................................
   625    611   
   626    612   db close
   627    613   db2 close
   628    614   T delete
   629    615   
   630    616   #-------------------------------------------------------------------------
   631    617   # 
   632         -do_test wal3-8.1.1 {
   633         -  forcedelete test.db test.db-journal test.db wal .test.db-conch
          618  +do_test wal3-8.1 {
          619  +  forcedelete test.db test.db-journal test.db wal
   634    620     sqlite3 db test.db
   635    621     sqlite3 db2 test.db
   636    622     execsql {
   637    623       PRAGMA auto_vacuum = off;
   638    624       PRAGMA journal_mode = WAL;
   639    625       CREATE TABLE b(c);
   640    626       INSERT INTO b VALUES('Tehran');
   641    627       INSERT INTO b VALUES('Qom');
   642    628       INSERT INTO b VALUES('Markazi');
          629  +    PRAGMA wal_checkpoint;
   643    630     }
   644         -} {wal}
   645         -
   646         -do_test wal3.8.1.2 {
   647         -  execsql { PRAGMA wal_checkpoint; }
   648         -} [list 0 [wal_frames db 5 4] [wal_frames db 5 4]]
          631  +} {wal 0 5 5}
   649    632   do_test wal3-8.2 {
   650    633     execsql { SELECT * FROM b }
   651    634   } {Tehran Qom Markazi}
   652    635   do_test wal3-8.3 {
   653    636     db eval { SELECT * FROM b } {
   654    637       db eval { INSERT INTO b VALUES('Qazvin') }
   655    638       set r [db2 eval { SELECT * FROM b }]

Changes to test/wal5.test.

   193    193         sql1 {
   194    194           CREATE TABLE t1(a, b);
   195    195           INSERT INTO t1 VALUES(1, 2);
   196    196           CREATE TABLE aux.t2(a, b);
   197    197           INSERT INTO t2 VALUES(1, 2);
   198    198         }
   199    199       } {}
   200         -    do_test 2.2.$tn.2 { file_page_counts } [
   201         -      list 1 [wal_frames db 3 2] 1 [wal_frames db 3 2]
   202         -    ]
   203         -    do_test 2.1.$tn.3 { code1 { do_wal_checkpoint db } } [
   204         -      list 0 [wal_frames db 3 2] [wal_frames db 3 2]
   205         -    ]
   206         -    do_test 2.1.$tn.4 { file_page_counts } [
   207         -      list 2 [wal_frames db 3 2] 2 [wal_frames db 3 2]
   208         -    ]
          200  +    do_test 2.2.$tn.2 { file_page_counts } {1 3 1 3}
          201  +    do_test 2.1.$tn.3 { code1 { do_wal_checkpoint db } } {0 3 3}
          202  +    do_test 2.1.$tn.4 { file_page_counts } {2 3 2 3}
   209    203     }
   210    204   
   211    205     do_multiclient_test tn {
   212    206       setup_and_attach_aux
   213    207       do_test 2.2.$tn.1 {
   214    208         execsql {
   215    209           CREATE TABLE t1(a, b);
   216    210           INSERT INTO t1 VALUES(1, 2);
   217    211           CREATE TABLE aux.t2(a, b);
   218    212           INSERT INTO t2 VALUES(1, 2);
   219    213           INSERT INTO t2 VALUES(3, 4);
   220    214         }
   221    215       } {}
   222         -    do_test 2.2.$tn.2 { file_page_counts } [
   223         -      list 1 [wal_frames db 3 2] 1 [wal_frames db 4 3]
   224         -    ]
          216  +    do_test 2.2.$tn.2 { file_page_counts } {1 3 1 4}
   225    217       do_test 2.2.$tn.3 { sql2 { BEGIN; SELECT * FROM t1 } } {1 2}
   226         -    do_test 2.2.$tn.4 { code1 { do_wal_checkpoint db -mode restart } } [
   227         -      list 1 [wal_frames db 3 2] [wal_frames db 3 2]
   228         -    ]
   229         -    do_test 2.2.$tn.5 { file_page_counts } [
   230         -      list 2 [wal_frames db 3 2] 2 [wal_frames db 4 3]
   231         -    ]
          218  +    do_test 2.2.$tn.4 { code1 { do_wal_checkpoint db -mode restart } } {1 3 3}
          219  +    do_test 2.2.$tn.5 { file_page_counts } {2 3 2 4}
   232    220     }
   233    221   
   234    222     do_multiclient_test tn {
   235    223       setup_and_attach_aux
   236    224       do_test 2.3.$tn.1 {
   237    225         execsql {
   238    226           CREATE TABLE t1(a, b);
   239    227           INSERT INTO t1 VALUES(1, 2);
   240    228           CREATE TABLE aux.t2(a, b);
   241    229           INSERT INTO t2 VALUES(1, 2);
   242    230         }
   243    231       } {}
   244         -    do_test 2.3.$tn.2 { file_page_counts } [
   245         -      list 1 [wal_frames db 3 2] 1 [wal_frames db 3 2]
   246         -    ]
          232  +    do_test 2.3.$tn.2 { file_page_counts } {1 3 1 3}
   247    233       do_test 2.3.$tn.3 { sql2 { BEGIN; SELECT * FROM t1 } } {1 2}
   248    234       do_test 2.3.$tn.4 { sql1 { INSERT INTO t1 VALUES(3, 4) } } {}
   249    235       do_test 2.3.$tn.5 { sql1 { INSERT INTO t2 VALUES(3, 4) } } {}
   250         -    do_test 2.3.$tn.6 { file_page_counts } [
   251         -      list 1 [wal_frames db 4 3] 1 [wal_frames db 4 3]
   252         -    ]
   253         -    do_test 2.3.$tn.7 { code1 { do_wal_checkpoint db -mode full } } [
   254         -      list 1 [wal_frames db 4 3] [wal_frames db 3 2]
   255         -    ]
   256         -    do_test 2.3.$tn.8 { file_page_counts } {1 7 2 7}
          236  +    do_test 2.3.$tn.6 { file_page_counts } {1 4 1 4}
          237  +    do_test 2.3.$tn.7 { code1 { do_wal_checkpoint db -mode full } } {1 4 3}
          238  +    do_test 2.3.$tn.8 { file_page_counts } {1 4 2 4}
   257    239     }
   258    240   
   259    241     # Check that checkpoints block on the correct locks. And respond correctly
   260    242     # if they cannot obtain those locks. There are three locks that a checkpoint
   261    243     # may block on (in the following order):
   262    244     #
   263    245     #   1. The writer lock: FULL and RESTART checkpoints block until any writer
................................................................................
   270    252     #      database file, RESTART checkpoints block until readers using any part
   271    253     #      of the log file have finished.
   272    254     #
   273    255     # This test case involves running a checkpoint while there exist other 
   274    256     # processes holding all three types of locks.
   275    257     #
   276    258     foreach {tn1 checkpoint busy_on ckpt_expected expected} {
   277         -    1   PASSIVE   -   {0 5 5}   -
   278         -    2   TYPO      -   {0 5 5}   -
          259  +    1   PASSIVE   -   {0 3 3}   -
          260  +    2   TYPO      -   {0 3 3}   -
   279    261   
   280         -    3   FULL      -   {0 7 7}   2
   281         -    4   FULL      1   {1 5 5}   1
   282         -    5   FULL      2   {1 7 5}   2
   283         -    6   FULL      3   {0 7 7}   2
          262  +    3   FULL      -   {0 4 4}   2
          263  +    4   FULL      1   {1 3 3}   1
          264  +    5   FULL      2   {1 4 3}   2
          265  +    6   FULL      3   {0 4 4}   2
   284    266   
   285         -    7   RESTART   -   {0 7 7}   3
   286         -    8   RESTART   1   {1 5 5}   1
   287         -    9   RESTART   2   {1 7 5}   2
   288         -    10  RESTART   3   {1 7 7}   3
          267  +    7   RESTART   -   {0 4 4}   3
          268  +    8   RESTART   1   {1 3 3}   1
          269  +    9   RESTART   2   {1 4 3}   2
          270  +    10  RESTART   3   {1 4 4}   3
   289    271   
   290    272     } {
   291    273       do_multiclient_test tn {
   292    274         setup_and_attach_aux
   293    275   
   294    276         proc busyhandler {x} {
   295    277           set ::max_busyhandler $x
................................................................................
   308    290             CREATE TABLE t1(a, b);
   309    291             INSERT INTO t1 VALUES(1, 2);
   310    292           }
   311    293           sql2 { BEGIN; INSERT INTO t1 VALUES(3, 4) }
   312    294           sql3 { BEGIN; SELECT * FROM t1 }
   313    295         } {1 2}
   314    296   
   315         -      # The value in ckpt_expected assumes that synchronous=FULL. If
   316         -      # synchronous=NORMAL, decrease the WAL size by 2 frames.
   317         -      if {$tn==1 && [db one {PRAGMA main.synchronous}] == 1} {
   318         -        lset ckpt_expected 1 [expr [lindex $ckpt_expected 1] - 2]
   319         -        lset ckpt_expected 2 [expr [lindex $ckpt_expected 2] - 2]
   320         -      }
   321         -  
   322    297         do_test 2.4.$tn1.$tn.2 {
   323    298           code1 { db busy busyhandler }
   324    299           code1 { do_wal_checkpoint db -mode [string tolower $checkpoint] }
   325    300         } $ckpt_expected
   326    301         do_test 2.4.$tn1.$tn.3 { set ::max_busyhandler } $expected
   327    302       }
   328    303     }

Added test/walcrash3.test.

            1  +# 2011 December 16
            2  +#
            3  +# The author disclaims copyright to this source code.  In place of
            4  +# a legal notice, here is a blessing:
            5  +#
            6  +#    May you do good and not evil.
            7  +#    May you find forgiveness for yourself and forgive others.
            8  +#    May you share freely, never taking more than you give.
            9  +#
           10  +#***********************************************************************
           11  +#
           12  +# This test simulates an application crash immediately following a
           13  +# system call to truncate a file. Specifically, the system call that
           14  +# truncates the WAL file if "PRAGMA journal_size_limit" is configured.
           15  +#
           16  +
           17  +set testdir [file dirname $argv0]
           18  +source $testdir/tester.tcl
           19  +
           20  +ifcapable !wal {finish_test ; return }
           21  +set testprefix walcrash3
           22  +
           23  +db close
           24  +testvfs tvfs
           25  +tvfs filter {xTruncate xWrite}
           26  +tvfs script tvfs_callback
           27  +proc tvfs_callback {args} {}
           28  +
           29  +sqlite3 db test.db -vfs tvfs
           30  +do_execsql_test 1.1 {
           31  +  PRAGMA page_size = 1024;
           32  +  PRAGMA journal_mode = WAL;
           33  +  PRAGMA wal_autocheckpoint = 128;
           34  +  PRAGMA journal_size_limit = 16384;
           35  +
           36  +  CREATE TABLE t1(a BLOB, b BLOB, UNIQUE(a, b));
           37  +  INSERT INTO t1 VALUES(randomblob(10), randomblob(1000));
           38  +} {wal 128 16384}
           39  +
           40  +proc tvfs_callback {method file arglist} {
           41  +  if {$::state==1} {
           42  +    foreach f [glob -nocomplain xx_test.*] { forcedelete $f }
           43  +    foreach f [glob -nocomplain test.*]    { forcecopy $f "xx_$f" }
           44  +    set ::state 2
           45  +  }
           46  +  if {$::state==0 && $method=="xTruncate" && [file tail $file]=="test.db-wal"} {
           47  +    set ::state 1
           48  +  }
           49  +}
           50  +
           51  +for {set i 2} {$i<1000} {incr i} {
           52  +
           53  +  # If the WAL file is truncated within the following, within the following
           54  +  # xWrite call the [tvfs_callback] makes a copy of the database and WAL 
           55  +  # files set sets $::state to 2. So that the copied files are in the same
           56  +  # state as the real database and WAL files would be if an application crash 
           57  +  # occurred immediately following the xTruncate().
           58  +  # 
           59  +  set ::state 0
           60  +  do_execsql_test 1.$i.1 {
           61  +    INSERT INTO t1 VALUES(randomblob(10), randomblob(1000));
           62  +  }
           63  +
           64  +  # If a copy was made, open it and run the integrity-check.
           65  +  #
           66  +  if {$::state==2} {
           67  +    sqlite3 db2 xx_test.db
           68  +    do_test 1.$i.2 { execsql { PRAGMA integrity_check  } db2 } "ok"
           69  +    do_test 1.$i.3 { execsql { SELECT count(*) FROM t1 } db2 } [expr $i-1]
           70  +    db2 close
           71  +  }
           72  +}
           73  +catch { db close }
           74  +tvfs delete
           75  +
           76  +#--------------------------------------------------------------------------
           77  +#
           78  +catch { db close }
           79  +forcedelete test.db
           80  +
           81  +do_test 2.1 {
           82  +  sqlite3 db test.db
           83  +  execsql {
           84  +    PRAGMA page_size = 512;
           85  +    PRAGMA journal_mode = WAL;
           86  +    PRAGMA wal_autocheckpoint = 128;
           87  +    CREATE TABLE t1(a PRIMARY KEY, b);
           88  +    INSERT INTO t1 VALUES(randomblob(25), randomblob(200));
           89  +  }
           90  +
           91  +  for {set i 0} {$i < 1500} {incr i} {
           92  +    execsql { INSERT INTO t1 VALUES(randomblob(25), randomblob(200)) }
           93  +  }
           94  +
           95  +  db_save
           96  +  db close
           97  +} {}
           98  +
           99  +set nInitialErr [set_test_counter errors]
          100  +for {set i 2} {$i<10000 && [set_test_counter errors]==$nInitialErr} {incr i} {
          101  +
          102  +  do_test 2.$i.1 {
          103  +    catch { db close } 
          104  +    db_restore
          105  +    crashsql -delay 2 -file test.db-wal -seed $i {
          106  +      SELECT * FROM sqlite_master;
          107  +      PRAGMA synchronous = full;
          108  +      PRAGMA wal_checkpoint;
          109  +      BEGIN;
          110  +        INSERT INTO t1 VALUES(randomblob(26), randomblob(200));
          111  +        INSERT INTO t1 VALUES(randomblob(26), randomblob(200));
          112  +        INSERT INTO t1 VALUES(randomblob(26), randomblob(200));
          113  +        INSERT INTO t1 VALUES(randomblob(26), randomblob(200));
          114  +        INSERT INTO t1 VALUES(randomblob(26), randomblob(200));
          115  +        INSERT INTO t1 VALUES(randomblob(26), randomblob(200));
          116  +        INSERT INTO t1 VALUES(randomblob(26), randomblob(200));
          117  +        INSERT INTO t1 VALUES(randomblob(26), randomblob(200));
          118  +      COMMIT;
          119  +    }
          120  +  } {1 {child process exited abnormally}}
          121  +
          122  +  do_test 2.$i.2 {
          123  +    sqlite3 db test.db
          124  +    execsql { PRAGMA integrity_check } 
          125  +  } {ok}
          126  +}
          127  +
          128  +finish_test
          129  +

Changes to test/walpersist.test.

    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     70   # Make sure the journal_size_limit works to limit the size of the
    71         -# persisted wal file.
           71  +# persisted wal file.  In persistent-wal mode, any non-negative
           72  +# journal_size_limit causes the WAL file to be truncated to zero bytes
           73  +# when closing.
           74  +#
    72     75   forcedelete test.db test.db-shm test.db-wal
    73     76   do_test walpersist-2.1 {
    74     77     sqlite3 db test.db
    75     78     db eval {
    76     79       PRAGMA journal_mode=WAL;
    77     80       PRAGMA wal_autocheckpoint=OFF;
    78     81       PRAGMA journal_size_limit=12000;
................................................................................
    81     84       UPDATE t1 SET x=randomblob(50000);
    82     85     }
    83     86     expr {[file size test.db-wal]>100000}
    84     87   } {1}
    85     88   do_test walpersist-2.2 {
    86     89     file_control_persist_wal db 1
    87     90     db close
    88         -  file size test.db-wal
    89         -} {12000}
           91  +  concat [file exists test.db-wal] [file size test.db-wal]
           92  +} {1 0}
           93  +do_test walpersist-2.3 {
           94  +  sqlite3 db test.db
           95  +  execsql { PRAGMA integrity_check }
           96  +} {ok}
           97  +
           98  +do_test 3.1 {
           99  +  catch {db close}
          100  +  forcedelete test.db test.db-shm test.db-wal
          101  +  sqlite3 db test.db
          102  +  execsql {
          103  +    PRAGMA page_size = 1024;
          104  +    PRAGMA journal_mode = WAL;
          105  +    PRAGMA wal_autocheckpoint=128;
          106  +    PRAGMA journal_size_limit=16384;
          107  +    CREATE TABLE t1(a, b, PRIMARY KEY(a, b));
          108  +  }
          109  +} {wal 128 16384}
          110  +do_test 3.2 {
          111  +  for {set i 0} {$i<200} {incr i} {
          112  +    execsql { INSERT INTO t1 VALUES(randomblob(500), randomblob(500)) }
          113  +  }
          114  +  file_control_persist_wal db 1
          115  +  db close
          116  +} {}
          117  +do_test walpersist-3.3 { 
          118  +  file size test.db-wal 
          119  +} {0}
          120  +do_test walpersist-3.4 { 
          121  +  sqlite3 db test.db
          122  +  execsql { PRAGMA integrity_check }
          123  +} {ok}
          124  + 
    90    125   
    91    126   finish_test

Added test/zerodamage.test.

            1  +# 2011 December 21
            2  +#
            3  +# The author disclaims copyright to this source code.  In place of
            4  +# a legal notice, here is a blessing:
            5  +#
            6  +#    May you do good and not evil.
            7  +#    May you find forgiveness for yourself and forgive others.
            8  +#    May you share freely, never taking more than you give.
            9  +#
           10  +#***********************************************************************
           11  +# 
           12  +# This file implements tests of the SQLITE_IOCAP_POWERSAFE_OVERWRITE property
           13  +# and the SQLITE_FCNTL_POWERSAFE_OVERWRITE file-control for manipulating it.
           14  +#
           15  +# The name of this file comes from the fact that we used to call the
           16  +# POWERSAFE_OVERWRITE property ZERO_DAMAGE.
           17  +#
           18  +
           19  +set testdir [file dirname $argv0]
           20  +source $testdir/tester.tcl
           21  +set testprefix wal5
           22  +
           23  +# POWERSAFE_OVERWRITE defaults to true
           24  +#
           25  +do_test zerodamage-1.0 {
           26  +  file_control_powersafe_overwrite db -1
           27  +} {0 1}
           28  +
           29  +# Check the ability to turn zero-damage on and off.
           30  +#
           31  +do_test zerodamage-1.1 {
           32  +  file_control_powersafe_overwrite db 0
           33  +  file_control_powersafe_overwrite db -1
           34  +} {0 0}
           35  +do_test zerodamage-1.2 {
           36  +  file_control_powersafe_overwrite db 1
           37  +  file_control_powersafe_overwrite db -1
           38  +} {0 1}
           39  +
           40  +# Run a transaction with zero-damage on, a small page size and a much larger
           41  +# sectorsize.  Verify that the maximum journal size is small - that the
           42  +# rollback journal is not being padded.
           43  +#
           44  +do_test zerodamage-2.0 {
           45  +  db close
           46  +  testvfs tv -default 1
           47  +  tv sectorsize 8192
           48  +  sqlite3 db file:test.db?psow=TRUE -uri 1
           49  +  unset -nocomplain ::max_journal_size
           50  +  set ::max_journal_size 0
           51  +  proc xDeleteCallback {method file args} {
           52  +    set sz [file size $file]
           53  +    if {$sz>$::max_journal_size} {set ::max_journal_size $sz}
           54  +  }
           55  +  tv filter xDelete
           56  +  tv script xDeleteCallback
           57  +  register_wholenumber_module db
           58  +  db eval {
           59  +    PRAGMA page_size=1024;
           60  +    PRAGMA journal_mode=DELETE;
           61  +    PRAGMA cache_size=5;
           62  +    CREATE VIRTUAL TABLE nums USING wholenumber;
           63  +    CREATE TABLE t1(x, y);
           64  +    INSERT INTO t1 SELECT value, randomblob(100) FROM nums
           65  +                    WHERE value BETWEEN 1 AND 400;
           66  +  }
           67  +  set ::max_journal_size 0
           68  +  db eval {
           69  +    UPDATE t1 SET y=randomblob(50) WHERE x=123;
           70  +  }
           71  +  concat [file_control_powersafe_overwrite db -1] [set ::max_journal_size]
           72  +} {0 1 2576}
           73  +
           74  +# Repeat the previous step with zero-damage turned off.  This time the
           75  +# maximum rollback journal size should be much larger.
           76  +#
           77  +do_test zerodamage-2.1 {
           78  +  set ::max_journal_size 0
           79  +  db close
           80  +  sqlite3 db file:test.db?psow=FALSE -uri 1
           81  +  db eval {
           82  +    UPDATE t1 SET y=randomblob(50) WHERE x=124;
           83  +  }
           84  +  concat [file_control_powersafe_overwrite db -1] [set ::max_journal_size]
           85  +} {0 0 24704}
           86  +
           87  +# Run a WAL-mode transaction with POWERSAFE_OVERWRITE on to verify that the
           88  +# WAL file does not get too big.
           89  +#
           90  +do_test zerodamage-3.0 {
           91  +  db eval {
           92  +     PRAGMA journal_mode=WAL;
           93  +  }
           94  +  db close
           95  +  sqlite3 db file:test.db?psow=TRUE -uri 1
           96  +  db eval {
           97  +     UPDATE t1 SET y=randomblob(50) WHERE x=124;
           98  +  }
           99  +  file size test.db-wal
          100  +} {1080}
          101  +
          102  +# Repeat the previous with POWERSAFE_OVERWRITE off.  Verify that the WAL file
          103  +# is padded.
          104  +#
          105  +do_test zerodamage-3.1 {
          106  +  db close
          107  +  sqlite3 db file:test.db?psow=FALSE -uri 1
          108  +  db eval {
          109  +     UPDATE t1 SET y=randomblob(50) WHERE x=124;
          110  +  }
          111  +  file size test.db-wal
          112  +} {8416}