]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
The btree.c module compiles and links and passes some tests. Many tests
authordrh <drh@noemail.net>
Fri, 7 May 2004 17:57:49 +0000 (17:57 +0000)
committerdrh <drh@noemail.net>
Fri, 7 May 2004 17:57:49 +0000 (17:57 +0000)
still fail, though. (CVS 1321)

FossilOrigin-Name: d394b2b217d4d728f9eba397262bf9d36195719e

manifest
manifest.uuid
src/btree.c
src/pager.c
src/tclsqlite.c
src/test3.c
test/btree.test
test/tester.tcl

index d5c601dd84d1e2a39a136b55070e855e10a692aa..9f34ea149f0826cc3fb443c7a655464c1d0738bb 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C New\sbtree.c\smodule\scompiles\sand\slinks.\s(CVS\s1320)
-D 2004-05-07T13:30:42
+C The\sbtree.c\smodule\scompiles\sand\slinks\sand\spasses\ssome\stests.\s\sMany\stests\nstill\sfail,\sthough.\s(CVS\s1321)
+D 2004-05-07T17:57:50
 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 4c4ccf85d2852aa85c5d6ec7b34b047e363c0366
+F src/btree.c ff2f51fcd01c4fb9f2ce0f061a549e0c9aae9d74
 F src/btree.h 49b255b2880c50a3572a536ea935edb2dd33aae3
 F src/btree_rb.c 99feb3ff835106d018a483a1ce403e5cf9c718bc
 F src/build.c 76fbca30081decd6615dee34b48c927ed5063752
@@ -40,7 +40,7 @@ F src/main.c 94dd355768e2a389e184a069b6880f4bac100307
 F src/md5.c c53e7b50418afbde22d07128baf3cc615530e846
 F src/os.c 5f11382733805d4529ec2a30800e117f30995ea8
 F src/os.h 250a3789be609adfee5c5aa20137ce8683276f24
-F src/pager.c 2e3af839e7aab5bfaff7a0ef4694bae487b0ffeb
+F src/pager.c d18d56247c40bf4006ca7761c457b7d76af5c62a
 F src/pager.h 138ca7f73c47bebf469591939dcefa934cdf8d26
 F src/parse.y 023720cb8c3bef74e51738bca78335d0dc6d2cfd
 F src/pragma.c f9c157b0591419d2d3407dac90222020d2a6d822
@@ -51,10 +51,10 @@ F src/shell.c 920af040d3a33ea8919c82cee45b424ad841cee0
 F src/sqlite.h.in 35bec264dfb4965bbfeb7e75221f8658f210c30d
 F src/sqliteInt.h 44a17815ec6ffb93151723aa5cde7263162f52f3
 F src/table.c d845cb101b5afc1f7fea083c99e3d2fa7998d895
-F src/tclsqlite.c 3a5f8192ed5279a68610102a92a3a9f0cdd09e68
+F src/tclsqlite.c 9fe6fc0c20820e9411dfea407635de9b9d3ae0e3
 F src/test1.c 9aa62b89d420e6763b5e7ae89a47f6cf87370477
 F src/test2.c 9d611c45e1b07039a2bd95f5ea73178362b23229
-F src/test3.c 0b62d371f43bdb8fb1e3d5c4863743d6729f4e80
+F src/test3.c d6af4e26bdbb7512ab5d01e49f34e72415d58a3b
 F src/test4.c 6e3e31acfaf21d66420fc35fda5b17dc0000cc8d
 F src/test5.c 3ff0565057b8d23e20092d5c6c0b7cb0d932c51e
 F src/tokenize.c 6676b946fd8825b67ab52140af4fdc57a70bda48
@@ -75,7 +75,7 @@ F test/auth.test 5c4d95cdaf539c0c236e20ce1f71a93e7dde9185
 F test/bigfile.test ea904b853ce2d703b16c5ce90e2b54951bc1ae81
 F test/bigrow.test 8ab252dba108f12ad64e337b0f2ff31a807ac578
 F test/bind.test 56a57043b42c4664ca705f6050e56717a8a6699a
-F test/btree.test 677aeaac7b7b81980b446ca9cab15aa0cc5550d5
+F test/btree.test 77f93efac02dd05c7532b366b226bfe74757af57
 F test/btree2.test e3b81ec33dc2f89b3e6087436dfe605b870c9080
 F test/btree3.test e597fb59be2ac0ea69c62aaa2064e998e528b665
 F test/btree3rb.test 127efcf5cdfcc352054e7db12622b01cdd8b36ac
@@ -135,7 +135,7 @@ F test/table.test 371a1fc1c470982b2f68f9732f903a5d96f949c4
 F test/tableapi.test e0c4cce61e58343caa84dab33fa6823cb35fe1e1
 F test/tclsqlite.test a684fc191b81e6cded8a81263663d5a130fbb013
 F test/temptable.test a770ba6308d7f7332fce985086b8e06bed6430c2
-F test/tester.tcl 5b47e21f442fe8afae963bc45beb54795cf5d162
+F test/tester.tcl 64babe2528dec64125ddc8c1af763713710b59c3
 F test/thread1.test 53f050d5be6932d9430df7756edd379366508ff6
 F test/threadtest1.c f7f896e62ed46feae1dc411114a48c15a0f82ee2
 F test/threadtest2.c d94ca4114fd1504f7e0ae724bcd83d4b40931d86
@@ -190,7 +190,7 @@ F www/sqlite.tcl 3c83b08cf9f18aa2d69453ff441a36c40e431604
 F www/tclsqlite.tcl b9271d44dcf147a93c98f8ecf28c927307abd6da
 F www/vdbe.tcl 9b9095d4495f37697fd1935d10e14c6015e80aa1
 F www/whentouse.tcl a8335bce47cc2fddb07f19052cb0cb4d9129a8e4
-P 7fd1a660b0607b7c36de1278724521cbea72af0c
-R e634acb38b6d10c4d5783a02c4f65e26
+P dcd6b55f932a7ade4ad058534651e198b56370ad
+R cdb403059e0209ca0544e8ccaa4370da
 U drh
-Z a193f9bb2598a024f21bcc3c2eb519e6
+Z 48eb767d5af5b72432055086442dfd47
index deca48c73a65b881e035e213da30a6dca1984143..474a8b183d59fa2646abb55929081f8fe3694d7a 100644 (file)
@@ -1 +1 @@
-dcd6b55f932a7ade4ad058534651e198b56370ad
\ No newline at end of file
+d394b2b217d4d728f9eba397262bf9d36195719e
\ No newline at end of file
index 442ca6c81c5e8ffb53278f88a088530c32cb0d5b..52da31bb56868645bf9a4bf58c58819bf10f45d3 100644 (file)
@@ -9,7 +9,7 @@
 **    May you share freely, never taking more than you give.
 **
 *************************************************************************
-** $Id: btree.c,v 1.110 2004/05/07 13:30:42 drh Exp $
+** $Id: btree.c,v 1.111 2004/05/07 17:57:50 drh Exp $
 **
 ** This file implements a external (disk-based) database using BTrees.
 ** For a detailed discussion of BTrees, refer to
@@ -57,7 +57,7 @@
 ** of that header is as follows:
 **
 **   OFFSET   SIZE    DESCRIPTION
-**      0      16     Header string: "SQLite version 3"
+**      0      16     Header string: "SQLite format 3\000"
 **     16       2     Page size in bytes.  
 **     18       1     File format write version
 **     19       1     File format read version
@@ -187,16 +187,16 @@ typedef struct MemPage MemPage;
 /*
 ** This is a magic string that appears at the beginning of every
 ** SQLite database in order to identify the file as a real database.
-**                                  0123456789 123456 */
-static const char zMagicHeader[] = "SQLite version 3";
+**                                  123456789 123456 */
+static const char zMagicHeader[] = "SQLite format 3";
 
 /*
 ** Page type flags.  An ORed combination of these flags appear as the
 ** first byte of every BTree page.
 */
-#define PTF_LEAF      0x01
+#define PTF_INTKEY    0x01
 #define PTF_ZERODATA  0x02
-#define PTF_INTKEY    0x04
+#define PTF_LEAF      0x04
 /* Idea for the future:  PTF_LEAFDATA */
 
 /*
@@ -210,6 +210,7 @@ static const char zMagicHeader[] = "SQLite version 3";
 ** The pageDestructor() routine handles that chore.
 */
 struct MemPage {
+  u32 notUsed;
   struct Btree *pBt;             /* Pointer back to BTree structure */
   unsigned char *aData;          /* Pointer back to the start of the page */
   u8 isInit;                     /* True if previously initialized */
@@ -326,10 +327,10 @@ static unsigned int getVarint(unsigned char *p, u64 *pResult){
 static unsigned int putVarint(unsigned char *p, u64 v){
   int i = 0;
   do{
-    p[i++] = v & 0x7f;
+    p[i++] = (v & 0x7f) | 0x80;
     v >>= 7;
   }while( v!=0 );
-  p[i-1] |= 0x80;
+  p[i-1] &= 0x7f;
   return i;
 }
 
@@ -354,7 +355,7 @@ static void parseCellHeader(
   }else{
     n += getVarint(&pCell[n], pnData);
   }
-  n += getVarint(pCell, pnKey);
+  n += getVarint(&pCell[n], pnKey);
   *pnHeader = n;
 }
 
@@ -489,9 +490,10 @@ static int allocateSpace(MemPage *pPage, int nByte){
   assert( pc>0 && size>=nByte );
   assert( pc+size<=pPage->pBt->pageSize );
   if( size>nByte+4 ){
-    put2byte(&data[addr], pc+nByte);
-    put2byte(&data[pc+size], get2byte(&data[pc]));
-    put2byte(&data[pc+size+2], size-nByte);
+    int newStart = pc+nByte;
+    put2byte(&data[addr], newStart);
+    put2byte(&data[newStart], get2byte(&data[pc]));
+    put2byte(&data[newStart+2], size-nByte);
   }else{
     put2byte(&data[addr], get2byte(&data[pc]));
     data[hdr+5] += size-nByte;
@@ -691,7 +693,7 @@ static int initPage(
   assert( pPage->pBt!=0 );
   assert( pParent==0 || pParent->pBt==pPage->pBt );
   assert( pPage->pgno==sqlite3pager_pagenumber(pPage->aData) );
-  assert( pPage->aData == &((unsigned char*)pPage)[pPage->pBt->pageSize] );
+  assert( pPage->aData == &((unsigned char*)pPage)[-pPage->pBt->pageSize] );
   assert( pPage->isInit==0 || pPage->pParent==pParent );
   if( pPage->isInit ) return SQLITE_OK;
   assert( pPage->pParent==0 );
@@ -700,7 +702,8 @@ static int initPage(
     sqlite3pager_ref(pParent->aData);
   }
   pPage->nCell = pPage->nCellAlloc = 0;
-  pPage->hdrOffset = hdr = pPage->pgno==1 ? 100 : 0;
+  assert( pPage->hdrOffset==(pPage->pgno==1 ? 100 : 0) );
+  hdr = pPage->hdrOffset;
   data = pPage->aData;
   c = data[hdr];
   pPage->intKey = (c & PTF_INTKEY)!=0;
@@ -722,8 +725,8 @@ static int initPage(
   pc = get2byte(&data[hdr+3]);
   for(i=0; pc>0; i++){
     pPage->aCell[i] = &data[pc];
-    pc = get2byte(&data[pc]);
     sumCell += cellSize(pPage, &data[pc]);
+    pc = get2byte(&data[pc]);
   }
 
   /* Compute the total free space on the page */
@@ -746,6 +749,7 @@ static int initPage(
     return SQLITE_CORRUPT;
   }
 
+  pPage->isInit = 1;
   return SQLITE_OK;
 }
 
@@ -762,12 +766,13 @@ static void zeroPage(MemPage *pPage, int flags){
   assert( sqlite3pager_iswriteable(data) );
   memset(&data[hdr], 0, pBt->pageSize - hdr);
   data[hdr] = flags;
-  first = hdr + 6 + 4*((flags&0x01)!=0);
+  first = hdr + 6 + 4*((flags&PTF_LEAF)==0);
   put2byte(&data[hdr+1], first);
   put2byte(&data[first+2], pBt->pageSize - first);
   sqliteFree(pPage->aCell);
   pPage->aCell = 0;
   pPage->nCell = 0;
+  pPage->nCellAlloc = 0;
   pPage->nFree = pBt->pageSize - first;
   pPage->intKey = (flags & PTF_INTKEY)!=0;
   pPage->leaf = (flags & PTF_LEAF)!=0;
@@ -789,10 +794,30 @@ static int getPage(Btree *pBt, Pgno pgno, MemPage **ppPage){
   pPage->aData = aData;
   pPage->pBt = pBt;
   pPage->pgno = pgno;
+  pPage->hdrOffset = pPage->pgno==1 ? 100 : 0;
   *ppPage = pPage;
   return SQLITE_OK;
 }
 
+/*
+** Get a page from the pager and initialize it.  This routine
+** is just a convenience wrapper around separate calls to
+** getPage() and initPage().
+*/
+static int getAndInitPage(
+  Btree *pBt,          /* The database file */
+  Pgno pgno,           /* Number of the page to get */
+  MemPage **ppPage,    /* Write the page pointer here */
+  MemPage *pParent     /* Parent of the page */
+){
+  int rc;
+  rc = getPage(pBt, pgno, ppPage);
+  if( rc==SQLITE_OK ){
+    rc = initPage(*ppPage, pParent);
+  }
+  return rc;
+}
+
 /*
 ** Release a MemPage.  This should be called once for each prior
 ** call to getPage.
@@ -988,7 +1013,7 @@ static int newDatabase(Btree *pBt){
   MemPage *pP1;
   unsigned char *data;
   int rc;
-  if( sqlite3pager_pagecount(pBt->pPager)>1 ) return SQLITE_OK;
+  if( sqlite3pager_pagecount(pBt->pPager)>0 ) return SQLITE_OK;
   pP1 = pBt->pPage1;
   assert( pP1!=0 );
   data = pP1->aData;
@@ -1231,11 +1256,7 @@ int sqlite3BtreeCursor(
     goto create_cursor_exception;
   }
   pCur->pgnoRoot = (Pgno)iTable;
-  rc = getPage(pBt, pCur->pgnoRoot, &pCur->pPage);
-  if( rc!=SQLITE_OK ){
-    goto create_cursor_exception;
-  }
-  rc = initPage(pCur->pPage, 0);
+  rc = getAndInitPage(pBt, pCur->pgnoRoot, &pCur->pPage, 0);
   if( rc!=SQLITE_OK ){
     goto create_cursor_exception;
   }
@@ -1338,7 +1359,7 @@ int sqlite3BtreeKeySize(BtCursor *pCur, u64 *pSize){
   }else{
     unsigned char *cell = pPage->aCell[pCur->idx];
     cell += 2;   /* Skip the offset to the next cell */
-    if( pPage->leaf ){
+    if( !pPage->leaf ){
       cell += 4;  /* Skip the child pointer */
     }
     if( !pPage->zeroData ){
@@ -1378,7 +1399,7 @@ static int getPayload(
   assert( pCur->idx>=0 && pCur->idx<pPage->nCell );
   aPayload = pPage->aCell[pCur->idx];
   aPayload += 2;  /* Skip the next cell index */
-  if( pPage->leaf ){
+  if( !pPage->leaf ){
     aPayload += 4;  /* Skip the child pointer */
   }
   if( pPage->zeroData ){
@@ -1497,7 +1518,7 @@ void *sqlite3BtreeKeyFetch(BtCursor *pCur){
   assert( pCur->idx>=0 && pCur->idx<pPage->nCell );
   aPayload = pPage->aCell[pCur->idx];
   aPayload += 2;  /* Skip the next cell index */
-  if( pPage->leaf ){
+  if( !pPage->leaf ){
     aPayload += 4;  /* Skip the child pointer */
   }
   if( !pPage->zeroData ){
@@ -1530,7 +1551,7 @@ int sqlite3BtreeDataSize(BtCursor *pCur, u32 *pSize){
     u64 size;
     cell = pPage->aCell[pCur->idx];
     cell += 2;   /* Skip the offset to the next cell */
-    if( pPage->leaf ){
+    if( !pPage->leaf ){
       cell += 4;  /* Skip the child pointer */
     }
     getVarint(cell, &size);
@@ -1572,9 +1593,7 @@ static int moveToChild(BtCursor *pCur, u32 newPgno){
   MemPage *pOldPage;
   Btree *pBt = pCur->pBt;
 
-  rc = getPage(pBt, newPgno, &pNewPage);
-  if( rc ) return rc;
-  rc = initPage(pNewPage, pCur->pPage);
+  rc = getAndInitPage(pBt, newPgno, &pNewPage, pCur->pPage);
   if( rc ) return rc;
   pNewPage->idxParent = pCur->idx;
   pOldPage = pCur->pPage;
@@ -1600,7 +1619,7 @@ static int moveToChild(BtCursor *pCur, u32 newPgno){
 static int isRootPage(MemPage *pPage){
   MemPage *pParent = pPage->pParent;
   assert( pParent==0 || pParent->isInit );
-  if( pParent || (pParent->pgno==1 && pParent->nCell==0) ) return 1;
+  if( pParent==0 || (pParent->pgno==1 && pParent->nCell==0) ) return 1;
   return 0;
 }
 
@@ -1666,9 +1685,7 @@ static int moveToRoot(BtCursor *pCur){
   int rc;
   Btree *pBt = pCur->pBt;
 
-  rc = getPage(pBt, pCur->pgnoRoot, &pRoot);
-  if( rc ) return rc;
-  rc = initPage(pRoot, 0);
+  rc = getAndInitPage(pBt, pCur->pgnoRoot, &pRoot, 0);
   if( rc ) return rc;
   releasePage(pCur->pPage);
   pCur->pPage = pRoot;
@@ -1807,7 +1824,7 @@ int sqlite3BtreeMoveto(BtCursor *pCur, const void *pKey, u64 nKey, int *pRes){
       void *pCellKey;
       u64 nCellKey;
       pCur->idx = (lwr+upr)/2;
-      nCellKey = sqlite3BtreeKeySize(pCur, &nCellKey);
+      sqlite3BtreeKeySize(pCur, &nCellKey);
       if( pPage->intKey ){
         if( nCellKey<nKey ){
           c = -1;
@@ -2211,6 +2228,7 @@ static int fillInCell(
     if( n>nSrc ) n = nSrc;
     memcpy(pPayload, pSrc, n);
     nPayload -= n;
+    pPayload += n;
     nSrc -= n;
     spaceLeft -= n;
     if( nSrc==0 ){
@@ -2285,13 +2303,15 @@ static void reparentChildPages(MemPage *pPage){
 ** the linked list.
 */
 static void dropCell(MemPage *pPage, int idx, int sz){
-  int j;
+  int j, pc;
   assert( idx>=0 && idx<pPage->nCell );
   assert( sz==cellSize(pPage, pPage->aCell[idx]) );
   assert( sqlite3pager_iswriteable(pPage->aData) );
   assert( pPage->aCell[idx]>=pPage->aData );
   assert( pPage->aCell[idx]<&pPage->aData[pPage->pBt->pageSize-sz] );
-  freeSpace(pPage, idx, sz);
+  pc = Addr(pPage->aCell[idx]) - Addr(pPage->aData);
+  assert( pc>pPage->hdrOffset && pc+sz<=pPage->pBt->pageSize );
+  freeSpace(pPage, pc, sz);
   for(j=idx; j<pPage->nCell-1; j++){
     pPage->aCell[j] = pPage->aCell[j+1];
   }
@@ -2344,7 +2364,7 @@ static void relinkCellList(MemPage *pPage){
   assert( sqlite3pager_iswriteable(pPage->aData) );
   idxFrom = pPage->hdrOffset+3;
   for(i=0; i<pPage->nCell; i++){
-    int idx = Addr(pPage->aCell[i]) - Addr(pPage);
+    int idx = Addr(pPage->aCell[i]) - Addr(pPage->aData);
     assert( idx>pPage->hdrOffset && idx<pPage->pBt->pageSize );
     put2byte(&pPage->aData[idxFrom], idx);
     idxFrom = idx;
@@ -2620,9 +2640,7 @@ static int balance(MemPage *pPage){
     }else{
       break;
     }
-    rc = getPage(pBt, pgnoOld[i], &apOld[i]);
-    if( rc ) goto balance_cleanup;
-    rc = initPage(apOld[i], pParent);
+    rc = getAndInitPage(pBt, pgnoOld[i], &apOld[i], pParent);
     if( rc ) goto balance_cleanup;
     apOld[i]->idxParent = k;
     apCopy[i] = 0;
@@ -3053,7 +3071,7 @@ int sqlite3BtreeCreateTable(Btree *pBt, int *piTable, int flags){
   rc = allocatePage(pBt, &pRoot, &pgnoRoot, 0);
   if( rc ) return rc;
   assert( sqlite3pager_iswriteable(pRoot->aData) );
-  zeroPage(pRoot, flags);
+  zeroPage(pRoot, flags | PTF_LEAF);
   sqlite3pager_unref(pRoot->aData);
   *piTable = (int)pgnoRoot;
   return SQLITE_OK;
@@ -3074,12 +3092,10 @@ static int clearDatabasePage(
   unsigned char *pCell;
   int i;
 
-  rc = getPage(pBt, pgno, &pPage);
+  rc = getAndInitPage(pBt, pgno, &pPage, pParent);
   if( rc ) return rc;
   rc = sqlite3pager_write(pPage->aData);
   if( rc ) return rc;
-  rc = initPage(pPage, pParent);
-  if( rc ) return rc;
   for(i=0; i<pPage->nCell; i++){
     pCell = pPage->aCell[i];
     if( !pPage->leaf ){
@@ -3183,8 +3199,8 @@ int sqlite3BtreeUpdateMeta(Btree *pBt, int idx, u32 iMeta){
   if( !pBt->inTrans ){
     return pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR;
   }
-  rc = sqlite3pager_get(pBt->pPager, 1, (void**)&pP1);
-  if( rc ) return rc;
+  assert( pBt->pPage1!=0 );
+  pP1 = pBt->pPage1->aData;
   rc = sqlite3pager_write(pP1);
   if( rc ) return rc;
   put4byte(&pP1[36 + idx*4], iMeta);
@@ -3218,7 +3234,7 @@ int sqlite3BtreePageDump(Btree *pBt, int pgno, int recursive){
   printf("PAGE %d:  flags=0x%02x  frag=%d\n", pgno,
     pPage->aData[pPage->hdrOffset], pPage->aData[pPage->hdrOffset+5]);
   i = 0;
-  hdrOffset = pgno==1 ? 100 : 0;
+  assert( pPage->hdrOffset == (pgno==1 ? 100 : 0) );
   idx = get2byte(&pPage->aData[hdrOffset+3]);
   while( idx>0 && idx<=pBt->pageSize ){
     u64 nData, nKey;
index 41db493e779031ec1ed4ad4919c1c8581cc99ad0..a1cfe9e5744b6f3cc147cd42da41af5a8a6c2219 100644 (file)
@@ -18,7 +18,7 @@
 ** file simultaneously, or one process from reading the database while
 ** another is writing.
 **
-** @(#) $Id: pager.c,v 1.102 2004/04/26 14:10:21 drh Exp $
+** @(#) $Id: pager.c,v 1.103 2004/05/07 17:57:50 drh Exp $
 */
 #include "os.h"         /* Must be first to enable large file support */
 #include "sqliteInt.h"
@@ -569,7 +569,9 @@ static int pager_playback_one_page(Pager *pPager, OsFile *jfd, int format){
     */
     assert( pPg->nRef==0 || pPg->pgno==1 );
     memcpy(PGHDR_TO_DATA(pPg), pgRec.aData, SQLITE_PAGE_SIZE);
-    memset(PGHDR_TO_EXTRA(pPg), 0, pPager->nExtra);
+    if( pPager->xDestructor ){
+      pPager->xDestructor(PGHDR_TO_DATA(pPg));
+    }
     pPg->dirty = 0;
     pPg->needSync = 0;
     CODEC(pPager, PGHDR_TO_DATA(pPg), pPg->pgno, 3);
index 73c1ea4b305ed4ab82c5981c4a148cfdabb0e93d..c828f19a0888a18a2df74df4ce59d62b7330aafe 100644 (file)
@@ -11,7 +11,7 @@
 *************************************************************************
 ** A TCL Interface to SQLite
 **
-** $Id: tclsqlite.c,v 1.61 2004/05/06 23:37:53 danielk1977 Exp $
+** $Id: tclsqlite.c,v 1.62 2004/05/07 17:57:50 drh Exp $
 */
 #ifndef NO_TCL     /* Omit this whole file if TCL is unavailable */
 
@@ -1212,7 +1212,7 @@ int TCLSH_MAIN(int argc, char **argv){
     extern int Md5_Init(Tcl_Interp*);
     /* Sqlitetest1_Init(interp); */
     Sqlitetest2_Init(interp);
-    /* Sqlitetest3_Init(interp); */
+    Sqlitetest3_Init(interp);
     /* Sqlitetest4_Init(interp); */
     Sqlitetest5_Init(interp);
     Md5_Init(interp);
index 707f5da38134355cfe03766f0f3d60ee4849e998..e5a3f1b9ea003c94bc28c0fee8ab86389882695d 100644 (file)
@@ -13,7 +13,7 @@
 ** is not included in the SQLite library.  It is used for automated
 ** testing of the SQLite library.
 **
-** $Id: test3.c,v 1.26 2004/05/07 13:30:42 drh Exp $
+** $Id: test3.c,v 1.27 2004/05/07 17:57:50 drh Exp $
 */
 #include "sqliteInt.h"
 #include "pager.h"
@@ -329,9 +329,9 @@ static int btree_update_meta(
   Btree *pBt;
   int rc;
   int i;
-  int aMeta[SQLITE_N_BTREE_META-1];
+  int aMeta[SQLITE_N_BTREE_META];
 
-  if( argc!=2+SQLITE_N_BTREE_META ){
+  if( argc!=1+SQLITE_N_BTREE_META ){
     char zBuf[30];
     sprintf(zBuf,"%d",SQLITE_N_BTREE_META);
     Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
@@ -339,11 +339,11 @@ static int btree_update_meta(
     return TCL_ERROR;
   }
   if( Tcl_GetInt(interp, argv[1], (int*)&pBt) ) return TCL_ERROR;
-  for(i=0; i<SQLITE_N_BTREE_META-1; i++){
-    if( Tcl_GetInt(interp, argv[i+2], &aMeta[i]) ) return TCL_ERROR;
+  for(i=1; i<SQLITE_N_BTREE_META; i++){
+    if( Tcl_GetInt(interp, argv[i+1], &aMeta[i]) ) return TCL_ERROR;
   }
-  for(i=0; i<SQLITE_N_BTREE_META-1; i++){
-    rc = sqlite3BtreeUpdateMeta(pBt, i+1, aMeta[i]);
+  for(i=1; i<SQLITE_N_BTREE_META; i++){
+    rc = sqlite3BtreeUpdateMeta(pBt, i, aMeta[i]);
     if( rc!=SQLITE_OK ){
       Tcl_AppendResult(interp, errorName(rc), 0);
       return TCL_ERROR;
@@ -594,7 +594,13 @@ static int btree_move_to(
     return TCL_ERROR;
   }
   if( Tcl_GetInt(interp, argv[1], (int*)&pCur) ) return TCL_ERROR;
-  rc = sqlite3BtreeMoveto(pCur, argv[2], strlen(argv[2]), &res);  
+  if( sqlite3BtreeFlags(pCur) & BTREE_INTKEY ){
+    int iKey;
+    if( Tcl_GetInt(interp, argv[2], &iKey) ) return TCL_ERROR;
+    rc = sqlite3BtreeMoveto(pCur, 0, iKey, &res);
+  }else{
+    rc = sqlite3BtreeMoveto(pCur, argv[2], strlen(argv[2]), &res);  
+  }
   if( rc ){
     Tcl_AppendResult(interp, errorName(rc), 0);
     return TCL_ERROR;
@@ -655,8 +661,14 @@ static int btree_insert(
     return TCL_ERROR;
   }
   if( Tcl_GetInt(interp, argv[1], (int*)&pCur) ) return TCL_ERROR;
-  rc = sqlite3BtreeInsert(pCur, argv[2], strlen(argv[2]),
+  if( sqlite3BtreeFlags(pCur) & BTREE_INTKEY ){
+    int iKey;
+    if( Tcl_GetInt(interp, argv[2], &iKey) ) return TCL_ERROR;
+    rc = sqlite3BtreeInsert(pCur, 0, iKey, argv[3], strlen(argv[3]));
+  }else{
+    rc = sqlite3BtreeInsert(pCur, argv[2], strlen(argv[2]),
                          argv[3], strlen(argv[3]));
+  }
   if( rc ){
     Tcl_AppendResult(interp, errorName(rc), 0);
     return TCL_ERROR;
@@ -855,11 +867,8 @@ static int btree_key(
   }else{
     zBuf = malloc( n+1 );
     rc = sqlite3BtreeKey(pCur, 0, n, zBuf);
-    if( rc!=n ){
-      char zMsg[100];
-      free(zBuf);
-      sprintf(zMsg, "truncated key: got %d of %llu bytes", rc, n);
-      Tcl_AppendResult(interp, zMsg, 0);
+    if( rc ){
+      Tcl_AppendResult(interp, errorName(rc), 0);
       return TCL_ERROR;
     }
     zBuf[n] = 0;
@@ -894,11 +903,8 @@ static int btree_data(
   sqlite3BtreeDataSize(pCur, &n);
   zBuf = malloc( n+1 );
   rc = sqlite3BtreeData(pCur, 0, n, zBuf);
-  if( rc!=n ){
-    char zMsg[100];
-    free(zBuf);
-    sprintf(zMsg, "truncated data: got %d of %u bytes", rc, n);
-    Tcl_AppendResult(interp, zMsg, 0);
+  if( rc ){
+    Tcl_AppendResult(interp, errorName(rc), 0);
     return TCL_ERROR;
   }
   zBuf[n] = 0;
index f2810483e8ed9837065cefc73d64de5ea3866348..9c417ecbe0ba479798e205c7ab9c339a6ee939db 100644 (file)
 # This file implements regression tests for SQLite library.  The
 # focus of this script is btree database backend
 #
-# $Id: btree.test,v 1.15 2004/02/10 01:54:28 drh Exp $
+# $Id: btree.test,v 1.16 2004/05/07 17:57:50 drh Exp $
 
 
 set testdir [file dirname $argv0]
 source $testdir/tester.tcl
 
-if {[info commands btree_open]!="" && $SQLITE_PAGE_SIZE==1024 
-     && $SQLITE_USABLE_SIZE==1024} {
-
 # 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]
+  set rc [catch {btree_open test1.bt 2000 0} ::b1]
 } {0}
 
 # The second element of the list returned by btree_pager_stats is the
@@ -38,7 +35,7 @@ do_test btree-1.1.1 {
   lindex [btree_pager_stats $::b1] 1
 } {0}
 do_test btree-1.2 {
-  set rc [catch {btree_open test1.bt} ::b2]
+  set rc [catch {btree_open test1.bt 2000 0} ::b2]
 } {0}
 do_test btree-1.3 {
   set rc [catch {btree_close $::b2} msg]
@@ -55,17 +52,18 @@ do_test btree-1.4.1 {
   lindex [btree_pager_stats $::b1] 1
 } {1}
 do_test btree-1.5 {
-  set rc [catch {btree_cursor $::b1 2 1} ::c1]
+  set rc [catch {btree_cursor $::b1 1 1} ::c1]
   if {$rc} {lappend rc $::c1}
   set rc
 } {0}
 do_test btree-1.6 {
-  set rc [catch {btree_insert $::c1 one 1.00} msg]
+  set rc [catch {btree_insert $::c1 100 1.00} msg]
   lappend rc $msg
 } {0 {}}
 do_test btree-1.7 {
+  btree_move_to $::c1 100
   btree_key $::c1
-} {one}
+} {100}
 do_test btree-1.8 {
   btree_data $::c1
 } {1.00}
@@ -79,7 +77,7 @@ do_test btree-1.10 {
 } {0 {}}
 do_test btree-1.11 {
   file size test1.bt
-} {2048}
+} {1024}
 do_test btree-1.12 {
   lindex [btree_pager_stats $::b1] 1
 } {0}
@@ -87,105 +85,110 @@ do_test btree-1.12 {
 # Reopen the database and attempt to read the record that we wrote.
 #
 do_test btree-2.1 {
-  set rc [catch {btree_cursor $::b1 2 1} ::c1]
+  set rc [catch {btree_cursor $::b1 1 1} ::c1]
   if {$rc} {lappend rc $::c1}
   set rc
 } {0}
 do_test btree-2.2 {
-  btree_move_to $::c1 abc
+  btree_move_to $::c1 99
 } {1}
 do_test btree-2.3 {
-  btree_move_to $::c1 xyz
+  btree_move_to $::c1 101
 } {-1}
 do_test btree-2.4 {
-  btree_move_to $::c1 one
+  btree_move_to $::c1 100
 } {0}
 do_test btree-2.5 {
   btree_key $::c1
-} {one}
+} {100}
 do_test btree-2.6 {
   btree_data $::c1
 } {1.00}
 do_test btree-2.7 {
   lindex [btree_pager_stats $::b1] 1
-} {2}
+} {1}
 
 # Do some additional inserts
 #
 do_test btree-3.1 {
   btree_begin_transaction $::b1
-  btree_insert $::c1 two 2.00
+  btree_insert $::c1 200 2.00
+  btree_move_to $::c1 200
   btree_key $::c1
-} {two}
+} {200}
 do_test btree-3.1.1 {
   lindex [btree_pager_stats $::b1] 1
-} {2}
+} {1}
 do_test btree-3.2 {
-  btree_insert $::c1 three 3.00
+  btree_insert $::c1 300 3.00
+  btree_move_to $::c1 300
   btree_key $::c1
-} {three}
+} {300}
 do_test btree-3.4 {
-  btree_insert $::c1 four 4.00
+  btree_insert $::c1 400 4.00
+  btree_move_to $::c1 400
   btree_key $::c1
-} {four}
+} {400}
 do_test btree-3.5 {
-  btree_insert $::c1 five 5.00
+  btree_insert $::c1 500 5.00
+  btree_move_to $::c1 500
   btree_key $::c1
-} {five}
+} {500}
 do_test btree-3.6 {
-  btree_insert $::c1 six 6.00
+  btree_insert $::c1 600 6.00
+  btree_move_to $::c1 600
   btree_key $::c1
-} {six}
+} {600}
 #btree_page_dump $::b1 2
 do_test btree-3.7 {
-  set rc [btree_move_to $::c1 {}]
+  set rc [btree_move_to $::c1 0]
   expr {$rc>0}
 } {1}
 do_test btree-3.8 {
   btree_key $::c1
-} {five}
+} {100}
 do_test btree-3.9 {
   btree_data $::c1
-} {5.00}
+} {1.00}
 do_test btree-3.10 {
   btree_next $::c1
   btree_key $::c1
-} {four}
+} {200}
 do_test btree-3.11 {
   btree_data $::c1
-} {4.00}
+} {2.00}
 do_test btree-3.12 {
   btree_next $::c1
   btree_key $::c1
-} {one}
+} {300}
 do_test btree-3.13 {
   btree_data $::c1
-} {1.00}
+} {3.00}
 do_test btree-3.14 {
   btree_next $::c1
   btree_key $::c1
-} {six}
+} {400}
 do_test btree-3.15 {
   btree_data $::c1
-} {6.00}
+} {4.00}
 do_test btree-3.16 {
   btree_next $::c1
   btree_key $::c1
-} {three}
+} {500}
 do_test btree-3.17 {
   btree_data $::c1
-} {3.00}
+} {5.00}
 do_test btree-3.18 {
   btree_next $::c1
   btree_key $::c1
-} {two}
+} {600}
 do_test btree-3.19 {
   btree_data $::c1
-} {2.00}
+} {6.00}
 do_test btree-3.20 {
   btree_next $::c1
   btree_key $::c1
-} {}
+} {0}
 do_test btree-3.21 {
   btree_data $::c1
 } {}
@@ -208,182 +211,188 @@ do_test btree-3.23.1 {
 } {0}
 do_test btree-3.24 {
   file size test1.bt
-} {2048}
+} {1024}
 do_test btree-3.25 {
-  set rc [catch {btree_cursor $::b1 2 1} ::c1]
+  set rc [catch {btree_cursor $::b1 1 1} ::c1]
   if {$rc} {lappend rc $::c1}
   set rc
 } {0}
 do_test btree-3.25.1 {
   lindex [btree_pager_stats $::b1] 1
-} {2}
+} {1}
 do_test btree-3.26 {
-  set rc [btree_move_to $::c1 {}]
+  set rc [btree_move_to $::c1 0]
   expr {$rc>0}
 } {1}
 do_test btree-3.27 {
   btree_key $::c1
-} {five}
+} {100}
 do_test btree-3.28 {
   btree_data $::c1
-} {5.00}
+} {1.00}
 do_test btree-3.29 {
   btree_next $::c1
   btree_key $::c1
-} {four}
+} {200}
 do_test btree-3.30 {
   btree_data $::c1
-} {4.00}
+} {2.00}
 do_test btree-3.31 {
   btree_next $::c1
   btree_key $::c1
-} {one}
+} {300}
 do_test btree-3.32 {
   btree_data $::c1
-} {1.00}
+} {3.00}
 do_test btree-3.33 {
   btree_next $::c1
   btree_key $::c1
-} {six}
+} {400}
 do_test btree-3.34 {
   btree_data $::c1
-} {6.00}
+} {4.00}
 do_test btree-3.35 {
   btree_next $::c1
   btree_key $::c1
-} {three}
+} {500}
 do_test btree-3.36 {
   btree_data $::c1
-} {3.00}
+} {5.00}
 do_test btree-3.37 {
   btree_next $::c1
   btree_key $::c1
-} {two}
+} {600}
 do_test btree-3.38 {
   btree_data $::c1
-} {2.00}
+} {6.00}
 do_test btree-3.39 {
   btree_next $::c1
   btree_key $::c1
-} {}
+} {0}
 do_test btree-3.40 {
   btree_data $::c1
 } {}
 do_test btree-3.41 {
   lindex [btree_pager_stats $::b1] 1
-} {2}
+} {1}
 
 
 # Now try a delete
 #
 do_test btree-4.1 {
   btree_begin_transaction $::b1
-  btree_move_to $::c1 one
+  btree_move_to $::c1 100
   btree_key $::c1
-} {one}
+} {100}
 do_test btree-4.1.1 {
   lindex [btree_pager_stats $::b1] 1
-} {2}
+} {1}
 do_test btree-4.2 {
   btree_delete $::c1
 } {}
 do_test btree-4.3 {
+  btree_move_to $::c1 100
   btree_key $::c1
-} {six}
+} {200}
 do_test btree-4.4 {
   btree_next $::c1
   btree_key $::c1
-} {six}
+} {300}
 do_test btree-4.5 {
   btree_next $::c1
   btree_key $::c1
-} {three}
+} {400}
 do_test btree-4.4 {
-  btree_move_to $::c1 {}
+  btree_move_to $::c1 0
   set r {}
   while 1 {
     set key [btree_key $::c1]
-    if {$key==""} break
+    if {$key==0} 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}
+} {200 2.00 300 3.00 400 4.00 500 5.00 600 6.00}
 
 # Commit and make sure the delete is still there.
 #
 do_test btree-4.5 {
   btree_commit $::b1
-  btree_move_to $::c1 {}
+  btree_move_to $::c1 0
   set r {}
   while 1 {
     set key [btree_key $::c1]
-    if {$key==""} break
+    if {$key==0} 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}
+} {200 2.00 300 3.00 400 4.00 500 5.00 600 6.00}
 
 # Completely close the database and reopen it.  Then check
 # the data again.
 #
 do_test btree-4.6 {
   lindex [btree_pager_stats $::b1] 1
-} {2}
+} {1}
 do_test btree-4.7 {
   btree_close_cursor $::c1
   lindex [btree_pager_stats $::b1] 1
 } {0}
 do_test btree-4.8 {
   btree_close $::b1
-  set ::b1 [btree_open test1.bt]
-  set ::c1 [btree_cursor $::b1 2 1]
+  set ::b1 [btree_open test1.bt 2000 0]
+  set ::c1 [btree_cursor $::b1 1 1]
   lindex [btree_pager_stats $::b1] 1
-} {2}
+} {1}
 do_test btree-4.9 {
   set r {}
   btree_first $::c1
   while 1 {
     set key [btree_key $::c1]
-    if {$key==""} break
+    if {$key==0} 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}
+} {200 2.00 300 3.00 400 4.00 500 5.00 600 6.00}
 
 # Try to read and write meta data
 #
 do_test btree-5.1 {
   btree_get_meta $::b1
-} {0 0 0 0 0 0 0 0 0 0}
+} {0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0}
 do_test btree-5.2 {
-  set rc [catch {btree_update_meta $::b1 1 2 3 4 5 6 7 8 9 10} msg]
+  set rc [catch {
+    btree_update_meta $::b1 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
+  } msg]
   lappend rc $msg
 } {1 SQLITE_ERROR}
 do_test btree-5.3 {
   btree_begin_transaction $::b1
-  set rc [catch {btree_update_meta $::b1 1 2 3 4 5 6 7 8 9 10} msg]
+  set rc [catch {
+    btree_update_meta $::b1 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
+  } msg]
   lappend rc $msg
 } {0 {}}
 do_test btree-5.4 {
   btree_get_meta $::b1
-} {0 2 3 4 5 6 7 8 9 10}
+} {0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15}
 do_test btree-5.5 {
   btree_close_cursor $::c1
   btree_rollback $::b1
   btree_get_meta $::b1
-} {0 0 0 0 0 0 0 0 0 0}
+} {0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0}
 do_test btree-5.6 {
   btree_begin_transaction $::b1
-  btree_update_meta $::b1 999 10 20 30 40 50 60 70 80 90
+  btree_update_meta $::b1 10 20 30 40 50 60 70 80 90 100 110 120 130 \
+     140 150
   btree_commit $::b1
   btree_get_meta $::b1
-} {0 10 20 30 40 50 60 70 80 90}
+} {0 10 20 30 40 50 60 70 80 90 100 110 120 130 140 150}
 
 proc select_all {cursor} {
   set r {}
@@ -397,6 +406,18 @@ proc select_all {cursor} {
   }
   return $r
 }
+proc select_all_intkey {cursor} {
+  set r {}
+  btree_move_to $cursor 0
+  while 1 {
+    set key [btree_key $cursor]
+    if {$key==0} break
+    lappend r $key
+    lappend r [btree_data $cursor]
+    btree_next $cursor
+  }
+  return $r
+}
 proc select_keys {cursor} {
   set r {}
   btree_move_to $cursor {}
@@ -412,13 +433,13 @@ proc select_keys {cursor} {
 # Try to create a new table in the database file
 #
 do_test btree-6.1 {
-  set rc [catch {btree_create_table $::b1} msg]
+  set rc [catch {btree_create_table $::b1 0} msg]
   lappend rc $msg
 } {1 SQLITE_ERROR}
 do_test btree-6.2 {
   btree_begin_transaction $::b1
-  set ::t2 [btree_create_table $::b1]
-} {3}
+  set ::t2 [btree_create_table $::b1 0]
+} {2}
 do_test btree-6.2.1 {
   lindex [btree_pager_stats $::b1] 1
 } {1}
@@ -432,12 +453,12 @@ do_test btree-6.2.3 {
 } {ten}
 do_test btree-6.3 {
   btree_commit $::b1
-  set ::c1 [btree_cursor $::b1 2 1]
+  set ::c1 [btree_cursor $::b1 1 1]
   lindex [btree_pager_stats $::b1] 1
-} {3}
+} {2}
 do_test btree-6.3.1 {
-  select_all $::c1
-} {five 5.00 four 4.00 six 6.00 three 3.00 two 2.00}
+  select_all_intkey $::c1
+} {200 2.00 300 3.00 400 4.00 500 5.00 600 6.00}
 #btree_page_dump $::b1 3
 do_test btree-6.4 {
   select_all $::c2
@@ -453,7 +474,7 @@ do_test btree-6.6 {
 } {}
 do_test btree-6.6.1 {
   lindex [btree_pager_stats $::b1] 1
-} {2}
+} {1}
 do_test btree-6.7 {
   btree_drop_table $::b1 $::t2
 } {}
@@ -461,15 +482,15 @@ do_test btree-6.7.1 {
   lindex [btree_get_meta $::b1] 0
 } {1}
 do_test btree-6.8 {
-  set ::t2 [btree_create_table $::b1]
-} {3}
+  set ::t2 [btree_create_table $::b1 0]
+} {2}
 do_test btree-6.8.1 {
   lindex [btree_get_meta $::b1] 0
 } {0}
 do_test btree-6.9 {
   set ::c2 [btree_cursor $::b1 $::t2 1]
   lindex [btree_pager_stats $::b1] 1
-} {3}
+} {2}
 
 do_test btree-6.9.1 {
   btree_move_to $::c2 {}
@@ -632,7 +653,7 @@ do_test btree-8.8 {
 do_test btree-8.9 {
   btree_close_cursor $::c1
   btree_close $::b1
-  set ::b1 [btree_open test1.bt]
+  set ::b1 [btree_open test1.bt 2000 0]
   set ::c1 [btree_cursor $::b1 2 1]
   btree_move_to $::c1 020
   btree_data $::c1
@@ -1015,6 +1036,4 @@ do_test btree-99.1 {
 catch {unset data}
 catch {unset key}
 
-} ;# end if( not mem: and has pager_open command );
-
 finish_test
index 30603f47ca298d07c4eaeb575019bec17802f7d5..db9005eb6ea74648cd98ade1b5e36e1572a14901 100644 (file)
@@ -11,7 +11,7 @@
 # This file implements some common TCL routines used for regression
 # testing the SQLite library
 #
-# $Id: tester.tcl,v 1.29 2004/04/26 14:10:22 drh Exp $
+# $Id: tester.tcl,v 1.30 2004/05/07 17:57:50 drh Exp $
 
 if 0 {
 # Make sure tclsqlite was compiled correctly.  Abort now with an
@@ -110,7 +110,7 @@ proc do_test {name cmd expected} {
     puts "\nExpected: \[$expected\]\n     Got: \[$result\]"
     incr nErr
     lappend ::failList $name
-    if {$nErr>100} {puts "*** Giving up..."; finalize_testing}
+    if {$nErr>=1} {puts "*** Giving up..."; finalize_testing}
   } else {
     puts " Ok"
   }