Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Changes In Branch two-mappings Excluding Merge-Ins
This is equivalent to a diff from 30c0a693 to 80c63443
2013-04-01
| ||
14:20 | Minor changes to unixMapfile() function. (Leaf check-in: 80c63443 user: dan tags: two-mappings) | |
2013-03-29
| ||
19:38 | Further fixes for test scripts. (check-in: 23ffa4f9 user: dan tags: two-mappings) | |
2013-03-26
| ||
20:32 | Change os_unix.c to use either one or two mappings internally. (check-in: e7698cba user: dan tags: two-mappings) | |
14:36 | Change the name of the Pager.pFree field to Pager.pMmapFreelist. (check-in: 611bd824 user: drh tags: experimental-mmap) | |
14:16 | In btree.c, save the positions of any open cursors before moving any pages around to auto-vacuum the database on commit. (check-in: 30c0a693 user: dan tags: experimental-mmap) | |
01:07 | Previous check-in accidently left mmap turned off by default. This checkin fixes that. Unfortunately, shared.test is now segfaulting. All other veryquick tests appear to work, however. (check-in: a850c731 user: drh tags: experimental-mmap) | |
Changes to src/btree.c.
︙ | ︙ | |||
2592 2593 2594 2595 2596 2597 2598 | for(pCsr=pBt->pCursor; pCsr && rc==SQLITE_OK; pCsr=pCsr->pNext){ if( pCsr->iPage>=0 ){ MemPage *pPg = pCsr->apPage[0]; if( pPg && pPg->pDbPage->flags & PGHDR_MMAP ){ MemPage *pNew = 0; rc = getAndInitPage(pBt, pPg->pgno, &pNew, 0); | | > | | | | < > | 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 | for(pCsr=pBt->pCursor; pCsr && rc==SQLITE_OK; pCsr=pCsr->pNext){ if( pCsr->iPage>=0 ){ MemPage *pPg = pCsr->apPage[0]; if( pPg && pPg->pDbPage->flags & PGHDR_MMAP ){ MemPage *pNew = 0; rc = getAndInitPage(pBt, pPg->pgno, &pNew, 0); if( rc==SQLITE_OK ){ if( pCsr->iPage==0 ){ pCsr->info.pCell = pNew->aData + (pCsr->info.pCell - pPg->aData); } pCsr->apPage[0] = pNew; releasePage(pPg); } } } } return rc; } |
︙ | ︙ |
Changes to src/os_unix.c.
︙ | ︙ | |||
202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 | ** opportunity to either close or reuse it. */ struct UnixUnusedFd { int fd; /* File descriptor to close */ int flags; /* Flags this file descriptor was opened with */ UnixUnusedFd *pNext; /* Next unused file descriptor on same file */ }; /* ** The unixFile structure is subclass of sqlite3_file specific to the unix ** VFS implementations. */ typedef struct unixFile unixFile; struct unixFile { sqlite3_io_methods const *pMethod; /* Always the first entry */ sqlite3_vfs *pVfs; /* The VFS that created this unixFile */ unixInodeInfo *pInode; /* Info about locks on this inode */ int h; /* The file descriptor */ unsigned char eFileLock; /* The type of lock held on this fd */ unsigned short int ctrlFlags; /* Behavioral bits. UNIXFILE_* flags */ int lastErrno; /* The unix errno from last I/O error */ void *lockingContext; /* Locking style specific state */ UnixUnusedFd *pUnused; /* Pre-allocated UnixUnusedFd */ const char *zPath; /* Name of the file */ unixShm *pShm; /* Shared memory segment information */ int szChunk; /* Configured by FCNTL_CHUNK_SIZE */ int nFetchOut; /* Number of outstanding xFetch refs */ | > > > > > > > > < < | > > | 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 | ** opportunity to either close or reuse it. */ struct UnixUnusedFd { int fd; /* File descriptor to close */ int flags; /* Flags this file descriptor was opened with */ UnixUnusedFd *pNext; /* Next unused file descriptor on same file */ }; typedef struct unixMapping unixMapping; struct unixMapping { sqlite3_int64 mmapSize; sqlite3_int64 mmapOrigsize; void *pMapRegion; }; /* ** The unixFile structure is subclass of sqlite3_file specific to the unix ** VFS implementations. */ typedef struct unixFile unixFile; struct unixFile { sqlite3_io_methods const *pMethod; /* Always the first entry */ sqlite3_vfs *pVfs; /* The VFS that created this unixFile */ unixInodeInfo *pInode; /* Info about locks on this inode */ int h; /* The file descriptor */ unsigned char eFileLock; /* The type of lock held on this fd */ unsigned short int ctrlFlags; /* Behavioral bits. UNIXFILE_* flags */ int lastErrno; /* The unix errno from last I/O error */ void *lockingContext; /* Locking style specific state */ UnixUnusedFd *pUnused; /* Pre-allocated UnixUnusedFd */ const char *zPath; /* Name of the file */ unixShm *pShm; /* Shared memory segment information */ int szChunk; /* Configured by FCNTL_CHUNK_SIZE */ int nFetchOut; /* Number of outstanding xFetch refs */ sqlite3_int64 mmapLimit; /* Configured FCNTL_MMAP_LIMIT value */ int szSyspage; /* System page size */ unixMapping aMmap[2]; /* Up to two memory mapped regions */ #ifdef __QNXNTO__ int sectorSize; /* Device sector size */ int deviceCharacteristics; /* Precomputed device characteristics */ #endif #if SQLITE_ENABLE_LOCKING_STYLE int openFlags; /* The flags specified at open() */ #endif |
︙ | ︙ | |||
308 309 310 311 312 313 314 315 316 317 318 319 320 321 | ** testing and debugging only. */ #if SQLITE_THREADSAFE #define threadid pthread_self() #else #define threadid 0 #endif /* ** Different Unix systems declare open() in different ways. Same use ** open(const char*,int,mode_t). Others use open(const char*,int,...). ** The difference is important when using a pointer to the function. ** ** The safest way to deal with the problem is to always use this wrapper | > > > > > > > > | 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 | ** testing and debugging only. */ #if SQLITE_THREADSAFE #define threadid pthread_self() #else #define threadid 0 #endif #if !defined(HAVE_MREMAP) #if defined(__linux__) && defined(_GNU_SOURCE) # define HAVE_MREMAP 1 #else # define HAVE_MREMAP 0 #endif #endif /* ** Different Unix systems declare open() in different ways. Same use ** open(const char*,int,mode_t). Others use open(const char*,int,...). ** The difference is important when using a pointer to the function. ** ** The safest way to deal with the problem is to always use this wrapper |
︙ | ︙ | |||
446 447 448 449 450 451 452 | { "mmap", (sqlite3_syscall_ptr)mmap, 0 }, #define osMmap ((void*(*)(void*,size_t,int,int,int,off_t))aSyscall[21].pCurrent) { "munmap", (sqlite3_syscall_ptr)munmap, 0 }, #define osMunmap ((void*(*)(void*,size_t))aSyscall[22].pCurrent) | | | 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 | { "mmap", (sqlite3_syscall_ptr)mmap, 0 }, #define osMmap ((void*(*)(void*,size_t,int,int,int,off_t))aSyscall[21].pCurrent) { "munmap", (sqlite3_syscall_ptr)munmap, 0 }, #define osMunmap ((void*(*)(void*,size_t))aSyscall[22].pCurrent) #if HAVE_MREMAP { "mremap", (sqlite3_syscall_ptr)mremap, 0 }, #else { "mremap", (sqlite3_syscall_ptr)0, 0 }, #endif #define osMremap ((void*(*)(void*,size_t,size_t,int,...))aSyscall[23].pCurrent) }; /* End of the overrideable system calls */ |
︙ | ︙ | |||
1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 | /* ** Close a file. */ static int unixClose(sqlite3_file *id){ int rc = SQLITE_OK; unixFile *pFile = (unixFile *)id; unixUnlock(id, NO_LOCK); unixEnterMutex(); /* unixFile.pInode is always valid here. Otherwise, a different close ** routine (e.g. nolockClose()) would be called instead. */ assert( pFile->pInode->nLock>0 || pFile->pInode->bProcessLock==0 ); | > | 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 | /* ** Close a file. */ static int unixClose(sqlite3_file *id){ int rc = SQLITE_OK; unixFile *pFile = (unixFile *)id; unixUnmapfile(pFile); unixUnlock(id, NO_LOCK); unixEnterMutex(); /* unixFile.pInode is always valid here. Otherwise, a different close ** routine (e.g. nolockClose()) would be called instead. */ assert( pFile->pInode->nLock>0 || pFile->pInode->bProcessLock==0 ); |
︙ | ︙ | |||
3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 | void *pBuf, int amt, sqlite3_int64 offset ){ unixFile *pFile = (unixFile *)id; int got; assert( id ); /* If this is a database file (not a journal, master-journal or temp ** file), the bytes in the locking range should never be read or written. */ #if 0 assert( pFile->pUnused==0 || offset>=PENDING_BYTE+512 || offset+amt<=PENDING_BYTE ); #endif | > > | | > > > | | | | | | | | | | | > > | 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 3132 3133 3134 3135 3136 3137 3138 3139 3140 3141 3142 3143 3144 3145 3146 3147 3148 3149 3150 3151 3152 3153 | void *pBuf, int amt, sqlite3_int64 offset ){ unixFile *pFile = (unixFile *)id; int got; assert( id ); sqlite3_int64 iMap = 0; /* File offset of start of mapping i */ int i; /* Used to iterate through mappings */ /* If this is a database file (not a journal, master-journal or temp ** file), the bytes in the locking range should never be read or written. */ #if 0 assert( pFile->pUnused==0 || offset>=PENDING_BYTE+512 || offset+amt<=PENDING_BYTE ); #endif /* Deal with as much of this read request as possible by transfering ** data from the memory mapping using memcpy(). */ for(i=0; i<2; i++){ unixMapping *pMap = &pFile->aMmap[i]; sqlite3_int64 iEnd = iMap + pMap->mmapSize; if( offset<iEnd ){ if( offset+amt <= iEnd ){ memcpy(pBuf, &((u8 *)(pMap->pMapRegion))[offset-iMap], amt); return SQLITE_OK; }else{ int nCopy = iEnd - offset; memcpy(pBuf, &((u8 *)(pMap->pMapRegion))[offset-iMap], nCopy); pBuf = &((u8 *)pBuf)[nCopy]; amt -= nCopy; offset += nCopy; } } iMap = pMap->mmapSize; } got = seekAndRead(pFile, offset, pBuf, amt); if( got==amt ){ return SQLITE_OK; }else if( got<0 ){ /* lastErrno set by seekAndRead */ |
︙ | ︙ | |||
3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 | int amt, sqlite3_int64 offset ){ unixFile *pFile = (unixFile*)id; int wrote = 0; assert( id ); assert( amt>0 ); /* If this is a database file (not a journal, master-journal or temp ** file), the bytes in the locking range should never be read or written. */ #if 0 assert( pFile->pUnused==0 || offset>=PENDING_BYTE+512 || offset+amt<=PENDING_BYTE | > > | 3214 3215 3216 3217 3218 3219 3220 3221 3222 3223 3224 3225 3226 3227 3228 3229 | int amt, sqlite3_int64 offset ){ unixFile *pFile = (unixFile*)id; int wrote = 0; assert( id ); assert( amt>0 ); int i; sqlite3_int64 iMap = 0; /* If this is a database file (not a journal, master-journal or temp ** file), the bytes in the locking range should never be read or written. */ #if 0 assert( pFile->pUnused==0 || offset>=PENDING_BYTE+512 || offset+amt<=PENDING_BYTE |
︙ | ︙ | |||
3222 3223 3224 3225 3226 3227 3228 | if( rc!=4 || memcmp(oldCntr, &((char*)pBuf)[24-offset], 4)!=0 ){ pFile->transCntrChng = 1; /* The transaction counter has changed */ } } } #endif | | | > | | | | | | | | | | | > > | 3248 3249 3250 3251 3252 3253 3254 3255 3256 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 3268 3269 3270 3271 3272 3273 3274 3275 3276 3277 | if( rc!=4 || memcmp(oldCntr, &((char*)pBuf)[24-offset], 4)!=0 ){ pFile->transCntrChng = 1; /* The transaction counter has changed */ } } } #endif for(i=0; i<2; i++){ unixMapping *pMap = &pFile->aMmap[i]; sqlite3_int64 iEnd = iMap + pMap->mmapSize; if( offset<iEnd ){ if( offset+amt <= iEnd ){ memcpy(&((u8 *)(pMap->pMapRegion))[offset-iMap], pBuf, amt); return SQLITE_OK; }else{ int nCopy = iEnd - offset; memcpy(&((u8 *)(pMap->pMapRegion))[offset-iMap], pBuf, nCopy); pBuf = &((u8 *)pBuf)[nCopy]; amt -= nCopy; offset += nCopy; } } iMap = pMap->mmapSize; } while( amt>0 && (wrote = seekAndWrite(pFile, offset, pBuf, amt))>0 ){ amt -= wrote; offset += wrote; pBuf = &((char*)pBuf)[wrote]; } |
︙ | ︙ | |||
3506 3507 3508 3509 3510 3511 3512 3513 3514 3515 3516 3517 3518 3519 3520 3521 3522 3523 3524 3525 3526 3527 3528 3529 | } rc = robust_ftruncate(pFile->h, (off_t)nByte); if( rc ){ pFile->lastErrno = errno; return unixLogError(SQLITE_IOERR_TRUNCATE, "ftruncate", pFile->zPath); }else{ #ifdef SQLITE_DEBUG /* If we are doing a normal write to a database file (as opposed to ** doing a hot-journal rollback or a write to some file other than a ** normal database file) and we truncate the file to zero length, ** that effectively updates the change counter. This might happen ** when restoring a database using the backup API from a zero-length ** source. */ if( pFile->inNormalWrite && nByte==0 ){ pFile->transCntrChng = 1; } #endif /* If the file was just truncated to a size smaller than the currently ** mapped region, reduce the effective mapping size as well. SQLite will ** use read() and write() to access data beyond this point from now on. */ | > > > > > | | > > | 3535 3536 3537 3538 3539 3540 3541 3542 3543 3544 3545 3546 3547 3548 3549 3550 3551 3552 3553 3554 3555 3556 3557 3558 3559 3560 3561 3562 3563 3564 3565 3566 3567 3568 3569 3570 3571 3572 3573 3574 | } rc = robust_ftruncate(pFile->h, (off_t)nByte); if( rc ){ pFile->lastErrno = errno; return unixLogError(SQLITE_IOERR_TRUNCATE, "ftruncate", pFile->zPath); }else{ int i; #ifdef SQLITE_DEBUG /* If we are doing a normal write to a database file (as opposed to ** doing a hot-journal rollback or a write to some file other than a ** normal database file) and we truncate the file to zero length, ** that effectively updates the change counter. This might happen ** when restoring a database using the backup API from a zero-length ** source. */ if( pFile->inNormalWrite && nByte==0 ){ pFile->transCntrChng = 1; } #endif /* If the file was just truncated to a size smaller than the currently ** mapped region, reduce the effective mapping size as well. SQLite will ** use read() and write() to access data beyond this point from now on. */ for(i=1; i>=0; i--){ unixMapping *pMap = &pFile->aMmap[i]; sqlite3_int64 iEnd = pMap->mmapSize + (i==1 ? pMap[-1].mmapSize : 0); if( nByte<iEnd ){ pMap->mmapSize -= (iEnd - nByte); if( pMap->mmapSize<0 ) pMap->mmapSize = 0; } } return SQLITE_OK; } } /* |
︙ | ︙ | |||
3617 3618 3619 3620 3621 3622 3623 3624 | } #endif } } if( pFile->mmapLimit>0 ){ int rc; if( pFile->szChunk<=0 ){ | > > | | | 3653 3654 3655 3656 3657 3658 3659 3660 3661 3662 3663 3664 3665 3666 3667 3668 3669 3670 3671 3672 3673 3674 3675 3676 | } #endif } } if( pFile->mmapLimit>0 ){ int rc; sqlite3_int64 nSz = nByte; if( pFile->szChunk<=0 ){ nSz = ((nSz+pFile->szSyspage-1) / pFile->szSyspage) * pFile->szSyspage; if( robust_ftruncate(pFile->h, nSz) ){ pFile->lastErrno = errno; return unixLogError(SQLITE_IOERR_TRUNCATE, "ftruncate", pFile->zPath); } } rc = unixMapfile(pFile, nSz); return rc; } return SQLITE_OK; } /* |
︙ | ︙ | |||
4505 4506 4507 4508 4509 4510 4511 4512 | # define unixShmUnmap 0 #endif /* #ifndef SQLITE_OMIT_WAL */ /* ** If it is currently memory mapped, unmap file pFd. */ static void unixUnmapfile(unixFile *pFd){ assert( pFd->nFetchOut==0 ); | > > > | | | | | | | > > > > > > > > > > > > > > | > > > > > | < > > > > > | | | < < > > > > | > > > | | > > > > > > > > > | > > > > > > > > > > > > > > > > > > > > > > > | | | | | | > | 4543 4544 4545 4546 4547 4548 4549 4550 4551 4552 4553 4554 4555 4556 4557 4558 4559 4560 4561 4562 4563 4564 4565 4566 4567 4568 4569 4570 4571 4572 4573 4574 4575 4576 4577 4578 4579 4580 4581 4582 4583 4584 4585 4586 4587 4588 4589 4590 4591 4592 4593 4594 4595 4596 4597 4598 4599 4600 4601 4602 4603 4604 4605 4606 4607 4608 4609 4610 4611 4612 4613 4614 4615 4616 4617 4618 4619 4620 4621 4622 4623 4624 4625 4626 4627 4628 4629 4630 4631 4632 4633 4634 4635 4636 4637 4638 4639 4640 4641 4642 4643 4644 4645 4646 4647 4648 4649 4650 4651 4652 4653 4654 4655 4656 4657 4658 4659 4660 4661 4662 4663 4664 4665 4666 4667 4668 4669 4670 4671 4672 4673 4674 4675 4676 4677 4678 4679 4680 4681 4682 4683 4684 4685 4686 4687 | # define unixShmUnmap 0 #endif /* #ifndef SQLITE_OMIT_WAL */ /* ** If it is currently memory mapped, unmap file pFd. */ static void unixUnmapfile(unixFile *pFd){ int i; assert( pFd->nFetchOut==0 ); for(i=0; i<2; i++){ unixMapping *pMap = &pFd->aMmap[i]; if( pMap->pMapRegion ){ osMunmap(pMap->pMapRegion, pMap->mmapOrigsize); pMap->pMapRegion = 0; pMap->mmapSize = 0; pMap->mmapOrigsize = 0; } } } /* ** Return the system page size somehow. */ static int unixGetPagesize(void){ #if HAVE_REMAP return 512; #elif _BSD_SOURCE return getpagesize(); #else return (int)sysconf(_SC_PAGESIZE); #endif } /* ** Memory map or remap the file opened by file-descriptor pFd (if the file ** is already mapped, the existing mapping is replaced by the new). Or, if ** there already exists a mapping for this file, and there are still ** outstanding xFetch() references to it, this function is a no-op. ** ** If parameter nByte is non-negative, then it is the requested size of ** the mapping to create. Otherwise, if nByte is less than zero, then the ** requested size is the size of the file on disk. The actual size of the ** created mapping is either the requested size or the value configured ** using SQLITE_FCNTL_MMAP_LIMIT, whichever is smaller. ** ** SQLITE_OK is returned if no error occurs (even if the mapping is not ** recreated as a result of outstanding references) or an SQLite error ** code otherwise. */ static int unixMapfile(unixFile *pFd, i64 nByte){ i64 nMap; /* Number of bytes of file to map */ int rc; assert( nMap>=0 || pFd->nFetchOut==0 ); if( pFd->nFetchOut>0 ) return SQLITE_OK; /* Set variable nMap to the number of bytes of the file to map. This is ** the smaller of argument nByte and the limit configured by ** SQLITE_FCNTL_MMAP_LIMIT. Or, if nByte is less than zero, the smaller ** of the file size or the SQLITE_FCNTL_MMAP_LIMIT value. */ nMap = nByte; if( nMap<0 ){ struct stat statbuf; /* Low-level file information */ rc = osFstat(pFd->h, &statbuf); if( rc!=SQLITE_OK ){ return SQLITE_IOERR_FSTAT; } nMap = statbuf.st_size; } if( nMap>pFd->mmapLimit ){ nMap = pFd->mmapLimit; } if( nMap!=(pFd->aMmap[0].mmapSize + pFd->aMmap[1].mmapSize) ){ /* If the request is for a mapping zero bytes in size, or there are ** currently already two mapping regions, or there is already a mapping ** region that is not a multiple of the page-size in size, unmap ** everything. */ if( nMap==0 #if !HAVE_MREMAP || (pFd->aMmap[0].pMapRegion && pFd->aMmap[1].pMapRegion) || (pFd->aMmap[0].mmapSize % pFd->szSyspage) #endif ){ unixUnmapfile(pFd); } assert( pFd->aMmap[1].pMapRegion==0 ); if( nMap>0 ){ unixMapping *pMap = &pFd->aMmap[0]; /* First mapping object */ void *pNew = 0; int iNew = 0; int flags = PROT_READ; if( (pFd->ctrlFlags & UNIXFILE_RDONLY)==0 ) flags |= PROT_WRITE; /* If there are currently no mappings, create a new one */ if( pMap->pMapRegion==0 ){ pNew = osMmap(0, nMap, flags, MAP_SHARED, pFd->h, 0); } #if HAVE_MREMAP /* If we have an mremap() call, resize the existing mapping. */ else{ pNew = osMremap( pMap->pMapRegion, pMap->mmapOrigsize, nMap, MREMAP_MAYMOVE ); } #else /* Otherwise, create a second mapping. If the existing mapping is ** a multiple of the page-size in size, then request that the new ** mapping immediately follow the old in virtual memory. */ else{ i64 nNew; /* Bytes to map with this call */ void *pAddr = 0; /* Virtual address to request mapping at */ nNew = nMap - pMap->mmapSize; if( pMap->mmapSize==pMap->mmapOrigsize ){ pAddr = (void *)&((u8 *)pMap->pMapRegion)[pMap->mmapSize]; } pNew = osMmap(pAddr, nNew, flags, MAP_SHARED, pFd->h, pMap->mmapSize); if( pAddr && pNew==pAddr ){ pNew = pMap->pMapRegion; }else{ iNew = 1; nMap = nNew; } } #endif if( pNew==MAP_FAILED ){ return SQLITE_IOERR_MMAP; } pFd->aMmap[iNew].pMapRegion = pNew; pFd->aMmap[iNew].mmapSize = nMap; pFd->aMmap[iNew].mmapOrigsize = nMap; } } return SQLITE_OK; } /* ** If possible, return a pointer to a mapping of file fd starting at offset |
︙ | ︙ | |||
4594 4595 4596 4597 4598 4599 4600 | ** release the reference by calling unixUnfetch(). */ static int unixFetch(sqlite3_file *fd, i64 iOff, int nAmt, void **pp){ unixFile *pFd = (unixFile *)fd; /* The underlying database file */ *pp = 0; if( pFd->mmapLimit>0 ){ | > > > | | > > > | | > > > | 4696 4697 4698 4699 4700 4701 4702 4703 4704 4705 4706 4707 4708 4709 4710 4711 4712 4713 4714 4715 4716 4717 4718 4719 4720 4721 4722 4723 4724 4725 | ** release the reference by calling unixUnfetch(). */ static int unixFetch(sqlite3_file *fd, i64 iOff, int nAmt, void **pp){ unixFile *pFd = (unixFile *)fd; /* The underlying database file */ *pp = 0; if( pFd->mmapLimit>0 ){ int i; sqlite3_int64 iMap = 0; if( pFd->aMmap[0].pMapRegion==0 ){ int rc = unixMapfile(pFd, -1); if( rc!=SQLITE_OK ) return rc; } for(i=0; i<2; i++){ unixMapping *pMap = &pFd->aMmap[i]; if( iOff>=iMap && iOff+nAmt<=(iMap + pMap->mmapSize) ){ *pp = &((u8 *)pMap->pMapRegion)[iOff-iMap]; pFd->nFetchOut++; break; } iMap = pMap->mmapSize; } } return SQLITE_OK; } /* ** If the third argument is non-NULL, then this function releases a |
︙ | ︙ | |||
4625 4626 4627 4628 4629 4630 4631 4632 4633 4634 4635 4636 4637 4638 4639 | /* If p==0 (unmap the entire file) then there must be no outstanding ** xFetch references. Or, if p!=0 (meaning it is an xFetch reference), ** then there must be at least one outstanding. */ assert( (p==0)==(pFd->nFetchOut==0) ); /* If p!=0, it must match the iOff value. */ assert( p==0 || p==&((u8 *)pFd->pMapRegion)[iOff] ); if( p ){ pFd->nFetchOut--; }else{ unixUnmapfile(pFd); } | > > | 4736 4737 4738 4739 4740 4741 4742 4743 4744 4745 4746 4747 4748 4749 4750 4751 4752 | /* If p==0 (unmap the entire file) then there must be no outstanding ** xFetch references. Or, if p!=0 (meaning it is an xFetch reference), ** then there must be at least one outstanding. */ assert( (p==0)==(pFd->nFetchOut==0) ); /* If p!=0, it must match the iOff value. */ #if 0 assert( p==0 || p==&((u8 *)pFd->pMapRegion)[iOff] ); #endif if( p ){ pFd->nFetchOut--; }else{ unixUnmapfile(pFd); } |
︙ | ︙ | |||
5587 5588 5589 5590 5591 5592 5593 5594 5595 5596 5597 5598 5599 5600 | } } goto open_finished; } } #endif rc = fillInUnixFile(pVfs, fd, pFile, zPath, ctrlFlags); open_finished: if( rc!=SQLITE_OK ){ sqlite3_free(p->pUnused); } return rc; | > | 5700 5701 5702 5703 5704 5705 5706 5707 5708 5709 5710 5711 5712 5713 5714 | } } goto open_finished; } } #endif p->szSyspage = unixGetPagesize(); rc = fillInUnixFile(pVfs, fd, pFile, zPath, ctrlFlags); open_finished: if( rc!=SQLITE_OK ){ sqlite3_free(p->pUnused); } return rc; |
︙ | ︙ |
Changes to src/pager.c.
︙ | ︙ | |||
3356 3357 3358 3359 3360 3361 3362 | /* ** Invoke SQLITE_FCNTL_MMAP_LIMIT based on the current value of mxMmap. */ static void pagerFixMaplimit(Pager *pPager){ sqlite3_file *fd = pPager->fd; if( isOpen(fd) ){ pPager->bUseFetch = (fd->pMethods->iVersion>=3) && pPager->mxMmap>0; | < | < | 3356 3357 3358 3359 3360 3361 3362 3363 3364 3365 3366 3367 3368 3369 3370 3371 | /* ** Invoke SQLITE_FCNTL_MMAP_LIMIT based on the current value of mxMmap. */ static void pagerFixMaplimit(Pager *pPager){ sqlite3_file *fd = pPager->fd; if( isOpen(fd) ){ pPager->bUseFetch = (fd->pMethods->iVersion>=3) && pPager->mxMmap>0; sqlite3OsFileControlHint(pPager->fd, SQLITE_FCNTL_MMAP_LIMIT, (void*)&pPager->mxMmap); } } /* ** Change the maximum size of any memory mapping made of the database file. */ void sqlite3PagerSetMmapLimit(Pager *pPager, sqlite3_int64 mxMmap){ |
︙ | ︙ | |||
3635 3636 3637 3638 3639 3640 3641 3642 3643 3644 3645 3646 3647 3648 3649 | ** Regardless of mxPage, return the current maximum page count. */ int sqlite3PagerMaxPageCount(Pager *pPager, int mxPage){ if( mxPage>0 ){ pPager->mxPgno = mxPage; } assert( pPager->eState!=PAGER_OPEN ); /* Called only by OP_MaxPgcnt */ assert( pPager->mxPgno>=pPager->dbSize ); /* OP_MaxPgcnt enforces this */ return pPager->mxPgno; } /* ** The following set of routines are used to disable the simulated ** I/O error mechanism. These routines are used to avoid simulated ** errors in places where we do not care about errors. | > > | 3633 3634 3635 3636 3637 3638 3639 3640 3641 3642 3643 3644 3645 3646 3647 3648 3649 | ** Regardless of mxPage, return the current maximum page count. */ int sqlite3PagerMaxPageCount(Pager *pPager, int mxPage){ if( mxPage>0 ){ pPager->mxPgno = mxPage; } assert( pPager->eState!=PAGER_OPEN ); /* Called only by OP_MaxPgcnt */ #if 0 assert( pPager->mxPgno>=pPager->dbSize ); /* OP_MaxPgcnt enforces this */ #endif return pPager->mxPgno; } /* ** The following set of routines are used to disable the simulated ** I/O error mechanism. These routines are used to avoid simulated ** errors in places where we do not care about errors. |
︙ | ︙ |
Changes to src/wal.c.
︙ | ︙ | |||
1204 1205 1206 1207 1208 1209 1210 | /* If more than one frame was recovered from the log file, report an ** event via sqlite3_log(). This is to help with identifying performance ** problems caused by applications routinely shutting down without ** checkpointing the log file. */ if( pWal->hdr.nPage ){ sqlite3_log(SQLITE_OK, "Recovered %d frames from WAL file %s", | | | 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 | /* If more than one frame was recovered from the log file, report an ** event via sqlite3_log(). This is to help with identifying performance ** problems caused by applications routinely shutting down without ** checkpointing the log file. */ if( pWal->hdr.nPage ){ sqlite3_log(SQLITE_OK, "Recovered %d frames from WAL file %s", pWal->hdr.mxFrame, pWal->zWalName ); } } recovery_error: WALTRACE(("WAL%p: recovery %s\n", pWal, rc ? "failed" : "ok")); walUnlockExclusive(pWal, iLock, nLock); |
︙ | ︙ |
Changes to test/autovacuum.test.
︙ | ︙ | |||
28 29 30 31 32 33 34 | proc make_str {char len} { set str [string repeat $char. $len] return [string range $str 0 [expr $len-1]] } # Return the number of pages in the file test.db by looking at the file system. proc file_pages {} { | | | 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | proc make_str {char len} { set str [string repeat $char. $len] return [string range $str 0 [expr $len-1]] } # Return the number of pages in the file test.db by looking at the file system. proc file_pages {} { file_page_count test.db } #------------------------------------------------------------------------- # Test cases autovacuum-1.* work as follows: # # 1. A table with a single indexed field is created. # 2. Approximately 20 rows are inserted into the table. Each row is long |
︙ | ︙ | |||
610 611 612 613 614 615 616 | INSERT INTO t1 SELECT randstr(400,400), randstr(400,400) FROM t1; -- 2 INSERT INTO t1 SELECT randstr(400,400), randstr(400,400) FROM t1; -- 4 INSERT INTO t1 SELECT randstr(400,400), randstr(400,400) FROM t1; -- 8 INSERT INTO t1 SELECT randstr(400,400), randstr(400,400) FROM t1; -- 16 INSERT INTO t1 SELECT randstr(400,400), randstr(400,400) FROM t1; -- 32 } | | | | | 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 | INSERT INTO t1 SELECT randstr(400,400), randstr(400,400) FROM t1; -- 2 INSERT INTO t1 SELECT randstr(400,400), randstr(400,400) FROM t1; -- 4 INSERT INTO t1 SELECT randstr(400,400), randstr(400,400) FROM t1; -- 8 INSERT INTO t1 SELECT randstr(400,400), randstr(400,400) FROM t1; -- 16 INSERT INTO t1 SELECT randstr(400,400), randstr(400,400) FROM t1; -- 32 } file_page_count test.db } {73} do_test autovacuum-7.2 { execsql { CREATE TABLE t2(a, b, PRIMARY KEY(a, b)); INSERT INTO t2 SELECT randstr(400,400), randstr(400,400) FROM t1; -- 2 CREATE TABLE t3(a, b, PRIMARY KEY(a, b)); INSERT INTO t3 SELECT randstr(400,400), randstr(400,400) FROM t1; -- 2 CREATE TABLE t4(a, b, PRIMARY KEY(a, b)); INSERT INTO t4 SELECT randstr(400,400), randstr(400,400) FROM t1; -- 2 CREATE TABLE t5(a, b, PRIMARY KEY(a, b)); INSERT INTO t5 SELECT randstr(400,400), randstr(400,400) FROM t1; -- 2 } file_page_count test.db } {354} do_test autovacuum-7.3 { db close sqlite3 db test.db execsql { BEGIN; DELETE FROM t4; COMMIT; SELECT count(*) FROM t1; } file_page_count test.db } {286} #------------------------------------------------------------------------ # Additional tests. # # Try to determine the autovacuum setting for a database that is locked. # |
︙ | ︙ |
Changes to test/backup.test.
︙ | ︙ | |||
657 658 659 660 661 662 663 | INSERT INTO t1 VALUES(3, randstr(1000,1000)); INSERT INTO t1 VALUES(4, randstr(1000,1000)); INSERT INTO t1 VALUES(5, randstr(1000,1000)); COMMIT; } } {} do_test backup-6.2 { | | | 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 | INSERT INTO t1 VALUES(3, randstr(1000,1000)); INSERT INTO t1 VALUES(4, randstr(1000,1000)); INSERT INTO t1 VALUES(5, randstr(1000,1000)); COMMIT; } } {} do_test backup-6.2 { set nTotal [file_page_count test.db] sqlite3_backup B db2 main db main B step 1 } {SQLITE_OK} do_test backup-6.3 { B pagecount } $nTotal do_test backup-6.4 { |
︙ | ︙ |
Changes to test/backup4.test.
︙ | ︙ | |||
59 60 61 62 63 64 65 | # Test that if the source is zero bytes, the destination database # consists of a single page only. # do_execsql_test 2.1 { CREATE TABLE t1(a, b); CREATE INDEX i1 ON t1(a, b); } | | | 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | # Test that if the source is zero bytes, the destination database # consists of a single page only. # do_execsql_test 2.1 { CREATE TABLE t1(a, b); CREATE INDEX i1 ON t1(a, b); } do_test 2.2 { file_page_count test.db } [expr $AUTOVACUUM ? 4 : 3] do_test 2.3 { sqlite3 db1 test.db2 db1 backup test.db db1 close file size test.db } {1024} |
︙ | ︙ |
Changes to test/corrupt2.test.
︙ | ︙ | |||
330 331 332 333 334 335 336 | PRAGMA page_size = 1024; CREATE TABLE t1(a INTEGER PRIMARY KEY, b); INSERT INTO t1 VALUES(1, randomblob(2500)); INSERT INTO t1 VALUES(2, randomblob(2500)); INSERT INTO t1 VALUES(3, randomblob(2500)); DELETE FROM t1 WHERE a = 1; } -corrupt { | | | 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 | PRAGMA page_size = 1024; CREATE TABLE t1(a INTEGER PRIMARY KEY, b); INSERT INTO t1 VALUES(1, randomblob(2500)); INSERT INTO t1 VALUES(2, randomblob(2500)); INSERT INTO t1 VALUES(3, randomblob(2500)); DELETE FROM t1 WHERE a = 1; } -corrupt { set nPage [file_page_count corrupt.db] hexio_write corrupt.db [expr 1024 + ($nPage-3)*5] 010000000 } -test { do_test corrupt2-6.3 { catchsql " $::presql pragma incremental_vacuum = 1 " } {1 {database disk image is malformed}} } |
︙ | ︙ |
Changes to test/corrupt3.test.
︙ | ︙ | |||
36 37 38 39 40 41 42 | set bigstring [string repeat 0123456789 200] execsql { PRAGMA auto_vacuum=OFF; PRAGMA page_size=1024; CREATE TABLE t1(x); INSERT INTO t1 VALUES($bigstring); } | | | | 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | set bigstring [string repeat 0123456789 200] execsql { PRAGMA auto_vacuum=OFF; PRAGMA page_size=1024; CREATE TABLE t1(x); INSERT INTO t1 VALUES($bigstring); } list [file_page_count test.db] [file_page_size test.db] } {3 1024} # Verify that the file format is as we expect. The page size # should be 1024 bytes. The only record should have a single # overflow page. The overflow page is page 3. The pointer to # the overflow page is on the last 4 bytes of page 2. # do_test corrupt3-1.2 { |
︙ | ︙ |
Changes to test/corrupt6.test.
︙ | ︙ | |||
37 38 39 40 41 42 43 | execsql { PRAGMA auto_vacuum=OFF; PRAGMA page_size=1024; CREATE TABLE t1(x); INSERT INTO t1(x) VALUES('varint32-01234567890123456789012345678901234567890123456789'); INSERT INTO t1(x) VALUES('varint32-01234567890123456789012345678901234567890123456789'); } | | | | 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | execsql { PRAGMA auto_vacuum=OFF; PRAGMA page_size=1024; CREATE TABLE t1(x); INSERT INTO t1(x) VALUES('varint32-01234567890123456789012345678901234567890123456789'); INSERT INTO t1(x) VALUES('varint32-01234567890123456789012345678901234567890123456789'); } file_page_count test.db } {2} # Verify that the file format is as we expect. The page size # should be 1024 bytes. # do_test corrupt6-1.2 { hexio_get_int [hexio_read test.db 16 2] } 1024 ;# The page size is 1024 |
︙ | ︙ |
Changes to test/corrupt7.test.
︙ | ︙ | |||
40 41 42 43 44 45 46 | CREATE TABLE t1(x); INSERT INTO t1(x) VALUES(1); INSERT INTO t1(x) VALUES(2); INSERT INTO t1(x) SELECT x+2 FROM t1; INSERT INTO t1(x) SELECT x+4 FROM t1; INSERT INTO t1(x) SELECT x+8 FROM t1; } | | | | 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | CREATE TABLE t1(x); INSERT INTO t1(x) VALUES(1); INSERT INTO t1(x) VALUES(2); INSERT INTO t1(x) SELECT x+2 FROM t1; INSERT INTO t1(x) SELECT x+4 FROM t1; INSERT INTO t1(x) SELECT x+8 FROM t1; } file_page_count test.db } {2} # Verify that the file format is as we expect. The page size # should be 1024 bytes. # do_test corrupt7-1.2 { hexio_get_int [hexio_read test.db 16 2] } 1024 ;# The page size is 1024 |
︙ | ︙ |
Changes to test/corruptC.test.
︙ | ︙ | |||
266 267 268 269 270 271 272 | forcecopy test.bu test.db sqlite3 db test.db set blob [string repeat abcdefghij 10000] execsql { INSERT INTO t1 VALUES (1, $blob) } sqlite3 db test.db | | | 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 | forcecopy test.bu test.db sqlite3 db test.db set blob [string repeat abcdefghij 10000] execsql { INSERT INTO t1 VALUES (1, $blob) } sqlite3 db test.db set filesize [expr [file_page_count test.db] * [file_page_size test.db]] hexio_write test.db [expr $filesize-2048] 00000001 catchsql {DELETE FROM t1 WHERE rowid = (SELECT max(rowid) FROM t1)} } {1 {database disk image is malformed}} # At one point this particular corrupt database was causing a buffer # overread. Which caused a crash in a run of all.test once. # |
︙ | ︙ |
Changes to test/corruptF.test.
︙ | ︙ | |||
52 53 54 55 56 57 58 | } do_test 1.1 { create_test_db } {} # Check the db is as we expect. 6 pages in total, with 3 and 4 on the free # list. Page 3 is the free list trunk and page 4 is a leaf. # | | | 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | } do_test 1.1 { create_test_db } {} # Check the db is as we expect. 6 pages in total, with 3 and 4 on the free # list. Page 3 is the free list trunk and page 4 is a leaf. # do_test 1.2 { file_page_count test.db } 6 do_test 1.3 { hexio_read test.db 32 4 } 00000003 do_test 1.4 { hexio_read test.db [expr 2*1024] 12 } 000000000000000100000004 # Change the free-list entry to page 6 and reopen the db file. do_test 1.5 { hexio_write test.db [expr 2*1024 + 8] 00000006 sqlite3 db test.db |
︙ | ︙ | |||
105 106 107 108 109 110 111 | } set res } {} } } do_test 2.1 { create_test_db } {} | | | 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 | } set res } {} } } do_test 2.1 { create_test_db } {} do_test 2.2 { file_page_count test.db } 6 do_test 2.3 { hexio_read test.db 32 4 } 00000003 do_test 2.4 { hexio_read test.db [expr 2*1024] 12 } 000000000000000100000004 # Change the free-list entry to page 5 and reopen the db file. do_test 2.5 { hexio_write test.db [expr 2*1024 + 8] 00000005 sqlite3 db test.db |
︙ | ︙ |
Changes to test/crash.test.
︙ | ︙ | |||
326 327 328 329 330 331 332 | INSERT INTO abc VALUES(randstr(1500,1500), 0, 0); -- Overflow page 4 INSERT INTO abc SELECT * FROM abc; INSERT INTO abc SELECT * FROM abc; INSERT INTO abc SELECT * FROM abc; } } {} do_test crash-5.2 { | | | 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 | INSERT INTO abc VALUES(randstr(1500,1500), 0, 0); -- Overflow page 4 INSERT INTO abc SELECT * FROM abc; INSERT INTO abc SELECT * FROM abc; INSERT INTO abc SELECT * FROM abc; } } {} do_test crash-5.2 { file_page_count test.db } [expr [string match [execsql {pragma auto_vacuum}] 1] ? 11 : 10] set sig [signature] do_test crash-5.3 { # The SQL below is used to expose a bug that existed in # sqlite3pager_movepage() during development of the auto-vacuum feature. It # functions as follows: # |
︙ | ︙ |
Changes to test/createtab.test.
︙ | ︙ | |||
48 49 50 51 52 53 54 | set isUtf16 0 ifcapable utf16 { set isUtf16 [expr {[execsql {PRAGMA encoding}] != "UTF-8"}] } do_test createtab-$av.2 { | | | | 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | set isUtf16 0 ifcapable utf16 { set isUtf16 [expr {[execsql {PRAGMA encoding}] != "UTF-8"}] } do_test createtab-$av.2 { file_page_count test.db } [expr {4+($av!=0)+(${isUtf16}*2)}] # Start reading the table # do_test createtab-$av.3 { set STMT [sqlite3_prepare db {SELECT x FROM t1} -1 TAIL] sqlite3_step $STMT } {SQLITE_ROW} |
︙ | ︙ |
Changes to test/dbstatus2.test.
︙ | ︙ | |||
16 17 18 19 20 21 22 23 24 25 26 27 28 29 | source $testdir/tester.tcl set ::testprefix dbstatus2 do_execsql_test 1.0 { PRAGMA page_size = 1024; PRAGMA auto_vacuum = 0; CREATE TABLE t1(a PRIMARY KEY, b); INSERT INTO t1 VALUES(1, randomblob(600)); INSERT INTO t1 VALUES(2, randomblob(600)); INSERT INTO t1 VALUES(3, randomblob(600)); } | > | 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | source $testdir/tester.tcl set ::testprefix dbstatus2 do_execsql_test 1.0 { PRAGMA page_size = 1024; PRAGMA auto_vacuum = 0; PRAGMA mmap_limit = 0; CREATE TABLE t1(a PRIMARY KEY, b); INSERT INTO t1 VALUES(1, randomblob(600)); INSERT INTO t1 VALUES(2, randomblob(600)); INSERT INTO t1 VALUES(3, randomblob(600)); } |
︙ | ︙ |
Changes to test/e_vacuum.test.
︙ | ︙ | |||
38 39 40 41 42 43 44 | INSERT INTO t1 SELECT a+64, randomblob(400) FROM t1; CREATE TABLE t2(a PRIMARY KEY, b UNIQUE); INSERT INTO t2 SELECT * FROM t1; } } | | | 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | INSERT INTO t1 SELECT a+64, randomblob(400) FROM t1; CREATE TABLE t2(a PRIMARY KEY, b UNIQUE); INSERT INTO t2 SELECT * FROM t1; } } return [file_page_count test.db] } # This proc returns the number of contiguous blocks of pages that make up # the table or index named by the only argument. For example, if the table # occupies database pages 3, 4, 8 and 9, then this command returns 2 (there # are 2 fragments - one consisting of pages 3 and 4, the other of fragments # 8 and 9). |
︙ | ︙ |
Changes to test/filefmt.test.
︙ | ︙ | |||
61 62 63 64 65 66 67 68 69 70 71 72 73 74 | foreach pagesize {512 1024 2048 4096 8192 16384 32768} { if {[info exists SQLITE_MAX_PAGE_SIZE] && $pagesize>$SQLITE_MAX_PAGE_SIZE} continue do_test filefmt-1.5.$pagesize.1 { db close forcedelete test.db sqlite3 db test.db db eval "PRAGMA auto_vacuum=OFF" db eval "PRAGMA page_size=$pagesize" db eval {CREATE TABLE t1(x)} file size test.db } [expr $pagesize*2] do_test filefmt-1.5.$pagesize.2 { hexio_get_int [hexio_read test.db 16 2] | > | 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 | foreach pagesize {512 1024 2048 4096 8192 16384 32768} { if {[info exists SQLITE_MAX_PAGE_SIZE] && $pagesize>$SQLITE_MAX_PAGE_SIZE} continue do_test filefmt-1.5.$pagesize.1 { db close forcedelete test.db sqlite3 db test.db db eval "PRAGMA mmap_limit=0" db eval "PRAGMA auto_vacuum=OFF" db eval "PRAGMA page_size=$pagesize" db eval {CREATE TABLE t1(x)} file size test.db } [expr $pagesize*2] do_test filefmt-1.5.$pagesize.2 { hexio_get_int [hexio_read test.db 16 2] |
︙ | ︙ | |||
211 212 213 214 215 216 217 218 219 220 221 222 223 224 | do_execsql_test filefmt-3.3 { SELECT * FROM sqlite_master; PRAGMA integrity_check; } {ok} reset_db do_execsql_test filefmt-4.1 { PRAGMA auto_vacuum = 1; CREATE TABLE t1(x, y); CREATE TABLE t2(x, y); INSERT INTO t1 VALUES(randomblob(100), randomblob(100)); INSERT INTO t1 VALUES(randomblob(100), randomblob(100)); INSERT INTO t1 VALUES(randomblob(100), randomblob(100)); | > | 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 | do_execsql_test filefmt-3.3 { SELECT * FROM sqlite_master; PRAGMA integrity_check; } {ok} reset_db do_execsql_test filefmt-4.1 { PRAGMA mmap_limit = 0; PRAGMA auto_vacuum = 1; CREATE TABLE t1(x, y); CREATE TABLE t2(x, y); INSERT INTO t1 VALUES(randomblob(100), randomblob(100)); INSERT INTO t1 VALUES(randomblob(100), randomblob(100)); INSERT INTO t1 VALUES(randomblob(100), randomblob(100)); |
︙ | ︙ |
Changes to test/format4.test.
︙ | ︙ | |||
42 43 44 45 46 47 48 | INSERT INTO t1 SELECT * FROM t1; INSERT INTO t1 SELECT * FROM t1; INSERT INTO t1 SELECT * FROM t1; INSERT INTO t1 SELECT * FROM t1; INSERT INTO t1 SELECT * FROM t1; INSERT INTO t1 SELECT * FROM t1; } | | | | | 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | INSERT INTO t1 SELECT * FROM t1; INSERT INTO t1 SELECT * FROM t1; INSERT INTO t1 SELECT * FROM t1; INSERT INTO t1 SELECT * FROM t1; INSERT INTO t1 SELECT * FROM t1; INSERT INTO t1 SELECT * FROM t1; } expr {1024 * [file_page_count test.db]} } $small do_test format4-1.2 { execsql { UPDATE t1 SET x0=1, x1=1, x2=1, x3=1, x4=1, x5=1, x6=1, x7=1, x8=1, x9=1 } expr {1024 * [file_page_count test.db]} } $small do_test format4-1.3 { execsql { UPDATE t1 SET x0=2, x1=2, x2=2, x3=2, x4=2, x5=2, x6=2, x7=2, x8=2, x9=2 } expr {1024 * [file_page_count test.db]} } $large finish_test |
Changes to test/incrblob.test.
︙ | ︙ | |||
615 616 617 618 619 620 621 | INSERT INTO t2 VALUES(456, $::otherdata); } set ::b [db incrblob -readonly t2 b 456] fconfigure $::b -translation binary read $::b } $::otherdata do_test incrblob-7.3.2 { | | | 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 | INSERT INTO t2 VALUES(456, $::otherdata); } set ::b [db incrblob -readonly t2 b 456] fconfigure $::b -translation binary read $::b } $::otherdata do_test incrblob-7.3.2 { file_page_count test.db } 30 do_test incrblob-7.3.3 { execsql { DELETE FROM t1 WHERE a = 123; PRAGMA INCREMENTAL_VACUUM(0); } seek $::b 0 |
︙ | ︙ |
Changes to test/incrvacuum.test.
︙ | ︙ | |||
145 146 147 148 149 150 151 | # # 1 -> database header # 2 -> first back-pointer page # 3 -> table abc # 4 -> table tbl2 # 5 -> table tbl2 overflow page. # | | | | | | | 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 | # # 1 -> database header # 2 -> first back-pointer page # 3 -> table abc # 4 -> table tbl2 # 5 -> table tbl2 overflow page. # file_page_count test.db } {5} do_test incrvacuum-3.3 { execsql { DROP TABLE abc; DELETE FROM tbl2; } file_page_count test.db } {5} do_test incrvacuum-3.4 { execsql { PRAGMA auto_vacuum = 1; INSERT INTO tbl2 VALUES('hello world'); } file_page_count test.db } {3} #--------------------------------------------------------------------- # Try to run a very simple incremental vacuum. Also verify that # PRAGMA incremental_vacuum is a harmless no-op against a database that # does not support auto-vacuum. # do_test incrvacuum-4.1 { set ::str [string repeat 1234567890 110] execsql { PRAGMA auto_vacuum = 2; INSERT INTO tbl2 VALUES($::str); CREATE TABLE tbl1(a, b, c); } file_page_count test.db } {5} do_test incrvacuum-4.2 { execsql { DELETE FROM tbl2; DROP TABLE tbl1; } file_page_count test.db } {5} do_test incrvacuum-4.3 { set ::nStep 0 db eval {pragma incremental_vacuum(10)} { incr ::nStep } list [expr {[file size test.db] / 1024}] $::nStep |
︙ | ︙ | |||
217 218 219 220 221 222 223 | execsql { BEGIN; CREATE TABLE tbl1(a); INSERT INTO tbl1 VALUES($::str); PRAGMA incremental_vacuum; -- this is a no-op. COMMIT; } | | | | | | 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 | execsql { BEGIN; CREATE TABLE tbl1(a); INSERT INTO tbl1 VALUES($::str); PRAGMA incremental_vacuum; -- this is a no-op. COMMIT; } file_page_count test.db } {4} do_test incrvacuum-5.2.2 { set ::str [string repeat abcdefghij 110] execsql { BEGIN; INSERT INTO tbl1 VALUES($::str); INSERT INTO tbl1 SELECT * FROM tbl1; DELETE FROM tbl1 WHERE oid%2; -- Put 2 overflow pages on free-list. COMMIT; } file_page_count test.db } {7} do_test incrvacuum-5.2.3 { execsql { BEGIN; PRAGMA incremental_vacuum; -- Vacuum up the two pages. CREATE TABLE tbl2(b); -- Use one free page as a table root. INSERT INTO tbl2 VALUES('a nice string'); COMMIT; } file_page_count test.db } {6} do_test incrvacuum-5.2.4 { execsql { SELECT * FROM tbl2; } } {{a nice string}} do_test incrvacuum-5.2.5 { execsql { DROP TABLE tbl1; DROP TABLE tbl2; PRAGMA incremental_vacuum; } file_page_count test.db } {1} # Test cases incrvacuum-5.3.* use the following list as input data. # Two new databases are opened, one with incremental vacuum enabled, # the other with no auto-vacuum completely disabled. After executing # each element of the following list on both databases, test that |
︙ | ︙ | |||
523 524 525 526 527 528 529 | # N pages are vacuumed. # do_test incrvacuum-10.1 { execsql { DROP TABLE t1; DROP TABLE t2; } | | | 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 | # N pages are vacuumed. # do_test incrvacuum-10.1 { execsql { DROP TABLE t1; DROP TABLE t2; } file_page_count test.db } {29} do_test incrvacuum-10.2 { execsql { PRAGMA incremental_vacuum(1); } expr [file size test.db] / 1024 |
︙ | ︙ |
Changes to test/io.test.
︙ | ︙ | |||
414 415 416 417 418 419 420 | # size may be a little less than that. So this test case just tests # that the file is now greater than 20000 bytes in size. list [expr [file size test.db]>20000] [nSync] } {1 0} do_test io-3.3 { # The COMMIT requires a single fsync() - to the database file. execsql { COMMIT } | | | | 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 | # size may be a little less than that. So this test case just tests # that the file is now greater than 20000 bytes in size. list [expr [file size test.db]>20000] [nSync] } {1 0} do_test io-3.3 { # The COMMIT requires a single fsync() - to the database file. execsql { COMMIT } list [file_page_count test.db] [nSync] } {39 1} } #---------------------------------------------------------------------- # Test cases io-4.* test the IOCAP_SAFE_APPEND optimization. # sqlite3_simulate_device -char safe_append |
︙ | ︙ | |||
484 485 486 487 488 489 490 | INSERT INTO abc SELECT * FROM abc; INSERT INTO abc SELECT * FROM abc; INSERT INTO abc SELECT * FROM abc; INSERT INTO abc SELECT * FROM abc; INSERT INTO abc SELECT * FROM abc; INSERT INTO abc SELECT * FROM abc; } | | | 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 | INSERT INTO abc SELECT * FROM abc; INSERT INTO abc SELECT * FROM abc; INSERT INTO abc SELECT * FROM abc; INSERT INTO abc SELECT * FROM abc; INSERT INTO abc SELECT * FROM abc; INSERT INTO abc SELECT * FROM abc; } file_page_count test.db } {43} ifcapable pager_pragmas { do_test io-4.3.2 { execsql { PRAGMA synchronous = full; PRAGMA cache_size = 10; PRAGMA synchronous; |
︙ | ︙ | |||
558 559 560 561 562 563 564 | if {[regexp {^atomic} $char]} continue } do_test io-5.$tn { execsql { CREATE TABLE abc(a, b, c); } expr {[file size test.db]/2} | > > | | 558 559 560 561 562 563 564 565 566 567 568 569 570 571 | if {[regexp {^atomic} $char]} continue } do_test io-5.$tn { execsql { CREATE TABLE abc(a, b, c); } expr {[file size test.db]/2} list [file_page_count test.db] [file_page_size test.db] } [list 2 $pgsize] } sqlite3_simulate_device -char {} -sectorsize 0 finish_test |
Changes to test/jrnlmode.test.
︙ | ︙ | |||
517 518 519 520 521 522 523 | PRAGMA journal_mode = memory; PRAGMA auto_vacuum = 0; PRAGMA page_size = 1024; PRAGMA user_version = 5; PRAGMA user_version; } } {memory 5} | | > > | 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 | PRAGMA journal_mode = memory; PRAGMA auto_vacuum = 0; PRAGMA page_size = 1024; PRAGMA user_version = 5; PRAGMA user_version; } } {memory 5} do_test jrnlmode-7.2 { list [file_page_count test.db] [file_page_size test.db] } {1 1024} } do_execsql_test jrnlmode-8.1 { PRAGMA locking_mode=EXCLUSIVE } {exclusive} do_execsql_test jrnlmode-8.2 { CREATE TABLE t1(x) } {} do_execsql_test jrnlmode-8.3 { INSERT INTO t1 VALUES(123) } {} do_execsql_test jrnlmode-8.4 { SELECT * FROM t1 } {123} do_execsql_test jrnlmode-8.5 { PRAGMA journal_mode=PERSIST } {persist} |
︙ | ︙ |
Changes to test/lock4.test.
︙ | ︙ | |||
29 30 31 32 33 34 35 | forcedelete test2.db test2.db-journal sqlite3 db2 test2.db db2 eval { PRAGMA auto_vacuum=OFF; CREATE TABLE t2(x) } db2 close | | | | 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | forcedelete test2.db test2.db-journal sqlite3 db2 test2.db db2 eval { PRAGMA auto_vacuum=OFF; CREATE TABLE t2(x) } db2 close list [file_page_count test.db] [file_page_count test2.db] } {2 2} # Create a script to drive a separate process that will # # 1. Create a second database test2.db # 2. Get an exclusive lock on test2.db # 3. Add an entry to test.db in table t1, waiting as necessary. # 4. Commit the change to test2.db. |
︙ | ︙ |
Changes to test/mallocH.test.
︙ | ︙ | |||
58 59 60 61 62 63 64 65 66 67 68 69 70 71 | EXPLAIN QUERY PLAN SELECT * FROM abc AS t2 WHERE rowid=1; } } # Malloc failure during integrity_check pragma. # do_malloc_test mallocH-5 -sqlprep { CREATE TABLE t1(a PRIMARY KEY, b UNIQUE); CREATE TABLE t2(x,y); INSERT INTO t1 VALUES(1,2); INSERT INTO t2 SELECT * FROM t1; } -sqlbody { PRAGMA integrity_check; } | > | 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | EXPLAIN QUERY PLAN SELECT * FROM abc AS t2 WHERE rowid=1; } } # Malloc failure during integrity_check pragma. # do_malloc_test mallocH-5 -sqlprep { PRAGMA mmap_limit = 0; CREATE TABLE t1(a PRIMARY KEY, b UNIQUE); CREATE TABLE t2(x,y); INSERT INTO t1 VALUES(1,2); INSERT INTO t2 SELECT * FROM t1; } -sqlbody { PRAGMA integrity_check; } |
︙ | ︙ |
Changes to test/pager1.test.
︙ | ︙ | |||
1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 | #------------------------------------------------------------------------- # The following tests work with "PRAGMA max_page_count" # do_test pager1-6.1 { faultsim_delete_and_reopen execsql { PRAGMA auto_vacuum = none; PRAGMA max_page_count = 10; CREATE TABLE t2(a, b); CREATE TABLE t3(a, b); CREATE TABLE t4(a, b); CREATE TABLE t5(a, b); CREATE TABLE t6(a, b); | > | 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 | #------------------------------------------------------------------------- # The following tests work with "PRAGMA max_page_count" # do_test pager1-6.1 { faultsim_delete_and_reopen execsql { PRAGMA page_size = 4096; PRAGMA auto_vacuum = none; PRAGMA max_page_count = 10; CREATE TABLE t2(a, b); CREATE TABLE t3(a, b); CREATE TABLE t4(a, b); CREATE TABLE t5(a, b); CREATE TABLE t6(a, b); |
︙ | ︙ | |||
1353 1354 1355 1356 1357 1358 1359 | B step 30 list [B step 10000] [B finish] } {SQLITE_DONE SQLITE_OK} do_test pager1-9.3.3 { db2 close db close tv delete | | | | 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 | B step 30 list [B step 10000] [B finish] } {SQLITE_DONE SQLITE_OK} do_test pager1-9.3.3 { db2 close db close tv delete file_page_count test.db2 } [file_page_count test.db] do_test pager1-9.4.1 { faultsim_delete_and_reopen sqlite3 db2 test.db2 execsql { PRAGMA page_size = 4096; CREATE TABLE t1(a, b); |
︙ | ︙ | |||
1467 1468 1469 1470 1471 1472 1473 | file size test.db } {32768} do_test pager1.10.x.2 { execsql { CREATE TABLE t2(x); DROP TABLE t2; } | | | | 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 | file size test.db } {32768} do_test pager1.10.x.2 { execsql { CREATE TABLE t2(x); DROP TABLE t2; } list [file_page_count test.db] [file_page_size test.db] } {33 1024} do_test pager1.10.x.3 { execsql { BEGIN; CREATE TABLE t2(x); } recursive_select 30 t1 execsql { |
︙ | ︙ | |||
1548 1549 1550 1551 1552 1553 1554 | do_test pager1-12.$pagesize.1 { sqlite3 db2 test.db execsql " PRAGMA page_size = $pagesize; CREATE VIEW v AS SELECT * FROM sqlite_master; " db2 | | | 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 | do_test pager1-12.$pagesize.1 { sqlite3 db2 test.db execsql " PRAGMA page_size = $pagesize; CREATE VIEW v AS SELECT * FROM sqlite_master; " db2 file_page_size test.db } $eff do_test pager1-12.$pagesize.2 { sqlite3 db2 test.db execsql { SELECT count(*) FROM v; PRAGMA main.page_size; } db2 |
︙ | ︙ | |||
2384 2385 2386 2387 2388 2389 2390 | execsql { PRAGMA page_size = 1024; PRAGMA auto_vacuum = full; PRAGMA locking_mode=exclusive; CREATE TABLE t1(a, b); INSERT INTO t1 VALUES(1, 2); } | | | | | | 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 | execsql { PRAGMA page_size = 1024; PRAGMA auto_vacuum = full; PRAGMA locking_mode=exclusive; CREATE TABLE t1(a, b); INSERT INTO t1 VALUES(1, 2); } list [file_page_count test.db] [file_page_size test.db] } {3 1024} do_test pager1-29.2 { execsql { PRAGMA page_size = 4096; VACUUM; } list [file_page_count test.db] [file_page_size test.db] } {3 4096} #------------------------------------------------------------------------- # Test that if an empty database file (size 0 bytes) is opened in # exclusive-locking mode, any journal file is deleted from the file-system # without being rolled back. And that the RESERVED lock obtained while # doing this is not released. # |
︙ | ︙ |
Changes to test/pagerfault.test.
︙ | ︙ | |||
1197 1198 1199 1200 1201 1202 1203 | } } -test { faultsim_test_result {0 {}} set contents [db eval {SELECT * FROM t1}] if {$contents != "1 2"} { error "Bad database contents ($contents)" } | > | | < > | | | 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 | } } -test { faultsim_test_result {0 {}} set contents [db eval {SELECT * FROM t1}] if {$contents != "1 2"} { error "Bad database contents ($contents)" } set nPg [file_page_count test.db] set pgsz [file_page_size test.db] if {$testrc!=0 && ($nPg!=3 || ($pgsz!=1024 && $pgsz!=4096))} { error "File should be 3 pages. Page size 1024 or 4096 bytes. Is $nPg/$pgsz." } if {$testrc==0 && ($nPg!=3 || $pgsz!=4096)} { error "File should be 3 pages. Page size 4096 bytes. Is $nPg/$pgsz." } } do_test pagerfault-27-pre { faultsim_delete_and_reopen db func a_string a_string execsql { |
︙ | ︙ |
Changes to test/pagesize.test.
︙ | ︙ | |||
111 112 113 114 115 116 117 | db close sqlite3 db test.db execsql { PRAGMA page_size } } $PGSZ do_test pagesize-2.$PGSZ.3 { | | | | 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 | db close sqlite3 db test.db execsql { PRAGMA page_size } } $PGSZ do_test pagesize-2.$PGSZ.3 { list [file_page_count test.db] [file_page_size test.db] } [list [expr ($AUTOVACUUM?3:2)] $PGSZ] ifcapable {vacuum} { do_test pagesize-2.$PGSZ.4 { execsql {VACUUM} } {} } integrity_check pagesize-2.$PGSZ.5 do_test pagesize-2.$PGSZ.6 { |
︙ | ︙ |
Changes to test/permutations.test.
︙ | ︙ | |||
164 165 166 167 168 169 170 | ] test_suite "full" -prefix "" -description { Full test suite. Takes a long time. } -files [ test_set $alltests ] -initialize { | | | 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 | ] test_suite "full" -prefix "" -description { Full test suite. Takes a long time. } -files [ test_set $alltests ] -initialize { # unset -nocomplain ::G(isquick) } test_suite "threads" -prefix "" -description { All multi-threaded tests. } -files { notify2.test thread001.test thread002.test thread003.test thread004.test thread005.test walthread.test |
︙ | ︙ |
Changes to test/pragma.test.
︙ | ︙ | |||
258 259 260 261 262 263 264 265 266 267 268 269 270 271 | # These tests won't work if the database is encrypted # do_test pragma-3.1 { db close forcedelete test.db test.db-journal sqlite3 db test.db execsql { PRAGMA auto_vacuum=OFF; BEGIN; CREATE TABLE t2(a,b,c); CREATE INDEX i2 ON t2(a); INSERT INTO t2 VALUES(11,2,3); INSERT INTO t2 VALUES(22,3,4); COMMIT; | > | 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 | # These tests won't work if the database is encrypted # do_test pragma-3.1 { db close forcedelete test.db test.db-journal sqlite3 db test.db execsql { PRAGMA mmap_limit=0; PRAGMA auto_vacuum=OFF; BEGIN; CREATE TABLE t2(a,b,c); CREATE INDEX i2 ON t2(a); INSERT INTO t2 VALUES(11,2,3); INSERT INTO t2 VALUES(22,3,4); COMMIT; |
︙ | ︙ | |||
280 281 282 283 284 285 286 287 288 289 290 291 292 293 | # overwrite the header on the rootpage of the index in order to # make the index appear to be empty. # set offset [expr {$pgsz*($rootpage-1)}] hexio_write test.db $offset 0a00000000040000000000 db close sqlite3 db test.db execsql {PRAGMA integrity_check} } {{rowid 1 missing from index i2} {rowid 2 missing from index i2} {wrong # of entries in index i2}} do_test pragma-3.3 { execsql {PRAGMA integrity_check=1} } {{rowid 1 missing from index i2}} do_test pragma-3.4 { execsql { | > | 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 | # overwrite the header on the rootpage of the index in order to # make the index appear to be empty. # set offset [expr {$pgsz*($rootpage-1)}] hexio_write test.db $offset 0a00000000040000000000 db close sqlite3 db test.db execsql {PRAGMA mmap_limit=0} execsql {PRAGMA integrity_check} } {{rowid 1 missing from index i2} {rowid 2 missing from index i2} {wrong # of entries in index i2}} do_test pragma-3.3 { execsql {PRAGMA integrity_check=1} } {{rowid 1 missing from index i2}} do_test pragma-3.4 { execsql { |
︙ | ︙ | |||
1247 1248 1249 1250 1251 1252 1253 | } {3} do_test pragma-14.3uc { execsql {pragma PAGE_COUNT} } {3} do_test pragma-14.4 { set page_size [db one {pragma page_size}] | | | | 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 | } {3} do_test pragma-14.3uc { execsql {pragma PAGE_COUNT} } {3} do_test pragma-14.4 { set page_size [db one {pragma page_size}] list [file_page_count test.db] $page_size } [list 2 [file_page_size test.db]] do_test pragma-14.5 { execsql { ROLLBACK; PRAGMA page_count; } } {2} |
︙ | ︙ |
Changes to test/pragma2.test.
︙ | ︙ | |||
82 83 84 85 86 87 88 | set ::val [string repeat 0123456789 1000] execsql { INSERT INTO aux.abc VALUES(1, 2, $::val); PRAGMA aux.freelist_count; } } {0} do_test pragma2-2.4 { | | | | 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 | set ::val [string repeat 0123456789 1000] execsql { INSERT INTO aux.abc VALUES(1, 2, $::val); PRAGMA aux.freelist_count; } } {0} do_test pragma2-2.4 { list [file_page_count test2.db] [file_page_size test2.db] } {11 1024} do_test pragma2-2.5 { execsql { DELETE FROM aux.abc; PRAGMA aux.freelist_count; } } {9} |
︙ | ︙ |
Changes to test/quota.test.
︙ | ︙ | |||
67 68 69 70 71 72 73 74 75 76 77 78 79 80 | do_test quota-2.1.1 { sqlite3_quota_set *test.db 4096 quota_check } {SQLITE_OK} do_test quota-2.1.2 { sqlite3 db test.db execsql { PRAGMA page_size=1024; PRAGMA auto_vacuum=OFF; PRAGMA journal_mode=DELETE; } set ::quota [list] execsql { CREATE TABLE t1(a, b); | > | 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 | do_test quota-2.1.1 { sqlite3_quota_set *test.db 4096 quota_check } {SQLITE_OK} do_test quota-2.1.2 { sqlite3 db test.db execsql { PRAGMA mmap_limit=0; PRAGMA page_size=1024; PRAGMA auto_vacuum=OFF; PRAGMA journal_mode=DELETE; } set ::quota [list] execsql { CREATE TABLE t1(a, b); |
︙ | ︙ | |||
139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 | forcedelete test.db sqlite3_quota_initialize "" 1 sqlite3_quota_set *test.db 4096 quota_check } {SQLITE_OK} do_test quota-3.1.2 { sqlite3 db test.db execsql { PRAGMA page_size = 1024; PRAGMA journal_mode = delete; PRAGMA auto_vacuum = off; CREATE TABLE t1(a PRIMARY KEY, b); INSERT INTO t1 VALUES(1, 'one'); } file size test.db } {3072} do_test quota-3.1.3 { sqlite3 db2 test.db set ::quota [list] execsql { CREATE TABLE t2(a, b) } db2 set ::quota } {} do_test quota-3.1.4 { catchsql { CREATE TABLE t3(a, b) } } {1 {database or disk is full}} do_test quota-3.1.5 { | > > | 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 | forcedelete test.db sqlite3_quota_initialize "" 1 sqlite3_quota_set *test.db 4096 quota_check } {SQLITE_OK} do_test quota-3.1.2 { sqlite3 db test.db execsql { PRAGMA mmap_limit = 0; PRAGMA page_size = 1024; PRAGMA journal_mode = delete; PRAGMA auto_vacuum = off; CREATE TABLE t1(a PRIMARY KEY, b); INSERT INTO t1 VALUES(1, 'one'); } file size test.db } {3072} do_test quota-3.1.3 { sqlite3 db2 test.db set ::quota [list] execsql { PRAGMA mmap_limit=0 } db2 execsql { CREATE TABLE t2(a, b) } db2 set ::quota } {} do_test quota-3.1.4 { catchsql { CREATE TABLE t3(a, b) } } {1 {database or disk is full}} do_test quota-3.1.5 { |
︙ | ︙ | |||
175 176 177 178 179 180 181 182 183 184 185 186 187 188 | sqlite3_quota_set * 4096 {} sqlite3 db1a test.db sqlite3 db2a test2.db foreach db {db1a db2a} { execsql { PRAGMA page_size = 1024; PRAGMA journal_mode = delete; PRAGMA auto_vacuum = off; CREATE TABLE t1(a, b); } $db } | > | 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 | sqlite3_quota_set * 4096 {} sqlite3 db1a test.db sqlite3 db2a test2.db foreach db {db1a db2a} { execsql { PRAGMA mmap_limit=0; PRAGMA page_size = 1024; PRAGMA journal_mode = delete; PRAGMA auto_vacuum = off; CREATE TABLE t1(a, b); } $db } |
︙ | ︙ |
Changes to test/sqllimits1.test.
︙ | ︙ | |||
530 531 532 533 534 535 536 | INSERT INTO abc SELECT a||b||c, b||c||a, c||a||b FROM abc; INSERT INTO abc SELECT a||b||c, b||c||a, c||a||b FROM abc; INSERT INTO abc SELECT a||b||c, b||c||a, c||a||b FROM abc; INSERT INTO abc SELECT a, b, c FROM abc; INSERT INTO abc SELECT b, a, c FROM abc; INSERT INTO abc SELECT c, b, a FROM abc; } | | | | 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 | INSERT INTO abc SELECT a||b||c, b||c||a, c||a||b FROM abc; INSERT INTO abc SELECT a||b||c, b||c||a, c||a||b FROM abc; INSERT INTO abc SELECT a||b||c, b||c||a, c||a||b FROM abc; INSERT INTO abc SELECT a, b, c FROM abc; INSERT INTO abc SELECT b, a, c FROM abc; INSERT INTO abc SELECT c, b, a FROM abc; } file_page_count test.db } $fsize do_test sqllimits1-7.7.2 { db close sqlite3 db test.db execsql { PRAGMA max_page_count = 1000; } execsql { SELECT count(*) FROM sqlite_master; } } {6} do_test sqllimits1-7.7.3 { execsql { PRAGMA max_page_count; } } [expr [file size test.db] / 1024] do_test sqllimits1-7.7.4 { execsql { DROP TABLE abc; } } {} #-------------------------------------------------------------------- |
︙ | ︙ |
Changes to test/tester.tcl.
︙ | ︙ | |||
1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 | # to the values they held before the SQL was executed. This simulates # a write by a pre-3.7.0 client. # proc sql36231 {sql} { set B [hexio_read test.db 92 8] set A [hexio_read test.db 28 4] sqlite3 db36231 test.db catch { db36231 func a_string a_string } execsql $sql db36231 db36231 close hexio_write test.db 28 $A hexio_write test.db 92 $B return "" } | > | 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 | # to the values they held before the SQL was executed. This simulates # a write by a pre-3.7.0 client. # proc sql36231 {sql} { set B [hexio_read test.db 92 8] set A [hexio_read test.db 28 4] sqlite3 db36231 test.db db36231 eval { PRAGMA mmap_limit = 0 } catch { db36231 func a_string a_string } execsql $sql db36231 db36231 close hexio_write test.db 28 $A hexio_write test.db 92 $B return "" } |
︙ | ︙ | |||
1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 | sqlite3 db $dbfile } proc db_delete_and_reopen {{file test.db}} { catch { db close } foreach f [glob -nocomplain test.db*] { forcedelete $f } sqlite3 db $file } # If the library is compiled with the SQLITE_DEFAULT_AUTOVACUUM macro set # to non-zero, then set the global variable $AUTOVACUUM to 1. set AUTOVACUUM $sqlite_options(default_autovacuum) # Make sure the FTS enhanced query syntax is disabled. set sqlite_fts3_enable_parentheses 0 source $testdir/thread_common.tcl source $testdir/malloc_common.tcl | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 | sqlite3 db $dbfile } proc db_delete_and_reopen {{file test.db}} { catch { db close } foreach f [glob -nocomplain test.db*] { forcedelete $f } sqlite3 db $file } # Return the number of pages in the database file $zFile, according to # the database header. # proc file_page_count {zFile} { set nPg [hexio_get_int [hexio_read $zFile 28 4]] set pgsz [file_page_size $zFile] set filesz [file size $zFile] set syspgsz 4096 # Check that the file size is consistent with the database page size, # the page count, and the system page size. if {($filesz < ($nPg * $pgsz)) || ($filesz > (((($nPg * $pgsz)+$syspgsz-1) / $syspgsz) * $syspgsz)) } { error "file_size=$filesz. page_count=$nPg. page_size=$pgsz." } return $nPg } # Return the page size of database file $zFile, according to the database # header. # proc file_page_size {zFile} { set pgsz [hexio_get_int [hexio_read $zFile 16 2]] if {$pgsz==1} {set pgsz 65536} return $pgsz } # If the library is compiled with the SQLITE_DEFAULT_AUTOVACUUM macro set # to non-zero, then set the global variable $AUTOVACUUM to 1. set AUTOVACUUM $sqlite_options(default_autovacuum) # Make sure the FTS enhanced query syntax is disabled. set sqlite_fts3_enable_parentheses 0 source $testdir/thread_common.tcl source $testdir/malloc_common.tcl |
Changes to test/tkt1512.test.
︙ | ︙ | |||
31 32 33 34 35 36 37 | CREATE TABLE t1(a,b); INSERT INTO t1 VALUES(1,2); INSERT INTO t1 VALUES(3,4); SELECT * FROM t1 } } {1 2 3 4} do_test tkt1512-1.2 { | | | | | | | | 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | CREATE TABLE t1(a,b); INSERT INTO t1 VALUES(1,2); INSERT INTO t1 VALUES(3,4); SELECT * FROM t1 } } {1 2 3 4} do_test tkt1512-1.2 { file_page_count test.db } {2} do_test tkt1512-1.3 { execsql { DROP TABLE t1; } file_page_count test.db } {2} do_test tkt1512-1.4 { execsql { VACUUM; } file_page_count test.db } {1} finish_test |
Changes to test/tkt2920.test.
︙ | ︙ | |||
22 23 24 25 26 27 28 | do_test tkt2920-1.1 { db eval { PRAGMA page_size=1024; PRAGMA max_page_count=40; PRAGMA auto_vacuum=0; CREATE TABLE filler (fill); } | | | | 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | do_test tkt2920-1.1 { db eval { PRAGMA page_size=1024; PRAGMA max_page_count=40; PRAGMA auto_vacuum=0; CREATE TABLE filler (fill); } list [file_page_count test.db] [file_page_size test.db] } {2 1024} do_test tkt2920-1.2 { db eval BEGIN for {set i 0} {$i<34} {incr i} { db eval {INSERT INTO filler VALUES(randomblob(1024))} } db eval COMMIT } {} |
︙ | ︙ |
Changes to test/vacuum3.test.
︙ | ︙ | |||
38 39 40 41 42 43 44 | INSERT INTO t1 VALUES(1, 2, 3); } } {} do_test vacuum3-1.2 { execsql { PRAGMA page_size } } {1024} do_test vacuum3-1.3 { | | | | > | | | 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 | INSERT INTO t1 VALUES(1, 2, 3); } } {} do_test vacuum3-1.2 { execsql { PRAGMA page_size } } {1024} do_test vacuum3-1.3 { file_page_count test.db } {2} set I 4 foreach {request actual database} [list \ 2048 2048 4096 \ 1024 1024 2048 \ 1170 1024 2048 \ 256 1024 2048 \ 512 512 1024 \ 4096 4096 8192 \ 1024 1024 2048 \ ] { do_test vacuum3-1.$I.1 { execsql " PRAGMA page_size = $request; VACUUM; " execsql { PRAGMA page_size } } $actual do_test vacuum3-1.$I.2 { set nPg [file_page_count test.db] expr {$nPg * $actual} } $database do_test vacuum3-1.$I.3 { execsql { SELECT * FROM t1 } } {1 2 3} integrity_check vacuum3-1.$I.4 incr I } #------------------------------------------------------------------- # Test cases vacuum3-2.* convert a simple 3-page database between a # few different page sizes. # do_test vacuum3-2.1 { execsql { PRAGMA page_size = 1024; VACUUM; ALTER TABLE t1 ADD COLUMN d; UPDATE t1 SET d = randomblob(1000); } file_page_count test.db } {3} do_test vacuum3-2.2 { execsql { PRAGMA page_size } } {1024} do_test vacuum3-2.3 { set blob [db one {select d from t1}] string length $blob } {1000} |
︙ | ︙ |
Changes to test/wal.test.
︙ | ︙ | |||
63 64 65 66 67 68 69 | # do_test wal-0.1 { execsql { PRAGMA auto_vacuum = 0 } execsql { PRAGMA synchronous = normal } execsql { PRAGMA journal_mode = wal } } {wal} do_test wal-0.2 { | | | | | | 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 | # do_test wal-0.1 { execsql { PRAGMA auto_vacuum = 0 } execsql { PRAGMA synchronous = normal } execsql { PRAGMA journal_mode = wal } } {wal} do_test wal-0.2 { file_page_count test.db } {1} do_test wal-1.0 { execsql { BEGIN; CREATE TABLE t1(a, b); } list [file exists test.db-journal] \ [file exists test.db-wal] \ [file_page_count test.db] } {0 1 1} do_test wal-1.1 { execsql COMMIT list [file exists test.db-journal] [file exists test.db-wal] } {0 1} do_test wal-1.2 { # There are now two pages in the log. file size test.db-wal |
︙ | ︙ | |||
343 344 345 346 347 348 349 | PRAGMA journal_mode = wal; " execsql " CREATE TABLE t1(a, b); INSERT INTO t1 VALUES(1, 2); " db close | | | > > | | > > | | | 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 | PRAGMA journal_mode = wal; " execsql " CREATE TABLE t1(a, b); INSERT INTO t1 VALUES(1, 2); " db close list [file_page_count test.db] [file_page_size test.db] } [list 2 $pgsz] do_test wal-6.$sector.$pgsz.2 { log_deleted test.db-wal } {1} } } do_test wal-7.1 { forcedelete test.db test.db-wal sqlite3_wal db test.db execsql { PRAGMA page_size = 1024; CREATE TABLE t1(a, b); INSERT INTO t1 VALUES(1, 2); } list [file_page_count test.db] \ [file_page_size test.db] \ [file size test.db-wal] } [list 1 1024 [wal_file_size 3 1024]] do_test wal-7.2 { execsql { PRAGMA wal_checkpoint } list [file_page_count test.db] \ [file_page_size test.db] \ [file size test.db-wal] } [list 2 1024 [wal_file_size 3 1024]] # Execute some transactions in auto-vacuum mode to test database file # truncation. # do_test wal-8.1 { reopen_db catch { db close } |
︙ | ︙ | |||
424 425 426 427 428 429 430 | INSERT INTO t1 SELECT blob(900) FROM t1; /* 8 */ INSERT INTO t1 SELECT blob(900) FROM t1; /* 16 */ INSERT INTO t1 SELECT blob(900) FROM t1; /* 32 */ INSERT INTO t1 SELECT blob(900) FROM t1; /* 64 */ INSERT INTO t1 SELECT blob(900) FROM t1; /* 128 */ INSERT INTO t1 SELECT blob(900) FROM t1; /* 256 */ } | | | | 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 | INSERT INTO t1 SELECT blob(900) FROM t1; /* 8 */ INSERT INTO t1 SELECT blob(900) FROM t1; /* 16 */ INSERT INTO t1 SELECT blob(900) FROM t1; /* 32 */ INSERT INTO t1 SELECT blob(900) FROM t1; /* 64 */ INSERT INTO t1 SELECT blob(900) FROM t1; /* 128 */ INSERT INTO t1 SELECT blob(900) FROM t1; /* 256 */ } file_page_count test.db } 1 do_test wal-9.2 { sqlite3_wal db2 test.db execsql {PRAGMA integrity_check } db2 } {ok} do_test wal-9.3 { forcedelete test2.db test2.db-wal |
︙ | ︙ | |||
677 678 679 680 681 682 683 | do_test wal-11.1 { reopen_db execsql { PRAGMA cache_size = 10; PRAGMA page_size = 1024; CREATE TABLE t1(x PRIMARY KEY); } | | | | | | | | | | | | | | | 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 | do_test wal-11.1 { reopen_db execsql { PRAGMA cache_size = 10; PRAGMA page_size = 1024; CREATE TABLE t1(x PRIMARY KEY); } list [file_page_count test.db] [expr [file size test.db-wal]/1044] } {1 3} do_test wal-11.2 { execsql { PRAGMA wal_checkpoint } list [file_page_count test.db] [file size test.db-wal] } [list 3 [wal_file_size 3 1024]] do_test wal-11.3 { execsql { INSERT INTO t1 VALUES( blob(900) ) } list [file_page_count test.db] [file size test.db-wal] } [list 3 [wal_file_size 4 1024]] do_test wal-11.4 { execsql { BEGIN; INSERT INTO t1 SELECT blob(900) FROM t1; -- 2 INSERT INTO t1 SELECT blob(900) FROM t1; -- 4 INSERT INTO t1 SELECT blob(900) FROM t1; -- 8 INSERT INTO t1 SELECT blob(900) FROM t1; -- 16 } list [file_page_count test.db] [file size test.db-wal] } [list 3 [wal_file_size 32 1024]] do_test wal-11.5 { execsql { SELECT count(*) FROM t1; PRAGMA integrity_check; } } {16 ok} do_test wal-11.6 { execsql COMMIT list [file_page_count test.db] [file size test.db-wal] } [list 3 [wal_file_size 41 1024]] do_test wal-11.7 { execsql { SELECT count(*) FROM t1; PRAGMA integrity_check; } } {16 ok} do_test wal-11.8 { execsql { PRAGMA wal_checkpoint } list [file_page_count test.db] [file size test.db-wal] } [list 37 [wal_file_size 41 1024]] do_test wal-11.9 { db close list [file_page_count test.db] [log_deleted test.db-wal] } {37 1} sqlite3_wal db test.db set nWal 39 if {[permutation]=="nommap"} {set nWal 37} do_test wal-11.10 { execsql { PRAGMA cache_size = 10; BEGIN; INSERT INTO t1 SELECT blob(900) FROM t1; -- 32 SELECT count(*) FROM t1; } list [file_page_count test.db] [file size test.db-wal] } [list 37 [wal_file_size $nWal 1024]] do_test wal-11.11 { execsql { SELECT count(*) FROM t1; ROLLBACK; SELECT count(*) FROM t1; } } {32 16} do_test wal-11.12 { list [file_page_count test.db] [file size test.db-wal] } [list 37 [wal_file_size $nWal 1024]] do_test wal-11.13 { execsql { INSERT INTO t1 VALUES( blob(900) ); SELECT count(*) FROM t1; PRAGMA integrity_check; } } {17 ok} do_test wal-11.14 { list [file_page_count test.db] [file size test.db-wal] } [list 37 [wal_file_size $nWal 1024]] #------------------------------------------------------------------------- # This block of tests, wal-12.*, tests the fix for a problem that # could occur if a log that is a prefix of an older log is written # into a reused log file. # reopen_db do_test wal-12.1 { execsql { PRAGMA page_size = 1024; CREATE TABLE t1(x, y); CREATE TABLE t2(x, y); INSERT INTO t1 VALUES('A', 1); } list [file_page_count test.db] [file size test.db-wal] } [list 1 [wal_file_size 5 1024]] do_test wal-12.2 { db close sqlite3 db test.db execsql { PRAGMA synchronous = normal; UPDATE t1 SET y = 0 WHERE x = 'A'; } list [file_page_count test.db] [expr [file size test.db-wal]/1044] } {3 1} do_test wal-12.3 { execsql { INSERT INTO t2 VALUES('B', 1) } list [file_page_count test.db] [expr [file size test.db-wal]/1044] } {3 2} do_test wal-12.4 { forcecopy test.db test2.db forcecopy test.db-wal test2.db-wal sqlite3_wal db2 test2.db execsql { SELECT * FROM t2 } db2 } {B 1} |
︙ | ︙ | |||
847 848 849 850 851 852 853 | set fd [open test.db-wal w] seek $fd [expr 200*1024*1024] puts $fd "" close $fd sqlite3 db test.db execsql { SELECT * FROM t2 } } {B 2} | < | 851 852 853 854 855 856 857 858 859 860 861 862 863 864 | set fd [open test.db-wal w] seek $fd [expr 200*1024*1024] puts $fd "" close $fd sqlite3 db test.db execsql { SELECT * FROM t2 } } {B 2} do_test wal-13.1.3 { db close file exists test.db-wal } {0} do_test wal-13.2.1 { sqlite3 db test.db |
︙ | ︙ | |||
1018 1019 1020 1021 1022 1023 1024 | execsql { COMMIT } db2 sqlite3_wal_checkpoint db } {SQLITE_OK} do_test wal-15.4.5 { sqlite3_errmsg db } {not an error} do_test wal-15.4.6 { | | | | 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 | execsql { COMMIT } db2 sqlite3_wal_checkpoint db } {SQLITE_OK} do_test wal-15.4.5 { sqlite3_errmsg db } {not an error} do_test wal-15.4.6 { list [file_page_count test.db] [file_page_size test.db] } {2 1024} catch { db2 close } catch { db close } #------------------------------------------------------------------------- # The following block of tests - wal-16.* - test that if a NULL pointer or # an empty string is passed as the second argument of the wal_checkpoint() |
︙ | ︙ | |||
1067 1068 1069 1070 1071 1072 1073 | CREATE TABLE aux.t2(a, b, PRIMARY KEY(a, b)); INSERT INTO t2 VALUES(1, randomblob(1000)); INSERT INTO t2 VALUES(2, randomblob(1000)); INSERT INTO t1 SELECT * FROM t2; } | | | | | | | | | | 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 | CREATE TABLE aux.t2(a, b, PRIMARY KEY(a, b)); INSERT INTO t2 VALUES(1, randomblob(1000)); INSERT INTO t2 VALUES(2, randomblob(1000)); INSERT INTO t1 SELECT * FROM t2; } list [file_page_count test.db] [file size test.db-wal] } [list 1 [wal_file_size 10 1024]] do_test wal-16.$tn.3 { list [file_page_count test2.db] [file size test2.db-wal] } [list 1 [wal_file_size 13 1024]] do_test wal-16.$tn.4 [list eval $ckpt_cmd] $ckpt_res do_test wal-16.$tn.5 { list [file_page_count test.db] [file size test.db-wal] } [list [expr ($ckpt_main ? 7 : 1)] [wal_file_size 10 1024]] do_test wal-16.$tn.6 { list [file_page_count test2.db] [file size test2.db-wal] } [list [expr ($ckpt_aux ? 7 : 1)] [wal_file_size 13 1024]] catch { db close } } #------------------------------------------------------------------------- # The following tests - wal-17.* - attempt to verify that the correct # number of "padding" frames are appended to the log file when a transaction |
︙ | ︙ | |||
1141 1142 1143 1144 1145 1146 1147 | } execsql COMMIT file size test.db-wal } $logsize do_test wal-17.$tn.2 { | | | | | | 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 | } execsql COMMIT file size test.db-wal } $logsize do_test wal-17.$tn.2 { file_page_count test.db } 1 do_test wal-17.$tn.3 { db close file_page_count test.db } 171 } sqlite3_test_control_pending_byte $old_pending_byte #------------------------------------------------------------------------- # This test - wal-18.* - verifies a couple of specific conditions that # may be encountered while recovering a log file are handled correctly: # |
︙ | ︙ | |||
1182 1183 1184 1185 1186 1187 1188 | INSERT INTO t1 VALUES(3, 4); -- frames 3 and 4 INSERT INTO t1 VALUES(5, 6); -- frames 5 and 6 } forcecopy test.db testX.db forcecopy test.db-wal testX.db-wal db close | | | | 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 | INSERT INTO t1 VALUES(3, 4); -- frames 3 and 4 INSERT INTO t1 VALUES(5, 6); -- frames 5 and 6 } forcecopy test.db testX.db forcecopy test.db-wal testX.db-wal db close list [file_page_count testX.db] [file size testX.db-wal] } [list 3 [wal_file_size 6 1024]] unset -nocomplain nFrame result foreach {nFrame result} { 0 {0 0} 1 {0 0} 2 {0 0 1 2} 3 {0 0 1 2} |
︙ | ︙ | |||
1263 1264 1265 1266 1267 1268 1269 | forcedelete test.db-wal # Check that the database now exists and consists of three pages. And # that there is no associated wal file. # do_test wal-18.2.$tn.$pg.1 { file exists test.db-wal } 0 do_test wal-18.2.$tn.$pg.2 { file exists test.db } 1 | | | 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 | forcedelete test.db-wal # Check that the database now exists and consists of three pages. And # that there is no associated wal file. # do_test wal-18.2.$tn.$pg.1 { file exists test.db-wal } 0 do_test wal-18.2.$tn.$pg.2 { file exists test.db } 1 do_test wal-18.2.$tn.$pg.3 { file_page_count test.db } 3 do_test wal-18.2.$tn.$pg.4 { # Create a wal file that contains a single frame (database page # number $pg) with the commit flag set. The frame checksum is # correct, but the contents of the database page are corrupt. # |
︙ | ︙ | |||
1505 1506 1507 1508 1509 1510 1511 | } {1 2 3 4} do_test wal-23.2 { set ::log } {} do_test wal-23.3 { db close set ::log [list] faultsim_restore_and_reopen | | | | 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 | } {1 2 3 4} do_test wal-23.2 { set ::log } {} do_test wal-23.3 { db close set ::log [list] faultsim_restore_and_reopen execsql { SELECT * FROM t1 ; PRAGMA page_size } } {1 2 3 4 1024} set nPage [expr 2+$AUTOVACUUM] do_test wal-23.4 { set ::log } [list SQLITE_OK "Recovered $nPage frames from WAL file $walfile"] ifcapable autovacuum { |
︙ | ︙ |
Changes to test/wal5.test.
︙ | ︙ | |||
17 18 19 20 21 22 23 | source $testdir/tester.tcl source $testdir/lock_common.tcl source $testdir/wal_common.tcl ifcapable !wal {finish_test ; return } set testprefix wal5 | | | 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | source $testdir/tester.tcl source $testdir/lock_common.tcl source $testdir/wal_common.tcl ifcapable !wal {finish_test ; return } set testprefix wal5 proc db_page_count {{file test.db}} { file_page_count $file } proc wal_page_count {{file test.db}} { wal_frame_count ${file}-wal 1024 } # A checkpoint may be requested either using the C API or by executing # an SQL PRAGMA command. To test both methods, all tests in this file are # run twice - once using each method to request checkpoints. # |
︙ | ︙ | |||
97 98 99 100 101 102 103 | PRAGMA auto_vacuum = 0; CREATE TABLE t1(x, y); PRAGMA journal_mode = WAL; INSERT INTO t1 VALUES(1, zeroblob(1200)); INSERT INTO t1 VALUES(2, zeroblob(1200)); INSERT INTO t1 VALUES(3, zeroblob(1200)); } | | | | 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 | PRAGMA auto_vacuum = 0; CREATE TABLE t1(x, y); PRAGMA journal_mode = WAL; INSERT INTO t1 VALUES(1, zeroblob(1200)); INSERT INTO t1 VALUES(2, zeroblob(1200)); INSERT INTO t1 VALUES(3, zeroblob(1200)); } list [file_page_count test.db] [file_page_size test.db] } {2 1024} # Have connection 2 grab a read-lock on the current snapshot. do_test 1.$tn.2 { sql2 { BEGIN; SELECT x FROM t1 } } {1 2 3} # Attempt a checkpoint. do_test 1.$tn.3 { code1 { do_wal_checkpoint db } |
︙ | ︙ |
Changes to test/wal9.test.
︙ | ︙ | |||
59 60 61 62 63 64 65 | } {} # Check file sizes are as expected. The real requirement here is that # the *shm file is now more than one chunk (>32KiB). # # The sizes of various files are slightly different in normal and # auto-vacuum mode. | | | 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | } {} # Check file sizes are as expected. The real requirement here is that # the *shm file is now more than one chunk (>32KiB). # # The sizes of various files are slightly different in normal and # auto-vacuum mode. do_test 1.3 { file_page_count test.db } {1} do_test 1.4 { expr {[file size test.db-wal]>(1500*1024)} } {1} do_test 1.5 { expr {[file size test.db-shm]>32768} } {1} do_test 1.6 { foreach {a b c} [db eval {PRAGMA wal_checkpoint}] break list [expr {$a==0}] [expr {$b>14500}] [expr {$c>14500}] [expr {$b==$c}] } {1 1 1 1} |
︙ | ︙ |
Changes to test/walbak.test.
︙ | ︙ | |||
46 47 48 49 50 51 52 | INSERT INTO t1 VALUES('I', 'one'); COMMIT; } } {wal} do_test walbak-1.1 { forcedelete bak.db bak.db-journal bak.db-wal db backup bak.db | | | | 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | INSERT INTO t1 VALUES('I', 'one'); COMMIT; } } {wal} do_test walbak-1.1 { forcedelete bak.db bak.db-journal bak.db-wal db backup bak.db file_page_count bak.db } 3 do_test walbak-1.2 { sqlite3 db2 bak.db execsql { SELECT * FROM t1; PRAGMA main.journal_mode; } db2 } {I one wal} |
︙ | ︙ | |||
69 70 71 72 73 74 75 | do_test walbak-1.4 { execsql { VACUUM; PRAGMA main.journal_mode; } } {wal} do_test walbak-1.5 { | | | | 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 | do_test walbak-1.4 { execsql { VACUUM; PRAGMA main.journal_mode; } } {wal} do_test walbak-1.5 { list [file_page_count test.db] [file size test.db-wal] } [list 1 [wal_file_size 6 1024]] do_test walbak-1.6 { execsql { PRAGMA wal_checkpoint } list [file size test.db] [file size test.db-wal] } [list [expr 3*1024] [wal_file_size 6 1024]] do_test walbak-1.6.1 { hexio_read test.db 18 2 } {0202} |
︙ | ︙ |
Changes to test/walcksum.test.
︙ | ︙ | |||
172 173 174 175 176 177 178 | INSERT INTO t1 VALUES(21, 'twentyone'); } forcecopy test.db test2.db forcecopy test.db-wal test2.db-wal db close | | | | 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 | INSERT INTO t1 VALUES(21, 'twentyone'); } forcecopy test.db test2.db forcecopy test.db-wal test2.db-wal db close list [file_page_count test2.db] [file size test2.db-wal] } [list 3 [wal_file_size 6 1024]] # Verify that the checksums are valid for all frames and that they # are calculated by interpreting data in native byte-order. # for {set f 1} {$f <= 6} {incr f} { do_test walcksum-1.$endian.2.$f { log_checksum_verify test2.db-wal $f $native |
︙ | ︙ | |||
209 210 211 212 213 214 215 | # endianness as the existing frames. Check that this is the case. # do_test walcksum-1.$endian.5.0 { execsql { PRAGMA synchronous = NORMAL; INSERT INTO t1 VALUES(34, 'thirtyfour'); } | | | | 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 | # endianness as the existing frames. Check that this is the case. # do_test walcksum-1.$endian.5.0 { execsql { PRAGMA synchronous = NORMAL; INSERT INTO t1 VALUES(34, 'thirtyfour'); } list [file_page_count test.db] [file size test.db-wal] } [list 3 [wal_file_size 8 1024]] for {set f 1} {$f <= 8} {incr f} { do_test walcksum-1.$endian.5.$f { log_checksum_verify test.db-wal $f $endian } {1} } # Now connect a second connection to the database. Check that this one |
︙ | ︙ | |||
233 234 235 236 237 238 239 | } db2 } {ok 1 2 3 5 8 13 21 34} do_test walcksum-1.$endian.7.0 { execsql { PRAGMA synchronous = NORMAL; INSERT INTO t1 VALUES(55, 'fiftyfive'); } db2 | | | | 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 | } db2 } {ok 1 2 3 5 8 13 21 34} do_test walcksum-1.$endian.7.0 { execsql { PRAGMA synchronous = NORMAL; INSERT INTO t1 VALUES(55, 'fiftyfive'); } db2 list [file_page_count test.db] [file size test.db-wal] } [list 3 [wal_file_size 10 1024]] for {set f 1} {$f <= 10} {incr f} { do_test walcksum-1.$endian.7.$f { log_checksum_verify test.db-wal $f $endian } {1} } # Now that both the recoverer and non-recoverer have added frames to the |
︙ | ︙ |
Changes to test/walhook.test.
︙ | ︙ | |||
45 46 47 48 49 50 51 | set ::wal_hook [list] execsql { INSERT INTO t1 VALUES(1, 'one') } set ::wal_hook } {main 5} do_test walhook-1.3 { proc wal_hook {args} { db eval {PRAGMA wal_checkpoint}; return 0 } execsql { INSERT INTO t1 VALUES(2, 'two') } | | | | 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | set ::wal_hook [list] execsql { INSERT INTO t1 VALUES(1, 'one') } set ::wal_hook } {main 5} do_test walhook-1.3 { proc wal_hook {args} { db eval {PRAGMA wal_checkpoint}; return 0 } execsql { INSERT INTO t1 VALUES(2, 'two') } file_page_count test.db } 3 do_test walhook-1.4 { proc wal_hook {zDb nEntry} { execsql { PRAGMA wal_checkpoint } return 0 } execsql { CREATE TABLE t2(a, b) } file size test.db |
︙ | ︙ |
Changes to test/walmode.test.
︙ | ︙ | |||
38 39 40 41 42 43 44 | do_test walmode-1.1 { set sqlite_sync_count 0 execsql { PRAGMA page_size = 1024 } execsql { PRAGMA journal_mode = wal } } {wal} do_test walmode-1.2 { | | | | | | 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | do_test walmode-1.1 { set sqlite_sync_count 0 execsql { PRAGMA page_size = 1024 } execsql { PRAGMA journal_mode = wal } } {wal} do_test walmode-1.2 { file_page_count test.db } {1} set expected_sync_count 3 if {$::tcl_platform(platform)!="windows"} { ifcapable dirsync { incr expected_sync_count } } do_test walmode-1.3 { set sqlite_sync_count } $expected_sync_count do_test walmode-1.4 { file exists test.db-wal } {0} do_test walmode-1.5 { execsql { CREATE TABLE t1(a, b) } file_page_count test.db } {1} do_test walmode-1.6 { file exists test.db-wal } {1} do_test walmode-1.7 { db close file exists test.db-wal } {0} |
︙ | ︙ |