| | @@ -509,10 +509,17 @@ |
| 509 | 509 | #else |
| 510 | 510 | # define ALWAYS(X) (X) |
| 511 | 511 | # define NEVER(X) (X) |
| 512 | 512 | #endif |
| 513 | 513 | |
| 514 | +/* |
| 515 | +** Return true (non-zero) if the input is a integer that is too large |
| 516 | +** to fit in 32-bits. This macro is used inside of various testcase() |
| 517 | +** macros to verify that we have tested SQLite for large-file support. |
| 518 | +*/ |
| 519 | +#define IS_BIG_INT(X) (((X)&(i64)0xffffffff)!=0) |
| 520 | + |
| 514 | 521 | /* |
| 515 | 522 | ** The macro unlikely() is a hint that surrounds a boolean |
| 516 | 523 | ** expression that is usually false. Macro likely() surrounds |
| 517 | 524 | ** a boolean expression that is usually true. GCC is able to |
| 518 | 525 | ** use these hints to generate better code, sometimes. |
| | @@ -636,11 +643,11 @@ |
| 636 | 643 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 637 | 644 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 638 | 645 | */ |
| 639 | 646 | #define SQLITE_VERSION "3.7.0" |
| 640 | 647 | #define SQLITE_VERSION_NUMBER 3007000 |
| 641 | | -#define SQLITE_SOURCE_ID "2010-07-03 13:59:01 3b20ad03be55613d922d81aec5313327bf4098b9" |
| 648 | +#define SQLITE_SOURCE_ID "2010-07-08 17:40:38 e396184cd3bdb96e29ac33af5d1f631cac553341" |
| 642 | 649 | |
| 643 | 650 | /* |
| 644 | 651 | ** CAPI3REF: Run-Time Library Version Numbers |
| 645 | 652 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 646 | 653 | ** |
| | @@ -1359,20 +1366,27 @@ |
| 1359 | 1366 | ** is also passed as a parameter to both methods. If the output buffer |
| 1360 | 1367 | ** is not large enough, [SQLITE_CANTOPEN] should be returned. Since this is |
| 1361 | 1368 | ** handled as a fatal error by SQLite, vfs implementations should endeavor |
| 1362 | 1369 | ** to prevent this by setting mxPathname to a sufficiently large value. |
| 1363 | 1370 | ** |
| 1364 | | -** The xRandomness(), xSleep(), and xCurrentTime() interfaces |
| 1365 | | -** are not strictly a part of the filesystem, but they are |
| 1371 | +** The xRandomness(), xSleep(), xCurrentTime(), and xCurrentTimeInt64() |
| 1372 | +** interfaces are not strictly a part of the filesystem, but they are |
| 1366 | 1373 | ** included in the VFS structure for completeness. |
| 1367 | 1374 | ** The xRandomness() function attempts to return nBytes bytes |
| 1368 | 1375 | ** of good-quality randomness into zOut. The return value is |
| 1369 | 1376 | ** the actual number of bytes of randomness obtained. |
| 1370 | 1377 | ** The xSleep() method causes the calling thread to sleep for at |
| 1371 | 1378 | ** least the number of microseconds given. The xCurrentTime() |
| 1372 | | -** method returns a Julian Day Number for the current date and time. |
| 1373 | | -** |
| 1379 | +** method returns a Julian Day Number for the current date and time as |
| 1380 | +** a floating point value. |
| 1381 | +** The xCurrentTimeInt64() method returns, as an integer, the Julian |
| 1382 | +** Day Number multipled by 86400000 (the number of milliseconds in |
| 1383 | +** a 24-hour day). |
| 1384 | +** ^SQLite will use the xCurrentTimeInt64() method to get the current |
| 1385 | +** date and time if that method is available (if iVersion is 2 or |
| 1386 | +** greater and the function pointer is not NULL) and will fall back |
| 1387 | +** to xCurrentTime() if xCurrentTimeInt64() is unavailable. |
| 1374 | 1388 | */ |
| 1375 | 1389 | typedef struct sqlite3_vfs sqlite3_vfs; |
| 1376 | 1390 | struct sqlite3_vfs { |
| 1377 | 1391 | int iVersion; /* Structure version number (currently 2) */ |
| 1378 | 1392 | int szOsFile; /* Size of subclassed sqlite3_file */ |
| | @@ -1395,11 +1409,10 @@ |
| 1395 | 1409 | int (*xGetLastError)(sqlite3_vfs*, int, char *); |
| 1396 | 1410 | /* |
| 1397 | 1411 | ** The methods above are in version 1 of the sqlite_vfs object |
| 1398 | 1412 | ** definition. Those that follow are added in version 2 or later |
| 1399 | 1413 | */ |
| 1400 | | - int (*xRename)(sqlite3_vfs*, const char *zOld, const char *zNew, int dirSync); |
| 1401 | 1414 | int (*xCurrentTimeInt64)(sqlite3_vfs*, sqlite3_int64*); |
| 1402 | 1415 | /* |
| 1403 | 1416 | ** The methods above are in versions 1 and 2 of the sqlite_vfs object. |
| 1404 | 1417 | ** New fields may be appended in figure versions. The iVersion |
| 1405 | 1418 | ** value will increment whenever this happens. |
| | @@ -8559,11 +8572,10 @@ |
| 8559 | 8572 | int errMask; /* & result codes with this before returning */ |
| 8560 | 8573 | u8 autoCommit; /* The auto-commit flag. */ |
| 8561 | 8574 | u8 temp_store; /* 1: file 2: memory 0: default */ |
| 8562 | 8575 | u8 mallocFailed; /* True if we have seen a malloc failure */ |
| 8563 | 8576 | u8 dfltLockMode; /* Default locking-mode for attached dbs */ |
| 8564 | | - u8 dfltJournalMode; /* Default journal mode for attached dbs */ |
| 8565 | 8577 | signed char nextAutovac; /* Autovac setting after VACUUM if >=0 */ |
| 8566 | 8578 | u8 suppressErr; /* Do not issue error messages if true */ |
| 8567 | 8579 | int nextPagesize; /* Pagesize after VACUUM if >0 */ |
| 8568 | 8580 | int nTable; /* Number of tables in the database */ |
| 8569 | 8581 | CollSeq *pDfltColl; /* The default collating sequence (BINARY) */ |
| | @@ -11327,13 +11339,15 @@ |
| 11327 | 11339 | "OMIT_CAST", |
| 11328 | 11340 | #endif |
| 11329 | 11341 | #ifdef SQLITE_OMIT_CHECK |
| 11330 | 11342 | "OMIT_CHECK", |
| 11331 | 11343 | #endif |
| 11332 | | -#ifdef SQLITE_OMIT_COMPILEOPTION_DIAGS |
| 11333 | | - "OMIT_COMPILEOPTION_DIAGS", |
| 11334 | | -#endif |
| 11344 | +/* // redundant |
| 11345 | +** #ifdef SQLITE_OMIT_COMPILEOPTION_DIAGS |
| 11346 | +** "OMIT_COMPILEOPTION_DIAGS", |
| 11347 | +** #endif |
| 11348 | +*/ |
| 11335 | 11349 | #ifdef SQLITE_OMIT_COMPLETE |
| 11336 | 11350 | "OMIT_COMPLETE", |
| 11337 | 11351 | #endif |
| 11338 | 11352 | #ifdef SQLITE_OMIT_COMPOUND_SELECT |
| 11339 | 11353 | "OMIT_COMPOUND_SELECT", |
| | @@ -11363,13 +11377,10 @@ |
| 11363 | 11377 | "OMIT_FOREIGN_KEY", |
| 11364 | 11378 | #endif |
| 11365 | 11379 | #ifdef SQLITE_OMIT_GET_TABLE |
| 11366 | 11380 | "OMIT_GET_TABLE", |
| 11367 | 11381 | #endif |
| 11368 | | -#ifdef SQLITE_OMIT_GLOBALRECOVER |
| 11369 | | - "OMIT_GLOBALRECOVER", |
| 11370 | | -#endif |
| 11371 | 11382 | #ifdef SQLITE_OMIT_INCRBLOB |
| 11372 | 11383 | "OMIT_INCRBLOB", |
| 11373 | 11384 | #endif |
| 11374 | 11385 | #ifdef SQLITE_OMIT_INTEGRITY_CHECK |
| 11375 | 11386 | "OMIT_INTEGRITY_CHECK", |
| | @@ -11443,10 +11454,13 @@ |
| 11443 | 11454 | #ifdef SQLITE_OMIT_VIEW |
| 11444 | 11455 | "OMIT_VIEW", |
| 11445 | 11456 | #endif |
| 11446 | 11457 | #ifdef SQLITE_OMIT_VIRTUALTABLE |
| 11447 | 11458 | "OMIT_VIRTUALTABLE", |
| 11459 | +#endif |
| 11460 | +#ifdef SQLITE_OMIT_WAL |
| 11461 | + "OMIT_WAL", |
| 11448 | 11462 | #endif |
| 11449 | 11463 | #ifdef SQLITE_OMIT_WSD |
| 11450 | 11464 | "OMIT_WSD", |
| 11451 | 11465 | #endif |
| 11452 | 11466 | #ifdef SQLITE_OMIT_XFER_OPT |
| | @@ -28503,11 +28517,10 @@ |
| 28503 | 28517 | unixDlClose, /* xDlClose */ \ |
| 28504 | 28518 | unixRandomness, /* xRandomness */ \ |
| 28505 | 28519 | unixSleep, /* xSleep */ \ |
| 28506 | 28520 | unixCurrentTime, /* xCurrentTime */ \ |
| 28507 | 28521 | unixGetLastError, /* xGetLastError */ \ |
| 28508 | | - 0, /* xRename */ \ |
| 28509 | 28522 | unixCurrentTimeInt64, /* xCurrentTimeInt64 */ \ |
| 28510 | 28523 | } |
| 28511 | 28524 | |
| 28512 | 28525 | /* |
| 28513 | 28526 | ** All default VFSes for unix are contained in the following array. |
| | @@ -29406,10 +29419,11 @@ |
| 29406 | 29419 | assert( id!=0 ); |
| 29407 | 29420 | assert( pFile->pShm==0 ); |
| 29408 | 29421 | OSTRACE(("CLOSE %d\n", pFile->h)); |
| 29409 | 29422 | do{ |
| 29410 | 29423 | rc = CloseHandle(pFile->h); |
| 29424 | + /* SimulateIOError( rc=0; cnt=MX_CLOSE_ATTEMPT; ); */ |
| 29411 | 29425 | }while( rc==0 && ++cnt < MX_CLOSE_ATTEMPT && (Sleep(100), 1) ); |
| 29412 | 29426 | #if SQLITE_OS_WINCE |
| 29413 | 29427 | #define WINCE_DELETION_ATTEMPTS 3 |
| 29414 | 29428 | winceDestroyLock(pFile); |
| 29415 | 29429 | if( pFile->zDeleteOnClose ){ |
| | @@ -29497,11 +29511,15 @@ |
| 29497 | 29511 | SimulateDiskfullError(return SQLITE_FULL); |
| 29498 | 29512 | OSTRACE(("WRITE %d lock=%d\n", pFile->h, pFile->locktype)); |
| 29499 | 29513 | rc = SetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN); |
| 29500 | 29514 | if( rc==INVALID_SET_FILE_POINTER && (error=GetLastError())!=NO_ERROR ){ |
| 29501 | 29515 | pFile->lastErrno = error; |
| 29502 | | - return SQLITE_FULL; |
| 29516 | + if( pFile->lastErrno==ERROR_HANDLE_DISK_FULL ){ |
| 29517 | + return SQLITE_FULL; |
| 29518 | + }else{ |
| 29519 | + return SQLITE_IOERR_WRITE; |
| 29520 | + } |
| 29503 | 29521 | } |
| 29504 | 29522 | assert( amt>0 ); |
| 29505 | 29523 | while( |
| 29506 | 29524 | amt>0 |
| 29507 | 29525 | && (rc = WriteFile(pFile->h, pBuf, amt, &wrote, 0))!=0 |
| | @@ -29510,11 +29528,15 @@ |
| 29510 | 29528 | amt -= wrote; |
| 29511 | 29529 | pBuf = &((char*)pBuf)[wrote]; |
| 29512 | 29530 | } |
| 29513 | 29531 | if( !rc || amt>(int)wrote ){ |
| 29514 | 29532 | pFile->lastErrno = GetLastError(); |
| 29515 | | - return SQLITE_FULL; |
| 29533 | + if( pFile->lastErrno==ERROR_HANDLE_DISK_FULL ){ |
| 29534 | + return SQLITE_FULL; |
| 29535 | + }else{ |
| 29536 | + return SQLITE_IOERR_WRITE; |
| 29537 | + } |
| 29516 | 29538 | } |
| 29517 | 29539 | return SQLITE_OK; |
| 29518 | 29540 | } |
| 29519 | 29541 | |
| 29520 | 29542 | /* |
| | @@ -29555,31 +29577,44 @@ |
| 29555 | 29577 | |
| 29556 | 29578 | /* |
| 29557 | 29579 | ** Make sure all writes to a particular file are committed to disk. |
| 29558 | 29580 | */ |
| 29559 | 29581 | static int winSync(sqlite3_file *id, int flags){ |
| 29560 | | -#ifndef SQLITE_NO_SYNC |
| 29582 | +#if !defined(NDEBUG) || !defined(SQLITE_NO_SYNC) || defined(SQLITE_DEBUG) |
| 29561 | 29583 | winFile *pFile = (winFile*)id; |
| 29562 | | - |
| 29563 | | - assert( id!=0 ); |
| 29564 | | - OSTRACE(("SYNC %d lock=%d\n", pFile->h, pFile->locktype)); |
| 29565 | 29584 | #else |
| 29566 | 29585 | UNUSED_PARAMETER(id); |
| 29567 | 29586 | #endif |
| 29587 | + |
| 29588 | + assert( pFile ); |
| 29589 | + /* Check that one of SQLITE_SYNC_NORMAL or FULL was passed */ |
| 29590 | + assert((flags&0x0F)==SQLITE_SYNC_NORMAL |
| 29591 | + || (flags&0x0F)==SQLITE_SYNC_FULL |
| 29592 | + ); |
| 29593 | + |
| 29594 | + OSTRACE(("SYNC %d lock=%d\n", pFile->h, pFile->locktype)); |
| 29595 | + |
| 29568 | 29596 | #ifndef SQLITE_TEST |
| 29569 | 29597 | UNUSED_PARAMETER(flags); |
| 29570 | 29598 | #else |
| 29571 | 29599 | if( flags & SQLITE_SYNC_FULL ){ |
| 29572 | 29600 | sqlite3_fullsync_count++; |
| 29573 | 29601 | } |
| 29574 | 29602 | sqlite3_sync_count++; |
| 29575 | 29603 | #endif |
| 29604 | + |
| 29605 | + /* Unix cannot, but some systems may return SQLITE_FULL from here. This |
| 29606 | + ** line is to test that doing so does not cause any problems. |
| 29607 | + */ |
| 29608 | + SimulateDiskfullError( return SQLITE_FULL ); |
| 29609 | + SimulateIOError( return SQLITE_IOERR; ); |
| 29610 | + |
| 29576 | 29611 | /* If we compiled with the SQLITE_NO_SYNC flag, then syncing is a |
| 29577 | 29612 | ** no-op |
| 29578 | 29613 | */ |
| 29579 | 29614 | #ifdef SQLITE_NO_SYNC |
| 29580 | | - return SQLITE_OK; |
| 29615 | + return SQLITE_OK; |
| 29581 | 29616 | #else |
| 29582 | 29617 | if( FlushFileBuffers(pFile->h) ){ |
| 29583 | 29618 | return SQLITE_OK; |
| 29584 | 29619 | }else{ |
| 29585 | 29620 | pFile->lastErrno = GetLastError(); |
| | @@ -29818,10 +29853,12 @@ |
| 29818 | 29853 | */ |
| 29819 | 29854 | static int winCheckReservedLock(sqlite3_file *id, int *pResOut){ |
| 29820 | 29855 | int rc; |
| 29821 | 29856 | winFile *pFile = (winFile*)id; |
| 29822 | 29857 | |
| 29858 | + SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; ); |
| 29859 | + |
| 29823 | 29860 | assert( id!=0 ); |
| 29824 | 29861 | if( pFile->locktype>=RESERVED_LOCK ){ |
| 29825 | 29862 | rc = 1; |
| 29826 | 29863 | OSTRACE(("TEST WR-LOCK %d %d (local)\n", pFile->h, rc)); |
| 29827 | 29864 | }else{ |
| | @@ -29890,11 +29927,13 @@ |
| 29890 | 29927 | *(int*)pArg = (int)((winFile*)id)->lastErrno; |
| 29891 | 29928 | return SQLITE_OK; |
| 29892 | 29929 | } |
| 29893 | 29930 | case SQLITE_FCNTL_SIZE_HINT: { |
| 29894 | 29931 | sqlite3_int64 sz = *(sqlite3_int64*)pArg; |
| 29932 | + SimulateIOErrorBenign(1); |
| 29895 | 29933 | winTruncate(id, sz); |
| 29934 | + SimulateIOErrorBenign(0); |
| 29896 | 29935 | return SQLITE_OK; |
| 29897 | 29936 | } |
| 29898 | 29937 | } |
| 29899 | 29938 | return SQLITE_ERROR; |
| 29900 | 29939 | } |
| | @@ -30101,14 +30140,20 @@ |
| 30101 | 30140 | if( p->mutex ) sqlite3_mutex_free(p->mutex); |
| 30102 | 30141 | for(i=0; i<p->nRegion; i++){ |
| 30103 | 30142 | UnmapViewOfFile(p->aRegion[i].pMap); |
| 30104 | 30143 | CloseHandle(p->aRegion[i].hMap); |
| 30105 | 30144 | } |
| 30106 | | - if( p->hFile.h != INVALID_HANDLE_VALUE ) { |
| 30145 | + if( p->hFile.h != INVALID_HANDLE_VALUE ){ |
| 30146 | + SimulateIOErrorBenign(1); |
| 30107 | 30147 | winClose((sqlite3_file *)&p->hFile); |
| 30148 | + SimulateIOErrorBenign(0); |
| 30108 | 30149 | } |
| 30109 | | - if( deleteFlag ) winDelete(pVfs, p->zFilename, 0); |
| 30150 | + if( deleteFlag ){ |
| 30151 | + SimulateIOErrorBenign(1); |
| 30152 | + winDelete(pVfs, p->zFilename, 0); |
| 30153 | + SimulateIOErrorBenign(0); |
| 30154 | + } |
| 30110 | 30155 | *pp = p->pNext; |
| 30111 | 30156 | sqlite3_free(p->aRegion); |
| 30112 | 30157 | sqlite3_free(p); |
| 30113 | 30158 | }else{ |
| 30114 | 30159 | pp = &p->pNext; |
| | @@ -30506,10 +30551,17 @@ |
| 30506 | 30551 | "abcdefghijklmnopqrstuvwxyz" |
| 30507 | 30552 | "ABCDEFGHIJKLMNOPQRSTUVWXYZ" |
| 30508 | 30553 | "0123456789"; |
| 30509 | 30554 | size_t i, j; |
| 30510 | 30555 | char zTempPath[MAX_PATH+1]; |
| 30556 | + |
| 30557 | + /* It's odd to simulate an io-error here, but really this is just |
| 30558 | + ** using the io-error infrastructure to test that SQLite handles this |
| 30559 | + ** function failing. |
| 30560 | + */ |
| 30561 | + SimulateIOError( return SQLITE_IOERR ); |
| 30562 | + |
| 30511 | 30563 | if( sqlite3_temp_directory ){ |
| 30512 | 30564 | sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", sqlite3_temp_directory); |
| 30513 | 30565 | }else if( isNT() ){ |
| 30514 | 30566 | char *zMulti; |
| 30515 | 30567 | WCHAR zWidePath[MAX_PATH]; |
| | @@ -30537,20 +30589,30 @@ |
| 30537 | 30589 | }else{ |
| 30538 | 30590 | return SQLITE_NOMEM; |
| 30539 | 30591 | } |
| 30540 | 30592 | #endif |
| 30541 | 30593 | } |
| 30594 | + |
| 30595 | + /* Check that the output buffer is large enough for the temporary file |
| 30596 | + ** name. If it is not, return SQLITE_ERROR. |
| 30597 | + */ |
| 30598 | + if( (sqlite3Strlen30(zTempPath) + sqlite3Strlen30(SQLITE_TEMP_FILE_PREFIX) + 17) >= nBuf ){ |
| 30599 | + return SQLITE_ERROR; |
| 30600 | + } |
| 30601 | + |
| 30542 | 30602 | for(i=sqlite3Strlen30(zTempPath); i>0 && zTempPath[i-1]=='\\'; i--){} |
| 30543 | 30603 | zTempPath[i] = 0; |
| 30544 | | - sqlite3_snprintf(nBuf-30, zBuf, |
| 30604 | + |
| 30605 | + sqlite3_snprintf(nBuf-17, zBuf, |
| 30545 | 30606 | "%s\\"SQLITE_TEMP_FILE_PREFIX, zTempPath); |
| 30546 | 30607 | j = sqlite3Strlen30(zBuf); |
| 30547 | | - sqlite3_randomness(20, &zBuf[j]); |
| 30548 | | - for(i=0; i<20; i++, j++){ |
| 30608 | + sqlite3_randomness(15, &zBuf[j]); |
| 30609 | + for(i=0; i<15; i++, j++){ |
| 30549 | 30610 | zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ]; |
| 30550 | 30611 | } |
| 30551 | 30612 | zBuf[j] = 0; |
| 30613 | + |
| 30552 | 30614 | OSTRACE(("TEMP FILENAME: %s\n", zBuf)); |
| 30553 | 30615 | return SQLITE_OK; |
| 30554 | 30616 | } |
| 30555 | 30617 | |
| 30556 | 30618 | /* |
| | @@ -30790,17 +30852,19 @@ |
| 30790 | 30852 | int syncDir /* Not used on win32 */ |
| 30791 | 30853 | ){ |
| 30792 | 30854 | int cnt = 0; |
| 30793 | 30855 | DWORD rc; |
| 30794 | 30856 | DWORD error = 0; |
| 30795 | | - void *zConverted = convertUtf8Filename(zFilename); |
| 30857 | + void *zConverted; |
| 30796 | 30858 | UNUSED_PARAMETER(pVfs); |
| 30797 | 30859 | UNUSED_PARAMETER(syncDir); |
| 30860 | + |
| 30861 | + SimulateIOError(return SQLITE_IOERR_DELETE); |
| 30862 | + zConverted = convertUtf8Filename(zFilename); |
| 30798 | 30863 | if( zConverted==0 ){ |
| 30799 | 30864 | return SQLITE_NOMEM; |
| 30800 | 30865 | } |
| 30801 | | - SimulateIOError(return SQLITE_IOERR_DELETE); |
| 30802 | 30866 | if( isNT() ){ |
| 30803 | 30867 | do{ |
| 30804 | 30868 | DeleteFileW(zConverted); |
| 30805 | 30869 | }while( ( ((rc = GetFileAttributesW(zConverted)) != INVALID_FILE_ATTRIBUTES) |
| 30806 | 30870 | || ((error = GetLastError()) == ERROR_ACCESS_DENIED)) |
| | @@ -30838,17 +30902,42 @@ |
| 30838 | 30902 | int flags, /* Type of test to make on this file */ |
| 30839 | 30903 | int *pResOut /* OUT: Result */ |
| 30840 | 30904 | ){ |
| 30841 | 30905 | DWORD attr; |
| 30842 | 30906 | int rc = 0; |
| 30843 | | - void *zConverted = convertUtf8Filename(zFilename); |
| 30907 | + void *zConverted; |
| 30844 | 30908 | UNUSED_PARAMETER(pVfs); |
| 30909 | + |
| 30910 | + SimulateIOError( return SQLITE_IOERR_ACCESS; ); |
| 30911 | + zConverted = convertUtf8Filename(zFilename); |
| 30845 | 30912 | if( zConverted==0 ){ |
| 30846 | 30913 | return SQLITE_NOMEM; |
| 30847 | 30914 | } |
| 30848 | 30915 | if( isNT() ){ |
| 30849 | | - attr = GetFileAttributesW((WCHAR*)zConverted); |
| 30916 | + WIN32_FILE_ATTRIBUTE_DATA sAttrData; |
| 30917 | + memset(&sAttrData, 0, sizeof(sAttrData)); |
| 30918 | + if( GetFileAttributesExW((WCHAR*)zConverted, |
| 30919 | + GetFileExInfoStandard, |
| 30920 | + &sAttrData) ){ |
| 30921 | + /* For an SQLITE_ACCESS_EXISTS query, treat a zero-length file |
| 30922 | + ** as if it does not exist. |
| 30923 | + */ |
| 30924 | + if( flags==SQLITE_ACCESS_EXISTS |
| 30925 | + && sAttrData.nFileSizeHigh==0 |
| 30926 | + && sAttrData.nFileSizeLow==0 ){ |
| 30927 | + attr = INVALID_FILE_ATTRIBUTES; |
| 30928 | + }else{ |
| 30929 | + attr = sAttrData.dwFileAttributes; |
| 30930 | + } |
| 30931 | + }else{ |
| 30932 | + if( GetLastError()!=ERROR_FILE_NOT_FOUND ){ |
| 30933 | + free(zConverted); |
| 30934 | + return SQLITE_IOERR_ACCESS; |
| 30935 | + }else{ |
| 30936 | + attr = INVALID_FILE_ATTRIBUTES; |
| 30937 | + } |
| 30938 | + } |
| 30850 | 30939 | /* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. |
| 30851 | 30940 | ** Since the ASCII version of these Windows API do not exist for WINCE, |
| 30852 | 30941 | ** it's important to not reference them for WINCE builds. |
| 30853 | 30942 | */ |
| 30854 | 30943 | #if SQLITE_OS_WINCE==0 |
| | @@ -30884,16 +30973,18 @@ |
| 30884 | 30973 | int nFull, /* Size of output buffer in bytes */ |
| 30885 | 30974 | char *zFull /* Output buffer */ |
| 30886 | 30975 | ){ |
| 30887 | 30976 | |
| 30888 | 30977 | #if defined(__CYGWIN__) |
| 30978 | + SimulateIOError( return SQLITE_ERROR ); |
| 30889 | 30979 | UNUSED_PARAMETER(nFull); |
| 30890 | 30980 | cygwin_conv_to_full_win32_path(zRelative, zFull); |
| 30891 | 30981 | return SQLITE_OK; |
| 30892 | 30982 | #endif |
| 30893 | 30983 | |
| 30894 | 30984 | #if SQLITE_OS_WINCE |
| 30985 | + SimulateIOError( return SQLITE_ERROR ); |
| 30895 | 30986 | UNUSED_PARAMETER(nFull); |
| 30896 | 30987 | /* WinCE has no concept of a relative pathname, or so I am told. */ |
| 30897 | 30988 | sqlite3_snprintf(pVfs->mxPathname, zFull, "%s", zRelative); |
| 30898 | 30989 | return SQLITE_OK; |
| 30899 | 30990 | #endif |
| | @@ -30900,10 +30991,17 @@ |
| 30900 | 30991 | |
| 30901 | 30992 | #if !SQLITE_OS_WINCE && !defined(__CYGWIN__) |
| 30902 | 30993 | int nByte; |
| 30903 | 30994 | void *zConverted; |
| 30904 | 30995 | char *zOut; |
| 30996 | + |
| 30997 | + /* It's odd to simulate an io-error here, but really this is just |
| 30998 | + ** using the io-error infrastructure to test that SQLite handles this |
| 30999 | + ** function failing. This function could fail if, for example, the |
| 31000 | + ** current working directory has been unlinked. |
| 31001 | + */ |
| 31002 | + SimulateIOError( return SQLITE_ERROR ); |
| 30905 | 31003 | UNUSED_PARAMETER(nFull); |
| 30906 | 31004 | zConverted = convertUtf8Filename(zRelative); |
| 30907 | 31005 | if( isNT() ){ |
| 30908 | 31006 | WCHAR *zTemp; |
| 30909 | 31007 | nByte = GetFullPathNameW((WCHAR*)zConverted, 0, 0, 0) + 3; |
| | @@ -30967,11 +31065,13 @@ |
| 30967 | 31065 | /* |
| 30968 | 31066 | ** We need to get the full path name of the file |
| 30969 | 31067 | ** to get the drive letter to look up the sector |
| 30970 | 31068 | ** size. |
| 30971 | 31069 | */ |
| 31070 | + SimulateIOErrorBenign(1); |
| 30972 | 31071 | rc = winFullPathname(pVfs, zRelative, MAX_PATH, zFullpath); |
| 31072 | + SimulateIOErrorBenign(0); |
| 30973 | 31073 | if( rc == SQLITE_OK ) |
| 30974 | 31074 | { |
| 30975 | 31075 | void *zConverted = convertUtf8Filename(zFullpath); |
| 30976 | 31076 | if( zConverted ){ |
| 30977 | 31077 | if( isNT() ){ |
| | @@ -31244,11 +31344,10 @@ |
| 31244 | 31344 | winDlClose, /* xDlClose */ |
| 31245 | 31345 | winRandomness, /* xRandomness */ |
| 31246 | 31346 | winSleep, /* xSleep */ |
| 31247 | 31347 | winCurrentTime, /* xCurrentTime */ |
| 31248 | 31348 | winGetLastError, /* xGetLastError */ |
| 31249 | | - 0, /* xRename */ |
| 31250 | 31349 | winCurrentTimeInt64, /* xCurrentTimeInt64 */ |
| 31251 | 31350 | }; |
| 31252 | 31351 | |
| 31253 | 31352 | sqlite3_vfs_register(&winVfs, 1); |
| 31254 | 31353 | return SQLITE_OK; |
| | @@ -33981,10 +34080,11 @@ |
| 33981 | 34080 | char *pTmpSpace; /* Pager.pageSize bytes of space for tmp use */ |
| 33982 | 34081 | PCache *pPCache; /* Pointer to page cache object */ |
| 33983 | 34082 | sqlite3_backup *pBackup; /* Pointer to list of ongoing backup processes */ |
| 33984 | 34083 | #ifndef SQLITE_OMIT_WAL |
| 33985 | 34084 | Wal *pWal; /* Write-ahead log used by "journal_mode=wal" */ |
| 34085 | + char *zWal; /* File name for write-ahead log */ |
| 33986 | 34086 | #endif |
| 33987 | 34087 | }; |
| 33988 | 34088 | |
| 33989 | 34089 | /* |
| 33990 | 34090 | ** The following global variables hold counters used for |
| | @@ -35091,10 +35191,25 @@ |
| 35091 | 35191 | i -= 200; |
| 35092 | 35192 | } |
| 35093 | 35193 | return cksum; |
| 35094 | 35194 | } |
| 35095 | 35195 | |
| 35196 | +/* |
| 35197 | +** Report the current page size and number of reserved bytes back |
| 35198 | +** to the codec. |
| 35199 | +*/ |
| 35200 | +#ifdef SQLITE_HAS_CODEC |
| 35201 | +static void pagerReportSize(Pager *pPager){ |
| 35202 | + if( pPager->xCodecSizeChng ){ |
| 35203 | + pPager->xCodecSizeChng(pPager->pCodec, pPager->pageSize, |
| 35204 | + (int)pPager->nReserve); |
| 35205 | + } |
| 35206 | +} |
| 35207 | +#else |
| 35208 | +# define pagerReportSize(X) /* No-op if we do not support a codec */ |
| 35209 | +#endif |
| 35210 | + |
| 35096 | 35211 | /* |
| 35097 | 35212 | ** Read a single page from either the journal file (if isMainJrnl==1) or |
| 35098 | 35213 | ** from the sub-journal (if isMainJrnl==0) and playback that page. |
| 35099 | 35214 | ** The page begins at offset *pOffset into the file. The *pOffset |
| 35100 | 35215 | ** value is increased to the start of the next page in the journal. |
| | @@ -35183,15 +35298,24 @@ |
| 35183 | 35298 | if( !isSavepnt && pager_cksum(pPager, (u8*)aData)!=cksum ){ |
| 35184 | 35299 | return SQLITE_DONE; |
| 35185 | 35300 | } |
| 35186 | 35301 | } |
| 35187 | 35302 | |
| 35303 | + /* If this page has already been played by before during the current |
| 35304 | + ** rollback, then don't bother to play it back again. |
| 35305 | + */ |
| 35188 | 35306 | if( pDone && (rc = sqlite3BitvecSet(pDone, pgno))!=SQLITE_OK ){ |
| 35189 | 35307 | return rc; |
| 35190 | 35308 | } |
| 35191 | | - |
| 35192 | 35309 | assert( pPager->state==PAGER_RESERVED || pPager->state>=PAGER_EXCLUSIVE ); |
| 35310 | + |
| 35311 | + /* When playing back page 1, restore the nReserve setting |
| 35312 | + */ |
| 35313 | + if( pgno==1 && pPager->nReserve!=((u8*)aData)[20] ){ |
| 35314 | + pPager->nReserve = ((u8*)aData)[20]; |
| 35315 | + pagerReportSize(pPager); |
| 35316 | + } |
| 35193 | 35317 | |
| 35194 | 35318 | /* If the pager is in RESERVED state, then there must be a copy of this |
| 35195 | 35319 | ** page in the pager cache. In this case just update the pager cache, |
| 35196 | 35320 | ** not the database file. The page is left marked dirty in this case. |
| 35197 | 35321 | ** |
| | @@ -35987,42 +36111,10 @@ |
| 35987 | 36111 | pPager->state = PAGER_SHARED; |
| 35988 | 36112 | |
| 35989 | 36113 | return rc; |
| 35990 | 36114 | } |
| 35991 | 36115 | |
| 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 | 36116 | /* |
| 36025 | 36117 | ** Check if the *-wal file that corresponds to the database opened by pPager |
| 36026 | 36118 | ** exists if the database is not empy, or verify that the *-wal file does |
| 36027 | 36119 | ** not exist (by deleting it) if the database file is empty. |
| 36028 | 36120 | ** |
| | @@ -36048,14 +36140,16 @@ |
| 36048 | 36140 | int nPage; /* Size of the database file */ |
| 36049 | 36141 | assert( pPager->state>=SHARED_LOCK ); |
| 36050 | 36142 | rc = sqlite3PagerPagecount(pPager, &nPage); |
| 36051 | 36143 | if( rc ) return rc; |
| 36052 | 36144 | if( nPage==0 ){ |
| 36053 | | - rc = pagerCheckForOrDeleteWAL(pPager, 0); |
| 36145 | + rc = sqlite3OsDelete(pPager->pVfs, pPager->zWal, 0); |
| 36054 | 36146 | isWal = 0; |
| 36055 | 36147 | }else{ |
| 36056 | | - rc = pagerCheckForOrDeleteWAL(pPager, &isWal); |
| 36148 | + rc = sqlite3OsAccess( |
| 36149 | + pPager->pVfs, pPager->zWal, SQLITE_ACCESS_EXISTS, &isWal |
| 36150 | + ); |
| 36057 | 36151 | } |
| 36058 | 36152 | if( rc==SQLITE_OK ){ |
| 36059 | 36153 | if( isWal ){ |
| 36060 | 36154 | pager_reset(pPager); |
| 36061 | 36155 | rc = sqlite3PagerOpenWal(pPager, 0); |
| | @@ -36125,10 +36219,11 @@ |
| 36125 | 36219 | |
| 36126 | 36220 | /* Set the database size back to the value it was before the savepoint |
| 36127 | 36221 | ** being reverted was opened. |
| 36128 | 36222 | */ |
| 36129 | 36223 | pPager->dbSize = pSavepoint ? pSavepoint->nOrig : pPager->dbOrigSize; |
| 36224 | + pPager->changeCountDone = pPager->tempFile; |
| 36130 | 36225 | |
| 36131 | 36226 | if( !pSavepoint && pagerUseWal(pPager) ){ |
| 36132 | 36227 | return pagerRollbackWal(pPager); |
| 36133 | 36228 | } |
| 36134 | 36229 | |
| | @@ -36325,25 +36420,10 @@ |
| 36325 | 36420 | ){ |
| 36326 | 36421 | pPager->xBusyHandler = xBusyHandler; |
| 36327 | 36422 | pPager->pBusyHandlerArg = pBusyHandlerArg; |
| 36328 | 36423 | } |
| 36329 | 36424 | |
| 36330 | | -/* |
| 36331 | | -** Report the current page size and number of reserved bytes back |
| 36332 | | -** to the codec. |
| 36333 | | -*/ |
| 36334 | | -#ifdef SQLITE_HAS_CODEC |
| 36335 | | -static void pagerReportSize(Pager *pPager){ |
| 36336 | | - if( pPager->xCodecSizeChng ){ |
| 36337 | | - pPager->xCodecSizeChng(pPager->pCodec, pPager->pageSize, |
| 36338 | | - (int)pPager->nReserve); |
| 36339 | | - } |
| 36340 | | -} |
| 36341 | | -#else |
| 36342 | | -# define pagerReportSize(X) /* No-op if we do not support a codec */ |
| 36343 | | -#endif |
| 36344 | | - |
| 36345 | 36425 | /* |
| 36346 | 36426 | ** Change the page size used by the Pager object. The new page size |
| 36347 | 36427 | ** is passed in *pPageSize. |
| 36348 | 36428 | ** |
| 36349 | 36429 | ** If the pager is in the error state when this function is called, it |
| | @@ -36479,19 +36559,10 @@ |
| 36479 | 36559 | /* This routine is only called by btree immediately after creating |
| 36480 | 36560 | ** the Pager object. There has not been an opportunity to transition |
| 36481 | 36561 | ** to WAL mode yet. |
| 36482 | 36562 | */ |
| 36483 | 36563 | assert( !pagerUseWal(pPager) ); |
| 36484 | | -#if 0 |
| 36485 | | - if( pagerUseWal(pPager) ){ |
| 36486 | | - int isInWal = 0; |
| 36487 | | - rc = sqlite3WalRead(pPager->pWal, 1, &isInWal, N, pDest); |
| 36488 | | - if( rc!=SQLITE_OK || isInWal ){ |
| 36489 | | - return rc; |
| 36490 | | - } |
| 36491 | | - } |
| 36492 | | -#endif |
| 36493 | 36564 | |
| 36494 | 36565 | if( isOpen(pPager->fd) ){ |
| 36495 | 36566 | IOTRACE(("DBHDR %p 0 %d\n", pPager, N)) |
| 36496 | 36567 | rc = sqlite3OsRead(pPager->fd, pDest, N, 0); |
| 36497 | 36568 | if( rc==SQLITE_IOERR_SHORT_READ ){ |
| | @@ -36931,17 +37002,13 @@ |
| 36931 | 37002 | ** |
| 36932 | 37003 | ** If everything is successful, SQLITE_OK is returned. If an IO error |
| 36933 | 37004 | ** occurs, an IO error code is returned. Or, if the EXCLUSIVE lock cannot |
| 36934 | 37005 | ** be obtained, SQLITE_BUSY is returned. |
| 36935 | 37006 | */ |
| 36936 | | -static int pager_write_pagelist(PgHdr *pList){ |
| 36937 | | - Pager *pPager; /* Pager object */ |
| 37007 | +static int pager_write_pagelist(Pager *pPager, PgHdr *pList){ |
| 36938 | 37008 | int rc; /* Return code */ |
| 36939 | 37009 | |
| 36940 | | - if( NEVER(pList==0) ) return SQLITE_OK; |
| 36941 | | - pPager = pList->pPager; |
| 36942 | | - |
| 36943 | 37010 | /* At this point there may be either a RESERVED or EXCLUSIVE lock on the |
| 36944 | 37011 | ** database file. If there is already an EXCLUSIVE lock, the following |
| 36945 | 37012 | ** call is a no-op. |
| 36946 | 37013 | ** |
| 36947 | 37014 | ** Moving the lock from RESERVED to EXCLUSIVE actually involves going |
| | @@ -36954,11 +37021,11 @@ |
| 36954 | 37021 | ** is unchanged and we can rollback without having to playback the |
| 36955 | 37022 | ** journal into the original database file. Once we transition to |
| 36956 | 37023 | ** EXCLUSIVE, it means the database file has been changed and any rollback |
| 36957 | 37024 | ** will require a journal playback. |
| 36958 | 37025 | */ |
| 36959 | | - assert( !pagerUseWal(pList->pPager) ); |
| 37026 | + assert( !pagerUseWal(pPager) ); |
| 36960 | 37027 | assert( pPager->state>=PAGER_RESERVED ); |
| 36961 | 37028 | rc = pager_wait_on_lock(pPager, EXCLUSIVE_LOCK); |
| 36962 | 37029 | |
| 36963 | 37030 | /* If the file is a temp-file has not yet been opened, open it now. It |
| 36964 | 37031 | ** is not possible for rc to be other than SQLITE_OK if this branch |
| | @@ -36970,11 +37037,12 @@ |
| 36970 | 37037 | } |
| 36971 | 37038 | |
| 36972 | 37039 | /* Before the first write, give the VFS a hint of what the final |
| 36973 | 37040 | ** file size will be. |
| 36974 | 37041 | */ |
| 36975 | | - if( pPager->dbSize > (pPager->dbOrigSize+1) && isOpen(pPager->fd) ){ |
| 37042 | + assert( rc!=SQLITE_OK || isOpen(pPager->fd) ); |
| 37043 | + if( rc==SQLITE_OK && pPager->dbSize>(pPager->dbOrigSize+1) ){ |
| 36976 | 37044 | sqlite3_int64 szFile = pPager->pageSize * (sqlite3_int64)pPager->dbSize; |
| 36977 | 37045 | sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_SIZE_HINT, &szFile); |
| 36978 | 37046 | } |
| 36979 | 37047 | |
| 36980 | 37048 | while( rc==SQLITE_OK && pList ){ |
| | @@ -37199,11 +37267,11 @@ |
| 37199 | 37267 | rc = subjournalPage(pPg); |
| 37200 | 37268 | } |
| 37201 | 37269 | |
| 37202 | 37270 | /* Write the contents of the page out to the database file. */ |
| 37203 | 37271 | if( rc==SQLITE_OK ){ |
| 37204 | | - rc = pager_write_pagelist(pPg); |
| 37272 | + rc = pager_write_pagelist(pPager, pPg); |
| 37205 | 37273 | } |
| 37206 | 37274 | } |
| 37207 | 37275 | |
| 37208 | 37276 | /* Mark the page as clean. */ |
| 37209 | 37277 | if( rc==SQLITE_OK ){ |
| | @@ -37339,10 +37407,13 @@ |
| 37339 | 37407 | ROUND8(pcacheSize) + /* PCache object */ |
| 37340 | 37408 | ROUND8(pVfs->szOsFile) + /* The main db file */ |
| 37341 | 37409 | journalFileSize * 2 + /* The two journal files */ |
| 37342 | 37410 | nPathname + 1 + /* zFilename */ |
| 37343 | 37411 | nPathname + 8 + 1 /* zJournal */ |
| 37412 | +#ifndef SQLITE_OMIT_WAL |
| 37413 | + + nPathname + 4 + 1 /* zWal */ |
| 37414 | +#endif |
| 37344 | 37415 | ); |
| 37345 | 37416 | assert( EIGHT_BYTE_ALIGNMENT(SQLITE_INT_TO_PTR(journalFileSize)) ); |
| 37346 | 37417 | if( !pPtr ){ |
| 37347 | 37418 | sqlite3_free(zPathname); |
| 37348 | 37419 | return SQLITE_NOMEM; |
| | @@ -37359,11 +37430,20 @@ |
| 37359 | 37430 | if( zPathname ){ |
| 37360 | 37431 | pPager->zJournal = (char*)(pPtr += nPathname + 1); |
| 37361 | 37432 | memcpy(pPager->zFilename, zPathname, nPathname); |
| 37362 | 37433 | memcpy(pPager->zJournal, zPathname, nPathname); |
| 37363 | 37434 | memcpy(&pPager->zJournal[nPathname], "-journal", 8); |
| 37364 | | - if( pPager->zFilename[0]==0 ) pPager->zJournal[0] = 0; |
| 37435 | + if( pPager->zFilename[0]==0 ){ |
| 37436 | + pPager->zJournal[0] = 0; |
| 37437 | + } |
| 37438 | +#ifndef SQLITE_OMIT_WAL |
| 37439 | + else{ |
| 37440 | + pPager->zWal = &pPager->zJournal[nPathname+8+1]; |
| 37441 | + memcpy(pPager->zWal, zPathname, nPathname); |
| 37442 | + memcpy(&pPager->zWal[nPathname], "-wal", 4); |
| 37443 | + } |
| 37444 | +#endif |
| 37365 | 37445 | sqlite3_free(zPathname); |
| 37366 | 37446 | } |
| 37367 | 37447 | pPager->pVfs = pVfs; |
| 37368 | 37448 | pPager->vfsFlags = vfsFlags; |
| 37369 | 37449 | |
| | @@ -38816,11 +38896,11 @@ |
| 38816 | 38896 | */ |
| 38817 | 38897 | rc = syncJournal(pPager); |
| 38818 | 38898 | if( rc!=SQLITE_OK ) goto commit_phase_one_exit; |
| 38819 | 38899 | |
| 38820 | 38900 | /* Write all dirty pages to the database file. */ |
| 38821 | | - rc = pager_write_pagelist(sqlite3PcacheDirtyList(pPager->pPCache)); |
| 38901 | + rc = pager_write_pagelist(pPager,sqlite3PcacheDirtyList(pPager->pPCache)); |
| 38822 | 38902 | if( rc!=SQLITE_OK ){ |
| 38823 | 38903 | assert( rc!=SQLITE_IOERR_BLOCKED ); |
| 38824 | 38904 | goto commit_phase_one_exit; |
| 38825 | 38905 | } |
| 38826 | 38906 | sqlite3PcacheCleanAll(pPager->pPCache); |
| | @@ -39651,12 +39731,11 @@ |
| 39651 | 39731 | |
| 39652 | 39732 | /* Open the connection to the log file. If this operation fails, |
| 39653 | 39733 | ** (e.g. due to malloc() failure), unlock the database file and |
| 39654 | 39734 | ** return an error code. |
| 39655 | 39735 | */ |
| 39656 | | - rc = sqlite3WalOpen(pPager->pVfs, pPager->fd, |
| 39657 | | - pPager->zFilename, &pPager->pWal); |
| 39736 | + rc = sqlite3WalOpen(pPager->pVfs, pPager->fd, pPager->zWal, &pPager->pWal); |
| 39658 | 39737 | if( rc==SQLITE_OK ){ |
| 39659 | 39738 | pPager->journalMode = PAGER_JOURNALMODE_WAL; |
| 39660 | 39739 | } |
| 39661 | 39740 | }else{ |
| 39662 | 39741 | *pisOpen = 1; |
| | @@ -39685,15 +39764,17 @@ |
| 39685 | 39764 | */ |
| 39686 | 39765 | if( !pPager->pWal ){ |
| 39687 | 39766 | int logexists = 0; |
| 39688 | 39767 | rc = sqlite3OsLock(pPager->fd, SQLITE_LOCK_SHARED); |
| 39689 | 39768 | if( rc==SQLITE_OK ){ |
| 39690 | | - rc = pagerCheckForOrDeleteWAL(pPager, &logexists); |
| 39769 | + rc = sqlite3OsAccess( |
| 39770 | + pPager->pVfs, pPager->zWal, SQLITE_ACCESS_EXISTS, &logexists |
| 39771 | + ); |
| 39691 | 39772 | } |
| 39692 | 39773 | if( rc==SQLITE_OK && logexists ){ |
| 39693 | 39774 | rc = sqlite3WalOpen(pPager->pVfs, pPager->fd, |
| 39694 | | - pPager->zFilename, &pPager->pWal); |
| 39775 | + pPager->zWal, &pPager->pWal); |
| 39695 | 39776 | } |
| 39696 | 39777 | } |
| 39697 | 39778 | |
| 39698 | 39779 | /* Checkpoint and close the log. Because an EXCLUSIVE lock is held on |
| 39699 | 39780 | ** the database file, the log and log-summary files will be deleted. |
| | @@ -40131,11 +40212,11 @@ |
| 40131 | 40212 | ** Return the offset of frame iFrame in the write-ahead log file, |
| 40132 | 40213 | ** assuming a database page size of szPage bytes. The offset returned |
| 40133 | 40214 | ** is to the start of the write-ahead log frame-header. |
| 40134 | 40215 | */ |
| 40135 | 40216 | #define walFrameOffset(iFrame, szPage) ( \ |
| 40136 | | - WAL_HDRSIZE + ((iFrame)-1)*((szPage)+WAL_FRAME_HDRSIZE) \ |
| 40217 | + WAL_HDRSIZE + ((iFrame)-1)*(i64)((szPage)+WAL_FRAME_HDRSIZE) \ |
| 40137 | 40218 | ) |
| 40138 | 40219 | |
| 40139 | 40220 | /* |
| 40140 | 40221 | ** An open write-ahead log file is represented by an instance of the |
| 40141 | 40222 | ** following object. |
| | @@ -40152,11 +40233,11 @@ |
| 40152 | 40233 | u8 exclusiveMode; /* Non-zero if connection is in exclusive mode */ |
| 40153 | 40234 | u8 isWIndexOpen; /* True if ShmOpen() called on pDbFd */ |
| 40154 | 40235 | u8 writeLock; /* True if in a write transaction */ |
| 40155 | 40236 | u8 ckptLock; /* True if holding a checkpoint lock */ |
| 40156 | 40237 | WalIndexHdr hdr; /* Wal-index header for current transaction */ |
| 40157 | | - char *zWalName; /* Name of WAL file */ |
| 40238 | + const char *zWalName; /* Name of WAL file */ |
| 40158 | 40239 | u32 nCkpt; /* Checkpoint sequence counter in the wal-header */ |
| 40159 | 40240 | #ifdef SQLITE_DEBUG |
| 40160 | 40241 | u8 lockError; /* True if a locking error has occurred */ |
| 40161 | 40242 | #endif |
| 40162 | 40243 | }; |
| | @@ -40907,12 +40988,13 @@ |
| 40907 | 40988 | pWal->isWIndexOpen = 0; |
| 40908 | 40989 | } |
| 40909 | 40990 | } |
| 40910 | 40991 | |
| 40911 | 40992 | /* |
| 40912 | | -** Open a connection to the WAL file associated with database zDbName. |
| 40913 | | -** The database file must already be opened on connection pDbFd. |
| 40993 | +** Open a connection to the WAL file zWalName. The database file must |
| 40994 | +** already be opened on connection pDbFd. The buffer that zWalName points |
| 40995 | +** to must remain valid for the lifetime of the returned Wal* handle. |
| 40914 | 40996 | ** |
| 40915 | 40997 | ** A SHARED lock should be held on the database file when this function |
| 40916 | 40998 | ** is called. The purpose of this SHARED lock is to prevent any other |
| 40917 | 40999 | ** client from unlinking the WAL or wal-index file. If another process |
| 40918 | 41000 | ** were to do this just after this client opened one of these files, the |
| | @@ -40923,20 +41005,18 @@ |
| 40923 | 41005 | ** an SQLite error code is returned and *ppWal is left unmodified. |
| 40924 | 41006 | */ |
| 40925 | 41007 | SQLITE_PRIVATE int sqlite3WalOpen( |
| 40926 | 41008 | sqlite3_vfs *pVfs, /* vfs module to open wal and wal-index */ |
| 40927 | 41009 | sqlite3_file *pDbFd, /* The open database file */ |
| 40928 | | - const char *zDbName, /* Name of the database file */ |
| 41010 | + const char *zWalName, /* Name of the WAL file */ |
| 40929 | 41011 | Wal **ppWal /* OUT: Allocated Wal handle */ |
| 40930 | 41012 | ){ |
| 40931 | 41013 | int rc; /* Return Code */ |
| 40932 | 41014 | Wal *pRet; /* Object to allocate and return */ |
| 40933 | 41015 | int flags; /* Flags passed to OsOpen() */ |
| 40934 | | - char *zWal; /* Name of write-ahead log file */ |
| 40935 | | - int nWal; /* Length of zWal in bytes */ |
| 40936 | 41016 | |
| 40937 | | - assert( zDbName && zDbName[0] ); |
| 41017 | + assert( zWalName && zWalName[0] ); |
| 40938 | 41018 | assert( pDbFd ); |
| 40939 | 41019 | |
| 40940 | 41020 | /* In the amalgamation, the os_unix.c and os_win.c source files come before |
| 40941 | 41021 | ** this source file. Verify that the #defines of the locking byte offsets |
| 40942 | 41022 | ** in os_unix.c and os_win.c agree with the WALINDEX_LOCK_OFFSET value. |
| | @@ -40949,30 +41029,27 @@ |
| 40949 | 41029 | #endif |
| 40950 | 41030 | |
| 40951 | 41031 | |
| 40952 | 41032 | /* Allocate an instance of struct Wal to return. */ |
| 40953 | 41033 | *ppWal = 0; |
| 40954 | | - nWal = sqlite3Strlen30(zDbName) + 5; |
| 40955 | | - pRet = (Wal*)sqlite3MallocZero(sizeof(Wal) + pVfs->szOsFile + nWal); |
| 41034 | + pRet = (Wal*)sqlite3MallocZero(sizeof(Wal) + pVfs->szOsFile); |
| 40956 | 41035 | if( !pRet ){ |
| 40957 | 41036 | return SQLITE_NOMEM; |
| 40958 | 41037 | } |
| 40959 | 41038 | |
| 40960 | 41039 | pRet->pVfs = pVfs; |
| 40961 | 41040 | pRet->pWalFd = (sqlite3_file *)&pRet[1]; |
| 40962 | 41041 | pRet->pDbFd = pDbFd; |
| 40963 | 41042 | pRet->readLock = -1; |
| 40964 | | - sqlite3_randomness(8, &pRet->hdr.aSalt); |
| 40965 | | - pRet->zWalName = zWal = pVfs->szOsFile + (char*)pRet->pWalFd; |
| 40966 | | - sqlite3_snprintf(nWal, zWal, "%s-wal", zDbName); |
| 41043 | + pRet->zWalName = zWalName; |
| 40967 | 41044 | rc = sqlite3OsShmOpen(pDbFd); |
| 40968 | 41045 | |
| 40969 | 41046 | /* Open file handle on the write-ahead log file. */ |
| 40970 | 41047 | if( rc==SQLITE_OK ){ |
| 40971 | 41048 | pRet->isWIndexOpen = 1; |
| 40972 | 41049 | flags = (SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|SQLITE_OPEN_MAIN_JOURNAL); |
| 40973 | | - rc = sqlite3OsOpen(pVfs, zWal, pRet->pWalFd, flags, &flags); |
| 41050 | + rc = sqlite3OsOpen(pVfs, zWalName, pRet->pWalFd, flags, &flags); |
| 40974 | 41051 | } |
| 40975 | 41052 | |
| 40976 | 41053 | if( rc!=SQLITE_OK ){ |
| 40977 | 41054 | walIndexClose(pRet, 0); |
| 40978 | 41055 | sqlite3OsClose(pRet->pWalFd); |
| | @@ -41310,24 +41387,29 @@ |
| 41310 | 41387 | rc = sqlite3OsSync(pWal->pWalFd, sync_flags); |
| 41311 | 41388 | } |
| 41312 | 41389 | |
| 41313 | 41390 | /* Iterate through the contents of the WAL, copying data to the db file. */ |
| 41314 | 41391 | while( rc==SQLITE_OK && 0==walIteratorNext(pIter, &iDbpage, &iFrame) ){ |
| 41392 | + i64 iOffset; |
| 41315 | 41393 | assert( walFramePgno(pWal, iFrame)==iDbpage ); |
| 41316 | 41394 | if( iFrame<=nBackfill || iFrame>mxSafeFrame ) continue; |
| 41317 | | - rc = sqlite3OsRead(pWal->pWalFd, zBuf, szPage, |
| 41318 | | - walFrameOffset(iFrame, szPage) + WAL_FRAME_HDRSIZE |
| 41319 | | - ); |
| 41395 | + iOffset = walFrameOffset(iFrame, szPage) + WAL_FRAME_HDRSIZE; |
| 41396 | + /* testcase( IS_BIG_INT(iOffset) ); // requires a 4GiB WAL file */ |
| 41397 | + rc = sqlite3OsRead(pWal->pWalFd, zBuf, szPage, iOffset); |
| 41320 | 41398 | if( rc!=SQLITE_OK ) break; |
| 41321 | | - rc = sqlite3OsWrite(pWal->pDbFd, zBuf, szPage, (iDbpage-1)*szPage); |
| 41399 | + iOffset = (iDbpage-1)*(i64)szPage; |
| 41400 | + testcase( IS_BIG_INT(iOffset) ); |
| 41401 | + rc = sqlite3OsWrite(pWal->pDbFd, zBuf, szPage, iOffset); |
| 41322 | 41402 | if( rc!=SQLITE_OK ) break; |
| 41323 | 41403 | } |
| 41324 | 41404 | |
| 41325 | 41405 | /* If work was actually accomplished... */ |
| 41326 | 41406 | if( rc==SQLITE_OK ){ |
| 41327 | 41407 | if( mxSafeFrame==walIndexHdr(pWal)->mxFrame ){ |
| 41328 | | - rc = sqlite3OsTruncate(pWal->pDbFd, ((i64)pWal->hdr.nPage*(i64)szPage)); |
| 41408 | + i64 szDb = pWal->hdr.nPage*(i64)szPage; |
| 41409 | + testcase( IS_BIG_INT(szDb) ); |
| 41410 | + rc = sqlite3OsTruncate(pWal->pDbFd, szDb); |
| 41329 | 41411 | if( rc==SQLITE_OK && sync_flags ){ |
| 41330 | 41412 | rc = sqlite3OsSync(pWal->pDbFd, sync_flags); |
| 41331 | 41413 | } |
| 41332 | 41414 | } |
| 41333 | 41415 | if( rc==SQLITE_OK ){ |
| | @@ -41861,10 +41943,11 @@ |
| 41861 | 41943 | ** required page. Read and return data from the log file. |
| 41862 | 41944 | */ |
| 41863 | 41945 | if( iRead ){ |
| 41864 | 41946 | i64 iOffset = walFrameOffset(iRead, pWal->hdr.szPage) + WAL_FRAME_HDRSIZE; |
| 41865 | 41947 | *pInWal = 1; |
| 41948 | + /* testcase( IS_BIG_INT(iOffset) ); // requires a 4GiB WAL */ |
| 41866 | 41949 | return sqlite3OsRead(pWal->pWalFd, pOut, nOut, iOffset); |
| 41867 | 41950 | } |
| 41868 | 41951 | |
| 41869 | 41952 | *pInWal = 0; |
| 41870 | 41953 | return SQLITE_OK; |
| | @@ -42127,10 +42210,11 @@ |
| 42127 | 42210 | |
| 42128 | 42211 | sqlite3Put4byte(&aWalHdr[0], (WAL_MAGIC | SQLITE_BIGENDIAN)); |
| 42129 | 42212 | sqlite3Put4byte(&aWalHdr[4], WAL_MAX_VERSION); |
| 42130 | 42213 | sqlite3Put4byte(&aWalHdr[8], szPage); |
| 42131 | 42214 | sqlite3Put4byte(&aWalHdr[12], pWal->nCkpt); |
| 42215 | + sqlite3_randomness(8, pWal->hdr.aSalt); |
| 42132 | 42216 | memcpy(&aWalHdr[16], pWal->hdr.aSalt, 8); |
| 42133 | 42217 | walChecksumBytes(1, aWalHdr, WAL_HDRSIZE-2*4, 0, aCksum); |
| 42134 | 42218 | sqlite3Put4byte(&aWalHdr[24], aCksum[0]); |
| 42135 | 42219 | sqlite3Put4byte(&aWalHdr[28], aCksum[1]); |
| 42136 | 42220 | |
| | @@ -42151,12 +42235,12 @@ |
| 42151 | 42235 | for(p=pList; p; p=p->pDirty){ |
| 42152 | 42236 | u32 nDbsize; /* Db-size field for frame header */ |
| 42153 | 42237 | i64 iOffset; /* Write offset in log file */ |
| 42154 | 42238 | void *pData; |
| 42155 | 42239 | |
| 42156 | | - |
| 42157 | 42240 | iOffset = walFrameOffset(++iFrame, szPage); |
| 42241 | + /* testcase( IS_BIG_INT(iOffset) ); // requires a 4GiB WAL */ |
| 42158 | 42242 | |
| 42159 | 42243 | /* Populate and write the frame header */ |
| 42160 | 42244 | nDbsize = (isCommit && p->pDirty==0) ? nTruncate : 0; |
| 42161 | 42245 | #if defined(SQLITE_HAS_CODEC) |
| 42162 | 42246 | if( (pData = sqlite3PagerCodec(p))==0 ) return SQLITE_NOMEM; |
| | @@ -42192,10 +42276,11 @@ |
| 42192 | 42276 | if( (pData = sqlite3PagerCodec(pLast))==0 ) return SQLITE_NOMEM; |
| 42193 | 42277 | #else |
| 42194 | 42278 | pData = pLast->pData; |
| 42195 | 42279 | #endif |
| 42196 | 42280 | walEncodeFrame(pWal, pLast->pgno, nTruncate, pData, aFrame); |
| 42281 | + /* testcase( IS_BIG_INT(iOffset) ); // requires a 4GiB WAL */ |
| 42197 | 42282 | rc = sqlite3OsWrite(pWal->pWalFd, aFrame, sizeof(aFrame), iOffset); |
| 42198 | 42283 | if( rc!=SQLITE_OK ){ |
| 42199 | 42284 | return rc; |
| 42200 | 42285 | } |
| 42201 | 42286 | iOffset += WAL_FRAME_HDRSIZE; |
| | @@ -63501,15 +63586,10 @@ |
| 63501 | 63586 | ** operation. No IO is required. |
| 63502 | 63587 | ** |
| 63503 | 63588 | ** If changing into or out of WAL mode the procedure is more complicated. |
| 63504 | 63589 | ** |
| 63505 | 63590 | ** Write a string containing the final journal-mode to register P2. |
| 63506 | | -** |
| 63507 | | -** If an attempt to change in to or out of WAL mode fails because another |
| 63508 | | -** connection also has the same database open, then an SQLITE_BUSY error |
| 63509 | | -** is raised if P5==0, or of P5!=0 the journal mode changed is skipped |
| 63510 | | -** without signaling the error. |
| 63511 | 63591 | */ |
| 63512 | 63592 | case OP_JournalMode: { /* out2-prerelease */ |
| 63513 | 63593 | #if 0 /* local variables moved into u.cd */ |
| 63514 | 63594 | Btree *pBt; /* Btree to change journal mode of */ |
| 63515 | 63595 | Pager *pPager; /* Pager associated with pBt */ |
| | @@ -63605,11 +63685,10 @@ |
| 63605 | 63685 | } |
| 63606 | 63686 | } |
| 63607 | 63687 | #endif /* ifndef SQLITE_OMIT_WAL */ |
| 63608 | 63688 | |
| 63609 | 63689 | if( rc ){ |
| 63610 | | - if( rc==SQLITE_BUSY && pOp->p5!=0 ) rc = SQLITE_OK; |
| 63611 | 63690 | u.cd.eNew = u.cd.eOld; |
| 63612 | 63691 | } |
| 63613 | 63692 | u.cd.eNew = sqlite3PagerSetJournalMode(u.cd.pPager, u.cd.eNew); |
| 63614 | 63693 | |
| 63615 | 63694 | pOut = &aMem[pOp->p2]; |
| | @@ -63617,11 +63696,11 @@ |
| 63617 | 63696 | pOut->z = (char *)sqlite3JournalModename(u.cd.eNew); |
| 63618 | 63697 | pOut->n = sqlite3Strlen30(pOut->z); |
| 63619 | 63698 | pOut->enc = SQLITE_UTF8; |
| 63620 | 63699 | sqlite3VdbeChangeEncoding(pOut, encoding); |
| 63621 | 63700 | break; |
| 63622 | | -}; |
| 63701 | +}; |
| 63623 | 63702 | #endif /* SQLITE_OMIT_PRAGMA */ |
| 63624 | 63703 | |
| 63625 | 63704 | #if !defined(SQLITE_OMIT_VACUUM) && !defined(SQLITE_OMIT_ATTACH) |
| 63626 | 63705 | /* Opcode: Vacuum * * * * * |
| 63627 | 63706 | ** |
| | @@ -71830,12 +71909,10 @@ |
| 71830 | 71909 | "attached databases must use the same text encoding as main database"); |
| 71831 | 71910 | rc = SQLITE_ERROR; |
| 71832 | 71911 | } |
| 71833 | 71912 | pPager = sqlite3BtreePager(aNew->pBt); |
| 71834 | 71913 | sqlite3PagerLockingMode(pPager, db->dfltLockMode); |
| 71835 | | - /* journal_mode set by the OP_JournalMode opcode that will following |
| 71836 | | - ** the OP_Function opcode that invoked this function. */ |
| 71837 | 71914 | sqlite3BtreeSecureDelete(aNew->pBt, |
| 71838 | 71915 | sqlite3BtreeSecureDelete(db->aDb[0].pBt,-1) ); |
| 71839 | 71916 | } |
| 71840 | 71917 | aNew->safety_level = 3; |
| 71841 | 71918 | aNew->zName = sqlite3DbStrDup(db, zName); |
| | @@ -72027,21 +72104,10 @@ |
| 72027 | 72104 | sqlite3VdbeAddOp3(v, OP_Function, 0, regArgs+3-pFunc->nArg, regArgs+3); |
| 72028 | 72105 | assert( pFunc->nArg==-1 || (pFunc->nArg&0xff)==pFunc->nArg ); |
| 72029 | 72106 | sqlite3VdbeChangeP5(v, (u8)(pFunc->nArg)); |
| 72030 | 72107 | sqlite3VdbeChangeP4(v, -1, (char *)pFunc, P4_FUNCDEF); |
| 72031 | 72108 | |
| 72032 | | - if( type==SQLITE_ATTACH ){ |
| 72033 | | - /* On an attach, also set the journal mode. Note that |
| 72034 | | - ** sqlite3VdbeUsesBtree() is not call here since the iDb index |
| 72035 | | - ** will be out of range prior to the new database being attached. |
| 72036 | | - ** The OP_JournalMode opcode will all sqlite3VdbeUsesBtree() for us. |
| 72037 | | - */ |
| 72038 | | - sqlite3VdbeAddOp3(v, OP_JournalMode, db->nDb, regArgs+3, |
| 72039 | | - db->dfltJournalMode); |
| 72040 | | - sqlite3VdbeChangeP5(v, 1); |
| 72041 | | - } |
| 72042 | | - |
| 72043 | 72109 | /* Code an OP_Expire. For an ATTACH statement, set P1 to true (expire this |
| 72044 | 72110 | ** statement only). For DETACH, set it to false (expire all existing |
| 72045 | 72111 | ** statements). |
| 72046 | 72112 | */ |
| 72047 | 72113 | sqlite3VdbeAddOp1(v, OP_Expire, (type==SQLITE_ATTACH)); |
| | @@ -75914,11 +75980,10 @@ |
| 75914 | 75980 | assert( db->aDb[1].pSchema ); |
| 75915 | 75981 | if( SQLITE_NOMEM==sqlite3BtreeSetPageSize(pBt, db->nextPagesize, -1, 0) ){ |
| 75916 | 75982 | db->mallocFailed = 1; |
| 75917 | 75983 | return 1; |
| 75918 | 75984 | } |
| 75919 | | - sqlite3PagerSetJournalMode(sqlite3BtreePager(pBt), db->dfltJournalMode); |
| 75920 | 75985 | } |
| 75921 | 75986 | return 0; |
| 75922 | 75987 | } |
| 75923 | 75988 | |
| 75924 | 75989 | /* |
| | @@ -83583,58 +83648,49 @@ |
| 83583 | 83648 | ** PRAGMA [database.]journal_mode |
| 83584 | 83649 | ** PRAGMA [database.]journal_mode = |
| 83585 | 83650 | ** (delete|persist|off|truncate|memory|wal|off) |
| 83586 | 83651 | */ |
| 83587 | 83652 | if( sqlite3StrICmp(zLeft,"journal_mode")==0 ){ |
| 83588 | | - int eMode; /* One of the PAGER_JOURNALMODE_XXX symbols */ |
| 83653 | + int eMode; /* One of the PAGER_JOURNALMODE_XXX symbols */ |
| 83654 | + int ii; /* Loop counter */ |
| 83655 | + |
| 83656 | + /* Force the schema to be loaded on all databases. This cases all |
| 83657 | + ** database files to be opened and the journal_modes set. */ |
| 83658 | + if( sqlite3ReadSchema(pParse) ){ |
| 83659 | + goto pragma_out; |
| 83660 | + } |
| 83589 | 83661 | |
| 83590 | 83662 | sqlite3VdbeSetNumCols(v, 1); |
| 83591 | 83663 | sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "journal_mode", SQLITE_STATIC); |
| 83592 | 83664 | |
| 83593 | 83665 | if( zRight==0 ){ |
| 83666 | + /* If there is no "=MODE" part of the pragma, do a query for the |
| 83667 | + ** current mode */ |
| 83594 | 83668 | eMode = PAGER_JOURNALMODE_QUERY; |
| 83595 | 83669 | }else{ |
| 83596 | 83670 | const char *zMode; |
| 83597 | 83671 | int n = sqlite3Strlen30(zRight); |
| 83598 | | - for(eMode=0; (zMode = sqlite3JournalModename(eMode)); eMode++){ |
| 83672 | + for(eMode=0; (zMode = sqlite3JournalModename(eMode))!=0; eMode++){ |
| 83599 | 83673 | if( sqlite3StrNICmp(zRight, zMode, n)==0 ) break; |
| 83600 | 83674 | } |
| 83601 | 83675 | if( !zMode ){ |
| 83676 | + /* If the "=MODE" part does not match any known journal mode, |
| 83677 | + ** then do a query */ |
| 83602 | 83678 | eMode = PAGER_JOURNALMODE_QUERY; |
| 83603 | 83679 | } |
| 83604 | 83680 | } |
| 83605 | | - if( pId2->n==0 && eMode==PAGER_JOURNALMODE_QUERY ){ |
| 83606 | | - /* Simple "PRAGMA journal_mode;" statement. This is a query for |
| 83607 | | - ** the current default journal mode (which may be different to |
| 83608 | | - ** the journal-mode of the main database). |
| 83609 | | - */ |
| 83610 | | - eMode = db->dfltJournalMode; |
| 83611 | | - sqlite3VdbeAddOp2(v, OP_String8, 0, 1); |
| 83612 | | - sqlite3VdbeChangeP4(v, -1, sqlite3JournalModename(eMode), P4_STATIC); |
| 83613 | | - }else{ |
| 83614 | | - int ii; |
| 83615 | | - |
| 83616 | | - if( pId2->n==0 ){ |
| 83617 | | - /* When there is no database name before the "journal_mode" keyword |
| 83618 | | - ** in the PRAGMA, then the journal-mode will be set on |
| 83619 | | - ** all attached databases, as well as the main db file. |
| 83620 | | - ** |
| 83621 | | - ** Also, the sqlite3.dfltJournalMode variable is set so that |
| 83622 | | - ** any subsequently attached databases also use the specified |
| 83623 | | - ** journal mode. |
| 83624 | | - */ |
| 83625 | | - db->dfltJournalMode = (u8)eMode; |
| 83626 | | - } |
| 83627 | | - |
| 83628 | | - for(ii=db->nDb-1; ii>=0; ii--){ |
| 83629 | | - if( db->aDb[ii].pBt && (ii==iDb || pId2->n==0) ){ |
| 83630 | | - sqlite3VdbeUsesBtree(v, ii); |
| 83631 | | - sqlite3VdbeAddOp3(v, OP_JournalMode, ii, 1, eMode); |
| 83632 | | - } |
| 83633 | | - } |
| 83634 | | - } |
| 83635 | | - |
| 83681 | + if( eMode==PAGER_JOURNALMODE_QUERY && pId2->n==0 ){ |
| 83682 | + /* Convert "PRAGMA journal_mode" into "PRAGMA main.journal_mode" */ |
| 83683 | + iDb = 0; |
| 83684 | + pId2->n = 1; |
| 83685 | + } |
| 83686 | + for(ii=db->nDb-1; ii>=0; ii--){ |
| 83687 | + if( db->aDb[ii].pBt && (ii==iDb || pId2->n==0) ){ |
| 83688 | + sqlite3VdbeUsesBtree(v, ii); |
| 83689 | + sqlite3VdbeAddOp3(v, OP_JournalMode, ii, 1, eMode); |
| 83690 | + } |
| 83691 | + } |
| 83636 | 83692 | sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1); |
| 83637 | 83693 | }else |
| 83638 | 83694 | |
| 83639 | 83695 | /* |
| 83640 | 83696 | ** PRAGMA [database.]journal_size_limit |
| | @@ -84648,25 +84704,28 @@ |
| 84648 | 84704 | ** or executed. All the parser does is build the internal data |
| 84649 | 84705 | ** structures that describe the table, index, or view. |
| 84650 | 84706 | */ |
| 84651 | 84707 | int rc; |
| 84652 | 84708 | sqlite3_stmt *pStmt; |
| 84709 | + TESTONLY(int rcp); /* Return code from sqlite3_prepare() */ |
| 84653 | 84710 | |
| 84654 | 84711 | assert( db->init.busy ); |
| 84655 | 84712 | db->init.iDb = iDb; |
| 84656 | 84713 | db->init.newTnum = atoi(argv[1]); |
| 84657 | 84714 | db->init.orphanTrigger = 0; |
| 84658 | | - rc = sqlite3_prepare(db, argv[2], -1, &pStmt, 0); |
| 84715 | + TESTONLY(rcp = ) sqlite3_prepare(db, argv[2], -1, &pStmt, 0); |
| 84716 | + rc = db->errCode; |
| 84717 | + assert( (rc&0xFF)==(rcp&0xFF) ); |
| 84659 | 84718 | db->init.iDb = 0; |
| 84660 | 84719 | if( SQLITE_OK!=rc ){ |
| 84661 | 84720 | if( db->init.orphanTrigger ){ |
| 84662 | 84721 | assert( iDb==1 ); |
| 84663 | 84722 | }else{ |
| 84664 | 84723 | pData->rc = rc; |
| 84665 | 84724 | if( rc==SQLITE_NOMEM ){ |
| 84666 | 84725 | db->mallocFailed = 1; |
| 84667 | | - }else if( rc!=SQLITE_INTERRUPT && rc!=SQLITE_LOCKED ){ |
| 84726 | + }else if( rc!=SQLITE_INTERRUPT && (rc&0xFF)!=SQLITE_LOCKED ){ |
| 84668 | 84727 | corruptSchema(pData, argv[0], sqlite3_errmsg(db)); |
| 84669 | 84728 | } |
| 84670 | 84729 | } |
| 84671 | 84730 | } |
| 84672 | 84731 | sqlite3_finalize(pStmt); |
| | @@ -104123,20 +104182,18 @@ |
| 104123 | 104182 | sqlite3_mutex_leave(db->mutex); |
| 104124 | 104183 | return SQLITE_OK; |
| 104125 | 104184 | } |
| 104126 | 104185 | #endif /* SQLITE_OMIT_UTF16 */ |
| 104127 | 104186 | |
| 104128 | | -#ifndef SQLITE_OMIT_GLOBALRECOVER |
| 104129 | 104187 | #ifndef SQLITE_OMIT_DEPRECATED |
| 104130 | 104188 | /* |
| 104131 | 104189 | ** This function is now an anachronism. It used to be used to recover from a |
| 104132 | 104190 | ** malloc() failure, but SQLite now does this automatically. |
| 104133 | 104191 | */ |
| 104134 | 104192 | SQLITE_API int sqlite3_global_recover(void){ |
| 104135 | 104193 | return SQLITE_OK; |
| 104136 | 104194 | } |
| 104137 | | -#endif |
| 104138 | 104195 | #endif |
| 104139 | 104196 | |
| 104140 | 104197 | /* |
| 104141 | 104198 | ** Test to see whether or not the database connection is in autocommit |
| 104142 | 104199 | ** mode. Return TRUE if it is and FALSE if not. Autocommit mode is on |
| 104143 | 104200 | |