Fossil SCM
Load the latest SQLite library from upstream, for the purpose of testing the 3.7.17 beta of SQLite in a real-world application.
Commit
997ebf7ff4d0c02d1ccd8e8c2f0fed592ac35c9f
Parent
b388e7347d04ce2…
2 files changed
+320
-94
+1
-1
+320
-94
| --- src/sqlite3.c | ||
| +++ src/sqlite3.c | ||
| @@ -678,11 +678,11 @@ | ||
| 678 | 678 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 679 | 679 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 680 | 680 | */ |
| 681 | 681 | #define SQLITE_VERSION "3.7.17" |
| 682 | 682 | #define SQLITE_VERSION_NUMBER 3007017 |
| 683 | -#define SQLITE_SOURCE_ID "2013-05-08 17:06:28 1fa8c457394c94864f7584e4c893ec09e685fba4" | |
| 683 | +#define SQLITE_SOURCE_ID "2013-05-15 18:34:17 00231fb0127960d700de3549e34e82f8ec1b5819" | |
| 684 | 684 | |
| 685 | 685 | /* |
| 686 | 686 | ** CAPI3REF: Run-Time Library Version Numbers |
| 687 | 687 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 688 | 688 | ** |
| @@ -12251,10 +12251,16 @@ | ||
| 12251 | 12251 | SQLITE_PRIVATE int sqlite3Atoi64(const char*, i64*, int, u8); |
| 12252 | 12252 | SQLITE_PRIVATE void sqlite3Error(sqlite3*, int, const char*,...); |
| 12253 | 12253 | SQLITE_PRIVATE void *sqlite3HexToBlob(sqlite3*, const char *z, int n); |
| 12254 | 12254 | SQLITE_PRIVATE u8 sqlite3HexToInt(int h); |
| 12255 | 12255 | SQLITE_PRIVATE int sqlite3TwoPartName(Parse *, Token *, Token *, Token **); |
| 12256 | + | |
| 12257 | +#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) || \ | |
| 12258 | + defined(SQLITE_DEBUG_OS_TRACE) | |
| 12259 | +SQLITE_PRIVATE const char *sqlite3ErrName(int); | |
| 12260 | +#endif | |
| 12261 | + | |
| 12256 | 12262 | SQLITE_PRIVATE const char *sqlite3ErrStr(int); |
| 12257 | 12263 | SQLITE_PRIVATE int sqlite3ReadSchema(Parse *pParse); |
| 12258 | 12264 | SQLITE_PRIVATE CollSeq *sqlite3FindCollSeq(sqlite3*,u8 enc, const char*,int); |
| 12259 | 12265 | SQLITE_PRIVATE CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char*zName); |
| 12260 | 12266 | SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr); |
| @@ -26237,10 +26243,12 @@ | ||
| 26237 | 26243 | sqlite3_int64 offset |
| 26238 | 26244 | ){ |
| 26239 | 26245 | unixFile *pFile = (unixFile *)id; |
| 26240 | 26246 | int got; |
| 26241 | 26247 | assert( id ); |
| 26248 | + assert( offset>=0 ); | |
| 26249 | + assert( amt>0 ); | |
| 26242 | 26250 | |
| 26243 | 26251 | /* If this is a database file (not a journal, master-journal or temp |
| 26244 | 26252 | ** file), the bytes in the locking range should never be read or written. */ |
| 26245 | 26253 | #if 0 |
| 26246 | 26254 | assert( pFile->pUnused==0 |
| @@ -32230,11 +32238,11 @@ | ||
| 32230 | 32238 | osLocalFree(zTemp); |
| 32231 | 32239 | } |
| 32232 | 32240 | } |
| 32233 | 32241 | #endif |
| 32234 | 32242 | if( 0 == dwLen ){ |
| 32235 | - sqlite3_snprintf(nBuf, zBuf, "OsError 0x%x (%u)", lastErrno, lastErrno); | |
| 32243 | + sqlite3_snprintf(nBuf, zBuf, "OsError 0x%lx (%lu)", lastErrno, lastErrno); | |
| 32236 | 32244 | }else{ |
| 32237 | 32245 | /* copy a maximum of nBuf chars to output buffer */ |
| 32238 | 32246 | sqlite3_snprintf(nBuf, zBuf, "%s", zOut); |
| 32239 | 32247 | /* free the UTF8 buffer */ |
| 32240 | 32248 | sqlite3_free(zOut); |
| @@ -32273,11 +32281,11 @@ | ||
| 32273 | 32281 | assert( errcode!=SQLITE_OK ); |
| 32274 | 32282 | if( zPath==0 ) zPath = ""; |
| 32275 | 32283 | for(i=0; zMsg[i] && zMsg[i]!='\r' && zMsg[i]!='\n'; i++){} |
| 32276 | 32284 | zMsg[i] = 0; |
| 32277 | 32285 | sqlite3_log(errcode, |
| 32278 | - "os_win.c:%d: (%d) %s(%s) - %s", | |
| 32286 | + "os_win.c:%d: (%lu) %s(%s) - %s", | |
| 32279 | 32287 | iLine, lastErrno, zFunc, zPath, zMsg |
| 32280 | 32288 | ); |
| 32281 | 32289 | |
| 32282 | 32290 | return errcode; |
| 32283 | 32291 | } |
| @@ -32734,10 +32742,12 @@ | ||
| 32734 | 32742 | LONG upperBits; /* Most sig. 32 bits of new offset */ |
| 32735 | 32743 | LONG lowerBits; /* Least sig. 32 bits of new offset */ |
| 32736 | 32744 | DWORD dwRet; /* Value returned by SetFilePointer() */ |
| 32737 | 32745 | DWORD lastErrno; /* Value returned by GetLastError() */ |
| 32738 | 32746 | |
| 32747 | + OSTRACE(("SEEK file=%p, offset=%lld\n", pFile->h, iOffset)); | |
| 32748 | + | |
| 32739 | 32749 | upperBits = (LONG)((iOffset>>32) & 0x7fffffff); |
| 32740 | 32750 | lowerBits = (LONG)(iOffset & 0xffffffff); |
| 32741 | 32751 | |
| 32742 | 32752 | /* API oddity: If successful, SetFilePointer() returns a dword |
| 32743 | 32753 | ** containing the lower 32-bits of the new file-offset. Or, if it fails, |
| @@ -32751,13 +32761,15 @@ | ||
| 32751 | 32761 | if( (dwRet==INVALID_SET_FILE_POINTER |
| 32752 | 32762 | && ((lastErrno = osGetLastError())!=NO_ERROR)) ){ |
| 32753 | 32763 | pFile->lastErrno = lastErrno; |
| 32754 | 32764 | winLogError(SQLITE_IOERR_SEEK, pFile->lastErrno, |
| 32755 | 32765 | "seekWinFile", pFile->zPath); |
| 32766 | + OSTRACE(("SEEK file=%p, rc=SQLITE_IOERR_SEEK\n", pFile->h)); | |
| 32756 | 32767 | return 1; |
| 32757 | 32768 | } |
| 32758 | 32769 | |
| 32770 | + OSTRACE(("SEEK file=%p, rc=SQLITE_OK\n", pFile->h)); | |
| 32759 | 32771 | return 0; |
| 32760 | 32772 | #else |
| 32761 | 32773 | /* |
| 32762 | 32774 | ** Same as above, except that this implementation works for WinRT. |
| 32763 | 32775 | */ |
| @@ -32770,13 +32782,15 @@ | ||
| 32770 | 32782 | |
| 32771 | 32783 | if(!bRet){ |
| 32772 | 32784 | pFile->lastErrno = osGetLastError(); |
| 32773 | 32785 | winLogError(SQLITE_IOERR_SEEK, pFile->lastErrno, |
| 32774 | 32786 | "seekWinFile", pFile->zPath); |
| 32787 | + OSTRACE(("SEEK file=%p, rc=SQLITE_IOERR_SEEK\n", pFile->h)); | |
| 32775 | 32788 | return 1; |
| 32776 | 32789 | } |
| 32777 | 32790 | |
| 32791 | + OSTRACE(("SEEK file=%p, rc=SQLITE_OK\n", pFile->h)); | |
| 32778 | 32792 | return 0; |
| 32779 | 32793 | #endif |
| 32780 | 32794 | } |
| 32781 | 32795 | |
| 32782 | 32796 | #if SQLITE_MAX_MMAP_SIZE>0 |
| @@ -32801,12 +32815,12 @@ | ||
| 32801 | 32815 | |
| 32802 | 32816 | assert( id!=0 ); |
| 32803 | 32817 | #ifndef SQLITE_OMIT_WAL |
| 32804 | 32818 | assert( pFile->pShm==0 ); |
| 32805 | 32819 | #endif |
| 32806 | - OSTRACE(("CLOSE %d\n", pFile->h)); | |
| 32807 | 32820 | assert( pFile->h!=NULL && pFile->h!=INVALID_HANDLE_VALUE ); |
| 32821 | + OSTRACE(("CLOSE file=%p\n", pFile->h)); | |
| 32808 | 32822 | |
| 32809 | 32823 | #if SQLITE_MAX_MMAP_SIZE>0 |
| 32810 | 32824 | rc = winUnmapfile(pFile); |
| 32811 | 32825 | if( rc!=SQLITE_OK ) return rc; |
| 32812 | 32826 | #endif |
| @@ -32828,15 +32842,15 @@ | ||
| 32828 | 32842 | sqlite3_win32_sleep(100); /* Wait a little before trying again */ |
| 32829 | 32843 | } |
| 32830 | 32844 | sqlite3_free(pFile->zDeleteOnClose); |
| 32831 | 32845 | } |
| 32832 | 32846 | #endif |
| 32833 | - OSTRACE(("CLOSE %d %s\n", pFile->h, rc ? "ok" : "failed")); | |
| 32834 | 32847 | if( rc ){ |
| 32835 | 32848 | pFile->h = NULL; |
| 32836 | 32849 | } |
| 32837 | 32850 | OpenCounter(-1); |
| 32851 | + OSTRACE(("CLOSE file=%p, rc=%s\n", pFile->h, rc ? "ok" : "failed")); | |
| 32838 | 32852 | return rc ? SQLITE_OK |
| 32839 | 32853 | : winLogError(SQLITE_IOERR_CLOSE, osGetLastError(), |
| 32840 | 32854 | "winClose", pFile->zPath); |
| 32841 | 32855 | } |
| 32842 | 32856 | |
| @@ -32858,19 +32872,22 @@ | ||
| 32858 | 32872 | DWORD nRead; /* Number of bytes actually read from file */ |
| 32859 | 32873 | int nRetry = 0; /* Number of retrys */ |
| 32860 | 32874 | |
| 32861 | 32875 | assert( id!=0 ); |
| 32862 | 32876 | assert( amt>0 ); |
| 32877 | + assert( offset>=0 ); | |
| 32863 | 32878 | SimulateIOError(return SQLITE_IOERR_READ); |
| 32864 | - OSTRACE(("READ %d lock=%d\n", pFile->h, pFile->locktype)); | |
| 32879 | + OSTRACE(("READ file=%p, buffer=%p, amount=%d, offset=%lld, lock=%d\n", | |
| 32880 | + pFile->h, pBuf, amt, offset, pFile->locktype)); | |
| 32865 | 32881 | |
| 32866 | 32882 | #if SQLITE_MAX_MMAP_SIZE>0 |
| 32867 | 32883 | /* Deal with as much of this read request as possible by transfering |
| 32868 | 32884 | ** data from the memory mapping using memcpy(). */ |
| 32869 | 32885 | if( offset<pFile->mmapSize ){ |
| 32870 | 32886 | if( offset+amt <= pFile->mmapSize ){ |
| 32871 | 32887 | memcpy(pBuf, &((u8 *)(pFile->pMapRegion))[offset], amt); |
| 32888 | + OSTRACE(("READ-MMAP file=%p, rc=SQLITE_OK\n", pFile->h)); | |
| 32872 | 32889 | return SQLITE_OK; |
| 32873 | 32890 | }else{ |
| 32874 | 32891 | int nCopy = (int)(pFile->mmapSize - offset); |
| 32875 | 32892 | memcpy(pBuf, &((u8 *)(pFile->pMapRegion))[offset], nCopy); |
| 32876 | 32893 | pBuf = &((u8 *)pBuf)[nCopy]; |
| @@ -32880,10 +32897,11 @@ | ||
| 32880 | 32897 | } |
| 32881 | 32898 | #endif |
| 32882 | 32899 | |
| 32883 | 32900 | #if SQLITE_OS_WINCE |
| 32884 | 32901 | if( seekWinFile(pFile, offset) ){ |
| 32902 | + OSTRACE(("READ file=%p, rc=SQLITE_FULL\n", pFile->h)); | |
| 32885 | 32903 | return SQLITE_FULL; |
| 32886 | 32904 | } |
| 32887 | 32905 | while( !osReadFile(pFile->h, pBuf, amt, &nRead, 0) ){ |
| 32888 | 32906 | #else |
| 32889 | 32907 | memset(&overlapped, 0, sizeof(OVERLAPPED)); |
| @@ -32893,20 +32911,23 @@ | ||
| 32893 | 32911 | osGetLastError()!=ERROR_HANDLE_EOF ){ |
| 32894 | 32912 | #endif |
| 32895 | 32913 | DWORD lastErrno; |
| 32896 | 32914 | if( retryIoerr(&nRetry, &lastErrno) ) continue; |
| 32897 | 32915 | pFile->lastErrno = lastErrno; |
| 32916 | + OSTRACE(("READ file=%p, rc=SQLITE_IOERR_READ\n", pFile->h)); | |
| 32898 | 32917 | return winLogError(SQLITE_IOERR_READ, pFile->lastErrno, |
| 32899 | 32918 | "winRead", pFile->zPath); |
| 32900 | 32919 | } |
| 32901 | 32920 | logIoerr(nRetry); |
| 32902 | 32921 | if( nRead<(DWORD)amt ){ |
| 32903 | 32922 | /* Unread parts of the buffer must be zero-filled */ |
| 32904 | 32923 | memset(&((char*)pBuf)[nRead], 0, amt-nRead); |
| 32924 | + OSTRACE(("READ file=%p, rc=SQLITE_IOERR_SHORT_READ\n", pFile->h)); | |
| 32905 | 32925 | return SQLITE_IOERR_SHORT_READ; |
| 32906 | 32926 | } |
| 32907 | 32927 | |
| 32928 | + OSTRACE(("READ file=%p, rc=SQLITE_OK\n", pFile->h)); | |
| 32908 | 32929 | return SQLITE_OK; |
| 32909 | 32930 | } |
| 32910 | 32931 | |
| 32911 | 32932 | /* |
| 32912 | 32933 | ** Write data from a buffer into a file. Return SQLITE_OK on success |
| @@ -32925,18 +32946,20 @@ | ||
| 32925 | 32946 | assert( amt>0 ); |
| 32926 | 32947 | assert( pFile ); |
| 32927 | 32948 | SimulateIOError(return SQLITE_IOERR_WRITE); |
| 32928 | 32949 | SimulateDiskfullError(return SQLITE_FULL); |
| 32929 | 32950 | |
| 32930 | - OSTRACE(("WRITE %d lock=%d\n", pFile->h, pFile->locktype)); | |
| 32951 | + OSTRACE(("WRITE file=%p, buffer=%p, amount=%d, offset=%lld, lock=%d\n", | |
| 32952 | + pFile->h, pBuf, amt, offset, pFile->locktype)); | |
| 32931 | 32953 | |
| 32932 | 32954 | #if SQLITE_MAX_MMAP_SIZE>0 |
| 32933 | 32955 | /* Deal with as much of this write request as possible by transfering |
| 32934 | 32956 | ** data from the memory mapping using memcpy(). */ |
| 32935 | 32957 | if( offset<pFile->mmapSize ){ |
| 32936 | 32958 | if( offset+amt <= pFile->mmapSize ){ |
| 32937 | 32959 | memcpy(&((u8 *)(pFile->pMapRegion))[offset], pBuf, amt); |
| 32960 | + OSTRACE(("WRITE-MMAP file=%p, rc=SQLITE_OK\n", pFile->h)); | |
| 32938 | 32961 | return SQLITE_OK; |
| 32939 | 32962 | }else{ |
| 32940 | 32963 | int nCopy = (int)(pFile->mmapSize - offset); |
| 32941 | 32964 | memcpy(&((u8 *)(pFile->pMapRegion))[offset], pBuf, nCopy); |
| 32942 | 32965 | pBuf = &((u8 *)pBuf)[nCopy]; |
| @@ -32995,17 +33018,20 @@ | ||
| 32995 | 33018 | } |
| 32996 | 33019 | |
| 32997 | 33020 | if( rc ){ |
| 32998 | 33021 | if( ( pFile->lastErrno==ERROR_HANDLE_DISK_FULL ) |
| 32999 | 33022 | || ( pFile->lastErrno==ERROR_DISK_FULL )){ |
| 33023 | + OSTRACE(("WRITE file=%p, rc=SQLITE_FULL\n", pFile->h)); | |
| 33000 | 33024 | return SQLITE_FULL; |
| 33001 | 33025 | } |
| 33026 | + OSTRACE(("WRITE file=%p, rc=SQLITE_IOERR_WRITE\n", pFile->h)); | |
| 33002 | 33027 | return winLogError(SQLITE_IOERR_WRITE, pFile->lastErrno, |
| 33003 | 33028 | "winWrite", pFile->zPath); |
| 33004 | 33029 | }else{ |
| 33005 | 33030 | logIoerr(nRetry); |
| 33006 | 33031 | } |
| 33032 | + OSTRACE(("WRITE file=%p, rc=SQLITE_OK\n", pFile->h)); | |
| 33007 | 33033 | return SQLITE_OK; |
| 33008 | 33034 | } |
| 33009 | 33035 | |
| 33010 | 33036 | /* |
| 33011 | 33037 | ** Truncate an open file to a specified size |
| @@ -33014,13 +33040,13 @@ | ||
| 33014 | 33040 | winFile *pFile = (winFile*)id; /* File handle object */ |
| 33015 | 33041 | int rc = SQLITE_OK; /* Return code for this function */ |
| 33016 | 33042 | DWORD lastErrno; |
| 33017 | 33043 | |
| 33018 | 33044 | assert( pFile ); |
| 33019 | - | |
| 33020 | - OSTRACE(("TRUNCATE %d %lld\n", pFile->h, nByte)); | |
| 33021 | 33045 | SimulateIOError(return SQLITE_IOERR_TRUNCATE); |
| 33046 | + OSTRACE(("TRUNCATE file=%p, size=%lld, lock=%d\n", | |
| 33047 | + pFile->h, nByte, pFile->locktype)); | |
| 33022 | 33048 | |
| 33023 | 33049 | /* If the user has configured a chunk-size for this file, truncate the |
| 33024 | 33050 | ** file so that it consists of an integer number of chunks (i.e. the |
| 33025 | 33051 | ** actual file size after the operation may be larger than the requested |
| 33026 | 33052 | ** size). |
| @@ -33048,11 +33074,11 @@ | ||
| 33048 | 33074 | if( pFile->pMapRegion && nByte<pFile->mmapSize ){ |
| 33049 | 33075 | pFile->mmapSize = nByte; |
| 33050 | 33076 | } |
| 33051 | 33077 | #endif |
| 33052 | 33078 | |
| 33053 | - OSTRACE(("TRUNCATE %d %lld %s\n", pFile->h, nByte, rc ? "failed" : "ok")); | |
| 33079 | + OSTRACE(("TRUNCATE file=%p, rc=%s\n", pFile->h, sqlite3ErrName(rc))); | |
| 33054 | 33080 | return rc; |
| 33055 | 33081 | } |
| 33056 | 33082 | |
| 33057 | 33083 | #ifdef SQLITE_TEST |
| 33058 | 33084 | /* |
| @@ -33088,16 +33114,17 @@ | ||
| 33088 | 33114 | /* Check that one of SQLITE_SYNC_NORMAL or FULL was passed */ |
| 33089 | 33115 | assert((flags&0x0F)==SQLITE_SYNC_NORMAL |
| 33090 | 33116 | || (flags&0x0F)==SQLITE_SYNC_FULL |
| 33091 | 33117 | ); |
| 33092 | 33118 | |
| 33093 | - OSTRACE(("SYNC %d lock=%d\n", pFile->h, pFile->locktype)); | |
| 33094 | - | |
| 33095 | 33119 | /* Unix cannot, but some systems may return SQLITE_FULL from here. This |
| 33096 | 33120 | ** line is to test that doing so does not cause any problems. |
| 33097 | 33121 | */ |
| 33098 | 33122 | SimulateDiskfullError( return SQLITE_FULL ); |
| 33123 | + | |
| 33124 | + OSTRACE(("SYNC file=%p, flags=%x, lock=%d\n", | |
| 33125 | + pFile->h, flags, pFile->locktype)); | |
| 33099 | 33126 | |
| 33100 | 33127 | #ifndef SQLITE_TEST |
| 33101 | 33128 | UNUSED_PARAMETER(flags); |
| 33102 | 33129 | #else |
| 33103 | 33130 | if( (flags&0x0F)==SQLITE_SYNC_FULL ){ |
| @@ -33113,13 +33140,15 @@ | ||
| 33113 | 33140 | return SQLITE_OK; |
| 33114 | 33141 | #else |
| 33115 | 33142 | rc = osFlushFileBuffers(pFile->h); |
| 33116 | 33143 | SimulateIOError( rc=FALSE ); |
| 33117 | 33144 | if( rc ){ |
| 33145 | + OSTRACE(("SYNC file=%p, rc=SQLITE_OK\n", pFile->h)); | |
| 33118 | 33146 | return SQLITE_OK; |
| 33119 | 33147 | }else{ |
| 33120 | 33148 | pFile->lastErrno = osGetLastError(); |
| 33149 | + OSTRACE(("SYNC file=%p, rc=SQLITE_IOERR_FSYNC\n", pFile->h)); | |
| 33121 | 33150 | return winLogError(SQLITE_IOERR_FSYNC, pFile->lastErrno, |
| 33122 | 33151 | "winSync", pFile->zPath); |
| 33123 | 33152 | } |
| 33124 | 33153 | #endif |
| 33125 | 33154 | } |
| @@ -33130,11 +33159,14 @@ | ||
| 33130 | 33159 | static int winFileSize(sqlite3_file *id, sqlite3_int64 *pSize){ |
| 33131 | 33160 | winFile *pFile = (winFile*)id; |
| 33132 | 33161 | int rc = SQLITE_OK; |
| 33133 | 33162 | |
| 33134 | 33163 | assert( id!=0 ); |
| 33164 | + assert( pSize!=0 ); | |
| 33135 | 33165 | SimulateIOError(return SQLITE_IOERR_FSTAT); |
| 33166 | + OSTRACE(("SIZE file=%p, pSize=%p\n", pFile->h, pSize)); | |
| 33167 | + | |
| 33136 | 33168 | #if SQLITE_OS_WINRT |
| 33137 | 33169 | { |
| 33138 | 33170 | FILE_STANDARD_INFO info; |
| 33139 | 33171 | if( osGetFileInformationByHandleEx(pFile->h, FileStandardInfo, |
| 33140 | 33172 | &info, sizeof(info)) ){ |
| @@ -33159,10 +33191,12 @@ | ||
| 33159 | 33191 | rc = winLogError(SQLITE_IOERR_FSTAT, pFile->lastErrno, |
| 33160 | 33192 | "winFileSize", pFile->zPath); |
| 33161 | 33193 | } |
| 33162 | 33194 | } |
| 33163 | 33195 | #endif |
| 33196 | + OSTRACE(("SIZE file=%p, pSize=%p, *pSize=%lld, rc=%s\n", | |
| 33197 | + pFile->h, pSize, *pSize, sqlite3ErrName(rc))); | |
| 33164 | 33198 | return rc; |
| 33165 | 33199 | } |
| 33166 | 33200 | |
| 33167 | 33201 | /* |
| 33168 | 33202 | ** LOCKFILE_FAIL_IMMEDIATELY is undefined on some Windows systems. |
| @@ -33200,10 +33234,11 @@ | ||
| 33200 | 33234 | ** Different API routines are called depending on whether or not this |
| 33201 | 33235 | ** is Win9x or WinNT. |
| 33202 | 33236 | */ |
| 33203 | 33237 | static int getReadLock(winFile *pFile){ |
| 33204 | 33238 | int res; |
| 33239 | + OSTRACE(("READ-LOCK file=%p, lock=%d\n", pFile->h, pFile->locktype)); | |
| 33205 | 33240 | if( isNT() ){ |
| 33206 | 33241 | #if SQLITE_OS_WINCE |
| 33207 | 33242 | /* |
| 33208 | 33243 | ** NOTE: Windows CE is handled differently here due its lack of the Win32 |
| 33209 | 33244 | ** API LockFileEx. |
| @@ -33225,19 +33260,21 @@ | ||
| 33225 | 33260 | #endif |
| 33226 | 33261 | if( res == 0 ){ |
| 33227 | 33262 | pFile->lastErrno = osGetLastError(); |
| 33228 | 33263 | /* No need to log a failure to lock */ |
| 33229 | 33264 | } |
| 33265 | + OSTRACE(("READ-LOCK file=%p, rc=%s\n", pFile->h, sqlite3ErrName(res))); | |
| 33230 | 33266 | return res; |
| 33231 | 33267 | } |
| 33232 | 33268 | |
| 33233 | 33269 | /* |
| 33234 | 33270 | ** Undo a readlock |
| 33235 | 33271 | */ |
| 33236 | 33272 | static int unlockReadLock(winFile *pFile){ |
| 33237 | 33273 | int res; |
| 33238 | 33274 | DWORD lastErrno; |
| 33275 | + OSTRACE(("READ-UNLOCK file=%p, lock=%d\n", pFile->h, pFile->locktype)); | |
| 33239 | 33276 | if( isNT() ){ |
| 33240 | 33277 | res = winUnlockFile(&pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0); |
| 33241 | 33278 | } |
| 33242 | 33279 | #ifdef SQLITE_WIN32_HAS_ANSI |
| 33243 | 33280 | else{ |
| @@ -33247,10 +33284,11 @@ | ||
| 33247 | 33284 | if( res==0 && ((lastErrno = osGetLastError())!=ERROR_NOT_LOCKED) ){ |
| 33248 | 33285 | pFile->lastErrno = lastErrno; |
| 33249 | 33286 | winLogError(SQLITE_IOERR_UNLOCK, pFile->lastErrno, |
| 33250 | 33287 | "unlockReadLock", pFile->zPath); |
| 33251 | 33288 | } |
| 33289 | + OSTRACE(("READ-UNLOCK file=%p, rc=%s\n", pFile->h, sqlite3ErrName(res))); | |
| 33252 | 33290 | return res; |
| 33253 | 33291 | } |
| 33254 | 33292 | |
| 33255 | 33293 | /* |
| 33256 | 33294 | ** Lock the file with the lock specified by parameter locktype - one |
| @@ -33285,18 +33323,19 @@ | ||
| 33285 | 33323 | int gotPendingLock = 0;/* True if we acquired a PENDING lock this time */ |
| 33286 | 33324 | winFile *pFile = (winFile*)id; |
| 33287 | 33325 | DWORD lastErrno = NO_ERROR; |
| 33288 | 33326 | |
| 33289 | 33327 | assert( id!=0 ); |
| 33290 | - OSTRACE(("LOCK %d %d was %d(%d)\n", | |
| 33291 | - pFile->h, locktype, pFile->locktype, pFile->sharedLockByte)); | |
| 33328 | + OSTRACE(("LOCK file=%p, oldLock=%d(%d), newLock=%d\n", | |
| 33329 | + pFile->h, pFile->locktype, pFile->sharedLockByte, locktype)); | |
| 33292 | 33330 | |
| 33293 | 33331 | /* If there is already a lock of this type or more restrictive on the |
| 33294 | 33332 | ** OsFile, do nothing. Don't use the end_lock: exit path, as |
| 33295 | 33333 | ** sqlite3OsEnterMutex() hasn't been called yet. |
| 33296 | 33334 | */ |
| 33297 | 33335 | if( pFile->locktype>=locktype ){ |
| 33336 | + OSTRACE(("LOCK-HELD file=%p, rc=SQLITE_OK\n", pFile->h)); | |
| 33298 | 33337 | return SQLITE_OK; |
| 33299 | 33338 | } |
| 33300 | 33339 | |
| 33301 | 33340 | /* Make sure the locking sequence is correct |
| 33302 | 33341 | */ |
| @@ -33320,11 +33359,12 @@ | ||
| 33320 | 33359 | ** around problems caused by indexing and/or anti-virus software on |
| 33321 | 33360 | ** Windows systems. |
| 33322 | 33361 | ** If you are using this code as a model for alternative VFSes, do not |
| 33323 | 33362 | ** copy this retry logic. It is a hack intended for Windows only. |
| 33324 | 33363 | */ |
| 33325 | - OSTRACE(("could not get a PENDING lock. cnt=%d\n", cnt)); | |
| 33364 | + OSTRACE(("LOCK-PENDING-FAIL file=%p, count=%d, rc=%s\n", | |
| 33365 | + pFile->h, cnt, sqlite3ErrName(res))); | |
| 33326 | 33366 | if( cnt ) sqlite3_win32_sleep(1); |
| 33327 | 33367 | } |
| 33328 | 33368 | gotPendingLock = res; |
| 33329 | 33369 | if( !res ){ |
| 33330 | 33370 | lastErrno = osGetLastError(); |
| @@ -33365,18 +33405,16 @@ | ||
| 33365 | 33405 | /* Acquire an EXCLUSIVE lock |
| 33366 | 33406 | */ |
| 33367 | 33407 | if( locktype==EXCLUSIVE_LOCK && res ){ |
| 33368 | 33408 | assert( pFile->locktype>=SHARED_LOCK ); |
| 33369 | 33409 | res = unlockReadLock(pFile); |
| 33370 | - OSTRACE(("unreadlock = %d\n", res)); | |
| 33371 | 33410 | res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS, SHARED_FIRST, 0, |
| 33372 | 33411 | SHARED_SIZE, 0); |
| 33373 | 33412 | if( res ){ |
| 33374 | 33413 | newLocktype = EXCLUSIVE_LOCK; |
| 33375 | 33414 | }else{ |
| 33376 | 33415 | lastErrno = osGetLastError(); |
| 33377 | - OSTRACE(("error-code = %d\n", lastErrno)); | |
| 33378 | 33416 | getReadLock(pFile); |
| 33379 | 33417 | } |
| 33380 | 33418 | } |
| 33381 | 33419 | |
| 33382 | 33420 | /* If we are holding a PENDING lock that ought to be released, then |
| @@ -33390,16 +33428,18 @@ | ||
| 33390 | 33428 | ** return the appropriate result code. |
| 33391 | 33429 | */ |
| 33392 | 33430 | if( res ){ |
| 33393 | 33431 | rc = SQLITE_OK; |
| 33394 | 33432 | }else{ |
| 33395 | - OSTRACE(("LOCK FAILED %d trying for %d but got %d\n", pFile->h, | |
| 33396 | - locktype, newLocktype)); | |
| 33433 | + OSTRACE(("LOCK-FAIL file=%p, wanted=%d, got=%d\n", | |
| 33434 | + pFile->h, locktype, newLocktype)); | |
| 33397 | 33435 | pFile->lastErrno = lastErrno; |
| 33398 | 33436 | rc = SQLITE_BUSY; |
| 33399 | 33437 | } |
| 33400 | 33438 | pFile->locktype = (u8)newLocktype; |
| 33439 | + OSTRACE(("LOCK file=%p, lock=%d, rc=%s\n", | |
| 33440 | + pFile->h, pFile->locktype, sqlite3ErrName(rc))); | |
| 33401 | 33441 | return rc; |
| 33402 | 33442 | } |
| 33403 | 33443 | |
| 33404 | 33444 | /* |
| 33405 | 33445 | ** This routine checks if there is a RESERVED lock held on the specified |
| @@ -33409,24 +33449,27 @@ | ||
| 33409 | 33449 | static int winCheckReservedLock(sqlite3_file *id, int *pResOut){ |
| 33410 | 33450 | int rc; |
| 33411 | 33451 | winFile *pFile = (winFile*)id; |
| 33412 | 33452 | |
| 33413 | 33453 | SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; ); |
| 33454 | + OSTRACE(("TEST-WR-LOCK file=%p, pResOut=%p\n", pFile->h, pResOut)); | |
| 33414 | 33455 | |
| 33415 | 33456 | assert( id!=0 ); |
| 33416 | 33457 | if( pFile->locktype>=RESERVED_LOCK ){ |
| 33417 | 33458 | rc = 1; |
| 33418 | - OSTRACE(("TEST WR-LOCK %d %d (local)\n", pFile->h, rc)); | |
| 33459 | + OSTRACE(("TEST-WR-LOCK file=%p, rc=%d (local)\n", pFile->h, rc)); | |
| 33419 | 33460 | }else{ |
| 33420 | 33461 | rc = winLockFile(&pFile->h, SQLITE_LOCKFILEEX_FLAGS,RESERVED_BYTE, 0, 1, 0); |
| 33421 | 33462 | if( rc ){ |
| 33422 | 33463 | winUnlockFile(&pFile->h, RESERVED_BYTE, 0, 1, 0); |
| 33423 | 33464 | } |
| 33424 | 33465 | rc = !rc; |
| 33425 | - OSTRACE(("TEST WR-LOCK %d %d (remote)\n", pFile->h, rc)); | |
| 33466 | + OSTRACE(("TEST-WR-LOCK file=%p, rc=%d (remote)\n", pFile->h, rc)); | |
| 33426 | 33467 | } |
| 33427 | 33468 | *pResOut = rc; |
| 33469 | + OSTRACE(("TEST-WR-LOCK file=%p, pResOut=%p, *pResOut=%d, rc=SQLITE_OK\n", | |
| 33470 | + pFile->h, pResOut, *pResOut)); | |
| 33428 | 33471 | return SQLITE_OK; |
| 33429 | 33472 | } |
| 33430 | 33473 | |
| 33431 | 33474 | /* |
| 33432 | 33475 | ** Lower the locking level on file descriptor id to locktype. locktype |
| @@ -33443,12 +33486,12 @@ | ||
| 33443 | 33486 | int type; |
| 33444 | 33487 | winFile *pFile = (winFile*)id; |
| 33445 | 33488 | int rc = SQLITE_OK; |
| 33446 | 33489 | assert( pFile!=0 ); |
| 33447 | 33490 | assert( locktype<=SHARED_LOCK ); |
| 33448 | - OSTRACE(("UNLOCK %d to %d was %d(%d)\n", pFile->h, locktype, | |
| 33449 | - pFile->locktype, pFile->sharedLockByte)); | |
| 33491 | + OSTRACE(("UNLOCK file=%p, oldLock=%d(%d), newLock=%d\n", | |
| 33492 | + pFile->h, pFile->locktype, pFile->sharedLockByte, locktype)); | |
| 33450 | 33493 | type = pFile->locktype; |
| 33451 | 33494 | if( type>=EXCLUSIVE_LOCK ){ |
| 33452 | 33495 | winUnlockFile(&pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0); |
| 33453 | 33496 | if( locktype==SHARED_LOCK && !getReadLock(pFile) ){ |
| 33454 | 33497 | /* This should never happen. We should always be able to |
| @@ -33465,10 +33508,12 @@ | ||
| 33465 | 33508 | } |
| 33466 | 33509 | if( type>=PENDING_LOCK ){ |
| 33467 | 33510 | winUnlockFile(&pFile->h, PENDING_BYTE, 0, 1, 0); |
| 33468 | 33511 | } |
| 33469 | 33512 | pFile->locktype = (u8)locktype; |
| 33513 | + OSTRACE(("UNLOCK file=%p, lock=%d, rc=%s\n", | |
| 33514 | + pFile->h, pFile->locktype, sqlite3ErrName(rc))); | |
| 33470 | 33515 | return rc; |
| 33471 | 33516 | } |
| 33472 | 33517 | |
| 33473 | 33518 | /* |
| 33474 | 33519 | ** If *pArg is inititially negative then this is a query. Set *pArg to |
| @@ -33492,21 +33537,25 @@ | ||
| 33492 | 33537 | /* |
| 33493 | 33538 | ** Control and query of the open file handle. |
| 33494 | 33539 | */ |
| 33495 | 33540 | static int winFileControl(sqlite3_file *id, int op, void *pArg){ |
| 33496 | 33541 | winFile *pFile = (winFile*)id; |
| 33542 | + OSTRACE(("FCNTL file=%p, op=%d, pArg=%p\n", pFile->h, op, pArg)); | |
| 33497 | 33543 | switch( op ){ |
| 33498 | 33544 | case SQLITE_FCNTL_LOCKSTATE: { |
| 33499 | 33545 | *(int*)pArg = pFile->locktype; |
| 33546 | + OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); | |
| 33500 | 33547 | return SQLITE_OK; |
| 33501 | 33548 | } |
| 33502 | 33549 | case SQLITE_LAST_ERRNO: { |
| 33503 | 33550 | *(int*)pArg = (int)pFile->lastErrno; |
| 33551 | + OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); | |
| 33504 | 33552 | return SQLITE_OK; |
| 33505 | 33553 | } |
| 33506 | 33554 | case SQLITE_FCNTL_CHUNK_SIZE: { |
| 33507 | 33555 | pFile->szChunk = *(int *)pArg; |
| 33556 | + OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); | |
| 33508 | 33557 | return SQLITE_OK; |
| 33509 | 33558 | } |
| 33510 | 33559 | case SQLITE_FCNTL_SIZE_HINT: { |
| 33511 | 33560 | if( pFile->szChunk>0 ){ |
| 33512 | 33561 | sqlite3_int64 oldSz; |
| @@ -33517,24 +33566,29 @@ | ||
| 33517 | 33566 | SimulateIOErrorBenign(1); |
| 33518 | 33567 | rc = winTruncate(id, newSz); |
| 33519 | 33568 | SimulateIOErrorBenign(0); |
| 33520 | 33569 | } |
| 33521 | 33570 | } |
| 33571 | + OSTRACE(("FCNTL file=%p, rc=%s\n", pFile->h, sqlite3ErrName(rc))); | |
| 33522 | 33572 | return rc; |
| 33523 | 33573 | } |
| 33574 | + OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); | |
| 33524 | 33575 | return SQLITE_OK; |
| 33525 | 33576 | } |
| 33526 | 33577 | case SQLITE_FCNTL_PERSIST_WAL: { |
| 33527 | 33578 | winModeBit(pFile, WINFILE_PERSIST_WAL, (int*)pArg); |
| 33579 | + OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); | |
| 33528 | 33580 | return SQLITE_OK; |
| 33529 | 33581 | } |
| 33530 | 33582 | case SQLITE_FCNTL_POWERSAFE_OVERWRITE: { |
| 33531 | 33583 | winModeBit(pFile, WINFILE_PSOW, (int*)pArg); |
| 33584 | + OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); | |
| 33532 | 33585 | return SQLITE_OK; |
| 33533 | 33586 | } |
| 33534 | 33587 | case SQLITE_FCNTL_VFSNAME: { |
| 33535 | 33588 | *(char**)pArg = sqlite3_mprintf("win32"); |
| 33589 | + OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); | |
| 33536 | 33590 | return SQLITE_OK; |
| 33537 | 33591 | } |
| 33538 | 33592 | case SQLITE_FCNTL_WIN32_AV_RETRY: { |
| 33539 | 33593 | int *a = (int*)pArg; |
| 33540 | 33594 | if( a[0]>0 ){ |
| @@ -33545,18 +33599,20 @@ | ||
| 33545 | 33599 | if( a[1]>0 ){ |
| 33546 | 33600 | win32IoerrRetryDelay = a[1]; |
| 33547 | 33601 | }else{ |
| 33548 | 33602 | a[1] = win32IoerrRetryDelay; |
| 33549 | 33603 | } |
| 33604 | + OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); | |
| 33550 | 33605 | return SQLITE_OK; |
| 33551 | 33606 | } |
| 33552 | 33607 | case SQLITE_FCNTL_TEMPFILENAME: { |
| 33553 | 33608 | char *zTFile = sqlite3MallocZero( pFile->pVfs->mxPathname ); |
| 33554 | 33609 | if( zTFile ){ |
| 33555 | 33610 | getTempname(pFile->pVfs->mxPathname, zTFile); |
| 33556 | 33611 | *(char**)pArg = zTFile; |
| 33557 | 33612 | } |
| 33613 | + OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); | |
| 33558 | 33614 | return SQLITE_OK; |
| 33559 | 33615 | } |
| 33560 | 33616 | #if SQLITE_MAX_MMAP_SIZE>0 |
| 33561 | 33617 | case SQLITE_FCNTL_MMAP_SIZE: { |
| 33562 | 33618 | i64 newLimit = *(i64*)pArg; |
| @@ -33563,14 +33619,16 @@ | ||
| 33563 | 33619 | if( newLimit>sqlite3GlobalConfig.mxMmap ){ |
| 33564 | 33620 | newLimit = sqlite3GlobalConfig.mxMmap; |
| 33565 | 33621 | } |
| 33566 | 33622 | *(i64*)pArg = pFile->mmapSizeMax; |
| 33567 | 33623 | if( newLimit>=0 ) pFile->mmapSizeMax = newLimit; |
| 33624 | + OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); | |
| 33568 | 33625 | return SQLITE_OK; |
| 33569 | 33626 | } |
| 33570 | 33627 | #endif |
| 33571 | 33628 | } |
| 33629 | + OSTRACE(("FCNTL file=%p, rc=SQLITE_NOTFOUND\n", pFile->h)); | |
| 33572 | 33630 | return SQLITE_NOTFOUND; |
| 33573 | 33631 | } |
| 33574 | 33632 | |
| 33575 | 33633 | /* |
| 33576 | 33634 | ** Return the sector size in bytes of the underlying block device for |
| @@ -33727,10 +33785,13 @@ | ||
| 33727 | 33785 | int rc = 0; /* Result code form Lock/UnlockFileEx() */ |
| 33728 | 33786 | |
| 33729 | 33787 | /* Access to the winShmNode object is serialized by the caller */ |
| 33730 | 33788 | assert( sqlite3_mutex_held(pFile->mutex) || pFile->nRef==0 ); |
| 33731 | 33789 | |
| 33790 | + OSTRACE(("SHM-LOCK file=%p, lock=%d, offset=%d, size=%d\n", | |
| 33791 | + pFile->hFile.h, lockType, ofst, nByte)); | |
| 33792 | + | |
| 33732 | 33793 | /* Release/Acquire the system-level lock */ |
| 33733 | 33794 | if( lockType==_SHM_UNLCK ){ |
| 33734 | 33795 | rc = winUnlockFile(&pFile->hFile.h, ofst, 0, nByte, 0); |
| 33735 | 33796 | }else{ |
| 33736 | 33797 | /* Initialize the locking parameters */ |
| @@ -33744,15 +33805,13 @@ | ||
| 33744 | 33805 | }else{ |
| 33745 | 33806 | pFile->lastErrno = osGetLastError(); |
| 33746 | 33807 | rc = SQLITE_BUSY; |
| 33747 | 33808 | } |
| 33748 | 33809 | |
| 33749 | - OSTRACE(("SHM-LOCK %d %s %s 0x%08lx\n", | |
| 33750 | - pFile->hFile.h, | |
| 33751 | - rc==SQLITE_OK ? "ok" : "failed", | |
| 33752 | - lockType==_SHM_UNLCK ? "UnlockFileEx" : "LockFileEx", | |
| 33753 | - pFile->lastErrno)); | |
| 33810 | + OSTRACE(("SHM-LOCK file=%p, func=%s, errno=%lu, rc=%s\n", | |
| 33811 | + pFile->hFile.h, (lockType == _SHM_UNLCK) ? "winUnlockFile" : | |
| 33812 | + "winLockFile", pFile->lastErrno, sqlite3ErrName(rc))); | |
| 33754 | 33813 | |
| 33755 | 33814 | return rc; |
| 33756 | 33815 | } |
| 33757 | 33816 | |
| 33758 | 33817 | /* Forward references to VFS methods */ |
| @@ -33768,24 +33827,24 @@ | ||
| 33768 | 33827 | static void winShmPurge(sqlite3_vfs *pVfs, int deleteFlag){ |
| 33769 | 33828 | winShmNode **pp; |
| 33770 | 33829 | winShmNode *p; |
| 33771 | 33830 | BOOL bRc; |
| 33772 | 33831 | assert( winShmMutexHeld() ); |
| 33832 | + OSTRACE(("SHM-PURGE pid=%lu, deleteFlag=%d\n", | |
| 33833 | + osGetCurrentProcessId(), deleteFlag)); | |
| 33773 | 33834 | pp = &winShmNodeList; |
| 33774 | 33835 | while( (p = *pp)!=0 ){ |
| 33775 | 33836 | if( p->nRef==0 ){ |
| 33776 | 33837 | int i; |
| 33777 | 33838 | if( p->mutex ) sqlite3_mutex_free(p->mutex); |
| 33778 | 33839 | for(i=0; i<p->nRegion; i++){ |
| 33779 | 33840 | bRc = osUnmapViewOfFile(p->aRegion[i].pMap); |
| 33780 | - OSTRACE(("SHM-PURGE pid-%d unmap region=%d %s\n", | |
| 33781 | - (int)osGetCurrentProcessId(), i, | |
| 33782 | - bRc ? "ok" : "failed")); | |
| 33841 | + OSTRACE(("SHM-PURGE-UNMAP pid=%lu, region=%d, rc=%s\n", | |
| 33842 | + osGetCurrentProcessId(), i, bRc ? "ok" : "failed")); | |
| 33783 | 33843 | bRc = osCloseHandle(p->aRegion[i].hMap); |
| 33784 | - OSTRACE(("SHM-PURGE pid-%d close region=%d %s\n", | |
| 33785 | - (int)osGetCurrentProcessId(), i, | |
| 33786 | - bRc ? "ok" : "failed")); | |
| 33844 | + OSTRACE(("SHM-PURGE-CLOSE pid=%lu, region=%d, rc=%s\n", | |
| 33845 | + osGetCurrentProcessId(), i, bRc ? "ok" : "failed")); | |
| 33787 | 33846 | } |
| 33788 | 33847 | if( p->hFile.h!=NULL && p->hFile.h!=INVALID_HANDLE_VALUE ){ |
| 33789 | 33848 | SimulateIOErrorBenign(1); |
| 33790 | 33849 | winClose((sqlite3_file *)&p->hFile); |
| 33791 | 33850 | SimulateIOErrorBenign(0); |
| @@ -34060,13 +34119,13 @@ | ||
| 34060 | 34119 | p->exclMask |= mask; |
| 34061 | 34120 | } |
| 34062 | 34121 | } |
| 34063 | 34122 | } |
| 34064 | 34123 | sqlite3_mutex_leave(pShmNode->mutex); |
| 34065 | - OSTRACE(("SHM-LOCK shmid-%d, pid-%d got %03x,%03x %s\n", | |
| 34066 | - p->id, (int)osGetCurrentProcessId(), p->sharedMask, p->exclMask, | |
| 34067 | - rc ? "failed" : "ok")); | |
| 34124 | + OSTRACE(("SHM-LOCK pid=%lu, id=%d, sharedMask=%03x, exclMask=%03x, rc=%s\n", | |
| 34125 | + osGetCurrentProcessId(), p->id, p->sharedMask, p->exclMask, | |
| 34126 | + sqlite3ErrName(rc))); | |
| 34068 | 34127 | return rc; |
| 34069 | 34128 | } |
| 34070 | 34129 | |
| 34071 | 34130 | /* |
| 34072 | 34131 | ** Implement a memory barrier or memory fence on shared memory. |
| @@ -34183,12 +34242,12 @@ | ||
| 34183 | 34242 | #elif defined(SQLITE_WIN32_HAS_ANSI) |
| 34184 | 34243 | hMap = osCreateFileMappingA(pShmNode->hFile.h, |
| 34185 | 34244 | NULL, PAGE_READWRITE, 0, nByte, NULL |
| 34186 | 34245 | ); |
| 34187 | 34246 | #endif |
| 34188 | - OSTRACE(("SHM-MAP pid-%d create region=%d nbyte=%d %s\n", | |
| 34189 | - (int)osGetCurrentProcessId(), pShmNode->nRegion, nByte, | |
| 34247 | + OSTRACE(("SHM-MAP-CREATE pid=%lu, region=%d, size=%d, rc=%s\n", | |
| 34248 | + osGetCurrentProcessId(), pShmNode->nRegion, nByte, | |
| 34190 | 34249 | hMap ? "ok" : "failed")); |
| 34191 | 34250 | if( hMap ){ |
| 34192 | 34251 | int iOffset = pShmNode->nRegion*szRegion; |
| 34193 | 34252 | int iOffsetShift = iOffset % winSysInfo.dwAllocationGranularity; |
| 34194 | 34253 | #if SQLITE_OS_WINRT |
| @@ -34198,12 +34257,12 @@ | ||
| 34198 | 34257 | #else |
| 34199 | 34258 | pMap = osMapViewOfFile(hMap, FILE_MAP_WRITE | FILE_MAP_READ, |
| 34200 | 34259 | 0, iOffset - iOffsetShift, szRegion + iOffsetShift |
| 34201 | 34260 | ); |
| 34202 | 34261 | #endif |
| 34203 | - OSTRACE(("SHM-MAP pid-%d map region=%d offset=%d size=%d %s\n", | |
| 34204 | - (int)osGetCurrentProcessId(), pShmNode->nRegion, iOffset, | |
| 34262 | + OSTRACE(("SHM-MAP-MAP pid=%lu, region=%d, offset=%d, size=%d, rc=%s\n", | |
| 34263 | + osGetCurrentProcessId(), pShmNode->nRegion, iOffset, | |
| 34205 | 34264 | szRegion, pMap ? "ok" : "failed")); |
| 34206 | 34265 | } |
| 34207 | 34266 | if( !pMap ){ |
| 34208 | 34267 | pShmNode->lastErrno = osGetLastError(); |
| 34209 | 34268 | rc = winLogError(SQLITE_IOERR_SHMMAP, pShmNode->lastErrno, |
| @@ -34242,13 +34301,20 @@ | ||
| 34242 | 34301 | ** Cleans up the mapped region of the specified file, if any. |
| 34243 | 34302 | */ |
| 34244 | 34303 | #if SQLITE_MAX_MMAP_SIZE>0 |
| 34245 | 34304 | static int winUnmapfile(winFile *pFile){ |
| 34246 | 34305 | assert( pFile!=0 ); |
| 34306 | + OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, hMap=%p, pMapRegion=%p, " | |
| 34307 | + "mmapSize=%lld, mmapSizeActual=%lld, mmapSizeMax=%lld\n", | |
| 34308 | + osGetCurrentProcessId(), pFile, pFile->hMap, pFile->pMapRegion, | |
| 34309 | + pFile->mmapSize, pFile->mmapSizeActual, pFile->mmapSizeMax)); | |
| 34247 | 34310 | if( pFile->pMapRegion ){ |
| 34248 | 34311 | if( !osUnmapViewOfFile(pFile->pMapRegion) ){ |
| 34249 | 34312 | pFile->lastErrno = osGetLastError(); |
| 34313 | + OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, pMapRegion=%p, " | |
| 34314 | + "rc=SQLITE_IOERR_MMAP\n", osGetCurrentProcessId(), pFile, | |
| 34315 | + pFile->pMapRegion)); | |
| 34250 | 34316 | return winLogError(SQLITE_IOERR_MMAP, pFile->lastErrno, |
| 34251 | 34317 | "winUnmap1", pFile->zPath); |
| 34252 | 34318 | } |
| 34253 | 34319 | pFile->pMapRegion = 0; |
| 34254 | 34320 | pFile->mmapSize = 0; |
| @@ -34255,15 +34321,19 @@ | ||
| 34255 | 34321 | pFile->mmapSizeActual = 0; |
| 34256 | 34322 | } |
| 34257 | 34323 | if( pFile->hMap!=NULL ){ |
| 34258 | 34324 | if( !osCloseHandle(pFile->hMap) ){ |
| 34259 | 34325 | pFile->lastErrno = osGetLastError(); |
| 34326 | + OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, hMap=%p, rc=SQLITE_IOERR_MMAP\n", | |
| 34327 | + osGetCurrentProcessId(), pFile, pFile->hMap)); | |
| 34260 | 34328 | return winLogError(SQLITE_IOERR_MMAP, pFile->lastErrno, |
| 34261 | 34329 | "winUnmap2", pFile->zPath); |
| 34262 | 34330 | } |
| 34263 | 34331 | pFile->hMap = NULL; |
| 34264 | 34332 | } |
| 34333 | + OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, rc=SQLITE_OK\n", | |
| 34334 | + osGetCurrentProcessId(), pFile)); | |
| 34265 | 34335 | return SQLITE_OK; |
| 34266 | 34336 | } |
| 34267 | 34337 | |
| 34268 | 34338 | /* |
| 34269 | 34339 | ** Memory map or remap the file opened by file-descriptor pFd (if the file |
| @@ -34284,15 +34354,20 @@ | ||
| 34284 | 34354 | static int winMapfile(winFile *pFd, sqlite3_int64 nByte){ |
| 34285 | 34355 | sqlite3_int64 nMap = nByte; |
| 34286 | 34356 | int rc; |
| 34287 | 34357 | |
| 34288 | 34358 | assert( nMap>=0 || pFd->nFetchOut==0 ); |
| 34359 | + OSTRACE(("MAP-FILE pid=%lu, pFile=%p, size=%lld\n", | |
| 34360 | + osGetCurrentProcessId(), pFd, nByte)); | |
| 34361 | + | |
| 34289 | 34362 | if( pFd->nFetchOut>0 ) return SQLITE_OK; |
| 34290 | 34363 | |
| 34291 | 34364 | if( nMap<0 ){ |
| 34292 | 34365 | rc = winFileSize((sqlite3_file*)pFd, &nMap); |
| 34293 | 34366 | if( rc ){ |
| 34367 | + OSTRACE(("MAP-FILE pid=%lu, pFile=%p, rc=SQLITE_IOERR_FSTAT\n", | |
| 34368 | + osGetCurrentProcessId(), pFd)); | |
| 34294 | 34369 | return SQLITE_IOERR_FSTAT; |
| 34295 | 34370 | } |
| 34296 | 34371 | } |
| 34297 | 34372 | if( nMap>pFd->mmapSizeMax ){ |
| 34298 | 34373 | nMap = pFd->mmapSizeMax; |
| @@ -34326,10 +34401,12 @@ | ||
| 34326 | 34401 | if( pFd->hMap==NULL ){ |
| 34327 | 34402 | pFd->lastErrno = osGetLastError(); |
| 34328 | 34403 | rc = winLogError(SQLITE_IOERR_MMAP, pFd->lastErrno, |
| 34329 | 34404 | "winMapfile", pFd->zPath); |
| 34330 | 34405 | /* Log the error, but continue normal operation using xRead/xWrite */ |
| 34406 | + OSTRACE(("MAP-FILE-CREATE pid=%lu, pFile=%p, rc=SQLITE_IOERR_MMAP\n", | |
| 34407 | + osGetCurrentProcessId(), pFd)); | |
| 34331 | 34408 | return SQLITE_OK; |
| 34332 | 34409 | } |
| 34333 | 34410 | assert( (nMap % winSysInfo.dwPageSize)==0 ); |
| 34334 | 34411 | #if SQLITE_OS_WINRT |
| 34335 | 34412 | pNew = osMapViewOfFileFromApp(pFd->hMap, flags, 0, nMap); |
| @@ -34341,17 +34418,21 @@ | ||
| 34341 | 34418 | osCloseHandle(pFd->hMap); |
| 34342 | 34419 | pFd->hMap = NULL; |
| 34343 | 34420 | pFd->lastErrno = osGetLastError(); |
| 34344 | 34421 | winLogError(SQLITE_IOERR_MMAP, pFd->lastErrno, |
| 34345 | 34422 | "winMapfile", pFd->zPath); |
| 34423 | + OSTRACE(("MAP-FILE-MAP pid=%lu, pFile=%p, rc=SQLITE_IOERR_MMAP\n", | |
| 34424 | + osGetCurrentProcessId(), pFd)); | |
| 34346 | 34425 | return SQLITE_OK; |
| 34347 | 34426 | } |
| 34348 | 34427 | pFd->pMapRegion = pNew; |
| 34349 | 34428 | pFd->mmapSize = nMap; |
| 34350 | 34429 | pFd->mmapSizeActual = nMap; |
| 34351 | 34430 | } |
| 34352 | 34431 | |
| 34432 | + OSTRACE(("MAP-FILE pid=%lu, pFile=%p, rc=SQLITE_OK\n", | |
| 34433 | + osGetCurrentProcessId(), pFd)); | |
| 34353 | 34434 | return SQLITE_OK; |
| 34354 | 34435 | } |
| 34355 | 34436 | #endif /* SQLITE_MAX_MMAP_SIZE>0 */ |
| 34356 | 34437 | |
| 34357 | 34438 | /* |
| @@ -34362,38 +34443,48 @@ | ||
| 34362 | 34443 | ** Or, if one cannot but no error occurs, set *pp to 0 and return SQLITE_OK. |
| 34363 | 34444 | ** Finally, if an error does occur, return an SQLite error code. The final |
| 34364 | 34445 | ** value of *pp is undefined in this case. |
| 34365 | 34446 | ** |
| 34366 | 34447 | ** If this function does return a pointer, the caller must eventually |
| 34367 | -** release the reference by calling unixUnfetch(). | |
| 34448 | +** release the reference by calling winUnfetch(). | |
| 34368 | 34449 | */ |
| 34369 | 34450 | static int winFetch(sqlite3_file *fd, i64 iOff, int nAmt, void **pp){ |
| 34370 | 34451 | #if SQLITE_MAX_MMAP_SIZE>0 |
| 34371 | 34452 | winFile *pFd = (winFile*)fd; /* The underlying database file */ |
| 34372 | 34453 | #endif |
| 34373 | 34454 | *pp = 0; |
| 34374 | 34455 | |
| 34456 | + OSTRACE(("FETCH pid=%lu, pFile=%p, offset=%lld, amount=%d, pp=%p\n", | |
| 34457 | + osGetCurrentProcessId(), fd, iOff, nAmt, pp)); | |
| 34458 | + | |
| 34375 | 34459 | #if SQLITE_MAX_MMAP_SIZE>0 |
| 34376 | 34460 | if( pFd->mmapSizeMax>0 ){ |
| 34377 | 34461 | if( pFd->pMapRegion==0 ){ |
| 34378 | 34462 | int rc = winMapfile(pFd, -1); |
| 34379 | - if( rc!=SQLITE_OK ) return rc; | |
| 34463 | + if( rc!=SQLITE_OK ){ | |
| 34464 | + OSTRACE(("FETCH pid=%lu, pFile=%p, rc=%s\n", | |
| 34465 | + osGetCurrentProcessId(), pFd, sqlite3ErrName(rc))); | |
| 34466 | + return rc; | |
| 34467 | + } | |
| 34380 | 34468 | } |
| 34381 | 34469 | if( pFd->mmapSize >= iOff+nAmt ){ |
| 34382 | 34470 | *pp = &((u8 *)pFd->pMapRegion)[iOff]; |
| 34383 | 34471 | pFd->nFetchOut++; |
| 34384 | 34472 | } |
| 34385 | 34473 | } |
| 34386 | 34474 | #endif |
| 34475 | + | |
| 34476 | + OSTRACE(("FETCH pid=%lu, pFile=%p, pp=%p, *pp=%p, rc=SQLITE_OK\n", | |
| 34477 | + osGetCurrentProcessId(), fd, pp, *pp)); | |
| 34387 | 34478 | return SQLITE_OK; |
| 34388 | 34479 | } |
| 34389 | 34480 | |
| 34390 | 34481 | /* |
| 34391 | 34482 | ** If the third argument is non-NULL, then this function releases a |
| 34392 | -** reference obtained by an earlier call to unixFetch(). The second | |
| 34483 | +** reference obtained by an earlier call to winFetch(). The second | |
| 34393 | 34484 | ** argument passed to this function must be the same as the corresponding |
| 34394 | -** argument that was passed to the unixFetch() invocation. | |
| 34485 | +** argument that was passed to the winFetch() invocation. | |
| 34395 | 34486 | ** |
| 34396 | 34487 | ** Or, if the third argument is NULL, then this function is being called |
| 34397 | 34488 | ** to inform the VFS layer that, according to POSIX, any existing mapping |
| 34398 | 34489 | ** may now be invalid and should be unmapped. |
| 34399 | 34490 | */ |
| @@ -34407,10 +34498,13 @@ | ||
| 34407 | 34498 | assert( (p==0)==(pFd->nFetchOut==0) ); |
| 34408 | 34499 | |
| 34409 | 34500 | /* If p!=0, it must match the iOff value. */ |
| 34410 | 34501 | assert( p==0 || p==&((u8 *)pFd->pMapRegion)[iOff] ); |
| 34411 | 34502 | |
| 34503 | + OSTRACE(("UNFETCH pid=%lu, pFile=%p, offset=%lld, p=%p\n", | |
| 34504 | + osGetCurrentProcessId(), pFd, iOff, p)); | |
| 34505 | + | |
| 34412 | 34506 | if( p ){ |
| 34413 | 34507 | pFd->nFetchOut--; |
| 34414 | 34508 | }else{ |
| 34415 | 34509 | /* FIXME: If Windows truly always prevents truncating or deleting a |
| 34416 | 34510 | ** file while a mapping is held, then the following winUnmapfile() call |
| @@ -34419,10 +34513,13 @@ | ||
| 34419 | 34513 | winUnmapfile(pFd); |
| 34420 | 34514 | } |
| 34421 | 34515 | |
| 34422 | 34516 | assert( pFd->nFetchOut>=0 ); |
| 34423 | 34517 | #endif |
| 34518 | + | |
| 34519 | + OSTRACE(("UNFETCH pid=%lu, pFile=%p, rc=SQLITE_OK\n", | |
| 34520 | + osGetCurrentProcessId(), fd)); | |
| 34424 | 34521 | return SQLITE_OK; |
| 34425 | 34522 | } |
| 34426 | 34523 | |
| 34427 | 34524 | /* |
| 34428 | 34525 | ** Here ends the implementation of all sqlite3_file methods. |
| @@ -34515,10 +34612,11 @@ | ||
| 34515 | 34612 | zMulti = unicodeToUtf8(zWidePath); |
| 34516 | 34613 | if( zMulti ){ |
| 34517 | 34614 | sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", zMulti); |
| 34518 | 34615 | sqlite3_free(zMulti); |
| 34519 | 34616 | }else{ |
| 34617 | + OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); | |
| 34520 | 34618 | return SQLITE_IOERR_NOMEM; |
| 34521 | 34619 | } |
| 34522 | 34620 | } |
| 34523 | 34621 | #ifdef SQLITE_WIN32_HAS_ANSI |
| 34524 | 34622 | else{ |
| @@ -34528,10 +34626,11 @@ | ||
| 34528 | 34626 | zUtf8 = sqlite3_win32_mbcs_to_utf8(zMbcsPath); |
| 34529 | 34627 | if( zUtf8 ){ |
| 34530 | 34628 | sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", zUtf8); |
| 34531 | 34629 | sqlite3_free(zUtf8); |
| 34532 | 34630 | }else{ |
| 34631 | + OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); | |
| 34533 | 34632 | return SQLITE_IOERR_NOMEM; |
| 34534 | 34633 | } |
| 34535 | 34634 | } |
| 34536 | 34635 | #endif |
| 34537 | 34636 | #endif |
| @@ -34540,10 +34639,11 @@ | ||
| 34540 | 34639 | ** name. If it is not, return SQLITE_ERROR. |
| 34541 | 34640 | */ |
| 34542 | 34641 | nTempPath = sqlite3Strlen30(zTempPath); |
| 34543 | 34642 | |
| 34544 | 34643 | if( (nTempPath + sqlite3Strlen30(SQLITE_TEMP_FILE_PREFIX) + 18) >= nBuf ){ |
| 34644 | + OSTRACE(("TEMP-FILENAME rc=SQLITE_ERROR\n")); | |
| 34545 | 34645 | return SQLITE_ERROR; |
| 34546 | 34646 | } |
| 34547 | 34647 | |
| 34548 | 34648 | for(i=nTempPath; i>0 && zTempPath[i-1]=='\\'; i--){} |
| 34549 | 34649 | zTempPath[i] = 0; |
| @@ -34557,12 +34657,12 @@ | ||
| 34557 | 34657 | zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ]; |
| 34558 | 34658 | } |
| 34559 | 34659 | zBuf[j] = 0; |
| 34560 | 34660 | zBuf[j+1] = 0; |
| 34561 | 34661 | |
| 34562 | - OSTRACE(("TEMP FILENAME: %s\n", zBuf)); | |
| 34563 | - return SQLITE_OK; | |
| 34662 | + OSTRACE(("TEMP-FILENAME name=%s, rc=SQLITE_OK\n", zBuf)); | |
| 34663 | + return SQLITE_OK; | |
| 34564 | 34664 | } |
| 34565 | 34665 | |
| 34566 | 34666 | /* |
| 34567 | 34667 | ** Return TRUE if the named file is really a directory. Return false if |
| 34568 | 34668 | ** it is something other than a directory, or if there is any kind of memory |
| @@ -34637,10 +34737,13 @@ | ||
| 34637 | 34737 | eType==SQLITE_OPEN_MASTER_JOURNAL |
| 34638 | 34738 | || eType==SQLITE_OPEN_MAIN_JOURNAL |
| 34639 | 34739 | || eType==SQLITE_OPEN_WAL |
| 34640 | 34740 | )); |
| 34641 | 34741 | #endif |
| 34742 | + | |
| 34743 | + OSTRACE(("OPEN name=%s, pFile=%p, flags=%x, pOutFlags=%p\n", | |
| 34744 | + zUtf8Name, id, flags, pOutFlags)); | |
| 34642 | 34745 | |
| 34643 | 34746 | /* Check the following statements are true: |
| 34644 | 34747 | ** |
| 34645 | 34748 | ** (a) Exactly one of the READWRITE and READONLY flags must be set, and |
| 34646 | 34749 | ** (b) if CREATE is set, then READWRITE must also be set, and |
| @@ -34683,10 +34786,11 @@ | ||
| 34683 | 34786 | if( !zUtf8Name ){ |
| 34684 | 34787 | assert(isDelete && !isOpenJournal); |
| 34685 | 34788 | memset(zTmpname, 0, MAX_PATH+2); |
| 34686 | 34789 | rc = getTempname(MAX_PATH+2, zTmpname); |
| 34687 | 34790 | if( rc!=SQLITE_OK ){ |
| 34791 | + OSTRACE(("OPEN name=%s, rc=%s", zUtf8Name, sqlite3ErrName(rc))); | |
| 34688 | 34792 | return rc; |
| 34689 | 34793 | } |
| 34690 | 34794 | zUtf8Name = zTmpname; |
| 34691 | 34795 | } |
| 34692 | 34796 | |
| @@ -34698,15 +34802,17 @@ | ||
| 34698 | 34802 | zUtf8Name[strlen(zUtf8Name)+1]==0 ); |
| 34699 | 34803 | |
| 34700 | 34804 | /* Convert the filename to the system encoding. */ |
| 34701 | 34805 | zConverted = convertUtf8Filename(zUtf8Name); |
| 34702 | 34806 | if( zConverted==0 ){ |
| 34807 | + OSTRACE(("OPEN name=%s, rc=SQLITE_IOERR_NOMEM", zUtf8Name)); | |
| 34703 | 34808 | return SQLITE_IOERR_NOMEM; |
| 34704 | 34809 | } |
| 34705 | 34810 | |
| 34706 | 34811 | if( winIsDir(zConverted) ){ |
| 34707 | 34812 | sqlite3_free(zConverted); |
| 34813 | + OSTRACE(("OPEN name=%s, rc=SQLITE_CANTOPEN_ISDIR", zUtf8Name)); | |
| 34708 | 34814 | return SQLITE_CANTOPEN_ISDIR; |
| 34709 | 34815 | } |
| 34710 | 34816 | |
| 34711 | 34817 | if( isReadWrite ){ |
| 34712 | 34818 | dwDesiredAccess = GENERIC_READ | GENERIC_WRITE; |
| @@ -34793,13 +34899,12 @@ | ||
| 34793 | 34899 | } |
| 34794 | 34900 | } |
| 34795 | 34901 | #endif |
| 34796 | 34902 | logIoerr(cnt); |
| 34797 | 34903 | |
| 34798 | - OSTRACE(("OPEN %d %s 0x%lx %s\n", | |
| 34799 | - h, zName, dwDesiredAccess, | |
| 34800 | - h==INVALID_HANDLE_VALUE ? "failed" : "ok")); | |
| 34904 | + OSTRACE(("OPEN file=%p, name=%s, access=%lx, rc=%s\n", h, zUtf8Name, | |
| 34905 | + dwDesiredAccess, (h==INVALID_HANDLE_VALUE) ? "failed" : "ok")); | |
| 34801 | 34906 | |
| 34802 | 34907 | if( h==INVALID_HANDLE_VALUE ){ |
| 34803 | 34908 | pFile->lastErrno = lastErrno; |
| 34804 | 34909 | winLogError(SQLITE_CANTOPEN, pFile->lastErrno, "winOpen", zUtf8Name); |
| 34805 | 34910 | sqlite3_free(zConverted); |
| @@ -34819,16 +34924,21 @@ | ||
| 34819 | 34924 | }else{ |
| 34820 | 34925 | *pOutFlags = SQLITE_OPEN_READONLY; |
| 34821 | 34926 | } |
| 34822 | 34927 | } |
| 34823 | 34928 | |
| 34929 | + OSTRACE(("OPEN file=%p, name=%s, access=%lx, pOutFlags=%p, *pOutFlags=%d, " | |
| 34930 | + "rc=%s\n", h, zUtf8Name, dwDesiredAccess, pOutFlags, pOutFlags ? | |
| 34931 | + *pOutFlags : 0, (h==INVALID_HANDLE_VALUE) ? "failed" : "ok")); | |
| 34932 | + | |
| 34824 | 34933 | #if SQLITE_OS_WINCE |
| 34825 | 34934 | if( isReadWrite && eType==SQLITE_OPEN_MAIN_DB |
| 34826 | 34935 | && (rc = winceCreateLock(zName, pFile))!=SQLITE_OK |
| 34827 | 34936 | ){ |
| 34828 | 34937 | osCloseHandle(h); |
| 34829 | 34938 | sqlite3_free(zConverted); |
| 34939 | + OSTRACE(("OPEN-CE-LOCK name=%s, rc=%s\n", zName, sqlite3ErrName(rc))); | |
| 34830 | 34940 | return rc; |
| 34831 | 34941 | } |
| 34832 | 34942 | if( isTemp ){ |
| 34833 | 34943 | pFile->zDeleteOnClose = zConverted; |
| 34834 | 34944 | }else |
| @@ -34884,10 +34994,12 @@ | ||
| 34884 | 34994 | void *zConverted; |
| 34885 | 34995 | UNUSED_PARAMETER(pVfs); |
| 34886 | 34996 | UNUSED_PARAMETER(syncDir); |
| 34887 | 34997 | |
| 34888 | 34998 | SimulateIOError(return SQLITE_IOERR_DELETE); |
| 34999 | + OSTRACE(("DELETE name=%s, syncDir=%d\n", zFilename, syncDir)); | |
| 35000 | + | |
| 34889 | 35001 | zConverted = convertUtf8Filename(zFilename); |
| 34890 | 35002 | if( zConverted==0 ){ |
| 34891 | 35003 | return SQLITE_IOERR_NOMEM; |
| 34892 | 35004 | } |
| 34893 | 35005 | if( isNT() ){ |
| @@ -34969,11 +35081,11 @@ | ||
| 34969 | 35081 | "winDelete", zFilename); |
| 34970 | 35082 | }else{ |
| 34971 | 35083 | logIoerr(cnt); |
| 34972 | 35084 | } |
| 34973 | 35085 | sqlite3_free(zConverted); |
| 34974 | - OSTRACE(("DELETE \"%s\" %s\n", zFilename, (rc ? "failed" : "ok" ))); | |
| 35086 | + OSTRACE(("DELETE name=%s, rc=%s\n", zFilename, sqlite3ErrName(rc))); | |
| 34975 | 35087 | return rc; |
| 34976 | 35088 | } |
| 34977 | 35089 | |
| 34978 | 35090 | /* |
| 34979 | 35091 | ** Check the existence and status of a file. |
| @@ -34989,12 +35101,16 @@ | ||
| 34989 | 35101 | DWORD lastErrno; |
| 34990 | 35102 | void *zConverted; |
| 34991 | 35103 | UNUSED_PARAMETER(pVfs); |
| 34992 | 35104 | |
| 34993 | 35105 | SimulateIOError( return SQLITE_IOERR_ACCESS; ); |
| 35106 | + OSTRACE(("ACCESS name=%s, flags=%x, pResOut=%p\n", | |
| 35107 | + zFilename, flags, pResOut)); | |
| 35108 | + | |
| 34994 | 35109 | zConverted = convertUtf8Filename(zFilename); |
| 34995 | 35110 | if( zConverted==0 ){ |
| 35111 | + OSTRACE(("ACCESS name=%s, rc=SQLITE_IOERR_NOMEM\n", zFilename)); | |
| 34996 | 35112 | return SQLITE_IOERR_NOMEM; |
| 34997 | 35113 | } |
| 34998 | 35114 | if( isNT() ){ |
| 34999 | 35115 | int cnt = 0; |
| 35000 | 35116 | WIN32_FILE_ATTRIBUTE_DATA sAttrData; |
| @@ -35041,10 +35157,12 @@ | ||
| 35041 | 35157 | break; |
| 35042 | 35158 | default: |
| 35043 | 35159 | assert(!"Invalid flags argument"); |
| 35044 | 35160 | } |
| 35045 | 35161 | *pResOut = rc; |
| 35162 | + OSTRACE(("ACCESS name=%s, pResOut=%p, *pResOut=%d, rc=SQLITE_OK\n", | |
| 35163 | + zFilename, pResOut, *pResOut)); | |
| 35046 | 35164 | return SQLITE_OK; |
| 35047 | 35165 | } |
| 35048 | 35166 | |
| 35049 | 35167 | |
| 35050 | 35168 | /* |
| @@ -51943,10 +52061,33 @@ | ||
| 51943 | 52061 | releasePage(pPage1); |
| 51944 | 52062 | pBt->pPage1 = 0; |
| 51945 | 52063 | return rc; |
| 51946 | 52064 | } |
| 51947 | 52065 | |
| 52066 | +#ifndef NDEBUG | |
| 52067 | +/* | |
| 52068 | +** Return the number of cursors open on pBt. This is for use | |
| 52069 | +** in assert() expressions, so it is only compiled if NDEBUG is not | |
| 52070 | +** defined. | |
| 52071 | +** | |
| 52072 | +** Only write cursors are counted if wrOnly is true. If wrOnly is | |
| 52073 | +** false then all cursors are counted. | |
| 52074 | +** | |
| 52075 | +** For the purposes of this routine, a cursor is any cursor that | |
| 52076 | +** is capable of reading or writing to the databse. Cursors that | |
| 52077 | +** have been tripped into the CURSOR_FAULT state are not counted. | |
| 52078 | +*/ | |
| 52079 | +static int countValidCursors(BtShared *pBt, int wrOnly){ | |
| 52080 | + BtCursor *pCur; | |
| 52081 | + int r = 0; | |
| 52082 | + for(pCur=pBt->pCursor; pCur; pCur=pCur->pNext){ | |
| 52083 | + if( (wrOnly==0 || pCur->wrFlag) && pCur->eState!=CURSOR_FAULT ) r++; | |
| 52084 | + } | |
| 52085 | + return r; | |
| 52086 | +} | |
| 52087 | +#endif | |
| 52088 | + | |
| 51948 | 52089 | /* |
| 51949 | 52090 | ** If there are no outstanding cursors and we are not in the middle |
| 51950 | 52091 | ** of a transaction but there is a read lock on the database, then |
| 51951 | 52092 | ** this routine unrefs the first page of the database file which |
| 51952 | 52093 | ** has the effect of releasing the read lock. |
| @@ -51953,11 +52094,11 @@ | ||
| 51953 | 52094 | ** |
| 51954 | 52095 | ** If there is a transaction in progress, this routine is a no-op. |
| 51955 | 52096 | */ |
| 51956 | 52097 | static void unlockBtreeIfUnused(BtShared *pBt){ |
| 51957 | 52098 | assert( sqlite3_mutex_held(pBt->mutex) ); |
| 51958 | - assert( pBt->pCursor==0 || pBt->inTransaction>TRANS_NONE ); | |
| 52099 | + assert( countValidCursors(pBt,0)==0 || pBt->inTransaction>TRANS_NONE ); | |
| 51959 | 52100 | if( pBt->inTransaction==TRANS_NONE && pBt->pPage1!=0 ){ |
| 51960 | 52101 | assert( pBt->pPage1->aData ); |
| 51961 | 52102 | assert( sqlite3PagerRefcount(pBt->pPager)==1 ); |
| 51962 | 52103 | assert( pBt->pPage1->aData ); |
| 51963 | 52104 | releasePage(pBt->pPage1); |
| @@ -52681,11 +52822,10 @@ | ||
| 52681 | 52822 | assert( sqlite3BtreeHoldsMutex(p) ); |
| 52682 | 52823 | |
| 52683 | 52824 | #ifndef SQLITE_OMIT_AUTOVACUUM |
| 52684 | 52825 | pBt->bDoTruncate = 0; |
| 52685 | 52826 | #endif |
| 52686 | - btreeClearHasContent(pBt); | |
| 52687 | 52827 | if( p->inTrans>TRANS_NONE && p->db->activeVdbeCnt>1 ){ |
| 52688 | 52828 | /* If there are other active statements that belong to this database |
| 52689 | 52829 | ** handle, downgrade to a read-only transaction. The other statements |
| 52690 | 52830 | ** may still be reading from the database. */ |
| 52691 | 52831 | downgradeAllSharedCacheTableLocks(p); |
| @@ -52756,10 +52896,11 @@ | ||
| 52756 | 52896 | if( rc!=SQLITE_OK && bCleanup==0 ){ |
| 52757 | 52897 | sqlite3BtreeLeave(p); |
| 52758 | 52898 | return rc; |
| 52759 | 52899 | } |
| 52760 | 52900 | pBt->inTransaction = TRANS_READ; |
| 52901 | + btreeClearHasContent(pBt); | |
| 52761 | 52902 | } |
| 52762 | 52903 | |
| 52763 | 52904 | btreeEndTransaction(p); |
| 52764 | 52905 | sqlite3BtreeLeave(p); |
| 52765 | 52906 | return SQLITE_OK; |
| @@ -52777,31 +52918,10 @@ | ||
| 52777 | 52918 | } |
| 52778 | 52919 | sqlite3BtreeLeave(p); |
| 52779 | 52920 | return rc; |
| 52780 | 52921 | } |
| 52781 | 52922 | |
| 52782 | -#ifndef NDEBUG | |
| 52783 | -/* | |
| 52784 | -** Return the number of write-cursors open on this handle. This is for use | |
| 52785 | -** in assert() expressions, so it is only compiled if NDEBUG is not | |
| 52786 | -** defined. | |
| 52787 | -** | |
| 52788 | -** For the purposes of this routine, a write-cursor is any cursor that | |
| 52789 | -** is capable of writing to the databse. That means the cursor was | |
| 52790 | -** originally opened for writing and the cursor has not be disabled | |
| 52791 | -** by having its state changed to CURSOR_FAULT. | |
| 52792 | -*/ | |
| 52793 | -static int countWriteCursors(BtShared *pBt){ | |
| 52794 | - BtCursor *pCur; | |
| 52795 | - int r = 0; | |
| 52796 | - for(pCur=pBt->pCursor; pCur; pCur=pCur->pNext){ | |
| 52797 | - if( pCur->wrFlag && pCur->eState!=CURSOR_FAULT ) r++; | |
| 52798 | - } | |
| 52799 | - return r; | |
| 52800 | -} | |
| 52801 | -#endif | |
| 52802 | - | |
| 52803 | 52923 | /* |
| 52804 | 52924 | ** This routine sets the state to CURSOR_FAULT and the error |
| 52805 | 52925 | ** code to errCode for every cursor on BtShared that pBtree |
| 52806 | 52926 | ** references. |
| 52807 | 52927 | ** |
| @@ -52877,12 +52997,13 @@ | ||
| 52877 | 52997 | if( nPage==0 ) sqlite3PagerPagecount(pBt->pPager, &nPage); |
| 52878 | 52998 | testcase( pBt->nPage!=nPage ); |
| 52879 | 52999 | pBt->nPage = nPage; |
| 52880 | 53000 | releasePage(pPage1); |
| 52881 | 53001 | } |
| 52882 | - assert( countWriteCursors(pBt)==0 ); | |
| 53002 | + assert( countValidCursors(pBt, 1)==0 ); | |
| 52883 | 53003 | pBt->inTransaction = TRANS_READ; |
| 53004 | + btreeClearHasContent(pBt); | |
| 52884 | 53005 | } |
| 52885 | 53006 | |
| 52886 | 53007 | btreeEndTransaction(p); |
| 52887 | 53008 | sqlite3BtreeLeave(p); |
| 52888 | 53009 | return rc; |
| @@ -75216,16 +75337,11 @@ | ||
| 75216 | 75337 | p = p->pLeft; |
| 75217 | 75338 | continue; |
| 75218 | 75339 | } |
| 75219 | 75340 | assert( op!=TK_REGISTER || p->op2!=TK_COLLATE ); |
| 75220 | 75341 | if( op==TK_COLLATE ){ |
| 75221 | - if( db->init.busy ){ | |
| 75222 | - /* Do not report errors when parsing while the schema */ | |
| 75223 | - pColl = sqlite3FindCollSeq(db, ENC(db), p->u.zToken, 0); | |
| 75224 | - }else{ | |
| 75225 | - pColl = sqlite3GetCollSeq(pParse, ENC(db), 0, p->u.zToken); | |
| 75226 | - } | |
| 75342 | + pColl = sqlite3GetCollSeq(pParse, ENC(db), 0, p->u.zToken); | |
| 75227 | 75343 | break; |
| 75228 | 75344 | } |
| 75229 | 75345 | if( p->pTab!=0 |
| 75230 | 75346 | && (op==TK_AGG_COLUMN || op==TK_COLUMN |
| 75231 | 75347 | || op==TK_REGISTER || op==TK_TRIGGER) |
| @@ -84722,14 +84838,12 @@ | ||
| 84722 | 84838 | ** specified collation sequence names. |
| 84723 | 84839 | */ |
| 84724 | 84840 | for(i=0; i<pList->nExpr; i++){ |
| 84725 | 84841 | Expr *pExpr = pList->a[i].pExpr; |
| 84726 | 84842 | if( pExpr ){ |
| 84727 | - CollSeq *pColl = sqlite3ExprCollSeq(pParse, pExpr); | |
| 84728 | - if( pColl ){ | |
| 84729 | - nExtra += (1 + sqlite3Strlen30(pColl->zName)); | |
| 84730 | - } | |
| 84843 | + assert( pExpr->op==TK_COLLATE ); | |
| 84844 | + nExtra += (1 + sqlite3Strlen30(pExpr->u.zToken)); | |
| 84731 | 84845 | } |
| 84732 | 84846 | } |
| 84733 | 84847 | |
| 84734 | 84848 | /* |
| 84735 | 84849 | ** Allocate the index structure. |
| @@ -84786,11 +84900,10 @@ | ||
| 84786 | 84900 | */ |
| 84787 | 84901 | for(i=0, pListItem=pList->a; i<pList->nExpr; i++, pListItem++){ |
| 84788 | 84902 | const char *zColName = pListItem->zName; |
| 84789 | 84903 | Column *pTabCol; |
| 84790 | 84904 | int requestedSortOrder; |
| 84791 | - CollSeq *pColl; /* Collating sequence */ | |
| 84792 | 84905 | char *zColl; /* Collation sequence name */ |
| 84793 | 84906 | |
| 84794 | 84907 | for(j=0, pTabCol=pTab->aCol; j<pTab->nCol; j++, pTabCol++){ |
| 84795 | 84908 | if( sqlite3StrICmp(zColName, pTabCol->zName)==0 ) break; |
| 84796 | 84909 | } |
| @@ -84799,26 +84912,23 @@ | ||
| 84799 | 84912 | pTab->zName, zColName); |
| 84800 | 84913 | pParse->checkSchema = 1; |
| 84801 | 84914 | goto exit_create_index; |
| 84802 | 84915 | } |
| 84803 | 84916 | pIndex->aiColumn[i] = j; |
| 84804 | - if( pListItem->pExpr | |
| 84805 | - && (pColl = sqlite3ExprCollSeq(pParse, pListItem->pExpr))!=0 | |
| 84806 | - ){ | |
| 84917 | + if( pListItem->pExpr ){ | |
| 84807 | 84918 | int nColl; |
| 84808 | - zColl = pColl->zName; | |
| 84919 | + assert( pListItem->pExpr->op==TK_COLLATE ); | |
| 84920 | + zColl = pListItem->pExpr->u.zToken; | |
| 84809 | 84921 | nColl = sqlite3Strlen30(zColl) + 1; |
| 84810 | 84922 | assert( nExtra>=nColl ); |
| 84811 | 84923 | memcpy(zExtra, zColl, nColl); |
| 84812 | 84924 | zColl = zExtra; |
| 84813 | 84925 | zExtra += nColl; |
| 84814 | 84926 | nExtra -= nColl; |
| 84815 | 84927 | }else{ |
| 84816 | 84928 | zColl = pTab->aCol[j].zColl; |
| 84817 | - if( !zColl ){ | |
| 84818 | - zColl = "BINARY"; | |
| 84819 | - } | |
| 84929 | + if( !zColl ) zColl = "BINARY"; | |
| 84820 | 84930 | } |
| 84821 | 84931 | if( !db->init.busy && !sqlite3LocateCollSeq(pParse, zColl) ){ |
| 84822 | 84932 | goto exit_create_index; |
| 84823 | 84933 | } |
| 84824 | 84934 | pIndex->azColl[i] = zColl; |
| @@ -108986,10 +109096,14 @@ | ||
| 108986 | 109096 | ** |
| 108987 | 109097 | ** Actually, each subexpression is converted to "xN AND w" where w is |
| 108988 | 109098 | ** the "interesting" terms of z - terms that did not originate in the |
| 108989 | 109099 | ** ON or USING clause of a LEFT JOIN, and terms that are usable as |
| 108990 | 109100 | ** indices. |
| 109101 | + ** | |
| 109102 | + ** This optimization also only applies if the (x1 OR x2 OR ...) term | |
| 109103 | + ** is not contained in the ON clause of a LEFT JOIN. | |
| 109104 | + ** See ticket http://www.sqlite.org/src/info/f2369304e4 | |
| 108991 | 109105 | */ |
| 108992 | 109106 | if( pWC->nTerm>1 ){ |
| 108993 | 109107 | int iTerm; |
| 108994 | 109108 | for(iTerm=0; iTerm<pWC->nTerm; iTerm++){ |
| 108995 | 109109 | Expr *pExpr = pWC->a[iTerm].pExpr; |
| @@ -109007,11 +109121,11 @@ | ||
| 109007 | 109121 | for(ii=0; ii<pOrWc->nTerm; ii++){ |
| 109008 | 109122 | WhereTerm *pOrTerm = &pOrWc->a[ii]; |
| 109009 | 109123 | if( pOrTerm->leftCursor==iCur || (pOrTerm->eOperator & WO_AND)!=0 ){ |
| 109010 | 109124 | WhereInfo *pSubWInfo; /* Info for single OR-term scan */ |
| 109011 | 109125 | Expr *pOrExpr = pOrTerm->pExpr; |
| 109012 | - if( pAndExpr ){ | |
| 109126 | + if( pAndExpr && !ExprHasProperty(pOrExpr, EP_FromJoin) ){ | |
| 109013 | 109127 | pAndExpr->pLeft = pOrExpr; |
| 109014 | 109128 | pOrExpr = pAndExpr; |
| 109015 | 109129 | } |
| 109016 | 109130 | /* Loop through table entries that match term pOrTerm. */ |
| 109017 | 109131 | pSubWInfo = sqlite3WhereBegin(pParse, pOrTab, pOrExpr, 0, 0, |
| @@ -115513,10 +115627,16 @@ | ||
| 115513 | 115627 | "statements or unfinished backups"); |
| 115514 | 115628 | sqlite3_mutex_leave(db->mutex); |
| 115515 | 115629 | return SQLITE_BUSY; |
| 115516 | 115630 | } |
| 115517 | 115631 | |
| 115632 | + /* If a transaction is open, roll it back. This also ensures that if | |
| 115633 | + ** any database schemas have been modified by the current transaction | |
| 115634 | + ** they are reset. And that the required b-tree mutex is held to make | |
| 115635 | + ** the the pager rollback and schema reset an atomic operation. */ | |
| 115636 | + sqlite3RollbackAll(db, SQLITE_OK); | |
| 115637 | + | |
| 115518 | 115638 | #ifdef SQLITE_ENABLE_SQLLOG |
| 115519 | 115639 | if( sqlite3GlobalConfig.xSqllog ){ |
| 115520 | 115640 | /* Closing the handle. Fourth parameter is passed the value 2. */ |
| 115521 | 115641 | sqlite3GlobalConfig.xSqllog(sqlite3GlobalConfig.pSqllogArg, db, 0, 2); |
| 115522 | 115642 | } |
| @@ -115667,10 +115787,11 @@ | ||
| 115667 | 115787 | SQLITE_PRIVATE void sqlite3RollbackAll(sqlite3 *db, int tripCode){ |
| 115668 | 115788 | int i; |
| 115669 | 115789 | int inTrans = 0; |
| 115670 | 115790 | assert( sqlite3_mutex_held(db->mutex) ); |
| 115671 | 115791 | sqlite3BeginBenignMalloc(); |
| 115792 | + sqlite3BtreeEnterAll(db); | |
| 115672 | 115793 | for(i=0; i<db->nDb; i++){ |
| 115673 | 115794 | Btree *p = db->aDb[i].pBt; |
| 115674 | 115795 | if( p ){ |
| 115675 | 115796 | if( sqlite3BtreeIsInTrans(p) ){ |
| 115676 | 115797 | inTrans = 1; |
| @@ -115684,10 +115805,11 @@ | ||
| 115684 | 115805 | |
| 115685 | 115806 | if( (db->flags&SQLITE_InternChanges)!=0 && db->init.busy==0 ){ |
| 115686 | 115807 | sqlite3ExpirePreparedStatements(db); |
| 115687 | 115808 | sqlite3ResetAllSchemasOfConnection(db); |
| 115688 | 115809 | } |
| 115810 | + sqlite3BtreeLeaveAll(db); | |
| 115689 | 115811 | |
| 115690 | 115812 | /* Any deferred constraint violations have now been resolved. */ |
| 115691 | 115813 | db->nDeferredCons = 0; |
| 115692 | 115814 | |
| 115693 | 115815 | /* If one has been configured, invoke the rollback-hook callback */ |
| @@ -115694,10 +115816,114 @@ | ||
| 115694 | 115816 | if( db->xRollbackCallback && (inTrans || !db->autoCommit) ){ |
| 115695 | 115817 | db->xRollbackCallback(db->pRollbackArg); |
| 115696 | 115818 | } |
| 115697 | 115819 | } |
| 115698 | 115820 | |
| 115821 | +/* | |
| 115822 | +** Return a static string containing the name corresponding to the error code | |
| 115823 | +** specified in the argument. | |
| 115824 | +*/ | |
| 115825 | +#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) || \ | |
| 115826 | + defined(SQLITE_DEBUG_OS_TRACE) | |
| 115827 | +SQLITE_PRIVATE const char *sqlite3ErrName(int rc){ | |
| 115828 | + const char *zName = 0; | |
| 115829 | + int i, origRc = rc; | |
| 115830 | + for(i=0; i<2 && zName==0; i++, rc &= 0xff){ | |
| 115831 | + switch( rc ){ | |
| 115832 | + case SQLITE_OK: zName = "SQLITE_OK"; break; | |
| 115833 | + case SQLITE_ERROR: zName = "SQLITE_ERROR"; break; | |
| 115834 | + case SQLITE_INTERNAL: zName = "SQLITE_INTERNAL"; break; | |
| 115835 | + case SQLITE_PERM: zName = "SQLITE_PERM"; break; | |
| 115836 | + case SQLITE_ABORT: zName = "SQLITE_ABORT"; break; | |
| 115837 | + case SQLITE_ABORT_ROLLBACK: zName = "SQLITE_ABORT_ROLLBACK"; break; | |
| 115838 | + case SQLITE_BUSY: zName = "SQLITE_BUSY"; break; | |
| 115839 | + case SQLITE_BUSY_RECOVERY: zName = "SQLITE_BUSY_RECOVERY"; break; | |
| 115840 | + case SQLITE_LOCKED: zName = "SQLITE_LOCKED"; break; | |
| 115841 | + case SQLITE_LOCKED_SHAREDCACHE: zName = "SQLITE_LOCKED_SHAREDCACHE";break; | |
| 115842 | + case SQLITE_NOMEM: zName = "SQLITE_NOMEM"; break; | |
| 115843 | + case SQLITE_READONLY: zName = "SQLITE_READONLY"; break; | |
| 115844 | + case SQLITE_READONLY_RECOVERY: zName = "SQLITE_READONLY_RECOVERY"; break; | |
| 115845 | + case SQLITE_READONLY_CANTLOCK: zName = "SQLITE_READONLY_CANTLOCK"; break; | |
| 115846 | + case SQLITE_READONLY_ROLLBACK: zName = "SQLITE_READONLY_ROLLBACK"; break; | |
| 115847 | + case SQLITE_INTERRUPT: zName = "SQLITE_INTERRUPT"; break; | |
| 115848 | + case SQLITE_IOERR: zName = "SQLITE_IOERR"; break; | |
| 115849 | + case SQLITE_IOERR_READ: zName = "SQLITE_IOERR_READ"; break; | |
| 115850 | + case SQLITE_IOERR_SHORT_READ: zName = "SQLITE_IOERR_SHORT_READ"; break; | |
| 115851 | + case SQLITE_IOERR_WRITE: zName = "SQLITE_IOERR_WRITE"; break; | |
| 115852 | + case SQLITE_IOERR_FSYNC: zName = "SQLITE_IOERR_FSYNC"; break; | |
| 115853 | + case SQLITE_IOERR_DIR_FSYNC: zName = "SQLITE_IOERR_DIR_FSYNC"; break; | |
| 115854 | + case SQLITE_IOERR_TRUNCATE: zName = "SQLITE_IOERR_TRUNCATE"; break; | |
| 115855 | + case SQLITE_IOERR_FSTAT: zName = "SQLITE_IOERR_FSTAT"; break; | |
| 115856 | + case SQLITE_IOERR_UNLOCK: zName = "SQLITE_IOERR_UNLOCK"; break; | |
| 115857 | + case SQLITE_IOERR_RDLOCK: zName = "SQLITE_IOERR_RDLOCK"; break; | |
| 115858 | + case SQLITE_IOERR_DELETE: zName = "SQLITE_IOERR_DELETE"; break; | |
| 115859 | + case SQLITE_IOERR_BLOCKED: zName = "SQLITE_IOERR_BLOCKED"; break; | |
| 115860 | + case SQLITE_IOERR_NOMEM: zName = "SQLITE_IOERR_NOMEM"; break; | |
| 115861 | + case SQLITE_IOERR_ACCESS: zName = "SQLITE_IOERR_ACCESS"; break; | |
| 115862 | + case SQLITE_IOERR_CHECKRESERVEDLOCK: | |
| 115863 | + zName = "SQLITE_IOERR_CHECKRESERVEDLOCK"; break; | |
| 115864 | + case SQLITE_IOERR_LOCK: zName = "SQLITE_IOERR_LOCK"; break; | |
| 115865 | + case SQLITE_IOERR_CLOSE: zName = "SQLITE_IOERR_CLOSE"; break; | |
| 115866 | + case SQLITE_IOERR_DIR_CLOSE: zName = "SQLITE_IOERR_DIR_CLOSE"; break; | |
| 115867 | + case SQLITE_IOERR_SHMOPEN: zName = "SQLITE_IOERR_SHMOPEN"; break; | |
| 115868 | + case SQLITE_IOERR_SHMSIZE: zName = "SQLITE_IOERR_SHMSIZE"; break; | |
| 115869 | + case SQLITE_IOERR_SHMLOCK: zName = "SQLITE_IOERR_SHMLOCK"; break; | |
| 115870 | + case SQLITE_IOERR_SHMMAP: zName = "SQLITE_IOERR_SHMMAP"; break; | |
| 115871 | + case SQLITE_IOERR_SEEK: zName = "SQLITE_IOERR_SEEK"; break; | |
| 115872 | + case SQLITE_IOERR_DELETE_NOENT: zName = "SQLITE_IOERR_DELETE_NOENT";break; | |
| 115873 | + case SQLITE_IOERR_MMAP: zName = "SQLITE_IOERR_MMAP"; break; | |
| 115874 | + case SQLITE_CORRUPT: zName = "SQLITE_CORRUPT"; break; | |
| 115875 | + case SQLITE_CORRUPT_VTAB: zName = "SQLITE_CORRUPT_VTAB"; break; | |
| 115876 | + case SQLITE_NOTFOUND: zName = "SQLITE_NOTFOUND"; break; | |
| 115877 | + case SQLITE_FULL: zName = "SQLITE_FULL"; break; | |
| 115878 | + case SQLITE_CANTOPEN: zName = "SQLITE_CANTOPEN"; break; | |
| 115879 | + case SQLITE_CANTOPEN_NOTEMPDIR: zName = "SQLITE_CANTOPEN_NOTEMPDIR";break; | |
| 115880 | + case SQLITE_CANTOPEN_ISDIR: zName = "SQLITE_CANTOPEN_ISDIR"; break; | |
| 115881 | + case SQLITE_CANTOPEN_FULLPATH: zName = "SQLITE_CANTOPEN_FULLPATH"; break; | |
| 115882 | + case SQLITE_PROTOCOL: zName = "SQLITE_PROTOCOL"; break; | |
| 115883 | + case SQLITE_EMPTY: zName = "SQLITE_EMPTY"; break; | |
| 115884 | + case SQLITE_SCHEMA: zName = "SQLITE_SCHEMA"; break; | |
| 115885 | + case SQLITE_TOOBIG: zName = "SQLITE_TOOBIG"; break; | |
| 115886 | + case SQLITE_CONSTRAINT: zName = "SQLITE_CONSTRAINT"; break; | |
| 115887 | + case SQLITE_CONSTRAINT_UNIQUE: zName = "SQLITE_CONSTRAINT_UNIQUE"; break; | |
| 115888 | + case SQLITE_CONSTRAINT_TRIGGER: zName = "SQLITE_CONSTRAINT_TRIGGER";break; | |
| 115889 | + case SQLITE_CONSTRAINT_FOREIGNKEY: | |
| 115890 | + zName = "SQLITE_CONSTRAINT_FOREIGNKEY"; break; | |
| 115891 | + case SQLITE_CONSTRAINT_CHECK: zName = "SQLITE_CONSTRAINT_CHECK"; break; | |
| 115892 | + case SQLITE_CONSTRAINT_PRIMARYKEY: | |
| 115893 | + zName = "SQLITE_CONSTRAINT_PRIMARYKEY"; break; | |
| 115894 | + case SQLITE_CONSTRAINT_NOTNULL: zName = "SQLITE_CONSTRAINT_NOTNULL";break; | |
| 115895 | + case SQLITE_CONSTRAINT_COMMITHOOK: | |
| 115896 | + zName = "SQLITE_CONSTRAINT_COMMITHOOK"; break; | |
| 115897 | + case SQLITE_CONSTRAINT_VTAB: zName = "SQLITE_CONSTRAINT_VTAB"; break; | |
| 115898 | + case SQLITE_CONSTRAINT_FUNCTION: | |
| 115899 | + zName = "SQLITE_CONSTRAINT_FUNCTION"; break; | |
| 115900 | + case SQLITE_MISMATCH: zName = "SQLITE_MISMATCH"; break; | |
| 115901 | + case SQLITE_MISUSE: zName = "SQLITE_MISUSE"; break; | |
| 115902 | + case SQLITE_NOLFS: zName = "SQLITE_NOLFS"; break; | |
| 115903 | + case SQLITE_AUTH: zName = "SQLITE_AUTH"; break; | |
| 115904 | + case SQLITE_FORMAT: zName = "SQLITE_FORMAT"; break; | |
| 115905 | + case SQLITE_RANGE: zName = "SQLITE_RANGE"; break; | |
| 115906 | + case SQLITE_NOTADB: zName = "SQLITE_NOTADB"; break; | |
| 115907 | + case SQLITE_ROW: zName = "SQLITE_ROW"; break; | |
| 115908 | + case SQLITE_NOTICE: zName = "SQLITE_NOTICE"; break; | |
| 115909 | + case SQLITE_NOTICE_RECOVER_WAL: zName = "SQLITE_NOTICE_RECOVER_WAL";break; | |
| 115910 | + case SQLITE_NOTICE_RECOVER_ROLLBACK: | |
| 115911 | + zName = "SQLITE_NOTICE_RECOVER_ROLLBACK"; break; | |
| 115912 | + case SQLITE_WARNING: zName = "SQLITE_WARNING"; break; | |
| 115913 | + case SQLITE_DONE: zName = "SQLITE_DONE"; break; | |
| 115914 | + } | |
| 115915 | + } | |
| 115916 | + if( zName==0 ){ | |
| 115917 | + static char zBuf[50]; | |
| 115918 | + sqlite3_snprintf(sizeof(zBuf), zBuf, "SQLITE_UNKNOWN(%d)", origRc); | |
| 115919 | + zName = zBuf; | |
| 115920 | + } | |
| 115921 | + return zName; | |
| 115922 | +} | |
| 115923 | +#endif | |
| 115924 | + | |
| 115699 | 115925 | /* |
| 115700 | 115926 | ** Return a static string that describes the kind of error specified in the |
| 115701 | 115927 | ** argument. |
| 115702 | 115928 | */ |
| 115703 | 115929 | SQLITE_PRIVATE const char *sqlite3ErrStr(int rc){ |
| 115704 | 115930 |
| --- src/sqlite3.c | |
| +++ src/sqlite3.c | |
| @@ -678,11 +678,11 @@ | |
| 678 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 679 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 680 | */ |
| 681 | #define SQLITE_VERSION "3.7.17" |
| 682 | #define SQLITE_VERSION_NUMBER 3007017 |
| 683 | #define SQLITE_SOURCE_ID "2013-05-08 17:06:28 1fa8c457394c94864f7584e4c893ec09e685fba4" |
| 684 | |
| 685 | /* |
| 686 | ** CAPI3REF: Run-Time Library Version Numbers |
| 687 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 688 | ** |
| @@ -12251,10 +12251,16 @@ | |
| 12251 | SQLITE_PRIVATE int sqlite3Atoi64(const char*, i64*, int, u8); |
| 12252 | SQLITE_PRIVATE void sqlite3Error(sqlite3*, int, const char*,...); |
| 12253 | SQLITE_PRIVATE void *sqlite3HexToBlob(sqlite3*, const char *z, int n); |
| 12254 | SQLITE_PRIVATE u8 sqlite3HexToInt(int h); |
| 12255 | SQLITE_PRIVATE int sqlite3TwoPartName(Parse *, Token *, Token *, Token **); |
| 12256 | SQLITE_PRIVATE const char *sqlite3ErrStr(int); |
| 12257 | SQLITE_PRIVATE int sqlite3ReadSchema(Parse *pParse); |
| 12258 | SQLITE_PRIVATE CollSeq *sqlite3FindCollSeq(sqlite3*,u8 enc, const char*,int); |
| 12259 | SQLITE_PRIVATE CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char*zName); |
| 12260 | SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr); |
| @@ -26237,10 +26243,12 @@ | |
| 26237 | sqlite3_int64 offset |
| 26238 | ){ |
| 26239 | unixFile *pFile = (unixFile *)id; |
| 26240 | int got; |
| 26241 | assert( id ); |
| 26242 | |
| 26243 | /* If this is a database file (not a journal, master-journal or temp |
| 26244 | ** file), the bytes in the locking range should never be read or written. */ |
| 26245 | #if 0 |
| 26246 | assert( pFile->pUnused==0 |
| @@ -32230,11 +32238,11 @@ | |
| 32230 | osLocalFree(zTemp); |
| 32231 | } |
| 32232 | } |
| 32233 | #endif |
| 32234 | if( 0 == dwLen ){ |
| 32235 | sqlite3_snprintf(nBuf, zBuf, "OsError 0x%x (%u)", lastErrno, lastErrno); |
| 32236 | }else{ |
| 32237 | /* copy a maximum of nBuf chars to output buffer */ |
| 32238 | sqlite3_snprintf(nBuf, zBuf, "%s", zOut); |
| 32239 | /* free the UTF8 buffer */ |
| 32240 | sqlite3_free(zOut); |
| @@ -32273,11 +32281,11 @@ | |
| 32273 | assert( errcode!=SQLITE_OK ); |
| 32274 | if( zPath==0 ) zPath = ""; |
| 32275 | for(i=0; zMsg[i] && zMsg[i]!='\r' && zMsg[i]!='\n'; i++){} |
| 32276 | zMsg[i] = 0; |
| 32277 | sqlite3_log(errcode, |
| 32278 | "os_win.c:%d: (%d) %s(%s) - %s", |
| 32279 | iLine, lastErrno, zFunc, zPath, zMsg |
| 32280 | ); |
| 32281 | |
| 32282 | return errcode; |
| 32283 | } |
| @@ -32734,10 +32742,12 @@ | |
| 32734 | LONG upperBits; /* Most sig. 32 bits of new offset */ |
| 32735 | LONG lowerBits; /* Least sig. 32 bits of new offset */ |
| 32736 | DWORD dwRet; /* Value returned by SetFilePointer() */ |
| 32737 | DWORD lastErrno; /* Value returned by GetLastError() */ |
| 32738 | |
| 32739 | upperBits = (LONG)((iOffset>>32) & 0x7fffffff); |
| 32740 | lowerBits = (LONG)(iOffset & 0xffffffff); |
| 32741 | |
| 32742 | /* API oddity: If successful, SetFilePointer() returns a dword |
| 32743 | ** containing the lower 32-bits of the new file-offset. Or, if it fails, |
| @@ -32751,13 +32761,15 @@ | |
| 32751 | if( (dwRet==INVALID_SET_FILE_POINTER |
| 32752 | && ((lastErrno = osGetLastError())!=NO_ERROR)) ){ |
| 32753 | pFile->lastErrno = lastErrno; |
| 32754 | winLogError(SQLITE_IOERR_SEEK, pFile->lastErrno, |
| 32755 | "seekWinFile", pFile->zPath); |
| 32756 | return 1; |
| 32757 | } |
| 32758 | |
| 32759 | return 0; |
| 32760 | #else |
| 32761 | /* |
| 32762 | ** Same as above, except that this implementation works for WinRT. |
| 32763 | */ |
| @@ -32770,13 +32782,15 @@ | |
| 32770 | |
| 32771 | if(!bRet){ |
| 32772 | pFile->lastErrno = osGetLastError(); |
| 32773 | winLogError(SQLITE_IOERR_SEEK, pFile->lastErrno, |
| 32774 | "seekWinFile", pFile->zPath); |
| 32775 | return 1; |
| 32776 | } |
| 32777 | |
| 32778 | return 0; |
| 32779 | #endif |
| 32780 | } |
| 32781 | |
| 32782 | #if SQLITE_MAX_MMAP_SIZE>0 |
| @@ -32801,12 +32815,12 @@ | |
| 32801 | |
| 32802 | assert( id!=0 ); |
| 32803 | #ifndef SQLITE_OMIT_WAL |
| 32804 | assert( pFile->pShm==0 ); |
| 32805 | #endif |
| 32806 | OSTRACE(("CLOSE %d\n", pFile->h)); |
| 32807 | assert( pFile->h!=NULL && pFile->h!=INVALID_HANDLE_VALUE ); |
| 32808 | |
| 32809 | #if SQLITE_MAX_MMAP_SIZE>0 |
| 32810 | rc = winUnmapfile(pFile); |
| 32811 | if( rc!=SQLITE_OK ) return rc; |
| 32812 | #endif |
| @@ -32828,15 +32842,15 @@ | |
| 32828 | sqlite3_win32_sleep(100); /* Wait a little before trying again */ |
| 32829 | } |
| 32830 | sqlite3_free(pFile->zDeleteOnClose); |
| 32831 | } |
| 32832 | #endif |
| 32833 | OSTRACE(("CLOSE %d %s\n", pFile->h, rc ? "ok" : "failed")); |
| 32834 | if( rc ){ |
| 32835 | pFile->h = NULL; |
| 32836 | } |
| 32837 | OpenCounter(-1); |
| 32838 | return rc ? SQLITE_OK |
| 32839 | : winLogError(SQLITE_IOERR_CLOSE, osGetLastError(), |
| 32840 | "winClose", pFile->zPath); |
| 32841 | } |
| 32842 | |
| @@ -32858,19 +32872,22 @@ | |
| 32858 | DWORD nRead; /* Number of bytes actually read from file */ |
| 32859 | int nRetry = 0; /* Number of retrys */ |
| 32860 | |
| 32861 | assert( id!=0 ); |
| 32862 | assert( amt>0 ); |
| 32863 | SimulateIOError(return SQLITE_IOERR_READ); |
| 32864 | OSTRACE(("READ %d lock=%d\n", pFile->h, pFile->locktype)); |
| 32865 | |
| 32866 | #if SQLITE_MAX_MMAP_SIZE>0 |
| 32867 | /* Deal with as much of this read request as possible by transfering |
| 32868 | ** data from the memory mapping using memcpy(). */ |
| 32869 | if( offset<pFile->mmapSize ){ |
| 32870 | if( offset+amt <= pFile->mmapSize ){ |
| 32871 | memcpy(pBuf, &((u8 *)(pFile->pMapRegion))[offset], amt); |
| 32872 | return SQLITE_OK; |
| 32873 | }else{ |
| 32874 | int nCopy = (int)(pFile->mmapSize - offset); |
| 32875 | memcpy(pBuf, &((u8 *)(pFile->pMapRegion))[offset], nCopy); |
| 32876 | pBuf = &((u8 *)pBuf)[nCopy]; |
| @@ -32880,10 +32897,11 @@ | |
| 32880 | } |
| 32881 | #endif |
| 32882 | |
| 32883 | #if SQLITE_OS_WINCE |
| 32884 | if( seekWinFile(pFile, offset) ){ |
| 32885 | return SQLITE_FULL; |
| 32886 | } |
| 32887 | while( !osReadFile(pFile->h, pBuf, amt, &nRead, 0) ){ |
| 32888 | #else |
| 32889 | memset(&overlapped, 0, sizeof(OVERLAPPED)); |
| @@ -32893,20 +32911,23 @@ | |
| 32893 | osGetLastError()!=ERROR_HANDLE_EOF ){ |
| 32894 | #endif |
| 32895 | DWORD lastErrno; |
| 32896 | if( retryIoerr(&nRetry, &lastErrno) ) continue; |
| 32897 | pFile->lastErrno = lastErrno; |
| 32898 | return winLogError(SQLITE_IOERR_READ, pFile->lastErrno, |
| 32899 | "winRead", pFile->zPath); |
| 32900 | } |
| 32901 | logIoerr(nRetry); |
| 32902 | if( nRead<(DWORD)amt ){ |
| 32903 | /* Unread parts of the buffer must be zero-filled */ |
| 32904 | memset(&((char*)pBuf)[nRead], 0, amt-nRead); |
| 32905 | return SQLITE_IOERR_SHORT_READ; |
| 32906 | } |
| 32907 | |
| 32908 | return SQLITE_OK; |
| 32909 | } |
| 32910 | |
| 32911 | /* |
| 32912 | ** Write data from a buffer into a file. Return SQLITE_OK on success |
| @@ -32925,18 +32946,20 @@ | |
| 32925 | assert( amt>0 ); |
| 32926 | assert( pFile ); |
| 32927 | SimulateIOError(return SQLITE_IOERR_WRITE); |
| 32928 | SimulateDiskfullError(return SQLITE_FULL); |
| 32929 | |
| 32930 | OSTRACE(("WRITE %d lock=%d\n", pFile->h, pFile->locktype)); |
| 32931 | |
| 32932 | #if SQLITE_MAX_MMAP_SIZE>0 |
| 32933 | /* Deal with as much of this write request as possible by transfering |
| 32934 | ** data from the memory mapping using memcpy(). */ |
| 32935 | if( offset<pFile->mmapSize ){ |
| 32936 | if( offset+amt <= pFile->mmapSize ){ |
| 32937 | memcpy(&((u8 *)(pFile->pMapRegion))[offset], pBuf, amt); |
| 32938 | return SQLITE_OK; |
| 32939 | }else{ |
| 32940 | int nCopy = (int)(pFile->mmapSize - offset); |
| 32941 | memcpy(&((u8 *)(pFile->pMapRegion))[offset], pBuf, nCopy); |
| 32942 | pBuf = &((u8 *)pBuf)[nCopy]; |
| @@ -32995,17 +33018,20 @@ | |
| 32995 | } |
| 32996 | |
| 32997 | if( rc ){ |
| 32998 | if( ( pFile->lastErrno==ERROR_HANDLE_DISK_FULL ) |
| 32999 | || ( pFile->lastErrno==ERROR_DISK_FULL )){ |
| 33000 | return SQLITE_FULL; |
| 33001 | } |
| 33002 | return winLogError(SQLITE_IOERR_WRITE, pFile->lastErrno, |
| 33003 | "winWrite", pFile->zPath); |
| 33004 | }else{ |
| 33005 | logIoerr(nRetry); |
| 33006 | } |
| 33007 | return SQLITE_OK; |
| 33008 | } |
| 33009 | |
| 33010 | /* |
| 33011 | ** Truncate an open file to a specified size |
| @@ -33014,13 +33040,13 @@ | |
| 33014 | winFile *pFile = (winFile*)id; /* File handle object */ |
| 33015 | int rc = SQLITE_OK; /* Return code for this function */ |
| 33016 | DWORD lastErrno; |
| 33017 | |
| 33018 | assert( pFile ); |
| 33019 | |
| 33020 | OSTRACE(("TRUNCATE %d %lld\n", pFile->h, nByte)); |
| 33021 | SimulateIOError(return SQLITE_IOERR_TRUNCATE); |
| 33022 | |
| 33023 | /* If the user has configured a chunk-size for this file, truncate the |
| 33024 | ** file so that it consists of an integer number of chunks (i.e. the |
| 33025 | ** actual file size after the operation may be larger than the requested |
| 33026 | ** size). |
| @@ -33048,11 +33074,11 @@ | |
| 33048 | if( pFile->pMapRegion && nByte<pFile->mmapSize ){ |
| 33049 | pFile->mmapSize = nByte; |
| 33050 | } |
| 33051 | #endif |
| 33052 | |
| 33053 | OSTRACE(("TRUNCATE %d %lld %s\n", pFile->h, nByte, rc ? "failed" : "ok")); |
| 33054 | return rc; |
| 33055 | } |
| 33056 | |
| 33057 | #ifdef SQLITE_TEST |
| 33058 | /* |
| @@ -33088,16 +33114,17 @@ | |
| 33088 | /* Check that one of SQLITE_SYNC_NORMAL or FULL was passed */ |
| 33089 | assert((flags&0x0F)==SQLITE_SYNC_NORMAL |
| 33090 | || (flags&0x0F)==SQLITE_SYNC_FULL |
| 33091 | ); |
| 33092 | |
| 33093 | OSTRACE(("SYNC %d lock=%d\n", pFile->h, pFile->locktype)); |
| 33094 | |
| 33095 | /* Unix cannot, but some systems may return SQLITE_FULL from here. This |
| 33096 | ** line is to test that doing so does not cause any problems. |
| 33097 | */ |
| 33098 | SimulateDiskfullError( return SQLITE_FULL ); |
| 33099 | |
| 33100 | #ifndef SQLITE_TEST |
| 33101 | UNUSED_PARAMETER(flags); |
| 33102 | #else |
| 33103 | if( (flags&0x0F)==SQLITE_SYNC_FULL ){ |
| @@ -33113,13 +33140,15 @@ | |
| 33113 | return SQLITE_OK; |
| 33114 | #else |
| 33115 | rc = osFlushFileBuffers(pFile->h); |
| 33116 | SimulateIOError( rc=FALSE ); |
| 33117 | if( rc ){ |
| 33118 | return SQLITE_OK; |
| 33119 | }else{ |
| 33120 | pFile->lastErrno = osGetLastError(); |
| 33121 | return winLogError(SQLITE_IOERR_FSYNC, pFile->lastErrno, |
| 33122 | "winSync", pFile->zPath); |
| 33123 | } |
| 33124 | #endif |
| 33125 | } |
| @@ -33130,11 +33159,14 @@ | |
| 33130 | static int winFileSize(sqlite3_file *id, sqlite3_int64 *pSize){ |
| 33131 | winFile *pFile = (winFile*)id; |
| 33132 | int rc = SQLITE_OK; |
| 33133 | |
| 33134 | assert( id!=0 ); |
| 33135 | SimulateIOError(return SQLITE_IOERR_FSTAT); |
| 33136 | #if SQLITE_OS_WINRT |
| 33137 | { |
| 33138 | FILE_STANDARD_INFO info; |
| 33139 | if( osGetFileInformationByHandleEx(pFile->h, FileStandardInfo, |
| 33140 | &info, sizeof(info)) ){ |
| @@ -33159,10 +33191,12 @@ | |
| 33159 | rc = winLogError(SQLITE_IOERR_FSTAT, pFile->lastErrno, |
| 33160 | "winFileSize", pFile->zPath); |
| 33161 | } |
| 33162 | } |
| 33163 | #endif |
| 33164 | return rc; |
| 33165 | } |
| 33166 | |
| 33167 | /* |
| 33168 | ** LOCKFILE_FAIL_IMMEDIATELY is undefined on some Windows systems. |
| @@ -33200,10 +33234,11 @@ | |
| 33200 | ** Different API routines are called depending on whether or not this |
| 33201 | ** is Win9x or WinNT. |
| 33202 | */ |
| 33203 | static int getReadLock(winFile *pFile){ |
| 33204 | int res; |
| 33205 | if( isNT() ){ |
| 33206 | #if SQLITE_OS_WINCE |
| 33207 | /* |
| 33208 | ** NOTE: Windows CE is handled differently here due its lack of the Win32 |
| 33209 | ** API LockFileEx. |
| @@ -33225,19 +33260,21 @@ | |
| 33225 | #endif |
| 33226 | if( res == 0 ){ |
| 33227 | pFile->lastErrno = osGetLastError(); |
| 33228 | /* No need to log a failure to lock */ |
| 33229 | } |
| 33230 | return res; |
| 33231 | } |
| 33232 | |
| 33233 | /* |
| 33234 | ** Undo a readlock |
| 33235 | */ |
| 33236 | static int unlockReadLock(winFile *pFile){ |
| 33237 | int res; |
| 33238 | DWORD lastErrno; |
| 33239 | if( isNT() ){ |
| 33240 | res = winUnlockFile(&pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0); |
| 33241 | } |
| 33242 | #ifdef SQLITE_WIN32_HAS_ANSI |
| 33243 | else{ |
| @@ -33247,10 +33284,11 @@ | |
| 33247 | if( res==0 && ((lastErrno = osGetLastError())!=ERROR_NOT_LOCKED) ){ |
| 33248 | pFile->lastErrno = lastErrno; |
| 33249 | winLogError(SQLITE_IOERR_UNLOCK, pFile->lastErrno, |
| 33250 | "unlockReadLock", pFile->zPath); |
| 33251 | } |
| 33252 | return res; |
| 33253 | } |
| 33254 | |
| 33255 | /* |
| 33256 | ** Lock the file with the lock specified by parameter locktype - one |
| @@ -33285,18 +33323,19 @@ | |
| 33285 | int gotPendingLock = 0;/* True if we acquired a PENDING lock this time */ |
| 33286 | winFile *pFile = (winFile*)id; |
| 33287 | DWORD lastErrno = NO_ERROR; |
| 33288 | |
| 33289 | assert( id!=0 ); |
| 33290 | OSTRACE(("LOCK %d %d was %d(%d)\n", |
| 33291 | pFile->h, locktype, pFile->locktype, pFile->sharedLockByte)); |
| 33292 | |
| 33293 | /* If there is already a lock of this type or more restrictive on the |
| 33294 | ** OsFile, do nothing. Don't use the end_lock: exit path, as |
| 33295 | ** sqlite3OsEnterMutex() hasn't been called yet. |
| 33296 | */ |
| 33297 | if( pFile->locktype>=locktype ){ |
| 33298 | return SQLITE_OK; |
| 33299 | } |
| 33300 | |
| 33301 | /* Make sure the locking sequence is correct |
| 33302 | */ |
| @@ -33320,11 +33359,12 @@ | |
| 33320 | ** around problems caused by indexing and/or anti-virus software on |
| 33321 | ** Windows systems. |
| 33322 | ** If you are using this code as a model for alternative VFSes, do not |
| 33323 | ** copy this retry logic. It is a hack intended for Windows only. |
| 33324 | */ |
| 33325 | OSTRACE(("could not get a PENDING lock. cnt=%d\n", cnt)); |
| 33326 | if( cnt ) sqlite3_win32_sleep(1); |
| 33327 | } |
| 33328 | gotPendingLock = res; |
| 33329 | if( !res ){ |
| 33330 | lastErrno = osGetLastError(); |
| @@ -33365,18 +33405,16 @@ | |
| 33365 | /* Acquire an EXCLUSIVE lock |
| 33366 | */ |
| 33367 | if( locktype==EXCLUSIVE_LOCK && res ){ |
| 33368 | assert( pFile->locktype>=SHARED_LOCK ); |
| 33369 | res = unlockReadLock(pFile); |
| 33370 | OSTRACE(("unreadlock = %d\n", res)); |
| 33371 | res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS, SHARED_FIRST, 0, |
| 33372 | SHARED_SIZE, 0); |
| 33373 | if( res ){ |
| 33374 | newLocktype = EXCLUSIVE_LOCK; |
| 33375 | }else{ |
| 33376 | lastErrno = osGetLastError(); |
| 33377 | OSTRACE(("error-code = %d\n", lastErrno)); |
| 33378 | getReadLock(pFile); |
| 33379 | } |
| 33380 | } |
| 33381 | |
| 33382 | /* If we are holding a PENDING lock that ought to be released, then |
| @@ -33390,16 +33428,18 @@ | |
| 33390 | ** return the appropriate result code. |
| 33391 | */ |
| 33392 | if( res ){ |
| 33393 | rc = SQLITE_OK; |
| 33394 | }else{ |
| 33395 | OSTRACE(("LOCK FAILED %d trying for %d but got %d\n", pFile->h, |
| 33396 | locktype, newLocktype)); |
| 33397 | pFile->lastErrno = lastErrno; |
| 33398 | rc = SQLITE_BUSY; |
| 33399 | } |
| 33400 | pFile->locktype = (u8)newLocktype; |
| 33401 | return rc; |
| 33402 | } |
| 33403 | |
| 33404 | /* |
| 33405 | ** This routine checks if there is a RESERVED lock held on the specified |
| @@ -33409,24 +33449,27 @@ | |
| 33409 | static int winCheckReservedLock(sqlite3_file *id, int *pResOut){ |
| 33410 | int rc; |
| 33411 | winFile *pFile = (winFile*)id; |
| 33412 | |
| 33413 | SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; ); |
| 33414 | |
| 33415 | assert( id!=0 ); |
| 33416 | if( pFile->locktype>=RESERVED_LOCK ){ |
| 33417 | rc = 1; |
| 33418 | OSTRACE(("TEST WR-LOCK %d %d (local)\n", pFile->h, rc)); |
| 33419 | }else{ |
| 33420 | rc = winLockFile(&pFile->h, SQLITE_LOCKFILEEX_FLAGS,RESERVED_BYTE, 0, 1, 0); |
| 33421 | if( rc ){ |
| 33422 | winUnlockFile(&pFile->h, RESERVED_BYTE, 0, 1, 0); |
| 33423 | } |
| 33424 | rc = !rc; |
| 33425 | OSTRACE(("TEST WR-LOCK %d %d (remote)\n", pFile->h, rc)); |
| 33426 | } |
| 33427 | *pResOut = rc; |
| 33428 | return SQLITE_OK; |
| 33429 | } |
| 33430 | |
| 33431 | /* |
| 33432 | ** Lower the locking level on file descriptor id to locktype. locktype |
| @@ -33443,12 +33486,12 @@ | |
| 33443 | int type; |
| 33444 | winFile *pFile = (winFile*)id; |
| 33445 | int rc = SQLITE_OK; |
| 33446 | assert( pFile!=0 ); |
| 33447 | assert( locktype<=SHARED_LOCK ); |
| 33448 | OSTRACE(("UNLOCK %d to %d was %d(%d)\n", pFile->h, locktype, |
| 33449 | pFile->locktype, pFile->sharedLockByte)); |
| 33450 | type = pFile->locktype; |
| 33451 | if( type>=EXCLUSIVE_LOCK ){ |
| 33452 | winUnlockFile(&pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0); |
| 33453 | if( locktype==SHARED_LOCK && !getReadLock(pFile) ){ |
| 33454 | /* This should never happen. We should always be able to |
| @@ -33465,10 +33508,12 @@ | |
| 33465 | } |
| 33466 | if( type>=PENDING_LOCK ){ |
| 33467 | winUnlockFile(&pFile->h, PENDING_BYTE, 0, 1, 0); |
| 33468 | } |
| 33469 | pFile->locktype = (u8)locktype; |
| 33470 | return rc; |
| 33471 | } |
| 33472 | |
| 33473 | /* |
| 33474 | ** If *pArg is inititially negative then this is a query. Set *pArg to |
| @@ -33492,21 +33537,25 @@ | |
| 33492 | /* |
| 33493 | ** Control and query of the open file handle. |
| 33494 | */ |
| 33495 | static int winFileControl(sqlite3_file *id, int op, void *pArg){ |
| 33496 | winFile *pFile = (winFile*)id; |
| 33497 | switch( op ){ |
| 33498 | case SQLITE_FCNTL_LOCKSTATE: { |
| 33499 | *(int*)pArg = pFile->locktype; |
| 33500 | return SQLITE_OK; |
| 33501 | } |
| 33502 | case SQLITE_LAST_ERRNO: { |
| 33503 | *(int*)pArg = (int)pFile->lastErrno; |
| 33504 | return SQLITE_OK; |
| 33505 | } |
| 33506 | case SQLITE_FCNTL_CHUNK_SIZE: { |
| 33507 | pFile->szChunk = *(int *)pArg; |
| 33508 | return SQLITE_OK; |
| 33509 | } |
| 33510 | case SQLITE_FCNTL_SIZE_HINT: { |
| 33511 | if( pFile->szChunk>0 ){ |
| 33512 | sqlite3_int64 oldSz; |
| @@ -33517,24 +33566,29 @@ | |
| 33517 | SimulateIOErrorBenign(1); |
| 33518 | rc = winTruncate(id, newSz); |
| 33519 | SimulateIOErrorBenign(0); |
| 33520 | } |
| 33521 | } |
| 33522 | return rc; |
| 33523 | } |
| 33524 | return SQLITE_OK; |
| 33525 | } |
| 33526 | case SQLITE_FCNTL_PERSIST_WAL: { |
| 33527 | winModeBit(pFile, WINFILE_PERSIST_WAL, (int*)pArg); |
| 33528 | return SQLITE_OK; |
| 33529 | } |
| 33530 | case SQLITE_FCNTL_POWERSAFE_OVERWRITE: { |
| 33531 | winModeBit(pFile, WINFILE_PSOW, (int*)pArg); |
| 33532 | return SQLITE_OK; |
| 33533 | } |
| 33534 | case SQLITE_FCNTL_VFSNAME: { |
| 33535 | *(char**)pArg = sqlite3_mprintf("win32"); |
| 33536 | return SQLITE_OK; |
| 33537 | } |
| 33538 | case SQLITE_FCNTL_WIN32_AV_RETRY: { |
| 33539 | int *a = (int*)pArg; |
| 33540 | if( a[0]>0 ){ |
| @@ -33545,18 +33599,20 @@ | |
| 33545 | if( a[1]>0 ){ |
| 33546 | win32IoerrRetryDelay = a[1]; |
| 33547 | }else{ |
| 33548 | a[1] = win32IoerrRetryDelay; |
| 33549 | } |
| 33550 | return SQLITE_OK; |
| 33551 | } |
| 33552 | case SQLITE_FCNTL_TEMPFILENAME: { |
| 33553 | char *zTFile = sqlite3MallocZero( pFile->pVfs->mxPathname ); |
| 33554 | if( zTFile ){ |
| 33555 | getTempname(pFile->pVfs->mxPathname, zTFile); |
| 33556 | *(char**)pArg = zTFile; |
| 33557 | } |
| 33558 | return SQLITE_OK; |
| 33559 | } |
| 33560 | #if SQLITE_MAX_MMAP_SIZE>0 |
| 33561 | case SQLITE_FCNTL_MMAP_SIZE: { |
| 33562 | i64 newLimit = *(i64*)pArg; |
| @@ -33563,14 +33619,16 @@ | |
| 33563 | if( newLimit>sqlite3GlobalConfig.mxMmap ){ |
| 33564 | newLimit = sqlite3GlobalConfig.mxMmap; |
| 33565 | } |
| 33566 | *(i64*)pArg = pFile->mmapSizeMax; |
| 33567 | if( newLimit>=0 ) pFile->mmapSizeMax = newLimit; |
| 33568 | return SQLITE_OK; |
| 33569 | } |
| 33570 | #endif |
| 33571 | } |
| 33572 | return SQLITE_NOTFOUND; |
| 33573 | } |
| 33574 | |
| 33575 | /* |
| 33576 | ** Return the sector size in bytes of the underlying block device for |
| @@ -33727,10 +33785,13 @@ | |
| 33727 | int rc = 0; /* Result code form Lock/UnlockFileEx() */ |
| 33728 | |
| 33729 | /* Access to the winShmNode object is serialized by the caller */ |
| 33730 | assert( sqlite3_mutex_held(pFile->mutex) || pFile->nRef==0 ); |
| 33731 | |
| 33732 | /* Release/Acquire the system-level lock */ |
| 33733 | if( lockType==_SHM_UNLCK ){ |
| 33734 | rc = winUnlockFile(&pFile->hFile.h, ofst, 0, nByte, 0); |
| 33735 | }else{ |
| 33736 | /* Initialize the locking parameters */ |
| @@ -33744,15 +33805,13 @@ | |
| 33744 | }else{ |
| 33745 | pFile->lastErrno = osGetLastError(); |
| 33746 | rc = SQLITE_BUSY; |
| 33747 | } |
| 33748 | |
| 33749 | OSTRACE(("SHM-LOCK %d %s %s 0x%08lx\n", |
| 33750 | pFile->hFile.h, |
| 33751 | rc==SQLITE_OK ? "ok" : "failed", |
| 33752 | lockType==_SHM_UNLCK ? "UnlockFileEx" : "LockFileEx", |
| 33753 | pFile->lastErrno)); |
| 33754 | |
| 33755 | return rc; |
| 33756 | } |
| 33757 | |
| 33758 | /* Forward references to VFS methods */ |
| @@ -33768,24 +33827,24 @@ | |
| 33768 | static void winShmPurge(sqlite3_vfs *pVfs, int deleteFlag){ |
| 33769 | winShmNode **pp; |
| 33770 | winShmNode *p; |
| 33771 | BOOL bRc; |
| 33772 | assert( winShmMutexHeld() ); |
| 33773 | pp = &winShmNodeList; |
| 33774 | while( (p = *pp)!=0 ){ |
| 33775 | if( p->nRef==0 ){ |
| 33776 | int i; |
| 33777 | if( p->mutex ) sqlite3_mutex_free(p->mutex); |
| 33778 | for(i=0; i<p->nRegion; i++){ |
| 33779 | bRc = osUnmapViewOfFile(p->aRegion[i].pMap); |
| 33780 | OSTRACE(("SHM-PURGE pid-%d unmap region=%d %s\n", |
| 33781 | (int)osGetCurrentProcessId(), i, |
| 33782 | bRc ? "ok" : "failed")); |
| 33783 | bRc = osCloseHandle(p->aRegion[i].hMap); |
| 33784 | OSTRACE(("SHM-PURGE pid-%d close region=%d %s\n", |
| 33785 | (int)osGetCurrentProcessId(), i, |
| 33786 | bRc ? "ok" : "failed")); |
| 33787 | } |
| 33788 | if( p->hFile.h!=NULL && p->hFile.h!=INVALID_HANDLE_VALUE ){ |
| 33789 | SimulateIOErrorBenign(1); |
| 33790 | winClose((sqlite3_file *)&p->hFile); |
| 33791 | SimulateIOErrorBenign(0); |
| @@ -34060,13 +34119,13 @@ | |
| 34060 | p->exclMask |= mask; |
| 34061 | } |
| 34062 | } |
| 34063 | } |
| 34064 | sqlite3_mutex_leave(pShmNode->mutex); |
| 34065 | OSTRACE(("SHM-LOCK shmid-%d, pid-%d got %03x,%03x %s\n", |
| 34066 | p->id, (int)osGetCurrentProcessId(), p->sharedMask, p->exclMask, |
| 34067 | rc ? "failed" : "ok")); |
| 34068 | return rc; |
| 34069 | } |
| 34070 | |
| 34071 | /* |
| 34072 | ** Implement a memory barrier or memory fence on shared memory. |
| @@ -34183,12 +34242,12 @@ | |
| 34183 | #elif defined(SQLITE_WIN32_HAS_ANSI) |
| 34184 | hMap = osCreateFileMappingA(pShmNode->hFile.h, |
| 34185 | NULL, PAGE_READWRITE, 0, nByte, NULL |
| 34186 | ); |
| 34187 | #endif |
| 34188 | OSTRACE(("SHM-MAP pid-%d create region=%d nbyte=%d %s\n", |
| 34189 | (int)osGetCurrentProcessId(), pShmNode->nRegion, nByte, |
| 34190 | hMap ? "ok" : "failed")); |
| 34191 | if( hMap ){ |
| 34192 | int iOffset = pShmNode->nRegion*szRegion; |
| 34193 | int iOffsetShift = iOffset % winSysInfo.dwAllocationGranularity; |
| 34194 | #if SQLITE_OS_WINRT |
| @@ -34198,12 +34257,12 @@ | |
| 34198 | #else |
| 34199 | pMap = osMapViewOfFile(hMap, FILE_MAP_WRITE | FILE_MAP_READ, |
| 34200 | 0, iOffset - iOffsetShift, szRegion + iOffsetShift |
| 34201 | ); |
| 34202 | #endif |
| 34203 | OSTRACE(("SHM-MAP pid-%d map region=%d offset=%d size=%d %s\n", |
| 34204 | (int)osGetCurrentProcessId(), pShmNode->nRegion, iOffset, |
| 34205 | szRegion, pMap ? "ok" : "failed")); |
| 34206 | } |
| 34207 | if( !pMap ){ |
| 34208 | pShmNode->lastErrno = osGetLastError(); |
| 34209 | rc = winLogError(SQLITE_IOERR_SHMMAP, pShmNode->lastErrno, |
| @@ -34242,13 +34301,20 @@ | |
| 34242 | ** Cleans up the mapped region of the specified file, if any. |
| 34243 | */ |
| 34244 | #if SQLITE_MAX_MMAP_SIZE>0 |
| 34245 | static int winUnmapfile(winFile *pFile){ |
| 34246 | assert( pFile!=0 ); |
| 34247 | if( pFile->pMapRegion ){ |
| 34248 | if( !osUnmapViewOfFile(pFile->pMapRegion) ){ |
| 34249 | pFile->lastErrno = osGetLastError(); |
| 34250 | return winLogError(SQLITE_IOERR_MMAP, pFile->lastErrno, |
| 34251 | "winUnmap1", pFile->zPath); |
| 34252 | } |
| 34253 | pFile->pMapRegion = 0; |
| 34254 | pFile->mmapSize = 0; |
| @@ -34255,15 +34321,19 @@ | |
| 34255 | pFile->mmapSizeActual = 0; |
| 34256 | } |
| 34257 | if( pFile->hMap!=NULL ){ |
| 34258 | if( !osCloseHandle(pFile->hMap) ){ |
| 34259 | pFile->lastErrno = osGetLastError(); |
| 34260 | return winLogError(SQLITE_IOERR_MMAP, pFile->lastErrno, |
| 34261 | "winUnmap2", pFile->zPath); |
| 34262 | } |
| 34263 | pFile->hMap = NULL; |
| 34264 | } |
| 34265 | return SQLITE_OK; |
| 34266 | } |
| 34267 | |
| 34268 | /* |
| 34269 | ** Memory map or remap the file opened by file-descriptor pFd (if the file |
| @@ -34284,15 +34354,20 @@ | |
| 34284 | static int winMapfile(winFile *pFd, sqlite3_int64 nByte){ |
| 34285 | sqlite3_int64 nMap = nByte; |
| 34286 | int rc; |
| 34287 | |
| 34288 | assert( nMap>=0 || pFd->nFetchOut==0 ); |
| 34289 | if( pFd->nFetchOut>0 ) return SQLITE_OK; |
| 34290 | |
| 34291 | if( nMap<0 ){ |
| 34292 | rc = winFileSize((sqlite3_file*)pFd, &nMap); |
| 34293 | if( rc ){ |
| 34294 | return SQLITE_IOERR_FSTAT; |
| 34295 | } |
| 34296 | } |
| 34297 | if( nMap>pFd->mmapSizeMax ){ |
| 34298 | nMap = pFd->mmapSizeMax; |
| @@ -34326,10 +34401,12 @@ | |
| 34326 | if( pFd->hMap==NULL ){ |
| 34327 | pFd->lastErrno = osGetLastError(); |
| 34328 | rc = winLogError(SQLITE_IOERR_MMAP, pFd->lastErrno, |
| 34329 | "winMapfile", pFd->zPath); |
| 34330 | /* Log the error, but continue normal operation using xRead/xWrite */ |
| 34331 | return SQLITE_OK; |
| 34332 | } |
| 34333 | assert( (nMap % winSysInfo.dwPageSize)==0 ); |
| 34334 | #if SQLITE_OS_WINRT |
| 34335 | pNew = osMapViewOfFileFromApp(pFd->hMap, flags, 0, nMap); |
| @@ -34341,17 +34418,21 @@ | |
| 34341 | osCloseHandle(pFd->hMap); |
| 34342 | pFd->hMap = NULL; |
| 34343 | pFd->lastErrno = osGetLastError(); |
| 34344 | winLogError(SQLITE_IOERR_MMAP, pFd->lastErrno, |
| 34345 | "winMapfile", pFd->zPath); |
| 34346 | return SQLITE_OK; |
| 34347 | } |
| 34348 | pFd->pMapRegion = pNew; |
| 34349 | pFd->mmapSize = nMap; |
| 34350 | pFd->mmapSizeActual = nMap; |
| 34351 | } |
| 34352 | |
| 34353 | return SQLITE_OK; |
| 34354 | } |
| 34355 | #endif /* SQLITE_MAX_MMAP_SIZE>0 */ |
| 34356 | |
| 34357 | /* |
| @@ -34362,38 +34443,48 @@ | |
| 34362 | ** Or, if one cannot but no error occurs, set *pp to 0 and return SQLITE_OK. |
| 34363 | ** Finally, if an error does occur, return an SQLite error code. The final |
| 34364 | ** value of *pp is undefined in this case. |
| 34365 | ** |
| 34366 | ** If this function does return a pointer, the caller must eventually |
| 34367 | ** release the reference by calling unixUnfetch(). |
| 34368 | */ |
| 34369 | static int winFetch(sqlite3_file *fd, i64 iOff, int nAmt, void **pp){ |
| 34370 | #if SQLITE_MAX_MMAP_SIZE>0 |
| 34371 | winFile *pFd = (winFile*)fd; /* The underlying database file */ |
| 34372 | #endif |
| 34373 | *pp = 0; |
| 34374 | |
| 34375 | #if SQLITE_MAX_MMAP_SIZE>0 |
| 34376 | if( pFd->mmapSizeMax>0 ){ |
| 34377 | if( pFd->pMapRegion==0 ){ |
| 34378 | int rc = winMapfile(pFd, -1); |
| 34379 | if( rc!=SQLITE_OK ) return rc; |
| 34380 | } |
| 34381 | if( pFd->mmapSize >= iOff+nAmt ){ |
| 34382 | *pp = &((u8 *)pFd->pMapRegion)[iOff]; |
| 34383 | pFd->nFetchOut++; |
| 34384 | } |
| 34385 | } |
| 34386 | #endif |
| 34387 | return SQLITE_OK; |
| 34388 | } |
| 34389 | |
| 34390 | /* |
| 34391 | ** If the third argument is non-NULL, then this function releases a |
| 34392 | ** reference obtained by an earlier call to unixFetch(). The second |
| 34393 | ** argument passed to this function must be the same as the corresponding |
| 34394 | ** argument that was passed to the unixFetch() invocation. |
| 34395 | ** |
| 34396 | ** Or, if the third argument is NULL, then this function is being called |
| 34397 | ** to inform the VFS layer that, according to POSIX, any existing mapping |
| 34398 | ** may now be invalid and should be unmapped. |
| 34399 | */ |
| @@ -34407,10 +34498,13 @@ | |
| 34407 | assert( (p==0)==(pFd->nFetchOut==0) ); |
| 34408 | |
| 34409 | /* If p!=0, it must match the iOff value. */ |
| 34410 | assert( p==0 || p==&((u8 *)pFd->pMapRegion)[iOff] ); |
| 34411 | |
| 34412 | if( p ){ |
| 34413 | pFd->nFetchOut--; |
| 34414 | }else{ |
| 34415 | /* FIXME: If Windows truly always prevents truncating or deleting a |
| 34416 | ** file while a mapping is held, then the following winUnmapfile() call |
| @@ -34419,10 +34513,13 @@ | |
| 34419 | winUnmapfile(pFd); |
| 34420 | } |
| 34421 | |
| 34422 | assert( pFd->nFetchOut>=0 ); |
| 34423 | #endif |
| 34424 | return SQLITE_OK; |
| 34425 | } |
| 34426 | |
| 34427 | /* |
| 34428 | ** Here ends the implementation of all sqlite3_file methods. |
| @@ -34515,10 +34612,11 @@ | |
| 34515 | zMulti = unicodeToUtf8(zWidePath); |
| 34516 | if( zMulti ){ |
| 34517 | sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", zMulti); |
| 34518 | sqlite3_free(zMulti); |
| 34519 | }else{ |
| 34520 | return SQLITE_IOERR_NOMEM; |
| 34521 | } |
| 34522 | } |
| 34523 | #ifdef SQLITE_WIN32_HAS_ANSI |
| 34524 | else{ |
| @@ -34528,10 +34626,11 @@ | |
| 34528 | zUtf8 = sqlite3_win32_mbcs_to_utf8(zMbcsPath); |
| 34529 | if( zUtf8 ){ |
| 34530 | sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", zUtf8); |
| 34531 | sqlite3_free(zUtf8); |
| 34532 | }else{ |
| 34533 | return SQLITE_IOERR_NOMEM; |
| 34534 | } |
| 34535 | } |
| 34536 | #endif |
| 34537 | #endif |
| @@ -34540,10 +34639,11 @@ | |
| 34540 | ** name. If it is not, return SQLITE_ERROR. |
| 34541 | */ |
| 34542 | nTempPath = sqlite3Strlen30(zTempPath); |
| 34543 | |
| 34544 | if( (nTempPath + sqlite3Strlen30(SQLITE_TEMP_FILE_PREFIX) + 18) >= nBuf ){ |
| 34545 | return SQLITE_ERROR; |
| 34546 | } |
| 34547 | |
| 34548 | for(i=nTempPath; i>0 && zTempPath[i-1]=='\\'; i--){} |
| 34549 | zTempPath[i] = 0; |
| @@ -34557,12 +34657,12 @@ | |
| 34557 | zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ]; |
| 34558 | } |
| 34559 | zBuf[j] = 0; |
| 34560 | zBuf[j+1] = 0; |
| 34561 | |
| 34562 | OSTRACE(("TEMP FILENAME: %s\n", zBuf)); |
| 34563 | return SQLITE_OK; |
| 34564 | } |
| 34565 | |
| 34566 | /* |
| 34567 | ** Return TRUE if the named file is really a directory. Return false if |
| 34568 | ** it is something other than a directory, or if there is any kind of memory |
| @@ -34637,10 +34737,13 @@ | |
| 34637 | eType==SQLITE_OPEN_MASTER_JOURNAL |
| 34638 | || eType==SQLITE_OPEN_MAIN_JOURNAL |
| 34639 | || eType==SQLITE_OPEN_WAL |
| 34640 | )); |
| 34641 | #endif |
| 34642 | |
| 34643 | /* Check the following statements are true: |
| 34644 | ** |
| 34645 | ** (a) Exactly one of the READWRITE and READONLY flags must be set, and |
| 34646 | ** (b) if CREATE is set, then READWRITE must also be set, and |
| @@ -34683,10 +34786,11 @@ | |
| 34683 | if( !zUtf8Name ){ |
| 34684 | assert(isDelete && !isOpenJournal); |
| 34685 | memset(zTmpname, 0, MAX_PATH+2); |
| 34686 | rc = getTempname(MAX_PATH+2, zTmpname); |
| 34687 | if( rc!=SQLITE_OK ){ |
| 34688 | return rc; |
| 34689 | } |
| 34690 | zUtf8Name = zTmpname; |
| 34691 | } |
| 34692 | |
| @@ -34698,15 +34802,17 @@ | |
| 34698 | zUtf8Name[strlen(zUtf8Name)+1]==0 ); |
| 34699 | |
| 34700 | /* Convert the filename to the system encoding. */ |
| 34701 | zConverted = convertUtf8Filename(zUtf8Name); |
| 34702 | if( zConverted==0 ){ |
| 34703 | return SQLITE_IOERR_NOMEM; |
| 34704 | } |
| 34705 | |
| 34706 | if( winIsDir(zConverted) ){ |
| 34707 | sqlite3_free(zConverted); |
| 34708 | return SQLITE_CANTOPEN_ISDIR; |
| 34709 | } |
| 34710 | |
| 34711 | if( isReadWrite ){ |
| 34712 | dwDesiredAccess = GENERIC_READ | GENERIC_WRITE; |
| @@ -34793,13 +34899,12 @@ | |
| 34793 | } |
| 34794 | } |
| 34795 | #endif |
| 34796 | logIoerr(cnt); |
| 34797 | |
| 34798 | OSTRACE(("OPEN %d %s 0x%lx %s\n", |
| 34799 | h, zName, dwDesiredAccess, |
| 34800 | h==INVALID_HANDLE_VALUE ? "failed" : "ok")); |
| 34801 | |
| 34802 | if( h==INVALID_HANDLE_VALUE ){ |
| 34803 | pFile->lastErrno = lastErrno; |
| 34804 | winLogError(SQLITE_CANTOPEN, pFile->lastErrno, "winOpen", zUtf8Name); |
| 34805 | sqlite3_free(zConverted); |
| @@ -34819,16 +34924,21 @@ | |
| 34819 | }else{ |
| 34820 | *pOutFlags = SQLITE_OPEN_READONLY; |
| 34821 | } |
| 34822 | } |
| 34823 | |
| 34824 | #if SQLITE_OS_WINCE |
| 34825 | if( isReadWrite && eType==SQLITE_OPEN_MAIN_DB |
| 34826 | && (rc = winceCreateLock(zName, pFile))!=SQLITE_OK |
| 34827 | ){ |
| 34828 | osCloseHandle(h); |
| 34829 | sqlite3_free(zConverted); |
| 34830 | return rc; |
| 34831 | } |
| 34832 | if( isTemp ){ |
| 34833 | pFile->zDeleteOnClose = zConverted; |
| 34834 | }else |
| @@ -34884,10 +34994,12 @@ | |
| 34884 | void *zConverted; |
| 34885 | UNUSED_PARAMETER(pVfs); |
| 34886 | UNUSED_PARAMETER(syncDir); |
| 34887 | |
| 34888 | SimulateIOError(return SQLITE_IOERR_DELETE); |
| 34889 | zConverted = convertUtf8Filename(zFilename); |
| 34890 | if( zConverted==0 ){ |
| 34891 | return SQLITE_IOERR_NOMEM; |
| 34892 | } |
| 34893 | if( isNT() ){ |
| @@ -34969,11 +35081,11 @@ | |
| 34969 | "winDelete", zFilename); |
| 34970 | }else{ |
| 34971 | logIoerr(cnt); |
| 34972 | } |
| 34973 | sqlite3_free(zConverted); |
| 34974 | OSTRACE(("DELETE \"%s\" %s\n", zFilename, (rc ? "failed" : "ok" ))); |
| 34975 | return rc; |
| 34976 | } |
| 34977 | |
| 34978 | /* |
| 34979 | ** Check the existence and status of a file. |
| @@ -34989,12 +35101,16 @@ | |
| 34989 | DWORD lastErrno; |
| 34990 | void *zConverted; |
| 34991 | UNUSED_PARAMETER(pVfs); |
| 34992 | |
| 34993 | SimulateIOError( return SQLITE_IOERR_ACCESS; ); |
| 34994 | zConverted = convertUtf8Filename(zFilename); |
| 34995 | if( zConverted==0 ){ |
| 34996 | return SQLITE_IOERR_NOMEM; |
| 34997 | } |
| 34998 | if( isNT() ){ |
| 34999 | int cnt = 0; |
| 35000 | WIN32_FILE_ATTRIBUTE_DATA sAttrData; |
| @@ -35041,10 +35157,12 @@ | |
| 35041 | break; |
| 35042 | default: |
| 35043 | assert(!"Invalid flags argument"); |
| 35044 | } |
| 35045 | *pResOut = rc; |
| 35046 | return SQLITE_OK; |
| 35047 | } |
| 35048 | |
| 35049 | |
| 35050 | /* |
| @@ -51943,10 +52061,33 @@ | |
| 51943 | releasePage(pPage1); |
| 51944 | pBt->pPage1 = 0; |
| 51945 | return rc; |
| 51946 | } |
| 51947 | |
| 51948 | /* |
| 51949 | ** If there are no outstanding cursors and we are not in the middle |
| 51950 | ** of a transaction but there is a read lock on the database, then |
| 51951 | ** this routine unrefs the first page of the database file which |
| 51952 | ** has the effect of releasing the read lock. |
| @@ -51953,11 +52094,11 @@ | |
| 51953 | ** |
| 51954 | ** If there is a transaction in progress, this routine is a no-op. |
| 51955 | */ |
| 51956 | static void unlockBtreeIfUnused(BtShared *pBt){ |
| 51957 | assert( sqlite3_mutex_held(pBt->mutex) ); |
| 51958 | assert( pBt->pCursor==0 || pBt->inTransaction>TRANS_NONE ); |
| 51959 | if( pBt->inTransaction==TRANS_NONE && pBt->pPage1!=0 ){ |
| 51960 | assert( pBt->pPage1->aData ); |
| 51961 | assert( sqlite3PagerRefcount(pBt->pPager)==1 ); |
| 51962 | assert( pBt->pPage1->aData ); |
| 51963 | releasePage(pBt->pPage1); |
| @@ -52681,11 +52822,10 @@ | |
| 52681 | assert( sqlite3BtreeHoldsMutex(p) ); |
| 52682 | |
| 52683 | #ifndef SQLITE_OMIT_AUTOVACUUM |
| 52684 | pBt->bDoTruncate = 0; |
| 52685 | #endif |
| 52686 | btreeClearHasContent(pBt); |
| 52687 | if( p->inTrans>TRANS_NONE && p->db->activeVdbeCnt>1 ){ |
| 52688 | /* If there are other active statements that belong to this database |
| 52689 | ** handle, downgrade to a read-only transaction. The other statements |
| 52690 | ** may still be reading from the database. */ |
| 52691 | downgradeAllSharedCacheTableLocks(p); |
| @@ -52756,10 +52896,11 @@ | |
| 52756 | if( rc!=SQLITE_OK && bCleanup==0 ){ |
| 52757 | sqlite3BtreeLeave(p); |
| 52758 | return rc; |
| 52759 | } |
| 52760 | pBt->inTransaction = TRANS_READ; |
| 52761 | } |
| 52762 | |
| 52763 | btreeEndTransaction(p); |
| 52764 | sqlite3BtreeLeave(p); |
| 52765 | return SQLITE_OK; |
| @@ -52777,31 +52918,10 @@ | |
| 52777 | } |
| 52778 | sqlite3BtreeLeave(p); |
| 52779 | return rc; |
| 52780 | } |
| 52781 | |
| 52782 | #ifndef NDEBUG |
| 52783 | /* |
| 52784 | ** Return the number of write-cursors open on this handle. This is for use |
| 52785 | ** in assert() expressions, so it is only compiled if NDEBUG is not |
| 52786 | ** defined. |
| 52787 | ** |
| 52788 | ** For the purposes of this routine, a write-cursor is any cursor that |
| 52789 | ** is capable of writing to the databse. That means the cursor was |
| 52790 | ** originally opened for writing and the cursor has not be disabled |
| 52791 | ** by having its state changed to CURSOR_FAULT. |
| 52792 | */ |
| 52793 | static int countWriteCursors(BtShared *pBt){ |
| 52794 | BtCursor *pCur; |
| 52795 | int r = 0; |
| 52796 | for(pCur=pBt->pCursor; pCur; pCur=pCur->pNext){ |
| 52797 | if( pCur->wrFlag && pCur->eState!=CURSOR_FAULT ) r++; |
| 52798 | } |
| 52799 | return r; |
| 52800 | } |
| 52801 | #endif |
| 52802 | |
| 52803 | /* |
| 52804 | ** This routine sets the state to CURSOR_FAULT and the error |
| 52805 | ** code to errCode for every cursor on BtShared that pBtree |
| 52806 | ** references. |
| 52807 | ** |
| @@ -52877,12 +52997,13 @@ | |
| 52877 | if( nPage==0 ) sqlite3PagerPagecount(pBt->pPager, &nPage); |
| 52878 | testcase( pBt->nPage!=nPage ); |
| 52879 | pBt->nPage = nPage; |
| 52880 | releasePage(pPage1); |
| 52881 | } |
| 52882 | assert( countWriteCursors(pBt)==0 ); |
| 52883 | pBt->inTransaction = TRANS_READ; |
| 52884 | } |
| 52885 | |
| 52886 | btreeEndTransaction(p); |
| 52887 | sqlite3BtreeLeave(p); |
| 52888 | return rc; |
| @@ -75216,16 +75337,11 @@ | |
| 75216 | p = p->pLeft; |
| 75217 | continue; |
| 75218 | } |
| 75219 | assert( op!=TK_REGISTER || p->op2!=TK_COLLATE ); |
| 75220 | if( op==TK_COLLATE ){ |
| 75221 | if( db->init.busy ){ |
| 75222 | /* Do not report errors when parsing while the schema */ |
| 75223 | pColl = sqlite3FindCollSeq(db, ENC(db), p->u.zToken, 0); |
| 75224 | }else{ |
| 75225 | pColl = sqlite3GetCollSeq(pParse, ENC(db), 0, p->u.zToken); |
| 75226 | } |
| 75227 | break; |
| 75228 | } |
| 75229 | if( p->pTab!=0 |
| 75230 | && (op==TK_AGG_COLUMN || op==TK_COLUMN |
| 75231 | || op==TK_REGISTER || op==TK_TRIGGER) |
| @@ -84722,14 +84838,12 @@ | |
| 84722 | ** specified collation sequence names. |
| 84723 | */ |
| 84724 | for(i=0; i<pList->nExpr; i++){ |
| 84725 | Expr *pExpr = pList->a[i].pExpr; |
| 84726 | if( pExpr ){ |
| 84727 | CollSeq *pColl = sqlite3ExprCollSeq(pParse, pExpr); |
| 84728 | if( pColl ){ |
| 84729 | nExtra += (1 + sqlite3Strlen30(pColl->zName)); |
| 84730 | } |
| 84731 | } |
| 84732 | } |
| 84733 | |
| 84734 | /* |
| 84735 | ** Allocate the index structure. |
| @@ -84786,11 +84900,10 @@ | |
| 84786 | */ |
| 84787 | for(i=0, pListItem=pList->a; i<pList->nExpr; i++, pListItem++){ |
| 84788 | const char *zColName = pListItem->zName; |
| 84789 | Column *pTabCol; |
| 84790 | int requestedSortOrder; |
| 84791 | CollSeq *pColl; /* Collating sequence */ |
| 84792 | char *zColl; /* Collation sequence name */ |
| 84793 | |
| 84794 | for(j=0, pTabCol=pTab->aCol; j<pTab->nCol; j++, pTabCol++){ |
| 84795 | if( sqlite3StrICmp(zColName, pTabCol->zName)==0 ) break; |
| 84796 | } |
| @@ -84799,26 +84912,23 @@ | |
| 84799 | pTab->zName, zColName); |
| 84800 | pParse->checkSchema = 1; |
| 84801 | goto exit_create_index; |
| 84802 | } |
| 84803 | pIndex->aiColumn[i] = j; |
| 84804 | if( pListItem->pExpr |
| 84805 | && (pColl = sqlite3ExprCollSeq(pParse, pListItem->pExpr))!=0 |
| 84806 | ){ |
| 84807 | int nColl; |
| 84808 | zColl = pColl->zName; |
| 84809 | nColl = sqlite3Strlen30(zColl) + 1; |
| 84810 | assert( nExtra>=nColl ); |
| 84811 | memcpy(zExtra, zColl, nColl); |
| 84812 | zColl = zExtra; |
| 84813 | zExtra += nColl; |
| 84814 | nExtra -= nColl; |
| 84815 | }else{ |
| 84816 | zColl = pTab->aCol[j].zColl; |
| 84817 | if( !zColl ){ |
| 84818 | zColl = "BINARY"; |
| 84819 | } |
| 84820 | } |
| 84821 | if( !db->init.busy && !sqlite3LocateCollSeq(pParse, zColl) ){ |
| 84822 | goto exit_create_index; |
| 84823 | } |
| 84824 | pIndex->azColl[i] = zColl; |
| @@ -108986,10 +109096,14 @@ | |
| 108986 | ** |
| 108987 | ** Actually, each subexpression is converted to "xN AND w" where w is |
| 108988 | ** the "interesting" terms of z - terms that did not originate in the |
| 108989 | ** ON or USING clause of a LEFT JOIN, and terms that are usable as |
| 108990 | ** indices. |
| 108991 | */ |
| 108992 | if( pWC->nTerm>1 ){ |
| 108993 | int iTerm; |
| 108994 | for(iTerm=0; iTerm<pWC->nTerm; iTerm++){ |
| 108995 | Expr *pExpr = pWC->a[iTerm].pExpr; |
| @@ -109007,11 +109121,11 @@ | |
| 109007 | for(ii=0; ii<pOrWc->nTerm; ii++){ |
| 109008 | WhereTerm *pOrTerm = &pOrWc->a[ii]; |
| 109009 | if( pOrTerm->leftCursor==iCur || (pOrTerm->eOperator & WO_AND)!=0 ){ |
| 109010 | WhereInfo *pSubWInfo; /* Info for single OR-term scan */ |
| 109011 | Expr *pOrExpr = pOrTerm->pExpr; |
| 109012 | if( pAndExpr ){ |
| 109013 | pAndExpr->pLeft = pOrExpr; |
| 109014 | pOrExpr = pAndExpr; |
| 109015 | } |
| 109016 | /* Loop through table entries that match term pOrTerm. */ |
| 109017 | pSubWInfo = sqlite3WhereBegin(pParse, pOrTab, pOrExpr, 0, 0, |
| @@ -115513,10 +115627,16 @@ | |
| 115513 | "statements or unfinished backups"); |
| 115514 | sqlite3_mutex_leave(db->mutex); |
| 115515 | return SQLITE_BUSY; |
| 115516 | } |
| 115517 | |
| 115518 | #ifdef SQLITE_ENABLE_SQLLOG |
| 115519 | if( sqlite3GlobalConfig.xSqllog ){ |
| 115520 | /* Closing the handle. Fourth parameter is passed the value 2. */ |
| 115521 | sqlite3GlobalConfig.xSqllog(sqlite3GlobalConfig.pSqllogArg, db, 0, 2); |
| 115522 | } |
| @@ -115667,10 +115787,11 @@ | |
| 115667 | SQLITE_PRIVATE void sqlite3RollbackAll(sqlite3 *db, int tripCode){ |
| 115668 | int i; |
| 115669 | int inTrans = 0; |
| 115670 | assert( sqlite3_mutex_held(db->mutex) ); |
| 115671 | sqlite3BeginBenignMalloc(); |
| 115672 | for(i=0; i<db->nDb; i++){ |
| 115673 | Btree *p = db->aDb[i].pBt; |
| 115674 | if( p ){ |
| 115675 | if( sqlite3BtreeIsInTrans(p) ){ |
| 115676 | inTrans = 1; |
| @@ -115684,10 +115805,11 @@ | |
| 115684 | |
| 115685 | if( (db->flags&SQLITE_InternChanges)!=0 && db->init.busy==0 ){ |
| 115686 | sqlite3ExpirePreparedStatements(db); |
| 115687 | sqlite3ResetAllSchemasOfConnection(db); |
| 115688 | } |
| 115689 | |
| 115690 | /* Any deferred constraint violations have now been resolved. */ |
| 115691 | db->nDeferredCons = 0; |
| 115692 | |
| 115693 | /* If one has been configured, invoke the rollback-hook callback */ |
| @@ -115694,10 +115816,114 @@ | |
| 115694 | if( db->xRollbackCallback && (inTrans || !db->autoCommit) ){ |
| 115695 | db->xRollbackCallback(db->pRollbackArg); |
| 115696 | } |
| 115697 | } |
| 115698 | |
| 115699 | /* |
| 115700 | ** Return a static string that describes the kind of error specified in the |
| 115701 | ** argument. |
| 115702 | */ |
| 115703 | SQLITE_PRIVATE const char *sqlite3ErrStr(int rc){ |
| 115704 |
| --- src/sqlite3.c | |
| +++ src/sqlite3.c | |
| @@ -678,11 +678,11 @@ | |
| 678 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 679 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 680 | */ |
| 681 | #define SQLITE_VERSION "3.7.17" |
| 682 | #define SQLITE_VERSION_NUMBER 3007017 |
| 683 | #define SQLITE_SOURCE_ID "2013-05-15 18:34:17 00231fb0127960d700de3549e34e82f8ec1b5819" |
| 684 | |
| 685 | /* |
| 686 | ** CAPI3REF: Run-Time Library Version Numbers |
| 687 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 688 | ** |
| @@ -12251,10 +12251,16 @@ | |
| 12251 | SQLITE_PRIVATE int sqlite3Atoi64(const char*, i64*, int, u8); |
| 12252 | SQLITE_PRIVATE void sqlite3Error(sqlite3*, int, const char*,...); |
| 12253 | SQLITE_PRIVATE void *sqlite3HexToBlob(sqlite3*, const char *z, int n); |
| 12254 | SQLITE_PRIVATE u8 sqlite3HexToInt(int h); |
| 12255 | SQLITE_PRIVATE int sqlite3TwoPartName(Parse *, Token *, Token *, Token **); |
| 12256 | |
| 12257 | #if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) || \ |
| 12258 | defined(SQLITE_DEBUG_OS_TRACE) |
| 12259 | SQLITE_PRIVATE const char *sqlite3ErrName(int); |
| 12260 | #endif |
| 12261 | |
| 12262 | SQLITE_PRIVATE const char *sqlite3ErrStr(int); |
| 12263 | SQLITE_PRIVATE int sqlite3ReadSchema(Parse *pParse); |
| 12264 | SQLITE_PRIVATE CollSeq *sqlite3FindCollSeq(sqlite3*,u8 enc, const char*,int); |
| 12265 | SQLITE_PRIVATE CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char*zName); |
| 12266 | SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr); |
| @@ -26237,10 +26243,12 @@ | |
| 26243 | sqlite3_int64 offset |
| 26244 | ){ |
| 26245 | unixFile *pFile = (unixFile *)id; |
| 26246 | int got; |
| 26247 | assert( id ); |
| 26248 | assert( offset>=0 ); |
| 26249 | assert( amt>0 ); |
| 26250 | |
| 26251 | /* If this is a database file (not a journal, master-journal or temp |
| 26252 | ** file), the bytes in the locking range should never be read or written. */ |
| 26253 | #if 0 |
| 26254 | assert( pFile->pUnused==0 |
| @@ -32230,11 +32238,11 @@ | |
| 32238 | osLocalFree(zTemp); |
| 32239 | } |
| 32240 | } |
| 32241 | #endif |
| 32242 | if( 0 == dwLen ){ |
| 32243 | sqlite3_snprintf(nBuf, zBuf, "OsError 0x%lx (%lu)", lastErrno, lastErrno); |
| 32244 | }else{ |
| 32245 | /* copy a maximum of nBuf chars to output buffer */ |
| 32246 | sqlite3_snprintf(nBuf, zBuf, "%s", zOut); |
| 32247 | /* free the UTF8 buffer */ |
| 32248 | sqlite3_free(zOut); |
| @@ -32273,11 +32281,11 @@ | |
| 32281 | assert( errcode!=SQLITE_OK ); |
| 32282 | if( zPath==0 ) zPath = ""; |
| 32283 | for(i=0; zMsg[i] && zMsg[i]!='\r' && zMsg[i]!='\n'; i++){} |
| 32284 | zMsg[i] = 0; |
| 32285 | sqlite3_log(errcode, |
| 32286 | "os_win.c:%d: (%lu) %s(%s) - %s", |
| 32287 | iLine, lastErrno, zFunc, zPath, zMsg |
| 32288 | ); |
| 32289 | |
| 32290 | return errcode; |
| 32291 | } |
| @@ -32734,10 +32742,12 @@ | |
| 32742 | LONG upperBits; /* Most sig. 32 bits of new offset */ |
| 32743 | LONG lowerBits; /* Least sig. 32 bits of new offset */ |
| 32744 | DWORD dwRet; /* Value returned by SetFilePointer() */ |
| 32745 | DWORD lastErrno; /* Value returned by GetLastError() */ |
| 32746 | |
| 32747 | OSTRACE(("SEEK file=%p, offset=%lld\n", pFile->h, iOffset)); |
| 32748 | |
| 32749 | upperBits = (LONG)((iOffset>>32) & 0x7fffffff); |
| 32750 | lowerBits = (LONG)(iOffset & 0xffffffff); |
| 32751 | |
| 32752 | /* API oddity: If successful, SetFilePointer() returns a dword |
| 32753 | ** containing the lower 32-bits of the new file-offset. Or, if it fails, |
| @@ -32751,13 +32761,15 @@ | |
| 32761 | if( (dwRet==INVALID_SET_FILE_POINTER |
| 32762 | && ((lastErrno = osGetLastError())!=NO_ERROR)) ){ |
| 32763 | pFile->lastErrno = lastErrno; |
| 32764 | winLogError(SQLITE_IOERR_SEEK, pFile->lastErrno, |
| 32765 | "seekWinFile", pFile->zPath); |
| 32766 | OSTRACE(("SEEK file=%p, rc=SQLITE_IOERR_SEEK\n", pFile->h)); |
| 32767 | return 1; |
| 32768 | } |
| 32769 | |
| 32770 | OSTRACE(("SEEK file=%p, rc=SQLITE_OK\n", pFile->h)); |
| 32771 | return 0; |
| 32772 | #else |
| 32773 | /* |
| 32774 | ** Same as above, except that this implementation works for WinRT. |
| 32775 | */ |
| @@ -32770,13 +32782,15 @@ | |
| 32782 | |
| 32783 | if(!bRet){ |
| 32784 | pFile->lastErrno = osGetLastError(); |
| 32785 | winLogError(SQLITE_IOERR_SEEK, pFile->lastErrno, |
| 32786 | "seekWinFile", pFile->zPath); |
| 32787 | OSTRACE(("SEEK file=%p, rc=SQLITE_IOERR_SEEK\n", pFile->h)); |
| 32788 | return 1; |
| 32789 | } |
| 32790 | |
| 32791 | OSTRACE(("SEEK file=%p, rc=SQLITE_OK\n", pFile->h)); |
| 32792 | return 0; |
| 32793 | #endif |
| 32794 | } |
| 32795 | |
| 32796 | #if SQLITE_MAX_MMAP_SIZE>0 |
| @@ -32801,12 +32815,12 @@ | |
| 32815 | |
| 32816 | assert( id!=0 ); |
| 32817 | #ifndef SQLITE_OMIT_WAL |
| 32818 | assert( pFile->pShm==0 ); |
| 32819 | #endif |
| 32820 | assert( pFile->h!=NULL && pFile->h!=INVALID_HANDLE_VALUE ); |
| 32821 | OSTRACE(("CLOSE file=%p\n", pFile->h)); |
| 32822 | |
| 32823 | #if SQLITE_MAX_MMAP_SIZE>0 |
| 32824 | rc = winUnmapfile(pFile); |
| 32825 | if( rc!=SQLITE_OK ) return rc; |
| 32826 | #endif |
| @@ -32828,15 +32842,15 @@ | |
| 32842 | sqlite3_win32_sleep(100); /* Wait a little before trying again */ |
| 32843 | } |
| 32844 | sqlite3_free(pFile->zDeleteOnClose); |
| 32845 | } |
| 32846 | #endif |
| 32847 | if( rc ){ |
| 32848 | pFile->h = NULL; |
| 32849 | } |
| 32850 | OpenCounter(-1); |
| 32851 | OSTRACE(("CLOSE file=%p, rc=%s\n", pFile->h, rc ? "ok" : "failed")); |
| 32852 | return rc ? SQLITE_OK |
| 32853 | : winLogError(SQLITE_IOERR_CLOSE, osGetLastError(), |
| 32854 | "winClose", pFile->zPath); |
| 32855 | } |
| 32856 | |
| @@ -32858,19 +32872,22 @@ | |
| 32872 | DWORD nRead; /* Number of bytes actually read from file */ |
| 32873 | int nRetry = 0; /* Number of retrys */ |
| 32874 | |
| 32875 | assert( id!=0 ); |
| 32876 | assert( amt>0 ); |
| 32877 | assert( offset>=0 ); |
| 32878 | SimulateIOError(return SQLITE_IOERR_READ); |
| 32879 | OSTRACE(("READ file=%p, buffer=%p, amount=%d, offset=%lld, lock=%d\n", |
| 32880 | pFile->h, pBuf, amt, offset, pFile->locktype)); |
| 32881 | |
| 32882 | #if SQLITE_MAX_MMAP_SIZE>0 |
| 32883 | /* Deal with as much of this read request as possible by transfering |
| 32884 | ** data from the memory mapping using memcpy(). */ |
| 32885 | if( offset<pFile->mmapSize ){ |
| 32886 | if( offset+amt <= pFile->mmapSize ){ |
| 32887 | memcpy(pBuf, &((u8 *)(pFile->pMapRegion))[offset], amt); |
| 32888 | OSTRACE(("READ-MMAP file=%p, rc=SQLITE_OK\n", pFile->h)); |
| 32889 | return SQLITE_OK; |
| 32890 | }else{ |
| 32891 | int nCopy = (int)(pFile->mmapSize - offset); |
| 32892 | memcpy(pBuf, &((u8 *)(pFile->pMapRegion))[offset], nCopy); |
| 32893 | pBuf = &((u8 *)pBuf)[nCopy]; |
| @@ -32880,10 +32897,11 @@ | |
| 32897 | } |
| 32898 | #endif |
| 32899 | |
| 32900 | #if SQLITE_OS_WINCE |
| 32901 | if( seekWinFile(pFile, offset) ){ |
| 32902 | OSTRACE(("READ file=%p, rc=SQLITE_FULL\n", pFile->h)); |
| 32903 | return SQLITE_FULL; |
| 32904 | } |
| 32905 | while( !osReadFile(pFile->h, pBuf, amt, &nRead, 0) ){ |
| 32906 | #else |
| 32907 | memset(&overlapped, 0, sizeof(OVERLAPPED)); |
| @@ -32893,20 +32911,23 @@ | |
| 32911 | osGetLastError()!=ERROR_HANDLE_EOF ){ |
| 32912 | #endif |
| 32913 | DWORD lastErrno; |
| 32914 | if( retryIoerr(&nRetry, &lastErrno) ) continue; |
| 32915 | pFile->lastErrno = lastErrno; |
| 32916 | OSTRACE(("READ file=%p, rc=SQLITE_IOERR_READ\n", pFile->h)); |
| 32917 | return winLogError(SQLITE_IOERR_READ, pFile->lastErrno, |
| 32918 | "winRead", pFile->zPath); |
| 32919 | } |
| 32920 | logIoerr(nRetry); |
| 32921 | if( nRead<(DWORD)amt ){ |
| 32922 | /* Unread parts of the buffer must be zero-filled */ |
| 32923 | memset(&((char*)pBuf)[nRead], 0, amt-nRead); |
| 32924 | OSTRACE(("READ file=%p, rc=SQLITE_IOERR_SHORT_READ\n", pFile->h)); |
| 32925 | return SQLITE_IOERR_SHORT_READ; |
| 32926 | } |
| 32927 | |
| 32928 | OSTRACE(("READ file=%p, rc=SQLITE_OK\n", pFile->h)); |
| 32929 | return SQLITE_OK; |
| 32930 | } |
| 32931 | |
| 32932 | /* |
| 32933 | ** Write data from a buffer into a file. Return SQLITE_OK on success |
| @@ -32925,18 +32946,20 @@ | |
| 32946 | assert( amt>0 ); |
| 32947 | assert( pFile ); |
| 32948 | SimulateIOError(return SQLITE_IOERR_WRITE); |
| 32949 | SimulateDiskfullError(return SQLITE_FULL); |
| 32950 | |
| 32951 | OSTRACE(("WRITE file=%p, buffer=%p, amount=%d, offset=%lld, lock=%d\n", |
| 32952 | pFile->h, pBuf, amt, offset, pFile->locktype)); |
| 32953 | |
| 32954 | #if SQLITE_MAX_MMAP_SIZE>0 |
| 32955 | /* Deal with as much of this write request as possible by transfering |
| 32956 | ** data from the memory mapping using memcpy(). */ |
| 32957 | if( offset<pFile->mmapSize ){ |
| 32958 | if( offset+amt <= pFile->mmapSize ){ |
| 32959 | memcpy(&((u8 *)(pFile->pMapRegion))[offset], pBuf, amt); |
| 32960 | OSTRACE(("WRITE-MMAP file=%p, rc=SQLITE_OK\n", pFile->h)); |
| 32961 | return SQLITE_OK; |
| 32962 | }else{ |
| 32963 | int nCopy = (int)(pFile->mmapSize - offset); |
| 32964 | memcpy(&((u8 *)(pFile->pMapRegion))[offset], pBuf, nCopy); |
| 32965 | pBuf = &((u8 *)pBuf)[nCopy]; |
| @@ -32995,17 +33018,20 @@ | |
| 33018 | } |
| 33019 | |
| 33020 | if( rc ){ |
| 33021 | if( ( pFile->lastErrno==ERROR_HANDLE_DISK_FULL ) |
| 33022 | || ( pFile->lastErrno==ERROR_DISK_FULL )){ |
| 33023 | OSTRACE(("WRITE file=%p, rc=SQLITE_FULL\n", pFile->h)); |
| 33024 | return SQLITE_FULL; |
| 33025 | } |
| 33026 | OSTRACE(("WRITE file=%p, rc=SQLITE_IOERR_WRITE\n", pFile->h)); |
| 33027 | return winLogError(SQLITE_IOERR_WRITE, pFile->lastErrno, |
| 33028 | "winWrite", pFile->zPath); |
| 33029 | }else{ |
| 33030 | logIoerr(nRetry); |
| 33031 | } |
| 33032 | OSTRACE(("WRITE file=%p, rc=SQLITE_OK\n", pFile->h)); |
| 33033 | return SQLITE_OK; |
| 33034 | } |
| 33035 | |
| 33036 | /* |
| 33037 | ** Truncate an open file to a specified size |
| @@ -33014,13 +33040,13 @@ | |
| 33040 | winFile *pFile = (winFile*)id; /* File handle object */ |
| 33041 | int rc = SQLITE_OK; /* Return code for this function */ |
| 33042 | DWORD lastErrno; |
| 33043 | |
| 33044 | assert( pFile ); |
| 33045 | SimulateIOError(return SQLITE_IOERR_TRUNCATE); |
| 33046 | OSTRACE(("TRUNCATE file=%p, size=%lld, lock=%d\n", |
| 33047 | pFile->h, nByte, pFile->locktype)); |
| 33048 | |
| 33049 | /* If the user has configured a chunk-size for this file, truncate the |
| 33050 | ** file so that it consists of an integer number of chunks (i.e. the |
| 33051 | ** actual file size after the operation may be larger than the requested |
| 33052 | ** size). |
| @@ -33048,11 +33074,11 @@ | |
| 33074 | if( pFile->pMapRegion && nByte<pFile->mmapSize ){ |
| 33075 | pFile->mmapSize = nByte; |
| 33076 | } |
| 33077 | #endif |
| 33078 | |
| 33079 | OSTRACE(("TRUNCATE file=%p, rc=%s\n", pFile->h, sqlite3ErrName(rc))); |
| 33080 | return rc; |
| 33081 | } |
| 33082 | |
| 33083 | #ifdef SQLITE_TEST |
| 33084 | /* |
| @@ -33088,16 +33114,17 @@ | |
| 33114 | /* Check that one of SQLITE_SYNC_NORMAL or FULL was passed */ |
| 33115 | assert((flags&0x0F)==SQLITE_SYNC_NORMAL |
| 33116 | || (flags&0x0F)==SQLITE_SYNC_FULL |
| 33117 | ); |
| 33118 | |
| 33119 | /* Unix cannot, but some systems may return SQLITE_FULL from here. This |
| 33120 | ** line is to test that doing so does not cause any problems. |
| 33121 | */ |
| 33122 | SimulateDiskfullError( return SQLITE_FULL ); |
| 33123 | |
| 33124 | OSTRACE(("SYNC file=%p, flags=%x, lock=%d\n", |
| 33125 | pFile->h, flags, pFile->locktype)); |
| 33126 | |
| 33127 | #ifndef SQLITE_TEST |
| 33128 | UNUSED_PARAMETER(flags); |
| 33129 | #else |
| 33130 | if( (flags&0x0F)==SQLITE_SYNC_FULL ){ |
| @@ -33113,13 +33140,15 @@ | |
| 33140 | return SQLITE_OK; |
| 33141 | #else |
| 33142 | rc = osFlushFileBuffers(pFile->h); |
| 33143 | SimulateIOError( rc=FALSE ); |
| 33144 | if( rc ){ |
| 33145 | OSTRACE(("SYNC file=%p, rc=SQLITE_OK\n", pFile->h)); |
| 33146 | return SQLITE_OK; |
| 33147 | }else{ |
| 33148 | pFile->lastErrno = osGetLastError(); |
| 33149 | OSTRACE(("SYNC file=%p, rc=SQLITE_IOERR_FSYNC\n", pFile->h)); |
| 33150 | return winLogError(SQLITE_IOERR_FSYNC, pFile->lastErrno, |
| 33151 | "winSync", pFile->zPath); |
| 33152 | } |
| 33153 | #endif |
| 33154 | } |
| @@ -33130,11 +33159,14 @@ | |
| 33159 | static int winFileSize(sqlite3_file *id, sqlite3_int64 *pSize){ |
| 33160 | winFile *pFile = (winFile*)id; |
| 33161 | int rc = SQLITE_OK; |
| 33162 | |
| 33163 | assert( id!=0 ); |
| 33164 | assert( pSize!=0 ); |
| 33165 | SimulateIOError(return SQLITE_IOERR_FSTAT); |
| 33166 | OSTRACE(("SIZE file=%p, pSize=%p\n", pFile->h, pSize)); |
| 33167 | |
| 33168 | #if SQLITE_OS_WINRT |
| 33169 | { |
| 33170 | FILE_STANDARD_INFO info; |
| 33171 | if( osGetFileInformationByHandleEx(pFile->h, FileStandardInfo, |
| 33172 | &info, sizeof(info)) ){ |
| @@ -33159,10 +33191,12 @@ | |
| 33191 | rc = winLogError(SQLITE_IOERR_FSTAT, pFile->lastErrno, |
| 33192 | "winFileSize", pFile->zPath); |
| 33193 | } |
| 33194 | } |
| 33195 | #endif |
| 33196 | OSTRACE(("SIZE file=%p, pSize=%p, *pSize=%lld, rc=%s\n", |
| 33197 | pFile->h, pSize, *pSize, sqlite3ErrName(rc))); |
| 33198 | return rc; |
| 33199 | } |
| 33200 | |
| 33201 | /* |
| 33202 | ** LOCKFILE_FAIL_IMMEDIATELY is undefined on some Windows systems. |
| @@ -33200,10 +33234,11 @@ | |
| 33234 | ** Different API routines are called depending on whether or not this |
| 33235 | ** is Win9x or WinNT. |
| 33236 | */ |
| 33237 | static int getReadLock(winFile *pFile){ |
| 33238 | int res; |
| 33239 | OSTRACE(("READ-LOCK file=%p, lock=%d\n", pFile->h, pFile->locktype)); |
| 33240 | if( isNT() ){ |
| 33241 | #if SQLITE_OS_WINCE |
| 33242 | /* |
| 33243 | ** NOTE: Windows CE is handled differently here due its lack of the Win32 |
| 33244 | ** API LockFileEx. |
| @@ -33225,19 +33260,21 @@ | |
| 33260 | #endif |
| 33261 | if( res == 0 ){ |
| 33262 | pFile->lastErrno = osGetLastError(); |
| 33263 | /* No need to log a failure to lock */ |
| 33264 | } |
| 33265 | OSTRACE(("READ-LOCK file=%p, rc=%s\n", pFile->h, sqlite3ErrName(res))); |
| 33266 | return res; |
| 33267 | } |
| 33268 | |
| 33269 | /* |
| 33270 | ** Undo a readlock |
| 33271 | */ |
| 33272 | static int unlockReadLock(winFile *pFile){ |
| 33273 | int res; |
| 33274 | DWORD lastErrno; |
| 33275 | OSTRACE(("READ-UNLOCK file=%p, lock=%d\n", pFile->h, pFile->locktype)); |
| 33276 | if( isNT() ){ |
| 33277 | res = winUnlockFile(&pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0); |
| 33278 | } |
| 33279 | #ifdef SQLITE_WIN32_HAS_ANSI |
| 33280 | else{ |
| @@ -33247,10 +33284,11 @@ | |
| 33284 | if( res==0 && ((lastErrno = osGetLastError())!=ERROR_NOT_LOCKED) ){ |
| 33285 | pFile->lastErrno = lastErrno; |
| 33286 | winLogError(SQLITE_IOERR_UNLOCK, pFile->lastErrno, |
| 33287 | "unlockReadLock", pFile->zPath); |
| 33288 | } |
| 33289 | OSTRACE(("READ-UNLOCK file=%p, rc=%s\n", pFile->h, sqlite3ErrName(res))); |
| 33290 | return res; |
| 33291 | } |
| 33292 | |
| 33293 | /* |
| 33294 | ** Lock the file with the lock specified by parameter locktype - one |
| @@ -33285,18 +33323,19 @@ | |
| 33323 | int gotPendingLock = 0;/* True if we acquired a PENDING lock this time */ |
| 33324 | winFile *pFile = (winFile*)id; |
| 33325 | DWORD lastErrno = NO_ERROR; |
| 33326 | |
| 33327 | assert( id!=0 ); |
| 33328 | OSTRACE(("LOCK file=%p, oldLock=%d(%d), newLock=%d\n", |
| 33329 | pFile->h, pFile->locktype, pFile->sharedLockByte, locktype)); |
| 33330 | |
| 33331 | /* If there is already a lock of this type or more restrictive on the |
| 33332 | ** OsFile, do nothing. Don't use the end_lock: exit path, as |
| 33333 | ** sqlite3OsEnterMutex() hasn't been called yet. |
| 33334 | */ |
| 33335 | if( pFile->locktype>=locktype ){ |
| 33336 | OSTRACE(("LOCK-HELD file=%p, rc=SQLITE_OK\n", pFile->h)); |
| 33337 | return SQLITE_OK; |
| 33338 | } |
| 33339 | |
| 33340 | /* Make sure the locking sequence is correct |
| 33341 | */ |
| @@ -33320,11 +33359,12 @@ | |
| 33359 | ** around problems caused by indexing and/or anti-virus software on |
| 33360 | ** Windows systems. |
| 33361 | ** If you are using this code as a model for alternative VFSes, do not |
| 33362 | ** copy this retry logic. It is a hack intended for Windows only. |
| 33363 | */ |
| 33364 | OSTRACE(("LOCK-PENDING-FAIL file=%p, count=%d, rc=%s\n", |
| 33365 | pFile->h, cnt, sqlite3ErrName(res))); |
| 33366 | if( cnt ) sqlite3_win32_sleep(1); |
| 33367 | } |
| 33368 | gotPendingLock = res; |
| 33369 | if( !res ){ |
| 33370 | lastErrno = osGetLastError(); |
| @@ -33365,18 +33405,16 @@ | |
| 33405 | /* Acquire an EXCLUSIVE lock |
| 33406 | */ |
| 33407 | if( locktype==EXCLUSIVE_LOCK && res ){ |
| 33408 | assert( pFile->locktype>=SHARED_LOCK ); |
| 33409 | res = unlockReadLock(pFile); |
| 33410 | res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS, SHARED_FIRST, 0, |
| 33411 | SHARED_SIZE, 0); |
| 33412 | if( res ){ |
| 33413 | newLocktype = EXCLUSIVE_LOCK; |
| 33414 | }else{ |
| 33415 | lastErrno = osGetLastError(); |
| 33416 | getReadLock(pFile); |
| 33417 | } |
| 33418 | } |
| 33419 | |
| 33420 | /* If we are holding a PENDING lock that ought to be released, then |
| @@ -33390,16 +33428,18 @@ | |
| 33428 | ** return the appropriate result code. |
| 33429 | */ |
| 33430 | if( res ){ |
| 33431 | rc = SQLITE_OK; |
| 33432 | }else{ |
| 33433 | OSTRACE(("LOCK-FAIL file=%p, wanted=%d, got=%d\n", |
| 33434 | pFile->h, locktype, newLocktype)); |
| 33435 | pFile->lastErrno = lastErrno; |
| 33436 | rc = SQLITE_BUSY; |
| 33437 | } |
| 33438 | pFile->locktype = (u8)newLocktype; |
| 33439 | OSTRACE(("LOCK file=%p, lock=%d, rc=%s\n", |
| 33440 | pFile->h, pFile->locktype, sqlite3ErrName(rc))); |
| 33441 | return rc; |
| 33442 | } |
| 33443 | |
| 33444 | /* |
| 33445 | ** This routine checks if there is a RESERVED lock held on the specified |
| @@ -33409,24 +33449,27 @@ | |
| 33449 | static int winCheckReservedLock(sqlite3_file *id, int *pResOut){ |
| 33450 | int rc; |
| 33451 | winFile *pFile = (winFile*)id; |
| 33452 | |
| 33453 | SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; ); |
| 33454 | OSTRACE(("TEST-WR-LOCK file=%p, pResOut=%p\n", pFile->h, pResOut)); |
| 33455 | |
| 33456 | assert( id!=0 ); |
| 33457 | if( pFile->locktype>=RESERVED_LOCK ){ |
| 33458 | rc = 1; |
| 33459 | OSTRACE(("TEST-WR-LOCK file=%p, rc=%d (local)\n", pFile->h, rc)); |
| 33460 | }else{ |
| 33461 | rc = winLockFile(&pFile->h, SQLITE_LOCKFILEEX_FLAGS,RESERVED_BYTE, 0, 1, 0); |
| 33462 | if( rc ){ |
| 33463 | winUnlockFile(&pFile->h, RESERVED_BYTE, 0, 1, 0); |
| 33464 | } |
| 33465 | rc = !rc; |
| 33466 | OSTRACE(("TEST-WR-LOCK file=%p, rc=%d (remote)\n", pFile->h, rc)); |
| 33467 | } |
| 33468 | *pResOut = rc; |
| 33469 | OSTRACE(("TEST-WR-LOCK file=%p, pResOut=%p, *pResOut=%d, rc=SQLITE_OK\n", |
| 33470 | pFile->h, pResOut, *pResOut)); |
| 33471 | return SQLITE_OK; |
| 33472 | } |
| 33473 | |
| 33474 | /* |
| 33475 | ** Lower the locking level on file descriptor id to locktype. locktype |
| @@ -33443,12 +33486,12 @@ | |
| 33486 | int type; |
| 33487 | winFile *pFile = (winFile*)id; |
| 33488 | int rc = SQLITE_OK; |
| 33489 | assert( pFile!=0 ); |
| 33490 | assert( locktype<=SHARED_LOCK ); |
| 33491 | OSTRACE(("UNLOCK file=%p, oldLock=%d(%d), newLock=%d\n", |
| 33492 | pFile->h, pFile->locktype, pFile->sharedLockByte, locktype)); |
| 33493 | type = pFile->locktype; |
| 33494 | if( type>=EXCLUSIVE_LOCK ){ |
| 33495 | winUnlockFile(&pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0); |
| 33496 | if( locktype==SHARED_LOCK && !getReadLock(pFile) ){ |
| 33497 | /* This should never happen. We should always be able to |
| @@ -33465,10 +33508,12 @@ | |
| 33508 | } |
| 33509 | if( type>=PENDING_LOCK ){ |
| 33510 | winUnlockFile(&pFile->h, PENDING_BYTE, 0, 1, 0); |
| 33511 | } |
| 33512 | pFile->locktype = (u8)locktype; |
| 33513 | OSTRACE(("UNLOCK file=%p, lock=%d, rc=%s\n", |
| 33514 | pFile->h, pFile->locktype, sqlite3ErrName(rc))); |
| 33515 | return rc; |
| 33516 | } |
| 33517 | |
| 33518 | /* |
| 33519 | ** If *pArg is inititially negative then this is a query. Set *pArg to |
| @@ -33492,21 +33537,25 @@ | |
| 33537 | /* |
| 33538 | ** Control and query of the open file handle. |
| 33539 | */ |
| 33540 | static int winFileControl(sqlite3_file *id, int op, void *pArg){ |
| 33541 | winFile *pFile = (winFile*)id; |
| 33542 | OSTRACE(("FCNTL file=%p, op=%d, pArg=%p\n", pFile->h, op, pArg)); |
| 33543 | switch( op ){ |
| 33544 | case SQLITE_FCNTL_LOCKSTATE: { |
| 33545 | *(int*)pArg = pFile->locktype; |
| 33546 | OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); |
| 33547 | return SQLITE_OK; |
| 33548 | } |
| 33549 | case SQLITE_LAST_ERRNO: { |
| 33550 | *(int*)pArg = (int)pFile->lastErrno; |
| 33551 | OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); |
| 33552 | return SQLITE_OK; |
| 33553 | } |
| 33554 | case SQLITE_FCNTL_CHUNK_SIZE: { |
| 33555 | pFile->szChunk = *(int *)pArg; |
| 33556 | OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); |
| 33557 | return SQLITE_OK; |
| 33558 | } |
| 33559 | case SQLITE_FCNTL_SIZE_HINT: { |
| 33560 | if( pFile->szChunk>0 ){ |
| 33561 | sqlite3_int64 oldSz; |
| @@ -33517,24 +33566,29 @@ | |
| 33566 | SimulateIOErrorBenign(1); |
| 33567 | rc = winTruncate(id, newSz); |
| 33568 | SimulateIOErrorBenign(0); |
| 33569 | } |
| 33570 | } |
| 33571 | OSTRACE(("FCNTL file=%p, rc=%s\n", pFile->h, sqlite3ErrName(rc))); |
| 33572 | return rc; |
| 33573 | } |
| 33574 | OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); |
| 33575 | return SQLITE_OK; |
| 33576 | } |
| 33577 | case SQLITE_FCNTL_PERSIST_WAL: { |
| 33578 | winModeBit(pFile, WINFILE_PERSIST_WAL, (int*)pArg); |
| 33579 | OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); |
| 33580 | return SQLITE_OK; |
| 33581 | } |
| 33582 | case SQLITE_FCNTL_POWERSAFE_OVERWRITE: { |
| 33583 | winModeBit(pFile, WINFILE_PSOW, (int*)pArg); |
| 33584 | OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); |
| 33585 | return SQLITE_OK; |
| 33586 | } |
| 33587 | case SQLITE_FCNTL_VFSNAME: { |
| 33588 | *(char**)pArg = sqlite3_mprintf("win32"); |
| 33589 | OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); |
| 33590 | return SQLITE_OK; |
| 33591 | } |
| 33592 | case SQLITE_FCNTL_WIN32_AV_RETRY: { |
| 33593 | int *a = (int*)pArg; |
| 33594 | if( a[0]>0 ){ |
| @@ -33545,18 +33599,20 @@ | |
| 33599 | if( a[1]>0 ){ |
| 33600 | win32IoerrRetryDelay = a[1]; |
| 33601 | }else{ |
| 33602 | a[1] = win32IoerrRetryDelay; |
| 33603 | } |
| 33604 | OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); |
| 33605 | return SQLITE_OK; |
| 33606 | } |
| 33607 | case SQLITE_FCNTL_TEMPFILENAME: { |
| 33608 | char *zTFile = sqlite3MallocZero( pFile->pVfs->mxPathname ); |
| 33609 | if( zTFile ){ |
| 33610 | getTempname(pFile->pVfs->mxPathname, zTFile); |
| 33611 | *(char**)pArg = zTFile; |
| 33612 | } |
| 33613 | OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); |
| 33614 | return SQLITE_OK; |
| 33615 | } |
| 33616 | #if SQLITE_MAX_MMAP_SIZE>0 |
| 33617 | case SQLITE_FCNTL_MMAP_SIZE: { |
| 33618 | i64 newLimit = *(i64*)pArg; |
| @@ -33563,14 +33619,16 @@ | |
| 33619 | if( newLimit>sqlite3GlobalConfig.mxMmap ){ |
| 33620 | newLimit = sqlite3GlobalConfig.mxMmap; |
| 33621 | } |
| 33622 | *(i64*)pArg = pFile->mmapSizeMax; |
| 33623 | if( newLimit>=0 ) pFile->mmapSizeMax = newLimit; |
| 33624 | OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); |
| 33625 | return SQLITE_OK; |
| 33626 | } |
| 33627 | #endif |
| 33628 | } |
| 33629 | OSTRACE(("FCNTL file=%p, rc=SQLITE_NOTFOUND\n", pFile->h)); |
| 33630 | return SQLITE_NOTFOUND; |
| 33631 | } |
| 33632 | |
| 33633 | /* |
| 33634 | ** Return the sector size in bytes of the underlying block device for |
| @@ -33727,10 +33785,13 @@ | |
| 33785 | int rc = 0; /* Result code form Lock/UnlockFileEx() */ |
| 33786 | |
| 33787 | /* Access to the winShmNode object is serialized by the caller */ |
| 33788 | assert( sqlite3_mutex_held(pFile->mutex) || pFile->nRef==0 ); |
| 33789 | |
| 33790 | OSTRACE(("SHM-LOCK file=%p, lock=%d, offset=%d, size=%d\n", |
| 33791 | pFile->hFile.h, lockType, ofst, nByte)); |
| 33792 | |
| 33793 | /* Release/Acquire the system-level lock */ |
| 33794 | if( lockType==_SHM_UNLCK ){ |
| 33795 | rc = winUnlockFile(&pFile->hFile.h, ofst, 0, nByte, 0); |
| 33796 | }else{ |
| 33797 | /* Initialize the locking parameters */ |
| @@ -33744,15 +33805,13 @@ | |
| 33805 | }else{ |
| 33806 | pFile->lastErrno = osGetLastError(); |
| 33807 | rc = SQLITE_BUSY; |
| 33808 | } |
| 33809 | |
| 33810 | OSTRACE(("SHM-LOCK file=%p, func=%s, errno=%lu, rc=%s\n", |
| 33811 | pFile->hFile.h, (lockType == _SHM_UNLCK) ? "winUnlockFile" : |
| 33812 | "winLockFile", pFile->lastErrno, sqlite3ErrName(rc))); |
| 33813 | |
| 33814 | return rc; |
| 33815 | } |
| 33816 | |
| 33817 | /* Forward references to VFS methods */ |
| @@ -33768,24 +33827,24 @@ | |
| 33827 | static void winShmPurge(sqlite3_vfs *pVfs, int deleteFlag){ |
| 33828 | winShmNode **pp; |
| 33829 | winShmNode *p; |
| 33830 | BOOL bRc; |
| 33831 | assert( winShmMutexHeld() ); |
| 33832 | OSTRACE(("SHM-PURGE pid=%lu, deleteFlag=%d\n", |
| 33833 | osGetCurrentProcessId(), deleteFlag)); |
| 33834 | pp = &winShmNodeList; |
| 33835 | while( (p = *pp)!=0 ){ |
| 33836 | if( p->nRef==0 ){ |
| 33837 | int i; |
| 33838 | if( p->mutex ) sqlite3_mutex_free(p->mutex); |
| 33839 | for(i=0; i<p->nRegion; i++){ |
| 33840 | bRc = osUnmapViewOfFile(p->aRegion[i].pMap); |
| 33841 | OSTRACE(("SHM-PURGE-UNMAP pid=%lu, region=%d, rc=%s\n", |
| 33842 | osGetCurrentProcessId(), i, bRc ? "ok" : "failed")); |
| 33843 | bRc = osCloseHandle(p->aRegion[i].hMap); |
| 33844 | OSTRACE(("SHM-PURGE-CLOSE pid=%lu, region=%d, rc=%s\n", |
| 33845 | osGetCurrentProcessId(), i, bRc ? "ok" : "failed")); |
| 33846 | } |
| 33847 | if( p->hFile.h!=NULL && p->hFile.h!=INVALID_HANDLE_VALUE ){ |
| 33848 | SimulateIOErrorBenign(1); |
| 33849 | winClose((sqlite3_file *)&p->hFile); |
| 33850 | SimulateIOErrorBenign(0); |
| @@ -34060,13 +34119,13 @@ | |
| 34119 | p->exclMask |= mask; |
| 34120 | } |
| 34121 | } |
| 34122 | } |
| 34123 | sqlite3_mutex_leave(pShmNode->mutex); |
| 34124 | OSTRACE(("SHM-LOCK pid=%lu, id=%d, sharedMask=%03x, exclMask=%03x, rc=%s\n", |
| 34125 | osGetCurrentProcessId(), p->id, p->sharedMask, p->exclMask, |
| 34126 | sqlite3ErrName(rc))); |
| 34127 | return rc; |
| 34128 | } |
| 34129 | |
| 34130 | /* |
| 34131 | ** Implement a memory barrier or memory fence on shared memory. |
| @@ -34183,12 +34242,12 @@ | |
| 34242 | #elif defined(SQLITE_WIN32_HAS_ANSI) |
| 34243 | hMap = osCreateFileMappingA(pShmNode->hFile.h, |
| 34244 | NULL, PAGE_READWRITE, 0, nByte, NULL |
| 34245 | ); |
| 34246 | #endif |
| 34247 | OSTRACE(("SHM-MAP-CREATE pid=%lu, region=%d, size=%d, rc=%s\n", |
| 34248 | osGetCurrentProcessId(), pShmNode->nRegion, nByte, |
| 34249 | hMap ? "ok" : "failed")); |
| 34250 | if( hMap ){ |
| 34251 | int iOffset = pShmNode->nRegion*szRegion; |
| 34252 | int iOffsetShift = iOffset % winSysInfo.dwAllocationGranularity; |
| 34253 | #if SQLITE_OS_WINRT |
| @@ -34198,12 +34257,12 @@ | |
| 34257 | #else |
| 34258 | pMap = osMapViewOfFile(hMap, FILE_MAP_WRITE | FILE_MAP_READ, |
| 34259 | 0, iOffset - iOffsetShift, szRegion + iOffsetShift |
| 34260 | ); |
| 34261 | #endif |
| 34262 | OSTRACE(("SHM-MAP-MAP pid=%lu, region=%d, offset=%d, size=%d, rc=%s\n", |
| 34263 | osGetCurrentProcessId(), pShmNode->nRegion, iOffset, |
| 34264 | szRegion, pMap ? "ok" : "failed")); |
| 34265 | } |
| 34266 | if( !pMap ){ |
| 34267 | pShmNode->lastErrno = osGetLastError(); |
| 34268 | rc = winLogError(SQLITE_IOERR_SHMMAP, pShmNode->lastErrno, |
| @@ -34242,13 +34301,20 @@ | |
| 34301 | ** Cleans up the mapped region of the specified file, if any. |
| 34302 | */ |
| 34303 | #if SQLITE_MAX_MMAP_SIZE>0 |
| 34304 | static int winUnmapfile(winFile *pFile){ |
| 34305 | assert( pFile!=0 ); |
| 34306 | OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, hMap=%p, pMapRegion=%p, " |
| 34307 | "mmapSize=%lld, mmapSizeActual=%lld, mmapSizeMax=%lld\n", |
| 34308 | osGetCurrentProcessId(), pFile, pFile->hMap, pFile->pMapRegion, |
| 34309 | pFile->mmapSize, pFile->mmapSizeActual, pFile->mmapSizeMax)); |
| 34310 | if( pFile->pMapRegion ){ |
| 34311 | if( !osUnmapViewOfFile(pFile->pMapRegion) ){ |
| 34312 | pFile->lastErrno = osGetLastError(); |
| 34313 | OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, pMapRegion=%p, " |
| 34314 | "rc=SQLITE_IOERR_MMAP\n", osGetCurrentProcessId(), pFile, |
| 34315 | pFile->pMapRegion)); |
| 34316 | return winLogError(SQLITE_IOERR_MMAP, pFile->lastErrno, |
| 34317 | "winUnmap1", pFile->zPath); |
| 34318 | } |
| 34319 | pFile->pMapRegion = 0; |
| 34320 | pFile->mmapSize = 0; |
| @@ -34255,15 +34321,19 @@ | |
| 34321 | pFile->mmapSizeActual = 0; |
| 34322 | } |
| 34323 | if( pFile->hMap!=NULL ){ |
| 34324 | if( !osCloseHandle(pFile->hMap) ){ |
| 34325 | pFile->lastErrno = osGetLastError(); |
| 34326 | OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, hMap=%p, rc=SQLITE_IOERR_MMAP\n", |
| 34327 | osGetCurrentProcessId(), pFile, pFile->hMap)); |
| 34328 | return winLogError(SQLITE_IOERR_MMAP, pFile->lastErrno, |
| 34329 | "winUnmap2", pFile->zPath); |
| 34330 | } |
| 34331 | pFile->hMap = NULL; |
| 34332 | } |
| 34333 | OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, rc=SQLITE_OK\n", |
| 34334 | osGetCurrentProcessId(), pFile)); |
| 34335 | return SQLITE_OK; |
| 34336 | } |
| 34337 | |
| 34338 | /* |
| 34339 | ** Memory map or remap the file opened by file-descriptor pFd (if the file |
| @@ -34284,15 +34354,20 @@ | |
| 34354 | static int winMapfile(winFile *pFd, sqlite3_int64 nByte){ |
| 34355 | sqlite3_int64 nMap = nByte; |
| 34356 | int rc; |
| 34357 | |
| 34358 | assert( nMap>=0 || pFd->nFetchOut==0 ); |
| 34359 | OSTRACE(("MAP-FILE pid=%lu, pFile=%p, size=%lld\n", |
| 34360 | osGetCurrentProcessId(), pFd, nByte)); |
| 34361 | |
| 34362 | if( pFd->nFetchOut>0 ) return SQLITE_OK; |
| 34363 | |
| 34364 | if( nMap<0 ){ |
| 34365 | rc = winFileSize((sqlite3_file*)pFd, &nMap); |
| 34366 | if( rc ){ |
| 34367 | OSTRACE(("MAP-FILE pid=%lu, pFile=%p, rc=SQLITE_IOERR_FSTAT\n", |
| 34368 | osGetCurrentProcessId(), pFd)); |
| 34369 | return SQLITE_IOERR_FSTAT; |
| 34370 | } |
| 34371 | } |
| 34372 | if( nMap>pFd->mmapSizeMax ){ |
| 34373 | nMap = pFd->mmapSizeMax; |
| @@ -34326,10 +34401,12 @@ | |
| 34401 | if( pFd->hMap==NULL ){ |
| 34402 | pFd->lastErrno = osGetLastError(); |
| 34403 | rc = winLogError(SQLITE_IOERR_MMAP, pFd->lastErrno, |
| 34404 | "winMapfile", pFd->zPath); |
| 34405 | /* Log the error, but continue normal operation using xRead/xWrite */ |
| 34406 | OSTRACE(("MAP-FILE-CREATE pid=%lu, pFile=%p, rc=SQLITE_IOERR_MMAP\n", |
| 34407 | osGetCurrentProcessId(), pFd)); |
| 34408 | return SQLITE_OK; |
| 34409 | } |
| 34410 | assert( (nMap % winSysInfo.dwPageSize)==0 ); |
| 34411 | #if SQLITE_OS_WINRT |
| 34412 | pNew = osMapViewOfFileFromApp(pFd->hMap, flags, 0, nMap); |
| @@ -34341,17 +34418,21 @@ | |
| 34418 | osCloseHandle(pFd->hMap); |
| 34419 | pFd->hMap = NULL; |
| 34420 | pFd->lastErrno = osGetLastError(); |
| 34421 | winLogError(SQLITE_IOERR_MMAP, pFd->lastErrno, |
| 34422 | "winMapfile", pFd->zPath); |
| 34423 | OSTRACE(("MAP-FILE-MAP pid=%lu, pFile=%p, rc=SQLITE_IOERR_MMAP\n", |
| 34424 | osGetCurrentProcessId(), pFd)); |
| 34425 | return SQLITE_OK; |
| 34426 | } |
| 34427 | pFd->pMapRegion = pNew; |
| 34428 | pFd->mmapSize = nMap; |
| 34429 | pFd->mmapSizeActual = nMap; |
| 34430 | } |
| 34431 | |
| 34432 | OSTRACE(("MAP-FILE pid=%lu, pFile=%p, rc=SQLITE_OK\n", |
| 34433 | osGetCurrentProcessId(), pFd)); |
| 34434 | return SQLITE_OK; |
| 34435 | } |
| 34436 | #endif /* SQLITE_MAX_MMAP_SIZE>0 */ |
| 34437 | |
| 34438 | /* |
| @@ -34362,38 +34443,48 @@ | |
| 34443 | ** Or, if one cannot but no error occurs, set *pp to 0 and return SQLITE_OK. |
| 34444 | ** Finally, if an error does occur, return an SQLite error code. The final |
| 34445 | ** value of *pp is undefined in this case. |
| 34446 | ** |
| 34447 | ** If this function does return a pointer, the caller must eventually |
| 34448 | ** release the reference by calling winUnfetch(). |
| 34449 | */ |
| 34450 | static int winFetch(sqlite3_file *fd, i64 iOff, int nAmt, void **pp){ |
| 34451 | #if SQLITE_MAX_MMAP_SIZE>0 |
| 34452 | winFile *pFd = (winFile*)fd; /* The underlying database file */ |
| 34453 | #endif |
| 34454 | *pp = 0; |
| 34455 | |
| 34456 | OSTRACE(("FETCH pid=%lu, pFile=%p, offset=%lld, amount=%d, pp=%p\n", |
| 34457 | osGetCurrentProcessId(), fd, iOff, nAmt, pp)); |
| 34458 | |
| 34459 | #if SQLITE_MAX_MMAP_SIZE>0 |
| 34460 | if( pFd->mmapSizeMax>0 ){ |
| 34461 | if( pFd->pMapRegion==0 ){ |
| 34462 | int rc = winMapfile(pFd, -1); |
| 34463 | if( rc!=SQLITE_OK ){ |
| 34464 | OSTRACE(("FETCH pid=%lu, pFile=%p, rc=%s\n", |
| 34465 | osGetCurrentProcessId(), pFd, sqlite3ErrName(rc))); |
| 34466 | return rc; |
| 34467 | } |
| 34468 | } |
| 34469 | if( pFd->mmapSize >= iOff+nAmt ){ |
| 34470 | *pp = &((u8 *)pFd->pMapRegion)[iOff]; |
| 34471 | pFd->nFetchOut++; |
| 34472 | } |
| 34473 | } |
| 34474 | #endif |
| 34475 | |
| 34476 | OSTRACE(("FETCH pid=%lu, pFile=%p, pp=%p, *pp=%p, rc=SQLITE_OK\n", |
| 34477 | osGetCurrentProcessId(), fd, pp, *pp)); |
| 34478 | return SQLITE_OK; |
| 34479 | } |
| 34480 | |
| 34481 | /* |
| 34482 | ** If the third argument is non-NULL, then this function releases a |
| 34483 | ** reference obtained by an earlier call to winFetch(). The second |
| 34484 | ** argument passed to this function must be the same as the corresponding |
| 34485 | ** argument that was passed to the winFetch() invocation. |
| 34486 | ** |
| 34487 | ** Or, if the third argument is NULL, then this function is being called |
| 34488 | ** to inform the VFS layer that, according to POSIX, any existing mapping |
| 34489 | ** may now be invalid and should be unmapped. |
| 34490 | */ |
| @@ -34407,10 +34498,13 @@ | |
| 34498 | assert( (p==0)==(pFd->nFetchOut==0) ); |
| 34499 | |
| 34500 | /* If p!=0, it must match the iOff value. */ |
| 34501 | assert( p==0 || p==&((u8 *)pFd->pMapRegion)[iOff] ); |
| 34502 | |
| 34503 | OSTRACE(("UNFETCH pid=%lu, pFile=%p, offset=%lld, p=%p\n", |
| 34504 | osGetCurrentProcessId(), pFd, iOff, p)); |
| 34505 | |
| 34506 | if( p ){ |
| 34507 | pFd->nFetchOut--; |
| 34508 | }else{ |
| 34509 | /* FIXME: If Windows truly always prevents truncating or deleting a |
| 34510 | ** file while a mapping is held, then the following winUnmapfile() call |
| @@ -34419,10 +34513,13 @@ | |
| 34513 | winUnmapfile(pFd); |
| 34514 | } |
| 34515 | |
| 34516 | assert( pFd->nFetchOut>=0 ); |
| 34517 | #endif |
| 34518 | |
| 34519 | OSTRACE(("UNFETCH pid=%lu, pFile=%p, rc=SQLITE_OK\n", |
| 34520 | osGetCurrentProcessId(), fd)); |
| 34521 | return SQLITE_OK; |
| 34522 | } |
| 34523 | |
| 34524 | /* |
| 34525 | ** Here ends the implementation of all sqlite3_file methods. |
| @@ -34515,10 +34612,11 @@ | |
| 34612 | zMulti = unicodeToUtf8(zWidePath); |
| 34613 | if( zMulti ){ |
| 34614 | sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", zMulti); |
| 34615 | sqlite3_free(zMulti); |
| 34616 | }else{ |
| 34617 | OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); |
| 34618 | return SQLITE_IOERR_NOMEM; |
| 34619 | } |
| 34620 | } |
| 34621 | #ifdef SQLITE_WIN32_HAS_ANSI |
| 34622 | else{ |
| @@ -34528,10 +34626,11 @@ | |
| 34626 | zUtf8 = sqlite3_win32_mbcs_to_utf8(zMbcsPath); |
| 34627 | if( zUtf8 ){ |
| 34628 | sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", zUtf8); |
| 34629 | sqlite3_free(zUtf8); |
| 34630 | }else{ |
| 34631 | OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); |
| 34632 | return SQLITE_IOERR_NOMEM; |
| 34633 | } |
| 34634 | } |
| 34635 | #endif |
| 34636 | #endif |
| @@ -34540,10 +34639,11 @@ | |
| 34639 | ** name. If it is not, return SQLITE_ERROR. |
| 34640 | */ |
| 34641 | nTempPath = sqlite3Strlen30(zTempPath); |
| 34642 | |
| 34643 | if( (nTempPath + sqlite3Strlen30(SQLITE_TEMP_FILE_PREFIX) + 18) >= nBuf ){ |
| 34644 | OSTRACE(("TEMP-FILENAME rc=SQLITE_ERROR\n")); |
| 34645 | return SQLITE_ERROR; |
| 34646 | } |
| 34647 | |
| 34648 | for(i=nTempPath; i>0 && zTempPath[i-1]=='\\'; i--){} |
| 34649 | zTempPath[i] = 0; |
| @@ -34557,12 +34657,12 @@ | |
| 34657 | zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ]; |
| 34658 | } |
| 34659 | zBuf[j] = 0; |
| 34660 | zBuf[j+1] = 0; |
| 34661 | |
| 34662 | OSTRACE(("TEMP-FILENAME name=%s, rc=SQLITE_OK\n", zBuf)); |
| 34663 | return SQLITE_OK; |
| 34664 | } |
| 34665 | |
| 34666 | /* |
| 34667 | ** Return TRUE if the named file is really a directory. Return false if |
| 34668 | ** it is something other than a directory, or if there is any kind of memory |
| @@ -34637,10 +34737,13 @@ | |
| 34737 | eType==SQLITE_OPEN_MASTER_JOURNAL |
| 34738 | || eType==SQLITE_OPEN_MAIN_JOURNAL |
| 34739 | || eType==SQLITE_OPEN_WAL |
| 34740 | )); |
| 34741 | #endif |
| 34742 | |
| 34743 | OSTRACE(("OPEN name=%s, pFile=%p, flags=%x, pOutFlags=%p\n", |
| 34744 | zUtf8Name, id, flags, pOutFlags)); |
| 34745 | |
| 34746 | /* Check the following statements are true: |
| 34747 | ** |
| 34748 | ** (a) Exactly one of the READWRITE and READONLY flags must be set, and |
| 34749 | ** (b) if CREATE is set, then READWRITE must also be set, and |
| @@ -34683,10 +34786,11 @@ | |
| 34786 | if( !zUtf8Name ){ |
| 34787 | assert(isDelete && !isOpenJournal); |
| 34788 | memset(zTmpname, 0, MAX_PATH+2); |
| 34789 | rc = getTempname(MAX_PATH+2, zTmpname); |
| 34790 | if( rc!=SQLITE_OK ){ |
| 34791 | OSTRACE(("OPEN name=%s, rc=%s", zUtf8Name, sqlite3ErrName(rc))); |
| 34792 | return rc; |
| 34793 | } |
| 34794 | zUtf8Name = zTmpname; |
| 34795 | } |
| 34796 | |
| @@ -34698,15 +34802,17 @@ | |
| 34802 | zUtf8Name[strlen(zUtf8Name)+1]==0 ); |
| 34803 | |
| 34804 | /* Convert the filename to the system encoding. */ |
| 34805 | zConverted = convertUtf8Filename(zUtf8Name); |
| 34806 | if( zConverted==0 ){ |
| 34807 | OSTRACE(("OPEN name=%s, rc=SQLITE_IOERR_NOMEM", zUtf8Name)); |
| 34808 | return SQLITE_IOERR_NOMEM; |
| 34809 | } |
| 34810 | |
| 34811 | if( winIsDir(zConverted) ){ |
| 34812 | sqlite3_free(zConverted); |
| 34813 | OSTRACE(("OPEN name=%s, rc=SQLITE_CANTOPEN_ISDIR", zUtf8Name)); |
| 34814 | return SQLITE_CANTOPEN_ISDIR; |
| 34815 | } |
| 34816 | |
| 34817 | if( isReadWrite ){ |
| 34818 | dwDesiredAccess = GENERIC_READ | GENERIC_WRITE; |
| @@ -34793,13 +34899,12 @@ | |
| 34899 | } |
| 34900 | } |
| 34901 | #endif |
| 34902 | logIoerr(cnt); |
| 34903 | |
| 34904 | OSTRACE(("OPEN file=%p, name=%s, access=%lx, rc=%s\n", h, zUtf8Name, |
| 34905 | dwDesiredAccess, (h==INVALID_HANDLE_VALUE) ? "failed" : "ok")); |
| 34906 | |
| 34907 | if( h==INVALID_HANDLE_VALUE ){ |
| 34908 | pFile->lastErrno = lastErrno; |
| 34909 | winLogError(SQLITE_CANTOPEN, pFile->lastErrno, "winOpen", zUtf8Name); |
| 34910 | sqlite3_free(zConverted); |
| @@ -34819,16 +34924,21 @@ | |
| 34924 | }else{ |
| 34925 | *pOutFlags = SQLITE_OPEN_READONLY; |
| 34926 | } |
| 34927 | } |
| 34928 | |
| 34929 | OSTRACE(("OPEN file=%p, name=%s, access=%lx, pOutFlags=%p, *pOutFlags=%d, " |
| 34930 | "rc=%s\n", h, zUtf8Name, dwDesiredAccess, pOutFlags, pOutFlags ? |
| 34931 | *pOutFlags : 0, (h==INVALID_HANDLE_VALUE) ? "failed" : "ok")); |
| 34932 | |
| 34933 | #if SQLITE_OS_WINCE |
| 34934 | if( isReadWrite && eType==SQLITE_OPEN_MAIN_DB |
| 34935 | && (rc = winceCreateLock(zName, pFile))!=SQLITE_OK |
| 34936 | ){ |
| 34937 | osCloseHandle(h); |
| 34938 | sqlite3_free(zConverted); |
| 34939 | OSTRACE(("OPEN-CE-LOCK name=%s, rc=%s\n", zName, sqlite3ErrName(rc))); |
| 34940 | return rc; |
| 34941 | } |
| 34942 | if( isTemp ){ |
| 34943 | pFile->zDeleteOnClose = zConverted; |
| 34944 | }else |
| @@ -34884,10 +34994,12 @@ | |
| 34994 | void *zConverted; |
| 34995 | UNUSED_PARAMETER(pVfs); |
| 34996 | UNUSED_PARAMETER(syncDir); |
| 34997 | |
| 34998 | SimulateIOError(return SQLITE_IOERR_DELETE); |
| 34999 | OSTRACE(("DELETE name=%s, syncDir=%d\n", zFilename, syncDir)); |
| 35000 | |
| 35001 | zConverted = convertUtf8Filename(zFilename); |
| 35002 | if( zConverted==0 ){ |
| 35003 | return SQLITE_IOERR_NOMEM; |
| 35004 | } |
| 35005 | if( isNT() ){ |
| @@ -34969,11 +35081,11 @@ | |
| 35081 | "winDelete", zFilename); |
| 35082 | }else{ |
| 35083 | logIoerr(cnt); |
| 35084 | } |
| 35085 | sqlite3_free(zConverted); |
| 35086 | OSTRACE(("DELETE name=%s, rc=%s\n", zFilename, sqlite3ErrName(rc))); |
| 35087 | return rc; |
| 35088 | } |
| 35089 | |
| 35090 | /* |
| 35091 | ** Check the existence and status of a file. |
| @@ -34989,12 +35101,16 @@ | |
| 35101 | DWORD lastErrno; |
| 35102 | void *zConverted; |
| 35103 | UNUSED_PARAMETER(pVfs); |
| 35104 | |
| 35105 | SimulateIOError( return SQLITE_IOERR_ACCESS; ); |
| 35106 | OSTRACE(("ACCESS name=%s, flags=%x, pResOut=%p\n", |
| 35107 | zFilename, flags, pResOut)); |
| 35108 | |
| 35109 | zConverted = convertUtf8Filename(zFilename); |
| 35110 | if( zConverted==0 ){ |
| 35111 | OSTRACE(("ACCESS name=%s, rc=SQLITE_IOERR_NOMEM\n", zFilename)); |
| 35112 | return SQLITE_IOERR_NOMEM; |
| 35113 | } |
| 35114 | if( isNT() ){ |
| 35115 | int cnt = 0; |
| 35116 | WIN32_FILE_ATTRIBUTE_DATA sAttrData; |
| @@ -35041,10 +35157,12 @@ | |
| 35157 | break; |
| 35158 | default: |
| 35159 | assert(!"Invalid flags argument"); |
| 35160 | } |
| 35161 | *pResOut = rc; |
| 35162 | OSTRACE(("ACCESS name=%s, pResOut=%p, *pResOut=%d, rc=SQLITE_OK\n", |
| 35163 | zFilename, pResOut, *pResOut)); |
| 35164 | return SQLITE_OK; |
| 35165 | } |
| 35166 | |
| 35167 | |
| 35168 | /* |
| @@ -51943,10 +52061,33 @@ | |
| 52061 | releasePage(pPage1); |
| 52062 | pBt->pPage1 = 0; |
| 52063 | return rc; |
| 52064 | } |
| 52065 | |
| 52066 | #ifndef NDEBUG |
| 52067 | /* |
| 52068 | ** Return the number of cursors open on pBt. This is for use |
| 52069 | ** in assert() expressions, so it is only compiled if NDEBUG is not |
| 52070 | ** defined. |
| 52071 | ** |
| 52072 | ** Only write cursors are counted if wrOnly is true. If wrOnly is |
| 52073 | ** false then all cursors are counted. |
| 52074 | ** |
| 52075 | ** For the purposes of this routine, a cursor is any cursor that |
| 52076 | ** is capable of reading or writing to the databse. Cursors that |
| 52077 | ** have been tripped into the CURSOR_FAULT state are not counted. |
| 52078 | */ |
| 52079 | static int countValidCursors(BtShared *pBt, int wrOnly){ |
| 52080 | BtCursor *pCur; |
| 52081 | int r = 0; |
| 52082 | for(pCur=pBt->pCursor; pCur; pCur=pCur->pNext){ |
| 52083 | if( (wrOnly==0 || pCur->wrFlag) && pCur->eState!=CURSOR_FAULT ) r++; |
| 52084 | } |
| 52085 | return r; |
| 52086 | } |
| 52087 | #endif |
| 52088 | |
| 52089 | /* |
| 52090 | ** If there are no outstanding cursors and we are not in the middle |
| 52091 | ** of a transaction but there is a read lock on the database, then |
| 52092 | ** this routine unrefs the first page of the database file which |
| 52093 | ** has the effect of releasing the read lock. |
| @@ -51953,11 +52094,11 @@ | |
| 52094 | ** |
| 52095 | ** If there is a transaction in progress, this routine is a no-op. |
| 52096 | */ |
| 52097 | static void unlockBtreeIfUnused(BtShared *pBt){ |
| 52098 | assert( sqlite3_mutex_held(pBt->mutex) ); |
| 52099 | assert( countValidCursors(pBt,0)==0 || pBt->inTransaction>TRANS_NONE ); |
| 52100 | if( pBt->inTransaction==TRANS_NONE && pBt->pPage1!=0 ){ |
| 52101 | assert( pBt->pPage1->aData ); |
| 52102 | assert( sqlite3PagerRefcount(pBt->pPager)==1 ); |
| 52103 | assert( pBt->pPage1->aData ); |
| 52104 | releasePage(pBt->pPage1); |
| @@ -52681,11 +52822,10 @@ | |
| 52822 | assert( sqlite3BtreeHoldsMutex(p) ); |
| 52823 | |
| 52824 | #ifndef SQLITE_OMIT_AUTOVACUUM |
| 52825 | pBt->bDoTruncate = 0; |
| 52826 | #endif |
| 52827 | if( p->inTrans>TRANS_NONE && p->db->activeVdbeCnt>1 ){ |
| 52828 | /* If there are other active statements that belong to this database |
| 52829 | ** handle, downgrade to a read-only transaction. The other statements |
| 52830 | ** may still be reading from the database. */ |
| 52831 | downgradeAllSharedCacheTableLocks(p); |
| @@ -52756,10 +52896,11 @@ | |
| 52896 | if( rc!=SQLITE_OK && bCleanup==0 ){ |
| 52897 | sqlite3BtreeLeave(p); |
| 52898 | return rc; |
| 52899 | } |
| 52900 | pBt->inTransaction = TRANS_READ; |
| 52901 | btreeClearHasContent(pBt); |
| 52902 | } |
| 52903 | |
| 52904 | btreeEndTransaction(p); |
| 52905 | sqlite3BtreeLeave(p); |
| 52906 | return SQLITE_OK; |
| @@ -52777,31 +52918,10 @@ | |
| 52918 | } |
| 52919 | sqlite3BtreeLeave(p); |
| 52920 | return rc; |
| 52921 | } |
| 52922 | |
| 52923 | /* |
| 52924 | ** This routine sets the state to CURSOR_FAULT and the error |
| 52925 | ** code to errCode for every cursor on BtShared that pBtree |
| 52926 | ** references. |
| 52927 | ** |
| @@ -52877,12 +52997,13 @@ | |
| 52997 | if( nPage==0 ) sqlite3PagerPagecount(pBt->pPager, &nPage); |
| 52998 | testcase( pBt->nPage!=nPage ); |
| 52999 | pBt->nPage = nPage; |
| 53000 | releasePage(pPage1); |
| 53001 | } |
| 53002 | assert( countValidCursors(pBt, 1)==0 ); |
| 53003 | pBt->inTransaction = TRANS_READ; |
| 53004 | btreeClearHasContent(pBt); |
| 53005 | } |
| 53006 | |
| 53007 | btreeEndTransaction(p); |
| 53008 | sqlite3BtreeLeave(p); |
| 53009 | return rc; |
| @@ -75216,16 +75337,11 @@ | |
| 75337 | p = p->pLeft; |
| 75338 | continue; |
| 75339 | } |
| 75340 | assert( op!=TK_REGISTER || p->op2!=TK_COLLATE ); |
| 75341 | if( op==TK_COLLATE ){ |
| 75342 | pColl = sqlite3GetCollSeq(pParse, ENC(db), 0, p->u.zToken); |
| 75343 | break; |
| 75344 | } |
| 75345 | if( p->pTab!=0 |
| 75346 | && (op==TK_AGG_COLUMN || op==TK_COLUMN |
| 75347 | || op==TK_REGISTER || op==TK_TRIGGER) |
| @@ -84722,14 +84838,12 @@ | |
| 84838 | ** specified collation sequence names. |
| 84839 | */ |
| 84840 | for(i=0; i<pList->nExpr; i++){ |
| 84841 | Expr *pExpr = pList->a[i].pExpr; |
| 84842 | if( pExpr ){ |
| 84843 | assert( pExpr->op==TK_COLLATE ); |
| 84844 | nExtra += (1 + sqlite3Strlen30(pExpr->u.zToken)); |
| 84845 | } |
| 84846 | } |
| 84847 | |
| 84848 | /* |
| 84849 | ** Allocate the index structure. |
| @@ -84786,11 +84900,10 @@ | |
| 84900 | */ |
| 84901 | for(i=0, pListItem=pList->a; i<pList->nExpr; i++, pListItem++){ |
| 84902 | const char *zColName = pListItem->zName; |
| 84903 | Column *pTabCol; |
| 84904 | int requestedSortOrder; |
| 84905 | char *zColl; /* Collation sequence name */ |
| 84906 | |
| 84907 | for(j=0, pTabCol=pTab->aCol; j<pTab->nCol; j++, pTabCol++){ |
| 84908 | if( sqlite3StrICmp(zColName, pTabCol->zName)==0 ) break; |
| 84909 | } |
| @@ -84799,26 +84912,23 @@ | |
| 84912 | pTab->zName, zColName); |
| 84913 | pParse->checkSchema = 1; |
| 84914 | goto exit_create_index; |
| 84915 | } |
| 84916 | pIndex->aiColumn[i] = j; |
| 84917 | if( pListItem->pExpr ){ |
| 84918 | int nColl; |
| 84919 | assert( pListItem->pExpr->op==TK_COLLATE ); |
| 84920 | zColl = pListItem->pExpr->u.zToken; |
| 84921 | nColl = sqlite3Strlen30(zColl) + 1; |
| 84922 | assert( nExtra>=nColl ); |
| 84923 | memcpy(zExtra, zColl, nColl); |
| 84924 | zColl = zExtra; |
| 84925 | zExtra += nColl; |
| 84926 | nExtra -= nColl; |
| 84927 | }else{ |
| 84928 | zColl = pTab->aCol[j].zColl; |
| 84929 | if( !zColl ) zColl = "BINARY"; |
| 84930 | } |
| 84931 | if( !db->init.busy && !sqlite3LocateCollSeq(pParse, zColl) ){ |
| 84932 | goto exit_create_index; |
| 84933 | } |
| 84934 | pIndex->azColl[i] = zColl; |
| @@ -108986,10 +109096,14 @@ | |
| 109096 | ** |
| 109097 | ** Actually, each subexpression is converted to "xN AND w" where w is |
| 109098 | ** the "interesting" terms of z - terms that did not originate in the |
| 109099 | ** ON or USING clause of a LEFT JOIN, and terms that are usable as |
| 109100 | ** indices. |
| 109101 | ** |
| 109102 | ** This optimization also only applies if the (x1 OR x2 OR ...) term |
| 109103 | ** is not contained in the ON clause of a LEFT JOIN. |
| 109104 | ** See ticket http://www.sqlite.org/src/info/f2369304e4 |
| 109105 | */ |
| 109106 | if( pWC->nTerm>1 ){ |
| 109107 | int iTerm; |
| 109108 | for(iTerm=0; iTerm<pWC->nTerm; iTerm++){ |
| 109109 | Expr *pExpr = pWC->a[iTerm].pExpr; |
| @@ -109007,11 +109121,11 @@ | |
| 109121 | for(ii=0; ii<pOrWc->nTerm; ii++){ |
| 109122 | WhereTerm *pOrTerm = &pOrWc->a[ii]; |
| 109123 | if( pOrTerm->leftCursor==iCur || (pOrTerm->eOperator & WO_AND)!=0 ){ |
| 109124 | WhereInfo *pSubWInfo; /* Info for single OR-term scan */ |
| 109125 | Expr *pOrExpr = pOrTerm->pExpr; |
| 109126 | if( pAndExpr && !ExprHasProperty(pOrExpr, EP_FromJoin) ){ |
| 109127 | pAndExpr->pLeft = pOrExpr; |
| 109128 | pOrExpr = pAndExpr; |
| 109129 | } |
| 109130 | /* Loop through table entries that match term pOrTerm. */ |
| 109131 | pSubWInfo = sqlite3WhereBegin(pParse, pOrTab, pOrExpr, 0, 0, |
| @@ -115513,10 +115627,16 @@ | |
| 115627 | "statements or unfinished backups"); |
| 115628 | sqlite3_mutex_leave(db->mutex); |
| 115629 | return SQLITE_BUSY; |
| 115630 | } |
| 115631 | |
| 115632 | /* If a transaction is open, roll it back. This also ensures that if |
| 115633 | ** any database schemas have been modified by the current transaction |
| 115634 | ** they are reset. And that the required b-tree mutex is held to make |
| 115635 | ** the the pager rollback and schema reset an atomic operation. */ |
| 115636 | sqlite3RollbackAll(db, SQLITE_OK); |
| 115637 | |
| 115638 | #ifdef SQLITE_ENABLE_SQLLOG |
| 115639 | if( sqlite3GlobalConfig.xSqllog ){ |
| 115640 | /* Closing the handle. Fourth parameter is passed the value 2. */ |
| 115641 | sqlite3GlobalConfig.xSqllog(sqlite3GlobalConfig.pSqllogArg, db, 0, 2); |
| 115642 | } |
| @@ -115667,10 +115787,11 @@ | |
| 115787 | SQLITE_PRIVATE void sqlite3RollbackAll(sqlite3 *db, int tripCode){ |
| 115788 | int i; |
| 115789 | int inTrans = 0; |
| 115790 | assert( sqlite3_mutex_held(db->mutex) ); |
| 115791 | sqlite3BeginBenignMalloc(); |
| 115792 | sqlite3BtreeEnterAll(db); |
| 115793 | for(i=0; i<db->nDb; i++){ |
| 115794 | Btree *p = db->aDb[i].pBt; |
| 115795 | if( p ){ |
| 115796 | if( sqlite3BtreeIsInTrans(p) ){ |
| 115797 | inTrans = 1; |
| @@ -115684,10 +115805,11 @@ | |
| 115805 | |
| 115806 | if( (db->flags&SQLITE_InternChanges)!=0 && db->init.busy==0 ){ |
| 115807 | sqlite3ExpirePreparedStatements(db); |
| 115808 | sqlite3ResetAllSchemasOfConnection(db); |
| 115809 | } |
| 115810 | sqlite3BtreeLeaveAll(db); |
| 115811 | |
| 115812 | /* Any deferred constraint violations have now been resolved. */ |
| 115813 | db->nDeferredCons = 0; |
| 115814 | |
| 115815 | /* If one has been configured, invoke the rollback-hook callback */ |
| @@ -115694,10 +115816,114 @@ | |
| 115816 | if( db->xRollbackCallback && (inTrans || !db->autoCommit) ){ |
| 115817 | db->xRollbackCallback(db->pRollbackArg); |
| 115818 | } |
| 115819 | } |
| 115820 | |
| 115821 | /* |
| 115822 | ** Return a static string containing the name corresponding to the error code |
| 115823 | ** specified in the argument. |
| 115824 | */ |
| 115825 | #if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) || \ |
| 115826 | defined(SQLITE_DEBUG_OS_TRACE) |
| 115827 | SQLITE_PRIVATE const char *sqlite3ErrName(int rc){ |
| 115828 | const char *zName = 0; |
| 115829 | int i, origRc = rc; |
| 115830 | for(i=0; i<2 && zName==0; i++, rc &= 0xff){ |
| 115831 | switch( rc ){ |
| 115832 | case SQLITE_OK: zName = "SQLITE_OK"; break; |
| 115833 | case SQLITE_ERROR: zName = "SQLITE_ERROR"; break; |
| 115834 | case SQLITE_INTERNAL: zName = "SQLITE_INTERNAL"; break; |
| 115835 | case SQLITE_PERM: zName = "SQLITE_PERM"; break; |
| 115836 | case SQLITE_ABORT: zName = "SQLITE_ABORT"; break; |
| 115837 | case SQLITE_ABORT_ROLLBACK: zName = "SQLITE_ABORT_ROLLBACK"; break; |
| 115838 | case SQLITE_BUSY: zName = "SQLITE_BUSY"; break; |
| 115839 | case SQLITE_BUSY_RECOVERY: zName = "SQLITE_BUSY_RECOVERY"; break; |
| 115840 | case SQLITE_LOCKED: zName = "SQLITE_LOCKED"; break; |
| 115841 | case SQLITE_LOCKED_SHAREDCACHE: zName = "SQLITE_LOCKED_SHAREDCACHE";break; |
| 115842 | case SQLITE_NOMEM: zName = "SQLITE_NOMEM"; break; |
| 115843 | case SQLITE_READONLY: zName = "SQLITE_READONLY"; break; |
| 115844 | case SQLITE_READONLY_RECOVERY: zName = "SQLITE_READONLY_RECOVERY"; break; |
| 115845 | case SQLITE_READONLY_CANTLOCK: zName = "SQLITE_READONLY_CANTLOCK"; break; |
| 115846 | case SQLITE_READONLY_ROLLBACK: zName = "SQLITE_READONLY_ROLLBACK"; break; |
| 115847 | case SQLITE_INTERRUPT: zName = "SQLITE_INTERRUPT"; break; |
| 115848 | case SQLITE_IOERR: zName = "SQLITE_IOERR"; break; |
| 115849 | case SQLITE_IOERR_READ: zName = "SQLITE_IOERR_READ"; break; |
| 115850 | case SQLITE_IOERR_SHORT_READ: zName = "SQLITE_IOERR_SHORT_READ"; break; |
| 115851 | case SQLITE_IOERR_WRITE: zName = "SQLITE_IOERR_WRITE"; break; |
| 115852 | case SQLITE_IOERR_FSYNC: zName = "SQLITE_IOERR_FSYNC"; break; |
| 115853 | case SQLITE_IOERR_DIR_FSYNC: zName = "SQLITE_IOERR_DIR_FSYNC"; break; |
| 115854 | case SQLITE_IOERR_TRUNCATE: zName = "SQLITE_IOERR_TRUNCATE"; break; |
| 115855 | case SQLITE_IOERR_FSTAT: zName = "SQLITE_IOERR_FSTAT"; break; |
| 115856 | case SQLITE_IOERR_UNLOCK: zName = "SQLITE_IOERR_UNLOCK"; break; |
| 115857 | case SQLITE_IOERR_RDLOCK: zName = "SQLITE_IOERR_RDLOCK"; break; |
| 115858 | case SQLITE_IOERR_DELETE: zName = "SQLITE_IOERR_DELETE"; break; |
| 115859 | case SQLITE_IOERR_BLOCKED: zName = "SQLITE_IOERR_BLOCKED"; break; |
| 115860 | case SQLITE_IOERR_NOMEM: zName = "SQLITE_IOERR_NOMEM"; break; |
| 115861 | case SQLITE_IOERR_ACCESS: zName = "SQLITE_IOERR_ACCESS"; break; |
| 115862 | case SQLITE_IOERR_CHECKRESERVEDLOCK: |
| 115863 | zName = "SQLITE_IOERR_CHECKRESERVEDLOCK"; break; |
| 115864 | case SQLITE_IOERR_LOCK: zName = "SQLITE_IOERR_LOCK"; break; |
| 115865 | case SQLITE_IOERR_CLOSE: zName = "SQLITE_IOERR_CLOSE"; break; |
| 115866 | case SQLITE_IOERR_DIR_CLOSE: zName = "SQLITE_IOERR_DIR_CLOSE"; break; |
| 115867 | case SQLITE_IOERR_SHMOPEN: zName = "SQLITE_IOERR_SHMOPEN"; break; |
| 115868 | case SQLITE_IOERR_SHMSIZE: zName = "SQLITE_IOERR_SHMSIZE"; break; |
| 115869 | case SQLITE_IOERR_SHMLOCK: zName = "SQLITE_IOERR_SHMLOCK"; break; |
| 115870 | case SQLITE_IOERR_SHMMAP: zName = "SQLITE_IOERR_SHMMAP"; break; |
| 115871 | case SQLITE_IOERR_SEEK: zName = "SQLITE_IOERR_SEEK"; break; |
| 115872 | case SQLITE_IOERR_DELETE_NOENT: zName = "SQLITE_IOERR_DELETE_NOENT";break; |
| 115873 | case SQLITE_IOERR_MMAP: zName = "SQLITE_IOERR_MMAP"; break; |
| 115874 | case SQLITE_CORRUPT: zName = "SQLITE_CORRUPT"; break; |
| 115875 | case SQLITE_CORRUPT_VTAB: zName = "SQLITE_CORRUPT_VTAB"; break; |
| 115876 | case SQLITE_NOTFOUND: zName = "SQLITE_NOTFOUND"; break; |
| 115877 | case SQLITE_FULL: zName = "SQLITE_FULL"; break; |
| 115878 | case SQLITE_CANTOPEN: zName = "SQLITE_CANTOPEN"; break; |
| 115879 | case SQLITE_CANTOPEN_NOTEMPDIR: zName = "SQLITE_CANTOPEN_NOTEMPDIR";break; |
| 115880 | case SQLITE_CANTOPEN_ISDIR: zName = "SQLITE_CANTOPEN_ISDIR"; break; |
| 115881 | case SQLITE_CANTOPEN_FULLPATH: zName = "SQLITE_CANTOPEN_FULLPATH"; break; |
| 115882 | case SQLITE_PROTOCOL: zName = "SQLITE_PROTOCOL"; break; |
| 115883 | case SQLITE_EMPTY: zName = "SQLITE_EMPTY"; break; |
| 115884 | case SQLITE_SCHEMA: zName = "SQLITE_SCHEMA"; break; |
| 115885 | case SQLITE_TOOBIG: zName = "SQLITE_TOOBIG"; break; |
| 115886 | case SQLITE_CONSTRAINT: zName = "SQLITE_CONSTRAINT"; break; |
| 115887 | case SQLITE_CONSTRAINT_UNIQUE: zName = "SQLITE_CONSTRAINT_UNIQUE"; break; |
| 115888 | case SQLITE_CONSTRAINT_TRIGGER: zName = "SQLITE_CONSTRAINT_TRIGGER";break; |
| 115889 | case SQLITE_CONSTRAINT_FOREIGNKEY: |
| 115890 | zName = "SQLITE_CONSTRAINT_FOREIGNKEY"; break; |
| 115891 | case SQLITE_CONSTRAINT_CHECK: zName = "SQLITE_CONSTRAINT_CHECK"; break; |
| 115892 | case SQLITE_CONSTRAINT_PRIMARYKEY: |
| 115893 | zName = "SQLITE_CONSTRAINT_PRIMARYKEY"; break; |
| 115894 | case SQLITE_CONSTRAINT_NOTNULL: zName = "SQLITE_CONSTRAINT_NOTNULL";break; |
| 115895 | case SQLITE_CONSTRAINT_COMMITHOOK: |
| 115896 | zName = "SQLITE_CONSTRAINT_COMMITHOOK"; break; |
| 115897 | case SQLITE_CONSTRAINT_VTAB: zName = "SQLITE_CONSTRAINT_VTAB"; break; |
| 115898 | case SQLITE_CONSTRAINT_FUNCTION: |
| 115899 | zName = "SQLITE_CONSTRAINT_FUNCTION"; break; |
| 115900 | case SQLITE_MISMATCH: zName = "SQLITE_MISMATCH"; break; |
| 115901 | case SQLITE_MISUSE: zName = "SQLITE_MISUSE"; break; |
| 115902 | case SQLITE_NOLFS: zName = "SQLITE_NOLFS"; break; |
| 115903 | case SQLITE_AUTH: zName = "SQLITE_AUTH"; break; |
| 115904 | case SQLITE_FORMAT: zName = "SQLITE_FORMAT"; break; |
| 115905 | case SQLITE_RANGE: zName = "SQLITE_RANGE"; break; |
| 115906 | case SQLITE_NOTADB: zName = "SQLITE_NOTADB"; break; |
| 115907 | case SQLITE_ROW: zName = "SQLITE_ROW"; break; |
| 115908 | case SQLITE_NOTICE: zName = "SQLITE_NOTICE"; break; |
| 115909 | case SQLITE_NOTICE_RECOVER_WAL: zName = "SQLITE_NOTICE_RECOVER_WAL";break; |
| 115910 | case SQLITE_NOTICE_RECOVER_ROLLBACK: |
| 115911 | zName = "SQLITE_NOTICE_RECOVER_ROLLBACK"; break; |
| 115912 | case SQLITE_WARNING: zName = "SQLITE_WARNING"; break; |
| 115913 | case SQLITE_DONE: zName = "SQLITE_DONE"; break; |
| 115914 | } |
| 115915 | } |
| 115916 | if( zName==0 ){ |
| 115917 | static char zBuf[50]; |
| 115918 | sqlite3_snprintf(sizeof(zBuf), zBuf, "SQLITE_UNKNOWN(%d)", origRc); |
| 115919 | zName = zBuf; |
| 115920 | } |
| 115921 | return zName; |
| 115922 | } |
| 115923 | #endif |
| 115924 | |
| 115925 | /* |
| 115926 | ** Return a static string that describes the kind of error specified in the |
| 115927 | ** argument. |
| 115928 | */ |
| 115929 | SQLITE_PRIVATE const char *sqlite3ErrStr(int rc){ |
| 115930 |
+1
-1
| --- src/sqlite3.h | ||
| +++ src/sqlite3.h | ||
| @@ -107,11 +107,11 @@ | ||
| 107 | 107 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 108 | 108 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 109 | 109 | */ |
| 110 | 110 | #define SQLITE_VERSION "3.7.17" |
| 111 | 111 | #define SQLITE_VERSION_NUMBER 3007017 |
| 112 | -#define SQLITE_SOURCE_ID "2013-05-08 17:06:28 1fa8c457394c94864f7584e4c893ec09e685fba4" | |
| 112 | +#define SQLITE_SOURCE_ID "2013-05-15 18:34:17 00231fb0127960d700de3549e34e82f8ec1b5819" | |
| 113 | 113 | |
| 114 | 114 | /* |
| 115 | 115 | ** CAPI3REF: Run-Time Library Version Numbers |
| 116 | 116 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 117 | 117 | ** |
| 118 | 118 |
| --- src/sqlite3.h | |
| +++ src/sqlite3.h | |
| @@ -107,11 +107,11 @@ | |
| 107 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 108 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 109 | */ |
| 110 | #define SQLITE_VERSION "3.7.17" |
| 111 | #define SQLITE_VERSION_NUMBER 3007017 |
| 112 | #define SQLITE_SOURCE_ID "2013-05-08 17:06:28 1fa8c457394c94864f7584e4c893ec09e685fba4" |
| 113 | |
| 114 | /* |
| 115 | ** CAPI3REF: Run-Time Library Version Numbers |
| 116 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 117 | ** |
| 118 |
| --- src/sqlite3.h | |
| +++ src/sqlite3.h | |
| @@ -107,11 +107,11 @@ | |
| 107 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 108 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 109 | */ |
| 110 | #define SQLITE_VERSION "3.7.17" |
| 111 | #define SQLITE_VERSION_NUMBER 3007017 |
| 112 | #define SQLITE_SOURCE_ID "2013-05-15 18:34:17 00231fb0127960d700de3549e34e82f8ec1b5819" |
| 113 | |
| 114 | /* |
| 115 | ** CAPI3REF: Run-Time Library Version Numbers |
| 116 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 117 | ** |
| 118 |