| | @@ -135,11 +135,11 @@ |
| 135 | 135 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 136 | 136 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 137 | 137 | */ |
| 138 | 138 | #define SQLITE_VERSION "3.8.2" |
| 139 | 139 | #define SQLITE_VERSION_NUMBER 3008002 |
| 140 | | -#define SQLITE_SOURCE_ID "2013-11-25 20:50:23 032e89934f36de10652d3454a0065a337827221a" |
| 140 | +#define SQLITE_SOURCE_ID "2013-11-27 14:50:51 c75f561f337a56c14335366ed9990e44bc9fc594" |
| 141 | 141 | |
| 142 | 142 | /* |
| 143 | 143 | ** CAPI3REF: Run-Time Library Version Numbers |
| 144 | 144 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 145 | 145 | ** |
| | @@ -1713,10 +1713,17 @@ |
| 1713 | 1713 | ** cannot be changed at run-time. Nor may the maximum allowed mmap size |
| 1714 | 1714 | ** exceed the compile-time maximum mmap size set by the |
| 1715 | 1715 | ** [SQLITE_MAX_MMAP_SIZE] compile-time option.)^ |
| 1716 | 1716 | ** ^If either argument to this option is negative, then that argument is |
| 1717 | 1717 | ** changed to its compile-time default. |
| 1718 | +** |
| 1719 | +** [[SQLITE_CONFIG_WIN32_HEAPSIZE]] |
| 1720 | +** <dt>SQLITE_CONFIG_WIN32_HEAPSIZE |
| 1721 | +** <dd>^This option is only available if SQLite is compiled for Windows |
| 1722 | +** with the [SQLITE_WIN32_MALLOC] pre-processor macro defined. |
| 1723 | +** SQLITE_CONFIG_WIN32_HEAPSIZE takes a 32-bit unsigned integer value |
| 1724 | +** that specifies the maximum size of the created heap. |
| 1718 | 1725 | ** </dl> |
| 1719 | 1726 | */ |
| 1720 | 1727 | #define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */ |
| 1721 | 1728 | #define SQLITE_CONFIG_MULTITHREAD 2 /* nil */ |
| 1722 | 1729 | #define SQLITE_CONFIG_SERIALIZED 3 /* nil */ |
| | @@ -1737,10 +1744,11 @@ |
| 1737 | 1744 | #define SQLITE_CONFIG_PCACHE2 18 /* sqlite3_pcache_methods2* */ |
| 1738 | 1745 | #define SQLITE_CONFIG_GETPCACHE2 19 /* sqlite3_pcache_methods2* */ |
| 1739 | 1746 | #define SQLITE_CONFIG_COVERING_INDEX_SCAN 20 /* int */ |
| 1740 | 1747 | #define SQLITE_CONFIG_SQLLOG 21 /* xSqllog, void* */ |
| 1741 | 1748 | #define SQLITE_CONFIG_MMAP_SIZE 22 /* sqlite3_int64, sqlite3_int64 */ |
| 1749 | +#define SQLITE_CONFIG_WIN32_HEAPSIZE 23 /* int nByte */ |
| 1742 | 1750 | |
| 1743 | 1751 | /* |
| 1744 | 1752 | ** CAPI3REF: Database Connection Configuration Options |
| 1745 | 1753 | ** |
| 1746 | 1754 | ** These constants are the available integer configuration options that |
| | @@ -21832,11 +21840,11 @@ |
| 21832 | 21840 | while( zNum<zEnd && zNum[0]=='0' ){ zNum+=incr; } /* Skip leading zeros. */ |
| 21833 | 21841 | for(i=0; &zNum[i]<zEnd && (c=zNum[i])>='0' && c<='9'; i+=incr){ |
| 21834 | 21842 | u = u*10 + c - '0'; |
| 21835 | 21843 | } |
| 21836 | 21844 | if( u>LARGEST_INT64 ){ |
| 21837 | | - *pNum = SMALLEST_INT64; |
| 21845 | + *pNum = neg ? SMALLEST_INT64 : LARGEST_INT64; |
| 21838 | 21846 | }else if( neg ){ |
| 21839 | 21847 | *pNum = -(i64)u; |
| 21840 | 21848 | }else{ |
| 21841 | 21849 | *pNum = (i64)u; |
| 21842 | 21850 | } |
| | @@ -21863,11 +21871,10 @@ |
| 21863 | 21871 | return 1; |
| 21864 | 21872 | }else{ |
| 21865 | 21873 | /* zNum is exactly 9223372036854775808. Fits if negative. The |
| 21866 | 21874 | ** special case 2 overflow if positive */ |
| 21867 | 21875 | assert( u-1==LARGEST_INT64 ); |
| 21868 | | - assert( (*pNum)==SMALLEST_INT64 ); |
| 21869 | 21876 | return neg ? 0 : 2; |
| 21870 | 21877 | } |
| 21871 | 21878 | } |
| 21872 | 21879 | } |
| 21873 | 21880 | |
| | @@ -30986,10 +30993,38 @@ |
| 30986 | 30993 | #if !defined(SQLITE_WIN32_HAS_ANSI) && !defined(SQLITE_WIN32_HAS_WIDE) |
| 30987 | 30994 | # error "At least one of SQLITE_WIN32_HAS_ANSI and SQLITE_WIN32_HAS_WIDE\ |
| 30988 | 30995 | must be defined." |
| 30989 | 30996 | #endif |
| 30990 | 30997 | |
| 30998 | +/* |
| 30999 | +** Define the required Windows SDK version constants if they are not |
| 31000 | +** already available. |
| 31001 | +*/ |
| 31002 | +#ifndef NTDDI_WIN8 |
| 31003 | +# define NTDDI_WIN8 0x06020000 |
| 31004 | +#endif |
| 31005 | + |
| 31006 | +#ifndef NTDDI_WINBLUE |
| 31007 | +# define NTDDI_WINBLUE 0x06030000 |
| 31008 | +#endif |
| 31009 | + |
| 31010 | +/* |
| 31011 | +** Check if the GetVersionEx[AW] functions should be considered deprecated |
| 31012 | +** and avoid using them in that case. It should be noted here that if the |
| 31013 | +** value of the SQLITE_WIN32_GETVERSIONEX pre-processor macro is zero |
| 31014 | +** (whether via this block or via being manually specified), that implies |
| 31015 | +** the underlying operating system will always be based on the Windows NT |
| 31016 | +** Kernel. |
| 31017 | +*/ |
| 31018 | +#ifndef SQLITE_WIN32_GETVERSIONEX |
| 31019 | +# if defined(NTDDI_VERSION) && NTDDI_VERSION >= NTDDI_WINBLUE |
| 31020 | +# define SQLITE_WIN32_GETVERSIONEX 0 |
| 31021 | +# else |
| 31022 | +# define SQLITE_WIN32_GETVERSIONEX 1 |
| 31023 | +# endif |
| 31024 | +#endif |
| 31025 | + |
| 30991 | 31026 | /* |
| 30992 | 31027 | ** This constant should already be defined (in the "WinDef.h" SDK file). |
| 30993 | 31028 | */ |
| 30994 | 31029 | #ifndef MAX_PATH |
| 30995 | 31030 | # define MAX_PATH (260) |
| | @@ -31621,20 +31656,22 @@ |
| 31621 | 31656 | { "GetTickCount", (SYSCALL)0, 0 }, |
| 31622 | 31657 | #endif |
| 31623 | 31658 | |
| 31624 | 31659 | #define osGetTickCount ((DWORD(WINAPI*)(VOID))aSyscall[33].pCurrent) |
| 31625 | 31660 | |
| 31626 | | -#if defined(SQLITE_WIN32_HAS_ANSI) |
| 31661 | +#if defined(SQLITE_WIN32_HAS_ANSI) && defined(SQLITE_WIN32_GETVERSIONEX) && \ |
| 31662 | + SQLITE_WIN32_GETVERSIONEX |
| 31627 | 31663 | { "GetVersionExA", (SYSCALL)GetVersionExA, 0 }, |
| 31628 | 31664 | #else |
| 31629 | 31665 | { "GetVersionExA", (SYSCALL)0, 0 }, |
| 31630 | 31666 | #endif |
| 31631 | 31667 | |
| 31632 | 31668 | #define osGetVersionExA ((BOOL(WINAPI*)( \ |
| 31633 | 31669 | LPOSVERSIONINFOA))aSyscall[34].pCurrent) |
| 31634 | 31670 | |
| 31635 | | -#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) |
| 31671 | +#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) && \ |
| 31672 | + defined(SQLITE_WIN32_GETVERSIONEX) && SQLITE_WIN32_GETVERSIONEX |
| 31636 | 31673 | { "GetVersionExW", (SYSCALL)GetVersionExW, 0 }, |
| 31637 | 31674 | #else |
| 31638 | 31675 | { "GetVersionExW", (SYSCALL)0, 0 }, |
| 31639 | 31676 | #endif |
| 31640 | 31677 | |
| | @@ -32187,15 +32224,14 @@ |
| 32187 | 32224 | ** API as long as we don't call it when running Win95/98/ME. A call to |
| 32188 | 32225 | ** this routine is used to determine if the host is Win95/98/ME or |
| 32189 | 32226 | ** WinNT/2K/XP so that we will know whether or not we can safely call |
| 32190 | 32227 | ** the LockFileEx() API. |
| 32191 | 32228 | */ |
| 32192 | | -#ifndef NTDDI_WIN8 |
| 32193 | | -# define NTDDI_WIN8 0x06020000 |
| 32194 | | -#endif |
| 32195 | 32229 | |
| 32196 | | -#if SQLITE_OS_WINCE || SQLITE_OS_WINRT || !defined(SQLITE_WIN32_HAS_ANSI) |
| 32230 | +#if !defined(SQLITE_WIN32_GETVERSIONEX) || !SQLITE_WIN32_GETVERSIONEX |
| 32231 | +# define osIsNT() (1) |
| 32232 | +#elif SQLITE_OS_WINCE || SQLITE_OS_WINRT || !defined(SQLITE_WIN32_HAS_ANSI) |
| 32197 | 32233 | # define osIsNT() (1) |
| 32198 | 32234 | #elif !defined(SQLITE_WIN32_HAS_WIDE) |
| 32199 | 32235 | # define osIsNT() (0) |
| 32200 | 32236 | #else |
| 32201 | 32237 | static int osIsNT(void){ |
| | @@ -32328,18 +32364,24 @@ |
| 32328 | 32364 | assert( pWinMemData->magic1==WINMEM_MAGIC1 ); |
| 32329 | 32365 | assert( pWinMemData->magic2==WINMEM_MAGIC2 ); |
| 32330 | 32366 | |
| 32331 | 32367 | #if !SQLITE_OS_WINRT && SQLITE_WIN32_HEAP_CREATE |
| 32332 | 32368 | if( !pWinMemData->hHeap ){ |
| 32369 | + DWORD dwInitialSize = SQLITE_WIN32_HEAP_INIT_SIZE; |
| 32370 | + DWORD dwMaximumSize = (DWORD)sqlite3GlobalConfig.nHeap; |
| 32371 | + if( dwMaximumSize==0 ){ |
| 32372 | + dwMaximumSize = SQLITE_WIN32_HEAP_MAX_SIZE; |
| 32373 | + }else if( dwInitialSize>dwMaximumSize ){ |
| 32374 | + dwInitialSize = dwMaximumSize; |
| 32375 | + } |
| 32333 | 32376 | pWinMemData->hHeap = osHeapCreate(SQLITE_WIN32_HEAP_FLAGS, |
| 32334 | | - SQLITE_WIN32_HEAP_INIT_SIZE, |
| 32335 | | - SQLITE_WIN32_HEAP_MAX_SIZE); |
| 32377 | + dwInitialSize, dwMaximumSize); |
| 32336 | 32378 | if( !pWinMemData->hHeap ){ |
| 32337 | 32379 | sqlite3_log(SQLITE_NOMEM, |
| 32338 | | - "failed to HeapCreate (%lu), flags=%u, initSize=%u, maxSize=%u", |
| 32339 | | - osGetLastError(), SQLITE_WIN32_HEAP_FLAGS, |
| 32340 | | - SQLITE_WIN32_HEAP_INIT_SIZE, SQLITE_WIN32_HEAP_MAX_SIZE); |
| 32380 | + "failed to HeapCreate (%lu), flags=%u, initSize=%lu, maxSize=%lu", |
| 32381 | + osGetLastError(), SQLITE_WIN32_HEAP_FLAGS, dwInitialSize, |
| 32382 | + dwMaximumSize); |
| 32341 | 32383 | return SQLITE_NOMEM; |
| 32342 | 32384 | } |
| 32343 | 32385 | pWinMemData->bOwned = TRUE; |
| 32344 | 32386 | assert( pWinMemData->bOwned ); |
| 32345 | 32387 | } |
| | @@ -34995,11 +35037,11 @@ |
| 34995 | 35037 | ** |
| 34996 | 35038 | ** This division contains the implementation of methods on the |
| 34997 | 35039 | ** sqlite3_vfs object. |
| 34998 | 35040 | */ |
| 34999 | 35041 | |
| 35000 | | -#if 0 |
| 35042 | +#if defined(__CYGWIN__) |
| 35001 | 35043 | /* |
| 35002 | 35044 | ** Convert a filename from whatever the underlying operating system |
| 35003 | 35045 | ** supports for filenames into UTF-8. Space to hold the result is |
| 35004 | 35046 | ** obtained from malloc and must be freed by the calling function. |
| 35005 | 35047 | */ |
| | @@ -35171,27 +35213,21 @@ |
| 35171 | 35213 | if( winIsDir(zConverted) ){ |
| 35172 | 35214 | /* At this point, we know the candidate directory exists and should |
| 35173 | 35215 | ** be used. However, we may need to convert the string containing |
| 35174 | 35216 | ** its name into UTF-8 (i.e. if it is UTF-16 right now). |
| 35175 | 35217 | */ |
| 35176 | | - if( osIsNT() ){ |
| 35177 | | - char *zUtf8 = winUnicodeToUtf8(zConverted); |
| 35178 | | - if( !zUtf8 ){ |
| 35179 | | - sqlite3_free(zConverted); |
| 35180 | | - sqlite3_free(zBuf); |
| 35181 | | - OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); |
| 35182 | | - return SQLITE_IOERR_NOMEM; |
| 35183 | | - } |
| 35184 | | - sqlite3_snprintf(nMax, zBuf, "%s", zUtf8); |
| 35185 | | - sqlite3_free(zUtf8); |
| 35186 | | - sqlite3_free(zConverted); |
| 35187 | | - break; |
| 35188 | | - }else{ |
| 35189 | | - sqlite3_snprintf(nMax, zBuf, "%s", zConverted); |
| 35190 | | - sqlite3_free(zConverted); |
| 35191 | | - break; |
| 35192 | | - } |
| 35218 | + char *zUtf8 = winConvertToUtf8Filename(zConverted); |
| 35219 | + if( !zUtf8 ){ |
| 35220 | + sqlite3_free(zConverted); |
| 35221 | + sqlite3_free(zBuf); |
| 35222 | + OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n")); |
| 35223 | + return SQLITE_IOERR_NOMEM; |
| 35224 | + } |
| 35225 | + sqlite3_snprintf(nMax, zBuf, "%s", zUtf8); |
| 35226 | + sqlite3_free(zUtf8); |
| 35227 | + sqlite3_free(zConverted); |
| 35228 | + break; |
| 35193 | 35229 | } |
| 35194 | 35230 | sqlite3_free(zConverted); |
| 35195 | 35231 | } |
| 35196 | 35232 | } |
| 35197 | 35233 | } |
| | @@ -35872,23 +35908,47 @@ |
| 35872 | 35908 | */ |
| 35873 | 35909 | char *zOut = sqlite3MallocZero( pVfs->mxPathname+1 ); |
| 35874 | 35910 | if( !zOut ){ |
| 35875 | 35911 | return SQLITE_IOERR_NOMEM; |
| 35876 | 35912 | } |
| 35877 | | - if( cygwin_conv_path(CCP_POSIX_TO_WIN_A|CCP_RELATIVE, zRelative, zOut, |
| 35878 | | - pVfs->mxPathname+1)<0 ){ |
| 35913 | + if( cygwin_conv_path( |
| 35914 | + (osIsNT() ? CCP_POSIX_TO_WIN_W : CCP_POSIX_TO_WIN_A) | |
| 35915 | + CCP_RELATIVE, zRelative, zOut, pVfs->mxPathname+1)<0 ){ |
| 35879 | 35916 | sqlite3_free(zOut); |
| 35880 | 35917 | return winLogError(SQLITE_CANTOPEN_CONVPATH, (DWORD)errno, |
| 35881 | 35918 | "winFullPathname1", zRelative); |
| 35919 | + }else{ |
| 35920 | + char *zUtf8 = winConvertToUtf8Filename(zOut); |
| 35921 | + if( !zUtf8 ){ |
| 35922 | + sqlite3_free(zOut); |
| 35923 | + return SQLITE_IOERR_NOMEM; |
| 35924 | + } |
| 35925 | + sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%c%s", |
| 35926 | + sqlite3_data_directory, winGetDirSep(), zUtf8); |
| 35927 | + sqlite3_free(zUtf8); |
| 35928 | + sqlite3_free(zOut); |
| 35882 | 35929 | } |
| 35883 | | - sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%c%s", |
| 35884 | | - sqlite3_data_directory, winGetDirSep(), zOut); |
| 35885 | | - sqlite3_free(zOut); |
| 35886 | 35930 | }else{ |
| 35887 | | - if( cygwin_conv_path(CCP_POSIX_TO_WIN_A, zRelative, zFull, nFull)<0 ){ |
| 35931 | + char *zOut = sqlite3MallocZero( pVfs->mxPathname+1 ); |
| 35932 | + if( !zOut ){ |
| 35933 | + return SQLITE_IOERR_NOMEM; |
| 35934 | + } |
| 35935 | + if( cygwin_conv_path( |
| 35936 | + (osIsNT() ? CCP_POSIX_TO_WIN_W : CCP_POSIX_TO_WIN_A), |
| 35937 | + zRelative, zOut, pVfs->mxPathname+1)<0 ){ |
| 35938 | + sqlite3_free(zOut); |
| 35888 | 35939 | return winLogError(SQLITE_CANTOPEN_CONVPATH, (DWORD)errno, |
| 35889 | 35940 | "winFullPathname2", zRelative); |
| 35941 | + }else{ |
| 35942 | + char *zUtf8 = winConvertToUtf8Filename(zOut); |
| 35943 | + if( !zUtf8 ){ |
| 35944 | + sqlite3_free(zOut); |
| 35945 | + return SQLITE_IOERR_NOMEM; |
| 35946 | + } |
| 35947 | + sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zUtf8); |
| 35948 | + sqlite3_free(zUtf8); |
| 35949 | + sqlite3_free(zOut); |
| 35890 | 35950 | } |
| 35891 | 35951 | } |
| 35892 | 35952 | return SQLITE_OK; |
| 35893 | 35953 | #endif |
| 35894 | 35954 | |
| | @@ -54478,11 +54538,11 @@ |
| 54478 | 54538 | assert( pCur!=0 && pCur->iPage>=0 && pCur->apPage[pCur->iPage]); |
| 54479 | 54539 | assert( pCur->eState==CURSOR_VALID ); |
| 54480 | 54540 | assert( cursorHoldsMutex(pCur) ); |
| 54481 | 54541 | pPage = pCur->apPage[pCur->iPage]; |
| 54482 | 54542 | assert( pCur->aiIdx[pCur->iPage]<pPage->nCell ); |
| 54483 | | - if( NEVER(pCur->info.nSize==0) ){ |
| 54543 | + if( pCur->info.nSize==0 ){ |
| 54484 | 54544 | btreeParseCell(pCur->apPage[pCur->iPage], pCur->aiIdx[pCur->iPage], |
| 54485 | 54545 | &pCur->info); |
| 54486 | 54546 | } |
| 54487 | 54547 | aPayload = pCur->info.pCell; |
| 54488 | 54548 | aPayload += pCur->info.nHeader; |
| | @@ -59842,19 +59902,12 @@ |
| 59842 | 59902 | p->xDel = 0; |
| 59843 | 59903 | } |
| 59844 | 59904 | |
| 59845 | 59905 | /* |
| 59846 | 59906 | ** Convert a 64-bit IEEE double into a 64-bit signed integer. |
| 59847 | | -** If the double is too large, return 0x8000000000000000. |
| 59848 | | -** |
| 59849 | | -** Most systems appear to do this simply by assigning |
| 59850 | | -** variables and without the extra range tests. But |
| 59851 | | -** there are reports that windows throws an expection |
| 59852 | | -** if the floating point value is out of range. (See ticket #2880.) |
| 59853 | | -** Because we do not completely understand the problem, we will |
| 59854 | | -** take the conservative approach and always do range tests |
| 59855 | | -** before attempting the conversion. |
| 59907 | +** If the double is out of range of a 64-bit signed integer then |
| 59908 | +** return the closest available 64-bit signed integer. |
| 59856 | 59909 | */ |
| 59857 | 59910 | static i64 doubleToInt64(double r){ |
| 59858 | 59911 | #ifdef SQLITE_OMIT_FLOATING_POINT |
| 59859 | 59912 | /* When floating-point is omitted, double and int64 are the same thing */ |
| 59860 | 59913 | return r; |
| | @@ -59867,18 +59920,14 @@ |
| 59867 | 59920 | ** larger than a 32-bit integer constant. |
| 59868 | 59921 | */ |
| 59869 | 59922 | static const i64 maxInt = LARGEST_INT64; |
| 59870 | 59923 | static const i64 minInt = SMALLEST_INT64; |
| 59871 | 59924 | |
| 59872 | | - if( r<(double)minInt ){ |
| 59873 | | - return minInt; |
| 59874 | | - }else if( r>(double)maxInt ){ |
| 59875 | | - /* minInt is correct here - not maxInt. It turns out that assigning |
| 59876 | | - ** a very large positive number to an integer results in a very large |
| 59877 | | - ** negative integer. This makes no sense, but it is what x86 hardware |
| 59878 | | - ** does so for compatibility we will do the same in software. */ |
| 59879 | | - return minInt; |
| 59925 | + if( r<=(double)minInt ){ |
| 59926 | + return minInt; |
| 59927 | + }else if( r>=(double)maxInt ){ |
| 59928 | + return maxInt; |
| 59880 | 59929 | }else{ |
| 59881 | 59930 | return (i64)r; |
| 59882 | 59931 | } |
| 59883 | 59932 | #endif |
| 59884 | 59933 | } |
| | @@ -59956,21 +60005,15 @@ |
| 59956 | 60005 | ** (2) The integer is neither the largest nor the smallest |
| 59957 | 60006 | ** possible integer (ticket #3922) |
| 59958 | 60007 | ** |
| 59959 | 60008 | ** The second and third terms in the following conditional enforces |
| 59960 | 60009 | ** the second condition under the assumption that addition overflow causes |
| 59961 | | - ** values to wrap around. On x86 hardware, the third term is always |
| 59962 | | - ** true and could be omitted. But we leave it in because other |
| 59963 | | - ** architectures might behave differently. |
| 60010 | + ** values to wrap around. |
| 59964 | 60011 | */ |
| 59965 | 60012 | if( pMem->r==(double)pMem->u.i |
| 59966 | 60013 | && pMem->u.i>SMALLEST_INT64 |
| 59967 | | -#if defined(__i486__) || defined(__x86_64__) |
| 59968 | | - && ALWAYS(pMem->u.i<LARGEST_INT64) |
| 59969 | | -#else |
| 59970 | 60014 | && pMem->u.i<LARGEST_INT64 |
| 59971 | | -#endif |
| 59972 | 60015 | ){ |
| 59973 | 60016 | pMem->flags |= MEM_Int; |
| 59974 | 60017 | } |
| 59975 | 60018 | } |
| 59976 | 60019 | |
| | @@ -64067,11 +64110,12 @@ |
| 64067 | 64110 | |
| 64068 | 64111 | idx1 = getVarint32(aKey1, szHdr1); |
| 64069 | 64112 | d1 = szHdr1; |
| 64070 | 64113 | assert( pKeyInfo->nField+pKeyInfo->nXField>=pPKey2->nField ); |
| 64071 | 64114 | assert( pKeyInfo->aSortOrder!=0 ); |
| 64072 | | - while( idx1<szHdr1 && i<pPKey2->nField ){ |
| 64115 | + assert( idx1<szHdr1 && i<pPKey2->nField ); |
| 64116 | + do{ |
| 64073 | 64117 | u32 serial_type1; |
| 64074 | 64118 | |
| 64075 | 64119 | /* Read the serial types for the next element in each key. */ |
| 64076 | 64120 | idx1 += getVarint32( aKey1+idx1, serial_type1 ); |
| 64077 | 64121 | |
| | @@ -64100,11 +64144,11 @@ |
| 64100 | 64144 | rc = -rc; /* Invert the result for DESC sort order. */ |
| 64101 | 64145 | } |
| 64102 | 64146 | return rc; |
| 64103 | 64147 | } |
| 64104 | 64148 | i++; |
| 64105 | | - } |
| 64149 | + }while( idx1<szHdr1 && i<pPKey2->nField ); |
| 64106 | 64150 | |
| 64107 | 64151 | /* No memory allocation is ever used on mem1. Prove this using |
| 64108 | 64152 | ** the following assert(). If the assert() fails, it indicates a |
| 64109 | 64153 | ** memory leak and a need to call sqlite3VdbeMemRelease(&mem1). |
| 64110 | 64154 | */ |
| | @@ -70040,40 +70084,32 @@ |
| 70040 | 70084 | /* If the P3 value cannot be converted into any kind of a number, |
| 70041 | 70085 | ** then the seek is not possible, so jump to P2 */ |
| 70042 | 70086 | pc = pOp->p2 - 1; |
| 70043 | 70087 | break; |
| 70044 | 70088 | } |
| 70045 | | - /* If we reach this point, then the P3 value must be a floating |
| 70046 | | - ** point number. */ |
| 70047 | | - assert( (pIn3->flags & MEM_Real)!=0 ); |
| 70048 | | - |
| 70049 | | - if( u.bd.iKey==SMALLEST_INT64 && (pIn3->r<(double)u.bd.iKey || pIn3->r>0) ){ |
| 70050 | | - /* The P3 value is too large in magnitude to be expressed as an |
| 70051 | | - ** integer. */ |
| 70052 | | - u.bd.res = 1; |
| 70053 | | - if( pIn3->r<0 ){ |
| 70054 | | - if( u.bd.oc>=OP_SeekGe ){ assert( u.bd.oc==OP_SeekGe || u.bd.oc==OP_SeekGt ); |
| 70055 | | - rc = sqlite3BtreeFirst(u.bd.pC->pCursor, &u.bd.res); |
| 70056 | | - if( rc!=SQLITE_OK ) goto abort_due_to_error; |
| 70057 | | - } |
| 70058 | | - }else{ |
| 70059 | | - if( u.bd.oc<=OP_SeekLe ){ assert( u.bd.oc==OP_SeekLt || u.bd.oc==OP_SeekLe ); |
| 70060 | | - rc = sqlite3BtreeLast(u.bd.pC->pCursor, &u.bd.res); |
| 70061 | | - if( rc!=SQLITE_OK ) goto abort_due_to_error; |
| 70062 | | - } |
| 70063 | | - } |
| 70064 | | - if( u.bd.res ){ |
| 70065 | | - pc = pOp->p2 - 1; |
| 70066 | | - } |
| 70067 | | - break; |
| 70068 | | - }else if( u.bd.oc==OP_SeekLt || u.bd.oc==OP_SeekGe ){ |
| 70069 | | - /* Use the ceiling() function to convert real->int */ |
| 70070 | | - if( pIn3->r > (double)u.bd.iKey ) u.bd.iKey++; |
| 70071 | | - }else{ |
| 70072 | | - /* Use the floor() function to convert real->int */ |
| 70073 | | - assert( u.bd.oc==OP_SeekLe || u.bd.oc==OP_SeekGt ); |
| 70074 | | - if( pIn3->r < (double)u.bd.iKey ) u.bd.iKey--; |
| 70089 | + |
| 70090 | + /* If the approximation u.bd.iKey is larger than the actual real search |
| 70091 | + ** term, substitute >= for > and < for <=. e.g. if the search term |
| 70092 | + ** is 4.9 and the integer approximation 5: |
| 70093 | + ** |
| 70094 | + ** (x > 4.9) -> (x >= 5) |
| 70095 | + ** (x <= 4.9) -> (x < 5) |
| 70096 | + */ |
| 70097 | + if( pIn3->r<(double)u.bd.iKey ){ |
| 70098 | + assert( OP_SeekGe==(OP_SeekGt-1) ); |
| 70099 | + assert( OP_SeekLt==(OP_SeekLe-1) ); |
| 70100 | + assert( (OP_SeekLe & 0x0001)==(OP_SeekGt & 0x0001) ); |
| 70101 | + if( (u.bd.oc & 0x0001)==(OP_SeekGt & 0x0001) ) u.bd.oc--; |
| 70102 | + } |
| 70103 | + |
| 70104 | + /* If the approximation u.bd.iKey is smaller than the actual real search |
| 70105 | + ** term, substitute <= for < and > for >=. */ |
| 70106 | + else if( pIn3->r>(double)u.bd.iKey ){ |
| 70107 | + assert( OP_SeekLe==(OP_SeekLt+1) ); |
| 70108 | + assert( OP_SeekGt==(OP_SeekGe+1) ); |
| 70109 | + assert( (OP_SeekLt & 0x0001)==(OP_SeekGe & 0x0001) ); |
| 70110 | + if( (u.bd.oc & 0x0001)==(OP_SeekLt & 0x0001) ) u.bd.oc++; |
| 70075 | 70111 | } |
| 70076 | 70112 | } |
| 70077 | 70113 | rc = sqlite3BtreeMovetoUnpacked(u.bd.pC->pCursor, 0, (u64)u.bd.iKey, 0, &u.bd.res); |
| 70078 | 70114 | if( rc!=SQLITE_OK ){ |
| 70079 | 70115 | goto abort_due_to_error; |
| | @@ -70659,24 +70695,15 @@ |
| 70659 | 70695 | #if 0 /* local variables moved into u.bj */ |
| 70660 | 70696 | i64 iKey; |
| 70661 | 70697 | VdbeCursor *pC; |
| 70662 | 70698 | #endif /* local variables moved into u.bj */ |
| 70663 | 70699 | |
| 70664 | | - u.bj.iKey = 0; |
| 70665 | 70700 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 70666 | 70701 | u.bj.pC = p->apCsr[pOp->p1]; |
| 70667 | 70702 | assert( u.bj.pC!=0 ); |
| 70668 | 70703 | assert( u.bj.pC->pCursor!=0 ); /* Only valid for real tables, no pseudotables */ |
| 70669 | | - |
| 70670 | | - /* If the update-hook will be invoked, set u.bj.iKey to the rowid of the |
| 70671 | | - ** row being deleted. |
| 70672 | | - */ |
| 70673 | | - if( db->xUpdateCallback && pOp->p4.z ){ |
| 70674 | | - assert( u.bj.pC->isTable ); |
| 70675 | | - assert( u.bj.pC->rowidIsValid ); /* lastRowid set by previous OP_NotFound */ |
| 70676 | | - u.bj.iKey = u.bj.pC->lastRowid; |
| 70677 | | - } |
| 70704 | + u.bj.iKey = u.bj.pC->lastRowid; /* Only used for the update hook */ |
| 70678 | 70705 | |
| 70679 | 70706 | /* The OP_Delete opcode always follows an OP_NotExists or OP_Last or |
| 70680 | 70707 | ** OP_Column on the same table without any intervening operations that |
| 70681 | 70708 | ** might move or invalidate the cursor. Hence cursor u.bj.pC is always pointing |
| 70682 | 70709 | ** to the row to be deleted and the sqlite3VdbeCursorMoveto() operation |
| | @@ -70690,11 +70717,11 @@ |
| 70690 | 70717 | sqlite3BtreeSetCachedRowid(u.bj.pC->pCursor, 0); |
| 70691 | 70718 | rc = sqlite3BtreeDelete(u.bj.pC->pCursor); |
| 70692 | 70719 | u.bj.pC->cacheStatus = CACHE_STALE; |
| 70693 | 70720 | |
| 70694 | 70721 | /* Invoke the update-hook if required. */ |
| 70695 | | - if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p4.z ){ |
| 70722 | + if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p4.z && u.bj.pC->isTable ){ |
| 70696 | 70723 | const char *zDb = db->aDb[u.bj.pC->iDb].zName; |
| 70697 | 70724 | const char *zTbl = pOp->p4.z; |
| 70698 | 70725 | db->xUpdateCallback(db->pUpdateArg, SQLITE_DELETE, zDb, zTbl, u.bj.iKey); |
| 70699 | 70726 | assert( u.bj.pC->iDb>=0 ); |
| 70700 | 70727 | } |
| | @@ -75464,11 +75491,13 @@ |
| 75464 | 75491 | } |
| 75465 | 75492 | break; |
| 75466 | 75493 | } |
| 75467 | 75494 | } |
| 75468 | 75495 | if( iCol>=pTab->nCol && sqlite3IsRowid(zCol) && HasRowid(pTab) ){ |
| 75469 | | - iCol = -1; /* IMP: R-44911-55124 */ |
| 75496 | + /* IMP: R-24309-18625 */ |
| 75497 | + /* IMP: R-44911-55124 */ |
| 75498 | + iCol = -1; |
| 75470 | 75499 | } |
| 75471 | 75500 | if( iCol<pTab->nCol ){ |
| 75472 | 75501 | cnt++; |
| 75473 | 75502 | if( iCol<0 ){ |
| 75474 | 75503 | pExpr->affinity = SQLITE_AFF_INTEGER; |
| | @@ -112290,16 +112319,18 @@ |
| 112290 | 112319 | pNew->rSetup = 0; |
| 112291 | 112320 | rLogSize = estLog(sqlite3LogEst(pProbe->aiRowEst[0])); |
| 112292 | 112321 | |
| 112293 | 112322 | /* Consider using a skip-scan if there are no WHERE clause constraints |
| 112294 | 112323 | ** available for the left-most terms of the index, and if the average |
| 112295 | | - ** number of repeats in the left-most terms is at least 50. |
| 112324 | + ** number of repeats in the left-most terms is at least 18. The magic |
| 112325 | + ** number 18 was found by experimentation to be the payoff point where |
| 112326 | + ** skip-scan become faster than a full-scan. |
| 112296 | 112327 | */ |
| 112297 | 112328 | if( pTerm==0 |
| 112298 | 112329 | && saved_nEq==saved_nSkip |
| 112299 | 112330 | && saved_nEq+1<pProbe->nKeyCol |
| 112300 | | - && pProbe->aiRowEst[saved_nEq+1]>50 /* TUNING: Minimum for skip-scan */ |
| 112331 | + && pProbe->aiRowEst[saved_nEq+1]>=18 /* TUNING: Minimum for skip-scan */ |
| 112301 | 112332 | ){ |
| 112302 | 112333 | LogEst nIter; |
| 112303 | 112334 | pNew->u.btree.nEq++; |
| 112304 | 112335 | pNew->u.btree.nSkip++; |
| 112305 | 112336 | pNew->aLTerm[pNew->nLTerm++] = 0; |
| | @@ -119466,10 +119497,17 @@ |
| 119466 | 119497 | if( szMmap<0 ) szMmap = SQLITE_DEFAULT_MMAP_SIZE; |
| 119467 | 119498 | if( szMmap>mxMmap) szMmap = mxMmap; |
| 119468 | 119499 | sqlite3GlobalConfig.szMmap = szMmap; |
| 119469 | 119500 | break; |
| 119470 | 119501 | } |
| 119502 | + |
| 119503 | +#if SQLITE_OS_WIN && defined(SQLITE_WIN32_MALLOC) |
| 119504 | + case SQLITE_CONFIG_WIN32_HEAPSIZE: { |
| 119505 | + sqlite3GlobalConfig.nHeap = va_arg(ap, int); |
| 119506 | + break; |
| 119507 | + } |
| 119508 | +#endif |
| 119471 | 119509 | |
| 119472 | 119510 | default: { |
| 119473 | 119511 | rc = SQLITE_ERROR; |
| 119474 | 119512 | break; |
| 119475 | 119513 | } |
| 119476 | 119514 | |