Fossil SCM
Update SQLite to the latest beta of 3.7.0. This provides much better server concurrency when the repository database file is set to WAL mode.
Commit
fb5f0c2580008d896dfe1fcd669c6b80b34988d9
Parent
515814f8e72ff2c…
2 files changed
+185
-108
+1
-1
+185
-108
| --- 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-26 20:25:31 f149b498b6ada3fc9f71ee104c351554c80c7f8a" | |
| 641 | +#define SQLITE_SOURCE_ID "2010-07-03 13:59:01 3b20ad03be55613d922d81aec5313327bf4098b9" | |
| 642 | 642 | |
| 643 | 643 | /* |
| 644 | 644 | ** CAPI3REF: Run-Time Library Version Numbers |
| 645 | 645 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 646 | 646 | ** |
| @@ -12795,12 +12795,14 @@ | ||
| 12795 | 12795 | ** sqlite3OsWrite() |
| 12796 | 12796 | ** sqlite3OsSync() |
| 12797 | 12797 | ** sqlite3OsLock() |
| 12798 | 12798 | ** |
| 12799 | 12799 | */ |
| 12800 | -#if defined(SQLITE_TEST) && (SQLITE_OS_WIN==0) | |
| 12801 | - #define DO_OS_MALLOC_TEST(x) if (!x || !sqlite3IsMemJournal(x)) { \ | |
| 12800 | +#if defined(SQLITE_TEST) | |
| 12801 | +SQLITE_API int sqlite3_memdebug_vfs_oom_test = 1; | |
| 12802 | + #define DO_OS_MALLOC_TEST(x) \ | |
| 12803 | + if (sqlite3_memdebug_vfs_oom_test && (!x || !sqlite3IsMemJournal(x))) { \ | |
| 12802 | 12804 | void *pTstAlloc = sqlite3Malloc(10); \ |
| 12803 | 12805 | if (!pTstAlloc) return SQLITE_IOERR_NOMEM; \ |
| 12804 | 12806 | sqlite3_free(pTstAlloc); \ |
| 12805 | 12807 | } |
| 12806 | 12808 | #else |
| @@ -15367,15 +15369,21 @@ | ||
| 15367 | 15369 | ** |
| 15368 | 15370 | ** This routines provide no mutual exclusion or error checking. |
| 15369 | 15371 | */ |
| 15370 | 15372 | static int noopMutexInit(void){ return SQLITE_OK; } |
| 15371 | 15373 | static int noopMutexEnd(void){ return SQLITE_OK; } |
| 15372 | -static sqlite3_mutex *noopMutexAlloc(int id){ return (sqlite3_mutex*)8; } | |
| 15373 | -static void noopMutexFree(sqlite3_mutex *p){ return; } | |
| 15374 | -static void noopMutexEnter(sqlite3_mutex *p){ return; } | |
| 15375 | -static int noopMutexTry(sqlite3_mutex *p){ return SQLITE_OK; } | |
| 15376 | -static void noopMutexLeave(sqlite3_mutex *p){ return; } | |
| 15374 | +static sqlite3_mutex *noopMutexAlloc(int id){ | |
| 15375 | + UNUSED_PARAMETER(id); | |
| 15376 | + return (sqlite3_mutex*)8; | |
| 15377 | +} | |
| 15378 | +static void noopMutexFree(sqlite3_mutex *p){ UNUSED_PARAMETER(p); return; } | |
| 15379 | +static void noopMutexEnter(sqlite3_mutex *p){ UNUSED_PARAMETER(p); return; } | |
| 15380 | +static int noopMutexTry(sqlite3_mutex *p){ | |
| 15381 | + UNUSED_PARAMETER(p); | |
| 15382 | + return SQLITE_OK; | |
| 15383 | +} | |
| 15384 | +static void noopMutexLeave(sqlite3_mutex *p){ UNUSED_PARAMETER(p); return; } | |
| 15377 | 15385 | |
| 15378 | 15386 | SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3NoopMutex(void){ |
| 15379 | 15387 | static const sqlite3_mutex_methods sMutex = { |
| 15380 | 15388 | noopMutexInit, |
| 15381 | 15389 | noopMutexEnd, |
| @@ -15524,11 +15532,11 @@ | ||
| 15524 | 15532 | ** If compiled with SQLITE_MUTEX_NOOP, then the no-op mutex implementation |
| 15525 | 15533 | ** is used regardless of the run-time threadsafety setting. |
| 15526 | 15534 | */ |
| 15527 | 15535 | #ifdef SQLITE_MUTEX_NOOP |
| 15528 | 15536 | SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){ |
| 15529 | - return sqliteNoopMutex(); | |
| 15537 | + return sqlite3NoopMutex(); | |
| 15530 | 15538 | } |
| 15531 | 15539 | #endif /* SQLITE_MUTEX_NOOP */ |
| 15532 | 15540 | #endif /* SQLITE_MUTEX_OMIT */ |
| 15533 | 15541 | |
| 15534 | 15542 | /************** End of mutex_noop.c ******************************************/ |
| @@ -25957,10 +25965,11 @@ | ||
| 25957 | 25965 | ** any load or store begun after the barrier. |
| 25958 | 25966 | */ |
| 25959 | 25967 | static void unixShmBarrier( |
| 25960 | 25968 | sqlite3_file *fd /* Database file holding the shared memory */ |
| 25961 | 25969 | ){ |
| 25970 | + UNUSED_PARAMETER(fd); | |
| 25962 | 25971 | unixEnterMutex(); |
| 25963 | 25972 | unixLeaveMutex(); |
| 25964 | 25973 | } |
| 25965 | 25974 | |
| 25966 | 25975 | /* |
| @@ -27249,10 +27258,11 @@ | ||
| 27249 | 27258 | ** current time and date as a Julian Day number into *prNow and |
| 27250 | 27259 | ** return 0. Return 1 if the time and date cannot be found. |
| 27251 | 27260 | */ |
| 27252 | 27261 | static int unixCurrentTime(sqlite3_vfs *NotUsed, double *prNow){ |
| 27253 | 27262 | sqlite3_int64 i; |
| 27263 | + UNUSED_PARAMETER(NotUsed); | |
| 27254 | 27264 | unixCurrentTimeInt64(0, &i); |
| 27255 | 27265 | *prNow = i/86400000.0; |
| 27256 | 27266 | return 0; |
| 27257 | 27267 | } |
| 27258 | 27268 | |
| @@ -27476,11 +27486,11 @@ | ||
| 27476 | 27486 | len = strlcat(lPath, "/", maxLen); |
| 27477 | 27487 | } |
| 27478 | 27488 | |
| 27479 | 27489 | /* transform the db path to a unique cache name */ |
| 27480 | 27490 | dbLen = (int)strlen(dbPath); |
| 27481 | - for( i=0; i<dbLen && (i+len+7)<maxLen; i++){ | |
| 27491 | + for( i=0; i<dbLen && (i+len+7)<(int)maxLen; i++){ | |
| 27482 | 27492 | char c = dbPath[i]; |
| 27483 | 27493 | lPath[i+len] = (c=='/')?'_':c; |
| 27484 | 27494 | } |
| 27485 | 27495 | lPath[i+len]='\0'; |
| 27486 | 27496 | strlcat(lPath, ":auto:", maxLen); |
| @@ -27617,10 +27627,13 @@ | ||
| 27617 | 27627 | SQLITE_API int sqlite3_hostid_num = 0; |
| 27618 | 27628 | #endif |
| 27619 | 27629 | |
| 27620 | 27630 | #define PROXY_HOSTIDLEN 16 /* conch file host id length */ |
| 27621 | 27631 | |
| 27632 | +/* Not always defined in the headers as it ought to be */ | |
| 27633 | +extern int gethostuuid(uuid_t id, const struct timespec *wait); | |
| 27634 | + | |
| 27622 | 27635 | /* get the host ID via gethostuuid(), pHostID must point to PROXY_HOSTIDLEN |
| 27623 | 27636 | ** bytes of writable memory. |
| 27624 | 27637 | */ |
| 27625 | 27638 | static int proxyGetHostID(unsigned char *pHostID, int *pError){ |
| 27626 | 27639 | struct timespec timeout = {1, 0}; /* 1 sec timeout */ |
| @@ -27666,10 +27679,11 @@ | ||
| 27666 | 27679 | size_t readLen = 0; |
| 27667 | 27680 | size_t pathLen = 0; |
| 27668 | 27681 | char errmsg[64] = ""; |
| 27669 | 27682 | int fd = -1; |
| 27670 | 27683 | int rc = -1; |
| 27684 | + UNUSED_PARAMETER(myHostID); | |
| 27671 | 27685 | |
| 27672 | 27686 | /* create a new path by replace the trailing '-conch' with '-break' */ |
| 27673 | 27687 | pathLen = strlcpy(tPath, cPath, MAXPATHLEN); |
| 27674 | 27688 | if( pathLen>MAXPATHLEN || pathLen<6 || |
| 27675 | 27689 | (strlcpy(&tPath[pathLen-5], "break", 6) != 5) ){ |
| @@ -27686,11 +27700,11 @@ | ||
| 27686 | 27700 | fd = open(tPath, (O_RDWR|O_CREAT|O_EXCL), SQLITE_DEFAULT_FILE_PERMISSIONS); |
| 27687 | 27701 | if( fd<0 ){ |
| 27688 | 27702 | sprintf(errmsg, "create failed (%d)", errno); |
| 27689 | 27703 | goto end_breaklock; |
| 27690 | 27704 | } |
| 27691 | - if( pwrite(fd, buf, readLen, 0) != readLen ){ | |
| 27705 | + if( pwrite(fd, buf, readLen, 0) != (ssize_t)readLen ){ | |
| 27692 | 27706 | sprintf(errmsg, "write failed (%d)", errno); |
| 27693 | 27707 | goto end_breaklock; |
| 27694 | 27708 | } |
| 27695 | 27709 | if( rename(tPath, cPath) ){ |
| 27696 | 27710 | sprintf(errmsg, "rename failed (%d)", errno); |
| @@ -30183,10 +30197,13 @@ | ||
| 30183 | 30197 | /* Check to see if another process is holding the dead-man switch. |
| 30184 | 30198 | ** If not, truncate the file to zero length. |
| 30185 | 30199 | */ |
| 30186 | 30200 | if( winShmSystemLock(pShmNode, _SHM_WRLCK, WIN_SHM_DMS, 1)==SQLITE_OK ){ |
| 30187 | 30201 | rc = winTruncate((sqlite3_file *)&pShmNode->hFile, 0); |
| 30202 | + if( rc!=SQLITE_OK ){ | |
| 30203 | + rc = SQLITE_IOERR_SHMOPEN; | |
| 30204 | + } | |
| 30188 | 30205 | } |
| 30189 | 30206 | if( rc==SQLITE_OK ){ |
| 30190 | 30207 | winShmSystemLock(pShmNode, _SHM_UNLCK, WIN_SHM_DMS, 1); |
| 30191 | 30208 | rc = winShmSystemLock(pShmNode, _SHM_RDLCK, WIN_SHM_DMS, 1); |
| 30192 | 30209 | } |
| @@ -30409,10 +30426,11 @@ | ||
| 30409 | 30426 | ** any load or store begun after the barrier. |
| 30410 | 30427 | */ |
| 30411 | 30428 | static void winShmBarrier( |
| 30412 | 30429 | sqlite3_file *fd /* Database holding the shared memory */ |
| 30413 | 30430 | ){ |
| 30431 | + UNUSED_PARAMETER(fd); | |
| 30414 | 30432 | /* MemoryBarrier(); // does not work -- do not know why not */ |
| 30415 | 30433 | winShmEnterMutex(); |
| 30416 | 30434 | winShmLeaveMutex(); |
| 30417 | 30435 | } |
| 30418 | 30436 | |
| @@ -33496,17 +33514,18 @@ | ||
| 33496 | 33514 | # define sqlite3WalBeginReadTransaction(y,z) 0 |
| 33497 | 33515 | # define sqlite3WalEndReadTransaction(z) |
| 33498 | 33516 | # define sqlite3WalRead(v,w,x,y,z) 0 |
| 33499 | 33517 | # define sqlite3WalDbsize(y,z) |
| 33500 | 33518 | # define sqlite3WalBeginWriteTransaction(y) 0 |
| 33501 | -# define sqlite3WalEndWRiteTransaction(x) 0 | |
| 33519 | +# define sqlite3WalEndWriteTransaction(x) 0 | |
| 33502 | 33520 | # define sqlite3WalUndo(x,y,z) 0 |
| 33503 | 33521 | # define sqlite3WalSavepoint(y,z) |
| 33504 | 33522 | # define sqlite3WalSavepointUndo(y,z) 0 |
| 33505 | 33523 | # define sqlite3WalFrames(u,v,w,x,y,z) 0 |
| 33506 | 33524 | # define sqlite3WalCheckpoint(u,v,w,x) 0 |
| 33507 | 33525 | # define sqlite3WalCallback(z) 0 |
| 33526 | +# define sqlite3WalExclusiveMode(y,z) 0 | |
| 33508 | 33527 | #else |
| 33509 | 33528 | |
| 33510 | 33529 | #define WAL_SAVEPOINT_NDATA 4 |
| 33511 | 33530 | |
| 33512 | 33531 | /* Connection to a write-ahead log (WAL) file. |
| @@ -33776,11 +33795,13 @@ | ||
| 33776 | 33795 | i64 iOffset; /* Starting offset in main journal */ |
| 33777 | 33796 | i64 iHdrOffset; /* See above */ |
| 33778 | 33797 | Bitvec *pInSavepoint; /* Set of pages in this savepoint */ |
| 33779 | 33798 | Pgno nOrig; /* Original number of pages in file */ |
| 33780 | 33799 | Pgno iSubRec; /* Index of first record in sub-journal */ |
| 33800 | +#ifndef SQLITE_OMIT_WAL | |
| 33781 | 33801 | u32 aWalData[WAL_SAVEPOINT_NDATA]; /* WAL savepoint context */ |
| 33802 | +#endif | |
| 33782 | 33803 | }; |
| 33783 | 33804 | |
| 33784 | 33805 | /* |
| 33785 | 33806 | ** A open page cache is an instance of the following structure. |
| 33786 | 33807 | ** |
| @@ -35967,48 +35988,75 @@ | ||
| 35967 | 35988 | |
| 35968 | 35989 | return rc; |
| 35969 | 35990 | } |
| 35970 | 35991 | |
| 35971 | 35992 | /* |
| 35972 | -** Check if the *-wal file that corresponds to the database opened by pPager | |
| 35973 | -** exists. Assuming no error occurs, set *pExists to 1 if the file exists, | |
| 35974 | -** or 0 otherwise and return SQLITE_OK. If an IO or OOM error occurs, return | |
| 35993 | +** Check for the existence of or delete the *-wal file that corresponds to | |
| 35994 | +** the database opened by pPager. | |
| 35995 | +** | |
| 35996 | +** When pExists!=NULL, set *pExists to 1 if the *-wal file exists, or 0 | |
| 35997 | +** if the *-wal file does not exist. | |
| 35998 | +** | |
| 35999 | +** When pExists==NULL, delete the *-wal file if it exists, or the do | |
| 36000 | +** nothing if the *-wal file does not exist. | |
| 36001 | +** | |
| 36002 | +** Return SQLITE_OK on success. If on an IO or OOM error occurs, return | |
| 35975 | 36003 | ** an SQLite error code. |
| 35976 | 36004 | */ |
| 35977 | -static int pagerHasWAL(Pager *pPager, int *pExists){ | |
| 36005 | +static int pagerCheckForOrDeleteWAL(Pager *pPager, int *pExists){ | |
| 35978 | 36006 | int rc; /* Return code */ |
| 35979 | 36007 | char *zWal; /* Name of the WAL file */ |
| 35980 | 36008 | |
| 35981 | 36009 | assert( !pPager->tempFile ); |
| 35982 | 36010 | zWal = sqlite3_mprintf("%s-wal", pPager->zFilename); |
| 35983 | 36011 | if( !zWal ){ |
| 35984 | 36012 | rc = SQLITE_NOMEM; |
| 35985 | 36013 | }else{ |
| 35986 | - rc = sqlite3OsAccess(pPager->pVfs, zWal, SQLITE_ACCESS_EXISTS, pExists); | |
| 36014 | + if( pExists ){ | |
| 36015 | + rc = sqlite3OsAccess(pPager->pVfs, zWal, SQLITE_ACCESS_EXISTS, pExists); | |
| 36016 | + }else{ | |
| 36017 | + rc = sqlite3OsDelete(pPager->pVfs, zWal, 0); | |
| 36018 | + } | |
| 35987 | 36019 | sqlite3_free(zWal); |
| 35988 | 36020 | } |
| 35989 | 36021 | return rc; |
| 35990 | 36022 | } |
| 35991 | 36023 | |
| 35992 | 36024 | /* |
| 35993 | 36025 | ** Check if the *-wal file that corresponds to the database opened by pPager |
| 35994 | -** exists. If it does, open the pager in WAL mode. Otherwise, if no error | |
| 35995 | -** occurs, make sure Pager.journalMode is not set to PAGER_JOURNALMODE_WAL. | |
| 35996 | -** If an IO or OOM error occurs, return an SQLite error code. | |
| 36026 | +** exists if the database is not empy, or verify that the *-wal file does | |
| 36027 | +** not exist (by deleting it) if the database file is empty. | |
| 36028 | +** | |
| 36029 | +** If the database is not empty and the *-wal file exists, open the pager | |
| 36030 | +** in WAL mode. If the database is empty or if no *-wal file exists and | |
| 36031 | +** if no error occurs, make sure Pager.journalMode is not set to | |
| 36032 | +** PAGER_JOURNALMODE_WAL. | |
| 36033 | +** | |
| 36034 | +** Return SQLITE_OK or an error code. | |
| 35997 | 36035 | ** |
| 35998 | 36036 | ** If the WAL file is opened, also open a snapshot (read transaction). |
| 35999 | 36037 | ** |
| 36000 | 36038 | ** The caller must hold a SHARED lock on the database file to call this |
| 36001 | 36039 | ** function. Because an EXCLUSIVE lock on the db file is required to delete |
| 36002 | -** a WAL, this ensures there is no race condition between the xAccess() | |
| 36003 | -** below and an xDelete() being executed by some other connection. | |
| 36040 | +** a WAL on a none-empty database, this ensures there is no race condition | |
| 36041 | +** between the xAccess() below and an xDelete() being executed by some | |
| 36042 | +** other connection. | |
| 36004 | 36043 | */ |
| 36005 | 36044 | static int pagerOpenWalIfPresent(Pager *pPager){ |
| 36006 | 36045 | int rc = SQLITE_OK; |
| 36007 | 36046 | if( !pPager->tempFile ){ |
| 36008 | 36047 | int isWal; /* True if WAL file exists */ |
| 36009 | - rc = pagerHasWAL(pPager, &isWal); | |
| 36048 | + int nPage; /* Size of the database file */ | |
| 36049 | + assert( pPager->state>=SHARED_LOCK ); | |
| 36050 | + rc = sqlite3PagerPagecount(pPager, &nPage); | |
| 36051 | + if( rc ) return rc; | |
| 36052 | + if( nPage==0 ){ | |
| 36053 | + rc = pagerCheckForOrDeleteWAL(pPager, 0); | |
| 36054 | + isWal = 0; | |
| 36055 | + }else{ | |
| 36056 | + rc = pagerCheckForOrDeleteWAL(pPager, &isWal); | |
| 36057 | + } | |
| 36010 | 36058 | if( rc==SQLITE_OK ){ |
| 36011 | 36059 | if( isWal ){ |
| 36012 | 36060 | pager_reset(pPager); |
| 36013 | 36061 | rc = sqlite3PagerOpenWal(pPager, 0); |
| 36014 | 36062 | if( rc==SQLITE_OK ){ |
| @@ -36378,11 +36426,11 @@ | ||
| 36378 | 36426 | if( mxPage>0 ){ |
| 36379 | 36427 | pPager->mxPgno = mxPage; |
| 36380 | 36428 | } |
| 36381 | 36429 | if( pPager->state!=PAGER_UNLOCK ){ |
| 36382 | 36430 | sqlite3PagerPagecount(pPager, &nPage); |
| 36383 | - assert( pPager->mxPgno>=nPage ); | |
| 36431 | + assert( (int)pPager->mxPgno>=nPage ); | |
| 36384 | 36432 | } |
| 36385 | 36433 | return pPager->mxPgno; |
| 36386 | 36434 | } |
| 36387 | 36435 | |
| 36388 | 36436 | /* |
| @@ -37756,11 +37804,11 @@ | ||
| 37756 | 37804 | ** |
| 37757 | 37805 | ** There is a vanishingly small chance that a change will not be |
| 37758 | 37806 | ** detected. The chance of an undetected change is so small that |
| 37759 | 37807 | ** it can be neglected. |
| 37760 | 37808 | */ |
| 37761 | - int nPage; | |
| 37809 | + int nPage = 0; | |
| 37762 | 37810 | char dbFileVers[sizeof(pPager->dbFileVers)]; |
| 37763 | 37811 | sqlite3PagerPagecount(pPager, &nPage); |
| 37764 | 37812 | |
| 37765 | 37813 | if( pPager->errCode ){ |
| 37766 | 37814 | rc = pPager->errCode; |
| @@ -38187,34 +38235,23 @@ | ||
| 38187 | 38235 | /* No need to open the journal file at this time. It will be |
| 38188 | 38236 | ** opened before it is written to. If we defer opening the journal, |
| 38189 | 38237 | ** we might save the work of creating a file if the transaction |
| 38190 | 38238 | ** ends up being a no-op. |
| 38191 | 38239 | */ |
| 38192 | - }else if( isOpen(pPager->jfd) && pPager->journalOff==0 ){ | |
| 38193 | - /* This happens when the pager was in exclusive-access mode the last | |
| 38194 | - ** time a (read or write) transaction was successfully concluded | |
| 38195 | - ** by this connection. Instead of deleting the journal file it was | |
| 38196 | - ** kept open and either was truncated to 0 bytes or its header was | |
| 38197 | - ** overwritten with zeros. | |
| 38198 | - */ | |
| 38199 | - assert( pagerUseWal(pPager)==0 ); | |
| 38200 | - assert( pPager->nRec==0 ); | |
| 38201 | - assert( pPager->dbOrigSize==0 ); | |
| 38202 | - assert( pPager->pInJournal==0 ); | |
| 38203 | - rc = pager_open_journal(pPager); | |
| 38240 | + | |
| 38241 | + if( rc!=SQLITE_OK ){ | |
| 38242 | + assert( !pPager->dbModified ); | |
| 38243 | + /* Ignore any IO error that occurs within pager_end_transaction(). The | |
| 38244 | + ** purpose of this call is to reset the internal state of the pager | |
| 38245 | + ** sub-system. It doesn't matter if the journal-file is not properly | |
| 38246 | + ** finalized at this point (since it is not a valid journal file anyway). | |
| 38247 | + */ | |
| 38248 | + pager_end_transaction(pPager, 0); | |
| 38249 | + } | |
| 38204 | 38250 | } |
| 38205 | 38251 | |
| 38206 | 38252 | PAGERTRACE(("TRANSACTION %d\n", PAGERID(pPager))); |
| 38207 | - if( rc!=SQLITE_OK ){ | |
| 38208 | - assert( !pPager->dbModified ); | |
| 38209 | - /* Ignore any IO error that occurs within pager_end_transaction(). The | |
| 38210 | - ** purpose of this call is to reset the internal state of the pager | |
| 38211 | - ** sub-system. It doesn't matter if the journal-file is not properly | |
| 38212 | - ** finalized at this point (since it is not a valid journal file anyway). | |
| 38213 | - */ | |
| 38214 | - pager_end_transaction(pPager, 0); | |
| 38215 | - } | |
| 38216 | 38253 | return rc; |
| 38217 | 38254 | } |
| 38218 | 38255 | |
| 38219 | 38256 | /* |
| 38220 | 38257 | ** Mark a single data page as writeable. The page is written into the |
| @@ -38261,14 +38298,11 @@ | ||
| 38261 | 38298 | ** |
| 38262 | 38299 | ** Higher level routines should have already started a transaction, |
| 38263 | 38300 | ** which means they have acquired the necessary locks but the rollback |
| 38264 | 38301 | ** journal might not yet be open. |
| 38265 | 38302 | */ |
| 38266 | - rc = sqlite3PagerBegin(pPager, 0, pPager->subjInMemory); | |
| 38267 | - if( rc!=SQLITE_OK ){ | |
| 38268 | - return rc; | |
| 38269 | - } | |
| 38303 | + assert( pPager->state>=RESERVED_LOCK ); | |
| 38270 | 38304 | if( pPager->pInJournal==0 |
| 38271 | 38305 | && pPager->journalMode!=PAGER_JOURNALMODE_OFF |
| 38272 | 38306 | && !pagerUseWal(pPager) |
| 38273 | 38307 | ){ |
| 38274 | 38308 | assert( pPager->useJournal ); |
| @@ -38705,11 +38739,14 @@ | ||
| 38705 | 38739 | ** in 'direct' mode. In this case the journal file will never be |
| 38706 | 38740 | ** created for this transaction. |
| 38707 | 38741 | */ |
| 38708 | 38742 | #ifdef SQLITE_ENABLE_ATOMIC_WRITE |
| 38709 | 38743 | PgHdr *pPg; |
| 38710 | - assert( isOpen(pPager->jfd) || pPager->journalMode==PAGER_JOURNALMODE_OFF ); | |
| 38744 | + assert( isOpen(pPager->jfd) | |
| 38745 | + || pPager->journalMode==PAGER_JOURNALMODE_OFF | |
| 38746 | + || pPager->journalMode==PAGER_JOURNALMODE_WAL | |
| 38747 | + ); | |
| 38711 | 38748 | if( !zMaster && isOpen(pPager->jfd) |
| 38712 | 38749 | && pPager->journalOff==jrnlBufferSize(pPager) |
| 38713 | 38750 | && pPager->dbSize>=pPager->dbFileSize |
| 38714 | 38751 | && (0==(pPg = sqlite3PcacheDirtyList(pPager->pPCache)) || 0==pPg->pDirty) |
| 38715 | 38752 | ){ |
| @@ -38839,11 +38876,11 @@ | ||
| 38839 | 38876 | /* This function should not be called if the pager is not in at least |
| 38840 | 38877 | ** PAGER_RESERVED state. **FIXME**: Make it so that this test always |
| 38841 | 38878 | ** fails - make it so that we never reach this point if we do not hold |
| 38842 | 38879 | ** all necessary locks. |
| 38843 | 38880 | */ |
| 38844 | - if( pPager->state<PAGER_RESERVED ) return SQLITE_ERROR; | |
| 38881 | + if( NEVER(pPager->state<PAGER_RESERVED) ) return SQLITE_ERROR; | |
| 38845 | 38882 | |
| 38846 | 38883 | /* An optimization. If the database was not actually modified during |
| 38847 | 38884 | ** this transaction, the pager is running in exclusive-mode and is |
| 38848 | 38885 | ** using persistent journals, then this function is a no-op. |
| 38849 | 38886 | ** |
| @@ -38855,11 +38892,11 @@ | ||
| 38855 | 38892 | ** to drop any locks either. |
| 38856 | 38893 | */ |
| 38857 | 38894 | if( pPager->dbModified==0 && pPager->exclusiveMode |
| 38858 | 38895 | && pPager->journalMode==PAGER_JOURNALMODE_PERSIST |
| 38859 | 38896 | ){ |
| 38860 | - assert( pPager->journalOff==JOURNAL_HDR_SZ(pPager) ); | |
| 38897 | + assert( pPager->journalOff==JOURNAL_HDR_SZ(pPager) || !pPager->journalOff ); | |
| 38861 | 38898 | return SQLITE_OK; |
| 38862 | 38899 | } |
| 38863 | 38900 | |
| 38864 | 38901 | PAGERTRACE(("COMMIT %d\n", PAGERID(pPager))); |
| 38865 | 38902 | assert( pPager->state==PAGER_SYNCED || MEMDB || !pPager->dbModified ); |
| @@ -39189,11 +39226,11 @@ | ||
| 39189 | 39226 | |
| 39190 | 39227 | #ifdef SQLITE_HAS_CODEC |
| 39191 | 39228 | /* |
| 39192 | 39229 | ** Set or retrieve the codec for this pager |
| 39193 | 39230 | */ |
| 39194 | -static void sqlite3PagerSetCodec( | |
| 39231 | +SQLITE_PRIVATE void sqlite3PagerSetCodec( | |
| 39195 | 39232 | Pager *pPager, |
| 39196 | 39233 | void *(*xCodec)(void*,void*,Pgno,int), |
| 39197 | 39234 | void (*xCodecSizeChng)(void*,int,int), |
| 39198 | 39235 | void (*xCodecFree)(void*), |
| 39199 | 39236 | void *pCodec |
| @@ -39203,11 +39240,11 @@ | ||
| 39203 | 39240 | pPager->xCodecSizeChng = xCodecSizeChng; |
| 39204 | 39241 | pPager->xCodecFree = xCodecFree; |
| 39205 | 39242 | pPager->pCodec = pCodec; |
| 39206 | 39243 | pagerReportSize(pPager); |
| 39207 | 39244 | } |
| 39208 | -static void *sqlite3PagerGetCodec(Pager *pPager){ | |
| 39245 | +SQLITE_PRIVATE void *sqlite3PagerGetCodec(Pager *pPager){ | |
| 39209 | 39246 | return pPager->pCodec; |
| 39210 | 39247 | } |
| 39211 | 39248 | #endif |
| 39212 | 39249 | |
| 39213 | 39250 | #ifndef SQLITE_OMIT_AUTOVACUUM |
| @@ -39527,11 +39564,11 @@ | ||
| 39527 | 39564 | ** journalmode. Journalmode changes can only happen when the database |
| 39528 | 39565 | ** is unmodified. |
| 39529 | 39566 | */ |
| 39530 | 39567 | SQLITE_PRIVATE int sqlite3PagerOkToChangeJournalMode(Pager *pPager){ |
| 39531 | 39568 | if( pPager->dbModified ) return 0; |
| 39532 | - if( isOpen(pPager->jfd) && pPager->journalOff>0 ) return 0; | |
| 39569 | + if( NEVER(isOpen(pPager->jfd) && pPager->journalOff>0) ) return 0; | |
| 39533 | 39570 | return 1; |
| 39534 | 39571 | } |
| 39535 | 39572 | |
| 39536 | 39573 | /* |
| 39537 | 39574 | ** Get/set the size-limit used for persistent journal files. |
| @@ -39584,21 +39621,34 @@ | ||
| 39584 | 39621 | const sqlite3_io_methods *pMethods = pPager->fd->pMethods; |
| 39585 | 39622 | return pMethods->iVersion>=2 && pMethods->xShmOpen!=0; |
| 39586 | 39623 | } |
| 39587 | 39624 | |
| 39588 | 39625 | /* |
| 39589 | -** Open a connection to the write-ahead log file for pager pPager. If | |
| 39590 | -** the log connection is already open, this function is a no-op. | |
| 39591 | -** | |
| 39592 | 39626 | ** The caller must be holding a SHARED lock on the database file to call |
| 39593 | 39627 | ** this function. |
| 39628 | +** | |
| 39629 | +** If the pager passed as the first argument is open on a real database | |
| 39630 | +** file (not a temp file or an in-memory database), and the WAL file | |
| 39631 | +** is not already open, make an attempt to open it now. If successful, | |
| 39632 | +** return SQLITE_OK. If an error occurs or the VFS used by the pager does | |
| 39633 | +** not support the xShmXXX() methods, return an error code. *pisOpen is | |
| 39634 | +** not modified in either case. | |
| 39635 | +** | |
| 39636 | +** If the pager is open on a temp-file (or in-memory database), or if | |
| 39637 | +** the WAL file is already open, set *pisOpen to 1 and return SQLITE_OK | |
| 39638 | +** without doing anything. | |
| 39594 | 39639 | */ |
| 39595 | -SQLITE_PRIVATE int sqlite3PagerOpenWal(Pager *pPager, int *pisOpen){ | |
| 39640 | +SQLITE_PRIVATE int sqlite3PagerOpenWal( | |
| 39641 | + Pager *pPager, /* Pager object */ | |
| 39642 | + int *pisOpen /* OUT: Set to true if call is a no-op */ | |
| 39643 | +){ | |
| 39596 | 39644 | int rc = SQLITE_OK; /* Return code */ |
| 39597 | 39645 | |
| 39598 | 39646 | assert( pPager->state>=PAGER_SHARED ); |
| 39599 | - if( !pPager->pWal ){ | |
| 39647 | + assert( (pisOpen==0 && !pPager->tempFile && !pPager->pWal) || *pisOpen==0 ); | |
| 39648 | + | |
| 39649 | + if( !pPager->tempFile && !pPager->pWal ){ | |
| 39600 | 39650 | if( !sqlite3PagerWalSupported(pPager) ) return SQLITE_CANTOPEN; |
| 39601 | 39651 | |
| 39602 | 39652 | /* Open the connection to the log file. If this operation fails, |
| 39603 | 39653 | ** (e.g. due to malloc() failure), unlock the database file and |
| 39604 | 39654 | ** return an error code. |
| @@ -39635,11 +39685,11 @@ | ||
| 39635 | 39685 | */ |
| 39636 | 39686 | if( !pPager->pWal ){ |
| 39637 | 39687 | int logexists = 0; |
| 39638 | 39688 | rc = sqlite3OsLock(pPager->fd, SQLITE_LOCK_SHARED); |
| 39639 | 39689 | if( rc==SQLITE_OK ){ |
| 39640 | - rc = pagerHasWAL(pPager, &logexists); | |
| 39690 | + rc = pagerCheckForOrDeleteWAL(pPager, &logexists); | |
| 39641 | 39691 | } |
| 39642 | 39692 | if( rc==SQLITE_OK && logexists ){ |
| 39643 | 39693 | rc = sqlite3WalOpen(pPager->pVfs, pPager->fd, |
| 39644 | 39694 | pPager->zFilename, &pPager->pWal); |
| 39645 | 39695 | } |
| @@ -40182,16 +40232,16 @@ | ||
| 40182 | 40232 | |
| 40183 | 40233 | /* Enlarge the pWal->apWiData[] array if required */ |
| 40184 | 40234 | if( pWal->nWiData<=iPage ){ |
| 40185 | 40235 | int nByte = sizeof(u32 *)*(iPage+1); |
| 40186 | 40236 | volatile u32 **apNew; |
| 40187 | - apNew = (volatile u32 **)sqlite3_realloc(pWal->apWiData, nByte); | |
| 40237 | + apNew = (volatile u32 **)sqlite3_realloc((void *)pWal->apWiData, nByte); | |
| 40188 | 40238 | if( !apNew ){ |
| 40189 | 40239 | *ppPage = 0; |
| 40190 | 40240 | return SQLITE_NOMEM; |
| 40191 | 40241 | } |
| 40192 | - memset(&apNew[pWal->nWiData], 0, sizeof(u32 *)*(iPage+1-pWal->nWiData)); | |
| 40242 | + memset((void *)&apNew[pWal->nWiData], 0, sizeof(u32 *)*(iPage+1-pWal->nWiData)); | |
| 40193 | 40243 | pWal->apWiData = apNew; |
| 40194 | 40244 | pWal->nWiData = iPage+1; |
| 40195 | 40245 | } |
| 40196 | 40246 | |
| 40197 | 40247 | /* Request a pointer to the required page from the VFS */ |
| @@ -40422,11 +40472,11 @@ | ||
| 40422 | 40472 | if( pWal->exclusiveMode ) return SQLITE_OK; |
| 40423 | 40473 | rc = sqlite3OsShmLock(pWal->pDbFd, lockIdx, 1, |
| 40424 | 40474 | SQLITE_SHM_LOCK | SQLITE_SHM_SHARED); |
| 40425 | 40475 | WALTRACE(("WAL%p: acquire SHARED-%s %s\n", pWal, |
| 40426 | 40476 | walLockName(lockIdx), rc ? "failed" : "ok")); |
| 40427 | - VVA_ONLY( pWal->lockError = (rc!=SQLITE_OK && rc!=SQLITE_BUSY); ) | |
| 40477 | + VVA_ONLY( pWal->lockError = (u8)(rc!=SQLITE_OK && rc!=SQLITE_BUSY); ) | |
| 40428 | 40478 | return rc; |
| 40429 | 40479 | } |
| 40430 | 40480 | static void walUnlockShared(Wal *pWal, int lockIdx){ |
| 40431 | 40481 | if( pWal->exclusiveMode ) return; |
| 40432 | 40482 | (void)sqlite3OsShmLock(pWal->pDbFd, lockIdx, 1, |
| @@ -40438,11 +40488,11 @@ | ||
| 40438 | 40488 | if( pWal->exclusiveMode ) return SQLITE_OK; |
| 40439 | 40489 | rc = sqlite3OsShmLock(pWal->pDbFd, lockIdx, n, |
| 40440 | 40490 | SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE); |
| 40441 | 40491 | WALTRACE(("WAL%p: acquire EXCLUSIVE-%s cnt=%d %s\n", pWal, |
| 40442 | 40492 | walLockName(lockIdx), n, rc ? "failed" : "ok")); |
| 40443 | - VVA_ONLY( pWal->lockError = (rc!=SQLITE_OK && rc!=SQLITE_BUSY); ) | |
| 40493 | + VVA_ONLY( pWal->lockError = (u8)(rc!=SQLITE_OK && rc!=SQLITE_BUSY); ) | |
| 40444 | 40494 | return rc; |
| 40445 | 40495 | } |
| 40446 | 40496 | static void walUnlockExclusive(Wal *pWal, int lockIdx, int n){ |
| 40447 | 40497 | if( pWal->exclusiveMode ) return; |
| 40448 | 40498 | (void)sqlite3OsShmLock(pWal->pDbFd, lockIdx, n, |
| @@ -40550,13 +40600,13 @@ | ||
| 40550 | 40600 | ** updated. Any later hash tables will be automatically cleared when |
| 40551 | 40601 | ** pWal->hdr.mxFrame advances to the point where those hash tables are |
| 40552 | 40602 | ** actually needed. |
| 40553 | 40603 | */ |
| 40554 | 40604 | static void walCleanupHash(Wal *pWal){ |
| 40555 | - volatile ht_slot *aHash; /* Pointer to hash table to clear */ | |
| 40556 | - volatile u32 *aPgno; /* Page number array for hash table */ | |
| 40557 | - u32 iZero; /* frame == (aHash[x]+iZero) */ | |
| 40605 | + volatile ht_slot *aHash = 0; /* Pointer to hash table to clear */ | |
| 40606 | + volatile u32 *aPgno = 0; /* Page number array for hash table */ | |
| 40607 | + u32 iZero = 0; /* frame == (aHash[x]+iZero) */ | |
| 40558 | 40608 | int iLimit = 0; /* Zero values greater than this */ |
| 40559 | 40609 | int nByte; /* Number of bytes to zero in aPgno[] */ |
| 40560 | 40610 | int i; /* Used to iterate through aHash[] */ |
| 40561 | 40611 | |
| 40562 | 40612 | assert( pWal->writeLock ); |
| @@ -40586,11 +40636,11 @@ | ||
| 40586 | 40636 | } |
| 40587 | 40637 | |
| 40588 | 40638 | /* Zero the entries in the aPgno array that correspond to frames with |
| 40589 | 40639 | ** frame numbers greater than pWal->hdr.mxFrame. |
| 40590 | 40640 | */ |
| 40591 | - nByte = ((char *)aHash - (char *)&aPgno[iLimit+1]); | |
| 40641 | + nByte = (int)((char *)aHash - (char *)&aPgno[iLimit+1]); | |
| 40592 | 40642 | memset((void *)&aPgno[iLimit+1], 0, nByte); |
| 40593 | 40643 | |
| 40594 | 40644 | #ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT |
| 40595 | 40645 | /* Verify that the every entry in the mapping region is still reachable |
| 40596 | 40646 | ** via the hash table even after the cleanup. |
| @@ -40613,13 +40663,13 @@ | ||
| 40613 | 40663 | ** Set an entry in the wal-index that will map database page number |
| 40614 | 40664 | ** pPage into WAL frame iFrame. |
| 40615 | 40665 | */ |
| 40616 | 40666 | static int walIndexAppend(Wal *pWal, u32 iFrame, u32 iPage){ |
| 40617 | 40667 | int rc; /* Return code */ |
| 40618 | - u32 iZero; /* One less than frame number of aPgno[1] */ | |
| 40619 | - volatile u32 *aPgno; /* Page number array */ | |
| 40620 | - volatile ht_slot *aHash; /* Hash table */ | |
| 40668 | + u32 iZero = 0; /* One less than frame number of aPgno[1] */ | |
| 40669 | + volatile u32 *aPgno = 0; /* Page number array */ | |
| 40670 | + volatile ht_slot *aHash = 0; /* Hash table */ | |
| 40621 | 40671 | |
| 40622 | 40672 | rc = walHashGet(pWal, walFramePage(iFrame), &aHash, &aPgno, &iZero); |
| 40623 | 40673 | |
| 40624 | 40674 | /* Assuming the wal-index file was successfully mapped, populate the |
| 40625 | 40675 | ** page number array and hash table entry. |
| @@ -40634,11 +40684,11 @@ | ||
| 40634 | 40684 | |
| 40635 | 40685 | /* If this is the first entry to be added to this hash-table, zero the |
| 40636 | 40686 | ** entire hash table and aPgno[] array before proceding. |
| 40637 | 40687 | */ |
| 40638 | 40688 | if( idx==1 ){ |
| 40639 | - int nByte = (u8 *)&aHash[HASHTABLE_NSLOT] - (u8 *)&aPgno[1]; | |
| 40689 | + int nByte = (int)((u8 *)&aHash[HASHTABLE_NSLOT] - (u8 *)&aPgno[1]); | |
| 40640 | 40690 | memset((void*)&aPgno[1], 0, nByte); |
| 40641 | 40691 | } |
| 40642 | 40692 | |
| 40643 | 40693 | /* If the entry in aPgno[] is already set, then the previous writer |
| 40644 | 40694 | ** must have exited unexpectedly in the middle of a transaction (after |
| @@ -40654,11 +40704,11 @@ | ||
| 40654 | 40704 | /* Write the aPgno[] array entry and the hash-table slot. */ |
| 40655 | 40705 | for(iKey=walHash(iPage); aHash[iKey]; iKey=walNextHash(iKey)){ |
| 40656 | 40706 | assert( nCollide++ < idx ); |
| 40657 | 40707 | } |
| 40658 | 40708 | aPgno[idx] = iPage; |
| 40659 | - aHash[iKey] = idx; | |
| 40709 | + aHash[iKey] = (ht_slot)idx; | |
| 40660 | 40710 | |
| 40661 | 40711 | #ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT |
| 40662 | 40712 | /* Verify that the number of entries in the hash table exactly equals |
| 40663 | 40713 | ** the number of entries in the mapping region. |
| 40664 | 40714 | */ |
| @@ -40762,12 +40812,12 @@ | ||
| 40762 | 40812 | || szPage>SQLITE_MAX_PAGE_SIZE |
| 40763 | 40813 | || szPage<512 |
| 40764 | 40814 | ){ |
| 40765 | 40815 | goto finished; |
| 40766 | 40816 | } |
| 40767 | - pWal->hdr.bigEndCksum = (magic&0x00000001); | |
| 40768 | - pWal->szPage = szPage; | |
| 40817 | + pWal->hdr.bigEndCksum = (u8)(magic&0x00000001); | |
| 40818 | + pWal->szPage = (u16)szPage; | |
| 40769 | 40819 | pWal->nCkpt = sqlite3Get4byte(&aBuf[12]); |
| 40770 | 40820 | memcpy(&pWal->hdr.aSalt, &aBuf[16], 8); |
| 40771 | 40821 | |
| 40772 | 40822 | /* Verify that the WAL header checksum is correct */ |
| 40773 | 40823 | walChecksumBytes(pWal->hdr.bigEndCksum==SQLITE_BIGENDIAN, |
| @@ -40813,11 +40863,11 @@ | ||
| 40813 | 40863 | |
| 40814 | 40864 | /* If nTruncate is non-zero, this is a commit record. */ |
| 40815 | 40865 | if( nTruncate ){ |
| 40816 | 40866 | pWal->hdr.mxFrame = iFrame; |
| 40817 | 40867 | pWal->hdr.nPage = nTruncate; |
| 40818 | - pWal->hdr.szPage = szPage; | |
| 40868 | + pWal->hdr.szPage = (u16)szPage; | |
| 40819 | 40869 | aFrameCksum[0] = pWal->hdr.aFrameCksum[0]; |
| 40820 | 40870 | aFrameCksum[1] = pWal->hdr.aFrameCksum[1]; |
| 40821 | 40871 | } |
| 40822 | 40872 | } |
| 40823 | 40873 | |
| @@ -41030,12 +41080,12 @@ | ||
| 41030 | 41080 | int nList; /* Number of elements in aList */ |
| 41031 | 41081 | ht_slot *aList; /* Pointer to sub-list content */ |
| 41032 | 41082 | }; |
| 41033 | 41083 | |
| 41034 | 41084 | 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 */ | |
| 41085 | + int nMerge = 0; /* Number of elements in list aMerge */ | |
| 41086 | + ht_slot *aMerge = 0; /* List to be merged */ | |
| 41037 | 41087 | int iList; /* Index into input list */ |
| 41038 | 41088 | int iSub = 0; /* Index into aSub array */ |
| 41039 | 41089 | struct Sublist aSub[13]; /* Array of sub-lists */ |
| 41040 | 41090 | |
| 41041 | 41091 | memset(aSub, 0, sizeof(aSub)); |
| @@ -41141,16 +41191,16 @@ | ||
| 41141 | 41191 | int j; /* Counter variable */ |
| 41142 | 41192 | int nEntry; /* Number of entries in this segment */ |
| 41143 | 41193 | ht_slot *aIndex; /* Sorted index for this segment */ |
| 41144 | 41194 | |
| 41145 | 41195 | aPgno++; |
| 41146 | - nEntry = ((i+1)==nSegment)?iLast-iZero:(u32 *)aHash-(u32 *)aPgno; | |
| 41196 | + nEntry = (int)(((i+1)==nSegment)?(int)(iLast-iZero):(u32 *)aHash-(u32 *)aPgno); | |
| 41147 | 41197 | aIndex = &((ht_slot *)&p->aSegment[p->nSegment])[iZero]; |
| 41148 | 41198 | iZero++; |
| 41149 | 41199 | |
| 41150 | 41200 | for(j=0; j<nEntry; j++){ |
| 41151 | - aIndex[j] = j; | |
| 41201 | + aIndex[j] = (ht_slot)j; | |
| 41152 | 41202 | } |
| 41153 | 41203 | walMergesort((u32 *)aPgno, aTmp, aIndex, &nEntry); |
| 41154 | 41204 | p->aSegment[i].iZero = iZero; |
| 41155 | 41205 | p->aSegment[i].nEntry = nEntry; |
| 41156 | 41206 | p->aSegment[i].aIndex = aIndex; |
| @@ -41333,11 +41383,11 @@ | ||
| 41333 | 41383 | sqlite3OsClose(pWal->pWalFd); |
| 41334 | 41384 | if( isDelete ){ |
| 41335 | 41385 | sqlite3OsDelete(pWal->pVfs, pWal->zWalName, 0); |
| 41336 | 41386 | } |
| 41337 | 41387 | WALTRACE(("WAL%p: closed\n", pWal)); |
| 41338 | - sqlite3_free(pWal->apWiData); | |
| 41388 | + sqlite3_free((void *)pWal->apWiData); | |
| 41339 | 41389 | sqlite3_free(pWal); |
| 41340 | 41390 | } |
| 41341 | 41391 | return rc; |
| 41342 | 41392 | } |
| 41343 | 41393 | |
| @@ -41356,11 +41406,11 @@ | ||
| 41356 | 41406 | ** and *pChanged is set to 1. |
| 41357 | 41407 | ** |
| 41358 | 41408 | ** If the checksum cannot be verified return non-zero. If the header |
| 41359 | 41409 | ** is read successfully and the checksum verified, return zero. |
| 41360 | 41410 | */ |
| 41361 | -int walIndexTryHdr(Wal *pWal, int *pChanged){ | |
| 41411 | +static int walIndexTryHdr(Wal *pWal, int *pChanged){ | |
| 41362 | 41412 | u32 aCksum[2]; /* Checksum on the header content */ |
| 41363 | 41413 | WalIndexHdr h1, h2; /* Two copies of the header content */ |
| 41364 | 41414 | WalIndexHdr volatile *aHdr; /* Header in shared memory */ |
| 41365 | 41415 | |
| 41366 | 41416 | /* The first page of the wal-index must be mapped at this point. */ |
| @@ -41669,11 +41719,11 @@ | ||
| 41669 | 41719 | ){ |
| 41670 | 41720 | walUnlockShared(pWal, WAL_READ_LOCK(mxI)); |
| 41671 | 41721 | return WAL_RETRY; |
| 41672 | 41722 | }else{ |
| 41673 | 41723 | assert( mxReadMark<=pWal->hdr.mxFrame ); |
| 41674 | - pWal->readLock = mxI; | |
| 41724 | + pWal->readLock = (i16)mxI; | |
| 41675 | 41725 | } |
| 41676 | 41726 | } |
| 41677 | 41727 | return rc; |
| 41678 | 41728 | } |
| 41679 | 41729 | |
| @@ -42082,11 +42132,11 @@ | ||
| 42082 | 42132 | memcpy(&aWalHdr[16], pWal->hdr.aSalt, 8); |
| 42083 | 42133 | walChecksumBytes(1, aWalHdr, WAL_HDRSIZE-2*4, 0, aCksum); |
| 42084 | 42134 | sqlite3Put4byte(&aWalHdr[24], aCksum[0]); |
| 42085 | 42135 | sqlite3Put4byte(&aWalHdr[28], aCksum[1]); |
| 42086 | 42136 | |
| 42087 | - pWal->szPage = szPage; | |
| 42137 | + pWal->szPage = (u16)szPage; | |
| 42088 | 42138 | pWal->hdr.bigEndCksum = SQLITE_BIGENDIAN; |
| 42089 | 42139 | pWal->hdr.aFrameCksum[0] = aCksum[0]; |
| 42090 | 42140 | pWal->hdr.aFrameCksum[1] = aCksum[1]; |
| 42091 | 42141 | |
| 42092 | 42142 | rc = sqlite3OsWrite(pWal->pWalFd, aWalHdr, sizeof(aWalHdr), 0); |
| @@ -42176,11 +42226,11 @@ | ||
| 42176 | 42226 | rc = walIndexAppend(pWal, iFrame, pLast->pgno); |
| 42177 | 42227 | } |
| 42178 | 42228 | |
| 42179 | 42229 | if( rc==SQLITE_OK ){ |
| 42180 | 42230 | /* Update the private copy of the header. */ |
| 42181 | - pWal->hdr.szPage = szPage; | |
| 42231 | + pWal->hdr.szPage = (u16)szPage; | |
| 42182 | 42232 | pWal->hdr.mxFrame = iFrame; |
| 42183 | 42233 | if( isCommit ){ |
| 42184 | 42234 | pWal->hdr.iChange++; |
| 42185 | 42235 | pWal->hdr.nPage = nTruncate; |
| 42186 | 42236 | } |
| @@ -44913,20 +44963,24 @@ | ||
| 44913 | 44963 | MemPage **ppPage /* Write the page pointer here */ |
| 44914 | 44964 | ){ |
| 44915 | 44965 | int rc; |
| 44916 | 44966 | assert( sqlite3_mutex_held(pBt->mutex) ); |
| 44917 | 44967 | |
| 44918 | - if( pgno<=0 || pgno>btreePagecount(pBt) ){ | |
| 44919 | - return SQLITE_CORRUPT_BKPT; | |
| 44920 | - } | |
| 44921 | - rc = btreeGetPage(pBt, pgno, ppPage, 0); | |
| 44922 | - if( rc==SQLITE_OK ){ | |
| 44923 | - rc = btreeInitPage(*ppPage); | |
| 44924 | - if( rc!=SQLITE_OK ){ | |
| 44925 | - releasePage(*ppPage); | |
| 44968 | + if( pgno>btreePagecount(pBt) ){ | |
| 44969 | + rc = SQLITE_CORRUPT_BKPT; | |
| 44970 | + }else{ | |
| 44971 | + rc = btreeGetPage(pBt, pgno, ppPage, 0); | |
| 44972 | + if( rc==SQLITE_OK ){ | |
| 44973 | + rc = btreeInitPage(*ppPage); | |
| 44974 | + if( rc!=SQLITE_OK ){ | |
| 44975 | + releasePage(*ppPage); | |
| 44976 | + } | |
| 44926 | 44977 | } |
| 44927 | 44978 | } |
| 44979 | + | |
| 44980 | + testcase( pgno==0 ); | |
| 44981 | + assert( pgno!=0 || rc==SQLITE_CORRUPT ); | |
| 44928 | 44982 | return rc; |
| 44929 | 44983 | } |
| 44930 | 44984 | |
| 44931 | 44985 | /* |
| 44932 | 44986 | ** Release a MemPage. This should be called once for each prior |
| @@ -45849,11 +45903,11 @@ | ||
| 45849 | 45903 | ** page 1. So if some other shared-cache client already has a write-lock |
| 45850 | 45904 | ** on page 1, the transaction cannot be opened. */ |
| 45851 | 45905 | rc = querySharedCacheTableLock(p, MASTER_ROOT, READ_LOCK); |
| 45852 | 45906 | if( SQLITE_OK!=rc ) goto trans_begun; |
| 45853 | 45907 | |
| 45854 | - pBt->initiallyEmpty = pBt->nPage==0; | |
| 45908 | + pBt->initiallyEmpty = (u8)(pBt->nPage==0); | |
| 45855 | 45909 | do { |
| 45856 | 45910 | /* Call lockBtree() until either pBt->pPage1 is populated or |
| 45857 | 45911 | ** lockBtree() returns something other than SQLITE_OK. lockBtree() |
| 45858 | 45912 | ** may return SQLITE_OK but leave pBt->pPage1 set to 0 if after |
| 45859 | 45913 | ** reading page 1 it discovers that the page-size of the database |
| @@ -47572,11 +47626,10 @@ | ||
| 47572 | 47626 | rc = moveToRoot(pCur); |
| 47573 | 47627 | if( rc==SQLITE_OK ){ |
| 47574 | 47628 | if( pCur->eState==CURSOR_INVALID ){ |
| 47575 | 47629 | assert( pCur->apPage[pCur->iPage]->nCell==0 ); |
| 47576 | 47630 | *pRes = 1; |
| 47577 | - rc = SQLITE_OK; | |
| 47578 | 47631 | }else{ |
| 47579 | 47632 | assert( pCur->apPage[pCur->iPage]->nCell>0 ); |
| 47580 | 47633 | *pRes = 0; |
| 47581 | 47634 | rc = moveToLeftmost(pCur); |
| 47582 | 47635 | } |
| @@ -51337,11 +51390,11 @@ | ||
| 51337 | 51390 | assert( iVersion==1 || iVersion==2 ); |
| 51338 | 51391 | |
| 51339 | 51392 | /* If setting the version fields to 1, do not automatically open the |
| 51340 | 51393 | ** WAL connection, even if the version fields are currently set to 2. |
| 51341 | 51394 | */ |
| 51342 | - pBt->doNotUseWAL = (iVersion==1); | |
| 51395 | + pBt->doNotUseWAL = (u8)(iVersion==1); | |
| 51343 | 51396 | |
| 51344 | 51397 | rc = sqlite3BtreeBeginTrans(pBtree, 0); |
| 51345 | 51398 | if( rc==SQLITE_OK ){ |
| 51346 | 51399 | u8 *aData = pBt->pPage1->aData; |
| 51347 | 51400 | if( aData[18]!=(u8)iVersion || aData[19]!=(u8)iVersion ){ |
| @@ -51829,10 +51882,13 @@ | ||
| 51829 | 51882 | TESTONLY( rc2 = ) sqlite3BtreeCommitPhaseOne(p->pSrc, 0); |
| 51830 | 51883 | TESTONLY( rc2 |= ) sqlite3BtreeCommitPhaseTwo(p->pSrc); |
| 51831 | 51884 | assert( rc2==SQLITE_OK ); |
| 51832 | 51885 | } |
| 51833 | 51886 | |
| 51887 | + if( rc==SQLITE_IOERR_NOMEM ){ | |
| 51888 | + rc = SQLITE_NOMEM; | |
| 51889 | + } | |
| 51834 | 51890 | p->rc = rc; |
| 51835 | 51891 | } |
| 51836 | 51892 | if( p->pDestDb ){ |
| 51837 | 51893 | sqlite3_mutex_leave(p->pDestDb->mutex); |
| 51838 | 51894 | } |
| @@ -53951,11 +54007,13 @@ | ||
| 53951 | 54007 | ** having to double-check to make sure that the result is non-negative. But |
| 53952 | 54008 | ** if SQLITE_OMIT_TRACE is defined, the OP_Trace is omitted and we do need to |
| 53953 | 54009 | ** check the value of p->nOp-1 before continuing. |
| 53954 | 54010 | */ |
| 53955 | 54011 | SQLITE_PRIVATE VdbeOp *sqlite3VdbeGetOp(Vdbe *p, int addr){ |
| 53956 | - static const VdbeOp dummy; | |
| 54012 | + /* C89 specifies that the constant "dummy" will be initialized to all | |
| 54013 | + ** zeros, which is correct. MSVC generates a warning, nevertheless. */ | |
| 54014 | + static const VdbeOp dummy; /* Ignore the MSVC warning about no initializer */ | |
| 53957 | 54015 | assert( p->magic==VDBE_MAGIC_INIT ); |
| 53958 | 54016 | if( addr<0 ){ |
| 53959 | 54017 | #ifdef SQLITE_OMIT_TRACE |
| 53960 | 54018 | if( p->nOp==0 ) return (VdbeOp*)&dummy; |
| 53961 | 54019 | #endif |
| @@ -62382,18 +62440,17 @@ | ||
| 62382 | 62440 | #endif /* local variables moved into u.bl */ |
| 62383 | 62441 | |
| 62384 | 62442 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 62385 | 62443 | u.bl.pC = p->apCsr[pOp->p1]; |
| 62386 | 62444 | assert( u.bl.pC!=0 ); |
| 62445 | + u.bl.res = 1; | |
| 62387 | 62446 | if( (u.bl.pCrsr = u.bl.pC->pCursor)!=0 ){ |
| 62388 | 62447 | rc = sqlite3BtreeFirst(u.bl.pCrsr, &u.bl.res); |
| 62389 | 62448 | u.bl.pC->atFirst = u.bl.res==0 ?1:0; |
| 62390 | 62449 | u.bl.pC->deferredMoveto = 0; |
| 62391 | 62450 | u.bl.pC->cacheStatus = CACHE_STALE; |
| 62392 | 62451 | u.bl.pC->rowidIsValid = 0; |
| 62393 | - }else{ | |
| 62394 | - u.bl.res = 1; | |
| 62395 | 62452 | } |
| 62396 | 62453 | u.bl.pC->nullRow = (u8)u.bl.res; |
| 62397 | 62454 | assert( pOp->p2>0 && pOp->p2<p->nOp ); |
| 62398 | 62455 | if( u.bl.res ){ |
| 62399 | 62456 | pc = pOp->p2 - 1; |
| @@ -63433,10 +63490,11 @@ | ||
| 63433 | 63490 | rc = sqlite3Checkpoint(db, pOp->p1); |
| 63434 | 63491 | break; |
| 63435 | 63492 | }; |
| 63436 | 63493 | #endif |
| 63437 | 63494 | |
| 63495 | +#ifndef SQLITE_OMIT_PRAGMA | |
| 63438 | 63496 | /* Opcode: JournalMode P1 P2 P3 * P5 |
| 63439 | 63497 | ** |
| 63440 | 63498 | ** Change the journal mode of database P1 to P3. P3 must be one of the |
| 63441 | 63499 | ** PAGER_JOURNALMODE_XXX values. If changing between the various rollback |
| 63442 | 63500 | ** modes (delete, truncate, persist, off and memory), this is a simple |
| @@ -63559,11 +63617,12 @@ | ||
| 63559 | 63617 | pOut->z = (char *)sqlite3JournalModename(u.cd.eNew); |
| 63560 | 63618 | pOut->n = sqlite3Strlen30(pOut->z); |
| 63561 | 63619 | pOut->enc = SQLITE_UTF8; |
| 63562 | 63620 | sqlite3VdbeChangeEncoding(pOut, encoding); |
| 63563 | 63621 | break; |
| 63564 | -}; | |
| 63622 | +}; | |
| 63623 | +#endif /* SQLITE_OMIT_PRAGMA */ | |
| 63565 | 63624 | |
| 63566 | 63625 | #if !defined(SQLITE_OMIT_VACUUM) && !defined(SQLITE_OMIT_ATTACH) |
| 63567 | 63626 | /* Opcode: Vacuum * * * * * |
| 63568 | 63627 | ** |
| 63569 | 63628 | ** Vacuum the entire database. This opcode will cause other virtual |
| @@ -64743,11 +64802,16 @@ | ||
| 64743 | 64802 | 0, /* xLock */ |
| 64744 | 64803 | 0, /* xUnlock */ |
| 64745 | 64804 | 0, /* xCheckReservedLock */ |
| 64746 | 64805 | 0, /* xFileControl */ |
| 64747 | 64806 | 0, /* xSectorSize */ |
| 64748 | - 0 /* xDeviceCharacteristics */ | |
| 64807 | + 0, /* xDeviceCharacteristics */ | |
| 64808 | + 0, /* xShmOpen */ | |
| 64809 | + 0, /* xShmLock */ | |
| 64810 | + 0, /* xShmMap */ | |
| 64811 | + 0, /* xShmBarrier */ | |
| 64812 | + 0 /* xShmClose */ | |
| 64749 | 64813 | }; |
| 64750 | 64814 | |
| 64751 | 64815 | /* |
| 64752 | 64816 | ** Open a journal file. |
| 64753 | 64817 | */ |
| @@ -65023,11 +65087,16 @@ | ||
| 65023 | 65087 | 0, /* xLock */ |
| 65024 | 65088 | 0, /* xUnlock */ |
| 65025 | 65089 | 0, /* xCheckReservedLock */ |
| 65026 | 65090 | 0, /* xFileControl */ |
| 65027 | 65091 | 0, /* xSectorSize */ |
| 65028 | - 0 /* xDeviceCharacteristics */ | |
| 65092 | + 0, /* xDeviceCharacteristics */ | |
| 65093 | + 0, /* xShmOpen */ | |
| 65094 | + 0, /* xShmLock */ | |
| 65095 | + 0, /* xShmMap */ | |
| 65096 | + 0, /* xShmBarrier */ | |
| 65097 | + 0 /* xShmClose */ | |
| 65029 | 65098 | }; |
| 65030 | 65099 | |
| 65031 | 65100 | /* |
| 65032 | 65101 | ** Open a journal file. |
| 65033 | 65102 | */ |
| @@ -65546,10 +65615,11 @@ | ||
| 65546 | 65615 | }else if( zTab ){ |
| 65547 | 65616 | sqlite3ErrorMsg(pParse, "%s: %s.%s", zErr, zTab, zCol); |
| 65548 | 65617 | }else{ |
| 65549 | 65618 | sqlite3ErrorMsg(pParse, "%s: %s", zErr, zCol); |
| 65550 | 65619 | } |
| 65620 | + pParse->checkSchema = 1; | |
| 65551 | 65621 | pTopNC->nErr++; |
| 65552 | 65622 | } |
| 65553 | 65623 | |
| 65554 | 65624 | /* If a column from a table in pSrcList is referenced, then record |
| 65555 | 65625 | ** this fact in the pSrcList.a[].colUsed bitmask. Column 0 causes |
| @@ -75035,10 +75105,11 @@ | ||
| 75035 | 75105 | if( sqlite3StrICmp(zColName, pTabCol->zName)==0 ) break; |
| 75036 | 75106 | } |
| 75037 | 75107 | if( j>=pTab->nCol ){ |
| 75038 | 75108 | sqlite3ErrorMsg(pParse, "table %s has no column named %s", |
| 75039 | 75109 | pTab->zName, zColName); |
| 75110 | + pParse->checkSchema = 1; | |
| 75040 | 75111 | goto exit_create_index; |
| 75041 | 75112 | } |
| 75042 | 75113 | pIndex->aiColumn[i] = j; |
| 75043 | 75114 | /* Justification of the ALWAYS(pListItem->pExpr->pColl): Because of |
| 75044 | 75115 | ** the way the "idxlist" non-terminal is constructed by the parser, |
| @@ -80735,11 +80806,11 @@ | ||
| 80735 | 80806 | if( sqlite3IsRowid(pColumn->a[i].zName) ){ |
| 80736 | 80807 | keyColumn = i; |
| 80737 | 80808 | }else{ |
| 80738 | 80809 | sqlite3ErrorMsg(pParse, "table %S has no column named %s", |
| 80739 | 80810 | pTabList, 0, pColumn->a[i].zName); |
| 80740 | - pParse->nErr++; | |
| 80811 | + pParse->checkSchema = 1; | |
| 80741 | 80812 | goto insert_cleanup; |
| 80742 | 80813 | } |
| 80743 | 80814 | } |
| 80744 | 80815 | } |
| 80745 | 80816 | } |
| @@ -88382,10 +88453,11 @@ | ||
| 88382 | 88453 | pIdx && sqlite3StrICmp(pIdx->zName, zIndex); |
| 88383 | 88454 | pIdx=pIdx->pNext |
| 88384 | 88455 | ); |
| 88385 | 88456 | if( !pIdx ){ |
| 88386 | 88457 | sqlite3ErrorMsg(pParse, "no such index: %s", zIndex, 0); |
| 88458 | + pParse->checkSchema = 1; | |
| 88387 | 88459 | return SQLITE_ERROR; |
| 88388 | 88460 | } |
| 88389 | 88461 | pFrom->pIndex = pIdx; |
| 88390 | 88462 | } |
| 88391 | 88463 | return SQLITE_OK; |
| @@ -90367,10 +90439,11 @@ | ||
| 90367 | 90439 | } |
| 90368 | 90440 | if( !pTrigger ){ |
| 90369 | 90441 | if( !noErr ){ |
| 90370 | 90442 | sqlite3ErrorMsg(pParse, "no such trigger: %S", pName, 0); |
| 90371 | 90443 | } |
| 90444 | + pParse->checkSchema = 1; | |
| 90372 | 90445 | goto drop_trigger_cleanup; |
| 90373 | 90446 | } |
| 90374 | 90447 | sqlite3DropTriggerPtr(pParse, pTrigger); |
| 90375 | 90448 | |
| 90376 | 90449 | drop_trigger_cleanup: |
| @@ -91177,10 +91250,11 @@ | ||
| 91177 | 91250 | if( sqlite3IsRowid(pChanges->a[i].zName) ){ |
| 91178 | 91251 | chngRowid = 1; |
| 91179 | 91252 | pRowidExpr = pChanges->a[i].pExpr; |
| 91180 | 91253 | }else{ |
| 91181 | 91254 | sqlite3ErrorMsg(pParse, "no such column: %s", pChanges->a[i].zName); |
| 91255 | + pParse->checkSchema = 1; | |
| 91182 | 91256 | goto update_cleanup; |
| 91183 | 91257 | } |
| 91184 | 91258 | } |
| 91185 | 91259 | #ifndef SQLITE_OMIT_AUTHORIZATION |
| 91186 | 91260 | { |
| @@ -94755,11 +94829,11 @@ | ||
| 94755 | 94829 | pIdx->azColl[n] = pColl->zName; |
| 94756 | 94830 | n++; |
| 94757 | 94831 | } |
| 94758 | 94832 | } |
| 94759 | 94833 | } |
| 94760 | - assert( n==pLevel->plan.nEq ); | |
| 94834 | + assert( (u32)n==pLevel->plan.nEq ); | |
| 94761 | 94835 | |
| 94762 | 94836 | /* Add additional columns needed to make the automatic index into |
| 94763 | 94837 | ** a covering index */ |
| 94764 | 94838 | for(i=0; i<mxBitCol; i++){ |
| 94765 | 94839 | if( extraCols & (((Bitmask)1)<<i) ){ |
| @@ -96349,11 +96423,11 @@ | ||
| 96349 | 96423 | |
| 96350 | 96424 | /* If we are doing a reverse order scan on an ascending index, or |
| 96351 | 96425 | ** a forward order scan on a descending index, interchange the |
| 96352 | 96426 | ** start and end terms (pRangeStart and pRangeEnd). |
| 96353 | 96427 | */ |
| 96354 | - if( bRev==(pIdx->aSortOrder[nEq]==SQLITE_SO_ASC) ){ | |
| 96428 | + if( nEq<pIdx->nColumn && bRev==(pIdx->aSortOrder[nEq]==SQLITE_SO_ASC) ){ | |
| 96355 | 96429 | SWAP(WhereTerm *, pRangeEnd, pRangeStart); |
| 96356 | 96430 | } |
| 96357 | 96431 | |
| 96358 | 96432 | testcase( pRangeStart && pRangeStart->eOperator & WO_LE ); |
| 96359 | 96433 | testcase( pRangeStart && pRangeStart->eOperator & WO_GE ); |
| @@ -106034,10 +106108,13 @@ | ||
| 106034 | 106108 | |
| 106035 | 106109 | /* |
| 106036 | 106110 | ** An sqlite3_exec() callback for fts3TableExists. |
| 106037 | 106111 | */ |
| 106038 | 106112 | static int fts3TableExistsCallback(void *pArg, int n, char **pp1, char **pp2){ |
| 106113 | + UNUSED_PARAMETER(n); | |
| 106114 | + UNUSED_PARAMETER(pp1); | |
| 106115 | + UNUSED_PARAMETER(pp2); | |
| 106039 | 106116 | *(int*)pArg = 1; |
| 106040 | 106117 | return 1; |
| 106041 | 106118 | } |
| 106042 | 106119 | |
| 106043 | 106120 | /* |
| @@ -106059,11 +106136,11 @@ | ||
| 106059 | 106136 | "SELECT 1 FROM %Q.sqlite_master WHERE name='%q%s'", |
| 106060 | 106137 | zDb, zName, zSuffix |
| 106061 | 106138 | ); |
| 106062 | 106139 | rc = sqlite3_exec(db, zSql, fts3TableExistsCallback, &res, 0); |
| 106063 | 106140 | sqlite3_free(zSql); |
| 106064 | - *pResult = res & 0xff; | |
| 106141 | + *pResult = (u8)(res & 0xff); | |
| 106065 | 106142 | if( rc!=SQLITE_ABORT ) *pRc = rc; |
| 106066 | 106143 | } |
| 106067 | 106144 | |
| 106068 | 106145 | /* |
| 106069 | 106146 | ** This function is the implementation of both the xConnect and xCreate |
| 106070 | 106147 |
| --- 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 | ** |
| @@ -12795,12 +12795,14 @@ | |
| 12795 | ** sqlite3OsWrite() |
| 12796 | ** sqlite3OsSync() |
| 12797 | ** sqlite3OsLock() |
| 12798 | ** |
| 12799 | */ |
| 12800 | #if defined(SQLITE_TEST) && (SQLITE_OS_WIN==0) |
| 12801 | #define DO_OS_MALLOC_TEST(x) if (!x || !sqlite3IsMemJournal(x)) { \ |
| 12802 | void *pTstAlloc = sqlite3Malloc(10); \ |
| 12803 | if (!pTstAlloc) return SQLITE_IOERR_NOMEM; \ |
| 12804 | sqlite3_free(pTstAlloc); \ |
| 12805 | } |
| 12806 | #else |
| @@ -15367,15 +15369,21 @@ | |
| 15367 | ** |
| 15368 | ** This routines provide no mutual exclusion or error checking. |
| 15369 | */ |
| 15370 | static int noopMutexInit(void){ return SQLITE_OK; } |
| 15371 | static int noopMutexEnd(void){ return SQLITE_OK; } |
| 15372 | static sqlite3_mutex *noopMutexAlloc(int id){ return (sqlite3_mutex*)8; } |
| 15373 | static void noopMutexFree(sqlite3_mutex *p){ return; } |
| 15374 | static void noopMutexEnter(sqlite3_mutex *p){ return; } |
| 15375 | static int noopMutexTry(sqlite3_mutex *p){ return SQLITE_OK; } |
| 15376 | static void noopMutexLeave(sqlite3_mutex *p){ return; } |
| 15377 | |
| 15378 | SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3NoopMutex(void){ |
| 15379 | static const sqlite3_mutex_methods sMutex = { |
| 15380 | noopMutexInit, |
| 15381 | noopMutexEnd, |
| @@ -15524,11 +15532,11 @@ | |
| 15524 | ** If compiled with SQLITE_MUTEX_NOOP, then the no-op mutex implementation |
| 15525 | ** is used regardless of the run-time threadsafety setting. |
| 15526 | */ |
| 15527 | #ifdef SQLITE_MUTEX_NOOP |
| 15528 | SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){ |
| 15529 | return sqliteNoopMutex(); |
| 15530 | } |
| 15531 | #endif /* SQLITE_MUTEX_NOOP */ |
| 15532 | #endif /* SQLITE_MUTEX_OMIT */ |
| 15533 | |
| 15534 | /************** End of mutex_noop.c ******************************************/ |
| @@ -25957,10 +25965,11 @@ | |
| 25957 | ** any load or store begun after the barrier. |
| 25958 | */ |
| 25959 | static void unixShmBarrier( |
| 25960 | sqlite3_file *fd /* Database file holding the shared memory */ |
| 25961 | ){ |
| 25962 | unixEnterMutex(); |
| 25963 | unixLeaveMutex(); |
| 25964 | } |
| 25965 | |
| 25966 | /* |
| @@ -27249,10 +27258,11 @@ | |
| 27249 | ** current time and date as a Julian Day number into *prNow and |
| 27250 | ** return 0. Return 1 if the time and date cannot be found. |
| 27251 | */ |
| 27252 | static int unixCurrentTime(sqlite3_vfs *NotUsed, double *prNow){ |
| 27253 | sqlite3_int64 i; |
| 27254 | unixCurrentTimeInt64(0, &i); |
| 27255 | *prNow = i/86400000.0; |
| 27256 | return 0; |
| 27257 | } |
| 27258 | |
| @@ -27476,11 +27486,11 @@ | |
| 27476 | len = strlcat(lPath, "/", maxLen); |
| 27477 | } |
| 27478 | |
| 27479 | /* transform the db path to a unique cache name */ |
| 27480 | dbLen = (int)strlen(dbPath); |
| 27481 | for( i=0; i<dbLen && (i+len+7)<maxLen; i++){ |
| 27482 | char c = dbPath[i]; |
| 27483 | lPath[i+len] = (c=='/')?'_':c; |
| 27484 | } |
| 27485 | lPath[i+len]='\0'; |
| 27486 | strlcat(lPath, ":auto:", maxLen); |
| @@ -27617,10 +27627,13 @@ | |
| 27617 | SQLITE_API int sqlite3_hostid_num = 0; |
| 27618 | #endif |
| 27619 | |
| 27620 | #define PROXY_HOSTIDLEN 16 /* conch file host id length */ |
| 27621 | |
| 27622 | /* get the host ID via gethostuuid(), pHostID must point to PROXY_HOSTIDLEN |
| 27623 | ** bytes of writable memory. |
| 27624 | */ |
| 27625 | static int proxyGetHostID(unsigned char *pHostID, int *pError){ |
| 27626 | struct timespec timeout = {1, 0}; /* 1 sec timeout */ |
| @@ -27666,10 +27679,11 @@ | |
| 27666 | size_t readLen = 0; |
| 27667 | size_t pathLen = 0; |
| 27668 | char errmsg[64] = ""; |
| 27669 | int fd = -1; |
| 27670 | int rc = -1; |
| 27671 | |
| 27672 | /* create a new path by replace the trailing '-conch' with '-break' */ |
| 27673 | pathLen = strlcpy(tPath, cPath, MAXPATHLEN); |
| 27674 | if( pathLen>MAXPATHLEN || pathLen<6 || |
| 27675 | (strlcpy(&tPath[pathLen-5], "break", 6) != 5) ){ |
| @@ -27686,11 +27700,11 @@ | |
| 27686 | fd = open(tPath, (O_RDWR|O_CREAT|O_EXCL), SQLITE_DEFAULT_FILE_PERMISSIONS); |
| 27687 | if( fd<0 ){ |
| 27688 | sprintf(errmsg, "create failed (%d)", errno); |
| 27689 | goto end_breaklock; |
| 27690 | } |
| 27691 | if( pwrite(fd, buf, readLen, 0) != readLen ){ |
| 27692 | sprintf(errmsg, "write failed (%d)", errno); |
| 27693 | goto end_breaklock; |
| 27694 | } |
| 27695 | if( rename(tPath, cPath) ){ |
| 27696 | sprintf(errmsg, "rename failed (%d)", errno); |
| @@ -30183,10 +30197,13 @@ | |
| 30183 | /* Check to see if another process is holding the dead-man switch. |
| 30184 | ** If not, truncate the file to zero length. |
| 30185 | */ |
| 30186 | if( winShmSystemLock(pShmNode, _SHM_WRLCK, WIN_SHM_DMS, 1)==SQLITE_OK ){ |
| 30187 | rc = winTruncate((sqlite3_file *)&pShmNode->hFile, 0); |
| 30188 | } |
| 30189 | if( rc==SQLITE_OK ){ |
| 30190 | winShmSystemLock(pShmNode, _SHM_UNLCK, WIN_SHM_DMS, 1); |
| 30191 | rc = winShmSystemLock(pShmNode, _SHM_RDLCK, WIN_SHM_DMS, 1); |
| 30192 | } |
| @@ -30409,10 +30426,11 @@ | |
| 30409 | ** any load or store begun after the barrier. |
| 30410 | */ |
| 30411 | static void winShmBarrier( |
| 30412 | sqlite3_file *fd /* Database holding the shared memory */ |
| 30413 | ){ |
| 30414 | /* MemoryBarrier(); // does not work -- do not know why not */ |
| 30415 | winShmEnterMutex(); |
| 30416 | winShmLeaveMutex(); |
| 30417 | } |
| 30418 | |
| @@ -33496,17 +33514,18 @@ | |
| 33496 | # define sqlite3WalBeginReadTransaction(y,z) 0 |
| 33497 | # define sqlite3WalEndReadTransaction(z) |
| 33498 | # define sqlite3WalRead(v,w,x,y,z) 0 |
| 33499 | # define sqlite3WalDbsize(y,z) |
| 33500 | # define sqlite3WalBeginWriteTransaction(y) 0 |
| 33501 | # define sqlite3WalEndWRiteTransaction(x) 0 |
| 33502 | # define sqlite3WalUndo(x,y,z) 0 |
| 33503 | # define sqlite3WalSavepoint(y,z) |
| 33504 | # define sqlite3WalSavepointUndo(y,z) 0 |
| 33505 | # define sqlite3WalFrames(u,v,w,x,y,z) 0 |
| 33506 | # define sqlite3WalCheckpoint(u,v,w,x) 0 |
| 33507 | # define sqlite3WalCallback(z) 0 |
| 33508 | #else |
| 33509 | |
| 33510 | #define WAL_SAVEPOINT_NDATA 4 |
| 33511 | |
| 33512 | /* Connection to a write-ahead log (WAL) file. |
| @@ -33776,11 +33795,13 @@ | |
| 33776 | i64 iOffset; /* Starting offset in main journal */ |
| 33777 | i64 iHdrOffset; /* See above */ |
| 33778 | Bitvec *pInSavepoint; /* Set of pages in this savepoint */ |
| 33779 | Pgno nOrig; /* Original number of pages in file */ |
| 33780 | Pgno iSubRec; /* Index of first record in sub-journal */ |
| 33781 | u32 aWalData[WAL_SAVEPOINT_NDATA]; /* WAL savepoint context */ |
| 33782 | }; |
| 33783 | |
| 33784 | /* |
| 33785 | ** A open page cache is an instance of the following structure. |
| 33786 | ** |
| @@ -35967,48 +35988,75 @@ | |
| 35967 | |
| 35968 | return rc; |
| 35969 | } |
| 35970 | |
| 35971 | /* |
| 35972 | ** Check if the *-wal file that corresponds to the database opened by pPager |
| 35973 | ** exists. Assuming no error occurs, set *pExists to 1 if the file exists, |
| 35974 | ** or 0 otherwise and return SQLITE_OK. If an IO or OOM error occurs, return |
| 35975 | ** an SQLite error code. |
| 35976 | */ |
| 35977 | static int pagerHasWAL(Pager *pPager, int *pExists){ |
| 35978 | int rc; /* Return code */ |
| 35979 | char *zWal; /* Name of the WAL file */ |
| 35980 | |
| 35981 | assert( !pPager->tempFile ); |
| 35982 | zWal = sqlite3_mprintf("%s-wal", pPager->zFilename); |
| 35983 | if( !zWal ){ |
| 35984 | rc = SQLITE_NOMEM; |
| 35985 | }else{ |
| 35986 | rc = sqlite3OsAccess(pPager->pVfs, zWal, SQLITE_ACCESS_EXISTS, pExists); |
| 35987 | sqlite3_free(zWal); |
| 35988 | } |
| 35989 | return rc; |
| 35990 | } |
| 35991 | |
| 35992 | /* |
| 35993 | ** Check if the *-wal file that corresponds to the database opened by pPager |
| 35994 | ** exists. If it does, open the pager in WAL mode. Otherwise, if no error |
| 35995 | ** occurs, make sure Pager.journalMode is not set to PAGER_JOURNALMODE_WAL. |
| 35996 | ** If an IO or OOM error occurs, return an SQLite error code. |
| 35997 | ** |
| 35998 | ** If the WAL file is opened, also open a snapshot (read transaction). |
| 35999 | ** |
| 36000 | ** The caller must hold a SHARED lock on the database file to call this |
| 36001 | ** function. Because an EXCLUSIVE lock on the db file is required to delete |
| 36002 | ** a WAL, this ensures there is no race condition between the xAccess() |
| 36003 | ** below and an xDelete() being executed by some other connection. |
| 36004 | */ |
| 36005 | static int pagerOpenWalIfPresent(Pager *pPager){ |
| 36006 | int rc = SQLITE_OK; |
| 36007 | if( !pPager->tempFile ){ |
| 36008 | int isWal; /* True if WAL file exists */ |
| 36009 | rc = pagerHasWAL(pPager, &isWal); |
| 36010 | if( rc==SQLITE_OK ){ |
| 36011 | if( isWal ){ |
| 36012 | pager_reset(pPager); |
| 36013 | rc = sqlite3PagerOpenWal(pPager, 0); |
| 36014 | if( rc==SQLITE_OK ){ |
| @@ -36378,11 +36426,11 @@ | |
| 36378 | if( mxPage>0 ){ |
| 36379 | pPager->mxPgno = mxPage; |
| 36380 | } |
| 36381 | if( pPager->state!=PAGER_UNLOCK ){ |
| 36382 | sqlite3PagerPagecount(pPager, &nPage); |
| 36383 | assert( pPager->mxPgno>=nPage ); |
| 36384 | } |
| 36385 | return pPager->mxPgno; |
| 36386 | } |
| 36387 | |
| 36388 | /* |
| @@ -37756,11 +37804,11 @@ | |
| 37756 | ** |
| 37757 | ** There is a vanishingly small chance that a change will not be |
| 37758 | ** detected. The chance of an undetected change is so small that |
| 37759 | ** it can be neglected. |
| 37760 | */ |
| 37761 | int nPage; |
| 37762 | char dbFileVers[sizeof(pPager->dbFileVers)]; |
| 37763 | sqlite3PagerPagecount(pPager, &nPage); |
| 37764 | |
| 37765 | if( pPager->errCode ){ |
| 37766 | rc = pPager->errCode; |
| @@ -38187,34 +38235,23 @@ | |
| 38187 | /* No need to open the journal file at this time. It will be |
| 38188 | ** opened before it is written to. If we defer opening the journal, |
| 38189 | ** we might save the work of creating a file if the transaction |
| 38190 | ** ends up being a no-op. |
| 38191 | */ |
| 38192 | }else if( isOpen(pPager->jfd) && pPager->journalOff==0 ){ |
| 38193 | /* This happens when the pager was in exclusive-access mode the last |
| 38194 | ** time a (read or write) transaction was successfully concluded |
| 38195 | ** by this connection. Instead of deleting the journal file it was |
| 38196 | ** kept open and either was truncated to 0 bytes or its header was |
| 38197 | ** overwritten with zeros. |
| 38198 | */ |
| 38199 | assert( pagerUseWal(pPager)==0 ); |
| 38200 | assert( pPager->nRec==0 ); |
| 38201 | assert( pPager->dbOrigSize==0 ); |
| 38202 | assert( pPager->pInJournal==0 ); |
| 38203 | rc = pager_open_journal(pPager); |
| 38204 | } |
| 38205 | |
| 38206 | PAGERTRACE(("TRANSACTION %d\n", PAGERID(pPager))); |
| 38207 | if( rc!=SQLITE_OK ){ |
| 38208 | assert( !pPager->dbModified ); |
| 38209 | /* Ignore any IO error that occurs within pager_end_transaction(). The |
| 38210 | ** purpose of this call is to reset the internal state of the pager |
| 38211 | ** sub-system. It doesn't matter if the journal-file is not properly |
| 38212 | ** finalized at this point (since it is not a valid journal file anyway). |
| 38213 | */ |
| 38214 | pager_end_transaction(pPager, 0); |
| 38215 | } |
| 38216 | return rc; |
| 38217 | } |
| 38218 | |
| 38219 | /* |
| 38220 | ** Mark a single data page as writeable. The page is written into the |
| @@ -38261,14 +38298,11 @@ | |
| 38261 | ** |
| 38262 | ** Higher level routines should have already started a transaction, |
| 38263 | ** which means they have acquired the necessary locks but the rollback |
| 38264 | ** journal might not yet be open. |
| 38265 | */ |
| 38266 | rc = sqlite3PagerBegin(pPager, 0, pPager->subjInMemory); |
| 38267 | if( rc!=SQLITE_OK ){ |
| 38268 | return rc; |
| 38269 | } |
| 38270 | if( pPager->pInJournal==0 |
| 38271 | && pPager->journalMode!=PAGER_JOURNALMODE_OFF |
| 38272 | && !pagerUseWal(pPager) |
| 38273 | ){ |
| 38274 | assert( pPager->useJournal ); |
| @@ -38705,11 +38739,14 @@ | |
| 38705 | ** in 'direct' mode. In this case the journal file will never be |
| 38706 | ** created for this transaction. |
| 38707 | */ |
| 38708 | #ifdef SQLITE_ENABLE_ATOMIC_WRITE |
| 38709 | PgHdr *pPg; |
| 38710 | assert( isOpen(pPager->jfd) || pPager->journalMode==PAGER_JOURNALMODE_OFF ); |
| 38711 | if( !zMaster && isOpen(pPager->jfd) |
| 38712 | && pPager->journalOff==jrnlBufferSize(pPager) |
| 38713 | && pPager->dbSize>=pPager->dbFileSize |
| 38714 | && (0==(pPg = sqlite3PcacheDirtyList(pPager->pPCache)) || 0==pPg->pDirty) |
| 38715 | ){ |
| @@ -38839,11 +38876,11 @@ | |
| 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 | ** |
| @@ -38855,11 +38892,11 @@ | |
| 38855 | ** to drop any locks either. |
| 38856 | */ |
| 38857 | if( pPager->dbModified==0 && pPager->exclusiveMode |
| 38858 | && pPager->journalMode==PAGER_JOURNALMODE_PERSIST |
| 38859 | ){ |
| 38860 | assert( pPager->journalOff==JOURNAL_HDR_SZ(pPager) ); |
| 38861 | return SQLITE_OK; |
| 38862 | } |
| 38863 | |
| 38864 | PAGERTRACE(("COMMIT %d\n", PAGERID(pPager))); |
| 38865 | assert( pPager->state==PAGER_SYNCED || MEMDB || !pPager->dbModified ); |
| @@ -39189,11 +39226,11 @@ | |
| 39189 | |
| 39190 | #ifdef SQLITE_HAS_CODEC |
| 39191 | /* |
| 39192 | ** Set or retrieve the codec for this pager |
| 39193 | */ |
| 39194 | static void sqlite3PagerSetCodec( |
| 39195 | Pager *pPager, |
| 39196 | void *(*xCodec)(void*,void*,Pgno,int), |
| 39197 | void (*xCodecSizeChng)(void*,int,int), |
| 39198 | void (*xCodecFree)(void*), |
| 39199 | void *pCodec |
| @@ -39203,11 +39240,11 @@ | |
| 39203 | pPager->xCodecSizeChng = xCodecSizeChng; |
| 39204 | pPager->xCodecFree = xCodecFree; |
| 39205 | pPager->pCodec = pCodec; |
| 39206 | pagerReportSize(pPager); |
| 39207 | } |
| 39208 | static void *sqlite3PagerGetCodec(Pager *pPager){ |
| 39209 | return pPager->pCodec; |
| 39210 | } |
| 39211 | #endif |
| 39212 | |
| 39213 | #ifndef SQLITE_OMIT_AUTOVACUUM |
| @@ -39527,11 +39564,11 @@ | |
| 39527 | ** journalmode. Journalmode changes can only happen when the database |
| 39528 | ** is unmodified. |
| 39529 | */ |
| 39530 | SQLITE_PRIVATE int sqlite3PagerOkToChangeJournalMode(Pager *pPager){ |
| 39531 | if( pPager->dbModified ) return 0; |
| 39532 | if( isOpen(pPager->jfd) && pPager->journalOff>0 ) return 0; |
| 39533 | return 1; |
| 39534 | } |
| 39535 | |
| 39536 | /* |
| 39537 | ** Get/set the size-limit used for persistent journal files. |
| @@ -39584,21 +39621,34 @@ | |
| 39584 | const sqlite3_io_methods *pMethods = pPager->fd->pMethods; |
| 39585 | return pMethods->iVersion>=2 && pMethods->xShmOpen!=0; |
| 39586 | } |
| 39587 | |
| 39588 | /* |
| 39589 | ** Open a connection to the write-ahead log file for pager pPager. If |
| 39590 | ** the log connection is already open, this function is a no-op. |
| 39591 | ** |
| 39592 | ** The caller must be holding a SHARED lock on the database file to call |
| 39593 | ** this function. |
| 39594 | */ |
| 39595 | SQLITE_PRIVATE int sqlite3PagerOpenWal(Pager *pPager, int *pisOpen){ |
| 39596 | int rc = SQLITE_OK; /* Return code */ |
| 39597 | |
| 39598 | assert( pPager->state>=PAGER_SHARED ); |
| 39599 | if( !pPager->pWal ){ |
| 39600 | if( !sqlite3PagerWalSupported(pPager) ) return SQLITE_CANTOPEN; |
| 39601 | |
| 39602 | /* Open the connection to the log file. If this operation fails, |
| 39603 | ** (e.g. due to malloc() failure), unlock the database file and |
| 39604 | ** return an error code. |
| @@ -39635,11 +39685,11 @@ | |
| 39635 | */ |
| 39636 | if( !pPager->pWal ){ |
| 39637 | int logexists = 0; |
| 39638 | rc = sqlite3OsLock(pPager->fd, SQLITE_LOCK_SHARED); |
| 39639 | if( rc==SQLITE_OK ){ |
| 39640 | rc = pagerHasWAL(pPager, &logexists); |
| 39641 | } |
| 39642 | if( rc==SQLITE_OK && logexists ){ |
| 39643 | rc = sqlite3WalOpen(pPager->pVfs, pPager->fd, |
| 39644 | pPager->zFilename, &pPager->pWal); |
| 39645 | } |
| @@ -40182,16 +40232,16 @@ | |
| 40182 | |
| 40183 | /* Enlarge the pWal->apWiData[] array if required */ |
| 40184 | if( pWal->nWiData<=iPage ){ |
| 40185 | int nByte = sizeof(u32 *)*(iPage+1); |
| 40186 | volatile u32 **apNew; |
| 40187 | apNew = (volatile u32 **)sqlite3_realloc(pWal->apWiData, nByte); |
| 40188 | if( !apNew ){ |
| 40189 | *ppPage = 0; |
| 40190 | return SQLITE_NOMEM; |
| 40191 | } |
| 40192 | memset(&apNew[pWal->nWiData], 0, sizeof(u32 *)*(iPage+1-pWal->nWiData)); |
| 40193 | pWal->apWiData = apNew; |
| 40194 | pWal->nWiData = iPage+1; |
| 40195 | } |
| 40196 | |
| 40197 | /* Request a pointer to the required page from the VFS */ |
| @@ -40422,11 +40472,11 @@ | |
| 40422 | if( pWal->exclusiveMode ) return SQLITE_OK; |
| 40423 | rc = sqlite3OsShmLock(pWal->pDbFd, lockIdx, 1, |
| 40424 | SQLITE_SHM_LOCK | SQLITE_SHM_SHARED); |
| 40425 | WALTRACE(("WAL%p: acquire SHARED-%s %s\n", pWal, |
| 40426 | walLockName(lockIdx), rc ? "failed" : "ok")); |
| 40427 | VVA_ONLY( pWal->lockError = (rc!=SQLITE_OK && rc!=SQLITE_BUSY); ) |
| 40428 | return rc; |
| 40429 | } |
| 40430 | static void walUnlockShared(Wal *pWal, int lockIdx){ |
| 40431 | if( pWal->exclusiveMode ) return; |
| 40432 | (void)sqlite3OsShmLock(pWal->pDbFd, lockIdx, 1, |
| @@ -40438,11 +40488,11 @@ | |
| 40438 | if( pWal->exclusiveMode ) return SQLITE_OK; |
| 40439 | rc = sqlite3OsShmLock(pWal->pDbFd, lockIdx, n, |
| 40440 | SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE); |
| 40441 | WALTRACE(("WAL%p: acquire EXCLUSIVE-%s cnt=%d %s\n", pWal, |
| 40442 | walLockName(lockIdx), n, rc ? "failed" : "ok")); |
| 40443 | VVA_ONLY( pWal->lockError = (rc!=SQLITE_OK && rc!=SQLITE_BUSY); ) |
| 40444 | return rc; |
| 40445 | } |
| 40446 | static void walUnlockExclusive(Wal *pWal, int lockIdx, int n){ |
| 40447 | if( pWal->exclusiveMode ) return; |
| 40448 | (void)sqlite3OsShmLock(pWal->pDbFd, lockIdx, n, |
| @@ -40550,13 +40600,13 @@ | |
| 40550 | ** updated. Any later hash tables will be automatically cleared when |
| 40551 | ** pWal->hdr.mxFrame advances to the point where those hash tables are |
| 40552 | ** actually needed. |
| 40553 | */ |
| 40554 | static void walCleanupHash(Wal *pWal){ |
| 40555 | volatile ht_slot *aHash; /* Pointer to hash table to clear */ |
| 40556 | volatile u32 *aPgno; /* Page number array for hash table */ |
| 40557 | u32 iZero; /* frame == (aHash[x]+iZero) */ |
| 40558 | int iLimit = 0; /* Zero values greater than this */ |
| 40559 | int nByte; /* Number of bytes to zero in aPgno[] */ |
| 40560 | int i; /* Used to iterate through aHash[] */ |
| 40561 | |
| 40562 | assert( pWal->writeLock ); |
| @@ -40586,11 +40636,11 @@ | |
| 40586 | } |
| 40587 | |
| 40588 | /* Zero the entries in the aPgno array that correspond to frames with |
| 40589 | ** frame numbers greater than pWal->hdr.mxFrame. |
| 40590 | */ |
| 40591 | nByte = ((char *)aHash - (char *)&aPgno[iLimit+1]); |
| 40592 | memset((void *)&aPgno[iLimit+1], 0, nByte); |
| 40593 | |
| 40594 | #ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT |
| 40595 | /* Verify that the every entry in the mapping region is still reachable |
| 40596 | ** via the hash table even after the cleanup. |
| @@ -40613,13 +40663,13 @@ | |
| 40613 | ** Set an entry in the wal-index that will map database page number |
| 40614 | ** pPage into WAL frame iFrame. |
| 40615 | */ |
| 40616 | static int walIndexAppend(Wal *pWal, u32 iFrame, u32 iPage){ |
| 40617 | int rc; /* Return code */ |
| 40618 | u32 iZero; /* One less than frame number of aPgno[1] */ |
| 40619 | volatile u32 *aPgno; /* Page number array */ |
| 40620 | volatile ht_slot *aHash; /* Hash table */ |
| 40621 | |
| 40622 | rc = walHashGet(pWal, walFramePage(iFrame), &aHash, &aPgno, &iZero); |
| 40623 | |
| 40624 | /* Assuming the wal-index file was successfully mapped, populate the |
| 40625 | ** page number array and hash table entry. |
| @@ -40634,11 +40684,11 @@ | |
| 40634 | |
| 40635 | /* If this is the first entry to be added to this hash-table, zero the |
| 40636 | ** entire hash table and aPgno[] array before proceding. |
| 40637 | */ |
| 40638 | if( idx==1 ){ |
| 40639 | int nByte = (u8 *)&aHash[HASHTABLE_NSLOT] - (u8 *)&aPgno[1]; |
| 40640 | memset((void*)&aPgno[1], 0, nByte); |
| 40641 | } |
| 40642 | |
| 40643 | /* If the entry in aPgno[] is already set, then the previous writer |
| 40644 | ** must have exited unexpectedly in the middle of a transaction (after |
| @@ -40654,11 +40704,11 @@ | |
| 40654 | /* Write the aPgno[] array entry and the hash-table slot. */ |
| 40655 | for(iKey=walHash(iPage); aHash[iKey]; iKey=walNextHash(iKey)){ |
| 40656 | assert( nCollide++ < idx ); |
| 40657 | } |
| 40658 | aPgno[idx] = iPage; |
| 40659 | aHash[iKey] = idx; |
| 40660 | |
| 40661 | #ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT |
| 40662 | /* Verify that the number of entries in the hash table exactly equals |
| 40663 | ** the number of entries in the mapping region. |
| 40664 | */ |
| @@ -40762,12 +40812,12 @@ | |
| 40762 | || szPage>SQLITE_MAX_PAGE_SIZE |
| 40763 | || szPage<512 |
| 40764 | ){ |
| 40765 | goto finished; |
| 40766 | } |
| 40767 | pWal->hdr.bigEndCksum = (magic&0x00000001); |
| 40768 | pWal->szPage = szPage; |
| 40769 | pWal->nCkpt = sqlite3Get4byte(&aBuf[12]); |
| 40770 | memcpy(&pWal->hdr.aSalt, &aBuf[16], 8); |
| 40771 | |
| 40772 | /* Verify that the WAL header checksum is correct */ |
| 40773 | walChecksumBytes(pWal->hdr.bigEndCksum==SQLITE_BIGENDIAN, |
| @@ -40813,11 +40863,11 @@ | |
| 40813 | |
| 40814 | /* If nTruncate is non-zero, this is a commit record. */ |
| 40815 | if( nTruncate ){ |
| 40816 | pWal->hdr.mxFrame = iFrame; |
| 40817 | pWal->hdr.nPage = nTruncate; |
| 40818 | pWal->hdr.szPage = szPage; |
| 40819 | aFrameCksum[0] = pWal->hdr.aFrameCksum[0]; |
| 40820 | aFrameCksum[1] = pWal->hdr.aFrameCksum[1]; |
| 40821 | } |
| 40822 | } |
| 40823 | |
| @@ -41030,12 +41080,12 @@ | |
| 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)); |
| @@ -41141,16 +41191,16 @@ | |
| 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; |
| @@ -41333,11 +41383,11 @@ | |
| 41333 | sqlite3OsClose(pWal->pWalFd); |
| 41334 | if( isDelete ){ |
| 41335 | sqlite3OsDelete(pWal->pVfs, pWal->zWalName, 0); |
| 41336 | } |
| 41337 | WALTRACE(("WAL%p: closed\n", pWal)); |
| 41338 | sqlite3_free(pWal->apWiData); |
| 41339 | sqlite3_free(pWal); |
| 41340 | } |
| 41341 | return rc; |
| 41342 | } |
| 41343 | |
| @@ -41356,11 +41406,11 @@ | |
| 41356 | ** and *pChanged is set to 1. |
| 41357 | ** |
| 41358 | ** If the checksum cannot be verified return non-zero. If the header |
| 41359 | ** is read successfully and the checksum verified, return zero. |
| 41360 | */ |
| 41361 | int walIndexTryHdr(Wal *pWal, int *pChanged){ |
| 41362 | u32 aCksum[2]; /* Checksum on the header content */ |
| 41363 | WalIndexHdr h1, h2; /* Two copies of the header content */ |
| 41364 | WalIndexHdr volatile *aHdr; /* Header in shared memory */ |
| 41365 | |
| 41366 | /* The first page of the wal-index must be mapped at this point. */ |
| @@ -41669,11 +41719,11 @@ | |
| 41669 | ){ |
| 41670 | walUnlockShared(pWal, WAL_READ_LOCK(mxI)); |
| 41671 | return WAL_RETRY; |
| 41672 | }else{ |
| 41673 | assert( mxReadMark<=pWal->hdr.mxFrame ); |
| 41674 | pWal->readLock = mxI; |
| 41675 | } |
| 41676 | } |
| 41677 | return rc; |
| 41678 | } |
| 41679 | |
| @@ -42082,11 +42132,11 @@ | |
| 42082 | memcpy(&aWalHdr[16], pWal->hdr.aSalt, 8); |
| 42083 | walChecksumBytes(1, aWalHdr, WAL_HDRSIZE-2*4, 0, aCksum); |
| 42084 | sqlite3Put4byte(&aWalHdr[24], aCksum[0]); |
| 42085 | sqlite3Put4byte(&aWalHdr[28], aCksum[1]); |
| 42086 | |
| 42087 | pWal->szPage = szPage; |
| 42088 | pWal->hdr.bigEndCksum = SQLITE_BIGENDIAN; |
| 42089 | pWal->hdr.aFrameCksum[0] = aCksum[0]; |
| 42090 | pWal->hdr.aFrameCksum[1] = aCksum[1]; |
| 42091 | |
| 42092 | rc = sqlite3OsWrite(pWal->pWalFd, aWalHdr, sizeof(aWalHdr), 0); |
| @@ -42176,11 +42226,11 @@ | |
| 42176 | rc = walIndexAppend(pWal, iFrame, pLast->pgno); |
| 42177 | } |
| 42178 | |
| 42179 | if( rc==SQLITE_OK ){ |
| 42180 | /* Update the private copy of the header. */ |
| 42181 | pWal->hdr.szPage = szPage; |
| 42182 | pWal->hdr.mxFrame = iFrame; |
| 42183 | if( isCommit ){ |
| 42184 | pWal->hdr.iChange++; |
| 42185 | pWal->hdr.nPage = nTruncate; |
| 42186 | } |
| @@ -44913,20 +44963,24 @@ | |
| 44913 | MemPage **ppPage /* Write the page pointer here */ |
| 44914 | ){ |
| 44915 | int rc; |
| 44916 | assert( sqlite3_mutex_held(pBt->mutex) ); |
| 44917 | |
| 44918 | if( pgno<=0 || pgno>btreePagecount(pBt) ){ |
| 44919 | return SQLITE_CORRUPT_BKPT; |
| 44920 | } |
| 44921 | rc = btreeGetPage(pBt, pgno, ppPage, 0); |
| 44922 | if( rc==SQLITE_OK ){ |
| 44923 | rc = btreeInitPage(*ppPage); |
| 44924 | if( rc!=SQLITE_OK ){ |
| 44925 | releasePage(*ppPage); |
| 44926 | } |
| 44927 | } |
| 44928 | return rc; |
| 44929 | } |
| 44930 | |
| 44931 | /* |
| 44932 | ** Release a MemPage. This should be called once for each prior |
| @@ -45849,11 +45903,11 @@ | |
| 45849 | ** page 1. So if some other shared-cache client already has a write-lock |
| 45850 | ** on page 1, the transaction cannot be opened. */ |
| 45851 | rc = querySharedCacheTableLock(p, MASTER_ROOT, READ_LOCK); |
| 45852 | if( SQLITE_OK!=rc ) goto trans_begun; |
| 45853 | |
| 45854 | pBt->initiallyEmpty = pBt->nPage==0; |
| 45855 | do { |
| 45856 | /* Call lockBtree() until either pBt->pPage1 is populated or |
| 45857 | ** lockBtree() returns something other than SQLITE_OK. lockBtree() |
| 45858 | ** may return SQLITE_OK but leave pBt->pPage1 set to 0 if after |
| 45859 | ** reading page 1 it discovers that the page-size of the database |
| @@ -47572,11 +47626,10 @@ | |
| 47572 | rc = moveToRoot(pCur); |
| 47573 | if( rc==SQLITE_OK ){ |
| 47574 | if( pCur->eState==CURSOR_INVALID ){ |
| 47575 | assert( pCur->apPage[pCur->iPage]->nCell==0 ); |
| 47576 | *pRes = 1; |
| 47577 | rc = SQLITE_OK; |
| 47578 | }else{ |
| 47579 | assert( pCur->apPage[pCur->iPage]->nCell>0 ); |
| 47580 | *pRes = 0; |
| 47581 | rc = moveToLeftmost(pCur); |
| 47582 | } |
| @@ -51337,11 +51390,11 @@ | |
| 51337 | assert( iVersion==1 || iVersion==2 ); |
| 51338 | |
| 51339 | /* If setting the version fields to 1, do not automatically open the |
| 51340 | ** WAL connection, even if the version fields are currently set to 2. |
| 51341 | */ |
| 51342 | pBt->doNotUseWAL = (iVersion==1); |
| 51343 | |
| 51344 | rc = sqlite3BtreeBeginTrans(pBtree, 0); |
| 51345 | if( rc==SQLITE_OK ){ |
| 51346 | u8 *aData = pBt->pPage1->aData; |
| 51347 | if( aData[18]!=(u8)iVersion || aData[19]!=(u8)iVersion ){ |
| @@ -51829,10 +51882,13 @@ | |
| 51829 | TESTONLY( rc2 = ) sqlite3BtreeCommitPhaseOne(p->pSrc, 0); |
| 51830 | TESTONLY( rc2 |= ) sqlite3BtreeCommitPhaseTwo(p->pSrc); |
| 51831 | assert( rc2==SQLITE_OK ); |
| 51832 | } |
| 51833 | |
| 51834 | p->rc = rc; |
| 51835 | } |
| 51836 | if( p->pDestDb ){ |
| 51837 | sqlite3_mutex_leave(p->pDestDb->mutex); |
| 51838 | } |
| @@ -53951,11 +54007,13 @@ | |
| 53951 | ** having to double-check to make sure that the result is non-negative. But |
| 53952 | ** if SQLITE_OMIT_TRACE is defined, the OP_Trace is omitted and we do need to |
| 53953 | ** check the value of p->nOp-1 before continuing. |
| 53954 | */ |
| 53955 | SQLITE_PRIVATE VdbeOp *sqlite3VdbeGetOp(Vdbe *p, int addr){ |
| 53956 | static const VdbeOp dummy; |
| 53957 | assert( p->magic==VDBE_MAGIC_INIT ); |
| 53958 | if( addr<0 ){ |
| 53959 | #ifdef SQLITE_OMIT_TRACE |
| 53960 | if( p->nOp==0 ) return (VdbeOp*)&dummy; |
| 53961 | #endif |
| @@ -62382,18 +62440,17 @@ | |
| 62382 | #endif /* local variables moved into u.bl */ |
| 62383 | |
| 62384 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 62385 | u.bl.pC = p->apCsr[pOp->p1]; |
| 62386 | assert( u.bl.pC!=0 ); |
| 62387 | if( (u.bl.pCrsr = u.bl.pC->pCursor)!=0 ){ |
| 62388 | rc = sqlite3BtreeFirst(u.bl.pCrsr, &u.bl.res); |
| 62389 | u.bl.pC->atFirst = u.bl.res==0 ?1:0; |
| 62390 | u.bl.pC->deferredMoveto = 0; |
| 62391 | u.bl.pC->cacheStatus = CACHE_STALE; |
| 62392 | u.bl.pC->rowidIsValid = 0; |
| 62393 | }else{ |
| 62394 | u.bl.res = 1; |
| 62395 | } |
| 62396 | u.bl.pC->nullRow = (u8)u.bl.res; |
| 62397 | assert( pOp->p2>0 && pOp->p2<p->nOp ); |
| 62398 | if( u.bl.res ){ |
| 62399 | pc = pOp->p2 - 1; |
| @@ -63433,10 +63490,11 @@ | |
| 63433 | rc = sqlite3Checkpoint(db, pOp->p1); |
| 63434 | break; |
| 63435 | }; |
| 63436 | #endif |
| 63437 | |
| 63438 | /* Opcode: JournalMode P1 P2 P3 * P5 |
| 63439 | ** |
| 63440 | ** Change the journal mode of database P1 to P3. P3 must be one of the |
| 63441 | ** PAGER_JOURNALMODE_XXX values. If changing between the various rollback |
| 63442 | ** modes (delete, truncate, persist, off and memory), this is a simple |
| @@ -63559,11 +63617,12 @@ | |
| 63559 | pOut->z = (char *)sqlite3JournalModename(u.cd.eNew); |
| 63560 | pOut->n = sqlite3Strlen30(pOut->z); |
| 63561 | pOut->enc = SQLITE_UTF8; |
| 63562 | sqlite3VdbeChangeEncoding(pOut, encoding); |
| 63563 | break; |
| 63564 | }; |
| 63565 | |
| 63566 | #if !defined(SQLITE_OMIT_VACUUM) && !defined(SQLITE_OMIT_ATTACH) |
| 63567 | /* Opcode: Vacuum * * * * * |
| 63568 | ** |
| 63569 | ** Vacuum the entire database. This opcode will cause other virtual |
| @@ -64743,11 +64802,16 @@ | |
| 64743 | 0, /* xLock */ |
| 64744 | 0, /* xUnlock */ |
| 64745 | 0, /* xCheckReservedLock */ |
| 64746 | 0, /* xFileControl */ |
| 64747 | 0, /* xSectorSize */ |
| 64748 | 0 /* xDeviceCharacteristics */ |
| 64749 | }; |
| 64750 | |
| 64751 | /* |
| 64752 | ** Open a journal file. |
| 64753 | */ |
| @@ -65023,11 +65087,16 @@ | |
| 65023 | 0, /* xLock */ |
| 65024 | 0, /* xUnlock */ |
| 65025 | 0, /* xCheckReservedLock */ |
| 65026 | 0, /* xFileControl */ |
| 65027 | 0, /* xSectorSize */ |
| 65028 | 0 /* xDeviceCharacteristics */ |
| 65029 | }; |
| 65030 | |
| 65031 | /* |
| 65032 | ** Open a journal file. |
| 65033 | */ |
| @@ -65546,10 +65615,11 @@ | |
| 65546 | }else if( zTab ){ |
| 65547 | sqlite3ErrorMsg(pParse, "%s: %s.%s", zErr, zTab, zCol); |
| 65548 | }else{ |
| 65549 | sqlite3ErrorMsg(pParse, "%s: %s", zErr, zCol); |
| 65550 | } |
| 65551 | pTopNC->nErr++; |
| 65552 | } |
| 65553 | |
| 65554 | /* If a column from a table in pSrcList is referenced, then record |
| 65555 | ** this fact in the pSrcList.a[].colUsed bitmask. Column 0 causes |
| @@ -75035,10 +75105,11 @@ | |
| 75035 | if( sqlite3StrICmp(zColName, pTabCol->zName)==0 ) break; |
| 75036 | } |
| 75037 | if( j>=pTab->nCol ){ |
| 75038 | sqlite3ErrorMsg(pParse, "table %s has no column named %s", |
| 75039 | pTab->zName, zColName); |
| 75040 | goto exit_create_index; |
| 75041 | } |
| 75042 | pIndex->aiColumn[i] = j; |
| 75043 | /* Justification of the ALWAYS(pListItem->pExpr->pColl): Because of |
| 75044 | ** the way the "idxlist" non-terminal is constructed by the parser, |
| @@ -80735,11 +80806,11 @@ | |
| 80735 | if( sqlite3IsRowid(pColumn->a[i].zName) ){ |
| 80736 | keyColumn = i; |
| 80737 | }else{ |
| 80738 | sqlite3ErrorMsg(pParse, "table %S has no column named %s", |
| 80739 | pTabList, 0, pColumn->a[i].zName); |
| 80740 | pParse->nErr++; |
| 80741 | goto insert_cleanup; |
| 80742 | } |
| 80743 | } |
| 80744 | } |
| 80745 | } |
| @@ -88382,10 +88453,11 @@ | |
| 88382 | pIdx && sqlite3StrICmp(pIdx->zName, zIndex); |
| 88383 | pIdx=pIdx->pNext |
| 88384 | ); |
| 88385 | if( !pIdx ){ |
| 88386 | sqlite3ErrorMsg(pParse, "no such index: %s", zIndex, 0); |
| 88387 | return SQLITE_ERROR; |
| 88388 | } |
| 88389 | pFrom->pIndex = pIdx; |
| 88390 | } |
| 88391 | return SQLITE_OK; |
| @@ -90367,10 +90439,11 @@ | |
| 90367 | } |
| 90368 | if( !pTrigger ){ |
| 90369 | if( !noErr ){ |
| 90370 | sqlite3ErrorMsg(pParse, "no such trigger: %S", pName, 0); |
| 90371 | } |
| 90372 | goto drop_trigger_cleanup; |
| 90373 | } |
| 90374 | sqlite3DropTriggerPtr(pParse, pTrigger); |
| 90375 | |
| 90376 | drop_trigger_cleanup: |
| @@ -91177,10 +91250,11 @@ | |
| 91177 | if( sqlite3IsRowid(pChanges->a[i].zName) ){ |
| 91178 | chngRowid = 1; |
| 91179 | pRowidExpr = pChanges->a[i].pExpr; |
| 91180 | }else{ |
| 91181 | sqlite3ErrorMsg(pParse, "no such column: %s", pChanges->a[i].zName); |
| 91182 | goto update_cleanup; |
| 91183 | } |
| 91184 | } |
| 91185 | #ifndef SQLITE_OMIT_AUTHORIZATION |
| 91186 | { |
| @@ -94755,11 +94829,11 @@ | |
| 94755 | pIdx->azColl[n] = pColl->zName; |
| 94756 | n++; |
| 94757 | } |
| 94758 | } |
| 94759 | } |
| 94760 | assert( n==pLevel->plan.nEq ); |
| 94761 | |
| 94762 | /* Add additional columns needed to make the automatic index into |
| 94763 | ** a covering index */ |
| 94764 | for(i=0; i<mxBitCol; i++){ |
| 94765 | if( extraCols & (((Bitmask)1)<<i) ){ |
| @@ -96349,11 +96423,11 @@ | |
| 96349 | |
| 96350 | /* If we are doing a reverse order scan on an ascending index, or |
| 96351 | ** a forward order scan on a descending index, interchange the |
| 96352 | ** start and end terms (pRangeStart and pRangeEnd). |
| 96353 | */ |
| 96354 | if( bRev==(pIdx->aSortOrder[nEq]==SQLITE_SO_ASC) ){ |
| 96355 | SWAP(WhereTerm *, pRangeEnd, pRangeStart); |
| 96356 | } |
| 96357 | |
| 96358 | testcase( pRangeStart && pRangeStart->eOperator & WO_LE ); |
| 96359 | testcase( pRangeStart && pRangeStart->eOperator & WO_GE ); |
| @@ -106034,10 +106108,13 @@ | |
| 106034 | |
| 106035 | /* |
| 106036 | ** An sqlite3_exec() callback for fts3TableExists. |
| 106037 | */ |
| 106038 | static int fts3TableExistsCallback(void *pArg, int n, char **pp1, char **pp2){ |
| 106039 | *(int*)pArg = 1; |
| 106040 | return 1; |
| 106041 | } |
| 106042 | |
| 106043 | /* |
| @@ -106059,11 +106136,11 @@ | |
| 106059 | "SELECT 1 FROM %Q.sqlite_master WHERE name='%q%s'", |
| 106060 | zDb, zName, zSuffix |
| 106061 | ); |
| 106062 | rc = sqlite3_exec(db, zSql, fts3TableExistsCallback, &res, 0); |
| 106063 | sqlite3_free(zSql); |
| 106064 | *pResult = res & 0xff; |
| 106065 | if( rc!=SQLITE_ABORT ) *pRc = rc; |
| 106066 | } |
| 106067 | |
| 106068 | /* |
| 106069 | ** This function is the implementation of both the xConnect and xCreate |
| 106070 |
| --- 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-07-03 13:59:01 3b20ad03be55613d922d81aec5313327bf4098b9" |
| 642 | |
| 643 | /* |
| 644 | ** CAPI3REF: Run-Time Library Version Numbers |
| 645 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 646 | ** |
| @@ -12795,12 +12795,14 @@ | |
| 12795 | ** sqlite3OsWrite() |
| 12796 | ** sqlite3OsSync() |
| 12797 | ** sqlite3OsLock() |
| 12798 | ** |
| 12799 | */ |
| 12800 | #if defined(SQLITE_TEST) |
| 12801 | SQLITE_API int sqlite3_memdebug_vfs_oom_test = 1; |
| 12802 | #define DO_OS_MALLOC_TEST(x) \ |
| 12803 | if (sqlite3_memdebug_vfs_oom_test && (!x || !sqlite3IsMemJournal(x))) { \ |
| 12804 | void *pTstAlloc = sqlite3Malloc(10); \ |
| 12805 | if (!pTstAlloc) return SQLITE_IOERR_NOMEM; \ |
| 12806 | sqlite3_free(pTstAlloc); \ |
| 12807 | } |
| 12808 | #else |
| @@ -15367,15 +15369,21 @@ | |
| 15369 | ** |
| 15370 | ** This routines provide no mutual exclusion or error checking. |
| 15371 | */ |
| 15372 | static int noopMutexInit(void){ return SQLITE_OK; } |
| 15373 | static int noopMutexEnd(void){ return SQLITE_OK; } |
| 15374 | static sqlite3_mutex *noopMutexAlloc(int id){ |
| 15375 | UNUSED_PARAMETER(id); |
| 15376 | return (sqlite3_mutex*)8; |
| 15377 | } |
| 15378 | static void noopMutexFree(sqlite3_mutex *p){ UNUSED_PARAMETER(p); return; } |
| 15379 | static void noopMutexEnter(sqlite3_mutex *p){ UNUSED_PARAMETER(p); return; } |
| 15380 | static int noopMutexTry(sqlite3_mutex *p){ |
| 15381 | UNUSED_PARAMETER(p); |
| 15382 | return SQLITE_OK; |
| 15383 | } |
| 15384 | static void noopMutexLeave(sqlite3_mutex *p){ UNUSED_PARAMETER(p); return; } |
| 15385 | |
| 15386 | SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3NoopMutex(void){ |
| 15387 | static const sqlite3_mutex_methods sMutex = { |
| 15388 | noopMutexInit, |
| 15389 | noopMutexEnd, |
| @@ -15524,11 +15532,11 @@ | |
| 15532 | ** If compiled with SQLITE_MUTEX_NOOP, then the no-op mutex implementation |
| 15533 | ** is used regardless of the run-time threadsafety setting. |
| 15534 | */ |
| 15535 | #ifdef SQLITE_MUTEX_NOOP |
| 15536 | SQLITE_PRIVATE sqlite3_mutex_methods const *sqlite3DefaultMutex(void){ |
| 15537 | return sqlite3NoopMutex(); |
| 15538 | } |
| 15539 | #endif /* SQLITE_MUTEX_NOOP */ |
| 15540 | #endif /* SQLITE_MUTEX_OMIT */ |
| 15541 | |
| 15542 | /************** End of mutex_noop.c ******************************************/ |
| @@ -25957,10 +25965,11 @@ | |
| 25965 | ** any load or store begun after the barrier. |
| 25966 | */ |
| 25967 | static void unixShmBarrier( |
| 25968 | sqlite3_file *fd /* Database file holding the shared memory */ |
| 25969 | ){ |
| 25970 | UNUSED_PARAMETER(fd); |
| 25971 | unixEnterMutex(); |
| 25972 | unixLeaveMutex(); |
| 25973 | } |
| 25974 | |
| 25975 | /* |
| @@ -27249,10 +27258,11 @@ | |
| 27258 | ** current time and date as a Julian Day number into *prNow and |
| 27259 | ** return 0. Return 1 if the time and date cannot be found. |
| 27260 | */ |
| 27261 | static int unixCurrentTime(sqlite3_vfs *NotUsed, double *prNow){ |
| 27262 | sqlite3_int64 i; |
| 27263 | UNUSED_PARAMETER(NotUsed); |
| 27264 | unixCurrentTimeInt64(0, &i); |
| 27265 | *prNow = i/86400000.0; |
| 27266 | return 0; |
| 27267 | } |
| 27268 | |
| @@ -27476,11 +27486,11 @@ | |
| 27486 | len = strlcat(lPath, "/", maxLen); |
| 27487 | } |
| 27488 | |
| 27489 | /* transform the db path to a unique cache name */ |
| 27490 | dbLen = (int)strlen(dbPath); |
| 27491 | for( i=0; i<dbLen && (i+len+7)<(int)maxLen; i++){ |
| 27492 | char c = dbPath[i]; |
| 27493 | lPath[i+len] = (c=='/')?'_':c; |
| 27494 | } |
| 27495 | lPath[i+len]='\0'; |
| 27496 | strlcat(lPath, ":auto:", maxLen); |
| @@ -27617,10 +27627,13 @@ | |
| 27627 | SQLITE_API int sqlite3_hostid_num = 0; |
| 27628 | #endif |
| 27629 | |
| 27630 | #define PROXY_HOSTIDLEN 16 /* conch file host id length */ |
| 27631 | |
| 27632 | /* Not always defined in the headers as it ought to be */ |
| 27633 | extern int gethostuuid(uuid_t id, const struct timespec *wait); |
| 27634 | |
| 27635 | /* get the host ID via gethostuuid(), pHostID must point to PROXY_HOSTIDLEN |
| 27636 | ** bytes of writable memory. |
| 27637 | */ |
| 27638 | static int proxyGetHostID(unsigned char *pHostID, int *pError){ |
| 27639 | struct timespec timeout = {1, 0}; /* 1 sec timeout */ |
| @@ -27666,10 +27679,11 @@ | |
| 27679 | size_t readLen = 0; |
| 27680 | size_t pathLen = 0; |
| 27681 | char errmsg[64] = ""; |
| 27682 | int fd = -1; |
| 27683 | int rc = -1; |
| 27684 | UNUSED_PARAMETER(myHostID); |
| 27685 | |
| 27686 | /* create a new path by replace the trailing '-conch' with '-break' */ |
| 27687 | pathLen = strlcpy(tPath, cPath, MAXPATHLEN); |
| 27688 | if( pathLen>MAXPATHLEN || pathLen<6 || |
| 27689 | (strlcpy(&tPath[pathLen-5], "break", 6) != 5) ){ |
| @@ -27686,11 +27700,11 @@ | |
| 27700 | fd = open(tPath, (O_RDWR|O_CREAT|O_EXCL), SQLITE_DEFAULT_FILE_PERMISSIONS); |
| 27701 | if( fd<0 ){ |
| 27702 | sprintf(errmsg, "create failed (%d)", errno); |
| 27703 | goto end_breaklock; |
| 27704 | } |
| 27705 | if( pwrite(fd, buf, readLen, 0) != (ssize_t)readLen ){ |
| 27706 | sprintf(errmsg, "write failed (%d)", errno); |
| 27707 | goto end_breaklock; |
| 27708 | } |
| 27709 | if( rename(tPath, cPath) ){ |
| 27710 | sprintf(errmsg, "rename failed (%d)", errno); |
| @@ -30183,10 +30197,13 @@ | |
| 30197 | /* Check to see if another process is holding the dead-man switch. |
| 30198 | ** If not, truncate the file to zero length. |
| 30199 | */ |
| 30200 | if( winShmSystemLock(pShmNode, _SHM_WRLCK, WIN_SHM_DMS, 1)==SQLITE_OK ){ |
| 30201 | rc = winTruncate((sqlite3_file *)&pShmNode->hFile, 0); |
| 30202 | if( rc!=SQLITE_OK ){ |
| 30203 | rc = SQLITE_IOERR_SHMOPEN; |
| 30204 | } |
| 30205 | } |
| 30206 | if( rc==SQLITE_OK ){ |
| 30207 | winShmSystemLock(pShmNode, _SHM_UNLCK, WIN_SHM_DMS, 1); |
| 30208 | rc = winShmSystemLock(pShmNode, _SHM_RDLCK, WIN_SHM_DMS, 1); |
| 30209 | } |
| @@ -30409,10 +30426,11 @@ | |
| 30426 | ** any load or store begun after the barrier. |
| 30427 | */ |
| 30428 | static void winShmBarrier( |
| 30429 | sqlite3_file *fd /* Database holding the shared memory */ |
| 30430 | ){ |
| 30431 | UNUSED_PARAMETER(fd); |
| 30432 | /* MemoryBarrier(); // does not work -- do not know why not */ |
| 30433 | winShmEnterMutex(); |
| 30434 | winShmLeaveMutex(); |
| 30435 | } |
| 30436 | |
| @@ -33496,17 +33514,18 @@ | |
| 33514 | # define sqlite3WalBeginReadTransaction(y,z) 0 |
| 33515 | # define sqlite3WalEndReadTransaction(z) |
| 33516 | # define sqlite3WalRead(v,w,x,y,z) 0 |
| 33517 | # define sqlite3WalDbsize(y,z) |
| 33518 | # define sqlite3WalBeginWriteTransaction(y) 0 |
| 33519 | # define sqlite3WalEndWriteTransaction(x) 0 |
| 33520 | # define sqlite3WalUndo(x,y,z) 0 |
| 33521 | # define sqlite3WalSavepoint(y,z) |
| 33522 | # define sqlite3WalSavepointUndo(y,z) 0 |
| 33523 | # define sqlite3WalFrames(u,v,w,x,y,z) 0 |
| 33524 | # define sqlite3WalCheckpoint(u,v,w,x) 0 |
| 33525 | # define sqlite3WalCallback(z) 0 |
| 33526 | # define sqlite3WalExclusiveMode(y,z) 0 |
| 33527 | #else |
| 33528 | |
| 33529 | #define WAL_SAVEPOINT_NDATA 4 |
| 33530 | |
| 33531 | /* Connection to a write-ahead log (WAL) file. |
| @@ -33776,11 +33795,13 @@ | |
| 33795 | i64 iOffset; /* Starting offset in main journal */ |
| 33796 | i64 iHdrOffset; /* See above */ |
| 33797 | Bitvec *pInSavepoint; /* Set of pages in this savepoint */ |
| 33798 | Pgno nOrig; /* Original number of pages in file */ |
| 33799 | Pgno iSubRec; /* Index of first record in sub-journal */ |
| 33800 | #ifndef SQLITE_OMIT_WAL |
| 33801 | u32 aWalData[WAL_SAVEPOINT_NDATA]; /* WAL savepoint context */ |
| 33802 | #endif |
| 33803 | }; |
| 33804 | |
| 33805 | /* |
| 33806 | ** A open page cache is an instance of the following structure. |
| 33807 | ** |
| @@ -35967,48 +35988,75 @@ | |
| 35988 | |
| 35989 | return rc; |
| 35990 | } |
| 35991 | |
| 35992 | /* |
| 35993 | ** Check for the existence of or delete the *-wal file that corresponds to |
| 35994 | ** the database opened by pPager. |
| 35995 | ** |
| 35996 | ** When pExists!=NULL, set *pExists to 1 if the *-wal file exists, or 0 |
| 35997 | ** if the *-wal file does not exist. |
| 35998 | ** |
| 35999 | ** When pExists==NULL, delete the *-wal file if it exists, or the do |
| 36000 | ** nothing if the *-wal file does not exist. |
| 36001 | ** |
| 36002 | ** Return SQLITE_OK on success. If on an IO or OOM error occurs, return |
| 36003 | ** an SQLite error code. |
| 36004 | */ |
| 36005 | static int pagerCheckForOrDeleteWAL(Pager *pPager, int *pExists){ |
| 36006 | int rc; /* Return code */ |
| 36007 | char *zWal; /* Name of the WAL file */ |
| 36008 | |
| 36009 | assert( !pPager->tempFile ); |
| 36010 | zWal = sqlite3_mprintf("%s-wal", pPager->zFilename); |
| 36011 | if( !zWal ){ |
| 36012 | rc = SQLITE_NOMEM; |
| 36013 | }else{ |
| 36014 | if( pExists ){ |
| 36015 | rc = sqlite3OsAccess(pPager->pVfs, zWal, SQLITE_ACCESS_EXISTS, pExists); |
| 36016 | }else{ |
| 36017 | rc = sqlite3OsDelete(pPager->pVfs, zWal, 0); |
| 36018 | } |
| 36019 | sqlite3_free(zWal); |
| 36020 | } |
| 36021 | return rc; |
| 36022 | } |
| 36023 | |
| 36024 | /* |
| 36025 | ** Check if the *-wal file that corresponds to the database opened by pPager |
| 36026 | ** exists if the database is not empy, or verify that the *-wal file does |
| 36027 | ** not exist (by deleting it) if the database file is empty. |
| 36028 | ** |
| 36029 | ** If the database is not empty and the *-wal file exists, open the pager |
| 36030 | ** in WAL mode. If the database is empty or if no *-wal file exists and |
| 36031 | ** if no error occurs, make sure Pager.journalMode is not set to |
| 36032 | ** PAGER_JOURNALMODE_WAL. |
| 36033 | ** |
| 36034 | ** Return SQLITE_OK or an error code. |
| 36035 | ** |
| 36036 | ** If the WAL file is opened, also open a snapshot (read transaction). |
| 36037 | ** |
| 36038 | ** The caller must hold a SHARED lock on the database file to call this |
| 36039 | ** function. Because an EXCLUSIVE lock on the db file is required to delete |
| 36040 | ** a WAL on a none-empty database, this ensures there is no race condition |
| 36041 | ** between the xAccess() below and an xDelete() being executed by some |
| 36042 | ** other connection. |
| 36043 | */ |
| 36044 | static int pagerOpenWalIfPresent(Pager *pPager){ |
| 36045 | int rc = SQLITE_OK; |
| 36046 | if( !pPager->tempFile ){ |
| 36047 | int isWal; /* True if WAL file exists */ |
| 36048 | int nPage; /* Size of the database file */ |
| 36049 | assert( pPager->state>=SHARED_LOCK ); |
| 36050 | rc = sqlite3PagerPagecount(pPager, &nPage); |
| 36051 | if( rc ) return rc; |
| 36052 | if( nPage==0 ){ |
| 36053 | rc = pagerCheckForOrDeleteWAL(pPager, 0); |
| 36054 | isWal = 0; |
| 36055 | }else{ |
| 36056 | rc = pagerCheckForOrDeleteWAL(pPager, &isWal); |
| 36057 | } |
| 36058 | if( rc==SQLITE_OK ){ |
| 36059 | if( isWal ){ |
| 36060 | pager_reset(pPager); |
| 36061 | rc = sqlite3PagerOpenWal(pPager, 0); |
| 36062 | if( rc==SQLITE_OK ){ |
| @@ -36378,11 +36426,11 @@ | |
| 36426 | if( mxPage>0 ){ |
| 36427 | pPager->mxPgno = mxPage; |
| 36428 | } |
| 36429 | if( pPager->state!=PAGER_UNLOCK ){ |
| 36430 | sqlite3PagerPagecount(pPager, &nPage); |
| 36431 | assert( (int)pPager->mxPgno>=nPage ); |
| 36432 | } |
| 36433 | return pPager->mxPgno; |
| 36434 | } |
| 36435 | |
| 36436 | /* |
| @@ -37756,11 +37804,11 @@ | |
| 37804 | ** |
| 37805 | ** There is a vanishingly small chance that a change will not be |
| 37806 | ** detected. The chance of an undetected change is so small that |
| 37807 | ** it can be neglected. |
| 37808 | */ |
| 37809 | int nPage = 0; |
| 37810 | char dbFileVers[sizeof(pPager->dbFileVers)]; |
| 37811 | sqlite3PagerPagecount(pPager, &nPage); |
| 37812 | |
| 37813 | if( pPager->errCode ){ |
| 37814 | rc = pPager->errCode; |
| @@ -38187,34 +38235,23 @@ | |
| 38235 | /* No need to open the journal file at this time. It will be |
| 38236 | ** opened before it is written to. If we defer opening the journal, |
| 38237 | ** we might save the work of creating a file if the transaction |
| 38238 | ** ends up being a no-op. |
| 38239 | */ |
| 38240 | |
| 38241 | if( rc!=SQLITE_OK ){ |
| 38242 | assert( !pPager->dbModified ); |
| 38243 | /* Ignore any IO error that occurs within pager_end_transaction(). The |
| 38244 | ** purpose of this call is to reset the internal state of the pager |
| 38245 | ** sub-system. It doesn't matter if the journal-file is not properly |
| 38246 | ** finalized at this point (since it is not a valid journal file anyway). |
| 38247 | */ |
| 38248 | pager_end_transaction(pPager, 0); |
| 38249 | } |
| 38250 | } |
| 38251 | |
| 38252 | PAGERTRACE(("TRANSACTION %d\n", PAGERID(pPager))); |
| 38253 | return rc; |
| 38254 | } |
| 38255 | |
| 38256 | /* |
| 38257 | ** Mark a single data page as writeable. The page is written into the |
| @@ -38261,14 +38298,11 @@ | |
| 38298 | ** |
| 38299 | ** Higher level routines should have already started a transaction, |
| 38300 | ** which means they have acquired the necessary locks but the rollback |
| 38301 | ** journal might not yet be open. |
| 38302 | */ |
| 38303 | assert( pPager->state>=RESERVED_LOCK ); |
| 38304 | if( pPager->pInJournal==0 |
| 38305 | && pPager->journalMode!=PAGER_JOURNALMODE_OFF |
| 38306 | && !pagerUseWal(pPager) |
| 38307 | ){ |
| 38308 | assert( pPager->useJournal ); |
| @@ -38705,11 +38739,14 @@ | |
| 38739 | ** in 'direct' mode. In this case the journal file will never be |
| 38740 | ** created for this transaction. |
| 38741 | */ |
| 38742 | #ifdef SQLITE_ENABLE_ATOMIC_WRITE |
| 38743 | PgHdr *pPg; |
| 38744 | assert( isOpen(pPager->jfd) |
| 38745 | || pPager->journalMode==PAGER_JOURNALMODE_OFF |
| 38746 | || pPager->journalMode==PAGER_JOURNALMODE_WAL |
| 38747 | ); |
| 38748 | if( !zMaster && isOpen(pPager->jfd) |
| 38749 | && pPager->journalOff==jrnlBufferSize(pPager) |
| 38750 | && pPager->dbSize>=pPager->dbFileSize |
| 38751 | && (0==(pPg = sqlite3PcacheDirtyList(pPager->pPCache)) || 0==pPg->pDirty) |
| 38752 | ){ |
| @@ -38839,11 +38876,11 @@ | |
| 38876 | /* This function should not be called if the pager is not in at least |
| 38877 | ** PAGER_RESERVED state. **FIXME**: Make it so that this test always |
| 38878 | ** fails - make it so that we never reach this point if we do not hold |
| 38879 | ** all necessary locks. |
| 38880 | */ |
| 38881 | if( NEVER(pPager->state<PAGER_RESERVED) ) return SQLITE_ERROR; |
| 38882 | |
| 38883 | /* An optimization. If the database was not actually modified during |
| 38884 | ** this transaction, the pager is running in exclusive-mode and is |
| 38885 | ** using persistent journals, then this function is a no-op. |
| 38886 | ** |
| @@ -38855,11 +38892,11 @@ | |
| 38892 | ** to drop any locks either. |
| 38893 | */ |
| 38894 | if( pPager->dbModified==0 && pPager->exclusiveMode |
| 38895 | && pPager->journalMode==PAGER_JOURNALMODE_PERSIST |
| 38896 | ){ |
| 38897 | assert( pPager->journalOff==JOURNAL_HDR_SZ(pPager) || !pPager->journalOff ); |
| 38898 | return SQLITE_OK; |
| 38899 | } |
| 38900 | |
| 38901 | PAGERTRACE(("COMMIT %d\n", PAGERID(pPager))); |
| 38902 | assert( pPager->state==PAGER_SYNCED || MEMDB || !pPager->dbModified ); |
| @@ -39189,11 +39226,11 @@ | |
| 39226 | |
| 39227 | #ifdef SQLITE_HAS_CODEC |
| 39228 | /* |
| 39229 | ** Set or retrieve the codec for this pager |
| 39230 | */ |
| 39231 | SQLITE_PRIVATE void sqlite3PagerSetCodec( |
| 39232 | Pager *pPager, |
| 39233 | void *(*xCodec)(void*,void*,Pgno,int), |
| 39234 | void (*xCodecSizeChng)(void*,int,int), |
| 39235 | void (*xCodecFree)(void*), |
| 39236 | void *pCodec |
| @@ -39203,11 +39240,11 @@ | |
| 39240 | pPager->xCodecSizeChng = xCodecSizeChng; |
| 39241 | pPager->xCodecFree = xCodecFree; |
| 39242 | pPager->pCodec = pCodec; |
| 39243 | pagerReportSize(pPager); |
| 39244 | } |
| 39245 | SQLITE_PRIVATE void *sqlite3PagerGetCodec(Pager *pPager){ |
| 39246 | return pPager->pCodec; |
| 39247 | } |
| 39248 | #endif |
| 39249 | |
| 39250 | #ifndef SQLITE_OMIT_AUTOVACUUM |
| @@ -39527,11 +39564,11 @@ | |
| 39564 | ** journalmode. Journalmode changes can only happen when the database |
| 39565 | ** is unmodified. |
| 39566 | */ |
| 39567 | SQLITE_PRIVATE int sqlite3PagerOkToChangeJournalMode(Pager *pPager){ |
| 39568 | if( pPager->dbModified ) return 0; |
| 39569 | if( NEVER(isOpen(pPager->jfd) && pPager->journalOff>0) ) return 0; |
| 39570 | return 1; |
| 39571 | } |
| 39572 | |
| 39573 | /* |
| 39574 | ** Get/set the size-limit used for persistent journal files. |
| @@ -39584,21 +39621,34 @@ | |
| 39621 | const sqlite3_io_methods *pMethods = pPager->fd->pMethods; |
| 39622 | return pMethods->iVersion>=2 && pMethods->xShmOpen!=0; |
| 39623 | } |
| 39624 | |
| 39625 | /* |
| 39626 | ** The caller must be holding a SHARED lock on the database file to call |
| 39627 | ** this function. |
| 39628 | ** |
| 39629 | ** If the pager passed as the first argument is open on a real database |
| 39630 | ** file (not a temp file or an in-memory database), and the WAL file |
| 39631 | ** is not already open, make an attempt to open it now. If successful, |
| 39632 | ** return SQLITE_OK. If an error occurs or the VFS used by the pager does |
| 39633 | ** not support the xShmXXX() methods, return an error code. *pisOpen is |
| 39634 | ** not modified in either case. |
| 39635 | ** |
| 39636 | ** If the pager is open on a temp-file (or in-memory database), or if |
| 39637 | ** the WAL file is already open, set *pisOpen to 1 and return SQLITE_OK |
| 39638 | ** without doing anything. |
| 39639 | */ |
| 39640 | SQLITE_PRIVATE int sqlite3PagerOpenWal( |
| 39641 | Pager *pPager, /* Pager object */ |
| 39642 | int *pisOpen /* OUT: Set to true if call is a no-op */ |
| 39643 | ){ |
| 39644 | int rc = SQLITE_OK; /* Return code */ |
| 39645 | |
| 39646 | assert( pPager->state>=PAGER_SHARED ); |
| 39647 | assert( (pisOpen==0 && !pPager->tempFile && !pPager->pWal) || *pisOpen==0 ); |
| 39648 | |
| 39649 | if( !pPager->tempFile && !pPager->pWal ){ |
| 39650 | if( !sqlite3PagerWalSupported(pPager) ) return SQLITE_CANTOPEN; |
| 39651 | |
| 39652 | /* Open the connection to the log file. If this operation fails, |
| 39653 | ** (e.g. due to malloc() failure), unlock the database file and |
| 39654 | ** return an error code. |
| @@ -39635,11 +39685,11 @@ | |
| 39685 | */ |
| 39686 | if( !pPager->pWal ){ |
| 39687 | int logexists = 0; |
| 39688 | rc = sqlite3OsLock(pPager->fd, SQLITE_LOCK_SHARED); |
| 39689 | if( rc==SQLITE_OK ){ |
| 39690 | rc = pagerCheckForOrDeleteWAL(pPager, &logexists); |
| 39691 | } |
| 39692 | if( rc==SQLITE_OK && logexists ){ |
| 39693 | rc = sqlite3WalOpen(pPager->pVfs, pPager->fd, |
| 39694 | pPager->zFilename, &pPager->pWal); |
| 39695 | } |
| @@ -40182,16 +40232,16 @@ | |
| 40232 | |
| 40233 | /* Enlarge the pWal->apWiData[] array if required */ |
| 40234 | if( pWal->nWiData<=iPage ){ |
| 40235 | int nByte = sizeof(u32 *)*(iPage+1); |
| 40236 | volatile u32 **apNew; |
| 40237 | apNew = (volatile u32 **)sqlite3_realloc((void *)pWal->apWiData, nByte); |
| 40238 | if( !apNew ){ |
| 40239 | *ppPage = 0; |
| 40240 | return SQLITE_NOMEM; |
| 40241 | } |
| 40242 | memset((void *)&apNew[pWal->nWiData], 0, sizeof(u32 *)*(iPage+1-pWal->nWiData)); |
| 40243 | pWal->apWiData = apNew; |
| 40244 | pWal->nWiData = iPage+1; |
| 40245 | } |
| 40246 | |
| 40247 | /* Request a pointer to the required page from the VFS */ |
| @@ -40422,11 +40472,11 @@ | |
| 40472 | if( pWal->exclusiveMode ) return SQLITE_OK; |
| 40473 | rc = sqlite3OsShmLock(pWal->pDbFd, lockIdx, 1, |
| 40474 | SQLITE_SHM_LOCK | SQLITE_SHM_SHARED); |
| 40475 | WALTRACE(("WAL%p: acquire SHARED-%s %s\n", pWal, |
| 40476 | walLockName(lockIdx), rc ? "failed" : "ok")); |
| 40477 | VVA_ONLY( pWal->lockError = (u8)(rc!=SQLITE_OK && rc!=SQLITE_BUSY); ) |
| 40478 | return rc; |
| 40479 | } |
| 40480 | static void walUnlockShared(Wal *pWal, int lockIdx){ |
| 40481 | if( pWal->exclusiveMode ) return; |
| 40482 | (void)sqlite3OsShmLock(pWal->pDbFd, lockIdx, 1, |
| @@ -40438,11 +40488,11 @@ | |
| 40488 | if( pWal->exclusiveMode ) return SQLITE_OK; |
| 40489 | rc = sqlite3OsShmLock(pWal->pDbFd, lockIdx, n, |
| 40490 | SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE); |
| 40491 | WALTRACE(("WAL%p: acquire EXCLUSIVE-%s cnt=%d %s\n", pWal, |
| 40492 | walLockName(lockIdx), n, rc ? "failed" : "ok")); |
| 40493 | VVA_ONLY( pWal->lockError = (u8)(rc!=SQLITE_OK && rc!=SQLITE_BUSY); ) |
| 40494 | return rc; |
| 40495 | } |
| 40496 | static void walUnlockExclusive(Wal *pWal, int lockIdx, int n){ |
| 40497 | if( pWal->exclusiveMode ) return; |
| 40498 | (void)sqlite3OsShmLock(pWal->pDbFd, lockIdx, n, |
| @@ -40550,13 +40600,13 @@ | |
| 40600 | ** updated. Any later hash tables will be automatically cleared when |
| 40601 | ** pWal->hdr.mxFrame advances to the point where those hash tables are |
| 40602 | ** actually needed. |
| 40603 | */ |
| 40604 | static void walCleanupHash(Wal *pWal){ |
| 40605 | volatile ht_slot *aHash = 0; /* Pointer to hash table to clear */ |
| 40606 | volatile u32 *aPgno = 0; /* Page number array for hash table */ |
| 40607 | u32 iZero = 0; /* frame == (aHash[x]+iZero) */ |
| 40608 | int iLimit = 0; /* Zero values greater than this */ |
| 40609 | int nByte; /* Number of bytes to zero in aPgno[] */ |
| 40610 | int i; /* Used to iterate through aHash[] */ |
| 40611 | |
| 40612 | assert( pWal->writeLock ); |
| @@ -40586,11 +40636,11 @@ | |
| 40636 | } |
| 40637 | |
| 40638 | /* Zero the entries in the aPgno array that correspond to frames with |
| 40639 | ** frame numbers greater than pWal->hdr.mxFrame. |
| 40640 | */ |
| 40641 | nByte = (int)((char *)aHash - (char *)&aPgno[iLimit+1]); |
| 40642 | memset((void *)&aPgno[iLimit+1], 0, nByte); |
| 40643 | |
| 40644 | #ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT |
| 40645 | /* Verify that the every entry in the mapping region is still reachable |
| 40646 | ** via the hash table even after the cleanup. |
| @@ -40613,13 +40663,13 @@ | |
| 40663 | ** Set an entry in the wal-index that will map database page number |
| 40664 | ** pPage into WAL frame iFrame. |
| 40665 | */ |
| 40666 | static int walIndexAppend(Wal *pWal, u32 iFrame, u32 iPage){ |
| 40667 | int rc; /* Return code */ |
| 40668 | u32 iZero = 0; /* One less than frame number of aPgno[1] */ |
| 40669 | volatile u32 *aPgno = 0; /* Page number array */ |
| 40670 | volatile ht_slot *aHash = 0; /* Hash table */ |
| 40671 | |
| 40672 | rc = walHashGet(pWal, walFramePage(iFrame), &aHash, &aPgno, &iZero); |
| 40673 | |
| 40674 | /* Assuming the wal-index file was successfully mapped, populate the |
| 40675 | ** page number array and hash table entry. |
| @@ -40634,11 +40684,11 @@ | |
| 40684 | |
| 40685 | /* If this is the first entry to be added to this hash-table, zero the |
| 40686 | ** entire hash table and aPgno[] array before proceding. |
| 40687 | */ |
| 40688 | if( idx==1 ){ |
| 40689 | int nByte = (int)((u8 *)&aHash[HASHTABLE_NSLOT] - (u8 *)&aPgno[1]); |
| 40690 | memset((void*)&aPgno[1], 0, nByte); |
| 40691 | } |
| 40692 | |
| 40693 | /* If the entry in aPgno[] is already set, then the previous writer |
| 40694 | ** must have exited unexpectedly in the middle of a transaction (after |
| @@ -40654,11 +40704,11 @@ | |
| 40704 | /* Write the aPgno[] array entry and the hash-table slot. */ |
| 40705 | for(iKey=walHash(iPage); aHash[iKey]; iKey=walNextHash(iKey)){ |
| 40706 | assert( nCollide++ < idx ); |
| 40707 | } |
| 40708 | aPgno[idx] = iPage; |
| 40709 | aHash[iKey] = (ht_slot)idx; |
| 40710 | |
| 40711 | #ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT |
| 40712 | /* Verify that the number of entries in the hash table exactly equals |
| 40713 | ** the number of entries in the mapping region. |
| 40714 | */ |
| @@ -40762,12 +40812,12 @@ | |
| 40812 | || szPage>SQLITE_MAX_PAGE_SIZE |
| 40813 | || szPage<512 |
| 40814 | ){ |
| 40815 | goto finished; |
| 40816 | } |
| 40817 | pWal->hdr.bigEndCksum = (u8)(magic&0x00000001); |
| 40818 | pWal->szPage = (u16)szPage; |
| 40819 | pWal->nCkpt = sqlite3Get4byte(&aBuf[12]); |
| 40820 | memcpy(&pWal->hdr.aSalt, &aBuf[16], 8); |
| 40821 | |
| 40822 | /* Verify that the WAL header checksum is correct */ |
| 40823 | walChecksumBytes(pWal->hdr.bigEndCksum==SQLITE_BIGENDIAN, |
| @@ -40813,11 +40863,11 @@ | |
| 40863 | |
| 40864 | /* If nTruncate is non-zero, this is a commit record. */ |
| 40865 | if( nTruncate ){ |
| 40866 | pWal->hdr.mxFrame = iFrame; |
| 40867 | pWal->hdr.nPage = nTruncate; |
| 40868 | pWal->hdr.szPage = (u16)szPage; |
| 40869 | aFrameCksum[0] = pWal->hdr.aFrameCksum[0]; |
| 40870 | aFrameCksum[1] = pWal->hdr.aFrameCksum[1]; |
| 40871 | } |
| 40872 | } |
| 40873 | |
| @@ -41030,12 +41080,12 @@ | |
| 41080 | int nList; /* Number of elements in aList */ |
| 41081 | ht_slot *aList; /* Pointer to sub-list content */ |
| 41082 | }; |
| 41083 | |
| 41084 | const int nList = *pnList; /* Size of input list */ |
| 41085 | int nMerge = 0; /* Number of elements in list aMerge */ |
| 41086 | ht_slot *aMerge = 0; /* List to be merged */ |
| 41087 | int iList; /* Index into input list */ |
| 41088 | int iSub = 0; /* Index into aSub array */ |
| 41089 | struct Sublist aSub[13]; /* Array of sub-lists */ |
| 41090 | |
| 41091 | memset(aSub, 0, sizeof(aSub)); |
| @@ -41141,16 +41191,16 @@ | |
| 41191 | int j; /* Counter variable */ |
| 41192 | int nEntry; /* Number of entries in this segment */ |
| 41193 | ht_slot *aIndex; /* Sorted index for this segment */ |
| 41194 | |
| 41195 | aPgno++; |
| 41196 | nEntry = (int)(((i+1)==nSegment)?(int)(iLast-iZero):(u32 *)aHash-(u32 *)aPgno); |
| 41197 | aIndex = &((ht_slot *)&p->aSegment[p->nSegment])[iZero]; |
| 41198 | iZero++; |
| 41199 | |
| 41200 | for(j=0; j<nEntry; j++){ |
| 41201 | aIndex[j] = (ht_slot)j; |
| 41202 | } |
| 41203 | walMergesort((u32 *)aPgno, aTmp, aIndex, &nEntry); |
| 41204 | p->aSegment[i].iZero = iZero; |
| 41205 | p->aSegment[i].nEntry = nEntry; |
| 41206 | p->aSegment[i].aIndex = aIndex; |
| @@ -41333,11 +41383,11 @@ | |
| 41383 | sqlite3OsClose(pWal->pWalFd); |
| 41384 | if( isDelete ){ |
| 41385 | sqlite3OsDelete(pWal->pVfs, pWal->zWalName, 0); |
| 41386 | } |
| 41387 | WALTRACE(("WAL%p: closed\n", pWal)); |
| 41388 | sqlite3_free((void *)pWal->apWiData); |
| 41389 | sqlite3_free(pWal); |
| 41390 | } |
| 41391 | return rc; |
| 41392 | } |
| 41393 | |
| @@ -41356,11 +41406,11 @@ | |
| 41406 | ** and *pChanged is set to 1. |
| 41407 | ** |
| 41408 | ** If the checksum cannot be verified return non-zero. If the header |
| 41409 | ** is read successfully and the checksum verified, return zero. |
| 41410 | */ |
| 41411 | static int walIndexTryHdr(Wal *pWal, int *pChanged){ |
| 41412 | u32 aCksum[2]; /* Checksum on the header content */ |
| 41413 | WalIndexHdr h1, h2; /* Two copies of the header content */ |
| 41414 | WalIndexHdr volatile *aHdr; /* Header in shared memory */ |
| 41415 | |
| 41416 | /* The first page of the wal-index must be mapped at this point. */ |
| @@ -41669,11 +41719,11 @@ | |
| 41719 | ){ |
| 41720 | walUnlockShared(pWal, WAL_READ_LOCK(mxI)); |
| 41721 | return WAL_RETRY; |
| 41722 | }else{ |
| 41723 | assert( mxReadMark<=pWal->hdr.mxFrame ); |
| 41724 | pWal->readLock = (i16)mxI; |
| 41725 | } |
| 41726 | } |
| 41727 | return rc; |
| 41728 | } |
| 41729 | |
| @@ -42082,11 +42132,11 @@ | |
| 42132 | memcpy(&aWalHdr[16], pWal->hdr.aSalt, 8); |
| 42133 | walChecksumBytes(1, aWalHdr, WAL_HDRSIZE-2*4, 0, aCksum); |
| 42134 | sqlite3Put4byte(&aWalHdr[24], aCksum[0]); |
| 42135 | sqlite3Put4byte(&aWalHdr[28], aCksum[1]); |
| 42136 | |
| 42137 | pWal->szPage = (u16)szPage; |
| 42138 | pWal->hdr.bigEndCksum = SQLITE_BIGENDIAN; |
| 42139 | pWal->hdr.aFrameCksum[0] = aCksum[0]; |
| 42140 | pWal->hdr.aFrameCksum[1] = aCksum[1]; |
| 42141 | |
| 42142 | rc = sqlite3OsWrite(pWal->pWalFd, aWalHdr, sizeof(aWalHdr), 0); |
| @@ -42176,11 +42226,11 @@ | |
| 42226 | rc = walIndexAppend(pWal, iFrame, pLast->pgno); |
| 42227 | } |
| 42228 | |
| 42229 | if( rc==SQLITE_OK ){ |
| 42230 | /* Update the private copy of the header. */ |
| 42231 | pWal->hdr.szPage = (u16)szPage; |
| 42232 | pWal->hdr.mxFrame = iFrame; |
| 42233 | if( isCommit ){ |
| 42234 | pWal->hdr.iChange++; |
| 42235 | pWal->hdr.nPage = nTruncate; |
| 42236 | } |
| @@ -44913,20 +44963,24 @@ | |
| 44963 | MemPage **ppPage /* Write the page pointer here */ |
| 44964 | ){ |
| 44965 | int rc; |
| 44966 | assert( sqlite3_mutex_held(pBt->mutex) ); |
| 44967 | |
| 44968 | if( pgno>btreePagecount(pBt) ){ |
| 44969 | rc = SQLITE_CORRUPT_BKPT; |
| 44970 | }else{ |
| 44971 | rc = btreeGetPage(pBt, pgno, ppPage, 0); |
| 44972 | if( rc==SQLITE_OK ){ |
| 44973 | rc = btreeInitPage(*ppPage); |
| 44974 | if( rc!=SQLITE_OK ){ |
| 44975 | releasePage(*ppPage); |
| 44976 | } |
| 44977 | } |
| 44978 | } |
| 44979 | |
| 44980 | testcase( pgno==0 ); |
| 44981 | assert( pgno!=0 || rc==SQLITE_CORRUPT ); |
| 44982 | return rc; |
| 44983 | } |
| 44984 | |
| 44985 | /* |
| 44986 | ** Release a MemPage. This should be called once for each prior |
| @@ -45849,11 +45903,11 @@ | |
| 45903 | ** page 1. So if some other shared-cache client already has a write-lock |
| 45904 | ** on page 1, the transaction cannot be opened. */ |
| 45905 | rc = querySharedCacheTableLock(p, MASTER_ROOT, READ_LOCK); |
| 45906 | if( SQLITE_OK!=rc ) goto trans_begun; |
| 45907 | |
| 45908 | pBt->initiallyEmpty = (u8)(pBt->nPage==0); |
| 45909 | do { |
| 45910 | /* Call lockBtree() until either pBt->pPage1 is populated or |
| 45911 | ** lockBtree() returns something other than SQLITE_OK. lockBtree() |
| 45912 | ** may return SQLITE_OK but leave pBt->pPage1 set to 0 if after |
| 45913 | ** reading page 1 it discovers that the page-size of the database |
| @@ -47572,11 +47626,10 @@ | |
| 47626 | rc = moveToRoot(pCur); |
| 47627 | if( rc==SQLITE_OK ){ |
| 47628 | if( pCur->eState==CURSOR_INVALID ){ |
| 47629 | assert( pCur->apPage[pCur->iPage]->nCell==0 ); |
| 47630 | *pRes = 1; |
| 47631 | }else{ |
| 47632 | assert( pCur->apPage[pCur->iPage]->nCell>0 ); |
| 47633 | *pRes = 0; |
| 47634 | rc = moveToLeftmost(pCur); |
| 47635 | } |
| @@ -51337,11 +51390,11 @@ | |
| 51390 | assert( iVersion==1 || iVersion==2 ); |
| 51391 | |
| 51392 | /* If setting the version fields to 1, do not automatically open the |
| 51393 | ** WAL connection, even if the version fields are currently set to 2. |
| 51394 | */ |
| 51395 | pBt->doNotUseWAL = (u8)(iVersion==1); |
| 51396 | |
| 51397 | rc = sqlite3BtreeBeginTrans(pBtree, 0); |
| 51398 | if( rc==SQLITE_OK ){ |
| 51399 | u8 *aData = pBt->pPage1->aData; |
| 51400 | if( aData[18]!=(u8)iVersion || aData[19]!=(u8)iVersion ){ |
| @@ -51829,10 +51882,13 @@ | |
| 51882 | TESTONLY( rc2 = ) sqlite3BtreeCommitPhaseOne(p->pSrc, 0); |
| 51883 | TESTONLY( rc2 |= ) sqlite3BtreeCommitPhaseTwo(p->pSrc); |
| 51884 | assert( rc2==SQLITE_OK ); |
| 51885 | } |
| 51886 | |
| 51887 | if( rc==SQLITE_IOERR_NOMEM ){ |
| 51888 | rc = SQLITE_NOMEM; |
| 51889 | } |
| 51890 | p->rc = rc; |
| 51891 | } |
| 51892 | if( p->pDestDb ){ |
| 51893 | sqlite3_mutex_leave(p->pDestDb->mutex); |
| 51894 | } |
| @@ -53951,11 +54007,13 @@ | |
| 54007 | ** having to double-check to make sure that the result is non-negative. But |
| 54008 | ** if SQLITE_OMIT_TRACE is defined, the OP_Trace is omitted and we do need to |
| 54009 | ** check the value of p->nOp-1 before continuing. |
| 54010 | */ |
| 54011 | SQLITE_PRIVATE VdbeOp *sqlite3VdbeGetOp(Vdbe *p, int addr){ |
| 54012 | /* C89 specifies that the constant "dummy" will be initialized to all |
| 54013 | ** zeros, which is correct. MSVC generates a warning, nevertheless. */ |
| 54014 | static const VdbeOp dummy; /* Ignore the MSVC warning about no initializer */ |
| 54015 | assert( p->magic==VDBE_MAGIC_INIT ); |
| 54016 | if( addr<0 ){ |
| 54017 | #ifdef SQLITE_OMIT_TRACE |
| 54018 | if( p->nOp==0 ) return (VdbeOp*)&dummy; |
| 54019 | #endif |
| @@ -62382,18 +62440,17 @@ | |
| 62440 | #endif /* local variables moved into u.bl */ |
| 62441 | |
| 62442 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 62443 | u.bl.pC = p->apCsr[pOp->p1]; |
| 62444 | assert( u.bl.pC!=0 ); |
| 62445 | u.bl.res = 1; |
| 62446 | if( (u.bl.pCrsr = u.bl.pC->pCursor)!=0 ){ |
| 62447 | rc = sqlite3BtreeFirst(u.bl.pCrsr, &u.bl.res); |
| 62448 | u.bl.pC->atFirst = u.bl.res==0 ?1:0; |
| 62449 | u.bl.pC->deferredMoveto = 0; |
| 62450 | u.bl.pC->cacheStatus = CACHE_STALE; |
| 62451 | u.bl.pC->rowidIsValid = 0; |
| 62452 | } |
| 62453 | u.bl.pC->nullRow = (u8)u.bl.res; |
| 62454 | assert( pOp->p2>0 && pOp->p2<p->nOp ); |
| 62455 | if( u.bl.res ){ |
| 62456 | pc = pOp->p2 - 1; |
| @@ -63433,10 +63490,11 @@ | |
| 63490 | rc = sqlite3Checkpoint(db, pOp->p1); |
| 63491 | break; |
| 63492 | }; |
| 63493 | #endif |
| 63494 | |
| 63495 | #ifndef SQLITE_OMIT_PRAGMA |
| 63496 | /* Opcode: JournalMode P1 P2 P3 * P5 |
| 63497 | ** |
| 63498 | ** Change the journal mode of database P1 to P3. P3 must be one of the |
| 63499 | ** PAGER_JOURNALMODE_XXX values. If changing between the various rollback |
| 63500 | ** modes (delete, truncate, persist, off and memory), this is a simple |
| @@ -63559,11 +63617,12 @@ | |
| 63617 | pOut->z = (char *)sqlite3JournalModename(u.cd.eNew); |
| 63618 | pOut->n = sqlite3Strlen30(pOut->z); |
| 63619 | pOut->enc = SQLITE_UTF8; |
| 63620 | sqlite3VdbeChangeEncoding(pOut, encoding); |
| 63621 | break; |
| 63622 | }; |
| 63623 | #endif /* SQLITE_OMIT_PRAGMA */ |
| 63624 | |
| 63625 | #if !defined(SQLITE_OMIT_VACUUM) && !defined(SQLITE_OMIT_ATTACH) |
| 63626 | /* Opcode: Vacuum * * * * * |
| 63627 | ** |
| 63628 | ** Vacuum the entire database. This opcode will cause other virtual |
| @@ -64743,11 +64802,16 @@ | |
| 64802 | 0, /* xLock */ |
| 64803 | 0, /* xUnlock */ |
| 64804 | 0, /* xCheckReservedLock */ |
| 64805 | 0, /* xFileControl */ |
| 64806 | 0, /* xSectorSize */ |
| 64807 | 0, /* xDeviceCharacteristics */ |
| 64808 | 0, /* xShmOpen */ |
| 64809 | 0, /* xShmLock */ |
| 64810 | 0, /* xShmMap */ |
| 64811 | 0, /* xShmBarrier */ |
| 64812 | 0 /* xShmClose */ |
| 64813 | }; |
| 64814 | |
| 64815 | /* |
| 64816 | ** Open a journal file. |
| 64817 | */ |
| @@ -65023,11 +65087,16 @@ | |
| 65087 | 0, /* xLock */ |
| 65088 | 0, /* xUnlock */ |
| 65089 | 0, /* xCheckReservedLock */ |
| 65090 | 0, /* xFileControl */ |
| 65091 | 0, /* xSectorSize */ |
| 65092 | 0, /* xDeviceCharacteristics */ |
| 65093 | 0, /* xShmOpen */ |
| 65094 | 0, /* xShmLock */ |
| 65095 | 0, /* xShmMap */ |
| 65096 | 0, /* xShmBarrier */ |
| 65097 | 0 /* xShmClose */ |
| 65098 | }; |
| 65099 | |
| 65100 | /* |
| 65101 | ** Open a journal file. |
| 65102 | */ |
| @@ -65546,10 +65615,11 @@ | |
| 65615 | }else if( zTab ){ |
| 65616 | sqlite3ErrorMsg(pParse, "%s: %s.%s", zErr, zTab, zCol); |
| 65617 | }else{ |
| 65618 | sqlite3ErrorMsg(pParse, "%s: %s", zErr, zCol); |
| 65619 | } |
| 65620 | pParse->checkSchema = 1; |
| 65621 | pTopNC->nErr++; |
| 65622 | } |
| 65623 | |
| 65624 | /* If a column from a table in pSrcList is referenced, then record |
| 65625 | ** this fact in the pSrcList.a[].colUsed bitmask. Column 0 causes |
| @@ -75035,10 +75105,11 @@ | |
| 75105 | if( sqlite3StrICmp(zColName, pTabCol->zName)==0 ) break; |
| 75106 | } |
| 75107 | if( j>=pTab->nCol ){ |
| 75108 | sqlite3ErrorMsg(pParse, "table %s has no column named %s", |
| 75109 | pTab->zName, zColName); |
| 75110 | pParse->checkSchema = 1; |
| 75111 | goto exit_create_index; |
| 75112 | } |
| 75113 | pIndex->aiColumn[i] = j; |
| 75114 | /* Justification of the ALWAYS(pListItem->pExpr->pColl): Because of |
| 75115 | ** the way the "idxlist" non-terminal is constructed by the parser, |
| @@ -80735,11 +80806,11 @@ | |
| 80806 | if( sqlite3IsRowid(pColumn->a[i].zName) ){ |
| 80807 | keyColumn = i; |
| 80808 | }else{ |
| 80809 | sqlite3ErrorMsg(pParse, "table %S has no column named %s", |
| 80810 | pTabList, 0, pColumn->a[i].zName); |
| 80811 | pParse->checkSchema = 1; |
| 80812 | goto insert_cleanup; |
| 80813 | } |
| 80814 | } |
| 80815 | } |
| 80816 | } |
| @@ -88382,10 +88453,11 @@ | |
| 88453 | pIdx && sqlite3StrICmp(pIdx->zName, zIndex); |
| 88454 | pIdx=pIdx->pNext |
| 88455 | ); |
| 88456 | if( !pIdx ){ |
| 88457 | sqlite3ErrorMsg(pParse, "no such index: %s", zIndex, 0); |
| 88458 | pParse->checkSchema = 1; |
| 88459 | return SQLITE_ERROR; |
| 88460 | } |
| 88461 | pFrom->pIndex = pIdx; |
| 88462 | } |
| 88463 | return SQLITE_OK; |
| @@ -90367,10 +90439,11 @@ | |
| 90439 | } |
| 90440 | if( !pTrigger ){ |
| 90441 | if( !noErr ){ |
| 90442 | sqlite3ErrorMsg(pParse, "no such trigger: %S", pName, 0); |
| 90443 | } |
| 90444 | pParse->checkSchema = 1; |
| 90445 | goto drop_trigger_cleanup; |
| 90446 | } |
| 90447 | sqlite3DropTriggerPtr(pParse, pTrigger); |
| 90448 | |
| 90449 | drop_trigger_cleanup: |
| @@ -91177,10 +91250,11 @@ | |
| 91250 | if( sqlite3IsRowid(pChanges->a[i].zName) ){ |
| 91251 | chngRowid = 1; |
| 91252 | pRowidExpr = pChanges->a[i].pExpr; |
| 91253 | }else{ |
| 91254 | sqlite3ErrorMsg(pParse, "no such column: %s", pChanges->a[i].zName); |
| 91255 | pParse->checkSchema = 1; |
| 91256 | goto update_cleanup; |
| 91257 | } |
| 91258 | } |
| 91259 | #ifndef SQLITE_OMIT_AUTHORIZATION |
| 91260 | { |
| @@ -94755,11 +94829,11 @@ | |
| 94829 | pIdx->azColl[n] = pColl->zName; |
| 94830 | n++; |
| 94831 | } |
| 94832 | } |
| 94833 | } |
| 94834 | assert( (u32)n==pLevel->plan.nEq ); |
| 94835 | |
| 94836 | /* Add additional columns needed to make the automatic index into |
| 94837 | ** a covering index */ |
| 94838 | for(i=0; i<mxBitCol; i++){ |
| 94839 | if( extraCols & (((Bitmask)1)<<i) ){ |
| @@ -96349,11 +96423,11 @@ | |
| 96423 | |
| 96424 | /* If we are doing a reverse order scan on an ascending index, or |
| 96425 | ** a forward order scan on a descending index, interchange the |
| 96426 | ** start and end terms (pRangeStart and pRangeEnd). |
| 96427 | */ |
| 96428 | if( nEq<pIdx->nColumn && bRev==(pIdx->aSortOrder[nEq]==SQLITE_SO_ASC) ){ |
| 96429 | SWAP(WhereTerm *, pRangeEnd, pRangeStart); |
| 96430 | } |
| 96431 | |
| 96432 | testcase( pRangeStart && pRangeStart->eOperator & WO_LE ); |
| 96433 | testcase( pRangeStart && pRangeStart->eOperator & WO_GE ); |
| @@ -106034,10 +106108,13 @@ | |
| 106108 | |
| 106109 | /* |
| 106110 | ** An sqlite3_exec() callback for fts3TableExists. |
| 106111 | */ |
| 106112 | static int fts3TableExistsCallback(void *pArg, int n, char **pp1, char **pp2){ |
| 106113 | UNUSED_PARAMETER(n); |
| 106114 | UNUSED_PARAMETER(pp1); |
| 106115 | UNUSED_PARAMETER(pp2); |
| 106116 | *(int*)pArg = 1; |
| 106117 | return 1; |
| 106118 | } |
| 106119 | |
| 106120 | /* |
| @@ -106059,11 +106136,11 @@ | |
| 106136 | "SELECT 1 FROM %Q.sqlite_master WHERE name='%q%s'", |
| 106137 | zDb, zName, zSuffix |
| 106138 | ); |
| 106139 | rc = sqlite3_exec(db, zSql, fts3TableExistsCallback, &res, 0); |
| 106140 | sqlite3_free(zSql); |
| 106141 | *pResult = (u8)(res & 0xff); |
| 106142 | if( rc!=SQLITE_ABORT ) *pRc = rc; |
| 106143 | } |
| 106144 | |
| 106145 | /* |
| 106146 | ** This function is the implementation of both the xConnect and xCreate |
| 106147 |
+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-26 20:25:31 f149b498b6ada3fc9f71ee104c351554c80c7f8a" | |
| 112 | +#define SQLITE_SOURCE_ID "2010-07-03 13:59:01 3b20ad03be55613d922d81aec5313327bf4098b9" | |
| 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-26 20:25:31 f149b498b6ada3fc9f71ee104c351554c80c7f8a" |
| 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-07-03 13:59:01 3b20ad03be55613d922d81aec5313327bf4098b9" |
| 113 | |
| 114 | /* |
| 115 | ** CAPI3REF: Run-Time Library Version Numbers |
| 116 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 117 | ** |
| 118 |