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

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

Overview
Comment:Cherry-pick the correct changes out of the recent "mistake" branch while omitting the bugs.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 48bf309391c32e7860c293acd13f3dda14212d39
User & Date: drh 2010-07-03 12:31:35
Original Comment: Cherry-pick the correct changes out of the recent "mistake" branch while omitting the bogus changes.
Context
2010-07-03
13:50
Fix an assert in pager.c. And various test cases that fail with the in-memory journal permutation. check-in: 622378db user: dan tags: trunk
12:31
Cherry-pick the correct changes out of the recent "mistake" branch while omitting the bugs. check-in: 48bf3093 user: drh tags: trunk
12:26
Remove dead code from the pager. check-in: 7cbe175a user: drh tags: mistake
2010-07-02
16:36
Add initializers for the xShmXXX() members to an sqlite3_io_methods structure in journal.c. This doesn't fix any real problem, just prevents a compiler warning. check-in: dafb3577 user: dan tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to ext/fts3/fts3.c.

   603    603     return rc;
   604    604   }
   605    605   
   606    606   /*
   607    607   ** An sqlite3_exec() callback for fts3TableExists.
   608    608   */
   609    609   static int fts3TableExistsCallback(void *pArg, int n, char **pp1, char **pp2){
          610  +  UNUSED_PARAMETER(n);
          611  +  UNUSED_PARAMETER(pp1);
          612  +  UNUSED_PARAMETER(pp2);
   610    613     *(int*)pArg = 1;
   611    614     return 1;
   612    615   }
   613    616   
   614    617   /*
   615    618   ** Determine if a table currently exists in the database.
   616    619   */
................................................................................
   628    631     if( *pRc ) return;
   629    632     zSql = sqlite3_mprintf(
   630    633       "SELECT 1 FROM %Q.sqlite_master WHERE name='%q%s'",
   631    634       zDb, zName, zSuffix
   632    635     );    
   633    636     rc = sqlite3_exec(db, zSql, fts3TableExistsCallback, &res, 0);
   634    637     sqlite3_free(zSql);
   635         -  *pResult = res & 0xff;
          638  +  *pResult = (u8)(res & 0xff);
   636    639     if( rc!=SQLITE_ABORT ) *pRc = rc;
   637    640   }
   638    641   
   639    642   /*
   640    643   ** This function is the implementation of both the xConnect and xCreate
   641    644   ** methods of the FTS3 virtual table.
   642    645   **

Changes to src/btree.c.

  2521   2521   
  2522   2522     /* Any read-only or read-write transaction implies a read-lock on 
  2523   2523     ** page 1. So if some other shared-cache client already has a write-lock 
  2524   2524     ** on page 1, the transaction cannot be opened. */
  2525   2525     rc = querySharedCacheTableLock(p, MASTER_ROOT, READ_LOCK);
  2526   2526     if( SQLITE_OK!=rc ) goto trans_begun;
  2527   2527   
  2528         -  pBt->initiallyEmpty = pBt->nPage==0;
         2528  +  pBt->initiallyEmpty = (u8)(pBt->nPage==0);
  2529   2529     do {
  2530   2530       /* Call lockBtree() until either pBt->pPage1 is populated or
  2531   2531       ** lockBtree() returns something other than SQLITE_OK. lockBtree()
  2532   2532       ** may return SQLITE_OK but leave pBt->pPage1 set to 0 if after
  2533   2533       ** reading page 1 it discovers that the page-size of the database 
  2534   2534       ** file is not pBt->pageSize. In this case lockBtree() will update
  2535   2535       ** pBt->pageSize to the page-size of the file on disk.
................................................................................
  4244   4244     assert( cursorHoldsMutex(pCur) );
  4245   4245     assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
  4246   4246     rc = moveToRoot(pCur);
  4247   4247     if( rc==SQLITE_OK ){
  4248   4248       if( pCur->eState==CURSOR_INVALID ){
  4249   4249         assert( pCur->apPage[pCur->iPage]->nCell==0 );
  4250   4250         *pRes = 1;
  4251         -      rc = SQLITE_OK;
  4252   4251       }else{
  4253   4252         assert( pCur->apPage[pCur->iPage]->nCell>0 );
  4254   4253         *pRes = 0;
  4255   4254         rc = moveToLeftmost(pCur);
  4256   4255       }
  4257   4256     }
  4258   4257     return rc;
................................................................................
  8009   8008    
  8010   8009     assert( pBtree->inTrans==TRANS_NONE );
  8011   8010     assert( iVersion==1 || iVersion==2 );
  8012   8011   
  8013   8012     /* If setting the version fields to 1, do not automatically open the
  8014   8013     ** WAL connection, even if the version fields are currently set to 2.
  8015   8014     */
  8016         -  pBt->doNotUseWAL = (iVersion==1);
         8015  +  pBt->doNotUseWAL = (u8)(iVersion==1);
  8017   8016   
  8018   8017     rc = sqlite3BtreeBeginTrans(pBtree, 0);
  8019   8018     if( rc==SQLITE_OK ){
  8020   8019       u8 *aData = pBt->pPage1->aData;
  8021   8020       if( aData[18]!=(u8)iVersion || aData[19]!=(u8)iVersion ){
  8022   8021         rc = sqlite3BtreeBeginTrans(pBtree, 2);
  8023   8022         if( rc==SQLITE_OK ){

Changes to src/os.c.

    30     30   **     sqlite3OsOpen()
    31     31   **     sqlite3OsRead()
    32     32   **     sqlite3OsWrite()
    33     33   **     sqlite3OsSync()
    34     34   **     sqlite3OsLock()
    35     35   **
    36     36   */
    37         -#if defined(SQLITE_TEST) && (SQLITE_OS_WIN==0)
           37  +#if defined(SQLITE_TEST)
    38     38   int sqlite3_memdebug_vfs_oom_test = 1;
    39     39     #define DO_OS_MALLOC_TEST(x)                                       \
    40     40     if (sqlite3_memdebug_vfs_oom_test && (!x || !sqlite3IsMemJournal(x))) {  \
    41     41       void *pTstAlloc = sqlite3Malloc(10);                             \
    42     42       if (!pTstAlloc) return SQLITE_IOERR_NOMEM;                       \
    43     43       sqlite3_free(pTstAlloc);                                         \
    44     44     }

Changes to src/os_unix.c.

  5063   5063   
  5064   5064     if( lPath[len-1]!='/' ){
  5065   5065       len = strlcat(lPath, "/", maxLen);
  5066   5066     }
  5067   5067     
  5068   5068     /* transform the db path to a unique cache name */
  5069   5069     dbLen = (int)strlen(dbPath);
  5070         -  for( i=0; i<dbLen && (i+len+7)<maxLen; i++){
         5070  +  for( i=0; i<dbLen && (i+len+7)<(int)maxLen; i++){
  5071   5071       char c = dbPath[i];
  5072   5072       lPath[i+len] = (c=='/')?'_':c;
  5073   5073     }
  5074   5074     lPath[i+len]='\0';
  5075   5075     strlcat(lPath, ":auto:", maxLen);
  5076   5076     OSTRACE(("GETLOCKPATH  proxy lock path=%s pid=%d\n", lPath, getpid()));
  5077   5077     return SQLITE_OK;
................................................................................
  5204   5204   #ifdef SQLITE_TEST
  5205   5205   /* simulate multiple hosts by creating unique hostid file paths */
  5206   5206   int sqlite3_hostid_num = 0;
  5207   5207   #endif
  5208   5208   
  5209   5209   #define PROXY_HOSTIDLEN    16  /* conch file host id length */
  5210   5210   
         5211  +/* Not always defined in the headers as it ought to be */
         5212  +extern int gethostuuid(uuid_t id, const struct timespec *wait);
         5213  +
  5211   5214   /* get the host ID via gethostuuid(), pHostID must point to PROXY_HOSTIDLEN 
  5212   5215   ** bytes of writable memory.
  5213   5216   */
  5214   5217   static int proxyGetHostID(unsigned char *pHostID, int *pError){
  5215   5218     struct timespec timeout = {1, 0}; /* 1 sec timeout */
  5216   5219     
  5217   5220     assert(PROXY_HOSTIDLEN == sizeof(uuid_t));
................................................................................
  5253   5256     char buf[PROXY_MAXCONCHLEN];
  5254   5257     char *cPath = pCtx->conchFilePath;
  5255   5258     size_t readLen = 0;
  5256   5259     size_t pathLen = 0;
  5257   5260     char errmsg[64] = "";
  5258   5261     int fd = -1;
  5259   5262     int rc = -1;
         5263  +  UNUSED_PARAMETER(myHostID);
  5260   5264   
  5261   5265     /* create a new path by replace the trailing '-conch' with '-break' */
  5262   5266     pathLen = strlcpy(tPath, cPath, MAXPATHLEN);
  5263   5267     if( pathLen>MAXPATHLEN || pathLen<6 || 
  5264   5268        (strlcpy(&tPath[pathLen-5], "break", 6) != 5) ){
  5265   5269       sprintf(errmsg, "path error (len %d)", (int)pathLen);
  5266   5270       goto end_breaklock;
................................................................................
  5273   5277     }
  5274   5278     /* write it out to the temporary break file */
  5275   5279     fd = open(tPath, (O_RDWR|O_CREAT|O_EXCL), SQLITE_DEFAULT_FILE_PERMISSIONS);
  5276   5280     if( fd<0 ){
  5277   5281       sprintf(errmsg, "create failed (%d)", errno);
  5278   5282       goto end_breaklock;
  5279   5283     }
  5280         -  if( pwrite(fd, buf, readLen, 0) != readLen ){
         5284  +  if( pwrite(fd, buf, readLen, 0) != (ssize_t)readLen ){
  5281   5285       sprintf(errmsg, "write failed (%d)", errno);
  5282   5286       goto end_breaklock;
  5283   5287     }
  5284   5288     if( rename(tPath, cPath) ){
  5285   5289       sprintf(errmsg, "rename failed (%d)", errno);
  5286   5290       goto end_breaklock;
  5287   5291     }

Changes to src/os_win.c.

  1427   1427       }
  1428   1428   
  1429   1429       /* Check to see if another process is holding the dead-man switch.
  1430   1430       ** If not, truncate the file to zero length. 
  1431   1431       */
  1432   1432       if( winShmSystemLock(pShmNode, _SHM_WRLCK, WIN_SHM_DMS, 1)==SQLITE_OK ){
  1433   1433         rc = winTruncate((sqlite3_file *)&pShmNode->hFile, 0);
         1434  +      if( rc!=SQLITE_OK ){
         1435  +        rc = SQLITE_IOERR_SHMOPEN;
         1436  +      }
  1434   1437       }
  1435   1438       if( rc==SQLITE_OK ){
  1436   1439         winShmSystemLock(pShmNode, _SHM_UNLCK, WIN_SHM_DMS, 1);
  1437   1440         rc = winShmSystemLock(pShmNode, _SHM_RDLCK, WIN_SHM_DMS, 1);
  1438   1441       }
  1439   1442       if( rc ) goto shm_open_err;
  1440   1443     }
................................................................................
  1653   1656   **
  1654   1657   ** All loads and stores begun before the barrier must complete before
  1655   1658   ** any load or store begun after the barrier.
  1656   1659   */
  1657   1660   static void winShmBarrier(
  1658   1661     sqlite3_file *fd          /* Database holding the shared memory */
  1659   1662   ){
         1663  +  UNUSED_PARAMETER(fd);
  1660   1664     /* MemoryBarrier(); // does not work -- do not know why not */
  1661   1665     winShmEnterMutex();
  1662   1666     winShmLeaveMutex();
  1663   1667   }
  1664   1668   
  1665   1669   #else
  1666   1670   # define winShmOpen    0

Changes to src/pager.c.

  2848   2848   int sqlite3PagerMaxPageCount(Pager *pPager, int mxPage){
  2849   2849     int nPage;
  2850   2850     if( mxPage>0 ){
  2851   2851       pPager->mxPgno = mxPage;
  2852   2852     }
  2853   2853     if( pPager->state!=PAGER_UNLOCK ){
  2854   2854       sqlite3PagerPagecount(pPager, &nPage);
  2855         -    assert( pPager->mxPgno>=nPage );
         2855  +    assert( (int)pPager->mxPgno>=nPage );
  2856   2856     }
  2857   2857     return pPager->mxPgno;
  2858   2858   }
  2859   2859   
  2860   2860   /*
  2861   2861   ** The following set of routines are used to disable the simulated
  2862   2862   ** I/O error mechanism.  These routines are used to avoid simulated
................................................................................
  5645   5645     return pPager->noSync;
  5646   5646   }
  5647   5647   
  5648   5648   #ifdef SQLITE_HAS_CODEC
  5649   5649   /*
  5650   5650   ** Set or retrieve the codec for this pager
  5651   5651   */
  5652         -static void sqlite3PagerSetCodec(
         5652  +void sqlite3PagerSetCodec(
  5653   5653     Pager *pPager,
  5654   5654     void *(*xCodec)(void*,void*,Pgno,int),
  5655   5655     void (*xCodecSizeChng)(void*,int,int),
  5656   5656     void (*xCodecFree)(void*),
  5657   5657     void *pCodec
  5658   5658   ){
  5659   5659     if( pPager->xCodecFree ) pPager->xCodecFree(pPager->pCodec);
  5660   5660     pPager->xCodec = pPager->memDb ? 0 : xCodec;
  5661   5661     pPager->xCodecSizeChng = xCodecSizeChng;
  5662   5662     pPager->xCodecFree = xCodecFree;
  5663   5663     pPager->pCodec = pCodec;
  5664   5664     pagerReportSize(pPager);
  5665   5665   }
  5666         -static void *sqlite3PagerGetCodec(Pager *pPager){
         5666  +void *sqlite3PagerGetCodec(Pager *pPager){
  5667   5667     return pPager->pCodec;
  5668   5668   }
  5669   5669   #endif
  5670   5670   
  5671   5671   #ifndef SQLITE_OMIT_AUTOVACUUM
  5672   5672   /*
  5673   5673   ** Move the page pPg to location pgno in the file.
................................................................................
  6040   6040   */
  6041   6041   int sqlite3PagerWalSupported(Pager *pPager){
  6042   6042     const sqlite3_io_methods *pMethods = pPager->fd->pMethods;
  6043   6043     return pMethods->iVersion>=2 && pMethods->xShmOpen!=0;
  6044   6044   }
  6045   6045   
  6046   6046   /*
  6047         -** Open a connection to the write-ahead log file for pager pPager. If
  6048         -** the log connection is already open, this function is a no-op.
  6049         -**
  6050   6047   ** The caller must be holding a SHARED lock on the database file to call
  6051   6048   ** this function.
         6049  +**
         6050  +** If the pager passed as the first argument is open on a real database
         6051  +** file (not a temp file or an in-memory database), and the WAL file
         6052  +** is not already open, make an attempt to open it now. If successful,
         6053  +** return SQLITE_OK. If an error occurs or the VFS used by the pager does 
         6054  +** not support the xShmXXX() methods, return an error code. *pisOpen is
         6055  +** not modified in either case.
         6056  +**
         6057  +** If the pager is open on a temp-file (or in-memory database), or if
         6058  +** the WAL file is already open, set *pisOpen to 1 and return SQLITE_OK
         6059  +** without doing anything.
  6052   6060   */
  6053         -int sqlite3PagerOpenWal(Pager *pPager, int *pisOpen){
         6061  +int sqlite3PagerOpenWal(
         6062  +  Pager *pPager,                  /* Pager object */
         6063  +  int *pisOpen                    /* OUT: Set to true if call is a no-op */
         6064  +){
  6054   6065     int rc = SQLITE_OK;             /* Return code */
  6055   6066   
  6056   6067     assert( pPager->state>=PAGER_SHARED );
  6057         -  if( !pPager->pWal ){
         6068  +  assert( (pisOpen==0 && !pPager->tempFile && !pPager->pWal) || *pisOpen==0 );
         6069  +
         6070  +  if( !pPager->tempFile && !pPager->pWal ){
  6058   6071       if( !sqlite3PagerWalSupported(pPager) ) return SQLITE_CANTOPEN;
  6059   6072   
  6060   6073       /* Open the connection to the log file. If this operation fails, 
  6061   6074       ** (e.g. due to malloc() failure), unlock the database file and 
  6062   6075       ** return an error code.
  6063   6076       */
  6064   6077       rc = sqlite3WalOpen(pPager->pVfs, pPager->fd,

Changes to src/test_vfs.c.

   906    906       );
   907    907       tvfsResultCode(p, &rc);
   908    908     }
   909    909   
   910    910     for(ppFd=&pBuffer->pFile; *ppFd!=pFd; ppFd=&((*ppFd)->pNext));
   911    911     assert( (*ppFd)==pFd );
   912    912     *ppFd = pFd->pNext;
          913  +  pFd->pNext = 0;
   913    914   
   914    915     if( pBuffer->pFile==0 ){
   915    916       int i;
   916    917       TestvfsBuffer **pp;
   917    918       for(pp=&p->pBuffer; *pp!=pBuffer; pp=&((*pp)->pNext));
   918    919       *pp = (*pp)->pNext;
   919    920       for(i=0; pBuffer->aPage[i]; i++){

Changes to src/vdbe.c.

  4134   4134     VdbeCursor *pC;
  4135   4135     BtCursor *pCrsr;
  4136   4136     int res;
  4137   4137   
  4138   4138     assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  4139   4139     pC = p->apCsr[pOp->p1];
  4140   4140     assert( pC!=0 );
         4141  +  res = 1;
  4141   4142     if( (pCrsr = pC->pCursor)!=0 ){
  4142   4143       rc = sqlite3BtreeFirst(pCrsr, &res);
  4143   4144       pC->atFirst = res==0 ?1:0;
  4144   4145       pC->deferredMoveto = 0;
  4145   4146       pC->cacheStatus = CACHE_STALE;
  4146   4147       pC->rowidIsValid = 0;
  4147         -  }else{
  4148         -    res = 1;
  4149   4148     }
  4150   4149     pC->nullRow = (u8)res;
  4151   4150     assert( pOp->p2>0 && pOp->p2<p->nOp );
  4152   4151     if( res ){
  4153   4152       pc = pOp->p2 - 1;
  4154   4153     }
  4155   4154     break;
................................................................................
  5151   5150   */
  5152   5151   case OP_Checkpoint: {
  5153   5152     rc = sqlite3Checkpoint(db, pOp->p1);
  5154   5153     break;
  5155   5154   };  
  5156   5155   #endif
  5157   5156   
         5157  +#ifndef SQLITE_OMIT_PRAGMA
  5158   5158   /* Opcode: JournalMode P1 P2 P3 * P5
  5159   5159   **
  5160   5160   ** Change the journal mode of database P1 to P3. P3 must be one of the
  5161   5161   ** PAGER_JOURNALMODE_XXX values. If changing between the various rollback
  5162   5162   ** modes (delete, truncate, persist, off and memory), this is a simple
  5163   5163   ** operation. No IO is required.
  5164   5164   **
................................................................................
  5275   5275     pOut = &aMem[pOp->p2];
  5276   5276     pOut->flags = MEM_Str|MEM_Static|MEM_Term;
  5277   5277     pOut->z = (char *)sqlite3JournalModename(eNew);
  5278   5278     pOut->n = sqlite3Strlen30(pOut->z);
  5279   5279     pOut->enc = SQLITE_UTF8;
  5280   5280     sqlite3VdbeChangeEncoding(pOut, encoding);
  5281   5281     break;
  5282         -};  
         5282  +};
         5283  +#endif /* SQLITE_OMIT_PRAGMA */
  5283   5284   
  5284   5285   #if !defined(SQLITE_OMIT_VACUUM) && !defined(SQLITE_OMIT_ATTACH)
  5285   5286   /* Opcode: Vacuum * * * * *
  5286   5287   **
  5287   5288   ** Vacuum the entire database.  This opcode will cause other virtual
  5288   5289   ** machines to be created and run.  It may not be called from within
  5289   5290   ** a transaction.

Changes to src/vdbeaux.c.

   826    826   ** an OP_Trace instruction is always inserted by sqlite3VdbeGet() as soon as
   827    827   ** a new VDBE is created.  So we are free to set addr to p->nOp-1 without
   828    828   ** having to double-check to make sure that the result is non-negative. But
   829    829   ** if SQLITE_OMIT_TRACE is defined, the OP_Trace is omitted and we do need to
   830    830   ** check the value of p->nOp-1 before continuing.
   831    831   */
   832    832   VdbeOp *sqlite3VdbeGetOp(Vdbe *p, int addr){
   833         -  static const VdbeOp dummy;
          833  +  /* C89 specifies that the constant "dummy" will be initialized to all
          834  +  ** zeros, which is correct.  MSVC generates a warning, nevertheless. */
          835  +  static const VdbeOp dummy;  /* Ignore the MSVC warning about no initializer */
   834    836     assert( p->magic==VDBE_MAGIC_INIT );
   835    837     if( addr<0 ){
   836    838   #ifdef SQLITE_OMIT_TRACE
   837    839       if( p->nOp==0 ) return (VdbeOp*)&dummy;
   838    840   #endif
   839    841       addr = p->nOp - 1;
   840    842     }

Changes to src/wal.c.

   493    493   static int walIndexPage(Wal *pWal, int iPage, volatile u32 **ppPage){
   494    494     int rc = SQLITE_OK;
   495    495   
   496    496     /* Enlarge the pWal->apWiData[] array if required */
   497    497     if( pWal->nWiData<=iPage ){
   498    498       int nByte = sizeof(u32 *)*(iPage+1);
   499    499       volatile u32 **apNew;
   500         -    apNew = (volatile u32 **)sqlite3_realloc(pWal->apWiData, nByte);
          500  +    apNew = (volatile u32 **)sqlite3_realloc((void *)pWal->apWiData, nByte);
   501    501       if( !apNew ){
   502    502         *ppPage = 0;
   503    503         return SQLITE_NOMEM;
   504    504       }
   505         -    memset(&apNew[pWal->nWiData], 0, sizeof(u32 *)*(iPage+1-pWal->nWiData));
          505  +    memset((void *)&apNew[pWal->nWiData], 0, sizeof(u32 *)*(iPage+1-pWal->nWiData));
   506    506       pWal->apWiData = apNew;
   507    507       pWal->nWiData = iPage+1;
   508    508     }
   509    509   
   510    510     /* Request a pointer to the required page from the VFS */
   511    511     if( pWal->apWiData[iPage]==0 ){
   512    512       rc = sqlite3OsShmMap(pWal->pDbFd, iPage, WALINDEX_PGSZ, 
................................................................................
   733    733   static int walLockShared(Wal *pWal, int lockIdx){
   734    734     int rc;
   735    735     if( pWal->exclusiveMode ) return SQLITE_OK;
   736    736     rc = sqlite3OsShmLock(pWal->pDbFd, lockIdx, 1,
   737    737                           SQLITE_SHM_LOCK | SQLITE_SHM_SHARED);
   738    738     WALTRACE(("WAL%p: acquire SHARED-%s %s\n", pWal,
   739    739               walLockName(lockIdx), rc ? "failed" : "ok"));
   740         -  VVA_ONLY( pWal->lockError = (rc!=SQLITE_OK && rc!=SQLITE_BUSY); )
          740  +  VVA_ONLY( pWal->lockError = (u8)(rc!=SQLITE_OK && rc!=SQLITE_BUSY); )
   741    741     return rc;
   742    742   }
   743    743   static void walUnlockShared(Wal *pWal, int lockIdx){
   744    744     if( pWal->exclusiveMode ) return;
   745    745     (void)sqlite3OsShmLock(pWal->pDbFd, lockIdx, 1,
   746    746                            SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED);
   747    747     WALTRACE(("WAL%p: release SHARED-%s\n", pWal, walLockName(lockIdx)));
................................................................................
   749    749   static int walLockExclusive(Wal *pWal, int lockIdx, int n){
   750    750     int rc;
   751    751     if( pWal->exclusiveMode ) return SQLITE_OK;
   752    752     rc = sqlite3OsShmLock(pWal->pDbFd, lockIdx, n,
   753    753                           SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE);
   754    754     WALTRACE(("WAL%p: acquire EXCLUSIVE-%s cnt=%d %s\n", pWal,
   755    755               walLockName(lockIdx), n, rc ? "failed" : "ok"));
   756         -  VVA_ONLY( pWal->lockError = (rc!=SQLITE_OK && rc!=SQLITE_BUSY); )
          756  +  VVA_ONLY( pWal->lockError = (u8)(rc!=SQLITE_OK && rc!=SQLITE_BUSY); )
   757    757     return rc;
   758    758   }
   759    759   static void walUnlockExclusive(Wal *pWal, int lockIdx, int n){
   760    760     if( pWal->exclusiveMode ) return;
   761    761     (void)sqlite3OsShmLock(pWal->pDbFd, lockIdx, n,
   762    762                            SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE);
   763    763     WALTRACE(("WAL%p: release EXCLUSIVE-%s cnt=%d\n", pWal,
................................................................................
   897    897         aHash[i] = 0;
   898    898       }
   899    899     }
   900    900     
   901    901     /* Zero the entries in the aPgno array that correspond to frames with
   902    902     ** frame numbers greater than pWal->hdr.mxFrame. 
   903    903     */
   904         -  nByte = ((char *)aHash - (char *)&aPgno[iLimit+1]);
          904  +  nByte = (int)((char *)aHash - (char *)&aPgno[iLimit+1]);
   905    905     memset((void *)&aPgno[iLimit+1], 0, nByte);
   906    906   
   907    907   #ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT
   908    908     /* Verify that the every entry in the mapping region is still reachable
   909    909     ** via the hash table even after the cleanup.
   910    910     */
   911    911     if( iLimit ){
................................................................................
   945    945       idx = iFrame - iZero;
   946    946       assert( idx <= HASHTABLE_NSLOT/2 + 1 );
   947    947       
   948    948       /* If this is the first entry to be added to this hash-table, zero the
   949    949       ** entire hash table and aPgno[] array before proceding. 
   950    950       */
   951    951       if( idx==1 ){
   952         -      int nByte = (u8 *)&aHash[HASHTABLE_NSLOT] - (u8 *)&aPgno[1];
          952  +      int nByte = (int)((u8 *)&aHash[HASHTABLE_NSLOT] - (u8 *)&aPgno[1]);
   953    953         memset((void*)&aPgno[1], 0, nByte);
   954    954       }
   955    955   
   956    956       /* If the entry in aPgno[] is already set, then the previous writer
   957    957       ** must have exited unexpectedly in the middle of a transaction (after
   958    958       ** writing one or more dirty pages to the WAL to free up memory). 
   959    959       ** Remove the remnants of that writers uncommitted transaction from 
................................................................................
   965    965       }
   966    966   
   967    967       /* Write the aPgno[] array entry and the hash-table slot. */
   968    968       for(iKey=walHash(iPage); aHash[iKey]; iKey=walNextHash(iKey)){
   969    969         assert( nCollide++ < idx );
   970    970       }
   971    971       aPgno[idx] = iPage;
   972         -    aHash[iKey] = idx;
          972  +    aHash[iKey] = (ht_slot)idx;
   973    973   
   974    974   #ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT
   975    975       /* Verify that the number of entries in the hash table exactly equals
   976    976       ** the number of entries in the mapping region.
   977    977       */
   978    978       {
   979    979         int i;           /* Loop counter */
................................................................................
  1073   1073       if( (magic&0xFFFFFFFE)!=WAL_MAGIC 
  1074   1074        || szPage&(szPage-1) 
  1075   1075        || szPage>SQLITE_MAX_PAGE_SIZE 
  1076   1076        || szPage<512 
  1077   1077       ){
  1078   1078         goto finished;
  1079   1079       }
  1080         -    pWal->hdr.bigEndCksum = (magic&0x00000001);
  1081         -    pWal->szPage = szPage;
         1080  +    pWal->hdr.bigEndCksum = (u8)(magic&0x00000001);
         1081  +    pWal->szPage = (u16)szPage;
  1082   1082       pWal->nCkpt = sqlite3Get4byte(&aBuf[12]);
  1083   1083       memcpy(&pWal->hdr.aSalt, &aBuf[16], 8);
  1084   1084   
  1085   1085       /* Verify that the WAL header checksum is correct */
  1086   1086       walChecksumBytes(pWal->hdr.bigEndCksum==SQLITE_BIGENDIAN, 
  1087   1087           aBuf, WAL_HDRSIZE-2*4, 0, pWal->hdr.aFrameCksum
  1088   1088       );
................................................................................
  1124   1124         rc = walIndexAppend(pWal, ++iFrame, pgno);
  1125   1125         if( rc!=SQLITE_OK ) break;
  1126   1126   
  1127   1127         /* If nTruncate is non-zero, this is a commit record. */
  1128   1128         if( nTruncate ){
  1129   1129           pWal->hdr.mxFrame = iFrame;
  1130   1130           pWal->hdr.nPage = nTruncate;
  1131         -        pWal->hdr.szPage = szPage;
         1131  +        pWal->hdr.szPage = (u16)szPage;
  1132   1132           aFrameCksum[0] = pWal->hdr.aFrameCksum[0];
  1133   1133           aFrameCksum[1] = pWal->hdr.aFrameCksum[1];
  1134   1134         }
  1135   1135       }
  1136   1136   
  1137   1137       sqlite3_free(aFrame);
  1138   1138     }
................................................................................
  1452   1452       rc = walHashGet(pWal, i, &aHash, &aPgno, &iZero);
  1453   1453       if( rc==SQLITE_OK ){
  1454   1454         int j;                      /* Counter variable */
  1455   1455         int nEntry;                 /* Number of entries in this segment */
  1456   1456         ht_slot *aIndex;            /* Sorted index for this segment */
  1457   1457   
  1458   1458         aPgno++;
  1459         -      nEntry = ((i+1)==nSegment)?(int)(iLast-iZero):(u32 *)aHash-(u32 *)aPgno;
         1459  +      nEntry = (int)(((i+1)==nSegment)?(int)(iLast-iZero):(u32 *)aHash-(u32 *)aPgno);
  1460   1460         aIndex = &((ht_slot *)&p->aSegment[p->nSegment])[iZero];
  1461   1461         iZero++;
  1462   1462     
  1463   1463         for(j=0; j<nEntry; j++){
  1464         -        aIndex[j] = j;
         1464  +        aIndex[j] = (ht_slot)j;
  1465   1465         }
  1466   1466         walMergesort((u32 *)aPgno, aTmp, aIndex, &nEntry);
  1467   1467         p->aSegment[i].iZero = iZero;
  1468   1468         p->aSegment[i].nEntry = nEntry;
  1469   1469         p->aSegment[i].aIndex = aIndex;
  1470   1470         p->aSegment[i].aPgno = (u32 *)aPgno;
  1471   1471       }
................................................................................
  1644   1644   
  1645   1645       walIndexClose(pWal, isDelete);
  1646   1646       sqlite3OsClose(pWal->pWalFd);
  1647   1647       if( isDelete ){
  1648   1648         sqlite3OsDelete(pWal->pVfs, pWal->zWalName, 0);
  1649   1649       }
  1650   1650       WALTRACE(("WAL%p: closed\n", pWal));
  1651         -    sqlite3_free(pWal->apWiData);
         1651  +    sqlite3_free((void *)pWal->apWiData);
  1652   1652       sqlite3_free(pWal);
  1653   1653     }
  1654   1654     return rc;
  1655   1655   }
  1656   1656   
  1657   1657   /*
  1658   1658   ** Try to read the wal-index header.  Return 0 on success and 1 if
................................................................................
  1980   1980       if( pInfo->aReadMark[mxI]!=mxReadMark
  1981   1981        || memcmp((void *)walIndexHdr(pWal), &pWal->hdr, sizeof(WalIndexHdr))
  1982   1982       ){
  1983   1983         walUnlockShared(pWal, WAL_READ_LOCK(mxI));
  1984   1984         return WAL_RETRY;
  1985   1985       }else{
  1986   1986         assert( mxReadMark<=pWal->hdr.mxFrame );
  1987         -      pWal->readLock = mxI;
         1987  +      pWal->readLock = (i16)mxI;
  1988   1988       }
  1989   1989     }
  1990   1990     return rc;
  1991   1991   }
  1992   1992   
  1993   1993   /*
  1994   1994   ** Begin a read transaction on the database.
................................................................................
  2393   2393       sqlite3Put4byte(&aWalHdr[8], szPage);
  2394   2394       sqlite3Put4byte(&aWalHdr[12], pWal->nCkpt);
  2395   2395       memcpy(&aWalHdr[16], pWal->hdr.aSalt, 8);
  2396   2396       walChecksumBytes(1, aWalHdr, WAL_HDRSIZE-2*4, 0, aCksum);
  2397   2397       sqlite3Put4byte(&aWalHdr[24], aCksum[0]);
  2398   2398       sqlite3Put4byte(&aWalHdr[28], aCksum[1]);
  2399   2399       
  2400         -    pWal->szPage = szPage;
         2400  +    pWal->szPage = (u16)szPage;
  2401   2401       pWal->hdr.bigEndCksum = SQLITE_BIGENDIAN;
  2402   2402       pWal->hdr.aFrameCksum[0] = aCksum[0];
  2403   2403       pWal->hdr.aFrameCksum[1] = aCksum[1];
  2404   2404   
  2405   2405       rc = sqlite3OsWrite(pWal->pWalFd, aWalHdr, sizeof(aWalHdr), 0);
  2406   2406       WALTRACE(("WAL%p: wal-header write %s\n", pWal, rc ? "failed" : "ok"));
  2407   2407       if( rc!=SQLITE_OK ){
................................................................................
  2487   2487       iFrame++;
  2488   2488       nLast--;
  2489   2489       rc = walIndexAppend(pWal, iFrame, pLast->pgno);
  2490   2490     }
  2491   2491   
  2492   2492     if( rc==SQLITE_OK ){
  2493   2493       /* Update the private copy of the header. */
  2494         -    pWal->hdr.szPage = szPage;
         2494  +    pWal->hdr.szPage = (u16)szPage;
  2495   2495       pWal->hdr.mxFrame = iFrame;
  2496   2496       if( isCommit ){
  2497   2497         pWal->hdr.iChange++;
  2498   2498         pWal->hdr.nPage = nTruncate;
  2499   2499       }
  2500   2500       /* If this is a commit, update the wal-index header too. */
  2501   2501       if( isCommit ){

Changes to src/where.c.

  1837   1837           pIdx->aiColumn[n] = pTerm->u.leftColumn;
  1838   1838           pColl = sqlite3BinaryCompareCollSeq(pParse, pX->pLeft, pX->pRight);
  1839   1839           pIdx->azColl[n] = pColl->zName;
  1840   1840           n++;
  1841   1841         }
  1842   1842       }
  1843   1843     }
  1844         -  assert( n==pLevel->plan.nEq );
         1844  +  assert( (u32)n==pLevel->plan.nEq );
  1845   1845   
  1846   1846     /* Add additional columns needed to make the automatic index into
  1847   1847     ** a covering index */
  1848   1848     for(i=0; i<mxBitCol; i++){
  1849   1849       if( extraCols & (((Bitmask)1)<<i) ){
  1850   1850         pIdx->aiColumn[n] = i;
  1851   1851         pIdx->azColl[n] = "BINARY";
................................................................................
  3431   3431       zEndAff = sqlite3DbStrDup(pParse->db, zStartAff);
  3432   3432       addrNxt = pLevel->addrNxt;
  3433   3433   
  3434   3434       /* If we are doing a reverse order scan on an ascending index, or
  3435   3435       ** a forward order scan on a descending index, interchange the 
  3436   3436       ** start and end terms (pRangeStart and pRangeEnd).
  3437   3437       */
  3438         -    if( bRev==(pIdx->aSortOrder[nEq]==SQLITE_SO_ASC) ){
         3438  +    if( nEq<pIdx->nColumn && bRev==(pIdx->aSortOrder[nEq]==SQLITE_SO_ASC) ){
  3439   3439         SWAP(WhereTerm *, pRangeEnd, pRangeStart);
  3440   3440       }
  3441   3441   
  3442   3442       testcase( pRangeStart && pRangeStart->eOperator & WO_LE );
  3443   3443       testcase( pRangeStart && pRangeStart->eOperator & WO_GE );
  3444   3444       testcase( pRangeEnd && pRangeEnd->eOperator & WO_LE );
  3445   3445       testcase( pRangeEnd && pRangeEnd->eOperator & WO_GE );

Changes to test/malloc.test.

   330    330   
   331    331   if {$tcl_platform(platform)!="windows"} {
   332    332     do_malloc_test 14 -tclprep {
   333    333       catch {db close}
   334    334       sqlite3 db2 test2.db
   335    335       sqlite3_extended_result_codes db2 1
   336    336       db2 eval {
          337  +      PRAGMA journal_mode = DELETE;    /* For inmemory_journal permutation */
   337    338         PRAGMA synchronous = 0;
   338    339         CREATE TABLE t1(a, b);
   339    340         INSERT INTO t1 VALUES(1, 2);
   340    341         BEGIN;
   341    342         INSERT INTO t1 VALUES(3, 4);
   342    343       }
   343    344       copy_file test2.db test.db

Changes to test/notify3.test.

    10     10   #***********************************************************************
    11     11   # This file implements regression tests for SQLite library.  The
    12     12   # focus of this file is testing the sqlite3_unlock_notify() API.
    13     13   #
    14     14   
    15     15   set testdir [file dirname $argv0]
    16     16   source $testdir/tester.tcl
           17  +
           18  +# This script only runs if shared-cache and unlock-notify are available.
           19  +#
           20  +ifcapable !unlock_notify||!shared_cache { 
           21  +  finish_test 
           22  +  return 
           23  +}
    17     24   
    18     25   set esc [sqlite3_enable_shared_cache 1]
    19     26   
    20     27   sqlite3 db  test.db
    21     28   file delete -force test.db2 test.db2-journal test.db2-wal
    22     29   sqlite3 db2 test.db2
    23     30   

Changes to test/pager1.test.

  1011   1011   
  1012   1012   #-------------------------------------------------------------------------
  1013   1013   # The following tests work with "PRAGMA max_page_count"
  1014   1014   #
  1015   1015   do_test pager1-6.1 {
  1016   1016     faultsim_delete_and_reopen
  1017   1017     execsql {
         1018  +    PRAGMA auto_vacuum = none;
  1018   1019       PRAGMA max_page_count = 10;
  1019   1020       CREATE TABLE t2(a, b);
  1020   1021       CREATE TABLE t3(a, b);
  1021   1022       CREATE TABLE t4(a, b);
  1022   1023       CREATE TABLE t5(a, b);
  1023   1024       CREATE TABLE t6(a, b);
  1024   1025       CREATE TABLE t7(a, b);
................................................................................
  1353   1354   }
  1354   1355   db close
  1355   1356   
  1356   1357   tv sectorsize 4096
  1357   1358   do_test pager1.10.x.1 {
  1358   1359     faultsim_delete_and_reopen
  1359   1360     execsql {
         1361  +    PRAGMA auto_vacuum = none;
  1360   1362       PRAGMA page_size = 1024;
  1361   1363       CREATE TABLE t1(x);
  1362   1364     }
  1363   1365     for {set i 0} {$i<30} {incr i} {
  1364   1366       execsql { INSERT INTO t1 VALUES(zeroblob(900)) }
  1365   1367     }
  1366   1368     file size test.db
................................................................................
  1425   1427   do_execsql_test pager1-11.5 { SELECT count(*) FROM zz } {32}
  1426   1428   db close
  1427   1429   tv delete
  1428   1430     
  1429   1431   #-------------------------------------------------------------------------
  1430   1432   # Test "PRAGMA page_size"
  1431   1433   #
         1434  +testvfs tv -default 1
         1435  +tv sectorsize 1024
  1432   1436   foreach pagesize {
  1433   1437       512   1024   2048 4096 8192 16384 32768 
  1434   1438   } {
  1435   1439     faultsim_delete_and_reopen
         1440  +
         1441  +  # The sector-size (according to the VFS) is 1024 bytes. So if the
         1442  +  # page-size requested using "PRAGMA page_size" is greater than the
         1443  +  # compile time value of SQLITE_MAX_PAGE_SIZE, then the effective 
         1444  +  # page-size remains 1024 bytes.
         1445  +  #
         1446  +  set eff $pagesize
         1447  +  if {$eff > $::SQLITE_MAX_PAGE_SIZE} { set eff 1024 }
  1436   1448   
  1437   1449     do_test pager1-12.$pagesize.1 {
  1438   1450       sqlite3 db2 test.db
  1439   1451       execsql "
  1440   1452         PRAGMA page_size = $pagesize;
  1441   1453         CREATE VIEW v AS SELECT * FROM sqlite_master;
  1442   1454       " db2
  1443   1455       file size test.db
  1444         -  } $pagesize
         1456  +  } $eff
  1445   1457     do_test pager1-12.$pagesize.2 {
  1446   1458       sqlite3 db2 test.db
  1447   1459       execsql { 
  1448   1460         SELECT count(*) FROM v;
  1449   1461         PRAGMA main.page_size;
  1450   1462       } db2
  1451         -  } [list 1 $pagesize]
         1463  +  } [list 1 $eff]
  1452   1464     do_test pager1-12.$pagesize.3 {
  1453   1465       execsql { 
  1454   1466         SELECT count(*) FROM v;
  1455   1467         PRAGMA main.page_size;
  1456   1468       }
  1457         -  } [list 1 $pagesize]
         1469  +  } [list 1 $eff]
  1458   1470     db2 close
  1459   1471   }
         1472  +db close
         1473  +tv delete
  1460   1474   
  1461   1475   #-------------------------------------------------------------------------
  1462   1476   # Test specal "PRAGMA journal_mode=PERSIST" test cases.
  1463   1477   #
  1464   1478   # pager1-13.1.*: This tests a special case encountered in persistent 
  1465   1479   #                journal mode: If the journal associated with a transaction
  1466   1480   #                is smaller than the journal file (because a previous 

Changes to test/pagerfault.test.

   237    237       BEGIN;
   238    238         INSERT INTO t1 SELECT a_string(200), a_string(300) FROM t1;
   239    239         CREATE TABLE aux.t2 AS SELECT * FROM t1;
   240    240       COMMIT;
   241    241     }
   242    242   } -test {
   243    243     faultsim_test_result {0 {}}
          244  +
          245  +  catchsql { COMMIT }
          246  +  catchsql { ROLLBACK }
          247  +
   244    248     faultsim_integrity_check
   245         -
   246    249     set res ""
   247    250     set rc [catch { set res [db one { PRAGMA aux.integrity_check }] }]
   248    251     if {$rc!=0 || $res != "ok"} {error "integrity-check problem:$rc $res"}
   249    252   }
   250    253   
   251    254   #-------------------------------------------------------------------------
   252    255   # Test fault-injection as part of a commit when using 

Changes to test/pagerfault2.test.

    32     32   }
    33     33   db func a_string a_string
    34     34   
    35     35   do_test pagerfault2-1-pre1 {
    36     36     faultsim_delete_and_reopen
    37     37     db func a_string a_string
    38     38     execsql {
           39  +    PRAGMA auto_vacuum = 0;
    39     40       PRAGMA journal_mode = DELETE;
    40     41       PRAGMA page_size = 1024;
    41     42       CREATE TABLE t1(a, b);
    42     43       INSERT INTO t1 VALUES(a_string(401), a_string(402));
    43     44     }
    44     45     for {set ii 0} {$ii < 13} {incr ii} {
    45     46       execsql { INSERT INTO t1 SELECT a_string(401), a_string(402) FROM t1 }

Changes to test/permutations.test.

   156    156   # Define the coverage related test suites:
   157    157   #
   158    158   #   coverage-wal
   159    159   #
   160    160   test_suite "coverage-wal" -description {
   161    161     Coverage tests for file wal.c.
   162    162   } -files {
   163         -  wal.test       wal2.test      wal3.test      walmode.test    
   164         -  walbak.test    walhook.test   walcrash2.test walcksum.test
          163  +  wal.test       wal2.test     wal3.test       walmode.test    
          164  +  walbak.test    walhook.test  walcrash2.test  walcksum.test
   165    165     walfault.test
   166    166   } 
   167    167   
   168    168   test_suite "coverage-pager" -description {
   169    169     Coverage tests for file pager.c.
   170    170   } -files {
   171         -  pager1.test
   172         -  pager2.test
   173         -  pagerfault.test
   174         -  pagerfault2.test
   175         -  walfault.test
   176         -  walbak.test
   177         -  journal2.test
   178         -  tkt-9d68c883.test
          171  +  pager1.test    pager2.test  pagerfault.test  pagerfault2.test
          172  +  walfault.test  walbak.test  journal2.test    tkt-9d68c883.test
   179    173   } 
   180    174   
   181    175   
   182    176   lappend ::testsuitelist xxx
   183    177   #-------------------------------------------------------------------------
   184    178   # Define the permutation test suites:
   185    179   #

Changes to test/tester.tcl.

   367    367     puts [format {%12d uS %s %s} $tm $rate $u2]
   368    368     global total_time
   369    369     set total_time [expr {$total_time+$tm}]
   370    370   }
   371    371   proc speed_trial_init {name} {
   372    372     global total_time
   373    373     set total_time 0
          374  +  sqlite3 versdb :memory:
          375  +  set vers [versdb one {SELECT sqlite_source_id()}]
          376  +  versdb close
          377  +  puts "SQLite $vers"
   374    378   }
   375    379   proc speed_trial_summary {name} {
   376    380     global total_time
   377    381     puts [format {%-21.21s %12d uS TOTAL} $name $total_time]
   378    382   }
   379    383   
   380    384   # Run this routine last

Changes to test/wal3.test.

   115    115     set testname(1) multiproc
   116    116     set testname(2) singleproc
   117    117     set tn $testname($i)
   118    118   
   119    119     do_test wal3-2.$tn.1 {
   120    120       sql1 { 
   121    121         PRAGMA page_size = 1024;
   122         -      PRAGMA auto_vacuum = OFF; 
   123    122         PRAGMA journal_mode = WAL;
   124    123       }
   125    124       sql1 {
   126    125         CREATE TABLE t1(a, b);
   127    126         INSERT INTO t1 VALUES(1, 'one');
   128    127         BEGIN;
   129    128           SELECT * FROM t1;

Changes to test/walbak.test.

    12     12   # focus of this file is testing the operation of the library in
    13     13   # "PRAGMA journal_mode=WAL" mode.
    14     14   #
    15     15   
    16     16   set testdir [file dirname $argv0]
    17     17   source $testdir/tester.tcl
    18     18   source $testdir/wal_common.tcl
           19  +source $testdir/malloc_common.tcl
    19     20   
    20     21   do_not_use_codec
    21     22   
    22     23   ifcapable !wal {finish_test ; return }
    23     24   
    24     25   
    25     26   # Test organization:
    26     27   # 
    27     28   #   walback-1.*: Simple tests.
           29  +#
    28     30   #   walback-2.*: Test backups when the source db is modified mid-backup.
           31  +#
           32  +#   walback-3.*: Backup of WAL sources into rollback destinations, and 
           33  +#                vice-versa.
    29     34   #
    30     35   
    31     36   # Make sure a simple backup from a WAL database works.
    32     37   #
    33     38   do_test walbak-1.0 {
    34     39     execsql { 
    35     40       PRAGMA synchronous = NORMAL;
................................................................................
   177    182   set sigB [sig db]
   178    183     list [B step 1000] [B finish]
   179    184   } {SQLITE_DONE SQLITE_OK}
   180    185   do_test walbak-2.12 {
   181    186     string compare [sig db] [sig db2]
   182    187   } {0}
   183    188   db2 close
          189  +db close
          190  +
          191  +#-------------------------------------------------------------------------
          192  +# Run some backup operations to copy back and forth between WAL and:
          193  +#
          194  +#   walbak-3.1.*: an in-memory database
          195  +#
          196  +#   walbak-3.2.*: a temporary database
          197  +#
          198  +#   walbak-3.3.*: a database in rollback mode.
          199  +#
          200  +#   walbak-3.4.*: a database in rollback mode that (initially) uses a 
          201  +#                 different page-size.
          202  +#
          203  +# Check that this does not confuse any connected clients.
          204  +#
          205  +foreach {tn setup} {
          206  +  1 {
          207  +    sqlite3 db  test.db
          208  +    sqlite3 db2 :memory:
          209  +    db  eval { PRAGMA page_size = 1024 ; PRAGMA journal_mode = WAL }
          210  +    db2 eval { PRAGMA page_size = 1024 }
          211  +  }
          212  +
          213  +  2 {
          214  +    sqlite3 db  test.db
          215  +    sqlite3 db2 ""
          216  +    db  eval { PRAGMA page_size = 1024 ; PRAGMA journal_mode = WAL }
          217  +    db2 eval { PRAGMA page_size = 1024 }
          218  +  }
          219  +
          220  +  3 {
          221  +    sqlite3 db  test.db
          222  +    sqlite3 db2 test.db2
          223  +    db  eval { PRAGMA page_size = 1024 ; PRAGMA journal_mode = WAL }
          224  +    db2 eval { PRAGMA page_size = 1024 ; PRAGMA journal_mode = PERSIST }
          225  +  }
          226  +
          227  +  4 {
          228  +    sqlite3 db  test.db
          229  +    sqlite3 db2 test.db2
          230  +    db  eval { PRAGMA page_size = 1024 ; PRAGMA journal_mode = WAL }
          231  +    db2 eval { 
          232  +      PRAGMA page_size = 2048;
          233  +      PRAGMA journal_mode = PERSIST;
          234  +      CREATE TABLE xx(x);
          235  +    }
          236  +  }
          237  +
          238  +} {
          239  +  foreach f [glob -nocomplain test.db*] { file delete -force $f }
          240  +
          241  +  eval $setup
          242  +
          243  +  do_test walbak-3.$tn.1 {
          244  +    execsql {
          245  +      CREATE TABLE t1(a, b);
          246  +      INSERT INTO t1 VALUES(1, 2);
          247  +      INSERT INTO t1 VALUES(3, 4);
          248  +      SELECT * FROM t1;
          249  +    }
          250  +  } {1 2 3 4}
          251  +
          252  +  do_test walbak-3.$tn.2 {
          253  +    sqlite3_backup B db2 main db main
          254  +    B step 10000
          255  +    B finish
          256  +    execsql { SELECT * FROM t1 } db2
          257  +  } {1 2 3 4}
          258  +
          259  +  do_test walbak-3.$tn.3 {
          260  +    execsql {
          261  +      INSERT INTO t1 VALUES(5, 6);
          262  +      INSERT INTO t1 VALUES(7, 8);
          263  +      SELECT * FROM t1;
          264  +    } db2
          265  +  } {1 2 3 4 5 6 7 8}
          266  +
          267  +  do_test walbak-3.$tn.4 {
          268  +    sqlite3_backup B db main db2 main
          269  +    B step 10000
          270  +    B finish
          271  +    execsql { SELECT * FROM t1 }
          272  +  } {1 2 3 4 5 6 7 8}
          273  +
          274  +  db  close
          275  +  db2 close
          276  +}
          277  +
   184    278   
   185    279   finish_test