Fossil SCM
Update the built-in SQLite to the latest 3.7.14 beta. Fossil does not need this upgrade - the purpose is to test SQLite.
Commit
1f4af61f41449c63f10ffef67e4cb833d772507c
Parent
65870e8736f65fb…
2 files changed
+469
-266
+5
-5
+469
-266
| --- src/sqlite3.c | ||
| +++ src/sqlite3.c | ||
| @@ -673,11 +673,11 @@ | ||
| 673 | 673 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 674 | 674 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 675 | 675 | */ |
| 676 | 676 | #define SQLITE_VERSION "3.7.14" |
| 677 | 677 | #define SQLITE_VERSION_NUMBER 3007014 |
| 678 | -#define SQLITE_SOURCE_ID "2012-06-21 17:21:52 d5e6880279210ca63e2d5e7f6d009f30566f1242" | |
| 678 | +#define SQLITE_SOURCE_ID "2012-08-14 17:29:27 6954fef006431d153de6e63e362b8d260ebeb1c6" | |
| 679 | 679 | |
| 680 | 680 | /* |
| 681 | 681 | ** CAPI3REF: Run-Time Library Version Numbers |
| 682 | 682 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 683 | 683 | ** |
| @@ -4721,15 +4721,15 @@ | ||
| 4721 | 4721 | ** ^The sqlite3_result_error_code() function changes the error code |
| 4722 | 4722 | ** returned by SQLite as a result of an error in a function. ^By default, |
| 4723 | 4723 | ** the error code is SQLITE_ERROR. ^A subsequent call to sqlite3_result_error() |
| 4724 | 4724 | ** or sqlite3_result_error16() resets the error code to SQLITE_ERROR. |
| 4725 | 4725 | ** |
| 4726 | -** ^The sqlite3_result_toobig() interface causes SQLite to throw an error | |
| 4727 | -** indicating that a string or BLOB is too long to represent. | |
| 4726 | +** ^The sqlite3_result_error_toobig() interface causes SQLite to throw an | |
| 4727 | +** error indicating that a string or BLOB is too long to represent. | |
| 4728 | 4728 | ** |
| 4729 | -** ^The sqlite3_result_nomem() interface causes SQLite to throw an error | |
| 4730 | -** indicating that a memory allocation failed. | |
| 4729 | +** ^The sqlite3_result_error_nomem() interface causes SQLite to throw an | |
| 4730 | +** error indicating that a memory allocation failed. | |
| 4731 | 4731 | ** |
| 4732 | 4732 | ** ^The sqlite3_result_int() interface sets the return value |
| 4733 | 4733 | ** of the application-defined function to be the 32-bit signed integer |
| 4734 | 4734 | ** value given in the 2nd argument. |
| 4735 | 4735 | ** ^The sqlite3_result_int64() interface sets the return value |
| @@ -8397,10 +8397,16 @@ | ||
| 8397 | 8397 | #define BTREE_LARGEST_ROOT_PAGE 4 |
| 8398 | 8398 | #define BTREE_TEXT_ENCODING 5 |
| 8399 | 8399 | #define BTREE_USER_VERSION 6 |
| 8400 | 8400 | #define BTREE_INCR_VACUUM 7 |
| 8401 | 8401 | |
| 8402 | +/* | |
| 8403 | +** Values that may be OR'd together to form the second argument of an | |
| 8404 | +** sqlite3BtreeCursorHints() call. | |
| 8405 | +*/ | |
| 8406 | +#define BTREE_BULKLOAD 0x00000001 | |
| 8407 | + | |
| 8402 | 8408 | SQLITE_PRIVATE int sqlite3BtreeCursor( |
| 8403 | 8409 | Btree*, /* BTree containing table to open */ |
| 8404 | 8410 | int iTable, /* Index of root page */ |
| 8405 | 8411 | int wrFlag, /* 1 for writing. 0 for read-only */ |
| 8406 | 8412 | struct KeyInfo*, /* First argument to compare function */ |
| @@ -8440,12 +8446,12 @@ | ||
| 8440 | 8446 | SQLITE_PRIVATE struct Pager *sqlite3BtreePager(Btree*); |
| 8441 | 8447 | |
| 8442 | 8448 | SQLITE_PRIVATE int sqlite3BtreePutData(BtCursor*, u32 offset, u32 amt, void*); |
| 8443 | 8449 | SQLITE_PRIVATE void sqlite3BtreeCacheOverflow(BtCursor *); |
| 8444 | 8450 | SQLITE_PRIVATE void sqlite3BtreeClearCursor(BtCursor *); |
| 8445 | - | |
| 8446 | 8451 | SQLITE_PRIVATE int sqlite3BtreeSetVersion(Btree *pBt, int iVersion); |
| 8452 | +SQLITE_PRIVATE void sqlite3BtreeCursorHints(BtCursor *, unsigned int mask); | |
| 8447 | 8453 | |
| 8448 | 8454 | #ifndef NDEBUG |
| 8449 | 8455 | SQLITE_PRIVATE int sqlite3BtreeCursorIsValid(BtCursor*); |
| 8450 | 8456 | #endif |
| 8451 | 8457 | |
| @@ -9384,12 +9390,12 @@ | ||
| 9384 | 9390 | #else |
| 9385 | 9391 | # define SQLITE_OS_WINCE 0 |
| 9386 | 9392 | #endif |
| 9387 | 9393 | |
| 9388 | 9394 | /* |
| 9389 | -** Determine if we are dealing with WindowsRT (Metro) as this has a different and | |
| 9390 | -** incompatible API from win32. | |
| 9395 | +** Determine if we are dealing with WinRT, which provides only a subset of | |
| 9396 | +** the full Win32 API. | |
| 9391 | 9397 | */ |
| 9392 | 9398 | #if !defined(SQLITE_OS_WINRT) |
| 9393 | 9399 | # define SQLITE_OS_WINRT 0 |
| 9394 | 9400 | #endif |
| 9395 | 9401 | |
| @@ -11085,14 +11091,14 @@ | ||
| 11085 | 11091 | ** comments above sqlite3Select() for details. |
| 11086 | 11092 | */ |
| 11087 | 11093 | typedef struct SelectDest SelectDest; |
| 11088 | 11094 | struct SelectDest { |
| 11089 | 11095 | u8 eDest; /* How to dispose of the results */ |
| 11090 | - u8 affinity; /* Affinity used when eDest==SRT_Set */ | |
| 11091 | - int iParm; /* A parameter used by the eDest disposal method */ | |
| 11092 | - int iMem; /* Base register where results are written */ | |
| 11093 | - int nMem; /* Number of registers allocated */ | |
| 11096 | + u8 affSdst; /* Affinity used when eDest==SRT_Set */ | |
| 11097 | + int iSDParm; /* A parameter used by the eDest disposal method */ | |
| 11098 | + int iSdst; /* Base register where results are written */ | |
| 11099 | + int nSdst; /* Number of registers allocated */ | |
| 11094 | 11100 | }; |
| 11095 | 11101 | |
| 11096 | 11102 | /* |
| 11097 | 11103 | ** During code generation of statements that do inserts into AUTOINCREMENT |
| 11098 | 11104 | ** tables, the following information is attached to the Table.u.autoInc.p |
| @@ -11284,10 +11290,12 @@ | ||
| 11284 | 11290 | #define OPFLAG_APPEND 0x08 /* This is likely to be an append */ |
| 11285 | 11291 | #define OPFLAG_USESEEKRESULT 0x10 /* Try to avoid a seek in BtreeInsert() */ |
| 11286 | 11292 | #define OPFLAG_CLEARCACHE 0x20 /* Clear pseudo-table cache in OP_Column */ |
| 11287 | 11293 | #define OPFLAG_LENGTHARG 0x40 /* OP_Column only used for length() */ |
| 11288 | 11294 | #define OPFLAG_TYPEOFARG 0x80 /* OP_Column only used for typeof() */ |
| 11295 | +#define OPFLAG_BULKCSR 0x01 /* OP_Open** used to open bulk cursor */ | |
| 11296 | +#define OPFLAG_P2ISREG 0x02 /* P2 to OP_Open** is a register number */ | |
| 11289 | 11297 | |
| 11290 | 11298 | /* |
| 11291 | 11299 | * Each trigger present in the database schema is stored as an instance of |
| 11292 | 11300 | * struct Trigger. |
| 11293 | 11301 | * |
| @@ -13354,15 +13362,15 @@ | ||
| 13354 | 13362 | # define sqlite3VdbeSorterNext(X,Y,Z) SQLITE_OK |
| 13355 | 13363 | # define sqlite3VdbeSorterCompare(X,Y,Z) SQLITE_OK |
| 13356 | 13364 | #else |
| 13357 | 13365 | SQLITE_PRIVATE int sqlite3VdbeSorterInit(sqlite3 *, VdbeCursor *); |
| 13358 | 13366 | SQLITE_PRIVATE void sqlite3VdbeSorterClose(sqlite3 *, VdbeCursor *); |
| 13359 | -SQLITE_PRIVATE int sqlite3VdbeSorterRowkey(VdbeCursor *, Mem *); | |
| 13360 | -SQLITE_PRIVATE int sqlite3VdbeSorterNext(sqlite3 *, VdbeCursor *, int *); | |
| 13361 | -SQLITE_PRIVATE int sqlite3VdbeSorterRewind(sqlite3 *, VdbeCursor *, int *); | |
| 13362 | -SQLITE_PRIVATE int sqlite3VdbeSorterWrite(sqlite3 *, VdbeCursor *, Mem *); | |
| 13363 | -SQLITE_PRIVATE int sqlite3VdbeSorterCompare(VdbeCursor *, Mem *, int *); | |
| 13367 | +SQLITE_PRIVATE int sqlite3VdbeSorterRowkey(const VdbeCursor *, Mem *); | |
| 13368 | +SQLITE_PRIVATE int sqlite3VdbeSorterNext(sqlite3 *, const VdbeCursor *, int *); | |
| 13369 | +SQLITE_PRIVATE int sqlite3VdbeSorterRewind(sqlite3 *, const VdbeCursor *, int *); | |
| 13370 | +SQLITE_PRIVATE int sqlite3VdbeSorterWrite(sqlite3 *, const VdbeCursor *, Mem *); | |
| 13371 | +SQLITE_PRIVATE int sqlite3VdbeSorterCompare(const VdbeCursor *, Mem *, int *); | |
| 13364 | 13372 | #endif |
| 13365 | 13373 | |
| 13366 | 13374 | #if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE>0 |
| 13367 | 13375 | SQLITE_PRIVATE void sqlite3VdbeEnter(Vdbe*); |
| 13368 | 13376 | SQLITE_PRIVATE void sqlite3VdbeLeave(Vdbe*); |
| @@ -22185,11 +22193,15 @@ | ||
| 22185 | 22193 | if( new_size==pH->htsize ) return 0; |
| 22186 | 22194 | #endif |
| 22187 | 22195 | |
| 22188 | 22196 | /* The inability to allocates space for a larger hash table is |
| 22189 | 22197 | ** a performance hit but it is not a fatal error. So mark the |
| 22190 | - ** allocation as a benign. | |
| 22198 | + ** allocation as a benign. Use sqlite3Malloc()/memset(0) instead of | |
| 22199 | + ** sqlite3MallocZero() to make the allocation, as sqlite3MallocZero() | |
| 22200 | + ** only zeroes the requested number of bytes whereas this module will | |
| 22201 | + ** use the actual amount of space allocated for the hash table (which | |
| 22202 | + ** may be larger than the requested amount). | |
| 22191 | 22203 | */ |
| 22192 | 22204 | sqlite3BeginBenignMalloc(); |
| 22193 | 22205 | new_ht = (struct _ht *)sqlite3Malloc( new_size*sizeof(struct _ht) ); |
| 22194 | 22206 | sqlite3EndBenignMalloc(); |
| 22195 | 22207 | |
| @@ -30109,11 +30121,12 @@ | ||
| 30109 | 30121 | #endif |
| 30110 | 30122 | |
| 30111 | 30123 | #define osCreateFileW ((HANDLE(WINAPI*)(LPCWSTR,DWORD,DWORD, \ |
| 30112 | 30124 | LPSECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE))aSyscall[5].pCurrent) |
| 30113 | 30125 | |
| 30114 | -#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) | |
| 30126 | +#if SQLITE_OS_WINCE || (!SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) && \ | |
| 30127 | + !defined(SQLITE_OMIT_WAL)) | |
| 30115 | 30128 | { "CreateFileMappingW", (SYSCALL)CreateFileMappingW, 0 }, |
| 30116 | 30129 | #else |
| 30117 | 30130 | { "CreateFileMappingW", (SYSCALL)0, 0 }, |
| 30118 | 30131 | #endif |
| 30119 | 30132 | |
| @@ -30421,11 +30434,11 @@ | ||
| 30421 | 30434 | #ifndef osLockFileEx |
| 30422 | 30435 | #define osLockFileEx ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD,DWORD, \ |
| 30423 | 30436 | LPOVERLAPPED))aSyscall[45].pCurrent) |
| 30424 | 30437 | #endif |
| 30425 | 30438 | |
| 30426 | -#if !SQLITE_OS_WINRT | |
| 30439 | +#if SQLITE_OS_WINCE || (!SQLITE_OS_WINRT && !defined(SQLITE_OMIT_WAL)) | |
| 30427 | 30440 | { "MapViewOfFile", (SYSCALL)MapViewOfFile, 0 }, |
| 30428 | 30441 | #else |
| 30429 | 30442 | { "MapViewOfFile", (SYSCALL)0, 0 }, |
| 30430 | 30443 | #endif |
| 30431 | 30444 | |
| @@ -30491,11 +30504,15 @@ | ||
| 30491 | 30504 | #endif |
| 30492 | 30505 | |
| 30493 | 30506 | #define osUnlockFileEx ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \ |
| 30494 | 30507 | LPOVERLAPPED))aSyscall[55].pCurrent) |
| 30495 | 30508 | |
| 30509 | +#if SQLITE_OS_WINCE || !defined(SQLITE_OMIT_WAL) | |
| 30496 | 30510 | { "UnmapViewOfFile", (SYSCALL)UnmapViewOfFile, 0 }, |
| 30511 | +#else | |
| 30512 | + { "UnmapViewOfFile", (SYSCALL)0, 0 }, | |
| 30513 | +#endif | |
| 30497 | 30514 | |
| 30498 | 30515 | #define osUnmapViewOfFile ((BOOL(WINAPI*)(LPCVOID))aSyscall[56].pCurrent) |
| 30499 | 30516 | |
| 30500 | 30517 | { "WideCharToMultiByte", (SYSCALL)WideCharToMultiByte, 0 }, |
| 30501 | 30518 | |
| @@ -30523,20 +30540,20 @@ | ||
| 30523 | 30540 | #endif |
| 30524 | 30541 | |
| 30525 | 30542 | #define osWaitForSingleObject ((DWORD(WINAPI*)(HANDLE, \ |
| 30526 | 30543 | DWORD))aSyscall[60].pCurrent) |
| 30527 | 30544 | |
| 30528 | -#if !SQLITE_OS_WINCE | |
| 30545 | +#if SQLITE_OS_WINRT | |
| 30529 | 30546 | { "WaitForSingleObjectEx", (SYSCALL)WaitForSingleObjectEx, 0 }, |
| 30530 | 30547 | #else |
| 30531 | 30548 | { "WaitForSingleObjectEx", (SYSCALL)0, 0 }, |
| 30532 | 30549 | #endif |
| 30533 | 30550 | |
| 30534 | 30551 | #define osWaitForSingleObjectEx ((DWORD(WINAPI*)(HANDLE,DWORD, \ |
| 30535 | 30552 | BOOL))aSyscall[61].pCurrent) |
| 30536 | 30553 | |
| 30537 | -#if !SQLITE_OS_WINCE | |
| 30554 | +#if SQLITE_OS_WINRT | |
| 30538 | 30555 | { "SetFilePointerEx", (SYSCALL)SetFilePointerEx, 0 }, |
| 30539 | 30556 | #else |
| 30540 | 30557 | { "SetFilePointerEx", (SYSCALL)0, 0 }, |
| 30541 | 30558 | #endif |
| 30542 | 30559 | |
| @@ -30550,11 +30567,11 @@ | ||
| 30550 | 30567 | #endif |
| 30551 | 30568 | |
| 30552 | 30569 | #define osGetFileInformationByHandleEx ((BOOL(WINAPI*)(HANDLE, \ |
| 30553 | 30570 | FILE_INFO_BY_HANDLE_CLASS,LPVOID,DWORD))aSyscall[63].pCurrent) |
| 30554 | 30571 | |
| 30555 | -#if SQLITE_OS_WINRT | |
| 30572 | +#if SQLITE_OS_WINRT && !defined(SQLITE_OMIT_WAL) | |
| 30556 | 30573 | { "MapViewOfFileFromApp", (SYSCALL)MapViewOfFileFromApp, 0 }, |
| 30557 | 30574 | #else |
| 30558 | 30575 | { "MapViewOfFileFromApp", (SYSCALL)0, 0 }, |
| 30559 | 30576 | #endif |
| 30560 | 30577 | |
| @@ -30614,11 +30631,11 @@ | ||
| 30614 | 30631 | |
| 30615 | 30632 | { "GetProcessHeap", (SYSCALL)GetProcessHeap, 0 }, |
| 30616 | 30633 | |
| 30617 | 30634 | #define osGetProcessHeap ((HANDLE(WINAPI*)(VOID))aSyscall[71].pCurrent) |
| 30618 | 30635 | |
| 30619 | -#if SQLITE_OS_WINRT | |
| 30636 | +#if SQLITE_OS_WINRT && !defined(SQLITE_OMIT_WAL) | |
| 30620 | 30637 | { "CreateFileMappingFromApp", (SYSCALL)CreateFileMappingFromApp, 0 }, |
| 30621 | 30638 | #else |
| 30622 | 30639 | { "CreateFileMappingFromApp", (SYSCALL)0, 0 }, |
| 30623 | 30640 | #endif |
| 30624 | 30641 | |
| @@ -34472,14 +34489,13 @@ | ||
| 34472 | 34489 | void *pTmpSpace; |
| 34473 | 34490 | |
| 34474 | 34491 | /* Allocate the Bitvec to be tested and a linear array of |
| 34475 | 34492 | ** bits to act as the reference */ |
| 34476 | 34493 | pBitvec = sqlite3BitvecCreate( sz ); |
| 34477 | - pV = sqlite3_malloc( (sz+7)/8 + 1 ); | |
| 34494 | + pV = sqlite3MallocZero( (sz+7)/8 + 1 ); | |
| 34478 | 34495 | pTmpSpace = sqlite3_malloc(BITVEC_SZ); |
| 34479 | 34496 | if( pBitvec==0 || pV==0 || pTmpSpace==0 ) goto bitvec_end; |
| 34480 | - memset(pV, 0, (sz+7)/8 + 1); | |
| 34481 | 34497 | |
| 34482 | 34498 | /* NULL pBitvec tests */ |
| 34483 | 34499 | sqlite3BitvecSet(0, 1); |
| 34484 | 34500 | sqlite3BitvecClear(0, 1, pTmpSpace); |
| 34485 | 34501 | |
| @@ -35559,15 +35575,14 @@ | ||
| 35559 | 35575 | nNew = 256; |
| 35560 | 35576 | } |
| 35561 | 35577 | |
| 35562 | 35578 | pcache1LeaveMutex(p->pGroup); |
| 35563 | 35579 | if( p->nHash ){ sqlite3BeginBenignMalloc(); } |
| 35564 | - apNew = (PgHdr1 **)sqlite3_malloc(sizeof(PgHdr1 *)*nNew); | |
| 35580 | + apNew = (PgHdr1 **)sqlite3MallocZero(sizeof(PgHdr1 *)*nNew); | |
| 35565 | 35581 | if( p->nHash ){ sqlite3EndBenignMalloc(); } |
| 35566 | 35582 | pcache1EnterMutex(p->pGroup); |
| 35567 | 35583 | if( apNew ){ |
| 35568 | - memset(apNew, 0, sizeof(PgHdr1 *)*nNew); | |
| 35569 | 35584 | for(i=0; i<p->nHash; i++){ |
| 35570 | 35585 | PgHdr1 *pPage; |
| 35571 | 35586 | PgHdr1 *pNext = p->apHash[i]; |
| 35572 | 35587 | while( (pPage = pNext)!=0 ){ |
| 35573 | 35588 | unsigned int h = pPage->iKey % nNew; |
| @@ -35747,13 +35762,12 @@ | ||
| 35747 | 35762 | |
| 35748 | 35763 | assert( (szPage & (szPage-1))==0 && szPage>=512 && szPage<=65536 ); |
| 35749 | 35764 | assert( szExtra < 300 ); |
| 35750 | 35765 | |
| 35751 | 35766 | sz = sizeof(PCache1) + sizeof(PGroup)*separateCache; |
| 35752 | - pCache = (PCache1 *)sqlite3_malloc(sz); | |
| 35767 | + pCache = (PCache1 *)sqlite3MallocZero(sz); | |
| 35753 | 35768 | if( pCache ){ |
| 35754 | - memset(pCache, 0, sz); | |
| 35755 | 35769 | if( separateCache ){ |
| 35756 | 35770 | pGroup = (PGroup*)&pCache[1]; |
| 35757 | 35771 | pGroup->mxPinned = 10; |
| 35758 | 35772 | }else{ |
| 35759 | 35773 | pGroup = &pcache1.grp; |
| @@ -43916,12 +43930,13 @@ | ||
| 43916 | 43930 | ** Hence, unlike the database and WAL file formats which store all values |
| 43917 | 43931 | ** as big endian, the wal-index can store multi-byte values in the native |
| 43918 | 43932 | ** byte order of the host computer. |
| 43919 | 43933 | ** |
| 43920 | 43934 | ** The purpose of the wal-index is to answer this question quickly: Given |
| 43921 | -** a page number P, return the index of the last frame for page P in the WAL, | |
| 43922 | -** or return NULL if there are no frames for page P in the WAL. | |
| 43935 | +** a page number P and a maximum frame index M, return the index of the | |
| 43936 | +** last frame in the wal before frame M for page P in the WAL, or return | |
| 43937 | +** NULL if there are no frames for page P in the WAL prior to M. | |
| 43923 | 43938 | ** |
| 43924 | 43939 | ** The wal-index consists of a header region, followed by an one or |
| 43925 | 43940 | ** more index blocks. |
| 43926 | 43941 | ** |
| 43927 | 43942 | ** The wal-index header contains the total number of frames within the WAL |
| @@ -44971,10 +44986,11 @@ | ||
| 44971 | 44986 | */ |
| 44972 | 44987 | pInfo = walCkptInfo(pWal); |
| 44973 | 44988 | pInfo->nBackfill = 0; |
| 44974 | 44989 | pInfo->aReadMark[0] = 0; |
| 44975 | 44990 | for(i=1; i<WAL_NREADER; i++) pInfo->aReadMark[i] = READMARK_NOT_USED; |
| 44991 | + if( pWal->hdr.mxFrame ) pInfo->aReadMark[1] = pWal->hdr.mxFrame; | |
| 44976 | 44992 | |
| 44977 | 44993 | /* If more than one frame was recovered from the log file, report an |
| 44978 | 44994 | ** event via sqlite3_log(). This is to help with identifying performance |
| 44979 | 44995 | ** problems caused by applications routinely shutting down without |
| 44980 | 44996 | ** checkpointing the log file. |
| @@ -45471,11 +45487,11 @@ | ||
| 45471 | 45487 | u32 y = pInfo->aReadMark[i]; |
| 45472 | 45488 | if( mxSafeFrame>y ){ |
| 45473 | 45489 | assert( y<=pWal->hdr.mxFrame ); |
| 45474 | 45490 | rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(i), 1); |
| 45475 | 45491 | if( rc==SQLITE_OK ){ |
| 45476 | - pInfo->aReadMark[i] = READMARK_NOT_USED; | |
| 45492 | + pInfo->aReadMark[i] = (i==1 ? mxSafeFrame : READMARK_NOT_USED); | |
| 45477 | 45493 | walUnlockExclusive(pWal, WAL_READ_LOCK(i), 1); |
| 45478 | 45494 | }else if( rc==SQLITE_BUSY ){ |
| 45479 | 45495 | mxSafeFrame = y; |
| 45480 | 45496 | xBusy = 0; |
| 45481 | 45497 | }else{ |
| @@ -46384,11 +46400,12 @@ | ||
| 46384 | 46400 | pWal->hdr.mxFrame = 0; |
| 46385 | 46401 | sqlite3Put4byte((u8*)&aSalt[0], 1 + sqlite3Get4byte((u8*)&aSalt[0])); |
| 46386 | 46402 | aSalt[1] = salt1; |
| 46387 | 46403 | walIndexWriteHdr(pWal); |
| 46388 | 46404 | pInfo->nBackfill = 0; |
| 46389 | - for(i=1; i<WAL_NREADER; i++) pInfo->aReadMark[i] = READMARK_NOT_USED; | |
| 46405 | + pInfo->aReadMark[1] = 0; | |
| 46406 | + for(i=2; i<WAL_NREADER; i++) pInfo->aReadMark[i] = READMARK_NOT_USED; | |
| 46390 | 46407 | assert( pInfo->aReadMark[0]==0 ); |
| 46391 | 46408 | walUnlockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1); |
| 46392 | 46409 | }else if( rc!=SQLITE_BUSY ){ |
| 46393 | 46410 | return rc; |
| 46394 | 46411 | } |
| @@ -47387,10 +47404,11 @@ | ||
| 47387 | 47404 | u8 validNKey; /* True if info.nKey is valid */ |
| 47388 | 47405 | u8 eState; /* One of the CURSOR_XXX constants (see below) */ |
| 47389 | 47406 | #ifndef SQLITE_OMIT_INCRBLOB |
| 47390 | 47407 | u8 isIncrblobHandle; /* True if this cursor is an incr. io handle */ |
| 47391 | 47408 | #endif |
| 47409 | + u8 hints; /* As configured by CursorSetHints() */ | |
| 47392 | 47410 | i16 iPage; /* Index of current page in apPage */ |
| 47393 | 47411 | u16 aiIdx[BTCURSOR_MAX_DEPTH]; /* Current index in apPage[i] */ |
| 47394 | 47412 | MemPage *apPage[BTCURSOR_MAX_DEPTH]; /* Pages from root to current page */ |
| 47395 | 47413 | }; |
| 47396 | 47414 | |
| @@ -53736,11 +53754,12 @@ | ||
| 53736 | 53754 | */ |
| 53737 | 53755 | static int balance_nonroot( |
| 53738 | 53756 | MemPage *pParent, /* Parent page of siblings being balanced */ |
| 53739 | 53757 | int iParentIdx, /* Index of "the page" in pParent */ |
| 53740 | 53758 | u8 *aOvflSpace, /* page-size bytes of space for parent ovfl */ |
| 53741 | - int isRoot /* True if pParent is a root-page */ | |
| 53759 | + int isRoot, /* True if pParent is a root-page */ | |
| 53760 | + int bBulk /* True if this call is part of a bulk load */ | |
| 53742 | 53761 | ){ |
| 53743 | 53762 | BtShared *pBt; /* The whole database */ |
| 53744 | 53763 | int nCell = 0; /* Number of cells in apCell[] */ |
| 53745 | 53764 | int nMaxCells = 0; /* Allocated size of apCell, szCell, aFrom. */ |
| 53746 | 53765 | int nNew = 0; /* Number of pages in apNew[] */ |
| @@ -53800,22 +53819,23 @@ | ||
| 53800 | 53819 | ** have already been removed. |
| 53801 | 53820 | */ |
| 53802 | 53821 | i = pParent->nOverflow + pParent->nCell; |
| 53803 | 53822 | if( i<2 ){ |
| 53804 | 53823 | nxDiv = 0; |
| 53805 | - nOld = i+1; | |
| 53806 | 53824 | }else{ |
| 53807 | - nOld = 3; | |
| 53825 | + assert( bBulk==0 || bBulk==1 ); | |
| 53808 | 53826 | if( iParentIdx==0 ){ |
| 53809 | 53827 | nxDiv = 0; |
| 53810 | 53828 | }else if( iParentIdx==i ){ |
| 53811 | - nxDiv = i-2; | |
| 53829 | + nxDiv = i-2+bBulk; | |
| 53812 | 53830 | }else{ |
| 53831 | + assert( bBulk==0 ); | |
| 53813 | 53832 | nxDiv = iParentIdx-1; |
| 53814 | 53833 | } |
| 53815 | - i = 2; | |
| 53834 | + i = 2-bBulk; | |
| 53816 | 53835 | } |
| 53836 | + nOld = i+1; | |
| 53817 | 53837 | if( (i+nxDiv-pParent->nOverflow)==pParent->nCell ){ |
| 53818 | 53838 | pRight = &pParent->aData[pParent->hdrOffset+8]; |
| 53819 | 53839 | }else{ |
| 53820 | 53840 | pRight = findCell(pParent, i+nxDiv-pParent->nOverflow); |
| 53821 | 53841 | } |
| @@ -54020,11 +54040,13 @@ | ||
| 54020 | 54040 | |
| 54021 | 54041 | r = cntNew[i-1] - 1; |
| 54022 | 54042 | d = r + 1 - leafData; |
| 54023 | 54043 | assert( d<nMaxCells ); |
| 54024 | 54044 | assert( r<nMaxCells ); |
| 54025 | - while( szRight==0 || szRight+szCell[d]+2<=szLeft-(szCell[r]+2) ){ | |
| 54045 | + while( szRight==0 | |
| 54046 | + || (!bBulk && szRight+szCell[d]+2<=szLeft-(szCell[r]+2)) | |
| 54047 | + ){ | |
| 54026 | 54048 | szRight += szCell[d] + 2; |
| 54027 | 54049 | szLeft -= szCell[r] + 2; |
| 54028 | 54050 | cntNew[i-1]--; |
| 54029 | 54051 | r = cntNew[i-1] - 1; |
| 54030 | 54052 | d = r + 1 - leafData; |
| @@ -54067,11 +54089,11 @@ | ||
| 54067 | 54089 | rc = sqlite3PagerWrite(pNew->pDbPage); |
| 54068 | 54090 | nNew++; |
| 54069 | 54091 | if( rc ) goto balance_cleanup; |
| 54070 | 54092 | }else{ |
| 54071 | 54093 | assert( i>0 ); |
| 54072 | - rc = allocateBtreePage(pBt, &pNew, &pgno, pgno, 0); | |
| 54094 | + rc = allocateBtreePage(pBt, &pNew, &pgno, (bBulk ? 1 : pgno), 0); | |
| 54073 | 54095 | if( rc ) goto balance_cleanup; |
| 54074 | 54096 | apNew[i] = pNew; |
| 54075 | 54097 | nNew++; |
| 54076 | 54098 | |
| 54077 | 54099 | /* Set the pointer-map entry for the new sibling page. */ |
| @@ -54517,11 +54539,11 @@ | ||
| 54517 | 54539 | ** the previous call, as the overflow cell data will have been |
| 54518 | 54540 | ** copied either into the body of a database page or into the new |
| 54519 | 54541 | ** pSpace buffer passed to the latter call to balance_nonroot(). |
| 54520 | 54542 | */ |
| 54521 | 54543 | u8 *pSpace = sqlite3PageMalloc(pCur->pBt->pageSize); |
| 54522 | - rc = balance_nonroot(pParent, iIdx, pSpace, iPage==1); | |
| 54544 | + rc = balance_nonroot(pParent, iIdx, pSpace, iPage==1, pCur->hints); | |
| 54523 | 54545 | if( pFree ){ |
| 54524 | 54546 | /* If pFree is not NULL, it points to the pSpace buffer used |
| 54525 | 54547 | ** by a previous call to balance_nonroot(). Its contents are |
| 54526 | 54548 | ** now stored either on real database pages or within the |
| 54527 | 54549 | ** new pSpace buffer, so it may be safely freed here. */ |
| @@ -56104,10 +56126,20 @@ | ||
| 56104 | 56126 | } |
| 56105 | 56127 | |
| 56106 | 56128 | pBt->btsFlags &= ~BTS_NO_WAL; |
| 56107 | 56129 | return rc; |
| 56108 | 56130 | } |
| 56131 | + | |
| 56132 | +/* | |
| 56133 | +** set the mask of hint flags for cursor pCsr. Currently the only valid | |
| 56134 | +** values are 0 and BTREE_BULKLOAD. | |
| 56135 | +*/ | |
| 56136 | +SQLITE_PRIVATE void sqlite3BtreeCursorHints(BtCursor *pCsr, unsigned int mask){ | |
| 56137 | + assert( mask==BTREE_BULKLOAD || mask==0 ); | |
| 56138 | + pCsr->hints = mask; | |
| 56139 | +} | |
| 56140 | + | |
| 56109 | 56141 | |
| 56110 | 56142 | /************** End of btree.c ***********************************************/ |
| 56111 | 56143 | /************** Begin file backup.c ******************************************/ |
| 56112 | 56144 | /* |
| 56113 | 56145 | ** 2009 January 28 |
| @@ -56271,19 +56303,18 @@ | ||
| 56271 | 56303 | }else { |
| 56272 | 56304 | /* Allocate space for a new sqlite3_backup object... |
| 56273 | 56305 | ** EVIDENCE-OF: R-64852-21591 The sqlite3_backup object is created by a |
| 56274 | 56306 | ** call to sqlite3_backup_init() and is destroyed by a call to |
| 56275 | 56307 | ** sqlite3_backup_finish(). */ |
| 56276 | - p = (sqlite3_backup *)sqlite3_malloc(sizeof(sqlite3_backup)); | |
| 56308 | + p = (sqlite3_backup *)sqlite3MallocZero(sizeof(sqlite3_backup)); | |
| 56277 | 56309 | if( !p ){ |
| 56278 | 56310 | sqlite3Error(pDestDb, SQLITE_NOMEM, 0); |
| 56279 | 56311 | } |
| 56280 | 56312 | } |
| 56281 | 56313 | |
| 56282 | 56314 | /* If the allocation succeeded, populate the new object. */ |
| 56283 | 56315 | if( p ){ |
| 56284 | - memset(p, 0, sizeof(sqlite3_backup)); | |
| 56285 | 56316 | p->pSrc = findBtree(pDestDb, pSrcDb, zSrcDb); |
| 56286 | 56317 | p->pDest = findBtree(pDestDb, pDestDb, zDestDb); |
| 56287 | 56318 | p->pDestDb = pDestDb; |
| 56288 | 56319 | p->pSrcDb = pSrcDb; |
| 56289 | 56320 | p->iNext = 1; |
| @@ -62703,13 +62734,12 @@ | ||
| 62703 | 62734 | */ |
| 62704 | 62735 | SQLITE_PRIVATE void sqlite3ExplainBegin(Vdbe *pVdbe){ |
| 62705 | 62736 | if( pVdbe ){ |
| 62706 | 62737 | Explain *p; |
| 62707 | 62738 | sqlite3BeginBenignMalloc(); |
| 62708 | - p = sqlite3_malloc( sizeof(Explain) ); | |
| 62739 | + p = (Explain *)sqlite3MallocZero( sizeof(Explain) ); | |
| 62709 | 62740 | if( p ){ |
| 62710 | - memset(p, 0, sizeof(*p)); | |
| 62711 | 62741 | p->pVdbe = pVdbe; |
| 62712 | 62742 | sqlite3_free(pVdbe->pExplain); |
| 62713 | 62743 | pVdbe->pExplain = p; |
| 62714 | 62744 | sqlite3StrAccumInit(&p->str, p->zBase, sizeof(p->zBase), |
| 62715 | 62745 | SQLITE_MAX_LENGTH); |
| @@ -66486,10 +66516,13 @@ | ||
| 66486 | 66516 | Btree *pX; |
| 66487 | 66517 | VdbeCursor *pCur; |
| 66488 | 66518 | Db *pDb; |
| 66489 | 66519 | #endif /* local variables moved into u.ax */ |
| 66490 | 66520 | |
| 66521 | + assert( (pOp->p5&(OPFLAG_P2ISREG|OPFLAG_BULKCSR))==pOp->p5 ); | |
| 66522 | + assert( pOp->opcode==OP_OpenWrite || pOp->p5==0 ); | |
| 66523 | + | |
| 66491 | 66524 | if( p->expired ){ |
| 66492 | 66525 | rc = SQLITE_ABORT; |
| 66493 | 66526 | break; |
| 66494 | 66527 | } |
| 66495 | 66528 | |
| @@ -66509,11 +66542,11 @@ | ||
| 66509 | 66542 | p->minWriteFileFormat = u.ax.pDb->pSchema->file_format; |
| 66510 | 66543 | } |
| 66511 | 66544 | }else{ |
| 66512 | 66545 | u.ax.wrFlag = 0; |
| 66513 | 66546 | } |
| 66514 | - if( pOp->p5 ){ | |
| 66547 | + if( pOp->p5 & OPFLAG_P2ISREG ){ | |
| 66515 | 66548 | assert( u.ax.p2>0 ); |
| 66516 | 66549 | assert( u.ax.p2<=p->nMem ); |
| 66517 | 66550 | pIn2 = &aMem[u.ax.p2]; |
| 66518 | 66551 | assert( memIsValid(pIn2) ); |
| 66519 | 66552 | assert( (pIn2->flags & MEM_Int)!=0 ); |
| @@ -66540,10 +66573,12 @@ | ||
| 66540 | 66573 | if( u.ax.pCur==0 ) goto no_mem; |
| 66541 | 66574 | u.ax.pCur->nullRow = 1; |
| 66542 | 66575 | u.ax.pCur->isOrdered = 1; |
| 66543 | 66576 | rc = sqlite3BtreeCursor(u.ax.pX, u.ax.p2, u.ax.wrFlag, u.ax.pKeyInfo, u.ax.pCur->pCursor); |
| 66544 | 66577 | u.ax.pCur->pKeyInfo = u.ax.pKeyInfo; |
| 66578 | + assert( OPFLAG_BULKCSR==BTREE_BULKLOAD ); | |
| 66579 | + sqlite3BtreeCursorHints(u.ax.pCur->pCursor, (pOp->p5 & OPFLAG_BULKCSR)); | |
| 66545 | 66580 | |
| 66546 | 66581 | /* Since it performs no memory allocation or IO, the only value that |
| 66547 | 66582 | ** sqlite3BtreeCursor() may return is SQLITE_OK. */ |
| 66548 | 66583 | assert( rc==SQLITE_OK ); |
| 66549 | 66584 | |
| @@ -70159,10 +70194,11 @@ | ||
| 70159 | 70194 | |
| 70160 | 70195 | #ifndef SQLITE_OMIT_MERGE_SORT |
| 70161 | 70196 | |
| 70162 | 70197 | typedef struct VdbeSorterIter VdbeSorterIter; |
| 70163 | 70198 | typedef struct SorterRecord SorterRecord; |
| 70199 | +typedef struct FileWriter FileWriter; | |
| 70164 | 70200 | |
| 70165 | 70201 | /* |
| 70166 | 70202 | ** NOTES ON DATA STRUCTURE USED FOR N-WAY MERGES: |
| 70167 | 70203 | ** |
| 70168 | 70204 | ** As keys are added to the sorter, they are written to disk in a series |
| @@ -70256,10 +70292,28 @@ | ||
| 70256 | 70292 | int nAlloc; /* Bytes of space at aAlloc */ |
| 70257 | 70293 | int nKey; /* Number of bytes in key */ |
| 70258 | 70294 | sqlite3_file *pFile; /* File iterator is reading from */ |
| 70259 | 70295 | u8 *aAlloc; /* Allocated space */ |
| 70260 | 70296 | u8 *aKey; /* Pointer to current key */ |
| 70297 | + u8 *aBuffer; /* Current read buffer */ | |
| 70298 | + int nBuffer; /* Size of read buffer in bytes */ | |
| 70299 | +}; | |
| 70300 | + | |
| 70301 | +/* | |
| 70302 | +** An instance of this structure is used to organize the stream of records | |
| 70303 | +** being written to files by the merge-sort code into aligned, page-sized | |
| 70304 | +** blocks. Doing all I/O in aligned page-sized blocks helps I/O to go | |
| 70305 | +** faster on many operating systems. | |
| 70306 | +*/ | |
| 70307 | +struct FileWriter { | |
| 70308 | + int eFWErr; /* Non-zero if in an error state */ | |
| 70309 | + u8 *aBuffer; /* Pointer to write buffer */ | |
| 70310 | + int nBuffer; /* Size of write buffer in bytes */ | |
| 70311 | + int iBufStart; /* First byte of buffer to write */ | |
| 70312 | + int iBufEnd; /* Last byte of buffer to write */ | |
| 70313 | + i64 iWriteOff; /* Offset of start of buffer in file */ | |
| 70314 | + sqlite3_file *pFile; /* File to write to */ | |
| 70261 | 70315 | }; |
| 70262 | 70316 | |
| 70263 | 70317 | /* |
| 70264 | 70318 | ** A structure to store a single record. All in-memory records are connected |
| 70265 | 70319 | ** together into a linked list headed at VdbeSorter.pRecord using the |
| @@ -70281,12 +70335,126 @@ | ||
| 70281 | 70335 | ** Free all memory belonging to the VdbeSorterIter object passed as the second |
| 70282 | 70336 | ** argument. All structure fields are set to zero before returning. |
| 70283 | 70337 | */ |
| 70284 | 70338 | static void vdbeSorterIterZero(sqlite3 *db, VdbeSorterIter *pIter){ |
| 70285 | 70339 | sqlite3DbFree(db, pIter->aAlloc); |
| 70340 | + sqlite3DbFree(db, pIter->aBuffer); | |
| 70286 | 70341 | memset(pIter, 0, sizeof(VdbeSorterIter)); |
| 70287 | 70342 | } |
| 70343 | + | |
| 70344 | +/* | |
| 70345 | +** Read nByte bytes of data from the stream of data iterated by object p. | |
| 70346 | +** If successful, set *ppOut to point to a buffer containing the data | |
| 70347 | +** and return SQLITE_OK. Otherwise, if an error occurs, return an SQLite | |
| 70348 | +** error code. | |
| 70349 | +** | |
| 70350 | +** The buffer indicated by *ppOut may only be considered valid until the | |
| 70351 | +** next call to this function. | |
| 70352 | +*/ | |
| 70353 | +static int vdbeSorterIterRead( | |
| 70354 | + sqlite3 *db, /* Database handle (for malloc) */ | |
| 70355 | + VdbeSorterIter *p, /* Iterator */ | |
| 70356 | + int nByte, /* Bytes of data to read */ | |
| 70357 | + u8 **ppOut /* OUT: Pointer to buffer containing data */ | |
| 70358 | +){ | |
| 70359 | + int iBuf; /* Offset within buffer to read from */ | |
| 70360 | + int nAvail; /* Bytes of data available in buffer */ | |
| 70361 | + assert( p->aBuffer ); | |
| 70362 | + | |
| 70363 | + /* If there is no more data to be read from the buffer, read the next | |
| 70364 | + ** p->nBuffer bytes of data from the file into it. Or, if there are less | |
| 70365 | + ** than p->nBuffer bytes remaining in the PMA, read all remaining data. */ | |
| 70366 | + iBuf = p->iReadOff % p->nBuffer; | |
| 70367 | + if( iBuf==0 ){ | |
| 70368 | + int nRead; /* Bytes to read from disk */ | |
| 70369 | + int rc; /* sqlite3OsRead() return code */ | |
| 70370 | + | |
| 70371 | + /* Determine how many bytes of data to read. */ | |
| 70372 | + nRead = p->iEof - p->iReadOff; | |
| 70373 | + if( nRead>p->nBuffer ) nRead = p->nBuffer; | |
| 70374 | + assert( nRead>0 ); | |
| 70375 | + | |
| 70376 | + /* Read data from the file. Return early if an error occurs. */ | |
| 70377 | + rc = sqlite3OsRead(p->pFile, p->aBuffer, nRead, p->iReadOff); | |
| 70378 | + assert( rc!=SQLITE_IOERR_SHORT_READ ); | |
| 70379 | + if( rc!=SQLITE_OK ) return rc; | |
| 70380 | + } | |
| 70381 | + nAvail = p->nBuffer - iBuf; | |
| 70382 | + | |
| 70383 | + if( nByte<=nAvail ){ | |
| 70384 | + /* The requested data is available in the in-memory buffer. In this | |
| 70385 | + ** case there is no need to make a copy of the data, just return a | |
| 70386 | + ** pointer into the buffer to the caller. */ | |
| 70387 | + *ppOut = &p->aBuffer[iBuf]; | |
| 70388 | + p->iReadOff += nByte; | |
| 70389 | + }else{ | |
| 70390 | + /* The requested data is not all available in the in-memory buffer. | |
| 70391 | + ** In this case, allocate space at p->aAlloc[] to copy the requested | |
| 70392 | + ** range into. Then return a copy of pointer p->aAlloc to the caller. */ | |
| 70393 | + int nRem; /* Bytes remaining to copy */ | |
| 70394 | + | |
| 70395 | + /* Extend the p->aAlloc[] allocation if required. */ | |
| 70396 | + if( p->nAlloc<nByte ){ | |
| 70397 | + int nNew = p->nAlloc*2; | |
| 70398 | + while( nByte>nNew ) nNew = nNew*2; | |
| 70399 | + p->aAlloc = sqlite3DbReallocOrFree(db, p->aAlloc, nNew); | |
| 70400 | + if( !p->aAlloc ) return SQLITE_NOMEM; | |
| 70401 | + p->nAlloc = nNew; | |
| 70402 | + } | |
| 70403 | + | |
| 70404 | + /* Copy as much data as is available in the buffer into the start of | |
| 70405 | + ** p->aAlloc[]. */ | |
| 70406 | + memcpy(p->aAlloc, &p->aBuffer[iBuf], nAvail); | |
| 70407 | + p->iReadOff += nAvail; | |
| 70408 | + nRem = nByte - nAvail; | |
| 70409 | + | |
| 70410 | + /* The following loop copies up to p->nBuffer bytes per iteration into | |
| 70411 | + ** the p->aAlloc[] buffer. */ | |
| 70412 | + while( nRem>0 ){ | |
| 70413 | + int rc; /* vdbeSorterIterRead() return code */ | |
| 70414 | + int nCopy; /* Number of bytes to copy */ | |
| 70415 | + u8 *aNext; /* Pointer to buffer to copy data from */ | |
| 70416 | + | |
| 70417 | + nCopy = nRem; | |
| 70418 | + if( nRem>p->nBuffer ) nCopy = p->nBuffer; | |
| 70419 | + rc = vdbeSorterIterRead(db, p, nCopy, &aNext); | |
| 70420 | + if( rc!=SQLITE_OK ) return rc; | |
| 70421 | + assert( aNext!=p->aAlloc ); | |
| 70422 | + memcpy(&p->aAlloc[nByte - nRem], aNext, nCopy); | |
| 70423 | + nRem -= nCopy; | |
| 70424 | + } | |
| 70425 | + | |
| 70426 | + *ppOut = p->aAlloc; | |
| 70427 | + } | |
| 70428 | + | |
| 70429 | + return SQLITE_OK; | |
| 70430 | +} | |
| 70431 | + | |
| 70432 | +/* | |
| 70433 | +** Read a varint from the stream of data accessed by p. Set *pnOut to | |
| 70434 | +** the value read. | |
| 70435 | +*/ | |
| 70436 | +static int vdbeSorterIterVarint(sqlite3 *db, VdbeSorterIter *p, u64 *pnOut){ | |
| 70437 | + int iBuf; | |
| 70438 | + | |
| 70439 | + iBuf = p->iReadOff % p->nBuffer; | |
| 70440 | + if( iBuf && (p->nBuffer-iBuf)>=9 ){ | |
| 70441 | + p->iReadOff += sqlite3GetVarint(&p->aBuffer[iBuf], pnOut); | |
| 70442 | + }else{ | |
| 70443 | + u8 aVarint[16], *a; | |
| 70444 | + int i = 0, rc; | |
| 70445 | + do{ | |
| 70446 | + rc = vdbeSorterIterRead(db, p, 1, &a); | |
| 70447 | + if( rc ) return rc; | |
| 70448 | + aVarint[(i++)&0xf] = a[0]; | |
| 70449 | + }while( (a[0]&0x80)!=0 ); | |
| 70450 | + sqlite3GetVarint(aVarint, pnOut); | |
| 70451 | + } | |
| 70452 | + | |
| 70453 | + return SQLITE_OK; | |
| 70454 | +} | |
| 70455 | + | |
| 70288 | 70456 | |
| 70289 | 70457 | /* |
| 70290 | 70458 | ** Advance iterator pIter to the next key in its PMA. Return SQLITE_OK if |
| 70291 | 70459 | ** no error occurs, or an SQLite error code if one does. |
| 70292 | 70460 | */ |
| @@ -70293,100 +70461,22 @@ | ||
| 70293 | 70461 | static int vdbeSorterIterNext( |
| 70294 | 70462 | sqlite3 *db, /* Database handle (for sqlite3DbMalloc() ) */ |
| 70295 | 70463 | VdbeSorterIter *pIter /* Iterator to advance */ |
| 70296 | 70464 | ){ |
| 70297 | 70465 | int rc; /* Return Code */ |
| 70298 | - int nRead; /* Number of bytes read */ | |
| 70299 | - int nRec = 0; /* Size of record in bytes */ | |
| 70300 | - int iOff = 0; /* Size of serialized size varint in bytes */ | |
| 70301 | - | |
| 70302 | - assert( pIter->iEof>=pIter->iReadOff ); | |
| 70303 | - if( pIter->iEof-pIter->iReadOff>5 ){ | |
| 70304 | - nRead = 5; | |
| 70305 | - }else{ | |
| 70306 | - nRead = (int)(pIter->iEof - pIter->iReadOff); | |
| 70307 | - } | |
| 70308 | - if( nRead<=0 ){ | |
| 70466 | + u64 nRec = 0; /* Size of record in bytes */ | |
| 70467 | + | |
| 70468 | + if( pIter->iReadOff>=pIter->iEof ){ | |
| 70309 | 70469 | /* This is an EOF condition */ |
| 70310 | 70470 | vdbeSorterIterZero(db, pIter); |
| 70311 | 70471 | return SQLITE_OK; |
| 70312 | 70472 | } |
| 70313 | 70473 | |
| 70314 | - rc = sqlite3OsRead(pIter->pFile, pIter->aAlloc, nRead, pIter->iReadOff); | |
| 70315 | - if( rc==SQLITE_OK ){ | |
| 70316 | - iOff = getVarint32(pIter->aAlloc, nRec); | |
| 70317 | - if( (iOff+nRec)>nRead ){ | |
| 70318 | - int nRead2; /* Number of extra bytes to read */ | |
| 70319 | - if( (iOff+nRec)>pIter->nAlloc ){ | |
| 70320 | - int nNew = pIter->nAlloc*2; | |
| 70321 | - while( (iOff+nRec)>nNew ) nNew = nNew*2; | |
| 70322 | - pIter->aAlloc = sqlite3DbReallocOrFree(db, pIter->aAlloc, nNew); | |
| 70323 | - if( !pIter->aAlloc ) return SQLITE_NOMEM; | |
| 70324 | - pIter->nAlloc = nNew; | |
| 70325 | - } | |
| 70326 | - | |
| 70327 | - nRead2 = iOff + nRec - nRead; | |
| 70328 | - rc = sqlite3OsRead( | |
| 70329 | - pIter->pFile, &pIter->aAlloc[nRead], nRead2, pIter->iReadOff+nRead | |
| 70330 | - ); | |
| 70331 | - } | |
| 70332 | - } | |
| 70333 | - | |
| 70334 | - assert( rc!=SQLITE_OK || nRec>0 ); | |
| 70335 | - pIter->iReadOff += iOff+nRec; | |
| 70336 | - pIter->nKey = nRec; | |
| 70337 | - pIter->aKey = &pIter->aAlloc[iOff]; | |
| 70338 | - return rc; | |
| 70339 | -} | |
| 70340 | - | |
| 70341 | -/* | |
| 70342 | -** Write a single varint, value iVal, to file-descriptor pFile. Return | |
| 70343 | -** SQLITE_OK if successful, or an SQLite error code if some error occurs. | |
| 70344 | -** | |
| 70345 | -** The value of *piOffset when this function is called is used as the byte | |
| 70346 | -** offset in file pFile to write to. Before returning, *piOffset is | |
| 70347 | -** incremented by the number of bytes written. | |
| 70348 | -*/ | |
| 70349 | -static int vdbeSorterWriteVarint( | |
| 70350 | - sqlite3_file *pFile, /* File to write to */ | |
| 70351 | - i64 iVal, /* Value to write as a varint */ | |
| 70352 | - i64 *piOffset /* IN/OUT: Write offset in file pFile */ | |
| 70353 | -){ | |
| 70354 | - u8 aVarint[9]; /* Buffer large enough for a varint */ | |
| 70355 | - int nVarint; /* Number of used bytes in varint */ | |
| 70356 | - int rc; /* Result of write() call */ | |
| 70357 | - | |
| 70358 | - nVarint = sqlite3PutVarint(aVarint, iVal); | |
| 70359 | - rc = sqlite3OsWrite(pFile, aVarint, nVarint, *piOffset); | |
| 70360 | - *piOffset += nVarint; | |
| 70361 | - | |
| 70362 | - return rc; | |
| 70363 | -} | |
| 70364 | - | |
| 70365 | -/* | |
| 70366 | -** Read a single varint from file-descriptor pFile. Return SQLITE_OK if | |
| 70367 | -** successful, or an SQLite error code if some error occurs. | |
| 70368 | -** | |
| 70369 | -** The value of *piOffset when this function is called is used as the | |
| 70370 | -** byte offset in file pFile from whence to read the varint. If successful | |
| 70371 | -** (i.e. if no IO error occurs), then *piOffset is set to the offset of | |
| 70372 | -** the first byte past the end of the varint before returning. *piVal is | |
| 70373 | -** set to the integer value read. If an error occurs, the final values of | |
| 70374 | -** both *piOffset and *piVal are undefined. | |
| 70375 | -*/ | |
| 70376 | -static int vdbeSorterReadVarint( | |
| 70377 | - sqlite3_file *pFile, /* File to read from */ | |
| 70378 | - i64 *piOffset, /* IN/OUT: Read offset in pFile */ | |
| 70379 | - i64 *piVal /* OUT: Value read from file */ | |
| 70380 | -){ | |
| 70381 | - u8 aVarint[9]; /* Buffer large enough for a varint */ | |
| 70382 | - i64 iOff = *piOffset; /* Offset in file to read from */ | |
| 70383 | - int rc; /* Return code */ | |
| 70384 | - | |
| 70385 | - rc = sqlite3OsRead(pFile, aVarint, 9, iOff); | |
| 70386 | - if( rc==SQLITE_OK ){ | |
| 70387 | - *piOffset += getVarint(aVarint, (u64 *)piVal); | |
| 70474 | + rc = vdbeSorterIterVarint(db, pIter, &nRec); | |
| 70475 | + if( rc==SQLITE_OK ){ | |
| 70476 | + pIter->nKey = (int)nRec; | |
| 70477 | + rc = vdbeSorterIterRead(db, pIter, nRec, &pIter->aKey); | |
| 70388 | 70478 | } |
| 70389 | 70479 | |
| 70390 | 70480 | return rc; |
| 70391 | 70481 | } |
| 70392 | 70482 | |
| @@ -70396,31 +70486,56 @@ | ||
| 70396 | 70486 | ** leaves the iterator pointing to the first key in the PMA (or EOF if the |
| 70397 | 70487 | ** PMA is empty). |
| 70398 | 70488 | */ |
| 70399 | 70489 | static int vdbeSorterIterInit( |
| 70400 | 70490 | sqlite3 *db, /* Database handle */ |
| 70401 | - VdbeSorter *pSorter, /* Sorter object */ | |
| 70491 | + const VdbeSorter *pSorter, /* Sorter object */ | |
| 70402 | 70492 | i64 iStart, /* Start offset in pFile */ |
| 70403 | 70493 | VdbeSorterIter *pIter, /* Iterator to populate */ |
| 70404 | 70494 | i64 *pnByte /* IN/OUT: Increment this value by PMA size */ |
| 70405 | 70495 | ){ |
| 70406 | - int rc; | |
| 70496 | + int rc = SQLITE_OK; | |
| 70497 | + int nBuf; | |
| 70498 | + | |
| 70499 | + nBuf = sqlite3BtreeGetPageSize(db->aDb[0].pBt); | |
| 70407 | 70500 | |
| 70408 | 70501 | assert( pSorter->iWriteOff>iStart ); |
| 70409 | 70502 | assert( pIter->aAlloc==0 ); |
| 70503 | + assert( pIter->aBuffer==0 ); | |
| 70410 | 70504 | pIter->pFile = pSorter->pTemp1; |
| 70411 | 70505 | pIter->iReadOff = iStart; |
| 70412 | 70506 | pIter->nAlloc = 128; |
| 70413 | 70507 | pIter->aAlloc = (u8 *)sqlite3DbMallocRaw(db, pIter->nAlloc); |
| 70414 | - if( !pIter->aAlloc ){ | |
| 70508 | + pIter->nBuffer = nBuf; | |
| 70509 | + pIter->aBuffer = (u8 *)sqlite3DbMallocRaw(db, nBuf); | |
| 70510 | + | |
| 70511 | + if( !pIter->aBuffer ){ | |
| 70415 | 70512 | rc = SQLITE_NOMEM; |
| 70416 | 70513 | }else{ |
| 70417 | - i64 nByte; /* Total size of PMA in bytes */ | |
| 70418 | - rc = vdbeSorterReadVarint(pSorter->pTemp1, &pIter->iReadOff, &nByte); | |
| 70419 | - *pnByte += nByte; | |
| 70420 | - pIter->iEof = pIter->iReadOff + nByte; | |
| 70514 | + int iBuf; | |
| 70515 | + | |
| 70516 | + iBuf = iStart % nBuf; | |
| 70517 | + if( iBuf ){ | |
| 70518 | + int nRead = nBuf - iBuf; | |
| 70519 | + if( (iStart + nRead) > pSorter->iWriteOff ){ | |
| 70520 | + nRead = pSorter->iWriteOff - iStart; | |
| 70521 | + } | |
| 70522 | + rc = sqlite3OsRead( | |
| 70523 | + pSorter->pTemp1, &pIter->aBuffer[iBuf], nRead, iStart | |
| 70524 | + ); | |
| 70525 | + assert( rc!=SQLITE_IOERR_SHORT_READ ); | |
| 70526 | + } | |
| 70527 | + | |
| 70528 | + if( rc==SQLITE_OK ){ | |
| 70529 | + u64 nByte; /* Size of PMA in bytes */ | |
| 70530 | + pIter->iEof = pSorter->iWriteOff; | |
| 70531 | + rc = vdbeSorterIterVarint(db, pIter, &nByte); | |
| 70532 | + pIter->iEof = pIter->iReadOff + nByte; | |
| 70533 | + *pnByte += nByte; | |
| 70534 | + } | |
| 70421 | 70535 | } |
| 70536 | + | |
| 70422 | 70537 | if( rc==SQLITE_OK ){ |
| 70423 | 70538 | rc = vdbeSorterIterNext(db, pIter); |
| 70424 | 70539 | } |
| 70425 | 70540 | return rc; |
| 70426 | 70541 | } |
| @@ -70440,14 +70555,14 @@ | ||
| 70440 | 70555 | ** |
| 70441 | 70556 | ** If pKey2 is passed a NULL pointer, then it is assumed that the pCsr->aSpace |
| 70442 | 70557 | ** has been allocated and contains an unpacked record that is used as key2. |
| 70443 | 70558 | */ |
| 70444 | 70559 | static void vdbeSorterCompare( |
| 70445 | - VdbeCursor *pCsr, /* Cursor object (for pKeyInfo) */ | |
| 70560 | + const VdbeCursor *pCsr, /* Cursor object (for pKeyInfo) */ | |
| 70446 | 70561 | int bOmitRowid, /* Ignore rowid field at end of keys */ |
| 70447 | - void *pKey1, int nKey1, /* Left side of comparison */ | |
| 70448 | - void *pKey2, int nKey2, /* Right side of comparison */ | |
| 70562 | + const void *pKey1, int nKey1, /* Left side of comparison */ | |
| 70563 | + const void *pKey2, int nKey2, /* Right side of comparison */ | |
| 70449 | 70564 | int *pRes /* OUT: Result of comparison */ |
| 70450 | 70565 | ){ |
| 70451 | 70566 | KeyInfo *pKeyInfo = pCsr->pKeyInfo; |
| 70452 | 70567 | VdbeSorter *pSorter = pCsr->pSorter; |
| 70453 | 70568 | UnpackedRecord *r2 = pSorter->pUnpacked; |
| @@ -70475,11 +70590,11 @@ | ||
| 70475 | 70590 | /* |
| 70476 | 70591 | ** This function is called to compare two iterator keys when merging |
| 70477 | 70592 | ** multiple b-tree segments. Parameter iOut is the index of the aTree[] |
| 70478 | 70593 | ** value to recalculate. |
| 70479 | 70594 | */ |
| 70480 | -static int vdbeSorterDoCompare(VdbeCursor *pCsr, int iOut){ | |
| 70595 | +static int vdbeSorterDoCompare(const VdbeCursor *pCsr, int iOut){ | |
| 70481 | 70596 | VdbeSorter *pSorter = pCsr->pSorter; |
| 70482 | 70597 | int i1; |
| 70483 | 70598 | int i2; |
| 70484 | 70599 | int iRes; |
| 70485 | 70600 | VdbeSorterIter *p1; |
| @@ -70601,11 +70716,11 @@ | ||
| 70601 | 70716 | /* |
| 70602 | 70717 | ** Merge the two sorted lists p1 and p2 into a single list. |
| 70603 | 70718 | ** Set *ppOut to the head of the new list. |
| 70604 | 70719 | */ |
| 70605 | 70720 | static void vdbeSorterMerge( |
| 70606 | - VdbeCursor *pCsr, /* For pKeyInfo */ | |
| 70721 | + const VdbeCursor *pCsr, /* For pKeyInfo */ | |
| 70607 | 70722 | SorterRecord *p1, /* First list to merge */ |
| 70608 | 70723 | SorterRecord *p2, /* Second list to merge */ |
| 70609 | 70724 | SorterRecord **ppOut /* OUT: Head of merged list */ |
| 70610 | 70725 | ){ |
| 70611 | 70726 | SorterRecord *pFinal = 0; |
| @@ -70635,11 +70750,11 @@ | ||
| 70635 | 70750 | /* |
| 70636 | 70751 | ** Sort the linked list of records headed at pCsr->pRecord. Return SQLITE_OK |
| 70637 | 70752 | ** if successful, or an SQLite error code (i.e. SQLITE_NOMEM) if an error |
| 70638 | 70753 | ** occurs. |
| 70639 | 70754 | */ |
| 70640 | -static int vdbeSorterSort(VdbeCursor *pCsr){ | |
| 70755 | +static int vdbeSorterSort(const VdbeCursor *pCsr){ | |
| 70641 | 70756 | int i; |
| 70642 | 70757 | SorterRecord **aSlot; |
| 70643 | 70758 | SorterRecord *p; |
| 70644 | 70759 | VdbeSorter *pSorter = pCsr->pSorter; |
| 70645 | 70760 | |
| @@ -70668,10 +70783,95 @@ | ||
| 70668 | 70783 | |
| 70669 | 70784 | sqlite3_free(aSlot); |
| 70670 | 70785 | return SQLITE_OK; |
| 70671 | 70786 | } |
| 70672 | 70787 | |
| 70788 | +/* | |
| 70789 | +** Initialize a file-writer object. | |
| 70790 | +*/ | |
| 70791 | +static void fileWriterInit( | |
| 70792 | + sqlite3 *db, /* Database (for malloc) */ | |
| 70793 | + sqlite3_file *pFile, /* File to write to */ | |
| 70794 | + FileWriter *p, /* Object to populate */ | |
| 70795 | + i64 iStart /* Offset of pFile to begin writing at */ | |
| 70796 | +){ | |
| 70797 | + int nBuf = sqlite3BtreeGetPageSize(db->aDb[0].pBt); | |
| 70798 | + | |
| 70799 | + memset(p, 0, sizeof(FileWriter)); | |
| 70800 | + p->aBuffer = (u8 *)sqlite3DbMallocRaw(db, nBuf); | |
| 70801 | + if( !p->aBuffer ){ | |
| 70802 | + p->eFWErr = SQLITE_NOMEM; | |
| 70803 | + }else{ | |
| 70804 | + p->iBufEnd = p->iBufStart = (iStart % nBuf); | |
| 70805 | + p->iWriteOff = iStart - p->iBufStart; | |
| 70806 | + p->nBuffer = nBuf; | |
| 70807 | + p->pFile = pFile; | |
| 70808 | + } | |
| 70809 | +} | |
| 70810 | + | |
| 70811 | +/* | |
| 70812 | +** Write nData bytes of data to the file-write object. Return SQLITE_OK | |
| 70813 | +** if successful, or an SQLite error code if an error occurs. | |
| 70814 | +*/ | |
| 70815 | +static void fileWriterWrite(FileWriter *p, u8 *pData, int nData){ | |
| 70816 | + int nRem = nData; | |
| 70817 | + while( nRem>0 && p->eFWErr==0 ){ | |
| 70818 | + int nCopy = nRem; | |
| 70819 | + if( nCopy>(p->nBuffer - p->iBufEnd) ){ | |
| 70820 | + nCopy = p->nBuffer - p->iBufEnd; | |
| 70821 | + } | |
| 70822 | + | |
| 70823 | + memcpy(&p->aBuffer[p->iBufEnd], &pData[nData-nRem], nCopy); | |
| 70824 | + p->iBufEnd += nCopy; | |
| 70825 | + if( p->iBufEnd==p->nBuffer ){ | |
| 70826 | + p->eFWErr = sqlite3OsWrite(p->pFile, | |
| 70827 | + &p->aBuffer[p->iBufStart], p->iBufEnd - p->iBufStart, | |
| 70828 | + p->iWriteOff + p->iBufStart | |
| 70829 | + ); | |
| 70830 | + p->iBufStart = p->iBufEnd = 0; | |
| 70831 | + p->iWriteOff += p->nBuffer; | |
| 70832 | + } | |
| 70833 | + assert( p->iBufEnd<p->nBuffer ); | |
| 70834 | + | |
| 70835 | + nRem -= nCopy; | |
| 70836 | + } | |
| 70837 | +} | |
| 70838 | + | |
| 70839 | +/* | |
| 70840 | +** Flush any buffered data to disk and clean up the file-writer object. | |
| 70841 | +** The results of using the file-writer after this call are undefined. | |
| 70842 | +** Return SQLITE_OK if flushing the buffered data succeeds or is not | |
| 70843 | +** required. Otherwise, return an SQLite error code. | |
| 70844 | +** | |
| 70845 | +** Before returning, set *piEof to the offset immediately following the | |
| 70846 | +** last byte written to the file. | |
| 70847 | +*/ | |
| 70848 | +static int fileWriterFinish(sqlite3 *db, FileWriter *p, i64 *piEof){ | |
| 70849 | + int rc; | |
| 70850 | + if( p->eFWErr==0 && ALWAYS(p->aBuffer) && p->iBufEnd>p->iBufStart ){ | |
| 70851 | + p->eFWErr = sqlite3OsWrite(p->pFile, | |
| 70852 | + &p->aBuffer[p->iBufStart], p->iBufEnd - p->iBufStart, | |
| 70853 | + p->iWriteOff + p->iBufStart | |
| 70854 | + ); | |
| 70855 | + } | |
| 70856 | + *piEof = (p->iWriteOff + p->iBufEnd); | |
| 70857 | + sqlite3DbFree(db, p->aBuffer); | |
| 70858 | + rc = p->eFWErr; | |
| 70859 | + memset(p, 0, sizeof(FileWriter)); | |
| 70860 | + return rc; | |
| 70861 | +} | |
| 70862 | + | |
| 70863 | +/* | |
| 70864 | +** Write value iVal encoded as a varint to the file-write object. Return | |
| 70865 | +** SQLITE_OK if successful, or an SQLite error code if an error occurs. | |
| 70866 | +*/ | |
| 70867 | +static void fileWriterWriteVarint(FileWriter *p, u64 iVal){ | |
| 70868 | + int nByte; | |
| 70869 | + u8 aByte[10]; | |
| 70870 | + nByte = sqlite3PutVarint(aByte, iVal); | |
| 70871 | + fileWriterWrite(p, aByte, nByte); | |
| 70872 | +} | |
| 70673 | 70873 | |
| 70674 | 70874 | /* |
| 70675 | 70875 | ** Write the current contents of the in-memory linked-list to a PMA. Return |
| 70676 | 70876 | ** SQLITE_OK if successful, or an SQLite error code otherwise. |
| 70677 | 70877 | ** |
| @@ -70682,13 +70882,16 @@ | ||
| 70682 | 70882 | ** |
| 70683 | 70883 | ** * One or more records packed end-to-end in order of ascending keys. |
| 70684 | 70884 | ** Each record consists of a varint followed by a blob of data (the |
| 70685 | 70885 | ** key). The varint is the number of bytes in the blob of data. |
| 70686 | 70886 | */ |
| 70687 | -static int vdbeSorterListToPMA(sqlite3 *db, VdbeCursor *pCsr){ | |
| 70887 | +static int vdbeSorterListToPMA(sqlite3 *db, const VdbeCursor *pCsr){ | |
| 70688 | 70888 | int rc = SQLITE_OK; /* Return code */ |
| 70689 | 70889 | VdbeSorter *pSorter = pCsr->pSorter; |
| 70890 | + FileWriter writer; | |
| 70891 | + | |
| 70892 | + memset(&writer, 0, sizeof(FileWriter)); | |
| 70690 | 70893 | |
| 70691 | 70894 | if( pSorter->nInMemory==0 ){ |
| 70692 | 70895 | assert( pSorter->pRecord==0 ); |
| 70693 | 70896 | return rc; |
| 70694 | 70897 | } |
| @@ -70702,43 +70905,24 @@ | ||
| 70702 | 70905 | assert( pSorter->iWriteOff==0 ); |
| 70703 | 70906 | assert( pSorter->nPMA==0 ); |
| 70704 | 70907 | } |
| 70705 | 70908 | |
| 70706 | 70909 | if( rc==SQLITE_OK ){ |
| 70707 | - i64 iOff = pSorter->iWriteOff; | |
| 70708 | 70910 | SorterRecord *p; |
| 70709 | 70911 | SorterRecord *pNext = 0; |
| 70710 | - static const char eightZeros[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; | |
| 70711 | 70912 | |
| 70913 | + fileWriterInit(db, pSorter->pTemp1, &writer, pSorter->iWriteOff); | |
| 70712 | 70914 | pSorter->nPMA++; |
| 70713 | - rc = vdbeSorterWriteVarint(pSorter->pTemp1, pSorter->nInMemory, &iOff); | |
| 70714 | - for(p=pSorter->pRecord; rc==SQLITE_OK && p; p=pNext){ | |
| 70915 | + fileWriterWriteVarint(&writer, pSorter->nInMemory); | |
| 70916 | + for(p=pSorter->pRecord; p; p=pNext){ | |
| 70715 | 70917 | pNext = p->pNext; |
| 70716 | - rc = vdbeSorterWriteVarint(pSorter->pTemp1, p->nVal, &iOff); | |
| 70717 | - | |
| 70718 | - if( rc==SQLITE_OK ){ | |
| 70719 | - rc = sqlite3OsWrite(pSorter->pTemp1, p->pVal, p->nVal, iOff); | |
| 70720 | - iOff += p->nVal; | |
| 70721 | - } | |
| 70722 | - | |
| 70918 | + fileWriterWriteVarint(&writer, p->nVal); | |
| 70919 | + fileWriterWrite(&writer, p->pVal, p->nVal); | |
| 70723 | 70920 | sqlite3DbFree(db, p); |
| 70724 | 70921 | } |
| 70725 | - | |
| 70726 | - /* This assert verifies that unless an error has occurred, the size of | |
| 70727 | - ** the PMA on disk is the same as the expected size stored in | |
| 70728 | - ** pSorter->nInMemory. */ | |
| 70729 | - assert( rc!=SQLITE_OK || pSorter->nInMemory==( | |
| 70730 | - iOff-pSorter->iWriteOff-sqlite3VarintLen(pSorter->nInMemory) | |
| 70731 | - )); | |
| 70732 | - | |
| 70733 | - pSorter->iWriteOff = iOff; | |
| 70734 | - if( rc==SQLITE_OK ){ | |
| 70735 | - /* Terminate each file with 8 extra bytes so that from any offset | |
| 70736 | - ** in the file we can always read 9 bytes without a SHORT_READ error */ | |
| 70737 | - rc = sqlite3OsWrite(pSorter->pTemp1, eightZeros, 8, iOff); | |
| 70738 | - } | |
| 70739 | 70922 | pSorter->pRecord = p; |
| 70923 | + rc = fileWriterFinish(db, &writer, &pSorter->iWriteOff); | |
| 70740 | 70924 | } |
| 70741 | 70925 | |
| 70742 | 70926 | return rc; |
| 70743 | 70927 | } |
| 70744 | 70928 | |
| @@ -70745,11 +70929,11 @@ | ||
| 70745 | 70929 | /* |
| 70746 | 70930 | ** Add a record to the sorter. |
| 70747 | 70931 | */ |
| 70748 | 70932 | SQLITE_PRIVATE int sqlite3VdbeSorterWrite( |
| 70749 | 70933 | sqlite3 *db, /* Database handle */ |
| 70750 | - VdbeCursor *pCsr, /* Sorter cursor */ | |
| 70934 | + const VdbeCursor *pCsr, /* Sorter cursor */ | |
| 70751 | 70935 | Mem *pVal /* Memory cell containing record */ |
| 70752 | 70936 | ){ |
| 70753 | 70937 | VdbeSorter *pSorter = pCsr->pSorter; |
| 70754 | 70938 | int rc = SQLITE_OK; /* Return Code */ |
| 70755 | 70939 | SorterRecord *pNew; /* New list element */ |
| @@ -70779,12 +70963,18 @@ | ||
| 70779 | 70963 | */ |
| 70780 | 70964 | if( rc==SQLITE_OK && pSorter->mxPmaSize>0 && ( |
| 70781 | 70965 | (pSorter->nInMemory>pSorter->mxPmaSize) |
| 70782 | 70966 | || (pSorter->nInMemory>pSorter->mnPmaSize && sqlite3HeapNearlyFull()) |
| 70783 | 70967 | )){ |
| 70968 | +#ifdef SQLITE_DEBUG | |
| 70969 | + i64 nExpect = pSorter->iWriteOff | |
| 70970 | + + sqlite3VarintLen(pSorter->nInMemory) | |
| 70971 | + + pSorter->nInMemory; | |
| 70972 | +#endif | |
| 70784 | 70973 | rc = vdbeSorterListToPMA(db, pCsr); |
| 70785 | 70974 | pSorter->nInMemory = 0; |
| 70975 | + assert( rc!=SQLITE_OK || (nExpect==pSorter->iWriteOff) ); | |
| 70786 | 70976 | } |
| 70787 | 70977 | |
| 70788 | 70978 | return rc; |
| 70789 | 70979 | } |
| 70790 | 70980 | |
| @@ -70791,11 +70981,11 @@ | ||
| 70791 | 70981 | /* |
| 70792 | 70982 | ** Helper function for sqlite3VdbeSorterRewind(). |
| 70793 | 70983 | */ |
| 70794 | 70984 | static int vdbeSorterInitMerge( |
| 70795 | 70985 | sqlite3 *db, /* Database handle */ |
| 70796 | - VdbeCursor *pCsr, /* Cursor handle for this sorter */ | |
| 70986 | + const VdbeCursor *pCsr, /* Cursor handle for this sorter */ | |
| 70797 | 70987 | i64 *pnByte /* Sum of bytes in all opened PMAs */ |
| 70798 | 70988 | ){ |
| 70799 | 70989 | VdbeSorter *pSorter = pCsr->pSorter; |
| 70800 | 70990 | int rc = SQLITE_OK; /* Return code */ |
| 70801 | 70991 | int i; /* Used to iterator through aIter[] */ |
| @@ -70821,11 +71011,11 @@ | ||
| 70821 | 71011 | |
| 70822 | 71012 | /* |
| 70823 | 71013 | ** Once the sorter has been populated, this function is called to prepare |
| 70824 | 71014 | ** for iterating through its contents in sorted order. |
| 70825 | 71015 | */ |
| 70826 | -SQLITE_PRIVATE int sqlite3VdbeSorterRewind(sqlite3 *db, VdbeCursor *pCsr, int *pbEof){ | |
| 71016 | +SQLITE_PRIVATE int sqlite3VdbeSorterRewind(sqlite3 *db, const VdbeCursor *pCsr, int *pbEof){ | |
| 70827 | 71017 | VdbeSorter *pSorter = pCsr->pSorter; |
| 70828 | 71018 | int rc; /* Return code */ |
| 70829 | 71019 | sqlite3_file *pTemp2 = 0; /* Second temp file to use */ |
| 70830 | 71020 | i64 iWrite2 = 0; /* Write offset for pTemp2 */ |
| 70831 | 71021 | int nIter; /* Number of iterators used */ |
| @@ -70841,11 +71031,11 @@ | ||
| 70841 | 71031 | *pbEof = !pSorter->pRecord; |
| 70842 | 71032 | assert( pSorter->aTree==0 ); |
| 70843 | 71033 | return vdbeSorterSort(pCsr); |
| 70844 | 71034 | } |
| 70845 | 71035 | |
| 70846 | - /* Write the current b-tree to a PMA. Close the b-tree cursor. */ | |
| 71036 | + /* Write the current in-memory list to a PMA. */ | |
| 70847 | 71037 | rc = vdbeSorterListToPMA(db, pCsr); |
| 70848 | 71038 | if( rc!=SQLITE_OK ) return rc; |
| 70849 | 71039 | |
| 70850 | 71040 | /* Allocate space for aIter[] and aTree[]. */ |
| 70851 | 71041 | nIter = pSorter->nPMA; |
| @@ -70863,11 +71053,15 @@ | ||
| 70863 | 71053 | |
| 70864 | 71054 | for(iNew=0; |
| 70865 | 71055 | rc==SQLITE_OK && iNew*SORTER_MAX_MERGE_COUNT<pSorter->nPMA; |
| 70866 | 71056 | iNew++ |
| 70867 | 71057 | ){ |
| 71058 | + int rc2; /* Return code from fileWriterFinish() */ | |
| 71059 | + FileWriter writer; /* Object used to write to disk */ | |
| 70868 | 71060 | i64 nWrite; /* Number of bytes in new PMA */ |
| 71061 | + | |
| 71062 | + memset(&writer, 0, sizeof(FileWriter)); | |
| 70869 | 71063 | |
| 70870 | 71064 | /* If there are SORTER_MAX_MERGE_COUNT or less PMAs in file pTemp1, |
| 70871 | 71065 | ** initialize an iterator for each of them and break out of the loop. |
| 70872 | 71066 | ** These iterators will be incrementally merged as the VDBE layer calls |
| 70873 | 71067 | ** sqlite3VdbeSorterNext(). |
| @@ -70886,27 +71080,24 @@ | ||
| 70886 | 71080 | if( pTemp2==0 ){ |
| 70887 | 71081 | assert( iWrite2==0 ); |
| 70888 | 71082 | rc = vdbeSorterOpenTempFile(db, &pTemp2); |
| 70889 | 71083 | } |
| 70890 | 71084 | |
| 70891 | - if( rc==SQLITE_OK ){ | |
| 70892 | - rc = vdbeSorterWriteVarint(pTemp2, nWrite, &iWrite2); | |
| 70893 | - } | |
| 70894 | - | |
| 70895 | 71085 | if( rc==SQLITE_OK ){ |
| 70896 | 71086 | int bEof = 0; |
| 71087 | + fileWriterInit(db, pTemp2, &writer, iWrite2); | |
| 71088 | + fileWriterWriteVarint(&writer, nWrite); | |
| 70897 | 71089 | while( rc==SQLITE_OK && bEof==0 ){ |
| 70898 | - int nToWrite; | |
| 70899 | 71090 | VdbeSorterIter *pIter = &pSorter->aIter[ pSorter->aTree[1] ]; |
| 70900 | 71091 | assert( pIter->pFile ); |
| 70901 | - nToWrite = pIter->nKey + sqlite3VarintLen(pIter->nKey); | |
| 70902 | - rc = sqlite3OsWrite(pTemp2, pIter->aAlloc, nToWrite, iWrite2); | |
| 70903 | - iWrite2 += nToWrite; | |
| 70904 | - if( rc==SQLITE_OK ){ | |
| 70905 | - rc = sqlite3VdbeSorterNext(db, pCsr, &bEof); | |
| 70906 | - } | |
| 71092 | + | |
| 71093 | + fileWriterWriteVarint(&writer, pIter->nKey); | |
| 71094 | + fileWriterWrite(&writer, pIter->aKey, pIter->nKey); | |
| 71095 | + rc = sqlite3VdbeSorterNext(db, pCsr, &bEof); | |
| 70907 | 71096 | } |
| 71097 | + rc2 = fileWriterFinish(db, &writer, &iWrite2); | |
| 71098 | + if( rc==SQLITE_OK ) rc = rc2; | |
| 70908 | 71099 | } |
| 70909 | 71100 | } |
| 70910 | 71101 | |
| 70911 | 71102 | if( pSorter->nPMA<=SORTER_MAX_MERGE_COUNT ){ |
| 70912 | 71103 | break; |
| @@ -70929,11 +71120,11 @@ | ||
| 70929 | 71120 | } |
| 70930 | 71121 | |
| 70931 | 71122 | /* |
| 70932 | 71123 | ** Advance to the next element in the sorter. |
| 70933 | 71124 | */ |
| 70934 | -SQLITE_PRIVATE int sqlite3VdbeSorterNext(sqlite3 *db, VdbeCursor *pCsr, int *pbEof){ | |
| 71125 | +SQLITE_PRIVATE int sqlite3VdbeSorterNext(sqlite3 *db, const VdbeCursor *pCsr, int *pbEof){ | |
| 70935 | 71126 | VdbeSorter *pSorter = pCsr->pSorter; |
| 70936 | 71127 | int rc; /* Return code */ |
| 70937 | 71128 | |
| 70938 | 71129 | if( pSorter->aTree ){ |
| 70939 | 71130 | int iPrev = pSorter->aTree[1];/* Index of iterator to advance */ |
| @@ -70959,11 +71150,11 @@ | ||
| 70959 | 71150 | /* |
| 70960 | 71151 | ** Return a pointer to a buffer owned by the sorter that contains the |
| 70961 | 71152 | ** current key. |
| 70962 | 71153 | */ |
| 70963 | 71154 | static void *vdbeSorterRowkey( |
| 70964 | - VdbeSorter *pSorter, /* Sorter object */ | |
| 71155 | + const VdbeSorter *pSorter, /* Sorter object */ | |
| 70965 | 71156 | int *pnKey /* OUT: Size of current key in bytes */ |
| 70966 | 71157 | ){ |
| 70967 | 71158 | void *pKey; |
| 70968 | 71159 | if( pSorter->aTree ){ |
| 70969 | 71160 | VdbeSorterIter *pIter; |
| @@ -70978,11 +71169,11 @@ | ||
| 70978 | 71169 | } |
| 70979 | 71170 | |
| 70980 | 71171 | /* |
| 70981 | 71172 | ** Copy the current sorter key into the memory cell pOut. |
| 70982 | 71173 | */ |
| 70983 | -SQLITE_PRIVATE int sqlite3VdbeSorterRowkey(VdbeCursor *pCsr, Mem *pOut){ | |
| 71174 | +SQLITE_PRIVATE int sqlite3VdbeSorterRowkey(const VdbeCursor *pCsr, Mem *pOut){ | |
| 70984 | 71175 | VdbeSorter *pSorter = pCsr->pSorter; |
| 70985 | 71176 | void *pKey; int nKey; /* Sorter key to copy into pOut */ |
| 70986 | 71177 | |
| 70987 | 71178 | pKey = vdbeSorterRowkey(pSorter, &nKey); |
| 70988 | 71179 | if( sqlite3VdbeMemGrow(pOut, nKey, 0) ){ |
| @@ -71004,11 +71195,11 @@ | ||
| 71004 | 71195 | ** Otherwise, set *pRes to a negative, zero or positive value if the |
| 71005 | 71196 | ** key in pVal is smaller than, equal to or larger than the current sorter |
| 71006 | 71197 | ** key. |
| 71007 | 71198 | */ |
| 71008 | 71199 | SQLITE_PRIVATE int sqlite3VdbeSorterCompare( |
| 71009 | - VdbeCursor *pCsr, /* Sorter cursor */ | |
| 71200 | + const VdbeCursor *pCsr, /* Sorter cursor */ | |
| 71010 | 71201 | Mem *pVal, /* Value to compare to current sorter key */ |
| 71011 | 71202 | int *pRes /* OUT: Result of comparison */ |
| 71012 | 71203 | ){ |
| 71013 | 71204 | VdbeSorter *pSorter = pCsr->pSorter; |
| 71014 | 71205 | void *pKey; int nKey; /* Sorter key to compare pVal with */ |
| @@ -74591,11 +74782,11 @@ | ||
| 74591 | 74782 | SelectDest dest; |
| 74592 | 74783 | ExprList *pEList; |
| 74593 | 74784 | |
| 74594 | 74785 | assert( !isRowid ); |
| 74595 | 74786 | sqlite3SelectDestInit(&dest, SRT_Set, pExpr->iTable); |
| 74596 | - dest.affinity = (u8)affinity; | |
| 74787 | + dest.affSdst = (u8)affinity; | |
| 74597 | 74788 | assert( (pExpr->iTable&0x0000FFFF)==pExpr->iTable ); |
| 74598 | 74789 | pExpr->x.pSelect->iLimit = 0; |
| 74599 | 74790 | if( sqlite3Select(pParse, pExpr->x.pSelect, &dest) ){ |
| 74600 | 74791 | return 0; |
| 74601 | 74792 | } |
| @@ -74684,25 +74875,25 @@ | ||
| 74684 | 74875 | assert( ExprHasProperty(pExpr, EP_xIsSelect) ); |
| 74685 | 74876 | pSel = pExpr->x.pSelect; |
| 74686 | 74877 | sqlite3SelectDestInit(&dest, 0, ++pParse->nMem); |
| 74687 | 74878 | if( pExpr->op==TK_SELECT ){ |
| 74688 | 74879 | dest.eDest = SRT_Mem; |
| 74689 | - sqlite3VdbeAddOp2(v, OP_Null, 0, dest.iParm); | |
| 74880 | + sqlite3VdbeAddOp2(v, OP_Null, 0, dest.iSDParm); | |
| 74690 | 74881 | VdbeComment((v, "Init subquery result")); |
| 74691 | 74882 | }else{ |
| 74692 | 74883 | dest.eDest = SRT_Exists; |
| 74693 | - sqlite3VdbeAddOp2(v, OP_Integer, 0, dest.iParm); | |
| 74884 | + sqlite3VdbeAddOp2(v, OP_Integer, 0, dest.iSDParm); | |
| 74694 | 74885 | VdbeComment((v, "Init EXISTS result")); |
| 74695 | 74886 | } |
| 74696 | 74887 | sqlite3ExprDelete(pParse->db, pSel->pLimit); |
| 74697 | 74888 | pSel->pLimit = sqlite3PExpr(pParse, TK_INTEGER, 0, 0, |
| 74698 | 74889 | &sqlite3IntTokens[1]); |
| 74699 | 74890 | pSel->iLimit = 0; |
| 74700 | 74891 | if( sqlite3Select(pParse, pSel, &dest) ){ |
| 74701 | 74892 | return 0; |
| 74702 | 74893 | } |
| 74703 | - rReg = dest.iParm; | |
| 74894 | + rReg = dest.iSDParm; | |
| 74704 | 74895 | ExprSetIrreducible(pExpr); |
| 74705 | 74896 | break; |
| 74706 | 74897 | } |
| 74707 | 74898 | } |
| 74708 | 74899 | |
| @@ -78012,11 +78203,11 @@ | ||
| 78012 | 78203 | ** because the OpenWrite opcode below will be needing it. */ |
| 78013 | 78204 | sqlite3NestedParse(pParse, |
| 78014 | 78205 | "CREATE TABLE %Q.%s(%s)", pDb->zName, zTab, aTable[i].zCols |
| 78015 | 78206 | ); |
| 78016 | 78207 | aRoot[i] = pParse->regRoot; |
| 78017 | - aCreateTbl[i] = 1; | |
| 78208 | + aCreateTbl[i] = OPFLAG_P2ISREG; | |
| 78018 | 78209 | }else{ |
| 78019 | 78210 | /* The table already exists. If zWhere is not NULL, delete all entries |
| 78020 | 78211 | ** associated with the table zWhere. If zWhere is NULL, delete the |
| 78021 | 78212 | ** entire contents of the table. */ |
| 78022 | 78213 | aRoot[i] = pStat->tnum; |
| @@ -78092,16 +78283,15 @@ | ||
| 78092 | 78283 | |
| 78093 | 78284 | UNUSED_PARAMETER(argc); |
| 78094 | 78285 | nRow = (tRowcnt)sqlite3_value_int64(argv[0]); |
| 78095 | 78286 | mxSample = sqlite3_value_int(argv[1]); |
| 78096 | 78287 | n = sizeof(*p) + sizeof(p->a[0])*mxSample; |
| 78097 | - p = sqlite3_malloc( n ); | |
| 78288 | + p = sqlite3MallocZero( n ); | |
| 78098 | 78289 | if( p==0 ){ |
| 78099 | 78290 | sqlite3_result_error_nomem(context); |
| 78100 | 78291 | return; |
| 78101 | 78292 | } |
| 78102 | - memset(p, 0, n); | |
| 78103 | 78293 | p->a = (struct Stat3Sample*)&p[1]; |
| 78104 | 78294 | p->nRow = nRow; |
| 78105 | 78295 | p->mxSample = mxSample; |
| 78106 | 78296 | p->nPSample = p->nRow/(mxSample/3+1) + 1; |
| 78107 | 78297 | sqlite3_randomness(sizeof(p->iPrn), &p->iPrn); |
| @@ -81354,11 +81544,11 @@ | ||
| 81354 | 81544 | SelectDest dest; |
| 81355 | 81545 | Table *pSelTab; |
| 81356 | 81546 | |
| 81357 | 81547 | assert(pParse->nTab==1); |
| 81358 | 81548 | sqlite3VdbeAddOp3(v, OP_OpenWrite, 1, pParse->regRoot, iDb); |
| 81359 | - sqlite3VdbeChangeP5(v, 1); | |
| 81549 | + sqlite3VdbeChangeP5(v, OPFLAG_P2ISREG); | |
| 81360 | 81550 | pParse->nTab = 2; |
| 81361 | 81551 | sqlite3SelectDestInit(&dest, SRT_Table, 1); |
| 81362 | 81552 | sqlite3Select(pParse, pSelect, &dest); |
| 81363 | 81553 | sqlite3VdbeAddOp1(v, OP_Close, 1); |
| 81364 | 81554 | if( pParse->nErr==0 ){ |
| @@ -82170,13 +82360,11 @@ | ||
| 82170 | 82360 | sqlite3VdbeAddOp2(v, OP_Clear, tnum, iDb); |
| 82171 | 82361 | } |
| 82172 | 82362 | pKey = sqlite3IndexKeyinfo(pParse, pIndex); |
| 82173 | 82363 | sqlite3VdbeAddOp4(v, OP_OpenWrite, iIdx, tnum, iDb, |
| 82174 | 82364 | (char *)pKey, P4_KEYINFO_HANDOFF); |
| 82175 | - if( memRootPage>=0 ){ | |
| 82176 | - sqlite3VdbeChangeP5(v, 1); | |
| 82177 | - } | |
| 82365 | + sqlite3VdbeChangeP5(v, OPFLAG_BULKCSR|((memRootPage>=0)?OPFLAG_P2ISREG:0)); | |
| 82178 | 82366 | |
| 82179 | 82367 | #ifndef SQLITE_OMIT_MERGE_SORT |
| 82180 | 82368 | /* Open the sorter cursor if we are to use one. */ |
| 82181 | 82369 | iSorter = pParse->nTab++; |
| 82182 | 82370 | sqlite3VdbeAddOp4(v, OP_SorterOpen, iSorter, 0, 0, (char*)pKey, P4_KEYINFO); |
| @@ -88191,11 +88379,11 @@ | ||
| 88191 | 88379 | regEof = ++pParse->nMem; |
| 88192 | 88380 | sqlite3VdbeAddOp2(v, OP_Integer, 0, regEof); /* EOF <- 0 */ |
| 88193 | 88381 | VdbeComment((v, "SELECT eof flag")); |
| 88194 | 88382 | sqlite3SelectDestInit(&dest, SRT_Coroutine, ++pParse->nMem); |
| 88195 | 88383 | addrSelect = sqlite3VdbeCurrentAddr(v)+2; |
| 88196 | - sqlite3VdbeAddOp2(v, OP_Integer, addrSelect-1, dest.iParm); | |
| 88384 | + sqlite3VdbeAddOp2(v, OP_Integer, addrSelect-1, dest.iSDParm); | |
| 88197 | 88385 | j1 = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0); |
| 88198 | 88386 | VdbeComment((v, "Jump over SELECT coroutine")); |
| 88199 | 88387 | |
| 88200 | 88388 | /* Resolve the expressions in the SELECT statement and execute it. */ |
| 88201 | 88389 | rc = sqlite3Select(pParse, pSelect, &dest); |
| @@ -88202,19 +88390,19 @@ | ||
| 88202 | 88390 | assert( pParse->nErr==0 || rc ); |
| 88203 | 88391 | if( rc || NEVER(pParse->nErr) || db->mallocFailed ){ |
| 88204 | 88392 | goto insert_cleanup; |
| 88205 | 88393 | } |
| 88206 | 88394 | sqlite3VdbeAddOp2(v, OP_Integer, 1, regEof); /* EOF <- 1 */ |
| 88207 | - sqlite3VdbeAddOp1(v, OP_Yield, dest.iParm); /* yield X */ | |
| 88395 | + sqlite3VdbeAddOp1(v, OP_Yield, dest.iSDParm); /* yield X */ | |
| 88208 | 88396 | sqlite3VdbeAddOp2(v, OP_Halt, SQLITE_INTERNAL, OE_Abort); |
| 88209 | 88397 | VdbeComment((v, "End of SELECT coroutine")); |
| 88210 | 88398 | sqlite3VdbeJumpHere(v, j1); /* label B: */ |
| 88211 | 88399 | |
| 88212 | - regFromSelect = dest.iMem; | |
| 88400 | + regFromSelect = dest.iSdst; | |
| 88213 | 88401 | assert( pSelect->pEList ); |
| 88214 | 88402 | nColumn = pSelect->pEList->nExpr; |
| 88215 | - assert( dest.nMem==nColumn ); | |
| 88403 | + assert( dest.nSdst==nColumn ); | |
| 88216 | 88404 | |
| 88217 | 88405 | /* Set useTempTable to TRUE if the result of the SELECT statement |
| 88218 | 88406 | ** should be written into a temporary table (template 4). Set to |
| 88219 | 88407 | ** FALSE if each* row of the SELECT can be written directly into |
| 88220 | 88408 | ** the destination table (template 3). |
| @@ -88246,11 +88434,11 @@ | ||
| 88246 | 88434 | |
| 88247 | 88435 | srcTab = pParse->nTab++; |
| 88248 | 88436 | regRec = sqlite3GetTempReg(pParse); |
| 88249 | 88437 | regTempRowid = sqlite3GetTempReg(pParse); |
| 88250 | 88438 | sqlite3VdbeAddOp2(v, OP_OpenEphemeral, srcTab, nColumn); |
| 88251 | - addrTop = sqlite3VdbeAddOp1(v, OP_Yield, dest.iParm); | |
| 88439 | + addrTop = sqlite3VdbeAddOp1(v, OP_Yield, dest.iSDParm); | |
| 88252 | 88440 | addrIf = sqlite3VdbeAddOp1(v, OP_If, regEof); |
| 88253 | 88441 | sqlite3VdbeAddOp3(v, OP_MakeRecord, regFromSelect, nColumn, regRec); |
| 88254 | 88442 | sqlite3VdbeAddOp2(v, OP_NewRowid, srcTab, regTempRowid); |
| 88255 | 88443 | sqlite3VdbeAddOp3(v, OP_Insert, srcTab, regRec, regTempRowid); |
| 88256 | 88444 | sqlite3VdbeAddOp2(v, OP_Goto, 0, addrTop); |
| @@ -88383,11 +88571,11 @@ | ||
| 88383 | 88571 | ** if EOF goto D |
| 88384 | 88572 | ** insert the select result into <table> from R..R+n |
| 88385 | 88573 | ** goto C |
| 88386 | 88574 | ** D: ... |
| 88387 | 88575 | */ |
| 88388 | - addrCont = sqlite3VdbeAddOp1(v, OP_Yield, dest.iParm); | |
| 88576 | + addrCont = sqlite3VdbeAddOp1(v, OP_Yield, dest.iSDParm); | |
| 88389 | 88577 | addrInsTop = sqlite3VdbeAddOp1(v, OP_If, regEof); |
| 88390 | 88578 | } |
| 88391 | 88579 | |
| 88392 | 88580 | /* Allocate registers for holding the rowid of the new row, |
| 88393 | 88581 | ** the content of the new row, and the assemblied row record. |
| @@ -91865,10 +92053,23 @@ | ||
| 91865 | 92053 | { OP_String8, 0, 3, 0}, /* 2 */ |
| 91866 | 92054 | { OP_ResultRow, 3, 1, 0}, |
| 91867 | 92055 | }; |
| 91868 | 92056 | |
| 91869 | 92057 | int isQuick = (sqlite3Tolower(zLeft[0])=='q'); |
| 92058 | + | |
| 92059 | + /* If the PRAGMA command was of the form "PRAGMA <db>.integrity_check", | |
| 92060 | + ** then iDb is set to the index of the database identified by <db>. | |
| 92061 | + ** In this case, the integrity of database iDb only is verified by | |
| 92062 | + ** the VDBE created below. | |
| 92063 | + ** | |
| 92064 | + ** Otherwise, if the command was simply "PRAGMA integrity_check" (or | |
| 92065 | + ** "PRAGMA quick_check"), then iDb is set to 0. In this case, set iDb | |
| 92066 | + ** to -1 here, to indicate that the VDBE should verify the integrity | |
| 92067 | + ** of all attached databases. */ | |
| 92068 | + assert( iDb>=0 ); | |
| 92069 | + assert( iDb==0 || pId2->z ); | |
| 92070 | + if( pId2->z==0 ) iDb = -1; | |
| 91870 | 92071 | |
| 91871 | 92072 | /* Initialize the VDBE program */ |
| 91872 | 92073 | if( sqlite3ReadSchema(pParse) ) goto pragma_out; |
| 91873 | 92074 | pParse->nMem = 6; |
| 91874 | 92075 | sqlite3VdbeSetNumCols(v, 1); |
| @@ -91889,10 +92090,11 @@ | ||
| 91889 | 92090 | HashElem *x; |
| 91890 | 92091 | Hash *pTbls; |
| 91891 | 92092 | int cnt = 0; |
| 91892 | 92093 | |
| 91893 | 92094 | if( OMIT_TEMPDB && i==1 ) continue; |
| 92095 | + if( iDb>=0 && i!=iDb ) continue; | |
| 91894 | 92096 | |
| 91895 | 92097 | sqlite3CodeVerifySchema(pParse, i); |
| 91896 | 92098 | addr = sqlite3VdbeAddOp1(v, OP_IfPos, 1); /* Halt if out of errors */ |
| 91897 | 92099 | sqlite3VdbeAddOp2(v, OP_Halt, 0, 0); |
| 91898 | 92100 | sqlite3VdbeJumpHere(v, addr); |
| @@ -91900,11 +92102,11 @@ | ||
| 91900 | 92102 | /* Do an integrity check of the B-Tree |
| 91901 | 92103 | ** |
| 91902 | 92104 | ** Begin by filling registers 2, 3, ... with the root pages numbers |
| 91903 | 92105 | ** for all tables and indices in the database. |
| 91904 | 92106 | */ |
| 91905 | - assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); | |
| 92107 | + assert( sqlite3SchemaMutexHeld(db, i, 0) ); | |
| 91906 | 92108 | pTbls = &db->aDb[i].pSchema->tblHash; |
| 91907 | 92109 | for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){ |
| 91908 | 92110 | Table *pTab = sqliteHashData(x); |
| 91909 | 92111 | Index *pIdx; |
| 91910 | 92112 | sqlite3VdbeAddOp2(v, OP_Integer, pTab->tnum, 2+cnt); |
| @@ -93224,14 +93426,14 @@ | ||
| 93224 | 93426 | /* |
| 93225 | 93427 | ** Initialize a SelectDest structure. |
| 93226 | 93428 | */ |
| 93227 | 93429 | SQLITE_PRIVATE void sqlite3SelectDestInit(SelectDest *pDest, int eDest, int iParm){ |
| 93228 | 93430 | pDest->eDest = (u8)eDest; |
| 93229 | - pDest->iParm = iParm; | |
| 93230 | - pDest->affinity = 0; | |
| 93231 | - pDest->iMem = 0; | |
| 93232 | - pDest->nMem = 0; | |
| 93431 | + pDest->iSDParm = iParm; | |
| 93432 | + pDest->affSdst = 0; | |
| 93433 | + pDest->iSdst = 0; | |
| 93434 | + pDest->nSdst = 0; | |
| 93233 | 93435 | } |
| 93234 | 93436 | |
| 93235 | 93437 | |
| 93236 | 93438 | /* |
| 93237 | 93439 | ** Allocate a new Select structure and return a pointer to that |
| @@ -93739,11 +93941,11 @@ | ||
| 93739 | 93941 | Vdbe *v = pParse->pVdbe; |
| 93740 | 93942 | int i; |
| 93741 | 93943 | int hasDistinct; /* True if the DISTINCT keyword is present */ |
| 93742 | 93944 | int regResult; /* Start of memory holding result set */ |
| 93743 | 93945 | int eDest = pDest->eDest; /* How to dispose of results */ |
| 93744 | - int iParm = pDest->iParm; /* First argument to disposal method */ | |
| 93946 | + int iParm = pDest->iSDParm; /* First argument to disposal method */ | |
| 93745 | 93947 | int nResultCol; /* Number of result columns */ |
| 93746 | 93948 | |
| 93747 | 93949 | assert( v ); |
| 93748 | 93950 | if( NEVER(v==0) ) return; |
| 93749 | 93951 | assert( pEList!=0 ); |
| @@ -93757,18 +93959,18 @@ | ||
| 93757 | 93959 | if( nColumn>0 ){ |
| 93758 | 93960 | nResultCol = nColumn; |
| 93759 | 93961 | }else{ |
| 93760 | 93962 | nResultCol = pEList->nExpr; |
| 93761 | 93963 | } |
| 93762 | - if( pDest->iMem==0 ){ | |
| 93763 | - pDest->iMem = pParse->nMem+1; | |
| 93764 | - pDest->nMem = nResultCol; | |
| 93964 | + if( pDest->iSdst==0 ){ | |
| 93965 | + pDest->iSdst = pParse->nMem+1; | |
| 93966 | + pDest->nSdst = nResultCol; | |
| 93765 | 93967 | pParse->nMem += nResultCol; |
| 93766 | 93968 | }else{ |
| 93767 | - assert( pDest->nMem==nResultCol ); | |
| 93969 | + assert( pDest->nSdst==nResultCol ); | |
| 93768 | 93970 | } |
| 93769 | - regResult = pDest->iMem; | |
| 93971 | + regResult = pDest->iSdst; | |
| 93770 | 93972 | if( nColumn>0 ){ |
| 93771 | 93973 | for(i=0; i<nColumn; i++){ |
| 93772 | 93974 | sqlite3VdbeAddOp3(v, OP_Column, srcTab, i, regResult+i); |
| 93773 | 93975 | } |
| 93774 | 93976 | }else if( eDest!=SRT_Exists ){ |
| @@ -93843,11 +94045,11 @@ | ||
| 93843 | 94045 | ** then there should be a single item on the stack. Write this |
| 93844 | 94046 | ** item into the set table with bogus data. |
| 93845 | 94047 | */ |
| 93846 | 94048 | case SRT_Set: { |
| 93847 | 94049 | assert( nColumn==1 ); |
| 93848 | - p->affinity = sqlite3CompareAffinity(pEList->a[0].pExpr, pDest->affinity); | |
| 94050 | + p->affinity = sqlite3CompareAffinity(pEList->a[0].pExpr, pDest->affSdst); | |
| 93849 | 94051 | if( pOrderBy ){ |
| 93850 | 94052 | /* At first glance you would think we could optimize out the |
| 93851 | 94053 | ** ORDER BY in this case since the order of entries in the set |
| 93852 | 94054 | ** does not matter. But there might be a LIMIT clause, in which |
| 93853 | 94055 | ** case the order does matter */ |
| @@ -93898,11 +94100,11 @@ | ||
| 93898 | 94100 | int r1 = sqlite3GetTempReg(pParse); |
| 93899 | 94101 | sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nColumn, r1); |
| 93900 | 94102 | pushOntoSorter(pParse, pOrderBy, p, r1); |
| 93901 | 94103 | sqlite3ReleaseTempReg(pParse, r1); |
| 93902 | 94104 | }else if( eDest==SRT_Coroutine ){ |
| 93903 | - sqlite3VdbeAddOp1(v, OP_Yield, pDest->iParm); | |
| 94105 | + sqlite3VdbeAddOp1(v, OP_Yield, pDest->iSDParm); | |
| 93904 | 94106 | }else{ |
| 93905 | 94107 | sqlite3VdbeAddOp2(v, OP_ResultRow, regResult, nColumn); |
| 93906 | 94108 | sqlite3ExprCacheAffinityChange(pParse, regResult, nColumn); |
| 93907 | 94109 | } |
| 93908 | 94110 | break; |
| @@ -94078,11 +94280,11 @@ | ||
| 94078 | 94280 | int iTab; |
| 94079 | 94281 | int pseudoTab = 0; |
| 94080 | 94282 | ExprList *pOrderBy = p->pOrderBy; |
| 94081 | 94283 | |
| 94082 | 94284 | int eDest = pDest->eDest; |
| 94083 | - int iParm = pDest->iParm; | |
| 94285 | + int iParm = pDest->iSDParm; | |
| 94084 | 94286 | |
| 94085 | 94287 | int regRow; |
| 94086 | 94288 | int regRowid; |
| 94087 | 94289 | |
| 94088 | 94290 | iTab = pOrderBy->iECursor; |
| @@ -94137,21 +94339,21 @@ | ||
| 94137 | 94339 | int i; |
| 94138 | 94340 | assert( eDest==SRT_Output || eDest==SRT_Coroutine ); |
| 94139 | 94341 | testcase( eDest==SRT_Output ); |
| 94140 | 94342 | testcase( eDest==SRT_Coroutine ); |
| 94141 | 94343 | for(i=0; i<nColumn; i++){ |
| 94142 | - assert( regRow!=pDest->iMem+i ); | |
| 94143 | - sqlite3VdbeAddOp3(v, OP_Column, pseudoTab, i, pDest->iMem+i); | |
| 94344 | + assert( regRow!=pDest->iSdst+i ); | |
| 94345 | + sqlite3VdbeAddOp3(v, OP_Column, pseudoTab, i, pDest->iSdst+i); | |
| 94144 | 94346 | if( i==0 ){ |
| 94145 | 94347 | sqlite3VdbeChangeP5(v, OPFLAG_CLEARCACHE); |
| 94146 | 94348 | } |
| 94147 | 94349 | } |
| 94148 | 94350 | if( eDest==SRT_Output ){ |
| 94149 | - sqlite3VdbeAddOp2(v, OP_ResultRow, pDest->iMem, nColumn); | |
| 94150 | - sqlite3ExprCacheAffinityChange(pParse, pDest->iMem, nColumn); | |
| 94351 | + sqlite3VdbeAddOp2(v, OP_ResultRow, pDest->iSdst, nColumn); | |
| 94352 | + sqlite3ExprCacheAffinityChange(pParse, pDest->iSdst, nColumn); | |
| 94151 | 94353 | }else{ |
| 94152 | - sqlite3VdbeAddOp1(v, OP_Yield, pDest->iParm); | |
| 94354 | + sqlite3VdbeAddOp1(v, OP_Yield, pDest->iSDParm); | |
| 94153 | 94355 | } |
| 94154 | 94356 | break; |
| 94155 | 94357 | } |
| 94156 | 94358 | } |
| 94157 | 94359 | sqlite3ReleaseTempReg(pParse, regRow); |
| @@ -94798,11 +95000,11 @@ | ||
| 94798 | 95000 | |
| 94799 | 95001 | /* Create the destination temporary table if necessary |
| 94800 | 95002 | */ |
| 94801 | 95003 | if( dest.eDest==SRT_EphemTab ){ |
| 94802 | 95004 | assert( p->pEList ); |
| 94803 | - sqlite3VdbeAddOp2(v, OP_OpenEphemeral, dest.iParm, p->pEList->nExpr); | |
| 95005 | + sqlite3VdbeAddOp2(v, OP_OpenEphemeral, dest.iSDParm, p->pEList->nExpr); | |
| 94804 | 95006 | sqlite3VdbeChangeP5(v, BTREE_UNORDERED); |
| 94805 | 95007 | dest.eDest = SRT_Table; |
| 94806 | 95008 | } |
| 94807 | 95009 | |
| 94808 | 95010 | /* Make sure all SELECTs in the statement have the same number of elements |
| @@ -94884,11 +95086,11 @@ | ||
| 94884 | 95086 | */ |
| 94885 | 95087 | assert( p->pRightmost!=p ); /* Can only happen for leftward elements |
| 94886 | 95088 | ** of a 3-way or more compound */ |
| 94887 | 95089 | assert( p->pLimit==0 ); /* Not allowed on leftward elements */ |
| 94888 | 95090 | assert( p->pOffset==0 ); /* Not allowed on leftward elements */ |
| 94889 | - unionTab = dest.iParm; | |
| 95091 | + unionTab = dest.iSDParm; | |
| 94890 | 95092 | }else{ |
| 94891 | 95093 | /* We will need to create our own temporary table to hold the |
| 94892 | 95094 | ** intermediate results. |
| 94893 | 95095 | */ |
| 94894 | 95096 | unionTab = pParse->nTab++; |
| @@ -94941,11 +95143,11 @@ | ||
| 94941 | 95143 | p->iOffset = 0; |
| 94942 | 95144 | |
| 94943 | 95145 | /* Convert the data in the temporary table into whatever form |
| 94944 | 95146 | ** it is that we currently need. |
| 94945 | 95147 | */ |
| 94946 | - assert( unionTab==dest.iParm || dest.eDest!=priorOp ); | |
| 95148 | + assert( unionTab==dest.iSDParm || dest.eDest!=priorOp ); | |
| 94947 | 95149 | if( dest.eDest!=priorOp ){ |
| 94948 | 95150 | int iCont, iBreak, iStart; |
| 94949 | 95151 | assert( p->pEList ); |
| 94950 | 95152 | if( dest.eDest==SRT_Output ){ |
| 94951 | 95153 | Select *pFirst = p; |
| @@ -95005,11 +95207,11 @@ | ||
| 95005 | 95207 | p->pPrior = 0; |
| 95006 | 95208 | pLimit = p->pLimit; |
| 95007 | 95209 | p->pLimit = 0; |
| 95008 | 95210 | pOffset = p->pOffset; |
| 95009 | 95211 | p->pOffset = 0; |
| 95010 | - intersectdest.iParm = tab2; | |
| 95212 | + intersectdest.iSDParm = tab2; | |
| 95011 | 95213 | explainSetInteger(iSub2, pParse->iNextSelectId); |
| 95012 | 95214 | rc = sqlite3Select(pParse, p, &intersectdest); |
| 95013 | 95215 | testcase( rc!=SQLITE_OK ); |
| 95014 | 95216 | pDelete = p->pPrior; |
| 95015 | 95217 | p->pPrior = pPrior; |
| @@ -95099,23 +95301,23 @@ | ||
| 95099 | 95301 | } |
| 95100 | 95302 | sqlite3DbFree(db, pKeyInfo); |
| 95101 | 95303 | } |
| 95102 | 95304 | |
| 95103 | 95305 | multi_select_end: |
| 95104 | - pDest->iMem = dest.iMem; | |
| 95105 | - pDest->nMem = dest.nMem; | |
| 95306 | + pDest->iSdst = dest.iSdst; | |
| 95307 | + pDest->nSdst = dest.nSdst; | |
| 95106 | 95308 | sqlite3SelectDelete(db, pDelete); |
| 95107 | 95309 | return rc; |
| 95108 | 95310 | } |
| 95109 | 95311 | #endif /* SQLITE_OMIT_COMPOUND_SELECT */ |
| 95110 | 95312 | |
| 95111 | 95313 | /* |
| 95112 | 95314 | ** Code an output subroutine for a coroutine implementation of a |
| 95113 | 95315 | ** SELECT statment. |
| 95114 | 95316 | ** |
| 95115 | -** The data to be output is contained in pIn->iMem. There are | |
| 95116 | -** pIn->nMem columns to be output. pDest is where the output should | |
| 95317 | +** The data to be output is contained in pIn->iSdst. There are | |
| 95318 | +** pIn->nSdst columns to be output. pDest is where the output should | |
| 95117 | 95319 | ** be sent. |
| 95118 | 95320 | ** |
| 95119 | 95321 | ** regReturn is the number of the register holding the subroutine |
| 95120 | 95322 | ** return address. |
| 95121 | 95323 | ** |
| @@ -95149,15 +95351,15 @@ | ||
| 95149 | 95351 | /* Suppress duplicates for UNION, EXCEPT, and INTERSECT |
| 95150 | 95352 | */ |
| 95151 | 95353 | if( regPrev ){ |
| 95152 | 95354 | int j1, j2; |
| 95153 | 95355 | j1 = sqlite3VdbeAddOp1(v, OP_IfNot, regPrev); |
| 95154 | - j2 = sqlite3VdbeAddOp4(v, OP_Compare, pIn->iMem, regPrev+1, pIn->nMem, | |
| 95356 | + j2 = sqlite3VdbeAddOp4(v, OP_Compare, pIn->iSdst, regPrev+1, pIn->nSdst, | |
| 95155 | 95357 | (char*)pKeyInfo, p4type); |
| 95156 | 95358 | sqlite3VdbeAddOp3(v, OP_Jump, j2+2, iContinue, j2+2); |
| 95157 | 95359 | sqlite3VdbeJumpHere(v, j1); |
| 95158 | - sqlite3ExprCodeCopy(pParse, pIn->iMem, regPrev+1, pIn->nMem); | |
| 95360 | + sqlite3ExprCodeCopy(pParse, pIn->iSdst, regPrev+1, pIn->nSdst); | |
| 95159 | 95361 | sqlite3VdbeAddOp2(v, OP_Integer, 1, regPrev); |
| 95160 | 95362 | } |
| 95161 | 95363 | if( pParse->db->mallocFailed ) return 0; |
| 95162 | 95364 | |
| 95163 | 95365 | /* Suppress the the first OFFSET entries if there is an OFFSET clause |
| @@ -95171,13 +95373,13 @@ | ||
| 95171 | 95373 | case SRT_EphemTab: { |
| 95172 | 95374 | int r1 = sqlite3GetTempReg(pParse); |
| 95173 | 95375 | int r2 = sqlite3GetTempReg(pParse); |
| 95174 | 95376 | testcase( pDest->eDest==SRT_Table ); |
| 95175 | 95377 | testcase( pDest->eDest==SRT_EphemTab ); |
| 95176 | - sqlite3VdbeAddOp3(v, OP_MakeRecord, pIn->iMem, pIn->nMem, r1); | |
| 95177 | - sqlite3VdbeAddOp2(v, OP_NewRowid, pDest->iParm, r2); | |
| 95178 | - sqlite3VdbeAddOp3(v, OP_Insert, pDest->iParm, r1, r2); | |
| 95378 | + sqlite3VdbeAddOp3(v, OP_MakeRecord, pIn->iSdst, pIn->nSdst, r1); | |
| 95379 | + sqlite3VdbeAddOp2(v, OP_NewRowid, pDest->iSDParm, r2); | |
| 95380 | + sqlite3VdbeAddOp3(v, OP_Insert, pDest->iSDParm, r1, r2); | |
| 95179 | 95381 | sqlite3VdbeChangeP5(v, OPFLAG_APPEND); |
| 95180 | 95382 | sqlite3ReleaseTempReg(pParse, r2); |
| 95181 | 95383 | sqlite3ReleaseTempReg(pParse, r1); |
| 95182 | 95384 | break; |
| 95183 | 95385 | } |
| @@ -95187,26 +95389,26 @@ | ||
| 95187 | 95389 | ** then there should be a single item on the stack. Write this |
| 95188 | 95390 | ** item into the set table with bogus data. |
| 95189 | 95391 | */ |
| 95190 | 95392 | case SRT_Set: { |
| 95191 | 95393 | int r1; |
| 95192 | - assert( pIn->nMem==1 ); | |
| 95394 | + assert( pIn->nSdst==1 ); | |
| 95193 | 95395 | p->affinity = |
| 95194 | - sqlite3CompareAffinity(p->pEList->a[0].pExpr, pDest->affinity); | |
| 95396 | + sqlite3CompareAffinity(p->pEList->a[0].pExpr, pDest->affSdst); | |
| 95195 | 95397 | r1 = sqlite3GetTempReg(pParse); |
| 95196 | - sqlite3VdbeAddOp4(v, OP_MakeRecord, pIn->iMem, 1, r1, &p->affinity, 1); | |
| 95197 | - sqlite3ExprCacheAffinityChange(pParse, pIn->iMem, 1); | |
| 95198 | - sqlite3VdbeAddOp2(v, OP_IdxInsert, pDest->iParm, r1); | |
| 95398 | + sqlite3VdbeAddOp4(v, OP_MakeRecord, pIn->iSdst, 1, r1, &p->affinity, 1); | |
| 95399 | + sqlite3ExprCacheAffinityChange(pParse, pIn->iSdst, 1); | |
| 95400 | + sqlite3VdbeAddOp2(v, OP_IdxInsert, pDest->iSDParm, r1); | |
| 95199 | 95401 | sqlite3ReleaseTempReg(pParse, r1); |
| 95200 | 95402 | break; |
| 95201 | 95403 | } |
| 95202 | 95404 | |
| 95203 | 95405 | #if 0 /* Never occurs on an ORDER BY query */ |
| 95204 | 95406 | /* If any row exist in the result set, record that fact and abort. |
| 95205 | 95407 | */ |
| 95206 | 95408 | case SRT_Exists: { |
| 95207 | - sqlite3VdbeAddOp2(v, OP_Integer, 1, pDest->iParm); | |
| 95409 | + sqlite3VdbeAddOp2(v, OP_Integer, 1, pDest->iSDParm); | |
| 95208 | 95410 | /* The LIMIT clause will terminate the loop for us */ |
| 95209 | 95411 | break; |
| 95210 | 95412 | } |
| 95211 | 95413 | #endif |
| 95212 | 95414 | |
| @@ -95213,27 +95415,27 @@ | ||
| 95213 | 95415 | /* If this is a scalar select that is part of an expression, then |
| 95214 | 95416 | ** store the results in the appropriate memory cell and break out |
| 95215 | 95417 | ** of the scan loop. |
| 95216 | 95418 | */ |
| 95217 | 95419 | case SRT_Mem: { |
| 95218 | - assert( pIn->nMem==1 ); | |
| 95219 | - sqlite3ExprCodeMove(pParse, pIn->iMem, pDest->iParm, 1); | |
| 95420 | + assert( pIn->nSdst==1 ); | |
| 95421 | + sqlite3ExprCodeMove(pParse, pIn->iSdst, pDest->iSDParm, 1); | |
| 95220 | 95422 | /* The LIMIT clause will jump out of the loop for us */ |
| 95221 | 95423 | break; |
| 95222 | 95424 | } |
| 95223 | 95425 | #endif /* #ifndef SQLITE_OMIT_SUBQUERY */ |
| 95224 | 95426 | |
| 95225 | 95427 | /* The results are stored in a sequence of registers |
| 95226 | - ** starting at pDest->iMem. Then the co-routine yields. | |
| 95428 | + ** starting at pDest->iSdst. Then the co-routine yields. | |
| 95227 | 95429 | */ |
| 95228 | 95430 | case SRT_Coroutine: { |
| 95229 | - if( pDest->iMem==0 ){ | |
| 95230 | - pDest->iMem = sqlite3GetTempRange(pParse, pIn->nMem); | |
| 95231 | - pDest->nMem = pIn->nMem; | |
| 95431 | + if( pDest->iSdst==0 ){ | |
| 95432 | + pDest->iSdst = sqlite3GetTempRange(pParse, pIn->nSdst); | |
| 95433 | + pDest->nSdst = pIn->nSdst; | |
| 95232 | 95434 | } |
| 95233 | - sqlite3ExprCodeMove(pParse, pIn->iMem, pDest->iMem, pDest->nMem); | |
| 95234 | - sqlite3VdbeAddOp1(v, OP_Yield, pDest->iParm); | |
| 95435 | + sqlite3ExprCodeMove(pParse, pIn->iSdst, pDest->iSdst, pDest->nSdst); | |
| 95436 | + sqlite3VdbeAddOp1(v, OP_Yield, pDest->iSDParm); | |
| 95235 | 95437 | break; |
| 95236 | 95438 | } |
| 95237 | 95439 | |
| 95238 | 95440 | /* If none of the above, then the result destination must be |
| 95239 | 95441 | ** SRT_Output. This routine is never called with any other |
| @@ -95243,12 +95445,12 @@ | ||
| 95243 | 95445 | ** Then the OP_ResultRow opcode is used to cause sqlite3_step() to |
| 95244 | 95446 | ** return the next row of result. |
| 95245 | 95447 | */ |
| 95246 | 95448 | default: { |
| 95247 | 95449 | assert( pDest->eDest==SRT_Output ); |
| 95248 | - sqlite3VdbeAddOp2(v, OP_ResultRow, pIn->iMem, pIn->nMem); | |
| 95249 | - sqlite3ExprCacheAffinityChange(pParse, pIn->iMem, pIn->nMem); | |
| 95450 | + sqlite3VdbeAddOp2(v, OP_ResultRow, pIn->iSdst, pIn->nSdst); | |
| 95451 | + sqlite3ExprCacheAffinityChange(pParse, pIn->iSdst, pIn->nSdst); | |
| 95250 | 95452 | break; |
| 95251 | 95453 | } |
| 95252 | 95454 | } |
| 95253 | 95455 | |
| 95254 | 95456 | /* Jump to the end of the loop if the LIMIT is reached. |
| @@ -95663,11 +95865,11 @@ | ||
| 95663 | 95865 | |
| 95664 | 95866 | /* Implement the main merge loop |
| 95665 | 95867 | */ |
| 95666 | 95868 | sqlite3VdbeResolveLabel(v, labelCmpr); |
| 95667 | 95869 | sqlite3VdbeAddOp4(v, OP_Permutation, 0, 0, 0, (char*)aPermute, P4_INTARRAY); |
| 95668 | - sqlite3VdbeAddOp4(v, OP_Compare, destA.iMem, destB.iMem, nOrderBy, | |
| 95870 | + sqlite3VdbeAddOp4(v, OP_Compare, destA.iSdst, destB.iSdst, nOrderBy, | |
| 95669 | 95871 | (char*)pKeyMerge, P4_KEYINFO_HANDOFF); |
| 95670 | 95872 | sqlite3VdbeAddOp3(v, OP_Jump, addrAltB, addrAeqB, addrAgtB); |
| 95671 | 95873 | |
| 95672 | 95874 | /* Release temporary registers |
| 95673 | 95875 | */ |
| @@ -96909,37 +97111,38 @@ | ||
| 96909 | 97111 | ** SRT_Output Generate a row of output (using the OP_ResultRow |
| 96910 | 97112 | ** opcode) for each row in the result set. |
| 96911 | 97113 | ** |
| 96912 | 97114 | ** SRT_Mem Only valid if the result is a single column. |
| 96913 | 97115 | ** Store the first column of the first result row |
| 96914 | -** in register pDest->iParm then abandon the rest | |
| 97116 | +** in register pDest->iSDParm then abandon the rest | |
| 96915 | 97117 | ** of the query. This destination implies "LIMIT 1". |
| 96916 | 97118 | ** |
| 96917 | 97119 | ** SRT_Set The result must be a single column. Store each |
| 96918 | -** row of result as the key in table pDest->iParm. | |
| 96919 | -** Apply the affinity pDest->affinity before storing | |
| 97120 | +** row of result as the key in table pDest->iSDParm. | |
| 97121 | +** Apply the affinity pDest->affSdst before storing | |
| 96920 | 97122 | ** results. Used to implement "IN (SELECT ...)". |
| 96921 | 97123 | ** |
| 96922 | -** SRT_Union Store results as a key in a temporary table pDest->iParm. | |
| 97124 | +** SRT_Union Store results as a key in a temporary table | |
| 97125 | +** identified by pDest->iSDParm. | |
| 96923 | 97126 | ** |
| 96924 | -** SRT_Except Remove results from the temporary table pDest->iParm. | |
| 97127 | +** SRT_Except Remove results from the temporary table pDest->iSDParm. | |
| 96925 | 97128 | ** |
| 96926 | -** SRT_Table Store results in temporary table pDest->iParm. | |
| 97129 | +** SRT_Table Store results in temporary table pDest->iSDParm. | |
| 96927 | 97130 | ** This is like SRT_EphemTab except that the table |
| 96928 | 97131 | ** is assumed to already be open. |
| 96929 | 97132 | ** |
| 96930 | -** SRT_EphemTab Create an temporary table pDest->iParm and store | |
| 97133 | +** SRT_EphemTab Create an temporary table pDest->iSDParm and store | |
| 96931 | 97134 | ** the result there. The cursor is left open after |
| 96932 | 97135 | ** returning. This is like SRT_Table except that |
| 96933 | 97136 | ** this destination uses OP_OpenEphemeral to create |
| 96934 | 97137 | ** the table first. |
| 96935 | 97138 | ** |
| 96936 | 97139 | ** SRT_Coroutine Generate a co-routine that returns a new row of |
| 96937 | 97140 | ** results each time it is invoked. The entry point |
| 96938 | -** of the co-routine is stored in register pDest->iParm. | |
| 97141 | +** of the co-routine is stored in register pDest->iSDParm. | |
| 96939 | 97142 | ** |
| 96940 | -** SRT_Exists Store a 1 in memory cell pDest->iParm if the result | |
| 97143 | +** SRT_Exists Store a 1 in memory cell pDest->iSDParm if the result | |
| 96941 | 97144 | ** set is not empty. |
| 96942 | 97145 | ** |
| 96943 | 97146 | ** SRT_Discard Throw the results away. This is used by SELECT |
| 96944 | 97147 | ** statements within triggers whose only purpose is |
| 96945 | 97148 | ** the side-effects of functions. |
| @@ -97179,11 +97382,11 @@ | ||
| 97179 | 97382 | } |
| 97180 | 97383 | |
| 97181 | 97384 | /* If the output is destined for a temporary table, open that table. |
| 97182 | 97385 | */ |
| 97183 | 97386 | if( pDest->eDest==SRT_EphemTab ){ |
| 97184 | - sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pDest->iParm, pEList->nExpr); | |
| 97387 | + sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pDest->iSDParm, pEList->nExpr); | |
| 97185 | 97388 | } |
| 97186 | 97389 | |
| 97187 | 97390 | /* Set the limiter. |
| 97188 | 97391 | */ |
| 97189 | 97392 | iEnd = sqlite3VdbeMakeLabel(v); |
| 97190 | 97393 |
| --- src/sqlite3.c | |
| +++ src/sqlite3.c | |
| @@ -673,11 +673,11 @@ | |
| 673 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 674 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 675 | */ |
| 676 | #define SQLITE_VERSION "3.7.14" |
| 677 | #define SQLITE_VERSION_NUMBER 3007014 |
| 678 | #define SQLITE_SOURCE_ID "2012-06-21 17:21:52 d5e6880279210ca63e2d5e7f6d009f30566f1242" |
| 679 | |
| 680 | /* |
| 681 | ** CAPI3REF: Run-Time Library Version Numbers |
| 682 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 683 | ** |
| @@ -4721,15 +4721,15 @@ | |
| 4721 | ** ^The sqlite3_result_error_code() function changes the error code |
| 4722 | ** returned by SQLite as a result of an error in a function. ^By default, |
| 4723 | ** the error code is SQLITE_ERROR. ^A subsequent call to sqlite3_result_error() |
| 4724 | ** or sqlite3_result_error16() resets the error code to SQLITE_ERROR. |
| 4725 | ** |
| 4726 | ** ^The sqlite3_result_toobig() interface causes SQLite to throw an error |
| 4727 | ** indicating that a string or BLOB is too long to represent. |
| 4728 | ** |
| 4729 | ** ^The sqlite3_result_nomem() interface causes SQLite to throw an error |
| 4730 | ** indicating that a memory allocation failed. |
| 4731 | ** |
| 4732 | ** ^The sqlite3_result_int() interface sets the return value |
| 4733 | ** of the application-defined function to be the 32-bit signed integer |
| 4734 | ** value given in the 2nd argument. |
| 4735 | ** ^The sqlite3_result_int64() interface sets the return value |
| @@ -8397,10 +8397,16 @@ | |
| 8397 | #define BTREE_LARGEST_ROOT_PAGE 4 |
| 8398 | #define BTREE_TEXT_ENCODING 5 |
| 8399 | #define BTREE_USER_VERSION 6 |
| 8400 | #define BTREE_INCR_VACUUM 7 |
| 8401 | |
| 8402 | SQLITE_PRIVATE int sqlite3BtreeCursor( |
| 8403 | Btree*, /* BTree containing table to open */ |
| 8404 | int iTable, /* Index of root page */ |
| 8405 | int wrFlag, /* 1 for writing. 0 for read-only */ |
| 8406 | struct KeyInfo*, /* First argument to compare function */ |
| @@ -8440,12 +8446,12 @@ | |
| 8440 | SQLITE_PRIVATE struct Pager *sqlite3BtreePager(Btree*); |
| 8441 | |
| 8442 | SQLITE_PRIVATE int sqlite3BtreePutData(BtCursor*, u32 offset, u32 amt, void*); |
| 8443 | SQLITE_PRIVATE void sqlite3BtreeCacheOverflow(BtCursor *); |
| 8444 | SQLITE_PRIVATE void sqlite3BtreeClearCursor(BtCursor *); |
| 8445 | |
| 8446 | SQLITE_PRIVATE int sqlite3BtreeSetVersion(Btree *pBt, int iVersion); |
| 8447 | |
| 8448 | #ifndef NDEBUG |
| 8449 | SQLITE_PRIVATE int sqlite3BtreeCursorIsValid(BtCursor*); |
| 8450 | #endif |
| 8451 | |
| @@ -9384,12 +9390,12 @@ | |
| 9384 | #else |
| 9385 | # define SQLITE_OS_WINCE 0 |
| 9386 | #endif |
| 9387 | |
| 9388 | /* |
| 9389 | ** Determine if we are dealing with WindowsRT (Metro) as this has a different and |
| 9390 | ** incompatible API from win32. |
| 9391 | */ |
| 9392 | #if !defined(SQLITE_OS_WINRT) |
| 9393 | # define SQLITE_OS_WINRT 0 |
| 9394 | #endif |
| 9395 | |
| @@ -11085,14 +11091,14 @@ | |
| 11085 | ** comments above sqlite3Select() for details. |
| 11086 | */ |
| 11087 | typedef struct SelectDest SelectDest; |
| 11088 | struct SelectDest { |
| 11089 | u8 eDest; /* How to dispose of the results */ |
| 11090 | u8 affinity; /* Affinity used when eDest==SRT_Set */ |
| 11091 | int iParm; /* A parameter used by the eDest disposal method */ |
| 11092 | int iMem; /* Base register where results are written */ |
| 11093 | int nMem; /* Number of registers allocated */ |
| 11094 | }; |
| 11095 | |
| 11096 | /* |
| 11097 | ** During code generation of statements that do inserts into AUTOINCREMENT |
| 11098 | ** tables, the following information is attached to the Table.u.autoInc.p |
| @@ -11284,10 +11290,12 @@ | |
| 11284 | #define OPFLAG_APPEND 0x08 /* This is likely to be an append */ |
| 11285 | #define OPFLAG_USESEEKRESULT 0x10 /* Try to avoid a seek in BtreeInsert() */ |
| 11286 | #define OPFLAG_CLEARCACHE 0x20 /* Clear pseudo-table cache in OP_Column */ |
| 11287 | #define OPFLAG_LENGTHARG 0x40 /* OP_Column only used for length() */ |
| 11288 | #define OPFLAG_TYPEOFARG 0x80 /* OP_Column only used for typeof() */ |
| 11289 | |
| 11290 | /* |
| 11291 | * Each trigger present in the database schema is stored as an instance of |
| 11292 | * struct Trigger. |
| 11293 | * |
| @@ -13354,15 +13362,15 @@ | |
| 13354 | # define sqlite3VdbeSorterNext(X,Y,Z) SQLITE_OK |
| 13355 | # define sqlite3VdbeSorterCompare(X,Y,Z) SQLITE_OK |
| 13356 | #else |
| 13357 | SQLITE_PRIVATE int sqlite3VdbeSorterInit(sqlite3 *, VdbeCursor *); |
| 13358 | SQLITE_PRIVATE void sqlite3VdbeSorterClose(sqlite3 *, VdbeCursor *); |
| 13359 | SQLITE_PRIVATE int sqlite3VdbeSorterRowkey(VdbeCursor *, Mem *); |
| 13360 | SQLITE_PRIVATE int sqlite3VdbeSorterNext(sqlite3 *, VdbeCursor *, int *); |
| 13361 | SQLITE_PRIVATE int sqlite3VdbeSorterRewind(sqlite3 *, VdbeCursor *, int *); |
| 13362 | SQLITE_PRIVATE int sqlite3VdbeSorterWrite(sqlite3 *, VdbeCursor *, Mem *); |
| 13363 | SQLITE_PRIVATE int sqlite3VdbeSorterCompare(VdbeCursor *, Mem *, int *); |
| 13364 | #endif |
| 13365 | |
| 13366 | #if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE>0 |
| 13367 | SQLITE_PRIVATE void sqlite3VdbeEnter(Vdbe*); |
| 13368 | SQLITE_PRIVATE void sqlite3VdbeLeave(Vdbe*); |
| @@ -22185,11 +22193,15 @@ | |
| 22185 | if( new_size==pH->htsize ) return 0; |
| 22186 | #endif |
| 22187 | |
| 22188 | /* The inability to allocates space for a larger hash table is |
| 22189 | ** a performance hit but it is not a fatal error. So mark the |
| 22190 | ** allocation as a benign. |
| 22191 | */ |
| 22192 | sqlite3BeginBenignMalloc(); |
| 22193 | new_ht = (struct _ht *)sqlite3Malloc( new_size*sizeof(struct _ht) ); |
| 22194 | sqlite3EndBenignMalloc(); |
| 22195 | |
| @@ -30109,11 +30121,12 @@ | |
| 30109 | #endif |
| 30110 | |
| 30111 | #define osCreateFileW ((HANDLE(WINAPI*)(LPCWSTR,DWORD,DWORD, \ |
| 30112 | LPSECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE))aSyscall[5].pCurrent) |
| 30113 | |
| 30114 | #if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) |
| 30115 | { "CreateFileMappingW", (SYSCALL)CreateFileMappingW, 0 }, |
| 30116 | #else |
| 30117 | { "CreateFileMappingW", (SYSCALL)0, 0 }, |
| 30118 | #endif |
| 30119 | |
| @@ -30421,11 +30434,11 @@ | |
| 30421 | #ifndef osLockFileEx |
| 30422 | #define osLockFileEx ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD,DWORD, \ |
| 30423 | LPOVERLAPPED))aSyscall[45].pCurrent) |
| 30424 | #endif |
| 30425 | |
| 30426 | #if !SQLITE_OS_WINRT |
| 30427 | { "MapViewOfFile", (SYSCALL)MapViewOfFile, 0 }, |
| 30428 | #else |
| 30429 | { "MapViewOfFile", (SYSCALL)0, 0 }, |
| 30430 | #endif |
| 30431 | |
| @@ -30491,11 +30504,15 @@ | |
| 30491 | #endif |
| 30492 | |
| 30493 | #define osUnlockFileEx ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \ |
| 30494 | LPOVERLAPPED))aSyscall[55].pCurrent) |
| 30495 | |
| 30496 | { "UnmapViewOfFile", (SYSCALL)UnmapViewOfFile, 0 }, |
| 30497 | |
| 30498 | #define osUnmapViewOfFile ((BOOL(WINAPI*)(LPCVOID))aSyscall[56].pCurrent) |
| 30499 | |
| 30500 | { "WideCharToMultiByte", (SYSCALL)WideCharToMultiByte, 0 }, |
| 30501 | |
| @@ -30523,20 +30540,20 @@ | |
| 30523 | #endif |
| 30524 | |
| 30525 | #define osWaitForSingleObject ((DWORD(WINAPI*)(HANDLE, \ |
| 30526 | DWORD))aSyscall[60].pCurrent) |
| 30527 | |
| 30528 | #if !SQLITE_OS_WINCE |
| 30529 | { "WaitForSingleObjectEx", (SYSCALL)WaitForSingleObjectEx, 0 }, |
| 30530 | #else |
| 30531 | { "WaitForSingleObjectEx", (SYSCALL)0, 0 }, |
| 30532 | #endif |
| 30533 | |
| 30534 | #define osWaitForSingleObjectEx ((DWORD(WINAPI*)(HANDLE,DWORD, \ |
| 30535 | BOOL))aSyscall[61].pCurrent) |
| 30536 | |
| 30537 | #if !SQLITE_OS_WINCE |
| 30538 | { "SetFilePointerEx", (SYSCALL)SetFilePointerEx, 0 }, |
| 30539 | #else |
| 30540 | { "SetFilePointerEx", (SYSCALL)0, 0 }, |
| 30541 | #endif |
| 30542 | |
| @@ -30550,11 +30567,11 @@ | |
| 30550 | #endif |
| 30551 | |
| 30552 | #define osGetFileInformationByHandleEx ((BOOL(WINAPI*)(HANDLE, \ |
| 30553 | FILE_INFO_BY_HANDLE_CLASS,LPVOID,DWORD))aSyscall[63].pCurrent) |
| 30554 | |
| 30555 | #if SQLITE_OS_WINRT |
| 30556 | { "MapViewOfFileFromApp", (SYSCALL)MapViewOfFileFromApp, 0 }, |
| 30557 | #else |
| 30558 | { "MapViewOfFileFromApp", (SYSCALL)0, 0 }, |
| 30559 | #endif |
| 30560 | |
| @@ -30614,11 +30631,11 @@ | |
| 30614 | |
| 30615 | { "GetProcessHeap", (SYSCALL)GetProcessHeap, 0 }, |
| 30616 | |
| 30617 | #define osGetProcessHeap ((HANDLE(WINAPI*)(VOID))aSyscall[71].pCurrent) |
| 30618 | |
| 30619 | #if SQLITE_OS_WINRT |
| 30620 | { "CreateFileMappingFromApp", (SYSCALL)CreateFileMappingFromApp, 0 }, |
| 30621 | #else |
| 30622 | { "CreateFileMappingFromApp", (SYSCALL)0, 0 }, |
| 30623 | #endif |
| 30624 | |
| @@ -34472,14 +34489,13 @@ | |
| 34472 | void *pTmpSpace; |
| 34473 | |
| 34474 | /* Allocate the Bitvec to be tested and a linear array of |
| 34475 | ** bits to act as the reference */ |
| 34476 | pBitvec = sqlite3BitvecCreate( sz ); |
| 34477 | pV = sqlite3_malloc( (sz+7)/8 + 1 ); |
| 34478 | pTmpSpace = sqlite3_malloc(BITVEC_SZ); |
| 34479 | if( pBitvec==0 || pV==0 || pTmpSpace==0 ) goto bitvec_end; |
| 34480 | memset(pV, 0, (sz+7)/8 + 1); |
| 34481 | |
| 34482 | /* NULL pBitvec tests */ |
| 34483 | sqlite3BitvecSet(0, 1); |
| 34484 | sqlite3BitvecClear(0, 1, pTmpSpace); |
| 34485 | |
| @@ -35559,15 +35575,14 @@ | |
| 35559 | nNew = 256; |
| 35560 | } |
| 35561 | |
| 35562 | pcache1LeaveMutex(p->pGroup); |
| 35563 | if( p->nHash ){ sqlite3BeginBenignMalloc(); } |
| 35564 | apNew = (PgHdr1 **)sqlite3_malloc(sizeof(PgHdr1 *)*nNew); |
| 35565 | if( p->nHash ){ sqlite3EndBenignMalloc(); } |
| 35566 | pcache1EnterMutex(p->pGroup); |
| 35567 | if( apNew ){ |
| 35568 | memset(apNew, 0, sizeof(PgHdr1 *)*nNew); |
| 35569 | for(i=0; i<p->nHash; i++){ |
| 35570 | PgHdr1 *pPage; |
| 35571 | PgHdr1 *pNext = p->apHash[i]; |
| 35572 | while( (pPage = pNext)!=0 ){ |
| 35573 | unsigned int h = pPage->iKey % nNew; |
| @@ -35747,13 +35762,12 @@ | |
| 35747 | |
| 35748 | assert( (szPage & (szPage-1))==0 && szPage>=512 && szPage<=65536 ); |
| 35749 | assert( szExtra < 300 ); |
| 35750 | |
| 35751 | sz = sizeof(PCache1) + sizeof(PGroup)*separateCache; |
| 35752 | pCache = (PCache1 *)sqlite3_malloc(sz); |
| 35753 | if( pCache ){ |
| 35754 | memset(pCache, 0, sz); |
| 35755 | if( separateCache ){ |
| 35756 | pGroup = (PGroup*)&pCache[1]; |
| 35757 | pGroup->mxPinned = 10; |
| 35758 | }else{ |
| 35759 | pGroup = &pcache1.grp; |
| @@ -43916,12 +43930,13 @@ | |
| 43916 | ** Hence, unlike the database and WAL file formats which store all values |
| 43917 | ** as big endian, the wal-index can store multi-byte values in the native |
| 43918 | ** byte order of the host computer. |
| 43919 | ** |
| 43920 | ** The purpose of the wal-index is to answer this question quickly: Given |
| 43921 | ** a page number P, return the index of the last frame for page P in the WAL, |
| 43922 | ** or return NULL if there are no frames for page P in the WAL. |
| 43923 | ** |
| 43924 | ** The wal-index consists of a header region, followed by an one or |
| 43925 | ** more index blocks. |
| 43926 | ** |
| 43927 | ** The wal-index header contains the total number of frames within the WAL |
| @@ -44971,10 +44986,11 @@ | |
| 44971 | */ |
| 44972 | pInfo = walCkptInfo(pWal); |
| 44973 | pInfo->nBackfill = 0; |
| 44974 | pInfo->aReadMark[0] = 0; |
| 44975 | for(i=1; i<WAL_NREADER; i++) pInfo->aReadMark[i] = READMARK_NOT_USED; |
| 44976 | |
| 44977 | /* If more than one frame was recovered from the log file, report an |
| 44978 | ** event via sqlite3_log(). This is to help with identifying performance |
| 44979 | ** problems caused by applications routinely shutting down without |
| 44980 | ** checkpointing the log file. |
| @@ -45471,11 +45487,11 @@ | |
| 45471 | u32 y = pInfo->aReadMark[i]; |
| 45472 | if( mxSafeFrame>y ){ |
| 45473 | assert( y<=pWal->hdr.mxFrame ); |
| 45474 | rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(i), 1); |
| 45475 | if( rc==SQLITE_OK ){ |
| 45476 | pInfo->aReadMark[i] = READMARK_NOT_USED; |
| 45477 | walUnlockExclusive(pWal, WAL_READ_LOCK(i), 1); |
| 45478 | }else if( rc==SQLITE_BUSY ){ |
| 45479 | mxSafeFrame = y; |
| 45480 | xBusy = 0; |
| 45481 | }else{ |
| @@ -46384,11 +46400,12 @@ | |
| 46384 | pWal->hdr.mxFrame = 0; |
| 46385 | sqlite3Put4byte((u8*)&aSalt[0], 1 + sqlite3Get4byte((u8*)&aSalt[0])); |
| 46386 | aSalt[1] = salt1; |
| 46387 | walIndexWriteHdr(pWal); |
| 46388 | pInfo->nBackfill = 0; |
| 46389 | for(i=1; i<WAL_NREADER; i++) pInfo->aReadMark[i] = READMARK_NOT_USED; |
| 46390 | assert( pInfo->aReadMark[0]==0 ); |
| 46391 | walUnlockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1); |
| 46392 | }else if( rc!=SQLITE_BUSY ){ |
| 46393 | return rc; |
| 46394 | } |
| @@ -47387,10 +47404,11 @@ | |
| 47387 | u8 validNKey; /* True if info.nKey is valid */ |
| 47388 | u8 eState; /* One of the CURSOR_XXX constants (see below) */ |
| 47389 | #ifndef SQLITE_OMIT_INCRBLOB |
| 47390 | u8 isIncrblobHandle; /* True if this cursor is an incr. io handle */ |
| 47391 | #endif |
| 47392 | i16 iPage; /* Index of current page in apPage */ |
| 47393 | u16 aiIdx[BTCURSOR_MAX_DEPTH]; /* Current index in apPage[i] */ |
| 47394 | MemPage *apPage[BTCURSOR_MAX_DEPTH]; /* Pages from root to current page */ |
| 47395 | }; |
| 47396 | |
| @@ -53736,11 +53754,12 @@ | |
| 53736 | */ |
| 53737 | static int balance_nonroot( |
| 53738 | MemPage *pParent, /* Parent page of siblings being balanced */ |
| 53739 | int iParentIdx, /* Index of "the page" in pParent */ |
| 53740 | u8 *aOvflSpace, /* page-size bytes of space for parent ovfl */ |
| 53741 | int isRoot /* True if pParent is a root-page */ |
| 53742 | ){ |
| 53743 | BtShared *pBt; /* The whole database */ |
| 53744 | int nCell = 0; /* Number of cells in apCell[] */ |
| 53745 | int nMaxCells = 0; /* Allocated size of apCell, szCell, aFrom. */ |
| 53746 | int nNew = 0; /* Number of pages in apNew[] */ |
| @@ -53800,22 +53819,23 @@ | |
| 53800 | ** have already been removed. |
| 53801 | */ |
| 53802 | i = pParent->nOverflow + pParent->nCell; |
| 53803 | if( i<2 ){ |
| 53804 | nxDiv = 0; |
| 53805 | nOld = i+1; |
| 53806 | }else{ |
| 53807 | nOld = 3; |
| 53808 | if( iParentIdx==0 ){ |
| 53809 | nxDiv = 0; |
| 53810 | }else if( iParentIdx==i ){ |
| 53811 | nxDiv = i-2; |
| 53812 | }else{ |
| 53813 | nxDiv = iParentIdx-1; |
| 53814 | } |
| 53815 | i = 2; |
| 53816 | } |
| 53817 | if( (i+nxDiv-pParent->nOverflow)==pParent->nCell ){ |
| 53818 | pRight = &pParent->aData[pParent->hdrOffset+8]; |
| 53819 | }else{ |
| 53820 | pRight = findCell(pParent, i+nxDiv-pParent->nOverflow); |
| 53821 | } |
| @@ -54020,11 +54040,13 @@ | |
| 54020 | |
| 54021 | r = cntNew[i-1] - 1; |
| 54022 | d = r + 1 - leafData; |
| 54023 | assert( d<nMaxCells ); |
| 54024 | assert( r<nMaxCells ); |
| 54025 | while( szRight==0 || szRight+szCell[d]+2<=szLeft-(szCell[r]+2) ){ |
| 54026 | szRight += szCell[d] + 2; |
| 54027 | szLeft -= szCell[r] + 2; |
| 54028 | cntNew[i-1]--; |
| 54029 | r = cntNew[i-1] - 1; |
| 54030 | d = r + 1 - leafData; |
| @@ -54067,11 +54089,11 @@ | |
| 54067 | rc = sqlite3PagerWrite(pNew->pDbPage); |
| 54068 | nNew++; |
| 54069 | if( rc ) goto balance_cleanup; |
| 54070 | }else{ |
| 54071 | assert( i>0 ); |
| 54072 | rc = allocateBtreePage(pBt, &pNew, &pgno, pgno, 0); |
| 54073 | if( rc ) goto balance_cleanup; |
| 54074 | apNew[i] = pNew; |
| 54075 | nNew++; |
| 54076 | |
| 54077 | /* Set the pointer-map entry for the new sibling page. */ |
| @@ -54517,11 +54539,11 @@ | |
| 54517 | ** the previous call, as the overflow cell data will have been |
| 54518 | ** copied either into the body of a database page or into the new |
| 54519 | ** pSpace buffer passed to the latter call to balance_nonroot(). |
| 54520 | */ |
| 54521 | u8 *pSpace = sqlite3PageMalloc(pCur->pBt->pageSize); |
| 54522 | rc = balance_nonroot(pParent, iIdx, pSpace, iPage==1); |
| 54523 | if( pFree ){ |
| 54524 | /* If pFree is not NULL, it points to the pSpace buffer used |
| 54525 | ** by a previous call to balance_nonroot(). Its contents are |
| 54526 | ** now stored either on real database pages or within the |
| 54527 | ** new pSpace buffer, so it may be safely freed here. */ |
| @@ -56104,10 +56126,20 @@ | |
| 56104 | } |
| 56105 | |
| 56106 | pBt->btsFlags &= ~BTS_NO_WAL; |
| 56107 | return rc; |
| 56108 | } |
| 56109 | |
| 56110 | /************** End of btree.c ***********************************************/ |
| 56111 | /************** Begin file backup.c ******************************************/ |
| 56112 | /* |
| 56113 | ** 2009 January 28 |
| @@ -56271,19 +56303,18 @@ | |
| 56271 | }else { |
| 56272 | /* Allocate space for a new sqlite3_backup object... |
| 56273 | ** EVIDENCE-OF: R-64852-21591 The sqlite3_backup object is created by a |
| 56274 | ** call to sqlite3_backup_init() and is destroyed by a call to |
| 56275 | ** sqlite3_backup_finish(). */ |
| 56276 | p = (sqlite3_backup *)sqlite3_malloc(sizeof(sqlite3_backup)); |
| 56277 | if( !p ){ |
| 56278 | sqlite3Error(pDestDb, SQLITE_NOMEM, 0); |
| 56279 | } |
| 56280 | } |
| 56281 | |
| 56282 | /* If the allocation succeeded, populate the new object. */ |
| 56283 | if( p ){ |
| 56284 | memset(p, 0, sizeof(sqlite3_backup)); |
| 56285 | p->pSrc = findBtree(pDestDb, pSrcDb, zSrcDb); |
| 56286 | p->pDest = findBtree(pDestDb, pDestDb, zDestDb); |
| 56287 | p->pDestDb = pDestDb; |
| 56288 | p->pSrcDb = pSrcDb; |
| 56289 | p->iNext = 1; |
| @@ -62703,13 +62734,12 @@ | |
| 62703 | */ |
| 62704 | SQLITE_PRIVATE void sqlite3ExplainBegin(Vdbe *pVdbe){ |
| 62705 | if( pVdbe ){ |
| 62706 | Explain *p; |
| 62707 | sqlite3BeginBenignMalloc(); |
| 62708 | p = sqlite3_malloc( sizeof(Explain) ); |
| 62709 | if( p ){ |
| 62710 | memset(p, 0, sizeof(*p)); |
| 62711 | p->pVdbe = pVdbe; |
| 62712 | sqlite3_free(pVdbe->pExplain); |
| 62713 | pVdbe->pExplain = p; |
| 62714 | sqlite3StrAccumInit(&p->str, p->zBase, sizeof(p->zBase), |
| 62715 | SQLITE_MAX_LENGTH); |
| @@ -66486,10 +66516,13 @@ | |
| 66486 | Btree *pX; |
| 66487 | VdbeCursor *pCur; |
| 66488 | Db *pDb; |
| 66489 | #endif /* local variables moved into u.ax */ |
| 66490 | |
| 66491 | if( p->expired ){ |
| 66492 | rc = SQLITE_ABORT; |
| 66493 | break; |
| 66494 | } |
| 66495 | |
| @@ -66509,11 +66542,11 @@ | |
| 66509 | p->minWriteFileFormat = u.ax.pDb->pSchema->file_format; |
| 66510 | } |
| 66511 | }else{ |
| 66512 | u.ax.wrFlag = 0; |
| 66513 | } |
| 66514 | if( pOp->p5 ){ |
| 66515 | assert( u.ax.p2>0 ); |
| 66516 | assert( u.ax.p2<=p->nMem ); |
| 66517 | pIn2 = &aMem[u.ax.p2]; |
| 66518 | assert( memIsValid(pIn2) ); |
| 66519 | assert( (pIn2->flags & MEM_Int)!=0 ); |
| @@ -66540,10 +66573,12 @@ | |
| 66540 | if( u.ax.pCur==0 ) goto no_mem; |
| 66541 | u.ax.pCur->nullRow = 1; |
| 66542 | u.ax.pCur->isOrdered = 1; |
| 66543 | rc = sqlite3BtreeCursor(u.ax.pX, u.ax.p2, u.ax.wrFlag, u.ax.pKeyInfo, u.ax.pCur->pCursor); |
| 66544 | u.ax.pCur->pKeyInfo = u.ax.pKeyInfo; |
| 66545 | |
| 66546 | /* Since it performs no memory allocation or IO, the only value that |
| 66547 | ** sqlite3BtreeCursor() may return is SQLITE_OK. */ |
| 66548 | assert( rc==SQLITE_OK ); |
| 66549 | |
| @@ -70159,10 +70194,11 @@ | |
| 70159 | |
| 70160 | #ifndef SQLITE_OMIT_MERGE_SORT |
| 70161 | |
| 70162 | typedef struct VdbeSorterIter VdbeSorterIter; |
| 70163 | typedef struct SorterRecord SorterRecord; |
| 70164 | |
| 70165 | /* |
| 70166 | ** NOTES ON DATA STRUCTURE USED FOR N-WAY MERGES: |
| 70167 | ** |
| 70168 | ** As keys are added to the sorter, they are written to disk in a series |
| @@ -70256,10 +70292,28 @@ | |
| 70256 | int nAlloc; /* Bytes of space at aAlloc */ |
| 70257 | int nKey; /* Number of bytes in key */ |
| 70258 | sqlite3_file *pFile; /* File iterator is reading from */ |
| 70259 | u8 *aAlloc; /* Allocated space */ |
| 70260 | u8 *aKey; /* Pointer to current key */ |
| 70261 | }; |
| 70262 | |
| 70263 | /* |
| 70264 | ** A structure to store a single record. All in-memory records are connected |
| 70265 | ** together into a linked list headed at VdbeSorter.pRecord using the |
| @@ -70281,12 +70335,126 @@ | |
| 70281 | ** Free all memory belonging to the VdbeSorterIter object passed as the second |
| 70282 | ** argument. All structure fields are set to zero before returning. |
| 70283 | */ |
| 70284 | static void vdbeSorterIterZero(sqlite3 *db, VdbeSorterIter *pIter){ |
| 70285 | sqlite3DbFree(db, pIter->aAlloc); |
| 70286 | memset(pIter, 0, sizeof(VdbeSorterIter)); |
| 70287 | } |
| 70288 | |
| 70289 | /* |
| 70290 | ** Advance iterator pIter to the next key in its PMA. Return SQLITE_OK if |
| 70291 | ** no error occurs, or an SQLite error code if one does. |
| 70292 | */ |
| @@ -70293,100 +70461,22 @@ | |
| 70293 | static int vdbeSorterIterNext( |
| 70294 | sqlite3 *db, /* Database handle (for sqlite3DbMalloc() ) */ |
| 70295 | VdbeSorterIter *pIter /* Iterator to advance */ |
| 70296 | ){ |
| 70297 | int rc; /* Return Code */ |
| 70298 | int nRead; /* Number of bytes read */ |
| 70299 | int nRec = 0; /* Size of record in bytes */ |
| 70300 | int iOff = 0; /* Size of serialized size varint in bytes */ |
| 70301 | |
| 70302 | assert( pIter->iEof>=pIter->iReadOff ); |
| 70303 | if( pIter->iEof-pIter->iReadOff>5 ){ |
| 70304 | nRead = 5; |
| 70305 | }else{ |
| 70306 | nRead = (int)(pIter->iEof - pIter->iReadOff); |
| 70307 | } |
| 70308 | if( nRead<=0 ){ |
| 70309 | /* This is an EOF condition */ |
| 70310 | vdbeSorterIterZero(db, pIter); |
| 70311 | return SQLITE_OK; |
| 70312 | } |
| 70313 | |
| 70314 | rc = sqlite3OsRead(pIter->pFile, pIter->aAlloc, nRead, pIter->iReadOff); |
| 70315 | if( rc==SQLITE_OK ){ |
| 70316 | iOff = getVarint32(pIter->aAlloc, nRec); |
| 70317 | if( (iOff+nRec)>nRead ){ |
| 70318 | int nRead2; /* Number of extra bytes to read */ |
| 70319 | if( (iOff+nRec)>pIter->nAlloc ){ |
| 70320 | int nNew = pIter->nAlloc*2; |
| 70321 | while( (iOff+nRec)>nNew ) nNew = nNew*2; |
| 70322 | pIter->aAlloc = sqlite3DbReallocOrFree(db, pIter->aAlloc, nNew); |
| 70323 | if( !pIter->aAlloc ) return SQLITE_NOMEM; |
| 70324 | pIter->nAlloc = nNew; |
| 70325 | } |
| 70326 | |
| 70327 | nRead2 = iOff + nRec - nRead; |
| 70328 | rc = sqlite3OsRead( |
| 70329 | pIter->pFile, &pIter->aAlloc[nRead], nRead2, pIter->iReadOff+nRead |
| 70330 | ); |
| 70331 | } |
| 70332 | } |
| 70333 | |
| 70334 | assert( rc!=SQLITE_OK || nRec>0 ); |
| 70335 | pIter->iReadOff += iOff+nRec; |
| 70336 | pIter->nKey = nRec; |
| 70337 | pIter->aKey = &pIter->aAlloc[iOff]; |
| 70338 | return rc; |
| 70339 | } |
| 70340 | |
| 70341 | /* |
| 70342 | ** Write a single varint, value iVal, to file-descriptor pFile. Return |
| 70343 | ** SQLITE_OK if successful, or an SQLite error code if some error occurs. |
| 70344 | ** |
| 70345 | ** The value of *piOffset when this function is called is used as the byte |
| 70346 | ** offset in file pFile to write to. Before returning, *piOffset is |
| 70347 | ** incremented by the number of bytes written. |
| 70348 | */ |
| 70349 | static int vdbeSorterWriteVarint( |
| 70350 | sqlite3_file *pFile, /* File to write to */ |
| 70351 | i64 iVal, /* Value to write as a varint */ |
| 70352 | i64 *piOffset /* IN/OUT: Write offset in file pFile */ |
| 70353 | ){ |
| 70354 | u8 aVarint[9]; /* Buffer large enough for a varint */ |
| 70355 | int nVarint; /* Number of used bytes in varint */ |
| 70356 | int rc; /* Result of write() call */ |
| 70357 | |
| 70358 | nVarint = sqlite3PutVarint(aVarint, iVal); |
| 70359 | rc = sqlite3OsWrite(pFile, aVarint, nVarint, *piOffset); |
| 70360 | *piOffset += nVarint; |
| 70361 | |
| 70362 | return rc; |
| 70363 | } |
| 70364 | |
| 70365 | /* |
| 70366 | ** Read a single varint from file-descriptor pFile. Return SQLITE_OK if |
| 70367 | ** successful, or an SQLite error code if some error occurs. |
| 70368 | ** |
| 70369 | ** The value of *piOffset when this function is called is used as the |
| 70370 | ** byte offset in file pFile from whence to read the varint. If successful |
| 70371 | ** (i.e. if no IO error occurs), then *piOffset is set to the offset of |
| 70372 | ** the first byte past the end of the varint before returning. *piVal is |
| 70373 | ** set to the integer value read. If an error occurs, the final values of |
| 70374 | ** both *piOffset and *piVal are undefined. |
| 70375 | */ |
| 70376 | static int vdbeSorterReadVarint( |
| 70377 | sqlite3_file *pFile, /* File to read from */ |
| 70378 | i64 *piOffset, /* IN/OUT: Read offset in pFile */ |
| 70379 | i64 *piVal /* OUT: Value read from file */ |
| 70380 | ){ |
| 70381 | u8 aVarint[9]; /* Buffer large enough for a varint */ |
| 70382 | i64 iOff = *piOffset; /* Offset in file to read from */ |
| 70383 | int rc; /* Return code */ |
| 70384 | |
| 70385 | rc = sqlite3OsRead(pFile, aVarint, 9, iOff); |
| 70386 | if( rc==SQLITE_OK ){ |
| 70387 | *piOffset += getVarint(aVarint, (u64 *)piVal); |
| 70388 | } |
| 70389 | |
| 70390 | return rc; |
| 70391 | } |
| 70392 | |
| @@ -70396,31 +70486,56 @@ | |
| 70396 | ** leaves the iterator pointing to the first key in the PMA (or EOF if the |
| 70397 | ** PMA is empty). |
| 70398 | */ |
| 70399 | static int vdbeSorterIterInit( |
| 70400 | sqlite3 *db, /* Database handle */ |
| 70401 | VdbeSorter *pSorter, /* Sorter object */ |
| 70402 | i64 iStart, /* Start offset in pFile */ |
| 70403 | VdbeSorterIter *pIter, /* Iterator to populate */ |
| 70404 | i64 *pnByte /* IN/OUT: Increment this value by PMA size */ |
| 70405 | ){ |
| 70406 | int rc; |
| 70407 | |
| 70408 | assert( pSorter->iWriteOff>iStart ); |
| 70409 | assert( pIter->aAlloc==0 ); |
| 70410 | pIter->pFile = pSorter->pTemp1; |
| 70411 | pIter->iReadOff = iStart; |
| 70412 | pIter->nAlloc = 128; |
| 70413 | pIter->aAlloc = (u8 *)sqlite3DbMallocRaw(db, pIter->nAlloc); |
| 70414 | if( !pIter->aAlloc ){ |
| 70415 | rc = SQLITE_NOMEM; |
| 70416 | }else{ |
| 70417 | i64 nByte; /* Total size of PMA in bytes */ |
| 70418 | rc = vdbeSorterReadVarint(pSorter->pTemp1, &pIter->iReadOff, &nByte); |
| 70419 | *pnByte += nByte; |
| 70420 | pIter->iEof = pIter->iReadOff + nByte; |
| 70421 | } |
| 70422 | if( rc==SQLITE_OK ){ |
| 70423 | rc = vdbeSorterIterNext(db, pIter); |
| 70424 | } |
| 70425 | return rc; |
| 70426 | } |
| @@ -70440,14 +70555,14 @@ | |
| 70440 | ** |
| 70441 | ** If pKey2 is passed a NULL pointer, then it is assumed that the pCsr->aSpace |
| 70442 | ** has been allocated and contains an unpacked record that is used as key2. |
| 70443 | */ |
| 70444 | static void vdbeSorterCompare( |
| 70445 | VdbeCursor *pCsr, /* Cursor object (for pKeyInfo) */ |
| 70446 | int bOmitRowid, /* Ignore rowid field at end of keys */ |
| 70447 | void *pKey1, int nKey1, /* Left side of comparison */ |
| 70448 | void *pKey2, int nKey2, /* Right side of comparison */ |
| 70449 | int *pRes /* OUT: Result of comparison */ |
| 70450 | ){ |
| 70451 | KeyInfo *pKeyInfo = pCsr->pKeyInfo; |
| 70452 | VdbeSorter *pSorter = pCsr->pSorter; |
| 70453 | UnpackedRecord *r2 = pSorter->pUnpacked; |
| @@ -70475,11 +70590,11 @@ | |
| 70475 | /* |
| 70476 | ** This function is called to compare two iterator keys when merging |
| 70477 | ** multiple b-tree segments. Parameter iOut is the index of the aTree[] |
| 70478 | ** value to recalculate. |
| 70479 | */ |
| 70480 | static int vdbeSorterDoCompare(VdbeCursor *pCsr, int iOut){ |
| 70481 | VdbeSorter *pSorter = pCsr->pSorter; |
| 70482 | int i1; |
| 70483 | int i2; |
| 70484 | int iRes; |
| 70485 | VdbeSorterIter *p1; |
| @@ -70601,11 +70716,11 @@ | |
| 70601 | /* |
| 70602 | ** Merge the two sorted lists p1 and p2 into a single list. |
| 70603 | ** Set *ppOut to the head of the new list. |
| 70604 | */ |
| 70605 | static void vdbeSorterMerge( |
| 70606 | VdbeCursor *pCsr, /* For pKeyInfo */ |
| 70607 | SorterRecord *p1, /* First list to merge */ |
| 70608 | SorterRecord *p2, /* Second list to merge */ |
| 70609 | SorterRecord **ppOut /* OUT: Head of merged list */ |
| 70610 | ){ |
| 70611 | SorterRecord *pFinal = 0; |
| @@ -70635,11 +70750,11 @@ | |
| 70635 | /* |
| 70636 | ** Sort the linked list of records headed at pCsr->pRecord. Return SQLITE_OK |
| 70637 | ** if successful, or an SQLite error code (i.e. SQLITE_NOMEM) if an error |
| 70638 | ** occurs. |
| 70639 | */ |
| 70640 | static int vdbeSorterSort(VdbeCursor *pCsr){ |
| 70641 | int i; |
| 70642 | SorterRecord **aSlot; |
| 70643 | SorterRecord *p; |
| 70644 | VdbeSorter *pSorter = pCsr->pSorter; |
| 70645 | |
| @@ -70668,10 +70783,95 @@ | |
| 70668 | |
| 70669 | sqlite3_free(aSlot); |
| 70670 | return SQLITE_OK; |
| 70671 | } |
| 70672 | |
| 70673 | |
| 70674 | /* |
| 70675 | ** Write the current contents of the in-memory linked-list to a PMA. Return |
| 70676 | ** SQLITE_OK if successful, or an SQLite error code otherwise. |
| 70677 | ** |
| @@ -70682,13 +70882,16 @@ | |
| 70682 | ** |
| 70683 | ** * One or more records packed end-to-end in order of ascending keys. |
| 70684 | ** Each record consists of a varint followed by a blob of data (the |
| 70685 | ** key). The varint is the number of bytes in the blob of data. |
| 70686 | */ |
| 70687 | static int vdbeSorterListToPMA(sqlite3 *db, VdbeCursor *pCsr){ |
| 70688 | int rc = SQLITE_OK; /* Return code */ |
| 70689 | VdbeSorter *pSorter = pCsr->pSorter; |
| 70690 | |
| 70691 | if( pSorter->nInMemory==0 ){ |
| 70692 | assert( pSorter->pRecord==0 ); |
| 70693 | return rc; |
| 70694 | } |
| @@ -70702,43 +70905,24 @@ | |
| 70702 | assert( pSorter->iWriteOff==0 ); |
| 70703 | assert( pSorter->nPMA==0 ); |
| 70704 | } |
| 70705 | |
| 70706 | if( rc==SQLITE_OK ){ |
| 70707 | i64 iOff = pSorter->iWriteOff; |
| 70708 | SorterRecord *p; |
| 70709 | SorterRecord *pNext = 0; |
| 70710 | static const char eightZeros[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; |
| 70711 | |
| 70712 | pSorter->nPMA++; |
| 70713 | rc = vdbeSorterWriteVarint(pSorter->pTemp1, pSorter->nInMemory, &iOff); |
| 70714 | for(p=pSorter->pRecord; rc==SQLITE_OK && p; p=pNext){ |
| 70715 | pNext = p->pNext; |
| 70716 | rc = vdbeSorterWriteVarint(pSorter->pTemp1, p->nVal, &iOff); |
| 70717 | |
| 70718 | if( rc==SQLITE_OK ){ |
| 70719 | rc = sqlite3OsWrite(pSorter->pTemp1, p->pVal, p->nVal, iOff); |
| 70720 | iOff += p->nVal; |
| 70721 | } |
| 70722 | |
| 70723 | sqlite3DbFree(db, p); |
| 70724 | } |
| 70725 | |
| 70726 | /* This assert verifies that unless an error has occurred, the size of |
| 70727 | ** the PMA on disk is the same as the expected size stored in |
| 70728 | ** pSorter->nInMemory. */ |
| 70729 | assert( rc!=SQLITE_OK || pSorter->nInMemory==( |
| 70730 | iOff-pSorter->iWriteOff-sqlite3VarintLen(pSorter->nInMemory) |
| 70731 | )); |
| 70732 | |
| 70733 | pSorter->iWriteOff = iOff; |
| 70734 | if( rc==SQLITE_OK ){ |
| 70735 | /* Terminate each file with 8 extra bytes so that from any offset |
| 70736 | ** in the file we can always read 9 bytes without a SHORT_READ error */ |
| 70737 | rc = sqlite3OsWrite(pSorter->pTemp1, eightZeros, 8, iOff); |
| 70738 | } |
| 70739 | pSorter->pRecord = p; |
| 70740 | } |
| 70741 | |
| 70742 | return rc; |
| 70743 | } |
| 70744 | |
| @@ -70745,11 +70929,11 @@ | |
| 70745 | /* |
| 70746 | ** Add a record to the sorter. |
| 70747 | */ |
| 70748 | SQLITE_PRIVATE int sqlite3VdbeSorterWrite( |
| 70749 | sqlite3 *db, /* Database handle */ |
| 70750 | VdbeCursor *pCsr, /* Sorter cursor */ |
| 70751 | Mem *pVal /* Memory cell containing record */ |
| 70752 | ){ |
| 70753 | VdbeSorter *pSorter = pCsr->pSorter; |
| 70754 | int rc = SQLITE_OK; /* Return Code */ |
| 70755 | SorterRecord *pNew; /* New list element */ |
| @@ -70779,12 +70963,18 @@ | |
| 70779 | */ |
| 70780 | if( rc==SQLITE_OK && pSorter->mxPmaSize>0 && ( |
| 70781 | (pSorter->nInMemory>pSorter->mxPmaSize) |
| 70782 | || (pSorter->nInMemory>pSorter->mnPmaSize && sqlite3HeapNearlyFull()) |
| 70783 | )){ |
| 70784 | rc = vdbeSorterListToPMA(db, pCsr); |
| 70785 | pSorter->nInMemory = 0; |
| 70786 | } |
| 70787 | |
| 70788 | return rc; |
| 70789 | } |
| 70790 | |
| @@ -70791,11 +70981,11 @@ | |
| 70791 | /* |
| 70792 | ** Helper function for sqlite3VdbeSorterRewind(). |
| 70793 | */ |
| 70794 | static int vdbeSorterInitMerge( |
| 70795 | sqlite3 *db, /* Database handle */ |
| 70796 | VdbeCursor *pCsr, /* Cursor handle for this sorter */ |
| 70797 | i64 *pnByte /* Sum of bytes in all opened PMAs */ |
| 70798 | ){ |
| 70799 | VdbeSorter *pSorter = pCsr->pSorter; |
| 70800 | int rc = SQLITE_OK; /* Return code */ |
| 70801 | int i; /* Used to iterator through aIter[] */ |
| @@ -70821,11 +71011,11 @@ | |
| 70821 | |
| 70822 | /* |
| 70823 | ** Once the sorter has been populated, this function is called to prepare |
| 70824 | ** for iterating through its contents in sorted order. |
| 70825 | */ |
| 70826 | SQLITE_PRIVATE int sqlite3VdbeSorterRewind(sqlite3 *db, VdbeCursor *pCsr, int *pbEof){ |
| 70827 | VdbeSorter *pSorter = pCsr->pSorter; |
| 70828 | int rc; /* Return code */ |
| 70829 | sqlite3_file *pTemp2 = 0; /* Second temp file to use */ |
| 70830 | i64 iWrite2 = 0; /* Write offset for pTemp2 */ |
| 70831 | int nIter; /* Number of iterators used */ |
| @@ -70841,11 +71031,11 @@ | |
| 70841 | *pbEof = !pSorter->pRecord; |
| 70842 | assert( pSorter->aTree==0 ); |
| 70843 | return vdbeSorterSort(pCsr); |
| 70844 | } |
| 70845 | |
| 70846 | /* Write the current b-tree to a PMA. Close the b-tree cursor. */ |
| 70847 | rc = vdbeSorterListToPMA(db, pCsr); |
| 70848 | if( rc!=SQLITE_OK ) return rc; |
| 70849 | |
| 70850 | /* Allocate space for aIter[] and aTree[]. */ |
| 70851 | nIter = pSorter->nPMA; |
| @@ -70863,11 +71053,15 @@ | |
| 70863 | |
| 70864 | for(iNew=0; |
| 70865 | rc==SQLITE_OK && iNew*SORTER_MAX_MERGE_COUNT<pSorter->nPMA; |
| 70866 | iNew++ |
| 70867 | ){ |
| 70868 | i64 nWrite; /* Number of bytes in new PMA */ |
| 70869 | |
| 70870 | /* If there are SORTER_MAX_MERGE_COUNT or less PMAs in file pTemp1, |
| 70871 | ** initialize an iterator for each of them and break out of the loop. |
| 70872 | ** These iterators will be incrementally merged as the VDBE layer calls |
| 70873 | ** sqlite3VdbeSorterNext(). |
| @@ -70886,27 +71080,24 @@ | |
| 70886 | if( pTemp2==0 ){ |
| 70887 | assert( iWrite2==0 ); |
| 70888 | rc = vdbeSorterOpenTempFile(db, &pTemp2); |
| 70889 | } |
| 70890 | |
| 70891 | if( rc==SQLITE_OK ){ |
| 70892 | rc = vdbeSorterWriteVarint(pTemp2, nWrite, &iWrite2); |
| 70893 | } |
| 70894 | |
| 70895 | if( rc==SQLITE_OK ){ |
| 70896 | int bEof = 0; |
| 70897 | while( rc==SQLITE_OK && bEof==0 ){ |
| 70898 | int nToWrite; |
| 70899 | VdbeSorterIter *pIter = &pSorter->aIter[ pSorter->aTree[1] ]; |
| 70900 | assert( pIter->pFile ); |
| 70901 | nToWrite = pIter->nKey + sqlite3VarintLen(pIter->nKey); |
| 70902 | rc = sqlite3OsWrite(pTemp2, pIter->aAlloc, nToWrite, iWrite2); |
| 70903 | iWrite2 += nToWrite; |
| 70904 | if( rc==SQLITE_OK ){ |
| 70905 | rc = sqlite3VdbeSorterNext(db, pCsr, &bEof); |
| 70906 | } |
| 70907 | } |
| 70908 | } |
| 70909 | } |
| 70910 | |
| 70911 | if( pSorter->nPMA<=SORTER_MAX_MERGE_COUNT ){ |
| 70912 | break; |
| @@ -70929,11 +71120,11 @@ | |
| 70929 | } |
| 70930 | |
| 70931 | /* |
| 70932 | ** Advance to the next element in the sorter. |
| 70933 | */ |
| 70934 | SQLITE_PRIVATE int sqlite3VdbeSorterNext(sqlite3 *db, VdbeCursor *pCsr, int *pbEof){ |
| 70935 | VdbeSorter *pSorter = pCsr->pSorter; |
| 70936 | int rc; /* Return code */ |
| 70937 | |
| 70938 | if( pSorter->aTree ){ |
| 70939 | int iPrev = pSorter->aTree[1];/* Index of iterator to advance */ |
| @@ -70959,11 +71150,11 @@ | |
| 70959 | /* |
| 70960 | ** Return a pointer to a buffer owned by the sorter that contains the |
| 70961 | ** current key. |
| 70962 | */ |
| 70963 | static void *vdbeSorterRowkey( |
| 70964 | VdbeSorter *pSorter, /* Sorter object */ |
| 70965 | int *pnKey /* OUT: Size of current key in bytes */ |
| 70966 | ){ |
| 70967 | void *pKey; |
| 70968 | if( pSorter->aTree ){ |
| 70969 | VdbeSorterIter *pIter; |
| @@ -70978,11 +71169,11 @@ | |
| 70978 | } |
| 70979 | |
| 70980 | /* |
| 70981 | ** Copy the current sorter key into the memory cell pOut. |
| 70982 | */ |
| 70983 | SQLITE_PRIVATE int sqlite3VdbeSorterRowkey(VdbeCursor *pCsr, Mem *pOut){ |
| 70984 | VdbeSorter *pSorter = pCsr->pSorter; |
| 70985 | void *pKey; int nKey; /* Sorter key to copy into pOut */ |
| 70986 | |
| 70987 | pKey = vdbeSorterRowkey(pSorter, &nKey); |
| 70988 | if( sqlite3VdbeMemGrow(pOut, nKey, 0) ){ |
| @@ -71004,11 +71195,11 @@ | |
| 71004 | ** Otherwise, set *pRes to a negative, zero or positive value if the |
| 71005 | ** key in pVal is smaller than, equal to or larger than the current sorter |
| 71006 | ** key. |
| 71007 | */ |
| 71008 | SQLITE_PRIVATE int sqlite3VdbeSorterCompare( |
| 71009 | VdbeCursor *pCsr, /* Sorter cursor */ |
| 71010 | Mem *pVal, /* Value to compare to current sorter key */ |
| 71011 | int *pRes /* OUT: Result of comparison */ |
| 71012 | ){ |
| 71013 | VdbeSorter *pSorter = pCsr->pSorter; |
| 71014 | void *pKey; int nKey; /* Sorter key to compare pVal with */ |
| @@ -74591,11 +74782,11 @@ | |
| 74591 | SelectDest dest; |
| 74592 | ExprList *pEList; |
| 74593 | |
| 74594 | assert( !isRowid ); |
| 74595 | sqlite3SelectDestInit(&dest, SRT_Set, pExpr->iTable); |
| 74596 | dest.affinity = (u8)affinity; |
| 74597 | assert( (pExpr->iTable&0x0000FFFF)==pExpr->iTable ); |
| 74598 | pExpr->x.pSelect->iLimit = 0; |
| 74599 | if( sqlite3Select(pParse, pExpr->x.pSelect, &dest) ){ |
| 74600 | return 0; |
| 74601 | } |
| @@ -74684,25 +74875,25 @@ | |
| 74684 | assert( ExprHasProperty(pExpr, EP_xIsSelect) ); |
| 74685 | pSel = pExpr->x.pSelect; |
| 74686 | sqlite3SelectDestInit(&dest, 0, ++pParse->nMem); |
| 74687 | if( pExpr->op==TK_SELECT ){ |
| 74688 | dest.eDest = SRT_Mem; |
| 74689 | sqlite3VdbeAddOp2(v, OP_Null, 0, dest.iParm); |
| 74690 | VdbeComment((v, "Init subquery result")); |
| 74691 | }else{ |
| 74692 | dest.eDest = SRT_Exists; |
| 74693 | sqlite3VdbeAddOp2(v, OP_Integer, 0, dest.iParm); |
| 74694 | VdbeComment((v, "Init EXISTS result")); |
| 74695 | } |
| 74696 | sqlite3ExprDelete(pParse->db, pSel->pLimit); |
| 74697 | pSel->pLimit = sqlite3PExpr(pParse, TK_INTEGER, 0, 0, |
| 74698 | &sqlite3IntTokens[1]); |
| 74699 | pSel->iLimit = 0; |
| 74700 | if( sqlite3Select(pParse, pSel, &dest) ){ |
| 74701 | return 0; |
| 74702 | } |
| 74703 | rReg = dest.iParm; |
| 74704 | ExprSetIrreducible(pExpr); |
| 74705 | break; |
| 74706 | } |
| 74707 | } |
| 74708 | |
| @@ -78012,11 +78203,11 @@ | |
| 78012 | ** because the OpenWrite opcode below will be needing it. */ |
| 78013 | sqlite3NestedParse(pParse, |
| 78014 | "CREATE TABLE %Q.%s(%s)", pDb->zName, zTab, aTable[i].zCols |
| 78015 | ); |
| 78016 | aRoot[i] = pParse->regRoot; |
| 78017 | aCreateTbl[i] = 1; |
| 78018 | }else{ |
| 78019 | /* The table already exists. If zWhere is not NULL, delete all entries |
| 78020 | ** associated with the table zWhere. If zWhere is NULL, delete the |
| 78021 | ** entire contents of the table. */ |
| 78022 | aRoot[i] = pStat->tnum; |
| @@ -78092,16 +78283,15 @@ | |
| 78092 | |
| 78093 | UNUSED_PARAMETER(argc); |
| 78094 | nRow = (tRowcnt)sqlite3_value_int64(argv[0]); |
| 78095 | mxSample = sqlite3_value_int(argv[1]); |
| 78096 | n = sizeof(*p) + sizeof(p->a[0])*mxSample; |
| 78097 | p = sqlite3_malloc( n ); |
| 78098 | if( p==0 ){ |
| 78099 | sqlite3_result_error_nomem(context); |
| 78100 | return; |
| 78101 | } |
| 78102 | memset(p, 0, n); |
| 78103 | p->a = (struct Stat3Sample*)&p[1]; |
| 78104 | p->nRow = nRow; |
| 78105 | p->mxSample = mxSample; |
| 78106 | p->nPSample = p->nRow/(mxSample/3+1) + 1; |
| 78107 | sqlite3_randomness(sizeof(p->iPrn), &p->iPrn); |
| @@ -81354,11 +81544,11 @@ | |
| 81354 | SelectDest dest; |
| 81355 | Table *pSelTab; |
| 81356 | |
| 81357 | assert(pParse->nTab==1); |
| 81358 | sqlite3VdbeAddOp3(v, OP_OpenWrite, 1, pParse->regRoot, iDb); |
| 81359 | sqlite3VdbeChangeP5(v, 1); |
| 81360 | pParse->nTab = 2; |
| 81361 | sqlite3SelectDestInit(&dest, SRT_Table, 1); |
| 81362 | sqlite3Select(pParse, pSelect, &dest); |
| 81363 | sqlite3VdbeAddOp1(v, OP_Close, 1); |
| 81364 | if( pParse->nErr==0 ){ |
| @@ -82170,13 +82360,11 @@ | |
| 82170 | sqlite3VdbeAddOp2(v, OP_Clear, tnum, iDb); |
| 82171 | } |
| 82172 | pKey = sqlite3IndexKeyinfo(pParse, pIndex); |
| 82173 | sqlite3VdbeAddOp4(v, OP_OpenWrite, iIdx, tnum, iDb, |
| 82174 | (char *)pKey, P4_KEYINFO_HANDOFF); |
| 82175 | if( memRootPage>=0 ){ |
| 82176 | sqlite3VdbeChangeP5(v, 1); |
| 82177 | } |
| 82178 | |
| 82179 | #ifndef SQLITE_OMIT_MERGE_SORT |
| 82180 | /* Open the sorter cursor if we are to use one. */ |
| 82181 | iSorter = pParse->nTab++; |
| 82182 | sqlite3VdbeAddOp4(v, OP_SorterOpen, iSorter, 0, 0, (char*)pKey, P4_KEYINFO); |
| @@ -88191,11 +88379,11 @@ | |
| 88191 | regEof = ++pParse->nMem; |
| 88192 | sqlite3VdbeAddOp2(v, OP_Integer, 0, regEof); /* EOF <- 0 */ |
| 88193 | VdbeComment((v, "SELECT eof flag")); |
| 88194 | sqlite3SelectDestInit(&dest, SRT_Coroutine, ++pParse->nMem); |
| 88195 | addrSelect = sqlite3VdbeCurrentAddr(v)+2; |
| 88196 | sqlite3VdbeAddOp2(v, OP_Integer, addrSelect-1, dest.iParm); |
| 88197 | j1 = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0); |
| 88198 | VdbeComment((v, "Jump over SELECT coroutine")); |
| 88199 | |
| 88200 | /* Resolve the expressions in the SELECT statement and execute it. */ |
| 88201 | rc = sqlite3Select(pParse, pSelect, &dest); |
| @@ -88202,19 +88390,19 @@ | |
| 88202 | assert( pParse->nErr==0 || rc ); |
| 88203 | if( rc || NEVER(pParse->nErr) || db->mallocFailed ){ |
| 88204 | goto insert_cleanup; |
| 88205 | } |
| 88206 | sqlite3VdbeAddOp2(v, OP_Integer, 1, regEof); /* EOF <- 1 */ |
| 88207 | sqlite3VdbeAddOp1(v, OP_Yield, dest.iParm); /* yield X */ |
| 88208 | sqlite3VdbeAddOp2(v, OP_Halt, SQLITE_INTERNAL, OE_Abort); |
| 88209 | VdbeComment((v, "End of SELECT coroutine")); |
| 88210 | sqlite3VdbeJumpHere(v, j1); /* label B: */ |
| 88211 | |
| 88212 | regFromSelect = dest.iMem; |
| 88213 | assert( pSelect->pEList ); |
| 88214 | nColumn = pSelect->pEList->nExpr; |
| 88215 | assert( dest.nMem==nColumn ); |
| 88216 | |
| 88217 | /* Set useTempTable to TRUE if the result of the SELECT statement |
| 88218 | ** should be written into a temporary table (template 4). Set to |
| 88219 | ** FALSE if each* row of the SELECT can be written directly into |
| 88220 | ** the destination table (template 3). |
| @@ -88246,11 +88434,11 @@ | |
| 88246 | |
| 88247 | srcTab = pParse->nTab++; |
| 88248 | regRec = sqlite3GetTempReg(pParse); |
| 88249 | regTempRowid = sqlite3GetTempReg(pParse); |
| 88250 | sqlite3VdbeAddOp2(v, OP_OpenEphemeral, srcTab, nColumn); |
| 88251 | addrTop = sqlite3VdbeAddOp1(v, OP_Yield, dest.iParm); |
| 88252 | addrIf = sqlite3VdbeAddOp1(v, OP_If, regEof); |
| 88253 | sqlite3VdbeAddOp3(v, OP_MakeRecord, regFromSelect, nColumn, regRec); |
| 88254 | sqlite3VdbeAddOp2(v, OP_NewRowid, srcTab, regTempRowid); |
| 88255 | sqlite3VdbeAddOp3(v, OP_Insert, srcTab, regRec, regTempRowid); |
| 88256 | sqlite3VdbeAddOp2(v, OP_Goto, 0, addrTop); |
| @@ -88383,11 +88571,11 @@ | |
| 88383 | ** if EOF goto D |
| 88384 | ** insert the select result into <table> from R..R+n |
| 88385 | ** goto C |
| 88386 | ** D: ... |
| 88387 | */ |
| 88388 | addrCont = sqlite3VdbeAddOp1(v, OP_Yield, dest.iParm); |
| 88389 | addrInsTop = sqlite3VdbeAddOp1(v, OP_If, regEof); |
| 88390 | } |
| 88391 | |
| 88392 | /* Allocate registers for holding the rowid of the new row, |
| 88393 | ** the content of the new row, and the assemblied row record. |
| @@ -91865,10 +92053,23 @@ | |
| 91865 | { OP_String8, 0, 3, 0}, /* 2 */ |
| 91866 | { OP_ResultRow, 3, 1, 0}, |
| 91867 | }; |
| 91868 | |
| 91869 | int isQuick = (sqlite3Tolower(zLeft[0])=='q'); |
| 91870 | |
| 91871 | /* Initialize the VDBE program */ |
| 91872 | if( sqlite3ReadSchema(pParse) ) goto pragma_out; |
| 91873 | pParse->nMem = 6; |
| 91874 | sqlite3VdbeSetNumCols(v, 1); |
| @@ -91889,10 +92090,11 @@ | |
| 91889 | HashElem *x; |
| 91890 | Hash *pTbls; |
| 91891 | int cnt = 0; |
| 91892 | |
| 91893 | if( OMIT_TEMPDB && i==1 ) continue; |
| 91894 | |
| 91895 | sqlite3CodeVerifySchema(pParse, i); |
| 91896 | addr = sqlite3VdbeAddOp1(v, OP_IfPos, 1); /* Halt if out of errors */ |
| 91897 | sqlite3VdbeAddOp2(v, OP_Halt, 0, 0); |
| 91898 | sqlite3VdbeJumpHere(v, addr); |
| @@ -91900,11 +92102,11 @@ | |
| 91900 | /* Do an integrity check of the B-Tree |
| 91901 | ** |
| 91902 | ** Begin by filling registers 2, 3, ... with the root pages numbers |
| 91903 | ** for all tables and indices in the database. |
| 91904 | */ |
| 91905 | assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); |
| 91906 | pTbls = &db->aDb[i].pSchema->tblHash; |
| 91907 | for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){ |
| 91908 | Table *pTab = sqliteHashData(x); |
| 91909 | Index *pIdx; |
| 91910 | sqlite3VdbeAddOp2(v, OP_Integer, pTab->tnum, 2+cnt); |
| @@ -93224,14 +93426,14 @@ | |
| 93224 | /* |
| 93225 | ** Initialize a SelectDest structure. |
| 93226 | */ |
| 93227 | SQLITE_PRIVATE void sqlite3SelectDestInit(SelectDest *pDest, int eDest, int iParm){ |
| 93228 | pDest->eDest = (u8)eDest; |
| 93229 | pDest->iParm = iParm; |
| 93230 | pDest->affinity = 0; |
| 93231 | pDest->iMem = 0; |
| 93232 | pDest->nMem = 0; |
| 93233 | } |
| 93234 | |
| 93235 | |
| 93236 | /* |
| 93237 | ** Allocate a new Select structure and return a pointer to that |
| @@ -93739,11 +93941,11 @@ | |
| 93739 | Vdbe *v = pParse->pVdbe; |
| 93740 | int i; |
| 93741 | int hasDistinct; /* True if the DISTINCT keyword is present */ |
| 93742 | int regResult; /* Start of memory holding result set */ |
| 93743 | int eDest = pDest->eDest; /* How to dispose of results */ |
| 93744 | int iParm = pDest->iParm; /* First argument to disposal method */ |
| 93745 | int nResultCol; /* Number of result columns */ |
| 93746 | |
| 93747 | assert( v ); |
| 93748 | if( NEVER(v==0) ) return; |
| 93749 | assert( pEList!=0 ); |
| @@ -93757,18 +93959,18 @@ | |
| 93757 | if( nColumn>0 ){ |
| 93758 | nResultCol = nColumn; |
| 93759 | }else{ |
| 93760 | nResultCol = pEList->nExpr; |
| 93761 | } |
| 93762 | if( pDest->iMem==0 ){ |
| 93763 | pDest->iMem = pParse->nMem+1; |
| 93764 | pDest->nMem = nResultCol; |
| 93765 | pParse->nMem += nResultCol; |
| 93766 | }else{ |
| 93767 | assert( pDest->nMem==nResultCol ); |
| 93768 | } |
| 93769 | regResult = pDest->iMem; |
| 93770 | if( nColumn>0 ){ |
| 93771 | for(i=0; i<nColumn; i++){ |
| 93772 | sqlite3VdbeAddOp3(v, OP_Column, srcTab, i, regResult+i); |
| 93773 | } |
| 93774 | }else if( eDest!=SRT_Exists ){ |
| @@ -93843,11 +94045,11 @@ | |
| 93843 | ** then there should be a single item on the stack. Write this |
| 93844 | ** item into the set table with bogus data. |
| 93845 | */ |
| 93846 | case SRT_Set: { |
| 93847 | assert( nColumn==1 ); |
| 93848 | p->affinity = sqlite3CompareAffinity(pEList->a[0].pExpr, pDest->affinity); |
| 93849 | if( pOrderBy ){ |
| 93850 | /* At first glance you would think we could optimize out the |
| 93851 | ** ORDER BY in this case since the order of entries in the set |
| 93852 | ** does not matter. But there might be a LIMIT clause, in which |
| 93853 | ** case the order does matter */ |
| @@ -93898,11 +94100,11 @@ | |
| 93898 | int r1 = sqlite3GetTempReg(pParse); |
| 93899 | sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nColumn, r1); |
| 93900 | pushOntoSorter(pParse, pOrderBy, p, r1); |
| 93901 | sqlite3ReleaseTempReg(pParse, r1); |
| 93902 | }else if( eDest==SRT_Coroutine ){ |
| 93903 | sqlite3VdbeAddOp1(v, OP_Yield, pDest->iParm); |
| 93904 | }else{ |
| 93905 | sqlite3VdbeAddOp2(v, OP_ResultRow, regResult, nColumn); |
| 93906 | sqlite3ExprCacheAffinityChange(pParse, regResult, nColumn); |
| 93907 | } |
| 93908 | break; |
| @@ -94078,11 +94280,11 @@ | |
| 94078 | int iTab; |
| 94079 | int pseudoTab = 0; |
| 94080 | ExprList *pOrderBy = p->pOrderBy; |
| 94081 | |
| 94082 | int eDest = pDest->eDest; |
| 94083 | int iParm = pDest->iParm; |
| 94084 | |
| 94085 | int regRow; |
| 94086 | int regRowid; |
| 94087 | |
| 94088 | iTab = pOrderBy->iECursor; |
| @@ -94137,21 +94339,21 @@ | |
| 94137 | int i; |
| 94138 | assert( eDest==SRT_Output || eDest==SRT_Coroutine ); |
| 94139 | testcase( eDest==SRT_Output ); |
| 94140 | testcase( eDest==SRT_Coroutine ); |
| 94141 | for(i=0; i<nColumn; i++){ |
| 94142 | assert( regRow!=pDest->iMem+i ); |
| 94143 | sqlite3VdbeAddOp3(v, OP_Column, pseudoTab, i, pDest->iMem+i); |
| 94144 | if( i==0 ){ |
| 94145 | sqlite3VdbeChangeP5(v, OPFLAG_CLEARCACHE); |
| 94146 | } |
| 94147 | } |
| 94148 | if( eDest==SRT_Output ){ |
| 94149 | sqlite3VdbeAddOp2(v, OP_ResultRow, pDest->iMem, nColumn); |
| 94150 | sqlite3ExprCacheAffinityChange(pParse, pDest->iMem, nColumn); |
| 94151 | }else{ |
| 94152 | sqlite3VdbeAddOp1(v, OP_Yield, pDest->iParm); |
| 94153 | } |
| 94154 | break; |
| 94155 | } |
| 94156 | } |
| 94157 | sqlite3ReleaseTempReg(pParse, regRow); |
| @@ -94798,11 +95000,11 @@ | |
| 94798 | |
| 94799 | /* Create the destination temporary table if necessary |
| 94800 | */ |
| 94801 | if( dest.eDest==SRT_EphemTab ){ |
| 94802 | assert( p->pEList ); |
| 94803 | sqlite3VdbeAddOp2(v, OP_OpenEphemeral, dest.iParm, p->pEList->nExpr); |
| 94804 | sqlite3VdbeChangeP5(v, BTREE_UNORDERED); |
| 94805 | dest.eDest = SRT_Table; |
| 94806 | } |
| 94807 | |
| 94808 | /* Make sure all SELECTs in the statement have the same number of elements |
| @@ -94884,11 +95086,11 @@ | |
| 94884 | */ |
| 94885 | assert( p->pRightmost!=p ); /* Can only happen for leftward elements |
| 94886 | ** of a 3-way or more compound */ |
| 94887 | assert( p->pLimit==0 ); /* Not allowed on leftward elements */ |
| 94888 | assert( p->pOffset==0 ); /* Not allowed on leftward elements */ |
| 94889 | unionTab = dest.iParm; |
| 94890 | }else{ |
| 94891 | /* We will need to create our own temporary table to hold the |
| 94892 | ** intermediate results. |
| 94893 | */ |
| 94894 | unionTab = pParse->nTab++; |
| @@ -94941,11 +95143,11 @@ | |
| 94941 | p->iOffset = 0; |
| 94942 | |
| 94943 | /* Convert the data in the temporary table into whatever form |
| 94944 | ** it is that we currently need. |
| 94945 | */ |
| 94946 | assert( unionTab==dest.iParm || dest.eDest!=priorOp ); |
| 94947 | if( dest.eDest!=priorOp ){ |
| 94948 | int iCont, iBreak, iStart; |
| 94949 | assert( p->pEList ); |
| 94950 | if( dest.eDest==SRT_Output ){ |
| 94951 | Select *pFirst = p; |
| @@ -95005,11 +95207,11 @@ | |
| 95005 | p->pPrior = 0; |
| 95006 | pLimit = p->pLimit; |
| 95007 | p->pLimit = 0; |
| 95008 | pOffset = p->pOffset; |
| 95009 | p->pOffset = 0; |
| 95010 | intersectdest.iParm = tab2; |
| 95011 | explainSetInteger(iSub2, pParse->iNextSelectId); |
| 95012 | rc = sqlite3Select(pParse, p, &intersectdest); |
| 95013 | testcase( rc!=SQLITE_OK ); |
| 95014 | pDelete = p->pPrior; |
| 95015 | p->pPrior = pPrior; |
| @@ -95099,23 +95301,23 @@ | |
| 95099 | } |
| 95100 | sqlite3DbFree(db, pKeyInfo); |
| 95101 | } |
| 95102 | |
| 95103 | multi_select_end: |
| 95104 | pDest->iMem = dest.iMem; |
| 95105 | pDest->nMem = dest.nMem; |
| 95106 | sqlite3SelectDelete(db, pDelete); |
| 95107 | return rc; |
| 95108 | } |
| 95109 | #endif /* SQLITE_OMIT_COMPOUND_SELECT */ |
| 95110 | |
| 95111 | /* |
| 95112 | ** Code an output subroutine for a coroutine implementation of a |
| 95113 | ** SELECT statment. |
| 95114 | ** |
| 95115 | ** The data to be output is contained in pIn->iMem. There are |
| 95116 | ** pIn->nMem columns to be output. pDest is where the output should |
| 95117 | ** be sent. |
| 95118 | ** |
| 95119 | ** regReturn is the number of the register holding the subroutine |
| 95120 | ** return address. |
| 95121 | ** |
| @@ -95149,15 +95351,15 @@ | |
| 95149 | /* Suppress duplicates for UNION, EXCEPT, and INTERSECT |
| 95150 | */ |
| 95151 | if( regPrev ){ |
| 95152 | int j1, j2; |
| 95153 | j1 = sqlite3VdbeAddOp1(v, OP_IfNot, regPrev); |
| 95154 | j2 = sqlite3VdbeAddOp4(v, OP_Compare, pIn->iMem, regPrev+1, pIn->nMem, |
| 95155 | (char*)pKeyInfo, p4type); |
| 95156 | sqlite3VdbeAddOp3(v, OP_Jump, j2+2, iContinue, j2+2); |
| 95157 | sqlite3VdbeJumpHere(v, j1); |
| 95158 | sqlite3ExprCodeCopy(pParse, pIn->iMem, regPrev+1, pIn->nMem); |
| 95159 | sqlite3VdbeAddOp2(v, OP_Integer, 1, regPrev); |
| 95160 | } |
| 95161 | if( pParse->db->mallocFailed ) return 0; |
| 95162 | |
| 95163 | /* Suppress the the first OFFSET entries if there is an OFFSET clause |
| @@ -95171,13 +95373,13 @@ | |
| 95171 | case SRT_EphemTab: { |
| 95172 | int r1 = sqlite3GetTempReg(pParse); |
| 95173 | int r2 = sqlite3GetTempReg(pParse); |
| 95174 | testcase( pDest->eDest==SRT_Table ); |
| 95175 | testcase( pDest->eDest==SRT_EphemTab ); |
| 95176 | sqlite3VdbeAddOp3(v, OP_MakeRecord, pIn->iMem, pIn->nMem, r1); |
| 95177 | sqlite3VdbeAddOp2(v, OP_NewRowid, pDest->iParm, r2); |
| 95178 | sqlite3VdbeAddOp3(v, OP_Insert, pDest->iParm, r1, r2); |
| 95179 | sqlite3VdbeChangeP5(v, OPFLAG_APPEND); |
| 95180 | sqlite3ReleaseTempReg(pParse, r2); |
| 95181 | sqlite3ReleaseTempReg(pParse, r1); |
| 95182 | break; |
| 95183 | } |
| @@ -95187,26 +95389,26 @@ | |
| 95187 | ** then there should be a single item on the stack. Write this |
| 95188 | ** item into the set table with bogus data. |
| 95189 | */ |
| 95190 | case SRT_Set: { |
| 95191 | int r1; |
| 95192 | assert( pIn->nMem==1 ); |
| 95193 | p->affinity = |
| 95194 | sqlite3CompareAffinity(p->pEList->a[0].pExpr, pDest->affinity); |
| 95195 | r1 = sqlite3GetTempReg(pParse); |
| 95196 | sqlite3VdbeAddOp4(v, OP_MakeRecord, pIn->iMem, 1, r1, &p->affinity, 1); |
| 95197 | sqlite3ExprCacheAffinityChange(pParse, pIn->iMem, 1); |
| 95198 | sqlite3VdbeAddOp2(v, OP_IdxInsert, pDest->iParm, r1); |
| 95199 | sqlite3ReleaseTempReg(pParse, r1); |
| 95200 | break; |
| 95201 | } |
| 95202 | |
| 95203 | #if 0 /* Never occurs on an ORDER BY query */ |
| 95204 | /* If any row exist in the result set, record that fact and abort. |
| 95205 | */ |
| 95206 | case SRT_Exists: { |
| 95207 | sqlite3VdbeAddOp2(v, OP_Integer, 1, pDest->iParm); |
| 95208 | /* The LIMIT clause will terminate the loop for us */ |
| 95209 | break; |
| 95210 | } |
| 95211 | #endif |
| 95212 | |
| @@ -95213,27 +95415,27 @@ | |
| 95213 | /* If this is a scalar select that is part of an expression, then |
| 95214 | ** store the results in the appropriate memory cell and break out |
| 95215 | ** of the scan loop. |
| 95216 | */ |
| 95217 | case SRT_Mem: { |
| 95218 | assert( pIn->nMem==1 ); |
| 95219 | sqlite3ExprCodeMove(pParse, pIn->iMem, pDest->iParm, 1); |
| 95220 | /* The LIMIT clause will jump out of the loop for us */ |
| 95221 | break; |
| 95222 | } |
| 95223 | #endif /* #ifndef SQLITE_OMIT_SUBQUERY */ |
| 95224 | |
| 95225 | /* The results are stored in a sequence of registers |
| 95226 | ** starting at pDest->iMem. Then the co-routine yields. |
| 95227 | */ |
| 95228 | case SRT_Coroutine: { |
| 95229 | if( pDest->iMem==0 ){ |
| 95230 | pDest->iMem = sqlite3GetTempRange(pParse, pIn->nMem); |
| 95231 | pDest->nMem = pIn->nMem; |
| 95232 | } |
| 95233 | sqlite3ExprCodeMove(pParse, pIn->iMem, pDest->iMem, pDest->nMem); |
| 95234 | sqlite3VdbeAddOp1(v, OP_Yield, pDest->iParm); |
| 95235 | break; |
| 95236 | } |
| 95237 | |
| 95238 | /* If none of the above, then the result destination must be |
| 95239 | ** SRT_Output. This routine is never called with any other |
| @@ -95243,12 +95445,12 @@ | |
| 95243 | ** Then the OP_ResultRow opcode is used to cause sqlite3_step() to |
| 95244 | ** return the next row of result. |
| 95245 | */ |
| 95246 | default: { |
| 95247 | assert( pDest->eDest==SRT_Output ); |
| 95248 | sqlite3VdbeAddOp2(v, OP_ResultRow, pIn->iMem, pIn->nMem); |
| 95249 | sqlite3ExprCacheAffinityChange(pParse, pIn->iMem, pIn->nMem); |
| 95250 | break; |
| 95251 | } |
| 95252 | } |
| 95253 | |
| 95254 | /* Jump to the end of the loop if the LIMIT is reached. |
| @@ -95663,11 +95865,11 @@ | |
| 95663 | |
| 95664 | /* Implement the main merge loop |
| 95665 | */ |
| 95666 | sqlite3VdbeResolveLabel(v, labelCmpr); |
| 95667 | sqlite3VdbeAddOp4(v, OP_Permutation, 0, 0, 0, (char*)aPermute, P4_INTARRAY); |
| 95668 | sqlite3VdbeAddOp4(v, OP_Compare, destA.iMem, destB.iMem, nOrderBy, |
| 95669 | (char*)pKeyMerge, P4_KEYINFO_HANDOFF); |
| 95670 | sqlite3VdbeAddOp3(v, OP_Jump, addrAltB, addrAeqB, addrAgtB); |
| 95671 | |
| 95672 | /* Release temporary registers |
| 95673 | */ |
| @@ -96909,37 +97111,38 @@ | |
| 96909 | ** SRT_Output Generate a row of output (using the OP_ResultRow |
| 96910 | ** opcode) for each row in the result set. |
| 96911 | ** |
| 96912 | ** SRT_Mem Only valid if the result is a single column. |
| 96913 | ** Store the first column of the first result row |
| 96914 | ** in register pDest->iParm then abandon the rest |
| 96915 | ** of the query. This destination implies "LIMIT 1". |
| 96916 | ** |
| 96917 | ** SRT_Set The result must be a single column. Store each |
| 96918 | ** row of result as the key in table pDest->iParm. |
| 96919 | ** Apply the affinity pDest->affinity before storing |
| 96920 | ** results. Used to implement "IN (SELECT ...)". |
| 96921 | ** |
| 96922 | ** SRT_Union Store results as a key in a temporary table pDest->iParm. |
| 96923 | ** |
| 96924 | ** SRT_Except Remove results from the temporary table pDest->iParm. |
| 96925 | ** |
| 96926 | ** SRT_Table Store results in temporary table pDest->iParm. |
| 96927 | ** This is like SRT_EphemTab except that the table |
| 96928 | ** is assumed to already be open. |
| 96929 | ** |
| 96930 | ** SRT_EphemTab Create an temporary table pDest->iParm and store |
| 96931 | ** the result there. The cursor is left open after |
| 96932 | ** returning. This is like SRT_Table except that |
| 96933 | ** this destination uses OP_OpenEphemeral to create |
| 96934 | ** the table first. |
| 96935 | ** |
| 96936 | ** SRT_Coroutine Generate a co-routine that returns a new row of |
| 96937 | ** results each time it is invoked. The entry point |
| 96938 | ** of the co-routine is stored in register pDest->iParm. |
| 96939 | ** |
| 96940 | ** SRT_Exists Store a 1 in memory cell pDest->iParm if the result |
| 96941 | ** set is not empty. |
| 96942 | ** |
| 96943 | ** SRT_Discard Throw the results away. This is used by SELECT |
| 96944 | ** statements within triggers whose only purpose is |
| 96945 | ** the side-effects of functions. |
| @@ -97179,11 +97382,11 @@ | |
| 97179 | } |
| 97180 | |
| 97181 | /* If the output is destined for a temporary table, open that table. |
| 97182 | */ |
| 97183 | if( pDest->eDest==SRT_EphemTab ){ |
| 97184 | sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pDest->iParm, pEList->nExpr); |
| 97185 | } |
| 97186 | |
| 97187 | /* Set the limiter. |
| 97188 | */ |
| 97189 | iEnd = sqlite3VdbeMakeLabel(v); |
| 97190 |
| --- src/sqlite3.c | |
| +++ src/sqlite3.c | |
| @@ -673,11 +673,11 @@ | |
| 673 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 674 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 675 | */ |
| 676 | #define SQLITE_VERSION "3.7.14" |
| 677 | #define SQLITE_VERSION_NUMBER 3007014 |
| 678 | #define SQLITE_SOURCE_ID "2012-08-14 17:29:27 6954fef006431d153de6e63e362b8d260ebeb1c6" |
| 679 | |
| 680 | /* |
| 681 | ** CAPI3REF: Run-Time Library Version Numbers |
| 682 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 683 | ** |
| @@ -4721,15 +4721,15 @@ | |
| 4721 | ** ^The sqlite3_result_error_code() function changes the error code |
| 4722 | ** returned by SQLite as a result of an error in a function. ^By default, |
| 4723 | ** the error code is SQLITE_ERROR. ^A subsequent call to sqlite3_result_error() |
| 4724 | ** or sqlite3_result_error16() resets the error code to SQLITE_ERROR. |
| 4725 | ** |
| 4726 | ** ^The sqlite3_result_error_toobig() interface causes SQLite to throw an |
| 4727 | ** error indicating that a string or BLOB is too long to represent. |
| 4728 | ** |
| 4729 | ** ^The sqlite3_result_error_nomem() interface causes SQLite to throw an |
| 4730 | ** error indicating that a memory allocation failed. |
| 4731 | ** |
| 4732 | ** ^The sqlite3_result_int() interface sets the return value |
| 4733 | ** of the application-defined function to be the 32-bit signed integer |
| 4734 | ** value given in the 2nd argument. |
| 4735 | ** ^The sqlite3_result_int64() interface sets the return value |
| @@ -8397,10 +8397,16 @@ | |
| 8397 | #define BTREE_LARGEST_ROOT_PAGE 4 |
| 8398 | #define BTREE_TEXT_ENCODING 5 |
| 8399 | #define BTREE_USER_VERSION 6 |
| 8400 | #define BTREE_INCR_VACUUM 7 |
| 8401 | |
| 8402 | /* |
| 8403 | ** Values that may be OR'd together to form the second argument of an |
| 8404 | ** sqlite3BtreeCursorHints() call. |
| 8405 | */ |
| 8406 | #define BTREE_BULKLOAD 0x00000001 |
| 8407 | |
| 8408 | SQLITE_PRIVATE int sqlite3BtreeCursor( |
| 8409 | Btree*, /* BTree containing table to open */ |
| 8410 | int iTable, /* Index of root page */ |
| 8411 | int wrFlag, /* 1 for writing. 0 for read-only */ |
| 8412 | struct KeyInfo*, /* First argument to compare function */ |
| @@ -8440,12 +8446,12 @@ | |
| 8446 | SQLITE_PRIVATE struct Pager *sqlite3BtreePager(Btree*); |
| 8447 | |
| 8448 | SQLITE_PRIVATE int sqlite3BtreePutData(BtCursor*, u32 offset, u32 amt, void*); |
| 8449 | SQLITE_PRIVATE void sqlite3BtreeCacheOverflow(BtCursor *); |
| 8450 | SQLITE_PRIVATE void sqlite3BtreeClearCursor(BtCursor *); |
| 8451 | SQLITE_PRIVATE int sqlite3BtreeSetVersion(Btree *pBt, int iVersion); |
| 8452 | SQLITE_PRIVATE void sqlite3BtreeCursorHints(BtCursor *, unsigned int mask); |
| 8453 | |
| 8454 | #ifndef NDEBUG |
| 8455 | SQLITE_PRIVATE int sqlite3BtreeCursorIsValid(BtCursor*); |
| 8456 | #endif |
| 8457 | |
| @@ -9384,12 +9390,12 @@ | |
| 9390 | #else |
| 9391 | # define SQLITE_OS_WINCE 0 |
| 9392 | #endif |
| 9393 | |
| 9394 | /* |
| 9395 | ** Determine if we are dealing with WinRT, which provides only a subset of |
| 9396 | ** the full Win32 API. |
| 9397 | */ |
| 9398 | #if !defined(SQLITE_OS_WINRT) |
| 9399 | # define SQLITE_OS_WINRT 0 |
| 9400 | #endif |
| 9401 | |
| @@ -11085,14 +11091,14 @@ | |
| 11091 | ** comments above sqlite3Select() for details. |
| 11092 | */ |
| 11093 | typedef struct SelectDest SelectDest; |
| 11094 | struct SelectDest { |
| 11095 | u8 eDest; /* How to dispose of the results */ |
| 11096 | u8 affSdst; /* Affinity used when eDest==SRT_Set */ |
| 11097 | int iSDParm; /* A parameter used by the eDest disposal method */ |
| 11098 | int iSdst; /* Base register where results are written */ |
| 11099 | int nSdst; /* Number of registers allocated */ |
| 11100 | }; |
| 11101 | |
| 11102 | /* |
| 11103 | ** During code generation of statements that do inserts into AUTOINCREMENT |
| 11104 | ** tables, the following information is attached to the Table.u.autoInc.p |
| @@ -11284,10 +11290,12 @@ | |
| 11290 | #define OPFLAG_APPEND 0x08 /* This is likely to be an append */ |
| 11291 | #define OPFLAG_USESEEKRESULT 0x10 /* Try to avoid a seek in BtreeInsert() */ |
| 11292 | #define OPFLAG_CLEARCACHE 0x20 /* Clear pseudo-table cache in OP_Column */ |
| 11293 | #define OPFLAG_LENGTHARG 0x40 /* OP_Column only used for length() */ |
| 11294 | #define OPFLAG_TYPEOFARG 0x80 /* OP_Column only used for typeof() */ |
| 11295 | #define OPFLAG_BULKCSR 0x01 /* OP_Open** used to open bulk cursor */ |
| 11296 | #define OPFLAG_P2ISREG 0x02 /* P2 to OP_Open** is a register number */ |
| 11297 | |
| 11298 | /* |
| 11299 | * Each trigger present in the database schema is stored as an instance of |
| 11300 | * struct Trigger. |
| 11301 | * |
| @@ -13354,15 +13362,15 @@ | |
| 13362 | # define sqlite3VdbeSorterNext(X,Y,Z) SQLITE_OK |
| 13363 | # define sqlite3VdbeSorterCompare(X,Y,Z) SQLITE_OK |
| 13364 | #else |
| 13365 | SQLITE_PRIVATE int sqlite3VdbeSorterInit(sqlite3 *, VdbeCursor *); |
| 13366 | SQLITE_PRIVATE void sqlite3VdbeSorterClose(sqlite3 *, VdbeCursor *); |
| 13367 | SQLITE_PRIVATE int sqlite3VdbeSorterRowkey(const VdbeCursor *, Mem *); |
| 13368 | SQLITE_PRIVATE int sqlite3VdbeSorterNext(sqlite3 *, const VdbeCursor *, int *); |
| 13369 | SQLITE_PRIVATE int sqlite3VdbeSorterRewind(sqlite3 *, const VdbeCursor *, int *); |
| 13370 | SQLITE_PRIVATE int sqlite3VdbeSorterWrite(sqlite3 *, const VdbeCursor *, Mem *); |
| 13371 | SQLITE_PRIVATE int sqlite3VdbeSorterCompare(const VdbeCursor *, Mem *, int *); |
| 13372 | #endif |
| 13373 | |
| 13374 | #if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE>0 |
| 13375 | SQLITE_PRIVATE void sqlite3VdbeEnter(Vdbe*); |
| 13376 | SQLITE_PRIVATE void sqlite3VdbeLeave(Vdbe*); |
| @@ -22185,11 +22193,15 @@ | |
| 22193 | if( new_size==pH->htsize ) return 0; |
| 22194 | #endif |
| 22195 | |
| 22196 | /* The inability to allocates space for a larger hash table is |
| 22197 | ** a performance hit but it is not a fatal error. So mark the |
| 22198 | ** allocation as a benign. Use sqlite3Malloc()/memset(0) instead of |
| 22199 | ** sqlite3MallocZero() to make the allocation, as sqlite3MallocZero() |
| 22200 | ** only zeroes the requested number of bytes whereas this module will |
| 22201 | ** use the actual amount of space allocated for the hash table (which |
| 22202 | ** may be larger than the requested amount). |
| 22203 | */ |
| 22204 | sqlite3BeginBenignMalloc(); |
| 22205 | new_ht = (struct _ht *)sqlite3Malloc( new_size*sizeof(struct _ht) ); |
| 22206 | sqlite3EndBenignMalloc(); |
| 22207 | |
| @@ -30109,11 +30121,12 @@ | |
| 30121 | #endif |
| 30122 | |
| 30123 | #define osCreateFileW ((HANDLE(WINAPI*)(LPCWSTR,DWORD,DWORD, \ |
| 30124 | LPSECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE))aSyscall[5].pCurrent) |
| 30125 | |
| 30126 | #if SQLITE_OS_WINCE || (!SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) && \ |
| 30127 | !defined(SQLITE_OMIT_WAL)) |
| 30128 | { "CreateFileMappingW", (SYSCALL)CreateFileMappingW, 0 }, |
| 30129 | #else |
| 30130 | { "CreateFileMappingW", (SYSCALL)0, 0 }, |
| 30131 | #endif |
| 30132 | |
| @@ -30421,11 +30434,11 @@ | |
| 30434 | #ifndef osLockFileEx |
| 30435 | #define osLockFileEx ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD,DWORD, \ |
| 30436 | LPOVERLAPPED))aSyscall[45].pCurrent) |
| 30437 | #endif |
| 30438 | |
| 30439 | #if SQLITE_OS_WINCE || (!SQLITE_OS_WINRT && !defined(SQLITE_OMIT_WAL)) |
| 30440 | { "MapViewOfFile", (SYSCALL)MapViewOfFile, 0 }, |
| 30441 | #else |
| 30442 | { "MapViewOfFile", (SYSCALL)0, 0 }, |
| 30443 | #endif |
| 30444 | |
| @@ -30491,11 +30504,15 @@ | |
| 30504 | #endif |
| 30505 | |
| 30506 | #define osUnlockFileEx ((BOOL(WINAPI*)(HANDLE,DWORD,DWORD,DWORD, \ |
| 30507 | LPOVERLAPPED))aSyscall[55].pCurrent) |
| 30508 | |
| 30509 | #if SQLITE_OS_WINCE || !defined(SQLITE_OMIT_WAL) |
| 30510 | { "UnmapViewOfFile", (SYSCALL)UnmapViewOfFile, 0 }, |
| 30511 | #else |
| 30512 | { "UnmapViewOfFile", (SYSCALL)0, 0 }, |
| 30513 | #endif |
| 30514 | |
| 30515 | #define osUnmapViewOfFile ((BOOL(WINAPI*)(LPCVOID))aSyscall[56].pCurrent) |
| 30516 | |
| 30517 | { "WideCharToMultiByte", (SYSCALL)WideCharToMultiByte, 0 }, |
| 30518 | |
| @@ -30523,20 +30540,20 @@ | |
| 30540 | #endif |
| 30541 | |
| 30542 | #define osWaitForSingleObject ((DWORD(WINAPI*)(HANDLE, \ |
| 30543 | DWORD))aSyscall[60].pCurrent) |
| 30544 | |
| 30545 | #if SQLITE_OS_WINRT |
| 30546 | { "WaitForSingleObjectEx", (SYSCALL)WaitForSingleObjectEx, 0 }, |
| 30547 | #else |
| 30548 | { "WaitForSingleObjectEx", (SYSCALL)0, 0 }, |
| 30549 | #endif |
| 30550 | |
| 30551 | #define osWaitForSingleObjectEx ((DWORD(WINAPI*)(HANDLE,DWORD, \ |
| 30552 | BOOL))aSyscall[61].pCurrent) |
| 30553 | |
| 30554 | #if SQLITE_OS_WINRT |
| 30555 | { "SetFilePointerEx", (SYSCALL)SetFilePointerEx, 0 }, |
| 30556 | #else |
| 30557 | { "SetFilePointerEx", (SYSCALL)0, 0 }, |
| 30558 | #endif |
| 30559 | |
| @@ -30550,11 +30567,11 @@ | |
| 30567 | #endif |
| 30568 | |
| 30569 | #define osGetFileInformationByHandleEx ((BOOL(WINAPI*)(HANDLE, \ |
| 30570 | FILE_INFO_BY_HANDLE_CLASS,LPVOID,DWORD))aSyscall[63].pCurrent) |
| 30571 | |
| 30572 | #if SQLITE_OS_WINRT && !defined(SQLITE_OMIT_WAL) |
| 30573 | { "MapViewOfFileFromApp", (SYSCALL)MapViewOfFileFromApp, 0 }, |
| 30574 | #else |
| 30575 | { "MapViewOfFileFromApp", (SYSCALL)0, 0 }, |
| 30576 | #endif |
| 30577 | |
| @@ -30614,11 +30631,11 @@ | |
| 30631 | |
| 30632 | { "GetProcessHeap", (SYSCALL)GetProcessHeap, 0 }, |
| 30633 | |
| 30634 | #define osGetProcessHeap ((HANDLE(WINAPI*)(VOID))aSyscall[71].pCurrent) |
| 30635 | |
| 30636 | #if SQLITE_OS_WINRT && !defined(SQLITE_OMIT_WAL) |
| 30637 | { "CreateFileMappingFromApp", (SYSCALL)CreateFileMappingFromApp, 0 }, |
| 30638 | #else |
| 30639 | { "CreateFileMappingFromApp", (SYSCALL)0, 0 }, |
| 30640 | #endif |
| 30641 | |
| @@ -34472,14 +34489,13 @@ | |
| 34489 | void *pTmpSpace; |
| 34490 | |
| 34491 | /* Allocate the Bitvec to be tested and a linear array of |
| 34492 | ** bits to act as the reference */ |
| 34493 | pBitvec = sqlite3BitvecCreate( sz ); |
| 34494 | pV = sqlite3MallocZero( (sz+7)/8 + 1 ); |
| 34495 | pTmpSpace = sqlite3_malloc(BITVEC_SZ); |
| 34496 | if( pBitvec==0 || pV==0 || pTmpSpace==0 ) goto bitvec_end; |
| 34497 | |
| 34498 | /* NULL pBitvec tests */ |
| 34499 | sqlite3BitvecSet(0, 1); |
| 34500 | sqlite3BitvecClear(0, 1, pTmpSpace); |
| 34501 | |
| @@ -35559,15 +35575,14 @@ | |
| 35575 | nNew = 256; |
| 35576 | } |
| 35577 | |
| 35578 | pcache1LeaveMutex(p->pGroup); |
| 35579 | if( p->nHash ){ sqlite3BeginBenignMalloc(); } |
| 35580 | apNew = (PgHdr1 **)sqlite3MallocZero(sizeof(PgHdr1 *)*nNew); |
| 35581 | if( p->nHash ){ sqlite3EndBenignMalloc(); } |
| 35582 | pcache1EnterMutex(p->pGroup); |
| 35583 | if( apNew ){ |
| 35584 | for(i=0; i<p->nHash; i++){ |
| 35585 | PgHdr1 *pPage; |
| 35586 | PgHdr1 *pNext = p->apHash[i]; |
| 35587 | while( (pPage = pNext)!=0 ){ |
| 35588 | unsigned int h = pPage->iKey % nNew; |
| @@ -35747,13 +35762,12 @@ | |
| 35762 | |
| 35763 | assert( (szPage & (szPage-1))==0 && szPage>=512 && szPage<=65536 ); |
| 35764 | assert( szExtra < 300 ); |
| 35765 | |
| 35766 | sz = sizeof(PCache1) + sizeof(PGroup)*separateCache; |
| 35767 | pCache = (PCache1 *)sqlite3MallocZero(sz); |
| 35768 | if( pCache ){ |
| 35769 | if( separateCache ){ |
| 35770 | pGroup = (PGroup*)&pCache[1]; |
| 35771 | pGroup->mxPinned = 10; |
| 35772 | }else{ |
| 35773 | pGroup = &pcache1.grp; |
| @@ -43916,12 +43930,13 @@ | |
| 43930 | ** Hence, unlike the database and WAL file formats which store all values |
| 43931 | ** as big endian, the wal-index can store multi-byte values in the native |
| 43932 | ** byte order of the host computer. |
| 43933 | ** |
| 43934 | ** The purpose of the wal-index is to answer this question quickly: Given |
| 43935 | ** a page number P and a maximum frame index M, return the index of the |
| 43936 | ** last frame in the wal before frame M for page P in the WAL, or return |
| 43937 | ** NULL if there are no frames for page P in the WAL prior to M. |
| 43938 | ** |
| 43939 | ** The wal-index consists of a header region, followed by an one or |
| 43940 | ** more index blocks. |
| 43941 | ** |
| 43942 | ** The wal-index header contains the total number of frames within the WAL |
| @@ -44971,10 +44986,11 @@ | |
| 44986 | */ |
| 44987 | pInfo = walCkptInfo(pWal); |
| 44988 | pInfo->nBackfill = 0; |
| 44989 | pInfo->aReadMark[0] = 0; |
| 44990 | for(i=1; i<WAL_NREADER; i++) pInfo->aReadMark[i] = READMARK_NOT_USED; |
| 44991 | if( pWal->hdr.mxFrame ) pInfo->aReadMark[1] = pWal->hdr.mxFrame; |
| 44992 | |
| 44993 | /* If more than one frame was recovered from the log file, report an |
| 44994 | ** event via sqlite3_log(). This is to help with identifying performance |
| 44995 | ** problems caused by applications routinely shutting down without |
| 44996 | ** checkpointing the log file. |
| @@ -45471,11 +45487,11 @@ | |
| 45487 | u32 y = pInfo->aReadMark[i]; |
| 45488 | if( mxSafeFrame>y ){ |
| 45489 | assert( y<=pWal->hdr.mxFrame ); |
| 45490 | rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(i), 1); |
| 45491 | if( rc==SQLITE_OK ){ |
| 45492 | pInfo->aReadMark[i] = (i==1 ? mxSafeFrame : READMARK_NOT_USED); |
| 45493 | walUnlockExclusive(pWal, WAL_READ_LOCK(i), 1); |
| 45494 | }else if( rc==SQLITE_BUSY ){ |
| 45495 | mxSafeFrame = y; |
| 45496 | xBusy = 0; |
| 45497 | }else{ |
| @@ -46384,11 +46400,12 @@ | |
| 46400 | pWal->hdr.mxFrame = 0; |
| 46401 | sqlite3Put4byte((u8*)&aSalt[0], 1 + sqlite3Get4byte((u8*)&aSalt[0])); |
| 46402 | aSalt[1] = salt1; |
| 46403 | walIndexWriteHdr(pWal); |
| 46404 | pInfo->nBackfill = 0; |
| 46405 | pInfo->aReadMark[1] = 0; |
| 46406 | for(i=2; i<WAL_NREADER; i++) pInfo->aReadMark[i] = READMARK_NOT_USED; |
| 46407 | assert( pInfo->aReadMark[0]==0 ); |
| 46408 | walUnlockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1); |
| 46409 | }else if( rc!=SQLITE_BUSY ){ |
| 46410 | return rc; |
| 46411 | } |
| @@ -47387,10 +47404,11 @@ | |
| 47404 | u8 validNKey; /* True if info.nKey is valid */ |
| 47405 | u8 eState; /* One of the CURSOR_XXX constants (see below) */ |
| 47406 | #ifndef SQLITE_OMIT_INCRBLOB |
| 47407 | u8 isIncrblobHandle; /* True if this cursor is an incr. io handle */ |
| 47408 | #endif |
| 47409 | u8 hints; /* As configured by CursorSetHints() */ |
| 47410 | i16 iPage; /* Index of current page in apPage */ |
| 47411 | u16 aiIdx[BTCURSOR_MAX_DEPTH]; /* Current index in apPage[i] */ |
| 47412 | MemPage *apPage[BTCURSOR_MAX_DEPTH]; /* Pages from root to current page */ |
| 47413 | }; |
| 47414 | |
| @@ -53736,11 +53754,12 @@ | |
| 53754 | */ |
| 53755 | static int balance_nonroot( |
| 53756 | MemPage *pParent, /* Parent page of siblings being balanced */ |
| 53757 | int iParentIdx, /* Index of "the page" in pParent */ |
| 53758 | u8 *aOvflSpace, /* page-size bytes of space for parent ovfl */ |
| 53759 | int isRoot, /* True if pParent is a root-page */ |
| 53760 | int bBulk /* True if this call is part of a bulk load */ |
| 53761 | ){ |
| 53762 | BtShared *pBt; /* The whole database */ |
| 53763 | int nCell = 0; /* Number of cells in apCell[] */ |
| 53764 | int nMaxCells = 0; /* Allocated size of apCell, szCell, aFrom. */ |
| 53765 | int nNew = 0; /* Number of pages in apNew[] */ |
| @@ -53800,22 +53819,23 @@ | |
| 53819 | ** have already been removed. |
| 53820 | */ |
| 53821 | i = pParent->nOverflow + pParent->nCell; |
| 53822 | if( i<2 ){ |
| 53823 | nxDiv = 0; |
| 53824 | }else{ |
| 53825 | assert( bBulk==0 || bBulk==1 ); |
| 53826 | if( iParentIdx==0 ){ |
| 53827 | nxDiv = 0; |
| 53828 | }else if( iParentIdx==i ){ |
| 53829 | nxDiv = i-2+bBulk; |
| 53830 | }else{ |
| 53831 | assert( bBulk==0 ); |
| 53832 | nxDiv = iParentIdx-1; |
| 53833 | } |
| 53834 | i = 2-bBulk; |
| 53835 | } |
| 53836 | nOld = i+1; |
| 53837 | if( (i+nxDiv-pParent->nOverflow)==pParent->nCell ){ |
| 53838 | pRight = &pParent->aData[pParent->hdrOffset+8]; |
| 53839 | }else{ |
| 53840 | pRight = findCell(pParent, i+nxDiv-pParent->nOverflow); |
| 53841 | } |
| @@ -54020,11 +54040,13 @@ | |
| 54040 | |
| 54041 | r = cntNew[i-1] - 1; |
| 54042 | d = r + 1 - leafData; |
| 54043 | assert( d<nMaxCells ); |
| 54044 | assert( r<nMaxCells ); |
| 54045 | while( szRight==0 |
| 54046 | || (!bBulk && szRight+szCell[d]+2<=szLeft-(szCell[r]+2)) |
| 54047 | ){ |
| 54048 | szRight += szCell[d] + 2; |
| 54049 | szLeft -= szCell[r] + 2; |
| 54050 | cntNew[i-1]--; |
| 54051 | r = cntNew[i-1] - 1; |
| 54052 | d = r + 1 - leafData; |
| @@ -54067,11 +54089,11 @@ | |
| 54089 | rc = sqlite3PagerWrite(pNew->pDbPage); |
| 54090 | nNew++; |
| 54091 | if( rc ) goto balance_cleanup; |
| 54092 | }else{ |
| 54093 | assert( i>0 ); |
| 54094 | rc = allocateBtreePage(pBt, &pNew, &pgno, (bBulk ? 1 : pgno), 0); |
| 54095 | if( rc ) goto balance_cleanup; |
| 54096 | apNew[i] = pNew; |
| 54097 | nNew++; |
| 54098 | |
| 54099 | /* Set the pointer-map entry for the new sibling page. */ |
| @@ -54517,11 +54539,11 @@ | |
| 54539 | ** the previous call, as the overflow cell data will have been |
| 54540 | ** copied either into the body of a database page or into the new |
| 54541 | ** pSpace buffer passed to the latter call to balance_nonroot(). |
| 54542 | */ |
| 54543 | u8 *pSpace = sqlite3PageMalloc(pCur->pBt->pageSize); |
| 54544 | rc = balance_nonroot(pParent, iIdx, pSpace, iPage==1, pCur->hints); |
| 54545 | if( pFree ){ |
| 54546 | /* If pFree is not NULL, it points to the pSpace buffer used |
| 54547 | ** by a previous call to balance_nonroot(). Its contents are |
| 54548 | ** now stored either on real database pages or within the |
| 54549 | ** new pSpace buffer, so it may be safely freed here. */ |
| @@ -56104,10 +56126,20 @@ | |
| 56126 | } |
| 56127 | |
| 56128 | pBt->btsFlags &= ~BTS_NO_WAL; |
| 56129 | return rc; |
| 56130 | } |
| 56131 | |
| 56132 | /* |
| 56133 | ** set the mask of hint flags for cursor pCsr. Currently the only valid |
| 56134 | ** values are 0 and BTREE_BULKLOAD. |
| 56135 | */ |
| 56136 | SQLITE_PRIVATE void sqlite3BtreeCursorHints(BtCursor *pCsr, unsigned int mask){ |
| 56137 | assert( mask==BTREE_BULKLOAD || mask==0 ); |
| 56138 | pCsr->hints = mask; |
| 56139 | } |
| 56140 | |
| 56141 | |
| 56142 | /************** End of btree.c ***********************************************/ |
| 56143 | /************** Begin file backup.c ******************************************/ |
| 56144 | /* |
| 56145 | ** 2009 January 28 |
| @@ -56271,19 +56303,18 @@ | |
| 56303 | }else { |
| 56304 | /* Allocate space for a new sqlite3_backup object... |
| 56305 | ** EVIDENCE-OF: R-64852-21591 The sqlite3_backup object is created by a |
| 56306 | ** call to sqlite3_backup_init() and is destroyed by a call to |
| 56307 | ** sqlite3_backup_finish(). */ |
| 56308 | p = (sqlite3_backup *)sqlite3MallocZero(sizeof(sqlite3_backup)); |
| 56309 | if( !p ){ |
| 56310 | sqlite3Error(pDestDb, SQLITE_NOMEM, 0); |
| 56311 | } |
| 56312 | } |
| 56313 | |
| 56314 | /* If the allocation succeeded, populate the new object. */ |
| 56315 | if( p ){ |
| 56316 | p->pSrc = findBtree(pDestDb, pSrcDb, zSrcDb); |
| 56317 | p->pDest = findBtree(pDestDb, pDestDb, zDestDb); |
| 56318 | p->pDestDb = pDestDb; |
| 56319 | p->pSrcDb = pSrcDb; |
| 56320 | p->iNext = 1; |
| @@ -62703,13 +62734,12 @@ | |
| 62734 | */ |
| 62735 | SQLITE_PRIVATE void sqlite3ExplainBegin(Vdbe *pVdbe){ |
| 62736 | if( pVdbe ){ |
| 62737 | Explain *p; |
| 62738 | sqlite3BeginBenignMalloc(); |
| 62739 | p = (Explain *)sqlite3MallocZero( sizeof(Explain) ); |
| 62740 | if( p ){ |
| 62741 | p->pVdbe = pVdbe; |
| 62742 | sqlite3_free(pVdbe->pExplain); |
| 62743 | pVdbe->pExplain = p; |
| 62744 | sqlite3StrAccumInit(&p->str, p->zBase, sizeof(p->zBase), |
| 62745 | SQLITE_MAX_LENGTH); |
| @@ -66486,10 +66516,13 @@ | |
| 66516 | Btree *pX; |
| 66517 | VdbeCursor *pCur; |
| 66518 | Db *pDb; |
| 66519 | #endif /* local variables moved into u.ax */ |
| 66520 | |
| 66521 | assert( (pOp->p5&(OPFLAG_P2ISREG|OPFLAG_BULKCSR))==pOp->p5 ); |
| 66522 | assert( pOp->opcode==OP_OpenWrite || pOp->p5==0 ); |
| 66523 | |
| 66524 | if( p->expired ){ |
| 66525 | rc = SQLITE_ABORT; |
| 66526 | break; |
| 66527 | } |
| 66528 | |
| @@ -66509,11 +66542,11 @@ | |
| 66542 | p->minWriteFileFormat = u.ax.pDb->pSchema->file_format; |
| 66543 | } |
| 66544 | }else{ |
| 66545 | u.ax.wrFlag = 0; |
| 66546 | } |
| 66547 | if( pOp->p5 & OPFLAG_P2ISREG ){ |
| 66548 | assert( u.ax.p2>0 ); |
| 66549 | assert( u.ax.p2<=p->nMem ); |
| 66550 | pIn2 = &aMem[u.ax.p2]; |
| 66551 | assert( memIsValid(pIn2) ); |
| 66552 | assert( (pIn2->flags & MEM_Int)!=0 ); |
| @@ -66540,10 +66573,12 @@ | |
| 66573 | if( u.ax.pCur==0 ) goto no_mem; |
| 66574 | u.ax.pCur->nullRow = 1; |
| 66575 | u.ax.pCur->isOrdered = 1; |
| 66576 | rc = sqlite3BtreeCursor(u.ax.pX, u.ax.p2, u.ax.wrFlag, u.ax.pKeyInfo, u.ax.pCur->pCursor); |
| 66577 | u.ax.pCur->pKeyInfo = u.ax.pKeyInfo; |
| 66578 | assert( OPFLAG_BULKCSR==BTREE_BULKLOAD ); |
| 66579 | sqlite3BtreeCursorHints(u.ax.pCur->pCursor, (pOp->p5 & OPFLAG_BULKCSR)); |
| 66580 | |
| 66581 | /* Since it performs no memory allocation or IO, the only value that |
| 66582 | ** sqlite3BtreeCursor() may return is SQLITE_OK. */ |
| 66583 | assert( rc==SQLITE_OK ); |
| 66584 | |
| @@ -70159,10 +70194,11 @@ | |
| 70194 | |
| 70195 | #ifndef SQLITE_OMIT_MERGE_SORT |
| 70196 | |
| 70197 | typedef struct VdbeSorterIter VdbeSorterIter; |
| 70198 | typedef struct SorterRecord SorterRecord; |
| 70199 | typedef struct FileWriter FileWriter; |
| 70200 | |
| 70201 | /* |
| 70202 | ** NOTES ON DATA STRUCTURE USED FOR N-WAY MERGES: |
| 70203 | ** |
| 70204 | ** As keys are added to the sorter, they are written to disk in a series |
| @@ -70256,10 +70292,28 @@ | |
| 70292 | int nAlloc; /* Bytes of space at aAlloc */ |
| 70293 | int nKey; /* Number of bytes in key */ |
| 70294 | sqlite3_file *pFile; /* File iterator is reading from */ |
| 70295 | u8 *aAlloc; /* Allocated space */ |
| 70296 | u8 *aKey; /* Pointer to current key */ |
| 70297 | u8 *aBuffer; /* Current read buffer */ |
| 70298 | int nBuffer; /* Size of read buffer in bytes */ |
| 70299 | }; |
| 70300 | |
| 70301 | /* |
| 70302 | ** An instance of this structure is used to organize the stream of records |
| 70303 | ** being written to files by the merge-sort code into aligned, page-sized |
| 70304 | ** blocks. Doing all I/O in aligned page-sized blocks helps I/O to go |
| 70305 | ** faster on many operating systems. |
| 70306 | */ |
| 70307 | struct FileWriter { |
| 70308 | int eFWErr; /* Non-zero if in an error state */ |
| 70309 | u8 *aBuffer; /* Pointer to write buffer */ |
| 70310 | int nBuffer; /* Size of write buffer in bytes */ |
| 70311 | int iBufStart; /* First byte of buffer to write */ |
| 70312 | int iBufEnd; /* Last byte of buffer to write */ |
| 70313 | i64 iWriteOff; /* Offset of start of buffer in file */ |
| 70314 | sqlite3_file *pFile; /* File to write to */ |
| 70315 | }; |
| 70316 | |
| 70317 | /* |
| 70318 | ** A structure to store a single record. All in-memory records are connected |
| 70319 | ** together into a linked list headed at VdbeSorter.pRecord using the |
| @@ -70281,12 +70335,126 @@ | |
| 70335 | ** Free all memory belonging to the VdbeSorterIter object passed as the second |
| 70336 | ** argument. All structure fields are set to zero before returning. |
| 70337 | */ |
| 70338 | static void vdbeSorterIterZero(sqlite3 *db, VdbeSorterIter *pIter){ |
| 70339 | sqlite3DbFree(db, pIter->aAlloc); |
| 70340 | sqlite3DbFree(db, pIter->aBuffer); |
| 70341 | memset(pIter, 0, sizeof(VdbeSorterIter)); |
| 70342 | } |
| 70343 | |
| 70344 | /* |
| 70345 | ** Read nByte bytes of data from the stream of data iterated by object p. |
| 70346 | ** If successful, set *ppOut to point to a buffer containing the data |
| 70347 | ** and return SQLITE_OK. Otherwise, if an error occurs, return an SQLite |
| 70348 | ** error code. |
| 70349 | ** |
| 70350 | ** The buffer indicated by *ppOut may only be considered valid until the |
| 70351 | ** next call to this function. |
| 70352 | */ |
| 70353 | static int vdbeSorterIterRead( |
| 70354 | sqlite3 *db, /* Database handle (for malloc) */ |
| 70355 | VdbeSorterIter *p, /* Iterator */ |
| 70356 | int nByte, /* Bytes of data to read */ |
| 70357 | u8 **ppOut /* OUT: Pointer to buffer containing data */ |
| 70358 | ){ |
| 70359 | int iBuf; /* Offset within buffer to read from */ |
| 70360 | int nAvail; /* Bytes of data available in buffer */ |
| 70361 | assert( p->aBuffer ); |
| 70362 | |
| 70363 | /* If there is no more data to be read from the buffer, read the next |
| 70364 | ** p->nBuffer bytes of data from the file into it. Or, if there are less |
| 70365 | ** than p->nBuffer bytes remaining in the PMA, read all remaining data. */ |
| 70366 | iBuf = p->iReadOff % p->nBuffer; |
| 70367 | if( iBuf==0 ){ |
| 70368 | int nRead; /* Bytes to read from disk */ |
| 70369 | int rc; /* sqlite3OsRead() return code */ |
| 70370 | |
| 70371 | /* Determine how many bytes of data to read. */ |
| 70372 | nRead = p->iEof - p->iReadOff; |
| 70373 | if( nRead>p->nBuffer ) nRead = p->nBuffer; |
| 70374 | assert( nRead>0 ); |
| 70375 | |
| 70376 | /* Read data from the file. Return early if an error occurs. */ |
| 70377 | rc = sqlite3OsRead(p->pFile, p->aBuffer, nRead, p->iReadOff); |
| 70378 | assert( rc!=SQLITE_IOERR_SHORT_READ ); |
| 70379 | if( rc!=SQLITE_OK ) return rc; |
| 70380 | } |
| 70381 | nAvail = p->nBuffer - iBuf; |
| 70382 | |
| 70383 | if( nByte<=nAvail ){ |
| 70384 | /* The requested data is available in the in-memory buffer. In this |
| 70385 | ** case there is no need to make a copy of the data, just return a |
| 70386 | ** pointer into the buffer to the caller. */ |
| 70387 | *ppOut = &p->aBuffer[iBuf]; |
| 70388 | p->iReadOff += nByte; |
| 70389 | }else{ |
| 70390 | /* The requested data is not all available in the in-memory buffer. |
| 70391 | ** In this case, allocate space at p->aAlloc[] to copy the requested |
| 70392 | ** range into. Then return a copy of pointer p->aAlloc to the caller. */ |
| 70393 | int nRem; /* Bytes remaining to copy */ |
| 70394 | |
| 70395 | /* Extend the p->aAlloc[] allocation if required. */ |
| 70396 | if( p->nAlloc<nByte ){ |
| 70397 | int nNew = p->nAlloc*2; |
| 70398 | while( nByte>nNew ) nNew = nNew*2; |
| 70399 | p->aAlloc = sqlite3DbReallocOrFree(db, p->aAlloc, nNew); |
| 70400 | if( !p->aAlloc ) return SQLITE_NOMEM; |
| 70401 | p->nAlloc = nNew; |
| 70402 | } |
| 70403 | |
| 70404 | /* Copy as much data as is available in the buffer into the start of |
| 70405 | ** p->aAlloc[]. */ |
| 70406 | memcpy(p->aAlloc, &p->aBuffer[iBuf], nAvail); |
| 70407 | p->iReadOff += nAvail; |
| 70408 | nRem = nByte - nAvail; |
| 70409 | |
| 70410 | /* The following loop copies up to p->nBuffer bytes per iteration into |
| 70411 | ** the p->aAlloc[] buffer. */ |
| 70412 | while( nRem>0 ){ |
| 70413 | int rc; /* vdbeSorterIterRead() return code */ |
| 70414 | int nCopy; /* Number of bytes to copy */ |
| 70415 | u8 *aNext; /* Pointer to buffer to copy data from */ |
| 70416 | |
| 70417 | nCopy = nRem; |
| 70418 | if( nRem>p->nBuffer ) nCopy = p->nBuffer; |
| 70419 | rc = vdbeSorterIterRead(db, p, nCopy, &aNext); |
| 70420 | if( rc!=SQLITE_OK ) return rc; |
| 70421 | assert( aNext!=p->aAlloc ); |
| 70422 | memcpy(&p->aAlloc[nByte - nRem], aNext, nCopy); |
| 70423 | nRem -= nCopy; |
| 70424 | } |
| 70425 | |
| 70426 | *ppOut = p->aAlloc; |
| 70427 | } |
| 70428 | |
| 70429 | return SQLITE_OK; |
| 70430 | } |
| 70431 | |
| 70432 | /* |
| 70433 | ** Read a varint from the stream of data accessed by p. Set *pnOut to |
| 70434 | ** the value read. |
| 70435 | */ |
| 70436 | static int vdbeSorterIterVarint(sqlite3 *db, VdbeSorterIter *p, u64 *pnOut){ |
| 70437 | int iBuf; |
| 70438 | |
| 70439 | iBuf = p->iReadOff % p->nBuffer; |
| 70440 | if( iBuf && (p->nBuffer-iBuf)>=9 ){ |
| 70441 | p->iReadOff += sqlite3GetVarint(&p->aBuffer[iBuf], pnOut); |
| 70442 | }else{ |
| 70443 | u8 aVarint[16], *a; |
| 70444 | int i = 0, rc; |
| 70445 | do{ |
| 70446 | rc = vdbeSorterIterRead(db, p, 1, &a); |
| 70447 | if( rc ) return rc; |
| 70448 | aVarint[(i++)&0xf] = a[0]; |
| 70449 | }while( (a[0]&0x80)!=0 ); |
| 70450 | sqlite3GetVarint(aVarint, pnOut); |
| 70451 | } |
| 70452 | |
| 70453 | return SQLITE_OK; |
| 70454 | } |
| 70455 | |
| 70456 | |
| 70457 | /* |
| 70458 | ** Advance iterator pIter to the next key in its PMA. Return SQLITE_OK if |
| 70459 | ** no error occurs, or an SQLite error code if one does. |
| 70460 | */ |
| @@ -70293,100 +70461,22 @@ | |
| 70461 | static int vdbeSorterIterNext( |
| 70462 | sqlite3 *db, /* Database handle (for sqlite3DbMalloc() ) */ |
| 70463 | VdbeSorterIter *pIter /* Iterator to advance */ |
| 70464 | ){ |
| 70465 | int rc; /* Return Code */ |
| 70466 | u64 nRec = 0; /* Size of record in bytes */ |
| 70467 | |
| 70468 | if( pIter->iReadOff>=pIter->iEof ){ |
| 70469 | /* This is an EOF condition */ |
| 70470 | vdbeSorterIterZero(db, pIter); |
| 70471 | return SQLITE_OK; |
| 70472 | } |
| 70473 | |
| 70474 | rc = vdbeSorterIterVarint(db, pIter, &nRec); |
| 70475 | if( rc==SQLITE_OK ){ |
| 70476 | pIter->nKey = (int)nRec; |
| 70477 | rc = vdbeSorterIterRead(db, pIter, nRec, &pIter->aKey); |
| 70478 | } |
| 70479 | |
| 70480 | return rc; |
| 70481 | } |
| 70482 | |
| @@ -70396,31 +70486,56 @@ | |
| 70486 | ** leaves the iterator pointing to the first key in the PMA (or EOF if the |
| 70487 | ** PMA is empty). |
| 70488 | */ |
| 70489 | static int vdbeSorterIterInit( |
| 70490 | sqlite3 *db, /* Database handle */ |
| 70491 | const VdbeSorter *pSorter, /* Sorter object */ |
| 70492 | i64 iStart, /* Start offset in pFile */ |
| 70493 | VdbeSorterIter *pIter, /* Iterator to populate */ |
| 70494 | i64 *pnByte /* IN/OUT: Increment this value by PMA size */ |
| 70495 | ){ |
| 70496 | int rc = SQLITE_OK; |
| 70497 | int nBuf; |
| 70498 | |
| 70499 | nBuf = sqlite3BtreeGetPageSize(db->aDb[0].pBt); |
| 70500 | |
| 70501 | assert( pSorter->iWriteOff>iStart ); |
| 70502 | assert( pIter->aAlloc==0 ); |
| 70503 | assert( pIter->aBuffer==0 ); |
| 70504 | pIter->pFile = pSorter->pTemp1; |
| 70505 | pIter->iReadOff = iStart; |
| 70506 | pIter->nAlloc = 128; |
| 70507 | pIter->aAlloc = (u8 *)sqlite3DbMallocRaw(db, pIter->nAlloc); |
| 70508 | pIter->nBuffer = nBuf; |
| 70509 | pIter->aBuffer = (u8 *)sqlite3DbMallocRaw(db, nBuf); |
| 70510 | |
| 70511 | if( !pIter->aBuffer ){ |
| 70512 | rc = SQLITE_NOMEM; |
| 70513 | }else{ |
| 70514 | int iBuf; |
| 70515 | |
| 70516 | iBuf = iStart % nBuf; |
| 70517 | if( iBuf ){ |
| 70518 | int nRead = nBuf - iBuf; |
| 70519 | if( (iStart + nRead) > pSorter->iWriteOff ){ |
| 70520 | nRead = pSorter->iWriteOff - iStart; |
| 70521 | } |
| 70522 | rc = sqlite3OsRead( |
| 70523 | pSorter->pTemp1, &pIter->aBuffer[iBuf], nRead, iStart |
| 70524 | ); |
| 70525 | assert( rc!=SQLITE_IOERR_SHORT_READ ); |
| 70526 | } |
| 70527 | |
| 70528 | if( rc==SQLITE_OK ){ |
| 70529 | u64 nByte; /* Size of PMA in bytes */ |
| 70530 | pIter->iEof = pSorter->iWriteOff; |
| 70531 | rc = vdbeSorterIterVarint(db, pIter, &nByte); |
| 70532 | pIter->iEof = pIter->iReadOff + nByte; |
| 70533 | *pnByte += nByte; |
| 70534 | } |
| 70535 | } |
| 70536 | |
| 70537 | if( rc==SQLITE_OK ){ |
| 70538 | rc = vdbeSorterIterNext(db, pIter); |
| 70539 | } |
| 70540 | return rc; |
| 70541 | } |
| @@ -70440,14 +70555,14 @@ | |
| 70555 | ** |
| 70556 | ** If pKey2 is passed a NULL pointer, then it is assumed that the pCsr->aSpace |
| 70557 | ** has been allocated and contains an unpacked record that is used as key2. |
| 70558 | */ |
| 70559 | static void vdbeSorterCompare( |
| 70560 | const VdbeCursor *pCsr, /* Cursor object (for pKeyInfo) */ |
| 70561 | int bOmitRowid, /* Ignore rowid field at end of keys */ |
| 70562 | const void *pKey1, int nKey1, /* Left side of comparison */ |
| 70563 | const void *pKey2, int nKey2, /* Right side of comparison */ |
| 70564 | int *pRes /* OUT: Result of comparison */ |
| 70565 | ){ |
| 70566 | KeyInfo *pKeyInfo = pCsr->pKeyInfo; |
| 70567 | VdbeSorter *pSorter = pCsr->pSorter; |
| 70568 | UnpackedRecord *r2 = pSorter->pUnpacked; |
| @@ -70475,11 +70590,11 @@ | |
| 70590 | /* |
| 70591 | ** This function is called to compare two iterator keys when merging |
| 70592 | ** multiple b-tree segments. Parameter iOut is the index of the aTree[] |
| 70593 | ** value to recalculate. |
| 70594 | */ |
| 70595 | static int vdbeSorterDoCompare(const VdbeCursor *pCsr, int iOut){ |
| 70596 | VdbeSorter *pSorter = pCsr->pSorter; |
| 70597 | int i1; |
| 70598 | int i2; |
| 70599 | int iRes; |
| 70600 | VdbeSorterIter *p1; |
| @@ -70601,11 +70716,11 @@ | |
| 70716 | /* |
| 70717 | ** Merge the two sorted lists p1 and p2 into a single list. |
| 70718 | ** Set *ppOut to the head of the new list. |
| 70719 | */ |
| 70720 | static void vdbeSorterMerge( |
| 70721 | const VdbeCursor *pCsr, /* For pKeyInfo */ |
| 70722 | SorterRecord *p1, /* First list to merge */ |
| 70723 | SorterRecord *p2, /* Second list to merge */ |
| 70724 | SorterRecord **ppOut /* OUT: Head of merged list */ |
| 70725 | ){ |
| 70726 | SorterRecord *pFinal = 0; |
| @@ -70635,11 +70750,11 @@ | |
| 70750 | /* |
| 70751 | ** Sort the linked list of records headed at pCsr->pRecord. Return SQLITE_OK |
| 70752 | ** if successful, or an SQLite error code (i.e. SQLITE_NOMEM) if an error |
| 70753 | ** occurs. |
| 70754 | */ |
| 70755 | static int vdbeSorterSort(const VdbeCursor *pCsr){ |
| 70756 | int i; |
| 70757 | SorterRecord **aSlot; |
| 70758 | SorterRecord *p; |
| 70759 | VdbeSorter *pSorter = pCsr->pSorter; |
| 70760 | |
| @@ -70668,10 +70783,95 @@ | |
| 70783 | |
| 70784 | sqlite3_free(aSlot); |
| 70785 | return SQLITE_OK; |
| 70786 | } |
| 70787 | |
| 70788 | /* |
| 70789 | ** Initialize a file-writer object. |
| 70790 | */ |
| 70791 | static void fileWriterInit( |
| 70792 | sqlite3 *db, /* Database (for malloc) */ |
| 70793 | sqlite3_file *pFile, /* File to write to */ |
| 70794 | FileWriter *p, /* Object to populate */ |
| 70795 | i64 iStart /* Offset of pFile to begin writing at */ |
| 70796 | ){ |
| 70797 | int nBuf = sqlite3BtreeGetPageSize(db->aDb[0].pBt); |
| 70798 | |
| 70799 | memset(p, 0, sizeof(FileWriter)); |
| 70800 | p->aBuffer = (u8 *)sqlite3DbMallocRaw(db, nBuf); |
| 70801 | if( !p->aBuffer ){ |
| 70802 | p->eFWErr = SQLITE_NOMEM; |
| 70803 | }else{ |
| 70804 | p->iBufEnd = p->iBufStart = (iStart % nBuf); |
| 70805 | p->iWriteOff = iStart - p->iBufStart; |
| 70806 | p->nBuffer = nBuf; |
| 70807 | p->pFile = pFile; |
| 70808 | } |
| 70809 | } |
| 70810 | |
| 70811 | /* |
| 70812 | ** Write nData bytes of data to the file-write object. Return SQLITE_OK |
| 70813 | ** if successful, or an SQLite error code if an error occurs. |
| 70814 | */ |
| 70815 | static void fileWriterWrite(FileWriter *p, u8 *pData, int nData){ |
| 70816 | int nRem = nData; |
| 70817 | while( nRem>0 && p->eFWErr==0 ){ |
| 70818 | int nCopy = nRem; |
| 70819 | if( nCopy>(p->nBuffer - p->iBufEnd) ){ |
| 70820 | nCopy = p->nBuffer - p->iBufEnd; |
| 70821 | } |
| 70822 | |
| 70823 | memcpy(&p->aBuffer[p->iBufEnd], &pData[nData-nRem], nCopy); |
| 70824 | p->iBufEnd += nCopy; |
| 70825 | if( p->iBufEnd==p->nBuffer ){ |
| 70826 | p->eFWErr = sqlite3OsWrite(p->pFile, |
| 70827 | &p->aBuffer[p->iBufStart], p->iBufEnd - p->iBufStart, |
| 70828 | p->iWriteOff + p->iBufStart |
| 70829 | ); |
| 70830 | p->iBufStart = p->iBufEnd = 0; |
| 70831 | p->iWriteOff += p->nBuffer; |
| 70832 | } |
| 70833 | assert( p->iBufEnd<p->nBuffer ); |
| 70834 | |
| 70835 | nRem -= nCopy; |
| 70836 | } |
| 70837 | } |
| 70838 | |
| 70839 | /* |
| 70840 | ** Flush any buffered data to disk and clean up the file-writer object. |
| 70841 | ** The results of using the file-writer after this call are undefined. |
| 70842 | ** Return SQLITE_OK if flushing the buffered data succeeds or is not |
| 70843 | ** required. Otherwise, return an SQLite error code. |
| 70844 | ** |
| 70845 | ** Before returning, set *piEof to the offset immediately following the |
| 70846 | ** last byte written to the file. |
| 70847 | */ |
| 70848 | static int fileWriterFinish(sqlite3 *db, FileWriter *p, i64 *piEof){ |
| 70849 | int rc; |
| 70850 | if( p->eFWErr==0 && ALWAYS(p->aBuffer) && p->iBufEnd>p->iBufStart ){ |
| 70851 | p->eFWErr = sqlite3OsWrite(p->pFile, |
| 70852 | &p->aBuffer[p->iBufStart], p->iBufEnd - p->iBufStart, |
| 70853 | p->iWriteOff + p->iBufStart |
| 70854 | ); |
| 70855 | } |
| 70856 | *piEof = (p->iWriteOff + p->iBufEnd); |
| 70857 | sqlite3DbFree(db, p->aBuffer); |
| 70858 | rc = p->eFWErr; |
| 70859 | memset(p, 0, sizeof(FileWriter)); |
| 70860 | return rc; |
| 70861 | } |
| 70862 | |
| 70863 | /* |
| 70864 | ** Write value iVal encoded as a varint to the file-write object. Return |
| 70865 | ** SQLITE_OK if successful, or an SQLite error code if an error occurs. |
| 70866 | */ |
| 70867 | static void fileWriterWriteVarint(FileWriter *p, u64 iVal){ |
| 70868 | int nByte; |
| 70869 | u8 aByte[10]; |
| 70870 | nByte = sqlite3PutVarint(aByte, iVal); |
| 70871 | fileWriterWrite(p, aByte, nByte); |
| 70872 | } |
| 70873 | |
| 70874 | /* |
| 70875 | ** Write the current contents of the in-memory linked-list to a PMA. Return |
| 70876 | ** SQLITE_OK if successful, or an SQLite error code otherwise. |
| 70877 | ** |
| @@ -70682,13 +70882,16 @@ | |
| 70882 | ** |
| 70883 | ** * One or more records packed end-to-end in order of ascending keys. |
| 70884 | ** Each record consists of a varint followed by a blob of data (the |
| 70885 | ** key). The varint is the number of bytes in the blob of data. |
| 70886 | */ |
| 70887 | static int vdbeSorterListToPMA(sqlite3 *db, const VdbeCursor *pCsr){ |
| 70888 | int rc = SQLITE_OK; /* Return code */ |
| 70889 | VdbeSorter *pSorter = pCsr->pSorter; |
| 70890 | FileWriter writer; |
| 70891 | |
| 70892 | memset(&writer, 0, sizeof(FileWriter)); |
| 70893 | |
| 70894 | if( pSorter->nInMemory==0 ){ |
| 70895 | assert( pSorter->pRecord==0 ); |
| 70896 | return rc; |
| 70897 | } |
| @@ -70702,43 +70905,24 @@ | |
| 70905 | assert( pSorter->iWriteOff==0 ); |
| 70906 | assert( pSorter->nPMA==0 ); |
| 70907 | } |
| 70908 | |
| 70909 | if( rc==SQLITE_OK ){ |
| 70910 | SorterRecord *p; |
| 70911 | SorterRecord *pNext = 0; |
| 70912 | |
| 70913 | fileWriterInit(db, pSorter->pTemp1, &writer, pSorter->iWriteOff); |
| 70914 | pSorter->nPMA++; |
| 70915 | fileWriterWriteVarint(&writer, pSorter->nInMemory); |
| 70916 | for(p=pSorter->pRecord; p; p=pNext){ |
| 70917 | pNext = p->pNext; |
| 70918 | fileWriterWriteVarint(&writer, p->nVal); |
| 70919 | fileWriterWrite(&writer, p->pVal, p->nVal); |
| 70920 | sqlite3DbFree(db, p); |
| 70921 | } |
| 70922 | pSorter->pRecord = p; |
| 70923 | rc = fileWriterFinish(db, &writer, &pSorter->iWriteOff); |
| 70924 | } |
| 70925 | |
| 70926 | return rc; |
| 70927 | } |
| 70928 | |
| @@ -70745,11 +70929,11 @@ | |
| 70929 | /* |
| 70930 | ** Add a record to the sorter. |
| 70931 | */ |
| 70932 | SQLITE_PRIVATE int sqlite3VdbeSorterWrite( |
| 70933 | sqlite3 *db, /* Database handle */ |
| 70934 | const VdbeCursor *pCsr, /* Sorter cursor */ |
| 70935 | Mem *pVal /* Memory cell containing record */ |
| 70936 | ){ |
| 70937 | VdbeSorter *pSorter = pCsr->pSorter; |
| 70938 | int rc = SQLITE_OK; /* Return Code */ |
| 70939 | SorterRecord *pNew; /* New list element */ |
| @@ -70779,12 +70963,18 @@ | |
| 70963 | */ |
| 70964 | if( rc==SQLITE_OK && pSorter->mxPmaSize>0 && ( |
| 70965 | (pSorter->nInMemory>pSorter->mxPmaSize) |
| 70966 | || (pSorter->nInMemory>pSorter->mnPmaSize && sqlite3HeapNearlyFull()) |
| 70967 | )){ |
| 70968 | #ifdef SQLITE_DEBUG |
| 70969 | i64 nExpect = pSorter->iWriteOff |
| 70970 | + sqlite3VarintLen(pSorter->nInMemory) |
| 70971 | + pSorter->nInMemory; |
| 70972 | #endif |
| 70973 | rc = vdbeSorterListToPMA(db, pCsr); |
| 70974 | pSorter->nInMemory = 0; |
| 70975 | assert( rc!=SQLITE_OK || (nExpect==pSorter->iWriteOff) ); |
| 70976 | } |
| 70977 | |
| 70978 | return rc; |
| 70979 | } |
| 70980 | |
| @@ -70791,11 +70981,11 @@ | |
| 70981 | /* |
| 70982 | ** Helper function for sqlite3VdbeSorterRewind(). |
| 70983 | */ |
| 70984 | static int vdbeSorterInitMerge( |
| 70985 | sqlite3 *db, /* Database handle */ |
| 70986 | const VdbeCursor *pCsr, /* Cursor handle for this sorter */ |
| 70987 | i64 *pnByte /* Sum of bytes in all opened PMAs */ |
| 70988 | ){ |
| 70989 | VdbeSorter *pSorter = pCsr->pSorter; |
| 70990 | int rc = SQLITE_OK; /* Return code */ |
| 70991 | int i; /* Used to iterator through aIter[] */ |
| @@ -70821,11 +71011,11 @@ | |
| 71011 | |
| 71012 | /* |
| 71013 | ** Once the sorter has been populated, this function is called to prepare |
| 71014 | ** for iterating through its contents in sorted order. |
| 71015 | */ |
| 71016 | SQLITE_PRIVATE int sqlite3VdbeSorterRewind(sqlite3 *db, const VdbeCursor *pCsr, int *pbEof){ |
| 71017 | VdbeSorter *pSorter = pCsr->pSorter; |
| 71018 | int rc; /* Return code */ |
| 71019 | sqlite3_file *pTemp2 = 0; /* Second temp file to use */ |
| 71020 | i64 iWrite2 = 0; /* Write offset for pTemp2 */ |
| 71021 | int nIter; /* Number of iterators used */ |
| @@ -70841,11 +71031,11 @@ | |
| 71031 | *pbEof = !pSorter->pRecord; |
| 71032 | assert( pSorter->aTree==0 ); |
| 71033 | return vdbeSorterSort(pCsr); |
| 71034 | } |
| 71035 | |
| 71036 | /* Write the current in-memory list to a PMA. */ |
| 71037 | rc = vdbeSorterListToPMA(db, pCsr); |
| 71038 | if( rc!=SQLITE_OK ) return rc; |
| 71039 | |
| 71040 | /* Allocate space for aIter[] and aTree[]. */ |
| 71041 | nIter = pSorter->nPMA; |
| @@ -70863,11 +71053,15 @@ | |
| 71053 | |
| 71054 | for(iNew=0; |
| 71055 | rc==SQLITE_OK && iNew*SORTER_MAX_MERGE_COUNT<pSorter->nPMA; |
| 71056 | iNew++ |
| 71057 | ){ |
| 71058 | int rc2; /* Return code from fileWriterFinish() */ |
| 71059 | FileWriter writer; /* Object used to write to disk */ |
| 71060 | i64 nWrite; /* Number of bytes in new PMA */ |
| 71061 | |
| 71062 | memset(&writer, 0, sizeof(FileWriter)); |
| 71063 | |
| 71064 | /* If there are SORTER_MAX_MERGE_COUNT or less PMAs in file pTemp1, |
| 71065 | ** initialize an iterator for each of them and break out of the loop. |
| 71066 | ** These iterators will be incrementally merged as the VDBE layer calls |
| 71067 | ** sqlite3VdbeSorterNext(). |
| @@ -70886,27 +71080,24 @@ | |
| 71080 | if( pTemp2==0 ){ |
| 71081 | assert( iWrite2==0 ); |
| 71082 | rc = vdbeSorterOpenTempFile(db, &pTemp2); |
| 71083 | } |
| 71084 | |
| 71085 | if( rc==SQLITE_OK ){ |
| 71086 | int bEof = 0; |
| 71087 | fileWriterInit(db, pTemp2, &writer, iWrite2); |
| 71088 | fileWriterWriteVarint(&writer, nWrite); |
| 71089 | while( rc==SQLITE_OK && bEof==0 ){ |
| 71090 | VdbeSorterIter *pIter = &pSorter->aIter[ pSorter->aTree[1] ]; |
| 71091 | assert( pIter->pFile ); |
| 71092 | |
| 71093 | fileWriterWriteVarint(&writer, pIter->nKey); |
| 71094 | fileWriterWrite(&writer, pIter->aKey, pIter->nKey); |
| 71095 | rc = sqlite3VdbeSorterNext(db, pCsr, &bEof); |
| 71096 | } |
| 71097 | rc2 = fileWriterFinish(db, &writer, &iWrite2); |
| 71098 | if( rc==SQLITE_OK ) rc = rc2; |
| 71099 | } |
| 71100 | } |
| 71101 | |
| 71102 | if( pSorter->nPMA<=SORTER_MAX_MERGE_COUNT ){ |
| 71103 | break; |
| @@ -70929,11 +71120,11 @@ | |
| 71120 | } |
| 71121 | |
| 71122 | /* |
| 71123 | ** Advance to the next element in the sorter. |
| 71124 | */ |
| 71125 | SQLITE_PRIVATE int sqlite3VdbeSorterNext(sqlite3 *db, const VdbeCursor *pCsr, int *pbEof){ |
| 71126 | VdbeSorter *pSorter = pCsr->pSorter; |
| 71127 | int rc; /* Return code */ |
| 71128 | |
| 71129 | if( pSorter->aTree ){ |
| 71130 | int iPrev = pSorter->aTree[1];/* Index of iterator to advance */ |
| @@ -70959,11 +71150,11 @@ | |
| 71150 | /* |
| 71151 | ** Return a pointer to a buffer owned by the sorter that contains the |
| 71152 | ** current key. |
| 71153 | */ |
| 71154 | static void *vdbeSorterRowkey( |
| 71155 | const VdbeSorter *pSorter, /* Sorter object */ |
| 71156 | int *pnKey /* OUT: Size of current key in bytes */ |
| 71157 | ){ |
| 71158 | void *pKey; |
| 71159 | if( pSorter->aTree ){ |
| 71160 | VdbeSorterIter *pIter; |
| @@ -70978,11 +71169,11 @@ | |
| 71169 | } |
| 71170 | |
| 71171 | /* |
| 71172 | ** Copy the current sorter key into the memory cell pOut. |
| 71173 | */ |
| 71174 | SQLITE_PRIVATE int sqlite3VdbeSorterRowkey(const VdbeCursor *pCsr, Mem *pOut){ |
| 71175 | VdbeSorter *pSorter = pCsr->pSorter; |
| 71176 | void *pKey; int nKey; /* Sorter key to copy into pOut */ |
| 71177 | |
| 71178 | pKey = vdbeSorterRowkey(pSorter, &nKey); |
| 71179 | if( sqlite3VdbeMemGrow(pOut, nKey, 0) ){ |
| @@ -71004,11 +71195,11 @@ | |
| 71195 | ** Otherwise, set *pRes to a negative, zero or positive value if the |
| 71196 | ** key in pVal is smaller than, equal to or larger than the current sorter |
| 71197 | ** key. |
| 71198 | */ |
| 71199 | SQLITE_PRIVATE int sqlite3VdbeSorterCompare( |
| 71200 | const VdbeCursor *pCsr, /* Sorter cursor */ |
| 71201 | Mem *pVal, /* Value to compare to current sorter key */ |
| 71202 | int *pRes /* OUT: Result of comparison */ |
| 71203 | ){ |
| 71204 | VdbeSorter *pSorter = pCsr->pSorter; |
| 71205 | void *pKey; int nKey; /* Sorter key to compare pVal with */ |
| @@ -74591,11 +74782,11 @@ | |
| 74782 | SelectDest dest; |
| 74783 | ExprList *pEList; |
| 74784 | |
| 74785 | assert( !isRowid ); |
| 74786 | sqlite3SelectDestInit(&dest, SRT_Set, pExpr->iTable); |
| 74787 | dest.affSdst = (u8)affinity; |
| 74788 | assert( (pExpr->iTable&0x0000FFFF)==pExpr->iTable ); |
| 74789 | pExpr->x.pSelect->iLimit = 0; |
| 74790 | if( sqlite3Select(pParse, pExpr->x.pSelect, &dest) ){ |
| 74791 | return 0; |
| 74792 | } |
| @@ -74684,25 +74875,25 @@ | |
| 74875 | assert( ExprHasProperty(pExpr, EP_xIsSelect) ); |
| 74876 | pSel = pExpr->x.pSelect; |
| 74877 | sqlite3SelectDestInit(&dest, 0, ++pParse->nMem); |
| 74878 | if( pExpr->op==TK_SELECT ){ |
| 74879 | dest.eDest = SRT_Mem; |
| 74880 | sqlite3VdbeAddOp2(v, OP_Null, 0, dest.iSDParm); |
| 74881 | VdbeComment((v, "Init subquery result")); |
| 74882 | }else{ |
| 74883 | dest.eDest = SRT_Exists; |
| 74884 | sqlite3VdbeAddOp2(v, OP_Integer, 0, dest.iSDParm); |
| 74885 | VdbeComment((v, "Init EXISTS result")); |
| 74886 | } |
| 74887 | sqlite3ExprDelete(pParse->db, pSel->pLimit); |
| 74888 | pSel->pLimit = sqlite3PExpr(pParse, TK_INTEGER, 0, 0, |
| 74889 | &sqlite3IntTokens[1]); |
| 74890 | pSel->iLimit = 0; |
| 74891 | if( sqlite3Select(pParse, pSel, &dest) ){ |
| 74892 | return 0; |
| 74893 | } |
| 74894 | rReg = dest.iSDParm; |
| 74895 | ExprSetIrreducible(pExpr); |
| 74896 | break; |
| 74897 | } |
| 74898 | } |
| 74899 | |
| @@ -78012,11 +78203,11 @@ | |
| 78203 | ** because the OpenWrite opcode below will be needing it. */ |
| 78204 | sqlite3NestedParse(pParse, |
| 78205 | "CREATE TABLE %Q.%s(%s)", pDb->zName, zTab, aTable[i].zCols |
| 78206 | ); |
| 78207 | aRoot[i] = pParse->regRoot; |
| 78208 | aCreateTbl[i] = OPFLAG_P2ISREG; |
| 78209 | }else{ |
| 78210 | /* The table already exists. If zWhere is not NULL, delete all entries |
| 78211 | ** associated with the table zWhere. If zWhere is NULL, delete the |
| 78212 | ** entire contents of the table. */ |
| 78213 | aRoot[i] = pStat->tnum; |
| @@ -78092,16 +78283,15 @@ | |
| 78283 | |
| 78284 | UNUSED_PARAMETER(argc); |
| 78285 | nRow = (tRowcnt)sqlite3_value_int64(argv[0]); |
| 78286 | mxSample = sqlite3_value_int(argv[1]); |
| 78287 | n = sizeof(*p) + sizeof(p->a[0])*mxSample; |
| 78288 | p = sqlite3MallocZero( n ); |
| 78289 | if( p==0 ){ |
| 78290 | sqlite3_result_error_nomem(context); |
| 78291 | return; |
| 78292 | } |
| 78293 | p->a = (struct Stat3Sample*)&p[1]; |
| 78294 | p->nRow = nRow; |
| 78295 | p->mxSample = mxSample; |
| 78296 | p->nPSample = p->nRow/(mxSample/3+1) + 1; |
| 78297 | sqlite3_randomness(sizeof(p->iPrn), &p->iPrn); |
| @@ -81354,11 +81544,11 @@ | |
| 81544 | SelectDest dest; |
| 81545 | Table *pSelTab; |
| 81546 | |
| 81547 | assert(pParse->nTab==1); |
| 81548 | sqlite3VdbeAddOp3(v, OP_OpenWrite, 1, pParse->regRoot, iDb); |
| 81549 | sqlite3VdbeChangeP5(v, OPFLAG_P2ISREG); |
| 81550 | pParse->nTab = 2; |
| 81551 | sqlite3SelectDestInit(&dest, SRT_Table, 1); |
| 81552 | sqlite3Select(pParse, pSelect, &dest); |
| 81553 | sqlite3VdbeAddOp1(v, OP_Close, 1); |
| 81554 | if( pParse->nErr==0 ){ |
| @@ -82170,13 +82360,11 @@ | |
| 82360 | sqlite3VdbeAddOp2(v, OP_Clear, tnum, iDb); |
| 82361 | } |
| 82362 | pKey = sqlite3IndexKeyinfo(pParse, pIndex); |
| 82363 | sqlite3VdbeAddOp4(v, OP_OpenWrite, iIdx, tnum, iDb, |
| 82364 | (char *)pKey, P4_KEYINFO_HANDOFF); |
| 82365 | sqlite3VdbeChangeP5(v, OPFLAG_BULKCSR|((memRootPage>=0)?OPFLAG_P2ISREG:0)); |
| 82366 | |
| 82367 | #ifndef SQLITE_OMIT_MERGE_SORT |
| 82368 | /* Open the sorter cursor if we are to use one. */ |
| 82369 | iSorter = pParse->nTab++; |
| 82370 | sqlite3VdbeAddOp4(v, OP_SorterOpen, iSorter, 0, 0, (char*)pKey, P4_KEYINFO); |
| @@ -88191,11 +88379,11 @@ | |
| 88379 | regEof = ++pParse->nMem; |
| 88380 | sqlite3VdbeAddOp2(v, OP_Integer, 0, regEof); /* EOF <- 0 */ |
| 88381 | VdbeComment((v, "SELECT eof flag")); |
| 88382 | sqlite3SelectDestInit(&dest, SRT_Coroutine, ++pParse->nMem); |
| 88383 | addrSelect = sqlite3VdbeCurrentAddr(v)+2; |
| 88384 | sqlite3VdbeAddOp2(v, OP_Integer, addrSelect-1, dest.iSDParm); |
| 88385 | j1 = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0); |
| 88386 | VdbeComment((v, "Jump over SELECT coroutine")); |
| 88387 | |
| 88388 | /* Resolve the expressions in the SELECT statement and execute it. */ |
| 88389 | rc = sqlite3Select(pParse, pSelect, &dest); |
| @@ -88202,19 +88390,19 @@ | |
| 88390 | assert( pParse->nErr==0 || rc ); |
| 88391 | if( rc || NEVER(pParse->nErr) || db->mallocFailed ){ |
| 88392 | goto insert_cleanup; |
| 88393 | } |
| 88394 | sqlite3VdbeAddOp2(v, OP_Integer, 1, regEof); /* EOF <- 1 */ |
| 88395 | sqlite3VdbeAddOp1(v, OP_Yield, dest.iSDParm); /* yield X */ |
| 88396 | sqlite3VdbeAddOp2(v, OP_Halt, SQLITE_INTERNAL, OE_Abort); |
| 88397 | VdbeComment((v, "End of SELECT coroutine")); |
| 88398 | sqlite3VdbeJumpHere(v, j1); /* label B: */ |
| 88399 | |
| 88400 | regFromSelect = dest.iSdst; |
| 88401 | assert( pSelect->pEList ); |
| 88402 | nColumn = pSelect->pEList->nExpr; |
| 88403 | assert( dest.nSdst==nColumn ); |
| 88404 | |
| 88405 | /* Set useTempTable to TRUE if the result of the SELECT statement |
| 88406 | ** should be written into a temporary table (template 4). Set to |
| 88407 | ** FALSE if each* row of the SELECT can be written directly into |
| 88408 | ** the destination table (template 3). |
| @@ -88246,11 +88434,11 @@ | |
| 88434 | |
| 88435 | srcTab = pParse->nTab++; |
| 88436 | regRec = sqlite3GetTempReg(pParse); |
| 88437 | regTempRowid = sqlite3GetTempReg(pParse); |
| 88438 | sqlite3VdbeAddOp2(v, OP_OpenEphemeral, srcTab, nColumn); |
| 88439 | addrTop = sqlite3VdbeAddOp1(v, OP_Yield, dest.iSDParm); |
| 88440 | addrIf = sqlite3VdbeAddOp1(v, OP_If, regEof); |
| 88441 | sqlite3VdbeAddOp3(v, OP_MakeRecord, regFromSelect, nColumn, regRec); |
| 88442 | sqlite3VdbeAddOp2(v, OP_NewRowid, srcTab, regTempRowid); |
| 88443 | sqlite3VdbeAddOp3(v, OP_Insert, srcTab, regRec, regTempRowid); |
| 88444 | sqlite3VdbeAddOp2(v, OP_Goto, 0, addrTop); |
| @@ -88383,11 +88571,11 @@ | |
| 88571 | ** if EOF goto D |
| 88572 | ** insert the select result into <table> from R..R+n |
| 88573 | ** goto C |
| 88574 | ** D: ... |
| 88575 | */ |
| 88576 | addrCont = sqlite3VdbeAddOp1(v, OP_Yield, dest.iSDParm); |
| 88577 | addrInsTop = sqlite3VdbeAddOp1(v, OP_If, regEof); |
| 88578 | } |
| 88579 | |
| 88580 | /* Allocate registers for holding the rowid of the new row, |
| 88581 | ** the content of the new row, and the assemblied row record. |
| @@ -91865,10 +92053,23 @@ | |
| 92053 | { OP_String8, 0, 3, 0}, /* 2 */ |
| 92054 | { OP_ResultRow, 3, 1, 0}, |
| 92055 | }; |
| 92056 | |
| 92057 | int isQuick = (sqlite3Tolower(zLeft[0])=='q'); |
| 92058 | |
| 92059 | /* If the PRAGMA command was of the form "PRAGMA <db>.integrity_check", |
| 92060 | ** then iDb is set to the index of the database identified by <db>. |
| 92061 | ** In this case, the integrity of database iDb only is verified by |
| 92062 | ** the VDBE created below. |
| 92063 | ** |
| 92064 | ** Otherwise, if the command was simply "PRAGMA integrity_check" (or |
| 92065 | ** "PRAGMA quick_check"), then iDb is set to 0. In this case, set iDb |
| 92066 | ** to -1 here, to indicate that the VDBE should verify the integrity |
| 92067 | ** of all attached databases. */ |
| 92068 | assert( iDb>=0 ); |
| 92069 | assert( iDb==0 || pId2->z ); |
| 92070 | if( pId2->z==0 ) iDb = -1; |
| 92071 | |
| 92072 | /* Initialize the VDBE program */ |
| 92073 | if( sqlite3ReadSchema(pParse) ) goto pragma_out; |
| 92074 | pParse->nMem = 6; |
| 92075 | sqlite3VdbeSetNumCols(v, 1); |
| @@ -91889,10 +92090,11 @@ | |
| 92090 | HashElem *x; |
| 92091 | Hash *pTbls; |
| 92092 | int cnt = 0; |
| 92093 | |
| 92094 | if( OMIT_TEMPDB && i==1 ) continue; |
| 92095 | if( iDb>=0 && i!=iDb ) continue; |
| 92096 | |
| 92097 | sqlite3CodeVerifySchema(pParse, i); |
| 92098 | addr = sqlite3VdbeAddOp1(v, OP_IfPos, 1); /* Halt if out of errors */ |
| 92099 | sqlite3VdbeAddOp2(v, OP_Halt, 0, 0); |
| 92100 | sqlite3VdbeJumpHere(v, addr); |
| @@ -91900,11 +92102,11 @@ | |
| 92102 | /* Do an integrity check of the B-Tree |
| 92103 | ** |
| 92104 | ** Begin by filling registers 2, 3, ... with the root pages numbers |
| 92105 | ** for all tables and indices in the database. |
| 92106 | */ |
| 92107 | assert( sqlite3SchemaMutexHeld(db, i, 0) ); |
| 92108 | pTbls = &db->aDb[i].pSchema->tblHash; |
| 92109 | for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){ |
| 92110 | Table *pTab = sqliteHashData(x); |
| 92111 | Index *pIdx; |
| 92112 | sqlite3VdbeAddOp2(v, OP_Integer, pTab->tnum, 2+cnt); |
| @@ -93224,14 +93426,14 @@ | |
| 93426 | /* |
| 93427 | ** Initialize a SelectDest structure. |
| 93428 | */ |
| 93429 | SQLITE_PRIVATE void sqlite3SelectDestInit(SelectDest *pDest, int eDest, int iParm){ |
| 93430 | pDest->eDest = (u8)eDest; |
| 93431 | pDest->iSDParm = iParm; |
| 93432 | pDest->affSdst = 0; |
| 93433 | pDest->iSdst = 0; |
| 93434 | pDest->nSdst = 0; |
| 93435 | } |
| 93436 | |
| 93437 | |
| 93438 | /* |
| 93439 | ** Allocate a new Select structure and return a pointer to that |
| @@ -93739,11 +93941,11 @@ | |
| 93941 | Vdbe *v = pParse->pVdbe; |
| 93942 | int i; |
| 93943 | int hasDistinct; /* True if the DISTINCT keyword is present */ |
| 93944 | int regResult; /* Start of memory holding result set */ |
| 93945 | int eDest = pDest->eDest; /* How to dispose of results */ |
| 93946 | int iParm = pDest->iSDParm; /* First argument to disposal method */ |
| 93947 | int nResultCol; /* Number of result columns */ |
| 93948 | |
| 93949 | assert( v ); |
| 93950 | if( NEVER(v==0) ) return; |
| 93951 | assert( pEList!=0 ); |
| @@ -93757,18 +93959,18 @@ | |
| 93959 | if( nColumn>0 ){ |
| 93960 | nResultCol = nColumn; |
| 93961 | }else{ |
| 93962 | nResultCol = pEList->nExpr; |
| 93963 | } |
| 93964 | if( pDest->iSdst==0 ){ |
| 93965 | pDest->iSdst = pParse->nMem+1; |
| 93966 | pDest->nSdst = nResultCol; |
| 93967 | pParse->nMem += nResultCol; |
| 93968 | }else{ |
| 93969 | assert( pDest->nSdst==nResultCol ); |
| 93970 | } |
| 93971 | regResult = pDest->iSdst; |
| 93972 | if( nColumn>0 ){ |
| 93973 | for(i=0; i<nColumn; i++){ |
| 93974 | sqlite3VdbeAddOp3(v, OP_Column, srcTab, i, regResult+i); |
| 93975 | } |
| 93976 | }else if( eDest!=SRT_Exists ){ |
| @@ -93843,11 +94045,11 @@ | |
| 94045 | ** then there should be a single item on the stack. Write this |
| 94046 | ** item into the set table with bogus data. |
| 94047 | */ |
| 94048 | case SRT_Set: { |
| 94049 | assert( nColumn==1 ); |
| 94050 | p->affinity = sqlite3CompareAffinity(pEList->a[0].pExpr, pDest->affSdst); |
| 94051 | if( pOrderBy ){ |
| 94052 | /* At first glance you would think we could optimize out the |
| 94053 | ** ORDER BY in this case since the order of entries in the set |
| 94054 | ** does not matter. But there might be a LIMIT clause, in which |
| 94055 | ** case the order does matter */ |
| @@ -93898,11 +94100,11 @@ | |
| 94100 | int r1 = sqlite3GetTempReg(pParse); |
| 94101 | sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nColumn, r1); |
| 94102 | pushOntoSorter(pParse, pOrderBy, p, r1); |
| 94103 | sqlite3ReleaseTempReg(pParse, r1); |
| 94104 | }else if( eDest==SRT_Coroutine ){ |
| 94105 | sqlite3VdbeAddOp1(v, OP_Yield, pDest->iSDParm); |
| 94106 | }else{ |
| 94107 | sqlite3VdbeAddOp2(v, OP_ResultRow, regResult, nColumn); |
| 94108 | sqlite3ExprCacheAffinityChange(pParse, regResult, nColumn); |
| 94109 | } |
| 94110 | break; |
| @@ -94078,11 +94280,11 @@ | |
| 94280 | int iTab; |
| 94281 | int pseudoTab = 0; |
| 94282 | ExprList *pOrderBy = p->pOrderBy; |
| 94283 | |
| 94284 | int eDest = pDest->eDest; |
| 94285 | int iParm = pDest->iSDParm; |
| 94286 | |
| 94287 | int regRow; |
| 94288 | int regRowid; |
| 94289 | |
| 94290 | iTab = pOrderBy->iECursor; |
| @@ -94137,21 +94339,21 @@ | |
| 94339 | int i; |
| 94340 | assert( eDest==SRT_Output || eDest==SRT_Coroutine ); |
| 94341 | testcase( eDest==SRT_Output ); |
| 94342 | testcase( eDest==SRT_Coroutine ); |
| 94343 | for(i=0; i<nColumn; i++){ |
| 94344 | assert( regRow!=pDest->iSdst+i ); |
| 94345 | sqlite3VdbeAddOp3(v, OP_Column, pseudoTab, i, pDest->iSdst+i); |
| 94346 | if( i==0 ){ |
| 94347 | sqlite3VdbeChangeP5(v, OPFLAG_CLEARCACHE); |
| 94348 | } |
| 94349 | } |
| 94350 | if( eDest==SRT_Output ){ |
| 94351 | sqlite3VdbeAddOp2(v, OP_ResultRow, pDest->iSdst, nColumn); |
| 94352 | sqlite3ExprCacheAffinityChange(pParse, pDest->iSdst, nColumn); |
| 94353 | }else{ |
| 94354 | sqlite3VdbeAddOp1(v, OP_Yield, pDest->iSDParm); |
| 94355 | } |
| 94356 | break; |
| 94357 | } |
| 94358 | } |
| 94359 | sqlite3ReleaseTempReg(pParse, regRow); |
| @@ -94798,11 +95000,11 @@ | |
| 95000 | |
| 95001 | /* Create the destination temporary table if necessary |
| 95002 | */ |
| 95003 | if( dest.eDest==SRT_EphemTab ){ |
| 95004 | assert( p->pEList ); |
| 95005 | sqlite3VdbeAddOp2(v, OP_OpenEphemeral, dest.iSDParm, p->pEList->nExpr); |
| 95006 | sqlite3VdbeChangeP5(v, BTREE_UNORDERED); |
| 95007 | dest.eDest = SRT_Table; |
| 95008 | } |
| 95009 | |
| 95010 | /* Make sure all SELECTs in the statement have the same number of elements |
| @@ -94884,11 +95086,11 @@ | |
| 95086 | */ |
| 95087 | assert( p->pRightmost!=p ); /* Can only happen for leftward elements |
| 95088 | ** of a 3-way or more compound */ |
| 95089 | assert( p->pLimit==0 ); /* Not allowed on leftward elements */ |
| 95090 | assert( p->pOffset==0 ); /* Not allowed on leftward elements */ |
| 95091 | unionTab = dest.iSDParm; |
| 95092 | }else{ |
| 95093 | /* We will need to create our own temporary table to hold the |
| 95094 | ** intermediate results. |
| 95095 | */ |
| 95096 | unionTab = pParse->nTab++; |
| @@ -94941,11 +95143,11 @@ | |
| 95143 | p->iOffset = 0; |
| 95144 | |
| 95145 | /* Convert the data in the temporary table into whatever form |
| 95146 | ** it is that we currently need. |
| 95147 | */ |
| 95148 | assert( unionTab==dest.iSDParm || dest.eDest!=priorOp ); |
| 95149 | if( dest.eDest!=priorOp ){ |
| 95150 | int iCont, iBreak, iStart; |
| 95151 | assert( p->pEList ); |
| 95152 | if( dest.eDest==SRT_Output ){ |
| 95153 | Select *pFirst = p; |
| @@ -95005,11 +95207,11 @@ | |
| 95207 | p->pPrior = 0; |
| 95208 | pLimit = p->pLimit; |
| 95209 | p->pLimit = 0; |
| 95210 | pOffset = p->pOffset; |
| 95211 | p->pOffset = 0; |
| 95212 | intersectdest.iSDParm = tab2; |
| 95213 | explainSetInteger(iSub2, pParse->iNextSelectId); |
| 95214 | rc = sqlite3Select(pParse, p, &intersectdest); |
| 95215 | testcase( rc!=SQLITE_OK ); |
| 95216 | pDelete = p->pPrior; |
| 95217 | p->pPrior = pPrior; |
| @@ -95099,23 +95301,23 @@ | |
| 95301 | } |
| 95302 | sqlite3DbFree(db, pKeyInfo); |
| 95303 | } |
| 95304 | |
| 95305 | multi_select_end: |
| 95306 | pDest->iSdst = dest.iSdst; |
| 95307 | pDest->nSdst = dest.nSdst; |
| 95308 | sqlite3SelectDelete(db, pDelete); |
| 95309 | return rc; |
| 95310 | } |
| 95311 | #endif /* SQLITE_OMIT_COMPOUND_SELECT */ |
| 95312 | |
| 95313 | /* |
| 95314 | ** Code an output subroutine for a coroutine implementation of a |
| 95315 | ** SELECT statment. |
| 95316 | ** |
| 95317 | ** The data to be output is contained in pIn->iSdst. There are |
| 95318 | ** pIn->nSdst columns to be output. pDest is where the output should |
| 95319 | ** be sent. |
| 95320 | ** |
| 95321 | ** regReturn is the number of the register holding the subroutine |
| 95322 | ** return address. |
| 95323 | ** |
| @@ -95149,15 +95351,15 @@ | |
| 95351 | /* Suppress duplicates for UNION, EXCEPT, and INTERSECT |
| 95352 | */ |
| 95353 | if( regPrev ){ |
| 95354 | int j1, j2; |
| 95355 | j1 = sqlite3VdbeAddOp1(v, OP_IfNot, regPrev); |
| 95356 | j2 = sqlite3VdbeAddOp4(v, OP_Compare, pIn->iSdst, regPrev+1, pIn->nSdst, |
| 95357 | (char*)pKeyInfo, p4type); |
| 95358 | sqlite3VdbeAddOp3(v, OP_Jump, j2+2, iContinue, j2+2); |
| 95359 | sqlite3VdbeJumpHere(v, j1); |
| 95360 | sqlite3ExprCodeCopy(pParse, pIn->iSdst, regPrev+1, pIn->nSdst); |
| 95361 | sqlite3VdbeAddOp2(v, OP_Integer, 1, regPrev); |
| 95362 | } |
| 95363 | if( pParse->db->mallocFailed ) return 0; |
| 95364 | |
| 95365 | /* Suppress the the first OFFSET entries if there is an OFFSET clause |
| @@ -95171,13 +95373,13 @@ | |
| 95373 | case SRT_EphemTab: { |
| 95374 | int r1 = sqlite3GetTempReg(pParse); |
| 95375 | int r2 = sqlite3GetTempReg(pParse); |
| 95376 | testcase( pDest->eDest==SRT_Table ); |
| 95377 | testcase( pDest->eDest==SRT_EphemTab ); |
| 95378 | sqlite3VdbeAddOp3(v, OP_MakeRecord, pIn->iSdst, pIn->nSdst, r1); |
| 95379 | sqlite3VdbeAddOp2(v, OP_NewRowid, pDest->iSDParm, r2); |
| 95380 | sqlite3VdbeAddOp3(v, OP_Insert, pDest->iSDParm, r1, r2); |
| 95381 | sqlite3VdbeChangeP5(v, OPFLAG_APPEND); |
| 95382 | sqlite3ReleaseTempReg(pParse, r2); |
| 95383 | sqlite3ReleaseTempReg(pParse, r1); |
| 95384 | break; |
| 95385 | } |
| @@ -95187,26 +95389,26 @@ | |
| 95389 | ** then there should be a single item on the stack. Write this |
| 95390 | ** item into the set table with bogus data. |
| 95391 | */ |
| 95392 | case SRT_Set: { |
| 95393 | int r1; |
| 95394 | assert( pIn->nSdst==1 ); |
| 95395 | p->affinity = |
| 95396 | sqlite3CompareAffinity(p->pEList->a[0].pExpr, pDest->affSdst); |
| 95397 | r1 = sqlite3GetTempReg(pParse); |
| 95398 | sqlite3VdbeAddOp4(v, OP_MakeRecord, pIn->iSdst, 1, r1, &p->affinity, 1); |
| 95399 | sqlite3ExprCacheAffinityChange(pParse, pIn->iSdst, 1); |
| 95400 | sqlite3VdbeAddOp2(v, OP_IdxInsert, pDest->iSDParm, r1); |
| 95401 | sqlite3ReleaseTempReg(pParse, r1); |
| 95402 | break; |
| 95403 | } |
| 95404 | |
| 95405 | #if 0 /* Never occurs on an ORDER BY query */ |
| 95406 | /* If any row exist in the result set, record that fact and abort. |
| 95407 | */ |
| 95408 | case SRT_Exists: { |
| 95409 | sqlite3VdbeAddOp2(v, OP_Integer, 1, pDest->iSDParm); |
| 95410 | /* The LIMIT clause will terminate the loop for us */ |
| 95411 | break; |
| 95412 | } |
| 95413 | #endif |
| 95414 | |
| @@ -95213,27 +95415,27 @@ | |
| 95415 | /* If this is a scalar select that is part of an expression, then |
| 95416 | ** store the results in the appropriate memory cell and break out |
| 95417 | ** of the scan loop. |
| 95418 | */ |
| 95419 | case SRT_Mem: { |
| 95420 | assert( pIn->nSdst==1 ); |
| 95421 | sqlite3ExprCodeMove(pParse, pIn->iSdst, pDest->iSDParm, 1); |
| 95422 | /* The LIMIT clause will jump out of the loop for us */ |
| 95423 | break; |
| 95424 | } |
| 95425 | #endif /* #ifndef SQLITE_OMIT_SUBQUERY */ |
| 95426 | |
| 95427 | /* The results are stored in a sequence of registers |
| 95428 | ** starting at pDest->iSdst. Then the co-routine yields. |
| 95429 | */ |
| 95430 | case SRT_Coroutine: { |
| 95431 | if( pDest->iSdst==0 ){ |
| 95432 | pDest->iSdst = sqlite3GetTempRange(pParse, pIn->nSdst); |
| 95433 | pDest->nSdst = pIn->nSdst; |
| 95434 | } |
| 95435 | sqlite3ExprCodeMove(pParse, pIn->iSdst, pDest->iSdst, pDest->nSdst); |
| 95436 | sqlite3VdbeAddOp1(v, OP_Yield, pDest->iSDParm); |
| 95437 | break; |
| 95438 | } |
| 95439 | |
| 95440 | /* If none of the above, then the result destination must be |
| 95441 | ** SRT_Output. This routine is never called with any other |
| @@ -95243,12 +95445,12 @@ | |
| 95445 | ** Then the OP_ResultRow opcode is used to cause sqlite3_step() to |
| 95446 | ** return the next row of result. |
| 95447 | */ |
| 95448 | default: { |
| 95449 | assert( pDest->eDest==SRT_Output ); |
| 95450 | sqlite3VdbeAddOp2(v, OP_ResultRow, pIn->iSdst, pIn->nSdst); |
| 95451 | sqlite3ExprCacheAffinityChange(pParse, pIn->iSdst, pIn->nSdst); |
| 95452 | break; |
| 95453 | } |
| 95454 | } |
| 95455 | |
| 95456 | /* Jump to the end of the loop if the LIMIT is reached. |
| @@ -95663,11 +95865,11 @@ | |
| 95865 | |
| 95866 | /* Implement the main merge loop |
| 95867 | */ |
| 95868 | sqlite3VdbeResolveLabel(v, labelCmpr); |
| 95869 | sqlite3VdbeAddOp4(v, OP_Permutation, 0, 0, 0, (char*)aPermute, P4_INTARRAY); |
| 95870 | sqlite3VdbeAddOp4(v, OP_Compare, destA.iSdst, destB.iSdst, nOrderBy, |
| 95871 | (char*)pKeyMerge, P4_KEYINFO_HANDOFF); |
| 95872 | sqlite3VdbeAddOp3(v, OP_Jump, addrAltB, addrAeqB, addrAgtB); |
| 95873 | |
| 95874 | /* Release temporary registers |
| 95875 | */ |
| @@ -96909,37 +97111,38 @@ | |
| 97111 | ** SRT_Output Generate a row of output (using the OP_ResultRow |
| 97112 | ** opcode) for each row in the result set. |
| 97113 | ** |
| 97114 | ** SRT_Mem Only valid if the result is a single column. |
| 97115 | ** Store the first column of the first result row |
| 97116 | ** in register pDest->iSDParm then abandon the rest |
| 97117 | ** of the query. This destination implies "LIMIT 1". |
| 97118 | ** |
| 97119 | ** SRT_Set The result must be a single column. Store each |
| 97120 | ** row of result as the key in table pDest->iSDParm. |
| 97121 | ** Apply the affinity pDest->affSdst before storing |
| 97122 | ** results. Used to implement "IN (SELECT ...)". |
| 97123 | ** |
| 97124 | ** SRT_Union Store results as a key in a temporary table |
| 97125 | ** identified by pDest->iSDParm. |
| 97126 | ** |
| 97127 | ** SRT_Except Remove results from the temporary table pDest->iSDParm. |
| 97128 | ** |
| 97129 | ** SRT_Table Store results in temporary table pDest->iSDParm. |
| 97130 | ** This is like SRT_EphemTab except that the table |
| 97131 | ** is assumed to already be open. |
| 97132 | ** |
| 97133 | ** SRT_EphemTab Create an temporary table pDest->iSDParm and store |
| 97134 | ** the result there. The cursor is left open after |
| 97135 | ** returning. This is like SRT_Table except that |
| 97136 | ** this destination uses OP_OpenEphemeral to create |
| 97137 | ** the table first. |
| 97138 | ** |
| 97139 | ** SRT_Coroutine Generate a co-routine that returns a new row of |
| 97140 | ** results each time it is invoked. The entry point |
| 97141 | ** of the co-routine is stored in register pDest->iSDParm. |
| 97142 | ** |
| 97143 | ** SRT_Exists Store a 1 in memory cell pDest->iSDParm if the result |
| 97144 | ** set is not empty. |
| 97145 | ** |
| 97146 | ** SRT_Discard Throw the results away. This is used by SELECT |
| 97147 | ** statements within triggers whose only purpose is |
| 97148 | ** the side-effects of functions. |
| @@ -97179,11 +97382,11 @@ | |
| 97382 | } |
| 97383 | |
| 97384 | /* If the output is destined for a temporary table, open that table. |
| 97385 | */ |
| 97386 | if( pDest->eDest==SRT_EphemTab ){ |
| 97387 | sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pDest->iSDParm, pEList->nExpr); |
| 97388 | } |
| 97389 | |
| 97390 | /* Set the limiter. |
| 97391 | */ |
| 97392 | iEnd = sqlite3VdbeMakeLabel(v); |
| 97393 |
+5
-5
| --- src/sqlite3.h | ||
| +++ src/sqlite3.h | ||
| @@ -107,11 +107,11 @@ | ||
| 107 | 107 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 108 | 108 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 109 | 109 | */ |
| 110 | 110 | #define SQLITE_VERSION "3.7.14" |
| 111 | 111 | #define SQLITE_VERSION_NUMBER 3007014 |
| 112 | -#define SQLITE_SOURCE_ID "2012-06-21 17:21:52 d5e6880279210ca63e2d5e7f6d009f30566f1242" | |
| 112 | +#define SQLITE_SOURCE_ID "2012-08-14 17:29:27 6954fef006431d153de6e63e362b8d260ebeb1c6" | |
| 113 | 113 | |
| 114 | 114 | /* |
| 115 | 115 | ** CAPI3REF: Run-Time Library Version Numbers |
| 116 | 116 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 117 | 117 | ** |
| @@ -4155,15 +4155,15 @@ | ||
| 4155 | 4155 | ** ^The sqlite3_result_error_code() function changes the error code |
| 4156 | 4156 | ** returned by SQLite as a result of an error in a function. ^By default, |
| 4157 | 4157 | ** the error code is SQLITE_ERROR. ^A subsequent call to sqlite3_result_error() |
| 4158 | 4158 | ** or sqlite3_result_error16() resets the error code to SQLITE_ERROR. |
| 4159 | 4159 | ** |
| 4160 | -** ^The sqlite3_result_toobig() interface causes SQLite to throw an error | |
| 4161 | -** indicating that a string or BLOB is too long to represent. | |
| 4160 | +** ^The sqlite3_result_error_toobig() interface causes SQLite to throw an | |
| 4161 | +** error indicating that a string or BLOB is too long to represent. | |
| 4162 | 4162 | ** |
| 4163 | -** ^The sqlite3_result_nomem() interface causes SQLite to throw an error | |
| 4164 | -** indicating that a memory allocation failed. | |
| 4163 | +** ^The sqlite3_result_error_nomem() interface causes SQLite to throw an | |
| 4164 | +** error indicating that a memory allocation failed. | |
| 4165 | 4165 | ** |
| 4166 | 4166 | ** ^The sqlite3_result_int() interface sets the return value |
| 4167 | 4167 | ** of the application-defined function to be the 32-bit signed integer |
| 4168 | 4168 | ** value given in the 2nd argument. |
| 4169 | 4169 | ** ^The sqlite3_result_int64() interface sets the return value |
| 4170 | 4170 |
| --- src/sqlite3.h | |
| +++ src/sqlite3.h | |
| @@ -107,11 +107,11 @@ | |
| 107 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 108 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 109 | */ |
| 110 | #define SQLITE_VERSION "3.7.14" |
| 111 | #define SQLITE_VERSION_NUMBER 3007014 |
| 112 | #define SQLITE_SOURCE_ID "2012-06-21 17:21:52 d5e6880279210ca63e2d5e7f6d009f30566f1242" |
| 113 | |
| 114 | /* |
| 115 | ** CAPI3REF: Run-Time Library Version Numbers |
| 116 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 117 | ** |
| @@ -4155,15 +4155,15 @@ | |
| 4155 | ** ^The sqlite3_result_error_code() function changes the error code |
| 4156 | ** returned by SQLite as a result of an error in a function. ^By default, |
| 4157 | ** the error code is SQLITE_ERROR. ^A subsequent call to sqlite3_result_error() |
| 4158 | ** or sqlite3_result_error16() resets the error code to SQLITE_ERROR. |
| 4159 | ** |
| 4160 | ** ^The sqlite3_result_toobig() interface causes SQLite to throw an error |
| 4161 | ** indicating that a string or BLOB is too long to represent. |
| 4162 | ** |
| 4163 | ** ^The sqlite3_result_nomem() interface causes SQLite to throw an error |
| 4164 | ** indicating that a memory allocation failed. |
| 4165 | ** |
| 4166 | ** ^The sqlite3_result_int() interface sets the return value |
| 4167 | ** of the application-defined function to be the 32-bit signed integer |
| 4168 | ** value given in the 2nd argument. |
| 4169 | ** ^The sqlite3_result_int64() interface sets the return value |
| 4170 |
| --- src/sqlite3.h | |
| +++ src/sqlite3.h | |
| @@ -107,11 +107,11 @@ | |
| 107 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 108 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 109 | */ |
| 110 | #define SQLITE_VERSION "3.7.14" |
| 111 | #define SQLITE_VERSION_NUMBER 3007014 |
| 112 | #define SQLITE_SOURCE_ID "2012-08-14 17:29:27 6954fef006431d153de6e63e362b8d260ebeb1c6" |
| 113 | |
| 114 | /* |
| 115 | ** CAPI3REF: Run-Time Library Version Numbers |
| 116 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 117 | ** |
| @@ -4155,15 +4155,15 @@ | |
| 4155 | ** ^The sqlite3_result_error_code() function changes the error code |
| 4156 | ** returned by SQLite as a result of an error in a function. ^By default, |
| 4157 | ** the error code is SQLITE_ERROR. ^A subsequent call to sqlite3_result_error() |
| 4158 | ** or sqlite3_result_error16() resets the error code to SQLITE_ERROR. |
| 4159 | ** |
| 4160 | ** ^The sqlite3_result_error_toobig() interface causes SQLite to throw an |
| 4161 | ** error indicating that a string or BLOB is too long to represent. |
| 4162 | ** |
| 4163 | ** ^The sqlite3_result_error_nomem() interface causes SQLite to throw an |
| 4164 | ** error indicating that a memory allocation failed. |
| 4165 | ** |
| 4166 | ** ^The sqlite3_result_int() interface sets the return value |
| 4167 | ** of the application-defined function to be the 32-bit signed integer |
| 4168 | ** value given in the 2nd argument. |
| 4169 | ** ^The sqlite3_result_int64() interface sets the return value |
| 4170 |