Fossil SCM
Update the built-in SQLite to the latest from the SQLite development tree.
Commit
ba14c7549c8c6d0aaf9cbb43d161e6e1290b14c0
Parent
e0bdd5afce44009…
2 files changed
+225
-153
+1
-1
+225
-153
| --- src/sqlite3.c | ||
| +++ src/sqlite3.c | ||
| @@ -636,11 +636,11 @@ | ||
| 636 | 636 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 637 | 637 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 638 | 638 | */ |
| 639 | 639 | #define SQLITE_VERSION "3.7.0" |
| 640 | 640 | #define SQLITE_VERSION_NUMBER 3007000 |
| 641 | -#define SQLITE_SOURCE_ID "2010-06-24 10:50:18 7aac9ad6dd14b1c56eb8e4750ac769c6197c30bd" | |
| 641 | +#define SQLITE_SOURCE_ID "2010-06-26 20:25:31 f149b498b6ada3fc9f71ee104c351554c80c7f8a" | |
| 642 | 642 | |
| 643 | 643 | /* |
| 644 | 644 | ** CAPI3REF: Run-Time Library Version Numbers |
| 645 | 645 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 646 | 646 | ** |
| @@ -16802,15 +16802,15 @@ | ||
| 16802 | 16802 | SQLITE_PRIVATE void *sqlite3ScratchMalloc(int n){ |
| 16803 | 16803 | void *p; |
| 16804 | 16804 | assert( n>0 ); |
| 16805 | 16805 | |
| 16806 | 16806 | #if SQLITE_THREADSAFE==0 && !defined(NDEBUG) |
| 16807 | - /* Verify that no more than one scratch allocation per thread | |
| 16807 | + /* Verify that no more than two scratch allocation per thread | |
| 16808 | 16808 | ** is outstanding at one time. (This is only checked in the |
| 16809 | 16809 | ** single-threaded case since checking in the multi-threaded case |
| 16810 | 16810 | ** would be much more complicated.) */ |
| 16811 | - assert( scratchAllocOut==0 ); | |
| 16811 | + assert( scratchAllocOut<=1 ); | |
| 16812 | 16812 | #endif |
| 16813 | 16813 | |
| 16814 | 16814 | if( sqlite3GlobalConfig.szScratch<n ){ |
| 16815 | 16815 | goto scratch_overflow; |
| 16816 | 16816 | }else{ |
| @@ -16851,20 +16851,10 @@ | ||
| 16851 | 16851 | #endif |
| 16852 | 16852 | return p; |
| 16853 | 16853 | } |
| 16854 | 16854 | SQLITE_PRIVATE void sqlite3ScratchFree(void *p){ |
| 16855 | 16855 | if( p ){ |
| 16856 | - | |
| 16857 | -#if SQLITE_THREADSAFE==0 && !defined(NDEBUG) | |
| 16858 | - /* Verify that no more than one scratch allocation per thread | |
| 16859 | - ** is outstanding at one time. (This is only checked in the | |
| 16860 | - ** single-threaded case since checking in the multi-threaded case | |
| 16861 | - ** would be much more complicated.) */ | |
| 16862 | - assert( scratchAllocOut==1 ); | |
| 16863 | - scratchAllocOut = 0; | |
| 16864 | -#endif | |
| 16865 | - | |
| 16866 | 16856 | if( sqlite3GlobalConfig.pScratch==0 |
| 16867 | 16857 | || p<sqlite3GlobalConfig.pScratch |
| 16868 | 16858 | || p>=(void*)mem0.aScratchFree ){ |
| 16869 | 16859 | assert( sqlite3MemdebugHasType(p, MEMTYPE_SCRATCH) ); |
| 16870 | 16860 | sqlite3MemdebugSetType(p, MEMTYPE_HEAP); |
| @@ -16886,10 +16876,20 @@ | ||
| 16886 | 16876 | sqlite3_mutex_enter(mem0.mutex); |
| 16887 | 16877 | assert( mem0.nScratchFree<(u32)sqlite3GlobalConfig.nScratch ); |
| 16888 | 16878 | mem0.aScratchFree[mem0.nScratchFree++] = i; |
| 16889 | 16879 | sqlite3StatusAdd(SQLITE_STATUS_SCRATCH_USED, -1); |
| 16890 | 16880 | sqlite3_mutex_leave(mem0.mutex); |
| 16881 | + | |
| 16882 | +#if SQLITE_THREADSAFE==0 && !defined(NDEBUG) | |
| 16883 | + /* Verify that no more than two scratch allocation per thread | |
| 16884 | + ** is outstanding at one time. (This is only checked in the | |
| 16885 | + ** single-threaded case since checking in the multi-threaded case | |
| 16886 | + ** would be much more complicated.) */ | |
| 16887 | + assert( scratchAllocOut>=1 && scratchAllocOut<=2 ); | |
| 16888 | + scratchAllocOut = 0; | |
| 16889 | +#endif | |
| 16890 | + | |
| 16891 | 16891 | } |
| 16892 | 16892 | } |
| 16893 | 16893 | } |
| 16894 | 16894 | |
| 16895 | 16895 | /* |
| @@ -30142,11 +30142,11 @@ | ||
| 30142 | 30142 | sqlite3_free(p); |
| 30143 | 30143 | return SQLITE_NOMEM; |
| 30144 | 30144 | } |
| 30145 | 30145 | memset(pNew, 0, sizeof(*pNew)); |
| 30146 | 30146 | pNew->zFilename = (char*)&pNew[1]; |
| 30147 | - sqlite3_snprintf(nName+15, pNew->zFilename, "%s-wal-index", pDbFd->zPath); | |
| 30147 | + sqlite3_snprintf(nName+15, pNew->zFilename, "%s-shm", pDbFd->zPath); | |
| 30148 | 30148 | |
| 30149 | 30149 | /* Look to see if there is an existing winShmNode that can be used. |
| 30150 | 30150 | ** If no matching winShmNode currently exists, create a new one. |
| 30151 | 30151 | */ |
| 30152 | 30152 | winShmEnterMutex(); |
| @@ -33860,16 +33860,19 @@ | ||
| 33860 | 33860 | ** may attempt to commit the transaction again later (calling |
| 33861 | 33861 | ** CommitPhaseOne() again). This flag is used to ensure that the |
| 33862 | 33862 | ** master journal name is only written to the journal file the first |
| 33863 | 33863 | ** time CommitPhaseOne() is called. |
| 33864 | 33864 | ** |
| 33865 | -** doNotSync | |
| 33865 | +** doNotSpill, doNotSyncSpill | |
| 33866 | 33866 | ** |
| 33867 | -** When enabled, cache spills are prohibited and the journal file cannot | |
| 33868 | -** be synced. This variable is set and cleared by sqlite3PagerWrite() | |
| 33869 | -** in order to prevent a journal sync from happening in between the | |
| 33870 | -** journalling of two pages on the same sector. | |
| 33867 | +** When enabled, cache spills are prohibited. The doNotSpill variable | |
| 33868 | +** inhibits all cache spill and doNotSyncSpill inhibits those spills that | |
| 33869 | +** would require a journal sync. The doNotSyncSpill is set and cleared | |
| 33870 | +** by sqlite3PagerWrite() in order to prevent a journal sync from happening | |
| 33871 | +** in between the journalling of two pages on the same sector. The | |
| 33872 | +** doNotSpill value set to prevent pagerStress() from trying to use | |
| 33873 | +** the journal during a rollback. | |
| 33871 | 33874 | ** |
| 33872 | 33875 | ** needSync |
| 33873 | 33876 | ** |
| 33874 | 33877 | ** TODO: It might be easier to set this variable in writeJournalHdr() |
| 33875 | 33878 | ** and writeMasterJournal() only. Change its meaning to "unsynced data |
| @@ -33909,11 +33912,12 @@ | ||
| 33909 | 33912 | u8 dbModified; /* True if there are any changes to the Db */ |
| 33910 | 33913 | u8 needSync; /* True if an fsync() is needed on the journal */ |
| 33911 | 33914 | u8 journalStarted; /* True if header of journal is synced */ |
| 33912 | 33915 | u8 changeCountDone; /* Set after incrementing the change-counter */ |
| 33913 | 33916 | u8 setMaster; /* True if a m-j name has been written to jrnl */ |
| 33914 | - u8 doNotSync; /* Boolean. While true, do not spill the cache */ | |
| 33917 | + u8 doNotSpill; /* Do not spill the cache when non-zero */ | |
| 33918 | + u8 doNotSyncSpill; /* Do not do a spill that requires jrnl sync */ | |
| 33915 | 33919 | u8 dbSizeValid; /* Set when dbSize is correct */ |
| 33916 | 33920 | u8 subjInMemory; /* True to use in-memory sub-journals */ |
| 33917 | 33921 | Pgno dbSize; /* Number of pages in the database */ |
| 33918 | 33922 | Pgno dbOrigSize; /* dbSize before the current transaction */ |
| 33919 | 33923 | Pgno dbFileSize; /* Number of pages in the database file */ |
| @@ -35245,13 +35249,16 @@ | ||
| 35245 | 35249 | ** the data just read from the sub-journal. Mark the page as dirty |
| 35246 | 35250 | ** and if the pager requires a journal-sync, then mark the page as |
| 35247 | 35251 | ** requiring a journal-sync before it is written. |
| 35248 | 35252 | */ |
| 35249 | 35253 | assert( isSavepnt ); |
| 35250 | - if( (rc = sqlite3PagerAcquire(pPager, pgno, &pPg, 1))!=SQLITE_OK ){ | |
| 35251 | - return rc; | |
| 35252 | - } | |
| 35254 | + assert( pPager->doNotSpill==0 ); | |
| 35255 | + pPager->doNotSpill++; | |
| 35256 | + rc = sqlite3PagerAcquire(pPager, pgno, &pPg, 1); | |
| 35257 | + assert( pPager->doNotSpill==1 ); | |
| 35258 | + pPager->doNotSpill--; | |
| 35259 | + if( rc!=SQLITE_OK ) return rc; | |
| 35253 | 35260 | pPg->flags &= ~PGHDR_NEED_READ; |
| 35254 | 35261 | sqlite3PcacheMakeDirty(pPg); |
| 35255 | 35262 | } |
| 35256 | 35263 | if( pPg ){ |
| 35257 | 35264 | /* No page should ever be explicitly rolled back that is in use, except |
| @@ -37068,10 +37075,26 @@ | ||
| 37068 | 37075 | Pager *pPager = (Pager *)p; |
| 37069 | 37076 | int rc = SQLITE_OK; |
| 37070 | 37077 | |
| 37071 | 37078 | assert( pPg->pPager==pPager ); |
| 37072 | 37079 | assert( pPg->flags&PGHDR_DIRTY ); |
| 37080 | + | |
| 37081 | + /* The doNotSyncSpill flag is set during times when doing a sync of | |
| 37082 | + ** journal (and adding a new header) is not allowed. This occurs | |
| 37083 | + ** during calls to sqlite3PagerWrite() while trying to journal multiple | |
| 37084 | + ** pages belonging to the same sector. | |
| 37085 | + ** | |
| 37086 | + ** The doNotSpill flag inhibits all cache spilling regardless of whether | |
| 37087 | + ** or not a sync is required. This is set during a rollback. | |
| 37088 | + ** | |
| 37089 | + ** Spilling is also inhibited when in an error state. | |
| 37090 | + */ | |
| 37091 | + if( pPager->errCode ) return SQLITE_OK; | |
| 37092 | + if( pPager->doNotSpill ) return SQLITE_OK; | |
| 37093 | + if( pPager->doNotSyncSpill && (pPg->flags & PGHDR_NEED_SYNC)!=0 ){ | |
| 37094 | + return SQLITE_OK; | |
| 37095 | + } | |
| 37073 | 37096 | |
| 37074 | 37097 | pPg->pDirty = 0; |
| 37075 | 37098 | if( pagerUseWal(pPager) ){ |
| 37076 | 37099 | /* Write a single frame for this page to the log. */ |
| 37077 | 37100 | if( subjRequiresPage(pPg) ){ |
| @@ -37079,31 +37102,16 @@ | ||
| 37079 | 37102 | } |
| 37080 | 37103 | if( rc==SQLITE_OK ){ |
| 37081 | 37104 | rc = pagerWalFrames(pPager, pPg, 0, 0, 0); |
| 37082 | 37105 | } |
| 37083 | 37106 | }else{ |
| 37084 | - /* The doNotSync flag is set by the sqlite3PagerWrite() function while it | |
| 37085 | - ** is journalling a set of two or more database pages that are stored | |
| 37086 | - ** on the same disk sector. Syncing the journal is not allowed while | |
| 37087 | - ** this is happening as it is important that all members of such a | |
| 37088 | - ** set of pages are synced to disk together. So, if the page this function | |
| 37089 | - ** is trying to make clean will require a journal sync and the doNotSync | |
| 37090 | - ** flag is set, return without doing anything. The pcache layer will | |
| 37091 | - ** just have to go ahead and allocate a new page buffer instead of | |
| 37092 | - ** reusing pPg. | |
| 37093 | - ** | |
| 37094 | - ** Similarly, if the pager has already entered the error state, do not | |
| 37095 | - ** try to write the contents of pPg to disk. | |
| 37096 | - */ | |
| 37097 | - if( pPager->errCode || (pPager->doNotSync && pPg->flags&PGHDR_NEED_SYNC) ){ | |
| 37098 | - return SQLITE_OK; | |
| 37099 | - } | |
| 37100 | 37107 | |
| 37101 | 37108 | /* Sync the journal file if required. */ |
| 37102 | 37109 | if( pPg->flags&PGHDR_NEED_SYNC ){ |
| 37110 | + assert( !pPager->noSync ); | |
| 37103 | 37111 | rc = syncJournal(pPager); |
| 37104 | - if( rc==SQLITE_OK && pPager->fullSync && | |
| 37112 | + if( rc==SQLITE_OK && | |
| 37105 | 37113 | !(pPager->journalMode==PAGER_JOURNALMODE_MEMORY) && |
| 37106 | 37114 | !(sqlite3OsDeviceCharacteristics(pPager->fd)&SQLITE_IOCAP_SAFE_APPEND) |
| 37107 | 37115 | ){ |
| 37108 | 37116 | pPager->nRec = 0; |
| 37109 | 37117 | rc = writeJournalHdr(pPager); |
| @@ -38385,39 +38393,41 @@ | ||
| 38385 | 38393 | Pgno nPagePerSector = (pPager->sectorSize/pPager->pageSize); |
| 38386 | 38394 | |
| 38387 | 38395 | if( nPagePerSector>1 ){ |
| 38388 | 38396 | Pgno nPageCount; /* Total number of pages in database file */ |
| 38389 | 38397 | Pgno pg1; /* First page of the sector pPg is located on. */ |
| 38390 | - int nPage; /* Number of pages starting at pg1 to journal */ | |
| 38398 | + int nPage = 0; /* Number of pages starting at pg1 to journal */ | |
| 38391 | 38399 | int ii; /* Loop counter */ |
| 38392 | 38400 | int needSync = 0; /* True if any page has PGHDR_NEED_SYNC */ |
| 38393 | 38401 | |
| 38394 | - /* Set the doNotSync flag to 1. This is because we cannot allow a journal | |
| 38395 | - ** header to be written between the pages journaled by this function. | |
| 38402 | + /* Set the doNotSyncSpill flag to 1. This is because we cannot allow | |
| 38403 | + ** a journal header to be written between the pages journaled by | |
| 38404 | + ** this function. | |
| 38396 | 38405 | */ |
| 38397 | 38406 | assert( !MEMDB ); |
| 38398 | - assert( pPager->doNotSync==0 ); | |
| 38399 | - pPager->doNotSync = 1; | |
| 38407 | + assert( pPager->doNotSyncSpill==0 ); | |
| 38408 | + pPager->doNotSyncSpill++; | |
| 38400 | 38409 | |
| 38401 | 38410 | /* This trick assumes that both the page-size and sector-size are |
| 38402 | 38411 | ** an integer power of 2. It sets variable pg1 to the identifier |
| 38403 | 38412 | ** of the first page of the sector pPg is located on. |
| 38404 | 38413 | */ |
| 38405 | 38414 | pg1 = ((pPg->pgno-1) & ~(nPagePerSector-1)) + 1; |
| 38406 | 38415 | |
| 38407 | 38416 | rc = sqlite3PagerPagecount(pPager, (int *)&nPageCount); |
| 38408 | - if( rc ) return rc; | |
| 38409 | - if( pPg->pgno>nPageCount ){ | |
| 38410 | - nPage = (pPg->pgno - pg1)+1; | |
| 38411 | - }else if( (pg1+nPagePerSector-1)>nPageCount ){ | |
| 38412 | - nPage = nPageCount+1-pg1; | |
| 38413 | - }else{ | |
| 38414 | - nPage = nPagePerSector; | |
| 38415 | - } | |
| 38416 | - assert(nPage>0); | |
| 38417 | - assert(pg1<=pPg->pgno); | |
| 38418 | - assert((pg1+nPage)>pPg->pgno); | |
| 38417 | + if( rc==SQLITE_OK ){ | |
| 38418 | + if( pPg->pgno>nPageCount ){ | |
| 38419 | + nPage = (pPg->pgno - pg1)+1; | |
| 38420 | + }else if( (pg1+nPagePerSector-1)>nPageCount ){ | |
| 38421 | + nPage = nPageCount+1-pg1; | |
| 38422 | + }else{ | |
| 38423 | + nPage = nPagePerSector; | |
| 38424 | + } | |
| 38425 | + assert(nPage>0); | |
| 38426 | + assert(pg1<=pPg->pgno); | |
| 38427 | + assert((pg1+nPage)>pPg->pgno); | |
| 38428 | + } | |
| 38419 | 38429 | |
| 38420 | 38430 | for(ii=0; ii<nPage && rc==SQLITE_OK; ii++){ |
| 38421 | 38431 | Pgno pg = pg1+ii; |
| 38422 | 38432 | PgHdr *pPage; |
| 38423 | 38433 | if( pg==pPg->pgno || !sqlite3BitvecTest(pPager->pInJournal, pg) ){ |
| @@ -38456,12 +38466,12 @@ | ||
| 38456 | 38466 | } |
| 38457 | 38467 | } |
| 38458 | 38468 | assert(pPager->needSync); |
| 38459 | 38469 | } |
| 38460 | 38470 | |
| 38461 | - assert( pPager->doNotSync==1 ); | |
| 38462 | - pPager->doNotSync = 0; | |
| 38471 | + assert( pPager->doNotSyncSpill==1 ); | |
| 38472 | + pPager->doNotSyncSpill--; | |
| 38463 | 38473 | }else{ |
| 38464 | 38474 | rc = pager_write(pDbPage); |
| 38465 | 38475 | } |
| 38466 | 38476 | return rc; |
| 38467 | 38477 | } |
| @@ -38825,14 +38835,15 @@ | ||
| 38825 | 38835 | ** But if (due to a coding error elsewhere in the system) it does get |
| 38826 | 38836 | ** called, just return the same error code without doing anything. */ |
| 38827 | 38837 | if( NEVER(pPager->errCode) ) return pPager->errCode; |
| 38828 | 38838 | |
| 38829 | 38839 | /* This function should not be called if the pager is not in at least |
| 38830 | - ** PAGER_RESERVED state. And indeed SQLite never does this. But it is | |
| 38831 | - ** nice to have this defensive test here anyway. | |
| 38840 | + ** PAGER_RESERVED state. **FIXME**: Make it so that this test always | |
| 38841 | + ** fails - make it so that we never reach this point if we do not hold | |
| 38842 | + ** all necessary locks. | |
| 38832 | 38843 | */ |
| 38833 | - if( NEVER(pPager->state<PAGER_RESERVED) ) return SQLITE_ERROR; | |
| 38844 | + if( pPager->state<PAGER_RESERVED ) return SQLITE_ERROR; | |
| 38834 | 38845 | |
| 38835 | 38846 | /* An optimization. If the database was not actually modified during |
| 38836 | 38847 | ** this transaction, the pager is running in exclusive-mode and is |
| 38837 | 38848 | ** using persistent journals, then this function is a no-op. |
| 38838 | 38849 | ** |
| @@ -40961,53 +40972,101 @@ | ||
| 40961 | 40972 | |
| 40962 | 40973 | *piPage = p->iPrior = iRet; |
| 40963 | 40974 | return (iRet==0xFFFFFFFF); |
| 40964 | 40975 | } |
| 40965 | 40976 | |
| 40977 | +/* | |
| 40978 | +** This function merges two sorted lists into a single sorted list. | |
| 40979 | +*/ | |
| 40980 | +static void walMerge( | |
| 40981 | + u32 *aContent, /* Pages in wal */ | |
| 40982 | + ht_slot *aLeft, /* IN: Left hand input list */ | |
| 40983 | + int nLeft, /* IN: Elements in array *paLeft */ | |
| 40984 | + ht_slot **paRight, /* IN/OUT: Right hand input list */ | |
| 40985 | + int *pnRight, /* IN/OUT: Elements in *paRight */ | |
| 40986 | + ht_slot *aTmp /* Temporary buffer */ | |
| 40987 | +){ | |
| 40988 | + int iLeft = 0; /* Current index in aLeft */ | |
| 40989 | + int iRight = 0; /* Current index in aRight */ | |
| 40990 | + int iOut = 0; /* Current index in output buffer */ | |
| 40991 | + int nRight = *pnRight; | |
| 40992 | + ht_slot *aRight = *paRight; | |
| 40966 | 40993 | |
| 40994 | + assert( nLeft>0 && nRight>0 ); | |
| 40995 | + while( iRight<nRight || iLeft<nLeft ){ | |
| 40996 | + ht_slot logpage; | |
| 40997 | + Pgno dbpage; | |
| 40998 | + | |
| 40999 | + if( (iLeft<nLeft) | |
| 41000 | + && (iRight>=nRight || aContent[aLeft[iLeft]]<aContent[aRight[iRight]]) | |
| 41001 | + ){ | |
| 41002 | + logpage = aLeft[iLeft++]; | |
| 41003 | + }else{ | |
| 41004 | + logpage = aRight[iRight++]; | |
| 41005 | + } | |
| 41006 | + dbpage = aContent[logpage]; | |
| 41007 | + | |
| 41008 | + aTmp[iOut++] = logpage; | |
| 41009 | + if( iLeft<nLeft && aContent[aLeft[iLeft]]==dbpage ) iLeft++; | |
| 41010 | + | |
| 41011 | + assert( iLeft>=nLeft || aContent[aLeft[iLeft]]>dbpage ); | |
| 41012 | + assert( iRight>=nRight || aContent[aRight[iRight]]>dbpage ); | |
| 41013 | + } | |
| 41014 | + | |
| 41015 | + *paRight = aLeft; | |
| 41016 | + *pnRight = iOut; | |
| 41017 | + memcpy(aLeft, aTmp, sizeof(aTmp[0])*iOut); | |
| 41018 | +} | |
| 41019 | + | |
| 41020 | +/* | |
| 41021 | +** Sort the elements in list aList, removing any duplicates. | |
| 41022 | +*/ | |
| 40967 | 41023 | static void walMergesort( |
| 40968 | 41024 | u32 *aContent, /* Pages in wal */ |
| 40969 | 41025 | ht_slot *aBuffer, /* Buffer of at least *pnList items to use */ |
| 40970 | 41026 | ht_slot *aList, /* IN/OUT: List to sort */ |
| 40971 | 41027 | int *pnList /* IN/OUT: Number of elements in aList[] */ |
| 40972 | 41028 | ){ |
| 40973 | - int nList = *pnList; | |
| 40974 | - if( nList>1 ){ | |
| 40975 | - int nLeft = nList / 2; /* Elements in left list */ | |
| 40976 | - int nRight = nList - nLeft; /* Elements in right list */ | |
| 40977 | - int iLeft = 0; /* Current index in aLeft */ | |
| 40978 | - int iRight = 0; /* Current index in aright */ | |
| 40979 | - int iOut = 0; /* Current index in output buffer */ | |
| 40980 | - ht_slot *aLeft = aList; /* Left list */ | |
| 40981 | - ht_slot *aRight = aList+nLeft;/* Right list */ | |
| 40982 | - | |
| 40983 | - /* TODO: Change to non-recursive version. */ | |
| 40984 | - walMergesort(aContent, aBuffer, aLeft, &nLeft); | |
| 40985 | - walMergesort(aContent, aBuffer, aRight, &nRight); | |
| 40986 | - | |
| 40987 | - while( iRight<nRight || iLeft<nLeft ){ | |
| 40988 | - ht_slot logpage; | |
| 40989 | - Pgno dbpage; | |
| 40990 | - | |
| 40991 | - if( (iLeft<nLeft) | |
| 40992 | - && (iRight>=nRight || aContent[aLeft[iLeft]]<aContent[aRight[iRight]]) | |
| 40993 | - ){ | |
| 40994 | - logpage = aLeft[iLeft++]; | |
| 40995 | - }else{ | |
| 40996 | - logpage = aRight[iRight++]; | |
| 40997 | - } | |
| 40998 | - dbpage = aContent[logpage]; | |
| 40999 | - | |
| 41000 | - aBuffer[iOut++] = logpage; | |
| 41001 | - if( iLeft<nLeft && aContent[aLeft[iLeft]]==dbpage ) iLeft++; | |
| 41002 | - | |
| 41003 | - assert( iLeft>=nLeft || aContent[aLeft[iLeft]]>dbpage ); | |
| 41004 | - assert( iRight>=nRight || aContent[aRight[iRight]]>dbpage ); | |
| 41005 | - } | |
| 41006 | - memcpy(aList, aBuffer, sizeof(aList[0])*iOut); | |
| 41007 | - *pnList = iOut; | |
| 41008 | - } | |
| 41029 | + struct Sublist { | |
| 41030 | + int nList; /* Number of elements in aList */ | |
| 41031 | + ht_slot *aList; /* Pointer to sub-list content */ | |
| 41032 | + }; | |
| 41033 | + | |
| 41034 | + const int nList = *pnList; /* Size of input list */ | |
| 41035 | + int nMerge; /* Number of elements in list aMerge */ | |
| 41036 | + ht_slot *aMerge; /* List to be merged */ | |
| 41037 | + int iList; /* Index into input list */ | |
| 41038 | + int iSub = 0; /* Index into aSub array */ | |
| 41039 | + struct Sublist aSub[13]; /* Array of sub-lists */ | |
| 41040 | + | |
| 41041 | + memset(aSub, 0, sizeof(aSub)); | |
| 41042 | + assert( nList<=HASHTABLE_NPAGE && nList>0 ); | |
| 41043 | + assert( HASHTABLE_NPAGE==(1<<(ArraySize(aSub)-1)) ); | |
| 41044 | + | |
| 41045 | + for(iList=0; iList<nList; iList++){ | |
| 41046 | + nMerge = 1; | |
| 41047 | + aMerge = &aList[iList]; | |
| 41048 | + for(iSub=0; iList & (1<<iSub); iSub++){ | |
| 41049 | + struct Sublist *p = &aSub[iSub]; | |
| 41050 | + assert( p->aList && p->nList<=(1<<iSub) ); | |
| 41051 | + assert( p->aList==&aList[iList&~((2<<iSub)-1)] ); | |
| 41052 | + walMerge(aContent, p->aList, p->nList, &aMerge, &nMerge, aBuffer); | |
| 41053 | + } | |
| 41054 | + aSub[iSub].aList = aMerge; | |
| 41055 | + aSub[iSub].nList = nMerge; | |
| 41056 | + } | |
| 41057 | + | |
| 41058 | + for(iSub++; iSub<ArraySize(aSub); iSub++){ | |
| 41059 | + if( nList & (1<<iSub) ){ | |
| 41060 | + struct Sublist *p = &aSub[iSub]; | |
| 41061 | + assert( p->nList<=(1<<iSub) ); | |
| 41062 | + assert( p->aList==&aList[nList&~((2<<iSub)-1)] ); | |
| 41063 | + walMerge(aContent, p->aList, p->nList, &aMerge, &nMerge, aBuffer); | |
| 41064 | + } | |
| 41065 | + } | |
| 41066 | + assert( aMerge==aList ); | |
| 41067 | + *pnList = nMerge; | |
| 41009 | 41068 | |
| 41010 | 41069 | #ifdef SQLITE_DEBUG |
| 41011 | 41070 | { |
| 41012 | 41071 | int i; |
| 41013 | 41072 | for(i=1; i<*pnList; i++){ |
| @@ -41019,91 +41078,94 @@ | ||
| 41019 | 41078 | |
| 41020 | 41079 | /* |
| 41021 | 41080 | ** Free an iterator allocated by walIteratorInit(). |
| 41022 | 41081 | */ |
| 41023 | 41082 | static void walIteratorFree(WalIterator *p){ |
| 41024 | - sqlite3_free(p); | |
| 41083 | + sqlite3ScratchFree(p); | |
| 41025 | 41084 | } |
| 41026 | 41085 | |
| 41027 | 41086 | /* |
| 41028 | -** Map the wal-index into memory owned by this thread, if it is not | |
| 41029 | -** mapped already. Then construct a WalInterator object that can be | |
| 41030 | -** used to loop over all pages in the WAL in ascending order. | |
| 41087 | +** Construct a WalInterator object that can be used to loop over all | |
| 41088 | +** pages in the WAL in ascending order. The caller must hold the checkpoint | |
| 41031 | 41089 | ** |
| 41032 | 41090 | ** On success, make *pp point to the newly allocated WalInterator object |
| 41033 | -** return SQLITE_OK. Otherwise, leave *pp unchanged and return an error | |
| 41034 | -** code. | |
| 41091 | +** return SQLITE_OK. Otherwise, return an error code. If this routine | |
| 41092 | +** returns an error, the value of *pp is undefined. | |
| 41035 | 41093 | ** |
| 41036 | 41094 | ** The calling routine should invoke walIteratorFree() to destroy the |
| 41037 | -** WalIterator object when it has finished with it. The caller must | |
| 41038 | -** also unmap the wal-index. But the wal-index must not be unmapped | |
| 41039 | -** prior to the WalIterator object being destroyed. | |
| 41095 | +** WalIterator object when it has finished with it. | |
| 41040 | 41096 | */ |
| 41041 | 41097 | static int walIteratorInit(Wal *pWal, WalIterator **pp){ |
| 41042 | 41098 | WalIterator *p; /* Return value */ |
| 41043 | 41099 | int nSegment; /* Number of segments to merge */ |
| 41044 | 41100 | u32 iLast; /* Last frame in log */ |
| 41045 | 41101 | int nByte; /* Number of bytes to allocate */ |
| 41046 | 41102 | int i; /* Iterator variable */ |
| 41047 | 41103 | ht_slot *aTmp; /* Temp space used by merge-sort */ |
| 41048 | - ht_slot *aSpace; /* Space at the end of the allocation */ | |
| 41049 | - | |
| 41050 | - /* This routine only runs while holding SQLITE_SHM_CHECKPOINT. No other | |
| 41051 | - ** thread is able to write to shared memory while this routine is | |
| 41052 | - ** running (or, indeed, while the WalIterator object exists). Hence, | |
| 41053 | - ** we can cast off the volatile qualification from shared memory | |
| 41054 | - */ | |
| 41055 | - assert( pWal->ckptLock ); | |
| 41104 | + int rc = SQLITE_OK; /* Return Code */ | |
| 41105 | + | |
| 41106 | + /* This routine only runs while holding the checkpoint lock. And | |
| 41107 | + ** it only runs if there is actually content in the log (mxFrame>0). | |
| 41108 | + */ | |
| 41109 | + assert( pWal->ckptLock && pWal->hdr.mxFrame>0 ); | |
| 41056 | 41110 | iLast = pWal->hdr.mxFrame; |
| 41057 | 41111 | |
| 41058 | - /* Allocate space for the WalIterator object */ | |
| 41112 | + /* Allocate space for the WalIterator object. */ | |
| 41059 | 41113 | nSegment = walFramePage(iLast) + 1; |
| 41060 | 41114 | nByte = sizeof(WalIterator) |
| 41061 | - + nSegment*(sizeof(struct WalSegment)) | |
| 41062 | - + (nSegment+1)*(HASHTABLE_NPAGE * sizeof(ht_slot)); | |
| 41063 | - p = (WalIterator *)sqlite3_malloc(nByte); | |
| 41115 | + + (nSegment-1)*sizeof(struct WalSegment) | |
| 41116 | + + iLast*sizeof(ht_slot); | |
| 41117 | + p = (WalIterator *)sqlite3ScratchMalloc(nByte); | |
| 41064 | 41118 | if( !p ){ |
| 41065 | 41119 | return SQLITE_NOMEM; |
| 41066 | 41120 | } |
| 41067 | 41121 | memset(p, 0, nByte); |
| 41068 | - | |
| 41069 | - /* Allocate space for the WalIterator object */ | |
| 41070 | 41122 | p->nSegment = nSegment; |
| 41071 | - aSpace = (ht_slot *)&p->aSegment[nSegment]; | |
| 41072 | - aTmp = &aSpace[HASHTABLE_NPAGE*nSegment]; | |
| 41073 | - for(i=0; i<nSegment; i++){ | |
| 41123 | + | |
| 41124 | + /* Allocate temporary space used by the merge-sort routine. This block | |
| 41125 | + ** of memory will be freed before this function returns. | |
| 41126 | + */ | |
| 41127 | + aTmp = (ht_slot *)sqlite3ScratchMalloc( | |
| 41128 | + sizeof(ht_slot) * (iLast>HASHTABLE_NPAGE?HASHTABLE_NPAGE:iLast) | |
| 41129 | + ); | |
| 41130 | + if( !aTmp ){ | |
| 41131 | + rc = SQLITE_NOMEM; | |
| 41132 | + } | |
| 41133 | + | |
| 41134 | + for(i=0; rc==SQLITE_OK && i<nSegment; i++){ | |
| 41074 | 41135 | volatile ht_slot *aHash; |
| 41075 | - int j; | |
| 41076 | 41136 | u32 iZero; |
| 41077 | - int nEntry; | |
| 41078 | 41137 | volatile u32 *aPgno; |
| 41079 | - int rc; | |
| 41080 | 41138 | |
| 41081 | 41139 | rc = walHashGet(pWal, i, &aHash, &aPgno, &iZero); |
| 41082 | - if( rc!=SQLITE_OK ){ | |
| 41083 | - walIteratorFree(p); | |
| 41084 | - return rc; | |
| 41085 | - } | |
| 41086 | - aPgno++; | |
| 41087 | - nEntry = ((i+1)==nSegment)?iLast-iZero:(u32 *)aHash-(u32 *)aPgno; | |
| 41088 | - iZero++; | |
| 41089 | - | |
| 41090 | - for(j=0; j<nEntry; j++){ | |
| 41091 | - aSpace[j] = j; | |
| 41092 | - } | |
| 41093 | - walMergesort((u32 *)aPgno, aTmp, aSpace, &nEntry); | |
| 41094 | - p->aSegment[i].iZero = iZero; | |
| 41095 | - p->aSegment[i].nEntry = nEntry; | |
| 41096 | - p->aSegment[i].aIndex = aSpace; | |
| 41097 | - p->aSegment[i].aPgno = (u32 *)aPgno; | |
| 41098 | - aSpace += HASHTABLE_NPAGE; | |
| 41099 | - } | |
| 41100 | - assert( aSpace==aTmp ); | |
| 41101 | - | |
| 41102 | - /* Return the fully initialized WalIterator object */ | |
| 41140 | + if( rc==SQLITE_OK ){ | |
| 41141 | + int j; /* Counter variable */ | |
| 41142 | + int nEntry; /* Number of entries in this segment */ | |
| 41143 | + ht_slot *aIndex; /* Sorted index for this segment */ | |
| 41144 | + | |
| 41145 | + aPgno++; | |
| 41146 | + nEntry = ((i+1)==nSegment)?iLast-iZero:(u32 *)aHash-(u32 *)aPgno; | |
| 41147 | + aIndex = &((ht_slot *)&p->aSegment[p->nSegment])[iZero]; | |
| 41148 | + iZero++; | |
| 41149 | + | |
| 41150 | + for(j=0; j<nEntry; j++){ | |
| 41151 | + aIndex[j] = j; | |
| 41152 | + } | |
| 41153 | + walMergesort((u32 *)aPgno, aTmp, aIndex, &nEntry); | |
| 41154 | + p->aSegment[i].iZero = iZero; | |
| 41155 | + p->aSegment[i].nEntry = nEntry; | |
| 41156 | + p->aSegment[i].aIndex = aIndex; | |
| 41157 | + p->aSegment[i].aPgno = (u32 *)aPgno; | |
| 41158 | + } | |
| 41159 | + } | |
| 41160 | + sqlite3ScratchFree(aTmp); | |
| 41161 | + | |
| 41162 | + if( rc!=SQLITE_OK ){ | |
| 41163 | + walIteratorFree(p); | |
| 41164 | + } | |
| 41103 | 41165 | *pp = p; |
| 41104 | - return SQLITE_OK ; | |
| 41166 | + return rc; | |
| 41105 | 41167 | } |
| 41106 | 41168 | |
| 41107 | 41169 | /* |
| 41108 | 41170 | ** Copy as much content as we can from the WAL back into the database file |
| 41109 | 41171 | ** in response to an sqlite3_wal_checkpoint() request or the equivalent. |
| @@ -41148,15 +41210,18 @@ | ||
| 41148 | 41210 | u32 iFrame = 0; /* Wal frame containing data for iDbpage */ |
| 41149 | 41211 | u32 mxSafeFrame; /* Max frame that can be backfilled */ |
| 41150 | 41212 | int i; /* Loop counter */ |
| 41151 | 41213 | volatile WalCkptInfo *pInfo; /* The checkpoint status information */ |
| 41152 | 41214 | |
| 41215 | + if( pWal->hdr.mxFrame==0 ) return SQLITE_OK; | |
| 41216 | + | |
| 41153 | 41217 | /* Allocate the iterator */ |
| 41154 | 41218 | rc = walIteratorInit(pWal, &pIter); |
| 41155 | - if( rc!=SQLITE_OK || pWal->hdr.mxFrame==0 ){ | |
| 41156 | - goto walcheckpoint_out; | |
| 41219 | + if( rc!=SQLITE_OK ){ | |
| 41220 | + return rc; | |
| 41157 | 41221 | } |
| 41222 | + assert( pIter ); | |
| 41158 | 41223 | |
| 41159 | 41224 | /*** TODO: Move this test out to the caller. Make it an assert() here ***/ |
| 41160 | 41225 | if( pWal->hdr.szPage!=nBuf ){ |
| 41161 | 41226 | rc = SQLITE_CORRUPT_BKPT; |
| 41162 | 41227 | goto walcheckpoint_out; |
| @@ -52950,13 +53015,20 @@ | ||
| 52950 | 53015 | if( !pExpr ){ |
| 52951 | 53016 | *ppVal = 0; |
| 52952 | 53017 | return SQLITE_OK; |
| 52953 | 53018 | } |
| 52954 | 53019 | op = pExpr->op; |
| 52955 | - if( op==TK_REGISTER ){ | |
| 52956 | - op = pExpr->op2; /* This only happens with SQLITE_ENABLE_STAT2 */ | |
| 52957 | - } | |
| 53020 | + | |
| 53021 | + /* op can only be TK_REGISTER is we have compiled with SQLITE_ENABLE_STAT2. | |
| 53022 | + ** The ifdef here is to enable us to achieve 100% branch test coverage even | |
| 53023 | + ** when SQLITE_ENABLE_STAT2 is omitted. | |
| 53024 | + */ | |
| 53025 | +#ifdef SQLITE_ENABLE_STAT2 | |
| 53026 | + if( op==TK_REGISTER ) op = pExpr->op2; | |
| 53027 | +#else | |
| 53028 | + if( NEVER(op==TK_REGISTER) ) op = pExpr->op2; | |
| 53029 | +#endif | |
| 52958 | 53030 | |
| 52959 | 53031 | if( op==TK_STRING || op==TK_FLOAT || op==TK_INTEGER ){ |
| 52960 | 53032 | pVal = sqlite3ValueNew(db); |
| 52961 | 53033 | if( pVal==0 ) goto no_mem; |
| 52962 | 53034 | if( ExprHasProperty(pExpr, EP_IntValue) ){ |
| 52963 | 53035 |
| --- src/sqlite3.c | |
| +++ src/sqlite3.c | |
| @@ -636,11 +636,11 @@ | |
| 636 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 637 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 638 | */ |
| 639 | #define SQLITE_VERSION "3.7.0" |
| 640 | #define SQLITE_VERSION_NUMBER 3007000 |
| 641 | #define SQLITE_SOURCE_ID "2010-06-24 10:50:18 7aac9ad6dd14b1c56eb8e4750ac769c6197c30bd" |
| 642 | |
| 643 | /* |
| 644 | ** CAPI3REF: Run-Time Library Version Numbers |
| 645 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 646 | ** |
| @@ -16802,15 +16802,15 @@ | |
| 16802 | SQLITE_PRIVATE void *sqlite3ScratchMalloc(int n){ |
| 16803 | void *p; |
| 16804 | assert( n>0 ); |
| 16805 | |
| 16806 | #if SQLITE_THREADSAFE==0 && !defined(NDEBUG) |
| 16807 | /* Verify that no more than one scratch allocation per thread |
| 16808 | ** is outstanding at one time. (This is only checked in the |
| 16809 | ** single-threaded case since checking in the multi-threaded case |
| 16810 | ** would be much more complicated.) */ |
| 16811 | assert( scratchAllocOut==0 ); |
| 16812 | #endif |
| 16813 | |
| 16814 | if( sqlite3GlobalConfig.szScratch<n ){ |
| 16815 | goto scratch_overflow; |
| 16816 | }else{ |
| @@ -16851,20 +16851,10 @@ | |
| 16851 | #endif |
| 16852 | return p; |
| 16853 | } |
| 16854 | SQLITE_PRIVATE void sqlite3ScratchFree(void *p){ |
| 16855 | if( p ){ |
| 16856 | |
| 16857 | #if SQLITE_THREADSAFE==0 && !defined(NDEBUG) |
| 16858 | /* Verify that no more than one scratch allocation per thread |
| 16859 | ** is outstanding at one time. (This is only checked in the |
| 16860 | ** single-threaded case since checking in the multi-threaded case |
| 16861 | ** would be much more complicated.) */ |
| 16862 | assert( scratchAllocOut==1 ); |
| 16863 | scratchAllocOut = 0; |
| 16864 | #endif |
| 16865 | |
| 16866 | if( sqlite3GlobalConfig.pScratch==0 |
| 16867 | || p<sqlite3GlobalConfig.pScratch |
| 16868 | || p>=(void*)mem0.aScratchFree ){ |
| 16869 | assert( sqlite3MemdebugHasType(p, MEMTYPE_SCRATCH) ); |
| 16870 | sqlite3MemdebugSetType(p, MEMTYPE_HEAP); |
| @@ -16886,10 +16876,20 @@ | |
| 16886 | sqlite3_mutex_enter(mem0.mutex); |
| 16887 | assert( mem0.nScratchFree<(u32)sqlite3GlobalConfig.nScratch ); |
| 16888 | mem0.aScratchFree[mem0.nScratchFree++] = i; |
| 16889 | sqlite3StatusAdd(SQLITE_STATUS_SCRATCH_USED, -1); |
| 16890 | sqlite3_mutex_leave(mem0.mutex); |
| 16891 | } |
| 16892 | } |
| 16893 | } |
| 16894 | |
| 16895 | /* |
| @@ -30142,11 +30142,11 @@ | |
| 30142 | sqlite3_free(p); |
| 30143 | return SQLITE_NOMEM; |
| 30144 | } |
| 30145 | memset(pNew, 0, sizeof(*pNew)); |
| 30146 | pNew->zFilename = (char*)&pNew[1]; |
| 30147 | sqlite3_snprintf(nName+15, pNew->zFilename, "%s-wal-index", pDbFd->zPath); |
| 30148 | |
| 30149 | /* Look to see if there is an existing winShmNode that can be used. |
| 30150 | ** If no matching winShmNode currently exists, create a new one. |
| 30151 | */ |
| 30152 | winShmEnterMutex(); |
| @@ -33860,16 +33860,19 @@ | |
| 33860 | ** may attempt to commit the transaction again later (calling |
| 33861 | ** CommitPhaseOne() again). This flag is used to ensure that the |
| 33862 | ** master journal name is only written to the journal file the first |
| 33863 | ** time CommitPhaseOne() is called. |
| 33864 | ** |
| 33865 | ** doNotSync |
| 33866 | ** |
| 33867 | ** When enabled, cache spills are prohibited and the journal file cannot |
| 33868 | ** be synced. This variable is set and cleared by sqlite3PagerWrite() |
| 33869 | ** in order to prevent a journal sync from happening in between the |
| 33870 | ** journalling of two pages on the same sector. |
| 33871 | ** |
| 33872 | ** needSync |
| 33873 | ** |
| 33874 | ** TODO: It might be easier to set this variable in writeJournalHdr() |
| 33875 | ** and writeMasterJournal() only. Change its meaning to "unsynced data |
| @@ -33909,11 +33912,12 @@ | |
| 33909 | u8 dbModified; /* True if there are any changes to the Db */ |
| 33910 | u8 needSync; /* True if an fsync() is needed on the journal */ |
| 33911 | u8 journalStarted; /* True if header of journal is synced */ |
| 33912 | u8 changeCountDone; /* Set after incrementing the change-counter */ |
| 33913 | u8 setMaster; /* True if a m-j name has been written to jrnl */ |
| 33914 | u8 doNotSync; /* Boolean. While true, do not spill the cache */ |
| 33915 | u8 dbSizeValid; /* Set when dbSize is correct */ |
| 33916 | u8 subjInMemory; /* True to use in-memory sub-journals */ |
| 33917 | Pgno dbSize; /* Number of pages in the database */ |
| 33918 | Pgno dbOrigSize; /* dbSize before the current transaction */ |
| 33919 | Pgno dbFileSize; /* Number of pages in the database file */ |
| @@ -35245,13 +35249,16 @@ | |
| 35245 | ** the data just read from the sub-journal. Mark the page as dirty |
| 35246 | ** and if the pager requires a journal-sync, then mark the page as |
| 35247 | ** requiring a journal-sync before it is written. |
| 35248 | */ |
| 35249 | assert( isSavepnt ); |
| 35250 | if( (rc = sqlite3PagerAcquire(pPager, pgno, &pPg, 1))!=SQLITE_OK ){ |
| 35251 | return rc; |
| 35252 | } |
| 35253 | pPg->flags &= ~PGHDR_NEED_READ; |
| 35254 | sqlite3PcacheMakeDirty(pPg); |
| 35255 | } |
| 35256 | if( pPg ){ |
| 35257 | /* No page should ever be explicitly rolled back that is in use, except |
| @@ -37068,10 +37075,26 @@ | |
| 37068 | Pager *pPager = (Pager *)p; |
| 37069 | int rc = SQLITE_OK; |
| 37070 | |
| 37071 | assert( pPg->pPager==pPager ); |
| 37072 | assert( pPg->flags&PGHDR_DIRTY ); |
| 37073 | |
| 37074 | pPg->pDirty = 0; |
| 37075 | if( pagerUseWal(pPager) ){ |
| 37076 | /* Write a single frame for this page to the log. */ |
| 37077 | if( subjRequiresPage(pPg) ){ |
| @@ -37079,31 +37102,16 @@ | |
| 37079 | } |
| 37080 | if( rc==SQLITE_OK ){ |
| 37081 | rc = pagerWalFrames(pPager, pPg, 0, 0, 0); |
| 37082 | } |
| 37083 | }else{ |
| 37084 | /* The doNotSync flag is set by the sqlite3PagerWrite() function while it |
| 37085 | ** is journalling a set of two or more database pages that are stored |
| 37086 | ** on the same disk sector. Syncing the journal is not allowed while |
| 37087 | ** this is happening as it is important that all members of such a |
| 37088 | ** set of pages are synced to disk together. So, if the page this function |
| 37089 | ** is trying to make clean will require a journal sync and the doNotSync |
| 37090 | ** flag is set, return without doing anything. The pcache layer will |
| 37091 | ** just have to go ahead and allocate a new page buffer instead of |
| 37092 | ** reusing pPg. |
| 37093 | ** |
| 37094 | ** Similarly, if the pager has already entered the error state, do not |
| 37095 | ** try to write the contents of pPg to disk. |
| 37096 | */ |
| 37097 | if( pPager->errCode || (pPager->doNotSync && pPg->flags&PGHDR_NEED_SYNC) ){ |
| 37098 | return SQLITE_OK; |
| 37099 | } |
| 37100 | |
| 37101 | /* Sync the journal file if required. */ |
| 37102 | if( pPg->flags&PGHDR_NEED_SYNC ){ |
| 37103 | rc = syncJournal(pPager); |
| 37104 | if( rc==SQLITE_OK && pPager->fullSync && |
| 37105 | !(pPager->journalMode==PAGER_JOURNALMODE_MEMORY) && |
| 37106 | !(sqlite3OsDeviceCharacteristics(pPager->fd)&SQLITE_IOCAP_SAFE_APPEND) |
| 37107 | ){ |
| 37108 | pPager->nRec = 0; |
| 37109 | rc = writeJournalHdr(pPager); |
| @@ -38385,39 +38393,41 @@ | |
| 38385 | Pgno nPagePerSector = (pPager->sectorSize/pPager->pageSize); |
| 38386 | |
| 38387 | if( nPagePerSector>1 ){ |
| 38388 | Pgno nPageCount; /* Total number of pages in database file */ |
| 38389 | Pgno pg1; /* First page of the sector pPg is located on. */ |
| 38390 | int nPage; /* Number of pages starting at pg1 to journal */ |
| 38391 | int ii; /* Loop counter */ |
| 38392 | int needSync = 0; /* True if any page has PGHDR_NEED_SYNC */ |
| 38393 | |
| 38394 | /* Set the doNotSync flag to 1. This is because we cannot allow a journal |
| 38395 | ** header to be written between the pages journaled by this function. |
| 38396 | */ |
| 38397 | assert( !MEMDB ); |
| 38398 | assert( pPager->doNotSync==0 ); |
| 38399 | pPager->doNotSync = 1; |
| 38400 | |
| 38401 | /* This trick assumes that both the page-size and sector-size are |
| 38402 | ** an integer power of 2. It sets variable pg1 to the identifier |
| 38403 | ** of the first page of the sector pPg is located on. |
| 38404 | */ |
| 38405 | pg1 = ((pPg->pgno-1) & ~(nPagePerSector-1)) + 1; |
| 38406 | |
| 38407 | rc = sqlite3PagerPagecount(pPager, (int *)&nPageCount); |
| 38408 | if( rc ) return rc; |
| 38409 | if( pPg->pgno>nPageCount ){ |
| 38410 | nPage = (pPg->pgno - pg1)+1; |
| 38411 | }else if( (pg1+nPagePerSector-1)>nPageCount ){ |
| 38412 | nPage = nPageCount+1-pg1; |
| 38413 | }else{ |
| 38414 | nPage = nPagePerSector; |
| 38415 | } |
| 38416 | assert(nPage>0); |
| 38417 | assert(pg1<=pPg->pgno); |
| 38418 | assert((pg1+nPage)>pPg->pgno); |
| 38419 | |
| 38420 | for(ii=0; ii<nPage && rc==SQLITE_OK; ii++){ |
| 38421 | Pgno pg = pg1+ii; |
| 38422 | PgHdr *pPage; |
| 38423 | if( pg==pPg->pgno || !sqlite3BitvecTest(pPager->pInJournal, pg) ){ |
| @@ -38456,12 +38466,12 @@ | |
| 38456 | } |
| 38457 | } |
| 38458 | assert(pPager->needSync); |
| 38459 | } |
| 38460 | |
| 38461 | assert( pPager->doNotSync==1 ); |
| 38462 | pPager->doNotSync = 0; |
| 38463 | }else{ |
| 38464 | rc = pager_write(pDbPage); |
| 38465 | } |
| 38466 | return rc; |
| 38467 | } |
| @@ -38825,14 +38835,15 @@ | |
| 38825 | ** But if (due to a coding error elsewhere in the system) it does get |
| 38826 | ** called, just return the same error code without doing anything. */ |
| 38827 | if( NEVER(pPager->errCode) ) return pPager->errCode; |
| 38828 | |
| 38829 | /* This function should not be called if the pager is not in at least |
| 38830 | ** PAGER_RESERVED state. And indeed SQLite never does this. But it is |
| 38831 | ** nice to have this defensive test here anyway. |
| 38832 | */ |
| 38833 | if( NEVER(pPager->state<PAGER_RESERVED) ) return SQLITE_ERROR; |
| 38834 | |
| 38835 | /* An optimization. If the database was not actually modified during |
| 38836 | ** this transaction, the pager is running in exclusive-mode and is |
| 38837 | ** using persistent journals, then this function is a no-op. |
| 38838 | ** |
| @@ -40961,53 +40972,101 @@ | |
| 40961 | |
| 40962 | *piPage = p->iPrior = iRet; |
| 40963 | return (iRet==0xFFFFFFFF); |
| 40964 | } |
| 40965 | |
| 40966 | |
| 40967 | static void walMergesort( |
| 40968 | u32 *aContent, /* Pages in wal */ |
| 40969 | ht_slot *aBuffer, /* Buffer of at least *pnList items to use */ |
| 40970 | ht_slot *aList, /* IN/OUT: List to sort */ |
| 40971 | int *pnList /* IN/OUT: Number of elements in aList[] */ |
| 40972 | ){ |
| 40973 | int nList = *pnList; |
| 40974 | if( nList>1 ){ |
| 40975 | int nLeft = nList / 2; /* Elements in left list */ |
| 40976 | int nRight = nList - nLeft; /* Elements in right list */ |
| 40977 | int iLeft = 0; /* Current index in aLeft */ |
| 40978 | int iRight = 0; /* Current index in aright */ |
| 40979 | int iOut = 0; /* Current index in output buffer */ |
| 40980 | ht_slot *aLeft = aList; /* Left list */ |
| 40981 | ht_slot *aRight = aList+nLeft;/* Right list */ |
| 40982 | |
| 40983 | /* TODO: Change to non-recursive version. */ |
| 40984 | walMergesort(aContent, aBuffer, aLeft, &nLeft); |
| 40985 | walMergesort(aContent, aBuffer, aRight, &nRight); |
| 40986 | |
| 40987 | while( iRight<nRight || iLeft<nLeft ){ |
| 40988 | ht_slot logpage; |
| 40989 | Pgno dbpage; |
| 40990 | |
| 40991 | if( (iLeft<nLeft) |
| 40992 | && (iRight>=nRight || aContent[aLeft[iLeft]]<aContent[aRight[iRight]]) |
| 40993 | ){ |
| 40994 | logpage = aLeft[iLeft++]; |
| 40995 | }else{ |
| 40996 | logpage = aRight[iRight++]; |
| 40997 | } |
| 40998 | dbpage = aContent[logpage]; |
| 40999 | |
| 41000 | aBuffer[iOut++] = logpage; |
| 41001 | if( iLeft<nLeft && aContent[aLeft[iLeft]]==dbpage ) iLeft++; |
| 41002 | |
| 41003 | assert( iLeft>=nLeft || aContent[aLeft[iLeft]]>dbpage ); |
| 41004 | assert( iRight>=nRight || aContent[aRight[iRight]]>dbpage ); |
| 41005 | } |
| 41006 | memcpy(aList, aBuffer, sizeof(aList[0])*iOut); |
| 41007 | *pnList = iOut; |
| 41008 | } |
| 41009 | |
| 41010 | #ifdef SQLITE_DEBUG |
| 41011 | { |
| 41012 | int i; |
| 41013 | for(i=1; i<*pnList; i++){ |
| @@ -41019,91 +41078,94 @@ | |
| 41019 | |
| 41020 | /* |
| 41021 | ** Free an iterator allocated by walIteratorInit(). |
| 41022 | */ |
| 41023 | static void walIteratorFree(WalIterator *p){ |
| 41024 | sqlite3_free(p); |
| 41025 | } |
| 41026 | |
| 41027 | /* |
| 41028 | ** Map the wal-index into memory owned by this thread, if it is not |
| 41029 | ** mapped already. Then construct a WalInterator object that can be |
| 41030 | ** used to loop over all pages in the WAL in ascending order. |
| 41031 | ** |
| 41032 | ** On success, make *pp point to the newly allocated WalInterator object |
| 41033 | ** return SQLITE_OK. Otherwise, leave *pp unchanged and return an error |
| 41034 | ** code. |
| 41035 | ** |
| 41036 | ** The calling routine should invoke walIteratorFree() to destroy the |
| 41037 | ** WalIterator object when it has finished with it. The caller must |
| 41038 | ** also unmap the wal-index. But the wal-index must not be unmapped |
| 41039 | ** prior to the WalIterator object being destroyed. |
| 41040 | */ |
| 41041 | static int walIteratorInit(Wal *pWal, WalIterator **pp){ |
| 41042 | WalIterator *p; /* Return value */ |
| 41043 | int nSegment; /* Number of segments to merge */ |
| 41044 | u32 iLast; /* Last frame in log */ |
| 41045 | int nByte; /* Number of bytes to allocate */ |
| 41046 | int i; /* Iterator variable */ |
| 41047 | ht_slot *aTmp; /* Temp space used by merge-sort */ |
| 41048 | ht_slot *aSpace; /* Space at the end of the allocation */ |
| 41049 | |
| 41050 | /* This routine only runs while holding SQLITE_SHM_CHECKPOINT. No other |
| 41051 | ** thread is able to write to shared memory while this routine is |
| 41052 | ** running (or, indeed, while the WalIterator object exists). Hence, |
| 41053 | ** we can cast off the volatile qualification from shared memory |
| 41054 | */ |
| 41055 | assert( pWal->ckptLock ); |
| 41056 | iLast = pWal->hdr.mxFrame; |
| 41057 | |
| 41058 | /* Allocate space for the WalIterator object */ |
| 41059 | nSegment = walFramePage(iLast) + 1; |
| 41060 | nByte = sizeof(WalIterator) |
| 41061 | + nSegment*(sizeof(struct WalSegment)) |
| 41062 | + (nSegment+1)*(HASHTABLE_NPAGE * sizeof(ht_slot)); |
| 41063 | p = (WalIterator *)sqlite3_malloc(nByte); |
| 41064 | if( !p ){ |
| 41065 | return SQLITE_NOMEM; |
| 41066 | } |
| 41067 | memset(p, 0, nByte); |
| 41068 | |
| 41069 | /* Allocate space for the WalIterator object */ |
| 41070 | p->nSegment = nSegment; |
| 41071 | aSpace = (ht_slot *)&p->aSegment[nSegment]; |
| 41072 | aTmp = &aSpace[HASHTABLE_NPAGE*nSegment]; |
| 41073 | for(i=0; i<nSegment; i++){ |
| 41074 | volatile ht_slot *aHash; |
| 41075 | int j; |
| 41076 | u32 iZero; |
| 41077 | int nEntry; |
| 41078 | volatile u32 *aPgno; |
| 41079 | int rc; |
| 41080 | |
| 41081 | rc = walHashGet(pWal, i, &aHash, &aPgno, &iZero); |
| 41082 | if( rc!=SQLITE_OK ){ |
| 41083 | walIteratorFree(p); |
| 41084 | return rc; |
| 41085 | } |
| 41086 | aPgno++; |
| 41087 | nEntry = ((i+1)==nSegment)?iLast-iZero:(u32 *)aHash-(u32 *)aPgno; |
| 41088 | iZero++; |
| 41089 | |
| 41090 | for(j=0; j<nEntry; j++){ |
| 41091 | aSpace[j] = j; |
| 41092 | } |
| 41093 | walMergesort((u32 *)aPgno, aTmp, aSpace, &nEntry); |
| 41094 | p->aSegment[i].iZero = iZero; |
| 41095 | p->aSegment[i].nEntry = nEntry; |
| 41096 | p->aSegment[i].aIndex = aSpace; |
| 41097 | p->aSegment[i].aPgno = (u32 *)aPgno; |
| 41098 | aSpace += HASHTABLE_NPAGE; |
| 41099 | } |
| 41100 | assert( aSpace==aTmp ); |
| 41101 | |
| 41102 | /* Return the fully initialized WalIterator object */ |
| 41103 | *pp = p; |
| 41104 | return SQLITE_OK ; |
| 41105 | } |
| 41106 | |
| 41107 | /* |
| 41108 | ** Copy as much content as we can from the WAL back into the database file |
| 41109 | ** in response to an sqlite3_wal_checkpoint() request or the equivalent. |
| @@ -41148,15 +41210,18 @@ | |
| 41148 | u32 iFrame = 0; /* Wal frame containing data for iDbpage */ |
| 41149 | u32 mxSafeFrame; /* Max frame that can be backfilled */ |
| 41150 | int i; /* Loop counter */ |
| 41151 | volatile WalCkptInfo *pInfo; /* The checkpoint status information */ |
| 41152 | |
| 41153 | /* Allocate the iterator */ |
| 41154 | rc = walIteratorInit(pWal, &pIter); |
| 41155 | if( rc!=SQLITE_OK || pWal->hdr.mxFrame==0 ){ |
| 41156 | goto walcheckpoint_out; |
| 41157 | } |
| 41158 | |
| 41159 | /*** TODO: Move this test out to the caller. Make it an assert() here ***/ |
| 41160 | if( pWal->hdr.szPage!=nBuf ){ |
| 41161 | rc = SQLITE_CORRUPT_BKPT; |
| 41162 | goto walcheckpoint_out; |
| @@ -52950,13 +53015,20 @@ | |
| 52950 | if( !pExpr ){ |
| 52951 | *ppVal = 0; |
| 52952 | return SQLITE_OK; |
| 52953 | } |
| 52954 | op = pExpr->op; |
| 52955 | if( op==TK_REGISTER ){ |
| 52956 | op = pExpr->op2; /* This only happens with SQLITE_ENABLE_STAT2 */ |
| 52957 | } |
| 52958 | |
| 52959 | if( op==TK_STRING || op==TK_FLOAT || op==TK_INTEGER ){ |
| 52960 | pVal = sqlite3ValueNew(db); |
| 52961 | if( pVal==0 ) goto no_mem; |
| 52962 | if( ExprHasProperty(pExpr, EP_IntValue) ){ |
| 52963 |
| --- src/sqlite3.c | |
| +++ src/sqlite3.c | |
| @@ -636,11 +636,11 @@ | |
| 636 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 637 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 638 | */ |
| 639 | #define SQLITE_VERSION "3.7.0" |
| 640 | #define SQLITE_VERSION_NUMBER 3007000 |
| 641 | #define SQLITE_SOURCE_ID "2010-06-26 20:25:31 f149b498b6ada3fc9f71ee104c351554c80c7f8a" |
| 642 | |
| 643 | /* |
| 644 | ** CAPI3REF: Run-Time Library Version Numbers |
| 645 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 646 | ** |
| @@ -16802,15 +16802,15 @@ | |
| 16802 | SQLITE_PRIVATE void *sqlite3ScratchMalloc(int n){ |
| 16803 | void *p; |
| 16804 | assert( n>0 ); |
| 16805 | |
| 16806 | #if SQLITE_THREADSAFE==0 && !defined(NDEBUG) |
| 16807 | /* Verify that no more than two scratch allocation per thread |
| 16808 | ** is outstanding at one time. (This is only checked in the |
| 16809 | ** single-threaded case since checking in the multi-threaded case |
| 16810 | ** would be much more complicated.) */ |
| 16811 | assert( scratchAllocOut<=1 ); |
| 16812 | #endif |
| 16813 | |
| 16814 | if( sqlite3GlobalConfig.szScratch<n ){ |
| 16815 | goto scratch_overflow; |
| 16816 | }else{ |
| @@ -16851,20 +16851,10 @@ | |
| 16851 | #endif |
| 16852 | return p; |
| 16853 | } |
| 16854 | SQLITE_PRIVATE void sqlite3ScratchFree(void *p){ |
| 16855 | if( p ){ |
| 16856 | if( sqlite3GlobalConfig.pScratch==0 |
| 16857 | || p<sqlite3GlobalConfig.pScratch |
| 16858 | || p>=(void*)mem0.aScratchFree ){ |
| 16859 | assert( sqlite3MemdebugHasType(p, MEMTYPE_SCRATCH) ); |
| 16860 | sqlite3MemdebugSetType(p, MEMTYPE_HEAP); |
| @@ -16886,10 +16876,20 @@ | |
| 16876 | sqlite3_mutex_enter(mem0.mutex); |
| 16877 | assert( mem0.nScratchFree<(u32)sqlite3GlobalConfig.nScratch ); |
| 16878 | mem0.aScratchFree[mem0.nScratchFree++] = i; |
| 16879 | sqlite3StatusAdd(SQLITE_STATUS_SCRATCH_USED, -1); |
| 16880 | sqlite3_mutex_leave(mem0.mutex); |
| 16881 | |
| 16882 | #if SQLITE_THREADSAFE==0 && !defined(NDEBUG) |
| 16883 | /* Verify that no more than two scratch allocation per thread |
| 16884 | ** is outstanding at one time. (This is only checked in the |
| 16885 | ** single-threaded case since checking in the multi-threaded case |
| 16886 | ** would be much more complicated.) */ |
| 16887 | assert( scratchAllocOut>=1 && scratchAllocOut<=2 ); |
| 16888 | scratchAllocOut = 0; |
| 16889 | #endif |
| 16890 | |
| 16891 | } |
| 16892 | } |
| 16893 | } |
| 16894 | |
| 16895 | /* |
| @@ -30142,11 +30142,11 @@ | |
| 30142 | sqlite3_free(p); |
| 30143 | return SQLITE_NOMEM; |
| 30144 | } |
| 30145 | memset(pNew, 0, sizeof(*pNew)); |
| 30146 | pNew->zFilename = (char*)&pNew[1]; |
| 30147 | sqlite3_snprintf(nName+15, pNew->zFilename, "%s-shm", pDbFd->zPath); |
| 30148 | |
| 30149 | /* Look to see if there is an existing winShmNode that can be used. |
| 30150 | ** If no matching winShmNode currently exists, create a new one. |
| 30151 | */ |
| 30152 | winShmEnterMutex(); |
| @@ -33860,16 +33860,19 @@ | |
| 33860 | ** may attempt to commit the transaction again later (calling |
| 33861 | ** CommitPhaseOne() again). This flag is used to ensure that the |
| 33862 | ** master journal name is only written to the journal file the first |
| 33863 | ** time CommitPhaseOne() is called. |
| 33864 | ** |
| 33865 | ** doNotSpill, doNotSyncSpill |
| 33866 | ** |
| 33867 | ** When enabled, cache spills are prohibited. The doNotSpill variable |
| 33868 | ** inhibits all cache spill and doNotSyncSpill inhibits those spills that |
| 33869 | ** would require a journal sync. The doNotSyncSpill is set and cleared |
| 33870 | ** by sqlite3PagerWrite() in order to prevent a journal sync from happening |
| 33871 | ** in between the journalling of two pages on the same sector. The |
| 33872 | ** doNotSpill value set to prevent pagerStress() from trying to use |
| 33873 | ** the journal during a rollback. |
| 33874 | ** |
| 33875 | ** needSync |
| 33876 | ** |
| 33877 | ** TODO: It might be easier to set this variable in writeJournalHdr() |
| 33878 | ** and writeMasterJournal() only. Change its meaning to "unsynced data |
| @@ -33909,11 +33912,12 @@ | |
| 33912 | u8 dbModified; /* True if there are any changes to the Db */ |
| 33913 | u8 needSync; /* True if an fsync() is needed on the journal */ |
| 33914 | u8 journalStarted; /* True if header of journal is synced */ |
| 33915 | u8 changeCountDone; /* Set after incrementing the change-counter */ |
| 33916 | u8 setMaster; /* True if a m-j name has been written to jrnl */ |
| 33917 | u8 doNotSpill; /* Do not spill the cache when non-zero */ |
| 33918 | u8 doNotSyncSpill; /* Do not do a spill that requires jrnl sync */ |
| 33919 | u8 dbSizeValid; /* Set when dbSize is correct */ |
| 33920 | u8 subjInMemory; /* True to use in-memory sub-journals */ |
| 33921 | Pgno dbSize; /* Number of pages in the database */ |
| 33922 | Pgno dbOrigSize; /* dbSize before the current transaction */ |
| 33923 | Pgno dbFileSize; /* Number of pages in the database file */ |
| @@ -35245,13 +35249,16 @@ | |
| 35249 | ** the data just read from the sub-journal. Mark the page as dirty |
| 35250 | ** and if the pager requires a journal-sync, then mark the page as |
| 35251 | ** requiring a journal-sync before it is written. |
| 35252 | */ |
| 35253 | assert( isSavepnt ); |
| 35254 | assert( pPager->doNotSpill==0 ); |
| 35255 | pPager->doNotSpill++; |
| 35256 | rc = sqlite3PagerAcquire(pPager, pgno, &pPg, 1); |
| 35257 | assert( pPager->doNotSpill==1 ); |
| 35258 | pPager->doNotSpill--; |
| 35259 | if( rc!=SQLITE_OK ) return rc; |
| 35260 | pPg->flags &= ~PGHDR_NEED_READ; |
| 35261 | sqlite3PcacheMakeDirty(pPg); |
| 35262 | } |
| 35263 | if( pPg ){ |
| 35264 | /* No page should ever be explicitly rolled back that is in use, except |
| @@ -37068,10 +37075,26 @@ | |
| 37075 | Pager *pPager = (Pager *)p; |
| 37076 | int rc = SQLITE_OK; |
| 37077 | |
| 37078 | assert( pPg->pPager==pPager ); |
| 37079 | assert( pPg->flags&PGHDR_DIRTY ); |
| 37080 | |
| 37081 | /* The doNotSyncSpill flag is set during times when doing a sync of |
| 37082 | ** journal (and adding a new header) is not allowed. This occurs |
| 37083 | ** during calls to sqlite3PagerWrite() while trying to journal multiple |
| 37084 | ** pages belonging to the same sector. |
| 37085 | ** |
| 37086 | ** The doNotSpill flag inhibits all cache spilling regardless of whether |
| 37087 | ** or not a sync is required. This is set during a rollback. |
| 37088 | ** |
| 37089 | ** Spilling is also inhibited when in an error state. |
| 37090 | */ |
| 37091 | if( pPager->errCode ) return SQLITE_OK; |
| 37092 | if( pPager->doNotSpill ) return SQLITE_OK; |
| 37093 | if( pPager->doNotSyncSpill && (pPg->flags & PGHDR_NEED_SYNC)!=0 ){ |
| 37094 | return SQLITE_OK; |
| 37095 | } |
| 37096 | |
| 37097 | pPg->pDirty = 0; |
| 37098 | if( pagerUseWal(pPager) ){ |
| 37099 | /* Write a single frame for this page to the log. */ |
| 37100 | if( subjRequiresPage(pPg) ){ |
| @@ -37079,31 +37102,16 @@ | |
| 37102 | } |
| 37103 | if( rc==SQLITE_OK ){ |
| 37104 | rc = pagerWalFrames(pPager, pPg, 0, 0, 0); |
| 37105 | } |
| 37106 | }else{ |
| 37107 | |
| 37108 | /* Sync the journal file if required. */ |
| 37109 | if( pPg->flags&PGHDR_NEED_SYNC ){ |
| 37110 | assert( !pPager->noSync ); |
| 37111 | rc = syncJournal(pPager); |
| 37112 | if( rc==SQLITE_OK && |
| 37113 | !(pPager->journalMode==PAGER_JOURNALMODE_MEMORY) && |
| 37114 | !(sqlite3OsDeviceCharacteristics(pPager->fd)&SQLITE_IOCAP_SAFE_APPEND) |
| 37115 | ){ |
| 37116 | pPager->nRec = 0; |
| 37117 | rc = writeJournalHdr(pPager); |
| @@ -38385,39 +38393,41 @@ | |
| 38393 | Pgno nPagePerSector = (pPager->sectorSize/pPager->pageSize); |
| 38394 | |
| 38395 | if( nPagePerSector>1 ){ |
| 38396 | Pgno nPageCount; /* Total number of pages in database file */ |
| 38397 | Pgno pg1; /* First page of the sector pPg is located on. */ |
| 38398 | int nPage = 0; /* Number of pages starting at pg1 to journal */ |
| 38399 | int ii; /* Loop counter */ |
| 38400 | int needSync = 0; /* True if any page has PGHDR_NEED_SYNC */ |
| 38401 | |
| 38402 | /* Set the doNotSyncSpill flag to 1. This is because we cannot allow |
| 38403 | ** a journal header to be written between the pages journaled by |
| 38404 | ** this function. |
| 38405 | */ |
| 38406 | assert( !MEMDB ); |
| 38407 | assert( pPager->doNotSyncSpill==0 ); |
| 38408 | pPager->doNotSyncSpill++; |
| 38409 | |
| 38410 | /* This trick assumes that both the page-size and sector-size are |
| 38411 | ** an integer power of 2. It sets variable pg1 to the identifier |
| 38412 | ** of the first page of the sector pPg is located on. |
| 38413 | */ |
| 38414 | pg1 = ((pPg->pgno-1) & ~(nPagePerSector-1)) + 1; |
| 38415 | |
| 38416 | rc = sqlite3PagerPagecount(pPager, (int *)&nPageCount); |
| 38417 | if( rc==SQLITE_OK ){ |
| 38418 | if( pPg->pgno>nPageCount ){ |
| 38419 | nPage = (pPg->pgno - pg1)+1; |
| 38420 | }else if( (pg1+nPagePerSector-1)>nPageCount ){ |
| 38421 | nPage = nPageCount+1-pg1; |
| 38422 | }else{ |
| 38423 | nPage = nPagePerSector; |
| 38424 | } |
| 38425 | assert(nPage>0); |
| 38426 | assert(pg1<=pPg->pgno); |
| 38427 | assert((pg1+nPage)>pPg->pgno); |
| 38428 | } |
| 38429 | |
| 38430 | for(ii=0; ii<nPage && rc==SQLITE_OK; ii++){ |
| 38431 | Pgno pg = pg1+ii; |
| 38432 | PgHdr *pPage; |
| 38433 | if( pg==pPg->pgno || !sqlite3BitvecTest(pPager->pInJournal, pg) ){ |
| @@ -38456,12 +38466,12 @@ | |
| 38466 | } |
| 38467 | } |
| 38468 | assert(pPager->needSync); |
| 38469 | } |
| 38470 | |
| 38471 | assert( pPager->doNotSyncSpill==1 ); |
| 38472 | pPager->doNotSyncSpill--; |
| 38473 | }else{ |
| 38474 | rc = pager_write(pDbPage); |
| 38475 | } |
| 38476 | return rc; |
| 38477 | } |
| @@ -38825,14 +38835,15 @@ | |
| 38835 | ** But if (due to a coding error elsewhere in the system) it does get |
| 38836 | ** called, just return the same error code without doing anything. */ |
| 38837 | if( NEVER(pPager->errCode) ) return pPager->errCode; |
| 38838 | |
| 38839 | /* This function should not be called if the pager is not in at least |
| 38840 | ** PAGER_RESERVED state. **FIXME**: Make it so that this test always |
| 38841 | ** fails - make it so that we never reach this point if we do not hold |
| 38842 | ** all necessary locks. |
| 38843 | */ |
| 38844 | if( pPager->state<PAGER_RESERVED ) return SQLITE_ERROR; |
| 38845 | |
| 38846 | /* An optimization. If the database was not actually modified during |
| 38847 | ** this transaction, the pager is running in exclusive-mode and is |
| 38848 | ** using persistent journals, then this function is a no-op. |
| 38849 | ** |
| @@ -40961,53 +40972,101 @@ | |
| 40972 | |
| 40973 | *piPage = p->iPrior = iRet; |
| 40974 | return (iRet==0xFFFFFFFF); |
| 40975 | } |
| 40976 | |
| 40977 | /* |
| 40978 | ** This function merges two sorted lists into a single sorted list. |
| 40979 | */ |
| 40980 | static void walMerge( |
| 40981 | u32 *aContent, /* Pages in wal */ |
| 40982 | ht_slot *aLeft, /* IN: Left hand input list */ |
| 40983 | int nLeft, /* IN: Elements in array *paLeft */ |
| 40984 | ht_slot **paRight, /* IN/OUT: Right hand input list */ |
| 40985 | int *pnRight, /* IN/OUT: Elements in *paRight */ |
| 40986 | ht_slot *aTmp /* Temporary buffer */ |
| 40987 | ){ |
| 40988 | int iLeft = 0; /* Current index in aLeft */ |
| 40989 | int iRight = 0; /* Current index in aRight */ |
| 40990 | int iOut = 0; /* Current index in output buffer */ |
| 40991 | int nRight = *pnRight; |
| 40992 | ht_slot *aRight = *paRight; |
| 40993 | |
| 40994 | assert( nLeft>0 && nRight>0 ); |
| 40995 | while( iRight<nRight || iLeft<nLeft ){ |
| 40996 | ht_slot logpage; |
| 40997 | Pgno dbpage; |
| 40998 | |
| 40999 | if( (iLeft<nLeft) |
| 41000 | && (iRight>=nRight || aContent[aLeft[iLeft]]<aContent[aRight[iRight]]) |
| 41001 | ){ |
| 41002 | logpage = aLeft[iLeft++]; |
| 41003 | }else{ |
| 41004 | logpage = aRight[iRight++]; |
| 41005 | } |
| 41006 | dbpage = aContent[logpage]; |
| 41007 | |
| 41008 | aTmp[iOut++] = logpage; |
| 41009 | if( iLeft<nLeft && aContent[aLeft[iLeft]]==dbpage ) iLeft++; |
| 41010 | |
| 41011 | assert( iLeft>=nLeft || aContent[aLeft[iLeft]]>dbpage ); |
| 41012 | assert( iRight>=nRight || aContent[aRight[iRight]]>dbpage ); |
| 41013 | } |
| 41014 | |
| 41015 | *paRight = aLeft; |
| 41016 | *pnRight = iOut; |
| 41017 | memcpy(aLeft, aTmp, sizeof(aTmp[0])*iOut); |
| 41018 | } |
| 41019 | |
| 41020 | /* |
| 41021 | ** Sort the elements in list aList, removing any duplicates. |
| 41022 | */ |
| 41023 | static void walMergesort( |
| 41024 | u32 *aContent, /* Pages in wal */ |
| 41025 | ht_slot *aBuffer, /* Buffer of at least *pnList items to use */ |
| 41026 | ht_slot *aList, /* IN/OUT: List to sort */ |
| 41027 | int *pnList /* IN/OUT: Number of elements in aList[] */ |
| 41028 | ){ |
| 41029 | struct Sublist { |
| 41030 | int nList; /* Number of elements in aList */ |
| 41031 | ht_slot *aList; /* Pointer to sub-list content */ |
| 41032 | }; |
| 41033 | |
| 41034 | const int nList = *pnList; /* Size of input list */ |
| 41035 | int nMerge; /* Number of elements in list aMerge */ |
| 41036 | ht_slot *aMerge; /* List to be merged */ |
| 41037 | int iList; /* Index into input list */ |
| 41038 | int iSub = 0; /* Index into aSub array */ |
| 41039 | struct Sublist aSub[13]; /* Array of sub-lists */ |
| 41040 | |
| 41041 | memset(aSub, 0, sizeof(aSub)); |
| 41042 | assert( nList<=HASHTABLE_NPAGE && nList>0 ); |
| 41043 | assert( HASHTABLE_NPAGE==(1<<(ArraySize(aSub)-1)) ); |
| 41044 | |
| 41045 | for(iList=0; iList<nList; iList++){ |
| 41046 | nMerge = 1; |
| 41047 | aMerge = &aList[iList]; |
| 41048 | for(iSub=0; iList & (1<<iSub); iSub++){ |
| 41049 | struct Sublist *p = &aSub[iSub]; |
| 41050 | assert( p->aList && p->nList<=(1<<iSub) ); |
| 41051 | assert( p->aList==&aList[iList&~((2<<iSub)-1)] ); |
| 41052 | walMerge(aContent, p->aList, p->nList, &aMerge, &nMerge, aBuffer); |
| 41053 | } |
| 41054 | aSub[iSub].aList = aMerge; |
| 41055 | aSub[iSub].nList = nMerge; |
| 41056 | } |
| 41057 | |
| 41058 | for(iSub++; iSub<ArraySize(aSub); iSub++){ |
| 41059 | if( nList & (1<<iSub) ){ |
| 41060 | struct Sublist *p = &aSub[iSub]; |
| 41061 | assert( p->nList<=(1<<iSub) ); |
| 41062 | assert( p->aList==&aList[nList&~((2<<iSub)-1)] ); |
| 41063 | walMerge(aContent, p->aList, p->nList, &aMerge, &nMerge, aBuffer); |
| 41064 | } |
| 41065 | } |
| 41066 | assert( aMerge==aList ); |
| 41067 | *pnList = nMerge; |
| 41068 | |
| 41069 | #ifdef SQLITE_DEBUG |
| 41070 | { |
| 41071 | int i; |
| 41072 | for(i=1; i<*pnList; i++){ |
| @@ -41019,91 +41078,94 @@ | |
| 41078 | |
| 41079 | /* |
| 41080 | ** Free an iterator allocated by walIteratorInit(). |
| 41081 | */ |
| 41082 | static void walIteratorFree(WalIterator *p){ |
| 41083 | sqlite3ScratchFree(p); |
| 41084 | } |
| 41085 | |
| 41086 | /* |
| 41087 | ** Construct a WalInterator object that can be used to loop over all |
| 41088 | ** pages in the WAL in ascending order. The caller must hold the checkpoint |
| 41089 | ** |
| 41090 | ** On success, make *pp point to the newly allocated WalInterator object |
| 41091 | ** return SQLITE_OK. Otherwise, return an error code. If this routine |
| 41092 | ** returns an error, the value of *pp is undefined. |
| 41093 | ** |
| 41094 | ** The calling routine should invoke walIteratorFree() to destroy the |
| 41095 | ** WalIterator object when it has finished with it. |
| 41096 | */ |
| 41097 | static int walIteratorInit(Wal *pWal, WalIterator **pp){ |
| 41098 | WalIterator *p; /* Return value */ |
| 41099 | int nSegment; /* Number of segments to merge */ |
| 41100 | u32 iLast; /* Last frame in log */ |
| 41101 | int nByte; /* Number of bytes to allocate */ |
| 41102 | int i; /* Iterator variable */ |
| 41103 | ht_slot *aTmp; /* Temp space used by merge-sort */ |
| 41104 | int rc = SQLITE_OK; /* Return Code */ |
| 41105 | |
| 41106 | /* This routine only runs while holding the checkpoint lock. And |
| 41107 | ** it only runs if there is actually content in the log (mxFrame>0). |
| 41108 | */ |
| 41109 | assert( pWal->ckptLock && pWal->hdr.mxFrame>0 ); |
| 41110 | iLast = pWal->hdr.mxFrame; |
| 41111 | |
| 41112 | /* Allocate space for the WalIterator object. */ |
| 41113 | nSegment = walFramePage(iLast) + 1; |
| 41114 | nByte = sizeof(WalIterator) |
| 41115 | + (nSegment-1)*sizeof(struct WalSegment) |
| 41116 | + iLast*sizeof(ht_slot); |
| 41117 | p = (WalIterator *)sqlite3ScratchMalloc(nByte); |
| 41118 | if( !p ){ |
| 41119 | return SQLITE_NOMEM; |
| 41120 | } |
| 41121 | memset(p, 0, nByte); |
| 41122 | p->nSegment = nSegment; |
| 41123 | |
| 41124 | /* Allocate temporary space used by the merge-sort routine. This block |
| 41125 | ** of memory will be freed before this function returns. |
| 41126 | */ |
| 41127 | aTmp = (ht_slot *)sqlite3ScratchMalloc( |
| 41128 | sizeof(ht_slot) * (iLast>HASHTABLE_NPAGE?HASHTABLE_NPAGE:iLast) |
| 41129 | ); |
| 41130 | if( !aTmp ){ |
| 41131 | rc = SQLITE_NOMEM; |
| 41132 | } |
| 41133 | |
| 41134 | for(i=0; rc==SQLITE_OK && i<nSegment; i++){ |
| 41135 | volatile ht_slot *aHash; |
| 41136 | u32 iZero; |
| 41137 | volatile u32 *aPgno; |
| 41138 | |
| 41139 | rc = walHashGet(pWal, i, &aHash, &aPgno, &iZero); |
| 41140 | if( rc==SQLITE_OK ){ |
| 41141 | int j; /* Counter variable */ |
| 41142 | int nEntry; /* Number of entries in this segment */ |
| 41143 | ht_slot *aIndex; /* Sorted index for this segment */ |
| 41144 | |
| 41145 | aPgno++; |
| 41146 | nEntry = ((i+1)==nSegment)?iLast-iZero:(u32 *)aHash-(u32 *)aPgno; |
| 41147 | aIndex = &((ht_slot *)&p->aSegment[p->nSegment])[iZero]; |
| 41148 | iZero++; |
| 41149 | |
| 41150 | for(j=0; j<nEntry; j++){ |
| 41151 | aIndex[j] = j; |
| 41152 | } |
| 41153 | walMergesort((u32 *)aPgno, aTmp, aIndex, &nEntry); |
| 41154 | p->aSegment[i].iZero = iZero; |
| 41155 | p->aSegment[i].nEntry = nEntry; |
| 41156 | p->aSegment[i].aIndex = aIndex; |
| 41157 | p->aSegment[i].aPgno = (u32 *)aPgno; |
| 41158 | } |
| 41159 | } |
| 41160 | sqlite3ScratchFree(aTmp); |
| 41161 | |
| 41162 | if( rc!=SQLITE_OK ){ |
| 41163 | walIteratorFree(p); |
| 41164 | } |
| 41165 | *pp = p; |
| 41166 | return rc; |
| 41167 | } |
| 41168 | |
| 41169 | /* |
| 41170 | ** Copy as much content as we can from the WAL back into the database file |
| 41171 | ** in response to an sqlite3_wal_checkpoint() request or the equivalent. |
| @@ -41148,15 +41210,18 @@ | |
| 41210 | u32 iFrame = 0; /* Wal frame containing data for iDbpage */ |
| 41211 | u32 mxSafeFrame; /* Max frame that can be backfilled */ |
| 41212 | int i; /* Loop counter */ |
| 41213 | volatile WalCkptInfo *pInfo; /* The checkpoint status information */ |
| 41214 | |
| 41215 | if( pWal->hdr.mxFrame==0 ) return SQLITE_OK; |
| 41216 | |
| 41217 | /* Allocate the iterator */ |
| 41218 | rc = walIteratorInit(pWal, &pIter); |
| 41219 | if( rc!=SQLITE_OK ){ |
| 41220 | return rc; |
| 41221 | } |
| 41222 | assert( pIter ); |
| 41223 | |
| 41224 | /*** TODO: Move this test out to the caller. Make it an assert() here ***/ |
| 41225 | if( pWal->hdr.szPage!=nBuf ){ |
| 41226 | rc = SQLITE_CORRUPT_BKPT; |
| 41227 | goto walcheckpoint_out; |
| @@ -52950,13 +53015,20 @@ | |
| 53015 | if( !pExpr ){ |
| 53016 | *ppVal = 0; |
| 53017 | return SQLITE_OK; |
| 53018 | } |
| 53019 | op = pExpr->op; |
| 53020 | |
| 53021 | /* op can only be TK_REGISTER is we have compiled with SQLITE_ENABLE_STAT2. |
| 53022 | ** The ifdef here is to enable us to achieve 100% branch test coverage even |
| 53023 | ** when SQLITE_ENABLE_STAT2 is omitted. |
| 53024 | */ |
| 53025 | #ifdef SQLITE_ENABLE_STAT2 |
| 53026 | if( op==TK_REGISTER ) op = pExpr->op2; |
| 53027 | #else |
| 53028 | if( NEVER(op==TK_REGISTER) ) op = pExpr->op2; |
| 53029 | #endif |
| 53030 | |
| 53031 | if( op==TK_STRING || op==TK_FLOAT || op==TK_INTEGER ){ |
| 53032 | pVal = sqlite3ValueNew(db); |
| 53033 | if( pVal==0 ) goto no_mem; |
| 53034 | if( ExprHasProperty(pExpr, EP_IntValue) ){ |
| 53035 |
+1
-1
| --- src/sqlite3.h | ||
| +++ src/sqlite3.h | ||
| @@ -107,11 +107,11 @@ | ||
| 107 | 107 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 108 | 108 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 109 | 109 | */ |
| 110 | 110 | #define SQLITE_VERSION "3.7.0" |
| 111 | 111 | #define SQLITE_VERSION_NUMBER 3007000 |
| 112 | -#define SQLITE_SOURCE_ID "2010-06-24 10:50:18 7aac9ad6dd14b1c56eb8e4750ac769c6197c30bd" | |
| 112 | +#define SQLITE_SOURCE_ID "2010-06-26 20:25:31 f149b498b6ada3fc9f71ee104c351554c80c7f8a" | |
| 113 | 113 | |
| 114 | 114 | /* |
| 115 | 115 | ** CAPI3REF: Run-Time Library Version Numbers |
| 116 | 116 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 117 | 117 | ** |
| 118 | 118 |
| --- src/sqlite3.h | |
| +++ src/sqlite3.h | |
| @@ -107,11 +107,11 @@ | |
| 107 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 108 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 109 | */ |
| 110 | #define SQLITE_VERSION "3.7.0" |
| 111 | #define SQLITE_VERSION_NUMBER 3007000 |
| 112 | #define SQLITE_SOURCE_ID "2010-06-24 10:50:18 7aac9ad6dd14b1c56eb8e4750ac769c6197c30bd" |
| 113 | |
| 114 | /* |
| 115 | ** CAPI3REF: Run-Time Library Version Numbers |
| 116 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 117 | ** |
| 118 |
| --- src/sqlite3.h | |
| +++ src/sqlite3.h | |
| @@ -107,11 +107,11 @@ | |
| 107 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 108 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 109 | */ |
| 110 | #define SQLITE_VERSION "3.7.0" |
| 111 | #define SQLITE_VERSION_NUMBER 3007000 |
| 112 | #define SQLITE_SOURCE_ID "2010-06-26 20:25:31 f149b498b6ada3fc9f71ee104c351554c80c7f8a" |
| 113 | |
| 114 | /* |
| 115 | ** CAPI3REF: Run-Time Library Version Numbers |
| 116 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 117 | ** |
| 118 |