diff options
author | dan <Dan Kennedy> | 2020-12-10 18:06:24 +0000 |
---|---|---|
committer | dan <Dan Kennedy> | 2020-12-10 18:06:24 +0000 |
commit | 7aae73588aeb9fd33d26f0d0a654bfbebdccf72c (patch) | |
tree | 4be4a4bb0a2159d5708dcce4fe4e2c03fd1c60e1 /src/btree.c | |
parent | cd1b2d0b5431164787d4acad07940191af992c6a (diff) | |
download | sqlite-7aae73588aeb9fd33d26f0d0a654bfbebdccf72c.tar.gz sqlite-7aae73588aeb9fd33d26f0d0a654bfbebdccf72c.zip |
Better integrate the changes on this branch with OP_Insert and OP_IdxInsert.
FossilOrigin-Name: 101cef14910d6e865a94bc870aed599321b893188062a9a61d70a9434992cf23
Diffstat (limited to 'src/btree.c')
-rw-r--r-- | src/btree.c | 168 |
1 files changed, 83 insertions, 85 deletions
diff --git a/src/btree.c b/src/btree.c index 8087d3935..224d533b7 100644 --- a/src/btree.c +++ b/src/btree.c @@ -8679,7 +8679,7 @@ int sqlite3BtreeInsert( unsigned char *newCell = 0; assert( (flags & (BTREE_SAVEPOSITION|BTREE_APPEND|BTREE_PREFORMAT))==flags ); - assert( (flags & BTREE_PREFORMAT)==0 || seekResult ); + assert( (flags & BTREE_PREFORMAT)==0 || seekResult || pCur->pKeyInfo==0 ); if( pCur->eState==CURSOR_FAULT ){ assert( pCur->skipNext!=SQLITE_OK ); @@ -8825,14 +8825,21 @@ int sqlite3BtreeInsert( newCell = pBt->pTmpSpace; assert( newCell!=0 ); if( flags & BTREE_PREFORMAT ){ - assert( pX->pData==pBt->pTmpSpace ); - szNew = pX->nData; - if( szNew<4 ) szNew = 4; rc = SQLITE_OK; + szNew = pBt->nPreformatSize; + if( szNew<4 ) szNew = 4; + if( ISAUTOVACUUM && szNew>pPage->maxLocal ){ + CellInfo info; + pPage->xParseCell(pPage, newCell, &info); + if( ISAUTOVACUUM && info.nPayload!=info.nLocal ){ + Pgno ovfl = get4byte(&newCell[szNew-4]); + ptrmapPut(pBt, ovfl, PTRMAP_OVERFLOW1, pPage->pgno, &rc); + } + } }else{ rc = fillInCell(pPage, newCell, pX, &szNew); - if( rc ) goto end_insert; } + if( rc ) goto end_insert; assert( szNew==pPage->xCellSize(pPage, newCell) ); assert( szNew <= MX_CELL_SIZE(pBt) ); idx = pCur->ix; @@ -8938,97 +8945,88 @@ end_insert: return rc; } -int sqlite3BtreeTransfer( - BtCursor *pDest, - BtCursor *pSrc, - i64 iKey, - int seekResult -){ +int sqlite3BtreeTransferRow(BtCursor *pDest, BtCursor *pSrc, i64 iKey){ int rc = SQLITE_OK; - BtreePayload x; - Pager *pSrcPager = pSrc->pBt->pPager; - u8 *pCell = pDest->pBt->pTmpSpace; - u8 *aOut; /* Pointer to next output buffer */ - int nOut; /* Size of output buffer aOut[] */ + BtShared *pBt = pDest->pBt; + u8 *aOut = pBt->pTmpSpace; /* Pointer to next output buffer */ const u8 *aIn; /* Pointer to next input buffer */ int nIn; /* Size of input buffer aIn[] */ int nRem; /* Bytes of data still to copy */ - u8 *pPgnoOut = 0; - Pgno ovflIn = 0; - DbPage *pPageIn = 0; - MemPage *pPageOut = 0; - memset(&x, 0, sizeof(x)); - x.nKey = iKey; getCellInfo(pSrc); - - x.pData = pCell; - x.nData += putVarint32(pCell, pSrc->info.nPayload); - if( pDest->pKeyInfo==0 ) x.nData += putVarint(&pCell[x.nData], iKey); - - nOut = btreePayloadToLocal(pDest->pPage, pSrc->info.nPayload); - aOut = &pCell[x.nData]; + aOut += putVarint32(aOut, pSrc->info.nPayload); + if( pDest->pKeyInfo==0 ) aOut += putVarint(aOut, iKey); nIn = pSrc->info.nLocal; aIn = pSrc->info.pPayload; nRem = pSrc->info.nPayload; - - x.nData += nOut; - if( nOut<pSrc->info.nPayload ){ - pPgnoOut = &pCell[x.nData]; - x.nData += 4; - } - - if( nRem>nIn ){ - ovflIn = get4byte(&pSrc->info.pPayload[nIn]); - } - - do { - nRem -= nOut; - do{ - assert( nOut>0 ); - if( nIn>0 ){ - int nCopy = MIN(nOut, nIn); - memcpy(aOut, aIn, nCopy); - nOut -= nCopy; - nIn -= nCopy; - aOut += nCopy; - aIn += nCopy; - } - if( nOut>0 ){ - sqlite3PagerUnref(pPageIn); - pPageIn = 0; - rc = sqlite3PagerGet(pSrcPager, ovflIn, &pPageIn, PAGER_GET_READONLY); - if( rc==SQLITE_OK ){ - aIn = (const u8*)sqlite3PagerGetData(pPageIn); - ovflIn = get4byte(aIn); - aIn += 4; - nIn = pSrc->pBt->usableSize - 4; + if( nIn==nRem && nIn<pDest->pPage->maxLocal ){ + memcpy(aOut, aIn, nIn); + pBt->nPreformatSize = nIn + (aOut - pBt->pTmpSpace); + }else{ + Pager *pSrcPager = pSrc->pBt->pPager; + u8 *pPgnoOut = 0; + Pgno ovflIn = 0; + DbPage *pPageIn = 0; + MemPage *pPageOut = 0; + int nOut; /* Size of output buffer aOut[] */ + + nOut = btreePayloadToLocal(pDest->pPage, pSrc->info.nPayload); + pBt->nPreformatSize = nOut + (aOut - pBt->pTmpSpace); + if( nOut<pSrc->info.nPayload ){ + pPgnoOut = &aOut[nOut]; + pBt->nPreformatSize += 4; + } + + if( nRem>nIn ){ + ovflIn = get4byte(&pSrc->info.pPayload[nIn]); + } + + do { + nRem -= nOut; + do{ + assert( nOut>0 ); + if( nIn>0 ){ + int nCopy = MIN(nOut, nIn); + memcpy(aOut, aIn, nCopy); + nOut -= nCopy; + nIn -= nCopy; + aOut += nCopy; + aIn += nCopy; + } + if( nOut>0 ){ + sqlite3PagerUnref(pPageIn); + pPageIn = 0; + rc = sqlite3PagerGet(pSrcPager, ovflIn, &pPageIn, PAGER_GET_READONLY); + if( rc==SQLITE_OK ){ + aIn = (const u8*)sqlite3PagerGetData(pPageIn); + ovflIn = get4byte(aIn); + aIn += 4; + nIn = pSrc->pBt->usableSize - 4; + } + } + }while( rc==SQLITE_OK && nOut>0 ); + + if( rc==SQLITE_OK && nRem>0 ){ + Pgno pgnoNew; + MemPage *pNew = 0; + rc = allocateBtreePage(pBt, &pNew, &pgnoNew, 0, 0); + put4byte(pPgnoOut, pgnoNew); + if( ISAUTOVACUUM && pPageOut ){ + ptrmapPut(pBt, pgnoNew, PTRMAP_OVERFLOW2, pPageOut->pgno, &rc); + } + releasePage(pPageOut); + pPageOut = pNew; + if( pPageOut ){ + pPgnoOut = pPageOut->aData; + put4byte(pPgnoOut, 0); + aOut = &pPgnoOut[4]; + nOut = MIN(pBt->usableSize - 4, nRem); } } - }while( rc==SQLITE_OK && nOut>0 ); - - if( rc==SQLITE_OK && nRem>0 ){ - Pgno pgnoNew; - MemPage *pNew = 0; - rc = allocateBtreePage(pDest->pBt, &pNew, &pgnoNew, 0, 0); - put4byte(pPgnoOut, pgnoNew); - releasePage(pPageOut); - pPageOut = pNew; - if( pPageOut ){ - pPgnoOut = pPageOut->aData; - put4byte(pPgnoOut, 0); - aOut = &pPgnoOut[4]; - nOut = MIN(pDest->pBt->usableSize - 4, nRem); - } - } - }while( nRem>0 && rc==SQLITE_OK ); - - releasePage(pPageOut); - sqlite3PagerUnref(pPageIn); - - if( rc==SQLITE_OK ){ - int flags = BTREE_APPEND|BTREE_PREFORMAT; - rc = sqlite3BtreeInsert(pDest, &x, flags, seekResult); + }while( nRem>0 && rc==SQLITE_OK ); + + releasePage(pPageOut); + sqlite3PagerUnref(pPageIn); } return rc; |