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 |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
6d378cb7e7e081bb3bcd3a347bc1e02f |
User & Date: | drh 2004-05-11 09:31:32.000 |
Context
2004-05-11
| ||
09:50 | Fix a bug that was preventing the library from opening existing files. (CVS 1358) (check-in: ad064bd429 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: 6d378cb7e7 user: drh tags: trunk) | |
09:05 | Remove the unused upgrade_3_schema subroutine from main.c. (CVS 1356) (check-in: b5d2771ee0 user: drh tags: trunk) | |
Changes
Changes to src/btree.c.
1 2 3 4 5 6 7 8 9 10 11 | /* ** 2004 April 6 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | /* ** 2004 April 6 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** $Id: btree.c,v 1.127 2004/05/11 09:31:32 drh Exp $ ** ** This file implements a external (disk-based) database using BTrees. ** For a detailed discussion of BTrees, refer to ** ** Donald E. Knuth, THE ART OF COMPUTER PROGRAMMING, Volume 3: ** "Sorting And Searching", pages 473-480. Addison-Wesley ** Publishing Company, Reading, Massachusetts. |
︙ | ︙ | |||
3432 3433 3434 3435 3436 3437 3438 | return rc; } /* ** Read the meta-information out of a database file. Meta[0] ** is the number of free pages currently in the database. Meta[1] | | > > > > > | 3432 3433 3434 3435 3436 3437 3438 3439 3440 3441 3442 3443 3444 3445 3446 3447 3448 3449 3450 3451 | return rc; } /* ** Read the meta-information out of a database file. Meta[0] ** is the number of free pages currently in the database. Meta[1] ** through meta[15] are available for use by higher layers. Meta[0] ** is read-only, the others are read/write. ** ** The schema layer numbers meta values differently. At the schema ** layer (and the SetCookie and ReadCookie opcodes) the number of ** free pages is not visible. So Cookie[0] is the same as Meta[1]. */ int sqlite3BtreeGetMeta(Btree *pBt, int idx, u32 *pMeta){ int rc; unsigned char *pP1; assert( idx>=0 && idx<=15 ); rc = sqlite3pager_get(pBt->pPager, 1, (void**)&pP1); |
︙ | ︙ |
Changes to src/main.c.
︙ | ︙ | |||
10 11 12 13 14 15 16 | ** ************************************************************************* ** Main file for the SQLite library. The routines in this file ** implement the programmer interface to the library. Routines in ** other files are for internal use by SQLite and should not be ** accessed by users of the library. ** | | | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | ** ************************************************************************* ** Main file for the SQLite library. The routines in this file ** implement the programmer interface to the library. Routines in ** other files are for internal use by SQLite and should not be ** accessed by users of the library. ** ** $Id: main.c,v 1.173 2004/05/11 09:31:32 drh Exp $ */ #include "sqliteInt.h" #include "os.h" #include <ctype.h> /* ** A pointer to this structure is used to communicate information |
︙ | ︙ | |||
134 135 136 137 138 139 140 | static int sqlite3InitOne(sqlite *db, int iDb, char **pzErrMsg){ int rc; BtCursor *curMain; int size; Table *pTab; char *azArg[6]; char zDbNum[30]; | | | 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 | static int sqlite3InitOne(sqlite *db, int iDb, char **pzErrMsg){ int rc; BtCursor *curMain; int size; Table *pTab; char *azArg[6]; char zDbNum[30]; int meta[10]; InitData initData; /* ** The master database table has a structure like this */ static char master_schema[] = "CREATE TABLE sqlite_master(\n" |
︙ | ︙ | |||
206 207 208 209 210 211 212 | if( db->aDb[iDb].pBt==0 ) return SQLITE_OK; rc = sqlite3BtreeCursor(db->aDb[iDb].pBt, MASTER_ROOT, 0, 0, 0, &curMain); if( rc!=SQLITE_OK && rc!=SQLITE_EMPTY ){ sqlite3SetString(pzErrMsg, sqlite3_error_string(rc), (char*)0); return rc; } | | > > > > > > > > > > > > | | | | | | | | | | | | | 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 | if( db->aDb[iDb].pBt==0 ) return SQLITE_OK; rc = sqlite3BtreeCursor(db->aDb[iDb].pBt, MASTER_ROOT, 0, 0, 0, &curMain); if( rc!=SQLITE_OK && rc!=SQLITE_EMPTY ){ sqlite3SetString(pzErrMsg, sqlite3_error_string(rc), (char*)0); return rc; } /* Get the database meta information. ** ** Meta values are as follows: ** meta[0] Schema cookie. Changes with each schema change. ** meta[1] File format of schema layer. ** meta[2] Size of the page cache. ** meta[3] Synchronous setting. 1:off, 2:normal, 3:full ** meta[4] ** meta[5] Pragma temp_store value. See comments on BtreeFactory ** meta[6] ** meta[7] ** meta[8] ** meta[9] */ if( rc==SQLITE_OK ){ int i; for(i=0; rc==SQLITE_OK && i<sizeof(meta)/sizeof(meta[0]); i++){ rc = sqlite3BtreeGetMeta(db->aDb[iDb].pBt, i+1, &meta[i]); } if( rc ){ sqlite3SetString(pzErrMsg, sqlite3_error_string(rc), (char*)0); sqlite3BtreeCloseCursor(curMain); return rc; } }else{ memset(meta, 0, sizeof(meta)); } db->aDb[iDb].schema_cookie = meta[0]; if( iDb==0 ){ db->next_cookie = meta[0]; db->file_format = meta[1]; size = meta[2]; if( size==0 ){ size = MAX_PAGES; } db->cache_size = size; db->safety_level = meta[3]; if( meta[5]>0 && meta[5]<=2 && db->temp_store==0 ){ db->temp_store = meta[5]; } if( db->safety_level==0 ) db->safety_level = 2; /* ** file_format==1 Version 3.0.0. */ if( db->file_format==0 ){ /* This happens if the database was initially empty */ db->file_format = 1; }else if( db->file_format>1 ){ sqlite3BtreeCloseCursor(curMain); sqlite3SetString(pzErrMsg, "unsupported file format", (char*)0); return SQLITE_ERROR; } }else if( db->file_format!=meta[1] ){ if( meta[1]==0 ){ sqlite3SetString(pzErrMsg, "cannot attach empty database: ", db->aDb[iDb].zName, (char*)0); }else{ sqlite3SetString(pzErrMsg, "incompatible file format in auxiliary " "database: ", db->aDb[iDb].zName, (char*)0); } sqlite3BtreeClose(db->aDb[iDb].pBt); db->aDb[iDb].pBt = 0; return SQLITE_FORMAT; } sqlite3BtreeSetCacheSize(db->aDb[iDb].pBt, db->cache_size); sqlite3BtreeSetSafetyLevel(db->aDb[iDb].pBt, meta[3]==0 ? 2 : meta[3]); /* Read the schema information out of the schema tables */ assert( db->init.busy ); sqlite3SafetyOff(db); if( rc==SQLITE_EMPTY ){ /* For an empty database, there is nothing to read */ |
︙ | ︙ |
Changes to src/vdbe.c.
︙ | ︙ | |||
39 40 41 42 43 44 45 | ** ** Various scripts scan this source file in order to generate HTML ** documentation, headers files, or other derived files. The formatting ** of the code in this file is, therefore, important. See other comments ** in this file for details. If in doubt, do not deviate from existing ** commenting and indentation practices when changing or adding code. ** | | | 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | ** ** Various scripts scan this source file in order to generate HTML ** documentation, headers files, or other derived files. The formatting ** of the code in this file is, therefore, important. See other comments ** in this file for details. If in doubt, do not deviate from existing ** commenting and indentation practices when changing or adding code. ** ** $Id: vdbe.c,v 1.281 2004/05/11 09:31:32 drh Exp $ */ #include "sqliteInt.h" #include "os.h" #include <ctype.h> #include "vdbeInt.h" /* |
︙ | ︙ | |||
2528 2529 2530 2531 2532 2533 2534 | ** executing this instruction. */ case OP_ReadCookie: { int iMeta; assert( pOp->p2<SQLITE_N_BTREE_META ); assert( pOp->p1>=0 && pOp->p1<db->nDb ); assert( db->aDb[pOp->p1].pBt!=0 ); | > > > > > > > | | 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 | ** executing this instruction. */ case OP_ReadCookie: { int iMeta; assert( pOp->p2<SQLITE_N_BTREE_META ); assert( pOp->p1>=0 && pOp->p1<db->nDb ); assert( db->aDb[pOp->p1].pBt!=0 ); /* The indexing of meta values at the schema layer is off by one from ** the indexing in the btree layer. The btree considers meta[0] to ** be the number of free pages in the database (a read-only value) ** and meta[1] to be the schema cookie. The schema layer considers ** meta[1] to be the schema cookie. So we have to shift the index ** by one in the following statement. */ rc = sqlite3BtreeGetMeta(db->aDb[pOp->p1].pBt, 1 + pOp->p2, &iMeta); pTos++; pTos->i = iMeta; pTos->flags = MEM_Int; break; } /* Opcode: SetCookie P1 P2 * |
︙ | ︙ | |||
2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 | */ case OP_SetCookie: { assert( pOp->p2<SQLITE_N_BTREE_META ); assert( pOp->p1>=0 && pOp->p1<db->nDb ); assert( db->aDb[pOp->p1].pBt!=0 ); assert( pTos>=p->aStack ); Integerify(pTos); rc = sqlite3BtreeUpdateMeta(db->aDb[pOp->p1].pBt, 1+pOp->p2, (int)pTos->i); Release(pTos); pTos--; break; } /* Opcode: VerifyCookie P1 P2 * | > | 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 | */ case OP_SetCookie: { assert( pOp->p2<SQLITE_N_BTREE_META ); assert( pOp->p1>=0 && pOp->p1<db->nDb ); assert( db->aDb[pOp->p1].pBt!=0 ); assert( pTos>=p->aStack ); Integerify(pTos); /* See note about index shifting on OP_ReadCookie */ rc = sqlite3BtreeUpdateMeta(db->aDb[pOp->p1].pBt, 1+pOp->p2, (int)pTos->i); Release(pTos); pTos--; break; } /* Opcode: VerifyCookie P1 P2 * |
︙ | ︙ | |||
2931 2932 2933 2934 2935 2936 2937 | /* Opcode: IsUnique P1 P2 * ** ** The top of the stack is an integer record number. Call this ** record number R. The next on the stack is an index key created ** using MakeIdxKey. Call it K. This instruction pops R from the ** stack but it leaves K unchanged. ** | | | | | | | < | | | | | | 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 | /* Opcode: IsUnique P1 P2 * ** ** The top of the stack is an integer record number. Call this ** record number R. The next on the stack is an index key created ** using MakeIdxKey. Call it K. This instruction pops R from the ** stack but it leaves K unchanged. ** ** P1 is an index. So all but the last four bytes of K are an ** index string. The last four bytes of K are a record number. ** ** This instruction asks if there is an entry in P1 where the ** index string matches K but the record number is different ** from R. If there is no such entry, then there is an immediate ** jump to P2. If any entry does exist where the index string ** matches K but the record number is not R, then the record ** number for that entry is pushed onto the stack and control ** falls through to the next instruction. ** ** See also: Distinct, NotFound, NotExists, Found */ case OP_IsUnique: { int i = pOp->p1; Mem *pNos = &pTos[-1]; Cursor *pCx; BtCursor *pCrsr; int R; /* Pop the value R off the top of the stack */ assert( pNos>=p->aStack ); Integerify(pTos); R = pTos->i; pTos--; assert( i>=0 && i<=p->nCursor ); pCx = &p->aCsr[i]; pCrsr = pCx->pCursor; if( pCrsr!=0 ){ int res, rc; int v; /* The record number on the P1 entry that matches K */ char *zKey; /* The value of K */ int nKey; /* Number of bytes in K */ /* Make sure K is a string and make zKey point to K */ Stringify(pNos); zKey = pNos->z; nKey = pNos->n; assert( nKey >= 4 ); /* Search for an entry in P1 where all but the last four bytes match K. ** If there is no such entry, jump immediately to P2. */ assert( p->aCsr[i].deferredMoveto==0 ); rc = sqlite3BtreeMoveto(pCrsr, zKey, nKey-4, &res); if( rc!=SQLITE_OK ) goto abort_due_to_error; if( res<0 ){ rc = sqlite3BtreeNext(pCrsr, &res); if( res ){ pc = pOp->p2 - 1; break; } } /* FIX ME - the sqlite2BtreeKeyCompare() function is a temporary hack */ rc = sqlite2BtreeKeyCompare(pCrsr, zKey, nKey-4, 4, &res); if( rc!=SQLITE_OK ) goto abort_due_to_error; if( res>0 ){ pc = pOp->p2 - 1; break; } /* At this point, pCrsr is pointing to an entry in P1 where all but ** the last for bytes of the key match K. Check to see if the last ** four bytes of the key are different from R. If the last four ** bytes equal R then jump immediately to P2. */ sqlite3BtreeKey(pCrsr, nKey - 4, 4, (char*)&v); v = keyToInt(v); if( v==R ){ pc = pOp->p2 - 1; break; } /* The last four bytes of the key are different from R. Convert the |
︙ | ︙ | |||
3429 3430 3431 3432 3433 3434 3435 | }else if( (pC = &p->aCsr[i])->pCursor!=0 ){ sqlite3VdbeCursorMoveto(pC); zRec = 0; pCrsr = pC->pCursor; if( pC->nullRow ){ payloadSize = 0; }else if( pC->keyAsData ){ | < > | 3436 3437 3438 3439 3440 3441 3442 3443 3444 3445 3446 3447 3448 3449 3450 3451 | }else if( (pC = &p->aCsr[i])->pCursor!=0 ){ sqlite3VdbeCursorMoveto(pC); zRec = 0; pCrsr = pC->pCursor; if( pC->nullRow ){ payloadSize = 0; }else if( pC->keyAsData ){ u64 pl64; assert( !pC->intKey ); sqlite3BtreeKeySize(pCrsr, &pl64); payloadSize = pl64; }else{ sqlite3BtreeDataSize(pCrsr, &payloadSize); } }else if( pC->pseudoTable ){ payloadSize = pC->nData; |
︙ | ︙ | |||
5087 5088 5089 5090 5091 5092 5093 | if( p->trace && pTos>=p->aStack ){ int i; fprintf(p->trace, "Stack:"); for(i=0; i>-5 && &pTos[i]>=p->aStack; i--){ if( pTos[i].flags & MEM_Null ){ fprintf(p->trace, " NULL"); }else if( (pTos[i].flags & (MEM_Int|MEM_Str))==(MEM_Int|MEM_Str) ){ | | | | 5094 5095 5096 5097 5098 5099 5100 5101 5102 5103 5104 5105 5106 5107 5108 5109 5110 | if( p->trace && pTos>=p->aStack ){ int i; fprintf(p->trace, "Stack:"); for(i=0; i>-5 && &pTos[i]>=p->aStack; i--){ if( pTos[i].flags & MEM_Null ){ fprintf(p->trace, " NULL"); }else if( (pTos[i].flags & (MEM_Int|MEM_Str))==(MEM_Int|MEM_Str) ){ fprintf(p->trace, " si:%lld", pTos[i].i); }else if( pTos[i].flags & MEM_Int ){ fprintf(p->trace, " i:%lld", pTos[i].i); }else if( pTos[i].flags & MEM_Real ){ fprintf(p->trace, " r:%g", pTos[i].r); }else if( pTos[i].flags & MEM_Str ){ int j, k; char zBuf[100]; zBuf[0] = ' '; if( pTos[i].flags & MEM_Dyn ){ |
︙ | ︙ |
Changes to src/vdbeaux.c.
︙ | ︙ | |||
1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 | ** MoveTo now. Return an error code. If no MoveTo is pending, this ** routine does nothing and returns SQLITE_OK. */ int sqlite3VdbeCursorMoveto(Cursor *p){ if( p->deferredMoveto ){ int res; extern int sqlite3_search_count; if( p->intKey ){ sqlite3BtreeMoveto(p->pCursor, 0, p->movetoTarget, &res); }else{ sqlite3BtreeMoveto(p->pCursor,(char*)&p->movetoTarget,sizeof(i64),&res); } p->lastRecno = keyToInt(p->movetoTarget); p->recnoIsValid = res==0; | > | 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 | ** MoveTo now. Return an error code. If no MoveTo is pending, this ** routine does nothing and returns SQLITE_OK. */ int sqlite3VdbeCursorMoveto(Cursor *p){ if( p->deferredMoveto ){ int res; extern int sqlite3_search_count; assert( p->intKey ); if( p->intKey ){ sqlite3BtreeMoveto(p->pCursor, 0, p->movetoTarget, &res); }else{ sqlite3BtreeMoveto(p->pCursor,(char*)&p->movetoTarget,sizeof(i64),&res); } p->lastRecno = keyToInt(p->movetoTarget); p->recnoIsValid = res==0; |
︙ | ︙ |
Changes to test/attach.test.
︙ | ︙ | |||
8 9 10 11 12 13 14 | # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. The # focus of this script is testing the ATTACH and DETACH commands # and related functionality. # | | | | 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | # May you share freely, never taking more than you give. # #*********************************************************************** # This file implements regression tests for SQLite library. The # focus of this script is testing the ATTACH and DETACH commands # and related functionality. # # $Id: attach.test,v 1.15 2004/05/11 09:31:32 drh Exp $ # set testdir [file dirname $argv0] source $testdir/tester.tcl for {set i 2} {$i<=15} {incr i} { file delete -force test$i.db file delete -force test$i.db-journal } set btree_trace 0 do_test attach-1.1 { execsql { CREATE TABLE t1(a,b); INSERT INTO t1 VALUES(1,2); INSERT INTO t1 VALUES(3,4); SELECT * FROM t1; } |
︙ | ︙ |