Fossil SCM
Update the built-in SQLite from upstream, for the purpose of testing SQLite.
Commit
fa0df0c77e67010967aebb2b57f91cd9c36eb4f3
Parent
612e0ecc2500e96…
2 files changed
+295
-123
+3
-1
+295
-123
| --- src/sqlite3.c | ||
| +++ src/sqlite3.c | ||
| @@ -656,11 +656,11 @@ | ||
| 656 | 656 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 657 | 657 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 658 | 658 | */ |
| 659 | 659 | #define SQLITE_VERSION "3.8.1" |
| 660 | 660 | #define SQLITE_VERSION_NUMBER 3008001 |
| 661 | -#define SQLITE_SOURCE_ID "2013-08-30 06:20:23 d9c018f8155ab48df8e0e02519bba50588fe49fc" | |
| 661 | +#define SQLITE_SOURCE_ID "2013-09-03 14:43:12 d59f580904e6e7e90fc0a692a3dd4eeff5942479" | |
| 662 | 662 | |
| 663 | 663 | /* |
| 664 | 664 | ** CAPI3REF: Run-Time Library Version Numbers |
| 665 | 665 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 666 | 666 | ** |
| @@ -1026,16 +1026,18 @@ | ||
| 1026 | 1026 | #define SQLITE_IOERR_SHMMAP (SQLITE_IOERR | (21<<8)) |
| 1027 | 1027 | #define SQLITE_IOERR_SEEK (SQLITE_IOERR | (22<<8)) |
| 1028 | 1028 | #define SQLITE_IOERR_DELETE_NOENT (SQLITE_IOERR | (23<<8)) |
| 1029 | 1029 | #define SQLITE_IOERR_MMAP (SQLITE_IOERR | (24<<8)) |
| 1030 | 1030 | #define SQLITE_IOERR_GETTEMPPATH (SQLITE_IOERR | (25<<8)) |
| 1031 | +#define SQLITE_IOERR_CONVPATH (SQLITE_IOERR | (26<<8)) | |
| 1031 | 1032 | #define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8)) |
| 1032 | 1033 | #define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8)) |
| 1033 | 1034 | #define SQLITE_BUSY_SNAPSHOT (SQLITE_BUSY | (2<<8)) |
| 1034 | 1035 | #define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8)) |
| 1035 | 1036 | #define SQLITE_CANTOPEN_ISDIR (SQLITE_CANTOPEN | (2<<8)) |
| 1036 | 1037 | #define SQLITE_CANTOPEN_FULLPATH (SQLITE_CANTOPEN | (3<<8)) |
| 1038 | +#define SQLITE_CANTOPEN_CONVPATH (SQLITE_CANTOPEN | (4<<8)) | |
| 1037 | 1039 | #define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8)) |
| 1038 | 1040 | #define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8)) |
| 1039 | 1041 | #define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8)) |
| 1040 | 1042 | #define SQLITE_READONLY_ROLLBACK (SQLITE_READONLY | (3<<8)) |
| 1041 | 1043 | #define SQLITE_ABORT_ROLLBACK (SQLITE_ABORT | (2<<8)) |
| @@ -16259,11 +16261,11 @@ | ||
| 16259 | 16261 | assert( mem.disallow==0 ); |
| 16260 | 16262 | assert( (nByte & 7)==0 ); /* EV: R-46199-30249 */ |
| 16261 | 16263 | pOldHdr = sqlite3MemsysGetHeader(pPrior); |
| 16262 | 16264 | pNew = sqlite3MemMalloc(nByte); |
| 16263 | 16265 | if( pNew ){ |
| 16264 | - memcpy(pNew, pPrior, nByte<pOldHdr->iSize ? nByte : pOldHdr->iSize); | |
| 16266 | + memcpy(pNew, pPrior, (int)(nByte<pOldHdr->iSize ? nByte : pOldHdr->iSize)); | |
| 16265 | 16267 | if( nByte>pOldHdr->iSize ){ |
| 16266 | 16268 | randomFill(&((char*)pNew)[pOldHdr->iSize], nByte - (int)pOldHdr->iSize); |
| 16267 | 16269 | } |
| 16268 | 16270 | sqlite3MemFree(pPrior); |
| 16269 | 16271 | } |
| @@ -23594,10 +23596,19 @@ | ||
| 23594 | 23596 | if( aSyscall[i].pCurrent!=0 ) return aSyscall[i].zName; |
| 23595 | 23597 | } |
| 23596 | 23598 | return 0; |
| 23597 | 23599 | } |
| 23598 | 23600 | |
| 23601 | +/* | |
| 23602 | +** Do not accept any file descriptor less than this value, in order to avoid | |
| 23603 | +** opening database file using file descriptors that are commonly used for | |
| 23604 | +** standard input, output, and error. | |
| 23605 | +*/ | |
| 23606 | +#ifndef SQLITE_MINIMUM_FILE_DESCRIPTOR | |
| 23607 | +# define SQLITE_MINIMUM_FILE_DESCRIPTOR 3 | |
| 23608 | +#endif | |
| 23609 | + | |
| 23599 | 23610 | /* |
| 23600 | 23611 | ** Invoke open(). Do so multiple times, until it either succeeds or |
| 23601 | 23612 | ** fails for some reason other than EINTR. |
| 23602 | 23613 | ** |
| 23603 | 23614 | ** If the file creation mode "m" is 0 then set it to the default for |
| @@ -23624,11 +23635,11 @@ | ||
| 23624 | 23635 | #endif |
| 23625 | 23636 | if( fd<0 ){ |
| 23626 | 23637 | if( errno==EINTR ) continue; |
| 23627 | 23638 | break; |
| 23628 | 23639 | } |
| 23629 | - if( fd>2 ) break; | |
| 23640 | + if( fd>=SQLITE_MINIMUM_FILE_DESCRIPTOR ) break; | |
| 23630 | 23641 | osClose(fd); |
| 23631 | 23642 | sqlite3_log(SQLITE_WARNING, |
| 23632 | 23643 | "attempt to open \"%s\" as file descriptor %d", z, fd); |
| 23633 | 23644 | fd = -1; |
| 23634 | 23645 | if( osOpen("/dev/null", f, m)<0 ) break; |
| @@ -28373,10 +28384,11 @@ | ||
| 28373 | 28384 | ** If no suitable temporary file directory can be found, return NULL. |
| 28374 | 28385 | */ |
| 28375 | 28386 | static const char *unixTempFileDir(void){ |
| 28376 | 28387 | static const char *azDirs[] = { |
| 28377 | 28388 | 0, |
| 28389 | + 0, | |
| 28378 | 28390 | 0, |
| 28379 | 28391 | "/var/tmp", |
| 28380 | 28392 | "/usr/tmp", |
| 28381 | 28393 | "/tmp", |
| 28382 | 28394 | 0 /* List terminator */ |
| @@ -28384,11 +28396,12 @@ | ||
| 28384 | 28396 | unsigned int i; |
| 28385 | 28397 | struct stat buf; |
| 28386 | 28398 | const char *zDir = 0; |
| 28387 | 28399 | |
| 28388 | 28400 | azDirs[0] = sqlite3_temp_directory; |
| 28389 | - if( !azDirs[1] ) azDirs[1] = getenv("TMPDIR"); | |
| 28401 | + if( !azDirs[1] ) azDirs[1] = getenv("SQLITE_TMPDIR"); | |
| 28402 | + if( !azDirs[2] ) azDirs[2] = getenv("TMPDIR"); | |
| 28390 | 28403 | for(i=0; i<sizeof(azDirs)/sizeof(azDirs[0]); zDir=azDirs[i++]){ |
| 28391 | 28404 | if( zDir==0 ) continue; |
| 28392 | 28405 | if( osStat(zDir, &buf) ) continue; |
| 28393 | 28406 | if( !S_ISDIR(buf.st_mode) ) continue; |
| 28394 | 28407 | if( osAccess(zDir, 07) ) continue; |
| @@ -30497,11 +30510,11 @@ | ||
| 30497 | 30510 | */ |
| 30498 | 30511 | #if SQLITE_OS_WIN /* This file is used for Windows only */ |
| 30499 | 30512 | |
| 30500 | 30513 | #ifdef __CYGWIN__ |
| 30501 | 30514 | # include <sys/cygwin.h> |
| 30502 | -/* # include <errno.h> */ | |
| 30515 | +# include <errno.h> /* amalgamator: keep */ | |
| 30503 | 30516 | #endif |
| 30504 | 30517 | |
| 30505 | 30518 | /* |
| 30506 | 30519 | ** Include code that is common to all os_*.c files |
| 30507 | 30520 | */ |
| @@ -30726,22 +30739,31 @@ | ||
| 30726 | 30739 | |
| 30727 | 30740 | /* |
| 30728 | 30741 | ** Are most of the Win32 ANSI APIs available (i.e. with certain exceptions |
| 30729 | 30742 | ** based on the sub-platform)? |
| 30730 | 30743 | */ |
| 30731 | -#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT | |
| 30744 | +#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && !defined(SQLITE_WIN32_NO_ANSI) | |
| 30732 | 30745 | # define SQLITE_WIN32_HAS_ANSI |
| 30733 | 30746 | #endif |
| 30734 | 30747 | |
| 30735 | 30748 | /* |
| 30736 | 30749 | ** Are most of the Win32 Unicode APIs available (i.e. with certain exceptions |
| 30737 | 30750 | ** based on the sub-platform)? |
| 30738 | 30751 | */ |
| 30739 | -#if SQLITE_OS_WINCE || SQLITE_OS_WINNT || SQLITE_OS_WINRT | |
| 30752 | +#if (SQLITE_OS_WINCE || SQLITE_OS_WINNT || SQLITE_OS_WINRT) && \ | |
| 30753 | + !defined(SQLITE_WIN32_NO_WIDE) | |
| 30740 | 30754 | # define SQLITE_WIN32_HAS_WIDE |
| 30741 | 30755 | #endif |
| 30742 | 30756 | |
| 30757 | +/* | |
| 30758 | +** Make sure at least one set of Win32 APIs is available. | |
| 30759 | +*/ | |
| 30760 | +#if !defined(SQLITE_WIN32_HAS_ANSI) && !defined(SQLITE_WIN32_HAS_WIDE) | |
| 30761 | +# error "At least one of SQLITE_WIN32_HAS_ANSI and SQLITE_WIN32_HAS_WIDE\ | |
| 30762 | + must be defined." | |
| 30763 | +#endif | |
| 30764 | + | |
| 30743 | 30765 | /* |
| 30744 | 30766 | ** Maximum pathname length (in chars) for Win32. This should normally be |
| 30745 | 30767 | ** MAX_PATH. |
| 30746 | 30768 | */ |
| 30747 | 30769 | #ifndef SQLITE_WIN32_MAX_PATH_CHARS |
| @@ -30849,11 +30871,11 @@ | ||
| 30849 | 30871 | #ifndef FILE_ATTRIBUTE_MASK |
| 30850 | 30872 | # define FILE_ATTRIBUTE_MASK (0x0003FFF7) |
| 30851 | 30873 | #endif |
| 30852 | 30874 | |
| 30853 | 30875 | #ifndef SQLITE_OMIT_WAL |
| 30854 | -/* Forward references */ | |
| 30876 | +/* Forward references to structures used for WAL */ | |
| 30855 | 30877 | typedef struct winShm winShm; /* A connection to shared-memory */ |
| 30856 | 30878 | typedef struct winShmNode winShmNode; /* A region of shared-memory */ |
| 30857 | 30879 | #endif |
| 30858 | 30880 | |
| 30859 | 30881 | /* |
| @@ -31804,11 +31826,11 @@ | ||
| 31804 | 31826 | ** API as long as we don't call it when running Win95/98/ME. A call to |
| 31805 | 31827 | ** this routine is used to determine if the host is Win95/98/ME or |
| 31806 | 31828 | ** WinNT/2K/XP so that we will know whether or not we can safely call |
| 31807 | 31829 | ** the LockFileEx() API. |
| 31808 | 31830 | */ |
| 31809 | -#if SQLITE_OS_WINCE || SQLITE_OS_WINRT | |
| 31831 | +#if SQLITE_OS_WINCE || SQLITE_OS_WINRT || !defined(SQLITE_WIN32_HAS_ANSI) | |
| 31810 | 31832 | # define osIsNT() (1) |
| 31811 | 31833 | #elif !defined(SQLITE_WIN32_HAS_WIDE) |
| 31812 | 31834 | # define osIsNT() (0) |
| 31813 | 31835 | #else |
| 31814 | 31836 | static int osIsNT(void){ |
| @@ -32449,14 +32471,13 @@ | ||
| 32449 | 32471 | |
| 32450 | 32472 | /* Create/open the named mutex */ |
| 32451 | 32473 | pFile->hMutex = osCreateMutexW(NULL, FALSE, zName); |
| 32452 | 32474 | if (!pFile->hMutex){ |
| 32453 | 32475 | pFile->lastErrno = osGetLastError(); |
| 32454 | - winLogError(SQLITE_IOERR, pFile->lastErrno, | |
| 32455 | - "winceCreateLock1", zFilename); | |
| 32456 | 32476 | sqlite3_free(zName); |
| 32457 | - return SQLITE_IOERR; | |
| 32477 | + return winLogError(SQLITE_IOERR, pFile->lastErrno, | |
| 32478 | + "winceCreateLock1", zFilename); | |
| 32458 | 32479 | } |
| 32459 | 32480 | |
| 32460 | 32481 | /* Acquire the mutex before continuing */ |
| 32461 | 32482 | winceMutexAcquire(pFile->hMutex); |
| 32462 | 32483 | |
| @@ -32788,11 +32809,11 @@ | ||
| 32788 | 32809 | |
| 32789 | 32810 | if( (dwRet==INVALID_SET_FILE_POINTER |
| 32790 | 32811 | && ((lastErrno = osGetLastError())!=NO_ERROR)) ){ |
| 32791 | 32812 | pFile->lastErrno = lastErrno; |
| 32792 | 32813 | winLogError(SQLITE_IOERR_SEEK, pFile->lastErrno, |
| 32793 | - "winSeekFile", pFile->zPath); | |
| 32814 | + "winSeekFile", pFile->zPath); | |
| 32794 | 32815 | OSTRACE(("SEEK file=%p, rc=SQLITE_IOERR_SEEK\n", pFile->h)); |
| 32795 | 32816 | return 1; |
| 32796 | 32817 | } |
| 32797 | 32818 | |
| 32798 | 32819 | OSTRACE(("SEEK file=%p, rc=SQLITE_OK\n", pFile->h)); |
| @@ -32809,11 +32830,11 @@ | ||
| 32809 | 32830 | bRet = osSetFilePointerEx(pFile->h, x, 0, FILE_BEGIN); |
| 32810 | 32831 | |
| 32811 | 32832 | if(!bRet){ |
| 32812 | 32833 | pFile->lastErrno = osGetLastError(); |
| 32813 | 32834 | winLogError(SQLITE_IOERR_SEEK, pFile->lastErrno, |
| 32814 | - "winSeekFile", pFile->zPath); | |
| 32835 | + "winSeekFile", pFile->zPath); | |
| 32815 | 32836 | OSTRACE(("SEEK file=%p, rc=SQLITE_IOERR_SEEK\n", pFile->h)); |
| 32816 | 32837 | return 1; |
| 32817 | 32838 | } |
| 32818 | 32839 | |
| 32819 | 32840 | OSTRACE(("SEEK file=%p, rc=SQLITE_OK\n", pFile->h)); |
| @@ -32820,11 +32841,12 @@ | ||
| 32820 | 32841 | return 0; |
| 32821 | 32842 | #endif |
| 32822 | 32843 | } |
| 32823 | 32844 | |
| 32824 | 32845 | #if SQLITE_MAX_MMAP_SIZE>0 |
| 32825 | -/* Forward references to VFS methods */ | |
| 32846 | +/* Forward references to VFS helper methods used for memory mapped files */ | |
| 32847 | +static int winMapfile(winFile*, sqlite3_int64); | |
| 32826 | 32848 | static int winUnmapfile(winFile*); |
| 32827 | 32849 | #endif |
| 32828 | 32850 | |
| 32829 | 32851 | /* |
| 32830 | 32852 | ** Close a file. |
| @@ -32941,11 +32963,11 @@ | ||
| 32941 | 32963 | DWORD lastErrno; |
| 32942 | 32964 | if( winRetryIoerr(&nRetry, &lastErrno) ) continue; |
| 32943 | 32965 | pFile->lastErrno = lastErrno; |
| 32944 | 32966 | OSTRACE(("READ file=%p, rc=SQLITE_IOERR_READ\n", pFile->h)); |
| 32945 | 32967 | return winLogError(SQLITE_IOERR_READ, pFile->lastErrno, |
| 32946 | - "winRead", pFile->zPath); | |
| 32968 | + "winRead", pFile->zPath); | |
| 32947 | 32969 | } |
| 32948 | 32970 | winLogIoerr(nRetry); |
| 32949 | 32971 | if( nRead<(DWORD)amt ){ |
| 32950 | 32972 | /* Unread parts of the buffer must be zero-filled */ |
| 32951 | 32973 | memset(&((char*)pBuf)[nRead], 0, amt-nRead); |
| @@ -33047,15 +33069,16 @@ | ||
| 33047 | 33069 | |
| 33048 | 33070 | if( rc ){ |
| 33049 | 33071 | if( ( pFile->lastErrno==ERROR_HANDLE_DISK_FULL ) |
| 33050 | 33072 | || ( pFile->lastErrno==ERROR_DISK_FULL )){ |
| 33051 | 33073 | OSTRACE(("WRITE file=%p, rc=SQLITE_FULL\n", pFile->h)); |
| 33052 | - return SQLITE_FULL; | |
| 33074 | + return winLogError(SQLITE_FULL, pFile->lastErrno, | |
| 33075 | + "winWrite1", pFile->zPath); | |
| 33053 | 33076 | } |
| 33054 | 33077 | OSTRACE(("WRITE file=%p, rc=SQLITE_IOERR_WRITE\n", pFile->h)); |
| 33055 | 33078 | return winLogError(SQLITE_IOERR_WRITE, pFile->lastErrno, |
| 33056 | - "winWrite", pFile->zPath); | |
| 33079 | + "winWrite2", pFile->zPath); | |
| 33057 | 33080 | }else{ |
| 33058 | 33081 | winLogIoerr(nRetry); |
| 33059 | 33082 | } |
| 33060 | 33083 | OSTRACE(("WRITE file=%p, rc=SQLITE_OK\n", pFile->h)); |
| 33061 | 33084 | return SQLITE_OK; |
| @@ -33175,11 +33198,11 @@ | ||
| 33175 | 33198 | return SQLITE_OK; |
| 33176 | 33199 | }else{ |
| 33177 | 33200 | pFile->lastErrno = osGetLastError(); |
| 33178 | 33201 | OSTRACE(("SYNC file=%p, rc=SQLITE_IOERR_FSYNC\n", pFile->h)); |
| 33179 | 33202 | return winLogError(SQLITE_IOERR_FSYNC, pFile->lastErrno, |
| 33180 | - "winSync", pFile->zPath); | |
| 33203 | + "winSync", pFile->zPath); | |
| 33181 | 33204 | } |
| 33182 | 33205 | #endif |
| 33183 | 33206 | } |
| 33184 | 33207 | |
| 33185 | 33208 | /* |
| @@ -33216,11 +33239,11 @@ | ||
| 33216 | 33239 | *pSize = (((sqlite3_int64)upperBits)<<32) + lowerBits; |
| 33217 | 33240 | if( (lowerBits == INVALID_FILE_SIZE) |
| 33218 | 33241 | && ((lastErrno = osGetLastError())!=NO_ERROR) ){ |
| 33219 | 33242 | pFile->lastErrno = lastErrno; |
| 33220 | 33243 | rc = winLogError(SQLITE_IOERR_FSTAT, pFile->lastErrno, |
| 33221 | - "winFileSize", pFile->zPath); | |
| 33244 | + "winFileSize", pFile->zPath); | |
| 33222 | 33245 | } |
| 33223 | 33246 | } |
| 33224 | 33247 | #endif |
| 33225 | 33248 | OSTRACE(("SIZE file=%p, pSize=%p, *pSize=%lld, rc=%s\n", |
| 33226 | 33249 | pFile->h, pSize, *pSize, sqlite3ErrName(rc))); |
| @@ -33311,11 +33334,11 @@ | ||
| 33311 | 33334 | } |
| 33312 | 33335 | #endif |
| 33313 | 33336 | if( res==0 && ((lastErrno = osGetLastError())!=ERROR_NOT_LOCKED) ){ |
| 33314 | 33337 | pFile->lastErrno = lastErrno; |
| 33315 | 33338 | winLogError(SQLITE_IOERR_UNLOCK, pFile->lastErrno, |
| 33316 | - "winUnlockReadLock", pFile->zPath); | |
| 33339 | + "winUnlockReadLock", pFile->zPath); | |
| 33317 | 33340 | } |
| 33318 | 33341 | OSTRACE(("READ-UNLOCK file=%p, rc=%s\n", pFile->h, sqlite3ErrName(res))); |
| 33319 | 33342 | return res; |
| 33320 | 33343 | } |
| 33321 | 33344 | |
| @@ -33524,11 +33547,11 @@ | ||
| 33524 | 33547 | winUnlockFile(&pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0); |
| 33525 | 33548 | if( locktype==SHARED_LOCK && !winGetReadLock(pFile) ){ |
| 33526 | 33549 | /* This should never happen. We should always be able to |
| 33527 | 33550 | ** reacquire the read lock */ |
| 33528 | 33551 | rc = winLogError(SQLITE_IOERR_UNLOCK, osGetLastError(), |
| 33529 | - "winUnlock", pFile->zPath); | |
| 33552 | + "winUnlock", pFile->zPath); | |
| 33530 | 33553 | } |
| 33531 | 33554 | } |
| 33532 | 33555 | if( type>=RESERVED_LOCK ){ |
| 33533 | 33556 | winUnlockFile(&pFile->h, RESERVED_BYTE, 0, 1, 0); |
| 33534 | 33557 | } |
| @@ -33558,15 +33581,14 @@ | ||
| 33558 | 33581 | }else{ |
| 33559 | 33582 | pFile->ctrlFlags |= mask; |
| 33560 | 33583 | } |
| 33561 | 33584 | } |
| 33562 | 33585 | |
| 33563 | -/* Forward declaration */ | |
| 33586 | +/* Forward references to VFS helper methods used for temporary files */ | |
| 33564 | 33587 | static int winGetTempname(sqlite3_vfs *, char **); |
| 33565 | -#if SQLITE_MAX_MMAP_SIZE>0 | |
| 33566 | -static int winMapfile(winFile*, sqlite3_int64); | |
| 33567 | -#endif | |
| 33588 | +static int winIsDir(const void *); | |
| 33589 | +static BOOL winIsDriveLetterAndColon(const char *); | |
| 33568 | 33590 | |
| 33569 | 33591 | /* |
| 33570 | 33592 | ** Control and query of the open file handle. |
| 33571 | 33593 | */ |
| 33572 | 33594 | static int winFileControl(sqlite3_file *id, int op, void *pArg){ |
| @@ -33640,11 +33662,11 @@ | ||
| 33640 | 33662 | char *zTFile = 0; |
| 33641 | 33663 | int rc = winGetTempname(pFile->pVfs, &zTFile); |
| 33642 | 33664 | if( rc==SQLITE_OK ){ |
| 33643 | 33665 | *(char**)pArg = zTFile; |
| 33644 | 33666 | } |
| 33645 | - OSTRACE(("FCNTL file=%p, rc=%d\n", pFile->h, rc)); | |
| 33667 | + OSTRACE(("FCNTL file=%p, rc=%s\n", pFile->h, sqlite3ErrName(rc))); | |
| 33646 | 33668 | return rc; |
| 33647 | 33669 | } |
| 33648 | 33670 | #if SQLITE_MAX_MMAP_SIZE>0 |
| 33649 | 33671 | case SQLITE_FCNTL_MMAP_SIZE: { |
| 33650 | 33672 | i64 newLimit = *(i64*)pArg; |
| @@ -33658,11 +33680,11 @@ | ||
| 33658 | 33680 | if( pFile->mmapSize>0 ){ |
| 33659 | 33681 | (void)winUnmapfile(pFile); |
| 33660 | 33682 | rc = winMapfile(pFile, -1); |
| 33661 | 33683 | } |
| 33662 | 33684 | } |
| 33663 | - OSTRACE(("FCNTL file=%p, rc=%d\n", pFile->h, rc)); | |
| 33685 | + OSTRACE(("FCNTL file=%p, rc=%s\n", pFile->h, sqlite3ErrName(rc))); | |
| 33664 | 33686 | return rc; |
| 33665 | 33687 | } |
| 33666 | 33688 | #endif |
| 33667 | 33689 | } |
| 33668 | 33690 | OSTRACE(("FCNTL file=%p, rc=SQLITE_NOTFOUND\n", pFile->h)); |
| @@ -33974,11 +33996,11 @@ | ||
| 33974 | 33996 | */ |
| 33975 | 33997 | if( winShmSystemLock(pShmNode, _SHM_WRLCK, WIN_SHM_DMS, 1)==SQLITE_OK ){ |
| 33976 | 33998 | rc = winTruncate((sqlite3_file *)&pShmNode->hFile, 0); |
| 33977 | 33999 | if( rc!=SQLITE_OK ){ |
| 33978 | 34000 | rc = winLogError(SQLITE_IOERR_SHMOPEN, osGetLastError(), |
| 33979 | - "winOpenShm", pDbFd->zPath); | |
| 34001 | + "winOpenShm", pDbFd->zPath); | |
| 33980 | 34002 | } |
| 33981 | 34003 | } |
| 33982 | 34004 | if( rc==SQLITE_OK ){ |
| 33983 | 34005 | winShmSystemLock(pShmNode, _SHM_UNLCK, WIN_SHM_DMS, 1); |
| 33984 | 34006 | rc = winShmSystemLock(pShmNode, _SHM_RDLCK, WIN_SHM_DMS, 1); |
| @@ -34234,11 +34256,11 @@ | ||
| 34234 | 34256 | ** large enough to contain the requested region). |
| 34235 | 34257 | */ |
| 34236 | 34258 | rc = winFileSize((sqlite3_file *)&pShmNode->hFile, &sz); |
| 34237 | 34259 | if( rc!=SQLITE_OK ){ |
| 34238 | 34260 | rc = winLogError(SQLITE_IOERR_SHMSIZE, osGetLastError(), |
| 34239 | - "winShmMap1", pDbFd->zPath); | |
| 34261 | + "winShmMap1", pDbFd->zPath); | |
| 34240 | 34262 | goto shmpage_out; |
| 34241 | 34263 | } |
| 34242 | 34264 | |
| 34243 | 34265 | if( sz<nByte ){ |
| 34244 | 34266 | /* The requested memory region does not exist. If isWrite is set to |
| @@ -34249,11 +34271,11 @@ | ||
| 34249 | 34271 | */ |
| 34250 | 34272 | if( !isWrite ) goto shmpage_out; |
| 34251 | 34273 | rc = winTruncate((sqlite3_file *)&pShmNode->hFile, nByte); |
| 34252 | 34274 | if( rc!=SQLITE_OK ){ |
| 34253 | 34275 | rc = winLogError(SQLITE_IOERR_SHMSIZE, osGetLastError(), |
| 34254 | - "winShmMap2", pDbFd->zPath); | |
| 34276 | + "winShmMap2", pDbFd->zPath); | |
| 34255 | 34277 | goto shmpage_out; |
| 34256 | 34278 | } |
| 34257 | 34279 | } |
| 34258 | 34280 | |
| 34259 | 34281 | /* Map the requested memory region into this processes address space. */ |
| @@ -34303,11 +34325,11 @@ | ||
| 34303 | 34325 | szRegion, pMap ? "ok" : "failed")); |
| 34304 | 34326 | } |
| 34305 | 34327 | if( !pMap ){ |
| 34306 | 34328 | pShmNode->lastErrno = osGetLastError(); |
| 34307 | 34329 | rc = winLogError(SQLITE_IOERR_SHMMAP, pShmNode->lastErrno, |
| 34308 | - "winShmMap3", pDbFd->zPath); | |
| 34330 | + "winShmMap3", pDbFd->zPath); | |
| 34309 | 34331 | if( hMap ) osCloseHandle(hMap); |
| 34310 | 34332 | goto shmpage_out; |
| 34311 | 34333 | } |
| 34312 | 34334 | |
| 34313 | 34335 | pShmNode->aRegion[pShmNode->nRegion].pMap = pMap; |
| @@ -34351,11 +34373,11 @@ | ||
| 34351 | 34373 | pFile->lastErrno = osGetLastError(); |
| 34352 | 34374 | OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, pMapRegion=%p, " |
| 34353 | 34375 | "rc=SQLITE_IOERR_MMAP\n", osGetCurrentProcessId(), pFile, |
| 34354 | 34376 | pFile->pMapRegion)); |
| 34355 | 34377 | return winLogError(SQLITE_IOERR_MMAP, pFile->lastErrno, |
| 34356 | - "winUnmap1", pFile->zPath); | |
| 34378 | + "winUnmapfile1", pFile->zPath); | |
| 34357 | 34379 | } |
| 34358 | 34380 | pFile->pMapRegion = 0; |
| 34359 | 34381 | pFile->mmapSize = 0; |
| 34360 | 34382 | pFile->mmapSizeActual = 0; |
| 34361 | 34383 | } |
| @@ -34363,11 +34385,11 @@ | ||
| 34363 | 34385 | if( !osCloseHandle(pFile->hMap) ){ |
| 34364 | 34386 | pFile->lastErrno = osGetLastError(); |
| 34365 | 34387 | OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, hMap=%p, rc=SQLITE_IOERR_MMAP\n", |
| 34366 | 34388 | osGetCurrentProcessId(), pFile, pFile->hMap)); |
| 34367 | 34389 | return winLogError(SQLITE_IOERR_MMAP, pFile->lastErrno, |
| 34368 | - "winUnmap2", pFile->zPath); | |
| 34390 | + "winUnmapfile2", pFile->zPath); | |
| 34369 | 34391 | } |
| 34370 | 34392 | pFile->hMap = NULL; |
| 34371 | 34393 | } |
| 34372 | 34394 | OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, rc=SQLITE_OK\n", |
| 34373 | 34395 | osGetCurrentProcessId(), pFile)); |
| @@ -34438,14 +34460,14 @@ | ||
| 34438 | 34460 | (DWORD)(nMap & 0xffffffff), NULL); |
| 34439 | 34461 | #endif |
| 34440 | 34462 | if( pFd->hMap==NULL ){ |
| 34441 | 34463 | pFd->lastErrno = osGetLastError(); |
| 34442 | 34464 | rc = winLogError(SQLITE_IOERR_MMAP, pFd->lastErrno, |
| 34443 | - "winMapfile", pFd->zPath); | |
| 34465 | + "winMapfile1", pFd->zPath); | |
| 34444 | 34466 | /* Log the error, but continue normal operation using xRead/xWrite */ |
| 34445 | - OSTRACE(("MAP-FILE-CREATE pid=%lu, pFile=%p, rc=SQLITE_IOERR_MMAP\n", | |
| 34446 | - osGetCurrentProcessId(), pFd)); | |
| 34467 | + OSTRACE(("MAP-FILE-CREATE pid=%lu, pFile=%p, rc=%s\n", | |
| 34468 | + osGetCurrentProcessId(), pFd, sqlite3ErrName(rc))); | |
| 34447 | 34469 | return SQLITE_OK; |
| 34448 | 34470 | } |
| 34449 | 34471 | assert( (nMap % winSysInfo.dwPageSize)==0 ); |
| 34450 | 34472 | assert( sizeof(SIZE_T)==sizeof(sqlite3_int64) || nMap<=0xffffffff ); |
| 34451 | 34473 | #if SQLITE_OS_WINRT |
| @@ -34455,14 +34477,15 @@ | ||
| 34455 | 34477 | #endif |
| 34456 | 34478 | if( pNew==NULL ){ |
| 34457 | 34479 | osCloseHandle(pFd->hMap); |
| 34458 | 34480 | pFd->hMap = NULL; |
| 34459 | 34481 | pFd->lastErrno = osGetLastError(); |
| 34460 | - winLogError(SQLITE_IOERR_MMAP, pFd->lastErrno, | |
| 34461 | - "winMapfile", pFd->zPath); | |
| 34462 | - OSTRACE(("MAP-FILE-MAP pid=%lu, pFile=%p, rc=SQLITE_IOERR_MMAP\n", | |
| 34463 | - osGetCurrentProcessId(), pFd)); | |
| 34482 | + rc = winLogError(SQLITE_IOERR_MMAP, pFd->lastErrno, | |
| 34483 | + "winMapfile2", pFd->zPath); | |
| 34484 | + /* Log the error, but continue normal operation using xRead/xWrite */ | |
| 34485 | + OSTRACE(("MAP-FILE-MAP pid=%lu, pFile=%p, rc=%s\n", | |
| 34486 | + osGetCurrentProcessId(), pFd, sqlite3ErrName(rc))); | |
| 34464 | 34487 | return SQLITE_OK; |
| 34465 | 34488 | } |
| 34466 | 34489 | pFd->pMapRegion = pNew; |
| 34467 | 34490 | pFd->mmapSize = nMap; |
| 34468 | 34491 | pFd->mmapSizeActual = nMap; |
| @@ -34596,18 +34619,37 @@ | ||
| 34596 | 34619 | **************************** sqlite3_vfs methods **************************** |
| 34597 | 34620 | ** |
| 34598 | 34621 | ** This division contains the implementation of methods on the |
| 34599 | 34622 | ** sqlite3_vfs object. |
| 34600 | 34623 | */ |
| 34624 | + | |
| 34625 | +/* | |
| 34626 | +** Convert a filename from whatever the underlying operating system | |
| 34627 | +** supports for filenames into UTF-8. Space to hold the result is | |
| 34628 | +** obtained from malloc and must be freed by the calling function. | |
| 34629 | +*/ | |
| 34630 | +static char *winConvertToUtf8Filename(const void *zFilename){ | |
| 34631 | + char *zConverted = 0; | |
| 34632 | + if( osIsNT() ){ | |
| 34633 | + zConverted = winUnicodeToUtf8(zFilename); | |
| 34634 | + } | |
| 34635 | +#ifdef SQLITE_WIN32_HAS_ANSI | |
| 34636 | + else{ | |
| 34637 | + zConverted = sqlite3_win32_mbcs_to_utf8(zFilename); | |
| 34638 | + } | |
| 34639 | +#endif | |
| 34640 | + /* caller will handle out of memory */ | |
| 34641 | + return zConverted; | |
| 34642 | +} | |
| 34601 | 34643 | |
| 34602 | 34644 | /* |
| 34603 | 34645 | ** Convert a UTF-8 filename into whatever form the underlying |
| 34604 | 34646 | ** operating system wants filenames in. Space to hold the result |
| 34605 | 34647 | ** is obtained from malloc and must be freed by the calling |
| 34606 | 34648 | ** function. |
| 34607 | 34649 | */ |
| 34608 | -static void *winConvertUtf8Filename(const char *zFilename){ | |
| 34650 | +static void *winConvertFromUtf8Filename(const char *zFilename){ | |
| 34609 | 34651 | void *zConverted = 0; |
| 34610 | 34652 | if( osIsNT() ){ |
| 34611 | 34653 | zConverted = winUtf8ToUnicode(zFilename); |
| 34612 | 34654 | } |
| 34613 | 34655 | #ifdef SQLITE_WIN32_HAS_ANSI |
| @@ -34668,11 +34710,94 @@ | ||
| 34668 | 34710 | if( sqlite3_temp_directory ){ |
| 34669 | 34711 | sqlite3_snprintf(nBuf-30, zBuf, "%s%s", sqlite3_temp_directory, |
| 34670 | 34712 | winEndsInDirSep(sqlite3_temp_directory) ? "" : |
| 34671 | 34713 | winGetDirDep()); |
| 34672 | 34714 | } |
| 34673 | -#if !SQLITE_OS_WINRT | |
| 34715 | +#if defined(__CYGWIN__) | |
| 34716 | + else{ | |
| 34717 | + static const char *azDirs[] = { | |
| 34718 | + 0, /* getenv("SQLITE_TMPDIR") */ | |
| 34719 | + 0, /* getenv("TMPDIR") */ | |
| 34720 | + 0, /* getenv("TMP") */ | |
| 34721 | + 0, /* getenv("TEMP") */ | |
| 34722 | + 0, /* getenv("USERPROFILE") */ | |
| 34723 | + "/var/tmp", | |
| 34724 | + "/usr/tmp", | |
| 34725 | + "/tmp", | |
| 34726 | + ".", | |
| 34727 | + 0 /* List terminator */ | |
| 34728 | + }; | |
| 34729 | + unsigned int i; | |
| 34730 | + const char *zDir = 0; | |
| 34731 | + | |
| 34732 | + if( !azDirs[0] ) azDirs[0] = getenv("SQLITE_TMPDIR"); | |
| 34733 | + if( !azDirs[1] ) azDirs[1] = getenv("TMPDIR"); | |
| 34734 | + if( !azDirs[2] ) azDirs[2] = getenv("TMP"); | |
| 34735 | + if( !azDirs[3] ) azDirs[3] = getenv("TEMP"); | |
| 34736 | + if( !azDirs[4] ) azDirs[4] = getenv("USERPROFILE"); | |
| 34737 | + for(i=0; i<sizeof(azDirs)/sizeof(azDirs[0]); zDir=azDirs[i++]){ | |
| 34738 | + void *zConverted; | |
| 34739 | + if( zDir==0 ) continue; | |
| 34740 | + /* If the path starts with a drive letter followed by the colon | |
| 34741 | + ** character, assume it is already a native Win32 path; otherwise, | |
| 34742 | + ** it must be converted to a native Win32 path prior via the Cygwin | |
| 34743 | + ** API prior to using it. | |
| 34744 | + */ | |
| 34745 | + if( winIsDriveLetterAndColon(zDir) ){ | |
| 34746 | + zConverted = winConvertFromUtf8Filename(zDir); | |
| 34747 | + if( !zConverted ){ | |
| 34748 | + OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); | |
| 34749 | + return SQLITE_IOERR_NOMEM; | |
| 34750 | + } | |
| 34751 | + if( winIsDir(zConverted) ){ | |
| 34752 | + sqlite3_snprintf(nBuf-30, zBuf, "%s", zDir); | |
| 34753 | + sqlite3_free(zConverted); | |
| 34754 | + break; | |
| 34755 | + } | |
| 34756 | + sqlite3_free(zConverted); | |
| 34757 | + }else{ | |
| 34758 | + zConverted = sqlite3MallocZero( nBuf+1 ); | |
| 34759 | + if( !zConverted ){ | |
| 34760 | + OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); | |
| 34761 | + return SQLITE_IOERR_NOMEM; | |
| 34762 | + } | |
| 34763 | + if( cygwin_conv_path( | |
| 34764 | + osIsNT() ? CCP_POSIX_TO_WIN_W : CCP_POSIX_TO_WIN_A, zDir, | |
| 34765 | + zConverted, nBuf+1)<0 ){ | |
| 34766 | + sqlite3_free(zConverted); | |
| 34767 | + OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_CONVPATH\n")); | |
| 34768 | + return winLogError(SQLITE_IOERR_CONVPATH, (DWORD)errno, | |
| 34769 | + "winGetTempname1", zDir); | |
| 34770 | + } | |
| 34771 | + if( winIsDir(zConverted) ){ | |
| 34772 | + /* At this point, we know the candidate directory exists and should | |
| 34773 | + ** be used. However, we may need to convert the string containing | |
| 34774 | + ** its name into UTF-8 (i.e. if it is UTF-16 right now). | |
| 34775 | + */ | |
| 34776 | + if( osIsNT() ){ | |
| 34777 | + char *zUtf8 = winUnicodeToUtf8(zConverted); | |
| 34778 | + if( !zUtf8 ){ | |
| 34779 | + sqlite3_free(zConverted); | |
| 34780 | + OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); | |
| 34781 | + return SQLITE_IOERR_NOMEM; | |
| 34782 | + } | |
| 34783 | + sqlite3_snprintf(nBuf-30, zBuf, "%s", zUtf8); | |
| 34784 | + sqlite3_free(zUtf8); | |
| 34785 | + sqlite3_free(zConverted); | |
| 34786 | + break; | |
| 34787 | + }else{ | |
| 34788 | + sqlite3_snprintf(nBuf-30, zBuf, "%s", zConverted); | |
| 34789 | + sqlite3_free(zConverted); | |
| 34790 | + break; | |
| 34791 | + } | |
| 34792 | + } | |
| 34793 | + sqlite3_free(zConverted); | |
| 34794 | + } | |
| 34795 | + break; | |
| 34796 | + } | |
| 34797 | + } | |
| 34798 | +#elif !SQLITE_OS_WINRT && !defined(__CYGWIN__) | |
| 34674 | 34799 | else if( osIsNT() ){ |
| 34675 | 34800 | char *zMulti; |
| 34676 | 34801 | LPWSTR zWidePath = sqlite3MallocZero( nBuf*sizeof(WCHAR) ); |
| 34677 | 34802 | if( !zWidePath ){ |
| 34678 | 34803 | sqlite3_free(zBuf); |
| @@ -34681,11 +34806,12 @@ | ||
| 34681 | 34806 | } |
| 34682 | 34807 | if( osGetTempPathW(nBuf, zWidePath)==0 ){ |
| 34683 | 34808 | sqlite3_free(zWidePath); |
| 34684 | 34809 | sqlite3_free(zBuf); |
| 34685 | 34810 | OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_GETTEMPPATH\n")); |
| 34686 | - return SQLITE_IOERR_GETTEMPPATH; | |
| 34811 | + return winLogError(SQLITE_IOERR_GETTEMPPATH, osGetLastError(), | |
| 34812 | + "winGetTempname1", 0); | |
| 34687 | 34813 | } |
| 34688 | 34814 | zMulti = winUnicodeToUtf8(zWidePath); |
| 34689 | 34815 | if( zMulti ){ |
| 34690 | 34816 | sqlite3_snprintf(nBuf-30, zBuf, "%s", zMulti); |
| 34691 | 34817 | sqlite3_free(zMulti); |
| @@ -34707,11 +34833,12 @@ | ||
| 34707 | 34833 | return SQLITE_IOERR_NOMEM; |
| 34708 | 34834 | } |
| 34709 | 34835 | if( osGetTempPathA(nBuf, zMbcsPath)==0 ){ |
| 34710 | 34836 | sqlite3_free(zBuf); |
| 34711 | 34837 | OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_GETTEMPPATH\n")); |
| 34712 | - return SQLITE_IOERR_GETTEMPPATH; | |
| 34838 | + return winLogError(SQLITE_IOERR_GETTEMPPATH, osGetLastError(), | |
| 34839 | + "winGetTempname2", 0); | |
| 34713 | 34840 | } |
| 34714 | 34841 | zUtf8 = sqlite3_win32_mbcs_to_utf8(zMbcsPath); |
| 34715 | 34842 | if( zUtf8 ){ |
| 34716 | 34843 | sqlite3_snprintf(nBuf-30, zBuf, "%s", zUtf8); |
| 34717 | 34844 | sqlite3_free(zUtf8); |
| @@ -34730,11 +34857,11 @@ | ||
| 34730 | 34857 | nLen = sqlite3Strlen30(zBuf); |
| 34731 | 34858 | |
| 34732 | 34859 | if( (nLen + sqlite3Strlen30(SQLITE_TEMP_FILE_PREFIX) + 18) >= nBuf ){ |
| 34733 | 34860 | sqlite3_free(zBuf); |
| 34734 | 34861 | OSTRACE(("TEMP-FILENAME rc=SQLITE_ERROR\n")); |
| 34735 | - return SQLITE_ERROR; | |
| 34862 | + return winLogError(SQLITE_ERROR, 0, "winGetTempname3", 0); | |
| 34736 | 34863 | } |
| 34737 | 34864 | |
| 34738 | 34865 | sqlite3_snprintf(nBuf-18-nLen, zBuf+nLen, SQLITE_TEMP_FILE_PREFIX); |
| 34739 | 34866 | |
| 34740 | 34867 | j = sqlite3Strlen30(zBuf); |
| @@ -34886,11 +35013,11 @@ | ||
| 34886 | 35013 | */ |
| 34887 | 35014 | assert( (eType!=SQLITE_OPEN_MAIN_DB) || (flags & SQLITE_OPEN_URI) || |
| 34888 | 35015 | zUtf8Name[sqlite3Strlen30(zUtf8Name)+1]==0 ); |
| 34889 | 35016 | |
| 34890 | 35017 | /* Convert the filename to the system encoding. */ |
| 34891 | - zConverted = winConvertUtf8Filename(zUtf8Name); | |
| 35018 | + zConverted = winConvertFromUtf8Filename(zUtf8Name); | |
| 34892 | 35019 | if( zConverted==0 ){ |
| 34893 | 35020 | sqlite3_free(zTmpname); |
| 34894 | 35021 | OSTRACE(("OPEN name=%s, rc=SQLITE_IOERR_NOMEM", zUtf8Name)); |
| 34895 | 35022 | return SQLITE_IOERR_NOMEM; |
| 34896 | 35023 | } |
| @@ -35087,11 +35214,11 @@ | ||
| 35087 | 35214 | UNUSED_PARAMETER(syncDir); |
| 35088 | 35215 | |
| 35089 | 35216 | SimulateIOError(return SQLITE_IOERR_DELETE); |
| 35090 | 35217 | OSTRACE(("DELETE name=%s, syncDir=%d\n", zFilename, syncDir)); |
| 35091 | 35218 | |
| 35092 | - zConverted = winConvertUtf8Filename(zFilename); | |
| 35219 | + zConverted = winConvertFromUtf8Filename(zFilename); | |
| 35093 | 35220 | if( zConverted==0 ){ |
| 35094 | 35221 | OSTRACE(("DELETE name=%s, rc=SQLITE_IOERR_NOMEM\n", zFilename)); |
| 35095 | 35222 | return SQLITE_IOERR_NOMEM; |
| 35096 | 35223 | } |
| 35097 | 35224 | if( osIsNT() ){ |
| @@ -35167,12 +35294,11 @@ | ||
| 35167 | 35294 | } |
| 35168 | 35295 | } while(1); |
| 35169 | 35296 | } |
| 35170 | 35297 | #endif |
| 35171 | 35298 | if( rc && rc!=SQLITE_IOERR_DELETE_NOENT ){ |
| 35172 | - rc = winLogError(SQLITE_IOERR_DELETE, lastErrno, | |
| 35173 | - "winDelete", zFilename); | |
| 35299 | + rc = winLogError(SQLITE_IOERR_DELETE, lastErrno, "winDelete", zFilename); | |
| 35174 | 35300 | }else{ |
| 35175 | 35301 | winLogIoerr(cnt); |
| 35176 | 35302 | } |
| 35177 | 35303 | sqlite3_free(zConverted); |
| 35178 | 35304 | OSTRACE(("DELETE name=%s, rc=%s\n", zFilename, sqlite3ErrName(rc))); |
| @@ -35196,11 +35322,11 @@ | ||
| 35196 | 35322 | |
| 35197 | 35323 | SimulateIOError( return SQLITE_IOERR_ACCESS; ); |
| 35198 | 35324 | OSTRACE(("ACCESS name=%s, flags=%x, pResOut=%p\n", |
| 35199 | 35325 | zFilename, flags, pResOut)); |
| 35200 | 35326 | |
| 35201 | - zConverted = winConvertUtf8Filename(zFilename); | |
| 35327 | + zConverted = winConvertFromUtf8Filename(zFilename); | |
| 35202 | 35328 | if( zConverted==0 ){ |
| 35203 | 35329 | OSTRACE(("ACCESS name=%s, rc=SQLITE_IOERR_NOMEM\n", zFilename)); |
| 35204 | 35330 | return SQLITE_IOERR_NOMEM; |
| 35205 | 35331 | } |
| 35206 | 35332 | if( osIsNT() ){ |
| @@ -35222,13 +35348,13 @@ | ||
| 35222 | 35348 | attr = sAttrData.dwFileAttributes; |
| 35223 | 35349 | } |
| 35224 | 35350 | }else{ |
| 35225 | 35351 | winLogIoerr(cnt); |
| 35226 | 35352 | if( lastErrno!=ERROR_FILE_NOT_FOUND && lastErrno!=ERROR_PATH_NOT_FOUND ){ |
| 35227 | - winLogError(SQLITE_IOERR_ACCESS, lastErrno, "winAccess", zFilename); | |
| 35228 | 35353 | sqlite3_free(zConverted); |
| 35229 | - return SQLITE_IOERR_ACCESS; | |
| 35354 | + return winLogError(SQLITE_IOERR_ACCESS, lastErrno, "winAccess", | |
| 35355 | + zFilename); | |
| 35230 | 35356 | }else{ |
| 35231 | 35357 | attr = INVALID_FILE_ATTRIBUTES; |
| 35232 | 35358 | } |
| 35233 | 35359 | } |
| 35234 | 35360 | } |
| @@ -35254,10 +35380,19 @@ | ||
| 35254 | 35380 | OSTRACE(("ACCESS name=%s, pResOut=%p, *pResOut=%d, rc=SQLITE_OK\n", |
| 35255 | 35381 | zFilename, pResOut, *pResOut)); |
| 35256 | 35382 | return SQLITE_OK; |
| 35257 | 35383 | } |
| 35258 | 35384 | |
| 35385 | +/* | |
| 35386 | +** Returns non-zero if the specified path name starts with a drive letter | |
| 35387 | +** followed by a colon character. | |
| 35388 | +*/ | |
| 35389 | +static BOOL winIsDriveLetterAndColon( | |
| 35390 | + const char *zPathname | |
| 35391 | +){ | |
| 35392 | + return ( sqlite3Isalpha(zPathname[0]) && zPathname[1]==':' ); | |
| 35393 | +} | |
| 35259 | 35394 | |
| 35260 | 35395 | /* |
| 35261 | 35396 | ** Returns non-zero if the specified path name should be used verbatim. If |
| 35262 | 35397 | ** non-zero is returned from this function, the calling function must simply |
| 35263 | 35398 | ** use the provided path name verbatim -OR- resolve it into a full path name |
| @@ -35281,11 +35416,11 @@ | ||
| 35281 | 35416 | ** If the path name starts with a letter and a colon it is either a volume |
| 35282 | 35417 | ** relative path or an absolute path. Callers of this function must not |
| 35283 | 35418 | ** attempt to treat it as a relative path name (i.e. they should simply use |
| 35284 | 35419 | ** it verbatim). |
| 35285 | 35420 | */ |
| 35286 | - if ( sqlite3Isalpha(zPathname[0]) && zPathname[1]==':' ){ | |
| 35421 | + if ( winIsDriveLetterAndColon(zPathname) ){ | |
| 35287 | 35422 | return TRUE; |
| 35288 | 35423 | } |
| 35289 | 35424 | |
| 35290 | 35425 | /* |
| 35291 | 35426 | ** If we get to this point, the path name should almost certainly be a purely |
| @@ -35317,28 +35452,25 @@ | ||
| 35317 | 35452 | ** for converting the relative path name to an absolute |
| 35318 | 35453 | ** one by prepending the data directory and a slash. |
| 35319 | 35454 | */ |
| 35320 | 35455 | char *zOut = sqlite3MallocZero( pVfs->mxPathname+1 ); |
| 35321 | 35456 | if( !zOut ){ |
| 35322 | - winLogError(SQLITE_IOERR_NOMEM, 0, "winFullPathname", zRelative); | |
| 35323 | 35457 | return SQLITE_IOERR_NOMEM; |
| 35324 | 35458 | } |
| 35325 | 35459 | if( cygwin_conv_path(CCP_POSIX_TO_WIN_A|CCP_RELATIVE, zRelative, zOut, |
| 35326 | 35460 | pVfs->mxPathname+1)<0 ){ |
| 35327 | - winLogError(SQLITE_CANTOPEN_FULLPATH, (DWORD)errno, "cygwin_conv_path", | |
| 35328 | - zRelative); | |
| 35329 | 35461 | sqlite3_free(zOut); |
| 35330 | - return SQLITE_CANTOPEN_FULLPATH; | |
| 35462 | + return winLogError(SQLITE_CANTOPEN_CONVPATH, (DWORD)errno, | |
| 35463 | + "winFullPathname1", zRelative); | |
| 35331 | 35464 | } |
| 35332 | 35465 | sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%s%s", |
| 35333 | 35466 | sqlite3_data_directory, winGetDirDep(), zOut); |
| 35334 | 35467 | sqlite3_free(zOut); |
| 35335 | 35468 | }else{ |
| 35336 | 35469 | if( cygwin_conv_path(CCP_POSIX_TO_WIN_A, zRelative, zFull, nFull)<0 ){ |
| 35337 | - winLogError(SQLITE_CANTOPEN_FULLPATH, (DWORD)errno, "cygwin_conv_path", | |
| 35338 | - zRelative); | |
| 35339 | - return SQLITE_CANTOPEN_FULLPATH; | |
| 35470 | + return winLogError(SQLITE_CANTOPEN_CONVPATH, (DWORD)errno, | |
| 35471 | + "winFullPathname2", zRelative); | |
| 35340 | 35472 | } |
| 35341 | 35473 | } |
| 35342 | 35474 | return SQLITE_OK; |
| 35343 | 35475 | #endif |
| 35344 | 35476 | |
| @@ -35367,11 +35499,11 @@ | ||
| 35367 | 35499 | char *zOut; |
| 35368 | 35500 | |
| 35369 | 35501 | /* If this path name begins with "/X:", where "X" is any alphabetic |
| 35370 | 35502 | ** character, discard the initial "/" from the pathname. |
| 35371 | 35503 | */ |
| 35372 | - if( zRelative[0]=='/' && sqlite3Isalpha(zRelative[1]) && zRelative[2]==':' ){ | |
| 35504 | + if( zRelative[0]=='/' && winIsDriveLetterAndColon(zRelative+1) ){ | |
| 35373 | 35505 | zRelative++; |
| 35374 | 35506 | } |
| 35375 | 35507 | |
| 35376 | 35508 | /* It's odd to simulate an io-error here, but really this is just |
| 35377 | 35509 | ** using the io-error infrastructure to test that SQLite handles this |
| @@ -35388,36 +35520,34 @@ | ||
| 35388 | 35520 | */ |
| 35389 | 35521 | sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%s%s", |
| 35390 | 35522 | sqlite3_data_directory, winGetDirDep(), zRelative); |
| 35391 | 35523 | return SQLITE_OK; |
| 35392 | 35524 | } |
| 35393 | - zConverted = winConvertUtf8Filename(zRelative); | |
| 35525 | + zConverted = winConvertFromUtf8Filename(zRelative); | |
| 35394 | 35526 | if( zConverted==0 ){ |
| 35395 | 35527 | return SQLITE_IOERR_NOMEM; |
| 35396 | 35528 | } |
| 35397 | 35529 | if( osIsNT() ){ |
| 35398 | 35530 | LPWSTR zTemp; |
| 35399 | 35531 | nByte = osGetFullPathNameW((LPCWSTR)zConverted, 0, 0, 0); |
| 35400 | 35532 | if( nByte==0 ){ |
| 35401 | - winLogError(SQLITE_ERROR, osGetLastError(), | |
| 35402 | - "GetFullPathNameW1", zConverted); | |
| 35403 | 35533 | sqlite3_free(zConverted); |
| 35404 | - return SQLITE_CANTOPEN_FULLPATH; | |
| 35534 | + return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(), | |
| 35535 | + "winFullPathname1", zRelative); | |
| 35405 | 35536 | } |
| 35406 | 35537 | nByte += 3; |
| 35407 | 35538 | zTemp = sqlite3MallocZero( nByte*sizeof(zTemp[0]) ); |
| 35408 | 35539 | if( zTemp==0 ){ |
| 35409 | 35540 | sqlite3_free(zConverted); |
| 35410 | 35541 | return SQLITE_IOERR_NOMEM; |
| 35411 | 35542 | } |
| 35412 | 35543 | nByte = osGetFullPathNameW((LPCWSTR)zConverted, nByte, zTemp, 0); |
| 35413 | 35544 | if( nByte==0 ){ |
| 35414 | - winLogError(SQLITE_ERROR, osGetLastError(), | |
| 35415 | - "GetFullPathNameW2", zConverted); | |
| 35416 | 35545 | sqlite3_free(zConverted); |
| 35417 | 35546 | sqlite3_free(zTemp); |
| 35418 | - return SQLITE_CANTOPEN_FULLPATH; | |
| 35547 | + return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(), | |
| 35548 | + "winFullPathname2", zRelative); | |
| 35419 | 35549 | } |
| 35420 | 35550 | sqlite3_free(zConverted); |
| 35421 | 35551 | zOut = winUnicodeToUtf8(zTemp); |
| 35422 | 35552 | sqlite3_free(zTemp); |
| 35423 | 35553 | } |
| @@ -35424,28 +35554,26 @@ | ||
| 35424 | 35554 | #ifdef SQLITE_WIN32_HAS_ANSI |
| 35425 | 35555 | else{ |
| 35426 | 35556 | char *zTemp; |
| 35427 | 35557 | nByte = osGetFullPathNameA((char*)zConverted, 0, 0, 0); |
| 35428 | 35558 | if( nByte==0 ){ |
| 35429 | - winLogError(SQLITE_ERROR, osGetLastError(), | |
| 35430 | - "GetFullPathNameA1", zConverted); | |
| 35431 | 35559 | sqlite3_free(zConverted); |
| 35432 | - return SQLITE_CANTOPEN_FULLPATH; | |
| 35560 | + return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(), | |
| 35561 | + "winFullPathname3", zRelative); | |
| 35433 | 35562 | } |
| 35434 | 35563 | nByte += 3; |
| 35435 | 35564 | zTemp = sqlite3MallocZero( nByte*sizeof(zTemp[0]) ); |
| 35436 | 35565 | if( zTemp==0 ){ |
| 35437 | 35566 | sqlite3_free(zConverted); |
| 35438 | 35567 | return SQLITE_IOERR_NOMEM; |
| 35439 | 35568 | } |
| 35440 | 35569 | nByte = osGetFullPathNameA((char*)zConverted, nByte, zTemp, 0); |
| 35441 | 35570 | if( nByte==0 ){ |
| 35442 | - winLogError(SQLITE_ERROR, osGetLastError(), | |
| 35443 | - "GetFullPathNameA2", zConverted); | |
| 35444 | 35571 | sqlite3_free(zConverted); |
| 35445 | 35572 | sqlite3_free(zTemp); |
| 35446 | - return SQLITE_CANTOPEN_FULLPATH; | |
| 35573 | + return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(), | |
| 35574 | + "winFullPathname4", zRelative); | |
| 35447 | 35575 | } |
| 35448 | 35576 | sqlite3_free(zConverted); |
| 35449 | 35577 | zOut = sqlite3_win32_mbcs_to_utf8(zTemp); |
| 35450 | 35578 | sqlite3_free(zTemp); |
| 35451 | 35579 | } |
| @@ -35469,11 +35597,11 @@ | ||
| 35469 | 35597 | ** Interfaces for opening a shared library, finding entry points |
| 35470 | 35598 | ** within the shared library, and closing the shared library. |
| 35471 | 35599 | */ |
| 35472 | 35600 | static void *winDlOpen(sqlite3_vfs *pVfs, const char *zFilename){ |
| 35473 | 35601 | HANDLE h; |
| 35474 | - void *zConverted = winConvertUtf8Filename(zFilename); | |
| 35602 | + void *zConverted = winConvertFromUtf8Filename(zFilename); | |
| 35475 | 35603 | UNUSED_PARAMETER(pVfs); |
| 35476 | 35604 | if( zConverted==0 ){ |
| 35477 | 35605 | return 0; |
| 35478 | 35606 | } |
| 35479 | 35607 | if( osIsNT() ){ |
| @@ -60283,10 +60411,13 @@ | ||
| 60283 | 60411 | alloc.pParse = pParse; |
| 60284 | 60412 | alloc.pIdx = pIdx; |
| 60285 | 60413 | alloc.ppRec = ppRec; |
| 60286 | 60414 | alloc.iVal = iVal; |
| 60287 | 60415 | |
| 60416 | + /* Skip over any TK_COLLATE nodes */ | |
| 60417 | + pExpr = sqlite3ExprSkipCollate(pExpr); | |
| 60418 | + | |
| 60288 | 60419 | if( !pExpr ){ |
| 60289 | 60420 | pVal = valueNew(pParse->db, &alloc); |
| 60290 | 60421 | if( pVal ){ |
| 60291 | 60422 | sqlite3VdbeMemSetNull((Mem*)pVal); |
| 60292 | 60423 | *pbOk = 1; |
| @@ -80950,11 +81081,11 @@ | ||
| 80950 | 81081 | ** SQLITE_ENABLE_STAT3 defined. The functionality of sqlite_stat3 |
| 80951 | 81082 | ** is a superset of sqlite_stat2. The sqlite_stat4 is an enhanced |
| 80952 | 81083 | ** version of sqlite_stat3 and is only available when compiled with |
| 80953 | 81084 | ** SQLITE_ENABLE_STAT4 and in SQLite versions 3.8.0 and later. It is |
| 80954 | 81085 | ** not possible to enable both STAT3 and STAT4 at the same time. If they |
| 80955 | -** are both enabled, then STAT4 is precedence. | |
| 81086 | +** are both enabled, then STAT4 takes precedence. | |
| 80956 | 81087 | ** |
| 80957 | 81088 | ** For most applications, sqlite_stat1 provides all the statisics required |
| 80958 | 81089 | ** for the query planner to make good choices. |
| 80959 | 81090 | ** |
| 80960 | 81091 | ** Format of sqlite_stat1: |
| @@ -81261,11 +81392,11 @@ | ||
| 81261 | 81392 | u8 *pSpace; /* Allocated space not yet assigned */ |
| 81262 | 81393 | int i; /* Used to iterate through p->aSample[] */ |
| 81263 | 81394 | |
| 81264 | 81395 | p->iGet = -1; |
| 81265 | 81396 | p->mxSample = mxSample; |
| 81266 | - p->nPSample = sqlite3_value_int64(argv[1])/(mxSample/3+1) + 1; | |
| 81397 | + p->nPSample = (tRowcnt)(sqlite3_value_int64(argv[1])/(mxSample/3+1) + 1); | |
| 81267 | 81398 | p->current.anLt = &p->current.anEq[nColUp]; |
| 81268 | 81399 | sqlite3_randomness(sizeof(p->iPrn), &p->iPrn); |
| 81269 | 81400 | |
| 81270 | 81401 | /* Set up the Stat4Accum.a[] and aBest[] arrays */ |
| 81271 | 81402 | p->a = (struct Stat4Sample*)&p->current.anLt[nColUp]; |
| @@ -81298,29 +81429,68 @@ | ||
| 81298 | 81429 | 0, /* xFinalize */ |
| 81299 | 81430 | "stat_init", /* zName */ |
| 81300 | 81431 | 0, /* pHash */ |
| 81301 | 81432 | 0 /* pDestructor */ |
| 81302 | 81433 | }; |
| 81434 | + | |
| 81435 | +#ifdef SQLITE_ENABLE_STAT4 | |
| 81436 | +/* | |
| 81437 | +** pNew and pOld are both candidate non-periodic samples selected for | |
| 81438 | +** the same column (pNew->iCol==pOld->iCol). Ignoring this column and | |
| 81439 | +** considering only any trailing columns and the sample hash value, this | |
| 81440 | +** function returns true if sample pNew is to be preferred over pOld. | |
| 81441 | +** In other words, if we assume that the cardinalities of the selected | |
| 81442 | +** column for pNew and pOld are equal, is pNew to be preferred over pOld. | |
| 81443 | +** | |
| 81444 | +** This function assumes that for each argument sample, the contents of | |
| 81445 | +** the anEq[] array from pSample->anEq[pSample->iCol+1] onwards are valid. | |
| 81446 | +*/ | |
| 81447 | +static int sampleIsBetterPost( | |
| 81448 | + Stat4Accum *pAccum, | |
| 81449 | + Stat4Sample *pNew, | |
| 81450 | + Stat4Sample *pOld | |
| 81451 | +){ | |
| 81452 | + int nCol = pAccum->nCol; | |
| 81453 | + int i; | |
| 81454 | + assert( pNew->iCol==pOld->iCol ); | |
| 81455 | + for(i=pNew->iCol+1; i<nCol; i++){ | |
| 81456 | + if( pNew->anEq[i]>pOld->anEq[i] ) return 1; | |
| 81457 | + if( pNew->anEq[i]<pOld->anEq[i] ) return 0; | |
| 81458 | + } | |
| 81459 | + if( pNew->iHash>pOld->iHash ) return 1; | |
| 81460 | + return 0; | |
| 81461 | +} | |
| 81462 | +#endif | |
| 81303 | 81463 | |
| 81304 | 81464 | #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 81305 | 81465 | /* |
| 81306 | 81466 | ** Return true if pNew is to be preferred over pOld. |
| 81467 | +** | |
| 81468 | +** This function assumes that for each argument sample, the contents of | |
| 81469 | +** the anEq[] array from pSample->anEq[pSample->iCol] onwards are valid. | |
| 81307 | 81470 | */ |
| 81308 | -static int sampleIsBetter(Stat4Sample *pNew, Stat4Sample *pOld){ | |
| 81471 | +static int sampleIsBetter( | |
| 81472 | + Stat4Accum *pAccum, | |
| 81473 | + Stat4Sample *pNew, | |
| 81474 | + Stat4Sample *pOld | |
| 81475 | +){ | |
| 81309 | 81476 | tRowcnt nEqNew = pNew->anEq[pNew->iCol]; |
| 81310 | 81477 | tRowcnt nEqOld = pOld->anEq[pOld->iCol]; |
| 81311 | 81478 | |
| 81312 | 81479 | assert( pOld->isPSample==0 && pNew->isPSample==0 ); |
| 81313 | 81480 | assert( IsStat4 || (pNew->iCol==0 && pOld->iCol==0) ); |
| 81314 | 81481 | |
| 81315 | - if( (nEqNew>nEqOld) | |
| 81316 | - || (nEqNew==nEqOld && pNew->iCol<pOld->iCol) | |
| 81317 | - || (nEqNew==nEqOld && pNew->iCol==pOld->iCol && pNew->iHash>pOld->iHash) | |
| 81318 | - ){ | |
| 81319 | - return 1; | |
| 81482 | + if( (nEqNew>nEqOld) ) return 1; | |
| 81483 | +#ifdef SQLITE_ENABLE_STAT4 | |
| 81484 | + if( nEqNew==nEqOld ){ | |
| 81485 | + if( pNew->iCol<pOld->iCol ) return 1; | |
| 81486 | + return (pNew->iCol==pOld->iCol && sampleIsBetterPost(pAccum, pNew, pOld)); | |
| 81320 | 81487 | } |
| 81321 | 81488 | return 0; |
| 81489 | +#else | |
| 81490 | + return (nEqNew==nEqOld && pNew->iHash>pOld->iHash); | |
| 81491 | +#endif | |
| 81322 | 81492 | } |
| 81323 | 81493 | |
| 81324 | 81494 | /* |
| 81325 | 81495 | ** Copy the contents of object (*pFrom) into (*pTo). |
| 81326 | 81496 | */ |
| @@ -81339,12 +81509,10 @@ | ||
| 81339 | 81509 | ** remove the least desirable sample from p->a[] to make room. |
| 81340 | 81510 | */ |
| 81341 | 81511 | static void sampleInsert(Stat4Accum *p, Stat4Sample *pNew, int nEqZero){ |
| 81342 | 81512 | Stat4Sample *pSample; |
| 81343 | 81513 | int i; |
| 81344 | - i64 iSeq; | |
| 81345 | - i64 iPos; | |
| 81346 | 81514 | |
| 81347 | 81515 | assert( IsStat4 || nEqZero==0 ); |
| 81348 | 81516 | |
| 81349 | 81517 | if( pNew->isPSample==0 ){ |
| 81350 | 81518 | Stat4Sample *pUpgrade = 0; |
| @@ -81357,12 +81525,13 @@ | ||
| 81357 | 81525 | ** existing sample that shares this prefix. */ |
| 81358 | 81526 | for(i=p->nSample-1; i>=0; i--){ |
| 81359 | 81527 | Stat4Sample *pOld = &p->a[i]; |
| 81360 | 81528 | if( pOld->anEq[pNew->iCol]==0 ){ |
| 81361 | 81529 | if( pOld->isPSample ) return; |
| 81362 | - assert( sampleIsBetter(pNew, pOld) ); | |
| 81363 | - if( pUpgrade==0 || sampleIsBetter(pOld, pUpgrade) ){ | |
| 81530 | + assert( pOld->iCol>pNew->iCol ); | |
| 81531 | + assert( sampleIsBetter(p, pNew, pOld) ); | |
| 81532 | + if( pUpgrade==0 || sampleIsBetter(p, pOld, pUpgrade) ){ | |
| 81364 | 81533 | pUpgrade = pOld; |
| 81365 | 81534 | } |
| 81366 | 81535 | } |
| 81367 | 81536 | } |
| 81368 | 81537 | if( pUpgrade ){ |
| @@ -81384,40 +81553,32 @@ | ||
| 81384 | 81553 | pSample->anDLt = anDLt; |
| 81385 | 81554 | pSample->anLt = anLt; |
| 81386 | 81555 | p->nSample = p->mxSample-1; |
| 81387 | 81556 | } |
| 81388 | 81557 | |
| 81389 | - /* Figure out where in the a[] array the new sample should be inserted. */ | |
| 81390 | - iSeq = pNew->anLt[p->nCol-1]; | |
| 81391 | - for(iPos=p->nSample; iPos>0; iPos--){ | |
| 81392 | - if( iSeq>p->a[iPos-1].anLt[p->nCol-1] ) break; | |
| 81393 | - } | |
| 81558 | + /* The "rows less-than" for the rowid column must be greater than that | |
| 81559 | + ** for the last sample in the p->a[] array. Otherwise, the samples would | |
| 81560 | + ** be out of order. */ | |
| 81561 | +#ifdef SQLITE_ENABLE_STAT4 | |
| 81562 | + assert( p->nSample==0 | |
| 81563 | + || pNew->anLt[p->nCol-1] > p->a[p->nSample-1].anLt[p->nCol-1] ); | |
| 81564 | +#endif | |
| 81394 | 81565 | |
| 81395 | 81566 | /* Insert the new sample */ |
| 81396 | - pSample = &p->a[iPos]; | |
| 81397 | - if( iPos!=p->nSample ){ | |
| 81398 | - Stat4Sample *pEnd = &p->a[p->nSample]; | |
| 81399 | - tRowcnt *anEq = pEnd->anEq; | |
| 81400 | - tRowcnt *anLt = pEnd->anLt; | |
| 81401 | - tRowcnt *anDLt = pEnd->anDLt; | |
| 81402 | - memmove(&p->a[iPos], &p->a[iPos+1], (p->nSample-iPos)*sizeof(p->a[0])); | |
| 81403 | - pSample->anEq = anEq; | |
| 81404 | - pSample->anDLt = anDLt; | |
| 81405 | - pSample->anLt = anLt; | |
| 81406 | - } | |
| 81407 | - p->nSample++; | |
| 81567 | + pSample = &p->a[p->nSample]; | |
| 81408 | 81568 | sampleCopy(p, pSample, pNew); |
| 81569 | + p->nSample++; | |
| 81409 | 81570 | |
| 81410 | 81571 | /* Zero the first nEqZero entries in the anEq[] array. */ |
| 81411 | 81572 | memset(pSample->anEq, 0, sizeof(tRowcnt)*nEqZero); |
| 81412 | 81573 | |
| 81413 | 81574 | find_new_min: |
| 81414 | 81575 | if( p->nSample>=p->mxSample ){ |
| 81415 | 81576 | int iMin = -1; |
| 81416 | 81577 | for(i=0; i<p->mxSample; i++){ |
| 81417 | 81578 | if( p->a[i].isPSample ) continue; |
| 81418 | - if( iMin<0 || sampleIsBetter(&p->a[iMin], &p->a[i]) ){ | |
| 81579 | + if( iMin<0 || sampleIsBetter(p, &p->a[iMin], &p->a[i]) ){ | |
| 81419 | 81580 | iMin = i; |
| 81420 | 81581 | } |
| 81421 | 81582 | } |
| 81422 | 81583 | assert( iMin>=0 ); |
| 81423 | 81584 | p->iMin = iMin; |
| @@ -81437,13 +81598,12 @@ | ||
| 81437 | 81598 | |
| 81438 | 81599 | /* Check if any samples from the aBest[] array should be pushed |
| 81439 | 81600 | ** into IndexSample.a[] at this point. */ |
| 81440 | 81601 | for(i=(p->nCol-2); i>=iChng; i--){ |
| 81441 | 81602 | Stat4Sample *pBest = &p->aBest[i]; |
| 81442 | - if( p->nSample<p->mxSample | |
| 81443 | - || sampleIsBetter(pBest, &p->a[p->iMin]) | |
| 81444 | - ){ | |
| 81603 | + pBest->anEq[i] = p->current.anEq[i]; | |
| 81604 | + if( p->nSample<p->mxSample || sampleIsBetter(p, pBest, &p->a[p->iMin]) ){ | |
| 81445 | 81605 | sampleInsert(p, pBest, i); |
| 81446 | 81606 | } |
| 81447 | 81607 | } |
| 81448 | 81608 | |
| 81449 | 81609 | /* Update the anEq[] fields of any samples already collected. */ |
| @@ -81466,11 +81626,13 @@ | ||
| 81466 | 81626 | sampleInsert(p, &p->current, 0); |
| 81467 | 81627 | p->current.isPSample = 0; |
| 81468 | 81628 | }else |
| 81469 | 81629 | |
| 81470 | 81630 | /* Or if it is a non-periodic sample. Add it in this case too. */ |
| 81471 | - if( p->nSample<p->mxSample || sampleIsBetter(&p->current, &p->a[p->iMin]) ){ | |
| 81631 | + if( p->nSample<p->mxSample | |
| 81632 | + || sampleIsBetter(p, &p->current, &p->a[p->iMin]) | |
| 81633 | + ){ | |
| 81472 | 81634 | sampleInsert(p, &p->current, 0); |
| 81473 | 81635 | } |
| 81474 | 81636 | } |
| 81475 | 81637 | #endif |
| 81476 | 81638 | } |
| @@ -81500,12 +81662,11 @@ | ||
| 81500 | 81662 | |
| 81501 | 81663 | assert( p->nCol>1 ); /* Includes rowid field */ |
| 81502 | 81664 | assert( iChng<p->nCol ); |
| 81503 | 81665 | |
| 81504 | 81666 | if( p->nRow==0 ){ |
| 81505 | - /* anEq[0] is only zero for the very first call to this function. Do | |
| 81506 | - ** appropriate initialization */ | |
| 81667 | + /* This is the first call to this function. Do initialization. */ | |
| 81507 | 81668 | for(i=0; i<p->nCol; i++) p->current.anEq[i] = 1; |
| 81508 | 81669 | }else{ |
| 81509 | 81670 | /* Second and subsequent calls get processed here */ |
| 81510 | 81671 | samplePushPrevious(p, iChng); |
| 81511 | 81672 | |
| @@ -81541,11 +81702,11 @@ | ||
| 81541 | 81702 | } |
| 81542 | 81703 | |
| 81543 | 81704 | /* Update the aBest[] array. */ |
| 81544 | 81705 | for(i=0; i<(p->nCol-1); i++){ |
| 81545 | 81706 | p->current.iCol = i; |
| 81546 | - if( i>=iChng || sampleIsBetter(&p->current, &p->aBest[i]) ){ | |
| 81707 | + if( i>=iChng || sampleIsBetterPost(p, &p->current, &p->aBest[i]) ){ | |
| 81547 | 81708 | sampleCopy(p, &p->aBest[i], &p->current); |
| 81548 | 81709 | } |
| 81549 | 81710 | } |
| 81550 | 81711 | } |
| 81551 | 81712 | #endif |
| @@ -82249,11 +82410,11 @@ | ||
| 82249 | 82410 | IndexSample *pFinal = &aSample[pIdx->nSample-1]; |
| 82250 | 82411 | int iCol; |
| 82251 | 82412 | for(iCol=0; iCol<pIdx->nColumn; iCol++){ |
| 82252 | 82413 | int i; /* Used to iterate through samples */ |
| 82253 | 82414 | tRowcnt sumEq = 0; /* Sum of the nEq values */ |
| 82254 | - int nSum = 0; /* Number of terms contributing to sumEq */ | |
| 82415 | + tRowcnt nSum = 0; /* Number of terms contributing to sumEq */ | |
| 82255 | 82416 | tRowcnt avgEq = 0; |
| 82256 | 82417 | tRowcnt nDLt = pFinal->anDLt[iCol]; |
| 82257 | 82418 | |
| 82258 | 82419 | /* Set nSum to the number of distinct (iCol+1) field prefixes that |
| 82259 | 82420 | ** occur in the stat4 table for this index before pFinal. Set |
| @@ -105797,13 +105958,13 @@ | ||
| 105797 | 105958 | /* |
| 105798 | 105959 | ** Each instance of this object holds a sequence of WhereLoop objects |
| 105799 | 105960 | ** that implement some or all of a query plan. |
| 105800 | 105961 | ** |
| 105801 | 105962 | ** Think of each WhereLoop object as a node in a graph with arcs |
| 105802 | -** showing dependences and costs for travelling between nodes. (That is | |
| 105963 | +** showing dependencies and costs for travelling between nodes. (That is | |
| 105803 | 105964 | ** not a completely accurate description because WhereLoop costs are a |
| 105804 | -** vector, not a scalar, and because dependences are many-to-one, not | |
| 105965 | +** vector, not a scalar, and because dependencies are many-to-one, not | |
| 105805 | 105966 | ** one-to-one as are graph nodes. But it is a useful visualization aid.) |
| 105806 | 105967 | ** Then a WherePath object is a path through the graph that visits some |
| 105807 | 105968 | ** or all of the WhereLoop objects once. |
| 105808 | 105969 | ** |
| 105809 | 105970 | ** The "solver" works by creating the N best WherePath objects of length |
| @@ -108165,11 +108326,16 @@ | ||
| 108165 | 108326 | && p->nSample |
| 108166 | 108327 | && OptimizationEnabled(pParse->db, SQLITE_Stat3) |
| 108167 | 108328 | ){ |
| 108168 | 108329 | UnpackedRecord *pRec = pBuilder->pRec; |
| 108169 | 108330 | tRowcnt a[2]; |
| 108170 | - u8 aff = p->pTable->aCol[p->aiColumn[0]].affinity; | |
| 108331 | + u8 aff; | |
| 108332 | + if( nEq==p->nColumn ){ | |
| 108333 | + aff = SQLITE_AFF_INTEGER; | |
| 108334 | + }else{ | |
| 108335 | + aff = p->pTable->aCol[p->aiColumn[nEq]].affinity; | |
| 108336 | + } | |
| 108171 | 108337 | |
| 108172 | 108338 | /* Variable iLower will be set to the estimate of the number of rows in |
| 108173 | 108339 | ** the index that are less than the lower bound of the range query. The |
| 108174 | 108340 | ** lower bound being the concatenation of $P and $L, where $P is the |
| 108175 | 108341 | ** key-prefix formed by the nEq values matched against the nEq left-most |
| @@ -109781,19 +109947,21 @@ | ||
| 109781 | 109947 | assert( p->rSetup>=pTemplate->rSetup ); |
| 109782 | 109948 | |
| 109783 | 109949 | if( (p->prereq & pTemplate->prereq)==p->prereq |
| 109784 | 109950 | && p->rSetup<=pTemplate->rSetup |
| 109785 | 109951 | && p->rRun<=pTemplate->rRun |
| 109952 | + && p->nOut<=pTemplate->nOut | |
| 109786 | 109953 | ){ |
| 109787 | 109954 | /* This branch taken when p is equal or better than pTemplate in |
| 109788 | - ** all of (1) dependences (2) setup-cost, and (3) run-cost. */ | |
| 109955 | + ** all of (1) dependencies (2) setup-cost, (3) run-cost, and | |
| 109956 | + ** (4) number of output rows. */ | |
| 109789 | 109957 | assert( p->rSetup==pTemplate->rSetup ); |
| 109790 | - if( p->nLTerm<pTemplate->nLTerm | |
| 109958 | + if( p->prereq==pTemplate->prereq | |
| 109959 | + && p->nLTerm<pTemplate->nLTerm | |
| 109791 | 109960 | && (p->wsFlags & WHERE_INDEXED)!=0 |
| 109792 | 109961 | && (pTemplate->wsFlags & WHERE_INDEXED)!=0 |
| 109793 | 109962 | && p->u.btree.pIndex==pTemplate->u.btree.pIndex |
| 109794 | - && p->prereq==pTemplate->prereq | |
| 109795 | 109963 | ){ |
| 109796 | 109964 | /* Overwrite an existing WhereLoop with an similar one that uses |
| 109797 | 109965 | ** more terms of the index */ |
| 109798 | 109966 | pNext = p->pNextLoop; |
| 109799 | 109967 | break; |
| @@ -109803,15 +109971,17 @@ | ||
| 109803 | 109971 | goto whereLoopInsert_noop; |
| 109804 | 109972 | } |
| 109805 | 109973 | } |
| 109806 | 109974 | if( (p->prereq & pTemplate->prereq)==pTemplate->prereq |
| 109807 | 109975 | && p->rRun>=pTemplate->rRun |
| 109976 | + && p->nOut>=pTemplate->nOut | |
| 109808 | 109977 | && ALWAYS(p->rSetup>=pTemplate->rSetup) /* See SETUP-INVARIANT above */ |
| 109809 | 109978 | ){ |
| 109810 | 109979 | /* Overwrite an existing WhereLoop with a better one: one that is |
| 109811 | - ** better at one of (1) dependences, (2) setup-cost, or (3) run-cost | |
| 109812 | - ** and is no worse in any of those categories. */ | |
| 109980 | + ** better at one of (1) dependencies, (2) setup-cost, (3) run-cost | |
| 109981 | + ** or (4) number of output rows, and is no worse in any of those | |
| 109982 | + ** categories. */ | |
| 109813 | 109983 | pNext = p->pNextLoop; |
| 109814 | 109984 | break; |
| 109815 | 109985 | } |
| 109816 | 109986 | } |
| 109817 | 109987 | |
| @@ -111512,11 +111682,11 @@ | ||
| 111512 | 111682 | if( pWInfo->nLevel>=2 |
| 111513 | 111683 | && pResultSet!=0 |
| 111514 | 111684 | && OptimizationEnabled(db, SQLITE_OmitNoopJoin) |
| 111515 | 111685 | ){ |
| 111516 | 111686 | Bitmask tabUsed = exprListTableUsage(pMaskSet, pResultSet); |
| 111517 | - if( pOrderBy ) tabUsed |= exprListTableUsage(pMaskSet, pOrderBy); | |
| 111687 | + if( sWLB.pOrderBy ) tabUsed |= exprListTableUsage(pMaskSet, sWLB.pOrderBy); | |
| 111518 | 111688 | while( pWInfo->nLevel>=2 ){ |
| 111519 | 111689 | WhereTerm *pTerm, *pEnd; |
| 111520 | 111690 | pLoop = pWInfo->a[pWInfo->nLevel-1].pWLoop; |
| 111521 | 111691 | if( (pWInfo->pTabList->a[pLoop->iTab].jointype & JT_LEFT)==0 ) break; |
| 111522 | 111692 | if( (wctrlFlags & WHERE_WANT_DISTINCT)==0 |
| @@ -117544,18 +117714,20 @@ | ||
| 117544 | 117714 | case SQLITE_IOERR_SHMMAP: zName = "SQLITE_IOERR_SHMMAP"; break; |
| 117545 | 117715 | case SQLITE_IOERR_SEEK: zName = "SQLITE_IOERR_SEEK"; break; |
| 117546 | 117716 | case SQLITE_IOERR_DELETE_NOENT: zName = "SQLITE_IOERR_DELETE_NOENT";break; |
| 117547 | 117717 | case SQLITE_IOERR_MMAP: zName = "SQLITE_IOERR_MMAP"; break; |
| 117548 | 117718 | case SQLITE_IOERR_GETTEMPPATH: zName = "SQLITE_IOERR_GETTEMPPATH"; break; |
| 117719 | + case SQLITE_IOERR_CONVPATH: zName = "SQLITE_IOERR_CONVPATH"; break; | |
| 117549 | 117720 | case SQLITE_CORRUPT: zName = "SQLITE_CORRUPT"; break; |
| 117550 | 117721 | case SQLITE_CORRUPT_VTAB: zName = "SQLITE_CORRUPT_VTAB"; break; |
| 117551 | 117722 | case SQLITE_NOTFOUND: zName = "SQLITE_NOTFOUND"; break; |
| 117552 | 117723 | case SQLITE_FULL: zName = "SQLITE_FULL"; break; |
| 117553 | 117724 | case SQLITE_CANTOPEN: zName = "SQLITE_CANTOPEN"; break; |
| 117554 | 117725 | case SQLITE_CANTOPEN_NOTEMPDIR: zName = "SQLITE_CANTOPEN_NOTEMPDIR";break; |
| 117555 | 117726 | case SQLITE_CANTOPEN_ISDIR: zName = "SQLITE_CANTOPEN_ISDIR"; break; |
| 117556 | 117727 | case SQLITE_CANTOPEN_FULLPATH: zName = "SQLITE_CANTOPEN_FULLPATH"; break; |
| 117728 | + case SQLITE_CANTOPEN_CONVPATH: zName = "SQLITE_CANTOPEN_CONVPATH"; break; | |
| 117557 | 117729 | case SQLITE_PROTOCOL: zName = "SQLITE_PROTOCOL"; break; |
| 117558 | 117730 | case SQLITE_EMPTY: zName = "SQLITE_EMPTY"; break; |
| 117559 | 117731 | case SQLITE_SCHEMA: zName = "SQLITE_SCHEMA"; break; |
| 117560 | 117732 | case SQLITE_TOOBIG: zName = "SQLITE_TOOBIG"; break; |
| 117561 | 117733 | case SQLITE_CONSTRAINT: zName = "SQLITE_CONSTRAINT"; break; |
| 117562 | 117734 |
| --- src/sqlite3.c | |
| +++ src/sqlite3.c | |
| @@ -656,11 +656,11 @@ | |
| 656 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 657 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 658 | */ |
| 659 | #define SQLITE_VERSION "3.8.1" |
| 660 | #define SQLITE_VERSION_NUMBER 3008001 |
| 661 | #define SQLITE_SOURCE_ID "2013-08-30 06:20:23 d9c018f8155ab48df8e0e02519bba50588fe49fc" |
| 662 | |
| 663 | /* |
| 664 | ** CAPI3REF: Run-Time Library Version Numbers |
| 665 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 666 | ** |
| @@ -1026,16 +1026,18 @@ | |
| 1026 | #define SQLITE_IOERR_SHMMAP (SQLITE_IOERR | (21<<8)) |
| 1027 | #define SQLITE_IOERR_SEEK (SQLITE_IOERR | (22<<8)) |
| 1028 | #define SQLITE_IOERR_DELETE_NOENT (SQLITE_IOERR | (23<<8)) |
| 1029 | #define SQLITE_IOERR_MMAP (SQLITE_IOERR | (24<<8)) |
| 1030 | #define SQLITE_IOERR_GETTEMPPATH (SQLITE_IOERR | (25<<8)) |
| 1031 | #define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8)) |
| 1032 | #define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8)) |
| 1033 | #define SQLITE_BUSY_SNAPSHOT (SQLITE_BUSY | (2<<8)) |
| 1034 | #define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8)) |
| 1035 | #define SQLITE_CANTOPEN_ISDIR (SQLITE_CANTOPEN | (2<<8)) |
| 1036 | #define SQLITE_CANTOPEN_FULLPATH (SQLITE_CANTOPEN | (3<<8)) |
| 1037 | #define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8)) |
| 1038 | #define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8)) |
| 1039 | #define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8)) |
| 1040 | #define SQLITE_READONLY_ROLLBACK (SQLITE_READONLY | (3<<8)) |
| 1041 | #define SQLITE_ABORT_ROLLBACK (SQLITE_ABORT | (2<<8)) |
| @@ -16259,11 +16261,11 @@ | |
| 16259 | assert( mem.disallow==0 ); |
| 16260 | assert( (nByte & 7)==0 ); /* EV: R-46199-30249 */ |
| 16261 | pOldHdr = sqlite3MemsysGetHeader(pPrior); |
| 16262 | pNew = sqlite3MemMalloc(nByte); |
| 16263 | if( pNew ){ |
| 16264 | memcpy(pNew, pPrior, nByte<pOldHdr->iSize ? nByte : pOldHdr->iSize); |
| 16265 | if( nByte>pOldHdr->iSize ){ |
| 16266 | randomFill(&((char*)pNew)[pOldHdr->iSize], nByte - (int)pOldHdr->iSize); |
| 16267 | } |
| 16268 | sqlite3MemFree(pPrior); |
| 16269 | } |
| @@ -23594,10 +23596,19 @@ | |
| 23594 | if( aSyscall[i].pCurrent!=0 ) return aSyscall[i].zName; |
| 23595 | } |
| 23596 | return 0; |
| 23597 | } |
| 23598 | |
| 23599 | /* |
| 23600 | ** Invoke open(). Do so multiple times, until it either succeeds or |
| 23601 | ** fails for some reason other than EINTR. |
| 23602 | ** |
| 23603 | ** If the file creation mode "m" is 0 then set it to the default for |
| @@ -23624,11 +23635,11 @@ | |
| 23624 | #endif |
| 23625 | if( fd<0 ){ |
| 23626 | if( errno==EINTR ) continue; |
| 23627 | break; |
| 23628 | } |
| 23629 | if( fd>2 ) break; |
| 23630 | osClose(fd); |
| 23631 | sqlite3_log(SQLITE_WARNING, |
| 23632 | "attempt to open \"%s\" as file descriptor %d", z, fd); |
| 23633 | fd = -1; |
| 23634 | if( osOpen("/dev/null", f, m)<0 ) break; |
| @@ -28373,10 +28384,11 @@ | |
| 28373 | ** If no suitable temporary file directory can be found, return NULL. |
| 28374 | */ |
| 28375 | static const char *unixTempFileDir(void){ |
| 28376 | static const char *azDirs[] = { |
| 28377 | 0, |
| 28378 | 0, |
| 28379 | "/var/tmp", |
| 28380 | "/usr/tmp", |
| 28381 | "/tmp", |
| 28382 | 0 /* List terminator */ |
| @@ -28384,11 +28396,12 @@ | |
| 28384 | unsigned int i; |
| 28385 | struct stat buf; |
| 28386 | const char *zDir = 0; |
| 28387 | |
| 28388 | azDirs[0] = sqlite3_temp_directory; |
| 28389 | if( !azDirs[1] ) azDirs[1] = getenv("TMPDIR"); |
| 28390 | for(i=0; i<sizeof(azDirs)/sizeof(azDirs[0]); zDir=azDirs[i++]){ |
| 28391 | if( zDir==0 ) continue; |
| 28392 | if( osStat(zDir, &buf) ) continue; |
| 28393 | if( !S_ISDIR(buf.st_mode) ) continue; |
| 28394 | if( osAccess(zDir, 07) ) continue; |
| @@ -30497,11 +30510,11 @@ | |
| 30497 | */ |
| 30498 | #if SQLITE_OS_WIN /* This file is used for Windows only */ |
| 30499 | |
| 30500 | #ifdef __CYGWIN__ |
| 30501 | # include <sys/cygwin.h> |
| 30502 | /* # include <errno.h> */ |
| 30503 | #endif |
| 30504 | |
| 30505 | /* |
| 30506 | ** Include code that is common to all os_*.c files |
| 30507 | */ |
| @@ -30726,22 +30739,31 @@ | |
| 30726 | |
| 30727 | /* |
| 30728 | ** Are most of the Win32 ANSI APIs available (i.e. with certain exceptions |
| 30729 | ** based on the sub-platform)? |
| 30730 | */ |
| 30731 | #if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT |
| 30732 | # define SQLITE_WIN32_HAS_ANSI |
| 30733 | #endif |
| 30734 | |
| 30735 | /* |
| 30736 | ** Are most of the Win32 Unicode APIs available (i.e. with certain exceptions |
| 30737 | ** based on the sub-platform)? |
| 30738 | */ |
| 30739 | #if SQLITE_OS_WINCE || SQLITE_OS_WINNT || SQLITE_OS_WINRT |
| 30740 | # define SQLITE_WIN32_HAS_WIDE |
| 30741 | #endif |
| 30742 | |
| 30743 | /* |
| 30744 | ** Maximum pathname length (in chars) for Win32. This should normally be |
| 30745 | ** MAX_PATH. |
| 30746 | */ |
| 30747 | #ifndef SQLITE_WIN32_MAX_PATH_CHARS |
| @@ -30849,11 +30871,11 @@ | |
| 30849 | #ifndef FILE_ATTRIBUTE_MASK |
| 30850 | # define FILE_ATTRIBUTE_MASK (0x0003FFF7) |
| 30851 | #endif |
| 30852 | |
| 30853 | #ifndef SQLITE_OMIT_WAL |
| 30854 | /* Forward references */ |
| 30855 | typedef struct winShm winShm; /* A connection to shared-memory */ |
| 30856 | typedef struct winShmNode winShmNode; /* A region of shared-memory */ |
| 30857 | #endif |
| 30858 | |
| 30859 | /* |
| @@ -31804,11 +31826,11 @@ | |
| 31804 | ** API as long as we don't call it when running Win95/98/ME. A call to |
| 31805 | ** this routine is used to determine if the host is Win95/98/ME or |
| 31806 | ** WinNT/2K/XP so that we will know whether or not we can safely call |
| 31807 | ** the LockFileEx() API. |
| 31808 | */ |
| 31809 | #if SQLITE_OS_WINCE || SQLITE_OS_WINRT |
| 31810 | # define osIsNT() (1) |
| 31811 | #elif !defined(SQLITE_WIN32_HAS_WIDE) |
| 31812 | # define osIsNT() (0) |
| 31813 | #else |
| 31814 | static int osIsNT(void){ |
| @@ -32449,14 +32471,13 @@ | |
| 32449 | |
| 32450 | /* Create/open the named mutex */ |
| 32451 | pFile->hMutex = osCreateMutexW(NULL, FALSE, zName); |
| 32452 | if (!pFile->hMutex){ |
| 32453 | pFile->lastErrno = osGetLastError(); |
| 32454 | winLogError(SQLITE_IOERR, pFile->lastErrno, |
| 32455 | "winceCreateLock1", zFilename); |
| 32456 | sqlite3_free(zName); |
| 32457 | return SQLITE_IOERR; |
| 32458 | } |
| 32459 | |
| 32460 | /* Acquire the mutex before continuing */ |
| 32461 | winceMutexAcquire(pFile->hMutex); |
| 32462 | |
| @@ -32788,11 +32809,11 @@ | |
| 32788 | |
| 32789 | if( (dwRet==INVALID_SET_FILE_POINTER |
| 32790 | && ((lastErrno = osGetLastError())!=NO_ERROR)) ){ |
| 32791 | pFile->lastErrno = lastErrno; |
| 32792 | winLogError(SQLITE_IOERR_SEEK, pFile->lastErrno, |
| 32793 | "winSeekFile", pFile->zPath); |
| 32794 | OSTRACE(("SEEK file=%p, rc=SQLITE_IOERR_SEEK\n", pFile->h)); |
| 32795 | return 1; |
| 32796 | } |
| 32797 | |
| 32798 | OSTRACE(("SEEK file=%p, rc=SQLITE_OK\n", pFile->h)); |
| @@ -32809,11 +32830,11 @@ | |
| 32809 | bRet = osSetFilePointerEx(pFile->h, x, 0, FILE_BEGIN); |
| 32810 | |
| 32811 | if(!bRet){ |
| 32812 | pFile->lastErrno = osGetLastError(); |
| 32813 | winLogError(SQLITE_IOERR_SEEK, pFile->lastErrno, |
| 32814 | "winSeekFile", pFile->zPath); |
| 32815 | OSTRACE(("SEEK file=%p, rc=SQLITE_IOERR_SEEK\n", pFile->h)); |
| 32816 | return 1; |
| 32817 | } |
| 32818 | |
| 32819 | OSTRACE(("SEEK file=%p, rc=SQLITE_OK\n", pFile->h)); |
| @@ -32820,11 +32841,12 @@ | |
| 32820 | return 0; |
| 32821 | #endif |
| 32822 | } |
| 32823 | |
| 32824 | #if SQLITE_MAX_MMAP_SIZE>0 |
| 32825 | /* Forward references to VFS methods */ |
| 32826 | static int winUnmapfile(winFile*); |
| 32827 | #endif |
| 32828 | |
| 32829 | /* |
| 32830 | ** Close a file. |
| @@ -32941,11 +32963,11 @@ | |
| 32941 | DWORD lastErrno; |
| 32942 | if( winRetryIoerr(&nRetry, &lastErrno) ) continue; |
| 32943 | pFile->lastErrno = lastErrno; |
| 32944 | OSTRACE(("READ file=%p, rc=SQLITE_IOERR_READ\n", pFile->h)); |
| 32945 | return winLogError(SQLITE_IOERR_READ, pFile->lastErrno, |
| 32946 | "winRead", pFile->zPath); |
| 32947 | } |
| 32948 | winLogIoerr(nRetry); |
| 32949 | if( nRead<(DWORD)amt ){ |
| 32950 | /* Unread parts of the buffer must be zero-filled */ |
| 32951 | memset(&((char*)pBuf)[nRead], 0, amt-nRead); |
| @@ -33047,15 +33069,16 @@ | |
| 33047 | |
| 33048 | if( rc ){ |
| 33049 | if( ( pFile->lastErrno==ERROR_HANDLE_DISK_FULL ) |
| 33050 | || ( pFile->lastErrno==ERROR_DISK_FULL )){ |
| 33051 | OSTRACE(("WRITE file=%p, rc=SQLITE_FULL\n", pFile->h)); |
| 33052 | return SQLITE_FULL; |
| 33053 | } |
| 33054 | OSTRACE(("WRITE file=%p, rc=SQLITE_IOERR_WRITE\n", pFile->h)); |
| 33055 | return winLogError(SQLITE_IOERR_WRITE, pFile->lastErrno, |
| 33056 | "winWrite", pFile->zPath); |
| 33057 | }else{ |
| 33058 | winLogIoerr(nRetry); |
| 33059 | } |
| 33060 | OSTRACE(("WRITE file=%p, rc=SQLITE_OK\n", pFile->h)); |
| 33061 | return SQLITE_OK; |
| @@ -33175,11 +33198,11 @@ | |
| 33175 | return SQLITE_OK; |
| 33176 | }else{ |
| 33177 | pFile->lastErrno = osGetLastError(); |
| 33178 | OSTRACE(("SYNC file=%p, rc=SQLITE_IOERR_FSYNC\n", pFile->h)); |
| 33179 | return winLogError(SQLITE_IOERR_FSYNC, pFile->lastErrno, |
| 33180 | "winSync", pFile->zPath); |
| 33181 | } |
| 33182 | #endif |
| 33183 | } |
| 33184 | |
| 33185 | /* |
| @@ -33216,11 +33239,11 @@ | |
| 33216 | *pSize = (((sqlite3_int64)upperBits)<<32) + lowerBits; |
| 33217 | if( (lowerBits == INVALID_FILE_SIZE) |
| 33218 | && ((lastErrno = osGetLastError())!=NO_ERROR) ){ |
| 33219 | pFile->lastErrno = lastErrno; |
| 33220 | rc = winLogError(SQLITE_IOERR_FSTAT, pFile->lastErrno, |
| 33221 | "winFileSize", pFile->zPath); |
| 33222 | } |
| 33223 | } |
| 33224 | #endif |
| 33225 | OSTRACE(("SIZE file=%p, pSize=%p, *pSize=%lld, rc=%s\n", |
| 33226 | pFile->h, pSize, *pSize, sqlite3ErrName(rc))); |
| @@ -33311,11 +33334,11 @@ | |
| 33311 | } |
| 33312 | #endif |
| 33313 | if( res==0 && ((lastErrno = osGetLastError())!=ERROR_NOT_LOCKED) ){ |
| 33314 | pFile->lastErrno = lastErrno; |
| 33315 | winLogError(SQLITE_IOERR_UNLOCK, pFile->lastErrno, |
| 33316 | "winUnlockReadLock", pFile->zPath); |
| 33317 | } |
| 33318 | OSTRACE(("READ-UNLOCK file=%p, rc=%s\n", pFile->h, sqlite3ErrName(res))); |
| 33319 | return res; |
| 33320 | } |
| 33321 | |
| @@ -33524,11 +33547,11 @@ | |
| 33524 | winUnlockFile(&pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0); |
| 33525 | if( locktype==SHARED_LOCK && !winGetReadLock(pFile) ){ |
| 33526 | /* This should never happen. We should always be able to |
| 33527 | ** reacquire the read lock */ |
| 33528 | rc = winLogError(SQLITE_IOERR_UNLOCK, osGetLastError(), |
| 33529 | "winUnlock", pFile->zPath); |
| 33530 | } |
| 33531 | } |
| 33532 | if( type>=RESERVED_LOCK ){ |
| 33533 | winUnlockFile(&pFile->h, RESERVED_BYTE, 0, 1, 0); |
| 33534 | } |
| @@ -33558,15 +33581,14 @@ | |
| 33558 | }else{ |
| 33559 | pFile->ctrlFlags |= mask; |
| 33560 | } |
| 33561 | } |
| 33562 | |
| 33563 | /* Forward declaration */ |
| 33564 | static int winGetTempname(sqlite3_vfs *, char **); |
| 33565 | #if SQLITE_MAX_MMAP_SIZE>0 |
| 33566 | static int winMapfile(winFile*, sqlite3_int64); |
| 33567 | #endif |
| 33568 | |
| 33569 | /* |
| 33570 | ** Control and query of the open file handle. |
| 33571 | */ |
| 33572 | static int winFileControl(sqlite3_file *id, int op, void *pArg){ |
| @@ -33640,11 +33662,11 @@ | |
| 33640 | char *zTFile = 0; |
| 33641 | int rc = winGetTempname(pFile->pVfs, &zTFile); |
| 33642 | if( rc==SQLITE_OK ){ |
| 33643 | *(char**)pArg = zTFile; |
| 33644 | } |
| 33645 | OSTRACE(("FCNTL file=%p, rc=%d\n", pFile->h, rc)); |
| 33646 | return rc; |
| 33647 | } |
| 33648 | #if SQLITE_MAX_MMAP_SIZE>0 |
| 33649 | case SQLITE_FCNTL_MMAP_SIZE: { |
| 33650 | i64 newLimit = *(i64*)pArg; |
| @@ -33658,11 +33680,11 @@ | |
| 33658 | if( pFile->mmapSize>0 ){ |
| 33659 | (void)winUnmapfile(pFile); |
| 33660 | rc = winMapfile(pFile, -1); |
| 33661 | } |
| 33662 | } |
| 33663 | OSTRACE(("FCNTL file=%p, rc=%d\n", pFile->h, rc)); |
| 33664 | return rc; |
| 33665 | } |
| 33666 | #endif |
| 33667 | } |
| 33668 | OSTRACE(("FCNTL file=%p, rc=SQLITE_NOTFOUND\n", pFile->h)); |
| @@ -33974,11 +33996,11 @@ | |
| 33974 | */ |
| 33975 | if( winShmSystemLock(pShmNode, _SHM_WRLCK, WIN_SHM_DMS, 1)==SQLITE_OK ){ |
| 33976 | rc = winTruncate((sqlite3_file *)&pShmNode->hFile, 0); |
| 33977 | if( rc!=SQLITE_OK ){ |
| 33978 | rc = winLogError(SQLITE_IOERR_SHMOPEN, osGetLastError(), |
| 33979 | "winOpenShm", pDbFd->zPath); |
| 33980 | } |
| 33981 | } |
| 33982 | if( rc==SQLITE_OK ){ |
| 33983 | winShmSystemLock(pShmNode, _SHM_UNLCK, WIN_SHM_DMS, 1); |
| 33984 | rc = winShmSystemLock(pShmNode, _SHM_RDLCK, WIN_SHM_DMS, 1); |
| @@ -34234,11 +34256,11 @@ | |
| 34234 | ** large enough to contain the requested region). |
| 34235 | */ |
| 34236 | rc = winFileSize((sqlite3_file *)&pShmNode->hFile, &sz); |
| 34237 | if( rc!=SQLITE_OK ){ |
| 34238 | rc = winLogError(SQLITE_IOERR_SHMSIZE, osGetLastError(), |
| 34239 | "winShmMap1", pDbFd->zPath); |
| 34240 | goto shmpage_out; |
| 34241 | } |
| 34242 | |
| 34243 | if( sz<nByte ){ |
| 34244 | /* The requested memory region does not exist. If isWrite is set to |
| @@ -34249,11 +34271,11 @@ | |
| 34249 | */ |
| 34250 | if( !isWrite ) goto shmpage_out; |
| 34251 | rc = winTruncate((sqlite3_file *)&pShmNode->hFile, nByte); |
| 34252 | if( rc!=SQLITE_OK ){ |
| 34253 | rc = winLogError(SQLITE_IOERR_SHMSIZE, osGetLastError(), |
| 34254 | "winShmMap2", pDbFd->zPath); |
| 34255 | goto shmpage_out; |
| 34256 | } |
| 34257 | } |
| 34258 | |
| 34259 | /* Map the requested memory region into this processes address space. */ |
| @@ -34303,11 +34325,11 @@ | |
| 34303 | szRegion, pMap ? "ok" : "failed")); |
| 34304 | } |
| 34305 | if( !pMap ){ |
| 34306 | pShmNode->lastErrno = osGetLastError(); |
| 34307 | rc = winLogError(SQLITE_IOERR_SHMMAP, pShmNode->lastErrno, |
| 34308 | "winShmMap3", pDbFd->zPath); |
| 34309 | if( hMap ) osCloseHandle(hMap); |
| 34310 | goto shmpage_out; |
| 34311 | } |
| 34312 | |
| 34313 | pShmNode->aRegion[pShmNode->nRegion].pMap = pMap; |
| @@ -34351,11 +34373,11 @@ | |
| 34351 | pFile->lastErrno = osGetLastError(); |
| 34352 | OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, pMapRegion=%p, " |
| 34353 | "rc=SQLITE_IOERR_MMAP\n", osGetCurrentProcessId(), pFile, |
| 34354 | pFile->pMapRegion)); |
| 34355 | return winLogError(SQLITE_IOERR_MMAP, pFile->lastErrno, |
| 34356 | "winUnmap1", pFile->zPath); |
| 34357 | } |
| 34358 | pFile->pMapRegion = 0; |
| 34359 | pFile->mmapSize = 0; |
| 34360 | pFile->mmapSizeActual = 0; |
| 34361 | } |
| @@ -34363,11 +34385,11 @@ | |
| 34363 | if( !osCloseHandle(pFile->hMap) ){ |
| 34364 | pFile->lastErrno = osGetLastError(); |
| 34365 | OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, hMap=%p, rc=SQLITE_IOERR_MMAP\n", |
| 34366 | osGetCurrentProcessId(), pFile, pFile->hMap)); |
| 34367 | return winLogError(SQLITE_IOERR_MMAP, pFile->lastErrno, |
| 34368 | "winUnmap2", pFile->zPath); |
| 34369 | } |
| 34370 | pFile->hMap = NULL; |
| 34371 | } |
| 34372 | OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, rc=SQLITE_OK\n", |
| 34373 | osGetCurrentProcessId(), pFile)); |
| @@ -34438,14 +34460,14 @@ | |
| 34438 | (DWORD)(nMap & 0xffffffff), NULL); |
| 34439 | #endif |
| 34440 | if( pFd->hMap==NULL ){ |
| 34441 | pFd->lastErrno = osGetLastError(); |
| 34442 | rc = winLogError(SQLITE_IOERR_MMAP, pFd->lastErrno, |
| 34443 | "winMapfile", pFd->zPath); |
| 34444 | /* Log the error, but continue normal operation using xRead/xWrite */ |
| 34445 | OSTRACE(("MAP-FILE-CREATE pid=%lu, pFile=%p, rc=SQLITE_IOERR_MMAP\n", |
| 34446 | osGetCurrentProcessId(), pFd)); |
| 34447 | return SQLITE_OK; |
| 34448 | } |
| 34449 | assert( (nMap % winSysInfo.dwPageSize)==0 ); |
| 34450 | assert( sizeof(SIZE_T)==sizeof(sqlite3_int64) || nMap<=0xffffffff ); |
| 34451 | #if SQLITE_OS_WINRT |
| @@ -34455,14 +34477,15 @@ | |
| 34455 | #endif |
| 34456 | if( pNew==NULL ){ |
| 34457 | osCloseHandle(pFd->hMap); |
| 34458 | pFd->hMap = NULL; |
| 34459 | pFd->lastErrno = osGetLastError(); |
| 34460 | winLogError(SQLITE_IOERR_MMAP, pFd->lastErrno, |
| 34461 | "winMapfile", pFd->zPath); |
| 34462 | OSTRACE(("MAP-FILE-MAP pid=%lu, pFile=%p, rc=SQLITE_IOERR_MMAP\n", |
| 34463 | osGetCurrentProcessId(), pFd)); |
| 34464 | return SQLITE_OK; |
| 34465 | } |
| 34466 | pFd->pMapRegion = pNew; |
| 34467 | pFd->mmapSize = nMap; |
| 34468 | pFd->mmapSizeActual = nMap; |
| @@ -34596,18 +34619,37 @@ | |
| 34596 | **************************** sqlite3_vfs methods **************************** |
| 34597 | ** |
| 34598 | ** This division contains the implementation of methods on the |
| 34599 | ** sqlite3_vfs object. |
| 34600 | */ |
| 34601 | |
| 34602 | /* |
| 34603 | ** Convert a UTF-8 filename into whatever form the underlying |
| 34604 | ** operating system wants filenames in. Space to hold the result |
| 34605 | ** is obtained from malloc and must be freed by the calling |
| 34606 | ** function. |
| 34607 | */ |
| 34608 | static void *winConvertUtf8Filename(const char *zFilename){ |
| 34609 | void *zConverted = 0; |
| 34610 | if( osIsNT() ){ |
| 34611 | zConverted = winUtf8ToUnicode(zFilename); |
| 34612 | } |
| 34613 | #ifdef SQLITE_WIN32_HAS_ANSI |
| @@ -34668,11 +34710,94 @@ | |
| 34668 | if( sqlite3_temp_directory ){ |
| 34669 | sqlite3_snprintf(nBuf-30, zBuf, "%s%s", sqlite3_temp_directory, |
| 34670 | winEndsInDirSep(sqlite3_temp_directory) ? "" : |
| 34671 | winGetDirDep()); |
| 34672 | } |
| 34673 | #if !SQLITE_OS_WINRT |
| 34674 | else if( osIsNT() ){ |
| 34675 | char *zMulti; |
| 34676 | LPWSTR zWidePath = sqlite3MallocZero( nBuf*sizeof(WCHAR) ); |
| 34677 | if( !zWidePath ){ |
| 34678 | sqlite3_free(zBuf); |
| @@ -34681,11 +34806,12 @@ | |
| 34681 | } |
| 34682 | if( osGetTempPathW(nBuf, zWidePath)==0 ){ |
| 34683 | sqlite3_free(zWidePath); |
| 34684 | sqlite3_free(zBuf); |
| 34685 | OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_GETTEMPPATH\n")); |
| 34686 | return SQLITE_IOERR_GETTEMPPATH; |
| 34687 | } |
| 34688 | zMulti = winUnicodeToUtf8(zWidePath); |
| 34689 | if( zMulti ){ |
| 34690 | sqlite3_snprintf(nBuf-30, zBuf, "%s", zMulti); |
| 34691 | sqlite3_free(zMulti); |
| @@ -34707,11 +34833,12 @@ | |
| 34707 | return SQLITE_IOERR_NOMEM; |
| 34708 | } |
| 34709 | if( osGetTempPathA(nBuf, zMbcsPath)==0 ){ |
| 34710 | sqlite3_free(zBuf); |
| 34711 | OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_GETTEMPPATH\n")); |
| 34712 | return SQLITE_IOERR_GETTEMPPATH; |
| 34713 | } |
| 34714 | zUtf8 = sqlite3_win32_mbcs_to_utf8(zMbcsPath); |
| 34715 | if( zUtf8 ){ |
| 34716 | sqlite3_snprintf(nBuf-30, zBuf, "%s", zUtf8); |
| 34717 | sqlite3_free(zUtf8); |
| @@ -34730,11 +34857,11 @@ | |
| 34730 | nLen = sqlite3Strlen30(zBuf); |
| 34731 | |
| 34732 | if( (nLen + sqlite3Strlen30(SQLITE_TEMP_FILE_PREFIX) + 18) >= nBuf ){ |
| 34733 | sqlite3_free(zBuf); |
| 34734 | OSTRACE(("TEMP-FILENAME rc=SQLITE_ERROR\n")); |
| 34735 | return SQLITE_ERROR; |
| 34736 | } |
| 34737 | |
| 34738 | sqlite3_snprintf(nBuf-18-nLen, zBuf+nLen, SQLITE_TEMP_FILE_PREFIX); |
| 34739 | |
| 34740 | j = sqlite3Strlen30(zBuf); |
| @@ -34886,11 +35013,11 @@ | |
| 34886 | */ |
| 34887 | assert( (eType!=SQLITE_OPEN_MAIN_DB) || (flags & SQLITE_OPEN_URI) || |
| 34888 | zUtf8Name[sqlite3Strlen30(zUtf8Name)+1]==0 ); |
| 34889 | |
| 34890 | /* Convert the filename to the system encoding. */ |
| 34891 | zConverted = winConvertUtf8Filename(zUtf8Name); |
| 34892 | if( zConverted==0 ){ |
| 34893 | sqlite3_free(zTmpname); |
| 34894 | OSTRACE(("OPEN name=%s, rc=SQLITE_IOERR_NOMEM", zUtf8Name)); |
| 34895 | return SQLITE_IOERR_NOMEM; |
| 34896 | } |
| @@ -35087,11 +35214,11 @@ | |
| 35087 | UNUSED_PARAMETER(syncDir); |
| 35088 | |
| 35089 | SimulateIOError(return SQLITE_IOERR_DELETE); |
| 35090 | OSTRACE(("DELETE name=%s, syncDir=%d\n", zFilename, syncDir)); |
| 35091 | |
| 35092 | zConverted = winConvertUtf8Filename(zFilename); |
| 35093 | if( zConverted==0 ){ |
| 35094 | OSTRACE(("DELETE name=%s, rc=SQLITE_IOERR_NOMEM\n", zFilename)); |
| 35095 | return SQLITE_IOERR_NOMEM; |
| 35096 | } |
| 35097 | if( osIsNT() ){ |
| @@ -35167,12 +35294,11 @@ | |
| 35167 | } |
| 35168 | } while(1); |
| 35169 | } |
| 35170 | #endif |
| 35171 | if( rc && rc!=SQLITE_IOERR_DELETE_NOENT ){ |
| 35172 | rc = winLogError(SQLITE_IOERR_DELETE, lastErrno, |
| 35173 | "winDelete", zFilename); |
| 35174 | }else{ |
| 35175 | winLogIoerr(cnt); |
| 35176 | } |
| 35177 | sqlite3_free(zConverted); |
| 35178 | OSTRACE(("DELETE name=%s, rc=%s\n", zFilename, sqlite3ErrName(rc))); |
| @@ -35196,11 +35322,11 @@ | |
| 35196 | |
| 35197 | SimulateIOError( return SQLITE_IOERR_ACCESS; ); |
| 35198 | OSTRACE(("ACCESS name=%s, flags=%x, pResOut=%p\n", |
| 35199 | zFilename, flags, pResOut)); |
| 35200 | |
| 35201 | zConverted = winConvertUtf8Filename(zFilename); |
| 35202 | if( zConverted==0 ){ |
| 35203 | OSTRACE(("ACCESS name=%s, rc=SQLITE_IOERR_NOMEM\n", zFilename)); |
| 35204 | return SQLITE_IOERR_NOMEM; |
| 35205 | } |
| 35206 | if( osIsNT() ){ |
| @@ -35222,13 +35348,13 @@ | |
| 35222 | attr = sAttrData.dwFileAttributes; |
| 35223 | } |
| 35224 | }else{ |
| 35225 | winLogIoerr(cnt); |
| 35226 | if( lastErrno!=ERROR_FILE_NOT_FOUND && lastErrno!=ERROR_PATH_NOT_FOUND ){ |
| 35227 | winLogError(SQLITE_IOERR_ACCESS, lastErrno, "winAccess", zFilename); |
| 35228 | sqlite3_free(zConverted); |
| 35229 | return SQLITE_IOERR_ACCESS; |
| 35230 | }else{ |
| 35231 | attr = INVALID_FILE_ATTRIBUTES; |
| 35232 | } |
| 35233 | } |
| 35234 | } |
| @@ -35254,10 +35380,19 @@ | |
| 35254 | OSTRACE(("ACCESS name=%s, pResOut=%p, *pResOut=%d, rc=SQLITE_OK\n", |
| 35255 | zFilename, pResOut, *pResOut)); |
| 35256 | return SQLITE_OK; |
| 35257 | } |
| 35258 | |
| 35259 | |
| 35260 | /* |
| 35261 | ** Returns non-zero if the specified path name should be used verbatim. If |
| 35262 | ** non-zero is returned from this function, the calling function must simply |
| 35263 | ** use the provided path name verbatim -OR- resolve it into a full path name |
| @@ -35281,11 +35416,11 @@ | |
| 35281 | ** If the path name starts with a letter and a colon it is either a volume |
| 35282 | ** relative path or an absolute path. Callers of this function must not |
| 35283 | ** attempt to treat it as a relative path name (i.e. they should simply use |
| 35284 | ** it verbatim). |
| 35285 | */ |
| 35286 | if ( sqlite3Isalpha(zPathname[0]) && zPathname[1]==':' ){ |
| 35287 | return TRUE; |
| 35288 | } |
| 35289 | |
| 35290 | /* |
| 35291 | ** If we get to this point, the path name should almost certainly be a purely |
| @@ -35317,28 +35452,25 @@ | |
| 35317 | ** for converting the relative path name to an absolute |
| 35318 | ** one by prepending the data directory and a slash. |
| 35319 | */ |
| 35320 | char *zOut = sqlite3MallocZero( pVfs->mxPathname+1 ); |
| 35321 | if( !zOut ){ |
| 35322 | winLogError(SQLITE_IOERR_NOMEM, 0, "winFullPathname", zRelative); |
| 35323 | return SQLITE_IOERR_NOMEM; |
| 35324 | } |
| 35325 | if( cygwin_conv_path(CCP_POSIX_TO_WIN_A|CCP_RELATIVE, zRelative, zOut, |
| 35326 | pVfs->mxPathname+1)<0 ){ |
| 35327 | winLogError(SQLITE_CANTOPEN_FULLPATH, (DWORD)errno, "cygwin_conv_path", |
| 35328 | zRelative); |
| 35329 | sqlite3_free(zOut); |
| 35330 | return SQLITE_CANTOPEN_FULLPATH; |
| 35331 | } |
| 35332 | sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%s%s", |
| 35333 | sqlite3_data_directory, winGetDirDep(), zOut); |
| 35334 | sqlite3_free(zOut); |
| 35335 | }else{ |
| 35336 | if( cygwin_conv_path(CCP_POSIX_TO_WIN_A, zRelative, zFull, nFull)<0 ){ |
| 35337 | winLogError(SQLITE_CANTOPEN_FULLPATH, (DWORD)errno, "cygwin_conv_path", |
| 35338 | zRelative); |
| 35339 | return SQLITE_CANTOPEN_FULLPATH; |
| 35340 | } |
| 35341 | } |
| 35342 | return SQLITE_OK; |
| 35343 | #endif |
| 35344 | |
| @@ -35367,11 +35499,11 @@ | |
| 35367 | char *zOut; |
| 35368 | |
| 35369 | /* If this path name begins with "/X:", where "X" is any alphabetic |
| 35370 | ** character, discard the initial "/" from the pathname. |
| 35371 | */ |
| 35372 | if( zRelative[0]=='/' && sqlite3Isalpha(zRelative[1]) && zRelative[2]==':' ){ |
| 35373 | zRelative++; |
| 35374 | } |
| 35375 | |
| 35376 | /* It's odd to simulate an io-error here, but really this is just |
| 35377 | ** using the io-error infrastructure to test that SQLite handles this |
| @@ -35388,36 +35520,34 @@ | |
| 35388 | */ |
| 35389 | sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%s%s", |
| 35390 | sqlite3_data_directory, winGetDirDep(), zRelative); |
| 35391 | return SQLITE_OK; |
| 35392 | } |
| 35393 | zConverted = winConvertUtf8Filename(zRelative); |
| 35394 | if( zConverted==0 ){ |
| 35395 | return SQLITE_IOERR_NOMEM; |
| 35396 | } |
| 35397 | if( osIsNT() ){ |
| 35398 | LPWSTR zTemp; |
| 35399 | nByte = osGetFullPathNameW((LPCWSTR)zConverted, 0, 0, 0); |
| 35400 | if( nByte==0 ){ |
| 35401 | winLogError(SQLITE_ERROR, osGetLastError(), |
| 35402 | "GetFullPathNameW1", zConverted); |
| 35403 | sqlite3_free(zConverted); |
| 35404 | return SQLITE_CANTOPEN_FULLPATH; |
| 35405 | } |
| 35406 | nByte += 3; |
| 35407 | zTemp = sqlite3MallocZero( nByte*sizeof(zTemp[0]) ); |
| 35408 | if( zTemp==0 ){ |
| 35409 | sqlite3_free(zConverted); |
| 35410 | return SQLITE_IOERR_NOMEM; |
| 35411 | } |
| 35412 | nByte = osGetFullPathNameW((LPCWSTR)zConverted, nByte, zTemp, 0); |
| 35413 | if( nByte==0 ){ |
| 35414 | winLogError(SQLITE_ERROR, osGetLastError(), |
| 35415 | "GetFullPathNameW2", zConverted); |
| 35416 | sqlite3_free(zConverted); |
| 35417 | sqlite3_free(zTemp); |
| 35418 | return SQLITE_CANTOPEN_FULLPATH; |
| 35419 | } |
| 35420 | sqlite3_free(zConverted); |
| 35421 | zOut = winUnicodeToUtf8(zTemp); |
| 35422 | sqlite3_free(zTemp); |
| 35423 | } |
| @@ -35424,28 +35554,26 @@ | |
| 35424 | #ifdef SQLITE_WIN32_HAS_ANSI |
| 35425 | else{ |
| 35426 | char *zTemp; |
| 35427 | nByte = osGetFullPathNameA((char*)zConverted, 0, 0, 0); |
| 35428 | if( nByte==0 ){ |
| 35429 | winLogError(SQLITE_ERROR, osGetLastError(), |
| 35430 | "GetFullPathNameA1", zConverted); |
| 35431 | sqlite3_free(zConverted); |
| 35432 | return SQLITE_CANTOPEN_FULLPATH; |
| 35433 | } |
| 35434 | nByte += 3; |
| 35435 | zTemp = sqlite3MallocZero( nByte*sizeof(zTemp[0]) ); |
| 35436 | if( zTemp==0 ){ |
| 35437 | sqlite3_free(zConverted); |
| 35438 | return SQLITE_IOERR_NOMEM; |
| 35439 | } |
| 35440 | nByte = osGetFullPathNameA((char*)zConverted, nByte, zTemp, 0); |
| 35441 | if( nByte==0 ){ |
| 35442 | winLogError(SQLITE_ERROR, osGetLastError(), |
| 35443 | "GetFullPathNameA2", zConverted); |
| 35444 | sqlite3_free(zConverted); |
| 35445 | sqlite3_free(zTemp); |
| 35446 | return SQLITE_CANTOPEN_FULLPATH; |
| 35447 | } |
| 35448 | sqlite3_free(zConverted); |
| 35449 | zOut = sqlite3_win32_mbcs_to_utf8(zTemp); |
| 35450 | sqlite3_free(zTemp); |
| 35451 | } |
| @@ -35469,11 +35597,11 @@ | |
| 35469 | ** Interfaces for opening a shared library, finding entry points |
| 35470 | ** within the shared library, and closing the shared library. |
| 35471 | */ |
| 35472 | static void *winDlOpen(sqlite3_vfs *pVfs, const char *zFilename){ |
| 35473 | HANDLE h; |
| 35474 | void *zConverted = winConvertUtf8Filename(zFilename); |
| 35475 | UNUSED_PARAMETER(pVfs); |
| 35476 | if( zConverted==0 ){ |
| 35477 | return 0; |
| 35478 | } |
| 35479 | if( osIsNT() ){ |
| @@ -60283,10 +60411,13 @@ | |
| 60283 | alloc.pParse = pParse; |
| 60284 | alloc.pIdx = pIdx; |
| 60285 | alloc.ppRec = ppRec; |
| 60286 | alloc.iVal = iVal; |
| 60287 | |
| 60288 | if( !pExpr ){ |
| 60289 | pVal = valueNew(pParse->db, &alloc); |
| 60290 | if( pVal ){ |
| 60291 | sqlite3VdbeMemSetNull((Mem*)pVal); |
| 60292 | *pbOk = 1; |
| @@ -80950,11 +81081,11 @@ | |
| 80950 | ** SQLITE_ENABLE_STAT3 defined. The functionality of sqlite_stat3 |
| 80951 | ** is a superset of sqlite_stat2. The sqlite_stat4 is an enhanced |
| 80952 | ** version of sqlite_stat3 and is only available when compiled with |
| 80953 | ** SQLITE_ENABLE_STAT4 and in SQLite versions 3.8.0 and later. It is |
| 80954 | ** not possible to enable both STAT3 and STAT4 at the same time. If they |
| 80955 | ** are both enabled, then STAT4 is precedence. |
| 80956 | ** |
| 80957 | ** For most applications, sqlite_stat1 provides all the statisics required |
| 80958 | ** for the query planner to make good choices. |
| 80959 | ** |
| 80960 | ** Format of sqlite_stat1: |
| @@ -81261,11 +81392,11 @@ | |
| 81261 | u8 *pSpace; /* Allocated space not yet assigned */ |
| 81262 | int i; /* Used to iterate through p->aSample[] */ |
| 81263 | |
| 81264 | p->iGet = -1; |
| 81265 | p->mxSample = mxSample; |
| 81266 | p->nPSample = sqlite3_value_int64(argv[1])/(mxSample/3+1) + 1; |
| 81267 | p->current.anLt = &p->current.anEq[nColUp]; |
| 81268 | sqlite3_randomness(sizeof(p->iPrn), &p->iPrn); |
| 81269 | |
| 81270 | /* Set up the Stat4Accum.a[] and aBest[] arrays */ |
| 81271 | p->a = (struct Stat4Sample*)&p->current.anLt[nColUp]; |
| @@ -81298,29 +81429,68 @@ | |
| 81298 | 0, /* xFinalize */ |
| 81299 | "stat_init", /* zName */ |
| 81300 | 0, /* pHash */ |
| 81301 | 0 /* pDestructor */ |
| 81302 | }; |
| 81303 | |
| 81304 | #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 81305 | /* |
| 81306 | ** Return true if pNew is to be preferred over pOld. |
| 81307 | */ |
| 81308 | static int sampleIsBetter(Stat4Sample *pNew, Stat4Sample *pOld){ |
| 81309 | tRowcnt nEqNew = pNew->anEq[pNew->iCol]; |
| 81310 | tRowcnt nEqOld = pOld->anEq[pOld->iCol]; |
| 81311 | |
| 81312 | assert( pOld->isPSample==0 && pNew->isPSample==0 ); |
| 81313 | assert( IsStat4 || (pNew->iCol==0 && pOld->iCol==0) ); |
| 81314 | |
| 81315 | if( (nEqNew>nEqOld) |
| 81316 | || (nEqNew==nEqOld && pNew->iCol<pOld->iCol) |
| 81317 | || (nEqNew==nEqOld && pNew->iCol==pOld->iCol && pNew->iHash>pOld->iHash) |
| 81318 | ){ |
| 81319 | return 1; |
| 81320 | } |
| 81321 | return 0; |
| 81322 | } |
| 81323 | |
| 81324 | /* |
| 81325 | ** Copy the contents of object (*pFrom) into (*pTo). |
| 81326 | */ |
| @@ -81339,12 +81509,10 @@ | |
| 81339 | ** remove the least desirable sample from p->a[] to make room. |
| 81340 | */ |
| 81341 | static void sampleInsert(Stat4Accum *p, Stat4Sample *pNew, int nEqZero){ |
| 81342 | Stat4Sample *pSample; |
| 81343 | int i; |
| 81344 | i64 iSeq; |
| 81345 | i64 iPos; |
| 81346 | |
| 81347 | assert( IsStat4 || nEqZero==0 ); |
| 81348 | |
| 81349 | if( pNew->isPSample==0 ){ |
| 81350 | Stat4Sample *pUpgrade = 0; |
| @@ -81357,12 +81525,13 @@ | |
| 81357 | ** existing sample that shares this prefix. */ |
| 81358 | for(i=p->nSample-1; i>=0; i--){ |
| 81359 | Stat4Sample *pOld = &p->a[i]; |
| 81360 | if( pOld->anEq[pNew->iCol]==0 ){ |
| 81361 | if( pOld->isPSample ) return; |
| 81362 | assert( sampleIsBetter(pNew, pOld) ); |
| 81363 | if( pUpgrade==0 || sampleIsBetter(pOld, pUpgrade) ){ |
| 81364 | pUpgrade = pOld; |
| 81365 | } |
| 81366 | } |
| 81367 | } |
| 81368 | if( pUpgrade ){ |
| @@ -81384,40 +81553,32 @@ | |
| 81384 | pSample->anDLt = anDLt; |
| 81385 | pSample->anLt = anLt; |
| 81386 | p->nSample = p->mxSample-1; |
| 81387 | } |
| 81388 | |
| 81389 | /* Figure out where in the a[] array the new sample should be inserted. */ |
| 81390 | iSeq = pNew->anLt[p->nCol-1]; |
| 81391 | for(iPos=p->nSample; iPos>0; iPos--){ |
| 81392 | if( iSeq>p->a[iPos-1].anLt[p->nCol-1] ) break; |
| 81393 | } |
| 81394 | |
| 81395 | /* Insert the new sample */ |
| 81396 | pSample = &p->a[iPos]; |
| 81397 | if( iPos!=p->nSample ){ |
| 81398 | Stat4Sample *pEnd = &p->a[p->nSample]; |
| 81399 | tRowcnt *anEq = pEnd->anEq; |
| 81400 | tRowcnt *anLt = pEnd->anLt; |
| 81401 | tRowcnt *anDLt = pEnd->anDLt; |
| 81402 | memmove(&p->a[iPos], &p->a[iPos+1], (p->nSample-iPos)*sizeof(p->a[0])); |
| 81403 | pSample->anEq = anEq; |
| 81404 | pSample->anDLt = anDLt; |
| 81405 | pSample->anLt = anLt; |
| 81406 | } |
| 81407 | p->nSample++; |
| 81408 | sampleCopy(p, pSample, pNew); |
| 81409 | |
| 81410 | /* Zero the first nEqZero entries in the anEq[] array. */ |
| 81411 | memset(pSample->anEq, 0, sizeof(tRowcnt)*nEqZero); |
| 81412 | |
| 81413 | find_new_min: |
| 81414 | if( p->nSample>=p->mxSample ){ |
| 81415 | int iMin = -1; |
| 81416 | for(i=0; i<p->mxSample; i++){ |
| 81417 | if( p->a[i].isPSample ) continue; |
| 81418 | if( iMin<0 || sampleIsBetter(&p->a[iMin], &p->a[i]) ){ |
| 81419 | iMin = i; |
| 81420 | } |
| 81421 | } |
| 81422 | assert( iMin>=0 ); |
| 81423 | p->iMin = iMin; |
| @@ -81437,13 +81598,12 @@ | |
| 81437 | |
| 81438 | /* Check if any samples from the aBest[] array should be pushed |
| 81439 | ** into IndexSample.a[] at this point. */ |
| 81440 | for(i=(p->nCol-2); i>=iChng; i--){ |
| 81441 | Stat4Sample *pBest = &p->aBest[i]; |
| 81442 | if( p->nSample<p->mxSample |
| 81443 | || sampleIsBetter(pBest, &p->a[p->iMin]) |
| 81444 | ){ |
| 81445 | sampleInsert(p, pBest, i); |
| 81446 | } |
| 81447 | } |
| 81448 | |
| 81449 | /* Update the anEq[] fields of any samples already collected. */ |
| @@ -81466,11 +81626,13 @@ | |
| 81466 | sampleInsert(p, &p->current, 0); |
| 81467 | p->current.isPSample = 0; |
| 81468 | }else |
| 81469 | |
| 81470 | /* Or if it is a non-periodic sample. Add it in this case too. */ |
| 81471 | if( p->nSample<p->mxSample || sampleIsBetter(&p->current, &p->a[p->iMin]) ){ |
| 81472 | sampleInsert(p, &p->current, 0); |
| 81473 | } |
| 81474 | } |
| 81475 | #endif |
| 81476 | } |
| @@ -81500,12 +81662,11 @@ | |
| 81500 | |
| 81501 | assert( p->nCol>1 ); /* Includes rowid field */ |
| 81502 | assert( iChng<p->nCol ); |
| 81503 | |
| 81504 | if( p->nRow==0 ){ |
| 81505 | /* anEq[0] is only zero for the very first call to this function. Do |
| 81506 | ** appropriate initialization */ |
| 81507 | for(i=0; i<p->nCol; i++) p->current.anEq[i] = 1; |
| 81508 | }else{ |
| 81509 | /* Second and subsequent calls get processed here */ |
| 81510 | samplePushPrevious(p, iChng); |
| 81511 | |
| @@ -81541,11 +81702,11 @@ | |
| 81541 | } |
| 81542 | |
| 81543 | /* Update the aBest[] array. */ |
| 81544 | for(i=0; i<(p->nCol-1); i++){ |
| 81545 | p->current.iCol = i; |
| 81546 | if( i>=iChng || sampleIsBetter(&p->current, &p->aBest[i]) ){ |
| 81547 | sampleCopy(p, &p->aBest[i], &p->current); |
| 81548 | } |
| 81549 | } |
| 81550 | } |
| 81551 | #endif |
| @@ -82249,11 +82410,11 @@ | |
| 82249 | IndexSample *pFinal = &aSample[pIdx->nSample-1]; |
| 82250 | int iCol; |
| 82251 | for(iCol=0; iCol<pIdx->nColumn; iCol++){ |
| 82252 | int i; /* Used to iterate through samples */ |
| 82253 | tRowcnt sumEq = 0; /* Sum of the nEq values */ |
| 82254 | int nSum = 0; /* Number of terms contributing to sumEq */ |
| 82255 | tRowcnt avgEq = 0; |
| 82256 | tRowcnt nDLt = pFinal->anDLt[iCol]; |
| 82257 | |
| 82258 | /* Set nSum to the number of distinct (iCol+1) field prefixes that |
| 82259 | ** occur in the stat4 table for this index before pFinal. Set |
| @@ -105797,13 +105958,13 @@ | |
| 105797 | /* |
| 105798 | ** Each instance of this object holds a sequence of WhereLoop objects |
| 105799 | ** that implement some or all of a query plan. |
| 105800 | ** |
| 105801 | ** Think of each WhereLoop object as a node in a graph with arcs |
| 105802 | ** showing dependences and costs for travelling between nodes. (That is |
| 105803 | ** not a completely accurate description because WhereLoop costs are a |
| 105804 | ** vector, not a scalar, and because dependences are many-to-one, not |
| 105805 | ** one-to-one as are graph nodes. But it is a useful visualization aid.) |
| 105806 | ** Then a WherePath object is a path through the graph that visits some |
| 105807 | ** or all of the WhereLoop objects once. |
| 105808 | ** |
| 105809 | ** The "solver" works by creating the N best WherePath objects of length |
| @@ -108165,11 +108326,16 @@ | |
| 108165 | && p->nSample |
| 108166 | && OptimizationEnabled(pParse->db, SQLITE_Stat3) |
| 108167 | ){ |
| 108168 | UnpackedRecord *pRec = pBuilder->pRec; |
| 108169 | tRowcnt a[2]; |
| 108170 | u8 aff = p->pTable->aCol[p->aiColumn[0]].affinity; |
| 108171 | |
| 108172 | /* Variable iLower will be set to the estimate of the number of rows in |
| 108173 | ** the index that are less than the lower bound of the range query. The |
| 108174 | ** lower bound being the concatenation of $P and $L, where $P is the |
| 108175 | ** key-prefix formed by the nEq values matched against the nEq left-most |
| @@ -109781,19 +109947,21 @@ | |
| 109781 | assert( p->rSetup>=pTemplate->rSetup ); |
| 109782 | |
| 109783 | if( (p->prereq & pTemplate->prereq)==p->prereq |
| 109784 | && p->rSetup<=pTemplate->rSetup |
| 109785 | && p->rRun<=pTemplate->rRun |
| 109786 | ){ |
| 109787 | /* This branch taken when p is equal or better than pTemplate in |
| 109788 | ** all of (1) dependences (2) setup-cost, and (3) run-cost. */ |
| 109789 | assert( p->rSetup==pTemplate->rSetup ); |
| 109790 | if( p->nLTerm<pTemplate->nLTerm |
| 109791 | && (p->wsFlags & WHERE_INDEXED)!=0 |
| 109792 | && (pTemplate->wsFlags & WHERE_INDEXED)!=0 |
| 109793 | && p->u.btree.pIndex==pTemplate->u.btree.pIndex |
| 109794 | && p->prereq==pTemplate->prereq |
| 109795 | ){ |
| 109796 | /* Overwrite an existing WhereLoop with an similar one that uses |
| 109797 | ** more terms of the index */ |
| 109798 | pNext = p->pNextLoop; |
| 109799 | break; |
| @@ -109803,15 +109971,17 @@ | |
| 109803 | goto whereLoopInsert_noop; |
| 109804 | } |
| 109805 | } |
| 109806 | if( (p->prereq & pTemplate->prereq)==pTemplate->prereq |
| 109807 | && p->rRun>=pTemplate->rRun |
| 109808 | && ALWAYS(p->rSetup>=pTemplate->rSetup) /* See SETUP-INVARIANT above */ |
| 109809 | ){ |
| 109810 | /* Overwrite an existing WhereLoop with a better one: one that is |
| 109811 | ** better at one of (1) dependences, (2) setup-cost, or (3) run-cost |
| 109812 | ** and is no worse in any of those categories. */ |
| 109813 | pNext = p->pNextLoop; |
| 109814 | break; |
| 109815 | } |
| 109816 | } |
| 109817 | |
| @@ -111512,11 +111682,11 @@ | |
| 111512 | if( pWInfo->nLevel>=2 |
| 111513 | && pResultSet!=0 |
| 111514 | && OptimizationEnabled(db, SQLITE_OmitNoopJoin) |
| 111515 | ){ |
| 111516 | Bitmask tabUsed = exprListTableUsage(pMaskSet, pResultSet); |
| 111517 | if( pOrderBy ) tabUsed |= exprListTableUsage(pMaskSet, pOrderBy); |
| 111518 | while( pWInfo->nLevel>=2 ){ |
| 111519 | WhereTerm *pTerm, *pEnd; |
| 111520 | pLoop = pWInfo->a[pWInfo->nLevel-1].pWLoop; |
| 111521 | if( (pWInfo->pTabList->a[pLoop->iTab].jointype & JT_LEFT)==0 ) break; |
| 111522 | if( (wctrlFlags & WHERE_WANT_DISTINCT)==0 |
| @@ -117544,18 +117714,20 @@ | |
| 117544 | case SQLITE_IOERR_SHMMAP: zName = "SQLITE_IOERR_SHMMAP"; break; |
| 117545 | case SQLITE_IOERR_SEEK: zName = "SQLITE_IOERR_SEEK"; break; |
| 117546 | case SQLITE_IOERR_DELETE_NOENT: zName = "SQLITE_IOERR_DELETE_NOENT";break; |
| 117547 | case SQLITE_IOERR_MMAP: zName = "SQLITE_IOERR_MMAP"; break; |
| 117548 | case SQLITE_IOERR_GETTEMPPATH: zName = "SQLITE_IOERR_GETTEMPPATH"; break; |
| 117549 | case SQLITE_CORRUPT: zName = "SQLITE_CORRUPT"; break; |
| 117550 | case SQLITE_CORRUPT_VTAB: zName = "SQLITE_CORRUPT_VTAB"; break; |
| 117551 | case SQLITE_NOTFOUND: zName = "SQLITE_NOTFOUND"; break; |
| 117552 | case SQLITE_FULL: zName = "SQLITE_FULL"; break; |
| 117553 | case SQLITE_CANTOPEN: zName = "SQLITE_CANTOPEN"; break; |
| 117554 | case SQLITE_CANTOPEN_NOTEMPDIR: zName = "SQLITE_CANTOPEN_NOTEMPDIR";break; |
| 117555 | case SQLITE_CANTOPEN_ISDIR: zName = "SQLITE_CANTOPEN_ISDIR"; break; |
| 117556 | case SQLITE_CANTOPEN_FULLPATH: zName = "SQLITE_CANTOPEN_FULLPATH"; break; |
| 117557 | case SQLITE_PROTOCOL: zName = "SQLITE_PROTOCOL"; break; |
| 117558 | case SQLITE_EMPTY: zName = "SQLITE_EMPTY"; break; |
| 117559 | case SQLITE_SCHEMA: zName = "SQLITE_SCHEMA"; break; |
| 117560 | case SQLITE_TOOBIG: zName = "SQLITE_TOOBIG"; break; |
| 117561 | case SQLITE_CONSTRAINT: zName = "SQLITE_CONSTRAINT"; break; |
| 117562 |
| --- src/sqlite3.c | |
| +++ src/sqlite3.c | |
| @@ -656,11 +656,11 @@ | |
| 656 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 657 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 658 | */ |
| 659 | #define SQLITE_VERSION "3.8.1" |
| 660 | #define SQLITE_VERSION_NUMBER 3008001 |
| 661 | #define SQLITE_SOURCE_ID "2013-09-03 14:43:12 d59f580904e6e7e90fc0a692a3dd4eeff5942479" |
| 662 | |
| 663 | /* |
| 664 | ** CAPI3REF: Run-Time Library Version Numbers |
| 665 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 666 | ** |
| @@ -1026,16 +1026,18 @@ | |
| 1026 | #define SQLITE_IOERR_SHMMAP (SQLITE_IOERR | (21<<8)) |
| 1027 | #define SQLITE_IOERR_SEEK (SQLITE_IOERR | (22<<8)) |
| 1028 | #define SQLITE_IOERR_DELETE_NOENT (SQLITE_IOERR | (23<<8)) |
| 1029 | #define SQLITE_IOERR_MMAP (SQLITE_IOERR | (24<<8)) |
| 1030 | #define SQLITE_IOERR_GETTEMPPATH (SQLITE_IOERR | (25<<8)) |
| 1031 | #define SQLITE_IOERR_CONVPATH (SQLITE_IOERR | (26<<8)) |
| 1032 | #define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8)) |
| 1033 | #define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8)) |
| 1034 | #define SQLITE_BUSY_SNAPSHOT (SQLITE_BUSY | (2<<8)) |
| 1035 | #define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8)) |
| 1036 | #define SQLITE_CANTOPEN_ISDIR (SQLITE_CANTOPEN | (2<<8)) |
| 1037 | #define SQLITE_CANTOPEN_FULLPATH (SQLITE_CANTOPEN | (3<<8)) |
| 1038 | #define SQLITE_CANTOPEN_CONVPATH (SQLITE_CANTOPEN | (4<<8)) |
| 1039 | #define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8)) |
| 1040 | #define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8)) |
| 1041 | #define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8)) |
| 1042 | #define SQLITE_READONLY_ROLLBACK (SQLITE_READONLY | (3<<8)) |
| 1043 | #define SQLITE_ABORT_ROLLBACK (SQLITE_ABORT | (2<<8)) |
| @@ -16259,11 +16261,11 @@ | |
| 16261 | assert( mem.disallow==0 ); |
| 16262 | assert( (nByte & 7)==0 ); /* EV: R-46199-30249 */ |
| 16263 | pOldHdr = sqlite3MemsysGetHeader(pPrior); |
| 16264 | pNew = sqlite3MemMalloc(nByte); |
| 16265 | if( pNew ){ |
| 16266 | memcpy(pNew, pPrior, (int)(nByte<pOldHdr->iSize ? nByte : pOldHdr->iSize)); |
| 16267 | if( nByte>pOldHdr->iSize ){ |
| 16268 | randomFill(&((char*)pNew)[pOldHdr->iSize], nByte - (int)pOldHdr->iSize); |
| 16269 | } |
| 16270 | sqlite3MemFree(pPrior); |
| 16271 | } |
| @@ -23594,10 +23596,19 @@ | |
| 23596 | if( aSyscall[i].pCurrent!=0 ) return aSyscall[i].zName; |
| 23597 | } |
| 23598 | return 0; |
| 23599 | } |
| 23600 | |
| 23601 | /* |
| 23602 | ** Do not accept any file descriptor less than this value, in order to avoid |
| 23603 | ** opening database file using file descriptors that are commonly used for |
| 23604 | ** standard input, output, and error. |
| 23605 | */ |
| 23606 | #ifndef SQLITE_MINIMUM_FILE_DESCRIPTOR |
| 23607 | # define SQLITE_MINIMUM_FILE_DESCRIPTOR 3 |
| 23608 | #endif |
| 23609 | |
| 23610 | /* |
| 23611 | ** Invoke open(). Do so multiple times, until it either succeeds or |
| 23612 | ** fails for some reason other than EINTR. |
| 23613 | ** |
| 23614 | ** If the file creation mode "m" is 0 then set it to the default for |
| @@ -23624,11 +23635,11 @@ | |
| 23635 | #endif |
| 23636 | if( fd<0 ){ |
| 23637 | if( errno==EINTR ) continue; |
| 23638 | break; |
| 23639 | } |
| 23640 | if( fd>=SQLITE_MINIMUM_FILE_DESCRIPTOR ) break; |
| 23641 | osClose(fd); |
| 23642 | sqlite3_log(SQLITE_WARNING, |
| 23643 | "attempt to open \"%s\" as file descriptor %d", z, fd); |
| 23644 | fd = -1; |
| 23645 | if( osOpen("/dev/null", f, m)<0 ) break; |
| @@ -28373,10 +28384,11 @@ | |
| 28384 | ** If no suitable temporary file directory can be found, return NULL. |
| 28385 | */ |
| 28386 | static const char *unixTempFileDir(void){ |
| 28387 | static const char *azDirs[] = { |
| 28388 | 0, |
| 28389 | 0, |
| 28390 | 0, |
| 28391 | "/var/tmp", |
| 28392 | "/usr/tmp", |
| 28393 | "/tmp", |
| 28394 | 0 /* List terminator */ |
| @@ -28384,11 +28396,12 @@ | |
| 28396 | unsigned int i; |
| 28397 | struct stat buf; |
| 28398 | const char *zDir = 0; |
| 28399 | |
| 28400 | azDirs[0] = sqlite3_temp_directory; |
| 28401 | if( !azDirs[1] ) azDirs[1] = getenv("SQLITE_TMPDIR"); |
| 28402 | if( !azDirs[2] ) azDirs[2] = getenv("TMPDIR"); |
| 28403 | for(i=0; i<sizeof(azDirs)/sizeof(azDirs[0]); zDir=azDirs[i++]){ |
| 28404 | if( zDir==0 ) continue; |
| 28405 | if( osStat(zDir, &buf) ) continue; |
| 28406 | if( !S_ISDIR(buf.st_mode) ) continue; |
| 28407 | if( osAccess(zDir, 07) ) continue; |
| @@ -30497,11 +30510,11 @@ | |
| 30510 | */ |
| 30511 | #if SQLITE_OS_WIN /* This file is used for Windows only */ |
| 30512 | |
| 30513 | #ifdef __CYGWIN__ |
| 30514 | # include <sys/cygwin.h> |
| 30515 | # include <errno.h> /* amalgamator: keep */ |
| 30516 | #endif |
| 30517 | |
| 30518 | /* |
| 30519 | ** Include code that is common to all os_*.c files |
| 30520 | */ |
| @@ -30726,22 +30739,31 @@ | |
| 30739 | |
| 30740 | /* |
| 30741 | ** Are most of the Win32 ANSI APIs available (i.e. with certain exceptions |
| 30742 | ** based on the sub-platform)? |
| 30743 | */ |
| 30744 | #if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && !defined(SQLITE_WIN32_NO_ANSI) |
| 30745 | # define SQLITE_WIN32_HAS_ANSI |
| 30746 | #endif |
| 30747 | |
| 30748 | /* |
| 30749 | ** Are most of the Win32 Unicode APIs available (i.e. with certain exceptions |
| 30750 | ** based on the sub-platform)? |
| 30751 | */ |
| 30752 | #if (SQLITE_OS_WINCE || SQLITE_OS_WINNT || SQLITE_OS_WINRT) && \ |
| 30753 | !defined(SQLITE_WIN32_NO_WIDE) |
| 30754 | # define SQLITE_WIN32_HAS_WIDE |
| 30755 | #endif |
| 30756 | |
| 30757 | /* |
| 30758 | ** Make sure at least one set of Win32 APIs is available. |
| 30759 | */ |
| 30760 | #if !defined(SQLITE_WIN32_HAS_ANSI) && !defined(SQLITE_WIN32_HAS_WIDE) |
| 30761 | # error "At least one of SQLITE_WIN32_HAS_ANSI and SQLITE_WIN32_HAS_WIDE\ |
| 30762 | must be defined." |
| 30763 | #endif |
| 30764 | |
| 30765 | /* |
| 30766 | ** Maximum pathname length (in chars) for Win32. This should normally be |
| 30767 | ** MAX_PATH. |
| 30768 | */ |
| 30769 | #ifndef SQLITE_WIN32_MAX_PATH_CHARS |
| @@ -30849,11 +30871,11 @@ | |
| 30871 | #ifndef FILE_ATTRIBUTE_MASK |
| 30872 | # define FILE_ATTRIBUTE_MASK (0x0003FFF7) |
| 30873 | #endif |
| 30874 | |
| 30875 | #ifndef SQLITE_OMIT_WAL |
| 30876 | /* Forward references to structures used for WAL */ |
| 30877 | typedef struct winShm winShm; /* A connection to shared-memory */ |
| 30878 | typedef struct winShmNode winShmNode; /* A region of shared-memory */ |
| 30879 | #endif |
| 30880 | |
| 30881 | /* |
| @@ -31804,11 +31826,11 @@ | |
| 31826 | ** API as long as we don't call it when running Win95/98/ME. A call to |
| 31827 | ** this routine is used to determine if the host is Win95/98/ME or |
| 31828 | ** WinNT/2K/XP so that we will know whether or not we can safely call |
| 31829 | ** the LockFileEx() API. |
| 31830 | */ |
| 31831 | #if SQLITE_OS_WINCE || SQLITE_OS_WINRT || !defined(SQLITE_WIN32_HAS_ANSI) |
| 31832 | # define osIsNT() (1) |
| 31833 | #elif !defined(SQLITE_WIN32_HAS_WIDE) |
| 31834 | # define osIsNT() (0) |
| 31835 | #else |
| 31836 | static int osIsNT(void){ |
| @@ -32449,14 +32471,13 @@ | |
| 32471 | |
| 32472 | /* Create/open the named mutex */ |
| 32473 | pFile->hMutex = osCreateMutexW(NULL, FALSE, zName); |
| 32474 | if (!pFile->hMutex){ |
| 32475 | pFile->lastErrno = osGetLastError(); |
| 32476 | sqlite3_free(zName); |
| 32477 | return winLogError(SQLITE_IOERR, pFile->lastErrno, |
| 32478 | "winceCreateLock1", zFilename); |
| 32479 | } |
| 32480 | |
| 32481 | /* Acquire the mutex before continuing */ |
| 32482 | winceMutexAcquire(pFile->hMutex); |
| 32483 | |
| @@ -32788,11 +32809,11 @@ | |
| 32809 | |
| 32810 | if( (dwRet==INVALID_SET_FILE_POINTER |
| 32811 | && ((lastErrno = osGetLastError())!=NO_ERROR)) ){ |
| 32812 | pFile->lastErrno = lastErrno; |
| 32813 | winLogError(SQLITE_IOERR_SEEK, pFile->lastErrno, |
| 32814 | "winSeekFile", pFile->zPath); |
| 32815 | OSTRACE(("SEEK file=%p, rc=SQLITE_IOERR_SEEK\n", pFile->h)); |
| 32816 | return 1; |
| 32817 | } |
| 32818 | |
| 32819 | OSTRACE(("SEEK file=%p, rc=SQLITE_OK\n", pFile->h)); |
| @@ -32809,11 +32830,11 @@ | |
| 32830 | bRet = osSetFilePointerEx(pFile->h, x, 0, FILE_BEGIN); |
| 32831 | |
| 32832 | if(!bRet){ |
| 32833 | pFile->lastErrno = osGetLastError(); |
| 32834 | winLogError(SQLITE_IOERR_SEEK, pFile->lastErrno, |
| 32835 | "winSeekFile", pFile->zPath); |
| 32836 | OSTRACE(("SEEK file=%p, rc=SQLITE_IOERR_SEEK\n", pFile->h)); |
| 32837 | return 1; |
| 32838 | } |
| 32839 | |
| 32840 | OSTRACE(("SEEK file=%p, rc=SQLITE_OK\n", pFile->h)); |
| @@ -32820,11 +32841,12 @@ | |
| 32841 | return 0; |
| 32842 | #endif |
| 32843 | } |
| 32844 | |
| 32845 | #if SQLITE_MAX_MMAP_SIZE>0 |
| 32846 | /* Forward references to VFS helper methods used for memory mapped files */ |
| 32847 | static int winMapfile(winFile*, sqlite3_int64); |
| 32848 | static int winUnmapfile(winFile*); |
| 32849 | #endif |
| 32850 | |
| 32851 | /* |
| 32852 | ** Close a file. |
| @@ -32941,11 +32963,11 @@ | |
| 32963 | DWORD lastErrno; |
| 32964 | if( winRetryIoerr(&nRetry, &lastErrno) ) continue; |
| 32965 | pFile->lastErrno = lastErrno; |
| 32966 | OSTRACE(("READ file=%p, rc=SQLITE_IOERR_READ\n", pFile->h)); |
| 32967 | return winLogError(SQLITE_IOERR_READ, pFile->lastErrno, |
| 32968 | "winRead", pFile->zPath); |
| 32969 | } |
| 32970 | winLogIoerr(nRetry); |
| 32971 | if( nRead<(DWORD)amt ){ |
| 32972 | /* Unread parts of the buffer must be zero-filled */ |
| 32973 | memset(&((char*)pBuf)[nRead], 0, amt-nRead); |
| @@ -33047,15 +33069,16 @@ | |
| 33069 | |
| 33070 | if( rc ){ |
| 33071 | if( ( pFile->lastErrno==ERROR_HANDLE_DISK_FULL ) |
| 33072 | || ( pFile->lastErrno==ERROR_DISK_FULL )){ |
| 33073 | OSTRACE(("WRITE file=%p, rc=SQLITE_FULL\n", pFile->h)); |
| 33074 | return winLogError(SQLITE_FULL, pFile->lastErrno, |
| 33075 | "winWrite1", pFile->zPath); |
| 33076 | } |
| 33077 | OSTRACE(("WRITE file=%p, rc=SQLITE_IOERR_WRITE\n", pFile->h)); |
| 33078 | return winLogError(SQLITE_IOERR_WRITE, pFile->lastErrno, |
| 33079 | "winWrite2", pFile->zPath); |
| 33080 | }else{ |
| 33081 | winLogIoerr(nRetry); |
| 33082 | } |
| 33083 | OSTRACE(("WRITE file=%p, rc=SQLITE_OK\n", pFile->h)); |
| 33084 | return SQLITE_OK; |
| @@ -33175,11 +33198,11 @@ | |
| 33198 | return SQLITE_OK; |
| 33199 | }else{ |
| 33200 | pFile->lastErrno = osGetLastError(); |
| 33201 | OSTRACE(("SYNC file=%p, rc=SQLITE_IOERR_FSYNC\n", pFile->h)); |
| 33202 | return winLogError(SQLITE_IOERR_FSYNC, pFile->lastErrno, |
| 33203 | "winSync", pFile->zPath); |
| 33204 | } |
| 33205 | #endif |
| 33206 | } |
| 33207 | |
| 33208 | /* |
| @@ -33216,11 +33239,11 @@ | |
| 33239 | *pSize = (((sqlite3_int64)upperBits)<<32) + lowerBits; |
| 33240 | if( (lowerBits == INVALID_FILE_SIZE) |
| 33241 | && ((lastErrno = osGetLastError())!=NO_ERROR) ){ |
| 33242 | pFile->lastErrno = lastErrno; |
| 33243 | rc = winLogError(SQLITE_IOERR_FSTAT, pFile->lastErrno, |
| 33244 | "winFileSize", pFile->zPath); |
| 33245 | } |
| 33246 | } |
| 33247 | #endif |
| 33248 | OSTRACE(("SIZE file=%p, pSize=%p, *pSize=%lld, rc=%s\n", |
| 33249 | pFile->h, pSize, *pSize, sqlite3ErrName(rc))); |
| @@ -33311,11 +33334,11 @@ | |
| 33334 | } |
| 33335 | #endif |
| 33336 | if( res==0 && ((lastErrno = osGetLastError())!=ERROR_NOT_LOCKED) ){ |
| 33337 | pFile->lastErrno = lastErrno; |
| 33338 | winLogError(SQLITE_IOERR_UNLOCK, pFile->lastErrno, |
| 33339 | "winUnlockReadLock", pFile->zPath); |
| 33340 | } |
| 33341 | OSTRACE(("READ-UNLOCK file=%p, rc=%s\n", pFile->h, sqlite3ErrName(res))); |
| 33342 | return res; |
| 33343 | } |
| 33344 | |
| @@ -33524,11 +33547,11 @@ | |
| 33547 | winUnlockFile(&pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0); |
| 33548 | if( locktype==SHARED_LOCK && !winGetReadLock(pFile) ){ |
| 33549 | /* This should never happen. We should always be able to |
| 33550 | ** reacquire the read lock */ |
| 33551 | rc = winLogError(SQLITE_IOERR_UNLOCK, osGetLastError(), |
| 33552 | "winUnlock", pFile->zPath); |
| 33553 | } |
| 33554 | } |
| 33555 | if( type>=RESERVED_LOCK ){ |
| 33556 | winUnlockFile(&pFile->h, RESERVED_BYTE, 0, 1, 0); |
| 33557 | } |
| @@ -33558,15 +33581,14 @@ | |
| 33581 | }else{ |
| 33582 | pFile->ctrlFlags |= mask; |
| 33583 | } |
| 33584 | } |
| 33585 | |
| 33586 | /* Forward references to VFS helper methods used for temporary files */ |
| 33587 | static int winGetTempname(sqlite3_vfs *, char **); |
| 33588 | static int winIsDir(const void *); |
| 33589 | static BOOL winIsDriveLetterAndColon(const char *); |
| 33590 | |
| 33591 | /* |
| 33592 | ** Control and query of the open file handle. |
| 33593 | */ |
| 33594 | static int winFileControl(sqlite3_file *id, int op, void *pArg){ |
| @@ -33640,11 +33662,11 @@ | |
| 33662 | char *zTFile = 0; |
| 33663 | int rc = winGetTempname(pFile->pVfs, &zTFile); |
| 33664 | if( rc==SQLITE_OK ){ |
| 33665 | *(char**)pArg = zTFile; |
| 33666 | } |
| 33667 | OSTRACE(("FCNTL file=%p, rc=%s\n", pFile->h, sqlite3ErrName(rc))); |
| 33668 | return rc; |
| 33669 | } |
| 33670 | #if SQLITE_MAX_MMAP_SIZE>0 |
| 33671 | case SQLITE_FCNTL_MMAP_SIZE: { |
| 33672 | i64 newLimit = *(i64*)pArg; |
| @@ -33658,11 +33680,11 @@ | |
| 33680 | if( pFile->mmapSize>0 ){ |
| 33681 | (void)winUnmapfile(pFile); |
| 33682 | rc = winMapfile(pFile, -1); |
| 33683 | } |
| 33684 | } |
| 33685 | OSTRACE(("FCNTL file=%p, rc=%s\n", pFile->h, sqlite3ErrName(rc))); |
| 33686 | return rc; |
| 33687 | } |
| 33688 | #endif |
| 33689 | } |
| 33690 | OSTRACE(("FCNTL file=%p, rc=SQLITE_NOTFOUND\n", pFile->h)); |
| @@ -33974,11 +33996,11 @@ | |
| 33996 | */ |
| 33997 | if( winShmSystemLock(pShmNode, _SHM_WRLCK, WIN_SHM_DMS, 1)==SQLITE_OK ){ |
| 33998 | rc = winTruncate((sqlite3_file *)&pShmNode->hFile, 0); |
| 33999 | if( rc!=SQLITE_OK ){ |
| 34000 | rc = winLogError(SQLITE_IOERR_SHMOPEN, osGetLastError(), |
| 34001 | "winOpenShm", pDbFd->zPath); |
| 34002 | } |
| 34003 | } |
| 34004 | if( rc==SQLITE_OK ){ |
| 34005 | winShmSystemLock(pShmNode, _SHM_UNLCK, WIN_SHM_DMS, 1); |
| 34006 | rc = winShmSystemLock(pShmNode, _SHM_RDLCK, WIN_SHM_DMS, 1); |
| @@ -34234,11 +34256,11 @@ | |
| 34256 | ** large enough to contain the requested region). |
| 34257 | */ |
| 34258 | rc = winFileSize((sqlite3_file *)&pShmNode->hFile, &sz); |
| 34259 | if( rc!=SQLITE_OK ){ |
| 34260 | rc = winLogError(SQLITE_IOERR_SHMSIZE, osGetLastError(), |
| 34261 | "winShmMap1", pDbFd->zPath); |
| 34262 | goto shmpage_out; |
| 34263 | } |
| 34264 | |
| 34265 | if( sz<nByte ){ |
| 34266 | /* The requested memory region does not exist. If isWrite is set to |
| @@ -34249,11 +34271,11 @@ | |
| 34271 | */ |
| 34272 | if( !isWrite ) goto shmpage_out; |
| 34273 | rc = winTruncate((sqlite3_file *)&pShmNode->hFile, nByte); |
| 34274 | if( rc!=SQLITE_OK ){ |
| 34275 | rc = winLogError(SQLITE_IOERR_SHMSIZE, osGetLastError(), |
| 34276 | "winShmMap2", pDbFd->zPath); |
| 34277 | goto shmpage_out; |
| 34278 | } |
| 34279 | } |
| 34280 | |
| 34281 | /* Map the requested memory region into this processes address space. */ |
| @@ -34303,11 +34325,11 @@ | |
| 34325 | szRegion, pMap ? "ok" : "failed")); |
| 34326 | } |
| 34327 | if( !pMap ){ |
| 34328 | pShmNode->lastErrno = osGetLastError(); |
| 34329 | rc = winLogError(SQLITE_IOERR_SHMMAP, pShmNode->lastErrno, |
| 34330 | "winShmMap3", pDbFd->zPath); |
| 34331 | if( hMap ) osCloseHandle(hMap); |
| 34332 | goto shmpage_out; |
| 34333 | } |
| 34334 | |
| 34335 | pShmNode->aRegion[pShmNode->nRegion].pMap = pMap; |
| @@ -34351,11 +34373,11 @@ | |
| 34373 | pFile->lastErrno = osGetLastError(); |
| 34374 | OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, pMapRegion=%p, " |
| 34375 | "rc=SQLITE_IOERR_MMAP\n", osGetCurrentProcessId(), pFile, |
| 34376 | pFile->pMapRegion)); |
| 34377 | return winLogError(SQLITE_IOERR_MMAP, pFile->lastErrno, |
| 34378 | "winUnmapfile1", pFile->zPath); |
| 34379 | } |
| 34380 | pFile->pMapRegion = 0; |
| 34381 | pFile->mmapSize = 0; |
| 34382 | pFile->mmapSizeActual = 0; |
| 34383 | } |
| @@ -34363,11 +34385,11 @@ | |
| 34385 | if( !osCloseHandle(pFile->hMap) ){ |
| 34386 | pFile->lastErrno = osGetLastError(); |
| 34387 | OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, hMap=%p, rc=SQLITE_IOERR_MMAP\n", |
| 34388 | osGetCurrentProcessId(), pFile, pFile->hMap)); |
| 34389 | return winLogError(SQLITE_IOERR_MMAP, pFile->lastErrno, |
| 34390 | "winUnmapfile2", pFile->zPath); |
| 34391 | } |
| 34392 | pFile->hMap = NULL; |
| 34393 | } |
| 34394 | OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, rc=SQLITE_OK\n", |
| 34395 | osGetCurrentProcessId(), pFile)); |
| @@ -34438,14 +34460,14 @@ | |
| 34460 | (DWORD)(nMap & 0xffffffff), NULL); |
| 34461 | #endif |
| 34462 | if( pFd->hMap==NULL ){ |
| 34463 | pFd->lastErrno = osGetLastError(); |
| 34464 | rc = winLogError(SQLITE_IOERR_MMAP, pFd->lastErrno, |
| 34465 | "winMapfile1", pFd->zPath); |
| 34466 | /* Log the error, but continue normal operation using xRead/xWrite */ |
| 34467 | OSTRACE(("MAP-FILE-CREATE pid=%lu, pFile=%p, rc=%s\n", |
| 34468 | osGetCurrentProcessId(), pFd, sqlite3ErrName(rc))); |
| 34469 | return SQLITE_OK; |
| 34470 | } |
| 34471 | assert( (nMap % winSysInfo.dwPageSize)==0 ); |
| 34472 | assert( sizeof(SIZE_T)==sizeof(sqlite3_int64) || nMap<=0xffffffff ); |
| 34473 | #if SQLITE_OS_WINRT |
| @@ -34455,14 +34477,15 @@ | |
| 34477 | #endif |
| 34478 | if( pNew==NULL ){ |
| 34479 | osCloseHandle(pFd->hMap); |
| 34480 | pFd->hMap = NULL; |
| 34481 | pFd->lastErrno = osGetLastError(); |
| 34482 | rc = winLogError(SQLITE_IOERR_MMAP, pFd->lastErrno, |
| 34483 | "winMapfile2", pFd->zPath); |
| 34484 | /* Log the error, but continue normal operation using xRead/xWrite */ |
| 34485 | OSTRACE(("MAP-FILE-MAP pid=%lu, pFile=%p, rc=%s\n", |
| 34486 | osGetCurrentProcessId(), pFd, sqlite3ErrName(rc))); |
| 34487 | return SQLITE_OK; |
| 34488 | } |
| 34489 | pFd->pMapRegion = pNew; |
| 34490 | pFd->mmapSize = nMap; |
| 34491 | pFd->mmapSizeActual = nMap; |
| @@ -34596,18 +34619,37 @@ | |
| 34619 | **************************** sqlite3_vfs methods **************************** |
| 34620 | ** |
| 34621 | ** This division contains the implementation of methods on the |
| 34622 | ** sqlite3_vfs object. |
| 34623 | */ |
| 34624 | |
| 34625 | /* |
| 34626 | ** Convert a filename from whatever the underlying operating system |
| 34627 | ** supports for filenames into UTF-8. Space to hold the result is |
| 34628 | ** obtained from malloc and must be freed by the calling function. |
| 34629 | */ |
| 34630 | static char *winConvertToUtf8Filename(const void *zFilename){ |
| 34631 | char *zConverted = 0; |
| 34632 | if( osIsNT() ){ |
| 34633 | zConverted = winUnicodeToUtf8(zFilename); |
| 34634 | } |
| 34635 | #ifdef SQLITE_WIN32_HAS_ANSI |
| 34636 | else{ |
| 34637 | zConverted = sqlite3_win32_mbcs_to_utf8(zFilename); |
| 34638 | } |
| 34639 | #endif |
| 34640 | /* caller will handle out of memory */ |
| 34641 | return zConverted; |
| 34642 | } |
| 34643 | |
| 34644 | /* |
| 34645 | ** Convert a UTF-8 filename into whatever form the underlying |
| 34646 | ** operating system wants filenames in. Space to hold the result |
| 34647 | ** is obtained from malloc and must be freed by the calling |
| 34648 | ** function. |
| 34649 | */ |
| 34650 | static void *winConvertFromUtf8Filename(const char *zFilename){ |
| 34651 | void *zConverted = 0; |
| 34652 | if( osIsNT() ){ |
| 34653 | zConverted = winUtf8ToUnicode(zFilename); |
| 34654 | } |
| 34655 | #ifdef SQLITE_WIN32_HAS_ANSI |
| @@ -34668,11 +34710,94 @@ | |
| 34710 | if( sqlite3_temp_directory ){ |
| 34711 | sqlite3_snprintf(nBuf-30, zBuf, "%s%s", sqlite3_temp_directory, |
| 34712 | winEndsInDirSep(sqlite3_temp_directory) ? "" : |
| 34713 | winGetDirDep()); |
| 34714 | } |
| 34715 | #if defined(__CYGWIN__) |
| 34716 | else{ |
| 34717 | static const char *azDirs[] = { |
| 34718 | 0, /* getenv("SQLITE_TMPDIR") */ |
| 34719 | 0, /* getenv("TMPDIR") */ |
| 34720 | 0, /* getenv("TMP") */ |
| 34721 | 0, /* getenv("TEMP") */ |
| 34722 | 0, /* getenv("USERPROFILE") */ |
| 34723 | "/var/tmp", |
| 34724 | "/usr/tmp", |
| 34725 | "/tmp", |
| 34726 | ".", |
| 34727 | 0 /* List terminator */ |
| 34728 | }; |
| 34729 | unsigned int i; |
| 34730 | const char *zDir = 0; |
| 34731 | |
| 34732 | if( !azDirs[0] ) azDirs[0] = getenv("SQLITE_TMPDIR"); |
| 34733 | if( !azDirs[1] ) azDirs[1] = getenv("TMPDIR"); |
| 34734 | if( !azDirs[2] ) azDirs[2] = getenv("TMP"); |
| 34735 | if( !azDirs[3] ) azDirs[3] = getenv("TEMP"); |
| 34736 | if( !azDirs[4] ) azDirs[4] = getenv("USERPROFILE"); |
| 34737 | for(i=0; i<sizeof(azDirs)/sizeof(azDirs[0]); zDir=azDirs[i++]){ |
| 34738 | void *zConverted; |
| 34739 | if( zDir==0 ) continue; |
| 34740 | /* If the path starts with a drive letter followed by the colon |
| 34741 | ** character, assume it is already a native Win32 path; otherwise, |
| 34742 | ** it must be converted to a native Win32 path prior via the Cygwin |
| 34743 | ** API prior to using it. |
| 34744 | */ |
| 34745 | if( winIsDriveLetterAndColon(zDir) ){ |
| 34746 | zConverted = winConvertFromUtf8Filename(zDir); |
| 34747 | if( !zConverted ){ |
| 34748 | OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); |
| 34749 | return SQLITE_IOERR_NOMEM; |
| 34750 | } |
| 34751 | if( winIsDir(zConverted) ){ |
| 34752 | sqlite3_snprintf(nBuf-30, zBuf, "%s", zDir); |
| 34753 | sqlite3_free(zConverted); |
| 34754 | break; |
| 34755 | } |
| 34756 | sqlite3_free(zConverted); |
| 34757 | }else{ |
| 34758 | zConverted = sqlite3MallocZero( nBuf+1 ); |
| 34759 | if( !zConverted ){ |
| 34760 | OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); |
| 34761 | return SQLITE_IOERR_NOMEM; |
| 34762 | } |
| 34763 | if( cygwin_conv_path( |
| 34764 | osIsNT() ? CCP_POSIX_TO_WIN_W : CCP_POSIX_TO_WIN_A, zDir, |
| 34765 | zConverted, nBuf+1)<0 ){ |
| 34766 | sqlite3_free(zConverted); |
| 34767 | OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_CONVPATH\n")); |
| 34768 | return winLogError(SQLITE_IOERR_CONVPATH, (DWORD)errno, |
| 34769 | "winGetTempname1", zDir); |
| 34770 | } |
| 34771 | if( winIsDir(zConverted) ){ |
| 34772 | /* At this point, we know the candidate directory exists and should |
| 34773 | ** be used. However, we may need to convert the string containing |
| 34774 | ** its name into UTF-8 (i.e. if it is UTF-16 right now). |
| 34775 | */ |
| 34776 | if( osIsNT() ){ |
| 34777 | char *zUtf8 = winUnicodeToUtf8(zConverted); |
| 34778 | if( !zUtf8 ){ |
| 34779 | sqlite3_free(zConverted); |
| 34780 | OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); |
| 34781 | return SQLITE_IOERR_NOMEM; |
| 34782 | } |
| 34783 | sqlite3_snprintf(nBuf-30, zBuf, "%s", zUtf8); |
| 34784 | sqlite3_free(zUtf8); |
| 34785 | sqlite3_free(zConverted); |
| 34786 | break; |
| 34787 | }else{ |
| 34788 | sqlite3_snprintf(nBuf-30, zBuf, "%s", zConverted); |
| 34789 | sqlite3_free(zConverted); |
| 34790 | break; |
| 34791 | } |
| 34792 | } |
| 34793 | sqlite3_free(zConverted); |
| 34794 | } |
| 34795 | break; |
| 34796 | } |
| 34797 | } |
| 34798 | #elif !SQLITE_OS_WINRT && !defined(__CYGWIN__) |
| 34799 | else if( osIsNT() ){ |
| 34800 | char *zMulti; |
| 34801 | LPWSTR zWidePath = sqlite3MallocZero( nBuf*sizeof(WCHAR) ); |
| 34802 | if( !zWidePath ){ |
| 34803 | sqlite3_free(zBuf); |
| @@ -34681,11 +34806,12 @@ | |
| 34806 | } |
| 34807 | if( osGetTempPathW(nBuf, zWidePath)==0 ){ |
| 34808 | sqlite3_free(zWidePath); |
| 34809 | sqlite3_free(zBuf); |
| 34810 | OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_GETTEMPPATH\n")); |
| 34811 | return winLogError(SQLITE_IOERR_GETTEMPPATH, osGetLastError(), |
| 34812 | "winGetTempname1", 0); |
| 34813 | } |
| 34814 | zMulti = winUnicodeToUtf8(zWidePath); |
| 34815 | if( zMulti ){ |
| 34816 | sqlite3_snprintf(nBuf-30, zBuf, "%s", zMulti); |
| 34817 | sqlite3_free(zMulti); |
| @@ -34707,11 +34833,12 @@ | |
| 34833 | return SQLITE_IOERR_NOMEM; |
| 34834 | } |
| 34835 | if( osGetTempPathA(nBuf, zMbcsPath)==0 ){ |
| 34836 | sqlite3_free(zBuf); |
| 34837 | OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_GETTEMPPATH\n")); |
| 34838 | return winLogError(SQLITE_IOERR_GETTEMPPATH, osGetLastError(), |
| 34839 | "winGetTempname2", 0); |
| 34840 | } |
| 34841 | zUtf8 = sqlite3_win32_mbcs_to_utf8(zMbcsPath); |
| 34842 | if( zUtf8 ){ |
| 34843 | sqlite3_snprintf(nBuf-30, zBuf, "%s", zUtf8); |
| 34844 | sqlite3_free(zUtf8); |
| @@ -34730,11 +34857,11 @@ | |
| 34857 | nLen = sqlite3Strlen30(zBuf); |
| 34858 | |
| 34859 | if( (nLen + sqlite3Strlen30(SQLITE_TEMP_FILE_PREFIX) + 18) >= nBuf ){ |
| 34860 | sqlite3_free(zBuf); |
| 34861 | OSTRACE(("TEMP-FILENAME rc=SQLITE_ERROR\n")); |
| 34862 | return winLogError(SQLITE_ERROR, 0, "winGetTempname3", 0); |
| 34863 | } |
| 34864 | |
| 34865 | sqlite3_snprintf(nBuf-18-nLen, zBuf+nLen, SQLITE_TEMP_FILE_PREFIX); |
| 34866 | |
| 34867 | j = sqlite3Strlen30(zBuf); |
| @@ -34886,11 +35013,11 @@ | |
| 35013 | */ |
| 35014 | assert( (eType!=SQLITE_OPEN_MAIN_DB) || (flags & SQLITE_OPEN_URI) || |
| 35015 | zUtf8Name[sqlite3Strlen30(zUtf8Name)+1]==0 ); |
| 35016 | |
| 35017 | /* Convert the filename to the system encoding. */ |
| 35018 | zConverted = winConvertFromUtf8Filename(zUtf8Name); |
| 35019 | if( zConverted==0 ){ |
| 35020 | sqlite3_free(zTmpname); |
| 35021 | OSTRACE(("OPEN name=%s, rc=SQLITE_IOERR_NOMEM", zUtf8Name)); |
| 35022 | return SQLITE_IOERR_NOMEM; |
| 35023 | } |
| @@ -35087,11 +35214,11 @@ | |
| 35214 | UNUSED_PARAMETER(syncDir); |
| 35215 | |
| 35216 | SimulateIOError(return SQLITE_IOERR_DELETE); |
| 35217 | OSTRACE(("DELETE name=%s, syncDir=%d\n", zFilename, syncDir)); |
| 35218 | |
| 35219 | zConverted = winConvertFromUtf8Filename(zFilename); |
| 35220 | if( zConverted==0 ){ |
| 35221 | OSTRACE(("DELETE name=%s, rc=SQLITE_IOERR_NOMEM\n", zFilename)); |
| 35222 | return SQLITE_IOERR_NOMEM; |
| 35223 | } |
| 35224 | if( osIsNT() ){ |
| @@ -35167,12 +35294,11 @@ | |
| 35294 | } |
| 35295 | } while(1); |
| 35296 | } |
| 35297 | #endif |
| 35298 | if( rc && rc!=SQLITE_IOERR_DELETE_NOENT ){ |
| 35299 | rc = winLogError(SQLITE_IOERR_DELETE, lastErrno, "winDelete", zFilename); |
| 35300 | }else{ |
| 35301 | winLogIoerr(cnt); |
| 35302 | } |
| 35303 | sqlite3_free(zConverted); |
| 35304 | OSTRACE(("DELETE name=%s, rc=%s\n", zFilename, sqlite3ErrName(rc))); |
| @@ -35196,11 +35322,11 @@ | |
| 35322 | |
| 35323 | SimulateIOError( return SQLITE_IOERR_ACCESS; ); |
| 35324 | OSTRACE(("ACCESS name=%s, flags=%x, pResOut=%p\n", |
| 35325 | zFilename, flags, pResOut)); |
| 35326 | |
| 35327 | zConverted = winConvertFromUtf8Filename(zFilename); |
| 35328 | if( zConverted==0 ){ |
| 35329 | OSTRACE(("ACCESS name=%s, rc=SQLITE_IOERR_NOMEM\n", zFilename)); |
| 35330 | return SQLITE_IOERR_NOMEM; |
| 35331 | } |
| 35332 | if( osIsNT() ){ |
| @@ -35222,13 +35348,13 @@ | |
| 35348 | attr = sAttrData.dwFileAttributes; |
| 35349 | } |
| 35350 | }else{ |
| 35351 | winLogIoerr(cnt); |
| 35352 | if( lastErrno!=ERROR_FILE_NOT_FOUND && lastErrno!=ERROR_PATH_NOT_FOUND ){ |
| 35353 | sqlite3_free(zConverted); |
| 35354 | return winLogError(SQLITE_IOERR_ACCESS, lastErrno, "winAccess", |
| 35355 | zFilename); |
| 35356 | }else{ |
| 35357 | attr = INVALID_FILE_ATTRIBUTES; |
| 35358 | } |
| 35359 | } |
| 35360 | } |
| @@ -35254,10 +35380,19 @@ | |
| 35380 | OSTRACE(("ACCESS name=%s, pResOut=%p, *pResOut=%d, rc=SQLITE_OK\n", |
| 35381 | zFilename, pResOut, *pResOut)); |
| 35382 | return SQLITE_OK; |
| 35383 | } |
| 35384 | |
| 35385 | /* |
| 35386 | ** Returns non-zero if the specified path name starts with a drive letter |
| 35387 | ** followed by a colon character. |
| 35388 | */ |
| 35389 | static BOOL winIsDriveLetterAndColon( |
| 35390 | const char *zPathname |
| 35391 | ){ |
| 35392 | return ( sqlite3Isalpha(zPathname[0]) && zPathname[1]==':' ); |
| 35393 | } |
| 35394 | |
| 35395 | /* |
| 35396 | ** Returns non-zero if the specified path name should be used verbatim. If |
| 35397 | ** non-zero is returned from this function, the calling function must simply |
| 35398 | ** use the provided path name verbatim -OR- resolve it into a full path name |
| @@ -35281,11 +35416,11 @@ | |
| 35416 | ** If the path name starts with a letter and a colon it is either a volume |
| 35417 | ** relative path or an absolute path. Callers of this function must not |
| 35418 | ** attempt to treat it as a relative path name (i.e. they should simply use |
| 35419 | ** it verbatim). |
| 35420 | */ |
| 35421 | if ( winIsDriveLetterAndColon(zPathname) ){ |
| 35422 | return TRUE; |
| 35423 | } |
| 35424 | |
| 35425 | /* |
| 35426 | ** If we get to this point, the path name should almost certainly be a purely |
| @@ -35317,28 +35452,25 @@ | |
| 35452 | ** for converting the relative path name to an absolute |
| 35453 | ** one by prepending the data directory and a slash. |
| 35454 | */ |
| 35455 | char *zOut = sqlite3MallocZero( pVfs->mxPathname+1 ); |
| 35456 | if( !zOut ){ |
| 35457 | return SQLITE_IOERR_NOMEM; |
| 35458 | } |
| 35459 | if( cygwin_conv_path(CCP_POSIX_TO_WIN_A|CCP_RELATIVE, zRelative, zOut, |
| 35460 | pVfs->mxPathname+1)<0 ){ |
| 35461 | sqlite3_free(zOut); |
| 35462 | return winLogError(SQLITE_CANTOPEN_CONVPATH, (DWORD)errno, |
| 35463 | "winFullPathname1", zRelative); |
| 35464 | } |
| 35465 | sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%s%s", |
| 35466 | sqlite3_data_directory, winGetDirDep(), zOut); |
| 35467 | sqlite3_free(zOut); |
| 35468 | }else{ |
| 35469 | if( cygwin_conv_path(CCP_POSIX_TO_WIN_A, zRelative, zFull, nFull)<0 ){ |
| 35470 | return winLogError(SQLITE_CANTOPEN_CONVPATH, (DWORD)errno, |
| 35471 | "winFullPathname2", zRelative); |
| 35472 | } |
| 35473 | } |
| 35474 | return SQLITE_OK; |
| 35475 | #endif |
| 35476 | |
| @@ -35367,11 +35499,11 @@ | |
| 35499 | char *zOut; |
| 35500 | |
| 35501 | /* If this path name begins with "/X:", where "X" is any alphabetic |
| 35502 | ** character, discard the initial "/" from the pathname. |
| 35503 | */ |
| 35504 | if( zRelative[0]=='/' && winIsDriveLetterAndColon(zRelative+1) ){ |
| 35505 | zRelative++; |
| 35506 | } |
| 35507 | |
| 35508 | /* It's odd to simulate an io-error here, but really this is just |
| 35509 | ** using the io-error infrastructure to test that SQLite handles this |
| @@ -35388,36 +35520,34 @@ | |
| 35520 | */ |
| 35521 | sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%s%s", |
| 35522 | sqlite3_data_directory, winGetDirDep(), zRelative); |
| 35523 | return SQLITE_OK; |
| 35524 | } |
| 35525 | zConverted = winConvertFromUtf8Filename(zRelative); |
| 35526 | if( zConverted==0 ){ |
| 35527 | return SQLITE_IOERR_NOMEM; |
| 35528 | } |
| 35529 | if( osIsNT() ){ |
| 35530 | LPWSTR zTemp; |
| 35531 | nByte = osGetFullPathNameW((LPCWSTR)zConverted, 0, 0, 0); |
| 35532 | if( nByte==0 ){ |
| 35533 | sqlite3_free(zConverted); |
| 35534 | return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(), |
| 35535 | "winFullPathname1", zRelative); |
| 35536 | } |
| 35537 | nByte += 3; |
| 35538 | zTemp = sqlite3MallocZero( nByte*sizeof(zTemp[0]) ); |
| 35539 | if( zTemp==0 ){ |
| 35540 | sqlite3_free(zConverted); |
| 35541 | return SQLITE_IOERR_NOMEM; |
| 35542 | } |
| 35543 | nByte = osGetFullPathNameW((LPCWSTR)zConverted, nByte, zTemp, 0); |
| 35544 | if( nByte==0 ){ |
| 35545 | sqlite3_free(zConverted); |
| 35546 | sqlite3_free(zTemp); |
| 35547 | return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(), |
| 35548 | "winFullPathname2", zRelative); |
| 35549 | } |
| 35550 | sqlite3_free(zConverted); |
| 35551 | zOut = winUnicodeToUtf8(zTemp); |
| 35552 | sqlite3_free(zTemp); |
| 35553 | } |
| @@ -35424,28 +35554,26 @@ | |
| 35554 | #ifdef SQLITE_WIN32_HAS_ANSI |
| 35555 | else{ |
| 35556 | char *zTemp; |
| 35557 | nByte = osGetFullPathNameA((char*)zConverted, 0, 0, 0); |
| 35558 | if( nByte==0 ){ |
| 35559 | sqlite3_free(zConverted); |
| 35560 | return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(), |
| 35561 | "winFullPathname3", zRelative); |
| 35562 | } |
| 35563 | nByte += 3; |
| 35564 | zTemp = sqlite3MallocZero( nByte*sizeof(zTemp[0]) ); |
| 35565 | if( zTemp==0 ){ |
| 35566 | sqlite3_free(zConverted); |
| 35567 | return SQLITE_IOERR_NOMEM; |
| 35568 | } |
| 35569 | nByte = osGetFullPathNameA((char*)zConverted, nByte, zTemp, 0); |
| 35570 | if( nByte==0 ){ |
| 35571 | sqlite3_free(zConverted); |
| 35572 | sqlite3_free(zTemp); |
| 35573 | return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(), |
| 35574 | "winFullPathname4", zRelative); |
| 35575 | } |
| 35576 | sqlite3_free(zConverted); |
| 35577 | zOut = sqlite3_win32_mbcs_to_utf8(zTemp); |
| 35578 | sqlite3_free(zTemp); |
| 35579 | } |
| @@ -35469,11 +35597,11 @@ | |
| 35597 | ** Interfaces for opening a shared library, finding entry points |
| 35598 | ** within the shared library, and closing the shared library. |
| 35599 | */ |
| 35600 | static void *winDlOpen(sqlite3_vfs *pVfs, const char *zFilename){ |
| 35601 | HANDLE h; |
| 35602 | void *zConverted = winConvertFromUtf8Filename(zFilename); |
| 35603 | UNUSED_PARAMETER(pVfs); |
| 35604 | if( zConverted==0 ){ |
| 35605 | return 0; |
| 35606 | } |
| 35607 | if( osIsNT() ){ |
| @@ -60283,10 +60411,13 @@ | |
| 60411 | alloc.pParse = pParse; |
| 60412 | alloc.pIdx = pIdx; |
| 60413 | alloc.ppRec = ppRec; |
| 60414 | alloc.iVal = iVal; |
| 60415 | |
| 60416 | /* Skip over any TK_COLLATE nodes */ |
| 60417 | pExpr = sqlite3ExprSkipCollate(pExpr); |
| 60418 | |
| 60419 | if( !pExpr ){ |
| 60420 | pVal = valueNew(pParse->db, &alloc); |
| 60421 | if( pVal ){ |
| 60422 | sqlite3VdbeMemSetNull((Mem*)pVal); |
| 60423 | *pbOk = 1; |
| @@ -80950,11 +81081,11 @@ | |
| 81081 | ** SQLITE_ENABLE_STAT3 defined. The functionality of sqlite_stat3 |
| 81082 | ** is a superset of sqlite_stat2. The sqlite_stat4 is an enhanced |
| 81083 | ** version of sqlite_stat3 and is only available when compiled with |
| 81084 | ** SQLITE_ENABLE_STAT4 and in SQLite versions 3.8.0 and later. It is |
| 81085 | ** not possible to enable both STAT3 and STAT4 at the same time. If they |
| 81086 | ** are both enabled, then STAT4 takes precedence. |
| 81087 | ** |
| 81088 | ** For most applications, sqlite_stat1 provides all the statisics required |
| 81089 | ** for the query planner to make good choices. |
| 81090 | ** |
| 81091 | ** Format of sqlite_stat1: |
| @@ -81261,11 +81392,11 @@ | |
| 81392 | u8 *pSpace; /* Allocated space not yet assigned */ |
| 81393 | int i; /* Used to iterate through p->aSample[] */ |
| 81394 | |
| 81395 | p->iGet = -1; |
| 81396 | p->mxSample = mxSample; |
| 81397 | p->nPSample = (tRowcnt)(sqlite3_value_int64(argv[1])/(mxSample/3+1) + 1); |
| 81398 | p->current.anLt = &p->current.anEq[nColUp]; |
| 81399 | sqlite3_randomness(sizeof(p->iPrn), &p->iPrn); |
| 81400 | |
| 81401 | /* Set up the Stat4Accum.a[] and aBest[] arrays */ |
| 81402 | p->a = (struct Stat4Sample*)&p->current.anLt[nColUp]; |
| @@ -81298,29 +81429,68 @@ | |
| 81429 | 0, /* xFinalize */ |
| 81430 | "stat_init", /* zName */ |
| 81431 | 0, /* pHash */ |
| 81432 | 0 /* pDestructor */ |
| 81433 | }; |
| 81434 | |
| 81435 | #ifdef SQLITE_ENABLE_STAT4 |
| 81436 | /* |
| 81437 | ** pNew and pOld are both candidate non-periodic samples selected for |
| 81438 | ** the same column (pNew->iCol==pOld->iCol). Ignoring this column and |
| 81439 | ** considering only any trailing columns and the sample hash value, this |
| 81440 | ** function returns true if sample pNew is to be preferred over pOld. |
| 81441 | ** In other words, if we assume that the cardinalities of the selected |
| 81442 | ** column for pNew and pOld are equal, is pNew to be preferred over pOld. |
| 81443 | ** |
| 81444 | ** This function assumes that for each argument sample, the contents of |
| 81445 | ** the anEq[] array from pSample->anEq[pSample->iCol+1] onwards are valid. |
| 81446 | */ |
| 81447 | static int sampleIsBetterPost( |
| 81448 | Stat4Accum *pAccum, |
| 81449 | Stat4Sample *pNew, |
| 81450 | Stat4Sample *pOld |
| 81451 | ){ |
| 81452 | int nCol = pAccum->nCol; |
| 81453 | int i; |
| 81454 | assert( pNew->iCol==pOld->iCol ); |
| 81455 | for(i=pNew->iCol+1; i<nCol; i++){ |
| 81456 | if( pNew->anEq[i]>pOld->anEq[i] ) return 1; |
| 81457 | if( pNew->anEq[i]<pOld->anEq[i] ) return 0; |
| 81458 | } |
| 81459 | if( pNew->iHash>pOld->iHash ) return 1; |
| 81460 | return 0; |
| 81461 | } |
| 81462 | #endif |
| 81463 | |
| 81464 | #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 81465 | /* |
| 81466 | ** Return true if pNew is to be preferred over pOld. |
| 81467 | ** |
| 81468 | ** This function assumes that for each argument sample, the contents of |
| 81469 | ** the anEq[] array from pSample->anEq[pSample->iCol] onwards are valid. |
| 81470 | */ |
| 81471 | static int sampleIsBetter( |
| 81472 | Stat4Accum *pAccum, |
| 81473 | Stat4Sample *pNew, |
| 81474 | Stat4Sample *pOld |
| 81475 | ){ |
| 81476 | tRowcnt nEqNew = pNew->anEq[pNew->iCol]; |
| 81477 | tRowcnt nEqOld = pOld->anEq[pOld->iCol]; |
| 81478 | |
| 81479 | assert( pOld->isPSample==0 && pNew->isPSample==0 ); |
| 81480 | assert( IsStat4 || (pNew->iCol==0 && pOld->iCol==0) ); |
| 81481 | |
| 81482 | if( (nEqNew>nEqOld) ) return 1; |
| 81483 | #ifdef SQLITE_ENABLE_STAT4 |
| 81484 | if( nEqNew==nEqOld ){ |
| 81485 | if( pNew->iCol<pOld->iCol ) return 1; |
| 81486 | return (pNew->iCol==pOld->iCol && sampleIsBetterPost(pAccum, pNew, pOld)); |
| 81487 | } |
| 81488 | return 0; |
| 81489 | #else |
| 81490 | return (nEqNew==nEqOld && pNew->iHash>pOld->iHash); |
| 81491 | #endif |
| 81492 | } |
| 81493 | |
| 81494 | /* |
| 81495 | ** Copy the contents of object (*pFrom) into (*pTo). |
| 81496 | */ |
| @@ -81339,12 +81509,10 @@ | |
| 81509 | ** remove the least desirable sample from p->a[] to make room. |
| 81510 | */ |
| 81511 | static void sampleInsert(Stat4Accum *p, Stat4Sample *pNew, int nEqZero){ |
| 81512 | Stat4Sample *pSample; |
| 81513 | int i; |
| 81514 | |
| 81515 | assert( IsStat4 || nEqZero==0 ); |
| 81516 | |
| 81517 | if( pNew->isPSample==0 ){ |
| 81518 | Stat4Sample *pUpgrade = 0; |
| @@ -81357,12 +81525,13 @@ | |
| 81525 | ** existing sample that shares this prefix. */ |
| 81526 | for(i=p->nSample-1; i>=0; i--){ |
| 81527 | Stat4Sample *pOld = &p->a[i]; |
| 81528 | if( pOld->anEq[pNew->iCol]==0 ){ |
| 81529 | if( pOld->isPSample ) return; |
| 81530 | assert( pOld->iCol>pNew->iCol ); |
| 81531 | assert( sampleIsBetter(p, pNew, pOld) ); |
| 81532 | if( pUpgrade==0 || sampleIsBetter(p, pOld, pUpgrade) ){ |
| 81533 | pUpgrade = pOld; |
| 81534 | } |
| 81535 | } |
| 81536 | } |
| 81537 | if( pUpgrade ){ |
| @@ -81384,40 +81553,32 @@ | |
| 81553 | pSample->anDLt = anDLt; |
| 81554 | pSample->anLt = anLt; |
| 81555 | p->nSample = p->mxSample-1; |
| 81556 | } |
| 81557 | |
| 81558 | /* The "rows less-than" for the rowid column must be greater than that |
| 81559 | ** for the last sample in the p->a[] array. Otherwise, the samples would |
| 81560 | ** be out of order. */ |
| 81561 | #ifdef SQLITE_ENABLE_STAT4 |
| 81562 | assert( p->nSample==0 |
| 81563 | || pNew->anLt[p->nCol-1] > p->a[p->nSample-1].anLt[p->nCol-1] ); |
| 81564 | #endif |
| 81565 | |
| 81566 | /* Insert the new sample */ |
| 81567 | pSample = &p->a[p->nSample]; |
| 81568 | sampleCopy(p, pSample, pNew); |
| 81569 | p->nSample++; |
| 81570 | |
| 81571 | /* Zero the first nEqZero entries in the anEq[] array. */ |
| 81572 | memset(pSample->anEq, 0, sizeof(tRowcnt)*nEqZero); |
| 81573 | |
| 81574 | find_new_min: |
| 81575 | if( p->nSample>=p->mxSample ){ |
| 81576 | int iMin = -1; |
| 81577 | for(i=0; i<p->mxSample; i++){ |
| 81578 | if( p->a[i].isPSample ) continue; |
| 81579 | if( iMin<0 || sampleIsBetter(p, &p->a[iMin], &p->a[i]) ){ |
| 81580 | iMin = i; |
| 81581 | } |
| 81582 | } |
| 81583 | assert( iMin>=0 ); |
| 81584 | p->iMin = iMin; |
| @@ -81437,13 +81598,12 @@ | |
| 81598 | |
| 81599 | /* Check if any samples from the aBest[] array should be pushed |
| 81600 | ** into IndexSample.a[] at this point. */ |
| 81601 | for(i=(p->nCol-2); i>=iChng; i--){ |
| 81602 | Stat4Sample *pBest = &p->aBest[i]; |
| 81603 | pBest->anEq[i] = p->current.anEq[i]; |
| 81604 | if( p->nSample<p->mxSample || sampleIsBetter(p, pBest, &p->a[p->iMin]) ){ |
| 81605 | sampleInsert(p, pBest, i); |
| 81606 | } |
| 81607 | } |
| 81608 | |
| 81609 | /* Update the anEq[] fields of any samples already collected. */ |
| @@ -81466,11 +81626,13 @@ | |
| 81626 | sampleInsert(p, &p->current, 0); |
| 81627 | p->current.isPSample = 0; |
| 81628 | }else |
| 81629 | |
| 81630 | /* Or if it is a non-periodic sample. Add it in this case too. */ |
| 81631 | if( p->nSample<p->mxSample |
| 81632 | || sampleIsBetter(p, &p->current, &p->a[p->iMin]) |
| 81633 | ){ |
| 81634 | sampleInsert(p, &p->current, 0); |
| 81635 | } |
| 81636 | } |
| 81637 | #endif |
| 81638 | } |
| @@ -81500,12 +81662,11 @@ | |
| 81662 | |
| 81663 | assert( p->nCol>1 ); /* Includes rowid field */ |
| 81664 | assert( iChng<p->nCol ); |
| 81665 | |
| 81666 | if( p->nRow==0 ){ |
| 81667 | /* This is the first call to this function. Do initialization. */ |
| 81668 | for(i=0; i<p->nCol; i++) p->current.anEq[i] = 1; |
| 81669 | }else{ |
| 81670 | /* Second and subsequent calls get processed here */ |
| 81671 | samplePushPrevious(p, iChng); |
| 81672 | |
| @@ -81541,11 +81702,11 @@ | |
| 81702 | } |
| 81703 | |
| 81704 | /* Update the aBest[] array. */ |
| 81705 | for(i=0; i<(p->nCol-1); i++){ |
| 81706 | p->current.iCol = i; |
| 81707 | if( i>=iChng || sampleIsBetterPost(p, &p->current, &p->aBest[i]) ){ |
| 81708 | sampleCopy(p, &p->aBest[i], &p->current); |
| 81709 | } |
| 81710 | } |
| 81711 | } |
| 81712 | #endif |
| @@ -82249,11 +82410,11 @@ | |
| 82410 | IndexSample *pFinal = &aSample[pIdx->nSample-1]; |
| 82411 | int iCol; |
| 82412 | for(iCol=0; iCol<pIdx->nColumn; iCol++){ |
| 82413 | int i; /* Used to iterate through samples */ |
| 82414 | tRowcnt sumEq = 0; /* Sum of the nEq values */ |
| 82415 | tRowcnt nSum = 0; /* Number of terms contributing to sumEq */ |
| 82416 | tRowcnt avgEq = 0; |
| 82417 | tRowcnt nDLt = pFinal->anDLt[iCol]; |
| 82418 | |
| 82419 | /* Set nSum to the number of distinct (iCol+1) field prefixes that |
| 82420 | ** occur in the stat4 table for this index before pFinal. Set |
| @@ -105797,13 +105958,13 @@ | |
| 105958 | /* |
| 105959 | ** Each instance of this object holds a sequence of WhereLoop objects |
| 105960 | ** that implement some or all of a query plan. |
| 105961 | ** |
| 105962 | ** Think of each WhereLoop object as a node in a graph with arcs |
| 105963 | ** showing dependencies and costs for travelling between nodes. (That is |
| 105964 | ** not a completely accurate description because WhereLoop costs are a |
| 105965 | ** vector, not a scalar, and because dependencies are many-to-one, not |
| 105966 | ** one-to-one as are graph nodes. But it is a useful visualization aid.) |
| 105967 | ** Then a WherePath object is a path through the graph that visits some |
| 105968 | ** or all of the WhereLoop objects once. |
| 105969 | ** |
| 105970 | ** The "solver" works by creating the N best WherePath objects of length |
| @@ -108165,11 +108326,16 @@ | |
| 108326 | && p->nSample |
| 108327 | && OptimizationEnabled(pParse->db, SQLITE_Stat3) |
| 108328 | ){ |
| 108329 | UnpackedRecord *pRec = pBuilder->pRec; |
| 108330 | tRowcnt a[2]; |
| 108331 | u8 aff; |
| 108332 | if( nEq==p->nColumn ){ |
| 108333 | aff = SQLITE_AFF_INTEGER; |
| 108334 | }else{ |
| 108335 | aff = p->pTable->aCol[p->aiColumn[nEq]].affinity; |
| 108336 | } |
| 108337 | |
| 108338 | /* Variable iLower will be set to the estimate of the number of rows in |
| 108339 | ** the index that are less than the lower bound of the range query. The |
| 108340 | ** lower bound being the concatenation of $P and $L, where $P is the |
| 108341 | ** key-prefix formed by the nEq values matched against the nEq left-most |
| @@ -109781,19 +109947,21 @@ | |
| 109947 | assert( p->rSetup>=pTemplate->rSetup ); |
| 109948 | |
| 109949 | if( (p->prereq & pTemplate->prereq)==p->prereq |
| 109950 | && p->rSetup<=pTemplate->rSetup |
| 109951 | && p->rRun<=pTemplate->rRun |
| 109952 | && p->nOut<=pTemplate->nOut |
| 109953 | ){ |
| 109954 | /* This branch taken when p is equal or better than pTemplate in |
| 109955 | ** all of (1) dependencies (2) setup-cost, (3) run-cost, and |
| 109956 | ** (4) number of output rows. */ |
| 109957 | assert( p->rSetup==pTemplate->rSetup ); |
| 109958 | if( p->prereq==pTemplate->prereq |
| 109959 | && p->nLTerm<pTemplate->nLTerm |
| 109960 | && (p->wsFlags & WHERE_INDEXED)!=0 |
| 109961 | && (pTemplate->wsFlags & WHERE_INDEXED)!=0 |
| 109962 | && p->u.btree.pIndex==pTemplate->u.btree.pIndex |
| 109963 | ){ |
| 109964 | /* Overwrite an existing WhereLoop with an similar one that uses |
| 109965 | ** more terms of the index */ |
| 109966 | pNext = p->pNextLoop; |
| 109967 | break; |
| @@ -109803,15 +109971,17 @@ | |
| 109971 | goto whereLoopInsert_noop; |
| 109972 | } |
| 109973 | } |
| 109974 | if( (p->prereq & pTemplate->prereq)==pTemplate->prereq |
| 109975 | && p->rRun>=pTemplate->rRun |
| 109976 | && p->nOut>=pTemplate->nOut |
| 109977 | && ALWAYS(p->rSetup>=pTemplate->rSetup) /* See SETUP-INVARIANT above */ |
| 109978 | ){ |
| 109979 | /* Overwrite an existing WhereLoop with a better one: one that is |
| 109980 | ** better at one of (1) dependencies, (2) setup-cost, (3) run-cost |
| 109981 | ** or (4) number of output rows, and is no worse in any of those |
| 109982 | ** categories. */ |
| 109983 | pNext = p->pNextLoop; |
| 109984 | break; |
| 109985 | } |
| 109986 | } |
| 109987 | |
| @@ -111512,11 +111682,11 @@ | |
| 111682 | if( pWInfo->nLevel>=2 |
| 111683 | && pResultSet!=0 |
| 111684 | && OptimizationEnabled(db, SQLITE_OmitNoopJoin) |
| 111685 | ){ |
| 111686 | Bitmask tabUsed = exprListTableUsage(pMaskSet, pResultSet); |
| 111687 | if( sWLB.pOrderBy ) tabUsed |= exprListTableUsage(pMaskSet, sWLB.pOrderBy); |
| 111688 | while( pWInfo->nLevel>=2 ){ |
| 111689 | WhereTerm *pTerm, *pEnd; |
| 111690 | pLoop = pWInfo->a[pWInfo->nLevel-1].pWLoop; |
| 111691 | if( (pWInfo->pTabList->a[pLoop->iTab].jointype & JT_LEFT)==0 ) break; |
| 111692 | if( (wctrlFlags & WHERE_WANT_DISTINCT)==0 |
| @@ -117544,18 +117714,20 @@ | |
| 117714 | case SQLITE_IOERR_SHMMAP: zName = "SQLITE_IOERR_SHMMAP"; break; |
| 117715 | case SQLITE_IOERR_SEEK: zName = "SQLITE_IOERR_SEEK"; break; |
| 117716 | case SQLITE_IOERR_DELETE_NOENT: zName = "SQLITE_IOERR_DELETE_NOENT";break; |
| 117717 | case SQLITE_IOERR_MMAP: zName = "SQLITE_IOERR_MMAP"; break; |
| 117718 | case SQLITE_IOERR_GETTEMPPATH: zName = "SQLITE_IOERR_GETTEMPPATH"; break; |
| 117719 | case SQLITE_IOERR_CONVPATH: zName = "SQLITE_IOERR_CONVPATH"; break; |
| 117720 | case SQLITE_CORRUPT: zName = "SQLITE_CORRUPT"; break; |
| 117721 | case SQLITE_CORRUPT_VTAB: zName = "SQLITE_CORRUPT_VTAB"; break; |
| 117722 | case SQLITE_NOTFOUND: zName = "SQLITE_NOTFOUND"; break; |
| 117723 | case SQLITE_FULL: zName = "SQLITE_FULL"; break; |
| 117724 | case SQLITE_CANTOPEN: zName = "SQLITE_CANTOPEN"; break; |
| 117725 | case SQLITE_CANTOPEN_NOTEMPDIR: zName = "SQLITE_CANTOPEN_NOTEMPDIR";break; |
| 117726 | case SQLITE_CANTOPEN_ISDIR: zName = "SQLITE_CANTOPEN_ISDIR"; break; |
| 117727 | case SQLITE_CANTOPEN_FULLPATH: zName = "SQLITE_CANTOPEN_FULLPATH"; break; |
| 117728 | case SQLITE_CANTOPEN_CONVPATH: zName = "SQLITE_CANTOPEN_CONVPATH"; break; |
| 117729 | case SQLITE_PROTOCOL: zName = "SQLITE_PROTOCOL"; break; |
| 117730 | case SQLITE_EMPTY: zName = "SQLITE_EMPTY"; break; |
| 117731 | case SQLITE_SCHEMA: zName = "SQLITE_SCHEMA"; break; |
| 117732 | case SQLITE_TOOBIG: zName = "SQLITE_TOOBIG"; break; |
| 117733 | case SQLITE_CONSTRAINT: zName = "SQLITE_CONSTRAINT"; break; |
| 117734 |
+3
-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.8.1" |
| 111 | 111 | #define SQLITE_VERSION_NUMBER 3008001 |
| 112 | -#define SQLITE_SOURCE_ID "2013-08-30 06:20:23 d9c018f8155ab48df8e0e02519bba50588fe49fc" | |
| 112 | +#define SQLITE_SOURCE_ID "2013-09-03 14:43:12 d59f580904e6e7e90fc0a692a3dd4eeff5942479" | |
| 113 | 113 | |
| 114 | 114 | /* |
| 115 | 115 | ** CAPI3REF: Run-Time Library Version Numbers |
| 116 | 116 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 117 | 117 | ** |
| @@ -477,16 +477,18 @@ | ||
| 477 | 477 | #define SQLITE_IOERR_SHMMAP (SQLITE_IOERR | (21<<8)) |
| 478 | 478 | #define SQLITE_IOERR_SEEK (SQLITE_IOERR | (22<<8)) |
| 479 | 479 | #define SQLITE_IOERR_DELETE_NOENT (SQLITE_IOERR | (23<<8)) |
| 480 | 480 | #define SQLITE_IOERR_MMAP (SQLITE_IOERR | (24<<8)) |
| 481 | 481 | #define SQLITE_IOERR_GETTEMPPATH (SQLITE_IOERR | (25<<8)) |
| 482 | +#define SQLITE_IOERR_CONVPATH (SQLITE_IOERR | (26<<8)) | |
| 482 | 483 | #define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8)) |
| 483 | 484 | #define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8)) |
| 484 | 485 | #define SQLITE_BUSY_SNAPSHOT (SQLITE_BUSY | (2<<8)) |
| 485 | 486 | #define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8)) |
| 486 | 487 | #define SQLITE_CANTOPEN_ISDIR (SQLITE_CANTOPEN | (2<<8)) |
| 487 | 488 | #define SQLITE_CANTOPEN_FULLPATH (SQLITE_CANTOPEN | (3<<8)) |
| 489 | +#define SQLITE_CANTOPEN_CONVPATH (SQLITE_CANTOPEN | (4<<8)) | |
| 488 | 490 | #define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8)) |
| 489 | 491 | #define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8)) |
| 490 | 492 | #define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8)) |
| 491 | 493 | #define SQLITE_READONLY_ROLLBACK (SQLITE_READONLY | (3<<8)) |
| 492 | 494 | #define SQLITE_ABORT_ROLLBACK (SQLITE_ABORT | (2<<8)) |
| 493 | 495 |
| --- 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.8.1" |
| 111 | #define SQLITE_VERSION_NUMBER 3008001 |
| 112 | #define SQLITE_SOURCE_ID "2013-08-30 06:20:23 d9c018f8155ab48df8e0e02519bba50588fe49fc" |
| 113 | |
| 114 | /* |
| 115 | ** CAPI3REF: Run-Time Library Version Numbers |
| 116 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 117 | ** |
| @@ -477,16 +477,18 @@ | |
| 477 | #define SQLITE_IOERR_SHMMAP (SQLITE_IOERR | (21<<8)) |
| 478 | #define SQLITE_IOERR_SEEK (SQLITE_IOERR | (22<<8)) |
| 479 | #define SQLITE_IOERR_DELETE_NOENT (SQLITE_IOERR | (23<<8)) |
| 480 | #define SQLITE_IOERR_MMAP (SQLITE_IOERR | (24<<8)) |
| 481 | #define SQLITE_IOERR_GETTEMPPATH (SQLITE_IOERR | (25<<8)) |
| 482 | #define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8)) |
| 483 | #define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8)) |
| 484 | #define SQLITE_BUSY_SNAPSHOT (SQLITE_BUSY | (2<<8)) |
| 485 | #define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8)) |
| 486 | #define SQLITE_CANTOPEN_ISDIR (SQLITE_CANTOPEN | (2<<8)) |
| 487 | #define SQLITE_CANTOPEN_FULLPATH (SQLITE_CANTOPEN | (3<<8)) |
| 488 | #define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8)) |
| 489 | #define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8)) |
| 490 | #define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8)) |
| 491 | #define SQLITE_READONLY_ROLLBACK (SQLITE_READONLY | (3<<8)) |
| 492 | #define SQLITE_ABORT_ROLLBACK (SQLITE_ABORT | (2<<8)) |
| 493 |
| --- 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.8.1" |
| 111 | #define SQLITE_VERSION_NUMBER 3008001 |
| 112 | #define SQLITE_SOURCE_ID "2013-09-03 14:43:12 d59f580904e6e7e90fc0a692a3dd4eeff5942479" |
| 113 | |
| 114 | /* |
| 115 | ** CAPI3REF: Run-Time Library Version Numbers |
| 116 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 117 | ** |
| @@ -477,16 +477,18 @@ | |
| 477 | #define SQLITE_IOERR_SHMMAP (SQLITE_IOERR | (21<<8)) |
| 478 | #define SQLITE_IOERR_SEEK (SQLITE_IOERR | (22<<8)) |
| 479 | #define SQLITE_IOERR_DELETE_NOENT (SQLITE_IOERR | (23<<8)) |
| 480 | #define SQLITE_IOERR_MMAP (SQLITE_IOERR | (24<<8)) |
| 481 | #define SQLITE_IOERR_GETTEMPPATH (SQLITE_IOERR | (25<<8)) |
| 482 | #define SQLITE_IOERR_CONVPATH (SQLITE_IOERR | (26<<8)) |
| 483 | #define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8)) |
| 484 | #define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8)) |
| 485 | #define SQLITE_BUSY_SNAPSHOT (SQLITE_BUSY | (2<<8)) |
| 486 | #define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8)) |
| 487 | #define SQLITE_CANTOPEN_ISDIR (SQLITE_CANTOPEN | (2<<8)) |
| 488 | #define SQLITE_CANTOPEN_FULLPATH (SQLITE_CANTOPEN | (3<<8)) |
| 489 | #define SQLITE_CANTOPEN_CONVPATH (SQLITE_CANTOPEN | (4<<8)) |
| 490 | #define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8)) |
| 491 | #define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8)) |
| 492 | #define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8)) |
| 493 | #define SQLITE_READONLY_ROLLBACK (SQLITE_READONLY | (3<<8)) |
| 494 | #define SQLITE_ABORT_ROLLBACK (SQLITE_ABORT | (2<<8)) |
| 495 |