-C Fix\sa\sbug\sin\spager.c\sintroduced\sin\sthe\sprevious\sdelta.\s(CVS\s227)
-D 2001-06-23T11:36:20
+C The\sfirst\stest\sfile\sfor\sBTree\sadded.\sSimple\sinsert\sand\sdelete\stests\spass.\nThere\sis\sstill\sa\slot\sof\swork\sto\sbe\sdone,\sthough.\s(CVS\s228)
+D 2001-06-24T20:39:41
F COPYRIGHT 74a8a6531a42e124df07ab5599aad63870fa0bd4
F Makefile.in 65862a30703b070209b5f5e565d75cc870962b3c
F README 51f6a4e7408b34afa5bc1c0485f61b6a4efb6958
F notes/notes2.txt 7e3fafd5e25906c1fe1e95f13b089aa398ca403e
F notes/notes3.txt 985bf688b59f1f52bfe6e4b1f896efdeffac1432
F src/TODO 38a68a489e56e9fd4a96263e0ff9404a47368ad4
-F src/btree.c 0a2b66ce90f0bee87f0449235060529b96cc96e4
+F src/btree.c e46ab610d0bef3d1a9f698bede21d554c42763e5
F src/btree.h 40ae2c9b6d2ba8feb03461a589ccab9afc04ec29
F src/build.c 4f6a2d551c56342cd4a0420654835be3ad179651
F src/dbbe.c b18259f99d87240cbe751021cf14dd3aa83a48af
F src/expr.c c4c24c3af1eba094a816522eb0e085bed518ee16
F src/insert.c aa528e20a787af85432a61daaea6df394bd251d7
F src/main.c 0a13c7a2beb8ce36aee43daf8c95989b200727a7
-F src/pager.c d5cb53ac679d039d40661e50200a8dde6406ca15
+F src/pager.c 866d4d9a736943c9a904d291bc9b66dc4a7f23de
F src/pager.h 724ac5a79b5fa704a1e1a87e421e421b3da9c1e4
F src/parse.y 8fc096948994a7ffbf61ba13129cc589f794a9cb
F src/printf.c b1e22a47be8cdf707815647239991e08e8cb69f9
F src/vdbe.h dc1205da434c6a9da03b5d6b089270bbc8e6d437
F src/where.c 0c542fc44bd85152dfb8507862cfe2e60c629e9f
F test/all.test 21d55a97e39e7ec5776751dc9dd8b1b51ef4a048
+F test/btree.test 8db61fdd957e906d7d237bf0f578f3e8cc9fb33e
F test/copy.test b77a1214bd7756f2849d5c4fa6e715c0ff0c34eb
F test/dbbe.test a022fe2d983848f786e17ef1fc6809cfd37fb02c
F test/delete.test 50b9b1f06c843d591741dba7869433a105360dbf
F test/lock.test bca7d53de73138b1f670a2fbdb1f481ff7eaa45a
F test/main.test da635f9e078cd21ddf074e727381a715064489ff
F test/malloc.test 3daa97f6a9577d8f4c6e468b274333af19ce5861
-F test/pager.test 475835b84cbec423a7dd3d0492b2c8701435d375
+F test/pager.test aa902a867ce6b925214d28e17400001946e0e5a4
F test/printf.test 4c71871e1a75a2dacb673945fc13ddb30168798f
F test/rowid.test 128453599def7435e988216f7fe89c7450b8a9a3
F test/select1.test 223507655cdb4f9901d83fa7f5c5328e022c211f
F www/sqlite.tcl cb0d23d8f061a80543928755ec7775da6e4f362f
F www/tclsqlite.tcl 06f81c401f79a04f2c5ebfb97e7c176225c0aef2
F www/vdbe.tcl 0c8aaa529dd216ccbf7daaabd80985e413d5f9ad
-P b31c49021c260a67b7848bc077b75a7146e31c71
-R e52ea2ba0d86c859453a43591ceb35fc
+P f4df6664037c68e1ce539c84c852124d95cd5a56
+R 3068b07f88f8e6db3749d5669bb8ecc6
U drh
-Z 86cec7512c643b5b976845158db125a4
+Z ee5edd13b8c55ec829c3087fe59854aa
-f4df6664037c68e1ce539c84c852124d95cd5a56
\ No newline at end of file
+85f015c9750a5eab274e82f0e2c6e8f09dc7ca70
\ No newline at end of file
** http://www.hwaci.com/drh/
**
*************************************************************************
-** $Id: btree.c,v 1.13 2001/06/22 19:15:00 drh Exp $
+** $Id: btree.c,v 1.14 2001/06/24 20:39:41 drh Exp $
**
** This file implements a external (disk-based) database using BTrees.
** For a detailed discussion of BTrees, refer to
** This macro casts a pointer to an integer. Useful for doing
** pointer arithmetic.
*/
-#define addr(X) ((uptr)X)
+#define Addr(X) ((uptr)X)
/*
** Forward declarations of structures used only in this file.
/* This routine should never be called on an overfull page. The
** following asserts verify that constraint. */
- assert( addr(pCell) > addr(pPage) );
- assert( addr(pCell) < addr(pPage) + SQLITE_PAGE_SIZE );
+ assert( Addr(pCell) > Addr(pPage) );
+ assert( Addr(pCell) < Addr(pPage) + SQLITE_PAGE_SIZE );
n = cellSize(pCell);
pCell->h.iNext = i<pPage->nCell-1 ? pc + n : 0;
if( idx<sizeof(PageHdr) ) goto page_format_error;
pFBlk = (FreeBlk*)&pPage->u.aDisk[idx];
pPage->nFree += pFBlk->iSize;
- if( pFBlk->iNext <= idx ) goto page_format_error;
+ if( pFBlk->iNext>0 && pFBlk->iNext <= idx ) goto page_format_error;
idx = pFBlk->iNext;
}
if( pPage->nCell==0 && pPage->nFree==0 ){
MemPage *pRoot;
PageOne *pP1;
int rc;
- if( sqlitepager_pagecount(pBt->pPager)>0 ) return SQLITE_OK;
+ if( sqlitepager_pagecount(pBt->pPager)>1 ) return SQLITE_OK;
pP1 = pBt->page1;
rc = sqlitepager_write(pBt->page1);
if( rc ) return rc;
** remove the read lock.
*/
static void unlockBtree(Btree *pBt){
- if( pBt->pCursor==0 && pBt->page1!=0 ){
+ if( pBt->inTrans==0 && pBt->pCursor==0 && pBt->page1!=0 ){
sqlitepager_unref(pBt->page1);
pBt->page1 = 0;
pBt->inTrans = 0;
*/
int sqliteBtreeCommit(Btree *pBt){
int rc;
- if( pBt->pCursor!=0 ) return SQLITE_ERROR;
+ if( pBt->pCursor!=0 || pBt->inTrans==0 ) return SQLITE_ERROR;
rc = sqlitepager_commit(pBt->pPager);
+ pBt->inTrans = 0;
unlockBtree(pBt);
return rc;
}
int sqliteBtreeRollback(Btree *pBt){
int rc;
if( pBt->pCursor!=0 ) return SQLITE_ERROR;
+ if( pBt->inTrans==0 ) return SQLITE_OK;
+ pBt->inTrans = 0;
rc = sqlitepager_rollback(pBt->pPager);
unlockBtree(pBt);
return rc;
** this value is as follows:
**
** *pRes<0 The cursor is left pointing at an entry that
-** is larger than pKey.
+** is smaller than pKey.
**
** *pRes==0 The cursor is left pointing at an entry that
** exactly matches pKey.
**
** *pRes>0 The cursor is left pointing at an entry that
-** is smaller than pKey.
+** is larger than pKey.
*/
int sqliteBtreeMoveto(BtCursor *pCur, void *pKey, int nKey, int *pRes){
int rc;
+ pCur->bSkipNext = 0;
rc = moveToRoot(pCur);
if( rc ) return rc;
for(;;){
int j;
assert( idx>=0 && idx<pPage->nCell );
assert( sz==cellSize(pPage->apCell[idx]) );
- freeSpace(pPage, idx, sz);
- for(j=idx; j<pPage->nCell-2; j++){
+ freeSpace(pPage, Addr(pPage->apCell[idx]) - Addr(pPage), sz);
+ for(j=idx; j<pPage->nCell-1; j++){
pPage->apCell[j] = pPage->apCell[j+1];
}
pPage->nCell--;
u16 *pIdx;
pIdx = &pPage->u.hdr.firstCell;
for(i=0; i<pPage->nCell; i++){
- int idx = addr(pPage->apCell[i]) - addr(pPage);
+ int idx = Addr(pPage->apCell[i]) - Addr(pPage);
assert( idx>0 && idx<SQLITE_PAGE_SIZE );
*pIdx = idx;
pIdx = &pPage->apCell[i]->h.iNext;
pTo->nCell = pFrom->nCell;
pTo->nFree = pFrom->nFree;
pTo->isOverfull = pFrom->isOverfull;
- to = addr(pTo);
- from = addr(pFrom);
+ to = Addr(pTo);
+ from = Addr(pFrom);
for(i=0; i<pTo->nCell; i++){
- uptr x = addr(pFrom->apCell[i]);
+ uptr x = Addr(pFrom->apCell[i]);
if( x>from && x<from+SQLITE_PAGE_SIZE ){
*((uptr*)&pTo->apCell[i]) = x + to - from;
}
rc = clearCell(pBt, pPage->apCell[pCur->idx]);
if( rc ) return rc;
dropCell(pPage, pCur->idx, cellSize(pPage->apCell[pCur->idx]));
- }else if( loc>0 ){
+ }else if( loc<0 && pPage->nCell>0 ){
assert( pPage->u.hdr.rightChild==0 ); /* Must be a leaf page */
pCur->idx++;
}else{
assert( pPage->u.hdr.rightChild==0 ); /* Must be a leaf page */
}
- insertCell(pPage, pCur->idx, &newCell, cellSize(&newCell));
+ insertCell(pPage, pCur->idx, &newCell, szNew);
rc = balance(pCur->pBt, pPage, pCur);
return rc;
}
i, range, (int)pCell->h.leftChild, pCell->h.nKey, pCell->h.nData,
pCell->aPayload
);
+ i++;
idx = pCell->h.iNext;
}
if( idx!=0 ){
** all writes in order to support rollback. Locking is used to limit
** access to one or more reader or one writer.
**
-** @(#) $Id: pager.c,v 1.10 2001/06/23 11:36:20 drh Exp $
+** @(#) $Id: pager.c,v 1.11 2001/06/24 20:39:41 drh Exp $
*/
#include "sqliteInt.h"
#include "pager.h"
pPager->errMask = 0;
pPager->pFirst = 0;
pPager->pLast = 0;
+ pPager->nExtra = nExtra;
memset(pPager->aHash, 0, sizeof(pPager->aHash));
*ppPager = pPager;
return SQLITE_OK;
--- /dev/null
+# Copyright (c) 1999, 2000 D. Richard Hipp
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public
+# License along with this library; if not, write to the
+# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+#
+# Author contact information:
+# drh@hwaci.com
+# http://www.hwaci.com/drh/
+#
+#***********************************************************************
+# This file implements regression tests for SQLite library. The
+# focus of this script is btree database backend
+#
+# $Id: btree.test,v 1.1 2001/06/24 20:39:41 drh Exp $
+
+
+set testdir [file dirname $argv0]
+source $testdir/tester.tcl
+
+if {$dbprefix!="memory:" && [info commands btree_open]!=""} {
+
+# Basic functionality. Open and close a database.
+#
+do_test btree-1.1 {
+ file delete -force test1.bt
+ file delete -force test1.bt-journal
+ set rc [catch {btree_open test1.bt} ::b1]
+} {0}
+do_test btree-1.2 {
+ set rc [catch {btree_open test1.bt} ::b2]
+} {0}
+do_test btree-1.3 {
+ set rc [catch {btree_close $::b2} msg]
+ lappend rc $msg
+} {0 {}}
+
+# Do an insert and verify that the database file grows in size.
+#
+do_test btree-1.4 {
+ set rc [catch {btree_begin_transaction $::b1} msg]
+ lappend rc $msg
+} {0 {}}
+do_test btree-1.5 {
+ set rc [catch {btree_cursor $::b1 2} ::c1]
+ if {$rc} {lappend rc $::c1}
+ set rc
+} {0}
+do_test btree-1.6 {
+ set rc [catch {btree_insert $::c1 one 1.00} msg]
+ lappend rc $msg
+} {0 {}}
+do_test btree-1.7 {
+ btree_key $::c1
+} {one}
+do_test btree-1.8 {
+ btree_data $::c1
+} {1.00}
+do_test btree-1.9 {
+ set rc [catch {btree_close_cursor $::c1} msg]
+ lappend rc $msg
+} {0 {}}
+do_test btree-1.10 {
+ set rc [catch {btree_commit $::b1} msg]
+ lappend rc $msg
+} {0 {}}
+do_test btree-1.11 {
+ file size test1.bt
+} {2048}
+
+# Reopen the database and attempt to read the record that we wrote.
+#
+do_test btree-2.1 {
+ set rc [catch {btree_cursor $::b1 2} ::c1]
+ if {$rc} {lappend rc $::c1}
+ set rc
+} {0}
+do_test btree-2.2 {
+ btree_move_to $::c1 abc
+} {1}
+do_test btree-2.3 {
+ btree_move_to $::c1 xyz
+} {-1}
+do_test btree-2.4 {
+ btree_move_to $::c1 one
+} {0}
+do_test btree-2.5 {
+ btree_key $::c1
+} {one}
+do_test btree-2.6 {
+ btree_data $::c1
+} {1.00}
+
+# Do some additional inserts
+#
+do_test btree-3.1 {
+ btree_begin_transaction $::b1
+ btree_insert $::c1 two 2.00
+ btree_key $::c1
+} {two}
+do_test btree-3.2 {
+ btree_insert $::c1 three 3.00
+ btree_key $::c1
+} {three}
+do_test btree-3.4 {
+ btree_insert $::c1 four 4.00
+ btree_key $::c1
+} {four}
+do_test btree-3.5 {
+ btree_insert $::c1 five 5.00
+ btree_key $::c1
+} {five}
+do_test btree-3.6 {
+ btree_insert $::c1 six 6.00
+ btree_key $::c1
+} {six}
+#btree_page_dump $::b1 2
+do_test btree-3.7 {
+ set rc [btree_move_to $::c1 {}]
+ expr {$rc>0}
+} {1}
+do_test btree-3.8 {
+ btree_key $::c1
+} {five}
+do_test btree-3.9 {
+ btree_data $::c1
+} {5.00}
+do_test btree-3.10 {
+ btree_next $::c1
+ btree_key $::c1
+} {four}
+do_test btree-3.11 {
+ btree_data $::c1
+} {4.00}
+do_test btree-3.12 {
+ btree_next $::c1
+ btree_key $::c1
+} {one}
+do_test btree-3.13 {
+ btree_data $::c1
+} {1.00}
+do_test btree-3.14 {
+ btree_next $::c1
+ btree_key $::c1
+} {six}
+do_test btree-3.15 {
+ btree_data $::c1
+} {6.00}
+do_test btree-3.16 {
+ btree_next $::c1
+ btree_key $::c1
+} {three}
+do_test btree-3.17 {
+ btree_data $::c1
+} {3.00}
+do_test btree-3.18 {
+ btree_next $::c1
+ btree_key $::c1
+} {two}
+do_test btree-3.19 {
+ btree_data $::c1
+} {2.00}
+do_test btree-3.20 {
+ btree_next $::c1
+ btree_key $::c1
+} {}
+do_test btree-3.21 {
+ btree_data $::c1
+} {}
+
+# Commit the changes, reopen and reread the data
+#
+do_test btree-3.22 {
+ set rc [catch {btree_close_cursor $::c1} msg]
+ lappend rc $msg
+} {0 {}}
+do_test btree-3.23 {
+ set rc [catch {btree_commit $::b1} msg]
+ lappend rc $msg
+} {0 {}}
+do_test btree-3.24 {
+ file size test1.bt
+} {2048}
+do_test btree-3.25 {
+ set rc [catch {btree_cursor $::b1 2} ::c1]
+ if {$rc} {lappend rc $::c1}
+ set rc
+} {0}
+do_test btree-3.26 {
+ set rc [btree_move_to $::c1 {}]
+ expr {$rc>0}
+} {1}
+do_test btree-3.27 {
+ btree_key $::c1
+} {five}
+do_test btree-3.28 {
+ btree_data $::c1
+} {5.00}
+do_test btree-3.29 {
+ btree_next $::c1
+ btree_key $::c1
+} {four}
+do_test btree-3.30 {
+ btree_data $::c1
+} {4.00}
+do_test btree-3.31 {
+ btree_next $::c1
+ btree_key $::c1
+} {one}
+do_test btree-3.32 {
+ btree_data $::c1
+} {1.00}
+do_test btree-3.33 {
+ btree_next $::c1
+ btree_key $::c1
+} {six}
+do_test btree-3.34 {
+ btree_data $::c1
+} {6.00}
+do_test btree-3.35 {
+ btree_next $::c1
+ btree_key $::c1
+} {three}
+do_test btree-3.36 {
+ btree_data $::c1
+} {3.00}
+do_test btree-3.37 {
+ btree_next $::c1
+ btree_key $::c1
+} {two}
+do_test btree-3.38 {
+ btree_data $::c1
+} {2.00}
+do_test btree-3.39 {
+ btree_next $::c1
+ btree_key $::c1
+} {}
+do_test btree-3.40 {
+ btree_data $::c1
+} {}
+
+# Now try a delete
+#
+do_test btree-4.1 {
+ btree_begin_transaction $::b1
+ btree_move_to $::c1 one
+ btree_key $::c1
+} {one}
+do_test btree-4.2 {
+ btree_delete $::c1
+} {}
+do_test btree-4.3 {
+ btree_key $::c1
+} {six}
+do_test btree-4.4 {
+ btree_next $::c1
+ btree_key $::c1
+} {six}
+do_test btree-4.5 {
+ btree_next $::c1
+ btree_key $::c1
+} {three}
+do_test btree-4.4 {
+ btree_move_to $::c1 {}
+ set r {}
+ while 1 {
+ set key [btree_key $::c1]
+ if {$key==""} break
+ lappend r $key
+ lappend r [btree_data $::c1]
+ btree_next $::c1
+ }
+ set r
+} {five 5.00 four 4.00 six 6.00 three 3.00 two 2.00}
+
+# Commit and make sure the delete is still there.
+#
+do_test btree-4.5 {
+ btree_close_cursor $::c1
+ btree_commit $::b1
+ set ::c1 [btree_cursor $::b1 2]
+ btree_move_to $::c1 {}
+ set r {}
+ while 1 {
+ set key [btree_key $::c1]
+ if {$key==""} break
+ lappend r $key
+ lappend r [btree_data $::c1]
+ btree_next $::c1
+ }
+ set r
+} {five 5.00 four 4.00 six 6.00 three 3.00 two 2.00}
+
+
+
+
+do_test btree-99.1 {
+ btree_close $::b1
+} {}
+
+
+} ;# end if( not mem: and has pager_open command );
+
+finish_test
# This file implements regression tests for SQLite library. The
# focus of this script is page cache subsystem.
#
-# $Id: pager.test,v 1.5 2001/05/24 21:06:36 drh Exp $
+# $Id: pager.test,v 1.6 2001/06/24 20:39:41 drh Exp $
set testdir [file dirname $argv0]
source $testdir/tester.tcl
-if {$dbprefix!="mem:" && [info commands pager_open]!=""} {
+if {$dbprefix!="memory:" && [info commands pager_open]!=""} {
# Basic sanity check. Open and close a pager.
#