/ Check-in [bc5a2daf]
Login

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

Overview
Comment:Work toward getting the new btree.c integrated with vdbe.c. (CVS 1345)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: bc5a2dafa1df74ba6403b4751ac1c33b0fee2884
User & Date: drh 2004-05-10 23:29:49
Context
2004-05-11
00:28
Change to OP_PutIntKey to use new btree API. (CVS 1346) check-in: c080fed7 user: danielk1977 tags: trunk
2004-05-10
23:29
Work toward getting the new btree.c integrated with vdbe.c. (CVS 1345) check-in: bc5a2daf user: drh tags: trunk
18:45
The btree.c module passes all tests and is ready for integration. Still need to go back and do coverage testing. (CVS 1343) check-in: 84506b23 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.123 2004/05/10 18:45:10 drh Exp $
           12  +** $Id: btree.c,v 1.124 2004/05/10 23:29:49 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.
................................................................................
  1890   1890       return pCur->status;
  1891   1891     }
  1892   1892     rc = moveToRoot(pCur);
  1893   1893     if( rc ) return rc;
  1894   1894     assert( pCur->pPage );
  1895   1895     assert( pCur->pPage->isInit );
  1896   1896     if( pCur->isValid==0 ){
         1897  +    *pRes = -1;
  1897   1898       assert( pCur->pPage->nCell==0 );
  1898   1899       return SQLITE_OK;
  1899   1900     }
  1900   1901     for(;;){
  1901   1902       int lwr, upr;
  1902   1903       Pgno chldPg;
  1903   1904       MemPage *pPage = pCur->pPage;
................................................................................
  3156   3157     assert( pPage->isInit );
  3157   3158     rc = sqlite3pager_write(pPage->aData);
  3158   3159     if( rc ) return rc;
  3159   3160     rc = fillInCell(pPage, newCell, pKey, nKey, pData, nData, &szNew);
  3160   3161     if( rc ) return rc;
  3161   3162     assert( szNew==cellSize(pPage, newCell) );
  3162   3163     assert( szNew<=sizeof(newCell) );
  3163         -  if( loc==0 ){
         3164  +  if( loc==0 && pCur->isValid ){
  3164   3165       int szOld;
  3165   3166       assert( pCur->idx>=0 && pCur->idx<pPage->nCell );
  3166   3167       oldCell = pPage->aCell[pCur->idx];
  3167   3168       if( !pPage->leaf ){
  3168   3169         memcpy(&newCell[2], &oldCell[2], 4);
  3169   3170       }
  3170   3171       szOld = cellSize(pPage, oldCell);
................................................................................
  3420   3421     assert( pBt->pPage1!=0 );
  3421   3422     pP1 = pBt->pPage1->aData;
  3422   3423     rc = sqlite3pager_write(pP1);
  3423   3424     if( rc ) return rc;
  3424   3425     put4byte(&pP1[36 + idx*4], iMeta);
  3425   3426     return SQLITE_OK;
  3426   3427   }
         3428  +
         3429  +/*
         3430  +** Return the flag byte at the beginning of the page that the cursor
         3431  +** is currently pointing to.
         3432  +*/
         3433  +int sqlite3BtreeFlags(BtCursor *pCur){
         3434  +  MemPage *pPage = pCur->pPage;
         3435  +  return pPage ? pPage->aData[pPage->hdrOffset] : 0;
         3436  +}
  3427   3437   
  3428   3438   /******************************************************************************
  3429   3439   ** The complete implementation of the BTree subsystem is above this line.
  3430   3440   ** All the code the follows is for testing and troubleshooting the BTree
  3431   3441   ** subsystem.  None of the code that follows is used during normal operation.
  3432   3442   ******************************************************************************/
  3433   3443   
................................................................................
  3524   3534       }
  3525   3535       sqlite3BtreePageDump(pBt, get4byte(&data[hdr+6]), 1);
  3526   3536     }
  3527   3537     sqlite3pager_unref(data);
  3528   3538     fflush(stdout);
  3529   3539     return SQLITE_OK;
  3530   3540   }
  3531         -#endif
  3532         -
  3533         -#ifdef SQLITE_TEST
  3534         -/*
  3535         -** Return the flag byte at the beginning of the page that the cursor
  3536         -** is currently pointing to.
  3537         -*/
  3538         -int sqlite3BtreeFlags(BtCursor *pCur){
  3539         -  return pCur->pPage->aData[pCur->pPage->hdrOffset];
  3540         -}
  3541   3541   #endif
  3542   3542   
  3543   3543   #ifdef SQLITE_TEST
  3544   3544   /*
  3545   3545   ** Fill aResult[] with information about the entry and page that the
  3546   3546   ** cursor is pointing to.
  3547   3547   ** 

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.43 2004/05/09 23:23:57 danielk1977 Exp $
           16  +** @(#) $Id: btree.h,v 1.44 2004/05/10 23:29:50 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   */
................................................................................
    77     77   int sqlite3BtreeDelete(BtCursor*);
    78     78   int sqlite3BtreeInsert(BtCursor*, const void *pKey, u64 nKey,
    79     79                                     const void *pData, int nData);
    80     80   int sqlite3BtreeFirst(BtCursor*, int *pRes);
    81     81   int sqlite3BtreeLast(BtCursor*, int *pRes);
    82     82   int sqlite3BtreeNext(BtCursor*, int *pRes);
    83     83   int sqlite3BtreeEof(BtCursor*);
           84  +int sqlite3BtreeFlags(BtCursor*);
    84     85   int sqlite3BtreePrevious(BtCursor*, int *pRes);
    85     86   int sqlite3BtreeKeySize(BtCursor*, u64 *pSize);
    86     87   int sqlite3BtreeKey(BtCursor*, u32 offset, u32 amt, void*);
    87     88   void *sqlite3BtreeKeyFetch(BtCursor*);
    88     89   int sqlite3BtreeDataSize(BtCursor*, u32 *pSize);
    89     90   int sqlite3BtreeData(BtCursor*, u32 offset, u32 amt, void*);
    90     91   
    91     92   char *sqlite3BtreeIntegrityCheck(Btree*, int *aRoot, int nRoot);
    92     93   struct Pager *sqlite3BtreePager(Btree*);
           94  +
    93     95   
    94     96   #ifdef SQLITE_TEST
    95     97   int sqlite3BtreeCursorInfo(BtCursor*, int*);
    96     98   void sqlite3BtreeCursorList(Btree*);
    97         -int sqlite3BtreeFlags(BtCursor*);
    98     99   int sqlite3BtreePageDump(Btree*, int, int recursive);
    99    100   #endif
   100    101   
   101    102   
   102    103   #endif /* _BTREE_H_ */

Changes to src/main.c.

    10     10   **
    11     11   *************************************************************************
    12     12   ** Main file for the SQLite library.  The routines in this file
    13     13   ** implement the programmer interface to the library.  Routines in
    14     14   ** other files are for internal use by SQLite and should not be
    15     15   ** accessed by users of the library.
    16     16   **
    17         -** $Id: main.c,v 1.168 2004/05/10 10:34:43 danielk1977 Exp $
           17  +** $Id: main.c,v 1.169 2004/05/10 23:29:50 drh Exp $
    18     18   */
    19     19   #include "sqliteInt.h"
    20     20   #include "os.h"
    21     21   #include <ctype.h>
    22     22   
    23     23   /*
    24     24   ** A pointer to this structure is used to communicate information
................................................................................
   213    213        "  tbl_name text,\n"
   214    214        "  rootpage integer,\n"
   215    215        "  sql text\n"
   216    216        ")"
   217    217     ;
   218    218   
   219    219     /* The following SQL will read the schema from the master tables.
   220         -  ** The first version works with SQLite file formats 2 or greater.
   221         -  ** The second version is for format 1 files.
   222         -  **
   223         -  ** Beginning with file format 2, the rowid for new table entries
   224         -  ** (including entries in sqlite_master) is an increasing integer.
   225         -  ** So for file format 2 and later, we can play back sqlite_master
   226         -  ** and all the CREATE statements will appear in the right order.
   227         -  ** But with file format 1, table entries were random and so we
   228         -  ** have to make sure the CREATE TABLEs occur before their corresponding
   229         -  ** CREATE INDEXs.  (We don't have to deal with CREATE VIEW or
   230         -  ** CREATE TRIGGER in file format 1 because those constructs did
   231         -  ** not exist then.) 
   232    220     */
   233    221     static char init_script[] = 
   234         -/****** FIX ME
   235    222        "SELECT type, name, rootpage, sql, 1 FROM sqlite_temp_master "
   236    223        "UNION ALL "
   237         -*/
   238    224        "SELECT type, name, rootpage, sql, 0 FROM sqlite_master";
   239         -  static char older_init_script[] = 
   240         -     "SELECT type, name, rootpage, sql, 1 FROM sqlite_temp_master "
   241         -     "UNION ALL "
   242         -     "SELECT type, name, rootpage, sql, 0 FROM sqlite_master "
   243         -     "WHERE type='table' "
   244         -     "UNION ALL "
   245         -     "SELECT type, name, rootpage, sql, 0 FROM sqlite_master "
   246         -     "WHERE type='index'";
   247         -
   248    225   
   249    226     assert( iDb>=0 && iDb!=1 && iDb<db->nDb );
   250    227   
   251    228     /* Construct the schema tables: sqlite_master and sqlite_temp_master
   252    229     */
   253    230     sqlite3SafetyOff(db);
   254    231     azArg[0] = "table";
................................................................................
   277    254     }
   278    255     sqlite3SafetyOn(db);
   279    256   
   280    257     /* Create a cursor to hold the database open
   281    258     */
   282    259     if( db->aDb[iDb].pBt==0 ) return SQLITE_OK;
   283    260     rc = sqlite3BtreeCursor(db->aDb[iDb].pBt, MASTER_ROOT, 0, 0, 0, &curMain);
   284         -  if( rc ){
          261  +  if( rc!=SQLITE_OK && rc!=SQLITE_EMPTY ){
   285    262       sqlite3SetString(pzErrMsg, sqlite3_error_string(rc), (char*)0);
   286    263       return rc;
   287    264     }
   288    265   
   289    266     /* Get the database meta information
   290    267     */
   291         -  {
   292         -    int ii;
   293         -    for(ii=0; rc==SQLITE_OK && ii<SQLITE_N_BTREE_META; ii++){
   294         -      rc = sqlite3BtreeGetMeta(db->aDb[iDb].pBt, ii+1, &meta[ii]);
          268  +  if( rc==SQLITE_OK ){
          269  +    int i;
          270  +    for(i=0; rc==SQLITE_OK && i<SQLITE_N_BTREE_META; i++){
          271  +      rc = sqlite3BtreeGetMeta(db->aDb[iDb].pBt, i+1, &meta[i]);
   295    272       }
   296         -  }
   297         -  if( rc ){
   298         -    sqlite3SetString(pzErrMsg, sqlite3_error_string(rc), (char*)0);
   299         -    sqlite3BtreeCloseCursor(curMain);
   300         -    return rc;
          273  +    if( rc ){
          274  +      sqlite3SetString(pzErrMsg, sqlite3_error_string(rc), (char*)0);
          275  +      sqlite3BtreeCloseCursor(curMain);
          276  +      return rc;
          277  +    }
          278  +  }else{
          279  +    memset(meta, 0, sizeof(meta));
   301    280     }
   302    281     db->aDb[iDb].schema_cookie = meta[1];
   303    282     if( iDb==0 ){
   304    283       db->next_cookie = meta[1];
   305    284       db->file_format = meta[2];
   306    285       size = meta[3];
   307    286       if( size==0 ){ size = MAX_PAGES; }
................................................................................
   309    288       db->safety_level = meta[4];
   310    289       if( meta[6]>0 && meta[6]<=2 && db->temp_store==0 ){
   311    290         db->temp_store = meta[6];
   312    291       }
   313    292       if( db->safety_level==0 ) db->safety_level = 2;
   314    293   
   315    294       /*
   316         -    **  file_format==1    Version 2.1.0.
   317         -    **  file_format==2    Version 2.2.0. Add support for INTEGER PRIMARY KEY.
   318         -    **  file_format==3    Version 2.6.0. Fix empty-string index bug.
   319         -    **  file_format==4    Version 2.7.0. Add support for separate numeric and
   320         -    **                    text datatypes.
          295  +    **  file_format==1    Version 3.0.0.
   321    296       */
   322    297       if( db->file_format==0 ){
   323    298         /* This happens if the database was initially empty */
   324         -      db->file_format = 4;
   325         -    }else if( db->file_format>4 ){
          299  +      db->file_format = 1;
          300  +    }else if( db->file_format>1 ){
   326    301         sqlite3BtreeCloseCursor(curMain);
   327    302         sqlite3SetString(pzErrMsg, "unsupported file format", (char*)0);
   328    303         return SQLITE_ERROR;
   329    304       }
   330         -  }else if( db->file_format!=meta[2] || db->file_format<4 ){
   331         -    assert( db->file_format>=4 );
          305  +  }else if( db->file_format!=meta[2] ){
   332    306       if( meta[2]==0 ){
   333    307         sqlite3SetString(pzErrMsg, "cannot attach empty database: ",
   334    308            db->aDb[iDb].zName, (char*)0);
   335    309       }else{
   336    310         sqlite3SetString(pzErrMsg, "incompatible file format in auxiliary "
   337    311            "database: ", db->aDb[iDb].zName, (char*)0);
   338    312       }
................................................................................
   343    317     sqlite3BtreeSetCacheSize(db->aDb[iDb].pBt, db->cache_size);
   344    318     sqlite3BtreeSetSafetyLevel(db->aDb[iDb].pBt, meta[4]==0 ? 2 : meta[4]);
   345    319   
   346    320     /* Read the schema information out of the schema tables
   347    321     */
   348    322     assert( db->init.busy );
   349    323     sqlite3SafetyOff(db);
   350         -  if( iDb==0 ){
   351         -    rc = sqlite3_exec(db, 
   352         -        db->file_format>=2 ? init_script : older_init_script,
   353         -        sqlite3InitCallback, &initData, 0);
          324  +  if( rc==SQLITE_EMPTY ){
          325  +    /* For an empty database, there is nothing to read */
          326  +    rc = SQLITE_OK;
   354    327     }else{
   355         -    char *zSql = 0;
   356         -    sqlite3SetString(&zSql, 
   357         -       "SELECT type, name, rootpage, sql, ", zDbNum, " FROM \"",
   358         -       db->aDb[iDb].zName, "\".sqlite_master", (char*)0);
   359         -    rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0);
   360         -    sqliteFree(zSql);
          328  +    if( iDb==0 ){
          329  +      rc = sqlite3_exec(db, init_script, sqlite3InitCallback, &initData, 0);
          330  +    }else{
          331  +      char *zSql = 0;
          332  +      sqlite3SetString(&zSql, 
          333  +         "SELECT type, name, rootpage, sql, ", zDbNum, " FROM \"",
          334  +         db->aDb[iDb].zName, "\".sqlite_master", (char*)0);
          335  +      rc = sqlite3_exec(db, zSql, sqlite3InitCallback, &initData, 0);
          336  +      sqliteFree(zSql);
          337  +    }
          338  +    sqlite3SafetyOn(db);
          339  +    sqlite3BtreeCloseCursor(curMain);
   361    340     }
   362         -  sqlite3SafetyOn(db);
   363         -  sqlite3BtreeCloseCursor(curMain);
   364    341     if( sqlite3_malloc_failed ){
   365    342       sqlite3SetString(pzErrMsg, "out of memory", (char*)0);
   366    343       rc = SQLITE_NOMEM;
   367    344       sqlite3ResetInternalSchema(db, 0);
   368    345     }
   369    346     if( rc==SQLITE_OK ){
   370    347       DbSetProperty(db, iDb, DB_SchemaLoaded);

Changes to src/sqliteInt.h.

     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     12   ** Internal interface definitions for SQLite.
    13     13   **
    14         -** @(#) $Id: sqliteInt.h,v 1.228 2004/05/10 10:34:52 danielk1977 Exp $
           14  +** @(#) $Id: sqliteInt.h,v 1.229 2004/05/10 23:29:50 drh Exp $
    15     15   */
    16     16   #include "config.h"
    17     17   #include "sqlite.h"
    18     18   #include "hash.h"
    19     19   #include "parse.h"
    20     20   #include <stdio.h>
    21     21   #include <stdlib.h>
................................................................................
   116    116   #ifndef INTPTR_TYPE
   117    117   # if SQLITE_PTR_SZ==4
   118    118   #   define INTPTR_TYPE int
   119    119   # else
   120    120   #   define INTPTR_TYPE long long
   121    121   # endif
   122    122   #endif
          123  +typedef INT64_TYPE i64;            /* 8-byte signed integer */
   123    124   typedef UINT64_TYPE u64;           /* 8-byte unsigned integer */
   124    125   typedef UINT32_TYPE u32;           /* 4-byte unsigned integer */
   125    126   typedef UINT16_TYPE u16;           /* 2-byte unsigned integer */
   126    127   typedef UINT8_TYPE u8;             /* 1-byte unsigned integer */
   127    128   typedef UINT8_TYPE i8;             /* 1-byte signed integer */
   128    129   typedef INTPTR_TYPE ptr;           /* Big enough to hold a pointer */
   129    130   typedef unsigned INTPTR_TYPE uptr; /* Big enough to hold a pointer */
................................................................................
   363    364     int cache_size;               /* Number of pages to use in the cache */
   364    365     int nTable;                   /* Number of tables in the database */
   365    366     void *pBusyArg;               /* 1st Argument to the busy callback */
   366    367     int (*xBusyCallback)(void *,const char*,int);  /* The busy callback */
   367    368     void *pCommitArg;             /* Argument to xCommitCallback() */   
   368    369     int (*xCommitCallback)(void*);/* Invoked at every commit. */
   369    370     Hash aFunc;                   /* All functions that can be in SQL exprs */
   370         -  int lastRowid;                /* ROWID of most recent insert (see above) */
   371         -  int priorNewRowid;            /* Last randomly generated ROWID */
          371  +  i64 lastRowid;                /* ROWID of most recent insert (see above) */
          372  +  i64 priorNewRowid;            /* Last randomly generated ROWID */
   372    373     int magic;                    /* Magic number for detect library misuse */
   373    374     int nChange;                  /* Number of rows changed (see above) */
   374    375     int lsChange;                 /* Last statement change count (see above) */
   375    376     int csChange;                 /* Current statement change count (see above) */
   376    377     struct sqlite3InitInfo {       /* Information used during initialization */
   377    378       int iDb;                       /* When back is being initialized */
   378    379       int newTnum;                   /* Rootpage of table being initialized */
................................................................................
  1283   1284   void *sqlite3utf8to16be(const unsigned char *pIn, int N);
  1284   1285   void *sqlite3utf8to16le(const unsigned char *pIn, int N);
  1285   1286   void sqlite3utf16to16le(void *pData, int N);
  1286   1287   void sqlite3utf16to16be(void *pData, int N);
  1287   1288   int sqlite3PutVarint(unsigned char *, u64);
  1288   1289   int sqlite3GetVarint(const unsigned char *, u64 *);
  1289   1290   int sqlite3VarintLen(u64 v);
  1290         -

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.273 2004/05/10 10:35:00 danielk1977 Exp $
           46  +** $Id: vdbe.c,v 1.274 2004/05/10 23:29:50 drh Exp $
    47     47   */
    48     48   #include "sqliteInt.h"
    49     49   #include "os.h"
    50     50   #include <ctype.h>
    51     51   #include "vdbeInt.h"
    52     52   
    53     53   /*
................................................................................
  2524   2524   ** temporary tables.
  2525   2525   **
  2526   2526   ** There must be a read-lock on the database (either a transaction
  2527   2527   ** must be started or there must be an open cursor) before
  2528   2528   ** executing this instruction.
  2529   2529   */
  2530   2530   case OP_ReadCookie: {
  2531         -  int aMeta[SQLITE_N_BTREE_META];
         2531  +  int iMeta;
  2532   2532     assert( pOp->p2<SQLITE_N_BTREE_META );
  2533   2533     assert( pOp->p1>=0 && pOp->p1<db->nDb );
  2534   2534     assert( db->aDb[pOp->p1].pBt!=0 );
  2535         -  {
  2536         -    int ii;
  2537         -    for(ii=0; rc==SQLITE_OK && ii<SQLITE_N_BTREE_META; ii++){
  2538         -      rc = sqlite3BtreeGetMeta(db->aDb[pOp->p1].pBt, ii+1, &aMeta[ii]);
  2539         -    }
  2540         -  }
         2535  +  rc = sqlite3BtreeGetMeta(db->aDb[pOp->p1].pBt, pOp->p2+1, &iMeta);
  2541   2536     pTos++;
  2542         -  pTos->i = aMeta[1+pOp->p2];
         2537  +  pTos->i = iMeta;
  2543   2538     pTos->flags = MEM_Int;
  2544   2539     break;
  2545   2540   }
  2546   2541   
  2547   2542   /* Opcode: SetCookie P1 P2 *
  2548   2543   **
  2549   2544   ** Write the top of the stack into cookie number P2 of database P1.
................................................................................
  2551   2546   ** P2==2 is the recommended pager cache size, and so forth.  P1==0 is
  2552   2547   ** the main database file and P1==1 is the database file used to store
  2553   2548   ** temporary tables.
  2554   2549   **
  2555   2550   ** A transaction must be started before executing this opcode.
  2556   2551   */
  2557   2552   case OP_SetCookie: {
  2558         -  int aMeta[SQLITE_N_BTREE_META];
  2559   2553     assert( pOp->p2<SQLITE_N_BTREE_META );
  2560   2554     assert( pOp->p1>=0 && pOp->p1<db->nDb );
  2561   2555     assert( db->aDb[pOp->p1].pBt!=0 );
  2562   2556     assert( pTos>=p->aStack );
  2563         -  Integerify(pTos)
  2564         -  {
  2565         -    int ii;
  2566         -    for(ii=0; rc==SQLITE_OK && ii<SQLITE_N_BTREE_META; ii++){
  2567         -      rc = sqlite3BtreeGetMeta(db->aDb[pOp->p1].pBt, ii+1, &aMeta[ii]);
  2568         -    }
  2569         -  }
  2570         -  if( rc==SQLITE_OK ){
  2571         -    aMeta[1+pOp->p2] = pTos->i;
  2572         -    {
  2573         -      int ii;
  2574         -      for(ii=0; rc==SQLITE_OK && ii<SQLITE_N_BTREE_META; ii++){
  2575         -        rc = sqlite3BtreeUpdateMeta(db->aDb[pOp->p1].pBt, ii+1, aMeta[ii]);
  2576         -      }
  2577         -    }
  2578         -  }
         2557  +  Integerify(pTos);
         2558  +  rc = sqlite3BtreeUpdateMeta(db->aDb[pOp->p1].pBt, 1+pOp->p2, (int)pTos->i);
  2579   2559     Release(pTos);
  2580   2560     pTos--;
  2581   2561     break;
  2582   2562   }
  2583   2563   
  2584   2564   /* Opcode: VerifyCookie P1 P2 *
  2585   2565   **
................................................................................
  2594   2574   ** and that the current process needs to reread the schema.
  2595   2575   **
  2596   2576   ** Either a transaction needs to have been started or an OP_Open needs
  2597   2577   ** to be executed (to establish a read lock) before this opcode is
  2598   2578   ** invoked.
  2599   2579   */
  2600   2580   case OP_VerifyCookie: {
  2601         -  int aMeta[SQLITE_N_BTREE_META];
         2581  +  int iMeta;
  2602   2582     assert( pOp->p1>=0 && pOp->p1<db->nDb );
  2603         -  {
  2604         -    int ii;
  2605         -    for(ii=0; rc==SQLITE_OK && ii<SQLITE_N_BTREE_META; ii++){
  2606         -      rc = sqlite3BtreeGetMeta(db->aDb[pOp->p1].pBt, ii+1, &aMeta[ii]);
  2607         -    }
  2608         -  }
  2609         -  if( rc==SQLITE_OK && aMeta[1]!=pOp->p2 ){
         2583  +  rc = sqlite3BtreeGetMeta(db->aDb[pOp->p1].pBt, 1, &iMeta);
         2584  +  if( rc==SQLITE_OK && iMeta!=pOp->p2 ){
  2610   2585       sqlite3SetString(&p->zErrMsg, "database schema has changed", (char*)0);
  2611   2586       rc = SQLITE_SCHEMA;
  2612   2587     }
  2613   2588     break;
  2614   2589   }
  2615   2590   
  2616   2591   /* Opcode: OpenRead P1 P2 P3
................................................................................
  2661   2636   case OP_OpenWrite: {
  2662   2637     int busy = 0;
  2663   2638     int i = pOp->p1;
  2664   2639     int p2 = pOp->p2;
  2665   2640     int wrFlag;
  2666   2641     Btree *pX;
  2667   2642     int iDb;
         2643  +  Cursor *pCur;
  2668   2644     
  2669   2645     assert( pTos>=p->aStack );
  2670   2646     Integerify(pTos);
  2671   2647     iDb = pTos->i;
  2672   2648     pTos--;
  2673   2649     assert( iDb>=0 && iDb<db->nDb );
  2674   2650     pX = db->aDb[iDb].pBt;
................................................................................
  2683   2659         sqlite3SetString(&p->zErrMsg, "root page number less than 2", (char*)0);
  2684   2660         rc = SQLITE_INTERNAL;
  2685   2661         break;
  2686   2662       }
  2687   2663     }
  2688   2664     assert( i>=0 );
  2689   2665     if( expandCursorArraySize(p, i) ) goto no_mem;
  2690         -  sqlite3VdbeCleanupCursor(&p->aCsr[i]);
  2691         -  memset(&p->aCsr[i], 0, sizeof(Cursor));
  2692         -  p->aCsr[i].nullRow = 1;
         2666  +  pCur = &p->aCsr[i];
         2667  +  sqlite3VdbeCleanupCursor(pCur);
         2668  +  memset(pCur, 0, sizeof(Cursor));
         2669  +  pCur->nullRow = 1;
  2693   2670     if( pX==0 ) break;
  2694   2671     do{
  2695         -    rc = sqlite3BtreeCursor(pX, p2, wrFlag, 0, 0, &p->aCsr[i].pCursor);
         2672  +    rc = sqlite3BtreeCursor(pX, p2, wrFlag, 0, 0, &pCur->pCursor);
  2696   2673       switch( rc ){
  2697   2674         case SQLITE_BUSY: {
  2698   2675           if( db->xBusyCallback==0 ){
  2699   2676             p->pc = pc;
  2700   2677             p->rc = SQLITE_BUSY;
  2701   2678             p->pTos = &pTos[1 + (pOp->p2<=0)]; /* Operands must remain on stack */
  2702   2679             return SQLITE_BUSY;
................................................................................
  2703   2680           }else if( (*db->xBusyCallback)(db->pBusyArg, pOp->p3, ++busy)==0 ){
  2704   2681             sqlite3SetString(&p->zErrMsg, sqlite3_error_string(rc), (char*)0);
  2705   2682             busy = 0;
  2706   2683           }
  2707   2684           break;
  2708   2685         }
  2709   2686         case SQLITE_OK: {
         2687  +        int flags = sqlite3BtreeFlags(pCur->pCursor);
         2688  +        pCur->intKey = (flags & BTREE_INTKEY)!=0;
         2689  +        pCur->zeroData = (flags & BTREE_ZERODATA)!=0;
  2710   2690           busy = 0;
  2711   2691           break;
  2712   2692         }
  2713   2693         default: {
  2714   2694           goto abort_due_to_error;
  2715   2695         }
  2716   2696       }
................................................................................
  2750   2730     if( rc==SQLITE_OK ){
  2751   2731       rc = sqlite3BtreeBeginTrans(pCx->pBt);
  2752   2732     }
  2753   2733     if( rc==SQLITE_OK ){
  2754   2734       /* If a transient index is required, create it by calling
  2755   2735       ** sqlite3BtreeCreateTable() with the BTREE_ZERODATA flag before
  2756   2736       ** opening it. If a transient table is required, just use the
  2757         -    ** automatically created table with root-page 2.
         2737  +    ** automatically created table with root-page 1.
  2758   2738       */
  2759   2739       if( pOp->p2 ){
  2760   2740         int pgno;
  2761   2741         rc = sqlite3BtreeCreateTable(pCx->pBt, &pgno, BTREE_ZERODATA); 
  2762   2742         if( rc==SQLITE_OK ){
         2743  +        assert( pgno==MASTER_ROOT+1 );
  2763   2744           rc = sqlite3BtreeCursor(pCx->pBt, pgno, 1, 0, 0, &pCx->pCursor);
  2764   2745         }
  2765   2746       }else{
  2766         -      rc = sqlite3BtreeCursor(pCx->pBt, 2, 1, 0, 0, &pCx->pCursor);
         2747  +      rc = sqlite3BtreeCursor(pCx->pBt, MASTER_ROOT, 1, 0, 0, &pCx->pCursor);
  2767   2748       }
  2768   2749     }
  2769   2750     break;
  2770   2751   }
  2771   2752   
  2772   2753   /* Opcode: OpenPseudo P1 * *
  2773   2754   **
................................................................................
  2833   2814   
  2834   2815     assert( pTos>=p->aStack );
  2835   2816     assert( i>=0 && i<p->nCursor );
  2836   2817     pC = &p->aCsr[i];
  2837   2818     if( pC->pCursor!=0 ){
  2838   2819       int res, oc;
  2839   2820       pC->nullRow = 0;
  2840         -    if( pTos->flags & MEM_Int ){
  2841         -      int iKey = intToKey(pTos->i);
         2821  +    if( pC->intKey ){
         2822  +      i64 iKey;
         2823  +      assert( pTos->flags & MEM_Int );
         2824  +      iKey = intToKey(pTos->i);
  2842   2825         if( pOp->p2==0 && pOp->opcode==OP_MoveTo ){
  2843   2826           pC->movetoTarget = iKey;
  2844   2827           pC->deferredMoveto = 1;
  2845   2828           Release(pTos);
  2846   2829           pTos--;
  2847   2830           break;
  2848   2831         }
  2849         -      sqlite3BtreeMoveto(pC->pCursor, (char*)&iKey, sizeof(int), &res);
         2832  +      sqlite3BtreeMoveto(pC->pCursor, 0, (u64)iKey, &res);
  2850   2833         pC->lastRecno = pTos->i;
  2851   2834         pC->recnoIsValid = res==0;
  2852   2835       }else{
  2853   2836         Stringify(pTos);
  2854   2837         sqlite3BtreeMoveto(pC->pCursor, pTos->z, pTos->n, &res);
  2855   2838         pC->recnoIsValid = 0;
  2856   2839       }
................................................................................
  2867   2850         if( res>=0 ){
  2868   2851           sqlite3BtreePrevious(pC->pCursor, &res);
  2869   2852           pC->recnoIsValid = 0;
  2870   2853         }else{
  2871   2854           /* res might be negative because the table is empty.  Check to
  2872   2855           ** see if this is the case.
  2873   2856           */
  2874         -        int keysize;
  2875         -        /* TODO: res = sqlite3BtreeKeySize(pC->pCursor,&keysize)!=0 || * keysize==0; */
         2857  +        res = sqlite3BtreeEof(pC->pCursor);
  2876   2858         }
  2877   2859         if( res && pOp->p2>0 ){
  2878   2860           pc = pOp->p2 - 1;
  2879   2861         }
  2880   2862       }
  2881   2863     }
  2882   2864     Release(pTos);
................................................................................
  2923   2905     int i = pOp->p1;
  2924   2906     int alreadyExists = 0;
  2925   2907     Cursor *pC;
  2926   2908     assert( pTos>=p->aStack );
  2927   2909     assert( i>=0 && i<p->nCursor );
  2928   2910     if( (pC = &p->aCsr[i])->pCursor!=0 ){
  2929   2911       int res, rx;
         2912  +    assert( pC->intKey==0 );
  2930   2913       Stringify(pTos);
  2931   2914       rx = sqlite3BtreeMoveto(pC->pCursor, pTos->z, pTos->n, &res);
  2932   2915       alreadyExists = rx==SQLITE_OK && res==0;
  2933   2916       pC->deferredMoveto = 0;
  2934   2917     }
  2935   2918     if( pOp->opcode==OP_Found ){
  2936   2919       if( alreadyExists ) pc = pOp->p2 - 1;
................................................................................
  2963   2946   ** falls through to the next instruction.
  2964   2947   **
  2965   2948   ** See also: Distinct, NotFound, NotExists, Found
  2966   2949   */
  2967   2950   case OP_IsUnique: {
  2968   2951     int i = pOp->p1;
  2969   2952     Mem *pNos = &pTos[-1];
         2953  +  Cursor *pCx;
  2970   2954     BtCursor *pCrsr;
  2971   2955     int R;
  2972   2956   
  2973   2957     /* Pop the value R off the top of the stack
  2974   2958     */
  2975   2959     assert( pNos>=p->aStack );
  2976   2960     Integerify(pTos);
  2977   2961     R = pTos->i;
  2978   2962     pTos--;
  2979   2963     assert( i>=0 && i<=p->nCursor );
  2980         -  if( (pCrsr = p->aCsr[i].pCursor)!=0 ){
         2964  +  pCx = &p->aCsr[i];
         2965  +  pCrsr = pCx->pCursor;
         2966  +  if( pCrsr!=0 ){
  2981   2967       int res, rc;
  2982   2968       int v;         /* The record number on the P1 entry that matches K */
  2983   2969       char *zKey;    /* The value of K */
  2984   2970       int nKey;      /* Number of bytes in K */
  2985   2971   
  2986   2972       /* Make sure K is a string and make zKey point to K
  2987   2973       */
................................................................................
  3076   3062   ** Get a new integer record number used as the key to a table.
  3077   3063   ** The record number is not previously used as a key in the database
  3078   3064   ** table that cursor P1 points to.  The new record number is pushed 
  3079   3065   ** onto the stack.
  3080   3066   */
  3081   3067   case OP_NewRecno: {
  3082   3068     int i = pOp->p1;
  3083         -  int v = 0;
         3069  +  i64 v = 0;
  3084   3070     Cursor *pC;
  3085   3071     assert( i>=0 && i<p->nCursor );
  3086   3072     if( (pC = &p->aCsr[i])->pCursor==0 ){
  3087         -    v = 0;
         3073  +    /* The zero initialization above is all that is needed */
  3088   3074     }else{
  3089   3075       /* The next rowid or record number (different terms for the same
  3090   3076       ** thing) is obtained in a two-step algorithm.
  3091   3077       **
  3092   3078       ** First we attempt to find the largest existing rowid and add one
  3093   3079       ** to that.  But if the largest existing rowid is already the maximum
  3094   3080       ** positive integer, we have to fall through to the second
................................................................................
  3113   3099       ** random number generator based on the RC4 algorithm.
  3114   3100       **
  3115   3101       ** To promote locality of reference for repetitive inserts, the
  3116   3102       ** first few attempts at chosing a random rowid pick values just a little
  3117   3103       ** larger than the previous rowid.  This has been shown experimentally
  3118   3104       ** to double the speed of the COPY operation.
  3119   3105       */
  3120         -    int res, rx, cnt, x;
         3106  +    int res, rx, cnt;
         3107  +    i64 x;
  3121   3108       cnt = 0;
         3109  +    assert( (sqlite3BtreeFlags(pC->pCursor) & BTREE_INTKEY)!=0 );
         3110  +    assert( (sqlite3BtreeFlags(pC->pCursor) & BTREE_ZERODATA)==0 );
  3122   3111       if( !pC->useRandomRowid ){
  3123   3112         if( pC->nextRowidValid ){
  3124   3113           v = pC->nextRowid;
  3125   3114         }else{
  3126   3115           rx = sqlite3BtreeLast(pC->pCursor, &res);
  3127   3116           if( res ){
  3128   3117             v = 1;
  3129   3118           }else{
  3130         -          sqlite3BtreeKey(pC->pCursor, 0, sizeof(v), (void*)&v);
         3119  +          sqlite3BtreeKeySize(pC->pCursor, (u64*)&v);
  3131   3120             v = keyToInt(v);
  3132         -          if( v==0x7fffffff ){
         3121  +          if( v==0x7fffffffffffffff ){
  3133   3122               pC->useRandomRowid = 1;
  3134   3123             }else{
  3135   3124               v++;
  3136   3125             }
  3137   3126           }
  3138   3127         }
  3139         -      if( v<0x7fffffff ){
         3128  +      if( v<0x7fffffffffffffff ){
  3140   3129           pC->nextRowidValid = 1;
  3141   3130           pC->nextRowid = v+1;
  3142   3131         }else{
  3143   3132           pC->nextRowidValid = 0;
  3144   3133         }
  3145   3134       }
  3146   3135       if( pC->useRandomRowid ){
................................................................................
  3153   3142           }else{
  3154   3143             unsigned char r;
  3155   3144             sqlite3Randomness(1, &r);
  3156   3145             v += r + 1;
  3157   3146           }
  3158   3147           if( v==0 ) continue;
  3159   3148           x = intToKey(v);
  3160         -        rx = sqlite3BtreeMoveto(pC->pCursor, &x, sizeof(int), &res);
         3149  +        rx = sqlite3BtreeMoveto(pC->pCursor, 0, (u64)x, &res);
  3161   3150           cnt++;
  3162   3151         }while( cnt<1000 && rx==SQLITE_OK && res==0 );
  3163   3152         db->priorNewRowid = v;
  3164   3153         if( rx==SQLITE_OK && res==0 ){
  3165   3154           rc = SQLITE_FULL;
  3166   3155           goto abort_due_to_error;
  3167   3156         }
................................................................................
  3513   3502   ** the key to the current entry in a sequential scan of the database
  3514   3503   ** file P1.  The sequential scan should have been started using the 
  3515   3504   ** Next opcode.
  3516   3505   */
  3517   3506   case OP_Recno: {
  3518   3507     int i = pOp->p1;
  3519   3508     Cursor *pC;
  3520         -  int v;
         3509  +  i64 v;
  3521   3510   
  3522   3511     assert( i>=0 && i<p->nCursor );
  3523   3512     pC = &p->aCsr[i];
  3524   3513     sqlite3VdbeCursorMoveto(pC);
  3525   3514     pTos++;
  3526   3515     if( pC->recnoIsValid ){
  3527   3516       v = pC->lastRecno;
................................................................................
  3528   3517     }else if( pC->pseudoTable ){
  3529   3518       v = keyToInt(pC->iKey);
  3530   3519     }else if( pC->nullRow || pC->pCursor==0 ){
  3531   3520       pTos->flags = MEM_Null;
  3532   3521       break;
  3533   3522     }else{
  3534   3523       assert( pC->pCursor!=0 );
  3535         -    sqlite3BtreeKey(pC->pCursor, 0, sizeof(u32), (char*)&v);
         3524  +    sqlite3BtreeKeySize(pC->pCursor, (u64*)&v);
  3536   3525       v = keyToInt(v);
  3537   3526     }
  3538   3527     pTos->i = v;
  3539   3528     pTos->flags = MEM_Int;
  3540   3529     break;
  3541   3530   }
  3542   3531   
................................................................................
  3961   3950   ** root page of the new index onto the stack.
  3962   3951   **
  3963   3952   ** See documentation on OP_CreateTable for additional information.
  3964   3953   */
  3965   3954   case OP_CreateIndex:
  3966   3955   case OP_CreateTable: {
  3967   3956     int pgno;
         3957  +  int flags;
  3968   3958     assert( pOp->p3!=0 && pOp->p3type==P3_POINTER );
  3969   3959     assert( pOp->p2>=0 && pOp->p2<db->nDb );
  3970   3960     assert( db->aDb[pOp->p2].pBt!=0 );
  3971   3961     if( pOp->opcode==OP_CreateTable ){
  3972         -    rc = sqlite3BtreeCreateTable(db->aDb[pOp->p2].pBt, &pgno, BTREE_INTKEY);
         3962  +    flags = BTREE_INTKEY;
  3973   3963     }else{
  3974         -    rc = sqlite3BtreeCreateTable(db->aDb[pOp->p2].pBt, &pgno, BTREE_ZERODATA);
         3964  +    flags = BTREE_ZERODATA;
  3975   3965     }
         3966  +  rc = sqlite3BtreeCreateTable(db->aDb[pOp->p2].pBt, &pgno, flags);
  3976   3967     pTos++;
  3977   3968     if( rc==SQLITE_OK ){
  3978   3969       pTos->i = pgno;
  3979   3970       pTos->flags = MEM_Int;
  3980   3971       *(u32*)pOp->p3 = pgno;
  3981   3972       pOp->p3 = 0;
  3982   3973     }else{

Changes to src/vdbeInt.h.

    13     13   ** VDBE.  This information used to all be at the top of the single
    14     14   ** source code file "vdbe.c".  When that file became too big (over
    15     15   ** 6000 lines long) it was split up into several smaller files and
    16     16   ** this header information was factored out.
    17     17   */
    18     18   
    19     19   /*
    20         -** When converting from the native format to the key format and back
    21         -** again, in addition to changing the byte order we invert the high-order
    22         -** bit of the most significant byte.  This causes negative numbers to
    23         -** sort before positive numbers in the memcmp() function.
           20  +** In the btree layer, a rowid is an unsigned 64-bit integer.  In the
           21  +** schema layer, a rowid is a signed 64-bit integer.  The following macros
           22  +** convert between the two in such a way as to preserve sort order.
    24     23   */
    25         -#define keyToInt(X)   (sqlite3VdbeByteSwap(X) ^ 0x80000000)
    26         -#define intToKey(X)   (sqlite3VdbeByteSwap((X) ^ 0x80000000))
           24  +#define keyToInt(X)   (X ^ 0x8000000000000000)
           25  +#define intToKey(X)   (X ^ 0x8000000000000000)
    27     26   
    28     27   /*
    29     28   ** The makefile scans this source file and creates the following
    30     29   ** array of string constants which are the names of all VDBE opcodes.
    31     30   ** This array is defined in a separate source code file named opcode.c
    32     31   ** which is automatically generated by the makefile.
    33     32   */
................................................................................
    58     57   ** If the Cursor.isTriggerRow flag is set it means that this cursor is
    59     58   ** really a single row that represents the NEW or OLD pseudo-table of
    60     59   ** a row trigger.  The data for the row is stored in Cursor.pData and
    61     60   ** the rowid is in Cursor.iKey.
    62     61   */
    63     62   struct Cursor {
    64     63     BtCursor *pCursor;    /* The cursor structure of the backend */
    65         -  int lastRecno;        /* Last recno from a Next or NextIdx operation */
    66         -  int nextRowid;        /* Next rowid returned by OP_NewRowid */
           64  +  i64 lastRecno;        /* Last recno from a Next or NextIdx operation */
           65  +  i64 nextRowid;        /* Next rowid returned by OP_NewRowid */
    67     66     Bool recnoIsValid;    /* True if lastRecno is valid */
    68     67     Bool keyAsData;       /* The OP_Column command works on key instead of data */
    69     68     Bool atFirst;         /* True if pointing to first entry */
    70     69     Bool useRandomRowid;  /* Generate new record numbers semi-randomly */
    71     70     Bool nullRow;         /* True if pointing to a row with no data */
    72     71     Bool nextRowidValid;  /* True if the nextRowid field is valid */
    73     72     Bool pseudoTable;     /* This is a NEW or OLD pseudo-tables of a trigger */
    74     73     Bool deferredMoveto;  /* A call to sqlite3BtreeMoveto() is needed */
    75         -  int movetoTarget;     /* Argument to the deferred sqlite3BtreeMoveto() */
           74  +  Bool intKey;          /* True if the table requires integer keys */
           75  +  Bool zeroData;        /* True if table contains keys only - no data */
           76  +  i64 movetoTarget;     /* Argument to the deferred sqlite3BtreeMoveto() */
    76     77     Btree *pBt;           /* Separate file holding temporary table */
    77     78     int nData;            /* Number of bytes in pData */
    78     79     char *pData;          /* Data for a NEW or OLD pseudo-table */
    79         -  int iKey;             /* Key for the NEW or OLD pseudo-table row */
           80  +  i64 iKey;             /* Key for the NEW or OLD pseudo-table row */
    80     81   };
    81     82   typedef struct Cursor Cursor;
    82     83   
    83     84   /*
    84     85   ** A sorter builds a list of elements to be sorted.  Each element of
    85     86   ** the list is an instance of the following structure.
    86     87   */
................................................................................
   106    107   #define NBFS 32
   107    108   
   108    109   /*
   109    110   ** A single level of the stack or a single memory cell
   110    111   ** is an instance of the following structure. 
   111    112   */
   112    113   struct Mem {
   113         -  int i;              /* Integer value */
          114  +  i64 i;              /* Integer value */
   114    115     int n;              /* Number of characters in string value, including '\0' */
   115    116     int flags;          /* Some combination of MEM_Null, MEM_Str, MEM_Dyn, etc. */
   116    117     double r;           /* Real value */
   117    118     char *z;            /* String or BLOB value */
   118    119     char zShort[NBFS];  /* Space for short strings */
   119    120   };
   120    121   typedef struct Mem Mem;

Changes to test/attach.test.

     8      8   #    May you share freely, never taking more than you give.
     9      9   #
    10     10   #***********************************************************************
    11     11   # This file implements regression tests for SQLite library.  The
    12     12   # focus of this script is testing the ATTACH and DETACH commands
    13     13   # and related functionality.
    14     14   #
    15         -# $Id: attach.test,v 1.13 2004/02/14 01:39:50 drh Exp $
           15  +# $Id: attach.test,v 1.14 2004/05/10 23:29:51 drh Exp $
    16     16   #
    17     17   
    18     18   set testdir [file dirname $argv0]
    19     19   source $testdir/tester.tcl
    20     20   
    21     21   for {set i 2} {$i<=15} {incr i} {
    22     22     file delete -force test$i.db
    23     23     file delete -force test$i.db-journal
    24     24   }
    25     25   
           26  +set btree_trace 1
    26     27   do_test attach-1.1 {
    27     28     execsql {
    28     29       CREATE TABLE t1(a,b);
    29     30       INSERT INTO t1 VALUES(1,2);
    30     31       INSERT INTO t1 VALUES(3,4);
    31     32       SELECT * FROM t1;
    32     33     }

Changes to test/tester.tcl.

     7      7   #    May you find forgiveness for yourself and forgive others.
     8      8   #    May you share freely, never taking more than you give.
     9      9   #
    10     10   #***********************************************************************
    11     11   # This file implements some common TCL routines used for regression
    12     12   # testing the SQLite library
    13     13   #
    14         -# $Id: tester.tcl,v 1.30 2004/05/07 17:57:50 drh Exp $
           14  +# $Id: tester.tcl,v 1.31 2004/05/10 23:29:51 drh Exp $
    15     15   
    16         -if 0 {
    17     16   # Make sure tclsqlite was compiled correctly.  Abort now with an
    18     17   # error message if not.
    19     18   #
    20     19   if {[sqlite -tcl-uses-utf]} {
    21     20     if {"\u1234"=="u1234"} {
    22     21       puts stderr "***** BUILD PROBLEM *****"
    23     22       puts stderr "$argv0 was linked against an older version"
................................................................................
    59     58   catch {db close}
    60     59   file delete -force test.db
    61     60   file delete -force test.db-journal
    62     61   sqlite db ./test.db
    63     62   if {[info exists ::SETUP_SQL]} {
    64     63     db eval $::SETUP_SQL
    65     64   }
    66         -}
    67         -proc db {args} {}
    68     65   
    69     66   # Abort early if this script has been run before.
    70     67   #
    71     68   if {[info exists nTest]} return
    72     69   
    73     70   # Set the test counters to zero
    74     71   #
................................................................................
   108    105       if {$nErr>100} {puts "*** Giving up..."; finalize_testing}
   109    106     } elseif {[string compare $result $expected]} {
   110    107       puts "\nExpected: \[$expected\]\n     Got: \[$result\]"
   111    108       incr nErr
   112    109       lappend ::failList $name
   113    110       if {$nErr>=1} {puts "*** Giving up..."; finalize_testing}
   114    111     } else {
   115         -    puts " Ok"
   116         -  }
   117         -}
   118         -
   119         -# Invoke this procedure on a test that is probabilistic
   120         -# and might fail sometimes.
   121         -#
   122         -proc do_probtest {name cmd expected} {
   123         -  global argv nProb nTest skip_test
   124         -  if {$skip_test} {
   125         -    set skip_test 0
   126         -    return
   127         -  }
   128         -  if {[llength $argv]==0} { 
   129         -    set go 1
   130         -  } else {
   131         -    set go 0
   132         -    foreach pattern $argv {
   133         -      if {[string match $pattern $name]} {
   134         -        set go 1
   135         -        break
   136         -      }
   137         -    }
   138         -  }
   139         -  if {!$go} return
   140         -  incr nTest
   141         -  puts -nonewline $name...
   142         -  flush stdout
   143         -  if {[catch {uplevel #0 "$cmd;\n"} result]} {
   144         -    puts "\nError: $result"
   145         -    incr nErr
   146         -  } elseif {[string compare $result $expected]} {
   147         -    puts "\nExpected: \[$expected\]\n     Got: \[$result\]"
   148         -    puts "NOTE: The results of the previous test depend on system load"
   149         -    puts "and processor speed.  The test may sometimes fail even if the"
   150         -    puts "library is working correctly."
   151         -    incr nProb	
   152         -  } else {
   153    112       puts " Ok"
   154    113     }
   155    114   }
   156    115   
   157    116   # The procedure uses the special "sqlite_malloc_stat" command
   158    117   # (which is only available if SQLite is compiled with -DMEMORY_DEBUG=1)
   159    118   # to see how many malloc()s have not been free()ed.  The number