| | @@ -452,11 +452,11 @@ |
| 452 | 452 | ** [sqlite3_libversion_number()], [sqlite3_sourceid()], |
| 453 | 453 | ** [sqlite_version()] and [sqlite_source_id()]. |
| 454 | 454 | */ |
| 455 | 455 | #define SQLITE_VERSION "3.38.0" |
| 456 | 456 | #define SQLITE_VERSION_NUMBER 3038000 |
| 457 | | -#define SQLITE_SOURCE_ID "2021-12-31 22:53:15 e654b57a9fc32021453eed48d1c1bba65c833fb1aac3946567968c877e4cbd10" |
| 457 | +#define SQLITE_SOURCE_ID "2022-01-06 17:13:56 2d6a16caa7d28ad5c766036b2eb6c2020683fcc9389b3c7df2013739929dd36f" |
| 458 | 458 | |
| 459 | 459 | /* |
| 460 | 460 | ** CAPI3REF: Run-Time Library Version Numbers |
| 461 | 461 | ** KEYWORDS: sqlite3_version sqlite3_sourceid |
| 462 | 462 | ** |
| | @@ -20137,17 +20137,19 @@ |
| 20137 | 20137 | SQLITE_PRIVATE void sqlite3FkDropTable(Parse*, SrcList *, Table*); |
| 20138 | 20138 | SQLITE_PRIVATE void sqlite3FkActions(Parse*, Table*, ExprList*, int, int*, int); |
| 20139 | 20139 | SQLITE_PRIVATE int sqlite3FkRequired(Parse*, Table*, int*, int); |
| 20140 | 20140 | SQLITE_PRIVATE u32 sqlite3FkOldmask(Parse*, Table*); |
| 20141 | 20141 | SQLITE_PRIVATE FKey *sqlite3FkReferences(Table *); |
| 20142 | +SQLITE_PRIVATE void sqlite3FkClearTriggerCache(sqlite3*,int); |
| 20142 | 20143 | #else |
| 20143 | 20144 | #define sqlite3FkActions(a,b,c,d,e,f) |
| 20144 | 20145 | #define sqlite3FkCheck(a,b,c,d,e,f) |
| 20145 | 20146 | #define sqlite3FkDropTable(a,b,c) |
| 20146 | 20147 | #define sqlite3FkOldmask(a,b) 0 |
| 20147 | 20148 | #define sqlite3FkRequired(a,b,c,d) 0 |
| 20148 | 20149 | #define sqlite3FkReferences(a) 0 |
| 20150 | + #define sqlite3FkClearTriggerCache(a,b) |
| 20149 | 20151 | #endif |
| 20150 | 20152 | #ifndef SQLITE_OMIT_FOREIGN_KEY |
| 20151 | 20153 | SQLITE_PRIVATE void sqlite3FkDelete(sqlite3 *, Table*); |
| 20152 | 20154 | SQLITE_PRIVATE int sqlite3FkLocateIndex(Parse*,Table*,FKey*,Index**,int**); |
| 20153 | 20155 | #else |
| | @@ -21797,11 +21799,11 @@ |
| 21797 | 21799 | ** * A one-row "pseudotable" stored in a single register |
| 21798 | 21800 | */ |
| 21799 | 21801 | typedef struct VdbeCursor VdbeCursor; |
| 21800 | 21802 | struct VdbeCursor { |
| 21801 | 21803 | u8 eCurType; /* One of the CURTYPE_* values above */ |
| 21802 | | - i8 iDb; /* Index of cursor database in db->aDb[] (or -1) */ |
| 21804 | + i8 iDb; /* Index of cursor database in db->aDb[] */ |
| 21803 | 21805 | u8 nullRow; /* True if pointing to a row with no data */ |
| 21804 | 21806 | u8 deferredMoveto; /* A call to sqlite3BtreeMoveto() is needed */ |
| 21805 | 21807 | u8 isTable; /* True for rowid tables. False for indexes */ |
| 21806 | 21808 | #ifdef SQLITE_DEBUG |
| 21807 | 21809 | u8 seekOp; /* Most recent seek operation on this cursor */ |
| | @@ -21810,13 +21812,15 @@ |
| 21810 | 21812 | Bool isEphemeral:1; /* True for an ephemeral table */ |
| 21811 | 21813 | Bool useRandomRowid:1; /* Generate new record numbers semi-randomly */ |
| 21812 | 21814 | Bool isOrdered:1; /* True if the table is not BTREE_UNORDERED */ |
| 21813 | 21815 | Bool hasBeenDuped:1; /* This cursor was source or target of OP_OpenDup */ |
| 21814 | 21816 | u16 seekHit; /* See the OP_SeekHit and OP_IfNoHope opcodes */ |
| 21815 | | - Btree *pBtx; /* Separate file holding temporary table */ |
| 21817 | + union { /* pBtx for isEphermeral. pAltMap otherwise */ |
| 21818 | + Btree *pBtx; /* Separate file holding temporary table */ |
| 21819 | + u32 *aAltMap; /* Mapping from table to index column numbers */ |
| 21820 | + } ub; |
| 21816 | 21821 | i64 seqCount; /* Sequence counter */ |
| 21817 | | - u32 *aAltMap; /* Mapping from table to index column numbers */ |
| 21818 | 21822 | |
| 21819 | 21823 | /* Cached OP_Column parse information is only valid if cacheStatus matches |
| 21820 | 21824 | ** Vdbe.cacheCtr. Vdbe.cacheCtr will never take on the value of |
| 21821 | 21825 | ** CACHE_STALE (0) and so setting cacheStatus=CACHE_STALE guarantees that |
| 21822 | 21826 | ** the cache is out of date. */ |
| | @@ -56664,12 +56668,11 @@ |
| 56664 | 56668 | ** |
| 56665 | 56669 | ** a) The page number is less than or equal to the size of the |
| 56666 | 56670 | ** current database image, in pages, OR |
| 56667 | 56671 | ** |
| 56668 | 56672 | ** b) if the page content were written at this time, it would not |
| 56669 | | -** be necessary to write the current content out to the sub-journal |
| 56670 | | -** (as determined by function subjRequiresPage()). |
| 56673 | +** be necessary to write the current content out to the sub-journal. |
| 56671 | 56674 | ** |
| 56672 | 56675 | ** If the condition asserted by this function were not true, and the |
| 56673 | 56676 | ** dirty page were to be discarded from the cache via the pagerStress() |
| 56674 | 56677 | ** routine, pagerStress() would not write the current page content to |
| 56675 | 56678 | ** the database file. If a savepoint transaction were rolled back after |
| | @@ -56680,12 +56683,20 @@ |
| 56680 | 56683 | ** database image would become corrupt. It is therefore fortunate that |
| 56681 | 56684 | ** this circumstance cannot arise. |
| 56682 | 56685 | */ |
| 56683 | 56686 | #if defined(SQLITE_DEBUG) |
| 56684 | 56687 | static void assertTruncateConstraintCb(PgHdr *pPg){ |
| 56688 | + Pager *pPager = pPg->pPager; |
| 56685 | 56689 | assert( pPg->flags&PGHDR_DIRTY ); |
| 56686 | | - assert( !subjRequiresPage(pPg) || pPg->pgno<=pPg->pPager->dbSize ); |
| 56690 | + if( pPg->pgno>pPager->dbSize ){ /* if (a) is false */ |
| 56691 | + Pgno pgno = pPg->pgno; |
| 56692 | + int i; |
| 56693 | + for(i=0; i<pPg->pPager->nSavepoint; i++){ |
| 56694 | + PagerSavepoint *p = &pPager->aSavepoint[i]; |
| 56695 | + assert( p->nOrig<pgno || sqlite3BitvecTestNotNull(p->pInSavepoint,pgno) ); |
| 56696 | + } |
| 56697 | + } |
| 56687 | 56698 | } |
| 56688 | 56699 | static void assertTruncateConstraint(Pager *pPager){ |
| 56689 | 56700 | sqlite3PcacheIterateDirty(pPager->pPCache, assertTruncateConstraintCb); |
| 56690 | 56701 | } |
| 56691 | 56702 | #else |
| | @@ -58022,11 +58033,11 @@ |
| 58022 | 58033 | ** other connection managed to get in and roll it back before |
| 58023 | 58034 | ** this connection obtained the exclusive lock above. Or, it |
| 58024 | 58035 | ** may mean that the pager was in the error-state when this |
| 58025 | 58036 | ** function was called and the journal file does not exist. |
| 58026 | 58037 | */ |
| 58027 | | - if( !isOpen(pPager->jfd) ){ |
| 58038 | + if( !isOpen(pPager->jfd) && pPager->journalMode!=PAGER_JOURNALMODE_OFF ){ |
| 58028 | 58039 | sqlite3_vfs * const pVfs = pPager->pVfs; |
| 58029 | 58040 | int bExists; /* True if journal file exists */ |
| 58030 | 58041 | rc = sqlite3OsAccess( |
| 58031 | 58042 | pVfs, pPager->zJournal, SQLITE_ACCESS_EXISTS, &bExists); |
| 58032 | 58043 | if( rc==SQLITE_OK && bExists ){ |
| | @@ -60029,16 +60040,16 @@ |
| 60029 | 60040 | */ |
| 60030 | 60041 | SQLITE_PRIVATE int sqlite3PagerSetJournalMode(Pager *pPager, int eMode){ |
| 60031 | 60042 | u8 eOld = pPager->journalMode; /* Prior journalmode */ |
| 60032 | 60043 | |
| 60033 | 60044 | /* The eMode parameter is always valid */ |
| 60034 | | - assert( eMode==PAGER_JOURNALMODE_DELETE |
| 60035 | | - || eMode==PAGER_JOURNALMODE_TRUNCATE |
| 60036 | | - || eMode==PAGER_JOURNALMODE_PERSIST |
| 60037 | | - || eMode==PAGER_JOURNALMODE_OFF |
| 60038 | | - || eMode==PAGER_JOURNALMODE_WAL |
| 60039 | | - || eMode==PAGER_JOURNALMODE_MEMORY ); |
| 60045 | + assert( eMode==PAGER_JOURNALMODE_DELETE /* 0 */ |
| 60046 | + || eMode==PAGER_JOURNALMODE_PERSIST /* 1 */ |
| 60047 | + || eMode==PAGER_JOURNALMODE_OFF /* 2 */ |
| 60048 | + || eMode==PAGER_JOURNALMODE_TRUNCATE /* 3 */ |
| 60049 | + || eMode==PAGER_JOURNALMODE_MEMORY /* 4 */ |
| 60050 | + || eMode==PAGER_JOURNALMODE_WAL /* 5 */ ); |
| 60040 | 60051 | |
| 60041 | 60052 | /* This routine is only called from the OP_JournalMode opcode, and |
| 60042 | 60053 | ** the logic there will never allow a temporary file to be changed |
| 60043 | 60054 | ** to WAL mode. |
| 60044 | 60055 | */ |
| | @@ -60071,11 +60082,10 @@ |
| 60071 | 60082 | assert( (PAGER_JOURNALMODE_OFF & 5)==0 ); |
| 60072 | 60083 | assert( (PAGER_JOURNALMODE_WAL & 5)==5 ); |
| 60073 | 60084 | |
| 60074 | 60085 | assert( isOpen(pPager->fd) || pPager->exclusiveMode ); |
| 60075 | 60086 | if( !pPager->exclusiveMode && (eOld & 5)==1 && (eMode & 1)==0 ){ |
| 60076 | | - |
| 60077 | 60087 | /* In this case we would like to delete the journal file. If it is |
| 60078 | 60088 | ** not possible, then that is not a problem. Deleting the journal file |
| 60079 | 60089 | ** here is an optimization only. |
| 60080 | 60090 | ** |
| 60081 | 60091 | ** Before deleting the journal file, obtain a RESERVED lock on the |
| | @@ -66904,22 +66914,36 @@ |
| 66904 | 66914 | |
| 66905 | 66915 | /* The next block of code is equivalent to: |
| 66906 | 66916 | ** |
| 66907 | 66917 | ** pIter += getVarint(pIter, (u64*)&pInfo->nKey); |
| 66908 | 66918 | ** |
| 66909 | | - ** The code is inlined to avoid a function call. |
| 66919 | + ** The code is inlined and the loop is unrolled for performance. |
| 66920 | + ** This routine is a high-runner. |
| 66910 | 66921 | */ |
| 66911 | 66922 | iKey = *pIter; |
| 66912 | 66923 | if( iKey>=0x80 ){ |
| 66913 | | - u8 *pEnd = &pIter[7]; |
| 66914 | | - iKey &= 0x7f; |
| 66915 | | - while(1){ |
| 66916 | | - iKey = (iKey<<7) | (*++pIter & 0x7f); |
| 66917 | | - if( (*pIter)<0x80 ) break; |
| 66918 | | - if( pIter>=pEnd ){ |
| 66919 | | - iKey = (iKey<<8) | *++pIter; |
| 66920 | | - break; |
| 66924 | + u8 x; |
| 66925 | + iKey = ((iKey&0x7f)<<7) | ((x = *++pIter) & 0x7f); |
| 66926 | + if( x>=0x80 ){ |
| 66927 | + iKey = (iKey<<7) | ((x =*++pIter) & 0x7f); |
| 66928 | + if( x>=0x80 ){ |
| 66929 | + iKey = (iKey<<7) | ((x = *++pIter) & 0x7f); |
| 66930 | + if( x>=0x80 ){ |
| 66931 | + iKey = (iKey<<7) | ((x = *++pIter) & 0x7f); |
| 66932 | + if( x>=0x80 ){ |
| 66933 | + iKey = (iKey<<7) | ((x = *++pIter) & 0x7f); |
| 66934 | + if( x>=0x80 ){ |
| 66935 | + iKey = (iKey<<7) | ((x = *++pIter) & 0x7f); |
| 66936 | + if( x>=0x80 ){ |
| 66937 | + iKey = (iKey<<7) | ((x = *++pIter) & 0x7f); |
| 66938 | + if( x>=0x80 ){ |
| 66939 | + iKey = (iKey<<8) | (*++pIter); |
| 66940 | + } |
| 66941 | + } |
| 66942 | + } |
| 66943 | + } |
| 66944 | + } |
| 66921 | 66945 | } |
| 66922 | 66946 | } |
| 66923 | 66947 | } |
| 66924 | 66948 | pIter++; |
| 66925 | 66949 | |
| | @@ -71240,11 +71264,10 @@ |
| 71240 | 71264 | assert( pPage->intKey ); |
| 71241 | 71265 | lwr = 0; |
| 71242 | 71266 | upr = pPage->nCell-1; |
| 71243 | 71267 | assert( biasRight==0 || biasRight==1 ); |
| 71244 | 71268 | idx = upr>>(1-biasRight); /* idx = biasRight ? upr : (lwr+upr)/2; */ |
| 71245 | | - pCur->ix = (u16)idx; |
| 71246 | 71269 | for(;;){ |
| 71247 | 71270 | i64 nCellKey; |
| 71248 | 71271 | pCell = findCellPastPtr(pPage, idx); |
| 71249 | 71272 | if( pPage->intKeyLeaf ){ |
| 71250 | 71273 | while( 0x80 <= *(pCell++) ){ |
| | @@ -71382,11 +71405,10 @@ |
| 71382 | 71405 | assert( pPage->nCell>0 ); |
| 71383 | 71406 | assert( pPage->intKey==(pIdxKey==0) ); |
| 71384 | 71407 | lwr = 0; |
| 71385 | 71408 | upr = pPage->nCell-1; |
| 71386 | 71409 | idx = upr>>1; /* idx = (lwr+upr)/2; */ |
| 71387 | | - pCur->ix = (u16)idx; |
| 71388 | 71410 | for(;;){ |
| 71389 | 71411 | int nCell; /* Size of the pCell cell in bytes */ |
| 71390 | 71412 | pCell = findCellPastPtr(pPage, idx); |
| 71391 | 71413 | |
| 71392 | 71414 | /* The maximum supported page-size is 65536 bytes. This means that |
| | @@ -72498,17 +72520,19 @@ |
| 72498 | 72520 | u8 *ptr; /* Used to move bytes around within data[] */ |
| 72499 | 72521 | int rc; /* The return code */ |
| 72500 | 72522 | int hdr; /* Beginning of the header. 0 most pages. 100 page 1 */ |
| 72501 | 72523 | |
| 72502 | 72524 | if( *pRC ) return; |
| 72503 | | - assert( idx>=0 && idx<pPage->nCell ); |
| 72525 | + assert( idx>=0 ); |
| 72526 | + assert( idx<pPage->nCell ); |
| 72504 | 72527 | assert( CORRUPT_DB || sz==cellSize(pPage, idx) ); |
| 72505 | 72528 | assert( sqlite3PagerIswriteable(pPage->pDbPage) ); |
| 72506 | 72529 | assert( sqlite3_mutex_held(pPage->pBt->mutex) ); |
| 72507 | 72530 | assert( pPage->nFree>=0 ); |
| 72508 | 72531 | data = pPage->aData; |
| 72509 | 72532 | ptr = &pPage->aCellIdx[2*idx]; |
| 72533 | + assert( pPage->pBt->usableSize > (int)(ptr-data) ); |
| 72510 | 72534 | pc = get2byte(ptr); |
| 72511 | 72535 | hdr = pPage->hdrOffset; |
| 72512 | 72536 | testcase( pc==(u32)get2byte(&data[hdr+5]) ); |
| 72513 | 72537 | testcase( pc+sz==pPage->pBt->usableSize ); |
| 72514 | 72538 | if( pc+sz > pPage->pBt->usableSize ){ |
| | @@ -72799,11 +72823,11 @@ |
| 72799 | 72823 | int k; /* Current slot in pCArray->apEnd[] */ |
| 72800 | 72824 | u8 *pSrcEnd; /* Current pCArray->apEnd[k] value */ |
| 72801 | 72825 | |
| 72802 | 72826 | assert( i<iEnd ); |
| 72803 | 72827 | j = get2byte(&aData[hdr+5]); |
| 72804 | | - if( NEVER(j>(u32)usableSize) ){ j = 0; } |
| 72828 | + if( j>(u32)usableSize ){ j = 0; } |
| 72805 | 72829 | memcpy(&pTmp[j], &aData[j], usableSize - j); |
| 72806 | 72830 | |
| 72807 | 72831 | for(k=0; pCArray->ixNx[k]<=i && ALWAYS(k<NB*2); k++){} |
| 72808 | 72832 | pSrcEnd = pCArray->apEnd[k]; |
| 72809 | 72833 | |
| | @@ -73030,11 +73054,11 @@ |
| 73030 | 73054 | nCell -= nTail; |
| 73031 | 73055 | } |
| 73032 | 73056 | |
| 73033 | 73057 | pData = &aData[get2byteNotZero(&aData[hdr+5])]; |
| 73034 | 73058 | if( pData<pBegin ) goto editpage_fail; |
| 73035 | | - if( NEVER(pData>pPg->aDataEnd) ) goto editpage_fail; |
| 73059 | + if( pData>pPg->aDataEnd ) goto editpage_fail; |
| 73036 | 73060 | |
| 73037 | 73061 | /* Add cells to the start of the page */ |
| 73038 | 73062 | if( iNew<iOld ){ |
| 73039 | 73063 | int nAdd = MIN(nNew,iOld-iNew); |
| 73040 | 73064 | assert( (iOld-iNew)<nNew || nCell==0 || CORRUPT_DB ); |
| | @@ -74906,18 +74930,17 @@ |
| 74906 | 74930 | ** but which might be used by alternative storage engines. |
| 74907 | 74931 | */ |
| 74908 | 74932 | SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){ |
| 74909 | 74933 | Btree *p = pCur->pBtree; |
| 74910 | 74934 | BtShared *pBt = p->pBt; |
| 74911 | | - int rc; /* Return code */ |
| 74912 | | - MemPage *pPage; /* Page to delete cell from */ |
| 74913 | | - unsigned char *pCell; /* Pointer to cell to delete */ |
| 74914 | | - int iCellIdx; /* Index of cell to delete */ |
| 74915 | | - int iCellDepth; /* Depth of node containing pCell */ |
| 74916 | | - CellInfo info; /* Size of the cell being deleted */ |
| 74917 | | - int bSkipnext = 0; /* Leaf cursor in SKIPNEXT state */ |
| 74918 | | - u8 bPreserve = flags & BTREE_SAVEPOSITION; /* Keep cursor valid */ |
| 74935 | + int rc; /* Return code */ |
| 74936 | + MemPage *pPage; /* Page to delete cell from */ |
| 74937 | + unsigned char *pCell; /* Pointer to cell to delete */ |
| 74938 | + int iCellIdx; /* Index of cell to delete */ |
| 74939 | + int iCellDepth; /* Depth of node containing pCell */ |
| 74940 | + CellInfo info; /* Size of the cell being deleted */ |
| 74941 | + u8 bPreserve; /* Keep cursor valid. 2 for CURSOR_SKIPNEXT */ |
| 74919 | 74942 | |
| 74920 | 74943 | assert( cursorOwnsBtShared(pCur) ); |
| 74921 | 74944 | assert( pBt->inTransaction==TRANS_WRITE ); |
| 74922 | 74945 | assert( (pBt->btsFlags & BTS_READ_ONLY)==0 ); |
| 74923 | 74946 | assert( pCur->curFlags & BTCF_WriteFlag ); |
| | @@ -74932,22 +74955,35 @@ |
| 74932 | 74955 | assert( CORRUPT_DB || pCur->eState==CURSOR_VALID ); |
| 74933 | 74956 | |
| 74934 | 74957 | iCellDepth = pCur->iPage; |
| 74935 | 74958 | iCellIdx = pCur->ix; |
| 74936 | 74959 | pPage = pCur->pPage; |
| 74960 | + if( pPage->nCell<=iCellIdx ){ |
| 74961 | + return SQLITE_CORRUPT_BKPT; |
| 74962 | + } |
| 74937 | 74963 | pCell = findCell(pPage, iCellIdx); |
| 74938 | | - if( pPage->nFree<0 && btreeComputeFreeSpace(pPage) ) return SQLITE_CORRUPT; |
| 74964 | + if( pPage->nFree<0 && btreeComputeFreeSpace(pPage) ){ |
| 74965 | + return SQLITE_CORRUPT_BKPT; |
| 74966 | + } |
| 74939 | 74967 | |
| 74940 | | - /* If the bPreserve flag is set to true, then the cursor position must |
| 74968 | + /* If the BTREE_SAVEPOSITION bit is on, then the cursor position must |
| 74941 | 74969 | ** be preserved following this delete operation. If the current delete |
| 74942 | 74970 | ** will cause a b-tree rebalance, then this is done by saving the cursor |
| 74943 | 74971 | ** key and leaving the cursor in CURSOR_REQUIRESEEK state before |
| 74944 | 74972 | ** returning. |
| 74945 | 74973 | ** |
| 74946 | | - ** Or, if the current delete will not cause a rebalance, then the cursor |
| 74974 | + ** If the current delete will not cause a rebalance, then the cursor |
| 74947 | 74975 | ** will be left in CURSOR_SKIPNEXT state pointing to the entry immediately |
| 74948 | | - ** before or after the deleted entry. In this case set bSkipnext to true. */ |
| 74976 | + ** before or after the deleted entry. |
| 74977 | + ** |
| 74978 | + ** The bPreserve value records which path is required: |
| 74979 | + ** |
| 74980 | + ** bPreserve==0 Not necessary to save the cursor position |
| 74981 | + ** bPreserve==1 Use CURSOR_REQUIRESEEK to save the cursor position |
| 74982 | + ** bPreserve==2 Cursor won't move. Set CURSOR_SKIPNEXT. |
| 74983 | + */ |
| 74984 | + bPreserve = (flags & BTREE_SAVEPOSITION)!=0; |
| 74949 | 74985 | if( bPreserve ){ |
| 74950 | 74986 | if( !pPage->leaf |
| 74951 | 74987 | || (pPage->nFree+cellSizePtr(pPage,pCell)+2)>(int)(pBt->usableSize*2/3) |
| 74952 | 74988 | || pPage->nCell==1 /* See dbfuzz001.test for a test case */ |
| 74953 | 74989 | ){ |
| | @@ -74954,11 +74990,11 @@ |
| 74954 | 74990 | /* A b-tree rebalance will be required after deleting this entry. |
| 74955 | 74991 | ** Save the cursor key. */ |
| 74956 | 74992 | rc = saveCursorKey(pCur); |
| 74957 | 74993 | if( rc ) return rc; |
| 74958 | 74994 | }else{ |
| 74959 | | - bSkipnext = 1; |
| 74995 | + bPreserve = 2; |
| 74960 | 74996 | } |
| 74961 | 74997 | } |
| 74962 | 74998 | |
| 74963 | 74999 | /* If the page containing the entry to delete is not a leaf page, move |
| 74964 | 75000 | ** the cursor to the largest entry in the tree that is smaller than |
| | @@ -75054,12 +75090,12 @@ |
| 75054 | 75090 | pCur->pPage = pCur->apPage[pCur->iPage]; |
| 75055 | 75091 | rc = balance(pCur); |
| 75056 | 75092 | } |
| 75057 | 75093 | |
| 75058 | 75094 | if( rc==SQLITE_OK ){ |
| 75059 | | - if( bSkipnext ){ |
| 75060 | | - assert( bPreserve && (pCur->iPage==iCellDepth || CORRUPT_DB) ); |
| 75095 | + if( bPreserve>1 ){ |
| 75096 | + assert( (pCur->iPage==iCellDepth || CORRUPT_DB) ); |
| 75061 | 75097 | assert( pPage==pCur->pPage || CORRUPT_DB ); |
| 75062 | 75098 | assert( (pPage->nCell>0 || CORRUPT_DB) && iCellIdx<=pPage->nCell ); |
| 75063 | 75099 | pCur->eState = CURSOR_SKIPNEXT; |
| 75064 | 75100 | if( iCellIdx>=pPage->nCell ){ |
| 75065 | 75101 | pCur->skipNext = -1; |
| | @@ -81753,12 +81789,10 @@ |
| 81753 | 81789 | */ |
| 81754 | 81790 | SQLITE_PRIVATE void sqlite3VdbeFreeCursor(Vdbe *p, VdbeCursor *pCx){ |
| 81755 | 81791 | if( pCx==0 ){ |
| 81756 | 81792 | return; |
| 81757 | 81793 | } |
| 81758 | | - assert( pCx->pBtx==0 || pCx->eCurType==CURTYPE_BTREE ); |
| 81759 | | - assert( pCx->pBtx==0 || pCx->isEphemeral ); |
| 81760 | 81794 | switch( pCx->eCurType ){ |
| 81761 | 81795 | case CURTYPE_SORTER: { |
| 81762 | 81796 | sqlite3VdbeSorterClose(p->db, pCx); |
| 81763 | 81797 | break; |
| 81764 | 81798 | } |
| | @@ -82856,11 +82890,11 @@ |
| 82856 | 82890 | VdbeCursor *p = *pp; |
| 82857 | 82891 | assert( p->eCurType==CURTYPE_BTREE || p->eCurType==CURTYPE_PSEUDO ); |
| 82858 | 82892 | if( p->deferredMoveto ){ |
| 82859 | 82893 | u32 iMap; |
| 82860 | 82894 | assert( !p->isEphemeral ); |
| 82861 | | - if( p->aAltMap && (iMap = p->aAltMap[1+*piCol])>0 && !p->nullRow ){ |
| 82895 | + if( p->ub.aAltMap && (iMap = p->ub.aAltMap[1+*piCol])>0 && !p->nullRow ){ |
| 82862 | 82896 | *pp = p->pAltCursor; |
| 82863 | 82897 | *piCol = iMap - 1; |
| 82864 | 82898 | return SQLITE_OK; |
| 82865 | 82899 | } |
| 82866 | 82900 | return sqlite3VdbeFinishMoveto(p); |
| | @@ -87057,11 +87091,10 @@ |
| 87057 | 87091 | */ |
| 87058 | 87092 | static VdbeCursor *allocateCursor( |
| 87059 | 87093 | Vdbe *p, /* The virtual machine */ |
| 87060 | 87094 | int iCur, /* Index of the new VdbeCursor */ |
| 87061 | 87095 | int nField, /* Number of fields in the table or index */ |
| 87062 | | - int iDb, /* Database the cursor belongs to, or -1 */ |
| 87063 | 87096 | u8 eCurType /* Type of the new cursor */ |
| 87064 | 87097 | ){ |
| 87065 | 87098 | /* Find the memory cell that will be used to store the blob of memory |
| 87066 | 87099 | ** required for this VdbeCursor structure. It is convenient to use a |
| 87067 | 87100 | ** vdbe memory cell to manage the memory allocation required for a |
| | @@ -87114,11 +87147,10 @@ |
| 87114 | 87147 | } |
| 87115 | 87148 | |
| 87116 | 87149 | p->apCsr[iCur] = pCx = (VdbeCursor*)pMem->zMalloc; |
| 87117 | 87150 | memset(pCx, 0, offsetof(VdbeCursor,pAltCursor)); |
| 87118 | 87151 | pCx->eCurType = eCurType; |
| 87119 | | - pCx->iDb = iDb; |
| 87120 | 87152 | pCx->nField = nField; |
| 87121 | 87153 | pCx->aOffset = &pCx->aType[nField]; |
| 87122 | 87154 | if( eCurType==CURTYPE_BTREE ){ |
| 87123 | 87155 | pCx->uc.pCursor = (BtCursor*) |
| 87124 | 87156 | &pMem->z[ROUND8(sizeof(VdbeCursor))+2*sizeof(u32)*nField]; |
| | @@ -89508,10 +89540,11 @@ |
| 89508 | 89540 | pDest = &aMem[pOp->p3]; |
| 89509 | 89541 | memAboutToChange(p, pDest); |
| 89510 | 89542 | assert( pC!=0 ); |
| 89511 | 89543 | assert( p2<(u32)pC->nField ); |
| 89512 | 89544 | aOffset = pC->aOffset; |
| 89545 | + assert( aOffset==pC->aType+pC->nField ); |
| 89513 | 89546 | assert( pC->eCurType!=CURTYPE_VTAB ); |
| 89514 | 89547 | assert( pC->eCurType!=CURTYPE_PSEUDO || pC->nullRow ); |
| 89515 | 89548 | assert( pC->eCurType!=CURTYPE_SORTER ); |
| 89516 | 89549 | |
| 89517 | 89550 | if( pC->cacheStatus!=p->cacheCtr ){ /*OPTIMIZATION-IF-FALSE*/ |
| | @@ -90657,10 +90690,11 @@ |
| 90657 | 90690 | rc = sqlite3BtreeUpdateMeta(pDb->pBt, pOp->p2, pOp->p3); |
| 90658 | 90691 | if( pOp->p2==BTREE_SCHEMA_VERSION ){ |
| 90659 | 90692 | /* When the schema cookie changes, record the new cookie internally */ |
| 90660 | 90693 | pDb->pSchema->schema_cookie = pOp->p3 - pOp->p5; |
| 90661 | 90694 | db->mDbFlags |= DBFLAG_SchemaChange; |
| 90695 | + sqlite3FkClearTriggerCache(db, pOp->p1); |
| 90662 | 90696 | }else if( pOp->p2==BTREE_FILE_FORMAT ){ |
| 90663 | 90697 | /* Record changes in the file format */ |
| 90664 | 90698 | pDb->pSchema->file_format = pOp->p3; |
| 90665 | 90699 | } |
| 90666 | 90700 | if( pOp->p1==1 ){ |
| | @@ -90834,12 +90868,13 @@ |
| 90834 | 90868 | nField = pOp->p4.i; |
| 90835 | 90869 | } |
| 90836 | 90870 | assert( pOp->p1>=0 ); |
| 90837 | 90871 | assert( nField>=0 ); |
| 90838 | 90872 | testcase( nField==0 ); /* Table with INTEGER PRIMARY KEY and nothing else */ |
| 90839 | | - pCur = allocateCursor(p, pOp->p1, nField, iDb, CURTYPE_BTREE); |
| 90873 | + pCur = allocateCursor(p, pOp->p1, nField, CURTYPE_BTREE); |
| 90840 | 90874 | if( pCur==0 ) goto no_mem; |
| 90875 | + pCur->iDb = iDb; |
| 90841 | 90876 | pCur->nullRow = 1; |
| 90842 | 90877 | pCur->isOrdered = 1; |
| 90843 | 90878 | pCur->pgnoRoot = p2; |
| 90844 | 90879 | #ifdef SQLITE_DEBUG |
| 90845 | 90880 | pCur->wrFlag = wrFlag; |
| | @@ -90877,22 +90912,22 @@ |
| 90877 | 90912 | |
| 90878 | 90913 | pOrig = p->apCsr[pOp->p2]; |
| 90879 | 90914 | assert( pOrig ); |
| 90880 | 90915 | assert( pOrig->isEphemeral ); /* Only ephemeral cursors can be duplicated */ |
| 90881 | 90916 | |
| 90882 | | - pCx = allocateCursor(p, pOp->p1, pOrig->nField, -1, CURTYPE_BTREE); |
| 90917 | + pCx = allocateCursor(p, pOp->p1, pOrig->nField, CURTYPE_BTREE); |
| 90883 | 90918 | if( pCx==0 ) goto no_mem; |
| 90884 | 90919 | pCx->nullRow = 1; |
| 90885 | 90920 | pCx->isEphemeral = 1; |
| 90886 | 90921 | pCx->pKeyInfo = pOrig->pKeyInfo; |
| 90887 | 90922 | pCx->isTable = pOrig->isTable; |
| 90888 | 90923 | pCx->pgnoRoot = pOrig->pgnoRoot; |
| 90889 | 90924 | pCx->isOrdered = pOrig->isOrdered; |
| 90890 | | - pCx->pBtx = pOrig->pBtx; |
| 90925 | + pCx->ub.pBtx = pOrig->ub.pBtx; |
| 90891 | 90926 | pCx->hasBeenDuped = 1; |
| 90892 | 90927 | pOrig->hasBeenDuped = 1; |
| 90893 | | - rc = sqlite3BtreeCursor(pCx->pBtx, pCx->pgnoRoot, BTREE_WRCSR, |
| 90928 | + rc = sqlite3BtreeCursor(pCx->ub.pBtx, pCx->pgnoRoot, BTREE_WRCSR, |
| 90894 | 90929 | pCx->pKeyInfo, pCx->uc.pCursor); |
| 90895 | 90930 | /* The sqlite3BtreeCursor() routine can only fail for the first cursor |
| 90896 | 90931 | ** opened for a database. Since there is already an open cursor when this |
| 90897 | 90932 | ** opcode is run, the sqlite3BtreeCursor() cannot fail */ |
| 90898 | 90933 | assert( rc==SQLITE_OK ); |
| | @@ -90961,48 +90996,48 @@ |
| 90961 | 90996 | ** OP_OpenDup, then erase all existing content so that the table is |
| 90962 | 90997 | ** empty again, rather than creating a new table. */ |
| 90963 | 90998 | assert( pCx->isEphemeral ); |
| 90964 | 90999 | pCx->seqCount = 0; |
| 90965 | 91000 | pCx->cacheStatus = CACHE_STALE; |
| 90966 | | - rc = sqlite3BtreeClearTable(pCx->pBtx, pCx->pgnoRoot, 0); |
| 91001 | + rc = sqlite3BtreeClearTable(pCx->ub.pBtx, pCx->pgnoRoot, 0); |
| 90967 | 91002 | }else{ |
| 90968 | | - pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, CURTYPE_BTREE); |
| 91003 | + pCx = allocateCursor(p, pOp->p1, pOp->p2, CURTYPE_BTREE); |
| 90969 | 91004 | if( pCx==0 ) goto no_mem; |
| 90970 | 91005 | pCx->isEphemeral = 1; |
| 90971 | | - rc = sqlite3BtreeOpen(db->pVfs, 0, db, &pCx->pBtx, |
| 91006 | + rc = sqlite3BtreeOpen(db->pVfs, 0, db, &pCx->ub.pBtx, |
| 90972 | 91007 | BTREE_OMIT_JOURNAL | BTREE_SINGLE | pOp->p5, |
| 90973 | 91008 | vfsFlags); |
| 90974 | 91009 | if( rc==SQLITE_OK ){ |
| 90975 | | - rc = sqlite3BtreeBeginTrans(pCx->pBtx, 1, 0); |
| 91010 | + rc = sqlite3BtreeBeginTrans(pCx->ub.pBtx, 1, 0); |
| 90976 | 91011 | if( rc==SQLITE_OK ){ |
| 90977 | 91012 | /* If a transient index is required, create it by calling |
| 90978 | 91013 | ** sqlite3BtreeCreateTable() with the BTREE_BLOBKEY flag before |
| 90979 | 91014 | ** opening it. If a transient table is required, just use the |
| 90980 | 91015 | ** automatically created table with root-page 1 (an BLOB_INTKEY table). |
| 90981 | 91016 | */ |
| 90982 | 91017 | if( (pCx->pKeyInfo = pKeyInfo = pOp->p4.pKeyInfo)!=0 ){ |
| 90983 | 91018 | assert( pOp->p4type==P4_KEYINFO ); |
| 90984 | | - rc = sqlite3BtreeCreateTable(pCx->pBtx, &pCx->pgnoRoot, |
| 91019 | + rc = sqlite3BtreeCreateTable(pCx->ub.pBtx, &pCx->pgnoRoot, |
| 90985 | 91020 | BTREE_BLOBKEY | pOp->p5); |
| 90986 | 91021 | if( rc==SQLITE_OK ){ |
| 90987 | 91022 | assert( pCx->pgnoRoot==SCHEMA_ROOT+1 ); |
| 90988 | 91023 | assert( pKeyInfo->db==db ); |
| 90989 | 91024 | assert( pKeyInfo->enc==ENC(db) ); |
| 90990 | | - rc = sqlite3BtreeCursor(pCx->pBtx, pCx->pgnoRoot, BTREE_WRCSR, |
| 91025 | + rc = sqlite3BtreeCursor(pCx->ub.pBtx, pCx->pgnoRoot, BTREE_WRCSR, |
| 90991 | 91026 | pKeyInfo, pCx->uc.pCursor); |
| 90992 | 91027 | } |
| 90993 | 91028 | pCx->isTable = 0; |
| 90994 | 91029 | }else{ |
| 90995 | 91030 | pCx->pgnoRoot = SCHEMA_ROOT; |
| 90996 | | - rc = sqlite3BtreeCursor(pCx->pBtx, SCHEMA_ROOT, BTREE_WRCSR, |
| 91031 | + rc = sqlite3BtreeCursor(pCx->ub.pBtx, SCHEMA_ROOT, BTREE_WRCSR, |
| 90997 | 91032 | 0, pCx->uc.pCursor); |
| 90998 | 91033 | pCx->isTable = 1; |
| 90999 | 91034 | } |
| 91000 | 91035 | } |
| 91001 | 91036 | pCx->isOrdered = (pOp->p5!=BTREE_UNORDERED); |
| 91002 | 91037 | if( rc ){ |
| 91003 | | - sqlite3BtreeClose(pCx->pBtx); |
| 91038 | + sqlite3BtreeClose(pCx->ub.pBtx); |
| 91004 | 91039 | } |
| 91005 | 91040 | } |
| 91006 | 91041 | } |
| 91007 | 91042 | if( rc ) goto abort_due_to_error; |
| 91008 | 91043 | pCx->nullRow = 1; |
| | @@ -91022,11 +91057,11 @@ |
| 91022 | 91057 | case OP_SorterOpen: { |
| 91023 | 91058 | VdbeCursor *pCx; |
| 91024 | 91059 | |
| 91025 | 91060 | assert( pOp->p1>=0 ); |
| 91026 | 91061 | assert( pOp->p2>=0 ); |
| 91027 | | - pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, CURTYPE_SORTER); |
| 91062 | + pCx = allocateCursor(p, pOp->p1, pOp->p2, CURTYPE_SORTER); |
| 91028 | 91063 | if( pCx==0 ) goto no_mem; |
| 91029 | 91064 | pCx->pKeyInfo = pOp->p4.pKeyInfo; |
| 91030 | 91065 | assert( pCx->pKeyInfo->db==db ); |
| 91031 | 91066 | assert( pCx->pKeyInfo->enc==ENC(db) ); |
| 91032 | 91067 | rc = sqlite3VdbeSorterInit(db, pOp->p3, pCx); |
| | @@ -91071,11 +91106,11 @@ |
| 91071 | 91106 | case OP_OpenPseudo: { |
| 91072 | 91107 | VdbeCursor *pCx; |
| 91073 | 91108 | |
| 91074 | 91109 | assert( pOp->p1>=0 ); |
| 91075 | 91110 | assert( pOp->p3>=0 ); |
| 91076 | | - pCx = allocateCursor(p, pOp->p1, pOp->p3, -1, CURTYPE_PSEUDO); |
| 91111 | + pCx = allocateCursor(p, pOp->p1, pOp->p3, CURTYPE_PSEUDO); |
| 91077 | 91112 | if( pCx==0 ) goto no_mem; |
| 91078 | 91113 | pCx->nullRow = 1; |
| 91079 | 91114 | pCx->seekResult = pOp->p2; |
| 91080 | 91115 | pCx->isTable = 1; |
| 91081 | 91116 | /* Give this pseudo-cursor a fake BtCursor pointer so that pCx |
| | @@ -93011,13 +93046,13 @@ |
| 93011 | 93046 | assert( pTabCur->isTable ); |
| 93012 | 93047 | pTabCur->nullRow = 0; |
| 93013 | 93048 | pTabCur->movetoTarget = rowid; |
| 93014 | 93049 | pTabCur->deferredMoveto = 1; |
| 93015 | 93050 | assert( pOp->p4type==P4_INTARRAY || pOp->p4.ai==0 ); |
| 93016 | | - pTabCur->aAltMap = pOp->p4.ai; |
| 93017 | | - assert( !pC->isEphemeral ); |
| 93018 | 93051 | assert( !pTabCur->isEphemeral ); |
| 93052 | + pTabCur->ub.aAltMap = pOp->p4.ai; |
| 93053 | + assert( !pC->isEphemeral ); |
| 93019 | 93054 | pTabCur->pAltCursor = pC; |
| 93020 | 93055 | }else{ |
| 93021 | 93056 | pOut = out2Prerelease(p, pOp); |
| 93022 | 93057 | pOut->u.i = rowid; |
| 93023 | 93058 | } |
| | @@ -94535,11 +94570,11 @@ |
| 94535 | 94570 | |
| 94536 | 94571 | /* Initialize sqlite3_vtab_cursor base class */ |
| 94537 | 94572 | pVCur->pVtab = pVtab; |
| 94538 | 94573 | |
| 94539 | 94574 | /* Initialize vdbe cursor object */ |
| 94540 | | - pCur = allocateCursor(p, pOp->p1, 0, -1, CURTYPE_VTAB); |
| 94575 | + pCur = allocateCursor(p, pOp->p1, 0, CURTYPE_VTAB); |
| 94541 | 94576 | if( pCur ){ |
| 94542 | 94577 | pCur->uc.pVCur = pVCur; |
| 94543 | 94578 | pVtab->nRef++; |
| 94544 | 94579 | }else{ |
| 94545 | 94580 | assert( db->mallocFailed ); |
| | @@ -96860,11 +96895,12 @@ |
| 96860 | 96895 | if( nWorker>=SORTER_MAX_MERGE_COUNT ){ |
| 96861 | 96896 | nWorker = SORTER_MAX_MERGE_COUNT-1; |
| 96862 | 96897 | } |
| 96863 | 96898 | #endif |
| 96864 | 96899 | |
| 96865 | | - assert( pCsr->pKeyInfo && pCsr->pBtx==0 ); |
| 96900 | + assert( pCsr->pKeyInfo ); |
| 96901 | + assert( !pCsr->isEphemeral ); |
| 96866 | 96902 | assert( pCsr->eCurType==CURTYPE_SORTER ); |
| 96867 | 96903 | szKeyInfo = sizeof(KeyInfo) + (pCsr->pKeyInfo->nKeyField-1)*sizeof(CollSeq*); |
| 96868 | 96904 | sz = sizeof(VdbeSorter) + nWorker * sizeof(SortSubtask); |
| 96869 | 96905 | |
| 96870 | 96906 | pSorter = (VdbeSorter*)sqlite3DbMallocZero(db, sz + szKeyInfo); |
| | @@ -99360,11 +99396,11 @@ |
| 99360 | 99396 | if( size==0 ){ |
| 99361 | 99397 | memjrnlFreeChunks(p->pFirst); |
| 99362 | 99398 | p->pFirst = 0; |
| 99363 | 99399 | }else{ |
| 99364 | 99400 | i64 iOff = p->nChunkSize; |
| 99365 | | - for(pIter=p->pFirst; ALWAYS(pIter) && iOff<=size; pIter=pIter->pNext){ |
| 99401 | + for(pIter=p->pFirst; ALWAYS(pIter) && iOff<size; pIter=pIter->pNext){ |
| 99366 | 99402 | iOff += p->nChunkSize; |
| 99367 | 99403 | } |
| 99368 | 99404 | if( ALWAYS(pIter) ){ |
| 99369 | 99405 | memjrnlFreeChunks(pIter->pNext); |
| 99370 | 99406 | pIter->pNext = 0; |
| | @@ -123463,10 +123499,29 @@ |
| 123463 | 123499 | sqlite3SelectDelete(dbMem, pStep->pSelect); |
| 123464 | 123500 | sqlite3ExprDelete(dbMem, p->pWhen); |
| 123465 | 123501 | sqlite3DbFree(dbMem, p); |
| 123466 | 123502 | } |
| 123467 | 123503 | } |
| 123504 | + |
| 123505 | +/* |
| 123506 | +** Clear the apTrigger[] cache of CASCADE triggers for all foreign keys |
| 123507 | +** in a particular database. This needs to happen when the schema |
| 123508 | +** changes. |
| 123509 | +*/ |
| 123510 | +SQLITE_PRIVATE void sqlite3FkClearTriggerCache(sqlite3 *db, int iDb){ |
| 123511 | + HashElem *k; |
| 123512 | + Hash *pHash = &db->aDb[iDb].pSchema->tblHash; |
| 123513 | + for(k=sqliteHashFirst(pHash); k; k=sqliteHashNext(k)){ |
| 123514 | + Table *pTab = sqliteHashData(k); |
| 123515 | + FKey *pFKey; |
| 123516 | + if( !IsOrdinaryTable(pTab) ) continue; |
| 123517 | + for(pFKey=pTab->u.tab.pFKey; pFKey; pFKey=pFKey->pNextFrom){ |
| 123518 | + fkTriggerDelete(db, pFKey->apTrigger[0]); pFKey->apTrigger[0] = 0; |
| 123519 | + fkTriggerDelete(db, pFKey->apTrigger[1]); pFKey->apTrigger[1] = 0; |
| 123520 | + } |
| 123521 | + } |
| 123522 | +} |
| 123468 | 123523 | |
| 123469 | 123524 | /* |
| 123470 | 123525 | ** This function is called to generate code that runs when table pTab is |
| 123471 | 123526 | ** being dropped from the database. The SrcList passed as the second argument |
| 123472 | 123527 | ** to this function contains a single entry guaranteed to resolve to |
| | @@ -124264,11 +124319,11 @@ |
| 124264 | 124319 | sqlite3VdbeAddOp4Int(v, opcode, iCur, pTab->tnum, iDb, pTab->nNVCol); |
| 124265 | 124320 | VdbeComment((v, "%s", pTab->zName)); |
| 124266 | 124321 | }else{ |
| 124267 | 124322 | Index *pPk = sqlite3PrimaryKeyIndex(pTab); |
| 124268 | 124323 | assert( pPk!=0 ); |
| 124269 | | - assert( pPk->tnum==pTab->tnum ); |
| 124324 | + assert( pPk->tnum==pTab->tnum || CORRUPT_DB ); |
| 124270 | 124325 | sqlite3VdbeAddOp3(v, opcode, iCur, pPk->tnum, iDb); |
| 124271 | 124326 | sqlite3VdbeSetP4KeyInfo(pParse, pPk); |
| 124272 | 124327 | VdbeComment((v, "%s", pTab->zName)); |
| 124273 | 124328 | } |
| 124274 | 124329 | } |
| | @@ -126768,11 +126823,10 @@ |
| 126768 | 126823 | sqlite3VdbeAddOp2(v, OP_IsNull, aRegIdx[i], sqlite3VdbeCurrentAddr(v)+2); |
| 126769 | 126824 | VdbeCoverage(v); |
| 126770 | 126825 | } |
| 126771 | 126826 | pik_flags = (useSeekResult ? OPFLAG_USESEEKRESULT : 0); |
| 126772 | 126827 | if( IsPrimaryKeyIndex(pIdx) && !HasRowid(pTab) ){ |
| 126773 | | - assert( pParse->nested==0 ); |
| 126774 | 126828 | pik_flags |= OPFLAG_NCHANGE; |
| 126775 | 126829 | pik_flags |= (update_flags & OPFLAG_SAVEPOSITION); |
| 126776 | 126830 | if( update_flags==0 ){ |
| 126777 | 126831 | codeWithoutRowidPreupdate(pParse, pTab, iIdxCur+i, aRegIdx[i]); |
| 126778 | 126832 | } |
| | @@ -133183,11 +133237,11 @@ |
| 133183 | 133237 | if( db->mallocFailed ){ |
| 133184 | 133238 | sParse.rc = SQLITE_NOMEM_BKPT; |
| 133185 | 133239 | sParse.checkSchema = 0; |
| 133186 | 133240 | } |
| 133187 | 133241 | if( sParse.rc!=SQLITE_OK && sParse.rc!=SQLITE_DONE ){ |
| 133188 | | - if( sParse.checkSchema ){ |
| 133242 | + if( sParse.checkSchema && db->init.busy==0 ){ |
| 133189 | 133243 | schemaIsValid(&sParse); |
| 133190 | 133244 | } |
| 133191 | 133245 | if( sParse.pVdbe ){ |
| 133192 | 133246 | sqlite3VdbeFinalize(sParse.pVdbe); |
| 133193 | 133247 | } |
| | @@ -142138,11 +142192,11 @@ |
| 142138 | 142192 | if( db->mallocFailed==0 && pParse->nErr==0 ){ |
| 142139 | 142193 | sqlite3GenerateColumnNames(pParse, &sSelect); |
| 142140 | 142194 | } |
| 142141 | 142195 | sqlite3ExprListDelete(db, sSelect.pEList); |
| 142142 | 142196 | pNew = sqlite3ExpandReturning(pParse, pReturning->pReturnEL, pTab); |
| 142143 | | - if( pNew ){ |
| 142197 | + if( !db->mallocFailed ){ |
| 142144 | 142198 | NameContext sNC; |
| 142145 | 142199 | memset(&sNC, 0, sizeof(sNC)); |
| 142146 | 142200 | if( pReturning->nRetCol==0 ){ |
| 142147 | 142201 | pReturning->nRetCol = pNew->nExpr; |
| 142148 | 142202 | pReturning->iRetCur = pParse->nTab++; |
| | @@ -142150,33 +142204,34 @@ |
| 142150 | 142204 | sNC.pParse = pParse; |
| 142151 | 142205 | sNC.uNC.iBaseReg = regIn; |
| 142152 | 142206 | sNC.ncFlags = NC_UBaseReg; |
| 142153 | 142207 | pParse->eTriggerOp = pTrigger->op; |
| 142154 | 142208 | pParse->pTriggerTab = pTab; |
| 142155 | | - if( sqlite3ResolveExprListNames(&sNC, pNew)==SQLITE_OK ){ |
| 142209 | + if( sqlite3ResolveExprListNames(&sNC, pNew)==SQLITE_OK |
| 142210 | + && !db->mallocFailed |
| 142211 | + ){ |
| 142156 | 142212 | int i; |
| 142157 | 142213 | int nCol = pNew->nExpr; |
| 142158 | 142214 | int reg = pParse->nMem+1; |
| 142159 | 142215 | pParse->nMem += nCol+2; |
| 142160 | 142216 | pReturning->iRetReg = reg; |
| 142161 | 142217 | for(i=0; i<nCol; i++){ |
| 142162 | 142218 | Expr *pCol = pNew->a[i].pExpr; |
| 142163 | | - assert( pCol!=0 || pParse->db->mallocFailed ); |
| 142164 | | - if( pCol==0 ) continue; |
| 142219 | + assert( pCol!=0 ); /* Due to !db->mallocFailed ~9 lines above */ |
| 142165 | 142220 | sqlite3ExprCodeFactorable(pParse, pCol, reg+i); |
| 142166 | 142221 | if( sqlite3ExprAffinity(pCol)==SQLITE_AFF_REAL ){ |
| 142167 | 142222 | sqlite3VdbeAddOp1(v, OP_RealAffinity, reg+i); |
| 142168 | 142223 | } |
| 142169 | 142224 | } |
| 142170 | 142225 | sqlite3VdbeAddOp3(v, OP_MakeRecord, reg, i, reg+i); |
| 142171 | 142226 | sqlite3VdbeAddOp2(v, OP_NewRowid, pReturning->iRetCur, reg+i+1); |
| 142172 | 142227 | sqlite3VdbeAddOp3(v, OP_Insert, pReturning->iRetCur, reg+i, reg+i+1); |
| 142173 | 142228 | } |
| 142174 | | - sqlite3ExprListDelete(db, pNew); |
| 142175 | | - pParse->eTriggerOp = 0; |
| 142176 | | - pParse->pTriggerTab = 0; |
| 142177 | 142229 | } |
| 142230 | + sqlite3ExprListDelete(db, pNew); |
| 142231 | + pParse->eTriggerOp = 0; |
| 142232 | + pParse->pTriggerTab = 0; |
| 142178 | 142233 | } |
| 142179 | 142234 | |
| 142180 | 142235 | |
| 142181 | 142236 | |
| 142182 | 142237 | /* |
| | @@ -229243,11 +229298,11 @@ |
| 229243 | 229298 | assert( (flags & FTS5INDEX_QUERY_SCAN)==0 || flags==FTS5INDEX_QUERY_SCAN ); |
| 229244 | 229299 | |
| 229245 | 229300 | if( sqlite3Fts5BufferSize(&p->rc, &buf, nToken+1)==0 ){ |
| 229246 | 229301 | int iIdx = 0; /* Index to search */ |
| 229247 | 229302 | int iPrefixIdx = 0; /* +1 prefix index */ |
| 229248 | | - if( nToken ) memcpy(&buf.p[1], pToken, nToken); |
| 229303 | + if( nToken>0 ) memcpy(&buf.p[1], pToken, nToken); |
| 229249 | 229304 | |
| 229250 | 229305 | /* Figure out which index to search and set iIdx accordingly. If this |
| 229251 | 229306 | ** is a prefix query for which there is no prefix index, set iIdx to |
| 229252 | 229307 | ** greater than pConfig->nPrefix to indicate that the query will be |
| 229253 | 229308 | ** satisfied by scanning multiple terms in the main index. |
| | @@ -233291,11 +233346,11 @@ |
| 233291 | 233346 | int nArg, /* Number of args */ |
| 233292 | 233347 | sqlite3_value **apUnused /* Function arguments */ |
| 233293 | 233348 | ){ |
| 233294 | 233349 | assert( nArg==0 ); |
| 233295 | 233350 | UNUSED_PARAM2(nArg, apUnused); |
| 233296 | | - sqlite3_result_text(pCtx, "fts5: 2021-12-31 22:53:15 e654b57a9fc32021453eed48d1c1bba65c833fb1aac3946567968c877e4cbd10", -1, SQLITE_TRANSIENT); |
| 233351 | + sqlite3_result_text(pCtx, "fts5: 2022-01-06 17:13:56 2d6a16caa7d28ad5c766036b2eb6c2020683fcc9389b3c7df2013739929dd36f", -1, SQLITE_TRANSIENT); |
| 233297 | 233352 | } |
| 233298 | 233353 | |
| 233299 | 233354 | /* |
| 233300 | 233355 | ** Return true if zName is the extension on one of the shadow tables used |
| 233301 | 233356 | ** by this module. |
| 233302 | 233357 | |