SQLite

Check-in [78ae74db1c]
Login

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

Overview
Comment:Bug fix and better testing of the extended result codes. (CVS 3423)
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 78ae74db1cbf605cd421e7ea321e879d3638968e
User & Date: drh 2006-09-15 12:29:16.000
Context
2006-09-15
16:09
Fix an initialization problem in FTS1. Ticket #1977. (CVS 3424) (check-in: 5a18dd8849 user: drh tags: trunk)
12:29
Bug fix and better testing of the extended result codes. (CVS 3423) (check-in: 78ae74db1c user: drh tags: trunk)
07:28
Add support for extended result codes - additional result information carried in the higher bits of the integer return codes. This must be enabled using the sqlite3_extended_result_code() API. Only a few extra result codes are currently defined. (CVS 3422) (check-in: ba579ddc43 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.272 2006/09/15 07:28:50 drh 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.273 2006/09/15 12:29:16 drh Exp $
*/
#ifndef SQLITE_OMIT_DISKIO
#include "sqliteInt.h"
#include "os.h"
#include "pager.h"
#include <assert.h>
#include <string.h>
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241

242
243
244
245
246
247
248
  u8 stmtOpen;                /* True if the statement subjournal is open */
  u8 stmtInUse;               /* True we are in a statement subtransaction */
  u8 stmtAutoopen;            /* Open stmt journal when main journal is opened*/
  u8 noSync;                  /* Do not sync the journal if true */
  u8 fullSync;                /* Do extra syncs of the journal for robustness */
  u8 full_fsync;              /* Use F_FULLFSYNC when available */
  u8 state;                   /* PAGER_UNLOCK, _SHARED, _RESERVED, etc. */
  u8 errCode;                 /* One of several kinds of errors */
  u8 tempFile;                /* zFilename is a temporary file */
  u8 readOnly;                /* True for a read-only database */
  u8 needSync;                /* True if an fsync() is needed on the journal */
  u8 dirtyCache;              /* True if cached pages have changed */
  u8 alwaysRollback;          /* Disable dont_rollback() for all pages */
  u8 memDb;                   /* True to inhibit all file I/O */
  u8 setMaster;               /* True if a m-j name has been written to jrnl */

  int dbSize;                 /* Number of pages in the file */
  int origDbSize;             /* dbSize before the current change */
  int stmtSize;               /* Size of database (in pages) at stmt_begin() */
  int nRec;                   /* Number of pages written to the journal */
  u32 cksumInit;              /* Quasi-random value added to every checksum */
  int stmtNRec;               /* Number of records in stmt subjournal */
  int nExtra;                 /* Add this many bytes to each in-memory page */







<







>







227
228
229
230
231
232
233

234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
  u8 stmtOpen;                /* True if the statement subjournal is open */
  u8 stmtInUse;               /* True we are in a statement subtransaction */
  u8 stmtAutoopen;            /* Open stmt journal when main journal is opened*/
  u8 noSync;                  /* Do not sync the journal if true */
  u8 fullSync;                /* Do extra syncs of the journal for robustness */
  u8 full_fsync;              /* Use F_FULLFSYNC when available */
  u8 state;                   /* PAGER_UNLOCK, _SHARED, _RESERVED, etc. */

  u8 tempFile;                /* zFilename is a temporary file */
  u8 readOnly;                /* True for a read-only database */
  u8 needSync;                /* True if an fsync() is needed on the journal */
  u8 dirtyCache;              /* True if cached pages have changed */
  u8 alwaysRollback;          /* Disable dont_rollback() for all pages */
  u8 memDb;                   /* True to inhibit all file I/O */
  u8 setMaster;               /* True if a m-j name has been written to jrnl */
  int errCode;                /* One of several kinds of errors */
  int dbSize;                 /* Number of pages in the file */
  int origDbSize;             /* dbSize before the current change */
  int stmtSize;               /* Size of database (in pages) at stmt_begin() */
  int nRec;                   /* Number of pages written to the journal */
  u32 cksumInit;              /* Quasi-random value added to every checksum */
  int stmtNRec;               /* Number of records in stmt subjournal */
  int nExtra;                 /* Add this many bytes to each in-memory page */
1811
1812
1813
1814
1815
1816
1817

1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
** If the PENDING_BYTE lies on the page directly after the end of the
** file, then consider this page part of the file too. For example, if
** PENDING_BYTE is byte 4096 (the first byte of page 5) and the size of the
** file is 4096 bytes, 5 is returned instead of 4.
*/
int sqlite3pager_pagecount(Pager *pPager){
  i64 n;

  assert( pPager!=0 );
  if( pPager->dbSize>=0 ){
    n = pPager->dbSize;
  } else {
    if( sqlite3OsFileSize(pPager->fd, &n)!=SQLITE_OK ){
      pager_error(pPager, SQLITE_IOERR);
      return 0;
    }
    if( n>0 && n<pPager->pageSize ){
      n = 1;
    }else{
      n /= pPager->pageSize;
    }







>




|
|







1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
** If the PENDING_BYTE lies on the page directly after the end of the
** file, then consider this page part of the file too. For example, if
** PENDING_BYTE is byte 4096 (the first byte of page 5) and the size of the
** file is 4096 bytes, 5 is returned instead of 4.
*/
int sqlite3pager_pagecount(Pager *pPager){
  i64 n;
  int rc;
  assert( pPager!=0 );
  if( pPager->dbSize>=0 ){
    n = pPager->dbSize;
  } else {
    if( (rc = sqlite3OsFileSize(pPager->fd, &n))!=SQLITE_OK ){
      pager_error(pPager, rc);
      return 0;
    }
    if( n>0 && n<pPager->pageSize ){
      n = 1;
    }else{
      n /= pPager->pageSize;
    }
Changes to test/tester.tcl.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 2001 September 15
#
# 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 some common TCL routines used for regression
# testing the SQLite library
#
# $Id: tester.tcl,v 1.67 2006/09/15 07:28:51 drh Exp $

# Make sure tclsqlite3 was compiled correctly.  Abort now with an
# error message if not.
#
if {[sqlite3 -tcl-uses-utf]} {
  if {"\u1234"=="u1234"} {
    puts stderr "***** BUILD PROBLEM *****"













|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 2001 September 15
#
# 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 some common TCL routines used for regression
# testing the SQLite library
#
# $Id: tester.tcl,v 1.68 2006/09/15 12:29:16 drh Exp $

# Make sure tclsqlite3 was compiled correctly.  Abort now with an
# error message if not.
#
if {[sqlite3 -tcl-uses-utf]} {
  if {"\u1234"=="u1234"} {
    puts stderr "***** BUILD PROBLEM *****"
380
381
382
383
384
385
386












387
388
389
390
391
392
393

    # Execute the TCL Script created in the above block. If
    # there are at least N IO operations performed by SQLite as
    # a result of the script, the Nth will fail.
    do_test $testname.$n.3 {
      set r [catch $::ioerrorbody msg]
      # puts rc=[sqlite3_errcode $::DB]












      set ::go [expr {$::sqlite_io_error_pending<=0}]
      set s [expr $::sqlite_io_error_hit==0]
      set ::sqlite_io_error_hit 0
      # puts "$::sqlite_io_error_pending $r $msg"
      # puts "r=$r s=$s go=$::go msg=\"$msg\""
      expr { ($s && !$r && !$::go) || (!$s && $r && $::go) }
      # expr {$::sqlite_io_error_pending>0 || $r!=0}







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







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

    # Execute the TCL Script created in the above block. If
    # there are at least N IO operations performed by SQLite as
    # a result of the script, the Nth will fail.
    do_test $testname.$n.3 {
      set r [catch $::ioerrorbody msg]
      # puts rc=[sqlite3_errcode $::DB]
      set rc [sqlite3_errcode $::DB]
      if {$::ioerropts(-erc)} {
        # In extended result mode, all IOERRs are qualified 
        if {[regexp {^SQLITE_IOERR} $rc] && ![regexp {IOERR\+\d} $rc]} {
          return $rc
        }
      } else {
        # Not in extended result mode, no errors are qualified
        if {[regexp {\+\d} $rc]} {
          return $rc
        }
      }
      set ::go [expr {$::sqlite_io_error_pending<=0}]
      set s [expr $::sqlite_io_error_hit==0]
      set ::sqlite_io_error_hit 0
      # puts "$::sqlite_io_error_pending $r $msg"
      # puts "r=$r s=$s go=$::go msg=\"$msg\""
      expr { ($s && !$r && !$::go) || (!$s && $r && $::go) }
      # expr {$::sqlite_io_error_pending>0 || $r!=0}