Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Fix a bug with internally saving cursors open on index tables. Also increase coverage of util.c and btree.c. (CVS 2976) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
a628d84d3185fb7742cc929e758bfd59 |
User & Date: | danielk1977 2006-01-19 07:18:14.000 |
Context
2006-01-19
| ||
08:43 | Account for read-uncommitted cursors in sqlite3BtreeClearTable(). (CVS 2977) (check-in: 9507983268 user: danielk1977 tags: trunk) | |
07:18 | Fix a bug with internally saving cursors open on index tables. Also increase coverage of util.c and btree.c. (CVS 2976) (check-in: a628d84d31 user: danielk1977 tags: trunk) | |
2006-01-18
| ||
18:33 | Omit thread2.test if memory-management is enabled at compile time. (CVS 2975) (check-in: df91f685ca user: danielk1977 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.301 2006/01/19 07:18:14 danielk1977 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. |
︙ | ︙ | |||
507 508 509 510 511 512 513 | #else /* ** Save the current cursor position in the variables BtCursor.nKey ** and BtCursor.pKey. The cursor's state is set to CURSOR_REQUIRESEEK. */ static int saveCursorPosition(BtCursor *pCur){ | | | < | | | | | | | | | | | | | | | | | | | | | | | | < | 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 | #else /* ** Save the current cursor position in the variables BtCursor.nKey ** and BtCursor.pKey. The cursor's state is set to CURSOR_REQUIRESEEK. */ static int saveCursorPosition(BtCursor *pCur){ int rc; assert( CURSOR_VALID==pCur->eState ); assert( 0==pCur->pKey ); rc = sqlite3BtreeKeySize(pCur, &pCur->nKey); /* If this is an intKey table, then the above call to BtreeKeySize() ** stores the integer key in pCur->nKey. In this case this value is ** all that is required. Otherwise, if pCur is not open on an intKey ** table, then malloc space for and store the pCur->nKey bytes of key ** data. */ if( rc==SQLITE_OK && 0==pCur->pPage->intKey){ void *pKey = sqliteMalloc(pCur->nKey); if( pKey ){ rc = sqlite3BtreeKey(pCur, 0, pCur->nKey, pKey); if( rc==SQLITE_OK ){ pCur->pKey = pKey; }else{ sqliteFree(pKey); } }else{ rc = SQLITE_NOMEM; } } assert( !pCur->pPage->intKey || !pCur->pKey ); /* Todo: Should we drop the reference to pCur->pPage here? */ if( rc==SQLITE_OK ){ pCur->eState = CURSOR_REQUIRESEEK; } return rc; } /* ** Save the positions of all cursors except pExcept open on the table |
︙ | ︙ | |||
581 582 583 584 585 586 587 588 589 | ** returning the cursor to it's saved position, any saved position is deleted ** and the cursor state set to CURSOR_INVALID. */ static int restoreOrClearCursorPositionX(BtCursor *pCur, int doSeek){ int rc = SQLITE_OK; assert( sqlite3ThreadDataReadOnly()->useSharedData ); assert( pCur->eState==CURSOR_REQUIRESEEK ); if( doSeek ){ rc = sqlite3BtreeMoveto(pCur, pCur->pKey, pCur->nKey, &pCur->skip); | > < < | 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 | ** returning the cursor to it's saved position, any saved position is deleted ** and the cursor state set to CURSOR_INVALID. */ static int restoreOrClearCursorPositionX(BtCursor *pCur, int doSeek){ int rc = SQLITE_OK; assert( sqlite3ThreadDataReadOnly()->useSharedData ); assert( pCur->eState==CURSOR_REQUIRESEEK ); pCur->eState = CURSOR_INVALID; if( doSeek ){ rc = sqlite3BtreeMoveto(pCur, pCur->pKey, pCur->nKey, &pCur->skip); } if( rc==SQLITE_OK ){ sqliteFree(pCur->pKey); pCur->pKey = 0; assert( CURSOR_VALID==pCur->eState || CURSOR_INVALID==pCur->eState ); } return rc; |
︙ | ︙ |
Changes to src/test1.c.
︙ | ︙ | |||
9 10 11 12 13 14 15 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** Code for testing the printf() interface to SQLite. This code ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. ** | | | 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | ** May you share freely, never taking more than you give. ** ************************************************************************* ** Code for testing the printf() interface to SQLite. This code ** is not included in the SQLite library. It is used for automated ** testing of the SQLite library. ** ** $Id: test1.c,v 1.198 2006/01/19 07:18:14 danielk1977 Exp $ */ #include "sqliteInt.h" #include "tcl.h" #include "os.h" #include <stdlib.h> #include <string.h> |
︙ | ︙ | |||
905 906 907 908 909 910 911 | ClientData clientData, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int objc, /* Number of arguments */ Tcl_Obj *CONST objv[] /* Command arguments */ ){ extern int sqlite3OutstandingMallocs(Tcl_Interp *interp); | | < > > | | > > | | < > > > | 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 | ClientData clientData, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int objc, /* Number of arguments */ Tcl_Obj *CONST objv[] /* Command arguments */ ){ extern int sqlite3OutstandingMallocs(Tcl_Interp *interp); #if defined(SQLITE_DEBUG) && defined(SQLITE_MEMDEBUG) if( objc==2 ){ const char *zArg = Tcl_GetString(objv[1]); #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT ThreadData const *pTd = sqlite3ThreadDataReadOnly(); if( 0==strcmp(zArg, "-bytes") ){ Tcl_SetObjResult(interp, Tcl_NewIntObj(pTd->nAlloc)); }else if( 0==strcmp(zArg, "-clearmaxbytes") ){ sqlite3_nMaxAlloc = pTd->nAlloc; }else #endif if( 0==strcmp(zArg, "-maxbytes") ){ Tcl_SetObjResult(interp, Tcl_NewWideIntObj(sqlite3_nMaxAlloc)); }else{ Tcl_AppendResult(interp, "bad option \"", zArg, "\": must be -bytes, -maxbytes or -clearmaxbytes", 0 ); return TCL_ERROR; } return TCL_OK; } if( objc!=1 ){ Tcl_WrongNumArgs(interp, 1, objv, "?-bytes?"); return TCL_ERROR; } return sqlite3OutstandingMallocs(interp); #else return TCL_OK; #endif } #endif /* ** Usage: sqlite3_enable_shared_cache BOOLEAN ** */ |
︙ | ︙ |
Changes to src/util.c.
︙ | ︙ | |||
10 11 12 13 14 15 16 | ** ************************************************************************* ** Utility functions used throughout sqlite. ** ** This file contains functions for allocating memory, comparing ** strings, and stuff like that. ** | | | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | ** ************************************************************************* ** Utility functions used throughout sqlite. ** ** This file contains functions for allocating memory, comparing ** strings, and stuff like that. ** ** $Id: util.c,v 1.179 2006/01/19 07:18:14 danielk1977 Exp $ */ #include "sqliteInt.h" #include "os.h" #include <stdarg.h> #include <ctype.h> /* |
︙ | ︙ | |||
388 389 390 391 392 393 394 | ** * The __LINE__ macro ... ** * The value of the sqlite3_malloc_id variable ... ** * The output of backtrace() (if available) ... ** ** Todo: We could have a version of this function that outputs to stdout, ** to debug memory leaks when Tcl is not available. */ | | > | 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 | ** * The __LINE__ macro ... ** * The value of the sqlite3_malloc_id variable ... ** * The output of backtrace() (if available) ... ** ** Todo: We could have a version of this function that outputs to stdout, ** to debug memory leaks when Tcl is not available. */ #if defined(TCLSH) && defined(SQLITE_DEBUG) && SQLITE_MEMDEBUG>1 #include <tcl.h> int sqlite3OutstandingMallocs(Tcl_Interp *interp){ void *p; Tcl_Obj *pRes = Tcl_NewObj(); Tcl_IncrRefCount(pRes); for(p=sqlite3_pFirst; p; p=((void **)p)[1]){ Tcl_Obj *pEntry = Tcl_NewObj(); Tcl_Obj *pStack = Tcl_NewObj(); char *z; u32 iLine; int nBytes = sqlite3OsAllocationSize(p) - TESTALLOC_OVERHEAD; |
︙ | ︙ | |||
439 440 441 442 443 444 445 | #endif /* ** This is the test layer's wrapper around sqlite3OsMalloc(). */ static void * OSMALLOC(int n){ #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT | < | > | 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 | #endif /* ** This is the test layer's wrapper around sqlite3OsMalloc(). */ static void * OSMALLOC(int n){ #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT sqlite3_nMaxAlloc = MAX(sqlite3_nMaxAlloc, sqlite3ThreadDataReadOnly()->nAlloc); #endif assert( !sqlite3_mallocDisallowed ); if( !sqlite3TestMallocFail() ){ u32 *p; p = (u32 *)sqlite3OsMalloc(n + TESTALLOC_OVERHEAD); assert(p); sqlite3_nMalloc++; |
︙ | ︙ | |||
481 482 483 484 485 486 487 | } /* ** This is the test layer's wrapper around sqlite3OsRealloc(). */ static void * OSREALLOC(void *pRealloc, int n){ #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT | < < < < | > | 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 | } /* ** This is the test layer's wrapper around sqlite3OsRealloc(). */ static void * OSREALLOC(void *pRealloc, int n){ #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT sqlite3_nMaxAlloc = MAX(sqlite3_nMaxAlloc, sqlite3ThreadDataReadOnly()->nAlloc); #endif assert( !sqlite3_mallocDisallowed ); if( !sqlite3TestMallocFail() ){ u32 *p = (u32 *)getOsPointer(pRealloc); checkGuards(p); p = sqlite3OsRealloc(p, n + TESTALLOC_OVERHEAD); applyGuards(p); |
︙ | ︙ |
Changes to test/shared.test.
1 2 3 4 5 6 7 8 9 10 11 | # 2005 December 30 # # 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 | # 2005 December 30 # # 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: shared.test,v 1.18 2006/01/19 07:18:15 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl db close ifcapable !shared_cache { finish_test |
︙ | ︙ | |||
36 37 38 39 40 41 42 43 44 45 46 47 48 49 | } else { if {$av} { db close break } } incr av # Test organization: # # shared-1.*: Simple test to verify basic sanity of table level locking when # two connections share a pager cache. # shared-2.*: Test that a read transaction can co-exist with a | > > > > > | 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | } else { if {$av} { db close break } } # $av is currently 0 if this loop iteration is to test with auto-vacuum turned # off, and 1 if it is turned on. Increment it so that (1 -> no auto-vacuum) # and (2 -> auto-vacuum). The sole reason for this is so that it looks nicer # when we use this variable as part of test-case names. # incr av # Test organization: # # shared-1.*: Simple test to verify basic sanity of table level locking when # two connections share a pager cache. # shared-2.*: Test that a read transaction can co-exist with a |
︙ | ︙ | |||
197 198 199 200 201 202 203 | do_test shared-$av.3.1.1 { # This test case starts a linear scan of table 'seq' using a # read-uncommitted connection. In the middle of the scan, rows are added # to the end of the seq table (ahead of the current cursor position). # The uncommitted rows should be included in the results of the scan. execsql " | | | | 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 | do_test shared-$av.3.1.1 { # This test case starts a linear scan of table 'seq' using a # read-uncommitted connection. In the middle of the scan, rows are added # to the end of the seq table (ahead of the current cursor position). # The uncommitted rows should be included in the results of the scan. execsql " CREATE TABLE seq(i PRIMARY KEY, x); INSERT INTO seq VALUES(1, '[string repeat X 500]'); INSERT INTO seq VALUES(2, '[string repeat X 500]'); " execsql {SELECT * FROM sqlite_master} db2 execsql {PRAGMA read_uncommitted = 1} db2 set ret [list] db2 eval {SELECT i FROM seq ORDER BY i} { if {$i < 4} { set max [execsql {SELECT max(i) FROM seq}] db eval { INSERT INTO seq SELECT i + :max, x FROM seq; } } lappend ret $i |
︙ | ︙ |