/ Check-in [aa61435a]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Improved oversized cell detection when updating ptrmap pages in balance_nonroot().
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: aa61435a4c3800f023788081c1342ad6a05a41449a424fa6c039d5ca46072256
User & Date: drh 2019-02-14 15:27:12
Context
2019-02-16
22:45
Fix an assert() that might be false for a corrupt database. check-in: 0cfb8887 user: drh tags: trunk
17:27
Add support for chaining of WINDOW definitions. check-in: c155125f user: dan tags: window-functions
2019-02-14
15:56
Merge latest trunk into this branch. check-in: 577d1638 user: dan tags: reuse-schema
15:27
Improved oversized cell detection when updating ptrmap pages in balance_nonroot(). check-in: aa61435a user: drh tags: trunk
2019-02-12
22:58
Ensure that the nProgressLimit variable is always initialized in sqlite3VdbeExec(), even if the routine jumps to its exit processing early. check-in: 167b91df user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/btree.c.

  6813   6813   **    ixNx[3] = Number of cells in Child-1 and Child-2 + both divider cells
  6814   6814   **    ixNx[4] = Total number of cells.
  6815   6815   **
  6816   6816   ** For a table-btree, the concept is similar, except only apEnd[0]..apEnd[2]
  6817   6817   ** are used and they point to the leaf pages only, and the ixNx value are:
  6818   6818   **
  6819   6819   **    ixNx[0] = Number of cells in Child-1.
  6820         -**    ixNx[1] = Number of cells in Child-1 and Child-2 + 1 for 1st divider.
  6821         -**    ixNx[2] = Number of cells in Child-1 and Child-2 + both divider cells
         6820  +**    ixNx[1] = Number of cells in Child-1 and Child-2.
         6821  +**    ixNx[2] = Total number of cells.
         6822  +**
         6823  +** Sometimes when deleting, a child page can have zero cells.  In those
         6824  +** cases, ixNx[] entries with higher indexes, and the corresponding apEnd[]
         6825  +** entries, shift down.  The end result is that each ixNx[] entry should
         6826  +** be larger than the previous
  6822   6827   */
  6823   6828   typedef struct CellArray CellArray;
  6824   6829   struct CellArray {
  6825   6830     int nCell;              /* Number of cells in apCell[] */
  6826   6831     MemPage *pRef;          /* Reference page */
  6827   6832     u8 **apCell;            /* All cells begin balanced */
  6828   6833     u16 *szCell;            /* Local size of all cells in apCell[] */
................................................................................
  7743   7748     ** 
  7744   7749     */
  7745   7750     usableSpace = pBt->usableSize - 12 + leafCorrection;
  7746   7751     for(i=k=0; i<nOld; i++, k++){
  7747   7752       MemPage *p = apOld[i];
  7748   7753       b.apEnd[k] = p->aDataEnd;
  7749   7754       b.ixNx[k] = cntOld[i];
         7755  +    if( k && b.ixNx[k]==b.ixNx[k-1] ){
         7756  +      k--;  /* Omit b.ixNx[] entry for child pages with no cells */
         7757  +    }
  7750   7758       if( !leafData ){
  7751   7759         k++;
  7752   7760         b.apEnd[k] = pParent->aDataEnd;
  7753   7761         b.ixNx[k] = cntOld[i]+1;
  7754   7762       }
  7755   7763       assert( p->nFree>=0 );
  7756   7764       szNew[i] = usableSpace - p->nFree;
................................................................................
  7974   7982     ** associated with the right-child of each sibling may also need to be 
  7975   7983     ** updated. This happens below, after the sibling pages have been 
  7976   7984     ** populated, not here.
  7977   7985     */
  7978   7986     if( ISAUTOVACUUM ){
  7979   7987       MemPage *pOld;
  7980   7988       MemPage *pNew = pOld = apNew[0];
  7981         -    u8 *aOld = pNew->aData;
  7982   7989       int cntOldNext = pNew->nCell + pNew->nOverflow;
  7983         -    int usableSize = pBt->usableSize;
  7984   7990       int iNew = 0;
  7985   7991       int iOld = 0;
  7986   7992   
  7987   7993       for(i=0; i<b.nCell; i++){
  7988   7994         u8 *pCell = b.apCell[i];
  7989         -      if( i==cntOldNext ){
  7990         -        pOld = (++iOld)<nNew ? apNew[iOld] : apOld[iOld];
         7995  +      while( i==cntOldNext ){
         7996  +        iOld++;
         7997  +        assert( iOld<nNew || iOld<nOld );
         7998  +        pOld = iOld<nNew ? apNew[iOld] : apOld[iOld];
  7991   7999           cntOldNext += pOld->nCell + pOld->nOverflow + !leafData;
  7992         -        aOld = pOld->aData;
  7993   8000         }
  7994   8001         if( i==cntNew[iNew] ){
  7995   8002           pNew = apNew[++iNew];
  7996   8003           if( !leafData ) continue;
  7997   8004         }
  7998   8005   
  7999   8006         /* Cell pCell is destined for new sibling page pNew. Originally, it
................................................................................
  8000   8007         ** was either part of sibling page iOld (possibly an overflow cell), 
  8001   8008         ** or else the divider cell to the left of sibling page iOld. So,
  8002   8009         ** if sibling page iOld had the same page number as pNew, and if
  8003   8010         ** pCell really was a part of sibling page iOld (not a divider or
  8004   8011         ** overflow cell), we can skip updating the pointer map entries.  */
  8005   8012         if( iOld>=nNew
  8006   8013          || pNew->pgno!=aPgno[iOld]
  8007         -       || !SQLITE_WITHIN(pCell,aOld,&aOld[usableSize])
         8014  +       || !SQLITE_WITHIN(pCell,pOld->aData,pOld->aDataEnd)
  8008   8015         ){
  8009   8016           if( !leafCorrection ){
  8010   8017             ptrmapPut(pBt, get4byte(pCell), PTRMAP_BTREE, pNew->pgno, &rc);
  8011   8018           }
  8012   8019           if( cachedCellSize(&b,i)>pNew->minLocal ){
  8013   8020             ptrmapPutOvflPtr(pNew, pOld, pCell, &rc);
  8014   8021           }

Changes to test/fuzzdata8.db.

cannot compute difference between binary files