/ Check-in [0e1d84f2]
Login

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

Overview
Comment:Removed the direct btree tests - part of the ongoing effort to test by calling only public interfaces. Modify the sqlite3VdbeRecordCompare interface to used a pre-parsed second key - resulting in a 13% performance improvement on speed1p.test. (CVS 4911)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 0e1d84f2f456e7680bb667266745b629ddf3605f
User & Date: drh 2008-03-25 00:22:21
Context
2008-03-25
09:47
Use a vdbe memory cell to allocate the space required for vdbe cursors. (CVS 4912) check-in: 04715364 user: danielk1977 tags: trunk
00:22
Removed the direct btree tests - part of the ongoing effort to test by calling only public interfaces. Modify the sqlite3VdbeRecordCompare interface to used a pre-parsed second key - resulting in a 13% performance improvement on speed1p.test. (CVS 4911) check-in: 0e1d84f2 user: drh tags: trunk
2008-03-24
12:51
Improved documentation of sqlite3_blob_open(). (CVS 4910) check-in: 1ed695f5 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/btree.c.

     5      5   ** a legal notice, here is a blessing:
     6      6   **
     7      7   **    May you do good and not evil.
     8      8   **    May you find forgiveness for yourself and forgive others.
     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12         -** $Id: btree.c,v 1.442 2008/03/23 00:20:36 drh Exp $
           12  +** $Id: btree.c,v 1.443 2008/03/25 00:22:21 drh Exp $
    13     13   **
    14     14   ** This file implements a external (disk-based) database using BTrees.
    15     15   ** See the header comment on "btreeInt.h" for additional information.
    16     16   ** Including a description of file format and an overview of operation.
    17     17   */
    18     18   #include "btreeInt.h"
    19     19   
................................................................................
  2645   2645       assert( countWriteCursors(pBt)==0 );
  2646   2646       pBt->inStmt = 0;
  2647   2647     }
  2648   2648     sqlite3BtreeLeave(p);
  2649   2649     return rc;
  2650   2650   }
  2651   2651   
  2652         -/*
  2653         -** Default key comparison function to be used if no comparison function
  2654         -** is specified on the sqlite3BtreeCursor() call.
  2655         -*/
  2656         -static int dfltCompare(
  2657         -  void *NotUsed,             /* User data is not used */
  2658         -  int n1, const void *p1,    /* First key to compare */
  2659         -  int n2, const void *p2     /* Second key to compare */
  2660         -){
  2661         -  int c;
  2662         -  c = memcmp(p1, p2, n1<n2 ? n1 : n2);
  2663         -  if( c==0 ){
  2664         -    c = n1 - n2;
  2665         -  }
  2666         -  return c;
  2667         -}
  2668         -
  2669   2652   /*
  2670   2653   ** Create a new cursor for the BTree whose root is on the page
  2671   2654   ** iTable.  The act of acquiring a cursor gets a read lock on 
  2672   2655   ** the database file.
  2673   2656   **
  2674   2657   ** If wrFlag==0, then the cursor can only be used for reading.
  2675   2658   ** If wrFlag==1, then the cursor can be used for reading or for
................................................................................
  2688   2671   ** 3:  The database must be writable (not on read-only media)
  2689   2672   **
  2690   2673   ** 4:  There must be an active transaction.
  2691   2674   **
  2692   2675   ** No checking is done to make sure that page iTable really is the
  2693   2676   ** root page of a b-tree.  If it is not, then the cursor acquired
  2694   2677   ** will not work correctly.
  2695         -**
  2696         -** The comparison function must be logically the same for every cursor
  2697         -** on a particular table.  Changing the comparison function will result
  2698         -** in incorrect operations.  If the comparison function is NULL, a
  2699         -** default comparison function is used.  The comparison function is
  2700         -** always ignored for INTKEY tables.
  2701   2678   */
  2702   2679   static int btreeCursor(
  2703         -  Btree *p,                                   /* The btree */
  2704         -  int iTable,                                 /* Root page of table to open */
  2705         -  int wrFlag,                                 /* 1 to write. 0 read-only */
  2706         -  int (*xCmp)(void*,int,const void*,int,const void*), /* Key Comparison func */
  2707         -  void *pArg,                                 /* First arg to xCompare() */
  2708         -  BtCursor **ppCur                            /* Write new cursor here */
         2680  +  Btree *p,                       /* The btree */
         2681  +  int iTable,                     /* Root page of table to open */
         2682  +  int wrFlag,                     /* 1 to write. 0 read-only */
         2683  +  struct KeyInfo *pKeyInfo,       /* First arg to comparison function */
         2684  +  BtCursor **ppCur                /* Write new cursor here */
  2709   2685   ){
  2710   2686     int rc;
  2711   2687     BtCursor *pCur;
  2712   2688     BtShared *pBt = p->pBt;
  2713   2689   
  2714   2690     assert( sqlite3BtreeHoldsMutex(p) );
  2715   2691     *ppCur = 0;
................................................................................
  2746   2722       goto create_cursor_exception;
  2747   2723     }
  2748   2724   
  2749   2725     /* Now that no other errors can occur, finish filling in the BtCursor
  2750   2726     ** variables, link the cursor into the BtShared list and set *ppCur (the
  2751   2727     ** output argument to this function).
  2752   2728     */
  2753         -  pCur->xCompare = xCmp ? xCmp : dfltCompare;
  2754         -  pCur->pArg = pArg;
         2729  +  pCur->pKeyInfo = pKeyInfo;
  2755   2730     pCur->pBtree = p;
  2756   2731     pCur->pBt = pBt;
  2757   2732     pCur->wrFlag = wrFlag;
  2758   2733     pCur->pNext = pBt->pCursor;
  2759   2734     if( pCur->pNext ){
  2760   2735       pCur->pNext->pPrev = pCur;
  2761   2736     }
................................................................................
  2770   2745       releasePage(pCur->pPage);
  2771   2746       sqlite3_free(pCur);
  2772   2747     }
  2773   2748     unlockBtreeIfUnused(pBt);
  2774   2749     return rc;
  2775   2750   }
  2776   2751   int sqlite3BtreeCursor(
  2777         -  Btree *p,                                   /* The btree */
  2778         -  int iTable,                                 /* Root page of table to open */
  2779         -  int wrFlag,                                 /* 1 to write. 0 read-only */
  2780         -  int (*xCmp)(void*,int,const void*,int,const void*), /* Key Comparison func */
  2781         -  void *pArg,                                 /* First arg to xCompare() */
  2782         -  BtCursor **ppCur                            /* Write new cursor here */
         2752  +  Btree *p,                   /* The btree */
         2753  +  int iTable,                 /* Root page of table to open */
         2754  +  int wrFlag,                 /* 1 to write. 0 read-only */
         2755  +  struct KeyInfo *pKeyInfo,   /* First arg to xCompare() */
         2756  +  BtCursor **ppCur            /* Write new cursor here */
  2783   2757   ){
  2784   2758     int rc;
  2785   2759     sqlite3BtreeEnter(p);
  2786   2760     p->pBt->db = p->db;
  2787         -  rc = btreeCursor(p, iTable, wrFlag, xCmp, pArg, ppCur);
         2761  +  rc = btreeCursor(p, iTable, wrFlag, pKeyInfo, ppCur);
  2788   2762     sqlite3BtreeLeave(p);
  2789   2763     return rc;
  2790   2764   }
  2791   2765   
  2792   2766   
  2793   2767   /*
  2794   2768   ** Close a cursor.  The read lock on the database file is released
................................................................................
  3574   3548   }
  3575   3549   
  3576   3550   /* Move the cursor so that it points to an entry near pKey/nKey.
  3577   3551   ** Return a success code.
  3578   3552   **
  3579   3553   ** For INTKEY tables, only the nKey parameter is used.  pKey is
  3580   3554   ** ignored.  For other tables, nKey is the number of bytes of data
  3581         -** in pKey.  The comparison function specified when the cursor was
  3582         -** created is used to compare keys.
         3555  +** in pKey.
  3583   3556   **
  3584   3557   ** If an exact match is not found, then the cursor is always
  3585   3558   ** left pointing at a leaf page which would hold the entry if it
  3586   3559   ** were present.  The cursor might point to an entry that comes
  3587   3560   ** before or after the key.
  3588   3561   **
  3589   3562   ** The result of comparing the key with the entry to which the
................................................................................
  3605   3578     BtCursor *pCur,        /* The cursor to be moved */
  3606   3579     const void *pKey,      /* The key content for indices.  Not used by tables */
  3607   3580     i64 nKey,              /* Size of pKey.  Or the key for tables */
  3608   3581     int biasRight,         /* If true, bias the search to the high end */
  3609   3582     int *pRes              /* Search result flag */
  3610   3583   ){
  3611   3584     int rc;
         3585  +  VdbeParsedRecord *pPKey;
         3586  +  char aSpace[200];
  3612   3587   
  3613   3588     assert( cursorHoldsMutex(pCur) );
  3614   3589     assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
  3615   3590     rc = moveToRoot(pCur);
  3616   3591     if( rc ){
  3617   3592       return rc;
  3618   3593     }
................................................................................
  3619   3594     assert( pCur->pPage );
  3620   3595     assert( pCur->pPage->isInit );
  3621   3596     if( pCur->eState==CURSOR_INVALID ){
  3622   3597       *pRes = -1;
  3623   3598       assert( pCur->pPage->nCell==0 );
  3624   3599       return SQLITE_OK;
  3625   3600     }
         3601  +  if( pCur->pPage->intKey ){
         3602  +    pPKey = 0;
         3603  +  }else{
         3604  +    pPKey = sqlite3VdbeRecordParse(pCur->pKeyInfo, nKey, pKey,
         3605  +                                   aSpace, sizeof(aSpace));
         3606  +    if( pPKey==0 ) return SQLITE_NOMEM;
         3607  +  }
  3626   3608     for(;;){
  3627   3609       int lwr, upr;
  3628   3610       Pgno chldPg;
  3629   3611       MemPage *pPage = pCur->pPage;
  3630   3612       int c = -1;  /* pRes return if table is empty must be -1 */
  3631   3613       lwr = 0;
  3632   3614       upr = pPage->nCell-1;
  3633   3615       if( !pPage->intKey && pKey==0 ){
  3634         -      return SQLITE_CORRUPT_BKPT;
         3616  +      rc = SQLITE_CORRUPT_BKPT;
         3617  +      goto moveto_finish;
  3635   3618       }
  3636   3619       if( biasRight ){
  3637   3620         pCur->idx = upr;
  3638   3621       }else{
  3639   3622         pCur->idx = (upr+lwr)/2;
  3640   3623       }
  3641   3624       if( lwr<=upr ) for(;;){
................................................................................
  3658   3641             c = 0;
  3659   3642           }
  3660   3643         }else{
  3661   3644           int available;
  3662   3645           pCellKey = (void *)fetchPayload(pCur, &available, 0);
  3663   3646           nCellKey = pCur->info.nKey;
  3664   3647           if( available>=nCellKey ){
  3665         -          c = pCur->xCompare(pCur->pArg, nCellKey, pCellKey, nKey, pKey);
         3648  +          c = sqlite3VdbeRecordCompareParsed(nCellKey, pCellKey, pPKey);
  3666   3649           }else{
  3667   3650             pCellKey = sqlite3_malloc( nCellKey );
  3668   3651             if( pCellKey==0 ) return SQLITE_NOMEM;
  3669   3652             rc = sqlite3BtreeKey(pCur, 0, nCellKey, (void *)pCellKey);
  3670         -          c = pCur->xCompare(pCur->pArg, nCellKey, pCellKey, nKey, pKey);
         3653  +          c = sqlite3VdbeRecordCompareParsed(nCellKey, pCellKey, pPKey);
  3671   3654             sqlite3_free(pCellKey);
  3672         -          if( rc ){
  3673         -            return rc;
  3674         -          }
         3655  +          if( rc ) goto moveto_finish;
  3675   3656           }
  3676   3657         }
  3677   3658         if( c==0 ){
  3678   3659           if( pPage->leafData && !pPage->leaf ){
  3679   3660             lwr = pCur->idx;
  3680   3661             upr = lwr - 1;
  3681   3662             break;
  3682   3663           }else{
  3683   3664             if( pRes ) *pRes = 0;
  3684         -          return SQLITE_OK;
         3665  +          rc = SQLITE_OK;
         3666  +          goto moveto_finish;
  3685   3667           }
  3686   3668         }
  3687   3669         if( c<0 ){
  3688   3670           lwr = pCur->idx+1;
  3689   3671         }else{
  3690   3672           upr = pCur->idx-1;
  3691   3673         }
................................................................................
  3702   3684         chldPg = get4byte(&pPage->aData[pPage->hdrOffset+8]);
  3703   3685       }else{
  3704   3686         chldPg = get4byte(findCell(pPage, lwr));
  3705   3687       }
  3706   3688       if( chldPg==0 ){
  3707   3689         assert( pCur->idx>=0 && pCur->idx<pCur->pPage->nCell );
  3708   3690         if( pRes ) *pRes = c;
  3709         -      return SQLITE_OK;
         3691  +      rc = SQLITE_OK;
         3692  +      goto moveto_finish;
  3710   3693       }
  3711   3694       pCur->idx = lwr;
  3712   3695       pCur->info.nSize = 0;
  3713   3696       rc = moveToChild(pCur, chldPg);
  3714         -    if( rc ){
  3715         -      return rc;
  3716         -    }
         3697  +    if( rc ) goto moveto_finish;
  3717   3698     }
  3718         -  /* NOT REACHED */
         3699  +moveto_finish:
         3700  +  sqlite3VdbeRecordUnparse(pPKey);
         3701  +  return rc;
  3719   3702   }
  3720   3703   
  3721   3704   
  3722   3705   /*
  3723   3706   ** Return TRUE if the cursor is not pointing at an entry of the table.
  3724   3707   **
  3725   3708   ** TRUE will be returned after a call to sqlite3BtreeNext() moves

Changes to src/btree.h.

     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   ** This header file defines the interface that the sqlite B-Tree file
    13     13   ** subsystem.  See comments in the source code for a detailed description
    14     14   ** of what each interface routine does.
    15     15   **
    16         -** @(#) $Id: btree.h,v 1.94 2007/12/07 18:55:28 drh Exp $
           16  +** @(#) $Id: btree.h,v 1.95 2008/03/25 00:22:21 drh Exp $
    17     17   */
    18     18   #ifndef _BTREE_H_
    19     19   #define _BTREE_H_
    20     20   
    21     21   /* TODO: This definition is just included so other modules compile. It
    22     22   ** needs to be revisited.
    23     23   */
................................................................................
   124    124   int sqlite3BtreeDropTable(Btree*, int, int*);
   125    125   int sqlite3BtreeClearTable(Btree*, int);
   126    126   int sqlite3BtreeGetMeta(Btree*, int idx, u32 *pValue);
   127    127   int sqlite3BtreeUpdateMeta(Btree*, int idx, u32 value);
   128    128   void sqlite3BtreeTripAllCursors(Btree*, int);
   129    129   
   130    130   int sqlite3BtreeCursor(
   131         -  Btree*,                              /* BTree containing table to open */
   132         -  int iTable,                          /* Index of root page */
   133         -  int wrFlag,                          /* 1 for writing.  0 for read-only */
   134         -  int(*)(void*,int,const void*,int,const void*),  /* Key comparison function */
   135         -  void*,                               /* First argument to compare function */
   136         -  BtCursor **ppCursor                  /* Returned cursor */
          131  +  Btree*,                  /* BTree containing table to open */
          132  +  int iTable,              /* Index of root page */
          133  +  int wrFlag,              /* 1 for writing.  0 for read-only */
          134  +  struct KeyInfo*,         /* First argument to compare function */
          135  +  BtCursor **ppCursor      /* Returned cursor */
   137    136   );
   138    137   
   139    138   int sqlite3BtreeCloseCursor(BtCursor*);
   140    139   int sqlite3BtreeMoveto(BtCursor*,const void *pKey,i64 nKey,int bias,int *pRes);
   141    140   int sqlite3BtreeDelete(BtCursor*);
   142    141   int sqlite3BtreeInsert(BtCursor*, const void *pKey, i64 nKey,
   143    142                                     const void *pData, int nData,

Changes to src/btreeInt.h.

     5      5   ** a legal notice, here is a blessing:
     6      6   **
     7      7   **    May you do good and not evil.
     8      8   **    May you find forgiveness for yourself and forgive others.
     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12         -** $Id: btreeInt.h,v 1.17 2008/03/04 17:45:01 mlcreech Exp $
           12  +** $Id: btreeInt.h,v 1.18 2008/03/25 00:22:21 drh Exp $
    13     13   **
    14     14   ** This file implements a external (disk-based) database using BTrees.
    15     15   ** For a detailed discussion of BTrees, refer to
    16     16   **
    17     17   **     Donald E. Knuth, THE ART OF COMPUTER PROGRAMMING, Volume 3:
    18     18   **     "Sorting And Searching", pages 473-480. Addison-Wesley
    19     19   **     Publishing Company, Reading, Massachusetts.
................................................................................
   431    431   ** Fields in this structure are accessed under the BtShared.mutex
   432    432   ** found at self->pBt->mutex. 
   433    433   */
   434    434   struct BtCursor {
   435    435     Btree *pBtree;            /* The Btree to which this cursor belongs */
   436    436     BtShared *pBt;            /* The BtShared this cursor points to */
   437    437     BtCursor *pNext, *pPrev;  /* Forms a linked list of all cursors */
   438         -  int (*xCompare)(void*,int,const void*,int,const void*); /* Key comp func */
   439         -  void *pArg;               /* First arg to xCompare() */
          438  +  struct KeyInfo *pKeyInfo; /* Argument passed to comparison function */
   440    439     Pgno pgnoRoot;            /* The root page of this tree */
   441    440     MemPage *pPage;           /* Page that contains the entry */
   442    441     int idx;                  /* Index of the entry in pPage->aCell[] */
   443    442     CellInfo info;            /* A parse of the cell we are pointing at */
   444    443     u8 wrFlag;                /* True if writable */
   445    444     u8 eState;                /* One of the CURSOR_XXX constants (see below) */
   446    445     void *pKey;      /* Saved key that was cursor's last known position */

Changes to src/prepare.c.

     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   ** This file contains the implementation of the sqlite3_prepare()
    13     13   ** interface, and routines that contribute to loading the database schema
    14     14   ** from disk.
    15     15   **
    16         -** $Id: prepare.c,v 1.80 2008/03/20 14:03:29 drh Exp $
           16  +** $Id: prepare.c,v 1.81 2008/03/25 00:22:21 drh Exp $
    17     17   */
    18     18   #include "sqliteInt.h"
    19     19   #include <ctype.h>
    20     20   
    21     21   /*
    22     22   ** Fill the InitData structure with an error message that indicates
    23     23   ** that the database is corrupt.
................................................................................
   204    204     if( pDb->pBt==0 ){
   205    205       if( !OMIT_TEMPDB && iDb==1 ){
   206    206         DbSetProperty(db, 1, DB_SchemaLoaded);
   207    207       }
   208    208       return SQLITE_OK;
   209    209     }
   210    210     sqlite3BtreeEnter(pDb->pBt);
   211         -  rc = sqlite3BtreeCursor(pDb->pBt, MASTER_ROOT, 0, 0, 0, &curMain);
          211  +  rc = sqlite3BtreeCursor(pDb->pBt, MASTER_ROOT, 0, 0, &curMain);
   212    212     if( rc!=SQLITE_OK && rc!=SQLITE_EMPTY ){
   213    213       sqlite3SetString(pzErrMsg, sqlite3ErrStr(rc), (char*)0);
   214    214       sqlite3BtreeLeave(pDb->pBt);
   215    215       goto error_out;
   216    216     }
   217    217   
   218    218     /* Get the database meta information.
................................................................................
   442    442     int allOk = 1;
   443    443   
   444    444     assert( sqlite3_mutex_held(db->mutex) );
   445    445     for(iDb=0; allOk && iDb<db->nDb; iDb++){
   446    446       Btree *pBt;
   447    447       pBt = db->aDb[iDb].pBt;
   448    448       if( pBt==0 ) continue;
   449         -    rc = sqlite3BtreeCursor(pBt, MASTER_ROOT, 0, 0, 0, &curTemp);
          449  +    rc = sqlite3BtreeCursor(pBt, MASTER_ROOT, 0, 0, &curTemp);
   450    450       if( rc==SQLITE_OK ){
   451    451         rc = sqlite3BtreeGetMeta(pBt, 1, (u32 *)&cookie);
   452    452         if( rc==SQLITE_OK && cookie!=db->aDb[iDb].pSchema->schema_cookie ){
   453    453           allOk = 0;
   454    454         }
   455    455         sqlite3BtreeCloseCursor(curTemp);
   456    456       }

Changes to src/test3.c.

     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   ** Code for testing the btree.c module in SQLite.  This code
    13     13   ** is not included in the SQLite library.  It is used for automated
    14     14   ** testing of the SQLite library.
    15     15   **
    16         -** $Id: test3.c,v 1.91 2008/03/04 17:45:02 mlcreech Exp $
           16  +** $Id: test3.c,v 1.92 2008/03/25 00:22:21 drh Exp $
    17     17   */
    18     18   #include "sqliteInt.h"
    19     19   #include "btreeInt.h"
    20     20   #include "tcl.h"
    21     21   #include <stdlib.h>
    22     22   #include <string.h>
    23     23   
................................................................................
   708    708          " ID TABLENUM WRITEABLE\"", 0);
   709    709       return TCL_ERROR;
   710    710     }
   711    711     pBt = sqlite3TextToPtr(argv[1]);
   712    712     if( Tcl_GetInt(interp, argv[2], &iTable) ) return TCL_ERROR;
   713    713     if( Tcl_GetBoolean(interp, argv[3], &wrFlag) ) return TCL_ERROR;
   714    714     sqlite3BtreeEnter(pBt);
   715         -  rc = sqlite3BtreeCursor(pBt, iTable, wrFlag, 0, 0, &pCur);
          715  +  rc = sqlite3BtreeCursor(pBt, iTable, wrFlag, 0, &pCur);
   716    716     sqlite3BtreeLeave(pBt);
   717    717     if( rc ){
   718    718       Tcl_AppendResult(interp, errorName(rc), 0);
   719    719       return TCL_ERROR;
   720    720     }
   721    721     sqlite3_snprintf(sizeof(zBuf), zBuf,"%p", pCur);
   722    722     Tcl_AppendResult(interp, zBuf, 0);

Changes to src/vdbe.c.

    39     39   **
    40     40   ** Various scripts scan this source file in order to generate HTML
    41     41   ** documentation, headers files, or other derived files.  The formatting
    42     42   ** of the code in this file is, therefore, important.  See other comments
    43     43   ** in this file for details.  If in doubt, do not deviate from existing
    44     44   ** commenting and indentation practices when changing or adding code.
    45     45   **
    46         -** $Id: vdbe.c,v 1.715 2008/03/21 17:13:13 drh Exp $
           46  +** $Id: vdbe.c,v 1.716 2008/03/25 00:22:21 drh Exp $
    47     47   */
    48     48   #include "sqliteInt.h"
    49     49   #include <ctype.h>
    50     50   #include "vdbeInt.h"
    51     51   
    52     52   /*
    53     53   ** The following global variable is incremented every time a cursor
................................................................................
  2050   2050   }
  2051   2051   
  2052   2052   /* Opcode: MakeRecord P1 P2 P3 P4 *
  2053   2053   **
  2054   2054   ** Convert P2 registers beginning with P1 into a single entry
  2055   2055   ** suitable for use as a data record in a database table or as a key
  2056   2056   ** in an index.  The details of the format are irrelavant as long as
  2057         -** the OP_Column opcode can decode the record later and as long as the
  2058         -** sqlite3VdbeRecordCompare function will correctly compare two encoded
  2059         -** records.  Refer to source code comments for the details of the record
         2057  +** the OP_Column opcode can decode the record later.
         2058  +** Refer to source code comments for the details of the record
  2060   2059   ** format.
  2061   2060   **
  2062   2061   ** P4 may be a string that is P1 characters long.  The nth character of the
  2063   2062   ** string indicates the column affinity that should be used for the nth
  2064   2063   ** field of the index key.
  2065   2064   **
  2066   2065   ** The mapping from character to affinity is given by the SQLITE_AFF_
................................................................................
  2515   2514       p2 = pIn2->u.i;
  2516   2515       assert( p2>=2 );
  2517   2516     }
  2518   2517     assert( i>=0 );
  2519   2518     pCur = allocateCursor(p, i, iDb);
  2520   2519     if( pCur==0 ) goto no_mem;
  2521   2520     pCur->nullRow = 1;
  2522         -  /* We always provide a key comparison function.  If the table being
  2523         -  ** opened is of type INTKEY, the comparision function will be ignored. */
  2524         -  rc = sqlite3BtreeCursor(pX, p2, wrFlag,
  2525         -           sqlite3VdbeRecordCompare, pOp->p4.p,
  2526         -           &pCur->pCursor);
         2521  +  rc = sqlite3BtreeCursor(pX, p2, wrFlag, pOp->p4.p, &pCur->pCursor);
  2527   2522     if( pOp->p4type==P4_KEYINFO ){
  2528   2523       pCur->pKeyInfo = pOp->p4.pKeyInfo;
  2529   2524       pCur->pIncrKey = &pCur->pKeyInfo->incrKey;
  2530   2525       pCur->pKeyInfo->enc = ENC(p->db);
  2531   2526     }else{
  2532   2527       pCur->pKeyInfo = 0;
  2533   2528       pCur->pIncrKey = &pCur->bogusIncrKey;
................................................................................
  2621   2616       */
  2622   2617       if( pOp->p4.pKeyInfo ){
  2623   2618         int pgno;
  2624   2619         assert( pOp->p4type==P4_KEYINFO );
  2625   2620         rc = sqlite3BtreeCreateTable(pCx->pBt, &pgno, BTREE_ZERODATA); 
  2626   2621         if( rc==SQLITE_OK ){
  2627   2622           assert( pgno==MASTER_ROOT+1 );
  2628         -        rc = sqlite3BtreeCursor(pCx->pBt, pgno, 1, sqlite3VdbeRecordCompare,
  2629         -            pOp->p4.z, &pCx->pCursor);
         2623  +        rc = sqlite3BtreeCursor(pCx->pBt, pgno, 1, 
         2624  +                                (KeyInfo*)pOp->p4.z, &pCx->pCursor);
  2630   2625           pCx->pKeyInfo = pOp->p4.pKeyInfo;
  2631   2626           pCx->pKeyInfo->enc = ENC(p->db);
  2632   2627           pCx->pIncrKey = &pCx->pKeyInfo->incrKey;
  2633   2628         }
  2634   2629         pCx->isTable = 0;
  2635   2630       }else{
  2636         -      rc = sqlite3BtreeCursor(pCx->pBt, MASTER_ROOT, 1, 0, 0, &pCx->pCursor);
         2631  +      rc = sqlite3BtreeCursor(pCx->pBt, MASTER_ROOT, 1, 0, &pCx->pCursor);
  2637   2632         pCx->isTable = 1;
  2638   2633         pCx->pIncrKey = &pCx->bogusIncrKey;
  2639   2634       }
  2640   2635     }
  2641   2636     pCx->nField = pOp->p2;
  2642   2637     pCx->isIndex = !pCx->isTable;
  2643   2638     break;

Changes to src/vdbe.h.

    11     11   *************************************************************************
    12     12   ** Header file for the Virtual DataBase Engine (VDBE)
    13     13   **
    14     14   ** This header defines the interface to the virtual database engine
    15     15   ** or VDBE.  The VDBE implements an abstract machine that runs a
    16     16   ** simple program to access and modify the underlying database.
    17     17   **
    18         -** $Id: vdbe.h,v 1.126 2008/03/22 01:07:18 drh Exp $
           18  +** $Id: vdbe.h,v 1.127 2008/03/25 00:22:21 drh Exp $
    19     19   */
    20     20   #ifndef _SQLITE_VDBE_H_
    21     21   #define _SQLITE_VDBE_H_
    22     22   #include <stdio.h>
    23     23   
    24     24   /*
    25     25   ** A single VDBE is an opaque structure named "Vdbe".  Only routines
................................................................................
    30     30   
    31     31   /*
    32     32   ** The names of the following types declared in vdbeInt.h are required
    33     33   ** for the VdbeOp definition.
    34     34   */
    35     35   typedef struct VdbeFunc VdbeFunc;
    36     36   typedef struct Mem Mem;
           37  +typedef struct VdbeParsedRecord VdbeParsedRecord;
    37     38   
    38     39   /*
    39     40   ** A single instruction of the virtual machine has an opcode
    40     41   ** and as many as three operands.  The instruction is recorded
    41     42   ** as an instance of the following structure:
    42     43   */
    43     44   struct VdbeOp {
................................................................................
   176    177   int sqlite3VdbeReset(Vdbe*);
   177    178   void sqlite3VdbeSetNumCols(Vdbe*,int);
   178    179   int sqlite3VdbeSetColName(Vdbe*, int, int, const char *, int);
   179    180   void sqlite3VdbeCountChanges(Vdbe*);
   180    181   sqlite3 *sqlite3VdbeDb(Vdbe*);
   181    182   void sqlite3VdbeSetSql(Vdbe*, const char *z, int n);
   182    183   void sqlite3VdbeSwap(Vdbe*,Vdbe*);
          184  +
          185  +VdbeParsedRecord *sqlite3VdbeRecordParse(KeyInfo*,int,const void*,void*,int);
          186  +void sqlite3VdbeRecordUnparse(VdbeParsedRecord*);
          187  +int sqlite3VdbeRecordCompareParsed(int,const void*,VdbeParsedRecord*);
          188  +
   183    189   
   184    190   #ifndef NDEBUG
   185    191     void sqlite3VdbeComment(Vdbe*, const char*, ...);
   186    192   # define VdbeComment(X)  sqlite3VdbeComment X
   187    193   #else
   188    194   # define VdbeComment(X)
   189    195   #endif
   190    196   
   191    197   #endif

Changes to src/vdbeInt.h.

   358    358   int sqlite3VdbeSerialGet(const unsigned char*, u32, Mem*);
   359    359   void sqlite3VdbeDeleteAuxData(VdbeFunc*, int);
   360    360   
   361    361   int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *);
   362    362   int sqlite3VdbeIdxKeyCompare(Cursor*,int,const unsigned char*,int*);
   363    363   int sqlite3VdbeIdxRowid(BtCursor *, i64 *);
   364    364   int sqlite3MemCompare(const Mem*, const Mem*, const CollSeq*);
   365         -int sqlite3VdbeRecordCompare(void*,int,const void*,int, const void*);
   366    365   int sqlite3VdbeIdxRowidLen(const u8*);
   367    366   int sqlite3VdbeExec(Vdbe*);
   368    367   int sqlite3VdbeList(Vdbe*);
   369    368   int sqlite3VdbeHalt(Vdbe*);
   370    369   int sqlite3VdbeChangeEncoding(Mem *, int);
   371    370   int sqlite3VdbeMemTooBig(Mem*);
   372    371   int sqlite3VdbeMemCopy(Mem*, const Mem*);

Changes to src/vdbeaux.c.

  2126   2126   **     x = sqlite3GetVarint32( A, &B );
  2127   2127   **
  2128   2128   **     x = GetVarint( A, B );
  2129   2129   **
  2130   2130   */
  2131   2131   #define GetVarint(A,B)  ((B = *(A))<=0x7f ? 1 : sqlite3GetVarint32(A, &B))
  2132   2132   
         2133  +#if 0
  2133   2134   /*
  2134   2135   ** This function compares the two table rows or index records specified by 
  2135   2136   ** {nKey1, pKey1} and {nKey2, pKey2}, returning a negative, zero
  2136   2137   ** or positive integer if {nKey1, pKey1} is less than, equal to or 
  2137   2138   ** greater than {nKey2, pKey2}.  Both Key1 and Key2 must be byte strings
  2138   2139   ** composed by the OP_MakeRecord opcode of the VDBE.
  2139   2140   **
................................................................................
  2212   2213     }else if( pKeyInfo->aSortOrder && i<pKeyInfo->nField
  2213   2214                  && pKeyInfo->aSortOrder[i] ){
  2214   2215       rc = -rc;
  2215   2216     }
  2216   2217   
  2217   2218     return rc;
  2218   2219   }
         2220  +#endif
         2221  +
         2222  +/*
         2223  +** An instance of the following structure holds information about a
         2224  +** single index record that has already been parsed out into individual
         2225  +** values.
         2226  +**
         2227  +** A record is an object that contains one or more fields of data.
         2228  +** Records are used to store the content of a table row and to store
         2229  +** the key of an index.  A blob encoding of a record is created by
         2230  +** the OP_MakeRecord opcode of the VDBE and is disassemblied by the
         2231  +** OP_Column opcode.
         2232  +**
         2233  +** This structure holds a record that has already been disassembled
         2234  +** into its constitutent fields.
         2235  +*/
         2236  +struct VdbeParsedRecord {
         2237  +  KeyInfo *pKeyInfo;  /* Collation and sort-order information */
         2238  +  u16 nField;         /* Number of entries in apMem[] */
         2239  +  u8 needFree;        /* True if memory obtained from sqlite3_malloc() */
         2240  +  u8 needDestroy;     /* True if apMem[]s should be destroyed on close */
         2241  +  Mem *apMem[1];      /* Values */
         2242  +};
         2243  +
         2244  +/*
         2245  +** Given the nKey-byte encoding of a record in pKey[], parse the
         2246  +** record into a VdbeParsedRecord structure.  Return a pointer to
         2247  +** that structure.
         2248  +**
         2249  +** The calling function might provide szSpace bytes of memory
         2250  +** space at pSpace.  This space can be used to hold the returned
         2251  +** VDbeParsedRecord structure if it is large enough.  If it is
         2252  +** not big enough, space is obtained from sqlite3_malloc().
         2253  +**
         2254  +** The returned structure should be closed by a call to
         2255  +** sqlite3VdbeRecordUnparse().
         2256  +*/ 
         2257  +VdbeParsedRecord *sqlite3VdbeRecordParse(
         2258  +  KeyInfo *pKeyInfo,     /* Information about the record format */
         2259  +  int nKey,              /* Size of the binary record */
         2260  +  const void *pKey,      /* The binary record */
         2261  +  void *pSpace,          /* Space available to hold resulting object */
         2262  +  int szSpace            /* Size of pSpace[] in bytes */
         2263  +){
         2264  +  const unsigned char *aKey = (const unsigned char *)pKey;
         2265  +  VdbeParsedRecord *p;
         2266  +  int nByte;
         2267  +  int i, idx, d;
         2268  +  u32 szHdr;
         2269  +  Mem *pMem;
         2270  +  
         2271  +  nByte = sizeof(*p) + sizeof(Mem*)*pKeyInfo->nField
         2272  +                     + sizeof(Mem)*(pKeyInfo->nField+1);
         2273  +  if( nByte>szSpace ){
         2274  +    p = sqlite3DbMallocRaw(pKeyInfo->db, nByte);
         2275  +    if( p==0 ) return 0;
         2276  +    p->needFree = 1;
         2277  +  }else{
         2278  +    p = pSpace;
         2279  +    p->needFree = 0;
         2280  +  }
         2281  +  p->pKeyInfo = pKeyInfo;
         2282  +  p->nField = pKeyInfo->nField + 1;
         2283  +  p->needDestroy = 1;
         2284  +  pMem = (Mem*)&p->apMem[pKeyInfo->nField+1];
         2285  +  idx = GetVarint(aKey, szHdr);
         2286  +  d = szHdr;
         2287  +  i = 0;
         2288  +  while( idx<szHdr && i<p->nField ){
         2289  +    u32 serial_type;
         2290  +
         2291  +    idx += GetVarint( aKey+idx, serial_type);
         2292  +    if( d>=nKey && sqlite3VdbeSerialTypeLen(serial_type)>0 ) break;
         2293  +    pMem->enc = pKeyInfo->enc;
         2294  +    pMem->db = pKeyInfo->db;
         2295  +    pMem->flags = 0;
         2296  +    d += sqlite3VdbeSerialGet(&aKey[d], serial_type, pMem);
         2297  +    p->apMem[i++] = pMem++;
         2298  +  }
         2299  +  p->nField = i;
         2300  +  return (void*)p;
         2301  +}
         2302  +
         2303  +/*
         2304  +** This routine destroys a VdbeParsedRecord object
         2305  +*/
         2306  +void sqlite3VdbeRecordUnparse(VdbeParsedRecord *p){
         2307  +  if( p ){
         2308  +    if( p->needDestroy ){
         2309  +      int i;
         2310  +      for(i=0; i<p->nField; i++){
         2311  +        if( p->apMem[i]->flags & MEM_Dyn ){
         2312  +          sqlite3VdbeMemRelease(p->apMem[i]);
         2313  +        }
         2314  +      }
         2315  +    }
         2316  +    if( p->needFree ){
         2317  +      sqlite3_free(p);
         2318  +    }
         2319  +  }
         2320  +}
         2321  +
         2322  +/*
         2323  +** This function compares the two table rows or index records
         2324  +** specified by {nKey1, pKey1} and pPKey2.  It returns a negative, zero
         2325  +** or positive integer if {nKey1, pKey1} is less than, equal to or 
         2326  +** greater than pPKey2.  The {nKey1, pKey1} key must be a blob
         2327  +** created by th OP_MakeRecord opcode of the VDBE.  The pPKey2
         2328  +** key must be a parsed key such as obtained from
         2329  +** sqlite3VdbeParseRecord.
         2330  +**
         2331  +** Key1 and Key2 do not have to contain the same number of fields.
         2332  +** But if the lengths differ, Key2 must be the shorter of the two.
         2333  +**
         2334  +** Historical note: In earlier versions of this routine both Key1
         2335  +** and Key2 were blobs obtained from OP_MakeRecord.  But we found
         2336  +** that in typical use the same Key2 would be submitted multiple times
         2337  +** in a row.  So an optimization was added to parse the Key2 key
         2338  +** separately and submit the parsed version.  In this way, we avoid
         2339  +** parsing the same Key2 multiple times in a row.
         2340  +*/
         2341  +int sqlite3VdbeRecordCompareParsed(
         2342  +  int nKey1, const void *pKey1, 
         2343  +  VdbeParsedRecord *pPKey2
         2344  +){
         2345  +  u32 d1;            /* Offset into aKey[] of next data element */
         2346  +  u32 idx1;          /* Offset into aKey[] of next header element */
         2347  +  u32 szHdr1;        /* Number of bytes in header */
         2348  +  int i = 0;
         2349  +  int nField;
         2350  +  int rc = 0;
         2351  +  const unsigned char *aKey1 = (const unsigned char *)pKey1;
         2352  +  KeyInfo *pKeyInfo;
         2353  +  Mem mem1;
         2354  +
         2355  +  pKeyInfo = pPKey2->pKeyInfo;
         2356  +  mem1.enc = pKeyInfo->enc;
         2357  +  mem1.db = pKeyInfo->db;
         2358  +  mem1.flags = 0;
         2359  +  
         2360  +  idx1 = GetVarint(aKey1, szHdr1);
         2361  +  d1 = szHdr1;
         2362  +  nField = pKeyInfo->nField;
         2363  +  while( idx1<szHdr1 && i<pPKey2->nField ){
         2364  +    u32 serial_type1;
         2365  +
         2366  +    /* Read the serial types for the next element in each key. */
         2367  +    idx1 += GetVarint( aKey1+idx1, serial_type1 );
         2368  +    if( d1>=nKey1 && sqlite3VdbeSerialTypeLen(serial_type1)>0 ) break;
         2369  +
         2370  +    /* Extract the values to be compared.
         2371  +    */
         2372  +    d1 += sqlite3VdbeSerialGet(&aKey1[d1], serial_type1, &mem1);
         2373  +
         2374  +    /* Do the comparison
         2375  +    */
         2376  +    rc = sqlite3MemCompare(&mem1, pPKey2->apMem[i],
         2377  +                           i<nField ? pKeyInfo->aColl[i] : 0);
         2378  +    if( mem1.flags&MEM_Dyn ) sqlite3VdbeMemRelease(&mem1);
         2379  +    if( rc!=0 ){
         2380  +      break;
         2381  +    }
         2382  +    i++;
         2383  +  }
         2384  +
         2385  +  /* One of the keys ran out of fields, but all the fields up to that point
         2386  +  ** were equal. If the incrKey flag is true, then the second key is
         2387  +  ** treated as larger.
         2388  +  */
         2389  +  if( rc==0 ){
         2390  +    if( pKeyInfo->incrKey ){
         2391  +      rc = -1;
         2392  +    }else if( !pKeyInfo->prefixIsEqual ){
         2393  +      if( d1<nKey1 ){
         2394  +        rc = 1;
         2395  +      }
         2396  +    }
         2397  +  }else if( pKeyInfo->aSortOrder && i<pKeyInfo->nField
         2398  +               && pKeyInfo->aSortOrder[i] ){
         2399  +    rc = -rc;
         2400  +  }
         2401  +
         2402  +  return rc;
         2403  +}
  2219   2404   
  2220   2405   /*
  2221   2406   ** The argument is an index entry composed using the OP_MakeRecord opcode.
  2222   2407   ** The last entry in this record should be an integer (specifically
  2223   2408   ** an integer rowid).  This routine returns the number of bytes in
  2224   2409   ** that integer.
  2225   2410   */
................................................................................
  2281   2466     int *res                    /* Write the comparison result here */
  2282   2467   ){
  2283   2468     i64 nCellKey = 0;
  2284   2469     int rc;
  2285   2470     BtCursor *pCur = pC->pCursor;
  2286   2471     int lenRowid;
  2287   2472     Mem m;
         2473  +  VdbeParsedRecord *pRec;
         2474  +  char zSpace[200];
  2288   2475   
  2289   2476     sqlite3BtreeKeySize(pCur, &nCellKey);
  2290   2477     if( nCellKey<=0 ){
  2291   2478       *res = 0;
  2292   2479       return SQLITE_OK;
  2293   2480     }
  2294   2481     m.db = 0;
  2295   2482     m.flags = 0;
  2296   2483     rc = sqlite3VdbeMemFromBtree(pC->pCursor, 0, nCellKey, 1, &m);
  2297   2484     if( rc ){
  2298   2485       return rc;
  2299   2486     }
  2300   2487     lenRowid = sqlite3VdbeIdxRowidLen((u8*)m.z);
  2301         -  *res = sqlite3VdbeRecordCompare(pC->pKeyInfo, m.n-lenRowid, m.z, nKey, pKey);
         2488  +  pRec = sqlite3VdbeRecordParse(pC->pKeyInfo, nKey, pKey,
         2489  +                                zSpace, sizeof(zSpace));
         2490  +  if( pRec==0 ){
         2491  +    return SQLITE_NOMEM;
         2492  +  }
         2493  +  *res = sqlite3VdbeRecordCompareParsed(m.n-lenRowid, m.z, pRec);
         2494  +  sqlite3VdbeRecordUnparse(pRec);
  2302   2495     sqlite3VdbeMemRelease(&m);
  2303   2496     return SQLITE_OK;
  2304   2497   }
  2305   2498   
  2306   2499   /*
  2307   2500   ** This routine sets the value to be returned by subsequent calls to
  2308   2501   ** sqlite3_changes() on the database handle 'db'. 

Deleted test/btree.test.

     1         -# 2001 September 15
     2         -#
     3         -# The author disclaims copyright to this source code.  In place of
     4         -# a legal notice, here is a blessing:
     5         -#
     6         -#    May you do good and not evil.
     7         -#    May you find forgiveness for yourself and forgive others.
     8         -#    May you share freely, never taking more than you give.
     9         -#
    10         -#***********************************************************************
    11         -# This file implements regression tests for SQLite library.  The
    12         -# focus of this script is btree database backend
    13         -#
    14         -# $Id: btree.test,v 1.43 2008/02/02 20:47:38 drh Exp $
    15         -
    16         -
    17         -set testdir [file dirname $argv0]
    18         -source $testdir/tester.tcl
    19         -
    20         -ifcapable default_autovacuum {
    21         -  finish_test
    22         -  return
    23         -}
    24         -
    25         -# Basic functionality.  Open and close a database.
    26         -#
    27         -do_test btree-1.1 {
    28         -  file delete -force test1.bt
    29         -  file delete -force test1.bt-journal
    30         -  set rc [catch {btree_open test1.bt 2000 0} ::b1]
    31         -} {0}
    32         -
    33         -# The second element of the list returned by btree_pager_stats is the
    34         -# number of pages currently checked out.  We'll be checking this value
    35         -# frequently during this test script, to make sure the btree library
    36         -# is properly releasing the pages it checks out, and thus avoiding
    37         -# page leaks.
    38         -#
    39         -do_test btree-1.1.1 {
    40         -  lindex [btree_pager_stats $::b1] 1
    41         -} {0}
    42         -do_test btree-1.2 {
    43         -  set rc [catch {btree_open test1.bt 2000 0} ::b2]
    44         -} {0}
    45         -do_test btree-1.3 {
    46         -  set rc [catch {btree_close $::b2} msg]
    47         -  lappend rc $msg
    48         -} {0 {}}
    49         -
    50         -# Do an insert and verify that the database file grows in size.
    51         -#
    52         -do_test btree-1.4 {
    53         -  set rc [catch {btree_begin_transaction $::b1} msg]
    54         -  lappend rc $msg
    55         -} {0 {}}
    56         -do_test btree-1.4.1 {
    57         -  lindex [btree_pager_stats $::b1] 1
    58         -} {1}
    59         -do_test btree-1.5 {
    60         -  set rc [catch {btree_cursor $::b1 1 1} ::c1]
    61         -  if {$rc} {lappend rc $::c1}
    62         -  set rc
    63         -} {0}
    64         -do_test btree-1.6 {
    65         -  set rc [catch {btree_insert $::c1 100 1.00} msg]
    66         -  lappend rc $msg
    67         -} {0 {}}
    68         -do_test btree-1.7 {
    69         -  btree_move_to $::c1 100
    70         -  btree_key $::c1
    71         -} {100}
    72         -do_test btree-1.8 {
    73         -  btree_data $::c1
    74         -} {1.00}
    75         -do_test btree-1.9 {
    76         -  set rc [catch {btree_close_cursor $::c1} msg]
    77         -  lappend rc $msg
    78         -} {0 {}}
    79         -do_test btree-1.10 {
    80         -  set rc [catch {btree_commit $::b1} msg]
    81         -  lappend rc $msg
    82         -} {0 {}}
    83         -do_test btree-1.11 {
    84         -  file size test1.bt
    85         -} {1024}
    86         -do_test btree-1.12 {
    87         -  lindex [btree_pager_stats $::b1] 1
    88         -} {0}
    89         -
    90         -# Reopen the database and attempt to read the record that we wrote.
    91         -#
    92         -do_test btree-2.1 {
    93         -  set rc [catch {btree_cursor $::b1 1 1} ::c1]
    94         -  if {$rc} {lappend rc $::c1}
    95         -  set rc
    96         -} {0}
    97         -do_test btree-2.1.1 {
    98         -  btree_cursor_list $::b1
    99         -} {}
   100         -do_test btree-2.2 {
   101         -  btree_move_to $::c1 99
   102         -} {1}
   103         -do_test btree-2.3 {
   104         -  btree_move_to $::c1 101
   105         -} {-1}
   106         -do_test btree-2.4 {
   107         -  btree_move_to $::c1 100
   108         -} {0}
   109         -do_test btree-2.5 {
   110         -  btree_key $::c1
   111         -} {100}
   112         -do_test btree-2.6 {
   113         -  btree_data $::c1
   114         -} {1.00}
   115         -do_test btree-2.7 {
   116         -  lindex [btree_pager_stats $::b1] 1
   117         -} {1}
   118         -
   119         -# Do some additional inserts
   120         -#
   121         -do_test btree-3.1 {
   122         -  btree_begin_transaction $::b1
   123         -  btree_insert $::c1 200 2.00
   124         -  btree_move_to $::c1 200
   125         -  btree_key $::c1
   126         -} {200}
   127         -do_test btree-3.1.1 {
   128         -  lindex [btree_pager_stats $::b1] 1
   129         -} {1}
   130         -do_test btree-3.2 {
   131         -  btree_insert $::c1 300 3.00
   132         -  btree_move_to $::c1 300
   133         -  btree_key $::c1
   134         -} {300}
   135         -do_test btree-3.4 {
   136         -  btree_insert $::c1 400 4.00
   137         -  btree_move_to $::c1 400
   138         -  btree_key $::c1
   139         -} {400}
   140         -do_test btree-3.5 {
   141         -  btree_insert $::c1 500 5.00
   142         -  btree_move_to $::c1 500
   143         -  btree_key $::c1
   144         -} {500}
   145         -do_test btree-3.6 {
   146         -  btree_insert $::c1 600 6.00
   147         -  btree_move_to $::c1 600
   148         -  btree_key $::c1
   149         -} {600}
   150         -#btree_page_dump $::b1 2
   151         -do_test btree-3.7 {
   152         -  set rc [btree_move_to $::c1 0]
   153         -  expr {$rc>0}
   154         -} {1}
   155         -do_test btree-3.8 {
   156         -  btree_key $::c1
   157         -} {100}
   158         -do_test btree-3.9 {
   159         -  btree_data $::c1
   160         -} {1.00}
   161         -do_test btree-3.10 {
   162         -  btree_next $::c1
   163         -  btree_key $::c1
   164         -} {200}
   165         -do_test btree-3.11 {
   166         -  btree_data $::c1
   167         -} {2.00}
   168         -do_test btree-3.12 {
   169         -  btree_next $::c1
   170         -  btree_key $::c1
   171         -} {300}
   172         -do_test btree-3.13 {
   173         -  btree_data $::c1
   174         -} {3.00}
   175         -do_test btree-3.14 {
   176         -  btree_next $::c1
   177         -  btree_key $::c1
   178         -} {400}
   179         -do_test btree-3.15 {
   180         -  btree_data $::c1
   181         -} {4.00}
   182         -do_test btree-3.16 {
   183         -  btree_next $::c1
   184         -  btree_key $::c1
   185         -} {500}
   186         -do_test btree-3.17 {
   187         -  btree_data $::c1
   188         -} {5.00}
   189         -do_test btree-3.18 {
   190         -  btree_next $::c1
   191         -  btree_key $::c1
   192         -} {600}
   193         -do_test btree-3.19 {
   194         -  btree_data $::c1
   195         -} {6.00}
   196         -do_test btree-3.20.1 {
   197         -  btree_next $::c1
   198         -  btree_key $::c1
   199         -} {0}
   200         -do_test btree-3.20.2 {
   201         -  btree_eof $::c1
   202         -} {1}
   203         -# This test case used to test that one couldn't request data from an 
   204         -# invalid cursor. That is now an assert()ed condition.
   205         -#
   206         -# do_test btree-3.21 {
   207         -#   set rc [catch {btree_data $::c1} res]
   208         -#   lappend rc $res
   209         -# } {1 SQLITE_INTERNAL}
   210         -
   211         -# Commit the changes, reopen and reread the data
   212         -#
   213         -do_test btree-3.22 {
   214         -  set rc [catch {btree_close_cursor $::c1} msg]
   215         -  lappend rc $msg
   216         -} {0 {}}
   217         -do_test btree-3.22.1 {
   218         -  lindex [btree_pager_stats $::b1] 1
   219         -} {1}
   220         -do_test btree-3.23 {
   221         -  set rc [catch {btree_commit $::b1} msg]
   222         -  lappend rc $msg
   223         -} {0 {}}
   224         -do_test btree-3.23.1 {
   225         -  lindex [btree_pager_stats $::b1] 1
   226         -} {0}
   227         -do_test btree-3.24 {
   228         -  file size test1.bt
   229         -} {1024}
   230         -do_test btree-3.25 {
   231         -  set rc [catch {btree_cursor $::b1 1 1} ::c1]
   232         -  if {$rc} {lappend rc $::c1}
   233         -  set rc
   234         -} {0}
   235         -do_test btree-3.25.1 {
   236         -  lindex [btree_pager_stats $::b1] 1
   237         -} {1}
   238         -do_test btree-3.26 {
   239         -  set rc [btree_move_to $::c1 0]
   240         -  expr {$rc>0}
   241         -} {1}
   242         -do_test btree-3.27 {
   243         -  btree_key $::c1
   244         -} {100}
   245         -do_test btree-3.28 {
   246         -  btree_data $::c1
   247         -} {1.00}
   248         -do_test btree-3.29 {
   249         -  btree_next $::c1
   250         -  btree_key $::c1
   251         -} {200}
   252         -do_test btree-3.30 {
   253         -  btree_data $::c1
   254         -} {2.00}
   255         -do_test btree-3.31 {
   256         -  btree_next $::c1
   257         -  btree_key $::c1
   258         -} {300}
   259         -do_test btree-3.32 {
   260         -  btree_data $::c1
   261         -} {3.00}
   262         -do_test btree-3.33 {
   263         -  btree_next $::c1
   264         -  btree_key $::c1
   265         -} {400}
   266         -do_test btree-3.34 {
   267         -  btree_data $::c1
   268         -} {4.00}
   269         -do_test btree-3.35 {
   270         -  btree_next $::c1
   271         -  btree_key $::c1
   272         -} {500}
   273         -do_test btree-3.36 {
   274         -  btree_data $::c1
   275         -} {5.00}
   276         -do_test btree-3.37 {
   277         -  btree_next $::c1
   278         -  btree_key $::c1
   279         -} {600}
   280         -do_test btree-3.38 {
   281         -  btree_data $::c1
   282         -} {6.00}
   283         -do_test btree-3.39 {
   284         -  btree_next $::c1
   285         -  btree_key $::c1
   286         -} {0}
   287         -# This test case used to test that requesting data from an invalid cursor
   288         -# returned SQLITE_INTERNAL. That is now an assert()ed condition.
   289         -#
   290         -# do_test btree-3.40 {
   291         -#   set rc [catch {btree_data $::c1} res]
   292         -#   lappend rc $res
   293         -# } {1 SQLITE_INTERNAL}
   294         -do_test btree-3.41 {
   295         -  lindex [btree_pager_stats $::b1] 1
   296         -} {1}
   297         -
   298         -
   299         -# Now try a delete
   300         -#
   301         -do_test btree-4.1 {
   302         -  btree_begin_transaction $::b1
   303         -  btree_move_to $::c1 100
   304         -  btree_key $::c1
   305         -} {100}
   306         -do_test btree-4.1.1 {
   307         -  lindex [btree_pager_stats $::b1] 1
   308         -} {1}
   309         -do_test btree-4.2 {
   310         -  btree_delete $::c1
   311         -} {}
   312         -do_test btree-4.3 {
   313         -  btree_move_to $::c1 100
   314         -  btree_key $::c1
   315         -} {200}
   316         -do_test btree-4.4 {
   317         -  btree_next $::c1
   318         -  btree_key $::c1
   319         -} {300}
   320         -do_test btree-4.5 {
   321         -  btree_next $::c1
   322         -  btree_key $::c1
   323         -} {400}
   324         -do_test btree-4.4 {
   325         -  btree_move_to $::c1 0
   326         -  set r {}
   327         -  while 1 {
   328         -    set key [btree_key $::c1]
   329         -    if {[btree_eof $::c1]} break
   330         -    lappend r $key
   331         -    lappend r [btree_data $::c1]
   332         -    btree_next $::c1
   333         -  }
   334         -  set r   
   335         -} {200 2.00 300 3.00 400 4.00 500 5.00 600 6.00}
   336         -
   337         -# Commit and make sure the delete is still there.
   338         -#
   339         -do_test btree-4.5 {
   340         -  btree_commit $::b1
   341         -  btree_move_to $::c1 0
   342         -  set r {}
   343         -  while 1 {
   344         -    set key [btree_key $::c1]
   345         -    if {[btree_eof $::c1]} break
   346         -    lappend r $key
   347         -    lappend r [btree_data $::c1]
   348         -    btree_next $::c1
   349         -  }
   350         -  set r   
   351         -} {200 2.00 300 3.00 400 4.00 500 5.00 600 6.00}
   352         -
   353         -# Completely close the database and reopen it.  Then check
   354         -# the data again.
   355         -#
   356         -do_test btree-4.6 {
   357         -  lindex [btree_pager_stats $::b1] 1
   358         -} {1}
   359         -do_test btree-4.7 {
   360         -  btree_close_cursor $::c1
   361         -  lindex [btree_pager_stats $::b1] 1
   362         -} {0}
   363         -do_test btree-4.8 {
   364         -  btree_close $::b1
   365         -  set ::b1 [btree_open test1.bt 2000 0]
   366         -  set ::c1 [btree_cursor $::b1 1 1]
   367         -  lindex [btree_pager_stats $::b1] 1
   368         -} {1}
   369         -do_test btree-4.9 {
   370         -  set r {}
   371         -  btree_first $::c1
   372         -  while 1 {
   373         -    set key [btree_key $::c1]
   374         -    if {[btree_eof $::c1]} break
   375         -    lappend r $key
   376         -    lappend r [btree_data $::c1]
   377         -    btree_next $::c1
   378         -  }
   379         -  set r   
   380         -} {200 2.00 300 3.00 400 4.00 500 5.00 600 6.00}
   381         -
   382         -# Try to read and write meta data
   383         -#
   384         -do_test btree-5.1 {
   385         -  btree_get_meta $::b1
   386         -} {0 0 0 0 0 0 0 0 0 0}
   387         -do_test btree-5.2 {
   388         -  set rc [catch {
   389         -    btree_update_meta $::b1 0 1 2 3 4 5 6 7 8 9
   390         -  } msg]
   391         -  lappend rc $msg
   392         -} {1 SQLITE_ERROR}
   393         -do_test btree-5.3 {
   394         -  btree_begin_transaction $::b1
   395         -  set rc [catch {
   396         -    btree_update_meta $::b1 0 1 2 3 0 5 6 0 8 9
   397         -  } msg]
   398         -  lappend rc $msg
   399         -} {0 {}}
   400         -do_test btree-5.4 {
   401         -  btree_get_meta $::b1
   402         -} {0 1 2 3 0 5 6 0 8 9}
   403         -do_test btree-5.5 {
   404         -  btree_close_cursor $::c1
   405         -  btree_rollback $::b1
   406         -  btree_get_meta $::b1
   407         -} {0 0 0 0 0 0 0 0 0 0}
   408         -do_test btree-5.6 {
   409         -  btree_begin_transaction $::b1
   410         -  btree_update_meta $::b1 0 10 20 30 0 50 60 0 80 90
   411         -  btree_commit $::b1
   412         -  btree_get_meta $::b1
   413         -} {0 10 20 30 0 50 60 0 80 90}
   414         -
   415         -proc select_all {cursor} {
   416         -  set r {}
   417         -  btree_first $cursor
   418         -  while {![btree_eof $cursor]} {
   419         -    set key [btree_key $cursor]
   420         -    lappend r $key
   421         -    lappend r [btree_data $cursor]
   422         -    btree_next $cursor
   423         -  }
   424         -  return $r
   425         -}
   426         -proc select_keys {cursor} {
   427         -  set r {}
   428         -  btree_first $cursor
   429         -  while {![btree_eof $cursor]} {
   430         -    set key [btree_key $cursor]
   431         -    lappend r $key
   432         -    btree_next $cursor
   433         -  }
   434         -  return $r
   435         -}
   436         -
   437         -# Try to create a new table in the database file
   438         -#
   439         -do_test btree-6.1 {
   440         -  set rc [catch {btree_create_table $::b1 0} msg]
   441         -  lappend rc $msg
   442         -} {1 SQLITE_ERROR}
   443         -do_test btree-6.2 {
   444         -  btree_begin_transaction $::b1
   445         -  set ::t2 [btree_create_table $::b1 0]
   446         -} {2}
   447         -do_test btree-6.2.1 {
   448         -  lindex [btree_pager_stats $::b1] 1
   449         -} {1}
   450         -do_test btree-6.2.2 {
   451         -  set ::c2 [btree_cursor $::b1 $::t2 1]
   452         -  lindex [btree_pager_stats $::b1] 1
   453         -} {2}
   454         -do_test btree-6.2.3 {
   455         -  btree_insert $::c2 ten 10
   456         -  btree_move_to $::c2 ten
   457         -  btree_key $::c2
   458         -} {ten}
   459         -do_test btree-6.3 {
   460         -  btree_commit $::b1
   461         -  set ::c1 [btree_cursor $::b1 1 1]
   462         -  lindex [btree_pager_stats $::b1] 1
   463         -} {2}
   464         -do_test btree-6.3.1 {
   465         -  select_all $::c1
   466         -} {200 2.00 300 3.00 400 4.00 500 5.00 600 6.00}
   467         -#btree_page_dump $::b1 3
   468         -do_test btree-6.4 {
   469         -  select_all $::c2
   470         -} {ten 10}
   471         -
   472         -# Drop the new table, then create it again anew.
   473         -#
   474         -do_test btree-6.5 {
   475         -  btree_begin_transaction $::b1
   476         -} {}
   477         -do_test btree-6.6 {
   478         -  btree_close_cursor $::c2
   479         -} {}
   480         -do_test btree-6.6.1 {
   481         -  lindex [btree_pager_stats $::b1] 1
   482         -} {1}
   483         -do_test btree-6.7 {
   484         -  btree_close_cursor $::c1
   485         -  btree_drop_table $::b1 $::t2
   486         -} {}
   487         -do_test btree-6.7.1 {
   488         -  lindex [btree_get_meta $::b1] 0
   489         -} {1}
   490         -do_test btree-6.8 {
   491         -  set ::t2 [btree_create_table $::b1 0]
   492         -} {2}
   493         -do_test btree-6.8.1 {
   494         -  lindex [btree_get_meta $::b1] 0
   495         -} {0}
   496         -do_test btree-6.9 {
   497         -  set ::c2 [btree_cursor $::b1 $::t2 1]
   498         -  lindex [btree_pager_stats $::b1] 1
   499         -} {2}
   500         -
   501         -# This test case used to test that requesting the key from an invalid cursor
   502         -# returned an empty string.  But that is now an assert()ed condition.
   503         -#
   504         -# do_test btree-6.9.1 {
   505         -#   btree_move_to $::c2 {}
   506         -#   btree_key $::c2
   507         -# } {}
   508         -
   509         -# If we drop table 1 it just clears the table.  Table 1 always exists.
   510         -#
   511         -do_test btree-6.10 {
   512         -  btree_close_cursor $::c2
   513         -  btree_drop_table $::b1 1
   514         -  set ::c2 [btree_cursor $::b1 $::t2 1]
   515         -  set ::c1 [btree_cursor $::b1 1 1]
   516         -  btree_first $::c1
   517         -  btree_eof $::c1
   518         -} {1}
   519         -do_test btree-6.11 {
   520         -  btree_commit $::b1
   521         -  select_all $::c1
   522         -} {}
   523         -do_test btree-6.12 {
   524         -  select_all $::c2
   525         -} {}
   526         -do_test btree-6.13 {
   527         -  btree_close_cursor $::c2
   528         -  lindex [btree_pager_stats $::b1] 1
   529         -} {1}
   530         -
   531         -# Check to see that pages defragment properly.  To do this test we will
   532         -# 
   533         -#   1.  Fill the first page of table 1 with data.
   534         -#   2.  Delete every other entry of table 1.
   535         -#   3.  Insert a single entry that requires more contiguous
   536         -#       space than is available.
   537         -#
   538         -do_test btree-7.1 {
   539         -  btree_begin_transaction $::b1
   540         -} {}
   541         -catch {unset key}
   542         -catch {unset data}
   543         -
   544         -# Check to see that data on overflow pages work correctly.
   545         -#
   546         -do_test btree-8.1 {
   547         -  set data "*** This is a very long key "
   548         -  while {[string length $data]<1234} {append data $data}
   549         -  set ::data $data
   550         -  btree_insert $::c1 2020 $data
   551         -} {}
   552         -btree_page_dump $::b1 1
   553         -btree_page_dump $::b1 2
   554         -do_test btree-8.1.1 {
   555         -  lindex [btree_pager_stats $::b1] 1
   556         -} {1}
   557         -btree_pager_ref_dump $::b1
   558         -do_test btree-8.2 {
   559         -  btree_move_to $::c1 2020
   560         -  string length [btree_data $::c1]
   561         -} [string length $::data]
   562         -do_test btree-8.3 {
   563         -  btree_data $::c1
   564         -} $::data
   565         -do_test btree-8.4 {
   566         -  btree_delete $::c1
   567         -} {}
   568         -do_test btree-8.4.1 {
   569         -  lindex [btree_get_meta $::b1] 0
   570         -} [expr {int(([string length $::data]-238+1019)/1020)}]
   571         -do_test btree-8.4.2 {
   572         -  btree_integrity_check $::b1 1 2
   573         -} {}
   574         -do_test btree-8.5 {
   575         -  set data "*** This is an even longer key "
   576         -  while {[string length $data]<2000} {append data $data}
   577         -  append data END
   578         -  set ::data $data
   579         -  btree_insert $::c1 2030 $data
   580         -} {}
   581         -do_test btree-8.6 {
   582         -  btree_move_to $::c1 2030
   583         -  string length [btree_data $::c1]
   584         -} [string length $::data]
   585         -do_test btree-8.7 {
   586         -  btree_data $::c1
   587         -} $::data
   588         -do_test btree-8.8 {
   589         -  btree_commit $::b1
   590         -  btree_data $::c1
   591         -} $::data
   592         -do_test btree-8.9.1 {
   593         -  btree_close_cursor $::c1
   594         -  btree_close $::b1
   595         -  set ::b1 [btree_open test1.bt 2000 0]
   596         -  set ::c1 [btree_cursor $::b1 1 1]
   597         -  btree_move_to $::c1 2030
   598         -  btree_data $::c1
   599         -} $::data
   600         -do_test btree-8.9.2 {
   601         -  btree_integrity_check $::b1 1 2
   602         -} {}
   603         -do_test btree-8.10 {
   604         -  btree_begin_transaction $::b1
   605         -  btree_delete $::c1
   606         -} {}
   607         -do_test btree-8.11 {
   608         -  lindex [btree_get_meta $::b1] 0
   609         -} {4}
   610         -
   611         -# Now check out keys on overflow pages.
   612         -#
   613         -do_test btree-8.12.1 {
   614         -  set ::keyprefix "This is a long prefix to a key "
   615         -  while {[string length $::keyprefix]<256} {append ::keyprefix $::keyprefix}
   616         -  btree_close_cursor $::c1
   617         -  btree_clear_table $::b1 2
   618         -  lindex [btree_get_meta $::b1] 0
   619         -} {4}
   620         -do_test btree-8.12.2 {
   621         -  btree_integrity_check $::b1 1 2
   622         -} {}
   623         -do_test btree-8.12.3 {
   624         -  set ::c1 [btree_cursor $::b1 2 1]
   625         -  btree_insert $::c1 ${::keyprefix}1 1
   626         -  btree_first $::c1
   627         -  btree_data $::c1
   628         -} {1}
   629         -do_test btree-8.13 {
   630         -  btree_key $::c1
   631         -} ${keyprefix}1
   632         -do_test btree-8.14 {
   633         -  btree_insert $::c1 ${::keyprefix}2 2
   634         -  btree_insert $::c1 ${::keyprefix}3 3
   635         -  btree_last $::c1
   636         -  btree_key $::c1
   637         -} ${keyprefix}3
   638         -do_test btree-8.15 {
   639         -  btree_move_to $::c1 ${::keyprefix}2
   640         -  btree_data $::c1
   641         -} {2}
   642         -do_test btree-8.16 {
   643         -  btree_move_to $::c1 ${::keyprefix}1
   644         -  btree_data $::c1
   645         -} {1}
   646         -do_test btree-8.17 {
   647         -  btree_move_to $::c1 ${::keyprefix}3
   648         -  btree_data $::c1
   649         -} {3}
   650         -do_test btree-8.18 {
   651         -  lindex [btree_get_meta $::b1] 0
   652         -} {1}
   653         -do_test btree-8.19 {
   654         -  btree_move_to $::c1 ${::keyprefix}2
   655         -  btree_key $::c1
   656         -} ${::keyprefix}2
   657         -#btree_page_dump $::b1 2
   658         -do_test btree-8.20 {
   659         -  btree_delete $::c1
   660         -  btree_next $::c1
   661         -  btree_key $::c1
   662         -} ${::keyprefix}3
   663         -#btree_page_dump $::b1 2
   664         -do_test btree-8.21 {
   665         -  lindex [btree_get_meta $::b1] 0
   666         -} {2}
   667         -do_test btree-8.22 {
   668         -  lindex [btree_pager_stats $::b1] 1
   669         -} {2}
   670         -do_test btree-8.23.1 {
   671         -  btree_close_cursor $::c1
   672         -  btree_drop_table $::b1 2
   673         -  btree_integrity_check $::b1 1
   674         -} {}
   675         -do_test btree-8.23.2 {
   676         -  btree_create_table $::b1 0
   677         -} {2}
   678         -do_test btree-8.23.3 {
   679         -  set ::c1 [btree_cursor $::b1 2 1]
   680         -  lindex [btree_get_meta $::b1] 0
   681         -} {4}
   682         -do_test btree-8.24 {
   683         -  lindex [btree_pager_stats $::b1] 1
   684         -} {2}
   685         -#btree_pager_ref_dump $::b1
   686         -do_test btree-8.25 {
   687         -  btree_integrity_check $::b1 1 2
   688         -} {}
   689         -
   690         -# Check page splitting logic
   691         -#
   692         -do_test btree-9.1 {
   693         -  for {set i 1} {$i<=19} {incr i} {
   694         -    set key [format %03d $i]
   695         -    set data "*** $key *** $key *** $key *** $key ***"
   696         -    btree_insert $::c1 $key $data
   697         -  }
   698         -} {}
   699         -do_test btree-9.2 {
   700         -  btree_insert $::c1 020 {*** 020 *** 020 *** 020 *** 020 ***}
   701         -  select_keys $::c1
   702         -} {001 002 003 004 005 006 007 008 009 010 011 012 013 014 015 016 017 018 019 020}
   703         -
   704         -# The previous "select_keys" command left the cursor pointing at the root
   705         -# page.  So there should only be two pages checked out.  2 (the root) and
   706         -# page 1.
   707         -do_test btree-9.2.1 {
   708         -  lindex [btree_pager_stats $::b1] 1
   709         -} {2}
   710         -for {set i 1} {$i<=20} {incr i} {
   711         -  do_test btree-9.3.$i.1 [subst {
   712         -    btree_move_to $::c1 [format %03d $i]
   713         -    btree_key $::c1
   714         -  }] [format %03d $i]
   715         -  do_test btree-9.3.$i.2 [subst {
   716         -    btree_move_to $::c1 [format %03d $i]
   717         -    string range \[btree_data $::c1\] 0 10
   718         -  }] "*** [format %03d $i] ***"
   719         -}
   720         -do_test btree-9.4.1 {
   721         -  lindex [btree_pager_stats $::b1] 1
   722         -} {2}
   723         -
   724         -# Check the page joining logic.
   725         -#
   726         -#btree_page_dump $::b1 2
   727         -#btree_pager_ref_dump $::b1
   728         -do_test btree-9.4.2 {
   729         -  btree_move_to $::c1 005
   730         -  btree_delete $::c1
   731         -} {}
   732         -#btree_page_dump $::b1 2
   733         -for {set i 1} {$i<=19} {incr i} {
   734         -  if {$i==5} continue
   735         -  do_test btree-9.5.$i.1 [subst {
   736         -    btree_move_to $::c1 [format %03d $i]
   737         -    btree_key $::c1
   738         -  }] [format %03d $i]
   739         -  do_test btree-9.5.$i.2 [subst {
   740         -    btree_move_to $::c1 [format %03d $i]
   741         -    string range \[btree_data $::c1\] 0 10
   742         -  }] "*** [format %03d $i] ***"
   743         -}
   744         -#btree_pager_ref_dump $::b1
   745         -do_test btree-9.6 {
   746         -  btree_close_cursor $::c1
   747         -  lindex [btree_pager_stats $::b1] 1
   748         -} {1}
   749         -do_test btree-9.7 {
   750         -  btree_integrity_check $::b1 1 2
   751         -} {}
   752         -do_test btree-9.8 {
   753         -  btree_rollback $::b1
   754         -  lindex [btree_pager_stats $::b1] 1
   755         -} {0}
   756         -do_test btree-9.9 {
   757         -  btree_integrity_check $::b1 1 2
   758         -} {}
   759         -do_test btree-9.10 {
   760         -  btree_close $::b1
   761         -  set ::b1 [btree_open test1.bt 2000 0]
   762         -  btree_integrity_check $::b1 1 2
   763         -} {}
   764         -
   765         -# Create a tree of depth two.  That is, there is a single divider entry
   766         -# on the root pages and two leaf pages.  Then delete the divider entry
   767         -# see what happens.
   768         -#
   769         -do_test btree-10.1 {
   770         -  btree_begin_transaction $::b1
   771         -  btree_clear_table $::b1 2
   772         -  lindex [btree_pager_stats $::b1] 1
   773         -} {1}
   774         -do_test btree-10.2 {
   775         -  set ::c1 [btree_cursor $::b1 2 1]
   776         -  lindex [btree_pager_stats $::b1] 1
   777         -} {2}
   778         -do_test btree-10.3 {
   779         -btree_breakpoint
   780         -  for {set i 1} {$i<=30} {incr i} {
   781         -    set key [format %03d $i]
   782         -    set data "*** $key *** $key *** $key *** $key ***"
   783         -    btree_insert $::c1 $key $data
   784         -  }
   785         -  select_keys $::c1
   786         -} {001 002 003 004 005 006 007 008 009 010 011 012 013 014 015 016 017 018 019 020 021 022 023 024 025 026 027 028 029 030}
   787         -#btree_tree_dump $::b1 2
   788         -do_test btree-10.4 {
   789         -  # The divider entry is 012.  This is found by uncommenting the 
   790         -  # btree_tree_dump call above and looking at the tree.  If the page size
   791         -  # changes, this test will no longer work.
   792         -  btree_move_to $::c1 012
   793         -  btree_delete $::c1
   794         -  select_keys $::c1
   795         -} {001 002 003 004 005 006 007 008 009 010 011 013 014 015 016 017 018 019 020 021 022 023 024 025 026 027 028 029 030}
   796         -#btree_pager_ref_dump $::b1
   797         -#btree_tree_dump $::b1 2
   798         -for {set i 1} {$i<=30} {incr i} {
   799         -  # Check the number of unreference pages.  This should be 3 in most cases,
   800         -  # but 2 when the cursor is pointing to the divider entry which is now 013.
   801         -  do_test btree-10.5.$i {
   802         -    btree_move_to $::c1 [format %03d $i]
   803         -    lindex [btree_pager_stats $::b1] 1
   804         -  } [expr {$i==13?2:3}]
   805         -  #btree_pager_ref_dump $::b1
   806         -  #btree_tree_dump $::b1 2
   807         -}
   808         -
   809         -# Create a tree with lots more pages
   810         -#
   811         -catch {unset ::data}
   812         -catch {unset ::key}
   813         -for {set i 31} {$i<=2000} {incr i} {
   814         -  do_test btree-11.1.$i.1 {
   815         -    set key [format %03d $i]
   816         -    set ::data "*** $key *** $key *** $key *** $key ***"
   817         -    btree_insert $::c1 $key $data
   818         -    btree_move_to $::c1 $key
   819         -    btree_key $::c1
   820         -  } [format %03d $i]
   821         -  do_test btree-11.1.$i.2 {
   822         -    btree_data $::c1
   823         -  } $::data
   824         -  set ::key [format %03d [expr {$i/2}]]
   825         -  if {$::key=="012"} {set ::key 013}
   826         -  do_test btree-11.1.$i.3 {
   827         -    btree_move_to $::c1 $::key
   828         -    btree_key $::c1
   829         -  } $::key
   830         -}
   831         -catch {unset ::data}
   832         -catch {unset ::key}
   833         -
   834         -# Make sure our reference count is still correct.
   835         -#
   836         -do_test btree-11.2 {
   837         -  btree_close_cursor $::c1
   838         -  lindex [btree_pager_stats $::b1] 1
   839         -} {1}
   840         -do_test btree-11.3 {
   841         -  set ::c1 [btree_cursor $::b1 2 1]
   842         -  lindex [btree_pager_stats $::b1] 1
   843         -} {2}
   844         -
   845         -# Delete the dividers on the root page
   846         -#
   847         -#btree_page_dump $::b1 2
   848         -do_test btree-11.4 {
   849         -  btree_move_to $::c1 1667
   850         -  btree_delete $::c1
   851         -  btree_move_to $::c1 1667
   852         -  set k [btree_key $::c1]
   853         -  if {$k==1666} {
   854         -    set k [btree_next $::c1]
   855         -  }
   856         -  btree_key $::c1
   857         -} {1668}
   858         -#btree_page_dump $::b1 2
   859         -
   860         -# Change the data on an intermediate node such that the node becomes overfull
   861         -# and has to split.  We happen to know that intermediate nodes exist on
   862         -# 337, 401 and 465 by the btree_page_dumps above
   863         -#
   864         -catch {unset ::data}
   865         -set ::data {This is going to be a very long data segment}
   866         -append ::data $::data
   867         -append ::data $::data
   868         -do_test btree-12.1 {
   869         -  btree_insert $::c1 337 $::data
   870         -  btree_move_to $::c1 337
   871         -  btree_data $::c1
   872         -} $::data
   873         -do_test btree-12.2 {
   874         -  btree_insert $::c1 401 $::data
   875         -  btree_move_to $::c1 401
   876         -  btree_data $::c1
   877         -} $::data
   878         -do_test btree-12.3 {
   879         -  btree_insert $::c1 465 $::data
   880         -  btree_move_to $::c1 465
   881         -  btree_data $::c1
   882         -} $::data
   883         -do_test btree-12.4 {
   884         -  btree_move_to $::c1 337
   885         -  btree_key $::c1
   886         -} {337}
   887         -do_test btree-12.5 {
   888         -  btree_data $::c1
   889         -} $::data
   890         -do_test btree-12.6 {
   891         -  btree_next $::c1
   892         -  btree_key $::c1
   893         -} {338}
   894         -do_test btree-12.7 {
   895         -  btree_move_to $::c1 464
   896         -  btree_key $::c1
   897         -} {464}
   898         -do_test btree-12.8 {
   899         -  btree_next $::c1
   900         -  btree_data $::c1
   901         -} $::data
   902         -do_test btree-12.9 {
   903         -  btree_next $::c1
   904         -  btree_key $::c1
   905         -} {466}
   906         -do_test btree-12.10 {
   907         -  btree_move_to $::c1 400
   908         -  btree_key $::c1
   909         -} {400}
   910         -do_test btree-12.11 {
   911         -  btree_next $::c1
   912         -  btree_data $::c1
   913         -} $::data
   914         -do_test btree-12.12 {
   915         -  btree_next $::c1
   916         -  btree_key $::c1
   917         -} {402}
   918         -# btree_commit $::b1
   919         -# btree_tree_dump $::b1 1
   920         -do_test btree-13.1 {
   921         -  btree_integrity_check $::b1 1 2
   922         -} {}
   923         -
   924         -# To Do:
   925         -#
   926         -#   1.  Do some deletes from the 3-layer tree
   927         -#   2.  Commit and reopen the database
   928         -#   3.  Read every 15th entry and make sure it works
   929         -#   4.  Implement btree_sanity and put it throughout this script
   930         -#
   931         -
   932         -do_test btree-15.98 {
   933         -  btree_close_cursor $::c1
   934         -  lindex [btree_pager_stats $::b1] 1
   935         -} {1}
   936         -do_test btree-15.99 {
   937         -  btree_rollback $::b1
   938         -  lindex [btree_pager_stats $::b1] 1
   939         -} {0}
   940         -btree_pager_ref_dump $::b1
   941         -
   942         -# Miscellaneous tests.
   943         -#
   944         -# btree-16.1 - Check that a statement cannot be started if a transaction 
   945         -#              is not active.
   946         -# btree-16.2 - Check that it is an error to request more payload from a 
   947         -#              btree entry than the entry contains.
   948         -do_test btree-16.1 {
   949         -  catch {btree_begin_statement $::b1} msg
   950         -  set msg
   951         -} SQLITE_ERROR
   952         -
   953         -do_test btree-16.2 {
   954         -  btree_begin_transaction $::b1
   955         -  set ::c1 [btree_cursor $::b1 2 1]
   956         -  btree_insert $::c1 1 helloworld
   957         -  btree_close_cursor $::c1
   958         -  btree_commit $::b1
   959         -} {}
   960         -do_test btree-16.3 {
   961         -  set ::c1 [btree_cursor $::b1 2 1]
   962         -  btree_first $::c1
   963         -} 0
   964         -do_test btree-16.4 {
   965         -  catch {btree_data $::c1 [expr [btree_payload_size $::c1] + 10]} msg
   966         -  set msg
   967         -} SQLITE_ERROR
   968         -
   969         -if {$tcl_platform(platform)=="unix"} {
   970         -  do_test btree-16.5 {
   971         -    btree_close $::b1
   972         -    set ::origperm [file attributes test1.bt -permissions]
   973         -    file attributes test1.bt -permissions o-w,g-w,a-w
   974         -    set ::b1 [btree_open test1.bt 2000 0]
   975         -    catch {btree_cursor $::b1 2 1} msg
   976         -    file attributes test1.bt -permissions $::origperm
   977         -    btree_close $::b1
   978         -    set ::b1 [btree_open test1.bt 2000 0]
   979         -    set msg
   980         -  } {SQLITE_READONLY}
   981         -}
   982         -
   983         -do_test btree-16.6 {
   984         -  set ::c1 [btree_cursor $::b1 2 1]
   985         -  set ::c2 [btree_cursor $::b1 2 1]
   986         -  btree_begin_transaction $::b1
   987         -  for {set i 0} {$i<100} {incr i} {
   988         -    btree_insert $::c1 $i [string repeat helloworld 10]
   989         -  }
   990         -  btree_last $::c2
   991         -  btree_insert $::c1 100 [string repeat helloworld 10]
   992         -} {}
   993         -
   994         -do_test btree-16.7 {
   995         -  btree_close_cursor $::c1
   996         -  btree_close_cursor $::c2
   997         -  btree_commit $::b1
   998         -  set ::c1 [btree_cursor $::b1 2 1]
   999         -  catch {btree_insert $::c1 101 helloworld} msg
  1000         -  set msg
  1001         -} {SQLITE_ERROR}
  1002         -do_test btree-16.8 {
  1003         -  btree_first $::c1
  1004         -  catch {btree_delete $::c1} msg
  1005         -  set msg
  1006         -} {SQLITE_ERROR}
  1007         -do_test btree-16.9 {
  1008         -  btree_close_cursor $::c1
  1009         -  btree_begin_transaction $::b1
  1010         -  set ::c1 [btree_cursor $::b1 2 0]
  1011         -  catch {btree_insert $::c1 101 helloworld} msg
  1012         -  set msg
  1013         -} {SQLITE_PERM}
  1014         -do_test btree-16.10 {
  1015         -  catch {btree_delete $::c1} msg
  1016         -  set msg
  1017         -} {SQLITE_PERM}
  1018         -
  1019         -# As of 2006-08-16 (version 3.3.7+) a read cursor will no
  1020         -# longer block a write cursor from the same database
  1021         -# connectiin.  The following three tests uses to return
  1022         -# the SQLITE_LOCK error, but no more.
  1023         -#
  1024         -do_test btree-16.11 {
  1025         -  btree_close_cursor $::c1
  1026         -  set ::c2 [btree_cursor $::b1 2 1]
  1027         -  set ::c1 [btree_cursor $::b1 2 0]
  1028         -  catch {btree_insert $::c2 101 helloworld} msg
  1029         -  set msg
  1030         -} {}
  1031         -do_test btree-16.12 {
  1032         -  btree_first $::c2
  1033         -  catch {btree_delete $::c2} msg
  1034         -  set msg
  1035         -} {}
  1036         -do_test btree-16.13 {
  1037         -  catch {btree_clear_table $::b1 2} msg
  1038         -  set msg
  1039         -} {}
  1040         -
  1041         -
  1042         -do_test btree-16.14 {
  1043         -  btree_close_cursor $::c1
  1044         -  btree_close_cursor $::c2
  1045         -  btree_commit $::b1
  1046         -  catch {btree_clear_table $::b1 2} msg
  1047         -  set msg
  1048         -} {SQLITE_ERROR}
  1049         -do_test btree-16.15 {
  1050         -  catch {btree_drop_table $::b1 2} msg
  1051         -  set msg
  1052         -} {SQLITE_ERROR}
  1053         -do_test btree-16.16 {
  1054         -  btree_begin_transaction $::b1
  1055         -  set ::c1 [btree_cursor $::b1 2 0]
  1056         -  catch {btree_drop_table $::b1 2} msg
  1057         -  set msg
  1058         -} {SQLITE_LOCKED}
  1059         -
  1060         -do_test btree-99.1 {
  1061         -  btree_close $::b1
  1062         -} {}
  1063         -catch {unset data}
  1064         -catch {unset key}
  1065         -
  1066         -finish_test

Deleted test/btree2.test.

     1         -# 2001 September 15
     2         -#
     3         -# The author disclaims copyright to this source code.  In place of
     4         -# a legal notice, here is a blessing:
     5         -#
     6         -#    May you do good and not evil.
     7         -#    May you find forgiveness for yourself and forgive others.
     8         -#    May you share freely, never taking more than you give.
     9         -#
    10         -#***********************************************************************
    11         -# This file implements regression tests for SQLite library.  The
    12         -# focus of this script is btree database backend
    13         -#
    14         -# $Id: btree2.test,v 1.15 2006/03/19 13:00:25 drh Exp $
    15         -
    16         -
    17         -set testdir [file dirname $argv0]
    18         -source $testdir/tester.tcl
    19         -
    20         -if {[info commands btree_open]!=""} {
    21         -
    22         -# Create a new database file containing no entries.  The database should
    23         -# contain 5 tables:
    24         -#
    25         -#     2   The descriptor table
    26         -#     3   The foreground table
    27         -#     4   The background table
    28         -#     5   The long key table
    29         -#     6   The long data table
    30         -#
    31         -# An explanation for what all these tables are used for is provided below.
    32         -#
    33         -do_test btree2-1.1 {
    34         -  expr srand(1)
    35         -  file delete -force test2.bt
    36         -  file delete -force test2.bt-journal
    37         -  set ::b [btree_open test2.bt 2000 0]
    38         -  btree_begin_transaction $::b
    39         -  btree_create_table $::b 0
    40         -} {2}
    41         -do_test btree2-1.2 {
    42         -  btree_create_table $::b 0
    43         -} {3}
    44         -do_test btree2-1.3 {
    45         -  btree_create_table $::b 0
    46         -} {4}
    47         -do_test btree2-1.4 {
    48         -  btree_create_table $::b 0
    49         -} {5}
    50         -do_test btree2-1.5 {
    51         -  btree_create_table $::b 0
    52         -} {6}
    53         -do_test btree2-1.6 {
    54         -  set ::c2 [btree_cursor $::b 2 1]
    55         -  btree_insert $::c2 {one} {1}
    56         -  btree_move_to $::c2 {one}
    57         -  btree_delete $::c2
    58         -  btree_close_cursor $::c2
    59         -  btree_commit $::b
    60         -  btree_integrity_check $::b 1 2 3 4 5 6
    61         -} {}
    62         -
    63         -# This test module works by making lots of pseudo-random changes to a
    64         -# database while simultaneously maintaining an invariant on that database.
    65         -# Periodically, the script does a sanity check on the database and verifies
    66         -# that the invariant is satisfied.
    67         -#
    68         -# The invariant is as follows:
    69         -#
    70         -#   1.  The descriptor table always contains 2 enters.  An entry keyed by
    71         -#       "N" is the number of elements in the foreground and background tables
    72         -#       combined.  The entry keyed by "L" is the number of digits in the keys
    73         -#       for foreground and background tables.
    74         -#
    75         -#   2.  The union of the foreground an background tables consists of N entries
    76         -#       where each entry has an L-digit key. (Actually, some keys can be longer 
    77         -#       than L characters, but they always start with L digits.)  The keys
    78         -#       cover all integers between 1 and N.  Whenever an entry is added to
    79         -#       the foreground it is removed form the background and vice versa.
    80         -#
    81         -#   3.  Some entries in the foreground and background tables have keys that
    82         -#       begin with an L-digit number but are followed by additional characters.
    83         -#       For each such entry there is a corresponding entry in the long key
    84         -#       table.  The long key table entry has a key which is just the L-digit
    85         -#       number and data which is the length of the key in the foreground and
    86         -#       background tables.
    87         -#
    88         -#   4.  The data for both foreground and background entries is usually a
    89         -#       short string.  But some entries have long data strings.  For each
    90         -#       such entries there is an entry in the long data type.  The key to
    91         -#       long data table is an L-digit number.  (The extension on long keys
    92         -#       is omitted.)  The data is the number of charaters in the data of the
    93         -#       foreground or background entry.
    94         -#
    95         -# The following function builds a database that satisfies all of the above
    96         -# invariants.
    97         -#
    98         -proc build_db {N L} {
    99         -  for {set i 2} {$i<=6} {incr i} {
   100         -    catch {btree_close_cursor [set ::c$i]}
   101         -    btree_clear_table $::b $i
   102         -    set ::c$i [btree_cursor $::b $i 1]
   103         -  }
   104         -  btree_insert $::c2 N $N
   105         -  btree_insert $::c2 L $L
   106         -  set format %0${L}d
   107         -  for {set i 1} {$i<=$N} {incr i} { 
   108         -    set key [format $format $i]
   109         -    set data $key
   110         -    btree_insert $::c3 $key $data
   111         -  }
   112         -}
   113         -
   114         -# Given a base key number and a length, construct the full text of the key
   115         -# or data.
   116         -#
   117         -proc make_payload {keynum L len} {
   118         -  set key [format %0${L}d $keynum]
   119         -  set r $key
   120         -  set i 1
   121         -  while {[string length $r]<$len} {
   122         -    append r " ($i) $key"
   123         -    incr i
   124         -  }
   125         -  return [string range $r 0 [expr {$len-1}]]
   126         -}
   127         -
   128         -# Verify the invariants on the database.  Return an empty string on 
   129         -# success or an error message if something is amiss.
   130         -#
   131         -proc check_invariants {} {
   132         -  set ck [btree_integrity_check $::b 1 2 3 4 5 6]
   133         -  if {$ck!=""} {
   134         -    puts "\n*** SANITY:\n$ck"
   135         -    exit
   136         -    return $ck
   137         -  }
   138         -  btree_move_to $::c3 {}
   139         -  btree_move_to $::c4 {}
   140         -  btree_move_to $::c2 N
   141         -  set N [btree_data $::c2]
   142         -  btree_move_to $::c2 L
   143         -  set L [btree_data $::c2]
   144         -  set LM1 [expr {$L-1}]
   145         -  for {set i 1} {$i<=$N} {incr i} {
   146         -    set key {}
   147         -    if {![btree_eof $::c3]} {
   148         -      set key [btree_key $::c3]
   149         -    }
   150         -    if {[scan $key %d k]<1} {set k 0}
   151         -    if {$k!=$i} {
   152         -      set key {}
   153         -      if {![btree_eof $::c4]} {
   154         -        set key [btree_key $::c4]
   155         -      }
   156         -      if {[scan $key %d k]<1} {set k 0}
   157         -      if {$k!=$i} {
   158         -        return "Key $i is missing from both foreground and background"
   159         -      }
   160         -      set data [btree_data $::c4]
   161         -      btree_next $::c4
   162         -    } else {
   163         -      set data [btree_data $::c3]
   164         -      btree_next $::c3
   165         -    }
   166         -    set skey [string range $key 0 $LM1]
   167         -    if {[btree_move_to $::c5 $skey]==0} {
   168         -      set keylen [btree_data $::c5]
   169         -    } else {
   170         -      set keylen $L
   171         -    }
   172         -    if {[string length $key]!=$keylen} {
   173         -      return "Key $i is the wrong size.\
   174         -              Is \"$key\" but should be \"[make_payload $k $L $keylen]\""
   175         -    }
   176         -    if {[make_payload $k $L $keylen]!=$key} {
   177         -      return "Key $i has an invalid extension"
   178         -    }
   179         -    if {[btree_move_to $::c6 $skey]==0} {
   180         -      set datalen [btree_data $::c6]
   181         -    } else {
   182         -      set datalen $L
   183         -    }
   184         -    if {[string length $data]!=$datalen} {
   185         -      return "Data for $i is the wrong size.\
   186         -              Is [string length $data] but should be $datalen"
   187         -    }
   188         -    if {[make_payload $k $L $datalen]!=$data} {
   189         -      return "Entry $i has an incorrect data"
   190         -    }
   191         -  }
   192         -}
   193         -
   194         -# Look at all elements in both the foreground and background tables.
   195         -# Make sure the key is always the same as the prefix of the data.
   196         -#
   197         -# This routine was used for hunting bugs.  It is not a part of standard
   198         -# tests.
   199         -#
   200         -proc check_data {n key} {
   201         -  global c3 c4
   202         -  incr n -1
   203         -  foreach c [list $c3 $c4] {
   204         -    btree_first $c  ;# move_to $c $key
   205         -    set cnt 0
   206         -    while {![btree_eof $c]} {
   207         -      set key [btree_key $c]
   208         -      set data [btree_data $c]
   209         -      if {[string range $key 0 $n] ne [string range $data 0 $n]} {
   210         -        puts "key=[list $key] data=[list $data] n=$n"
   211         -        puts "cursor info = [btree_cursor_info $c]"
   212         -        btree_page_dump $::b [lindex [btree_cursor_info $c] 0]
   213         -        exit
   214         -      }
   215         -      btree_next $c
   216         -    }
   217         -  }
   218         -}
   219         -
   220         -# Make random changes to the database such that each change preserves
   221         -# the invariants.  The number of changes is $n*N where N is the parameter
   222         -# from the descriptor table.  Each changes begins with a random key.
   223         -# the entry with that key is put in the foreground table with probability
   224         -# $I and it is put in background with probability (1.0-$I).  It gets
   225         -# a long key with probability $K and long data with probability $D.  
   226         -# 
   227         -set chngcnt 0
   228         -proc random_changes {n I K D} {
   229         -  global chngcnt
   230         -  btree_move_to $::c2 N
   231         -  set N [btree_data $::c2]
   232         -  btree_move_to $::c2 L
   233         -  set L [btree_data $::c2]
   234         -  set LM1 [expr {$L-1}]
   235         -  set total [expr {int($N*$n)}]
   236         -  set format %0${L}d
   237         -  for {set i 0} {$i<$total} {incr i} {
   238         -    set k [expr {int(rand()*$N)+1}]
   239         -    set insert [expr {rand()<=$I}]
   240         -    set longkey [expr {rand()<=$K}]
   241         -    set longdata [expr {rand()<=$D}]
   242         -    if {$longkey} {
   243         -      set x [expr {rand()}]
   244         -      set keylen [expr {int($x*$x*$x*$x*3000)+10}]
   245         -    } else {
   246         -      set keylen $L
   247         -    }
   248         -    set key [make_payload $k $L $keylen]
   249         -    if {$longdata} {
   250         -      set x [expr {rand()}]
   251         -      set datalen [expr {int($x*$x*$x*$x*3000)+10}]
   252         -    } else {
   253         -      set datalen $L
   254         -    }
   255         -    set data [make_payload $k $L $datalen]
   256         -    set basekey [format $format $k]
   257         -    if {[set c [btree_move_to $::c3 $basekey]]==0} {
   258         -      btree_delete $::c3
   259         -    } else {
   260         -      if {$c<0} {btree_next $::c3}
   261         -      if {![btree_eof $::c3]} {
   262         -        if {[string match $basekey* [btree_key $::c3]]} {
   263         -          btree_delete $::c3
   264         -        }
   265         -      }
   266         -    }
   267         -    if {[set c [btree_move_to $::c4 $basekey]]==0} {
   268         -      btree_delete $::c4
   269         -    } else {
   270         -      if {$c<0} {btree_next $::c4}
   271         -      if {![btree_eof $::c4]} {
   272         -        if {[string match $basekey* [btree_key $::c4]]} {
   273         -          btree_delete $::c4
   274         -        }
   275         -      }
   276         -    }
   277         -    set kx -1
   278         -    if {![btree_eof $::c4]} {
   279         -      if {[scan [btree_key $::c4] %d kx]<1} {set kx -1}
   280         -    }
   281         -    if {$kx==$k} {
   282         -      btree_delete $::c4
   283         -    }
   284         -    # For debugging - change the "0" to "1" to integrity check after
   285         -    # every change.
   286         -    if 0 {
   287         -      incr chngcnt
   288         -      puts check----$chngcnt
   289         -      set ck [btree_integrity_check $::b 1 2 3 4 5 6]
   290         -      if {$ck!=""} {
   291         -         puts "\nSANITY CHECK FAILED!\n$ck"
   292         -         exit
   293         -       }
   294         -    }
   295         -    if {$insert} {
   296         -      btree_insert $::c3 $key $data
   297         -    } else {
   298         -      btree_insert $::c4 $key $data
   299         -    }
   300         -    if {$longkey} {
   301         -      btree_insert $::c5 $basekey $keylen
   302         -    } elseif {[btree_move_to $::c5 $basekey]==0} {
   303         -      btree_delete $::c5
   304         -    }
   305         -    if {$longdata} {
   306         -      btree_insert $::c6 $basekey $datalen
   307         -    } elseif {[btree_move_to $::c6 $basekey]==0} {
   308         -      btree_delete $::c6
   309         -    }
   310         -    # For debugging - change the "0" to "1" to integrity check after
   311         -    # every change.
   312         -    if 0 {
   313         -      incr chngcnt
   314         -      puts check----$chngcnt
   315         -      set ck [btree_integrity_check $::b 1 2 3 4 5 6]
   316         -      if {$ck!=""} {
   317         -         puts "\nSANITY CHECK FAILED!\n$ck"
   318         -         exit
   319         -       }
   320         -    }
   321         -  }
   322         -}
   323         -set btree_trace 0
   324         -
   325         -# Repeat this test sequence on database of various sizes
   326         -#
   327         -set testno 2
   328         -foreach {N L} {
   329         -  10 2
   330         -  50 2
   331         -  200 3
   332         -  2000 5
   333         -} {
   334         -  puts "**** N=$N L=$L ****"
   335         -  set hash [md5file test2.bt]
   336         -  do_test btree2-$testno.1 [subst -nocommands {
   337         -    set ::c2 [btree_cursor $::b 2 1]
   338         -    set ::c3 [btree_cursor $::b 3 1]
   339         -    set ::c4 [btree_cursor $::b 4 1]
   340         -    set ::c5 [btree_cursor $::b 5 1]
   341         -    set ::c6 [btree_cursor $::b 6 1]
   342         -    btree_begin_transaction $::b
   343         -    build_db $N $L
   344         -    check_invariants
   345         -  }] {}
   346         -  do_test btree2-$testno.2 {
   347         -    btree_close_cursor $::c2
   348         -    btree_close_cursor $::c3
   349         -    btree_close_cursor $::c4
   350         -    btree_close_cursor $::c5
   351         -    btree_close_cursor $::c6
   352         -    btree_rollback $::b
   353         -    md5file test2.bt
   354         -  } $hash
   355         -  do_test btree2-$testno.3 [subst -nocommands {
   356         -    btree_begin_transaction $::b
   357         -    set ::c2 [btree_cursor $::b 2 1]
   358         -    set ::c3 [btree_cursor $::b 3 1]
   359         -    set ::c4 [btree_cursor $::b 4 1]
   360         -    set ::c5 [btree_cursor $::b 5 1]
   361         -    set ::c6 [btree_cursor $::b 6 1]
   362         -    build_db $N $L
   363         -    check_invariants
   364         -  }] {}
   365         -  do_test btree2-$testno.4 {
   366         -    btree_commit $::b
   367         -    check_invariants
   368         -  } {}
   369         -  do_test btree2-$testno.5  {
   370         -    lindex [btree_pager_stats $::b] 1
   371         -  } {6}
   372         -  do_test btree2-$testno.6  {
   373         -    btree_cursor_info $::c2
   374         -    btree_cursor_info $::c3
   375         -    btree_cursor_info $::c4
   376         -    btree_cursor_info $::c5
   377         -    btree_cursor_info $::c6
   378         -    btree_close_cursor $::c2
   379         -    btree_close_cursor $::c3
   380         -    btree_close_cursor $::c4
   381         -    btree_close_cursor $::c5
   382         -    btree_close_cursor $::c6
   383         -    lindex [btree_pager_stats $::b] 1
   384         -  } {0}
   385         -  do_test btree2-$testno.7 {
   386         -    btree_close $::b
   387         -  } {}
   388         -
   389         -  # For each database size, run various changes tests.
   390         -  #
   391         -  set num2 1
   392         -  foreach {n I K D} {
   393         -    0.5 0.5 0.1 0.1
   394         -    1.0 0.2 0.1 0.1
   395         -    1.0 0.8 0.1 0.1
   396         -    2.0 0.0 0.1 0.1
   397         -    2.0 1.0 0.1 0.1
   398         -    2.0 0.0 0.0 0.0
   399         -    2.0 1.0 0.0 0.0
   400         -  } {
   401         -    set testid btree2-$testno.8.$num2
   402         -    set hash [md5file test2.bt]
   403         -    do_test $testid.0 {
   404         -      set ::b [btree_open test2.bt 2000 0]
   405         -      set ::c2 [btree_cursor $::b 2 1]
   406         -      set ::c3 [btree_cursor $::b 3 1]
   407         -      set ::c4 [btree_cursor $::b 4 1]
   408         -      set ::c5 [btree_cursor $::b 5 1]
   409         -      set ::c6 [btree_cursor $::b 6 1]
   410         -      check_invariants
   411         -    } {}
   412         -    set cnt 6
   413         -    for {set i 2} {$i<=6} {incr i} {
   414         -      if {[lindex [btree_cursor_info [set ::c$i]] 0]!=$i} {incr cnt}
   415         -    }
   416         -    do_test $testid.1 {
   417         -      btree_begin_transaction $::b
   418         -      lindex [btree_pager_stats $::b] 1
   419         -    } $cnt
   420         -    do_test $testid.2 [subst {
   421         -      random_changes $n $I $K $D
   422         -    }] {}
   423         -    do_test $testid.3 {
   424         -      check_invariants
   425         -    } {}
   426         -    do_test $testid.4 {
   427         -      btree_close_cursor $::c2
   428         -      btree_close_cursor $::c3
   429         -      btree_close_cursor $::c4
   430         -      btree_close_cursor $::c5
   431         -      btree_close_cursor $::c6
   432         -      btree_rollback $::b
   433         -      md5file test2.bt
   434         -    } $hash
   435         -    btree_begin_transaction $::b
   436         -    set ::c2 [btree_cursor $::b 2 1]
   437         -    set ::c3 [btree_cursor $::b 3 1]
   438         -    set ::c4 [btree_cursor $::b 4 1]
   439         -    set ::c5 [btree_cursor $::b 5 1]
   440         -    set ::c6 [btree_cursor $::b 6 1]
   441         -    do_test $testid.5 [subst {
   442         -      random_changes $n $I $K $D
   443         -    }] {}
   444         -    do_test $testid.6 {
   445         -      check_invariants
   446         -    } {}
   447         -    do_test $testid.7 {
   448         -      btree_commit $::b
   449         -      check_invariants
   450         -    } {}
   451         -    set hash [md5file test2.bt]
   452         -    do_test $testid.8 {
   453         -      btree_close_cursor $::c2
   454         -      btree_close_cursor $::c3
   455         -      btree_close_cursor $::c4
   456         -      btree_close_cursor $::c5
   457         -      btree_close_cursor $::c6
   458         -      lindex [btree_pager_stats $::b] 1
   459         -    } {0}
   460         -    do_test $testid.9 {
   461         -      btree_close $::b
   462         -      set ::b [btree_open test2.bt 2000 0]
   463         -      set ::c2 [btree_cursor $::b 2 1]
   464         -      set ::c3 [btree_cursor $::b 3 1]
   465         -      set ::c4 [btree_cursor $::b 4 1]
   466         -      set ::c5 [btree_cursor $::b 5 1]
   467         -      set ::c6 [btree_cursor $::b 6 1]
   468         -      check_invariants
   469         -    } {}
   470         -    do_test $testid.10 {
   471         -      btree_close_cursor $::c2
   472         -      btree_close_cursor $::c3
   473         -      btree_close_cursor $::c4
   474         -      btree_close_cursor $::c5
   475         -      btree_close_cursor $::c6
   476         -      lindex [btree_pager_stats $::b] 1
   477         -    } {0}
   478         -    do_test $testid.11 {
   479         -      btree_close $::b
   480         -    } {}
   481         -    incr num2
   482         -  }
   483         -  incr testno
   484         -  set ::b [btree_open test2.bt 2000 0]
   485         -}  
   486         -
   487         -# Testing is complete.  Shut everything down.
   488         -#
   489         -do_test btree-999.1 {
   490         -  lindex [btree_pager_stats $::b] 1
   491         -} {0}
   492         -do_test btree-999.2 {
   493         -  btree_close $::b
   494         -} {}
   495         -do_test btree-999.3 {
   496         -  file delete -force test2.bt
   497         -  file exists test2.bt-journal
   498         -} {0}
   499         -
   500         -} ;# end if( not mem: and has pager_open command );
   501         -
   502         -finish_test

Deleted test/btree4.test.

     1         -# 2002 December 03
     2         -#
     3         -# The author disclaims copyright to this source code.  In place of
     4         -# a legal notice, here is a blessing:
     5         -#
     6         -#    May you do good and not evil.
     7         -#    May you find forgiveness for yourself and forgive others.
     8         -#    May you share freely, never taking more than you give.
     9         -#
    10         -#***********************************************************************
    11         -# This file implements regression tests for SQLite library.  The
    12         -# focus of this script is btree database backend
    13         -#
    14         -# This file focuses on testing the sqliteBtreeNext() and 
    15         -# sqliteBtreePrevious() procedures and making sure they are able
    16         -# to step through an entire table from either direction.
    17         -#
    18         -# $Id: btree4.test,v 1.2 2004/05/09 20:40:12 drh Exp $
    19         -
    20         -
    21         -set testdir [file dirname $argv0]
    22         -source $testdir/tester.tcl
    23         -
    24         -if {[info commands btree_open]!=""} {
    25         -
    26         -# Open a test database.
    27         -#
    28         -file delete -force test1.bt
    29         -file delete -force test1.bt-journal
    30         -set b1 [btree_open test1.bt 2000 0]
    31         -btree_begin_transaction $b1
    32         -do_test btree4-0.1 {
    33         -  btree_create_table $b1 0
    34         -} 2
    35         -
    36         -set data {abcdefghijklmnopqrstuvwxyz0123456789}
    37         -append data $data
    38         -append data $data
    39         -append data $data
    40         -append data $data
    41         -
    42         -foreach N {10 100 1000} {
    43         -  btree_clear_table $::b1 2
    44         -  set ::c1 [btree_cursor $::b1 2 1]
    45         -  do_test btree4-$N.1 {
    46         -    for {set i 1} {$i<=$N} {incr i} {
    47         -      btree_insert $::c1 [format k-%05d $i] $::data-$i
    48         -    }
    49         -    btree_first $::c1
    50         -    btree_key $::c1
    51         -  } {k-00001}
    52         -  do_test btree4-$N.2 {
    53         -    btree_data $::c1
    54         -  } $::data-1
    55         -  for {set i 2} {$i<=$N} {incr i} {
    56         -    do_test btree-$N.3.$i.1 {
    57         -      btree_next $::c1
    58         -    } 0
    59         -    do_test btree-$N.3.$i.2 {
    60         -      btree_key $::c1
    61         -    } [format k-%05d $i]
    62         -    do_test btree-$N.3.$i.3 {
    63         -      btree_data $::c1
    64         -    } $::data-$i
    65         -  }
    66         -  do_test btree4-$N.4 {
    67         -    btree_next $::c1
    68         -  } 1
    69         -  do_test btree4-$N.5 {
    70         -    btree_last $::c1
    71         -  } 0
    72         -  do_test btree4-$N.6 {
    73         -    btree_key $::c1
    74         -  } [format k-%05d $N]
    75         -  do_test btree4-$N.7 {
    76         -    btree_data $::c1
    77         -  } $::data-$N
    78         -  for {set i [expr {$N-1}]} {$i>=1} {incr i -1} {
    79         -    do_test btree4-$N.8.$i.1 {
    80         -      btree_prev $::c1
    81         -    } 0
    82         -    do_test btree4-$N.8.$i.2 {
    83         -      btree_key $::c1
    84         -    } [format k-%05d $i]
    85         -    do_test btree4-$N.8.$i.3 {
    86         -      btree_data $::c1
    87         -    } $::data-$i
    88         -  }
    89         -  do_test btree4-$N.9 {
    90         -    btree_prev $::c1
    91         -  } 1
    92         -  btree_close_cursor $::c1
    93         -}
    94         -
    95         -btree_rollback $::b1    
    96         -btree_pager_ref_dump $::b1
    97         -btree_close $::b1
    98         -
    99         -} ;# end if( not mem: and has pager_open command );
   100         -
   101         -finish_test

Deleted test/btree5.test.

     1         -# 2004 May 10
     2         -#
     3         -# The author disclaims copyright to this source code.  In place of
     4         -# a legal notice, here is a blessing:
     5         -#
     6         -#    May you do good and not evil.
     7         -#    May you find forgiveness for yourself and forgive others.
     8         -#    May you share freely, never taking more than you give.
     9         -#
    10         -#***********************************************************************
    11         -# This file implements regression tests for SQLite library.  The
    12         -# focus of this script is btree database backend
    13         -#
    14         -# $Id: btree5.test,v 1.5 2004/05/14 12:17:46 drh Exp $
    15         -
    16         -
    17         -set testdir [file dirname $argv0]
    18         -source $testdir/tester.tcl
    19         -
    20         -# Attempting to read table 1 of an empty file gives an SQLITE_EMPTY
    21         -# error.
    22         -#
    23         -do_test btree5-1.1 {
    24         -  file delete -force test1.bt
    25         -  file delete -force test1.bt-journal
    26         -  set rc [catch {btree_open test1.bt 2000 0} ::b1]
    27         -} {0}
    28         -do_test btree5-1.2 {
    29         -  set rc [catch {btree_cursor $::b1 1 0} ::c1]
    30         -} {1}
    31         -do_test btree5-1.3 {
    32         -  set ::c1
    33         -} {SQLITE_EMPTY}
    34         -do_test btree5-1.4 {
    35         -  set rc [catch {btree_cursor $::b1 1 1} ::c1]
    36         -} {1}
    37         -do_test btree5-1.5 {
    38         -  set ::c1
    39         -} {SQLITE_EMPTY}
    40         -
    41         -# Starting a transaction initializes the first page of the database
    42         -# and the error goes away.
    43         -#
    44         -do_test btree5-1.6 {
    45         -  btree_begin_transaction $b1
    46         -  set rc [catch {btree_cursor $b1 1 0} c1]
    47         -} {0}
    48         -do_test btree5-1.7 {
    49         -  btree_first $c1
    50         -} {1}
    51         -do_test btree5-1.8 {
    52         -  btree_close_cursor $c1
    53         -  btree_rollback $b1
    54         -  set rc [catch {btree_cursor $b1 1 0} c1]
    55         -} {1}
    56         -do_test btree5-1.9 {
    57         -  set c1
    58         -} {SQLITE_EMPTY}
    59         -do_test btree5-1.10 {
    60         -  btree_begin_transaction $b1
    61         -  set rc [catch {btree_cursor $b1 1 0} c1]
    62         -} {0}
    63         -do_test btree5-1.11 {
    64         -  btree_first $c1
    65         -} {1}
    66         -do_test btree5-1.12 {
    67         -  btree_close_cursor $c1
    68         -  btree_commit $b1
    69         -  set rc [catch {btree_cursor $b1 1 0} c1]
    70         -} {0}
    71         -do_test btree5-1.13 {
    72         -  btree_first $c1
    73         -} {1}
    74         -do_test btree5-1.14 {
    75         -  btree_close_cursor $c1
    76         -  btree_integrity_check $b1 1
    77         -} {}
    78         -
    79         -# Insert many entries into table 1.  This is designed to test the
    80         -# virtual-root logic that comes into play for page one.  It is also
    81         -# a good test of INTKEY tables.
    82         -#
    83         -# Stagger the inserts.  After the inserts complete, go back and do
    84         -# deletes.  Stagger the deletes too.  Repeat this several times.
    85         -#
    86         -
    87         -# Do N inserts into table 1 using random keys between 0 and 1000000
    88         -#
    89         -proc random_inserts {N} {
    90         -  global c1
    91         -  while {$N>0} {
    92         -    set k [expr {int(rand()*1000000)}]
    93         -    if {[btree_move_to $c1 $k]==0} continue;  # entry already exists
    94         -    btree_insert $c1 $k data-for-$k
    95         -    incr N -1
    96         -  }
    97         -}
    98         -
    99         -# Do N delete from table 1
   100         -#
   101         -proc random_deletes {N} {
   102         -  global c1
   103         -  while {$N>0} {
   104         -    set k [expr {int(rand()*1000000)}]
   105         -    btree_move_to $c1 $k
   106         -    btree_delete $c1
   107         -    incr N -1
   108         -  }
   109         -}
   110         -
   111         -# Make sure the table has exactly N entries.  Make sure the data for
   112         -# each entry agrees with its key.
   113         -#
   114         -proc check_table {N} {
   115         -  global c1
   116         -  btree_first $c1
   117         -  set cnt 0
   118         -  while {![btree_eof $c1]} {
   119         -    if {[set data [btree_data $c1]] ne "data-for-[btree_key $c1]"} {
   120         -      return "wrong data for entry $cnt"
   121         -    }
   122         -    set n [string length $data]
   123         -    set fdata1 [btree_fetch_data $c1 $n]
   124         -    set fdata2 [btree_fetch_data $c1 -1]
   125         -    if {$fdata1 ne "" && $fdata1 ne $data} {
   126         -      return "DataFetch returned the wrong value with amt=$n"
   127         -    }
   128         -    if {$fdata1 ne $fdata2} {
   129         -      return "DataFetch returned the wrong value when amt=-1"
   130         -    }
   131         -    if {$n>10} {
   132         -      set fdata3 [btree_fetch_data $c1 10]
   133         -      if {$fdata3 ne [string range $data 0 9]} {
   134         -        return "DataFetch returned the wrong value when amt=10"
   135         -      }
   136         -    }
   137         -    incr cnt
   138         -    btree_next $c1
   139         -  }
   140         -  if {$cnt!=$N} {
   141         -    return "wrong number of entries"
   142         -  }
   143         -  return {}
   144         -}
   145         -
   146         -# Initialize the database
   147         -#
   148         -btree_begin_transaction $b1
   149         -set c1 [btree_cursor $b1 1 1]
   150         -set btree_trace 0
   151         -
   152         -# Do the tests.
   153         -#
   154         -set cnt 0
   155         -for {set i 1} {$i<=100} {incr i} {
   156         -  do_test btree5-2.$i.1 {
   157         -    random_inserts 200
   158         -    incr cnt 200
   159         -    check_table $cnt
   160         -  } {}
   161         -  do_test btree5-2.$i.2 {
   162         -    btree_integrity_check $b1 1
   163         -  } {}
   164         -  do_test btree5-2.$i.3 {
   165         -    random_deletes 190
   166         -    incr cnt -190
   167         -    check_table $cnt
   168         -  } {}
   169         -  do_test btree5-2.$i.4 {
   170         -    btree_integrity_check $b1 1
   171         -  } {}
   172         -}
   173         -
   174         -#btree_tree_dump $b1 1
   175         -btree_close_cursor $c1
   176         -btree_commit $b1
   177         -btree_begin_transaction $b1
   178         -
   179         -# This procedure converts an integer into a variable-length text key.
   180         -# The conversion is reversible.
   181         -#
   182         -# The first two characters of the string are alphabetics derived from
   183         -# the least significant bits of the number.  Because they are derived
   184         -# from least significant bits, the sort order of the resulting string
   185         -# is different from numeric order.  After the alphabetic prefix comes
   186         -# the original number.  A variable-length suffix follows.  The length
   187         -# of the suffix is based on a hash of the original number.
   188         -# 
   189         -proc num_to_key {n} {
   190         -  global charset ncharset suffix
   191         -  set c1 [string index $charset [expr {$n%$ncharset}]]
   192         -  set c2 [string index $charset [expr {($n/$ncharset)%$ncharset}]]
   193         -  set nsuf [expr {($n*211)%593}]
   194         -  return $c1$c2-$n-[string range $suffix 0 $nsuf]
   195         -}
   196         -set charset {abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ}
   197         -set ncharset [string length $charset]
   198         -set suffix $charset$charset
   199         -while {[string length $suffix]<1000} {append suffix $suffix}
   200         -
   201         -# This procedures extracts the original integer used to create
   202         -# a key by num_to_key
   203         -#
   204         -proc key_to_num {key} {
   205         -  regexp {^..-([0-9]+)} $key all n
   206         -  return $n
   207         -}
   208         -
   209         -# Insert into table $tab keys corresponding to all values between
   210         -# $start and $end, inclusive.
   211         -#
   212         -proc insert_range {tab start end} {
   213         -  for {set i $start} {$i<=$end} {incr i} {
   214         -    btree_insert $tab [num_to_key $i] {}
   215         -  }
   216         -}
   217         -
   218         -# Delete from table $tab keys corresponding to all values between
   219         -# $start and $end, inclusive.
   220         -#
   221         -proc delete_range {tab start end} {
   222         -  for {set i $start} {$i<=$end} {incr i} {
   223         -    if {[btree_move_to $tab [num_to_key $i]]==0} {
   224         -      btree_delete $tab
   225         -    }
   226         -  }
   227         -}
   228         -
   229         -# Make sure table $tab contains exactly those keys corresponding
   230         -# to values between $start and $end
   231         -#
   232         -proc check_range {tab start end} {
   233         -  btree_first $tab
   234         -  while {![btree_eof $tab]} {
   235         -    set key [btree_key $tab]
   236         -    set i [key_to_num $key]
   237         -    if {[num_to_key $i] ne $key} {
   238         -      return "malformed key: $key"
   239         -    }
   240         -    set got($i) 1
   241         -    btree_next $tab
   242         -  }
   243         -  set all [lsort -integer [array names got]]
   244         -  if {[llength $all]!=$end+1-$start} {
   245         -    return "table contains wrong number of values"
   246         -  }
   247         -  if {[lindex $all 0]!=$start} {
   248         -    return "wrong starting value"
   249         -  }
   250         -  if {[lindex $all end]!=$end} {
   251         -    return "wrong ending value"
   252         -  }
   253         -  return {}
   254         -}
   255         -
   256         -# Create a zero-data table and test it out.
   257         -#
   258         -do_test btree5-3.1 {
   259         -  set rc [catch {btree_create_table $b1 2} t2]
   260         -} {0}
   261         -do_test btree5-3.2 {
   262         -  set rc [catch {btree_cursor $b1 $t2 1} c2]
   263         -} {0}
   264         -set start 1
   265         -set end 100
   266         -for {set i 1} {$i<=100} {incr i} {
   267         -  do_test btree5-3.3.$i.1 {
   268         -    insert_range $c2 $start $end
   269         -    btree_integrity_check $b1 1 $t2
   270         -  } {}
   271         -  do_test btree5-3.3.$i.2 {
   272         -    check_range $c2 $start $end
   273         -  } {}
   274         -  set nstart $start
   275         -  incr nstart 89
   276         -  do_test btree5-3.3.$i.3 {
   277         -    delete_range $c2 $start $nstart
   278         -    btree_integrity_check $b1 1 $t2
   279         -  } {}
   280         -  incr start 90
   281         -  do_test btree5-3.3.$i.4 {
   282         -    check_range $c2 $start $end
   283         -  } {}
   284         -  incr end 100
   285         -}
   286         -
   287         -
   288         -btree_close_cursor $c2
   289         -btree_commit $b1
   290         -btree_close $b1
   291         -
   292         -finish_test

Deleted test/btree6.test.

     1         -# 2004 May 10
     2         -#
     3         -# The author disclaims copyright to this source code.  In place of
     4         -# a legal notice, here is a blessing:
     5         -#
     6         -#    May you do good and not evil.
     7         -#    May you find forgiveness for yourself and forgive others.
     8         -#    May you share freely, never taking more than you give.
     9         -#
    10         -#***********************************************************************
    11         -# This file implements regression tests for SQLite library.  The
    12         -# focus of this script is btree database backend - specifically
    13         -# the B+tree tables.  B+trees store all data on the leaves rather
    14         -# that storing data with keys on interior nodes.
    15         -#
    16         -# $Id: btree6.test,v 1.4 2004/05/20 22:16:31 drh Exp $
    17         -
    18         -
    19         -set testdir [file dirname $argv0]
    20         -source $testdir/tester.tcl
    21         -
    22         -
    23         -# Insert many entries into the table that cursor $cur points to.
    24         -# The table should be an INTKEY table.
    25         -#
    26         -# Stagger the inserts.  After the inserts complete, go back and do
    27         -# deletes.  Stagger the deletes too.  Repeat this several times.
    28         -#
    29         -
    30         -# Do N inserts into table $tab using random keys between 0 and 1000000
    31         -#
    32         -proc random_inserts {cur N} {
    33         -  global inscnt
    34         -  while {$N>0} {
    35         -    set k [expr {int(rand()*1000000)}]
    36         -    if {[btree_move_to $cur $k]==0} {
    37         -      continue;  # entry already exists
    38         -    }
    39         -    incr inscnt
    40         -    btree_insert $cur $k data-for-$k
    41         -    incr N -1
    42         -  }
    43         -}
    44         -set inscnt 0
    45         -
    46         -# Do N delete from the table that $cur points to.
    47         -#
    48         -proc random_deletes {cur N} {
    49         -  while {$N>0} {
    50         -    set k [expr {int(rand()*1000000)}]
    51         -    btree_move_to $cur $k
    52         -    btree_delete $cur
    53         -    incr N -1
    54         -  }
    55         -}
    56         -
    57         -# Make sure the table that $cur points to has exactly N entries.  
    58         -# Make sure the data for each entry agrees with its key.
    59         -#
    60         -proc check_table {cur N} {
    61         -  btree_first $cur
    62         -  set cnt 0
    63         -  while {![btree_eof $cur]} {
    64         -    if {[set data [btree_data $cur]] ne "data-for-[btree_key $cur]"} {
    65         -      return "wrong data for entry $cnt"
    66         -    }
    67         -    set n [string length $data]
    68         -    set fdata1 [btree_fetch_data $cur $n]
    69         -    set fdata2 [btree_fetch_data $cur -1]
    70         -    if {$fdata1 ne "" && $fdata1 ne $data} {
    71         -      return "DataFetch returned the wrong value with amt=$n"
    72         -    }
    73         -    if {$fdata1 ne $fdata2} {
    74         -      return "DataFetch returned the wrong value when amt=-1"
    75         -    }
    76         -    if {$n>10} {
    77         -      set fdata3 [btree_fetch_data $cur 10]
    78         -      if {$fdata3 ne [string range $data 0 9]} {
    79         -        return "DataFetch returned the wrong value when amt=10"
    80         -      }
    81         -    }
    82         -    incr cnt
    83         -    btree_next $cur
    84         -  }
    85         -  if {$cnt!=$N} {
    86         -    return "wrong number of entries.  Got $cnt.  Looking for $N"
    87         -  }
    88         -  return {}
    89         -}
    90         -
    91         -# Initialize the database
    92         -#
    93         -file delete -force test1.bt
    94         -file delete -force test1.bt-journal
    95         -set b1 [btree_open test1.bt 2000 0]
    96         -btree_begin_transaction $b1
    97         -set tab [btree_create_table $b1 5]
    98         -set cur [btree_cursor $b1 $tab 1]
    99         -set btree_trace 0
   100         -expr srand(1)
   101         -
   102         -# Do the tests.
   103         -#
   104         -set cnt 0
   105         -for {set i 1} {$i<=40} {incr i} {
   106         -  do_test btree6-1.$i.1 {
   107         -    random_inserts $cur 200
   108         -    incr cnt 200
   109         -    check_table $cur $cnt
   110         -  } {}
   111         -  do_test btree6-1.$i.2 {
   112         -    btree_integrity_check $b1 1 $tab
   113         -  } {}
   114         -  do_test btree6-1.$i.3 {
   115         -    random_deletes $cur 90
   116         -    incr cnt -90
   117         -    check_table $cur $cnt
   118         -  } {}
   119         -  do_test btree6-1.$i.4 {
   120         -    btree_integrity_check $b1 1 $tab
   121         -  } {}
   122         -}
   123         -
   124         -btree_close_cursor $cur
   125         -btree_commit $b1
   126         -btree_close $b1
   127         -
   128         -finish_test

Deleted test/btree7.test.

     1         -# 2004 Jun 4	
     2         -#
     3         -# The author disclaims copyright to this source code.  In place of
     4         -# a legal notice, here is a blessing:
     5         -#
     6         -#    May you do good and not evil.
     7         -#    May you find forgiveness for yourself and forgive others.
     8         -#    May you share freely, never taking more than you give.
     9         -#
    10         -#***********************************************************************
    11         -# This file implements regression tests for SQLite library.  The
    12         -# focus of this script is btree database backend.
    13         -#
    14         -# $Id: btree7.test,v 1.2 2004/11/04 14:47:13 drh Exp $
    15         -
    16         -
    17         -set testdir [file dirname $argv0]
    18         -source $testdir/tester.tcl
    19         -
    20         -# Stress the balance routine by trying to create situations where
    21         -# 3 neighboring nodes split into 5.
    22         -#
    23         -set bigdata _123456789    ;#  10
    24         -append bigdata $bigdata   ;#  20
    25         -append bigdata $bigdata   ;#  40
    26         -append bigdata $bigdata   ;#  80
    27         -append bigdata $bigdata   ;# 160
    28         -append bigdata $bigdata   ;# 320
    29         -append bigdata $bigdata   ;# 640
    30         -set data450 [string range $bigdata 0 449]
    31         -do_test btree7-1.1 {
    32         -  execsql "
    33         -    CREATE TABLE t1(x INTEGER PRIMARY KEY, y TEXT);
    34         -    INSERT INTO t1 VALUES(1, '$bigdata');
    35         -    INSERT INTO t1 VALUES(2, '$bigdata');
    36         -    INSERT INTO t1 VALUES(3, '$data450');
    37         -    INSERT INTO t1 VALUES(5, '$data450');
    38         -    INSERT INTO t1 VALUES(8, '$bigdata');
    39         -    INSERT INTO t1 VALUES(9, '$bigdata');
    40         -  "
    41         -} {}
    42         -integrity_check btree7-1.2
    43         -do_test btree7-1.3 {
    44         -  execsql "
    45         -    INSERT INTO t1 VALUES(4, '$bigdata');
    46         -  "
    47         -} {}
    48         -integrity_check btree7-1.4
    49         -
    50         -finish_test

Deleted test/btree8.test.

     1         -# 2005 August 2
     2         -#
     3         -# The author disclaims copyright to this source code.  In place of
     4         -# a legal notice, here is a blessing:
     5         -#
     6         -#    May you do good and not evil.
     7         -#    May you find forgiveness for yourself and forgive others.
     8         -#    May you share freely, never taking more than you give.
     9         -#
    10         -#***********************************************************************
    11         -# This file implements regression tests for SQLite library.  The
    12         -# focus of this script is btree database backend.
    13         -#
    14         -# $Id: btree8.test,v 1.6 2005/08/02 17:13:12 drh Exp $
    15         -
    16         -set testdir [file dirname $argv0]
    17         -source $testdir/tester.tcl
    18         -
    19         -# Ticket #1346:  If the table rooted on page 1 contains a single entry
    20         -# and that single entries has to flow out into another page because
    21         -# page 1 is 100-bytes smaller than most other pages, then you delete that
    22         -# one entry, everything should still work.
    23         -#
    24         -do_test btree8-1.1 {
    25         -  execsql {
    26         -CREATE TABLE t1(x
    27         - ----------------------------------------------------------------------------
    28         - ----------------------------------------------------------------------------
    29         - ----------------------------------------------------------------------------
    30         - ----------------------------------------------------------------------------
    31         - ----------------------------------------------------------------------------
    32         - ----------------------------------------------------------------------------
    33         - ----------------------------------------------------------------------------
    34         - ----------------------------------------------------------------------------
    35         - ----------------------------------------------------------------------------
    36         - ----------------------------------------------------------------------------
    37         - ----------------------------------------------------------------------------
    38         - ----------------------------------------------------------------------------
    39         -);
    40         -DROP table t1;
    41         -  }
    42         -} {}
    43         -integrity_check btree8-1.2

Deleted test/btree9.test.

     1         -# 2007 May 01
     2         -#
     3         -# The author disclaims copyright to this source code.  In place of
     4         -# a legal notice, here is a blessing:
     5         -#
     6         -#    May you do good and not evil.
     7         -#    May you find forgiveness for yourself and forgive others.
     8         -#    May you share freely, never taking more than you give.
     9         -#
    10         -#***********************************************************************
    11         -# This file implements regression tests for SQLite library.  The
    12         -# focus of this script is btree database backend.
    13         -#
    14         -# $Id: btree9.test,v 1.1 2007/05/02 01:34:32 drh Exp $
    15         -
    16         -set testdir [file dirname $argv0]
    17         -source $testdir/tester.tcl
    18         -
    19         -# The sqlite3BtreeInsert() API now has an additional "nZero" parameter
    20         -# which specifies the number of zero bytes to append to the end of the
    21         -# data.  This feature allows large zero-filled BLOBs to be created without
    22         -# having to allocate a big chunk of memory to instantiate the blob.
    23         -#
    24         -# The following code tests the new feature.
    25         -#
    26         -
    27         -# Create the database
    28         -#
    29         -do_test btree9-1.1 {
    30         -  file delete -force test1.bt
    31         -  file delete -force test1.bt-journal
    32         -  set b1 [btree_open test1.bt 2000 0]
    33         -  btree_begin_transaction $b1
    34         -  set t1 [btree_create_table $b1 5]
    35         -  set c1 [btree_cursor $b1 $t1 1]
    36         -  btree_insert $c1 1 data-for-1 20000
    37         -  btree_move_to $c1 1
    38         -  btree_key $c1
    39         -} {1}
    40         -do_test btree9-1.2 {
    41         -  btree_payload_size $c1
    42         -} {20010}
    43         -
    44         -
    45         -btree_close_cursor $c1
    46         -btree_commit $b1
    47         -btree_close $b1
    48         -
    49         -finish_test

Changes to test/quick.test.

     2      2   #    May you do good and not evil.
     3      3   #    May you find forgiveness for yourself and forgive others.
     4      4   #    May you share freely, never taking more than you give.
     5      5   #
     6      6   #***********************************************************************
     7      7   # This file runs all tests.
     8      8   #
     9         -# $Id: quick.test,v 1.72 2008/03/22 01:08:01 drh Exp $
            9  +# $Id: quick.test,v 1.73 2008/03/25 00:22:22 drh Exp $
    10     10   
    11     11   proc lshift {lvar} {
    12     12     upvar $lvar l
    13     13     set ret [lindex $l 0]
    14     14     set l [lrange $l 1 end]
    15     15     return $ret
    16     16   }
................................................................................
    35     35   proc finish_test {} {}
    36     36   set ISQUICK 1
    37     37   
    38     38   set EXCLUDE {
    39     39     all.test
    40     40     async.test
    41     41     async2.test
    42         -  btree2.test
    43         -  btree3.test
    44         -  btree4.test
    45         -  btree5.test
    46         -  btree6.test
    47     42     corrupt.test
    48     43     crash.test
    49     44     crash2.test
    50     45     crash3.test
    51     46     crash4.test
    52     47     crash6.test
    53     48     crash7.test