xref: /sqlite-3.40.0/test/filefmt.test (revision ff4fa772)
115926590Sdrh# 2007 April 6
215926590Sdrh#
315926590Sdrh# The author disclaims copyright to this source code.  In place of
415926590Sdrh# a legal notice, here is a blessing:
515926590Sdrh#
615926590Sdrh#    May you do good and not evil.
715926590Sdrh#    May you find forgiveness for yourself and forgive others.
815926590Sdrh#    May you share freely, never taking more than you give.
915926590Sdrh#
1015926590Sdrh#***********************************************************************
1115926590Sdrh# This file implements regression tests for SQLite library.
1215926590Sdrh#
1315926590Sdrh# This file implements tests to verify database file format.
1415926590Sdrh#
15ccf6d093Sdrh# $Id: filefmt.test,v 1.3 2009/06/18 11:34:43 drh Exp $
1615926590Sdrh
1715926590Sdrhset testdir [file dirname $argv0]
1815926590Sdrhsource $testdir/tester.tcl
1968928b6cSdan
2068928b6cSdan# Do not use a codec for tests in this file, as the database file is
2168928b6cSdan# manipulated directly using tcl scripts (using the [hexio_write] command).
2268928b6cSdan#
2368928b6cSdando_not_use_codec
2468928b6cSdan
2515926590Sdrhdb close
26fda06befSmistachkinforcedelete test.db test.db-journal
2715926590Sdrh
2815926590Sdrh# Database begins with valid 16-byte header string.
2915926590Sdrh#
3015926590Sdrhdo_test filefmt-1.1 {
3115926590Sdrh  sqlite3 db test.db
3215926590Sdrh  db eval {CREATE TABLE t1(x)}
3315926590Sdrh  db close
3415926590Sdrh  hexio_read test.db 0 16
3515926590Sdrh} {53514C69746520666F726D6174203300}
3615926590Sdrh
3715926590Sdrh# If the 16-byte header is changed, the file will not open
3815926590Sdrh#
3915926590Sdrhdo_test filefmt-1.2 {
4015926590Sdrh  hexio_write test.db 0 54
4115926590Sdrh  set x [catch {sqlite3 db test.db} err]
4215926590Sdrh  lappend x $err
4315926590Sdrh} {0 {}}
4415926590Sdrhdo_test filefmt-1.3 {
4515926590Sdrh  catchsql {
4615926590Sdrh    SELECT count(*) FROM sqlite_master
4715926590Sdrh  }
48*ff4fa772Sdrh} {1 {file is not a database}}
4915926590Sdrhdo_test filefmt-1.4 {
5015926590Sdrh  db close
5115926590Sdrh  hexio_write test.db 0 53
5215926590Sdrh  sqlite3 db test.db
5315926590Sdrh  catchsql {
5415926590Sdrh    SELECT count(*) FROM sqlite_master
5515926590Sdrh  }
5615926590Sdrh} {0 1}
5715926590Sdrh
5815926590Sdrh# The page-size is stored at offset 16
5915926590Sdrh#
6015926590Sdrhifcapable pager_pragmas {
6115926590Sdrh  foreach pagesize {512 1024 2048 4096 8192 16384 32768} {
621e9daa6aSdrh     if {[info exists SQLITE_MAX_PAGE_SIZE]
631e9daa6aSdrh          && $pagesize>$SQLITE_MAX_PAGE_SIZE} continue
6415926590Sdrh     do_test filefmt-1.5.$pagesize.1 {
6515926590Sdrh       db close
66fda06befSmistachkin       forcedelete test.db
6715926590Sdrh       sqlite3 db test.db
681e9daa6aSdrh       db eval "PRAGMA auto_vacuum=OFF"
6915926590Sdrh       db eval "PRAGMA page_size=$pagesize"
7015926590Sdrh       db eval {CREATE TABLE t1(x)}
7115926590Sdrh       file size test.db
7215926590Sdrh     } [expr $pagesize*2]
7315926590Sdrh     do_test filefmt-1.5.$pagesize.2 {
7415926590Sdrh       hexio_get_int [hexio_read test.db 16 2]
7515926590Sdrh     } $pagesize
7615926590Sdrh  }
7715926590Sdrh}
7815926590Sdrh
7915926590Sdrh# The page-size must be a power of 2
8015926590Sdrh#
8115926590Sdrhdo_test filefmt-1.6 {
8215926590Sdrh  db close
8315926590Sdrh  hexio_write test.db 16 [hexio_render_int16 1025]
8415926590Sdrh  sqlite3 db test.db
8515926590Sdrh  catchsql {
8615926590Sdrh     SELECT count(*) FROM sqlite_master
8715926590Sdrh  }
88*ff4fa772Sdrh} {1 {file is not a database}}
8915926590Sdrh
9015926590Sdrh
9115926590Sdrh# The page-size must be at least 512 bytes
9215926590Sdrh#
9315926590Sdrhdo_test filefmt-1.7 {
9415926590Sdrh  db close
9515926590Sdrh  hexio_write test.db 16 [hexio_render_int16 256]
9615926590Sdrh  sqlite3 db test.db
9715926590Sdrh  catchsql {
9815926590Sdrh     SELECT count(*) FROM sqlite_master
9915926590Sdrh  }
100*ff4fa772Sdrh} {1 {file is not a database}}
10115926590Sdrh
10215926590Sdrh# Usable space per page (page-size minus unused space per page)
103ccf6d093Sdrh# must be at least 480 bytes
10415926590Sdrh#
10515926590Sdrhifcapable pager_pragmas {
10615926590Sdrh  do_test filefmt-1.8 {
10715926590Sdrh    db close
108fda06befSmistachkin    forcedelete test.db
10915926590Sdrh    sqlite3 db test.db
11015926590Sdrh    db eval {PRAGMA page_size=512; CREATE TABLE t1(x)}
11115926590Sdrh    db close
112ccf6d093Sdrh    hexio_write test.db 20 21
11315926590Sdrh    sqlite3 db test.db
11415926590Sdrh    catchsql {
11515926590Sdrh       SELECT count(*) FROM sqlite_master
11615926590Sdrh    }
117*ff4fa772Sdrh  } {1 {file is not a database}}
11815926590Sdrh}
11915926590Sdrh
12059257dc6Sdan#-------------------------------------------------------------------------
12159257dc6Sdan# The following block of tests - filefmt-2.* - test that versions 3.7.0
12259257dc6Sdan# and later can read and write databases that have been modified or created
12359257dc6Sdan# by 3.6.23.1 and earlier. The difference difference is that 3.7.0 stores
12459257dc6Sdan# the size of the database in the database file header, whereas 3.6.23.1
12559257dc6Sdan# always derives this from the size of the file.
12659257dc6Sdan#
12759257dc6Sdandb close
128fda06befSmistachkinforcedelete test.db
12959257dc6Sdan
13059257dc6Sdanset a_string_counter 1
13159257dc6Sdanproc a_string {n} {
13259257dc6Sdan  incr ::a_string_counter
13359257dc6Sdan  string range [string repeat "${::a_string_counter}." $n] 1 $n
13459257dc6Sdan}
13559257dc6Sdansqlite3 db test.db
13659257dc6Sdandb func a_string a_string
13759257dc6Sdan
13859257dc6Sdando_execsql_test filefmt-2.1.1 {
13959257dc6Sdan  PRAGMA page_size = 1024;
14059257dc6Sdan  PRAGMA auto_vacuum = 0;
14159257dc6Sdan  CREATE TABLE t1(a);
14259257dc6Sdan  CREATE INDEX i1 ON t1(a);
14359257dc6Sdan  INSERT INTO t1 VALUES(a_string(3000));
14459257dc6Sdan  CREATE TABLE t2(a);
14559257dc6Sdan  INSERT INTO t2 VALUES(1);
14659257dc6Sdan} {}
14782f52540Sdrhif {![nonzero_reserved_bytes]} {
14859257dc6Sdan  do_test filefmt-2.1.2 {
14959257dc6Sdan    hexio_read test.db 28 4
15059257dc6Sdan  } {00000009}
15182f52540Sdrh}
15259257dc6Sdan
15359257dc6Sdando_test filefmt-2.1.3 {
15459257dc6Sdan  sql36231 { INSERT INTO t1 VALUES(a_string(3000)) }
15559257dc6Sdan} {}
15659257dc6Sdan
15759257dc6Sdando_execsql_test filefmt-2.1.4 { INSERT INTO t2 VALUES(2) } {}
15859257dc6Sdanintegrity_check filefmt-2.1.5
15959257dc6Sdando_test         filefmt-2.1.6 { hexio_read test.db 28 4 } {00000010}
16059257dc6Sdan
16159257dc6Sdandb close
162fda06befSmistachkinforcedelete test.db
16359257dc6Sdansqlite3 db test.db
16459257dc6Sdandb func a_string a_string
16559257dc6Sdan
16659257dc6Sdando_execsql_test filefmt-2.2.1 {
16759257dc6Sdan  PRAGMA page_size = 1024;
16859257dc6Sdan  PRAGMA auto_vacuum = 0;
16959257dc6Sdan  CREATE TABLE t1(a);
17059257dc6Sdan  CREATE INDEX i1 ON t1(a);
17159257dc6Sdan  INSERT INTO t1 VALUES(a_string(3000));
17259257dc6Sdan  CREATE TABLE t2(a);
17359257dc6Sdan  INSERT INTO t2 VALUES(1);
17459257dc6Sdan} {}
17582f52540Sdrhif {![nonzero_reserved_bytes]} {
17659257dc6Sdan  do_test filefmt-2.2.2 {
17759257dc6Sdan    hexio_read test.db 28 4
17859257dc6Sdan  } {00000009}
17982f52540Sdrh}
18059257dc6Sdan
18159257dc6Sdando_test filefmt-2.2.3 {
18259257dc6Sdan  sql36231 { INSERT INTO t1 VALUES(a_string(3000)) }
18359257dc6Sdan} {}
18459257dc6Sdan
18559257dc6Sdando_execsql_test filefmt-2.2.4 {
18659257dc6Sdan  PRAGMA integrity_check;
18759257dc6Sdan  BEGIN;
18859257dc6Sdan    INSERT INTO t2 VALUES(2);
18959257dc6Sdan    SAVEPOINT a;
19059257dc6Sdan      INSERT INTO t2 VALUES(3);
19159257dc6Sdan    ROLLBACK TO a;
19259257dc6Sdan} {ok}
19359257dc6Sdan
19459257dc6Sdanintegrity_check filefmt-2.2.5
19559257dc6Sdando_execsql_test filefmt-2.2.6 { COMMIT } {}
19659257dc6Sdandb close
19759257dc6Sdansqlite3 db test.db
19859257dc6Sdanintegrity_check filefmt-2.2.7
19915926590Sdrh
200ecac670aSdan#--------------------------------------------------------------------------
201ecac670aSdan# Check that ticket 89b8c9ac54 is fixed. Before the fix, the SELECT
202ecac670aSdan# statement would return SQLITE_CORRUPT. The database file was not actually
203ecac670aSdan# corrupted, but SQLite was reporting that it was.
204ecac670aSdan#
205ecac670aSdandb close
206ecac670aSdanforcedelete test.db
207ecac670aSdansqlite3 db test.db
208ecac670aSdando_execsql_test filefmt-3.1 {
209ecac670aSdan  PRAGMA auto_vacuum = 1;
210ecac670aSdan  CREATE TABLE t1(a, b);
211ecac670aSdan} {}
212ecac670aSdando_test filefmt-3.2 {
213ecac670aSdan  sql36231 { DROP TABLE t1 }
214ecac670aSdan} {}
215ecac670aSdando_execsql_test filefmt-3.3 {
216ecac670aSdan  SELECT * FROM sqlite_master;
217ecac670aSdan  PRAGMA integrity_check;
218ecac670aSdan} {ok}
219ecac670aSdan
2205cc3bea4Sdanreset_db
2215cc3bea4Sdando_execsql_test filefmt-4.1 {
2225cc3bea4Sdan  PRAGMA auto_vacuum = 1;
2235cc3bea4Sdan  CREATE TABLE t1(x, y);
2245cc3bea4Sdan  CREATE TABLE t2(x, y);
2255cc3bea4Sdan
2265cc3bea4Sdan  INSERT INTO t1 VALUES(randomblob(100), randomblob(100));
2275cc3bea4Sdan  INSERT INTO t1 VALUES(randomblob(100), randomblob(100));
2285cc3bea4Sdan  INSERT INTO t1 VALUES(randomblob(100), randomblob(100));
2295cc3bea4Sdan  INSERT INTO t1 VALUES(randomblob(100), randomblob(100));
2305cc3bea4Sdan  INSERT INTO t1 VALUES(randomblob(100), randomblob(100));
2315cc3bea4Sdan  INSERT INTO t1 VALUES(randomblob(100), randomblob(100));
2325cc3bea4Sdan
2335cc3bea4Sdan  INSERT INTO t2 SELECT randomblob(100), randomblob(100) FROM t1;
2345cc3bea4Sdan  INSERT INTO t2 SELECT randomblob(100), randomblob(100) FROM t1;
2355cc3bea4Sdan  INSERT INTO t2 SELECT randomblob(100), randomblob(100) FROM t1;
2365cc3bea4Sdan  INSERT INTO t2 SELECT randomblob(100), randomblob(100) FROM t1;
2375cc3bea4Sdan}
2385cc3bea4Sdan
2395cc3bea4Sdando_test filefmt-4.2 {
2405cc3bea4Sdan  sql36231 { INSERT INTO t2 SELECT * FROM t1 }
2415cc3bea4Sdan} {}
2425cc3bea4Sdan
2435cc3bea4Sdando_test filefmt-4.3 {
2445cc3bea4Sdan  forcedelete bak.db
2455cc3bea4Sdan  db backup bak.db
2465cc3bea4Sdan} {}
2475cc3bea4Sdan
2485cc3bea4Sdando_test filefmt-4.4 {
2495cc3bea4Sdan  sqlite3 db2 bak.db
2505cc3bea4Sdan  db2 eval { PRAGMA integrity_check }
2515cc3bea4Sdan} {ok}
2525cc3bea4Sdandb2 close
2535cc3bea4Sdan
25415926590Sdrhfinish_test
255