Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Changes In Branch cell-overwrite-prototype Excluding Merge-Ins
This is equivalent to a diff from 7fdad122a2 to 3e11dc3183
2018-05-07
| ||
11:48 | On an UPDATE, try to overwrite an existing btree cell with the modified content, if the old and new cell are the same size. Use memcmp() first to avoid dirtying pages that are unchanged. (check-in: 5887d8beb5 user: drh tags: trunk) | |
11:29 | Fix harmless compiler warnings in the cell-overwrite logic. (Closed-Leaf check-in: 3e11dc3183 user: drh tags: cell-overwrite-prototype) | |
2018-05-05
| ||
01:23 | Fix a slightly incorrect corruption detection branch in the btree logic. (check-in: 9191ff670c user: drh tags: trunk) | |
2018-05-04
| ||
19:33 | Merge recent enhancements from trunk. (check-in: e17bca2cdb user: drh tags: apple-osx) | |
19:18 | Merge enhancements from trunk. (check-in: 9650f71b82 user: drh tags: cell-overwrite-prototype) | |
18:32 | Fix requirements marks. No code changes. (check-in: 7fdad122a2 user: drh tags: trunk) | |
04:49 | For the amalgamation-tarball, enable FTS5 and JSON1 by default and provide a new --enable-debug option that actives debugging facilities. (check-in: 03edecaf9d user: drh tags: trunk) | |
Changes to src/btree.c.
︙ | ︙ | |||
8148 8149 8150 8151 8152 8153 8154 8155 8156 8157 8158 8159 8160 8161 | if( pFree ){ sqlite3PageFree(pFree); } return rc; } /* ** Insert a new record into the BTree. The content of the new record ** is described by the pX object. The pCur cursor is used only to ** define what table the record should be inserted into, and is left ** pointing at a random location. ** | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 8148 8149 8150 8151 8152 8153 8154 8155 8156 8157 8158 8159 8160 8161 8162 8163 8164 8165 8166 8167 8168 8169 8170 8171 8172 8173 8174 8175 8176 8177 8178 8179 8180 8181 8182 8183 8184 8185 8186 8187 8188 8189 8190 8191 8192 8193 8194 8195 8196 8197 8198 8199 8200 8201 8202 8203 8204 8205 8206 8207 8208 8209 8210 8211 8212 8213 8214 8215 8216 8217 8218 8219 8220 8221 8222 8223 8224 8225 8226 8227 8228 8229 8230 8231 8232 8233 8234 8235 8236 8237 8238 8239 8240 8241 8242 8243 8244 8245 8246 8247 8248 8249 | if( pFree ){ sqlite3PageFree(pFree); } return rc; } /* Overwrite content from pX into pDest. Only do the write if the ** content is different from what is already there. */ static int btreeOverwriteContent( MemPage *pPage, /* MemPage on which writing will occur */ u8 *pDest, /* Pointer to the place to start writing */ const BtreePayload *pX, /* Source of data to write */ int iOffset, /* Offset of first byte to write */ int iAmt /* Number of bytes to be written */ ){ int nData = pX->nData - iOffset; if( nData<=0 ){ /* Overwritting with zeros */ int i; for(i=0; i<iAmt && pDest[i]==0; i++){} if( i<iAmt ){ int rc = sqlite3PagerWrite(pPage->pDbPage); if( rc ) return rc; memset(pDest + i, 0, iAmt - i); } }else{ if( nData<iAmt ){ /* Mixed read data and zeros at the end. Make a recursive call ** to write the zeros then fall through to write the real data */ int rc = btreeOverwriteContent(pPage, pDest+nData, pX, iOffset+nData, iAmt-nData); if( rc ) return rc; iAmt = nData; } if( memcmp(pDest, ((u8*)pX->pData) + iOffset, iAmt)!=0 ){ int rc = sqlite3PagerWrite(pPage->pDbPage); if( rc ) return rc; memcpy(pDest, ((u8*)pX->pData) + iOffset, iAmt); } } return SQLITE_OK; } /* ** Overwrite the cell that cursor pCur is pointing to with fresh content ** contained in pX. */ static int btreeOverwriteCell(BtCursor *pCur, const BtreePayload *pX){ int iOffset; /* Next byte of pX->pData to write */ int nTotal = pX->nData + pX->nZero; /* Total bytes of to write */ int rc; /* Return code */ MemPage *pPage = pCur->pPage; /* Page being written */ BtShared *pBt; /* Btree */ Pgno ovflPgno; /* Next overflow page to write */ u32 ovflPageSize; /* Size to write on overflow page */ if( pCur->info.pPayload + pCur->info.nLocal > pPage->aDataEnd ){ return SQLITE_CORRUPT_BKPT; } /* Overwrite the local portion first */ rc = btreeOverwriteContent(pPage, pCur->info.pPayload, pX, 0, pCur->info.nLocal); if( rc ) return rc; if( pCur->info.nLocal==nTotal ) return SQLITE_OK; /* Now overwrite the overflow pages */ iOffset = pCur->info.nLocal; assert( nTotal>=0 ); assert( iOffset>=0 ); ovflPgno = get4byte(pCur->info.pPayload + iOffset); pBt = pPage->pBt; ovflPageSize = pBt->usableSize - 4; do{ rc = btreeGetPage(pBt, ovflPgno, &pPage, 0); if( rc ) return rc; if( sqlite3PagerPageRefcount(pPage->pDbPage)!=1 ){ rc = SQLITE_CORRUPT_BKPT; }else{ if( iOffset+ovflPageSize<(u32)nTotal ){ ovflPgno = get4byte(pPage->aData); }else{ ovflPageSize = nTotal - iOffset; } rc = btreeOverwriteContent(pPage, pPage->aData+4, pX, iOffset, ovflPageSize); } sqlite3PagerUnref(pPage->pDbPage); if( rc ) return rc; iOffset += ovflPageSize; }while( iOffset<nTotal ); return SQLITE_OK; } /* ** Insert a new record into the BTree. The content of the new record ** is described by the pX object. The pCur cursor is used only to ** define what table the record should be inserted into, and is left ** pointing at a random location. ** |
︙ | ︙ | |||
8246 8247 8248 8249 8250 8251 8252 8253 8254 8255 8256 8257 8258 8259 | assert( (flags & BTREE_SAVEPOSITION)==0 || ((pCur->curFlags&BTCF_ValidNKey)!=0 && pX->nKey==pCur->info.nKey) ); /* If the cursor is currently on the last row and we are appending a ** new row onto the end, set the "loc" to avoid an unnecessary ** btreeMoveto() call */ if( (pCur->curFlags&BTCF_ValidNKey)!=0 && pX->nKey==pCur->info.nKey ){ loc = 0; }else if( loc==0 ){ rc = sqlite3BtreeMovetoUnpacked(pCur, 0, pX->nKey, flags!=0, &loc); if( rc ) return rc; } }else if( loc==0 && (flags & BTREE_SAVEPOSITION)==0 ){ if( pX->nMem ){ | > > > > > > > > | 8334 8335 8336 8337 8338 8339 8340 8341 8342 8343 8344 8345 8346 8347 8348 8349 8350 8351 8352 8353 8354 8355 | assert( (flags & BTREE_SAVEPOSITION)==0 || ((pCur->curFlags&BTCF_ValidNKey)!=0 && pX->nKey==pCur->info.nKey) ); /* If the cursor is currently on the last row and we are appending a ** new row onto the end, set the "loc" to avoid an unnecessary ** btreeMoveto() call */ if( (pCur->curFlags&BTCF_ValidNKey)!=0 && pX->nKey==pCur->info.nKey ){ /* The current is currently pointing to the entry that is to be ** overwritten */ assert( pX->nData>=0 && pX->nZero>=0 ); if( pCur->info.nSize!=0 && pCur->info.nPayload==(u32)pX->nData+pX->nZero ){ return btreeOverwriteCell(pCur, pX); } loc = 0; }else if( loc==0 ){ rc = sqlite3BtreeMovetoUnpacked(pCur, 0, pX->nKey, flags!=0, &loc); if( rc ) return rc; } }else if( loc==0 && (flags & BTREE_SAVEPOSITION)==0 ){ if( pX->nMem ){ |
︙ | ︙ |
Changes to test/pager1.test.
︙ | ︙ | |||
1145 1146 1147 1148 1149 1150 1151 | do_test pager1-5.5.1 { sqlite3 db test.db execsql { ATTACH 'test.db2' AS aux; PRAGMA journal_mode = PERSIST; CREATE TABLE t3(a, b); INSERT INTO t3 SELECT randomblob(1500), randomblob(1500) FROM t1; | | | 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 | do_test pager1-5.5.1 { sqlite3 db test.db execsql { ATTACH 'test.db2' AS aux; PRAGMA journal_mode = PERSIST; CREATE TABLE t3(a, b); INSERT INTO t3 SELECT randomblob(1500), randomblob(1500) FROM t1; UPDATE t3 SET b = randomblob(1501); } expr [file size test.db-journal] > 15000 } {1} do_test pager1-5.5.2 { execsql { PRAGMA synchronous = full; BEGIN; |
︙ | ︙ |