1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-07-30 19:03:16 +03:00

Fix a bug with internally saving cursors open on index tables. Also increase coverage of util.c and btree.c. (CVS 2976)

FossilOrigin-Name: a628d84d3185fb7742cc929e758bfd59c811ca0b
This commit is contained in:
danielk1977
2006-01-19 07:18:14 +00:00
parent e7823cb591
commit 191c3e7db0
6 changed files with 61 additions and 56 deletions

View File

@ -1,5 +1,5 @@
C Omit\sthread2.test\sif\smemory-management\sis\senabled\sat\scompile\stime.\s(CVS\s2975) C Fix\sa\sbug\swith\sinternally\ssaving\scursors\sopen\son\sindex\stables.\sAlso\sincrease\scoverage\sof\sutil.c\sand\sbtree.c.\s(CVS\s2976)
D 2006-01-18T18:33:42 D 2006-01-19T07:18:14
F Makefile.in ab3ffd8d469cef4477257169b82810030a6bb967 F Makefile.in ab3ffd8d469cef4477257169b82810030a6bb967
F Makefile.linux-gcc aee18d8a05546dcf1888bd4547e442008a49a092 F Makefile.linux-gcc aee18d8a05546dcf1888bd4547e442008a49a092
F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028 F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028
@ -34,7 +34,7 @@ F src/alter.c 90b779cf00489535cab6490df6dc050f40e4e874
F src/analyze.c 7d2b7ab9a9c2fd6e55700f69064dfdd3e36d7a8a F src/analyze.c 7d2b7ab9a9c2fd6e55700f69064dfdd3e36d7a8a
F src/attach.c 0081040e9a5d13669b6712e947688c10f030bfc1 F src/attach.c 0081040e9a5d13669b6712e947688c10f030bfc1
F src/auth.c 9ae84d2d94eb96195e04515715e08e85963e96c2 F src/auth.c 9ae84d2d94eb96195e04515715e08e85963e96c2
F src/btree.c cff3ab167ad25b394d8c8dcac783bf3db5ae7e31 F src/btree.c 1f760cdb5bd763e8c8a7e4cf822a4266274e3faa
F src/btree.h 5663c4f43e8521546ccebc8fc95acb013b8f3184 F src/btree.h 5663c4f43e8521546ccebc8fc95acb013b8f3184
F src/build.c 15224e2fd348ad32b9044aaa5bdc912e4067da15 F src/build.c 15224e2fd348ad32b9044aaa5bdc912e4067da15
F src/callback.c 1bf497306c32229114f826707054df7ebe10abf2 F src/callback.c 1bf497306c32229114f826707054df7ebe10abf2
@ -73,7 +73,7 @@ F src/sqlite.h.in 492580f7e3ff71eb43193eb7bb98e2d549889ce3
F src/sqliteInt.h 7ddd6141a57748363fe42119f165d06260996aa3 F src/sqliteInt.h 7ddd6141a57748363fe42119f165d06260996aa3
F src/table.c 486dcfce532685b53b5a2b5da8bba0ded6fb2316 F src/table.c 486dcfce532685b53b5a2b5da8bba0ded6fb2316
F src/tclsqlite.c d650bea0248fc0a310ddc2cb94273a3a5021fddf F src/tclsqlite.c d650bea0248fc0a310ddc2cb94273a3a5021fddf
F src/test1.c 1c08d6533843687266d0d090d2c19bb0c9a9a907 F src/test1.c b7051f5080b1f9796cbc071f2cf4c03a4a975af3
F src/test2.c ca74a1d8aeb7d9606e8f6b762c5daf85c1a3f92b F src/test2.c ca74a1d8aeb7d9606e8f6b762c5daf85c1a3f92b
F src/test3.c 9742aa146eb750cab81c1d5605286c3a0eb88054 F src/test3.c 9742aa146eb750cab81c1d5605286c3a0eb88054
F src/test4.c 6633cb7b4a7429e938804a34f688d118c8b7f8e1 F src/test4.c 6633cb7b4a7429e938804a34f688d118c8b7f8e1
@ -85,7 +85,7 @@ F src/tokenize.c 1ac078540c2074568e16c0e9beea836fb16b1adc
F src/trigger.c 4d3644cbd16959b568c95ae73493402be8021b08 F src/trigger.c 4d3644cbd16959b568c95ae73493402be8021b08
F src/update.c 14be4ba2f438919b4217085c02feff569e6cf1f2 F src/update.c 14be4ba2f438919b4217085c02feff569e6cf1f2
F src/utf.c 5ab8ca05d4e9ec81174b010f01ab12a232f0087d F src/utf.c 5ab8ca05d4e9ec81174b010f01ab12a232f0087d
F src/util.c 3f09c6ffb1d0ea4efe17304c8c5c3612c5cd53fc F src/util.c 14f1f842caede231c8f72308c40d8e1f1cbec59e
F src/vacuum.c 3865673cc66acd0717ecd517f6b8fdb2a5e7924b F src/vacuum.c 3865673cc66acd0717ecd517f6b8fdb2a5e7924b
F src/vdbe.c 2a3d5ea76ab166bd77de9e3a7dbeb4a9354a1603 F src/vdbe.c 2a3d5ea76ab166bd77de9e3a7dbeb4a9354a1603
F src/vdbe.h 8729a4ee16ff9aeab2af9667df3cf300ff978e13 F src/vdbe.h 8729a4ee16ff9aeab2af9667df3cf300ff978e13
@ -225,7 +225,7 @@ F test/select5.test 07a90ab3c7e3f0a241a9cdea1d997b2c8a89ff0b
F test/select6.test f459a19bdac0501c4d3eb1a4df4b7a76f1bb8ad4 F test/select6.test f459a19bdac0501c4d3eb1a4df4b7a76f1bb8ad4
F test/select7.test 1bf795b948c133a15a2a5e99d3270e652ec58ce6 F test/select7.test 1bf795b948c133a15a2a5e99d3270e652ec58ce6
F test/server1.test e328b8e641ba8fe9273132cfef497383185dc1f5 F test/server1.test e328b8e641ba8fe9273132cfef497383185dc1f5
F test/shared.test fa058377c914a1abfc7d2247864d0471906111fd F test/shared.test 688bffac6928329f2e4d188de6c674652b7d61b7
F test/sort.test 0e4456e729e5a92a625907c63dcdedfbe72c5dc5 F test/sort.test 0e4456e729e5a92a625907c63dcdedfbe72c5dc5
F test/subquery.test ae324ee928c5fb463a3ce08a8860d6e7f1ca5797 F test/subquery.test ae324ee928c5fb463a3ce08a8860d6e7f1ca5797
F test/subselect.test 2d13fb7f450db3595adcdd24079a0dd1d2d6abc2 F test/subselect.test 2d13fb7f450db3595adcdd24079a0dd1d2d6abc2
@ -341,7 +341,7 @@ F www/tclsqlite.tcl bb0d1357328a42b1993d78573e587c6dcbc964b9
F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0
F www/version3.tcl a99cf5f6d8bd4d5537584a2b342f0fb9fa601d8b F www/version3.tcl a99cf5f6d8bd4d5537584a2b342f0fb9fa601d8b
F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513 F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513
P c7b9d50d0a975912776aaa2b870308652f77e1e6 P df91f685cacbcb3e048eaa03260b33bbcfcb321c
R 0b4da9c6676a7d07030b097567d769d5 R 72a56160d91187b3cc45d20fb8121c09
U danielk1977 U danielk1977
Z d8e3e0fd22ee5223fc21b64d390a9190 Z 2d080ce01ccda1df734492ab6955a12f

View File

@ -1 +1 @@
df91f685cacbcb3e048eaa03260b33bbcfcb321c a628d84d3185fb7742cc929e758bfd59c811ca0b

View File

@ -9,7 +9,7 @@
** May you share freely, never taking more than you give. ** May you share freely, never taking more than you give.
** **
************************************************************************* *************************************************************************
** $Id: btree.c,v 1.300 2006/01/18 15:25:17 danielk1977 Exp $ ** $Id: btree.c,v 1.301 2006/01/19 07:18:14 danielk1977 Exp $
** **
** This file implements a external (disk-based) database using BTrees. ** This file implements a external (disk-based) database using BTrees.
** For a detailed discussion of BTrees, refer to ** For a detailed discussion of BTrees, refer to
@ -511,40 +511,38 @@ struct BtLock {
** and BtCursor.pKey. The cursor's state is set to CURSOR_REQUIRESEEK. ** and BtCursor.pKey. The cursor's state is set to CURSOR_REQUIRESEEK.
*/ */
static int saveCursorPosition(BtCursor *pCur){ static int saveCursorPosition(BtCursor *pCur){
int rc = SQLITE_OK; int rc;
assert( CURSOR_VALID==pCur->eState|| CURSOR_INVALID==pCur->eState ); assert( CURSOR_VALID==pCur->eState );
assert( 0==pCur->pKey ); assert( 0==pCur->pKey );
if( pCur->eState==CURSOR_VALID ){ rc = sqlite3BtreeKeySize(pCur, &pCur->nKey);
rc = sqlite3BtreeKeySize(pCur, &pCur->nKey);
/* If this is an intKey table, then the above call to BtreeKeySize() /* 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 ** 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 ** 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 ** table, then malloc space for and store the pCur->nKey bytes of key
** data. ** data.
*/ */
if( rc==SQLITE_OK && 0==pCur->pPage->intKey){ if( rc==SQLITE_OK && 0==pCur->pPage->intKey){
void *pKey = sqliteMalloc(pCur->nKey); void *pKey = sqliteMalloc(pCur->nKey);
if( pKey ){ if( pKey ){
rc = sqlite3BtreeKey(pCur, 0, pCur->nKey, pKey); rc = sqlite3BtreeKey(pCur, 0, pCur->nKey, pKey);
if( rc==SQLITE_OK ){ if( rc==SQLITE_OK ){
pCur->pKey = pKey; pCur->pKey = pKey;
}else{
sqliteFree(pKey);
}
}else{ }else{
rc = SQLITE_NOMEM; sqliteFree(pKey);
} }
}else{
rc = SQLITE_NOMEM;
} }
assert( !pCur->pPage->intKey || !pCur->pKey ); }
assert( !pCur->pPage->intKey || !pCur->pKey );
/* Todo: Should we drop the reference to pCur->pPage here? */ /* Todo: Should we drop the reference to pCur->pPage here? */
if( rc==SQLITE_OK ){ if( rc==SQLITE_OK ){
pCur->eState = CURSOR_REQUIRESEEK; pCur->eState = CURSOR_REQUIRESEEK;
}
} }
return rc; return rc;
@ -585,10 +583,9 @@ static int restoreOrClearCursorPositionX(BtCursor *pCur, int doSeek){
int rc = SQLITE_OK; int rc = SQLITE_OK;
assert( sqlite3ThreadDataReadOnly()->useSharedData ); assert( sqlite3ThreadDataReadOnly()->useSharedData );
assert( pCur->eState==CURSOR_REQUIRESEEK ); assert( pCur->eState==CURSOR_REQUIRESEEK );
pCur->eState = CURSOR_INVALID;
if( doSeek ){ if( doSeek ){
rc = sqlite3BtreeMoveto(pCur, pCur->pKey, pCur->nKey, &pCur->skip); rc = sqlite3BtreeMoveto(pCur, pCur->pKey, pCur->nKey, &pCur->skip);
}else{
pCur->eState = CURSOR_INVALID;
} }
if( rc==SQLITE_OK ){ if( rc==SQLITE_OK ){
sqliteFree(pCur->pKey); sqliteFree(pCur->pKey);

View File

@ -13,7 +13,7 @@
** is not included in the SQLite library. It is used for automated ** is not included in the SQLite library. It is used for automated
** testing of the SQLite library. ** testing of the SQLite library.
** **
** $Id: test1.c,v 1.197 2006/01/18 18:22:43 danielk1977 Exp $ ** $Id: test1.c,v 1.198 2006/01/19 07:18:14 danielk1977 Exp $
*/ */
#include "sqliteInt.h" #include "sqliteInt.h"
#include "tcl.h" #include "tcl.h"
@ -909,16 +909,19 @@ static int sqlite_malloc_outstanding(
){ ){
extern int sqlite3OutstandingMallocs(Tcl_Interp *interp); extern int sqlite3OutstandingMallocs(Tcl_Interp *interp);
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT #if defined(SQLITE_DEBUG) && defined(SQLITE_MEMDEBUG)
if( objc==2 ){ if( objc==2 ){
ThreadData const *pTd = sqlite3ThreadDataReadOnly();
const char *zArg = Tcl_GetString(objv[1]); const char *zArg = Tcl_GetString(objv[1]);
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
ThreadData const *pTd = sqlite3ThreadDataReadOnly();
if( 0==strcmp(zArg, "-bytes") ){ if( 0==strcmp(zArg, "-bytes") ){
Tcl_SetObjResult(interp, Tcl_NewIntObj(pTd->nAlloc)); Tcl_SetObjResult(interp, Tcl_NewIntObj(pTd->nAlloc));
}else if( 0==strcmp(zArg, "-maxbytes") ){
Tcl_SetObjResult(interp, Tcl_NewWideIntObj(sqlite3_nMaxAlloc));
}else if( 0==strcmp(zArg, "-clearmaxbytes") ){ }else if( 0==strcmp(zArg, "-clearmaxbytes") ){
sqlite3_nMaxAlloc = pTd->nAlloc; sqlite3_nMaxAlloc = pTd->nAlloc;
}else
#endif
if( 0==strcmp(zArg, "-maxbytes") ){
Tcl_SetObjResult(interp, Tcl_NewWideIntObj(sqlite3_nMaxAlloc));
}else{ }else{
Tcl_AppendResult(interp, "bad option \"", zArg, Tcl_AppendResult(interp, "bad option \"", zArg,
"\": must be -bytes, -maxbytes or -clearmaxbytes", 0 "\": must be -bytes, -maxbytes or -clearmaxbytes", 0
@ -928,7 +931,6 @@ static int sqlite_malloc_outstanding(
return TCL_OK; return TCL_OK;
} }
#endif
if( objc!=1 ){ if( objc!=1 ){
Tcl_WrongNumArgs(interp, 1, objv, "?-bytes?"); Tcl_WrongNumArgs(interp, 1, objv, "?-bytes?");
@ -936,6 +938,9 @@ static int sqlite_malloc_outstanding(
} }
return sqlite3OutstandingMallocs(interp); return sqlite3OutstandingMallocs(interp);
#else
return TCL_OK;
#endif
} }
#endif #endif

View File

@ -14,7 +14,7 @@
** This file contains functions for allocating memory, comparing ** This file contains functions for allocating memory, comparing
** strings, and stuff like that. ** strings, and stuff like that.
** **
** $Id: util.c,v 1.178 2006/01/18 18:22:43 danielk1977 Exp $ ** $Id: util.c,v 1.179 2006/01/19 07:18:14 danielk1977 Exp $
*/ */
#include "sqliteInt.h" #include "sqliteInt.h"
#include "os.h" #include "os.h"
@ -392,13 +392,14 @@ static void relinkAlloc(void *p)
** Todo: We could have a version of this function that outputs to stdout, ** Todo: We could have a version of this function that outputs to stdout,
** to debug memory leaks when Tcl is not available. ** to debug memory leaks when Tcl is not available.
*/ */
#ifdef TCLSH #if defined(TCLSH) && defined(SQLITE_DEBUG) && SQLITE_MEMDEBUG>1
#include <tcl.h> #include <tcl.h>
int sqlite3OutstandingMallocs(Tcl_Interp *interp){ int sqlite3OutstandingMallocs(Tcl_Interp *interp){
void *p; void *p;
Tcl_Obj *pRes = Tcl_NewObj(); Tcl_Obj *pRes = Tcl_NewObj();
Tcl_IncrRefCount(pRes); Tcl_IncrRefCount(pRes);
for(p=sqlite3_pFirst; p; p=((void **)p)[1]){ for(p=sqlite3_pFirst; p; p=((void **)p)[1]){
Tcl_Obj *pEntry = Tcl_NewObj(); Tcl_Obj *pEntry = Tcl_NewObj();
Tcl_Obj *pStack = Tcl_NewObj(); Tcl_Obj *pStack = Tcl_NewObj();
@ -443,8 +444,8 @@ int sqlite3OutstandingMallocs(Tcl_Interp *interp){
*/ */
static void * OSMALLOC(int n){ static void * OSMALLOC(int n){
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
ThreadData const *pTsd = sqlite3ThreadDataReadOnly(); sqlite3_nMaxAlloc =
sqlite3_nMaxAlloc = MAX(sqlite3_nMaxAlloc, pTsd->nAlloc); MAX(sqlite3_nMaxAlloc, sqlite3ThreadDataReadOnly()->nAlloc);
#endif #endif
assert( !sqlite3_mallocDisallowed ); assert( !sqlite3_mallocDisallowed );
if( !sqlite3TestMallocFail() ){ if( !sqlite3TestMallocFail() ){
@ -485,11 +486,8 @@ static void OSFREE(void *pFree){
*/ */
static void * OSREALLOC(void *pRealloc, int n){ static void * OSREALLOC(void *pRealloc, int n){
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
ThreadData *pTsd = sqlite3ThreadData(); sqlite3_nMaxAlloc =
if( !pTsd ){ MAX(sqlite3_nMaxAlloc, sqlite3ThreadDataReadOnly()->nAlloc);
return 0;
}
sqlite3_nMaxAlloc = MAX(sqlite3_nMaxAlloc, pTsd->nAlloc);
#endif #endif
assert( !sqlite3_mallocDisallowed ); assert( !sqlite3_mallocDisallowed );
if( !sqlite3TestMallocFail() ){ if( !sqlite3TestMallocFail() ){

View File

@ -9,7 +9,7 @@
# #
#*********************************************************************** #***********************************************************************
# #
# $Id: shared.test,v 1.17 2006/01/17 09:35:02 danielk1977 Exp $ # $Id: shared.test,v 1.18 2006/01/19 07:18:15 danielk1977 Exp $
set testdir [file dirname $argv0] set testdir [file dirname $argv0]
source $testdir/tester.tcl source $testdir/tester.tcl
@ -40,6 +40,11 @@ ifcapable autovacuum {
} }
} }
# $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 incr av
# Test organization: # Test organization:
@ -201,7 +206,7 @@ do_test shared-$av.3.1.1 {
# to the end of the seq table (ahead of the current cursor position). # 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. # The uncommitted rows should be included in the results of the scan.
execsql " execsql "
CREATE TABLE seq(i, x); CREATE TABLE seq(i PRIMARY KEY, x);
INSERT INTO seq VALUES(1, '[string repeat X 500]'); INSERT INTO seq VALUES(1, '[string repeat X 500]');
INSERT INTO seq VALUES(2, '[string repeat X 500]'); INSERT INTO seq VALUES(2, '[string repeat X 500]');
" "
@ -209,7 +214,7 @@ do_test shared-$av.3.1.1 {
execsql {PRAGMA read_uncommitted = 1} db2 execsql {PRAGMA read_uncommitted = 1} db2
set ret [list] set ret [list]
db2 eval {SELECT i FROM seq} { db2 eval {SELECT i FROM seq ORDER BY i} {
if {$i < 4} { if {$i < 4} {
set max [execsql {SELECT max(i) FROM seq}] set max [execsql {SELECT max(i) FROM seq}]
db eval { db eval {