| | @@ -1,8 +1,8 @@ |
| 1 | 1 | /****************************************************************************** |
| 2 | 2 | ** This file is an amalgamation of many separate C source files from SQLite |
| 3 | | -** version 3.8.0.1. By combining all the individual C code files into this |
| 3 | +** version 3.8.1. By combining all the individual C code files into this |
| 4 | 4 | ** single large file, the entire code can be compiled as a single translation |
| 5 | 5 | ** unit. This allows many compilers to do optimizations that would not be |
| 6 | 6 | ** possible if the files were compiled separately. Performance improvements |
| 7 | 7 | ** of 5% or more are commonly seen when SQLite is compiled as a single |
| 8 | 8 | ** translation unit. |
| | @@ -654,13 +654,13 @@ |
| 654 | 654 | ** |
| 655 | 655 | ** See also: [sqlite3_libversion()], |
| 656 | 656 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 657 | 657 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 658 | 658 | */ |
| 659 | | -#define SQLITE_VERSION "3.8.0.1" |
| 660 | | -#define SQLITE_VERSION_NUMBER 3008000 |
| 661 | | -#define SQLITE_SOURCE_ID "2013-08-29 13:47:05 c5857808c0707baa30994dd6aa3b9c93a74c0073" |
| 659 | +#define SQLITE_VERSION "3.8.1" |
| 660 | +#define SQLITE_VERSION_NUMBER 3008001 |
| 661 | +#define SQLITE_SOURCE_ID "2013-09-04 04:04:08 8df95bb0b3f72222cf262174247a467c234f9939" |
| 662 | 662 | |
| 663 | 663 | /* |
| 664 | 664 | ** CAPI3REF: Run-Time Library Version Numbers |
| 665 | 665 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 666 | 666 | ** |
| | @@ -1026,16 +1026,18 @@ |
| 1026 | 1026 | #define SQLITE_IOERR_SHMMAP (SQLITE_IOERR | (21<<8)) |
| 1027 | 1027 | #define SQLITE_IOERR_SEEK (SQLITE_IOERR | (22<<8)) |
| 1028 | 1028 | #define SQLITE_IOERR_DELETE_NOENT (SQLITE_IOERR | (23<<8)) |
| 1029 | 1029 | #define SQLITE_IOERR_MMAP (SQLITE_IOERR | (24<<8)) |
| 1030 | 1030 | #define SQLITE_IOERR_GETTEMPPATH (SQLITE_IOERR | (25<<8)) |
| 1031 | +#define SQLITE_IOERR_CONVPATH (SQLITE_IOERR | (26<<8)) |
| 1031 | 1032 | #define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8)) |
| 1032 | 1033 | #define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8)) |
| 1033 | 1034 | #define SQLITE_BUSY_SNAPSHOT (SQLITE_BUSY | (2<<8)) |
| 1034 | 1035 | #define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8)) |
| 1035 | 1036 | #define SQLITE_CANTOPEN_ISDIR (SQLITE_CANTOPEN | (2<<8)) |
| 1036 | 1037 | #define SQLITE_CANTOPEN_FULLPATH (SQLITE_CANTOPEN | (3<<8)) |
| 1038 | +#define SQLITE_CANTOPEN_CONVPATH (SQLITE_CANTOPEN | (4<<8)) |
| 1037 | 1039 | #define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8)) |
| 1038 | 1040 | #define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8)) |
| 1039 | 1041 | #define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8)) |
| 1040 | 1042 | #define SQLITE_READONLY_ROLLBACK (SQLITE_READONLY | (3<<8)) |
| 1041 | 1043 | #define SQLITE_ABORT_ROLLBACK (SQLITE_ABORT | (2<<8)) |
| | @@ -8368,10 +8370,24 @@ |
| 8368 | 8370 | #if SQLITE_DEFAULT_MMAP_SIZE>SQLITE_MAX_MMAP_SIZE |
| 8369 | 8371 | # undef SQLITE_DEFAULT_MMAP_SIZE |
| 8370 | 8372 | # define SQLITE_DEFAULT_MMAP_SIZE SQLITE_MAX_MMAP_SIZE |
| 8371 | 8373 | #endif |
| 8372 | 8374 | |
| 8375 | +/* |
| 8376 | +** Only one of SQLITE_ENABLE_STAT3 or SQLITE_ENABLE_STAT4 can be defined. |
| 8377 | +** Priority is given to SQLITE_ENABLE_STAT4. If either are defined, also |
| 8378 | +** define SQLITE_ENABLE_STAT3_OR_STAT4 |
| 8379 | +*/ |
| 8380 | +#ifdef SQLITE_ENABLE_STAT4 |
| 8381 | +# undef SQLITE_ENABLE_STAT3 |
| 8382 | +# define SQLITE_ENABLE_STAT3_OR_STAT4 1 |
| 8383 | +#elif SQLITE_ENABLE_STAT3 |
| 8384 | +# define SQLITE_ENABLE_STAT3_OR_STAT4 1 |
| 8385 | +#elif SQLITE_ENABLE_STAT3_OR_STAT4 |
| 8386 | +# undef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 8387 | +#endif |
| 8388 | + |
| 8373 | 8389 | /* |
| 8374 | 8390 | ** An instance of the following structure is used to store the busy-handler |
| 8375 | 8391 | ** callback for a given sqlite handle. |
| 8376 | 8392 | ** |
| 8377 | 8393 | ** The sqlite.busyHandler member of the sqlite struct contains the busy |
| | @@ -10770,13 +10786,14 @@ |
| 10770 | 10786 | u16 nColumn; /* Number of columns in table used by this index */ |
| 10771 | 10787 | u8 onError; /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */ |
| 10772 | 10788 | unsigned autoIndex:2; /* 1==UNIQUE, 2==PRIMARY KEY, 0==CREATE INDEX */ |
| 10773 | 10789 | unsigned bUnordered:1; /* Use this index for == or IN queries only */ |
| 10774 | 10790 | unsigned uniqNotNull:1; /* True if UNIQUE and NOT NULL for all columns */ |
| 10775 | | -#ifdef SQLITE_ENABLE_STAT3 |
| 10791 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 10776 | 10792 | int nSample; /* Number of elements in aSample[] */ |
| 10777 | | - tRowcnt avgEq; /* Average nEq value for key values not in aSample */ |
| 10793 | + int nSampleCol; /* Size of IndexSample.anEq[] and so on */ |
| 10794 | + tRowcnt *aAvgEq; /* Average nEq values for keys not in aSample */ |
| 10778 | 10795 | IndexSample *aSample; /* Samples of the left-most key */ |
| 10779 | 10796 | #endif |
| 10780 | 10797 | }; |
| 10781 | 10798 | |
| 10782 | 10799 | /* |
| | @@ -10783,20 +10800,15 @@ |
| 10783 | 10800 | ** Each sample stored in the sqlite_stat3 table is represented in memory |
| 10784 | 10801 | ** using a structure of this type. See documentation at the top of the |
| 10785 | 10802 | ** analyze.c source file for additional information. |
| 10786 | 10803 | */ |
| 10787 | 10804 | struct IndexSample { |
| 10788 | | - union { |
| 10789 | | - char *z; /* Value if eType is SQLITE_TEXT or SQLITE_BLOB */ |
| 10790 | | - double r; /* Value if eType is SQLITE_FLOAT */ |
| 10791 | | - i64 i; /* Value if eType is SQLITE_INTEGER */ |
| 10792 | | - } u; |
| 10793 | | - u8 eType; /* SQLITE_NULL, SQLITE_INTEGER ... etc. */ |
| 10794 | | - int nByte; /* Size in byte of text or blob. */ |
| 10795 | | - tRowcnt nEq; /* Est. number of rows where the key equals this sample */ |
| 10796 | | - tRowcnt nLt; /* Est. number of rows where key is less than this sample */ |
| 10797 | | - tRowcnt nDLt; /* Est. number of distinct keys less than this sample */ |
| 10805 | + void *p; /* Pointer to sampled record */ |
| 10806 | + int n; /* Size of record in bytes */ |
| 10807 | + tRowcnt *anEq; /* Est. number of rows where the key equals this sample */ |
| 10808 | + tRowcnt *anLt; /* Est. number of rows where key is less than this sample */ |
| 10809 | + tRowcnt *anDLt; /* Est. number of distinct keys less than this sample */ |
| 10798 | 10810 | }; |
| 10799 | 10811 | |
| 10800 | 10812 | /* |
| 10801 | 10813 | ** Each token coming out of the lexer is an instance of |
| 10802 | 10814 | ** this structure. Tokens are also used as part of an expression. |
| | @@ -12264,13 +12276,10 @@ |
| 12264 | 12276 | SQLITE_PRIVATE void sqlite3ValueSetStr(sqlite3_value*, int, const void *,u8, |
| 12265 | 12277 | void(*)(void*)); |
| 12266 | 12278 | SQLITE_PRIVATE void sqlite3ValueFree(sqlite3_value*); |
| 12267 | 12279 | SQLITE_PRIVATE sqlite3_value *sqlite3ValueNew(sqlite3 *); |
| 12268 | 12280 | SQLITE_PRIVATE char *sqlite3Utf16to8(sqlite3 *, const void*, int, u8); |
| 12269 | | -#ifdef SQLITE_ENABLE_STAT3 |
| 12270 | | -SQLITE_PRIVATE char *sqlite3Utf8to16(sqlite3 *, u8, char *, int, int *); |
| 12271 | | -#endif |
| 12272 | 12281 | SQLITE_PRIVATE int sqlite3ValueFromExpr(sqlite3 *, Expr *, u8, u8, sqlite3_value **); |
| 12273 | 12282 | SQLITE_PRIVATE void sqlite3ValueApplyAffinity(sqlite3_value *, u8, u8); |
| 12274 | 12283 | #ifndef SQLITE_AMALGAMATION |
| 12275 | 12284 | SQLITE_PRIVATE const unsigned char sqlite3OpcodeProperty[]; |
| 12276 | 12285 | SQLITE_PRIVATE const unsigned char sqlite3UpperToLower[]; |
| | @@ -12332,10 +12341,16 @@ |
| 12332 | 12341 | SQLITE_PRIVATE void sqlite3SelectDestInit(SelectDest*,int,int); |
| 12333 | 12342 | SQLITE_PRIVATE Expr *sqlite3CreateColumnExpr(sqlite3 *, SrcList *, int, int); |
| 12334 | 12343 | |
| 12335 | 12344 | SQLITE_PRIVATE void sqlite3BackupRestart(sqlite3_backup *); |
| 12336 | 12345 | SQLITE_PRIVATE void sqlite3BackupUpdate(sqlite3_backup *, Pgno, const u8 *); |
| 12346 | + |
| 12347 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 12348 | +SQLITE_PRIVATE void sqlite3AnalyzeFunctions(void); |
| 12349 | +SQLITE_PRIVATE int sqlite3Stat4ProbeSetValue(Parse*,Index*,UnpackedRecord**,Expr*,u8,int,int*); |
| 12350 | +SQLITE_PRIVATE void sqlite3Stat4ProbeFree(UnpackedRecord*); |
| 12351 | +#endif |
| 12337 | 12352 | |
| 12338 | 12353 | /* |
| 12339 | 12354 | ** The interface to the LEMON-generated parser |
| 12340 | 12355 | */ |
| 12341 | 12356 | SQLITE_PRIVATE void *sqlite3ParserAlloc(void*(*)(size_t)); |
| | @@ -12916,11 +12931,13 @@ |
| 12916 | 12931 | "ENABLE_OVERSIZE_CELL_CHECK", |
| 12917 | 12932 | #endif |
| 12918 | 12933 | #ifdef SQLITE_ENABLE_RTREE |
| 12919 | 12934 | "ENABLE_RTREE", |
| 12920 | 12935 | #endif |
| 12921 | | -#ifdef SQLITE_ENABLE_STAT3 |
| 12936 | +#if defined(SQLITE_ENABLE_STAT4) |
| 12937 | + "ENABLE_STAT4", |
| 12938 | +#elif defined(SQLITE_ENABLE_STAT3) |
| 12922 | 12939 | "ENABLE_STAT3", |
| 12923 | 12940 | #endif |
| 12924 | 12941 | #ifdef SQLITE_ENABLE_UNLOCK_NOTIFY |
| 12925 | 12942 | "ENABLE_UNLOCK_NOTIFY", |
| 12926 | 12943 | #endif |
| | @@ -16075,11 +16092,11 @@ |
| 16075 | 16092 | struct MemBlockHdr *pHdr; |
| 16076 | 16093 | if( !p ){ |
| 16077 | 16094 | return 0; |
| 16078 | 16095 | } |
| 16079 | 16096 | pHdr = sqlite3MemsysGetHeader(p); |
| 16080 | | - return pHdr->iSize; |
| 16097 | + return (int)pHdr->iSize; |
| 16081 | 16098 | } |
| 16082 | 16099 | |
| 16083 | 16100 | /* |
| 16084 | 16101 | ** Initialize the memory allocation subsystem. |
| 16085 | 16102 | */ |
| | @@ -16117,19 +16134,19 @@ |
| 16117 | 16134 | static void randomFill(char *pBuf, int nByte){ |
| 16118 | 16135 | unsigned int x, y, r; |
| 16119 | 16136 | x = SQLITE_PTR_TO_INT(pBuf); |
| 16120 | 16137 | y = nByte | 1; |
| 16121 | 16138 | while( nByte >= 4 ){ |
| 16122 | | - x = (x>>1) ^ (-(x&1) & 0xd0000001); |
| 16139 | + x = (x>>1) ^ (-(int)(x&1) & 0xd0000001); |
| 16123 | 16140 | y = y*1103515245 + 12345; |
| 16124 | 16141 | r = x ^ y; |
| 16125 | 16142 | *(int*)pBuf = r; |
| 16126 | 16143 | pBuf += 4; |
| 16127 | 16144 | nByte -= 4; |
| 16128 | 16145 | } |
| 16129 | 16146 | while( nByte-- > 0 ){ |
| 16130 | | - x = (x>>1) ^ (-(x&1) & 0xd0000001); |
| 16147 | + x = (x>>1) ^ (-(int)(x&1) & 0xd0000001); |
| 16131 | 16148 | y = y*1103515245 + 12345; |
| 16132 | 16149 | r = x ^ y; |
| 16133 | 16150 | *(pBuf++) = r & 0xff; |
| 16134 | 16151 | } |
| 16135 | 16152 | } |
| | @@ -16220,13 +16237,13 @@ |
| 16220 | 16237 | assert( mem.pLast==pHdr ); |
| 16221 | 16238 | mem.pLast = pHdr->pPrev; |
| 16222 | 16239 | } |
| 16223 | 16240 | z = (char*)pBt; |
| 16224 | 16241 | z -= pHdr->nTitle; |
| 16225 | | - adjustStats(pHdr->iSize, -1); |
| 16242 | + adjustStats((int)pHdr->iSize, -1); |
| 16226 | 16243 | randomFill(z, sizeof(void*)*pHdr->nBacktraceSlots + sizeof(*pHdr) + |
| 16227 | | - pHdr->iSize + sizeof(int) + pHdr->nTitle); |
| 16244 | + (int)pHdr->iSize + sizeof(int) + pHdr->nTitle); |
| 16228 | 16245 | free(z); |
| 16229 | 16246 | sqlite3_mutex_leave(mem.mutex); |
| 16230 | 16247 | } |
| 16231 | 16248 | |
| 16232 | 16249 | /* |
| | @@ -16244,13 +16261,13 @@ |
| 16244 | 16261 | assert( mem.disallow==0 ); |
| 16245 | 16262 | assert( (nByte & 7)==0 ); /* EV: R-46199-30249 */ |
| 16246 | 16263 | pOldHdr = sqlite3MemsysGetHeader(pPrior); |
| 16247 | 16264 | pNew = sqlite3MemMalloc(nByte); |
| 16248 | 16265 | if( pNew ){ |
| 16249 | | - memcpy(pNew, pPrior, nByte<pOldHdr->iSize ? nByte : pOldHdr->iSize); |
| 16266 | + memcpy(pNew, pPrior, (int)(nByte<pOldHdr->iSize ? nByte : pOldHdr->iSize)); |
| 16250 | 16267 | if( nByte>pOldHdr->iSize ){ |
| 16251 | | - randomFill(&((char*)pNew)[pOldHdr->iSize], nByte - pOldHdr->iSize); |
| 16268 | + randomFill(&((char*)pNew)[pOldHdr->iSize], nByte - (int)pOldHdr->iSize); |
| 16252 | 16269 | } |
| 16253 | 16270 | sqlite3MemFree(pPrior); |
| 16254 | 16271 | } |
| 16255 | 16272 | return pNew; |
| 16256 | 16273 | } |
| | @@ -16361,11 +16378,11 @@ |
| 16361 | 16378 | SQLITE_PRIVATE void sqlite3MemdebugSync(){ |
| 16362 | 16379 | struct MemBlockHdr *pHdr; |
| 16363 | 16380 | for(pHdr=mem.pFirst; pHdr; pHdr=pHdr->pNext){ |
| 16364 | 16381 | void **pBt = (void**)pHdr; |
| 16365 | 16382 | pBt -= pHdr->nBacktraceSlots; |
| 16366 | | - mem.xBacktrace(pHdr->iSize, pHdr->nBacktrace-1, &pBt[1]); |
| 16383 | + mem.xBacktrace((int)pHdr->iSize, pHdr->nBacktrace-1, &pBt[1]); |
| 16367 | 16384 | } |
| 16368 | 16385 | } |
| 16369 | 16386 | |
| 16370 | 16387 | /* |
| 16371 | 16388 | ** Open the file indicated and write a log of all unfreed memory |
| | @@ -18483,11 +18500,11 @@ |
| 18483 | 18500 | GetVersionEx(&sInfo); |
| 18484 | 18501 | osType = sInfo.dwPlatformId==VER_PLATFORM_WIN32_NT ? 2 : 1; |
| 18485 | 18502 | } |
| 18486 | 18503 | return osType==2; |
| 18487 | 18504 | } |
| 18488 | | -#endif /* SQLITE_OS_WINCE */ |
| 18505 | +#endif /* SQLITE_OS_WINCE || SQLITE_OS_WINRT */ |
| 18489 | 18506 | #endif |
| 18490 | 18507 | |
| 18491 | 18508 | #ifdef SQLITE_DEBUG |
| 18492 | 18509 | /* |
| 18493 | 18510 | ** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are |
| | @@ -18521,11 +18538,11 @@ |
| 18521 | 18538 | /* As winMutexInit() and winMutexEnd() are called as part |
| 18522 | 18539 | ** of the sqlite3_initialize and sqlite3_shutdown() |
| 18523 | 18540 | ** processing, the "interlocked" magic is probably not |
| 18524 | 18541 | ** strictly necessary. |
| 18525 | 18542 | */ |
| 18526 | | -static long winMutex_lock = 0; |
| 18543 | +static LONG winMutex_lock = 0; |
| 18527 | 18544 | |
| 18528 | 18545 | SQLITE_API void sqlite3_win32_sleep(DWORD milliseconds); /* os_win.c */ |
| 18529 | 18546 | |
| 18530 | 18547 | static int winMutexInit(void){ |
| 18531 | 18548 | /* The first to increment to 1 does actual initialization */ |
| | @@ -21082,36 +21099,10 @@ |
| 21082 | 21099 | assert( (m.flags & MEM_Dyn)!=0 || db->mallocFailed ); |
| 21083 | 21100 | assert( m.z || db->mallocFailed ); |
| 21084 | 21101 | return m.z; |
| 21085 | 21102 | } |
| 21086 | 21103 | |
| 21087 | | -/* |
| 21088 | | -** Convert a UTF-8 string to the UTF-16 encoding specified by parameter |
| 21089 | | -** enc. A pointer to the new string is returned, and the value of *pnOut |
| 21090 | | -** is set to the length of the returned string in bytes. The call should |
| 21091 | | -** arrange to call sqlite3DbFree() on the returned pointer when it is |
| 21092 | | -** no longer required. |
| 21093 | | -** |
| 21094 | | -** If a malloc failure occurs, NULL is returned and the db.mallocFailed |
| 21095 | | -** flag set. |
| 21096 | | -*/ |
| 21097 | | -#ifdef SQLITE_ENABLE_STAT3 |
| 21098 | | -SQLITE_PRIVATE char *sqlite3Utf8to16(sqlite3 *db, u8 enc, char *z, int n, int *pnOut){ |
| 21099 | | - Mem m; |
| 21100 | | - memset(&m, 0, sizeof(m)); |
| 21101 | | - m.db = db; |
| 21102 | | - sqlite3VdbeMemSetStr(&m, z, n, SQLITE_UTF8, SQLITE_STATIC); |
| 21103 | | - if( sqlite3VdbeMemTranslate(&m, enc) ){ |
| 21104 | | - assert( db->mallocFailed ); |
| 21105 | | - return 0; |
| 21106 | | - } |
| 21107 | | - assert( m.z==m.zMalloc ); |
| 21108 | | - *pnOut = m.n; |
| 21109 | | - return m.z; |
| 21110 | | -} |
| 21111 | | -#endif |
| 21112 | | - |
| 21113 | 21104 | /* |
| 21114 | 21105 | ** zIn is a UTF-16 encoded unicode string at least nChar characters long. |
| 21115 | 21106 | ** Return the number of bytes in the first nChar unicode characters |
| 21116 | 21107 | ** in pZ. nChar must be non-negative. |
| 21117 | 21108 | */ |
| | @@ -23064,15 +23055,17 @@ |
| 23064 | 23055 | void *lockingContext; /* Locking style specific state */ |
| 23065 | 23056 | UnixUnusedFd *pUnused; /* Pre-allocated UnixUnusedFd */ |
| 23066 | 23057 | const char *zPath; /* Name of the file */ |
| 23067 | 23058 | unixShm *pShm; /* Shared memory segment information */ |
| 23068 | 23059 | int szChunk; /* Configured by FCNTL_CHUNK_SIZE */ |
| 23060 | +#if SQLITE_MAX_MMAP_SIZE>0 |
| 23069 | 23061 | int nFetchOut; /* Number of outstanding xFetch refs */ |
| 23070 | 23062 | sqlite3_int64 mmapSize; /* Usable size of mapping at pMapRegion */ |
| 23071 | 23063 | sqlite3_int64 mmapSizeActual; /* Actual size of mapping at pMapRegion */ |
| 23072 | 23064 | sqlite3_int64 mmapSizeMax; /* Configured FCNTL_MMAP_SIZE value */ |
| 23073 | 23065 | void *pMapRegion; /* Memory mapped region */ |
| 23066 | +#endif |
| 23074 | 23067 | #ifdef __QNXNTO__ |
| 23075 | 23068 | int sectorSize; /* Device sector size */ |
| 23076 | 23069 | int deviceCharacteristics; /* Precomputed device characteristics */ |
| 23077 | 23070 | #endif |
| 23078 | 23071 | #if SQLITE_ENABLE_LOCKING_STYLE |
| | @@ -23503,10 +23496,11 @@ |
| 23503 | 23496 | #define osRmdir ((int(*)(const char*))aSyscall[19].pCurrent) |
| 23504 | 23497 | |
| 23505 | 23498 | { "fchown", (sqlite3_syscall_ptr)posixFchown, 0 }, |
| 23506 | 23499 | #define osFchown ((int(*)(int,uid_t,gid_t))aSyscall[20].pCurrent) |
| 23507 | 23500 | |
| 23501 | +#if !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0 |
| 23508 | 23502 | { "mmap", (sqlite3_syscall_ptr)mmap, 0 }, |
| 23509 | 23503 | #define osMmap ((void*(*)(void*,size_t,int,int,int,off_t))aSyscall[21].pCurrent) |
| 23510 | 23504 | |
| 23511 | 23505 | { "munmap", (sqlite3_syscall_ptr)munmap, 0 }, |
| 23512 | 23506 | #define osMunmap ((void*(*)(void*,size_t))aSyscall[22].pCurrent) |
| | @@ -23515,10 +23509,11 @@ |
| 23515 | 23509 | { "mremap", (sqlite3_syscall_ptr)mremap, 0 }, |
| 23516 | 23510 | #else |
| 23517 | 23511 | { "mremap", (sqlite3_syscall_ptr)0, 0 }, |
| 23518 | 23512 | #endif |
| 23519 | 23513 | #define osMremap ((void*(*)(void*,size_t,size_t,int,...))aSyscall[23].pCurrent) |
| 23514 | +#endif |
| 23520 | 23515 | |
| 23521 | 23516 | }; /* End of the overrideable system calls */ |
| 23522 | 23517 | |
| 23523 | 23518 | /* |
| 23524 | 23519 | ** This is the xSetSystemCall() method of sqlite3_vfs for all of the |
| | @@ -23601,10 +23596,19 @@ |
| 23601 | 23596 | if( aSyscall[i].pCurrent!=0 ) return aSyscall[i].zName; |
| 23602 | 23597 | } |
| 23603 | 23598 | return 0; |
| 23604 | 23599 | } |
| 23605 | 23600 | |
| 23601 | +/* |
| 23602 | +** Do not accept any file descriptor less than this value, in order to avoid |
| 23603 | +** opening database file using file descriptors that are commonly used for |
| 23604 | +** standard input, output, and error. |
| 23605 | +*/ |
| 23606 | +#ifndef SQLITE_MINIMUM_FILE_DESCRIPTOR |
| 23607 | +# define SQLITE_MINIMUM_FILE_DESCRIPTOR 3 |
| 23608 | +#endif |
| 23609 | + |
| 23606 | 23610 | /* |
| 23607 | 23611 | ** Invoke open(). Do so multiple times, until it either succeeds or |
| 23608 | 23612 | ** fails for some reason other than EINTR. |
| 23609 | 23613 | ** |
| 23610 | 23614 | ** If the file creation mode "m" is 0 then set it to the default for |
| | @@ -23621,17 +23625,27 @@ |
| 23621 | 23625 | ** recover the hot journals. |
| 23622 | 23626 | */ |
| 23623 | 23627 | static int robust_open(const char *z, int f, mode_t m){ |
| 23624 | 23628 | int fd; |
| 23625 | 23629 | mode_t m2 = m ? m : SQLITE_DEFAULT_FILE_PERMISSIONS; |
| 23626 | | - do{ |
| 23630 | + while(1){ |
| 23627 | 23631 | #if defined(O_CLOEXEC) |
| 23628 | 23632 | fd = osOpen(z,f|O_CLOEXEC,m2); |
| 23629 | 23633 | #else |
| 23630 | 23634 | fd = osOpen(z,f,m2); |
| 23631 | 23635 | #endif |
| 23632 | | - }while( fd<0 && errno==EINTR ); |
| 23636 | + if( fd<0 ){ |
| 23637 | + if( errno==EINTR ) continue; |
| 23638 | + break; |
| 23639 | + } |
| 23640 | + if( fd>=SQLITE_MINIMUM_FILE_DESCRIPTOR ) break; |
| 23641 | + osClose(fd); |
| 23642 | + sqlite3_log(SQLITE_WARNING, |
| 23643 | + "attempt to open \"%s\" as file descriptor %d", z, fd); |
| 23644 | + fd = -1; |
| 23645 | + if( osOpen("/dev/null", f, m)<0 ) break; |
| 23646 | + } |
| 23633 | 23647 | if( fd>=0 ){ |
| 23634 | 23648 | if( m!=0 ){ |
| 23635 | 23649 | struct stat statbuf; |
| 23636 | 23650 | if( osFstat(fd, &statbuf)==0 |
| 23637 | 23651 | && statbuf.st_size==0 |
| | @@ -24925,12 +24939,14 @@ |
| 24925 | 24939 | static int unixUnlock(sqlite3_file *id, int eFileLock){ |
| 24926 | 24940 | assert( eFileLock==SHARED_LOCK || ((unixFile *)id)->nFetchOut==0 ); |
| 24927 | 24941 | return posixUnlock(id, eFileLock, 0); |
| 24928 | 24942 | } |
| 24929 | 24943 | |
| 24944 | +#if SQLITE_MAX_MMAP_SIZE>0 |
| 24930 | 24945 | static int unixMapfile(unixFile *pFd, i64 nByte); |
| 24931 | 24946 | static void unixUnmapfile(unixFile *pFd); |
| 24947 | +#endif |
| 24932 | 24948 | |
| 24933 | 24949 | /* |
| 24934 | 24950 | ** This function performs the parts of the "close file" operation |
| 24935 | 24951 | ** common to all locking schemes. It closes the directory and file |
| 24936 | 24952 | ** handles, if they are valid, and sets all fields of the unixFile |
| | @@ -24940,11 +24956,13 @@ |
| 24940 | 24956 | ** even on VxWorks. A mutex will be acquired on VxWorks by the |
| 24941 | 24957 | ** vxworksReleaseFileId() routine. |
| 24942 | 24958 | */ |
| 24943 | 24959 | static int closeUnixFile(sqlite3_file *id){ |
| 24944 | 24960 | unixFile *pFile = (unixFile*)id; |
| 24961 | +#if SQLITE_MAX_MMAP_SIZE>0 |
| 24945 | 24962 | unixUnmapfile(pFile); |
| 24963 | +#endif |
| 24946 | 24964 | if( pFile->h>=0 ){ |
| 24947 | 24965 | robust_close(pFile, pFile->h, __LINE__); |
| 24948 | 24966 | pFile->h = -1; |
| 24949 | 24967 | } |
| 24950 | 24968 | #if OS_VXWORKS |
| | @@ -26145,10 +26163,11 @@ |
| 26145 | 26163 | #if (!defined(USE_PREAD) && !defined(USE_PREAD64)) |
| 26146 | 26164 | i64 newOffset; |
| 26147 | 26165 | #endif |
| 26148 | 26166 | TIMER_START; |
| 26149 | 26167 | assert( cnt==(cnt&0x1ffff) ); |
| 26168 | + assert( id->h>2 ); |
| 26150 | 26169 | cnt &= 0x1ffff; |
| 26151 | 26170 | do{ |
| 26152 | 26171 | #if defined(USE_PREAD) |
| 26153 | 26172 | got = osPread(id->h, pBuf, cnt, offset); |
| 26154 | 26173 | SimulateIOError( got = -1 ); |
| | @@ -26259,10 +26278,11 @@ |
| 26259 | 26278 | int *piErrno /* OUT: Error number if error occurs */ |
| 26260 | 26279 | ){ |
| 26261 | 26280 | int rc = 0; /* Value returned by system call */ |
| 26262 | 26281 | |
| 26263 | 26282 | assert( nBuf==(nBuf&0x1ffff) ); |
| 26283 | + assert( fd>2 ); |
| 26264 | 26284 | nBuf &= 0x1ffff; |
| 26265 | 26285 | TIMER_START; |
| 26266 | 26286 | |
| 26267 | 26287 | #if defined(USE_PREAD) |
| 26268 | 26288 | do{ rc = osPwrite(fd, pBuf, nBuf, iOff); }while( rc<0 && errno==EINTR ); |
| | @@ -26644,17 +26664,19 @@ |
| 26644 | 26664 | if( pFile->inNormalWrite && nByte==0 ){ |
| 26645 | 26665 | pFile->transCntrChng = 1; |
| 26646 | 26666 | } |
| 26647 | 26667 | #endif |
| 26648 | 26668 | |
| 26669 | +#if SQLITE_MAX_MMAP_SIZE>0 |
| 26649 | 26670 | /* If the file was just truncated to a size smaller than the currently |
| 26650 | 26671 | ** mapped region, reduce the effective mapping size as well. SQLite will |
| 26651 | 26672 | ** use read() and write() to access data beyond this point from now on. |
| 26652 | 26673 | */ |
| 26653 | 26674 | if( nByte<pFile->mmapSize ){ |
| 26654 | 26675 | pFile->mmapSize = nByte; |
| 26655 | 26676 | } |
| 26677 | +#endif |
| 26656 | 26678 | |
| 26657 | 26679 | return SQLITE_OK; |
| 26658 | 26680 | } |
| 26659 | 26681 | } |
| 26660 | 26682 | |
| | @@ -26740,10 +26762,11 @@ |
| 26740 | 26762 | } |
| 26741 | 26763 | #endif |
| 26742 | 26764 | } |
| 26743 | 26765 | } |
| 26744 | 26766 | |
| 26767 | +#if SQLITE_MAX_MMAP_SIZE>0 |
| 26745 | 26768 | if( pFile->mmapSizeMax>0 && nByte>pFile->mmapSize ){ |
| 26746 | 26769 | int rc; |
| 26747 | 26770 | if( pFile->szChunk<=0 ){ |
| 26748 | 26771 | if( robust_ftruncate(pFile->h, nByte) ){ |
| 26749 | 26772 | pFile->lastErrno = errno; |
| | @@ -26752,10 +26775,11 @@ |
| 26752 | 26775 | } |
| 26753 | 26776 | |
| 26754 | 26777 | rc = unixMapfile(pFile, nByte); |
| 26755 | 26778 | return rc; |
| 26756 | 26779 | } |
| 26780 | +#endif |
| 26757 | 26781 | |
| 26758 | 26782 | return SQLITE_OK; |
| 26759 | 26783 | } |
| 26760 | 26784 | |
| 26761 | 26785 | /* |
| | @@ -26820,10 +26844,11 @@ |
| 26820 | 26844 | unixGetTempname(pFile->pVfs->mxPathname, zTFile); |
| 26821 | 26845 | *(char**)pArg = zTFile; |
| 26822 | 26846 | } |
| 26823 | 26847 | return SQLITE_OK; |
| 26824 | 26848 | } |
| 26849 | +#if SQLITE_MAX_MMAP_SIZE>0 |
| 26825 | 26850 | case SQLITE_FCNTL_MMAP_SIZE: { |
| 26826 | 26851 | i64 newLimit = *(i64*)pArg; |
| 26827 | 26852 | int rc = SQLITE_OK; |
| 26828 | 26853 | if( newLimit>sqlite3GlobalConfig.mxMmap ){ |
| 26829 | 26854 | newLimit = sqlite3GlobalConfig.mxMmap; |
| | @@ -26836,10 +26861,11 @@ |
| 26836 | 26861 | rc = unixMapfile(pFile, -1); |
| 26837 | 26862 | } |
| 26838 | 26863 | } |
| 26839 | 26864 | return rc; |
| 26840 | 26865 | } |
| 26866 | +#endif |
| 26841 | 26867 | #ifdef SQLITE_DEBUG |
| 26842 | 26868 | /* The pager calls this method to signal that it has done |
| 26843 | 26869 | ** a rollback and that the database is therefore unchanged and |
| 26844 | 26870 | ** it hence it is OK for the transaction change counter to be |
| 26845 | 26871 | ** unchanged. |
| | @@ -27646,26 +27672,24 @@ |
| 27646 | 27672 | # define unixShmLock 0 |
| 27647 | 27673 | # define unixShmBarrier 0 |
| 27648 | 27674 | # define unixShmUnmap 0 |
| 27649 | 27675 | #endif /* #ifndef SQLITE_OMIT_WAL */ |
| 27650 | 27676 | |
| 27677 | +#if SQLITE_MAX_MMAP_SIZE>0 |
| 27651 | 27678 | /* |
| 27652 | 27679 | ** If it is currently memory mapped, unmap file pFd. |
| 27653 | 27680 | */ |
| 27654 | 27681 | static void unixUnmapfile(unixFile *pFd){ |
| 27655 | 27682 | assert( pFd->nFetchOut==0 ); |
| 27656 | | -#if SQLITE_MAX_MMAP_SIZE>0 |
| 27657 | 27683 | if( pFd->pMapRegion ){ |
| 27658 | 27684 | osMunmap(pFd->pMapRegion, pFd->mmapSizeActual); |
| 27659 | 27685 | pFd->pMapRegion = 0; |
| 27660 | 27686 | pFd->mmapSize = 0; |
| 27661 | 27687 | pFd->mmapSizeActual = 0; |
| 27662 | 27688 | } |
| 27663 | | -#endif |
| 27664 | 27689 | } |
| 27665 | 27690 | |
| 27666 | | -#if SQLITE_MAX_MMAP_SIZE>0 |
| 27667 | 27691 | /* |
| 27668 | 27692 | ** Return the system page size. |
| 27669 | 27693 | */ |
| 27670 | 27694 | static int unixGetPagesize(void){ |
| 27671 | 27695 | #if HAVE_MREMAP |
| | @@ -27674,13 +27698,11 @@ |
| 27674 | 27698 | return getpagesize(); |
| 27675 | 27699 | #else |
| 27676 | 27700 | return (int)sysconf(_SC_PAGESIZE); |
| 27677 | 27701 | #endif |
| 27678 | 27702 | } |
| 27679 | | -#endif /* SQLITE_MAX_MMAP_SIZE>0 */ |
| 27680 | 27703 | |
| 27681 | | -#if SQLITE_MAX_MMAP_SIZE>0 |
| 27682 | 27704 | /* |
| 27683 | 27705 | ** Attempt to set the size of the memory mapping maintained by file |
| 27684 | 27706 | ** descriptor pFd to nNew bytes. Any existing mapping is discarded. |
| 27685 | 27707 | ** |
| 27686 | 27708 | ** If successful, this function sets the following variables: |
| | @@ -27761,11 +27783,10 @@ |
| 27761 | 27783 | pFd->mmapSizeMax = 0; |
| 27762 | 27784 | } |
| 27763 | 27785 | pFd->pMapRegion = (void *)pNew; |
| 27764 | 27786 | pFd->mmapSize = pFd->mmapSizeActual = nNew; |
| 27765 | 27787 | } |
| 27766 | | -#endif |
| 27767 | 27788 | |
| 27768 | 27789 | /* |
| 27769 | 27790 | ** Memory map or remap the file opened by file-descriptor pFd (if the file |
| 27770 | 27791 | ** is already mapped, the existing mapping is replaced by the new). Or, if |
| 27771 | 27792 | ** there already exists a mapping for this file, and there are still |
| | @@ -27780,11 +27801,10 @@ |
| 27780 | 27801 | ** SQLITE_OK is returned if no error occurs (even if the mapping is not |
| 27781 | 27802 | ** recreated as a result of outstanding references) or an SQLite error |
| 27782 | 27803 | ** code otherwise. |
| 27783 | 27804 | */ |
| 27784 | 27805 | static int unixMapfile(unixFile *pFd, i64 nByte){ |
| 27785 | | -#if SQLITE_MAX_MMAP_SIZE>0 |
| 27786 | 27806 | i64 nMap = nByte; |
| 27787 | 27807 | int rc; |
| 27788 | 27808 | |
| 27789 | 27809 | assert( nMap>=0 || pFd->nFetchOut==0 ); |
| 27790 | 27810 | if( pFd->nFetchOut>0 ) return SQLITE_OK; |
| | @@ -27806,14 +27826,14 @@ |
| 27806 | 27826 | unixRemapfile(pFd, nMap); |
| 27807 | 27827 | }else{ |
| 27808 | 27828 | unixUnmapfile(pFd); |
| 27809 | 27829 | } |
| 27810 | 27830 | } |
| 27811 | | -#endif |
| 27812 | 27831 | |
| 27813 | 27832 | return SQLITE_OK; |
| 27814 | 27833 | } |
| 27834 | +#endif /* SQLITE_MAX_MMAP_SIZE>0 */ |
| 27815 | 27835 | |
| 27816 | 27836 | /* |
| 27817 | 27837 | ** If possible, return a pointer to a mapping of file fd starting at offset |
| 27818 | 27838 | ** iOff. The mapping must be valid for at least nAmt bytes. |
| 27819 | 27839 | ** |
| | @@ -27858,10 +27878,11 @@ |
| 27858 | 27878 | */ |
| 27859 | 27879 | static int unixUnfetch(sqlite3_file *fd, i64 iOff, void *p){ |
| 27860 | 27880 | unixFile *pFd = (unixFile *)fd; /* The underlying database file */ |
| 27861 | 27881 | UNUSED_PARAMETER(iOff); |
| 27862 | 27882 | |
| 27883 | +#if SQLITE_MAX_MMAP_SIZE>0 |
| 27863 | 27884 | /* If p==0 (unmap the entire file) then there must be no outstanding |
| 27864 | 27885 | ** xFetch references. Or, if p!=0 (meaning it is an xFetch reference), |
| 27865 | 27886 | ** then there must be at least one outstanding. */ |
| 27866 | 27887 | assert( (p==0)==(pFd->nFetchOut==0) ); |
| 27867 | 27888 | |
| | @@ -27873,10 +27894,11 @@ |
| 27873 | 27894 | }else{ |
| 27874 | 27895 | unixUnmapfile(pFd); |
| 27875 | 27896 | } |
| 27876 | 27897 | |
| 27877 | 27898 | assert( pFd->nFetchOut>=0 ); |
| 27899 | +#endif |
| 27878 | 27900 | return SQLITE_OK; |
| 27879 | 27901 | } |
| 27880 | 27902 | |
| 27881 | 27903 | /* |
| 27882 | 27904 | ** Here ends the implementation of all sqlite3_file methods. |
| | @@ -28204,11 +28226,13 @@ |
| 28204 | 28226 | OSTRACE(("OPEN %-3d %s\n", h, zFilename)); |
| 28205 | 28227 | pNew->h = h; |
| 28206 | 28228 | pNew->pVfs = pVfs; |
| 28207 | 28229 | pNew->zPath = zFilename; |
| 28208 | 28230 | pNew->ctrlFlags = (u8)ctrlFlags; |
| 28231 | +#if SQLITE_MAX_MMAP_SIZE>0 |
| 28209 | 28232 | pNew->mmapSizeMax = sqlite3GlobalConfig.szMmap; |
| 28233 | +#endif |
| 28210 | 28234 | if( sqlite3_uri_boolean(((ctrlFlags & UNIXFILE_URI) ? zFilename : 0), |
| 28211 | 28235 | "psow", SQLITE_POWERSAFE_OVERWRITE) ){ |
| 28212 | 28236 | pNew->ctrlFlags |= UNIXFILE_PSOW; |
| 28213 | 28237 | } |
| 28214 | 28238 | if( strcmp(pVfs->zName,"unix-excl")==0 ){ |
| | @@ -28360,10 +28384,11 @@ |
| 28360 | 28384 | ** If no suitable temporary file directory can be found, return NULL. |
| 28361 | 28385 | */ |
| 28362 | 28386 | static const char *unixTempFileDir(void){ |
| 28363 | 28387 | static const char *azDirs[] = { |
| 28364 | 28388 | 0, |
| 28389 | + 0, |
| 28365 | 28390 | 0, |
| 28366 | 28391 | "/var/tmp", |
| 28367 | 28392 | "/usr/tmp", |
| 28368 | 28393 | "/tmp", |
| 28369 | 28394 | 0 /* List terminator */ |
| | @@ -28371,11 +28396,12 @@ |
| 28371 | 28396 | unsigned int i; |
| 28372 | 28397 | struct stat buf; |
| 28373 | 28398 | const char *zDir = 0; |
| 28374 | 28399 | |
| 28375 | 28400 | azDirs[0] = sqlite3_temp_directory; |
| 28376 | | - if( !azDirs[1] ) azDirs[1] = getenv("TMPDIR"); |
| 28401 | + if( !azDirs[1] ) azDirs[1] = getenv("SQLITE_TMPDIR"); |
| 28402 | + if( !azDirs[2] ) azDirs[2] = getenv("TMPDIR"); |
| 28377 | 28403 | for(i=0; i<sizeof(azDirs)/sizeof(azDirs[0]); zDir=azDirs[i++]){ |
| 28378 | 28404 | if( zDir==0 ) continue; |
| 28379 | 28405 | if( osStat(zDir, &buf) ) continue; |
| 28380 | 28406 | if( !S_ISDIR(buf.st_mode) ) continue; |
| 28381 | 28407 | if( osAccess(zDir, 07) ) continue; |
| | @@ -30484,11 +30510,11 @@ |
| 30484 | 30510 | */ |
| 30485 | 30511 | #if SQLITE_OS_WIN /* This file is used for Windows only */ |
| 30486 | 30512 | |
| 30487 | 30513 | #ifdef __CYGWIN__ |
| 30488 | 30514 | # include <sys/cygwin.h> |
| 30489 | | -/* # include <errno.h> */ |
| 30515 | +# include <errno.h> /* amalgamator: keep */ |
| 30490 | 30516 | #endif |
| 30491 | 30517 | |
| 30492 | 30518 | /* |
| 30493 | 30519 | ** Include code that is common to all os_*.c files |
| 30494 | 30520 | */ |
| | @@ -30705,30 +30731,99 @@ |
| 30705 | 30731 | /* |
| 30706 | 30732 | ** Compiling and using WAL mode requires several APIs that are only |
| 30707 | 30733 | ** available in Windows platforms based on the NT kernel. |
| 30708 | 30734 | */ |
| 30709 | 30735 | #if !SQLITE_OS_WINNT && !defined(SQLITE_OMIT_WAL) |
| 30710 | | -# error "WAL mode requires support from the Windows NT kernel, compile\ |
| 30736 | +# error "WAL mode requires support from the Windows NT kernel, compile\ |
| 30711 | 30737 | with SQLITE_OMIT_WAL." |
| 30712 | 30738 | #endif |
| 30713 | 30739 | |
| 30714 | 30740 | /* |
| 30715 | 30741 | ** Are most of the Win32 ANSI APIs available (i.e. with certain exceptions |
| 30716 | 30742 | ** based on the sub-platform)? |
| 30717 | 30743 | */ |
| 30718 | | -#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT |
| 30744 | +#if !SQLITE_OS_WINCE && !SQLITE_OS_WINRT && !defined(SQLITE_WIN32_NO_ANSI) |
| 30719 | 30745 | # define SQLITE_WIN32_HAS_ANSI |
| 30720 | 30746 | #endif |
| 30721 | 30747 | |
| 30722 | 30748 | /* |
| 30723 | 30749 | ** Are most of the Win32 Unicode APIs available (i.e. with certain exceptions |
| 30724 | 30750 | ** based on the sub-platform)? |
| 30725 | 30751 | */ |
| 30726 | | -#if SQLITE_OS_WINCE || SQLITE_OS_WINNT || SQLITE_OS_WINRT |
| 30752 | +#if (SQLITE_OS_WINCE || SQLITE_OS_WINNT || SQLITE_OS_WINRT) && \ |
| 30753 | + !defined(SQLITE_WIN32_NO_WIDE) |
| 30727 | 30754 | # define SQLITE_WIN32_HAS_WIDE |
| 30728 | 30755 | #endif |
| 30729 | 30756 | |
| 30757 | +/* |
| 30758 | +** Make sure at least one set of Win32 APIs is available. |
| 30759 | +*/ |
| 30760 | +#if !defined(SQLITE_WIN32_HAS_ANSI) && !defined(SQLITE_WIN32_HAS_WIDE) |
| 30761 | +# error "At least one of SQLITE_WIN32_HAS_ANSI and SQLITE_WIN32_HAS_WIDE\ |
| 30762 | + must be defined." |
| 30763 | +#endif |
| 30764 | + |
| 30765 | +/* |
| 30766 | +** Maximum pathname length (in chars) for Win32. This should normally be |
| 30767 | +** MAX_PATH. |
| 30768 | +*/ |
| 30769 | +#ifndef SQLITE_WIN32_MAX_PATH_CHARS |
| 30770 | +# define SQLITE_WIN32_MAX_PATH_CHARS (MAX_PATH) |
| 30771 | +#endif |
| 30772 | + |
| 30773 | +/* |
| 30774 | +** Maximum pathname length (in chars) for WinNT. This should normally be |
| 30775 | +** 32767. |
| 30776 | +*/ |
| 30777 | +#ifndef SQLITE_WINNT_MAX_PATH_CHARS |
| 30778 | +# define SQLITE_WINNT_MAX_PATH_CHARS (32767) |
| 30779 | +#endif |
| 30780 | + |
| 30781 | +/* |
| 30782 | +** Maximum pathname length (in bytes) for Win32. The MAX_PATH macro is in |
| 30783 | +** characters, so we allocate 3 bytes per character assuming worst-case of |
| 30784 | +** 4-bytes-per-character for UTF8. |
| 30785 | +*/ |
| 30786 | +#ifndef SQLITE_WIN32_MAX_PATH_BYTES |
| 30787 | +# define SQLITE_WIN32_MAX_PATH_BYTES (SQLITE_WIN32_MAX_PATH_CHARS*4) |
| 30788 | +#endif |
| 30789 | + |
| 30790 | +/* |
| 30791 | +** Maximum pathname length (in bytes) for WinNT. This should normally be |
| 30792 | +** 32767 * sizeof(WCHAR). |
| 30793 | +*/ |
| 30794 | +#ifndef SQLITE_WINNT_MAX_PATH_BYTES |
| 30795 | +# define SQLITE_WINNT_MAX_PATH_BYTES \ |
| 30796 | + (sizeof(WCHAR) * SQLITE_WINNT_MAX_PATH_CHARS) |
| 30797 | +#endif |
| 30798 | + |
| 30799 | +/* |
| 30800 | +** Maximum error message length (in chars) for WinRT. |
| 30801 | +*/ |
| 30802 | +#ifndef SQLITE_WIN32_MAX_ERRMSG_CHARS |
| 30803 | +# define SQLITE_WIN32_MAX_ERRMSG_CHARS (1024) |
| 30804 | +#endif |
| 30805 | + |
| 30806 | +/* |
| 30807 | +** Returns non-zero if the character should be treated as a directory |
| 30808 | +** separator. |
| 30809 | +*/ |
| 30810 | +#ifndef winIsDirSep |
| 30811 | +# define winIsDirSep(a) (((a) == '/') || ((a) == '\\')) |
| 30812 | +#endif |
| 30813 | + |
| 30814 | +/* |
| 30815 | +** Returns the string that should be used as the directory separator. |
| 30816 | +*/ |
| 30817 | +#ifndef winGetDirDep |
| 30818 | +# ifdef __CYGWIN__ |
| 30819 | +# define winGetDirDep() "/" |
| 30820 | +# else |
| 30821 | +# define winGetDirDep() "\\" |
| 30822 | +# endif |
| 30823 | +#endif |
| 30824 | + |
| 30730 | 30825 | /* |
| 30731 | 30826 | ** Do we need to manually define the Win32 file mapping APIs for use with WAL |
| 30732 | 30827 | ** mode (e.g. these APIs are available in the Windows CE SDK; however, they |
| 30733 | 30828 | ** are not present in the header file)? |
| 30734 | 30829 | */ |
| | @@ -30776,11 +30871,11 @@ |
| 30776 | 30871 | #ifndef FILE_ATTRIBUTE_MASK |
| 30777 | 30872 | # define FILE_ATTRIBUTE_MASK (0x0003FFF7) |
| 30778 | 30873 | #endif |
| 30779 | 30874 | |
| 30780 | 30875 | #ifndef SQLITE_OMIT_WAL |
| 30781 | | -/* Forward references */ |
| 30876 | +/* Forward references to structures used for WAL */ |
| 30782 | 30877 | typedef struct winShm winShm; /* A connection to shared-memory */ |
| 30783 | 30878 | typedef struct winShmNode winShmNode; /* A region of shared-memory */ |
| 30784 | 30879 | #endif |
| 30785 | 30880 | |
| 30786 | 30881 | /* |
| | @@ -31731,16 +31826,16 @@ |
| 31731 | 31826 | ** API as long as we don't call it when running Win95/98/ME. A call to |
| 31732 | 31827 | ** this routine is used to determine if the host is Win95/98/ME or |
| 31733 | 31828 | ** WinNT/2K/XP so that we will know whether or not we can safely call |
| 31734 | 31829 | ** the LockFileEx() API. |
| 31735 | 31830 | */ |
| 31736 | | -#if SQLITE_OS_WINCE || SQLITE_OS_WINRT |
| 31737 | | -# define isNT() (1) |
| 31831 | +#if SQLITE_OS_WINCE || SQLITE_OS_WINRT || !defined(SQLITE_WIN32_HAS_ANSI) |
| 31832 | +# define osIsNT() (1) |
| 31738 | 31833 | #elif !defined(SQLITE_WIN32_HAS_WIDE) |
| 31739 | | -# define isNT() (0) |
| 31834 | +# define osIsNT() (0) |
| 31740 | 31835 | #else |
| 31741 | | - static int isNT(void){ |
| 31836 | + static int osIsNT(void){ |
| 31742 | 31837 | if( sqlite3_os_type==0 ){ |
| 31743 | 31838 | OSVERSIONINFOA sInfo; |
| 31744 | 31839 | sInfo.dwOSVersionInfoSize = sizeof(sInfo); |
| 31745 | 31840 | osGetVersionExA(&sInfo); |
| 31746 | 31841 | sqlite3_os_type = sInfo.dwPlatformId==VER_PLATFORM_WIN32_NT ? 2 : 1; |
| | @@ -31947,11 +32042,11 @@ |
| 31947 | 32042 | /* |
| 31948 | 32043 | ** Convert a UTF-8 string to Microsoft Unicode (UTF-16?). |
| 31949 | 32044 | ** |
| 31950 | 32045 | ** Space to hold the returned string is obtained from malloc. |
| 31951 | 32046 | */ |
| 31952 | | -static LPWSTR utf8ToUnicode(const char *zFilename){ |
| 32047 | +static LPWSTR winUtf8ToUnicode(const char *zFilename){ |
| 31953 | 32048 | int nChar; |
| 31954 | 32049 | LPWSTR zWideFilename; |
| 31955 | 32050 | |
| 31956 | 32051 | nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0); |
| 31957 | 32052 | if( nChar==0 ){ |
| | @@ -31972,11 +32067,11 @@ |
| 31972 | 32067 | |
| 31973 | 32068 | /* |
| 31974 | 32069 | ** Convert Microsoft Unicode to UTF-8. Space to hold the returned string is |
| 31975 | 32070 | ** obtained from sqlite3_malloc(). |
| 31976 | 32071 | */ |
| 31977 | | -static char *unicodeToUtf8(LPCWSTR zWideFilename){ |
| 32072 | +static char *winUnicodeToUtf8(LPCWSTR zWideFilename){ |
| 31978 | 32073 | int nByte; |
| 31979 | 32074 | char *zFilename; |
| 31980 | 32075 | |
| 31981 | 32076 | nByte = osWideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, 0, 0, 0, 0); |
| 31982 | 32077 | if( nByte == 0 ){ |
| | @@ -32000,11 +32095,11 @@ |
| 32000 | 32095 | ** current codepage settings for file apis. |
| 32001 | 32096 | ** |
| 32002 | 32097 | ** Space to hold the returned string is obtained |
| 32003 | 32098 | ** from sqlite3_malloc. |
| 32004 | 32099 | */ |
| 32005 | | -static LPWSTR mbcsToUnicode(const char *zFilename){ |
| 32100 | +static LPWSTR winMbcsToUnicode(const char *zFilename){ |
| 32006 | 32101 | int nByte; |
| 32007 | 32102 | LPWSTR zMbcsFilename; |
| 32008 | 32103 | int codepage = osAreFileApisANSI() ? CP_ACP : CP_OEMCP; |
| 32009 | 32104 | |
| 32010 | 32105 | nByte = osMultiByteToWideChar(codepage, 0, zFilename, -1, NULL, |
| | @@ -32030,11 +32125,11 @@ |
| 32030 | 32125 | ** user's ANSI codepage. |
| 32031 | 32126 | ** |
| 32032 | 32127 | ** Space to hold the returned string is obtained from |
| 32033 | 32128 | ** sqlite3_malloc(). |
| 32034 | 32129 | */ |
| 32035 | | -static char *unicodeToMbcs(LPCWSTR zWideFilename){ |
| 32130 | +static char *winUnicodeToMbcs(LPCWSTR zWideFilename){ |
| 32036 | 32131 | int nByte; |
| 32037 | 32132 | char *zFilename; |
| 32038 | 32133 | int codepage = osAreFileApisANSI() ? CP_ACP : CP_OEMCP; |
| 32039 | 32134 | |
| 32040 | 32135 | nByte = osWideCharToMultiByte(codepage, 0, zWideFilename, -1, 0, 0, 0, 0); |
| | @@ -32060,15 +32155,15 @@ |
| 32060 | 32155 | */ |
| 32061 | 32156 | SQLITE_API char *sqlite3_win32_mbcs_to_utf8(const char *zFilename){ |
| 32062 | 32157 | char *zFilenameUtf8; |
| 32063 | 32158 | LPWSTR zTmpWide; |
| 32064 | 32159 | |
| 32065 | | - zTmpWide = mbcsToUnicode(zFilename); |
| 32160 | + zTmpWide = winMbcsToUnicode(zFilename); |
| 32066 | 32161 | if( zTmpWide==0 ){ |
| 32067 | 32162 | return 0; |
| 32068 | 32163 | } |
| 32069 | | - zFilenameUtf8 = unicodeToUtf8(zTmpWide); |
| 32164 | + zFilenameUtf8 = winUnicodeToUtf8(zTmpWide); |
| 32070 | 32165 | sqlite3_free(zTmpWide); |
| 32071 | 32166 | return zFilenameUtf8; |
| 32072 | 32167 | } |
| 32073 | 32168 | |
| 32074 | 32169 | /* |
| | @@ -32077,15 +32172,15 @@ |
| 32077 | 32172 | */ |
| 32078 | 32173 | SQLITE_API char *sqlite3_win32_utf8_to_mbcs(const char *zFilename){ |
| 32079 | 32174 | char *zFilenameMbcs; |
| 32080 | 32175 | LPWSTR zTmpWide; |
| 32081 | 32176 | |
| 32082 | | - zTmpWide = utf8ToUnicode(zFilename); |
| 32177 | + zTmpWide = winUtf8ToUnicode(zFilename); |
| 32083 | 32178 | if( zTmpWide==0 ){ |
| 32084 | 32179 | return 0; |
| 32085 | 32180 | } |
| 32086 | | - zFilenameMbcs = unicodeToMbcs(zTmpWide); |
| 32181 | + zFilenameMbcs = winUnicodeToMbcs(zTmpWide); |
| 32087 | 32182 | sqlite3_free(zTmpWide); |
| 32088 | 32183 | return zFilenameMbcs; |
| 32089 | 32184 | } |
| 32090 | 32185 | |
| 32091 | 32186 | /* |
| | @@ -32111,11 +32206,11 @@ |
| 32111 | 32206 | ); |
| 32112 | 32207 | assert( !ppDirectory || sqlite3MemdebugHasType(*ppDirectory, MEMTYPE_HEAP) ); |
| 32113 | 32208 | if( ppDirectory ){ |
| 32114 | 32209 | char *zValueUtf8 = 0; |
| 32115 | 32210 | if( zValue && zValue[0] ){ |
| 32116 | | - zValueUtf8 = unicodeToUtf8(zValue); |
| 32211 | + zValueUtf8 = winUnicodeToUtf8(zValue); |
| 32117 | 32212 | if ( zValueUtf8==0 ){ |
| 32118 | 32213 | return SQLITE_NOMEM; |
| 32119 | 32214 | } |
| 32120 | 32215 | } |
| 32121 | 32216 | sqlite3_free(*ppDirectory); |
| | @@ -32124,32 +32219,32 @@ |
| 32124 | 32219 | } |
| 32125 | 32220 | return SQLITE_ERROR; |
| 32126 | 32221 | } |
| 32127 | 32222 | |
| 32128 | 32223 | /* |
| 32129 | | -** The return value of getLastErrorMsg |
| 32224 | +** The return value of winGetLastErrorMsg |
| 32130 | 32225 | ** is zero if the error message fits in the buffer, or non-zero |
| 32131 | 32226 | ** otherwise (if the message was truncated). |
| 32132 | 32227 | */ |
| 32133 | | -static int getLastErrorMsg(DWORD lastErrno, int nBuf, char *zBuf){ |
| 32228 | +static int winGetLastErrorMsg(DWORD lastErrno, int nBuf, char *zBuf){ |
| 32134 | 32229 | /* FormatMessage returns 0 on failure. Otherwise it |
| 32135 | 32230 | ** returns the number of TCHARs written to the output |
| 32136 | 32231 | ** buffer, excluding the terminating null char. |
| 32137 | 32232 | */ |
| 32138 | 32233 | DWORD dwLen = 0; |
| 32139 | 32234 | char *zOut = 0; |
| 32140 | 32235 | |
| 32141 | | - if( isNT() ){ |
| 32236 | + if( osIsNT() ){ |
| 32142 | 32237 | #if SQLITE_OS_WINRT |
| 32143 | | - WCHAR zTempWide[MAX_PATH+1]; /* NOTE: Somewhat arbitrary. */ |
| 32238 | + WCHAR zTempWide[SQLITE_WIN32_MAX_ERRMSG_CHARS+1]; |
| 32144 | 32239 | dwLen = osFormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | |
| 32145 | 32240 | FORMAT_MESSAGE_IGNORE_INSERTS, |
| 32146 | 32241 | NULL, |
| 32147 | 32242 | lastErrno, |
| 32148 | 32243 | 0, |
| 32149 | 32244 | zTempWide, |
| 32150 | | - MAX_PATH, |
| 32245 | + SQLITE_WIN32_MAX_ERRMSG_CHARS, |
| 32151 | 32246 | 0); |
| 32152 | 32247 | #else |
| 32153 | 32248 | LPWSTR zTempWide = NULL; |
| 32154 | 32249 | dwLen = osFormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | |
| 32155 | 32250 | FORMAT_MESSAGE_FROM_SYSTEM | |
| | @@ -32162,11 +32257,11 @@ |
| 32162 | 32257 | 0); |
| 32163 | 32258 | #endif |
| 32164 | 32259 | if( dwLen > 0 ){ |
| 32165 | 32260 | /* allocate a buffer and convert to UTF8 */ |
| 32166 | 32261 | sqlite3BeginBenignMalloc(); |
| 32167 | | - zOut = unicodeToUtf8(zTempWide); |
| 32262 | + zOut = winUnicodeToUtf8(zTempWide); |
| 32168 | 32263 | sqlite3EndBenignMalloc(); |
| 32169 | 32264 | #if !SQLITE_OS_WINRT |
| 32170 | 32265 | /* free the system buffer allocated by FormatMessage */ |
| 32171 | 32266 | osLocalFree(zTempWide); |
| 32172 | 32267 | #endif |
| | @@ -32230,11 +32325,11 @@ |
| 32230 | 32325 | ){ |
| 32231 | 32326 | char zMsg[500]; /* Human readable error text */ |
| 32232 | 32327 | int i; /* Loop counter */ |
| 32233 | 32328 | |
| 32234 | 32329 | zMsg[0] = 0; |
| 32235 | | - getLastErrorMsg(lastErrno, sizeof(zMsg), zMsg); |
| 32330 | + winGetLastErrorMsg(lastErrno, sizeof(zMsg), zMsg); |
| 32236 | 32331 | assert( errcode!=SQLITE_OK ); |
| 32237 | 32332 | if( zPath==0 ) zPath = ""; |
| 32238 | 32333 | for(i=0; zMsg[i] && zMsg[i]!='\r' && zMsg[i]!='\n'; i++){} |
| 32239 | 32334 | zMsg[i] = 0; |
| 32240 | 32335 | sqlite3_log(errcode, |
| | @@ -32255,30 +32350,30 @@ |
| 32255 | 32350 | # define SQLITE_WIN32_IOERR_RETRY 10 |
| 32256 | 32351 | #endif |
| 32257 | 32352 | #ifndef SQLITE_WIN32_IOERR_RETRY_DELAY |
| 32258 | 32353 | # define SQLITE_WIN32_IOERR_RETRY_DELAY 25 |
| 32259 | 32354 | #endif |
| 32260 | | -static int win32IoerrRetry = SQLITE_WIN32_IOERR_RETRY; |
| 32261 | | -static int win32IoerrRetryDelay = SQLITE_WIN32_IOERR_RETRY_DELAY; |
| 32355 | +static int winIoerrRetry = SQLITE_WIN32_IOERR_RETRY; |
| 32356 | +static int winIoerrRetryDelay = SQLITE_WIN32_IOERR_RETRY_DELAY; |
| 32262 | 32357 | |
| 32263 | 32358 | /* |
| 32264 | 32359 | ** If a ReadFile() or WriteFile() error occurs, invoke this routine |
| 32265 | 32360 | ** to see if it should be retried. Return TRUE to retry. Return FALSE |
| 32266 | 32361 | ** to give up with an error. |
| 32267 | 32362 | */ |
| 32268 | | -static int retryIoerr(int *pnRetry, DWORD *pError){ |
| 32363 | +static int winRetryIoerr(int *pnRetry, DWORD *pError){ |
| 32269 | 32364 | DWORD e = osGetLastError(); |
| 32270 | | - if( *pnRetry>=win32IoerrRetry ){ |
| 32365 | + if( *pnRetry>=winIoerrRetry ){ |
| 32271 | 32366 | if( pError ){ |
| 32272 | 32367 | *pError = e; |
| 32273 | 32368 | } |
| 32274 | 32369 | return 0; |
| 32275 | 32370 | } |
| 32276 | 32371 | if( e==ERROR_ACCESS_DENIED || |
| 32277 | 32372 | e==ERROR_LOCK_VIOLATION || |
| 32278 | 32373 | e==ERROR_SHARING_VIOLATION ){ |
| 32279 | | - sqlite3_win32_sleep(win32IoerrRetryDelay*(1+*pnRetry)); |
| 32374 | + sqlite3_win32_sleep(winIoerrRetryDelay*(1+*pnRetry)); |
| 32280 | 32375 | ++*pnRetry; |
| 32281 | 32376 | return 1; |
| 32282 | 32377 | } |
| 32283 | 32378 | if( pError ){ |
| 32284 | 32379 | *pError = e; |
| | @@ -32287,15 +32382,15 @@ |
| 32287 | 32382 | } |
| 32288 | 32383 | |
| 32289 | 32384 | /* |
| 32290 | 32385 | ** Log a I/O error retry episode. |
| 32291 | 32386 | */ |
| 32292 | | -static void logIoerr(int nRetry){ |
| 32387 | +static void winLogIoerr(int nRetry){ |
| 32293 | 32388 | if( nRetry ){ |
| 32294 | 32389 | sqlite3_log(SQLITE_IOERR, |
| 32295 | 32390 | "delayed %dms for lock/sharing conflict", |
| 32296 | | - win32IoerrRetryDelay*nRetry*(nRetry+1)/2 |
| 32391 | + winIoerrRetryDelay*nRetry*(nRetry+1)/2 |
| 32297 | 32392 | ); |
| 32298 | 32393 | } |
| 32299 | 32394 | } |
| 32300 | 32395 | |
| 32301 | 32396 | #if SQLITE_OS_WINCE |
| | @@ -32356,11 +32451,11 @@ |
| 32356 | 32451 | LPWSTR zName; |
| 32357 | 32452 | DWORD lastErrno; |
| 32358 | 32453 | BOOL bLogged = FALSE; |
| 32359 | 32454 | BOOL bInit = TRUE; |
| 32360 | 32455 | |
| 32361 | | - zName = utf8ToUnicode(zFilename); |
| 32456 | + zName = winUtf8ToUnicode(zFilename); |
| 32362 | 32457 | if( zName==0 ){ |
| 32363 | 32458 | /* out of memory */ |
| 32364 | 32459 | return SQLITE_IOERR_NOMEM; |
| 32365 | 32460 | } |
| 32366 | 32461 | |
| | @@ -32376,14 +32471,13 @@ |
| 32376 | 32471 | |
| 32377 | 32472 | /* Create/open the named mutex */ |
| 32378 | 32473 | pFile->hMutex = osCreateMutexW(NULL, FALSE, zName); |
| 32379 | 32474 | if (!pFile->hMutex){ |
| 32380 | 32475 | pFile->lastErrno = osGetLastError(); |
| 32381 | | - winLogError(SQLITE_IOERR, pFile->lastErrno, |
| 32382 | | - "winceCreateLock1", zFilename); |
| 32383 | 32476 | sqlite3_free(zName); |
| 32384 | | - return SQLITE_IOERR; |
| 32477 | + return winLogError(SQLITE_IOERR, pFile->lastErrno, |
| 32478 | + "winceCreateLock1", zFilename); |
| 32385 | 32479 | } |
| 32386 | 32480 | |
| 32387 | 32481 | /* Acquire the mutex before continuing */ |
| 32388 | 32482 | winceMutexAcquire(pFile->hMutex); |
| 32389 | 32483 | |
| | @@ -32629,11 +32723,11 @@ |
| 32629 | 32723 | ** API LockFile. |
| 32630 | 32724 | */ |
| 32631 | 32725 | return winceLockFile(phFile, offsetLow, offsetHigh, |
| 32632 | 32726 | numBytesLow, numBytesHigh); |
| 32633 | 32727 | #else |
| 32634 | | - if( isNT() ){ |
| 32728 | + if( osIsNT() ){ |
| 32635 | 32729 | OVERLAPPED ovlp; |
| 32636 | 32730 | memset(&ovlp, 0, sizeof(OVERLAPPED)); |
| 32637 | 32731 | ovlp.Offset = offsetLow; |
| 32638 | 32732 | ovlp.OffsetHigh = offsetHigh; |
| 32639 | 32733 | return osLockFileEx(*phFile, flags, 0, numBytesLow, numBytesHigh, &ovlp); |
| | @@ -32660,11 +32754,11 @@ |
| 32660 | 32754 | ** API UnlockFile. |
| 32661 | 32755 | */ |
| 32662 | 32756 | return winceUnlockFile(phFile, offsetLow, offsetHigh, |
| 32663 | 32757 | numBytesLow, numBytesHigh); |
| 32664 | 32758 | #else |
| 32665 | | - if( isNT() ){ |
| 32759 | + if( osIsNT() ){ |
| 32666 | 32760 | OVERLAPPED ovlp; |
| 32667 | 32761 | memset(&ovlp, 0, sizeof(OVERLAPPED)); |
| 32668 | 32762 | ovlp.Offset = offsetLow; |
| 32669 | 32763 | ovlp.OffsetHigh = offsetHigh; |
| 32670 | 32764 | return osUnlockFileEx(*phFile, 0, numBytesLow, numBytesHigh, &ovlp); |
| | @@ -32690,11 +32784,11 @@ |
| 32690 | 32784 | /* |
| 32691 | 32785 | ** Move the current position of the file handle passed as the first |
| 32692 | 32786 | ** argument to offset iOffset within the file. If successful, return 0. |
| 32693 | 32787 | ** Otherwise, set pFile->lastErrno and return non-zero. |
| 32694 | 32788 | */ |
| 32695 | | -static int seekWinFile(winFile *pFile, sqlite3_int64 iOffset){ |
| 32789 | +static int winSeekFile(winFile *pFile, sqlite3_int64 iOffset){ |
| 32696 | 32790 | #if !SQLITE_OS_WINRT |
| 32697 | 32791 | LONG upperBits; /* Most sig. 32 bits of new offset */ |
| 32698 | 32792 | LONG lowerBits; /* Least sig. 32 bits of new offset */ |
| 32699 | 32793 | DWORD dwRet; /* Value returned by SetFilePointer() */ |
| 32700 | 32794 | DWORD lastErrno; /* Value returned by GetLastError() */ |
| | @@ -32715,11 +32809,11 @@ |
| 32715 | 32809 | |
| 32716 | 32810 | if( (dwRet==INVALID_SET_FILE_POINTER |
| 32717 | 32811 | && ((lastErrno = osGetLastError())!=NO_ERROR)) ){ |
| 32718 | 32812 | pFile->lastErrno = lastErrno; |
| 32719 | 32813 | winLogError(SQLITE_IOERR_SEEK, pFile->lastErrno, |
| 32720 | | - "seekWinFile", pFile->zPath); |
| 32814 | + "winSeekFile", pFile->zPath); |
| 32721 | 32815 | OSTRACE(("SEEK file=%p, rc=SQLITE_IOERR_SEEK\n", pFile->h)); |
| 32722 | 32816 | return 1; |
| 32723 | 32817 | } |
| 32724 | 32818 | |
| 32725 | 32819 | OSTRACE(("SEEK file=%p, rc=SQLITE_OK\n", pFile->h)); |
| | @@ -32736,11 +32830,11 @@ |
| 32736 | 32830 | bRet = osSetFilePointerEx(pFile->h, x, 0, FILE_BEGIN); |
| 32737 | 32831 | |
| 32738 | 32832 | if(!bRet){ |
| 32739 | 32833 | pFile->lastErrno = osGetLastError(); |
| 32740 | 32834 | winLogError(SQLITE_IOERR_SEEK, pFile->lastErrno, |
| 32741 | | - "seekWinFile", pFile->zPath); |
| 32835 | + "winSeekFile", pFile->zPath); |
| 32742 | 32836 | OSTRACE(("SEEK file=%p, rc=SQLITE_IOERR_SEEK\n", pFile->h)); |
| 32743 | 32837 | return 1; |
| 32744 | 32838 | } |
| 32745 | 32839 | |
| 32746 | 32840 | OSTRACE(("SEEK file=%p, rc=SQLITE_OK\n", pFile->h)); |
| | @@ -32747,11 +32841,12 @@ |
| 32747 | 32841 | return 0; |
| 32748 | 32842 | #endif |
| 32749 | 32843 | } |
| 32750 | 32844 | |
| 32751 | 32845 | #if SQLITE_MAX_MMAP_SIZE>0 |
| 32752 | | -/* Forward references to VFS methods */ |
| 32846 | +/* Forward references to VFS helper methods used for memory mapped files */ |
| 32847 | +static int winMapfile(winFile*, sqlite3_int64); |
| 32753 | 32848 | static int winUnmapfile(winFile*); |
| 32754 | 32849 | #endif |
| 32755 | 32850 | |
| 32756 | 32851 | /* |
| 32757 | 32852 | ** Close a file. |
| | @@ -32851,11 +32946,11 @@ |
| 32851 | 32946 | } |
| 32852 | 32947 | } |
| 32853 | 32948 | #endif |
| 32854 | 32949 | |
| 32855 | 32950 | #if SQLITE_OS_WINCE |
| 32856 | | - if( seekWinFile(pFile, offset) ){ |
| 32951 | + if( winSeekFile(pFile, offset) ){ |
| 32857 | 32952 | OSTRACE(("READ file=%p, rc=SQLITE_FULL\n", pFile->h)); |
| 32858 | 32953 | return SQLITE_FULL; |
| 32859 | 32954 | } |
| 32860 | 32955 | while( !osReadFile(pFile->h, pBuf, amt, &nRead, 0) ){ |
| 32861 | 32956 | #else |
| | @@ -32864,17 +32959,17 @@ |
| 32864 | 32959 | overlapped.OffsetHigh = (LONG)((offset>>32) & 0x7fffffff); |
| 32865 | 32960 | while( !osReadFile(pFile->h, pBuf, amt, &nRead, &overlapped) && |
| 32866 | 32961 | osGetLastError()!=ERROR_HANDLE_EOF ){ |
| 32867 | 32962 | #endif |
| 32868 | 32963 | DWORD lastErrno; |
| 32869 | | - if( retryIoerr(&nRetry, &lastErrno) ) continue; |
| 32964 | + if( winRetryIoerr(&nRetry, &lastErrno) ) continue; |
| 32870 | 32965 | pFile->lastErrno = lastErrno; |
| 32871 | 32966 | OSTRACE(("READ file=%p, rc=SQLITE_IOERR_READ\n", pFile->h)); |
| 32872 | 32967 | return winLogError(SQLITE_IOERR_READ, pFile->lastErrno, |
| 32873 | | - "winRead", pFile->zPath); |
| 32968 | + "winRead", pFile->zPath); |
| 32874 | 32969 | } |
| 32875 | | - logIoerr(nRetry); |
| 32970 | + winLogIoerr(nRetry); |
| 32876 | 32971 | if( nRead<(DWORD)amt ){ |
| 32877 | 32972 | /* Unread parts of the buffer must be zero-filled */ |
| 32878 | 32973 | memset(&((char*)pBuf)[nRead], 0, amt-nRead); |
| 32879 | 32974 | OSTRACE(("READ file=%p, rc=SQLITE_IOERR_SHORT_READ\n", pFile->h)); |
| 32880 | 32975 | return SQLITE_IOERR_SHORT_READ; |
| | @@ -32923,11 +33018,11 @@ |
| 32923 | 33018 | } |
| 32924 | 33019 | } |
| 32925 | 33020 | #endif |
| 32926 | 33021 | |
| 32927 | 33022 | #if SQLITE_OS_WINCE |
| 32928 | | - rc = seekWinFile(pFile, offset); |
| 33023 | + rc = winSeekFile(pFile, offset); |
| 32929 | 33024 | if( rc==0 ){ |
| 32930 | 33025 | #else |
| 32931 | 33026 | { |
| 32932 | 33027 | #endif |
| 32933 | 33028 | #if !SQLITE_OS_WINCE |
| | @@ -32948,11 +33043,11 @@ |
| 32948 | 33043 | #if SQLITE_OS_WINCE |
| 32949 | 33044 | if( !osWriteFile(pFile->h, aRem, nRem, &nWrite, 0) ){ |
| 32950 | 33045 | #else |
| 32951 | 33046 | if( !osWriteFile(pFile->h, aRem, nRem, &nWrite, &overlapped) ){ |
| 32952 | 33047 | #endif |
| 32953 | | - if( retryIoerr(&nRetry, &lastErrno) ) continue; |
| 33048 | + if( winRetryIoerr(&nRetry, &lastErrno) ) continue; |
| 32954 | 33049 | break; |
| 32955 | 33050 | } |
| 32956 | 33051 | assert( nWrite==0 || nWrite<=(DWORD)nRem ); |
| 32957 | 33052 | if( nWrite==0 || nWrite>(DWORD)nRem ){ |
| 32958 | 33053 | lastErrno = osGetLastError(); |
| | @@ -32974,17 +33069,18 @@ |
| 32974 | 33069 | |
| 32975 | 33070 | if( rc ){ |
| 32976 | 33071 | if( ( pFile->lastErrno==ERROR_HANDLE_DISK_FULL ) |
| 32977 | 33072 | || ( pFile->lastErrno==ERROR_DISK_FULL )){ |
| 32978 | 33073 | OSTRACE(("WRITE file=%p, rc=SQLITE_FULL\n", pFile->h)); |
| 32979 | | - return SQLITE_FULL; |
| 33074 | + return winLogError(SQLITE_FULL, pFile->lastErrno, |
| 33075 | + "winWrite1", pFile->zPath); |
| 32980 | 33076 | } |
| 32981 | 33077 | OSTRACE(("WRITE file=%p, rc=SQLITE_IOERR_WRITE\n", pFile->h)); |
| 32982 | 33078 | return winLogError(SQLITE_IOERR_WRITE, pFile->lastErrno, |
| 32983 | | - "winWrite", pFile->zPath); |
| 33079 | + "winWrite2", pFile->zPath); |
| 32984 | 33080 | }else{ |
| 32985 | | - logIoerr(nRetry); |
| 33081 | + winLogIoerr(nRetry); |
| 32986 | 33082 | } |
| 32987 | 33083 | OSTRACE(("WRITE file=%p, rc=SQLITE_OK\n", pFile->h)); |
| 32988 | 33084 | return SQLITE_OK; |
| 32989 | 33085 | } |
| 32990 | 33086 | |
| | @@ -33009,11 +33105,11 @@ |
| 33009 | 33105 | if( pFile->szChunk>0 ){ |
| 33010 | 33106 | nByte = ((nByte + pFile->szChunk - 1)/pFile->szChunk) * pFile->szChunk; |
| 33011 | 33107 | } |
| 33012 | 33108 | |
| 33013 | 33109 | /* SetEndOfFile() returns non-zero when successful, or zero when it fails. */ |
| 33014 | | - if( seekWinFile(pFile, nByte) ){ |
| 33110 | + if( winSeekFile(pFile, nByte) ){ |
| 33015 | 33111 | rc = winLogError(SQLITE_IOERR_TRUNCATE, pFile->lastErrno, |
| 33016 | 33112 | "winTruncate1", pFile->zPath); |
| 33017 | 33113 | }else if( 0==osSetEndOfFile(pFile->h) && |
| 33018 | 33114 | ((lastErrno = osGetLastError())!=ERROR_USER_MAPPED_FILE) ){ |
| 33019 | 33115 | pFile->lastErrno = lastErrno; |
| | @@ -33090,10 +33186,11 @@ |
| 33090 | 33186 | |
| 33091 | 33187 | /* If we compiled with the SQLITE_NO_SYNC flag, then syncing is a |
| 33092 | 33188 | ** no-op |
| 33093 | 33189 | */ |
| 33094 | 33190 | #ifdef SQLITE_NO_SYNC |
| 33191 | + OSTRACE(("SYNC-NOP file=%p, rc=SQLITE_OK\n", pFile->h)); |
| 33095 | 33192 | return SQLITE_OK; |
| 33096 | 33193 | #else |
| 33097 | 33194 | rc = osFlushFileBuffers(pFile->h); |
| 33098 | 33195 | SimulateIOError( rc=FALSE ); |
| 33099 | 33196 | if( rc ){ |
| | @@ -33101,11 +33198,11 @@ |
| 33101 | 33198 | return SQLITE_OK; |
| 33102 | 33199 | }else{ |
| 33103 | 33200 | pFile->lastErrno = osGetLastError(); |
| 33104 | 33201 | OSTRACE(("SYNC file=%p, rc=SQLITE_IOERR_FSYNC\n", pFile->h)); |
| 33105 | 33202 | return winLogError(SQLITE_IOERR_FSYNC, pFile->lastErrno, |
| 33106 | | - "winSync", pFile->zPath); |
| 33203 | + "winSync", pFile->zPath); |
| 33107 | 33204 | } |
| 33108 | 33205 | #endif |
| 33109 | 33206 | } |
| 33110 | 33207 | |
| 33111 | 33208 | /* |
| | @@ -33142,11 +33239,11 @@ |
| 33142 | 33239 | *pSize = (((sqlite3_int64)upperBits)<<32) + lowerBits; |
| 33143 | 33240 | if( (lowerBits == INVALID_FILE_SIZE) |
| 33144 | 33241 | && ((lastErrno = osGetLastError())!=NO_ERROR) ){ |
| 33145 | 33242 | pFile->lastErrno = lastErrno; |
| 33146 | 33243 | rc = winLogError(SQLITE_IOERR_FSTAT, pFile->lastErrno, |
| 33147 | | - "winFileSize", pFile->zPath); |
| 33244 | + "winFileSize", pFile->zPath); |
| 33148 | 33245 | } |
| 33149 | 33246 | } |
| 33150 | 33247 | #endif |
| 33151 | 33248 | OSTRACE(("SIZE file=%p, pSize=%p, *pSize=%lld, rc=%s\n", |
| 33152 | 33249 | pFile->h, pSize, *pSize, sqlite3ErrName(rc))); |
| | @@ -33187,14 +33284,14 @@ |
| 33187 | 33284 | /* |
| 33188 | 33285 | ** Acquire a reader lock. |
| 33189 | 33286 | ** Different API routines are called depending on whether or not this |
| 33190 | 33287 | ** is Win9x or WinNT. |
| 33191 | 33288 | */ |
| 33192 | | -static int getReadLock(winFile *pFile){ |
| 33289 | +static int winGetReadLock(winFile *pFile){ |
| 33193 | 33290 | int res; |
| 33194 | 33291 | OSTRACE(("READ-LOCK file=%p, lock=%d\n", pFile->h, pFile->locktype)); |
| 33195 | | - if( isNT() ){ |
| 33292 | + if( osIsNT() ){ |
| 33196 | 33293 | #if SQLITE_OS_WINCE |
| 33197 | 33294 | /* |
| 33198 | 33295 | ** NOTE: Windows CE is handled differently here due its lack of the Win32 |
| 33199 | 33296 | ** API LockFileEx. |
| 33200 | 33297 | */ |
| | @@ -33222,15 +33319,15 @@ |
| 33222 | 33319 | } |
| 33223 | 33320 | |
| 33224 | 33321 | /* |
| 33225 | 33322 | ** Undo a readlock |
| 33226 | 33323 | */ |
| 33227 | | -static int unlockReadLock(winFile *pFile){ |
| 33324 | +static int winUnlockReadLock(winFile *pFile){ |
| 33228 | 33325 | int res; |
| 33229 | 33326 | DWORD lastErrno; |
| 33230 | 33327 | OSTRACE(("READ-UNLOCK file=%p, lock=%d\n", pFile->h, pFile->locktype)); |
| 33231 | | - if( isNT() ){ |
| 33328 | + if( osIsNT() ){ |
| 33232 | 33329 | res = winUnlockFile(&pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0); |
| 33233 | 33330 | } |
| 33234 | 33331 | #ifdef SQLITE_WIN32_HAS_ANSI |
| 33235 | 33332 | else{ |
| 33236 | 33333 | res = winUnlockFile(&pFile->h, SHARED_FIRST+pFile->sharedLockByte, 0, 1, 0); |
| | @@ -33237,11 +33334,11 @@ |
| 33237 | 33334 | } |
| 33238 | 33335 | #endif |
| 33239 | 33336 | if( res==0 && ((lastErrno = osGetLastError())!=ERROR_NOT_LOCKED) ){ |
| 33240 | 33337 | pFile->lastErrno = lastErrno; |
| 33241 | 33338 | winLogError(SQLITE_IOERR_UNLOCK, pFile->lastErrno, |
| 33242 | | - "unlockReadLock", pFile->zPath); |
| 33339 | + "winUnlockReadLock", pFile->zPath); |
| 33243 | 33340 | } |
| 33244 | 33341 | OSTRACE(("READ-UNLOCK file=%p, rc=%s\n", pFile->h, sqlite3ErrName(res))); |
| 33245 | 33342 | return res; |
| 33246 | 33343 | } |
| 33247 | 33344 | |
| | @@ -33328,11 +33425,11 @@ |
| 33328 | 33425 | |
| 33329 | 33426 | /* Acquire a shared lock |
| 33330 | 33427 | */ |
| 33331 | 33428 | if( locktype==SHARED_LOCK && res ){ |
| 33332 | 33429 | assert( pFile->locktype==NO_LOCK ); |
| 33333 | | - res = getReadLock(pFile); |
| 33430 | + res = winGetReadLock(pFile); |
| 33334 | 33431 | if( res ){ |
| 33335 | 33432 | newLocktype = SHARED_LOCK; |
| 33336 | 33433 | }else{ |
| 33337 | 33434 | lastErrno = osGetLastError(); |
| 33338 | 33435 | } |
| | @@ -33359,18 +33456,18 @@ |
| 33359 | 33456 | |
| 33360 | 33457 | /* Acquire an EXCLUSIVE lock |
| 33361 | 33458 | */ |
| 33362 | 33459 | if( locktype==EXCLUSIVE_LOCK && res ){ |
| 33363 | 33460 | assert( pFile->locktype>=SHARED_LOCK ); |
| 33364 | | - res = unlockReadLock(pFile); |
| 33461 | + res = winUnlockReadLock(pFile); |
| 33365 | 33462 | res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS, SHARED_FIRST, 0, |
| 33366 | 33463 | SHARED_SIZE, 0); |
| 33367 | 33464 | if( res ){ |
| 33368 | 33465 | newLocktype = EXCLUSIVE_LOCK; |
| 33369 | 33466 | }else{ |
| 33370 | 33467 | lastErrno = osGetLastError(); |
| 33371 | | - getReadLock(pFile); |
| 33468 | + winGetReadLock(pFile); |
| 33372 | 33469 | } |
| 33373 | 33470 | } |
| 33374 | 33471 | |
| 33375 | 33472 | /* If we are holding a PENDING lock that ought to be released, then |
| 33376 | 33473 | ** release it now. |
| | @@ -33383,14 +33480,14 @@ |
| 33383 | 33480 | ** return the appropriate result code. |
| 33384 | 33481 | */ |
| 33385 | 33482 | if( res ){ |
| 33386 | 33483 | rc = SQLITE_OK; |
| 33387 | 33484 | }else{ |
| 33485 | + pFile->lastErrno = lastErrno; |
| 33486 | + rc = SQLITE_BUSY; |
| 33388 | 33487 | OSTRACE(("LOCK-FAIL file=%p, wanted=%d, got=%d\n", |
| 33389 | 33488 | pFile->h, locktype, newLocktype)); |
| 33390 | | - pFile->lastErrno = lastErrno; |
| 33391 | | - rc = SQLITE_BUSY; |
| 33392 | 33489 | } |
| 33393 | 33490 | pFile->locktype = (u8)newLocktype; |
| 33394 | 33491 | OSTRACE(("LOCK file=%p, lock=%d, rc=%s\n", |
| 33395 | 33492 | pFile->h, pFile->locktype, sqlite3ErrName(rc))); |
| 33396 | 33493 | return rc; |
| | @@ -33446,22 +33543,22 @@ |
| 33446 | 33543 | OSTRACE(("UNLOCK file=%p, oldLock=%d(%d), newLock=%d\n", |
| 33447 | 33544 | pFile->h, pFile->locktype, pFile->sharedLockByte, locktype)); |
| 33448 | 33545 | type = pFile->locktype; |
| 33449 | 33546 | if( type>=EXCLUSIVE_LOCK ){ |
| 33450 | 33547 | winUnlockFile(&pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0); |
| 33451 | | - if( locktype==SHARED_LOCK && !getReadLock(pFile) ){ |
| 33548 | + if( locktype==SHARED_LOCK && !winGetReadLock(pFile) ){ |
| 33452 | 33549 | /* This should never happen. We should always be able to |
| 33453 | 33550 | ** reacquire the read lock */ |
| 33454 | 33551 | rc = winLogError(SQLITE_IOERR_UNLOCK, osGetLastError(), |
| 33455 | | - "winUnlock", pFile->zPath); |
| 33552 | + "winUnlock", pFile->zPath); |
| 33456 | 33553 | } |
| 33457 | 33554 | } |
| 33458 | 33555 | if( type>=RESERVED_LOCK ){ |
| 33459 | 33556 | winUnlockFile(&pFile->h, RESERVED_BYTE, 0, 1, 0); |
| 33460 | 33557 | } |
| 33461 | 33558 | if( locktype==NO_LOCK && type>=SHARED_LOCK ){ |
| 33462 | | - unlockReadLock(pFile); |
| 33559 | + winUnlockReadLock(pFile); |
| 33463 | 33560 | } |
| 33464 | 33561 | if( type>=PENDING_LOCK ){ |
| 33465 | 33562 | winUnlockFile(&pFile->h, PENDING_BYTE, 0, 1, 0); |
| 33466 | 33563 | } |
| 33467 | 33564 | pFile->locktype = (u8)locktype; |
| | @@ -33484,15 +33581,14 @@ |
| 33484 | 33581 | }else{ |
| 33485 | 33582 | pFile->ctrlFlags |= mask; |
| 33486 | 33583 | } |
| 33487 | 33584 | } |
| 33488 | 33585 | |
| 33489 | | -/* Forward declaration */ |
| 33490 | | -static int getTempname(int nBuf, char *zBuf); |
| 33491 | | -#if SQLITE_MAX_MMAP_SIZE>0 |
| 33492 | | -static int winMapfile(winFile*, sqlite3_int64); |
| 33493 | | -#endif |
| 33586 | +/* Forward references to VFS helper methods used for temporary files */ |
| 33587 | +static int winGetTempname(sqlite3_vfs *, char **); |
| 33588 | +static int winIsDir(const void *); |
| 33589 | +static BOOL winIsDriveLetterAndColon(const char *); |
| 33494 | 33590 | |
| 33495 | 33591 | /* |
| 33496 | 33592 | ** Control and query of the open file handle. |
| 33497 | 33593 | */ |
| 33498 | 33594 | static int winFileControl(sqlite3_file *id, int op, void *pArg){ |
| | @@ -33548,30 +33644,30 @@ |
| 33548 | 33644 | return SQLITE_OK; |
| 33549 | 33645 | } |
| 33550 | 33646 | case SQLITE_FCNTL_WIN32_AV_RETRY: { |
| 33551 | 33647 | int *a = (int*)pArg; |
| 33552 | 33648 | if( a[0]>0 ){ |
| 33553 | | - win32IoerrRetry = a[0]; |
| 33649 | + winIoerrRetry = a[0]; |
| 33554 | 33650 | }else{ |
| 33555 | | - a[0] = win32IoerrRetry; |
| 33651 | + a[0] = winIoerrRetry; |
| 33556 | 33652 | } |
| 33557 | 33653 | if( a[1]>0 ){ |
| 33558 | | - win32IoerrRetryDelay = a[1]; |
| 33654 | + winIoerrRetryDelay = a[1]; |
| 33559 | 33655 | }else{ |
| 33560 | | - a[1] = win32IoerrRetryDelay; |
| 33656 | + a[1] = winIoerrRetryDelay; |
| 33561 | 33657 | } |
| 33562 | 33658 | OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); |
| 33563 | 33659 | return SQLITE_OK; |
| 33564 | 33660 | } |
| 33565 | 33661 | case SQLITE_FCNTL_TEMPFILENAME: { |
| 33566 | | - char *zTFile = sqlite3MallocZero( pFile->pVfs->mxPathname ); |
| 33567 | | - if( zTFile ){ |
| 33568 | | - getTempname(pFile->pVfs->mxPathname, zTFile); |
| 33662 | + char *zTFile = 0; |
| 33663 | + int rc = winGetTempname(pFile->pVfs, &zTFile); |
| 33664 | + if( rc==SQLITE_OK ){ |
| 33569 | 33665 | *(char**)pArg = zTFile; |
| 33570 | 33666 | } |
| 33571 | | - OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); |
| 33572 | | - return SQLITE_OK; |
| 33667 | + OSTRACE(("FCNTL file=%p, rc=%s\n", pFile->h, sqlite3ErrName(rc))); |
| 33668 | + return rc; |
| 33573 | 33669 | } |
| 33574 | 33670 | #if SQLITE_MAX_MMAP_SIZE>0 |
| 33575 | 33671 | case SQLITE_FCNTL_MMAP_SIZE: { |
| 33576 | 33672 | i64 newLimit = *(i64*)pArg; |
| 33577 | 33673 | int rc = SQLITE_OK; |
| | @@ -33584,11 +33680,11 @@ |
| 33584 | 33680 | if( pFile->mmapSize>0 ){ |
| 33585 | 33681 | (void)winUnmapfile(pFile); |
| 33586 | 33682 | rc = winMapfile(pFile, -1); |
| 33587 | 33683 | } |
| 33588 | 33684 | } |
| 33589 | | - OSTRACE(("FCNTL file=%p, rc=%d\n", pFile->h, rc)); |
| 33685 | + OSTRACE(("FCNTL file=%p, rc=%s\n", pFile->h, sqlite3ErrName(rc))); |
| 33590 | 33686 | return rc; |
| 33591 | 33687 | } |
| 33592 | 33688 | #endif |
| 33593 | 33689 | } |
| 33594 | 33690 | OSTRACE(("FCNTL file=%p, rc=SQLITE_NOTFOUND\n", pFile->h)); |
| | @@ -33900,11 +33996,11 @@ |
| 33900 | 33996 | */ |
| 33901 | 33997 | if( winShmSystemLock(pShmNode, _SHM_WRLCK, WIN_SHM_DMS, 1)==SQLITE_OK ){ |
| 33902 | 33998 | rc = winTruncate((sqlite3_file *)&pShmNode->hFile, 0); |
| 33903 | 33999 | if( rc!=SQLITE_OK ){ |
| 33904 | 34000 | rc = winLogError(SQLITE_IOERR_SHMOPEN, osGetLastError(), |
| 33905 | | - "winOpenShm", pDbFd->zPath); |
| 34001 | + "winOpenShm", pDbFd->zPath); |
| 33906 | 34002 | } |
| 33907 | 34003 | } |
| 33908 | 34004 | if( rc==SQLITE_OK ){ |
| 33909 | 34005 | winShmSystemLock(pShmNode, _SHM_UNLCK, WIN_SHM_DMS, 1); |
| 33910 | 34006 | rc = winShmSystemLock(pShmNode, _SHM_RDLCK, WIN_SHM_DMS, 1); |
| | @@ -34160,11 +34256,11 @@ |
| 34160 | 34256 | ** large enough to contain the requested region). |
| 34161 | 34257 | */ |
| 34162 | 34258 | rc = winFileSize((sqlite3_file *)&pShmNode->hFile, &sz); |
| 34163 | 34259 | if( rc!=SQLITE_OK ){ |
| 34164 | 34260 | rc = winLogError(SQLITE_IOERR_SHMSIZE, osGetLastError(), |
| 34165 | | - "winShmMap1", pDbFd->zPath); |
| 34261 | + "winShmMap1", pDbFd->zPath); |
| 34166 | 34262 | goto shmpage_out; |
| 34167 | 34263 | } |
| 34168 | 34264 | |
| 34169 | 34265 | if( sz<nByte ){ |
| 34170 | 34266 | /* The requested memory region does not exist. If isWrite is set to |
| | @@ -34175,11 +34271,11 @@ |
| 34175 | 34271 | */ |
| 34176 | 34272 | if( !isWrite ) goto shmpage_out; |
| 34177 | 34273 | rc = winTruncate((sqlite3_file *)&pShmNode->hFile, nByte); |
| 34178 | 34274 | if( rc!=SQLITE_OK ){ |
| 34179 | 34275 | rc = winLogError(SQLITE_IOERR_SHMSIZE, osGetLastError(), |
| 34180 | | - "winShmMap2", pDbFd->zPath); |
| 34276 | + "winShmMap2", pDbFd->zPath); |
| 34181 | 34277 | goto shmpage_out; |
| 34182 | 34278 | } |
| 34183 | 34279 | } |
| 34184 | 34280 | |
| 34185 | 34281 | /* Map the requested memory region into this processes address space. */ |
| | @@ -34229,11 +34325,11 @@ |
| 34229 | 34325 | szRegion, pMap ? "ok" : "failed")); |
| 34230 | 34326 | } |
| 34231 | 34327 | if( !pMap ){ |
| 34232 | 34328 | pShmNode->lastErrno = osGetLastError(); |
| 34233 | 34329 | rc = winLogError(SQLITE_IOERR_SHMMAP, pShmNode->lastErrno, |
| 34234 | | - "winShmMap3", pDbFd->zPath); |
| 34330 | + "winShmMap3", pDbFd->zPath); |
| 34235 | 34331 | if( hMap ) osCloseHandle(hMap); |
| 34236 | 34332 | goto shmpage_out; |
| 34237 | 34333 | } |
| 34238 | 34334 | |
| 34239 | 34335 | pShmNode->aRegion[pShmNode->nRegion].pMap = pMap; |
| | @@ -34277,11 +34373,11 @@ |
| 34277 | 34373 | pFile->lastErrno = osGetLastError(); |
| 34278 | 34374 | OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, pMapRegion=%p, " |
| 34279 | 34375 | "rc=SQLITE_IOERR_MMAP\n", osGetCurrentProcessId(), pFile, |
| 34280 | 34376 | pFile->pMapRegion)); |
| 34281 | 34377 | return winLogError(SQLITE_IOERR_MMAP, pFile->lastErrno, |
| 34282 | | - "winUnmap1", pFile->zPath); |
| 34378 | + "winUnmapfile1", pFile->zPath); |
| 34283 | 34379 | } |
| 34284 | 34380 | pFile->pMapRegion = 0; |
| 34285 | 34381 | pFile->mmapSize = 0; |
| 34286 | 34382 | pFile->mmapSizeActual = 0; |
| 34287 | 34383 | } |
| | @@ -34289,11 +34385,11 @@ |
| 34289 | 34385 | if( !osCloseHandle(pFile->hMap) ){ |
| 34290 | 34386 | pFile->lastErrno = osGetLastError(); |
| 34291 | 34387 | OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, hMap=%p, rc=SQLITE_IOERR_MMAP\n", |
| 34292 | 34388 | osGetCurrentProcessId(), pFile, pFile->hMap)); |
| 34293 | 34389 | return winLogError(SQLITE_IOERR_MMAP, pFile->lastErrno, |
| 34294 | | - "winUnmap2", pFile->zPath); |
| 34390 | + "winUnmapfile2", pFile->zPath); |
| 34295 | 34391 | } |
| 34296 | 34392 | pFile->hMap = NULL; |
| 34297 | 34393 | } |
| 34298 | 34394 | OSTRACE(("UNMAP-FILE pid=%lu, pFile=%p, rc=SQLITE_OK\n", |
| 34299 | 34395 | osGetCurrentProcessId(), pFile)); |
| | @@ -34364,14 +34460,14 @@ |
| 34364 | 34460 | (DWORD)(nMap & 0xffffffff), NULL); |
| 34365 | 34461 | #endif |
| 34366 | 34462 | if( pFd->hMap==NULL ){ |
| 34367 | 34463 | pFd->lastErrno = osGetLastError(); |
| 34368 | 34464 | rc = winLogError(SQLITE_IOERR_MMAP, pFd->lastErrno, |
| 34369 | | - "winMapfile", pFd->zPath); |
| 34465 | + "winMapfile1", pFd->zPath); |
| 34370 | 34466 | /* Log the error, but continue normal operation using xRead/xWrite */ |
| 34371 | | - OSTRACE(("MAP-FILE-CREATE pid=%lu, pFile=%p, rc=SQLITE_IOERR_MMAP\n", |
| 34372 | | - osGetCurrentProcessId(), pFd)); |
| 34467 | + OSTRACE(("MAP-FILE-CREATE pid=%lu, pFile=%p, rc=%s\n", |
| 34468 | + osGetCurrentProcessId(), pFd, sqlite3ErrName(rc))); |
| 34373 | 34469 | return SQLITE_OK; |
| 34374 | 34470 | } |
| 34375 | 34471 | assert( (nMap % winSysInfo.dwPageSize)==0 ); |
| 34376 | 34472 | assert( sizeof(SIZE_T)==sizeof(sqlite3_int64) || nMap<=0xffffffff ); |
| 34377 | 34473 | #if SQLITE_OS_WINRT |
| | @@ -34381,14 +34477,15 @@ |
| 34381 | 34477 | #endif |
| 34382 | 34478 | if( pNew==NULL ){ |
| 34383 | 34479 | osCloseHandle(pFd->hMap); |
| 34384 | 34480 | pFd->hMap = NULL; |
| 34385 | 34481 | pFd->lastErrno = osGetLastError(); |
| 34386 | | - winLogError(SQLITE_IOERR_MMAP, pFd->lastErrno, |
| 34387 | | - "winMapfile", pFd->zPath); |
| 34388 | | - OSTRACE(("MAP-FILE-MAP pid=%lu, pFile=%p, rc=SQLITE_IOERR_MMAP\n", |
| 34389 | | - osGetCurrentProcessId(), pFd)); |
| 34482 | + rc = winLogError(SQLITE_IOERR_MMAP, pFd->lastErrno, |
| 34483 | + "winMapfile2", pFd->zPath); |
| 34484 | + /* Log the error, but continue normal operation using xRead/xWrite */ |
| 34485 | + OSTRACE(("MAP-FILE-MAP pid=%lu, pFile=%p, rc=%s\n", |
| 34486 | + osGetCurrentProcessId(), pFd, sqlite3ErrName(rc))); |
| 34390 | 34487 | return SQLITE_OK; |
| 34391 | 34488 | } |
| 34392 | 34489 | pFd->pMapRegion = pNew; |
| 34393 | 34490 | pFd->mmapSize = nMap; |
| 34394 | 34491 | pFd->mmapSizeActual = nMap; |
| | @@ -34522,21 +34619,40 @@ |
| 34522 | 34619 | **************************** sqlite3_vfs methods **************************** |
| 34523 | 34620 | ** |
| 34524 | 34621 | ** This division contains the implementation of methods on the |
| 34525 | 34622 | ** sqlite3_vfs object. |
| 34526 | 34623 | */ |
| 34624 | + |
| 34625 | +/* |
| 34626 | +** Convert a filename from whatever the underlying operating system |
| 34627 | +** supports for filenames into UTF-8. Space to hold the result is |
| 34628 | +** obtained from malloc and must be freed by the calling function. |
| 34629 | +*/ |
| 34630 | +static char *winConvertToUtf8Filename(const void *zFilename){ |
| 34631 | + char *zConverted = 0; |
| 34632 | + if( osIsNT() ){ |
| 34633 | + zConverted = winUnicodeToUtf8(zFilename); |
| 34634 | + } |
| 34635 | +#ifdef SQLITE_WIN32_HAS_ANSI |
| 34636 | + else{ |
| 34637 | + zConverted = sqlite3_win32_mbcs_to_utf8(zFilename); |
| 34638 | + } |
| 34639 | +#endif |
| 34640 | + /* caller will handle out of memory */ |
| 34641 | + return zConverted; |
| 34642 | +} |
| 34527 | 34643 | |
| 34528 | 34644 | /* |
| 34529 | 34645 | ** Convert a UTF-8 filename into whatever form the underlying |
| 34530 | 34646 | ** operating system wants filenames in. Space to hold the result |
| 34531 | 34647 | ** is obtained from malloc and must be freed by the calling |
| 34532 | 34648 | ** function. |
| 34533 | 34649 | */ |
| 34534 | | -static void *convertUtf8Filename(const char *zFilename){ |
| 34650 | +static void *winConvertFromUtf8Filename(const char *zFilename){ |
| 34535 | 34651 | void *zConverted = 0; |
| 34536 | | - if( isNT() ){ |
| 34537 | | - zConverted = utf8ToUnicode(zFilename); |
| 34652 | + if( osIsNT() ){ |
| 34653 | + zConverted = winUtf8ToUnicode(zFilename); |
| 34538 | 34654 | } |
| 34539 | 34655 | #ifdef SQLITE_WIN32_HAS_ANSI |
| 34540 | 34656 | else{ |
| 34541 | 34657 | zConverted = sqlite3_win32_utf8_to_mbcs(zFilename); |
| 34542 | 34658 | } |
| | @@ -34544,117 +34660,220 @@ |
| 34544 | 34660 | /* caller will handle out of memory */ |
| 34545 | 34661 | return zConverted; |
| 34546 | 34662 | } |
| 34547 | 34663 | |
| 34548 | 34664 | /* |
| 34549 | | -** Maximum pathname length (in bytes) for windows. The MAX_PATH macro is |
| 34550 | | -** in characters, so we allocate 3 bytes per character assuming worst-case |
| 34551 | | -** 3-bytes-per-character UTF8. |
| 34665 | +** This function returns non-zero if the specified UTF-8 string buffer |
| 34666 | +** ends with a directory separator character. |
| 34552 | 34667 | */ |
| 34553 | | -#ifndef SQLITE_WIN32_MAX_PATH |
| 34554 | | -# define SQLITE_WIN32_MAX_PATH (MAX_PATH*3) |
| 34555 | | -#endif |
| 34668 | +static int winEndsInDirSep(char *zBuf){ |
| 34669 | + if( zBuf ){ |
| 34670 | + int nLen = sqlite3Strlen30(zBuf); |
| 34671 | + return nLen>0 && winIsDirSep(zBuf[nLen-1]); |
| 34672 | + } |
| 34673 | + return 0; |
| 34674 | +} |
| 34556 | 34675 | |
| 34557 | 34676 | /* |
| 34558 | | -** Create a temporary file name in zBuf. zBuf must be big enough to |
| 34559 | | -** hold at pVfs->mxPathname characters. |
| 34677 | +** Create a temporary file name and store the resulting pointer into pzBuf. |
| 34678 | +** The pointer returned in pzBuf must be freed via sqlite3_free(). |
| 34560 | 34679 | */ |
| 34561 | | -static int getTempname(int nBuf, char *zBuf){ |
| 34680 | +static int winGetTempname(sqlite3_vfs *pVfs, char **pzBuf){ |
| 34562 | 34681 | static char zChars[] = |
| 34563 | 34682 | "abcdefghijklmnopqrstuvwxyz" |
| 34564 | 34683 | "ABCDEFGHIJKLMNOPQRSTUVWXYZ" |
| 34565 | 34684 | "0123456789"; |
| 34566 | 34685 | size_t i, j; |
| 34567 | | - int nTempPath; |
| 34568 | | - char zTempPath[SQLITE_WIN32_MAX_PATH+2]; |
| 34686 | + int nBuf, nLen; |
| 34687 | + char *zBuf; |
| 34569 | 34688 | |
| 34570 | 34689 | /* It's odd to simulate an io-error here, but really this is just |
| 34571 | 34690 | ** using the io-error infrastructure to test that SQLite handles this |
| 34572 | 34691 | ** function failing. |
| 34573 | 34692 | */ |
| 34574 | 34693 | SimulateIOError( return SQLITE_IOERR ); |
| 34575 | 34694 | |
| 34695 | + /* Allocate a temporary buffer to store the fully qualified file |
| 34696 | + ** name for the temporary file. If this fails, we cannot continue. |
| 34697 | + */ |
| 34698 | + nBuf = pVfs->mxPathname; |
| 34699 | + zBuf = sqlite3MallocZero( nBuf+2 ); |
| 34700 | + if( !zBuf ){ |
| 34701 | + OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); |
| 34702 | + return SQLITE_IOERR_NOMEM; |
| 34703 | + } |
| 34704 | + |
| 34705 | + /* Figure out the effective temporary directory. First, check if one |
| 34706 | + ** has been explicitly set by the application; otherwise, use the one |
| 34707 | + ** configured by the operating system. |
| 34708 | + */ |
| 34709 | + assert( nBuf>30 ); |
| 34576 | 34710 | if( sqlite3_temp_directory ){ |
| 34577 | | - sqlite3_snprintf(SQLITE_WIN32_MAX_PATH-30, zTempPath, "%s", |
| 34578 | | - sqlite3_temp_directory); |
| 34711 | + sqlite3_snprintf(nBuf-30, zBuf, "%s%s", sqlite3_temp_directory, |
| 34712 | + winEndsInDirSep(sqlite3_temp_directory) ? "" : |
| 34713 | + winGetDirDep()); |
| 34579 | 34714 | } |
| 34580 | | -#if !SQLITE_OS_WINRT |
| 34581 | | - else if( isNT() ){ |
| 34715 | +#if defined(__CYGWIN__) |
| 34716 | + else{ |
| 34717 | + static const char *azDirs[] = { |
| 34718 | + 0, /* getenv("SQLITE_TMPDIR") */ |
| 34719 | + 0, /* getenv("TMPDIR") */ |
| 34720 | + 0, /* getenv("TMP") */ |
| 34721 | + 0, /* getenv("TEMP") */ |
| 34722 | + 0, /* getenv("USERPROFILE") */ |
| 34723 | + "/var/tmp", |
| 34724 | + "/usr/tmp", |
| 34725 | + "/tmp", |
| 34726 | + ".", |
| 34727 | + 0 /* List terminator */ |
| 34728 | + }; |
| 34729 | + unsigned int i; |
| 34730 | + const char *zDir = 0; |
| 34731 | + |
| 34732 | + if( !azDirs[0] ) azDirs[0] = getenv("SQLITE_TMPDIR"); |
| 34733 | + if( !azDirs[1] ) azDirs[1] = getenv("TMPDIR"); |
| 34734 | + if( !azDirs[2] ) azDirs[2] = getenv("TMP"); |
| 34735 | + if( !azDirs[3] ) azDirs[3] = getenv("TEMP"); |
| 34736 | + if( !azDirs[4] ) azDirs[4] = getenv("USERPROFILE"); |
| 34737 | + for(i=0; i<sizeof(azDirs)/sizeof(azDirs[0]); zDir=azDirs[i++]){ |
| 34738 | + void *zConverted; |
| 34739 | + if( zDir==0 ) continue; |
| 34740 | + /* If the path starts with a drive letter followed by the colon |
| 34741 | + ** character, assume it is already a native Win32 path; otherwise, |
| 34742 | + ** it must be converted to a native Win32 path prior via the Cygwin |
| 34743 | + ** API prior to using it. |
| 34744 | + */ |
| 34745 | + if( winIsDriveLetterAndColon(zDir) ){ |
| 34746 | + zConverted = winConvertFromUtf8Filename(zDir); |
| 34747 | + if( !zConverted ){ |
| 34748 | + OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); |
| 34749 | + return SQLITE_IOERR_NOMEM; |
| 34750 | + } |
| 34751 | + if( winIsDir(zConverted) ){ |
| 34752 | + sqlite3_snprintf(nBuf-30, zBuf, "%s", zDir); |
| 34753 | + sqlite3_free(zConverted); |
| 34754 | + break; |
| 34755 | + } |
| 34756 | + sqlite3_free(zConverted); |
| 34757 | + }else{ |
| 34758 | + zConverted = sqlite3MallocZero( nBuf+1 ); |
| 34759 | + if( !zConverted ){ |
| 34760 | + OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); |
| 34761 | + return SQLITE_IOERR_NOMEM; |
| 34762 | + } |
| 34763 | + if( cygwin_conv_path( |
| 34764 | + osIsNT() ? CCP_POSIX_TO_WIN_W : CCP_POSIX_TO_WIN_A, zDir, |
| 34765 | + zConverted, nBuf+1)<0 ){ |
| 34766 | + sqlite3_free(zConverted); |
| 34767 | + OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_CONVPATH\n")); |
| 34768 | + return winLogError(SQLITE_IOERR_CONVPATH, (DWORD)errno, |
| 34769 | + "winGetTempname1", zDir); |
| 34770 | + } |
| 34771 | + if( winIsDir(zConverted) ){ |
| 34772 | + /* At this point, we know the candidate directory exists and should |
| 34773 | + ** be used. However, we may need to convert the string containing |
| 34774 | + ** its name into UTF-8 (i.e. if it is UTF-16 right now). |
| 34775 | + */ |
| 34776 | + if( osIsNT() ){ |
| 34777 | + char *zUtf8 = winUnicodeToUtf8(zConverted); |
| 34778 | + if( !zUtf8 ){ |
| 34779 | + sqlite3_free(zConverted); |
| 34780 | + OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); |
| 34781 | + return SQLITE_IOERR_NOMEM; |
| 34782 | + } |
| 34783 | + sqlite3_snprintf(nBuf-30, zBuf, "%s", zUtf8); |
| 34784 | + sqlite3_free(zUtf8); |
| 34785 | + sqlite3_free(zConverted); |
| 34786 | + break; |
| 34787 | + }else{ |
| 34788 | + sqlite3_snprintf(nBuf-30, zBuf, "%s", zConverted); |
| 34789 | + sqlite3_free(zConverted); |
| 34790 | + break; |
| 34791 | + } |
| 34792 | + } |
| 34793 | + sqlite3_free(zConverted); |
| 34794 | + } |
| 34795 | + break; |
| 34796 | + } |
| 34797 | + } |
| 34798 | +#elif !SQLITE_OS_WINRT && !defined(__CYGWIN__) |
| 34799 | + else if( osIsNT() ){ |
| 34582 | 34800 | char *zMulti; |
| 34583 | | - WCHAR zWidePath[MAX_PATH]; |
| 34584 | | - if( osGetTempPathW(MAX_PATH-30, zWidePath)==0 ){ |
| 34801 | + LPWSTR zWidePath = sqlite3MallocZero( nBuf*sizeof(WCHAR) ); |
| 34802 | + if( !zWidePath ){ |
| 34803 | + sqlite3_free(zBuf); |
| 34804 | + OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); |
| 34805 | + return SQLITE_IOERR_NOMEM; |
| 34806 | + } |
| 34807 | + if( osGetTempPathW(nBuf, zWidePath)==0 ){ |
| 34808 | + sqlite3_free(zWidePath); |
| 34809 | + sqlite3_free(zBuf); |
| 34585 | 34810 | OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_GETTEMPPATH\n")); |
| 34586 | | - return SQLITE_IOERR_GETTEMPPATH; |
| 34811 | + return winLogError(SQLITE_IOERR_GETTEMPPATH, osGetLastError(), |
| 34812 | + "winGetTempname1", 0); |
| 34587 | 34813 | } |
| 34588 | | - zMulti = unicodeToUtf8(zWidePath); |
| 34814 | + zMulti = winUnicodeToUtf8(zWidePath); |
| 34589 | 34815 | if( zMulti ){ |
| 34590 | | - sqlite3_snprintf(SQLITE_WIN32_MAX_PATH-30, zTempPath, "%s", zMulti); |
| 34816 | + sqlite3_snprintf(nBuf-30, zBuf, "%s", zMulti); |
| 34591 | 34817 | sqlite3_free(zMulti); |
| 34818 | + sqlite3_free(zWidePath); |
| 34592 | 34819 | }else{ |
| 34820 | + sqlite3_free(zWidePath); |
| 34821 | + sqlite3_free(zBuf); |
| 34593 | 34822 | OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); |
| 34594 | 34823 | return SQLITE_IOERR_NOMEM; |
| 34595 | 34824 | } |
| 34596 | 34825 | } |
| 34597 | 34826 | #ifdef SQLITE_WIN32_HAS_ANSI |
| 34598 | 34827 | else{ |
| 34599 | 34828 | char *zUtf8; |
| 34600 | | - char zMbcsPath[SQLITE_WIN32_MAX_PATH]; |
| 34601 | | - if( osGetTempPathA(SQLITE_WIN32_MAX_PATH-30, zMbcsPath)==0 ){ |
| 34829 | + char *zMbcsPath = sqlite3MallocZero( nBuf ); |
| 34830 | + if( !zMbcsPath ){ |
| 34831 | + sqlite3_free(zBuf); |
| 34832 | + OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); |
| 34833 | + return SQLITE_IOERR_NOMEM; |
| 34834 | + } |
| 34835 | + if( osGetTempPathA(nBuf, zMbcsPath)==0 ){ |
| 34836 | + sqlite3_free(zBuf); |
| 34602 | 34837 | OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_GETTEMPPATH\n")); |
| 34603 | | - return SQLITE_IOERR_GETTEMPPATH; |
| 34838 | + return winLogError(SQLITE_IOERR_GETTEMPPATH, osGetLastError(), |
| 34839 | + "winGetTempname2", 0); |
| 34604 | 34840 | } |
| 34605 | 34841 | zUtf8 = sqlite3_win32_mbcs_to_utf8(zMbcsPath); |
| 34606 | 34842 | if( zUtf8 ){ |
| 34607 | | - sqlite3_snprintf(SQLITE_WIN32_MAX_PATH-30, zTempPath, "%s", zUtf8); |
| 34843 | + sqlite3_snprintf(nBuf-30, zBuf, "%s", zUtf8); |
| 34608 | 34844 | sqlite3_free(zUtf8); |
| 34609 | 34845 | }else{ |
| 34846 | + sqlite3_free(zBuf); |
| 34610 | 34847 | OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); |
| 34611 | 34848 | return SQLITE_IOERR_NOMEM; |
| 34612 | 34849 | } |
| 34613 | 34850 | } |
| 34614 | | -#else |
| 34615 | | - else{ |
| 34616 | | - /* |
| 34617 | | - ** Compiled without ANSI support and the current operating system |
| 34618 | | - ** is not Windows NT; therefore, just zero the temporary buffer. |
| 34619 | | - */ |
| 34620 | | - memset(zTempPath, 0, SQLITE_WIN32_MAX_PATH+2); |
| 34621 | | - } |
| 34622 | 34851 | #endif /* SQLITE_WIN32_HAS_ANSI */ |
| 34623 | | -#else |
| 34624 | | - else{ |
| 34625 | | - /* |
| 34626 | | - ** Compiled for WinRT and the sqlite3_temp_directory is not set; |
| 34627 | | - ** therefore, just zero the temporary buffer. |
| 34628 | | - */ |
| 34629 | | - memset(zTempPath, 0, SQLITE_WIN32_MAX_PATH+2); |
| 34630 | | - } |
| 34631 | 34852 | #endif /* !SQLITE_OS_WINRT */ |
| 34632 | 34853 | |
| 34633 | 34854 | /* Check that the output buffer is large enough for the temporary file |
| 34634 | 34855 | ** name. If it is not, return SQLITE_ERROR. |
| 34635 | 34856 | */ |
| 34636 | | - nTempPath = sqlite3Strlen30(zTempPath); |
| 34857 | + nLen = sqlite3Strlen30(zBuf); |
| 34637 | 34858 | |
| 34638 | | - if( (nTempPath + sqlite3Strlen30(SQLITE_TEMP_FILE_PREFIX) + 18) >= nBuf ){ |
| 34859 | + if( (nLen + sqlite3Strlen30(SQLITE_TEMP_FILE_PREFIX) + 18) >= nBuf ){ |
| 34860 | + sqlite3_free(zBuf); |
| 34639 | 34861 | OSTRACE(("TEMP-FILENAME rc=SQLITE_ERROR\n")); |
| 34640 | | - return SQLITE_ERROR; |
| 34862 | + return winLogError(SQLITE_ERROR, 0, "winGetTempname3", 0); |
| 34641 | 34863 | } |
| 34642 | 34864 | |
| 34643 | | - for(i=nTempPath; i>0 && zTempPath[i-1]=='\\'; i--){} |
| 34644 | | - zTempPath[i] = 0; |
| 34865 | + sqlite3_snprintf(nBuf-18-nLen, zBuf+nLen, SQLITE_TEMP_FILE_PREFIX); |
| 34645 | 34866 | |
| 34646 | | - sqlite3_snprintf(nBuf-18, zBuf, (nTempPath > 0) ? |
| 34647 | | - "%s\\"SQLITE_TEMP_FILE_PREFIX : SQLITE_TEMP_FILE_PREFIX, |
| 34648 | | - zTempPath); |
| 34649 | 34867 | j = sqlite3Strlen30(zBuf); |
| 34650 | 34868 | sqlite3_randomness(15, &zBuf[j]); |
| 34651 | 34869 | for(i=0; i<15; i++, j++){ |
| 34652 | 34870 | zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ]; |
| 34653 | 34871 | } |
| 34654 | 34872 | zBuf[j] = 0; |
| 34655 | 34873 | zBuf[j+1] = 0; |
| 34874 | + *pzBuf = zBuf; |
| 34656 | 34875 | |
| 34657 | 34876 | OSTRACE(("TEMP-FILENAME name=%s, rc=SQLITE_OK\n", zBuf)); |
| 34658 | 34877 | return SQLITE_OK; |
| 34659 | 34878 | } |
| 34660 | 34879 | |
| | @@ -34666,17 +34885,17 @@ |
| 34666 | 34885 | static int winIsDir(const void *zConverted){ |
| 34667 | 34886 | DWORD attr; |
| 34668 | 34887 | int rc = 0; |
| 34669 | 34888 | DWORD lastErrno; |
| 34670 | 34889 | |
| 34671 | | - if( isNT() ){ |
| 34890 | + if( osIsNT() ){ |
| 34672 | 34891 | int cnt = 0; |
| 34673 | 34892 | WIN32_FILE_ATTRIBUTE_DATA sAttrData; |
| 34674 | 34893 | memset(&sAttrData, 0, sizeof(sAttrData)); |
| 34675 | 34894 | while( !(rc = osGetFileAttributesExW((LPCWSTR)zConverted, |
| 34676 | 34895 | GetFileExInfoStandard, |
| 34677 | | - &sAttrData)) && retryIoerr(&cnt, &lastErrno) ){} |
| 34896 | + &sAttrData)) && winRetryIoerr(&cnt, &lastErrno) ){} |
| 34678 | 34897 | if( !rc ){ |
| 34679 | 34898 | return 0; /* Invalid name? */ |
| 34680 | 34899 | } |
| 34681 | 34900 | attr = sAttrData.dwFileAttributes; |
| 34682 | 34901 | #if SQLITE_OS_WINCE==0 |
| | @@ -34689,11 +34908,11 @@ |
| 34689 | 34908 | |
| 34690 | 34909 | /* |
| 34691 | 34910 | ** Open a file. |
| 34692 | 34911 | */ |
| 34693 | 34912 | static int winOpen( |
| 34694 | | - sqlite3_vfs *pVfs, /* Not used */ |
| 34913 | + sqlite3_vfs *pVfs, /* Used to get maximum path name length */ |
| 34695 | 34914 | const char *zName, /* Name of the file (UTF-8) */ |
| 34696 | 34915 | sqlite3_file *id, /* Write the SQLite file handle here */ |
| 34697 | 34916 | int flags, /* Open mode flags */ |
| 34698 | 34917 | int *pOutFlags /* Status return flags */ |
| 34699 | 34918 | ){ |
| | @@ -34712,11 +34931,11 @@ |
| 34712 | 34931 | int cnt = 0; |
| 34713 | 34932 | |
| 34714 | 34933 | /* If argument zPath is a NULL pointer, this function is required to open |
| 34715 | 34934 | ** a temporary file. Use this buffer to store the file name in. |
| 34716 | 34935 | */ |
| 34717 | | - char zTmpname[SQLITE_WIN32_MAX_PATH+2]; /* Buffer used to create temp filename */ |
| 34936 | + char *zTmpname = 0; /* For temporary filename, if necessary. */ |
| 34718 | 34937 | |
| 34719 | 34938 | int rc = SQLITE_OK; /* Function Return Code */ |
| 34720 | 34939 | #if !defined(NDEBUG) || SQLITE_OS_WINCE |
| 34721 | 34940 | int eType = flags&0xFFFFFF00; /* Type of file to open */ |
| 34722 | 34941 | #endif |
| | @@ -34767,22 +34986,22 @@ |
| 34767 | 34986 | assert( pFile!=0 ); |
| 34768 | 34987 | memset(pFile, 0, sizeof(winFile)); |
| 34769 | 34988 | pFile->h = INVALID_HANDLE_VALUE; |
| 34770 | 34989 | |
| 34771 | 34990 | #if SQLITE_OS_WINRT |
| 34772 | | - if( !sqlite3_temp_directory ){ |
| 34991 | + if( !zUtf8Name && !sqlite3_temp_directory ){ |
| 34773 | 34992 | sqlite3_log(SQLITE_ERROR, |
| 34774 | 34993 | "sqlite3_temp_directory variable should be set for WinRT"); |
| 34775 | 34994 | } |
| 34776 | 34995 | #endif |
| 34777 | 34996 | |
| 34778 | 34997 | /* If the second argument to this function is NULL, generate a |
| 34779 | 34998 | ** temporary file name to use |
| 34780 | 34999 | */ |
| 34781 | 35000 | if( !zUtf8Name ){ |
| 34782 | | - assert(isDelete && !isOpenJournal); |
| 34783 | | - rc = getTempname(SQLITE_WIN32_MAX_PATH+2, zTmpname); |
| 35001 | + assert( isDelete && !isOpenJournal ); |
| 35002 | + rc = winGetTempname(pVfs, &zTmpname); |
| 34784 | 35003 | if( rc!=SQLITE_OK ){ |
| 34785 | 35004 | OSTRACE(("OPEN name=%s, rc=%s", zUtf8Name, sqlite3ErrName(rc))); |
| 34786 | 35005 | return rc; |
| 34787 | 35006 | } |
| 34788 | 35007 | zUtf8Name = zTmpname; |
| | @@ -34791,21 +35010,23 @@ |
| 34791 | 35010 | /* Database filenames are double-zero terminated if they are not |
| 34792 | 35011 | ** URIs with parameters. Hence, they can always be passed into |
| 34793 | 35012 | ** sqlite3_uri_parameter(). |
| 34794 | 35013 | */ |
| 34795 | 35014 | assert( (eType!=SQLITE_OPEN_MAIN_DB) || (flags & SQLITE_OPEN_URI) || |
| 34796 | | - zUtf8Name[strlen(zUtf8Name)+1]==0 ); |
| 35015 | + zUtf8Name[sqlite3Strlen30(zUtf8Name)+1]==0 ); |
| 34797 | 35016 | |
| 34798 | 35017 | /* Convert the filename to the system encoding. */ |
| 34799 | | - zConverted = convertUtf8Filename(zUtf8Name); |
| 35018 | + zConverted = winConvertFromUtf8Filename(zUtf8Name); |
| 34800 | 35019 | if( zConverted==0 ){ |
| 35020 | + sqlite3_free(zTmpname); |
| 34801 | 35021 | OSTRACE(("OPEN name=%s, rc=SQLITE_IOERR_NOMEM", zUtf8Name)); |
| 34802 | 35022 | return SQLITE_IOERR_NOMEM; |
| 34803 | 35023 | } |
| 34804 | 35024 | |
| 34805 | 35025 | if( winIsDir(zConverted) ){ |
| 34806 | 35026 | sqlite3_free(zConverted); |
| 35027 | + sqlite3_free(zTmpname); |
| 34807 | 35028 | OSTRACE(("OPEN name=%s, rc=SQLITE_CANTOPEN_ISDIR", zUtf8Name)); |
| 34808 | 35029 | return SQLITE_CANTOPEN_ISDIR; |
| 34809 | 35030 | } |
| 34810 | 35031 | |
| 34811 | 35032 | if( isReadWrite ){ |
| | @@ -34848,11 +35069,11 @@ |
| 34848 | 35069 | ** better if FILE_FLAG_RANDOM_ACCESS is used. Ticket #2699. */ |
| 34849 | 35070 | #if SQLITE_OS_WINCE |
| 34850 | 35071 | dwFlagsAndAttributes |= FILE_FLAG_RANDOM_ACCESS; |
| 34851 | 35072 | #endif |
| 34852 | 35073 | |
| 34853 | | - if( isNT() ){ |
| 35074 | + if( osIsNT() ){ |
| 34854 | 35075 | #if SQLITE_OS_WINRT |
| 34855 | 35076 | CREATEFILE2_EXTENDED_PARAMETERS extendedParameters; |
| 34856 | 35077 | extendedParameters.dwSize = sizeof(CREATEFILE2_EXTENDED_PARAMETERS); |
| 34857 | 35078 | extendedParameters.dwFileAttributes = |
| 34858 | 35079 | dwFlagsAndAttributes & FILE_ATTRIBUTE_MASK; |
| | @@ -34863,21 +35084,21 @@ |
| 34863 | 35084 | while( (h = osCreateFile2((LPCWSTR)zConverted, |
| 34864 | 35085 | dwDesiredAccess, |
| 34865 | 35086 | dwShareMode, |
| 34866 | 35087 | dwCreationDisposition, |
| 34867 | 35088 | &extendedParameters))==INVALID_HANDLE_VALUE && |
| 34868 | | - retryIoerr(&cnt, &lastErrno) ){ |
| 35089 | + winRetryIoerr(&cnt, &lastErrno) ){ |
| 34869 | 35090 | /* Noop */ |
| 34870 | 35091 | } |
| 34871 | 35092 | #else |
| 34872 | 35093 | while( (h = osCreateFileW((LPCWSTR)zConverted, |
| 34873 | 35094 | dwDesiredAccess, |
| 34874 | 35095 | dwShareMode, NULL, |
| 34875 | 35096 | dwCreationDisposition, |
| 34876 | 35097 | dwFlagsAndAttributes, |
| 34877 | 35098 | NULL))==INVALID_HANDLE_VALUE && |
| 34878 | | - retryIoerr(&cnt, &lastErrno) ){ |
| 35099 | + winRetryIoerr(&cnt, &lastErrno) ){ |
| 34879 | 35100 | /* Noop */ |
| 34880 | 35101 | } |
| 34881 | 35102 | #endif |
| 34882 | 35103 | } |
| 34883 | 35104 | #ifdef SQLITE_WIN32_HAS_ANSI |
| | @@ -34886,24 +35107,25 @@ |
| 34886 | 35107 | dwDesiredAccess, |
| 34887 | 35108 | dwShareMode, NULL, |
| 34888 | 35109 | dwCreationDisposition, |
| 34889 | 35110 | dwFlagsAndAttributes, |
| 34890 | 35111 | NULL))==INVALID_HANDLE_VALUE && |
| 34891 | | - retryIoerr(&cnt, &lastErrno) ){ |
| 35112 | + winRetryIoerr(&cnt, &lastErrno) ){ |
| 34892 | 35113 | /* Noop */ |
| 34893 | 35114 | } |
| 34894 | 35115 | } |
| 34895 | 35116 | #endif |
| 34896 | | - logIoerr(cnt); |
| 35117 | + winLogIoerr(cnt); |
| 34897 | 35118 | |
| 34898 | 35119 | OSTRACE(("OPEN file=%p, name=%s, access=%lx, rc=%s\n", h, zUtf8Name, |
| 34899 | 35120 | dwDesiredAccess, (h==INVALID_HANDLE_VALUE) ? "failed" : "ok")); |
| 34900 | 35121 | |
| 34901 | 35122 | if( h==INVALID_HANDLE_VALUE ){ |
| 34902 | 35123 | pFile->lastErrno = lastErrno; |
| 34903 | 35124 | winLogError(SQLITE_CANTOPEN, pFile->lastErrno, "winOpen", zUtf8Name); |
| 34904 | 35125 | sqlite3_free(zConverted); |
| 35126 | + sqlite3_free(zTmpname); |
| 34905 | 35127 | if( isReadWrite && !isExclusive ){ |
| 34906 | 35128 | return winOpen(pVfs, zName, id, |
| 34907 | 35129 | ((flags|SQLITE_OPEN_READONLY) & |
| 34908 | 35130 | ~(SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE)), |
| 34909 | 35131 | pOutFlags); |
| | @@ -34928,19 +35150,21 @@ |
| 34928 | 35150 | if( isReadWrite && eType==SQLITE_OPEN_MAIN_DB |
| 34929 | 35151 | && (rc = winceCreateLock(zName, pFile))!=SQLITE_OK |
| 34930 | 35152 | ){ |
| 34931 | 35153 | osCloseHandle(h); |
| 34932 | 35154 | sqlite3_free(zConverted); |
| 35155 | + sqlite3_free(zTmpname); |
| 34933 | 35156 | OSTRACE(("OPEN-CE-LOCK name=%s, rc=%s\n", zName, sqlite3ErrName(rc))); |
| 34934 | 35157 | return rc; |
| 34935 | 35158 | } |
| 34936 | 35159 | if( isTemp ){ |
| 34937 | 35160 | pFile->zDeleteOnClose = zConverted; |
| 34938 | 35161 | }else |
| 34939 | 35162 | #endif |
| 34940 | 35163 | { |
| 34941 | 35164 | sqlite3_free(zConverted); |
| 35165 | + sqlite3_free(zTmpname); |
| 34942 | 35166 | } |
| 34943 | 35167 | |
| 34944 | 35168 | pFile->pMethod = &winIoMethod; |
| 34945 | 35169 | pFile->pVfs = pVfs; |
| 34946 | 35170 | pFile->h = h; |
| | @@ -34990,15 +35214,16 @@ |
| 34990 | 35214 | UNUSED_PARAMETER(syncDir); |
| 34991 | 35215 | |
| 34992 | 35216 | SimulateIOError(return SQLITE_IOERR_DELETE); |
| 34993 | 35217 | OSTRACE(("DELETE name=%s, syncDir=%d\n", zFilename, syncDir)); |
| 34994 | 35218 | |
| 34995 | | - zConverted = convertUtf8Filename(zFilename); |
| 35219 | + zConverted = winConvertFromUtf8Filename(zFilename); |
| 34996 | 35220 | if( zConverted==0 ){ |
| 35221 | + OSTRACE(("DELETE name=%s, rc=SQLITE_IOERR_NOMEM\n", zFilename)); |
| 34997 | 35222 | return SQLITE_IOERR_NOMEM; |
| 34998 | 35223 | } |
| 34999 | | - if( isNT() ){ |
| 35224 | + if( osIsNT() ){ |
| 35000 | 35225 | do { |
| 35001 | 35226 | #if SQLITE_OS_WINRT |
| 35002 | 35227 | WIN32_FILE_ATTRIBUTE_DATA sAttrData; |
| 35003 | 35228 | memset(&sAttrData, 0, sizeof(sAttrData)); |
| 35004 | 35229 | if ( osGetFileAttributesExW(zConverted, GetFileExInfoStandard, |
| | @@ -35033,11 +35258,11 @@ |
| 35033 | 35258 | } |
| 35034 | 35259 | if ( osDeleteFileW(zConverted) ){ |
| 35035 | 35260 | rc = SQLITE_OK; /* Deleted OK. */ |
| 35036 | 35261 | break; |
| 35037 | 35262 | } |
| 35038 | | - if ( !retryIoerr(&cnt, &lastErrno) ){ |
| 35263 | + if ( !winRetryIoerr(&cnt, &lastErrno) ){ |
| 35039 | 35264 | rc = SQLITE_ERROR; /* No more retries. */ |
| 35040 | 35265 | break; |
| 35041 | 35266 | } |
| 35042 | 35267 | } while(1); |
| 35043 | 35268 | } |
| | @@ -35061,22 +35286,21 @@ |
| 35061 | 35286 | } |
| 35062 | 35287 | if ( osDeleteFileA(zConverted) ){ |
| 35063 | 35288 | rc = SQLITE_OK; /* Deleted OK. */ |
| 35064 | 35289 | break; |
| 35065 | 35290 | } |
| 35066 | | - if ( !retryIoerr(&cnt, &lastErrno) ){ |
| 35291 | + if ( !winRetryIoerr(&cnt, &lastErrno) ){ |
| 35067 | 35292 | rc = SQLITE_ERROR; /* No more retries. */ |
| 35068 | 35293 | break; |
| 35069 | 35294 | } |
| 35070 | 35295 | } while(1); |
| 35071 | 35296 | } |
| 35072 | 35297 | #endif |
| 35073 | 35298 | if( rc && rc!=SQLITE_IOERR_DELETE_NOENT ){ |
| 35074 | | - rc = winLogError(SQLITE_IOERR_DELETE, lastErrno, |
| 35075 | | - "winDelete", zFilename); |
| 35299 | + rc = winLogError(SQLITE_IOERR_DELETE, lastErrno, "winDelete", zFilename); |
| 35076 | 35300 | }else{ |
| 35077 | | - logIoerr(cnt); |
| 35301 | + winLogIoerr(cnt); |
| 35078 | 35302 | } |
| 35079 | 35303 | sqlite3_free(zConverted); |
| 35080 | 35304 | OSTRACE(("DELETE name=%s, rc=%s\n", zFilename, sqlite3ErrName(rc))); |
| 35081 | 35305 | return rc; |
| 35082 | 35306 | } |
| | @@ -35098,22 +35322,22 @@ |
| 35098 | 35322 | |
| 35099 | 35323 | SimulateIOError( return SQLITE_IOERR_ACCESS; ); |
| 35100 | 35324 | OSTRACE(("ACCESS name=%s, flags=%x, pResOut=%p\n", |
| 35101 | 35325 | zFilename, flags, pResOut)); |
| 35102 | 35326 | |
| 35103 | | - zConverted = convertUtf8Filename(zFilename); |
| 35327 | + zConverted = winConvertFromUtf8Filename(zFilename); |
| 35104 | 35328 | if( zConverted==0 ){ |
| 35105 | 35329 | OSTRACE(("ACCESS name=%s, rc=SQLITE_IOERR_NOMEM\n", zFilename)); |
| 35106 | 35330 | return SQLITE_IOERR_NOMEM; |
| 35107 | 35331 | } |
| 35108 | | - if( isNT() ){ |
| 35332 | + if( osIsNT() ){ |
| 35109 | 35333 | int cnt = 0; |
| 35110 | 35334 | WIN32_FILE_ATTRIBUTE_DATA sAttrData; |
| 35111 | 35335 | memset(&sAttrData, 0, sizeof(sAttrData)); |
| 35112 | 35336 | while( !(rc = osGetFileAttributesExW((LPCWSTR)zConverted, |
| 35113 | 35337 | GetFileExInfoStandard, |
| 35114 | | - &sAttrData)) && retryIoerr(&cnt, &lastErrno) ){} |
| 35338 | + &sAttrData)) && winRetryIoerr(&cnt, &lastErrno) ){} |
| 35115 | 35339 | if( rc ){ |
| 35116 | 35340 | /* For an SQLITE_ACCESS_EXISTS query, treat a zero-length file |
| 35117 | 35341 | ** as if it does not exist. |
| 35118 | 35342 | */ |
| 35119 | 35343 | if( flags==SQLITE_ACCESS_EXISTS |
| | @@ -35122,15 +35346,15 @@ |
| 35122 | 35346 | attr = INVALID_FILE_ATTRIBUTES; |
| 35123 | 35347 | }else{ |
| 35124 | 35348 | attr = sAttrData.dwFileAttributes; |
| 35125 | 35349 | } |
| 35126 | 35350 | }else{ |
| 35127 | | - logIoerr(cnt); |
| 35351 | + winLogIoerr(cnt); |
| 35128 | 35352 | if( lastErrno!=ERROR_FILE_NOT_FOUND && lastErrno!=ERROR_PATH_NOT_FOUND ){ |
| 35129 | | - winLogError(SQLITE_IOERR_ACCESS, lastErrno, "winAccess", zFilename); |
| 35130 | 35353 | sqlite3_free(zConverted); |
| 35131 | | - return SQLITE_IOERR_ACCESS; |
| 35354 | + return winLogError(SQLITE_IOERR_ACCESS, lastErrno, "winAccess", |
| 35355 | + zFilename); |
| 35132 | 35356 | }else{ |
| 35133 | 35357 | attr = INVALID_FILE_ATTRIBUTES; |
| 35134 | 35358 | } |
| 35135 | 35359 | } |
| 35136 | 35360 | } |
| | @@ -35156,10 +35380,19 @@ |
| 35156 | 35380 | OSTRACE(("ACCESS name=%s, pResOut=%p, *pResOut=%d, rc=SQLITE_OK\n", |
| 35157 | 35381 | zFilename, pResOut, *pResOut)); |
| 35158 | 35382 | return SQLITE_OK; |
| 35159 | 35383 | } |
| 35160 | 35384 | |
| 35385 | +/* |
| 35386 | +** Returns non-zero if the specified path name starts with a drive letter |
| 35387 | +** followed by a colon character. |
| 35388 | +*/ |
| 35389 | +static BOOL winIsDriveLetterAndColon( |
| 35390 | + const char *zPathname |
| 35391 | +){ |
| 35392 | + return ( sqlite3Isalpha(zPathname[0]) && zPathname[1]==':' ); |
| 35393 | +} |
| 35161 | 35394 | |
| 35162 | 35395 | /* |
| 35163 | 35396 | ** Returns non-zero if the specified path name should be used verbatim. If |
| 35164 | 35397 | ** non-zero is returned from this function, the calling function must simply |
| 35165 | 35398 | ** use the provided path name verbatim -OR- resolve it into a full path name |
| | @@ -35173,21 +35406,21 @@ |
| 35173 | 35406 | ** a legal UNC name, a volume relative path, or an absolute path name in the |
| 35174 | 35407 | ** "Unix" format on Windows. There is no easy way to differentiate between |
| 35175 | 35408 | ** the final two cases; therefore, we return the safer return value of TRUE |
| 35176 | 35409 | ** so that callers of this function will simply use it verbatim. |
| 35177 | 35410 | */ |
| 35178 | | - if ( zPathname[0]=='/' || zPathname[0]=='\\' ){ |
| 35411 | + if ( winIsDirSep(zPathname[0]) ){ |
| 35179 | 35412 | return TRUE; |
| 35180 | 35413 | } |
| 35181 | 35414 | |
| 35182 | 35415 | /* |
| 35183 | 35416 | ** If the path name starts with a letter and a colon it is either a volume |
| 35184 | 35417 | ** relative path or an absolute path. Callers of this function must not |
| 35185 | 35418 | ** attempt to treat it as a relative path name (i.e. they should simply use |
| 35186 | 35419 | ** it verbatim). |
| 35187 | 35420 | */ |
| 35188 | | - if ( sqlite3Isalpha(zPathname[0]) && zPathname[1]==':' ){ |
| 35421 | + if ( winIsDriveLetterAndColon(zPathname) ){ |
| 35189 | 35422 | return TRUE; |
| 35190 | 35423 | } |
| 35191 | 35424 | |
| 35192 | 35425 | /* |
| 35193 | 35426 | ** If we get to this point, the path name should almost certainly be a purely |
| | @@ -35209,33 +35442,35 @@ |
| 35209 | 35442 | ){ |
| 35210 | 35443 | |
| 35211 | 35444 | #if defined(__CYGWIN__) |
| 35212 | 35445 | SimulateIOError( return SQLITE_ERROR ); |
| 35213 | 35446 | UNUSED_PARAMETER(nFull); |
| 35214 | | - assert( pVfs->mxPathname>=SQLITE_WIN32_MAX_PATH ); |
| 35215 | 35447 | assert( nFull>=pVfs->mxPathname ); |
| 35216 | 35448 | if ( sqlite3_data_directory && !winIsVerbatimPathname(zRelative) ){ |
| 35217 | 35449 | /* |
| 35218 | 35450 | ** NOTE: We are dealing with a relative path name and the data |
| 35219 | 35451 | ** directory has been set. Therefore, use it as the basis |
| 35220 | 35452 | ** for converting the relative path name to an absolute |
| 35221 | 35453 | ** one by prepending the data directory and a slash. |
| 35222 | 35454 | */ |
| 35223 | | - char zOut[SQLITE_WIN32_MAX_PATH+1]; |
| 35455 | + char *zOut = sqlite3MallocZero( pVfs->mxPathname+1 ); |
| 35456 | + if( !zOut ){ |
| 35457 | + return SQLITE_IOERR_NOMEM; |
| 35458 | + } |
| 35224 | 35459 | if( cygwin_conv_path(CCP_POSIX_TO_WIN_A|CCP_RELATIVE, zRelative, zOut, |
| 35225 | | - SQLITE_WIN32_MAX_PATH+1)<0 ){ |
| 35226 | | - winLogError(SQLITE_CANTOPEN_FULLPATH, (DWORD)errno, "cygwin_conv_path", |
| 35227 | | - zRelative); |
| 35228 | | - return SQLITE_CANTOPEN_FULLPATH; |
| 35460 | + pVfs->mxPathname+1)<0 ){ |
| 35461 | + sqlite3_free(zOut); |
| 35462 | + return winLogError(SQLITE_CANTOPEN_CONVPATH, (DWORD)errno, |
| 35463 | + "winFullPathname1", zRelative); |
| 35229 | 35464 | } |
| 35230 | | - sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s\\%s", |
| 35231 | | - sqlite3_data_directory, zOut); |
| 35465 | + sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%s%s", |
| 35466 | + sqlite3_data_directory, winGetDirDep(), zOut); |
| 35467 | + sqlite3_free(zOut); |
| 35232 | 35468 | }else{ |
| 35233 | 35469 | if( cygwin_conv_path(CCP_POSIX_TO_WIN_A, zRelative, zFull, nFull)<0 ){ |
| 35234 | | - winLogError(SQLITE_CANTOPEN_FULLPATH, (DWORD)errno, "cygwin_conv_path", |
| 35235 | | - zRelative); |
| 35236 | | - return SQLITE_CANTOPEN_FULLPATH; |
| 35470 | + return winLogError(SQLITE_CANTOPEN_CONVPATH, (DWORD)errno, |
| 35471 | + "winFullPathname2", zRelative); |
| 35237 | 35472 | } |
| 35238 | 35473 | } |
| 35239 | 35474 | return SQLITE_OK; |
| 35240 | 35475 | #endif |
| 35241 | 35476 | |
| | @@ -35248,12 +35483,12 @@ |
| 35248 | 35483 | ** NOTE: We are dealing with a relative path name and the data |
| 35249 | 35484 | ** directory has been set. Therefore, use it as the basis |
| 35250 | 35485 | ** for converting the relative path name to an absolute |
| 35251 | 35486 | ** one by prepending the data directory and a backslash. |
| 35252 | 35487 | */ |
| 35253 | | - sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s\\%s", |
| 35254 | | - sqlite3_data_directory, zRelative); |
| 35488 | + sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%s%s", |
| 35489 | + sqlite3_data_directory, winGetDirDep(), zRelative); |
| 35255 | 35490 | }else{ |
| 35256 | 35491 | sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zRelative); |
| 35257 | 35492 | } |
| 35258 | 35493 | return SQLITE_OK; |
| 35259 | 35494 | #endif |
| | @@ -35264,11 +35499,11 @@ |
| 35264 | 35499 | char *zOut; |
| 35265 | 35500 | |
| 35266 | 35501 | /* If this path name begins with "/X:", where "X" is any alphabetic |
| 35267 | 35502 | ** character, discard the initial "/" from the pathname. |
| 35268 | 35503 | */ |
| 35269 | | - if( zRelative[0]=='/' && sqlite3Isalpha(zRelative[1]) && zRelative[2]==':' ){ |
| 35504 | + if( zRelative[0]=='/' && winIsDriveLetterAndColon(zRelative+1) ){ |
| 35270 | 35505 | zRelative++; |
| 35271 | 35506 | } |
| 35272 | 35507 | |
| 35273 | 35508 | /* It's odd to simulate an io-error here, but really this is just |
| 35274 | 35509 | ** using the io-error infrastructure to test that SQLite handles this |
| | @@ -35281,68 +35516,64 @@ |
| 35281 | 35516 | ** NOTE: We are dealing with a relative path name and the data |
| 35282 | 35517 | ** directory has been set. Therefore, use it as the basis |
| 35283 | 35518 | ** for converting the relative path name to an absolute |
| 35284 | 35519 | ** one by prepending the data directory and a backslash. |
| 35285 | 35520 | */ |
| 35286 | | - sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s\\%s", |
| 35287 | | - sqlite3_data_directory, zRelative); |
| 35521 | + sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%s%s", |
| 35522 | + sqlite3_data_directory, winGetDirDep(), zRelative); |
| 35288 | 35523 | return SQLITE_OK; |
| 35289 | 35524 | } |
| 35290 | | - zConverted = convertUtf8Filename(zRelative); |
| 35525 | + zConverted = winConvertFromUtf8Filename(zRelative); |
| 35291 | 35526 | if( zConverted==0 ){ |
| 35292 | 35527 | return SQLITE_IOERR_NOMEM; |
| 35293 | 35528 | } |
| 35294 | | - if( isNT() ){ |
| 35529 | + if( osIsNT() ){ |
| 35295 | 35530 | LPWSTR zTemp; |
| 35296 | 35531 | nByte = osGetFullPathNameW((LPCWSTR)zConverted, 0, 0, 0); |
| 35297 | 35532 | if( nByte==0 ){ |
| 35298 | | - winLogError(SQLITE_ERROR, osGetLastError(), |
| 35299 | | - "GetFullPathNameW1", zConverted); |
| 35300 | 35533 | sqlite3_free(zConverted); |
| 35301 | | - return SQLITE_CANTOPEN_FULLPATH; |
| 35534 | + return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(), |
| 35535 | + "winFullPathname1", zRelative); |
| 35302 | 35536 | } |
| 35303 | 35537 | nByte += 3; |
| 35304 | 35538 | zTemp = sqlite3MallocZero( nByte*sizeof(zTemp[0]) ); |
| 35305 | 35539 | if( zTemp==0 ){ |
| 35306 | 35540 | sqlite3_free(zConverted); |
| 35307 | 35541 | return SQLITE_IOERR_NOMEM; |
| 35308 | 35542 | } |
| 35309 | 35543 | nByte = osGetFullPathNameW((LPCWSTR)zConverted, nByte, zTemp, 0); |
| 35310 | 35544 | if( nByte==0 ){ |
| 35311 | | - winLogError(SQLITE_ERROR, osGetLastError(), |
| 35312 | | - "GetFullPathNameW2", zConverted); |
| 35313 | 35545 | sqlite3_free(zConverted); |
| 35314 | 35546 | sqlite3_free(zTemp); |
| 35315 | | - return SQLITE_CANTOPEN_FULLPATH; |
| 35547 | + return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(), |
| 35548 | + "winFullPathname2", zRelative); |
| 35316 | 35549 | } |
| 35317 | 35550 | sqlite3_free(zConverted); |
| 35318 | | - zOut = unicodeToUtf8(zTemp); |
| 35551 | + zOut = winUnicodeToUtf8(zTemp); |
| 35319 | 35552 | sqlite3_free(zTemp); |
| 35320 | 35553 | } |
| 35321 | 35554 | #ifdef SQLITE_WIN32_HAS_ANSI |
| 35322 | 35555 | else{ |
| 35323 | 35556 | char *zTemp; |
| 35324 | 35557 | nByte = osGetFullPathNameA((char*)zConverted, 0, 0, 0); |
| 35325 | 35558 | if( nByte==0 ){ |
| 35326 | | - winLogError(SQLITE_ERROR, osGetLastError(), |
| 35327 | | - "GetFullPathNameA1", zConverted); |
| 35328 | 35559 | sqlite3_free(zConverted); |
| 35329 | | - return SQLITE_CANTOPEN_FULLPATH; |
| 35560 | + return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(), |
| 35561 | + "winFullPathname3", zRelative); |
| 35330 | 35562 | } |
| 35331 | 35563 | nByte += 3; |
| 35332 | 35564 | zTemp = sqlite3MallocZero( nByte*sizeof(zTemp[0]) ); |
| 35333 | 35565 | if( zTemp==0 ){ |
| 35334 | 35566 | sqlite3_free(zConverted); |
| 35335 | 35567 | return SQLITE_IOERR_NOMEM; |
| 35336 | 35568 | } |
| 35337 | 35569 | nByte = osGetFullPathNameA((char*)zConverted, nByte, zTemp, 0); |
| 35338 | 35570 | if( nByte==0 ){ |
| 35339 | | - winLogError(SQLITE_ERROR, osGetLastError(), |
| 35340 | | - "GetFullPathNameA2", zConverted); |
| 35341 | 35571 | sqlite3_free(zConverted); |
| 35342 | 35572 | sqlite3_free(zTemp); |
| 35343 | | - return SQLITE_CANTOPEN_FULLPATH; |
| 35573 | + return winLogError(SQLITE_CANTOPEN_FULLPATH, osGetLastError(), |
| 35574 | + "winFullPathname4", zRelative); |
| 35344 | 35575 | } |
| 35345 | 35576 | sqlite3_free(zConverted); |
| 35346 | 35577 | zOut = sqlite3_win32_mbcs_to_utf8(zTemp); |
| 35347 | 35578 | sqlite3_free(zTemp); |
| 35348 | 35579 | } |
| | @@ -35366,16 +35597,16 @@ |
| 35366 | 35597 | ** Interfaces for opening a shared library, finding entry points |
| 35367 | 35598 | ** within the shared library, and closing the shared library. |
| 35368 | 35599 | */ |
| 35369 | 35600 | static void *winDlOpen(sqlite3_vfs *pVfs, const char *zFilename){ |
| 35370 | 35601 | HANDLE h; |
| 35371 | | - void *zConverted = convertUtf8Filename(zFilename); |
| 35602 | + void *zConverted = winConvertFromUtf8Filename(zFilename); |
| 35372 | 35603 | UNUSED_PARAMETER(pVfs); |
| 35373 | 35604 | if( zConverted==0 ){ |
| 35374 | 35605 | return 0; |
| 35375 | 35606 | } |
| 35376 | | - if( isNT() ){ |
| 35607 | + if( osIsNT() ){ |
| 35377 | 35608 | #if SQLITE_OS_WINRT |
| 35378 | 35609 | h = osLoadPackagedLibrary((LPCWSTR)zConverted, 0); |
| 35379 | 35610 | #else |
| 35380 | 35611 | h = osLoadLibraryW((LPCWSTR)zConverted); |
| 35381 | 35612 | #endif |
| | @@ -35388,11 +35619,11 @@ |
| 35388 | 35619 | sqlite3_free(zConverted); |
| 35389 | 35620 | return (void*)h; |
| 35390 | 35621 | } |
| 35391 | 35622 | static void winDlError(sqlite3_vfs *pVfs, int nBuf, char *zBufOut){ |
| 35392 | 35623 | UNUSED_PARAMETER(pVfs); |
| 35393 | | - getLastErrorMsg(osGetLastError(), nBuf, zBufOut); |
| 35624 | + winGetLastErrorMsg(osGetLastError(), nBuf, zBufOut); |
| 35394 | 35625 | } |
| 35395 | 35626 | static void (*winDlSym(sqlite3_vfs *pVfs,void *pH,const char *zSym))(void){ |
| 35396 | 35627 | UNUSED_PARAMETER(pVfs); |
| 35397 | 35628 | return (void(*)(void))osGetProcAddressA((HANDLE)pH, zSym); |
| 35398 | 35629 | } |
| | @@ -35564,21 +35795,21 @@ |
| 35564 | 35795 | ** by sqlite into the error message available to the user using |
| 35565 | 35796 | ** sqlite3_errmsg(), possibly making IO errors easier to debug. |
| 35566 | 35797 | */ |
| 35567 | 35798 | static int winGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){ |
| 35568 | 35799 | UNUSED_PARAMETER(pVfs); |
| 35569 | | - return getLastErrorMsg(osGetLastError(), nBuf, zBuf); |
| 35800 | + return winGetLastErrorMsg(osGetLastError(), nBuf, zBuf); |
| 35570 | 35801 | } |
| 35571 | 35802 | |
| 35572 | 35803 | /* |
| 35573 | 35804 | ** Initialize and deinitialize the operating system interface. |
| 35574 | 35805 | */ |
| 35575 | 35806 | SQLITE_API int sqlite3_os_init(void){ |
| 35576 | 35807 | static sqlite3_vfs winVfs = { |
| 35577 | 35808 | 3, /* iVersion */ |
| 35578 | 35809 | sizeof(winFile), /* szOsFile */ |
| 35579 | | - SQLITE_WIN32_MAX_PATH, /* mxPathname */ |
| 35810 | + SQLITE_WIN32_MAX_PATH_BYTES, /* mxPathname */ |
| 35580 | 35811 | 0, /* pNext */ |
| 35581 | 35812 | "win32", /* zName */ |
| 35582 | 35813 | 0, /* pAppData */ |
| 35583 | 35814 | winOpen, /* xOpen */ |
| 35584 | 35815 | winDelete, /* xDelete */ |
| | @@ -35595,10 +35826,36 @@ |
| 35595 | 35826 | winCurrentTimeInt64, /* xCurrentTimeInt64 */ |
| 35596 | 35827 | winSetSystemCall, /* xSetSystemCall */ |
| 35597 | 35828 | winGetSystemCall, /* xGetSystemCall */ |
| 35598 | 35829 | winNextSystemCall, /* xNextSystemCall */ |
| 35599 | 35830 | }; |
| 35831 | +#if defined(SQLITE_WIN32_HAS_WIDE) |
| 35832 | + static sqlite3_vfs winLongPathVfs = { |
| 35833 | + 3, /* iVersion */ |
| 35834 | + sizeof(winFile), /* szOsFile */ |
| 35835 | + SQLITE_WINNT_MAX_PATH_BYTES, /* mxPathname */ |
| 35836 | + 0, /* pNext */ |
| 35837 | + "win32-longpath", /* zName */ |
| 35838 | + 0, /* pAppData */ |
| 35839 | + winOpen, /* xOpen */ |
| 35840 | + winDelete, /* xDelete */ |
| 35841 | + winAccess, /* xAccess */ |
| 35842 | + winFullPathname, /* xFullPathname */ |
| 35843 | + winDlOpen, /* xDlOpen */ |
| 35844 | + winDlError, /* xDlError */ |
| 35845 | + winDlSym, /* xDlSym */ |
| 35846 | + winDlClose, /* xDlClose */ |
| 35847 | + winRandomness, /* xRandomness */ |
| 35848 | + winSleep, /* xSleep */ |
| 35849 | + winCurrentTime, /* xCurrentTime */ |
| 35850 | + winGetLastError, /* xGetLastError */ |
| 35851 | + winCurrentTimeInt64, /* xCurrentTimeInt64 */ |
| 35852 | + winSetSystemCall, /* xSetSystemCall */ |
| 35853 | + winGetSystemCall, /* xGetSystemCall */ |
| 35854 | + winNextSystemCall, /* xNextSystemCall */ |
| 35855 | + }; |
| 35856 | +#endif |
| 35600 | 35857 | |
| 35601 | 35858 | /* Double-check that the aSyscall[] array has been constructed |
| 35602 | 35859 | ** correctly. See ticket [bb3a86e890c8e96ab] */ |
| 35603 | 35860 | assert( ArraySize(aSyscall)==74 ); |
| 35604 | 35861 | |
| | @@ -35611,10 +35868,15 @@ |
| 35611 | 35868 | #endif |
| 35612 | 35869 | assert( winSysInfo.dwAllocationGranularity>0 ); |
| 35613 | 35870 | assert( winSysInfo.dwPageSize>0 ); |
| 35614 | 35871 | |
| 35615 | 35872 | sqlite3_vfs_register(&winVfs, 1); |
| 35873 | + |
| 35874 | +#if defined(SQLITE_WIN32_HAS_WIDE) |
| 35875 | + sqlite3_vfs_register(&winLongPathVfs, 0); |
| 35876 | +#endif |
| 35877 | + |
| 35616 | 35878 | return SQLITE_OK; |
| 35617 | 35879 | } |
| 35618 | 35880 | |
| 35619 | 35881 | SQLITE_API int sqlite3_os_end(void){ |
| 35620 | 35882 | #if SQLITE_OS_WINRT |
| | @@ -52086,10 +52348,11 @@ |
| 52086 | 52348 | pBt->max1bytePayload = (u8)pBt->maxLocal; |
| 52087 | 52349 | } |
| 52088 | 52350 | assert( pBt->maxLeaf + 23 <= MX_CELL_SIZE(pBt) ); |
| 52089 | 52351 | pBt->pPage1 = pPage1; |
| 52090 | 52352 | pBt->nPage = nPage; |
| 52353 | +assert( pPage1->leaf==0 || pPage1->leaf==1 ); |
| 52091 | 52354 | return SQLITE_OK; |
| 52092 | 52355 | |
| 52093 | 52356 | page1_init_failed: |
| 52094 | 52357 | releasePage(pPage1); |
| 52095 | 52358 | pBt->pPage1 = 0; |
| | @@ -59838,43 +60101,108 @@ |
| 59838 | 60101 | } |
| 59839 | 60102 | return p; |
| 59840 | 60103 | } |
| 59841 | 60104 | |
| 59842 | 60105 | /* |
| 59843 | | -** Create a new sqlite3_value object, containing the value of pExpr. |
| 60106 | +** Context object passed by sqlite3Stat4ProbeSetValue() through to |
| 60107 | +** valueNew(). See comments above valueNew() for details. |
| 60108 | +*/ |
| 60109 | +struct ValueNewStat4Ctx { |
| 60110 | + Parse *pParse; |
| 60111 | + Index *pIdx; |
| 60112 | + UnpackedRecord **ppRec; |
| 60113 | + int iVal; |
| 60114 | +}; |
| 60115 | + |
| 60116 | +/* |
| 60117 | +** Allocate and return a pointer to a new sqlite3_value object. If |
| 60118 | +** the second argument to this function is NULL, the object is allocated |
| 60119 | +** by calling sqlite3ValueNew(). |
| 59844 | 60120 | ** |
| 59845 | | -** This only works for very simple expressions that consist of one constant |
| 59846 | | -** token (i.e. "5", "5.1", "'a string'"). If the expression can |
| 59847 | | -** be converted directly into a value, then the value is allocated and |
| 59848 | | -** a pointer written to *ppVal. The caller is responsible for deallocating |
| 59849 | | -** the value by passing it to sqlite3ValueFree() later on. If the expression |
| 59850 | | -** cannot be converted to a value, then *ppVal is set to NULL. |
| 60121 | +** Otherwise, if the second argument is non-zero, then this function is |
| 60122 | +** being called indirectly by sqlite3Stat4ProbeSetValue(). If it has not |
| 60123 | +** already been allocated, allocate the UnpackedRecord structure that |
| 60124 | +** that function will return to its caller here. Then return a pointer |
| 60125 | +** an sqlite3_value within the UnpackedRecord.a[] array. |
| 59851 | 60126 | */ |
| 59852 | | -SQLITE_PRIVATE int sqlite3ValueFromExpr( |
| 59853 | | - sqlite3 *db, /* The database connection */ |
| 59854 | | - Expr *pExpr, /* The expression to evaluate */ |
| 59855 | | - u8 enc, /* Encoding to use */ |
| 59856 | | - u8 affinity, /* Affinity to use */ |
| 59857 | | - sqlite3_value **ppVal /* Write the new value here */ |
| 60127 | +static sqlite3_value *valueNew(sqlite3 *db, struct ValueNewStat4Ctx *p){ |
| 60128 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 60129 | + if( p ){ |
| 60130 | + UnpackedRecord *pRec = p->ppRec[0]; |
| 60131 | + |
| 60132 | + if( pRec==0 ){ |
| 60133 | + Index *pIdx = p->pIdx; /* Index being probed */ |
| 60134 | + int nByte; /* Bytes of space to allocate */ |
| 60135 | + int i; /* Counter variable */ |
| 60136 | + int nCol = pIdx->nColumn+1; /* Number of index columns including rowid */ |
| 60137 | + |
| 60138 | + nByte = sizeof(Mem) * nCol + sizeof(UnpackedRecord); |
| 60139 | + pRec = (UnpackedRecord*)sqlite3DbMallocZero(db, nByte); |
| 60140 | + if( pRec ){ |
| 60141 | + pRec->pKeyInfo = sqlite3IndexKeyinfo(p->pParse, pIdx); |
| 60142 | + if( pRec->pKeyInfo ){ |
| 60143 | + assert( pRec->pKeyInfo->nField+1==nCol ); |
| 60144 | + pRec->pKeyInfo->enc = ENC(db); |
| 60145 | + pRec->flags = UNPACKED_PREFIX_MATCH; |
| 60146 | + pRec->aMem = (Mem *)&pRec[1]; |
| 60147 | + for(i=0; i<nCol; i++){ |
| 60148 | + pRec->aMem[i].flags = MEM_Null; |
| 60149 | + pRec->aMem[i].type = SQLITE_NULL; |
| 60150 | + pRec->aMem[i].db = db; |
| 60151 | + } |
| 60152 | + }else{ |
| 60153 | + sqlite3DbFree(db, pRec); |
| 60154 | + pRec = 0; |
| 60155 | + } |
| 60156 | + } |
| 60157 | + if( pRec==0 ) return 0; |
| 60158 | + p->ppRec[0] = pRec; |
| 60159 | + } |
| 60160 | + |
| 60161 | + pRec->nField = p->iVal+1; |
| 60162 | + return &pRec->aMem[p->iVal]; |
| 60163 | + } |
| 60164 | +#endif |
| 60165 | + return sqlite3ValueNew(db); |
| 60166 | +} |
| 60167 | + |
| 60168 | +/* |
| 60169 | +** Extract a value from the supplied expression in the manner described |
| 60170 | +** above sqlite3ValueFromExpr(). Allocate the sqlite3_value object |
| 60171 | +** using valueNew(). |
| 60172 | +** |
| 60173 | +** If pCtx is NULL and an error occurs after the sqlite3_value object |
| 60174 | +** has been allocated, it is freed before returning. Or, if pCtx is not |
| 60175 | +** NULL, it is assumed that the caller will free any allocated object |
| 60176 | +** in all cases. |
| 60177 | +*/ |
| 60178 | +int valueFromExpr( |
| 60179 | + sqlite3 *db, /* The database connection */ |
| 60180 | + Expr *pExpr, /* The expression to evaluate */ |
| 60181 | + u8 enc, /* Encoding to use */ |
| 60182 | + u8 affinity, /* Affinity to use */ |
| 60183 | + sqlite3_value **ppVal, /* Write the new value here */ |
| 60184 | + struct ValueNewStat4Ctx *pCtx /* Second argument for valueNew() */ |
| 59858 | 60185 | ){ |
| 59859 | 60186 | int op; |
| 59860 | 60187 | char *zVal = 0; |
| 59861 | 60188 | sqlite3_value *pVal = 0; |
| 59862 | 60189 | int negInt = 1; |
| 59863 | 60190 | const char *zNeg = ""; |
| 60191 | + int rc = SQLITE_OK; |
| 59864 | 60192 | |
| 59865 | 60193 | if( !pExpr ){ |
| 59866 | 60194 | *ppVal = 0; |
| 59867 | 60195 | return SQLITE_OK; |
| 59868 | 60196 | } |
| 59869 | 60197 | op = pExpr->op; |
| 59870 | 60198 | |
| 59871 | | - /* op can only be TK_REGISTER if we have compiled with SQLITE_ENABLE_STAT3. |
| 60199 | + /* op can only be TK_REGISTER if we have compiled with SQLITE_ENABLE_STAT4. |
| 59872 | 60200 | ** The ifdef here is to enable us to achieve 100% branch test coverage even |
| 59873 | | - ** when SQLITE_ENABLE_STAT3 is omitted. |
| 60201 | + ** when SQLITE_ENABLE_STAT4 is omitted. |
| 59874 | 60202 | */ |
| 59875 | | -#ifdef SQLITE_ENABLE_STAT3 |
| 60203 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 59876 | 60204 | if( op==TK_REGISTER ) op = pExpr->op2; |
| 59877 | 60205 | #else |
| 59878 | 60206 | if( NEVER(op==TK_REGISTER) ) op = pExpr->op2; |
| 59879 | 60207 | #endif |
| 59880 | 60208 | |
| | @@ -59888,11 +60216,11 @@ |
| 59888 | 60216 | negInt = -1; |
| 59889 | 60217 | zNeg = "-"; |
| 59890 | 60218 | } |
| 59891 | 60219 | |
| 59892 | 60220 | if( op==TK_STRING || op==TK_FLOAT || op==TK_INTEGER ){ |
| 59893 | | - pVal = sqlite3ValueNew(db); |
| 60221 | + pVal = valueNew(db, pCtx); |
| 59894 | 60222 | if( pVal==0 ) goto no_mem; |
| 59895 | 60223 | if( ExprHasProperty(pExpr, EP_IntValue) ){ |
| 59896 | 60224 | sqlite3VdbeMemSetInt64(pVal, (i64)pExpr->u.iValue*negInt); |
| 59897 | 60225 | }else{ |
| 59898 | 60226 | zVal = sqlite3MPrintf(db, "%s%s", zNeg, pExpr->u.zToken); |
| | @@ -59905,15 +60233,17 @@ |
| 59905 | 60233 | }else{ |
| 59906 | 60234 | sqlite3ValueApplyAffinity(pVal, affinity, SQLITE_UTF8); |
| 59907 | 60235 | } |
| 59908 | 60236 | if( pVal->flags & (MEM_Int|MEM_Real) ) pVal->flags &= ~MEM_Str; |
| 59909 | 60237 | if( enc!=SQLITE_UTF8 ){ |
| 59910 | | - sqlite3VdbeChangeEncoding(pVal, enc); |
| 60238 | + rc = sqlite3VdbeChangeEncoding(pVal, enc); |
| 59911 | 60239 | } |
| 59912 | 60240 | }else if( op==TK_UMINUS ) { |
| 59913 | 60241 | /* This branch happens for multiple negative signs. Ex: -(-5) */ |
| 59914 | | - if( SQLITE_OK==sqlite3ValueFromExpr(db,pExpr->pLeft,enc,affinity,&pVal) ){ |
| 60242 | + if( SQLITE_OK==sqlite3ValueFromExpr(db,pExpr->pLeft,enc,affinity,&pVal) |
| 60243 | + && pVal!=0 |
| 60244 | + ){ |
| 59915 | 60245 | sqlite3VdbeMemNumerify(pVal); |
| 59916 | 60246 | if( pVal->u.i==SMALLEST_INT64 ){ |
| 59917 | 60247 | pVal->flags &= MEM_Int; |
| 59918 | 60248 | pVal->flags |= MEM_Real; |
| 59919 | 60249 | pVal->r = (double)LARGEST_INT64; |
| | @@ -59922,19 +60252,19 @@ |
| 59922 | 60252 | } |
| 59923 | 60253 | pVal->r = -pVal->r; |
| 59924 | 60254 | sqlite3ValueApplyAffinity(pVal, affinity, enc); |
| 59925 | 60255 | } |
| 59926 | 60256 | }else if( op==TK_NULL ){ |
| 59927 | | - pVal = sqlite3ValueNew(db); |
| 60257 | + pVal = valueNew(db, pCtx); |
| 59928 | 60258 | if( pVal==0 ) goto no_mem; |
| 59929 | 60259 | } |
| 59930 | 60260 | #ifndef SQLITE_OMIT_BLOB_LITERAL |
| 59931 | 60261 | else if( op==TK_BLOB ){ |
| 59932 | 60262 | int nVal; |
| 59933 | 60263 | assert( pExpr->u.zToken[0]=='x' || pExpr->u.zToken[0]=='X' ); |
| 59934 | 60264 | assert( pExpr->u.zToken[1]=='\'' ); |
| 59935 | | - pVal = sqlite3ValueNew(db); |
| 60265 | + pVal = valueNew(db, pCtx); |
| 59936 | 60266 | if( !pVal ) goto no_mem; |
| 59937 | 60267 | zVal = &pExpr->u.zToken[2]; |
| 59938 | 60268 | nVal = sqlite3Strlen30(zVal)-1; |
| 59939 | 60269 | assert( zVal[nVal]=='\'' ); |
| 59940 | 60270 | sqlite3VdbeMemSetStr(pVal, sqlite3HexToBlob(db, zVal, nVal), nVal/2, |
| | @@ -59944,20 +60274,206 @@ |
| 59944 | 60274 | |
| 59945 | 60275 | if( pVal ){ |
| 59946 | 60276 | sqlite3VdbeMemStoreType(pVal); |
| 59947 | 60277 | } |
| 59948 | 60278 | *ppVal = pVal; |
| 59949 | | - return SQLITE_OK; |
| 60279 | + return rc; |
| 59950 | 60280 | |
| 59951 | 60281 | no_mem: |
| 59952 | 60282 | db->mallocFailed = 1; |
| 59953 | 60283 | sqlite3DbFree(db, zVal); |
| 59954 | | - sqlite3ValueFree(pVal); |
| 59955 | | - *ppVal = 0; |
| 60284 | + assert( *ppVal==0 ); |
| 60285 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 60286 | + if( pCtx==0 ) sqlite3ValueFree(pVal); |
| 60287 | +#else |
| 60288 | + assert( pCtx==0 ); sqlite3ValueFree(pVal); |
| 60289 | +#endif |
| 59956 | 60290 | return SQLITE_NOMEM; |
| 59957 | 60291 | } |
| 59958 | 60292 | |
| 60293 | +/* |
| 60294 | +** Create a new sqlite3_value object, containing the value of pExpr. |
| 60295 | +** |
| 60296 | +** This only works for very simple expressions that consist of one constant |
| 60297 | +** token (i.e. "5", "5.1", "'a string'"). If the expression can |
| 60298 | +** be converted directly into a value, then the value is allocated and |
| 60299 | +** a pointer written to *ppVal. The caller is responsible for deallocating |
| 60300 | +** the value by passing it to sqlite3ValueFree() later on. If the expression |
| 60301 | +** cannot be converted to a value, then *ppVal is set to NULL. |
| 60302 | +*/ |
| 60303 | +SQLITE_PRIVATE int sqlite3ValueFromExpr( |
| 60304 | + sqlite3 *db, /* The database connection */ |
| 60305 | + Expr *pExpr, /* The expression to evaluate */ |
| 60306 | + u8 enc, /* Encoding to use */ |
| 60307 | + u8 affinity, /* Affinity to use */ |
| 60308 | + sqlite3_value **ppVal /* Write the new value here */ |
| 60309 | +){ |
| 60310 | + return valueFromExpr(db, pExpr, enc, affinity, ppVal, 0); |
| 60311 | +} |
| 60312 | + |
| 60313 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 60314 | +/* |
| 60315 | +** The implementation of the sqlite_record() function. This function accepts |
| 60316 | +** a single argument of any type. The return value is a formatted database |
| 60317 | +** record (a blob) containing the argument value. |
| 60318 | +** |
| 60319 | +** This is used to convert the value stored in the 'sample' column of the |
| 60320 | +** sqlite_stat3 table to the record format SQLite uses internally. |
| 60321 | +*/ |
| 60322 | +static void recordFunc( |
| 60323 | + sqlite3_context *context, |
| 60324 | + int argc, |
| 60325 | + sqlite3_value **argv |
| 60326 | +){ |
| 60327 | + const int file_format = 1; |
| 60328 | + int iSerial; /* Serial type */ |
| 60329 | + int nSerial; /* Bytes of space for iSerial as varint */ |
| 60330 | + int nVal; /* Bytes of space required for argv[0] */ |
| 60331 | + int nRet; |
| 60332 | + sqlite3 *db; |
| 60333 | + u8 *aRet; |
| 60334 | + |
| 60335 | + iSerial = sqlite3VdbeSerialType(argv[0], file_format); |
| 60336 | + nSerial = sqlite3VarintLen(iSerial); |
| 60337 | + nVal = sqlite3VdbeSerialTypeLen(iSerial); |
| 60338 | + db = sqlite3_context_db_handle(context); |
| 60339 | + |
| 60340 | + nRet = 1 + nSerial + nVal; |
| 60341 | + aRet = sqlite3DbMallocRaw(db, nRet); |
| 60342 | + if( aRet==0 ){ |
| 60343 | + sqlite3_result_error_nomem(context); |
| 60344 | + }else{ |
| 60345 | + aRet[0] = nSerial+1; |
| 60346 | + sqlite3PutVarint(&aRet[1], iSerial); |
| 60347 | + sqlite3VdbeSerialPut(&aRet[1+nSerial], nVal, argv[0], file_format); |
| 60348 | + sqlite3_result_blob(context, aRet, nRet, SQLITE_TRANSIENT); |
| 60349 | + sqlite3DbFree(db, aRet); |
| 60350 | + } |
| 60351 | +} |
| 60352 | + |
| 60353 | +/* |
| 60354 | +** Register built-in functions used to help read ANALYZE data. |
| 60355 | +*/ |
| 60356 | +SQLITE_PRIVATE void sqlite3AnalyzeFunctions(void){ |
| 60357 | + static SQLITE_WSD FuncDef aAnalyzeTableFuncs[] = { |
| 60358 | + FUNCTION(sqlite_record, 1, 0, 0, recordFunc), |
| 60359 | + }; |
| 60360 | + int i; |
| 60361 | + FuncDefHash *pHash = &GLOBAL(FuncDefHash, sqlite3GlobalFunctions); |
| 60362 | + FuncDef *aFunc = (FuncDef*)&GLOBAL(FuncDef, aAnalyzeTableFuncs); |
| 60363 | + for(i=0; i<ArraySize(aAnalyzeTableFuncs); i++){ |
| 60364 | + sqlite3FuncDefInsert(pHash, &aFunc[i]); |
| 60365 | + } |
| 60366 | +} |
| 60367 | + |
| 60368 | +/* |
| 60369 | +** This function is used to allocate and populate UnpackedRecord |
| 60370 | +** structures intended to be compared against sample index keys stored |
| 60371 | +** in the sqlite_stat4 table. |
| 60372 | +** |
| 60373 | +** A single call to this function attempts to populates field iVal (leftmost |
| 60374 | +** is 0 etc.) of the unpacked record with a value extracted from expression |
| 60375 | +** pExpr. Extraction of values is possible if: |
| 60376 | +** |
| 60377 | +** * (pExpr==0). In this case the value is assumed to be an SQL NULL, |
| 60378 | +** |
| 60379 | +** * The expression is a bound variable, and this is a reprepare, or |
| 60380 | +** |
| 60381 | +** * The sqlite3ValueFromExpr() function is able to extract a value |
| 60382 | +** from the expression (i.e. the expression is a literal value). |
| 60383 | +** |
| 60384 | +** If a value can be extracted, the affinity passed as the 5th argument |
| 60385 | +** is applied to it before it is copied into the UnpackedRecord. Output |
| 60386 | +** parameter *pbOk is set to true if a value is extracted, or false |
| 60387 | +** otherwise. |
| 60388 | +** |
| 60389 | +** When this function is called, *ppRec must either point to an object |
| 60390 | +** allocated by an earlier call to this function, or must be NULL. If it |
| 60391 | +** is NULL and a value can be successfully extracted, a new UnpackedRecord |
| 60392 | +** is allocated (and *ppRec set to point to it) before returning. |
| 60393 | +** |
| 60394 | +** Unless an error is encountered, SQLITE_OK is returned. It is not an |
| 60395 | +** error if a value cannot be extracted from pExpr. If an error does |
| 60396 | +** occur, an SQLite error code is returned. |
| 60397 | +*/ |
| 60398 | +SQLITE_PRIVATE int sqlite3Stat4ProbeSetValue( |
| 60399 | + Parse *pParse, /* Parse context */ |
| 60400 | + Index *pIdx, /* Index being probed */ |
| 60401 | + UnpackedRecord **ppRec, /* IN/OUT: Probe record */ |
| 60402 | + Expr *pExpr, /* The expression to extract a value from */ |
| 60403 | + u8 affinity, /* Affinity to use */ |
| 60404 | + int iVal, /* Array element to populate */ |
| 60405 | + int *pbOk /* OUT: True if value was extracted */ |
| 60406 | +){ |
| 60407 | + int rc = SQLITE_OK; |
| 60408 | + sqlite3_value *pVal = 0; |
| 60409 | + |
| 60410 | + struct ValueNewStat4Ctx alloc; |
| 60411 | + alloc.pParse = pParse; |
| 60412 | + alloc.pIdx = pIdx; |
| 60413 | + alloc.ppRec = ppRec; |
| 60414 | + alloc.iVal = iVal; |
| 60415 | + |
| 60416 | + /* Skip over any TK_COLLATE nodes */ |
| 60417 | + pExpr = sqlite3ExprSkipCollate(pExpr); |
| 60418 | + |
| 60419 | + if( !pExpr ){ |
| 60420 | + pVal = valueNew(pParse->db, &alloc); |
| 60421 | + if( pVal ){ |
| 60422 | + sqlite3VdbeMemSetNull((Mem*)pVal); |
| 60423 | + *pbOk = 1; |
| 60424 | + } |
| 60425 | + }else if( pExpr->op==TK_VARIABLE |
| 60426 | + || (pExpr->op==TK_REGISTER && pExpr->op2==TK_VARIABLE) |
| 60427 | + ){ |
| 60428 | + Vdbe *v; |
| 60429 | + int iBindVar = pExpr->iColumn; |
| 60430 | + sqlite3VdbeSetVarmask(pParse->pVdbe, iBindVar); |
| 60431 | + if( (v = pParse->pReprepare)!=0 ){ |
| 60432 | + pVal = valueNew(pParse->db, &alloc); |
| 60433 | + if( pVal ){ |
| 60434 | + rc = sqlite3VdbeMemCopy((Mem*)pVal, &v->aVar[iBindVar-1]); |
| 60435 | + if( rc==SQLITE_OK ){ |
| 60436 | + sqlite3ValueApplyAffinity(pVal, affinity, SQLITE_UTF8); |
| 60437 | + } |
| 60438 | + pVal->db = pParse->db; |
| 60439 | + *pbOk = 1; |
| 60440 | + sqlite3VdbeMemStoreType((Mem*)pVal); |
| 60441 | + } |
| 60442 | + }else{ |
| 60443 | + *pbOk = 0; |
| 60444 | + } |
| 60445 | + }else{ |
| 60446 | + sqlite3 *db = pParse->db; |
| 60447 | + rc = valueFromExpr(db, pExpr, ENC(db), affinity, &pVal, &alloc); |
| 60448 | + *pbOk = (pVal!=0); |
| 60449 | + } |
| 60450 | + |
| 60451 | + assert( pVal==0 || pVal->db==pParse->db ); |
| 60452 | + return rc; |
| 60453 | +} |
| 60454 | + |
| 60455 | +/* |
| 60456 | +** Unless it is NULL, the argument must be an UnpackedRecord object returned |
| 60457 | +** by an earlier call to sqlite3Stat4ProbeSetValue(). This call deletes |
| 60458 | +** the object. |
| 60459 | +*/ |
| 60460 | +SQLITE_PRIVATE void sqlite3Stat4ProbeFree(UnpackedRecord *pRec){ |
| 60461 | + if( pRec ){ |
| 60462 | + int i; |
| 60463 | + int nCol = pRec->pKeyInfo->nField+1; |
| 60464 | + Mem *aMem = pRec->aMem; |
| 60465 | + sqlite3 *db = aMem[0].db; |
| 60466 | + for(i=0; i<nCol; i++){ |
| 60467 | + sqlite3DbFree(db, aMem[i].zMalloc); |
| 60468 | + } |
| 60469 | + sqlite3DbFree(db, pRec->pKeyInfo); |
| 60470 | + sqlite3DbFree(db, pRec); |
| 60471 | + } |
| 60472 | +} |
| 60473 | +#endif /* ifdef SQLITE_ENABLE_STAT4 */ |
| 60474 | + |
| 59959 | 60475 | /* |
| 59960 | 60476 | ** Change the string value of an sqlite3_value object |
| 59961 | 60477 | */ |
| 59962 | 60478 | SQLITE_PRIVATE void sqlite3ValueSetStr( |
| 59963 | 60479 | sqlite3_value *v, /* Value to be set */ |
| | @@ -66073,11 +66589,11 @@ |
| 66073 | 66589 | ** value or convert mem[p2] to a different type. |
| 66074 | 66590 | */ |
| 66075 | 66591 | assert( pOp->opflags==sqlite3OpcodeProperty[pOp->opcode] ); |
| 66076 | 66592 | if( pOp->opflags & OPFLG_OUT2_PRERELEASE ){ |
| 66077 | 66593 | assert( pOp->p2>0 ); |
| 66078 | | - assert( pOp->p2<=p->nMem ); |
| 66594 | + assert( pOp->p2<=(p->nMem-p->nCursor) ); |
| 66079 | 66595 | pOut = &aMem[pOp->p2]; |
| 66080 | 66596 | memAboutToChange(p, pOut); |
| 66081 | 66597 | VdbeMemRelease(pOut); |
| 66082 | 66598 | pOut->flags = MEM_Int; |
| 66083 | 66599 | } |
| | @@ -66084,34 +66600,34 @@ |
| 66084 | 66600 | |
| 66085 | 66601 | /* Sanity checking on other operands */ |
| 66086 | 66602 | #ifdef SQLITE_DEBUG |
| 66087 | 66603 | if( (pOp->opflags & OPFLG_IN1)!=0 ){ |
| 66088 | 66604 | assert( pOp->p1>0 ); |
| 66089 | | - assert( pOp->p1<=p->nMem ); |
| 66605 | + assert( pOp->p1<=(p->nMem-p->nCursor) ); |
| 66090 | 66606 | assert( memIsValid(&aMem[pOp->p1]) ); |
| 66091 | 66607 | REGISTER_TRACE(pOp->p1, &aMem[pOp->p1]); |
| 66092 | 66608 | } |
| 66093 | 66609 | if( (pOp->opflags & OPFLG_IN2)!=0 ){ |
| 66094 | 66610 | assert( pOp->p2>0 ); |
| 66095 | | - assert( pOp->p2<=p->nMem ); |
| 66611 | + assert( pOp->p2<=(p->nMem-p->nCursor) ); |
| 66096 | 66612 | assert( memIsValid(&aMem[pOp->p2]) ); |
| 66097 | 66613 | REGISTER_TRACE(pOp->p2, &aMem[pOp->p2]); |
| 66098 | 66614 | } |
| 66099 | 66615 | if( (pOp->opflags & OPFLG_IN3)!=0 ){ |
| 66100 | 66616 | assert( pOp->p3>0 ); |
| 66101 | | - assert( pOp->p3<=p->nMem ); |
| 66617 | + assert( pOp->p3<=(p->nMem-p->nCursor) ); |
| 66102 | 66618 | assert( memIsValid(&aMem[pOp->p3]) ); |
| 66103 | 66619 | REGISTER_TRACE(pOp->p3, &aMem[pOp->p3]); |
| 66104 | 66620 | } |
| 66105 | 66621 | if( (pOp->opflags & OPFLG_OUT2)!=0 ){ |
| 66106 | 66622 | assert( pOp->p2>0 ); |
| 66107 | | - assert( pOp->p2<=p->nMem ); |
| 66623 | + assert( pOp->p2<=(p->nMem-p->nCursor) ); |
| 66108 | 66624 | memAboutToChange(p, &aMem[pOp->p2]); |
| 66109 | 66625 | } |
| 66110 | 66626 | if( (pOp->opflags & OPFLG_OUT3)!=0 ){ |
| 66111 | 66627 | assert( pOp->p3>0 ); |
| 66112 | | - assert( pOp->p3<=p->nMem ); |
| 66628 | + assert( pOp->p3<=(p->nMem-p->nCursor) ); |
| 66113 | 66629 | memAboutToChange(p, &aMem[pOp->p3]); |
| 66114 | 66630 | } |
| 66115 | 66631 | #endif |
| 66116 | 66632 | |
| 66117 | 66633 | switch( pOp->opcode ){ |
| | @@ -66200,11 +66716,11 @@ |
| 66200 | 66716 | ** |
| 66201 | 66717 | ** Write the current address onto register P1 |
| 66202 | 66718 | ** and then jump to address P2. |
| 66203 | 66719 | */ |
| 66204 | 66720 | case OP_Gosub: { /* jump */ |
| 66205 | | - assert( pOp->p1>0 && pOp->p1<=p->nMem ); |
| 66721 | + assert( pOp->p1>0 && pOp->p1<=(p->nMem-p->nCursor) ); |
| 66206 | 66722 | pIn1 = &aMem[pOp->p1]; |
| 66207 | 66723 | assert( (pIn1->flags & MEM_Dyn)==0 ); |
| 66208 | 66724 | memAboutToChange(p, pIn1); |
| 66209 | 66725 | pIn1->flags = MEM_Int; |
| 66210 | 66726 | pIn1->u.i = pc; |
| | @@ -66416,11 +66932,11 @@ |
| 66416 | 66932 | #if 0 /* local variables moved into u.ab */ |
| 66417 | 66933 | int cnt; |
| 66418 | 66934 | u16 nullFlag; |
| 66419 | 66935 | #endif /* local variables moved into u.ab */ |
| 66420 | 66936 | u.ab.cnt = pOp->p3-pOp->p2; |
| 66421 | | - assert( pOp->p3<=p->nMem ); |
| 66937 | + assert( pOp->p3<=(p->nMem-p->nCursor) ); |
| 66422 | 66938 | pOut->flags = u.ab.nullFlag = pOp->p1 ? (MEM_Null|MEM_Cleared) : MEM_Null; |
| 66423 | 66939 | while( u.ab.cnt>0 ){ |
| 66424 | 66940 | pOut++; |
| 66425 | 66941 | memAboutToChange(p, pOut); |
| 66426 | 66942 | VdbeMemRelease(pOut); |
| | @@ -66489,12 +67005,12 @@ |
| 66489 | 67005 | assert( u.ad.p1+u.ad.n<=u.ad.p2 || u.ad.p2+u.ad.n<=u.ad.p1 ); |
| 66490 | 67006 | |
| 66491 | 67007 | pIn1 = &aMem[u.ad.p1]; |
| 66492 | 67008 | pOut = &aMem[u.ad.p2]; |
| 66493 | 67009 | while( u.ad.n-- ){ |
| 66494 | | - assert( pOut<=&aMem[p->nMem] ); |
| 66495 | | - assert( pIn1<=&aMem[p->nMem] ); |
| 67010 | + assert( pOut<=&aMem[(p->nMem-p->nCursor)] ); |
| 67011 | + assert( pIn1<=&aMem[(p->nMem-p->nCursor)] ); |
| 66496 | 67012 | assert( memIsValid(pIn1) ); |
| 66497 | 67013 | memAboutToChange(p, pOut); |
| 66498 | 67014 | u.ad.zMalloc = pOut->zMalloc; |
| 66499 | 67015 | pOut->zMalloc = 0; |
| 66500 | 67016 | sqlite3VdbeMemMove(pOut, pIn1); |
| | @@ -66578,11 +67094,11 @@ |
| 66578 | 67094 | Mem *pMem; |
| 66579 | 67095 | int i; |
| 66580 | 67096 | #endif /* local variables moved into u.af */ |
| 66581 | 67097 | assert( p->nResColumn==pOp->p2 ); |
| 66582 | 67098 | assert( pOp->p1>0 ); |
| 66583 | | - assert( pOp->p1+pOp->p2<=p->nMem+1 ); |
| 67099 | + assert( pOp->p1+pOp->p2<=(p->nMem-p->nCursor)+1 ); |
| 66584 | 67100 | |
| 66585 | 67101 | /* If this statement has violated immediate foreign key constraints, do |
| 66586 | 67102 | ** not return the number of rows modified. And do not RELEASE the statement |
| 66587 | 67103 | ** transaction. It needs to be rolled back. */ |
| 66588 | 67104 | if( SQLITE_OK!=(rc = sqlite3VdbeCheckFk(p, 0)) ){ |
| | @@ -66858,15 +67374,15 @@ |
| 66858 | 67374 | #endif /* local variables moved into u.ai */ |
| 66859 | 67375 | |
| 66860 | 67376 | u.ai.n = pOp->p5; |
| 66861 | 67377 | u.ai.apVal = p->apArg; |
| 66862 | 67378 | assert( u.ai.apVal || u.ai.n==0 ); |
| 66863 | | - assert( pOp->p3>0 && pOp->p3<=p->nMem ); |
| 67379 | + assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) ); |
| 66864 | 67380 | pOut = &aMem[pOp->p3]; |
| 66865 | 67381 | memAboutToChange(p, pOut); |
| 66866 | 67382 | |
| 66867 | | - assert( u.ai.n==0 || (pOp->p2>0 && pOp->p2+u.ai.n<=p->nMem+1) ); |
| 67383 | + assert( u.ai.n==0 || (pOp->p2>0 && pOp->p2+u.ai.n<=(p->nMem-p->nCursor)+1) ); |
| 66868 | 67384 | assert( pOp->p3<pOp->p2 || pOp->p3>=pOp->p2+u.ai.n ); |
| 66869 | 67385 | u.ai.pArg = &aMem[pOp->p2]; |
| 66870 | 67386 | for(u.ai.i=0; u.ai.i<u.ai.n; u.ai.i++, u.ai.pArg++){ |
| 66871 | 67387 | assert( memIsValid(u.ai.pArg) ); |
| 66872 | 67388 | u.ai.apVal[u.ai.i] = u.ai.pArg; |
| | @@ -67398,15 +67914,15 @@ |
| 67398 | 67914 | u.al.p2 = pOp->p2; |
| 67399 | 67915 | #if SQLITE_DEBUG |
| 67400 | 67916 | if( aPermute ){ |
| 67401 | 67917 | int k, mx = 0; |
| 67402 | 67918 | for(k=0; k<u.al.n; k++) if( aPermute[k]>mx ) mx = aPermute[k]; |
| 67403 | | - assert( u.al.p1>0 && u.al.p1+mx<=p->nMem+1 ); |
| 67404 | | - assert( u.al.p2>0 && u.al.p2+mx<=p->nMem+1 ); |
| 67919 | + assert( u.al.p1>0 && u.al.p1+mx<=(p->nMem-p->nCursor)+1 ); |
| 67920 | + assert( u.al.p2>0 && u.al.p2+mx<=(p->nMem-p->nCursor)+1 ); |
| 67405 | 67921 | }else{ |
| 67406 | | - assert( u.al.p1>0 && u.al.p1+u.al.n<=p->nMem+1 ); |
| 67407 | | - assert( u.al.p2>0 && u.al.p2+u.al.n<=p->nMem+1 ); |
| 67922 | + assert( u.al.p1>0 && u.al.p1+u.al.n<=(p->nMem-p->nCursor)+1 ); |
| 67923 | + assert( u.al.p2>0 && u.al.p2+u.al.n<=(p->nMem-p->nCursor)+1 ); |
| 67408 | 67924 | } |
| 67409 | 67925 | #endif /* SQLITE_DEBUG */ |
| 67410 | 67926 | for(u.al.i=0; u.al.i<u.al.n; u.al.i++){ |
| 67411 | 67927 | u.al.idx = aPermute ? aPermute[u.al.i] : u.al.i; |
| 67412 | 67928 | assert( memIsValid(&aMem[u.al.p1+u.al.idx]) ); |
| | @@ -67659,11 +68175,11 @@ |
| 67659 | 68175 | u.ao.p1 = pOp->p1; |
| 67660 | 68176 | u.ao.p2 = pOp->p2; |
| 67661 | 68177 | u.ao.pC = 0; |
| 67662 | 68178 | memset(&u.ao.sMem, 0, sizeof(u.ao.sMem)); |
| 67663 | 68179 | assert( u.ao.p1<p->nCursor ); |
| 67664 | | - assert( pOp->p3>0 && pOp->p3<=p->nMem ); |
| 68180 | + assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) ); |
| 67665 | 68181 | u.ao.pDest = &aMem[pOp->p3]; |
| 67666 | 68182 | memAboutToChange(p, u.ao.pDest); |
| 67667 | 68183 | u.ao.zRec = 0; |
| 67668 | 68184 | |
| 67669 | 68185 | /* This block sets the variable u.ao.payloadSize to be the total number of |
| | @@ -67959,11 +68475,11 @@ |
| 67959 | 68475 | u.ap.zAffinity = pOp->p4.z; |
| 67960 | 68476 | assert( u.ap.zAffinity!=0 ); |
| 67961 | 68477 | assert( u.ap.zAffinity[pOp->p2]==0 ); |
| 67962 | 68478 | pIn1 = &aMem[pOp->p1]; |
| 67963 | 68479 | while( (u.ap.cAff = *(u.ap.zAffinity++))!=0 ){ |
| 67964 | | - assert( pIn1 <= &p->aMem[p->nMem] ); |
| 68480 | + assert( pIn1 <= &p->aMem[(p->nMem-p->nCursor)] ); |
| 67965 | 68481 | assert( memIsValid(pIn1) ); |
| 67966 | 68482 | ExpandBlob(pIn1); |
| 67967 | 68483 | applyAffinity(pIn1, u.ap.cAff, encoding); |
| 67968 | 68484 | pIn1++; |
| 67969 | 68485 | } |
| | @@ -68022,11 +68538,11 @@ |
| 68022 | 68538 | u.aq.nData = 0; /* Number of bytes of data space */ |
| 68023 | 68539 | u.aq.nHdr = 0; /* Number of bytes of header space */ |
| 68024 | 68540 | u.aq.nZero = 0; /* Number of zero bytes at the end of the record */ |
| 68025 | 68541 | u.aq.nField = pOp->p1; |
| 68026 | 68542 | u.aq.zAffinity = pOp->p4.z; |
| 68027 | | - assert( u.aq.nField>0 && pOp->p2>0 && pOp->p2+u.aq.nField<=p->nMem+1 ); |
| 68543 | + assert( u.aq.nField>0 && pOp->p2>0 && pOp->p2+u.aq.nField<=(p->nMem-p->nCursor)+1 ); |
| 68028 | 68544 | u.aq.pData0 = &aMem[u.aq.nField]; |
| 68029 | 68545 | u.aq.nField = pOp->p2; |
| 68030 | 68546 | u.aq.pLast = &u.aq.pData0[u.aq.nField-1]; |
| 68031 | 68547 | u.aq.file_format = p->minWriteFileFormat; |
| 68032 | 68548 | |
| | @@ -68088,11 +68604,11 @@ |
| 68088 | 68604 | for(u.aq.pRec=u.aq.pData0; u.aq.pRec<=u.aq.pLast; u.aq.pRec++){ /* serial data */ |
| 68089 | 68605 | u.aq.i += sqlite3VdbeSerialPut(&u.aq.zNewRecord[u.aq.i], (int)(u.aq.nByte-u.aq.i), u.aq.pRec,u.aq.file_format); |
| 68090 | 68606 | } |
| 68091 | 68607 | assert( u.aq.i==u.aq.nByte ); |
| 68092 | 68608 | |
| 68093 | | - assert( pOp->p3>0 && pOp->p3<=p->nMem ); |
| 68609 | + assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) ); |
| 68094 | 68610 | pOut->n = (int)u.aq.nByte; |
| 68095 | 68611 | pOut->flags = MEM_Blob | MEM_Dyn; |
| 68096 | 68612 | pOut->xDel = 0; |
| 68097 | 68613 | if( u.aq.nZero ){ |
| 68098 | 68614 | pOut->u.nZero = u.aq.nZero; |
| | @@ -68684,11 +69200,11 @@ |
| 68684 | 69200 | }else{ |
| 68685 | 69201 | u.ay.wrFlag = 0; |
| 68686 | 69202 | } |
| 68687 | 69203 | if( pOp->p5 & OPFLAG_P2ISREG ){ |
| 68688 | 69204 | assert( u.ay.p2>0 ); |
| 68689 | | - assert( u.ay.p2<=p->nMem ); |
| 69205 | + assert( u.ay.p2<=(p->nMem-p->nCursor) ); |
| 68690 | 69206 | pIn2 = &aMem[u.ay.p2]; |
| 68691 | 69207 | assert( memIsValid(pIn2) ); |
| 68692 | 69208 | assert( (pIn2->flags & MEM_Int)!=0 ); |
| 68693 | 69209 | sqlite3VdbeMemIntegerify(pIn2); |
| 68694 | 69210 | u.ay.p2 = (int)pIn2->u.i; |
| | @@ -69235,11 +69751,11 @@ |
| 69235 | 69751 | |
| 69236 | 69752 | pIn3 = &aMem[pOp->p3]; |
| 69237 | 69753 | u.bf.aMx = &aMem[pOp->p4.i]; |
| 69238 | 69754 | /* Assert that the values of parameters P1 and P4 are in range. */ |
| 69239 | 69755 | assert( pOp->p4type==P4_INT32 ); |
| 69240 | | - assert( pOp->p4.i>0 && pOp->p4.i<=p->nMem ); |
| 69756 | + assert( pOp->p4.i>0 && pOp->p4.i<=(p->nMem-p->nCursor) ); |
| 69241 | 69757 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 69242 | 69758 | |
| 69243 | 69759 | /* Find the index cursor. */ |
| 69244 | 69760 | u.bf.pCx = p->apCsr[pOp->p1]; |
| 69245 | 69761 | assert( u.bf.pCx->deferredMoveto==0 ); |
| | @@ -69442,11 +69958,11 @@ |
| 69442 | 69958 | /* Assert that P3 is a valid memory cell. */ |
| 69443 | 69959 | assert( pOp->p3<=u.bh.pFrame->nMem ); |
| 69444 | 69960 | u.bh.pMem = &u.bh.pFrame->aMem[pOp->p3]; |
| 69445 | 69961 | }else{ |
| 69446 | 69962 | /* Assert that P3 is a valid memory cell. */ |
| 69447 | | - assert( pOp->p3<=p->nMem ); |
| 69963 | + assert( pOp->p3<=(p->nMem-p->nCursor) ); |
| 69448 | 69964 | u.bh.pMem = &aMem[pOp->p3]; |
| 69449 | 69965 | memAboutToChange(p, u.bh.pMem); |
| 69450 | 69966 | } |
| 69451 | 69967 | assert( memIsValid(u.bh.pMem) ); |
| 69452 | 69968 | |
| | @@ -70120,11 +70636,11 @@ |
| 70120 | 70636 | int res; |
| 70121 | 70637 | UnpackedRecord r; |
| 70122 | 70638 | #endif /* local variables moved into u.bt */ |
| 70123 | 70639 | |
| 70124 | 70640 | assert( pOp->p3>0 ); |
| 70125 | | - assert( pOp->p2>0 && pOp->p2+pOp->p3<=p->nMem+1 ); |
| 70641 | + assert( pOp->p2>0 && pOp->p2+pOp->p3<=(p->nMem-p->nCursor)+1 ); |
| 70126 | 70642 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 70127 | 70643 | u.bt.pC = p->apCsr[pOp->p1]; |
| 70128 | 70644 | assert( u.bt.pC!=0 ); |
| 70129 | 70645 | u.bt.pCrsr = u.bt.pC->pCursor; |
| 70130 | 70646 | if( ALWAYS(u.bt.pCrsr!=0) ){ |
| | @@ -70336,10 +70852,11 @@ |
| 70336 | 70852 | int nChange; |
| 70337 | 70853 | #endif /* local variables moved into u.bx */ |
| 70338 | 70854 | |
| 70339 | 70855 | u.bx.nChange = 0; |
| 70340 | 70856 | assert( p->readOnly==0 ); |
| 70857 | + assert( pOp->p1!=1 ); |
| 70341 | 70858 | assert( (p->btreeMask & (((yDbMask)1)<<pOp->p2))!=0 ); |
| 70342 | 70859 | rc = sqlite3BtreeClearTable( |
| 70343 | 70860 | db->aDb[pOp->p2].pBt, pOp->p1, (pOp->p3 ? &u.bx.nChange : 0) |
| 70344 | 70861 | ); |
| 70345 | 70862 | if( pOp->p3 ){ |
| | @@ -70542,11 +71059,11 @@ |
| 70542 | 71059 | assert( p->bIsReader ); |
| 70543 | 71060 | u.ca.nRoot = pOp->p2; |
| 70544 | 71061 | assert( u.ca.nRoot>0 ); |
| 70545 | 71062 | u.ca.aRoot = sqlite3DbMallocRaw(db, sizeof(int)*(u.ca.nRoot+1) ); |
| 70546 | 71063 | if( u.ca.aRoot==0 ) goto no_mem; |
| 70547 | | - assert( pOp->p3>0 && pOp->p3<=p->nMem ); |
| 71064 | + assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) ); |
| 70548 | 71065 | u.ca.pnErr = &aMem[pOp->p3]; |
| 70549 | 71066 | assert( (u.ca.pnErr->flags & MEM_Int)!=0 ); |
| 70550 | 71067 | assert( (u.ca.pnErr->flags & (MEM_Str|MEM_Blob))==0 ); |
| 70551 | 71068 | pIn1 = &aMem[pOp->p1]; |
| 70552 | 71069 | for(u.ca.j=0; u.ca.j<u.ca.nRoot; u.ca.j++){ |
| | @@ -70978,11 +71495,11 @@ |
| 70978 | 71495 | u.cg.apVal[u.cg.i] = u.cg.pRec; |
| 70979 | 71496 | memAboutToChange(p, u.cg.pRec); |
| 70980 | 71497 | sqlite3VdbeMemStoreType(u.cg.pRec); |
| 70981 | 71498 | } |
| 70982 | 71499 | u.cg.ctx.pFunc = pOp->p4.pFunc; |
| 70983 | | - assert( pOp->p3>0 && pOp->p3<=p->nMem ); |
| 71500 | + assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) ); |
| 70984 | 71501 | u.cg.ctx.pMem = u.cg.pMem = &aMem[pOp->p3]; |
| 70985 | 71502 | u.cg.pMem->n++; |
| 70986 | 71503 | u.cg.ctx.s.flags = MEM_Null; |
| 70987 | 71504 | u.cg.ctx.s.z = 0; |
| 70988 | 71505 | u.cg.ctx.s.zMalloc = 0; |
| | @@ -71027,11 +71544,11 @@ |
| 71027 | 71544 | */ |
| 71028 | 71545 | case OP_AggFinal: { |
| 71029 | 71546 | #if 0 /* local variables moved into u.ch */ |
| 71030 | 71547 | Mem *pMem; |
| 71031 | 71548 | #endif /* local variables moved into u.ch */ |
| 71032 | | - assert( pOp->p1>0 && pOp->p1<=p->nMem ); |
| 71549 | + assert( pOp->p1>0 && pOp->p1<=(p->nMem-p->nCursor) ); |
| 71033 | 71550 | u.ch.pMem = &aMem[pOp->p1]; |
| 71034 | 71551 | assert( (u.ch.pMem->flags & ~(MEM_Null|MEM_Agg))==0 ); |
| 71035 | 71552 | rc = sqlite3VdbeMemFinalize(u.ch.pMem, pOp->p4.pFunc); |
| 71036 | 71553 | if( rc ){ |
| 71037 | 71554 | sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(u.ch.pMem)); |
| | @@ -71458,11 +71975,11 @@ |
| 71458 | 71975 | sqlite3_context sContext; |
| 71459 | 71976 | #endif /* local variables moved into u.co */ |
| 71460 | 71977 | |
| 71461 | 71978 | VdbeCursor *pCur = p->apCsr[pOp->p1]; |
| 71462 | 71979 | assert( pCur->pVtabCursor ); |
| 71463 | | - assert( pOp->p3>0 && pOp->p3<=p->nMem ); |
| 71980 | + assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) ); |
| 71464 | 71981 | u.co.pDest = &aMem[pOp->p3]; |
| 71465 | 71982 | memAboutToChange(p, u.co.pDest); |
| 71466 | 71983 | if( pCur->nullRow ){ |
| 71467 | 71984 | sqlite3VdbeMemSetNull(u.co.pDest); |
| 71468 | 71985 | break; |
| | @@ -76729,11 +77246,11 @@ |
| 76729 | 77246 | break; |
| 76730 | 77247 | } |
| 76731 | 77248 | case TK_UMINUS: { |
| 76732 | 77249 | int v; |
| 76733 | 77250 | if( sqlite3ExprIsInteger(p->pLeft, &v) ){ |
| 76734 | | - assert( v!=-2147483648 ); |
| 77251 | + assert( v!=(-2147483647-1) ); |
| 76735 | 77252 | *pValue = -v; |
| 76736 | 77253 | rc = 1; |
| 76737 | 77254 | } |
| 76738 | 77255 | break; |
| 76739 | 77256 | } |
| | @@ -80389,11 +80906,11 @@ |
| 80389 | 80906 | |
| 80390 | 80907 | /* Ensure the default expression is something that sqlite3ValueFromExpr() |
| 80391 | 80908 | ** can handle (i.e. not CURRENT_TIME etc.) |
| 80392 | 80909 | */ |
| 80393 | 80910 | if( pDflt ){ |
| 80394 | | - sqlite3_value *pVal; |
| 80911 | + sqlite3_value *pVal = 0; |
| 80395 | 80912 | if( sqlite3ValueFromExpr(db, pDflt, SQLITE_UTF8, SQLITE_AFF_NONE, &pVal) ){ |
| 80396 | 80913 | db->mallocFailed = 1; |
| 80397 | 80914 | return; |
| 80398 | 80915 | } |
| 80399 | 80916 | if( !pVal ){ |
| | @@ -80530,11 +81047,11 @@ |
| 80530 | 81047 | #endif /* SQLITE_ALTER_TABLE */ |
| 80531 | 81048 | |
| 80532 | 81049 | /************** End of alter.c ***********************************************/ |
| 80533 | 81050 | /************** Begin file analyze.c *****************************************/ |
| 80534 | 81051 | /* |
| 80535 | | -** 2005 July 8 |
| 81052 | +** 2005-07-08 |
| 80536 | 81053 | ** |
| 80537 | 81054 | ** The author disclaims copyright to this source code. In place of |
| 80538 | 81055 | ** a legal notice, here is a blessing: |
| 80539 | 81056 | ** |
| 80540 | 81057 | ** May you do good and not evil. |
| | @@ -80551,27 +81068,36 @@ |
| 80551 | 81068 | ** The following system tables are or have been supported: |
| 80552 | 81069 | ** |
| 80553 | 81070 | ** CREATE TABLE sqlite_stat1(tbl, idx, stat); |
| 80554 | 81071 | ** CREATE TABLE sqlite_stat2(tbl, idx, sampleno, sample); |
| 80555 | 81072 | ** CREATE TABLE sqlite_stat3(tbl, idx, nEq, nLt, nDLt, sample); |
| 81073 | +** CREATE TABLE sqlite_stat4(tbl, idx, nEq, nLt, nDLt, sample); |
| 80556 | 81074 | ** |
| 80557 | 81075 | ** Additional tables might be added in future releases of SQLite. |
| 80558 | 81076 | ** The sqlite_stat2 table is not created or used unless the SQLite version |
| 80559 | 81077 | ** is between 3.6.18 and 3.7.8, inclusive, and unless SQLite is compiled |
| 80560 | 81078 | ** with SQLITE_ENABLE_STAT2. The sqlite_stat2 table is deprecated. |
| 80561 | 81079 | ** The sqlite_stat2 table is superseded by sqlite_stat3, which is only |
| 80562 | 81080 | ** created and used by SQLite versions 3.7.9 and later and with |
| 80563 | | -** SQLITE_ENABLE_STAT3 defined. The fucntionality of sqlite_stat3 |
| 80564 | | -** is a superset of sqlite_stat2. |
| 81081 | +** SQLITE_ENABLE_STAT3 defined. The functionality of sqlite_stat3 |
| 81082 | +** is a superset of sqlite_stat2. The sqlite_stat4 is an enhanced |
| 81083 | +** version of sqlite_stat3 and is only available when compiled with |
| 81084 | +** SQLITE_ENABLE_STAT4 and in SQLite versions 3.8.0 and later. It is |
| 81085 | +** not possible to enable both STAT3 and STAT4 at the same time. If they |
| 81086 | +** are both enabled, then STAT4 takes precedence. |
| 81087 | +** |
| 81088 | +** For most applications, sqlite_stat1 provides all the statisics required |
| 81089 | +** for the query planner to make good choices. |
| 80565 | 81090 | ** |
| 80566 | 81091 | ** Format of sqlite_stat1: |
| 80567 | 81092 | ** |
| 80568 | 81093 | ** There is normally one row per index, with the index identified by the |
| 80569 | 81094 | ** name in the idx column. The tbl column is the name of the table to |
| 80570 | 81095 | ** which the index belongs. In each such row, the stat column will be |
| 80571 | 81096 | ** a string consisting of a list of integers. The first integer in this |
| 80572 | | -** list is the number of rows in the index and in the table. The second |
| 81097 | +** list is the number of rows in the index. (This is the same as the |
| 81098 | +** number of rows in the table, except for partial indices.) The second |
| 80573 | 81099 | ** integer is the average number of rows in the index that have the same |
| 80574 | 81100 | ** value in the first column of the index. The third integer is the average |
| 80575 | 81101 | ** number of rows in the index that have the same value for the first two |
| 80576 | 81102 | ** columns. The N-th integer (for N>1) is the average number of rows in |
| 80577 | 81103 | ** the index which have the same value for the first N-1 columns. For |
| | @@ -80614,57 +81140,85 @@ |
| 80614 | 81140 | ** writes the sqlite_stat2 table. This version of SQLite only supports |
| 80615 | 81141 | ** sqlite_stat3. |
| 80616 | 81142 | ** |
| 80617 | 81143 | ** Format for sqlite_stat3: |
| 80618 | 81144 | ** |
| 80619 | | -** The sqlite_stat3 is an enhancement to sqlite_stat2. A new name is |
| 80620 | | -** used to avoid compatibility problems. |
| 81145 | +** The sqlite_stat3 format is a subset of sqlite_stat4. Hence, the |
| 81146 | +** sqlite_stat4 format will be described first. Further information |
| 81147 | +** about sqlite_stat3 follows the sqlite_stat4 description. |
| 80621 | 81148 | ** |
| 80622 | | -** The format of the sqlite_stat3 table is similar to the format of |
| 80623 | | -** the sqlite_stat2 table. There are multiple entries for each index. |
| 81149 | +** Format for sqlite_stat4: |
| 81150 | +** |
| 81151 | +** As with sqlite_stat2, the sqlite_stat4 table contains histogram data |
| 81152 | +** to aid the query planner in choosing good indices based on the values |
| 81153 | +** that indexed columns are compared against in the WHERE clauses of |
| 81154 | +** queries. |
| 81155 | +** |
| 81156 | +** The sqlite_stat4 table contains multiple entries for each index. |
| 80624 | 81157 | ** The idx column names the index and the tbl column is the table of the |
| 80625 | 81158 | ** index. If the idx and tbl columns are the same, then the sample is |
| 80626 | | -** of the INTEGER PRIMARY KEY. The sample column is a value taken from |
| 80627 | | -** the left-most column of the index. The nEq column is the approximate |
| 80628 | | -** number of entires in the index whose left-most column exactly matches |
| 80629 | | -** the sample. nLt is the approximate number of entires whose left-most |
| 80630 | | -** column is less than the sample. The nDLt column is the approximate |
| 80631 | | -** number of distinct left-most entries in the index that are less than |
| 80632 | | -** the sample. |
| 80633 | | -** |
| 80634 | | -** Future versions of SQLite might change to store a string containing |
| 80635 | | -** multiple integers values in the nDLt column of sqlite_stat3. The first |
| 80636 | | -** integer will be the number of prior index entires that are distinct in |
| 80637 | | -** the left-most column. The second integer will be the number of prior index |
| 80638 | | -** entries that are distinct in the first two columns. The third integer |
| 80639 | | -** will be the number of prior index entries that are distinct in the first |
| 80640 | | -** three columns. And so forth. With that extension, the nDLt field is |
| 80641 | | -** similar in function to the sqlite_stat1.stat field. |
| 80642 | | -** |
| 80643 | | -** There can be an arbitrary number of sqlite_stat3 entries per index. |
| 80644 | | -** The ANALYZE command will typically generate sqlite_stat3 tables |
| 81159 | +** of the INTEGER PRIMARY KEY. The sample column is a blob which is the |
| 81160 | +** binary encoding of a key from the index, with the trailing rowid |
| 81161 | +** omitted. The nEq column is a list of integers. The first integer |
| 81162 | +** is the approximate number of entries in the index whose left-most |
| 81163 | +** column exactly matches the left-most column of the sample. The second |
| 81164 | +** integer in nEq is the approximate number of entries in the index where |
| 81165 | +** the first two columns match the first two columns of the sample. |
| 81166 | +** And so forth. nLt is another list of integers that show the approximate |
| 81167 | +** number of entries that are strictly less than the sample. The first |
| 81168 | +** integer in nLt contains the number of entries in the index where the |
| 81169 | +** left-most column is less than the left-most column of the sample. |
| 81170 | +** The K-th integer in the nLt entry is the number of index entries |
| 81171 | +** where the first K columns are less than the first K columns of the |
| 81172 | +** sample. The nDLt column is like nLt except that it contains the |
| 81173 | +** number of distinct entries in the index that are less than the |
| 81174 | +** sample. |
| 81175 | +** |
| 81176 | +** There can be an arbitrary number of sqlite_stat4 entries per index. |
| 81177 | +** The ANALYZE command will typically generate sqlite_stat4 tables |
| 80645 | 81178 | ** that contain between 10 and 40 samples which are distributed across |
| 80646 | 81179 | ** the key space, though not uniformly, and which include samples with |
| 80647 | | -** largest possible nEq values. |
| 81180 | +** large nEq values. |
| 81181 | +** |
| 81182 | +** Format for sqlite_stat3 redux: |
| 81183 | +** |
| 81184 | +** The sqlite_stat3 table is like sqlite_stat4 except that it only |
| 81185 | +** looks at the left-most column of the index. The sqlite_stat3.sample |
| 81186 | +** column contains the actual value of the left-most column instead |
| 81187 | +** of a blob encoding of the complete index key as is found in |
| 81188 | +** sqlite_stat4.sample. The nEq, nLt, and nDLt entries of sqlite_stat3 |
| 81189 | +** all contain just a single integer which is the same as the first |
| 81190 | +** integer in the equivalent columns in sqlite_stat4. |
| 80648 | 81191 | */ |
| 80649 | 81192 | #ifndef SQLITE_OMIT_ANALYZE |
| 80650 | 81193 | |
| 81194 | +#if defined(SQLITE_ENABLE_STAT4) |
| 81195 | +# define IsStat4 1 |
| 81196 | +# define IsStat3 0 |
| 81197 | +#elif defined(SQLITE_ENABLE_STAT3) |
| 81198 | +# define IsStat4 0 |
| 81199 | +# define IsStat3 1 |
| 81200 | +#else |
| 81201 | +# define IsStat4 0 |
| 81202 | +# define IsStat3 0 |
| 81203 | +# undef SQLITE_STAT4_SAMPLES |
| 81204 | +# define SQLITE_STAT4_SAMPLES 1 |
| 81205 | +#endif |
| 81206 | +#define IsStat34 (IsStat3+IsStat4) /* 1 for STAT3 or STAT4. 0 otherwise */ |
| 81207 | + |
| 80651 | 81208 | /* |
| 80652 | | -** This routine generates code that opens the sqlite_stat1 table for |
| 80653 | | -** writing with cursor iStatCur. If the library was built with the |
| 80654 | | -** SQLITE_ENABLE_STAT3 macro defined, then the sqlite_stat3 table is |
| 80655 | | -** opened for writing using cursor (iStatCur+1) |
| 81209 | +** This routine generates code that opens the sqlite_statN tables. |
| 81210 | +** The sqlite_stat1 table is always relevant. sqlite_stat2 is now |
| 81211 | +** obsolete. sqlite_stat3 and sqlite_stat4 are only opened when |
| 81212 | +** appropriate compile-time options are provided. |
| 80656 | 81213 | ** |
| 80657 | | -** If the sqlite_stat1 tables does not previously exist, it is created. |
| 80658 | | -** Similarly, if the sqlite_stat3 table does not exist and the library |
| 80659 | | -** is compiled with SQLITE_ENABLE_STAT3 defined, it is created. |
| 81214 | +** If the sqlite_statN tables do not previously exist, it is created. |
| 80660 | 81215 | ** |
| 80661 | 81216 | ** Argument zWhere may be a pointer to a buffer containing a table name, |
| 80662 | 81217 | ** or it may be a NULL pointer. If it is not NULL, then all entries in |
| 80663 | | -** the sqlite_stat1 and (if applicable) sqlite_stat3 tables associated |
| 80664 | | -** with the named table are deleted. If zWhere==0, then code is generated |
| 80665 | | -** to delete all stat table entries. |
| 81218 | +** the sqlite_statN tables associated with the named table are deleted. |
| 81219 | +** If zWhere==0, then code is generated to delete all stat table entries. |
| 80666 | 81220 | */ |
| 80667 | 81221 | static void openStatTable( |
| 80668 | 81222 | Parse *pParse, /* Parsing context */ |
| 80669 | 81223 | int iDb, /* The database we are looking in */ |
| 80670 | 81224 | int iStatCur, /* Open the sqlite_stat1 table on this cursor */ |
| | @@ -80674,22 +81228,28 @@ |
| 80674 | 81228 | static const struct { |
| 80675 | 81229 | const char *zName; |
| 80676 | 81230 | const char *zCols; |
| 80677 | 81231 | } aTable[] = { |
| 80678 | 81232 | { "sqlite_stat1", "tbl,idx,stat" }, |
| 80679 | | -#ifdef SQLITE_ENABLE_STAT3 |
| 81233 | +#if defined(SQLITE_ENABLE_STAT4) |
| 81234 | + { "sqlite_stat4", "tbl,idx,neq,nlt,ndlt,sample" }, |
| 81235 | + { "sqlite_stat3", 0 }, |
| 81236 | +#elif defined(SQLITE_ENABLE_STAT3) |
| 80680 | 81237 | { "sqlite_stat3", "tbl,idx,neq,nlt,ndlt,sample" }, |
| 81238 | + { "sqlite_stat4", 0 }, |
| 81239 | +#else |
| 81240 | + { "sqlite_stat3", 0 }, |
| 81241 | + { "sqlite_stat4", 0 }, |
| 80681 | 81242 | #endif |
| 80682 | 81243 | }; |
| 80683 | | - |
| 80684 | | - int aRoot[] = {0, 0}; |
| 80685 | | - u8 aCreateTbl[] = {0, 0}; |
| 80686 | | - |
| 80687 | 81244 | int i; |
| 80688 | 81245 | sqlite3 *db = pParse->db; |
| 80689 | 81246 | Db *pDb; |
| 80690 | 81247 | Vdbe *v = sqlite3GetVdbe(pParse); |
| 81248 | + int aRoot[ArraySize(aTable)]; |
| 81249 | + u8 aCreateTbl[ArraySize(aTable)]; |
| 81250 | + |
| 80691 | 81251 | if( v==0 ) return; |
| 80692 | 81252 | assert( sqlite3BtreeHoldsAllMutexes(db) ); |
| 80693 | 81253 | assert( sqlite3VdbeDb(v)==db ); |
| 80694 | 81254 | pDb = &db->aDb[iDb]; |
| 80695 | 81255 | |
| | @@ -80698,262 +81258,626 @@ |
| 80698 | 81258 | */ |
| 80699 | 81259 | for(i=0; i<ArraySize(aTable); i++){ |
| 80700 | 81260 | const char *zTab = aTable[i].zName; |
| 80701 | 81261 | Table *pStat; |
| 80702 | 81262 | if( (pStat = sqlite3FindTable(db, zTab, pDb->zName))==0 ){ |
| 80703 | | - /* The sqlite_stat[12] table does not exist. Create it. Note that a |
| 80704 | | - ** side-effect of the CREATE TABLE statement is to leave the rootpage |
| 80705 | | - ** of the new table in register pParse->regRoot. This is important |
| 80706 | | - ** because the OpenWrite opcode below will be needing it. */ |
| 80707 | | - sqlite3NestedParse(pParse, |
| 80708 | | - "CREATE TABLE %Q.%s(%s)", pDb->zName, zTab, aTable[i].zCols |
| 80709 | | - ); |
| 80710 | | - aRoot[i] = pParse->regRoot; |
| 80711 | | - aCreateTbl[i] = OPFLAG_P2ISREG; |
| 81263 | + if( aTable[i].zCols ){ |
| 81264 | + /* The sqlite_statN table does not exist. Create it. Note that a |
| 81265 | + ** side-effect of the CREATE TABLE statement is to leave the rootpage |
| 81266 | + ** of the new table in register pParse->regRoot. This is important |
| 81267 | + ** because the OpenWrite opcode below will be needing it. */ |
| 81268 | + sqlite3NestedParse(pParse, |
| 81269 | + "CREATE TABLE %Q.%s(%s)", pDb->zName, zTab, aTable[i].zCols |
| 81270 | + ); |
| 81271 | + aRoot[i] = pParse->regRoot; |
| 81272 | + aCreateTbl[i] = OPFLAG_P2ISREG; |
| 81273 | + } |
| 80712 | 81274 | }else{ |
| 80713 | 81275 | /* The table already exists. If zWhere is not NULL, delete all entries |
| 80714 | 81276 | ** associated with the table zWhere. If zWhere is NULL, delete the |
| 80715 | 81277 | ** entire contents of the table. */ |
| 80716 | 81278 | aRoot[i] = pStat->tnum; |
| 81279 | + aCreateTbl[i] = 0; |
| 80717 | 81280 | sqlite3TableLock(pParse, iDb, aRoot[i], 1, zTab); |
| 80718 | 81281 | if( zWhere ){ |
| 80719 | 81282 | sqlite3NestedParse(pParse, |
| 80720 | | - "DELETE FROM %Q.%s WHERE %s=%Q", pDb->zName, zTab, zWhereType, zWhere |
| 81283 | + "DELETE FROM %Q.%s WHERE %s=%Q", |
| 81284 | + pDb->zName, zTab, zWhereType, zWhere |
| 80721 | 81285 | ); |
| 80722 | 81286 | }else{ |
| 80723 | | - /* The sqlite_stat[12] table already exists. Delete all rows. */ |
| 81287 | + /* The sqlite_stat[134] table already exists. Delete all rows. */ |
| 80724 | 81288 | sqlite3VdbeAddOp2(v, OP_Clear, aRoot[i], iDb); |
| 80725 | 81289 | } |
| 80726 | 81290 | } |
| 80727 | 81291 | } |
| 80728 | 81292 | |
| 80729 | | - /* Open the sqlite_stat[13] tables for writing. */ |
| 80730 | | - for(i=0; i<ArraySize(aTable); i++){ |
| 81293 | + /* Open the sqlite_stat[134] tables for writing. */ |
| 81294 | + for(i=0; aTable[i].zCols; i++){ |
| 81295 | + assert( i<ArraySize(aTable) ); |
| 80731 | 81296 | sqlite3VdbeAddOp3(v, OP_OpenWrite, iStatCur+i, aRoot[i], iDb); |
| 80732 | 81297 | sqlite3VdbeChangeP4(v, -1, (char *)3, P4_INT32); |
| 80733 | 81298 | sqlite3VdbeChangeP5(v, aCreateTbl[i]); |
| 80734 | 81299 | } |
| 80735 | 81300 | } |
| 80736 | 81301 | |
| 80737 | 81302 | /* |
| 80738 | | -** Recommended number of samples for sqlite_stat3 |
| 81303 | +** Recommended number of samples for sqlite_stat4 |
| 80739 | 81304 | */ |
| 80740 | | -#ifndef SQLITE_STAT3_SAMPLES |
| 80741 | | -# define SQLITE_STAT3_SAMPLES 24 |
| 81305 | +#ifndef SQLITE_STAT4_SAMPLES |
| 81306 | +# define SQLITE_STAT4_SAMPLES 24 |
| 80742 | 81307 | #endif |
| 80743 | 81308 | |
| 80744 | 81309 | /* |
| 80745 | | -** Three SQL functions - stat3_init(), stat3_push(), and stat3_pop() - |
| 81310 | +** Three SQL functions - stat_init(), stat_push(), and stat_get() - |
| 80746 | 81311 | ** share an instance of the following structure to hold their state |
| 80747 | 81312 | ** information. |
| 80748 | 81313 | */ |
| 80749 | | -typedef struct Stat3Accum Stat3Accum; |
| 80750 | | -struct Stat3Accum { |
| 81314 | +typedef struct Stat4Accum Stat4Accum; |
| 81315 | +typedef struct Stat4Sample Stat4Sample; |
| 81316 | +struct Stat4Sample { |
| 81317 | + tRowcnt *anEq; /* sqlite_stat4.nEq */ |
| 81318 | + tRowcnt *anDLt; /* sqlite_stat4.nDLt */ |
| 81319 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 81320 | + tRowcnt *anLt; /* sqlite_stat4.nLt */ |
| 81321 | + i64 iRowid; /* Rowid in main table of the key */ |
| 81322 | + u8 isPSample; /* True if a periodic sample */ |
| 81323 | + int iCol; /* If !isPSample, the reason for inclusion */ |
| 81324 | + u32 iHash; /* Tiebreaker hash */ |
| 81325 | +#endif |
| 81326 | +}; |
| 81327 | +struct Stat4Accum { |
| 80751 | 81328 | tRowcnt nRow; /* Number of rows in the entire table */ |
| 80752 | 81329 | tRowcnt nPSample; /* How often to do a periodic sample */ |
| 80753 | | - int iMin; /* Index of entry with minimum nEq and hash */ |
| 81330 | + int nCol; /* Number of columns in index + rowid */ |
| 80754 | 81331 | int mxSample; /* Maximum number of samples to accumulate */ |
| 80755 | | - int nSample; /* Current number of samples */ |
| 81332 | + Stat4Sample current; /* Current row as a Stat4Sample */ |
| 80756 | 81333 | u32 iPrn; /* Pseudo-random number used for sampling */ |
| 80757 | | - struct Stat3Sample { |
| 80758 | | - i64 iRowid; /* Rowid in main table of the key */ |
| 80759 | | - tRowcnt nEq; /* sqlite_stat3.nEq */ |
| 80760 | | - tRowcnt nLt; /* sqlite_stat3.nLt */ |
| 80761 | | - tRowcnt nDLt; /* sqlite_stat3.nDLt */ |
| 80762 | | - u8 isPSample; /* True if a periodic sample */ |
| 80763 | | - u32 iHash; /* Tiebreaker hash */ |
| 80764 | | - } *a; /* An array of samples */ |
| 81334 | + Stat4Sample *aBest; /* Array of (nCol-1) best samples */ |
| 81335 | + int iMin; /* Index in a[] of entry with minimum score */ |
| 81336 | + int nSample; /* Current number of samples */ |
| 81337 | + int iGet; /* Index of current sample accessed by stat_get() */ |
| 81338 | + Stat4Sample *a; /* Array of mxSample Stat4Sample objects */ |
| 80765 | 81339 | }; |
| 80766 | 81340 | |
| 80767 | | -#ifdef SQLITE_ENABLE_STAT3 |
| 80768 | 81341 | /* |
| 80769 | | -** Implementation of the stat3_init(C,S) SQL function. The two parameters |
| 80770 | | -** are the number of rows in the table or index (C) and the number of samples |
| 80771 | | -** to accumulate (S). |
| 80772 | | -** |
| 80773 | | -** This routine allocates the Stat3Accum object. |
| 80774 | | -** |
| 80775 | | -** The return value is the Stat3Accum object (P). |
| 80776 | | -*/ |
| 80777 | | -static void stat3Init( |
| 81342 | +** Implementation of the stat_init(N,C) SQL function. The two parameters |
| 81343 | +** are the number of rows in the table or index (C) and the number of columns |
| 81344 | +** in the index (N). The second argument (C) is only used for STAT3 and STAT4. |
| 81345 | +** |
| 81346 | +** This routine allocates the Stat4Accum object in heap memory. The return |
| 81347 | +** value is a pointer to the the Stat4Accum object encoded as a blob (i.e. |
| 81348 | +** the size of the blob is sizeof(void*) bytes). |
| 81349 | +*/ |
| 81350 | +static void statInit( |
| 80778 | 81351 | sqlite3_context *context, |
| 80779 | 81352 | int argc, |
| 80780 | 81353 | sqlite3_value **argv |
| 80781 | 81354 | ){ |
| 80782 | | - Stat3Accum *p; |
| 80783 | | - tRowcnt nRow; |
| 80784 | | - int mxSample; |
| 80785 | | - int n; |
| 81355 | + Stat4Accum *p; |
| 81356 | + int nCol; /* Number of columns in index being sampled */ |
| 81357 | + int nColUp; /* nCol rounded up for alignment */ |
| 81358 | + int n; /* Bytes of space to allocate */ |
| 81359 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 81360 | + int mxSample = SQLITE_STAT4_SAMPLES; |
| 81361 | +#endif |
| 80786 | 81362 | |
| 81363 | + /* Decode the three function arguments */ |
| 80787 | 81364 | UNUSED_PARAMETER(argc); |
| 80788 | | - nRow = (tRowcnt)sqlite3_value_int64(argv[0]); |
| 80789 | | - mxSample = sqlite3_value_int(argv[1]); |
| 80790 | | - n = sizeof(*p) + sizeof(p->a[0])*mxSample; |
| 80791 | | - p = sqlite3MallocZero( n ); |
| 81365 | + nCol = sqlite3_value_int(argv[0]); |
| 81366 | + assert( nCol>1 ); /* >1 because it includes the rowid column */ |
| 81367 | + nColUp = sizeof(tRowcnt)<8 ? (nCol+1)&~1 : nCol; |
| 81368 | + |
| 81369 | + /* Allocate the space required for the Stat4Accum object */ |
| 81370 | + n = sizeof(*p) |
| 81371 | + + sizeof(tRowcnt)*nColUp /* Stat4Accum.anEq */ |
| 81372 | + + sizeof(tRowcnt)*nColUp /* Stat4Accum.anDLt */ |
| 81373 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 81374 | + + sizeof(tRowcnt)*nColUp /* Stat4Accum.anLt */ |
| 81375 | + + sizeof(Stat4Sample)*(nCol+mxSample) /* Stat4Accum.aBest[], a[] */ |
| 81376 | + + sizeof(tRowcnt)*3*nColUp*(nCol+mxSample) |
| 81377 | +#endif |
| 81378 | + ; |
| 81379 | + p = sqlite3MallocZero(n); |
| 80792 | 81380 | if( p==0 ){ |
| 80793 | 81381 | sqlite3_result_error_nomem(context); |
| 80794 | 81382 | return; |
| 80795 | 81383 | } |
| 80796 | | - p->a = (struct Stat3Sample*)&p[1]; |
| 80797 | | - p->nRow = nRow; |
| 80798 | | - p->mxSample = mxSample; |
| 80799 | | - p->nPSample = p->nRow/(mxSample/3+1) + 1; |
| 80800 | | - sqlite3_randomness(sizeof(p->iPrn), &p->iPrn); |
| 81384 | + |
| 81385 | + p->nRow = 0; |
| 81386 | + p->nCol = nCol; |
| 81387 | + p->current.anDLt = (tRowcnt*)&p[1]; |
| 81388 | + p->current.anEq = &p->current.anDLt[nColUp]; |
| 81389 | + |
| 81390 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 81391 | + { |
| 81392 | + u8 *pSpace; /* Allocated space not yet assigned */ |
| 81393 | + int i; /* Used to iterate through p->aSample[] */ |
| 81394 | + |
| 81395 | + p->iGet = -1; |
| 81396 | + p->mxSample = mxSample; |
| 81397 | + p->nPSample = (tRowcnt)(sqlite3_value_int64(argv[1])/(mxSample/3+1) + 1); |
| 81398 | + p->current.anLt = &p->current.anEq[nColUp]; |
| 81399 | + sqlite3_randomness(sizeof(p->iPrn), &p->iPrn); |
| 81400 | + |
| 81401 | + /* Set up the Stat4Accum.a[] and aBest[] arrays */ |
| 81402 | + p->a = (struct Stat4Sample*)&p->current.anLt[nColUp]; |
| 81403 | + p->aBest = &p->a[mxSample]; |
| 81404 | + pSpace = (u8*)(&p->a[mxSample+nCol]); |
| 81405 | + for(i=0; i<(mxSample+nCol); i++){ |
| 81406 | + p->a[i].anEq = (tRowcnt *)pSpace; pSpace += (sizeof(tRowcnt) * nColUp); |
| 81407 | + p->a[i].anLt = (tRowcnt *)pSpace; pSpace += (sizeof(tRowcnt) * nColUp); |
| 81408 | + p->a[i].anDLt = (tRowcnt *)pSpace; pSpace += (sizeof(tRowcnt) * nColUp); |
| 81409 | + } |
| 81410 | + assert( (pSpace - (u8*)p)==n ); |
| 81411 | + |
| 81412 | + for(i=0; i<nCol; i++){ |
| 81413 | + p->aBest[i].iCol = i; |
| 81414 | + } |
| 81415 | + } |
| 81416 | +#endif |
| 81417 | + |
| 81418 | + /* Return a pointer to the allocated object to the caller */ |
| 80801 | 81419 | sqlite3_result_blob(context, p, sizeof(p), sqlite3_free); |
| 80802 | 81420 | } |
| 80803 | | -static const FuncDef stat3InitFuncdef = { |
| 80804 | | - 2, /* nArg */ |
| 80805 | | - SQLITE_UTF8, /* iPrefEnc */ |
| 80806 | | - 0, /* flags */ |
| 80807 | | - 0, /* pUserData */ |
| 80808 | | - 0, /* pNext */ |
| 80809 | | - stat3Init, /* xFunc */ |
| 80810 | | - 0, /* xStep */ |
| 80811 | | - 0, /* xFinalize */ |
| 80812 | | - "stat3_init", /* zName */ |
| 80813 | | - 0, /* pHash */ |
| 80814 | | - 0 /* pDestructor */ |
| 80815 | | -}; |
| 80816 | | - |
| 80817 | | - |
| 80818 | | -/* |
| 80819 | | -** Implementation of the stat3_push(nEq,nLt,nDLt,rowid,P) SQL function. The |
| 80820 | | -** arguments describe a single key instance. This routine makes the |
| 80821 | | -** decision about whether or not to retain this key for the sqlite_stat3 |
| 80822 | | -** table. |
| 80823 | | -** |
| 80824 | | -** The return value is NULL. |
| 80825 | | -*/ |
| 80826 | | -static void stat3Push( |
| 80827 | | - sqlite3_context *context, |
| 80828 | | - int argc, |
| 80829 | | - sqlite3_value **argv |
| 80830 | | -){ |
| 80831 | | - Stat3Accum *p = (Stat3Accum*)sqlite3_value_blob(argv[4]); |
| 80832 | | - tRowcnt nEq = sqlite3_value_int64(argv[0]); |
| 80833 | | - tRowcnt nLt = sqlite3_value_int64(argv[1]); |
| 80834 | | - tRowcnt nDLt = sqlite3_value_int64(argv[2]); |
| 80835 | | - i64 rowid = sqlite3_value_int64(argv[3]); |
| 80836 | | - u8 isPSample = 0; |
| 80837 | | - u8 doInsert = 0; |
| 80838 | | - int iMin = p->iMin; |
| 80839 | | - struct Stat3Sample *pSample; |
| 80840 | | - int i; |
| 80841 | | - u32 h; |
| 80842 | | - |
| 80843 | | - UNUSED_PARAMETER(context); |
| 80844 | | - UNUSED_PARAMETER(argc); |
| 80845 | | - if( nEq==0 ) return; |
| 80846 | | - h = p->iPrn = p->iPrn*1103515245 + 12345; |
| 80847 | | - if( (nLt/p->nPSample)!=((nEq+nLt)/p->nPSample) ){ |
| 80848 | | - doInsert = isPSample = 1; |
| 80849 | | - }else if( p->nSample<p->mxSample ){ |
| 80850 | | - doInsert = 1; |
| 80851 | | - }else{ |
| 80852 | | - if( nEq>p->a[iMin].nEq || (nEq==p->a[iMin].nEq && h>p->a[iMin].iHash) ){ |
| 80853 | | - doInsert = 1; |
| 80854 | | - } |
| 80855 | | - } |
| 80856 | | - if( !doInsert ) return; |
| 80857 | | - if( p->nSample==p->mxSample ){ |
| 80858 | | - assert( p->nSample - iMin - 1 >= 0 ); |
| 80859 | | - memmove(&p->a[iMin], &p->a[iMin+1], sizeof(p->a[0])*(p->nSample-iMin-1)); |
| 81421 | +static const FuncDef statInitFuncdef = { |
| 81422 | + 1+IsStat34, /* nArg */ |
| 81423 | + SQLITE_UTF8, /* iPrefEnc */ |
| 81424 | + 0, /* flags */ |
| 81425 | + 0, /* pUserData */ |
| 81426 | + 0, /* pNext */ |
| 81427 | + statInit, /* xFunc */ |
| 81428 | + 0, /* xStep */ |
| 81429 | + 0, /* xFinalize */ |
| 81430 | + "stat_init", /* zName */ |
| 81431 | + 0, /* pHash */ |
| 81432 | + 0 /* pDestructor */ |
| 81433 | +}; |
| 81434 | + |
| 81435 | +#ifdef SQLITE_ENABLE_STAT4 |
| 81436 | +/* |
| 81437 | +** pNew and pOld are both candidate non-periodic samples selected for |
| 81438 | +** the same column (pNew->iCol==pOld->iCol). Ignoring this column and |
| 81439 | +** considering only any trailing columns and the sample hash value, this |
| 81440 | +** function returns true if sample pNew is to be preferred over pOld. |
| 81441 | +** In other words, if we assume that the cardinalities of the selected |
| 81442 | +** column for pNew and pOld are equal, is pNew to be preferred over pOld. |
| 81443 | +** |
| 81444 | +** This function assumes that for each argument sample, the contents of |
| 81445 | +** the anEq[] array from pSample->anEq[pSample->iCol+1] onwards are valid. |
| 81446 | +*/ |
| 81447 | +static int sampleIsBetterPost( |
| 81448 | + Stat4Accum *pAccum, |
| 81449 | + Stat4Sample *pNew, |
| 81450 | + Stat4Sample *pOld |
| 81451 | +){ |
| 81452 | + int nCol = pAccum->nCol; |
| 81453 | + int i; |
| 81454 | + assert( pNew->iCol==pOld->iCol ); |
| 81455 | + for(i=pNew->iCol+1; i<nCol; i++){ |
| 81456 | + if( pNew->anEq[i]>pOld->anEq[i] ) return 1; |
| 81457 | + if( pNew->anEq[i]<pOld->anEq[i] ) return 0; |
| 81458 | + } |
| 81459 | + if( pNew->iHash>pOld->iHash ) return 1; |
| 81460 | + return 0; |
| 81461 | +} |
| 81462 | +#endif |
| 81463 | + |
| 81464 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 81465 | +/* |
| 81466 | +** Return true if pNew is to be preferred over pOld. |
| 81467 | +** |
| 81468 | +** This function assumes that for each argument sample, the contents of |
| 81469 | +** the anEq[] array from pSample->anEq[pSample->iCol] onwards are valid. |
| 81470 | +*/ |
| 81471 | +static int sampleIsBetter( |
| 81472 | + Stat4Accum *pAccum, |
| 81473 | + Stat4Sample *pNew, |
| 81474 | + Stat4Sample *pOld |
| 81475 | +){ |
| 81476 | + tRowcnt nEqNew = pNew->anEq[pNew->iCol]; |
| 81477 | + tRowcnt nEqOld = pOld->anEq[pOld->iCol]; |
| 81478 | + |
| 81479 | + assert( pOld->isPSample==0 && pNew->isPSample==0 ); |
| 81480 | + assert( IsStat4 || (pNew->iCol==0 && pOld->iCol==0) ); |
| 81481 | + |
| 81482 | + if( (nEqNew>nEqOld) ) return 1; |
| 81483 | +#ifdef SQLITE_ENABLE_STAT4 |
| 81484 | + if( nEqNew==nEqOld ){ |
| 81485 | + if( pNew->iCol<pOld->iCol ) return 1; |
| 81486 | + return (pNew->iCol==pOld->iCol && sampleIsBetterPost(pAccum, pNew, pOld)); |
| 81487 | + } |
| 81488 | + return 0; |
| 81489 | +#else |
| 81490 | + return (nEqNew==nEqOld && pNew->iHash>pOld->iHash); |
| 81491 | +#endif |
| 81492 | +} |
| 81493 | + |
| 81494 | +/* |
| 81495 | +** Copy the contents of object (*pFrom) into (*pTo). |
| 81496 | +*/ |
| 81497 | +void sampleCopy(Stat4Accum *p, Stat4Sample *pTo, Stat4Sample *pFrom){ |
| 81498 | + pTo->iRowid = pFrom->iRowid; |
| 81499 | + pTo->isPSample = pFrom->isPSample; |
| 81500 | + pTo->iCol = pFrom->iCol; |
| 81501 | + pTo->iHash = pFrom->iHash; |
| 81502 | + memcpy(pTo->anEq, pFrom->anEq, sizeof(tRowcnt)*p->nCol); |
| 81503 | + memcpy(pTo->anLt, pFrom->anLt, sizeof(tRowcnt)*p->nCol); |
| 81504 | + memcpy(pTo->anDLt, pFrom->anDLt, sizeof(tRowcnt)*p->nCol); |
| 81505 | +} |
| 81506 | + |
| 81507 | +/* |
| 81508 | +** Copy the contents of sample *pNew into the p->a[] array. If necessary, |
| 81509 | +** remove the least desirable sample from p->a[] to make room. |
| 81510 | +*/ |
| 81511 | +static void sampleInsert(Stat4Accum *p, Stat4Sample *pNew, int nEqZero){ |
| 81512 | + Stat4Sample *pSample; |
| 81513 | + int i; |
| 81514 | + |
| 81515 | + assert( IsStat4 || nEqZero==0 ); |
| 81516 | + |
| 81517 | +#ifdef SQLITE_ENABLE_STAT4 |
| 81518 | + if( pNew->isPSample==0 ){ |
| 81519 | + Stat4Sample *pUpgrade = 0; |
| 81520 | + assert( pNew->anEq[pNew->iCol]>0 ); |
| 81521 | + |
| 81522 | + /* This sample is being added because the prefix that ends in column |
| 81523 | + ** iCol occurs many times in the table. However, if we have already |
| 81524 | + ** added a sample that shares this prefix, there is no need to add |
| 81525 | + ** this one. Instead, upgrade the priority of the highest priority |
| 81526 | + ** existing sample that shares this prefix. */ |
| 81527 | + for(i=p->nSample-1; i>=0; i--){ |
| 81528 | + Stat4Sample *pOld = &p->a[i]; |
| 81529 | + if( pOld->anEq[pNew->iCol]==0 ){ |
| 81530 | + if( pOld->isPSample ) return; |
| 81531 | + assert( pOld->iCol>pNew->iCol ); |
| 81532 | + assert( sampleIsBetter(p, pNew, pOld) ); |
| 81533 | + if( pUpgrade==0 || sampleIsBetter(p, pOld, pUpgrade) ){ |
| 81534 | + pUpgrade = pOld; |
| 81535 | + } |
| 81536 | + } |
| 81537 | + } |
| 81538 | + if( pUpgrade ){ |
| 81539 | + pUpgrade->iCol = pNew->iCol; |
| 81540 | + pUpgrade->anEq[pUpgrade->iCol] = pNew->anEq[pUpgrade->iCol]; |
| 81541 | + goto find_new_min; |
| 81542 | + } |
| 81543 | + } |
| 81544 | +#endif |
| 81545 | + |
| 81546 | + /* If necessary, remove sample iMin to make room for the new sample. */ |
| 81547 | + if( p->nSample>=p->mxSample ){ |
| 81548 | + Stat4Sample *pMin = &p->a[p->iMin]; |
| 81549 | + tRowcnt *anEq = pMin->anEq; |
| 81550 | + tRowcnt *anLt = pMin->anLt; |
| 81551 | + tRowcnt *anDLt = pMin->anDLt; |
| 81552 | + memmove(pMin, &pMin[1], sizeof(p->a[0])*(p->nSample-p->iMin-1)); |
| 80860 | 81553 | pSample = &p->a[p->nSample-1]; |
| 80861 | | - }else{ |
| 80862 | | - pSample = &p->a[p->nSample++]; |
| 80863 | | - } |
| 80864 | | - pSample->iRowid = rowid; |
| 80865 | | - pSample->nEq = nEq; |
| 80866 | | - pSample->nLt = nLt; |
| 80867 | | - pSample->nDLt = nDLt; |
| 80868 | | - pSample->iHash = h; |
| 80869 | | - pSample->isPSample = isPSample; |
| 80870 | | - |
| 80871 | | - /* Find the new minimum */ |
| 80872 | | - if( p->nSample==p->mxSample ){ |
| 80873 | | - pSample = p->a; |
| 80874 | | - i = 0; |
| 80875 | | - while( pSample->isPSample ){ |
| 80876 | | - i++; |
| 80877 | | - pSample++; |
| 80878 | | - assert( i<p->nSample ); |
| 80879 | | - } |
| 80880 | | - nEq = pSample->nEq; |
| 80881 | | - h = pSample->iHash; |
| 80882 | | - iMin = i; |
| 80883 | | - for(i++, pSample++; i<p->nSample; i++, pSample++){ |
| 80884 | | - if( pSample->isPSample ) continue; |
| 80885 | | - if( pSample->nEq<nEq |
| 80886 | | - || (pSample->nEq==nEq && pSample->iHash<h) |
| 80887 | | - ){ |
| 80888 | | - iMin = i; |
| 80889 | | - nEq = pSample->nEq; |
| 80890 | | - h = pSample->iHash; |
| 80891 | | - } |
| 80892 | | - } |
| 81554 | + pSample->anEq = anEq; |
| 81555 | + pSample->anDLt = anDLt; |
| 81556 | + pSample->anLt = anLt; |
| 81557 | + p->nSample = p->mxSample-1; |
| 81558 | + } |
| 81559 | + |
| 81560 | + /* The "rows less-than" for the rowid column must be greater than that |
| 81561 | + ** for the last sample in the p->a[] array. Otherwise, the samples would |
| 81562 | + ** be out of order. */ |
| 81563 | +#ifdef SQLITE_ENABLE_STAT4 |
| 81564 | + assert( p->nSample==0 |
| 81565 | + || pNew->anLt[p->nCol-1] > p->a[p->nSample-1].anLt[p->nCol-1] ); |
| 81566 | +#endif |
| 81567 | + |
| 81568 | + /* Insert the new sample */ |
| 81569 | + pSample = &p->a[p->nSample]; |
| 81570 | + sampleCopy(p, pSample, pNew); |
| 81571 | + p->nSample++; |
| 81572 | + |
| 81573 | + /* Zero the first nEqZero entries in the anEq[] array. */ |
| 81574 | + memset(pSample->anEq, 0, sizeof(tRowcnt)*nEqZero); |
| 81575 | + |
| 81576 | +#ifdef SQLITE_ENABLE_STAT4 |
| 81577 | + find_new_min: |
| 81578 | +#endif |
| 81579 | + if( p->nSample>=p->mxSample ){ |
| 81580 | + int iMin = -1; |
| 81581 | + for(i=0; i<p->mxSample; i++){ |
| 81582 | + if( p->a[i].isPSample ) continue; |
| 81583 | + if( iMin<0 || sampleIsBetter(p, &p->a[iMin], &p->a[i]) ){ |
| 81584 | + iMin = i; |
| 81585 | + } |
| 81586 | + } |
| 81587 | + assert( iMin>=0 ); |
| 80893 | 81588 | p->iMin = iMin; |
| 80894 | 81589 | } |
| 80895 | 81590 | } |
| 80896 | | -static const FuncDef stat3PushFuncdef = { |
| 80897 | | - 5, /* nArg */ |
| 80898 | | - SQLITE_UTF8, /* iPrefEnc */ |
| 80899 | | - 0, /* flags */ |
| 80900 | | - 0, /* pUserData */ |
| 80901 | | - 0, /* pNext */ |
| 80902 | | - stat3Push, /* xFunc */ |
| 80903 | | - 0, /* xStep */ |
| 80904 | | - 0, /* xFinalize */ |
| 80905 | | - "stat3_push", /* zName */ |
| 80906 | | - 0, /* pHash */ |
| 80907 | | - 0 /* pDestructor */ |
| 80908 | | -}; |
| 80909 | | - |
| 80910 | | -/* |
| 80911 | | -** Implementation of the stat3_get(P,N,...) SQL function. This routine is |
| 80912 | | -** used to query the results. Content is returned for the Nth sqlite_stat3 |
| 80913 | | -** row where N is between 0 and S-1 and S is the number of samples. The |
| 80914 | | -** value returned depends on the number of arguments. |
| 80915 | | -** |
| 80916 | | -** argc==2 result: rowid |
| 80917 | | -** argc==3 result: nEq |
| 80918 | | -** argc==4 result: nLt |
| 80919 | | -** argc==5 result: nDLt |
| 80920 | | -*/ |
| 80921 | | -static void stat3Get( |
| 81591 | +#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */ |
| 81592 | + |
| 81593 | +/* |
| 81594 | +** Field iChng of the index being scanned has changed. So at this point |
| 81595 | +** p->current contains a sample that reflects the previous row of the |
| 81596 | +** index. The value of anEq[iChng] and subsequent anEq[] elements are |
| 81597 | +** correct at this point. |
| 81598 | +*/ |
| 81599 | +static void samplePushPrevious(Stat4Accum *p, int iChng){ |
| 81600 | +#ifdef SQLITE_ENABLE_STAT4 |
| 81601 | + int i; |
| 81602 | + |
| 81603 | + /* Check if any samples from the aBest[] array should be pushed |
| 81604 | + ** into IndexSample.a[] at this point. */ |
| 81605 | + for(i=(p->nCol-2); i>=iChng; i--){ |
| 81606 | + Stat4Sample *pBest = &p->aBest[i]; |
| 81607 | + pBest->anEq[i] = p->current.anEq[i]; |
| 81608 | + if( p->nSample<p->mxSample || sampleIsBetter(p, pBest, &p->a[p->iMin]) ){ |
| 81609 | + sampleInsert(p, pBest, i); |
| 81610 | + } |
| 81611 | + } |
| 81612 | + |
| 81613 | + /* Update the anEq[] fields of any samples already collected. */ |
| 81614 | + for(i=p->nSample-1; i>=0; i--){ |
| 81615 | + int j; |
| 81616 | + for(j=iChng; j<p->nCol; j++){ |
| 81617 | + if( p->a[i].anEq[j]==0 ) p->a[i].anEq[j] = p->current.anEq[j]; |
| 81618 | + } |
| 81619 | + } |
| 81620 | +#endif |
| 81621 | + |
| 81622 | +#if defined(SQLITE_ENABLE_STAT3) && !defined(SQLITE_ENABLE_STAT4) |
| 81623 | + if( iChng==0 ){ |
| 81624 | + tRowcnt nLt = p->current.anLt[0]; |
| 81625 | + tRowcnt nEq = p->current.anEq[0]; |
| 81626 | + |
| 81627 | + /* Check if this is to be a periodic sample. If so, add it. */ |
| 81628 | + if( (nLt/p->nPSample)!=(nLt+nEq)/p->nPSample ){ |
| 81629 | + p->current.isPSample = 1; |
| 81630 | + sampleInsert(p, &p->current, 0); |
| 81631 | + p->current.isPSample = 0; |
| 81632 | + }else |
| 81633 | + |
| 81634 | + /* Or if it is a non-periodic sample. Add it in this case too. */ |
| 81635 | + if( p->nSample<p->mxSample |
| 81636 | + || sampleIsBetter(p, &p->current, &p->a[p->iMin]) |
| 81637 | + ){ |
| 81638 | + sampleInsert(p, &p->current, 0); |
| 81639 | + } |
| 81640 | + } |
| 81641 | +#endif |
| 81642 | +} |
| 81643 | + |
| 81644 | +/* |
| 81645 | +** Implementation of the stat_push SQL function: stat_push(P,R,C) |
| 81646 | +** Arguments: |
| 81647 | +** |
| 81648 | +** P Pointer to the Stat4Accum object created by stat_init() |
| 81649 | +** C Index of left-most column to differ from previous row |
| 81650 | +** R Rowid for the current row |
| 81651 | +** |
| 81652 | +** The SQL function always returns NULL. |
| 81653 | +** |
| 81654 | +** The R parameter is only used for STAT3 and STAT4. |
| 81655 | +*/ |
| 81656 | +static void statPush( |
| 81657 | + sqlite3_context *context, |
| 81658 | + int argc, |
| 81659 | + sqlite3_value **argv |
| 81660 | +){ |
| 81661 | + int i; |
| 81662 | + |
| 81663 | + /* The three function arguments */ |
| 81664 | + Stat4Accum *p = (Stat4Accum*)sqlite3_value_blob(argv[0]); |
| 81665 | + int iChng = sqlite3_value_int(argv[1]); |
| 81666 | + |
| 81667 | + assert( p->nCol>1 ); /* Includes rowid field */ |
| 81668 | + assert( iChng<p->nCol ); |
| 81669 | + |
| 81670 | + if( p->nRow==0 ){ |
| 81671 | + /* This is the first call to this function. Do initialization. */ |
| 81672 | + for(i=0; i<p->nCol; i++) p->current.anEq[i] = 1; |
| 81673 | + }else{ |
| 81674 | + /* Second and subsequent calls get processed here */ |
| 81675 | + samplePushPrevious(p, iChng); |
| 81676 | + |
| 81677 | + /* Update anDLt[], anLt[] and anEq[] to reflect the values that apply |
| 81678 | + ** to the current row of the index. */ |
| 81679 | + for(i=0; i<iChng; i++){ |
| 81680 | + p->current.anEq[i]++; |
| 81681 | + } |
| 81682 | + for(i=iChng; i<p->nCol; i++){ |
| 81683 | + p->current.anDLt[i]++; |
| 81684 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 81685 | + p->current.anLt[i] += p->current.anEq[i]; |
| 81686 | +#endif |
| 81687 | + p->current.anEq[i] = 1; |
| 81688 | + } |
| 81689 | + } |
| 81690 | + p->nRow++; |
| 81691 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 81692 | + p->current.iRowid = sqlite3_value_int64(argv[2]); |
| 81693 | + p->current.iHash = p->iPrn = p->iPrn*1103515245 + 12345; |
| 81694 | +#endif |
| 81695 | + |
| 81696 | +#ifdef SQLITE_ENABLE_STAT4 |
| 81697 | + { |
| 81698 | + tRowcnt nLt = p->current.anLt[p->nCol-1]; |
| 81699 | + |
| 81700 | + /* Check if this is to be a periodic sample. If so, add it. */ |
| 81701 | + if( (nLt/p->nPSample)!=(nLt+1)/p->nPSample ){ |
| 81702 | + p->current.isPSample = 1; |
| 81703 | + p->current.iCol = 0; |
| 81704 | + sampleInsert(p, &p->current, p->nCol-1); |
| 81705 | + p->current.isPSample = 0; |
| 81706 | + } |
| 81707 | + |
| 81708 | + /* Update the aBest[] array. */ |
| 81709 | + for(i=0; i<(p->nCol-1); i++){ |
| 81710 | + p->current.iCol = i; |
| 81711 | + if( i>=iChng || sampleIsBetterPost(p, &p->current, &p->aBest[i]) ){ |
| 81712 | + sampleCopy(p, &p->aBest[i], &p->current); |
| 81713 | + } |
| 81714 | + } |
| 81715 | + } |
| 81716 | +#endif |
| 81717 | +} |
| 81718 | +static const FuncDef statPushFuncdef = { |
| 81719 | + 2+IsStat34, /* nArg */ |
| 81720 | + SQLITE_UTF8, /* iPrefEnc */ |
| 81721 | + 0, /* flags */ |
| 81722 | + 0, /* pUserData */ |
| 81723 | + 0, /* pNext */ |
| 81724 | + statPush, /* xFunc */ |
| 81725 | + 0, /* xStep */ |
| 81726 | + 0, /* xFinalize */ |
| 81727 | + "stat_push", /* zName */ |
| 81728 | + 0, /* pHash */ |
| 81729 | + 0 /* pDestructor */ |
| 81730 | +}; |
| 81731 | + |
| 81732 | +#define STAT_GET_STAT1 0 /* "stat" column of stat1 table */ |
| 81733 | +#define STAT_GET_ROWID 1 /* "rowid" column of stat[34] entry */ |
| 81734 | +#define STAT_GET_NEQ 2 /* "neq" column of stat[34] entry */ |
| 81735 | +#define STAT_GET_NLT 3 /* "nlt" column of stat[34] entry */ |
| 81736 | +#define STAT_GET_NDLT 4 /* "ndlt" column of stat[34] entry */ |
| 81737 | + |
| 81738 | +/* |
| 81739 | +** Implementation of the stat_get(P,J) SQL function. This routine is |
| 81740 | +** used to query the results. Content is returned for parameter J |
| 81741 | +** which is one of the STAT_GET_xxxx values defined above. |
| 81742 | +** |
| 81743 | +** If neither STAT3 nor STAT4 are enabled, then J is always |
| 81744 | +** STAT_GET_STAT1 and is hence omitted and this routine becomes |
| 81745 | +** a one-parameter function, stat_get(P), that always returns the |
| 81746 | +** stat1 table entry information. |
| 81747 | +*/ |
| 81748 | +static void statGet( |
| 80922 | 81749 | sqlite3_context *context, |
| 80923 | 81750 | int argc, |
| 80924 | 81751 | sqlite3_value **argv |
| 80925 | 81752 | ){ |
| 80926 | | - int n = sqlite3_value_int(argv[1]); |
| 80927 | | - Stat3Accum *p = (Stat3Accum*)sqlite3_value_blob(argv[0]); |
| 80928 | | - |
| 80929 | | - assert( p!=0 ); |
| 80930 | | - if( p->nSample<=n ) return; |
| 80931 | | - switch( argc ){ |
| 80932 | | - case 2: sqlite3_result_int64(context, p->a[n].iRowid); break; |
| 80933 | | - case 3: sqlite3_result_int64(context, p->a[n].nEq); break; |
| 80934 | | - case 4: sqlite3_result_int64(context, p->a[n].nLt); break; |
| 80935 | | - default: sqlite3_result_int64(context, p->a[n].nDLt); break; |
| 80936 | | - } |
| 80937 | | -} |
| 80938 | | -static const FuncDef stat3GetFuncdef = { |
| 80939 | | - -1, /* nArg */ |
| 80940 | | - SQLITE_UTF8, /* iPrefEnc */ |
| 80941 | | - 0, /* flags */ |
| 80942 | | - 0, /* pUserData */ |
| 80943 | | - 0, /* pNext */ |
| 80944 | | - stat3Get, /* xFunc */ |
| 80945 | | - 0, /* xStep */ |
| 80946 | | - 0, /* xFinalize */ |
| 80947 | | - "stat3_get", /* zName */ |
| 80948 | | - 0, /* pHash */ |
| 80949 | | - 0 /* pDestructor */ |
| 80950 | | -}; |
| 80951 | | -#endif /* SQLITE_ENABLE_STAT3 */ |
| 80952 | | - |
| 80953 | | - |
| 80954 | | - |
| 81753 | + Stat4Accum *p = (Stat4Accum*)sqlite3_value_blob(argv[0]); |
| 81754 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 81755 | + /* STAT3 and STAT4 have a parameter on this routine. */ |
| 81756 | + int eCall = sqlite3_value_int(argv[1]); |
| 81757 | + assert( argc==2 ); |
| 81758 | + assert( eCall==STAT_GET_STAT1 || eCall==STAT_GET_NEQ |
| 81759 | + || eCall==STAT_GET_ROWID || eCall==STAT_GET_NLT |
| 81760 | + || eCall==STAT_GET_NDLT |
| 81761 | + ); |
| 81762 | + if( eCall==STAT_GET_STAT1 ) |
| 81763 | +#else |
| 81764 | + assert( argc==1 ); |
| 81765 | +#endif |
| 81766 | + { |
| 81767 | + /* Return the value to store in the "stat" column of the sqlite_stat1 |
| 81768 | + ** table for this index. |
| 81769 | + ** |
| 81770 | + ** The value is a string composed of a list of integers describing |
| 81771 | + ** the index. The first integer in the list is the total number of |
| 81772 | + ** entries in the index. There is one additional integer in the list |
| 81773 | + ** for each indexed column. This additional integer is an estimate of |
| 81774 | + ** the number of rows matched by a stabbing query on the index using |
| 81775 | + ** a key with the corresponding number of fields. In other words, |
| 81776 | + ** if the index is on columns (a,b) and the sqlite_stat1 value is |
| 81777 | + ** "100 10 2", then SQLite estimates that: |
| 81778 | + ** |
| 81779 | + ** * the index contains 100 rows, |
| 81780 | + ** * "WHERE a=?" matches 10 rows, and |
| 81781 | + ** * "WHERE a=? AND b=?" matches 2 rows. |
| 81782 | + ** |
| 81783 | + ** If D is the count of distinct values and K is the total number of |
| 81784 | + ** rows, then each estimate is computed as: |
| 81785 | + ** |
| 81786 | + ** I = (K+D-1)/D |
| 81787 | + */ |
| 81788 | + char *z; |
| 81789 | + int i; |
| 81790 | + |
| 81791 | + char *zRet = sqlite3MallocZero(p->nCol * 25); |
| 81792 | + if( zRet==0 ){ |
| 81793 | + sqlite3_result_error_nomem(context); |
| 81794 | + return; |
| 81795 | + } |
| 81796 | + |
| 81797 | + sqlite3_snprintf(24, zRet, "%lld", p->nRow); |
| 81798 | + z = zRet + sqlite3Strlen30(zRet); |
| 81799 | + for(i=0; i<(p->nCol-1); i++){ |
| 81800 | + i64 nDistinct = p->current.anDLt[i] + 1; |
| 81801 | + i64 iVal = (p->nRow + nDistinct - 1) / nDistinct; |
| 81802 | + sqlite3_snprintf(24, z, " %lld", iVal); |
| 81803 | + z += sqlite3Strlen30(z); |
| 81804 | + assert( p->current.anEq[i] ); |
| 81805 | + } |
| 81806 | + assert( z[0]=='\0' && z>zRet ); |
| 81807 | + |
| 81808 | + sqlite3_result_text(context, zRet, -1, sqlite3_free); |
| 81809 | + } |
| 81810 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 81811 | + else if( eCall==STAT_GET_ROWID ){ |
| 81812 | + if( p->iGet<0 ){ |
| 81813 | + samplePushPrevious(p, 0); |
| 81814 | + p->iGet = 0; |
| 81815 | + } |
| 81816 | + if( p->iGet<p->nSample ){ |
| 81817 | + sqlite3_result_int64(context, p->a[p->iGet].iRowid); |
| 81818 | + } |
| 81819 | + }else{ |
| 81820 | + tRowcnt *aCnt = 0; |
| 81821 | + |
| 81822 | + assert( p->iGet<p->nSample ); |
| 81823 | + switch( eCall ){ |
| 81824 | + case STAT_GET_NEQ: aCnt = p->a[p->iGet].anEq; break; |
| 81825 | + case STAT_GET_NLT: aCnt = p->a[p->iGet].anLt; break; |
| 81826 | + default: { |
| 81827 | + aCnt = p->a[p->iGet].anDLt; |
| 81828 | + p->iGet++; |
| 81829 | + break; |
| 81830 | + } |
| 81831 | + } |
| 81832 | + |
| 81833 | + if( IsStat3 ){ |
| 81834 | + sqlite3_result_int64(context, (i64)aCnt[0]); |
| 81835 | + }else{ |
| 81836 | + char *zRet = sqlite3MallocZero(p->nCol * 25); |
| 81837 | + if( zRet==0 ){ |
| 81838 | + sqlite3_result_error_nomem(context); |
| 81839 | + }else{ |
| 81840 | + int i; |
| 81841 | + char *z = zRet; |
| 81842 | + for(i=0; i<p->nCol; i++){ |
| 81843 | + sqlite3_snprintf(24, z, "%lld ", aCnt[i]); |
| 81844 | + z += sqlite3Strlen30(z); |
| 81845 | + } |
| 81846 | + assert( z[0]=='\0' && z>zRet ); |
| 81847 | + z[-1] = '\0'; |
| 81848 | + sqlite3_result_text(context, zRet, -1, sqlite3_free); |
| 81849 | + } |
| 81850 | + } |
| 81851 | + } |
| 81852 | +#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */ |
| 81853 | +} |
| 81854 | +static const FuncDef statGetFuncdef = { |
| 81855 | + 1+IsStat34, /* nArg */ |
| 81856 | + SQLITE_UTF8, /* iPrefEnc */ |
| 81857 | + 0, /* flags */ |
| 81858 | + 0, /* pUserData */ |
| 81859 | + 0, /* pNext */ |
| 81860 | + statGet, /* xFunc */ |
| 81861 | + 0, /* xStep */ |
| 81862 | + 0, /* xFinalize */ |
| 81863 | + "stat_get", /* zName */ |
| 81864 | + 0, /* pHash */ |
| 81865 | + 0 /* pDestructor */ |
| 81866 | +}; |
| 81867 | + |
| 81868 | +static void callStatGet(Vdbe *v, int regStat4, int iParam, int regOut){ |
| 81869 | + assert( regOut!=regStat4 && regOut!=regStat4+1 ); |
| 81870 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 81871 | + sqlite3VdbeAddOp2(v, OP_Integer, iParam, regStat4+1); |
| 81872 | +#else |
| 81873 | + assert( iParam==STAT_GET_STAT1 ); |
| 81874 | +#endif |
| 81875 | + sqlite3VdbeAddOp3(v, OP_Function, 0, regStat4, regOut); |
| 81876 | + sqlite3VdbeChangeP4(v, -1, (char*)&statGetFuncdef, P4_FUNCDEF); |
| 81877 | + sqlite3VdbeChangeP5(v, 1 + IsStat34); |
| 81878 | +} |
| 80955 | 81879 | |
| 80956 | 81880 | /* |
| 80957 | 81881 | ** Generate code to do an analysis of all indices associated with |
| 80958 | 81882 | ** a single table. |
| 80959 | 81883 | */ |
| | @@ -80960,46 +81884,35 @@ |
| 80960 | 81884 | static void analyzeOneTable( |
| 80961 | 81885 | Parse *pParse, /* Parser context */ |
| 80962 | 81886 | Table *pTab, /* Table whose indices are to be analyzed */ |
| 80963 | 81887 | Index *pOnlyIdx, /* If not NULL, only analyze this one index */ |
| 80964 | 81888 | int iStatCur, /* Index of VdbeCursor that writes the sqlite_stat1 table */ |
| 80965 | | - int iMem /* Available memory locations begin here */ |
| 81889 | + int iMem, /* Available memory locations begin here */ |
| 81890 | + int iTab /* Next available cursor */ |
| 80966 | 81891 | ){ |
| 80967 | 81892 | sqlite3 *db = pParse->db; /* Database handle */ |
| 80968 | 81893 | Index *pIdx; /* An index to being analyzed */ |
| 80969 | 81894 | int iIdxCur; /* Cursor open on index being analyzed */ |
| 81895 | + int iTabCur; /* Table cursor */ |
| 80970 | 81896 | Vdbe *v; /* The virtual machine being built up */ |
| 80971 | 81897 | int i; /* Loop counter */ |
| 80972 | | - int topOfLoop; /* The top of the loop */ |
| 80973 | | - int endOfLoop; /* The end of the loop */ |
| 80974 | 81898 | int jZeroRows = -1; /* Jump from here if number of rows is zero */ |
| 80975 | 81899 | int iDb; /* Index of database containing pTab */ |
| 80976 | 81900 | u8 needTableCnt = 1; /* True to count the table */ |
| 81901 | + int regNewRowid = iMem++; /* Rowid for the inserted record */ |
| 81902 | + int regStat4 = iMem++; /* Register to hold Stat4Accum object */ |
| 81903 | + int regChng = iMem++; /* Index of changed index field */ |
| 81904 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 81905 | + int regRowid = iMem++; /* Rowid argument passed to stat_push() */ |
| 81906 | +#endif |
| 81907 | + int regTemp = iMem++; /* Temporary use register */ |
| 80977 | 81908 | int regTabname = iMem++; /* Register containing table name */ |
| 80978 | 81909 | int regIdxname = iMem++; /* Register containing index name */ |
| 80979 | | - int regStat1 = iMem++; /* The stat column of sqlite_stat1 */ |
| 80980 | | -#ifdef SQLITE_ENABLE_STAT3 |
| 80981 | | - int regNumEq = regStat1; /* Number of instances. Same as regStat1 */ |
| 80982 | | - int regNumLt = iMem++; /* Number of keys less than regSample */ |
| 80983 | | - int regNumDLt = iMem++; /* Number of distinct keys less than regSample */ |
| 80984 | | - int regSample = iMem++; /* The next sample value */ |
| 80985 | | - int regRowid = regSample; /* Rowid of a sample */ |
| 80986 | | - int regAccum = iMem++; /* Register to hold Stat3Accum object */ |
| 80987 | | - int regLoop = iMem++; /* Loop counter */ |
| 80988 | | - int regCount = iMem++; /* Number of rows in the table or index */ |
| 80989 | | - int regTemp1 = iMem++; /* Intermediate register */ |
| 80990 | | - int regTemp2 = iMem++; /* Intermediate register */ |
| 80991 | | - int once = 1; /* One-time initialization */ |
| 80992 | | - int shortJump = 0; /* Instruction address */ |
| 80993 | | - int iTabCur = pParse->nTab++; /* Table cursor */ |
| 80994 | | -#endif |
| 80995 | | - int regCol = iMem++; /* Content of a column in analyzed table */ |
| 80996 | | - int regRec = iMem++; /* Register holding completed record */ |
| 80997 | | - int regTemp = iMem++; /* Temporary use register */ |
| 80998 | | - int regNewRowid = iMem++; /* Rowid for the inserted record */ |
| 80999 | | - |
| 81000 | | - |
| 81910 | + int regStat1 = iMem++; /* Value for the stat column of sqlite_stat1 */ |
| 81911 | + int regPrev = iMem; /* MUST BE LAST (see below) */ |
| 81912 | + |
| 81913 | + pParse->nMem = MAX(pParse->nMem, iMem); |
| 81001 | 81914 | v = sqlite3GetVdbe(pParse); |
| 81002 | 81915 | if( v==0 || NEVER(pTab==0) ){ |
| 81003 | 81916 | return; |
| 81004 | 81917 | } |
| 81005 | 81918 | if( pTab->tnum==0 ){ |
| | @@ -81019,217 +81932,230 @@ |
| 81019 | 81932 | db->aDb[iDb].zName ) ){ |
| 81020 | 81933 | return; |
| 81021 | 81934 | } |
| 81022 | 81935 | #endif |
| 81023 | 81936 | |
| 81024 | | - /* Establish a read-lock on the table at the shared-cache level. */ |
| 81937 | + /* Establish a read-lock on the table at the shared-cache level. |
| 81938 | + ** Open a read-only cursor on the table. Also allocate a cursor number |
| 81939 | + ** to use for scanning indexes (iIdxCur). No index cursor is opened at |
| 81940 | + ** this time though. */ |
| 81025 | 81941 | sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName); |
| 81026 | | - |
| 81027 | | - iIdxCur = pParse->nTab++; |
| 81942 | + iTabCur = iTab++; |
| 81943 | + iIdxCur = iTab++; |
| 81944 | + pParse->nTab = MAX(pParse->nTab, iTab); |
| 81945 | + sqlite3OpenTable(pParse, iTabCur, iDb, pTab, OP_OpenRead); |
| 81028 | 81946 | sqlite3VdbeAddOp4(v, OP_String8, 0, regTabname, 0, pTab->zName, 0); |
| 81947 | + |
| 81029 | 81948 | for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ |
| 81030 | | - int nCol; |
| 81031 | | - KeyInfo *pKey; |
| 81032 | | - int addrIfNot = 0; /* address of OP_IfNot */ |
| 81033 | | - int *aChngAddr; /* Array of jump instruction addresses */ |
| 81949 | + int nCol; /* Number of columns indexed by pIdx */ |
| 81950 | + KeyInfo *pKey; /* KeyInfo structure for pIdx */ |
| 81951 | + int *aGotoChng; /* Array of jump instruction addresses */ |
| 81952 | + int addrRewind; /* Address of "OP_Rewind iIdxCur" */ |
| 81953 | + int addrGotoChng0; /* Address of "Goto addr_chng_0" */ |
| 81954 | + int addrNextRow; /* Address of "next_row:" */ |
| 81034 | 81955 | |
| 81035 | 81956 | if( pOnlyIdx && pOnlyIdx!=pIdx ) continue; |
| 81036 | 81957 | if( pIdx->pPartIdxWhere==0 ) needTableCnt = 0; |
| 81037 | 81958 | VdbeNoopComment((v, "Begin analysis of %s", pIdx->zName)); |
| 81038 | 81959 | nCol = pIdx->nColumn; |
| 81039 | | - aChngAddr = sqlite3DbMallocRaw(db, sizeof(int)*nCol); |
| 81040 | | - if( aChngAddr==0 ) continue; |
| 81960 | + aGotoChng = sqlite3DbMallocRaw(db, sizeof(int)*(nCol+1)); |
| 81961 | + if( aGotoChng==0 ) continue; |
| 81041 | 81962 | pKey = sqlite3IndexKeyinfo(pParse, pIdx); |
| 81042 | | - if( iMem+1+(nCol*2)>pParse->nMem ){ |
| 81043 | | - pParse->nMem = iMem+1+(nCol*2); |
| 81044 | | - } |
| 81045 | | - |
| 81046 | | - /* Open a cursor to the index to be analyzed. */ |
| 81047 | | - assert( iDb==sqlite3SchemaToIndex(db, pIdx->pSchema) ); |
| 81048 | | - sqlite3VdbeAddOp4(v, OP_OpenRead, iIdxCur, pIdx->tnum, iDb, |
| 81049 | | - (char *)pKey, P4_KEYINFO_HANDOFF); |
| 81050 | | - VdbeComment((v, "%s", pIdx->zName)); |
| 81051 | 81963 | |
| 81052 | 81964 | /* Populate the register containing the index name. */ |
| 81053 | 81965 | sqlite3VdbeAddOp4(v, OP_String8, 0, regIdxname, 0, pIdx->zName, 0); |
| 81054 | 81966 | |
| 81055 | | -#ifdef SQLITE_ENABLE_STAT3 |
| 81056 | | - if( once ){ |
| 81057 | | - once = 0; |
| 81058 | | - sqlite3OpenTable(pParse, iTabCur, iDb, pTab, OP_OpenRead); |
| 81059 | | - } |
| 81060 | | - sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regCount); |
| 81061 | | - sqlite3VdbeAddOp2(v, OP_Integer, SQLITE_STAT3_SAMPLES, regTemp1); |
| 81062 | | - sqlite3VdbeAddOp2(v, OP_Integer, 0, regNumEq); |
| 81063 | | - sqlite3VdbeAddOp2(v, OP_Integer, 0, regNumLt); |
| 81064 | | - sqlite3VdbeAddOp2(v, OP_Integer, -1, regNumDLt); |
| 81065 | | - sqlite3VdbeAddOp3(v, OP_Null, 0, regSample, regAccum); |
| 81066 | | - sqlite3VdbeAddOp4(v, OP_Function, 1, regCount, regAccum, |
| 81067 | | - (char*)&stat3InitFuncdef, P4_FUNCDEF); |
| 81068 | | - sqlite3VdbeChangeP5(v, 2); |
| 81069 | | -#endif /* SQLITE_ENABLE_STAT3 */ |
| 81070 | | - |
| 81071 | | - /* The block of memory cells initialized here is used as follows. |
| 81072 | | - ** |
| 81073 | | - ** iMem: |
| 81074 | | - ** The total number of rows in the table. |
| 81075 | | - ** |
| 81076 | | - ** iMem+1 .. iMem+nCol: |
| 81077 | | - ** Number of distinct entries in index considering the |
| 81078 | | - ** left-most N columns only, where N is between 1 and nCol, |
| 81079 | | - ** inclusive. |
| 81080 | | - ** |
| 81081 | | - ** iMem+nCol+1 .. Mem+2*nCol: |
| 81082 | | - ** Previous value of indexed columns, from left to right. |
| 81083 | | - ** |
| 81084 | | - ** Cells iMem through iMem+nCol are initialized to 0. The others are |
| 81085 | | - ** initialized to contain an SQL NULL. |
| 81086 | | - */ |
| 81087 | | - for(i=0; i<=nCol; i++){ |
| 81088 | | - sqlite3VdbeAddOp2(v, OP_Integer, 0, iMem+i); |
| 81089 | | - } |
| 81090 | | - for(i=0; i<nCol; i++){ |
| 81091 | | - sqlite3VdbeAddOp2(v, OP_Null, 0, iMem+nCol+i+1); |
| 81092 | | - } |
| 81093 | | - |
| 81094 | | - /* Start the analysis loop. This loop runs through all the entries in |
| 81095 | | - ** the index b-tree. */ |
| 81096 | | - endOfLoop = sqlite3VdbeMakeLabel(v); |
| 81097 | | - sqlite3VdbeAddOp2(v, OP_Rewind, iIdxCur, endOfLoop); |
| 81098 | | - topOfLoop = sqlite3VdbeCurrentAddr(v); |
| 81099 | | - sqlite3VdbeAddOp2(v, OP_AddImm, iMem, 1); /* Increment row counter */ |
| 81100 | | - |
| 81101 | | - for(i=0; i<nCol; i++){ |
| 81102 | | - CollSeq *pColl; |
| 81103 | | - sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, regCol); |
| 81104 | | - if( i==0 ){ |
| 81105 | | - /* Always record the very first row */ |
| 81106 | | - addrIfNot = sqlite3VdbeAddOp1(v, OP_IfNot, iMem+1); |
| 81107 | | - } |
| 81108 | | - assert( pIdx->azColl!=0 ); |
| 81109 | | - assert( pIdx->azColl[i]!=0 ); |
| 81110 | | - pColl = sqlite3LocateCollSeq(pParse, pIdx->azColl[i]); |
| 81111 | | - aChngAddr[i] = sqlite3VdbeAddOp4(v, OP_Ne, regCol, 0, iMem+nCol+i+1, |
| 81112 | | - (char*)pColl, P4_COLLSEQ); |
| 81967 | + /* |
| 81968 | + ** Pseudo-code for loop that calls stat_push(): |
| 81969 | + ** |
| 81970 | + ** Rewind csr |
| 81971 | + ** if eof(csr) goto end_of_scan; |
| 81972 | + ** regChng = 0 |
| 81973 | + ** goto chng_addr_0; |
| 81974 | + ** |
| 81975 | + ** next_row: |
| 81976 | + ** regChng = 0 |
| 81977 | + ** if( idx(0) != regPrev(0) ) goto chng_addr_0 |
| 81978 | + ** regChng = 1 |
| 81979 | + ** if( idx(1) != regPrev(1) ) goto chng_addr_1 |
| 81980 | + ** ... |
| 81981 | + ** regChng = N |
| 81982 | + ** goto chng_addr_N |
| 81983 | + ** |
| 81984 | + ** chng_addr_0: |
| 81985 | + ** regPrev(0) = idx(0) |
| 81986 | + ** chng_addr_1: |
| 81987 | + ** regPrev(1) = idx(1) |
| 81988 | + ** ... |
| 81989 | + ** |
| 81990 | + ** chng_addr_N: |
| 81991 | + ** regRowid = idx(rowid) |
| 81992 | + ** stat_push(P, regChng, regRowid) |
| 81993 | + ** Next csr |
| 81994 | + ** if !eof(csr) goto next_row; |
| 81995 | + ** |
| 81996 | + ** end_of_scan: |
| 81997 | + */ |
| 81998 | + |
| 81999 | + /* Make sure there are enough memory cells allocated to accommodate |
| 82000 | + ** the regPrev array and a trailing rowid (the rowid slot is required |
| 82001 | + ** when building a record to insert into the sample column of |
| 82002 | + ** the sqlite_stat4 table. */ |
| 82003 | + pParse->nMem = MAX(pParse->nMem, regPrev+nCol); |
| 82004 | + |
| 82005 | + /* Open a read-only cursor on the index being analyzed. */ |
| 82006 | + assert( iDb==sqlite3SchemaToIndex(db, pIdx->pSchema) ); |
| 82007 | + sqlite3VdbeAddOp3(v, OP_OpenRead, iIdxCur, pIdx->tnum, iDb); |
| 82008 | + sqlite3VdbeChangeP4(v, -1, (char*)pKey, P4_KEYINFO_HANDOFF); |
| 82009 | + VdbeComment((v, "%s", pIdx->zName)); |
| 82010 | + |
| 82011 | + /* Invoke the stat_init() function. The arguments are: |
| 82012 | + ** |
| 82013 | + ** (1) the number of columns in the index including the rowid, |
| 82014 | + ** (2) the number of rows in the index, |
| 82015 | + ** |
| 82016 | + ** The second argument is only used for STAT3 and STAT4 |
| 82017 | + */ |
| 82018 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 82019 | + sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regStat4+2); |
| 82020 | +#endif |
| 82021 | + sqlite3VdbeAddOp2(v, OP_Integer, nCol+1, regStat4+1); |
| 82022 | + sqlite3VdbeAddOp3(v, OP_Function, 0, regStat4+1, regStat4); |
| 82023 | + sqlite3VdbeChangeP4(v, -1, (char*)&statInitFuncdef, P4_FUNCDEF); |
| 82024 | + sqlite3VdbeChangeP5(v, 1+IsStat34); |
| 82025 | + |
| 82026 | + /* Implementation of the following: |
| 82027 | + ** |
| 82028 | + ** Rewind csr |
| 82029 | + ** if eof(csr) goto end_of_scan; |
| 82030 | + ** regChng = 0 |
| 82031 | + ** goto next_push_0; |
| 82032 | + ** |
| 82033 | + */ |
| 82034 | + addrRewind = sqlite3VdbeAddOp1(v, OP_Rewind, iIdxCur); |
| 82035 | + sqlite3VdbeAddOp2(v, OP_Integer, 0, regChng); |
| 82036 | + addrGotoChng0 = sqlite3VdbeAddOp0(v, OP_Goto); |
| 82037 | + |
| 82038 | + /* |
| 82039 | + ** next_row: |
| 82040 | + ** regChng = 0 |
| 82041 | + ** if( idx(0) != regPrev(0) ) goto chng_addr_0 |
| 82042 | + ** regChng = 1 |
| 82043 | + ** if( idx(1) != regPrev(1) ) goto chng_addr_1 |
| 82044 | + ** ... |
| 82045 | + ** regChng = N |
| 82046 | + ** goto chng_addr_N |
| 82047 | + */ |
| 82048 | + addrNextRow = sqlite3VdbeCurrentAddr(v); |
| 82049 | + for(i=0; i<nCol; i++){ |
| 82050 | + char *pColl = (char*)sqlite3LocateCollSeq(pParse, pIdx->azColl[i]); |
| 82051 | + sqlite3VdbeAddOp2(v, OP_Integer, i, regChng); |
| 82052 | + sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, regTemp); |
| 82053 | + aGotoChng[i] = |
| 82054 | + sqlite3VdbeAddOp4(v, OP_Ne, regTemp, 0, regPrev+i, pColl, P4_COLLSEQ); |
| 81113 | 82055 | sqlite3VdbeChangeP5(v, SQLITE_NULLEQ); |
| 81114 | | - VdbeComment((v, "jump if column %d changed", i)); |
| 81115 | | -#ifdef SQLITE_ENABLE_STAT3 |
| 81116 | | - if( i==0 ){ |
| 81117 | | - sqlite3VdbeAddOp2(v, OP_AddImm, regNumEq, 1); |
| 81118 | | - VdbeComment((v, "incr repeat count")); |
| 81119 | | - } |
| 81120 | | -#endif |
| 81121 | | - } |
| 81122 | | - sqlite3VdbeAddOp2(v, OP_Goto, 0, endOfLoop); |
| 81123 | | - for(i=0; i<nCol; i++){ |
| 81124 | | - sqlite3VdbeJumpHere(v, aChngAddr[i]); /* Set jump dest for the OP_Ne */ |
| 81125 | | - if( i==0 ){ |
| 81126 | | - sqlite3VdbeJumpHere(v, addrIfNot); /* Jump dest for OP_IfNot */ |
| 81127 | | -#ifdef SQLITE_ENABLE_STAT3 |
| 81128 | | - sqlite3VdbeAddOp4(v, OP_Function, 1, regNumEq, regTemp2, |
| 81129 | | - (char*)&stat3PushFuncdef, P4_FUNCDEF); |
| 81130 | | - sqlite3VdbeChangeP5(v, 5); |
| 81131 | | - sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, pIdx->nColumn, regRowid); |
| 81132 | | - sqlite3VdbeAddOp3(v, OP_Add, regNumEq, regNumLt, regNumLt); |
| 81133 | | - sqlite3VdbeAddOp2(v, OP_AddImm, regNumDLt, 1); |
| 81134 | | - sqlite3VdbeAddOp2(v, OP_Integer, 1, regNumEq); |
| 81135 | | -#endif |
| 81136 | | - } |
| 81137 | | - sqlite3VdbeAddOp2(v, OP_AddImm, iMem+i+1, 1); |
| 81138 | | - sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, iMem+nCol+i+1); |
| 81139 | | - } |
| 81140 | | - sqlite3DbFree(db, aChngAddr); |
| 81141 | | - |
| 81142 | | - /* Always jump here after updating the iMem+1...iMem+1+nCol counters */ |
| 81143 | | - sqlite3VdbeResolveLabel(v, endOfLoop); |
| 81144 | | - |
| 81145 | | - sqlite3VdbeAddOp2(v, OP_Next, iIdxCur, topOfLoop); |
| 81146 | | - sqlite3VdbeAddOp1(v, OP_Close, iIdxCur); |
| 81147 | | -#ifdef SQLITE_ENABLE_STAT3 |
| 81148 | | - sqlite3VdbeAddOp4(v, OP_Function, 1, regNumEq, regTemp2, |
| 81149 | | - (char*)&stat3PushFuncdef, P4_FUNCDEF); |
| 81150 | | - sqlite3VdbeChangeP5(v, 5); |
| 81151 | | - sqlite3VdbeAddOp2(v, OP_Integer, -1, regLoop); |
| 81152 | | - shortJump = |
| 81153 | | - sqlite3VdbeAddOp2(v, OP_AddImm, regLoop, 1); |
| 81154 | | - sqlite3VdbeAddOp4(v, OP_Function, 1, regAccum, regTemp1, |
| 81155 | | - (char*)&stat3GetFuncdef, P4_FUNCDEF); |
| 81156 | | - sqlite3VdbeChangeP5(v, 2); |
| 81157 | | - sqlite3VdbeAddOp1(v, OP_IsNull, regTemp1); |
| 81158 | | - sqlite3VdbeAddOp3(v, OP_NotExists, iTabCur, shortJump, regTemp1); |
| 81159 | | - sqlite3VdbeAddOp3(v, OP_Column, iTabCur, pIdx->aiColumn[0], regSample); |
| 81160 | | - sqlite3ColumnDefault(v, pTab, pIdx->aiColumn[0], regSample); |
| 81161 | | - sqlite3VdbeAddOp4(v, OP_Function, 1, regAccum, regNumEq, |
| 81162 | | - (char*)&stat3GetFuncdef, P4_FUNCDEF); |
| 81163 | | - sqlite3VdbeChangeP5(v, 3); |
| 81164 | | - sqlite3VdbeAddOp4(v, OP_Function, 1, regAccum, regNumLt, |
| 81165 | | - (char*)&stat3GetFuncdef, P4_FUNCDEF); |
| 81166 | | - sqlite3VdbeChangeP5(v, 4); |
| 81167 | | - sqlite3VdbeAddOp4(v, OP_Function, 1, regAccum, regNumDLt, |
| 81168 | | - (char*)&stat3GetFuncdef, P4_FUNCDEF); |
| 81169 | | - sqlite3VdbeChangeP5(v, 5); |
| 81170 | | - sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 6, regRec, "bbbbbb", 0); |
| 81171 | | - sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur+1, regNewRowid); |
| 81172 | | - sqlite3VdbeAddOp3(v, OP_Insert, iStatCur+1, regRec, regNewRowid); |
| 81173 | | - sqlite3VdbeAddOp2(v, OP_Goto, 0, shortJump); |
| 81174 | | - sqlite3VdbeJumpHere(v, shortJump+2); |
| 81175 | | -#endif |
| 81176 | | - |
| 81177 | | - /* Store the results in sqlite_stat1. |
| 81178 | | - ** |
| 81179 | | - ** The result is a single row of the sqlite_stat1 table. The first |
| 81180 | | - ** two columns are the names of the table and index. The third column |
| 81181 | | - ** is a string composed of a list of integer statistics about the |
| 81182 | | - ** index. The first integer in the list is the total number of entries |
| 81183 | | - ** in the index. There is one additional integer in the list for each |
| 81184 | | - ** column of the table. This additional integer is a guess of how many |
| 81185 | | - ** rows of the table the index will select. If D is the count of distinct |
| 81186 | | - ** values and K is the total number of rows, then the integer is computed |
| 81187 | | - ** as: |
| 81188 | | - ** |
| 81189 | | - ** I = (K+D-1)/D |
| 81190 | | - ** |
| 81191 | | - ** If K==0 then no entry is made into the sqlite_stat1 table. |
| 81192 | | - ** If K>0 then it is always the case the D>0 so division by zero |
| 81193 | | - ** is never possible. |
| 81194 | | - */ |
| 81195 | | - sqlite3VdbeAddOp2(v, OP_SCopy, iMem, regStat1); |
| 81196 | | - jZeroRows = sqlite3VdbeAddOp1(v, OP_IfNot, iMem); |
| 81197 | | - for(i=0; i<nCol; i++){ |
| 81198 | | - sqlite3VdbeAddOp4(v, OP_String8, 0, regTemp, 0, " ", 0); |
| 81199 | | - sqlite3VdbeAddOp3(v, OP_Concat, regTemp, regStat1, regStat1); |
| 81200 | | - sqlite3VdbeAddOp3(v, OP_Add, iMem, iMem+i+1, regTemp); |
| 81201 | | - sqlite3VdbeAddOp2(v, OP_AddImm, regTemp, -1); |
| 81202 | | - sqlite3VdbeAddOp3(v, OP_Divide, iMem+i+1, regTemp, regTemp); |
| 81203 | | - sqlite3VdbeAddOp1(v, OP_ToInt, regTemp); |
| 81204 | | - sqlite3VdbeAddOp3(v, OP_Concat, regTemp, regStat1, regStat1); |
| 81205 | | - } |
| 81206 | | - if( pIdx->pPartIdxWhere!=0 ) sqlite3VdbeJumpHere(v, jZeroRows); |
| 81207 | | - sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regRec, "aaa", 0); |
| 81208 | | - sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid); |
| 81209 | | - sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regRec, regNewRowid); |
| 81210 | | - sqlite3VdbeChangeP5(v, OPFLAG_APPEND); |
| 81211 | | - if( pIdx->pPartIdxWhere==0 ) sqlite3VdbeJumpHere(v, jZeroRows); |
| 81212 | | - } |
| 82056 | + } |
| 82057 | + sqlite3VdbeAddOp2(v, OP_Integer, nCol, regChng); |
| 82058 | + aGotoChng[nCol] = sqlite3VdbeAddOp0(v, OP_Goto); |
| 82059 | + |
| 82060 | + /* |
| 82061 | + ** chng_addr_0: |
| 82062 | + ** regPrev(0) = idx(0) |
| 82063 | + ** chng_addr_1: |
| 82064 | + ** regPrev(1) = idx(1) |
| 82065 | + ** ... |
| 82066 | + */ |
| 82067 | + sqlite3VdbeJumpHere(v, addrGotoChng0); |
| 82068 | + for(i=0; i<nCol; i++){ |
| 82069 | + sqlite3VdbeJumpHere(v, aGotoChng[i]); |
| 82070 | + sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, regPrev+i); |
| 82071 | + } |
| 82072 | + |
| 82073 | + /* |
| 82074 | + ** chng_addr_N: |
| 82075 | + ** regRowid = idx(rowid) // STAT34 only |
| 82076 | + ** stat_push(P, regChng, regRowid) // 3rd parameter STAT34 only |
| 82077 | + ** Next csr |
| 82078 | + ** if !eof(csr) goto next_row; |
| 82079 | + */ |
| 82080 | + sqlite3VdbeJumpHere(v, aGotoChng[nCol]); |
| 82081 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 82082 | + sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur, regRowid); |
| 82083 | + assert( regRowid==(regStat4+2) ); |
| 82084 | +#endif |
| 82085 | + assert( regChng==(regStat4+1) ); |
| 82086 | + sqlite3VdbeAddOp3(v, OP_Function, 1, regStat4, regTemp); |
| 82087 | + sqlite3VdbeChangeP4(v, -1, (char*)&statPushFuncdef, P4_FUNCDEF); |
| 82088 | + sqlite3VdbeChangeP5(v, 2+IsStat34); |
| 82089 | + sqlite3VdbeAddOp2(v, OP_Next, iIdxCur, addrNextRow); |
| 82090 | + |
| 82091 | + /* Add the entry to the stat1 table. */ |
| 82092 | + callStatGet(v, regStat4, STAT_GET_STAT1, regStat1); |
| 82093 | + sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regTemp, "aaa", 0); |
| 82094 | + sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid); |
| 82095 | + sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regTemp, regNewRowid); |
| 82096 | + sqlite3VdbeChangeP5(v, OPFLAG_APPEND); |
| 82097 | + |
| 82098 | + /* Add the entries to the stat3 or stat4 table. */ |
| 82099 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 82100 | + { |
| 82101 | + int regEq = regStat1; |
| 82102 | + int regLt = regStat1+1; |
| 82103 | + int regDLt = regStat1+2; |
| 82104 | + int regSample = regStat1+3; |
| 82105 | + int regCol = regStat1+4; |
| 82106 | + int regSampleRowid = regCol + nCol; |
| 82107 | + int addrNext; |
| 82108 | + int addrIsNull; |
| 82109 | + |
| 82110 | + pParse->nMem = MAX(pParse->nMem, regCol+nCol+1); |
| 82111 | + |
| 82112 | + addrNext = sqlite3VdbeCurrentAddr(v); |
| 82113 | + callStatGet(v, regStat4, STAT_GET_ROWID, regSampleRowid); |
| 82114 | + addrIsNull = sqlite3VdbeAddOp1(v, OP_IsNull, regSampleRowid); |
| 82115 | + callStatGet(v, regStat4, STAT_GET_NEQ, regEq); |
| 82116 | + callStatGet(v, regStat4, STAT_GET_NLT, regLt); |
| 82117 | + callStatGet(v, regStat4, STAT_GET_NDLT, regDLt); |
| 82118 | + sqlite3VdbeAddOp3(v, OP_NotExists, iTabCur, addrNext, regSampleRowid); |
| 82119 | +#ifdef SQLITE_ENABLE_STAT3 |
| 82120 | + sqlite3ExprCodeGetColumnOfTable(v, pTab, iTabCur, |
| 82121 | + pIdx->aiColumn[0], regSample); |
| 82122 | +#else |
| 82123 | + for(i=0; i<nCol; i++){ |
| 82124 | + int iCol = pIdx->aiColumn[i]; |
| 82125 | + sqlite3ExprCodeGetColumnOfTable(v, pTab, iTabCur, iCol, regCol+i); |
| 82126 | + } |
| 82127 | + sqlite3VdbeAddOp3(v, OP_MakeRecord, regCol, nCol+1, regSample); |
| 82128 | +#endif |
| 82129 | + sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 6, regTemp, "bbbbbb", 0); |
| 82130 | + sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur+1, regNewRowid); |
| 82131 | + sqlite3VdbeAddOp3(v, OP_Insert, iStatCur+1, regTemp, regNewRowid); |
| 82132 | + sqlite3VdbeAddOp2(v, OP_Goto, 0, addrNext); |
| 82133 | + sqlite3VdbeJumpHere(v, addrIsNull); |
| 82134 | + } |
| 82135 | +#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */ |
| 82136 | + |
| 82137 | + /* End of analysis */ |
| 82138 | + sqlite3VdbeJumpHere(v, addrRewind); |
| 82139 | + sqlite3DbFree(db, aGotoChng); |
| 82140 | + } |
| 82141 | + |
| 81213 | 82142 | |
| 81214 | 82143 | /* Create a single sqlite_stat1 entry containing NULL as the index |
| 81215 | 82144 | ** name and the row count as the content. |
| 81216 | 82145 | */ |
| 81217 | 82146 | if( pOnlyIdx==0 && needTableCnt ){ |
| 81218 | | - sqlite3VdbeAddOp3(v, OP_OpenRead, iIdxCur, pTab->tnum, iDb); |
| 81219 | 82147 | VdbeComment((v, "%s", pTab->zName)); |
| 81220 | | - sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regStat1); |
| 81221 | | - sqlite3VdbeAddOp1(v, OP_Close, iIdxCur); |
| 82148 | + sqlite3VdbeAddOp2(v, OP_Count, iTabCur, regStat1); |
| 81222 | 82149 | jZeroRows = sqlite3VdbeAddOp1(v, OP_IfNot, regStat1); |
| 81223 | 82150 | sqlite3VdbeAddOp2(v, OP_Null, 0, regIdxname); |
| 81224 | | - sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regRec, "aaa", 0); |
| 82151 | + sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regTemp, "aaa", 0); |
| 81225 | 82152 | sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid); |
| 81226 | | - sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regRec, regNewRowid); |
| 82153 | + sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regTemp, regNewRowid); |
| 81227 | 82154 | sqlite3VdbeChangeP5(v, OPFLAG_APPEND); |
| 81228 | 82155 | sqlite3VdbeJumpHere(v, jZeroRows); |
| 81229 | 82156 | } |
| 81230 | | - if( pParse->nMem<regRec ) pParse->nMem = regRec; |
| 81231 | 82157 | } |
| 81232 | 82158 | |
| 81233 | 82159 | |
| 81234 | 82160 | /* |
| 81235 | 82161 | ** Generate code that will cause the most recent index analysis to |
| | @@ -81249,20 +82175,22 @@ |
| 81249 | 82175 | sqlite3 *db = pParse->db; |
| 81250 | 82176 | Schema *pSchema = db->aDb[iDb].pSchema; /* Schema of database iDb */ |
| 81251 | 82177 | HashElem *k; |
| 81252 | 82178 | int iStatCur; |
| 81253 | 82179 | int iMem; |
| 82180 | + int iTab; |
| 81254 | 82181 | |
| 81255 | 82182 | sqlite3BeginWriteOperation(pParse, 0, iDb); |
| 81256 | 82183 | iStatCur = pParse->nTab; |
| 81257 | 82184 | pParse->nTab += 3; |
| 81258 | 82185 | openStatTable(pParse, iDb, iStatCur, 0, 0); |
| 81259 | 82186 | iMem = pParse->nMem+1; |
| 82187 | + iTab = pParse->nTab; |
| 81260 | 82188 | assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); |
| 81261 | 82189 | for(k=sqliteHashFirst(&pSchema->tblHash); k; k=sqliteHashNext(k)){ |
| 81262 | 82190 | Table *pTab = (Table*)sqliteHashData(k); |
| 81263 | | - analyzeOneTable(pParse, pTab, 0, iStatCur, iMem); |
| 82191 | + analyzeOneTable(pParse, pTab, 0, iStatCur, iMem, iTab); |
| 81264 | 82192 | } |
| 81265 | 82193 | loadAnalysis(pParse, iDb); |
| 81266 | 82194 | } |
| 81267 | 82195 | |
| 81268 | 82196 | /* |
| | @@ -81283,11 +82211,11 @@ |
| 81283 | 82211 | if( pOnlyIdx ){ |
| 81284 | 82212 | openStatTable(pParse, iDb, iStatCur, pOnlyIdx->zName, "idx"); |
| 81285 | 82213 | }else{ |
| 81286 | 82214 | openStatTable(pParse, iDb, iStatCur, pTab->zName, "tbl"); |
| 81287 | 82215 | } |
| 81288 | | - analyzeOneTable(pParse, pTab, pOnlyIdx, iStatCur, pParse->nMem+1); |
| 82216 | + analyzeOneTable(pParse, pTab, pOnlyIdx, iStatCur,pParse->nMem+1,pParse->nTab); |
| 81289 | 82217 | loadAnalysis(pParse, iDb); |
| 81290 | 82218 | } |
| 81291 | 82219 | |
| 81292 | 82220 | /* |
| 81293 | 82221 | ** Generate code for the ANALYZE command. The parser calls this routine |
| | @@ -81365,10 +82293,47 @@ |
| 81365 | 82293 | typedef struct analysisInfo analysisInfo; |
| 81366 | 82294 | struct analysisInfo { |
| 81367 | 82295 | sqlite3 *db; |
| 81368 | 82296 | const char *zDatabase; |
| 81369 | 82297 | }; |
| 82298 | + |
| 82299 | +/* |
| 82300 | +** The first argument points to a nul-terminated string containing a |
| 82301 | +** list of space separated integers. Read the first nOut of these into |
| 82302 | +** the array aOut[]. |
| 82303 | +*/ |
| 82304 | +static void decodeIntArray( |
| 82305 | + char *zIntArray, |
| 82306 | + int nOut, |
| 82307 | + tRowcnt *aOut, |
| 82308 | + int *pbUnordered |
| 82309 | +){ |
| 82310 | + char *z = zIntArray; |
| 82311 | + int c; |
| 82312 | + int i; |
| 82313 | + tRowcnt v; |
| 82314 | + |
| 82315 | + assert( pbUnordered==0 || *pbUnordered==0 ); |
| 82316 | + |
| 82317 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 82318 | + if( z==0 ) z = ""; |
| 82319 | +#else |
| 82320 | + if( NEVER(z==0) ) z = ""; |
| 82321 | +#endif |
| 82322 | + for(i=0; *z && i<nOut; i++){ |
| 82323 | + v = 0; |
| 82324 | + while( (c=z[0])>='0' && c<='9' ){ |
| 82325 | + v = v*10 + c - '0'; |
| 82326 | + z++; |
| 82327 | + } |
| 82328 | + aOut[i] = v; |
| 82329 | + if( *z==' ' ) z++; |
| 82330 | + } |
| 82331 | + if( pbUnordered && strcmp(z, "unordered")==0 ){ |
| 82332 | + *pbUnordered = 1; |
| 82333 | + } |
| 82334 | +} |
| 81370 | 82335 | |
| 81371 | 82336 | /* |
| 81372 | 82337 | ** This callback is invoked once for each index when reading the |
| 81373 | 82338 | ** sqlite_stat1 table. |
| 81374 | 82339 | ** |
| | @@ -81381,12 +82346,10 @@ |
| 81381 | 82346 | */ |
| 81382 | 82347 | static int analysisLoader(void *pData, int argc, char **argv, char **NotUsed){ |
| 81383 | 82348 | analysisInfo *pInfo = (analysisInfo*)pData; |
| 81384 | 82349 | Index *pIndex; |
| 81385 | 82350 | Table *pTable; |
| 81386 | | - int i, c, n; |
| 81387 | | - tRowcnt v; |
| 81388 | 82351 | const char *z; |
| 81389 | 82352 | |
| 81390 | 82353 | assert( argc==3 ); |
| 81391 | 82354 | UNUSED_PARAMETER2(NotUsed, argc); |
| 81392 | 82355 | |
| | @@ -81400,45 +82363,35 @@ |
| 81400 | 82363 | if( argv[1] ){ |
| 81401 | 82364 | pIndex = sqlite3FindIndex(pInfo->db, argv[1], pInfo->zDatabase); |
| 81402 | 82365 | }else{ |
| 81403 | 82366 | pIndex = 0; |
| 81404 | 82367 | } |
| 81405 | | - n = pIndex ? pIndex->nColumn : 0; |
| 81406 | 82368 | z = argv[2]; |
| 81407 | | - for(i=0; *z && i<=n; i++){ |
| 81408 | | - v = 0; |
| 81409 | | - while( (c=z[0])>='0' && c<='9' ){ |
| 81410 | | - v = v*10 + c - '0'; |
| 81411 | | - z++; |
| 81412 | | - } |
| 81413 | | - if( i==0 && (pIndex==0 || pIndex->pPartIdxWhere==0) ){ |
| 81414 | | - if( v>0 ) pTable->nRowEst = v; |
| 81415 | | - if( pIndex==0 ) break; |
| 81416 | | - } |
| 81417 | | - pIndex->aiRowEst[i] = v; |
| 81418 | | - if( *z==' ' ) z++; |
| 81419 | | - if( strcmp(z, "unordered")==0 ){ |
| 81420 | | - pIndex->bUnordered = 1; |
| 81421 | | - break; |
| 81422 | | - } |
| 81423 | | - } |
| 82369 | + |
| 82370 | + if( pIndex ){ |
| 82371 | + int bUnordered = 0; |
| 82372 | + decodeIntArray((char*)z, pIndex->nColumn+1, pIndex->aiRowEst,&bUnordered); |
| 82373 | + if( pIndex->pPartIdxWhere==0 ) pTable->nRowEst = pIndex->aiRowEst[0]; |
| 82374 | + pIndex->bUnordered = bUnordered; |
| 82375 | + }else{ |
| 82376 | + decodeIntArray((char*)z, 1, &pTable->nRowEst, 0); |
| 82377 | + } |
| 82378 | + |
| 81424 | 82379 | return 0; |
| 81425 | 82380 | } |
| 81426 | 82381 | |
| 81427 | 82382 | /* |
| 81428 | 82383 | ** If the Index.aSample variable is not NULL, delete the aSample[] array |
| 81429 | 82384 | ** and its contents. |
| 81430 | 82385 | */ |
| 81431 | 82386 | SQLITE_PRIVATE void sqlite3DeleteIndexSamples(sqlite3 *db, Index *pIdx){ |
| 81432 | | -#ifdef SQLITE_ENABLE_STAT3 |
| 82387 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 81433 | 82388 | if( pIdx->aSample ){ |
| 81434 | 82389 | int j; |
| 81435 | 82390 | for(j=0; j<pIdx->nSample; j++){ |
| 81436 | 82391 | IndexSample *p = &pIdx->aSample[j]; |
| 81437 | | - if( p->eType==SQLITE_TEXT || p->eType==SQLITE_BLOB ){ |
| 81438 | | - sqlite3DbFree(db, p->u.z); |
| 81439 | | - } |
| 82392 | + sqlite3DbFree(db, p->p); |
| 81440 | 82393 | } |
| 81441 | 82394 | sqlite3DbFree(db, pIdx->aSample); |
| 81442 | 82395 | } |
| 81443 | 82396 | if( db && db->pnBytesFreed==0 ){ |
| 81444 | 82397 | pIdx->nSample = 0; |
| | @@ -81445,155 +82398,222 @@ |
| 81445 | 82398 | pIdx->aSample = 0; |
| 81446 | 82399 | } |
| 81447 | 82400 | #else |
| 81448 | 82401 | UNUSED_PARAMETER(db); |
| 81449 | 82402 | UNUSED_PARAMETER(pIdx); |
| 81450 | | -#endif |
| 82403 | +#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */ |
| 81451 | 82404 | } |
| 81452 | 82405 | |
| 81453 | | -#ifdef SQLITE_ENABLE_STAT3 |
| 82406 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 81454 | 82407 | /* |
| 81455 | | -** Load content from the sqlite_stat3 table into the Index.aSample[] |
| 81456 | | -** arrays of all indices. |
| 82408 | +** Populate the pIdx->aAvgEq[] array based on the samples currently |
| 82409 | +** stored in pIdx->aSample[]. |
| 81457 | 82410 | */ |
| 81458 | | -static int loadStat3(sqlite3 *db, const char *zDb){ |
| 82411 | +static void initAvgEq(Index *pIdx){ |
| 82412 | + if( pIdx ){ |
| 82413 | + IndexSample *aSample = pIdx->aSample; |
| 82414 | + IndexSample *pFinal = &aSample[pIdx->nSample-1]; |
| 82415 | + int iCol; |
| 82416 | + for(iCol=0; iCol<pIdx->nColumn; iCol++){ |
| 82417 | + int i; /* Used to iterate through samples */ |
| 82418 | + tRowcnt sumEq = 0; /* Sum of the nEq values */ |
| 82419 | + tRowcnt nSum = 0; /* Number of terms contributing to sumEq */ |
| 82420 | + tRowcnt avgEq = 0; |
| 82421 | + tRowcnt nDLt = pFinal->anDLt[iCol]; |
| 82422 | + |
| 82423 | + /* Set nSum to the number of distinct (iCol+1) field prefixes that |
| 82424 | + ** occur in the stat4 table for this index before pFinal. Set |
| 82425 | + ** sumEq to the sum of the nEq values for column iCol for the same |
| 82426 | + ** set (adding the value only once where there exist dupicate |
| 82427 | + ** prefixes). */ |
| 82428 | + for(i=0; i<(pIdx->nSample-1); i++){ |
| 82429 | + if( aSample[i].anDLt[iCol]!=aSample[i+1].anDLt[iCol] ){ |
| 82430 | + sumEq += aSample[i].anEq[iCol]; |
| 82431 | + nSum++; |
| 82432 | + } |
| 82433 | + } |
| 82434 | + if( nDLt>nSum ){ |
| 82435 | + avgEq = (pFinal->anLt[iCol] - sumEq)/(nDLt - nSum); |
| 82436 | + } |
| 82437 | + if( avgEq==0 ) avgEq = 1; |
| 82438 | + pIdx->aAvgEq[iCol] = avgEq; |
| 82439 | + if( pIdx->nSampleCol==1 ) break; |
| 82440 | + } |
| 82441 | + } |
| 82442 | +} |
| 82443 | + |
| 82444 | +/* |
| 82445 | +** Load the content from either the sqlite_stat4 or sqlite_stat3 table |
| 82446 | +** into the relevant Index.aSample[] arrays. |
| 82447 | +** |
| 82448 | +** Arguments zSql1 and zSql2 must point to SQL statements that return |
| 82449 | +** data equivalent to the following (statements are different for stat3, |
| 82450 | +** see the caller of this function for details): |
| 82451 | +** |
| 82452 | +** zSql1: SELECT idx,count(*) FROM %Q.sqlite_stat4 GROUP BY idx |
| 82453 | +** zSql2: SELECT idx,neq,nlt,ndlt,sample FROM %Q.sqlite_stat4 |
| 82454 | +** |
| 82455 | +** where %Q is replaced with the database name before the SQL is executed. |
| 82456 | +*/ |
| 82457 | +static int loadStatTbl( |
| 82458 | + sqlite3 *db, /* Database handle */ |
| 82459 | + int bStat3, /* Assume single column records only */ |
| 82460 | + const char *zSql1, /* SQL statement 1 (see above) */ |
| 82461 | + const char *zSql2, /* SQL statement 2 (see above) */ |
| 82462 | + const char *zDb /* Database name (e.g. "main") */ |
| 82463 | +){ |
| 81459 | 82464 | int rc; /* Result codes from subroutines */ |
| 81460 | 82465 | sqlite3_stmt *pStmt = 0; /* An SQL statement being run */ |
| 81461 | 82466 | char *zSql; /* Text of the SQL statement */ |
| 81462 | 82467 | Index *pPrevIdx = 0; /* Previous index in the loop */ |
| 81463 | | - int idx = 0; /* slot in pIdx->aSample[] for next sample */ |
| 81464 | | - int eType; /* Datatype of a sample */ |
| 81465 | 82468 | IndexSample *pSample; /* A slot in pIdx->aSample[] */ |
| 81466 | 82469 | |
| 81467 | 82470 | assert( db->lookaside.bEnabled==0 ); |
| 81468 | | - if( !sqlite3FindTable(db, "sqlite_stat3", zDb) ){ |
| 81469 | | - return SQLITE_OK; |
| 81470 | | - } |
| 81471 | | - |
| 81472 | | - zSql = sqlite3MPrintf(db, |
| 81473 | | - "SELECT idx,count(*) FROM %Q.sqlite_stat3" |
| 81474 | | - " GROUP BY idx", zDb); |
| 82471 | + zSql = sqlite3MPrintf(db, zSql1, zDb); |
| 81475 | 82472 | if( !zSql ){ |
| 81476 | 82473 | return SQLITE_NOMEM; |
| 81477 | 82474 | } |
| 81478 | 82475 | rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0); |
| 81479 | 82476 | sqlite3DbFree(db, zSql); |
| 81480 | 82477 | if( rc ) return rc; |
| 81481 | 82478 | |
| 81482 | 82479 | while( sqlite3_step(pStmt)==SQLITE_ROW ){ |
| 82480 | + int nIdxCol = 1; /* Number of columns in stat4 records */ |
| 82481 | + int nAvgCol = 1; /* Number of entries in Index.aAvgEq */ |
| 82482 | + |
| 81483 | 82483 | char *zIndex; /* Index name */ |
| 81484 | 82484 | Index *pIdx; /* Pointer to the index object */ |
| 81485 | 82485 | int nSample; /* Number of samples */ |
| 82486 | + int nByte; /* Bytes of space required */ |
| 82487 | + int i; /* Bytes of space required */ |
| 82488 | + tRowcnt *pSpace; |
| 81486 | 82489 | |
| 81487 | 82490 | zIndex = (char *)sqlite3_column_text(pStmt, 0); |
| 81488 | 82491 | if( zIndex==0 ) continue; |
| 81489 | 82492 | nSample = sqlite3_column_int(pStmt, 1); |
| 81490 | 82493 | pIdx = sqlite3FindIndex(db, zIndex, zDb); |
| 81491 | | - if( pIdx==0 ) continue; |
| 81492 | | - assert( pIdx->nSample==0 ); |
| 81493 | | - pIdx->nSample = nSample; |
| 81494 | | - pIdx->aSample = sqlite3DbMallocZero(db, nSample*sizeof(IndexSample)); |
| 81495 | | - pIdx->avgEq = pIdx->aiRowEst[1]; |
| 82494 | + assert( pIdx==0 || bStat3 || pIdx->nSample==0 ); |
| 82495 | + /* Index.nSample is non-zero at this point if data has already been |
| 82496 | + ** loaded from the stat4 table. In this case ignore stat3 data. */ |
| 82497 | + if( pIdx==0 || pIdx->nSample ) continue; |
| 82498 | + if( bStat3==0 ){ |
| 82499 | + nIdxCol = pIdx->nColumn+1; |
| 82500 | + nAvgCol = pIdx->nColumn; |
| 82501 | + } |
| 82502 | + pIdx->nSampleCol = nIdxCol; |
| 82503 | + nByte = sizeof(IndexSample) * nSample; |
| 82504 | + nByte += sizeof(tRowcnt) * nIdxCol * 3 * nSample; |
| 82505 | + nByte += nAvgCol * sizeof(tRowcnt); /* Space for Index.aAvgEq[] */ |
| 82506 | + |
| 82507 | + pIdx->aSample = sqlite3DbMallocZero(db, nByte); |
| 81496 | 82508 | if( pIdx->aSample==0 ){ |
| 81497 | | - db->mallocFailed = 1; |
| 81498 | 82509 | sqlite3_finalize(pStmt); |
| 81499 | 82510 | return SQLITE_NOMEM; |
| 81500 | 82511 | } |
| 82512 | + pSpace = (tRowcnt*)&pIdx->aSample[nSample]; |
| 82513 | + pIdx->aAvgEq = pSpace; pSpace += nAvgCol; |
| 82514 | + for(i=0; i<nSample; i++){ |
| 82515 | + pIdx->aSample[i].anEq = pSpace; pSpace += nIdxCol; |
| 82516 | + pIdx->aSample[i].anLt = pSpace; pSpace += nIdxCol; |
| 82517 | + pIdx->aSample[i].anDLt = pSpace; pSpace += nIdxCol; |
| 82518 | + } |
| 82519 | + assert( ((u8*)pSpace)-nByte==(u8*)(pIdx->aSample) ); |
| 81501 | 82520 | } |
| 81502 | 82521 | rc = sqlite3_finalize(pStmt); |
| 81503 | 82522 | if( rc ) return rc; |
| 81504 | 82523 | |
| 81505 | | - zSql = sqlite3MPrintf(db, |
| 81506 | | - "SELECT idx,neq,nlt,ndlt,sample FROM %Q.sqlite_stat3", zDb); |
| 82524 | + zSql = sqlite3MPrintf(db, zSql2, zDb); |
| 81507 | 82525 | if( !zSql ){ |
| 81508 | 82526 | return SQLITE_NOMEM; |
| 81509 | 82527 | } |
| 81510 | 82528 | rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0); |
| 81511 | 82529 | sqlite3DbFree(db, zSql); |
| 81512 | 82530 | if( rc ) return rc; |
| 81513 | 82531 | |
| 81514 | 82532 | while( sqlite3_step(pStmt)==SQLITE_ROW ){ |
| 81515 | | - char *zIndex; /* Index name */ |
| 81516 | | - Index *pIdx; /* Pointer to the index object */ |
| 81517 | | - int i; /* Loop counter */ |
| 81518 | | - tRowcnt sumEq; /* Sum of the nEq values */ |
| 82533 | + char *zIndex; /* Index name */ |
| 82534 | + Index *pIdx; /* Pointer to the index object */ |
| 82535 | + int nCol = 1; /* Number of columns in index */ |
| 81519 | 82536 | |
| 81520 | 82537 | zIndex = (char *)sqlite3_column_text(pStmt, 0); |
| 81521 | 82538 | if( zIndex==0 ) continue; |
| 81522 | 82539 | pIdx = sqlite3FindIndex(db, zIndex, zDb); |
| 81523 | 82540 | if( pIdx==0 ) continue; |
| 81524 | | - if( pIdx==pPrevIdx ){ |
| 81525 | | - idx++; |
| 81526 | | - }else{ |
| 82541 | + /* This next condition is true if data has already been loaded from |
| 82542 | + ** the sqlite_stat4 table. In this case ignore stat3 data. */ |
| 82543 | + nCol = pIdx->nSampleCol; |
| 82544 | + if( bStat3 && nCol>1 ) continue; |
| 82545 | + if( pIdx!=pPrevIdx ){ |
| 82546 | + initAvgEq(pPrevIdx); |
| 81527 | 82547 | pPrevIdx = pIdx; |
| 81528 | | - idx = 0; |
| 81529 | | - } |
| 81530 | | - assert( idx<pIdx->nSample ); |
| 81531 | | - pSample = &pIdx->aSample[idx]; |
| 81532 | | - pSample->nEq = (tRowcnt)sqlite3_column_int64(pStmt, 1); |
| 81533 | | - pSample->nLt = (tRowcnt)sqlite3_column_int64(pStmt, 2); |
| 81534 | | - pSample->nDLt = (tRowcnt)sqlite3_column_int64(pStmt, 3); |
| 81535 | | - if( idx==pIdx->nSample-1 ){ |
| 81536 | | - if( pSample->nDLt>0 ){ |
| 81537 | | - for(i=0, sumEq=0; i<=idx-1; i++) sumEq += pIdx->aSample[i].nEq; |
| 81538 | | - pIdx->avgEq = (pSample->nLt - sumEq)/pSample->nDLt; |
| 81539 | | - } |
| 81540 | | - if( pIdx->avgEq<=0 ) pIdx->avgEq = 1; |
| 81541 | | - } |
| 81542 | | - eType = sqlite3_column_type(pStmt, 4); |
| 81543 | | - pSample->eType = (u8)eType; |
| 81544 | | - switch( eType ){ |
| 81545 | | - case SQLITE_INTEGER: { |
| 81546 | | - pSample->u.i = sqlite3_column_int64(pStmt, 4); |
| 81547 | | - break; |
| 81548 | | - } |
| 81549 | | - case SQLITE_FLOAT: { |
| 81550 | | - pSample->u.r = sqlite3_column_double(pStmt, 4); |
| 81551 | | - break; |
| 81552 | | - } |
| 81553 | | - case SQLITE_NULL: { |
| 81554 | | - break; |
| 81555 | | - } |
| 81556 | | - default: assert( eType==SQLITE_TEXT || eType==SQLITE_BLOB ); { |
| 81557 | | - const char *z = (const char *)( |
| 81558 | | - (eType==SQLITE_BLOB) ? |
| 81559 | | - sqlite3_column_blob(pStmt, 4): |
| 81560 | | - sqlite3_column_text(pStmt, 4) |
| 81561 | | - ); |
| 81562 | | - int n = z ? sqlite3_column_bytes(pStmt, 4) : 0; |
| 81563 | | - pSample->nByte = n; |
| 81564 | | - if( n < 1){ |
| 81565 | | - pSample->u.z = 0; |
| 81566 | | - }else{ |
| 81567 | | - pSample->u.z = sqlite3DbMallocRaw(db, n); |
| 81568 | | - if( pSample->u.z==0 ){ |
| 81569 | | - db->mallocFailed = 1; |
| 81570 | | - sqlite3_finalize(pStmt); |
| 81571 | | - return SQLITE_NOMEM; |
| 81572 | | - } |
| 81573 | | - memcpy(pSample->u.z, z, n); |
| 81574 | | - } |
| 81575 | | - } |
| 81576 | | - } |
| 81577 | | - } |
| 81578 | | - return sqlite3_finalize(pStmt); |
| 81579 | | -} |
| 81580 | | -#endif /* SQLITE_ENABLE_STAT3 */ |
| 81581 | | - |
| 81582 | | -/* |
| 81583 | | -** Load the content of the sqlite_stat1 and sqlite_stat3 tables. The |
| 82548 | + } |
| 82549 | + pSample = &pIdx->aSample[pIdx->nSample]; |
| 82550 | + decodeIntArray((char*)sqlite3_column_text(pStmt,1), nCol, pSample->anEq, 0); |
| 82551 | + decodeIntArray((char*)sqlite3_column_text(pStmt,2), nCol, pSample->anLt, 0); |
| 82552 | + decodeIntArray((char*)sqlite3_column_text(pStmt,3), nCol, pSample->anDLt,0); |
| 82553 | + |
| 82554 | + /* Take a copy of the sample. Add two 0x00 bytes the end of the buffer. |
| 82555 | + ** This is in case the sample record is corrupted. In that case, the |
| 82556 | + ** sqlite3VdbeRecordCompare() may read up to two varints past the |
| 82557 | + ** end of the allocated buffer before it realizes it is dealing with |
| 82558 | + ** a corrupt record. Adding the two 0x00 bytes prevents this from causing |
| 82559 | + ** a buffer overread. */ |
| 82560 | + pSample->n = sqlite3_column_bytes(pStmt, 4); |
| 82561 | + pSample->p = sqlite3DbMallocZero(db, pSample->n + 2); |
| 82562 | + if( pSample->p==0 ){ |
| 82563 | + sqlite3_finalize(pStmt); |
| 82564 | + return SQLITE_NOMEM; |
| 82565 | + } |
| 82566 | + memcpy(pSample->p, sqlite3_column_blob(pStmt, 4), pSample->n); |
| 82567 | + pIdx->nSample++; |
| 82568 | + } |
| 82569 | + rc = sqlite3_finalize(pStmt); |
| 82570 | + if( rc==SQLITE_OK ) initAvgEq(pPrevIdx); |
| 82571 | + return rc; |
| 82572 | +} |
| 82573 | + |
| 82574 | +/* |
| 82575 | +** Load content from the sqlite_stat4 and sqlite_stat3 tables into |
| 82576 | +** the Index.aSample[] arrays of all indices. |
| 82577 | +*/ |
| 82578 | +static int loadStat4(sqlite3 *db, const char *zDb){ |
| 82579 | + int rc = SQLITE_OK; /* Result codes from subroutines */ |
| 82580 | + |
| 82581 | + assert( db->lookaside.bEnabled==0 ); |
| 82582 | + if( sqlite3FindTable(db, "sqlite_stat4", zDb) ){ |
| 82583 | + rc = loadStatTbl(db, 0, |
| 82584 | + "SELECT idx,count(*) FROM %Q.sqlite_stat4 GROUP BY idx", |
| 82585 | + "SELECT idx,neq,nlt,ndlt,sample FROM %Q.sqlite_stat4", |
| 82586 | + zDb |
| 82587 | + ); |
| 82588 | + } |
| 82589 | + |
| 82590 | + if( rc==SQLITE_OK && sqlite3FindTable(db, "sqlite_stat3", zDb) ){ |
| 82591 | + rc = loadStatTbl(db, 1, |
| 82592 | + "SELECT idx,count(*) FROM %Q.sqlite_stat3 GROUP BY idx", |
| 82593 | + "SELECT idx,neq,nlt,ndlt,sqlite_record(sample) FROM %Q.sqlite_stat3", |
| 82594 | + zDb |
| 82595 | + ); |
| 82596 | + } |
| 82597 | + |
| 82598 | + return rc; |
| 82599 | +} |
| 82600 | +#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */ |
| 82601 | + |
| 82602 | +/* |
| 82603 | +** Load the content of the sqlite_stat1 and sqlite_stat3/4 tables. The |
| 81584 | 82604 | ** contents of sqlite_stat1 are used to populate the Index.aiRowEst[] |
| 81585 | | -** arrays. The contents of sqlite_stat3 are used to populate the |
| 82605 | +** arrays. The contents of sqlite_stat3/4 are used to populate the |
| 81586 | 82606 | ** Index.aSample[] arrays. |
| 81587 | 82607 | ** |
| 81588 | 82608 | ** If the sqlite_stat1 table is not present in the database, SQLITE_ERROR |
| 81589 | | -** is returned. In this case, even if SQLITE_ENABLE_STAT3 was defined |
| 81590 | | -** during compilation and the sqlite_stat3 table is present, no data is |
| 82609 | +** is returned. In this case, even if SQLITE_ENABLE_STAT3/4 was defined |
| 82610 | +** during compilation and the sqlite_stat3/4 table is present, no data is |
| 81591 | 82611 | ** read from it. |
| 81592 | 82612 | ** |
| 81593 | | -** If SQLITE_ENABLE_STAT3 was defined during compilation and the |
| 81594 | | -** sqlite_stat3 table is not present in the database, SQLITE_ERROR is |
| 82613 | +** If SQLITE_ENABLE_STAT3/4 was defined during compilation and the |
| 82614 | +** sqlite_stat4 table is not present in the database, SQLITE_ERROR is |
| 81595 | 82615 | ** returned. However, in this case, data is read from the sqlite_stat1 |
| 81596 | 82616 | ** table (if it is present) before returning. |
| 81597 | 82617 | ** |
| 81598 | 82618 | ** If an OOM error occurs, this function always sets db->mallocFailed. |
| 81599 | 82619 | ** This means if the caller does not care about other errors, the return |
| | @@ -81611,11 +82631,11 @@ |
| 81611 | 82631 | /* Clear any prior statistics */ |
| 81612 | 82632 | assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); |
| 81613 | 82633 | for(i=sqliteHashFirst(&db->aDb[iDb].pSchema->idxHash);i;i=sqliteHashNext(i)){ |
| 81614 | 82634 | Index *pIdx = sqliteHashData(i); |
| 81615 | 82635 | sqlite3DefaultRowEst(pIdx); |
| 81616 | | -#ifdef SQLITE_ENABLE_STAT3 |
| 82636 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 81617 | 82637 | sqlite3DeleteIndexSamples(db, pIdx); |
| 81618 | 82638 | pIdx->aSample = 0; |
| 81619 | 82639 | #endif |
| 81620 | 82640 | } |
| 81621 | 82641 | |
| | @@ -81635,16 +82655,16 @@ |
| 81635 | 82655 | rc = sqlite3_exec(db, zSql, analysisLoader, &sInfo, 0); |
| 81636 | 82656 | sqlite3DbFree(db, zSql); |
| 81637 | 82657 | } |
| 81638 | 82658 | |
| 81639 | 82659 | |
| 81640 | | - /* Load the statistics from the sqlite_stat3 table. */ |
| 81641 | | -#ifdef SQLITE_ENABLE_STAT3 |
| 82660 | + /* Load the statistics from the sqlite_stat4 table. */ |
| 82661 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 81642 | 82662 | if( rc==SQLITE_OK ){ |
| 81643 | 82663 | int lookasideEnabled = db->lookaside.bEnabled; |
| 81644 | 82664 | db->lookaside.bEnabled = 0; |
| 81645 | | - rc = loadStat3(db, sInfo.zDatabase); |
| 82665 | + rc = loadStat4(db, sInfo.zDatabase); |
| 81646 | 82666 | db->lookaside.bEnabled = lookasideEnabled; |
| 81647 | 82667 | } |
| 81648 | 82668 | #endif |
| 81649 | 82669 | |
| 81650 | 82670 | if( rc==SQLITE_NOMEM ){ |
| | @@ -84496,11 +85516,11 @@ |
| 84496 | 85516 | const char *zType, /* "idx" or "tbl" */ |
| 84497 | 85517 | const char *zName /* Name of index or table */ |
| 84498 | 85518 | ){ |
| 84499 | 85519 | int i; |
| 84500 | 85520 | const char *zDbName = pParse->db->aDb[iDb].zName; |
| 84501 | | - for(i=1; i<=3; i++){ |
| 85521 | + for(i=1; i<=4; i++){ |
| 84502 | 85522 | char zTab[24]; |
| 84503 | 85523 | sqlite3_snprintf(sizeof(zTab),zTab,"sqlite_stat%d",i); |
| 84504 | 85524 | if( sqlite3FindTable(pParse->db, zTab, zDbName) ){ |
| 84505 | 85525 | sqlite3NestedParse(pParse, |
| 84506 | 85526 | "DELETE FROM %Q.%s WHERE %s=%Q", |
| | @@ -89167,10 +90187,13 @@ |
| 89167 | 90187 | sqlite3FuncDefInsert(pHash, &aFunc[i]); |
| 89168 | 90188 | } |
| 89169 | 90189 | sqlite3RegisterDateTimeFunctions(); |
| 89170 | 90190 | #ifndef SQLITE_OMIT_ALTERTABLE |
| 89171 | 90191 | sqlite3AlterFunctions(); |
| 90192 | +#endif |
| 90193 | +#if defined(SQLITE_ENABLE_STAT3) || defined(SQLITE_ENABLE_STAT4) |
| 90194 | + sqlite3AnalyzeFunctions(); |
| 89172 | 90195 | #endif |
| 89173 | 90196 | } |
| 89174 | 90197 | |
| 89175 | 90198 | /************** End of func.c ************************************************/ |
| 89176 | 90199 | /************** Begin file fkey.c ********************************************/ |
| | @@ -94387,11 +95410,11 @@ |
| 94387 | 95410 | */ |
| 94388 | 95411 | if( sqlite3StrICmp(zLeft,"journal_size_limit")==0 ){ |
| 94389 | 95412 | Pager *pPager = sqlite3BtreePager(pDb->pBt); |
| 94390 | 95413 | i64 iLimit = -2; |
| 94391 | 95414 | if( zRight ){ |
| 94392 | | - sqlite3Atoi64(zRight, &iLimit, 1000000, SQLITE_UTF8); |
| 95415 | + sqlite3Atoi64(zRight, &iLimit, sqlite3Strlen30(zRight), SQLITE_UTF8); |
| 94393 | 95416 | if( iLimit<-1 ) iLimit = -1; |
| 94394 | 95417 | } |
| 94395 | 95418 | iLimit = sqlite3PagerJournalSizeLimit(pPager, iLimit); |
| 94396 | 95419 | returnSingleInt(pParse, "journal_size_limit", iLimit); |
| 94397 | 95420 | }else |
| | @@ -94521,14 +95544,15 @@ |
| 94521 | 95544 | ** as little or as much as it wants. Except, if N is set to 0 then the |
| 94522 | 95545 | ** upper layers will never invoke the xFetch interfaces to the VFS. |
| 94523 | 95546 | */ |
| 94524 | 95547 | if( sqlite3StrICmp(zLeft,"mmap_size")==0 ){ |
| 94525 | 95548 | sqlite3_int64 sz; |
| 95549 | +#if SQLITE_MAX_MMAP_SIZE>0 |
| 94526 | 95550 | assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); |
| 94527 | 95551 | if( zRight ){ |
| 94528 | 95552 | int ii; |
| 94529 | | - sqlite3Atoi64(zRight, &sz, 1000, SQLITE_UTF8); |
| 95553 | + sqlite3Atoi64(zRight, &sz, sqlite3Strlen30(zRight), SQLITE_UTF8); |
| 94530 | 95554 | if( sz<0 ) sz = sqlite3GlobalConfig.szMmap; |
| 94531 | 95555 | if( pId2->n==0 ) db->szMmap = sz; |
| 94532 | 95556 | for(ii=db->nDb-1; ii>=0; ii--){ |
| 94533 | 95557 | if( db->aDb[ii].pBt && (ii==iDb || pId2->n==0) ){ |
| 94534 | 95558 | sqlite3BtreeSetMmapLimit(db->aDb[ii].pBt, sz); |
| | @@ -94535,12 +95559,13 @@ |
| 94535 | 95559 | } |
| 94536 | 95560 | } |
| 94537 | 95561 | } |
| 94538 | 95562 | sz = -1; |
| 94539 | 95563 | rc = sqlite3_file_control(db, zDb, SQLITE_FCNTL_MMAP_SIZE, &sz); |
| 94540 | | -#if SQLITE_MAX_MMAP_SIZE==0 |
| 95564 | +#else |
| 94541 | 95565 | sz = 0; |
| 95566 | + rc = SQLITE_OK; |
| 94542 | 95567 | #endif |
| 94543 | 95568 | if( rc==SQLITE_OK ){ |
| 94544 | 95569 | returnSingleInt(pParse, "mmap_size", sz); |
| 94545 | 95570 | }else if( rc!=SQLITE_NOTFOUND ){ |
| 94546 | 95571 | pParse->nErr++; |
| | @@ -102688,11 +103713,11 @@ |
| 102688 | 103713 | ** space. |
| 102689 | 103714 | */ |
| 102690 | 103715 | SQLITE_PRIVATE void sqlite3ColumnDefault(Vdbe *v, Table *pTab, int i, int iReg){ |
| 102691 | 103716 | assert( pTab!=0 ); |
| 102692 | 103717 | if( !pTab->pSelect ){ |
| 102693 | | - sqlite3_value *pValue; |
| 103718 | + sqlite3_value *pValue = 0; |
| 102694 | 103719 | u8 enc = ENC(sqlite3VdbeDb(v)); |
| 102695 | 103720 | Column *pCol = &pTab->aCol[i]; |
| 102696 | 103721 | VdbeComment((v, "%s.%s", pTab->zName, pCol->zName)); |
| 102697 | 103722 | assert( i<pTab->nCol ); |
| 102698 | 103723 | sqlite3ValueFromExpr(sqlite3VdbeDb(v), pCol->pDflt, enc, |
| | @@ -104937,13 +105962,13 @@ |
| 104937 | 105962 | /* |
| 104938 | 105963 | ** Each instance of this object holds a sequence of WhereLoop objects |
| 104939 | 105964 | ** that implement some or all of a query plan. |
| 104940 | 105965 | ** |
| 104941 | 105966 | ** Think of each WhereLoop object as a node in a graph with arcs |
| 104942 | | -** showing dependences and costs for travelling between nodes. (That is |
| 105967 | +** showing dependencies and costs for travelling between nodes. (That is |
| 104943 | 105968 | ** not a completely accurate description because WhereLoop costs are a |
| 104944 | | -** vector, not a scalar, and because dependences are many-to-one, not |
| 105969 | +** vector, not a scalar, and because dependencies are many-to-one, not |
| 104945 | 105970 | ** one-to-one as are graph nodes. But it is a useful visualization aid.) |
| 104946 | 105971 | ** Then a WherePath object is a path through the graph that visits some |
| 104947 | 105972 | ** or all of the WhereLoop objects once. |
| 104948 | 105973 | ** |
| 104949 | 105974 | ** The "solver" works by creating the N best WherePath objects of length |
| | @@ -105038,11 +106063,11 @@ |
| 105038 | 106063 | #define TERM_CODED 0x04 /* This term is already coded */ |
| 105039 | 106064 | #define TERM_COPIED 0x08 /* Has a child */ |
| 105040 | 106065 | #define TERM_ORINFO 0x10 /* Need to free the WhereTerm.u.pOrInfo object */ |
| 105041 | 106066 | #define TERM_ANDINFO 0x20 /* Need to free the WhereTerm.u.pAndInfo obj */ |
| 105042 | 106067 | #define TERM_OR_OK 0x40 /* Used during OR-clause processing */ |
| 105043 | | -#ifdef SQLITE_ENABLE_STAT3 |
| 106068 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 105044 | 106069 | # define TERM_VNULL 0x80 /* Manufactured x>NULL or x<=NULL term */ |
| 105045 | 106070 | #else |
| 105046 | 106071 | # define TERM_VNULL 0x00 /* Disabled if not using stat3 */ |
| 105047 | 106072 | #endif |
| 105048 | 106073 | |
| | @@ -105144,10 +106169,14 @@ |
| 105144 | 106169 | WhereInfo *pWInfo; /* Information about this WHERE */ |
| 105145 | 106170 | WhereClause *pWC; /* WHERE clause terms */ |
| 105146 | 106171 | ExprList *pOrderBy; /* ORDER BY clause */ |
| 105147 | 106172 | WhereLoop *pNew; /* Template WhereLoop */ |
| 105148 | 106173 | WhereOrSet *pOrSet; /* Record best loops here, if not NULL */ |
| 106174 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 106175 | + UnpackedRecord *pRec; /* Probe for stat4 (if required) */ |
| 106176 | + int nRecValid; /* Number of valid fields currently in pRec */ |
| 106177 | +#endif |
| 105149 | 106178 | }; |
| 105150 | 106179 | |
| 105151 | 106180 | /* |
| 105152 | 106181 | ** The WHERE clause processing routine has two halves. The |
| 105153 | 106182 | ** first part does the start of the WHERE loop and the second |
| | @@ -106543,11 +107572,11 @@ |
| 106543 | 107572 | pNewTerm->prereqAll = pTerm->prereqAll; |
| 106544 | 107573 | } |
| 106545 | 107574 | } |
| 106546 | 107575 | #endif /* SQLITE_OMIT_VIRTUALTABLE */ |
| 106547 | 107576 | |
| 106548 | | -#ifdef SQLITE_ENABLE_STAT3 |
| 107577 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 106549 | 107578 | /* When sqlite_stat3 histogram data is available an operator of the |
| 106550 | 107579 | ** form "x IS NOT NULL" can sometimes be evaluated more efficiently |
| 106551 | 107580 | ** as "x>NULL" if x is not an INTEGER PRIMARY KEY. So construct a |
| 106552 | 107581 | ** virtual term of that form. |
| 106553 | 107582 | ** |
| | @@ -106583,11 +107612,11 @@ |
| 106583 | 107612 | pTerm->nChild = 1; |
| 106584 | 107613 | pTerm->wtFlags |= TERM_COPIED; |
| 106585 | 107614 | pNewTerm->prereqAll = pTerm->prereqAll; |
| 106586 | 107615 | } |
| 106587 | 107616 | } |
| 106588 | | -#endif /* SQLITE_ENABLE_STAT */ |
| 107617 | +#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */ |
| 106589 | 107618 | |
| 106590 | 107619 | /* Prevent ON clause terms of a LEFT JOIN from being used to drive |
| 106591 | 107620 | ** an index for tables to the left of the join. |
| 106592 | 107621 | */ |
| 106593 | 107622 | pTerm->prereqRight |= extraRight; |
| | @@ -107151,155 +108180,87 @@ |
| 107151 | 108180 | return pParse->nErr; |
| 107152 | 108181 | } |
| 107153 | 108182 | #endif /* !defined(SQLITE_OMIT_VIRTUALTABLE) */ |
| 107154 | 108183 | |
| 107155 | 108184 | |
| 107156 | | -#ifdef SQLITE_ENABLE_STAT3 |
| 108185 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 107157 | 108186 | /* |
| 107158 | 108187 | ** Estimate the location of a particular key among all keys in an |
| 107159 | 108188 | ** index. Store the results in aStat as follows: |
| 107160 | 108189 | ** |
| 107161 | 108190 | ** aStat[0] Est. number of rows less than pVal |
| 107162 | 108191 | ** aStat[1] Est. number of rows equal to pVal |
| 107163 | 108192 | ** |
| 107164 | 108193 | ** Return SQLITE_OK on success. |
| 107165 | 108194 | */ |
| 107166 | | -static int whereKeyStats( |
| 108195 | +static void whereKeyStats( |
| 107167 | 108196 | Parse *pParse, /* Database connection */ |
| 107168 | 108197 | Index *pIdx, /* Index to consider domain of */ |
| 107169 | | - sqlite3_value *pVal, /* Value to consider */ |
| 108198 | + UnpackedRecord *pRec, /* Vector of values to consider */ |
| 107170 | 108199 | int roundUp, /* Round up if true. Round down if false */ |
| 107171 | 108200 | tRowcnt *aStat /* OUT: stats written here */ |
| 107172 | 108201 | ){ |
| 107173 | | - tRowcnt n; |
| 107174 | | - IndexSample *aSample; |
| 107175 | | - int i, eType; |
| 107176 | | - int isEq = 0; |
| 107177 | | - i64 v; |
| 107178 | | - double r, rS; |
| 107179 | | - |
| 107180 | | - assert( roundUp==0 || roundUp==1 ); |
| 108202 | + IndexSample *aSample = pIdx->aSample; |
| 108203 | + int iCol; /* Index of required stats in anEq[] etc. */ |
| 108204 | + int iMin = 0; /* Smallest sample not yet tested */ |
| 108205 | + int i = pIdx->nSample; /* Smallest sample larger than or equal to pRec */ |
| 108206 | + int iTest; /* Next sample to test */ |
| 108207 | + int res; /* Result of comparison operation */ |
| 108208 | + |
| 108209 | + assert( pRec!=0 || pParse->db->mallocFailed ); |
| 108210 | + if( pRec==0 ) return; |
| 108211 | + iCol = pRec->nField - 1; |
| 107181 | 108212 | assert( pIdx->nSample>0 ); |
| 107182 | | - if( pVal==0 ) return SQLITE_ERROR; |
| 107183 | | - n = pIdx->aiRowEst[0]; |
| 107184 | | - aSample = pIdx->aSample; |
| 107185 | | - eType = sqlite3_value_type(pVal); |
| 107186 | | - |
| 107187 | | - if( eType==SQLITE_INTEGER ){ |
| 107188 | | - v = sqlite3_value_int64(pVal); |
| 107189 | | - r = (i64)v; |
| 107190 | | - for(i=0; i<pIdx->nSample; i++){ |
| 107191 | | - if( aSample[i].eType==SQLITE_NULL ) continue; |
| 107192 | | - if( aSample[i].eType>=SQLITE_TEXT ) break; |
| 107193 | | - if( aSample[i].eType==SQLITE_INTEGER ){ |
| 107194 | | - if( aSample[i].u.i>=v ){ |
| 107195 | | - isEq = aSample[i].u.i==v; |
| 107196 | | - break; |
| 107197 | | - } |
| 107198 | | - }else{ |
| 107199 | | - assert( aSample[i].eType==SQLITE_FLOAT ); |
| 107200 | | - if( aSample[i].u.r>=r ){ |
| 107201 | | - isEq = aSample[i].u.r==r; |
| 107202 | | - break; |
| 107203 | | - } |
| 107204 | | - } |
| 107205 | | - } |
| 107206 | | - }else if( eType==SQLITE_FLOAT ){ |
| 107207 | | - r = sqlite3_value_double(pVal); |
| 107208 | | - for(i=0; i<pIdx->nSample; i++){ |
| 107209 | | - if( aSample[i].eType==SQLITE_NULL ) continue; |
| 107210 | | - if( aSample[i].eType>=SQLITE_TEXT ) break; |
| 107211 | | - if( aSample[i].eType==SQLITE_FLOAT ){ |
| 107212 | | - rS = aSample[i].u.r; |
| 107213 | | - }else{ |
| 107214 | | - rS = aSample[i].u.i; |
| 107215 | | - } |
| 107216 | | - if( rS>=r ){ |
| 107217 | | - isEq = rS==r; |
| 107218 | | - break; |
| 107219 | | - } |
| 107220 | | - } |
| 107221 | | - }else if( eType==SQLITE_NULL ){ |
| 107222 | | - i = 0; |
| 107223 | | - if( aSample[0].eType==SQLITE_NULL ) isEq = 1; |
| 107224 | | - }else{ |
| 107225 | | - assert( eType==SQLITE_TEXT || eType==SQLITE_BLOB ); |
| 107226 | | - for(i=0; i<pIdx->nSample; i++){ |
| 107227 | | - if( aSample[i].eType==SQLITE_TEXT || aSample[i].eType==SQLITE_BLOB ){ |
| 107228 | | - break; |
| 107229 | | - } |
| 107230 | | - } |
| 107231 | | - if( i<pIdx->nSample ){ |
| 107232 | | - sqlite3 *db = pParse->db; |
| 107233 | | - CollSeq *pColl; |
| 107234 | | - const u8 *z; |
| 107235 | | - if( eType==SQLITE_BLOB ){ |
| 107236 | | - z = (const u8 *)sqlite3_value_blob(pVal); |
| 107237 | | - pColl = db->pDfltColl; |
| 107238 | | - assert( pColl->enc==SQLITE_UTF8 ); |
| 107239 | | - }else{ |
| 107240 | | - pColl = sqlite3GetCollSeq(pParse, SQLITE_UTF8, 0, *pIdx->azColl); |
| 107241 | | - /* If the collating sequence was unavailable, we should have failed |
| 107242 | | - ** long ago and never reached this point. But we'll check just to |
| 107243 | | - ** be doubly sure. */ |
| 107244 | | - if( NEVER(pColl==0) ) return SQLITE_ERROR; |
| 107245 | | - z = (const u8 *)sqlite3ValueText(pVal, pColl->enc); |
| 107246 | | - if( !z ){ |
| 107247 | | - return SQLITE_NOMEM; |
| 107248 | | - } |
| 107249 | | - assert( z && pColl && pColl->xCmp ); |
| 107250 | | - } |
| 107251 | | - n = sqlite3ValueBytes(pVal, pColl->enc); |
| 107252 | | - |
| 107253 | | - for(; i<pIdx->nSample; i++){ |
| 107254 | | - int c; |
| 107255 | | - int eSampletype = aSample[i].eType; |
| 107256 | | - if( eSampletype<eType ) continue; |
| 107257 | | - if( eSampletype!=eType ) break; |
| 107258 | | -#ifndef SQLITE_OMIT_UTF16 |
| 107259 | | - if( pColl->enc!=SQLITE_UTF8 ){ |
| 107260 | | - int nSample; |
| 107261 | | - char *zSample = sqlite3Utf8to16( |
| 107262 | | - db, pColl->enc, aSample[i].u.z, aSample[i].nByte, &nSample |
| 107263 | | - ); |
| 107264 | | - if( !zSample ){ |
| 107265 | | - assert( db->mallocFailed ); |
| 107266 | | - return SQLITE_NOMEM; |
| 107267 | | - } |
| 107268 | | - c = pColl->xCmp(pColl->pUser, nSample, zSample, n, z); |
| 107269 | | - sqlite3DbFree(db, zSample); |
| 107270 | | - }else |
| 107271 | | -#endif |
| 107272 | | - { |
| 107273 | | - c = pColl->xCmp(pColl->pUser, aSample[i].nByte, aSample[i].u.z, n, z); |
| 107274 | | - } |
| 107275 | | - if( c>=0 ){ |
| 107276 | | - if( c==0 ) isEq = 1; |
| 107277 | | - break; |
| 107278 | | - } |
| 107279 | | - } |
| 107280 | | - } |
| 107281 | | - } |
| 108213 | + assert( pRec->nField>0 && iCol<pIdx->nSampleCol ); |
| 108214 | + do{ |
| 108215 | + iTest = (iMin+i)/2; |
| 108216 | + res = sqlite3VdbeRecordCompare(aSample[iTest].n, aSample[iTest].p, pRec); |
| 108217 | + if( res<0 ){ |
| 108218 | + iMin = iTest+1; |
| 108219 | + }else{ |
| 108220 | + i = iTest; |
| 108221 | + } |
| 108222 | + }while( res && iMin<i ); |
| 108223 | + |
| 108224 | +#ifdef SQLITE_DEBUG |
| 108225 | + /* The following assert statements check that the binary search code |
| 108226 | + ** above found the right answer. This block serves no purpose other |
| 108227 | + ** than to invoke the asserts. */ |
| 108228 | + if( res==0 ){ |
| 108229 | + /* If (res==0) is true, then sample $i must be equal to pRec */ |
| 108230 | + assert( i<pIdx->nSample ); |
| 108231 | + assert( 0==sqlite3VdbeRecordCompare(aSample[i].n, aSample[i].p, pRec) |
| 108232 | + || pParse->db->mallocFailed ); |
| 108233 | + }else{ |
| 108234 | + /* Otherwise, pRec must be smaller than sample $i and larger than |
| 108235 | + ** sample ($i-1). */ |
| 108236 | + assert( i==pIdx->nSample |
| 108237 | + || sqlite3VdbeRecordCompare(aSample[i].n, aSample[i].p, pRec)>0 |
| 108238 | + || pParse->db->mallocFailed ); |
| 108239 | + assert( i==0 |
| 108240 | + || sqlite3VdbeRecordCompare(aSample[i-1].n, aSample[i-1].p, pRec)<0 |
| 108241 | + || pParse->db->mallocFailed ); |
| 108242 | + } |
| 108243 | +#endif /* ifdef SQLITE_DEBUG */ |
| 107282 | 108244 | |
| 107283 | 108245 | /* At this point, aSample[i] is the first sample that is greater than |
| 107284 | 108246 | ** or equal to pVal. Or if i==pIdx->nSample, then all samples are less |
| 107285 | | - ** than pVal. If aSample[i]==pVal, then isEq==1. |
| 108247 | + ** than pVal. If aSample[i]==pVal, then res==0. |
| 107286 | 108248 | */ |
| 107287 | | - if( isEq ){ |
| 107288 | | - assert( i<pIdx->nSample ); |
| 107289 | | - aStat[0] = aSample[i].nLt; |
| 107290 | | - aStat[1] = aSample[i].nEq; |
| 108249 | + if( res==0 ){ |
| 108250 | + aStat[0] = aSample[i].anLt[iCol]; |
| 108251 | + aStat[1] = aSample[i].anEq[iCol]; |
| 107291 | 108252 | }else{ |
| 107292 | 108253 | tRowcnt iLower, iUpper, iGap; |
| 107293 | 108254 | if( i==0 ){ |
| 107294 | 108255 | iLower = 0; |
| 107295 | | - iUpper = aSample[0].nLt; |
| 108256 | + iUpper = aSample[0].anLt[iCol]; |
| 107296 | 108257 | }else{ |
| 107297 | | - iUpper = i>=pIdx->nSample ? n : aSample[i].nLt; |
| 107298 | | - iLower = aSample[i-1].nEq + aSample[i-1].nLt; |
| 108258 | + iUpper = i>=pIdx->nSample ? pIdx->aiRowEst[0] : aSample[i].anLt[iCol]; |
| 108259 | + iLower = aSample[i-1].anEq[iCol] + aSample[i-1].anLt[iCol]; |
| 107299 | 108260 | } |
| 107300 | | - aStat[1] = pIdx->avgEq; |
| 108261 | + aStat[1] = (pIdx->nColumn>iCol ? pIdx->aAvgEq[iCol] : 1); |
| 107301 | 108262 | if( iLower>=iUpper ){ |
| 107302 | 108263 | iGap = 0; |
| 107303 | 108264 | }else{ |
| 107304 | 108265 | iGap = iUpper - iLower; |
| 107305 | 108266 | } |
| | @@ -107308,48 +108269,12 @@ |
| 107308 | 108269 | }else{ |
| 107309 | 108270 | iGap = iGap/3; |
| 107310 | 108271 | } |
| 107311 | 108272 | aStat[0] = iLower + iGap; |
| 107312 | 108273 | } |
| 107313 | | - return SQLITE_OK; |
| 107314 | | -} |
| 107315 | | -#endif /* SQLITE_ENABLE_STAT3 */ |
| 107316 | | - |
| 107317 | | -/* |
| 107318 | | -** If expression pExpr represents a literal value, set *pp to point to |
| 107319 | | -** an sqlite3_value structure containing the same value, with affinity |
| 107320 | | -** aff applied to it, before returning. It is the responsibility of the |
| 107321 | | -** caller to eventually release this structure by passing it to |
| 107322 | | -** sqlite3ValueFree(). |
| 107323 | | -** |
| 107324 | | -** If the current parse is a recompile (sqlite3Reprepare()) and pExpr |
| 107325 | | -** is an SQL variable that currently has a non-NULL value bound to it, |
| 107326 | | -** create an sqlite3_value structure containing this value, again with |
| 107327 | | -** affinity aff applied to it, instead. |
| 107328 | | -** |
| 107329 | | -** If neither of the above apply, set *pp to NULL. |
| 107330 | | -** |
| 107331 | | -** If an error occurs, return an error code. Otherwise, SQLITE_OK. |
| 107332 | | -*/ |
| 107333 | | -#ifdef SQLITE_ENABLE_STAT3 |
| 107334 | | -static int valueFromExpr( |
| 107335 | | - Parse *pParse, |
| 107336 | | - Expr *pExpr, |
| 107337 | | - u8 aff, |
| 107338 | | - sqlite3_value **pp |
| 107339 | | -){ |
| 107340 | | - if( pExpr->op==TK_VARIABLE |
| 107341 | | - || (pExpr->op==TK_REGISTER && pExpr->op2==TK_VARIABLE) |
| 107342 | | - ){ |
| 107343 | | - int iVar = pExpr->iColumn; |
| 107344 | | - sqlite3VdbeSetVarmask(pParse->pVdbe, iVar); |
| 107345 | | - *pp = sqlite3VdbeGetBoundValue(pParse->pReprepare, iVar, aff); |
| 107346 | | - return SQLITE_OK; |
| 107347 | | - } |
| 107348 | | - return sqlite3ValueFromExpr(pParse->db, pExpr, SQLITE_UTF8, aff, pp); |
| 107349 | | -} |
| 107350 | | -#endif |
| 108274 | +} |
| 108275 | +#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */ |
| 107351 | 108276 | |
| 107352 | 108277 | /* |
| 107353 | 108278 | ** This function is used to estimate the number of rows that will be visited |
| 107354 | 108279 | ** by scanning an index for a range of values. The range may have an upper |
| 107355 | 108280 | ** bound, a lower bound, or both. The WHERE clause terms that set the upper |
| | @@ -107362,107 +108287,159 @@ |
| 107362 | 108287 | ** pLower pUpper |
| 107363 | 108288 | ** |
| 107364 | 108289 | ** If either of the upper or lower bound is not present, then NULL is passed in |
| 107365 | 108290 | ** place of the corresponding WhereTerm. |
| 107366 | 108291 | ** |
| 107367 | | -** The nEq parameter is passed the index of the index column subject to the |
| 107368 | | -** range constraint. Or, equivalently, the number of equality constraints |
| 107369 | | -** optimized by the proposed index scan. For example, assuming index p is |
| 107370 | | -** on t1(a, b), and the SQL query is: |
| 108292 | +** The value in (pBuilder->pNew->u.btree.nEq) is the index of the index |
| 108293 | +** column subject to the range constraint. Or, equivalently, the number of |
| 108294 | +** equality constraints optimized by the proposed index scan. For example, |
| 108295 | +** assuming index p is on t1(a, b), and the SQL query is: |
| 107371 | 108296 | ** |
| 107372 | 108297 | ** ... FROM t1 WHERE a = ? AND b > ? AND b < ? ... |
| 107373 | 108298 | ** |
| 107374 | | -** then nEq should be passed the value 1 (as the range restricted column, |
| 107375 | | -** b, is the second left-most column of the index). Or, if the query is: |
| 108299 | +** then nEq is set to 1 (as the range restricted column, b, is the second |
| 108300 | +** left-most column of the index). Or, if the query is: |
| 107376 | 108301 | ** |
| 107377 | 108302 | ** ... FROM t1 WHERE a > ? AND a < ? ... |
| 107378 | 108303 | ** |
| 107379 | | -** then nEq should be passed 0. |
| 107380 | | -** |
| 107381 | | -** The returned value is an integer divisor to reduce the estimated |
| 107382 | | -** search space. A return value of 1 means that range constraints are |
| 107383 | | -** no help at all. A return value of 2 means range constraints are |
| 107384 | | -** expected to reduce the search space by half. And so forth... |
| 107385 | | -** |
| 107386 | | -** In the absence of sqlite_stat3 ANALYZE data, each range inequality |
| 107387 | | -** reduces the search space by a factor of 4. Hence a single constraint (x>?) |
| 107388 | | -** results in a return of 4 and a range constraint (x>? AND x<?) results |
| 107389 | | -** in a return of 16. |
| 108304 | +** then nEq is set to 0. |
| 108305 | +** |
| 108306 | +** When this function is called, *pnOut is set to the whereCost() of the |
| 108307 | +** number of rows that the index scan is expected to visit without |
| 108308 | +** considering the range constraints. If nEq is 0, this is the number of |
| 108309 | +** rows in the index. Assuming no error occurs, *pnOut is adjusted (reduced) |
| 108310 | +** to account for the range contraints pLower and pUpper. |
| 108311 | +** |
| 108312 | +** In the absence of sqlite_stat4 ANALYZE data, or if such data cannot be |
| 108313 | +** used, each range inequality reduces the search space by a factor of 4. |
| 108314 | +** Hence a pair of constraints (x>? AND x<?) reduces the expected number of |
| 108315 | +** rows visited by a factor of 16. |
| 107390 | 108316 | */ |
| 107391 | 108317 | static int whereRangeScanEst( |
| 107392 | 108318 | Parse *pParse, /* Parsing & code generating context */ |
| 107393 | | - Index *p, /* The index containing the range-compared column; "x" */ |
| 107394 | | - int nEq, /* index into p->aCol[] of the range-compared column */ |
| 108319 | + WhereLoopBuilder *pBuilder, |
| 107395 | 108320 | WhereTerm *pLower, /* Lower bound on the range. ex: "x>123" Might be NULL */ |
| 107396 | 108321 | WhereTerm *pUpper, /* Upper bound on the range. ex: "x<455" Might be NULL */ |
| 107397 | | - WhereCost *pRangeDiv /* OUT: Reduce search space by this divisor */ |
| 108322 | + WhereCost *pnOut /* IN/OUT: Number of rows visited */ |
| 107398 | 108323 | ){ |
| 107399 | 108324 | int rc = SQLITE_OK; |
| 108325 | + int nOut = (int)*pnOut; |
| 107400 | 108326 | |
| 107401 | | -#ifdef SQLITE_ENABLE_STAT3 |
| 108327 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 108328 | + Index *p = pBuilder->pNew->u.btree.pIndex; |
| 108329 | + int nEq = pBuilder->pNew->u.btree.nEq; |
| 107402 | 108330 | |
| 107403 | | - if( nEq==0 && p->nSample && OptimizationEnabled(pParse->db, SQLITE_Stat3) ){ |
| 107404 | | - sqlite3_value *pRangeVal; |
| 107405 | | - tRowcnt iLower = 0; |
| 107406 | | - tRowcnt iUpper = p->aiRowEst[0]; |
| 108331 | + if( nEq==pBuilder->nRecValid |
| 108332 | + && nEq<p->nSampleCol |
| 108333 | + && p->nSample |
| 108334 | + && OptimizationEnabled(pParse->db, SQLITE_Stat3) |
| 108335 | + ){ |
| 108336 | + UnpackedRecord *pRec = pBuilder->pRec; |
| 107407 | 108337 | tRowcnt a[2]; |
| 107408 | | - u8 aff = p->pTable->aCol[p->aiColumn[0]].affinity; |
| 108338 | + u8 aff; |
| 107409 | 108339 | |
| 108340 | + /* Variable iLower will be set to the estimate of the number of rows in |
| 108341 | + ** the index that are less than the lower bound of the range query. The |
| 108342 | + ** lower bound being the concatenation of $P and $L, where $P is the |
| 108343 | + ** key-prefix formed by the nEq values matched against the nEq left-most |
| 108344 | + ** columns of the index, and $L is the value in pLower. |
| 108345 | + ** |
| 108346 | + ** Or, if pLower is NULL or $L cannot be extracted from it (because it |
| 108347 | + ** is not a simple variable or literal value), the lower bound of the |
| 108348 | + ** range is $P. Due to a quirk in the way whereKeyStats() works, even |
| 108349 | + ** if $L is available, whereKeyStats() is called for both ($P) and |
| 108350 | + ** ($P:$L) and the larger of the two returned values used. |
| 108351 | + ** |
| 108352 | + ** Similarly, iUpper is to be set to the estimate of the number of rows |
| 108353 | + ** less than the upper bound of the range query. Where the upper bound |
| 108354 | + ** is either ($P) or ($P:$U). Again, even if $U is available, both values |
| 108355 | + ** of iUpper are requested of whereKeyStats() and the smaller used. |
| 108356 | + */ |
| 108357 | + tRowcnt iLower; |
| 108358 | + tRowcnt iUpper; |
| 108359 | + |
| 108360 | + if( nEq==p->nColumn ){ |
| 108361 | + aff = SQLITE_AFF_INTEGER; |
| 108362 | + }else{ |
| 108363 | + aff = p->pTable->aCol[p->aiColumn[nEq]].affinity; |
| 108364 | + } |
| 108365 | + /* Determine iLower and iUpper using ($P) only. */ |
| 108366 | + if( nEq==0 ){ |
| 108367 | + iLower = 0; |
| 108368 | + iUpper = p->aiRowEst[0]; |
| 108369 | + }else{ |
| 108370 | + /* Note: this call could be optimized away - since the same values must |
| 108371 | + ** have been requested when testing key $P in whereEqualScanEst(). */ |
| 108372 | + whereKeyStats(pParse, p, pRec, 0, a); |
| 108373 | + iLower = a[0]; |
| 108374 | + iUpper = a[0] + a[1]; |
| 108375 | + } |
| 108376 | + |
| 108377 | + /* If possible, improve on the iLower estimate using ($P:$L). */ |
| 107410 | 108378 | if( pLower ){ |
| 108379 | + int bOk; /* True if value is extracted from pExpr */ |
| 107411 | 108380 | Expr *pExpr = pLower->pExpr->pRight; |
| 107412 | | - rc = valueFromExpr(pParse, pExpr, aff, &pRangeVal); |
| 107413 | 108381 | assert( (pLower->eOperator & (WO_GT|WO_GE))!=0 ); |
| 107414 | | - if( rc==SQLITE_OK |
| 107415 | | - && whereKeyStats(pParse, p, pRangeVal, 0, a)==SQLITE_OK |
| 107416 | | - ){ |
| 107417 | | - iLower = a[0]; |
| 107418 | | - if( (pLower->eOperator & WO_GT)!=0 ) iLower += a[1]; |
| 107419 | | - } |
| 107420 | | - sqlite3ValueFree(pRangeVal); |
| 107421 | | - } |
| 107422 | | - if( rc==SQLITE_OK && pUpper ){ |
| 107423 | | - Expr *pExpr = pUpper->pExpr->pRight; |
| 107424 | | - rc = valueFromExpr(pParse, pExpr, aff, &pRangeVal); |
| 108382 | + rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, aff, nEq, &bOk); |
| 108383 | + if( rc==SQLITE_OK && bOk ){ |
| 108384 | + tRowcnt iNew; |
| 108385 | + whereKeyStats(pParse, p, pRec, 0, a); |
| 108386 | + iNew = a[0] + ((pLower->eOperator & WO_GT) ? a[1] : 0); |
| 108387 | + if( iNew>iLower ) iLower = iNew; |
| 108388 | + } |
| 108389 | + } |
| 108390 | + |
| 108391 | + /* If possible, improve on the iUpper estimate using ($P:$U). */ |
| 108392 | + if( pUpper ){ |
| 108393 | + int bOk; /* True if value is extracted from pExpr */ |
| 108394 | + Expr *pExpr = pUpper->pExpr->pRight; |
| 107425 | 108395 | assert( (pUpper->eOperator & (WO_LT|WO_LE))!=0 ); |
| 107426 | | - if( rc==SQLITE_OK |
| 107427 | | - && whereKeyStats(pParse, p, pRangeVal, 1, a)==SQLITE_OK |
| 107428 | | - ){ |
| 107429 | | - iUpper = a[0]; |
| 107430 | | - if( (pUpper->eOperator & WO_LE)!=0 ) iUpper += a[1]; |
| 107431 | | - } |
| 107432 | | - sqlite3ValueFree(pRangeVal); |
| 107433 | | - } |
| 108396 | + rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, aff, nEq, &bOk); |
| 108397 | + if( rc==SQLITE_OK && bOk ){ |
| 108398 | + tRowcnt iNew; |
| 108399 | + whereKeyStats(pParse, p, pRec, 1, a); |
| 108400 | + iNew = a[0] + ((pUpper->eOperator & WO_LE) ? a[1] : 0); |
| 108401 | + if( iNew<iUpper ) iUpper = iNew; |
| 108402 | + } |
| 108403 | + } |
| 108404 | + |
| 108405 | + pBuilder->pRec = pRec; |
| 107434 | 108406 | if( rc==SQLITE_OK ){ |
| 107435 | | - WhereCost iBase = whereCost(p->aiRowEst[0]); |
| 108407 | + WhereCost nNew; |
| 107436 | 108408 | if( iUpper>iLower ){ |
| 107437 | | - iBase -= whereCost(iUpper - iLower); |
| 108409 | + nNew = whereCost(iUpper - iLower); |
| 108410 | + }else{ |
| 108411 | + nNew = 10; assert( 10==whereCost(2) ); |
| 107438 | 108412 | } |
| 107439 | | - *pRangeDiv = iBase; |
| 107440 | | - WHERETRACE(0x100, ("range scan regions: %u..%u div=%d\n", |
| 107441 | | - (u32)iLower, (u32)iUpper, *pRangeDiv)); |
| 108413 | + if( nNew<nOut ){ |
| 108414 | + nOut = nNew; |
| 108415 | + } |
| 108416 | + *pnOut = (WhereCost)nOut; |
| 108417 | + WHERETRACE(0x100, ("range scan regions: %u..%u est=%d\n", |
| 108418 | + (u32)iLower, (u32)iUpper, nOut)); |
| 107442 | 108419 | return SQLITE_OK; |
| 107443 | 108420 | } |
| 107444 | 108421 | } |
| 107445 | 108422 | #else |
| 107446 | 108423 | UNUSED_PARAMETER(pParse); |
| 107447 | | - UNUSED_PARAMETER(p); |
| 107448 | | - UNUSED_PARAMETER(nEq); |
| 108424 | + UNUSED_PARAMETER(pBuilder); |
| 107449 | 108425 | #endif |
| 107450 | 108426 | assert( pLower || pUpper ); |
| 107451 | | - *pRangeDiv = 0; |
| 107452 | 108427 | /* TUNING: Each inequality constraint reduces the search space 4-fold. |
| 107453 | 108428 | ** A BETWEEN operator, therefore, reduces the search space 16-fold */ |
| 107454 | 108429 | if( pLower && (pLower->wtFlags & TERM_VNULL)==0 ){ |
| 107455 | | - *pRangeDiv += 20; assert( 20==whereCost(4) ); |
| 108430 | + nOut -= 20; assert( 20==whereCost(4) ); |
| 107456 | 108431 | } |
| 107457 | 108432 | if( pUpper ){ |
| 107458 | | - *pRangeDiv += 20; assert( 20==whereCost(4) ); |
| 108433 | + nOut -= 20; assert( 20==whereCost(4) ); |
| 107459 | 108434 | } |
| 108435 | + if( nOut<10 ) nOut = 10; |
| 108436 | + *pnOut = (WhereCost)nOut; |
| 107460 | 108437 | return rc; |
| 107461 | 108438 | } |
| 107462 | 108439 | |
| 107463 | | -#ifdef SQLITE_ENABLE_STAT3 |
| 108440 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 107464 | 108441 | /* |
| 107465 | 108442 | ** Estimate the number of rows that will be returned based on |
| 107466 | 108443 | ** an equality constraint x=VALUE and where that VALUE occurs in |
| 107467 | 108444 | ** the histogram data. This only works when x is the left-most |
| 107468 | 108445 | ** column of an index and sqlite_stat3 histogram data is available |
| | @@ -107478,41 +108455,57 @@ |
| 107478 | 108455 | ** for a UTF conversion required for comparison. The error is stored |
| 107479 | 108456 | ** in the pParse structure. |
| 107480 | 108457 | */ |
| 107481 | 108458 | static int whereEqualScanEst( |
| 107482 | 108459 | Parse *pParse, /* Parsing & code generating context */ |
| 107483 | | - Index *p, /* The index whose left-most column is pTerm */ |
| 108460 | + WhereLoopBuilder *pBuilder, |
| 107484 | 108461 | Expr *pExpr, /* Expression for VALUE in the x=VALUE constraint */ |
| 107485 | 108462 | tRowcnt *pnRow /* Write the revised row estimate here */ |
| 107486 | 108463 | ){ |
| 107487 | | - sqlite3_value *pRhs = 0; /* VALUE on right-hand side of pTerm */ |
| 108464 | + Index *p = pBuilder->pNew->u.btree.pIndex; |
| 108465 | + int nEq = pBuilder->pNew->u.btree.nEq; |
| 108466 | + UnpackedRecord *pRec = pBuilder->pRec; |
| 107488 | 108467 | u8 aff; /* Column affinity */ |
| 107489 | 108468 | int rc; /* Subfunction return code */ |
| 107490 | 108469 | tRowcnt a[2]; /* Statistics */ |
| 108470 | + int bOk; |
| 107491 | 108471 | |
| 108472 | + assert( nEq>=1 ); |
| 108473 | + assert( nEq<=(p->nColumn+1) ); |
| 107492 | 108474 | assert( p->aSample!=0 ); |
| 107493 | 108475 | assert( p->nSample>0 ); |
| 107494 | | - aff = p->pTable->aCol[p->aiColumn[0]].affinity; |
| 107495 | | - if( pExpr ){ |
| 107496 | | - rc = valueFromExpr(pParse, pExpr, aff, &pRhs); |
| 107497 | | - if( rc ) goto whereEqualScanEst_cancel; |
| 107498 | | - }else{ |
| 107499 | | - pRhs = sqlite3ValueNew(pParse->db); |
| 107500 | | - } |
| 107501 | | - if( pRhs==0 ) return SQLITE_NOTFOUND; |
| 107502 | | - rc = whereKeyStats(pParse, p, pRhs, 0, a); |
| 107503 | | - if( rc==SQLITE_OK ){ |
| 107504 | | - WHERETRACE(0x100,("equality scan regions: %d\n", (int)a[1])); |
| 107505 | | - *pnRow = a[1]; |
| 107506 | | - } |
| 107507 | | -whereEqualScanEst_cancel: |
| 107508 | | - sqlite3ValueFree(pRhs); |
| 108476 | + assert( pBuilder->nRecValid<nEq ); |
| 108477 | + |
| 108478 | + /* If values are not available for all fields of the index to the left |
| 108479 | + ** of this one, no estimate can be made. Return SQLITE_NOTFOUND. */ |
| 108480 | + if( pBuilder->nRecValid<(nEq-1) ){ |
| 108481 | + return SQLITE_NOTFOUND; |
| 108482 | + } |
| 108483 | + |
| 108484 | + /* This is an optimization only. The call to sqlite3Stat4ProbeSetValue() |
| 108485 | + ** below would return the same value. */ |
| 108486 | + if( nEq>p->nColumn ){ |
| 108487 | + *pnRow = 1; |
| 108488 | + return SQLITE_OK; |
| 108489 | + } |
| 108490 | + |
| 108491 | + aff = p->pTable->aCol[p->aiColumn[nEq-1]].affinity; |
| 108492 | + rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, aff, nEq-1, &bOk); |
| 108493 | + pBuilder->pRec = pRec; |
| 108494 | + if( rc!=SQLITE_OK ) return rc; |
| 108495 | + if( bOk==0 ) return SQLITE_NOTFOUND; |
| 108496 | + pBuilder->nRecValid = nEq; |
| 108497 | + |
| 108498 | + whereKeyStats(pParse, p, pRec, 0, a); |
| 108499 | + WHERETRACE(0x100,("equality scan regions: %d\n", (int)a[1])); |
| 108500 | + *pnRow = a[1]; |
| 108501 | + |
| 107509 | 108502 | return rc; |
| 107510 | 108503 | } |
| 107511 | | -#endif /* defined(SQLITE_ENABLE_STAT3) */ |
| 108504 | +#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */ |
| 107512 | 108505 | |
| 107513 | | -#ifdef SQLITE_ENABLE_STAT3 |
| 108506 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 107514 | 108507 | /* |
| 107515 | 108508 | ** Estimate the number of rows that will be returned based on |
| 107516 | 108509 | ** an IN constraint where the right-hand side of the IN operator |
| 107517 | 108510 | ** is a list of values. Example: |
| 107518 | 108511 | ** |
| | @@ -107527,33 +108520,38 @@ |
| 107527 | 108520 | ** for a UTF conversion required for comparison. The error is stored |
| 107528 | 108521 | ** in the pParse structure. |
| 107529 | 108522 | */ |
| 107530 | 108523 | static int whereInScanEst( |
| 107531 | 108524 | Parse *pParse, /* Parsing & code generating context */ |
| 107532 | | - Index *p, /* The index whose left-most column is pTerm */ |
| 108525 | + WhereLoopBuilder *pBuilder, |
| 107533 | 108526 | ExprList *pList, /* The value list on the RHS of "x IN (v1,v2,v3,...)" */ |
| 107534 | 108527 | tRowcnt *pnRow /* Write the revised row estimate here */ |
| 107535 | 108528 | ){ |
| 108529 | + Index *p = pBuilder->pNew->u.btree.pIndex; |
| 108530 | + int nRecValid = pBuilder->nRecValid; |
| 107536 | 108531 | int rc = SQLITE_OK; /* Subfunction return code */ |
| 107537 | 108532 | tRowcnt nEst; /* Number of rows for a single term */ |
| 107538 | 108533 | tRowcnt nRowEst = 0; /* New estimate of the number of rows */ |
| 107539 | 108534 | int i; /* Loop counter */ |
| 107540 | 108535 | |
| 107541 | 108536 | assert( p->aSample!=0 ); |
| 107542 | 108537 | for(i=0; rc==SQLITE_OK && i<pList->nExpr; i++){ |
| 107543 | 108538 | nEst = p->aiRowEst[0]; |
| 107544 | | - rc = whereEqualScanEst(pParse, p, pList->a[i].pExpr, &nEst); |
| 108539 | + rc = whereEqualScanEst(pParse, pBuilder, pList->a[i].pExpr, &nEst); |
| 107545 | 108540 | nRowEst += nEst; |
| 108541 | + pBuilder->nRecValid = nRecValid; |
| 107546 | 108542 | } |
| 108543 | + |
| 107547 | 108544 | if( rc==SQLITE_OK ){ |
| 107548 | 108545 | if( nRowEst > p->aiRowEst[0] ) nRowEst = p->aiRowEst[0]; |
| 107549 | 108546 | *pnRow = nRowEst; |
| 107550 | 108547 | WHERETRACE(0x100,("IN row estimate: est=%g\n", nRowEst)); |
| 107551 | 108548 | } |
| 108549 | + assert( pBuilder->nRecValid==nRecValid ); |
| 107552 | 108550 | return rc; |
| 107553 | 108551 | } |
| 107554 | | -#endif /* defined(SQLITE_ENABLE_STAT3) */ |
| 108552 | +#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */ |
| 107555 | 108553 | |
| 107556 | 108554 | /* |
| 107557 | 108555 | ** Disable a term in the WHERE clause. Except, do not disable the term |
| 107558 | 108556 | ** if it controls a LEFT OUTER JOIN and it did not originate in the ON |
| 107559 | 108557 | ** or USING clause of that join. |
| | @@ -107787,11 +108785,11 @@ |
| 107787 | 108785 | pParse->db->mallocFailed = 1; |
| 107788 | 108786 | } |
| 107789 | 108787 | |
| 107790 | 108788 | /* Evaluate the equality constraints |
| 107791 | 108789 | */ |
| 107792 | | - assert( zAff==0 || strlen(zAff)>=nEq ); |
| 108790 | + assert( zAff==0 || (int)strlen(zAff)>=nEq ); |
| 107793 | 108791 | for(j=0; j<nEq; j++){ |
| 107794 | 108792 | int r1; |
| 107795 | 108793 | pTerm = pLoop->aLTerm[j]; |
| 107796 | 108794 | assert( pTerm!=0 ); |
| 107797 | 108795 | /* The following true for indices with redundant columns. |
| | @@ -108956,19 +109954,21 @@ |
| 108956 | 109954 | assert( p->rSetup>=pTemplate->rSetup ); |
| 108957 | 109955 | |
| 108958 | 109956 | if( (p->prereq & pTemplate->prereq)==p->prereq |
| 108959 | 109957 | && p->rSetup<=pTemplate->rSetup |
| 108960 | 109958 | && p->rRun<=pTemplate->rRun |
| 109959 | + && p->nOut<=pTemplate->nOut |
| 108961 | 109960 | ){ |
| 108962 | 109961 | /* This branch taken when p is equal or better than pTemplate in |
| 108963 | | - ** all of (1) dependences (2) setup-cost, and (3) run-cost. */ |
| 109962 | + ** all of (1) dependencies (2) setup-cost, (3) run-cost, and |
| 109963 | + ** (4) number of output rows. */ |
| 108964 | 109964 | assert( p->rSetup==pTemplate->rSetup ); |
| 108965 | | - if( p->nLTerm<pTemplate->nLTerm |
| 109965 | + if( p->prereq==pTemplate->prereq |
| 109966 | + && p->nLTerm<pTemplate->nLTerm |
| 108966 | 109967 | && (p->wsFlags & WHERE_INDEXED)!=0 |
| 108967 | 109968 | && (pTemplate->wsFlags & WHERE_INDEXED)!=0 |
| 108968 | 109969 | && p->u.btree.pIndex==pTemplate->u.btree.pIndex |
| 108969 | | - && p->prereq==pTemplate->prereq |
| 108970 | 109970 | ){ |
| 108971 | 109971 | /* Overwrite an existing WhereLoop with an similar one that uses |
| 108972 | 109972 | ** more terms of the index */ |
| 108973 | 109973 | pNext = p->pNextLoop; |
| 108974 | 109974 | break; |
| | @@ -108978,15 +109978,17 @@ |
| 108978 | 109978 | goto whereLoopInsert_noop; |
| 108979 | 109979 | } |
| 108980 | 109980 | } |
| 108981 | 109981 | if( (p->prereq & pTemplate->prereq)==pTemplate->prereq |
| 108982 | 109982 | && p->rRun>=pTemplate->rRun |
| 109983 | + && p->nOut>=pTemplate->nOut |
| 108983 | 109984 | && ALWAYS(p->rSetup>=pTemplate->rSetup) /* See SETUP-INVARIANT above */ |
| 108984 | 109985 | ){ |
| 108985 | 109986 | /* Overwrite an existing WhereLoop with a better one: one that is |
| 108986 | | - ** better at one of (1) dependences, (2) setup-cost, or (3) run-cost |
| 108987 | | - ** and is no worse in any of those categories. */ |
| 109987 | + ** better at one of (1) dependencies, (2) setup-cost, (3) run-cost |
| 109988 | + ** or (4) number of output rows, and is no worse in any of those |
| 109989 | + ** categories. */ |
| 108988 | 109990 | pNext = p->pNextLoop; |
| 108989 | 109991 | break; |
| 108990 | 109992 | } |
| 108991 | 109993 | } |
| 108992 | 109994 | |
| | @@ -109094,16 +110096,22 @@ |
| 109094 | 110096 | saved_nOut = pNew->nOut; |
| 109095 | 110097 | pNew->rSetup = 0; |
| 109096 | 110098 | rLogSize = estLog(whereCost(pProbe->aiRowEst[0])); |
| 109097 | 110099 | for(; rc==SQLITE_OK && pTerm!=0; pTerm = whereScanNext(&scan)){ |
| 109098 | 110100 | int nIn = 0; |
| 109099 | | - if( pTerm->prereqRight & pNew->maskSelf ) continue; |
| 110101 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 110102 | + int nRecValid = pBuilder->nRecValid; |
| 110103 | +#endif |
| 109100 | 110104 | if( (pTerm->eOperator==WO_ISNULL || (pTerm->wtFlags&TERM_VNULL)!=0) |
| 109101 | 110105 | && (iCol<0 || pSrc->pTab->aCol[iCol].notNull) |
| 109102 | 110106 | ){ |
| 109103 | 110107 | continue; /* ignore IS [NOT] NULL constraints on NOT NULL columns */ |
| 109104 | 110108 | } |
| 110109 | + if( pTerm->prereqRight & pNew->maskSelf ) continue; |
| 110110 | + |
| 110111 | + assert( pNew->nOut==saved_nOut ); |
| 110112 | + |
| 109105 | 110113 | pNew->wsFlags = saved_wsFlags; |
| 109106 | 110114 | pNew->u.btree.nEq = saved_nEq; |
| 109107 | 110115 | pNew->nLTerm = saved_nLTerm; |
| 109108 | 110116 | if( whereLoopResize(db, pNew, pNew->nLTerm+1) ) break; /* OOM */ |
| 109109 | 110117 | pNew->aLTerm[pNew->nLTerm++] = pTerm; |
| | @@ -109156,29 +110164,34 @@ |
| 109156 | 110164 | pBtm = (pNew->wsFlags & WHERE_BTM_LIMIT)!=0 ? |
| 109157 | 110165 | pNew->aLTerm[pNew->nLTerm-2] : 0; |
| 109158 | 110166 | } |
| 109159 | 110167 | if( pNew->wsFlags & WHERE_COLUMN_RANGE ){ |
| 109160 | 110168 | /* Adjust nOut and rRun for STAT3 range values */ |
| 109161 | | - WhereCost rDiv; |
| 109162 | | - whereRangeScanEst(pParse, pProbe, pNew->u.btree.nEq, |
| 109163 | | - pBtm, pTop, &rDiv); |
| 109164 | | - pNew->nOut = saved_nOut>rDiv+10 ? saved_nOut - rDiv : 10; |
| 109165 | | - } |
| 109166 | | -#ifdef SQLITE_ENABLE_STAT3 |
| 109167 | | - if( pNew->u.btree.nEq==1 && pProbe->nSample |
| 109168 | | - && OptimizationEnabled(db, SQLITE_Stat3) ){ |
| 110169 | + assert( pNew->nOut==saved_nOut ); |
| 110170 | + whereRangeScanEst(pParse, pBuilder, pBtm, pTop, &pNew->nOut); |
| 110171 | + } |
| 110172 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 110173 | + if( nInMul==0 |
| 110174 | + && pProbe->nSample |
| 110175 | + && pNew->u.btree.nEq<=pProbe->nSampleCol |
| 110176 | + && OptimizationEnabled(db, SQLITE_Stat3) |
| 110177 | + ){ |
| 110178 | + Expr *pExpr = pTerm->pExpr; |
| 109169 | 110179 | tRowcnt nOut = 0; |
| 109170 | 110180 | if( (pTerm->eOperator & (WO_EQ|WO_ISNULL))!=0 ){ |
| 109171 | 110181 | testcase( pTerm->eOperator & WO_EQ ); |
| 109172 | 110182 | testcase( pTerm->eOperator & WO_ISNULL ); |
| 109173 | | - rc = whereEqualScanEst(pParse, pProbe, pTerm->pExpr->pRight, &nOut); |
| 110183 | + rc = whereEqualScanEst(pParse, pBuilder, pExpr->pRight, &nOut); |
| 109174 | 110184 | }else if( (pTerm->eOperator & WO_IN) |
| 109175 | | - && !ExprHasProperty(pTerm->pExpr, EP_xIsSelect) ){ |
| 109176 | | - rc = whereInScanEst(pParse, pProbe, pTerm->pExpr->x.pList, &nOut); |
| 110185 | + && !ExprHasProperty(pExpr, EP_xIsSelect) ){ |
| 110186 | + rc = whereInScanEst(pParse, pBuilder, pExpr->x.pList, &nOut); |
| 109177 | 110187 | } |
| 109178 | 110188 | assert( nOut==0 || rc==SQLITE_OK ); |
| 109179 | | - if( nOut ) pNew->nOut = whereCost(nOut); |
| 110189 | + if( nOut ){ |
| 110190 | + nOut = whereCost(nOut); |
| 110191 | + pNew->nOut = MIN(nOut, saved_nOut); |
| 110192 | + } |
| 109180 | 110193 | } |
| 109181 | 110194 | #endif |
| 109182 | 110195 | if( (pNew->wsFlags & (WHERE_IDX_ONLY|WHERE_IPK))==0 ){ |
| 109183 | 110196 | /* Each row involves a step of the index, then a binary search of |
| 109184 | 110197 | ** the main table */ |
| | @@ -109191,10 +110204,14 @@ |
| 109191 | 110204 | if( (pNew->wsFlags & WHERE_TOP_LIMIT)==0 |
| 109192 | 110205 | && pNew->u.btree.nEq<(pProbe->nColumn + (pProbe->zName!=0)) |
| 109193 | 110206 | ){ |
| 109194 | 110207 | whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, nInMul+nIn); |
| 109195 | 110208 | } |
| 110209 | + pNew->nOut = saved_nOut; |
| 110210 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 110211 | + pBuilder->nRecValid = nRecValid; |
| 110212 | +#endif |
| 109196 | 110213 | } |
| 109197 | 110214 | pNew->prereq = saved_prereq; |
| 109198 | 110215 | pNew->u.btree.nEq = saved_nEq; |
| 109199 | 110216 | pNew->wsFlags = saved_wsFlags; |
| 109200 | 110217 | pNew->nOut = saved_nOut; |
| | @@ -109420,11 +110437,17 @@ |
| 109420 | 110437 | } |
| 109421 | 110438 | rc = whereLoopInsert(pBuilder, pNew); |
| 109422 | 110439 | if( rc ) break; |
| 109423 | 110440 | } |
| 109424 | 110441 | } |
| 110442 | + |
| 109425 | 110443 | rc = whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, 0); |
| 110444 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 110445 | + sqlite3Stat4ProbeFree(pBuilder->pRec); |
| 110446 | + pBuilder->nRecValid = 0; |
| 110447 | + pBuilder->pRec = 0; |
| 110448 | +#endif |
| 109426 | 110449 | |
| 109427 | 110450 | /* If there was an INDEXED BY clause, then only that one index is |
| 109428 | 110451 | ** considered. */ |
| 109429 | 110452 | if( pSrc->pIndex ) break; |
| 109430 | 110453 | } |
| | @@ -110666,11 +111689,11 @@ |
| 110666 | 111689 | if( pWInfo->nLevel>=2 |
| 110667 | 111690 | && pResultSet!=0 |
| 110668 | 111691 | && OptimizationEnabled(db, SQLITE_OmitNoopJoin) |
| 110669 | 111692 | ){ |
| 110670 | 111693 | Bitmask tabUsed = exprListTableUsage(pMaskSet, pResultSet); |
| 110671 | | - if( pOrderBy ) tabUsed |= exprListTableUsage(pMaskSet, pOrderBy); |
| 111694 | + if( sWLB.pOrderBy ) tabUsed |= exprListTableUsage(pMaskSet, sWLB.pOrderBy); |
| 110672 | 111695 | while( pWInfo->nLevel>=2 ){ |
| 110673 | 111696 | WhereTerm *pTerm, *pEnd; |
| 110674 | 111697 | pLoop = pWInfo->a[pWInfo->nLevel-1].pWLoop; |
| 110675 | 111698 | if( (pWInfo->pTabList->a[pLoop->iTab].jointype & JT_LEFT)==0 ) break; |
| 110676 | 111699 | if( (wctrlFlags & WHERE_WANT_DISTINCT)==0 |
| | @@ -116698,18 +117721,20 @@ |
| 116698 | 117721 | case SQLITE_IOERR_SHMMAP: zName = "SQLITE_IOERR_SHMMAP"; break; |
| 116699 | 117722 | case SQLITE_IOERR_SEEK: zName = "SQLITE_IOERR_SEEK"; break; |
| 116700 | 117723 | case SQLITE_IOERR_DELETE_NOENT: zName = "SQLITE_IOERR_DELETE_NOENT";break; |
| 116701 | 117724 | case SQLITE_IOERR_MMAP: zName = "SQLITE_IOERR_MMAP"; break; |
| 116702 | 117725 | case SQLITE_IOERR_GETTEMPPATH: zName = "SQLITE_IOERR_GETTEMPPATH"; break; |
| 117726 | + case SQLITE_IOERR_CONVPATH: zName = "SQLITE_IOERR_CONVPATH"; break; |
| 116703 | 117727 | case SQLITE_CORRUPT: zName = "SQLITE_CORRUPT"; break; |
| 116704 | 117728 | case SQLITE_CORRUPT_VTAB: zName = "SQLITE_CORRUPT_VTAB"; break; |
| 116705 | 117729 | case SQLITE_NOTFOUND: zName = "SQLITE_NOTFOUND"; break; |
| 116706 | 117730 | case SQLITE_FULL: zName = "SQLITE_FULL"; break; |
| 116707 | 117731 | case SQLITE_CANTOPEN: zName = "SQLITE_CANTOPEN"; break; |
| 116708 | 117732 | case SQLITE_CANTOPEN_NOTEMPDIR: zName = "SQLITE_CANTOPEN_NOTEMPDIR";break; |
| 116709 | 117733 | case SQLITE_CANTOPEN_ISDIR: zName = "SQLITE_CANTOPEN_ISDIR"; break; |
| 116710 | 117734 | case SQLITE_CANTOPEN_FULLPATH: zName = "SQLITE_CANTOPEN_FULLPATH"; break; |
| 117735 | + case SQLITE_CANTOPEN_CONVPATH: zName = "SQLITE_CANTOPEN_CONVPATH"; break; |
| 116711 | 117736 | case SQLITE_PROTOCOL: zName = "SQLITE_PROTOCOL"; break; |
| 116712 | 117737 | case SQLITE_EMPTY: zName = "SQLITE_EMPTY"; break; |
| 116713 | 117738 | case SQLITE_SCHEMA: zName = "SQLITE_SCHEMA"; break; |
| 116714 | 117739 | case SQLITE_TOOBIG: zName = "SQLITE_TOOBIG"; break; |
| 116715 | 117740 | case SQLITE_CONSTRAINT: zName = "SQLITE_CONSTRAINT"; break; |
| 116716 | 117741 | |