SQLite

Check-in [1f680cb375]
Login

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

Overview
Comment:Merge leaf created by accident.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 1f680cb37584baa106cee0544d5be63049d55858
User & Date: dan 2010-08-20 12:34:00.000
References
2010-08-26
16:46
Add EXTERN macros before entry points in tclsqlite.c. These EXTERN macros were inexplicably removed by [1f680cb37584baa106cee05] a few days ago. (check-in: 8b2cf9d492 user: drh tags: trunk)
Context
2010-08-20
12:43
Fix typo in backcompat.test. (check-in: 6a0cbb272c user: dan tags: trunk)
12:34
Merge leaf created by accident. (check-in: 1f680cb375 user: dan tags: trunk)
12:31
Avoid assuming that the user has "." in their path when running multi-process tests. (check-in: daa5d461b9 user: dan tags: trunk)
10:28
Do not attempt run backwards compatibility tests if no historical "testfixture" binaries are available. (check-in: 40e11aabc7 user: drh tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/mem2.c.
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
  sqlite3_config(SQLITE_CONFIG_MALLOC, &defaultMethods);
}

/*
** Set the "type" of an allocation.
*/
void sqlite3MemdebugSetType(void *p, u8 eType){
  if( p ){
    struct MemBlockHdr *pHdr;
    pHdr = sqlite3MemsysGetHeader(p);
    assert( pHdr->iForeGuard==FOREGUARD );
    pHdr->eType = eType;
  }
}

/*
** Return TRUE if the mask of type in eType matches the type of the
** allocation p.  Also return true if p==NULL.
**
** This routine is designed for use within an assert() statement, to
** verify the type of an allocation.  For example:
**
**     assert( sqlite3MemdebugHasType(p, MEMTYPE_DB) );
*/
int sqlite3MemdebugHasType(void *p, u8 eType){
  int rc = 1;
  if( p ){
    struct MemBlockHdr *pHdr;
    pHdr = sqlite3MemsysGetHeader(p);
    assert( pHdr->iForeGuard==FOREGUARD );         /* Allocation is valid */
    if( (pHdr->eType&eType)==0 ){
      rc = 0;
    }
  }







|


















|







374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
  sqlite3_config(SQLITE_CONFIG_MALLOC, &defaultMethods);
}

/*
** Set the "type" of an allocation.
*/
void sqlite3MemdebugSetType(void *p, u8 eType){
  if( p && sqlite3GlobalConfig.m.xMalloc==sqlite3MemMalloc ){
    struct MemBlockHdr *pHdr;
    pHdr = sqlite3MemsysGetHeader(p);
    assert( pHdr->iForeGuard==FOREGUARD );
    pHdr->eType = eType;
  }
}

/*
** Return TRUE if the mask of type in eType matches the type of the
** allocation p.  Also return true if p==NULL.
**
** This routine is designed for use within an assert() statement, to
** verify the type of an allocation.  For example:
**
**     assert( sqlite3MemdebugHasType(p, MEMTYPE_DB) );
*/
int sqlite3MemdebugHasType(void *p, u8 eType){
  int rc = 1;
  if( p && sqlite3GlobalConfig.m.xMalloc==sqlite3MemMalloc ){
    struct MemBlockHdr *pHdr;
    pHdr = sqlite3MemsysGetHeader(p);
    assert( pHdr->iForeGuard==FOREGUARD );         /* Allocation is valid */
    if( (pHdr->eType&eType)==0 ){
      rc = 0;
    }
  }
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
** This routine is designed for use within an assert() statement, to
** verify the type of an allocation.  For example:
**
**     assert( sqlite3MemdebugNoType(p, MEMTYPE_DB) );
*/
int sqlite3MemdebugNoType(void *p, u8 eType){
  int rc = 1;
  if( p ){
    struct MemBlockHdr *pHdr;
    pHdr = sqlite3MemsysGetHeader(p);
    assert( pHdr->iForeGuard==FOREGUARD );         /* Allocation is valid */
    if( (pHdr->eType&eType)!=0 ){
      rc = 0;
    }
  }







|







415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
** This routine is designed for use within an assert() statement, to
** verify the type of an allocation.  For example:
**
**     assert( sqlite3MemdebugNoType(p, MEMTYPE_DB) );
*/
int sqlite3MemdebugNoType(void *p, u8 eType){
  int rc = 1;
  if( p && sqlite3GlobalConfig.m.xMalloc==sqlite3MemMalloc ){
    struct MemBlockHdr *pHdr;
    pHdr = sqlite3MemsysGetHeader(p);
    assert( pHdr->iForeGuard==FOREGUARD );         /* Allocation is valid */
    if( (pHdr->eType&eType)!=0 ){
      rc = 0;
    }
  }
Changes to src/pcache1.c.
196
197
198
199
200
201
202



















203
204
205
206
207
208
209
    sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
    iSize = sqlite3MallocSize(p);
    sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_OVERFLOW, -iSize);
    sqlite3_free(p);
  }
}




















/*
** Allocate a new page object initially associated with cache pCache.
*/
static PgHdr1 *pcache1AllocPage(PCache1 *pCache){
  int nByte = sizeof(PgHdr1) + pCache->szPage;
  void *pPg = pcache1Alloc(nByte);
  PgHdr1 *p;







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
    sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
    iSize = sqlite3MallocSize(p);
    sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_OVERFLOW, -iSize);
    sqlite3_free(p);
  }
}

#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
/*
** Return the size of a pache allocation
*/
static int pcache1MemSize(void *p){
  assert( sqlite3_mutex_held(pcache1.mutex) );
  if( p>=pcache1.pStart && p<pcache1.pEnd ){
    return pcache1.szSlot;
  }else{
    int iSize;
    assert( sqlite3MemdebugHasType(p, MEMTYPE_PCACHE) );
    sqlite3MemdebugSetType(p, MEMTYPE_HEAP);
    iSize = sqlite3MallocSize(p);
    sqlite3MemdebugSetType(p, MEMTYPE_PCACHE);
    return iSize;
  }
}
#endif /* SQLITE_ENABLE_MEMORY_MANAGEMENT */

/*
** Allocate a new page object initially associated with cache pCache.
*/
static PgHdr1 *pcache1AllocPage(PCache1 *pCache){
  int nByte = sizeof(PgHdr1) + pCache->szPage;
  void *pPg = pcache1Alloc(nByte);
  PgHdr1 *p;
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
*/
int sqlite3PcacheReleaseMemory(int nReq){
  int nFree = 0;
  if( pcache1.pStart==0 ){
    PgHdr1 *p;
    pcache1EnterMutex();
    while( (nReq<0 || nFree<nReq) && (p=pcache1.pLruTail) ){
      nFree += sqlite3MallocSize(PGHDR1_TO_PAGE(p));
      pcache1PinPage(p);
      pcache1RemoveFromHash(p);
      pcache1FreePage(p);
    }
    pcache1LeaveMutex();
  }
  return nFree;







|







763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
*/
int sqlite3PcacheReleaseMemory(int nReq){
  int nFree = 0;
  if( pcache1.pStart==0 ){
    PgHdr1 *p;
    pcache1EnterMutex();
    while( (nReq<0 || nFree<nReq) && (p=pcache1.pLruTail) ){
      nFree += pcache1MemSize(PGHDR1_TO_PAGE(p));
      pcache1PinPage(p);
      pcache1RemoveFromHash(p);
      pcache1FreePage(p);
    }
    pcache1LeaveMutex();
  }
  return nFree;
Changes to src/tclsqlite.c.
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
**
** This Tcl module contains only a single new Tcl command named "sqlite".
** (Hence there is no namespace.  There is no point in using a namespace
** if the extension only supplies one new name!)  The "sqlite" command is
** used to open a new SQLite database.  See the DbMain() routine above
** for additional information.
*/
EXTERN int Sqlite3_Init(Tcl_Interp *interp){
  Tcl_InitStubs(interp, "8.4", 0);
  Tcl_CreateObjCommand(interp, "sqlite3", (Tcl_ObjCmdProc*)DbMain, 0, 0);
  Tcl_PkgProvide(interp, "sqlite3", PACKAGE_VERSION);
  Tcl_CreateObjCommand(interp, "sqlite", (Tcl_ObjCmdProc*)DbMain, 0, 0);
  Tcl_PkgProvide(interp, "sqlite", PACKAGE_VERSION);
  return TCL_OK;
}
EXTERN int Tclsqlite3_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp); }
EXTERN int Sqlite3_SafeInit(Tcl_Interp *interp){ return TCL_OK; }
EXTERN int Tclsqlite3_SafeInit(Tcl_Interp *interp){ return TCL_OK; }
EXTERN int Sqlite3_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; }
EXTERN int Tclsqlite3_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; }
EXTERN int Sqlite3_SafeUnload(Tcl_Interp *interp, int flags){ return TCL_OK; }
EXTERN int Tclsqlite3_SafeUnload(Tcl_Interp *interp, int flags){ return TCL_OK;}


#ifndef SQLITE_3_SUFFIX_ONLY
EXTERN int Sqlite_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp); }
EXTERN int Tclsqlite_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp); }
EXTERN int Sqlite_SafeInit(Tcl_Interp *interp){ return TCL_OK; }
EXTERN int Tclsqlite_SafeInit(Tcl_Interp *interp){ return TCL_OK; }
EXTERN int Sqlite_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; }
EXTERN int Tclsqlite_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; }
EXTERN int Sqlite_SafeUnload(Tcl_Interp *interp, int flags){ return TCL_OK; }
EXTERN int Tclsqlite_SafeUnload(Tcl_Interp *interp, int flags){ return TCL_OK;}
#endif

#ifdef TCLSH
/*****************************************************************************
** All of the code that follows is used to build standalone TCL interpreters
** that are statically linked with SQLite.  Enable these by compiling
** with -DTCLSH=n where n can be 1 or 2.  An n of 1 generates a standard







|







|
|
|
|
|
|
|



|
|
|
|
|
|
|
|







3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
**
** This Tcl module contains only a single new Tcl command named "sqlite".
** (Hence there is no namespace.  There is no point in using a namespace
** if the extension only supplies one new name!)  The "sqlite" command is
** used to open a new SQLite database.  See the DbMain() routine above
** for additional information.
*/
int Sqlite3_Init(Tcl_Interp *interp){
  Tcl_InitStubs(interp, "8.4", 0);
  Tcl_CreateObjCommand(interp, "sqlite3", (Tcl_ObjCmdProc*)DbMain, 0, 0);
  Tcl_PkgProvide(interp, "sqlite3", PACKAGE_VERSION);
  Tcl_CreateObjCommand(interp, "sqlite", (Tcl_ObjCmdProc*)DbMain, 0, 0);
  Tcl_PkgProvide(interp, "sqlite", PACKAGE_VERSION);
  return TCL_OK;
}
int Tclsqlite3_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp); }
int Sqlite3_SafeInit(Tcl_Interp *interp){ return TCL_OK; }
int Tclsqlite3_SafeInit(Tcl_Interp *interp){ return TCL_OK; }
int Sqlite3_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; }
int Tclsqlite3_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; }
int Sqlite3_SafeUnload(Tcl_Interp *interp, int flags){ return TCL_OK; }
int Tclsqlite3_SafeUnload(Tcl_Interp *interp, int flags){ return TCL_OK;}


#ifndef SQLITE_3_SUFFIX_ONLY
int Sqlite_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp); }
int Tclsqlite_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp); }
int Sqlite_SafeInit(Tcl_Interp *interp){ return TCL_OK; }
int Tclsqlite_SafeInit(Tcl_Interp *interp){ return TCL_OK; }
int Sqlite_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; }
int Tclsqlite_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; }
int Sqlite_SafeUnload(Tcl_Interp *interp, int flags){ return TCL_OK; }
int Tclsqlite_SafeUnload(Tcl_Interp *interp, int flags){ return TCL_OK;}
#endif

#ifdef TCLSH
/*****************************************************************************
** All of the code that follows is used to build standalone TCL interpreters
** that are statically linked with SQLite.  Enable these by compiling
** with -DTCLSH=n where n can be 1 or 2.  An n of 1 generates a standard
Changes to test/backcompat.test.
30
31
32
33
34
35
36
37



38
39
40
41
42

43
44
45
46
47
48
49
50
51
52


53
54
55
56
57
58
59
60
db close

# Search for binaries to test against. Any executable files that match
# our naming convention are assumed to be testfixture binaries to test
# against.
#
set binaries [list]
set pattern "[file tail [info nameofexec]]*"



foreach file [glob $pattern] {
  if {[file executable $file]} {lappend binaries $file}
}
if {[llength $binaries]==0} {
  puts "WARNING: No binaries to test against. No tests have been run."

  finish_test
  return
}
proc get_version {binary} {
  set chan [launch_testfixture $binary]
  set v [testfixture $chan { sqlite3 -version }]
  close $chan
  set v
}
foreach bin $binaries {


  puts "Testing against $bin - version [get_version $bin]"
}

proc do_backcompat_test {rv bin1 bin2 script} {

  file delete -force test.db

  if {$bin1 != ""} { set ::bc_chan1 [launch_testfixture $bin1] }







|
>
>
>
|
|


|
>










>
>
|







30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
db close

# Search for binaries to test against. Any executable files that match
# our naming convention are assumed to be testfixture binaries to test
# against.
#
set binaries [list]
set pattern "[file tail [info nameofexec]]?*"
if {$tcl_platform(platform)=="windows"} {
  set pattern [string map {\.exe {}} $pattern]
}
foreach file [glob -nocomplain $pattern] {
  if {[file executable $file] && } {lappend binaries $file}
}
if {[llength $binaries]==0} {
  puts "WARNING: No historical binaries to test against."
  puts "WARNING: No backwards-compatibility tests have been run."
  finish_test
  return
}
proc get_version {binary} {
  set chan [launch_testfixture $binary]
  set v [testfixture $chan { sqlite3 -version }]
  close $chan
  set v
}
foreach bin $binaries {
  puts -nonewline "Testing against $bin - "
  flush stdout
  puts "version [get_version $bin]"
}

proc do_backcompat_test {rv bin1 bin2 script} {

  file delete -force test.db

  if {$bin1 != ""} { set ::bc_chan1 [launch_testfixture $bin1] }
88
89
90
91
92
93
94

95
96
97
98
99
100
101
proc do_allbackcompat_test {script} {

  foreach bin $::binaries {
    set nErr [set_test_counter errors]
    foreach dir {0 1} {

      set bintag [string map {testfixture {}} $bin]

      if {$bintag == ""} {set bintag self}
      set ::bcname ".$bintag.$dir."

      rename do_test _do_test
      proc do_test {nm sql res} {
        set nm [regsub {\.} $nm $::bcname]
        uplevel [list _do_test $nm $sql $res]







>







94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
proc do_allbackcompat_test {script} {

  foreach bin $::binaries {
    set nErr [set_test_counter errors]
    foreach dir {0 1} {

      set bintag [string map {testfixture {}} $bin]
      set bintag [string map {\.exe {}} $bintag]
      if {$bintag == ""} {set bintag self}
      set ::bcname ".$bintag.$dir."

      rename do_test _do_test
      proc do_test {nm sql res} {
        set nm [regsub {\.} $nm $::bcname]
        uplevel [list _do_test $nm $sql $res]
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213

  do_test backcompat-1.2.3 { sql1 {
    BEGIN;
      UPDATE t1 SET a = randomblob(500);
  } } {}
  set data [read_file_system]

  set f "test.db-journal[incr x]"
  file copy -force test.db-journal $f

  do_test backcompat-1.2.4 { sql1 { COMMIT } } {}

  set same [expr {[sql2 {SELECT md5sum(a), md5sum(b) FROM t1}] == $cksum2}]
  do_test backcompat-1.2.5 [list set {} $same] 0

  code1 { db close }
  code2 { db close }







<
<
<







204
205
206
207
208
209
210



211
212
213
214
215
216
217

  do_test backcompat-1.2.3 { sql1 {
    BEGIN;
      UPDATE t1 SET a = randomblob(500);
  } } {}
  set data [read_file_system]




  do_test backcompat-1.2.4 { sql1 { COMMIT } } {}

  set same [expr {[sql2 {SELECT md5sum(a), md5sum(b) FROM t1}] == $cksum2}]
  do_test backcompat-1.2.5 [list set {} $same] 0

  code1 { db close }
  code2 { db close }