/ Check-in [6d378cb7]
Login

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

Overview
Comment:Fix an offset problem in the meta values that was causing problems for many tests. (CVS 1357)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 6d378cb7e7e081bb3bcd3a347bc1e02f50ee25cc
User & Date: drh 2004-05-11 09:31:32
Context
2004-05-11
09:50
Fix a bug that was preventing the library from opening existing files. (CVS 1358) check-in: ad064bd4 user: danielk1977 tags: trunk
09:31
Fix an offset problem in the meta values that was causing problems for many tests. (CVS 1357) check-in: 6d378cb7 user: drh tags: trunk
09:05
Remove the unused upgrade_3_schema subroutine from main.c. (CVS 1356) check-in: b5d2771e 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.126 2004/05/11 02:10:07 danielk1977 Exp $
           12  +** $Id: btree.c,v 1.127 2004/05/11 09:31:32 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.
................................................................................
  3432   3432     return rc;  
  3433   3433   }
  3434   3434   
  3435   3435   
  3436   3436   /*
  3437   3437   ** Read the meta-information out of a database file.  Meta[0]
  3438   3438   ** is the number of free pages currently in the database.  Meta[1]
  3439         -** through meta[15] are available for use by higher layers.
         3439  +** through meta[15] are available for use by higher layers.  Meta[0]
         3440  +** is read-only, the others are read/write.
         3441  +** 
         3442  +** The schema layer numbers meta values differently.  At the schema
         3443  +** layer (and the SetCookie and ReadCookie opcodes) the number of
         3444  +** free pages is not visible.  So Cookie[0] is the same as Meta[1].
  3440   3445   */
  3441   3446   int sqlite3BtreeGetMeta(Btree *pBt, int idx, u32 *pMeta){
  3442   3447     int rc;
  3443   3448     unsigned char *pP1;
  3444   3449   
  3445   3450     assert( idx>=0 && idx<=15 );
  3446   3451     rc = sqlite3pager_get(pBt->pPager, 1, (void**)&pP1);

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.172 2004/05/11 09:05:49 drh Exp $
           17  +** $Id: main.c,v 1.173 2004/05/11 09:31:32 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
................................................................................
   134    134   static int sqlite3InitOne(sqlite *db, int iDb, char **pzErrMsg){
   135    135     int rc;
   136    136     BtCursor *curMain;
   137    137     int size;
   138    138     Table *pTab;
   139    139     char *azArg[6];
   140    140     char zDbNum[30];
   141         -  int meta[SQLITE_N_BTREE_META];
          141  +  int meta[10];
   142    142     InitData initData;
   143    143   
   144    144     /*
   145    145     ** The master database table has a structure like this
   146    146     */
   147    147     static char master_schema[] = 
   148    148        "CREATE TABLE sqlite_master(\n"
................................................................................
   206    206     if( db->aDb[iDb].pBt==0 ) return SQLITE_OK;
   207    207     rc = sqlite3BtreeCursor(db->aDb[iDb].pBt, MASTER_ROOT, 0, 0, 0, &curMain);
   208    208     if( rc!=SQLITE_OK && rc!=SQLITE_EMPTY ){
   209    209       sqlite3SetString(pzErrMsg, sqlite3_error_string(rc), (char*)0);
   210    210       return rc;
   211    211     }
   212    212   
   213         -  /* Get the database meta information
          213  +  /* Get the database meta information.
          214  +  **
          215  +  ** Meta values are as follows:
          216  +  **    meta[0]   Schema cookie.  Changes with each schema change.
          217  +  **    meta[1]   File format of schema layer.
          218  +  **    meta[2]   Size of the page cache.
          219  +  **    meta[3]   Synchronous setting.  1:off, 2:normal, 3:full
          220  +  **    meta[4]
          221  +  **    meta[5]   Pragma temp_store value.  See comments on BtreeFactory
          222  +  **    meta[6]
          223  +  **    meta[7]
          224  +  **    meta[8]
          225  +  **    meta[9]
   214    226     */
   215    227     if( rc==SQLITE_OK ){
   216    228       int i;
   217         -    for(i=0; rc==SQLITE_OK && i<SQLITE_N_BTREE_META; i++){
   218         -      rc = sqlite3BtreeGetMeta(db->aDb[iDb].pBt, i, &meta[i]);
          229  +    for(i=0; rc==SQLITE_OK && i<sizeof(meta)/sizeof(meta[0]); i++){
          230  +      rc = sqlite3BtreeGetMeta(db->aDb[iDb].pBt, i+1, &meta[i]);
   219    231       }
   220    232       if( rc ){
   221    233         sqlite3SetString(pzErrMsg, sqlite3_error_string(rc), (char*)0);
   222    234         sqlite3BtreeCloseCursor(curMain);
   223    235         return rc;
   224    236       }
   225    237     }else{
   226    238       memset(meta, 0, sizeof(meta));
   227    239     }
   228         -  db->aDb[iDb].schema_cookie = meta[1];
          240  +  db->aDb[iDb].schema_cookie = meta[0];
   229    241     if( iDb==0 ){
   230         -    db->next_cookie = meta[1];
   231         -    db->file_format = meta[2];
   232         -    size = meta[3];
          242  +    db->next_cookie = meta[0];
          243  +    db->file_format = meta[1];
          244  +    size = meta[2];
   233    245       if( size==0 ){ size = MAX_PAGES; }
   234    246       db->cache_size = size;
   235         -    db->safety_level = meta[4];
   236         -    if( meta[6]>0 && meta[6]<=2 && db->temp_store==0 ){
   237         -      db->temp_store = meta[6];
          247  +    db->safety_level = meta[3];
          248  +    if( meta[5]>0 && meta[5]<=2 && db->temp_store==0 ){
          249  +      db->temp_store = meta[5];
   238    250       }
   239    251       if( db->safety_level==0 ) db->safety_level = 2;
   240    252   
   241    253       /*
   242    254       **  file_format==1    Version 3.0.0.
   243    255       */
   244    256       if( db->file_format==0 ){
................................................................................
   245    257         /* This happens if the database was initially empty */
   246    258         db->file_format = 1;
   247    259       }else if( db->file_format>1 ){
   248    260         sqlite3BtreeCloseCursor(curMain);
   249    261         sqlite3SetString(pzErrMsg, "unsupported file format", (char*)0);
   250    262         return SQLITE_ERROR;
   251    263       }
   252         -  }else if( db->file_format!=meta[2] ){
   253         -    if( meta[2]==0 ){
          264  +  }else if( db->file_format!=meta[1] ){
          265  +    if( meta[1]==0 ){
   254    266         sqlite3SetString(pzErrMsg, "cannot attach empty database: ",
   255    267            db->aDb[iDb].zName, (char*)0);
   256    268       }else{
   257    269         sqlite3SetString(pzErrMsg, "incompatible file format in auxiliary "
   258    270            "database: ", db->aDb[iDb].zName, (char*)0);
   259    271       }
   260    272       sqlite3BtreeClose(db->aDb[iDb].pBt);
   261    273       db->aDb[iDb].pBt = 0;
   262    274       return SQLITE_FORMAT;
   263    275     }
   264    276     sqlite3BtreeSetCacheSize(db->aDb[iDb].pBt, db->cache_size);
   265         -  sqlite3BtreeSetSafetyLevel(db->aDb[iDb].pBt, meta[4]==0 ? 2 : meta[4]);
          277  +  sqlite3BtreeSetSafetyLevel(db->aDb[iDb].pBt, meta[3]==0 ? 2 : meta[3]);
   266    278   
   267    279     /* Read the schema information out of the schema tables
   268    280     */
   269    281     assert( db->init.busy );
   270    282     sqlite3SafetyOff(db);
   271    283     if( rc==SQLITE_EMPTY ){
   272    284       /* For an empty database, there is nothing to read */

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.280 2004/05/11 08:48:11 danielk1977 Exp $
           46  +** $Id: vdbe.c,v 1.281 2004/05/11 09:31:32 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   /*
................................................................................
  2528   2528   ** executing this instruction.
  2529   2529   */
  2530   2530   case OP_ReadCookie: {
  2531   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         -  rc = sqlite3BtreeGetMeta(db->aDb[pOp->p1].pBt, pOp->p2+1, &iMeta);
         2535  +  /* The indexing of meta values at the schema layer is off by one from
         2536  +  ** the indexing in the btree layer.  The btree considers meta[0] to
         2537  +  ** be the number of free pages in the database (a read-only value)
         2538  +  ** and meta[1] to be the schema cookie.  The schema layer considers
         2539  +  ** meta[1] to be the schema cookie.  So we have to shift the index
         2540  +  ** by one in the following statement.
         2541  +  */
         2542  +  rc = sqlite3BtreeGetMeta(db->aDb[pOp->p1].pBt, 1 + pOp->p2, &iMeta);
  2536   2543     pTos++;
  2537   2544     pTos->i = iMeta;
  2538   2545     pTos->flags = MEM_Int;
  2539   2546     break;
  2540   2547   }
  2541   2548   
  2542   2549   /* Opcode: SetCookie P1 P2 *
................................................................................
  2551   2558   */
  2552   2559   case OP_SetCookie: {
  2553   2560     assert( pOp->p2<SQLITE_N_BTREE_META );
  2554   2561     assert( pOp->p1>=0 && pOp->p1<db->nDb );
  2555   2562     assert( db->aDb[pOp->p1].pBt!=0 );
  2556   2563     assert( pTos>=p->aStack );
  2557   2564     Integerify(pTos);
         2565  +  /* See note about index shifting on OP_ReadCookie */
  2558   2566     rc = sqlite3BtreeUpdateMeta(db->aDb[pOp->p1].pBt, 1+pOp->p2, (int)pTos->i);
  2559   2567     Release(pTos);
  2560   2568     pTos--;
  2561   2569     break;
  2562   2570   }
  2563   2571   
  2564   2572   /* Opcode: VerifyCookie P1 P2 *
................................................................................
  2931   2939   /* Opcode: IsUnique P1 P2 *
  2932   2940   **
  2933   2941   ** The top of the stack is an integer record number.  Call this
  2934   2942   ** record number R.  The next on the stack is an index key created
  2935   2943   ** using MakeIdxKey.  Call it K.  This instruction pops R from the
  2936   2944   ** stack but it leaves K unchanged.
  2937   2945   **
  2938         -** P1 is an index.  So all but the last eight bytes of K are an
  2939         -** index string.  The last eight bytes of K are a record number.
         2946  +** P1 is an index.  So all but the last four bytes of K are an
         2947  +** index string.  The last four bytes of K are a record number.
  2940   2948   **
  2941   2949   ** This instruction asks if there is an entry in P1 where the
  2942   2950   ** index string matches K but the record number is different
  2943   2951   ** from R.  If there is no such entry, then there is an immediate
  2944   2952   ** jump to P2.  If any entry does exist where the index string
  2945   2953   ** matches K but the record number is not R, then the record
  2946   2954   ** number for that entry is pushed onto the stack and control
................................................................................
  2949   2957   ** See also: Distinct, NotFound, NotExists, Found
  2950   2958   */
  2951   2959   case OP_IsUnique: {
  2952   2960     int i = pOp->p1;
  2953   2961     Mem *pNos = &pTos[-1];
  2954   2962     Cursor *pCx;
  2955   2963     BtCursor *pCrsr;
  2956         -  i64 R;
         2964  +  int R;
  2957   2965   
  2958   2966     /* Pop the value R off the top of the stack
  2959   2967     */
  2960   2968     assert( pNos>=p->aStack );
  2961   2969     Integerify(pTos);
  2962   2970     R = pTos->i;
  2963   2971     pTos--;
  2964   2972     assert( i>=0 && i<=p->nCursor );
  2965   2973     pCx = &p->aCsr[i];
  2966   2974     pCrsr = pCx->pCursor;
  2967   2975     if( pCrsr!=0 ){
  2968   2976       int res, rc;
  2969         -    i64 v;         /* The record number on the P1 entry that matches K */
         2977  +    int v;         /* The record number on the P1 entry that matches K */
  2970   2978       char *zKey;    /* The value of K */
  2971   2979       int nKey;      /* Number of bytes in K */
  2972   2980   
  2973   2981       /* Make sure K is a string and make zKey point to K
  2974   2982       */
  2975   2983       Stringify(pNos);
  2976   2984       zKey = pNos->z;
  2977   2985       nKey = pNos->n;
  2978         -    assert( nKey >= 8 );
         2986  +    assert( nKey >= 4 );
  2979   2987   
  2980         -    /* Search for an entry in P1 where all but the last eight bytes match K.
         2988  +    /* Search for an entry in P1 where all but the last four bytes match K.
  2981   2989       ** If there is no such entry, jump immediately to P2.
  2982   2990       */
  2983   2991       assert( p->aCsr[i].deferredMoveto==0 );
  2984         -    assert( p->aCsr[i].intKey==0 );
  2985         -    rc = sqlite3BtreeMoveto(pCrsr, zKey, nKey-8, &res);
         2992  +    rc = sqlite3BtreeMoveto(pCrsr, zKey, nKey-4, &res);
  2986   2993       if( rc!=SQLITE_OK ) goto abort_due_to_error;
  2987   2994       if( res<0 ){
  2988   2995         rc = sqlite3BtreeNext(pCrsr, &res);
  2989   2996         if( res ){
  2990   2997           pc = pOp->p2 - 1;
  2991   2998           break;
  2992   2999         }
  2993   3000       }
  2994   3001       /* FIX ME - the sqlite2BtreeKeyCompare() function is a temporary hack */
  2995         -    rc = sqlite2BtreeKeyCompare(pCrsr, zKey, nKey-8, 8, &res); 
         3002  +    rc = sqlite2BtreeKeyCompare(pCrsr, zKey, nKey-4, 4, &res); 
  2996   3003       if( rc!=SQLITE_OK ) goto abort_due_to_error;
  2997   3004       if( res>0 ){
  2998   3005         pc = pOp->p2 - 1;
  2999   3006         break;
  3000   3007       }
  3001   3008   
  3002   3009       /* At this point, pCrsr is pointing to an entry in P1 where all but
  3003         -    ** the last eight bytes of the key match K.  Check to see if the last
  3004         -    ** eight bytes of the key are different from R.  If the last four
         3010  +    ** the last for bytes of the key match K.  Check to see if the last
         3011  +    ** four bytes of the key are different from R.  If the last four
  3005   3012       ** bytes equal R then jump immediately to P2.
  3006   3013       */
  3007         -    sqlite3BtreeKey(pCrsr, nKey - sizeof(i64), sizeof(i64), (char*)&v);
         3014  +    sqlite3BtreeKey(pCrsr, nKey - 4, 4, (char*)&v);
  3008   3015       v = keyToInt(v);
  3009   3016       if( v==R ){
  3010   3017         pc = pOp->p2 - 1;
  3011   3018         break;
  3012   3019       }
  3013   3020   
  3014   3021       /* The last four bytes of the key are different from R.  Convert the
................................................................................
  3429   3436     }else if( (pC = &p->aCsr[i])->pCursor!=0 ){
  3430   3437       sqlite3VdbeCursorMoveto(pC);
  3431   3438       zRec = 0;
  3432   3439       pCrsr = pC->pCursor;
  3433   3440       if( pC->nullRow ){
  3434   3441         payloadSize = 0;
  3435   3442       }else if( pC->keyAsData ){
  3436         -      assert( !pC->intKey );
  3437   3443         u64 pl64;
         3444  +      assert( !pC->intKey );
  3438   3445         sqlite3BtreeKeySize(pCrsr, &pl64);
  3439   3446         payloadSize = pl64;
  3440   3447       }else{
  3441   3448         sqlite3BtreeDataSize(pCrsr, &payloadSize);
  3442   3449       }
  3443   3450     }else if( pC->pseudoTable ){
  3444   3451       payloadSize = pC->nData;
................................................................................
  5087   5094       if( p->trace && pTos>=p->aStack ){
  5088   5095         int i;
  5089   5096         fprintf(p->trace, "Stack:");
  5090   5097         for(i=0; i>-5 && &pTos[i]>=p->aStack; i--){
  5091   5098           if( pTos[i].flags & MEM_Null ){
  5092   5099             fprintf(p->trace, " NULL");
  5093   5100           }else if( (pTos[i].flags & (MEM_Int|MEM_Str))==(MEM_Int|MEM_Str) ){
  5094         -          fprintf(p->trace, " si:%d", pTos[i].i);
         5101  +          fprintf(p->trace, " si:%lld", pTos[i].i);
  5095   5102           }else if( pTos[i].flags & MEM_Int ){
  5096         -          fprintf(p->trace, " i:%d", pTos[i].i);
         5103  +          fprintf(p->trace, " i:%lld", pTos[i].i);
  5097   5104           }else if( pTos[i].flags & MEM_Real ){
  5098   5105             fprintf(p->trace, " r:%g", pTos[i].r);
  5099   5106           }else if( pTos[i].flags & MEM_Str ){
  5100   5107             int j, k;
  5101   5108             char zBuf[100];
  5102   5109             zBuf[0] = ' ';
  5103   5110             if( pTos[i].flags & MEM_Dyn ){

Changes to src/vdbeaux.c.

  1044   1044   ** MoveTo now.  Return an error code.  If no MoveTo is pending, this
  1045   1045   ** routine does nothing and returns SQLITE_OK.
  1046   1046   */
  1047   1047   int sqlite3VdbeCursorMoveto(Cursor *p){
  1048   1048     if( p->deferredMoveto ){
  1049   1049       int res;
  1050   1050       extern int sqlite3_search_count;
         1051  +    assert( p->intKey );
  1051   1052       if( p->intKey ){
  1052   1053         sqlite3BtreeMoveto(p->pCursor, 0, p->movetoTarget, &res);
  1053   1054       }else{
  1054   1055         sqlite3BtreeMoveto(p->pCursor,(char*)&p->movetoTarget,sizeof(i64),&res);
  1055   1056       }
  1056   1057       p->lastRecno = keyToInt(p->movetoTarget);
  1057   1058       p->recnoIsValid = res==0;

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.14 2004/05/10 23:29:51 drh Exp $
           15  +# $Id: attach.test,v 1.15 2004/05/11 09:31:32 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  +set btree_trace 0
    27     27   do_test attach-1.1 {
    28     28     execsql {
    29     29       CREATE TABLE t1(a,b);
    30     30       INSERT INTO t1 VALUES(1,2);
    31     31       INSERT INTO t1 VALUES(3,4);
    32     32       SELECT * FROM t1;
    33     33     }