Index: SQLite.Interop/src/core/sqlite3.c
==================================================================
--- SQLite.Interop/src/core/sqlite3.c
+++ SQLite.Interop/src/core/sqlite3.c
@@ -135,11 +135,11 @@
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
#define SQLITE_VERSION "3.8.2"
#define SQLITE_VERSION_NUMBER 3008002
-#define SQLITE_SOURCE_ID "2013-11-22 21:32:44 f336c18fb72ab90e93640b12ac540d41accc7658"
+#define SQLITE_SOURCE_ID "2013-11-27 04:22:27 83c0bb9913838d18ba355033afde6e38b4690842"
/*
** CAPI3REF: Run-Time Library Version Numbers
** KEYWORDS: sqlite3_version, sqlite3_sourceid
**
@@ -1713,10 +1713,17 @@
** cannot be changed at run-time. Nor may the maximum allowed mmap size
** exceed the compile-time maximum mmap size set by the
** [SQLITE_MAX_MMAP_SIZE] compile-time option.)^
** ^If either argument to this option is negative, then that argument is
** changed to its compile-time default.
+**
+** [[SQLITE_CONFIG_WIN32_HEAPSIZE]]
+**
SQLITE_CONFIG_WIN32_HEAPSIZE
+** ^This option is only available if SQLite is compiled for Windows
+** with the [SQLITE_WIN32_MALLOC] pre-processor macro defined.
+** SQLITE_CONFIG_WIN32_HEAPSIZE takes a 32-bit unsigned integer value
+** that specifies the maximum size of the created heap.
**
*/
#define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */
#define SQLITE_CONFIG_MULTITHREAD 2 /* nil */
#define SQLITE_CONFIG_SERIALIZED 3 /* nil */
@@ -1737,10 +1744,11 @@
#define SQLITE_CONFIG_PCACHE2 18 /* sqlite3_pcache_methods2* */
#define SQLITE_CONFIG_GETPCACHE2 19 /* sqlite3_pcache_methods2* */
#define SQLITE_CONFIG_COVERING_INDEX_SCAN 20 /* int */
#define SQLITE_CONFIG_SQLLOG 21 /* xSqllog, void* */
#define SQLITE_CONFIG_MMAP_SIZE 22 /* sqlite3_int64, sqlite3_int64 */
+#define SQLITE_CONFIG_WIN32_HEAPSIZE 23 /* int nByte */
/*
** CAPI3REF: Database Connection Configuration Options
**
** These constants are the available integer configuration options that
@@ -17497,29 +17505,10 @@
iSize = mem5.szAtom * (1 << (mem5.aCtrl[i]&CTRL_LOGSIZE));
}
return iSize;
}
-/*
-** Find the first entry on the freelist iLogsize. Unlink that
-** entry and return its index.
-*/
-static int memsys5UnlinkFirst(int iLogsize){
- int i;
- int iFirst;
-
- assert( iLogsize>=0 && iLogsize<=LOGMAX );
- i = iFirst = mem5.aiFreelist[iLogsize];
- assert( iFirst>=0 );
- while( i>0 ){
- if( inext;
- }
- memsys5Unlink(iFirst, iLogsize);
- return iFirst;
-}
-
/*
** Return a block of memory of at least nBytes in size.
** Return NULL if unable. Return NULL if nBytes==0.
**
** The caller guarantees that nByte is positive.
@@ -17561,11 +17550,12 @@
if( iBin>LOGMAX ){
testcase( sqlite3GlobalConfig.xLog!=0 );
sqlite3_log(SQLITE_NOMEM, "failed to allocate %u bytes", nByte);
return 0;
}
- i = memsys5UnlinkFirst(iBin);
+ i = mem5.aiFreelist[iBin];
+ memsys5Unlink(i, iBin);
while( iBin>iLogsize ){
int newSize;
iBin--;
newSize = 1 << iBin;
@@ -21850,11 +21840,11 @@
while( zNum='0' && c<='9'; i+=incr){
u = u*10 + c - '0';
}
if( u>LARGEST_INT64 ){
- *pNum = SMALLEST_INT64;
+ *pNum = neg ? SMALLEST_INT64 : LARGEST_INT64;
}else if( neg ){
*pNum = -(i64)u;
}else{
*pNum = (i64)u;
}
@@ -21881,11 +21871,10 @@
return 1;
}else{
/* zNum is exactly 9223372036854775808. Fits if negative. The
** special case 2 overflow if positive */
assert( u-1==LARGEST_INT64 );
- assert( (*pNum)==SMALLEST_INT64 );
return neg ? 0 : 2;
}
}
}
@@ -31004,10 +30993,38 @@
#if !defined(SQLITE_WIN32_HAS_ANSI) && !defined(SQLITE_WIN32_HAS_WIDE)
# error "At least one of SQLITE_WIN32_HAS_ANSI and SQLITE_WIN32_HAS_WIDE\
must be defined."
#endif
+/*
+** Define the required Windows SDK version constants if they are not
+** already available.
+*/
+#ifndef NTDDI_WIN8
+# define NTDDI_WIN8 0x06020000
+#endif
+
+#ifndef NTDDI_WINBLUE
+# define NTDDI_WINBLUE 0x06030000
+#endif
+
+/*
+** Check if the GetVersionEx[AW] functions should be considered deprecated
+** and avoid using them in that case. It should be noted here that if the
+** value of the SQLITE_WIN32_GETVERSIONEX pre-processor macro is zero
+** (whether via this block or via being manually specified), that implies
+** the underlying operating system will always be based on the Windows NT
+** Kernel.
+*/
+#ifndef SQLITE_WIN32_GETVERSIONEX
+# if defined(NTDDI_VERSION) && NTDDI_VERSION >= NTDDI_WINBLUE
+# define SQLITE_WIN32_GETVERSIONEX 0
+# else
+# define SQLITE_WIN32_GETVERSIONEX 1
+# endif
+#endif
+
/*
** This constant should already be defined (in the "WinDef.h" SDK file).
*/
#ifndef MAX_PATH
# define MAX_PATH (260)
@@ -31639,20 +31656,22 @@
{ "GetTickCount", (SYSCALL)0, 0 },
#endif
#define osGetTickCount ((DWORD(WINAPI*)(VOID))aSyscall[33].pCurrent)
-#if defined(SQLITE_WIN32_HAS_ANSI)
+#if defined(SQLITE_WIN32_HAS_ANSI) && defined(SQLITE_WIN32_GETVERSIONEX) && \
+ SQLITE_WIN32_GETVERSIONEX
{ "GetVersionExA", (SYSCALL)GetVersionExA, 0 },
#else
{ "GetVersionExA", (SYSCALL)0, 0 },
#endif
#define osGetVersionExA ((BOOL(WINAPI*)( \
LPOSVERSIONINFOA))aSyscall[34].pCurrent)
-#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE)
+#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) && \
+ defined(SQLITE_WIN32_GETVERSIONEX) && SQLITE_WIN32_GETVERSIONEX
{ "GetVersionExW", (SYSCALL)GetVersionExW, 0 },
#else
{ "GetVersionExW", (SYSCALL)0, 0 },
#endif
@@ -32205,15 +32224,14 @@
** API as long as we don't call it when running Win95/98/ME. A call to
** this routine is used to determine if the host is Win95/98/ME or
** WinNT/2K/XP so that we will know whether or not we can safely call
** the LockFileEx() API.
*/
-#ifndef NTDDI_WIN8
-# define NTDDI_WIN8 0x06020000
-#endif
-#if SQLITE_OS_WINCE || SQLITE_OS_WINRT || !defined(SQLITE_WIN32_HAS_ANSI)
+#if !defined(SQLITE_WIN32_GETVERSIONEX) || !SQLITE_WIN32_GETVERSIONEX
+# define osIsNT() (1)
+#elif SQLITE_OS_WINCE || SQLITE_OS_WINRT || !defined(SQLITE_WIN32_HAS_ANSI)
# define osIsNT() (1)
#elif !defined(SQLITE_WIN32_HAS_WIDE)
# define osIsNT() (0)
#else
static int osIsNT(void){
@@ -32346,18 +32364,24 @@
assert( pWinMemData->magic1==WINMEM_MAGIC1 );
assert( pWinMemData->magic2==WINMEM_MAGIC2 );
#if !SQLITE_OS_WINRT && SQLITE_WIN32_HEAP_CREATE
if( !pWinMemData->hHeap ){
+ DWORD dwInitialSize = SQLITE_WIN32_HEAP_INIT_SIZE;
+ DWORD dwMaximumSize = (DWORD)sqlite3GlobalConfig.nHeap;
+ if( dwMaximumSize==0 ){
+ dwMaximumSize = SQLITE_WIN32_HEAP_MAX_SIZE;
+ }else if( dwInitialSize>dwMaximumSize ){
+ dwInitialSize = dwMaximumSize;
+ }
pWinMemData->hHeap = osHeapCreate(SQLITE_WIN32_HEAP_FLAGS,
- SQLITE_WIN32_HEAP_INIT_SIZE,
- SQLITE_WIN32_HEAP_MAX_SIZE);
+ dwInitialSize, dwMaximumSize);
if( !pWinMemData->hHeap ){
sqlite3_log(SQLITE_NOMEM,
- "failed to HeapCreate (%lu), flags=%u, initSize=%u, maxSize=%u",
- osGetLastError(), SQLITE_WIN32_HEAP_FLAGS,
- SQLITE_WIN32_HEAP_INIT_SIZE, SQLITE_WIN32_HEAP_MAX_SIZE);
+ "failed to HeapCreate (%lu), flags=%u, initSize=%lu, maxSize=%lu",
+ osGetLastError(), SQLITE_WIN32_HEAP_FLAGS, dwInitialSize,
+ dwMaximumSize);
return SQLITE_NOMEM;
}
pWinMemData->bOwned = TRUE;
assert( pWinMemData->bOwned );
}
@@ -35013,11 +35037,11 @@
**
** This division contains the implementation of methods on the
** sqlite3_vfs object.
*/
-#if 0
+#if defined(__CYGWIN__)
/*
** Convert a filename from whatever the underlying operating system
** supports for filenames into UTF-8. Space to hold the result is
** obtained from malloc and must be freed by the calling function.
*/
@@ -35189,27 +35213,21 @@
if( winIsDir(zConverted) ){
/* At this point, we know the candidate directory exists and should
** be used. However, we may need to convert the string containing
** its name into UTF-8 (i.e. if it is UTF-16 right now).
*/
- if( osIsNT() ){
- char *zUtf8 = winUnicodeToUtf8(zConverted);
- if( !zUtf8 ){
- sqlite3_free(zConverted);
- sqlite3_free(zBuf);
- OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
- return SQLITE_IOERR_NOMEM;
- }
- sqlite3_snprintf(nMax, zBuf, "%s", zUtf8);
- sqlite3_free(zUtf8);
- sqlite3_free(zConverted);
- break;
- }else{
- sqlite3_snprintf(nMax, zBuf, "%s", zConverted);
- sqlite3_free(zConverted);
- break;
- }
+ char *zUtf8 = winConvertToUtf8Filename(zConverted);
+ if( !zUtf8 ){
+ sqlite3_free(zConverted);
+ sqlite3_free(zBuf);
+ OSTRACE(("TEMP-FILENAME rc=SQLITE_IOERR_NOMEM\n"));
+ return SQLITE_IOERR_NOMEM;
+ }
+ sqlite3_snprintf(nMax, zBuf, "%s", zUtf8);
+ sqlite3_free(zUtf8);
+ sqlite3_free(zConverted);
+ break;
}
sqlite3_free(zConverted);
}
}
}
@@ -35890,23 +35908,47 @@
*/
char *zOut = sqlite3MallocZero( pVfs->mxPathname+1 );
if( !zOut ){
return SQLITE_IOERR_NOMEM;
}
- if( cygwin_conv_path(CCP_POSIX_TO_WIN_A|CCP_RELATIVE, zRelative, zOut,
- pVfs->mxPathname+1)<0 ){
+ if( cygwin_conv_path(
+ (osIsNT() ? CCP_POSIX_TO_WIN_W : CCP_POSIX_TO_WIN_A) |
+ CCP_RELATIVE, zRelative, zOut, pVfs->mxPathname+1)<0 ){
sqlite3_free(zOut);
return winLogError(SQLITE_CANTOPEN_CONVPATH, (DWORD)errno,
"winFullPathname1", zRelative);
+ }else{
+ char *zUtf8 = winConvertToUtf8Filename(zOut);
+ if( !zUtf8 ){
+ sqlite3_free(zOut);
+ return SQLITE_IOERR_NOMEM;
+ }
+ sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%c%s",
+ sqlite3_data_directory, winGetDirSep(), zUtf8);
+ sqlite3_free(zUtf8);
+ sqlite3_free(zOut);
}
- sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%c%s",
- sqlite3_data_directory, winGetDirSep(), zOut);
- sqlite3_free(zOut);
}else{
- if( cygwin_conv_path(CCP_POSIX_TO_WIN_A, zRelative, zFull, nFull)<0 ){
+ char *zOut = sqlite3MallocZero( pVfs->mxPathname+1 );
+ if( !zOut ){
+ return SQLITE_IOERR_NOMEM;
+ }
+ if( cygwin_conv_path(
+ (osIsNT() ? CCP_POSIX_TO_WIN_W : CCP_POSIX_TO_WIN_A),
+ zRelative, zOut, pVfs->mxPathname+1)<0 ){
+ sqlite3_free(zOut);
return winLogError(SQLITE_CANTOPEN_CONVPATH, (DWORD)errno,
"winFullPathname2", zRelative);
+ }else{
+ char *zUtf8 = winConvertToUtf8Filename(zOut);
+ if( !zUtf8 ){
+ sqlite3_free(zOut);
+ return SQLITE_IOERR_NOMEM;
+ }
+ sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s", zUtf8);
+ sqlite3_free(zUtf8);
+ sqlite3_free(zOut);
}
}
return SQLITE_OK;
#endif
@@ -54496,11 +54538,11 @@
assert( pCur!=0 && pCur->iPage>=0 && pCur->apPage[pCur->iPage]);
assert( pCur->eState==CURSOR_VALID );
assert( cursorHoldsMutex(pCur) );
pPage = pCur->apPage[pCur->iPage];
assert( pCur->aiIdx[pCur->iPage]nCell );
- if( NEVER(pCur->info.nSize==0) ){
+ if( pCur->info.nSize==0 ){
btreeParseCell(pCur->apPage[pCur->iPage], pCur->aiIdx[pCur->iPage],
&pCur->info);
}
aPayload = pCur->info.pCell;
aPayload += pCur->info.nHeader;
@@ -54924,14 +54966,14 @@
assert( pCur->pgnoRoot==0 || pCur->apPage[pCur->iPage]->nCell==0 );
return SQLITE_OK;
}
assert( pCur->apPage[0]->intKey || pIdxKey );
for(;;){
- int lwr, upr, idx;
+ int lwr, upr, idx, c;
Pgno chldPg;
MemPage *pPage = pCur->apPage[pCur->iPage];
- int c;
+ u8 *pCell; /* Pointer to current cell in pPage */
/* pPage->nCell must be greater than zero. If this is the root-page
** the cursor would have been INVALID above and this for(;;) loop
** not run. If this is not the root-page, then the moveToChild() routine
** would have already detected db corruption. Similarly, pPage must
@@ -54939,48 +54981,60 @@
** a moveToChild() or moveToRoot() call would have detected corruption. */
assert( pPage->nCell>0 );
assert( pPage->intKey==(pIdxKey==0) );
lwr = 0;
upr = pPage->nCell-1;
- if( biasRight ){
- pCur->aiIdx[pCur->iPage] = (u16)(idx = upr);
- }else{
- pCur->aiIdx[pCur->iPage] = (u16)(idx = (upr+lwr)/2);
- }
- for(;;){
- u8 *pCell; /* Pointer to current cell in pPage */
-
- assert( idx==pCur->aiIdx[pCur->iPage] );
- pCur->info.nSize = 0;
- pCell = findCell(pPage, idx) + pPage->childPtrSize;
- if( pPage->intKey ){
+ assert( biasRight==0 || biasRight==1 );
+ idx = upr>>(1-biasRight); /* idx = biasRight ? upr : (lwr+upr)/2; */
+ pCur->aiIdx[pCur->iPage] = (u16)idx;
+ if( pPage->intKey ){
+ for(;;){
i64 nCellKey;
+ pCell = findCell(pPage, idx) + pPage->childPtrSize;
if( pPage->hasData ){
- u32 dummy;
- pCell += getVarint32(pCell, dummy);
+ while( 0x80 <= *(pCell++) ){
+ if( pCell>=pPage->aDataEnd ) return SQLITE_CORRUPT_BKPT;
+ }
}
getVarint(pCell, (u64*)&nCellKey);
- if( nCellKey==intKey ){
- c = 0;
- }else if( nCellKeyintKey );
- c = +1;
- }
- pCur->validNKey = 1;
- pCur->info.nKey = nCellKey;
- }else{
+ if( nCellKeyupr ){ c = -1; break; }
+ }else if( nCellKey>intKey ){
+ upr = idx-1;
+ if( lwr>upr ){ c = +1; break; }
+ }else{
+ assert( nCellKey==intKey );
+ pCur->validNKey = 1;
+ pCur->info.nKey = nCellKey;
+ pCur->aiIdx[pCur->iPage] = (u16)idx;
+ if( !pPage->leaf ){
+ lwr = idx;
+ goto moveto_next_layer;
+ }else{
+ *pRes = 0;
+ rc = SQLITE_OK;
+ goto moveto_finish;
+ }
+ }
+ assert( lwr+upr>=0 );
+ idx = (lwr+upr)>>1; /* idx = (lwr+upr)/2; */
+ }
+ }else{
+ for(;;){
+ int nCell;
+ pCell = findCell(pPage, idx) + pPage->childPtrSize;
+
/* The maximum supported page-size is 65536 bytes. This means that
** the maximum number of record bytes stored on an index B-Tree
** page is less than 16384 bytes and may be stored as a 2-byte
** varint. This information is used to attempt to avoid parsing
** the entire cell by checking for the cases where the record is
** stored entirely within the b-tree page by inspecting the first
** 2 bytes of the cell.
*/
- int nCell = pCell[0];
+ nCell = pCell[0];
if( nCell<=pPage->max1bytePayload
/* && (pCell+nCell)aDataEnd */
){
/* This branch runs if the record-size field of the cell is a
** single byte varint and the record fits entirely on the main
@@ -55007,61 +55061,57 @@
pCellKey = sqlite3Malloc( nCell );
if( pCellKey==0 ){
rc = SQLITE_NOMEM;
goto moveto_finish;
}
+ pCur->aiIdx[pCur->iPage] = (u16)idx;
rc = accessPayload(pCur, 0, nCell, (unsigned char*)pCellKey, 0);
if( rc ){
sqlite3_free(pCellKey);
goto moveto_finish;
}
c = sqlite3VdbeRecordCompare(nCell, pCellKey, pIdxKey);
sqlite3_free(pCellKey);
}
- }
- if( c==0 ){
- if( pPage->intKey && !pPage->leaf ){
- lwr = idx;
- break;
+ if( c<0 ){
+ lwr = idx+1;
+ }else if( c>0 ){
+ upr = idx-1;
}else{
+ assert( c==0 );
*pRes = 0;
rc = SQLITE_OK;
+ pCur->aiIdx[pCur->iPage] = (u16)idx;
goto moveto_finish;
}
- }
- if( c<0 ){
- lwr = idx+1;
- }else{
- upr = idx-1;
- }
- if( lwr>upr ){
- break;
- }
- pCur->aiIdx[pCur->iPage] = (u16)(idx = (lwr+upr)/2);
+ if( lwr>upr ) break;
+ assert( lwr+upr>=0 );
+ idx = (lwr+upr)>>1; /* idx = (lwr+upr)/2 */
+ }
}
assert( lwr==upr+1 || (pPage->intKey && !pPage->leaf) );
assert( pPage->isInit );
if( pPage->leaf ){
- chldPg = 0;
- }else if( lwr>=pPage->nCell ){
- chldPg = get4byte(&pPage->aData[pPage->hdrOffset+8]);
- }else{
- chldPg = get4byte(findCell(pPage, lwr));
- }
- if( chldPg==0 ){
assert( pCur->aiIdx[pCur->iPage]apPage[pCur->iPage]->nCell );
+ pCur->aiIdx[pCur->iPage] = (u16)idx;
*pRes = c;
rc = SQLITE_OK;
goto moveto_finish;
}
+moveto_next_layer:
+ if( lwr>=pPage->nCell ){
+ chldPg = get4byte(&pPage->aData[pPage->hdrOffset+8]);
+ }else{
+ chldPg = get4byte(findCell(pPage, lwr));
+ }
pCur->aiIdx[pCur->iPage] = (u16)lwr;
- pCur->info.nSize = 0;
- pCur->validNKey = 0;
rc = moveToChild(pCur, chldPg);
- if( rc ) goto moveto_finish;
+ if( rc ) break;
}
moveto_finish:
+ pCur->info.nSize = 0;
+ pCur->validNKey = 0;
return rc;
}
/*
@@ -59852,19 +59902,12 @@
p->xDel = 0;
}
/*
** Convert a 64-bit IEEE double into a 64-bit signed integer.
-** If the double is too large, return 0x8000000000000000.
-**
-** Most systems appear to do this simply by assigning
-** variables and without the extra range tests. But
-** there are reports that windows throws an expection
-** if the floating point value is out of range. (See ticket #2880.)
-** Because we do not completely understand the problem, we will
-** take the conservative approach and always do range tests
-** before attempting the conversion.
+** If the double is out of range of a 64-bit signed integer then
+** return the closest available 64-bit signed integer.
*/
static i64 doubleToInt64(double r){
#ifdef SQLITE_OMIT_FLOATING_POINT
/* When floating-point is omitted, double and int64 are the same thing */
return r;
@@ -59877,18 +59920,14 @@
** larger than a 32-bit integer constant.
*/
static const i64 maxInt = LARGEST_INT64;
static const i64 minInt = SMALLEST_INT64;
- if( r<(double)minInt ){
- return minInt;
- }else if( r>(double)maxInt ){
- /* minInt is correct here - not maxInt. It turns out that assigning
- ** a very large positive number to an integer results in a very large
- ** negative integer. This makes no sense, but it is what x86 hardware
- ** does so for compatibility we will do the same in software. */
- return minInt;
+ if( r<=(double)minInt ){
+ return minInt;
+ }else if( r>=(double)maxInt ){
+ return maxInt;
}else{
return (i64)r;
}
#endif
}
@@ -59966,21 +60005,15 @@
** (2) The integer is neither the largest nor the smallest
** possible integer (ticket #3922)
**
** The second and third terms in the following conditional enforces
** the second condition under the assumption that addition overflow causes
- ** values to wrap around. On x86 hardware, the third term is always
- ** true and could be omitted. But we leave it in because other
- ** architectures might behave differently.
+ ** values to wrap around.
*/
if( pMem->r==(double)pMem->u.i
&& pMem->u.i>SMALLEST_INT64
-#if defined(__i486__) || defined(__x86_64__)
- && ALWAYS(pMem->u.iu.iflags |= MEM_Int;
}
}
@@ -64077,11 +64110,12 @@
idx1 = getVarint32(aKey1, szHdr1);
d1 = szHdr1;
assert( pKeyInfo->nField+pKeyInfo->nXField>=pPKey2->nField );
assert( pKeyInfo->aSortOrder!=0 );
- while( idx1nField ){
+ assert( idx1nField );
+ do{
u32 serial_type1;
/* Read the serial types for the next element in each key. */
idx1 += getVarint32( aKey1+idx1, serial_type1 );
@@ -64110,11 +64144,11 @@
rc = -rc; /* Invert the result for DESC sort order. */
}
return rc;
}
i++;
- }
+ }while( idx1nField );
/* No memory allocation is ever used on mem1. Prove this using
** the following assert(). If the assert() fails, it indicates a
** memory leak and a need to call sqlite3VdbeMemRelease(&mem1).
*/
@@ -70050,40 +70084,32 @@
/* If the P3 value cannot be converted into any kind of a number,
** then the seek is not possible, so jump to P2 */
pc = pOp->p2 - 1;
break;
}
- /* If we reach this point, then the P3 value must be a floating
- ** point number. */
- assert( (pIn3->flags & MEM_Real)!=0 );
-
- if( u.bd.iKey==SMALLEST_INT64 && (pIn3->r<(double)u.bd.iKey || pIn3->r>0) ){
- /* The P3 value is too large in magnitude to be expressed as an
- ** integer. */
- u.bd.res = 1;
- if( pIn3->r<0 ){
- if( u.bd.oc>=OP_SeekGe ){ assert( u.bd.oc==OP_SeekGe || u.bd.oc==OP_SeekGt );
- rc = sqlite3BtreeFirst(u.bd.pC->pCursor, &u.bd.res);
- if( rc!=SQLITE_OK ) goto abort_due_to_error;
- }
- }else{
- if( u.bd.oc<=OP_SeekLe ){ assert( u.bd.oc==OP_SeekLt || u.bd.oc==OP_SeekLe );
- rc = sqlite3BtreeLast(u.bd.pC->pCursor, &u.bd.res);
- if( rc!=SQLITE_OK ) goto abort_due_to_error;
- }
- }
- if( u.bd.res ){
- pc = pOp->p2 - 1;
- }
- break;
- }else if( u.bd.oc==OP_SeekLt || u.bd.oc==OP_SeekGe ){
- /* Use the ceiling() function to convert real->int */
- if( pIn3->r > (double)u.bd.iKey ) u.bd.iKey++;
- }else{
- /* Use the floor() function to convert real->int */
- assert( u.bd.oc==OP_SeekLe || u.bd.oc==OP_SeekGt );
- if( pIn3->r < (double)u.bd.iKey ) u.bd.iKey--;
+
+ /* If the approximation u.bd.iKey is larger than the actual real search
+ ** term, substitute >= for > and < for <=. e.g. if the search term
+ ** is 4.9 and the integer approximation 5:
+ **
+ ** (x > 4.9) -> (x >= 5)
+ ** (x <= 4.9) -> (x < 5)
+ */
+ if( pIn3->r<(double)u.bd.iKey ){
+ assert( OP_SeekGe==(OP_SeekGt-1) );
+ assert( OP_SeekLt==(OP_SeekLe-1) );
+ assert( (OP_SeekLe & 0x0001)==(OP_SeekGt & 0x0001) );
+ if( (u.bd.oc & 0x0001)==(OP_SeekGt & 0x0001) ) u.bd.oc--;
+ }
+
+ /* If the approximation u.bd.iKey is smaller than the actual real search
+ ** term, substitute <= for < and > for >=. */
+ else if( pIn3->r>(double)u.bd.iKey ){
+ assert( OP_SeekLe==(OP_SeekLt+1) );
+ assert( OP_SeekGt==(OP_SeekGe+1) );
+ assert( (OP_SeekLt & 0x0001)==(OP_SeekGe & 0x0001) );
+ if( (u.bd.oc & 0x0001)==(OP_SeekLt & 0x0001) ) u.bd.oc++;
}
}
rc = sqlite3BtreeMovetoUnpacked(u.bd.pC->pCursor, 0, (u64)u.bd.iKey, 0, &u.bd.res);
if( rc!=SQLITE_OK ){
goto abort_due_to_error;
@@ -70625,11 +70651,11 @@
u.bi.nZero = 0;
}
sqlite3BtreeSetCachedRowid(u.bi.pC->pCursor, 0);
rc = sqlite3BtreeInsert(u.bi.pC->pCursor, 0, u.bi.iKey,
u.bi.pData->z, u.bi.pData->n, u.bi.nZero,
- pOp->p5 & OPFLAG_APPEND, u.bi.seekResult
+ (pOp->p5 & OPFLAG_APPEND)!=0, u.bi.seekResult
);
u.bi.pC->rowidIsValid = 0;
u.bi.pC->deferredMoveto = 0;
u.bi.pC->cacheStatus = CACHE_STALE;
@@ -70669,24 +70695,15 @@
#if 0 /* local variables moved into u.bj */
i64 iKey;
VdbeCursor *pC;
#endif /* local variables moved into u.bj */
- u.bj.iKey = 0;
assert( pOp->p1>=0 && pOp->p1nCursor );
u.bj.pC = p->apCsr[pOp->p1];
assert( u.bj.pC!=0 );
assert( u.bj.pC->pCursor!=0 ); /* Only valid for real tables, no pseudotables */
-
- /* If the update-hook will be invoked, set u.bj.iKey to the rowid of the
- ** row being deleted.
- */
- if( db->xUpdateCallback && pOp->p4.z ){
- assert( u.bj.pC->isTable );
- assert( u.bj.pC->rowidIsValid ); /* lastRowid set by previous OP_NotFound */
- u.bj.iKey = u.bj.pC->lastRowid;
- }
+ u.bj.iKey = u.bj.pC->lastRowid; /* Only used for the update hook */
/* The OP_Delete opcode always follows an OP_NotExists or OP_Last or
** OP_Column on the same table without any intervening operations that
** might move or invalidate the cursor. Hence cursor u.bj.pC is always pointing
** to the row to be deleted and the sqlite3VdbeCursorMoveto() operation
@@ -70700,11 +70717,11 @@
sqlite3BtreeSetCachedRowid(u.bj.pC->pCursor, 0);
rc = sqlite3BtreeDelete(u.bj.pC->pCursor);
u.bj.pC->cacheStatus = CACHE_STALE;
/* Invoke the update-hook if required. */
- if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p4.z ){
+ if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p4.z && u.bj.pC->isTable ){
const char *zDb = db->aDb[u.bj.pC->iDb].zName;
const char *zTbl = pOp->p4.z;
db->xUpdateCallback(db->pUpdateArg, SQLITE_DELETE, zDb, zTbl, u.bj.iKey);
assert( u.bj.pC->iDb>=0 );
}
@@ -75474,11 +75491,13 @@
}
break;
}
}
if( iCol>=pTab->nCol && sqlite3IsRowid(zCol) && HasRowid(pTab) ){
- iCol = -1; /* IMP: R-44911-55124 */
+ /* IMP: R-24309-18625 */
+ /* IMP: R-44911-55124 */
+ iCol = -1;
}
if( iColnCol ){
cnt++;
if( iCol<0 ){
pExpr->affinity = SQLITE_AFF_INTEGER;
@@ -112300,16 +112319,18 @@
pNew->rSetup = 0;
rLogSize = estLog(sqlite3LogEst(pProbe->aiRowEst[0]));
/* Consider using a skip-scan if there are no WHERE clause constraints
** available for the left-most terms of the index, and if the average
- ** number of repeats in the left-most terms is at least 50.
+ ** number of repeats in the left-most terms is at least 18. The magic
+ ** number 18 was found by experimentation to be the payoff point where
+ ** skip-scan become faster than a full-scan.
*/
if( pTerm==0
&& saved_nEq==saved_nSkip
&& saved_nEq+1nKeyCol
- && pProbe->aiRowEst[saved_nEq+1]>50 /* TUNING: Minimum for skip-scan */
+ && pProbe->aiRowEst[saved_nEq+1]>=18 /* TUNING: Minimum for skip-scan */
){
LogEst nIter;
pNew->u.btree.nEq++;
pNew->u.btree.nSkip++;
pNew->aLTerm[pNew->nLTerm++] = 0;
@@ -119476,10 +119497,17 @@
if( szMmap<0 ) szMmap = SQLITE_DEFAULT_MMAP_SIZE;
if( szMmap>mxMmap) szMmap = mxMmap;
sqlite3GlobalConfig.szMmap = szMmap;
break;
}
+
+#if SQLITE_OS_WIN && defined(SQLITE_WIN32_MALLOC)
+ case SQLITE_CONFIG_WIN32_HEAPSIZE: {
+ sqlite3GlobalConfig.nHeap = va_arg(ap, int);
+ break;
+ }
+#endif
default: {
rc = SQLITE_ERROR;
break;
}
Index: SQLite.Interop/src/core/sqlite3.h
==================================================================
--- SQLite.Interop/src/core/sqlite3.h
+++ SQLite.Interop/src/core/sqlite3.h
@@ -107,11 +107,11 @@
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
#define SQLITE_VERSION "3.8.2"
#define SQLITE_VERSION_NUMBER 3008002
-#define SQLITE_SOURCE_ID "2013-11-22 21:32:44 f336c18fb72ab90e93640b12ac540d41accc7658"
+#define SQLITE_SOURCE_ID "2013-11-27 04:22:27 83c0bb9913838d18ba355033afde6e38b4690842"
/*
** CAPI3REF: Run-Time Library Version Numbers
** KEYWORDS: sqlite3_version, sqlite3_sourceid
**
@@ -1685,10 +1685,17 @@
** cannot be changed at run-time. Nor may the maximum allowed mmap size
** exceed the compile-time maximum mmap size set by the
** [SQLITE_MAX_MMAP_SIZE] compile-time option.)^
** ^If either argument to this option is negative, then that argument is
** changed to its compile-time default.
+**
+** [[SQLITE_CONFIG_WIN32_HEAPSIZE]]
+** SQLITE_CONFIG_WIN32_HEAPSIZE
+** ^This option is only available if SQLite is compiled for Windows
+** with the [SQLITE_WIN32_MALLOC] pre-processor macro defined.
+** SQLITE_CONFIG_WIN32_HEAPSIZE takes a 32-bit unsigned integer value
+** that specifies the maximum size of the created heap.
**
*/
#define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */
#define SQLITE_CONFIG_MULTITHREAD 2 /* nil */
#define SQLITE_CONFIG_SERIALIZED 3 /* nil */
@@ -1709,10 +1716,11 @@
#define SQLITE_CONFIG_PCACHE2 18 /* sqlite3_pcache_methods2* */
#define SQLITE_CONFIG_GETPCACHE2 19 /* sqlite3_pcache_methods2* */
#define SQLITE_CONFIG_COVERING_INDEX_SCAN 20 /* int */
#define SQLITE_CONFIG_SQLLOG 21 /* xSqllog, void* */
#define SQLITE_CONFIG_MMAP_SIZE 22 /* sqlite3_int64, sqlite3_int64 */
+#define SQLITE_CONFIG_WIN32_HEAPSIZE 23 /* int nByte */
/*
** CAPI3REF: Database Connection Configuration Options
**
** These constants are the available integer configuration options that
Index: SQLite.Interop/src/win/interop.h
==================================================================
--- SQLite.Interop/src/win/interop.h
+++ SQLite.Interop/src/win/interop.h
@@ -8,11 +8,11 @@
#ifndef INTEROP_VERSION
#define INTEROP_VERSION "1.0.90.0"
#endif
#ifndef INTEROP_SOURCE_ID
-#define INTEROP_SOURCE_ID "07ecc4ebfa97eddd155df718c73523746b853a0d"
+#define INTEROP_SOURCE_ID "0000000000000000000000000000000000000000"
#endif
#ifndef INTEROP_SOURCE_TIMESTAMP
-#define INTEROP_SOURCE_TIMESTAMP "2013-11-27 02:15:17 UTC"
+#define INTEROP_SOURCE_TIMESTAMP "0000-00-00 00:00:00 UTC"
#endif
Index: System.Data.SQLite/SQLitePatchLevel.cs
==================================================================
--- System.Data.SQLite/SQLitePatchLevel.cs
+++ System.Data.SQLite/SQLitePatchLevel.cs
@@ -7,10 +7,10 @@
using System.Data.SQLite;
///////////////////////////////////////////////////////////////////////////////
-[assembly: AssemblySourceId("07ecc4ebfa97eddd155df718c73523746b853a0d")]
+[assembly: AssemblySourceId("0000000000000000000000000000000000000000")]
///////////////////////////////////////////////////////////////////////////////
-[assembly: AssemblySourceTimeStamp("2013-11-27 02:15:17 UTC")]
+[assembly: AssemblySourceTimeStamp("0000-00-00 00:00:00 UTC")]