/ Check-in [d1ed743b]
Login

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

Overview
Comment:Changes to support building with SQLITE_OMIT_WAL.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: d1ed743b6ed07ad0ee7d466932c5a83caa9489ee
User & Date: shaneh 2010-08-24 18:35:12
Context
2010-08-24
20:46
Replicate asserts on unixOpen() to winOpen() in os_win.c. check-in: 40526d83 user: shaneh tags: trunk
18:35
Changes to support building with SQLITE_OMIT_WAL. check-in: d1ed743b user: shaneh tags: trunk
18:07
Change sqlite3_open_v2() to return SQLITE_MISUSE if the combination of bits in the flags parameter is invalid. The documentation says the behavior in this situation is undefined - the documentation is unaltered by this code change. check-in: 5e8101c5 user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/pager.c.

2973
2974
2975
2976
2977
2978
2979

2980
2981
2982
2983
2984
2985
2986
....
2994
2995
2996
2997
2998
2999
3000

3001



3002
3003
3004
3005
3006
3007
3008
....
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
....
4774
4775
4776
4777
4778
4779
4780

4781

4782
4783
4784
4785
4786
4787
4788
  rc = sqlite3WalBeginReadTransaction(pPager->pWal, &changed);
  if( rc==SQLITE_OK && changed ){
    pager_reset(pPager);
  }

  return rc;
}


/*
** This function is called as part of the transition from PAGER_OPEN
** to PAGER_READER state to determine the size of the database file
** in pages (assuming the page size currently stored in Pager.pageSize).
**
** If no error occurs, SQLITE_OK is returned and the size of the database
................................................................................
  ** function returns zero if the WAL is not open (i.e. Pager.pWal==0), or
  ** if the database size is not available. The database size is not
  ** available from the WAL sub-system if the log file is empty or
  ** contains no valid committed transactions.
  */
  assert( pPager->eState==PAGER_OPEN );
  assert( pPager->eLock>=SHARED_LOCK || pPager->noReadlock );

  nPage = sqlite3WalDbsize(pPager->pWal);




  /* If the database size was not available from the WAL sub-system,
  ** determine it based on the size of the database file. If the size
  ** of the database file is not an integer multiple of the page-size,
  ** round down to the nearest page. Except, any file larger than 0
  ** bytes in size is considered to contain at least one page.
  */
................................................................................
    pPager->mxPgno = (Pgno)nPage;
  }

  *pnPage = nPage;
  return SQLITE_OK;
}


/*
** Check if the *-wal file that corresponds to the database opened by pPager
** exists if the database is not empy, or verify that the *-wal file does
** not exist (by deleting it) if the database file is empty.
**
** If the database is not empty and the *-wal file exists, open the pager
** in WAL mode.  If the database is empty or if no *-wal file exists and
................................................................................
      }
    }

    /* If there is a WAL file in the file-system, open this database in WAL
    ** mode. Otherwise, the following function call is a no-op.
    */
    rc = pagerOpenWalIfPresent(pPager);

    assert( pPager->pWal==0 || rc==SQLITE_OK );

  }

  if( pagerUseWal(pPager) ){
    assert( rc==SQLITE_OK );
    rc = pagerBeginReadTransaction(pPager);
  }








>







 







>

>
>
>







 







|







 







>

>







2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
....
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
....
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
....
4779
4780
4781
4782
4783
4784
4785
4786
4787
4788
4789
4790
4791
4792
4793
4794
4795
  rc = sqlite3WalBeginReadTransaction(pPager->pWal, &changed);
  if( rc==SQLITE_OK && changed ){
    pager_reset(pPager);
  }

  return rc;
}
#endif

/*
** This function is called as part of the transition from PAGER_OPEN
** to PAGER_READER state to determine the size of the database file
** in pages (assuming the page size currently stored in Pager.pageSize).
**
** If no error occurs, SQLITE_OK is returned and the size of the database
................................................................................
  ** function returns zero if the WAL is not open (i.e. Pager.pWal==0), or
  ** if the database size is not available. The database size is not
  ** available from the WAL sub-system if the log file is empty or
  ** contains no valid committed transactions.
  */
  assert( pPager->eState==PAGER_OPEN );
  assert( pPager->eLock>=SHARED_LOCK || pPager->noReadlock );
#ifndef SQLITE_OMIT_WAL
  nPage = sqlite3WalDbsize(pPager->pWal);
#else
  nPage = 0;
#endif

  /* If the database size was not available from the WAL sub-system,
  ** determine it based on the size of the database file. If the size
  ** of the database file is not an integer multiple of the page-size,
  ** round down to the nearest page. Except, any file larger than 0
  ** bytes in size is considered to contain at least one page.
  */
................................................................................
    pPager->mxPgno = (Pgno)nPage;
  }

  *pnPage = nPage;
  return SQLITE_OK;
}

#ifndef SQLITE_OMIT_WAL
/*
** Check if the *-wal file that corresponds to the database opened by pPager
** exists if the database is not empy, or verify that the *-wal file does
** not exist (by deleting it) if the database file is empty.
**
** If the database is not empty and the *-wal file exists, open the pager
** in WAL mode.  If the database is empty or if no *-wal file exists and
................................................................................
      }
    }

    /* If there is a WAL file in the file-system, open this database in WAL
    ** mode. Otherwise, the following function call is a no-op.
    */
    rc = pagerOpenWalIfPresent(pPager);
#ifndef SQLITE_OMIT_WAL
    assert( pPager->pWal==0 || rc==SQLITE_OK );
#endif
  }

  if( pagerUseWal(pPager) ){
    assert( rc==SQLITE_OK );
    rc = pagerBeginReadTransaction(pPager);
  }

Changes to test/pager1.test.

1915
1916
1917
1918
1919
1920
1921

1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948

1949
1950
1951
1952
1953
1954

1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976

1977
1978
1979
1980
1981
1982
1983
....
2250
2251
2252
2253
2254
2255
2256

2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274

2275
2276
2277
2278
2279
2280
2281
do_test pager1-20.2.2 {
  execsql {
    BEGIN EXCLUSIVE;
    COMMIT;
  }
} {}


do_test pager1-20.3.1 {
  faultsim_delete_and_reopen
  db func a_string a_string
  execsql {
    PRAGMA cache_size = 10;
    PRAGMA journal_mode = wal;
    BEGIN;
      CREATE TABLE t1(x);
      CREATE TABLE t2(y);
      INSERT INTO t1 VALUES(a_string(800));
      INSERT INTO t1 SELECT a_string(800) FROM t1;         /*   2 */
      INSERT INTO t1 SELECT a_string(800) FROM t1;         /*   4 */
      INSERT INTO t1 SELECT a_string(800) FROM t1;         /*   8 */
      INSERT INTO t1 SELECT a_string(800) FROM t1;         /*  16 */
      INSERT INTO t1 SELECT a_string(800) FROM t1;         /*  32 */
    COMMIT;
  }
} {wal}
do_test pager1-20.3.2 {
  execsql {
    BEGIN;
    INSERT INTO t2 VALUES('xxxx');
  }
  recursive_select 32 t1
  execsql COMMIT
} {}


#-------------------------------------------------------------------------
# Test that a WAL database may not be opened if:
#
#   pager1-21.1.*: The VFS has an iVersion less than 2, or
#   pager1-21.2.*: The VFS does not provide xShmXXX() methods.
#

do_test pager1-21.0 {
  faultsim_delete_and_reopen
  execsql {
    PRAGMA journal_mode = WAL;
    CREATE TABLE ko(c DEFAULT 'abc', b DEFAULT 'def');
    INSERT INTO ko DEFAULT VALUES;
  }
} {wal}
do_test pager1-21.1 {
  testvfs tv -noshm 1
  sqlite3 db2 test.db -vfs tv
  catchsql { SELECT * FROM ko } db2
} {1 {unable to open database file}}
db2 close
tv delete
do_test pager1-21.2 {
  testvfs tv -iversion 1
  sqlite3 db2 test.db -vfs tv
  catchsql { SELECT * FROM ko } db2
} {1 {unable to open database file}}
db2 close
tv delete


#-------------------------------------------------------------------------
# Test that a "PRAGMA wal_checkpoint":
#
#   pager1-22.1.*: is a no-op on a non-WAL db, and
#   pager1-22.2.*: does not cause xSync calls with a synchronous=off db.
#
................................................................................

#-------------------------------------------------------------------------
# Test that attempting to open a write-transaction with 
# locking_mode=exclusive in WAL mode fails if there are other clients on 
# the same database.
#
catch { db close }

do_multiclient_test tn {
  do_test pager1-28.$tn.1 {
    sql1 { 
      PRAGMA journal_mode = WAL;
      CREATE TABLE t1(a, b);
      INSERT INTO t1 VALUES('a', 'b');
    }
  } {wal}
  do_test pager1-28.$tn.2 { sql2 { SELECT * FROM t1 } } {a b}

  do_test pager1-28.$tn.3 { sql1 { PRAGMA locking_mode=exclusive } } {exclusive}
  do_test pager1-28.$tn.4 { 
    csql1 { BEGIN; INSERT INTO t1 VALUES('c', 'd'); }
  } {1 {database is locked}}
  code2 { db2 close ; sqlite3 db2 test.db }
  do_test pager1-28.$tn.4 { 
    sql1 { INSERT INTO t1 VALUES('c', 'd'); COMMIT }
  } {}

}

#-------------------------------------------------------------------------
# Normally, when changing from journal_mode=PERSIST to DELETE the pager
# attempts to delete the journal file. However, if it cannot obtain a
# RESERVED lock on the database file, this step is skipped.
#







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






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







 







>
|
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
>







1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
....
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
do_test pager1-20.2.2 {
  execsql {
    BEGIN EXCLUSIVE;
    COMMIT;
  }
} {}

ifcapable wal {
  do_test pager1-20.3.1 {
    faultsim_delete_and_reopen
    db func a_string a_string
    execsql {
      PRAGMA cache_size = 10;
      PRAGMA journal_mode = wal;
      BEGIN;
        CREATE TABLE t1(x);
        CREATE TABLE t2(y);
        INSERT INTO t1 VALUES(a_string(800));
        INSERT INTO t1 SELECT a_string(800) FROM t1;         /*   2 */
        INSERT INTO t1 SELECT a_string(800) FROM t1;         /*   4 */
        INSERT INTO t1 SELECT a_string(800) FROM t1;         /*   8 */
        INSERT INTO t1 SELECT a_string(800) FROM t1;         /*  16 */
        INSERT INTO t1 SELECT a_string(800) FROM t1;         /*  32 */
      COMMIT;
    }
  } {wal}
  do_test pager1-20.3.2 {
    execsql {
      BEGIN;
      INSERT INTO t2 VALUES('xxxx');
    }
    recursive_select 32 t1
    execsql COMMIT
  } {}
}

#-------------------------------------------------------------------------
# Test that a WAL database may not be opened if:
#
#   pager1-21.1.*: The VFS has an iVersion less than 2, or
#   pager1-21.2.*: The VFS does not provide xShmXXX() methods.
#
ifcapable wal {
  do_test pager1-21.0 {
    faultsim_delete_and_reopen
    execsql {
      PRAGMA journal_mode = WAL;
      CREATE TABLE ko(c DEFAULT 'abc', b DEFAULT 'def');
      INSERT INTO ko DEFAULT VALUES;
    }
  } {wal}
  do_test pager1-21.1 {
    testvfs tv -noshm 1
    sqlite3 db2 test.db -vfs tv
    catchsql { SELECT * FROM ko } db2
  } {1 {unable to open database file}}
  db2 close
  tv delete
  do_test pager1-21.2 {
    testvfs tv -iversion 1
    sqlite3 db2 test.db -vfs tv
    catchsql { SELECT * FROM ko } db2
  } {1 {unable to open database file}}
  db2 close
  tv delete
}

#-------------------------------------------------------------------------
# Test that a "PRAGMA wal_checkpoint":
#
#   pager1-22.1.*: is a no-op on a non-WAL db, and
#   pager1-22.2.*: does not cause xSync calls with a synchronous=off db.
#
................................................................................

#-------------------------------------------------------------------------
# Test that attempting to open a write-transaction with 
# locking_mode=exclusive in WAL mode fails if there are other clients on 
# the same database.
#
catch { db close }
ifcapable wal {
  do_multiclient_test tn {
    do_test pager1-28.$tn.1 {
      sql1 { 
        PRAGMA journal_mode = WAL;
        CREATE TABLE t1(a, b);
        INSERT INTO t1 VALUES('a', 'b');
      }
    } {wal}
    do_test pager1-28.$tn.2 { sql2 { SELECT * FROM t1 } } {a b}

    do_test pager1-28.$tn.3 { sql1 { PRAGMA locking_mode=exclusive } } {exclusive}
    do_test pager1-28.$tn.4 { 
      csql1 { BEGIN; INSERT INTO t1 VALUES('c', 'd'); }
    } {1 {database is locked}}
    code2 { db2 close ; sqlite3 db2 test.db }
    do_test pager1-28.$tn.4 { 
      sql1 { INSERT INTO t1 VALUES('c', 'd'); COMMIT }
    } {}
  }
}

#-------------------------------------------------------------------------
# Normally, when changing from journal_mode=PERSIST to DELETE the pager
# attempts to delete the journal file. However, if it cannot obtain a
# RESERVED lock on the database file, this step is skipped.
#

Changes to test/stat.test.

26
27
28
29
30
31
32


33
34
35
36
37

38
39
40
41
42
43
44
db func a_string a_string

register_dbstat_vtab db
do_execsql_test stat-0.0 {
  CREATE VIRTUAL TABLE temp.stat USING dbstat;
  SELECT * FROM stat;
} {}


do_execsql_test stat-0.1 {
  PRAGMA journal_mode = WAL;
  PRAGMA journal_mode = delete;
  SELECT * FROM stat;
} {wal delete sqlite_master / 1 leaf 0 0 916 0}


do_test stat-1.0 {
  execsql {
    CREATE TABLE t1(a, b);
    CREATE INDEX i1 ON t1(b);
    INSERT INTO t1(rowid, a, b) VALUES(2, 2, 3);
    INSERT INTO t1(rowid, a, b) VALUES(3, 4, 5);







>
>
|
|
|
|
|
>







26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
db func a_string a_string

register_dbstat_vtab db
do_execsql_test stat-0.0 {
  CREATE VIRTUAL TABLE temp.stat USING dbstat;
  SELECT * FROM stat;
} {}

ifcapable wal {
  do_execsql_test stat-0.1 {
    PRAGMA journal_mode = WAL;
    PRAGMA journal_mode = delete;
    SELECT * FROM stat;
  } {wal delete sqlite_master / 1 leaf 0 0 916 0}
}

do_test stat-1.0 {
  execsql {
    CREATE TABLE t1(a, b);
    CREATE INDEX i1 ON t1(b);
    INSERT INTO t1(rowid, a, b) VALUES(2, 2, 3);
    INSERT INTO t1(rowid, a, b) VALUES(3, 4, 5);

Changes to test/walshared.test.

11
12
13
14
15
16
17



18
19
20
21
22
23
24
# This file implements regression tests for SQLite library.  The
# focus of this file is testing the operation of the library in
# "PRAGMA journal_mode=WAL" mode with shared-cache turned on.
#

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



db close
set ::enable_shared_cache [sqlite3_enable_shared_cache 1]

sqlite3 db  test.db
sqlite3 db2 test.db

do_test walshared-1.0 {







>
>
>







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# This file implements regression tests for SQLite library.  The
# focus of this file is testing the operation of the library in
# "PRAGMA journal_mode=WAL" mode with shared-cache turned on.
#

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

ifcapable !wal {finish_test ; return }

db close
set ::enable_shared_cache [sqlite3_enable_shared_cache 1]

sqlite3 db  test.db
sqlite3 db2 test.db

do_test walshared-1.0 {