SQLite

Check-in [e376480f08]
Login

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

Overview
Comment:Merge with latest trunk changes.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | blocking-checkpoint
Files: files | file ages | folders
SHA1: e376480f0855c598c91529abacbd73e31d9f4713
User & Date: dan 2010-11-18 16:32:54.000
Context
2010-11-18
16:59
Merge with latest trunk fix. (check-in: a8910e89de user: dan tags: blocking-checkpoint)
16:32
Merge with latest trunk changes. (check-in: e376480f08 user: dan tags: blocking-checkpoint)
16:14
Update test cases to account for the change in the previous commit. (check-in: ae089ec881 user: dan tags: blocking-checkpoint)
15:44
Added some tests to check that umlaut characters are supported in filenames. (check-in: c36f275d70 user: shaneh tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to ext/fts3/fts3.c.
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
        "CREATE TABLE %Q.'%q_stat'(id INTEGER PRIMARY KEY, value BLOB);",
        p->zDb, p->zName
    );
  }
  return rc;
}

/*
** An sqlite3_exec() callback for fts3TableExists.
*/
static int fts3TableExistsCallback(void *pArg, int n, char **pp1, char **pp2){
  UNUSED_PARAMETER(n);
  UNUSED_PARAMETER(pp1);
  UNUSED_PARAMETER(pp2);
  *(int*)pArg = 1;
  return 1;
}

/*
** Determine if a table currently exists in the database.
*/
static void fts3TableExists(
  int *pRc,             /* Success code */
  sqlite3 *db,          /* The database connection to test */
  const char *zDb,      /* ATTACHed database within the connection */
  const char *zName,    /* Name of the FTS3 table */
  const char *zSuffix,  /* Shadow table extension */
  u8 *pResult           /* Write results here */
){
  int rc = SQLITE_OK;
  int res = 0;
  char *zSql;
  if( *pRc ) return;
  zSql = sqlite3_mprintf(
    "SELECT 1 FROM %Q.sqlite_master WHERE name='%q%s'",
    zDb, zName, zSuffix
  );    
  rc = sqlite3_exec(db, zSql, fts3TableExistsCallback, &res, 0);
  sqlite3_free(zSql);
  *pResult = (u8)(res & 0xff);
  if( rc!=SQLITE_ABORT ) *pRc = rc;
}

/*
** Store the current database page-size in bytes in p->nPgsz.
**
** If *pRc is non-zero when this function is called, it is a no-op. 
** Otherwise, if an error occurs, an SQLite error code is stored in *pRc
** before returning.
*/







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







601
602
603
604
605
606
607




































608
609
610
611
612
613
614
        "CREATE TABLE %Q.'%q_stat'(id INTEGER PRIMARY KEY, value BLOB);",
        p->zDb, p->zName
    );
  }
  return rc;
}





































/*
** Store the current database page-size in bytes in p->nPgsz.
**
** If *pRc is non-zero when this function is called, it is a no-op. 
** Otherwise, if an error occurs, an SQLite error code is stored in *pRc
** before returning.
*/
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
}

/*
** Return the sum of the costs of all tokens in the expression pExpr. This
** function must be called after Fts3SegReaderArrays have been allocated
** for all tokens using fts3ExprAllocateSegReaders().
*/
int fts3ExprCost(Fts3Expr *pExpr){
  int nCost;                      /* Return value */
  if( pExpr->eType==FTSQUERY_PHRASE ){
    Fts3Phrase *pPhrase = pExpr->pPhrase;
    int ii;
    nCost = 0;
    for(ii=0; ii<pPhrase->nToken; ii++){
      nCost += pPhrase->aToken[ii].pArray->nCost;







|







2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
}

/*
** Return the sum of the costs of all tokens in the expression pExpr. This
** function must be called after Fts3SegReaderArrays have been allocated
** for all tokens using fts3ExprAllocateSegReaders().
*/
static int fts3ExprCost(Fts3Expr *pExpr){
  int nCost;                      /* Return value */
  if( pExpr->eType==FTSQUERY_PHRASE ){
    Fts3Phrase *pPhrase = pExpr->pPhrase;
    int ii;
    nCost = 0;
    for(ii=0; ii<pPhrase->nToken; ii++){
      nCost += pPhrase->aToken[ii].pArray->nCost;
Changes to ext/rtree/rtree.c.
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
  sqlite3_bind_null(pRtree->pWriteRowid, 2);
  sqlite3_step(pRtree->pWriteRowid);
  rc = sqlite3_reset(pRtree->pWriteRowid);
  *piRowid = sqlite3_last_insert_rowid(pRtree->db);
  return rc;
}

#ifndef NDEBUG
static int hashIsEmpty(Rtree *pRtree){
  int ii;
  for(ii=0; ii<HASHSIZE; ii++){
    assert( !pRtree->aHash[ii] );
  }
  return 1;
}
#endif

/*
** The xUpdate method for rtree module virtual tables.
*/
static int rtreeUpdate(
  sqlite3_vtab *pVtab, 
  int nData, 
  sqlite3_value **azData, 







<
<
<
<
<
<
<
<
<
<







2645
2646
2647
2648
2649
2650
2651










2652
2653
2654
2655
2656
2657
2658
  sqlite3_bind_null(pRtree->pWriteRowid, 2);
  sqlite3_step(pRtree->pWriteRowid);
  rc = sqlite3_reset(pRtree->pWriteRowid);
  *piRowid = sqlite3_last_insert_rowid(pRtree->db);
  return rc;
}











/*
** The xUpdate method for rtree module virtual tables.
*/
static int rtreeUpdate(
  sqlite3_vtab *pVtab, 
  int nData, 
  sqlite3_value **azData, 
Changes to src/sqlite.h.in.
2624
2625
2626
2627
2628
2629
2630














2631
2632
2633
2634
2635
2636
2637
**
** ^This interface can be used to retrieve a saved copy of the original
** SQL text used to create a [prepared statement] if that statement was
** compiled using either [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()].
*/
const char *sqlite3_sql(sqlite3_stmt *pStmt);















/*
** CAPI3REF: Dynamically Typed Value Object
** KEYWORDS: {protected sqlite3_value} {unprotected sqlite3_value}
**
** SQLite uses the sqlite3_value object to represent all values
** that can be stored in a database table. SQLite uses dynamic typing
** for the values it stores.  ^Values stored in sqlite3_value objects







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







2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
**
** ^This interface can be used to retrieve a saved copy of the original
** SQL text used to create a [prepared statement] if that statement was
** compiled using either [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()].
*/
const char *sqlite3_sql(sqlite3_stmt *pStmt);

/*
** CAPI3REF: Determine If An SQL Statement Writes The Database
**
** ^The sqlite3_stmt_readonly(X) interface returns true (non-zero) if
** the [prepared statement] X is [SELECT] statement and false (zero) if
** X is an [INSERT], [UPDATE], [DELETE], CREATE, DROP, [ANALYZE],
** [ALTER], or [REINDEX] statement.
** If X is a NULL pointer or any other kind of statement, including but
** not limited to [ATTACH], [DETACH], [COMMIT], [ROLLBACK], [RELEASE],
** [SAVEPOINT], [PRAGMA], or [VACUUM] the result of sqlite3_stmt_readonly(X) is
** undefined.
*/
int sqlite3_stmt_readonly(sqlite3_stmt *pStmt);

/*
** CAPI3REF: Dynamically Typed Value Object
** KEYWORDS: {protected sqlite3_value} {unprotected sqlite3_value}
**
** SQLite uses the sqlite3_value object to represent all values
** that can be stored in a database table. SQLite uses dynamic typing
** for the values it stores.  ^Values stored in sqlite3_value objects
Changes to src/test1.c.
2295
2296
2297
2298
2299
2300
2301



























2302
2303
2304
2305
2306
2307
2308
  if( pStmt ){
    if( sqlite3TestMakePointerStr(interp, zBuf, pStmt) ) return TCL_ERROR;
    Tcl_AppendResult(interp, zBuf, 0);
  }
  return TCL_OK;
}





























/*
** Usage:  sqlite3_reset  STMT 
**
** Reset a statement handle.
*/
static int test_reset(







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







2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
  if( pStmt ){
    if( sqlite3TestMakePointerStr(interp, zBuf, pStmt) ) return TCL_ERROR;
    Tcl_AppendResult(interp, zBuf, 0);
  }
  return TCL_OK;
}

/*
** Usage:  sqlite3_stmt_readonly  STMT
**
** Return true if STMT is a NULL pointer or a pointer to a statement
** that is guaranteed to leave the database unmodified.
*/
static int test_stmt_readonly(
  void * clientData,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
){
  sqlite3_stmt *pStmt;
  int rc;

  if( objc!=2 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"",
        Tcl_GetStringFromObj(objv[0], 0), " STMT", 0);
    return TCL_ERROR;
  }

  if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR;
  rc = sqlite3_stmt_readonly(pStmt);
  Tcl_SetObjResult(interp, Tcl_NewBooleanObj(rc));
  return TCL_OK;
}


/*
** Usage:  sqlite3_reset  STMT 
**
** Reset a statement handle.
*/
static int test_reset(
5388
5389
5390
5391
5392
5393
5394

5395
5396
5397
5398
5399
5400
5401
     { "sqlite3_reset",                 test_reset         ,0 },
     { "sqlite3_expired",               test_expired       ,0 },
     { "sqlite3_transfer_bindings",     test_transfer_bind ,0 },
     { "sqlite3_changes",               test_changes       ,0 },
     { "sqlite3_step",                  test_step          ,0 },
     { "sqlite3_sql",                   test_sql           ,0 },
     { "sqlite3_next_stmt",             test_next_stmt     ,0 },


     { "sqlite3_release_memory",        test_release_memory,     0},
     { "sqlite3_soft_heap_limit",       test_soft_heap_limit,    0},
     { "sqlite3_thread_cleanup",        test_thread_cleanup,     0},
     { "sqlite3_pager_refcounts",       test_pager_refcounts,    0},

     { "sqlite3_load_extension",        test_load_extension,     0},







>







5415
5416
5417
5418
5419
5420
5421
5422
5423
5424
5425
5426
5427
5428
5429
     { "sqlite3_reset",                 test_reset         ,0 },
     { "sqlite3_expired",               test_expired       ,0 },
     { "sqlite3_transfer_bindings",     test_transfer_bind ,0 },
     { "sqlite3_changes",               test_changes       ,0 },
     { "sqlite3_step",                  test_step          ,0 },
     { "sqlite3_sql",                   test_sql           ,0 },
     { "sqlite3_next_stmt",             test_next_stmt     ,0 },
     { "sqlite3_stmt_readonly",         test_stmt_readonly ,0 },

     { "sqlite3_release_memory",        test_release_memory,     0},
     { "sqlite3_soft_heap_limit",       test_soft_heap_limit,    0},
     { "sqlite3_thread_cleanup",        test_thread_cleanup,     0},
     { "sqlite3_pager_refcounts",       test_pager_refcounts,    0},

     { "sqlite3_load_extension",        test_load_extension,     0},
Changes to src/vdbe.c.
307
308
309
310
311
312
313
314
315
316
317
318

319
320

321
322
323
324
325
326
327
}

/*
** Try to convert the type of a function argument or a result column
** into a numeric representation.  Use either INTEGER or REAL whichever
** is appropriate.  But only do the conversion if it is possible without
** loss of information and return the revised type of the argument.
**
** This is an EXPERIMENTAL api and is subject to change or removal.
*/
int sqlite3_value_numeric_type(sqlite3_value *pVal){
  Mem *pMem = (Mem*)pVal;

  applyNumericAffinity(pMem);
  sqlite3VdbeMemStoreType(pMem);

  return pMem->type;
}

/*
** Exported version of applyAffinity(). This one works on sqlite3_value*, 
** not the internal Mem* type.
*/







<
<



>
|
|
>







307
308
309
310
311
312
313


314
315
316
317
318
319
320
321
322
323
324
325
326
327
}

/*
** Try to convert the type of a function argument or a result column
** into a numeric representation.  Use either INTEGER or REAL whichever
** is appropriate.  But only do the conversion if it is possible without
** loss of information and return the revised type of the argument.


*/
int sqlite3_value_numeric_type(sqlite3_value *pVal){
  Mem *pMem = (Mem*)pVal;
  if( pMem->type==SQLITE_TEXT ){
    applyNumericAffinity(pMem);
    sqlite3VdbeMemStoreType(pMem);
  }
  return pMem->type;
}

/*
** Exported version of applyAffinity(). This one works on sqlite3_value*, 
** not the internal Mem* type.
*/
Changes to src/vdbeapi.c.
1261
1262
1263
1264
1265
1266
1267








1268
1269
1270
1271
1272
1273
1274
** in the argument belongs.  This is the same database handle that was
** the first argument to the sqlite3_prepare() that was used to create
** the statement in the first place.
*/
sqlite3 *sqlite3_db_handle(sqlite3_stmt *pStmt){
  return pStmt ? ((Vdbe*)pStmt)->db : 0;
}









/*
** Return a pointer to the next prepared statement after pStmt associated
** with database connection pDb.  If pStmt is NULL, return the first
** prepared statement for the database connection.  Return NULL if there
** are no more.
*/







>
>
>
>
>
>
>
>







1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
** in the argument belongs.  This is the same database handle that was
** the first argument to the sqlite3_prepare() that was used to create
** the statement in the first place.
*/
sqlite3 *sqlite3_db_handle(sqlite3_stmt *pStmt){
  return pStmt ? ((Vdbe*)pStmt)->db : 0;
}

/*
** Return true if the prepared statement is guaranteed to not modify the
** database.
*/
int sqlite3_stmt_readonly(sqlite3_stmt *pStmt){
  return pStmt ? ((Vdbe*)pStmt)->readOnly : 1;
}

/*
** Return a pointer to the next prepared statement after pStmt associated
** with database connection pDb.  If pStmt is NULL, return the first
** prepared statement for the database connection.  Return NULL if there
** are no more.
*/
Changes to src/where.c.
4483
4484
4485
4486
4487
4488
4489
4490
4491
4492
4493
4494
4495
4496
4497

  /* Generate the code to do the search.  Each iteration of the for
  ** loop below generates code for a single nested loop of the VM
  ** program.
  */
  notReady = ~(Bitmask)0;
  for(i=0; i<nTabList; i++){
    WhereLevel *pLevel = &pWInfo->a[i];
    explainOneScan(pParse, pTabList, pLevel, i, pLevel->iFrom, wctrlFlags);
    notReady = codeOneLoopStart(pWInfo, i, wctrlFlags, notReady);
    pWInfo->iContinue = pLevel->addrCont;
  }

#ifdef SQLITE_TEST  /* For testing and debugging use only */
  /* Record in the query plan information about the current table







|







4483
4484
4485
4486
4487
4488
4489
4490
4491
4492
4493
4494
4495
4496
4497

  /* Generate the code to do the search.  Each iteration of the for
  ** loop below generates code for a single nested loop of the VM
  ** program.
  */
  notReady = ~(Bitmask)0;
  for(i=0; i<nTabList; i++){
    pLevel = &pWInfo->a[i];
    explainOneScan(pParse, pTabList, pLevel, i, pLevel->iFrom, wctrlFlags);
    notReady = codeOneLoopStart(pWInfo, i, wctrlFlags, notReady);
    pWInfo->iContinue = pLevel->addrCont;
  }

#ifdef SQLITE_TEST  /* For testing and debugging use only */
  /* Record in the query plan information about the current table
Changes to test/capi3d.test.
1
2
3
4
5
6
7
8
9
10
11
12
13

14
15
16
17
18
19
20
# 2008 June 18
#
# 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.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  
#
# This file is devoted to testing the sqlite3_next_stmt interface.

#
# $Id: capi3d.test,v 1.2 2008/07/14 15:11:20 drh Exp $
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl













|
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 2008 June 18
#
# 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.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  
#
# This file is devoted to testing the sqlite3_next_stmt and
# sqlite3_stmt_readonly interfaces.
#
# $Id: capi3d.test,v 1.2 2008/07/14 15:11:20 drh Exp $
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl

84
85
86
87
88
89
90
91

92





















93
  do_test capi3-1.2.$i.2 {
    foreach p [scramble $::stmtlist] {
      sqlite3_finalize $p
    }
    sqlite3_next_stmt db 0
  } {}
}
      























finish_test







|
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
  do_test capi3-1.2.$i.2 {
    foreach p [scramble $::stmtlist] {
      sqlite3_finalize $p
    }
    sqlite3_next_stmt db 0
  } {}
}

# Tests for the is-read-only interface.
#
proc test_is_readonly {testname sql truth} {
  do_test $testname [format {
    set DB [sqlite3_connection_pointer db]
    set STMT [sqlite3_prepare $DB {%s} -1 TAIL]
    set rc [sqlite3_stmt_readonly $STMT]
    sqlite3_finalize $STMT
    set rc
  } $sql] $truth
}

test_is_readonly capi3d-2.1 {SELECT * FROM sqlite_master} 1
test_is_readonly capi3d-2.2 {CREATE TABLE t1(x)} 0
db eval {CREATE TABLE t1(x)}
test_is_readonly capi3d-2.3 {INSERT INTO t1 VALUES(5)} 0
test_is_readonly capi3d-2.4 {UPDATE t1 SET x=x+1 WHERE x<0} 0
test_is_readonly capi3d-2.5 {SELECT * FROM t1} 1
do_test capi3-2.99 {
  sqlite3_stmt_readonly 0
} 1


finish_test
Added test/capi3e.test.






































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
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
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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# 2010 Novemeber 18
#
# 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.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this script testing the callback-free C/C++ API.
#
# $Id: capi3e.test,v 1.70 2009/01/09 02:49:32 drh Exp $
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# Do not use a codec for tests in this file, as the database file is
# manipulated directly using tcl scripts (using the [hexio_write] command).
#
do_not_use_codec

# Return the UTF-16 representation of the supplied UTF-8 string $str.
# If $nt is true, append two 0x00 bytes as a nul terminator.
proc utf16 {str {nt 1}} {
  set r [encoding convertto unicode $str]
  if {$nt} {
    append r "\x00\x00"
  }
  return $r
}

# Return the UTF-8 representation of the supplied UTF-16 string $str. 
proc utf8 {str} {
  # If $str ends in two 0x00 0x00 bytes, knock these off before
  # converting to UTF-8 using TCL.
  binary scan $str \c* vals
  if {[lindex $vals end]==0 && [lindex $vals end-1]==0} {
    set str [binary format \c* [lrange $vals 0 end-2]]
  }

  set r [encoding convertfrom unicode $str]
  return $r
}

# These tests complement those in capi2.test. They are organized
# as follows:
#
# capi3e-1.*: Test sqlite3_open with various UTF8 filenames
# capi3e-2.*: Test sqlite3_open16 with various UTF8 filenames
# capi3e-3.*: Test ATTACH with various UTF8 filenames

db close

# here's the list of file names we're testing
set names {t 1 t. 1. t.d 1.d t-1 1-1 t.db ä.db ë.db ö.db ü.db ÿ.db}

set i 0
foreach name $names {
  incr i
  do_test capi3e-1.1.$i {
    set db2 [sqlite3_open $name {}]
    sqlite3_errcode $db2
  } {SQLITE_OK}
  do_test capi3e-1.2.$i {
    sqlite3_close $db2
  } {SQLITE_OK}
  do_test capi3e-1.3.$i {
    file isfile $name
  } {1}
}

set i 0
foreach name $names {
  incr i
  do_test capi3e-2.1.$i {
    set db2 [sqlite3_open16 [utf16 $name] {}]
    sqlite3_errcode $db2
  } {SQLITE_OK}
  do_test capi3e-2.2.$i {
    sqlite3_close $db2
  } {SQLITE_OK}
  do_test capi3e-2.3.$i {
    file isfile $name
  } {1}
}

ifcapable attach {
  do_test capi3e-3.1 {
    sqlite3 db2 base.db
  } {}
  set i 0
  foreach name $names {
    incr i
    do_test capi3e-3.2.$i {
      db2 eval "ATTACH DATABASE '$name' AS db$i;"
    } {}
    do_test capi3e-3.3.$i {
      db2 eval "DETACH DATABASE db$i;"
    } {}
  }
  do_test capi3e-3.4 {
    db2 close
  } {}
}

# clean up
forcedelete base.db
foreach name $names {
  forcedelete $name
}

finish_test
Changes to test/wal5.test.
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119

  set ::busy_handler_script { 
    if {$n==5} { sql2 COMMIT } 
    if {$n==6} { set ::db_file_size [db_page_count] }
    if {$n==7} { sql3 COMMIT }
  }
  do_test 1.$tn.11 {
breakpoint
    sql1 { PRAGMA wal_checkpoint = RESTART }
    list [db_page_count] [wal_page_count] $::nBusyHandler
  } {10 5 8}
  do_test 1.$tn.12 { set ::db_file_size } 10
}

finish_test







<







105
106
107
108
109
110
111

112
113
114
115
116
117
118

  set ::busy_handler_script { 
    if {$n==5} { sql2 COMMIT } 
    if {$n==6} { set ::db_file_size [db_page_count] }
    if {$n==7} { sql3 COMMIT }
  }
  do_test 1.$tn.11 {

    sql1 { PRAGMA wal_checkpoint = RESTART }
    list [db_page_count] [wal_page_count] $::nBusyHandler
  } {10 5 8}
  do_test 1.$tn.12 { set ::db_file_size } 10
}

finish_test