/ Check-in [79544fc2]
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

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

Overview
Comment:Remove sqlite3_log() and abort() calls added to this branch to debug the pointer-map problem ([fda22108]).
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | begin-concurrent
Files: files | file ages | folders
SHA3-256: 79544fc2856f30cac8b0962d00698974e8918562f09769a68264d17e1e1176fe
User & Date: dan 2017-06-10 17:23:20
Wiki:begin-concurrent
Context
2017-07-20
17:47
Merge all the latest trunk enhancements. check-in: 213c61cb user: drh tags: begin-concurrent
2017-06-10
17:23
Remove sqlite3_log() and abort() calls added to this branch to debug the pointer-map problem ([fda22108]). check-in: 79544fc2 user: dan tags: begin-concurrent
2017-06-08
16:23
Update the recent auto-vacuum fix so that it works for the in-memory pointer-map structure used by this branch. check-in: 8e311a6d user: dan tags: begin-concurrent
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/btree.c.

625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
....
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
....
8713
8714
8715
8716
8717
8718
8719
8720
8721
8722
8723
8724
8725
8726
8727
....
8809
8810
8811
8812
8813
8814
8815
8816
8817
8818
8819
8820
8821
8822
8823
8824
8825
8826
8827
8828
8829
8830
8831
8832
8833
8834
8835
....
8847
8848
8849
8850
8851
8852
8853
8854
8855
8856
8857
8858
8859
8860
8861
8862
....
8872
8873
8874
8875
8876
8877
8878
8879
8880
8881
8882
8883
8884
8885
8886
8887
    sqlite3_free(pMap->aRollback);
    sqlite3_free(pMap->aPtr);
    sqlite3_free(pMap->aSvpt);
    sqlite3_free(pMap);
    pBt->pMap = 0;
  }
}

static void btreeCheckPtrmap(BtShared *p, int nPage, const char *zLog){
  BtreePtrmap *pMap = p->pMap;
  if( pMap ){
    int n = MIN(1 + nPage - (int)pMap->iFirst, 5);
    int i;
    for(i=0; i<n; i++){
      int eType = pMap->aPtr[i].eType;
      if( (eType==PTRMAP_OVERFLOW1 || 
            eType==PTRMAP_OVERFLOW2 || 
            eType==PTRMAP_BTREE) && pMap->aPtr[i].parent==0 
        ){
        sqlite3_log(SQLITE_ERROR, 
            "Bitvec: error at (%s) - (%d/%d %d/%d %d/%d %d/%d %d/%d)",
            zLog,
            (int)pMap->aPtr[0].eType, (int)pMap->aPtr[0].parent,
            (n>1 ? (int)pMap->aPtr[1].eType : -1),
            (n>1 ? (int)pMap->aPtr[1].parent : -1),

            (n>2 ? (int)pMap->aPtr[2].eType : -1),
            (n>2 ? (int)pMap->aPtr[2].parent : -1),

            (n>3 ? (int)pMap->aPtr[3].eType : -1),
            (n>3 ? (int)pMap->aPtr[3].parent : -1),

            (n>4 ? (int)pMap->aPtr[4].eType : -1),
            (n>4 ? (int)pMap->aPtr[4].parent : -1)
            );
        abort();
        break;
      }
    }
  }
}
#else  /* SQLITE_OMIT_CONCURRENT */
# define btreePtrmapAllocate(x) SQLITE_OK
# define btreePtrmapDelete(x) 
# define btreePtrmapBegin(x,y)  SQLITE_OK
# define btreePtrmapEnd(x,y,z) 
# define btreeCheckPtrmap(a,b,c)
#endif /* SQLITE_OMIT_CONCURRENT */

static void releasePage(MemPage *pPage);  /* Forward reference */

/*
***** This routine is used inside of assert() only ****
**
................................................................................
  ** or freed by this transaction. In this case no special handling is 
  ** required. Otherwise, if page 1 is dirty, proceed.  */
  BtreePtrmap *pMap = pBt->pMap;
  Pgno iTrunk = get4byte(&p1[32]);
  Pgno nPage = btreePagecount(pBt);
  u32 nFree = get4byte(&p1[36]);

  btreeCheckPtrmap(pBt, nPage, "btreeFixUnlocked(1)");

  assert( pBt->pMap );
  rc = sqlite3PagerUpgradeSnapshot(pPager, pPage1->pDbPage);
  assert( p1==pPage1->aData );

  if( rc==SQLITE_OK ){
    Pgno nHPage = get4byte(&p1[28]);
    Pgno nFin = nHPage;         /* Size of db after transaction merge */
................................................................................
      pCur->eState = CURSOR_REQUIRESEEK;
      pCur->nKey = pX->nKey;
    }
  }
  assert( pCur->apPage[pCur->iPage]->nOverflow==0 );

end_insert:
  btreeCheckPtrmap(pBt, pBt->nPage, "sqlite3BtreeInsert()");
  return rc;
}

/*
** Delete the entry that the cursor is pointing to. 
**
** If the BTREE_SAVEPOSITION bit of the flags parameter is zero, then
................................................................................

  /* If this is a delete operation to remove a row from a table b-tree,
  ** invalidate any incrblob cursors open on the row being deleted.  */
  if( pCur->pKeyInfo==0 ){
    invalidateIncrblobCursors(p, pCur->pgnoRoot, pCur->info.nKey, 0);
  }

  btreeCheckPtrmap(pBt, pBt->nPage, "sqlite3BtreeDelete(0)");

  /* Make the page containing the entry to be deleted writable. Then free any
  ** overflow pages associated with the entry and finally remove the cell
  ** itself from within the page.  */
  rc = sqlite3PagerWrite(pPage->pDbPage);
  if( rc ) return rc;
  rc = clearCell(pPage, pCell, &info);
  dropCell(pPage, iCellIdx, info.nSize, &rc);
  if( rc ) return rc;

  btreeCheckPtrmap(pBt, pBt->nPage, "sqlite3BtreeDelete(1)");

  /* If the cell deleted was not located on a leaf page, then the cursor
  ** is currently pointing to the largest entry in the sub-tree headed
  ** by the child-page of the cell that was just deleted from an internal
  ** node. The cell from the leaf node needs to be moved to the internal
  ** node to replace the deleted cell.  */
  if( !pPage->leaf ){
    MemPage *pLeaf = pCur->apPage[pCur->iPage];
................................................................................
    if( rc==SQLITE_OK ){
      insertCell(pPage, iCellIdx, pCell-4, nCell+4, pTmp, n, &rc);
    }
    dropCell(pLeaf, pLeaf->nCell-1, nCell, &rc);
    if( rc ) return rc;
  }

  btreeCheckPtrmap(pBt, pBt->nPage, "sqlite3BtreeDelete(2)");

  /* Balance the tree. If the entry deleted was located on a leaf page,
  ** then the cursor still points to that page. In this case the first
  ** call to balance() repairs the tree, and the if(...) condition is
  ** never true.
  **
  ** Otherwise, if the entry deleted was on an internal node page, then
  ** pCur is pointing to the leaf page from which a cell was removed to
................................................................................
  if( rc==SQLITE_OK && pCur->iPage>iCellDepth ){
    while( pCur->iPage>iCellDepth ){
      releasePage(pCur->apPage[pCur->iPage--]);
    }
    rc = balance(pCur);
  }

  btreeCheckPtrmap(pBt, pBt->nPage, "sqlite3BtreeDelete(3)");

  if( rc==SQLITE_OK ){
    if( bSkipnext ){
      assert( bPreserve && (pCur->iPage==iCellDepth || CORRUPT_DB) );
      assert( pPage==pCur->apPage[pCur->iPage] || CORRUPT_DB );
      assert( (pPage->nCell>0 || CORRUPT_DB) && iCellIdx<=pPage->nCell );
      pCur->eState = CURSOR_SKIPNEXT;
      if( iCellIdx>=pPage->nCell ){







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<





<







 







<
<







 







<







 







<
<









<
<







 







<
<







 







<
<







625
626
627
628
629
630
631


































632
633
634
635
636

637
638
639
640
641
642
643
....
4084
4085
4086
4087
4088
4089
4090


4091
4092
4093
4094
4095
4096
4097
....
8676
8677
8678
8679
8680
8681
8682

8683
8684
8685
8686
8687
8688
8689
....
8771
8772
8773
8774
8775
8776
8777


8778
8779
8780
8781
8782
8783
8784
8785
8786


8787
8788
8789
8790
8791
8792
8793
....
8805
8806
8807
8808
8809
8810
8811


8812
8813
8814
8815
8816
8817
8818
....
8828
8829
8830
8831
8832
8833
8834


8835
8836
8837
8838
8839
8840
8841
    sqlite3_free(pMap->aRollback);
    sqlite3_free(pMap->aPtr);
    sqlite3_free(pMap->aSvpt);
    sqlite3_free(pMap);
    pBt->pMap = 0;
  }
}


































#else  /* SQLITE_OMIT_CONCURRENT */
# define btreePtrmapAllocate(x) SQLITE_OK
# define btreePtrmapDelete(x) 
# define btreePtrmapBegin(x,y)  SQLITE_OK
# define btreePtrmapEnd(x,y,z) 

#endif /* SQLITE_OMIT_CONCURRENT */

static void releasePage(MemPage *pPage);  /* Forward reference */

/*
***** This routine is used inside of assert() only ****
**
................................................................................
  ** or freed by this transaction. In this case no special handling is 
  ** required. Otherwise, if page 1 is dirty, proceed.  */
  BtreePtrmap *pMap = pBt->pMap;
  Pgno iTrunk = get4byte(&p1[32]);
  Pgno nPage = btreePagecount(pBt);
  u32 nFree = get4byte(&p1[36]);



  assert( pBt->pMap );
  rc = sqlite3PagerUpgradeSnapshot(pPager, pPage1->pDbPage);
  assert( p1==pPage1->aData );

  if( rc==SQLITE_OK ){
    Pgno nHPage = get4byte(&p1[28]);
    Pgno nFin = nHPage;         /* Size of db after transaction merge */
................................................................................
      pCur->eState = CURSOR_REQUIRESEEK;
      pCur->nKey = pX->nKey;
    }
  }
  assert( pCur->apPage[pCur->iPage]->nOverflow==0 );

end_insert:

  return rc;
}

/*
** Delete the entry that the cursor is pointing to. 
**
** If the BTREE_SAVEPOSITION bit of the flags parameter is zero, then
................................................................................

  /* If this is a delete operation to remove a row from a table b-tree,
  ** invalidate any incrblob cursors open on the row being deleted.  */
  if( pCur->pKeyInfo==0 ){
    invalidateIncrblobCursors(p, pCur->pgnoRoot, pCur->info.nKey, 0);
  }



  /* Make the page containing the entry to be deleted writable. Then free any
  ** overflow pages associated with the entry and finally remove the cell
  ** itself from within the page.  */
  rc = sqlite3PagerWrite(pPage->pDbPage);
  if( rc ) return rc;
  rc = clearCell(pPage, pCell, &info);
  dropCell(pPage, iCellIdx, info.nSize, &rc);
  if( rc ) return rc;



  /* If the cell deleted was not located on a leaf page, then the cursor
  ** is currently pointing to the largest entry in the sub-tree headed
  ** by the child-page of the cell that was just deleted from an internal
  ** node. The cell from the leaf node needs to be moved to the internal
  ** node to replace the deleted cell.  */
  if( !pPage->leaf ){
    MemPage *pLeaf = pCur->apPage[pCur->iPage];
................................................................................
    if( rc==SQLITE_OK ){
      insertCell(pPage, iCellIdx, pCell-4, nCell+4, pTmp, n, &rc);
    }
    dropCell(pLeaf, pLeaf->nCell-1, nCell, &rc);
    if( rc ) return rc;
  }



  /* Balance the tree. If the entry deleted was located on a leaf page,
  ** then the cursor still points to that page. In this case the first
  ** call to balance() repairs the tree, and the if(...) condition is
  ** never true.
  **
  ** Otherwise, if the entry deleted was on an internal node page, then
  ** pCur is pointing to the leaf page from which a cell was removed to
................................................................................
  if( rc==SQLITE_OK && pCur->iPage>iCellDepth ){
    while( pCur->iPage>iCellDepth ){
      releasePage(pCur->apPage[pCur->iPage--]);
    }
    rc = balance(pCur);
  }



  if( rc==SQLITE_OK ){
    if( bSkipnext ){
      assert( bPreserve && (pCur->iPage==iCellDepth || CORRUPT_DB) );
      assert( pPage==pCur->apPage[pCur->iPage] || CORRUPT_DB );
      assert( (pPage->nCell>0 || CORRUPT_DB) && iCellIdx<=pPage->nCell );
      pCur->eState = CURSOR_SKIPNEXT;
      if( iCellIdx>=pPage->nCell ){