| | @@ -650,11 +650,11 @@ |
| 650 | 650 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 651 | 651 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 652 | 652 | */ |
| 653 | 653 | #define SQLITE_VERSION "3.7.7" |
| 654 | 654 | #define SQLITE_VERSION_NUMBER 3007007 |
| 655 | | -#define SQLITE_SOURCE_ID "2011-05-20 01:50:01 2018d4e108872f2436df046636401b89cfde589d" |
| 655 | +#define SQLITE_SOURCE_ID "2011-06-03 14:19:10 0206bc6f87bb9393218a380fc5b18039d334a8d8" |
| 656 | 656 | |
| 657 | 657 | /* |
| 658 | 658 | ** CAPI3REF: Run-Time Library Version Numbers |
| 659 | 659 | ** KEYWORDS: sqlite3_version, sqlite3_sourceid |
| 660 | 660 | ** |
| | @@ -1000,10 +1000,12 @@ |
| 1000 | 1000 | #define SQLITE_IOERR_SEEK (SQLITE_IOERR | (22<<8)) |
| 1001 | 1001 | #define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8)) |
| 1002 | 1002 | #define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8)) |
| 1003 | 1003 | #define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8)) |
| 1004 | 1004 | #define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8)) |
| 1005 | +#define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8)) |
| 1006 | +#define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8)) |
| 1005 | 1007 | |
| 1006 | 1008 | /* |
| 1007 | 1009 | ** CAPI3REF: Flags For File Open Operations |
| 1008 | 1010 | ** |
| 1009 | 1011 | ** These bit values are intended for use in the |
| | @@ -1305,15 +1307,15 @@ |
| 1305 | 1307 | */ |
| 1306 | 1308 | typedef struct sqlite3_mutex sqlite3_mutex; |
| 1307 | 1309 | |
| 1308 | 1310 | /* |
| 1309 | 1311 | ** CAPI3REF: OS Interface Object |
| 1310 | | -** KEYWORDS: VFS VFSes |
| 1311 | 1312 | ** |
| 1312 | 1313 | ** An instance of the sqlite3_vfs object defines the interface between |
| 1313 | 1314 | ** the SQLite core and the underlying operating system. The "vfs" |
| 1314 | | -** in the name of the object stands for "virtual file system". |
| 1315 | +** in the name of the object stands for "virtual file system". See |
| 1316 | +** the [VFS | VFS documentation] for further information. |
| 1315 | 1317 | ** |
| 1316 | 1318 | ** The value of the iVersion field is initially 1 but may be larger in |
| 1317 | 1319 | ** future versions of SQLite. Additional fields may be appended to this |
| 1318 | 1320 | ** object when the iVersion value is increased. Note that the structure |
| 1319 | 1321 | ** of the sqlite3_vfs object changes in the transaction between |
| | @@ -8494,19 +8496,20 @@ |
| 8494 | 8496 | SQLITE_PRIVATE VdbeOp *sqlite3VdbeGetOp(Vdbe*, int); |
| 8495 | 8497 | SQLITE_PRIVATE int sqlite3VdbeMakeLabel(Vdbe*); |
| 8496 | 8498 | SQLITE_PRIVATE void sqlite3VdbeRunOnlyOnce(Vdbe*); |
| 8497 | 8499 | SQLITE_PRIVATE void sqlite3VdbeDelete(Vdbe*); |
| 8498 | 8500 | SQLITE_PRIVATE void sqlite3VdbeDeleteObject(sqlite3*,Vdbe*); |
| 8499 | | -SQLITE_PRIVATE void sqlite3VdbeMakeReady(Vdbe*,int,int,int,int,int,int); |
| 8501 | +SQLITE_PRIVATE void sqlite3VdbeMakeReady(Vdbe*,Parse*); |
| 8500 | 8502 | SQLITE_PRIVATE int sqlite3VdbeFinalize(Vdbe*); |
| 8501 | 8503 | SQLITE_PRIVATE void sqlite3VdbeResolveLabel(Vdbe*, int); |
| 8502 | 8504 | SQLITE_PRIVATE int sqlite3VdbeCurrentAddr(Vdbe*); |
| 8503 | 8505 | #ifdef SQLITE_DEBUG |
| 8504 | 8506 | SQLITE_PRIVATE int sqlite3VdbeAssertMayAbort(Vdbe *, int); |
| 8505 | 8507 | SQLITE_PRIVATE void sqlite3VdbeTrace(Vdbe*,FILE*); |
| 8506 | 8508 | #endif |
| 8507 | 8509 | SQLITE_PRIVATE void sqlite3VdbeResetStepResult(Vdbe*); |
| 8510 | +SQLITE_PRIVATE void sqlite3VdbeRewind(Vdbe*); |
| 8508 | 8511 | SQLITE_PRIVATE int sqlite3VdbeReset(Vdbe*); |
| 8509 | 8512 | SQLITE_PRIVATE void sqlite3VdbeSetNumCols(Vdbe*,int); |
| 8510 | 8513 | SQLITE_PRIVATE int sqlite3VdbeSetColName(Vdbe*, int, int, const char *, void(*)(void*)); |
| 8511 | 8514 | SQLITE_PRIVATE void sqlite3VdbeCountChanges(Vdbe*); |
| 8512 | 8515 | SQLITE_PRIVATE sqlite3 *sqlite3VdbeDb(Vdbe*); |
| | @@ -9832,10 +9835,11 @@ |
| 9832 | 9835 | sqlite3 *db; /* Database connection associated with this table */ |
| 9833 | 9836 | Module *pMod; /* Pointer to module implementation */ |
| 9834 | 9837 | sqlite3_vtab *pVtab; /* Pointer to vtab instance */ |
| 9835 | 9838 | int nRef; /* Number of pointers to this structure */ |
| 9836 | 9839 | u8 bConstraint; /* True if constraints are supported */ |
| 9840 | + int iSavepoint; /* Depth of the SAVEPOINT stack */ |
| 9837 | 9841 | VTable *pNext; /* Next in linked list (see above) */ |
| 9838 | 9842 | }; |
| 9839 | 9843 | |
| 9840 | 9844 | /* |
| 9841 | 9845 | ** Each SQL table is represented in memory by an instance of the |
| | @@ -10826,13 +10830,12 @@ |
| 10826 | 10830 | |
| 10827 | 10831 | /* Above is constant between recursions. Below is reset before and after |
| 10828 | 10832 | ** each recursion */ |
| 10829 | 10833 | |
| 10830 | 10834 | int nVar; /* Number of '?' variables seen in the SQL so far */ |
| 10831 | | - int nVarExpr; /* Number of used slots in apVarExpr[] */ |
| 10832 | | - int nVarExprAlloc; /* Number of allocated slots in apVarExpr[] */ |
| 10833 | | - Expr **apVarExpr; /* Pointers to :aaa and $aaaa wildcard expressions */ |
| 10835 | + int nzVar; /* Number of available slots in azVar[] */ |
| 10836 | + char **azVar; /* Pointers to names of parameters */ |
| 10834 | 10837 | Vdbe *pReprepare; /* VM being reprepared (sqlite3Reprepare()) */ |
| 10835 | 10838 | int nAlias; /* Number of aliased result set columns */ |
| 10836 | 10839 | int nAliasAlloc; /* Number of allocated slots for aAlias[] */ |
| 10837 | 10840 | int *aAlias; /* Register used to hold aliased result */ |
| 10838 | 10841 | u8 explain; /* True if the EXPLAIN flag is found on the query */ |
| | @@ -12761,15 +12764,15 @@ |
| 12761 | 12764 | Vdbe *pPrev,*pNext; /* Linked list of VDBEs with the same Vdbe.db */ |
| 12762 | 12765 | VdbeCursor **apCsr; /* One element of this array for each open cursor */ |
| 12763 | 12766 | Mem *aVar; /* Values for the OP_Variable opcode. */ |
| 12764 | 12767 | char **azVar; /* Name of variables */ |
| 12765 | 12768 | ynVar nVar; /* Number of entries in aVar[] */ |
| 12769 | + ynVar nzVar; /* Number of entries in azVar[] */ |
| 12766 | 12770 | u32 cacheCtr; /* VdbeCursor row cache generation counter */ |
| 12767 | 12771 | int pc; /* The program counter */ |
| 12768 | 12772 | int rc; /* Value to return */ |
| 12769 | 12773 | u8 errorAction; /* Recovery action to do in case of an error */ |
| 12770 | | - u8 okVar; /* True if azVar[] has been initialized */ |
| 12771 | 12774 | u8 explain; /* True if EXPLAIN present on SQL command */ |
| 12772 | 12775 | u8 changeCntOn; /* True to update the change-counter */ |
| 12773 | 12776 | u8 expired; /* True if the VM needs to be recompiled */ |
| 12774 | 12777 | u8 runOnlyOnce; /* Automatically expire on reset */ |
| 12775 | 12778 | u8 minWriteFileFormat; /* Minimum file format for writable database files */ |
| | @@ -27963,11 +27966,12 @@ |
| 27963 | 27966 | unixInodeInfo *pInode; /* unixInodeInfo that owns this SHM node */ |
| 27964 | 27967 | sqlite3_mutex *mutex; /* Mutex to access this object */ |
| 27965 | 27968 | char *zFilename; /* Name of the mmapped file */ |
| 27966 | 27969 | int h; /* Open file descriptor */ |
| 27967 | 27970 | int szRegion; /* Size of shared-memory regions */ |
| 27968 | | - int nRegion; /* Size of array apRegion */ |
| 27971 | + u16 nRegion; /* Size of array apRegion */ |
| 27972 | + u8 isReadonly; /* True if read-only */ |
| 27969 | 27973 | char **apRegion; /* Array of mapped shared-memory regions */ |
| 27970 | 27974 | int nRef; /* Number of unixShm objects pointing to this */ |
| 27971 | 27975 | unixShm *pFirst; /* All unixShm objects pointing to this */ |
| 27972 | 27976 | #ifdef SQLITE_DEBUG |
| 27973 | 27977 | u8 exclMask; /* Mask of exclusive locks held */ |
| | @@ -28210,12 +28214,21 @@ |
| 28210 | 28214 | |
| 28211 | 28215 | if( pInode->bProcessLock==0 ){ |
| 28212 | 28216 | pShmNode->h = robust_open(zShmFilename, O_RDWR|O_CREAT, |
| 28213 | 28217 | (sStat.st_mode & 0777)); |
| 28214 | 28218 | if( pShmNode->h<0 ){ |
| 28215 | | - rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zShmFilename); |
| 28216 | | - goto shm_open_err; |
| 28219 | + const char *zRO; |
| 28220 | + zRO = sqlite3_uri_parameter(pDbFd->zPath, "readonly_shm"); |
| 28221 | + if( zRO && sqlite3GetBoolean(zRO) ){ |
| 28222 | + pShmNode->h = robust_open(zShmFilename, O_RDONLY, |
| 28223 | + (sStat.st_mode & 0777)); |
| 28224 | + pShmNode->isReadonly = 1; |
| 28225 | + } |
| 28226 | + if( pShmNode->h<0 ){ |
| 28227 | + rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zShmFilename); |
| 28228 | + goto shm_open_err; |
| 28229 | + } |
| 28217 | 28230 | } |
| 28218 | 28231 | |
| 28219 | 28232 | /* Check to see if another process is holding the dead-man switch. |
| 28220 | 28233 | ** If not, truncate the file to zero length. |
| 28221 | 28234 | */ |
| | @@ -28350,11 +28363,12 @@ |
| 28350 | 28363 | } |
| 28351 | 28364 | pShmNode->apRegion = apNew; |
| 28352 | 28365 | while(pShmNode->nRegion<=iRegion){ |
| 28353 | 28366 | void *pMem; |
| 28354 | 28367 | if( pShmNode->h>=0 ){ |
| 28355 | | - pMem = mmap(0, szRegion, PROT_READ|PROT_WRITE, |
| 28368 | + pMem = mmap(0, szRegion, |
| 28369 | + pShmNode->isReadonly ? PROT_READ : PROT_READ|PROT_WRITE, |
| 28356 | 28370 | MAP_SHARED, pShmNode->h, pShmNode->nRegion*szRegion |
| 28357 | 28371 | ); |
| 28358 | 28372 | if( pMem==MAP_FAILED ){ |
| 28359 | 28373 | rc = unixLogError(SQLITE_IOERR_SHMMAP, "mmap", pShmNode->zFilename); |
| 28360 | 28374 | goto shmpage_out; |
| | @@ -28376,10 +28390,11 @@ |
| 28376 | 28390 | if( pShmNode->nRegion>iRegion ){ |
| 28377 | 28391 | *pp = pShmNode->apRegion[iRegion]; |
| 28378 | 28392 | }else{ |
| 28379 | 28393 | *pp = 0; |
| 28380 | 28394 | } |
| 28395 | + if( pShmNode->isReadonly && rc==SQLITE_OK ) rc = SQLITE_READONLY; |
| 28381 | 28396 | sqlite3_mutex_leave(pShmNode->mutex); |
| 28382 | 28397 | return rc; |
| 28383 | 28398 | } |
| 28384 | 28399 | |
| 28385 | 28400 | /* |
| | @@ -34873,10 +34888,17 @@ |
| 34873 | 34888 | if( !pPg ){ |
| 34874 | 34889 | for(pPg=pCache->pDirtyTail; pPg && pPg->nRef; pPg=pPg->pDirtyPrev); |
| 34875 | 34890 | } |
| 34876 | 34891 | if( pPg ){ |
| 34877 | 34892 | int rc; |
| 34893 | +#ifdef SQLITE_LOG_CACHE_SPILL |
| 34894 | + sqlite3_log(SQLITE_FULL, |
| 34895 | + "spill page %d making room for %d - cache used: %d/%d", |
| 34896 | + pPg->pgno, pgno, |
| 34897 | + sqlite3GlobalConfig.pcache.xPagecount(pCache->pCache), |
| 34898 | + pCache->nMax); |
| 34899 | +#endif |
| 34878 | 34900 | rc = pCache->xStress(pCache->pStress, pPg); |
| 34879 | 34901 | if( rc!=SQLITE_OK && rc!=SQLITE_BUSY ){ |
| 34880 | 34902 | return rc; |
| 34881 | 34903 | } |
| 34882 | 34904 | } |
| | @@ -43977,11 +43999,11 @@ |
| 43977 | 43999 | u32 szPage; /* Database page size */ |
| 43978 | 44000 | i16 readLock; /* Which read lock is being held. -1 for none */ |
| 43979 | 44001 | u8 exclusiveMode; /* Non-zero if connection is in exclusive mode */ |
| 43980 | 44002 | u8 writeLock; /* True if in a write transaction */ |
| 43981 | 44003 | u8 ckptLock; /* True if holding a checkpoint lock */ |
| 43982 | | - u8 readOnly; /* True if the WAL file is open read-only */ |
| 44004 | + u8 readOnly; /* WAL_RDWR, WAL_RDONLY, or WAL_SHM_RDONLY */ |
| 43983 | 44005 | WalIndexHdr hdr; /* Wal-index header for current transaction */ |
| 43984 | 44006 | const char *zWalName; /* Name of WAL file */ |
| 43985 | 44007 | u32 nCkpt; /* Checkpoint sequence counter in the wal-header */ |
| 43986 | 44008 | #ifdef SQLITE_DEBUG |
| 43987 | 44009 | u8 lockError; /* True if a locking error has occurred */ |
| | @@ -43993,10 +44015,17 @@ |
| 43993 | 44015 | */ |
| 43994 | 44016 | #define WAL_NORMAL_MODE 0 |
| 43995 | 44017 | #define WAL_EXCLUSIVE_MODE 1 |
| 43996 | 44018 | #define WAL_HEAPMEMORY_MODE 2 |
| 43997 | 44019 | |
| 44020 | +/* |
| 44021 | +** Possible values for WAL.readOnly |
| 44022 | +*/ |
| 44023 | +#define WAL_RDWR 0 /* Normal read/write connection */ |
| 44024 | +#define WAL_RDONLY 1 /* The WAL file is readonly */ |
| 44025 | +#define WAL_SHM_RDONLY 2 /* The SHM file is readonly */ |
| 44026 | + |
| 43998 | 44027 | /* |
| 43999 | 44028 | ** Each page of the wal-index mapping contains a hash-table made up of |
| 44000 | 44029 | ** an array of HASHTABLE_NSLOT elements of the following type. |
| 44001 | 44030 | */ |
| 44002 | 44031 | typedef u16 ht_slot; |
| | @@ -44086,10 +44115,14 @@ |
| 44086 | 44115 | if( !pWal->apWiData[iPage] ) rc = SQLITE_NOMEM; |
| 44087 | 44116 | }else{ |
| 44088 | 44117 | rc = sqlite3OsShmMap(pWal->pDbFd, iPage, WALINDEX_PGSZ, |
| 44089 | 44118 | pWal->writeLock, (void volatile **)&pWal->apWiData[iPage] |
| 44090 | 44119 | ); |
| 44120 | + if( rc==SQLITE_READONLY ){ |
| 44121 | + pWal->readOnly |= WAL_SHM_RDONLY; |
| 44122 | + rc = SQLITE_OK; |
| 44123 | + } |
| 44091 | 44124 | } |
| 44092 | 44125 | } |
| 44093 | 44126 | |
| 44094 | 44127 | *ppPage = pWal->apWiData[iPage]; |
| 44095 | 44128 | assert( iPage==0 || *ppPage || rc!=SQLITE_OK ); |
| | @@ -44833,11 +44866,11 @@ |
| 44833 | 44866 | |
| 44834 | 44867 | /* Open file handle on the write-ahead log file. */ |
| 44835 | 44868 | flags = (SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|SQLITE_OPEN_WAL); |
| 44836 | 44869 | rc = sqlite3OsOpen(pVfs, zWalName, pRet->pWalFd, flags, &flags); |
| 44837 | 44870 | if( rc==SQLITE_OK && flags&SQLITE_OPEN_READONLY ){ |
| 44838 | | - pRet->readOnly = 1; |
| 44871 | + pRet->readOnly = WAL_RDONLY; |
| 44839 | 44872 | } |
| 44840 | 44873 | |
| 44841 | 44874 | if( rc!=SQLITE_OK ){ |
| 44842 | 44875 | walIndexClose(pRet, 0); |
| 44843 | 44876 | sqlite3OsClose(pRet->pWalFd); |
| | @@ -45474,25 +45507,32 @@ |
| 45474 | 45507 | |
| 45475 | 45508 | /* If the first attempt failed, it might have been due to a race |
| 45476 | 45509 | ** with a writer. So get a WRITE lock and try again. |
| 45477 | 45510 | */ |
| 45478 | 45511 | assert( badHdr==0 || pWal->writeLock==0 ); |
| 45479 | | - if( badHdr && SQLITE_OK==(rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1)) ){ |
| 45480 | | - pWal->writeLock = 1; |
| 45481 | | - if( SQLITE_OK==(rc = walIndexPage(pWal, 0, &page0)) ){ |
| 45482 | | - badHdr = walIndexTryHdr(pWal, pChanged); |
| 45483 | | - if( badHdr ){ |
| 45484 | | - /* If the wal-index header is still malformed even while holding |
| 45485 | | - ** a WRITE lock, it can only mean that the header is corrupted and |
| 45486 | | - ** needs to be reconstructed. So run recovery to do exactly that. |
| 45487 | | - */ |
| 45488 | | - rc = walIndexRecover(pWal); |
| 45489 | | - *pChanged = 1; |
| 45490 | | - } |
| 45491 | | - } |
| 45492 | | - pWal->writeLock = 0; |
| 45493 | | - walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1); |
| 45512 | + if( badHdr ){ |
| 45513 | + if( pWal->readOnly & WAL_SHM_RDONLY ){ |
| 45514 | + if( SQLITE_OK==(rc = walLockShared(pWal, WAL_WRITE_LOCK)) ){ |
| 45515 | + walUnlockShared(pWal, WAL_WRITE_LOCK); |
| 45516 | + rc = SQLITE_READONLY_RECOVERY; |
| 45517 | + } |
| 45518 | + }else if( SQLITE_OK==(rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1)) ){ |
| 45519 | + pWal->writeLock = 1; |
| 45520 | + if( SQLITE_OK==(rc = walIndexPage(pWal, 0, &page0)) ){ |
| 45521 | + badHdr = walIndexTryHdr(pWal, pChanged); |
| 45522 | + if( badHdr ){ |
| 45523 | + /* If the wal-index header is still malformed even while holding |
| 45524 | + ** a WRITE lock, it can only mean that the header is corrupted and |
| 45525 | + ** needs to be reconstructed. So run recovery to do exactly that. |
| 45526 | + */ |
| 45527 | + rc = walIndexRecover(pWal); |
| 45528 | + *pChanged = 1; |
| 45529 | + } |
| 45530 | + } |
| 45531 | + pWal->writeLock = 0; |
| 45532 | + walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1); |
| 45533 | + } |
| 45494 | 45534 | } |
| 45495 | 45535 | |
| 45496 | 45536 | /* If the header is read successfully, check the version number to make |
| 45497 | 45537 | ** sure the wal-index was not constructed with some future format that |
| 45498 | 45538 | ** this version of SQLite cannot understand. |
| | @@ -45675,11 +45715,13 @@ |
| 45675 | 45715 | mxI = i; |
| 45676 | 45716 | } |
| 45677 | 45717 | } |
| 45678 | 45718 | /* There was once an "if" here. The extra "{" is to preserve indentation. */ |
| 45679 | 45719 | { |
| 45680 | | - if( mxReadMark < pWal->hdr.mxFrame || mxI==0 ){ |
| 45720 | + if( (pWal->readOnly & WAL_SHM_RDONLY)==0 |
| 45721 | + && (mxReadMark<pWal->hdr.mxFrame || mxI==0) |
| 45722 | + ){ |
| 45681 | 45723 | for(i=1; i<WAL_NREADER; i++){ |
| 45682 | 45724 | rc = walLockExclusive(pWal, WAL_READ_LOCK(i), 1); |
| 45683 | 45725 | if( rc==SQLITE_OK ){ |
| 45684 | 45726 | mxReadMark = pInfo->aReadMark[i] = pWal->hdr.mxFrame; |
| 45685 | 45727 | mxI = i; |
| | @@ -45689,12 +45731,12 @@ |
| 45689 | 45731 | return rc; |
| 45690 | 45732 | } |
| 45691 | 45733 | } |
| 45692 | 45734 | } |
| 45693 | 45735 | if( mxI==0 ){ |
| 45694 | | - assert( rc==SQLITE_BUSY ); |
| 45695 | | - return WAL_RETRY; |
| 45736 | + assert( rc==SQLITE_BUSY || (pWal->readOnly & WAL_SHM_RDONLY)!=0 ); |
| 45737 | + return rc==SQLITE_BUSY ? WAL_RETRY : SQLITE_READONLY_CANTLOCK; |
| 45696 | 45738 | } |
| 45697 | 45739 | |
| 45698 | 45740 | rc = walLockShared(pWal, WAL_READ_LOCK(mxI)); |
| 45699 | 45741 | if( rc ){ |
| 45700 | 45742 | return rc==SQLITE_BUSY ? WAL_RETRY : rc; |
| | @@ -46096,14 +46138,16 @@ |
| 46096 | 46138 | ** set to a non-negative value. Log errors encountered |
| 46097 | 46139 | ** during the truncation attempt. */ |
| 46098 | 46140 | if( pWal->mxWalSize>=0 ){ |
| 46099 | 46141 | i64 sz; |
| 46100 | 46142 | int rx; |
| 46143 | + sqlite3BeginBenignMalloc(); |
| 46101 | 46144 | rx = sqlite3OsFileSize(pWal->pWalFd, &sz); |
| 46102 | 46145 | if( rx==SQLITE_OK && (sz > pWal->mxWalSize) ){ |
| 46103 | 46146 | rx = sqlite3OsTruncate(pWal->pWalFd, pWal->mxWalSize); |
| 46104 | 46147 | } |
| 46148 | + sqlite3EndBenignMalloc(); |
| 46105 | 46149 | if( rx ){ |
| 46106 | 46150 | sqlite3_log(rx, "cannot limit WAL size: %s", pWal->zWalName); |
| 46107 | 46151 | } |
| 46108 | 46152 | } |
| 46109 | 46153 | |
| | @@ -46330,10 +46374,11 @@ |
| 46330 | 46374 | int eMode2 = eMode; /* Mode to pass to walCheckpoint() */ |
| 46331 | 46375 | |
| 46332 | 46376 | assert( pWal->ckptLock==0 ); |
| 46333 | 46377 | assert( pWal->writeLock==0 ); |
| 46334 | 46378 | |
| 46379 | + if( pWal->readOnly ) return SQLITE_READONLY; |
| 46335 | 46380 | WALTRACE(("WAL%p: checkpoint begins\n", pWal)); |
| 46336 | 46381 | rc = walLockExclusive(pWal, WAL_CKPT_LOCK, 1); |
| 46337 | 46382 | if( rc ){ |
| 46338 | 46383 | /* Usually this is SQLITE_BUSY meaning that another thread or process |
| 46339 | 46384 | ** is already running a checkpoint, or maybe a recovery. But it might |
| | @@ -52812,14 +52857,14 @@ |
| 52812 | 52857 | ** removes the reference to the cell from pPage. |
| 52813 | 52858 | ** |
| 52814 | 52859 | ** "sz" must be the number of bytes in the cell. |
| 52815 | 52860 | */ |
| 52816 | 52861 | static void dropCell(MemPage *pPage, int idx, int sz, int *pRC){ |
| 52817 | | - int i; /* Loop counter */ |
| 52818 | 52862 | u32 pc; /* Offset to cell content of cell being deleted */ |
| 52819 | 52863 | u8 *data; /* pPage->aData */ |
| 52820 | 52864 | u8 *ptr; /* Used to move bytes around within data[] */ |
| 52865 | + u8 *endPtr; /* End of loop */ |
| 52821 | 52866 | int rc; /* The return code */ |
| 52822 | 52867 | int hdr; /* Beginning of the header. 0 most pages. 100 page 1 */ |
| 52823 | 52868 | |
| 52824 | 52869 | if( *pRC ) return; |
| 52825 | 52870 | |
| | @@ -52840,13 +52885,15 @@ |
| 52840 | 52885 | rc = freeSpace(pPage, pc, sz); |
| 52841 | 52886 | if( rc ){ |
| 52842 | 52887 | *pRC = rc; |
| 52843 | 52888 | return; |
| 52844 | 52889 | } |
| 52845 | | - for(i=idx+1; i<pPage->nCell; i++, ptr+=2){ |
| 52890 | + endPtr = &data[pPage->cellOffset + 2*pPage->nCell - 2]; |
| 52891 | + while( ptr<endPtr ){ |
| 52846 | 52892 | ptr[0] = ptr[2]; |
| 52847 | 52893 | ptr[1] = ptr[3]; |
| 52894 | + ptr += 2; |
| 52848 | 52895 | } |
| 52849 | 52896 | pPage->nCell--; |
| 52850 | 52897 | put2byte(&data[hdr+3], pPage->nCell); |
| 52851 | 52898 | pPage->nFree += 2; |
| 52852 | 52899 | } |
| | @@ -58825,38 +58872,17 @@ |
| 58825 | 58872 | } |
| 58826 | 58873 | return pBuf; |
| 58827 | 58874 | } |
| 58828 | 58875 | |
| 58829 | 58876 | /* |
| 58830 | | -** Prepare a virtual machine for execution. This involves things such |
| 58831 | | -** as allocating stack space and initializing the program counter. |
| 58832 | | -** After the VDBE has be prepped, it can be executed by one or more |
| 58833 | | -** calls to sqlite3VdbeExec(). |
| 58834 | | -** |
| 58835 | | -** This is the only way to move a VDBE from VDBE_MAGIC_INIT to |
| 58836 | | -** VDBE_MAGIC_RUN. |
| 58837 | | -** |
| 58838 | | -** This function may be called more than once on a single virtual machine. |
| 58839 | | -** The first call is made while compiling the SQL statement. Subsequent |
| 58840 | | -** calls are made as part of the process of resetting a statement to be |
| 58841 | | -** re-executed (from a call to sqlite3_reset()). The nVar, nMem, nCursor |
| 58842 | | -** and isExplain parameters are only passed correct values the first time |
| 58843 | | -** the function is called. On subsequent calls, from sqlite3_reset(), nVar |
| 58844 | | -** is passed -1 and nMem, nCursor and isExplain are all passed zero. |
| 58877 | +** Rewind the VDBE back to the beginning in preparation for |
| 58878 | +** running it. |
| 58845 | 58879 | */ |
| 58846 | | -SQLITE_PRIVATE void sqlite3VdbeMakeReady( |
| 58847 | | - Vdbe *p, /* The VDBE */ |
| 58848 | | - int nVar, /* Number of '?' see in the SQL statement */ |
| 58849 | | - int nMem, /* Number of memory cells to allocate */ |
| 58850 | | - int nCursor, /* Number of cursors to allocate */ |
| 58851 | | - int nArg, /* Maximum number of args in SubPrograms */ |
| 58852 | | - int isExplain, /* True if the EXPLAIN keywords is present */ |
| 58853 | | - int usesStmtJournal /* True to set Vdbe.usesStmtJournal */ |
| 58854 | | -){ |
| 58855 | | - int n; |
| 58856 | | - sqlite3 *db = p->db; |
| 58857 | | - |
| 58880 | +SQLITE_PRIVATE void sqlite3VdbeRewind(Vdbe *p){ |
| 58881 | +#if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE) |
| 58882 | + int i; |
| 58883 | +#endif |
| 58858 | 58884 | assert( p!=0 ); |
| 58859 | 58885 | assert( p->magic==VDBE_MAGIC_INIT ); |
| 58860 | 58886 | |
| 58861 | 58887 | /* There should be at least one opcode. |
| 58862 | 58888 | */ |
| | @@ -58863,10 +58889,75 @@ |
| 58863 | 58889 | assert( p->nOp>0 ); |
| 58864 | 58890 | |
| 58865 | 58891 | /* Set the magic to VDBE_MAGIC_RUN sooner rather than later. */ |
| 58866 | 58892 | p->magic = VDBE_MAGIC_RUN; |
| 58867 | 58893 | |
| 58894 | +#ifdef SQLITE_DEBUG |
| 58895 | + for(i=1; i<p->nMem; i++){ |
| 58896 | + assert( p->aMem[i].db==p->db ); |
| 58897 | + } |
| 58898 | +#endif |
| 58899 | + p->pc = -1; |
| 58900 | + p->rc = SQLITE_OK; |
| 58901 | + p->errorAction = OE_Abort; |
| 58902 | + p->magic = VDBE_MAGIC_RUN; |
| 58903 | + p->nChange = 0; |
| 58904 | + p->cacheCtr = 1; |
| 58905 | + p->minWriteFileFormat = 255; |
| 58906 | + p->iStatement = 0; |
| 58907 | + p->nFkConstraint = 0; |
| 58908 | +#ifdef VDBE_PROFILE |
| 58909 | + for(i=0; i<p->nOp; i++){ |
| 58910 | + p->aOp[i].cnt = 0; |
| 58911 | + p->aOp[i].cycles = 0; |
| 58912 | + } |
| 58913 | +#endif |
| 58914 | +} |
| 58915 | + |
| 58916 | +/* |
| 58917 | +** Prepare a virtual machine for execution for the first time after |
| 58918 | +** creating the virtual machine. This involves things such |
| 58919 | +** as allocating stack space and initializing the program counter. |
| 58920 | +** After the VDBE has be prepped, it can be executed by one or more |
| 58921 | +** calls to sqlite3VdbeExec(). |
| 58922 | +** |
| 58923 | +** This function may be called exact once on a each virtual machine. |
| 58924 | +** After this routine is called the VM has been "packaged" and is ready |
| 58925 | +** to run. After this routine is called, futher calls to |
| 58926 | +** sqlite3VdbeAddOp() functions are prohibited. This routine disconnects |
| 58927 | +** the Vdbe from the Parse object that helped generate it so that the |
| 58928 | +** the Vdbe becomes an independent entity and the Parse object can be |
| 58929 | +** destroyed. |
| 58930 | +** |
| 58931 | +** Use the sqlite3VdbeRewind() procedure to restore a virtual machine back |
| 58932 | +** to its initial state after it has been run. |
| 58933 | +*/ |
| 58934 | +SQLITE_PRIVATE void sqlite3VdbeMakeReady( |
| 58935 | + Vdbe *p, /* The VDBE */ |
| 58936 | + Parse *pParse /* Parsing context */ |
| 58937 | +){ |
| 58938 | + sqlite3 *db; /* The database connection */ |
| 58939 | + int nVar; /* Number of parameters */ |
| 58940 | + int nMem; /* Number of VM memory registers */ |
| 58941 | + int nCursor; /* Number of cursors required */ |
| 58942 | + int nArg; /* Number of arguments in subprograms */ |
| 58943 | + int n; /* Loop counter */ |
| 58944 | + u8 *zCsr; /* Memory available for allocation */ |
| 58945 | + u8 *zEnd; /* First byte past allocated memory */ |
| 58946 | + int nByte; /* How much extra memory is needed */ |
| 58947 | + |
| 58948 | + assert( p!=0 ); |
| 58949 | + assert( p->nOp>0 ); |
| 58950 | + assert( pParse!=0 ); |
| 58951 | + assert( p->magic==VDBE_MAGIC_INIT ); |
| 58952 | + db = p->db; |
| 58953 | + assert( db->mallocFailed==0 ); |
| 58954 | + nVar = pParse->nVar; |
| 58955 | + nMem = pParse->nMem; |
| 58956 | + nCursor = pParse->nTab; |
| 58957 | + nArg = pParse->nMaxArg; |
| 58958 | + |
| 58868 | 58959 | /* For each cursor required, also allocate a memory cell. Memory |
| 58869 | 58960 | ** cells (nMem+1-nCursor)..nMem, inclusive, will never be used by |
| 58870 | 58961 | ** the vdbe program. Instead they are used to allocate space for |
| 58871 | 58962 | ** VdbeCursor/BtCursor structures. The blob of memory associated with |
| 58872 | 58963 | ** cursor 0 is stored in memory cell nMem. Memory cell (nMem-1) |
| | @@ -58875,95 +58966,72 @@ |
| 58875 | 58966 | ** See also: allocateCursor(). |
| 58876 | 58967 | */ |
| 58877 | 58968 | nMem += nCursor; |
| 58878 | 58969 | |
| 58879 | 58970 | /* Allocate space for memory registers, SQL variables, VDBE cursors and |
| 58880 | | - ** an array to marshal SQL function arguments in. This is only done the |
| 58881 | | - ** first time this function is called for a given VDBE, not when it is |
| 58882 | | - ** being called from sqlite3_reset() to reset the virtual machine. |
| 58883 | | - */ |
| 58884 | | - if( nVar>=0 && ALWAYS(db->mallocFailed==0) ){ |
| 58885 | | - u8 *zCsr = (u8 *)&p->aOp[p->nOp]; /* Memory avaliable for alloation */ |
| 58886 | | - u8 *zEnd = (u8 *)&p->aOp[p->nOpAlloc]; /* First byte past available mem */ |
| 58887 | | - int nByte; /* How much extra memory needed */ |
| 58888 | | - |
| 58889 | | - resolveP2Values(p, &nArg); |
| 58890 | | - p->usesStmtJournal = (u8)usesStmtJournal; |
| 58891 | | - if( isExplain && nMem<10 ){ |
| 58892 | | - nMem = 10; |
| 58893 | | - } |
| 58894 | | - memset(zCsr, 0, zEnd-zCsr); |
| 58895 | | - zCsr += (zCsr - (u8*)0)&7; |
| 58896 | | - assert( EIGHT_BYTE_ALIGNMENT(zCsr) ); |
| 58897 | | - |
| 58898 | | - /* Memory for registers, parameters, cursor, etc, is allocated in two |
| 58899 | | - ** passes. On the first pass, we try to reuse unused space at the |
| 58900 | | - ** end of the opcode array. If we are unable to satisfy all memory |
| 58901 | | - ** requirements by reusing the opcode array tail, then the second |
| 58902 | | - ** pass will fill in the rest using a fresh allocation. |
| 58903 | | - ** |
| 58904 | | - ** This two-pass approach that reuses as much memory as possible from |
| 58905 | | - ** the leftover space at the end of the opcode array can significantly |
| 58906 | | - ** reduce the amount of memory held by a prepared statement. |
| 58907 | | - */ |
| 58908 | | - do { |
| 58909 | | - nByte = 0; |
| 58910 | | - p->aMem = allocSpace(p->aMem, nMem*sizeof(Mem), &zCsr, zEnd, &nByte); |
| 58911 | | - p->aVar = allocSpace(p->aVar, nVar*sizeof(Mem), &zCsr, zEnd, &nByte); |
| 58912 | | - p->apArg = allocSpace(p->apArg, nArg*sizeof(Mem*), &zCsr, zEnd, &nByte); |
| 58913 | | - p->azVar = allocSpace(p->azVar, nVar*sizeof(char*), &zCsr, zEnd, &nByte); |
| 58914 | | - p->apCsr = allocSpace(p->apCsr, nCursor*sizeof(VdbeCursor*), |
| 58915 | | - &zCsr, zEnd, &nByte); |
| 58916 | | - if( nByte ){ |
| 58917 | | - p->pFree = sqlite3DbMallocZero(db, nByte); |
| 58918 | | - } |
| 58919 | | - zCsr = p->pFree; |
| 58920 | | - zEnd = &zCsr[nByte]; |
| 58921 | | - }while( nByte && !db->mallocFailed ); |
| 58922 | | - |
| 58923 | | - p->nCursor = (u16)nCursor; |
| 58924 | | - if( p->aVar ){ |
| 58925 | | - p->nVar = (ynVar)nVar; |
| 58926 | | - for(n=0; n<nVar; n++){ |
| 58927 | | - p->aVar[n].flags = MEM_Null; |
| 58928 | | - p->aVar[n].db = db; |
| 58929 | | - } |
| 58930 | | - } |
| 58931 | | - if( p->aMem ){ |
| 58932 | | - p->aMem--; /* aMem[] goes from 1..nMem */ |
| 58933 | | - p->nMem = nMem; /* not from 0..nMem-1 */ |
| 58934 | | - for(n=1; n<=nMem; n++){ |
| 58935 | | - p->aMem[n].flags = MEM_Null; |
| 58936 | | - p->aMem[n].db = db; |
| 58937 | | - } |
| 58938 | | - } |
| 58939 | | - } |
| 58940 | | -#ifdef SQLITE_DEBUG |
| 58941 | | - for(n=1; n<p->nMem; n++){ |
| 58942 | | - assert( p->aMem[n].db==db ); |
| 58943 | | - } |
| 58944 | | -#endif |
| 58945 | | - |
| 58946 | | - p->pc = -1; |
| 58947 | | - p->rc = SQLITE_OK; |
| 58948 | | - p->errorAction = OE_Abort; |
| 58949 | | - p->explain |= isExplain; |
| 58950 | | - p->magic = VDBE_MAGIC_RUN; |
| 58951 | | - p->nChange = 0; |
| 58952 | | - p->cacheCtr = 1; |
| 58953 | | - p->minWriteFileFormat = 255; |
| 58954 | | - p->iStatement = 0; |
| 58955 | | - p->nFkConstraint = 0; |
| 58956 | | -#ifdef VDBE_PROFILE |
| 58957 | | - { |
| 58958 | | - int i; |
| 58959 | | - for(i=0; i<p->nOp; i++){ |
| 58960 | | - p->aOp[i].cnt = 0; |
| 58961 | | - p->aOp[i].cycles = 0; |
| 58962 | | - } |
| 58963 | | - } |
| 58964 | | -#endif |
| 58971 | + ** an array to marshal SQL function arguments in. |
| 58972 | + */ |
| 58973 | + zCsr = (u8*)&p->aOp[p->nOp]; /* Memory avaliable for allocation */ |
| 58974 | + zEnd = (u8*)&p->aOp[p->nOpAlloc]; /* First byte past end of zCsr[] */ |
| 58975 | + |
| 58976 | + resolveP2Values(p, &nArg); |
| 58977 | + p->usesStmtJournal = (u8)(pParse->isMultiWrite && pParse->mayAbort); |
| 58978 | + if( pParse->explain && nMem<10 ){ |
| 58979 | + nMem = 10; |
| 58980 | + } |
| 58981 | + memset(zCsr, 0, zEnd-zCsr); |
| 58982 | + zCsr += (zCsr - (u8*)0)&7; |
| 58983 | + assert( EIGHT_BYTE_ALIGNMENT(zCsr) ); |
| 58984 | + |
| 58985 | + /* Memory for registers, parameters, cursor, etc, is allocated in two |
| 58986 | + ** passes. On the first pass, we try to reuse unused space at the |
| 58987 | + ** end of the opcode array. If we are unable to satisfy all memory |
| 58988 | + ** requirements by reusing the opcode array tail, then the second |
| 58989 | + ** pass will fill in the rest using a fresh allocation. |
| 58990 | + ** |
| 58991 | + ** This two-pass approach that reuses as much memory as possible from |
| 58992 | + ** the leftover space at the end of the opcode array can significantly |
| 58993 | + ** reduce the amount of memory held by a prepared statement. |
| 58994 | + */ |
| 58995 | + do { |
| 58996 | + nByte = 0; |
| 58997 | + p->aMem = allocSpace(p->aMem, nMem*sizeof(Mem), &zCsr, zEnd, &nByte); |
| 58998 | + p->aVar = allocSpace(p->aVar, nVar*sizeof(Mem), &zCsr, zEnd, &nByte); |
| 58999 | + p->apArg = allocSpace(p->apArg, nArg*sizeof(Mem*), &zCsr, zEnd, &nByte); |
| 59000 | + p->azVar = allocSpace(p->azVar, nVar*sizeof(char*), &zCsr, zEnd, &nByte); |
| 59001 | + p->apCsr = allocSpace(p->apCsr, nCursor*sizeof(VdbeCursor*), |
| 59002 | + &zCsr, zEnd, &nByte); |
| 59003 | + if( nByte ){ |
| 59004 | + p->pFree = sqlite3DbMallocZero(db, nByte); |
| 59005 | + } |
| 59006 | + zCsr = p->pFree; |
| 59007 | + zEnd = &zCsr[nByte]; |
| 59008 | + }while( nByte && !db->mallocFailed ); |
| 59009 | + |
| 59010 | + p->nCursor = (u16)nCursor; |
| 59011 | + if( p->aVar ){ |
| 59012 | + p->nVar = (ynVar)nVar; |
| 59013 | + for(n=0; n<nVar; n++){ |
| 59014 | + p->aVar[n].flags = MEM_Null; |
| 59015 | + p->aVar[n].db = db; |
| 59016 | + } |
| 59017 | + } |
| 59018 | + if( p->azVar ){ |
| 59019 | + p->nzVar = pParse->nzVar; |
| 59020 | + memcpy(p->azVar, pParse->azVar, p->nzVar*sizeof(p->azVar[0])); |
| 59021 | + memset(pParse->azVar, 0, pParse->nzVar*sizeof(pParse->azVar[0])); |
| 59022 | + } |
| 59023 | + if( p->aMem ){ |
| 59024 | + p->aMem--; /* aMem[] goes from 1..nMem */ |
| 59025 | + p->nMem = nMem; /* not from 0..nMem-1 */ |
| 59026 | + for(n=1; n<=nMem; n++){ |
| 59027 | + p->aMem[n].flags = MEM_Null; |
| 59028 | + p->aMem[n].db = db; |
| 59029 | + } |
| 59030 | + } |
| 59031 | + p->explain = pParse->explain; |
| 59032 | + sqlite3VdbeRewind(p); |
| 58965 | 59033 | } |
| 58966 | 59034 | |
| 58967 | 59035 | /* |
| 58968 | 59036 | ** Close a VDBE cursor and release all the resources that cursor |
| 58969 | 59037 | ** happens to hold. |
| | @@ -59636,21 +59704,15 @@ |
| 59636 | 59704 | /* If eStatementOp is non-zero, then a statement transaction needs to |
| 59637 | 59705 | ** be committed or rolled back. Call sqlite3VdbeCloseStatement() to |
| 59638 | 59706 | ** do so. If this operation returns an error, and the current statement |
| 59639 | 59707 | ** error code is SQLITE_OK or SQLITE_CONSTRAINT, then promote the |
| 59640 | 59708 | ** current statement error code. |
| 59641 | | - ** |
| 59642 | | - ** Note that sqlite3VdbeCloseStatement() can only fail if eStatementOp |
| 59643 | | - ** is SAVEPOINT_ROLLBACK. But if p->rc==SQLITE_OK then eStatementOp |
| 59644 | | - ** must be SAVEPOINT_RELEASE. Hence the NEVER(p->rc==SQLITE_OK) in |
| 59645 | | - ** the following code. |
| 59646 | 59709 | */ |
| 59647 | 59710 | if( eStatementOp ){ |
| 59648 | 59711 | rc = sqlite3VdbeCloseStatement(p, eStatementOp); |
| 59649 | 59712 | if( rc ){ |
| 59650 | | - assert( eStatementOp==SAVEPOINT_ROLLBACK ); |
| 59651 | | - if( NEVER(p->rc==SQLITE_OK) || p->rc==SQLITE_CONSTRAINT ){ |
| 59713 | + if( p->rc==SQLITE_OK || p->rc==SQLITE_CONSTRAINT ){ |
| 59652 | 59714 | p->rc = rc; |
| 59653 | 59715 | sqlite3DbFree(db, p->zErrMsg); |
| 59654 | 59716 | p->zErrMsg = 0; |
| 59655 | 59717 | } |
| 59656 | 59718 | invalidateCursorsOnModifiedBtrees(db); |
| | @@ -59839,18 +59901,20 @@ |
| 59839 | 59901 | ** VdbeDelete() also unlinks the Vdbe from the list of VMs associated with |
| 59840 | 59902 | ** the database connection. |
| 59841 | 59903 | */ |
| 59842 | 59904 | SQLITE_PRIVATE void sqlite3VdbeDeleteObject(sqlite3 *db, Vdbe *p){ |
| 59843 | 59905 | SubProgram *pSub, *pNext; |
| 59906 | + int i; |
| 59844 | 59907 | assert( p->db==0 || p->db==db ); |
| 59845 | 59908 | releaseMemArray(p->aVar, p->nVar); |
| 59846 | 59909 | releaseMemArray(p->aColName, p->nResColumn*COLNAME_N); |
| 59847 | 59910 | for(pSub=p->pProgram; pSub; pSub=pNext){ |
| 59848 | 59911 | pNext = pSub->pNext; |
| 59849 | 59912 | vdbeFreeOpArray(db, pSub->aOp, pSub->nOp); |
| 59850 | 59913 | sqlite3DbFree(db, pSub); |
| 59851 | 59914 | } |
| 59915 | + for(i=p->nzVar-1; i>=0; i--) sqlite3DbFree(db, p->azVar[i]); |
| 59852 | 59916 | vdbeFreeOpArray(db, p->aOp, p->nOp); |
| 59853 | 59917 | sqlite3DbFree(db, p->aLabel); |
| 59854 | 59918 | sqlite3DbFree(db, p->aColName); |
| 59855 | 59919 | sqlite3DbFree(db, p->zSql); |
| 59856 | 59920 | sqlite3DbFree(db, p->pFree); |
| | @@ -60292,11 +60356,11 @@ |
| 60292 | 60356 | u32 serial_type; |
| 60293 | 60357 | |
| 60294 | 60358 | idx += getVarint32(&aKey[idx], serial_type); |
| 60295 | 60359 | pMem->enc = pKeyInfo->enc; |
| 60296 | 60360 | pMem->db = pKeyInfo->db; |
| 60297 | | - pMem->flags = 0; |
| 60361 | + /* pMem->flags = 0; // sqlite3VdbeSerialGet() will set this for us */ |
| 60298 | 60362 | pMem->zMalloc = 0; |
| 60299 | 60363 | d += sqlite3VdbeSerialGet(&aKey[d], serial_type, pMem); |
| 60300 | 60364 | pMem++; |
| 60301 | 60365 | u++; |
| 60302 | 60366 | } |
| | @@ -60307,10 +60371,11 @@ |
| 60307 | 60371 | |
| 60308 | 60372 | /* |
| 60309 | 60373 | ** This routine destroys a UnpackedRecord object. |
| 60310 | 60374 | */ |
| 60311 | 60375 | SQLITE_PRIVATE void sqlite3VdbeDeleteUnpackedRecord(UnpackedRecord *p){ |
| 60376 | +#ifdef SQLITE_DEBUG |
| 60312 | 60377 | int i; |
| 60313 | 60378 | Mem *pMem; |
| 60314 | 60379 | |
| 60315 | 60380 | assert( p!=0 ); |
| 60316 | 60381 | assert( p->flags & UNPACKED_NEED_DESTROY ); |
| | @@ -60320,10 +60385,11 @@ |
| 60320 | 60385 | ** strings and blobs static. And none of the elements are |
| 60321 | 60386 | ** ever transformed, so there is never anything to delete. |
| 60322 | 60387 | */ |
| 60323 | 60388 | if( NEVER(pMem->zMalloc) ) sqlite3VdbeMemRelease(pMem); |
| 60324 | 60389 | } |
| 60390 | +#endif |
| 60325 | 60391 | if( p->flags & UNPACKED_NEED_FREE ){ |
| 60326 | 60392 | sqlite3DbFree(p->pKeyInfo->db, p); |
| 60327 | 60393 | } |
| 60328 | 60394 | } |
| 60329 | 60395 | |
| | @@ -60755,11 +60821,11 @@ |
| 60755 | 60821 | rc = SQLITE_OK; |
| 60756 | 60822 | }else{ |
| 60757 | 60823 | Vdbe *v = (Vdbe*)pStmt; |
| 60758 | 60824 | sqlite3_mutex_enter(v->db->mutex); |
| 60759 | 60825 | rc = sqlite3VdbeReset(v); |
| 60760 | | - sqlite3VdbeMakeReady(v, -1, 0, 0, 0, 0, 0); |
| 60826 | + sqlite3VdbeRewind(v); |
| 60761 | 60827 | assert( (rc & (v->db->errMask))==rc ); |
| 60762 | 60828 | rc = sqlite3ApiExit(v->db, rc); |
| 60763 | 60829 | sqlite3_mutex_leave(v->db->mutex); |
| 60764 | 60830 | } |
| 60765 | 60831 | return rc; |
| | @@ -61820,48 +61886,21 @@ |
| 61820 | 61886 | SQLITE_API int sqlite3_bind_parameter_count(sqlite3_stmt *pStmt){ |
| 61821 | 61887 | Vdbe *p = (Vdbe*)pStmt; |
| 61822 | 61888 | return p ? p->nVar : 0; |
| 61823 | 61889 | } |
| 61824 | 61890 | |
| 61825 | | -/* |
| 61826 | | -** Create a mapping from variable numbers to variable names |
| 61827 | | -** in the Vdbe.azVar[] array, if such a mapping does not already |
| 61828 | | -** exist. |
| 61829 | | -*/ |
| 61830 | | -static void createVarMap(Vdbe *p){ |
| 61831 | | - if( !p->okVar ){ |
| 61832 | | - int j; |
| 61833 | | - Op *pOp; |
| 61834 | | - sqlite3_mutex_enter(p->db->mutex); |
| 61835 | | - /* The race condition here is harmless. If two threads call this |
| 61836 | | - ** routine on the same Vdbe at the same time, they both might end |
| 61837 | | - ** up initializing the Vdbe.azVar[] array. That is a little extra |
| 61838 | | - ** work but it results in the same answer. |
| 61839 | | - */ |
| 61840 | | - for(j=0, pOp=p->aOp; j<p->nOp; j++, pOp++){ |
| 61841 | | - if( pOp->opcode==OP_Variable ){ |
| 61842 | | - assert( pOp->p1>0 && pOp->p1<=p->nVar ); |
| 61843 | | - p->azVar[pOp->p1-1] = pOp->p4.z; |
| 61844 | | - } |
| 61845 | | - } |
| 61846 | | - p->okVar = 1; |
| 61847 | | - sqlite3_mutex_leave(p->db->mutex); |
| 61848 | | - } |
| 61849 | | -} |
| 61850 | | - |
| 61851 | 61891 | /* |
| 61852 | 61892 | ** Return the name of a wildcard parameter. Return NULL if the index |
| 61853 | 61893 | ** is out of range or if the wildcard is unnamed. |
| 61854 | 61894 | ** |
| 61855 | 61895 | ** The result is always UTF-8. |
| 61856 | 61896 | */ |
| 61857 | 61897 | SQLITE_API const char *sqlite3_bind_parameter_name(sqlite3_stmt *pStmt, int i){ |
| 61858 | 61898 | Vdbe *p = (Vdbe*)pStmt; |
| 61859 | | - if( p==0 || i<1 || i>p->nVar ){ |
| 61899 | + if( p==0 || i<1 || i>p->nzVar ){ |
| 61860 | 61900 | return 0; |
| 61861 | 61901 | } |
| 61862 | | - createVarMap(p); |
| 61863 | 61902 | return p->azVar[i-1]; |
| 61864 | 61903 | } |
| 61865 | 61904 | |
| 61866 | 61905 | /* |
| 61867 | 61906 | ** Given a wildcard parameter name, return the index of the variable |
| | @@ -61871,13 +61910,12 @@ |
| 61871 | 61910 | SQLITE_PRIVATE int sqlite3VdbeParameterIndex(Vdbe *p, const char *zName, int nName){ |
| 61872 | 61911 | int i; |
| 61873 | 61912 | if( p==0 ){ |
| 61874 | 61913 | return 0; |
| 61875 | 61914 | } |
| 61876 | | - createVarMap(p); |
| 61877 | 61915 | if( zName ){ |
| 61878 | | - for(i=0; i<p->nVar; i++){ |
| 61916 | + for(i=0; i<p->nzVar; i++){ |
| 61879 | 61917 | const char *z = p->azVar[i]; |
| 61880 | 61918 | if( z && memcmp(z,zName,nName)==0 && z[nName]==0 ){ |
| 61881 | 61919 | return i+1; |
| 61882 | 61920 | } |
| 61883 | 61921 | } |
| | @@ -63197,10 +63235,11 @@ |
| 63197 | 63235 | Mem **apArg; |
| 63198 | 63236 | Mem *pX; |
| 63199 | 63237 | } cm; |
| 63200 | 63238 | struct OP_Trace_stack_vars { |
| 63201 | 63239 | char *zTrace; |
| 63240 | + char *z; |
| 63202 | 63241 | } cn; |
| 63203 | 63242 | } u; |
| 63204 | 63243 | /* End automatically generated code |
| 63205 | 63244 | ********************************************************************/ |
| 63206 | 63245 | |
| | @@ -63623,10 +63662,11 @@ |
| 63623 | 63662 | #if 0 /* local variables moved into u.ab */ |
| 63624 | 63663 | Mem *pVar; /* Value being transferred */ |
| 63625 | 63664 | #endif /* local variables moved into u.ab */ |
| 63626 | 63665 | |
| 63627 | 63666 | assert( pOp->p1>0 && pOp->p1<=p->nVar ); |
| 63667 | + assert( pOp->p4.z==0 || pOp->p4.z==p->azVar[pOp->p1-1] ); |
| 63628 | 63668 | u.ab.pVar = &p->aVar[pOp->p1 - 1]; |
| 63629 | 63669 | if( sqlite3VdbeMemTooBig(u.ab.pVar) ){ |
| 63630 | 63670 | goto too_big; |
| 63631 | 63671 | } |
| 63632 | 63672 | sqlite3VdbeMemShallowCopy(pOut, u.ab.pVar, MEM_Static); |
| | @@ -64415,19 +64455,19 @@ |
| 64415 | 64455 | |
| 64416 | 64456 | pIn1 = &aMem[pOp->p1]; |
| 64417 | 64457 | pIn3 = &aMem[pOp->p3]; |
| 64418 | 64458 | u.ai.flags1 = pIn1->flags; |
| 64419 | 64459 | u.ai.flags3 = pIn3->flags; |
| 64420 | | - if( (pIn1->flags | pIn3->flags)&MEM_Null ){ |
| 64460 | + if( (u.ai.flags1 | u.ai.flags3)&MEM_Null ){ |
| 64421 | 64461 | /* One or both operands are NULL */ |
| 64422 | 64462 | if( pOp->p5 & SQLITE_NULLEQ ){ |
| 64423 | 64463 | /* If SQLITE_NULLEQ is set (which will only happen if the operator is |
| 64424 | 64464 | ** OP_Eq or OP_Ne) then take the jump or not depending on whether |
| 64425 | 64465 | ** or not both operands are null. |
| 64426 | 64466 | */ |
| 64427 | 64467 | assert( pOp->opcode==OP_Eq || pOp->opcode==OP_Ne ); |
| 64428 | | - u.ai.res = (pIn1->flags & pIn3->flags & MEM_Null)==0; |
| 64468 | + u.ai.res = (u.ai.flags1 & u.ai.flags3 & MEM_Null)==0; |
| 64429 | 64469 | }else{ |
| 64430 | 64470 | /* SQLITE_NULLEQ is clear and at least one operand is NULL, |
| 64431 | 64471 | ** then the result is always NULL. |
| 64432 | 64472 | ** The jump is taken if the SQLITE_JUMPIFNULL bit is set. |
| 64433 | 64473 | */ |
| | @@ -65249,17 +65289,20 @@ |
| 65249 | 65289 | "SQL statements in progress"); |
| 65250 | 65290 | rc = SQLITE_BUSY; |
| 65251 | 65291 | }else{ |
| 65252 | 65292 | u.aq.nName = sqlite3Strlen30(u.aq.zName); |
| 65253 | 65293 | |
| 65294 | +#ifndef SQLITE_OMIT_VIRTUALTABLE |
| 65254 | 65295 | /* This call is Ok even if this savepoint is actually a transaction |
| 65255 | 65296 | ** savepoint (and therefore should not prompt xSavepoint()) callbacks. |
| 65256 | 65297 | ** If this is a transaction savepoint being opened, it is guaranteed |
| 65257 | 65298 | ** that the db->aVTrans[] array is empty. */ |
| 65258 | 65299 | assert( db->autoCommit==0 || db->nVTrans==0 ); |
| 65259 | | - rc = sqlite3VtabSavepoint(db, SAVEPOINT_BEGIN, p->iStatement); |
| 65300 | + rc = sqlite3VtabSavepoint(db, SAVEPOINT_BEGIN, |
| 65301 | + db->nStatement+db->nSavepoint); |
| 65260 | 65302 | if( rc!=SQLITE_OK ) goto abort_due_to_error; |
| 65303 | +#endif |
| 65261 | 65304 | |
| 65262 | 65305 | /* Create a new savepoint structure. */ |
| 65263 | 65306 | u.aq.pNew = sqlite3DbMallocRaw(db, sizeof(Savepoint)+u.aq.nName+1); |
| 65264 | 65307 | if( u.aq.pNew ){ |
| 65265 | 65308 | u.aq.pNew->zName = (char *)&u.aq.pNew[1]; |
| | @@ -65508,11 +65551,11 @@ |
| 65508 | 65551 | assert( db->nStatement>=0 && db->nSavepoint>=0 ); |
| 65509 | 65552 | db->nStatement++; |
| 65510 | 65553 | p->iStatement = db->nSavepoint + db->nStatement; |
| 65511 | 65554 | } |
| 65512 | 65555 | |
| 65513 | | - rc = sqlite3VtabSavepoint(db, SAVEPOINT_BEGIN, p->iStatement); |
| 65556 | + rc = sqlite3VtabSavepoint(db, SAVEPOINT_BEGIN, p->iStatement-1); |
| 65514 | 65557 | if( rc==SQLITE_OK ){ |
| 65515 | 65558 | rc = sqlite3BtreeBeginStmt(u.as.pBt, p->iStatement); |
| 65516 | 65559 | } |
| 65517 | 65560 | |
| 65518 | 65561 | /* Store the current value of the database handles deferred constraint |
| | @@ -68641,25 +68684,25 @@ |
| 68641 | 68684 | ** the UTF-8 string contained in P4 is emitted on the trace callback. |
| 68642 | 68685 | */ |
| 68643 | 68686 | case OP_Trace: { |
| 68644 | 68687 | #if 0 /* local variables moved into u.cn */ |
| 68645 | 68688 | char *zTrace; |
| 68689 | + char *z; |
| 68646 | 68690 | #endif /* local variables moved into u.cn */ |
| 68647 | 68691 | |
| 68648 | | - u.cn.zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql); |
| 68649 | | - if( u.cn.zTrace ){ |
| 68650 | | - if( db->xTrace ){ |
| 68651 | | - char *z = sqlite3VdbeExpandSql(p, u.cn.zTrace); |
| 68652 | | - db->xTrace(db->pTraceArg, z); |
| 68653 | | - sqlite3DbFree(db, z); |
| 68654 | | - } |
| 68692 | + if( db->xTrace && (u.cn.zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0 ){ |
| 68693 | + u.cn.z = sqlite3VdbeExpandSql(p, u.cn.zTrace); |
| 68694 | + db->xTrace(db->pTraceArg, u.cn.z); |
| 68695 | + sqlite3DbFree(db, u.cn.z); |
| 68696 | + } |
| 68655 | 68697 | #ifdef SQLITE_DEBUG |
| 68656 | | - if( (db->flags & SQLITE_SqlTrace)!=0 ){ |
| 68657 | | - sqlite3DebugPrintf("SQL-trace: %s\n", u.cn.zTrace); |
| 68658 | | - } |
| 68698 | + if( (db->flags & SQLITE_SqlTrace)!=0 |
| 68699 | + && (u.cn.zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql))!=0 |
| 68700 | + ){ |
| 68701 | + sqlite3DebugPrintf("SQL-trace: %s\n", u.cn.zTrace); |
| 68702 | + } |
| 68659 | 68703 | #endif /* SQLITE_DEBUG */ |
| 68660 | | - } |
| 68661 | 68704 | break; |
| 68662 | 68705 | } |
| 68663 | 68706 | #endif |
| 68664 | 68707 | |
| 68665 | 68708 | |
| | @@ -69080,11 +69123,14 @@ |
| 69080 | 69123 | ** and offset cache without causing any IO. |
| 69081 | 69124 | */ |
| 69082 | 69125 | sqlite3VdbeChangeP4(v, 3+flags, SQLITE_INT_TO_PTR(pTab->nCol+1),P4_INT32); |
| 69083 | 69126 | sqlite3VdbeChangeP2(v, 7, pTab->nCol); |
| 69084 | 69127 | if( !db->mallocFailed ){ |
| 69085 | | - sqlite3VdbeMakeReady(v, 1, 1, 1, 0, 0, 0); |
| 69128 | + pParse->nVar = 1; |
| 69129 | + pParse->nMem = 1; |
| 69130 | + pParse->nTab = 1; |
| 69131 | + sqlite3VdbeMakeReady(v, pParse); |
| 69086 | 69132 | } |
| 69087 | 69133 | } |
| 69088 | 69134 | |
| 69089 | 69135 | pBlob->flags = flags; |
| 69090 | 69136 | pBlob->iCol = iCol; |
| | @@ -71647,57 +71693,57 @@ |
| 71647 | 71693 | assert( z[0]!=0 ); |
| 71648 | 71694 | if( z[1]==0 ){ |
| 71649 | 71695 | /* Wildcard of the form "?". Assign the next variable number */ |
| 71650 | 71696 | assert( z[0]=='?' ); |
| 71651 | 71697 | pExpr->iColumn = (ynVar)(++pParse->nVar); |
| 71652 | | - }else if( z[0]=='?' ){ |
| 71653 | | - /* Wildcard of the form "?nnn". Convert "nnn" to an integer and |
| 71654 | | - ** use it as the variable number */ |
| 71655 | | - i64 i; |
| 71656 | | - int bOk = 0==sqlite3Atoi64(&z[1], &i, sqlite3Strlen30(&z[1]), SQLITE_UTF8); |
| 71657 | | - pExpr->iColumn = (ynVar)i; |
| 71658 | | - testcase( i==0 ); |
| 71659 | | - testcase( i==1 ); |
| 71660 | | - testcase( i==db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]-1 ); |
| 71661 | | - testcase( i==db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ); |
| 71662 | | - if( bOk==0 || i<1 || i>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){ |
| 71663 | | - sqlite3ErrorMsg(pParse, "variable number must be between ?1 and ?%d", |
| 71664 | | - db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]); |
| 71665 | | - } |
| 71666 | | - if( i>pParse->nVar ){ |
| 71667 | | - pParse->nVar = (int)i; |
| 71668 | | - } |
| 71669 | | - }else{ |
| 71670 | | - /* Wildcards like ":aaa", "$aaa" or "@aaa". Reuse the same variable |
| 71671 | | - ** number as the prior appearance of the same name, or if the name |
| 71672 | | - ** has never appeared before, reuse the same variable number |
| 71673 | | - */ |
| 71674 | | - int i; |
| 71675 | | - u32 n; |
| 71676 | | - n = sqlite3Strlen30(z); |
| 71677 | | - for(i=0; i<pParse->nVarExpr; i++){ |
| 71678 | | - Expr *pE = pParse->apVarExpr[i]; |
| 71679 | | - assert( pE!=0 ); |
| 71680 | | - if( memcmp(pE->u.zToken, z, n)==0 && pE->u.zToken[n]==0 ){ |
| 71681 | | - pExpr->iColumn = pE->iColumn; |
| 71682 | | - break; |
| 71683 | | - } |
| 71684 | | - } |
| 71685 | | - if( i>=pParse->nVarExpr ){ |
| 71686 | | - pExpr->iColumn = (ynVar)(++pParse->nVar); |
| 71687 | | - if( pParse->nVarExpr>=pParse->nVarExprAlloc-1 ){ |
| 71688 | | - pParse->nVarExprAlloc += pParse->nVarExprAlloc + 10; |
| 71689 | | - pParse->apVarExpr = |
| 71690 | | - sqlite3DbReallocOrFree( |
| 71691 | | - db, |
| 71692 | | - pParse->apVarExpr, |
| 71693 | | - pParse->nVarExprAlloc*sizeof(pParse->apVarExpr[0]) |
| 71694 | | - ); |
| 71695 | | - } |
| 71696 | | - if( !db->mallocFailed ){ |
| 71697 | | - assert( pParse->apVarExpr!=0 ); |
| 71698 | | - pParse->apVarExpr[pParse->nVarExpr++] = pExpr; |
| 71698 | + }else{ |
| 71699 | + ynVar x = 0; |
| 71700 | + u32 n = sqlite3Strlen30(z); |
| 71701 | + if( z[0]=='?' ){ |
| 71702 | + /* Wildcard of the form "?nnn". Convert "nnn" to an integer and |
| 71703 | + ** use it as the variable number */ |
| 71704 | + i64 i; |
| 71705 | + int bOk = 0==sqlite3Atoi64(&z[1], &i, n-1, SQLITE_UTF8); |
| 71706 | + pExpr->iColumn = x = (ynVar)i; |
| 71707 | + testcase( i==0 ); |
| 71708 | + testcase( i==1 ); |
| 71709 | + testcase( i==db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]-1 ); |
| 71710 | + testcase( i==db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ); |
| 71711 | + if( bOk==0 || i<1 || i>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){ |
| 71712 | + sqlite3ErrorMsg(pParse, "variable number must be between ?1 and ?%d", |
| 71713 | + db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER]); |
| 71714 | + x = 0; |
| 71715 | + } |
| 71716 | + if( i>pParse->nVar ){ |
| 71717 | + pParse->nVar = (int)i; |
| 71718 | + } |
| 71719 | + }else{ |
| 71720 | + /* Wildcards like ":aaa", "$aaa" or "@aaa". Reuse the same variable |
| 71721 | + ** number as the prior appearance of the same name, or if the name |
| 71722 | + ** has never appeared before, reuse the same variable number |
| 71723 | + */ |
| 71724 | + ynVar i; |
| 71725 | + for(i=0; i<pParse->nzVar; i++){ |
| 71726 | + if( pParse->azVar[i] && memcmp(pParse->azVar[i],z,n+1)==0 ){ |
| 71727 | + pExpr->iColumn = x = (ynVar)i+1; |
| 71728 | + break; |
| 71729 | + } |
| 71730 | + } |
| 71731 | + if( x==0 ) x = pExpr->iColumn = (ynVar)(++pParse->nVar); |
| 71732 | + } |
| 71733 | + if( x>0 ){ |
| 71734 | + if( x>pParse->nzVar ){ |
| 71735 | + char **a; |
| 71736 | + a = sqlite3DbRealloc(db, pParse->azVar, x*sizeof(a[0])); |
| 71737 | + if( a==0 ) return; /* Error reported through db->mallocFailed */ |
| 71738 | + pParse->azVar = a; |
| 71739 | + memset(&a[pParse->nzVar], 0, (x-pParse->nzVar)*sizeof(a[0])); |
| 71740 | + pParse->nzVar = x; |
| 71741 | + } |
| 71742 | + if( z[0]!='?' || pParse->azVar[x-1]==0 ){ |
| 71743 | + sqlite3DbFree(db, pParse->azVar[x-1]); |
| 71744 | + pParse->azVar[x-1] = sqlite3DbStrNDup(db, z, n); |
| 71699 | 71745 | } |
| 71700 | 71746 | } |
| 71701 | 71747 | } |
| 71702 | 71748 | if( !pParse->nErr && pParse->nVar>db->aLimit[SQLITE_LIMIT_VARIABLE_NUMBER] ){ |
| 71703 | 71749 | sqlite3ErrorMsg(pParse, "too many SQL variables"); |
| | @@ -73437,11 +73483,13 @@ |
| 73437 | 73483 | assert( !ExprHasProperty(pExpr, EP_IntValue) ); |
| 73438 | 73484 | assert( pExpr->u.zToken!=0 ); |
| 73439 | 73485 | assert( pExpr->u.zToken[0]!=0 ); |
| 73440 | 73486 | sqlite3VdbeAddOp2(v, OP_Variable, pExpr->iColumn, target); |
| 73441 | 73487 | if( pExpr->u.zToken[1]!=0 ){ |
| 73442 | | - sqlite3VdbeChangeP4(v, -1, pExpr->u.zToken, P4_TRANSIENT); |
| 73488 | + assert( pExpr->u.zToken[0]=='?' |
| 73489 | + || strcmp(pExpr->u.zToken, pParse->azVar[pExpr->iColumn-1])==0 ); |
| 73490 | + sqlite3VdbeChangeP4(v, -1, pParse->azVar[pExpr->iColumn-1], P4_STATIC); |
| 73443 | 73491 | } |
| 73444 | 73492 | break; |
| 73445 | 73493 | } |
| 73446 | 73494 | case TK_REGISTER: { |
| 73447 | 73495 | inReg = pExpr->iTable; |
| | @@ -77408,13 +77456,11 @@ |
| 77408 | 77456 | #endif |
| 77409 | 77457 | assert( pParse->iCacheLevel==0 ); /* Disables and re-enables match */ |
| 77410 | 77458 | /* A minimum of one cursor is required if autoincrement is used |
| 77411 | 77459 | * See ticket [a696379c1f08866] */ |
| 77412 | 77460 | if( pParse->pAinc!=0 && pParse->nTab==0 ) pParse->nTab = 1; |
| 77413 | | - sqlite3VdbeMakeReady(v, pParse->nVar, pParse->nMem, |
| 77414 | | - pParse->nTab, pParse->nMaxArg, pParse->explain, |
| 77415 | | - pParse->isMultiWrite && pParse->mayAbort); |
| 77461 | + sqlite3VdbeMakeReady(v, pParse); |
| 77416 | 77462 | pParse->rc = SQLITE_DONE; |
| 77417 | 77463 | pParse->colNamesSet = 0; |
| 77418 | 77464 | }else{ |
| 77419 | 77465 | pParse->rc = SQLITE_ERROR; |
| 77420 | 77466 | } |
| | @@ -81827,10 +81873,11 @@ |
| 81827 | 81873 | #ifndef SQLITE_OMIT_VIRTUALTABLE |
| 81828 | 81874 | if( IsVirtual(pTab) ){ |
| 81829 | 81875 | const char *pVTab = (const char *)sqlite3GetVTable(db, pTab); |
| 81830 | 81876 | sqlite3VtabMakeWritable(pParse, pTab); |
| 81831 | 81877 | sqlite3VdbeAddOp4(v, OP_VUpdate, 0, 1, iRowid, pVTab, P4_VTAB); |
| 81878 | + sqlite3VdbeChangeP5(v, OE_Abort); |
| 81832 | 81879 | sqlite3MayAbort(pParse); |
| 81833 | 81880 | }else |
| 81834 | 81881 | #endif |
| 81835 | 81882 | { |
| 81836 | 81883 | int count = (pParse->nested==0); /* True to count changes */ |
| | @@ -87947,14 +87994,10 @@ |
| 87947 | 87994 | ** |
| 87948 | 87995 | ************************************************************************* |
| 87949 | 87996 | ** This file contains code used to implement the PRAGMA command. |
| 87950 | 87997 | */ |
| 87951 | 87998 | |
| 87952 | | -/* Ignore this whole file if pragmas are disabled |
| 87953 | | -*/ |
| 87954 | | -#if !defined(SQLITE_OMIT_PRAGMA) |
| 87955 | | - |
| 87956 | 87999 | /* |
| 87957 | 88000 | ** Interpret the given string as a safety level. Return 0 for OFF, |
| 87958 | 88001 | ** 1 for ON or NORMAL and 2 for FULL. Return 1 for an empty or |
| 87959 | 88002 | ** unrecognized string argument. |
| 87960 | 88003 | ** |
| | @@ -87986,10 +88029,16 @@ |
| 87986 | 88029 | ** Interpret the given string as a boolean value. |
| 87987 | 88030 | */ |
| 87988 | 88031 | SQLITE_PRIVATE u8 sqlite3GetBoolean(const char *z){ |
| 87989 | 88032 | return getSafetyLevel(z)&1; |
| 87990 | 88033 | } |
| 88034 | + |
| 88035 | +/* The sqlite3GetBoolean() function is used by other modules but the |
| 88036 | +** remainder of this file is specific to PRAGMA processing. So omit |
| 88037 | +** the rest of the file if PRAGMAs are omitted from the build. |
| 88038 | +*/ |
| 88039 | +#if !defined(SQLITE_OMIT_PRAGMA) |
| 87991 | 88040 | |
| 87992 | 88041 | /* |
| 87993 | 88042 | ** Interpret the given string as a locking mode value. |
| 87994 | 88043 | */ |
| 87995 | 88044 | static int getLockingMode(const char *z){ |
| | @@ -97692,15 +97741,15 @@ |
| 97692 | 97741 | sqlite3DbFree(db, zErr); |
| 97693 | 97742 | } |
| 97694 | 97743 | |
| 97695 | 97744 | return rc; |
| 97696 | 97745 | } |
| 97697 | | - |
| 97698 | 97746 | /* |
| 97699 | | -** Add the virtual table pVTab to the array sqlite3.aVTrans[]. |
| 97747 | +** Grow the db->aVTrans[] array so that there is room for at least one |
| 97748 | +** more v-table. Return SQLITE_NOMEM if a malloc fails, or SQLITE_OK otherwise. |
| 97700 | 97749 | */ |
| 97701 | | -static int addToVTrans(sqlite3 *db, VTable *pVTab){ |
| 97750 | +static int growVTrans(sqlite3 *db){ |
| 97702 | 97751 | const int ARRAY_INCR = 5; |
| 97703 | 97752 | |
| 97704 | 97753 | /* Grow the sqlite3.aVTrans array if required */ |
| 97705 | 97754 | if( (db->nVTrans%ARRAY_INCR)==0 ){ |
| 97706 | 97755 | VTable **aVTrans; |
| | @@ -97711,14 +97760,21 @@ |
| 97711 | 97760 | } |
| 97712 | 97761 | memset(&aVTrans[db->nVTrans], 0, sizeof(sqlite3_vtab *)*ARRAY_INCR); |
| 97713 | 97762 | db->aVTrans = aVTrans; |
| 97714 | 97763 | } |
| 97715 | 97764 | |
| 97765 | + return SQLITE_OK; |
| 97766 | +} |
| 97767 | + |
| 97768 | +/* |
| 97769 | +** Add the virtual table pVTab to the array sqlite3.aVTrans[]. Space should |
| 97770 | +** have already been reserved using growVTrans(). |
| 97771 | +*/ |
| 97772 | +static void addToVTrans(sqlite3 *db, VTable *pVTab){ |
| 97716 | 97773 | /* Add pVtab to the end of sqlite3.aVTrans */ |
| 97717 | 97774 | db->aVTrans[db->nVTrans++] = pVTab; |
| 97718 | 97775 | sqlite3VtabLock(pVTab); |
| 97719 | | - return SQLITE_OK; |
| 97720 | 97776 | } |
| 97721 | 97777 | |
| 97722 | 97778 | /* |
| 97723 | 97779 | ** This function is invoked by the vdbe to call the xCreate method |
| 97724 | 97780 | ** of the virtual table named zTab in database iDb. |
| | @@ -97752,11 +97808,14 @@ |
| 97752 | 97808 | } |
| 97753 | 97809 | |
| 97754 | 97810 | /* Justification of ALWAYS(): The xConstructor method is required to |
| 97755 | 97811 | ** create a valid sqlite3_vtab if it returns SQLITE_OK. */ |
| 97756 | 97812 | if( rc==SQLITE_OK && ALWAYS(sqlite3GetVTable(db, pTab)) ){ |
| 97757 | | - rc = addToVTrans(db, sqlite3GetVTable(db, pTab)); |
| 97813 | + rc = growVTrans(db); |
| 97814 | + if( rc==SQLITE_OK ){ |
| 97815 | + addToVTrans(db, sqlite3GetVTable(db, pTab)); |
| 97816 | + } |
| 97758 | 97817 | } |
| 97759 | 97818 | |
| 97760 | 97819 | return rc; |
| 97761 | 97820 | } |
| 97762 | 97821 | |
| | @@ -97868,10 +97927,11 @@ |
| 97868 | 97927 | if( p ){ |
| 97869 | 97928 | int (*x)(sqlite3_vtab *); |
| 97870 | 97929 | x = *(int (**)(sqlite3_vtab *))((char *)p->pModule + offset); |
| 97871 | 97930 | if( x ) x(p); |
| 97872 | 97931 | } |
| 97932 | + pVTab->iSavepoint = 0; |
| 97873 | 97933 | sqlite3VtabUnlock(pVTab); |
| 97874 | 97934 | } |
| 97875 | 97935 | sqlite3DbFree(db, db->aVTrans); |
| 97876 | 97936 | db->nVTrans = 0; |
| 97877 | 97937 | db->aVTrans = 0; |
| | @@ -97957,14 +98017,18 @@ |
| 97957 | 98017 | if( db->aVTrans[i]==pVTab ){ |
| 97958 | 98018 | return SQLITE_OK; |
| 97959 | 98019 | } |
| 97960 | 98020 | } |
| 97961 | 98021 | |
| 97962 | | - /* Invoke the xBegin method */ |
| 97963 | | - rc = pModule->xBegin(pVTab->pVtab); |
| 98022 | + /* Invoke the xBegin method. If successful, add the vtab to the |
| 98023 | + ** sqlite3.aVTrans[] array. */ |
| 98024 | + rc = growVTrans(db); |
| 97964 | 98025 | if( rc==SQLITE_OK ){ |
| 97965 | | - rc = addToVTrans(db, pVTab); |
| 98026 | + rc = pModule->xBegin(pVTab->pVtab); |
| 98027 | + if( rc==SQLITE_OK ){ |
| 98028 | + addToVTrans(db, pVTab); |
| 98029 | + } |
| 97966 | 98030 | } |
| 97967 | 98031 | } |
| 97968 | 98032 | return rc; |
| 97969 | 98033 | } |
| 97970 | 98034 | |
| | @@ -97985,28 +98049,33 @@ |
| 97985 | 98049 | */ |
| 97986 | 98050 | SQLITE_PRIVATE int sqlite3VtabSavepoint(sqlite3 *db, int op, int iSavepoint){ |
| 97987 | 98051 | int rc = SQLITE_OK; |
| 97988 | 98052 | |
| 97989 | 98053 | assert( op==SAVEPOINT_RELEASE||op==SAVEPOINT_ROLLBACK||op==SAVEPOINT_BEGIN ); |
| 98054 | + assert( iSavepoint>=0 ); |
| 97990 | 98055 | if( db->aVTrans ){ |
| 97991 | 98056 | int i; |
| 97992 | 98057 | for(i=0; rc==SQLITE_OK && i<db->nVTrans; i++){ |
| 97993 | | - const sqlite3_module *pMod = db->aVTrans[i]->pMod->pModule; |
| 98058 | + VTable *pVTab = db->aVTrans[i]; |
| 98059 | + const sqlite3_module *pMod = pVTab->pMod->pModule; |
| 97994 | 98060 | if( pMod->iVersion>=2 ){ |
| 97995 | 98061 | int (*xMethod)(sqlite3_vtab *, int); |
| 97996 | 98062 | switch( op ){ |
| 97997 | 98063 | case SAVEPOINT_BEGIN: |
| 97998 | 98064 | xMethod = pMod->xSavepoint; |
| 98065 | + pVTab->iSavepoint = iSavepoint+1; |
| 97999 | 98066 | break; |
| 98000 | 98067 | case SAVEPOINT_ROLLBACK: |
| 98001 | 98068 | xMethod = pMod->xRollbackTo; |
| 98002 | 98069 | break; |
| 98003 | 98070 | default: |
| 98004 | 98071 | xMethod = pMod->xRelease; |
| 98005 | 98072 | break; |
| 98006 | 98073 | } |
| 98007 | | - if( xMethod ) rc = xMethod(db->aVTrans[i]->pVtab, iSavepoint); |
| 98074 | + if( xMethod && pVTab->iSavepoint>iSavepoint ){ |
| 98075 | + rc = xMethod(db->aVTrans[i]->pVtab, iSavepoint); |
| 98076 | + } |
| 98008 | 98077 | } |
| 98009 | 98078 | } |
| 98010 | 98079 | } |
| 98011 | 98080 | return rc; |
| 98012 | 98081 | } |
| | @@ -107264,13 +107333,12 @@ |
| 107264 | 107333 | return SQLITE_NOMEM; |
| 107265 | 107334 | } |
| 107266 | 107335 | assert( pParse->pNewTable==0 ); |
| 107267 | 107336 | assert( pParse->pNewTrigger==0 ); |
| 107268 | 107337 | assert( pParse->nVar==0 ); |
| 107269 | | - assert( pParse->nVarExpr==0 ); |
| 107270 | | - assert( pParse->nVarExprAlloc==0 ); |
| 107271 | | - assert( pParse->apVarExpr==0 ); |
| 107338 | + assert( pParse->nzVar==0 ); |
| 107339 | + assert( pParse->azVar==0 ); |
| 107272 | 107340 | enableLookaside = db->lookaside.bEnabled; |
| 107273 | 107341 | if( db->lookaside.pStart ) db->lookaside.bEnabled = 1; |
| 107274 | 107342 | while( !db->mallocFailed && zSql[i]!=0 ){ |
| 107275 | 107343 | assert( i>=0 ); |
| 107276 | 107344 | pParse->sLastToken.z = &zSql[i]; |
| | @@ -107360,11 +107428,12 @@ |
| 107360 | 107428 | */ |
| 107361 | 107429 | sqlite3DeleteTable(db, pParse->pNewTable); |
| 107362 | 107430 | } |
| 107363 | 107431 | |
| 107364 | 107432 | sqlite3DeleteTrigger(db, pParse->pNewTrigger); |
| 107365 | | - sqlite3DbFree(db, pParse->apVarExpr); |
| 107433 | + for(i=pParse->nzVar-1; i>=0; i--) sqlite3DbFree(db, pParse->azVar[i]); |
| 107434 | + sqlite3DbFree(db, pParse->azVar); |
| 107366 | 107435 | sqlite3DbFree(db, pParse->aAlias); |
| 107367 | 107436 | while( pParse->pAinc ){ |
| 107368 | 107437 | AutoincInfo *p = pParse->pAinc; |
| 107369 | 107438 | pParse->pAinc = p->pNext; |
| 107370 | 107439 | sqlite3DbFree(db, p); |
| | @@ -109692,13 +109761,13 @@ |
| 109692 | 109761 | }else{ |
| 109693 | 109762 | struct OpenMode { |
| 109694 | 109763 | const char *z; |
| 109695 | 109764 | int mode; |
| 109696 | 109765 | } *aMode = 0; |
| 109697 | | - char *zModeType; |
| 109698 | | - int mask; |
| 109699 | | - int limit; |
| 109766 | + char *zModeType = 0; |
| 109767 | + int mask = 0; |
| 109768 | + int limit = 0; |
| 109700 | 109769 | |
| 109701 | 109770 | if( nOpt==5 && memcmp("cache", zOpt, 5)==0 ){ |
| 109702 | 109771 | static struct OpenMode aCacheMode[] = { |
| 109703 | 109772 | { "shared", SQLITE_OPEN_SHAREDCACHE }, |
| 109704 | 109773 | { "private", SQLITE_OPEN_PRIVATECACHE }, |
| | @@ -111686,15 +111755,35 @@ |
| 111686 | 111755 | */ |
| 111687 | 111756 | typedef unsigned char u8; /* 1-byte (or larger) unsigned integer */ |
| 111688 | 111757 | typedef short int i16; /* 2-byte (or larger) signed integer */ |
| 111689 | 111758 | typedef unsigned int u32; /* 4-byte unsigned integer */ |
| 111690 | 111759 | typedef sqlite3_uint64 u64; /* 8-byte unsigned integer */ |
| 111760 | + |
| 111691 | 111761 | /* |
| 111692 | 111762 | ** Macro used to suppress compiler warnings for unused parameters. |
| 111693 | 111763 | */ |
| 111694 | 111764 | #define UNUSED_PARAMETER(x) (void)(x) |
| 111765 | + |
| 111766 | +/* |
| 111767 | +** Activate assert() only if SQLITE_TEST is enabled. |
| 111768 | +*/ |
| 111769 | +#if !defined(NDEBUG) && !defined(SQLITE_DEBUG) |
| 111770 | +# define NDEBUG 1 |
| 111771 | +#endif |
| 111772 | + |
| 111773 | +/* |
| 111774 | +** The TESTONLY macro is used to enclose variable declarations or |
| 111775 | +** other bits of code that are needed to support the arguments |
| 111776 | +** within testcase() and assert() macros. |
| 111777 | +*/ |
| 111778 | +#if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST) |
| 111779 | +# define TESTONLY(X) X |
| 111780 | +#else |
| 111781 | +# define TESTONLY(X) |
| 111695 | 111782 | #endif |
| 111783 | + |
| 111784 | +#endif /* SQLITE_AMALGAMATION */ |
| 111696 | 111785 | |
| 111697 | 111786 | typedef struct Fts3Table Fts3Table; |
| 111698 | 111787 | typedef struct Fts3Cursor Fts3Cursor; |
| 111699 | 111788 | typedef struct Fts3Expr Fts3Expr; |
| 111700 | 111789 | typedef struct Fts3Phrase Fts3Phrase; |
| | @@ -111745,10 +111834,20 @@ |
| 111745 | 111834 | */ |
| 111746 | 111835 | int nMaxPendingData; |
| 111747 | 111836 | int nPendingData; |
| 111748 | 111837 | sqlite_int64 iPrevDocid; |
| 111749 | 111838 | Fts3Hash pendingTerms; |
| 111839 | + |
| 111840 | +#if defined(SQLITE_DEBUG) |
| 111841 | + /* State variables used for validating that the transaction control |
| 111842 | + ** methods of the virtual table are called at appropriate times. These |
| 111843 | + ** values do not contribution to the FTS computation; they are used for |
| 111844 | + ** verifying the SQLite core. |
| 111845 | + */ |
| 111846 | + int inTransaction; /* True after xBegin but before xCommit/xRollback */ |
| 111847 | + int mxSavepoint; /* Largest valid xSavepoint integer */ |
| 111848 | +#endif |
| 111750 | 111849 | }; |
| 111751 | 111850 | |
| 111752 | 111851 | /* |
| 111753 | 111852 | ** When the core wants to read from the virtual table, it creates a |
| 111754 | 111853 | ** virtual table cursor (an instance of the following structure) using |
| | @@ -112655,10 +112754,12 @@ |
| 112655 | 112754 | p->pTokenizer = pTokenizer; |
| 112656 | 112755 | p->nNodeSize = 1000; |
| 112657 | 112756 | p->nMaxPendingData = FTS3_MAX_PENDING_DATA; |
| 112658 | 112757 | p->bHasDocsize = (isFts4 && bNoDocsize==0); |
| 112659 | 112758 | p->bHasStat = isFts4; |
| 112759 | + TESTONLY( p->inTransaction = -1 ); |
| 112760 | + TESTONLY( p->mxSavepoint = -1 ); |
| 112660 | 112761 | fts3HashInit(&p->pendingTerms, FTS3_HASH_STRING, 1); |
| 112661 | 112762 | |
| 112662 | 112763 | /* Fill in the zName and zDb fields of the vtab structure. */ |
| 112663 | 112764 | zCsr = (char *)&p->azColumn[nCol]; |
| 112664 | 112765 | p->zName = zCsr; |
| | @@ -114952,11 +115053,15 @@ |
| 114952 | 115053 | /* |
| 114953 | 115054 | ** Implementation of xBegin() method. This is a no-op. |
| 114954 | 115055 | */ |
| 114955 | 115056 | static int fts3BeginMethod(sqlite3_vtab *pVtab){ |
| 114956 | 115057 | UNUSED_PARAMETER(pVtab); |
| 114957 | | - assert( ((Fts3Table *)pVtab)->nPendingData==0 ); |
| 115058 | + TESTONLY( Fts3Table *p = (Fts3Table*)pVtab ); |
| 115059 | + assert( p->nPendingData==0 ); |
| 115060 | + assert( p->inTransaction!=1 ); |
| 115061 | + TESTONLY( p->inTransaction = 1 ); |
| 115062 | + TESTONLY( p->mxSavepoint = -1; ); |
| 114958 | 115063 | return SQLITE_OK; |
| 114959 | 115064 | } |
| 114960 | 115065 | |
| 114961 | 115066 | /* |
| 114962 | 115067 | ** Implementation of xCommit() method. This is a no-op. The contents of |
| | @@ -114963,20 +115068,28 @@ |
| 114963 | 115068 | ** the pending-terms hash-table have already been flushed into the database |
| 114964 | 115069 | ** by fts3SyncMethod(). |
| 114965 | 115070 | */ |
| 114966 | 115071 | static int fts3CommitMethod(sqlite3_vtab *pVtab){ |
| 114967 | 115072 | UNUSED_PARAMETER(pVtab); |
| 114968 | | - assert( ((Fts3Table *)pVtab)->nPendingData==0 ); |
| 115073 | + TESTONLY( Fts3Table *p = (Fts3Table*)pVtab ); |
| 115074 | + assert( p->nPendingData==0 ); |
| 115075 | + assert( p->inTransaction!=0 ); |
| 115076 | + TESTONLY( p->inTransaction = 0 ); |
| 115077 | + TESTONLY( p->mxSavepoint = -1; ); |
| 114969 | 115078 | return SQLITE_OK; |
| 114970 | 115079 | } |
| 114971 | 115080 | |
| 114972 | 115081 | /* |
| 114973 | 115082 | ** Implementation of xRollback(). Discard the contents of the pending-terms |
| 114974 | 115083 | ** hash-table. Any changes made to the database are reverted by SQLite. |
| 114975 | 115084 | */ |
| 114976 | 115085 | static int fts3RollbackMethod(sqlite3_vtab *pVtab){ |
| 114977 | | - sqlite3Fts3PendingTermsClear((Fts3Table *)pVtab); |
| 115086 | + Fts3Table *p = (Fts3Table*)pVtab; |
| 115087 | + sqlite3Fts3PendingTermsClear(p); |
| 115088 | + assert( p->inTransaction!=0 ); |
| 115089 | + TESTONLY( p->inTransaction = 0 ); |
| 115090 | + TESTONLY( p->mxSavepoint = -1; ); |
| 114978 | 115091 | return SQLITE_OK; |
| 114979 | 115092 | } |
| 114980 | 115093 | |
| 114981 | 115094 | /* |
| 114982 | 115095 | ** Load the doclist associated with expression pExpr to pExpr->aDoclist. |
| | @@ -115328,17 +115441,33 @@ |
| 115328 | 115441 | ); |
| 115329 | 115442 | return rc; |
| 115330 | 115443 | } |
| 115331 | 115444 | |
| 115332 | 115445 | static int fts3SavepointMethod(sqlite3_vtab *pVtab, int iSavepoint){ |
| 115333 | | - return sqlite3Fts3PendingTermsFlush((Fts3Table *)pVtab); |
| 115446 | + Fts3Table *p = (Fts3Table*)pVtab; |
| 115447 | + UNUSED_PARAMETER(iSavepoint); |
| 115448 | + assert( p->inTransaction ); |
| 115449 | + assert( p->mxSavepoint < iSavepoint ); |
| 115450 | + TESTONLY( p->mxSavepoint = iSavepoint ); |
| 115451 | + return sqlite3Fts3PendingTermsFlush(p); |
| 115334 | 115452 | } |
| 115335 | 115453 | static int fts3ReleaseMethod(sqlite3_vtab *pVtab, int iSavepoint){ |
| 115454 | + TESTONLY( Fts3Table *p = (Fts3Table*)pVtab ); |
| 115455 | + UNUSED_PARAMETER(iSavepoint); |
| 115456 | + UNUSED_PARAMETER(pVtab); |
| 115457 | + assert( p->inTransaction ); |
| 115458 | + assert( p->mxSavepoint >= iSavepoint ); |
| 115459 | + TESTONLY( p->mxSavepoint = iSavepoint-1 ); |
| 115336 | 115460 | return SQLITE_OK; |
| 115337 | 115461 | } |
| 115338 | 115462 | static int fts3RollbackToMethod(sqlite3_vtab *pVtab, int iSavepoint){ |
| 115339 | | - sqlite3Fts3PendingTermsClear((Fts3Table *)pVtab); |
| 115463 | + Fts3Table *p = (Fts3Table*)pVtab; |
| 115464 | + UNUSED_PARAMETER(iSavepoint); |
| 115465 | + assert( p->inTransaction ); |
| 115466 | + assert( p->mxSavepoint >= iSavepoint ); |
| 115467 | + TESTONLY( p->mxSavepoint = iSavepoint ); |
| 115468 | + sqlite3Fts3PendingTermsClear(p); |
| 115340 | 115469 | return SQLITE_OK; |
| 115341 | 115470 | } |
| 115342 | 115471 | |
| 115343 | 115472 | static const sqlite3_module fts3Module = { |
| 115344 | 115473 | /* iVersion */ 2, |
| | @@ -115833,10 +115962,11 @@ |
| 115833 | 115962 | Fts3Table *pFts3 = ((Fts3auxTable *)pCursor->pVtab)->pFts3Tab; |
| 115834 | 115963 | int rc; |
| 115835 | 115964 | int isScan; |
| 115836 | 115965 | |
| 115837 | 115966 | UNUSED_PARAMETER(nVal); |
| 115967 | + UNUSED_PARAMETER(idxStr); |
| 115838 | 115968 | |
| 115839 | 115969 | assert( idxStr==0 ); |
| 115840 | 115970 | assert( idxNum==FTS4AUX_EQ_CONSTRAINT || idxNum==0 |
| 115841 | 115971 | || idxNum==FTS4AUX_LE_CONSTRAINT || idxNum==FTS4AUX_GE_CONSTRAINT |
| 115842 | 115972 | || idxNum==(FTS4AUX_LE_CONSTRAINT|FTS4AUX_GE_CONSTRAINT) |
| | @@ -115950,11 +116080,14 @@ |
| 115950 | 116080 | 0, /* xBegin */ |
| 115951 | 116081 | 0, /* xSync */ |
| 115952 | 116082 | 0, /* xCommit */ |
| 115953 | 116083 | 0, /* xRollback */ |
| 115954 | 116084 | 0, /* xFindFunction */ |
| 115955 | | - 0 /* xRename */ |
| 116085 | + 0, /* xRename */ |
| 116086 | + 0, /* xSavepoint */ |
| 116087 | + 0, /* xRelease */ |
| 116088 | + 0 /* xRollbackTo */ |
| 115956 | 116089 | }; |
| 115957 | 116090 | int rc; /* Return code */ |
| 115958 | 116091 | |
| 115959 | 116092 | rc = sqlite3_create_module(db, "fts4aux", &fts3aux_module, 0); |
| 115960 | 116093 | return rc; |
| | @@ -125929,11 +126062,11 @@ |
| 125929 | 126062 | } |
| 125930 | 126063 | return rc; |
| 125931 | 126064 | } |
| 125932 | 126065 | |
| 125933 | 126066 | static sqlite3_module rtreeModule = { |
| 125934 | | - 0, /* iVersion */ |
| 126067 | + 0, /* iVersion */ |
| 125935 | 126068 | rtreeCreate, /* xCreate - create a table */ |
| 125936 | 126069 | rtreeConnect, /* xConnect - connect to an existing table */ |
| 125937 | 126070 | rtreeBestIndex, /* xBestIndex - Determine search strategy */ |
| 125938 | 126071 | rtreeDisconnect, /* xDisconnect - Disconnect from a table */ |
| 125939 | 126072 | rtreeDestroy, /* xDestroy - Drop a table */ |
| | @@ -125948,11 +126081,14 @@ |
| 125948 | 126081 | 0, /* xBegin - begin transaction */ |
| 125949 | 126082 | 0, /* xSync - sync transaction */ |
| 125950 | 126083 | 0, /* xCommit - commit transaction */ |
| 125951 | 126084 | 0, /* xRollback - rollback transaction */ |
| 125952 | 126085 | 0, /* xFindFunction - function overloading */ |
| 125953 | | - rtreeRename /* xRename - rename the table */ |
| 126086 | + rtreeRename, /* xRename - rename the table */ |
| 126087 | + 0, /* xSavepoint */ |
| 126088 | + 0, /* xRelease */ |
| 126089 | + 0 /* xRollbackTo */ |
| 125954 | 126090 | }; |
| 125955 | 126091 | |
| 125956 | 126092 | static int rtreeSqlInit( |
| 125957 | 126093 | Rtree *pRtree, |
| 125958 | 126094 | sqlite3 *db, |
| 125959 | 126095 | |