SQLite

Check-in [9f62ef1ec3]
Login

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

Overview
Comment:Fix some problems with test cases in shared_err.test. Also a real bug causing a segfault after an IO error in pager.c. (CVS 3703)
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 9f62ef1ec385d9f1a1913439dc4c2d710373f12a
User & Date: danielk1977 2007-03-19 13:53:38.000
Context
2007-03-19
15:04
Add some test cases simulating crashes with various storage medium sector sizes. (CVS 3704) (check-in: c3c5f658cf user: danielk1977 tags: trunk)
13:53
Fix some problems with test cases in shared_err.test. Also a real bug causing a segfault after an IO error in pager.c. (CVS 3703) (check-in: 9f62ef1ec3 user: danielk1977 tags: trunk)
11:54
Fix a comment in btree.c (CVS 3702) (check-in: 05700c11a9 user: drh tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/pager.c.
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
** The pager is used to access a database disk file.  It implements
** atomic commit and rollback through the use of a journal file that
** is separate from the database file.  The pager also implements file
** locking to prevent two processes from writing the same database
** file simultaneously, or one process from reading the database while
** another is writing.
**
** @(#) $Id: pager.c,v 1.290 2007/03/19 11:25:20 danielk1977 Exp $
*/
#ifndef SQLITE_OMIT_DISKIO
#include "sqliteInt.h"
#include "os.h"
#include "pager.h"
#include <assert.h>
#include <string.h>







|







14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
** The pager is used to access a database disk file.  It implements
** atomic commit and rollback through the use of a journal file that
** is separate from the database file.  The pager also implements file
** locking to prevent two processes from writing the same database
** file simultaneously, or one process from reading the database while
** another is writing.
**
** @(#) $Id: pager.c,v 1.291 2007/03/19 13:53:38 danielk1977 Exp $
*/
#ifndef SQLITE_OMIT_DISKIO
#include "sqliteInt.h"
#include "os.h"
#include "pager.h"
#include <assert.h>
#include <string.h>
876
877
878
879
880
881
882

883
884
885
886
887
888
889
static void pager_reset(Pager *pPager){
  PgHdr *pPg, *pNext;
  if( pPager->errCode ) return;
  for(pPg=pPager->pAll; pPg; pPg=pNext){
    pNext = pPg->pNextAll;
    sqliteFree(pPg);
  }

  pPager->pFirst = 0;
  pPager->pFirstSynced = 0;
  pPager->pLast = 0;
  pPager->pAll = 0;
  pPager->nHash = 0;
  sqliteFree(pPager->aHash);
  pPager->nPage = 0;







>







876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
static void pager_reset(Pager *pPager){
  PgHdr *pPg, *pNext;
  if( pPager->errCode ) return;
  for(pPg=pPager->pAll; pPg; pPg=pNext){
    pNext = pPg->pNextAll;
    sqliteFree(pPg);
  }
  pPager->pStmt = 0;
  pPager->pFirst = 0;
  pPager->pFirstSynced = 0;
  pPager->pLast = 0;
  pPager->pAll = 0;
  pPager->nHash = 0;
  sqliteFree(pPager->aHash);
  pPager->nPage = 0;
Changes to test/shared_err.test.
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
#
#***********************************************************************
#
# The focus of the tests in this file are IO errors that occur in a shared
# cache context. What happens to connection B if one connection A encounters
# an IO-error whilst reading or writing the file-system?
#
# $Id: shared_err.test,v 1.9 2006/01/24 16:37:59 danielk1977 Exp $

proc skip {args} {}


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

ifcapable !shared_cache||!subquery {
  finish_test
  return
}
set ::enable_shared_cache [sqlite3_enable_shared_cache 1]


# Todo: This is a copy of the [do_malloc_test] proc in malloc.test
# It would be better if these were consolidated.

# Usage: do_malloc_test <test number> <options...>
#
# The first argument, <test number>, is an integer used to name the







|













<







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
#
#***********************************************************************
#
# The focus of the tests in this file are IO errors that occur in a shared
# cache context. What happens to connection B if one connection A encounters
# an IO-error whilst reading or writing the file-system?
#
# $Id: shared_err.test,v 1.10 2007/03/19 13:53:38 danielk1977 Exp $

proc skip {args} {}


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

ifcapable !shared_cache||!subquery {
  finish_test
  return
}
set ::enable_shared_cache [sqlite3_enable_shared_cache 1]


# Todo: This is a copy of the [do_malloc_test] proc in malloc.test
# It would be better if these were consolidated.

# Usage: do_malloc_test <test number> <options...>
#
# The first argument, <test number>, is an integer used to name the
252
253
254
255
256
257
258





















259

260

261


262
263
264




265

266



267

268
269
270
271
272
273
274
  execsql {
    BEGIN;
    INSERT INTO t1 VALUES('201.201.201.201.201', NULL);
    UPDATE t1 SET a = '202.202.202.202.202' WHERE a LIKE '201%';
    COMMIT;
  }
} -cleanup {





















  do_test shared_ioerr-3.$n.cleanup.1 {

    sqlite3_step $::STMT

  } {SQLITE_ROW}


  do_test shared_ioerr-3.$n.cleanup.2 {
    sqlite3_column_text $::STMT 0
  } {002.002.002.002.002}




  do_test shared_ioerr-3.$n.cleanup.3 {

    sqlite3_finalize $::STMT



  } {SQLITE_OK}

# db2 eval {select * from sqlite_master}
  db2 close
}

# Only run these tests if memory debugging is turned on.
#
if {[info command sqlite_malloc_stat]==""} {







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

>
|
>
|
>
>

|
|
>
>
>
>

>
|
>
>
>
|
>







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
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
  execsql {
    BEGIN;
    INSERT INTO t1 VALUES('201.201.201.201.201', NULL);
    UPDATE t1 SET a = '202.202.202.202.202' WHERE a LIKE '201%';
    COMMIT;
  }
} -cleanup {
  set ::steprc  [sqlite3_step $::STMT]
  set ::column  [sqlite3_column_text $::STMT 0]
  set ::finalrc [sqlite3_finalize $::STMT]

  # There are three possible outcomes here (assuming persistent IO errors):
  #
  # 1. If the [sqlite3_step] did not require any IO (required pages in
  #    the cache), then the next row ("002...") may be retrieved 
  #    successfully.
  #
  # 2. If the [sqlite3_step] does require IO, then [sqlite3_step] returns
  #    SQLITE_ERROR and [sqlite3_finalize] returns IOERR.
  #
  # 3. If, after the initial IO error, SQLite tried to rollback the
  #    active transaction and a second IO error was encountered, then
  #    statement $::STMT will have been aborted. This means [sqlite3_stmt]
  #    returns SQLITE_ABORT, and the statement cursor does not move. i.e.
  #    [sqlite3_column] still returns the current row ("001...") and
  #    [sqlite3_finalize] returns SQLITE_OK.
  #

  do_test shared_ioerr-3.$n.cleanup.1 {
    expr {
      $::steprc eq "SQLITE_ROW" || 
      $::steprc eq "SQLITE_ERROR" ||
      $::steprc eq "SQLITE_ABORT" 
    }
  } {1}
  do_test shared_ioerr-3.$n.cleanup.2 {
    expr {
      ($::steprc eq "SQLITE_ROW" && $::column eq "002.002.002.002.002") ||
      ($::steprc eq "SQLITE_ERROR" && $::column eq "") ||
      ($::steprc eq "SQLITE_ABORT" && $::column eq "001.001.001.001.001") 
    }
  } {1}
  do_test shared_ioerr-3.$n.cleanup.3 {
    expr {
      ($::steprc eq "SQLITE_ROW" && $::finalrc eq "SQLITE_OK") ||
      ($::steprc eq "SQLITE_ERROR" && $::finalrc eq "SQLITE_IOERR") ||
      ($::steprc eq "SQLITE_ABORT" && $::finalrc eq "SQLITE_OK")
    }
  } {1}

# db2 eval {select * from sqlite_master}
  db2 close
}

# Only run these tests if memory debugging is turned on.
#
if {[info command sqlite_malloc_stat]==""} {