Fossil SCM
Update the built-in SQLite to the version that refuses to open database files using file descriptors 0, 1, or 2.
Commit
e454de135ab734cfb78a598edc98abb8520dd800
Parent
5d60e609c2320cd…
2 files changed
+1953
-1092
+3
-3
+1953
-1092
| --- src/sqlite3.c | ||
| +++ src/sqlite3.c | ||
| @@ -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-08-29 23:36:49 30d38cc44904d93508b87e373b2f45d5f93e556b" | |
| 662 | 662 | |
| 663 | 663 | /* |
| 664 | 664 | ** CAPI3REF: Run-Time Library Version Numbers |
| 665 | 665 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 666 | 666 | ** |
| @@ -8368,10 +8368,24 @@ | ||
| 8368 | 8368 | #if SQLITE_DEFAULT_MMAP_SIZE>SQLITE_MAX_MMAP_SIZE |
| 8369 | 8369 | # undef SQLITE_DEFAULT_MMAP_SIZE |
| 8370 | 8370 | # define SQLITE_DEFAULT_MMAP_SIZE SQLITE_MAX_MMAP_SIZE |
| 8371 | 8371 | #endif |
| 8372 | 8372 | |
| 8373 | +/* | |
| 8374 | +** Only one of SQLITE_ENABLE_STAT3 or SQLITE_ENABLE_STAT4 can be defined. | |
| 8375 | +** Priority is given to SQLITE_ENABLE_STAT4. If either are defined, also | |
| 8376 | +** define SQLITE_ENABLE_STAT3_OR_STAT4 | |
| 8377 | +*/ | |
| 8378 | +#ifdef SQLITE_ENABLE_STAT4 | |
| 8379 | +# undef SQLITE_ENABLE_STAT3 | |
| 8380 | +# define SQLITE_ENABLE_STAT3_OR_STAT4 1 | |
| 8381 | +#elif SQLITE_ENABLE_STAT3 | |
| 8382 | +# define SQLITE_ENABLE_STAT3_OR_STAT4 1 | |
| 8383 | +#elif SQLITE_ENABLE_STAT3_OR_STAT4 | |
| 8384 | +# undef SQLITE_ENABLE_STAT3_OR_STAT4 | |
| 8385 | +#endif | |
| 8386 | + | |
| 8373 | 8387 | /* |
| 8374 | 8388 | ** An instance of the following structure is used to store the busy-handler |
| 8375 | 8389 | ** callback for a given sqlite handle. |
| 8376 | 8390 | ** |
| 8377 | 8391 | ** The sqlite.busyHandler member of the sqlite struct contains the busy |
| @@ -10770,13 +10784,14 @@ | ||
| 10770 | 10784 | u16 nColumn; /* Number of columns in table used by this index */ |
| 10771 | 10785 | u8 onError; /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */ |
| 10772 | 10786 | unsigned autoIndex:2; /* 1==UNIQUE, 2==PRIMARY KEY, 0==CREATE INDEX */ |
| 10773 | 10787 | unsigned bUnordered:1; /* Use this index for == or IN queries only */ |
| 10774 | 10788 | unsigned uniqNotNull:1; /* True if UNIQUE and NOT NULL for all columns */ |
| 10775 | -#ifdef SQLITE_ENABLE_STAT3 | |
| 10789 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 | |
| 10776 | 10790 | int nSample; /* Number of elements in aSample[] */ |
| 10777 | - tRowcnt avgEq; /* Average nEq value for key values not in aSample */ | |
| 10791 | + int nSampleCol; /* Size of IndexSample.anEq[] and so on */ | |
| 10792 | + tRowcnt *aAvgEq; /* Average nEq values for keys not in aSample */ | |
| 10778 | 10793 | IndexSample *aSample; /* Samples of the left-most key */ |
| 10779 | 10794 | #endif |
| 10780 | 10795 | }; |
| 10781 | 10796 | |
| 10782 | 10797 | /* |
| @@ -10783,20 +10798,15 @@ | ||
| 10783 | 10798 | ** Each sample stored in the sqlite_stat3 table is represented in memory |
| 10784 | 10799 | ** using a structure of this type. See documentation at the top of the |
| 10785 | 10800 | ** analyze.c source file for additional information. |
| 10786 | 10801 | */ |
| 10787 | 10802 | 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 */ | |
| 10803 | + void *p; /* Pointer to sampled record */ | |
| 10804 | + int n; /* Size of record in bytes */ | |
| 10805 | + tRowcnt *anEq; /* Est. number of rows where the key equals this sample */ | |
| 10806 | + tRowcnt *anLt; /* Est. number of rows where key is less than this sample */ | |
| 10807 | + tRowcnt *anDLt; /* Est. number of distinct keys less than this sample */ | |
| 10798 | 10808 | }; |
| 10799 | 10809 | |
| 10800 | 10810 | /* |
| 10801 | 10811 | ** Each token coming out of the lexer is an instance of |
| 10802 | 10812 | ** this structure. Tokens are also used as part of an expression. |
| @@ -12264,13 +12274,10 @@ | ||
| 12264 | 12274 | SQLITE_PRIVATE void sqlite3ValueSetStr(sqlite3_value*, int, const void *,u8, |
| 12265 | 12275 | void(*)(void*)); |
| 12266 | 12276 | SQLITE_PRIVATE void sqlite3ValueFree(sqlite3_value*); |
| 12267 | 12277 | SQLITE_PRIVATE sqlite3_value *sqlite3ValueNew(sqlite3 *); |
| 12268 | 12278 | 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 | 12279 | SQLITE_PRIVATE int sqlite3ValueFromExpr(sqlite3 *, Expr *, u8, u8, sqlite3_value **); |
| 12273 | 12280 | SQLITE_PRIVATE void sqlite3ValueApplyAffinity(sqlite3_value *, u8, u8); |
| 12274 | 12281 | #ifndef SQLITE_AMALGAMATION |
| 12275 | 12282 | SQLITE_PRIVATE const unsigned char sqlite3OpcodeProperty[]; |
| 12276 | 12283 | SQLITE_PRIVATE const unsigned char sqlite3UpperToLower[]; |
| @@ -12332,10 +12339,16 @@ | ||
| 12332 | 12339 | SQLITE_PRIVATE void sqlite3SelectDestInit(SelectDest*,int,int); |
| 12333 | 12340 | SQLITE_PRIVATE Expr *sqlite3CreateColumnExpr(sqlite3 *, SrcList *, int, int); |
| 12334 | 12341 | |
| 12335 | 12342 | SQLITE_PRIVATE void sqlite3BackupRestart(sqlite3_backup *); |
| 12336 | 12343 | SQLITE_PRIVATE void sqlite3BackupUpdate(sqlite3_backup *, Pgno, const u8 *); |
| 12344 | + | |
| 12345 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 | |
| 12346 | +SQLITE_PRIVATE void sqlite3AnalyzeFunctions(void); | |
| 12347 | +SQLITE_PRIVATE int sqlite3Stat4ProbeSetValue(Parse*,Index*,UnpackedRecord**,Expr*,u8,int,int*); | |
| 12348 | +SQLITE_PRIVATE void sqlite3Stat4ProbeFree(UnpackedRecord*); | |
| 12349 | +#endif | |
| 12337 | 12350 | |
| 12338 | 12351 | /* |
| 12339 | 12352 | ** The interface to the LEMON-generated parser |
| 12340 | 12353 | */ |
| 12341 | 12354 | SQLITE_PRIVATE void *sqlite3ParserAlloc(void*(*)(size_t)); |
| @@ -12916,11 +12929,13 @@ | ||
| 12916 | 12929 | "ENABLE_OVERSIZE_CELL_CHECK", |
| 12917 | 12930 | #endif |
| 12918 | 12931 | #ifdef SQLITE_ENABLE_RTREE |
| 12919 | 12932 | "ENABLE_RTREE", |
| 12920 | 12933 | #endif |
| 12921 | -#ifdef SQLITE_ENABLE_STAT3 | |
| 12934 | +#if defined(SQLITE_ENABLE_STAT4) | |
| 12935 | + "ENABLE_STAT4", | |
| 12936 | +#elif defined(SQLITE_ENABLE_STAT3) | |
| 12922 | 12937 | "ENABLE_STAT3", |
| 12923 | 12938 | #endif |
| 12924 | 12939 | #ifdef SQLITE_ENABLE_UNLOCK_NOTIFY |
| 12925 | 12940 | "ENABLE_UNLOCK_NOTIFY", |
| 12926 | 12941 | #endif |
| @@ -16075,11 +16090,11 @@ | ||
| 16075 | 16090 | struct MemBlockHdr *pHdr; |
| 16076 | 16091 | if( !p ){ |
| 16077 | 16092 | return 0; |
| 16078 | 16093 | } |
| 16079 | 16094 | pHdr = sqlite3MemsysGetHeader(p); |
| 16080 | - return pHdr->iSize; | |
| 16095 | + return (int)pHdr->iSize; | |
| 16081 | 16096 | } |
| 16082 | 16097 | |
| 16083 | 16098 | /* |
| 16084 | 16099 | ** Initialize the memory allocation subsystem. |
| 16085 | 16100 | */ |
| @@ -16117,19 +16132,19 @@ | ||
| 16117 | 16132 | static void randomFill(char *pBuf, int nByte){ |
| 16118 | 16133 | unsigned int x, y, r; |
| 16119 | 16134 | x = SQLITE_PTR_TO_INT(pBuf); |
| 16120 | 16135 | y = nByte | 1; |
| 16121 | 16136 | while( nByte >= 4 ){ |
| 16122 | - x = (x>>1) ^ (-(x&1) & 0xd0000001); | |
| 16137 | + x = (x>>1) ^ (-(int)(x&1) & 0xd0000001); | |
| 16123 | 16138 | y = y*1103515245 + 12345; |
| 16124 | 16139 | r = x ^ y; |
| 16125 | 16140 | *(int*)pBuf = r; |
| 16126 | 16141 | pBuf += 4; |
| 16127 | 16142 | nByte -= 4; |
| 16128 | 16143 | } |
| 16129 | 16144 | while( nByte-- > 0 ){ |
| 16130 | - x = (x>>1) ^ (-(x&1) & 0xd0000001); | |
| 16145 | + x = (x>>1) ^ (-(int)(x&1) & 0xd0000001); | |
| 16131 | 16146 | y = y*1103515245 + 12345; |
| 16132 | 16147 | r = x ^ y; |
| 16133 | 16148 | *(pBuf++) = r & 0xff; |
| 16134 | 16149 | } |
| 16135 | 16150 | } |
| @@ -16220,13 +16235,13 @@ | ||
| 16220 | 16235 | assert( mem.pLast==pHdr ); |
| 16221 | 16236 | mem.pLast = pHdr->pPrev; |
| 16222 | 16237 | } |
| 16223 | 16238 | z = (char*)pBt; |
| 16224 | 16239 | z -= pHdr->nTitle; |
| 16225 | - adjustStats(pHdr->iSize, -1); | |
| 16240 | + adjustStats((int)pHdr->iSize, -1); | |
| 16226 | 16241 | randomFill(z, sizeof(void*)*pHdr->nBacktraceSlots + sizeof(*pHdr) + |
| 16227 | - pHdr->iSize + sizeof(int) + pHdr->nTitle); | |
| 16242 | + (int)pHdr->iSize + sizeof(int) + pHdr->nTitle); | |
| 16228 | 16243 | free(z); |
| 16229 | 16244 | sqlite3_mutex_leave(mem.mutex); |
| 16230 | 16245 | } |
| 16231 | 16246 | |
| 16232 | 16247 | /* |
| @@ -16246,11 +16261,11 @@ | ||
| 16246 | 16261 | pOldHdr = sqlite3MemsysGetHeader(pPrior); |
| 16247 | 16262 | pNew = sqlite3MemMalloc(nByte); |
| 16248 | 16263 | if( pNew ){ |
| 16249 | 16264 | memcpy(pNew, pPrior, nByte<pOldHdr->iSize ? nByte : pOldHdr->iSize); |
| 16250 | 16265 | if( nByte>pOldHdr->iSize ){ |
| 16251 | - randomFill(&((char*)pNew)[pOldHdr->iSize], nByte - pOldHdr->iSize); | |
| 16266 | + randomFill(&((char*)pNew)[pOldHdr->iSize], nByte - (int)pOldHdr->iSize); | |
| 16252 | 16267 | } |
| 16253 | 16268 | sqlite3MemFree(pPrior); |
| 16254 | 16269 | } |
| 16255 | 16270 | return pNew; |
| 16256 | 16271 | } |
| @@ -16361,11 +16376,11 @@ | ||
| 16361 | 16376 | SQLITE_PRIVATE void sqlite3MemdebugSync(){ |
| 16362 | 16377 | struct MemBlockHdr *pHdr; |
| 16363 | 16378 | for(pHdr=mem.pFirst; pHdr; pHdr=pHdr->pNext){ |
| 16364 | 16379 | void **pBt = (void**)pHdr; |
| 16365 | 16380 | pBt -= pHdr->nBacktraceSlots; |
| 16366 | - mem.xBacktrace(pHdr->iSize, pHdr->nBacktrace-1, &pBt[1]); | |
| 16381 | + mem.xBacktrace((int)pHdr->iSize, pHdr->nBacktrace-1, &pBt[1]); | |
| 16367 | 16382 | } |
| 16368 | 16383 | } |
| 16369 | 16384 | |
| 16370 | 16385 | /* |
| 16371 | 16386 | ** Open the file indicated and write a log of all unfreed memory |
| @@ -18483,11 +18498,11 @@ | ||
| 18483 | 18498 | GetVersionEx(&sInfo); |
| 18484 | 18499 | osType = sInfo.dwPlatformId==VER_PLATFORM_WIN32_NT ? 2 : 1; |
| 18485 | 18500 | } |
| 18486 | 18501 | return osType==2; |
| 18487 | 18502 | } |
| 18488 | -#endif /* SQLITE_OS_WINCE */ | |
| 18503 | +#endif /* SQLITE_OS_WINCE || SQLITE_OS_WINRT */ | |
| 18489 | 18504 | #endif |
| 18490 | 18505 | |
| 18491 | 18506 | #ifdef SQLITE_DEBUG |
| 18492 | 18507 | /* |
| 18493 | 18508 | ** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are |
| @@ -18521,11 +18536,11 @@ | ||
| 18521 | 18536 | /* As winMutexInit() and winMutexEnd() are called as part |
| 18522 | 18537 | ** of the sqlite3_initialize and sqlite3_shutdown() |
| 18523 | 18538 | ** processing, the "interlocked" magic is probably not |
| 18524 | 18539 | ** strictly necessary. |
| 18525 | 18540 | */ |
| 18526 | -static long winMutex_lock = 0; | |
| 18541 | +static LONG winMutex_lock = 0; | |
| 18527 | 18542 | |
| 18528 | 18543 | SQLITE_API void sqlite3_win32_sleep(DWORD milliseconds); /* os_win.c */ |
| 18529 | 18544 | |
| 18530 | 18545 | static int winMutexInit(void){ |
| 18531 | 18546 | /* The first to increment to 1 does actual initialization */ |
| @@ -21082,36 +21097,10 @@ | ||
| 21082 | 21097 | assert( (m.flags & MEM_Dyn)!=0 || db->mallocFailed ); |
| 21083 | 21098 | assert( m.z || db->mallocFailed ); |
| 21084 | 21099 | return m.z; |
| 21085 | 21100 | } |
| 21086 | 21101 | |
| 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 | 21102 | /* |
| 21114 | 21103 | ** zIn is a UTF-16 encoded unicode string at least nChar characters long. |
| 21115 | 21104 | ** Return the number of bytes in the first nChar unicode characters |
| 21116 | 21105 | ** in pZ. nChar must be non-negative. |
| 21117 | 21106 | */ |
| @@ -23064,15 +23053,17 @@ | ||
| 23064 | 23053 | void *lockingContext; /* Locking style specific state */ |
| 23065 | 23054 | UnixUnusedFd *pUnused; /* Pre-allocated UnixUnusedFd */ |
| 23066 | 23055 | const char *zPath; /* Name of the file */ |
| 23067 | 23056 | unixShm *pShm; /* Shared memory segment information */ |
| 23068 | 23057 | int szChunk; /* Configured by FCNTL_CHUNK_SIZE */ |
| 23058 | +#if SQLITE_MAX_MMAP_SIZE>0 | |
| 23069 | 23059 | int nFetchOut; /* Number of outstanding xFetch refs */ |
| 23070 | 23060 | sqlite3_int64 mmapSize; /* Usable size of mapping at pMapRegion */ |
| 23071 | 23061 | sqlite3_int64 mmapSizeActual; /* Actual size of mapping at pMapRegion */ |
| 23072 | 23062 | sqlite3_int64 mmapSizeMax; /* Configured FCNTL_MMAP_SIZE value */ |
| 23073 | 23063 | void *pMapRegion; /* Memory mapped region */ |
| 23064 | +#endif | |
| 23074 | 23065 | #ifdef __QNXNTO__ |
| 23075 | 23066 | int sectorSize; /* Device sector size */ |
| 23076 | 23067 | int deviceCharacteristics; /* Precomputed device characteristics */ |
| 23077 | 23068 | #endif |
| 23078 | 23069 | #if SQLITE_ENABLE_LOCKING_STYLE |
| @@ -23503,10 +23494,11 @@ | ||
| 23503 | 23494 | #define osRmdir ((int(*)(const char*))aSyscall[19].pCurrent) |
| 23504 | 23495 | |
| 23505 | 23496 | { "fchown", (sqlite3_syscall_ptr)posixFchown, 0 }, |
| 23506 | 23497 | #define osFchown ((int(*)(int,uid_t,gid_t))aSyscall[20].pCurrent) |
| 23507 | 23498 | |
| 23499 | +#if !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0 | |
| 23508 | 23500 | { "mmap", (sqlite3_syscall_ptr)mmap, 0 }, |
| 23509 | 23501 | #define osMmap ((void*(*)(void*,size_t,int,int,int,off_t))aSyscall[21].pCurrent) |
| 23510 | 23502 | |
| 23511 | 23503 | { "munmap", (sqlite3_syscall_ptr)munmap, 0 }, |
| 23512 | 23504 | #define osMunmap ((void*(*)(void*,size_t))aSyscall[22].pCurrent) |
| @@ -23515,10 +23507,11 @@ | ||
| 23515 | 23507 | { "mremap", (sqlite3_syscall_ptr)mremap, 0 }, |
| 23516 | 23508 | #else |
| 23517 | 23509 | { "mremap", (sqlite3_syscall_ptr)0, 0 }, |
| 23518 | 23510 | #endif |
| 23519 | 23511 | #define osMremap ((void*(*)(void*,size_t,size_t,int,...))aSyscall[23].pCurrent) |
| 23512 | +#endif | |
| 23520 | 23513 | |
| 23521 | 23514 | }; /* End of the overrideable system calls */ |
| 23522 | 23515 | |
| 23523 | 23516 | /* |
| 23524 | 23517 | ** This is the xSetSystemCall() method of sqlite3_vfs for all of the |
| @@ -23600,10 +23593,35 @@ | ||
| 23600 | 23593 | for(i++; i<ArraySize(aSyscall); i++){ |
| 23601 | 23594 | if( aSyscall[i].pCurrent!=0 ) return aSyscall[i].zName; |
| 23602 | 23595 | } |
| 23603 | 23596 | return 0; |
| 23604 | 23597 | } |
| 23598 | + | |
| 23599 | +/* | |
| 23600 | +** If fd is a file descriptor that would be dangerous to use for an | |
| 23601 | +** ordinary file, the close it, reopen it as /dev/null to get it out | |
| 23602 | +** of the way, then return true. | |
| 23603 | +** | |
| 23604 | +** If fd is safe, return 0. | |
| 23605 | +** | |
| 23606 | +** It is dangerous to have a database file open of file descriptors 1 or | |
| 23607 | +** 2 because those normally mean standard output and standard error. Other | |
| 23608 | +** components of the system might write directly to those file descriptors | |
| 23609 | +** and overwrite parts of the database file. Something like this happened | |
| 23610 | +** on 2013-08-29 to the canonical Fossil repository when some error caused | |
| 23611 | +** the database file to be opened on file descriptor 2 and later an assert() | |
| 23612 | +** fired and wrote error message text into file descriptor 2, corrupting | |
| 23613 | +** the repository. | |
| 23614 | +*/ | |
| 23615 | +static int isReservedFd(int fd, const char *z, int f, int m){ | |
| 23616 | + if( fd<0 || fd>2 ) return 0; | |
| 23617 | + sqlite3_log(SQLITE_WARNING, | |
| 23618 | + "attempt to open \"%s\" as file descriptor %d", z, fd); | |
| 23619 | + osClose(fd); | |
| 23620 | + (void)osOpen("/dev/null",f,m); | |
| 23621 | + return 1; | |
| 23622 | +} | |
| 23605 | 23623 | |
| 23606 | 23624 | /* |
| 23607 | 23625 | ** Invoke open(). Do so multiple times, until it either succeeds or |
| 23608 | 23626 | ** fails for some reason other than EINTR. |
| 23609 | 23627 | ** |
| @@ -23627,11 +23645,11 @@ | ||
| 23627 | 23645 | #if defined(O_CLOEXEC) |
| 23628 | 23646 | fd = osOpen(z,f|O_CLOEXEC,m2); |
| 23629 | 23647 | #else |
| 23630 | 23648 | fd = osOpen(z,f,m2); |
| 23631 | 23649 | #endif |
| 23632 | - }while( fd<0 && errno==EINTR ); | |
| 23650 | + }while( (fd<0 && errno==EINTR) || isReservedFd(fd,z,f,m2) ); | |
| 23633 | 23651 | if( fd>=0 ){ |
| 23634 | 23652 | if( m!=0 ){ |
| 23635 | 23653 | struct stat statbuf; |
| 23636 | 23654 | if( osFstat(fd, &statbuf)==0 |
| 23637 | 23655 | && statbuf.st_size==0 |
| @@ -24925,12 +24943,14 @@ | ||
| 24925 | 24943 | static int unixUnlock(sqlite3_file *id, int eFileLock){ |
| 24926 | 24944 | assert( eFileLock==SHARED_LOCK || ((unixFile *)id)->nFetchOut==0 ); |
| 24927 | 24945 | return posixUnlock(id, eFileLock, 0); |
| 24928 | 24946 | } |
| 24929 | 24947 | |
| 24948 | +#if SQLITE_MAX_MMAP_SIZE>0 | |
| 24930 | 24949 | static int unixMapfile(unixFile *pFd, i64 nByte); |
| 24931 | 24950 | static void unixUnmapfile(unixFile *pFd); |
| 24951 | +#endif | |
| 24932 | 24952 | |
| 24933 | 24953 | /* |
| 24934 | 24954 | ** This function performs the parts of the "close file" operation |
| 24935 | 24955 | ** common to all locking schemes. It closes the directory and file |
| 24936 | 24956 | ** handles, if they are valid, and sets all fields of the unixFile |
| @@ -24940,11 +24960,13 @@ | ||
| 24940 | 24960 | ** even on VxWorks. A mutex will be acquired on VxWorks by the |
| 24941 | 24961 | ** vxworksReleaseFileId() routine. |
| 24942 | 24962 | */ |
| 24943 | 24963 | static int closeUnixFile(sqlite3_file *id){ |
| 24944 | 24964 | unixFile *pFile = (unixFile*)id; |
| 24965 | +#if SQLITE_MAX_MMAP_SIZE>0 | |
| 24945 | 24966 | unixUnmapfile(pFile); |
| 24967 | +#endif | |
| 24946 | 24968 | if( pFile->h>=0 ){ |
| 24947 | 24969 | robust_close(pFile, pFile->h, __LINE__); |
| 24948 | 24970 | pFile->h = -1; |
| 24949 | 24971 | } |
| 24950 | 24972 | #if OS_VXWORKS |
| @@ -26145,10 +26167,11 @@ | ||
| 26145 | 26167 | #if (!defined(USE_PREAD) && !defined(USE_PREAD64)) |
| 26146 | 26168 | i64 newOffset; |
| 26147 | 26169 | #endif |
| 26148 | 26170 | TIMER_START; |
| 26149 | 26171 | assert( cnt==(cnt&0x1ffff) ); |
| 26172 | + assert( id->h>2 ); | |
| 26150 | 26173 | cnt &= 0x1ffff; |
| 26151 | 26174 | do{ |
| 26152 | 26175 | #if defined(USE_PREAD) |
| 26153 | 26176 | got = osPread(id->h, pBuf, cnt, offset); |
| 26154 | 26177 | SimulateIOError( got = -1 ); |
| @@ -26259,10 +26282,11 @@ | ||
| 26259 | 26282 | int *piErrno /* OUT: Error number if error occurs */ |
| 26260 | 26283 | ){ |
| 26261 | 26284 | int rc = 0; /* Value returned by system call */ |
| 26262 | 26285 | |
| 26263 | 26286 | assert( nBuf==(nBuf&0x1ffff) ); |
| 26287 | + assert( fd>2 ); | |
| 26264 | 26288 | nBuf &= 0x1ffff; |
| 26265 | 26289 | TIMER_START; |
| 26266 | 26290 | |
| 26267 | 26291 | #if defined(USE_PREAD) |
| 26268 | 26292 | do{ rc = osPwrite(fd, pBuf, nBuf, iOff); }while( rc<0 && errno==EINTR ); |
| @@ -26644,17 +26668,19 @@ | ||
| 26644 | 26668 | if( pFile->inNormalWrite && nByte==0 ){ |
| 26645 | 26669 | pFile->transCntrChng = 1; |
| 26646 | 26670 | } |
| 26647 | 26671 | #endif |
| 26648 | 26672 | |
| 26673 | +#if SQLITE_MAX_MMAP_SIZE>0 | |
| 26649 | 26674 | /* If the file was just truncated to a size smaller than the currently |
| 26650 | 26675 | ** mapped region, reduce the effective mapping size as well. SQLite will |
| 26651 | 26676 | ** use read() and write() to access data beyond this point from now on. |
| 26652 | 26677 | */ |
| 26653 | 26678 | if( nByte<pFile->mmapSize ){ |
| 26654 | 26679 | pFile->mmapSize = nByte; |
| 26655 | 26680 | } |
| 26681 | +#endif | |
| 26656 | 26682 | |
| 26657 | 26683 | return SQLITE_OK; |
| 26658 | 26684 | } |
| 26659 | 26685 | } |
| 26660 | 26686 | |
| @@ -26740,10 +26766,11 @@ | ||
| 26740 | 26766 | } |
| 26741 | 26767 | #endif |
| 26742 | 26768 | } |
| 26743 | 26769 | } |
| 26744 | 26770 | |
| 26771 | +#if SQLITE_MAX_MMAP_SIZE>0 | |
| 26745 | 26772 | if( pFile->mmapSizeMax>0 && nByte>pFile->mmapSize ){ |
| 26746 | 26773 | int rc; |
| 26747 | 26774 | if( pFile->szChunk<=0 ){ |
| 26748 | 26775 | if( robust_ftruncate(pFile->h, nByte) ){ |
| 26749 | 26776 | pFile->lastErrno = errno; |
| @@ -26752,10 +26779,11 @@ | ||
| 26752 | 26779 | } |
| 26753 | 26780 | |
| 26754 | 26781 | rc = unixMapfile(pFile, nByte); |
| 26755 | 26782 | return rc; |
| 26756 | 26783 | } |
| 26784 | +#endif | |
| 26757 | 26785 | |
| 26758 | 26786 | return SQLITE_OK; |
| 26759 | 26787 | } |
| 26760 | 26788 | |
| 26761 | 26789 | /* |
| @@ -26820,10 +26848,11 @@ | ||
| 26820 | 26848 | unixGetTempname(pFile->pVfs->mxPathname, zTFile); |
| 26821 | 26849 | *(char**)pArg = zTFile; |
| 26822 | 26850 | } |
| 26823 | 26851 | return SQLITE_OK; |
| 26824 | 26852 | } |
| 26853 | +#if SQLITE_MAX_MMAP_SIZE>0 | |
| 26825 | 26854 | case SQLITE_FCNTL_MMAP_SIZE: { |
| 26826 | 26855 | i64 newLimit = *(i64*)pArg; |
| 26827 | 26856 | int rc = SQLITE_OK; |
| 26828 | 26857 | if( newLimit>sqlite3GlobalConfig.mxMmap ){ |
| 26829 | 26858 | newLimit = sqlite3GlobalConfig.mxMmap; |
| @@ -26836,10 +26865,11 @@ | ||
| 26836 | 26865 | rc = unixMapfile(pFile, -1); |
| 26837 | 26866 | } |
| 26838 | 26867 | } |
| 26839 | 26868 | return rc; |
| 26840 | 26869 | } |
| 26870 | +#endif | |
| 26841 | 26871 | #ifdef SQLITE_DEBUG |
| 26842 | 26872 | /* The pager calls this method to signal that it has done |
| 26843 | 26873 | ** a rollback and that the database is therefore unchanged and |
| 26844 | 26874 | ** it hence it is OK for the transaction change counter to be |
| 26845 | 26875 | ** unchanged. |
| @@ -27646,26 +27676,24 @@ | ||
| 27646 | 27676 | # define unixShmLock 0 |
| 27647 | 27677 | # define unixShmBarrier 0 |
| 27648 | 27678 | # define unixShmUnmap 0 |
| 27649 | 27679 | #endif /* #ifndef SQLITE_OMIT_WAL */ |
| 27650 | 27680 | |
| 27681 | +#if SQLITE_MAX_MMAP_SIZE>0 | |
| 27651 | 27682 | /* |
| 27652 | 27683 | ** If it is currently memory mapped, unmap file pFd. |
| 27653 | 27684 | */ |
| 27654 | 27685 | static void unixUnmapfile(unixFile *pFd){ |
| 27655 | 27686 | assert( pFd->nFetchOut==0 ); |
| 27656 | -#if SQLITE_MAX_MMAP_SIZE>0 | |
| 27657 | 27687 | if( pFd->pMapRegion ){ |
| 27658 | 27688 | osMunmap(pFd->pMapRegion, pFd->mmapSizeActual); |
| 27659 | 27689 | pFd->pMapRegion = 0; |
| 27660 | 27690 | pFd->mmapSize = 0; |
| 27661 | 27691 | pFd->mmapSizeActual = 0; |
| 27662 | 27692 | } |
| 27663 | -#endif | |
| 27664 | 27693 | } |
| 27665 | 27694 | |
| 27666 | -#if SQLITE_MAX_MMAP_SIZE>0 | |
| 27667 | 27695 | /* |
| 27668 | 27696 | ** Return the system page size. |
| 27669 | 27697 | */ |
| 27670 | 27698 | static int unixGetPagesize(void){ |
| 27671 | 27699 | #if HAVE_MREMAP |
| @@ -27674,13 +27702,11 @@ | ||
| 27674 | 27702 | return getpagesize(); |
| 27675 | 27703 | #else |
| 27676 | 27704 | return (int)sysconf(_SC_PAGESIZE); |
| 27677 | 27705 | #endif |
| 27678 | 27706 | } |
| 27679 | -#endif /* SQLITE_MAX_MMAP_SIZE>0 */ | |
| 27680 | 27707 | |
| 27681 | -#if SQLITE_MAX_MMAP_SIZE>0 | |
| 27682 | 27708 | /* |
| 27683 | 27709 | ** Attempt to set the size of the memory mapping maintained by file |
| 27684 | 27710 | ** descriptor pFd to nNew bytes. Any existing mapping is discarded. |
| 27685 | 27711 | ** |
| 27686 | 27712 | ** If successful, this function sets the following variables: |
| @@ -27761,11 +27787,10 @@ | ||
| 27761 | 27787 | pFd->mmapSizeMax = 0; |
| 27762 | 27788 | } |
| 27763 | 27789 | pFd->pMapRegion = (void *)pNew; |
| 27764 | 27790 | pFd->mmapSize = pFd->mmapSizeActual = nNew; |
| 27765 | 27791 | } |
| 27766 | -#endif | |
| 27767 | 27792 | |
| 27768 | 27793 | /* |
| 27769 | 27794 | ** Memory map or remap the file opened by file-descriptor pFd (if the file |
| 27770 | 27795 | ** is already mapped, the existing mapping is replaced by the new). Or, if |
| 27771 | 27796 | ** there already exists a mapping for this file, and there are still |
| @@ -27780,11 +27805,10 @@ | ||
| 27780 | 27805 | ** SQLITE_OK is returned if no error occurs (even if the mapping is not |
| 27781 | 27806 | ** recreated as a result of outstanding references) or an SQLite error |
| 27782 | 27807 | ** code otherwise. |
| 27783 | 27808 | */ |
| 27784 | 27809 | static int unixMapfile(unixFile *pFd, i64 nByte){ |
| 27785 | -#if SQLITE_MAX_MMAP_SIZE>0 | |
| 27786 | 27810 | i64 nMap = nByte; |
| 27787 | 27811 | int rc; |
| 27788 | 27812 | |
| 27789 | 27813 | assert( nMap>=0 || pFd->nFetchOut==0 ); |
| 27790 | 27814 | if( pFd->nFetchOut>0 ) return SQLITE_OK; |
| @@ -27806,14 +27830,14 @@ | ||
| 27806 | 27830 | unixRemapfile(pFd, nMap); |
| 27807 | 27831 | }else{ |
| 27808 | 27832 | unixUnmapfile(pFd); |
| 27809 | 27833 | } |
| 27810 | 27834 | } |
| 27811 | -#endif | |
| 27812 | 27835 | |
| 27813 | 27836 | return SQLITE_OK; |
| 27814 | 27837 | } |
| 27838 | +#endif /* SQLITE_MAX_MMAP_SIZE>0 */ | |
| 27815 | 27839 | |
| 27816 | 27840 | /* |
| 27817 | 27841 | ** If possible, return a pointer to a mapping of file fd starting at offset |
| 27818 | 27842 | ** iOff. The mapping must be valid for at least nAmt bytes. |
| 27819 | 27843 | ** |
| @@ -27858,10 +27882,11 @@ | ||
| 27858 | 27882 | */ |
| 27859 | 27883 | static int unixUnfetch(sqlite3_file *fd, i64 iOff, void *p){ |
| 27860 | 27884 | unixFile *pFd = (unixFile *)fd; /* The underlying database file */ |
| 27861 | 27885 | UNUSED_PARAMETER(iOff); |
| 27862 | 27886 | |
| 27887 | +#if SQLITE_MAX_MMAP_SIZE>0 | |
| 27863 | 27888 | /* If p==0 (unmap the entire file) then there must be no outstanding |
| 27864 | 27889 | ** xFetch references. Or, if p!=0 (meaning it is an xFetch reference), |
| 27865 | 27890 | ** then there must be at least one outstanding. */ |
| 27866 | 27891 | assert( (p==0)==(pFd->nFetchOut==0) ); |
| 27867 | 27892 | |
| @@ -27873,10 +27898,11 @@ | ||
| 27873 | 27898 | }else{ |
| 27874 | 27899 | unixUnmapfile(pFd); |
| 27875 | 27900 | } |
| 27876 | 27901 | |
| 27877 | 27902 | assert( pFd->nFetchOut>=0 ); |
| 27903 | +#endif | |
| 27878 | 27904 | return SQLITE_OK; |
| 27879 | 27905 | } |
| 27880 | 27906 | |
| 27881 | 27907 | /* |
| 27882 | 27908 | ** Here ends the implementation of all sqlite3_file methods. |
| @@ -28204,11 +28230,13 @@ | ||
| 28204 | 28230 | OSTRACE(("OPEN %-3d %s\n", h, zFilename)); |
| 28205 | 28231 | pNew->h = h; |
| 28206 | 28232 | pNew->pVfs = pVfs; |
| 28207 | 28233 | pNew->zPath = zFilename; |
| 28208 | 28234 | pNew->ctrlFlags = (u8)ctrlFlags; |
| 28235 | +#if SQLITE_MAX_MMAP_SIZE>0 | |
| 28209 | 28236 | pNew->mmapSizeMax = sqlite3GlobalConfig.szMmap; |
| 28237 | +#endif | |
| 28210 | 28238 | if( sqlite3_uri_boolean(((ctrlFlags & UNIXFILE_URI) ? zFilename : 0), |
| 28211 | 28239 | "psow", SQLITE_POWERSAFE_OVERWRITE) ){ |
| 28212 | 28240 | pNew->ctrlFlags |= UNIXFILE_PSOW; |
| 28213 | 28241 | } |
| 28214 | 28242 | if( strcmp(pVfs->zName,"unix-excl")==0 ){ |
| @@ -30705,11 +30733,11 @@ | ||
| 30705 | 30733 | /* |
| 30706 | 30734 | ** Compiling and using WAL mode requires several APIs that are only |
| 30707 | 30735 | ** available in Windows platforms based on the NT kernel. |
| 30708 | 30736 | */ |
| 30709 | 30737 | #if !SQLITE_OS_WINNT && !defined(SQLITE_OMIT_WAL) |
| 30710 | -# error "WAL mode requires support from the Windows NT kernel, compile\ | |
| 30738 | +# error "WAL mode requires support from the Windows NT kernel, compile\ | |
| 30711 | 30739 | with SQLITE_OMIT_WAL." |
| 30712 | 30740 | #endif |
| 30713 | 30741 | |
| 30714 | 30742 | /* |
| 30715 | 30743 | ** Are most of the Win32 ANSI APIs available (i.e. with certain exceptions |
| @@ -30725,10 +30753,70 @@ | ||
| 30725 | 30753 | */ |
| 30726 | 30754 | #if SQLITE_OS_WINCE || SQLITE_OS_WINNT || SQLITE_OS_WINRT |
| 30727 | 30755 | # define SQLITE_WIN32_HAS_WIDE |
| 30728 | 30756 | #endif |
| 30729 | 30757 | |
| 30758 | +/* | |
| 30759 | +** Maximum pathname length (in chars) for Win32. This should normally be | |
| 30760 | +** MAX_PATH. | |
| 30761 | +*/ | |
| 30762 | +#ifndef SQLITE_WIN32_MAX_PATH_CHARS | |
| 30763 | +# define SQLITE_WIN32_MAX_PATH_CHARS (MAX_PATH) | |
| 30764 | +#endif | |
| 30765 | + | |
| 30766 | +/* | |
| 30767 | +** Maximum pathname length (in chars) for WinNT. This should normally be | |
| 30768 | +** 32767. | |
| 30769 | +*/ | |
| 30770 | +#ifndef SQLITE_WINNT_MAX_PATH_CHARS | |
| 30771 | +# define SQLITE_WINNT_MAX_PATH_CHARS (32767) | |
| 30772 | +#endif | |
| 30773 | + | |
| 30774 | +/* | |
| 30775 | +** Maximum pathname length (in bytes) for Win32. The MAX_PATH macro is in | |
| 30776 | +** characters, so we allocate 3 bytes per character assuming worst-case of | |
| 30777 | +** 4-bytes-per-character for UTF8. | |
| 30778 | +*/ | |
| 30779 | +#ifndef SQLITE_WIN32_MAX_PATH_BYTES | |
| 30780 | +# define SQLITE_WIN32_MAX_PATH_BYTES (SQLITE_WIN32_MAX_PATH_CHARS*4) | |
| 30781 | +#endif | |
| 30782 | + | |
| 30783 | +/* | |
| 30784 | +** Maximum pathname length (in bytes) for WinNT. This should normally be | |
| 30785 | +** 32767 * sizeof(WCHAR). | |
| 30786 | +*/ | |
| 30787 | +#ifndef SQLITE_WINNT_MAX_PATH_BYTES | |
| 30788 | +# define SQLITE_WINNT_MAX_PATH_BYTES \ | |
| 30789 | + (sizeof(WCHAR) * SQLITE_WINNT_MAX_PATH_CHARS) | |
| 30790 | +#endif | |
| 30791 | + | |
| 30792 | +/* | |
| 30793 | +** Maximum error message length (in chars) for WinRT. | |
| 30794 | +*/ | |
| 30795 | +#ifndef SQLITE_WIN32_MAX_ERRMSG_CHARS | |
| 30796 | +# define SQLITE_WIN32_MAX_ERRMSG_CHARS (1024) | |
| 30797 | +#endif | |
| 30798 | + | |
| 30799 | +/* | |
| 30800 | +** Returns non-zero if the character should be treated as a directory | |
| 30801 | +** separator. | |
| 30802 | +*/ | |
| 30803 | +#ifndef winIsDirSep | |
| 30804 | +# define winIsDirSep(a) (((a) == '/') || ((a) == '\\')) | |
| 30805 | +#endif | |
| 30806 | + | |
| 30807 | +/* | |
| 30808 | +** Returns the string that should be used as the directory separator. | |
| 30809 | +*/ | |
| 30810 | +#ifndef winGetDirDep | |
| 30811 | +# ifdef __CYGWIN__ | |
| 30812 | +# define winGetDirDep() "/" | |
| 30813 | +# else | |
| 30814 | +# define winGetDirDep() "\\" | |
| 30815 | +# endif | |
| 30816 | +#endif | |
| 30817 | + | |
| 30730 | 30818 | /* |
| 30731 | 30819 | ** Do we need to manually define the Win32 file mapping APIs for use with WAL |
| 30732 | 30820 | ** mode (e.g. these APIs are available in the Windows CE SDK; however, they |
| 30733 | 30821 | ** are not present in the header file)? |
| 30734 | 30822 | */ |
| @@ -31732,15 +31820,15 @@ | ||
| 31732 | 31820 | ** this routine is used to determine if the host is Win95/98/ME or |
| 31733 | 31821 | ** WinNT/2K/XP so that we will know whether or not we can safely call |
| 31734 | 31822 | ** the LockFileEx() API. |
| 31735 | 31823 | */ |
| 31736 | 31824 | #if SQLITE_OS_WINCE || SQLITE_OS_WINRT |
| 31737 | -# define isNT() (1) | |
| 31825 | +# define osIsNT() (1) | |
| 31738 | 31826 | #elif !defined(SQLITE_WIN32_HAS_WIDE) |
| 31739 | -# define isNT() (0) | |
| 31827 | +# define osIsNT() (0) | |
| 31740 | 31828 | #else |
| 31741 | - static int isNT(void){ | |
| 31829 | + static int osIsNT(void){ | |
| 31742 | 31830 | if( sqlite3_os_type==0 ){ |
| 31743 | 31831 | OSVERSIONINFOA sInfo; |
| 31744 | 31832 | sInfo.dwOSVersionInfoSize = sizeof(sInfo); |
| 31745 | 31833 | osGetVersionExA(&sInfo); |
| 31746 | 31834 | sqlite3_os_type = sInfo.dwPlatformId==VER_PLATFORM_WIN32_NT ? 2 : 1; |
| @@ -31947,11 +32035,11 @@ | ||
| 31947 | 32035 | /* |
| 31948 | 32036 | ** Convert a UTF-8 string to Microsoft Unicode (UTF-16?). |
| 31949 | 32037 | ** |
| 31950 | 32038 | ** Space to hold the returned string is obtained from malloc. |
| 31951 | 32039 | */ |
| 31952 | -static LPWSTR utf8ToUnicode(const char *zFilename){ | |
| 32040 | +static LPWSTR winUtf8ToUnicode(const char *zFilename){ | |
| 31953 | 32041 | int nChar; |
| 31954 | 32042 | LPWSTR zWideFilename; |
| 31955 | 32043 | |
| 31956 | 32044 | nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0); |
| 31957 | 32045 | if( nChar==0 ){ |
| @@ -31972,11 +32060,11 @@ | ||
| 31972 | 32060 | |
| 31973 | 32061 | /* |
| 31974 | 32062 | ** Convert Microsoft Unicode to UTF-8. Space to hold the returned string is |
| 31975 | 32063 | ** obtained from sqlite3_malloc(). |
| 31976 | 32064 | */ |
| 31977 | -static char *unicodeToUtf8(LPCWSTR zWideFilename){ | |
| 32065 | +static char *winUnicodeToUtf8(LPCWSTR zWideFilename){ | |
| 31978 | 32066 | int nByte; |
| 31979 | 32067 | char *zFilename; |
| 31980 | 32068 | |
| 31981 | 32069 | nByte = osWideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, 0, 0, 0, 0); |
| 31982 | 32070 | if( nByte == 0 ){ |
| @@ -32000,11 +32088,11 @@ | ||
| 32000 | 32088 | ** current codepage settings for file apis. |
| 32001 | 32089 | ** |
| 32002 | 32090 | ** Space to hold the returned string is obtained |
| 32003 | 32091 | ** from sqlite3_malloc. |
| 32004 | 32092 | */ |
| 32005 | -static LPWSTR mbcsToUnicode(const char *zFilename){ | |
| 32093 | +static LPWSTR winMbcsToUnicode(const char *zFilename){ | |
| 32006 | 32094 | int nByte; |
| 32007 | 32095 | LPWSTR zMbcsFilename; |
| 32008 | 32096 | int codepage = osAreFileApisANSI() ? CP_ACP : CP_OEMCP; |
| 32009 | 32097 | |
| 32010 | 32098 | nByte = osMultiByteToWideChar(codepage, 0, zFilename, -1, NULL, |
| @@ -32030,11 +32118,11 @@ | ||
| 32030 | 32118 | ** user's ANSI codepage. |
| 32031 | 32119 | ** |
| 32032 | 32120 | ** Space to hold the returned string is obtained from |
| 32033 | 32121 | ** sqlite3_malloc(). |
| 32034 | 32122 | */ |
| 32035 | -static char *unicodeToMbcs(LPCWSTR zWideFilename){ | |
| 32123 | +static char *winUnicodeToMbcs(LPCWSTR zWideFilename){ | |
| 32036 | 32124 | int nByte; |
| 32037 | 32125 | char *zFilename; |
| 32038 | 32126 | int codepage = osAreFileApisANSI() ? CP_ACP : CP_OEMCP; |
| 32039 | 32127 | |
| 32040 | 32128 | nByte = osWideCharToMultiByte(codepage, 0, zWideFilename, -1, 0, 0, 0, 0); |
| @@ -32060,15 +32148,15 @@ | ||
| 32060 | 32148 | */ |
| 32061 | 32149 | SQLITE_API char *sqlite3_win32_mbcs_to_utf8(const char *zFilename){ |
| 32062 | 32150 | char *zFilenameUtf8; |
| 32063 | 32151 | LPWSTR zTmpWide; |
| 32064 | 32152 | |
| 32065 | - zTmpWide = mbcsToUnicode(zFilename); | |
| 32153 | + zTmpWide = winMbcsToUnicode(zFilename); | |
| 32066 | 32154 | if( zTmpWide==0 ){ |
| 32067 | 32155 | return 0; |
| 32068 | 32156 | } |
| 32069 | - zFilenameUtf8 = unicodeToUtf8(zTmpWide); | |
| 32157 | + zFilenameUtf8 = winUnicodeToUtf8(zTmpWide); | |
| 32070 | 32158 | sqlite3_free(zTmpWide); |
| 32071 | 32159 | return zFilenameUtf8; |
| 32072 | 32160 | } |
| 32073 | 32161 | |
| 32074 | 32162 | /* |
| @@ -32077,15 +32165,15 @@ | ||
| 32077 | 32165 | */ |
| 32078 | 32166 | SQLITE_API char *sqlite3_win32_utf8_to_mbcs(const char *zFilename){ |
| 32079 | 32167 | char *zFilenameMbcs; |
| 32080 | 32168 | LPWSTR zTmpWide; |
| 32081 | 32169 | |
| 32082 | - zTmpWide = utf8ToUnicode(zFilename); | |
| 32170 | + zTmpWide = winUtf8ToUnicode(zFilename); | |
| 32083 | 32171 | if( zTmpWide==0 ){ |
| 32084 | 32172 | return 0; |
| 32085 | 32173 | } |
| 32086 | - zFilenameMbcs = unicodeToMbcs(zTmpWide); | |
| 32174 | + zFilenameMbcs = winUnicodeToMbcs(zTmpWide); | |
| 32087 | 32175 | sqlite3_free(zTmpWide); |
| 32088 | 32176 | return zFilenameMbcs; |
| 32089 | 32177 | } |
| 32090 | 32178 | |
| 32091 | 32179 | /* |
| @@ -32111,11 +32199,11 @@ | ||
| 32111 | 32199 | ); |
| 32112 | 32200 | assert( !ppDirectory || sqlite3MemdebugHasType(*ppDirectory, MEMTYPE_HEAP) ); |
| 32113 | 32201 | if( ppDirectory ){ |
| 32114 | 32202 | char *zValueUtf8 = 0; |
| 32115 | 32203 | if( zValue && zValue[0] ){ |
| 32116 | - zValueUtf8 = unicodeToUtf8(zValue); | |
| 32204 | + zValueUtf8 = winUnicodeToUtf8(zValue); | |
| 32117 | 32205 | if ( zValueUtf8==0 ){ |
| 32118 | 32206 | return SQLITE_NOMEM; |
| 32119 | 32207 | } |
| 32120 | 32208 | } |
| 32121 | 32209 | sqlite3_free(*ppDirectory); |
| @@ -32124,32 +32212,32 @@ | ||
| 32124 | 32212 | } |
| 32125 | 32213 | return SQLITE_ERROR; |
| 32126 | 32214 | } |
| 32127 | 32215 | |
| 32128 | 32216 | /* |
| 32129 | -** The return value of getLastErrorMsg | |
| 32217 | +** The return value of winGetLastErrorMsg | |
| 32130 | 32218 | ** is zero if the error message fits in the buffer, or non-zero |
| 32131 | 32219 | ** otherwise (if the message was truncated). |
| 32132 | 32220 | */ |
| 32133 | -static int getLastErrorMsg(DWORD lastErrno, int nBuf, char *zBuf){ | |
| 32221 | +static int winGetLastErrorMsg(DWORD lastErrno, int nBuf, char *zBuf){ | |
| 32134 | 32222 | /* FormatMessage returns 0 on failure. Otherwise it |
| 32135 | 32223 | ** returns the number of TCHARs written to the output |
| 32136 | 32224 | ** buffer, excluding the terminating null char. |
| 32137 | 32225 | */ |
| 32138 | 32226 | DWORD dwLen = 0; |
| 32139 | 32227 | char *zOut = 0; |
| 32140 | 32228 | |
| 32141 | - if( isNT() ){ | |
| 32229 | + if( osIsNT() ){ | |
| 32142 | 32230 | #if SQLITE_OS_WINRT |
| 32143 | - WCHAR zTempWide[MAX_PATH+1]; /* NOTE: Somewhat arbitrary. */ | |
| 32231 | + WCHAR zTempWide[SQLITE_WIN32_MAX_ERRMSG_CHARS+1]; | |
| 32144 | 32232 | dwLen = osFormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | |
| 32145 | 32233 | FORMAT_MESSAGE_IGNORE_INSERTS, |
| 32146 | 32234 | NULL, |
| 32147 | 32235 | lastErrno, |
| 32148 | 32236 | 0, |
| 32149 | 32237 | zTempWide, |
| 32150 | - MAX_PATH, | |
| 32238 | + SQLITE_WIN32_MAX_ERRMSG_CHARS, | |
| 32151 | 32239 | 0); |
| 32152 | 32240 | #else |
| 32153 | 32241 | LPWSTR zTempWide = NULL; |
| 32154 | 32242 | dwLen = osFormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | |
| 32155 | 32243 | FORMAT_MESSAGE_FROM_SYSTEM | |
| @@ -32162,11 +32250,11 @@ | ||
| 32162 | 32250 | 0); |
| 32163 | 32251 | #endif |
| 32164 | 32252 | if( dwLen > 0 ){ |
| 32165 | 32253 | /* allocate a buffer and convert to UTF8 */ |
| 32166 | 32254 | sqlite3BeginBenignMalloc(); |
| 32167 | - zOut = unicodeToUtf8(zTempWide); | |
| 32255 | + zOut = winUnicodeToUtf8(zTempWide); | |
| 32168 | 32256 | sqlite3EndBenignMalloc(); |
| 32169 | 32257 | #if !SQLITE_OS_WINRT |
| 32170 | 32258 | /* free the system buffer allocated by FormatMessage */ |
| 32171 | 32259 | osLocalFree(zTempWide); |
| 32172 | 32260 | #endif |
| @@ -32230,11 +32318,11 @@ | ||
| 32230 | 32318 | ){ |
| 32231 | 32319 | char zMsg[500]; /* Human readable error text */ |
| 32232 | 32320 | int i; /* Loop counter */ |
| 32233 | 32321 | |
| 32234 | 32322 | zMsg[0] = 0; |
| 32235 | - getLastErrorMsg(lastErrno, sizeof(zMsg), zMsg); | |
| 32323 | + winGetLastErrorMsg(lastErrno, sizeof(zMsg), zMsg); | |
| 32236 | 32324 | assert( errcode!=SQLITE_OK ); |
| 32237 | 32325 | if( zPath==0 ) zPath = ""; |
| 32238 | 32326 | for(i=0; zMsg[i] && zMsg[i]!='\r' && zMsg[i]!='\n'; i++){} |
| 32239 | 32327 | zMsg[i] = 0; |
| 32240 | 32328 | sqlite3_log(errcode, |
| @@ -32255,30 +32343,30 @@ | ||
| 32255 | 32343 | # define SQLITE_WIN32_IOERR_RETRY 10 |
| 32256 | 32344 | #endif |
| 32257 | 32345 | #ifndef SQLITE_WIN32_IOERR_RETRY_DELAY |
| 32258 | 32346 | # define SQLITE_WIN32_IOERR_RETRY_DELAY 25 |
| 32259 | 32347 | #endif |
| 32260 | -static int win32IoerrRetry = SQLITE_WIN32_IOERR_RETRY; | |
| 32261 | -static int win32IoerrRetryDelay = SQLITE_WIN32_IOERR_RETRY_DELAY; | |
| 32348 | +static int winIoerrRetry = SQLITE_WIN32_IOERR_RETRY; | |
| 32349 | +static int winIoerrRetryDelay = SQLITE_WIN32_IOERR_RETRY_DELAY; | |
| 32262 | 32350 | |
| 32263 | 32351 | /* |
| 32264 | 32352 | ** If a ReadFile() or WriteFile() error occurs, invoke this routine |
| 32265 | 32353 | ** to see if it should be retried. Return TRUE to retry. Return FALSE |
| 32266 | 32354 | ** to give up with an error. |
| 32267 | 32355 | */ |
| 32268 | -static int retryIoerr(int *pnRetry, DWORD *pError){ | |
| 32356 | +static int winRetryIoerr(int *pnRetry, DWORD *pError){ | |
| 32269 | 32357 | DWORD e = osGetLastError(); |
| 32270 | - if( *pnRetry>=win32IoerrRetry ){ | |
| 32358 | + if( *pnRetry>=winIoerrRetry ){ | |
| 32271 | 32359 | if( pError ){ |
| 32272 | 32360 | *pError = e; |
| 32273 | 32361 | } |
| 32274 | 32362 | return 0; |
| 32275 | 32363 | } |
| 32276 | 32364 | if( e==ERROR_ACCESS_DENIED || |
| 32277 | 32365 | e==ERROR_LOCK_VIOLATION || |
| 32278 | 32366 | e==ERROR_SHARING_VIOLATION ){ |
| 32279 | - sqlite3_win32_sleep(win32IoerrRetryDelay*(1+*pnRetry)); | |
| 32367 | + sqlite3_win32_sleep(winIoerrRetryDelay*(1+*pnRetry)); | |
| 32280 | 32368 | ++*pnRetry; |
| 32281 | 32369 | return 1; |
| 32282 | 32370 | } |
| 32283 | 32371 | if( pError ){ |
| 32284 | 32372 | *pError = e; |
| @@ -32287,15 +32375,15 @@ | ||
| 32287 | 32375 | } |
| 32288 | 32376 | |
| 32289 | 32377 | /* |
| 32290 | 32378 | ** Log a I/O error retry episode. |
| 32291 | 32379 | */ |
| 32292 | -static void logIoerr(int nRetry){ | |
| 32380 | +static void winLogIoerr(int nRetry){ | |
| 32293 | 32381 | if( nRetry ){ |
| 32294 | 32382 | sqlite3_log(SQLITE_IOERR, |
| 32295 | 32383 | "delayed %dms for lock/sharing conflict", |
| 32296 | - win32IoerrRetryDelay*nRetry*(nRetry+1)/2 | |
| 32384 | + winIoerrRetryDelay*nRetry*(nRetry+1)/2 | |
| 32297 | 32385 | ); |
| 32298 | 32386 | } |
| 32299 | 32387 | } |
| 32300 | 32388 | |
| 32301 | 32389 | #if SQLITE_OS_WINCE |
| @@ -32356,11 +32444,11 @@ | ||
| 32356 | 32444 | LPWSTR zName; |
| 32357 | 32445 | DWORD lastErrno; |
| 32358 | 32446 | BOOL bLogged = FALSE; |
| 32359 | 32447 | BOOL bInit = TRUE; |
| 32360 | 32448 | |
| 32361 | - zName = utf8ToUnicode(zFilename); | |
| 32449 | + zName = winUtf8ToUnicode(zFilename); | |
| 32362 | 32450 | if( zName==0 ){ |
| 32363 | 32451 | /* out of memory */ |
| 32364 | 32452 | return SQLITE_IOERR_NOMEM; |
| 32365 | 32453 | } |
| 32366 | 32454 | |
| @@ -32629,11 +32717,11 @@ | ||
| 32629 | 32717 | ** API LockFile. |
| 32630 | 32718 | */ |
| 32631 | 32719 | return winceLockFile(phFile, offsetLow, offsetHigh, |
| 32632 | 32720 | numBytesLow, numBytesHigh); |
| 32633 | 32721 | #else |
| 32634 | - if( isNT() ){ | |
| 32722 | + if( osIsNT() ){ | |
| 32635 | 32723 | OVERLAPPED ovlp; |
| 32636 | 32724 | memset(&ovlp, 0, sizeof(OVERLAPPED)); |
| 32637 | 32725 | ovlp.Offset = offsetLow; |
| 32638 | 32726 | ovlp.OffsetHigh = offsetHigh; |
| 32639 | 32727 | return osLockFileEx(*phFile, flags, 0, numBytesLow, numBytesHigh, &ovlp); |
| @@ -32660,11 +32748,11 @@ | ||
| 32660 | 32748 | ** API UnlockFile. |
| 32661 | 32749 | */ |
| 32662 | 32750 | return winceUnlockFile(phFile, offsetLow, offsetHigh, |
| 32663 | 32751 | numBytesLow, numBytesHigh); |
| 32664 | 32752 | #else |
| 32665 | - if( isNT() ){ | |
| 32753 | + if( osIsNT() ){ | |
| 32666 | 32754 | OVERLAPPED ovlp; |
| 32667 | 32755 | memset(&ovlp, 0, sizeof(OVERLAPPED)); |
| 32668 | 32756 | ovlp.Offset = offsetLow; |
| 32669 | 32757 | ovlp.OffsetHigh = offsetHigh; |
| 32670 | 32758 | return osUnlockFileEx(*phFile, 0, numBytesLow, numBytesHigh, &ovlp); |
| @@ -32690,11 +32778,11 @@ | ||
| 32690 | 32778 | /* |
| 32691 | 32779 | ** Move the current position of the file handle passed as the first |
| 32692 | 32780 | ** argument to offset iOffset within the file. If successful, return 0. |
| 32693 | 32781 | ** Otherwise, set pFile->lastErrno and return non-zero. |
| 32694 | 32782 | */ |
| 32695 | -static int seekWinFile(winFile *pFile, sqlite3_int64 iOffset){ | |
| 32783 | +static int winSeekFile(winFile *pFile, sqlite3_int64 iOffset){ | |
| 32696 | 32784 | #if !SQLITE_OS_WINRT |
| 32697 | 32785 | LONG upperBits; /* Most sig. 32 bits of new offset */ |
| 32698 | 32786 | LONG lowerBits; /* Least sig. 32 bits of new offset */ |
| 32699 | 32787 | DWORD dwRet; /* Value returned by SetFilePointer() */ |
| 32700 | 32788 | DWORD lastErrno; /* Value returned by GetLastError() */ |
| @@ -32715,11 +32803,11 @@ | ||
| 32715 | 32803 | |
| 32716 | 32804 | if( (dwRet==INVALID_SET_FILE_POINTER |
| 32717 | 32805 | && ((lastErrno = osGetLastError())!=NO_ERROR)) ){ |
| 32718 | 32806 | pFile->lastErrno = lastErrno; |
| 32719 | 32807 | winLogError(SQLITE_IOERR_SEEK, pFile->lastErrno, |
| 32720 | - "seekWinFile", pFile->zPath); | |
| 32808 | + "winSeekFile", pFile->zPath); | |
| 32721 | 32809 | OSTRACE(("SEEK file=%p, rc=SQLITE_IOERR_SEEK\n", pFile->h)); |
| 32722 | 32810 | return 1; |
| 32723 | 32811 | } |
| 32724 | 32812 | |
| 32725 | 32813 | OSTRACE(("SEEK file=%p, rc=SQLITE_OK\n", pFile->h)); |
| @@ -32736,11 +32824,11 @@ | ||
| 32736 | 32824 | bRet = osSetFilePointerEx(pFile->h, x, 0, FILE_BEGIN); |
| 32737 | 32825 | |
| 32738 | 32826 | if(!bRet){ |
| 32739 | 32827 | pFile->lastErrno = osGetLastError(); |
| 32740 | 32828 | winLogError(SQLITE_IOERR_SEEK, pFile->lastErrno, |
| 32741 | - "seekWinFile", pFile->zPath); | |
| 32829 | + "winSeekFile", pFile->zPath); | |
| 32742 | 32830 | OSTRACE(("SEEK file=%p, rc=SQLITE_IOERR_SEEK\n", pFile->h)); |
| 32743 | 32831 | return 1; |
| 32744 | 32832 | } |
| 32745 | 32833 | |
| 32746 | 32834 | OSTRACE(("SEEK file=%p, rc=SQLITE_OK\n", pFile->h)); |
| @@ -32851,11 +32939,11 @@ | ||
| 32851 | 32939 | } |
| 32852 | 32940 | } |
| 32853 | 32941 | #endif |
| 32854 | 32942 | |
| 32855 | 32943 | #if SQLITE_OS_WINCE |
| 32856 | - if( seekWinFile(pFile, offset) ){ | |
| 32944 | + if( winSeekFile(pFile, offset) ){ | |
| 32857 | 32945 | OSTRACE(("READ file=%p, rc=SQLITE_FULL\n", pFile->h)); |
| 32858 | 32946 | return SQLITE_FULL; |
| 32859 | 32947 | } |
| 32860 | 32948 | while( !osReadFile(pFile->h, pBuf, amt, &nRead, 0) ){ |
| 32861 | 32949 | #else |
| @@ -32864,17 +32952,17 @@ | ||
| 32864 | 32952 | overlapped.OffsetHigh = (LONG)((offset>>32) & 0x7fffffff); |
| 32865 | 32953 | while( !osReadFile(pFile->h, pBuf, amt, &nRead, &overlapped) && |
| 32866 | 32954 | osGetLastError()!=ERROR_HANDLE_EOF ){ |
| 32867 | 32955 | #endif |
| 32868 | 32956 | DWORD lastErrno; |
| 32869 | - if( retryIoerr(&nRetry, &lastErrno) ) continue; | |
| 32957 | + if( winRetryIoerr(&nRetry, &lastErrno) ) continue; | |
| 32870 | 32958 | pFile->lastErrno = lastErrno; |
| 32871 | 32959 | OSTRACE(("READ file=%p, rc=SQLITE_IOERR_READ\n", pFile->h)); |
| 32872 | 32960 | return winLogError(SQLITE_IOERR_READ, pFile->lastErrno, |
| 32873 | 32961 | "winRead", pFile->zPath); |
| 32874 | 32962 | } |
| 32875 | - logIoerr(nRetry); | |
| 32963 | + winLogIoerr(nRetry); | |
| 32876 | 32964 | if( nRead<(DWORD)amt ){ |
| 32877 | 32965 | /* Unread parts of the buffer must be zero-filled */ |
| 32878 | 32966 | memset(&((char*)pBuf)[nRead], 0, amt-nRead); |
| 32879 | 32967 | OSTRACE(("READ file=%p, rc=SQLITE_IOERR_SHORT_READ\n", pFile->h)); |
| 32880 | 32968 | return SQLITE_IOERR_SHORT_READ; |
| @@ -32923,11 +33011,11 @@ | ||
| 32923 | 33011 | } |
| 32924 | 33012 | } |
| 32925 | 33013 | #endif |
| 32926 | 33014 | |
| 32927 | 33015 | #if SQLITE_OS_WINCE |
| 32928 | - rc = seekWinFile(pFile, offset); | |
| 33016 | + rc = winSeekFile(pFile, offset); | |
| 32929 | 33017 | if( rc==0 ){ |
| 32930 | 33018 | #else |
| 32931 | 33019 | { |
| 32932 | 33020 | #endif |
| 32933 | 33021 | #if !SQLITE_OS_WINCE |
| @@ -32948,11 +33036,11 @@ | ||
| 32948 | 33036 | #if SQLITE_OS_WINCE |
| 32949 | 33037 | if( !osWriteFile(pFile->h, aRem, nRem, &nWrite, 0) ){ |
| 32950 | 33038 | #else |
| 32951 | 33039 | if( !osWriteFile(pFile->h, aRem, nRem, &nWrite, &overlapped) ){ |
| 32952 | 33040 | #endif |
| 32953 | - if( retryIoerr(&nRetry, &lastErrno) ) continue; | |
| 33041 | + if( winRetryIoerr(&nRetry, &lastErrno) ) continue; | |
| 32954 | 33042 | break; |
| 32955 | 33043 | } |
| 32956 | 33044 | assert( nWrite==0 || nWrite<=(DWORD)nRem ); |
| 32957 | 33045 | if( nWrite==0 || nWrite>(DWORD)nRem ){ |
| 32958 | 33046 | lastErrno = osGetLastError(); |
| @@ -32980,11 +33068,11 @@ | ||
| 32980 | 33068 | } |
| 32981 | 33069 | OSTRACE(("WRITE file=%p, rc=SQLITE_IOERR_WRITE\n", pFile->h)); |
| 32982 | 33070 | return winLogError(SQLITE_IOERR_WRITE, pFile->lastErrno, |
| 32983 | 33071 | "winWrite", pFile->zPath); |
| 32984 | 33072 | }else{ |
| 32985 | - logIoerr(nRetry); | |
| 33073 | + winLogIoerr(nRetry); | |
| 32986 | 33074 | } |
| 32987 | 33075 | OSTRACE(("WRITE file=%p, rc=SQLITE_OK\n", pFile->h)); |
| 32988 | 33076 | return SQLITE_OK; |
| 32989 | 33077 | } |
| 32990 | 33078 | |
| @@ -33009,11 +33097,11 @@ | ||
| 33009 | 33097 | if( pFile->szChunk>0 ){ |
| 33010 | 33098 | nByte = ((nByte + pFile->szChunk - 1)/pFile->szChunk) * pFile->szChunk; |
| 33011 | 33099 | } |
| 33012 | 33100 | |
| 33013 | 33101 | /* SetEndOfFile() returns non-zero when successful, or zero when it fails. */ |
| 33014 | - if( seekWinFile(pFile, nByte) ){ | |
| 33102 | + if( winSeekFile(pFile, nByte) ){ | |
| 33015 | 33103 | rc = winLogError(SQLITE_IOERR_TRUNCATE, pFile->lastErrno, |
| 33016 | 33104 | "winTruncate1", pFile->zPath); |
| 33017 | 33105 | }else if( 0==osSetEndOfFile(pFile->h) && |
| 33018 | 33106 | ((lastErrno = osGetLastError())!=ERROR_USER_MAPPED_FILE) ){ |
| 33019 | 33107 | pFile->lastErrno = lastErrno; |
| @@ -33090,10 +33178,11 @@ | ||
| 33090 | 33178 | |
| 33091 | 33179 | /* If we compiled with the SQLITE_NO_SYNC flag, then syncing is a |
| 33092 | 33180 | ** no-op |
| 33093 | 33181 | */ |
| 33094 | 33182 | #ifdef SQLITE_NO_SYNC |
| 33183 | + OSTRACE(("SYNC-NOP file=%p, rc=SQLITE_OK\n", pFile->h)); | |
| 33095 | 33184 | return SQLITE_OK; |
| 33096 | 33185 | #else |
| 33097 | 33186 | rc = osFlushFileBuffers(pFile->h); |
| 33098 | 33187 | SimulateIOError( rc=FALSE ); |
| 33099 | 33188 | if( rc ){ |
| @@ -33187,14 +33276,14 @@ | ||
| 33187 | 33276 | /* |
| 33188 | 33277 | ** Acquire a reader lock. |
| 33189 | 33278 | ** Different API routines are called depending on whether or not this |
| 33190 | 33279 | ** is Win9x or WinNT. |
| 33191 | 33280 | */ |
| 33192 | -static int getReadLock(winFile *pFile){ | |
| 33281 | +static int winGetReadLock(winFile *pFile){ | |
| 33193 | 33282 | int res; |
| 33194 | 33283 | OSTRACE(("READ-LOCK file=%p, lock=%d\n", pFile->h, pFile->locktype)); |
| 33195 | - if( isNT() ){ | |
| 33284 | + if( osIsNT() ){ | |
| 33196 | 33285 | #if SQLITE_OS_WINCE |
| 33197 | 33286 | /* |
| 33198 | 33287 | ** NOTE: Windows CE is handled differently here due its lack of the Win32 |
| 33199 | 33288 | ** API LockFileEx. |
| 33200 | 33289 | */ |
| @@ -33222,15 +33311,15 @@ | ||
| 33222 | 33311 | } |
| 33223 | 33312 | |
| 33224 | 33313 | /* |
| 33225 | 33314 | ** Undo a readlock |
| 33226 | 33315 | */ |
| 33227 | -static int unlockReadLock(winFile *pFile){ | |
| 33316 | +static int winUnlockReadLock(winFile *pFile){ | |
| 33228 | 33317 | int res; |
| 33229 | 33318 | DWORD lastErrno; |
| 33230 | 33319 | OSTRACE(("READ-UNLOCK file=%p, lock=%d\n", pFile->h, pFile->locktype)); |
| 33231 | - if( isNT() ){ | |
| 33320 | + if( osIsNT() ){ | |
| 33232 | 33321 | res = winUnlockFile(&pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0); |
| 33233 | 33322 | } |
| 33234 | 33323 | #ifdef SQLITE_WIN32_HAS_ANSI |
| 33235 | 33324 | else{ |
| 33236 | 33325 | res = winUnlockFile(&pFile->h, SHARED_FIRST+pFile->sharedLockByte, 0, 1, 0); |
| @@ -33237,11 +33326,11 @@ | ||
| 33237 | 33326 | } |
| 33238 | 33327 | #endif |
| 33239 | 33328 | if( res==0 && ((lastErrno = osGetLastError())!=ERROR_NOT_LOCKED) ){ |
| 33240 | 33329 | pFile->lastErrno = lastErrno; |
| 33241 | 33330 | winLogError(SQLITE_IOERR_UNLOCK, pFile->lastErrno, |
| 33242 | - "unlockReadLock", pFile->zPath); | |
| 33331 | + "winUnlockReadLock", pFile->zPath); | |
| 33243 | 33332 | } |
| 33244 | 33333 | OSTRACE(("READ-UNLOCK file=%p, rc=%s\n", pFile->h, sqlite3ErrName(res))); |
| 33245 | 33334 | return res; |
| 33246 | 33335 | } |
| 33247 | 33336 | |
| @@ -33328,11 +33417,11 @@ | ||
| 33328 | 33417 | |
| 33329 | 33418 | /* Acquire a shared lock |
| 33330 | 33419 | */ |
| 33331 | 33420 | if( locktype==SHARED_LOCK && res ){ |
| 33332 | 33421 | assert( pFile->locktype==NO_LOCK ); |
| 33333 | - res = getReadLock(pFile); | |
| 33422 | + res = winGetReadLock(pFile); | |
| 33334 | 33423 | if( res ){ |
| 33335 | 33424 | newLocktype = SHARED_LOCK; |
| 33336 | 33425 | }else{ |
| 33337 | 33426 | lastErrno = osGetLastError(); |
| 33338 | 33427 | } |
| @@ -33359,18 +33448,18 @@ | ||
| 33359 | 33448 | |
| 33360 | 33449 | /* Acquire an EXCLUSIVE lock |
| 33361 | 33450 | */ |
| 33362 | 33451 | if( locktype==EXCLUSIVE_LOCK && res ){ |
| 33363 | 33452 | assert( pFile->locktype>=SHARED_LOCK ); |
| 33364 | - res = unlockReadLock(pFile); | |
| 33453 | + res = winUnlockReadLock(pFile); | |
| 33365 | 33454 | res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS, SHARED_FIRST, 0, |
| 33366 | 33455 | SHARED_SIZE, 0); |
| 33367 | 33456 | if( res ){ |
| 33368 | 33457 | newLocktype = EXCLUSIVE_LOCK; |
| 33369 | 33458 | }else{ |
| 33370 | 33459 | lastErrno = osGetLastError(); |
| 33371 | - getReadLock(pFile); | |
| 33460 | + winGetReadLock(pFile); | |
| 33372 | 33461 | } |
| 33373 | 33462 | } |
| 33374 | 33463 | |
| 33375 | 33464 | /* If we are holding a PENDING lock that ought to be released, then |
| 33376 | 33465 | ** release it now. |
| @@ -33383,14 +33472,14 @@ | ||
| 33383 | 33472 | ** return the appropriate result code. |
| 33384 | 33473 | */ |
| 33385 | 33474 | if( res ){ |
| 33386 | 33475 | rc = SQLITE_OK; |
| 33387 | 33476 | }else{ |
| 33477 | + pFile->lastErrno = lastErrno; | |
| 33478 | + rc = SQLITE_BUSY; | |
| 33388 | 33479 | OSTRACE(("LOCK-FAIL file=%p, wanted=%d, got=%d\n", |
| 33389 | 33480 | pFile->h, locktype, newLocktype)); |
| 33390 | - pFile->lastErrno = lastErrno; | |
| 33391 | - rc = SQLITE_BUSY; | |
| 33392 | 33481 | } |
| 33393 | 33482 | pFile->locktype = (u8)newLocktype; |
| 33394 | 33483 | OSTRACE(("LOCK file=%p, lock=%d, rc=%s\n", |
| 33395 | 33484 | pFile->h, pFile->locktype, sqlite3ErrName(rc))); |
| 33396 | 33485 | return rc; |
| @@ -33446,11 +33535,11 @@ | ||
| 33446 | 33535 | OSTRACE(("UNLOCK file=%p, oldLock=%d(%d), newLock=%d\n", |
| 33447 | 33536 | pFile->h, pFile->locktype, pFile->sharedLockByte, locktype)); |
| 33448 | 33537 | type = pFile->locktype; |
| 33449 | 33538 | if( type>=EXCLUSIVE_LOCK ){ |
| 33450 | 33539 | winUnlockFile(&pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0); |
| 33451 | - if( locktype==SHARED_LOCK && !getReadLock(pFile) ){ | |
| 33540 | + if( locktype==SHARED_LOCK && !winGetReadLock(pFile) ){ | |
| 33452 | 33541 | /* This should never happen. We should always be able to |
| 33453 | 33542 | ** reacquire the read lock */ |
| 33454 | 33543 | rc = winLogError(SQLITE_IOERR_UNLOCK, osGetLastError(), |
| 33455 | 33544 | "winUnlock", pFile->zPath); |
| 33456 | 33545 | } |
| @@ -33457,11 +33546,11 @@ | ||
| 33457 | 33546 | } |
| 33458 | 33547 | if( type>=RESERVED_LOCK ){ |
| 33459 | 33548 | winUnlockFile(&pFile->h, RESERVED_BYTE, 0, 1, 0); |
| 33460 | 33549 | } |
| 33461 | 33550 | if( locktype==NO_LOCK && type>=SHARED_LOCK ){ |
| 33462 | - unlockReadLock(pFile); | |
| 33551 | + winUnlockReadLock(pFile); | |
| 33463 | 33552 | } |
| 33464 | 33553 | if( type>=PENDING_LOCK ){ |
| 33465 | 33554 | winUnlockFile(&pFile->h, PENDING_BYTE, 0, 1, 0); |
| 33466 | 33555 | } |
| 33467 | 33556 | pFile->locktype = (u8)locktype; |
| @@ -33485,11 +33574,11 @@ | ||
| 33485 | 33574 | pFile->ctrlFlags |= mask; |
| 33486 | 33575 | } |
| 33487 | 33576 | } |
| 33488 | 33577 | |
| 33489 | 33578 | /* Forward declaration */ |
| 33490 | -static int getTempname(int nBuf, char *zBuf); | |
| 33579 | +static int winGetTempname(sqlite3_vfs *, char **); | |
| 33491 | 33580 | #if SQLITE_MAX_MMAP_SIZE>0 |
| 33492 | 33581 | static int winMapfile(winFile*, sqlite3_int64); |
| 33493 | 33582 | #endif |
| 33494 | 33583 | |
| 33495 | 33584 | /* |
| @@ -33548,30 +33637,30 @@ | ||
| 33548 | 33637 | return SQLITE_OK; |
| 33549 | 33638 | } |
| 33550 | 33639 | case SQLITE_FCNTL_WIN32_AV_RETRY: { |
| 33551 | 33640 | int *a = (int*)pArg; |
| 33552 | 33641 | if( a[0]>0 ){ |
| 33553 | - win32IoerrRetry = a[0]; | |
| 33642 | + winIoerrRetry = a[0]; | |
| 33554 | 33643 | }else{ |
| 33555 | - a[0] = win32IoerrRetry; | |
| 33644 | + a[0] = winIoerrRetry; | |
| 33556 | 33645 | } |
| 33557 | 33646 | if( a[1]>0 ){ |
| 33558 | - win32IoerrRetryDelay = a[1]; | |
| 33647 | + winIoerrRetryDelay = a[1]; | |
| 33559 | 33648 | }else{ |
| 33560 | - a[1] = win32IoerrRetryDelay; | |
| 33649 | + a[1] = winIoerrRetryDelay; | |
| 33561 | 33650 | } |
| 33562 | 33651 | OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); |
| 33563 | 33652 | return SQLITE_OK; |
| 33564 | 33653 | } |
| 33565 | 33654 | case SQLITE_FCNTL_TEMPFILENAME: { |
| 33566 | - char *zTFile = sqlite3MallocZero( pFile->pVfs->mxPathname ); | |
| 33567 | - if( zTFile ){ | |
| 33568 | - getTempname(pFile->pVfs->mxPathname, zTFile); | |
| 33655 | + char *zTFile = 0; | |
| 33656 | + int rc = winGetTempname(pFile->pVfs, &zTFile); | |
| 33657 | + if( rc==SQLITE_OK ){ | |
| 33569 | 33658 | *(char**)pArg = zTFile; |
| 33570 | 33659 | } |
| 33571 | - OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); | |
| 33572 | - return SQLITE_OK; | |
| 33660 | + OSTRACE(("FCNTL file=%p, rc=%d\n", pFile->h, rc)); | |
| 33661 | + return rc; | |
| 33573 | 33662 | } |
| 33574 | 33663 | #if SQLITE_MAX_MMAP_SIZE>0 |
| 33575 | 33664 | case SQLITE_FCNTL_MMAP_SIZE: { |
| 33576 | 33665 | i64 newLimit = *(i64*)pArg; |
| 33577 | 33666 | int rc = SQLITE_OK; |
| @@ -34529,14 +34618,14 @@ | ||
| 34529 | 34618 | ** Convert a UTF-8 filename into whatever form the underlying |
| 34530 | 34619 | ** operating system wants filenames in. Space to hold the result |
| 34531 | 34620 | ** is obtained from malloc and must be freed by the calling |
| 34532 | 34621 | ** function. |
| 34533 | 34622 | */ |
| 34534 | -static void *convertUtf8Filename(const char *zFilename){ | |
| 34623 | +static void *winConvertUtf8Filename(const char *zFilename){ | |
| 34535 | 34624 | void *zConverted = 0; |
| 34536 | - if( isNT() ){ | |
| 34537 | - zConverted = utf8ToUnicode(zFilename); | |
| 34625 | + if( osIsNT() ){ | |
| 34626 | + zConverted = winUtf8ToUnicode(zFilename); | |
| 34538 | 34627 | } |
| 34539 | 34628 | #ifdef SQLITE_WIN32_HAS_ANSI |
| 34540 | 34629 | else{ |
| 34541 | 34630 | zConverted = sqlite3_win32_utf8_to_mbcs(zFilename); |
| 34542 | 34631 | } |
| @@ -34544,117 +34633,135 @@ | ||
| 34544 | 34633 | /* caller will handle out of memory */ |
| 34545 | 34634 | return zConverted; |
| 34546 | 34635 | } |
| 34547 | 34636 | |
| 34548 | 34637 | /* |
| 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. | |
| 34638 | +** This function returns non-zero if the specified UTF-8 string buffer | |
| 34639 | +** ends with a directory separator character. | |
| 34552 | 34640 | */ |
| 34553 | -#ifndef SQLITE_WIN32_MAX_PATH | |
| 34554 | -# define SQLITE_WIN32_MAX_PATH (MAX_PATH*3) | |
| 34555 | -#endif | |
| 34641 | +static int winEndsInDirSep(char *zBuf){ | |
| 34642 | + if( zBuf ){ | |
| 34643 | + int nLen = sqlite3Strlen30(zBuf); | |
| 34644 | + return nLen>0 && winIsDirSep(zBuf[nLen-1]); | |
| 34645 | + } | |
| 34646 | + return 0; | |
| 34647 | +} | |
| 34556 | 34648 | |
| 34557 | 34649 | /* |
| 34558 | -** Create a temporary file name in zBuf. zBuf must be big enough to | |
| 34559 | -** hold at pVfs->mxPathname characters. | |
| 34650 | +** Create a temporary file name and store the resulting pointer into pzBuf. | |
| 34651 | +** The pointer returned in pzBuf must be freed via sqlite3_free(). | |
| 34560 | 34652 | */ |
| 34561 | -static int getTempname(int nBuf, char *zBuf){ | |
| 34653 | +static int winGetTempname(sqlite3_vfs *pVfs, char **pzBuf){ | |
| 34562 | 34654 | static char zChars[] = |
| 34563 | 34655 | "abcdefghijklmnopqrstuvwxyz" |
| 34564 | 34656 | "ABCDEFGHIJKLMNOPQRSTUVWXYZ" |
| 34565 | 34657 | "0123456789"; |
| 34566 | 34658 | size_t i, j; |
| 34567 | - int nTempPath; | |
| 34568 | - char zTempPath[SQLITE_WIN32_MAX_PATH+2]; | |
| 34659 | + int nBuf, nLen; | |
| 34660 | + char *zBuf; | |
| 34569 | 34661 | |
| 34570 | 34662 | /* It's odd to simulate an io-error here, but really this is just |
| 34571 | 34663 | ** using the io-error infrastructure to test that SQLite handles this |
| 34572 | 34664 | ** function failing. |
| 34573 | 34665 | */ |
| 34574 | 34666 | SimulateIOError( return SQLITE_IOERR ); |
| 34575 | 34667 | |
| 34668 | + /* Allocate a temporary buffer to store the fully qualified file | |
| 34669 | + ** name for the temporary file. If this fails, we cannot continue. | |
| 34670 | + */ | |
| 34671 | + nBuf = pVfs->mxPathname; | |
| 34672 | + zBuf = sqlite3MallocZero( nBuf+2 ); | |
| 34673 | + if( !zBuf ){ | |
| 34674 | + OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); | |
| 34675 | + return SQLITE_IOERR_NOMEM; | |
| 34676 | + } | |
| 34677 | + | |
| 34678 | + /* Figure out the effective temporary directory. First, check if one | |
| 34679 | + ** has been explicitly set by the application; otherwise, use the one | |
| 34680 | + ** configured by the operating system. | |
| 34681 | + */ | |
| 34682 | + assert( nBuf>30 ); | |
| 34576 | 34683 | if( sqlite3_temp_directory ){ |
| 34577 | - sqlite3_snprintf(SQLITE_WIN32_MAX_PATH-30, zTempPath, "%s", | |
| 34578 | - sqlite3_temp_directory); | |
| 34684 | + sqlite3_snprintf(nBuf-30, zBuf, "%s%s", sqlite3_temp_directory, | |
| 34685 | + winEndsInDirSep(sqlite3_temp_directory) ? "" : | |
| 34686 | + winGetDirDep()); | |
| 34579 | 34687 | } |
| 34580 | 34688 | #if !SQLITE_OS_WINRT |
| 34581 | - else if( isNT() ){ | |
| 34689 | + else if( osIsNT() ){ | |
| 34582 | 34690 | char *zMulti; |
| 34583 | - WCHAR zWidePath[MAX_PATH]; | |
| 34584 | - if( osGetTempPathW(MAX_PATH-30, zWidePath)==0 ){ | |
| 34691 | + LPWSTR zWidePath = sqlite3MallocZero( nBuf*sizeof(WCHAR) ); | |
| 34692 | + if( !zWidePath ){ | |
| 34693 | + sqlite3_free(zBuf); | |
| 34694 | + OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); | |
| 34695 | + return SQLITE_IOERR_NOMEM; | |
| 34696 | + } | |
| 34697 | + if( osGetTempPathW(nBuf, zWidePath)==0 ){ | |
| 34698 | + sqlite3_free(zWidePath); | |
| 34699 | + sqlite3_free(zBuf); | |
| 34585 | 34700 | OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_GETTEMPPATH\n")); |
| 34586 | 34701 | return SQLITE_IOERR_GETTEMPPATH; |
| 34587 | 34702 | } |
| 34588 | - zMulti = unicodeToUtf8(zWidePath); | |
| 34703 | + zMulti = winUnicodeToUtf8(zWidePath); | |
| 34589 | 34704 | if( zMulti ){ |
| 34590 | - sqlite3_snprintf(SQLITE_WIN32_MAX_PATH-30, zTempPath, "%s", zMulti); | |
| 34705 | + sqlite3_snprintf(nBuf-30, zBuf, "%s", zMulti); | |
| 34591 | 34706 | sqlite3_free(zMulti); |
| 34707 | + sqlite3_free(zWidePath); | |
| 34592 | 34708 | }else{ |
| 34709 | + sqlite3_free(zWidePath); | |
| 34710 | + sqlite3_free(zBuf); | |
| 34593 | 34711 | OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); |
| 34594 | 34712 | return SQLITE_IOERR_NOMEM; |
| 34595 | 34713 | } |
| 34596 | 34714 | } |
| 34597 | 34715 | #ifdef SQLITE_WIN32_HAS_ANSI |
| 34598 | 34716 | else{ |
| 34599 | 34717 | char *zUtf8; |
| 34600 | - char zMbcsPath[SQLITE_WIN32_MAX_PATH]; | |
| 34601 | - if( osGetTempPathA(SQLITE_WIN32_MAX_PATH-30, zMbcsPath)==0 ){ | |
| 34718 | + char *zMbcsPath = sqlite3MallocZero( nBuf ); | |
| 34719 | + if( !zMbcsPath ){ | |
| 34720 | + sqlite3_free(zBuf); | |
| 34721 | + OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); | |
| 34722 | + return SQLITE_IOERR_NOMEM; | |
| 34723 | + } | |
| 34724 | + if( osGetTempPathA(nBuf, zMbcsPath)==0 ){ | |
| 34725 | + sqlite3_free(zBuf); | |
| 34602 | 34726 | OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_GETTEMPPATH\n")); |
| 34603 | 34727 | return SQLITE_IOERR_GETTEMPPATH; |
| 34604 | 34728 | } |
| 34605 | 34729 | zUtf8 = sqlite3_win32_mbcs_to_utf8(zMbcsPath); |
| 34606 | 34730 | if( zUtf8 ){ |
| 34607 | - sqlite3_snprintf(SQLITE_WIN32_MAX_PATH-30, zTempPath, "%s", zUtf8); | |
| 34731 | + sqlite3_snprintf(nBuf-30, zBuf, "%s", zUtf8); | |
| 34608 | 34732 | sqlite3_free(zUtf8); |
| 34609 | 34733 | }else{ |
| 34734 | + sqlite3_free(zBuf); | |
| 34610 | 34735 | OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); |
| 34611 | 34736 | return SQLITE_IOERR_NOMEM; |
| 34612 | 34737 | } |
| 34613 | 34738 | } |
| 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 | 34739 | #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 | 34740 | #endif /* !SQLITE_OS_WINRT */ |
| 34632 | 34741 | |
| 34633 | 34742 | /* Check that the output buffer is large enough for the temporary file |
| 34634 | 34743 | ** name. If it is not, return SQLITE_ERROR. |
| 34635 | 34744 | */ |
| 34636 | - nTempPath = sqlite3Strlen30(zTempPath); | |
| 34745 | + nLen = sqlite3Strlen30(zBuf); | |
| 34637 | 34746 | |
| 34638 | - if( (nTempPath + sqlite3Strlen30(SQLITE_TEMP_FILE_PREFIX) + 18) >= nBuf ){ | |
| 34747 | + if( (nLen + sqlite3Strlen30(SQLITE_TEMP_FILE_PREFIX) + 18) >= nBuf ){ | |
| 34748 | + sqlite3_free(zBuf); | |
| 34639 | 34749 | OSTRACE(("TEMP-FILENAME rc=SQLITE_ERROR\n")); |
| 34640 | 34750 | return SQLITE_ERROR; |
| 34641 | 34751 | } |
| 34642 | 34752 | |
| 34643 | - for(i=nTempPath; i>0 && zTempPath[i-1]=='\\'; i--){} | |
| 34644 | - zTempPath[i] = 0; | |
| 34753 | + sqlite3_snprintf(nBuf-18-nLen, zBuf+nLen, SQLITE_TEMP_FILE_PREFIX); | |
| 34645 | 34754 | |
| 34646 | - sqlite3_snprintf(nBuf-18, zBuf, (nTempPath > 0) ? | |
| 34647 | - "%s\\"SQLITE_TEMP_FILE_PREFIX : SQLITE_TEMP_FILE_PREFIX, | |
| 34648 | - zTempPath); | |
| 34649 | 34755 | j = sqlite3Strlen30(zBuf); |
| 34650 | 34756 | sqlite3_randomness(15, &zBuf[j]); |
| 34651 | 34757 | for(i=0; i<15; i++, j++){ |
| 34652 | 34758 | zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ]; |
| 34653 | 34759 | } |
| 34654 | 34760 | zBuf[j] = 0; |
| 34655 | 34761 | zBuf[j+1] = 0; |
| 34762 | + *pzBuf = zBuf; | |
| 34656 | 34763 | |
| 34657 | 34764 | OSTRACE(("TEMP-FILENAME name=%s, rc=SQLITE_OK\n", zBuf)); |
| 34658 | 34765 | return SQLITE_OK; |
| 34659 | 34766 | } |
| 34660 | 34767 | |
| @@ -34666,17 +34773,17 @@ | ||
| 34666 | 34773 | static int winIsDir(const void *zConverted){ |
| 34667 | 34774 | DWORD attr; |
| 34668 | 34775 | int rc = 0; |
| 34669 | 34776 | DWORD lastErrno; |
| 34670 | 34777 | |
| 34671 | - if( isNT() ){ | |
| 34778 | + if( osIsNT() ){ | |
| 34672 | 34779 | int cnt = 0; |
| 34673 | 34780 | WIN32_FILE_ATTRIBUTE_DATA sAttrData; |
| 34674 | 34781 | memset(&sAttrData, 0, sizeof(sAttrData)); |
| 34675 | 34782 | while( !(rc = osGetFileAttributesExW((LPCWSTR)zConverted, |
| 34676 | 34783 | GetFileExInfoStandard, |
| 34677 | - &sAttrData)) && retryIoerr(&cnt, &lastErrno) ){} | |
| 34784 | + &sAttrData)) && winRetryIoerr(&cnt, &lastErrno) ){} | |
| 34678 | 34785 | if( !rc ){ |
| 34679 | 34786 | return 0; /* Invalid name? */ |
| 34680 | 34787 | } |
| 34681 | 34788 | attr = sAttrData.dwFileAttributes; |
| 34682 | 34789 | #if SQLITE_OS_WINCE==0 |
| @@ -34689,11 +34796,11 @@ | ||
| 34689 | 34796 | |
| 34690 | 34797 | /* |
| 34691 | 34798 | ** Open a file. |
| 34692 | 34799 | */ |
| 34693 | 34800 | static int winOpen( |
| 34694 | - sqlite3_vfs *pVfs, /* Not used */ | |
| 34801 | + sqlite3_vfs *pVfs, /* Used to get maximum path name length */ | |
| 34695 | 34802 | const char *zName, /* Name of the file (UTF-8) */ |
| 34696 | 34803 | sqlite3_file *id, /* Write the SQLite file handle here */ |
| 34697 | 34804 | int flags, /* Open mode flags */ |
| 34698 | 34805 | int *pOutFlags /* Status return flags */ |
| 34699 | 34806 | ){ |
| @@ -34712,11 +34819,11 @@ | ||
| 34712 | 34819 | int cnt = 0; |
| 34713 | 34820 | |
| 34714 | 34821 | /* If argument zPath is a NULL pointer, this function is required to open |
| 34715 | 34822 | ** a temporary file. Use this buffer to store the file name in. |
| 34716 | 34823 | */ |
| 34717 | - char zTmpname[SQLITE_WIN32_MAX_PATH+2]; /* Buffer used to create temp filename */ | |
| 34824 | + char *zTmpname = 0; /* For temporary filename, if necessary. */ | |
| 34718 | 34825 | |
| 34719 | 34826 | int rc = SQLITE_OK; /* Function Return Code */ |
| 34720 | 34827 | #if !defined(NDEBUG) || SQLITE_OS_WINCE |
| 34721 | 34828 | int eType = flags&0xFFFFFF00; /* Type of file to open */ |
| 34722 | 34829 | #endif |
| @@ -34767,22 +34874,22 @@ | ||
| 34767 | 34874 | assert( pFile!=0 ); |
| 34768 | 34875 | memset(pFile, 0, sizeof(winFile)); |
| 34769 | 34876 | pFile->h = INVALID_HANDLE_VALUE; |
| 34770 | 34877 | |
| 34771 | 34878 | #if SQLITE_OS_WINRT |
| 34772 | - if( !sqlite3_temp_directory ){ | |
| 34879 | + if( !zUtf8Name && !sqlite3_temp_directory ){ | |
| 34773 | 34880 | sqlite3_log(SQLITE_ERROR, |
| 34774 | 34881 | "sqlite3_temp_directory variable should be set for WinRT"); |
| 34775 | 34882 | } |
| 34776 | 34883 | #endif |
| 34777 | 34884 | |
| 34778 | 34885 | /* If the second argument to this function is NULL, generate a |
| 34779 | 34886 | ** temporary file name to use |
| 34780 | 34887 | */ |
| 34781 | 34888 | if( !zUtf8Name ){ |
| 34782 | - assert(isDelete && !isOpenJournal); | |
| 34783 | - rc = getTempname(SQLITE_WIN32_MAX_PATH+2, zTmpname); | |
| 34889 | + assert( isDelete && !isOpenJournal ); | |
| 34890 | + rc = winGetTempname(pVfs, &zTmpname); | |
| 34784 | 34891 | if( rc!=SQLITE_OK ){ |
| 34785 | 34892 | OSTRACE(("OPEN name=%s, rc=%s", zUtf8Name, sqlite3ErrName(rc))); |
| 34786 | 34893 | return rc; |
| 34787 | 34894 | } |
| 34788 | 34895 | zUtf8Name = zTmpname; |
| @@ -34791,21 +34898,23 @@ | ||
| 34791 | 34898 | /* Database filenames are double-zero terminated if they are not |
| 34792 | 34899 | ** URIs with parameters. Hence, they can always be passed into |
| 34793 | 34900 | ** sqlite3_uri_parameter(). |
| 34794 | 34901 | */ |
| 34795 | 34902 | assert( (eType!=SQLITE_OPEN_MAIN_DB) || (flags & SQLITE_OPEN_URI) || |
| 34796 | - zUtf8Name[strlen(zUtf8Name)+1]==0 ); | |
| 34903 | + zUtf8Name[sqlite3Strlen30(zUtf8Name)+1]==0 ); | |
| 34797 | 34904 | |
| 34798 | 34905 | /* Convert the filename to the system encoding. */ |
| 34799 | - zConverted = convertUtf8Filename(zUtf8Name); | |
| 34906 | + zConverted = winConvertUtf8Filename(zUtf8Name); | |
| 34800 | 34907 | if( zConverted==0 ){ |
| 34908 | + sqlite3_free(zTmpname); | |
| 34801 | 34909 | OSTRACE(("OPEN name=%s, rc=SQLITE_IOERR_NOMEM", zUtf8Name)); |
| 34802 | 34910 | return SQLITE_IOERR_NOMEM; |
| 34803 | 34911 | } |
| 34804 | 34912 | |
| 34805 | 34913 | if( winIsDir(zConverted) ){ |
| 34806 | 34914 | sqlite3_free(zConverted); |
| 34915 | + sqlite3_free(zTmpname); | |
| 34807 | 34916 | OSTRACE(("OPEN name=%s, rc=SQLITE_CANTOPEN_ISDIR", zUtf8Name)); |
| 34808 | 34917 | return SQLITE_CANTOPEN_ISDIR; |
| 34809 | 34918 | } |
| 34810 | 34919 | |
| 34811 | 34920 | if( isReadWrite ){ |
| @@ -34848,11 +34957,11 @@ | ||
| 34848 | 34957 | ** better if FILE_FLAG_RANDOM_ACCESS is used. Ticket #2699. */ |
| 34849 | 34958 | #if SQLITE_OS_WINCE |
| 34850 | 34959 | dwFlagsAndAttributes |= FILE_FLAG_RANDOM_ACCESS; |
| 34851 | 34960 | #endif |
| 34852 | 34961 | |
| 34853 | - if( isNT() ){ | |
| 34962 | + if( osIsNT() ){ | |
| 34854 | 34963 | #if SQLITE_OS_WINRT |
| 34855 | 34964 | CREATEFILE2_EXTENDED_PARAMETERS extendedParameters; |
| 34856 | 34965 | extendedParameters.dwSize = sizeof(CREATEFILE2_EXTENDED_PARAMETERS); |
| 34857 | 34966 | extendedParameters.dwFileAttributes = |
| 34858 | 34967 | dwFlagsAndAttributes & FILE_ATTRIBUTE_MASK; |
| @@ -34863,21 +34972,21 @@ | ||
| 34863 | 34972 | while( (h = osCreateFile2((LPCWSTR)zConverted, |
| 34864 | 34973 | dwDesiredAccess, |
| 34865 | 34974 | dwShareMode, |
| 34866 | 34975 | dwCreationDisposition, |
| 34867 | 34976 | &extendedParameters))==INVALID_HANDLE_VALUE && |
| 34868 | - retryIoerr(&cnt, &lastErrno) ){ | |
| 34977 | + winRetryIoerr(&cnt, &lastErrno) ){ | |
| 34869 | 34978 | /* Noop */ |
| 34870 | 34979 | } |
| 34871 | 34980 | #else |
| 34872 | 34981 | while( (h = osCreateFileW((LPCWSTR)zConverted, |
| 34873 | 34982 | dwDesiredAccess, |
| 34874 | 34983 | dwShareMode, NULL, |
| 34875 | 34984 | dwCreationDisposition, |
| 34876 | 34985 | dwFlagsAndAttributes, |
| 34877 | 34986 | NULL))==INVALID_HANDLE_VALUE && |
| 34878 | - retryIoerr(&cnt, &lastErrno) ){ | |
| 34987 | + winRetryIoerr(&cnt, &lastErrno) ){ | |
| 34879 | 34988 | /* Noop */ |
| 34880 | 34989 | } |
| 34881 | 34990 | #endif |
| 34882 | 34991 | } |
| 34883 | 34992 | #ifdef SQLITE_WIN32_HAS_ANSI |
| @@ -34886,24 +34995,25 @@ | ||
| 34886 | 34995 | dwDesiredAccess, |
| 34887 | 34996 | dwShareMode, NULL, |
| 34888 | 34997 | dwCreationDisposition, |
| 34889 | 34998 | dwFlagsAndAttributes, |
| 34890 | 34999 | NULL))==INVALID_HANDLE_VALUE && |
| 34891 | - retryIoerr(&cnt, &lastErrno) ){ | |
| 35000 | + winRetryIoerr(&cnt, &lastErrno) ){ | |
| 34892 | 35001 | /* Noop */ |
| 34893 | 35002 | } |
| 34894 | 35003 | } |
| 34895 | 35004 | #endif |
| 34896 | - logIoerr(cnt); | |
| 35005 | + winLogIoerr(cnt); | |
| 34897 | 35006 | |
| 34898 | 35007 | OSTRACE(("OPEN file=%p, name=%s, access=%lx, rc=%s\n", h, zUtf8Name, |
| 34899 | 35008 | dwDesiredAccess, (h==INVALID_HANDLE_VALUE) ? "failed" : "ok")); |
| 34900 | 35009 | |
| 34901 | 35010 | if( h==INVALID_HANDLE_VALUE ){ |
| 34902 | 35011 | pFile->lastErrno = lastErrno; |
| 34903 | 35012 | winLogError(SQLITE_CANTOPEN, pFile->lastErrno, "winOpen", zUtf8Name); |
| 34904 | 35013 | sqlite3_free(zConverted); |
| 35014 | + sqlite3_free(zTmpname); | |
| 34905 | 35015 | if( isReadWrite && !isExclusive ){ |
| 34906 | 35016 | return winOpen(pVfs, zName, id, |
| 34907 | 35017 | ((flags|SQLITE_OPEN_READONLY) & |
| 34908 | 35018 | ~(SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE)), |
| 34909 | 35019 | pOutFlags); |
| @@ -34928,19 +35038,21 @@ | ||
| 34928 | 35038 | if( isReadWrite && eType==SQLITE_OPEN_MAIN_DB |
| 34929 | 35039 | && (rc = winceCreateLock(zName, pFile))!=SQLITE_OK |
| 34930 | 35040 | ){ |
| 34931 | 35041 | osCloseHandle(h); |
| 34932 | 35042 | sqlite3_free(zConverted); |
| 35043 | + sqlite3_free(zTmpname); | |
| 34933 | 35044 | OSTRACE(("OPEN-CE-LOCK name=%s, rc=%s\n", zName, sqlite3ErrName(rc))); |
| 34934 | 35045 | return rc; |
| 34935 | 35046 | } |
| 34936 | 35047 | if( isTemp ){ |
| 34937 | 35048 | pFile->zDeleteOnClose = zConverted; |
| 34938 | 35049 | }else |
| 34939 | 35050 | #endif |
| 34940 | 35051 | { |
| 34941 | 35052 | sqlite3_free(zConverted); |
| 35053 | + sqlite3_free(zTmpname); | |
| 34942 | 35054 | } |
| 34943 | 35055 | |
| 34944 | 35056 | pFile->pMethod = &winIoMethod; |
| 34945 | 35057 | pFile->pVfs = pVfs; |
| 34946 | 35058 | pFile->h = h; |
| @@ -34990,15 +35102,16 @@ | ||
| 34990 | 35102 | UNUSED_PARAMETER(syncDir); |
| 34991 | 35103 | |
| 34992 | 35104 | SimulateIOError(return SQLITE_IOERR_DELETE); |
| 34993 | 35105 | OSTRACE(("DELETE name=%s, syncDir=%d\n", zFilename, syncDir)); |
| 34994 | 35106 | |
| 34995 | - zConverted = convertUtf8Filename(zFilename); | |
| 35107 | + zConverted = winConvertUtf8Filename(zFilename); | |
| 34996 | 35108 | if( zConverted==0 ){ |
| 35109 | + OSTRACE(("DELETE name=%s, rc=SQLITE_IOERR_NOMEM\n", zFilename)); | |
| 34997 | 35110 | return SQLITE_IOERR_NOMEM; |
| 34998 | 35111 | } |
| 34999 | - if( isNT() ){ | |
| 35112 | + if( osIsNT() ){ | |
| 35000 | 35113 | do { |
| 35001 | 35114 | #if SQLITE_OS_WINRT |
| 35002 | 35115 | WIN32_FILE_ATTRIBUTE_DATA sAttrData; |
| 35003 | 35116 | memset(&sAttrData, 0, sizeof(sAttrData)); |
| 35004 | 35117 | if ( osGetFileAttributesExW(zConverted, GetFileExInfoStandard, |
| @@ -35033,11 +35146,11 @@ | ||
| 35033 | 35146 | } |
| 35034 | 35147 | if ( osDeleteFileW(zConverted) ){ |
| 35035 | 35148 | rc = SQLITE_OK; /* Deleted OK. */ |
| 35036 | 35149 | break; |
| 35037 | 35150 | } |
| 35038 | - if ( !retryIoerr(&cnt, &lastErrno) ){ | |
| 35151 | + if ( !winRetryIoerr(&cnt, &lastErrno) ){ | |
| 35039 | 35152 | rc = SQLITE_ERROR; /* No more retries. */ |
| 35040 | 35153 | break; |
| 35041 | 35154 | } |
| 35042 | 35155 | } while(1); |
| 35043 | 35156 | } |
| @@ -35061,11 +35174,11 @@ | ||
| 35061 | 35174 | } |
| 35062 | 35175 | if ( osDeleteFileA(zConverted) ){ |
| 35063 | 35176 | rc = SQLITE_OK; /* Deleted OK. */ |
| 35064 | 35177 | break; |
| 35065 | 35178 | } |
| 35066 | - if ( !retryIoerr(&cnt, &lastErrno) ){ | |
| 35179 | + if ( !winRetryIoerr(&cnt, &lastErrno) ){ | |
| 35067 | 35180 | rc = SQLITE_ERROR; /* No more retries. */ |
| 35068 | 35181 | break; |
| 35069 | 35182 | } |
| 35070 | 35183 | } while(1); |
| 35071 | 35184 | } |
| @@ -35072,11 +35185,11 @@ | ||
| 35072 | 35185 | #endif |
| 35073 | 35186 | if( rc && rc!=SQLITE_IOERR_DELETE_NOENT ){ |
| 35074 | 35187 | rc = winLogError(SQLITE_IOERR_DELETE, lastErrno, |
| 35075 | 35188 | "winDelete", zFilename); |
| 35076 | 35189 | }else{ |
| 35077 | - logIoerr(cnt); | |
| 35190 | + winLogIoerr(cnt); | |
| 35078 | 35191 | } |
| 35079 | 35192 | sqlite3_free(zConverted); |
| 35080 | 35193 | OSTRACE(("DELETE name=%s, rc=%s\n", zFilename, sqlite3ErrName(rc))); |
| 35081 | 35194 | return rc; |
| 35082 | 35195 | } |
| @@ -35098,22 +35211,22 @@ | ||
| 35098 | 35211 | |
| 35099 | 35212 | SimulateIOError( return SQLITE_IOERR_ACCESS; ); |
| 35100 | 35213 | OSTRACE(("ACCESS name=%s, flags=%x, pResOut=%p\n", |
| 35101 | 35214 | zFilename, flags, pResOut)); |
| 35102 | 35215 | |
| 35103 | - zConverted = convertUtf8Filename(zFilename); | |
| 35216 | + zConverted = winConvertUtf8Filename(zFilename); | |
| 35104 | 35217 | if( zConverted==0 ){ |
| 35105 | 35218 | OSTRACE(("ACCESS name=%s, rc=SQLITE_IOERR_NOMEM\n", zFilename)); |
| 35106 | 35219 | return SQLITE_IOERR_NOMEM; |
| 35107 | 35220 | } |
| 35108 | - if( isNT() ){ | |
| 35221 | + if( osIsNT() ){ | |
| 35109 | 35222 | int cnt = 0; |
| 35110 | 35223 | WIN32_FILE_ATTRIBUTE_DATA sAttrData; |
| 35111 | 35224 | memset(&sAttrData, 0, sizeof(sAttrData)); |
| 35112 | 35225 | while( !(rc = osGetFileAttributesExW((LPCWSTR)zConverted, |
| 35113 | 35226 | GetFileExInfoStandard, |
| 35114 | - &sAttrData)) && retryIoerr(&cnt, &lastErrno) ){} | |
| 35227 | + &sAttrData)) && winRetryIoerr(&cnt, &lastErrno) ){} | |
| 35115 | 35228 | if( rc ){ |
| 35116 | 35229 | /* For an SQLITE_ACCESS_EXISTS query, treat a zero-length file |
| 35117 | 35230 | ** as if it does not exist. |
| 35118 | 35231 | */ |
| 35119 | 35232 | if( flags==SQLITE_ACCESS_EXISTS |
| @@ -35122,11 +35235,11 @@ | ||
| 35122 | 35235 | attr = INVALID_FILE_ATTRIBUTES; |
| 35123 | 35236 | }else{ |
| 35124 | 35237 | attr = sAttrData.dwFileAttributes; |
| 35125 | 35238 | } |
| 35126 | 35239 | }else{ |
| 35127 | - logIoerr(cnt); | |
| 35240 | + winLogIoerr(cnt); | |
| 35128 | 35241 | if( lastErrno!=ERROR_FILE_NOT_FOUND && lastErrno!=ERROR_PATH_NOT_FOUND ){ |
| 35129 | 35242 | winLogError(SQLITE_IOERR_ACCESS, lastErrno, "winAccess", zFilename); |
| 35130 | 35243 | sqlite3_free(zConverted); |
| 35131 | 35244 | return SQLITE_IOERR_ACCESS; |
| 35132 | 35245 | }else{ |
| @@ -35173,11 +35286,11 @@ | ||
| 35173 | 35286 | ** a legal UNC name, a volume relative path, or an absolute path name in the |
| 35174 | 35287 | ** "Unix" format on Windows. There is no easy way to differentiate between |
| 35175 | 35288 | ** the final two cases; therefore, we return the safer return value of TRUE |
| 35176 | 35289 | ** so that callers of this function will simply use it verbatim. |
| 35177 | 35290 | */ |
| 35178 | - if ( zPathname[0]=='/' || zPathname[0]=='\\' ){ | |
| 35291 | + if ( winIsDirSep(zPathname[0]) ){ | |
| 35179 | 35292 | return TRUE; |
| 35180 | 35293 | } |
| 35181 | 35294 | |
| 35182 | 35295 | /* |
| 35183 | 35296 | ** If the path name starts with a letter and a colon it is either a volume |
| @@ -35209,28 +35322,33 @@ | ||
| 35209 | 35322 | ){ |
| 35210 | 35323 | |
| 35211 | 35324 | #if defined(__CYGWIN__) |
| 35212 | 35325 | SimulateIOError( return SQLITE_ERROR ); |
| 35213 | 35326 | UNUSED_PARAMETER(nFull); |
| 35214 | - assert( pVfs->mxPathname>=SQLITE_WIN32_MAX_PATH ); | |
| 35215 | 35327 | assert( nFull>=pVfs->mxPathname ); |
| 35216 | 35328 | if ( sqlite3_data_directory && !winIsVerbatimPathname(zRelative) ){ |
| 35217 | 35329 | /* |
| 35218 | 35330 | ** NOTE: We are dealing with a relative path name and the data |
| 35219 | 35331 | ** directory has been set. Therefore, use it as the basis |
| 35220 | 35332 | ** for converting the relative path name to an absolute |
| 35221 | 35333 | ** one by prepending the data directory and a slash. |
| 35222 | 35334 | */ |
| 35223 | - char zOut[SQLITE_WIN32_MAX_PATH+1]; | |
| 35335 | + char *zOut = sqlite3MallocZero( pVfs->mxPathname+1 ); | |
| 35336 | + if( !zOut ){ | |
| 35337 | + winLogError(SQLITE_IOERR_NOMEM, 0, "winFullPathname", zRelative); | |
| 35338 | + return SQLITE_IOERR_NOMEM; | |
| 35339 | + } | |
| 35224 | 35340 | if( cygwin_conv_path(CCP_POSIX_TO_WIN_A|CCP_RELATIVE, zRelative, zOut, |
| 35225 | - SQLITE_WIN32_MAX_PATH+1)<0 ){ | |
| 35341 | + pVfs->mxPathname+1)<0 ){ | |
| 35226 | 35342 | winLogError(SQLITE_CANTOPEN_FULLPATH, (DWORD)errno, "cygwin_conv_path", |
| 35227 | 35343 | zRelative); |
| 35344 | + sqlite3_free(zOut); | |
| 35228 | 35345 | return SQLITE_CANTOPEN_FULLPATH; |
| 35229 | 35346 | } |
| 35230 | - sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s\\%s", | |
| 35231 | - sqlite3_data_directory, zOut); | |
| 35347 | + sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%s%s", | |
| 35348 | + sqlite3_data_directory, winGetDirDep(), zOut); | |
| 35349 | + sqlite3_free(zOut); | |
| 35232 | 35350 | }else{ |
| 35233 | 35351 | if( cygwin_conv_path(CCP_POSIX_TO_WIN_A, zRelative, zFull, nFull)<0 ){ |
| 35234 | 35352 | winLogError(SQLITE_CANTOPEN_FULLPATH, (DWORD)errno, "cygwin_conv_path", |
| 35235 | 35353 | zRelative); |
| 35236 | 35354 | return SQLITE_CANTOPEN_FULLPATH; |
| @@ -35248,12 +35366,12 @@ | ||
| 35248 | 35366 | ** NOTE: We are dealing with a relative path name and the data |
| 35249 | 35367 | ** directory has been set. Therefore, use it as the basis |
| 35250 | 35368 | ** for converting the relative path name to an absolute |
| 35251 | 35369 | ** one by prepending the data directory and a backslash. |
| 35252 | 35370 | */ |
| 35253 | - sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s\\%s", | |
| 35254 | - sqlite3_data_directory, zRelative); | |
| 35371 | + sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%s%s", | |
| 35372 | + sqlite3_data_directory, winGetDirDep(), zRelative); | |
| 35255 | 35373 | }else{ |
| 35256 | 35374 | sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zRelative); |
| 35257 | 35375 | } |
| 35258 | 35376 | return SQLITE_OK; |
| 35259 | 35377 | #endif |
| @@ -35281,19 +35399,19 @@ | ||
| 35281 | 35399 | ** NOTE: We are dealing with a relative path name and the data |
| 35282 | 35400 | ** directory has been set. Therefore, use it as the basis |
| 35283 | 35401 | ** for converting the relative path name to an absolute |
| 35284 | 35402 | ** one by prepending the data directory and a backslash. |
| 35285 | 35403 | */ |
| 35286 | - sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s\\%s", | |
| 35287 | - sqlite3_data_directory, zRelative); | |
| 35404 | + sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%s%s", | |
| 35405 | + sqlite3_data_directory, winGetDirDep(), zRelative); | |
| 35288 | 35406 | return SQLITE_OK; |
| 35289 | 35407 | } |
| 35290 | - zConverted = convertUtf8Filename(zRelative); | |
| 35408 | + zConverted = winConvertUtf8Filename(zRelative); | |
| 35291 | 35409 | if( zConverted==0 ){ |
| 35292 | 35410 | return SQLITE_IOERR_NOMEM; |
| 35293 | 35411 | } |
| 35294 | - if( isNT() ){ | |
| 35412 | + if( osIsNT() ){ | |
| 35295 | 35413 | LPWSTR zTemp; |
| 35296 | 35414 | nByte = osGetFullPathNameW((LPCWSTR)zConverted, 0, 0, 0); |
| 35297 | 35415 | if( nByte==0 ){ |
| 35298 | 35416 | winLogError(SQLITE_ERROR, osGetLastError(), |
| 35299 | 35417 | "GetFullPathNameW1", zConverted); |
| @@ -35313,11 +35431,11 @@ | ||
| 35313 | 35431 | sqlite3_free(zConverted); |
| 35314 | 35432 | sqlite3_free(zTemp); |
| 35315 | 35433 | return SQLITE_CANTOPEN_FULLPATH; |
| 35316 | 35434 | } |
| 35317 | 35435 | sqlite3_free(zConverted); |
| 35318 | - zOut = unicodeToUtf8(zTemp); | |
| 35436 | + zOut = winUnicodeToUtf8(zTemp); | |
| 35319 | 35437 | sqlite3_free(zTemp); |
| 35320 | 35438 | } |
| 35321 | 35439 | #ifdef SQLITE_WIN32_HAS_ANSI |
| 35322 | 35440 | else{ |
| 35323 | 35441 | char *zTemp; |
| @@ -35366,16 +35484,16 @@ | ||
| 35366 | 35484 | ** Interfaces for opening a shared library, finding entry points |
| 35367 | 35485 | ** within the shared library, and closing the shared library. |
| 35368 | 35486 | */ |
| 35369 | 35487 | static void *winDlOpen(sqlite3_vfs *pVfs, const char *zFilename){ |
| 35370 | 35488 | HANDLE h; |
| 35371 | - void *zConverted = convertUtf8Filename(zFilename); | |
| 35489 | + void *zConverted = winConvertUtf8Filename(zFilename); | |
| 35372 | 35490 | UNUSED_PARAMETER(pVfs); |
| 35373 | 35491 | if( zConverted==0 ){ |
| 35374 | 35492 | return 0; |
| 35375 | 35493 | } |
| 35376 | - if( isNT() ){ | |
| 35494 | + if( osIsNT() ){ | |
| 35377 | 35495 | #if SQLITE_OS_WINRT |
| 35378 | 35496 | h = osLoadPackagedLibrary((LPCWSTR)zConverted, 0); |
| 35379 | 35497 | #else |
| 35380 | 35498 | h = osLoadLibraryW((LPCWSTR)zConverted); |
| 35381 | 35499 | #endif |
| @@ -35388,11 +35506,11 @@ | ||
| 35388 | 35506 | sqlite3_free(zConverted); |
| 35389 | 35507 | return (void*)h; |
| 35390 | 35508 | } |
| 35391 | 35509 | static void winDlError(sqlite3_vfs *pVfs, int nBuf, char *zBufOut){ |
| 35392 | 35510 | UNUSED_PARAMETER(pVfs); |
| 35393 | - getLastErrorMsg(osGetLastError(), nBuf, zBufOut); | |
| 35511 | + winGetLastErrorMsg(osGetLastError(), nBuf, zBufOut); | |
| 35394 | 35512 | } |
| 35395 | 35513 | static void (*winDlSym(sqlite3_vfs *pVfs,void *pH,const char *zSym))(void){ |
| 35396 | 35514 | UNUSED_PARAMETER(pVfs); |
| 35397 | 35515 | return (void(*)(void))osGetProcAddressA((HANDLE)pH, zSym); |
| 35398 | 35516 | } |
| @@ -35564,21 +35682,21 @@ | ||
| 35564 | 35682 | ** by sqlite into the error message available to the user using |
| 35565 | 35683 | ** sqlite3_errmsg(), possibly making IO errors easier to debug. |
| 35566 | 35684 | */ |
| 35567 | 35685 | static int winGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){ |
| 35568 | 35686 | UNUSED_PARAMETER(pVfs); |
| 35569 | - return getLastErrorMsg(osGetLastError(), nBuf, zBuf); | |
| 35687 | + return winGetLastErrorMsg(osGetLastError(), nBuf, zBuf); | |
| 35570 | 35688 | } |
| 35571 | 35689 | |
| 35572 | 35690 | /* |
| 35573 | 35691 | ** Initialize and deinitialize the operating system interface. |
| 35574 | 35692 | */ |
| 35575 | 35693 | SQLITE_API int sqlite3_os_init(void){ |
| 35576 | 35694 | static sqlite3_vfs winVfs = { |
| 35577 | 35695 | 3, /* iVersion */ |
| 35578 | 35696 | sizeof(winFile), /* szOsFile */ |
| 35579 | - SQLITE_WIN32_MAX_PATH, /* mxPathname */ | |
| 35697 | + SQLITE_WIN32_MAX_PATH_BYTES, /* mxPathname */ | |
| 35580 | 35698 | 0, /* pNext */ |
| 35581 | 35699 | "win32", /* zName */ |
| 35582 | 35700 | 0, /* pAppData */ |
| 35583 | 35701 | winOpen, /* xOpen */ |
| 35584 | 35702 | winDelete, /* xDelete */ |
| @@ -35595,10 +35713,36 @@ | ||
| 35595 | 35713 | winCurrentTimeInt64, /* xCurrentTimeInt64 */ |
| 35596 | 35714 | winSetSystemCall, /* xSetSystemCall */ |
| 35597 | 35715 | winGetSystemCall, /* xGetSystemCall */ |
| 35598 | 35716 | winNextSystemCall, /* xNextSystemCall */ |
| 35599 | 35717 | }; |
| 35718 | +#if defined(SQLITE_WIN32_HAS_WIDE) | |
| 35719 | + static sqlite3_vfs winLongPathVfs = { | |
| 35720 | + 3, /* iVersion */ | |
| 35721 | + sizeof(winFile), /* szOsFile */ | |
| 35722 | + SQLITE_WINNT_MAX_PATH_BYTES, /* mxPathname */ | |
| 35723 | + 0, /* pNext */ | |
| 35724 | + "win32-longpath", /* zName */ | |
| 35725 | + 0, /* pAppData */ | |
| 35726 | + winOpen, /* xOpen */ | |
| 35727 | + winDelete, /* xDelete */ | |
| 35728 | + winAccess, /* xAccess */ | |
| 35729 | + winFullPathname, /* xFullPathname */ | |
| 35730 | + winDlOpen, /* xDlOpen */ | |
| 35731 | + winDlError, /* xDlError */ | |
| 35732 | + winDlSym, /* xDlSym */ | |
| 35733 | + winDlClose, /* xDlClose */ | |
| 35734 | + winRandomness, /* xRandomness */ | |
| 35735 | + winSleep, /* xSleep */ | |
| 35736 | + winCurrentTime, /* xCurrentTime */ | |
| 35737 | + winGetLastError, /* xGetLastError */ | |
| 35738 | + winCurrentTimeInt64, /* xCurrentTimeInt64 */ | |
| 35739 | + winSetSystemCall, /* xSetSystemCall */ | |
| 35740 | + winGetSystemCall, /* xGetSystemCall */ | |
| 35741 | + winNextSystemCall, /* xNextSystemCall */ | |
| 35742 | + }; | |
| 35743 | +#endif | |
| 35600 | 35744 | |
| 35601 | 35745 | /* Double-check that the aSyscall[] array has been constructed |
| 35602 | 35746 | ** correctly. See ticket [bb3a86e890c8e96ab] */ |
| 35603 | 35747 | assert( ArraySize(aSyscall)==74 ); |
| 35604 | 35748 | |
| @@ -35611,10 +35755,15 @@ | ||
| 35611 | 35755 | #endif |
| 35612 | 35756 | assert( winSysInfo.dwAllocationGranularity>0 ); |
| 35613 | 35757 | assert( winSysInfo.dwPageSize>0 ); |
| 35614 | 35758 | |
| 35615 | 35759 | sqlite3_vfs_register(&winVfs, 1); |
| 35760 | + | |
| 35761 | +#if defined(SQLITE_WIN32_HAS_WIDE) | |
| 35762 | + sqlite3_vfs_register(&winLongPathVfs, 0); | |
| 35763 | +#endif | |
| 35764 | + | |
| 35616 | 35765 | return SQLITE_OK; |
| 35617 | 35766 | } |
| 35618 | 35767 | |
| 35619 | 35768 | SQLITE_API int sqlite3_os_end(void){ |
| 35620 | 35769 | #if SQLITE_OS_WINRT |
| @@ -52086,10 +52235,11 @@ | ||
| 52086 | 52235 | pBt->max1bytePayload = (u8)pBt->maxLocal; |
| 52087 | 52236 | } |
| 52088 | 52237 | assert( pBt->maxLeaf + 23 <= MX_CELL_SIZE(pBt) ); |
| 52089 | 52238 | pBt->pPage1 = pPage1; |
| 52090 | 52239 | pBt->nPage = nPage; |
| 52240 | +assert( pPage1->leaf==0 || pPage1->leaf==1 ); | |
| 52091 | 52241 | return SQLITE_OK; |
| 52092 | 52242 | |
| 52093 | 52243 | page1_init_failed: |
| 52094 | 52244 | releasePage(pPage1); |
| 52095 | 52245 | pBt->pPage1 = 0; |
| @@ -59838,43 +59988,108 @@ | ||
| 59838 | 59988 | } |
| 59839 | 59989 | return p; |
| 59840 | 59990 | } |
| 59841 | 59991 | |
| 59842 | 59992 | /* |
| 59843 | -** Create a new sqlite3_value object, containing the value of pExpr. | |
| 59993 | +** Context object passed by sqlite3Stat4ProbeSetValue() through to | |
| 59994 | +** valueNew(). See comments above valueNew() for details. | |
| 59995 | +*/ | |
| 59996 | +struct ValueNewStat4Ctx { | |
| 59997 | + Parse *pParse; | |
| 59998 | + Index *pIdx; | |
| 59999 | + UnpackedRecord **ppRec; | |
| 60000 | + int iVal; | |
| 60001 | +}; | |
| 60002 | + | |
| 60003 | +/* | |
| 60004 | +** Allocate and return a pointer to a new sqlite3_value object. If | |
| 60005 | +** the second argument to this function is NULL, the object is allocated | |
| 60006 | +** by calling sqlite3ValueNew(). | |
| 59844 | 60007 | ** |
| 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. | |
| 60008 | +** Otherwise, if the second argument is non-zero, then this function is | |
| 60009 | +** being called indirectly by sqlite3Stat4ProbeSetValue(). If it has not | |
| 60010 | +** already been allocated, allocate the UnpackedRecord structure that | |
| 60011 | +** that function will return to its caller here. Then return a pointer | |
| 60012 | +** an sqlite3_value within the UnpackedRecord.a[] array. | |
| 59851 | 60013 | */ |
| 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 */ | |
| 60014 | +static sqlite3_value *valueNew(sqlite3 *db, struct ValueNewStat4Ctx *p){ | |
| 60015 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 | |
| 60016 | + if( p ){ | |
| 60017 | + UnpackedRecord *pRec = p->ppRec[0]; | |
| 60018 | + | |
| 60019 | + if( pRec==0 ){ | |
| 60020 | + Index *pIdx = p->pIdx; /* Index being probed */ | |
| 60021 | + int nByte; /* Bytes of space to allocate */ | |
| 60022 | + int i; /* Counter variable */ | |
| 60023 | + int nCol = pIdx->nColumn+1; /* Number of index columns including rowid */ | |
| 60024 | + | |
| 60025 | + nByte = sizeof(Mem) * nCol + sizeof(UnpackedRecord); | |
| 60026 | + pRec = (UnpackedRecord*)sqlite3DbMallocZero(db, nByte); | |
| 60027 | + if( pRec ){ | |
| 60028 | + pRec->pKeyInfo = sqlite3IndexKeyinfo(p->pParse, pIdx); | |
| 60029 | + if( pRec->pKeyInfo ){ | |
| 60030 | + assert( pRec->pKeyInfo->nField+1==nCol ); | |
| 60031 | + pRec->pKeyInfo->enc = ENC(db); | |
| 60032 | + pRec->flags = UNPACKED_PREFIX_MATCH; | |
| 60033 | + pRec->aMem = (Mem *)&pRec[1]; | |
| 60034 | + for(i=0; i<nCol; i++){ | |
| 60035 | + pRec->aMem[i].flags = MEM_Null; | |
| 60036 | + pRec->aMem[i].type = SQLITE_NULL; | |
| 60037 | + pRec->aMem[i].db = db; | |
| 60038 | + } | |
| 60039 | + }else{ | |
| 60040 | + sqlite3DbFree(db, pRec); | |
| 60041 | + pRec = 0; | |
| 60042 | + } | |
| 60043 | + } | |
| 60044 | + if( pRec==0 ) return 0; | |
| 60045 | + p->ppRec[0] = pRec; | |
| 60046 | + } | |
| 60047 | + | |
| 60048 | + pRec->nField = p->iVal+1; | |
| 60049 | + return &pRec->aMem[p->iVal]; | |
| 60050 | + } | |
| 60051 | +#endif | |
| 60052 | + return sqlite3ValueNew(db); | |
| 60053 | +} | |
| 60054 | + | |
| 60055 | +/* | |
| 60056 | +** Extract a value from the supplied expression in the manner described | |
| 60057 | +** above sqlite3ValueFromExpr(). Allocate the sqlite3_value object | |
| 60058 | +** using valueNew(). | |
| 60059 | +** | |
| 60060 | +** If pCtx is NULL and an error occurs after the sqlite3_value object | |
| 60061 | +** has been allocated, it is freed before returning. Or, if pCtx is not | |
| 60062 | +** NULL, it is assumed that the caller will free any allocated object | |
| 60063 | +** in all cases. | |
| 60064 | +*/ | |
| 60065 | +int valueFromExpr( | |
| 60066 | + sqlite3 *db, /* The database connection */ | |
| 60067 | + Expr *pExpr, /* The expression to evaluate */ | |
| 60068 | + u8 enc, /* Encoding to use */ | |
| 60069 | + u8 affinity, /* Affinity to use */ | |
| 60070 | + sqlite3_value **ppVal, /* Write the new value here */ | |
| 60071 | + struct ValueNewStat4Ctx *pCtx /* Second argument for valueNew() */ | |
| 59858 | 60072 | ){ |
| 59859 | 60073 | int op; |
| 59860 | 60074 | char *zVal = 0; |
| 59861 | 60075 | sqlite3_value *pVal = 0; |
| 59862 | 60076 | int negInt = 1; |
| 59863 | 60077 | const char *zNeg = ""; |
| 60078 | + int rc = SQLITE_OK; | |
| 59864 | 60079 | |
| 59865 | 60080 | if( !pExpr ){ |
| 59866 | 60081 | *ppVal = 0; |
| 59867 | 60082 | return SQLITE_OK; |
| 59868 | 60083 | } |
| 59869 | 60084 | op = pExpr->op; |
| 59870 | 60085 | |
| 59871 | - /* op can only be TK_REGISTER if we have compiled with SQLITE_ENABLE_STAT3. | |
| 60086 | + /* op can only be TK_REGISTER if we have compiled with SQLITE_ENABLE_STAT4. | |
| 59872 | 60087 | ** The ifdef here is to enable us to achieve 100% branch test coverage even |
| 59873 | - ** when SQLITE_ENABLE_STAT3 is omitted. | |
| 60088 | + ** when SQLITE_ENABLE_STAT4 is omitted. | |
| 59874 | 60089 | */ |
| 59875 | -#ifdef SQLITE_ENABLE_STAT3 | |
| 60090 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 | |
| 59876 | 60091 | if( op==TK_REGISTER ) op = pExpr->op2; |
| 59877 | 60092 | #else |
| 59878 | 60093 | if( NEVER(op==TK_REGISTER) ) op = pExpr->op2; |
| 59879 | 60094 | #endif |
| 59880 | 60095 | |
| @@ -59888,11 +60103,11 @@ | ||
| 59888 | 60103 | negInt = -1; |
| 59889 | 60104 | zNeg = "-"; |
| 59890 | 60105 | } |
| 59891 | 60106 | |
| 59892 | 60107 | if( op==TK_STRING || op==TK_FLOAT || op==TK_INTEGER ){ |
| 59893 | - pVal = sqlite3ValueNew(db); | |
| 60108 | + pVal = valueNew(db, pCtx); | |
| 59894 | 60109 | if( pVal==0 ) goto no_mem; |
| 59895 | 60110 | if( ExprHasProperty(pExpr, EP_IntValue) ){ |
| 59896 | 60111 | sqlite3VdbeMemSetInt64(pVal, (i64)pExpr->u.iValue*negInt); |
| 59897 | 60112 | }else{ |
| 59898 | 60113 | zVal = sqlite3MPrintf(db, "%s%s", zNeg, pExpr->u.zToken); |
| @@ -59905,15 +60120,17 @@ | ||
| 59905 | 60120 | }else{ |
| 59906 | 60121 | sqlite3ValueApplyAffinity(pVal, affinity, SQLITE_UTF8); |
| 59907 | 60122 | } |
| 59908 | 60123 | if( pVal->flags & (MEM_Int|MEM_Real) ) pVal->flags &= ~MEM_Str; |
| 59909 | 60124 | if( enc!=SQLITE_UTF8 ){ |
| 59910 | - sqlite3VdbeChangeEncoding(pVal, enc); | |
| 60125 | + rc = sqlite3VdbeChangeEncoding(pVal, enc); | |
| 59911 | 60126 | } |
| 59912 | 60127 | }else if( op==TK_UMINUS ) { |
| 59913 | 60128 | /* This branch happens for multiple negative signs. Ex: -(-5) */ |
| 59914 | - if( SQLITE_OK==sqlite3ValueFromExpr(db,pExpr->pLeft,enc,affinity,&pVal) ){ | |
| 60129 | + if( SQLITE_OK==sqlite3ValueFromExpr(db,pExpr->pLeft,enc,affinity,&pVal) | |
| 60130 | + && pVal!=0 | |
| 60131 | + ){ | |
| 59915 | 60132 | sqlite3VdbeMemNumerify(pVal); |
| 59916 | 60133 | if( pVal->u.i==SMALLEST_INT64 ){ |
| 59917 | 60134 | pVal->flags &= MEM_Int; |
| 59918 | 60135 | pVal->flags |= MEM_Real; |
| 59919 | 60136 | pVal->r = (double)LARGEST_INT64; |
| @@ -59922,19 +60139,19 @@ | ||
| 59922 | 60139 | } |
| 59923 | 60140 | pVal->r = -pVal->r; |
| 59924 | 60141 | sqlite3ValueApplyAffinity(pVal, affinity, enc); |
| 59925 | 60142 | } |
| 59926 | 60143 | }else if( op==TK_NULL ){ |
| 59927 | - pVal = sqlite3ValueNew(db); | |
| 60144 | + pVal = valueNew(db, pCtx); | |
| 59928 | 60145 | if( pVal==0 ) goto no_mem; |
| 59929 | 60146 | } |
| 59930 | 60147 | #ifndef SQLITE_OMIT_BLOB_LITERAL |
| 59931 | 60148 | else if( op==TK_BLOB ){ |
| 59932 | 60149 | int nVal; |
| 59933 | 60150 | assert( pExpr->u.zToken[0]=='x' || pExpr->u.zToken[0]=='X' ); |
| 59934 | 60151 | assert( pExpr->u.zToken[1]=='\'' ); |
| 59935 | - pVal = sqlite3ValueNew(db); | |
| 60152 | + pVal = valueNew(db, pCtx); | |
| 59936 | 60153 | if( !pVal ) goto no_mem; |
| 59937 | 60154 | zVal = &pExpr->u.zToken[2]; |
| 59938 | 60155 | nVal = sqlite3Strlen30(zVal)-1; |
| 59939 | 60156 | assert( zVal[nVal]=='\'' ); |
| 59940 | 60157 | sqlite3VdbeMemSetStr(pVal, sqlite3HexToBlob(db, zVal, nVal), nVal/2, |
| @@ -59944,20 +60161,203 @@ | ||
| 59944 | 60161 | |
| 59945 | 60162 | if( pVal ){ |
| 59946 | 60163 | sqlite3VdbeMemStoreType(pVal); |
| 59947 | 60164 | } |
| 59948 | 60165 | *ppVal = pVal; |
| 59949 | - return SQLITE_OK; | |
| 60166 | + return rc; | |
| 59950 | 60167 | |
| 59951 | 60168 | no_mem: |
| 59952 | 60169 | db->mallocFailed = 1; |
| 59953 | 60170 | sqlite3DbFree(db, zVal); |
| 59954 | - sqlite3ValueFree(pVal); | |
| 59955 | - *ppVal = 0; | |
| 60171 | + assert( *ppVal==0 ); | |
| 60172 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 | |
| 60173 | + if( pCtx==0 ) sqlite3ValueFree(pVal); | |
| 60174 | +#else | |
| 60175 | + assert( pCtx==0 ); sqlite3ValueFree(pVal); | |
| 60176 | +#endif | |
| 59956 | 60177 | return SQLITE_NOMEM; |
| 59957 | 60178 | } |
| 59958 | 60179 | |
| 60180 | +/* | |
| 60181 | +** Create a new sqlite3_value object, containing the value of pExpr. | |
| 60182 | +** | |
| 60183 | +** This only works for very simple expressions that consist of one constant | |
| 60184 | +** token (i.e. "5", "5.1", "'a string'"). If the expression can | |
| 60185 | +** be converted directly into a value, then the value is allocated and | |
| 60186 | +** a pointer written to *ppVal. The caller is responsible for deallocating | |
| 60187 | +** the value by passing it to sqlite3ValueFree() later on. If the expression | |
| 60188 | +** cannot be converted to a value, then *ppVal is set to NULL. | |
| 60189 | +*/ | |
| 60190 | +SQLITE_PRIVATE int sqlite3ValueFromExpr( | |
| 60191 | + sqlite3 *db, /* The database connection */ | |
| 60192 | + Expr *pExpr, /* The expression to evaluate */ | |
| 60193 | + u8 enc, /* Encoding to use */ | |
| 60194 | + u8 affinity, /* Affinity to use */ | |
| 60195 | + sqlite3_value **ppVal /* Write the new value here */ | |
| 60196 | +){ | |
| 60197 | + return valueFromExpr(db, pExpr, enc, affinity, ppVal, 0); | |
| 60198 | +} | |
| 60199 | + | |
| 60200 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 | |
| 60201 | +/* | |
| 60202 | +** The implementation of the sqlite_record() function. This function accepts | |
| 60203 | +** a single argument of any type. The return value is a formatted database | |
| 60204 | +** record (a blob) containing the argument value. | |
| 60205 | +** | |
| 60206 | +** This is used to convert the value stored in the 'sample' column of the | |
| 60207 | +** sqlite_stat3 table to the record format SQLite uses internally. | |
| 60208 | +*/ | |
| 60209 | +static void recordFunc( | |
| 60210 | + sqlite3_context *context, | |
| 60211 | + int argc, | |
| 60212 | + sqlite3_value **argv | |
| 60213 | +){ | |
| 60214 | + const int file_format = 1; | |
| 60215 | + int iSerial; /* Serial type */ | |
| 60216 | + int nSerial; /* Bytes of space for iSerial as varint */ | |
| 60217 | + int nVal; /* Bytes of space required for argv[0] */ | |
| 60218 | + int nRet; | |
| 60219 | + sqlite3 *db; | |
| 60220 | + u8 *aRet; | |
| 60221 | + | |
| 60222 | + iSerial = sqlite3VdbeSerialType(argv[0], file_format); | |
| 60223 | + nSerial = sqlite3VarintLen(iSerial); | |
| 60224 | + nVal = sqlite3VdbeSerialTypeLen(iSerial); | |
| 60225 | + db = sqlite3_context_db_handle(context); | |
| 60226 | + | |
| 60227 | + nRet = 1 + nSerial + nVal; | |
| 60228 | + aRet = sqlite3DbMallocRaw(db, nRet); | |
| 60229 | + if( aRet==0 ){ | |
| 60230 | + sqlite3_result_error_nomem(context); | |
| 60231 | + }else{ | |
| 60232 | + aRet[0] = nSerial+1; | |
| 60233 | + sqlite3PutVarint(&aRet[1], iSerial); | |
| 60234 | + sqlite3VdbeSerialPut(&aRet[1+nSerial], nVal, argv[0], file_format); | |
| 60235 | + sqlite3_result_blob(context, aRet, nRet, SQLITE_TRANSIENT); | |
| 60236 | + sqlite3DbFree(db, aRet); | |
| 60237 | + } | |
| 60238 | +} | |
| 60239 | + | |
| 60240 | +/* | |
| 60241 | +** Register built-in functions used to help read ANALYZE data. | |
| 60242 | +*/ | |
| 60243 | +SQLITE_PRIVATE void sqlite3AnalyzeFunctions(void){ | |
| 60244 | + static SQLITE_WSD FuncDef aAnalyzeTableFuncs[] = { | |
| 60245 | + FUNCTION(sqlite_record, 1, 0, 0, recordFunc), | |
| 60246 | + }; | |
| 60247 | + int i; | |
| 60248 | + FuncDefHash *pHash = &GLOBAL(FuncDefHash, sqlite3GlobalFunctions); | |
| 60249 | + FuncDef *aFunc = (FuncDef*)&GLOBAL(FuncDef, aAnalyzeTableFuncs); | |
| 60250 | + for(i=0; i<ArraySize(aAnalyzeTableFuncs); i++){ | |
| 60251 | + sqlite3FuncDefInsert(pHash, &aFunc[i]); | |
| 60252 | + } | |
| 60253 | +} | |
| 60254 | + | |
| 60255 | +/* | |
| 60256 | +** This function is used to allocate and populate UnpackedRecord | |
| 60257 | +** structures intended to be compared against sample index keys stored | |
| 60258 | +** in the sqlite_stat4 table. | |
| 60259 | +** | |
| 60260 | +** A single call to this function attempts to populates field iVal (leftmost | |
| 60261 | +** is 0 etc.) of the unpacked record with a value extracted from expression | |
| 60262 | +** pExpr. Extraction of values is possible if: | |
| 60263 | +** | |
| 60264 | +** * (pExpr==0). In this case the value is assumed to be an SQL NULL, | |
| 60265 | +** | |
| 60266 | +** * The expression is a bound variable, and this is a reprepare, or | |
| 60267 | +** | |
| 60268 | +** * The sqlite3ValueFromExpr() function is able to extract a value | |
| 60269 | +** from the expression (i.e. the expression is a literal value). | |
| 60270 | +** | |
| 60271 | +** If a value can be extracted, the affinity passed as the 5th argument | |
| 60272 | +** is applied to it before it is copied into the UnpackedRecord. Output | |
| 60273 | +** parameter *pbOk is set to true if a value is extracted, or false | |
| 60274 | +** otherwise. | |
| 60275 | +** | |
| 60276 | +** When this function is called, *ppRec must either point to an object | |
| 60277 | +** allocated by an earlier call to this function, or must be NULL. If it | |
| 60278 | +** is NULL and a value can be successfully extracted, a new UnpackedRecord | |
| 60279 | +** is allocated (and *ppRec set to point to it) before returning. | |
| 60280 | +** | |
| 60281 | +** Unless an error is encountered, SQLITE_OK is returned. It is not an | |
| 60282 | +** error if a value cannot be extracted from pExpr. If an error does | |
| 60283 | +** occur, an SQLite error code is returned. | |
| 60284 | +*/ | |
| 60285 | +SQLITE_PRIVATE int sqlite3Stat4ProbeSetValue( | |
| 60286 | + Parse *pParse, /* Parse context */ | |
| 60287 | + Index *pIdx, /* Index being probed */ | |
| 60288 | + UnpackedRecord **ppRec, /* IN/OUT: Probe record */ | |
| 60289 | + Expr *pExpr, /* The expression to extract a value from */ | |
| 60290 | + u8 affinity, /* Affinity to use */ | |
| 60291 | + int iVal, /* Array element to populate */ | |
| 60292 | + int *pbOk /* OUT: True if value was extracted */ | |
| 60293 | +){ | |
| 60294 | + int rc = SQLITE_OK; | |
| 60295 | + sqlite3_value *pVal = 0; | |
| 60296 | + | |
| 60297 | + struct ValueNewStat4Ctx alloc; | |
| 60298 | + alloc.pParse = pParse; | |
| 60299 | + alloc.pIdx = pIdx; | |
| 60300 | + alloc.ppRec = ppRec; | |
| 60301 | + alloc.iVal = iVal; | |
| 60302 | + | |
| 60303 | + if( !pExpr ){ | |
| 60304 | + pVal = valueNew(pParse->db, &alloc); | |
| 60305 | + if( pVal ){ | |
| 60306 | + sqlite3VdbeMemSetNull((Mem*)pVal); | |
| 60307 | + *pbOk = 1; | |
| 60308 | + } | |
| 60309 | + }else if( pExpr->op==TK_VARIABLE | |
| 60310 | + || (pExpr->op==TK_REGISTER && pExpr->op2==TK_VARIABLE) | |
| 60311 | + ){ | |
| 60312 | + Vdbe *v; | |
| 60313 | + int iBindVar = pExpr->iColumn; | |
| 60314 | + sqlite3VdbeSetVarmask(pParse->pVdbe, iBindVar); | |
| 60315 | + if( (v = pParse->pReprepare)!=0 ){ | |
| 60316 | + pVal = valueNew(pParse->db, &alloc); | |
| 60317 | + if( pVal ){ | |
| 60318 | + rc = sqlite3VdbeMemCopy((Mem*)pVal, &v->aVar[iBindVar-1]); | |
| 60319 | + if( rc==SQLITE_OK ){ | |
| 60320 | + sqlite3ValueApplyAffinity(pVal, affinity, SQLITE_UTF8); | |
| 60321 | + } | |
| 60322 | + pVal->db = pParse->db; | |
| 60323 | + *pbOk = 1; | |
| 60324 | + sqlite3VdbeMemStoreType((Mem*)pVal); | |
| 60325 | + } | |
| 60326 | + }else{ | |
| 60327 | + *pbOk = 0; | |
| 60328 | + } | |
| 60329 | + }else{ | |
| 60330 | + sqlite3 *db = pParse->db; | |
| 60331 | + rc = valueFromExpr(db, pExpr, ENC(db), affinity, &pVal, &alloc); | |
| 60332 | + *pbOk = (pVal!=0); | |
| 60333 | + } | |
| 60334 | + | |
| 60335 | + assert( pVal==0 || pVal->db==pParse->db ); | |
| 60336 | + return rc; | |
| 60337 | +} | |
| 60338 | + | |
| 60339 | +/* | |
| 60340 | +** Unless it is NULL, the argument must be an UnpackedRecord object returned | |
| 60341 | +** by an earlier call to sqlite3Stat4ProbeSetValue(). This call deletes | |
| 60342 | +** the object. | |
| 60343 | +*/ | |
| 60344 | +SQLITE_PRIVATE void sqlite3Stat4ProbeFree(UnpackedRecord *pRec){ | |
| 60345 | + if( pRec ){ | |
| 60346 | + int i; | |
| 60347 | + int nCol = pRec->pKeyInfo->nField+1; | |
| 60348 | + Mem *aMem = pRec->aMem; | |
| 60349 | + sqlite3 *db = aMem[0].db; | |
| 60350 | + for(i=0; i<nCol; i++){ | |
| 60351 | + sqlite3DbFree(db, aMem[i].zMalloc); | |
| 60352 | + } | |
| 60353 | + sqlite3DbFree(db, pRec->pKeyInfo); | |
| 60354 | + sqlite3DbFree(db, pRec); | |
| 60355 | + } | |
| 60356 | +} | |
| 60357 | +#endif /* ifdef SQLITE_ENABLE_STAT4 */ | |
| 60358 | + | |
| 59959 | 60359 | /* |
| 59960 | 60360 | ** Change the string value of an sqlite3_value object |
| 59961 | 60361 | */ |
| 59962 | 60362 | SQLITE_PRIVATE void sqlite3ValueSetStr( |
| 59963 | 60363 | sqlite3_value *v, /* Value to be set */ |
| @@ -66073,11 +66473,11 @@ | ||
| 66073 | 66473 | ** value or convert mem[p2] to a different type. |
| 66074 | 66474 | */ |
| 66075 | 66475 | assert( pOp->opflags==sqlite3OpcodeProperty[pOp->opcode] ); |
| 66076 | 66476 | if( pOp->opflags & OPFLG_OUT2_PRERELEASE ){ |
| 66077 | 66477 | assert( pOp->p2>0 ); |
| 66078 | - assert( pOp->p2<=p->nMem ); | |
| 66478 | + assert( pOp->p2<=(p->nMem-p->nCursor) ); | |
| 66079 | 66479 | pOut = &aMem[pOp->p2]; |
| 66080 | 66480 | memAboutToChange(p, pOut); |
| 66081 | 66481 | VdbeMemRelease(pOut); |
| 66082 | 66482 | pOut->flags = MEM_Int; |
| 66083 | 66483 | } |
| @@ -66084,34 +66484,34 @@ | ||
| 66084 | 66484 | |
| 66085 | 66485 | /* Sanity checking on other operands */ |
| 66086 | 66486 | #ifdef SQLITE_DEBUG |
| 66087 | 66487 | if( (pOp->opflags & OPFLG_IN1)!=0 ){ |
| 66088 | 66488 | assert( pOp->p1>0 ); |
| 66089 | - assert( pOp->p1<=p->nMem ); | |
| 66489 | + assert( pOp->p1<=(p->nMem-p->nCursor) ); | |
| 66090 | 66490 | assert( memIsValid(&aMem[pOp->p1]) ); |
| 66091 | 66491 | REGISTER_TRACE(pOp->p1, &aMem[pOp->p1]); |
| 66092 | 66492 | } |
| 66093 | 66493 | if( (pOp->opflags & OPFLG_IN2)!=0 ){ |
| 66094 | 66494 | assert( pOp->p2>0 ); |
| 66095 | - assert( pOp->p2<=p->nMem ); | |
| 66495 | + assert( pOp->p2<=(p->nMem-p->nCursor) ); | |
| 66096 | 66496 | assert( memIsValid(&aMem[pOp->p2]) ); |
| 66097 | 66497 | REGISTER_TRACE(pOp->p2, &aMem[pOp->p2]); |
| 66098 | 66498 | } |
| 66099 | 66499 | if( (pOp->opflags & OPFLG_IN3)!=0 ){ |
| 66100 | 66500 | assert( pOp->p3>0 ); |
| 66101 | - assert( pOp->p3<=p->nMem ); | |
| 66501 | + assert( pOp->p3<=(p->nMem-p->nCursor) ); | |
| 66102 | 66502 | assert( memIsValid(&aMem[pOp->p3]) ); |
| 66103 | 66503 | REGISTER_TRACE(pOp->p3, &aMem[pOp->p3]); |
| 66104 | 66504 | } |
| 66105 | 66505 | if( (pOp->opflags & OPFLG_OUT2)!=0 ){ |
| 66106 | 66506 | assert( pOp->p2>0 ); |
| 66107 | - assert( pOp->p2<=p->nMem ); | |
| 66507 | + assert( pOp->p2<=(p->nMem-p->nCursor) ); | |
| 66108 | 66508 | memAboutToChange(p, &aMem[pOp->p2]); |
| 66109 | 66509 | } |
| 66110 | 66510 | if( (pOp->opflags & OPFLG_OUT3)!=0 ){ |
| 66111 | 66511 | assert( pOp->p3>0 ); |
| 66112 | - assert( pOp->p3<=p->nMem ); | |
| 66512 | + assert( pOp->p3<=(p->nMem-p->nCursor) ); | |
| 66113 | 66513 | memAboutToChange(p, &aMem[pOp->p3]); |
| 66114 | 66514 | } |
| 66115 | 66515 | #endif |
| 66116 | 66516 | |
| 66117 | 66517 | switch( pOp->opcode ){ |
| @@ -66200,11 +66600,11 @@ | ||
| 66200 | 66600 | ** |
| 66201 | 66601 | ** Write the current address onto register P1 |
| 66202 | 66602 | ** and then jump to address P2. |
| 66203 | 66603 | */ |
| 66204 | 66604 | case OP_Gosub: { /* jump */ |
| 66205 | - assert( pOp->p1>0 && pOp->p1<=p->nMem ); | |
| 66605 | + assert( pOp->p1>0 && pOp->p1<=(p->nMem-p->nCursor) ); | |
| 66206 | 66606 | pIn1 = &aMem[pOp->p1]; |
| 66207 | 66607 | assert( (pIn1->flags & MEM_Dyn)==0 ); |
| 66208 | 66608 | memAboutToChange(p, pIn1); |
| 66209 | 66609 | pIn1->flags = MEM_Int; |
| 66210 | 66610 | pIn1->u.i = pc; |
| @@ -66416,11 +66816,11 @@ | ||
| 66416 | 66816 | #if 0 /* local variables moved into u.ab */ |
| 66417 | 66817 | int cnt; |
| 66418 | 66818 | u16 nullFlag; |
| 66419 | 66819 | #endif /* local variables moved into u.ab */ |
| 66420 | 66820 | u.ab.cnt = pOp->p3-pOp->p2; |
| 66421 | - assert( pOp->p3<=p->nMem ); | |
| 66821 | + assert( pOp->p3<=(p->nMem-p->nCursor) ); | |
| 66422 | 66822 | pOut->flags = u.ab.nullFlag = pOp->p1 ? (MEM_Null|MEM_Cleared) : MEM_Null; |
| 66423 | 66823 | while( u.ab.cnt>0 ){ |
| 66424 | 66824 | pOut++; |
| 66425 | 66825 | memAboutToChange(p, pOut); |
| 66426 | 66826 | VdbeMemRelease(pOut); |
| @@ -66489,12 +66889,12 @@ | ||
| 66489 | 66889 | assert( u.ad.p1+u.ad.n<=u.ad.p2 || u.ad.p2+u.ad.n<=u.ad.p1 ); |
| 66490 | 66890 | |
| 66491 | 66891 | pIn1 = &aMem[u.ad.p1]; |
| 66492 | 66892 | pOut = &aMem[u.ad.p2]; |
| 66493 | 66893 | while( u.ad.n-- ){ |
| 66494 | - assert( pOut<=&aMem[p->nMem] ); | |
| 66495 | - assert( pIn1<=&aMem[p->nMem] ); | |
| 66894 | + assert( pOut<=&aMem[(p->nMem-p->nCursor)] ); | |
| 66895 | + assert( pIn1<=&aMem[(p->nMem-p->nCursor)] ); | |
| 66496 | 66896 | assert( memIsValid(pIn1) ); |
| 66497 | 66897 | memAboutToChange(p, pOut); |
| 66498 | 66898 | u.ad.zMalloc = pOut->zMalloc; |
| 66499 | 66899 | pOut->zMalloc = 0; |
| 66500 | 66900 | sqlite3VdbeMemMove(pOut, pIn1); |
| @@ -66578,11 +66978,11 @@ | ||
| 66578 | 66978 | Mem *pMem; |
| 66579 | 66979 | int i; |
| 66580 | 66980 | #endif /* local variables moved into u.af */ |
| 66581 | 66981 | assert( p->nResColumn==pOp->p2 ); |
| 66582 | 66982 | assert( pOp->p1>0 ); |
| 66583 | - assert( pOp->p1+pOp->p2<=p->nMem+1 ); | |
| 66983 | + assert( pOp->p1+pOp->p2<=(p->nMem-p->nCursor)+1 ); | |
| 66584 | 66984 | |
| 66585 | 66985 | /* If this statement has violated immediate foreign key constraints, do |
| 66586 | 66986 | ** not return the number of rows modified. And do not RELEASE the statement |
| 66587 | 66987 | ** transaction. It needs to be rolled back. */ |
| 66588 | 66988 | if( SQLITE_OK!=(rc = sqlite3VdbeCheckFk(p, 0)) ){ |
| @@ -66858,15 +67258,15 @@ | ||
| 66858 | 67258 | #endif /* local variables moved into u.ai */ |
| 66859 | 67259 | |
| 66860 | 67260 | u.ai.n = pOp->p5; |
| 66861 | 67261 | u.ai.apVal = p->apArg; |
| 66862 | 67262 | assert( u.ai.apVal || u.ai.n==0 ); |
| 66863 | - assert( pOp->p3>0 && pOp->p3<=p->nMem ); | |
| 67263 | + assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) ); | |
| 66864 | 67264 | pOut = &aMem[pOp->p3]; |
| 66865 | 67265 | memAboutToChange(p, pOut); |
| 66866 | 67266 | |
| 66867 | - assert( u.ai.n==0 || (pOp->p2>0 && pOp->p2+u.ai.n<=p->nMem+1) ); | |
| 67267 | + assert( u.ai.n==0 || (pOp->p2>0 && pOp->p2+u.ai.n<=(p->nMem-p->nCursor)+1) ); | |
| 66868 | 67268 | assert( pOp->p3<pOp->p2 || pOp->p3>=pOp->p2+u.ai.n ); |
| 66869 | 67269 | u.ai.pArg = &aMem[pOp->p2]; |
| 66870 | 67270 | for(u.ai.i=0; u.ai.i<u.ai.n; u.ai.i++, u.ai.pArg++){ |
| 66871 | 67271 | assert( memIsValid(u.ai.pArg) ); |
| 66872 | 67272 | u.ai.apVal[u.ai.i] = u.ai.pArg; |
| @@ -67398,15 +67798,15 @@ | ||
| 67398 | 67798 | u.al.p2 = pOp->p2; |
| 67399 | 67799 | #if SQLITE_DEBUG |
| 67400 | 67800 | if( aPermute ){ |
| 67401 | 67801 | int k, mx = 0; |
| 67402 | 67802 | 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 ); | |
| 67803 | + assert( u.al.p1>0 && u.al.p1+mx<=(p->nMem-p->nCursor)+1 ); | |
| 67804 | + assert( u.al.p2>0 && u.al.p2+mx<=(p->nMem-p->nCursor)+1 ); | |
| 67405 | 67805 | }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 ); | |
| 67806 | + assert( u.al.p1>0 && u.al.p1+u.al.n<=(p->nMem-p->nCursor)+1 ); | |
| 67807 | + assert( u.al.p2>0 && u.al.p2+u.al.n<=(p->nMem-p->nCursor)+1 ); | |
| 67408 | 67808 | } |
| 67409 | 67809 | #endif /* SQLITE_DEBUG */ |
| 67410 | 67810 | for(u.al.i=0; u.al.i<u.al.n; u.al.i++){ |
| 67411 | 67811 | u.al.idx = aPermute ? aPermute[u.al.i] : u.al.i; |
| 67412 | 67812 | assert( memIsValid(&aMem[u.al.p1+u.al.idx]) ); |
| @@ -67659,11 +68059,11 @@ | ||
| 67659 | 68059 | u.ao.p1 = pOp->p1; |
| 67660 | 68060 | u.ao.p2 = pOp->p2; |
| 67661 | 68061 | u.ao.pC = 0; |
| 67662 | 68062 | memset(&u.ao.sMem, 0, sizeof(u.ao.sMem)); |
| 67663 | 68063 | assert( u.ao.p1<p->nCursor ); |
| 67664 | - assert( pOp->p3>0 && pOp->p3<=p->nMem ); | |
| 68064 | + assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) ); | |
| 67665 | 68065 | u.ao.pDest = &aMem[pOp->p3]; |
| 67666 | 68066 | memAboutToChange(p, u.ao.pDest); |
| 67667 | 68067 | u.ao.zRec = 0; |
| 67668 | 68068 | |
| 67669 | 68069 | /* This block sets the variable u.ao.payloadSize to be the total number of |
| @@ -67959,11 +68359,11 @@ | ||
| 67959 | 68359 | u.ap.zAffinity = pOp->p4.z; |
| 67960 | 68360 | assert( u.ap.zAffinity!=0 ); |
| 67961 | 68361 | assert( u.ap.zAffinity[pOp->p2]==0 ); |
| 67962 | 68362 | pIn1 = &aMem[pOp->p1]; |
| 67963 | 68363 | while( (u.ap.cAff = *(u.ap.zAffinity++))!=0 ){ |
| 67964 | - assert( pIn1 <= &p->aMem[p->nMem] ); | |
| 68364 | + assert( pIn1 <= &p->aMem[(p->nMem-p->nCursor)] ); | |
| 67965 | 68365 | assert( memIsValid(pIn1) ); |
| 67966 | 68366 | ExpandBlob(pIn1); |
| 67967 | 68367 | applyAffinity(pIn1, u.ap.cAff, encoding); |
| 67968 | 68368 | pIn1++; |
| 67969 | 68369 | } |
| @@ -68022,11 +68422,11 @@ | ||
| 68022 | 68422 | u.aq.nData = 0; /* Number of bytes of data space */ |
| 68023 | 68423 | u.aq.nHdr = 0; /* Number of bytes of header space */ |
| 68024 | 68424 | u.aq.nZero = 0; /* Number of zero bytes at the end of the record */ |
| 68025 | 68425 | u.aq.nField = pOp->p1; |
| 68026 | 68426 | u.aq.zAffinity = pOp->p4.z; |
| 68027 | - assert( u.aq.nField>0 && pOp->p2>0 && pOp->p2+u.aq.nField<=p->nMem+1 ); | |
| 68427 | + assert( u.aq.nField>0 && pOp->p2>0 && pOp->p2+u.aq.nField<=(p->nMem-p->nCursor)+1 ); | |
| 68028 | 68428 | u.aq.pData0 = &aMem[u.aq.nField]; |
| 68029 | 68429 | u.aq.nField = pOp->p2; |
| 68030 | 68430 | u.aq.pLast = &u.aq.pData0[u.aq.nField-1]; |
| 68031 | 68431 | u.aq.file_format = p->minWriteFileFormat; |
| 68032 | 68432 | |
| @@ -68088,11 +68488,11 @@ | ||
| 68088 | 68488 | for(u.aq.pRec=u.aq.pData0; u.aq.pRec<=u.aq.pLast; u.aq.pRec++){ /* serial data */ |
| 68089 | 68489 | 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 | 68490 | } |
| 68091 | 68491 | assert( u.aq.i==u.aq.nByte ); |
| 68092 | 68492 | |
| 68093 | - assert( pOp->p3>0 && pOp->p3<=p->nMem ); | |
| 68493 | + assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) ); | |
| 68094 | 68494 | pOut->n = (int)u.aq.nByte; |
| 68095 | 68495 | pOut->flags = MEM_Blob | MEM_Dyn; |
| 68096 | 68496 | pOut->xDel = 0; |
| 68097 | 68497 | if( u.aq.nZero ){ |
| 68098 | 68498 | pOut->u.nZero = u.aq.nZero; |
| @@ -68684,11 +69084,11 @@ | ||
| 68684 | 69084 | }else{ |
| 68685 | 69085 | u.ay.wrFlag = 0; |
| 68686 | 69086 | } |
| 68687 | 69087 | if( pOp->p5 & OPFLAG_P2ISREG ){ |
| 68688 | 69088 | assert( u.ay.p2>0 ); |
| 68689 | - assert( u.ay.p2<=p->nMem ); | |
| 69089 | + assert( u.ay.p2<=(p->nMem-p->nCursor) ); | |
| 68690 | 69090 | pIn2 = &aMem[u.ay.p2]; |
| 68691 | 69091 | assert( memIsValid(pIn2) ); |
| 68692 | 69092 | assert( (pIn2->flags & MEM_Int)!=0 ); |
| 68693 | 69093 | sqlite3VdbeMemIntegerify(pIn2); |
| 68694 | 69094 | u.ay.p2 = (int)pIn2->u.i; |
| @@ -69235,11 +69635,11 @@ | ||
| 69235 | 69635 | |
| 69236 | 69636 | pIn3 = &aMem[pOp->p3]; |
| 69237 | 69637 | u.bf.aMx = &aMem[pOp->p4.i]; |
| 69238 | 69638 | /* Assert that the values of parameters P1 and P4 are in range. */ |
| 69239 | 69639 | assert( pOp->p4type==P4_INT32 ); |
| 69240 | - assert( pOp->p4.i>0 && pOp->p4.i<=p->nMem ); | |
| 69640 | + assert( pOp->p4.i>0 && pOp->p4.i<=(p->nMem-p->nCursor) ); | |
| 69241 | 69641 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 69242 | 69642 | |
| 69243 | 69643 | /* Find the index cursor. */ |
| 69244 | 69644 | u.bf.pCx = p->apCsr[pOp->p1]; |
| 69245 | 69645 | assert( u.bf.pCx->deferredMoveto==0 ); |
| @@ -69442,11 +69842,11 @@ | ||
| 69442 | 69842 | /* Assert that P3 is a valid memory cell. */ |
| 69443 | 69843 | assert( pOp->p3<=u.bh.pFrame->nMem ); |
| 69444 | 69844 | u.bh.pMem = &u.bh.pFrame->aMem[pOp->p3]; |
| 69445 | 69845 | }else{ |
| 69446 | 69846 | /* Assert that P3 is a valid memory cell. */ |
| 69447 | - assert( pOp->p3<=p->nMem ); | |
| 69847 | + assert( pOp->p3<=(p->nMem-p->nCursor) ); | |
| 69448 | 69848 | u.bh.pMem = &aMem[pOp->p3]; |
| 69449 | 69849 | memAboutToChange(p, u.bh.pMem); |
| 69450 | 69850 | } |
| 69451 | 69851 | assert( memIsValid(u.bh.pMem) ); |
| 69452 | 69852 | |
| @@ -70120,11 +70520,11 @@ | ||
| 70120 | 70520 | int res; |
| 70121 | 70521 | UnpackedRecord r; |
| 70122 | 70522 | #endif /* local variables moved into u.bt */ |
| 70123 | 70523 | |
| 70124 | 70524 | assert( pOp->p3>0 ); |
| 70125 | - assert( pOp->p2>0 && pOp->p2+pOp->p3<=p->nMem+1 ); | |
| 70525 | + assert( pOp->p2>0 && pOp->p2+pOp->p3<=(p->nMem-p->nCursor)+1 ); | |
| 70126 | 70526 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 70127 | 70527 | u.bt.pC = p->apCsr[pOp->p1]; |
| 70128 | 70528 | assert( u.bt.pC!=0 ); |
| 70129 | 70529 | u.bt.pCrsr = u.bt.pC->pCursor; |
| 70130 | 70530 | if( ALWAYS(u.bt.pCrsr!=0) ){ |
| @@ -70336,10 +70736,11 @@ | ||
| 70336 | 70736 | int nChange; |
| 70337 | 70737 | #endif /* local variables moved into u.bx */ |
| 70338 | 70738 | |
| 70339 | 70739 | u.bx.nChange = 0; |
| 70340 | 70740 | assert( p->readOnly==0 ); |
| 70741 | + assert( pOp->p1!=1 ); | |
| 70341 | 70742 | assert( (p->btreeMask & (((yDbMask)1)<<pOp->p2))!=0 ); |
| 70342 | 70743 | rc = sqlite3BtreeClearTable( |
| 70343 | 70744 | db->aDb[pOp->p2].pBt, pOp->p1, (pOp->p3 ? &u.bx.nChange : 0) |
| 70344 | 70745 | ); |
| 70345 | 70746 | if( pOp->p3 ){ |
| @@ -70542,11 +70943,11 @@ | ||
| 70542 | 70943 | assert( p->bIsReader ); |
| 70543 | 70944 | u.ca.nRoot = pOp->p2; |
| 70544 | 70945 | assert( u.ca.nRoot>0 ); |
| 70545 | 70946 | u.ca.aRoot = sqlite3DbMallocRaw(db, sizeof(int)*(u.ca.nRoot+1) ); |
| 70546 | 70947 | if( u.ca.aRoot==0 ) goto no_mem; |
| 70547 | - assert( pOp->p3>0 && pOp->p3<=p->nMem ); | |
| 70948 | + assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) ); | |
| 70548 | 70949 | u.ca.pnErr = &aMem[pOp->p3]; |
| 70549 | 70950 | assert( (u.ca.pnErr->flags & MEM_Int)!=0 ); |
| 70550 | 70951 | assert( (u.ca.pnErr->flags & (MEM_Str|MEM_Blob))==0 ); |
| 70551 | 70952 | pIn1 = &aMem[pOp->p1]; |
| 70552 | 70953 | for(u.ca.j=0; u.ca.j<u.ca.nRoot; u.ca.j++){ |
| @@ -70978,11 +71379,11 @@ | ||
| 70978 | 71379 | u.cg.apVal[u.cg.i] = u.cg.pRec; |
| 70979 | 71380 | memAboutToChange(p, u.cg.pRec); |
| 70980 | 71381 | sqlite3VdbeMemStoreType(u.cg.pRec); |
| 70981 | 71382 | } |
| 70982 | 71383 | u.cg.ctx.pFunc = pOp->p4.pFunc; |
| 70983 | - assert( pOp->p3>0 && pOp->p3<=p->nMem ); | |
| 71384 | + assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) ); | |
| 70984 | 71385 | u.cg.ctx.pMem = u.cg.pMem = &aMem[pOp->p3]; |
| 70985 | 71386 | u.cg.pMem->n++; |
| 70986 | 71387 | u.cg.ctx.s.flags = MEM_Null; |
| 70987 | 71388 | u.cg.ctx.s.z = 0; |
| 70988 | 71389 | u.cg.ctx.s.zMalloc = 0; |
| @@ -71027,11 +71428,11 @@ | ||
| 71027 | 71428 | */ |
| 71028 | 71429 | case OP_AggFinal: { |
| 71029 | 71430 | #if 0 /* local variables moved into u.ch */ |
| 71030 | 71431 | Mem *pMem; |
| 71031 | 71432 | #endif /* local variables moved into u.ch */ |
| 71032 | - assert( pOp->p1>0 && pOp->p1<=p->nMem ); | |
| 71433 | + assert( pOp->p1>0 && pOp->p1<=(p->nMem-p->nCursor) ); | |
| 71033 | 71434 | u.ch.pMem = &aMem[pOp->p1]; |
| 71034 | 71435 | assert( (u.ch.pMem->flags & ~(MEM_Null|MEM_Agg))==0 ); |
| 71035 | 71436 | rc = sqlite3VdbeMemFinalize(u.ch.pMem, pOp->p4.pFunc); |
| 71036 | 71437 | if( rc ){ |
| 71037 | 71438 | sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(u.ch.pMem)); |
| @@ -71458,11 +71859,11 @@ | ||
| 71458 | 71859 | sqlite3_context sContext; |
| 71459 | 71860 | #endif /* local variables moved into u.co */ |
| 71460 | 71861 | |
| 71461 | 71862 | VdbeCursor *pCur = p->apCsr[pOp->p1]; |
| 71462 | 71863 | assert( pCur->pVtabCursor ); |
| 71463 | - assert( pOp->p3>0 && pOp->p3<=p->nMem ); | |
| 71864 | + assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) ); | |
| 71464 | 71865 | u.co.pDest = &aMem[pOp->p3]; |
| 71465 | 71866 | memAboutToChange(p, u.co.pDest); |
| 71466 | 71867 | if( pCur->nullRow ){ |
| 71467 | 71868 | sqlite3VdbeMemSetNull(u.co.pDest); |
| 71468 | 71869 | break; |
| @@ -76729,11 +77130,11 @@ | ||
| 76729 | 77130 | break; |
| 76730 | 77131 | } |
| 76731 | 77132 | case TK_UMINUS: { |
| 76732 | 77133 | int v; |
| 76733 | 77134 | if( sqlite3ExprIsInteger(p->pLeft, &v) ){ |
| 76734 | - assert( v!=-2147483648 ); | |
| 77135 | + assert( v!=(-2147483647-1) ); | |
| 76735 | 77136 | *pValue = -v; |
| 76736 | 77137 | rc = 1; |
| 76737 | 77138 | } |
| 76738 | 77139 | break; |
| 76739 | 77140 | } |
| @@ -80389,11 +80790,11 @@ | ||
| 80389 | 80790 | |
| 80390 | 80791 | /* Ensure the default expression is something that sqlite3ValueFromExpr() |
| 80391 | 80792 | ** can handle (i.e. not CURRENT_TIME etc.) |
| 80392 | 80793 | */ |
| 80393 | 80794 | if( pDflt ){ |
| 80394 | - sqlite3_value *pVal; | |
| 80795 | + sqlite3_value *pVal = 0; | |
| 80395 | 80796 | if( sqlite3ValueFromExpr(db, pDflt, SQLITE_UTF8, SQLITE_AFF_NONE, &pVal) ){ |
| 80396 | 80797 | db->mallocFailed = 1; |
| 80397 | 80798 | return; |
| 80398 | 80799 | } |
| 80399 | 80800 | if( !pVal ){ |
| @@ -80530,11 +80931,11 @@ | ||
| 80530 | 80931 | #endif /* SQLITE_ALTER_TABLE */ |
| 80531 | 80932 | |
| 80532 | 80933 | /************** End of alter.c ***********************************************/ |
| 80533 | 80934 | /************** Begin file analyze.c *****************************************/ |
| 80534 | 80935 | /* |
| 80535 | -** 2005 July 8 | |
| 80936 | +** 2005-07-08 | |
| 80536 | 80937 | ** |
| 80537 | 80938 | ** The author disclaims copyright to this source code. In place of |
| 80538 | 80939 | ** a legal notice, here is a blessing: |
| 80539 | 80940 | ** |
| 80540 | 80941 | ** May you do good and not evil. |
| @@ -80551,27 +80952,36 @@ | ||
| 80551 | 80952 | ** The following system tables are or have been supported: |
| 80552 | 80953 | ** |
| 80553 | 80954 | ** CREATE TABLE sqlite_stat1(tbl, idx, stat); |
| 80554 | 80955 | ** CREATE TABLE sqlite_stat2(tbl, idx, sampleno, sample); |
| 80555 | 80956 | ** CREATE TABLE sqlite_stat3(tbl, idx, nEq, nLt, nDLt, sample); |
| 80957 | +** CREATE TABLE sqlite_stat4(tbl, idx, nEq, nLt, nDLt, sample); | |
| 80556 | 80958 | ** |
| 80557 | 80959 | ** Additional tables might be added in future releases of SQLite. |
| 80558 | 80960 | ** The sqlite_stat2 table is not created or used unless the SQLite version |
| 80559 | 80961 | ** is between 3.6.18 and 3.7.8, inclusive, and unless SQLite is compiled |
| 80560 | 80962 | ** with SQLITE_ENABLE_STAT2. The sqlite_stat2 table is deprecated. |
| 80561 | 80963 | ** The sqlite_stat2 table is superseded by sqlite_stat3, which is only |
| 80562 | 80964 | ** 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. | |
| 80965 | +** SQLITE_ENABLE_STAT3 defined. The functionality of sqlite_stat3 | |
| 80966 | +** is a superset of sqlite_stat2. The sqlite_stat4 is an enhanced | |
| 80967 | +** version of sqlite_stat3 and is only available when compiled with | |
| 80968 | +** SQLITE_ENABLE_STAT4 and in SQLite versions 3.8.0 and later. It is | |
| 80969 | +** not possible to enable both STAT3 and STAT4 at the same time. If they | |
| 80970 | +** are both enabled, then STAT4 is precedence. | |
| 80971 | +** | |
| 80972 | +** For most applications, sqlite_stat1 provides all the statisics required | |
| 80973 | +** for the query planner to make good choices. | |
| 80565 | 80974 | ** |
| 80566 | 80975 | ** Format of sqlite_stat1: |
| 80567 | 80976 | ** |
| 80568 | 80977 | ** There is normally one row per index, with the index identified by the |
| 80569 | 80978 | ** name in the idx column. The tbl column is the name of the table to |
| 80570 | 80979 | ** which the index belongs. In each such row, the stat column will be |
| 80571 | 80980 | ** 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 | |
| 80981 | +** list is the number of rows in the index. (This is the same as the | |
| 80982 | +** number of rows in the table, except for partial indices.) The second | |
| 80573 | 80983 | ** integer is the average number of rows in the index that have the same |
| 80574 | 80984 | ** value in the first column of the index. The third integer is the average |
| 80575 | 80985 | ** number of rows in the index that have the same value for the first two |
| 80576 | 80986 | ** columns. The N-th integer (for N>1) is the average number of rows in |
| 80577 | 80987 | ** the index which have the same value for the first N-1 columns. For |
| @@ -80614,57 +81024,85 @@ | ||
| 80614 | 81024 | ** writes the sqlite_stat2 table. This version of SQLite only supports |
| 80615 | 81025 | ** sqlite_stat3. |
| 80616 | 81026 | ** |
| 80617 | 81027 | ** Format for sqlite_stat3: |
| 80618 | 81028 | ** |
| 80619 | -** The sqlite_stat3 is an enhancement to sqlite_stat2. A new name is | |
| 80620 | -** used to avoid compatibility problems. | |
| 81029 | +** The sqlite_stat3 format is a subset of sqlite_stat4. Hence, the | |
| 81030 | +** sqlite_stat4 format will be described first. Further information | |
| 81031 | +** about sqlite_stat3 follows the sqlite_stat4 description. | |
| 80621 | 81032 | ** |
| 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. | |
| 81033 | +** Format for sqlite_stat4: | |
| 81034 | +** | |
| 81035 | +** As with sqlite_stat2, the sqlite_stat4 table contains histogram data | |
| 81036 | +** to aid the query planner in choosing good indices based on the values | |
| 81037 | +** that indexed columns are compared against in the WHERE clauses of | |
| 81038 | +** queries. | |
| 81039 | +** | |
| 81040 | +** The sqlite_stat4 table contains multiple entries for each index. | |
| 80624 | 81041 | ** The idx column names the index and the tbl column is the table of the |
| 80625 | 81042 | ** 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 | |
| 81043 | +** of the INTEGER PRIMARY KEY. The sample column is a blob which is the | |
| 81044 | +** binary encoding of a key from the index, with the trailing rowid | |
| 81045 | +** omitted. The nEq column is a list of integers. The first integer | |
| 81046 | +** is the approximate number of entries in the index whose left-most | |
| 81047 | +** column exactly matches the left-most column of the sample. The second | |
| 81048 | +** integer in nEq is the approximate number of entries in the index where | |
| 81049 | +** the first two columns match the first two columns of the sample. | |
| 81050 | +** And so forth. nLt is another list of integers that show the approximate | |
| 81051 | +** number of entries that are strictly less than the sample. The first | |
| 81052 | +** integer in nLt contains the number of entries in the index where the | |
| 81053 | +** left-most column is less than the left-most column of the sample. | |
| 81054 | +** The K-th integer in the nLt entry is the number of index entries | |
| 81055 | +** where the first K columns are less than the first K columns of the | |
| 81056 | +** sample. The nDLt column is like nLt except that it contains the | |
| 81057 | +** number of distinct entries in the index that are less than the | |
| 81058 | +** sample. | |
| 81059 | +** | |
| 81060 | +** There can be an arbitrary number of sqlite_stat4 entries per index. | |
| 81061 | +** The ANALYZE command will typically generate sqlite_stat4 tables | |
| 80645 | 81062 | ** that contain between 10 and 40 samples which are distributed across |
| 80646 | 81063 | ** the key space, though not uniformly, and which include samples with |
| 80647 | -** largest possible nEq values. | |
| 81064 | +** large nEq values. | |
| 81065 | +** | |
| 81066 | +** Format for sqlite_stat3 redux: | |
| 81067 | +** | |
| 81068 | +** The sqlite_stat3 table is like sqlite_stat4 except that it only | |
| 81069 | +** looks at the left-most column of the index. The sqlite_stat3.sample | |
| 81070 | +** column contains the actual value of the left-most column instead | |
| 81071 | +** of a blob encoding of the complete index key as is found in | |
| 81072 | +** sqlite_stat4.sample. The nEq, nLt, and nDLt entries of sqlite_stat3 | |
| 81073 | +** all contain just a single integer which is the same as the first | |
| 81074 | +** integer in the equivalent columns in sqlite_stat4. | |
| 80648 | 81075 | */ |
| 80649 | 81076 | #ifndef SQLITE_OMIT_ANALYZE |
| 80650 | 81077 | |
| 81078 | +#if defined(SQLITE_ENABLE_STAT4) | |
| 81079 | +# define IsStat4 1 | |
| 81080 | +# define IsStat3 0 | |
| 81081 | +#elif defined(SQLITE_ENABLE_STAT3) | |
| 81082 | +# define IsStat4 0 | |
| 81083 | +# define IsStat3 1 | |
| 81084 | +#else | |
| 81085 | +# define IsStat4 0 | |
| 81086 | +# define IsStat3 0 | |
| 81087 | +# undef SQLITE_STAT4_SAMPLES | |
| 81088 | +# define SQLITE_STAT4_SAMPLES 1 | |
| 81089 | +#endif | |
| 81090 | +#define IsStat34 (IsStat3+IsStat4) /* 1 for STAT3 or STAT4. 0 otherwise */ | |
| 81091 | + | |
| 80651 | 81092 | /* |
| 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) | |
| 81093 | +** This routine generates code that opens the sqlite_statN tables. | |
| 81094 | +** The sqlite_stat1 table is always relevant. sqlite_stat2 is now | |
| 81095 | +** obsolete. sqlite_stat3 and sqlite_stat4 are only opened when | |
| 81096 | +** appropriate compile-time options are provided. | |
| 80656 | 81097 | ** |
| 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. | |
| 81098 | +** If the sqlite_statN tables do not previously exist, it is created. | |
| 80660 | 81099 | ** |
| 80661 | 81100 | ** Argument zWhere may be a pointer to a buffer containing a table name, |
| 80662 | 81101 | ** 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. | |
| 81102 | +** the sqlite_statN tables associated with the named table are deleted. | |
| 81103 | +** If zWhere==0, then code is generated to delete all stat table entries. | |
| 80666 | 81104 | */ |
| 80667 | 81105 | static void openStatTable( |
| 80668 | 81106 | Parse *pParse, /* Parsing context */ |
| 80669 | 81107 | int iDb, /* The database we are looking in */ |
| 80670 | 81108 | int iStatCur, /* Open the sqlite_stat1 table on this cursor */ |
| @@ -80674,22 +81112,28 @@ | ||
| 80674 | 81112 | static const struct { |
| 80675 | 81113 | const char *zName; |
| 80676 | 81114 | const char *zCols; |
| 80677 | 81115 | } aTable[] = { |
| 80678 | 81116 | { "sqlite_stat1", "tbl,idx,stat" }, |
| 80679 | -#ifdef SQLITE_ENABLE_STAT3 | |
| 81117 | +#if defined(SQLITE_ENABLE_STAT4) | |
| 81118 | + { "sqlite_stat4", "tbl,idx,neq,nlt,ndlt,sample" }, | |
| 81119 | + { "sqlite_stat3", 0 }, | |
| 81120 | +#elif defined(SQLITE_ENABLE_STAT3) | |
| 80680 | 81121 | { "sqlite_stat3", "tbl,idx,neq,nlt,ndlt,sample" }, |
| 81122 | + { "sqlite_stat4", 0 }, | |
| 81123 | +#else | |
| 81124 | + { "sqlite_stat3", 0 }, | |
| 81125 | + { "sqlite_stat4", 0 }, | |
| 80681 | 81126 | #endif |
| 80682 | 81127 | }; |
| 80683 | - | |
| 80684 | - int aRoot[] = {0, 0}; | |
| 80685 | - u8 aCreateTbl[] = {0, 0}; | |
| 80686 | - | |
| 80687 | 81128 | int i; |
| 80688 | 81129 | sqlite3 *db = pParse->db; |
| 80689 | 81130 | Db *pDb; |
| 80690 | 81131 | Vdbe *v = sqlite3GetVdbe(pParse); |
| 81132 | + int aRoot[ArraySize(aTable)]; | |
| 81133 | + u8 aCreateTbl[ArraySize(aTable)]; | |
| 81134 | + | |
| 80691 | 81135 | if( v==0 ) return; |
| 80692 | 81136 | assert( sqlite3BtreeHoldsAllMutexes(db) ); |
| 80693 | 81137 | assert( sqlite3VdbeDb(v)==db ); |
| 80694 | 81138 | pDb = &db->aDb[iDb]; |
| 80695 | 81139 | |
| @@ -80698,262 +81142,592 @@ | ||
| 80698 | 81142 | */ |
| 80699 | 81143 | for(i=0; i<ArraySize(aTable); i++){ |
| 80700 | 81144 | const char *zTab = aTable[i].zName; |
| 80701 | 81145 | Table *pStat; |
| 80702 | 81146 | 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; | |
| 81147 | + if( aTable[i].zCols ){ | |
| 81148 | + /* The sqlite_statN table does not exist. Create it. Note that a | |
| 81149 | + ** side-effect of the CREATE TABLE statement is to leave the rootpage | |
| 81150 | + ** of the new table in register pParse->regRoot. This is important | |
| 81151 | + ** because the OpenWrite opcode below will be needing it. */ | |
| 81152 | + sqlite3NestedParse(pParse, | |
| 81153 | + "CREATE TABLE %Q.%s(%s)", pDb->zName, zTab, aTable[i].zCols | |
| 81154 | + ); | |
| 81155 | + aRoot[i] = pParse->regRoot; | |
| 81156 | + aCreateTbl[i] = OPFLAG_P2ISREG; | |
| 81157 | + } | |
| 80712 | 81158 | }else{ |
| 80713 | 81159 | /* The table already exists. If zWhere is not NULL, delete all entries |
| 80714 | 81160 | ** associated with the table zWhere. If zWhere is NULL, delete the |
| 80715 | 81161 | ** entire contents of the table. */ |
| 80716 | 81162 | aRoot[i] = pStat->tnum; |
| 81163 | + aCreateTbl[i] = 0; | |
| 80717 | 81164 | sqlite3TableLock(pParse, iDb, aRoot[i], 1, zTab); |
| 80718 | 81165 | if( zWhere ){ |
| 80719 | 81166 | sqlite3NestedParse(pParse, |
| 80720 | - "DELETE FROM %Q.%s WHERE %s=%Q", pDb->zName, zTab, zWhereType, zWhere | |
| 81167 | + "DELETE FROM %Q.%s WHERE %s=%Q", | |
| 81168 | + pDb->zName, zTab, zWhereType, zWhere | |
| 80721 | 81169 | ); |
| 80722 | 81170 | }else{ |
| 80723 | - /* The sqlite_stat[12] table already exists. Delete all rows. */ | |
| 81171 | + /* The sqlite_stat[134] table already exists. Delete all rows. */ | |
| 80724 | 81172 | sqlite3VdbeAddOp2(v, OP_Clear, aRoot[i], iDb); |
| 80725 | 81173 | } |
| 80726 | 81174 | } |
| 80727 | 81175 | } |
| 80728 | 81176 | |
| 80729 | - /* Open the sqlite_stat[13] tables for writing. */ | |
| 80730 | - for(i=0; i<ArraySize(aTable); i++){ | |
| 81177 | + /* Open the sqlite_stat[134] tables for writing. */ | |
| 81178 | + for(i=0; aTable[i].zCols; i++){ | |
| 81179 | + assert( i<ArraySize(aTable) ); | |
| 80731 | 81180 | sqlite3VdbeAddOp3(v, OP_OpenWrite, iStatCur+i, aRoot[i], iDb); |
| 80732 | 81181 | sqlite3VdbeChangeP4(v, -1, (char *)3, P4_INT32); |
| 80733 | 81182 | sqlite3VdbeChangeP5(v, aCreateTbl[i]); |
| 80734 | 81183 | } |
| 80735 | 81184 | } |
| 80736 | 81185 | |
| 80737 | 81186 | /* |
| 80738 | -** Recommended number of samples for sqlite_stat3 | |
| 81187 | +** Recommended number of samples for sqlite_stat4 | |
| 80739 | 81188 | */ |
| 80740 | -#ifndef SQLITE_STAT3_SAMPLES | |
| 80741 | -# define SQLITE_STAT3_SAMPLES 24 | |
| 81189 | +#ifndef SQLITE_STAT4_SAMPLES | |
| 81190 | +# define SQLITE_STAT4_SAMPLES 24 | |
| 80742 | 81191 | #endif |
| 80743 | 81192 | |
| 80744 | 81193 | /* |
| 80745 | -** Three SQL functions - stat3_init(), stat3_push(), and stat3_pop() - | |
| 81194 | +** Three SQL functions - stat_init(), stat_push(), and stat_get() - | |
| 80746 | 81195 | ** share an instance of the following structure to hold their state |
| 80747 | 81196 | ** information. |
| 80748 | 81197 | */ |
| 80749 | -typedef struct Stat3Accum Stat3Accum; | |
| 80750 | -struct Stat3Accum { | |
| 81198 | +typedef struct Stat4Accum Stat4Accum; | |
| 81199 | +typedef struct Stat4Sample Stat4Sample; | |
| 81200 | +struct Stat4Sample { | |
| 81201 | + tRowcnt *anEq; /* sqlite_stat4.nEq */ | |
| 81202 | + tRowcnt *anDLt; /* sqlite_stat4.nDLt */ | |
| 81203 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 | |
| 81204 | + tRowcnt *anLt; /* sqlite_stat4.nLt */ | |
| 81205 | + i64 iRowid; /* Rowid in main table of the key */ | |
| 81206 | + u8 isPSample; /* True if a periodic sample */ | |
| 81207 | + int iCol; /* If !isPSample, the reason for inclusion */ | |
| 81208 | + u32 iHash; /* Tiebreaker hash */ | |
| 81209 | +#endif | |
| 81210 | +}; | |
| 81211 | +struct Stat4Accum { | |
| 80751 | 81212 | tRowcnt nRow; /* Number of rows in the entire table */ |
| 80752 | 81213 | tRowcnt nPSample; /* How often to do a periodic sample */ |
| 80753 | - int iMin; /* Index of entry with minimum nEq and hash */ | |
| 81214 | + int nCol; /* Number of columns in index + rowid */ | |
| 80754 | 81215 | int mxSample; /* Maximum number of samples to accumulate */ |
| 80755 | - int nSample; /* Current number of samples */ | |
| 81216 | + Stat4Sample current; /* Current row as a Stat4Sample */ | |
| 80756 | 81217 | 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 */ | |
| 81218 | + Stat4Sample *aBest; /* Array of (nCol-1) best samples */ | |
| 81219 | + int iMin; /* Index in a[] of entry with minimum score */ | |
| 81220 | + int nSample; /* Current number of samples */ | |
| 81221 | + int iGet; /* Index of current sample accessed by stat_get() */ | |
| 81222 | + Stat4Sample *a; /* Array of mxSample Stat4Sample objects */ | |
| 80765 | 81223 | }; |
| 80766 | 81224 | |
| 80767 | -#ifdef SQLITE_ENABLE_STAT3 | |
| 80768 | 81225 | /* |
| 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( | |
| 81226 | +** Implementation of the stat_init(N,C) SQL function. The two parameters | |
| 81227 | +** are the number of rows in the table or index (C) and the number of columns | |
| 81228 | +** in the index (N). The second argument (C) is only used for STAT3 and STAT4. | |
| 81229 | +** | |
| 81230 | +** This routine allocates the Stat4Accum object in heap memory. The return | |
| 81231 | +** value is a pointer to the the Stat4Accum object encoded as a blob (i.e. | |
| 81232 | +** the size of the blob is sizeof(void*) bytes). | |
| 81233 | +*/ | |
| 81234 | +static void statInit( | |
| 80778 | 81235 | sqlite3_context *context, |
| 80779 | 81236 | int argc, |
| 80780 | 81237 | sqlite3_value **argv |
| 80781 | 81238 | ){ |
| 80782 | - Stat3Accum *p; | |
| 80783 | - tRowcnt nRow; | |
| 80784 | - int mxSample; | |
| 80785 | - int n; | |
| 81239 | + Stat4Accum *p; | |
| 81240 | + int nCol; /* Number of columns in index being sampled */ | |
| 81241 | + int nColUp; /* nCol rounded up for alignment */ | |
| 81242 | + int n; /* Bytes of space to allocate */ | |
| 81243 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 | |
| 81244 | + int mxSample = SQLITE_STAT4_SAMPLES; | |
| 81245 | +#endif | |
| 80786 | 81246 | |
| 81247 | + /* Decode the three function arguments */ | |
| 80787 | 81248 | 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 ); | |
| 81249 | + nCol = sqlite3_value_int(argv[0]); | |
| 81250 | + assert( nCol>1 ); /* >1 because it includes the rowid column */ | |
| 81251 | + nColUp = sizeof(tRowcnt)<8 ? (nCol+1)&~1 : nCol; | |
| 81252 | + | |
| 81253 | + /* Allocate the space required for the Stat4Accum object */ | |
| 81254 | + n = sizeof(*p) | |
| 81255 | + + sizeof(tRowcnt)*nColUp /* Stat4Accum.anEq */ | |
| 81256 | + + sizeof(tRowcnt)*nColUp /* Stat4Accum.anDLt */ | |
| 81257 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 | |
| 81258 | + + sizeof(tRowcnt)*nColUp /* Stat4Accum.anLt */ | |
| 81259 | + + sizeof(Stat4Sample)*(nCol+mxSample) /* Stat4Accum.aBest[], a[] */ | |
| 81260 | + + sizeof(tRowcnt)*3*nColUp*(nCol+mxSample) | |
| 81261 | +#endif | |
| 81262 | + ; | |
| 81263 | + p = sqlite3MallocZero(n); | |
| 80792 | 81264 | if( p==0 ){ |
| 80793 | 81265 | sqlite3_result_error_nomem(context); |
| 80794 | 81266 | return; |
| 80795 | 81267 | } |
| 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); | |
| 81268 | + | |
| 81269 | + p->nRow = 0; | |
| 81270 | + p->nCol = nCol; | |
| 81271 | + p->current.anDLt = (tRowcnt*)&p[1]; | |
| 81272 | + p->current.anEq = &p->current.anDLt[nColUp]; | |
| 81273 | + | |
| 81274 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 | |
| 81275 | + { | |
| 81276 | + u8 *pSpace; /* Allocated space not yet assigned */ | |
| 81277 | + int i; /* Used to iterate through p->aSample[] */ | |
| 81278 | + | |
| 81279 | + p->iGet = -1; | |
| 81280 | + p->mxSample = mxSample; | |
| 81281 | + p->nPSample = sqlite3_value_int64(argv[1])/(mxSample/3+1) + 1; | |
| 81282 | + p->current.anLt = &p->current.anEq[nColUp]; | |
| 81283 | + sqlite3_randomness(sizeof(p->iPrn), &p->iPrn); | |
| 81284 | + | |
| 81285 | + /* Set up the Stat4Accum.a[] and aBest[] arrays */ | |
| 81286 | + p->a = (struct Stat4Sample*)&p->current.anLt[nColUp]; | |
| 81287 | + p->aBest = &p->a[mxSample]; | |
| 81288 | + pSpace = (u8*)(&p->a[mxSample+nCol]); | |
| 81289 | + for(i=0; i<(mxSample+nCol); i++){ | |
| 81290 | + p->a[i].anEq = (tRowcnt *)pSpace; pSpace += (sizeof(tRowcnt) * nColUp); | |
| 81291 | + p->a[i].anLt = (tRowcnt *)pSpace; pSpace += (sizeof(tRowcnt) * nColUp); | |
| 81292 | + p->a[i].anDLt = (tRowcnt *)pSpace; pSpace += (sizeof(tRowcnt) * nColUp); | |
| 81293 | + } | |
| 81294 | + assert( (pSpace - (u8*)p)==n ); | |
| 81295 | + | |
| 81296 | + for(i=0; i<nCol; i++){ | |
| 81297 | + p->aBest[i].iCol = i; | |
| 81298 | + } | |
| 81299 | + } | |
| 81300 | +#endif | |
| 81301 | + | |
| 81302 | + /* Return a pointer to the allocated object to the caller */ | |
| 80801 | 81303 | sqlite3_result_blob(context, p, sizeof(p), sqlite3_free); |
| 80802 | 81304 | } |
| 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)); | |
| 81305 | +static const FuncDef statInitFuncdef = { | |
| 81306 | + 1+IsStat34, /* nArg */ | |
| 81307 | + SQLITE_UTF8, /* iPrefEnc */ | |
| 81308 | + 0, /* flags */ | |
| 81309 | + 0, /* pUserData */ | |
| 81310 | + 0, /* pNext */ | |
| 81311 | + statInit, /* xFunc */ | |
| 81312 | + 0, /* xStep */ | |
| 81313 | + 0, /* xFinalize */ | |
| 81314 | + "stat_init", /* zName */ | |
| 81315 | + 0, /* pHash */ | |
| 81316 | + 0 /* pDestructor */ | |
| 81317 | +}; | |
| 81318 | + | |
| 81319 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 | |
| 81320 | +/* | |
| 81321 | +** Return true if pNew is to be preferred over pOld. | |
| 81322 | +*/ | |
| 81323 | +static int sampleIsBetter(Stat4Sample *pNew, Stat4Sample *pOld){ | |
| 81324 | + tRowcnt nEqNew = pNew->anEq[pNew->iCol]; | |
| 81325 | + tRowcnt nEqOld = pOld->anEq[pOld->iCol]; | |
| 81326 | + | |
| 81327 | + assert( pOld->isPSample==0 && pNew->isPSample==0 ); | |
| 81328 | + assert( IsStat4 || (pNew->iCol==0 && pOld->iCol==0) ); | |
| 81329 | + | |
| 81330 | + if( (nEqNew>nEqOld) | |
| 81331 | + || (nEqNew==nEqOld && pNew->iCol<pOld->iCol) | |
| 81332 | + || (nEqNew==nEqOld && pNew->iCol==pOld->iCol && pNew->iHash>pOld->iHash) | |
| 81333 | + ){ | |
| 81334 | + return 1; | |
| 81335 | + } | |
| 81336 | + return 0; | |
| 81337 | +} | |
| 81338 | + | |
| 81339 | +/* | |
| 81340 | +** Copy the contents of object (*pFrom) into (*pTo). | |
| 81341 | +*/ | |
| 81342 | +void sampleCopy(Stat4Accum *p, Stat4Sample *pTo, Stat4Sample *pFrom){ | |
| 81343 | + pTo->iRowid = pFrom->iRowid; | |
| 81344 | + pTo->isPSample = pFrom->isPSample; | |
| 81345 | + pTo->iCol = pFrom->iCol; | |
| 81346 | + pTo->iHash = pFrom->iHash; | |
| 81347 | + memcpy(pTo->anEq, pFrom->anEq, sizeof(tRowcnt)*p->nCol); | |
| 81348 | + memcpy(pTo->anLt, pFrom->anLt, sizeof(tRowcnt)*p->nCol); | |
| 81349 | + memcpy(pTo->anDLt, pFrom->anDLt, sizeof(tRowcnt)*p->nCol); | |
| 81350 | +} | |
| 81351 | + | |
| 81352 | +/* | |
| 81353 | +** Copy the contents of sample *pNew into the p->a[] array. If necessary, | |
| 81354 | +** remove the least desirable sample from p->a[] to make room. | |
| 81355 | +*/ | |
| 81356 | +static void sampleInsert(Stat4Accum *p, Stat4Sample *pNew, int nEqZero){ | |
| 81357 | + Stat4Sample *pSample; | |
| 81358 | + int i; | |
| 81359 | + i64 iSeq; | |
| 81360 | + i64 iPos; | |
| 81361 | + | |
| 81362 | + assert( IsStat4 || nEqZero==0 ); | |
| 81363 | + | |
| 81364 | + if( pNew->isPSample==0 ){ | |
| 81365 | + Stat4Sample *pUpgrade = 0; | |
| 81366 | + assert( pNew->anEq[pNew->iCol]>0 ); | |
| 81367 | + | |
| 81368 | + /* This sample is being added because the prefix that ends in column | |
| 81369 | + ** iCol occurs many times in the table. However, if we have already | |
| 81370 | + ** added a sample that shares this prefix, there is no need to add | |
| 81371 | + ** this one. Instead, upgrade the priority of the highest priority | |
| 81372 | + ** existing sample that shares this prefix. */ | |
| 81373 | + for(i=p->nSample-1; i>=0; i--){ | |
| 81374 | + Stat4Sample *pOld = &p->a[i]; | |
| 81375 | + if( pOld->anEq[pNew->iCol]==0 ){ | |
| 81376 | + if( pOld->isPSample ) return; | |
| 81377 | + assert( sampleIsBetter(pNew, pOld) ); | |
| 81378 | + if( pUpgrade==0 || sampleIsBetter(pOld, pUpgrade) ){ | |
| 81379 | + pUpgrade = pOld; | |
| 81380 | + } | |
| 81381 | + } | |
| 81382 | + } | |
| 81383 | + if( pUpgrade ){ | |
| 81384 | + pUpgrade->iCol = pNew->iCol; | |
| 81385 | + pUpgrade->anEq[pUpgrade->iCol] = pNew->anEq[pUpgrade->iCol]; | |
| 81386 | + goto find_new_min; | |
| 81387 | + } | |
| 81388 | + } | |
| 81389 | + | |
| 81390 | + /* If necessary, remove sample iMin to make room for the new sample. */ | |
| 81391 | + if( p->nSample>=p->mxSample ){ | |
| 81392 | + Stat4Sample *pMin = &p->a[p->iMin]; | |
| 81393 | + tRowcnt *anEq = pMin->anEq; | |
| 81394 | + tRowcnt *anLt = pMin->anLt; | |
| 81395 | + tRowcnt *anDLt = pMin->anDLt; | |
| 81396 | + memmove(pMin, &pMin[1], sizeof(p->a[0])*(p->nSample-p->iMin-1)); | |
| 80860 | 81397 | 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 | - } | |
| 81398 | + pSample->anEq = anEq; | |
| 81399 | + pSample->anDLt = anDLt; | |
| 81400 | + pSample->anLt = anLt; | |
| 81401 | + p->nSample = p->mxSample-1; | |
| 81402 | + } | |
| 81403 | + | |
| 81404 | + /* Figure out where in the a[] array the new sample should be inserted. */ | |
| 81405 | + iSeq = pNew->anLt[p->nCol-1]; | |
| 81406 | + for(iPos=p->nSample; iPos>0; iPos--){ | |
| 81407 | + if( iSeq>p->a[iPos-1].anLt[p->nCol-1] ) break; | |
| 81408 | + } | |
| 81409 | + | |
| 81410 | + /* Insert the new sample */ | |
| 81411 | + pSample = &p->a[iPos]; | |
| 81412 | + if( iPos!=p->nSample ){ | |
| 81413 | + Stat4Sample *pEnd = &p->a[p->nSample]; | |
| 81414 | + tRowcnt *anEq = pEnd->anEq; | |
| 81415 | + tRowcnt *anLt = pEnd->anLt; | |
| 81416 | + tRowcnt *anDLt = pEnd->anDLt; | |
| 81417 | + memmove(&p->a[iPos], &p->a[iPos+1], (p->nSample-iPos)*sizeof(p->a[0])); | |
| 81418 | + pSample->anEq = anEq; | |
| 81419 | + pSample->anDLt = anDLt; | |
| 81420 | + pSample->anLt = anLt; | |
| 81421 | + } | |
| 81422 | + p->nSample++; | |
| 81423 | + sampleCopy(p, pSample, pNew); | |
| 81424 | + | |
| 81425 | + /* Zero the first nEqZero entries in the anEq[] array. */ | |
| 81426 | + memset(pSample->anEq, 0, sizeof(tRowcnt)*nEqZero); | |
| 81427 | + | |
| 81428 | + find_new_min: | |
| 81429 | + if( p->nSample>=p->mxSample ){ | |
| 81430 | + int iMin = -1; | |
| 81431 | + for(i=0; i<p->mxSample; i++){ | |
| 81432 | + if( p->a[i].isPSample ) continue; | |
| 81433 | + if( iMin<0 || sampleIsBetter(&p->a[iMin], &p->a[i]) ){ | |
| 81434 | + iMin = i; | |
| 81435 | + } | |
| 81436 | + } | |
| 81437 | + assert( iMin>=0 ); | |
| 80893 | 81438 | p->iMin = iMin; |
| 80894 | 81439 | } |
| 80895 | 81440 | } |
| 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( | |
| 81441 | +#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */ | |
| 81442 | + | |
| 81443 | +/* | |
| 81444 | +** Field iChng of the index being scanned has changed. So at this point | |
| 81445 | +** p->current contains a sample that reflects the previous row of the | |
| 81446 | +** index. The value of anEq[iChng] and subsequent anEq[] elements are | |
| 81447 | +** correct at this point. | |
| 81448 | +*/ | |
| 81449 | +static void samplePushPrevious(Stat4Accum *p, int iChng){ | |
| 81450 | +#ifdef SQLITE_ENABLE_STAT4 | |
| 81451 | + int i; | |
| 81452 | + | |
| 81453 | + /* Check if any samples from the aBest[] array should be pushed | |
| 81454 | + ** into IndexSample.a[] at this point. */ | |
| 81455 | + for(i=(p->nCol-2); i>=iChng; i--){ | |
| 81456 | + Stat4Sample *pBest = &p->aBest[i]; | |
| 81457 | + if( p->nSample<p->mxSample | |
| 81458 | + || sampleIsBetter(pBest, &p->a[p->iMin]) | |
| 81459 | + ){ | |
| 81460 | + sampleInsert(p, pBest, i); | |
| 81461 | + } | |
| 81462 | + } | |
| 81463 | + | |
| 81464 | + /* Update the anEq[] fields of any samples already collected. */ | |
| 81465 | + for(i=p->nSample-1; i>=0; i--){ | |
| 81466 | + int j; | |
| 81467 | + for(j=iChng; j<p->nCol; j++){ | |
| 81468 | + if( p->a[i].anEq[j]==0 ) p->a[i].anEq[j] = p->current.anEq[j]; | |
| 81469 | + } | |
| 81470 | + } | |
| 81471 | +#endif | |
| 81472 | + | |
| 81473 | +#if defined(SQLITE_ENABLE_STAT3) && !defined(SQLITE_ENABLE_STAT4) | |
| 81474 | + if( iChng==0 ){ | |
| 81475 | + tRowcnt nLt = p->current.anLt[0]; | |
| 81476 | + tRowcnt nEq = p->current.anEq[0]; | |
| 81477 | + | |
| 81478 | + /* Check if this is to be a periodic sample. If so, add it. */ | |
| 81479 | + if( (nLt/p->nPSample)!=(nLt+nEq)/p->nPSample ){ | |
| 81480 | + p->current.isPSample = 1; | |
| 81481 | + sampleInsert(p, &p->current, 0); | |
| 81482 | + p->current.isPSample = 0; | |
| 81483 | + }else | |
| 81484 | + | |
| 81485 | + /* Or if it is a non-periodic sample. Add it in this case too. */ | |
| 81486 | + if( p->nSample<p->mxSample || sampleIsBetter(&p->current, &p->a[p->iMin]) ){ | |
| 81487 | + sampleInsert(p, &p->current, 0); | |
| 81488 | + } | |
| 81489 | + } | |
| 81490 | +#endif | |
| 81491 | +} | |
| 81492 | + | |
| 81493 | +/* | |
| 81494 | +** Implementation of the stat_push SQL function: stat_push(P,R,C) | |
| 81495 | +** Arguments: | |
| 81496 | +** | |
| 81497 | +** P Pointer to the Stat4Accum object created by stat_init() | |
| 81498 | +** C Index of left-most column to differ from previous row | |
| 81499 | +** R Rowid for the current row | |
| 81500 | +** | |
| 81501 | +** The SQL function always returns NULL. | |
| 81502 | +** | |
| 81503 | +** The R parameter is only used for STAT3 and STAT4. | |
| 81504 | +*/ | |
| 81505 | +static void statPush( | |
| 81506 | + sqlite3_context *context, | |
| 81507 | + int argc, | |
| 81508 | + sqlite3_value **argv | |
| 81509 | +){ | |
| 81510 | + int i; | |
| 81511 | + | |
| 81512 | + /* The three function arguments */ | |
| 81513 | + Stat4Accum *p = (Stat4Accum*)sqlite3_value_blob(argv[0]); | |
| 81514 | + int iChng = sqlite3_value_int(argv[1]); | |
| 81515 | + | |
| 81516 | + assert( p->nCol>1 ); /* Includes rowid field */ | |
| 81517 | + assert( iChng<p->nCol ); | |
| 81518 | + | |
| 81519 | + if( p->nRow==0 ){ | |
| 81520 | + /* anEq[0] is only zero for the very first call to this function. Do | |
| 81521 | + ** appropriate initialization */ | |
| 81522 | + for(i=0; i<p->nCol; i++) p->current.anEq[i] = 1; | |
| 81523 | + }else{ | |
| 81524 | + /* Second and subsequent calls get processed here */ | |
| 81525 | + samplePushPrevious(p, iChng); | |
| 81526 | + | |
| 81527 | + /* Update anDLt[], anLt[] and anEq[] to reflect the values that apply | |
| 81528 | + ** to the current row of the index. */ | |
| 81529 | + for(i=0; i<iChng; i++){ | |
| 81530 | + p->current.anEq[i]++; | |
| 81531 | + } | |
| 81532 | + for(i=iChng; i<p->nCol; i++){ | |
| 81533 | + p->current.anDLt[i]++; | |
| 81534 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 | |
| 81535 | + p->current.anLt[i] += p->current.anEq[i]; | |
| 81536 | +#endif | |
| 81537 | + p->current.anEq[i] = 1; | |
| 81538 | + } | |
| 81539 | + } | |
| 81540 | + p->nRow++; | |
| 81541 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 | |
| 81542 | + p->current.iRowid = sqlite3_value_int64(argv[2]); | |
| 81543 | + p->current.iHash = p->iPrn = p->iPrn*1103515245 + 12345; | |
| 81544 | +#endif | |
| 81545 | + | |
| 81546 | +#ifdef SQLITE_ENABLE_STAT4 | |
| 81547 | + { | |
| 81548 | + tRowcnt nLt = p->current.anLt[p->nCol-1]; | |
| 81549 | + | |
| 81550 | + /* Check if this is to be a periodic sample. If so, add it. */ | |
| 81551 | + if( (nLt/p->nPSample)!=(nLt+1)/p->nPSample ){ | |
| 81552 | + p->current.isPSample = 1; | |
| 81553 | + p->current.iCol = 0; | |
| 81554 | + sampleInsert(p, &p->current, p->nCol-1); | |
| 81555 | + p->current.isPSample = 0; | |
| 81556 | + } | |
| 81557 | + | |
| 81558 | + /* Update the aBest[] array. */ | |
| 81559 | + for(i=0; i<(p->nCol-1); i++){ | |
| 81560 | + p->current.iCol = i; | |
| 81561 | + if( i>=iChng || sampleIsBetter(&p->current, &p->aBest[i]) ){ | |
| 81562 | + sampleCopy(p, &p->aBest[i], &p->current); | |
| 81563 | + } | |
| 81564 | + } | |
| 81565 | + } | |
| 81566 | +#endif | |
| 81567 | +} | |
| 81568 | +static const FuncDef statPushFuncdef = { | |
| 81569 | + 2+IsStat34, /* nArg */ | |
| 81570 | + SQLITE_UTF8, /* iPrefEnc */ | |
| 81571 | + 0, /* flags */ | |
| 81572 | + 0, /* pUserData */ | |
| 81573 | + 0, /* pNext */ | |
| 81574 | + statPush, /* xFunc */ | |
| 81575 | + 0, /* xStep */ | |
| 81576 | + 0, /* xFinalize */ | |
| 81577 | + "stat_push", /* zName */ | |
| 81578 | + 0, /* pHash */ | |
| 81579 | + 0 /* pDestructor */ | |
| 81580 | +}; | |
| 81581 | + | |
| 81582 | +#define STAT_GET_STAT1 0 /* "stat" column of stat1 table */ | |
| 81583 | +#define STAT_GET_ROWID 1 /* "rowid" column of stat[34] entry */ | |
| 81584 | +#define STAT_GET_NEQ 2 /* "neq" column of stat[34] entry */ | |
| 81585 | +#define STAT_GET_NLT 3 /* "nlt" column of stat[34] entry */ | |
| 81586 | +#define STAT_GET_NDLT 4 /* "ndlt" column of stat[34] entry */ | |
| 81587 | + | |
| 81588 | +/* | |
| 81589 | +** Implementation of the stat_get(P,J) SQL function. This routine is | |
| 81590 | +** used to query the results. Content is returned for parameter J | |
| 81591 | +** which is one of the STAT_GET_xxxx values defined above. | |
| 81592 | +** | |
| 81593 | +** If neither STAT3 nor STAT4 are enabled, then J is always | |
| 81594 | +** STAT_GET_STAT1 and is hence omitted and this routine becomes | |
| 81595 | +** a one-parameter function, stat_get(P), that always returns the | |
| 81596 | +** stat1 table entry information. | |
| 81597 | +*/ | |
| 81598 | +static void statGet( | |
| 80922 | 81599 | sqlite3_context *context, |
| 80923 | 81600 | int argc, |
| 80924 | 81601 | sqlite3_value **argv |
| 80925 | 81602 | ){ |
| 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 | - | |
| 81603 | + Stat4Accum *p = (Stat4Accum*)sqlite3_value_blob(argv[0]); | |
| 81604 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 | |
| 81605 | + /* STAT3 and STAT4 have a parameter on this routine. */ | |
| 81606 | + int eCall = sqlite3_value_int(argv[1]); | |
| 81607 | + assert( argc==2 ); | |
| 81608 | + assert( eCall==STAT_GET_STAT1 || eCall==STAT_GET_NEQ | |
| 81609 | + || eCall==STAT_GET_ROWID || eCall==STAT_GET_NLT | |
| 81610 | + || eCall==STAT_GET_NDLT | |
| 81611 | + ); | |
| 81612 | + if( eCall==STAT_GET_STAT1 ) | |
| 81613 | +#else | |
| 81614 | + assert( argc==1 ); | |
| 81615 | +#endif | |
| 81616 | + { | |
| 81617 | + /* Return the value to store in the "stat" column of the sqlite_stat1 | |
| 81618 | + ** table for this index. | |
| 81619 | + ** | |
| 81620 | + ** The value is a string composed of a list of integers describing | |
| 81621 | + ** the index. The first integer in the list is the total number of | |
| 81622 | + ** entries in the index. There is one additional integer in the list | |
| 81623 | + ** for each indexed column. This additional integer is an estimate of | |
| 81624 | + ** the number of rows matched by a stabbing query on the index using | |
| 81625 | + ** a key with the corresponding number of fields. In other words, | |
| 81626 | + ** if the index is on columns (a,b) and the sqlite_stat1 value is | |
| 81627 | + ** "100 10 2", then SQLite estimates that: | |
| 81628 | + ** | |
| 81629 | + ** * the index contains 100 rows, | |
| 81630 | + ** * "WHERE a=?" matches 10 rows, and | |
| 81631 | + ** * "WHERE a=? AND b=?" matches 2 rows. | |
| 81632 | + ** | |
| 81633 | + ** If D is the count of distinct values and K is the total number of | |
| 81634 | + ** rows, then each estimate is computed as: | |
| 81635 | + ** | |
| 81636 | + ** I = (K+D-1)/D | |
| 81637 | + */ | |
| 81638 | + char *z; | |
| 81639 | + int i; | |
| 81640 | + | |
| 81641 | + char *zRet = sqlite3MallocZero(p->nCol * 25); | |
| 81642 | + if( zRet==0 ){ | |
| 81643 | + sqlite3_result_error_nomem(context); | |
| 81644 | + return; | |
| 81645 | + } | |
| 81646 | + | |
| 81647 | + sqlite3_snprintf(24, zRet, "%lld", p->nRow); | |
| 81648 | + z = zRet + sqlite3Strlen30(zRet); | |
| 81649 | + for(i=0; i<(p->nCol-1); i++){ | |
| 81650 | + i64 nDistinct = p->current.anDLt[i] + 1; | |
| 81651 | + i64 iVal = (p->nRow + nDistinct - 1) / nDistinct; | |
| 81652 | + sqlite3_snprintf(24, z, " %lld", iVal); | |
| 81653 | + z += sqlite3Strlen30(z); | |
| 81654 | + assert( p->current.anEq[i] ); | |
| 81655 | + } | |
| 81656 | + assert( z[0]=='\0' && z>zRet ); | |
| 81657 | + | |
| 81658 | + sqlite3_result_text(context, zRet, -1, sqlite3_free); | |
| 81659 | + } | |
| 81660 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 | |
| 81661 | + else if( eCall==STAT_GET_ROWID ){ | |
| 81662 | + if( p->iGet<0 ){ | |
| 81663 | + samplePushPrevious(p, 0); | |
| 81664 | + p->iGet = 0; | |
| 81665 | + } | |
| 81666 | + if( p->iGet<p->nSample ){ | |
| 81667 | + sqlite3_result_int64(context, p->a[p->iGet].iRowid); | |
| 81668 | + } | |
| 81669 | + }else{ | |
| 81670 | + tRowcnt *aCnt = 0; | |
| 81671 | + | |
| 81672 | + assert( p->iGet<p->nSample ); | |
| 81673 | + switch( eCall ){ | |
| 81674 | + case STAT_GET_NEQ: aCnt = p->a[p->iGet].anEq; break; | |
| 81675 | + case STAT_GET_NLT: aCnt = p->a[p->iGet].anLt; break; | |
| 81676 | + default: { | |
| 81677 | + aCnt = p->a[p->iGet].anDLt; | |
| 81678 | + p->iGet++; | |
| 81679 | + break; | |
| 81680 | + } | |
| 81681 | + } | |
| 81682 | + | |
| 81683 | + if( IsStat3 ){ | |
| 81684 | + sqlite3_result_int64(context, (i64)aCnt[0]); | |
| 81685 | + }else{ | |
| 81686 | + char *zRet = sqlite3MallocZero(p->nCol * 25); | |
| 81687 | + if( zRet==0 ){ | |
| 81688 | + sqlite3_result_error_nomem(context); | |
| 81689 | + }else{ | |
| 81690 | + int i; | |
| 81691 | + char *z = zRet; | |
| 81692 | + for(i=0; i<p->nCol; i++){ | |
| 81693 | + sqlite3_snprintf(24, z, "%lld ", aCnt[i]); | |
| 81694 | + z += sqlite3Strlen30(z); | |
| 81695 | + } | |
| 81696 | + assert( z[0]=='\0' && z>zRet ); | |
| 81697 | + z[-1] = '\0'; | |
| 81698 | + sqlite3_result_text(context, zRet, -1, sqlite3_free); | |
| 81699 | + } | |
| 81700 | + } | |
| 81701 | + } | |
| 81702 | +#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */ | |
| 81703 | +} | |
| 81704 | +static const FuncDef statGetFuncdef = { | |
| 81705 | + 1+IsStat34, /* nArg */ | |
| 81706 | + SQLITE_UTF8, /* iPrefEnc */ | |
| 81707 | + 0, /* flags */ | |
| 81708 | + 0, /* pUserData */ | |
| 81709 | + 0, /* pNext */ | |
| 81710 | + statGet, /* xFunc */ | |
| 81711 | + 0, /* xStep */ | |
| 81712 | + 0, /* xFinalize */ | |
| 81713 | + "stat_get", /* zName */ | |
| 81714 | + 0, /* pHash */ | |
| 81715 | + 0 /* pDestructor */ | |
| 81716 | +}; | |
| 81717 | + | |
| 81718 | +static void callStatGet(Vdbe *v, int regStat4, int iParam, int regOut){ | |
| 81719 | + assert( regOut!=regStat4 && regOut!=regStat4+1 ); | |
| 81720 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 | |
| 81721 | + sqlite3VdbeAddOp2(v, OP_Integer, iParam, regStat4+1); | |
| 81722 | +#else | |
| 81723 | + assert( iParam==STAT_GET_STAT1 ); | |
| 81724 | +#endif | |
| 81725 | + sqlite3VdbeAddOp3(v, OP_Function, 0, regStat4, regOut); | |
| 81726 | + sqlite3VdbeChangeP4(v, -1, (char*)&statGetFuncdef, P4_FUNCDEF); | |
| 81727 | + sqlite3VdbeChangeP5(v, 1 + IsStat34); | |
| 81728 | +} | |
| 80955 | 81729 | |
| 80956 | 81730 | /* |
| 80957 | 81731 | ** Generate code to do an analysis of all indices associated with |
| 80958 | 81732 | ** a single table. |
| 80959 | 81733 | */ |
| @@ -80960,46 +81734,35 @@ | ||
| 80960 | 81734 | static void analyzeOneTable( |
| 80961 | 81735 | Parse *pParse, /* Parser context */ |
| 80962 | 81736 | Table *pTab, /* Table whose indices are to be analyzed */ |
| 80963 | 81737 | Index *pOnlyIdx, /* If not NULL, only analyze this one index */ |
| 80964 | 81738 | int iStatCur, /* Index of VdbeCursor that writes the sqlite_stat1 table */ |
| 80965 | - int iMem /* Available memory locations begin here */ | |
| 81739 | + int iMem, /* Available memory locations begin here */ | |
| 81740 | + int iTab /* Next available cursor */ | |
| 80966 | 81741 | ){ |
| 80967 | 81742 | sqlite3 *db = pParse->db; /* Database handle */ |
| 80968 | 81743 | Index *pIdx; /* An index to being analyzed */ |
| 80969 | 81744 | int iIdxCur; /* Cursor open on index being analyzed */ |
| 81745 | + int iTabCur; /* Table cursor */ | |
| 80970 | 81746 | Vdbe *v; /* The virtual machine being built up */ |
| 80971 | 81747 | int i; /* Loop counter */ |
| 80972 | - int topOfLoop; /* The top of the loop */ | |
| 80973 | - int endOfLoop; /* The end of the loop */ | |
| 80974 | 81748 | int jZeroRows = -1; /* Jump from here if number of rows is zero */ |
| 80975 | 81749 | int iDb; /* Index of database containing pTab */ |
| 80976 | 81750 | u8 needTableCnt = 1; /* True to count the table */ |
| 81751 | + int regNewRowid = iMem++; /* Rowid for the inserted record */ | |
| 81752 | + int regStat4 = iMem++; /* Register to hold Stat4Accum object */ | |
| 81753 | + int regChng = iMem++; /* Index of changed index field */ | |
| 81754 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 | |
| 81755 | + int regRowid = iMem++; /* Rowid argument passed to stat_push() */ | |
| 81756 | +#endif | |
| 81757 | + int regTemp = iMem++; /* Temporary use register */ | |
| 80977 | 81758 | int regTabname = iMem++; /* Register containing table name */ |
| 80978 | 81759 | 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 | - | |
| 81760 | + int regStat1 = iMem++; /* Value for the stat column of sqlite_stat1 */ | |
| 81761 | + int regPrev = iMem; /* MUST BE LAST (see below) */ | |
| 81762 | + | |
| 81763 | + pParse->nMem = MAX(pParse->nMem, iMem); | |
| 81001 | 81764 | v = sqlite3GetVdbe(pParse); |
| 81002 | 81765 | if( v==0 || NEVER(pTab==0) ){ |
| 81003 | 81766 | return; |
| 81004 | 81767 | } |
| 81005 | 81768 | if( pTab->tnum==0 ){ |
| @@ -81019,217 +81782,230 @@ | ||
| 81019 | 81782 | db->aDb[iDb].zName ) ){ |
| 81020 | 81783 | return; |
| 81021 | 81784 | } |
| 81022 | 81785 | #endif |
| 81023 | 81786 | |
| 81024 | - /* Establish a read-lock on the table at the shared-cache level. */ | |
| 81787 | + /* Establish a read-lock on the table at the shared-cache level. | |
| 81788 | + ** Open a read-only cursor on the table. Also allocate a cursor number | |
| 81789 | + ** to use for scanning indexes (iIdxCur). No index cursor is opened at | |
| 81790 | + ** this time though. */ | |
| 81025 | 81791 | sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName); |
| 81026 | - | |
| 81027 | - iIdxCur = pParse->nTab++; | |
| 81792 | + iTabCur = iTab++; | |
| 81793 | + iIdxCur = iTab++; | |
| 81794 | + pParse->nTab = MAX(pParse->nTab, iTab); | |
| 81795 | + sqlite3OpenTable(pParse, iTabCur, iDb, pTab, OP_OpenRead); | |
| 81028 | 81796 | sqlite3VdbeAddOp4(v, OP_String8, 0, regTabname, 0, pTab->zName, 0); |
| 81797 | + | |
| 81029 | 81798 | 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 */ | |
| 81799 | + int nCol; /* Number of columns indexed by pIdx */ | |
| 81800 | + KeyInfo *pKey; /* KeyInfo structure for pIdx */ | |
| 81801 | + int *aGotoChng; /* Array of jump instruction addresses */ | |
| 81802 | + int addrRewind; /* Address of "OP_Rewind iIdxCur" */ | |
| 81803 | + int addrGotoChng0; /* Address of "Goto addr_chng_0" */ | |
| 81804 | + int addrNextRow; /* Address of "next_row:" */ | |
| 81034 | 81805 | |
| 81035 | 81806 | if( pOnlyIdx && pOnlyIdx!=pIdx ) continue; |
| 81036 | 81807 | if( pIdx->pPartIdxWhere==0 ) needTableCnt = 0; |
| 81037 | 81808 | VdbeNoopComment((v, "Begin analysis of %s", pIdx->zName)); |
| 81038 | 81809 | nCol = pIdx->nColumn; |
| 81039 | - aChngAddr = sqlite3DbMallocRaw(db, sizeof(int)*nCol); | |
| 81040 | - if( aChngAddr==0 ) continue; | |
| 81810 | + aGotoChng = sqlite3DbMallocRaw(db, sizeof(int)*(nCol+1)); | |
| 81811 | + if( aGotoChng==0 ) continue; | |
| 81041 | 81812 | 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 | 81813 | |
| 81052 | 81814 | /* Populate the register containing the index name. */ |
| 81053 | 81815 | sqlite3VdbeAddOp4(v, OP_String8, 0, regIdxname, 0, pIdx->zName, 0); |
| 81054 | 81816 | |
| 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); | |
| 81817 | + /* | |
| 81818 | + ** Pseudo-code for loop that calls stat_push(): | |
| 81819 | + ** | |
| 81820 | + ** Rewind csr | |
| 81821 | + ** if eof(csr) goto end_of_scan; | |
| 81822 | + ** regChng = 0 | |
| 81823 | + ** goto chng_addr_0; | |
| 81824 | + ** | |
| 81825 | + ** next_row: | |
| 81826 | + ** regChng = 0 | |
| 81827 | + ** if( idx(0) != regPrev(0) ) goto chng_addr_0 | |
| 81828 | + ** regChng = 1 | |
| 81829 | + ** if( idx(1) != regPrev(1) ) goto chng_addr_1 | |
| 81830 | + ** ... | |
| 81831 | + ** regChng = N | |
| 81832 | + ** goto chng_addr_N | |
| 81833 | + ** | |
| 81834 | + ** chng_addr_0: | |
| 81835 | + ** regPrev(0) = idx(0) | |
| 81836 | + ** chng_addr_1: | |
| 81837 | + ** regPrev(1) = idx(1) | |
| 81838 | + ** ... | |
| 81839 | + ** | |
| 81840 | + ** chng_addr_N: | |
| 81841 | + ** regRowid = idx(rowid) | |
| 81842 | + ** stat_push(P, regChng, regRowid) | |
| 81843 | + ** Next csr | |
| 81844 | + ** if !eof(csr) goto next_row; | |
| 81845 | + ** | |
| 81846 | + ** end_of_scan: | |
| 81847 | + */ | |
| 81848 | + | |
| 81849 | + /* Make sure there are enough memory cells allocated to accommodate | |
| 81850 | + ** the regPrev array and a trailing rowid (the rowid slot is required | |
| 81851 | + ** when building a record to insert into the sample column of | |
| 81852 | + ** the sqlite_stat4 table. */ | |
| 81853 | + pParse->nMem = MAX(pParse->nMem, regPrev+nCol); | |
| 81854 | + | |
| 81855 | + /* Open a read-only cursor on the index being analyzed. */ | |
| 81856 | + assert( iDb==sqlite3SchemaToIndex(db, pIdx->pSchema) ); | |
| 81857 | + sqlite3VdbeAddOp3(v, OP_OpenRead, iIdxCur, pIdx->tnum, iDb); | |
| 81858 | + sqlite3VdbeChangeP4(v, -1, (char*)pKey, P4_KEYINFO_HANDOFF); | |
| 81859 | + VdbeComment((v, "%s", pIdx->zName)); | |
| 81860 | + | |
| 81861 | + /* Invoke the stat_init() function. The arguments are: | |
| 81862 | + ** | |
| 81863 | + ** (1) the number of columns in the index including the rowid, | |
| 81864 | + ** (2) the number of rows in the index, | |
| 81865 | + ** | |
| 81866 | + ** The second argument is only used for STAT3 and STAT4 | |
| 81867 | + */ | |
| 81868 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 | |
| 81869 | + sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regStat4+2); | |
| 81870 | +#endif | |
| 81871 | + sqlite3VdbeAddOp2(v, OP_Integer, nCol+1, regStat4+1); | |
| 81872 | + sqlite3VdbeAddOp3(v, OP_Function, 0, regStat4+1, regStat4); | |
| 81873 | + sqlite3VdbeChangeP4(v, -1, (char*)&statInitFuncdef, P4_FUNCDEF); | |
| 81874 | + sqlite3VdbeChangeP5(v, 1+IsStat34); | |
| 81875 | + | |
| 81876 | + /* Implementation of the following: | |
| 81877 | + ** | |
| 81878 | + ** Rewind csr | |
| 81879 | + ** if eof(csr) goto end_of_scan; | |
| 81880 | + ** regChng = 0 | |
| 81881 | + ** goto next_push_0; | |
| 81882 | + ** | |
| 81883 | + */ | |
| 81884 | + addrRewind = sqlite3VdbeAddOp1(v, OP_Rewind, iIdxCur); | |
| 81885 | + sqlite3VdbeAddOp2(v, OP_Integer, 0, regChng); | |
| 81886 | + addrGotoChng0 = sqlite3VdbeAddOp0(v, OP_Goto); | |
| 81887 | + | |
| 81888 | + /* | |
| 81889 | + ** next_row: | |
| 81890 | + ** regChng = 0 | |
| 81891 | + ** if( idx(0) != regPrev(0) ) goto chng_addr_0 | |
| 81892 | + ** regChng = 1 | |
| 81893 | + ** if( idx(1) != regPrev(1) ) goto chng_addr_1 | |
| 81894 | + ** ... | |
| 81895 | + ** regChng = N | |
| 81896 | + ** goto chng_addr_N | |
| 81897 | + */ | |
| 81898 | + addrNextRow = sqlite3VdbeCurrentAddr(v); | |
| 81899 | + for(i=0; i<nCol; i++){ | |
| 81900 | + char *pColl = (char*)sqlite3LocateCollSeq(pParse, pIdx->azColl[i]); | |
| 81901 | + sqlite3VdbeAddOp2(v, OP_Integer, i, regChng); | |
| 81902 | + sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, regTemp); | |
| 81903 | + aGotoChng[i] = | |
| 81904 | + sqlite3VdbeAddOp4(v, OP_Ne, regTemp, 0, regPrev+i, pColl, P4_COLLSEQ); | |
| 81113 | 81905 | 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 | - } | |
| 81906 | + } | |
| 81907 | + sqlite3VdbeAddOp2(v, OP_Integer, nCol, regChng); | |
| 81908 | + aGotoChng[nCol] = sqlite3VdbeAddOp0(v, OP_Goto); | |
| 81909 | + | |
| 81910 | + /* | |
| 81911 | + ** chng_addr_0: | |
| 81912 | + ** regPrev(0) = idx(0) | |
| 81913 | + ** chng_addr_1: | |
| 81914 | + ** regPrev(1) = idx(1) | |
| 81915 | + ** ... | |
| 81916 | + */ | |
| 81917 | + sqlite3VdbeJumpHere(v, addrGotoChng0); | |
| 81918 | + for(i=0; i<nCol; i++){ | |
| 81919 | + sqlite3VdbeJumpHere(v, aGotoChng[i]); | |
| 81920 | + sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, regPrev+i); | |
| 81921 | + } | |
| 81922 | + | |
| 81923 | + /* | |
| 81924 | + ** chng_addr_N: | |
| 81925 | + ** regRowid = idx(rowid) // STAT34 only | |
| 81926 | + ** stat_push(P, regChng, regRowid) // 3rd parameter STAT34 only | |
| 81927 | + ** Next csr | |
| 81928 | + ** if !eof(csr) goto next_row; | |
| 81929 | + */ | |
| 81930 | + sqlite3VdbeJumpHere(v, aGotoChng[nCol]); | |
| 81931 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 | |
| 81932 | + sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur, regRowid); | |
| 81933 | + assert( regRowid==(regStat4+2) ); | |
| 81934 | +#endif | |
| 81935 | + assert( regChng==(regStat4+1) ); | |
| 81936 | + sqlite3VdbeAddOp3(v, OP_Function, 1, regStat4, regTemp); | |
| 81937 | + sqlite3VdbeChangeP4(v, -1, (char*)&statPushFuncdef, P4_FUNCDEF); | |
| 81938 | + sqlite3VdbeChangeP5(v, 2+IsStat34); | |
| 81939 | + sqlite3VdbeAddOp2(v, OP_Next, iIdxCur, addrNextRow); | |
| 81940 | + | |
| 81941 | + /* Add the entry to the stat1 table. */ | |
| 81942 | + callStatGet(v, regStat4, STAT_GET_STAT1, regStat1); | |
| 81943 | + sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regTemp, "aaa", 0); | |
| 81944 | + sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid); | |
| 81945 | + sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regTemp, regNewRowid); | |
| 81946 | + sqlite3VdbeChangeP5(v, OPFLAG_APPEND); | |
| 81947 | + | |
| 81948 | + /* Add the entries to the stat3 or stat4 table. */ | |
| 81949 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 | |
| 81950 | + { | |
| 81951 | + int regEq = regStat1; | |
| 81952 | + int regLt = regStat1+1; | |
| 81953 | + int regDLt = regStat1+2; | |
| 81954 | + int regSample = regStat1+3; | |
| 81955 | + int regCol = regStat1+4; | |
| 81956 | + int regSampleRowid = regCol + nCol; | |
| 81957 | + int addrNext; | |
| 81958 | + int addrIsNull; | |
| 81959 | + | |
| 81960 | + pParse->nMem = MAX(pParse->nMem, regCol+nCol+1); | |
| 81961 | + | |
| 81962 | + addrNext = sqlite3VdbeCurrentAddr(v); | |
| 81963 | + callStatGet(v, regStat4, STAT_GET_ROWID, regSampleRowid); | |
| 81964 | + addrIsNull = sqlite3VdbeAddOp1(v, OP_IsNull, regSampleRowid); | |
| 81965 | + callStatGet(v, regStat4, STAT_GET_NEQ, regEq); | |
| 81966 | + callStatGet(v, regStat4, STAT_GET_NLT, regLt); | |
| 81967 | + callStatGet(v, regStat4, STAT_GET_NDLT, regDLt); | |
| 81968 | + sqlite3VdbeAddOp3(v, OP_NotExists, iTabCur, addrNext, regSampleRowid); | |
| 81969 | +#ifdef SQLITE_ENABLE_STAT3 | |
| 81970 | + sqlite3ExprCodeGetColumnOfTable(v, pTab, iTabCur, | |
| 81971 | + pIdx->aiColumn[0], regSample); | |
| 81972 | +#else | |
| 81973 | + for(i=0; i<nCol; i++){ | |
| 81974 | + int iCol = pIdx->aiColumn[i]; | |
| 81975 | + sqlite3ExprCodeGetColumnOfTable(v, pTab, iTabCur, iCol, regCol+i); | |
| 81976 | + } | |
| 81977 | + sqlite3VdbeAddOp3(v, OP_MakeRecord, regCol, nCol+1, regSample); | |
| 81978 | +#endif | |
| 81979 | + sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 6, regTemp, "bbbbbb", 0); | |
| 81980 | + sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur+1, regNewRowid); | |
| 81981 | + sqlite3VdbeAddOp3(v, OP_Insert, iStatCur+1, regTemp, regNewRowid); | |
| 81982 | + sqlite3VdbeAddOp2(v, OP_Goto, 0, addrNext); | |
| 81983 | + sqlite3VdbeJumpHere(v, addrIsNull); | |
| 81984 | + } | |
| 81985 | +#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */ | |
| 81986 | + | |
| 81987 | + /* End of analysis */ | |
| 81988 | + sqlite3VdbeJumpHere(v, addrRewind); | |
| 81989 | + sqlite3DbFree(db, aGotoChng); | |
| 81990 | + } | |
| 81991 | + | |
| 81213 | 81992 | |
| 81214 | 81993 | /* Create a single sqlite_stat1 entry containing NULL as the index |
| 81215 | 81994 | ** name and the row count as the content. |
| 81216 | 81995 | */ |
| 81217 | 81996 | if( pOnlyIdx==0 && needTableCnt ){ |
| 81218 | - sqlite3VdbeAddOp3(v, OP_OpenRead, iIdxCur, pTab->tnum, iDb); | |
| 81219 | 81997 | VdbeComment((v, "%s", pTab->zName)); |
| 81220 | - sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regStat1); | |
| 81221 | - sqlite3VdbeAddOp1(v, OP_Close, iIdxCur); | |
| 81998 | + sqlite3VdbeAddOp2(v, OP_Count, iTabCur, regStat1); | |
| 81222 | 81999 | jZeroRows = sqlite3VdbeAddOp1(v, OP_IfNot, regStat1); |
| 81223 | 82000 | sqlite3VdbeAddOp2(v, OP_Null, 0, regIdxname); |
| 81224 | - sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regRec, "aaa", 0); | |
| 82001 | + sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regTemp, "aaa", 0); | |
| 81225 | 82002 | sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid); |
| 81226 | - sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regRec, regNewRowid); | |
| 82003 | + sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regTemp, regNewRowid); | |
| 81227 | 82004 | sqlite3VdbeChangeP5(v, OPFLAG_APPEND); |
| 81228 | 82005 | sqlite3VdbeJumpHere(v, jZeroRows); |
| 81229 | 82006 | } |
| 81230 | - if( pParse->nMem<regRec ) pParse->nMem = regRec; | |
| 81231 | 82007 | } |
| 81232 | 82008 | |
| 81233 | 82009 | |
| 81234 | 82010 | /* |
| 81235 | 82011 | ** Generate code that will cause the most recent index analysis to |
| @@ -81249,20 +82025,22 @@ | ||
| 81249 | 82025 | sqlite3 *db = pParse->db; |
| 81250 | 82026 | Schema *pSchema = db->aDb[iDb].pSchema; /* Schema of database iDb */ |
| 81251 | 82027 | HashElem *k; |
| 81252 | 82028 | int iStatCur; |
| 81253 | 82029 | int iMem; |
| 82030 | + int iTab; | |
| 81254 | 82031 | |
| 81255 | 82032 | sqlite3BeginWriteOperation(pParse, 0, iDb); |
| 81256 | 82033 | iStatCur = pParse->nTab; |
| 81257 | 82034 | pParse->nTab += 3; |
| 81258 | 82035 | openStatTable(pParse, iDb, iStatCur, 0, 0); |
| 81259 | 82036 | iMem = pParse->nMem+1; |
| 82037 | + iTab = pParse->nTab; | |
| 81260 | 82038 | assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); |
| 81261 | 82039 | for(k=sqliteHashFirst(&pSchema->tblHash); k; k=sqliteHashNext(k)){ |
| 81262 | 82040 | Table *pTab = (Table*)sqliteHashData(k); |
| 81263 | - analyzeOneTable(pParse, pTab, 0, iStatCur, iMem); | |
| 82041 | + analyzeOneTable(pParse, pTab, 0, iStatCur, iMem, iTab); | |
| 81264 | 82042 | } |
| 81265 | 82043 | loadAnalysis(pParse, iDb); |
| 81266 | 82044 | } |
| 81267 | 82045 | |
| 81268 | 82046 | /* |
| @@ -81283,11 +82061,11 @@ | ||
| 81283 | 82061 | if( pOnlyIdx ){ |
| 81284 | 82062 | openStatTable(pParse, iDb, iStatCur, pOnlyIdx->zName, "idx"); |
| 81285 | 82063 | }else{ |
| 81286 | 82064 | openStatTable(pParse, iDb, iStatCur, pTab->zName, "tbl"); |
| 81287 | 82065 | } |
| 81288 | - analyzeOneTable(pParse, pTab, pOnlyIdx, iStatCur, pParse->nMem+1); | |
| 82066 | + analyzeOneTable(pParse, pTab, pOnlyIdx, iStatCur,pParse->nMem+1,pParse->nTab); | |
| 81289 | 82067 | loadAnalysis(pParse, iDb); |
| 81290 | 82068 | } |
| 81291 | 82069 | |
| 81292 | 82070 | /* |
| 81293 | 82071 | ** Generate code for the ANALYZE command. The parser calls this routine |
| @@ -81365,10 +82143,47 @@ | ||
| 81365 | 82143 | typedef struct analysisInfo analysisInfo; |
| 81366 | 82144 | struct analysisInfo { |
| 81367 | 82145 | sqlite3 *db; |
| 81368 | 82146 | const char *zDatabase; |
| 81369 | 82147 | }; |
| 82148 | + | |
| 82149 | +/* | |
| 82150 | +** The first argument points to a nul-terminated string containing a | |
| 82151 | +** list of space separated integers. Read the first nOut of these into | |
| 82152 | +** the array aOut[]. | |
| 82153 | +*/ | |
| 82154 | +static void decodeIntArray( | |
| 82155 | + char *zIntArray, | |
| 82156 | + int nOut, | |
| 82157 | + tRowcnt *aOut, | |
| 82158 | + int *pbUnordered | |
| 82159 | +){ | |
| 82160 | + char *z = zIntArray; | |
| 82161 | + int c; | |
| 82162 | + int i; | |
| 82163 | + tRowcnt v; | |
| 82164 | + | |
| 82165 | + assert( pbUnordered==0 || *pbUnordered==0 ); | |
| 82166 | + | |
| 82167 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 | |
| 82168 | + if( z==0 ) z = ""; | |
| 82169 | +#else | |
| 82170 | + if( NEVER(z==0) ) z = ""; | |
| 82171 | +#endif | |
| 82172 | + for(i=0; *z && i<nOut; i++){ | |
| 82173 | + v = 0; | |
| 82174 | + while( (c=z[0])>='0' && c<='9' ){ | |
| 82175 | + v = v*10 + c - '0'; | |
| 82176 | + z++; | |
| 82177 | + } | |
| 82178 | + aOut[i] = v; | |
| 82179 | + if( *z==' ' ) z++; | |
| 82180 | + } | |
| 82181 | + if( pbUnordered && strcmp(z, "unordered")==0 ){ | |
| 82182 | + *pbUnordered = 1; | |
| 82183 | + } | |
| 82184 | +} | |
| 81370 | 82185 | |
| 81371 | 82186 | /* |
| 81372 | 82187 | ** This callback is invoked once for each index when reading the |
| 81373 | 82188 | ** sqlite_stat1 table. |
| 81374 | 82189 | ** |
| @@ -81381,12 +82196,10 @@ | ||
| 81381 | 82196 | */ |
| 81382 | 82197 | static int analysisLoader(void *pData, int argc, char **argv, char **NotUsed){ |
| 81383 | 82198 | analysisInfo *pInfo = (analysisInfo*)pData; |
| 81384 | 82199 | Index *pIndex; |
| 81385 | 82200 | Table *pTable; |
| 81386 | - int i, c, n; | |
| 81387 | - tRowcnt v; | |
| 81388 | 82201 | const char *z; |
| 81389 | 82202 | |
| 81390 | 82203 | assert( argc==3 ); |
| 81391 | 82204 | UNUSED_PARAMETER2(NotUsed, argc); |
| 81392 | 82205 | |
| @@ -81400,45 +82213,35 @@ | ||
| 81400 | 82213 | if( argv[1] ){ |
| 81401 | 82214 | pIndex = sqlite3FindIndex(pInfo->db, argv[1], pInfo->zDatabase); |
| 81402 | 82215 | }else{ |
| 81403 | 82216 | pIndex = 0; |
| 81404 | 82217 | } |
| 81405 | - n = pIndex ? pIndex->nColumn : 0; | |
| 81406 | 82218 | 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 | - } | |
| 82219 | + | |
| 82220 | + if( pIndex ){ | |
| 82221 | + int bUnordered = 0; | |
| 82222 | + decodeIntArray((char*)z, pIndex->nColumn+1, pIndex->aiRowEst,&bUnordered); | |
| 82223 | + if( pIndex->pPartIdxWhere==0 ) pTable->nRowEst = pIndex->aiRowEst[0]; | |
| 82224 | + pIndex->bUnordered = bUnordered; | |
| 82225 | + }else{ | |
| 82226 | + decodeIntArray((char*)z, 1, &pTable->nRowEst, 0); | |
| 82227 | + } | |
| 82228 | + | |
| 81424 | 82229 | return 0; |
| 81425 | 82230 | } |
| 81426 | 82231 | |
| 81427 | 82232 | /* |
| 81428 | 82233 | ** If the Index.aSample variable is not NULL, delete the aSample[] array |
| 81429 | 82234 | ** and its contents. |
| 81430 | 82235 | */ |
| 81431 | 82236 | SQLITE_PRIVATE void sqlite3DeleteIndexSamples(sqlite3 *db, Index *pIdx){ |
| 81432 | -#ifdef SQLITE_ENABLE_STAT3 | |
| 82237 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 | |
| 81433 | 82238 | if( pIdx->aSample ){ |
| 81434 | 82239 | int j; |
| 81435 | 82240 | for(j=0; j<pIdx->nSample; j++){ |
| 81436 | 82241 | IndexSample *p = &pIdx->aSample[j]; |
| 81437 | - if( p->eType==SQLITE_TEXT || p->eType==SQLITE_BLOB ){ | |
| 81438 | - sqlite3DbFree(db, p->u.z); | |
| 81439 | - } | |
| 82242 | + sqlite3DbFree(db, p->p); | |
| 81440 | 82243 | } |
| 81441 | 82244 | sqlite3DbFree(db, pIdx->aSample); |
| 81442 | 82245 | } |
| 81443 | 82246 | if( db && db->pnBytesFreed==0 ){ |
| 81444 | 82247 | pIdx->nSample = 0; |
| @@ -81445,155 +82248,222 @@ | ||
| 81445 | 82248 | pIdx->aSample = 0; |
| 81446 | 82249 | } |
| 81447 | 82250 | #else |
| 81448 | 82251 | UNUSED_PARAMETER(db); |
| 81449 | 82252 | UNUSED_PARAMETER(pIdx); |
| 81450 | -#endif | |
| 82253 | +#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */ | |
| 81451 | 82254 | } |
| 81452 | 82255 | |
| 81453 | -#ifdef SQLITE_ENABLE_STAT3 | |
| 82256 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 | |
| 81454 | 82257 | /* |
| 81455 | -** Load content from the sqlite_stat3 table into the Index.aSample[] | |
| 81456 | -** arrays of all indices. | |
| 82258 | +** Populate the pIdx->aAvgEq[] array based on the samples currently | |
| 82259 | +** stored in pIdx->aSample[]. | |
| 81457 | 82260 | */ |
| 81458 | -static int loadStat3(sqlite3 *db, const char *zDb){ | |
| 82261 | +static void initAvgEq(Index *pIdx){ | |
| 82262 | + if( pIdx ){ | |
| 82263 | + IndexSample *aSample = pIdx->aSample; | |
| 82264 | + IndexSample *pFinal = &aSample[pIdx->nSample-1]; | |
| 82265 | + int iCol; | |
| 82266 | + for(iCol=0; iCol<pIdx->nColumn; iCol++){ | |
| 82267 | + int i; /* Used to iterate through samples */ | |
| 82268 | + tRowcnt sumEq = 0; /* Sum of the nEq values */ | |
| 82269 | + int nSum = 0; /* Number of terms contributing to sumEq */ | |
| 82270 | + tRowcnt avgEq = 0; | |
| 82271 | + tRowcnt nDLt = pFinal->anDLt[iCol]; | |
| 82272 | + | |
| 82273 | + /* Set nSum to the number of distinct (iCol+1) field prefixes that | |
| 82274 | + ** occur in the stat4 table for this index before pFinal. Set | |
| 82275 | + ** sumEq to the sum of the nEq values for column iCol for the same | |
| 82276 | + ** set (adding the value only once where there exist dupicate | |
| 82277 | + ** prefixes). */ | |
| 82278 | + for(i=0; i<(pIdx->nSample-1); i++){ | |
| 82279 | + if( aSample[i].anDLt[iCol]!=aSample[i+1].anDLt[iCol] ){ | |
| 82280 | + sumEq += aSample[i].anEq[iCol]; | |
| 82281 | + nSum++; | |
| 82282 | + } | |
| 82283 | + } | |
| 82284 | + if( nDLt>nSum ){ | |
| 82285 | + avgEq = (pFinal->anLt[iCol] - sumEq)/(nDLt - nSum); | |
| 82286 | + } | |
| 82287 | + if( avgEq==0 ) avgEq = 1; | |
| 82288 | + pIdx->aAvgEq[iCol] = avgEq; | |
| 82289 | + if( pIdx->nSampleCol==1 ) break; | |
| 82290 | + } | |
| 82291 | + } | |
| 82292 | +} | |
| 82293 | + | |
| 82294 | +/* | |
| 82295 | +** Load the content from either the sqlite_stat4 or sqlite_stat3 table | |
| 82296 | +** into the relevant Index.aSample[] arrays. | |
| 82297 | +** | |
| 82298 | +** Arguments zSql1 and zSql2 must point to SQL statements that return | |
| 82299 | +** data equivalent to the following (statements are different for stat3, | |
| 82300 | +** see the caller of this function for details): | |
| 82301 | +** | |
| 82302 | +** zSql1: SELECT idx,count(*) FROM %Q.sqlite_stat4 GROUP BY idx | |
| 82303 | +** zSql2: SELECT idx,neq,nlt,ndlt,sample FROM %Q.sqlite_stat4 | |
| 82304 | +** | |
| 82305 | +** where %Q is replaced with the database name before the SQL is executed. | |
| 82306 | +*/ | |
| 82307 | +static int loadStatTbl( | |
| 82308 | + sqlite3 *db, /* Database handle */ | |
| 82309 | + int bStat3, /* Assume single column records only */ | |
| 82310 | + const char *zSql1, /* SQL statement 1 (see above) */ | |
| 82311 | + const char *zSql2, /* SQL statement 2 (see above) */ | |
| 82312 | + const char *zDb /* Database name (e.g. "main") */ | |
| 82313 | +){ | |
| 81459 | 82314 | int rc; /* Result codes from subroutines */ |
| 81460 | 82315 | sqlite3_stmt *pStmt = 0; /* An SQL statement being run */ |
| 81461 | 82316 | char *zSql; /* Text of the SQL statement */ |
| 81462 | 82317 | 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 | 82318 | IndexSample *pSample; /* A slot in pIdx->aSample[] */ |
| 81466 | 82319 | |
| 81467 | 82320 | 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); | |
| 82321 | + zSql = sqlite3MPrintf(db, zSql1, zDb); | |
| 81475 | 82322 | if( !zSql ){ |
| 81476 | 82323 | return SQLITE_NOMEM; |
| 81477 | 82324 | } |
| 81478 | 82325 | rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0); |
| 81479 | 82326 | sqlite3DbFree(db, zSql); |
| 81480 | 82327 | if( rc ) return rc; |
| 81481 | 82328 | |
| 81482 | 82329 | while( sqlite3_step(pStmt)==SQLITE_ROW ){ |
| 82330 | + int nIdxCol = 1; /* Number of columns in stat4 records */ | |
| 82331 | + int nAvgCol = 1; /* Number of entries in Index.aAvgEq */ | |
| 82332 | + | |
| 81483 | 82333 | char *zIndex; /* Index name */ |
| 81484 | 82334 | Index *pIdx; /* Pointer to the index object */ |
| 81485 | 82335 | int nSample; /* Number of samples */ |
| 82336 | + int nByte; /* Bytes of space required */ | |
| 82337 | + int i; /* Bytes of space required */ | |
| 82338 | + tRowcnt *pSpace; | |
| 81486 | 82339 | |
| 81487 | 82340 | zIndex = (char *)sqlite3_column_text(pStmt, 0); |
| 81488 | 82341 | if( zIndex==0 ) continue; |
| 81489 | 82342 | nSample = sqlite3_column_int(pStmt, 1); |
| 81490 | 82343 | 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]; | |
| 82344 | + assert( pIdx==0 || bStat3 || pIdx->nSample==0 ); | |
| 82345 | + /* Index.nSample is non-zero at this point if data has already been | |
| 82346 | + ** loaded from the stat4 table. In this case ignore stat3 data. */ | |
| 82347 | + if( pIdx==0 || pIdx->nSample ) continue; | |
| 82348 | + if( bStat3==0 ){ | |
| 82349 | + nIdxCol = pIdx->nColumn+1; | |
| 82350 | + nAvgCol = pIdx->nColumn; | |
| 82351 | + } | |
| 82352 | + pIdx->nSampleCol = nIdxCol; | |
| 82353 | + nByte = sizeof(IndexSample) * nSample; | |
| 82354 | + nByte += sizeof(tRowcnt) * nIdxCol * 3 * nSample; | |
| 82355 | + nByte += nAvgCol * sizeof(tRowcnt); /* Space for Index.aAvgEq[] */ | |
| 82356 | + | |
| 82357 | + pIdx->aSample = sqlite3DbMallocZero(db, nByte); | |
| 81496 | 82358 | if( pIdx->aSample==0 ){ |
| 81497 | - db->mallocFailed = 1; | |
| 81498 | 82359 | sqlite3_finalize(pStmt); |
| 81499 | 82360 | return SQLITE_NOMEM; |
| 81500 | 82361 | } |
| 82362 | + pSpace = (tRowcnt*)&pIdx->aSample[nSample]; | |
| 82363 | + pIdx->aAvgEq = pSpace; pSpace += nAvgCol; | |
| 82364 | + for(i=0; i<nSample; i++){ | |
| 82365 | + pIdx->aSample[i].anEq = pSpace; pSpace += nIdxCol; | |
| 82366 | + pIdx->aSample[i].anLt = pSpace; pSpace += nIdxCol; | |
| 82367 | + pIdx->aSample[i].anDLt = pSpace; pSpace += nIdxCol; | |
| 82368 | + } | |
| 82369 | + assert( ((u8*)pSpace)-nByte==(u8*)(pIdx->aSample) ); | |
| 81501 | 82370 | } |
| 81502 | 82371 | rc = sqlite3_finalize(pStmt); |
| 81503 | 82372 | if( rc ) return rc; |
| 81504 | 82373 | |
| 81505 | - zSql = sqlite3MPrintf(db, | |
| 81506 | - "SELECT idx,neq,nlt,ndlt,sample FROM %Q.sqlite_stat3", zDb); | |
| 82374 | + zSql = sqlite3MPrintf(db, zSql2, zDb); | |
| 81507 | 82375 | if( !zSql ){ |
| 81508 | 82376 | return SQLITE_NOMEM; |
| 81509 | 82377 | } |
| 81510 | 82378 | rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0); |
| 81511 | 82379 | sqlite3DbFree(db, zSql); |
| 81512 | 82380 | if( rc ) return rc; |
| 81513 | 82381 | |
| 81514 | 82382 | 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 */ | |
| 82383 | + char *zIndex; /* Index name */ | |
| 82384 | + Index *pIdx; /* Pointer to the index object */ | |
| 82385 | + int nCol = 1; /* Number of columns in index */ | |
| 81519 | 82386 | |
| 81520 | 82387 | zIndex = (char *)sqlite3_column_text(pStmt, 0); |
| 81521 | 82388 | if( zIndex==0 ) continue; |
| 81522 | 82389 | pIdx = sqlite3FindIndex(db, zIndex, zDb); |
| 81523 | 82390 | if( pIdx==0 ) continue; |
| 81524 | - if( pIdx==pPrevIdx ){ | |
| 81525 | - idx++; | |
| 81526 | - }else{ | |
| 82391 | + /* This next condition is true if data has already been loaded from | |
| 82392 | + ** the sqlite_stat4 table. In this case ignore stat3 data. */ | |
| 82393 | + nCol = pIdx->nSampleCol; | |
| 82394 | + if( bStat3 && nCol>1 ) continue; | |
| 82395 | + if( pIdx!=pPrevIdx ){ | |
| 82396 | + initAvgEq(pPrevIdx); | |
| 81527 | 82397 | 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 | |
| 82398 | + } | |
| 82399 | + pSample = &pIdx->aSample[pIdx->nSample]; | |
| 82400 | + decodeIntArray((char*)sqlite3_column_text(pStmt,1), nCol, pSample->anEq, 0); | |
| 82401 | + decodeIntArray((char*)sqlite3_column_text(pStmt,2), nCol, pSample->anLt, 0); | |
| 82402 | + decodeIntArray((char*)sqlite3_column_text(pStmt,3), nCol, pSample->anDLt,0); | |
| 82403 | + | |
| 82404 | + /* Take a copy of the sample. Add two 0x00 bytes the end of the buffer. | |
| 82405 | + ** This is in case the sample record is corrupted. In that case, the | |
| 82406 | + ** sqlite3VdbeRecordCompare() may read up to two varints past the | |
| 82407 | + ** end of the allocated buffer before it realizes it is dealing with | |
| 82408 | + ** a corrupt record. Adding the two 0x00 bytes prevents this from causing | |
| 82409 | + ** a buffer overread. */ | |
| 82410 | + pSample->n = sqlite3_column_bytes(pStmt, 4); | |
| 82411 | + pSample->p = sqlite3DbMallocZero(db, pSample->n + 2); | |
| 82412 | + if( pSample->p==0 ){ | |
| 82413 | + sqlite3_finalize(pStmt); | |
| 82414 | + return SQLITE_NOMEM; | |
| 82415 | + } | |
| 82416 | + memcpy(pSample->p, sqlite3_column_blob(pStmt, 4), pSample->n); | |
| 82417 | + pIdx->nSample++; | |
| 82418 | + } | |
| 82419 | + rc = sqlite3_finalize(pStmt); | |
| 82420 | + if( rc==SQLITE_OK ) initAvgEq(pPrevIdx); | |
| 82421 | + return rc; | |
| 82422 | +} | |
| 82423 | + | |
| 82424 | +/* | |
| 82425 | +** Load content from the sqlite_stat4 and sqlite_stat3 tables into | |
| 82426 | +** the Index.aSample[] arrays of all indices. | |
| 82427 | +*/ | |
| 82428 | +static int loadStat4(sqlite3 *db, const char *zDb){ | |
| 82429 | + int rc = SQLITE_OK; /* Result codes from subroutines */ | |
| 82430 | + | |
| 82431 | + assert( db->lookaside.bEnabled==0 ); | |
| 82432 | + if( sqlite3FindTable(db, "sqlite_stat4", zDb) ){ | |
| 82433 | + rc = loadStatTbl(db, 0, | |
| 82434 | + "SELECT idx,count(*) FROM %Q.sqlite_stat4 GROUP BY idx", | |
| 82435 | + "SELECT idx,neq,nlt,ndlt,sample FROM %Q.sqlite_stat4", | |
| 82436 | + zDb | |
| 82437 | + ); | |
| 82438 | + } | |
| 82439 | + | |
| 82440 | + if( rc==SQLITE_OK && sqlite3FindTable(db, "sqlite_stat3", zDb) ){ | |
| 82441 | + rc = loadStatTbl(db, 1, | |
| 82442 | + "SELECT idx,count(*) FROM %Q.sqlite_stat3 GROUP BY idx", | |
| 82443 | + "SELECT idx,neq,nlt,ndlt,sqlite_record(sample) FROM %Q.sqlite_stat3", | |
| 82444 | + zDb | |
| 82445 | + ); | |
| 82446 | + } | |
| 82447 | + | |
| 82448 | + return rc; | |
| 82449 | +} | |
| 82450 | +#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */ | |
| 82451 | + | |
| 82452 | +/* | |
| 82453 | +** Load the content of the sqlite_stat1 and sqlite_stat3/4 tables. The | |
| 81584 | 82454 | ** contents of sqlite_stat1 are used to populate the Index.aiRowEst[] |
| 81585 | -** arrays. The contents of sqlite_stat3 are used to populate the | |
| 82455 | +** arrays. The contents of sqlite_stat3/4 are used to populate the | |
| 81586 | 82456 | ** Index.aSample[] arrays. |
| 81587 | 82457 | ** |
| 81588 | 82458 | ** 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 | |
| 82459 | +** is returned. In this case, even if SQLITE_ENABLE_STAT3/4 was defined | |
| 82460 | +** during compilation and the sqlite_stat3/4 table is present, no data is | |
| 81591 | 82461 | ** read from it. |
| 81592 | 82462 | ** |
| 81593 | -** If SQLITE_ENABLE_STAT3 was defined during compilation and the | |
| 81594 | -** sqlite_stat3 table is not present in the database, SQLITE_ERROR is | |
| 82463 | +** If SQLITE_ENABLE_STAT3/4 was defined during compilation and the | |
| 82464 | +** sqlite_stat4 table is not present in the database, SQLITE_ERROR is | |
| 81595 | 82465 | ** returned. However, in this case, data is read from the sqlite_stat1 |
| 81596 | 82466 | ** table (if it is present) before returning. |
| 81597 | 82467 | ** |
| 81598 | 82468 | ** If an OOM error occurs, this function always sets db->mallocFailed. |
| 81599 | 82469 | ** This means if the caller does not care about other errors, the return |
| @@ -81611,11 +82481,11 @@ | ||
| 81611 | 82481 | /* Clear any prior statistics */ |
| 81612 | 82482 | assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); |
| 81613 | 82483 | for(i=sqliteHashFirst(&db->aDb[iDb].pSchema->idxHash);i;i=sqliteHashNext(i)){ |
| 81614 | 82484 | Index *pIdx = sqliteHashData(i); |
| 81615 | 82485 | sqlite3DefaultRowEst(pIdx); |
| 81616 | -#ifdef SQLITE_ENABLE_STAT3 | |
| 82486 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 | |
| 81617 | 82487 | sqlite3DeleteIndexSamples(db, pIdx); |
| 81618 | 82488 | pIdx->aSample = 0; |
| 81619 | 82489 | #endif |
| 81620 | 82490 | } |
| 81621 | 82491 | |
| @@ -81635,16 +82505,16 @@ | ||
| 81635 | 82505 | rc = sqlite3_exec(db, zSql, analysisLoader, &sInfo, 0); |
| 81636 | 82506 | sqlite3DbFree(db, zSql); |
| 81637 | 82507 | } |
| 81638 | 82508 | |
| 81639 | 82509 | |
| 81640 | - /* Load the statistics from the sqlite_stat3 table. */ | |
| 81641 | -#ifdef SQLITE_ENABLE_STAT3 | |
| 82510 | + /* Load the statistics from the sqlite_stat4 table. */ | |
| 82511 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 | |
| 81642 | 82512 | if( rc==SQLITE_OK ){ |
| 81643 | 82513 | int lookasideEnabled = db->lookaside.bEnabled; |
| 81644 | 82514 | db->lookaside.bEnabled = 0; |
| 81645 | - rc = loadStat3(db, sInfo.zDatabase); | |
| 82515 | + rc = loadStat4(db, sInfo.zDatabase); | |
| 81646 | 82516 | db->lookaside.bEnabled = lookasideEnabled; |
| 81647 | 82517 | } |
| 81648 | 82518 | #endif |
| 81649 | 82519 | |
| 81650 | 82520 | if( rc==SQLITE_NOMEM ){ |
| @@ -84496,11 +85366,11 @@ | ||
| 84496 | 85366 | const char *zType, /* "idx" or "tbl" */ |
| 84497 | 85367 | const char *zName /* Name of index or table */ |
| 84498 | 85368 | ){ |
| 84499 | 85369 | int i; |
| 84500 | 85370 | const char *zDbName = pParse->db->aDb[iDb].zName; |
| 84501 | - for(i=1; i<=3; i++){ | |
| 85371 | + for(i=1; i<=4; i++){ | |
| 84502 | 85372 | char zTab[24]; |
| 84503 | 85373 | sqlite3_snprintf(sizeof(zTab),zTab,"sqlite_stat%d",i); |
| 84504 | 85374 | if( sqlite3FindTable(pParse->db, zTab, zDbName) ){ |
| 84505 | 85375 | sqlite3NestedParse(pParse, |
| 84506 | 85376 | "DELETE FROM %Q.%s WHERE %s=%Q", |
| @@ -89167,10 +90037,13 @@ | ||
| 89167 | 90037 | sqlite3FuncDefInsert(pHash, &aFunc[i]); |
| 89168 | 90038 | } |
| 89169 | 90039 | sqlite3RegisterDateTimeFunctions(); |
| 89170 | 90040 | #ifndef SQLITE_OMIT_ALTERTABLE |
| 89171 | 90041 | sqlite3AlterFunctions(); |
| 90042 | +#endif | |
| 90043 | +#if defined(SQLITE_ENABLE_STAT3) || defined(SQLITE_ENABLE_STAT4) | |
| 90044 | + sqlite3AnalyzeFunctions(); | |
| 89172 | 90045 | #endif |
| 89173 | 90046 | } |
| 89174 | 90047 | |
| 89175 | 90048 | /************** End of func.c ************************************************/ |
| 89176 | 90049 | /************** Begin file fkey.c ********************************************/ |
| @@ -94387,11 +95260,11 @@ | ||
| 94387 | 95260 | */ |
| 94388 | 95261 | if( sqlite3StrICmp(zLeft,"journal_size_limit")==0 ){ |
| 94389 | 95262 | Pager *pPager = sqlite3BtreePager(pDb->pBt); |
| 94390 | 95263 | i64 iLimit = -2; |
| 94391 | 95264 | if( zRight ){ |
| 94392 | - sqlite3Atoi64(zRight, &iLimit, 1000000, SQLITE_UTF8); | |
| 95265 | + sqlite3Atoi64(zRight, &iLimit, sqlite3Strlen30(zRight), SQLITE_UTF8); | |
| 94393 | 95266 | if( iLimit<-1 ) iLimit = -1; |
| 94394 | 95267 | } |
| 94395 | 95268 | iLimit = sqlite3PagerJournalSizeLimit(pPager, iLimit); |
| 94396 | 95269 | returnSingleInt(pParse, "journal_size_limit", iLimit); |
| 94397 | 95270 | }else |
| @@ -94521,14 +95394,15 @@ | ||
| 94521 | 95394 | ** as little or as much as it wants. Except, if N is set to 0 then the |
| 94522 | 95395 | ** upper layers will never invoke the xFetch interfaces to the VFS. |
| 94523 | 95396 | */ |
| 94524 | 95397 | if( sqlite3StrICmp(zLeft,"mmap_size")==0 ){ |
| 94525 | 95398 | sqlite3_int64 sz; |
| 95399 | +#if SQLITE_MAX_MMAP_SIZE>0 | |
| 94526 | 95400 | assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); |
| 94527 | 95401 | if( zRight ){ |
| 94528 | 95402 | int ii; |
| 94529 | - sqlite3Atoi64(zRight, &sz, 1000, SQLITE_UTF8); | |
| 95403 | + sqlite3Atoi64(zRight, &sz, sqlite3Strlen30(zRight), SQLITE_UTF8); | |
| 94530 | 95404 | if( sz<0 ) sz = sqlite3GlobalConfig.szMmap; |
| 94531 | 95405 | if( pId2->n==0 ) db->szMmap = sz; |
| 94532 | 95406 | for(ii=db->nDb-1; ii>=0; ii--){ |
| 94533 | 95407 | if( db->aDb[ii].pBt && (ii==iDb || pId2->n==0) ){ |
| 94534 | 95408 | sqlite3BtreeSetMmapLimit(db->aDb[ii].pBt, sz); |
| @@ -94535,12 +95409,13 @@ | ||
| 94535 | 95409 | } |
| 94536 | 95410 | } |
| 94537 | 95411 | } |
| 94538 | 95412 | sz = -1; |
| 94539 | 95413 | rc = sqlite3_file_control(db, zDb, SQLITE_FCNTL_MMAP_SIZE, &sz); |
| 94540 | -#if SQLITE_MAX_MMAP_SIZE==0 | |
| 95414 | +#else | |
| 94541 | 95415 | sz = 0; |
| 95416 | + rc = SQLITE_OK; | |
| 94542 | 95417 | #endif |
| 94543 | 95418 | if( rc==SQLITE_OK ){ |
| 94544 | 95419 | returnSingleInt(pParse, "mmap_size", sz); |
| 94545 | 95420 | }else if( rc!=SQLITE_NOTFOUND ){ |
| 94546 | 95421 | pParse->nErr++; |
| @@ -102688,11 +103563,11 @@ | ||
| 102688 | 103563 | ** space. |
| 102689 | 103564 | */ |
| 102690 | 103565 | SQLITE_PRIVATE void sqlite3ColumnDefault(Vdbe *v, Table *pTab, int i, int iReg){ |
| 102691 | 103566 | assert( pTab!=0 ); |
| 102692 | 103567 | if( !pTab->pSelect ){ |
| 102693 | - sqlite3_value *pValue; | |
| 103568 | + sqlite3_value *pValue = 0; | |
| 102694 | 103569 | u8 enc = ENC(sqlite3VdbeDb(v)); |
| 102695 | 103570 | Column *pCol = &pTab->aCol[i]; |
| 102696 | 103571 | VdbeComment((v, "%s.%s", pTab->zName, pCol->zName)); |
| 102697 | 103572 | assert( i<pTab->nCol ); |
| 102698 | 103573 | sqlite3ValueFromExpr(sqlite3VdbeDb(v), pCol->pDflt, enc, |
| @@ -105038,11 +105913,11 @@ | ||
| 105038 | 105913 | #define TERM_CODED 0x04 /* This term is already coded */ |
| 105039 | 105914 | #define TERM_COPIED 0x08 /* Has a child */ |
| 105040 | 105915 | #define TERM_ORINFO 0x10 /* Need to free the WhereTerm.u.pOrInfo object */ |
| 105041 | 105916 | #define TERM_ANDINFO 0x20 /* Need to free the WhereTerm.u.pAndInfo obj */ |
| 105042 | 105917 | #define TERM_OR_OK 0x40 /* Used during OR-clause processing */ |
| 105043 | -#ifdef SQLITE_ENABLE_STAT3 | |
| 105918 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 | |
| 105044 | 105919 | # define TERM_VNULL 0x80 /* Manufactured x>NULL or x<=NULL term */ |
| 105045 | 105920 | #else |
| 105046 | 105921 | # define TERM_VNULL 0x00 /* Disabled if not using stat3 */ |
| 105047 | 105922 | #endif |
| 105048 | 105923 | |
| @@ -105144,10 +106019,14 @@ | ||
| 105144 | 106019 | WhereInfo *pWInfo; /* Information about this WHERE */ |
| 105145 | 106020 | WhereClause *pWC; /* WHERE clause terms */ |
| 105146 | 106021 | ExprList *pOrderBy; /* ORDER BY clause */ |
| 105147 | 106022 | WhereLoop *pNew; /* Template WhereLoop */ |
| 105148 | 106023 | WhereOrSet *pOrSet; /* Record best loops here, if not NULL */ |
| 106024 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 | |
| 106025 | + UnpackedRecord *pRec; /* Probe for stat4 (if required) */ | |
| 106026 | + int nRecValid; /* Number of valid fields currently in pRec */ | |
| 106027 | +#endif | |
| 105149 | 106028 | }; |
| 105150 | 106029 | |
| 105151 | 106030 | /* |
| 105152 | 106031 | ** The WHERE clause processing routine has two halves. The |
| 105153 | 106032 | ** first part does the start of the WHERE loop and the second |
| @@ -106543,11 +107422,11 @@ | ||
| 106543 | 107422 | pNewTerm->prereqAll = pTerm->prereqAll; |
| 106544 | 107423 | } |
| 106545 | 107424 | } |
| 106546 | 107425 | #endif /* SQLITE_OMIT_VIRTUALTABLE */ |
| 106547 | 107426 | |
| 106548 | -#ifdef SQLITE_ENABLE_STAT3 | |
| 107427 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 | |
| 106549 | 107428 | /* When sqlite_stat3 histogram data is available an operator of the |
| 106550 | 107429 | ** form "x IS NOT NULL" can sometimes be evaluated more efficiently |
| 106551 | 107430 | ** as "x>NULL" if x is not an INTEGER PRIMARY KEY. So construct a |
| 106552 | 107431 | ** virtual term of that form. |
| 106553 | 107432 | ** |
| @@ -106583,11 +107462,11 @@ | ||
| 106583 | 107462 | pTerm->nChild = 1; |
| 106584 | 107463 | pTerm->wtFlags |= TERM_COPIED; |
| 106585 | 107464 | pNewTerm->prereqAll = pTerm->prereqAll; |
| 106586 | 107465 | } |
| 106587 | 107466 | } |
| 106588 | -#endif /* SQLITE_ENABLE_STAT */ | |
| 107467 | +#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */ | |
| 106589 | 107468 | |
| 106590 | 107469 | /* Prevent ON clause terms of a LEFT JOIN from being used to drive |
| 106591 | 107470 | ** an index for tables to the left of the join. |
| 106592 | 107471 | */ |
| 106593 | 107472 | pTerm->prereqRight |= extraRight; |
| @@ -107151,155 +108030,84 @@ | ||
| 107151 | 108030 | return pParse->nErr; |
| 107152 | 108031 | } |
| 107153 | 108032 | #endif /* !defined(SQLITE_OMIT_VIRTUALTABLE) */ |
| 107154 | 108033 | |
| 107155 | 108034 | |
| 107156 | -#ifdef SQLITE_ENABLE_STAT3 | |
| 108035 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 | |
| 107157 | 108036 | /* |
| 107158 | 108037 | ** Estimate the location of a particular key among all keys in an |
| 107159 | 108038 | ** index. Store the results in aStat as follows: |
| 107160 | 108039 | ** |
| 107161 | 108040 | ** aStat[0] Est. number of rows less than pVal |
| 107162 | 108041 | ** aStat[1] Est. number of rows equal to pVal |
| 107163 | 108042 | ** |
| 107164 | 108043 | ** Return SQLITE_OK on success. |
| 107165 | 108044 | */ |
| 107166 | -static int whereKeyStats( | |
| 108045 | +static void whereKeyStats( | |
| 107167 | 108046 | Parse *pParse, /* Database connection */ |
| 107168 | 108047 | Index *pIdx, /* Index to consider domain of */ |
| 107169 | - sqlite3_value *pVal, /* Value to consider */ | |
| 108048 | + UnpackedRecord *pRec, /* Vector of values to consider */ | |
| 107170 | 108049 | int roundUp, /* Round up if true. Round down if false */ |
| 107171 | 108050 | tRowcnt *aStat /* OUT: stats written here */ |
| 107172 | 108051 | ){ |
| 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 ); | |
| 108052 | + IndexSample *aSample = pIdx->aSample; | |
| 108053 | + int iCol = pRec->nField-1; /* Index of required stats in anEq[] etc. */ | |
| 108054 | + int iMin = 0; /* Smallest sample not yet tested */ | |
| 108055 | + int i = pIdx->nSample; /* Smallest sample larger than or equal to pRec */ | |
| 108056 | + int iTest; /* Next sample to test */ | |
| 108057 | + int res; /* Result of comparison operation */ | |
| 108058 | + | |
| 107181 | 108059 | 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 | - } | |
| 108060 | + assert( pRec->nField>0 && iCol<pIdx->nSampleCol ); | |
| 108061 | + do{ | |
| 108062 | + iTest = (iMin+i)/2; | |
| 108063 | + res = sqlite3VdbeRecordCompare(aSample[iTest].n, aSample[iTest].p, pRec); | |
| 108064 | + if( res<0 ){ | |
| 108065 | + iMin = iTest+1; | |
| 108066 | + }else{ | |
| 108067 | + i = iTest; | |
| 108068 | + } | |
| 108069 | + }while( res && iMin<i ); | |
| 108070 | + | |
| 108071 | +#ifdef SQLITE_DEBUG | |
| 108072 | + /* The following assert statements check that the binary search code | |
| 108073 | + ** above found the right answer. This block serves no purpose other | |
| 108074 | + ** than to invoke the asserts. */ | |
| 108075 | + if( res==0 ){ | |
| 108076 | + /* If (res==0) is true, then sample $i must be equal to pRec */ | |
| 108077 | + assert( i<pIdx->nSample ); | |
| 108078 | + assert( 0==sqlite3VdbeRecordCompare(aSample[i].n, aSample[i].p, pRec) | |
| 108079 | + || pParse->db->mallocFailed ); | |
| 108080 | + }else{ | |
| 108081 | + /* Otherwise, pRec must be smaller than sample $i and larger than | |
| 108082 | + ** sample ($i-1). */ | |
| 108083 | + assert( i==pIdx->nSample | |
| 108084 | + || sqlite3VdbeRecordCompare(aSample[i].n, aSample[i].p, pRec)>0 | |
| 108085 | + || pParse->db->mallocFailed ); | |
| 108086 | + assert( i==0 | |
| 108087 | + || sqlite3VdbeRecordCompare(aSample[i-1].n, aSample[i-1].p, pRec)<0 | |
| 108088 | + || pParse->db->mallocFailed ); | |
| 108089 | + } | |
| 108090 | +#endif /* ifdef SQLITE_DEBUG */ | |
| 107282 | 108091 | |
| 107283 | 108092 | /* At this point, aSample[i] is the first sample that is greater than |
| 107284 | 108093 | ** or equal to pVal. Or if i==pIdx->nSample, then all samples are less |
| 107285 | - ** than pVal. If aSample[i]==pVal, then isEq==1. | |
| 108094 | + ** than pVal. If aSample[i]==pVal, then res==0. | |
| 107286 | 108095 | */ |
| 107287 | - if( isEq ){ | |
| 107288 | - assert( i<pIdx->nSample ); | |
| 107289 | - aStat[0] = aSample[i].nLt; | |
| 107290 | - aStat[1] = aSample[i].nEq; | |
| 108096 | + if( res==0 ){ | |
| 108097 | + aStat[0] = aSample[i].anLt[iCol]; | |
| 108098 | + aStat[1] = aSample[i].anEq[iCol]; | |
| 107291 | 108099 | }else{ |
| 107292 | 108100 | tRowcnt iLower, iUpper, iGap; |
| 107293 | 108101 | if( i==0 ){ |
| 107294 | 108102 | iLower = 0; |
| 107295 | - iUpper = aSample[0].nLt; | |
| 108103 | + iUpper = aSample[0].anLt[iCol]; | |
| 107296 | 108104 | }else{ |
| 107297 | - iUpper = i>=pIdx->nSample ? n : aSample[i].nLt; | |
| 107298 | - iLower = aSample[i-1].nEq + aSample[i-1].nLt; | |
| 108105 | + iUpper = i>=pIdx->nSample ? pIdx->aiRowEst[0] : aSample[i].anLt[iCol]; | |
| 108106 | + iLower = aSample[i-1].anEq[iCol] + aSample[i-1].anLt[iCol]; | |
| 107299 | 108107 | } |
| 107300 | - aStat[1] = pIdx->avgEq; | |
| 108108 | + aStat[1] = (pIdx->nColumn>iCol ? pIdx->aAvgEq[iCol] : 1); | |
| 107301 | 108109 | if( iLower>=iUpper ){ |
| 107302 | 108110 | iGap = 0; |
| 107303 | 108111 | }else{ |
| 107304 | 108112 | iGap = iUpper - iLower; |
| 107305 | 108113 | } |
| @@ -107308,48 +108116,12 @@ | ||
| 107308 | 108116 | }else{ |
| 107309 | 108117 | iGap = iGap/3; |
| 107310 | 108118 | } |
| 107311 | 108119 | aStat[0] = iLower + iGap; |
| 107312 | 108120 | } |
| 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 | |
| 108121 | +} | |
| 108122 | +#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */ | |
| 107351 | 108123 | |
| 107352 | 108124 | /* |
| 107353 | 108125 | ** This function is used to estimate the number of rows that will be visited |
| 107354 | 108126 | ** by scanning an index for a range of values. The range may have an upper |
| 107355 | 108127 | ** bound, a lower bound, or both. The WHERE clause terms that set the upper |
| @@ -107362,107 +108134,154 @@ | ||
| 107362 | 108134 | ** pLower pUpper |
| 107363 | 108135 | ** |
| 107364 | 108136 | ** If either of the upper or lower bound is not present, then NULL is passed in |
| 107365 | 108137 | ** place of the corresponding WhereTerm. |
| 107366 | 108138 | ** |
| 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: | |
| 108139 | +** The value in (pBuilder->pNew->u.btree.nEq) is the index of the index | |
| 108140 | +** column subject to the range constraint. Or, equivalently, the number of | |
| 108141 | +** equality constraints optimized by the proposed index scan. For example, | |
| 108142 | +** assuming index p is on t1(a, b), and the SQL query is: | |
| 107371 | 108143 | ** |
| 107372 | 108144 | ** ... FROM t1 WHERE a = ? AND b > ? AND b < ? ... |
| 107373 | 108145 | ** |
| 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: | |
| 108146 | +** then nEq is set to 1 (as the range restricted column, b, is the second | |
| 108147 | +** left-most column of the index). Or, if the query is: | |
| 107376 | 108148 | ** |
| 107377 | 108149 | ** ... FROM t1 WHERE a > ? AND a < ? ... |
| 107378 | 108150 | ** |
| 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. | |
| 108151 | +** then nEq is set to 0. | |
| 108152 | +** | |
| 108153 | +** When this function is called, *pnOut is set to the whereCost() of the | |
| 108154 | +** number of rows that the index scan is expected to visit without | |
| 108155 | +** considering the range constraints. If nEq is 0, this is the number of | |
| 108156 | +** rows in the index. Assuming no error occurs, *pnOut is adjusted (reduced) | |
| 108157 | +** to account for the range contraints pLower and pUpper. | |
| 108158 | +** | |
| 108159 | +** In the absence of sqlite_stat4 ANALYZE data, or if such data cannot be | |
| 108160 | +** used, each range inequality reduces the search space by a factor of 4. | |
| 108161 | +** Hence a pair of constraints (x>? AND x<?) reduces the expected number of | |
| 108162 | +** rows visited by a factor of 16. | |
| 107390 | 108163 | */ |
| 107391 | 108164 | static int whereRangeScanEst( |
| 107392 | 108165 | 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 */ | |
| 108166 | + WhereLoopBuilder *pBuilder, | |
| 107395 | 108167 | WhereTerm *pLower, /* Lower bound on the range. ex: "x>123" Might be NULL */ |
| 107396 | 108168 | WhereTerm *pUpper, /* Upper bound on the range. ex: "x<455" Might be NULL */ |
| 107397 | - WhereCost *pRangeDiv /* OUT: Reduce search space by this divisor */ | |
| 108169 | + WhereCost *pnOut /* IN/OUT: Number of rows visited */ | |
| 107398 | 108170 | ){ |
| 107399 | 108171 | int rc = SQLITE_OK; |
| 108172 | + int nOut = (int)*pnOut; | |
| 107400 | 108173 | |
| 107401 | -#ifdef SQLITE_ENABLE_STAT3 | |
| 108174 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 | |
| 108175 | + Index *p = pBuilder->pNew->u.btree.pIndex; | |
| 108176 | + int nEq = pBuilder->pNew->u.btree.nEq; | |
| 107402 | 108177 | |
| 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]; | |
| 108178 | + if( nEq==pBuilder->nRecValid | |
| 108179 | + && nEq<p->nSampleCol | |
| 108180 | + && p->nSample | |
| 108181 | + && OptimizationEnabled(pParse->db, SQLITE_Stat3) | |
| 108182 | + ){ | |
| 108183 | + UnpackedRecord *pRec = pBuilder->pRec; | |
| 107407 | 108184 | tRowcnt a[2]; |
| 107408 | 108185 | u8 aff = p->pTable->aCol[p->aiColumn[0]].affinity; |
| 107409 | 108186 | |
| 108187 | + /* Variable iLower will be set to the estimate of the number of rows in | |
| 108188 | + ** the index that are less than the lower bound of the range query. The | |
| 108189 | + ** lower bound being the concatenation of $P and $L, where $P is the | |
| 108190 | + ** key-prefix formed by the nEq values matched against the nEq left-most | |
| 108191 | + ** columns of the index, and $L is the value in pLower. | |
| 108192 | + ** | |
| 108193 | + ** Or, if pLower is NULL or $L cannot be extracted from it (because it | |
| 108194 | + ** is not a simple variable or literal value), the lower bound of the | |
| 108195 | + ** range is $P. Due to a quirk in the way whereKeyStats() works, even | |
| 108196 | + ** if $L is available, whereKeyStats() is called for both ($P) and | |
| 108197 | + ** ($P:$L) and the larger of the two returned values used. | |
| 108198 | + ** | |
| 108199 | + ** Similarly, iUpper is to be set to the estimate of the number of rows | |
| 108200 | + ** less than the upper bound of the range query. Where the upper bound | |
| 108201 | + ** is either ($P) or ($P:$U). Again, even if $U is available, both values | |
| 108202 | + ** of iUpper are requested of whereKeyStats() and the smaller used. | |
| 108203 | + */ | |
| 108204 | + tRowcnt iLower; | |
| 108205 | + tRowcnt iUpper; | |
| 108206 | + | |
| 108207 | + /* Determine iLower and iUpper using ($P) only. */ | |
| 108208 | + if( nEq==0 ){ | |
| 108209 | + iLower = 0; | |
| 108210 | + iUpper = p->aiRowEst[0]; | |
| 108211 | + }else{ | |
| 108212 | + /* Note: this call could be optimized away - since the same values must | |
| 108213 | + ** have been requested when testing key $P in whereEqualScanEst(). */ | |
| 108214 | + whereKeyStats(pParse, p, pRec, 0, a); | |
| 108215 | + iLower = a[0]; | |
| 108216 | + iUpper = a[0] + a[1]; | |
| 108217 | + } | |
| 108218 | + | |
| 108219 | + /* If possible, improve on the iLower estimate using ($P:$L). */ | |
| 107410 | 108220 | if( pLower ){ |
| 108221 | + int bOk; /* True if value is extracted from pExpr */ | |
| 107411 | 108222 | Expr *pExpr = pLower->pExpr->pRight; |
| 107412 | - rc = valueFromExpr(pParse, pExpr, aff, &pRangeVal); | |
| 107413 | 108223 | 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); | |
| 108224 | + rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, aff, nEq, &bOk); | |
| 108225 | + if( rc==SQLITE_OK && bOk ){ | |
| 108226 | + tRowcnt iNew; | |
| 108227 | + whereKeyStats(pParse, p, pRec, 0, a); | |
| 108228 | + iNew = a[0] + ((pLower->eOperator & WO_GT) ? a[1] : 0); | |
| 108229 | + if( iNew>iLower ) iLower = iNew; | |
| 108230 | + } | |
| 108231 | + } | |
| 108232 | + | |
| 108233 | + /* If possible, improve on the iUpper estimate using ($P:$U). */ | |
| 108234 | + if( pUpper ){ | |
| 108235 | + int bOk; /* True if value is extracted from pExpr */ | |
| 108236 | + Expr *pExpr = pUpper->pExpr->pRight; | |
| 107425 | 108237 | 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 | - } | |
| 108238 | + rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, aff, nEq, &bOk); | |
| 108239 | + if( rc==SQLITE_OK && bOk ){ | |
| 108240 | + tRowcnt iNew; | |
| 108241 | + whereKeyStats(pParse, p, pRec, 1, a); | |
| 108242 | + iNew = a[0] + ((pUpper->eOperator & WO_LE) ? a[1] : 0); | |
| 108243 | + if( iNew<iUpper ) iUpper = iNew; | |
| 108244 | + } | |
| 108245 | + } | |
| 108246 | + | |
| 108247 | + pBuilder->pRec = pRec; | |
| 107434 | 108248 | if( rc==SQLITE_OK ){ |
| 107435 | - WhereCost iBase = whereCost(p->aiRowEst[0]); | |
| 108249 | + WhereCost nNew; | |
| 107436 | 108250 | if( iUpper>iLower ){ |
| 107437 | - iBase -= whereCost(iUpper - iLower); | |
| 108251 | + nNew = whereCost(iUpper - iLower); | |
| 108252 | + }else{ | |
| 108253 | + nNew = 10; assert( 10==whereCost(2) ); | |
| 107438 | 108254 | } |
| 107439 | - *pRangeDiv = iBase; | |
| 107440 | - WHERETRACE(0x100, ("range scan regions: %u..%u div=%d\n", | |
| 107441 | - (u32)iLower, (u32)iUpper, *pRangeDiv)); | |
| 108255 | + if( nNew<nOut ){ | |
| 108256 | + nOut = nNew; | |
| 108257 | + } | |
| 108258 | + *pnOut = (WhereCost)nOut; | |
| 108259 | + WHERETRACE(0x100, ("range scan regions: %u..%u est=%d\n", | |
| 108260 | + (u32)iLower, (u32)iUpper, nOut)); | |
| 107442 | 108261 | return SQLITE_OK; |
| 107443 | 108262 | } |
| 107444 | 108263 | } |
| 107445 | 108264 | #else |
| 107446 | 108265 | UNUSED_PARAMETER(pParse); |
| 107447 | - UNUSED_PARAMETER(p); | |
| 107448 | - UNUSED_PARAMETER(nEq); | |
| 108266 | + UNUSED_PARAMETER(pBuilder); | |
| 107449 | 108267 | #endif |
| 107450 | 108268 | assert( pLower || pUpper ); |
| 107451 | - *pRangeDiv = 0; | |
| 107452 | 108269 | /* TUNING: Each inequality constraint reduces the search space 4-fold. |
| 107453 | 108270 | ** A BETWEEN operator, therefore, reduces the search space 16-fold */ |
| 107454 | 108271 | if( pLower && (pLower->wtFlags & TERM_VNULL)==0 ){ |
| 107455 | - *pRangeDiv += 20; assert( 20==whereCost(4) ); | |
| 108272 | + nOut -= 20; assert( 20==whereCost(4) ); | |
| 107456 | 108273 | } |
| 107457 | 108274 | if( pUpper ){ |
| 107458 | - *pRangeDiv += 20; assert( 20==whereCost(4) ); | |
| 108275 | + nOut -= 20; assert( 20==whereCost(4) ); | |
| 107459 | 108276 | } |
| 108277 | + if( nOut<10 ) nOut = 10; | |
| 108278 | + *pnOut = (WhereCost)nOut; | |
| 107460 | 108279 | return rc; |
| 107461 | 108280 | } |
| 107462 | 108281 | |
| 107463 | -#ifdef SQLITE_ENABLE_STAT3 | |
| 108282 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 | |
| 107464 | 108283 | /* |
| 107465 | 108284 | ** Estimate the number of rows that will be returned based on |
| 107466 | 108285 | ** an equality constraint x=VALUE and where that VALUE occurs in |
| 107467 | 108286 | ** the histogram data. This only works when x is the left-most |
| 107468 | 108287 | ** column of an index and sqlite_stat3 histogram data is available |
| @@ -107478,41 +108297,57 @@ | ||
| 107478 | 108297 | ** for a UTF conversion required for comparison. The error is stored |
| 107479 | 108298 | ** in the pParse structure. |
| 107480 | 108299 | */ |
| 107481 | 108300 | static int whereEqualScanEst( |
| 107482 | 108301 | Parse *pParse, /* Parsing & code generating context */ |
| 107483 | - Index *p, /* The index whose left-most column is pTerm */ | |
| 108302 | + WhereLoopBuilder *pBuilder, | |
| 107484 | 108303 | Expr *pExpr, /* Expression for VALUE in the x=VALUE constraint */ |
| 107485 | 108304 | tRowcnt *pnRow /* Write the revised row estimate here */ |
| 107486 | 108305 | ){ |
| 107487 | - sqlite3_value *pRhs = 0; /* VALUE on right-hand side of pTerm */ | |
| 108306 | + Index *p = pBuilder->pNew->u.btree.pIndex; | |
| 108307 | + int nEq = pBuilder->pNew->u.btree.nEq; | |
| 108308 | + UnpackedRecord *pRec = pBuilder->pRec; | |
| 107488 | 108309 | u8 aff; /* Column affinity */ |
| 107489 | 108310 | int rc; /* Subfunction return code */ |
| 107490 | 108311 | tRowcnt a[2]; /* Statistics */ |
| 108312 | + int bOk; | |
| 107491 | 108313 | |
| 108314 | + assert( nEq>=1 ); | |
| 108315 | + assert( nEq<=(p->nColumn+1) ); | |
| 107492 | 108316 | assert( p->aSample!=0 ); |
| 107493 | 108317 | 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); | |
| 108318 | + assert( pBuilder->nRecValid<nEq ); | |
| 108319 | + | |
| 108320 | + /* If values are not available for all fields of the index to the left | |
| 108321 | + ** of this one, no estimate can be made. Return SQLITE_NOTFOUND. */ | |
| 108322 | + if( pBuilder->nRecValid<(nEq-1) ){ | |
| 108323 | + return SQLITE_NOTFOUND; | |
| 108324 | + } | |
| 108325 | + | |
| 108326 | + /* This is an optimization only. The call to sqlite3Stat4ProbeSetValue() | |
| 108327 | + ** below would return the same value. */ | |
| 108328 | + if( nEq>p->nColumn ){ | |
| 108329 | + *pnRow = 1; | |
| 108330 | + return SQLITE_OK; | |
| 108331 | + } | |
| 108332 | + | |
| 108333 | + aff = p->pTable->aCol[p->aiColumn[nEq-1]].affinity; | |
| 108334 | + rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, aff, nEq-1, &bOk); | |
| 108335 | + pBuilder->pRec = pRec; | |
| 108336 | + if( rc!=SQLITE_OK ) return rc; | |
| 108337 | + if( bOk==0 ) return SQLITE_NOTFOUND; | |
| 108338 | + pBuilder->nRecValid = nEq; | |
| 108339 | + | |
| 108340 | + whereKeyStats(pParse, p, pRec, 0, a); | |
| 108341 | + WHERETRACE(0x100,("equality scan regions: %d\n", (int)a[1])); | |
| 108342 | + *pnRow = a[1]; | |
| 108343 | + | |
| 107509 | 108344 | return rc; |
| 107510 | 108345 | } |
| 107511 | -#endif /* defined(SQLITE_ENABLE_STAT3) */ | |
| 108346 | +#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */ | |
| 107512 | 108347 | |
| 107513 | -#ifdef SQLITE_ENABLE_STAT3 | |
| 108348 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 | |
| 107514 | 108349 | /* |
| 107515 | 108350 | ** Estimate the number of rows that will be returned based on |
| 107516 | 108351 | ** an IN constraint where the right-hand side of the IN operator |
| 107517 | 108352 | ** is a list of values. Example: |
| 107518 | 108353 | ** |
| @@ -107527,33 +108362,38 @@ | ||
| 107527 | 108362 | ** for a UTF conversion required for comparison. The error is stored |
| 107528 | 108363 | ** in the pParse structure. |
| 107529 | 108364 | */ |
| 107530 | 108365 | static int whereInScanEst( |
| 107531 | 108366 | Parse *pParse, /* Parsing & code generating context */ |
| 107532 | - Index *p, /* The index whose left-most column is pTerm */ | |
| 108367 | + WhereLoopBuilder *pBuilder, | |
| 107533 | 108368 | ExprList *pList, /* The value list on the RHS of "x IN (v1,v2,v3,...)" */ |
| 107534 | 108369 | tRowcnt *pnRow /* Write the revised row estimate here */ |
| 107535 | 108370 | ){ |
| 108371 | + Index *p = pBuilder->pNew->u.btree.pIndex; | |
| 108372 | + int nRecValid = pBuilder->nRecValid; | |
| 107536 | 108373 | int rc = SQLITE_OK; /* Subfunction return code */ |
| 107537 | 108374 | tRowcnt nEst; /* Number of rows for a single term */ |
| 107538 | 108375 | tRowcnt nRowEst = 0; /* New estimate of the number of rows */ |
| 107539 | 108376 | int i; /* Loop counter */ |
| 107540 | 108377 | |
| 107541 | 108378 | assert( p->aSample!=0 ); |
| 107542 | 108379 | for(i=0; rc==SQLITE_OK && i<pList->nExpr; i++){ |
| 107543 | 108380 | nEst = p->aiRowEst[0]; |
| 107544 | - rc = whereEqualScanEst(pParse, p, pList->a[i].pExpr, &nEst); | |
| 108381 | + rc = whereEqualScanEst(pParse, pBuilder, pList->a[i].pExpr, &nEst); | |
| 107545 | 108382 | nRowEst += nEst; |
| 108383 | + pBuilder->nRecValid = nRecValid; | |
| 107546 | 108384 | } |
| 108385 | + | |
| 107547 | 108386 | if( rc==SQLITE_OK ){ |
| 107548 | 108387 | if( nRowEst > p->aiRowEst[0] ) nRowEst = p->aiRowEst[0]; |
| 107549 | 108388 | *pnRow = nRowEst; |
| 107550 | 108389 | WHERETRACE(0x100,("IN row estimate: est=%g\n", nRowEst)); |
| 107551 | 108390 | } |
| 108391 | + assert( pBuilder->nRecValid==nRecValid ); | |
| 107552 | 108392 | return rc; |
| 107553 | 108393 | } |
| 107554 | -#endif /* defined(SQLITE_ENABLE_STAT3) */ | |
| 108394 | +#endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */ | |
| 107555 | 108395 | |
| 107556 | 108396 | /* |
| 107557 | 108397 | ** Disable a term in the WHERE clause. Except, do not disable the term |
| 107558 | 108398 | ** if it controls a LEFT OUTER JOIN and it did not originate in the ON |
| 107559 | 108399 | ** or USING clause of that join. |
| @@ -107787,11 +108627,11 @@ | ||
| 107787 | 108627 | pParse->db->mallocFailed = 1; |
| 107788 | 108628 | } |
| 107789 | 108629 | |
| 107790 | 108630 | /* Evaluate the equality constraints |
| 107791 | 108631 | */ |
| 107792 | - assert( zAff==0 || strlen(zAff)>=nEq ); | |
| 108632 | + assert( zAff==0 || (int)strlen(zAff)>=nEq ); | |
| 107793 | 108633 | for(j=0; j<nEq; j++){ |
| 107794 | 108634 | int r1; |
| 107795 | 108635 | pTerm = pLoop->aLTerm[j]; |
| 107796 | 108636 | assert( pTerm!=0 ); |
| 107797 | 108637 | /* The following true for indices with redundant columns. |
| @@ -109094,16 +109934,22 @@ | ||
| 109094 | 109934 | saved_nOut = pNew->nOut; |
| 109095 | 109935 | pNew->rSetup = 0; |
| 109096 | 109936 | rLogSize = estLog(whereCost(pProbe->aiRowEst[0])); |
| 109097 | 109937 | for(; rc==SQLITE_OK && pTerm!=0; pTerm = whereScanNext(&scan)){ |
| 109098 | 109938 | int nIn = 0; |
| 109099 | - if( pTerm->prereqRight & pNew->maskSelf ) continue; | |
| 109939 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 | |
| 109940 | + int nRecValid = pBuilder->nRecValid; | |
| 109941 | +#endif | |
| 109100 | 109942 | if( (pTerm->eOperator==WO_ISNULL || (pTerm->wtFlags&TERM_VNULL)!=0) |
| 109101 | 109943 | && (iCol<0 || pSrc->pTab->aCol[iCol].notNull) |
| 109102 | 109944 | ){ |
| 109103 | 109945 | continue; /* ignore IS [NOT] NULL constraints on NOT NULL columns */ |
| 109104 | 109946 | } |
| 109947 | + if( pTerm->prereqRight & pNew->maskSelf ) continue; | |
| 109948 | + | |
| 109949 | + assert( pNew->nOut==saved_nOut ); | |
| 109950 | + | |
| 109105 | 109951 | pNew->wsFlags = saved_wsFlags; |
| 109106 | 109952 | pNew->u.btree.nEq = saved_nEq; |
| 109107 | 109953 | pNew->nLTerm = saved_nLTerm; |
| 109108 | 109954 | if( whereLoopResize(db, pNew, pNew->nLTerm+1) ) break; /* OOM */ |
| 109109 | 109955 | pNew->aLTerm[pNew->nLTerm++] = pTerm; |
| @@ -109156,29 +110002,34 @@ | ||
| 109156 | 110002 | pBtm = (pNew->wsFlags & WHERE_BTM_LIMIT)!=0 ? |
| 109157 | 110003 | pNew->aLTerm[pNew->nLTerm-2] : 0; |
| 109158 | 110004 | } |
| 109159 | 110005 | if( pNew->wsFlags & WHERE_COLUMN_RANGE ){ |
| 109160 | 110006 | /* 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) ){ | |
| 110007 | + assert( pNew->nOut==saved_nOut ); | |
| 110008 | + whereRangeScanEst(pParse, pBuilder, pBtm, pTop, &pNew->nOut); | |
| 110009 | + } | |
| 110010 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 | |
| 110011 | + if( nInMul==0 | |
| 110012 | + && pProbe->nSample | |
| 110013 | + && pNew->u.btree.nEq<=pProbe->nSampleCol | |
| 110014 | + && OptimizationEnabled(db, SQLITE_Stat3) | |
| 110015 | + ){ | |
| 110016 | + Expr *pExpr = pTerm->pExpr; | |
| 109169 | 110017 | tRowcnt nOut = 0; |
| 109170 | 110018 | if( (pTerm->eOperator & (WO_EQ|WO_ISNULL))!=0 ){ |
| 109171 | 110019 | testcase( pTerm->eOperator & WO_EQ ); |
| 109172 | 110020 | testcase( pTerm->eOperator & WO_ISNULL ); |
| 109173 | - rc = whereEqualScanEst(pParse, pProbe, pTerm->pExpr->pRight, &nOut); | |
| 110021 | + rc = whereEqualScanEst(pParse, pBuilder, pExpr->pRight, &nOut); | |
| 109174 | 110022 | }else if( (pTerm->eOperator & WO_IN) |
| 109175 | - && !ExprHasProperty(pTerm->pExpr, EP_xIsSelect) ){ | |
| 109176 | - rc = whereInScanEst(pParse, pProbe, pTerm->pExpr->x.pList, &nOut); | |
| 110023 | + && !ExprHasProperty(pExpr, EP_xIsSelect) ){ | |
| 110024 | + rc = whereInScanEst(pParse, pBuilder, pExpr->x.pList, &nOut); | |
| 109177 | 110025 | } |
| 109178 | 110026 | assert( nOut==0 || rc==SQLITE_OK ); |
| 109179 | - if( nOut ) pNew->nOut = whereCost(nOut); | |
| 110027 | + if( nOut ){ | |
| 110028 | + nOut = whereCost(nOut); | |
| 110029 | + pNew->nOut = MIN(nOut, saved_nOut); | |
| 110030 | + } | |
| 109180 | 110031 | } |
| 109181 | 110032 | #endif |
| 109182 | 110033 | if( (pNew->wsFlags & (WHERE_IDX_ONLY|WHERE_IPK))==0 ){ |
| 109183 | 110034 | /* Each row involves a step of the index, then a binary search of |
| 109184 | 110035 | ** the main table */ |
| @@ -109191,10 +110042,14 @@ | ||
| 109191 | 110042 | if( (pNew->wsFlags & WHERE_TOP_LIMIT)==0 |
| 109192 | 110043 | && pNew->u.btree.nEq<(pProbe->nColumn + (pProbe->zName!=0)) |
| 109193 | 110044 | ){ |
| 109194 | 110045 | whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, nInMul+nIn); |
| 109195 | 110046 | } |
| 110047 | + pNew->nOut = saved_nOut; | |
| 110048 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 | |
| 110049 | + pBuilder->nRecValid = nRecValid; | |
| 110050 | +#endif | |
| 109196 | 110051 | } |
| 109197 | 110052 | pNew->prereq = saved_prereq; |
| 109198 | 110053 | pNew->u.btree.nEq = saved_nEq; |
| 109199 | 110054 | pNew->wsFlags = saved_wsFlags; |
| 109200 | 110055 | pNew->nOut = saved_nOut; |
| @@ -109420,11 +110275,17 @@ | ||
| 109420 | 110275 | } |
| 109421 | 110276 | rc = whereLoopInsert(pBuilder, pNew); |
| 109422 | 110277 | if( rc ) break; |
| 109423 | 110278 | } |
| 109424 | 110279 | } |
| 110280 | + | |
| 109425 | 110281 | rc = whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, 0); |
| 110282 | +#ifdef SQLITE_ENABLE_STAT3_OR_STAT4 | |
| 110283 | + sqlite3Stat4ProbeFree(pBuilder->pRec); | |
| 110284 | + pBuilder->nRecValid = 0; | |
| 110285 | + pBuilder->pRec = 0; | |
| 110286 | +#endif | |
| 109426 | 110287 | |
| 109427 | 110288 | /* If there was an INDEXED BY clause, then only that one index is |
| 109428 | 110289 | ** considered. */ |
| 109429 | 110290 | if( pSrc->pIndex ) break; |
| 109430 | 110291 | } |
| 109431 | 110292 |
| --- src/sqlite3.c | |
| +++ src/sqlite3.c | |
| @@ -1,8 +1,8 @@ | |
| 1 | /****************************************************************************** |
| 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 |
| 4 | ** single large file, the entire code can be compiled as a single translation |
| 5 | ** unit. This allows many compilers to do optimizations that would not be |
| 6 | ** possible if the files were compiled separately. Performance improvements |
| 7 | ** of 5% or more are commonly seen when SQLite is compiled as a single |
| 8 | ** translation unit. |
| @@ -654,13 +654,13 @@ | |
| 654 | ** |
| 655 | ** See also: [sqlite3_libversion()], |
| 656 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 657 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 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" |
| 662 | |
| 663 | /* |
| 664 | ** CAPI3REF: Run-Time Library Version Numbers |
| 665 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 666 | ** |
| @@ -8368,10 +8368,24 @@ | |
| 8368 | #if SQLITE_DEFAULT_MMAP_SIZE>SQLITE_MAX_MMAP_SIZE |
| 8369 | # undef SQLITE_DEFAULT_MMAP_SIZE |
| 8370 | # define SQLITE_DEFAULT_MMAP_SIZE SQLITE_MAX_MMAP_SIZE |
| 8371 | #endif |
| 8372 | |
| 8373 | /* |
| 8374 | ** An instance of the following structure is used to store the busy-handler |
| 8375 | ** callback for a given sqlite handle. |
| 8376 | ** |
| 8377 | ** The sqlite.busyHandler member of the sqlite struct contains the busy |
| @@ -10770,13 +10784,14 @@ | |
| 10770 | u16 nColumn; /* Number of columns in table used by this index */ |
| 10771 | u8 onError; /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */ |
| 10772 | unsigned autoIndex:2; /* 1==UNIQUE, 2==PRIMARY KEY, 0==CREATE INDEX */ |
| 10773 | unsigned bUnordered:1; /* Use this index for == or IN queries only */ |
| 10774 | unsigned uniqNotNull:1; /* True if UNIQUE and NOT NULL for all columns */ |
| 10775 | #ifdef SQLITE_ENABLE_STAT3 |
| 10776 | int nSample; /* Number of elements in aSample[] */ |
| 10777 | tRowcnt avgEq; /* Average nEq value for key values not in aSample */ |
| 10778 | IndexSample *aSample; /* Samples of the left-most key */ |
| 10779 | #endif |
| 10780 | }; |
| 10781 | |
| 10782 | /* |
| @@ -10783,20 +10798,15 @@ | |
| 10783 | ** Each sample stored in the sqlite_stat3 table is represented in memory |
| 10784 | ** using a structure of this type. See documentation at the top of the |
| 10785 | ** analyze.c source file for additional information. |
| 10786 | */ |
| 10787 | 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 */ |
| 10798 | }; |
| 10799 | |
| 10800 | /* |
| 10801 | ** Each token coming out of the lexer is an instance of |
| 10802 | ** this structure. Tokens are also used as part of an expression. |
| @@ -12264,13 +12274,10 @@ | |
| 12264 | SQLITE_PRIVATE void sqlite3ValueSetStr(sqlite3_value*, int, const void *,u8, |
| 12265 | void(*)(void*)); |
| 12266 | SQLITE_PRIVATE void sqlite3ValueFree(sqlite3_value*); |
| 12267 | SQLITE_PRIVATE sqlite3_value *sqlite3ValueNew(sqlite3 *); |
| 12268 | 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 | SQLITE_PRIVATE int sqlite3ValueFromExpr(sqlite3 *, Expr *, u8, u8, sqlite3_value **); |
| 12273 | SQLITE_PRIVATE void sqlite3ValueApplyAffinity(sqlite3_value *, u8, u8); |
| 12274 | #ifndef SQLITE_AMALGAMATION |
| 12275 | SQLITE_PRIVATE const unsigned char sqlite3OpcodeProperty[]; |
| 12276 | SQLITE_PRIVATE const unsigned char sqlite3UpperToLower[]; |
| @@ -12332,10 +12339,16 @@ | |
| 12332 | SQLITE_PRIVATE void sqlite3SelectDestInit(SelectDest*,int,int); |
| 12333 | SQLITE_PRIVATE Expr *sqlite3CreateColumnExpr(sqlite3 *, SrcList *, int, int); |
| 12334 | |
| 12335 | SQLITE_PRIVATE void sqlite3BackupRestart(sqlite3_backup *); |
| 12336 | SQLITE_PRIVATE void sqlite3BackupUpdate(sqlite3_backup *, Pgno, const u8 *); |
| 12337 | |
| 12338 | /* |
| 12339 | ** The interface to the LEMON-generated parser |
| 12340 | */ |
| 12341 | SQLITE_PRIVATE void *sqlite3ParserAlloc(void*(*)(size_t)); |
| @@ -12916,11 +12929,13 @@ | |
| 12916 | "ENABLE_OVERSIZE_CELL_CHECK", |
| 12917 | #endif |
| 12918 | #ifdef SQLITE_ENABLE_RTREE |
| 12919 | "ENABLE_RTREE", |
| 12920 | #endif |
| 12921 | #ifdef SQLITE_ENABLE_STAT3 |
| 12922 | "ENABLE_STAT3", |
| 12923 | #endif |
| 12924 | #ifdef SQLITE_ENABLE_UNLOCK_NOTIFY |
| 12925 | "ENABLE_UNLOCK_NOTIFY", |
| 12926 | #endif |
| @@ -16075,11 +16090,11 @@ | |
| 16075 | struct MemBlockHdr *pHdr; |
| 16076 | if( !p ){ |
| 16077 | return 0; |
| 16078 | } |
| 16079 | pHdr = sqlite3MemsysGetHeader(p); |
| 16080 | return pHdr->iSize; |
| 16081 | } |
| 16082 | |
| 16083 | /* |
| 16084 | ** Initialize the memory allocation subsystem. |
| 16085 | */ |
| @@ -16117,19 +16132,19 @@ | |
| 16117 | static void randomFill(char *pBuf, int nByte){ |
| 16118 | unsigned int x, y, r; |
| 16119 | x = SQLITE_PTR_TO_INT(pBuf); |
| 16120 | y = nByte | 1; |
| 16121 | while( nByte >= 4 ){ |
| 16122 | x = (x>>1) ^ (-(x&1) & 0xd0000001); |
| 16123 | y = y*1103515245 + 12345; |
| 16124 | r = x ^ y; |
| 16125 | *(int*)pBuf = r; |
| 16126 | pBuf += 4; |
| 16127 | nByte -= 4; |
| 16128 | } |
| 16129 | while( nByte-- > 0 ){ |
| 16130 | x = (x>>1) ^ (-(x&1) & 0xd0000001); |
| 16131 | y = y*1103515245 + 12345; |
| 16132 | r = x ^ y; |
| 16133 | *(pBuf++) = r & 0xff; |
| 16134 | } |
| 16135 | } |
| @@ -16220,13 +16235,13 @@ | |
| 16220 | assert( mem.pLast==pHdr ); |
| 16221 | mem.pLast = pHdr->pPrev; |
| 16222 | } |
| 16223 | z = (char*)pBt; |
| 16224 | z -= pHdr->nTitle; |
| 16225 | adjustStats(pHdr->iSize, -1); |
| 16226 | randomFill(z, sizeof(void*)*pHdr->nBacktraceSlots + sizeof(*pHdr) + |
| 16227 | pHdr->iSize + sizeof(int) + pHdr->nTitle); |
| 16228 | free(z); |
| 16229 | sqlite3_mutex_leave(mem.mutex); |
| 16230 | } |
| 16231 | |
| 16232 | /* |
| @@ -16246,11 +16261,11 @@ | |
| 16246 | pOldHdr = sqlite3MemsysGetHeader(pPrior); |
| 16247 | pNew = sqlite3MemMalloc(nByte); |
| 16248 | if( pNew ){ |
| 16249 | memcpy(pNew, pPrior, nByte<pOldHdr->iSize ? nByte : pOldHdr->iSize); |
| 16250 | if( nByte>pOldHdr->iSize ){ |
| 16251 | randomFill(&((char*)pNew)[pOldHdr->iSize], nByte - pOldHdr->iSize); |
| 16252 | } |
| 16253 | sqlite3MemFree(pPrior); |
| 16254 | } |
| 16255 | return pNew; |
| 16256 | } |
| @@ -16361,11 +16376,11 @@ | |
| 16361 | SQLITE_PRIVATE void sqlite3MemdebugSync(){ |
| 16362 | struct MemBlockHdr *pHdr; |
| 16363 | for(pHdr=mem.pFirst; pHdr; pHdr=pHdr->pNext){ |
| 16364 | void **pBt = (void**)pHdr; |
| 16365 | pBt -= pHdr->nBacktraceSlots; |
| 16366 | mem.xBacktrace(pHdr->iSize, pHdr->nBacktrace-1, &pBt[1]); |
| 16367 | } |
| 16368 | } |
| 16369 | |
| 16370 | /* |
| 16371 | ** Open the file indicated and write a log of all unfreed memory |
| @@ -18483,11 +18498,11 @@ | |
| 18483 | GetVersionEx(&sInfo); |
| 18484 | osType = sInfo.dwPlatformId==VER_PLATFORM_WIN32_NT ? 2 : 1; |
| 18485 | } |
| 18486 | return osType==2; |
| 18487 | } |
| 18488 | #endif /* SQLITE_OS_WINCE */ |
| 18489 | #endif |
| 18490 | |
| 18491 | #ifdef SQLITE_DEBUG |
| 18492 | /* |
| 18493 | ** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are |
| @@ -18521,11 +18536,11 @@ | |
| 18521 | /* As winMutexInit() and winMutexEnd() are called as part |
| 18522 | ** of the sqlite3_initialize and sqlite3_shutdown() |
| 18523 | ** processing, the "interlocked" magic is probably not |
| 18524 | ** strictly necessary. |
| 18525 | */ |
| 18526 | static long winMutex_lock = 0; |
| 18527 | |
| 18528 | SQLITE_API void sqlite3_win32_sleep(DWORD milliseconds); /* os_win.c */ |
| 18529 | |
| 18530 | static int winMutexInit(void){ |
| 18531 | /* The first to increment to 1 does actual initialization */ |
| @@ -21082,36 +21097,10 @@ | |
| 21082 | assert( (m.flags & MEM_Dyn)!=0 || db->mallocFailed ); |
| 21083 | assert( m.z || db->mallocFailed ); |
| 21084 | return m.z; |
| 21085 | } |
| 21086 | |
| 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 | /* |
| 21114 | ** zIn is a UTF-16 encoded unicode string at least nChar characters long. |
| 21115 | ** Return the number of bytes in the first nChar unicode characters |
| 21116 | ** in pZ. nChar must be non-negative. |
| 21117 | */ |
| @@ -23064,15 +23053,17 @@ | |
| 23064 | void *lockingContext; /* Locking style specific state */ |
| 23065 | UnixUnusedFd *pUnused; /* Pre-allocated UnixUnusedFd */ |
| 23066 | const char *zPath; /* Name of the file */ |
| 23067 | unixShm *pShm; /* Shared memory segment information */ |
| 23068 | int szChunk; /* Configured by FCNTL_CHUNK_SIZE */ |
| 23069 | int nFetchOut; /* Number of outstanding xFetch refs */ |
| 23070 | sqlite3_int64 mmapSize; /* Usable size of mapping at pMapRegion */ |
| 23071 | sqlite3_int64 mmapSizeActual; /* Actual size of mapping at pMapRegion */ |
| 23072 | sqlite3_int64 mmapSizeMax; /* Configured FCNTL_MMAP_SIZE value */ |
| 23073 | void *pMapRegion; /* Memory mapped region */ |
| 23074 | #ifdef __QNXNTO__ |
| 23075 | int sectorSize; /* Device sector size */ |
| 23076 | int deviceCharacteristics; /* Precomputed device characteristics */ |
| 23077 | #endif |
| 23078 | #if SQLITE_ENABLE_LOCKING_STYLE |
| @@ -23503,10 +23494,11 @@ | |
| 23503 | #define osRmdir ((int(*)(const char*))aSyscall[19].pCurrent) |
| 23504 | |
| 23505 | { "fchown", (sqlite3_syscall_ptr)posixFchown, 0 }, |
| 23506 | #define osFchown ((int(*)(int,uid_t,gid_t))aSyscall[20].pCurrent) |
| 23507 | |
| 23508 | { "mmap", (sqlite3_syscall_ptr)mmap, 0 }, |
| 23509 | #define osMmap ((void*(*)(void*,size_t,int,int,int,off_t))aSyscall[21].pCurrent) |
| 23510 | |
| 23511 | { "munmap", (sqlite3_syscall_ptr)munmap, 0 }, |
| 23512 | #define osMunmap ((void*(*)(void*,size_t))aSyscall[22].pCurrent) |
| @@ -23515,10 +23507,11 @@ | |
| 23515 | { "mremap", (sqlite3_syscall_ptr)mremap, 0 }, |
| 23516 | #else |
| 23517 | { "mremap", (sqlite3_syscall_ptr)0, 0 }, |
| 23518 | #endif |
| 23519 | #define osMremap ((void*(*)(void*,size_t,size_t,int,...))aSyscall[23].pCurrent) |
| 23520 | |
| 23521 | }; /* End of the overrideable system calls */ |
| 23522 | |
| 23523 | /* |
| 23524 | ** This is the xSetSystemCall() method of sqlite3_vfs for all of the |
| @@ -23600,10 +23593,35 @@ | |
| 23600 | for(i++; i<ArraySize(aSyscall); i++){ |
| 23601 | if( aSyscall[i].pCurrent!=0 ) return aSyscall[i].zName; |
| 23602 | } |
| 23603 | return 0; |
| 23604 | } |
| 23605 | |
| 23606 | /* |
| 23607 | ** Invoke open(). Do so multiple times, until it either succeeds or |
| 23608 | ** fails for some reason other than EINTR. |
| 23609 | ** |
| @@ -23627,11 +23645,11 @@ | |
| 23627 | #if defined(O_CLOEXEC) |
| 23628 | fd = osOpen(z,f|O_CLOEXEC,m2); |
| 23629 | #else |
| 23630 | fd = osOpen(z,f,m2); |
| 23631 | #endif |
| 23632 | }while( fd<0 && errno==EINTR ); |
| 23633 | if( fd>=0 ){ |
| 23634 | if( m!=0 ){ |
| 23635 | struct stat statbuf; |
| 23636 | if( osFstat(fd, &statbuf)==0 |
| 23637 | && statbuf.st_size==0 |
| @@ -24925,12 +24943,14 @@ | |
| 24925 | static int unixUnlock(sqlite3_file *id, int eFileLock){ |
| 24926 | assert( eFileLock==SHARED_LOCK || ((unixFile *)id)->nFetchOut==0 ); |
| 24927 | return posixUnlock(id, eFileLock, 0); |
| 24928 | } |
| 24929 | |
| 24930 | static int unixMapfile(unixFile *pFd, i64 nByte); |
| 24931 | static void unixUnmapfile(unixFile *pFd); |
| 24932 | |
| 24933 | /* |
| 24934 | ** This function performs the parts of the "close file" operation |
| 24935 | ** common to all locking schemes. It closes the directory and file |
| 24936 | ** handles, if they are valid, and sets all fields of the unixFile |
| @@ -24940,11 +24960,13 @@ | |
| 24940 | ** even on VxWorks. A mutex will be acquired on VxWorks by the |
| 24941 | ** vxworksReleaseFileId() routine. |
| 24942 | */ |
| 24943 | static int closeUnixFile(sqlite3_file *id){ |
| 24944 | unixFile *pFile = (unixFile*)id; |
| 24945 | unixUnmapfile(pFile); |
| 24946 | if( pFile->h>=0 ){ |
| 24947 | robust_close(pFile, pFile->h, __LINE__); |
| 24948 | pFile->h = -1; |
| 24949 | } |
| 24950 | #if OS_VXWORKS |
| @@ -26145,10 +26167,11 @@ | |
| 26145 | #if (!defined(USE_PREAD) && !defined(USE_PREAD64)) |
| 26146 | i64 newOffset; |
| 26147 | #endif |
| 26148 | TIMER_START; |
| 26149 | assert( cnt==(cnt&0x1ffff) ); |
| 26150 | cnt &= 0x1ffff; |
| 26151 | do{ |
| 26152 | #if defined(USE_PREAD) |
| 26153 | got = osPread(id->h, pBuf, cnt, offset); |
| 26154 | SimulateIOError( got = -1 ); |
| @@ -26259,10 +26282,11 @@ | |
| 26259 | int *piErrno /* OUT: Error number if error occurs */ |
| 26260 | ){ |
| 26261 | int rc = 0; /* Value returned by system call */ |
| 26262 | |
| 26263 | assert( nBuf==(nBuf&0x1ffff) ); |
| 26264 | nBuf &= 0x1ffff; |
| 26265 | TIMER_START; |
| 26266 | |
| 26267 | #if defined(USE_PREAD) |
| 26268 | do{ rc = osPwrite(fd, pBuf, nBuf, iOff); }while( rc<0 && errno==EINTR ); |
| @@ -26644,17 +26668,19 @@ | |
| 26644 | if( pFile->inNormalWrite && nByte==0 ){ |
| 26645 | pFile->transCntrChng = 1; |
| 26646 | } |
| 26647 | #endif |
| 26648 | |
| 26649 | /* If the file was just truncated to a size smaller than the currently |
| 26650 | ** mapped region, reduce the effective mapping size as well. SQLite will |
| 26651 | ** use read() and write() to access data beyond this point from now on. |
| 26652 | */ |
| 26653 | if( nByte<pFile->mmapSize ){ |
| 26654 | pFile->mmapSize = nByte; |
| 26655 | } |
| 26656 | |
| 26657 | return SQLITE_OK; |
| 26658 | } |
| 26659 | } |
| 26660 | |
| @@ -26740,10 +26766,11 @@ | |
| 26740 | } |
| 26741 | #endif |
| 26742 | } |
| 26743 | } |
| 26744 | |
| 26745 | if( pFile->mmapSizeMax>0 && nByte>pFile->mmapSize ){ |
| 26746 | int rc; |
| 26747 | if( pFile->szChunk<=0 ){ |
| 26748 | if( robust_ftruncate(pFile->h, nByte) ){ |
| 26749 | pFile->lastErrno = errno; |
| @@ -26752,10 +26779,11 @@ | |
| 26752 | } |
| 26753 | |
| 26754 | rc = unixMapfile(pFile, nByte); |
| 26755 | return rc; |
| 26756 | } |
| 26757 | |
| 26758 | return SQLITE_OK; |
| 26759 | } |
| 26760 | |
| 26761 | /* |
| @@ -26820,10 +26848,11 @@ | |
| 26820 | unixGetTempname(pFile->pVfs->mxPathname, zTFile); |
| 26821 | *(char**)pArg = zTFile; |
| 26822 | } |
| 26823 | return SQLITE_OK; |
| 26824 | } |
| 26825 | case SQLITE_FCNTL_MMAP_SIZE: { |
| 26826 | i64 newLimit = *(i64*)pArg; |
| 26827 | int rc = SQLITE_OK; |
| 26828 | if( newLimit>sqlite3GlobalConfig.mxMmap ){ |
| 26829 | newLimit = sqlite3GlobalConfig.mxMmap; |
| @@ -26836,10 +26865,11 @@ | |
| 26836 | rc = unixMapfile(pFile, -1); |
| 26837 | } |
| 26838 | } |
| 26839 | return rc; |
| 26840 | } |
| 26841 | #ifdef SQLITE_DEBUG |
| 26842 | /* The pager calls this method to signal that it has done |
| 26843 | ** a rollback and that the database is therefore unchanged and |
| 26844 | ** it hence it is OK for the transaction change counter to be |
| 26845 | ** unchanged. |
| @@ -27646,26 +27676,24 @@ | |
| 27646 | # define unixShmLock 0 |
| 27647 | # define unixShmBarrier 0 |
| 27648 | # define unixShmUnmap 0 |
| 27649 | #endif /* #ifndef SQLITE_OMIT_WAL */ |
| 27650 | |
| 27651 | /* |
| 27652 | ** If it is currently memory mapped, unmap file pFd. |
| 27653 | */ |
| 27654 | static void unixUnmapfile(unixFile *pFd){ |
| 27655 | assert( pFd->nFetchOut==0 ); |
| 27656 | #if SQLITE_MAX_MMAP_SIZE>0 |
| 27657 | if( pFd->pMapRegion ){ |
| 27658 | osMunmap(pFd->pMapRegion, pFd->mmapSizeActual); |
| 27659 | pFd->pMapRegion = 0; |
| 27660 | pFd->mmapSize = 0; |
| 27661 | pFd->mmapSizeActual = 0; |
| 27662 | } |
| 27663 | #endif |
| 27664 | } |
| 27665 | |
| 27666 | #if SQLITE_MAX_MMAP_SIZE>0 |
| 27667 | /* |
| 27668 | ** Return the system page size. |
| 27669 | */ |
| 27670 | static int unixGetPagesize(void){ |
| 27671 | #if HAVE_MREMAP |
| @@ -27674,13 +27702,11 @@ | |
| 27674 | return getpagesize(); |
| 27675 | #else |
| 27676 | return (int)sysconf(_SC_PAGESIZE); |
| 27677 | #endif |
| 27678 | } |
| 27679 | #endif /* SQLITE_MAX_MMAP_SIZE>0 */ |
| 27680 | |
| 27681 | #if SQLITE_MAX_MMAP_SIZE>0 |
| 27682 | /* |
| 27683 | ** Attempt to set the size of the memory mapping maintained by file |
| 27684 | ** descriptor pFd to nNew bytes. Any existing mapping is discarded. |
| 27685 | ** |
| 27686 | ** If successful, this function sets the following variables: |
| @@ -27761,11 +27787,10 @@ | |
| 27761 | pFd->mmapSizeMax = 0; |
| 27762 | } |
| 27763 | pFd->pMapRegion = (void *)pNew; |
| 27764 | pFd->mmapSize = pFd->mmapSizeActual = nNew; |
| 27765 | } |
| 27766 | #endif |
| 27767 | |
| 27768 | /* |
| 27769 | ** Memory map or remap the file opened by file-descriptor pFd (if the file |
| 27770 | ** is already mapped, the existing mapping is replaced by the new). Or, if |
| 27771 | ** there already exists a mapping for this file, and there are still |
| @@ -27780,11 +27805,10 @@ | |
| 27780 | ** SQLITE_OK is returned if no error occurs (even if the mapping is not |
| 27781 | ** recreated as a result of outstanding references) or an SQLite error |
| 27782 | ** code otherwise. |
| 27783 | */ |
| 27784 | static int unixMapfile(unixFile *pFd, i64 nByte){ |
| 27785 | #if SQLITE_MAX_MMAP_SIZE>0 |
| 27786 | i64 nMap = nByte; |
| 27787 | int rc; |
| 27788 | |
| 27789 | assert( nMap>=0 || pFd->nFetchOut==0 ); |
| 27790 | if( pFd->nFetchOut>0 ) return SQLITE_OK; |
| @@ -27806,14 +27830,14 @@ | |
| 27806 | unixRemapfile(pFd, nMap); |
| 27807 | }else{ |
| 27808 | unixUnmapfile(pFd); |
| 27809 | } |
| 27810 | } |
| 27811 | #endif |
| 27812 | |
| 27813 | return SQLITE_OK; |
| 27814 | } |
| 27815 | |
| 27816 | /* |
| 27817 | ** If possible, return a pointer to a mapping of file fd starting at offset |
| 27818 | ** iOff. The mapping must be valid for at least nAmt bytes. |
| 27819 | ** |
| @@ -27858,10 +27882,11 @@ | |
| 27858 | */ |
| 27859 | static int unixUnfetch(sqlite3_file *fd, i64 iOff, void *p){ |
| 27860 | unixFile *pFd = (unixFile *)fd; /* The underlying database file */ |
| 27861 | UNUSED_PARAMETER(iOff); |
| 27862 | |
| 27863 | /* If p==0 (unmap the entire file) then there must be no outstanding |
| 27864 | ** xFetch references. Or, if p!=0 (meaning it is an xFetch reference), |
| 27865 | ** then there must be at least one outstanding. */ |
| 27866 | assert( (p==0)==(pFd->nFetchOut==0) ); |
| 27867 | |
| @@ -27873,10 +27898,11 @@ | |
| 27873 | }else{ |
| 27874 | unixUnmapfile(pFd); |
| 27875 | } |
| 27876 | |
| 27877 | assert( pFd->nFetchOut>=0 ); |
| 27878 | return SQLITE_OK; |
| 27879 | } |
| 27880 | |
| 27881 | /* |
| 27882 | ** Here ends the implementation of all sqlite3_file methods. |
| @@ -28204,11 +28230,13 @@ | |
| 28204 | OSTRACE(("OPEN %-3d %s\n", h, zFilename)); |
| 28205 | pNew->h = h; |
| 28206 | pNew->pVfs = pVfs; |
| 28207 | pNew->zPath = zFilename; |
| 28208 | pNew->ctrlFlags = (u8)ctrlFlags; |
| 28209 | pNew->mmapSizeMax = sqlite3GlobalConfig.szMmap; |
| 28210 | if( sqlite3_uri_boolean(((ctrlFlags & UNIXFILE_URI) ? zFilename : 0), |
| 28211 | "psow", SQLITE_POWERSAFE_OVERWRITE) ){ |
| 28212 | pNew->ctrlFlags |= UNIXFILE_PSOW; |
| 28213 | } |
| 28214 | if( strcmp(pVfs->zName,"unix-excl")==0 ){ |
| @@ -30705,11 +30733,11 @@ | |
| 30705 | /* |
| 30706 | ** Compiling and using WAL mode requires several APIs that are only |
| 30707 | ** available in Windows platforms based on the NT kernel. |
| 30708 | */ |
| 30709 | #if !SQLITE_OS_WINNT && !defined(SQLITE_OMIT_WAL) |
| 30710 | # error "WAL mode requires support from the Windows NT kernel, compile\ |
| 30711 | with SQLITE_OMIT_WAL." |
| 30712 | #endif |
| 30713 | |
| 30714 | /* |
| 30715 | ** Are most of the Win32 ANSI APIs available (i.e. with certain exceptions |
| @@ -30725,10 +30753,70 @@ | |
| 30725 | */ |
| 30726 | #if SQLITE_OS_WINCE || SQLITE_OS_WINNT || SQLITE_OS_WINRT |
| 30727 | # define SQLITE_WIN32_HAS_WIDE |
| 30728 | #endif |
| 30729 | |
| 30730 | /* |
| 30731 | ** Do we need to manually define the Win32 file mapping APIs for use with WAL |
| 30732 | ** mode (e.g. these APIs are available in the Windows CE SDK; however, they |
| 30733 | ** are not present in the header file)? |
| 30734 | */ |
| @@ -31732,15 +31820,15 @@ | |
| 31732 | ** this routine is used to determine if the host is Win95/98/ME or |
| 31733 | ** WinNT/2K/XP so that we will know whether or not we can safely call |
| 31734 | ** the LockFileEx() API. |
| 31735 | */ |
| 31736 | #if SQLITE_OS_WINCE || SQLITE_OS_WINRT |
| 31737 | # define isNT() (1) |
| 31738 | #elif !defined(SQLITE_WIN32_HAS_WIDE) |
| 31739 | # define isNT() (0) |
| 31740 | #else |
| 31741 | static int isNT(void){ |
| 31742 | if( sqlite3_os_type==0 ){ |
| 31743 | OSVERSIONINFOA sInfo; |
| 31744 | sInfo.dwOSVersionInfoSize = sizeof(sInfo); |
| 31745 | osGetVersionExA(&sInfo); |
| 31746 | sqlite3_os_type = sInfo.dwPlatformId==VER_PLATFORM_WIN32_NT ? 2 : 1; |
| @@ -31947,11 +32035,11 @@ | |
| 31947 | /* |
| 31948 | ** Convert a UTF-8 string to Microsoft Unicode (UTF-16?). |
| 31949 | ** |
| 31950 | ** Space to hold the returned string is obtained from malloc. |
| 31951 | */ |
| 31952 | static LPWSTR utf8ToUnicode(const char *zFilename){ |
| 31953 | int nChar; |
| 31954 | LPWSTR zWideFilename; |
| 31955 | |
| 31956 | nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0); |
| 31957 | if( nChar==0 ){ |
| @@ -31972,11 +32060,11 @@ | |
| 31972 | |
| 31973 | /* |
| 31974 | ** Convert Microsoft Unicode to UTF-8. Space to hold the returned string is |
| 31975 | ** obtained from sqlite3_malloc(). |
| 31976 | */ |
| 31977 | static char *unicodeToUtf8(LPCWSTR zWideFilename){ |
| 31978 | int nByte; |
| 31979 | char *zFilename; |
| 31980 | |
| 31981 | nByte = osWideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, 0, 0, 0, 0); |
| 31982 | if( nByte == 0 ){ |
| @@ -32000,11 +32088,11 @@ | |
| 32000 | ** current codepage settings for file apis. |
| 32001 | ** |
| 32002 | ** Space to hold the returned string is obtained |
| 32003 | ** from sqlite3_malloc. |
| 32004 | */ |
| 32005 | static LPWSTR mbcsToUnicode(const char *zFilename){ |
| 32006 | int nByte; |
| 32007 | LPWSTR zMbcsFilename; |
| 32008 | int codepage = osAreFileApisANSI() ? CP_ACP : CP_OEMCP; |
| 32009 | |
| 32010 | nByte = osMultiByteToWideChar(codepage, 0, zFilename, -1, NULL, |
| @@ -32030,11 +32118,11 @@ | |
| 32030 | ** user's ANSI codepage. |
| 32031 | ** |
| 32032 | ** Space to hold the returned string is obtained from |
| 32033 | ** sqlite3_malloc(). |
| 32034 | */ |
| 32035 | static char *unicodeToMbcs(LPCWSTR zWideFilename){ |
| 32036 | int nByte; |
| 32037 | char *zFilename; |
| 32038 | int codepage = osAreFileApisANSI() ? CP_ACP : CP_OEMCP; |
| 32039 | |
| 32040 | nByte = osWideCharToMultiByte(codepage, 0, zWideFilename, -1, 0, 0, 0, 0); |
| @@ -32060,15 +32148,15 @@ | |
| 32060 | */ |
| 32061 | SQLITE_API char *sqlite3_win32_mbcs_to_utf8(const char *zFilename){ |
| 32062 | char *zFilenameUtf8; |
| 32063 | LPWSTR zTmpWide; |
| 32064 | |
| 32065 | zTmpWide = mbcsToUnicode(zFilename); |
| 32066 | if( zTmpWide==0 ){ |
| 32067 | return 0; |
| 32068 | } |
| 32069 | zFilenameUtf8 = unicodeToUtf8(zTmpWide); |
| 32070 | sqlite3_free(zTmpWide); |
| 32071 | return zFilenameUtf8; |
| 32072 | } |
| 32073 | |
| 32074 | /* |
| @@ -32077,15 +32165,15 @@ | |
| 32077 | */ |
| 32078 | SQLITE_API char *sqlite3_win32_utf8_to_mbcs(const char *zFilename){ |
| 32079 | char *zFilenameMbcs; |
| 32080 | LPWSTR zTmpWide; |
| 32081 | |
| 32082 | zTmpWide = utf8ToUnicode(zFilename); |
| 32083 | if( zTmpWide==0 ){ |
| 32084 | return 0; |
| 32085 | } |
| 32086 | zFilenameMbcs = unicodeToMbcs(zTmpWide); |
| 32087 | sqlite3_free(zTmpWide); |
| 32088 | return zFilenameMbcs; |
| 32089 | } |
| 32090 | |
| 32091 | /* |
| @@ -32111,11 +32199,11 @@ | |
| 32111 | ); |
| 32112 | assert( !ppDirectory || sqlite3MemdebugHasType(*ppDirectory, MEMTYPE_HEAP) ); |
| 32113 | if( ppDirectory ){ |
| 32114 | char *zValueUtf8 = 0; |
| 32115 | if( zValue && zValue[0] ){ |
| 32116 | zValueUtf8 = unicodeToUtf8(zValue); |
| 32117 | if ( zValueUtf8==0 ){ |
| 32118 | return SQLITE_NOMEM; |
| 32119 | } |
| 32120 | } |
| 32121 | sqlite3_free(*ppDirectory); |
| @@ -32124,32 +32212,32 @@ | |
| 32124 | } |
| 32125 | return SQLITE_ERROR; |
| 32126 | } |
| 32127 | |
| 32128 | /* |
| 32129 | ** The return value of getLastErrorMsg |
| 32130 | ** is zero if the error message fits in the buffer, or non-zero |
| 32131 | ** otherwise (if the message was truncated). |
| 32132 | */ |
| 32133 | static int getLastErrorMsg(DWORD lastErrno, int nBuf, char *zBuf){ |
| 32134 | /* FormatMessage returns 0 on failure. Otherwise it |
| 32135 | ** returns the number of TCHARs written to the output |
| 32136 | ** buffer, excluding the terminating null char. |
| 32137 | */ |
| 32138 | DWORD dwLen = 0; |
| 32139 | char *zOut = 0; |
| 32140 | |
| 32141 | if( isNT() ){ |
| 32142 | #if SQLITE_OS_WINRT |
| 32143 | WCHAR zTempWide[MAX_PATH+1]; /* NOTE: Somewhat arbitrary. */ |
| 32144 | dwLen = osFormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | |
| 32145 | FORMAT_MESSAGE_IGNORE_INSERTS, |
| 32146 | NULL, |
| 32147 | lastErrno, |
| 32148 | 0, |
| 32149 | zTempWide, |
| 32150 | MAX_PATH, |
| 32151 | 0); |
| 32152 | #else |
| 32153 | LPWSTR zTempWide = NULL; |
| 32154 | dwLen = osFormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | |
| 32155 | FORMAT_MESSAGE_FROM_SYSTEM | |
| @@ -32162,11 +32250,11 @@ | |
| 32162 | 0); |
| 32163 | #endif |
| 32164 | if( dwLen > 0 ){ |
| 32165 | /* allocate a buffer and convert to UTF8 */ |
| 32166 | sqlite3BeginBenignMalloc(); |
| 32167 | zOut = unicodeToUtf8(zTempWide); |
| 32168 | sqlite3EndBenignMalloc(); |
| 32169 | #if !SQLITE_OS_WINRT |
| 32170 | /* free the system buffer allocated by FormatMessage */ |
| 32171 | osLocalFree(zTempWide); |
| 32172 | #endif |
| @@ -32230,11 +32318,11 @@ | |
| 32230 | ){ |
| 32231 | char zMsg[500]; /* Human readable error text */ |
| 32232 | int i; /* Loop counter */ |
| 32233 | |
| 32234 | zMsg[0] = 0; |
| 32235 | getLastErrorMsg(lastErrno, sizeof(zMsg), zMsg); |
| 32236 | assert( errcode!=SQLITE_OK ); |
| 32237 | if( zPath==0 ) zPath = ""; |
| 32238 | for(i=0; zMsg[i] && zMsg[i]!='\r' && zMsg[i]!='\n'; i++){} |
| 32239 | zMsg[i] = 0; |
| 32240 | sqlite3_log(errcode, |
| @@ -32255,30 +32343,30 @@ | |
| 32255 | # define SQLITE_WIN32_IOERR_RETRY 10 |
| 32256 | #endif |
| 32257 | #ifndef SQLITE_WIN32_IOERR_RETRY_DELAY |
| 32258 | # define SQLITE_WIN32_IOERR_RETRY_DELAY 25 |
| 32259 | #endif |
| 32260 | static int win32IoerrRetry = SQLITE_WIN32_IOERR_RETRY; |
| 32261 | static int win32IoerrRetryDelay = SQLITE_WIN32_IOERR_RETRY_DELAY; |
| 32262 | |
| 32263 | /* |
| 32264 | ** If a ReadFile() or WriteFile() error occurs, invoke this routine |
| 32265 | ** to see if it should be retried. Return TRUE to retry. Return FALSE |
| 32266 | ** to give up with an error. |
| 32267 | */ |
| 32268 | static int retryIoerr(int *pnRetry, DWORD *pError){ |
| 32269 | DWORD e = osGetLastError(); |
| 32270 | if( *pnRetry>=win32IoerrRetry ){ |
| 32271 | if( pError ){ |
| 32272 | *pError = e; |
| 32273 | } |
| 32274 | return 0; |
| 32275 | } |
| 32276 | if( e==ERROR_ACCESS_DENIED || |
| 32277 | e==ERROR_LOCK_VIOLATION || |
| 32278 | e==ERROR_SHARING_VIOLATION ){ |
| 32279 | sqlite3_win32_sleep(win32IoerrRetryDelay*(1+*pnRetry)); |
| 32280 | ++*pnRetry; |
| 32281 | return 1; |
| 32282 | } |
| 32283 | if( pError ){ |
| 32284 | *pError = e; |
| @@ -32287,15 +32375,15 @@ | |
| 32287 | } |
| 32288 | |
| 32289 | /* |
| 32290 | ** Log a I/O error retry episode. |
| 32291 | */ |
| 32292 | static void logIoerr(int nRetry){ |
| 32293 | if( nRetry ){ |
| 32294 | sqlite3_log(SQLITE_IOERR, |
| 32295 | "delayed %dms for lock/sharing conflict", |
| 32296 | win32IoerrRetryDelay*nRetry*(nRetry+1)/2 |
| 32297 | ); |
| 32298 | } |
| 32299 | } |
| 32300 | |
| 32301 | #if SQLITE_OS_WINCE |
| @@ -32356,11 +32444,11 @@ | |
| 32356 | LPWSTR zName; |
| 32357 | DWORD lastErrno; |
| 32358 | BOOL bLogged = FALSE; |
| 32359 | BOOL bInit = TRUE; |
| 32360 | |
| 32361 | zName = utf8ToUnicode(zFilename); |
| 32362 | if( zName==0 ){ |
| 32363 | /* out of memory */ |
| 32364 | return SQLITE_IOERR_NOMEM; |
| 32365 | } |
| 32366 | |
| @@ -32629,11 +32717,11 @@ | |
| 32629 | ** API LockFile. |
| 32630 | */ |
| 32631 | return winceLockFile(phFile, offsetLow, offsetHigh, |
| 32632 | numBytesLow, numBytesHigh); |
| 32633 | #else |
| 32634 | if( isNT() ){ |
| 32635 | OVERLAPPED ovlp; |
| 32636 | memset(&ovlp, 0, sizeof(OVERLAPPED)); |
| 32637 | ovlp.Offset = offsetLow; |
| 32638 | ovlp.OffsetHigh = offsetHigh; |
| 32639 | return osLockFileEx(*phFile, flags, 0, numBytesLow, numBytesHigh, &ovlp); |
| @@ -32660,11 +32748,11 @@ | |
| 32660 | ** API UnlockFile. |
| 32661 | */ |
| 32662 | return winceUnlockFile(phFile, offsetLow, offsetHigh, |
| 32663 | numBytesLow, numBytesHigh); |
| 32664 | #else |
| 32665 | if( isNT() ){ |
| 32666 | OVERLAPPED ovlp; |
| 32667 | memset(&ovlp, 0, sizeof(OVERLAPPED)); |
| 32668 | ovlp.Offset = offsetLow; |
| 32669 | ovlp.OffsetHigh = offsetHigh; |
| 32670 | return osUnlockFileEx(*phFile, 0, numBytesLow, numBytesHigh, &ovlp); |
| @@ -32690,11 +32778,11 @@ | |
| 32690 | /* |
| 32691 | ** Move the current position of the file handle passed as the first |
| 32692 | ** argument to offset iOffset within the file. If successful, return 0. |
| 32693 | ** Otherwise, set pFile->lastErrno and return non-zero. |
| 32694 | */ |
| 32695 | static int seekWinFile(winFile *pFile, sqlite3_int64 iOffset){ |
| 32696 | #if !SQLITE_OS_WINRT |
| 32697 | LONG upperBits; /* Most sig. 32 bits of new offset */ |
| 32698 | LONG lowerBits; /* Least sig. 32 bits of new offset */ |
| 32699 | DWORD dwRet; /* Value returned by SetFilePointer() */ |
| 32700 | DWORD lastErrno; /* Value returned by GetLastError() */ |
| @@ -32715,11 +32803,11 @@ | |
| 32715 | |
| 32716 | if( (dwRet==INVALID_SET_FILE_POINTER |
| 32717 | && ((lastErrno = osGetLastError())!=NO_ERROR)) ){ |
| 32718 | pFile->lastErrno = lastErrno; |
| 32719 | winLogError(SQLITE_IOERR_SEEK, pFile->lastErrno, |
| 32720 | "seekWinFile", pFile->zPath); |
| 32721 | OSTRACE(("SEEK file=%p, rc=SQLITE_IOERR_SEEK\n", pFile->h)); |
| 32722 | return 1; |
| 32723 | } |
| 32724 | |
| 32725 | OSTRACE(("SEEK file=%p, rc=SQLITE_OK\n", pFile->h)); |
| @@ -32736,11 +32824,11 @@ | |
| 32736 | bRet = osSetFilePointerEx(pFile->h, x, 0, FILE_BEGIN); |
| 32737 | |
| 32738 | if(!bRet){ |
| 32739 | pFile->lastErrno = osGetLastError(); |
| 32740 | winLogError(SQLITE_IOERR_SEEK, pFile->lastErrno, |
| 32741 | "seekWinFile", pFile->zPath); |
| 32742 | OSTRACE(("SEEK file=%p, rc=SQLITE_IOERR_SEEK\n", pFile->h)); |
| 32743 | return 1; |
| 32744 | } |
| 32745 | |
| 32746 | OSTRACE(("SEEK file=%p, rc=SQLITE_OK\n", pFile->h)); |
| @@ -32851,11 +32939,11 @@ | |
| 32851 | } |
| 32852 | } |
| 32853 | #endif |
| 32854 | |
| 32855 | #if SQLITE_OS_WINCE |
| 32856 | if( seekWinFile(pFile, offset) ){ |
| 32857 | OSTRACE(("READ file=%p, rc=SQLITE_FULL\n", pFile->h)); |
| 32858 | return SQLITE_FULL; |
| 32859 | } |
| 32860 | while( !osReadFile(pFile->h, pBuf, amt, &nRead, 0) ){ |
| 32861 | #else |
| @@ -32864,17 +32952,17 @@ | |
| 32864 | overlapped.OffsetHigh = (LONG)((offset>>32) & 0x7fffffff); |
| 32865 | while( !osReadFile(pFile->h, pBuf, amt, &nRead, &overlapped) && |
| 32866 | osGetLastError()!=ERROR_HANDLE_EOF ){ |
| 32867 | #endif |
| 32868 | DWORD lastErrno; |
| 32869 | if( retryIoerr(&nRetry, &lastErrno) ) continue; |
| 32870 | pFile->lastErrno = lastErrno; |
| 32871 | OSTRACE(("READ file=%p, rc=SQLITE_IOERR_READ\n", pFile->h)); |
| 32872 | return winLogError(SQLITE_IOERR_READ, pFile->lastErrno, |
| 32873 | "winRead", pFile->zPath); |
| 32874 | } |
| 32875 | logIoerr(nRetry); |
| 32876 | if( nRead<(DWORD)amt ){ |
| 32877 | /* Unread parts of the buffer must be zero-filled */ |
| 32878 | memset(&((char*)pBuf)[nRead], 0, amt-nRead); |
| 32879 | OSTRACE(("READ file=%p, rc=SQLITE_IOERR_SHORT_READ\n", pFile->h)); |
| 32880 | return SQLITE_IOERR_SHORT_READ; |
| @@ -32923,11 +33011,11 @@ | |
| 32923 | } |
| 32924 | } |
| 32925 | #endif |
| 32926 | |
| 32927 | #if SQLITE_OS_WINCE |
| 32928 | rc = seekWinFile(pFile, offset); |
| 32929 | if( rc==0 ){ |
| 32930 | #else |
| 32931 | { |
| 32932 | #endif |
| 32933 | #if !SQLITE_OS_WINCE |
| @@ -32948,11 +33036,11 @@ | |
| 32948 | #if SQLITE_OS_WINCE |
| 32949 | if( !osWriteFile(pFile->h, aRem, nRem, &nWrite, 0) ){ |
| 32950 | #else |
| 32951 | if( !osWriteFile(pFile->h, aRem, nRem, &nWrite, &overlapped) ){ |
| 32952 | #endif |
| 32953 | if( retryIoerr(&nRetry, &lastErrno) ) continue; |
| 32954 | break; |
| 32955 | } |
| 32956 | assert( nWrite==0 || nWrite<=(DWORD)nRem ); |
| 32957 | if( nWrite==0 || nWrite>(DWORD)nRem ){ |
| 32958 | lastErrno = osGetLastError(); |
| @@ -32980,11 +33068,11 @@ | |
| 32980 | } |
| 32981 | OSTRACE(("WRITE file=%p, rc=SQLITE_IOERR_WRITE\n", pFile->h)); |
| 32982 | return winLogError(SQLITE_IOERR_WRITE, pFile->lastErrno, |
| 32983 | "winWrite", pFile->zPath); |
| 32984 | }else{ |
| 32985 | logIoerr(nRetry); |
| 32986 | } |
| 32987 | OSTRACE(("WRITE file=%p, rc=SQLITE_OK\n", pFile->h)); |
| 32988 | return SQLITE_OK; |
| 32989 | } |
| 32990 | |
| @@ -33009,11 +33097,11 @@ | |
| 33009 | if( pFile->szChunk>0 ){ |
| 33010 | nByte = ((nByte + pFile->szChunk - 1)/pFile->szChunk) * pFile->szChunk; |
| 33011 | } |
| 33012 | |
| 33013 | /* SetEndOfFile() returns non-zero when successful, or zero when it fails. */ |
| 33014 | if( seekWinFile(pFile, nByte) ){ |
| 33015 | rc = winLogError(SQLITE_IOERR_TRUNCATE, pFile->lastErrno, |
| 33016 | "winTruncate1", pFile->zPath); |
| 33017 | }else if( 0==osSetEndOfFile(pFile->h) && |
| 33018 | ((lastErrno = osGetLastError())!=ERROR_USER_MAPPED_FILE) ){ |
| 33019 | pFile->lastErrno = lastErrno; |
| @@ -33090,10 +33178,11 @@ | |
| 33090 | |
| 33091 | /* If we compiled with the SQLITE_NO_SYNC flag, then syncing is a |
| 33092 | ** no-op |
| 33093 | */ |
| 33094 | #ifdef SQLITE_NO_SYNC |
| 33095 | return SQLITE_OK; |
| 33096 | #else |
| 33097 | rc = osFlushFileBuffers(pFile->h); |
| 33098 | SimulateIOError( rc=FALSE ); |
| 33099 | if( rc ){ |
| @@ -33187,14 +33276,14 @@ | |
| 33187 | /* |
| 33188 | ** Acquire a reader lock. |
| 33189 | ** Different API routines are called depending on whether or not this |
| 33190 | ** is Win9x or WinNT. |
| 33191 | */ |
| 33192 | static int getReadLock(winFile *pFile){ |
| 33193 | int res; |
| 33194 | OSTRACE(("READ-LOCK file=%p, lock=%d\n", pFile->h, pFile->locktype)); |
| 33195 | if( isNT() ){ |
| 33196 | #if SQLITE_OS_WINCE |
| 33197 | /* |
| 33198 | ** NOTE: Windows CE is handled differently here due its lack of the Win32 |
| 33199 | ** API LockFileEx. |
| 33200 | */ |
| @@ -33222,15 +33311,15 @@ | |
| 33222 | } |
| 33223 | |
| 33224 | /* |
| 33225 | ** Undo a readlock |
| 33226 | */ |
| 33227 | static int unlockReadLock(winFile *pFile){ |
| 33228 | int res; |
| 33229 | DWORD lastErrno; |
| 33230 | OSTRACE(("READ-UNLOCK file=%p, lock=%d\n", pFile->h, pFile->locktype)); |
| 33231 | if( isNT() ){ |
| 33232 | res = winUnlockFile(&pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0); |
| 33233 | } |
| 33234 | #ifdef SQLITE_WIN32_HAS_ANSI |
| 33235 | else{ |
| 33236 | res = winUnlockFile(&pFile->h, SHARED_FIRST+pFile->sharedLockByte, 0, 1, 0); |
| @@ -33237,11 +33326,11 @@ | |
| 33237 | } |
| 33238 | #endif |
| 33239 | if( res==0 && ((lastErrno = osGetLastError())!=ERROR_NOT_LOCKED) ){ |
| 33240 | pFile->lastErrno = lastErrno; |
| 33241 | winLogError(SQLITE_IOERR_UNLOCK, pFile->lastErrno, |
| 33242 | "unlockReadLock", pFile->zPath); |
| 33243 | } |
| 33244 | OSTRACE(("READ-UNLOCK file=%p, rc=%s\n", pFile->h, sqlite3ErrName(res))); |
| 33245 | return res; |
| 33246 | } |
| 33247 | |
| @@ -33328,11 +33417,11 @@ | |
| 33328 | |
| 33329 | /* Acquire a shared lock |
| 33330 | */ |
| 33331 | if( locktype==SHARED_LOCK && res ){ |
| 33332 | assert( pFile->locktype==NO_LOCK ); |
| 33333 | res = getReadLock(pFile); |
| 33334 | if( res ){ |
| 33335 | newLocktype = SHARED_LOCK; |
| 33336 | }else{ |
| 33337 | lastErrno = osGetLastError(); |
| 33338 | } |
| @@ -33359,18 +33448,18 @@ | |
| 33359 | |
| 33360 | /* Acquire an EXCLUSIVE lock |
| 33361 | */ |
| 33362 | if( locktype==EXCLUSIVE_LOCK && res ){ |
| 33363 | assert( pFile->locktype>=SHARED_LOCK ); |
| 33364 | res = unlockReadLock(pFile); |
| 33365 | res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS, SHARED_FIRST, 0, |
| 33366 | SHARED_SIZE, 0); |
| 33367 | if( res ){ |
| 33368 | newLocktype = EXCLUSIVE_LOCK; |
| 33369 | }else{ |
| 33370 | lastErrno = osGetLastError(); |
| 33371 | getReadLock(pFile); |
| 33372 | } |
| 33373 | } |
| 33374 | |
| 33375 | /* If we are holding a PENDING lock that ought to be released, then |
| 33376 | ** release it now. |
| @@ -33383,14 +33472,14 @@ | |
| 33383 | ** return the appropriate result code. |
| 33384 | */ |
| 33385 | if( res ){ |
| 33386 | rc = SQLITE_OK; |
| 33387 | }else{ |
| 33388 | OSTRACE(("LOCK-FAIL file=%p, wanted=%d, got=%d\n", |
| 33389 | pFile->h, locktype, newLocktype)); |
| 33390 | pFile->lastErrno = lastErrno; |
| 33391 | rc = SQLITE_BUSY; |
| 33392 | } |
| 33393 | pFile->locktype = (u8)newLocktype; |
| 33394 | OSTRACE(("LOCK file=%p, lock=%d, rc=%s\n", |
| 33395 | pFile->h, pFile->locktype, sqlite3ErrName(rc))); |
| 33396 | return rc; |
| @@ -33446,11 +33535,11 @@ | |
| 33446 | OSTRACE(("UNLOCK file=%p, oldLock=%d(%d), newLock=%d\n", |
| 33447 | pFile->h, pFile->locktype, pFile->sharedLockByte, locktype)); |
| 33448 | type = pFile->locktype; |
| 33449 | if( type>=EXCLUSIVE_LOCK ){ |
| 33450 | winUnlockFile(&pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0); |
| 33451 | if( locktype==SHARED_LOCK && !getReadLock(pFile) ){ |
| 33452 | /* This should never happen. We should always be able to |
| 33453 | ** reacquire the read lock */ |
| 33454 | rc = winLogError(SQLITE_IOERR_UNLOCK, osGetLastError(), |
| 33455 | "winUnlock", pFile->zPath); |
| 33456 | } |
| @@ -33457,11 +33546,11 @@ | |
| 33457 | } |
| 33458 | if( type>=RESERVED_LOCK ){ |
| 33459 | winUnlockFile(&pFile->h, RESERVED_BYTE, 0, 1, 0); |
| 33460 | } |
| 33461 | if( locktype==NO_LOCK && type>=SHARED_LOCK ){ |
| 33462 | unlockReadLock(pFile); |
| 33463 | } |
| 33464 | if( type>=PENDING_LOCK ){ |
| 33465 | winUnlockFile(&pFile->h, PENDING_BYTE, 0, 1, 0); |
| 33466 | } |
| 33467 | pFile->locktype = (u8)locktype; |
| @@ -33485,11 +33574,11 @@ | |
| 33485 | pFile->ctrlFlags |= mask; |
| 33486 | } |
| 33487 | } |
| 33488 | |
| 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 |
| 33494 | |
| 33495 | /* |
| @@ -33548,30 +33637,30 @@ | |
| 33548 | return SQLITE_OK; |
| 33549 | } |
| 33550 | case SQLITE_FCNTL_WIN32_AV_RETRY: { |
| 33551 | int *a = (int*)pArg; |
| 33552 | if( a[0]>0 ){ |
| 33553 | win32IoerrRetry = a[0]; |
| 33554 | }else{ |
| 33555 | a[0] = win32IoerrRetry; |
| 33556 | } |
| 33557 | if( a[1]>0 ){ |
| 33558 | win32IoerrRetryDelay = a[1]; |
| 33559 | }else{ |
| 33560 | a[1] = win32IoerrRetryDelay; |
| 33561 | } |
| 33562 | OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); |
| 33563 | return SQLITE_OK; |
| 33564 | } |
| 33565 | case SQLITE_FCNTL_TEMPFILENAME: { |
| 33566 | char *zTFile = sqlite3MallocZero( pFile->pVfs->mxPathname ); |
| 33567 | if( zTFile ){ |
| 33568 | getTempname(pFile->pVfs->mxPathname, zTFile); |
| 33569 | *(char**)pArg = zTFile; |
| 33570 | } |
| 33571 | OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); |
| 33572 | return SQLITE_OK; |
| 33573 | } |
| 33574 | #if SQLITE_MAX_MMAP_SIZE>0 |
| 33575 | case SQLITE_FCNTL_MMAP_SIZE: { |
| 33576 | i64 newLimit = *(i64*)pArg; |
| 33577 | int rc = SQLITE_OK; |
| @@ -34529,14 +34618,14 @@ | |
| 34529 | ** Convert a UTF-8 filename into whatever form the underlying |
| 34530 | ** operating system wants filenames in. Space to hold the result |
| 34531 | ** is obtained from malloc and must be freed by the calling |
| 34532 | ** function. |
| 34533 | */ |
| 34534 | static void *convertUtf8Filename(const char *zFilename){ |
| 34535 | void *zConverted = 0; |
| 34536 | if( isNT() ){ |
| 34537 | zConverted = utf8ToUnicode(zFilename); |
| 34538 | } |
| 34539 | #ifdef SQLITE_WIN32_HAS_ANSI |
| 34540 | else{ |
| 34541 | zConverted = sqlite3_win32_utf8_to_mbcs(zFilename); |
| 34542 | } |
| @@ -34544,117 +34633,135 @@ | |
| 34544 | /* caller will handle out of memory */ |
| 34545 | return zConverted; |
| 34546 | } |
| 34547 | |
| 34548 | /* |
| 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. |
| 34552 | */ |
| 34553 | #ifndef SQLITE_WIN32_MAX_PATH |
| 34554 | # define SQLITE_WIN32_MAX_PATH (MAX_PATH*3) |
| 34555 | #endif |
| 34556 | |
| 34557 | /* |
| 34558 | ** Create a temporary file name in zBuf. zBuf must be big enough to |
| 34559 | ** hold at pVfs->mxPathname characters. |
| 34560 | */ |
| 34561 | static int getTempname(int nBuf, char *zBuf){ |
| 34562 | static char zChars[] = |
| 34563 | "abcdefghijklmnopqrstuvwxyz" |
| 34564 | "ABCDEFGHIJKLMNOPQRSTUVWXYZ" |
| 34565 | "0123456789"; |
| 34566 | size_t i, j; |
| 34567 | int nTempPath; |
| 34568 | char zTempPath[SQLITE_WIN32_MAX_PATH+2]; |
| 34569 | |
| 34570 | /* It's odd to simulate an io-error here, but really this is just |
| 34571 | ** using the io-error infrastructure to test that SQLite handles this |
| 34572 | ** function failing. |
| 34573 | */ |
| 34574 | SimulateIOError( return SQLITE_IOERR ); |
| 34575 | |
| 34576 | if( sqlite3_temp_directory ){ |
| 34577 | sqlite3_snprintf(SQLITE_WIN32_MAX_PATH-30, zTempPath, "%s", |
| 34578 | sqlite3_temp_directory); |
| 34579 | } |
| 34580 | #if !SQLITE_OS_WINRT |
| 34581 | else if( isNT() ){ |
| 34582 | char *zMulti; |
| 34583 | WCHAR zWidePath[MAX_PATH]; |
| 34584 | if( osGetTempPathW(MAX_PATH-30, zWidePath)==0 ){ |
| 34585 | OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_GETTEMPPATH\n")); |
| 34586 | return SQLITE_IOERR_GETTEMPPATH; |
| 34587 | } |
| 34588 | zMulti = unicodeToUtf8(zWidePath); |
| 34589 | if( zMulti ){ |
| 34590 | sqlite3_snprintf(SQLITE_WIN32_MAX_PATH-30, zTempPath, "%s", zMulti); |
| 34591 | sqlite3_free(zMulti); |
| 34592 | }else{ |
| 34593 | OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); |
| 34594 | return SQLITE_IOERR_NOMEM; |
| 34595 | } |
| 34596 | } |
| 34597 | #ifdef SQLITE_WIN32_HAS_ANSI |
| 34598 | else{ |
| 34599 | char *zUtf8; |
| 34600 | char zMbcsPath[SQLITE_WIN32_MAX_PATH]; |
| 34601 | if( osGetTempPathA(SQLITE_WIN32_MAX_PATH-30, zMbcsPath)==0 ){ |
| 34602 | OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_GETTEMPPATH\n")); |
| 34603 | return SQLITE_IOERR_GETTEMPPATH; |
| 34604 | } |
| 34605 | zUtf8 = sqlite3_win32_mbcs_to_utf8(zMbcsPath); |
| 34606 | if( zUtf8 ){ |
| 34607 | sqlite3_snprintf(SQLITE_WIN32_MAX_PATH-30, zTempPath, "%s", zUtf8); |
| 34608 | sqlite3_free(zUtf8); |
| 34609 | }else{ |
| 34610 | OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); |
| 34611 | return SQLITE_IOERR_NOMEM; |
| 34612 | } |
| 34613 | } |
| 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 | #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 | #endif /* !SQLITE_OS_WINRT */ |
| 34632 | |
| 34633 | /* Check that the output buffer is large enough for the temporary file |
| 34634 | ** name. If it is not, return SQLITE_ERROR. |
| 34635 | */ |
| 34636 | nTempPath = sqlite3Strlen30(zTempPath); |
| 34637 | |
| 34638 | if( (nTempPath + sqlite3Strlen30(SQLITE_TEMP_FILE_PREFIX) + 18) >= nBuf ){ |
| 34639 | OSTRACE(("TEMP-FILENAME rc=SQLITE_ERROR\n")); |
| 34640 | return SQLITE_ERROR; |
| 34641 | } |
| 34642 | |
| 34643 | for(i=nTempPath; i>0 && zTempPath[i-1]=='\\'; i--){} |
| 34644 | zTempPath[i] = 0; |
| 34645 | |
| 34646 | sqlite3_snprintf(nBuf-18, zBuf, (nTempPath > 0) ? |
| 34647 | "%s\\"SQLITE_TEMP_FILE_PREFIX : SQLITE_TEMP_FILE_PREFIX, |
| 34648 | zTempPath); |
| 34649 | j = sqlite3Strlen30(zBuf); |
| 34650 | sqlite3_randomness(15, &zBuf[j]); |
| 34651 | for(i=0; i<15; i++, j++){ |
| 34652 | zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ]; |
| 34653 | } |
| 34654 | zBuf[j] = 0; |
| 34655 | zBuf[j+1] = 0; |
| 34656 | |
| 34657 | OSTRACE(("TEMP-FILENAME name=%s, rc=SQLITE_OK\n", zBuf)); |
| 34658 | return SQLITE_OK; |
| 34659 | } |
| 34660 | |
| @@ -34666,17 +34773,17 @@ | |
| 34666 | static int winIsDir(const void *zConverted){ |
| 34667 | DWORD attr; |
| 34668 | int rc = 0; |
| 34669 | DWORD lastErrno; |
| 34670 | |
| 34671 | if( isNT() ){ |
| 34672 | int cnt = 0; |
| 34673 | WIN32_FILE_ATTRIBUTE_DATA sAttrData; |
| 34674 | memset(&sAttrData, 0, sizeof(sAttrData)); |
| 34675 | while( !(rc = osGetFileAttributesExW((LPCWSTR)zConverted, |
| 34676 | GetFileExInfoStandard, |
| 34677 | &sAttrData)) && retryIoerr(&cnt, &lastErrno) ){} |
| 34678 | if( !rc ){ |
| 34679 | return 0; /* Invalid name? */ |
| 34680 | } |
| 34681 | attr = sAttrData.dwFileAttributes; |
| 34682 | #if SQLITE_OS_WINCE==0 |
| @@ -34689,11 +34796,11 @@ | |
| 34689 | |
| 34690 | /* |
| 34691 | ** Open a file. |
| 34692 | */ |
| 34693 | static int winOpen( |
| 34694 | sqlite3_vfs *pVfs, /* Not used */ |
| 34695 | const char *zName, /* Name of the file (UTF-8) */ |
| 34696 | sqlite3_file *id, /* Write the SQLite file handle here */ |
| 34697 | int flags, /* Open mode flags */ |
| 34698 | int *pOutFlags /* Status return flags */ |
| 34699 | ){ |
| @@ -34712,11 +34819,11 @@ | |
| 34712 | int cnt = 0; |
| 34713 | |
| 34714 | /* If argument zPath is a NULL pointer, this function is required to open |
| 34715 | ** a temporary file. Use this buffer to store the file name in. |
| 34716 | */ |
| 34717 | char zTmpname[SQLITE_WIN32_MAX_PATH+2]; /* Buffer used to create temp filename */ |
| 34718 | |
| 34719 | int rc = SQLITE_OK; /* Function Return Code */ |
| 34720 | #if !defined(NDEBUG) || SQLITE_OS_WINCE |
| 34721 | int eType = flags&0xFFFFFF00; /* Type of file to open */ |
| 34722 | #endif |
| @@ -34767,22 +34874,22 @@ | |
| 34767 | assert( pFile!=0 ); |
| 34768 | memset(pFile, 0, sizeof(winFile)); |
| 34769 | pFile->h = INVALID_HANDLE_VALUE; |
| 34770 | |
| 34771 | #if SQLITE_OS_WINRT |
| 34772 | if( !sqlite3_temp_directory ){ |
| 34773 | sqlite3_log(SQLITE_ERROR, |
| 34774 | "sqlite3_temp_directory variable should be set for WinRT"); |
| 34775 | } |
| 34776 | #endif |
| 34777 | |
| 34778 | /* If the second argument to this function is NULL, generate a |
| 34779 | ** temporary file name to use |
| 34780 | */ |
| 34781 | if( !zUtf8Name ){ |
| 34782 | assert(isDelete && !isOpenJournal); |
| 34783 | rc = getTempname(SQLITE_WIN32_MAX_PATH+2, zTmpname); |
| 34784 | if( rc!=SQLITE_OK ){ |
| 34785 | OSTRACE(("OPEN name=%s, rc=%s", zUtf8Name, sqlite3ErrName(rc))); |
| 34786 | return rc; |
| 34787 | } |
| 34788 | zUtf8Name = zTmpname; |
| @@ -34791,21 +34898,23 @@ | |
| 34791 | /* Database filenames are double-zero terminated if they are not |
| 34792 | ** URIs with parameters. Hence, they can always be passed into |
| 34793 | ** sqlite3_uri_parameter(). |
| 34794 | */ |
| 34795 | assert( (eType!=SQLITE_OPEN_MAIN_DB) || (flags & SQLITE_OPEN_URI) || |
| 34796 | zUtf8Name[strlen(zUtf8Name)+1]==0 ); |
| 34797 | |
| 34798 | /* Convert the filename to the system encoding. */ |
| 34799 | zConverted = convertUtf8Filename(zUtf8Name); |
| 34800 | if( zConverted==0 ){ |
| 34801 | OSTRACE(("OPEN name=%s, rc=SQLITE_IOERR_NOMEM", zUtf8Name)); |
| 34802 | return SQLITE_IOERR_NOMEM; |
| 34803 | } |
| 34804 | |
| 34805 | if( winIsDir(zConverted) ){ |
| 34806 | sqlite3_free(zConverted); |
| 34807 | OSTRACE(("OPEN name=%s, rc=SQLITE_CANTOPEN_ISDIR", zUtf8Name)); |
| 34808 | return SQLITE_CANTOPEN_ISDIR; |
| 34809 | } |
| 34810 | |
| 34811 | if( isReadWrite ){ |
| @@ -34848,11 +34957,11 @@ | |
| 34848 | ** better if FILE_FLAG_RANDOM_ACCESS is used. Ticket #2699. */ |
| 34849 | #if SQLITE_OS_WINCE |
| 34850 | dwFlagsAndAttributes |= FILE_FLAG_RANDOM_ACCESS; |
| 34851 | #endif |
| 34852 | |
| 34853 | if( isNT() ){ |
| 34854 | #if SQLITE_OS_WINRT |
| 34855 | CREATEFILE2_EXTENDED_PARAMETERS extendedParameters; |
| 34856 | extendedParameters.dwSize = sizeof(CREATEFILE2_EXTENDED_PARAMETERS); |
| 34857 | extendedParameters.dwFileAttributes = |
| 34858 | dwFlagsAndAttributes & FILE_ATTRIBUTE_MASK; |
| @@ -34863,21 +34972,21 @@ | |
| 34863 | while( (h = osCreateFile2((LPCWSTR)zConverted, |
| 34864 | dwDesiredAccess, |
| 34865 | dwShareMode, |
| 34866 | dwCreationDisposition, |
| 34867 | &extendedParameters))==INVALID_HANDLE_VALUE && |
| 34868 | retryIoerr(&cnt, &lastErrno) ){ |
| 34869 | /* Noop */ |
| 34870 | } |
| 34871 | #else |
| 34872 | while( (h = osCreateFileW((LPCWSTR)zConverted, |
| 34873 | dwDesiredAccess, |
| 34874 | dwShareMode, NULL, |
| 34875 | dwCreationDisposition, |
| 34876 | dwFlagsAndAttributes, |
| 34877 | NULL))==INVALID_HANDLE_VALUE && |
| 34878 | retryIoerr(&cnt, &lastErrno) ){ |
| 34879 | /* Noop */ |
| 34880 | } |
| 34881 | #endif |
| 34882 | } |
| 34883 | #ifdef SQLITE_WIN32_HAS_ANSI |
| @@ -34886,24 +34995,25 @@ | |
| 34886 | dwDesiredAccess, |
| 34887 | dwShareMode, NULL, |
| 34888 | dwCreationDisposition, |
| 34889 | dwFlagsAndAttributes, |
| 34890 | NULL))==INVALID_HANDLE_VALUE && |
| 34891 | retryIoerr(&cnt, &lastErrno) ){ |
| 34892 | /* Noop */ |
| 34893 | } |
| 34894 | } |
| 34895 | #endif |
| 34896 | logIoerr(cnt); |
| 34897 | |
| 34898 | OSTRACE(("OPEN file=%p, name=%s, access=%lx, rc=%s\n", h, zUtf8Name, |
| 34899 | dwDesiredAccess, (h==INVALID_HANDLE_VALUE) ? "failed" : "ok")); |
| 34900 | |
| 34901 | if( h==INVALID_HANDLE_VALUE ){ |
| 34902 | pFile->lastErrno = lastErrno; |
| 34903 | winLogError(SQLITE_CANTOPEN, pFile->lastErrno, "winOpen", zUtf8Name); |
| 34904 | sqlite3_free(zConverted); |
| 34905 | if( isReadWrite && !isExclusive ){ |
| 34906 | return winOpen(pVfs, zName, id, |
| 34907 | ((flags|SQLITE_OPEN_READONLY) & |
| 34908 | ~(SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE)), |
| 34909 | pOutFlags); |
| @@ -34928,19 +35038,21 @@ | |
| 34928 | if( isReadWrite && eType==SQLITE_OPEN_MAIN_DB |
| 34929 | && (rc = winceCreateLock(zName, pFile))!=SQLITE_OK |
| 34930 | ){ |
| 34931 | osCloseHandle(h); |
| 34932 | sqlite3_free(zConverted); |
| 34933 | OSTRACE(("OPEN-CE-LOCK name=%s, rc=%s\n", zName, sqlite3ErrName(rc))); |
| 34934 | return rc; |
| 34935 | } |
| 34936 | if( isTemp ){ |
| 34937 | pFile->zDeleteOnClose = zConverted; |
| 34938 | }else |
| 34939 | #endif |
| 34940 | { |
| 34941 | sqlite3_free(zConverted); |
| 34942 | } |
| 34943 | |
| 34944 | pFile->pMethod = &winIoMethod; |
| 34945 | pFile->pVfs = pVfs; |
| 34946 | pFile->h = h; |
| @@ -34990,15 +35102,16 @@ | |
| 34990 | UNUSED_PARAMETER(syncDir); |
| 34991 | |
| 34992 | SimulateIOError(return SQLITE_IOERR_DELETE); |
| 34993 | OSTRACE(("DELETE name=%s, syncDir=%d\n", zFilename, syncDir)); |
| 34994 | |
| 34995 | zConverted = convertUtf8Filename(zFilename); |
| 34996 | if( zConverted==0 ){ |
| 34997 | return SQLITE_IOERR_NOMEM; |
| 34998 | } |
| 34999 | if( isNT() ){ |
| 35000 | do { |
| 35001 | #if SQLITE_OS_WINRT |
| 35002 | WIN32_FILE_ATTRIBUTE_DATA sAttrData; |
| 35003 | memset(&sAttrData, 0, sizeof(sAttrData)); |
| 35004 | if ( osGetFileAttributesExW(zConverted, GetFileExInfoStandard, |
| @@ -35033,11 +35146,11 @@ | |
| 35033 | } |
| 35034 | if ( osDeleteFileW(zConverted) ){ |
| 35035 | rc = SQLITE_OK; /* Deleted OK. */ |
| 35036 | break; |
| 35037 | } |
| 35038 | if ( !retryIoerr(&cnt, &lastErrno) ){ |
| 35039 | rc = SQLITE_ERROR; /* No more retries. */ |
| 35040 | break; |
| 35041 | } |
| 35042 | } while(1); |
| 35043 | } |
| @@ -35061,11 +35174,11 @@ | |
| 35061 | } |
| 35062 | if ( osDeleteFileA(zConverted) ){ |
| 35063 | rc = SQLITE_OK; /* Deleted OK. */ |
| 35064 | break; |
| 35065 | } |
| 35066 | if ( !retryIoerr(&cnt, &lastErrno) ){ |
| 35067 | rc = SQLITE_ERROR; /* No more retries. */ |
| 35068 | break; |
| 35069 | } |
| 35070 | } while(1); |
| 35071 | } |
| @@ -35072,11 +35185,11 @@ | |
| 35072 | #endif |
| 35073 | if( rc && rc!=SQLITE_IOERR_DELETE_NOENT ){ |
| 35074 | rc = winLogError(SQLITE_IOERR_DELETE, lastErrno, |
| 35075 | "winDelete", zFilename); |
| 35076 | }else{ |
| 35077 | logIoerr(cnt); |
| 35078 | } |
| 35079 | sqlite3_free(zConverted); |
| 35080 | OSTRACE(("DELETE name=%s, rc=%s\n", zFilename, sqlite3ErrName(rc))); |
| 35081 | return rc; |
| 35082 | } |
| @@ -35098,22 +35211,22 @@ | |
| 35098 | |
| 35099 | SimulateIOError( return SQLITE_IOERR_ACCESS; ); |
| 35100 | OSTRACE(("ACCESS name=%s, flags=%x, pResOut=%p\n", |
| 35101 | zFilename, flags, pResOut)); |
| 35102 | |
| 35103 | zConverted = convertUtf8Filename(zFilename); |
| 35104 | if( zConverted==0 ){ |
| 35105 | OSTRACE(("ACCESS name=%s, rc=SQLITE_IOERR_NOMEM\n", zFilename)); |
| 35106 | return SQLITE_IOERR_NOMEM; |
| 35107 | } |
| 35108 | if( isNT() ){ |
| 35109 | int cnt = 0; |
| 35110 | WIN32_FILE_ATTRIBUTE_DATA sAttrData; |
| 35111 | memset(&sAttrData, 0, sizeof(sAttrData)); |
| 35112 | while( !(rc = osGetFileAttributesExW((LPCWSTR)zConverted, |
| 35113 | GetFileExInfoStandard, |
| 35114 | &sAttrData)) && retryIoerr(&cnt, &lastErrno) ){} |
| 35115 | if( rc ){ |
| 35116 | /* For an SQLITE_ACCESS_EXISTS query, treat a zero-length file |
| 35117 | ** as if it does not exist. |
| 35118 | */ |
| 35119 | if( flags==SQLITE_ACCESS_EXISTS |
| @@ -35122,11 +35235,11 @@ | |
| 35122 | attr = INVALID_FILE_ATTRIBUTES; |
| 35123 | }else{ |
| 35124 | attr = sAttrData.dwFileAttributes; |
| 35125 | } |
| 35126 | }else{ |
| 35127 | logIoerr(cnt); |
| 35128 | if( lastErrno!=ERROR_FILE_NOT_FOUND && lastErrno!=ERROR_PATH_NOT_FOUND ){ |
| 35129 | winLogError(SQLITE_IOERR_ACCESS, lastErrno, "winAccess", zFilename); |
| 35130 | sqlite3_free(zConverted); |
| 35131 | return SQLITE_IOERR_ACCESS; |
| 35132 | }else{ |
| @@ -35173,11 +35286,11 @@ | |
| 35173 | ** a legal UNC name, a volume relative path, or an absolute path name in the |
| 35174 | ** "Unix" format on Windows. There is no easy way to differentiate between |
| 35175 | ** the final two cases; therefore, we return the safer return value of TRUE |
| 35176 | ** so that callers of this function will simply use it verbatim. |
| 35177 | */ |
| 35178 | if ( zPathname[0]=='/' || zPathname[0]=='\\' ){ |
| 35179 | return TRUE; |
| 35180 | } |
| 35181 | |
| 35182 | /* |
| 35183 | ** If the path name starts with a letter and a colon it is either a volume |
| @@ -35209,28 +35322,33 @@ | |
| 35209 | ){ |
| 35210 | |
| 35211 | #if defined(__CYGWIN__) |
| 35212 | SimulateIOError( return SQLITE_ERROR ); |
| 35213 | UNUSED_PARAMETER(nFull); |
| 35214 | assert( pVfs->mxPathname>=SQLITE_WIN32_MAX_PATH ); |
| 35215 | assert( nFull>=pVfs->mxPathname ); |
| 35216 | if ( sqlite3_data_directory && !winIsVerbatimPathname(zRelative) ){ |
| 35217 | /* |
| 35218 | ** NOTE: We are dealing with a relative path name and the data |
| 35219 | ** directory has been set. Therefore, use it as the basis |
| 35220 | ** for converting the relative path name to an absolute |
| 35221 | ** one by prepending the data directory and a slash. |
| 35222 | */ |
| 35223 | char zOut[SQLITE_WIN32_MAX_PATH+1]; |
| 35224 | 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; |
| 35229 | } |
| 35230 | sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s\\%s", |
| 35231 | sqlite3_data_directory, zOut); |
| 35232 | }else{ |
| 35233 | 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; |
| @@ -35248,12 +35366,12 @@ | |
| 35248 | ** NOTE: We are dealing with a relative path name and the data |
| 35249 | ** directory has been set. Therefore, use it as the basis |
| 35250 | ** for converting the relative path name to an absolute |
| 35251 | ** one by prepending the data directory and a backslash. |
| 35252 | */ |
| 35253 | sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s\\%s", |
| 35254 | sqlite3_data_directory, zRelative); |
| 35255 | }else{ |
| 35256 | sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zRelative); |
| 35257 | } |
| 35258 | return SQLITE_OK; |
| 35259 | #endif |
| @@ -35281,19 +35399,19 @@ | |
| 35281 | ** NOTE: We are dealing with a relative path name and the data |
| 35282 | ** directory has been set. Therefore, use it as the basis |
| 35283 | ** for converting the relative path name to an absolute |
| 35284 | ** one by prepending the data directory and a backslash. |
| 35285 | */ |
| 35286 | sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s\\%s", |
| 35287 | sqlite3_data_directory, zRelative); |
| 35288 | return SQLITE_OK; |
| 35289 | } |
| 35290 | zConverted = convertUtf8Filename(zRelative); |
| 35291 | if( zConverted==0 ){ |
| 35292 | return SQLITE_IOERR_NOMEM; |
| 35293 | } |
| 35294 | if( isNT() ){ |
| 35295 | LPWSTR zTemp; |
| 35296 | nByte = osGetFullPathNameW((LPCWSTR)zConverted, 0, 0, 0); |
| 35297 | if( nByte==0 ){ |
| 35298 | winLogError(SQLITE_ERROR, osGetLastError(), |
| 35299 | "GetFullPathNameW1", zConverted); |
| @@ -35313,11 +35431,11 @@ | |
| 35313 | sqlite3_free(zConverted); |
| 35314 | sqlite3_free(zTemp); |
| 35315 | return SQLITE_CANTOPEN_FULLPATH; |
| 35316 | } |
| 35317 | sqlite3_free(zConverted); |
| 35318 | zOut = unicodeToUtf8(zTemp); |
| 35319 | sqlite3_free(zTemp); |
| 35320 | } |
| 35321 | #ifdef SQLITE_WIN32_HAS_ANSI |
| 35322 | else{ |
| 35323 | char *zTemp; |
| @@ -35366,16 +35484,16 @@ | |
| 35366 | ** Interfaces for opening a shared library, finding entry points |
| 35367 | ** within the shared library, and closing the shared library. |
| 35368 | */ |
| 35369 | static void *winDlOpen(sqlite3_vfs *pVfs, const char *zFilename){ |
| 35370 | HANDLE h; |
| 35371 | void *zConverted = convertUtf8Filename(zFilename); |
| 35372 | UNUSED_PARAMETER(pVfs); |
| 35373 | if( zConverted==0 ){ |
| 35374 | return 0; |
| 35375 | } |
| 35376 | if( isNT() ){ |
| 35377 | #if SQLITE_OS_WINRT |
| 35378 | h = osLoadPackagedLibrary((LPCWSTR)zConverted, 0); |
| 35379 | #else |
| 35380 | h = osLoadLibraryW((LPCWSTR)zConverted); |
| 35381 | #endif |
| @@ -35388,11 +35506,11 @@ | |
| 35388 | sqlite3_free(zConverted); |
| 35389 | return (void*)h; |
| 35390 | } |
| 35391 | static void winDlError(sqlite3_vfs *pVfs, int nBuf, char *zBufOut){ |
| 35392 | UNUSED_PARAMETER(pVfs); |
| 35393 | getLastErrorMsg(osGetLastError(), nBuf, zBufOut); |
| 35394 | } |
| 35395 | static void (*winDlSym(sqlite3_vfs *pVfs,void *pH,const char *zSym))(void){ |
| 35396 | UNUSED_PARAMETER(pVfs); |
| 35397 | return (void(*)(void))osGetProcAddressA((HANDLE)pH, zSym); |
| 35398 | } |
| @@ -35564,21 +35682,21 @@ | |
| 35564 | ** by sqlite into the error message available to the user using |
| 35565 | ** sqlite3_errmsg(), possibly making IO errors easier to debug. |
| 35566 | */ |
| 35567 | static int winGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){ |
| 35568 | UNUSED_PARAMETER(pVfs); |
| 35569 | return getLastErrorMsg(osGetLastError(), nBuf, zBuf); |
| 35570 | } |
| 35571 | |
| 35572 | /* |
| 35573 | ** Initialize and deinitialize the operating system interface. |
| 35574 | */ |
| 35575 | SQLITE_API int sqlite3_os_init(void){ |
| 35576 | static sqlite3_vfs winVfs = { |
| 35577 | 3, /* iVersion */ |
| 35578 | sizeof(winFile), /* szOsFile */ |
| 35579 | SQLITE_WIN32_MAX_PATH, /* mxPathname */ |
| 35580 | 0, /* pNext */ |
| 35581 | "win32", /* zName */ |
| 35582 | 0, /* pAppData */ |
| 35583 | winOpen, /* xOpen */ |
| 35584 | winDelete, /* xDelete */ |
| @@ -35595,10 +35713,36 @@ | |
| 35595 | winCurrentTimeInt64, /* xCurrentTimeInt64 */ |
| 35596 | winSetSystemCall, /* xSetSystemCall */ |
| 35597 | winGetSystemCall, /* xGetSystemCall */ |
| 35598 | winNextSystemCall, /* xNextSystemCall */ |
| 35599 | }; |
| 35600 | |
| 35601 | /* Double-check that the aSyscall[] array has been constructed |
| 35602 | ** correctly. See ticket [bb3a86e890c8e96ab] */ |
| 35603 | assert( ArraySize(aSyscall)==74 ); |
| 35604 | |
| @@ -35611,10 +35755,15 @@ | |
| 35611 | #endif |
| 35612 | assert( winSysInfo.dwAllocationGranularity>0 ); |
| 35613 | assert( winSysInfo.dwPageSize>0 ); |
| 35614 | |
| 35615 | sqlite3_vfs_register(&winVfs, 1); |
| 35616 | return SQLITE_OK; |
| 35617 | } |
| 35618 | |
| 35619 | SQLITE_API int sqlite3_os_end(void){ |
| 35620 | #if SQLITE_OS_WINRT |
| @@ -52086,10 +52235,11 @@ | |
| 52086 | pBt->max1bytePayload = (u8)pBt->maxLocal; |
| 52087 | } |
| 52088 | assert( pBt->maxLeaf + 23 <= MX_CELL_SIZE(pBt) ); |
| 52089 | pBt->pPage1 = pPage1; |
| 52090 | pBt->nPage = nPage; |
| 52091 | return SQLITE_OK; |
| 52092 | |
| 52093 | page1_init_failed: |
| 52094 | releasePage(pPage1); |
| 52095 | pBt->pPage1 = 0; |
| @@ -59838,43 +59988,108 @@ | |
| 59838 | } |
| 59839 | return p; |
| 59840 | } |
| 59841 | |
| 59842 | /* |
| 59843 | ** Create a new sqlite3_value object, containing the value of pExpr. |
| 59844 | ** |
| 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. |
| 59851 | */ |
| 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 */ |
| 59858 | ){ |
| 59859 | int op; |
| 59860 | char *zVal = 0; |
| 59861 | sqlite3_value *pVal = 0; |
| 59862 | int negInt = 1; |
| 59863 | const char *zNeg = ""; |
| 59864 | |
| 59865 | if( !pExpr ){ |
| 59866 | *ppVal = 0; |
| 59867 | return SQLITE_OK; |
| 59868 | } |
| 59869 | op = pExpr->op; |
| 59870 | |
| 59871 | /* op can only be TK_REGISTER if we have compiled with SQLITE_ENABLE_STAT3. |
| 59872 | ** The ifdef here is to enable us to achieve 100% branch test coverage even |
| 59873 | ** when SQLITE_ENABLE_STAT3 is omitted. |
| 59874 | */ |
| 59875 | #ifdef SQLITE_ENABLE_STAT3 |
| 59876 | if( op==TK_REGISTER ) op = pExpr->op2; |
| 59877 | #else |
| 59878 | if( NEVER(op==TK_REGISTER) ) op = pExpr->op2; |
| 59879 | #endif |
| 59880 | |
| @@ -59888,11 +60103,11 @@ | |
| 59888 | negInt = -1; |
| 59889 | zNeg = "-"; |
| 59890 | } |
| 59891 | |
| 59892 | if( op==TK_STRING || op==TK_FLOAT || op==TK_INTEGER ){ |
| 59893 | pVal = sqlite3ValueNew(db); |
| 59894 | if( pVal==0 ) goto no_mem; |
| 59895 | if( ExprHasProperty(pExpr, EP_IntValue) ){ |
| 59896 | sqlite3VdbeMemSetInt64(pVal, (i64)pExpr->u.iValue*negInt); |
| 59897 | }else{ |
| 59898 | zVal = sqlite3MPrintf(db, "%s%s", zNeg, pExpr->u.zToken); |
| @@ -59905,15 +60120,17 @@ | |
| 59905 | }else{ |
| 59906 | sqlite3ValueApplyAffinity(pVal, affinity, SQLITE_UTF8); |
| 59907 | } |
| 59908 | if( pVal->flags & (MEM_Int|MEM_Real) ) pVal->flags &= ~MEM_Str; |
| 59909 | if( enc!=SQLITE_UTF8 ){ |
| 59910 | sqlite3VdbeChangeEncoding(pVal, enc); |
| 59911 | } |
| 59912 | }else if( op==TK_UMINUS ) { |
| 59913 | /* This branch happens for multiple negative signs. Ex: -(-5) */ |
| 59914 | if( SQLITE_OK==sqlite3ValueFromExpr(db,pExpr->pLeft,enc,affinity,&pVal) ){ |
| 59915 | sqlite3VdbeMemNumerify(pVal); |
| 59916 | if( pVal->u.i==SMALLEST_INT64 ){ |
| 59917 | pVal->flags &= MEM_Int; |
| 59918 | pVal->flags |= MEM_Real; |
| 59919 | pVal->r = (double)LARGEST_INT64; |
| @@ -59922,19 +60139,19 @@ | |
| 59922 | } |
| 59923 | pVal->r = -pVal->r; |
| 59924 | sqlite3ValueApplyAffinity(pVal, affinity, enc); |
| 59925 | } |
| 59926 | }else if( op==TK_NULL ){ |
| 59927 | pVal = sqlite3ValueNew(db); |
| 59928 | if( pVal==0 ) goto no_mem; |
| 59929 | } |
| 59930 | #ifndef SQLITE_OMIT_BLOB_LITERAL |
| 59931 | else if( op==TK_BLOB ){ |
| 59932 | int nVal; |
| 59933 | assert( pExpr->u.zToken[0]=='x' || pExpr->u.zToken[0]=='X' ); |
| 59934 | assert( pExpr->u.zToken[1]=='\'' ); |
| 59935 | pVal = sqlite3ValueNew(db); |
| 59936 | if( !pVal ) goto no_mem; |
| 59937 | zVal = &pExpr->u.zToken[2]; |
| 59938 | nVal = sqlite3Strlen30(zVal)-1; |
| 59939 | assert( zVal[nVal]=='\'' ); |
| 59940 | sqlite3VdbeMemSetStr(pVal, sqlite3HexToBlob(db, zVal, nVal), nVal/2, |
| @@ -59944,20 +60161,203 @@ | |
| 59944 | |
| 59945 | if( pVal ){ |
| 59946 | sqlite3VdbeMemStoreType(pVal); |
| 59947 | } |
| 59948 | *ppVal = pVal; |
| 59949 | return SQLITE_OK; |
| 59950 | |
| 59951 | no_mem: |
| 59952 | db->mallocFailed = 1; |
| 59953 | sqlite3DbFree(db, zVal); |
| 59954 | sqlite3ValueFree(pVal); |
| 59955 | *ppVal = 0; |
| 59956 | return SQLITE_NOMEM; |
| 59957 | } |
| 59958 | |
| 59959 | /* |
| 59960 | ** Change the string value of an sqlite3_value object |
| 59961 | */ |
| 59962 | SQLITE_PRIVATE void sqlite3ValueSetStr( |
| 59963 | sqlite3_value *v, /* Value to be set */ |
| @@ -66073,11 +66473,11 @@ | |
| 66073 | ** value or convert mem[p2] to a different type. |
| 66074 | */ |
| 66075 | assert( pOp->opflags==sqlite3OpcodeProperty[pOp->opcode] ); |
| 66076 | if( pOp->opflags & OPFLG_OUT2_PRERELEASE ){ |
| 66077 | assert( pOp->p2>0 ); |
| 66078 | assert( pOp->p2<=p->nMem ); |
| 66079 | pOut = &aMem[pOp->p2]; |
| 66080 | memAboutToChange(p, pOut); |
| 66081 | VdbeMemRelease(pOut); |
| 66082 | pOut->flags = MEM_Int; |
| 66083 | } |
| @@ -66084,34 +66484,34 @@ | |
| 66084 | |
| 66085 | /* Sanity checking on other operands */ |
| 66086 | #ifdef SQLITE_DEBUG |
| 66087 | if( (pOp->opflags & OPFLG_IN1)!=0 ){ |
| 66088 | assert( pOp->p1>0 ); |
| 66089 | assert( pOp->p1<=p->nMem ); |
| 66090 | assert( memIsValid(&aMem[pOp->p1]) ); |
| 66091 | REGISTER_TRACE(pOp->p1, &aMem[pOp->p1]); |
| 66092 | } |
| 66093 | if( (pOp->opflags & OPFLG_IN2)!=0 ){ |
| 66094 | assert( pOp->p2>0 ); |
| 66095 | assert( pOp->p2<=p->nMem ); |
| 66096 | assert( memIsValid(&aMem[pOp->p2]) ); |
| 66097 | REGISTER_TRACE(pOp->p2, &aMem[pOp->p2]); |
| 66098 | } |
| 66099 | if( (pOp->opflags & OPFLG_IN3)!=0 ){ |
| 66100 | assert( pOp->p3>0 ); |
| 66101 | assert( pOp->p3<=p->nMem ); |
| 66102 | assert( memIsValid(&aMem[pOp->p3]) ); |
| 66103 | REGISTER_TRACE(pOp->p3, &aMem[pOp->p3]); |
| 66104 | } |
| 66105 | if( (pOp->opflags & OPFLG_OUT2)!=0 ){ |
| 66106 | assert( pOp->p2>0 ); |
| 66107 | assert( pOp->p2<=p->nMem ); |
| 66108 | memAboutToChange(p, &aMem[pOp->p2]); |
| 66109 | } |
| 66110 | if( (pOp->opflags & OPFLG_OUT3)!=0 ){ |
| 66111 | assert( pOp->p3>0 ); |
| 66112 | assert( pOp->p3<=p->nMem ); |
| 66113 | memAboutToChange(p, &aMem[pOp->p3]); |
| 66114 | } |
| 66115 | #endif |
| 66116 | |
| 66117 | switch( pOp->opcode ){ |
| @@ -66200,11 +66600,11 @@ | |
| 66200 | ** |
| 66201 | ** Write the current address onto register P1 |
| 66202 | ** and then jump to address P2. |
| 66203 | */ |
| 66204 | case OP_Gosub: { /* jump */ |
| 66205 | assert( pOp->p1>0 && pOp->p1<=p->nMem ); |
| 66206 | pIn1 = &aMem[pOp->p1]; |
| 66207 | assert( (pIn1->flags & MEM_Dyn)==0 ); |
| 66208 | memAboutToChange(p, pIn1); |
| 66209 | pIn1->flags = MEM_Int; |
| 66210 | pIn1->u.i = pc; |
| @@ -66416,11 +66816,11 @@ | |
| 66416 | #if 0 /* local variables moved into u.ab */ |
| 66417 | int cnt; |
| 66418 | u16 nullFlag; |
| 66419 | #endif /* local variables moved into u.ab */ |
| 66420 | u.ab.cnt = pOp->p3-pOp->p2; |
| 66421 | assert( pOp->p3<=p->nMem ); |
| 66422 | pOut->flags = u.ab.nullFlag = pOp->p1 ? (MEM_Null|MEM_Cleared) : MEM_Null; |
| 66423 | while( u.ab.cnt>0 ){ |
| 66424 | pOut++; |
| 66425 | memAboutToChange(p, pOut); |
| 66426 | VdbeMemRelease(pOut); |
| @@ -66489,12 +66889,12 @@ | |
| 66489 | assert( u.ad.p1+u.ad.n<=u.ad.p2 || u.ad.p2+u.ad.n<=u.ad.p1 ); |
| 66490 | |
| 66491 | pIn1 = &aMem[u.ad.p1]; |
| 66492 | pOut = &aMem[u.ad.p2]; |
| 66493 | while( u.ad.n-- ){ |
| 66494 | assert( pOut<=&aMem[p->nMem] ); |
| 66495 | assert( pIn1<=&aMem[p->nMem] ); |
| 66496 | assert( memIsValid(pIn1) ); |
| 66497 | memAboutToChange(p, pOut); |
| 66498 | u.ad.zMalloc = pOut->zMalloc; |
| 66499 | pOut->zMalloc = 0; |
| 66500 | sqlite3VdbeMemMove(pOut, pIn1); |
| @@ -66578,11 +66978,11 @@ | |
| 66578 | Mem *pMem; |
| 66579 | int i; |
| 66580 | #endif /* local variables moved into u.af */ |
| 66581 | assert( p->nResColumn==pOp->p2 ); |
| 66582 | assert( pOp->p1>0 ); |
| 66583 | assert( pOp->p1+pOp->p2<=p->nMem+1 ); |
| 66584 | |
| 66585 | /* If this statement has violated immediate foreign key constraints, do |
| 66586 | ** not return the number of rows modified. And do not RELEASE the statement |
| 66587 | ** transaction. It needs to be rolled back. */ |
| 66588 | if( SQLITE_OK!=(rc = sqlite3VdbeCheckFk(p, 0)) ){ |
| @@ -66858,15 +67258,15 @@ | |
| 66858 | #endif /* local variables moved into u.ai */ |
| 66859 | |
| 66860 | u.ai.n = pOp->p5; |
| 66861 | u.ai.apVal = p->apArg; |
| 66862 | assert( u.ai.apVal || u.ai.n==0 ); |
| 66863 | assert( pOp->p3>0 && pOp->p3<=p->nMem ); |
| 66864 | pOut = &aMem[pOp->p3]; |
| 66865 | memAboutToChange(p, pOut); |
| 66866 | |
| 66867 | assert( u.ai.n==0 || (pOp->p2>0 && pOp->p2+u.ai.n<=p->nMem+1) ); |
| 66868 | assert( pOp->p3<pOp->p2 || pOp->p3>=pOp->p2+u.ai.n ); |
| 66869 | u.ai.pArg = &aMem[pOp->p2]; |
| 66870 | for(u.ai.i=0; u.ai.i<u.ai.n; u.ai.i++, u.ai.pArg++){ |
| 66871 | assert( memIsValid(u.ai.pArg) ); |
| 66872 | u.ai.apVal[u.ai.i] = u.ai.pArg; |
| @@ -67398,15 +67798,15 @@ | |
| 67398 | u.al.p2 = pOp->p2; |
| 67399 | #if SQLITE_DEBUG |
| 67400 | if( aPermute ){ |
| 67401 | int k, mx = 0; |
| 67402 | 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 ); |
| 67405 | }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 ); |
| 67408 | } |
| 67409 | #endif /* SQLITE_DEBUG */ |
| 67410 | for(u.al.i=0; u.al.i<u.al.n; u.al.i++){ |
| 67411 | u.al.idx = aPermute ? aPermute[u.al.i] : u.al.i; |
| 67412 | assert( memIsValid(&aMem[u.al.p1+u.al.idx]) ); |
| @@ -67659,11 +68059,11 @@ | |
| 67659 | u.ao.p1 = pOp->p1; |
| 67660 | u.ao.p2 = pOp->p2; |
| 67661 | u.ao.pC = 0; |
| 67662 | memset(&u.ao.sMem, 0, sizeof(u.ao.sMem)); |
| 67663 | assert( u.ao.p1<p->nCursor ); |
| 67664 | assert( pOp->p3>0 && pOp->p3<=p->nMem ); |
| 67665 | u.ao.pDest = &aMem[pOp->p3]; |
| 67666 | memAboutToChange(p, u.ao.pDest); |
| 67667 | u.ao.zRec = 0; |
| 67668 | |
| 67669 | /* This block sets the variable u.ao.payloadSize to be the total number of |
| @@ -67959,11 +68359,11 @@ | |
| 67959 | u.ap.zAffinity = pOp->p4.z; |
| 67960 | assert( u.ap.zAffinity!=0 ); |
| 67961 | assert( u.ap.zAffinity[pOp->p2]==0 ); |
| 67962 | pIn1 = &aMem[pOp->p1]; |
| 67963 | while( (u.ap.cAff = *(u.ap.zAffinity++))!=0 ){ |
| 67964 | assert( pIn1 <= &p->aMem[p->nMem] ); |
| 67965 | assert( memIsValid(pIn1) ); |
| 67966 | ExpandBlob(pIn1); |
| 67967 | applyAffinity(pIn1, u.ap.cAff, encoding); |
| 67968 | pIn1++; |
| 67969 | } |
| @@ -68022,11 +68422,11 @@ | |
| 68022 | u.aq.nData = 0; /* Number of bytes of data space */ |
| 68023 | u.aq.nHdr = 0; /* Number of bytes of header space */ |
| 68024 | u.aq.nZero = 0; /* Number of zero bytes at the end of the record */ |
| 68025 | u.aq.nField = pOp->p1; |
| 68026 | u.aq.zAffinity = pOp->p4.z; |
| 68027 | assert( u.aq.nField>0 && pOp->p2>0 && pOp->p2+u.aq.nField<=p->nMem+1 ); |
| 68028 | u.aq.pData0 = &aMem[u.aq.nField]; |
| 68029 | u.aq.nField = pOp->p2; |
| 68030 | u.aq.pLast = &u.aq.pData0[u.aq.nField-1]; |
| 68031 | u.aq.file_format = p->minWriteFileFormat; |
| 68032 | |
| @@ -68088,11 +68488,11 @@ | |
| 68088 | for(u.aq.pRec=u.aq.pData0; u.aq.pRec<=u.aq.pLast; u.aq.pRec++){ /* serial data */ |
| 68089 | 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 | } |
| 68091 | assert( u.aq.i==u.aq.nByte ); |
| 68092 | |
| 68093 | assert( pOp->p3>0 && pOp->p3<=p->nMem ); |
| 68094 | pOut->n = (int)u.aq.nByte; |
| 68095 | pOut->flags = MEM_Blob | MEM_Dyn; |
| 68096 | pOut->xDel = 0; |
| 68097 | if( u.aq.nZero ){ |
| 68098 | pOut->u.nZero = u.aq.nZero; |
| @@ -68684,11 +69084,11 @@ | |
| 68684 | }else{ |
| 68685 | u.ay.wrFlag = 0; |
| 68686 | } |
| 68687 | if( pOp->p5 & OPFLAG_P2ISREG ){ |
| 68688 | assert( u.ay.p2>0 ); |
| 68689 | assert( u.ay.p2<=p->nMem ); |
| 68690 | pIn2 = &aMem[u.ay.p2]; |
| 68691 | assert( memIsValid(pIn2) ); |
| 68692 | assert( (pIn2->flags & MEM_Int)!=0 ); |
| 68693 | sqlite3VdbeMemIntegerify(pIn2); |
| 68694 | u.ay.p2 = (int)pIn2->u.i; |
| @@ -69235,11 +69635,11 @@ | |
| 69235 | |
| 69236 | pIn3 = &aMem[pOp->p3]; |
| 69237 | u.bf.aMx = &aMem[pOp->p4.i]; |
| 69238 | /* Assert that the values of parameters P1 and P4 are in range. */ |
| 69239 | assert( pOp->p4type==P4_INT32 ); |
| 69240 | assert( pOp->p4.i>0 && pOp->p4.i<=p->nMem ); |
| 69241 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 69242 | |
| 69243 | /* Find the index cursor. */ |
| 69244 | u.bf.pCx = p->apCsr[pOp->p1]; |
| 69245 | assert( u.bf.pCx->deferredMoveto==0 ); |
| @@ -69442,11 +69842,11 @@ | |
| 69442 | /* Assert that P3 is a valid memory cell. */ |
| 69443 | assert( pOp->p3<=u.bh.pFrame->nMem ); |
| 69444 | u.bh.pMem = &u.bh.pFrame->aMem[pOp->p3]; |
| 69445 | }else{ |
| 69446 | /* Assert that P3 is a valid memory cell. */ |
| 69447 | assert( pOp->p3<=p->nMem ); |
| 69448 | u.bh.pMem = &aMem[pOp->p3]; |
| 69449 | memAboutToChange(p, u.bh.pMem); |
| 69450 | } |
| 69451 | assert( memIsValid(u.bh.pMem) ); |
| 69452 | |
| @@ -70120,11 +70520,11 @@ | |
| 70120 | int res; |
| 70121 | UnpackedRecord r; |
| 70122 | #endif /* local variables moved into u.bt */ |
| 70123 | |
| 70124 | assert( pOp->p3>0 ); |
| 70125 | assert( pOp->p2>0 && pOp->p2+pOp->p3<=p->nMem+1 ); |
| 70126 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 70127 | u.bt.pC = p->apCsr[pOp->p1]; |
| 70128 | assert( u.bt.pC!=0 ); |
| 70129 | u.bt.pCrsr = u.bt.pC->pCursor; |
| 70130 | if( ALWAYS(u.bt.pCrsr!=0) ){ |
| @@ -70336,10 +70736,11 @@ | |
| 70336 | int nChange; |
| 70337 | #endif /* local variables moved into u.bx */ |
| 70338 | |
| 70339 | u.bx.nChange = 0; |
| 70340 | assert( p->readOnly==0 ); |
| 70341 | assert( (p->btreeMask & (((yDbMask)1)<<pOp->p2))!=0 ); |
| 70342 | rc = sqlite3BtreeClearTable( |
| 70343 | db->aDb[pOp->p2].pBt, pOp->p1, (pOp->p3 ? &u.bx.nChange : 0) |
| 70344 | ); |
| 70345 | if( pOp->p3 ){ |
| @@ -70542,11 +70943,11 @@ | |
| 70542 | assert( p->bIsReader ); |
| 70543 | u.ca.nRoot = pOp->p2; |
| 70544 | assert( u.ca.nRoot>0 ); |
| 70545 | u.ca.aRoot = sqlite3DbMallocRaw(db, sizeof(int)*(u.ca.nRoot+1) ); |
| 70546 | if( u.ca.aRoot==0 ) goto no_mem; |
| 70547 | assert( pOp->p3>0 && pOp->p3<=p->nMem ); |
| 70548 | u.ca.pnErr = &aMem[pOp->p3]; |
| 70549 | assert( (u.ca.pnErr->flags & MEM_Int)!=0 ); |
| 70550 | assert( (u.ca.pnErr->flags & (MEM_Str|MEM_Blob))==0 ); |
| 70551 | pIn1 = &aMem[pOp->p1]; |
| 70552 | for(u.ca.j=0; u.ca.j<u.ca.nRoot; u.ca.j++){ |
| @@ -70978,11 +71379,11 @@ | |
| 70978 | u.cg.apVal[u.cg.i] = u.cg.pRec; |
| 70979 | memAboutToChange(p, u.cg.pRec); |
| 70980 | sqlite3VdbeMemStoreType(u.cg.pRec); |
| 70981 | } |
| 70982 | u.cg.ctx.pFunc = pOp->p4.pFunc; |
| 70983 | assert( pOp->p3>0 && pOp->p3<=p->nMem ); |
| 70984 | u.cg.ctx.pMem = u.cg.pMem = &aMem[pOp->p3]; |
| 70985 | u.cg.pMem->n++; |
| 70986 | u.cg.ctx.s.flags = MEM_Null; |
| 70987 | u.cg.ctx.s.z = 0; |
| 70988 | u.cg.ctx.s.zMalloc = 0; |
| @@ -71027,11 +71428,11 @@ | |
| 71027 | */ |
| 71028 | case OP_AggFinal: { |
| 71029 | #if 0 /* local variables moved into u.ch */ |
| 71030 | Mem *pMem; |
| 71031 | #endif /* local variables moved into u.ch */ |
| 71032 | assert( pOp->p1>0 && pOp->p1<=p->nMem ); |
| 71033 | u.ch.pMem = &aMem[pOp->p1]; |
| 71034 | assert( (u.ch.pMem->flags & ~(MEM_Null|MEM_Agg))==0 ); |
| 71035 | rc = sqlite3VdbeMemFinalize(u.ch.pMem, pOp->p4.pFunc); |
| 71036 | if( rc ){ |
| 71037 | sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(u.ch.pMem)); |
| @@ -71458,11 +71859,11 @@ | |
| 71458 | sqlite3_context sContext; |
| 71459 | #endif /* local variables moved into u.co */ |
| 71460 | |
| 71461 | VdbeCursor *pCur = p->apCsr[pOp->p1]; |
| 71462 | assert( pCur->pVtabCursor ); |
| 71463 | assert( pOp->p3>0 && pOp->p3<=p->nMem ); |
| 71464 | u.co.pDest = &aMem[pOp->p3]; |
| 71465 | memAboutToChange(p, u.co.pDest); |
| 71466 | if( pCur->nullRow ){ |
| 71467 | sqlite3VdbeMemSetNull(u.co.pDest); |
| 71468 | break; |
| @@ -76729,11 +77130,11 @@ | |
| 76729 | break; |
| 76730 | } |
| 76731 | case TK_UMINUS: { |
| 76732 | int v; |
| 76733 | if( sqlite3ExprIsInteger(p->pLeft, &v) ){ |
| 76734 | assert( v!=-2147483648 ); |
| 76735 | *pValue = -v; |
| 76736 | rc = 1; |
| 76737 | } |
| 76738 | break; |
| 76739 | } |
| @@ -80389,11 +80790,11 @@ | |
| 80389 | |
| 80390 | /* Ensure the default expression is something that sqlite3ValueFromExpr() |
| 80391 | ** can handle (i.e. not CURRENT_TIME etc.) |
| 80392 | */ |
| 80393 | if( pDflt ){ |
| 80394 | sqlite3_value *pVal; |
| 80395 | if( sqlite3ValueFromExpr(db, pDflt, SQLITE_UTF8, SQLITE_AFF_NONE, &pVal) ){ |
| 80396 | db->mallocFailed = 1; |
| 80397 | return; |
| 80398 | } |
| 80399 | if( !pVal ){ |
| @@ -80530,11 +80931,11 @@ | |
| 80530 | #endif /* SQLITE_ALTER_TABLE */ |
| 80531 | |
| 80532 | /************** End of alter.c ***********************************************/ |
| 80533 | /************** Begin file analyze.c *****************************************/ |
| 80534 | /* |
| 80535 | ** 2005 July 8 |
| 80536 | ** |
| 80537 | ** The author disclaims copyright to this source code. In place of |
| 80538 | ** a legal notice, here is a blessing: |
| 80539 | ** |
| 80540 | ** May you do good and not evil. |
| @@ -80551,27 +80952,36 @@ | |
| 80551 | ** The following system tables are or have been supported: |
| 80552 | ** |
| 80553 | ** CREATE TABLE sqlite_stat1(tbl, idx, stat); |
| 80554 | ** CREATE TABLE sqlite_stat2(tbl, idx, sampleno, sample); |
| 80555 | ** CREATE TABLE sqlite_stat3(tbl, idx, nEq, nLt, nDLt, sample); |
| 80556 | ** |
| 80557 | ** Additional tables might be added in future releases of SQLite. |
| 80558 | ** The sqlite_stat2 table is not created or used unless the SQLite version |
| 80559 | ** is between 3.6.18 and 3.7.8, inclusive, and unless SQLite is compiled |
| 80560 | ** with SQLITE_ENABLE_STAT2. The sqlite_stat2 table is deprecated. |
| 80561 | ** The sqlite_stat2 table is superseded by sqlite_stat3, which is only |
| 80562 | ** 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. |
| 80565 | ** |
| 80566 | ** Format of sqlite_stat1: |
| 80567 | ** |
| 80568 | ** There is normally one row per index, with the index identified by the |
| 80569 | ** name in the idx column. The tbl column is the name of the table to |
| 80570 | ** which the index belongs. In each such row, the stat column will be |
| 80571 | ** 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 |
| 80573 | ** integer is the average number of rows in the index that have the same |
| 80574 | ** value in the first column of the index. The third integer is the average |
| 80575 | ** number of rows in the index that have the same value for the first two |
| 80576 | ** columns. The N-th integer (for N>1) is the average number of rows in |
| 80577 | ** the index which have the same value for the first N-1 columns. For |
| @@ -80614,57 +81024,85 @@ | |
| 80614 | ** writes the sqlite_stat2 table. This version of SQLite only supports |
| 80615 | ** sqlite_stat3. |
| 80616 | ** |
| 80617 | ** Format for sqlite_stat3: |
| 80618 | ** |
| 80619 | ** The sqlite_stat3 is an enhancement to sqlite_stat2. A new name is |
| 80620 | ** used to avoid compatibility problems. |
| 80621 | ** |
| 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. |
| 80624 | ** The idx column names the index and the tbl column is the table of the |
| 80625 | ** 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 |
| 80645 | ** that contain between 10 and 40 samples which are distributed across |
| 80646 | ** the key space, though not uniformly, and which include samples with |
| 80647 | ** largest possible nEq values. |
| 80648 | */ |
| 80649 | #ifndef SQLITE_OMIT_ANALYZE |
| 80650 | |
| 80651 | /* |
| 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) |
| 80656 | ** |
| 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. |
| 80660 | ** |
| 80661 | ** Argument zWhere may be a pointer to a buffer containing a table name, |
| 80662 | ** 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. |
| 80666 | */ |
| 80667 | static void openStatTable( |
| 80668 | Parse *pParse, /* Parsing context */ |
| 80669 | int iDb, /* The database we are looking in */ |
| 80670 | int iStatCur, /* Open the sqlite_stat1 table on this cursor */ |
| @@ -80674,22 +81112,28 @@ | |
| 80674 | static const struct { |
| 80675 | const char *zName; |
| 80676 | const char *zCols; |
| 80677 | } aTable[] = { |
| 80678 | { "sqlite_stat1", "tbl,idx,stat" }, |
| 80679 | #ifdef SQLITE_ENABLE_STAT3 |
| 80680 | { "sqlite_stat3", "tbl,idx,neq,nlt,ndlt,sample" }, |
| 80681 | #endif |
| 80682 | }; |
| 80683 | |
| 80684 | int aRoot[] = {0, 0}; |
| 80685 | u8 aCreateTbl[] = {0, 0}; |
| 80686 | |
| 80687 | int i; |
| 80688 | sqlite3 *db = pParse->db; |
| 80689 | Db *pDb; |
| 80690 | Vdbe *v = sqlite3GetVdbe(pParse); |
| 80691 | if( v==0 ) return; |
| 80692 | assert( sqlite3BtreeHoldsAllMutexes(db) ); |
| 80693 | assert( sqlite3VdbeDb(v)==db ); |
| 80694 | pDb = &db->aDb[iDb]; |
| 80695 | |
| @@ -80698,262 +81142,592 @@ | |
| 80698 | */ |
| 80699 | for(i=0; i<ArraySize(aTable); i++){ |
| 80700 | const char *zTab = aTable[i].zName; |
| 80701 | Table *pStat; |
| 80702 | 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; |
| 80712 | }else{ |
| 80713 | /* The table already exists. If zWhere is not NULL, delete all entries |
| 80714 | ** associated with the table zWhere. If zWhere is NULL, delete the |
| 80715 | ** entire contents of the table. */ |
| 80716 | aRoot[i] = pStat->tnum; |
| 80717 | sqlite3TableLock(pParse, iDb, aRoot[i], 1, zTab); |
| 80718 | if( zWhere ){ |
| 80719 | sqlite3NestedParse(pParse, |
| 80720 | "DELETE FROM %Q.%s WHERE %s=%Q", pDb->zName, zTab, zWhereType, zWhere |
| 80721 | ); |
| 80722 | }else{ |
| 80723 | /* The sqlite_stat[12] table already exists. Delete all rows. */ |
| 80724 | sqlite3VdbeAddOp2(v, OP_Clear, aRoot[i], iDb); |
| 80725 | } |
| 80726 | } |
| 80727 | } |
| 80728 | |
| 80729 | /* Open the sqlite_stat[13] tables for writing. */ |
| 80730 | for(i=0; i<ArraySize(aTable); i++){ |
| 80731 | sqlite3VdbeAddOp3(v, OP_OpenWrite, iStatCur+i, aRoot[i], iDb); |
| 80732 | sqlite3VdbeChangeP4(v, -1, (char *)3, P4_INT32); |
| 80733 | sqlite3VdbeChangeP5(v, aCreateTbl[i]); |
| 80734 | } |
| 80735 | } |
| 80736 | |
| 80737 | /* |
| 80738 | ** Recommended number of samples for sqlite_stat3 |
| 80739 | */ |
| 80740 | #ifndef SQLITE_STAT3_SAMPLES |
| 80741 | # define SQLITE_STAT3_SAMPLES 24 |
| 80742 | #endif |
| 80743 | |
| 80744 | /* |
| 80745 | ** Three SQL functions - stat3_init(), stat3_push(), and stat3_pop() - |
| 80746 | ** share an instance of the following structure to hold their state |
| 80747 | ** information. |
| 80748 | */ |
| 80749 | typedef struct Stat3Accum Stat3Accum; |
| 80750 | struct Stat3Accum { |
| 80751 | tRowcnt nRow; /* Number of rows in the entire table */ |
| 80752 | tRowcnt nPSample; /* How often to do a periodic sample */ |
| 80753 | int iMin; /* Index of entry with minimum nEq and hash */ |
| 80754 | int mxSample; /* Maximum number of samples to accumulate */ |
| 80755 | int nSample; /* Current number of samples */ |
| 80756 | 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 */ |
| 80765 | }; |
| 80766 | |
| 80767 | #ifdef SQLITE_ENABLE_STAT3 |
| 80768 | /* |
| 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( |
| 80778 | sqlite3_context *context, |
| 80779 | int argc, |
| 80780 | sqlite3_value **argv |
| 80781 | ){ |
| 80782 | Stat3Accum *p; |
| 80783 | tRowcnt nRow; |
| 80784 | int mxSample; |
| 80785 | int n; |
| 80786 | |
| 80787 | 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 ); |
| 80792 | if( p==0 ){ |
| 80793 | sqlite3_result_error_nomem(context); |
| 80794 | return; |
| 80795 | } |
| 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); |
| 80801 | sqlite3_result_blob(context, p, sizeof(p), sqlite3_free); |
| 80802 | } |
| 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)); |
| 80860 | 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 | } |
| 80893 | p->iMin = iMin; |
| 80894 | } |
| 80895 | } |
| 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( |
| 80922 | sqlite3_context *context, |
| 80923 | int argc, |
| 80924 | sqlite3_value **argv |
| 80925 | ){ |
| 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 | |
| 80955 | |
| 80956 | /* |
| 80957 | ** Generate code to do an analysis of all indices associated with |
| 80958 | ** a single table. |
| 80959 | */ |
| @@ -80960,46 +81734,35 @@ | |
| 80960 | static void analyzeOneTable( |
| 80961 | Parse *pParse, /* Parser context */ |
| 80962 | Table *pTab, /* Table whose indices are to be analyzed */ |
| 80963 | Index *pOnlyIdx, /* If not NULL, only analyze this one index */ |
| 80964 | int iStatCur, /* Index of VdbeCursor that writes the sqlite_stat1 table */ |
| 80965 | int iMem /* Available memory locations begin here */ |
| 80966 | ){ |
| 80967 | sqlite3 *db = pParse->db; /* Database handle */ |
| 80968 | Index *pIdx; /* An index to being analyzed */ |
| 80969 | int iIdxCur; /* Cursor open on index being analyzed */ |
| 80970 | Vdbe *v; /* The virtual machine being built up */ |
| 80971 | int i; /* Loop counter */ |
| 80972 | int topOfLoop; /* The top of the loop */ |
| 80973 | int endOfLoop; /* The end of the loop */ |
| 80974 | int jZeroRows = -1; /* Jump from here if number of rows is zero */ |
| 80975 | int iDb; /* Index of database containing pTab */ |
| 80976 | u8 needTableCnt = 1; /* True to count the table */ |
| 80977 | int regTabname = iMem++; /* Register containing table name */ |
| 80978 | 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 | |
| 81001 | v = sqlite3GetVdbe(pParse); |
| 81002 | if( v==0 || NEVER(pTab==0) ){ |
| 81003 | return; |
| 81004 | } |
| 81005 | if( pTab->tnum==0 ){ |
| @@ -81019,217 +81782,230 @@ | |
| 81019 | db->aDb[iDb].zName ) ){ |
| 81020 | return; |
| 81021 | } |
| 81022 | #endif |
| 81023 | |
| 81024 | /* Establish a read-lock on the table at the shared-cache level. */ |
| 81025 | sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName); |
| 81026 | |
| 81027 | iIdxCur = pParse->nTab++; |
| 81028 | sqlite3VdbeAddOp4(v, OP_String8, 0, regTabname, 0, pTab->zName, 0); |
| 81029 | 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 */ |
| 81034 | |
| 81035 | if( pOnlyIdx && pOnlyIdx!=pIdx ) continue; |
| 81036 | if( pIdx->pPartIdxWhere==0 ) needTableCnt = 0; |
| 81037 | VdbeNoopComment((v, "Begin analysis of %s", pIdx->zName)); |
| 81038 | nCol = pIdx->nColumn; |
| 81039 | aChngAddr = sqlite3DbMallocRaw(db, sizeof(int)*nCol); |
| 81040 | if( aChngAddr==0 ) continue; |
| 81041 | 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 | |
| 81052 | /* Populate the register containing the index name. */ |
| 81053 | sqlite3VdbeAddOp4(v, OP_String8, 0, regIdxname, 0, pIdx->zName, 0); |
| 81054 | |
| 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); |
| 81113 | 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 | } |
| 81213 | |
| 81214 | /* Create a single sqlite_stat1 entry containing NULL as the index |
| 81215 | ** name and the row count as the content. |
| 81216 | */ |
| 81217 | if( pOnlyIdx==0 && needTableCnt ){ |
| 81218 | sqlite3VdbeAddOp3(v, OP_OpenRead, iIdxCur, pTab->tnum, iDb); |
| 81219 | VdbeComment((v, "%s", pTab->zName)); |
| 81220 | sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regStat1); |
| 81221 | sqlite3VdbeAddOp1(v, OP_Close, iIdxCur); |
| 81222 | jZeroRows = sqlite3VdbeAddOp1(v, OP_IfNot, regStat1); |
| 81223 | sqlite3VdbeAddOp2(v, OP_Null, 0, regIdxname); |
| 81224 | sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regRec, "aaa", 0); |
| 81225 | sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid); |
| 81226 | sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regRec, regNewRowid); |
| 81227 | sqlite3VdbeChangeP5(v, OPFLAG_APPEND); |
| 81228 | sqlite3VdbeJumpHere(v, jZeroRows); |
| 81229 | } |
| 81230 | if( pParse->nMem<regRec ) pParse->nMem = regRec; |
| 81231 | } |
| 81232 | |
| 81233 | |
| 81234 | /* |
| 81235 | ** Generate code that will cause the most recent index analysis to |
| @@ -81249,20 +82025,22 @@ | |
| 81249 | sqlite3 *db = pParse->db; |
| 81250 | Schema *pSchema = db->aDb[iDb].pSchema; /* Schema of database iDb */ |
| 81251 | HashElem *k; |
| 81252 | int iStatCur; |
| 81253 | int iMem; |
| 81254 | |
| 81255 | sqlite3BeginWriteOperation(pParse, 0, iDb); |
| 81256 | iStatCur = pParse->nTab; |
| 81257 | pParse->nTab += 3; |
| 81258 | openStatTable(pParse, iDb, iStatCur, 0, 0); |
| 81259 | iMem = pParse->nMem+1; |
| 81260 | assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); |
| 81261 | for(k=sqliteHashFirst(&pSchema->tblHash); k; k=sqliteHashNext(k)){ |
| 81262 | Table *pTab = (Table*)sqliteHashData(k); |
| 81263 | analyzeOneTable(pParse, pTab, 0, iStatCur, iMem); |
| 81264 | } |
| 81265 | loadAnalysis(pParse, iDb); |
| 81266 | } |
| 81267 | |
| 81268 | /* |
| @@ -81283,11 +82061,11 @@ | |
| 81283 | if( pOnlyIdx ){ |
| 81284 | openStatTable(pParse, iDb, iStatCur, pOnlyIdx->zName, "idx"); |
| 81285 | }else{ |
| 81286 | openStatTable(pParse, iDb, iStatCur, pTab->zName, "tbl"); |
| 81287 | } |
| 81288 | analyzeOneTable(pParse, pTab, pOnlyIdx, iStatCur, pParse->nMem+1); |
| 81289 | loadAnalysis(pParse, iDb); |
| 81290 | } |
| 81291 | |
| 81292 | /* |
| 81293 | ** Generate code for the ANALYZE command. The parser calls this routine |
| @@ -81365,10 +82143,47 @@ | |
| 81365 | typedef struct analysisInfo analysisInfo; |
| 81366 | struct analysisInfo { |
| 81367 | sqlite3 *db; |
| 81368 | const char *zDatabase; |
| 81369 | }; |
| 81370 | |
| 81371 | /* |
| 81372 | ** This callback is invoked once for each index when reading the |
| 81373 | ** sqlite_stat1 table. |
| 81374 | ** |
| @@ -81381,12 +82196,10 @@ | |
| 81381 | */ |
| 81382 | static int analysisLoader(void *pData, int argc, char **argv, char **NotUsed){ |
| 81383 | analysisInfo *pInfo = (analysisInfo*)pData; |
| 81384 | Index *pIndex; |
| 81385 | Table *pTable; |
| 81386 | int i, c, n; |
| 81387 | tRowcnt v; |
| 81388 | const char *z; |
| 81389 | |
| 81390 | assert( argc==3 ); |
| 81391 | UNUSED_PARAMETER2(NotUsed, argc); |
| 81392 | |
| @@ -81400,45 +82213,35 @@ | |
| 81400 | if( argv[1] ){ |
| 81401 | pIndex = sqlite3FindIndex(pInfo->db, argv[1], pInfo->zDatabase); |
| 81402 | }else{ |
| 81403 | pIndex = 0; |
| 81404 | } |
| 81405 | n = pIndex ? pIndex->nColumn : 0; |
| 81406 | 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 | } |
| 81424 | return 0; |
| 81425 | } |
| 81426 | |
| 81427 | /* |
| 81428 | ** If the Index.aSample variable is not NULL, delete the aSample[] array |
| 81429 | ** and its contents. |
| 81430 | */ |
| 81431 | SQLITE_PRIVATE void sqlite3DeleteIndexSamples(sqlite3 *db, Index *pIdx){ |
| 81432 | #ifdef SQLITE_ENABLE_STAT3 |
| 81433 | if( pIdx->aSample ){ |
| 81434 | int j; |
| 81435 | for(j=0; j<pIdx->nSample; j++){ |
| 81436 | IndexSample *p = &pIdx->aSample[j]; |
| 81437 | if( p->eType==SQLITE_TEXT || p->eType==SQLITE_BLOB ){ |
| 81438 | sqlite3DbFree(db, p->u.z); |
| 81439 | } |
| 81440 | } |
| 81441 | sqlite3DbFree(db, pIdx->aSample); |
| 81442 | } |
| 81443 | if( db && db->pnBytesFreed==0 ){ |
| 81444 | pIdx->nSample = 0; |
| @@ -81445,155 +82248,222 @@ | |
| 81445 | pIdx->aSample = 0; |
| 81446 | } |
| 81447 | #else |
| 81448 | UNUSED_PARAMETER(db); |
| 81449 | UNUSED_PARAMETER(pIdx); |
| 81450 | #endif |
| 81451 | } |
| 81452 | |
| 81453 | #ifdef SQLITE_ENABLE_STAT3 |
| 81454 | /* |
| 81455 | ** Load content from the sqlite_stat3 table into the Index.aSample[] |
| 81456 | ** arrays of all indices. |
| 81457 | */ |
| 81458 | static int loadStat3(sqlite3 *db, const char *zDb){ |
| 81459 | int rc; /* Result codes from subroutines */ |
| 81460 | sqlite3_stmt *pStmt = 0; /* An SQL statement being run */ |
| 81461 | char *zSql; /* Text of the SQL statement */ |
| 81462 | 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 | IndexSample *pSample; /* A slot in pIdx->aSample[] */ |
| 81466 | |
| 81467 | 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); |
| 81475 | if( !zSql ){ |
| 81476 | return SQLITE_NOMEM; |
| 81477 | } |
| 81478 | rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0); |
| 81479 | sqlite3DbFree(db, zSql); |
| 81480 | if( rc ) return rc; |
| 81481 | |
| 81482 | while( sqlite3_step(pStmt)==SQLITE_ROW ){ |
| 81483 | char *zIndex; /* Index name */ |
| 81484 | Index *pIdx; /* Pointer to the index object */ |
| 81485 | int nSample; /* Number of samples */ |
| 81486 | |
| 81487 | zIndex = (char *)sqlite3_column_text(pStmt, 0); |
| 81488 | if( zIndex==0 ) continue; |
| 81489 | nSample = sqlite3_column_int(pStmt, 1); |
| 81490 | 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]; |
| 81496 | if( pIdx->aSample==0 ){ |
| 81497 | db->mallocFailed = 1; |
| 81498 | sqlite3_finalize(pStmt); |
| 81499 | return SQLITE_NOMEM; |
| 81500 | } |
| 81501 | } |
| 81502 | rc = sqlite3_finalize(pStmt); |
| 81503 | if( rc ) return rc; |
| 81504 | |
| 81505 | zSql = sqlite3MPrintf(db, |
| 81506 | "SELECT idx,neq,nlt,ndlt,sample FROM %Q.sqlite_stat3", zDb); |
| 81507 | if( !zSql ){ |
| 81508 | return SQLITE_NOMEM; |
| 81509 | } |
| 81510 | rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0); |
| 81511 | sqlite3DbFree(db, zSql); |
| 81512 | if( rc ) return rc; |
| 81513 | |
| 81514 | 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 */ |
| 81519 | |
| 81520 | zIndex = (char *)sqlite3_column_text(pStmt, 0); |
| 81521 | if( zIndex==0 ) continue; |
| 81522 | pIdx = sqlite3FindIndex(db, zIndex, zDb); |
| 81523 | if( pIdx==0 ) continue; |
| 81524 | if( pIdx==pPrevIdx ){ |
| 81525 | idx++; |
| 81526 | }else{ |
| 81527 | 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 |
| 81584 | ** contents of sqlite_stat1 are used to populate the Index.aiRowEst[] |
| 81585 | ** arrays. The contents of sqlite_stat3 are used to populate the |
| 81586 | ** Index.aSample[] arrays. |
| 81587 | ** |
| 81588 | ** 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 |
| 81591 | ** read from it. |
| 81592 | ** |
| 81593 | ** If SQLITE_ENABLE_STAT3 was defined during compilation and the |
| 81594 | ** sqlite_stat3 table is not present in the database, SQLITE_ERROR is |
| 81595 | ** returned. However, in this case, data is read from the sqlite_stat1 |
| 81596 | ** table (if it is present) before returning. |
| 81597 | ** |
| 81598 | ** If an OOM error occurs, this function always sets db->mallocFailed. |
| 81599 | ** This means if the caller does not care about other errors, the return |
| @@ -81611,11 +82481,11 @@ | |
| 81611 | /* Clear any prior statistics */ |
| 81612 | assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); |
| 81613 | for(i=sqliteHashFirst(&db->aDb[iDb].pSchema->idxHash);i;i=sqliteHashNext(i)){ |
| 81614 | Index *pIdx = sqliteHashData(i); |
| 81615 | sqlite3DefaultRowEst(pIdx); |
| 81616 | #ifdef SQLITE_ENABLE_STAT3 |
| 81617 | sqlite3DeleteIndexSamples(db, pIdx); |
| 81618 | pIdx->aSample = 0; |
| 81619 | #endif |
| 81620 | } |
| 81621 | |
| @@ -81635,16 +82505,16 @@ | |
| 81635 | rc = sqlite3_exec(db, zSql, analysisLoader, &sInfo, 0); |
| 81636 | sqlite3DbFree(db, zSql); |
| 81637 | } |
| 81638 | |
| 81639 | |
| 81640 | /* Load the statistics from the sqlite_stat3 table. */ |
| 81641 | #ifdef SQLITE_ENABLE_STAT3 |
| 81642 | if( rc==SQLITE_OK ){ |
| 81643 | int lookasideEnabled = db->lookaside.bEnabled; |
| 81644 | db->lookaside.bEnabled = 0; |
| 81645 | rc = loadStat3(db, sInfo.zDatabase); |
| 81646 | db->lookaside.bEnabled = lookasideEnabled; |
| 81647 | } |
| 81648 | #endif |
| 81649 | |
| 81650 | if( rc==SQLITE_NOMEM ){ |
| @@ -84496,11 +85366,11 @@ | |
| 84496 | const char *zType, /* "idx" or "tbl" */ |
| 84497 | const char *zName /* Name of index or table */ |
| 84498 | ){ |
| 84499 | int i; |
| 84500 | const char *zDbName = pParse->db->aDb[iDb].zName; |
| 84501 | for(i=1; i<=3; i++){ |
| 84502 | char zTab[24]; |
| 84503 | sqlite3_snprintf(sizeof(zTab),zTab,"sqlite_stat%d",i); |
| 84504 | if( sqlite3FindTable(pParse->db, zTab, zDbName) ){ |
| 84505 | sqlite3NestedParse(pParse, |
| 84506 | "DELETE FROM %Q.%s WHERE %s=%Q", |
| @@ -89167,10 +90037,13 @@ | |
| 89167 | sqlite3FuncDefInsert(pHash, &aFunc[i]); |
| 89168 | } |
| 89169 | sqlite3RegisterDateTimeFunctions(); |
| 89170 | #ifndef SQLITE_OMIT_ALTERTABLE |
| 89171 | sqlite3AlterFunctions(); |
| 89172 | #endif |
| 89173 | } |
| 89174 | |
| 89175 | /************** End of func.c ************************************************/ |
| 89176 | /************** Begin file fkey.c ********************************************/ |
| @@ -94387,11 +95260,11 @@ | |
| 94387 | */ |
| 94388 | if( sqlite3StrICmp(zLeft,"journal_size_limit")==0 ){ |
| 94389 | Pager *pPager = sqlite3BtreePager(pDb->pBt); |
| 94390 | i64 iLimit = -2; |
| 94391 | if( zRight ){ |
| 94392 | sqlite3Atoi64(zRight, &iLimit, 1000000, SQLITE_UTF8); |
| 94393 | if( iLimit<-1 ) iLimit = -1; |
| 94394 | } |
| 94395 | iLimit = sqlite3PagerJournalSizeLimit(pPager, iLimit); |
| 94396 | returnSingleInt(pParse, "journal_size_limit", iLimit); |
| 94397 | }else |
| @@ -94521,14 +95394,15 @@ | |
| 94521 | ** as little or as much as it wants. Except, if N is set to 0 then the |
| 94522 | ** upper layers will never invoke the xFetch interfaces to the VFS. |
| 94523 | */ |
| 94524 | if( sqlite3StrICmp(zLeft,"mmap_size")==0 ){ |
| 94525 | sqlite3_int64 sz; |
| 94526 | assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); |
| 94527 | if( zRight ){ |
| 94528 | int ii; |
| 94529 | sqlite3Atoi64(zRight, &sz, 1000, SQLITE_UTF8); |
| 94530 | if( sz<0 ) sz = sqlite3GlobalConfig.szMmap; |
| 94531 | if( pId2->n==0 ) db->szMmap = sz; |
| 94532 | for(ii=db->nDb-1; ii>=0; ii--){ |
| 94533 | if( db->aDb[ii].pBt && (ii==iDb || pId2->n==0) ){ |
| 94534 | sqlite3BtreeSetMmapLimit(db->aDb[ii].pBt, sz); |
| @@ -94535,12 +95409,13 @@ | |
| 94535 | } |
| 94536 | } |
| 94537 | } |
| 94538 | sz = -1; |
| 94539 | rc = sqlite3_file_control(db, zDb, SQLITE_FCNTL_MMAP_SIZE, &sz); |
| 94540 | #if SQLITE_MAX_MMAP_SIZE==0 |
| 94541 | sz = 0; |
| 94542 | #endif |
| 94543 | if( rc==SQLITE_OK ){ |
| 94544 | returnSingleInt(pParse, "mmap_size", sz); |
| 94545 | }else if( rc!=SQLITE_NOTFOUND ){ |
| 94546 | pParse->nErr++; |
| @@ -102688,11 +103563,11 @@ | |
| 102688 | ** space. |
| 102689 | */ |
| 102690 | SQLITE_PRIVATE void sqlite3ColumnDefault(Vdbe *v, Table *pTab, int i, int iReg){ |
| 102691 | assert( pTab!=0 ); |
| 102692 | if( !pTab->pSelect ){ |
| 102693 | sqlite3_value *pValue; |
| 102694 | u8 enc = ENC(sqlite3VdbeDb(v)); |
| 102695 | Column *pCol = &pTab->aCol[i]; |
| 102696 | VdbeComment((v, "%s.%s", pTab->zName, pCol->zName)); |
| 102697 | assert( i<pTab->nCol ); |
| 102698 | sqlite3ValueFromExpr(sqlite3VdbeDb(v), pCol->pDflt, enc, |
| @@ -105038,11 +105913,11 @@ | |
| 105038 | #define TERM_CODED 0x04 /* This term is already coded */ |
| 105039 | #define TERM_COPIED 0x08 /* Has a child */ |
| 105040 | #define TERM_ORINFO 0x10 /* Need to free the WhereTerm.u.pOrInfo object */ |
| 105041 | #define TERM_ANDINFO 0x20 /* Need to free the WhereTerm.u.pAndInfo obj */ |
| 105042 | #define TERM_OR_OK 0x40 /* Used during OR-clause processing */ |
| 105043 | #ifdef SQLITE_ENABLE_STAT3 |
| 105044 | # define TERM_VNULL 0x80 /* Manufactured x>NULL or x<=NULL term */ |
| 105045 | #else |
| 105046 | # define TERM_VNULL 0x00 /* Disabled if not using stat3 */ |
| 105047 | #endif |
| 105048 | |
| @@ -105144,10 +106019,14 @@ | |
| 105144 | WhereInfo *pWInfo; /* Information about this WHERE */ |
| 105145 | WhereClause *pWC; /* WHERE clause terms */ |
| 105146 | ExprList *pOrderBy; /* ORDER BY clause */ |
| 105147 | WhereLoop *pNew; /* Template WhereLoop */ |
| 105148 | WhereOrSet *pOrSet; /* Record best loops here, if not NULL */ |
| 105149 | }; |
| 105150 | |
| 105151 | /* |
| 105152 | ** The WHERE clause processing routine has two halves. The |
| 105153 | ** first part does the start of the WHERE loop and the second |
| @@ -106543,11 +107422,11 @@ | |
| 106543 | pNewTerm->prereqAll = pTerm->prereqAll; |
| 106544 | } |
| 106545 | } |
| 106546 | #endif /* SQLITE_OMIT_VIRTUALTABLE */ |
| 106547 | |
| 106548 | #ifdef SQLITE_ENABLE_STAT3 |
| 106549 | /* When sqlite_stat3 histogram data is available an operator of the |
| 106550 | ** form "x IS NOT NULL" can sometimes be evaluated more efficiently |
| 106551 | ** as "x>NULL" if x is not an INTEGER PRIMARY KEY. So construct a |
| 106552 | ** virtual term of that form. |
| 106553 | ** |
| @@ -106583,11 +107462,11 @@ | |
| 106583 | pTerm->nChild = 1; |
| 106584 | pTerm->wtFlags |= TERM_COPIED; |
| 106585 | pNewTerm->prereqAll = pTerm->prereqAll; |
| 106586 | } |
| 106587 | } |
| 106588 | #endif /* SQLITE_ENABLE_STAT */ |
| 106589 | |
| 106590 | /* Prevent ON clause terms of a LEFT JOIN from being used to drive |
| 106591 | ** an index for tables to the left of the join. |
| 106592 | */ |
| 106593 | pTerm->prereqRight |= extraRight; |
| @@ -107151,155 +108030,84 @@ | |
| 107151 | return pParse->nErr; |
| 107152 | } |
| 107153 | #endif /* !defined(SQLITE_OMIT_VIRTUALTABLE) */ |
| 107154 | |
| 107155 | |
| 107156 | #ifdef SQLITE_ENABLE_STAT3 |
| 107157 | /* |
| 107158 | ** Estimate the location of a particular key among all keys in an |
| 107159 | ** index. Store the results in aStat as follows: |
| 107160 | ** |
| 107161 | ** aStat[0] Est. number of rows less than pVal |
| 107162 | ** aStat[1] Est. number of rows equal to pVal |
| 107163 | ** |
| 107164 | ** Return SQLITE_OK on success. |
| 107165 | */ |
| 107166 | static int whereKeyStats( |
| 107167 | Parse *pParse, /* Database connection */ |
| 107168 | Index *pIdx, /* Index to consider domain of */ |
| 107169 | sqlite3_value *pVal, /* Value to consider */ |
| 107170 | int roundUp, /* Round up if true. Round down if false */ |
| 107171 | tRowcnt *aStat /* OUT: stats written here */ |
| 107172 | ){ |
| 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 ); |
| 107181 | 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 | } |
| 107282 | |
| 107283 | /* At this point, aSample[i] is the first sample that is greater than |
| 107284 | ** or equal to pVal. Or if i==pIdx->nSample, then all samples are less |
| 107285 | ** than pVal. If aSample[i]==pVal, then isEq==1. |
| 107286 | */ |
| 107287 | if( isEq ){ |
| 107288 | assert( i<pIdx->nSample ); |
| 107289 | aStat[0] = aSample[i].nLt; |
| 107290 | aStat[1] = aSample[i].nEq; |
| 107291 | }else{ |
| 107292 | tRowcnt iLower, iUpper, iGap; |
| 107293 | if( i==0 ){ |
| 107294 | iLower = 0; |
| 107295 | iUpper = aSample[0].nLt; |
| 107296 | }else{ |
| 107297 | iUpper = i>=pIdx->nSample ? n : aSample[i].nLt; |
| 107298 | iLower = aSample[i-1].nEq + aSample[i-1].nLt; |
| 107299 | } |
| 107300 | aStat[1] = pIdx->avgEq; |
| 107301 | if( iLower>=iUpper ){ |
| 107302 | iGap = 0; |
| 107303 | }else{ |
| 107304 | iGap = iUpper - iLower; |
| 107305 | } |
| @@ -107308,48 +108116,12 @@ | |
| 107308 | }else{ |
| 107309 | iGap = iGap/3; |
| 107310 | } |
| 107311 | aStat[0] = iLower + iGap; |
| 107312 | } |
| 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 |
| 107351 | |
| 107352 | /* |
| 107353 | ** This function is used to estimate the number of rows that will be visited |
| 107354 | ** by scanning an index for a range of values. The range may have an upper |
| 107355 | ** bound, a lower bound, or both. The WHERE clause terms that set the upper |
| @@ -107362,107 +108134,154 @@ | |
| 107362 | ** pLower pUpper |
| 107363 | ** |
| 107364 | ** If either of the upper or lower bound is not present, then NULL is passed in |
| 107365 | ** place of the corresponding WhereTerm. |
| 107366 | ** |
| 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: |
| 107371 | ** |
| 107372 | ** ... FROM t1 WHERE a = ? AND b > ? AND b < ? ... |
| 107373 | ** |
| 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: |
| 107376 | ** |
| 107377 | ** ... FROM t1 WHERE a > ? AND a < ? ... |
| 107378 | ** |
| 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. |
| 107390 | */ |
| 107391 | static int whereRangeScanEst( |
| 107392 | 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 */ |
| 107395 | WhereTerm *pLower, /* Lower bound on the range. ex: "x>123" Might be NULL */ |
| 107396 | WhereTerm *pUpper, /* Upper bound on the range. ex: "x<455" Might be NULL */ |
| 107397 | WhereCost *pRangeDiv /* OUT: Reduce search space by this divisor */ |
| 107398 | ){ |
| 107399 | int rc = SQLITE_OK; |
| 107400 | |
| 107401 | #ifdef SQLITE_ENABLE_STAT3 |
| 107402 | |
| 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]; |
| 107407 | tRowcnt a[2]; |
| 107408 | u8 aff = p->pTable->aCol[p->aiColumn[0]].affinity; |
| 107409 | |
| 107410 | if( pLower ){ |
| 107411 | Expr *pExpr = pLower->pExpr->pRight; |
| 107412 | rc = valueFromExpr(pParse, pExpr, aff, &pRangeVal); |
| 107413 | 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); |
| 107425 | 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 | } |
| 107434 | if( rc==SQLITE_OK ){ |
| 107435 | WhereCost iBase = whereCost(p->aiRowEst[0]); |
| 107436 | if( iUpper>iLower ){ |
| 107437 | iBase -= whereCost(iUpper - iLower); |
| 107438 | } |
| 107439 | *pRangeDiv = iBase; |
| 107440 | WHERETRACE(0x100, ("range scan regions: %u..%u div=%d\n", |
| 107441 | (u32)iLower, (u32)iUpper, *pRangeDiv)); |
| 107442 | return SQLITE_OK; |
| 107443 | } |
| 107444 | } |
| 107445 | #else |
| 107446 | UNUSED_PARAMETER(pParse); |
| 107447 | UNUSED_PARAMETER(p); |
| 107448 | UNUSED_PARAMETER(nEq); |
| 107449 | #endif |
| 107450 | assert( pLower || pUpper ); |
| 107451 | *pRangeDiv = 0; |
| 107452 | /* TUNING: Each inequality constraint reduces the search space 4-fold. |
| 107453 | ** A BETWEEN operator, therefore, reduces the search space 16-fold */ |
| 107454 | if( pLower && (pLower->wtFlags & TERM_VNULL)==0 ){ |
| 107455 | *pRangeDiv += 20; assert( 20==whereCost(4) ); |
| 107456 | } |
| 107457 | if( pUpper ){ |
| 107458 | *pRangeDiv += 20; assert( 20==whereCost(4) ); |
| 107459 | } |
| 107460 | return rc; |
| 107461 | } |
| 107462 | |
| 107463 | #ifdef SQLITE_ENABLE_STAT3 |
| 107464 | /* |
| 107465 | ** Estimate the number of rows that will be returned based on |
| 107466 | ** an equality constraint x=VALUE and where that VALUE occurs in |
| 107467 | ** the histogram data. This only works when x is the left-most |
| 107468 | ** column of an index and sqlite_stat3 histogram data is available |
| @@ -107478,41 +108297,57 @@ | |
| 107478 | ** for a UTF conversion required for comparison. The error is stored |
| 107479 | ** in the pParse structure. |
| 107480 | */ |
| 107481 | static int whereEqualScanEst( |
| 107482 | Parse *pParse, /* Parsing & code generating context */ |
| 107483 | Index *p, /* The index whose left-most column is pTerm */ |
| 107484 | Expr *pExpr, /* Expression for VALUE in the x=VALUE constraint */ |
| 107485 | tRowcnt *pnRow /* Write the revised row estimate here */ |
| 107486 | ){ |
| 107487 | sqlite3_value *pRhs = 0; /* VALUE on right-hand side of pTerm */ |
| 107488 | u8 aff; /* Column affinity */ |
| 107489 | int rc; /* Subfunction return code */ |
| 107490 | tRowcnt a[2]; /* Statistics */ |
| 107491 | |
| 107492 | assert( p->aSample!=0 ); |
| 107493 | 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); |
| 107509 | return rc; |
| 107510 | } |
| 107511 | #endif /* defined(SQLITE_ENABLE_STAT3) */ |
| 107512 | |
| 107513 | #ifdef SQLITE_ENABLE_STAT3 |
| 107514 | /* |
| 107515 | ** Estimate the number of rows that will be returned based on |
| 107516 | ** an IN constraint where the right-hand side of the IN operator |
| 107517 | ** is a list of values. Example: |
| 107518 | ** |
| @@ -107527,33 +108362,38 @@ | |
| 107527 | ** for a UTF conversion required for comparison. The error is stored |
| 107528 | ** in the pParse structure. |
| 107529 | */ |
| 107530 | static int whereInScanEst( |
| 107531 | Parse *pParse, /* Parsing & code generating context */ |
| 107532 | Index *p, /* The index whose left-most column is pTerm */ |
| 107533 | ExprList *pList, /* The value list on the RHS of "x IN (v1,v2,v3,...)" */ |
| 107534 | tRowcnt *pnRow /* Write the revised row estimate here */ |
| 107535 | ){ |
| 107536 | int rc = SQLITE_OK; /* Subfunction return code */ |
| 107537 | tRowcnt nEst; /* Number of rows for a single term */ |
| 107538 | tRowcnt nRowEst = 0; /* New estimate of the number of rows */ |
| 107539 | int i; /* Loop counter */ |
| 107540 | |
| 107541 | assert( p->aSample!=0 ); |
| 107542 | for(i=0; rc==SQLITE_OK && i<pList->nExpr; i++){ |
| 107543 | nEst = p->aiRowEst[0]; |
| 107544 | rc = whereEqualScanEst(pParse, p, pList->a[i].pExpr, &nEst); |
| 107545 | nRowEst += nEst; |
| 107546 | } |
| 107547 | if( rc==SQLITE_OK ){ |
| 107548 | if( nRowEst > p->aiRowEst[0] ) nRowEst = p->aiRowEst[0]; |
| 107549 | *pnRow = nRowEst; |
| 107550 | WHERETRACE(0x100,("IN row estimate: est=%g\n", nRowEst)); |
| 107551 | } |
| 107552 | return rc; |
| 107553 | } |
| 107554 | #endif /* defined(SQLITE_ENABLE_STAT3) */ |
| 107555 | |
| 107556 | /* |
| 107557 | ** Disable a term in the WHERE clause. Except, do not disable the term |
| 107558 | ** if it controls a LEFT OUTER JOIN and it did not originate in the ON |
| 107559 | ** or USING clause of that join. |
| @@ -107787,11 +108627,11 @@ | |
| 107787 | pParse->db->mallocFailed = 1; |
| 107788 | } |
| 107789 | |
| 107790 | /* Evaluate the equality constraints |
| 107791 | */ |
| 107792 | assert( zAff==0 || strlen(zAff)>=nEq ); |
| 107793 | for(j=0; j<nEq; j++){ |
| 107794 | int r1; |
| 107795 | pTerm = pLoop->aLTerm[j]; |
| 107796 | assert( pTerm!=0 ); |
| 107797 | /* The following true for indices with redundant columns. |
| @@ -109094,16 +109934,22 @@ | |
| 109094 | saved_nOut = pNew->nOut; |
| 109095 | pNew->rSetup = 0; |
| 109096 | rLogSize = estLog(whereCost(pProbe->aiRowEst[0])); |
| 109097 | for(; rc==SQLITE_OK && pTerm!=0; pTerm = whereScanNext(&scan)){ |
| 109098 | int nIn = 0; |
| 109099 | if( pTerm->prereqRight & pNew->maskSelf ) continue; |
| 109100 | if( (pTerm->eOperator==WO_ISNULL || (pTerm->wtFlags&TERM_VNULL)!=0) |
| 109101 | && (iCol<0 || pSrc->pTab->aCol[iCol].notNull) |
| 109102 | ){ |
| 109103 | continue; /* ignore IS [NOT] NULL constraints on NOT NULL columns */ |
| 109104 | } |
| 109105 | pNew->wsFlags = saved_wsFlags; |
| 109106 | pNew->u.btree.nEq = saved_nEq; |
| 109107 | pNew->nLTerm = saved_nLTerm; |
| 109108 | if( whereLoopResize(db, pNew, pNew->nLTerm+1) ) break; /* OOM */ |
| 109109 | pNew->aLTerm[pNew->nLTerm++] = pTerm; |
| @@ -109156,29 +110002,34 @@ | |
| 109156 | pBtm = (pNew->wsFlags & WHERE_BTM_LIMIT)!=0 ? |
| 109157 | pNew->aLTerm[pNew->nLTerm-2] : 0; |
| 109158 | } |
| 109159 | if( pNew->wsFlags & WHERE_COLUMN_RANGE ){ |
| 109160 | /* 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) ){ |
| 109169 | tRowcnt nOut = 0; |
| 109170 | if( (pTerm->eOperator & (WO_EQ|WO_ISNULL))!=0 ){ |
| 109171 | testcase( pTerm->eOperator & WO_EQ ); |
| 109172 | testcase( pTerm->eOperator & WO_ISNULL ); |
| 109173 | rc = whereEqualScanEst(pParse, pProbe, pTerm->pExpr->pRight, &nOut); |
| 109174 | }else if( (pTerm->eOperator & WO_IN) |
| 109175 | && !ExprHasProperty(pTerm->pExpr, EP_xIsSelect) ){ |
| 109176 | rc = whereInScanEst(pParse, pProbe, pTerm->pExpr->x.pList, &nOut); |
| 109177 | } |
| 109178 | assert( nOut==0 || rc==SQLITE_OK ); |
| 109179 | if( nOut ) pNew->nOut = whereCost(nOut); |
| 109180 | } |
| 109181 | #endif |
| 109182 | if( (pNew->wsFlags & (WHERE_IDX_ONLY|WHERE_IPK))==0 ){ |
| 109183 | /* Each row involves a step of the index, then a binary search of |
| 109184 | ** the main table */ |
| @@ -109191,10 +110042,14 @@ | |
| 109191 | if( (pNew->wsFlags & WHERE_TOP_LIMIT)==0 |
| 109192 | && pNew->u.btree.nEq<(pProbe->nColumn + (pProbe->zName!=0)) |
| 109193 | ){ |
| 109194 | whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, nInMul+nIn); |
| 109195 | } |
| 109196 | } |
| 109197 | pNew->prereq = saved_prereq; |
| 109198 | pNew->u.btree.nEq = saved_nEq; |
| 109199 | pNew->wsFlags = saved_wsFlags; |
| 109200 | pNew->nOut = saved_nOut; |
| @@ -109420,11 +110275,17 @@ | |
| 109420 | } |
| 109421 | rc = whereLoopInsert(pBuilder, pNew); |
| 109422 | if( rc ) break; |
| 109423 | } |
| 109424 | } |
| 109425 | rc = whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, 0); |
| 109426 | |
| 109427 | /* If there was an INDEXED BY clause, then only that one index is |
| 109428 | ** considered. */ |
| 109429 | if( pSrc->pIndex ) break; |
| 109430 | } |
| 109431 |
| --- src/sqlite3.c | |
| +++ src/sqlite3.c | |
| @@ -1,8 +1,8 @@ | |
| 1 | /****************************************************************************** |
| 2 | ** This file is an amalgamation of many separate C source files from SQLite |
| 3 | ** version 3.8.1. By combining all the individual C code files into this |
| 4 | ** single large file, the entire code can be compiled as a single translation |
| 5 | ** unit. This allows many compilers to do optimizations that would not be |
| 6 | ** possible if the files were compiled separately. Performance improvements |
| 7 | ** of 5% or more are commonly seen when SQLite is compiled as a single |
| 8 | ** translation unit. |
| @@ -654,13 +654,13 @@ | |
| 654 | ** |
| 655 | ** See also: [sqlite3_libversion()], |
| 656 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 657 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 658 | */ |
| 659 | #define SQLITE_VERSION "3.8.1" |
| 660 | #define SQLITE_VERSION_NUMBER 3008001 |
| 661 | #define SQLITE_SOURCE_ID "2013-08-29 23:36:49 30d38cc44904d93508b87e373b2f45d5f93e556b" |
| 662 | |
| 663 | /* |
| 664 | ** CAPI3REF: Run-Time Library Version Numbers |
| 665 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 666 | ** |
| @@ -8368,10 +8368,24 @@ | |
| 8368 | #if SQLITE_DEFAULT_MMAP_SIZE>SQLITE_MAX_MMAP_SIZE |
| 8369 | # undef SQLITE_DEFAULT_MMAP_SIZE |
| 8370 | # define SQLITE_DEFAULT_MMAP_SIZE SQLITE_MAX_MMAP_SIZE |
| 8371 | #endif |
| 8372 | |
| 8373 | /* |
| 8374 | ** Only one of SQLITE_ENABLE_STAT3 or SQLITE_ENABLE_STAT4 can be defined. |
| 8375 | ** Priority is given to SQLITE_ENABLE_STAT4. If either are defined, also |
| 8376 | ** define SQLITE_ENABLE_STAT3_OR_STAT4 |
| 8377 | */ |
| 8378 | #ifdef SQLITE_ENABLE_STAT4 |
| 8379 | # undef SQLITE_ENABLE_STAT3 |
| 8380 | # define SQLITE_ENABLE_STAT3_OR_STAT4 1 |
| 8381 | #elif SQLITE_ENABLE_STAT3 |
| 8382 | # define SQLITE_ENABLE_STAT3_OR_STAT4 1 |
| 8383 | #elif SQLITE_ENABLE_STAT3_OR_STAT4 |
| 8384 | # undef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 8385 | #endif |
| 8386 | |
| 8387 | /* |
| 8388 | ** An instance of the following structure is used to store the busy-handler |
| 8389 | ** callback for a given sqlite handle. |
| 8390 | ** |
| 8391 | ** The sqlite.busyHandler member of the sqlite struct contains the busy |
| @@ -10770,13 +10784,14 @@ | |
| 10784 | u16 nColumn; /* Number of columns in table used by this index */ |
| 10785 | u8 onError; /* OE_Abort, OE_Ignore, OE_Replace, or OE_None */ |
| 10786 | unsigned autoIndex:2; /* 1==UNIQUE, 2==PRIMARY KEY, 0==CREATE INDEX */ |
| 10787 | unsigned bUnordered:1; /* Use this index for == or IN queries only */ |
| 10788 | unsigned uniqNotNull:1; /* True if UNIQUE and NOT NULL for all columns */ |
| 10789 | #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 10790 | int nSample; /* Number of elements in aSample[] */ |
| 10791 | int nSampleCol; /* Size of IndexSample.anEq[] and so on */ |
| 10792 | tRowcnt *aAvgEq; /* Average nEq values for keys not in aSample */ |
| 10793 | IndexSample *aSample; /* Samples of the left-most key */ |
| 10794 | #endif |
| 10795 | }; |
| 10796 | |
| 10797 | /* |
| @@ -10783,20 +10798,15 @@ | |
| 10798 | ** Each sample stored in the sqlite_stat3 table is represented in memory |
| 10799 | ** using a structure of this type. See documentation at the top of the |
| 10800 | ** analyze.c source file for additional information. |
| 10801 | */ |
| 10802 | struct IndexSample { |
| 10803 | void *p; /* Pointer to sampled record */ |
| 10804 | int n; /* Size of record in bytes */ |
| 10805 | tRowcnt *anEq; /* Est. number of rows where the key equals this sample */ |
| 10806 | tRowcnt *anLt; /* Est. number of rows where key is less than this sample */ |
| 10807 | tRowcnt *anDLt; /* Est. number of distinct keys less than this sample */ |
| 10808 | }; |
| 10809 | |
| 10810 | /* |
| 10811 | ** Each token coming out of the lexer is an instance of |
| 10812 | ** this structure. Tokens are also used as part of an expression. |
| @@ -12264,13 +12274,10 @@ | |
| 12274 | SQLITE_PRIVATE void sqlite3ValueSetStr(sqlite3_value*, int, const void *,u8, |
| 12275 | void(*)(void*)); |
| 12276 | SQLITE_PRIVATE void sqlite3ValueFree(sqlite3_value*); |
| 12277 | SQLITE_PRIVATE sqlite3_value *sqlite3ValueNew(sqlite3 *); |
| 12278 | SQLITE_PRIVATE char *sqlite3Utf16to8(sqlite3 *, const void*, int, u8); |
| 12279 | SQLITE_PRIVATE int sqlite3ValueFromExpr(sqlite3 *, Expr *, u8, u8, sqlite3_value **); |
| 12280 | SQLITE_PRIVATE void sqlite3ValueApplyAffinity(sqlite3_value *, u8, u8); |
| 12281 | #ifndef SQLITE_AMALGAMATION |
| 12282 | SQLITE_PRIVATE const unsigned char sqlite3OpcodeProperty[]; |
| 12283 | SQLITE_PRIVATE const unsigned char sqlite3UpperToLower[]; |
| @@ -12332,10 +12339,16 @@ | |
| 12339 | SQLITE_PRIVATE void sqlite3SelectDestInit(SelectDest*,int,int); |
| 12340 | SQLITE_PRIVATE Expr *sqlite3CreateColumnExpr(sqlite3 *, SrcList *, int, int); |
| 12341 | |
| 12342 | SQLITE_PRIVATE void sqlite3BackupRestart(sqlite3_backup *); |
| 12343 | SQLITE_PRIVATE void sqlite3BackupUpdate(sqlite3_backup *, Pgno, const u8 *); |
| 12344 | |
| 12345 | #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 12346 | SQLITE_PRIVATE void sqlite3AnalyzeFunctions(void); |
| 12347 | SQLITE_PRIVATE int sqlite3Stat4ProbeSetValue(Parse*,Index*,UnpackedRecord**,Expr*,u8,int,int*); |
| 12348 | SQLITE_PRIVATE void sqlite3Stat4ProbeFree(UnpackedRecord*); |
| 12349 | #endif |
| 12350 | |
| 12351 | /* |
| 12352 | ** The interface to the LEMON-generated parser |
| 12353 | */ |
| 12354 | SQLITE_PRIVATE void *sqlite3ParserAlloc(void*(*)(size_t)); |
| @@ -12916,11 +12929,13 @@ | |
| 12929 | "ENABLE_OVERSIZE_CELL_CHECK", |
| 12930 | #endif |
| 12931 | #ifdef SQLITE_ENABLE_RTREE |
| 12932 | "ENABLE_RTREE", |
| 12933 | #endif |
| 12934 | #if defined(SQLITE_ENABLE_STAT4) |
| 12935 | "ENABLE_STAT4", |
| 12936 | #elif defined(SQLITE_ENABLE_STAT3) |
| 12937 | "ENABLE_STAT3", |
| 12938 | #endif |
| 12939 | #ifdef SQLITE_ENABLE_UNLOCK_NOTIFY |
| 12940 | "ENABLE_UNLOCK_NOTIFY", |
| 12941 | #endif |
| @@ -16075,11 +16090,11 @@ | |
| 16090 | struct MemBlockHdr *pHdr; |
| 16091 | if( !p ){ |
| 16092 | return 0; |
| 16093 | } |
| 16094 | pHdr = sqlite3MemsysGetHeader(p); |
| 16095 | return (int)pHdr->iSize; |
| 16096 | } |
| 16097 | |
| 16098 | /* |
| 16099 | ** Initialize the memory allocation subsystem. |
| 16100 | */ |
| @@ -16117,19 +16132,19 @@ | |
| 16132 | static void randomFill(char *pBuf, int nByte){ |
| 16133 | unsigned int x, y, r; |
| 16134 | x = SQLITE_PTR_TO_INT(pBuf); |
| 16135 | y = nByte | 1; |
| 16136 | while( nByte >= 4 ){ |
| 16137 | x = (x>>1) ^ (-(int)(x&1) & 0xd0000001); |
| 16138 | y = y*1103515245 + 12345; |
| 16139 | r = x ^ y; |
| 16140 | *(int*)pBuf = r; |
| 16141 | pBuf += 4; |
| 16142 | nByte -= 4; |
| 16143 | } |
| 16144 | while( nByte-- > 0 ){ |
| 16145 | x = (x>>1) ^ (-(int)(x&1) & 0xd0000001); |
| 16146 | y = y*1103515245 + 12345; |
| 16147 | r = x ^ y; |
| 16148 | *(pBuf++) = r & 0xff; |
| 16149 | } |
| 16150 | } |
| @@ -16220,13 +16235,13 @@ | |
| 16235 | assert( mem.pLast==pHdr ); |
| 16236 | mem.pLast = pHdr->pPrev; |
| 16237 | } |
| 16238 | z = (char*)pBt; |
| 16239 | z -= pHdr->nTitle; |
| 16240 | adjustStats((int)pHdr->iSize, -1); |
| 16241 | randomFill(z, sizeof(void*)*pHdr->nBacktraceSlots + sizeof(*pHdr) + |
| 16242 | (int)pHdr->iSize + sizeof(int) + pHdr->nTitle); |
| 16243 | free(z); |
| 16244 | sqlite3_mutex_leave(mem.mutex); |
| 16245 | } |
| 16246 | |
| 16247 | /* |
| @@ -16246,11 +16261,11 @@ | |
| 16261 | pOldHdr = sqlite3MemsysGetHeader(pPrior); |
| 16262 | pNew = sqlite3MemMalloc(nByte); |
| 16263 | if( pNew ){ |
| 16264 | memcpy(pNew, pPrior, nByte<pOldHdr->iSize ? nByte : pOldHdr->iSize); |
| 16265 | if( nByte>pOldHdr->iSize ){ |
| 16266 | randomFill(&((char*)pNew)[pOldHdr->iSize], nByte - (int)pOldHdr->iSize); |
| 16267 | } |
| 16268 | sqlite3MemFree(pPrior); |
| 16269 | } |
| 16270 | return pNew; |
| 16271 | } |
| @@ -16361,11 +16376,11 @@ | |
| 16376 | SQLITE_PRIVATE void sqlite3MemdebugSync(){ |
| 16377 | struct MemBlockHdr *pHdr; |
| 16378 | for(pHdr=mem.pFirst; pHdr; pHdr=pHdr->pNext){ |
| 16379 | void **pBt = (void**)pHdr; |
| 16380 | pBt -= pHdr->nBacktraceSlots; |
| 16381 | mem.xBacktrace((int)pHdr->iSize, pHdr->nBacktrace-1, &pBt[1]); |
| 16382 | } |
| 16383 | } |
| 16384 | |
| 16385 | /* |
| 16386 | ** Open the file indicated and write a log of all unfreed memory |
| @@ -18483,11 +18498,11 @@ | |
| 18498 | GetVersionEx(&sInfo); |
| 18499 | osType = sInfo.dwPlatformId==VER_PLATFORM_WIN32_NT ? 2 : 1; |
| 18500 | } |
| 18501 | return osType==2; |
| 18502 | } |
| 18503 | #endif /* SQLITE_OS_WINCE || SQLITE_OS_WINRT */ |
| 18504 | #endif |
| 18505 | |
| 18506 | #ifdef SQLITE_DEBUG |
| 18507 | /* |
| 18508 | ** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are |
| @@ -18521,11 +18536,11 @@ | |
| 18536 | /* As winMutexInit() and winMutexEnd() are called as part |
| 18537 | ** of the sqlite3_initialize and sqlite3_shutdown() |
| 18538 | ** processing, the "interlocked" magic is probably not |
| 18539 | ** strictly necessary. |
| 18540 | */ |
| 18541 | static LONG winMutex_lock = 0; |
| 18542 | |
| 18543 | SQLITE_API void sqlite3_win32_sleep(DWORD milliseconds); /* os_win.c */ |
| 18544 | |
| 18545 | static int winMutexInit(void){ |
| 18546 | /* The first to increment to 1 does actual initialization */ |
| @@ -21082,36 +21097,10 @@ | |
| 21097 | assert( (m.flags & MEM_Dyn)!=0 || db->mallocFailed ); |
| 21098 | assert( m.z || db->mallocFailed ); |
| 21099 | return m.z; |
| 21100 | } |
| 21101 | |
| 21102 | /* |
| 21103 | ** zIn is a UTF-16 encoded unicode string at least nChar characters long. |
| 21104 | ** Return the number of bytes in the first nChar unicode characters |
| 21105 | ** in pZ. nChar must be non-negative. |
| 21106 | */ |
| @@ -23064,15 +23053,17 @@ | |
| 23053 | void *lockingContext; /* Locking style specific state */ |
| 23054 | UnixUnusedFd *pUnused; /* Pre-allocated UnixUnusedFd */ |
| 23055 | const char *zPath; /* Name of the file */ |
| 23056 | unixShm *pShm; /* Shared memory segment information */ |
| 23057 | int szChunk; /* Configured by FCNTL_CHUNK_SIZE */ |
| 23058 | #if SQLITE_MAX_MMAP_SIZE>0 |
| 23059 | int nFetchOut; /* Number of outstanding xFetch refs */ |
| 23060 | sqlite3_int64 mmapSize; /* Usable size of mapping at pMapRegion */ |
| 23061 | sqlite3_int64 mmapSizeActual; /* Actual size of mapping at pMapRegion */ |
| 23062 | sqlite3_int64 mmapSizeMax; /* Configured FCNTL_MMAP_SIZE value */ |
| 23063 | void *pMapRegion; /* Memory mapped region */ |
| 23064 | #endif |
| 23065 | #ifdef __QNXNTO__ |
| 23066 | int sectorSize; /* Device sector size */ |
| 23067 | int deviceCharacteristics; /* Precomputed device characteristics */ |
| 23068 | #endif |
| 23069 | #if SQLITE_ENABLE_LOCKING_STYLE |
| @@ -23503,10 +23494,11 @@ | |
| 23494 | #define osRmdir ((int(*)(const char*))aSyscall[19].pCurrent) |
| 23495 | |
| 23496 | { "fchown", (sqlite3_syscall_ptr)posixFchown, 0 }, |
| 23497 | #define osFchown ((int(*)(int,uid_t,gid_t))aSyscall[20].pCurrent) |
| 23498 | |
| 23499 | #if !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0 |
| 23500 | { "mmap", (sqlite3_syscall_ptr)mmap, 0 }, |
| 23501 | #define osMmap ((void*(*)(void*,size_t,int,int,int,off_t))aSyscall[21].pCurrent) |
| 23502 | |
| 23503 | { "munmap", (sqlite3_syscall_ptr)munmap, 0 }, |
| 23504 | #define osMunmap ((void*(*)(void*,size_t))aSyscall[22].pCurrent) |
| @@ -23515,10 +23507,11 @@ | |
| 23507 | { "mremap", (sqlite3_syscall_ptr)mremap, 0 }, |
| 23508 | #else |
| 23509 | { "mremap", (sqlite3_syscall_ptr)0, 0 }, |
| 23510 | #endif |
| 23511 | #define osMremap ((void*(*)(void*,size_t,size_t,int,...))aSyscall[23].pCurrent) |
| 23512 | #endif |
| 23513 | |
| 23514 | }; /* End of the overrideable system calls */ |
| 23515 | |
| 23516 | /* |
| 23517 | ** This is the xSetSystemCall() method of sqlite3_vfs for all of the |
| @@ -23600,10 +23593,35 @@ | |
| 23593 | for(i++; i<ArraySize(aSyscall); i++){ |
| 23594 | if( aSyscall[i].pCurrent!=0 ) return aSyscall[i].zName; |
| 23595 | } |
| 23596 | return 0; |
| 23597 | } |
| 23598 | |
| 23599 | /* |
| 23600 | ** If fd is a file descriptor that would be dangerous to use for an |
| 23601 | ** ordinary file, the close it, reopen it as /dev/null to get it out |
| 23602 | ** of the way, then return true. |
| 23603 | ** |
| 23604 | ** If fd is safe, return 0. |
| 23605 | ** |
| 23606 | ** It is dangerous to have a database file open of file descriptors 1 or |
| 23607 | ** 2 because those normally mean standard output and standard error. Other |
| 23608 | ** components of the system might write directly to those file descriptors |
| 23609 | ** and overwrite parts of the database file. Something like this happened |
| 23610 | ** on 2013-08-29 to the canonical Fossil repository when some error caused |
| 23611 | ** the database file to be opened on file descriptor 2 and later an assert() |
| 23612 | ** fired and wrote error message text into file descriptor 2, corrupting |
| 23613 | ** the repository. |
| 23614 | */ |
| 23615 | static int isReservedFd(int fd, const char *z, int f, int m){ |
| 23616 | if( fd<0 || fd>2 ) return 0; |
| 23617 | sqlite3_log(SQLITE_WARNING, |
| 23618 | "attempt to open \"%s\" as file descriptor %d", z, fd); |
| 23619 | osClose(fd); |
| 23620 | (void)osOpen("/dev/null",f,m); |
| 23621 | return 1; |
| 23622 | } |
| 23623 | |
| 23624 | /* |
| 23625 | ** Invoke open(). Do so multiple times, until it either succeeds or |
| 23626 | ** fails for some reason other than EINTR. |
| 23627 | ** |
| @@ -23627,11 +23645,11 @@ | |
| 23645 | #if defined(O_CLOEXEC) |
| 23646 | fd = osOpen(z,f|O_CLOEXEC,m2); |
| 23647 | #else |
| 23648 | fd = osOpen(z,f,m2); |
| 23649 | #endif |
| 23650 | }while( (fd<0 && errno==EINTR) || isReservedFd(fd,z,f,m2) ); |
| 23651 | if( fd>=0 ){ |
| 23652 | if( m!=0 ){ |
| 23653 | struct stat statbuf; |
| 23654 | if( osFstat(fd, &statbuf)==0 |
| 23655 | && statbuf.st_size==0 |
| @@ -24925,12 +24943,14 @@ | |
| 24943 | static int unixUnlock(sqlite3_file *id, int eFileLock){ |
| 24944 | assert( eFileLock==SHARED_LOCK || ((unixFile *)id)->nFetchOut==0 ); |
| 24945 | return posixUnlock(id, eFileLock, 0); |
| 24946 | } |
| 24947 | |
| 24948 | #if SQLITE_MAX_MMAP_SIZE>0 |
| 24949 | static int unixMapfile(unixFile *pFd, i64 nByte); |
| 24950 | static void unixUnmapfile(unixFile *pFd); |
| 24951 | #endif |
| 24952 | |
| 24953 | /* |
| 24954 | ** This function performs the parts of the "close file" operation |
| 24955 | ** common to all locking schemes. It closes the directory and file |
| 24956 | ** handles, if they are valid, and sets all fields of the unixFile |
| @@ -24940,11 +24960,13 @@ | |
| 24960 | ** even on VxWorks. A mutex will be acquired on VxWorks by the |
| 24961 | ** vxworksReleaseFileId() routine. |
| 24962 | */ |
| 24963 | static int closeUnixFile(sqlite3_file *id){ |
| 24964 | unixFile *pFile = (unixFile*)id; |
| 24965 | #if SQLITE_MAX_MMAP_SIZE>0 |
| 24966 | unixUnmapfile(pFile); |
| 24967 | #endif |
| 24968 | if( pFile->h>=0 ){ |
| 24969 | robust_close(pFile, pFile->h, __LINE__); |
| 24970 | pFile->h = -1; |
| 24971 | } |
| 24972 | #if OS_VXWORKS |
| @@ -26145,10 +26167,11 @@ | |
| 26167 | #if (!defined(USE_PREAD) && !defined(USE_PREAD64)) |
| 26168 | i64 newOffset; |
| 26169 | #endif |
| 26170 | TIMER_START; |
| 26171 | assert( cnt==(cnt&0x1ffff) ); |
| 26172 | assert( id->h>2 ); |
| 26173 | cnt &= 0x1ffff; |
| 26174 | do{ |
| 26175 | #if defined(USE_PREAD) |
| 26176 | got = osPread(id->h, pBuf, cnt, offset); |
| 26177 | SimulateIOError( got = -1 ); |
| @@ -26259,10 +26282,11 @@ | |
| 26282 | int *piErrno /* OUT: Error number if error occurs */ |
| 26283 | ){ |
| 26284 | int rc = 0; /* Value returned by system call */ |
| 26285 | |
| 26286 | assert( nBuf==(nBuf&0x1ffff) ); |
| 26287 | assert( fd>2 ); |
| 26288 | nBuf &= 0x1ffff; |
| 26289 | TIMER_START; |
| 26290 | |
| 26291 | #if defined(USE_PREAD) |
| 26292 | do{ rc = osPwrite(fd, pBuf, nBuf, iOff); }while( rc<0 && errno==EINTR ); |
| @@ -26644,17 +26668,19 @@ | |
| 26668 | if( pFile->inNormalWrite && nByte==0 ){ |
| 26669 | pFile->transCntrChng = 1; |
| 26670 | } |
| 26671 | #endif |
| 26672 | |
| 26673 | #if SQLITE_MAX_MMAP_SIZE>0 |
| 26674 | /* If the file was just truncated to a size smaller than the currently |
| 26675 | ** mapped region, reduce the effective mapping size as well. SQLite will |
| 26676 | ** use read() and write() to access data beyond this point from now on. |
| 26677 | */ |
| 26678 | if( nByte<pFile->mmapSize ){ |
| 26679 | pFile->mmapSize = nByte; |
| 26680 | } |
| 26681 | #endif |
| 26682 | |
| 26683 | return SQLITE_OK; |
| 26684 | } |
| 26685 | } |
| 26686 | |
| @@ -26740,10 +26766,11 @@ | |
| 26766 | } |
| 26767 | #endif |
| 26768 | } |
| 26769 | } |
| 26770 | |
| 26771 | #if SQLITE_MAX_MMAP_SIZE>0 |
| 26772 | if( pFile->mmapSizeMax>0 && nByte>pFile->mmapSize ){ |
| 26773 | int rc; |
| 26774 | if( pFile->szChunk<=0 ){ |
| 26775 | if( robust_ftruncate(pFile->h, nByte) ){ |
| 26776 | pFile->lastErrno = errno; |
| @@ -26752,10 +26779,11 @@ | |
| 26779 | } |
| 26780 | |
| 26781 | rc = unixMapfile(pFile, nByte); |
| 26782 | return rc; |
| 26783 | } |
| 26784 | #endif |
| 26785 | |
| 26786 | return SQLITE_OK; |
| 26787 | } |
| 26788 | |
| 26789 | /* |
| @@ -26820,10 +26848,11 @@ | |
| 26848 | unixGetTempname(pFile->pVfs->mxPathname, zTFile); |
| 26849 | *(char**)pArg = zTFile; |
| 26850 | } |
| 26851 | return SQLITE_OK; |
| 26852 | } |
| 26853 | #if SQLITE_MAX_MMAP_SIZE>0 |
| 26854 | case SQLITE_FCNTL_MMAP_SIZE: { |
| 26855 | i64 newLimit = *(i64*)pArg; |
| 26856 | int rc = SQLITE_OK; |
| 26857 | if( newLimit>sqlite3GlobalConfig.mxMmap ){ |
| 26858 | newLimit = sqlite3GlobalConfig.mxMmap; |
| @@ -26836,10 +26865,11 @@ | |
| 26865 | rc = unixMapfile(pFile, -1); |
| 26866 | } |
| 26867 | } |
| 26868 | return rc; |
| 26869 | } |
| 26870 | #endif |
| 26871 | #ifdef SQLITE_DEBUG |
| 26872 | /* The pager calls this method to signal that it has done |
| 26873 | ** a rollback and that the database is therefore unchanged and |
| 26874 | ** it hence it is OK for the transaction change counter to be |
| 26875 | ** unchanged. |
| @@ -27646,26 +27676,24 @@ | |
| 27676 | # define unixShmLock 0 |
| 27677 | # define unixShmBarrier 0 |
| 27678 | # define unixShmUnmap 0 |
| 27679 | #endif /* #ifndef SQLITE_OMIT_WAL */ |
| 27680 | |
| 27681 | #if SQLITE_MAX_MMAP_SIZE>0 |
| 27682 | /* |
| 27683 | ** If it is currently memory mapped, unmap file pFd. |
| 27684 | */ |
| 27685 | static void unixUnmapfile(unixFile *pFd){ |
| 27686 | assert( pFd->nFetchOut==0 ); |
| 27687 | if( pFd->pMapRegion ){ |
| 27688 | osMunmap(pFd->pMapRegion, pFd->mmapSizeActual); |
| 27689 | pFd->pMapRegion = 0; |
| 27690 | pFd->mmapSize = 0; |
| 27691 | pFd->mmapSizeActual = 0; |
| 27692 | } |
| 27693 | } |
| 27694 | |
| 27695 | /* |
| 27696 | ** Return the system page size. |
| 27697 | */ |
| 27698 | static int unixGetPagesize(void){ |
| 27699 | #if HAVE_MREMAP |
| @@ -27674,13 +27702,11 @@ | |
| 27702 | return getpagesize(); |
| 27703 | #else |
| 27704 | return (int)sysconf(_SC_PAGESIZE); |
| 27705 | #endif |
| 27706 | } |
| 27707 | |
| 27708 | /* |
| 27709 | ** Attempt to set the size of the memory mapping maintained by file |
| 27710 | ** descriptor pFd to nNew bytes. Any existing mapping is discarded. |
| 27711 | ** |
| 27712 | ** If successful, this function sets the following variables: |
| @@ -27761,11 +27787,10 @@ | |
| 27787 | pFd->mmapSizeMax = 0; |
| 27788 | } |
| 27789 | pFd->pMapRegion = (void *)pNew; |
| 27790 | pFd->mmapSize = pFd->mmapSizeActual = nNew; |
| 27791 | } |
| 27792 | |
| 27793 | /* |
| 27794 | ** Memory map or remap the file opened by file-descriptor pFd (if the file |
| 27795 | ** is already mapped, the existing mapping is replaced by the new). Or, if |
| 27796 | ** there already exists a mapping for this file, and there are still |
| @@ -27780,11 +27805,10 @@ | |
| 27805 | ** SQLITE_OK is returned if no error occurs (even if the mapping is not |
| 27806 | ** recreated as a result of outstanding references) or an SQLite error |
| 27807 | ** code otherwise. |
| 27808 | */ |
| 27809 | static int unixMapfile(unixFile *pFd, i64 nByte){ |
| 27810 | i64 nMap = nByte; |
| 27811 | int rc; |
| 27812 | |
| 27813 | assert( nMap>=0 || pFd->nFetchOut==0 ); |
| 27814 | if( pFd->nFetchOut>0 ) return SQLITE_OK; |
| @@ -27806,14 +27830,14 @@ | |
| 27830 | unixRemapfile(pFd, nMap); |
| 27831 | }else{ |
| 27832 | unixUnmapfile(pFd); |
| 27833 | } |
| 27834 | } |
| 27835 | |
| 27836 | return SQLITE_OK; |
| 27837 | } |
| 27838 | #endif /* SQLITE_MAX_MMAP_SIZE>0 */ |
| 27839 | |
| 27840 | /* |
| 27841 | ** If possible, return a pointer to a mapping of file fd starting at offset |
| 27842 | ** iOff. The mapping must be valid for at least nAmt bytes. |
| 27843 | ** |
| @@ -27858,10 +27882,11 @@ | |
| 27882 | */ |
| 27883 | static int unixUnfetch(sqlite3_file *fd, i64 iOff, void *p){ |
| 27884 | unixFile *pFd = (unixFile *)fd; /* The underlying database file */ |
| 27885 | UNUSED_PARAMETER(iOff); |
| 27886 | |
| 27887 | #if SQLITE_MAX_MMAP_SIZE>0 |
| 27888 | /* If p==0 (unmap the entire file) then there must be no outstanding |
| 27889 | ** xFetch references. Or, if p!=0 (meaning it is an xFetch reference), |
| 27890 | ** then there must be at least one outstanding. */ |
| 27891 | assert( (p==0)==(pFd->nFetchOut==0) ); |
| 27892 | |
| @@ -27873,10 +27898,11 @@ | |
| 27898 | }else{ |
| 27899 | unixUnmapfile(pFd); |
| 27900 | } |
| 27901 | |
| 27902 | assert( pFd->nFetchOut>=0 ); |
| 27903 | #endif |
| 27904 | return SQLITE_OK; |
| 27905 | } |
| 27906 | |
| 27907 | /* |
| 27908 | ** Here ends the implementation of all sqlite3_file methods. |
| @@ -28204,11 +28230,13 @@ | |
| 28230 | OSTRACE(("OPEN %-3d %s\n", h, zFilename)); |
| 28231 | pNew->h = h; |
| 28232 | pNew->pVfs = pVfs; |
| 28233 | pNew->zPath = zFilename; |
| 28234 | pNew->ctrlFlags = (u8)ctrlFlags; |
| 28235 | #if SQLITE_MAX_MMAP_SIZE>0 |
| 28236 | pNew->mmapSizeMax = sqlite3GlobalConfig.szMmap; |
| 28237 | #endif |
| 28238 | if( sqlite3_uri_boolean(((ctrlFlags & UNIXFILE_URI) ? zFilename : 0), |
| 28239 | "psow", SQLITE_POWERSAFE_OVERWRITE) ){ |
| 28240 | pNew->ctrlFlags |= UNIXFILE_PSOW; |
| 28241 | } |
| 28242 | if( strcmp(pVfs->zName,"unix-excl")==0 ){ |
| @@ -30705,11 +30733,11 @@ | |
| 30733 | /* |
| 30734 | ** Compiling and using WAL mode requires several APIs that are only |
| 30735 | ** available in Windows platforms based on the NT kernel. |
| 30736 | */ |
| 30737 | #if !SQLITE_OS_WINNT && !defined(SQLITE_OMIT_WAL) |
| 30738 | # error "WAL mode requires support from the Windows NT kernel, compile\ |
| 30739 | with SQLITE_OMIT_WAL." |
| 30740 | #endif |
| 30741 | |
| 30742 | /* |
| 30743 | ** Are most of the Win32 ANSI APIs available (i.e. with certain exceptions |
| @@ -30725,10 +30753,70 @@ | |
| 30753 | */ |
| 30754 | #if SQLITE_OS_WINCE || SQLITE_OS_WINNT || SQLITE_OS_WINRT |
| 30755 | # define SQLITE_WIN32_HAS_WIDE |
| 30756 | #endif |
| 30757 | |
| 30758 | /* |
| 30759 | ** Maximum pathname length (in chars) for Win32. This should normally be |
| 30760 | ** MAX_PATH. |
| 30761 | */ |
| 30762 | #ifndef SQLITE_WIN32_MAX_PATH_CHARS |
| 30763 | # define SQLITE_WIN32_MAX_PATH_CHARS (MAX_PATH) |
| 30764 | #endif |
| 30765 | |
| 30766 | /* |
| 30767 | ** Maximum pathname length (in chars) for WinNT. This should normally be |
| 30768 | ** 32767. |
| 30769 | */ |
| 30770 | #ifndef SQLITE_WINNT_MAX_PATH_CHARS |
| 30771 | # define SQLITE_WINNT_MAX_PATH_CHARS (32767) |
| 30772 | #endif |
| 30773 | |
| 30774 | /* |
| 30775 | ** Maximum pathname length (in bytes) for Win32. The MAX_PATH macro is in |
| 30776 | ** characters, so we allocate 3 bytes per character assuming worst-case of |
| 30777 | ** 4-bytes-per-character for UTF8. |
| 30778 | */ |
| 30779 | #ifndef SQLITE_WIN32_MAX_PATH_BYTES |
| 30780 | # define SQLITE_WIN32_MAX_PATH_BYTES (SQLITE_WIN32_MAX_PATH_CHARS*4) |
| 30781 | #endif |
| 30782 | |
| 30783 | /* |
| 30784 | ** Maximum pathname length (in bytes) for WinNT. This should normally be |
| 30785 | ** 32767 * sizeof(WCHAR). |
| 30786 | */ |
| 30787 | #ifndef SQLITE_WINNT_MAX_PATH_BYTES |
| 30788 | # define SQLITE_WINNT_MAX_PATH_BYTES \ |
| 30789 | (sizeof(WCHAR) * SQLITE_WINNT_MAX_PATH_CHARS) |
| 30790 | #endif |
| 30791 | |
| 30792 | /* |
| 30793 | ** Maximum error message length (in chars) for WinRT. |
| 30794 | */ |
| 30795 | #ifndef SQLITE_WIN32_MAX_ERRMSG_CHARS |
| 30796 | # define SQLITE_WIN32_MAX_ERRMSG_CHARS (1024) |
| 30797 | #endif |
| 30798 | |
| 30799 | /* |
| 30800 | ** Returns non-zero if the character should be treated as a directory |
| 30801 | ** separator. |
| 30802 | */ |
| 30803 | #ifndef winIsDirSep |
| 30804 | # define winIsDirSep(a) (((a) == '/') || ((a) == '\\')) |
| 30805 | #endif |
| 30806 | |
| 30807 | /* |
| 30808 | ** Returns the string that should be used as the directory separator. |
| 30809 | */ |
| 30810 | #ifndef winGetDirDep |
| 30811 | # ifdef __CYGWIN__ |
| 30812 | # define winGetDirDep() "/" |
| 30813 | # else |
| 30814 | # define winGetDirDep() "\\" |
| 30815 | # endif |
| 30816 | #endif |
| 30817 | |
| 30818 | /* |
| 30819 | ** Do we need to manually define the Win32 file mapping APIs for use with WAL |
| 30820 | ** mode (e.g. these APIs are available in the Windows CE SDK; however, they |
| 30821 | ** are not present in the header file)? |
| 30822 | */ |
| @@ -31732,15 +31820,15 @@ | |
| 31820 | ** this routine is used to determine if the host is Win95/98/ME or |
| 31821 | ** WinNT/2K/XP so that we will know whether or not we can safely call |
| 31822 | ** the LockFileEx() API. |
| 31823 | */ |
| 31824 | #if SQLITE_OS_WINCE || SQLITE_OS_WINRT |
| 31825 | # define osIsNT() (1) |
| 31826 | #elif !defined(SQLITE_WIN32_HAS_WIDE) |
| 31827 | # define osIsNT() (0) |
| 31828 | #else |
| 31829 | static int osIsNT(void){ |
| 31830 | if( sqlite3_os_type==0 ){ |
| 31831 | OSVERSIONINFOA sInfo; |
| 31832 | sInfo.dwOSVersionInfoSize = sizeof(sInfo); |
| 31833 | osGetVersionExA(&sInfo); |
| 31834 | sqlite3_os_type = sInfo.dwPlatformId==VER_PLATFORM_WIN32_NT ? 2 : 1; |
| @@ -31947,11 +32035,11 @@ | |
| 32035 | /* |
| 32036 | ** Convert a UTF-8 string to Microsoft Unicode (UTF-16?). |
| 32037 | ** |
| 32038 | ** Space to hold the returned string is obtained from malloc. |
| 32039 | */ |
| 32040 | static LPWSTR winUtf8ToUnicode(const char *zFilename){ |
| 32041 | int nChar; |
| 32042 | LPWSTR zWideFilename; |
| 32043 | |
| 32044 | nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0); |
| 32045 | if( nChar==0 ){ |
| @@ -31972,11 +32060,11 @@ | |
| 32060 | |
| 32061 | /* |
| 32062 | ** Convert Microsoft Unicode to UTF-8. Space to hold the returned string is |
| 32063 | ** obtained from sqlite3_malloc(). |
| 32064 | */ |
| 32065 | static char *winUnicodeToUtf8(LPCWSTR zWideFilename){ |
| 32066 | int nByte; |
| 32067 | char *zFilename; |
| 32068 | |
| 32069 | nByte = osWideCharToMultiByte(CP_UTF8, 0, zWideFilename, -1, 0, 0, 0, 0); |
| 32070 | if( nByte == 0 ){ |
| @@ -32000,11 +32088,11 @@ | |
| 32088 | ** current codepage settings for file apis. |
| 32089 | ** |
| 32090 | ** Space to hold the returned string is obtained |
| 32091 | ** from sqlite3_malloc. |
| 32092 | */ |
| 32093 | static LPWSTR winMbcsToUnicode(const char *zFilename){ |
| 32094 | int nByte; |
| 32095 | LPWSTR zMbcsFilename; |
| 32096 | int codepage = osAreFileApisANSI() ? CP_ACP : CP_OEMCP; |
| 32097 | |
| 32098 | nByte = osMultiByteToWideChar(codepage, 0, zFilename, -1, NULL, |
| @@ -32030,11 +32118,11 @@ | |
| 32118 | ** user's ANSI codepage. |
| 32119 | ** |
| 32120 | ** Space to hold the returned string is obtained from |
| 32121 | ** sqlite3_malloc(). |
| 32122 | */ |
| 32123 | static char *winUnicodeToMbcs(LPCWSTR zWideFilename){ |
| 32124 | int nByte; |
| 32125 | char *zFilename; |
| 32126 | int codepage = osAreFileApisANSI() ? CP_ACP : CP_OEMCP; |
| 32127 | |
| 32128 | nByte = osWideCharToMultiByte(codepage, 0, zWideFilename, -1, 0, 0, 0, 0); |
| @@ -32060,15 +32148,15 @@ | |
| 32148 | */ |
| 32149 | SQLITE_API char *sqlite3_win32_mbcs_to_utf8(const char *zFilename){ |
| 32150 | char *zFilenameUtf8; |
| 32151 | LPWSTR zTmpWide; |
| 32152 | |
| 32153 | zTmpWide = winMbcsToUnicode(zFilename); |
| 32154 | if( zTmpWide==0 ){ |
| 32155 | return 0; |
| 32156 | } |
| 32157 | zFilenameUtf8 = winUnicodeToUtf8(zTmpWide); |
| 32158 | sqlite3_free(zTmpWide); |
| 32159 | return zFilenameUtf8; |
| 32160 | } |
| 32161 | |
| 32162 | /* |
| @@ -32077,15 +32165,15 @@ | |
| 32165 | */ |
| 32166 | SQLITE_API char *sqlite3_win32_utf8_to_mbcs(const char *zFilename){ |
| 32167 | char *zFilenameMbcs; |
| 32168 | LPWSTR zTmpWide; |
| 32169 | |
| 32170 | zTmpWide = winUtf8ToUnicode(zFilename); |
| 32171 | if( zTmpWide==0 ){ |
| 32172 | return 0; |
| 32173 | } |
| 32174 | zFilenameMbcs = winUnicodeToMbcs(zTmpWide); |
| 32175 | sqlite3_free(zTmpWide); |
| 32176 | return zFilenameMbcs; |
| 32177 | } |
| 32178 | |
| 32179 | /* |
| @@ -32111,11 +32199,11 @@ | |
| 32199 | ); |
| 32200 | assert( !ppDirectory || sqlite3MemdebugHasType(*ppDirectory, MEMTYPE_HEAP) ); |
| 32201 | if( ppDirectory ){ |
| 32202 | char *zValueUtf8 = 0; |
| 32203 | if( zValue && zValue[0] ){ |
| 32204 | zValueUtf8 = winUnicodeToUtf8(zValue); |
| 32205 | if ( zValueUtf8==0 ){ |
| 32206 | return SQLITE_NOMEM; |
| 32207 | } |
| 32208 | } |
| 32209 | sqlite3_free(*ppDirectory); |
| @@ -32124,32 +32212,32 @@ | |
| 32212 | } |
| 32213 | return SQLITE_ERROR; |
| 32214 | } |
| 32215 | |
| 32216 | /* |
| 32217 | ** The return value of winGetLastErrorMsg |
| 32218 | ** is zero if the error message fits in the buffer, or non-zero |
| 32219 | ** otherwise (if the message was truncated). |
| 32220 | */ |
| 32221 | static int winGetLastErrorMsg(DWORD lastErrno, int nBuf, char *zBuf){ |
| 32222 | /* FormatMessage returns 0 on failure. Otherwise it |
| 32223 | ** returns the number of TCHARs written to the output |
| 32224 | ** buffer, excluding the terminating null char. |
| 32225 | */ |
| 32226 | DWORD dwLen = 0; |
| 32227 | char *zOut = 0; |
| 32228 | |
| 32229 | if( osIsNT() ){ |
| 32230 | #if SQLITE_OS_WINRT |
| 32231 | WCHAR zTempWide[SQLITE_WIN32_MAX_ERRMSG_CHARS+1]; |
| 32232 | dwLen = osFormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | |
| 32233 | FORMAT_MESSAGE_IGNORE_INSERTS, |
| 32234 | NULL, |
| 32235 | lastErrno, |
| 32236 | 0, |
| 32237 | zTempWide, |
| 32238 | SQLITE_WIN32_MAX_ERRMSG_CHARS, |
| 32239 | 0); |
| 32240 | #else |
| 32241 | LPWSTR zTempWide = NULL; |
| 32242 | dwLen = osFormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | |
| 32243 | FORMAT_MESSAGE_FROM_SYSTEM | |
| @@ -32162,11 +32250,11 @@ | |
| 32250 | 0); |
| 32251 | #endif |
| 32252 | if( dwLen > 0 ){ |
| 32253 | /* allocate a buffer and convert to UTF8 */ |
| 32254 | sqlite3BeginBenignMalloc(); |
| 32255 | zOut = winUnicodeToUtf8(zTempWide); |
| 32256 | sqlite3EndBenignMalloc(); |
| 32257 | #if !SQLITE_OS_WINRT |
| 32258 | /* free the system buffer allocated by FormatMessage */ |
| 32259 | osLocalFree(zTempWide); |
| 32260 | #endif |
| @@ -32230,11 +32318,11 @@ | |
| 32318 | ){ |
| 32319 | char zMsg[500]; /* Human readable error text */ |
| 32320 | int i; /* Loop counter */ |
| 32321 | |
| 32322 | zMsg[0] = 0; |
| 32323 | winGetLastErrorMsg(lastErrno, sizeof(zMsg), zMsg); |
| 32324 | assert( errcode!=SQLITE_OK ); |
| 32325 | if( zPath==0 ) zPath = ""; |
| 32326 | for(i=0; zMsg[i] && zMsg[i]!='\r' && zMsg[i]!='\n'; i++){} |
| 32327 | zMsg[i] = 0; |
| 32328 | sqlite3_log(errcode, |
| @@ -32255,30 +32343,30 @@ | |
| 32343 | # define SQLITE_WIN32_IOERR_RETRY 10 |
| 32344 | #endif |
| 32345 | #ifndef SQLITE_WIN32_IOERR_RETRY_DELAY |
| 32346 | # define SQLITE_WIN32_IOERR_RETRY_DELAY 25 |
| 32347 | #endif |
| 32348 | static int winIoerrRetry = SQLITE_WIN32_IOERR_RETRY; |
| 32349 | static int winIoerrRetryDelay = SQLITE_WIN32_IOERR_RETRY_DELAY; |
| 32350 | |
| 32351 | /* |
| 32352 | ** If a ReadFile() or WriteFile() error occurs, invoke this routine |
| 32353 | ** to see if it should be retried. Return TRUE to retry. Return FALSE |
| 32354 | ** to give up with an error. |
| 32355 | */ |
| 32356 | static int winRetryIoerr(int *pnRetry, DWORD *pError){ |
| 32357 | DWORD e = osGetLastError(); |
| 32358 | if( *pnRetry>=winIoerrRetry ){ |
| 32359 | if( pError ){ |
| 32360 | *pError = e; |
| 32361 | } |
| 32362 | return 0; |
| 32363 | } |
| 32364 | if( e==ERROR_ACCESS_DENIED || |
| 32365 | e==ERROR_LOCK_VIOLATION || |
| 32366 | e==ERROR_SHARING_VIOLATION ){ |
| 32367 | sqlite3_win32_sleep(winIoerrRetryDelay*(1+*pnRetry)); |
| 32368 | ++*pnRetry; |
| 32369 | return 1; |
| 32370 | } |
| 32371 | if( pError ){ |
| 32372 | *pError = e; |
| @@ -32287,15 +32375,15 @@ | |
| 32375 | } |
| 32376 | |
| 32377 | /* |
| 32378 | ** Log a I/O error retry episode. |
| 32379 | */ |
| 32380 | static void winLogIoerr(int nRetry){ |
| 32381 | if( nRetry ){ |
| 32382 | sqlite3_log(SQLITE_IOERR, |
| 32383 | "delayed %dms for lock/sharing conflict", |
| 32384 | winIoerrRetryDelay*nRetry*(nRetry+1)/2 |
| 32385 | ); |
| 32386 | } |
| 32387 | } |
| 32388 | |
| 32389 | #if SQLITE_OS_WINCE |
| @@ -32356,11 +32444,11 @@ | |
| 32444 | LPWSTR zName; |
| 32445 | DWORD lastErrno; |
| 32446 | BOOL bLogged = FALSE; |
| 32447 | BOOL bInit = TRUE; |
| 32448 | |
| 32449 | zName = winUtf8ToUnicode(zFilename); |
| 32450 | if( zName==0 ){ |
| 32451 | /* out of memory */ |
| 32452 | return SQLITE_IOERR_NOMEM; |
| 32453 | } |
| 32454 | |
| @@ -32629,11 +32717,11 @@ | |
| 32717 | ** API LockFile. |
| 32718 | */ |
| 32719 | return winceLockFile(phFile, offsetLow, offsetHigh, |
| 32720 | numBytesLow, numBytesHigh); |
| 32721 | #else |
| 32722 | if( osIsNT() ){ |
| 32723 | OVERLAPPED ovlp; |
| 32724 | memset(&ovlp, 0, sizeof(OVERLAPPED)); |
| 32725 | ovlp.Offset = offsetLow; |
| 32726 | ovlp.OffsetHigh = offsetHigh; |
| 32727 | return osLockFileEx(*phFile, flags, 0, numBytesLow, numBytesHigh, &ovlp); |
| @@ -32660,11 +32748,11 @@ | |
| 32748 | ** API UnlockFile. |
| 32749 | */ |
| 32750 | return winceUnlockFile(phFile, offsetLow, offsetHigh, |
| 32751 | numBytesLow, numBytesHigh); |
| 32752 | #else |
| 32753 | if( osIsNT() ){ |
| 32754 | OVERLAPPED ovlp; |
| 32755 | memset(&ovlp, 0, sizeof(OVERLAPPED)); |
| 32756 | ovlp.Offset = offsetLow; |
| 32757 | ovlp.OffsetHigh = offsetHigh; |
| 32758 | return osUnlockFileEx(*phFile, 0, numBytesLow, numBytesHigh, &ovlp); |
| @@ -32690,11 +32778,11 @@ | |
| 32778 | /* |
| 32779 | ** Move the current position of the file handle passed as the first |
| 32780 | ** argument to offset iOffset within the file. If successful, return 0. |
| 32781 | ** Otherwise, set pFile->lastErrno and return non-zero. |
| 32782 | */ |
| 32783 | static int winSeekFile(winFile *pFile, sqlite3_int64 iOffset){ |
| 32784 | #if !SQLITE_OS_WINRT |
| 32785 | LONG upperBits; /* Most sig. 32 bits of new offset */ |
| 32786 | LONG lowerBits; /* Least sig. 32 bits of new offset */ |
| 32787 | DWORD dwRet; /* Value returned by SetFilePointer() */ |
| 32788 | DWORD lastErrno; /* Value returned by GetLastError() */ |
| @@ -32715,11 +32803,11 @@ | |
| 32803 | |
| 32804 | if( (dwRet==INVALID_SET_FILE_POINTER |
| 32805 | && ((lastErrno = osGetLastError())!=NO_ERROR)) ){ |
| 32806 | pFile->lastErrno = lastErrno; |
| 32807 | winLogError(SQLITE_IOERR_SEEK, pFile->lastErrno, |
| 32808 | "winSeekFile", pFile->zPath); |
| 32809 | OSTRACE(("SEEK file=%p, rc=SQLITE_IOERR_SEEK\n", pFile->h)); |
| 32810 | return 1; |
| 32811 | } |
| 32812 | |
| 32813 | OSTRACE(("SEEK file=%p, rc=SQLITE_OK\n", pFile->h)); |
| @@ -32736,11 +32824,11 @@ | |
| 32824 | bRet = osSetFilePointerEx(pFile->h, x, 0, FILE_BEGIN); |
| 32825 | |
| 32826 | if(!bRet){ |
| 32827 | pFile->lastErrno = osGetLastError(); |
| 32828 | winLogError(SQLITE_IOERR_SEEK, pFile->lastErrno, |
| 32829 | "winSeekFile", pFile->zPath); |
| 32830 | OSTRACE(("SEEK file=%p, rc=SQLITE_IOERR_SEEK\n", pFile->h)); |
| 32831 | return 1; |
| 32832 | } |
| 32833 | |
| 32834 | OSTRACE(("SEEK file=%p, rc=SQLITE_OK\n", pFile->h)); |
| @@ -32851,11 +32939,11 @@ | |
| 32939 | } |
| 32940 | } |
| 32941 | #endif |
| 32942 | |
| 32943 | #if SQLITE_OS_WINCE |
| 32944 | if( winSeekFile(pFile, offset) ){ |
| 32945 | OSTRACE(("READ file=%p, rc=SQLITE_FULL\n", pFile->h)); |
| 32946 | return SQLITE_FULL; |
| 32947 | } |
| 32948 | while( !osReadFile(pFile->h, pBuf, amt, &nRead, 0) ){ |
| 32949 | #else |
| @@ -32864,17 +32952,17 @@ | |
| 32952 | overlapped.OffsetHigh = (LONG)((offset>>32) & 0x7fffffff); |
| 32953 | while( !osReadFile(pFile->h, pBuf, amt, &nRead, &overlapped) && |
| 32954 | osGetLastError()!=ERROR_HANDLE_EOF ){ |
| 32955 | #endif |
| 32956 | DWORD lastErrno; |
| 32957 | if( winRetryIoerr(&nRetry, &lastErrno) ) continue; |
| 32958 | pFile->lastErrno = lastErrno; |
| 32959 | OSTRACE(("READ file=%p, rc=SQLITE_IOERR_READ\n", pFile->h)); |
| 32960 | return winLogError(SQLITE_IOERR_READ, pFile->lastErrno, |
| 32961 | "winRead", pFile->zPath); |
| 32962 | } |
| 32963 | winLogIoerr(nRetry); |
| 32964 | if( nRead<(DWORD)amt ){ |
| 32965 | /* Unread parts of the buffer must be zero-filled */ |
| 32966 | memset(&((char*)pBuf)[nRead], 0, amt-nRead); |
| 32967 | OSTRACE(("READ file=%p, rc=SQLITE_IOERR_SHORT_READ\n", pFile->h)); |
| 32968 | return SQLITE_IOERR_SHORT_READ; |
| @@ -32923,11 +33011,11 @@ | |
| 33011 | } |
| 33012 | } |
| 33013 | #endif |
| 33014 | |
| 33015 | #if SQLITE_OS_WINCE |
| 33016 | rc = winSeekFile(pFile, offset); |
| 33017 | if( rc==0 ){ |
| 33018 | #else |
| 33019 | { |
| 33020 | #endif |
| 33021 | #if !SQLITE_OS_WINCE |
| @@ -32948,11 +33036,11 @@ | |
| 33036 | #if SQLITE_OS_WINCE |
| 33037 | if( !osWriteFile(pFile->h, aRem, nRem, &nWrite, 0) ){ |
| 33038 | #else |
| 33039 | if( !osWriteFile(pFile->h, aRem, nRem, &nWrite, &overlapped) ){ |
| 33040 | #endif |
| 33041 | if( winRetryIoerr(&nRetry, &lastErrno) ) continue; |
| 33042 | break; |
| 33043 | } |
| 33044 | assert( nWrite==0 || nWrite<=(DWORD)nRem ); |
| 33045 | if( nWrite==0 || nWrite>(DWORD)nRem ){ |
| 33046 | lastErrno = osGetLastError(); |
| @@ -32980,11 +33068,11 @@ | |
| 33068 | } |
| 33069 | OSTRACE(("WRITE file=%p, rc=SQLITE_IOERR_WRITE\n", pFile->h)); |
| 33070 | return winLogError(SQLITE_IOERR_WRITE, pFile->lastErrno, |
| 33071 | "winWrite", pFile->zPath); |
| 33072 | }else{ |
| 33073 | winLogIoerr(nRetry); |
| 33074 | } |
| 33075 | OSTRACE(("WRITE file=%p, rc=SQLITE_OK\n", pFile->h)); |
| 33076 | return SQLITE_OK; |
| 33077 | } |
| 33078 | |
| @@ -33009,11 +33097,11 @@ | |
| 33097 | if( pFile->szChunk>0 ){ |
| 33098 | nByte = ((nByte + pFile->szChunk - 1)/pFile->szChunk) * pFile->szChunk; |
| 33099 | } |
| 33100 | |
| 33101 | /* SetEndOfFile() returns non-zero when successful, or zero when it fails. */ |
| 33102 | if( winSeekFile(pFile, nByte) ){ |
| 33103 | rc = winLogError(SQLITE_IOERR_TRUNCATE, pFile->lastErrno, |
| 33104 | "winTruncate1", pFile->zPath); |
| 33105 | }else if( 0==osSetEndOfFile(pFile->h) && |
| 33106 | ((lastErrno = osGetLastError())!=ERROR_USER_MAPPED_FILE) ){ |
| 33107 | pFile->lastErrno = lastErrno; |
| @@ -33090,10 +33178,11 @@ | |
| 33178 | |
| 33179 | /* If we compiled with the SQLITE_NO_SYNC flag, then syncing is a |
| 33180 | ** no-op |
| 33181 | */ |
| 33182 | #ifdef SQLITE_NO_SYNC |
| 33183 | OSTRACE(("SYNC-NOP file=%p, rc=SQLITE_OK\n", pFile->h)); |
| 33184 | return SQLITE_OK; |
| 33185 | #else |
| 33186 | rc = osFlushFileBuffers(pFile->h); |
| 33187 | SimulateIOError( rc=FALSE ); |
| 33188 | if( rc ){ |
| @@ -33187,14 +33276,14 @@ | |
| 33276 | /* |
| 33277 | ** Acquire a reader lock. |
| 33278 | ** Different API routines are called depending on whether or not this |
| 33279 | ** is Win9x or WinNT. |
| 33280 | */ |
| 33281 | static int winGetReadLock(winFile *pFile){ |
| 33282 | int res; |
| 33283 | OSTRACE(("READ-LOCK file=%p, lock=%d\n", pFile->h, pFile->locktype)); |
| 33284 | if( osIsNT() ){ |
| 33285 | #if SQLITE_OS_WINCE |
| 33286 | /* |
| 33287 | ** NOTE: Windows CE is handled differently here due its lack of the Win32 |
| 33288 | ** API LockFileEx. |
| 33289 | */ |
| @@ -33222,15 +33311,15 @@ | |
| 33311 | } |
| 33312 | |
| 33313 | /* |
| 33314 | ** Undo a readlock |
| 33315 | */ |
| 33316 | static int winUnlockReadLock(winFile *pFile){ |
| 33317 | int res; |
| 33318 | DWORD lastErrno; |
| 33319 | OSTRACE(("READ-UNLOCK file=%p, lock=%d\n", pFile->h, pFile->locktype)); |
| 33320 | if( osIsNT() ){ |
| 33321 | res = winUnlockFile(&pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0); |
| 33322 | } |
| 33323 | #ifdef SQLITE_WIN32_HAS_ANSI |
| 33324 | else{ |
| 33325 | res = winUnlockFile(&pFile->h, SHARED_FIRST+pFile->sharedLockByte, 0, 1, 0); |
| @@ -33237,11 +33326,11 @@ | |
| 33326 | } |
| 33327 | #endif |
| 33328 | if( res==0 && ((lastErrno = osGetLastError())!=ERROR_NOT_LOCKED) ){ |
| 33329 | pFile->lastErrno = lastErrno; |
| 33330 | winLogError(SQLITE_IOERR_UNLOCK, pFile->lastErrno, |
| 33331 | "winUnlockReadLock", pFile->zPath); |
| 33332 | } |
| 33333 | OSTRACE(("READ-UNLOCK file=%p, rc=%s\n", pFile->h, sqlite3ErrName(res))); |
| 33334 | return res; |
| 33335 | } |
| 33336 | |
| @@ -33328,11 +33417,11 @@ | |
| 33417 | |
| 33418 | /* Acquire a shared lock |
| 33419 | */ |
| 33420 | if( locktype==SHARED_LOCK && res ){ |
| 33421 | assert( pFile->locktype==NO_LOCK ); |
| 33422 | res = winGetReadLock(pFile); |
| 33423 | if( res ){ |
| 33424 | newLocktype = SHARED_LOCK; |
| 33425 | }else{ |
| 33426 | lastErrno = osGetLastError(); |
| 33427 | } |
| @@ -33359,18 +33448,18 @@ | |
| 33448 | |
| 33449 | /* Acquire an EXCLUSIVE lock |
| 33450 | */ |
| 33451 | if( locktype==EXCLUSIVE_LOCK && res ){ |
| 33452 | assert( pFile->locktype>=SHARED_LOCK ); |
| 33453 | res = winUnlockReadLock(pFile); |
| 33454 | res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS, SHARED_FIRST, 0, |
| 33455 | SHARED_SIZE, 0); |
| 33456 | if( res ){ |
| 33457 | newLocktype = EXCLUSIVE_LOCK; |
| 33458 | }else{ |
| 33459 | lastErrno = osGetLastError(); |
| 33460 | winGetReadLock(pFile); |
| 33461 | } |
| 33462 | } |
| 33463 | |
| 33464 | /* If we are holding a PENDING lock that ought to be released, then |
| 33465 | ** release it now. |
| @@ -33383,14 +33472,14 @@ | |
| 33472 | ** return the appropriate result code. |
| 33473 | */ |
| 33474 | if( res ){ |
| 33475 | rc = SQLITE_OK; |
| 33476 | }else{ |
| 33477 | pFile->lastErrno = lastErrno; |
| 33478 | rc = SQLITE_BUSY; |
| 33479 | OSTRACE(("LOCK-FAIL file=%p, wanted=%d, got=%d\n", |
| 33480 | pFile->h, locktype, newLocktype)); |
| 33481 | } |
| 33482 | pFile->locktype = (u8)newLocktype; |
| 33483 | OSTRACE(("LOCK file=%p, lock=%d, rc=%s\n", |
| 33484 | pFile->h, pFile->locktype, sqlite3ErrName(rc))); |
| 33485 | return rc; |
| @@ -33446,11 +33535,11 @@ | |
| 33535 | OSTRACE(("UNLOCK file=%p, oldLock=%d(%d), newLock=%d\n", |
| 33536 | pFile->h, pFile->locktype, pFile->sharedLockByte, locktype)); |
| 33537 | type = pFile->locktype; |
| 33538 | if( type>=EXCLUSIVE_LOCK ){ |
| 33539 | winUnlockFile(&pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0); |
| 33540 | if( locktype==SHARED_LOCK && !winGetReadLock(pFile) ){ |
| 33541 | /* This should never happen. We should always be able to |
| 33542 | ** reacquire the read lock */ |
| 33543 | rc = winLogError(SQLITE_IOERR_UNLOCK, osGetLastError(), |
| 33544 | "winUnlock", pFile->zPath); |
| 33545 | } |
| @@ -33457,11 +33546,11 @@ | |
| 33546 | } |
| 33547 | if( type>=RESERVED_LOCK ){ |
| 33548 | winUnlockFile(&pFile->h, RESERVED_BYTE, 0, 1, 0); |
| 33549 | } |
| 33550 | if( locktype==NO_LOCK && type>=SHARED_LOCK ){ |
| 33551 | winUnlockReadLock(pFile); |
| 33552 | } |
| 33553 | if( type>=PENDING_LOCK ){ |
| 33554 | winUnlockFile(&pFile->h, PENDING_BYTE, 0, 1, 0); |
| 33555 | } |
| 33556 | pFile->locktype = (u8)locktype; |
| @@ -33485,11 +33574,11 @@ | |
| 33574 | pFile->ctrlFlags |= mask; |
| 33575 | } |
| 33576 | } |
| 33577 | |
| 33578 | /* Forward declaration */ |
| 33579 | static int winGetTempname(sqlite3_vfs *, char **); |
| 33580 | #if SQLITE_MAX_MMAP_SIZE>0 |
| 33581 | static int winMapfile(winFile*, sqlite3_int64); |
| 33582 | #endif |
| 33583 | |
| 33584 | /* |
| @@ -33548,30 +33637,30 @@ | |
| 33637 | return SQLITE_OK; |
| 33638 | } |
| 33639 | case SQLITE_FCNTL_WIN32_AV_RETRY: { |
| 33640 | int *a = (int*)pArg; |
| 33641 | if( a[0]>0 ){ |
| 33642 | winIoerrRetry = a[0]; |
| 33643 | }else{ |
| 33644 | a[0] = winIoerrRetry; |
| 33645 | } |
| 33646 | if( a[1]>0 ){ |
| 33647 | winIoerrRetryDelay = a[1]; |
| 33648 | }else{ |
| 33649 | a[1] = winIoerrRetryDelay; |
| 33650 | } |
| 33651 | OSTRACE(("FCNTL file=%p, rc=SQLITE_OK\n", pFile->h)); |
| 33652 | return SQLITE_OK; |
| 33653 | } |
| 33654 | case SQLITE_FCNTL_TEMPFILENAME: { |
| 33655 | char *zTFile = 0; |
| 33656 | int rc = winGetTempname(pFile->pVfs, &zTFile); |
| 33657 | if( rc==SQLITE_OK ){ |
| 33658 | *(char**)pArg = zTFile; |
| 33659 | } |
| 33660 | OSTRACE(("FCNTL file=%p, rc=%d\n", pFile->h, rc)); |
| 33661 | return rc; |
| 33662 | } |
| 33663 | #if SQLITE_MAX_MMAP_SIZE>0 |
| 33664 | case SQLITE_FCNTL_MMAP_SIZE: { |
| 33665 | i64 newLimit = *(i64*)pArg; |
| 33666 | int rc = SQLITE_OK; |
| @@ -34529,14 +34618,14 @@ | |
| 34618 | ** Convert a UTF-8 filename into whatever form the underlying |
| 34619 | ** operating system wants filenames in. Space to hold the result |
| 34620 | ** is obtained from malloc and must be freed by the calling |
| 34621 | ** function. |
| 34622 | */ |
| 34623 | static void *winConvertUtf8Filename(const char *zFilename){ |
| 34624 | void *zConverted = 0; |
| 34625 | if( osIsNT() ){ |
| 34626 | zConverted = winUtf8ToUnicode(zFilename); |
| 34627 | } |
| 34628 | #ifdef SQLITE_WIN32_HAS_ANSI |
| 34629 | else{ |
| 34630 | zConverted = sqlite3_win32_utf8_to_mbcs(zFilename); |
| 34631 | } |
| @@ -34544,117 +34633,135 @@ | |
| 34633 | /* caller will handle out of memory */ |
| 34634 | return zConverted; |
| 34635 | } |
| 34636 | |
| 34637 | /* |
| 34638 | ** This function returns non-zero if the specified UTF-8 string buffer |
| 34639 | ** ends with a directory separator character. |
| 34640 | */ |
| 34641 | static int winEndsInDirSep(char *zBuf){ |
| 34642 | if( zBuf ){ |
| 34643 | int nLen = sqlite3Strlen30(zBuf); |
| 34644 | return nLen>0 && winIsDirSep(zBuf[nLen-1]); |
| 34645 | } |
| 34646 | return 0; |
| 34647 | } |
| 34648 | |
| 34649 | /* |
| 34650 | ** Create a temporary file name and store the resulting pointer into pzBuf. |
| 34651 | ** The pointer returned in pzBuf must be freed via sqlite3_free(). |
| 34652 | */ |
| 34653 | static int winGetTempname(sqlite3_vfs *pVfs, char **pzBuf){ |
| 34654 | static char zChars[] = |
| 34655 | "abcdefghijklmnopqrstuvwxyz" |
| 34656 | "ABCDEFGHIJKLMNOPQRSTUVWXYZ" |
| 34657 | "0123456789"; |
| 34658 | size_t i, j; |
| 34659 | int nBuf, nLen; |
| 34660 | char *zBuf; |
| 34661 | |
| 34662 | /* It's odd to simulate an io-error here, but really this is just |
| 34663 | ** using the io-error infrastructure to test that SQLite handles this |
| 34664 | ** function failing. |
| 34665 | */ |
| 34666 | SimulateIOError( return SQLITE_IOERR ); |
| 34667 | |
| 34668 | /* Allocate a temporary buffer to store the fully qualified file |
| 34669 | ** name for the temporary file. If this fails, we cannot continue. |
| 34670 | */ |
| 34671 | nBuf = pVfs->mxPathname; |
| 34672 | zBuf = sqlite3MallocZero( nBuf+2 ); |
| 34673 | if( !zBuf ){ |
| 34674 | OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); |
| 34675 | return SQLITE_IOERR_NOMEM; |
| 34676 | } |
| 34677 | |
| 34678 | /* Figure out the effective temporary directory. First, check if one |
| 34679 | ** has been explicitly set by the application; otherwise, use the one |
| 34680 | ** configured by the operating system. |
| 34681 | */ |
| 34682 | assert( nBuf>30 ); |
| 34683 | if( sqlite3_temp_directory ){ |
| 34684 | sqlite3_snprintf(nBuf-30, zBuf, "%s%s", sqlite3_temp_directory, |
| 34685 | winEndsInDirSep(sqlite3_temp_directory) ? "" : |
| 34686 | winGetDirDep()); |
| 34687 | } |
| 34688 | #if !SQLITE_OS_WINRT |
| 34689 | else if( osIsNT() ){ |
| 34690 | char *zMulti; |
| 34691 | LPWSTR zWidePath = sqlite3MallocZero( nBuf*sizeof(WCHAR) ); |
| 34692 | if( !zWidePath ){ |
| 34693 | sqlite3_free(zBuf); |
| 34694 | OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); |
| 34695 | return SQLITE_IOERR_NOMEM; |
| 34696 | } |
| 34697 | if( osGetTempPathW(nBuf, zWidePath)==0 ){ |
| 34698 | sqlite3_free(zWidePath); |
| 34699 | sqlite3_free(zBuf); |
| 34700 | OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_GETTEMPPATH\n")); |
| 34701 | return SQLITE_IOERR_GETTEMPPATH; |
| 34702 | } |
| 34703 | zMulti = winUnicodeToUtf8(zWidePath); |
| 34704 | if( zMulti ){ |
| 34705 | sqlite3_snprintf(nBuf-30, zBuf, "%s", zMulti); |
| 34706 | sqlite3_free(zMulti); |
| 34707 | sqlite3_free(zWidePath); |
| 34708 | }else{ |
| 34709 | sqlite3_free(zWidePath); |
| 34710 | sqlite3_free(zBuf); |
| 34711 | OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); |
| 34712 | return SQLITE_IOERR_NOMEM; |
| 34713 | } |
| 34714 | } |
| 34715 | #ifdef SQLITE_WIN32_HAS_ANSI |
| 34716 | else{ |
| 34717 | char *zUtf8; |
| 34718 | char *zMbcsPath = sqlite3MallocZero( nBuf ); |
| 34719 | if( !zMbcsPath ){ |
| 34720 | sqlite3_free(zBuf); |
| 34721 | OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); |
| 34722 | return SQLITE_IOERR_NOMEM; |
| 34723 | } |
| 34724 | if( osGetTempPathA(nBuf, zMbcsPath)==0 ){ |
| 34725 | sqlite3_free(zBuf); |
| 34726 | OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_GETTEMPPATH\n")); |
| 34727 | return SQLITE_IOERR_GETTEMPPATH; |
| 34728 | } |
| 34729 | zUtf8 = sqlite3_win32_mbcs_to_utf8(zMbcsPath); |
| 34730 | if( zUtf8 ){ |
| 34731 | sqlite3_snprintf(nBuf-30, zBuf, "%s", zUtf8); |
| 34732 | sqlite3_free(zUtf8); |
| 34733 | }else{ |
| 34734 | sqlite3_free(zBuf); |
| 34735 | OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); |
| 34736 | return SQLITE_IOERR_NOMEM; |
| 34737 | } |
| 34738 | } |
| 34739 | #endif /* SQLITE_WIN32_HAS_ANSI */ |
| 34740 | #endif /* !SQLITE_OS_WINRT */ |
| 34741 | |
| 34742 | /* Check that the output buffer is large enough for the temporary file |
| 34743 | ** name. If it is not, return SQLITE_ERROR. |
| 34744 | */ |
| 34745 | nLen = sqlite3Strlen30(zBuf); |
| 34746 | |
| 34747 | if( (nLen + sqlite3Strlen30(SQLITE_TEMP_FILE_PREFIX) + 18) >= nBuf ){ |
| 34748 | sqlite3_free(zBuf); |
| 34749 | OSTRACE(("TEMP-FILENAME rc=SQLITE_ERROR\n")); |
| 34750 | return SQLITE_ERROR; |
| 34751 | } |
| 34752 | |
| 34753 | sqlite3_snprintf(nBuf-18-nLen, zBuf+nLen, SQLITE_TEMP_FILE_PREFIX); |
| 34754 | |
| 34755 | j = sqlite3Strlen30(zBuf); |
| 34756 | sqlite3_randomness(15, &zBuf[j]); |
| 34757 | for(i=0; i<15; i++, j++){ |
| 34758 | zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ]; |
| 34759 | } |
| 34760 | zBuf[j] = 0; |
| 34761 | zBuf[j+1] = 0; |
| 34762 | *pzBuf = zBuf; |
| 34763 | |
| 34764 | OSTRACE(("TEMP-FILENAME name=%s, rc=SQLITE_OK\n", zBuf)); |
| 34765 | return SQLITE_OK; |
| 34766 | } |
| 34767 | |
| @@ -34666,17 +34773,17 @@ | |
| 34773 | static int winIsDir(const void *zConverted){ |
| 34774 | DWORD attr; |
| 34775 | int rc = 0; |
| 34776 | DWORD lastErrno; |
| 34777 | |
| 34778 | if( osIsNT() ){ |
| 34779 | int cnt = 0; |
| 34780 | WIN32_FILE_ATTRIBUTE_DATA sAttrData; |
| 34781 | memset(&sAttrData, 0, sizeof(sAttrData)); |
| 34782 | while( !(rc = osGetFileAttributesExW((LPCWSTR)zConverted, |
| 34783 | GetFileExInfoStandard, |
| 34784 | &sAttrData)) && winRetryIoerr(&cnt, &lastErrno) ){} |
| 34785 | if( !rc ){ |
| 34786 | return 0; /* Invalid name? */ |
| 34787 | } |
| 34788 | attr = sAttrData.dwFileAttributes; |
| 34789 | #if SQLITE_OS_WINCE==0 |
| @@ -34689,11 +34796,11 @@ | |
| 34796 | |
| 34797 | /* |
| 34798 | ** Open a file. |
| 34799 | */ |
| 34800 | static int winOpen( |
| 34801 | sqlite3_vfs *pVfs, /* Used to get maximum path name length */ |
| 34802 | const char *zName, /* Name of the file (UTF-8) */ |
| 34803 | sqlite3_file *id, /* Write the SQLite file handle here */ |
| 34804 | int flags, /* Open mode flags */ |
| 34805 | int *pOutFlags /* Status return flags */ |
| 34806 | ){ |
| @@ -34712,11 +34819,11 @@ | |
| 34819 | int cnt = 0; |
| 34820 | |
| 34821 | /* If argument zPath is a NULL pointer, this function is required to open |
| 34822 | ** a temporary file. Use this buffer to store the file name in. |
| 34823 | */ |
| 34824 | char *zTmpname = 0; /* For temporary filename, if necessary. */ |
| 34825 | |
| 34826 | int rc = SQLITE_OK; /* Function Return Code */ |
| 34827 | #if !defined(NDEBUG) || SQLITE_OS_WINCE |
| 34828 | int eType = flags&0xFFFFFF00; /* Type of file to open */ |
| 34829 | #endif |
| @@ -34767,22 +34874,22 @@ | |
| 34874 | assert( pFile!=0 ); |
| 34875 | memset(pFile, 0, sizeof(winFile)); |
| 34876 | pFile->h = INVALID_HANDLE_VALUE; |
| 34877 | |
| 34878 | #if SQLITE_OS_WINRT |
| 34879 | if( !zUtf8Name && !sqlite3_temp_directory ){ |
| 34880 | sqlite3_log(SQLITE_ERROR, |
| 34881 | "sqlite3_temp_directory variable should be set for WinRT"); |
| 34882 | } |
| 34883 | #endif |
| 34884 | |
| 34885 | /* If the second argument to this function is NULL, generate a |
| 34886 | ** temporary file name to use |
| 34887 | */ |
| 34888 | if( !zUtf8Name ){ |
| 34889 | assert( isDelete && !isOpenJournal ); |
| 34890 | rc = winGetTempname(pVfs, &zTmpname); |
| 34891 | if( rc!=SQLITE_OK ){ |
| 34892 | OSTRACE(("OPEN name=%s, rc=%s", zUtf8Name, sqlite3ErrName(rc))); |
| 34893 | return rc; |
| 34894 | } |
| 34895 | zUtf8Name = zTmpname; |
| @@ -34791,21 +34898,23 @@ | |
| 34898 | /* Database filenames are double-zero terminated if they are not |
| 34899 | ** URIs with parameters. Hence, they can always be passed into |
| 34900 | ** sqlite3_uri_parameter(). |
| 34901 | */ |
| 34902 | assert( (eType!=SQLITE_OPEN_MAIN_DB) || (flags & SQLITE_OPEN_URI) || |
| 34903 | zUtf8Name[sqlite3Strlen30(zUtf8Name)+1]==0 ); |
| 34904 | |
| 34905 | /* Convert the filename to the system encoding. */ |
| 34906 | zConverted = winConvertUtf8Filename(zUtf8Name); |
| 34907 | if( zConverted==0 ){ |
| 34908 | sqlite3_free(zTmpname); |
| 34909 | OSTRACE(("OPEN name=%s, rc=SQLITE_IOERR_NOMEM", zUtf8Name)); |
| 34910 | return SQLITE_IOERR_NOMEM; |
| 34911 | } |
| 34912 | |
| 34913 | if( winIsDir(zConverted) ){ |
| 34914 | sqlite3_free(zConverted); |
| 34915 | sqlite3_free(zTmpname); |
| 34916 | OSTRACE(("OPEN name=%s, rc=SQLITE_CANTOPEN_ISDIR", zUtf8Name)); |
| 34917 | return SQLITE_CANTOPEN_ISDIR; |
| 34918 | } |
| 34919 | |
| 34920 | if( isReadWrite ){ |
| @@ -34848,11 +34957,11 @@ | |
| 34957 | ** better if FILE_FLAG_RANDOM_ACCESS is used. Ticket #2699. */ |
| 34958 | #if SQLITE_OS_WINCE |
| 34959 | dwFlagsAndAttributes |= FILE_FLAG_RANDOM_ACCESS; |
| 34960 | #endif |
| 34961 | |
| 34962 | if( osIsNT() ){ |
| 34963 | #if SQLITE_OS_WINRT |
| 34964 | CREATEFILE2_EXTENDED_PARAMETERS extendedParameters; |
| 34965 | extendedParameters.dwSize = sizeof(CREATEFILE2_EXTENDED_PARAMETERS); |
| 34966 | extendedParameters.dwFileAttributes = |
| 34967 | dwFlagsAndAttributes & FILE_ATTRIBUTE_MASK; |
| @@ -34863,21 +34972,21 @@ | |
| 34972 | while( (h = osCreateFile2((LPCWSTR)zConverted, |
| 34973 | dwDesiredAccess, |
| 34974 | dwShareMode, |
| 34975 | dwCreationDisposition, |
| 34976 | &extendedParameters))==INVALID_HANDLE_VALUE && |
| 34977 | winRetryIoerr(&cnt, &lastErrno) ){ |
| 34978 | /* Noop */ |
| 34979 | } |
| 34980 | #else |
| 34981 | while( (h = osCreateFileW((LPCWSTR)zConverted, |
| 34982 | dwDesiredAccess, |
| 34983 | dwShareMode, NULL, |
| 34984 | dwCreationDisposition, |
| 34985 | dwFlagsAndAttributes, |
| 34986 | NULL))==INVALID_HANDLE_VALUE && |
| 34987 | winRetryIoerr(&cnt, &lastErrno) ){ |
| 34988 | /* Noop */ |
| 34989 | } |
| 34990 | #endif |
| 34991 | } |
| 34992 | #ifdef SQLITE_WIN32_HAS_ANSI |
| @@ -34886,24 +34995,25 @@ | |
| 34995 | dwDesiredAccess, |
| 34996 | dwShareMode, NULL, |
| 34997 | dwCreationDisposition, |
| 34998 | dwFlagsAndAttributes, |
| 34999 | NULL))==INVALID_HANDLE_VALUE && |
| 35000 | winRetryIoerr(&cnt, &lastErrno) ){ |
| 35001 | /* Noop */ |
| 35002 | } |
| 35003 | } |
| 35004 | #endif |
| 35005 | winLogIoerr(cnt); |
| 35006 | |
| 35007 | OSTRACE(("OPEN file=%p, name=%s, access=%lx, rc=%s\n", h, zUtf8Name, |
| 35008 | dwDesiredAccess, (h==INVALID_HANDLE_VALUE) ? "failed" : "ok")); |
| 35009 | |
| 35010 | if( h==INVALID_HANDLE_VALUE ){ |
| 35011 | pFile->lastErrno = lastErrno; |
| 35012 | winLogError(SQLITE_CANTOPEN, pFile->lastErrno, "winOpen", zUtf8Name); |
| 35013 | sqlite3_free(zConverted); |
| 35014 | sqlite3_free(zTmpname); |
| 35015 | if( isReadWrite && !isExclusive ){ |
| 35016 | return winOpen(pVfs, zName, id, |
| 35017 | ((flags|SQLITE_OPEN_READONLY) & |
| 35018 | ~(SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE)), |
| 35019 | pOutFlags); |
| @@ -34928,19 +35038,21 @@ | |
| 35038 | if( isReadWrite && eType==SQLITE_OPEN_MAIN_DB |
| 35039 | && (rc = winceCreateLock(zName, pFile))!=SQLITE_OK |
| 35040 | ){ |
| 35041 | osCloseHandle(h); |
| 35042 | sqlite3_free(zConverted); |
| 35043 | sqlite3_free(zTmpname); |
| 35044 | OSTRACE(("OPEN-CE-LOCK name=%s, rc=%s\n", zName, sqlite3ErrName(rc))); |
| 35045 | return rc; |
| 35046 | } |
| 35047 | if( isTemp ){ |
| 35048 | pFile->zDeleteOnClose = zConverted; |
| 35049 | }else |
| 35050 | #endif |
| 35051 | { |
| 35052 | sqlite3_free(zConverted); |
| 35053 | sqlite3_free(zTmpname); |
| 35054 | } |
| 35055 | |
| 35056 | pFile->pMethod = &winIoMethod; |
| 35057 | pFile->pVfs = pVfs; |
| 35058 | pFile->h = h; |
| @@ -34990,15 +35102,16 @@ | |
| 35102 | UNUSED_PARAMETER(syncDir); |
| 35103 | |
| 35104 | SimulateIOError(return SQLITE_IOERR_DELETE); |
| 35105 | OSTRACE(("DELETE name=%s, syncDir=%d\n", zFilename, syncDir)); |
| 35106 | |
| 35107 | zConverted = winConvertUtf8Filename(zFilename); |
| 35108 | if( zConverted==0 ){ |
| 35109 | OSTRACE(("DELETE name=%s, rc=SQLITE_IOERR_NOMEM\n", zFilename)); |
| 35110 | return SQLITE_IOERR_NOMEM; |
| 35111 | } |
| 35112 | if( osIsNT() ){ |
| 35113 | do { |
| 35114 | #if SQLITE_OS_WINRT |
| 35115 | WIN32_FILE_ATTRIBUTE_DATA sAttrData; |
| 35116 | memset(&sAttrData, 0, sizeof(sAttrData)); |
| 35117 | if ( osGetFileAttributesExW(zConverted, GetFileExInfoStandard, |
| @@ -35033,11 +35146,11 @@ | |
| 35146 | } |
| 35147 | if ( osDeleteFileW(zConverted) ){ |
| 35148 | rc = SQLITE_OK; /* Deleted OK. */ |
| 35149 | break; |
| 35150 | } |
| 35151 | if ( !winRetryIoerr(&cnt, &lastErrno) ){ |
| 35152 | rc = SQLITE_ERROR; /* No more retries. */ |
| 35153 | break; |
| 35154 | } |
| 35155 | } while(1); |
| 35156 | } |
| @@ -35061,11 +35174,11 @@ | |
| 35174 | } |
| 35175 | if ( osDeleteFileA(zConverted) ){ |
| 35176 | rc = SQLITE_OK; /* Deleted OK. */ |
| 35177 | break; |
| 35178 | } |
| 35179 | if ( !winRetryIoerr(&cnt, &lastErrno) ){ |
| 35180 | rc = SQLITE_ERROR; /* No more retries. */ |
| 35181 | break; |
| 35182 | } |
| 35183 | } while(1); |
| 35184 | } |
| @@ -35072,11 +35185,11 @@ | |
| 35185 | #endif |
| 35186 | if( rc && rc!=SQLITE_IOERR_DELETE_NOENT ){ |
| 35187 | rc = winLogError(SQLITE_IOERR_DELETE, lastErrno, |
| 35188 | "winDelete", zFilename); |
| 35189 | }else{ |
| 35190 | winLogIoerr(cnt); |
| 35191 | } |
| 35192 | sqlite3_free(zConverted); |
| 35193 | OSTRACE(("DELETE name=%s, rc=%s\n", zFilename, sqlite3ErrName(rc))); |
| 35194 | return rc; |
| 35195 | } |
| @@ -35098,22 +35211,22 @@ | |
| 35211 | |
| 35212 | SimulateIOError( return SQLITE_IOERR_ACCESS; ); |
| 35213 | OSTRACE(("ACCESS name=%s, flags=%x, pResOut=%p\n", |
| 35214 | zFilename, flags, pResOut)); |
| 35215 | |
| 35216 | zConverted = winConvertUtf8Filename(zFilename); |
| 35217 | if( zConverted==0 ){ |
| 35218 | OSTRACE(("ACCESS name=%s, rc=SQLITE_IOERR_NOMEM\n", zFilename)); |
| 35219 | return SQLITE_IOERR_NOMEM; |
| 35220 | } |
| 35221 | if( osIsNT() ){ |
| 35222 | int cnt = 0; |
| 35223 | WIN32_FILE_ATTRIBUTE_DATA sAttrData; |
| 35224 | memset(&sAttrData, 0, sizeof(sAttrData)); |
| 35225 | while( !(rc = osGetFileAttributesExW((LPCWSTR)zConverted, |
| 35226 | GetFileExInfoStandard, |
| 35227 | &sAttrData)) && winRetryIoerr(&cnt, &lastErrno) ){} |
| 35228 | if( rc ){ |
| 35229 | /* For an SQLITE_ACCESS_EXISTS query, treat a zero-length file |
| 35230 | ** as if it does not exist. |
| 35231 | */ |
| 35232 | if( flags==SQLITE_ACCESS_EXISTS |
| @@ -35122,11 +35235,11 @@ | |
| 35235 | attr = INVALID_FILE_ATTRIBUTES; |
| 35236 | }else{ |
| 35237 | attr = sAttrData.dwFileAttributes; |
| 35238 | } |
| 35239 | }else{ |
| 35240 | winLogIoerr(cnt); |
| 35241 | if( lastErrno!=ERROR_FILE_NOT_FOUND && lastErrno!=ERROR_PATH_NOT_FOUND ){ |
| 35242 | winLogError(SQLITE_IOERR_ACCESS, lastErrno, "winAccess", zFilename); |
| 35243 | sqlite3_free(zConverted); |
| 35244 | return SQLITE_IOERR_ACCESS; |
| 35245 | }else{ |
| @@ -35173,11 +35286,11 @@ | |
| 35286 | ** a legal UNC name, a volume relative path, or an absolute path name in the |
| 35287 | ** "Unix" format on Windows. There is no easy way to differentiate between |
| 35288 | ** the final two cases; therefore, we return the safer return value of TRUE |
| 35289 | ** so that callers of this function will simply use it verbatim. |
| 35290 | */ |
| 35291 | if ( winIsDirSep(zPathname[0]) ){ |
| 35292 | return TRUE; |
| 35293 | } |
| 35294 | |
| 35295 | /* |
| 35296 | ** If the path name starts with a letter and a colon it is either a volume |
| @@ -35209,28 +35322,33 @@ | |
| 35322 | ){ |
| 35323 | |
| 35324 | #if defined(__CYGWIN__) |
| 35325 | SimulateIOError( return SQLITE_ERROR ); |
| 35326 | UNUSED_PARAMETER(nFull); |
| 35327 | assert( nFull>=pVfs->mxPathname ); |
| 35328 | if ( sqlite3_data_directory && !winIsVerbatimPathname(zRelative) ){ |
| 35329 | /* |
| 35330 | ** NOTE: We are dealing with a relative path name and the data |
| 35331 | ** directory has been set. Therefore, use it as the basis |
| 35332 | ** for converting the relative path name to an absolute |
| 35333 | ** one by prepending the data directory and a slash. |
| 35334 | */ |
| 35335 | char *zOut = sqlite3MallocZero( pVfs->mxPathname+1 ); |
| 35336 | if( !zOut ){ |
| 35337 | winLogError(SQLITE_IOERR_NOMEM, 0, "winFullPathname", zRelative); |
| 35338 | return SQLITE_IOERR_NOMEM; |
| 35339 | } |
| 35340 | if( cygwin_conv_path(CCP_POSIX_TO_WIN_A|CCP_RELATIVE, zRelative, zOut, |
| 35341 | pVfs->mxPathname+1)<0 ){ |
| 35342 | winLogError(SQLITE_CANTOPEN_FULLPATH, (DWORD)errno, "cygwin_conv_path", |
| 35343 | zRelative); |
| 35344 | sqlite3_free(zOut); |
| 35345 | return SQLITE_CANTOPEN_FULLPATH; |
| 35346 | } |
| 35347 | sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%s%s", |
| 35348 | sqlite3_data_directory, winGetDirDep(), zOut); |
| 35349 | sqlite3_free(zOut); |
| 35350 | }else{ |
| 35351 | if( cygwin_conv_path(CCP_POSIX_TO_WIN_A, zRelative, zFull, nFull)<0 ){ |
| 35352 | winLogError(SQLITE_CANTOPEN_FULLPATH, (DWORD)errno, "cygwin_conv_path", |
| 35353 | zRelative); |
| 35354 | return SQLITE_CANTOPEN_FULLPATH; |
| @@ -35248,12 +35366,12 @@ | |
| 35366 | ** NOTE: We are dealing with a relative path name and the data |
| 35367 | ** directory has been set. Therefore, use it as the basis |
| 35368 | ** for converting the relative path name to an absolute |
| 35369 | ** one by prepending the data directory and a backslash. |
| 35370 | */ |
| 35371 | sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%s%s", |
| 35372 | sqlite3_data_directory, winGetDirDep(), zRelative); |
| 35373 | }else{ |
| 35374 | sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zRelative); |
| 35375 | } |
| 35376 | return SQLITE_OK; |
| 35377 | #endif |
| @@ -35281,19 +35399,19 @@ | |
| 35399 | ** NOTE: We are dealing with a relative path name and the data |
| 35400 | ** directory has been set. Therefore, use it as the basis |
| 35401 | ** for converting the relative path name to an absolute |
| 35402 | ** one by prepending the data directory and a backslash. |
| 35403 | */ |
| 35404 | sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%s%s", |
| 35405 | sqlite3_data_directory, winGetDirDep(), zRelative); |
| 35406 | return SQLITE_OK; |
| 35407 | } |
| 35408 | zConverted = winConvertUtf8Filename(zRelative); |
| 35409 | if( zConverted==0 ){ |
| 35410 | return SQLITE_IOERR_NOMEM; |
| 35411 | } |
| 35412 | if( osIsNT() ){ |
| 35413 | LPWSTR zTemp; |
| 35414 | nByte = osGetFullPathNameW((LPCWSTR)zConverted, 0, 0, 0); |
| 35415 | if( nByte==0 ){ |
| 35416 | winLogError(SQLITE_ERROR, osGetLastError(), |
| 35417 | "GetFullPathNameW1", zConverted); |
| @@ -35313,11 +35431,11 @@ | |
| 35431 | sqlite3_free(zConverted); |
| 35432 | sqlite3_free(zTemp); |
| 35433 | return SQLITE_CANTOPEN_FULLPATH; |
| 35434 | } |
| 35435 | sqlite3_free(zConverted); |
| 35436 | zOut = winUnicodeToUtf8(zTemp); |
| 35437 | sqlite3_free(zTemp); |
| 35438 | } |
| 35439 | #ifdef SQLITE_WIN32_HAS_ANSI |
| 35440 | else{ |
| 35441 | char *zTemp; |
| @@ -35366,16 +35484,16 @@ | |
| 35484 | ** Interfaces for opening a shared library, finding entry points |
| 35485 | ** within the shared library, and closing the shared library. |
| 35486 | */ |
| 35487 | static void *winDlOpen(sqlite3_vfs *pVfs, const char *zFilename){ |
| 35488 | HANDLE h; |
| 35489 | void *zConverted = winConvertUtf8Filename(zFilename); |
| 35490 | UNUSED_PARAMETER(pVfs); |
| 35491 | if( zConverted==0 ){ |
| 35492 | return 0; |
| 35493 | } |
| 35494 | if( osIsNT() ){ |
| 35495 | #if SQLITE_OS_WINRT |
| 35496 | h = osLoadPackagedLibrary((LPCWSTR)zConverted, 0); |
| 35497 | #else |
| 35498 | h = osLoadLibraryW((LPCWSTR)zConverted); |
| 35499 | #endif |
| @@ -35388,11 +35506,11 @@ | |
| 35506 | sqlite3_free(zConverted); |
| 35507 | return (void*)h; |
| 35508 | } |
| 35509 | static void winDlError(sqlite3_vfs *pVfs, int nBuf, char *zBufOut){ |
| 35510 | UNUSED_PARAMETER(pVfs); |
| 35511 | winGetLastErrorMsg(osGetLastError(), nBuf, zBufOut); |
| 35512 | } |
| 35513 | static void (*winDlSym(sqlite3_vfs *pVfs,void *pH,const char *zSym))(void){ |
| 35514 | UNUSED_PARAMETER(pVfs); |
| 35515 | return (void(*)(void))osGetProcAddressA((HANDLE)pH, zSym); |
| 35516 | } |
| @@ -35564,21 +35682,21 @@ | |
| 35682 | ** by sqlite into the error message available to the user using |
| 35683 | ** sqlite3_errmsg(), possibly making IO errors easier to debug. |
| 35684 | */ |
| 35685 | static int winGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){ |
| 35686 | UNUSED_PARAMETER(pVfs); |
| 35687 | return winGetLastErrorMsg(osGetLastError(), nBuf, zBuf); |
| 35688 | } |
| 35689 | |
| 35690 | /* |
| 35691 | ** Initialize and deinitialize the operating system interface. |
| 35692 | */ |
| 35693 | SQLITE_API int sqlite3_os_init(void){ |
| 35694 | static sqlite3_vfs winVfs = { |
| 35695 | 3, /* iVersion */ |
| 35696 | sizeof(winFile), /* szOsFile */ |
| 35697 | SQLITE_WIN32_MAX_PATH_BYTES, /* mxPathname */ |
| 35698 | 0, /* pNext */ |
| 35699 | "win32", /* zName */ |
| 35700 | 0, /* pAppData */ |
| 35701 | winOpen, /* xOpen */ |
| 35702 | winDelete, /* xDelete */ |
| @@ -35595,10 +35713,36 @@ | |
| 35713 | winCurrentTimeInt64, /* xCurrentTimeInt64 */ |
| 35714 | winSetSystemCall, /* xSetSystemCall */ |
| 35715 | winGetSystemCall, /* xGetSystemCall */ |
| 35716 | winNextSystemCall, /* xNextSystemCall */ |
| 35717 | }; |
| 35718 | #if defined(SQLITE_WIN32_HAS_WIDE) |
| 35719 | static sqlite3_vfs winLongPathVfs = { |
| 35720 | 3, /* iVersion */ |
| 35721 | sizeof(winFile), /* szOsFile */ |
| 35722 | SQLITE_WINNT_MAX_PATH_BYTES, /* mxPathname */ |
| 35723 | 0, /* pNext */ |
| 35724 | "win32-longpath", /* zName */ |
| 35725 | 0, /* pAppData */ |
| 35726 | winOpen, /* xOpen */ |
| 35727 | winDelete, /* xDelete */ |
| 35728 | winAccess, /* xAccess */ |
| 35729 | winFullPathname, /* xFullPathname */ |
| 35730 | winDlOpen, /* xDlOpen */ |
| 35731 | winDlError, /* xDlError */ |
| 35732 | winDlSym, /* xDlSym */ |
| 35733 | winDlClose, /* xDlClose */ |
| 35734 | winRandomness, /* xRandomness */ |
| 35735 | winSleep, /* xSleep */ |
| 35736 | winCurrentTime, /* xCurrentTime */ |
| 35737 | winGetLastError, /* xGetLastError */ |
| 35738 | winCurrentTimeInt64, /* xCurrentTimeInt64 */ |
| 35739 | winSetSystemCall, /* xSetSystemCall */ |
| 35740 | winGetSystemCall, /* xGetSystemCall */ |
| 35741 | winNextSystemCall, /* xNextSystemCall */ |
| 35742 | }; |
| 35743 | #endif |
| 35744 | |
| 35745 | /* Double-check that the aSyscall[] array has been constructed |
| 35746 | ** correctly. See ticket [bb3a86e890c8e96ab] */ |
| 35747 | assert( ArraySize(aSyscall)==74 ); |
| 35748 | |
| @@ -35611,10 +35755,15 @@ | |
| 35755 | #endif |
| 35756 | assert( winSysInfo.dwAllocationGranularity>0 ); |
| 35757 | assert( winSysInfo.dwPageSize>0 ); |
| 35758 | |
| 35759 | sqlite3_vfs_register(&winVfs, 1); |
| 35760 | |
| 35761 | #if defined(SQLITE_WIN32_HAS_WIDE) |
| 35762 | sqlite3_vfs_register(&winLongPathVfs, 0); |
| 35763 | #endif |
| 35764 | |
| 35765 | return SQLITE_OK; |
| 35766 | } |
| 35767 | |
| 35768 | SQLITE_API int sqlite3_os_end(void){ |
| 35769 | #if SQLITE_OS_WINRT |
| @@ -52086,10 +52235,11 @@ | |
| 52235 | pBt->max1bytePayload = (u8)pBt->maxLocal; |
| 52236 | } |
| 52237 | assert( pBt->maxLeaf + 23 <= MX_CELL_SIZE(pBt) ); |
| 52238 | pBt->pPage1 = pPage1; |
| 52239 | pBt->nPage = nPage; |
| 52240 | assert( pPage1->leaf==0 || pPage1->leaf==1 ); |
| 52241 | return SQLITE_OK; |
| 52242 | |
| 52243 | page1_init_failed: |
| 52244 | releasePage(pPage1); |
| 52245 | pBt->pPage1 = 0; |
| @@ -59838,43 +59988,108 @@ | |
| 59988 | } |
| 59989 | return p; |
| 59990 | } |
| 59991 | |
| 59992 | /* |
| 59993 | ** Context object passed by sqlite3Stat4ProbeSetValue() through to |
| 59994 | ** valueNew(). See comments above valueNew() for details. |
| 59995 | */ |
| 59996 | struct ValueNewStat4Ctx { |
| 59997 | Parse *pParse; |
| 59998 | Index *pIdx; |
| 59999 | UnpackedRecord **ppRec; |
| 60000 | int iVal; |
| 60001 | }; |
| 60002 | |
| 60003 | /* |
| 60004 | ** Allocate and return a pointer to a new sqlite3_value object. If |
| 60005 | ** the second argument to this function is NULL, the object is allocated |
| 60006 | ** by calling sqlite3ValueNew(). |
| 60007 | ** |
| 60008 | ** Otherwise, if the second argument is non-zero, then this function is |
| 60009 | ** being called indirectly by sqlite3Stat4ProbeSetValue(). If it has not |
| 60010 | ** already been allocated, allocate the UnpackedRecord structure that |
| 60011 | ** that function will return to its caller here. Then return a pointer |
| 60012 | ** an sqlite3_value within the UnpackedRecord.a[] array. |
| 60013 | */ |
| 60014 | static sqlite3_value *valueNew(sqlite3 *db, struct ValueNewStat4Ctx *p){ |
| 60015 | #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 60016 | if( p ){ |
| 60017 | UnpackedRecord *pRec = p->ppRec[0]; |
| 60018 | |
| 60019 | if( pRec==0 ){ |
| 60020 | Index *pIdx = p->pIdx; /* Index being probed */ |
| 60021 | int nByte; /* Bytes of space to allocate */ |
| 60022 | int i; /* Counter variable */ |
| 60023 | int nCol = pIdx->nColumn+1; /* Number of index columns including rowid */ |
| 60024 | |
| 60025 | nByte = sizeof(Mem) * nCol + sizeof(UnpackedRecord); |
| 60026 | pRec = (UnpackedRecord*)sqlite3DbMallocZero(db, nByte); |
| 60027 | if( pRec ){ |
| 60028 | pRec->pKeyInfo = sqlite3IndexKeyinfo(p->pParse, pIdx); |
| 60029 | if( pRec->pKeyInfo ){ |
| 60030 | assert( pRec->pKeyInfo->nField+1==nCol ); |
| 60031 | pRec->pKeyInfo->enc = ENC(db); |
| 60032 | pRec->flags = UNPACKED_PREFIX_MATCH; |
| 60033 | pRec->aMem = (Mem *)&pRec[1]; |
| 60034 | for(i=0; i<nCol; i++){ |
| 60035 | pRec->aMem[i].flags = MEM_Null; |
| 60036 | pRec->aMem[i].type = SQLITE_NULL; |
| 60037 | pRec->aMem[i].db = db; |
| 60038 | } |
| 60039 | }else{ |
| 60040 | sqlite3DbFree(db, pRec); |
| 60041 | pRec = 0; |
| 60042 | } |
| 60043 | } |
| 60044 | if( pRec==0 ) return 0; |
| 60045 | p->ppRec[0] = pRec; |
| 60046 | } |
| 60047 | |
| 60048 | pRec->nField = p->iVal+1; |
| 60049 | return &pRec->aMem[p->iVal]; |
| 60050 | } |
| 60051 | #endif |
| 60052 | return sqlite3ValueNew(db); |
| 60053 | } |
| 60054 | |
| 60055 | /* |
| 60056 | ** Extract a value from the supplied expression in the manner described |
| 60057 | ** above sqlite3ValueFromExpr(). Allocate the sqlite3_value object |
| 60058 | ** using valueNew(). |
| 60059 | ** |
| 60060 | ** If pCtx is NULL and an error occurs after the sqlite3_value object |
| 60061 | ** has been allocated, it is freed before returning. Or, if pCtx is not |
| 60062 | ** NULL, it is assumed that the caller will free any allocated object |
| 60063 | ** in all cases. |
| 60064 | */ |
| 60065 | int valueFromExpr( |
| 60066 | sqlite3 *db, /* The database connection */ |
| 60067 | Expr *pExpr, /* The expression to evaluate */ |
| 60068 | u8 enc, /* Encoding to use */ |
| 60069 | u8 affinity, /* Affinity to use */ |
| 60070 | sqlite3_value **ppVal, /* Write the new value here */ |
| 60071 | struct ValueNewStat4Ctx *pCtx /* Second argument for valueNew() */ |
| 60072 | ){ |
| 60073 | int op; |
| 60074 | char *zVal = 0; |
| 60075 | sqlite3_value *pVal = 0; |
| 60076 | int negInt = 1; |
| 60077 | const char *zNeg = ""; |
| 60078 | int rc = SQLITE_OK; |
| 60079 | |
| 60080 | if( !pExpr ){ |
| 60081 | *ppVal = 0; |
| 60082 | return SQLITE_OK; |
| 60083 | } |
| 60084 | op = pExpr->op; |
| 60085 | |
| 60086 | /* op can only be TK_REGISTER if we have compiled with SQLITE_ENABLE_STAT4. |
| 60087 | ** The ifdef here is to enable us to achieve 100% branch test coverage even |
| 60088 | ** when SQLITE_ENABLE_STAT4 is omitted. |
| 60089 | */ |
| 60090 | #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 60091 | if( op==TK_REGISTER ) op = pExpr->op2; |
| 60092 | #else |
| 60093 | if( NEVER(op==TK_REGISTER) ) op = pExpr->op2; |
| 60094 | #endif |
| 60095 | |
| @@ -59888,11 +60103,11 @@ | |
| 60103 | negInt = -1; |
| 60104 | zNeg = "-"; |
| 60105 | } |
| 60106 | |
| 60107 | if( op==TK_STRING || op==TK_FLOAT || op==TK_INTEGER ){ |
| 60108 | pVal = valueNew(db, pCtx); |
| 60109 | if( pVal==0 ) goto no_mem; |
| 60110 | if( ExprHasProperty(pExpr, EP_IntValue) ){ |
| 60111 | sqlite3VdbeMemSetInt64(pVal, (i64)pExpr->u.iValue*negInt); |
| 60112 | }else{ |
| 60113 | zVal = sqlite3MPrintf(db, "%s%s", zNeg, pExpr->u.zToken); |
| @@ -59905,15 +60120,17 @@ | |
| 60120 | }else{ |
| 60121 | sqlite3ValueApplyAffinity(pVal, affinity, SQLITE_UTF8); |
| 60122 | } |
| 60123 | if( pVal->flags & (MEM_Int|MEM_Real) ) pVal->flags &= ~MEM_Str; |
| 60124 | if( enc!=SQLITE_UTF8 ){ |
| 60125 | rc = sqlite3VdbeChangeEncoding(pVal, enc); |
| 60126 | } |
| 60127 | }else if( op==TK_UMINUS ) { |
| 60128 | /* This branch happens for multiple negative signs. Ex: -(-5) */ |
| 60129 | if( SQLITE_OK==sqlite3ValueFromExpr(db,pExpr->pLeft,enc,affinity,&pVal) |
| 60130 | && pVal!=0 |
| 60131 | ){ |
| 60132 | sqlite3VdbeMemNumerify(pVal); |
| 60133 | if( pVal->u.i==SMALLEST_INT64 ){ |
| 60134 | pVal->flags &= MEM_Int; |
| 60135 | pVal->flags |= MEM_Real; |
| 60136 | pVal->r = (double)LARGEST_INT64; |
| @@ -59922,19 +60139,19 @@ | |
| 60139 | } |
| 60140 | pVal->r = -pVal->r; |
| 60141 | sqlite3ValueApplyAffinity(pVal, affinity, enc); |
| 60142 | } |
| 60143 | }else if( op==TK_NULL ){ |
| 60144 | pVal = valueNew(db, pCtx); |
| 60145 | if( pVal==0 ) goto no_mem; |
| 60146 | } |
| 60147 | #ifndef SQLITE_OMIT_BLOB_LITERAL |
| 60148 | else if( op==TK_BLOB ){ |
| 60149 | int nVal; |
| 60150 | assert( pExpr->u.zToken[0]=='x' || pExpr->u.zToken[0]=='X' ); |
| 60151 | assert( pExpr->u.zToken[1]=='\'' ); |
| 60152 | pVal = valueNew(db, pCtx); |
| 60153 | if( !pVal ) goto no_mem; |
| 60154 | zVal = &pExpr->u.zToken[2]; |
| 60155 | nVal = sqlite3Strlen30(zVal)-1; |
| 60156 | assert( zVal[nVal]=='\'' ); |
| 60157 | sqlite3VdbeMemSetStr(pVal, sqlite3HexToBlob(db, zVal, nVal), nVal/2, |
| @@ -59944,20 +60161,203 @@ | |
| 60161 | |
| 60162 | if( pVal ){ |
| 60163 | sqlite3VdbeMemStoreType(pVal); |
| 60164 | } |
| 60165 | *ppVal = pVal; |
| 60166 | return rc; |
| 60167 | |
| 60168 | no_mem: |
| 60169 | db->mallocFailed = 1; |
| 60170 | sqlite3DbFree(db, zVal); |
| 60171 | assert( *ppVal==0 ); |
| 60172 | #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 60173 | if( pCtx==0 ) sqlite3ValueFree(pVal); |
| 60174 | #else |
| 60175 | assert( pCtx==0 ); sqlite3ValueFree(pVal); |
| 60176 | #endif |
| 60177 | return SQLITE_NOMEM; |
| 60178 | } |
| 60179 | |
| 60180 | /* |
| 60181 | ** Create a new sqlite3_value object, containing the value of pExpr. |
| 60182 | ** |
| 60183 | ** This only works for very simple expressions that consist of one constant |
| 60184 | ** token (i.e. "5", "5.1", "'a string'"). If the expression can |
| 60185 | ** be converted directly into a value, then the value is allocated and |
| 60186 | ** a pointer written to *ppVal. The caller is responsible for deallocating |
| 60187 | ** the value by passing it to sqlite3ValueFree() later on. If the expression |
| 60188 | ** cannot be converted to a value, then *ppVal is set to NULL. |
| 60189 | */ |
| 60190 | SQLITE_PRIVATE int sqlite3ValueFromExpr( |
| 60191 | sqlite3 *db, /* The database connection */ |
| 60192 | Expr *pExpr, /* The expression to evaluate */ |
| 60193 | u8 enc, /* Encoding to use */ |
| 60194 | u8 affinity, /* Affinity to use */ |
| 60195 | sqlite3_value **ppVal /* Write the new value here */ |
| 60196 | ){ |
| 60197 | return valueFromExpr(db, pExpr, enc, affinity, ppVal, 0); |
| 60198 | } |
| 60199 | |
| 60200 | #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 60201 | /* |
| 60202 | ** The implementation of the sqlite_record() function. This function accepts |
| 60203 | ** a single argument of any type. The return value is a formatted database |
| 60204 | ** record (a blob) containing the argument value. |
| 60205 | ** |
| 60206 | ** This is used to convert the value stored in the 'sample' column of the |
| 60207 | ** sqlite_stat3 table to the record format SQLite uses internally. |
| 60208 | */ |
| 60209 | static void recordFunc( |
| 60210 | sqlite3_context *context, |
| 60211 | int argc, |
| 60212 | sqlite3_value **argv |
| 60213 | ){ |
| 60214 | const int file_format = 1; |
| 60215 | int iSerial; /* Serial type */ |
| 60216 | int nSerial; /* Bytes of space for iSerial as varint */ |
| 60217 | int nVal; /* Bytes of space required for argv[0] */ |
| 60218 | int nRet; |
| 60219 | sqlite3 *db; |
| 60220 | u8 *aRet; |
| 60221 | |
| 60222 | iSerial = sqlite3VdbeSerialType(argv[0], file_format); |
| 60223 | nSerial = sqlite3VarintLen(iSerial); |
| 60224 | nVal = sqlite3VdbeSerialTypeLen(iSerial); |
| 60225 | db = sqlite3_context_db_handle(context); |
| 60226 | |
| 60227 | nRet = 1 + nSerial + nVal; |
| 60228 | aRet = sqlite3DbMallocRaw(db, nRet); |
| 60229 | if( aRet==0 ){ |
| 60230 | sqlite3_result_error_nomem(context); |
| 60231 | }else{ |
| 60232 | aRet[0] = nSerial+1; |
| 60233 | sqlite3PutVarint(&aRet[1], iSerial); |
| 60234 | sqlite3VdbeSerialPut(&aRet[1+nSerial], nVal, argv[0], file_format); |
| 60235 | sqlite3_result_blob(context, aRet, nRet, SQLITE_TRANSIENT); |
| 60236 | sqlite3DbFree(db, aRet); |
| 60237 | } |
| 60238 | } |
| 60239 | |
| 60240 | /* |
| 60241 | ** Register built-in functions used to help read ANALYZE data. |
| 60242 | */ |
| 60243 | SQLITE_PRIVATE void sqlite3AnalyzeFunctions(void){ |
| 60244 | static SQLITE_WSD FuncDef aAnalyzeTableFuncs[] = { |
| 60245 | FUNCTION(sqlite_record, 1, 0, 0, recordFunc), |
| 60246 | }; |
| 60247 | int i; |
| 60248 | FuncDefHash *pHash = &GLOBAL(FuncDefHash, sqlite3GlobalFunctions); |
| 60249 | FuncDef *aFunc = (FuncDef*)&GLOBAL(FuncDef, aAnalyzeTableFuncs); |
| 60250 | for(i=0; i<ArraySize(aAnalyzeTableFuncs); i++){ |
| 60251 | sqlite3FuncDefInsert(pHash, &aFunc[i]); |
| 60252 | } |
| 60253 | } |
| 60254 | |
| 60255 | /* |
| 60256 | ** This function is used to allocate and populate UnpackedRecord |
| 60257 | ** structures intended to be compared against sample index keys stored |
| 60258 | ** in the sqlite_stat4 table. |
| 60259 | ** |
| 60260 | ** A single call to this function attempts to populates field iVal (leftmost |
| 60261 | ** is 0 etc.) of the unpacked record with a value extracted from expression |
| 60262 | ** pExpr. Extraction of values is possible if: |
| 60263 | ** |
| 60264 | ** * (pExpr==0). In this case the value is assumed to be an SQL NULL, |
| 60265 | ** |
| 60266 | ** * The expression is a bound variable, and this is a reprepare, or |
| 60267 | ** |
| 60268 | ** * The sqlite3ValueFromExpr() function is able to extract a value |
| 60269 | ** from the expression (i.e. the expression is a literal value). |
| 60270 | ** |
| 60271 | ** If a value can be extracted, the affinity passed as the 5th argument |
| 60272 | ** is applied to it before it is copied into the UnpackedRecord. Output |
| 60273 | ** parameter *pbOk is set to true if a value is extracted, or false |
| 60274 | ** otherwise. |
| 60275 | ** |
| 60276 | ** When this function is called, *ppRec must either point to an object |
| 60277 | ** allocated by an earlier call to this function, or must be NULL. If it |
| 60278 | ** is NULL and a value can be successfully extracted, a new UnpackedRecord |
| 60279 | ** is allocated (and *ppRec set to point to it) before returning. |
| 60280 | ** |
| 60281 | ** Unless an error is encountered, SQLITE_OK is returned. It is not an |
| 60282 | ** error if a value cannot be extracted from pExpr. If an error does |
| 60283 | ** occur, an SQLite error code is returned. |
| 60284 | */ |
| 60285 | SQLITE_PRIVATE int sqlite3Stat4ProbeSetValue( |
| 60286 | Parse *pParse, /* Parse context */ |
| 60287 | Index *pIdx, /* Index being probed */ |
| 60288 | UnpackedRecord **ppRec, /* IN/OUT: Probe record */ |
| 60289 | Expr *pExpr, /* The expression to extract a value from */ |
| 60290 | u8 affinity, /* Affinity to use */ |
| 60291 | int iVal, /* Array element to populate */ |
| 60292 | int *pbOk /* OUT: True if value was extracted */ |
| 60293 | ){ |
| 60294 | int rc = SQLITE_OK; |
| 60295 | sqlite3_value *pVal = 0; |
| 60296 | |
| 60297 | struct ValueNewStat4Ctx alloc; |
| 60298 | alloc.pParse = pParse; |
| 60299 | alloc.pIdx = pIdx; |
| 60300 | alloc.ppRec = ppRec; |
| 60301 | alloc.iVal = iVal; |
| 60302 | |
| 60303 | if( !pExpr ){ |
| 60304 | pVal = valueNew(pParse->db, &alloc); |
| 60305 | if( pVal ){ |
| 60306 | sqlite3VdbeMemSetNull((Mem*)pVal); |
| 60307 | *pbOk = 1; |
| 60308 | } |
| 60309 | }else if( pExpr->op==TK_VARIABLE |
| 60310 | || (pExpr->op==TK_REGISTER && pExpr->op2==TK_VARIABLE) |
| 60311 | ){ |
| 60312 | Vdbe *v; |
| 60313 | int iBindVar = pExpr->iColumn; |
| 60314 | sqlite3VdbeSetVarmask(pParse->pVdbe, iBindVar); |
| 60315 | if( (v = pParse->pReprepare)!=0 ){ |
| 60316 | pVal = valueNew(pParse->db, &alloc); |
| 60317 | if( pVal ){ |
| 60318 | rc = sqlite3VdbeMemCopy((Mem*)pVal, &v->aVar[iBindVar-1]); |
| 60319 | if( rc==SQLITE_OK ){ |
| 60320 | sqlite3ValueApplyAffinity(pVal, affinity, SQLITE_UTF8); |
| 60321 | } |
| 60322 | pVal->db = pParse->db; |
| 60323 | *pbOk = 1; |
| 60324 | sqlite3VdbeMemStoreType((Mem*)pVal); |
| 60325 | } |
| 60326 | }else{ |
| 60327 | *pbOk = 0; |
| 60328 | } |
| 60329 | }else{ |
| 60330 | sqlite3 *db = pParse->db; |
| 60331 | rc = valueFromExpr(db, pExpr, ENC(db), affinity, &pVal, &alloc); |
| 60332 | *pbOk = (pVal!=0); |
| 60333 | } |
| 60334 | |
| 60335 | assert( pVal==0 || pVal->db==pParse->db ); |
| 60336 | return rc; |
| 60337 | } |
| 60338 | |
| 60339 | /* |
| 60340 | ** Unless it is NULL, the argument must be an UnpackedRecord object returned |
| 60341 | ** by an earlier call to sqlite3Stat4ProbeSetValue(). This call deletes |
| 60342 | ** the object. |
| 60343 | */ |
| 60344 | SQLITE_PRIVATE void sqlite3Stat4ProbeFree(UnpackedRecord *pRec){ |
| 60345 | if( pRec ){ |
| 60346 | int i; |
| 60347 | int nCol = pRec->pKeyInfo->nField+1; |
| 60348 | Mem *aMem = pRec->aMem; |
| 60349 | sqlite3 *db = aMem[0].db; |
| 60350 | for(i=0; i<nCol; i++){ |
| 60351 | sqlite3DbFree(db, aMem[i].zMalloc); |
| 60352 | } |
| 60353 | sqlite3DbFree(db, pRec->pKeyInfo); |
| 60354 | sqlite3DbFree(db, pRec); |
| 60355 | } |
| 60356 | } |
| 60357 | #endif /* ifdef SQLITE_ENABLE_STAT4 */ |
| 60358 | |
| 60359 | /* |
| 60360 | ** Change the string value of an sqlite3_value object |
| 60361 | */ |
| 60362 | SQLITE_PRIVATE void sqlite3ValueSetStr( |
| 60363 | sqlite3_value *v, /* Value to be set */ |
| @@ -66073,11 +66473,11 @@ | |
| 66473 | ** value or convert mem[p2] to a different type. |
| 66474 | */ |
| 66475 | assert( pOp->opflags==sqlite3OpcodeProperty[pOp->opcode] ); |
| 66476 | if( pOp->opflags & OPFLG_OUT2_PRERELEASE ){ |
| 66477 | assert( pOp->p2>0 ); |
| 66478 | assert( pOp->p2<=(p->nMem-p->nCursor) ); |
| 66479 | pOut = &aMem[pOp->p2]; |
| 66480 | memAboutToChange(p, pOut); |
| 66481 | VdbeMemRelease(pOut); |
| 66482 | pOut->flags = MEM_Int; |
| 66483 | } |
| @@ -66084,34 +66484,34 @@ | |
| 66484 | |
| 66485 | /* Sanity checking on other operands */ |
| 66486 | #ifdef SQLITE_DEBUG |
| 66487 | if( (pOp->opflags & OPFLG_IN1)!=0 ){ |
| 66488 | assert( pOp->p1>0 ); |
| 66489 | assert( pOp->p1<=(p->nMem-p->nCursor) ); |
| 66490 | assert( memIsValid(&aMem[pOp->p1]) ); |
| 66491 | REGISTER_TRACE(pOp->p1, &aMem[pOp->p1]); |
| 66492 | } |
| 66493 | if( (pOp->opflags & OPFLG_IN2)!=0 ){ |
| 66494 | assert( pOp->p2>0 ); |
| 66495 | assert( pOp->p2<=(p->nMem-p->nCursor) ); |
| 66496 | assert( memIsValid(&aMem[pOp->p2]) ); |
| 66497 | REGISTER_TRACE(pOp->p2, &aMem[pOp->p2]); |
| 66498 | } |
| 66499 | if( (pOp->opflags & OPFLG_IN3)!=0 ){ |
| 66500 | assert( pOp->p3>0 ); |
| 66501 | assert( pOp->p3<=(p->nMem-p->nCursor) ); |
| 66502 | assert( memIsValid(&aMem[pOp->p3]) ); |
| 66503 | REGISTER_TRACE(pOp->p3, &aMem[pOp->p3]); |
| 66504 | } |
| 66505 | if( (pOp->opflags & OPFLG_OUT2)!=0 ){ |
| 66506 | assert( pOp->p2>0 ); |
| 66507 | assert( pOp->p2<=(p->nMem-p->nCursor) ); |
| 66508 | memAboutToChange(p, &aMem[pOp->p2]); |
| 66509 | } |
| 66510 | if( (pOp->opflags & OPFLG_OUT3)!=0 ){ |
| 66511 | assert( pOp->p3>0 ); |
| 66512 | assert( pOp->p3<=(p->nMem-p->nCursor) ); |
| 66513 | memAboutToChange(p, &aMem[pOp->p3]); |
| 66514 | } |
| 66515 | #endif |
| 66516 | |
| 66517 | switch( pOp->opcode ){ |
| @@ -66200,11 +66600,11 @@ | |
| 66600 | ** |
| 66601 | ** Write the current address onto register P1 |
| 66602 | ** and then jump to address P2. |
| 66603 | */ |
| 66604 | case OP_Gosub: { /* jump */ |
| 66605 | assert( pOp->p1>0 && pOp->p1<=(p->nMem-p->nCursor) ); |
| 66606 | pIn1 = &aMem[pOp->p1]; |
| 66607 | assert( (pIn1->flags & MEM_Dyn)==0 ); |
| 66608 | memAboutToChange(p, pIn1); |
| 66609 | pIn1->flags = MEM_Int; |
| 66610 | pIn1->u.i = pc; |
| @@ -66416,11 +66816,11 @@ | |
| 66816 | #if 0 /* local variables moved into u.ab */ |
| 66817 | int cnt; |
| 66818 | u16 nullFlag; |
| 66819 | #endif /* local variables moved into u.ab */ |
| 66820 | u.ab.cnt = pOp->p3-pOp->p2; |
| 66821 | assert( pOp->p3<=(p->nMem-p->nCursor) ); |
| 66822 | pOut->flags = u.ab.nullFlag = pOp->p1 ? (MEM_Null|MEM_Cleared) : MEM_Null; |
| 66823 | while( u.ab.cnt>0 ){ |
| 66824 | pOut++; |
| 66825 | memAboutToChange(p, pOut); |
| 66826 | VdbeMemRelease(pOut); |
| @@ -66489,12 +66889,12 @@ | |
| 66889 | assert( u.ad.p1+u.ad.n<=u.ad.p2 || u.ad.p2+u.ad.n<=u.ad.p1 ); |
| 66890 | |
| 66891 | pIn1 = &aMem[u.ad.p1]; |
| 66892 | pOut = &aMem[u.ad.p2]; |
| 66893 | while( u.ad.n-- ){ |
| 66894 | assert( pOut<=&aMem[(p->nMem-p->nCursor)] ); |
| 66895 | assert( pIn1<=&aMem[(p->nMem-p->nCursor)] ); |
| 66896 | assert( memIsValid(pIn1) ); |
| 66897 | memAboutToChange(p, pOut); |
| 66898 | u.ad.zMalloc = pOut->zMalloc; |
| 66899 | pOut->zMalloc = 0; |
| 66900 | sqlite3VdbeMemMove(pOut, pIn1); |
| @@ -66578,11 +66978,11 @@ | |
| 66978 | Mem *pMem; |
| 66979 | int i; |
| 66980 | #endif /* local variables moved into u.af */ |
| 66981 | assert( p->nResColumn==pOp->p2 ); |
| 66982 | assert( pOp->p1>0 ); |
| 66983 | assert( pOp->p1+pOp->p2<=(p->nMem-p->nCursor)+1 ); |
| 66984 | |
| 66985 | /* If this statement has violated immediate foreign key constraints, do |
| 66986 | ** not return the number of rows modified. And do not RELEASE the statement |
| 66987 | ** transaction. It needs to be rolled back. */ |
| 66988 | if( SQLITE_OK!=(rc = sqlite3VdbeCheckFk(p, 0)) ){ |
| @@ -66858,15 +67258,15 @@ | |
| 67258 | #endif /* local variables moved into u.ai */ |
| 67259 | |
| 67260 | u.ai.n = pOp->p5; |
| 67261 | u.ai.apVal = p->apArg; |
| 67262 | assert( u.ai.apVal || u.ai.n==0 ); |
| 67263 | assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) ); |
| 67264 | pOut = &aMem[pOp->p3]; |
| 67265 | memAboutToChange(p, pOut); |
| 67266 | |
| 67267 | assert( u.ai.n==0 || (pOp->p2>0 && pOp->p2+u.ai.n<=(p->nMem-p->nCursor)+1) ); |
| 67268 | assert( pOp->p3<pOp->p2 || pOp->p3>=pOp->p2+u.ai.n ); |
| 67269 | u.ai.pArg = &aMem[pOp->p2]; |
| 67270 | for(u.ai.i=0; u.ai.i<u.ai.n; u.ai.i++, u.ai.pArg++){ |
| 67271 | assert( memIsValid(u.ai.pArg) ); |
| 67272 | u.ai.apVal[u.ai.i] = u.ai.pArg; |
| @@ -67398,15 +67798,15 @@ | |
| 67798 | u.al.p2 = pOp->p2; |
| 67799 | #if SQLITE_DEBUG |
| 67800 | if( aPermute ){ |
| 67801 | int k, mx = 0; |
| 67802 | for(k=0; k<u.al.n; k++) if( aPermute[k]>mx ) mx = aPermute[k]; |
| 67803 | assert( u.al.p1>0 && u.al.p1+mx<=(p->nMem-p->nCursor)+1 ); |
| 67804 | assert( u.al.p2>0 && u.al.p2+mx<=(p->nMem-p->nCursor)+1 ); |
| 67805 | }else{ |
| 67806 | assert( u.al.p1>0 && u.al.p1+u.al.n<=(p->nMem-p->nCursor)+1 ); |
| 67807 | assert( u.al.p2>0 && u.al.p2+u.al.n<=(p->nMem-p->nCursor)+1 ); |
| 67808 | } |
| 67809 | #endif /* SQLITE_DEBUG */ |
| 67810 | for(u.al.i=0; u.al.i<u.al.n; u.al.i++){ |
| 67811 | u.al.idx = aPermute ? aPermute[u.al.i] : u.al.i; |
| 67812 | assert( memIsValid(&aMem[u.al.p1+u.al.idx]) ); |
| @@ -67659,11 +68059,11 @@ | |
| 68059 | u.ao.p1 = pOp->p1; |
| 68060 | u.ao.p2 = pOp->p2; |
| 68061 | u.ao.pC = 0; |
| 68062 | memset(&u.ao.sMem, 0, sizeof(u.ao.sMem)); |
| 68063 | assert( u.ao.p1<p->nCursor ); |
| 68064 | assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) ); |
| 68065 | u.ao.pDest = &aMem[pOp->p3]; |
| 68066 | memAboutToChange(p, u.ao.pDest); |
| 68067 | u.ao.zRec = 0; |
| 68068 | |
| 68069 | /* This block sets the variable u.ao.payloadSize to be the total number of |
| @@ -67959,11 +68359,11 @@ | |
| 68359 | u.ap.zAffinity = pOp->p4.z; |
| 68360 | assert( u.ap.zAffinity!=0 ); |
| 68361 | assert( u.ap.zAffinity[pOp->p2]==0 ); |
| 68362 | pIn1 = &aMem[pOp->p1]; |
| 68363 | while( (u.ap.cAff = *(u.ap.zAffinity++))!=0 ){ |
| 68364 | assert( pIn1 <= &p->aMem[(p->nMem-p->nCursor)] ); |
| 68365 | assert( memIsValid(pIn1) ); |
| 68366 | ExpandBlob(pIn1); |
| 68367 | applyAffinity(pIn1, u.ap.cAff, encoding); |
| 68368 | pIn1++; |
| 68369 | } |
| @@ -68022,11 +68422,11 @@ | |
| 68422 | u.aq.nData = 0; /* Number of bytes of data space */ |
| 68423 | u.aq.nHdr = 0; /* Number of bytes of header space */ |
| 68424 | u.aq.nZero = 0; /* Number of zero bytes at the end of the record */ |
| 68425 | u.aq.nField = pOp->p1; |
| 68426 | u.aq.zAffinity = pOp->p4.z; |
| 68427 | assert( u.aq.nField>0 && pOp->p2>0 && pOp->p2+u.aq.nField<=(p->nMem-p->nCursor)+1 ); |
| 68428 | u.aq.pData0 = &aMem[u.aq.nField]; |
| 68429 | u.aq.nField = pOp->p2; |
| 68430 | u.aq.pLast = &u.aq.pData0[u.aq.nField-1]; |
| 68431 | u.aq.file_format = p->minWriteFileFormat; |
| 68432 | |
| @@ -68088,11 +68488,11 @@ | |
| 68488 | for(u.aq.pRec=u.aq.pData0; u.aq.pRec<=u.aq.pLast; u.aq.pRec++){ /* serial data */ |
| 68489 | u.aq.i += sqlite3VdbeSerialPut(&u.aq.zNewRecord[u.aq.i], (int)(u.aq.nByte-u.aq.i), u.aq.pRec,u.aq.file_format); |
| 68490 | } |
| 68491 | assert( u.aq.i==u.aq.nByte ); |
| 68492 | |
| 68493 | assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) ); |
| 68494 | pOut->n = (int)u.aq.nByte; |
| 68495 | pOut->flags = MEM_Blob | MEM_Dyn; |
| 68496 | pOut->xDel = 0; |
| 68497 | if( u.aq.nZero ){ |
| 68498 | pOut->u.nZero = u.aq.nZero; |
| @@ -68684,11 +69084,11 @@ | |
| 69084 | }else{ |
| 69085 | u.ay.wrFlag = 0; |
| 69086 | } |
| 69087 | if( pOp->p5 & OPFLAG_P2ISREG ){ |
| 69088 | assert( u.ay.p2>0 ); |
| 69089 | assert( u.ay.p2<=(p->nMem-p->nCursor) ); |
| 69090 | pIn2 = &aMem[u.ay.p2]; |
| 69091 | assert( memIsValid(pIn2) ); |
| 69092 | assert( (pIn2->flags & MEM_Int)!=0 ); |
| 69093 | sqlite3VdbeMemIntegerify(pIn2); |
| 69094 | u.ay.p2 = (int)pIn2->u.i; |
| @@ -69235,11 +69635,11 @@ | |
| 69635 | |
| 69636 | pIn3 = &aMem[pOp->p3]; |
| 69637 | u.bf.aMx = &aMem[pOp->p4.i]; |
| 69638 | /* Assert that the values of parameters P1 and P4 are in range. */ |
| 69639 | assert( pOp->p4type==P4_INT32 ); |
| 69640 | assert( pOp->p4.i>0 && pOp->p4.i<=(p->nMem-p->nCursor) ); |
| 69641 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 69642 | |
| 69643 | /* Find the index cursor. */ |
| 69644 | u.bf.pCx = p->apCsr[pOp->p1]; |
| 69645 | assert( u.bf.pCx->deferredMoveto==0 ); |
| @@ -69442,11 +69842,11 @@ | |
| 69842 | /* Assert that P3 is a valid memory cell. */ |
| 69843 | assert( pOp->p3<=u.bh.pFrame->nMem ); |
| 69844 | u.bh.pMem = &u.bh.pFrame->aMem[pOp->p3]; |
| 69845 | }else{ |
| 69846 | /* Assert that P3 is a valid memory cell. */ |
| 69847 | assert( pOp->p3<=(p->nMem-p->nCursor) ); |
| 69848 | u.bh.pMem = &aMem[pOp->p3]; |
| 69849 | memAboutToChange(p, u.bh.pMem); |
| 69850 | } |
| 69851 | assert( memIsValid(u.bh.pMem) ); |
| 69852 | |
| @@ -70120,11 +70520,11 @@ | |
| 70520 | int res; |
| 70521 | UnpackedRecord r; |
| 70522 | #endif /* local variables moved into u.bt */ |
| 70523 | |
| 70524 | assert( pOp->p3>0 ); |
| 70525 | assert( pOp->p2>0 && pOp->p2+pOp->p3<=(p->nMem-p->nCursor)+1 ); |
| 70526 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 70527 | u.bt.pC = p->apCsr[pOp->p1]; |
| 70528 | assert( u.bt.pC!=0 ); |
| 70529 | u.bt.pCrsr = u.bt.pC->pCursor; |
| 70530 | if( ALWAYS(u.bt.pCrsr!=0) ){ |
| @@ -70336,10 +70736,11 @@ | |
| 70736 | int nChange; |
| 70737 | #endif /* local variables moved into u.bx */ |
| 70738 | |
| 70739 | u.bx.nChange = 0; |
| 70740 | assert( p->readOnly==0 ); |
| 70741 | assert( pOp->p1!=1 ); |
| 70742 | assert( (p->btreeMask & (((yDbMask)1)<<pOp->p2))!=0 ); |
| 70743 | rc = sqlite3BtreeClearTable( |
| 70744 | db->aDb[pOp->p2].pBt, pOp->p1, (pOp->p3 ? &u.bx.nChange : 0) |
| 70745 | ); |
| 70746 | if( pOp->p3 ){ |
| @@ -70542,11 +70943,11 @@ | |
| 70943 | assert( p->bIsReader ); |
| 70944 | u.ca.nRoot = pOp->p2; |
| 70945 | assert( u.ca.nRoot>0 ); |
| 70946 | u.ca.aRoot = sqlite3DbMallocRaw(db, sizeof(int)*(u.ca.nRoot+1) ); |
| 70947 | if( u.ca.aRoot==0 ) goto no_mem; |
| 70948 | assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) ); |
| 70949 | u.ca.pnErr = &aMem[pOp->p3]; |
| 70950 | assert( (u.ca.pnErr->flags & MEM_Int)!=0 ); |
| 70951 | assert( (u.ca.pnErr->flags & (MEM_Str|MEM_Blob))==0 ); |
| 70952 | pIn1 = &aMem[pOp->p1]; |
| 70953 | for(u.ca.j=0; u.ca.j<u.ca.nRoot; u.ca.j++){ |
| @@ -70978,11 +71379,11 @@ | |
| 71379 | u.cg.apVal[u.cg.i] = u.cg.pRec; |
| 71380 | memAboutToChange(p, u.cg.pRec); |
| 71381 | sqlite3VdbeMemStoreType(u.cg.pRec); |
| 71382 | } |
| 71383 | u.cg.ctx.pFunc = pOp->p4.pFunc; |
| 71384 | assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) ); |
| 71385 | u.cg.ctx.pMem = u.cg.pMem = &aMem[pOp->p3]; |
| 71386 | u.cg.pMem->n++; |
| 71387 | u.cg.ctx.s.flags = MEM_Null; |
| 71388 | u.cg.ctx.s.z = 0; |
| 71389 | u.cg.ctx.s.zMalloc = 0; |
| @@ -71027,11 +71428,11 @@ | |
| 71428 | */ |
| 71429 | case OP_AggFinal: { |
| 71430 | #if 0 /* local variables moved into u.ch */ |
| 71431 | Mem *pMem; |
| 71432 | #endif /* local variables moved into u.ch */ |
| 71433 | assert( pOp->p1>0 && pOp->p1<=(p->nMem-p->nCursor) ); |
| 71434 | u.ch.pMem = &aMem[pOp->p1]; |
| 71435 | assert( (u.ch.pMem->flags & ~(MEM_Null|MEM_Agg))==0 ); |
| 71436 | rc = sqlite3VdbeMemFinalize(u.ch.pMem, pOp->p4.pFunc); |
| 71437 | if( rc ){ |
| 71438 | sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(u.ch.pMem)); |
| @@ -71458,11 +71859,11 @@ | |
| 71859 | sqlite3_context sContext; |
| 71860 | #endif /* local variables moved into u.co */ |
| 71861 | |
| 71862 | VdbeCursor *pCur = p->apCsr[pOp->p1]; |
| 71863 | assert( pCur->pVtabCursor ); |
| 71864 | assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) ); |
| 71865 | u.co.pDest = &aMem[pOp->p3]; |
| 71866 | memAboutToChange(p, u.co.pDest); |
| 71867 | if( pCur->nullRow ){ |
| 71868 | sqlite3VdbeMemSetNull(u.co.pDest); |
| 71869 | break; |
| @@ -76729,11 +77130,11 @@ | |
| 77130 | break; |
| 77131 | } |
| 77132 | case TK_UMINUS: { |
| 77133 | int v; |
| 77134 | if( sqlite3ExprIsInteger(p->pLeft, &v) ){ |
| 77135 | assert( v!=(-2147483647-1) ); |
| 77136 | *pValue = -v; |
| 77137 | rc = 1; |
| 77138 | } |
| 77139 | break; |
| 77140 | } |
| @@ -80389,11 +80790,11 @@ | |
| 80790 | |
| 80791 | /* Ensure the default expression is something that sqlite3ValueFromExpr() |
| 80792 | ** can handle (i.e. not CURRENT_TIME etc.) |
| 80793 | */ |
| 80794 | if( pDflt ){ |
| 80795 | sqlite3_value *pVal = 0; |
| 80796 | if( sqlite3ValueFromExpr(db, pDflt, SQLITE_UTF8, SQLITE_AFF_NONE, &pVal) ){ |
| 80797 | db->mallocFailed = 1; |
| 80798 | return; |
| 80799 | } |
| 80800 | if( !pVal ){ |
| @@ -80530,11 +80931,11 @@ | |
| 80931 | #endif /* SQLITE_ALTER_TABLE */ |
| 80932 | |
| 80933 | /************** End of alter.c ***********************************************/ |
| 80934 | /************** Begin file analyze.c *****************************************/ |
| 80935 | /* |
| 80936 | ** 2005-07-08 |
| 80937 | ** |
| 80938 | ** The author disclaims copyright to this source code. In place of |
| 80939 | ** a legal notice, here is a blessing: |
| 80940 | ** |
| 80941 | ** May you do good and not evil. |
| @@ -80551,27 +80952,36 @@ | |
| 80952 | ** The following system tables are or have been supported: |
| 80953 | ** |
| 80954 | ** CREATE TABLE sqlite_stat1(tbl, idx, stat); |
| 80955 | ** CREATE TABLE sqlite_stat2(tbl, idx, sampleno, sample); |
| 80956 | ** CREATE TABLE sqlite_stat3(tbl, idx, nEq, nLt, nDLt, sample); |
| 80957 | ** CREATE TABLE sqlite_stat4(tbl, idx, nEq, nLt, nDLt, sample); |
| 80958 | ** |
| 80959 | ** Additional tables might be added in future releases of SQLite. |
| 80960 | ** The sqlite_stat2 table is not created or used unless the SQLite version |
| 80961 | ** is between 3.6.18 and 3.7.8, inclusive, and unless SQLite is compiled |
| 80962 | ** with SQLITE_ENABLE_STAT2. The sqlite_stat2 table is deprecated. |
| 80963 | ** The sqlite_stat2 table is superseded by sqlite_stat3, which is only |
| 80964 | ** created and used by SQLite versions 3.7.9 and later and with |
| 80965 | ** SQLITE_ENABLE_STAT3 defined. The functionality of sqlite_stat3 |
| 80966 | ** is a superset of sqlite_stat2. The sqlite_stat4 is an enhanced |
| 80967 | ** version of sqlite_stat3 and is only available when compiled with |
| 80968 | ** SQLITE_ENABLE_STAT4 and in SQLite versions 3.8.0 and later. It is |
| 80969 | ** not possible to enable both STAT3 and STAT4 at the same time. If they |
| 80970 | ** are both enabled, then STAT4 is precedence. |
| 80971 | ** |
| 80972 | ** For most applications, sqlite_stat1 provides all the statisics required |
| 80973 | ** for the query planner to make good choices. |
| 80974 | ** |
| 80975 | ** Format of sqlite_stat1: |
| 80976 | ** |
| 80977 | ** There is normally one row per index, with the index identified by the |
| 80978 | ** name in the idx column. The tbl column is the name of the table to |
| 80979 | ** which the index belongs. In each such row, the stat column will be |
| 80980 | ** a string consisting of a list of integers. The first integer in this |
| 80981 | ** list is the number of rows in the index. (This is the same as the |
| 80982 | ** number of rows in the table, except for partial indices.) The second |
| 80983 | ** integer is the average number of rows in the index that have the same |
| 80984 | ** value in the first column of the index. The third integer is the average |
| 80985 | ** number of rows in the index that have the same value for the first two |
| 80986 | ** columns. The N-th integer (for N>1) is the average number of rows in |
| 80987 | ** the index which have the same value for the first N-1 columns. For |
| @@ -80614,57 +81024,85 @@ | |
| 81024 | ** writes the sqlite_stat2 table. This version of SQLite only supports |
| 81025 | ** sqlite_stat3. |
| 81026 | ** |
| 81027 | ** Format for sqlite_stat3: |
| 81028 | ** |
| 81029 | ** The sqlite_stat3 format is a subset of sqlite_stat4. Hence, the |
| 81030 | ** sqlite_stat4 format will be described first. Further information |
| 81031 | ** about sqlite_stat3 follows the sqlite_stat4 description. |
| 81032 | ** |
| 81033 | ** Format for sqlite_stat4: |
| 81034 | ** |
| 81035 | ** As with sqlite_stat2, the sqlite_stat4 table contains histogram data |
| 81036 | ** to aid the query planner in choosing good indices based on the values |
| 81037 | ** that indexed columns are compared against in the WHERE clauses of |
| 81038 | ** queries. |
| 81039 | ** |
| 81040 | ** The sqlite_stat4 table contains multiple entries for each index. |
| 81041 | ** The idx column names the index and the tbl column is the table of the |
| 81042 | ** index. If the idx and tbl columns are the same, then the sample is |
| 81043 | ** of the INTEGER PRIMARY KEY. The sample column is a blob which is the |
| 81044 | ** binary encoding of a key from the index, with the trailing rowid |
| 81045 | ** omitted. The nEq column is a list of integers. The first integer |
| 81046 | ** is the approximate number of entries in the index whose left-most |
| 81047 | ** column exactly matches the left-most column of the sample. The second |
| 81048 | ** integer in nEq is the approximate number of entries in the index where |
| 81049 | ** the first two columns match the first two columns of the sample. |
| 81050 | ** And so forth. nLt is another list of integers that show the approximate |
| 81051 | ** number of entries that are strictly less than the sample. The first |
| 81052 | ** integer in nLt contains the number of entries in the index where the |
| 81053 | ** left-most column is less than the left-most column of the sample. |
| 81054 | ** The K-th integer in the nLt entry is the number of index entries |
| 81055 | ** where the first K columns are less than the first K columns of the |
| 81056 | ** sample. The nDLt column is like nLt except that it contains the |
| 81057 | ** number of distinct entries in the index that are less than the |
| 81058 | ** sample. |
| 81059 | ** |
| 81060 | ** There can be an arbitrary number of sqlite_stat4 entries per index. |
| 81061 | ** The ANALYZE command will typically generate sqlite_stat4 tables |
| 81062 | ** that contain between 10 and 40 samples which are distributed across |
| 81063 | ** the key space, though not uniformly, and which include samples with |
| 81064 | ** large nEq values. |
| 81065 | ** |
| 81066 | ** Format for sqlite_stat3 redux: |
| 81067 | ** |
| 81068 | ** The sqlite_stat3 table is like sqlite_stat4 except that it only |
| 81069 | ** looks at the left-most column of the index. The sqlite_stat3.sample |
| 81070 | ** column contains the actual value of the left-most column instead |
| 81071 | ** of a blob encoding of the complete index key as is found in |
| 81072 | ** sqlite_stat4.sample. The nEq, nLt, and nDLt entries of sqlite_stat3 |
| 81073 | ** all contain just a single integer which is the same as the first |
| 81074 | ** integer in the equivalent columns in sqlite_stat4. |
| 81075 | */ |
| 81076 | #ifndef SQLITE_OMIT_ANALYZE |
| 81077 | |
| 81078 | #if defined(SQLITE_ENABLE_STAT4) |
| 81079 | # define IsStat4 1 |
| 81080 | # define IsStat3 0 |
| 81081 | #elif defined(SQLITE_ENABLE_STAT3) |
| 81082 | # define IsStat4 0 |
| 81083 | # define IsStat3 1 |
| 81084 | #else |
| 81085 | # define IsStat4 0 |
| 81086 | # define IsStat3 0 |
| 81087 | # undef SQLITE_STAT4_SAMPLES |
| 81088 | # define SQLITE_STAT4_SAMPLES 1 |
| 81089 | #endif |
| 81090 | #define IsStat34 (IsStat3+IsStat4) /* 1 for STAT3 or STAT4. 0 otherwise */ |
| 81091 | |
| 81092 | /* |
| 81093 | ** This routine generates code that opens the sqlite_statN tables. |
| 81094 | ** The sqlite_stat1 table is always relevant. sqlite_stat2 is now |
| 81095 | ** obsolete. sqlite_stat3 and sqlite_stat4 are only opened when |
| 81096 | ** appropriate compile-time options are provided. |
| 81097 | ** |
| 81098 | ** If the sqlite_statN tables do not previously exist, it is created. |
| 81099 | ** |
| 81100 | ** Argument zWhere may be a pointer to a buffer containing a table name, |
| 81101 | ** or it may be a NULL pointer. If it is not NULL, then all entries in |
| 81102 | ** the sqlite_statN tables associated with the named table are deleted. |
| 81103 | ** If zWhere==0, then code is generated to delete all stat table entries. |
| 81104 | */ |
| 81105 | static void openStatTable( |
| 81106 | Parse *pParse, /* Parsing context */ |
| 81107 | int iDb, /* The database we are looking in */ |
| 81108 | int iStatCur, /* Open the sqlite_stat1 table on this cursor */ |
| @@ -80674,22 +81112,28 @@ | |
| 81112 | static const struct { |
| 81113 | const char *zName; |
| 81114 | const char *zCols; |
| 81115 | } aTable[] = { |
| 81116 | { "sqlite_stat1", "tbl,idx,stat" }, |
| 81117 | #if defined(SQLITE_ENABLE_STAT4) |
| 81118 | { "sqlite_stat4", "tbl,idx,neq,nlt,ndlt,sample" }, |
| 81119 | { "sqlite_stat3", 0 }, |
| 81120 | #elif defined(SQLITE_ENABLE_STAT3) |
| 81121 | { "sqlite_stat3", "tbl,idx,neq,nlt,ndlt,sample" }, |
| 81122 | { "sqlite_stat4", 0 }, |
| 81123 | #else |
| 81124 | { "sqlite_stat3", 0 }, |
| 81125 | { "sqlite_stat4", 0 }, |
| 81126 | #endif |
| 81127 | }; |
| 81128 | int i; |
| 81129 | sqlite3 *db = pParse->db; |
| 81130 | Db *pDb; |
| 81131 | Vdbe *v = sqlite3GetVdbe(pParse); |
| 81132 | int aRoot[ArraySize(aTable)]; |
| 81133 | u8 aCreateTbl[ArraySize(aTable)]; |
| 81134 | |
| 81135 | if( v==0 ) return; |
| 81136 | assert( sqlite3BtreeHoldsAllMutexes(db) ); |
| 81137 | assert( sqlite3VdbeDb(v)==db ); |
| 81138 | pDb = &db->aDb[iDb]; |
| 81139 | |
| @@ -80698,262 +81142,592 @@ | |
| 81142 | */ |
| 81143 | for(i=0; i<ArraySize(aTable); i++){ |
| 81144 | const char *zTab = aTable[i].zName; |
| 81145 | Table *pStat; |
| 81146 | if( (pStat = sqlite3FindTable(db, zTab, pDb->zName))==0 ){ |
| 81147 | if( aTable[i].zCols ){ |
| 81148 | /* The sqlite_statN table does not exist. Create it. Note that a |
| 81149 | ** side-effect of the CREATE TABLE statement is to leave the rootpage |
| 81150 | ** of the new table in register pParse->regRoot. This is important |
| 81151 | ** because the OpenWrite opcode below will be needing it. */ |
| 81152 | sqlite3NestedParse(pParse, |
| 81153 | "CREATE TABLE %Q.%s(%s)", pDb->zName, zTab, aTable[i].zCols |
| 81154 | ); |
| 81155 | aRoot[i] = pParse->regRoot; |
| 81156 | aCreateTbl[i] = OPFLAG_P2ISREG; |
| 81157 | } |
| 81158 | }else{ |
| 81159 | /* The table already exists. If zWhere is not NULL, delete all entries |
| 81160 | ** associated with the table zWhere. If zWhere is NULL, delete the |
| 81161 | ** entire contents of the table. */ |
| 81162 | aRoot[i] = pStat->tnum; |
| 81163 | aCreateTbl[i] = 0; |
| 81164 | sqlite3TableLock(pParse, iDb, aRoot[i], 1, zTab); |
| 81165 | if( zWhere ){ |
| 81166 | sqlite3NestedParse(pParse, |
| 81167 | "DELETE FROM %Q.%s WHERE %s=%Q", |
| 81168 | pDb->zName, zTab, zWhereType, zWhere |
| 81169 | ); |
| 81170 | }else{ |
| 81171 | /* The sqlite_stat[134] table already exists. Delete all rows. */ |
| 81172 | sqlite3VdbeAddOp2(v, OP_Clear, aRoot[i], iDb); |
| 81173 | } |
| 81174 | } |
| 81175 | } |
| 81176 | |
| 81177 | /* Open the sqlite_stat[134] tables for writing. */ |
| 81178 | for(i=0; aTable[i].zCols; i++){ |
| 81179 | assert( i<ArraySize(aTable) ); |
| 81180 | sqlite3VdbeAddOp3(v, OP_OpenWrite, iStatCur+i, aRoot[i], iDb); |
| 81181 | sqlite3VdbeChangeP4(v, -1, (char *)3, P4_INT32); |
| 81182 | sqlite3VdbeChangeP5(v, aCreateTbl[i]); |
| 81183 | } |
| 81184 | } |
| 81185 | |
| 81186 | /* |
| 81187 | ** Recommended number of samples for sqlite_stat4 |
| 81188 | */ |
| 81189 | #ifndef SQLITE_STAT4_SAMPLES |
| 81190 | # define SQLITE_STAT4_SAMPLES 24 |
| 81191 | #endif |
| 81192 | |
| 81193 | /* |
| 81194 | ** Three SQL functions - stat_init(), stat_push(), and stat_get() - |
| 81195 | ** share an instance of the following structure to hold their state |
| 81196 | ** information. |
| 81197 | */ |
| 81198 | typedef struct Stat4Accum Stat4Accum; |
| 81199 | typedef struct Stat4Sample Stat4Sample; |
| 81200 | struct Stat4Sample { |
| 81201 | tRowcnt *anEq; /* sqlite_stat4.nEq */ |
| 81202 | tRowcnt *anDLt; /* sqlite_stat4.nDLt */ |
| 81203 | #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 81204 | tRowcnt *anLt; /* sqlite_stat4.nLt */ |
| 81205 | i64 iRowid; /* Rowid in main table of the key */ |
| 81206 | u8 isPSample; /* True if a periodic sample */ |
| 81207 | int iCol; /* If !isPSample, the reason for inclusion */ |
| 81208 | u32 iHash; /* Tiebreaker hash */ |
| 81209 | #endif |
| 81210 | }; |
| 81211 | struct Stat4Accum { |
| 81212 | tRowcnt nRow; /* Number of rows in the entire table */ |
| 81213 | tRowcnt nPSample; /* How often to do a periodic sample */ |
| 81214 | int nCol; /* Number of columns in index + rowid */ |
| 81215 | int mxSample; /* Maximum number of samples to accumulate */ |
| 81216 | Stat4Sample current; /* Current row as a Stat4Sample */ |
| 81217 | u32 iPrn; /* Pseudo-random number used for sampling */ |
| 81218 | Stat4Sample *aBest; /* Array of (nCol-1) best samples */ |
| 81219 | int iMin; /* Index in a[] of entry with minimum score */ |
| 81220 | int nSample; /* Current number of samples */ |
| 81221 | int iGet; /* Index of current sample accessed by stat_get() */ |
| 81222 | Stat4Sample *a; /* Array of mxSample Stat4Sample objects */ |
| 81223 | }; |
| 81224 | |
| 81225 | /* |
| 81226 | ** Implementation of the stat_init(N,C) SQL function. The two parameters |
| 81227 | ** are the number of rows in the table or index (C) and the number of columns |
| 81228 | ** in the index (N). The second argument (C) is only used for STAT3 and STAT4. |
| 81229 | ** |
| 81230 | ** This routine allocates the Stat4Accum object in heap memory. The return |
| 81231 | ** value is a pointer to the the Stat4Accum object encoded as a blob (i.e. |
| 81232 | ** the size of the blob is sizeof(void*) bytes). |
| 81233 | */ |
| 81234 | static void statInit( |
| 81235 | sqlite3_context *context, |
| 81236 | int argc, |
| 81237 | sqlite3_value **argv |
| 81238 | ){ |
| 81239 | Stat4Accum *p; |
| 81240 | int nCol; /* Number of columns in index being sampled */ |
| 81241 | int nColUp; /* nCol rounded up for alignment */ |
| 81242 | int n; /* Bytes of space to allocate */ |
| 81243 | #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 81244 | int mxSample = SQLITE_STAT4_SAMPLES; |
| 81245 | #endif |
| 81246 | |
| 81247 | /* Decode the three function arguments */ |
| 81248 | UNUSED_PARAMETER(argc); |
| 81249 | nCol = sqlite3_value_int(argv[0]); |
| 81250 | assert( nCol>1 ); /* >1 because it includes the rowid column */ |
| 81251 | nColUp = sizeof(tRowcnt)<8 ? (nCol+1)&~1 : nCol; |
| 81252 | |
| 81253 | /* Allocate the space required for the Stat4Accum object */ |
| 81254 | n = sizeof(*p) |
| 81255 | + sizeof(tRowcnt)*nColUp /* Stat4Accum.anEq */ |
| 81256 | + sizeof(tRowcnt)*nColUp /* Stat4Accum.anDLt */ |
| 81257 | #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 81258 | + sizeof(tRowcnt)*nColUp /* Stat4Accum.anLt */ |
| 81259 | + sizeof(Stat4Sample)*(nCol+mxSample) /* Stat4Accum.aBest[], a[] */ |
| 81260 | + sizeof(tRowcnt)*3*nColUp*(nCol+mxSample) |
| 81261 | #endif |
| 81262 | ; |
| 81263 | p = sqlite3MallocZero(n); |
| 81264 | if( p==0 ){ |
| 81265 | sqlite3_result_error_nomem(context); |
| 81266 | return; |
| 81267 | } |
| 81268 | |
| 81269 | p->nRow = 0; |
| 81270 | p->nCol = nCol; |
| 81271 | p->current.anDLt = (tRowcnt*)&p[1]; |
| 81272 | p->current.anEq = &p->current.anDLt[nColUp]; |
| 81273 | |
| 81274 | #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 81275 | { |
| 81276 | u8 *pSpace; /* Allocated space not yet assigned */ |
| 81277 | int i; /* Used to iterate through p->aSample[] */ |
| 81278 | |
| 81279 | p->iGet = -1; |
| 81280 | p->mxSample = mxSample; |
| 81281 | p->nPSample = sqlite3_value_int64(argv[1])/(mxSample/3+1) + 1; |
| 81282 | p->current.anLt = &p->current.anEq[nColUp]; |
| 81283 | sqlite3_randomness(sizeof(p->iPrn), &p->iPrn); |
| 81284 | |
| 81285 | /* Set up the Stat4Accum.a[] and aBest[] arrays */ |
| 81286 | p->a = (struct Stat4Sample*)&p->current.anLt[nColUp]; |
| 81287 | p->aBest = &p->a[mxSample]; |
| 81288 | pSpace = (u8*)(&p->a[mxSample+nCol]); |
| 81289 | for(i=0; i<(mxSample+nCol); i++){ |
| 81290 | p->a[i].anEq = (tRowcnt *)pSpace; pSpace += (sizeof(tRowcnt) * nColUp); |
| 81291 | p->a[i].anLt = (tRowcnt *)pSpace; pSpace += (sizeof(tRowcnt) * nColUp); |
| 81292 | p->a[i].anDLt = (tRowcnt *)pSpace; pSpace += (sizeof(tRowcnt) * nColUp); |
| 81293 | } |
| 81294 | assert( (pSpace - (u8*)p)==n ); |
| 81295 | |
| 81296 | for(i=0; i<nCol; i++){ |
| 81297 | p->aBest[i].iCol = i; |
| 81298 | } |
| 81299 | } |
| 81300 | #endif |
| 81301 | |
| 81302 | /* Return a pointer to the allocated object to the caller */ |
| 81303 | sqlite3_result_blob(context, p, sizeof(p), sqlite3_free); |
| 81304 | } |
| 81305 | static const FuncDef statInitFuncdef = { |
| 81306 | 1+IsStat34, /* nArg */ |
| 81307 | SQLITE_UTF8, /* iPrefEnc */ |
| 81308 | 0, /* flags */ |
| 81309 | 0, /* pUserData */ |
| 81310 | 0, /* pNext */ |
| 81311 | statInit, /* xFunc */ |
| 81312 | 0, /* xStep */ |
| 81313 | 0, /* xFinalize */ |
| 81314 | "stat_init", /* zName */ |
| 81315 | 0, /* pHash */ |
| 81316 | 0 /* pDestructor */ |
| 81317 | }; |
| 81318 | |
| 81319 | #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 81320 | /* |
| 81321 | ** Return true if pNew is to be preferred over pOld. |
| 81322 | */ |
| 81323 | static int sampleIsBetter(Stat4Sample *pNew, Stat4Sample *pOld){ |
| 81324 | tRowcnt nEqNew = pNew->anEq[pNew->iCol]; |
| 81325 | tRowcnt nEqOld = pOld->anEq[pOld->iCol]; |
| 81326 | |
| 81327 | assert( pOld->isPSample==0 && pNew->isPSample==0 ); |
| 81328 | assert( IsStat4 || (pNew->iCol==0 && pOld->iCol==0) ); |
| 81329 | |
| 81330 | if( (nEqNew>nEqOld) |
| 81331 | || (nEqNew==nEqOld && pNew->iCol<pOld->iCol) |
| 81332 | || (nEqNew==nEqOld && pNew->iCol==pOld->iCol && pNew->iHash>pOld->iHash) |
| 81333 | ){ |
| 81334 | return 1; |
| 81335 | } |
| 81336 | return 0; |
| 81337 | } |
| 81338 | |
| 81339 | /* |
| 81340 | ** Copy the contents of object (*pFrom) into (*pTo). |
| 81341 | */ |
| 81342 | void sampleCopy(Stat4Accum *p, Stat4Sample *pTo, Stat4Sample *pFrom){ |
| 81343 | pTo->iRowid = pFrom->iRowid; |
| 81344 | pTo->isPSample = pFrom->isPSample; |
| 81345 | pTo->iCol = pFrom->iCol; |
| 81346 | pTo->iHash = pFrom->iHash; |
| 81347 | memcpy(pTo->anEq, pFrom->anEq, sizeof(tRowcnt)*p->nCol); |
| 81348 | memcpy(pTo->anLt, pFrom->anLt, sizeof(tRowcnt)*p->nCol); |
| 81349 | memcpy(pTo->anDLt, pFrom->anDLt, sizeof(tRowcnt)*p->nCol); |
| 81350 | } |
| 81351 | |
| 81352 | /* |
| 81353 | ** Copy the contents of sample *pNew into the p->a[] array. If necessary, |
| 81354 | ** remove the least desirable sample from p->a[] to make room. |
| 81355 | */ |
| 81356 | static void sampleInsert(Stat4Accum *p, Stat4Sample *pNew, int nEqZero){ |
| 81357 | Stat4Sample *pSample; |
| 81358 | int i; |
| 81359 | i64 iSeq; |
| 81360 | i64 iPos; |
| 81361 | |
| 81362 | assert( IsStat4 || nEqZero==0 ); |
| 81363 | |
| 81364 | if( pNew->isPSample==0 ){ |
| 81365 | Stat4Sample *pUpgrade = 0; |
| 81366 | assert( pNew->anEq[pNew->iCol]>0 ); |
| 81367 | |
| 81368 | /* This sample is being added because the prefix that ends in column |
| 81369 | ** iCol occurs many times in the table. However, if we have already |
| 81370 | ** added a sample that shares this prefix, there is no need to add |
| 81371 | ** this one. Instead, upgrade the priority of the highest priority |
| 81372 | ** existing sample that shares this prefix. */ |
| 81373 | for(i=p->nSample-1; i>=0; i--){ |
| 81374 | Stat4Sample *pOld = &p->a[i]; |
| 81375 | if( pOld->anEq[pNew->iCol]==0 ){ |
| 81376 | if( pOld->isPSample ) return; |
| 81377 | assert( sampleIsBetter(pNew, pOld) ); |
| 81378 | if( pUpgrade==0 || sampleIsBetter(pOld, pUpgrade) ){ |
| 81379 | pUpgrade = pOld; |
| 81380 | } |
| 81381 | } |
| 81382 | } |
| 81383 | if( pUpgrade ){ |
| 81384 | pUpgrade->iCol = pNew->iCol; |
| 81385 | pUpgrade->anEq[pUpgrade->iCol] = pNew->anEq[pUpgrade->iCol]; |
| 81386 | goto find_new_min; |
| 81387 | } |
| 81388 | } |
| 81389 | |
| 81390 | /* If necessary, remove sample iMin to make room for the new sample. */ |
| 81391 | if( p->nSample>=p->mxSample ){ |
| 81392 | Stat4Sample *pMin = &p->a[p->iMin]; |
| 81393 | tRowcnt *anEq = pMin->anEq; |
| 81394 | tRowcnt *anLt = pMin->anLt; |
| 81395 | tRowcnt *anDLt = pMin->anDLt; |
| 81396 | memmove(pMin, &pMin[1], sizeof(p->a[0])*(p->nSample-p->iMin-1)); |
| 81397 | pSample = &p->a[p->nSample-1]; |
| 81398 | pSample->anEq = anEq; |
| 81399 | pSample->anDLt = anDLt; |
| 81400 | pSample->anLt = anLt; |
| 81401 | p->nSample = p->mxSample-1; |
| 81402 | } |
| 81403 | |
| 81404 | /* Figure out where in the a[] array the new sample should be inserted. */ |
| 81405 | iSeq = pNew->anLt[p->nCol-1]; |
| 81406 | for(iPos=p->nSample; iPos>0; iPos--){ |
| 81407 | if( iSeq>p->a[iPos-1].anLt[p->nCol-1] ) break; |
| 81408 | } |
| 81409 | |
| 81410 | /* Insert the new sample */ |
| 81411 | pSample = &p->a[iPos]; |
| 81412 | if( iPos!=p->nSample ){ |
| 81413 | Stat4Sample *pEnd = &p->a[p->nSample]; |
| 81414 | tRowcnt *anEq = pEnd->anEq; |
| 81415 | tRowcnt *anLt = pEnd->anLt; |
| 81416 | tRowcnt *anDLt = pEnd->anDLt; |
| 81417 | memmove(&p->a[iPos], &p->a[iPos+1], (p->nSample-iPos)*sizeof(p->a[0])); |
| 81418 | pSample->anEq = anEq; |
| 81419 | pSample->anDLt = anDLt; |
| 81420 | pSample->anLt = anLt; |
| 81421 | } |
| 81422 | p->nSample++; |
| 81423 | sampleCopy(p, pSample, pNew); |
| 81424 | |
| 81425 | /* Zero the first nEqZero entries in the anEq[] array. */ |
| 81426 | memset(pSample->anEq, 0, sizeof(tRowcnt)*nEqZero); |
| 81427 | |
| 81428 | find_new_min: |
| 81429 | if( p->nSample>=p->mxSample ){ |
| 81430 | int iMin = -1; |
| 81431 | for(i=0; i<p->mxSample; i++){ |
| 81432 | if( p->a[i].isPSample ) continue; |
| 81433 | if( iMin<0 || sampleIsBetter(&p->a[iMin], &p->a[i]) ){ |
| 81434 | iMin = i; |
| 81435 | } |
| 81436 | } |
| 81437 | assert( iMin>=0 ); |
| 81438 | p->iMin = iMin; |
| 81439 | } |
| 81440 | } |
| 81441 | #endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */ |
| 81442 | |
| 81443 | /* |
| 81444 | ** Field iChng of the index being scanned has changed. So at this point |
| 81445 | ** p->current contains a sample that reflects the previous row of the |
| 81446 | ** index. The value of anEq[iChng] and subsequent anEq[] elements are |
| 81447 | ** correct at this point. |
| 81448 | */ |
| 81449 | static void samplePushPrevious(Stat4Accum *p, int iChng){ |
| 81450 | #ifdef SQLITE_ENABLE_STAT4 |
| 81451 | int i; |
| 81452 | |
| 81453 | /* Check if any samples from the aBest[] array should be pushed |
| 81454 | ** into IndexSample.a[] at this point. */ |
| 81455 | for(i=(p->nCol-2); i>=iChng; i--){ |
| 81456 | Stat4Sample *pBest = &p->aBest[i]; |
| 81457 | if( p->nSample<p->mxSample |
| 81458 | || sampleIsBetter(pBest, &p->a[p->iMin]) |
| 81459 | ){ |
| 81460 | sampleInsert(p, pBest, i); |
| 81461 | } |
| 81462 | } |
| 81463 | |
| 81464 | /* Update the anEq[] fields of any samples already collected. */ |
| 81465 | for(i=p->nSample-1; i>=0; i--){ |
| 81466 | int j; |
| 81467 | for(j=iChng; j<p->nCol; j++){ |
| 81468 | if( p->a[i].anEq[j]==0 ) p->a[i].anEq[j] = p->current.anEq[j]; |
| 81469 | } |
| 81470 | } |
| 81471 | #endif |
| 81472 | |
| 81473 | #if defined(SQLITE_ENABLE_STAT3) && !defined(SQLITE_ENABLE_STAT4) |
| 81474 | if( iChng==0 ){ |
| 81475 | tRowcnt nLt = p->current.anLt[0]; |
| 81476 | tRowcnt nEq = p->current.anEq[0]; |
| 81477 | |
| 81478 | /* Check if this is to be a periodic sample. If so, add it. */ |
| 81479 | if( (nLt/p->nPSample)!=(nLt+nEq)/p->nPSample ){ |
| 81480 | p->current.isPSample = 1; |
| 81481 | sampleInsert(p, &p->current, 0); |
| 81482 | p->current.isPSample = 0; |
| 81483 | }else |
| 81484 | |
| 81485 | /* Or if it is a non-periodic sample. Add it in this case too. */ |
| 81486 | if( p->nSample<p->mxSample || sampleIsBetter(&p->current, &p->a[p->iMin]) ){ |
| 81487 | sampleInsert(p, &p->current, 0); |
| 81488 | } |
| 81489 | } |
| 81490 | #endif |
| 81491 | } |
| 81492 | |
| 81493 | /* |
| 81494 | ** Implementation of the stat_push SQL function: stat_push(P,R,C) |
| 81495 | ** Arguments: |
| 81496 | ** |
| 81497 | ** P Pointer to the Stat4Accum object created by stat_init() |
| 81498 | ** C Index of left-most column to differ from previous row |
| 81499 | ** R Rowid for the current row |
| 81500 | ** |
| 81501 | ** The SQL function always returns NULL. |
| 81502 | ** |
| 81503 | ** The R parameter is only used for STAT3 and STAT4. |
| 81504 | */ |
| 81505 | static void statPush( |
| 81506 | sqlite3_context *context, |
| 81507 | int argc, |
| 81508 | sqlite3_value **argv |
| 81509 | ){ |
| 81510 | int i; |
| 81511 | |
| 81512 | /* The three function arguments */ |
| 81513 | Stat4Accum *p = (Stat4Accum*)sqlite3_value_blob(argv[0]); |
| 81514 | int iChng = sqlite3_value_int(argv[1]); |
| 81515 | |
| 81516 | assert( p->nCol>1 ); /* Includes rowid field */ |
| 81517 | assert( iChng<p->nCol ); |
| 81518 | |
| 81519 | if( p->nRow==0 ){ |
| 81520 | /* anEq[0] is only zero for the very first call to this function. Do |
| 81521 | ** appropriate initialization */ |
| 81522 | for(i=0; i<p->nCol; i++) p->current.anEq[i] = 1; |
| 81523 | }else{ |
| 81524 | /* Second and subsequent calls get processed here */ |
| 81525 | samplePushPrevious(p, iChng); |
| 81526 | |
| 81527 | /* Update anDLt[], anLt[] and anEq[] to reflect the values that apply |
| 81528 | ** to the current row of the index. */ |
| 81529 | for(i=0; i<iChng; i++){ |
| 81530 | p->current.anEq[i]++; |
| 81531 | } |
| 81532 | for(i=iChng; i<p->nCol; i++){ |
| 81533 | p->current.anDLt[i]++; |
| 81534 | #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 81535 | p->current.anLt[i] += p->current.anEq[i]; |
| 81536 | #endif |
| 81537 | p->current.anEq[i] = 1; |
| 81538 | } |
| 81539 | } |
| 81540 | p->nRow++; |
| 81541 | #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 81542 | p->current.iRowid = sqlite3_value_int64(argv[2]); |
| 81543 | p->current.iHash = p->iPrn = p->iPrn*1103515245 + 12345; |
| 81544 | #endif |
| 81545 | |
| 81546 | #ifdef SQLITE_ENABLE_STAT4 |
| 81547 | { |
| 81548 | tRowcnt nLt = p->current.anLt[p->nCol-1]; |
| 81549 | |
| 81550 | /* Check if this is to be a periodic sample. If so, add it. */ |
| 81551 | if( (nLt/p->nPSample)!=(nLt+1)/p->nPSample ){ |
| 81552 | p->current.isPSample = 1; |
| 81553 | p->current.iCol = 0; |
| 81554 | sampleInsert(p, &p->current, p->nCol-1); |
| 81555 | p->current.isPSample = 0; |
| 81556 | } |
| 81557 | |
| 81558 | /* Update the aBest[] array. */ |
| 81559 | for(i=0; i<(p->nCol-1); i++){ |
| 81560 | p->current.iCol = i; |
| 81561 | if( i>=iChng || sampleIsBetter(&p->current, &p->aBest[i]) ){ |
| 81562 | sampleCopy(p, &p->aBest[i], &p->current); |
| 81563 | } |
| 81564 | } |
| 81565 | } |
| 81566 | #endif |
| 81567 | } |
| 81568 | static const FuncDef statPushFuncdef = { |
| 81569 | 2+IsStat34, /* nArg */ |
| 81570 | SQLITE_UTF8, /* iPrefEnc */ |
| 81571 | 0, /* flags */ |
| 81572 | 0, /* pUserData */ |
| 81573 | 0, /* pNext */ |
| 81574 | statPush, /* xFunc */ |
| 81575 | 0, /* xStep */ |
| 81576 | 0, /* xFinalize */ |
| 81577 | "stat_push", /* zName */ |
| 81578 | 0, /* pHash */ |
| 81579 | 0 /* pDestructor */ |
| 81580 | }; |
| 81581 | |
| 81582 | #define STAT_GET_STAT1 0 /* "stat" column of stat1 table */ |
| 81583 | #define STAT_GET_ROWID 1 /* "rowid" column of stat[34] entry */ |
| 81584 | #define STAT_GET_NEQ 2 /* "neq" column of stat[34] entry */ |
| 81585 | #define STAT_GET_NLT 3 /* "nlt" column of stat[34] entry */ |
| 81586 | #define STAT_GET_NDLT 4 /* "ndlt" column of stat[34] entry */ |
| 81587 | |
| 81588 | /* |
| 81589 | ** Implementation of the stat_get(P,J) SQL function. This routine is |
| 81590 | ** used to query the results. Content is returned for parameter J |
| 81591 | ** which is one of the STAT_GET_xxxx values defined above. |
| 81592 | ** |
| 81593 | ** If neither STAT3 nor STAT4 are enabled, then J is always |
| 81594 | ** STAT_GET_STAT1 and is hence omitted and this routine becomes |
| 81595 | ** a one-parameter function, stat_get(P), that always returns the |
| 81596 | ** stat1 table entry information. |
| 81597 | */ |
| 81598 | static void statGet( |
| 81599 | sqlite3_context *context, |
| 81600 | int argc, |
| 81601 | sqlite3_value **argv |
| 81602 | ){ |
| 81603 | Stat4Accum *p = (Stat4Accum*)sqlite3_value_blob(argv[0]); |
| 81604 | #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 81605 | /* STAT3 and STAT4 have a parameter on this routine. */ |
| 81606 | int eCall = sqlite3_value_int(argv[1]); |
| 81607 | assert( argc==2 ); |
| 81608 | assert( eCall==STAT_GET_STAT1 || eCall==STAT_GET_NEQ |
| 81609 | || eCall==STAT_GET_ROWID || eCall==STAT_GET_NLT |
| 81610 | || eCall==STAT_GET_NDLT |
| 81611 | ); |
| 81612 | if( eCall==STAT_GET_STAT1 ) |
| 81613 | #else |
| 81614 | assert( argc==1 ); |
| 81615 | #endif |
| 81616 | { |
| 81617 | /* Return the value to store in the "stat" column of the sqlite_stat1 |
| 81618 | ** table for this index. |
| 81619 | ** |
| 81620 | ** The value is a string composed of a list of integers describing |
| 81621 | ** the index. The first integer in the list is the total number of |
| 81622 | ** entries in the index. There is one additional integer in the list |
| 81623 | ** for each indexed column. This additional integer is an estimate of |
| 81624 | ** the number of rows matched by a stabbing query on the index using |
| 81625 | ** a key with the corresponding number of fields. In other words, |
| 81626 | ** if the index is on columns (a,b) and the sqlite_stat1 value is |
| 81627 | ** "100 10 2", then SQLite estimates that: |
| 81628 | ** |
| 81629 | ** * the index contains 100 rows, |
| 81630 | ** * "WHERE a=?" matches 10 rows, and |
| 81631 | ** * "WHERE a=? AND b=?" matches 2 rows. |
| 81632 | ** |
| 81633 | ** If D is the count of distinct values and K is the total number of |
| 81634 | ** rows, then each estimate is computed as: |
| 81635 | ** |
| 81636 | ** I = (K+D-1)/D |
| 81637 | */ |
| 81638 | char *z; |
| 81639 | int i; |
| 81640 | |
| 81641 | char *zRet = sqlite3MallocZero(p->nCol * 25); |
| 81642 | if( zRet==0 ){ |
| 81643 | sqlite3_result_error_nomem(context); |
| 81644 | return; |
| 81645 | } |
| 81646 | |
| 81647 | sqlite3_snprintf(24, zRet, "%lld", p->nRow); |
| 81648 | z = zRet + sqlite3Strlen30(zRet); |
| 81649 | for(i=0; i<(p->nCol-1); i++){ |
| 81650 | i64 nDistinct = p->current.anDLt[i] + 1; |
| 81651 | i64 iVal = (p->nRow + nDistinct - 1) / nDistinct; |
| 81652 | sqlite3_snprintf(24, z, " %lld", iVal); |
| 81653 | z += sqlite3Strlen30(z); |
| 81654 | assert( p->current.anEq[i] ); |
| 81655 | } |
| 81656 | assert( z[0]=='\0' && z>zRet ); |
| 81657 | |
| 81658 | sqlite3_result_text(context, zRet, -1, sqlite3_free); |
| 81659 | } |
| 81660 | #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 81661 | else if( eCall==STAT_GET_ROWID ){ |
| 81662 | if( p->iGet<0 ){ |
| 81663 | samplePushPrevious(p, 0); |
| 81664 | p->iGet = 0; |
| 81665 | } |
| 81666 | if( p->iGet<p->nSample ){ |
| 81667 | sqlite3_result_int64(context, p->a[p->iGet].iRowid); |
| 81668 | } |
| 81669 | }else{ |
| 81670 | tRowcnt *aCnt = 0; |
| 81671 | |
| 81672 | assert( p->iGet<p->nSample ); |
| 81673 | switch( eCall ){ |
| 81674 | case STAT_GET_NEQ: aCnt = p->a[p->iGet].anEq; break; |
| 81675 | case STAT_GET_NLT: aCnt = p->a[p->iGet].anLt; break; |
| 81676 | default: { |
| 81677 | aCnt = p->a[p->iGet].anDLt; |
| 81678 | p->iGet++; |
| 81679 | break; |
| 81680 | } |
| 81681 | } |
| 81682 | |
| 81683 | if( IsStat3 ){ |
| 81684 | sqlite3_result_int64(context, (i64)aCnt[0]); |
| 81685 | }else{ |
| 81686 | char *zRet = sqlite3MallocZero(p->nCol * 25); |
| 81687 | if( zRet==0 ){ |
| 81688 | sqlite3_result_error_nomem(context); |
| 81689 | }else{ |
| 81690 | int i; |
| 81691 | char *z = zRet; |
| 81692 | for(i=0; i<p->nCol; i++){ |
| 81693 | sqlite3_snprintf(24, z, "%lld ", aCnt[i]); |
| 81694 | z += sqlite3Strlen30(z); |
| 81695 | } |
| 81696 | assert( z[0]=='\0' && z>zRet ); |
| 81697 | z[-1] = '\0'; |
| 81698 | sqlite3_result_text(context, zRet, -1, sqlite3_free); |
| 81699 | } |
| 81700 | } |
| 81701 | } |
| 81702 | #endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */ |
| 81703 | } |
| 81704 | static const FuncDef statGetFuncdef = { |
| 81705 | 1+IsStat34, /* nArg */ |
| 81706 | SQLITE_UTF8, /* iPrefEnc */ |
| 81707 | 0, /* flags */ |
| 81708 | 0, /* pUserData */ |
| 81709 | 0, /* pNext */ |
| 81710 | statGet, /* xFunc */ |
| 81711 | 0, /* xStep */ |
| 81712 | 0, /* xFinalize */ |
| 81713 | "stat_get", /* zName */ |
| 81714 | 0, /* pHash */ |
| 81715 | 0 /* pDestructor */ |
| 81716 | }; |
| 81717 | |
| 81718 | static void callStatGet(Vdbe *v, int regStat4, int iParam, int regOut){ |
| 81719 | assert( regOut!=regStat4 && regOut!=regStat4+1 ); |
| 81720 | #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 81721 | sqlite3VdbeAddOp2(v, OP_Integer, iParam, regStat4+1); |
| 81722 | #else |
| 81723 | assert( iParam==STAT_GET_STAT1 ); |
| 81724 | #endif |
| 81725 | sqlite3VdbeAddOp3(v, OP_Function, 0, regStat4, regOut); |
| 81726 | sqlite3VdbeChangeP4(v, -1, (char*)&statGetFuncdef, P4_FUNCDEF); |
| 81727 | sqlite3VdbeChangeP5(v, 1 + IsStat34); |
| 81728 | } |
| 81729 | |
| 81730 | /* |
| 81731 | ** Generate code to do an analysis of all indices associated with |
| 81732 | ** a single table. |
| 81733 | */ |
| @@ -80960,46 +81734,35 @@ | |
| 81734 | static void analyzeOneTable( |
| 81735 | Parse *pParse, /* Parser context */ |
| 81736 | Table *pTab, /* Table whose indices are to be analyzed */ |
| 81737 | Index *pOnlyIdx, /* If not NULL, only analyze this one index */ |
| 81738 | int iStatCur, /* Index of VdbeCursor that writes the sqlite_stat1 table */ |
| 81739 | int iMem, /* Available memory locations begin here */ |
| 81740 | int iTab /* Next available cursor */ |
| 81741 | ){ |
| 81742 | sqlite3 *db = pParse->db; /* Database handle */ |
| 81743 | Index *pIdx; /* An index to being analyzed */ |
| 81744 | int iIdxCur; /* Cursor open on index being analyzed */ |
| 81745 | int iTabCur; /* Table cursor */ |
| 81746 | Vdbe *v; /* The virtual machine being built up */ |
| 81747 | int i; /* Loop counter */ |
| 81748 | int jZeroRows = -1; /* Jump from here if number of rows is zero */ |
| 81749 | int iDb; /* Index of database containing pTab */ |
| 81750 | u8 needTableCnt = 1; /* True to count the table */ |
| 81751 | int regNewRowid = iMem++; /* Rowid for the inserted record */ |
| 81752 | int regStat4 = iMem++; /* Register to hold Stat4Accum object */ |
| 81753 | int regChng = iMem++; /* Index of changed index field */ |
| 81754 | #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 81755 | int regRowid = iMem++; /* Rowid argument passed to stat_push() */ |
| 81756 | #endif |
| 81757 | int regTemp = iMem++; /* Temporary use register */ |
| 81758 | int regTabname = iMem++; /* Register containing table name */ |
| 81759 | int regIdxname = iMem++; /* Register containing index name */ |
| 81760 | int regStat1 = iMem++; /* Value for the stat column of sqlite_stat1 */ |
| 81761 | int regPrev = iMem; /* MUST BE LAST (see below) */ |
| 81762 | |
| 81763 | pParse->nMem = MAX(pParse->nMem, iMem); |
| 81764 | v = sqlite3GetVdbe(pParse); |
| 81765 | if( v==0 || NEVER(pTab==0) ){ |
| 81766 | return; |
| 81767 | } |
| 81768 | if( pTab->tnum==0 ){ |
| @@ -81019,217 +81782,230 @@ | |
| 81782 | db->aDb[iDb].zName ) ){ |
| 81783 | return; |
| 81784 | } |
| 81785 | #endif |
| 81786 | |
| 81787 | /* Establish a read-lock on the table at the shared-cache level. |
| 81788 | ** Open a read-only cursor on the table. Also allocate a cursor number |
| 81789 | ** to use for scanning indexes (iIdxCur). No index cursor is opened at |
| 81790 | ** this time though. */ |
| 81791 | sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName); |
| 81792 | iTabCur = iTab++; |
| 81793 | iIdxCur = iTab++; |
| 81794 | pParse->nTab = MAX(pParse->nTab, iTab); |
| 81795 | sqlite3OpenTable(pParse, iTabCur, iDb, pTab, OP_OpenRead); |
| 81796 | sqlite3VdbeAddOp4(v, OP_String8, 0, regTabname, 0, pTab->zName, 0); |
| 81797 | |
| 81798 | for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ |
| 81799 | int nCol; /* Number of columns indexed by pIdx */ |
| 81800 | KeyInfo *pKey; /* KeyInfo structure for pIdx */ |
| 81801 | int *aGotoChng; /* Array of jump instruction addresses */ |
| 81802 | int addrRewind; /* Address of "OP_Rewind iIdxCur" */ |
| 81803 | int addrGotoChng0; /* Address of "Goto addr_chng_0" */ |
| 81804 | int addrNextRow; /* Address of "next_row:" */ |
| 81805 | |
| 81806 | if( pOnlyIdx && pOnlyIdx!=pIdx ) continue; |
| 81807 | if( pIdx->pPartIdxWhere==0 ) needTableCnt = 0; |
| 81808 | VdbeNoopComment((v, "Begin analysis of %s", pIdx->zName)); |
| 81809 | nCol = pIdx->nColumn; |
| 81810 | aGotoChng = sqlite3DbMallocRaw(db, sizeof(int)*(nCol+1)); |
| 81811 | if( aGotoChng==0 ) continue; |
| 81812 | pKey = sqlite3IndexKeyinfo(pParse, pIdx); |
| 81813 | |
| 81814 | /* Populate the register containing the index name. */ |
| 81815 | sqlite3VdbeAddOp4(v, OP_String8, 0, regIdxname, 0, pIdx->zName, 0); |
| 81816 | |
| 81817 | /* |
| 81818 | ** Pseudo-code for loop that calls stat_push(): |
| 81819 | ** |
| 81820 | ** Rewind csr |
| 81821 | ** if eof(csr) goto end_of_scan; |
| 81822 | ** regChng = 0 |
| 81823 | ** goto chng_addr_0; |
| 81824 | ** |
| 81825 | ** next_row: |
| 81826 | ** regChng = 0 |
| 81827 | ** if( idx(0) != regPrev(0) ) goto chng_addr_0 |
| 81828 | ** regChng = 1 |
| 81829 | ** if( idx(1) != regPrev(1) ) goto chng_addr_1 |
| 81830 | ** ... |
| 81831 | ** regChng = N |
| 81832 | ** goto chng_addr_N |
| 81833 | ** |
| 81834 | ** chng_addr_0: |
| 81835 | ** regPrev(0) = idx(0) |
| 81836 | ** chng_addr_1: |
| 81837 | ** regPrev(1) = idx(1) |
| 81838 | ** ... |
| 81839 | ** |
| 81840 | ** chng_addr_N: |
| 81841 | ** regRowid = idx(rowid) |
| 81842 | ** stat_push(P, regChng, regRowid) |
| 81843 | ** Next csr |
| 81844 | ** if !eof(csr) goto next_row; |
| 81845 | ** |
| 81846 | ** end_of_scan: |
| 81847 | */ |
| 81848 | |
| 81849 | /* Make sure there are enough memory cells allocated to accommodate |
| 81850 | ** the regPrev array and a trailing rowid (the rowid slot is required |
| 81851 | ** when building a record to insert into the sample column of |
| 81852 | ** the sqlite_stat4 table. */ |
| 81853 | pParse->nMem = MAX(pParse->nMem, regPrev+nCol); |
| 81854 | |
| 81855 | /* Open a read-only cursor on the index being analyzed. */ |
| 81856 | assert( iDb==sqlite3SchemaToIndex(db, pIdx->pSchema) ); |
| 81857 | sqlite3VdbeAddOp3(v, OP_OpenRead, iIdxCur, pIdx->tnum, iDb); |
| 81858 | sqlite3VdbeChangeP4(v, -1, (char*)pKey, P4_KEYINFO_HANDOFF); |
| 81859 | VdbeComment((v, "%s", pIdx->zName)); |
| 81860 | |
| 81861 | /* Invoke the stat_init() function. The arguments are: |
| 81862 | ** |
| 81863 | ** (1) the number of columns in the index including the rowid, |
| 81864 | ** (2) the number of rows in the index, |
| 81865 | ** |
| 81866 | ** The second argument is only used for STAT3 and STAT4 |
| 81867 | */ |
| 81868 | #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 81869 | sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regStat4+2); |
| 81870 | #endif |
| 81871 | sqlite3VdbeAddOp2(v, OP_Integer, nCol+1, regStat4+1); |
| 81872 | sqlite3VdbeAddOp3(v, OP_Function, 0, regStat4+1, regStat4); |
| 81873 | sqlite3VdbeChangeP4(v, -1, (char*)&statInitFuncdef, P4_FUNCDEF); |
| 81874 | sqlite3VdbeChangeP5(v, 1+IsStat34); |
| 81875 | |
| 81876 | /* Implementation of the following: |
| 81877 | ** |
| 81878 | ** Rewind csr |
| 81879 | ** if eof(csr) goto end_of_scan; |
| 81880 | ** regChng = 0 |
| 81881 | ** goto next_push_0; |
| 81882 | ** |
| 81883 | */ |
| 81884 | addrRewind = sqlite3VdbeAddOp1(v, OP_Rewind, iIdxCur); |
| 81885 | sqlite3VdbeAddOp2(v, OP_Integer, 0, regChng); |
| 81886 | addrGotoChng0 = sqlite3VdbeAddOp0(v, OP_Goto); |
| 81887 | |
| 81888 | /* |
| 81889 | ** next_row: |
| 81890 | ** regChng = 0 |
| 81891 | ** if( idx(0) != regPrev(0) ) goto chng_addr_0 |
| 81892 | ** regChng = 1 |
| 81893 | ** if( idx(1) != regPrev(1) ) goto chng_addr_1 |
| 81894 | ** ... |
| 81895 | ** regChng = N |
| 81896 | ** goto chng_addr_N |
| 81897 | */ |
| 81898 | addrNextRow = sqlite3VdbeCurrentAddr(v); |
| 81899 | for(i=0; i<nCol; i++){ |
| 81900 | char *pColl = (char*)sqlite3LocateCollSeq(pParse, pIdx->azColl[i]); |
| 81901 | sqlite3VdbeAddOp2(v, OP_Integer, i, regChng); |
| 81902 | sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, regTemp); |
| 81903 | aGotoChng[i] = |
| 81904 | sqlite3VdbeAddOp4(v, OP_Ne, regTemp, 0, regPrev+i, pColl, P4_COLLSEQ); |
| 81905 | sqlite3VdbeChangeP5(v, SQLITE_NULLEQ); |
| 81906 | } |
| 81907 | sqlite3VdbeAddOp2(v, OP_Integer, nCol, regChng); |
| 81908 | aGotoChng[nCol] = sqlite3VdbeAddOp0(v, OP_Goto); |
| 81909 | |
| 81910 | /* |
| 81911 | ** chng_addr_0: |
| 81912 | ** regPrev(0) = idx(0) |
| 81913 | ** chng_addr_1: |
| 81914 | ** regPrev(1) = idx(1) |
| 81915 | ** ... |
| 81916 | */ |
| 81917 | sqlite3VdbeJumpHere(v, addrGotoChng0); |
| 81918 | for(i=0; i<nCol; i++){ |
| 81919 | sqlite3VdbeJumpHere(v, aGotoChng[i]); |
| 81920 | sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, i, regPrev+i); |
| 81921 | } |
| 81922 | |
| 81923 | /* |
| 81924 | ** chng_addr_N: |
| 81925 | ** regRowid = idx(rowid) // STAT34 only |
| 81926 | ** stat_push(P, regChng, regRowid) // 3rd parameter STAT34 only |
| 81927 | ** Next csr |
| 81928 | ** if !eof(csr) goto next_row; |
| 81929 | */ |
| 81930 | sqlite3VdbeJumpHere(v, aGotoChng[nCol]); |
| 81931 | #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 81932 | sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur, regRowid); |
| 81933 | assert( regRowid==(regStat4+2) ); |
| 81934 | #endif |
| 81935 | assert( regChng==(regStat4+1) ); |
| 81936 | sqlite3VdbeAddOp3(v, OP_Function, 1, regStat4, regTemp); |
| 81937 | sqlite3VdbeChangeP4(v, -1, (char*)&statPushFuncdef, P4_FUNCDEF); |
| 81938 | sqlite3VdbeChangeP5(v, 2+IsStat34); |
| 81939 | sqlite3VdbeAddOp2(v, OP_Next, iIdxCur, addrNextRow); |
| 81940 | |
| 81941 | /* Add the entry to the stat1 table. */ |
| 81942 | callStatGet(v, regStat4, STAT_GET_STAT1, regStat1); |
| 81943 | sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regTemp, "aaa", 0); |
| 81944 | sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid); |
| 81945 | sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regTemp, regNewRowid); |
| 81946 | sqlite3VdbeChangeP5(v, OPFLAG_APPEND); |
| 81947 | |
| 81948 | /* Add the entries to the stat3 or stat4 table. */ |
| 81949 | #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 81950 | { |
| 81951 | int regEq = regStat1; |
| 81952 | int regLt = regStat1+1; |
| 81953 | int regDLt = regStat1+2; |
| 81954 | int regSample = regStat1+3; |
| 81955 | int regCol = regStat1+4; |
| 81956 | int regSampleRowid = regCol + nCol; |
| 81957 | int addrNext; |
| 81958 | int addrIsNull; |
| 81959 | |
| 81960 | pParse->nMem = MAX(pParse->nMem, regCol+nCol+1); |
| 81961 | |
| 81962 | addrNext = sqlite3VdbeCurrentAddr(v); |
| 81963 | callStatGet(v, regStat4, STAT_GET_ROWID, regSampleRowid); |
| 81964 | addrIsNull = sqlite3VdbeAddOp1(v, OP_IsNull, regSampleRowid); |
| 81965 | callStatGet(v, regStat4, STAT_GET_NEQ, regEq); |
| 81966 | callStatGet(v, regStat4, STAT_GET_NLT, regLt); |
| 81967 | callStatGet(v, regStat4, STAT_GET_NDLT, regDLt); |
| 81968 | sqlite3VdbeAddOp3(v, OP_NotExists, iTabCur, addrNext, regSampleRowid); |
| 81969 | #ifdef SQLITE_ENABLE_STAT3 |
| 81970 | sqlite3ExprCodeGetColumnOfTable(v, pTab, iTabCur, |
| 81971 | pIdx->aiColumn[0], regSample); |
| 81972 | #else |
| 81973 | for(i=0; i<nCol; i++){ |
| 81974 | int iCol = pIdx->aiColumn[i]; |
| 81975 | sqlite3ExprCodeGetColumnOfTable(v, pTab, iTabCur, iCol, regCol+i); |
| 81976 | } |
| 81977 | sqlite3VdbeAddOp3(v, OP_MakeRecord, regCol, nCol+1, regSample); |
| 81978 | #endif |
| 81979 | sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 6, regTemp, "bbbbbb", 0); |
| 81980 | sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur+1, regNewRowid); |
| 81981 | sqlite3VdbeAddOp3(v, OP_Insert, iStatCur+1, regTemp, regNewRowid); |
| 81982 | sqlite3VdbeAddOp2(v, OP_Goto, 0, addrNext); |
| 81983 | sqlite3VdbeJumpHere(v, addrIsNull); |
| 81984 | } |
| 81985 | #endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */ |
| 81986 | |
| 81987 | /* End of analysis */ |
| 81988 | sqlite3VdbeJumpHere(v, addrRewind); |
| 81989 | sqlite3DbFree(db, aGotoChng); |
| 81990 | } |
| 81991 | |
| 81992 | |
| 81993 | /* Create a single sqlite_stat1 entry containing NULL as the index |
| 81994 | ** name and the row count as the content. |
| 81995 | */ |
| 81996 | if( pOnlyIdx==0 && needTableCnt ){ |
| 81997 | VdbeComment((v, "%s", pTab->zName)); |
| 81998 | sqlite3VdbeAddOp2(v, OP_Count, iTabCur, regStat1); |
| 81999 | jZeroRows = sqlite3VdbeAddOp1(v, OP_IfNot, regStat1); |
| 82000 | sqlite3VdbeAddOp2(v, OP_Null, 0, regIdxname); |
| 82001 | sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regTemp, "aaa", 0); |
| 82002 | sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid); |
| 82003 | sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regTemp, regNewRowid); |
| 82004 | sqlite3VdbeChangeP5(v, OPFLAG_APPEND); |
| 82005 | sqlite3VdbeJumpHere(v, jZeroRows); |
| 82006 | } |
| 82007 | } |
| 82008 | |
| 82009 | |
| 82010 | /* |
| 82011 | ** Generate code that will cause the most recent index analysis to |
| @@ -81249,20 +82025,22 @@ | |
| 82025 | sqlite3 *db = pParse->db; |
| 82026 | Schema *pSchema = db->aDb[iDb].pSchema; /* Schema of database iDb */ |
| 82027 | HashElem *k; |
| 82028 | int iStatCur; |
| 82029 | int iMem; |
| 82030 | int iTab; |
| 82031 | |
| 82032 | sqlite3BeginWriteOperation(pParse, 0, iDb); |
| 82033 | iStatCur = pParse->nTab; |
| 82034 | pParse->nTab += 3; |
| 82035 | openStatTable(pParse, iDb, iStatCur, 0, 0); |
| 82036 | iMem = pParse->nMem+1; |
| 82037 | iTab = pParse->nTab; |
| 82038 | assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); |
| 82039 | for(k=sqliteHashFirst(&pSchema->tblHash); k; k=sqliteHashNext(k)){ |
| 82040 | Table *pTab = (Table*)sqliteHashData(k); |
| 82041 | analyzeOneTable(pParse, pTab, 0, iStatCur, iMem, iTab); |
| 82042 | } |
| 82043 | loadAnalysis(pParse, iDb); |
| 82044 | } |
| 82045 | |
| 82046 | /* |
| @@ -81283,11 +82061,11 @@ | |
| 82061 | if( pOnlyIdx ){ |
| 82062 | openStatTable(pParse, iDb, iStatCur, pOnlyIdx->zName, "idx"); |
| 82063 | }else{ |
| 82064 | openStatTable(pParse, iDb, iStatCur, pTab->zName, "tbl"); |
| 82065 | } |
| 82066 | analyzeOneTable(pParse, pTab, pOnlyIdx, iStatCur,pParse->nMem+1,pParse->nTab); |
| 82067 | loadAnalysis(pParse, iDb); |
| 82068 | } |
| 82069 | |
| 82070 | /* |
| 82071 | ** Generate code for the ANALYZE command. The parser calls this routine |
| @@ -81365,10 +82143,47 @@ | |
| 82143 | typedef struct analysisInfo analysisInfo; |
| 82144 | struct analysisInfo { |
| 82145 | sqlite3 *db; |
| 82146 | const char *zDatabase; |
| 82147 | }; |
| 82148 | |
| 82149 | /* |
| 82150 | ** The first argument points to a nul-terminated string containing a |
| 82151 | ** list of space separated integers. Read the first nOut of these into |
| 82152 | ** the array aOut[]. |
| 82153 | */ |
| 82154 | static void decodeIntArray( |
| 82155 | char *zIntArray, |
| 82156 | int nOut, |
| 82157 | tRowcnt *aOut, |
| 82158 | int *pbUnordered |
| 82159 | ){ |
| 82160 | char *z = zIntArray; |
| 82161 | int c; |
| 82162 | int i; |
| 82163 | tRowcnt v; |
| 82164 | |
| 82165 | assert( pbUnordered==0 || *pbUnordered==0 ); |
| 82166 | |
| 82167 | #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 82168 | if( z==0 ) z = ""; |
| 82169 | #else |
| 82170 | if( NEVER(z==0) ) z = ""; |
| 82171 | #endif |
| 82172 | for(i=0; *z && i<nOut; i++){ |
| 82173 | v = 0; |
| 82174 | while( (c=z[0])>='0' && c<='9' ){ |
| 82175 | v = v*10 + c - '0'; |
| 82176 | z++; |
| 82177 | } |
| 82178 | aOut[i] = v; |
| 82179 | if( *z==' ' ) z++; |
| 82180 | } |
| 82181 | if( pbUnordered && strcmp(z, "unordered")==0 ){ |
| 82182 | *pbUnordered = 1; |
| 82183 | } |
| 82184 | } |
| 82185 | |
| 82186 | /* |
| 82187 | ** This callback is invoked once for each index when reading the |
| 82188 | ** sqlite_stat1 table. |
| 82189 | ** |
| @@ -81381,12 +82196,10 @@ | |
| 82196 | */ |
| 82197 | static int analysisLoader(void *pData, int argc, char **argv, char **NotUsed){ |
| 82198 | analysisInfo *pInfo = (analysisInfo*)pData; |
| 82199 | Index *pIndex; |
| 82200 | Table *pTable; |
| 82201 | const char *z; |
| 82202 | |
| 82203 | assert( argc==3 ); |
| 82204 | UNUSED_PARAMETER2(NotUsed, argc); |
| 82205 | |
| @@ -81400,45 +82213,35 @@ | |
| 82213 | if( argv[1] ){ |
| 82214 | pIndex = sqlite3FindIndex(pInfo->db, argv[1], pInfo->zDatabase); |
| 82215 | }else{ |
| 82216 | pIndex = 0; |
| 82217 | } |
| 82218 | z = argv[2]; |
| 82219 | |
| 82220 | if( pIndex ){ |
| 82221 | int bUnordered = 0; |
| 82222 | decodeIntArray((char*)z, pIndex->nColumn+1, pIndex->aiRowEst,&bUnordered); |
| 82223 | if( pIndex->pPartIdxWhere==0 ) pTable->nRowEst = pIndex->aiRowEst[0]; |
| 82224 | pIndex->bUnordered = bUnordered; |
| 82225 | }else{ |
| 82226 | decodeIntArray((char*)z, 1, &pTable->nRowEst, 0); |
| 82227 | } |
| 82228 | |
| 82229 | return 0; |
| 82230 | } |
| 82231 | |
| 82232 | /* |
| 82233 | ** If the Index.aSample variable is not NULL, delete the aSample[] array |
| 82234 | ** and its contents. |
| 82235 | */ |
| 82236 | SQLITE_PRIVATE void sqlite3DeleteIndexSamples(sqlite3 *db, Index *pIdx){ |
| 82237 | #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 82238 | if( pIdx->aSample ){ |
| 82239 | int j; |
| 82240 | for(j=0; j<pIdx->nSample; j++){ |
| 82241 | IndexSample *p = &pIdx->aSample[j]; |
| 82242 | sqlite3DbFree(db, p->p); |
| 82243 | } |
| 82244 | sqlite3DbFree(db, pIdx->aSample); |
| 82245 | } |
| 82246 | if( db && db->pnBytesFreed==0 ){ |
| 82247 | pIdx->nSample = 0; |
| @@ -81445,155 +82248,222 @@ | |
| 82248 | pIdx->aSample = 0; |
| 82249 | } |
| 82250 | #else |
| 82251 | UNUSED_PARAMETER(db); |
| 82252 | UNUSED_PARAMETER(pIdx); |
| 82253 | #endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */ |
| 82254 | } |
| 82255 | |
| 82256 | #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 82257 | /* |
| 82258 | ** Populate the pIdx->aAvgEq[] array based on the samples currently |
| 82259 | ** stored in pIdx->aSample[]. |
| 82260 | */ |
| 82261 | static void initAvgEq(Index *pIdx){ |
| 82262 | if( pIdx ){ |
| 82263 | IndexSample *aSample = pIdx->aSample; |
| 82264 | IndexSample *pFinal = &aSample[pIdx->nSample-1]; |
| 82265 | int iCol; |
| 82266 | for(iCol=0; iCol<pIdx->nColumn; iCol++){ |
| 82267 | int i; /* Used to iterate through samples */ |
| 82268 | tRowcnt sumEq = 0; /* Sum of the nEq values */ |
| 82269 | int nSum = 0; /* Number of terms contributing to sumEq */ |
| 82270 | tRowcnt avgEq = 0; |
| 82271 | tRowcnt nDLt = pFinal->anDLt[iCol]; |
| 82272 | |
| 82273 | /* Set nSum to the number of distinct (iCol+1) field prefixes that |
| 82274 | ** occur in the stat4 table for this index before pFinal. Set |
| 82275 | ** sumEq to the sum of the nEq values for column iCol for the same |
| 82276 | ** set (adding the value only once where there exist dupicate |
| 82277 | ** prefixes). */ |
| 82278 | for(i=0; i<(pIdx->nSample-1); i++){ |
| 82279 | if( aSample[i].anDLt[iCol]!=aSample[i+1].anDLt[iCol] ){ |
| 82280 | sumEq += aSample[i].anEq[iCol]; |
| 82281 | nSum++; |
| 82282 | } |
| 82283 | } |
| 82284 | if( nDLt>nSum ){ |
| 82285 | avgEq = (pFinal->anLt[iCol] - sumEq)/(nDLt - nSum); |
| 82286 | } |
| 82287 | if( avgEq==0 ) avgEq = 1; |
| 82288 | pIdx->aAvgEq[iCol] = avgEq; |
| 82289 | if( pIdx->nSampleCol==1 ) break; |
| 82290 | } |
| 82291 | } |
| 82292 | } |
| 82293 | |
| 82294 | /* |
| 82295 | ** Load the content from either the sqlite_stat4 or sqlite_stat3 table |
| 82296 | ** into the relevant Index.aSample[] arrays. |
| 82297 | ** |
| 82298 | ** Arguments zSql1 and zSql2 must point to SQL statements that return |
| 82299 | ** data equivalent to the following (statements are different for stat3, |
| 82300 | ** see the caller of this function for details): |
| 82301 | ** |
| 82302 | ** zSql1: SELECT idx,count(*) FROM %Q.sqlite_stat4 GROUP BY idx |
| 82303 | ** zSql2: SELECT idx,neq,nlt,ndlt,sample FROM %Q.sqlite_stat4 |
| 82304 | ** |
| 82305 | ** where %Q is replaced with the database name before the SQL is executed. |
| 82306 | */ |
| 82307 | static int loadStatTbl( |
| 82308 | sqlite3 *db, /* Database handle */ |
| 82309 | int bStat3, /* Assume single column records only */ |
| 82310 | const char *zSql1, /* SQL statement 1 (see above) */ |
| 82311 | const char *zSql2, /* SQL statement 2 (see above) */ |
| 82312 | const char *zDb /* Database name (e.g. "main") */ |
| 82313 | ){ |
| 82314 | int rc; /* Result codes from subroutines */ |
| 82315 | sqlite3_stmt *pStmt = 0; /* An SQL statement being run */ |
| 82316 | char *zSql; /* Text of the SQL statement */ |
| 82317 | Index *pPrevIdx = 0; /* Previous index in the loop */ |
| 82318 | IndexSample *pSample; /* A slot in pIdx->aSample[] */ |
| 82319 | |
| 82320 | assert( db->lookaside.bEnabled==0 ); |
| 82321 | zSql = sqlite3MPrintf(db, zSql1, zDb); |
| 82322 | if( !zSql ){ |
| 82323 | return SQLITE_NOMEM; |
| 82324 | } |
| 82325 | rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0); |
| 82326 | sqlite3DbFree(db, zSql); |
| 82327 | if( rc ) return rc; |
| 82328 | |
| 82329 | while( sqlite3_step(pStmt)==SQLITE_ROW ){ |
| 82330 | int nIdxCol = 1; /* Number of columns in stat4 records */ |
| 82331 | int nAvgCol = 1; /* Number of entries in Index.aAvgEq */ |
| 82332 | |
| 82333 | char *zIndex; /* Index name */ |
| 82334 | Index *pIdx; /* Pointer to the index object */ |
| 82335 | int nSample; /* Number of samples */ |
| 82336 | int nByte; /* Bytes of space required */ |
| 82337 | int i; /* Bytes of space required */ |
| 82338 | tRowcnt *pSpace; |
| 82339 | |
| 82340 | zIndex = (char *)sqlite3_column_text(pStmt, 0); |
| 82341 | if( zIndex==0 ) continue; |
| 82342 | nSample = sqlite3_column_int(pStmt, 1); |
| 82343 | pIdx = sqlite3FindIndex(db, zIndex, zDb); |
| 82344 | assert( pIdx==0 || bStat3 || pIdx->nSample==0 ); |
| 82345 | /* Index.nSample is non-zero at this point if data has already been |
| 82346 | ** loaded from the stat4 table. In this case ignore stat3 data. */ |
| 82347 | if( pIdx==0 || pIdx->nSample ) continue; |
| 82348 | if( bStat3==0 ){ |
| 82349 | nIdxCol = pIdx->nColumn+1; |
| 82350 | nAvgCol = pIdx->nColumn; |
| 82351 | } |
| 82352 | pIdx->nSampleCol = nIdxCol; |
| 82353 | nByte = sizeof(IndexSample) * nSample; |
| 82354 | nByte += sizeof(tRowcnt) * nIdxCol * 3 * nSample; |
| 82355 | nByte += nAvgCol * sizeof(tRowcnt); /* Space for Index.aAvgEq[] */ |
| 82356 | |
| 82357 | pIdx->aSample = sqlite3DbMallocZero(db, nByte); |
| 82358 | if( pIdx->aSample==0 ){ |
| 82359 | sqlite3_finalize(pStmt); |
| 82360 | return SQLITE_NOMEM; |
| 82361 | } |
| 82362 | pSpace = (tRowcnt*)&pIdx->aSample[nSample]; |
| 82363 | pIdx->aAvgEq = pSpace; pSpace += nAvgCol; |
| 82364 | for(i=0; i<nSample; i++){ |
| 82365 | pIdx->aSample[i].anEq = pSpace; pSpace += nIdxCol; |
| 82366 | pIdx->aSample[i].anLt = pSpace; pSpace += nIdxCol; |
| 82367 | pIdx->aSample[i].anDLt = pSpace; pSpace += nIdxCol; |
| 82368 | } |
| 82369 | assert( ((u8*)pSpace)-nByte==(u8*)(pIdx->aSample) ); |
| 82370 | } |
| 82371 | rc = sqlite3_finalize(pStmt); |
| 82372 | if( rc ) return rc; |
| 82373 | |
| 82374 | zSql = sqlite3MPrintf(db, zSql2, zDb); |
| 82375 | if( !zSql ){ |
| 82376 | return SQLITE_NOMEM; |
| 82377 | } |
| 82378 | rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0); |
| 82379 | sqlite3DbFree(db, zSql); |
| 82380 | if( rc ) return rc; |
| 82381 | |
| 82382 | while( sqlite3_step(pStmt)==SQLITE_ROW ){ |
| 82383 | char *zIndex; /* Index name */ |
| 82384 | Index *pIdx; /* Pointer to the index object */ |
| 82385 | int nCol = 1; /* Number of columns in index */ |
| 82386 | |
| 82387 | zIndex = (char *)sqlite3_column_text(pStmt, 0); |
| 82388 | if( zIndex==0 ) continue; |
| 82389 | pIdx = sqlite3FindIndex(db, zIndex, zDb); |
| 82390 | if( pIdx==0 ) continue; |
| 82391 | /* This next condition is true if data has already been loaded from |
| 82392 | ** the sqlite_stat4 table. In this case ignore stat3 data. */ |
| 82393 | nCol = pIdx->nSampleCol; |
| 82394 | if( bStat3 && nCol>1 ) continue; |
| 82395 | if( pIdx!=pPrevIdx ){ |
| 82396 | initAvgEq(pPrevIdx); |
| 82397 | pPrevIdx = pIdx; |
| 82398 | } |
| 82399 | pSample = &pIdx->aSample[pIdx->nSample]; |
| 82400 | decodeIntArray((char*)sqlite3_column_text(pStmt,1), nCol, pSample->anEq, 0); |
| 82401 | decodeIntArray((char*)sqlite3_column_text(pStmt,2), nCol, pSample->anLt, 0); |
| 82402 | decodeIntArray((char*)sqlite3_column_text(pStmt,3), nCol, pSample->anDLt,0); |
| 82403 | |
| 82404 | /* Take a copy of the sample. Add two 0x00 bytes the end of the buffer. |
| 82405 | ** This is in case the sample record is corrupted. In that case, the |
| 82406 | ** sqlite3VdbeRecordCompare() may read up to two varints past the |
| 82407 | ** end of the allocated buffer before it realizes it is dealing with |
| 82408 | ** a corrupt record. Adding the two 0x00 bytes prevents this from causing |
| 82409 | ** a buffer overread. */ |
| 82410 | pSample->n = sqlite3_column_bytes(pStmt, 4); |
| 82411 | pSample->p = sqlite3DbMallocZero(db, pSample->n + 2); |
| 82412 | if( pSample->p==0 ){ |
| 82413 | sqlite3_finalize(pStmt); |
| 82414 | return SQLITE_NOMEM; |
| 82415 | } |
| 82416 | memcpy(pSample->p, sqlite3_column_blob(pStmt, 4), pSample->n); |
| 82417 | pIdx->nSample++; |
| 82418 | } |
| 82419 | rc = sqlite3_finalize(pStmt); |
| 82420 | if( rc==SQLITE_OK ) initAvgEq(pPrevIdx); |
| 82421 | return rc; |
| 82422 | } |
| 82423 | |
| 82424 | /* |
| 82425 | ** Load content from the sqlite_stat4 and sqlite_stat3 tables into |
| 82426 | ** the Index.aSample[] arrays of all indices. |
| 82427 | */ |
| 82428 | static int loadStat4(sqlite3 *db, const char *zDb){ |
| 82429 | int rc = SQLITE_OK; /* Result codes from subroutines */ |
| 82430 | |
| 82431 | assert( db->lookaside.bEnabled==0 ); |
| 82432 | if( sqlite3FindTable(db, "sqlite_stat4", zDb) ){ |
| 82433 | rc = loadStatTbl(db, 0, |
| 82434 | "SELECT idx,count(*) FROM %Q.sqlite_stat4 GROUP BY idx", |
| 82435 | "SELECT idx,neq,nlt,ndlt,sample FROM %Q.sqlite_stat4", |
| 82436 | zDb |
| 82437 | ); |
| 82438 | } |
| 82439 | |
| 82440 | if( rc==SQLITE_OK && sqlite3FindTable(db, "sqlite_stat3", zDb) ){ |
| 82441 | rc = loadStatTbl(db, 1, |
| 82442 | "SELECT idx,count(*) FROM %Q.sqlite_stat3 GROUP BY idx", |
| 82443 | "SELECT idx,neq,nlt,ndlt,sqlite_record(sample) FROM %Q.sqlite_stat3", |
| 82444 | zDb |
| 82445 | ); |
| 82446 | } |
| 82447 | |
| 82448 | return rc; |
| 82449 | } |
| 82450 | #endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */ |
| 82451 | |
| 82452 | /* |
| 82453 | ** Load the content of the sqlite_stat1 and sqlite_stat3/4 tables. The |
| 82454 | ** contents of sqlite_stat1 are used to populate the Index.aiRowEst[] |
| 82455 | ** arrays. The contents of sqlite_stat3/4 are used to populate the |
| 82456 | ** Index.aSample[] arrays. |
| 82457 | ** |
| 82458 | ** If the sqlite_stat1 table is not present in the database, SQLITE_ERROR |
| 82459 | ** is returned. In this case, even if SQLITE_ENABLE_STAT3/4 was defined |
| 82460 | ** during compilation and the sqlite_stat3/4 table is present, no data is |
| 82461 | ** read from it. |
| 82462 | ** |
| 82463 | ** If SQLITE_ENABLE_STAT3/4 was defined during compilation and the |
| 82464 | ** sqlite_stat4 table is not present in the database, SQLITE_ERROR is |
| 82465 | ** returned. However, in this case, data is read from the sqlite_stat1 |
| 82466 | ** table (if it is present) before returning. |
| 82467 | ** |
| 82468 | ** If an OOM error occurs, this function always sets db->mallocFailed. |
| 82469 | ** This means if the caller does not care about other errors, the return |
| @@ -81611,11 +82481,11 @@ | |
| 82481 | /* Clear any prior statistics */ |
| 82482 | assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); |
| 82483 | for(i=sqliteHashFirst(&db->aDb[iDb].pSchema->idxHash);i;i=sqliteHashNext(i)){ |
| 82484 | Index *pIdx = sqliteHashData(i); |
| 82485 | sqlite3DefaultRowEst(pIdx); |
| 82486 | #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 82487 | sqlite3DeleteIndexSamples(db, pIdx); |
| 82488 | pIdx->aSample = 0; |
| 82489 | #endif |
| 82490 | } |
| 82491 | |
| @@ -81635,16 +82505,16 @@ | |
| 82505 | rc = sqlite3_exec(db, zSql, analysisLoader, &sInfo, 0); |
| 82506 | sqlite3DbFree(db, zSql); |
| 82507 | } |
| 82508 | |
| 82509 | |
| 82510 | /* Load the statistics from the sqlite_stat4 table. */ |
| 82511 | #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 82512 | if( rc==SQLITE_OK ){ |
| 82513 | int lookasideEnabled = db->lookaside.bEnabled; |
| 82514 | db->lookaside.bEnabled = 0; |
| 82515 | rc = loadStat4(db, sInfo.zDatabase); |
| 82516 | db->lookaside.bEnabled = lookasideEnabled; |
| 82517 | } |
| 82518 | #endif |
| 82519 | |
| 82520 | if( rc==SQLITE_NOMEM ){ |
| @@ -84496,11 +85366,11 @@ | |
| 85366 | const char *zType, /* "idx" or "tbl" */ |
| 85367 | const char *zName /* Name of index or table */ |
| 85368 | ){ |
| 85369 | int i; |
| 85370 | const char *zDbName = pParse->db->aDb[iDb].zName; |
| 85371 | for(i=1; i<=4; i++){ |
| 85372 | char zTab[24]; |
| 85373 | sqlite3_snprintf(sizeof(zTab),zTab,"sqlite_stat%d",i); |
| 85374 | if( sqlite3FindTable(pParse->db, zTab, zDbName) ){ |
| 85375 | sqlite3NestedParse(pParse, |
| 85376 | "DELETE FROM %Q.%s WHERE %s=%Q", |
| @@ -89167,10 +90037,13 @@ | |
| 90037 | sqlite3FuncDefInsert(pHash, &aFunc[i]); |
| 90038 | } |
| 90039 | sqlite3RegisterDateTimeFunctions(); |
| 90040 | #ifndef SQLITE_OMIT_ALTERTABLE |
| 90041 | sqlite3AlterFunctions(); |
| 90042 | #endif |
| 90043 | #if defined(SQLITE_ENABLE_STAT3) || defined(SQLITE_ENABLE_STAT4) |
| 90044 | sqlite3AnalyzeFunctions(); |
| 90045 | #endif |
| 90046 | } |
| 90047 | |
| 90048 | /************** End of func.c ************************************************/ |
| 90049 | /************** Begin file fkey.c ********************************************/ |
| @@ -94387,11 +95260,11 @@ | |
| 95260 | */ |
| 95261 | if( sqlite3StrICmp(zLeft,"journal_size_limit")==0 ){ |
| 95262 | Pager *pPager = sqlite3BtreePager(pDb->pBt); |
| 95263 | i64 iLimit = -2; |
| 95264 | if( zRight ){ |
| 95265 | sqlite3Atoi64(zRight, &iLimit, sqlite3Strlen30(zRight), SQLITE_UTF8); |
| 95266 | if( iLimit<-1 ) iLimit = -1; |
| 95267 | } |
| 95268 | iLimit = sqlite3PagerJournalSizeLimit(pPager, iLimit); |
| 95269 | returnSingleInt(pParse, "journal_size_limit", iLimit); |
| 95270 | }else |
| @@ -94521,14 +95394,15 @@ | |
| 95394 | ** as little or as much as it wants. Except, if N is set to 0 then the |
| 95395 | ** upper layers will never invoke the xFetch interfaces to the VFS. |
| 95396 | */ |
| 95397 | if( sqlite3StrICmp(zLeft,"mmap_size")==0 ){ |
| 95398 | sqlite3_int64 sz; |
| 95399 | #if SQLITE_MAX_MMAP_SIZE>0 |
| 95400 | assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); |
| 95401 | if( zRight ){ |
| 95402 | int ii; |
| 95403 | sqlite3Atoi64(zRight, &sz, sqlite3Strlen30(zRight), SQLITE_UTF8); |
| 95404 | if( sz<0 ) sz = sqlite3GlobalConfig.szMmap; |
| 95405 | if( pId2->n==0 ) db->szMmap = sz; |
| 95406 | for(ii=db->nDb-1; ii>=0; ii--){ |
| 95407 | if( db->aDb[ii].pBt && (ii==iDb || pId2->n==0) ){ |
| 95408 | sqlite3BtreeSetMmapLimit(db->aDb[ii].pBt, sz); |
| @@ -94535,12 +95409,13 @@ | |
| 95409 | } |
| 95410 | } |
| 95411 | } |
| 95412 | sz = -1; |
| 95413 | rc = sqlite3_file_control(db, zDb, SQLITE_FCNTL_MMAP_SIZE, &sz); |
| 95414 | #else |
| 95415 | sz = 0; |
| 95416 | rc = SQLITE_OK; |
| 95417 | #endif |
| 95418 | if( rc==SQLITE_OK ){ |
| 95419 | returnSingleInt(pParse, "mmap_size", sz); |
| 95420 | }else if( rc!=SQLITE_NOTFOUND ){ |
| 95421 | pParse->nErr++; |
| @@ -102688,11 +103563,11 @@ | |
| 103563 | ** space. |
| 103564 | */ |
| 103565 | SQLITE_PRIVATE void sqlite3ColumnDefault(Vdbe *v, Table *pTab, int i, int iReg){ |
| 103566 | assert( pTab!=0 ); |
| 103567 | if( !pTab->pSelect ){ |
| 103568 | sqlite3_value *pValue = 0; |
| 103569 | u8 enc = ENC(sqlite3VdbeDb(v)); |
| 103570 | Column *pCol = &pTab->aCol[i]; |
| 103571 | VdbeComment((v, "%s.%s", pTab->zName, pCol->zName)); |
| 103572 | assert( i<pTab->nCol ); |
| 103573 | sqlite3ValueFromExpr(sqlite3VdbeDb(v), pCol->pDflt, enc, |
| @@ -105038,11 +105913,11 @@ | |
| 105913 | #define TERM_CODED 0x04 /* This term is already coded */ |
| 105914 | #define TERM_COPIED 0x08 /* Has a child */ |
| 105915 | #define TERM_ORINFO 0x10 /* Need to free the WhereTerm.u.pOrInfo object */ |
| 105916 | #define TERM_ANDINFO 0x20 /* Need to free the WhereTerm.u.pAndInfo obj */ |
| 105917 | #define TERM_OR_OK 0x40 /* Used during OR-clause processing */ |
| 105918 | #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 105919 | # define TERM_VNULL 0x80 /* Manufactured x>NULL or x<=NULL term */ |
| 105920 | #else |
| 105921 | # define TERM_VNULL 0x00 /* Disabled if not using stat3 */ |
| 105922 | #endif |
| 105923 | |
| @@ -105144,10 +106019,14 @@ | |
| 106019 | WhereInfo *pWInfo; /* Information about this WHERE */ |
| 106020 | WhereClause *pWC; /* WHERE clause terms */ |
| 106021 | ExprList *pOrderBy; /* ORDER BY clause */ |
| 106022 | WhereLoop *pNew; /* Template WhereLoop */ |
| 106023 | WhereOrSet *pOrSet; /* Record best loops here, if not NULL */ |
| 106024 | #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 106025 | UnpackedRecord *pRec; /* Probe for stat4 (if required) */ |
| 106026 | int nRecValid; /* Number of valid fields currently in pRec */ |
| 106027 | #endif |
| 106028 | }; |
| 106029 | |
| 106030 | /* |
| 106031 | ** The WHERE clause processing routine has two halves. The |
| 106032 | ** first part does the start of the WHERE loop and the second |
| @@ -106543,11 +107422,11 @@ | |
| 107422 | pNewTerm->prereqAll = pTerm->prereqAll; |
| 107423 | } |
| 107424 | } |
| 107425 | #endif /* SQLITE_OMIT_VIRTUALTABLE */ |
| 107426 | |
| 107427 | #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 107428 | /* When sqlite_stat3 histogram data is available an operator of the |
| 107429 | ** form "x IS NOT NULL" can sometimes be evaluated more efficiently |
| 107430 | ** as "x>NULL" if x is not an INTEGER PRIMARY KEY. So construct a |
| 107431 | ** virtual term of that form. |
| 107432 | ** |
| @@ -106583,11 +107462,11 @@ | |
| 107462 | pTerm->nChild = 1; |
| 107463 | pTerm->wtFlags |= TERM_COPIED; |
| 107464 | pNewTerm->prereqAll = pTerm->prereqAll; |
| 107465 | } |
| 107466 | } |
| 107467 | #endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */ |
| 107468 | |
| 107469 | /* Prevent ON clause terms of a LEFT JOIN from being used to drive |
| 107470 | ** an index for tables to the left of the join. |
| 107471 | */ |
| 107472 | pTerm->prereqRight |= extraRight; |
| @@ -107151,155 +108030,84 @@ | |
| 108030 | return pParse->nErr; |
| 108031 | } |
| 108032 | #endif /* !defined(SQLITE_OMIT_VIRTUALTABLE) */ |
| 108033 | |
| 108034 | |
| 108035 | #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 108036 | /* |
| 108037 | ** Estimate the location of a particular key among all keys in an |
| 108038 | ** index. Store the results in aStat as follows: |
| 108039 | ** |
| 108040 | ** aStat[0] Est. number of rows less than pVal |
| 108041 | ** aStat[1] Est. number of rows equal to pVal |
| 108042 | ** |
| 108043 | ** Return SQLITE_OK on success. |
| 108044 | */ |
| 108045 | static void whereKeyStats( |
| 108046 | Parse *pParse, /* Database connection */ |
| 108047 | Index *pIdx, /* Index to consider domain of */ |
| 108048 | UnpackedRecord *pRec, /* Vector of values to consider */ |
| 108049 | int roundUp, /* Round up if true. Round down if false */ |
| 108050 | tRowcnt *aStat /* OUT: stats written here */ |
| 108051 | ){ |
| 108052 | IndexSample *aSample = pIdx->aSample; |
| 108053 | int iCol = pRec->nField-1; /* Index of required stats in anEq[] etc. */ |
| 108054 | int iMin = 0; /* Smallest sample not yet tested */ |
| 108055 | int i = pIdx->nSample; /* Smallest sample larger than or equal to pRec */ |
| 108056 | int iTest; /* Next sample to test */ |
| 108057 | int res; /* Result of comparison operation */ |
| 108058 | |
| 108059 | assert( pIdx->nSample>0 ); |
| 108060 | assert( pRec->nField>0 && iCol<pIdx->nSampleCol ); |
| 108061 | do{ |
| 108062 | iTest = (iMin+i)/2; |
| 108063 | res = sqlite3VdbeRecordCompare(aSample[iTest].n, aSample[iTest].p, pRec); |
| 108064 | if( res<0 ){ |
| 108065 | iMin = iTest+1; |
| 108066 | }else{ |
| 108067 | i = iTest; |
| 108068 | } |
| 108069 | }while( res && iMin<i ); |
| 108070 | |
| 108071 | #ifdef SQLITE_DEBUG |
| 108072 | /* The following assert statements check that the binary search code |
| 108073 | ** above found the right answer. This block serves no purpose other |
| 108074 | ** than to invoke the asserts. */ |
| 108075 | if( res==0 ){ |
| 108076 | /* If (res==0) is true, then sample $i must be equal to pRec */ |
| 108077 | assert( i<pIdx->nSample ); |
| 108078 | assert( 0==sqlite3VdbeRecordCompare(aSample[i].n, aSample[i].p, pRec) |
| 108079 | || pParse->db->mallocFailed ); |
| 108080 | }else{ |
| 108081 | /* Otherwise, pRec must be smaller than sample $i and larger than |
| 108082 | ** sample ($i-1). */ |
| 108083 | assert( i==pIdx->nSample |
| 108084 | || sqlite3VdbeRecordCompare(aSample[i].n, aSample[i].p, pRec)>0 |
| 108085 | || pParse->db->mallocFailed ); |
| 108086 | assert( i==0 |
| 108087 | || sqlite3VdbeRecordCompare(aSample[i-1].n, aSample[i-1].p, pRec)<0 |
| 108088 | || pParse->db->mallocFailed ); |
| 108089 | } |
| 108090 | #endif /* ifdef SQLITE_DEBUG */ |
| 108091 | |
| 108092 | /* At this point, aSample[i] is the first sample that is greater than |
| 108093 | ** or equal to pVal. Or if i==pIdx->nSample, then all samples are less |
| 108094 | ** than pVal. If aSample[i]==pVal, then res==0. |
| 108095 | */ |
| 108096 | if( res==0 ){ |
| 108097 | aStat[0] = aSample[i].anLt[iCol]; |
| 108098 | aStat[1] = aSample[i].anEq[iCol]; |
| 108099 | }else{ |
| 108100 | tRowcnt iLower, iUpper, iGap; |
| 108101 | if( i==0 ){ |
| 108102 | iLower = 0; |
| 108103 | iUpper = aSample[0].anLt[iCol]; |
| 108104 | }else{ |
| 108105 | iUpper = i>=pIdx->nSample ? pIdx->aiRowEst[0] : aSample[i].anLt[iCol]; |
| 108106 | iLower = aSample[i-1].anEq[iCol] + aSample[i-1].anLt[iCol]; |
| 108107 | } |
| 108108 | aStat[1] = (pIdx->nColumn>iCol ? pIdx->aAvgEq[iCol] : 1); |
| 108109 | if( iLower>=iUpper ){ |
| 108110 | iGap = 0; |
| 108111 | }else{ |
| 108112 | iGap = iUpper - iLower; |
| 108113 | } |
| @@ -107308,48 +108116,12 @@ | |
| 108116 | }else{ |
| 108117 | iGap = iGap/3; |
| 108118 | } |
| 108119 | aStat[0] = iLower + iGap; |
| 108120 | } |
| 108121 | } |
| 108122 | #endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */ |
| 108123 | |
| 108124 | /* |
| 108125 | ** This function is used to estimate the number of rows that will be visited |
| 108126 | ** by scanning an index for a range of values. The range may have an upper |
| 108127 | ** bound, a lower bound, or both. The WHERE clause terms that set the upper |
| @@ -107362,107 +108134,154 @@ | |
| 108134 | ** pLower pUpper |
| 108135 | ** |
| 108136 | ** If either of the upper or lower bound is not present, then NULL is passed in |
| 108137 | ** place of the corresponding WhereTerm. |
| 108138 | ** |
| 108139 | ** The value in (pBuilder->pNew->u.btree.nEq) is the index of the index |
| 108140 | ** column subject to the range constraint. Or, equivalently, the number of |
| 108141 | ** equality constraints optimized by the proposed index scan. For example, |
| 108142 | ** assuming index p is on t1(a, b), and the SQL query is: |
| 108143 | ** |
| 108144 | ** ... FROM t1 WHERE a = ? AND b > ? AND b < ? ... |
| 108145 | ** |
| 108146 | ** then nEq is set to 1 (as the range restricted column, b, is the second |
| 108147 | ** left-most column of the index). Or, if the query is: |
| 108148 | ** |
| 108149 | ** ... FROM t1 WHERE a > ? AND a < ? ... |
| 108150 | ** |
| 108151 | ** then nEq is set to 0. |
| 108152 | ** |
| 108153 | ** When this function is called, *pnOut is set to the whereCost() of the |
| 108154 | ** number of rows that the index scan is expected to visit without |
| 108155 | ** considering the range constraints. If nEq is 0, this is the number of |
| 108156 | ** rows in the index. Assuming no error occurs, *pnOut is adjusted (reduced) |
| 108157 | ** to account for the range contraints pLower and pUpper. |
| 108158 | ** |
| 108159 | ** In the absence of sqlite_stat4 ANALYZE data, or if such data cannot be |
| 108160 | ** used, each range inequality reduces the search space by a factor of 4. |
| 108161 | ** Hence a pair of constraints (x>? AND x<?) reduces the expected number of |
| 108162 | ** rows visited by a factor of 16. |
| 108163 | */ |
| 108164 | static int whereRangeScanEst( |
| 108165 | Parse *pParse, /* Parsing & code generating context */ |
| 108166 | WhereLoopBuilder *pBuilder, |
| 108167 | WhereTerm *pLower, /* Lower bound on the range. ex: "x>123" Might be NULL */ |
| 108168 | WhereTerm *pUpper, /* Upper bound on the range. ex: "x<455" Might be NULL */ |
| 108169 | WhereCost *pnOut /* IN/OUT: Number of rows visited */ |
| 108170 | ){ |
| 108171 | int rc = SQLITE_OK; |
| 108172 | int nOut = (int)*pnOut; |
| 108173 | |
| 108174 | #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 108175 | Index *p = pBuilder->pNew->u.btree.pIndex; |
| 108176 | int nEq = pBuilder->pNew->u.btree.nEq; |
| 108177 | |
| 108178 | if( nEq==pBuilder->nRecValid |
| 108179 | && nEq<p->nSampleCol |
| 108180 | && p->nSample |
| 108181 | && OptimizationEnabled(pParse->db, SQLITE_Stat3) |
| 108182 | ){ |
| 108183 | UnpackedRecord *pRec = pBuilder->pRec; |
| 108184 | tRowcnt a[2]; |
| 108185 | u8 aff = p->pTable->aCol[p->aiColumn[0]].affinity; |
| 108186 | |
| 108187 | /* Variable iLower will be set to the estimate of the number of rows in |
| 108188 | ** the index that are less than the lower bound of the range query. The |
| 108189 | ** lower bound being the concatenation of $P and $L, where $P is the |
| 108190 | ** key-prefix formed by the nEq values matched against the nEq left-most |
| 108191 | ** columns of the index, and $L is the value in pLower. |
| 108192 | ** |
| 108193 | ** Or, if pLower is NULL or $L cannot be extracted from it (because it |
| 108194 | ** is not a simple variable or literal value), the lower bound of the |
| 108195 | ** range is $P. Due to a quirk in the way whereKeyStats() works, even |
| 108196 | ** if $L is available, whereKeyStats() is called for both ($P) and |
| 108197 | ** ($P:$L) and the larger of the two returned values used. |
| 108198 | ** |
| 108199 | ** Similarly, iUpper is to be set to the estimate of the number of rows |
| 108200 | ** less than the upper bound of the range query. Where the upper bound |
| 108201 | ** is either ($P) or ($P:$U). Again, even if $U is available, both values |
| 108202 | ** of iUpper are requested of whereKeyStats() and the smaller used. |
| 108203 | */ |
| 108204 | tRowcnt iLower; |
| 108205 | tRowcnt iUpper; |
| 108206 | |
| 108207 | /* Determine iLower and iUpper using ($P) only. */ |
| 108208 | if( nEq==0 ){ |
| 108209 | iLower = 0; |
| 108210 | iUpper = p->aiRowEst[0]; |
| 108211 | }else{ |
| 108212 | /* Note: this call could be optimized away - since the same values must |
| 108213 | ** have been requested when testing key $P in whereEqualScanEst(). */ |
| 108214 | whereKeyStats(pParse, p, pRec, 0, a); |
| 108215 | iLower = a[0]; |
| 108216 | iUpper = a[0] + a[1]; |
| 108217 | } |
| 108218 | |
| 108219 | /* If possible, improve on the iLower estimate using ($P:$L). */ |
| 108220 | if( pLower ){ |
| 108221 | int bOk; /* True if value is extracted from pExpr */ |
| 108222 | Expr *pExpr = pLower->pExpr->pRight; |
| 108223 | assert( (pLower->eOperator & (WO_GT|WO_GE))!=0 ); |
| 108224 | rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, aff, nEq, &bOk); |
| 108225 | if( rc==SQLITE_OK && bOk ){ |
| 108226 | tRowcnt iNew; |
| 108227 | whereKeyStats(pParse, p, pRec, 0, a); |
| 108228 | iNew = a[0] + ((pLower->eOperator & WO_GT) ? a[1] : 0); |
| 108229 | if( iNew>iLower ) iLower = iNew; |
| 108230 | } |
| 108231 | } |
| 108232 | |
| 108233 | /* If possible, improve on the iUpper estimate using ($P:$U). */ |
| 108234 | if( pUpper ){ |
| 108235 | int bOk; /* True if value is extracted from pExpr */ |
| 108236 | Expr *pExpr = pUpper->pExpr->pRight; |
| 108237 | assert( (pUpper->eOperator & (WO_LT|WO_LE))!=0 ); |
| 108238 | rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, aff, nEq, &bOk); |
| 108239 | if( rc==SQLITE_OK && bOk ){ |
| 108240 | tRowcnt iNew; |
| 108241 | whereKeyStats(pParse, p, pRec, 1, a); |
| 108242 | iNew = a[0] + ((pUpper->eOperator & WO_LE) ? a[1] : 0); |
| 108243 | if( iNew<iUpper ) iUpper = iNew; |
| 108244 | } |
| 108245 | } |
| 108246 | |
| 108247 | pBuilder->pRec = pRec; |
| 108248 | if( rc==SQLITE_OK ){ |
| 108249 | WhereCost nNew; |
| 108250 | if( iUpper>iLower ){ |
| 108251 | nNew = whereCost(iUpper - iLower); |
| 108252 | }else{ |
| 108253 | nNew = 10; assert( 10==whereCost(2) ); |
| 108254 | } |
| 108255 | if( nNew<nOut ){ |
| 108256 | nOut = nNew; |
| 108257 | } |
| 108258 | *pnOut = (WhereCost)nOut; |
| 108259 | WHERETRACE(0x100, ("range scan regions: %u..%u est=%d\n", |
| 108260 | (u32)iLower, (u32)iUpper, nOut)); |
| 108261 | return SQLITE_OK; |
| 108262 | } |
| 108263 | } |
| 108264 | #else |
| 108265 | UNUSED_PARAMETER(pParse); |
| 108266 | UNUSED_PARAMETER(pBuilder); |
| 108267 | #endif |
| 108268 | assert( pLower || pUpper ); |
| 108269 | /* TUNING: Each inequality constraint reduces the search space 4-fold. |
| 108270 | ** A BETWEEN operator, therefore, reduces the search space 16-fold */ |
| 108271 | if( pLower && (pLower->wtFlags & TERM_VNULL)==0 ){ |
| 108272 | nOut -= 20; assert( 20==whereCost(4) ); |
| 108273 | } |
| 108274 | if( pUpper ){ |
| 108275 | nOut -= 20; assert( 20==whereCost(4) ); |
| 108276 | } |
| 108277 | if( nOut<10 ) nOut = 10; |
| 108278 | *pnOut = (WhereCost)nOut; |
| 108279 | return rc; |
| 108280 | } |
| 108281 | |
| 108282 | #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 108283 | /* |
| 108284 | ** Estimate the number of rows that will be returned based on |
| 108285 | ** an equality constraint x=VALUE and where that VALUE occurs in |
| 108286 | ** the histogram data. This only works when x is the left-most |
| 108287 | ** column of an index and sqlite_stat3 histogram data is available |
| @@ -107478,41 +108297,57 @@ | |
| 108297 | ** for a UTF conversion required for comparison. The error is stored |
| 108298 | ** in the pParse structure. |
| 108299 | */ |
| 108300 | static int whereEqualScanEst( |
| 108301 | Parse *pParse, /* Parsing & code generating context */ |
| 108302 | WhereLoopBuilder *pBuilder, |
| 108303 | Expr *pExpr, /* Expression for VALUE in the x=VALUE constraint */ |
| 108304 | tRowcnt *pnRow /* Write the revised row estimate here */ |
| 108305 | ){ |
| 108306 | Index *p = pBuilder->pNew->u.btree.pIndex; |
| 108307 | int nEq = pBuilder->pNew->u.btree.nEq; |
| 108308 | UnpackedRecord *pRec = pBuilder->pRec; |
| 108309 | u8 aff; /* Column affinity */ |
| 108310 | int rc; /* Subfunction return code */ |
| 108311 | tRowcnt a[2]; /* Statistics */ |
| 108312 | int bOk; |
| 108313 | |
| 108314 | assert( nEq>=1 ); |
| 108315 | assert( nEq<=(p->nColumn+1) ); |
| 108316 | assert( p->aSample!=0 ); |
| 108317 | assert( p->nSample>0 ); |
| 108318 | assert( pBuilder->nRecValid<nEq ); |
| 108319 | |
| 108320 | /* If values are not available for all fields of the index to the left |
| 108321 | ** of this one, no estimate can be made. Return SQLITE_NOTFOUND. */ |
| 108322 | if( pBuilder->nRecValid<(nEq-1) ){ |
| 108323 | return SQLITE_NOTFOUND; |
| 108324 | } |
| 108325 | |
| 108326 | /* This is an optimization only. The call to sqlite3Stat4ProbeSetValue() |
| 108327 | ** below would return the same value. */ |
| 108328 | if( nEq>p->nColumn ){ |
| 108329 | *pnRow = 1; |
| 108330 | return SQLITE_OK; |
| 108331 | } |
| 108332 | |
| 108333 | aff = p->pTable->aCol[p->aiColumn[nEq-1]].affinity; |
| 108334 | rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, aff, nEq-1, &bOk); |
| 108335 | pBuilder->pRec = pRec; |
| 108336 | if( rc!=SQLITE_OK ) return rc; |
| 108337 | if( bOk==0 ) return SQLITE_NOTFOUND; |
| 108338 | pBuilder->nRecValid = nEq; |
| 108339 | |
| 108340 | whereKeyStats(pParse, p, pRec, 0, a); |
| 108341 | WHERETRACE(0x100,("equality scan regions: %d\n", (int)a[1])); |
| 108342 | *pnRow = a[1]; |
| 108343 | |
| 108344 | return rc; |
| 108345 | } |
| 108346 | #endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */ |
| 108347 | |
| 108348 | #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 108349 | /* |
| 108350 | ** Estimate the number of rows that will be returned based on |
| 108351 | ** an IN constraint where the right-hand side of the IN operator |
| 108352 | ** is a list of values. Example: |
| 108353 | ** |
| @@ -107527,33 +108362,38 @@ | |
| 108362 | ** for a UTF conversion required for comparison. The error is stored |
| 108363 | ** in the pParse structure. |
| 108364 | */ |
| 108365 | static int whereInScanEst( |
| 108366 | Parse *pParse, /* Parsing & code generating context */ |
| 108367 | WhereLoopBuilder *pBuilder, |
| 108368 | ExprList *pList, /* The value list on the RHS of "x IN (v1,v2,v3,...)" */ |
| 108369 | tRowcnt *pnRow /* Write the revised row estimate here */ |
| 108370 | ){ |
| 108371 | Index *p = pBuilder->pNew->u.btree.pIndex; |
| 108372 | int nRecValid = pBuilder->nRecValid; |
| 108373 | int rc = SQLITE_OK; /* Subfunction return code */ |
| 108374 | tRowcnt nEst; /* Number of rows for a single term */ |
| 108375 | tRowcnt nRowEst = 0; /* New estimate of the number of rows */ |
| 108376 | int i; /* Loop counter */ |
| 108377 | |
| 108378 | assert( p->aSample!=0 ); |
| 108379 | for(i=0; rc==SQLITE_OK && i<pList->nExpr; i++){ |
| 108380 | nEst = p->aiRowEst[0]; |
| 108381 | rc = whereEqualScanEst(pParse, pBuilder, pList->a[i].pExpr, &nEst); |
| 108382 | nRowEst += nEst; |
| 108383 | pBuilder->nRecValid = nRecValid; |
| 108384 | } |
| 108385 | |
| 108386 | if( rc==SQLITE_OK ){ |
| 108387 | if( nRowEst > p->aiRowEst[0] ) nRowEst = p->aiRowEst[0]; |
| 108388 | *pnRow = nRowEst; |
| 108389 | WHERETRACE(0x100,("IN row estimate: est=%g\n", nRowEst)); |
| 108390 | } |
| 108391 | assert( pBuilder->nRecValid==nRecValid ); |
| 108392 | return rc; |
| 108393 | } |
| 108394 | #endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */ |
| 108395 | |
| 108396 | /* |
| 108397 | ** Disable a term in the WHERE clause. Except, do not disable the term |
| 108398 | ** if it controls a LEFT OUTER JOIN and it did not originate in the ON |
| 108399 | ** or USING clause of that join. |
| @@ -107787,11 +108627,11 @@ | |
| 108627 | pParse->db->mallocFailed = 1; |
| 108628 | } |
| 108629 | |
| 108630 | /* Evaluate the equality constraints |
| 108631 | */ |
| 108632 | assert( zAff==0 || (int)strlen(zAff)>=nEq ); |
| 108633 | for(j=0; j<nEq; j++){ |
| 108634 | int r1; |
| 108635 | pTerm = pLoop->aLTerm[j]; |
| 108636 | assert( pTerm!=0 ); |
| 108637 | /* The following true for indices with redundant columns. |
| @@ -109094,16 +109934,22 @@ | |
| 109934 | saved_nOut = pNew->nOut; |
| 109935 | pNew->rSetup = 0; |
| 109936 | rLogSize = estLog(whereCost(pProbe->aiRowEst[0])); |
| 109937 | for(; rc==SQLITE_OK && pTerm!=0; pTerm = whereScanNext(&scan)){ |
| 109938 | int nIn = 0; |
| 109939 | #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 109940 | int nRecValid = pBuilder->nRecValid; |
| 109941 | #endif |
| 109942 | if( (pTerm->eOperator==WO_ISNULL || (pTerm->wtFlags&TERM_VNULL)!=0) |
| 109943 | && (iCol<0 || pSrc->pTab->aCol[iCol].notNull) |
| 109944 | ){ |
| 109945 | continue; /* ignore IS [NOT] NULL constraints on NOT NULL columns */ |
| 109946 | } |
| 109947 | if( pTerm->prereqRight & pNew->maskSelf ) continue; |
| 109948 | |
| 109949 | assert( pNew->nOut==saved_nOut ); |
| 109950 | |
| 109951 | pNew->wsFlags = saved_wsFlags; |
| 109952 | pNew->u.btree.nEq = saved_nEq; |
| 109953 | pNew->nLTerm = saved_nLTerm; |
| 109954 | if( whereLoopResize(db, pNew, pNew->nLTerm+1) ) break; /* OOM */ |
| 109955 | pNew->aLTerm[pNew->nLTerm++] = pTerm; |
| @@ -109156,29 +110002,34 @@ | |
| 110002 | pBtm = (pNew->wsFlags & WHERE_BTM_LIMIT)!=0 ? |
| 110003 | pNew->aLTerm[pNew->nLTerm-2] : 0; |
| 110004 | } |
| 110005 | if( pNew->wsFlags & WHERE_COLUMN_RANGE ){ |
| 110006 | /* Adjust nOut and rRun for STAT3 range values */ |
| 110007 | assert( pNew->nOut==saved_nOut ); |
| 110008 | whereRangeScanEst(pParse, pBuilder, pBtm, pTop, &pNew->nOut); |
| 110009 | } |
| 110010 | #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 110011 | if( nInMul==0 |
| 110012 | && pProbe->nSample |
| 110013 | && pNew->u.btree.nEq<=pProbe->nSampleCol |
| 110014 | && OptimizationEnabled(db, SQLITE_Stat3) |
| 110015 | ){ |
| 110016 | Expr *pExpr = pTerm->pExpr; |
| 110017 | tRowcnt nOut = 0; |
| 110018 | if( (pTerm->eOperator & (WO_EQ|WO_ISNULL))!=0 ){ |
| 110019 | testcase( pTerm->eOperator & WO_EQ ); |
| 110020 | testcase( pTerm->eOperator & WO_ISNULL ); |
| 110021 | rc = whereEqualScanEst(pParse, pBuilder, pExpr->pRight, &nOut); |
| 110022 | }else if( (pTerm->eOperator & WO_IN) |
| 110023 | && !ExprHasProperty(pExpr, EP_xIsSelect) ){ |
| 110024 | rc = whereInScanEst(pParse, pBuilder, pExpr->x.pList, &nOut); |
| 110025 | } |
| 110026 | assert( nOut==0 || rc==SQLITE_OK ); |
| 110027 | if( nOut ){ |
| 110028 | nOut = whereCost(nOut); |
| 110029 | pNew->nOut = MIN(nOut, saved_nOut); |
| 110030 | } |
| 110031 | } |
| 110032 | #endif |
| 110033 | if( (pNew->wsFlags & (WHERE_IDX_ONLY|WHERE_IPK))==0 ){ |
| 110034 | /* Each row involves a step of the index, then a binary search of |
| 110035 | ** the main table */ |
| @@ -109191,10 +110042,14 @@ | |
| 110042 | if( (pNew->wsFlags & WHERE_TOP_LIMIT)==0 |
| 110043 | && pNew->u.btree.nEq<(pProbe->nColumn + (pProbe->zName!=0)) |
| 110044 | ){ |
| 110045 | whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, nInMul+nIn); |
| 110046 | } |
| 110047 | pNew->nOut = saved_nOut; |
| 110048 | #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 110049 | pBuilder->nRecValid = nRecValid; |
| 110050 | #endif |
| 110051 | } |
| 110052 | pNew->prereq = saved_prereq; |
| 110053 | pNew->u.btree.nEq = saved_nEq; |
| 110054 | pNew->wsFlags = saved_wsFlags; |
| 110055 | pNew->nOut = saved_nOut; |
| @@ -109420,11 +110275,17 @@ | |
| 110275 | } |
| 110276 | rc = whereLoopInsert(pBuilder, pNew); |
| 110277 | if( rc ) break; |
| 110278 | } |
| 110279 | } |
| 110280 | |
| 110281 | rc = whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, 0); |
| 110282 | #ifdef SQLITE_ENABLE_STAT3_OR_STAT4 |
| 110283 | sqlite3Stat4ProbeFree(pBuilder->pRec); |
| 110284 | pBuilder->nRecValid = 0; |
| 110285 | pBuilder->pRec = 0; |
| 110286 | #endif |
| 110287 | |
| 110288 | /* If there was an INDEXED BY clause, then only that one index is |
| 110289 | ** considered. */ |
| 110290 | if( pSrc->pIndex ) break; |
| 110291 | } |
| 110292 |
+3
-3
| --- src/sqlite3.h | ||
| +++ src/sqlite3.h | ||
| @@ -105,13 +105,13 @@ | ||
| 105 | 105 | ** |
| 106 | 106 | ** See also: [sqlite3_libversion()], |
| 107 | 107 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 108 | 108 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 109 | 109 | */ |
| 110 | -#define SQLITE_VERSION "3.8.0.1" | |
| 111 | -#define SQLITE_VERSION_NUMBER 3008000 | |
| 112 | -#define SQLITE_SOURCE_ID "2013-08-29 13:47:05 c5857808c0707baa30994dd6aa3b9c93a74c0073" | |
| 110 | +#define SQLITE_VERSION "3.8.1" | |
| 111 | +#define SQLITE_VERSION_NUMBER 3008001 | |
| 112 | +#define SQLITE_SOURCE_ID "2013-08-29 23:36:49 30d38cc44904d93508b87e373b2f45d5f93e556b" | |
| 113 | 113 | |
| 114 | 114 | /* |
| 115 | 115 | ** CAPI3REF: Run-Time Library Version Numbers |
| 116 | 116 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 117 | 117 | ** |
| 118 | 118 |
| --- src/sqlite3.h | |
| +++ src/sqlite3.h | |
| @@ -105,13 +105,13 @@ | |
| 105 | ** |
| 106 | ** See also: [sqlite3_libversion()], |
| 107 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 108 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 109 | */ |
| 110 | #define SQLITE_VERSION "3.8.0.1" |
| 111 | #define SQLITE_VERSION_NUMBER 3008000 |
| 112 | #define SQLITE_SOURCE_ID "2013-08-29 13:47:05 c5857808c0707baa30994dd6aa3b9c93a74c0073" |
| 113 | |
| 114 | /* |
| 115 | ** CAPI3REF: Run-Time Library Version Numbers |
| 116 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 117 | ** |
| 118 |
| --- src/sqlite3.h | |
| +++ src/sqlite3.h | |
| @@ -105,13 +105,13 @@ | |
| 105 | ** |
| 106 | ** See also: [sqlite3_libversion()], |
| 107 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 108 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 109 | */ |
| 110 | #define SQLITE_VERSION "3.8.1" |
| 111 | #define SQLITE_VERSION_NUMBER 3008001 |
| 112 | #define SQLITE_SOURCE_ID "2013-08-29 23:36:49 30d38cc44904d93508b87e373b2f45d5f93e556b" |
| 113 | |
| 114 | /* |
| 115 | ** CAPI3REF: Run-Time Library Version Numbers |
| 116 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 117 | ** |
| 118 |