]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Transfer large index or WITHOUT ROWID records between b-trees when vacuuming without...
authordan <Dan Kennedy>
Wed, 9 Dec 2020 20:33:51 +0000 (20:33 +0000)
committerdan <Dan Kennedy>
Wed, 9 Dec 2020 20:33:51 +0000 (20:33 +0000)
FossilOrigin-Name: dfd4ca6891a893d0e9551689954d3e79114d5565f8a5264f96ad1d64fe1d6280

manifest
manifest.uuid
src/btree.c
src/btree.h
src/insert.c
src/vdbe.c

index 9e63b89316dd8be0147e2a4c4bfa904147af6c75..3a5de7a2d673a287b6a88c2888cdf280f54bc441 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Avoid\sloading\slarge\sintkey\srows\swhen\sVACUUMing,\seven\sif\sthe\spage-size\sis\schanging.
-D 2020-12-09T16:32:11.593
+C Transfer\slarge\sindex\sor\sWITHOUT\sROWID\srecords\sbetween\sb-trees\swhen\svacuuming\swithout\sloading\sthem\sinto\smemory.
+D 2020-12-09T20:33:51.761
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -481,8 +481,8 @@ F src/auth.c a3d5bfdba83d25abed1013a8c7a5f204e2e29b0c25242a56bc02bb0c07bf1e06
 F src/backup.c 3014889fa06e20e6adfa0d07b60097eec1f6e5b06671625f476a714d2356513d
 F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33
 F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6
-F src/btree.c 2dd52a7d6f473ef345ac028f49f3cc14e1207a3596b2d9fd92fe532e57da6328
-F src/btree.h cff4cd182eb0d97802d82f398e4c8447f01bd2f5e501f70386b1097c910091cb
+F src/btree.c ce6a27f7d8be22aed5914e3c5bb7293eb6bc8fa43b332c0c2cdd71afcceb81e7
+F src/btree.h 78908bc31dd4cbd54762825346d7a24534773ec4ca42e16faf10a0a164d74ec4
 F src/btreeInt.h ffd66480520d9d70222171b3a026d78b80833b5cea49c89867949f3e023d5f43
 F src/build.c f6449d4e85e998e14d3f537e8ea898dca2fcb83c277db3e60945af9b9177db81
 F src/callback.c d0b853dd413255d2e337b34545e54d888ea02f20da5ad0e63585b389624c4a6c
@@ -501,7 +501,7 @@ F src/hash.c 8d7dda241d0ebdafb6ffdeda3149a412d7df75102cecfc1021c98d6219823b19
 F src/hash.h 9d56a9079d523b648774c1784b74b89bd93fac7b365210157482e4319a468f38
 F src/hwtime.h cb1d7e3e1ed94b7aa6fde95ae2c2daccc3df826be26fc9ed7fd90d1750ae6144
 F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71
-F src/insert.c a64406fb5ae856fb30be018423eec9984a60a9b46d261447717c502b1fb781d3
+F src/insert.c 0c4f619e119dc6201fdc8f7ea4cbde9e71268cf3089b36c064c49c3e2d07077d
 F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa
 F src/loadext.c 8c9c8cd2bd8eecdb06d9b6e89de7e9e65bae45cc8fc33609cc74023a5c296067
 F src/main.c 97e9f137354bc1f76dc9bb60a0a24f8c45cf73b33e80d3ee4c64155336fb820d
@@ -612,7 +612,7 @@ F src/upsert.c 2920de71b20f04fe25eb00b655d086f0ba60ea133c59d7fa3325c49838818e78
 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0
 F src/util.c c0c7977de7ef9b8cb10f6c85f2d0557889a658f817b0455909a49179ba4c8002
 F src/vacuum.c 492422c1463c076473bae1858799c7a0a5fe87a133d1223239447c422cd26286
-F src/vdbe.c 77fd09a782f72d5ff6e69363353e80e31d26bedd1d187e8813d781c74ba15770
+F src/vdbe.c 334c2626ad478fc85c992856e71a6bdd95dc11bf0d7cfe10856ec915f3d9fbe5
 F src/vdbe.h 83603854bfa5851af601fc0947671eb260f4363e62e960e8a994fb9bbcd2aaa1
 F src/vdbeInt.h 3ca5e9fd6e095a8b6cf6bc3587a46fc93499503b2fe48951e1034ba9e2ce2f6e
 F src/vdbeapi.c c5e7cb2ab89a24d7f723e87b508f21bfb1359a04db5277d8a99fd1e015c12eb9
@@ -1889,7 +1889,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P c90e063ca9ddcdd1e9f1a2e25a3f7d6e7ee798373ad8acf65b90536b0a124c0d
-R 306b82fcb1780d3a4b54ba51609ce03f
+P 0d2c3776065dc94119899ae4164995193b82fca7ac31868f3141b729d0b65ab9
+R 2ada74530286abe77d1ee50368ad4c2c
 U dan
-Z fc13f09d46076f2b65a2bba6a14de43b
+Z b452c10135ea2f1997d2fa69cc2163a3
index e9576184e17e39a7d64b7134dbc461b87a2990d2..604f1fcaeb7eec082a20dfe0ba78cbc0cdd2125d 100644 (file)
@@ -1 +1 @@
-0d2c3776065dc94119899ae4164995193b82fca7ac31868f3141b729d0b65ab9
\ No newline at end of file
+dfd4ca6891a893d0e9551689954d3e79114d5565f8a5264f96ad1d64fe1d6280
\ No newline at end of file
index 96ea9c4a047b289ae08f7c87d986a40d9cd95208..8087d3935bb16d8f4ee7a335e2b2edd864cbdf12 100644 (file)
@@ -6518,10 +6518,6 @@ static int fillInCell(
   /* Fill in the header. */
   nHeader = pPage->childPtrSize;
   if( pPage->intKey ){
-    if( pX->nZero<0 ){
-      *pnSize = pX->nData;
-      return SQLITE_OK;
-    }
     nPayload = pX->nData + pX->nZero;
     pSrc = pX->pData;
     nSrc = pX->nData;
@@ -8682,7 +8678,8 @@ int sqlite3BtreeInsert(
   unsigned char *oldCell;
   unsigned char *newCell = 0;
 
-  assert( (flags & (BTREE_SAVEPOSITION|BTREE_APPEND))==flags );
+  assert( (flags & (BTREE_SAVEPOSITION|BTREE_APPEND|BTREE_PREFORMAT))==flags );
+  assert( (flags & BTREE_PREFORMAT)==0 || seekResult );
 
   if( pCur->eState==CURSOR_FAULT ){
     assert( pCur->skipNext!=SQLITE_OK );
@@ -8700,7 +8697,7 @@ int sqlite3BtreeInsert(
   ** keys with no associated data. If the cursor was opened expecting an
   ** intkey table, the caller should be inserting integer keys with a
   ** blob of associated data.  */
-  assert( (pX->pKey==0)==(pCur->pKeyInfo==0) );
+  assert( (pX->pKey==0)==(pCur->pKeyInfo==0) || (flags & BTREE_PREFORMAT) );
 
   /* Save the positions of any other cursors open on this table.
   **
@@ -8810,7 +8807,7 @@ int sqlite3BtreeInsert(
        || CORRUPT_DB );
 
   pPage = pCur->pPage;
-  assert( pPage->intKey || pX->nKey>=0 );
+  assert( pPage->intKey || pX->nKey>=0 || (flags & BTREE_PREFORMAT) );
   assert( pPage->leaf || !pPage->intKey );
   if( pPage->nFree<0 ){
     if( pCur->eState>CURSOR_INVALID ){
@@ -8827,8 +8824,15 @@ int sqlite3BtreeInsert(
   assert( pPage->isInit );
   newCell = pBt->pTmpSpace;
   assert( newCell!=0 );
-  rc = fillInCell(pPage, newCell, pX, &szNew);
-  if( rc ) goto end_insert;
+  if( flags & BTREE_PREFORMAT ){
+    assert( pX->pData==pBt->pTmpSpace );
+    szNew = pX->nData;
+    if( szNew<4 ) szNew = 4;
+    rc = SQLITE_OK;
+  }else{
+    rc = fillInCell(pPage, newCell, pX, &szNew);
+    if( rc ) goto end_insert;
+  }
   assert( szNew==pPage->xCellSize(pPage, newCell) );
   assert( szNew <= MX_CELL_SIZE(pBt) );
   idx = pCur->ix;
@@ -8959,9 +8963,8 @@ int sqlite3BtreeTransfer(
   getCellInfo(pSrc);
 
   x.pData = pCell;
-  x.nData = putVarint32(pCell, pSrc->info.nPayload);
-  x.nData += putVarint(&pCell[x.nData], iKey);
-  x.nZero = -1;
+  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];
@@ -9024,7 +9027,8 @@ int sqlite3BtreeTransfer(
   sqlite3PagerUnref(pPageIn);
 
   if( rc==SQLITE_OK ){
-    rc = sqlite3BtreeInsert(pDest, &x, OPFLAG_APPEND, seekResult);
+    int flags = BTREE_APPEND|BTREE_PREFORMAT;
+    rc = sqlite3BtreeInsert(pDest, &x, flags, seekResult);
   }
 
   return rc;
index abdfc3363034283e41af507b580dae195106d0f8..4c2a872bb99aa79191972c32fc2e9c6d113d5d7a 100644 (file)
@@ -262,6 +262,7 @@ int sqlite3BtreeDelete(BtCursor*, u8 flags);
 #define BTREE_SAVEPOSITION 0x02  /* Leave cursor pointing at NEXT or PREV */
 #define BTREE_AUXDELETE    0x04  /* not the primary delete operation */
 #define BTREE_APPEND       0x08  /* Insert is likely an append */
+#define BTREE_PREFORMAT    0x10  /* Insert is likely an append */
 
 /* An instance of the BtreePayload object describes the content of a single
 ** entry in either an index or table btree.
index d801b47902c8eb1915eb69e3f1b9e9f2647f5ace..0af845e887fbfc4df0ef83b0d6199124a49b2f0f 100644 (file)
@@ -2851,13 +2851,16 @@ static int xferOptimization(
       if( i==pSrcIdx->nColumn ){
         idxInsFlags = OPFLAG_USESEEKRESULT;
         sqlite3VdbeAddOp1(v, OP_SeekEnd, iDest);
+        sqlite3VdbeAddOp3(v, OP_Transfer, iDest, iSrc, 0);
       }
     }else if( !HasRowid(pSrc) && pDestIdx->idxType==SQLITE_IDXTYPE_PRIMARYKEY ){
       idxInsFlags |= OPFLAG_NCHANGE;
     }
-    sqlite3VdbeAddOp3(v, OP_RowData, iSrc, regData, 1);
-    sqlite3VdbeAddOp2(v, OP_IdxInsert, iDest, regData);
-    sqlite3VdbeChangeP5(v, idxInsFlags|OPFLAG_APPEND);
+    if( idxInsFlags!=OPFLAG_USESEEKRESULT ){
+      sqlite3VdbeAddOp3(v, OP_RowData, iSrc, regData, 1);
+      sqlite3VdbeAddOp2(v, OP_IdxInsert, iDest, regData);
+      sqlite3VdbeChangeP5(v, idxInsFlags|OPFLAG_APPEND);
+    }
     sqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1+1); VdbeCoverage(v);
     sqlite3VdbeJumpHere(v, addr1);
     sqlite3VdbeAddOp2(v, OP_Close, iSrc, 0);
index ea35e6aa56dc9ae4317a3fecf96be90f1e21eeaf..74fede85625988579ca9ba43cddbf89ab4e4bed1 100644 (file)
@@ -5158,7 +5158,7 @@ case OP_Transfer: {
 
   pDest = p->apCsr[pOp->p1];
   pSrc = p->apCsr[pOp->p2];
-  iKey = aMem[pOp->p3].u.i;
+  iKey = pOp->p3 ? aMem[pOp->p3].u.i : 0;
 
   rc = sqlite3BtreeTransfer(
       pDest->uc.pCursor, pSrc->uc.pCursor, iKey, pDest->seekResult