aboutsummaryrefslogtreecommitdiff
path: root/src/btree.c
diff options
context:
space:
mode:
authordan <Dan Kennedy>2020-12-10 18:06:24 +0000
committerdan <Dan Kennedy>2020-12-10 18:06:24 +0000
commit7aae73588aeb9fd33d26f0d0a654bfbebdccf72c (patch)
tree4be4a4bb0a2159d5708dcce4fe4e2c03fd1c60e1 /src/btree.c
parentcd1b2d0b5431164787d4acad07940191af992c6a (diff)
downloadsqlite-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.c168
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;