]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Sync all version 3 changes. (CVS 1309)
authordrh <drh@noemail.net>
Thu, 29 Apr 2004 14:42:46 +0000 (14:42 +0000)
committerdrh <drh@noemail.net>
Thu, 29 Apr 2004 14:42:46 +0000 (14:42 +0000)
FossilOrigin-Name: 51892d6cdc739bb049fdfce8301354312167c181

manifest
manifest.uuid
src/btree.c

index 56938aa9e933bd96a1e19c7f81a6f90d0d0ac3fe..9c8246f93ccad96b3099cc6e6bc1e3071b770a6a 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Pager\stests\sworking.\s(CVS\s1308)
-D 2004-04-26T14:10:21
+C Sync\sall\sversion\s3\schanges.\s(CVS\s1309)
+D 2004-04-29T14:42:46
 F Makefile.in ab7b0d5118e2da97bac66be8684a1034e3500f5a
 F Makefile.linux-gcc b86a99c493a5bfb402d1d9178dcdc4bd4b32f906
 F README f1de682fbbd94899d50aca13d387d1b3fd3be2dd
@@ -23,7 +23,7 @@ F sqlite.def fc4f5734786fe4743cfe2aa98eb2da4b089edb5f
 F sqlite.pc.in 30552343140c53304c2a658c080fbe810cd09ca2
 F src/attach.c b01db0d3211f673d8e670abf7eaad04591d40d14
 F src/auth.c 4fa3b05bd19445d1c474d6751c4a508d6ea0abe1
-F src/btree.c 4e2b50ae03bd4d9e678bda14b08307d80dd4471c
+F src/btree.c 09272a46501fb5e60474c0b5c1e32c825086067f
 F src/btree.h 858659c6605ae07a2a0fb3d176b25573d30f27c5
 F src/btree_rb.c 99feb3ff835106d018a483a1ce403e5cf9c718bc
 F src/build.c 76fbca30081decd6615dee34b48c927ed5063752
@@ -188,7 +188,7 @@ F www/sqlite.tcl 3c83b08cf9f18aa2d69453ff441a36c40e431604
 F www/tclsqlite.tcl b9271d44dcf147a93c98f8ecf28c927307abd6da
 F www/vdbe.tcl 9b9095d4495f37697fd1935d10e14c6015e80aa1
 F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4
-P ce0bbd3a7159e12c86c5cde6571d6668b234827b
-R e6250126bdd2ced9348d9f2d5069495a
+P 910067a200c4b25b5d813a84146673d3d1c80952
+R 9774fd5f44f9196be5f8b828df0f1a01
 U drh
-Z 07ad078caa4fedefbf47bb778c51fa1e
+Z 1f01b8b1967a026f92cc6d5ed5f03774
index 067e908d3863226ed89f12ca2936837d9c4b941c..27ead59fc4b3305647f72bf589964ea298b73f18 100644 (file)
@@ -1 +1 @@
-910067a200c4b25b5d813a84146673d3d1c80952
\ No newline at end of file
+51892d6cdc739bb049fdfce8301354312167c181
\ No newline at end of file
index abccfb851b23bc73ac5e71bf78444a198ea30a88..bd846f95e65f000957a5e1f6d3e73a068c37dbfb 100644 (file)
@@ -9,7 +9,7 @@
 **    May you share freely, never taking more than you give.
 **
 *************************************************************************
-** $Id: btree.c,v 1.105 2004/04/26 14:10:21 drh Exp $
+** $Id: btree.c,v 1.106 2004/04/29 14:42:46 drh Exp $
 **
 ** This file implements a external (disk-based) database using BTrees.
 ** For a detailed discussion of BTrees, refer to
@@ -1519,6 +1519,22 @@ static int moveToChild(BtCursor *pCur, u32 newPgno){
   return SQLITE_OK;
 }
 
+/*
+** Return true if the page is the virtual root of its table.
+**
+** The virtual root page is the root page for most tables.  But
+** for the table rooted on page 1, sometime the real root page
+** is empty except for the right-pointer.  In such cases the
+** virtual root page is the page that the right-pointer of page
+** 1 is pointing to.
+*/
+static int isRootPage(MemPage *pPage){
+  MemPage *pParent = pPage->pParent;
+  assert( pParent==0 || pParent->isInit );
+  if( pParent || (pParent->pgno==1 && pParent->nCell==0) ) return 1;
+  return 0;
+}
+
 /*
 ** Move the cursor up to the parent page.
 **
@@ -1535,6 +1551,7 @@ static void moveToParent(BtCursor *pCur){
 
   pPage = pCur->pPage;
   assert( pPage!=0 );
+  assert( !isRootPage(pPage) );
   pParent = pPage->pParent;
   assert( pParent!=0 );
   idxParent = pPage->idxParent;
@@ -1580,14 +1597,21 @@ static int moveToRoot(BtCursor *pCur){
   int rc;
   Btree *pBt = pCur->pBt;
 
-  rc = sqlitepager_get(pBt->pPager, pCur->pgnoRoot, &pRoot);
+  rc = getPage(pBt, pCur->pgnoRoot, &pRoot);
   if( rc ) return rc;
   rc = initPage(pRoot, 0);
   if( rc ) return rc;
   releasePage(pCur->pPage);
   pCur->pPage = pRoot;
   pCur->idx = 0;
-  return SQLITE_OK;
+  if( pRoot->nCell==0 && !pRoot->leaf ){
+    Pgno subpage;
+    assert( pRoot->pgno==1 );
+    subpage = get4byte(&pRoot->aData[pRoot->hdrOffset+6]);
+    assert( subpage>0 );
+    rc = movetoChild(pCur, subpage);
+  }
+  return rc;
 }
 
 /*
@@ -1802,7 +1826,7 @@ int sqlite3BtreeNext(BtCursor *pCur, int *pRes){
       return rc;
     }
     do{
-      if( pPage->pParent==0 ){
+      if( isRootPage(pPage) ){
         *pRes = 1;
         return SQLITE_OK;
       }
@@ -1855,7 +1879,7 @@ int sqlite3BtreePrevious(BtCursor *pCur, int *pRes){
     rc = moveToRightmost(pCur);
   }else{
     while( pCur->idx==0 ){
-      if( pPage->pParent==0 ){
+      if( isRootPage(pPage) ){
         if( pRes ) *pRes = 1;
         return SQLITE_OK;
       }
@@ -2374,20 +2398,35 @@ static int balance(Btree *pBt, MemPage *pPage, BtCursor *pCur){
     MemPage *pChild;
     assert( pPage->isInit );
     if( pPage->nCell==0 ){
-      if( pPage->u.hdr.rightChild ){
-        /*
-        ** The root page is empty.  Copy the one child page
-        ** into the root page and return.  This reduces the depth
-        ** of the BTree by one.
+      if( pPage->leaf ){
+        /* The table is completely empty */
+        relinkCellList(pPage);
+      }else{
+        /* The root page is empty but has one child.  Transfer the
+        ** information from that one child into the root page if it 
+        ** will fit.  This reduces the depth of the BTree by one.
+        **
+        ** If the root page is page 1, it has less space available than
+        ** the child, so it might not be able to hold all of the information
+        ** in the child.  If this is the case, then do not do the transfer.
+        ** Leave page 1 empty except for the right-pointer to the child page.
+        ** The child page becomes the virtual root of the tree.
         */
-        pgnoChild = SWAB32(pBt, pPage->u.hdr.rightChild);
-        rc = sqlitepager_get(pBt->pPager, pgnoChild, (void**)&pChild);
+        pgnoChild = get4byte(pPage->aData[pPage->hdrOffset+6]);
+        assert( pgnoChild>0 && pgnoChild<=sqlit3pager_pagecount(pBt->pPager) );
+        rc = getPage(pBt, pgnoChild, &pChild);
         if( rc ) return rc;
-        memcpy(pPage, pChild, SQLITE_USABLE_SIZE);
-        pPage->isInit = 0;
-        rc = initPage(pBt, pPage, sqlitepager_pagenumber(pPage), 0);
-        assert( rc==SQLITE_OK );
-        reparentChildPages(pBt, pPage);
+        if( pPage->pgno==1 ){
+          rc = initPage(pChild);
+          if( rc ) return rc;
+          if( pChild->nFree>=100 ){
+          }
+        }else{
+          memcpy(pPage, pChild, SQLITE_USABLE_SIZE);
+          pPage->isInit = 0;
+          rc = initPage(pBt, pPage, sqlitepager_pagenumber(pPage), 0);
+          assert( rc==SQLITE_OK );
+          reparentChildPages(pBt, pPage);
         if( pCur && pCur->pPage==pChild ){
           sqlitepager_unref(pChild);
           pCur->pPage = pPage;