|
|
@@ -676,7 +676,7 @@ extern "C" {
|
|
|
*/
|
|
|
#define SQLITE_VERSION "3.7.16"
|
|
|
#define SQLITE_VERSION_NUMBER 3007016
|
|
|
-#define SQLITE_SOURCE_ID "2013-03-01 21:01:05 f476eace86102fd5442cfbba169c18f6ee44eae2"
|
|
|
+#define SQLITE_SOURCE_ID "2013-03-05 16:54:45 4e6e07a60e543d5d1727cde27ab11e156202a1b8"
|
|
|
|
|
|
/*
|
|
|
** CAPI3REF: Run-Time Library Version Numbers
|
|
|
@@ -1060,6 +1060,7 @@ SQLITE_API int sqlite3_exec(
|
|
|
#define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8))
|
|
|
#define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8))
|
|
|
#define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8))
|
|
|
+#define SQLITE_READONLY_ROLLBACK (SQLITE_READONLY | (3<<8))
|
|
|
#define SQLITE_ABORT_ROLLBACK (SQLITE_ABORT | (2<<8))
|
|
|
#define SQLITE_CONSTRAINT_CHECK (SQLITE_CONSTRAINT | (1<<8))
|
|
|
#define SQLITE_CONSTRAINT_COMMITHOOK (SQLITE_CONSTRAINT | (2<<8))
|
|
|
@@ -23644,7 +23645,10 @@ static int robust_open(const char *z, int f, mode_t m){
|
|
|
if( fd>=0 ){
|
|
|
if( m!=0 ){
|
|
|
struct stat statbuf;
|
|
|
- if( osFstat(fd, &statbuf)==0 && (statbuf.st_mode&0777)!=m ){
|
|
|
+ if( osFstat(fd, &statbuf)==0
|
|
|
+ && statbuf.st_size==0
|
|
|
+ && statbuf.st_mode&0777!=m
|
|
|
+ ){
|
|
|
osFchmod(fd, m);
|
|
|
}
|
|
|
}
|
|
|
@@ -32162,7 +32166,8 @@ static BOOL winceLockFile(
|
|
|
}
|
|
|
|
|
|
/* Want a pending lock? */
|
|
|
- else if (dwFileOffsetLow == (DWORD)PENDING_BYTE && nNumberOfBytesToLockLow == 1){
|
|
|
+ else if (dwFileOffsetLow == (DWORD)PENDING_BYTE
|
|
|
+ && nNumberOfBytesToLockLow == 1){
|
|
|
/* If no pending lock has been acquired, then acquire it */
|
|
|
if (pFile->shared->bPending == 0) {
|
|
|
pFile->shared->bPending = TRUE;
|
|
|
@@ -32172,7 +32177,8 @@ static BOOL winceLockFile(
|
|
|
}
|
|
|
|
|
|
/* Want a reserved lock? */
|
|
|
- else if (dwFileOffsetLow == (DWORD)RESERVED_BYTE && nNumberOfBytesToLockLow == 1){
|
|
|
+ else if (dwFileOffsetLow == (DWORD)RESERVED_BYTE
|
|
|
+ && nNumberOfBytesToLockLow == 1){
|
|
|
if (pFile->shared->bReserved == 0) {
|
|
|
pFile->shared->bReserved = TRUE;
|
|
|
pFile->local.bReserved = TRUE;
|
|
|
@@ -32215,7 +32221,8 @@ static BOOL winceUnlockFile(
|
|
|
|
|
|
/* Did we just have a reader lock? */
|
|
|
else if (pFile->local.nReaders){
|
|
|
- assert(nNumberOfBytesToUnlockLow == (DWORD)SHARED_SIZE || nNumberOfBytesToUnlockLow == 1);
|
|
|
+ assert(nNumberOfBytesToUnlockLow == (DWORD)SHARED_SIZE
|
|
|
+ || nNumberOfBytesToUnlockLow == 1);
|
|
|
pFile->local.nReaders --;
|
|
|
if (pFile->local.nReaders == 0)
|
|
|
{
|
|
|
@@ -32226,7 +32233,8 @@ static BOOL winceUnlockFile(
|
|
|
}
|
|
|
|
|
|
/* Releasing a pending lock */
|
|
|
- else if (dwFileOffsetLow == (DWORD)PENDING_BYTE && nNumberOfBytesToUnlockLow == 1){
|
|
|
+ else if (dwFileOffsetLow == (DWORD)PENDING_BYTE
|
|
|
+ && nNumberOfBytesToUnlockLow == 1){
|
|
|
if (pFile->local.bPending){
|
|
|
pFile->local.bPending = FALSE;
|
|
|
pFile->shared->bPending = FALSE;
|
|
|
@@ -32234,7 +32242,8 @@ static BOOL winceUnlockFile(
|
|
|
}
|
|
|
}
|
|
|
/* Releasing a reserved lock */
|
|
|
- else if (dwFileOffsetLow == (DWORD)RESERVED_BYTE && nNumberOfBytesToUnlockLow == 1){
|
|
|
+ else if (dwFileOffsetLow == (DWORD)RESERVED_BYTE
|
|
|
+ && nNumberOfBytesToUnlockLow == 1){
|
|
|
if (pFile->local.bReserved) {
|
|
|
pFile->local.bReserved = FALSE;
|
|
|
pFile->shared->bReserved = FALSE;
|
|
|
@@ -33397,7 +33406,7 @@ static int winOpenSharedMemory(winFile *pDbFd){
|
|
|
rc = winOpen(pDbFd->pVfs,
|
|
|
pShmNode->zFilename, /* Name of the file (UTF-8) */
|
|
|
(sqlite3_file*)&pShmNode->hFile, /* File handle here */
|
|
|
- SQLITE_OPEN_WAL | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, /* Mode flags */
|
|
|
+ SQLITE_OPEN_WAL | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
|
|
|
0);
|
|
|
if( SQLITE_OK!=rc ){
|
|
|
goto shm_open_err;
|
|
|
@@ -34151,7 +34160,9 @@ static int winOpen(
|
|
|
sqlite3_free(zConverted);
|
|
|
if( isReadWrite && !isExclusive ){
|
|
|
return winOpen(pVfs, zName, id,
|
|
|
- ((flags|SQLITE_OPEN_READONLY)&~(SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE)), pOutFlags);
|
|
|
+ ((flags|SQLITE_OPEN_READONLY) &
|
|
|
+ ~(SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE)),
|
|
|
+ pOutFlags);
|
|
|
}else{
|
|
|
return SQLITE_CANTOPEN_BKPT;
|
|
|
}
|
|
|
@@ -34234,7 +34245,8 @@ static int winDelete(
|
|
|
attr = sAttrData.dwFileAttributes;
|
|
|
}else{
|
|
|
lastErrno = osGetLastError();
|
|
|
- if( lastErrno==ERROR_FILE_NOT_FOUND || lastErrno==ERROR_PATH_NOT_FOUND ){
|
|
|
+ if( lastErrno==ERROR_FILE_NOT_FOUND
|
|
|
+ || lastErrno==ERROR_PATH_NOT_FOUND ){
|
|
|
rc = SQLITE_IOERR_DELETE_NOENT; /* Already gone? */
|
|
|
}else{
|
|
|
rc = SQLITE_ERROR;
|
|
|
@@ -34246,7 +34258,8 @@ static int winDelete(
|
|
|
#endif
|
|
|
if ( attr==INVALID_FILE_ATTRIBUTES ){
|
|
|
lastErrno = osGetLastError();
|
|
|
- if( lastErrno==ERROR_FILE_NOT_FOUND || lastErrno==ERROR_PATH_NOT_FOUND ){
|
|
|
+ if( lastErrno==ERROR_FILE_NOT_FOUND
|
|
|
+ || lastErrno==ERROR_PATH_NOT_FOUND ){
|
|
|
rc = SQLITE_IOERR_DELETE_NOENT; /* Already gone? */
|
|
|
}else{
|
|
|
rc = SQLITE_ERROR;
|
|
|
@@ -34273,7 +34286,8 @@ static int winDelete(
|
|
|
attr = osGetFileAttributesA(zConverted);
|
|
|
if ( attr==INVALID_FILE_ATTRIBUTES ){
|
|
|
lastErrno = osGetLastError();
|
|
|
- if( lastErrno==ERROR_FILE_NOT_FOUND || lastErrno==ERROR_PATH_NOT_FOUND ){
|
|
|
+ if( lastErrno==ERROR_FILE_NOT_FOUND
|
|
|
+ || lastErrno==ERROR_PATH_NOT_FOUND ){
|
|
|
rc = SQLITE_IOERR_DELETE_NOENT; /* Already gone? */
|
|
|
}else{
|
|
|
rc = SQLITE_ERROR;
|
|
|
@@ -34441,16 +34455,12 @@ static int winFullPathname(
|
|
|
*/
|
|
|
char zOut[MAX_PATH+1];
|
|
|
memset(zOut, 0, MAX_PATH+1);
|
|
|
- cygwin_conv_to_win32_path(zRelative, zOut); /* POSIX to Win32 */
|
|
|
+ cygwin_conv_path(CCP_POSIX_TO_WIN_A|CCP_RELATIVE, zRelative, zOut,
|
|
|
+ MAX_PATH+1);
|
|
|
sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s\\%s",
|
|
|
sqlite3_data_directory, zOut);
|
|
|
}else{
|
|
|
- /*
|
|
|
- ** NOTE: The Cygwin docs state that the maximum length needed
|
|
|
- ** for the buffer passed to cygwin_conv_to_full_win32_path
|
|
|
- ** is MAX_PATH.
|
|
|
- */
|
|
|
- cygwin_conv_to_full_win32_path(zRelative, zFull);
|
|
|
+ cygwin_conv_path(CCP_POSIX_TO_WIN_A, zRelative, zFull, nFull);
|
|
|
}
|
|
|
return SQLITE_OK;
|
|
|
#endif
|
|
|
@@ -34608,9 +34618,9 @@ static void winDlError(sqlite3_vfs *pVfs, int nBuf, char *zBufOut){
|
|
|
UNUSED_PARAMETER(pVfs);
|
|
|
getLastErrorMsg(osGetLastError(), nBuf, zBufOut);
|
|
|
}
|
|
|
-static void (*winDlSym(sqlite3_vfs *pVfs, void *pHandle, const char *zSymbol))(void){
|
|
|
+static void (*winDlSym(sqlite3_vfs *pVfs,void *pH,const char *zSym))(void){
|
|
|
UNUSED_PARAMETER(pVfs);
|
|
|
- return (void(*)(void))osGetProcAddressA((HANDLE)pHandle, zSymbol);
|
|
|
+ return (void(*)(void))osGetProcAddressA((HANDLE)pH, zSym);
|
|
|
}
|
|
|
static void winDlClose(sqlite3_vfs *pVfs, void *pHandle){
|
|
|
UNUSED_PARAMETER(pVfs);
|
|
|
@@ -34708,7 +34718,8 @@ static int winCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *piNow){
|
|
|
#endif
|
|
|
/* 2^32 - to avoid use of LL and warnings in gcc */
|
|
|
static const sqlite3_int64 max32BitValue =
|
|
|
- (sqlite3_int64)2000000000 + (sqlite3_int64)2000000000 + (sqlite3_int64)294967296;
|
|
|
+ (sqlite3_int64)2000000000 + (sqlite3_int64)2000000000 +
|
|
|
+ (sqlite3_int64)294967296;
|
|
|
|
|
|
#if SQLITE_OS_WINCE
|
|
|
SYSTEMTIME time;
|
|
|
@@ -41303,12 +41314,26 @@ static void assertTruncateConstraint(Pager *pPager){
|
|
|
** function does not actually modify the database file on disk. It
|
|
|
** just sets the internal state of the pager object so that the
|
|
|
** truncation will be done when the current transaction is committed.
|
|
|
+**
|
|
|
+** This function is only called right before committing a transaction.
|
|
|
+** Once this function has been called, the transaction must either be
|
|
|
+** rolled back or committed. It is not safe to call this function and
|
|
|
+** then continue writing to the database.
|
|
|
*/
|
|
|
SQLITE_PRIVATE void sqlite3PagerTruncateImage(Pager *pPager, Pgno nPage){
|
|
|
assert( pPager->dbSize>=nPage );
|
|
|
assert( pPager->eState>=PAGER_WRITER_CACHEMOD );
|
|
|
pPager->dbSize = nPage;
|
|
|
- assertTruncateConstraint(pPager);
|
|
|
+
|
|
|
+ /* At one point the code here called assertTruncateConstraint() to
|
|
|
+ ** ensure that all pages being truncated away by this operation are,
|
|
|
+ ** if one or more savepoints are open, present in the savepoint
|
|
|
+ ** journal so that they can be restored if the savepoint is rolled
|
|
|
+ ** back. This is no longer necessary as this function is now only
|
|
|
+ ** called right before committing a transaction. So although the
|
|
|
+ ** Pager object may still have open savepoints (Pager.nSavepoint!=0),
|
|
|
+ ** they cannot be rolled back. So the assertTruncateConstraint() call
|
|
|
+ ** is no longer correct. */
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -42361,6 +42386,11 @@ SQLITE_PRIVATE int sqlite3PagerSharedLock(Pager *pPager){
|
|
|
goto failed;
|
|
|
}
|
|
|
if( bHotJournal ){
|
|
|
+ if( pPager->readOnly ){
|
|
|
+ rc = SQLITE_READONLY_ROLLBACK;
|
|
|
+ goto failed;
|
|
|
+ }
|
|
|
+
|
|
|
/* Get an EXCLUSIVE lock on the database file. At this point it is
|
|
|
** important that a RESERVED lock is not obtained on the way to the
|
|
|
** EXCLUSIVE lock. If it were, another process might open the
|
|
|
@@ -51532,7 +51562,7 @@ static int incrVacuumStep(BtShared *pBt, Pgno nFin, Pgno iLastPg, int bCommit){
|
|
|
}while( bCommit && iFreePg>nFin );
|
|
|
assert( iFreePg<iLastPg );
|
|
|
|
|
|
- rc = relocatePage(pBt, pLastPg, eType, iPtrPage, iFreePg, nFin!=0);
|
|
|
+ rc = relocatePage(pBt, pLastPg, eType, iPtrPage, iFreePg, bCommit);
|
|
|
releasePage(pLastPg);
|
|
|
if( rc!=SQLITE_OK ){
|
|
|
return rc;
|
|
|
@@ -53403,21 +53433,23 @@ SQLITE_PRIVATE int sqlite3BtreePrevious(BtCursor *pCur, int *pRes){
|
|
|
** an error. *ppPage and *pPgno are undefined in the event of an error.
|
|
|
** Do not invoke sqlite3PagerUnref() on *ppPage if an error is returned.
|
|
|
**
|
|
|
-** If the "nearby" parameter is not 0, then a (feeble) effort is made to
|
|
|
+** If the "nearby" parameter is not 0, then an effort is made to
|
|
|
** locate a page close to the page number "nearby". This can be used in an
|
|
|
** attempt to keep related pages close to each other in the database file,
|
|
|
** which in turn can make database access faster.
|
|
|
**
|
|
|
-** If the "exact" parameter is not 0, and the page-number nearby exists
|
|
|
-** anywhere on the free-list, then it is guarenteed to be returned. This
|
|
|
-** is only used by auto-vacuum databases when allocating a new table.
|
|
|
+** If the eMode parameter is BTALLOC_EXACT and the nearby page exists
|
|
|
+** anywhere on the free-list, then it is guaranteed to be returned. If
|
|
|
+** eMode is BTALLOC_LT then the page returned will be less than or equal
|
|
|
+** to nearby if any such page exists. If eMode is BTALLOC_ANY then there
|
|
|
+** are no restrictions on which page is returned.
|
|
|
*/
|
|
|
static int allocateBtreePage(
|
|
|
- BtShared *pBt,
|
|
|
- MemPage **ppPage,
|
|
|
- Pgno *pPgno,
|
|
|
- Pgno nearby,
|
|
|
- u8 eMode
|
|
|
+ BtShared *pBt, /* The btree */
|
|
|
+ MemPage **ppPage, /* Store pointer to the allocated page here */
|
|
|
+ Pgno *pPgno, /* Store the page number here */
|
|
|
+ Pgno nearby, /* Search for a page near this one */
|
|
|
+ u8 eMode /* BTALLOC_EXACT, BTALLOC_LT, or BTALLOC_ANY */
|
|
|
){
|
|
|
MemPage *pPage1;
|
|
|
int rc;
|
|
|
@@ -53428,6 +53460,7 @@ static int allocateBtreePage(
|
|
|
Pgno mxPage; /* Total size of the database file */
|
|
|
|
|
|
assert( sqlite3_mutex_held(pBt->mutex) );
|
|
|
+ assert( eMode==BTALLOC_ANY || (nearby>0 && pBt->autoVacuum) );
|
|
|
pPage1 = pBt->pPage1;
|
|
|
mxPage = btreePagecount(pBt);
|
|
|
n = get4byte(&pPage1->aData[36]);
|
|
|
@@ -53440,7 +53473,7 @@ static int allocateBtreePage(
|
|
|
Pgno iTrunk;
|
|
|
u8 searchList = 0; /* If the free-list must be searched for 'nearby' */
|
|
|
|
|
|
- /* If the 'exact' parameter was true and a query of the pointer-map
|
|
|
+ /* If eMode==BTALLOC_EXACT and a query of the pointer-map
|
|
|
** shows that the page 'nearby' is somewhere on the free-list, then
|
|
|
** the entire-list will be searched for that page.
|
|
|
*/
|
|
|
@@ -53470,7 +53503,8 @@ static int allocateBtreePage(
|
|
|
|
|
|
/* The code within this loop is run only once if the 'searchList' variable
|
|
|
** is not true. Otherwise, it runs once for each trunk-page on the
|
|
|
- ** free-list until the page 'nearby' is located.
|
|
|
+ ** free-list until the page 'nearby' is located (eMode==BTALLOC_EXACT)
|
|
|
+ ** or until a page less than 'nearby' is located (eMode==BTALLOC_LT)
|
|
|
*/
|
|
|
do {
|
|
|
pPrevTrunk = pTrunk;
|
|
|
@@ -87099,6 +87133,7 @@ static void unicodeFunc(
|
|
|
sqlite3_value **argv
|
|
|
){
|
|
|
const unsigned char *z = sqlite3_value_text(argv[0]);
|
|
|
+ (void)argc;
|
|
|
if( z && z[0] ) sqlite3_result_int(context, sqlite3Utf8Read(&z));
|
|
|
}
|
|
|
|
|
|
@@ -91981,6 +92016,19 @@ static const sqlite3_api_routines sqlite3Apis = {
|
|
|
sqlite3_blob_reopen,
|
|
|
sqlite3_vtab_config,
|
|
|
sqlite3_vtab_on_conflict,
|
|
|
+ sqlite3_close_v2,
|
|
|
+ sqlite3_db_filename,
|
|
|
+ sqlite3_db_readonly,
|
|
|
+ sqlite3_db_release_memory,
|
|
|
+ sqlite3_errstr,
|
|
|
+ sqlite3_stmt_busy,
|
|
|
+ sqlite3_stmt_readonly,
|
|
|
+ sqlite3_stricmp,
|
|
|
+ sqlite3_uri_boolean,
|
|
|
+ sqlite3_uri_int64,
|
|
|
+ sqlite3_uri_parameter,
|
|
|
+ sqlite3_vsnprintf,
|
|
|
+ sqlite3_wal_checkpoint_v2
|
|
|
};
|
|
|
|
|
|
/*
|
|
|
@@ -114241,7 +114289,7 @@ static int alphanumCollatingFunc(
|
|
|
int nKey2, const void *pKey2
|
|
|
){
|
|
|
int r = strnatncmp(
|
|
|
- (const char *)pKey1, (const char *)pKey2, (nKey1<nKey2)?nKey1:nKey2, (int)fold_case);
|
|
|
+ (const char *)pKey1, (const char *)pKey2, (nKey1<nKey2)?nKey1:nKey2, (fold_case != 0));
|
|
|
if( 0==r ){
|
|
|
r = nKey1-nKey2;
|
|
|
}
|