Fossil SCM
Update the built-in SQLite to the first 3.12.0 beta.
Commit
fbc2f1c287495c38605713ead0f6a88e1b4f03c5
Parent
567ab1937e1a15b…
2 files changed
+550
-126
+13
-1
+550
-126
| --- src/sqlite3.c | ||
| +++ src/sqlite3.c | ||
| @@ -336,11 +336,11 @@ | ||
| 336 | 336 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 337 | 337 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 338 | 338 | */ |
| 339 | 339 | #define SQLITE_VERSION "3.12.0" |
| 340 | 340 | #define SQLITE_VERSION_NUMBER 3012000 |
| 341 | -#define SQLITE_SOURCE_ID "2016-03-19 00:35:02 88439a866b3b16ad7c308ebe59198662a05e7eeb" | |
| 341 | +#define SQLITE_SOURCE_ID "2016-03-21 16:06:42 4dc30cce7fdb7dba9a9aad96bb8b499b965610b2" | |
| 342 | 342 | |
| 343 | 343 | /* |
| 344 | 344 | ** CAPI3REF: Run-Time Library Version Numbers |
| 345 | 345 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 346 | 346 | ** |
| @@ -8138,10 +8138,22 @@ | ||
| 8138 | 8138 | ** ^This function does not set the database handle error code or message |
| 8139 | 8139 | ** returned by the [sqlite3_errcode()] and [sqlite3_errmsg()] functions. |
| 8140 | 8140 | */ |
| 8141 | 8141 | SQLITE_API int SQLITE_STDCALL sqlite3_db_cacheflush(sqlite3*); |
| 8142 | 8142 | |
| 8143 | +/* | |
| 8144 | +** CAPI3REF: Low-level system error code | |
| 8145 | +** | |
| 8146 | +** ^Attempt to return the underlying operating system error code or error | |
| 8147 | +** number that caused the most reason I/O error or failure to open a file. | |
| 8148 | +** The return value is OS-dependent. For example, on unix systems, after | |
| 8149 | +** [sqlite3_open_v2()] returns [SQLITE_CANTOPEN], this interface could be | |
| 8150 | +** called to get back the underlying "errno" that caused the problem, such | |
| 8151 | +** as ENOSPC, EAUTH, EISDIR, and so forth. | |
| 8152 | +*/ | |
| 8153 | +SQLITE_API int SQLITE_STDCALL sqlite3_system_errno(sqlite3*); | |
| 8154 | + | |
| 8143 | 8155 | /* |
| 8144 | 8156 | ** CAPI3REF: Database Snapshot |
| 8145 | 8157 | ** KEYWORDS: {snapshot} |
| 8146 | 8158 | ** EXPERIMENTAL |
| 8147 | 8159 | ** |
| @@ -11844,10 +11856,11 @@ | ||
| 11844 | 11856 | SQLITE_PRIVATE void (*sqlite3OsDlSym(sqlite3_vfs *, void *, const char *))(void); |
| 11845 | 11857 | SQLITE_PRIVATE void sqlite3OsDlClose(sqlite3_vfs *, void *); |
| 11846 | 11858 | #endif /* SQLITE_OMIT_LOAD_EXTENSION */ |
| 11847 | 11859 | SQLITE_PRIVATE int sqlite3OsRandomness(sqlite3_vfs *, int, char *); |
| 11848 | 11860 | SQLITE_PRIVATE int sqlite3OsSleep(sqlite3_vfs *, int); |
| 11861 | +SQLITE_PRIVATE int sqlite3OsGetLastError(sqlite3_vfs*); | |
| 11849 | 11862 | SQLITE_PRIVATE int sqlite3OsCurrentTimeInt64(sqlite3_vfs *, sqlite3_int64*); |
| 11850 | 11863 | |
| 11851 | 11864 | /* |
| 11852 | 11865 | ** Convenience functions for opening and closing files using |
| 11853 | 11866 | ** sqlite3_malloc() to obtain space for the file-handle structure. |
| @@ -12141,10 +12154,11 @@ | ||
| 12141 | 12154 | i64 lastRowid; /* ROWID of most recent insert (see above) */ |
| 12142 | 12155 | i64 szMmap; /* Default mmap_size setting */ |
| 12143 | 12156 | unsigned int openFlags; /* Flags passed to sqlite3_vfs.xOpen() */ |
| 12144 | 12157 | int errCode; /* Most recent error code (SQLITE_*) */ |
| 12145 | 12158 | int errMask; /* & result codes with this before returning */ |
| 12159 | + int iSysErrno; /* Errno value from last system error */ | |
| 12146 | 12160 | u16 dbOptFlags; /* Flags to enable/disable optimizations */ |
| 12147 | 12161 | u8 enc; /* Text encoding */ |
| 12148 | 12162 | u8 autoCommit; /* The auto-commit flag. */ |
| 12149 | 12163 | u8 temp_store; /* 1: file 2: memory 0: default */ |
| 12150 | 12164 | u8 mallocFailed; /* True if we have seen a malloc failure */ |
| @@ -14687,10 +14701,11 @@ | ||
| 14687 | 14701 | SQLITE_PRIVATE char sqlite3ExprAffinity(Expr *pExpr); |
| 14688 | 14702 | SQLITE_PRIVATE int sqlite3Atoi64(const char*, i64*, int, u8); |
| 14689 | 14703 | SQLITE_PRIVATE int sqlite3DecOrHexToI64(const char*, i64*); |
| 14690 | 14704 | SQLITE_PRIVATE void sqlite3ErrorWithMsg(sqlite3*, int, const char*,...); |
| 14691 | 14705 | SQLITE_PRIVATE void sqlite3Error(sqlite3*,int); |
| 14706 | +SQLITE_PRIVATE void sqlite3SystemError(sqlite3*,int); | |
| 14692 | 14707 | SQLITE_PRIVATE void *sqlite3HexToBlob(sqlite3*, const char *z, int n); |
| 14693 | 14708 | SQLITE_PRIVATE u8 sqlite3HexToInt(int h); |
| 14694 | 14709 | SQLITE_PRIVATE int sqlite3TwoPartName(Parse *, Token *, Token *, Token **); |
| 14695 | 14710 | |
| 14696 | 14711 | #if defined(SQLITE_NEED_ERR_NAME) |
| @@ -18111,10 +18126,13 @@ | ||
| 18111 | 18126 | return pVfs->xRandomness(pVfs, nByte, zBufOut); |
| 18112 | 18127 | } |
| 18113 | 18128 | SQLITE_PRIVATE int sqlite3OsSleep(sqlite3_vfs *pVfs, int nMicro){ |
| 18114 | 18129 | return pVfs->xSleep(pVfs, nMicro); |
| 18115 | 18130 | } |
| 18131 | +SQLITE_PRIVATE int sqlite3OsGetLastError(sqlite3_vfs *pVfs){ | |
| 18132 | + return pVfs->xGetLastError ? pVfs->xGetLastError(pVfs, 0, 0) : 0; | |
| 18133 | +} | |
| 18116 | 18134 | SQLITE_PRIVATE int sqlite3OsCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *pTimeOut){ |
| 18117 | 18135 | int rc; |
| 18118 | 18136 | /* IMPLEMENTATION-OF: R-49045-42493 SQLite will use the xCurrentTimeInt64() |
| 18119 | 18137 | ** method to get the current date and time if that method is available |
| 18120 | 18138 | ** (if iVersion is 2 or greater and the function pointer is not NULL) and |
| @@ -25475,18 +25493,42 @@ | ||
| 25475 | 25493 | ** a poiner to that other string. |
| 25476 | 25494 | */ |
| 25477 | 25495 | SQLITE_PRIVATE const char *sqlite3StrNext(const char *z){ |
| 25478 | 25496 | return z + strlen(z) + 1; |
| 25479 | 25497 | } |
| 25498 | + | |
| 25499 | +/* | |
| 25500 | +** Helper function for sqlite3Error() - called rarely. Broken out into | |
| 25501 | +** a separate routine to avoid unnecessary register saves on entry to | |
| 25502 | +** sqlite3Error(). | |
| 25503 | +*/ | |
| 25504 | +static SQLITE_NOINLINE void sqlite3ErrorFinish(sqlite3 *db, int err_code){ | |
| 25505 | + if( db->pErr ) sqlite3ValueSetNull(db->pErr); | |
| 25506 | + sqlite3SystemError(db, err_code); | |
| 25507 | +} | |
| 25480 | 25508 | |
| 25481 | 25509 | /* |
| 25482 | 25510 | ** Set the current error code to err_code and clear any prior error message. |
| 25511 | +** Also set iSysErrno (by calling sqlite3System) if the err_code indicates | |
| 25512 | +** that would be appropriate. | |
| 25483 | 25513 | */ |
| 25484 | 25514 | SQLITE_PRIVATE void sqlite3Error(sqlite3 *db, int err_code){ |
| 25485 | 25515 | assert( db!=0 ); |
| 25486 | 25516 | db->errCode = err_code; |
| 25487 | - if( db->pErr ) sqlite3ValueSetNull(db->pErr); | |
| 25517 | + if( err_code || db->pErr ) sqlite3ErrorFinish(db, err_code); | |
| 25518 | +} | |
| 25519 | + | |
| 25520 | +/* | |
| 25521 | +** Load the sqlite3.iSysErrno field if that is an appropriate thing | |
| 25522 | +** to do based on the SQLite error code in rc. | |
| 25523 | +*/ | |
| 25524 | +SQLITE_PRIVATE void sqlite3SystemError(sqlite3 *db, int rc){ | |
| 25525 | + if( rc==SQLITE_IOERR_NOMEM ) return; | |
| 25526 | + rc &= 0xff; | |
| 25527 | + if( rc==SQLITE_CANTOPEN || rc==SQLITE_IOERR ){ | |
| 25528 | + db->iSysErrno = sqlite3OsGetLastError(db->pVfs); | |
| 25529 | + } | |
| 25488 | 25530 | } |
| 25489 | 25531 | |
| 25490 | 25532 | /* |
| 25491 | 25533 | ** Set the most recent error code and error string for the sqlite |
| 25492 | 25534 | ** handle "db". The error code is set to "err_code". |
| @@ -25509,10 +25551,11 @@ | ||
| 25509 | 25551 | ** to NULL. |
| 25510 | 25552 | */ |
| 25511 | 25553 | SQLITE_PRIVATE void sqlite3ErrorWithMsg(sqlite3 *db, int err_code, const char *zFormat, ...){ |
| 25512 | 25554 | assert( db!=0 ); |
| 25513 | 25555 | db->errCode = err_code; |
| 25556 | + sqlite3SystemError(db, err_code); | |
| 25514 | 25557 | if( zFormat==0 ){ |
| 25515 | 25558 | sqlite3Error(db, err_code); |
| 25516 | 25559 | }else if( db->pErr || (db->pErr = sqlite3ValueNew(db))!=0 ){ |
| 25517 | 25560 | char *z; |
| 25518 | 25561 | va_list ap; |
| @@ -28814,11 +28857,11 @@ | ||
| 28814 | 28857 | rc = osFstat(pFile->h, &buf); |
| 28815 | 28858 | if( rc!=0 ){ |
| 28816 | 28859 | sqlite3_log(SQLITE_WARNING, "cannot fstat db file %s", pFile->zPath); |
| 28817 | 28860 | return; |
| 28818 | 28861 | } |
| 28819 | - if( buf.st_nlink==0 && (pFile->ctrlFlags & UNIXFILE_DELETE)==0 ){ | |
| 28862 | + if( buf.st_nlink==0 ){ | |
| 28820 | 28863 | sqlite3_log(SQLITE_WARNING, "file unlinked while open: %s", pFile->zPath); |
| 28821 | 28864 | return; |
| 28822 | 28865 | } |
| 28823 | 28866 | if( buf.st_nlink>1 ){ |
| 28824 | 28867 | sqlite3_log(SQLITE_WARNING, "multiple links to file: %s", pFile->zPath); |
| @@ -33712,27 +33755,22 @@ | ||
| 33712 | 33755 | } |
| 33713 | 33756 | #else |
| 33714 | 33757 | # define unixCurrentTime 0 |
| 33715 | 33758 | #endif |
| 33716 | 33759 | |
| 33717 | -#ifndef SQLITE_OMIT_DEPRECATED | |
| 33718 | 33760 | /* |
| 33719 | -** We added the xGetLastError() method with the intention of providing | |
| 33720 | -** better low-level error messages when operating-system problems come up | |
| 33721 | -** during SQLite operation. But so far, none of that has been implemented | |
| 33722 | -** in the core. So this routine is never called. For now, it is merely | |
| 33723 | -** a place-holder. | |
| 33761 | +** The xGetLastError() method is designed to return a better | |
| 33762 | +** low-level error message when operating-system problems come up | |
| 33763 | +** during SQLite operation. Only the integer return code is currently | |
| 33764 | +** used. | |
| 33724 | 33765 | */ |
| 33725 | 33766 | static int unixGetLastError(sqlite3_vfs *NotUsed, int NotUsed2, char *NotUsed3){ |
| 33726 | 33767 | UNUSED_PARAMETER(NotUsed); |
| 33727 | 33768 | UNUSED_PARAMETER(NotUsed2); |
| 33728 | 33769 | UNUSED_PARAMETER(NotUsed3); |
| 33729 | - return 0; | |
| 33770 | + return errno; | |
| 33730 | 33771 | } |
| 33731 | -#else | |
| 33732 | -# define unixGetLastError 0 | |
| 33733 | -#endif | |
| 33734 | 33772 | |
| 33735 | 33773 | |
| 33736 | 33774 | /* |
| 33737 | 33775 | ************************ End of sqlite3_vfs methods *************************** |
| 33738 | 33776 | ******************************************************************************/ |
| @@ -40819,12 +40857,14 @@ | ||
| 40819 | 40857 | ** However if an error message is supplied, it will be incorporated |
| 40820 | 40858 | ** by sqlite into the error message available to the user using |
| 40821 | 40859 | ** sqlite3_errmsg(), possibly making IO errors easier to debug. |
| 40822 | 40860 | */ |
| 40823 | 40861 | static int winGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){ |
| 40862 | + DWORD e = osGetLastError(); | |
| 40824 | 40863 | UNUSED_PARAMETER(pVfs); |
| 40825 | - return winGetLastErrorMsg(osGetLastError(), nBuf, zBuf); | |
| 40864 | + if( nBuf>0 ) winGetLastErrorMsg(e, nBuf, zBuf); | |
| 40865 | + return e; | |
| 40826 | 40866 | } |
| 40827 | 40867 | |
| 40828 | 40868 | /* |
| 40829 | 40869 | ** Initialize and deinitialize the operating system interface. |
| 40830 | 40870 | */ |
| @@ -66997,11 +67037,11 @@ | ||
| 66997 | 67037 | ** copies are not misused. |
| 66998 | 67038 | */ |
| 66999 | 67039 | SQLITE_PRIVATE void sqlite3VdbeMemAboutToChange(Vdbe *pVdbe, Mem *pMem){ |
| 67000 | 67040 | int i; |
| 67001 | 67041 | Mem *pX; |
| 67002 | - for(i=1, pX=&pVdbe->aMem[1]; i<=pVdbe->nMem; i++, pX++){ | |
| 67042 | + for(i=0, pX=pVdbe->aMem; i<pVdbe->nMem; i++, pX++){ | |
| 67003 | 67043 | if( pX->pScopyFrom==pMem ){ |
| 67004 | 67044 | pX->flags |= MEM_Undefined; |
| 67005 | 67045 | pX->pScopyFrom = 0; |
| 67006 | 67046 | } |
| 67007 | 67047 | } |
| @@ -69752,11 +69792,11 @@ | ||
| 69752 | 69792 | |
| 69753 | 69793 | /* Set the magic to VDBE_MAGIC_RUN sooner rather than later. */ |
| 69754 | 69794 | p->magic = VDBE_MAGIC_RUN; |
| 69755 | 69795 | |
| 69756 | 69796 | #ifdef SQLITE_DEBUG |
| 69757 | - for(i=1; i<p->nMem; i++){ | |
| 69797 | + for(i=0; i<p->nMem; i++){ | |
| 69758 | 69798 | assert( p->aMem[i].db==p->db ); |
| 69759 | 69799 | } |
| 69760 | 69800 | #endif |
| 69761 | 69801 | p->pc = -1; |
| 69762 | 69802 | p->rc = SQLITE_OK; |
| @@ -69817,20 +69857,17 @@ | ||
| 69817 | 69857 | nCursor = pParse->nTab; |
| 69818 | 69858 | nArg = pParse->nMaxArg; |
| 69819 | 69859 | nOnce = pParse->nOnce; |
| 69820 | 69860 | if( nOnce==0 ) nOnce = 1; /* Ensure at least one byte in p->aOnceFlag[] */ |
| 69821 | 69861 | |
| 69822 | - /* For each cursor required, also allocate a memory cell. Memory | |
| 69823 | - ** cells (nMem+1-nCursor)..nMem, inclusive, will never be used by | |
| 69824 | - ** the vdbe program. Instead they are used to allocate memory for | |
| 69825 | - ** VdbeCursor/BtCursor structures. The blob of memory associated with | |
| 69826 | - ** cursor 0 is stored in memory cell nMem. Memory cell (nMem-1) | |
| 69827 | - ** stores the blob of memory associated with cursor 1, etc. | |
| 69828 | - ** | |
| 69862 | + /* Each cursor uses a memory cell. The first cursor (cursor 0) can | |
| 69863 | + ** use aMem[0] which is not otherwise used by the VDBE program. Allocate | |
| 69864 | + ** space at the end of aMem[] for cursors 1 and greater. | |
| 69829 | 69865 | ** See also: allocateCursor(). |
| 69830 | 69866 | */ |
| 69831 | 69867 | nMem += nCursor; |
| 69868 | + if( nCursor==0 && nMem>0 ) nMem++; /* Space for aMem[0] even if not used */ | |
| 69832 | 69869 | |
| 69833 | 69870 | /* Figure out how much reusable memory is available at the end of the |
| 69834 | 69871 | ** opcode array. This extra memory will be reallocated for other elements |
| 69835 | 69872 | ** of the prepared statement. |
| 69836 | 69873 | */ |
| @@ -69888,13 +69925,12 @@ | ||
| 69888 | 69925 | p->nzVar = pParse->nzVar; |
| 69889 | 69926 | p->azVar = pParse->azVar; |
| 69890 | 69927 | pParse->nzVar = 0; |
| 69891 | 69928 | pParse->azVar = 0; |
| 69892 | 69929 | if( p->aMem ){ |
| 69893 | - p->aMem--; /* aMem[] goes from 1..nMem */ | |
| 69894 | - p->nMem = nMem; /* not from 0..nMem-1 */ | |
| 69895 | - for(n=1; n<=nMem; n++){ | |
| 69930 | + p->nMem = nMem; | |
| 69931 | + for(n=0; n<nMem; n++){ | |
| 69896 | 69932 | p->aMem[n].flags = MEM_Undefined; |
| 69897 | 69933 | p->aMem[n].db = db; |
| 69898 | 69934 | } |
| 69899 | 69935 | } |
| 69900 | 69936 | p->explain = pParse->explain; |
| @@ -70000,11 +70036,11 @@ | ||
| 70000 | 70036 | p->nFrame = 0; |
| 70001 | 70037 | } |
| 70002 | 70038 | assert( p->nFrame==0 ); |
| 70003 | 70039 | closeCursorsInFrame(p); |
| 70004 | 70040 | if( p->aMem ){ |
| 70005 | - releaseMemArray(&p->aMem[1], p->nMem); | |
| 70041 | + releaseMemArray(p->aMem, p->nMem); | |
| 70006 | 70042 | } |
| 70007 | 70043 | while( p->pDelFrame ){ |
| 70008 | 70044 | VdbeFrame *pDel = p->pDelFrame; |
| 70009 | 70045 | p->pDelFrame = pDel->pParent; |
| 70010 | 70046 | sqlite3VdbeFrameDelete(pDel); |
| @@ -70025,11 +70061,11 @@ | ||
| 70025 | 70061 | /* Execute assert() statements to ensure that the Vdbe.apCsr[] and |
| 70026 | 70062 | ** Vdbe.aMem[] arrays have already been cleaned up. */ |
| 70027 | 70063 | int i; |
| 70028 | 70064 | if( p->apCsr ) for(i=0; i<p->nCursor; i++) assert( p->apCsr[i]==0 ); |
| 70029 | 70065 | if( p->aMem ){ |
| 70030 | - for(i=1; i<=p->nMem; i++) assert( p->aMem[i].flags==MEM_Undefined ); | |
| 70066 | + for(i=0; i<p->nMem; i++) assert( p->aMem[i].flags==MEM_Undefined ); | |
| 70031 | 70067 | } |
| 70032 | 70068 | #endif |
| 70033 | 70069 | |
| 70034 | 70070 | sqlite3DbFree(db, p->zErrMsg); |
| 70035 | 70071 | p->zErrMsg = 0; |
| @@ -74506,23 +74542,23 @@ | ||
| 74506 | 74542 | ** |
| 74507 | 74543 | ** * When using ENABLE_MEMORY_MANAGEMENT, memory cell buffers can |
| 74508 | 74544 | ** be freed lazily via the sqlite3_release_memory() API. This |
| 74509 | 74545 | ** minimizes the number of malloc calls made by the system. |
| 74510 | 74546 | ** |
| 74511 | - ** Memory cells for cursors are allocated at the top of the address | |
| 74512 | - ** space. Memory cell (p->nMem) corresponds to cursor 0. Space for | |
| 74513 | - ** cursor 1 is managed by memory cell (p->nMem-1), etc. | |
| 74547 | + ** The memory cell for cursor 0 is aMem[0]. The rest are allocated from | |
| 74548 | + ** the top of the register space. Cursor 1 is at Mem[p->nMem-1]. | |
| 74549 | + ** Cursor 2 is at Mem[p->nMem-2]. And so forth. | |
| 74514 | 74550 | */ |
| 74515 | - Mem *pMem = &p->aMem[p->nMem-iCur]; | |
| 74551 | + Mem *pMem = iCur>0 ? &p->aMem[p->nMem-iCur] : p->aMem; | |
| 74516 | 74552 | |
| 74517 | 74553 | int nByte; |
| 74518 | 74554 | VdbeCursor *pCx = 0; |
| 74519 | 74555 | nByte = |
| 74520 | 74556 | ROUND8(sizeof(VdbeCursor)) + 2*sizeof(u32)*nField + |
| 74521 | 74557 | (eCurType==CURTYPE_BTREE?sqlite3BtreeCursorSize():0); |
| 74522 | 74558 | |
| 74523 | - assert( iCur<p->nCursor ); | |
| 74559 | + assert( iCur>=0 && iCur<p->nCursor ); | |
| 74524 | 74560 | if( p->apCsr[iCur] ){ |
| 74525 | 74561 | sqlite3VdbeFreeCursor(p, p->apCsr[iCur]); |
| 74526 | 74562 | p->apCsr[iCur] = 0; |
| 74527 | 74563 | } |
| 74528 | 74564 | if( SQLITE_OK==sqlite3VdbeMemClearAndResize(pMem, nByte) ){ |
| @@ -74932,11 +74968,11 @@ | ||
| 74932 | 74968 | return pOut; |
| 74933 | 74969 | } |
| 74934 | 74970 | static Mem *out2Prerelease(Vdbe *p, VdbeOp *pOp){ |
| 74935 | 74971 | Mem *pOut; |
| 74936 | 74972 | assert( pOp->p2>0 ); |
| 74937 | - assert( pOp->p2<=(p->nMem-p->nCursor) ); | |
| 74973 | + assert( pOp->p2<=(p->nMem+1 - p->nCursor) ); | |
| 74938 | 74974 | pOut = &p->aMem[pOp->p2]; |
| 74939 | 74975 | memAboutToChange(p, pOut); |
| 74940 | 74976 | if( VdbeMemDynamic(pOut) ){ |
| 74941 | 74977 | return out2PrereleaseWithClear(pOut); |
| 74942 | 74978 | }else{ |
| @@ -75070,37 +75106,37 @@ | ||
| 75070 | 75106 | /* Sanity checking on other operands */ |
| 75071 | 75107 | #ifdef SQLITE_DEBUG |
| 75072 | 75108 | assert( pOp->opflags==sqlite3OpcodeProperty[pOp->opcode] ); |
| 75073 | 75109 | if( (pOp->opflags & OPFLG_IN1)!=0 ){ |
| 75074 | 75110 | assert( pOp->p1>0 ); |
| 75075 | - assert( pOp->p1<=(p->nMem-p->nCursor) ); | |
| 75111 | + assert( pOp->p1<=(p->nMem+1 - p->nCursor) ); | |
| 75076 | 75112 | assert( memIsValid(&aMem[pOp->p1]) ); |
| 75077 | 75113 | assert( sqlite3VdbeCheckMemInvariants(&aMem[pOp->p1]) ); |
| 75078 | 75114 | REGISTER_TRACE(pOp->p1, &aMem[pOp->p1]); |
| 75079 | 75115 | } |
| 75080 | 75116 | if( (pOp->opflags & OPFLG_IN2)!=0 ){ |
| 75081 | 75117 | assert( pOp->p2>0 ); |
| 75082 | - assert( pOp->p2<=(p->nMem-p->nCursor) ); | |
| 75118 | + assert( pOp->p2<=(p->nMem+1 - p->nCursor) ); | |
| 75083 | 75119 | assert( memIsValid(&aMem[pOp->p2]) ); |
| 75084 | 75120 | assert( sqlite3VdbeCheckMemInvariants(&aMem[pOp->p2]) ); |
| 75085 | 75121 | REGISTER_TRACE(pOp->p2, &aMem[pOp->p2]); |
| 75086 | 75122 | } |
| 75087 | 75123 | if( (pOp->opflags & OPFLG_IN3)!=0 ){ |
| 75088 | 75124 | assert( pOp->p3>0 ); |
| 75089 | - assert( pOp->p3<=(p->nMem-p->nCursor) ); | |
| 75125 | + assert( pOp->p3<=(p->nMem+1 - p->nCursor) ); | |
| 75090 | 75126 | assert( memIsValid(&aMem[pOp->p3]) ); |
| 75091 | 75127 | assert( sqlite3VdbeCheckMemInvariants(&aMem[pOp->p3]) ); |
| 75092 | 75128 | REGISTER_TRACE(pOp->p3, &aMem[pOp->p3]); |
| 75093 | 75129 | } |
| 75094 | 75130 | if( (pOp->opflags & OPFLG_OUT2)!=0 ){ |
| 75095 | 75131 | assert( pOp->p2>0 ); |
| 75096 | - assert( pOp->p2<=(p->nMem-p->nCursor) ); | |
| 75132 | + assert( pOp->p2<=(p->nMem+1 - p->nCursor) ); | |
| 75097 | 75133 | memAboutToChange(p, &aMem[pOp->p2]); |
| 75098 | 75134 | } |
| 75099 | 75135 | if( (pOp->opflags & OPFLG_OUT3)!=0 ){ |
| 75100 | 75136 | assert( pOp->p3>0 ); |
| 75101 | - assert( pOp->p3<=(p->nMem-p->nCursor) ); | |
| 75137 | + assert( pOp->p3<=(p->nMem+1 - p->nCursor) ); | |
| 75102 | 75138 | memAboutToChange(p, &aMem[pOp->p3]); |
| 75103 | 75139 | } |
| 75104 | 75140 | #endif |
| 75105 | 75141 | #if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE) |
| 75106 | 75142 | pOrigOp = pOp; |
| @@ -75195,11 +75231,11 @@ | ||
| 75195 | 75231 | ** |
| 75196 | 75232 | ** Write the current address onto register P1 |
| 75197 | 75233 | ** and then jump to address P2. |
| 75198 | 75234 | */ |
| 75199 | 75235 | case OP_Gosub: { /* jump */ |
| 75200 | - assert( pOp->p1>0 && pOp->p1<=(p->nMem-p->nCursor) ); | |
| 75236 | + assert( pOp->p1>0 && pOp->p1<=(p->nMem+1 - p->nCursor) ); | |
| 75201 | 75237 | pIn1 = &aMem[pOp->p1]; |
| 75202 | 75238 | assert( VdbeMemDynamic(pIn1)==0 ); |
| 75203 | 75239 | memAboutToChange(p, pIn1); |
| 75204 | 75240 | pIn1->flags = MEM_Int; |
| 75205 | 75241 | pIn1->u.i = (int)(pOp-aOp); |
| @@ -75235,11 +75271,11 @@ | ||
| 75235 | 75271 | ** address P2. |
| 75236 | 75272 | ** |
| 75237 | 75273 | ** See also: EndCoroutine |
| 75238 | 75274 | */ |
| 75239 | 75275 | case OP_InitCoroutine: { /* jump */ |
| 75240 | - assert( pOp->p1>0 && pOp->p1<=(p->nMem-p->nCursor) ); | |
| 75276 | + assert( pOp->p1>0 && pOp->p1<=(p->nMem+1 - p->nCursor) ); | |
| 75241 | 75277 | assert( pOp->p2>=0 && pOp->p2<p->nOp ); |
| 75242 | 75278 | assert( pOp->p3>=0 && pOp->p3<p->nOp ); |
| 75243 | 75279 | pOut = &aMem[pOp->p1]; |
| 75244 | 75280 | assert( !VdbeMemDynamic(pOut) ); |
| 75245 | 75281 | pOut->u.i = pOp->p3 - 1; |
| @@ -75504,11 +75540,11 @@ | ||
| 75504 | 75540 | pOut->enc = encoding; |
| 75505 | 75541 | UPDATE_MAX_BLOBSIZE(pOut); |
| 75506 | 75542 | #ifndef SQLITE_LIKE_DOESNT_MATCH_BLOBS |
| 75507 | 75543 | if( pOp->p5 ){ |
| 75508 | 75544 | assert( pOp->p3>0 ); |
| 75509 | - assert( pOp->p3<=(p->nMem-p->nCursor) ); | |
| 75545 | + assert( pOp->p3<=(p->nMem+1 - p->nCursor) ); | |
| 75510 | 75546 | pIn3 = &aMem[pOp->p3]; |
| 75511 | 75547 | assert( pIn3->flags & MEM_Int ); |
| 75512 | 75548 | if( pIn3->u.i ) pOut->flags = MEM_Blob|MEM_Static|MEM_Term; |
| 75513 | 75549 | } |
| 75514 | 75550 | #endif |
| @@ -75530,11 +75566,11 @@ | ||
| 75530 | 75566 | case OP_Null: { /* out2 */ |
| 75531 | 75567 | int cnt; |
| 75532 | 75568 | u16 nullFlag; |
| 75533 | 75569 | pOut = out2Prerelease(p, pOp); |
| 75534 | 75570 | cnt = pOp->p3-pOp->p2; |
| 75535 | - assert( pOp->p3<=(p->nMem-p->nCursor) ); | |
| 75571 | + assert( pOp->p3<=(p->nMem+1 - p->nCursor) ); | |
| 75536 | 75572 | pOut->flags = nullFlag = pOp->p1 ? (MEM_Null|MEM_Cleared) : MEM_Null; |
| 75537 | 75573 | while( cnt>0 ){ |
| 75538 | 75574 | pOut++; |
| 75539 | 75575 | memAboutToChange(p, pOut); |
| 75540 | 75576 | sqlite3VdbeMemSetNull(pOut); |
| @@ -75551,11 +75587,11 @@ | ||
| 75551 | 75587 | ** instruction, but do not free any string or blob memory associated with |
| 75552 | 75588 | ** the register, so that if the value was a string or blob that was |
| 75553 | 75589 | ** previously copied using OP_SCopy, the copies will continue to be valid. |
| 75554 | 75590 | */ |
| 75555 | 75591 | case OP_SoftNull: { |
| 75556 | - assert( pOp->p1>0 && pOp->p1<=(p->nMem-p->nCursor) ); | |
| 75592 | + assert( pOp->p1>0 && pOp->p1<=(p->nMem+1 - p->nCursor) ); | |
| 75557 | 75593 | pOut = &aMem[pOp->p1]; |
| 75558 | 75594 | pOut->flags = (pOut->flags|MEM_Null)&~MEM_Undefined; |
| 75559 | 75595 | break; |
| 75560 | 75596 | } |
| 75561 | 75597 | |
| @@ -75618,12 +75654,12 @@ | ||
| 75618 | 75654 | assert( p1+n<=p2 || p2+n<=p1 ); |
| 75619 | 75655 | |
| 75620 | 75656 | pIn1 = &aMem[p1]; |
| 75621 | 75657 | pOut = &aMem[p2]; |
| 75622 | 75658 | do{ |
| 75623 | - assert( pOut<=&aMem[(p->nMem-p->nCursor)] ); | |
| 75624 | - assert( pIn1<=&aMem[(p->nMem-p->nCursor)] ); | |
| 75659 | + assert( pOut<=&aMem[(p->nMem+1 - p->nCursor)] ); | |
| 75660 | + assert( pIn1<=&aMem[(p->nMem+1 - p->nCursor)] ); | |
| 75625 | 75661 | assert( memIsValid(pIn1) ); |
| 75626 | 75662 | memAboutToChange(p, pOut); |
| 75627 | 75663 | sqlite3VdbeMemMove(pOut, pIn1); |
| 75628 | 75664 | #ifdef SQLITE_DEBUG |
| 75629 | 75665 | if( pOut->pScopyFrom>=&aMem[p1] && pOut->pScopyFrom<pOut ){ |
| @@ -75719,11 +75755,11 @@ | ||
| 75719 | 75755 | case OP_ResultRow: { |
| 75720 | 75756 | Mem *pMem; |
| 75721 | 75757 | int i; |
| 75722 | 75758 | assert( p->nResColumn==pOp->p2 ); |
| 75723 | 75759 | assert( pOp->p1>0 ); |
| 75724 | - assert( pOp->p1+pOp->p2<=(p->nMem-p->nCursor)+1 ); | |
| 75760 | + assert( pOp->p1+pOp->p2<=(p->nMem+1 - p->nCursor)+1 ); | |
| 75725 | 75761 | |
| 75726 | 75762 | #ifndef SQLITE_OMIT_PROGRESS_CALLBACK |
| 75727 | 75763 | /* Run the progress counter just before returning. |
| 75728 | 75764 | */ |
| 75729 | 75765 | if( db->xProgress!=0 |
| @@ -76031,12 +76067,12 @@ | ||
| 76031 | 76067 | int n; |
| 76032 | 76068 | sqlite3_context *pCtx; |
| 76033 | 76069 | |
| 76034 | 76070 | assert( pOp->p4type==P4_FUNCDEF ); |
| 76035 | 76071 | n = pOp->p5; |
| 76036 | - assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) ); | |
| 76037 | - assert( n==0 || (pOp->p2>0 && pOp->p2+n<=(p->nMem-p->nCursor)+1) ); | |
| 76072 | + assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) ); | |
| 76073 | + assert( n==0 || (pOp->p2>0 && pOp->p2+n<=(p->nMem+1 - p->nCursor)+1) ); | |
| 76038 | 76074 | assert( pOp->p3<pOp->p2 || pOp->p3>=pOp->p2+n ); |
| 76039 | 76075 | pCtx = sqlite3DbMallocRawNN(db, sizeof(*pCtx) + (n-1)*sizeof(sqlite3_value*)); |
| 76040 | 76076 | if( pCtx==0 ) goto no_mem; |
| 76041 | 76077 | pCtx->pOut = 0; |
| 76042 | 76078 | pCtx->pFunc = pOp->p4.pFunc; |
| @@ -76532,15 +76568,15 @@ | ||
| 76532 | 76568 | p2 = pOp->p2; |
| 76533 | 76569 | #if SQLITE_DEBUG |
| 76534 | 76570 | if( aPermute ){ |
| 76535 | 76571 | int k, mx = 0; |
| 76536 | 76572 | for(k=0; k<n; k++) if( aPermute[k]>mx ) mx = aPermute[k]; |
| 76537 | - assert( p1>0 && p1+mx<=(p->nMem-p->nCursor)+1 ); | |
| 76538 | - assert( p2>0 && p2+mx<=(p->nMem-p->nCursor)+1 ); | |
| 76573 | + assert( p1>0 && p1+mx<=(p->nMem+1 - p->nCursor)+1 ); | |
| 76574 | + assert( p2>0 && p2+mx<=(p->nMem+1 - p->nCursor)+1 ); | |
| 76539 | 76575 | }else{ |
| 76540 | - assert( p1>0 && p1+n<=(p->nMem-p->nCursor)+1 ); | |
| 76541 | - assert( p2>0 && p2+n<=(p->nMem-p->nCursor)+1 ); | |
| 76576 | + assert( p1>0 && p1+n<=(p->nMem+1 - p->nCursor)+1 ); | |
| 76577 | + assert( p2>0 && p2+n<=(p->nMem+1 - p->nCursor)+1 ); | |
| 76542 | 76578 | } |
| 76543 | 76579 | #endif /* SQLITE_DEBUG */ |
| 76544 | 76580 | for(i=0; i<n; i++){ |
| 76545 | 76581 | idx = aPermute ? aPermute[i] : i; |
| 76546 | 76582 | assert( memIsValid(&aMem[p1+idx]) ); |
| @@ -76798,11 +76834,11 @@ | ||
| 76798 | 76834 | p2 = pOp->p2; |
| 76799 | 76835 | |
| 76800 | 76836 | /* If the cursor cache is stale, bring it up-to-date */ |
| 76801 | 76837 | rc = sqlite3VdbeCursorMoveto(&pC, &p2); |
| 76802 | 76838 | |
| 76803 | - assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) ); | |
| 76839 | + assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) ); | |
| 76804 | 76840 | pDest = &aMem[pOp->p3]; |
| 76805 | 76841 | memAboutToChange(p, pDest); |
| 76806 | 76842 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 76807 | 76843 | assert( pC!=0 ); |
| 76808 | 76844 | assert( p2<pC->nField ); |
| @@ -77041,11 +77077,11 @@ | ||
| 77041 | 77077 | zAffinity = pOp->p4.z; |
| 77042 | 77078 | assert( zAffinity!=0 ); |
| 77043 | 77079 | assert( zAffinity[pOp->p2]==0 ); |
| 77044 | 77080 | pIn1 = &aMem[pOp->p1]; |
| 77045 | 77081 | while( (cAff = *(zAffinity++))!=0 ){ |
| 77046 | - assert( pIn1 <= &p->aMem[(p->nMem-p->nCursor)] ); | |
| 77082 | + assert( pIn1 <= &p->aMem[(p->nMem+1 - p->nCursor)] ); | |
| 77047 | 77083 | assert( memIsValid(pIn1) ); |
| 77048 | 77084 | applyAffinity(pIn1, cAff, encoding); |
| 77049 | 77085 | pIn1++; |
| 77050 | 77086 | } |
| 77051 | 77087 | break; |
| @@ -77103,11 +77139,11 @@ | ||
| 77103 | 77139 | nData = 0; /* Number of bytes of data space */ |
| 77104 | 77140 | nHdr = 0; /* Number of bytes of header space */ |
| 77105 | 77141 | nZero = 0; /* Number of zero bytes at the end of the record */ |
| 77106 | 77142 | nField = pOp->p1; |
| 77107 | 77143 | zAffinity = pOp->p4.z; |
| 77108 | - assert( nField>0 && pOp->p2>0 && pOp->p2+nField<=(p->nMem-p->nCursor)+1 ); | |
| 77144 | + assert( nField>0 && pOp->p2>0 && pOp->p2+nField<=(p->nMem+1 - p->nCursor)+1 ); | |
| 77109 | 77145 | pData0 = &aMem[nField]; |
| 77110 | 77146 | nField = pOp->p2; |
| 77111 | 77147 | pLast = &pData0[nField-1]; |
| 77112 | 77148 | file_format = p->minWriteFileFormat; |
| 77113 | 77149 | |
| @@ -77193,11 +77229,11 @@ | ||
| 77193 | 77229 | j += sqlite3VdbeSerialPut(&zNewRecord[j], pRec, serial_type); /* content */ |
| 77194 | 77230 | }while( (++pRec)<=pLast ); |
| 77195 | 77231 | assert( i==nHdr ); |
| 77196 | 77232 | assert( j==nByte ); |
| 77197 | 77233 | |
| 77198 | - assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) ); | |
| 77234 | + assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) ); | |
| 77199 | 77235 | pOut->n = (int)nByte; |
| 77200 | 77236 | pOut->flags = MEM_Blob; |
| 77201 | 77237 | if( nZero ){ |
| 77202 | 77238 | pOut->u.nZero = nZero; |
| 77203 | 77239 | pOut->flags |= MEM_Zero; |
| @@ -77779,11 +77815,11 @@ | ||
| 77779 | 77815 | }else{ |
| 77780 | 77816 | wrFlag = 0; |
| 77781 | 77817 | } |
| 77782 | 77818 | if( pOp->p5 & OPFLAG_P2ISREG ){ |
| 77783 | 77819 | assert( p2>0 ); |
| 77784 | - assert( p2<=(p->nMem-p->nCursor) ); | |
| 77820 | + assert( p2<=(p->nMem+1 - p->nCursor) ); | |
| 77785 | 77821 | pIn2 = &aMem[p2]; |
| 77786 | 77822 | assert( memIsValid(pIn2) ); |
| 77787 | 77823 | assert( (pIn2->flags & MEM_Int)!=0 ); |
| 77788 | 77824 | sqlite3VdbeMemIntegerify(pIn2); |
| 77789 | 77825 | p2 = (int)pIn2->u.i; |
| @@ -78574,11 +78610,11 @@ | ||
| 78574 | 78610 | /* Assert that P3 is a valid memory cell. */ |
| 78575 | 78611 | assert( pOp->p3<=pFrame->nMem ); |
| 78576 | 78612 | pMem = &pFrame->aMem[pOp->p3]; |
| 78577 | 78613 | }else{ |
| 78578 | 78614 | /* Assert that P3 is a valid memory cell. */ |
| 78579 | - assert( pOp->p3<=(p->nMem-p->nCursor) ); | |
| 78615 | + assert( pOp->p3<=(p->nMem+1 - p->nCursor) ); | |
| 78580 | 78616 | pMem = &aMem[pOp->p3]; |
| 78581 | 78617 | memAboutToChange(p, pMem); |
| 78582 | 78618 | } |
| 78583 | 78619 | assert( memIsValid(pMem) ); |
| 78584 | 78620 | |
| @@ -79350,11 +79386,11 @@ | ||
| 79350 | 79386 | BtCursor *pCrsr; |
| 79351 | 79387 | int res; |
| 79352 | 79388 | UnpackedRecord r; |
| 79353 | 79389 | |
| 79354 | 79390 | assert( pOp->p3>0 ); |
| 79355 | - assert( pOp->p2>0 && pOp->p2+pOp->p3<=(p->nMem-p->nCursor)+1 ); | |
| 79391 | + assert( pOp->p2>0 && pOp->p2+pOp->p3<=(p->nMem+1 - p->nCursor)+1 ); | |
| 79356 | 79392 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 79357 | 79393 | pC = p->apCsr[pOp->p1]; |
| 79358 | 79394 | assert( pC!=0 ); |
| 79359 | 79395 | assert( pC->eCurType==CURTYPE_BTREE ); |
| 79360 | 79396 | pCrsr = pC->uc.pCursor; |
| @@ -79856,11 +79892,11 @@ | ||
| 79856 | 79892 | assert( p->bIsReader ); |
| 79857 | 79893 | nRoot = pOp->p2; |
| 79858 | 79894 | aRoot = pOp->p4.ai; |
| 79859 | 79895 | assert( nRoot>0 ); |
| 79860 | 79896 | assert( aRoot[nRoot]==0 ); |
| 79861 | - assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) ); | |
| 79897 | + assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) ); | |
| 79862 | 79898 | pnErr = &aMem[pOp->p3]; |
| 79863 | 79899 | assert( (pnErr->flags & MEM_Int)!=0 ); |
| 79864 | 79900 | assert( (pnErr->flags & (MEM_Str|MEM_Blob))==0 ); |
| 79865 | 79901 | pIn1 = &aMem[pOp->p1]; |
| 79866 | 79902 | assert( pOp->p5<db->nDb ); |
| @@ -80046,10 +80082,12 @@ | ||
| 80046 | 80082 | ** program stored in SubProgram.aOp. As well as these, one memory |
| 80047 | 80083 | ** cell is required for each cursor used by the program. Set local |
| 80048 | 80084 | ** variable nMem (and later, VdbeFrame.nChildMem) to this value. |
| 80049 | 80085 | */ |
| 80050 | 80086 | nMem = pProgram->nMem + pProgram->nCsr; |
| 80087 | + assert( nMem>0 ); | |
| 80088 | + if( pProgram->nCsr==0 ) nMem++; | |
| 80051 | 80089 | nByte = ROUND8(sizeof(VdbeFrame)) |
| 80052 | 80090 | + nMem * sizeof(Mem) |
| 80053 | 80091 | + pProgram->nCsr * sizeof(VdbeCursor *) |
| 80054 | 80092 | + pProgram->nOnce * sizeof(u8); |
| 80055 | 80093 | pFrame = sqlite3DbMallocZero(db, nByte); |
| @@ -80082,11 +80120,12 @@ | ||
| 80082 | 80120 | pMem->flags = MEM_Undefined; |
| 80083 | 80121 | pMem->db = db; |
| 80084 | 80122 | } |
| 80085 | 80123 | }else{ |
| 80086 | 80124 | pFrame = pRt->u.pFrame; |
| 80087 | - assert( pProgram->nMem+pProgram->nCsr==pFrame->nChildMem ); | |
| 80125 | + assert( pProgram->nMem+pProgram->nCsr==pFrame->nChildMem | |
| 80126 | + || (pProgram->nCsr==0 && pProgram->nMem+1==pFrame->nChildMem) ); | |
| 80088 | 80127 | assert( pProgram->nCsr==pFrame->nChildCsr ); |
| 80089 | 80128 | assert( (int)(pOp - aOp)==pFrame->pc ); |
| 80090 | 80129 | } |
| 80091 | 80130 | |
| 80092 | 80131 | p->nFrame++; |
| @@ -80097,14 +80136,14 @@ | ||
| 80097 | 80136 | assert( pFrame->pAuxData==0 ); |
| 80098 | 80137 | pFrame->pAuxData = p->pAuxData; |
| 80099 | 80138 | p->pAuxData = 0; |
| 80100 | 80139 | p->nChange = 0; |
| 80101 | 80140 | p->pFrame = pFrame; |
| 80102 | - p->aMem = aMem = &VdbeFrameMem(pFrame)[-1]; | |
| 80141 | + p->aMem = aMem = VdbeFrameMem(pFrame); | |
| 80103 | 80142 | p->nMem = pFrame->nChildMem; |
| 80104 | 80143 | p->nCursor = (u16)pFrame->nChildCsr; |
| 80105 | - p->apCsr = (VdbeCursor **)&aMem[p->nMem+1]; | |
| 80144 | + p->apCsr = (VdbeCursor **)&aMem[p->nMem]; | |
| 80106 | 80145 | p->aOp = aOp = pProgram->aOp; |
| 80107 | 80146 | p->nOp = pProgram->nOp; |
| 80108 | 80147 | p->aOnceFlag = (u8 *)&p->apCsr[p->nCursor]; |
| 80109 | 80148 | p->nOnceFlag = pProgram->nOnce; |
| 80110 | 80149 | #ifdef SQLITE_ENABLE_STMT_SCANSTATUS |
| @@ -80346,12 +80385,12 @@ | ||
| 80346 | 80385 | int n; |
| 80347 | 80386 | sqlite3_context *pCtx; |
| 80348 | 80387 | |
| 80349 | 80388 | assert( pOp->p4type==P4_FUNCDEF ); |
| 80350 | 80389 | n = pOp->p5; |
| 80351 | - assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) ); | |
| 80352 | - assert( n==0 || (pOp->p2>0 && pOp->p2+n<=(p->nMem-p->nCursor)+1) ); | |
| 80390 | + assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) ); | |
| 80391 | + assert( n==0 || (pOp->p2>0 && pOp->p2+n<=(p->nMem+1 - p->nCursor)+1) ); | |
| 80353 | 80392 | assert( pOp->p3<pOp->p2 || pOp->p3>=pOp->p2+n ); |
| 80354 | 80393 | pCtx = sqlite3DbMallocRawNN(db, sizeof(*pCtx) + (n-1)*sizeof(sqlite3_value*)); |
| 80355 | 80394 | if( pCtx==0 ) goto no_mem; |
| 80356 | 80395 | pCtx->pMem = 0; |
| 80357 | 80396 | pCtx->pFunc = pOp->p4.pFunc; |
| @@ -80426,11 +80465,11 @@ | ||
| 80426 | 80465 | ** P4 argument is only needed for the degenerate case where |
| 80427 | 80466 | ** the step function was not previously called. |
| 80428 | 80467 | */ |
| 80429 | 80468 | case OP_AggFinal: { |
| 80430 | 80469 | Mem *pMem; |
| 80431 | - assert( pOp->p1>0 && pOp->p1<=(p->nMem-p->nCursor) ); | |
| 80470 | + assert( pOp->p1>0 && pOp->p1<=(p->nMem+1 - p->nCursor) ); | |
| 80432 | 80471 | pMem = &aMem[pOp->p1]; |
| 80433 | 80472 | assert( (pMem->flags & ~(MEM_Null|MEM_Agg))==0 ); |
| 80434 | 80473 | rc = sqlite3VdbeMemFinalize(pMem, pOp->p4.pFunc); |
| 80435 | 80474 | if( rc ){ |
| 80436 | 80475 | sqlite3VdbeError(p, "%s", sqlite3_value_text(pMem)); |
| @@ -80868,11 +80907,11 @@ | ||
| 80868 | 80907 | Mem *pDest; |
| 80869 | 80908 | sqlite3_context sContext; |
| 80870 | 80909 | |
| 80871 | 80910 | VdbeCursor *pCur = p->apCsr[pOp->p1]; |
| 80872 | 80911 | assert( pCur->eCurType==CURTYPE_VTAB ); |
| 80873 | - assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) ); | |
| 80912 | + assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) ); | |
| 80874 | 80913 | pDest = &aMem[pOp->p3]; |
| 80875 | 80914 | memAboutToChange(p, pDest); |
| 80876 | 80915 | if( pCur->nullRow ){ |
| 80877 | 80916 | sqlite3VdbeMemSetNull(pDest); |
| 80878 | 80917 | break; |
| @@ -81226,10 +81265,11 @@ | ||
| 81226 | 81265 | assert( rc ); |
| 81227 | 81266 | if( p->zErrMsg==0 && rc!=SQLITE_IOERR_NOMEM ){ |
| 81228 | 81267 | sqlite3VdbeError(p, "%s", sqlite3ErrStr(rc)); |
| 81229 | 81268 | } |
| 81230 | 81269 | p->rc = rc; |
| 81270 | + sqlite3SystemError(db, rc); | |
| 81231 | 81271 | testcase( sqlite3GlobalConfig.xLog!=0 ); |
| 81232 | 81272 | sqlite3_log(rc, "statement aborts at %d: [%s] %s", |
| 81233 | 81273 | (int)(pOp - aOp), p->zSql, p->zErrMsg); |
| 81234 | 81274 | sqlite3VdbeHalt(p); |
| 81235 | 81275 | if( rc==SQLITE_IOERR_NOMEM ) sqlite3OomFault(db); |
| @@ -106052,10 +106092,12 @@ | ||
| 106052 | 106092 | void (*result_subtype)(sqlite3_context*,unsigned int); |
| 106053 | 106093 | /* Version 3.10.0 and later */ |
| 106054 | 106094 | int (*status64)(int,sqlite3_int64*,sqlite3_int64*,int); |
| 106055 | 106095 | int (*strlike)(const char*,const char*,unsigned int); |
| 106056 | 106096 | int (*db_cacheflush)(sqlite3*); |
| 106097 | + /* Version 3.12.0 and later */ | |
| 106098 | + int (*system_errno)(sqlite3*); | |
| 106057 | 106099 | }; |
| 106058 | 106100 | |
| 106059 | 106101 | /* |
| 106060 | 106102 | ** The following macros redefine the API routines so that they are |
| 106061 | 106103 | ** redirected through the global sqlite3_api structure. |
| @@ -106295,10 +106337,12 @@ | ||
| 106295 | 106337 | #define sqlite3_result_subtype sqlite3_api->result_subtype |
| 106296 | 106338 | /* Version 3.10.0 and later */ |
| 106297 | 106339 | #define sqlite3_status64 sqlite3_api->status64 |
| 106298 | 106340 | #define sqlite3_strlike sqlite3_api->strlike |
| 106299 | 106341 | #define sqlite3_db_cacheflush sqlite3_api->db_cacheflush |
| 106342 | +/* Version 3.12.0 and later */ | |
| 106343 | +#define sqlite3_system_errno sqlite3_api->system_errno | |
| 106300 | 106344 | #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */ |
| 106301 | 106345 | |
| 106302 | 106346 | #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) |
| 106303 | 106347 | /* This case when the file really is being compiled as a loadable |
| 106304 | 106348 | ** extension */ |
| @@ -106713,11 +106757,13 @@ | ||
| 106713 | 106757 | sqlite3_value_subtype, |
| 106714 | 106758 | sqlite3_result_subtype, |
| 106715 | 106759 | /* Version 3.10.0 and later */ |
| 106716 | 106760 | sqlite3_status64, |
| 106717 | 106761 | sqlite3_strlike, |
| 106718 | - sqlite3_db_cacheflush | |
| 106762 | + sqlite3_db_cacheflush, | |
| 106763 | + /* Version 3.12.0 and later */ | |
| 106764 | + sqlite3_system_errno | |
| 106719 | 106765 | }; |
| 106720 | 106766 | |
| 106721 | 106767 | /* |
| 106722 | 106768 | ** Attempt to load an SQLite extension library contained in the file |
| 106723 | 106769 | ** zFile. The entry point is zProc. zProc may be 0 in which case a |
| @@ -135359,10 +135405,13 @@ | ||
| 135359 | 135405 | if( !db || db->mallocFailed ){ |
| 135360 | 135406 | return SQLITE_NOMEM_BKPT; |
| 135361 | 135407 | } |
| 135362 | 135408 | return db->errCode; |
| 135363 | 135409 | } |
| 135410 | +SQLITE_API int SQLITE_STDCALL sqlite3_system_errno(sqlite3 *db){ | |
| 135411 | + return db ? db->iSysErrno : 0; | |
| 135412 | +} | |
| 135364 | 135413 | |
| 135365 | 135414 | /* |
| 135366 | 135415 | ** Return a string that describes the kind of error specified in the |
| 135367 | 135416 | ** argument. For now, this simply calls the internal sqlite3ErrStr() |
| 135368 | 135417 | ** function. |
| @@ -161345,10 +161394,52 @@ | ||
| 161345 | 161394 | ** updates) that have been performed on the target database since the |
| 161346 | 161395 | ** current RBU update was started. |
| 161347 | 161396 | */ |
| 161348 | 161397 | SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3rbu_progress(sqlite3rbu *pRbu); |
| 161349 | 161398 | |
| 161399 | +/* | |
| 161400 | +** Obtain permyriadage (permyriadage is to 10000 as percentage is to 100) | |
| 161401 | +** progress indications for the two stages of an RBU update. This API may | |
| 161402 | +** be useful for driving GUI progress indicators and similar. | |
| 161403 | +** | |
| 161404 | +** An RBU update is divided into two stages: | |
| 161405 | +** | |
| 161406 | +** * Stage 1, in which changes are accumulated in an oal/wal file, and | |
| 161407 | +** * Stage 2, in which the contents of the wal file are copied into the | |
| 161408 | +** main database. | |
| 161409 | +** | |
| 161410 | +** The update is visible to non-RBU clients during stage 2. During stage 1 | |
| 161411 | +** non-RBU reader clients may see the original database. | |
| 161412 | +** | |
| 161413 | +** If this API is called during stage 2 of the update, output variable | |
| 161414 | +** (*pnOne) is set to 10000 to indicate that stage 1 has finished and (*pnTwo) | |
| 161415 | +** to a value between 0 and 10000 to indicate the permyriadage progress of | |
| 161416 | +** stage 2. A value of 5000 indicates that stage 2 is half finished, | |
| 161417 | +** 9000 indicates that it is 90% finished, and so on. | |
| 161418 | +** | |
| 161419 | +** If this API is called during stage 1 of the update, output variable | |
| 161420 | +** (*pnTwo) is set to 0 to indicate that stage 2 has not yet started. The | |
| 161421 | +** value to which (*pnOne) is set depends on whether or not the RBU | |
| 161422 | +** database contains an "rbu_count" table. The rbu_count table, if it | |
| 161423 | +** exists, must contain the same columns as the following: | |
| 161424 | +** | |
| 161425 | +** CREATE TABLE rbu_count(tbl TEXT PRIMARY KEY, cnt INTEGER) WITHOUT ROWID; | |
| 161426 | +** | |
| 161427 | +** There must be one row in the table for each source (data_xxx) table within | |
| 161428 | +** the RBU database. The 'tbl' column should contain the name of the source | |
| 161429 | +** table. The 'cnt' column should contain the number of rows within the | |
| 161430 | +** source table. | |
| 161431 | +** | |
| 161432 | +** If the rbu_count table is present and populated correctly and this | |
| 161433 | +** API is called during stage 1, the *pnOne output variable is set to the | |
| 161434 | +** permyriadage progress of the same stage. If the rbu_count table does | |
| 161435 | +** not exist, then (*pnOne) is set to -1 during stage 1. If the rbu_count | |
| 161436 | +** table exists but is not correctly populated, the value of the *pnOne | |
| 161437 | +** output variable during stage 1 is undefined. | |
| 161438 | +*/ | |
| 161439 | +SQLITE_API void SQLITE_STDCALL sqlite3rbu_bp_progress(sqlite3rbu *pRbu, int *pnOne, int *pnTwo); | |
| 161440 | + | |
| 161350 | 161441 | /* |
| 161351 | 161442 | ** Create an RBU VFS named zName that accesses the underlying file-system |
| 161352 | 161443 | ** via existing VFS zParent. Or, if the zParent parameter is passed NULL, |
| 161353 | 161444 | ** then the new RBU VFS uses the default system VFS to access the file-system. |
| 161354 | 161445 | ** The new object is registered as a non-default VFS with SQLite before |
| @@ -161466,18 +161557,19 @@ | ||
| 161466 | 161557 | ** target db file. |
| 161467 | 161558 | ** |
| 161468 | 161559 | ** RBU_STATE_OALSZ: |
| 161469 | 161560 | ** Valid if STAGE==1. The size in bytes of the *-oal file. |
| 161470 | 161561 | */ |
| 161471 | -#define RBU_STATE_STAGE 1 | |
| 161472 | -#define RBU_STATE_TBL 2 | |
| 161473 | -#define RBU_STATE_IDX 3 | |
| 161474 | -#define RBU_STATE_ROW 4 | |
| 161475 | -#define RBU_STATE_PROGRESS 5 | |
| 161476 | -#define RBU_STATE_CKPT 6 | |
| 161477 | -#define RBU_STATE_COOKIE 7 | |
| 161478 | -#define RBU_STATE_OALSZ 8 | |
| 161562 | +#define RBU_STATE_STAGE 1 | |
| 161563 | +#define RBU_STATE_TBL 2 | |
| 161564 | +#define RBU_STATE_IDX 3 | |
| 161565 | +#define RBU_STATE_ROW 4 | |
| 161566 | +#define RBU_STATE_PROGRESS 5 | |
| 161567 | +#define RBU_STATE_CKPT 6 | |
| 161568 | +#define RBU_STATE_COOKIE 7 | |
| 161569 | +#define RBU_STATE_OALSZ 8 | |
| 161570 | +#define RBU_STATE_PHASEONESTEP 9 | |
| 161479 | 161571 | |
| 161480 | 161572 | #define RBU_STAGE_OAL 1 |
| 161481 | 161573 | #define RBU_STAGE_MOVE 2 |
| 161482 | 161574 | #define RBU_STAGE_CAPTURE 3 |
| 161483 | 161575 | #define RBU_STAGE_CKPT 4 |
| @@ -161519,10 +161611,11 @@ | ||
| 161519 | 161611 | i64 iWalCksum; |
| 161520 | 161612 | int nRow; |
| 161521 | 161613 | i64 nProgress; |
| 161522 | 161614 | u32 iCookie; |
| 161523 | 161615 | i64 iOalSz; |
| 161616 | + i64 nPhaseOneStep; | |
| 161524 | 161617 | }; |
| 161525 | 161618 | |
| 161526 | 161619 | struct RbuUpdateStmt { |
| 161527 | 161620 | char *zMask; /* Copy of update mask used with pUpdate */ |
| 161528 | 161621 | sqlite3_stmt *pUpdate; /* Last update statement (or NULL) */ |
| @@ -161563,10 +161656,11 @@ | ||
| 161563 | 161656 | const char *zDataTbl; /* Name of rbu db table (or null) */ |
| 161564 | 161657 | const char *zIdx; /* Name of target db index (or null) */ |
| 161565 | 161658 | int iTnum; /* Root page of current object */ |
| 161566 | 161659 | int iPkTnum; /* If eType==EXTERNAL, root of PK index */ |
| 161567 | 161660 | int bUnique; /* Current index is unique */ |
| 161661 | + int nIndex; /* Number of aux. indexes on table zTbl */ | |
| 161568 | 161662 | |
| 161569 | 161663 | /* Statements created by rbuObjIterPrepareAll() */ |
| 161570 | 161664 | int nCol; /* Number of columns in current object */ |
| 161571 | 161665 | sqlite3_stmt *pSelect; /* Source data */ |
| 161572 | 161666 | sqlite3_stmt *pInsert; /* Statement for INSERT operations */ |
| @@ -161616,10 +161710,47 @@ | ||
| 161616 | 161710 | u32 iWalFrame; |
| 161617 | 161711 | }; |
| 161618 | 161712 | |
| 161619 | 161713 | /* |
| 161620 | 161714 | ** RBU handle. |
| 161715 | +** | |
| 161716 | +** nPhaseOneStep: | |
| 161717 | +** If the RBU database contains an rbu_count table, this value is set to | |
| 161718 | +** a running estimate of the number of b-tree operations required to | |
| 161719 | +** finish populating the *-oal file. This allows the sqlite3_bp_progress() | |
| 161720 | +** API to calculate the permyriadage progress of populating the *-oal file | |
| 161721 | +** using the formula: | |
| 161722 | +** | |
| 161723 | +** permyriadage = (10000 * nProgress) / nPhaseOneStep | |
| 161724 | +** | |
| 161725 | +** nPhaseOneStep is initialized to the sum of: | |
| 161726 | +** | |
| 161727 | +** nRow * (nIndex + 1) | |
| 161728 | +** | |
| 161729 | +** for all source tables in the RBU database, where nRow is the number | |
| 161730 | +** of rows in the source table and nIndex the number of indexes on the | |
| 161731 | +** corresponding target database table. | |
| 161732 | +** | |
| 161733 | +** This estimate is accurate if the RBU update consists entirely of | |
| 161734 | +** INSERT operations. However, it is inaccurate if: | |
| 161735 | +** | |
| 161736 | +** * the RBU update contains any UPDATE operations. If the PK specified | |
| 161737 | +** for an UPDATE operation does not exist in the target table, then | |
| 161738 | +** no b-tree operations are required on index b-trees. Or if the | |
| 161739 | +** specified PK does exist, then (nIndex*2) such operations are | |
| 161740 | +** required (one delete and one insert on each index b-tree). | |
| 161741 | +** | |
| 161742 | +** * the RBU update contains any DELETE operations for which the specified | |
| 161743 | +** PK does not exist. In this case no operations are required on index | |
| 161744 | +** b-trees. | |
| 161745 | +** | |
| 161746 | +** * the RBU update contains REPLACE operations. These are similar to | |
| 161747 | +** UPDATE operations. | |
| 161748 | +** | |
| 161749 | +** nPhaseOneStep is updated to account for the conditions above during the | |
| 161750 | +** first pass of each source table. The updated nPhaseOneStep value is | |
| 161751 | +** stored in the rbu_state table if the RBU update is suspended. | |
| 161621 | 161752 | */ |
| 161622 | 161753 | struct sqlite3rbu { |
| 161623 | 161754 | int eStage; /* Value of RBU_STATE_STAGE field */ |
| 161624 | 161755 | sqlite3 *dbMain; /* target database handle */ |
| 161625 | 161756 | sqlite3 *dbRbu; /* rbu database handle */ |
| @@ -161633,10 +161764,11 @@ | ||
| 161633 | 161764 | int nProgress; /* Rows processed for all objects */ |
| 161634 | 161765 | RbuObjIter objiter; /* Iterator for skipping through tbl/idx */ |
| 161635 | 161766 | const char *zVfsName; /* Name of automatically created rbu vfs */ |
| 161636 | 161767 | rbu_file *pTargetFd; /* File handle open on target db */ |
| 161637 | 161768 | i64 iOalSz; |
| 161769 | + i64 nPhaseOneStep; | |
| 161638 | 161770 | |
| 161639 | 161771 | /* The following state variables are used as part of the incremental |
| 161640 | 161772 | ** checkpoint stage (eStage==RBU_STAGE_CKPT). See comments surrounding |
| 161641 | 161773 | ** function rbuSetupCheckpoint() for details. */ |
| 161642 | 161774 | u32 iMaxFrame; /* Largest iWalFrame value in aFrame[] */ |
| @@ -162463,10 +162595,11 @@ | ||
| 162463 | 162595 | p->rc = prepareFreeAndCollectError(p->dbMain, &pList, &p->zErrmsg, |
| 162464 | 162596 | sqlite3_mprintf("PRAGMA main.index_list = %Q", pIter->zTbl) |
| 162465 | 162597 | ); |
| 162466 | 162598 | } |
| 162467 | 162599 | |
| 162600 | + pIter->nIndex = 0; | |
| 162468 | 162601 | while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pList) ){ |
| 162469 | 162602 | const char *zIdx = (const char*)sqlite3_column_text(pList, 1); |
| 162470 | 162603 | sqlite3_stmt *pXInfo = 0; |
| 162471 | 162604 | if( zIdx==0 ) break; |
| 162472 | 162605 | p->rc = prepareFreeAndCollectError(p->dbMain, &pXInfo, &p->zErrmsg, |
| @@ -162476,10 +162609,16 @@ | ||
| 162476 | 162609 | int iCid = sqlite3_column_int(pXInfo, 1); |
| 162477 | 162610 | if( iCid>=0 ) pIter->abIndexed[iCid] = 1; |
| 162478 | 162611 | } |
| 162479 | 162612 | rbuFinalize(p, pXInfo); |
| 162480 | 162613 | bIndex = 1; |
| 162614 | + pIter->nIndex++; | |
| 162615 | + } | |
| 162616 | + | |
| 162617 | + if( pIter->eType==RBU_PK_WITHOUT_ROWID ){ | |
| 162618 | + /* "PRAGMA index_list" includes the main PK b-tree */ | |
| 162619 | + pIter->nIndex--; | |
| 162481 | 162620 | } |
| 162482 | 162621 | |
| 162483 | 162622 | rbuFinalize(p, pList); |
| 162484 | 162623 | if( bIndex==0 ) pIter->abIndexed = 0; |
| 162485 | 162624 | } |
| @@ -162589,10 +162728,11 @@ | ||
| 162589 | 162728 | } |
| 162590 | 162729 | |
| 162591 | 162730 | rbuFinalize(p, pStmt); |
| 162592 | 162731 | rbuObjIterCacheIndexedCols(p, pIter); |
| 162593 | 162732 | assert( pIter->eType!=RBU_PK_VTAB || pIter->abIndexed==0 ); |
| 162733 | + assert( pIter->eType!=RBU_PK_VTAB || pIter->nIndex==0 ); | |
| 162594 | 162734 | } |
| 162595 | 162735 | |
| 162596 | 162736 | return p->rc; |
| 162597 | 162737 | } |
| 162598 | 162738 | |
| @@ -163141,10 +163281,18 @@ | ||
| 163141 | 163281 | sqlite3_value **apVal |
| 163142 | 163282 | ){ |
| 163143 | 163283 | sqlite3rbu *p = sqlite3_user_data(pCtx); |
| 163144 | 163284 | int rc = SQLITE_OK; |
| 163145 | 163285 | int i; |
| 163286 | + | |
| 163287 | + assert( sqlite3_value_int(apVal[0])!=0 | |
| 163288 | + || p->objiter.eType==RBU_PK_EXTERNAL | |
| 163289 | + || p->objiter.eType==RBU_PK_NONE | |
| 163290 | + ); | |
| 163291 | + if( sqlite3_value_int(apVal[0])!=0 ){ | |
| 163292 | + p->nPhaseOneStep += p->objiter.nIndex; | |
| 163293 | + } | |
| 163146 | 163294 | |
| 163147 | 163295 | for(i=0; rc==SQLITE_OK && i<nVal; i++){ |
| 163148 | 163296 | rc = sqlite3_bind_value(p->objiter.pTmpInsert, i+1, apVal[i]); |
| 163149 | 163297 | } |
| 163150 | 163298 | if( rc==SQLITE_OK ){ |
| @@ -163886,10 +164034,21 @@ | ||
| 163886 | 164034 | sqlite3_stmt *pWriter; |
| 163887 | 164035 | int i; |
| 163888 | 164036 | |
| 163889 | 164037 | assert( p->rc==SQLITE_OK ); |
| 163890 | 164038 | assert( eType!=RBU_DELETE || pIter->zIdx==0 ); |
| 164039 | + assert( eType==RBU_DELETE || eType==RBU_IDX_DELETE | |
| 164040 | + || eType==RBU_INSERT || eType==RBU_IDX_INSERT | |
| 164041 | + ); | |
| 164042 | + | |
| 164043 | + /* If this is a delete, decrement nPhaseOneStep by nIndex. If the DELETE | |
| 164044 | + ** statement below does actually delete a row, nPhaseOneStep will be | |
| 164045 | + ** incremented by the same amount when SQL function rbu_tmp_insert() | |
| 164046 | + ** is invoked by the trigger. */ | |
| 164047 | + if( eType==RBU_DELETE ){ | |
| 164048 | + p->nPhaseOneStep -= p->objiter.nIndex; | |
| 164049 | + } | |
| 163891 | 164050 | |
| 163892 | 164051 | if( eType==RBU_IDX_DELETE || eType==RBU_DELETE ){ |
| 163893 | 164052 | pWriter = pIter->pDelete; |
| 163894 | 164053 | }else{ |
| 163895 | 164054 | pWriter = pIter->pInsert; |
| @@ -163957,24 +164116,28 @@ | ||
| 163957 | 164116 | || eType==RBU_REPLACE || eType==RBU_IDX_DELETE |
| 163958 | 164117 | || eType==RBU_IDX_INSERT || eType==RBU_UPDATE |
| 163959 | 164118 | ); |
| 163960 | 164119 | assert( eType!=RBU_UPDATE || pIter->zIdx==0 ); |
| 163961 | 164120 | |
| 163962 | - if( pIter->zIdx==0 && eType==RBU_IDX_DELETE ){ | |
| 164121 | + if( pIter->zIdx==0 && (eType==RBU_IDX_DELETE || eType==RBU_IDX_INSERT) ){ | |
| 163963 | 164122 | rbuBadControlError(p); |
| 163964 | 164123 | } |
| 163965 | 164124 | else if( eType==RBU_REPLACE ){ |
| 163966 | - if( pIter->zIdx==0 ) rbuStepOneOp(p, RBU_DELETE); | |
| 164125 | + if( pIter->zIdx==0 ){ | |
| 164126 | + p->nPhaseOneStep += p->objiter.nIndex; | |
| 164127 | + rbuStepOneOp(p, RBU_DELETE); | |
| 164128 | + } | |
| 163967 | 164129 | if( p->rc==SQLITE_OK ) rbuStepOneOp(p, RBU_INSERT); |
| 163968 | 164130 | } |
| 163969 | 164131 | else if( eType!=RBU_UPDATE ){ |
| 163970 | 164132 | rbuStepOneOp(p, eType); |
| 163971 | 164133 | } |
| 163972 | 164134 | else{ |
| 163973 | 164135 | sqlite3_value *pVal; |
| 163974 | 164136 | sqlite3_stmt *pUpdate = 0; |
| 163975 | 164137 | assert( eType==RBU_UPDATE ); |
| 164138 | + p->nPhaseOneStep -= p->objiter.nIndex; | |
| 163976 | 164139 | rbuGetUpdateStmt(p, pIter, zMask, &pUpdate); |
| 163977 | 164140 | if( pUpdate ){ |
| 163978 | 164141 | int i; |
| 163979 | 164142 | for(i=0; p->rc==SQLITE_OK && i<pIter->nCol; i++){ |
| 163980 | 164143 | char c = zMask[pIter->aiSrcOrder[i]]; |
| @@ -164048,20 +164211,22 @@ | ||
| 164048 | 164211 | "(%d, %Q), " |
| 164049 | 164212 | "(%d, %d), " |
| 164050 | 164213 | "(%d, %d), " |
| 164051 | 164214 | "(%d, %lld), " |
| 164052 | 164215 | "(%d, %lld), " |
| 164216 | + "(%d, %lld), " | |
| 164053 | 164217 | "(%d, %lld) ", |
| 164054 | 164218 | p->zStateDb, |
| 164055 | 164219 | RBU_STATE_STAGE, eStage, |
| 164056 | 164220 | RBU_STATE_TBL, p->objiter.zTbl, |
| 164057 | 164221 | RBU_STATE_IDX, p->objiter.zIdx, |
| 164058 | 164222 | RBU_STATE_ROW, p->nStep, |
| 164059 | 164223 | RBU_STATE_PROGRESS, p->nProgress, |
| 164060 | 164224 | RBU_STATE_CKPT, p->iWalCksum, |
| 164061 | 164225 | RBU_STATE_COOKIE, (i64)p->pTargetFd->iCookie, |
| 164062 | - RBU_STATE_OALSZ, p->iOalSz | |
| 164226 | + RBU_STATE_OALSZ, p->iOalSz, | |
| 164227 | + RBU_STATE_PHASEONESTEP, p->nPhaseOneStep | |
| 164063 | 164228 | ) |
| 164064 | 164229 | ); |
| 164065 | 164230 | assert( pInsert==0 || rc==SQLITE_OK ); |
| 164066 | 164231 | |
| 164067 | 164232 | if( rc==SQLITE_OK ){ |
| @@ -164244,10 +164409,14 @@ | ||
| 164244 | 164409 | |
| 164245 | 164410 | case RBU_STATE_OALSZ: |
| 164246 | 164411 | pRet->iOalSz = (u32)sqlite3_column_int64(pStmt, 1); |
| 164247 | 164412 | break; |
| 164248 | 164413 | |
| 164414 | + case RBU_STATE_PHASEONESTEP: | |
| 164415 | + pRet->nPhaseOneStep = sqlite3_column_int64(pStmt, 1); | |
| 164416 | + break; | |
| 164417 | + | |
| 164249 | 164418 | default: |
| 164250 | 164419 | rc = SQLITE_CORRUPT; |
| 164251 | 164420 | break; |
| 164252 | 164421 | } |
| 164253 | 164422 | } |
| @@ -164350,10 +164519,104 @@ | ||
| 164350 | 164519 | if( p->zVfsName ){ |
| 164351 | 164520 | sqlite3rbu_destroy_vfs(p->zVfsName); |
| 164352 | 164521 | p->zVfsName = 0; |
| 164353 | 164522 | } |
| 164354 | 164523 | } |
| 164524 | + | |
| 164525 | +/* | |
| 164526 | +** This user-defined SQL function is invoked with a single argument - the | |
| 164527 | +** name of a table expected to appear in the target database. It returns | |
| 164528 | +** the number of auxilliary indexes on the table. | |
| 164529 | +*/ | |
| 164530 | +static void rbuIndexCntFunc( | |
| 164531 | + sqlite3_context *pCtx, | |
| 164532 | + int nVal, | |
| 164533 | + sqlite3_value **apVal | |
| 164534 | +){ | |
| 164535 | + sqlite3rbu *p = (sqlite3rbu*)sqlite3_user_data(pCtx); | |
| 164536 | + sqlite3_stmt *pStmt = 0; | |
| 164537 | + char *zErrmsg = 0; | |
| 164538 | + int rc; | |
| 164539 | + | |
| 164540 | + assert( nVal==1 ); | |
| 164541 | + | |
| 164542 | + rc = prepareFreeAndCollectError(p->dbMain, &pStmt, &zErrmsg, | |
| 164543 | + sqlite3_mprintf("SELECT count(*) FROM sqlite_master " | |
| 164544 | + "WHERE type='index' AND tbl_name = %Q", sqlite3_value_text(apVal[0])) | |
| 164545 | + ); | |
| 164546 | + if( rc!=SQLITE_OK ){ | |
| 164547 | + sqlite3_result_error(pCtx, zErrmsg, -1); | |
| 164548 | + }else{ | |
| 164549 | + int nIndex = 0; | |
| 164550 | + if( SQLITE_ROW==sqlite3_step(pStmt) ){ | |
| 164551 | + nIndex = sqlite3_column_int(pStmt, 0); | |
| 164552 | + } | |
| 164553 | + rc = sqlite3_finalize(pStmt); | |
| 164554 | + if( rc==SQLITE_OK ){ | |
| 164555 | + sqlite3_result_int(pCtx, nIndex); | |
| 164556 | + }else{ | |
| 164557 | + sqlite3_result_error(pCtx, sqlite3_errmsg(p->dbMain), -1); | |
| 164558 | + } | |
| 164559 | + } | |
| 164560 | + | |
| 164561 | + sqlite3_free(zErrmsg); | |
| 164562 | +} | |
| 164563 | + | |
| 164564 | +/* | |
| 164565 | +** If the RBU database contains the rbu_count table, use it to initialize | |
| 164566 | +** the sqlite3rbu.nPhaseOneStep variable. The schema of the rbu_count table | |
| 164567 | +** is assumed to contain the same columns as: | |
| 164568 | +** | |
| 164569 | +** CREATE TABLE rbu_count(tbl TEXT PRIMARY KEY, cnt INTEGER) WITHOUT ROWID; | |
| 164570 | +** | |
| 164571 | +** There should be one row in the table for each data_xxx table in the | |
| 164572 | +** database. The 'tbl' column should contain the name of a data_xxx table, | |
| 164573 | +** and the cnt column the number of rows it contains. | |
| 164574 | +** | |
| 164575 | +** sqlite3rbu.nPhaseOneStep is initialized to the sum of (1 + nIndex) * cnt | |
| 164576 | +** for all rows in the rbu_count table, where nIndex is the number of | |
| 164577 | +** indexes on the corresponding target database table. | |
| 164578 | +*/ | |
| 164579 | +static void rbuInitPhaseOneSteps(sqlite3rbu *p){ | |
| 164580 | + if( p->rc==SQLITE_OK ){ | |
| 164581 | + sqlite3_stmt *pStmt = 0; | |
| 164582 | + int bExists = 0; /* True if rbu_count exists */ | |
| 164583 | + | |
| 164584 | + p->nPhaseOneStep = -1; | |
| 164585 | + | |
| 164586 | + p->rc = sqlite3_create_function(p->dbRbu, | |
| 164587 | + "rbu_index_cnt", 1, SQLITE_UTF8, (void*)p, rbuIndexCntFunc, 0, 0 | |
| 164588 | + ); | |
| 164589 | + | |
| 164590 | + /* Check for the rbu_count table. If it does not exist, or if an error | |
| 164591 | + ** occurs, nPhaseOneStep will be left set to -1. */ | |
| 164592 | + if( p->rc==SQLITE_OK ){ | |
| 164593 | + p->rc = prepareAndCollectError(p->dbRbu, &pStmt, &p->zErrmsg, | |
| 164594 | + "SELECT 1 FROM sqlite_master WHERE tbl_name = 'rbu_count'" | |
| 164595 | + ); | |
| 164596 | + } | |
| 164597 | + if( p->rc==SQLITE_OK ){ | |
| 164598 | + if( SQLITE_ROW==sqlite3_step(pStmt) ){ | |
| 164599 | + bExists = 1; | |
| 164600 | + } | |
| 164601 | + p->rc = sqlite3_finalize(pStmt); | |
| 164602 | + } | |
| 164603 | + | |
| 164604 | + if( p->rc==SQLITE_OK && bExists ){ | |
| 164605 | + p->rc = prepareAndCollectError(p->dbRbu, &pStmt, &p->zErrmsg, | |
| 164606 | + "SELECT sum(cnt * (1 + rbu_index_cnt(rbu_target_name(tbl))))" | |
| 164607 | + "FROM rbu_count" | |
| 164608 | + ); | |
| 164609 | + if( p->rc==SQLITE_OK ){ | |
| 164610 | + if( SQLITE_ROW==sqlite3_step(pStmt) ){ | |
| 164611 | + p->nPhaseOneStep = sqlite3_column_int64(pStmt, 0); | |
| 164612 | + } | |
| 164613 | + p->rc = sqlite3_finalize(pStmt); | |
| 164614 | + } | |
| 164615 | + } | |
| 164616 | + } | |
| 164617 | +} | |
| 164355 | 164618 | |
| 164356 | 164619 | /* |
| 164357 | 164620 | ** Open and return a new RBU handle. |
| 164358 | 164621 | */ |
| 164359 | 164622 | SQLITE_API sqlite3rbu *SQLITE_STDCALL sqlite3rbu_open( |
| @@ -164396,13 +164659,15 @@ | ||
| 164396 | 164659 | assert( pState || p->rc!=SQLITE_OK ); |
| 164397 | 164660 | if( p->rc==SQLITE_OK ){ |
| 164398 | 164661 | |
| 164399 | 164662 | if( pState->eStage==0 ){ |
| 164400 | 164663 | rbuDeleteOalFile(p); |
| 164664 | + rbuInitPhaseOneSteps(p); | |
| 164401 | 164665 | p->eStage = RBU_STAGE_OAL; |
| 164402 | 164666 | }else{ |
| 164403 | 164667 | p->eStage = pState->eStage; |
| 164668 | + p->nPhaseOneStep = pState->nPhaseOneStep; | |
| 164404 | 164669 | } |
| 164405 | 164670 | p->nProgress = pState->nProgress; |
| 164406 | 164671 | p->iOalSz = pState->iOalSz; |
| 164407 | 164672 | } |
| 164408 | 164673 | } |
| @@ -164561,10 +164826,46 @@ | ||
| 164561 | 164826 | ** current RBU update was started. |
| 164562 | 164827 | */ |
| 164563 | 164828 | SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3rbu_progress(sqlite3rbu *pRbu){ |
| 164564 | 164829 | return pRbu->nProgress; |
| 164565 | 164830 | } |
| 164831 | + | |
| 164832 | +/* | |
| 164833 | +** Return permyriadage progress indications for the two main stages of | |
| 164834 | +** an RBU update. | |
| 164835 | +*/ | |
| 164836 | +SQLITE_API void SQLITE_STDCALL sqlite3rbu_bp_progress(sqlite3rbu *p, int *pnOne, int *pnTwo){ | |
| 164837 | + const int MAX_PROGRESS = 10000; | |
| 164838 | + switch( p->eStage ){ | |
| 164839 | + case RBU_STAGE_OAL: | |
| 164840 | + if( p->nPhaseOneStep>0 ){ | |
| 164841 | + *pnOne = (int)(MAX_PROGRESS * (i64)p->nProgress/(i64)p->nPhaseOneStep); | |
| 164842 | + }else{ | |
| 164843 | + *pnOne = -1; | |
| 164844 | + } | |
| 164845 | + *pnTwo = 0; | |
| 164846 | + break; | |
| 164847 | + | |
| 164848 | + case RBU_STAGE_MOVE: | |
| 164849 | + *pnOne = MAX_PROGRESS; | |
| 164850 | + *pnTwo = 0; | |
| 164851 | + break; | |
| 164852 | + | |
| 164853 | + case RBU_STAGE_CKPT: | |
| 164854 | + *pnOne = MAX_PROGRESS; | |
| 164855 | + *pnTwo = (int)(MAX_PROGRESS * (i64)p->nStep / (i64)p->nFrame); | |
| 164856 | + break; | |
| 164857 | + | |
| 164858 | + case RBU_STAGE_DONE: | |
| 164859 | + *pnOne = MAX_PROGRESS; | |
| 164860 | + *pnTwo = MAX_PROGRESS; | |
| 164861 | + break; | |
| 164862 | + | |
| 164863 | + default: | |
| 164864 | + assert( 0 ); | |
| 164865 | + } | |
| 164866 | +} | |
| 164566 | 164867 | |
| 164567 | 164868 | SQLITE_API int SQLITE_STDCALL sqlite3rbu_savestate(sqlite3rbu *p){ |
| 164568 | 164869 | int rc = p->rc; |
| 164569 | 164870 | |
| 164570 | 164871 | if( rc==SQLITE_DONE ) return SQLITE_OK; |
| @@ -169364,10 +169665,11 @@ | ||
| 169364 | 169665 | static int sqlite3Fts5IndexReads(Fts5Index *p); |
| 169365 | 169666 | |
| 169366 | 169667 | static int sqlite3Fts5IndexReinit(Fts5Index *p); |
| 169367 | 169668 | static int sqlite3Fts5IndexOptimize(Fts5Index *p); |
| 169368 | 169669 | static int sqlite3Fts5IndexMerge(Fts5Index *p, int nMerge); |
| 169670 | +static int sqlite3Fts5IndexReset(Fts5Index *p); | |
| 169369 | 169671 | |
| 169370 | 169672 | static int sqlite3Fts5IndexLoadConfig(Fts5Index *p); |
| 169371 | 169673 | |
| 169372 | 169674 | /* |
| 169373 | 169675 | ** End of interface to code in fts5_index.c. |
| @@ -169506,10 +169808,11 @@ | ||
| 169506 | 169808 | |
| 169507 | 169809 | static int sqlite3Fts5StorageDeleteAll(Fts5Storage *p); |
| 169508 | 169810 | static int sqlite3Fts5StorageRebuild(Fts5Storage *p); |
| 169509 | 169811 | static int sqlite3Fts5StorageOptimize(Fts5Storage *p); |
| 169510 | 169812 | static int sqlite3Fts5StorageMerge(Fts5Storage *p, int nMerge); |
| 169813 | +static int sqlite3Fts5StorageReset(Fts5Storage *p); | |
| 169511 | 169814 | |
| 169512 | 169815 | /* |
| 169513 | 169816 | ** End of interface to code in fts5_storage.c. |
| 169514 | 169817 | **************************************************************************/ |
| 169515 | 169818 | |
| @@ -176314,10 +176617,14 @@ | ||
| 176314 | 176617 | sqlite3_stmt *pDeleter; /* "DELETE FROM %_data ... id>=? AND id<=?" */ |
| 176315 | 176618 | sqlite3_stmt *pIdxWriter; /* "INSERT ... %_idx VALUES(?,?,?,?)" */ |
| 176316 | 176619 | sqlite3_stmt *pIdxDeleter; /* "DELETE FROM %_idx WHERE segid=? */ |
| 176317 | 176620 | sqlite3_stmt *pIdxSelect; |
| 176318 | 176621 | int nRead; /* Total number of blocks read */ |
| 176622 | + | |
| 176623 | + sqlite3_stmt *pDataVersion; | |
| 176624 | + i64 iStructVersion; /* data_version when pStruct read */ | |
| 176625 | + Fts5Structure *pStruct; /* Current db structure (or NULL) */ | |
| 176319 | 176626 | }; |
| 176320 | 176627 | |
| 176321 | 176628 | struct Fts5DoclistIter { |
| 176322 | 176629 | u8 *aEof; /* Pointer to 1 byte past end of doclist */ |
| 176323 | 176630 | |
| @@ -176968,10 +177275,54 @@ | ||
| 176968 | 177275 | }else{ |
| 176969 | 177276 | *pRc = SQLITE_NOMEM; |
| 176970 | 177277 | } |
| 176971 | 177278 | } |
| 176972 | 177279 | } |
| 177280 | + | |
| 177281 | +static Fts5Structure *fts5StructureReadUncached(Fts5Index *p){ | |
| 177282 | + Fts5Structure *pRet = 0; | |
| 177283 | + Fts5Config *pConfig = p->pConfig; | |
| 177284 | + int iCookie; /* Configuration cookie */ | |
| 177285 | + Fts5Data *pData; | |
| 177286 | + | |
| 177287 | + pData = fts5DataRead(p, FTS5_STRUCTURE_ROWID); | |
| 177288 | + if( p->rc==SQLITE_OK ){ | |
| 177289 | + /* TODO: Do we need this if the leaf-index is appended? Probably... */ | |
| 177290 | + memset(&pData->p[pData->nn], 0, FTS5_DATA_PADDING); | |
| 177291 | + p->rc = fts5StructureDecode(pData->p, pData->nn, &iCookie, &pRet); | |
| 177292 | + if( p->rc==SQLITE_OK && pConfig->iCookie!=iCookie ){ | |
| 177293 | + p->rc = sqlite3Fts5ConfigLoad(pConfig, iCookie); | |
| 177294 | + } | |
| 177295 | + fts5DataRelease(pData); | |
| 177296 | + if( p->rc!=SQLITE_OK ){ | |
| 177297 | + fts5StructureRelease(pRet); | |
| 177298 | + pRet = 0; | |
| 177299 | + } | |
| 177300 | + } | |
| 177301 | + | |
| 177302 | + return pRet; | |
| 177303 | +} | |
| 177304 | + | |
| 177305 | +static i64 fts5IndexDataVersion(Fts5Index *p){ | |
| 177306 | + i64 iVersion = 0; | |
| 177307 | + | |
| 177308 | + if( p->rc==SQLITE_OK ){ | |
| 177309 | + if( p->pDataVersion==0 ){ | |
| 177310 | + p->rc = fts5IndexPrepareStmt(p, &p->pDataVersion, | |
| 177311 | + sqlite3_mprintf("PRAGMA %Q.data_version", p->pConfig->zDb) | |
| 177312 | + ); | |
| 177313 | + if( p->rc ) return 0; | |
| 177314 | + } | |
| 177315 | + | |
| 177316 | + if( SQLITE_ROW==sqlite3_step(p->pDataVersion) ){ | |
| 177317 | + iVersion = sqlite3_column_int64(p->pDataVersion, 0); | |
| 177318 | + } | |
| 177319 | + p->rc = sqlite3_reset(p->pDataVersion); | |
| 177320 | + } | |
| 177321 | + | |
| 177322 | + return iVersion; | |
| 177323 | +} | |
| 176973 | 177324 | |
| 176974 | 177325 | /* |
| 176975 | 177326 | ** Read, deserialize and return the structure record. |
| 176976 | 177327 | ** |
| 176977 | 177328 | ** The Fts5Structure.aLevel[] and each Fts5StructureLevel.aSeg[] array |
| @@ -176981,30 +177332,53 @@ | ||
| 176981 | 177332 | ** If an error occurs, NULL is returned and an error code left in the |
| 176982 | 177333 | ** Fts5Index handle. If an error has already occurred when this function |
| 176983 | 177334 | ** is called, it is a no-op. |
| 176984 | 177335 | */ |
| 176985 | 177336 | static Fts5Structure *fts5StructureRead(Fts5Index *p){ |
| 176986 | - Fts5Config *pConfig = p->pConfig; | |
| 176987 | - Fts5Structure *pRet = 0; /* Object to return */ | |
| 176988 | - int iCookie; /* Configuration cookie */ | |
| 176989 | - Fts5Data *pData; | |
| 176990 | - | |
| 176991 | - pData = fts5DataRead(p, FTS5_STRUCTURE_ROWID); | |
| 176992 | - if( p->rc ) return 0; | |
| 176993 | - /* TODO: Do we need this if the leaf-index is appended? Probably... */ | |
| 176994 | - memset(&pData->p[pData->nn], 0, FTS5_DATA_PADDING); | |
| 176995 | - p->rc = fts5StructureDecode(pData->p, pData->nn, &iCookie, &pRet); | |
| 176996 | - if( p->rc==SQLITE_OK && pConfig->iCookie!=iCookie ){ | |
| 176997 | - p->rc = sqlite3Fts5ConfigLoad(pConfig, iCookie); | |
| 176998 | - } | |
| 176999 | - | |
| 177000 | - fts5DataRelease(pData); | |
| 177001 | - if( p->rc!=SQLITE_OK ){ | |
| 177002 | - fts5StructureRelease(pRet); | |
| 177003 | - pRet = 0; | |
| 177004 | - } | |
| 177005 | - return pRet; | |
| 177337 | + | |
| 177338 | + if( p->pStruct==0 ){ | |
| 177339 | + p->iStructVersion = fts5IndexDataVersion(p); | |
| 177340 | + if( p->rc==SQLITE_OK ){ | |
| 177341 | + p->pStruct = fts5StructureReadUncached(p); | |
| 177342 | + } | |
| 177343 | + } | |
| 177344 | + | |
| 177345 | +#ifdef SQLITE_DEBUG | |
| 177346 | + else{ | |
| 177347 | + Fts5Structure *pTest = fts5StructureReadUncached(p); | |
| 177348 | + if( pTest ){ | |
| 177349 | + int i, j; | |
| 177350 | + assert_nc( p->pStruct->nSegment==pTest->nSegment ); | |
| 177351 | + assert_nc( p->pStruct->nLevel==pTest->nLevel ); | |
| 177352 | + for(i=0; i<pTest->nLevel; i++){ | |
| 177353 | + assert_nc( p->pStruct->aLevel[i].nMerge==pTest->aLevel[i].nMerge ); | |
| 177354 | + assert_nc( p->pStruct->aLevel[i].nSeg==pTest->aLevel[i].nSeg ); | |
| 177355 | + for(j=0; j<pTest->aLevel[i].nSeg; j++){ | |
| 177356 | + Fts5StructureSegment *p1 = &pTest->aLevel[i].aSeg[j]; | |
| 177357 | + Fts5StructureSegment *p2 = &p->pStruct->aLevel[i].aSeg[j]; | |
| 177358 | + assert_nc( p1->iSegid==p2->iSegid ); | |
| 177359 | + assert_nc( p1->pgnoFirst==p2->pgnoFirst ); | |
| 177360 | + assert_nc( p1->pgnoLast==p2->pgnoLast ); | |
| 177361 | + } | |
| 177362 | + } | |
| 177363 | + fts5StructureRelease(pTest); | |
| 177364 | + } | |
| 177365 | + } | |
| 177366 | +#endif | |
| 177367 | + | |
| 177368 | + if( p->rc!=SQLITE_OK ) return 0; | |
| 177369 | + assert( p->iStructVersion!=0 ); | |
| 177370 | + assert( p->pStruct!=0 ); | |
| 177371 | + fts5StructureRef(p->pStruct); | |
| 177372 | + return p->pStruct; | |
| 177373 | +} | |
| 177374 | + | |
| 177375 | +static void fts5StructureInvalidate(Fts5Index *p){ | |
| 177376 | + if( p->pStruct ){ | |
| 177377 | + fts5StructureRelease(p->pStruct); | |
| 177378 | + p->pStruct = 0; | |
| 177379 | + } | |
| 177006 | 177380 | } |
| 177007 | 177381 | |
| 177008 | 177382 | /* |
| 177009 | 177383 | ** Return the total number of segments in index structure pStruct. This |
| 177010 | 177384 | ** function is only ever used as part of assert() conditions. |
| @@ -179463,22 +179837,39 @@ | ||
| 179463 | 179837 | |
| 179464 | 179838 | if( p->rc==SQLITE_OK ){ |
| 179465 | 179839 | if( pStruct->nSegment>=FTS5_MAX_SEGMENT ){ |
| 179466 | 179840 | p->rc = SQLITE_FULL; |
| 179467 | 179841 | }else{ |
| 179468 | - while( iSegid==0 ){ | |
| 179469 | - int iLvl, iSeg; | |
| 179470 | - sqlite3_randomness(sizeof(u32), (void*)&iSegid); | |
| 179471 | - iSegid = iSegid & ((1 << FTS5_DATA_ID_B)-1); | |
| 179472 | - for(iLvl=0; iLvl<pStruct->nLevel; iLvl++){ | |
| 179473 | - for(iSeg=0; iSeg<pStruct->aLevel[iLvl].nSeg; iSeg++){ | |
| 179474 | - if( iSegid==pStruct->aLevel[iLvl].aSeg[iSeg].iSegid ){ | |
| 179475 | - iSegid = 0; | |
| 179476 | - } | |
| 179842 | + /* FTS5_MAX_SEGMENT is currently defined as 2000. So the following | |
| 179843 | + ** array is 63 elements, or 252 bytes, in size. */ | |
| 179844 | + u32 aUsed[(FTS5_MAX_SEGMENT+31) / 32]; | |
| 179845 | + int iLvl, iSeg; | |
| 179846 | + int i; | |
| 179847 | + u32 mask; | |
| 179848 | + memset(aUsed, 0, sizeof(aUsed)); | |
| 179849 | + for(iLvl=0; iLvl<pStruct->nLevel; iLvl++){ | |
| 179850 | + for(iSeg=0; iSeg<pStruct->aLevel[iLvl].nSeg; iSeg++){ | |
| 179851 | + int iId = pStruct->aLevel[iLvl].aSeg[iSeg].iSegid; | |
| 179852 | + if( iId<=FTS5_MAX_SEGMENT ){ | |
| 179853 | + aUsed[(iId-1) / 32] |= 1 << ((iId-1) % 32); | |
| 179477 | 179854 | } |
| 179478 | 179855 | } |
| 179479 | 179856 | } |
| 179857 | + | |
| 179858 | + for(i=0; aUsed[i]==0xFFFFFFFF; i++); | |
| 179859 | + mask = aUsed[i]; | |
| 179860 | + for(iSegid=0; mask & (1 << iSegid); iSegid++); | |
| 179861 | + iSegid += 1 + i*32; | |
| 179862 | + | |
| 179863 | +#ifdef SQLITE_DEBUG | |
| 179864 | + for(iLvl=0; iLvl<pStruct->nLevel; iLvl++){ | |
| 179865 | + for(iSeg=0; iSeg<pStruct->aLevel[iLvl].nSeg; iSeg++){ | |
| 179866 | + assert( iSegid!=pStruct->aLevel[iLvl].aSeg[iSeg].iSegid ); | |
| 179867 | + } | |
| 179868 | + } | |
| 179869 | + assert( iSegid>0 && iSegid<=FTS5_MAX_SEGMENT ); | |
| 179870 | +#endif | |
| 179480 | 179871 | } |
| 179481 | 179872 | } |
| 179482 | 179873 | |
| 179483 | 179874 | return iSegid; |
| 179484 | 179875 | } |
| @@ -179919,11 +180310,13 @@ | ||
| 179919 | 180310 | assert( pLeaf->pgno>=1 ); |
| 179920 | 180311 | if( pLeaf->buf.n>4 ){ |
| 179921 | 180312 | fts5WriteFlushLeaf(p, pWriter); |
| 179922 | 180313 | } |
| 179923 | 180314 | *pnLeaf = pLeaf->pgno-1; |
| 179924 | - fts5WriteFlushBtree(p, pWriter); | |
| 180315 | + if( pLeaf->pgno>1 ){ | |
| 180316 | + fts5WriteFlushBtree(p, pWriter); | |
| 180317 | + } | |
| 179925 | 180318 | } |
| 179926 | 180319 | fts5BufferFree(&pLeaf->term); |
| 179927 | 180320 | fts5BufferFree(&pLeaf->buf); |
| 179928 | 180321 | fts5BufferFree(&pLeaf->pgidx); |
| 179929 | 180322 | fts5BufferFree(&pWriter->btterm); |
| @@ -180338,10 +180731,11 @@ | ||
| 180338 | 180731 | |
| 180339 | 180732 | /* Obtain a reference to the index structure and allocate a new segment-id |
| 180340 | 180733 | ** for the new level-0 segment. */ |
| 180341 | 180734 | pStruct = fts5StructureRead(p); |
| 180342 | 180735 | iSegid = fts5AllocateSegid(p, pStruct); |
| 180736 | + fts5StructureInvalidate(p); | |
| 180343 | 180737 | |
| 180344 | 180738 | if( iSegid ){ |
| 180345 | 180739 | const int pgsz = p->pConfig->pgsz; |
| 180346 | 180740 | int eDetail = p->pConfig->eDetail; |
| 180347 | 180741 | Fts5StructureSegment *pSeg; /* New segment within pStruct */ |
| @@ -180557,10 +180951,11 @@ | ||
| 180557 | 180951 | Fts5Structure *pNew = 0; |
| 180558 | 180952 | |
| 180559 | 180953 | assert( p->rc==SQLITE_OK ); |
| 180560 | 180954 | fts5IndexFlush(p); |
| 180561 | 180955 | pStruct = fts5StructureRead(p); |
| 180956 | + fts5StructureInvalidate(p); | |
| 180562 | 180957 | |
| 180563 | 180958 | if( pStruct ){ |
| 180564 | 180959 | pNew = fts5IndexOptimizeStruct(p, pStruct); |
| 180565 | 180960 | } |
| 180566 | 180961 | fts5StructureRelease(pStruct); |
| @@ -180587,10 +180982,11 @@ | ||
| 180587 | 180982 | */ |
| 180588 | 180983 | static int sqlite3Fts5IndexMerge(Fts5Index *p, int nMerge){ |
| 180589 | 180984 | Fts5Structure *pStruct = fts5StructureRead(p); |
| 180590 | 180985 | if( pStruct ){ |
| 180591 | 180986 | int nMin = p->pConfig->nUsermerge; |
| 180987 | + fts5StructureInvalidate(p); | |
| 180592 | 180988 | if( nMerge<0 ){ |
| 180593 | 180989 | Fts5Structure *pNew = fts5IndexOptimizeStruct(p, pStruct); |
| 180594 | 180990 | fts5StructureRelease(pStruct); |
| 180595 | 180991 | pStruct = pNew; |
| 180596 | 180992 | nMin = 2; |
| @@ -181014,10 +181410,11 @@ | ||
| 181014 | 181410 | ** records must be invalidated. |
| 181015 | 181411 | */ |
| 181016 | 181412 | static int sqlite3Fts5IndexRollback(Fts5Index *p){ |
| 181017 | 181413 | fts5CloseReader(p); |
| 181018 | 181414 | fts5IndexDiscardData(p); |
| 181415 | + fts5StructureInvalidate(p); | |
| 181019 | 181416 | /* assert( p->rc==SQLITE_OK ); */ |
| 181020 | 181417 | return SQLITE_OK; |
| 181021 | 181418 | } |
| 181022 | 181419 | |
| 181023 | 181420 | /* |
| @@ -181025,10 +181422,11 @@ | ||
| 181025 | 181422 | ** function populates it with the initial structure objects for each index, |
| 181026 | 181423 | ** and the initial version of the "averages" record (a zero-byte blob). |
| 181027 | 181424 | */ |
| 181028 | 181425 | static int sqlite3Fts5IndexReinit(Fts5Index *p){ |
| 181029 | 181426 | Fts5Structure s; |
| 181427 | + fts5StructureInvalidate(p); | |
| 181030 | 181428 | memset(&s, 0, sizeof(Fts5Structure)); |
| 181031 | 181429 | fts5DataWrite(p, FTS5_AVERAGES_ROWID, (const u8*)"", 0); |
| 181032 | 181430 | fts5StructureWrite(p, &s); |
| 181033 | 181431 | return fts5IndexReturn(p); |
| 181034 | 181432 | } |
| @@ -181083,15 +181481,17 @@ | ||
| 181083 | 181481 | */ |
| 181084 | 181482 | static int sqlite3Fts5IndexClose(Fts5Index *p){ |
| 181085 | 181483 | int rc = SQLITE_OK; |
| 181086 | 181484 | if( p ){ |
| 181087 | 181485 | assert( p->pReader==0 ); |
| 181486 | + fts5StructureInvalidate(p); | |
| 181088 | 181487 | sqlite3_finalize(p->pWriter); |
| 181089 | 181488 | sqlite3_finalize(p->pDeleter); |
| 181090 | 181489 | sqlite3_finalize(p->pIdxWriter); |
| 181091 | 181490 | sqlite3_finalize(p->pIdxDeleter); |
| 181092 | 181491 | sqlite3_finalize(p->pIdxSelect); |
| 181492 | + sqlite3_finalize(p->pDataVersion); | |
| 181093 | 181493 | sqlite3Fts5HashFree(p->pHash); |
| 181094 | 181494 | sqlite3_free(p->zDataTbl); |
| 181095 | 181495 | sqlite3_free(p); |
| 181096 | 181496 | } |
| 181097 | 181497 | return rc; |
| @@ -182344,10 +182744,19 @@ | ||
| 182344 | 182744 | ); |
| 182345 | 182745 | } |
| 182346 | 182746 | return rc; |
| 182347 | 182747 | } |
| 182348 | 182748 | |
| 182749 | + | |
| 182750 | +static int sqlite3Fts5IndexReset(Fts5Index *p){ | |
| 182751 | + assert( p->pStruct==0 || p->iStructVersion!=0 ); | |
| 182752 | + if( fts5IndexDataVersion(p)!=p->iStructVersion ){ | |
| 182753 | + fts5StructureInvalidate(p); | |
| 182754 | + } | |
| 182755 | + return fts5IndexReturn(p); | |
| 182756 | +} | |
| 182757 | + | |
| 182349 | 182758 | /* |
| 182350 | 182759 | ** 2014 Jun 09 |
| 182351 | 182760 | ** |
| 182352 | 182761 | ** The author disclaims copyright to this source code. In place of |
| 182353 | 182762 | ** a legal notice, here is a blessing: |
| @@ -182942,32 +183351,43 @@ | ||
| 182942 | 183351 | } |
| 182943 | 183352 | |
| 182944 | 183353 | pInfo->idxNum = idxFlags; |
| 182945 | 183354 | return SQLITE_OK; |
| 182946 | 183355 | } |
| 183356 | + | |
| 183357 | +static int fts5NewTransaction(Fts5Table *pTab){ | |
| 183358 | + Fts5Cursor *pCsr; | |
| 183359 | + for(pCsr=pTab->pGlobal->pCsr; pCsr; pCsr=pCsr->pNext){ | |
| 183360 | + if( pCsr->base.pVtab==(sqlite3_vtab*)pTab ) return SQLITE_OK; | |
| 183361 | + } | |
| 183362 | + return sqlite3Fts5StorageReset(pTab->pStorage); | |
| 183363 | +} | |
| 182947 | 183364 | |
| 182948 | 183365 | /* |
| 182949 | 183366 | ** Implementation of xOpen method. |
| 182950 | 183367 | */ |
| 182951 | 183368 | static int fts5OpenMethod(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCsr){ |
| 182952 | 183369 | Fts5Table *pTab = (Fts5Table*)pVTab; |
| 182953 | 183370 | Fts5Config *pConfig = pTab->pConfig; |
| 182954 | - Fts5Cursor *pCsr; /* New cursor object */ | |
| 183371 | + Fts5Cursor *pCsr = 0; /* New cursor object */ | |
| 182955 | 183372 | int nByte; /* Bytes of space to allocate */ |
| 182956 | - int rc = SQLITE_OK; /* Return code */ | |
| 182957 | - | |
| 182958 | - nByte = sizeof(Fts5Cursor) + pConfig->nCol * sizeof(int); | |
| 182959 | - pCsr = (Fts5Cursor*)sqlite3_malloc(nByte); | |
| 182960 | - if( pCsr ){ | |
| 182961 | - Fts5Global *pGlobal = pTab->pGlobal; | |
| 182962 | - memset(pCsr, 0, nByte); | |
| 182963 | - pCsr->aColumnSize = (int*)&pCsr[1]; | |
| 182964 | - pCsr->pNext = pGlobal->pCsr; | |
| 182965 | - pGlobal->pCsr = pCsr; | |
| 182966 | - pCsr->iCsrId = ++pGlobal->iNextId; | |
| 182967 | - }else{ | |
| 182968 | - rc = SQLITE_NOMEM; | |
| 183373 | + int rc; /* Return code */ | |
| 183374 | + | |
| 183375 | + rc = fts5NewTransaction(pTab); | |
| 183376 | + if( rc==SQLITE_OK ){ | |
| 183377 | + nByte = sizeof(Fts5Cursor) + pConfig->nCol * sizeof(int); | |
| 183378 | + pCsr = (Fts5Cursor*)sqlite3_malloc(nByte); | |
| 183379 | + if( pCsr ){ | |
| 183380 | + Fts5Global *pGlobal = pTab->pGlobal; | |
| 183381 | + memset(pCsr, 0, nByte); | |
| 183382 | + pCsr->aColumnSize = (int*)&pCsr[1]; | |
| 183383 | + pCsr->pNext = pGlobal->pCsr; | |
| 183384 | + pGlobal->pCsr = pCsr; | |
| 183385 | + pCsr->iCsrId = ++pGlobal->iNextId; | |
| 183386 | + }else{ | |
| 183387 | + rc = SQLITE_NOMEM; | |
| 183388 | + } | |
| 182969 | 183389 | } |
| 182970 | 183390 | *ppCsr = (sqlite3_vtab_cursor*)pCsr; |
| 182971 | 183391 | return rc; |
| 182972 | 183392 | } |
| 182973 | 183393 | |
| @@ -183924,12 +184344,12 @@ | ||
| 183924 | 184344 | |
| 183925 | 184345 | /* |
| 183926 | 184346 | ** Implementation of xBegin() method. |
| 183927 | 184347 | */ |
| 183928 | 184348 | static int fts5BeginMethod(sqlite3_vtab *pVtab){ |
| 183929 | - UNUSED_PARAM(pVtab); /* Call below is a no-op for NDEBUG builds */ | |
| 183930 | 184349 | fts5CheckTransactionState((Fts5Table*)pVtab, FTS5_BEGIN, 0); |
| 184350 | + fts5NewTransaction((Fts5Table*)pVtab); | |
| 183931 | 184351 | return SQLITE_OK; |
| 183932 | 184352 | } |
| 183933 | 184353 | |
| 183934 | 184354 | /* |
| 183935 | 184355 | ** Implementation of xCommit() method. This is a no-op. The contents of |
| @@ -184950,11 +185370,11 @@ | ||
| 184950 | 185370 | int nArg, /* Number of args */ |
| 184951 | 185371 | sqlite3_value **apUnused /* Function arguments */ |
| 184952 | 185372 | ){ |
| 184953 | 185373 | assert( nArg==0 ); |
| 184954 | 185374 | UNUSED_PARAM2(nArg, apUnused); |
| 184955 | - sqlite3_result_text(pCtx, "fts5: 2016-03-18 00:39:40 b199637d81d7e2a767131ac03c7679b101fd459c", -1, SQLITE_TRANSIENT); | |
| 185375 | + sqlite3_result_text(pCtx, "fts5: 2016-03-21 16:06:42 4dc30cce7fdb7dba9a9aad96bb8b499b965610b2", -1, SQLITE_TRANSIENT); | |
| 184956 | 185376 | } |
| 184957 | 185377 | |
| 184958 | 185378 | static int fts5Init(sqlite3 *db){ |
| 184959 | 185379 | static const sqlite3_module fts5Mod = { |
| 184960 | 185380 | /* iVersion */ 2, |
| @@ -185707,10 +186127,14 @@ | ||
| 185707 | 186127 | } |
| 185708 | 186128 | |
| 185709 | 186129 | static int sqlite3Fts5StorageMerge(Fts5Storage *p, int nMerge){ |
| 185710 | 186130 | return sqlite3Fts5IndexMerge(p->pIndex, nMerge); |
| 185711 | 186131 | } |
| 186132 | + | |
| 186133 | +static int sqlite3Fts5StorageReset(Fts5Storage *p){ | |
| 186134 | + return sqlite3Fts5IndexReset(p->pIndex); | |
| 186135 | +} | |
| 185712 | 186136 | |
| 185713 | 186137 | /* |
| 185714 | 186138 | ** Allocate a new rowid. This is used for "external content" tables when |
| 185715 | 186139 | ** a NULL value is inserted into the rowid column. The new rowid is allocated |
| 185716 | 186140 | ** by inserting a dummy row into the %_docsize table. The dummy will be |
| 185717 | 186141 |
| --- src/sqlite3.c | |
| +++ src/sqlite3.c | |
| @@ -336,11 +336,11 @@ | |
| 336 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 337 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 338 | */ |
| 339 | #define SQLITE_VERSION "3.12.0" |
| 340 | #define SQLITE_VERSION_NUMBER 3012000 |
| 341 | #define SQLITE_SOURCE_ID "2016-03-19 00:35:02 88439a866b3b16ad7c308ebe59198662a05e7eeb" |
| 342 | |
| 343 | /* |
| 344 | ** CAPI3REF: Run-Time Library Version Numbers |
| 345 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 346 | ** |
| @@ -8138,10 +8138,22 @@ | |
| 8138 | ** ^This function does not set the database handle error code or message |
| 8139 | ** returned by the [sqlite3_errcode()] and [sqlite3_errmsg()] functions. |
| 8140 | */ |
| 8141 | SQLITE_API int SQLITE_STDCALL sqlite3_db_cacheflush(sqlite3*); |
| 8142 | |
| 8143 | /* |
| 8144 | ** CAPI3REF: Database Snapshot |
| 8145 | ** KEYWORDS: {snapshot} |
| 8146 | ** EXPERIMENTAL |
| 8147 | ** |
| @@ -11844,10 +11856,11 @@ | |
| 11844 | SQLITE_PRIVATE void (*sqlite3OsDlSym(sqlite3_vfs *, void *, const char *))(void); |
| 11845 | SQLITE_PRIVATE void sqlite3OsDlClose(sqlite3_vfs *, void *); |
| 11846 | #endif /* SQLITE_OMIT_LOAD_EXTENSION */ |
| 11847 | SQLITE_PRIVATE int sqlite3OsRandomness(sqlite3_vfs *, int, char *); |
| 11848 | SQLITE_PRIVATE int sqlite3OsSleep(sqlite3_vfs *, int); |
| 11849 | SQLITE_PRIVATE int sqlite3OsCurrentTimeInt64(sqlite3_vfs *, sqlite3_int64*); |
| 11850 | |
| 11851 | /* |
| 11852 | ** Convenience functions for opening and closing files using |
| 11853 | ** sqlite3_malloc() to obtain space for the file-handle structure. |
| @@ -12141,10 +12154,11 @@ | |
| 12141 | i64 lastRowid; /* ROWID of most recent insert (see above) */ |
| 12142 | i64 szMmap; /* Default mmap_size setting */ |
| 12143 | unsigned int openFlags; /* Flags passed to sqlite3_vfs.xOpen() */ |
| 12144 | int errCode; /* Most recent error code (SQLITE_*) */ |
| 12145 | int errMask; /* & result codes with this before returning */ |
| 12146 | u16 dbOptFlags; /* Flags to enable/disable optimizations */ |
| 12147 | u8 enc; /* Text encoding */ |
| 12148 | u8 autoCommit; /* The auto-commit flag. */ |
| 12149 | u8 temp_store; /* 1: file 2: memory 0: default */ |
| 12150 | u8 mallocFailed; /* True if we have seen a malloc failure */ |
| @@ -14687,10 +14701,11 @@ | |
| 14687 | SQLITE_PRIVATE char sqlite3ExprAffinity(Expr *pExpr); |
| 14688 | SQLITE_PRIVATE int sqlite3Atoi64(const char*, i64*, int, u8); |
| 14689 | SQLITE_PRIVATE int sqlite3DecOrHexToI64(const char*, i64*); |
| 14690 | SQLITE_PRIVATE void sqlite3ErrorWithMsg(sqlite3*, int, const char*,...); |
| 14691 | SQLITE_PRIVATE void sqlite3Error(sqlite3*,int); |
| 14692 | SQLITE_PRIVATE void *sqlite3HexToBlob(sqlite3*, const char *z, int n); |
| 14693 | SQLITE_PRIVATE u8 sqlite3HexToInt(int h); |
| 14694 | SQLITE_PRIVATE int sqlite3TwoPartName(Parse *, Token *, Token *, Token **); |
| 14695 | |
| 14696 | #if defined(SQLITE_NEED_ERR_NAME) |
| @@ -18111,10 +18126,13 @@ | |
| 18111 | return pVfs->xRandomness(pVfs, nByte, zBufOut); |
| 18112 | } |
| 18113 | SQLITE_PRIVATE int sqlite3OsSleep(sqlite3_vfs *pVfs, int nMicro){ |
| 18114 | return pVfs->xSleep(pVfs, nMicro); |
| 18115 | } |
| 18116 | SQLITE_PRIVATE int sqlite3OsCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *pTimeOut){ |
| 18117 | int rc; |
| 18118 | /* IMPLEMENTATION-OF: R-49045-42493 SQLite will use the xCurrentTimeInt64() |
| 18119 | ** method to get the current date and time if that method is available |
| 18120 | ** (if iVersion is 2 or greater and the function pointer is not NULL) and |
| @@ -25475,18 +25493,42 @@ | |
| 25475 | ** a poiner to that other string. |
| 25476 | */ |
| 25477 | SQLITE_PRIVATE const char *sqlite3StrNext(const char *z){ |
| 25478 | return z + strlen(z) + 1; |
| 25479 | } |
| 25480 | |
| 25481 | /* |
| 25482 | ** Set the current error code to err_code and clear any prior error message. |
| 25483 | */ |
| 25484 | SQLITE_PRIVATE void sqlite3Error(sqlite3 *db, int err_code){ |
| 25485 | assert( db!=0 ); |
| 25486 | db->errCode = err_code; |
| 25487 | if( db->pErr ) sqlite3ValueSetNull(db->pErr); |
| 25488 | } |
| 25489 | |
| 25490 | /* |
| 25491 | ** Set the most recent error code and error string for the sqlite |
| 25492 | ** handle "db". The error code is set to "err_code". |
| @@ -25509,10 +25551,11 @@ | |
| 25509 | ** to NULL. |
| 25510 | */ |
| 25511 | SQLITE_PRIVATE void sqlite3ErrorWithMsg(sqlite3 *db, int err_code, const char *zFormat, ...){ |
| 25512 | assert( db!=0 ); |
| 25513 | db->errCode = err_code; |
| 25514 | if( zFormat==0 ){ |
| 25515 | sqlite3Error(db, err_code); |
| 25516 | }else if( db->pErr || (db->pErr = sqlite3ValueNew(db))!=0 ){ |
| 25517 | char *z; |
| 25518 | va_list ap; |
| @@ -28814,11 +28857,11 @@ | |
| 28814 | rc = osFstat(pFile->h, &buf); |
| 28815 | if( rc!=0 ){ |
| 28816 | sqlite3_log(SQLITE_WARNING, "cannot fstat db file %s", pFile->zPath); |
| 28817 | return; |
| 28818 | } |
| 28819 | if( buf.st_nlink==0 && (pFile->ctrlFlags & UNIXFILE_DELETE)==0 ){ |
| 28820 | sqlite3_log(SQLITE_WARNING, "file unlinked while open: %s", pFile->zPath); |
| 28821 | return; |
| 28822 | } |
| 28823 | if( buf.st_nlink>1 ){ |
| 28824 | sqlite3_log(SQLITE_WARNING, "multiple links to file: %s", pFile->zPath); |
| @@ -33712,27 +33755,22 @@ | |
| 33712 | } |
| 33713 | #else |
| 33714 | # define unixCurrentTime 0 |
| 33715 | #endif |
| 33716 | |
| 33717 | #ifndef SQLITE_OMIT_DEPRECATED |
| 33718 | /* |
| 33719 | ** We added the xGetLastError() method with the intention of providing |
| 33720 | ** better low-level error messages when operating-system problems come up |
| 33721 | ** during SQLite operation. But so far, none of that has been implemented |
| 33722 | ** in the core. So this routine is never called. For now, it is merely |
| 33723 | ** a place-holder. |
| 33724 | */ |
| 33725 | static int unixGetLastError(sqlite3_vfs *NotUsed, int NotUsed2, char *NotUsed3){ |
| 33726 | UNUSED_PARAMETER(NotUsed); |
| 33727 | UNUSED_PARAMETER(NotUsed2); |
| 33728 | UNUSED_PARAMETER(NotUsed3); |
| 33729 | return 0; |
| 33730 | } |
| 33731 | #else |
| 33732 | # define unixGetLastError 0 |
| 33733 | #endif |
| 33734 | |
| 33735 | |
| 33736 | /* |
| 33737 | ************************ End of sqlite3_vfs methods *************************** |
| 33738 | ******************************************************************************/ |
| @@ -40819,12 +40857,14 @@ | |
| 40819 | ** However if an error message is supplied, it will be incorporated |
| 40820 | ** by sqlite into the error message available to the user using |
| 40821 | ** sqlite3_errmsg(), possibly making IO errors easier to debug. |
| 40822 | */ |
| 40823 | static int winGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){ |
| 40824 | UNUSED_PARAMETER(pVfs); |
| 40825 | return winGetLastErrorMsg(osGetLastError(), nBuf, zBuf); |
| 40826 | } |
| 40827 | |
| 40828 | /* |
| 40829 | ** Initialize and deinitialize the operating system interface. |
| 40830 | */ |
| @@ -66997,11 +67037,11 @@ | |
| 66997 | ** copies are not misused. |
| 66998 | */ |
| 66999 | SQLITE_PRIVATE void sqlite3VdbeMemAboutToChange(Vdbe *pVdbe, Mem *pMem){ |
| 67000 | int i; |
| 67001 | Mem *pX; |
| 67002 | for(i=1, pX=&pVdbe->aMem[1]; i<=pVdbe->nMem; i++, pX++){ |
| 67003 | if( pX->pScopyFrom==pMem ){ |
| 67004 | pX->flags |= MEM_Undefined; |
| 67005 | pX->pScopyFrom = 0; |
| 67006 | } |
| 67007 | } |
| @@ -69752,11 +69792,11 @@ | |
| 69752 | |
| 69753 | /* Set the magic to VDBE_MAGIC_RUN sooner rather than later. */ |
| 69754 | p->magic = VDBE_MAGIC_RUN; |
| 69755 | |
| 69756 | #ifdef SQLITE_DEBUG |
| 69757 | for(i=1; i<p->nMem; i++){ |
| 69758 | assert( p->aMem[i].db==p->db ); |
| 69759 | } |
| 69760 | #endif |
| 69761 | p->pc = -1; |
| 69762 | p->rc = SQLITE_OK; |
| @@ -69817,20 +69857,17 @@ | |
| 69817 | nCursor = pParse->nTab; |
| 69818 | nArg = pParse->nMaxArg; |
| 69819 | nOnce = pParse->nOnce; |
| 69820 | if( nOnce==0 ) nOnce = 1; /* Ensure at least one byte in p->aOnceFlag[] */ |
| 69821 | |
| 69822 | /* For each cursor required, also allocate a memory cell. Memory |
| 69823 | ** cells (nMem+1-nCursor)..nMem, inclusive, will never be used by |
| 69824 | ** the vdbe program. Instead they are used to allocate memory for |
| 69825 | ** VdbeCursor/BtCursor structures. The blob of memory associated with |
| 69826 | ** cursor 0 is stored in memory cell nMem. Memory cell (nMem-1) |
| 69827 | ** stores the blob of memory associated with cursor 1, etc. |
| 69828 | ** |
| 69829 | ** See also: allocateCursor(). |
| 69830 | */ |
| 69831 | nMem += nCursor; |
| 69832 | |
| 69833 | /* Figure out how much reusable memory is available at the end of the |
| 69834 | ** opcode array. This extra memory will be reallocated for other elements |
| 69835 | ** of the prepared statement. |
| 69836 | */ |
| @@ -69888,13 +69925,12 @@ | |
| 69888 | p->nzVar = pParse->nzVar; |
| 69889 | p->azVar = pParse->azVar; |
| 69890 | pParse->nzVar = 0; |
| 69891 | pParse->azVar = 0; |
| 69892 | if( p->aMem ){ |
| 69893 | p->aMem--; /* aMem[] goes from 1..nMem */ |
| 69894 | p->nMem = nMem; /* not from 0..nMem-1 */ |
| 69895 | for(n=1; n<=nMem; n++){ |
| 69896 | p->aMem[n].flags = MEM_Undefined; |
| 69897 | p->aMem[n].db = db; |
| 69898 | } |
| 69899 | } |
| 69900 | p->explain = pParse->explain; |
| @@ -70000,11 +70036,11 @@ | |
| 70000 | p->nFrame = 0; |
| 70001 | } |
| 70002 | assert( p->nFrame==0 ); |
| 70003 | closeCursorsInFrame(p); |
| 70004 | if( p->aMem ){ |
| 70005 | releaseMemArray(&p->aMem[1], p->nMem); |
| 70006 | } |
| 70007 | while( p->pDelFrame ){ |
| 70008 | VdbeFrame *pDel = p->pDelFrame; |
| 70009 | p->pDelFrame = pDel->pParent; |
| 70010 | sqlite3VdbeFrameDelete(pDel); |
| @@ -70025,11 +70061,11 @@ | |
| 70025 | /* Execute assert() statements to ensure that the Vdbe.apCsr[] and |
| 70026 | ** Vdbe.aMem[] arrays have already been cleaned up. */ |
| 70027 | int i; |
| 70028 | if( p->apCsr ) for(i=0; i<p->nCursor; i++) assert( p->apCsr[i]==0 ); |
| 70029 | if( p->aMem ){ |
| 70030 | for(i=1; i<=p->nMem; i++) assert( p->aMem[i].flags==MEM_Undefined ); |
| 70031 | } |
| 70032 | #endif |
| 70033 | |
| 70034 | sqlite3DbFree(db, p->zErrMsg); |
| 70035 | p->zErrMsg = 0; |
| @@ -74506,23 +74542,23 @@ | |
| 74506 | ** |
| 74507 | ** * When using ENABLE_MEMORY_MANAGEMENT, memory cell buffers can |
| 74508 | ** be freed lazily via the sqlite3_release_memory() API. This |
| 74509 | ** minimizes the number of malloc calls made by the system. |
| 74510 | ** |
| 74511 | ** Memory cells for cursors are allocated at the top of the address |
| 74512 | ** space. Memory cell (p->nMem) corresponds to cursor 0. Space for |
| 74513 | ** cursor 1 is managed by memory cell (p->nMem-1), etc. |
| 74514 | */ |
| 74515 | Mem *pMem = &p->aMem[p->nMem-iCur]; |
| 74516 | |
| 74517 | int nByte; |
| 74518 | VdbeCursor *pCx = 0; |
| 74519 | nByte = |
| 74520 | ROUND8(sizeof(VdbeCursor)) + 2*sizeof(u32)*nField + |
| 74521 | (eCurType==CURTYPE_BTREE?sqlite3BtreeCursorSize():0); |
| 74522 | |
| 74523 | assert( iCur<p->nCursor ); |
| 74524 | if( p->apCsr[iCur] ){ |
| 74525 | sqlite3VdbeFreeCursor(p, p->apCsr[iCur]); |
| 74526 | p->apCsr[iCur] = 0; |
| 74527 | } |
| 74528 | if( SQLITE_OK==sqlite3VdbeMemClearAndResize(pMem, nByte) ){ |
| @@ -74932,11 +74968,11 @@ | |
| 74932 | return pOut; |
| 74933 | } |
| 74934 | static Mem *out2Prerelease(Vdbe *p, VdbeOp *pOp){ |
| 74935 | Mem *pOut; |
| 74936 | assert( pOp->p2>0 ); |
| 74937 | assert( pOp->p2<=(p->nMem-p->nCursor) ); |
| 74938 | pOut = &p->aMem[pOp->p2]; |
| 74939 | memAboutToChange(p, pOut); |
| 74940 | if( VdbeMemDynamic(pOut) ){ |
| 74941 | return out2PrereleaseWithClear(pOut); |
| 74942 | }else{ |
| @@ -75070,37 +75106,37 @@ | |
| 75070 | /* Sanity checking on other operands */ |
| 75071 | #ifdef SQLITE_DEBUG |
| 75072 | assert( pOp->opflags==sqlite3OpcodeProperty[pOp->opcode] ); |
| 75073 | if( (pOp->opflags & OPFLG_IN1)!=0 ){ |
| 75074 | assert( pOp->p1>0 ); |
| 75075 | assert( pOp->p1<=(p->nMem-p->nCursor) ); |
| 75076 | assert( memIsValid(&aMem[pOp->p1]) ); |
| 75077 | assert( sqlite3VdbeCheckMemInvariants(&aMem[pOp->p1]) ); |
| 75078 | REGISTER_TRACE(pOp->p1, &aMem[pOp->p1]); |
| 75079 | } |
| 75080 | if( (pOp->opflags & OPFLG_IN2)!=0 ){ |
| 75081 | assert( pOp->p2>0 ); |
| 75082 | assert( pOp->p2<=(p->nMem-p->nCursor) ); |
| 75083 | assert( memIsValid(&aMem[pOp->p2]) ); |
| 75084 | assert( sqlite3VdbeCheckMemInvariants(&aMem[pOp->p2]) ); |
| 75085 | REGISTER_TRACE(pOp->p2, &aMem[pOp->p2]); |
| 75086 | } |
| 75087 | if( (pOp->opflags & OPFLG_IN3)!=0 ){ |
| 75088 | assert( pOp->p3>0 ); |
| 75089 | assert( pOp->p3<=(p->nMem-p->nCursor) ); |
| 75090 | assert( memIsValid(&aMem[pOp->p3]) ); |
| 75091 | assert( sqlite3VdbeCheckMemInvariants(&aMem[pOp->p3]) ); |
| 75092 | REGISTER_TRACE(pOp->p3, &aMem[pOp->p3]); |
| 75093 | } |
| 75094 | if( (pOp->opflags & OPFLG_OUT2)!=0 ){ |
| 75095 | assert( pOp->p2>0 ); |
| 75096 | assert( pOp->p2<=(p->nMem-p->nCursor) ); |
| 75097 | memAboutToChange(p, &aMem[pOp->p2]); |
| 75098 | } |
| 75099 | if( (pOp->opflags & OPFLG_OUT3)!=0 ){ |
| 75100 | assert( pOp->p3>0 ); |
| 75101 | assert( pOp->p3<=(p->nMem-p->nCursor) ); |
| 75102 | memAboutToChange(p, &aMem[pOp->p3]); |
| 75103 | } |
| 75104 | #endif |
| 75105 | #if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE) |
| 75106 | pOrigOp = pOp; |
| @@ -75195,11 +75231,11 @@ | |
| 75195 | ** |
| 75196 | ** Write the current address onto register P1 |
| 75197 | ** and then jump to address P2. |
| 75198 | */ |
| 75199 | case OP_Gosub: { /* jump */ |
| 75200 | assert( pOp->p1>0 && pOp->p1<=(p->nMem-p->nCursor) ); |
| 75201 | pIn1 = &aMem[pOp->p1]; |
| 75202 | assert( VdbeMemDynamic(pIn1)==0 ); |
| 75203 | memAboutToChange(p, pIn1); |
| 75204 | pIn1->flags = MEM_Int; |
| 75205 | pIn1->u.i = (int)(pOp-aOp); |
| @@ -75235,11 +75271,11 @@ | |
| 75235 | ** address P2. |
| 75236 | ** |
| 75237 | ** See also: EndCoroutine |
| 75238 | */ |
| 75239 | case OP_InitCoroutine: { /* jump */ |
| 75240 | assert( pOp->p1>0 && pOp->p1<=(p->nMem-p->nCursor) ); |
| 75241 | assert( pOp->p2>=0 && pOp->p2<p->nOp ); |
| 75242 | assert( pOp->p3>=0 && pOp->p3<p->nOp ); |
| 75243 | pOut = &aMem[pOp->p1]; |
| 75244 | assert( !VdbeMemDynamic(pOut) ); |
| 75245 | pOut->u.i = pOp->p3 - 1; |
| @@ -75504,11 +75540,11 @@ | |
| 75504 | pOut->enc = encoding; |
| 75505 | UPDATE_MAX_BLOBSIZE(pOut); |
| 75506 | #ifndef SQLITE_LIKE_DOESNT_MATCH_BLOBS |
| 75507 | if( pOp->p5 ){ |
| 75508 | assert( pOp->p3>0 ); |
| 75509 | assert( pOp->p3<=(p->nMem-p->nCursor) ); |
| 75510 | pIn3 = &aMem[pOp->p3]; |
| 75511 | assert( pIn3->flags & MEM_Int ); |
| 75512 | if( pIn3->u.i ) pOut->flags = MEM_Blob|MEM_Static|MEM_Term; |
| 75513 | } |
| 75514 | #endif |
| @@ -75530,11 +75566,11 @@ | |
| 75530 | case OP_Null: { /* out2 */ |
| 75531 | int cnt; |
| 75532 | u16 nullFlag; |
| 75533 | pOut = out2Prerelease(p, pOp); |
| 75534 | cnt = pOp->p3-pOp->p2; |
| 75535 | assert( pOp->p3<=(p->nMem-p->nCursor) ); |
| 75536 | pOut->flags = nullFlag = pOp->p1 ? (MEM_Null|MEM_Cleared) : MEM_Null; |
| 75537 | while( cnt>0 ){ |
| 75538 | pOut++; |
| 75539 | memAboutToChange(p, pOut); |
| 75540 | sqlite3VdbeMemSetNull(pOut); |
| @@ -75551,11 +75587,11 @@ | |
| 75551 | ** instruction, but do not free any string or blob memory associated with |
| 75552 | ** the register, so that if the value was a string or blob that was |
| 75553 | ** previously copied using OP_SCopy, the copies will continue to be valid. |
| 75554 | */ |
| 75555 | case OP_SoftNull: { |
| 75556 | assert( pOp->p1>0 && pOp->p1<=(p->nMem-p->nCursor) ); |
| 75557 | pOut = &aMem[pOp->p1]; |
| 75558 | pOut->flags = (pOut->flags|MEM_Null)&~MEM_Undefined; |
| 75559 | break; |
| 75560 | } |
| 75561 | |
| @@ -75618,12 +75654,12 @@ | |
| 75618 | assert( p1+n<=p2 || p2+n<=p1 ); |
| 75619 | |
| 75620 | pIn1 = &aMem[p1]; |
| 75621 | pOut = &aMem[p2]; |
| 75622 | do{ |
| 75623 | assert( pOut<=&aMem[(p->nMem-p->nCursor)] ); |
| 75624 | assert( pIn1<=&aMem[(p->nMem-p->nCursor)] ); |
| 75625 | assert( memIsValid(pIn1) ); |
| 75626 | memAboutToChange(p, pOut); |
| 75627 | sqlite3VdbeMemMove(pOut, pIn1); |
| 75628 | #ifdef SQLITE_DEBUG |
| 75629 | if( pOut->pScopyFrom>=&aMem[p1] && pOut->pScopyFrom<pOut ){ |
| @@ -75719,11 +75755,11 @@ | |
| 75719 | case OP_ResultRow: { |
| 75720 | Mem *pMem; |
| 75721 | int i; |
| 75722 | assert( p->nResColumn==pOp->p2 ); |
| 75723 | assert( pOp->p1>0 ); |
| 75724 | assert( pOp->p1+pOp->p2<=(p->nMem-p->nCursor)+1 ); |
| 75725 | |
| 75726 | #ifndef SQLITE_OMIT_PROGRESS_CALLBACK |
| 75727 | /* Run the progress counter just before returning. |
| 75728 | */ |
| 75729 | if( db->xProgress!=0 |
| @@ -76031,12 +76067,12 @@ | |
| 76031 | int n; |
| 76032 | sqlite3_context *pCtx; |
| 76033 | |
| 76034 | assert( pOp->p4type==P4_FUNCDEF ); |
| 76035 | n = pOp->p5; |
| 76036 | assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) ); |
| 76037 | assert( n==0 || (pOp->p2>0 && pOp->p2+n<=(p->nMem-p->nCursor)+1) ); |
| 76038 | assert( pOp->p3<pOp->p2 || pOp->p3>=pOp->p2+n ); |
| 76039 | pCtx = sqlite3DbMallocRawNN(db, sizeof(*pCtx) + (n-1)*sizeof(sqlite3_value*)); |
| 76040 | if( pCtx==0 ) goto no_mem; |
| 76041 | pCtx->pOut = 0; |
| 76042 | pCtx->pFunc = pOp->p4.pFunc; |
| @@ -76532,15 +76568,15 @@ | |
| 76532 | p2 = pOp->p2; |
| 76533 | #if SQLITE_DEBUG |
| 76534 | if( aPermute ){ |
| 76535 | int k, mx = 0; |
| 76536 | for(k=0; k<n; k++) if( aPermute[k]>mx ) mx = aPermute[k]; |
| 76537 | assert( p1>0 && p1+mx<=(p->nMem-p->nCursor)+1 ); |
| 76538 | assert( p2>0 && p2+mx<=(p->nMem-p->nCursor)+1 ); |
| 76539 | }else{ |
| 76540 | assert( p1>0 && p1+n<=(p->nMem-p->nCursor)+1 ); |
| 76541 | assert( p2>0 && p2+n<=(p->nMem-p->nCursor)+1 ); |
| 76542 | } |
| 76543 | #endif /* SQLITE_DEBUG */ |
| 76544 | for(i=0; i<n; i++){ |
| 76545 | idx = aPermute ? aPermute[i] : i; |
| 76546 | assert( memIsValid(&aMem[p1+idx]) ); |
| @@ -76798,11 +76834,11 @@ | |
| 76798 | p2 = pOp->p2; |
| 76799 | |
| 76800 | /* If the cursor cache is stale, bring it up-to-date */ |
| 76801 | rc = sqlite3VdbeCursorMoveto(&pC, &p2); |
| 76802 | |
| 76803 | assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) ); |
| 76804 | pDest = &aMem[pOp->p3]; |
| 76805 | memAboutToChange(p, pDest); |
| 76806 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 76807 | assert( pC!=0 ); |
| 76808 | assert( p2<pC->nField ); |
| @@ -77041,11 +77077,11 @@ | |
| 77041 | zAffinity = pOp->p4.z; |
| 77042 | assert( zAffinity!=0 ); |
| 77043 | assert( zAffinity[pOp->p2]==0 ); |
| 77044 | pIn1 = &aMem[pOp->p1]; |
| 77045 | while( (cAff = *(zAffinity++))!=0 ){ |
| 77046 | assert( pIn1 <= &p->aMem[(p->nMem-p->nCursor)] ); |
| 77047 | assert( memIsValid(pIn1) ); |
| 77048 | applyAffinity(pIn1, cAff, encoding); |
| 77049 | pIn1++; |
| 77050 | } |
| 77051 | break; |
| @@ -77103,11 +77139,11 @@ | |
| 77103 | nData = 0; /* Number of bytes of data space */ |
| 77104 | nHdr = 0; /* Number of bytes of header space */ |
| 77105 | nZero = 0; /* Number of zero bytes at the end of the record */ |
| 77106 | nField = pOp->p1; |
| 77107 | zAffinity = pOp->p4.z; |
| 77108 | assert( nField>0 && pOp->p2>0 && pOp->p2+nField<=(p->nMem-p->nCursor)+1 ); |
| 77109 | pData0 = &aMem[nField]; |
| 77110 | nField = pOp->p2; |
| 77111 | pLast = &pData0[nField-1]; |
| 77112 | file_format = p->minWriteFileFormat; |
| 77113 | |
| @@ -77193,11 +77229,11 @@ | |
| 77193 | j += sqlite3VdbeSerialPut(&zNewRecord[j], pRec, serial_type); /* content */ |
| 77194 | }while( (++pRec)<=pLast ); |
| 77195 | assert( i==nHdr ); |
| 77196 | assert( j==nByte ); |
| 77197 | |
| 77198 | assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) ); |
| 77199 | pOut->n = (int)nByte; |
| 77200 | pOut->flags = MEM_Blob; |
| 77201 | if( nZero ){ |
| 77202 | pOut->u.nZero = nZero; |
| 77203 | pOut->flags |= MEM_Zero; |
| @@ -77779,11 +77815,11 @@ | |
| 77779 | }else{ |
| 77780 | wrFlag = 0; |
| 77781 | } |
| 77782 | if( pOp->p5 & OPFLAG_P2ISREG ){ |
| 77783 | assert( p2>0 ); |
| 77784 | assert( p2<=(p->nMem-p->nCursor) ); |
| 77785 | pIn2 = &aMem[p2]; |
| 77786 | assert( memIsValid(pIn2) ); |
| 77787 | assert( (pIn2->flags & MEM_Int)!=0 ); |
| 77788 | sqlite3VdbeMemIntegerify(pIn2); |
| 77789 | p2 = (int)pIn2->u.i; |
| @@ -78574,11 +78610,11 @@ | |
| 78574 | /* Assert that P3 is a valid memory cell. */ |
| 78575 | assert( pOp->p3<=pFrame->nMem ); |
| 78576 | pMem = &pFrame->aMem[pOp->p3]; |
| 78577 | }else{ |
| 78578 | /* Assert that P3 is a valid memory cell. */ |
| 78579 | assert( pOp->p3<=(p->nMem-p->nCursor) ); |
| 78580 | pMem = &aMem[pOp->p3]; |
| 78581 | memAboutToChange(p, pMem); |
| 78582 | } |
| 78583 | assert( memIsValid(pMem) ); |
| 78584 | |
| @@ -79350,11 +79386,11 @@ | |
| 79350 | BtCursor *pCrsr; |
| 79351 | int res; |
| 79352 | UnpackedRecord r; |
| 79353 | |
| 79354 | assert( pOp->p3>0 ); |
| 79355 | assert( pOp->p2>0 && pOp->p2+pOp->p3<=(p->nMem-p->nCursor)+1 ); |
| 79356 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 79357 | pC = p->apCsr[pOp->p1]; |
| 79358 | assert( pC!=0 ); |
| 79359 | assert( pC->eCurType==CURTYPE_BTREE ); |
| 79360 | pCrsr = pC->uc.pCursor; |
| @@ -79856,11 +79892,11 @@ | |
| 79856 | assert( p->bIsReader ); |
| 79857 | nRoot = pOp->p2; |
| 79858 | aRoot = pOp->p4.ai; |
| 79859 | assert( nRoot>0 ); |
| 79860 | assert( aRoot[nRoot]==0 ); |
| 79861 | assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) ); |
| 79862 | pnErr = &aMem[pOp->p3]; |
| 79863 | assert( (pnErr->flags & MEM_Int)!=0 ); |
| 79864 | assert( (pnErr->flags & (MEM_Str|MEM_Blob))==0 ); |
| 79865 | pIn1 = &aMem[pOp->p1]; |
| 79866 | assert( pOp->p5<db->nDb ); |
| @@ -80046,10 +80082,12 @@ | |
| 80046 | ** program stored in SubProgram.aOp. As well as these, one memory |
| 80047 | ** cell is required for each cursor used by the program. Set local |
| 80048 | ** variable nMem (and later, VdbeFrame.nChildMem) to this value. |
| 80049 | */ |
| 80050 | nMem = pProgram->nMem + pProgram->nCsr; |
| 80051 | nByte = ROUND8(sizeof(VdbeFrame)) |
| 80052 | + nMem * sizeof(Mem) |
| 80053 | + pProgram->nCsr * sizeof(VdbeCursor *) |
| 80054 | + pProgram->nOnce * sizeof(u8); |
| 80055 | pFrame = sqlite3DbMallocZero(db, nByte); |
| @@ -80082,11 +80120,12 @@ | |
| 80082 | pMem->flags = MEM_Undefined; |
| 80083 | pMem->db = db; |
| 80084 | } |
| 80085 | }else{ |
| 80086 | pFrame = pRt->u.pFrame; |
| 80087 | assert( pProgram->nMem+pProgram->nCsr==pFrame->nChildMem ); |
| 80088 | assert( pProgram->nCsr==pFrame->nChildCsr ); |
| 80089 | assert( (int)(pOp - aOp)==pFrame->pc ); |
| 80090 | } |
| 80091 | |
| 80092 | p->nFrame++; |
| @@ -80097,14 +80136,14 @@ | |
| 80097 | assert( pFrame->pAuxData==0 ); |
| 80098 | pFrame->pAuxData = p->pAuxData; |
| 80099 | p->pAuxData = 0; |
| 80100 | p->nChange = 0; |
| 80101 | p->pFrame = pFrame; |
| 80102 | p->aMem = aMem = &VdbeFrameMem(pFrame)[-1]; |
| 80103 | p->nMem = pFrame->nChildMem; |
| 80104 | p->nCursor = (u16)pFrame->nChildCsr; |
| 80105 | p->apCsr = (VdbeCursor **)&aMem[p->nMem+1]; |
| 80106 | p->aOp = aOp = pProgram->aOp; |
| 80107 | p->nOp = pProgram->nOp; |
| 80108 | p->aOnceFlag = (u8 *)&p->apCsr[p->nCursor]; |
| 80109 | p->nOnceFlag = pProgram->nOnce; |
| 80110 | #ifdef SQLITE_ENABLE_STMT_SCANSTATUS |
| @@ -80346,12 +80385,12 @@ | |
| 80346 | int n; |
| 80347 | sqlite3_context *pCtx; |
| 80348 | |
| 80349 | assert( pOp->p4type==P4_FUNCDEF ); |
| 80350 | n = pOp->p5; |
| 80351 | assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) ); |
| 80352 | assert( n==0 || (pOp->p2>0 && pOp->p2+n<=(p->nMem-p->nCursor)+1) ); |
| 80353 | assert( pOp->p3<pOp->p2 || pOp->p3>=pOp->p2+n ); |
| 80354 | pCtx = sqlite3DbMallocRawNN(db, sizeof(*pCtx) + (n-1)*sizeof(sqlite3_value*)); |
| 80355 | if( pCtx==0 ) goto no_mem; |
| 80356 | pCtx->pMem = 0; |
| 80357 | pCtx->pFunc = pOp->p4.pFunc; |
| @@ -80426,11 +80465,11 @@ | |
| 80426 | ** P4 argument is only needed for the degenerate case where |
| 80427 | ** the step function was not previously called. |
| 80428 | */ |
| 80429 | case OP_AggFinal: { |
| 80430 | Mem *pMem; |
| 80431 | assert( pOp->p1>0 && pOp->p1<=(p->nMem-p->nCursor) ); |
| 80432 | pMem = &aMem[pOp->p1]; |
| 80433 | assert( (pMem->flags & ~(MEM_Null|MEM_Agg))==0 ); |
| 80434 | rc = sqlite3VdbeMemFinalize(pMem, pOp->p4.pFunc); |
| 80435 | if( rc ){ |
| 80436 | sqlite3VdbeError(p, "%s", sqlite3_value_text(pMem)); |
| @@ -80868,11 +80907,11 @@ | |
| 80868 | Mem *pDest; |
| 80869 | sqlite3_context sContext; |
| 80870 | |
| 80871 | VdbeCursor *pCur = p->apCsr[pOp->p1]; |
| 80872 | assert( pCur->eCurType==CURTYPE_VTAB ); |
| 80873 | assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) ); |
| 80874 | pDest = &aMem[pOp->p3]; |
| 80875 | memAboutToChange(p, pDest); |
| 80876 | if( pCur->nullRow ){ |
| 80877 | sqlite3VdbeMemSetNull(pDest); |
| 80878 | break; |
| @@ -81226,10 +81265,11 @@ | |
| 81226 | assert( rc ); |
| 81227 | if( p->zErrMsg==0 && rc!=SQLITE_IOERR_NOMEM ){ |
| 81228 | sqlite3VdbeError(p, "%s", sqlite3ErrStr(rc)); |
| 81229 | } |
| 81230 | p->rc = rc; |
| 81231 | testcase( sqlite3GlobalConfig.xLog!=0 ); |
| 81232 | sqlite3_log(rc, "statement aborts at %d: [%s] %s", |
| 81233 | (int)(pOp - aOp), p->zSql, p->zErrMsg); |
| 81234 | sqlite3VdbeHalt(p); |
| 81235 | if( rc==SQLITE_IOERR_NOMEM ) sqlite3OomFault(db); |
| @@ -106052,10 +106092,12 @@ | |
| 106052 | void (*result_subtype)(sqlite3_context*,unsigned int); |
| 106053 | /* Version 3.10.0 and later */ |
| 106054 | int (*status64)(int,sqlite3_int64*,sqlite3_int64*,int); |
| 106055 | int (*strlike)(const char*,const char*,unsigned int); |
| 106056 | int (*db_cacheflush)(sqlite3*); |
| 106057 | }; |
| 106058 | |
| 106059 | /* |
| 106060 | ** The following macros redefine the API routines so that they are |
| 106061 | ** redirected through the global sqlite3_api structure. |
| @@ -106295,10 +106337,12 @@ | |
| 106295 | #define sqlite3_result_subtype sqlite3_api->result_subtype |
| 106296 | /* Version 3.10.0 and later */ |
| 106297 | #define sqlite3_status64 sqlite3_api->status64 |
| 106298 | #define sqlite3_strlike sqlite3_api->strlike |
| 106299 | #define sqlite3_db_cacheflush sqlite3_api->db_cacheflush |
| 106300 | #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */ |
| 106301 | |
| 106302 | #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) |
| 106303 | /* This case when the file really is being compiled as a loadable |
| 106304 | ** extension */ |
| @@ -106713,11 +106757,13 @@ | |
| 106713 | sqlite3_value_subtype, |
| 106714 | sqlite3_result_subtype, |
| 106715 | /* Version 3.10.0 and later */ |
| 106716 | sqlite3_status64, |
| 106717 | sqlite3_strlike, |
| 106718 | sqlite3_db_cacheflush |
| 106719 | }; |
| 106720 | |
| 106721 | /* |
| 106722 | ** Attempt to load an SQLite extension library contained in the file |
| 106723 | ** zFile. The entry point is zProc. zProc may be 0 in which case a |
| @@ -135359,10 +135405,13 @@ | |
| 135359 | if( !db || db->mallocFailed ){ |
| 135360 | return SQLITE_NOMEM_BKPT; |
| 135361 | } |
| 135362 | return db->errCode; |
| 135363 | } |
| 135364 | |
| 135365 | /* |
| 135366 | ** Return a string that describes the kind of error specified in the |
| 135367 | ** argument. For now, this simply calls the internal sqlite3ErrStr() |
| 135368 | ** function. |
| @@ -161345,10 +161394,52 @@ | |
| 161345 | ** updates) that have been performed on the target database since the |
| 161346 | ** current RBU update was started. |
| 161347 | */ |
| 161348 | SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3rbu_progress(sqlite3rbu *pRbu); |
| 161349 | |
| 161350 | /* |
| 161351 | ** Create an RBU VFS named zName that accesses the underlying file-system |
| 161352 | ** via existing VFS zParent. Or, if the zParent parameter is passed NULL, |
| 161353 | ** then the new RBU VFS uses the default system VFS to access the file-system. |
| 161354 | ** The new object is registered as a non-default VFS with SQLite before |
| @@ -161466,18 +161557,19 @@ | |
| 161466 | ** target db file. |
| 161467 | ** |
| 161468 | ** RBU_STATE_OALSZ: |
| 161469 | ** Valid if STAGE==1. The size in bytes of the *-oal file. |
| 161470 | */ |
| 161471 | #define RBU_STATE_STAGE 1 |
| 161472 | #define RBU_STATE_TBL 2 |
| 161473 | #define RBU_STATE_IDX 3 |
| 161474 | #define RBU_STATE_ROW 4 |
| 161475 | #define RBU_STATE_PROGRESS 5 |
| 161476 | #define RBU_STATE_CKPT 6 |
| 161477 | #define RBU_STATE_COOKIE 7 |
| 161478 | #define RBU_STATE_OALSZ 8 |
| 161479 | |
| 161480 | #define RBU_STAGE_OAL 1 |
| 161481 | #define RBU_STAGE_MOVE 2 |
| 161482 | #define RBU_STAGE_CAPTURE 3 |
| 161483 | #define RBU_STAGE_CKPT 4 |
| @@ -161519,10 +161611,11 @@ | |
| 161519 | i64 iWalCksum; |
| 161520 | int nRow; |
| 161521 | i64 nProgress; |
| 161522 | u32 iCookie; |
| 161523 | i64 iOalSz; |
| 161524 | }; |
| 161525 | |
| 161526 | struct RbuUpdateStmt { |
| 161527 | char *zMask; /* Copy of update mask used with pUpdate */ |
| 161528 | sqlite3_stmt *pUpdate; /* Last update statement (or NULL) */ |
| @@ -161563,10 +161656,11 @@ | |
| 161563 | const char *zDataTbl; /* Name of rbu db table (or null) */ |
| 161564 | const char *zIdx; /* Name of target db index (or null) */ |
| 161565 | int iTnum; /* Root page of current object */ |
| 161566 | int iPkTnum; /* If eType==EXTERNAL, root of PK index */ |
| 161567 | int bUnique; /* Current index is unique */ |
| 161568 | |
| 161569 | /* Statements created by rbuObjIterPrepareAll() */ |
| 161570 | int nCol; /* Number of columns in current object */ |
| 161571 | sqlite3_stmt *pSelect; /* Source data */ |
| 161572 | sqlite3_stmt *pInsert; /* Statement for INSERT operations */ |
| @@ -161616,10 +161710,47 @@ | |
| 161616 | u32 iWalFrame; |
| 161617 | }; |
| 161618 | |
| 161619 | /* |
| 161620 | ** RBU handle. |
| 161621 | */ |
| 161622 | struct sqlite3rbu { |
| 161623 | int eStage; /* Value of RBU_STATE_STAGE field */ |
| 161624 | sqlite3 *dbMain; /* target database handle */ |
| 161625 | sqlite3 *dbRbu; /* rbu database handle */ |
| @@ -161633,10 +161764,11 @@ | |
| 161633 | int nProgress; /* Rows processed for all objects */ |
| 161634 | RbuObjIter objiter; /* Iterator for skipping through tbl/idx */ |
| 161635 | const char *zVfsName; /* Name of automatically created rbu vfs */ |
| 161636 | rbu_file *pTargetFd; /* File handle open on target db */ |
| 161637 | i64 iOalSz; |
| 161638 | |
| 161639 | /* The following state variables are used as part of the incremental |
| 161640 | ** checkpoint stage (eStage==RBU_STAGE_CKPT). See comments surrounding |
| 161641 | ** function rbuSetupCheckpoint() for details. */ |
| 161642 | u32 iMaxFrame; /* Largest iWalFrame value in aFrame[] */ |
| @@ -162463,10 +162595,11 @@ | |
| 162463 | p->rc = prepareFreeAndCollectError(p->dbMain, &pList, &p->zErrmsg, |
| 162464 | sqlite3_mprintf("PRAGMA main.index_list = %Q", pIter->zTbl) |
| 162465 | ); |
| 162466 | } |
| 162467 | |
| 162468 | while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pList) ){ |
| 162469 | const char *zIdx = (const char*)sqlite3_column_text(pList, 1); |
| 162470 | sqlite3_stmt *pXInfo = 0; |
| 162471 | if( zIdx==0 ) break; |
| 162472 | p->rc = prepareFreeAndCollectError(p->dbMain, &pXInfo, &p->zErrmsg, |
| @@ -162476,10 +162609,16 @@ | |
| 162476 | int iCid = sqlite3_column_int(pXInfo, 1); |
| 162477 | if( iCid>=0 ) pIter->abIndexed[iCid] = 1; |
| 162478 | } |
| 162479 | rbuFinalize(p, pXInfo); |
| 162480 | bIndex = 1; |
| 162481 | } |
| 162482 | |
| 162483 | rbuFinalize(p, pList); |
| 162484 | if( bIndex==0 ) pIter->abIndexed = 0; |
| 162485 | } |
| @@ -162589,10 +162728,11 @@ | |
| 162589 | } |
| 162590 | |
| 162591 | rbuFinalize(p, pStmt); |
| 162592 | rbuObjIterCacheIndexedCols(p, pIter); |
| 162593 | assert( pIter->eType!=RBU_PK_VTAB || pIter->abIndexed==0 ); |
| 162594 | } |
| 162595 | |
| 162596 | return p->rc; |
| 162597 | } |
| 162598 | |
| @@ -163141,10 +163281,18 @@ | |
| 163141 | sqlite3_value **apVal |
| 163142 | ){ |
| 163143 | sqlite3rbu *p = sqlite3_user_data(pCtx); |
| 163144 | int rc = SQLITE_OK; |
| 163145 | int i; |
| 163146 | |
| 163147 | for(i=0; rc==SQLITE_OK && i<nVal; i++){ |
| 163148 | rc = sqlite3_bind_value(p->objiter.pTmpInsert, i+1, apVal[i]); |
| 163149 | } |
| 163150 | if( rc==SQLITE_OK ){ |
| @@ -163886,10 +164034,21 @@ | |
| 163886 | sqlite3_stmt *pWriter; |
| 163887 | int i; |
| 163888 | |
| 163889 | assert( p->rc==SQLITE_OK ); |
| 163890 | assert( eType!=RBU_DELETE || pIter->zIdx==0 ); |
| 163891 | |
| 163892 | if( eType==RBU_IDX_DELETE || eType==RBU_DELETE ){ |
| 163893 | pWriter = pIter->pDelete; |
| 163894 | }else{ |
| 163895 | pWriter = pIter->pInsert; |
| @@ -163957,24 +164116,28 @@ | |
| 163957 | || eType==RBU_REPLACE || eType==RBU_IDX_DELETE |
| 163958 | || eType==RBU_IDX_INSERT || eType==RBU_UPDATE |
| 163959 | ); |
| 163960 | assert( eType!=RBU_UPDATE || pIter->zIdx==0 ); |
| 163961 | |
| 163962 | if( pIter->zIdx==0 && eType==RBU_IDX_DELETE ){ |
| 163963 | rbuBadControlError(p); |
| 163964 | } |
| 163965 | else if( eType==RBU_REPLACE ){ |
| 163966 | if( pIter->zIdx==0 ) rbuStepOneOp(p, RBU_DELETE); |
| 163967 | if( p->rc==SQLITE_OK ) rbuStepOneOp(p, RBU_INSERT); |
| 163968 | } |
| 163969 | else if( eType!=RBU_UPDATE ){ |
| 163970 | rbuStepOneOp(p, eType); |
| 163971 | } |
| 163972 | else{ |
| 163973 | sqlite3_value *pVal; |
| 163974 | sqlite3_stmt *pUpdate = 0; |
| 163975 | assert( eType==RBU_UPDATE ); |
| 163976 | rbuGetUpdateStmt(p, pIter, zMask, &pUpdate); |
| 163977 | if( pUpdate ){ |
| 163978 | int i; |
| 163979 | for(i=0; p->rc==SQLITE_OK && i<pIter->nCol; i++){ |
| 163980 | char c = zMask[pIter->aiSrcOrder[i]]; |
| @@ -164048,20 +164211,22 @@ | |
| 164048 | "(%d, %Q), " |
| 164049 | "(%d, %d), " |
| 164050 | "(%d, %d), " |
| 164051 | "(%d, %lld), " |
| 164052 | "(%d, %lld), " |
| 164053 | "(%d, %lld) ", |
| 164054 | p->zStateDb, |
| 164055 | RBU_STATE_STAGE, eStage, |
| 164056 | RBU_STATE_TBL, p->objiter.zTbl, |
| 164057 | RBU_STATE_IDX, p->objiter.zIdx, |
| 164058 | RBU_STATE_ROW, p->nStep, |
| 164059 | RBU_STATE_PROGRESS, p->nProgress, |
| 164060 | RBU_STATE_CKPT, p->iWalCksum, |
| 164061 | RBU_STATE_COOKIE, (i64)p->pTargetFd->iCookie, |
| 164062 | RBU_STATE_OALSZ, p->iOalSz |
| 164063 | ) |
| 164064 | ); |
| 164065 | assert( pInsert==0 || rc==SQLITE_OK ); |
| 164066 | |
| 164067 | if( rc==SQLITE_OK ){ |
| @@ -164244,10 +164409,14 @@ | |
| 164244 | |
| 164245 | case RBU_STATE_OALSZ: |
| 164246 | pRet->iOalSz = (u32)sqlite3_column_int64(pStmt, 1); |
| 164247 | break; |
| 164248 | |
| 164249 | default: |
| 164250 | rc = SQLITE_CORRUPT; |
| 164251 | break; |
| 164252 | } |
| 164253 | } |
| @@ -164350,10 +164519,104 @@ | |
| 164350 | if( p->zVfsName ){ |
| 164351 | sqlite3rbu_destroy_vfs(p->zVfsName); |
| 164352 | p->zVfsName = 0; |
| 164353 | } |
| 164354 | } |
| 164355 | |
| 164356 | /* |
| 164357 | ** Open and return a new RBU handle. |
| 164358 | */ |
| 164359 | SQLITE_API sqlite3rbu *SQLITE_STDCALL sqlite3rbu_open( |
| @@ -164396,13 +164659,15 @@ | |
| 164396 | assert( pState || p->rc!=SQLITE_OK ); |
| 164397 | if( p->rc==SQLITE_OK ){ |
| 164398 | |
| 164399 | if( pState->eStage==0 ){ |
| 164400 | rbuDeleteOalFile(p); |
| 164401 | p->eStage = RBU_STAGE_OAL; |
| 164402 | }else{ |
| 164403 | p->eStage = pState->eStage; |
| 164404 | } |
| 164405 | p->nProgress = pState->nProgress; |
| 164406 | p->iOalSz = pState->iOalSz; |
| 164407 | } |
| 164408 | } |
| @@ -164561,10 +164826,46 @@ | |
| 164561 | ** current RBU update was started. |
| 164562 | */ |
| 164563 | SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3rbu_progress(sqlite3rbu *pRbu){ |
| 164564 | return pRbu->nProgress; |
| 164565 | } |
| 164566 | |
| 164567 | SQLITE_API int SQLITE_STDCALL sqlite3rbu_savestate(sqlite3rbu *p){ |
| 164568 | int rc = p->rc; |
| 164569 | |
| 164570 | if( rc==SQLITE_DONE ) return SQLITE_OK; |
| @@ -169364,10 +169665,11 @@ | |
| 169364 | static int sqlite3Fts5IndexReads(Fts5Index *p); |
| 169365 | |
| 169366 | static int sqlite3Fts5IndexReinit(Fts5Index *p); |
| 169367 | static int sqlite3Fts5IndexOptimize(Fts5Index *p); |
| 169368 | static int sqlite3Fts5IndexMerge(Fts5Index *p, int nMerge); |
| 169369 | |
| 169370 | static int sqlite3Fts5IndexLoadConfig(Fts5Index *p); |
| 169371 | |
| 169372 | /* |
| 169373 | ** End of interface to code in fts5_index.c. |
| @@ -169506,10 +169808,11 @@ | |
| 169506 | |
| 169507 | static int sqlite3Fts5StorageDeleteAll(Fts5Storage *p); |
| 169508 | static int sqlite3Fts5StorageRebuild(Fts5Storage *p); |
| 169509 | static int sqlite3Fts5StorageOptimize(Fts5Storage *p); |
| 169510 | static int sqlite3Fts5StorageMerge(Fts5Storage *p, int nMerge); |
| 169511 | |
| 169512 | /* |
| 169513 | ** End of interface to code in fts5_storage.c. |
| 169514 | **************************************************************************/ |
| 169515 | |
| @@ -176314,10 +176617,14 @@ | |
| 176314 | sqlite3_stmt *pDeleter; /* "DELETE FROM %_data ... id>=? AND id<=?" */ |
| 176315 | sqlite3_stmt *pIdxWriter; /* "INSERT ... %_idx VALUES(?,?,?,?)" */ |
| 176316 | sqlite3_stmt *pIdxDeleter; /* "DELETE FROM %_idx WHERE segid=? */ |
| 176317 | sqlite3_stmt *pIdxSelect; |
| 176318 | int nRead; /* Total number of blocks read */ |
| 176319 | }; |
| 176320 | |
| 176321 | struct Fts5DoclistIter { |
| 176322 | u8 *aEof; /* Pointer to 1 byte past end of doclist */ |
| 176323 | |
| @@ -176968,10 +177275,54 @@ | |
| 176968 | }else{ |
| 176969 | *pRc = SQLITE_NOMEM; |
| 176970 | } |
| 176971 | } |
| 176972 | } |
| 176973 | |
| 176974 | /* |
| 176975 | ** Read, deserialize and return the structure record. |
| 176976 | ** |
| 176977 | ** The Fts5Structure.aLevel[] and each Fts5StructureLevel.aSeg[] array |
| @@ -176981,30 +177332,53 @@ | |
| 176981 | ** If an error occurs, NULL is returned and an error code left in the |
| 176982 | ** Fts5Index handle. If an error has already occurred when this function |
| 176983 | ** is called, it is a no-op. |
| 176984 | */ |
| 176985 | static Fts5Structure *fts5StructureRead(Fts5Index *p){ |
| 176986 | Fts5Config *pConfig = p->pConfig; |
| 176987 | Fts5Structure *pRet = 0; /* Object to return */ |
| 176988 | int iCookie; /* Configuration cookie */ |
| 176989 | Fts5Data *pData; |
| 176990 | |
| 176991 | pData = fts5DataRead(p, FTS5_STRUCTURE_ROWID); |
| 176992 | if( p->rc ) return 0; |
| 176993 | /* TODO: Do we need this if the leaf-index is appended? Probably... */ |
| 176994 | memset(&pData->p[pData->nn], 0, FTS5_DATA_PADDING); |
| 176995 | p->rc = fts5StructureDecode(pData->p, pData->nn, &iCookie, &pRet); |
| 176996 | if( p->rc==SQLITE_OK && pConfig->iCookie!=iCookie ){ |
| 176997 | p->rc = sqlite3Fts5ConfigLoad(pConfig, iCookie); |
| 176998 | } |
| 176999 | |
| 177000 | fts5DataRelease(pData); |
| 177001 | if( p->rc!=SQLITE_OK ){ |
| 177002 | fts5StructureRelease(pRet); |
| 177003 | pRet = 0; |
| 177004 | } |
| 177005 | return pRet; |
| 177006 | } |
| 177007 | |
| 177008 | /* |
| 177009 | ** Return the total number of segments in index structure pStruct. This |
| 177010 | ** function is only ever used as part of assert() conditions. |
| @@ -179463,22 +179837,39 @@ | |
| 179463 | |
| 179464 | if( p->rc==SQLITE_OK ){ |
| 179465 | if( pStruct->nSegment>=FTS5_MAX_SEGMENT ){ |
| 179466 | p->rc = SQLITE_FULL; |
| 179467 | }else{ |
| 179468 | while( iSegid==0 ){ |
| 179469 | int iLvl, iSeg; |
| 179470 | sqlite3_randomness(sizeof(u32), (void*)&iSegid); |
| 179471 | iSegid = iSegid & ((1 << FTS5_DATA_ID_B)-1); |
| 179472 | for(iLvl=0; iLvl<pStruct->nLevel; iLvl++){ |
| 179473 | for(iSeg=0; iSeg<pStruct->aLevel[iLvl].nSeg; iSeg++){ |
| 179474 | if( iSegid==pStruct->aLevel[iLvl].aSeg[iSeg].iSegid ){ |
| 179475 | iSegid = 0; |
| 179476 | } |
| 179477 | } |
| 179478 | } |
| 179479 | } |
| 179480 | } |
| 179481 | } |
| 179482 | |
| 179483 | return iSegid; |
| 179484 | } |
| @@ -179919,11 +180310,13 @@ | |
| 179919 | assert( pLeaf->pgno>=1 ); |
| 179920 | if( pLeaf->buf.n>4 ){ |
| 179921 | fts5WriteFlushLeaf(p, pWriter); |
| 179922 | } |
| 179923 | *pnLeaf = pLeaf->pgno-1; |
| 179924 | fts5WriteFlushBtree(p, pWriter); |
| 179925 | } |
| 179926 | fts5BufferFree(&pLeaf->term); |
| 179927 | fts5BufferFree(&pLeaf->buf); |
| 179928 | fts5BufferFree(&pLeaf->pgidx); |
| 179929 | fts5BufferFree(&pWriter->btterm); |
| @@ -180338,10 +180731,11 @@ | |
| 180338 | |
| 180339 | /* Obtain a reference to the index structure and allocate a new segment-id |
| 180340 | ** for the new level-0 segment. */ |
| 180341 | pStruct = fts5StructureRead(p); |
| 180342 | iSegid = fts5AllocateSegid(p, pStruct); |
| 180343 | |
| 180344 | if( iSegid ){ |
| 180345 | const int pgsz = p->pConfig->pgsz; |
| 180346 | int eDetail = p->pConfig->eDetail; |
| 180347 | Fts5StructureSegment *pSeg; /* New segment within pStruct */ |
| @@ -180557,10 +180951,11 @@ | |
| 180557 | Fts5Structure *pNew = 0; |
| 180558 | |
| 180559 | assert( p->rc==SQLITE_OK ); |
| 180560 | fts5IndexFlush(p); |
| 180561 | pStruct = fts5StructureRead(p); |
| 180562 | |
| 180563 | if( pStruct ){ |
| 180564 | pNew = fts5IndexOptimizeStruct(p, pStruct); |
| 180565 | } |
| 180566 | fts5StructureRelease(pStruct); |
| @@ -180587,10 +180982,11 @@ | |
| 180587 | */ |
| 180588 | static int sqlite3Fts5IndexMerge(Fts5Index *p, int nMerge){ |
| 180589 | Fts5Structure *pStruct = fts5StructureRead(p); |
| 180590 | if( pStruct ){ |
| 180591 | int nMin = p->pConfig->nUsermerge; |
| 180592 | if( nMerge<0 ){ |
| 180593 | Fts5Structure *pNew = fts5IndexOptimizeStruct(p, pStruct); |
| 180594 | fts5StructureRelease(pStruct); |
| 180595 | pStruct = pNew; |
| 180596 | nMin = 2; |
| @@ -181014,10 +181410,11 @@ | |
| 181014 | ** records must be invalidated. |
| 181015 | */ |
| 181016 | static int sqlite3Fts5IndexRollback(Fts5Index *p){ |
| 181017 | fts5CloseReader(p); |
| 181018 | fts5IndexDiscardData(p); |
| 181019 | /* assert( p->rc==SQLITE_OK ); */ |
| 181020 | return SQLITE_OK; |
| 181021 | } |
| 181022 | |
| 181023 | /* |
| @@ -181025,10 +181422,11 @@ | |
| 181025 | ** function populates it with the initial structure objects for each index, |
| 181026 | ** and the initial version of the "averages" record (a zero-byte blob). |
| 181027 | */ |
| 181028 | static int sqlite3Fts5IndexReinit(Fts5Index *p){ |
| 181029 | Fts5Structure s; |
| 181030 | memset(&s, 0, sizeof(Fts5Structure)); |
| 181031 | fts5DataWrite(p, FTS5_AVERAGES_ROWID, (const u8*)"", 0); |
| 181032 | fts5StructureWrite(p, &s); |
| 181033 | return fts5IndexReturn(p); |
| 181034 | } |
| @@ -181083,15 +181481,17 @@ | |
| 181083 | */ |
| 181084 | static int sqlite3Fts5IndexClose(Fts5Index *p){ |
| 181085 | int rc = SQLITE_OK; |
| 181086 | if( p ){ |
| 181087 | assert( p->pReader==0 ); |
| 181088 | sqlite3_finalize(p->pWriter); |
| 181089 | sqlite3_finalize(p->pDeleter); |
| 181090 | sqlite3_finalize(p->pIdxWriter); |
| 181091 | sqlite3_finalize(p->pIdxDeleter); |
| 181092 | sqlite3_finalize(p->pIdxSelect); |
| 181093 | sqlite3Fts5HashFree(p->pHash); |
| 181094 | sqlite3_free(p->zDataTbl); |
| 181095 | sqlite3_free(p); |
| 181096 | } |
| 181097 | return rc; |
| @@ -182344,10 +182744,19 @@ | |
| 182344 | ); |
| 182345 | } |
| 182346 | return rc; |
| 182347 | } |
| 182348 | |
| 182349 | /* |
| 182350 | ** 2014 Jun 09 |
| 182351 | ** |
| 182352 | ** The author disclaims copyright to this source code. In place of |
| 182353 | ** a legal notice, here is a blessing: |
| @@ -182942,32 +183351,43 @@ | |
| 182942 | } |
| 182943 | |
| 182944 | pInfo->idxNum = idxFlags; |
| 182945 | return SQLITE_OK; |
| 182946 | } |
| 182947 | |
| 182948 | /* |
| 182949 | ** Implementation of xOpen method. |
| 182950 | */ |
| 182951 | static int fts5OpenMethod(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCsr){ |
| 182952 | Fts5Table *pTab = (Fts5Table*)pVTab; |
| 182953 | Fts5Config *pConfig = pTab->pConfig; |
| 182954 | Fts5Cursor *pCsr; /* New cursor object */ |
| 182955 | int nByte; /* Bytes of space to allocate */ |
| 182956 | int rc = SQLITE_OK; /* Return code */ |
| 182957 | |
| 182958 | nByte = sizeof(Fts5Cursor) + pConfig->nCol * sizeof(int); |
| 182959 | pCsr = (Fts5Cursor*)sqlite3_malloc(nByte); |
| 182960 | if( pCsr ){ |
| 182961 | Fts5Global *pGlobal = pTab->pGlobal; |
| 182962 | memset(pCsr, 0, nByte); |
| 182963 | pCsr->aColumnSize = (int*)&pCsr[1]; |
| 182964 | pCsr->pNext = pGlobal->pCsr; |
| 182965 | pGlobal->pCsr = pCsr; |
| 182966 | pCsr->iCsrId = ++pGlobal->iNextId; |
| 182967 | }else{ |
| 182968 | rc = SQLITE_NOMEM; |
| 182969 | } |
| 182970 | *ppCsr = (sqlite3_vtab_cursor*)pCsr; |
| 182971 | return rc; |
| 182972 | } |
| 182973 | |
| @@ -183924,12 +184344,12 @@ | |
| 183924 | |
| 183925 | /* |
| 183926 | ** Implementation of xBegin() method. |
| 183927 | */ |
| 183928 | static int fts5BeginMethod(sqlite3_vtab *pVtab){ |
| 183929 | UNUSED_PARAM(pVtab); /* Call below is a no-op for NDEBUG builds */ |
| 183930 | fts5CheckTransactionState((Fts5Table*)pVtab, FTS5_BEGIN, 0); |
| 183931 | return SQLITE_OK; |
| 183932 | } |
| 183933 | |
| 183934 | /* |
| 183935 | ** Implementation of xCommit() method. This is a no-op. The contents of |
| @@ -184950,11 +185370,11 @@ | |
| 184950 | int nArg, /* Number of args */ |
| 184951 | sqlite3_value **apUnused /* Function arguments */ |
| 184952 | ){ |
| 184953 | assert( nArg==0 ); |
| 184954 | UNUSED_PARAM2(nArg, apUnused); |
| 184955 | sqlite3_result_text(pCtx, "fts5: 2016-03-18 00:39:40 b199637d81d7e2a767131ac03c7679b101fd459c", -1, SQLITE_TRANSIENT); |
| 184956 | } |
| 184957 | |
| 184958 | static int fts5Init(sqlite3 *db){ |
| 184959 | static const sqlite3_module fts5Mod = { |
| 184960 | /* iVersion */ 2, |
| @@ -185707,10 +186127,14 @@ | |
| 185707 | } |
| 185708 | |
| 185709 | static int sqlite3Fts5StorageMerge(Fts5Storage *p, int nMerge){ |
| 185710 | return sqlite3Fts5IndexMerge(p->pIndex, nMerge); |
| 185711 | } |
| 185712 | |
| 185713 | /* |
| 185714 | ** Allocate a new rowid. This is used for "external content" tables when |
| 185715 | ** a NULL value is inserted into the rowid column. The new rowid is allocated |
| 185716 | ** by inserting a dummy row into the %_docsize table. The dummy will be |
| 185717 |
| --- src/sqlite3.c | |
| +++ src/sqlite3.c | |
| @@ -336,11 +336,11 @@ | |
| 336 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 337 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 338 | */ |
| 339 | #define SQLITE_VERSION "3.12.0" |
| 340 | #define SQLITE_VERSION_NUMBER 3012000 |
| 341 | #define SQLITE_SOURCE_ID "2016-03-21 16:06:42 4dc30cce7fdb7dba9a9aad96bb8b499b965610b2" |
| 342 | |
| 343 | /* |
| 344 | ** CAPI3REF: Run-Time Library Version Numbers |
| 345 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 346 | ** |
| @@ -8138,10 +8138,22 @@ | |
| 8138 | ** ^This function does not set the database handle error code or message |
| 8139 | ** returned by the [sqlite3_errcode()] and [sqlite3_errmsg()] functions. |
| 8140 | */ |
| 8141 | SQLITE_API int SQLITE_STDCALL sqlite3_db_cacheflush(sqlite3*); |
| 8142 | |
| 8143 | /* |
| 8144 | ** CAPI3REF: Low-level system error code |
| 8145 | ** |
| 8146 | ** ^Attempt to return the underlying operating system error code or error |
| 8147 | ** number that caused the most reason I/O error or failure to open a file. |
| 8148 | ** The return value is OS-dependent. For example, on unix systems, after |
| 8149 | ** [sqlite3_open_v2()] returns [SQLITE_CANTOPEN], this interface could be |
| 8150 | ** called to get back the underlying "errno" that caused the problem, such |
| 8151 | ** as ENOSPC, EAUTH, EISDIR, and so forth. |
| 8152 | */ |
| 8153 | SQLITE_API int SQLITE_STDCALL sqlite3_system_errno(sqlite3*); |
| 8154 | |
| 8155 | /* |
| 8156 | ** CAPI3REF: Database Snapshot |
| 8157 | ** KEYWORDS: {snapshot} |
| 8158 | ** EXPERIMENTAL |
| 8159 | ** |
| @@ -11844,10 +11856,11 @@ | |
| 11856 | SQLITE_PRIVATE void (*sqlite3OsDlSym(sqlite3_vfs *, void *, const char *))(void); |
| 11857 | SQLITE_PRIVATE void sqlite3OsDlClose(sqlite3_vfs *, void *); |
| 11858 | #endif /* SQLITE_OMIT_LOAD_EXTENSION */ |
| 11859 | SQLITE_PRIVATE int sqlite3OsRandomness(sqlite3_vfs *, int, char *); |
| 11860 | SQLITE_PRIVATE int sqlite3OsSleep(sqlite3_vfs *, int); |
| 11861 | SQLITE_PRIVATE int sqlite3OsGetLastError(sqlite3_vfs*); |
| 11862 | SQLITE_PRIVATE int sqlite3OsCurrentTimeInt64(sqlite3_vfs *, sqlite3_int64*); |
| 11863 | |
| 11864 | /* |
| 11865 | ** Convenience functions for opening and closing files using |
| 11866 | ** sqlite3_malloc() to obtain space for the file-handle structure. |
| @@ -12141,10 +12154,11 @@ | |
| 12154 | i64 lastRowid; /* ROWID of most recent insert (see above) */ |
| 12155 | i64 szMmap; /* Default mmap_size setting */ |
| 12156 | unsigned int openFlags; /* Flags passed to sqlite3_vfs.xOpen() */ |
| 12157 | int errCode; /* Most recent error code (SQLITE_*) */ |
| 12158 | int errMask; /* & result codes with this before returning */ |
| 12159 | int iSysErrno; /* Errno value from last system error */ |
| 12160 | u16 dbOptFlags; /* Flags to enable/disable optimizations */ |
| 12161 | u8 enc; /* Text encoding */ |
| 12162 | u8 autoCommit; /* The auto-commit flag. */ |
| 12163 | u8 temp_store; /* 1: file 2: memory 0: default */ |
| 12164 | u8 mallocFailed; /* True if we have seen a malloc failure */ |
| @@ -14687,10 +14701,11 @@ | |
| 14701 | SQLITE_PRIVATE char sqlite3ExprAffinity(Expr *pExpr); |
| 14702 | SQLITE_PRIVATE int sqlite3Atoi64(const char*, i64*, int, u8); |
| 14703 | SQLITE_PRIVATE int sqlite3DecOrHexToI64(const char*, i64*); |
| 14704 | SQLITE_PRIVATE void sqlite3ErrorWithMsg(sqlite3*, int, const char*,...); |
| 14705 | SQLITE_PRIVATE void sqlite3Error(sqlite3*,int); |
| 14706 | SQLITE_PRIVATE void sqlite3SystemError(sqlite3*,int); |
| 14707 | SQLITE_PRIVATE void *sqlite3HexToBlob(sqlite3*, const char *z, int n); |
| 14708 | SQLITE_PRIVATE u8 sqlite3HexToInt(int h); |
| 14709 | SQLITE_PRIVATE int sqlite3TwoPartName(Parse *, Token *, Token *, Token **); |
| 14710 | |
| 14711 | #if defined(SQLITE_NEED_ERR_NAME) |
| @@ -18111,10 +18126,13 @@ | |
| 18126 | return pVfs->xRandomness(pVfs, nByte, zBufOut); |
| 18127 | } |
| 18128 | SQLITE_PRIVATE int sqlite3OsSleep(sqlite3_vfs *pVfs, int nMicro){ |
| 18129 | return pVfs->xSleep(pVfs, nMicro); |
| 18130 | } |
| 18131 | SQLITE_PRIVATE int sqlite3OsGetLastError(sqlite3_vfs *pVfs){ |
| 18132 | return pVfs->xGetLastError ? pVfs->xGetLastError(pVfs, 0, 0) : 0; |
| 18133 | } |
| 18134 | SQLITE_PRIVATE int sqlite3OsCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *pTimeOut){ |
| 18135 | int rc; |
| 18136 | /* IMPLEMENTATION-OF: R-49045-42493 SQLite will use the xCurrentTimeInt64() |
| 18137 | ** method to get the current date and time if that method is available |
| 18138 | ** (if iVersion is 2 or greater and the function pointer is not NULL) and |
| @@ -25475,18 +25493,42 @@ | |
| 25493 | ** a poiner to that other string. |
| 25494 | */ |
| 25495 | SQLITE_PRIVATE const char *sqlite3StrNext(const char *z){ |
| 25496 | return z + strlen(z) + 1; |
| 25497 | } |
| 25498 | |
| 25499 | /* |
| 25500 | ** Helper function for sqlite3Error() - called rarely. Broken out into |
| 25501 | ** a separate routine to avoid unnecessary register saves on entry to |
| 25502 | ** sqlite3Error(). |
| 25503 | */ |
| 25504 | static SQLITE_NOINLINE void sqlite3ErrorFinish(sqlite3 *db, int err_code){ |
| 25505 | if( db->pErr ) sqlite3ValueSetNull(db->pErr); |
| 25506 | sqlite3SystemError(db, err_code); |
| 25507 | } |
| 25508 | |
| 25509 | /* |
| 25510 | ** Set the current error code to err_code and clear any prior error message. |
| 25511 | ** Also set iSysErrno (by calling sqlite3System) if the err_code indicates |
| 25512 | ** that would be appropriate. |
| 25513 | */ |
| 25514 | SQLITE_PRIVATE void sqlite3Error(sqlite3 *db, int err_code){ |
| 25515 | assert( db!=0 ); |
| 25516 | db->errCode = err_code; |
| 25517 | if( err_code || db->pErr ) sqlite3ErrorFinish(db, err_code); |
| 25518 | } |
| 25519 | |
| 25520 | /* |
| 25521 | ** Load the sqlite3.iSysErrno field if that is an appropriate thing |
| 25522 | ** to do based on the SQLite error code in rc. |
| 25523 | */ |
| 25524 | SQLITE_PRIVATE void sqlite3SystemError(sqlite3 *db, int rc){ |
| 25525 | if( rc==SQLITE_IOERR_NOMEM ) return; |
| 25526 | rc &= 0xff; |
| 25527 | if( rc==SQLITE_CANTOPEN || rc==SQLITE_IOERR ){ |
| 25528 | db->iSysErrno = sqlite3OsGetLastError(db->pVfs); |
| 25529 | } |
| 25530 | } |
| 25531 | |
| 25532 | /* |
| 25533 | ** Set the most recent error code and error string for the sqlite |
| 25534 | ** handle "db". The error code is set to "err_code". |
| @@ -25509,10 +25551,11 @@ | |
| 25551 | ** to NULL. |
| 25552 | */ |
| 25553 | SQLITE_PRIVATE void sqlite3ErrorWithMsg(sqlite3 *db, int err_code, const char *zFormat, ...){ |
| 25554 | assert( db!=0 ); |
| 25555 | db->errCode = err_code; |
| 25556 | sqlite3SystemError(db, err_code); |
| 25557 | if( zFormat==0 ){ |
| 25558 | sqlite3Error(db, err_code); |
| 25559 | }else if( db->pErr || (db->pErr = sqlite3ValueNew(db))!=0 ){ |
| 25560 | char *z; |
| 25561 | va_list ap; |
| @@ -28814,11 +28857,11 @@ | |
| 28857 | rc = osFstat(pFile->h, &buf); |
| 28858 | if( rc!=0 ){ |
| 28859 | sqlite3_log(SQLITE_WARNING, "cannot fstat db file %s", pFile->zPath); |
| 28860 | return; |
| 28861 | } |
| 28862 | if( buf.st_nlink==0 ){ |
| 28863 | sqlite3_log(SQLITE_WARNING, "file unlinked while open: %s", pFile->zPath); |
| 28864 | return; |
| 28865 | } |
| 28866 | if( buf.st_nlink>1 ){ |
| 28867 | sqlite3_log(SQLITE_WARNING, "multiple links to file: %s", pFile->zPath); |
| @@ -33712,27 +33755,22 @@ | |
| 33755 | } |
| 33756 | #else |
| 33757 | # define unixCurrentTime 0 |
| 33758 | #endif |
| 33759 | |
| 33760 | /* |
| 33761 | ** The xGetLastError() method is designed to return a better |
| 33762 | ** low-level error message when operating-system problems come up |
| 33763 | ** during SQLite operation. Only the integer return code is currently |
| 33764 | ** used. |
| 33765 | */ |
| 33766 | static int unixGetLastError(sqlite3_vfs *NotUsed, int NotUsed2, char *NotUsed3){ |
| 33767 | UNUSED_PARAMETER(NotUsed); |
| 33768 | UNUSED_PARAMETER(NotUsed2); |
| 33769 | UNUSED_PARAMETER(NotUsed3); |
| 33770 | return errno; |
| 33771 | } |
| 33772 | |
| 33773 | |
| 33774 | /* |
| 33775 | ************************ End of sqlite3_vfs methods *************************** |
| 33776 | ******************************************************************************/ |
| @@ -40819,12 +40857,14 @@ | |
| 40857 | ** However if an error message is supplied, it will be incorporated |
| 40858 | ** by sqlite into the error message available to the user using |
| 40859 | ** sqlite3_errmsg(), possibly making IO errors easier to debug. |
| 40860 | */ |
| 40861 | static int winGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){ |
| 40862 | DWORD e = osGetLastError(); |
| 40863 | UNUSED_PARAMETER(pVfs); |
| 40864 | if( nBuf>0 ) winGetLastErrorMsg(e, nBuf, zBuf); |
| 40865 | return e; |
| 40866 | } |
| 40867 | |
| 40868 | /* |
| 40869 | ** Initialize and deinitialize the operating system interface. |
| 40870 | */ |
| @@ -66997,11 +67037,11 @@ | |
| 67037 | ** copies are not misused. |
| 67038 | */ |
| 67039 | SQLITE_PRIVATE void sqlite3VdbeMemAboutToChange(Vdbe *pVdbe, Mem *pMem){ |
| 67040 | int i; |
| 67041 | Mem *pX; |
| 67042 | for(i=0, pX=pVdbe->aMem; i<pVdbe->nMem; i++, pX++){ |
| 67043 | if( pX->pScopyFrom==pMem ){ |
| 67044 | pX->flags |= MEM_Undefined; |
| 67045 | pX->pScopyFrom = 0; |
| 67046 | } |
| 67047 | } |
| @@ -69752,11 +69792,11 @@ | |
| 69792 | |
| 69793 | /* Set the magic to VDBE_MAGIC_RUN sooner rather than later. */ |
| 69794 | p->magic = VDBE_MAGIC_RUN; |
| 69795 | |
| 69796 | #ifdef SQLITE_DEBUG |
| 69797 | for(i=0; i<p->nMem; i++){ |
| 69798 | assert( p->aMem[i].db==p->db ); |
| 69799 | } |
| 69800 | #endif |
| 69801 | p->pc = -1; |
| 69802 | p->rc = SQLITE_OK; |
| @@ -69817,20 +69857,17 @@ | |
| 69857 | nCursor = pParse->nTab; |
| 69858 | nArg = pParse->nMaxArg; |
| 69859 | nOnce = pParse->nOnce; |
| 69860 | if( nOnce==0 ) nOnce = 1; /* Ensure at least one byte in p->aOnceFlag[] */ |
| 69861 | |
| 69862 | /* Each cursor uses a memory cell. The first cursor (cursor 0) can |
| 69863 | ** use aMem[0] which is not otherwise used by the VDBE program. Allocate |
| 69864 | ** space at the end of aMem[] for cursors 1 and greater. |
| 69865 | ** See also: allocateCursor(). |
| 69866 | */ |
| 69867 | nMem += nCursor; |
| 69868 | if( nCursor==0 && nMem>0 ) nMem++; /* Space for aMem[0] even if not used */ |
| 69869 | |
| 69870 | /* Figure out how much reusable memory is available at the end of the |
| 69871 | ** opcode array. This extra memory will be reallocated for other elements |
| 69872 | ** of the prepared statement. |
| 69873 | */ |
| @@ -69888,13 +69925,12 @@ | |
| 69925 | p->nzVar = pParse->nzVar; |
| 69926 | p->azVar = pParse->azVar; |
| 69927 | pParse->nzVar = 0; |
| 69928 | pParse->azVar = 0; |
| 69929 | if( p->aMem ){ |
| 69930 | p->nMem = nMem; |
| 69931 | for(n=0; n<nMem; n++){ |
| 69932 | p->aMem[n].flags = MEM_Undefined; |
| 69933 | p->aMem[n].db = db; |
| 69934 | } |
| 69935 | } |
| 69936 | p->explain = pParse->explain; |
| @@ -70000,11 +70036,11 @@ | |
| 70036 | p->nFrame = 0; |
| 70037 | } |
| 70038 | assert( p->nFrame==0 ); |
| 70039 | closeCursorsInFrame(p); |
| 70040 | if( p->aMem ){ |
| 70041 | releaseMemArray(p->aMem, p->nMem); |
| 70042 | } |
| 70043 | while( p->pDelFrame ){ |
| 70044 | VdbeFrame *pDel = p->pDelFrame; |
| 70045 | p->pDelFrame = pDel->pParent; |
| 70046 | sqlite3VdbeFrameDelete(pDel); |
| @@ -70025,11 +70061,11 @@ | |
| 70061 | /* Execute assert() statements to ensure that the Vdbe.apCsr[] and |
| 70062 | ** Vdbe.aMem[] arrays have already been cleaned up. */ |
| 70063 | int i; |
| 70064 | if( p->apCsr ) for(i=0; i<p->nCursor; i++) assert( p->apCsr[i]==0 ); |
| 70065 | if( p->aMem ){ |
| 70066 | for(i=0; i<p->nMem; i++) assert( p->aMem[i].flags==MEM_Undefined ); |
| 70067 | } |
| 70068 | #endif |
| 70069 | |
| 70070 | sqlite3DbFree(db, p->zErrMsg); |
| 70071 | p->zErrMsg = 0; |
| @@ -74506,23 +74542,23 @@ | |
| 74542 | ** |
| 74543 | ** * When using ENABLE_MEMORY_MANAGEMENT, memory cell buffers can |
| 74544 | ** be freed lazily via the sqlite3_release_memory() API. This |
| 74545 | ** minimizes the number of malloc calls made by the system. |
| 74546 | ** |
| 74547 | ** The memory cell for cursor 0 is aMem[0]. The rest are allocated from |
| 74548 | ** the top of the register space. Cursor 1 is at Mem[p->nMem-1]. |
| 74549 | ** Cursor 2 is at Mem[p->nMem-2]. And so forth. |
| 74550 | */ |
| 74551 | Mem *pMem = iCur>0 ? &p->aMem[p->nMem-iCur] : p->aMem; |
| 74552 | |
| 74553 | int nByte; |
| 74554 | VdbeCursor *pCx = 0; |
| 74555 | nByte = |
| 74556 | ROUND8(sizeof(VdbeCursor)) + 2*sizeof(u32)*nField + |
| 74557 | (eCurType==CURTYPE_BTREE?sqlite3BtreeCursorSize():0); |
| 74558 | |
| 74559 | assert( iCur>=0 && iCur<p->nCursor ); |
| 74560 | if( p->apCsr[iCur] ){ |
| 74561 | sqlite3VdbeFreeCursor(p, p->apCsr[iCur]); |
| 74562 | p->apCsr[iCur] = 0; |
| 74563 | } |
| 74564 | if( SQLITE_OK==sqlite3VdbeMemClearAndResize(pMem, nByte) ){ |
| @@ -74932,11 +74968,11 @@ | |
| 74968 | return pOut; |
| 74969 | } |
| 74970 | static Mem *out2Prerelease(Vdbe *p, VdbeOp *pOp){ |
| 74971 | Mem *pOut; |
| 74972 | assert( pOp->p2>0 ); |
| 74973 | assert( pOp->p2<=(p->nMem+1 - p->nCursor) ); |
| 74974 | pOut = &p->aMem[pOp->p2]; |
| 74975 | memAboutToChange(p, pOut); |
| 74976 | if( VdbeMemDynamic(pOut) ){ |
| 74977 | return out2PrereleaseWithClear(pOut); |
| 74978 | }else{ |
| @@ -75070,37 +75106,37 @@ | |
| 75106 | /* Sanity checking on other operands */ |
| 75107 | #ifdef SQLITE_DEBUG |
| 75108 | assert( pOp->opflags==sqlite3OpcodeProperty[pOp->opcode] ); |
| 75109 | if( (pOp->opflags & OPFLG_IN1)!=0 ){ |
| 75110 | assert( pOp->p1>0 ); |
| 75111 | assert( pOp->p1<=(p->nMem+1 - p->nCursor) ); |
| 75112 | assert( memIsValid(&aMem[pOp->p1]) ); |
| 75113 | assert( sqlite3VdbeCheckMemInvariants(&aMem[pOp->p1]) ); |
| 75114 | REGISTER_TRACE(pOp->p1, &aMem[pOp->p1]); |
| 75115 | } |
| 75116 | if( (pOp->opflags & OPFLG_IN2)!=0 ){ |
| 75117 | assert( pOp->p2>0 ); |
| 75118 | assert( pOp->p2<=(p->nMem+1 - p->nCursor) ); |
| 75119 | assert( memIsValid(&aMem[pOp->p2]) ); |
| 75120 | assert( sqlite3VdbeCheckMemInvariants(&aMem[pOp->p2]) ); |
| 75121 | REGISTER_TRACE(pOp->p2, &aMem[pOp->p2]); |
| 75122 | } |
| 75123 | if( (pOp->opflags & OPFLG_IN3)!=0 ){ |
| 75124 | assert( pOp->p3>0 ); |
| 75125 | assert( pOp->p3<=(p->nMem+1 - p->nCursor) ); |
| 75126 | assert( memIsValid(&aMem[pOp->p3]) ); |
| 75127 | assert( sqlite3VdbeCheckMemInvariants(&aMem[pOp->p3]) ); |
| 75128 | REGISTER_TRACE(pOp->p3, &aMem[pOp->p3]); |
| 75129 | } |
| 75130 | if( (pOp->opflags & OPFLG_OUT2)!=0 ){ |
| 75131 | assert( pOp->p2>0 ); |
| 75132 | assert( pOp->p2<=(p->nMem+1 - p->nCursor) ); |
| 75133 | memAboutToChange(p, &aMem[pOp->p2]); |
| 75134 | } |
| 75135 | if( (pOp->opflags & OPFLG_OUT3)!=0 ){ |
| 75136 | assert( pOp->p3>0 ); |
| 75137 | assert( pOp->p3<=(p->nMem+1 - p->nCursor) ); |
| 75138 | memAboutToChange(p, &aMem[pOp->p3]); |
| 75139 | } |
| 75140 | #endif |
| 75141 | #if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE) |
| 75142 | pOrigOp = pOp; |
| @@ -75195,11 +75231,11 @@ | |
| 75231 | ** |
| 75232 | ** Write the current address onto register P1 |
| 75233 | ** and then jump to address P2. |
| 75234 | */ |
| 75235 | case OP_Gosub: { /* jump */ |
| 75236 | assert( pOp->p1>0 && pOp->p1<=(p->nMem+1 - p->nCursor) ); |
| 75237 | pIn1 = &aMem[pOp->p1]; |
| 75238 | assert( VdbeMemDynamic(pIn1)==0 ); |
| 75239 | memAboutToChange(p, pIn1); |
| 75240 | pIn1->flags = MEM_Int; |
| 75241 | pIn1->u.i = (int)(pOp-aOp); |
| @@ -75235,11 +75271,11 @@ | |
| 75271 | ** address P2. |
| 75272 | ** |
| 75273 | ** See also: EndCoroutine |
| 75274 | */ |
| 75275 | case OP_InitCoroutine: { /* jump */ |
| 75276 | assert( pOp->p1>0 && pOp->p1<=(p->nMem+1 - p->nCursor) ); |
| 75277 | assert( pOp->p2>=0 && pOp->p2<p->nOp ); |
| 75278 | assert( pOp->p3>=0 && pOp->p3<p->nOp ); |
| 75279 | pOut = &aMem[pOp->p1]; |
| 75280 | assert( !VdbeMemDynamic(pOut) ); |
| 75281 | pOut->u.i = pOp->p3 - 1; |
| @@ -75504,11 +75540,11 @@ | |
| 75540 | pOut->enc = encoding; |
| 75541 | UPDATE_MAX_BLOBSIZE(pOut); |
| 75542 | #ifndef SQLITE_LIKE_DOESNT_MATCH_BLOBS |
| 75543 | if( pOp->p5 ){ |
| 75544 | assert( pOp->p3>0 ); |
| 75545 | assert( pOp->p3<=(p->nMem+1 - p->nCursor) ); |
| 75546 | pIn3 = &aMem[pOp->p3]; |
| 75547 | assert( pIn3->flags & MEM_Int ); |
| 75548 | if( pIn3->u.i ) pOut->flags = MEM_Blob|MEM_Static|MEM_Term; |
| 75549 | } |
| 75550 | #endif |
| @@ -75530,11 +75566,11 @@ | |
| 75566 | case OP_Null: { /* out2 */ |
| 75567 | int cnt; |
| 75568 | u16 nullFlag; |
| 75569 | pOut = out2Prerelease(p, pOp); |
| 75570 | cnt = pOp->p3-pOp->p2; |
| 75571 | assert( pOp->p3<=(p->nMem+1 - p->nCursor) ); |
| 75572 | pOut->flags = nullFlag = pOp->p1 ? (MEM_Null|MEM_Cleared) : MEM_Null; |
| 75573 | while( cnt>0 ){ |
| 75574 | pOut++; |
| 75575 | memAboutToChange(p, pOut); |
| 75576 | sqlite3VdbeMemSetNull(pOut); |
| @@ -75551,11 +75587,11 @@ | |
| 75587 | ** instruction, but do not free any string or blob memory associated with |
| 75588 | ** the register, so that if the value was a string or blob that was |
| 75589 | ** previously copied using OP_SCopy, the copies will continue to be valid. |
| 75590 | */ |
| 75591 | case OP_SoftNull: { |
| 75592 | assert( pOp->p1>0 && pOp->p1<=(p->nMem+1 - p->nCursor) ); |
| 75593 | pOut = &aMem[pOp->p1]; |
| 75594 | pOut->flags = (pOut->flags|MEM_Null)&~MEM_Undefined; |
| 75595 | break; |
| 75596 | } |
| 75597 | |
| @@ -75618,12 +75654,12 @@ | |
| 75654 | assert( p1+n<=p2 || p2+n<=p1 ); |
| 75655 | |
| 75656 | pIn1 = &aMem[p1]; |
| 75657 | pOut = &aMem[p2]; |
| 75658 | do{ |
| 75659 | assert( pOut<=&aMem[(p->nMem+1 - p->nCursor)] ); |
| 75660 | assert( pIn1<=&aMem[(p->nMem+1 - p->nCursor)] ); |
| 75661 | assert( memIsValid(pIn1) ); |
| 75662 | memAboutToChange(p, pOut); |
| 75663 | sqlite3VdbeMemMove(pOut, pIn1); |
| 75664 | #ifdef SQLITE_DEBUG |
| 75665 | if( pOut->pScopyFrom>=&aMem[p1] && pOut->pScopyFrom<pOut ){ |
| @@ -75719,11 +75755,11 @@ | |
| 75755 | case OP_ResultRow: { |
| 75756 | Mem *pMem; |
| 75757 | int i; |
| 75758 | assert( p->nResColumn==pOp->p2 ); |
| 75759 | assert( pOp->p1>0 ); |
| 75760 | assert( pOp->p1+pOp->p2<=(p->nMem+1 - p->nCursor)+1 ); |
| 75761 | |
| 75762 | #ifndef SQLITE_OMIT_PROGRESS_CALLBACK |
| 75763 | /* Run the progress counter just before returning. |
| 75764 | */ |
| 75765 | if( db->xProgress!=0 |
| @@ -76031,12 +76067,12 @@ | |
| 76067 | int n; |
| 76068 | sqlite3_context *pCtx; |
| 76069 | |
| 76070 | assert( pOp->p4type==P4_FUNCDEF ); |
| 76071 | n = pOp->p5; |
| 76072 | assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) ); |
| 76073 | assert( n==0 || (pOp->p2>0 && pOp->p2+n<=(p->nMem+1 - p->nCursor)+1) ); |
| 76074 | assert( pOp->p3<pOp->p2 || pOp->p3>=pOp->p2+n ); |
| 76075 | pCtx = sqlite3DbMallocRawNN(db, sizeof(*pCtx) + (n-1)*sizeof(sqlite3_value*)); |
| 76076 | if( pCtx==0 ) goto no_mem; |
| 76077 | pCtx->pOut = 0; |
| 76078 | pCtx->pFunc = pOp->p4.pFunc; |
| @@ -76532,15 +76568,15 @@ | |
| 76568 | p2 = pOp->p2; |
| 76569 | #if SQLITE_DEBUG |
| 76570 | if( aPermute ){ |
| 76571 | int k, mx = 0; |
| 76572 | for(k=0; k<n; k++) if( aPermute[k]>mx ) mx = aPermute[k]; |
| 76573 | assert( p1>0 && p1+mx<=(p->nMem+1 - p->nCursor)+1 ); |
| 76574 | assert( p2>0 && p2+mx<=(p->nMem+1 - p->nCursor)+1 ); |
| 76575 | }else{ |
| 76576 | assert( p1>0 && p1+n<=(p->nMem+1 - p->nCursor)+1 ); |
| 76577 | assert( p2>0 && p2+n<=(p->nMem+1 - p->nCursor)+1 ); |
| 76578 | } |
| 76579 | #endif /* SQLITE_DEBUG */ |
| 76580 | for(i=0; i<n; i++){ |
| 76581 | idx = aPermute ? aPermute[i] : i; |
| 76582 | assert( memIsValid(&aMem[p1+idx]) ); |
| @@ -76798,11 +76834,11 @@ | |
| 76834 | p2 = pOp->p2; |
| 76835 | |
| 76836 | /* If the cursor cache is stale, bring it up-to-date */ |
| 76837 | rc = sqlite3VdbeCursorMoveto(&pC, &p2); |
| 76838 | |
| 76839 | assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) ); |
| 76840 | pDest = &aMem[pOp->p3]; |
| 76841 | memAboutToChange(p, pDest); |
| 76842 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 76843 | assert( pC!=0 ); |
| 76844 | assert( p2<pC->nField ); |
| @@ -77041,11 +77077,11 @@ | |
| 77077 | zAffinity = pOp->p4.z; |
| 77078 | assert( zAffinity!=0 ); |
| 77079 | assert( zAffinity[pOp->p2]==0 ); |
| 77080 | pIn1 = &aMem[pOp->p1]; |
| 77081 | while( (cAff = *(zAffinity++))!=0 ){ |
| 77082 | assert( pIn1 <= &p->aMem[(p->nMem+1 - p->nCursor)] ); |
| 77083 | assert( memIsValid(pIn1) ); |
| 77084 | applyAffinity(pIn1, cAff, encoding); |
| 77085 | pIn1++; |
| 77086 | } |
| 77087 | break; |
| @@ -77103,11 +77139,11 @@ | |
| 77139 | nData = 0; /* Number of bytes of data space */ |
| 77140 | nHdr = 0; /* Number of bytes of header space */ |
| 77141 | nZero = 0; /* Number of zero bytes at the end of the record */ |
| 77142 | nField = pOp->p1; |
| 77143 | zAffinity = pOp->p4.z; |
| 77144 | assert( nField>0 && pOp->p2>0 && pOp->p2+nField<=(p->nMem+1 - p->nCursor)+1 ); |
| 77145 | pData0 = &aMem[nField]; |
| 77146 | nField = pOp->p2; |
| 77147 | pLast = &pData0[nField-1]; |
| 77148 | file_format = p->minWriteFileFormat; |
| 77149 | |
| @@ -77193,11 +77229,11 @@ | |
| 77229 | j += sqlite3VdbeSerialPut(&zNewRecord[j], pRec, serial_type); /* content */ |
| 77230 | }while( (++pRec)<=pLast ); |
| 77231 | assert( i==nHdr ); |
| 77232 | assert( j==nByte ); |
| 77233 | |
| 77234 | assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) ); |
| 77235 | pOut->n = (int)nByte; |
| 77236 | pOut->flags = MEM_Blob; |
| 77237 | if( nZero ){ |
| 77238 | pOut->u.nZero = nZero; |
| 77239 | pOut->flags |= MEM_Zero; |
| @@ -77779,11 +77815,11 @@ | |
| 77815 | }else{ |
| 77816 | wrFlag = 0; |
| 77817 | } |
| 77818 | if( pOp->p5 & OPFLAG_P2ISREG ){ |
| 77819 | assert( p2>0 ); |
| 77820 | assert( p2<=(p->nMem+1 - p->nCursor) ); |
| 77821 | pIn2 = &aMem[p2]; |
| 77822 | assert( memIsValid(pIn2) ); |
| 77823 | assert( (pIn2->flags & MEM_Int)!=0 ); |
| 77824 | sqlite3VdbeMemIntegerify(pIn2); |
| 77825 | p2 = (int)pIn2->u.i; |
| @@ -78574,11 +78610,11 @@ | |
| 78610 | /* Assert that P3 is a valid memory cell. */ |
| 78611 | assert( pOp->p3<=pFrame->nMem ); |
| 78612 | pMem = &pFrame->aMem[pOp->p3]; |
| 78613 | }else{ |
| 78614 | /* Assert that P3 is a valid memory cell. */ |
| 78615 | assert( pOp->p3<=(p->nMem+1 - p->nCursor) ); |
| 78616 | pMem = &aMem[pOp->p3]; |
| 78617 | memAboutToChange(p, pMem); |
| 78618 | } |
| 78619 | assert( memIsValid(pMem) ); |
| 78620 | |
| @@ -79350,11 +79386,11 @@ | |
| 79386 | BtCursor *pCrsr; |
| 79387 | int res; |
| 79388 | UnpackedRecord r; |
| 79389 | |
| 79390 | assert( pOp->p3>0 ); |
| 79391 | assert( pOp->p2>0 && pOp->p2+pOp->p3<=(p->nMem+1 - p->nCursor)+1 ); |
| 79392 | assert( pOp->p1>=0 && pOp->p1<p->nCursor ); |
| 79393 | pC = p->apCsr[pOp->p1]; |
| 79394 | assert( pC!=0 ); |
| 79395 | assert( pC->eCurType==CURTYPE_BTREE ); |
| 79396 | pCrsr = pC->uc.pCursor; |
| @@ -79856,11 +79892,11 @@ | |
| 79892 | assert( p->bIsReader ); |
| 79893 | nRoot = pOp->p2; |
| 79894 | aRoot = pOp->p4.ai; |
| 79895 | assert( nRoot>0 ); |
| 79896 | assert( aRoot[nRoot]==0 ); |
| 79897 | assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) ); |
| 79898 | pnErr = &aMem[pOp->p3]; |
| 79899 | assert( (pnErr->flags & MEM_Int)!=0 ); |
| 79900 | assert( (pnErr->flags & (MEM_Str|MEM_Blob))==0 ); |
| 79901 | pIn1 = &aMem[pOp->p1]; |
| 79902 | assert( pOp->p5<db->nDb ); |
| @@ -80046,10 +80082,12 @@ | |
| 80082 | ** program stored in SubProgram.aOp. As well as these, one memory |
| 80083 | ** cell is required for each cursor used by the program. Set local |
| 80084 | ** variable nMem (and later, VdbeFrame.nChildMem) to this value. |
| 80085 | */ |
| 80086 | nMem = pProgram->nMem + pProgram->nCsr; |
| 80087 | assert( nMem>0 ); |
| 80088 | if( pProgram->nCsr==0 ) nMem++; |
| 80089 | nByte = ROUND8(sizeof(VdbeFrame)) |
| 80090 | + nMem * sizeof(Mem) |
| 80091 | + pProgram->nCsr * sizeof(VdbeCursor *) |
| 80092 | + pProgram->nOnce * sizeof(u8); |
| 80093 | pFrame = sqlite3DbMallocZero(db, nByte); |
| @@ -80082,11 +80120,12 @@ | |
| 80120 | pMem->flags = MEM_Undefined; |
| 80121 | pMem->db = db; |
| 80122 | } |
| 80123 | }else{ |
| 80124 | pFrame = pRt->u.pFrame; |
| 80125 | assert( pProgram->nMem+pProgram->nCsr==pFrame->nChildMem |
| 80126 | || (pProgram->nCsr==0 && pProgram->nMem+1==pFrame->nChildMem) ); |
| 80127 | assert( pProgram->nCsr==pFrame->nChildCsr ); |
| 80128 | assert( (int)(pOp - aOp)==pFrame->pc ); |
| 80129 | } |
| 80130 | |
| 80131 | p->nFrame++; |
| @@ -80097,14 +80136,14 @@ | |
| 80136 | assert( pFrame->pAuxData==0 ); |
| 80137 | pFrame->pAuxData = p->pAuxData; |
| 80138 | p->pAuxData = 0; |
| 80139 | p->nChange = 0; |
| 80140 | p->pFrame = pFrame; |
| 80141 | p->aMem = aMem = VdbeFrameMem(pFrame); |
| 80142 | p->nMem = pFrame->nChildMem; |
| 80143 | p->nCursor = (u16)pFrame->nChildCsr; |
| 80144 | p->apCsr = (VdbeCursor **)&aMem[p->nMem]; |
| 80145 | p->aOp = aOp = pProgram->aOp; |
| 80146 | p->nOp = pProgram->nOp; |
| 80147 | p->aOnceFlag = (u8 *)&p->apCsr[p->nCursor]; |
| 80148 | p->nOnceFlag = pProgram->nOnce; |
| 80149 | #ifdef SQLITE_ENABLE_STMT_SCANSTATUS |
| @@ -80346,12 +80385,12 @@ | |
| 80385 | int n; |
| 80386 | sqlite3_context *pCtx; |
| 80387 | |
| 80388 | assert( pOp->p4type==P4_FUNCDEF ); |
| 80389 | n = pOp->p5; |
| 80390 | assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) ); |
| 80391 | assert( n==0 || (pOp->p2>0 && pOp->p2+n<=(p->nMem+1 - p->nCursor)+1) ); |
| 80392 | assert( pOp->p3<pOp->p2 || pOp->p3>=pOp->p2+n ); |
| 80393 | pCtx = sqlite3DbMallocRawNN(db, sizeof(*pCtx) + (n-1)*sizeof(sqlite3_value*)); |
| 80394 | if( pCtx==0 ) goto no_mem; |
| 80395 | pCtx->pMem = 0; |
| 80396 | pCtx->pFunc = pOp->p4.pFunc; |
| @@ -80426,11 +80465,11 @@ | |
| 80465 | ** P4 argument is only needed for the degenerate case where |
| 80466 | ** the step function was not previously called. |
| 80467 | */ |
| 80468 | case OP_AggFinal: { |
| 80469 | Mem *pMem; |
| 80470 | assert( pOp->p1>0 && pOp->p1<=(p->nMem+1 - p->nCursor) ); |
| 80471 | pMem = &aMem[pOp->p1]; |
| 80472 | assert( (pMem->flags & ~(MEM_Null|MEM_Agg))==0 ); |
| 80473 | rc = sqlite3VdbeMemFinalize(pMem, pOp->p4.pFunc); |
| 80474 | if( rc ){ |
| 80475 | sqlite3VdbeError(p, "%s", sqlite3_value_text(pMem)); |
| @@ -80868,11 +80907,11 @@ | |
| 80907 | Mem *pDest; |
| 80908 | sqlite3_context sContext; |
| 80909 | |
| 80910 | VdbeCursor *pCur = p->apCsr[pOp->p1]; |
| 80911 | assert( pCur->eCurType==CURTYPE_VTAB ); |
| 80912 | assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) ); |
| 80913 | pDest = &aMem[pOp->p3]; |
| 80914 | memAboutToChange(p, pDest); |
| 80915 | if( pCur->nullRow ){ |
| 80916 | sqlite3VdbeMemSetNull(pDest); |
| 80917 | break; |
| @@ -81226,10 +81265,11 @@ | |
| 81265 | assert( rc ); |
| 81266 | if( p->zErrMsg==0 && rc!=SQLITE_IOERR_NOMEM ){ |
| 81267 | sqlite3VdbeError(p, "%s", sqlite3ErrStr(rc)); |
| 81268 | } |
| 81269 | p->rc = rc; |
| 81270 | sqlite3SystemError(db, rc); |
| 81271 | testcase( sqlite3GlobalConfig.xLog!=0 ); |
| 81272 | sqlite3_log(rc, "statement aborts at %d: [%s] %s", |
| 81273 | (int)(pOp - aOp), p->zSql, p->zErrMsg); |
| 81274 | sqlite3VdbeHalt(p); |
| 81275 | if( rc==SQLITE_IOERR_NOMEM ) sqlite3OomFault(db); |
| @@ -106052,10 +106092,12 @@ | |
| 106092 | void (*result_subtype)(sqlite3_context*,unsigned int); |
| 106093 | /* Version 3.10.0 and later */ |
| 106094 | int (*status64)(int,sqlite3_int64*,sqlite3_int64*,int); |
| 106095 | int (*strlike)(const char*,const char*,unsigned int); |
| 106096 | int (*db_cacheflush)(sqlite3*); |
| 106097 | /* Version 3.12.0 and later */ |
| 106098 | int (*system_errno)(sqlite3*); |
| 106099 | }; |
| 106100 | |
| 106101 | /* |
| 106102 | ** The following macros redefine the API routines so that they are |
| 106103 | ** redirected through the global sqlite3_api structure. |
| @@ -106295,10 +106337,12 @@ | |
| 106337 | #define sqlite3_result_subtype sqlite3_api->result_subtype |
| 106338 | /* Version 3.10.0 and later */ |
| 106339 | #define sqlite3_status64 sqlite3_api->status64 |
| 106340 | #define sqlite3_strlike sqlite3_api->strlike |
| 106341 | #define sqlite3_db_cacheflush sqlite3_api->db_cacheflush |
| 106342 | /* Version 3.12.0 and later */ |
| 106343 | #define sqlite3_system_errno sqlite3_api->system_errno |
| 106344 | #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */ |
| 106345 | |
| 106346 | #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) |
| 106347 | /* This case when the file really is being compiled as a loadable |
| 106348 | ** extension */ |
| @@ -106713,11 +106757,13 @@ | |
| 106757 | sqlite3_value_subtype, |
| 106758 | sqlite3_result_subtype, |
| 106759 | /* Version 3.10.0 and later */ |
| 106760 | sqlite3_status64, |
| 106761 | sqlite3_strlike, |
| 106762 | sqlite3_db_cacheflush, |
| 106763 | /* Version 3.12.0 and later */ |
| 106764 | sqlite3_system_errno |
| 106765 | }; |
| 106766 | |
| 106767 | /* |
| 106768 | ** Attempt to load an SQLite extension library contained in the file |
| 106769 | ** zFile. The entry point is zProc. zProc may be 0 in which case a |
| @@ -135359,10 +135405,13 @@ | |
| 135405 | if( !db || db->mallocFailed ){ |
| 135406 | return SQLITE_NOMEM_BKPT; |
| 135407 | } |
| 135408 | return db->errCode; |
| 135409 | } |
| 135410 | SQLITE_API int SQLITE_STDCALL sqlite3_system_errno(sqlite3 *db){ |
| 135411 | return db ? db->iSysErrno : 0; |
| 135412 | } |
| 135413 | |
| 135414 | /* |
| 135415 | ** Return a string that describes the kind of error specified in the |
| 135416 | ** argument. For now, this simply calls the internal sqlite3ErrStr() |
| 135417 | ** function. |
| @@ -161345,10 +161394,52 @@ | |
| 161394 | ** updates) that have been performed on the target database since the |
| 161395 | ** current RBU update was started. |
| 161396 | */ |
| 161397 | SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3rbu_progress(sqlite3rbu *pRbu); |
| 161398 | |
| 161399 | /* |
| 161400 | ** Obtain permyriadage (permyriadage is to 10000 as percentage is to 100) |
| 161401 | ** progress indications for the two stages of an RBU update. This API may |
| 161402 | ** be useful for driving GUI progress indicators and similar. |
| 161403 | ** |
| 161404 | ** An RBU update is divided into two stages: |
| 161405 | ** |
| 161406 | ** * Stage 1, in which changes are accumulated in an oal/wal file, and |
| 161407 | ** * Stage 2, in which the contents of the wal file are copied into the |
| 161408 | ** main database. |
| 161409 | ** |
| 161410 | ** The update is visible to non-RBU clients during stage 2. During stage 1 |
| 161411 | ** non-RBU reader clients may see the original database. |
| 161412 | ** |
| 161413 | ** If this API is called during stage 2 of the update, output variable |
| 161414 | ** (*pnOne) is set to 10000 to indicate that stage 1 has finished and (*pnTwo) |
| 161415 | ** to a value between 0 and 10000 to indicate the permyriadage progress of |
| 161416 | ** stage 2. A value of 5000 indicates that stage 2 is half finished, |
| 161417 | ** 9000 indicates that it is 90% finished, and so on. |
| 161418 | ** |
| 161419 | ** If this API is called during stage 1 of the update, output variable |
| 161420 | ** (*pnTwo) is set to 0 to indicate that stage 2 has not yet started. The |
| 161421 | ** value to which (*pnOne) is set depends on whether or not the RBU |
| 161422 | ** database contains an "rbu_count" table. The rbu_count table, if it |
| 161423 | ** exists, must contain the same columns as the following: |
| 161424 | ** |
| 161425 | ** CREATE TABLE rbu_count(tbl TEXT PRIMARY KEY, cnt INTEGER) WITHOUT ROWID; |
| 161426 | ** |
| 161427 | ** There must be one row in the table for each source (data_xxx) table within |
| 161428 | ** the RBU database. The 'tbl' column should contain the name of the source |
| 161429 | ** table. The 'cnt' column should contain the number of rows within the |
| 161430 | ** source table. |
| 161431 | ** |
| 161432 | ** If the rbu_count table is present and populated correctly and this |
| 161433 | ** API is called during stage 1, the *pnOne output variable is set to the |
| 161434 | ** permyriadage progress of the same stage. If the rbu_count table does |
| 161435 | ** not exist, then (*pnOne) is set to -1 during stage 1. If the rbu_count |
| 161436 | ** table exists but is not correctly populated, the value of the *pnOne |
| 161437 | ** output variable during stage 1 is undefined. |
| 161438 | */ |
| 161439 | SQLITE_API void SQLITE_STDCALL sqlite3rbu_bp_progress(sqlite3rbu *pRbu, int *pnOne, int *pnTwo); |
| 161440 | |
| 161441 | /* |
| 161442 | ** Create an RBU VFS named zName that accesses the underlying file-system |
| 161443 | ** via existing VFS zParent. Or, if the zParent parameter is passed NULL, |
| 161444 | ** then the new RBU VFS uses the default system VFS to access the file-system. |
| 161445 | ** The new object is registered as a non-default VFS with SQLite before |
| @@ -161466,18 +161557,19 @@ | |
| 161557 | ** target db file. |
| 161558 | ** |
| 161559 | ** RBU_STATE_OALSZ: |
| 161560 | ** Valid if STAGE==1. The size in bytes of the *-oal file. |
| 161561 | */ |
| 161562 | #define RBU_STATE_STAGE 1 |
| 161563 | #define RBU_STATE_TBL 2 |
| 161564 | #define RBU_STATE_IDX 3 |
| 161565 | #define RBU_STATE_ROW 4 |
| 161566 | #define RBU_STATE_PROGRESS 5 |
| 161567 | #define RBU_STATE_CKPT 6 |
| 161568 | #define RBU_STATE_COOKIE 7 |
| 161569 | #define RBU_STATE_OALSZ 8 |
| 161570 | #define RBU_STATE_PHASEONESTEP 9 |
| 161571 | |
| 161572 | #define RBU_STAGE_OAL 1 |
| 161573 | #define RBU_STAGE_MOVE 2 |
| 161574 | #define RBU_STAGE_CAPTURE 3 |
| 161575 | #define RBU_STAGE_CKPT 4 |
| @@ -161519,10 +161611,11 @@ | |
| 161611 | i64 iWalCksum; |
| 161612 | int nRow; |
| 161613 | i64 nProgress; |
| 161614 | u32 iCookie; |
| 161615 | i64 iOalSz; |
| 161616 | i64 nPhaseOneStep; |
| 161617 | }; |
| 161618 | |
| 161619 | struct RbuUpdateStmt { |
| 161620 | char *zMask; /* Copy of update mask used with pUpdate */ |
| 161621 | sqlite3_stmt *pUpdate; /* Last update statement (or NULL) */ |
| @@ -161563,10 +161656,11 @@ | |
| 161656 | const char *zDataTbl; /* Name of rbu db table (or null) */ |
| 161657 | const char *zIdx; /* Name of target db index (or null) */ |
| 161658 | int iTnum; /* Root page of current object */ |
| 161659 | int iPkTnum; /* If eType==EXTERNAL, root of PK index */ |
| 161660 | int bUnique; /* Current index is unique */ |
| 161661 | int nIndex; /* Number of aux. indexes on table zTbl */ |
| 161662 | |
| 161663 | /* Statements created by rbuObjIterPrepareAll() */ |
| 161664 | int nCol; /* Number of columns in current object */ |
| 161665 | sqlite3_stmt *pSelect; /* Source data */ |
| 161666 | sqlite3_stmt *pInsert; /* Statement for INSERT operations */ |
| @@ -161616,10 +161710,47 @@ | |
| 161710 | u32 iWalFrame; |
| 161711 | }; |
| 161712 | |
| 161713 | /* |
| 161714 | ** RBU handle. |
| 161715 | ** |
| 161716 | ** nPhaseOneStep: |
| 161717 | ** If the RBU database contains an rbu_count table, this value is set to |
| 161718 | ** a running estimate of the number of b-tree operations required to |
| 161719 | ** finish populating the *-oal file. This allows the sqlite3_bp_progress() |
| 161720 | ** API to calculate the permyriadage progress of populating the *-oal file |
| 161721 | ** using the formula: |
| 161722 | ** |
| 161723 | ** permyriadage = (10000 * nProgress) / nPhaseOneStep |
| 161724 | ** |
| 161725 | ** nPhaseOneStep is initialized to the sum of: |
| 161726 | ** |
| 161727 | ** nRow * (nIndex + 1) |
| 161728 | ** |
| 161729 | ** for all source tables in the RBU database, where nRow is the number |
| 161730 | ** of rows in the source table and nIndex the number of indexes on the |
| 161731 | ** corresponding target database table. |
| 161732 | ** |
| 161733 | ** This estimate is accurate if the RBU update consists entirely of |
| 161734 | ** INSERT operations. However, it is inaccurate if: |
| 161735 | ** |
| 161736 | ** * the RBU update contains any UPDATE operations. If the PK specified |
| 161737 | ** for an UPDATE operation does not exist in the target table, then |
| 161738 | ** no b-tree operations are required on index b-trees. Or if the |
| 161739 | ** specified PK does exist, then (nIndex*2) such operations are |
| 161740 | ** required (one delete and one insert on each index b-tree). |
| 161741 | ** |
| 161742 | ** * the RBU update contains any DELETE operations for which the specified |
| 161743 | ** PK does not exist. In this case no operations are required on index |
| 161744 | ** b-trees. |
| 161745 | ** |
| 161746 | ** * the RBU update contains REPLACE operations. These are similar to |
| 161747 | ** UPDATE operations. |
| 161748 | ** |
| 161749 | ** nPhaseOneStep is updated to account for the conditions above during the |
| 161750 | ** first pass of each source table. The updated nPhaseOneStep value is |
| 161751 | ** stored in the rbu_state table if the RBU update is suspended. |
| 161752 | */ |
| 161753 | struct sqlite3rbu { |
| 161754 | int eStage; /* Value of RBU_STATE_STAGE field */ |
| 161755 | sqlite3 *dbMain; /* target database handle */ |
| 161756 | sqlite3 *dbRbu; /* rbu database handle */ |
| @@ -161633,10 +161764,11 @@ | |
| 161764 | int nProgress; /* Rows processed for all objects */ |
| 161765 | RbuObjIter objiter; /* Iterator for skipping through tbl/idx */ |
| 161766 | const char *zVfsName; /* Name of automatically created rbu vfs */ |
| 161767 | rbu_file *pTargetFd; /* File handle open on target db */ |
| 161768 | i64 iOalSz; |
| 161769 | i64 nPhaseOneStep; |
| 161770 | |
| 161771 | /* The following state variables are used as part of the incremental |
| 161772 | ** checkpoint stage (eStage==RBU_STAGE_CKPT). See comments surrounding |
| 161773 | ** function rbuSetupCheckpoint() for details. */ |
| 161774 | u32 iMaxFrame; /* Largest iWalFrame value in aFrame[] */ |
| @@ -162463,10 +162595,11 @@ | |
| 162595 | p->rc = prepareFreeAndCollectError(p->dbMain, &pList, &p->zErrmsg, |
| 162596 | sqlite3_mprintf("PRAGMA main.index_list = %Q", pIter->zTbl) |
| 162597 | ); |
| 162598 | } |
| 162599 | |
| 162600 | pIter->nIndex = 0; |
| 162601 | while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pList) ){ |
| 162602 | const char *zIdx = (const char*)sqlite3_column_text(pList, 1); |
| 162603 | sqlite3_stmt *pXInfo = 0; |
| 162604 | if( zIdx==0 ) break; |
| 162605 | p->rc = prepareFreeAndCollectError(p->dbMain, &pXInfo, &p->zErrmsg, |
| @@ -162476,10 +162609,16 @@ | |
| 162609 | int iCid = sqlite3_column_int(pXInfo, 1); |
| 162610 | if( iCid>=0 ) pIter->abIndexed[iCid] = 1; |
| 162611 | } |
| 162612 | rbuFinalize(p, pXInfo); |
| 162613 | bIndex = 1; |
| 162614 | pIter->nIndex++; |
| 162615 | } |
| 162616 | |
| 162617 | if( pIter->eType==RBU_PK_WITHOUT_ROWID ){ |
| 162618 | /* "PRAGMA index_list" includes the main PK b-tree */ |
| 162619 | pIter->nIndex--; |
| 162620 | } |
| 162621 | |
| 162622 | rbuFinalize(p, pList); |
| 162623 | if( bIndex==0 ) pIter->abIndexed = 0; |
| 162624 | } |
| @@ -162589,10 +162728,11 @@ | |
| 162728 | } |
| 162729 | |
| 162730 | rbuFinalize(p, pStmt); |
| 162731 | rbuObjIterCacheIndexedCols(p, pIter); |
| 162732 | assert( pIter->eType!=RBU_PK_VTAB || pIter->abIndexed==0 ); |
| 162733 | assert( pIter->eType!=RBU_PK_VTAB || pIter->nIndex==0 ); |
| 162734 | } |
| 162735 | |
| 162736 | return p->rc; |
| 162737 | } |
| 162738 | |
| @@ -163141,10 +163281,18 @@ | |
| 163281 | sqlite3_value **apVal |
| 163282 | ){ |
| 163283 | sqlite3rbu *p = sqlite3_user_data(pCtx); |
| 163284 | int rc = SQLITE_OK; |
| 163285 | int i; |
| 163286 | |
| 163287 | assert( sqlite3_value_int(apVal[0])!=0 |
| 163288 | || p->objiter.eType==RBU_PK_EXTERNAL |
| 163289 | || p->objiter.eType==RBU_PK_NONE |
| 163290 | ); |
| 163291 | if( sqlite3_value_int(apVal[0])!=0 ){ |
| 163292 | p->nPhaseOneStep += p->objiter.nIndex; |
| 163293 | } |
| 163294 | |
| 163295 | for(i=0; rc==SQLITE_OK && i<nVal; i++){ |
| 163296 | rc = sqlite3_bind_value(p->objiter.pTmpInsert, i+1, apVal[i]); |
| 163297 | } |
| 163298 | if( rc==SQLITE_OK ){ |
| @@ -163886,10 +164034,21 @@ | |
| 164034 | sqlite3_stmt *pWriter; |
| 164035 | int i; |
| 164036 | |
| 164037 | assert( p->rc==SQLITE_OK ); |
| 164038 | assert( eType!=RBU_DELETE || pIter->zIdx==0 ); |
| 164039 | assert( eType==RBU_DELETE || eType==RBU_IDX_DELETE |
| 164040 | || eType==RBU_INSERT || eType==RBU_IDX_INSERT |
| 164041 | ); |
| 164042 | |
| 164043 | /* If this is a delete, decrement nPhaseOneStep by nIndex. If the DELETE |
| 164044 | ** statement below does actually delete a row, nPhaseOneStep will be |
| 164045 | ** incremented by the same amount when SQL function rbu_tmp_insert() |
| 164046 | ** is invoked by the trigger. */ |
| 164047 | if( eType==RBU_DELETE ){ |
| 164048 | p->nPhaseOneStep -= p->objiter.nIndex; |
| 164049 | } |
| 164050 | |
| 164051 | if( eType==RBU_IDX_DELETE || eType==RBU_DELETE ){ |
| 164052 | pWriter = pIter->pDelete; |
| 164053 | }else{ |
| 164054 | pWriter = pIter->pInsert; |
| @@ -163957,24 +164116,28 @@ | |
| 164116 | || eType==RBU_REPLACE || eType==RBU_IDX_DELETE |
| 164117 | || eType==RBU_IDX_INSERT || eType==RBU_UPDATE |
| 164118 | ); |
| 164119 | assert( eType!=RBU_UPDATE || pIter->zIdx==0 ); |
| 164120 | |
| 164121 | if( pIter->zIdx==0 && (eType==RBU_IDX_DELETE || eType==RBU_IDX_INSERT) ){ |
| 164122 | rbuBadControlError(p); |
| 164123 | } |
| 164124 | else if( eType==RBU_REPLACE ){ |
| 164125 | if( pIter->zIdx==0 ){ |
| 164126 | p->nPhaseOneStep += p->objiter.nIndex; |
| 164127 | rbuStepOneOp(p, RBU_DELETE); |
| 164128 | } |
| 164129 | if( p->rc==SQLITE_OK ) rbuStepOneOp(p, RBU_INSERT); |
| 164130 | } |
| 164131 | else if( eType!=RBU_UPDATE ){ |
| 164132 | rbuStepOneOp(p, eType); |
| 164133 | } |
| 164134 | else{ |
| 164135 | sqlite3_value *pVal; |
| 164136 | sqlite3_stmt *pUpdate = 0; |
| 164137 | assert( eType==RBU_UPDATE ); |
| 164138 | p->nPhaseOneStep -= p->objiter.nIndex; |
| 164139 | rbuGetUpdateStmt(p, pIter, zMask, &pUpdate); |
| 164140 | if( pUpdate ){ |
| 164141 | int i; |
| 164142 | for(i=0; p->rc==SQLITE_OK && i<pIter->nCol; i++){ |
| 164143 | char c = zMask[pIter->aiSrcOrder[i]]; |
| @@ -164048,20 +164211,22 @@ | |
| 164211 | "(%d, %Q), " |
| 164212 | "(%d, %d), " |
| 164213 | "(%d, %d), " |
| 164214 | "(%d, %lld), " |
| 164215 | "(%d, %lld), " |
| 164216 | "(%d, %lld), " |
| 164217 | "(%d, %lld) ", |
| 164218 | p->zStateDb, |
| 164219 | RBU_STATE_STAGE, eStage, |
| 164220 | RBU_STATE_TBL, p->objiter.zTbl, |
| 164221 | RBU_STATE_IDX, p->objiter.zIdx, |
| 164222 | RBU_STATE_ROW, p->nStep, |
| 164223 | RBU_STATE_PROGRESS, p->nProgress, |
| 164224 | RBU_STATE_CKPT, p->iWalCksum, |
| 164225 | RBU_STATE_COOKIE, (i64)p->pTargetFd->iCookie, |
| 164226 | RBU_STATE_OALSZ, p->iOalSz, |
| 164227 | RBU_STATE_PHASEONESTEP, p->nPhaseOneStep |
| 164228 | ) |
| 164229 | ); |
| 164230 | assert( pInsert==0 || rc==SQLITE_OK ); |
| 164231 | |
| 164232 | if( rc==SQLITE_OK ){ |
| @@ -164244,10 +164409,14 @@ | |
| 164409 | |
| 164410 | case RBU_STATE_OALSZ: |
| 164411 | pRet->iOalSz = (u32)sqlite3_column_int64(pStmt, 1); |
| 164412 | break; |
| 164413 | |
| 164414 | case RBU_STATE_PHASEONESTEP: |
| 164415 | pRet->nPhaseOneStep = sqlite3_column_int64(pStmt, 1); |
| 164416 | break; |
| 164417 | |
| 164418 | default: |
| 164419 | rc = SQLITE_CORRUPT; |
| 164420 | break; |
| 164421 | } |
| 164422 | } |
| @@ -164350,10 +164519,104 @@ | |
| 164519 | if( p->zVfsName ){ |
| 164520 | sqlite3rbu_destroy_vfs(p->zVfsName); |
| 164521 | p->zVfsName = 0; |
| 164522 | } |
| 164523 | } |
| 164524 | |
| 164525 | /* |
| 164526 | ** This user-defined SQL function is invoked with a single argument - the |
| 164527 | ** name of a table expected to appear in the target database. It returns |
| 164528 | ** the number of auxilliary indexes on the table. |
| 164529 | */ |
| 164530 | static void rbuIndexCntFunc( |
| 164531 | sqlite3_context *pCtx, |
| 164532 | int nVal, |
| 164533 | sqlite3_value **apVal |
| 164534 | ){ |
| 164535 | sqlite3rbu *p = (sqlite3rbu*)sqlite3_user_data(pCtx); |
| 164536 | sqlite3_stmt *pStmt = 0; |
| 164537 | char *zErrmsg = 0; |
| 164538 | int rc; |
| 164539 | |
| 164540 | assert( nVal==1 ); |
| 164541 | |
| 164542 | rc = prepareFreeAndCollectError(p->dbMain, &pStmt, &zErrmsg, |
| 164543 | sqlite3_mprintf("SELECT count(*) FROM sqlite_master " |
| 164544 | "WHERE type='index' AND tbl_name = %Q", sqlite3_value_text(apVal[0])) |
| 164545 | ); |
| 164546 | if( rc!=SQLITE_OK ){ |
| 164547 | sqlite3_result_error(pCtx, zErrmsg, -1); |
| 164548 | }else{ |
| 164549 | int nIndex = 0; |
| 164550 | if( SQLITE_ROW==sqlite3_step(pStmt) ){ |
| 164551 | nIndex = sqlite3_column_int(pStmt, 0); |
| 164552 | } |
| 164553 | rc = sqlite3_finalize(pStmt); |
| 164554 | if( rc==SQLITE_OK ){ |
| 164555 | sqlite3_result_int(pCtx, nIndex); |
| 164556 | }else{ |
| 164557 | sqlite3_result_error(pCtx, sqlite3_errmsg(p->dbMain), -1); |
| 164558 | } |
| 164559 | } |
| 164560 | |
| 164561 | sqlite3_free(zErrmsg); |
| 164562 | } |
| 164563 | |
| 164564 | /* |
| 164565 | ** If the RBU database contains the rbu_count table, use it to initialize |
| 164566 | ** the sqlite3rbu.nPhaseOneStep variable. The schema of the rbu_count table |
| 164567 | ** is assumed to contain the same columns as: |
| 164568 | ** |
| 164569 | ** CREATE TABLE rbu_count(tbl TEXT PRIMARY KEY, cnt INTEGER) WITHOUT ROWID; |
| 164570 | ** |
| 164571 | ** There should be one row in the table for each data_xxx table in the |
| 164572 | ** database. The 'tbl' column should contain the name of a data_xxx table, |
| 164573 | ** and the cnt column the number of rows it contains. |
| 164574 | ** |
| 164575 | ** sqlite3rbu.nPhaseOneStep is initialized to the sum of (1 + nIndex) * cnt |
| 164576 | ** for all rows in the rbu_count table, where nIndex is the number of |
| 164577 | ** indexes on the corresponding target database table. |
| 164578 | */ |
| 164579 | static void rbuInitPhaseOneSteps(sqlite3rbu *p){ |
| 164580 | if( p->rc==SQLITE_OK ){ |
| 164581 | sqlite3_stmt *pStmt = 0; |
| 164582 | int bExists = 0; /* True if rbu_count exists */ |
| 164583 | |
| 164584 | p->nPhaseOneStep = -1; |
| 164585 | |
| 164586 | p->rc = sqlite3_create_function(p->dbRbu, |
| 164587 | "rbu_index_cnt", 1, SQLITE_UTF8, (void*)p, rbuIndexCntFunc, 0, 0 |
| 164588 | ); |
| 164589 | |
| 164590 | /* Check for the rbu_count table. If it does not exist, or if an error |
| 164591 | ** occurs, nPhaseOneStep will be left set to -1. */ |
| 164592 | if( p->rc==SQLITE_OK ){ |
| 164593 | p->rc = prepareAndCollectError(p->dbRbu, &pStmt, &p->zErrmsg, |
| 164594 | "SELECT 1 FROM sqlite_master WHERE tbl_name = 'rbu_count'" |
| 164595 | ); |
| 164596 | } |
| 164597 | if( p->rc==SQLITE_OK ){ |
| 164598 | if( SQLITE_ROW==sqlite3_step(pStmt) ){ |
| 164599 | bExists = 1; |
| 164600 | } |
| 164601 | p->rc = sqlite3_finalize(pStmt); |
| 164602 | } |
| 164603 | |
| 164604 | if( p->rc==SQLITE_OK && bExists ){ |
| 164605 | p->rc = prepareAndCollectError(p->dbRbu, &pStmt, &p->zErrmsg, |
| 164606 | "SELECT sum(cnt * (1 + rbu_index_cnt(rbu_target_name(tbl))))" |
| 164607 | "FROM rbu_count" |
| 164608 | ); |
| 164609 | if( p->rc==SQLITE_OK ){ |
| 164610 | if( SQLITE_ROW==sqlite3_step(pStmt) ){ |
| 164611 | p->nPhaseOneStep = sqlite3_column_int64(pStmt, 0); |
| 164612 | } |
| 164613 | p->rc = sqlite3_finalize(pStmt); |
| 164614 | } |
| 164615 | } |
| 164616 | } |
| 164617 | } |
| 164618 | |
| 164619 | /* |
| 164620 | ** Open and return a new RBU handle. |
| 164621 | */ |
| 164622 | SQLITE_API sqlite3rbu *SQLITE_STDCALL sqlite3rbu_open( |
| @@ -164396,13 +164659,15 @@ | |
| 164659 | assert( pState || p->rc!=SQLITE_OK ); |
| 164660 | if( p->rc==SQLITE_OK ){ |
| 164661 | |
| 164662 | if( pState->eStage==0 ){ |
| 164663 | rbuDeleteOalFile(p); |
| 164664 | rbuInitPhaseOneSteps(p); |
| 164665 | p->eStage = RBU_STAGE_OAL; |
| 164666 | }else{ |
| 164667 | p->eStage = pState->eStage; |
| 164668 | p->nPhaseOneStep = pState->nPhaseOneStep; |
| 164669 | } |
| 164670 | p->nProgress = pState->nProgress; |
| 164671 | p->iOalSz = pState->iOalSz; |
| 164672 | } |
| 164673 | } |
| @@ -164561,10 +164826,46 @@ | |
| 164826 | ** current RBU update was started. |
| 164827 | */ |
| 164828 | SQLITE_API sqlite3_int64 SQLITE_STDCALL sqlite3rbu_progress(sqlite3rbu *pRbu){ |
| 164829 | return pRbu->nProgress; |
| 164830 | } |
| 164831 | |
| 164832 | /* |
| 164833 | ** Return permyriadage progress indications for the two main stages of |
| 164834 | ** an RBU update. |
| 164835 | */ |
| 164836 | SQLITE_API void SQLITE_STDCALL sqlite3rbu_bp_progress(sqlite3rbu *p, int *pnOne, int *pnTwo){ |
| 164837 | const int MAX_PROGRESS = 10000; |
| 164838 | switch( p->eStage ){ |
| 164839 | case RBU_STAGE_OAL: |
| 164840 | if( p->nPhaseOneStep>0 ){ |
| 164841 | *pnOne = (int)(MAX_PROGRESS * (i64)p->nProgress/(i64)p->nPhaseOneStep); |
| 164842 | }else{ |
| 164843 | *pnOne = -1; |
| 164844 | } |
| 164845 | *pnTwo = 0; |
| 164846 | break; |
| 164847 | |
| 164848 | case RBU_STAGE_MOVE: |
| 164849 | *pnOne = MAX_PROGRESS; |
| 164850 | *pnTwo = 0; |
| 164851 | break; |
| 164852 | |
| 164853 | case RBU_STAGE_CKPT: |
| 164854 | *pnOne = MAX_PROGRESS; |
| 164855 | *pnTwo = (int)(MAX_PROGRESS * (i64)p->nStep / (i64)p->nFrame); |
| 164856 | break; |
| 164857 | |
| 164858 | case RBU_STAGE_DONE: |
| 164859 | *pnOne = MAX_PROGRESS; |
| 164860 | *pnTwo = MAX_PROGRESS; |
| 164861 | break; |
| 164862 | |
| 164863 | default: |
| 164864 | assert( 0 ); |
| 164865 | } |
| 164866 | } |
| 164867 | |
| 164868 | SQLITE_API int SQLITE_STDCALL sqlite3rbu_savestate(sqlite3rbu *p){ |
| 164869 | int rc = p->rc; |
| 164870 | |
| 164871 | if( rc==SQLITE_DONE ) return SQLITE_OK; |
| @@ -169364,10 +169665,11 @@ | |
| 169665 | static int sqlite3Fts5IndexReads(Fts5Index *p); |
| 169666 | |
| 169667 | static int sqlite3Fts5IndexReinit(Fts5Index *p); |
| 169668 | static int sqlite3Fts5IndexOptimize(Fts5Index *p); |
| 169669 | static int sqlite3Fts5IndexMerge(Fts5Index *p, int nMerge); |
| 169670 | static int sqlite3Fts5IndexReset(Fts5Index *p); |
| 169671 | |
| 169672 | static int sqlite3Fts5IndexLoadConfig(Fts5Index *p); |
| 169673 | |
| 169674 | /* |
| 169675 | ** End of interface to code in fts5_index.c. |
| @@ -169506,10 +169808,11 @@ | |
| 169808 | |
| 169809 | static int sqlite3Fts5StorageDeleteAll(Fts5Storage *p); |
| 169810 | static int sqlite3Fts5StorageRebuild(Fts5Storage *p); |
| 169811 | static int sqlite3Fts5StorageOptimize(Fts5Storage *p); |
| 169812 | static int sqlite3Fts5StorageMerge(Fts5Storage *p, int nMerge); |
| 169813 | static int sqlite3Fts5StorageReset(Fts5Storage *p); |
| 169814 | |
| 169815 | /* |
| 169816 | ** End of interface to code in fts5_storage.c. |
| 169817 | **************************************************************************/ |
| 169818 | |
| @@ -176314,10 +176617,14 @@ | |
| 176617 | sqlite3_stmt *pDeleter; /* "DELETE FROM %_data ... id>=? AND id<=?" */ |
| 176618 | sqlite3_stmt *pIdxWriter; /* "INSERT ... %_idx VALUES(?,?,?,?)" */ |
| 176619 | sqlite3_stmt *pIdxDeleter; /* "DELETE FROM %_idx WHERE segid=? */ |
| 176620 | sqlite3_stmt *pIdxSelect; |
| 176621 | int nRead; /* Total number of blocks read */ |
| 176622 | |
| 176623 | sqlite3_stmt *pDataVersion; |
| 176624 | i64 iStructVersion; /* data_version when pStruct read */ |
| 176625 | Fts5Structure *pStruct; /* Current db structure (or NULL) */ |
| 176626 | }; |
| 176627 | |
| 176628 | struct Fts5DoclistIter { |
| 176629 | u8 *aEof; /* Pointer to 1 byte past end of doclist */ |
| 176630 | |
| @@ -176968,10 +177275,54 @@ | |
| 177275 | }else{ |
| 177276 | *pRc = SQLITE_NOMEM; |
| 177277 | } |
| 177278 | } |
| 177279 | } |
| 177280 | |
| 177281 | static Fts5Structure *fts5StructureReadUncached(Fts5Index *p){ |
| 177282 | Fts5Structure *pRet = 0; |
| 177283 | Fts5Config *pConfig = p->pConfig; |
| 177284 | int iCookie; /* Configuration cookie */ |
| 177285 | Fts5Data *pData; |
| 177286 | |
| 177287 | pData = fts5DataRead(p, FTS5_STRUCTURE_ROWID); |
| 177288 | if( p->rc==SQLITE_OK ){ |
| 177289 | /* TODO: Do we need this if the leaf-index is appended? Probably... */ |
| 177290 | memset(&pData->p[pData->nn], 0, FTS5_DATA_PADDING); |
| 177291 | p->rc = fts5StructureDecode(pData->p, pData->nn, &iCookie, &pRet); |
| 177292 | if( p->rc==SQLITE_OK && pConfig->iCookie!=iCookie ){ |
| 177293 | p->rc = sqlite3Fts5ConfigLoad(pConfig, iCookie); |
| 177294 | } |
| 177295 | fts5DataRelease(pData); |
| 177296 | if( p->rc!=SQLITE_OK ){ |
| 177297 | fts5StructureRelease(pRet); |
| 177298 | pRet = 0; |
| 177299 | } |
| 177300 | } |
| 177301 | |
| 177302 | return pRet; |
| 177303 | } |
| 177304 | |
| 177305 | static i64 fts5IndexDataVersion(Fts5Index *p){ |
| 177306 | i64 iVersion = 0; |
| 177307 | |
| 177308 | if( p->rc==SQLITE_OK ){ |
| 177309 | if( p->pDataVersion==0 ){ |
| 177310 | p->rc = fts5IndexPrepareStmt(p, &p->pDataVersion, |
| 177311 | sqlite3_mprintf("PRAGMA %Q.data_version", p->pConfig->zDb) |
| 177312 | ); |
| 177313 | if( p->rc ) return 0; |
| 177314 | } |
| 177315 | |
| 177316 | if( SQLITE_ROW==sqlite3_step(p->pDataVersion) ){ |
| 177317 | iVersion = sqlite3_column_int64(p->pDataVersion, 0); |
| 177318 | } |
| 177319 | p->rc = sqlite3_reset(p->pDataVersion); |
| 177320 | } |
| 177321 | |
| 177322 | return iVersion; |
| 177323 | } |
| 177324 | |
| 177325 | /* |
| 177326 | ** Read, deserialize and return the structure record. |
| 177327 | ** |
| 177328 | ** The Fts5Structure.aLevel[] and each Fts5StructureLevel.aSeg[] array |
| @@ -176981,30 +177332,53 @@ | |
| 177332 | ** If an error occurs, NULL is returned and an error code left in the |
| 177333 | ** Fts5Index handle. If an error has already occurred when this function |
| 177334 | ** is called, it is a no-op. |
| 177335 | */ |
| 177336 | static Fts5Structure *fts5StructureRead(Fts5Index *p){ |
| 177337 | |
| 177338 | if( p->pStruct==0 ){ |
| 177339 | p->iStructVersion = fts5IndexDataVersion(p); |
| 177340 | if( p->rc==SQLITE_OK ){ |
| 177341 | p->pStruct = fts5StructureReadUncached(p); |
| 177342 | } |
| 177343 | } |
| 177344 | |
| 177345 | #ifdef SQLITE_DEBUG |
| 177346 | else{ |
| 177347 | Fts5Structure *pTest = fts5StructureReadUncached(p); |
| 177348 | if( pTest ){ |
| 177349 | int i, j; |
| 177350 | assert_nc( p->pStruct->nSegment==pTest->nSegment ); |
| 177351 | assert_nc( p->pStruct->nLevel==pTest->nLevel ); |
| 177352 | for(i=0; i<pTest->nLevel; i++){ |
| 177353 | assert_nc( p->pStruct->aLevel[i].nMerge==pTest->aLevel[i].nMerge ); |
| 177354 | assert_nc( p->pStruct->aLevel[i].nSeg==pTest->aLevel[i].nSeg ); |
| 177355 | for(j=0; j<pTest->aLevel[i].nSeg; j++){ |
| 177356 | Fts5StructureSegment *p1 = &pTest->aLevel[i].aSeg[j]; |
| 177357 | Fts5StructureSegment *p2 = &p->pStruct->aLevel[i].aSeg[j]; |
| 177358 | assert_nc( p1->iSegid==p2->iSegid ); |
| 177359 | assert_nc( p1->pgnoFirst==p2->pgnoFirst ); |
| 177360 | assert_nc( p1->pgnoLast==p2->pgnoLast ); |
| 177361 | } |
| 177362 | } |
| 177363 | fts5StructureRelease(pTest); |
| 177364 | } |
| 177365 | } |
| 177366 | #endif |
| 177367 | |
| 177368 | if( p->rc!=SQLITE_OK ) return 0; |
| 177369 | assert( p->iStructVersion!=0 ); |
| 177370 | assert( p->pStruct!=0 ); |
| 177371 | fts5StructureRef(p->pStruct); |
| 177372 | return p->pStruct; |
| 177373 | } |
| 177374 | |
| 177375 | static void fts5StructureInvalidate(Fts5Index *p){ |
| 177376 | if( p->pStruct ){ |
| 177377 | fts5StructureRelease(p->pStruct); |
| 177378 | p->pStruct = 0; |
| 177379 | } |
| 177380 | } |
| 177381 | |
| 177382 | /* |
| 177383 | ** Return the total number of segments in index structure pStruct. This |
| 177384 | ** function is only ever used as part of assert() conditions. |
| @@ -179463,22 +179837,39 @@ | |
| 179837 | |
| 179838 | if( p->rc==SQLITE_OK ){ |
| 179839 | if( pStruct->nSegment>=FTS5_MAX_SEGMENT ){ |
| 179840 | p->rc = SQLITE_FULL; |
| 179841 | }else{ |
| 179842 | /* FTS5_MAX_SEGMENT is currently defined as 2000. So the following |
| 179843 | ** array is 63 elements, or 252 bytes, in size. */ |
| 179844 | u32 aUsed[(FTS5_MAX_SEGMENT+31) / 32]; |
| 179845 | int iLvl, iSeg; |
| 179846 | int i; |
| 179847 | u32 mask; |
| 179848 | memset(aUsed, 0, sizeof(aUsed)); |
| 179849 | for(iLvl=0; iLvl<pStruct->nLevel; iLvl++){ |
| 179850 | for(iSeg=0; iSeg<pStruct->aLevel[iLvl].nSeg; iSeg++){ |
| 179851 | int iId = pStruct->aLevel[iLvl].aSeg[iSeg].iSegid; |
| 179852 | if( iId<=FTS5_MAX_SEGMENT ){ |
| 179853 | aUsed[(iId-1) / 32] |= 1 << ((iId-1) % 32); |
| 179854 | } |
| 179855 | } |
| 179856 | } |
| 179857 | |
| 179858 | for(i=0; aUsed[i]==0xFFFFFFFF; i++); |
| 179859 | mask = aUsed[i]; |
| 179860 | for(iSegid=0; mask & (1 << iSegid); iSegid++); |
| 179861 | iSegid += 1 + i*32; |
| 179862 | |
| 179863 | #ifdef SQLITE_DEBUG |
| 179864 | for(iLvl=0; iLvl<pStruct->nLevel; iLvl++){ |
| 179865 | for(iSeg=0; iSeg<pStruct->aLevel[iLvl].nSeg; iSeg++){ |
| 179866 | assert( iSegid!=pStruct->aLevel[iLvl].aSeg[iSeg].iSegid ); |
| 179867 | } |
| 179868 | } |
| 179869 | assert( iSegid>0 && iSegid<=FTS5_MAX_SEGMENT ); |
| 179870 | #endif |
| 179871 | } |
| 179872 | } |
| 179873 | |
| 179874 | return iSegid; |
| 179875 | } |
| @@ -179919,11 +180310,13 @@ | |
| 180310 | assert( pLeaf->pgno>=1 ); |
| 180311 | if( pLeaf->buf.n>4 ){ |
| 180312 | fts5WriteFlushLeaf(p, pWriter); |
| 180313 | } |
| 180314 | *pnLeaf = pLeaf->pgno-1; |
| 180315 | if( pLeaf->pgno>1 ){ |
| 180316 | fts5WriteFlushBtree(p, pWriter); |
| 180317 | } |
| 180318 | } |
| 180319 | fts5BufferFree(&pLeaf->term); |
| 180320 | fts5BufferFree(&pLeaf->buf); |
| 180321 | fts5BufferFree(&pLeaf->pgidx); |
| 180322 | fts5BufferFree(&pWriter->btterm); |
| @@ -180338,10 +180731,11 @@ | |
| 180731 | |
| 180732 | /* Obtain a reference to the index structure and allocate a new segment-id |
| 180733 | ** for the new level-0 segment. */ |
| 180734 | pStruct = fts5StructureRead(p); |
| 180735 | iSegid = fts5AllocateSegid(p, pStruct); |
| 180736 | fts5StructureInvalidate(p); |
| 180737 | |
| 180738 | if( iSegid ){ |
| 180739 | const int pgsz = p->pConfig->pgsz; |
| 180740 | int eDetail = p->pConfig->eDetail; |
| 180741 | Fts5StructureSegment *pSeg; /* New segment within pStruct */ |
| @@ -180557,10 +180951,11 @@ | |
| 180951 | Fts5Structure *pNew = 0; |
| 180952 | |
| 180953 | assert( p->rc==SQLITE_OK ); |
| 180954 | fts5IndexFlush(p); |
| 180955 | pStruct = fts5StructureRead(p); |
| 180956 | fts5StructureInvalidate(p); |
| 180957 | |
| 180958 | if( pStruct ){ |
| 180959 | pNew = fts5IndexOptimizeStruct(p, pStruct); |
| 180960 | } |
| 180961 | fts5StructureRelease(pStruct); |
| @@ -180587,10 +180982,11 @@ | |
| 180982 | */ |
| 180983 | static int sqlite3Fts5IndexMerge(Fts5Index *p, int nMerge){ |
| 180984 | Fts5Structure *pStruct = fts5StructureRead(p); |
| 180985 | if( pStruct ){ |
| 180986 | int nMin = p->pConfig->nUsermerge; |
| 180987 | fts5StructureInvalidate(p); |
| 180988 | if( nMerge<0 ){ |
| 180989 | Fts5Structure *pNew = fts5IndexOptimizeStruct(p, pStruct); |
| 180990 | fts5StructureRelease(pStruct); |
| 180991 | pStruct = pNew; |
| 180992 | nMin = 2; |
| @@ -181014,10 +181410,11 @@ | |
| 181410 | ** records must be invalidated. |
| 181411 | */ |
| 181412 | static int sqlite3Fts5IndexRollback(Fts5Index *p){ |
| 181413 | fts5CloseReader(p); |
| 181414 | fts5IndexDiscardData(p); |
| 181415 | fts5StructureInvalidate(p); |
| 181416 | /* assert( p->rc==SQLITE_OK ); */ |
| 181417 | return SQLITE_OK; |
| 181418 | } |
| 181419 | |
| 181420 | /* |
| @@ -181025,10 +181422,11 @@ | |
| 181422 | ** function populates it with the initial structure objects for each index, |
| 181423 | ** and the initial version of the "averages" record (a zero-byte blob). |
| 181424 | */ |
| 181425 | static int sqlite3Fts5IndexReinit(Fts5Index *p){ |
| 181426 | Fts5Structure s; |
| 181427 | fts5StructureInvalidate(p); |
| 181428 | memset(&s, 0, sizeof(Fts5Structure)); |
| 181429 | fts5DataWrite(p, FTS5_AVERAGES_ROWID, (const u8*)"", 0); |
| 181430 | fts5StructureWrite(p, &s); |
| 181431 | return fts5IndexReturn(p); |
| 181432 | } |
| @@ -181083,15 +181481,17 @@ | |
| 181481 | */ |
| 181482 | static int sqlite3Fts5IndexClose(Fts5Index *p){ |
| 181483 | int rc = SQLITE_OK; |
| 181484 | if( p ){ |
| 181485 | assert( p->pReader==0 ); |
| 181486 | fts5StructureInvalidate(p); |
| 181487 | sqlite3_finalize(p->pWriter); |
| 181488 | sqlite3_finalize(p->pDeleter); |
| 181489 | sqlite3_finalize(p->pIdxWriter); |
| 181490 | sqlite3_finalize(p->pIdxDeleter); |
| 181491 | sqlite3_finalize(p->pIdxSelect); |
| 181492 | sqlite3_finalize(p->pDataVersion); |
| 181493 | sqlite3Fts5HashFree(p->pHash); |
| 181494 | sqlite3_free(p->zDataTbl); |
| 181495 | sqlite3_free(p); |
| 181496 | } |
| 181497 | return rc; |
| @@ -182344,10 +182744,19 @@ | |
| 182744 | ); |
| 182745 | } |
| 182746 | return rc; |
| 182747 | } |
| 182748 | |
| 182749 | |
| 182750 | static int sqlite3Fts5IndexReset(Fts5Index *p){ |
| 182751 | assert( p->pStruct==0 || p->iStructVersion!=0 ); |
| 182752 | if( fts5IndexDataVersion(p)!=p->iStructVersion ){ |
| 182753 | fts5StructureInvalidate(p); |
| 182754 | } |
| 182755 | return fts5IndexReturn(p); |
| 182756 | } |
| 182757 | |
| 182758 | /* |
| 182759 | ** 2014 Jun 09 |
| 182760 | ** |
| 182761 | ** The author disclaims copyright to this source code. In place of |
| 182762 | ** a legal notice, here is a blessing: |
| @@ -182942,32 +183351,43 @@ | |
| 183351 | } |
| 183352 | |
| 183353 | pInfo->idxNum = idxFlags; |
| 183354 | return SQLITE_OK; |
| 183355 | } |
| 183356 | |
| 183357 | static int fts5NewTransaction(Fts5Table *pTab){ |
| 183358 | Fts5Cursor *pCsr; |
| 183359 | for(pCsr=pTab->pGlobal->pCsr; pCsr; pCsr=pCsr->pNext){ |
| 183360 | if( pCsr->base.pVtab==(sqlite3_vtab*)pTab ) return SQLITE_OK; |
| 183361 | } |
| 183362 | return sqlite3Fts5StorageReset(pTab->pStorage); |
| 183363 | } |
| 183364 | |
| 183365 | /* |
| 183366 | ** Implementation of xOpen method. |
| 183367 | */ |
| 183368 | static int fts5OpenMethod(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCsr){ |
| 183369 | Fts5Table *pTab = (Fts5Table*)pVTab; |
| 183370 | Fts5Config *pConfig = pTab->pConfig; |
| 183371 | Fts5Cursor *pCsr = 0; /* New cursor object */ |
| 183372 | int nByte; /* Bytes of space to allocate */ |
| 183373 | int rc; /* Return code */ |
| 183374 | |
| 183375 | rc = fts5NewTransaction(pTab); |
| 183376 | if( rc==SQLITE_OK ){ |
| 183377 | nByte = sizeof(Fts5Cursor) + pConfig->nCol * sizeof(int); |
| 183378 | pCsr = (Fts5Cursor*)sqlite3_malloc(nByte); |
| 183379 | if( pCsr ){ |
| 183380 | Fts5Global *pGlobal = pTab->pGlobal; |
| 183381 | memset(pCsr, 0, nByte); |
| 183382 | pCsr->aColumnSize = (int*)&pCsr[1]; |
| 183383 | pCsr->pNext = pGlobal->pCsr; |
| 183384 | pGlobal->pCsr = pCsr; |
| 183385 | pCsr->iCsrId = ++pGlobal->iNextId; |
| 183386 | }else{ |
| 183387 | rc = SQLITE_NOMEM; |
| 183388 | } |
| 183389 | } |
| 183390 | *ppCsr = (sqlite3_vtab_cursor*)pCsr; |
| 183391 | return rc; |
| 183392 | } |
| 183393 | |
| @@ -183924,12 +184344,12 @@ | |
| 184344 | |
| 184345 | /* |
| 184346 | ** Implementation of xBegin() method. |
| 184347 | */ |
| 184348 | static int fts5BeginMethod(sqlite3_vtab *pVtab){ |
| 184349 | fts5CheckTransactionState((Fts5Table*)pVtab, FTS5_BEGIN, 0); |
| 184350 | fts5NewTransaction((Fts5Table*)pVtab); |
| 184351 | return SQLITE_OK; |
| 184352 | } |
| 184353 | |
| 184354 | /* |
| 184355 | ** Implementation of xCommit() method. This is a no-op. The contents of |
| @@ -184950,11 +185370,11 @@ | |
| 185370 | int nArg, /* Number of args */ |
| 185371 | sqlite3_value **apUnused /* Function arguments */ |
| 185372 | ){ |
| 185373 | assert( nArg==0 ); |
| 185374 | UNUSED_PARAM2(nArg, apUnused); |
| 185375 | sqlite3_result_text(pCtx, "fts5: 2016-03-21 16:06:42 4dc30cce7fdb7dba9a9aad96bb8b499b965610b2", -1, SQLITE_TRANSIENT); |
| 185376 | } |
| 185377 | |
| 185378 | static int fts5Init(sqlite3 *db){ |
| 185379 | static const sqlite3_module fts5Mod = { |
| 185380 | /* iVersion */ 2, |
| @@ -185707,10 +186127,14 @@ | |
| 186127 | } |
| 186128 | |
| 186129 | static int sqlite3Fts5StorageMerge(Fts5Storage *p, int nMerge){ |
| 186130 | return sqlite3Fts5IndexMerge(p->pIndex, nMerge); |
| 186131 | } |
| 186132 | |
| 186133 | static int sqlite3Fts5StorageReset(Fts5Storage *p){ |
| 186134 | return sqlite3Fts5IndexReset(p->pIndex); |
| 186135 | } |
| 186136 | |
| 186137 | /* |
| 186138 | ** Allocate a new rowid. This is used for "external content" tables when |
| 186139 | ** a NULL value is inserted into the rowid column. The new rowid is allocated |
| 186140 | ** by inserting a dummy row into the %_docsize table. The dummy will be |
| 186141 |
+13
-1
| --- src/sqlite3.h | ||
| +++ src/sqlite3.h | ||
| @@ -111,11 +111,11 @@ | ||
| 111 | 111 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 112 | 112 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 113 | 113 | */ |
| 114 | 114 | #define SQLITE_VERSION "3.12.0" |
| 115 | 115 | #define SQLITE_VERSION_NUMBER 3012000 |
| 116 | -#define SQLITE_SOURCE_ID "2016-03-19 00:35:02 88439a866b3b16ad7c308ebe59198662a05e7eeb" | |
| 116 | +#define SQLITE_SOURCE_ID "2016-03-21 16:06:42 4dc30cce7fdb7dba9a9aad96bb8b499b965610b2" | |
| 117 | 117 | |
| 118 | 118 | /* |
| 119 | 119 | ** CAPI3REF: Run-Time Library Version Numbers |
| 120 | 120 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 121 | 121 | ** |
| @@ -7913,10 +7913,22 @@ | ||
| 7913 | 7913 | ** ^This function does not set the database handle error code or message |
| 7914 | 7914 | ** returned by the [sqlite3_errcode()] and [sqlite3_errmsg()] functions. |
| 7915 | 7915 | */ |
| 7916 | 7916 | SQLITE_API int SQLITE_STDCALL sqlite3_db_cacheflush(sqlite3*); |
| 7917 | 7917 | |
| 7918 | +/* | |
| 7919 | +** CAPI3REF: Low-level system error code | |
| 7920 | +** | |
| 7921 | +** ^Attempt to return the underlying operating system error code or error | |
| 7922 | +** number that caused the most reason I/O error or failure to open a file. | |
| 7923 | +** The return value is OS-dependent. For example, on unix systems, after | |
| 7924 | +** [sqlite3_open_v2()] returns [SQLITE_CANTOPEN], this interface could be | |
| 7925 | +** called to get back the underlying "errno" that caused the problem, such | |
| 7926 | +** as ENOSPC, EAUTH, EISDIR, and so forth. | |
| 7927 | +*/ | |
| 7928 | +SQLITE_API int SQLITE_STDCALL sqlite3_system_errno(sqlite3*); | |
| 7929 | + | |
| 7918 | 7930 | /* |
| 7919 | 7931 | ** CAPI3REF: Database Snapshot |
| 7920 | 7932 | ** KEYWORDS: {snapshot} |
| 7921 | 7933 | ** EXPERIMENTAL |
| 7922 | 7934 | ** |
| 7923 | 7935 |
| --- src/sqlite3.h | |
| +++ src/sqlite3.h | |
| @@ -111,11 +111,11 @@ | |
| 111 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 112 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 113 | */ |
| 114 | #define SQLITE_VERSION "3.12.0" |
| 115 | #define SQLITE_VERSION_NUMBER 3012000 |
| 116 | #define SQLITE_SOURCE_ID "2016-03-19 00:35:02 88439a866b3b16ad7c308ebe59198662a05e7eeb" |
| 117 | |
| 118 | /* |
| 119 | ** CAPI3REF: Run-Time Library Version Numbers |
| 120 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 121 | ** |
| @@ -7913,10 +7913,22 @@ | |
| 7913 | ** ^This function does not set the database handle error code or message |
| 7914 | ** returned by the [sqlite3_errcode()] and [sqlite3_errmsg()] functions. |
| 7915 | */ |
| 7916 | SQLITE_API int SQLITE_STDCALL sqlite3_db_cacheflush(sqlite3*); |
| 7917 | |
| 7918 | /* |
| 7919 | ** CAPI3REF: Database Snapshot |
| 7920 | ** KEYWORDS: {snapshot} |
| 7921 | ** EXPERIMENTAL |
| 7922 | ** |
| 7923 |
| --- src/sqlite3.h | |
| +++ src/sqlite3.h | |
| @@ -111,11 +111,11 @@ | |
| 111 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 112 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 113 | */ |
| 114 | #define SQLITE_VERSION "3.12.0" |
| 115 | #define SQLITE_VERSION_NUMBER 3012000 |
| 116 | #define SQLITE_SOURCE_ID "2016-03-21 16:06:42 4dc30cce7fdb7dba9a9aad96bb8b499b965610b2" |
| 117 | |
| 118 | /* |
| 119 | ** CAPI3REF: Run-Time Library Version Numbers |
| 120 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 121 | ** |
| @@ -7913,10 +7913,22 @@ | |
| 7913 | ** ^This function does not set the database handle error code or message |
| 7914 | ** returned by the [sqlite3_errcode()] and [sqlite3_errmsg()] functions. |
| 7915 | */ |
| 7916 | SQLITE_API int SQLITE_STDCALL sqlite3_db_cacheflush(sqlite3*); |
| 7917 | |
| 7918 | /* |
| 7919 | ** CAPI3REF: Low-level system error code |
| 7920 | ** |
| 7921 | ** ^Attempt to return the underlying operating system error code or error |
| 7922 | ** number that caused the most reason I/O error or failure to open a file. |
| 7923 | ** The return value is OS-dependent. For example, on unix systems, after |
| 7924 | ** [sqlite3_open_v2()] returns [SQLITE_CANTOPEN], this interface could be |
| 7925 | ** called to get back the underlying "errno" that caused the problem, such |
| 7926 | ** as ENOSPC, EAUTH, EISDIR, and so forth. |
| 7927 | */ |
| 7928 | SQLITE_API int SQLITE_STDCALL sqlite3_system_errno(sqlite3*); |
| 7929 | |
| 7930 | /* |
| 7931 | ** CAPI3REF: Database Snapshot |
| 7932 | ** KEYWORDS: {snapshot} |
| 7933 | ** EXPERIMENTAL |
| 7934 | ** |
| 7935 |