1ea2844f1Sdrh# 2017-07-30 2ea2844f1Sdrh# 3ea2844f1Sdrh# The author disclaims copyright to this source code. In place of 4ea2844f1Sdrh# a legal notice, here is a blessing: 5ea2844f1Sdrh# 6ea2844f1Sdrh# May you do good and not evil. 7ea2844f1Sdrh# May you find forgiveness for yourself and forgive others. 8ea2844f1Sdrh# May you share freely, never taking more than you give. 9ea2844f1Sdrh# 10ea2844f1Sdrh#*********************************************************************** 11ea2844f1Sdrh# 12ea2844f1Sdrh# This file implements tests to show that certain CREATE TABLE statements 13ea2844f1Sdrh# generate identical database files. For example, changes in identifier 14ea2844f1Sdrh# names, white-space, and formatting of the CREATE TABLE statement should 15ea2844f1Sdrh# produce identical table content. 16ea2844f1Sdrh# 17ea2844f1Sdrh 18ea2844f1Sdrhset testdir [file dirname $argv0] 19ea2844f1Sdrhsource $testdir/tester.tcl 20ea2844f1Sdrhset ::testprefix schema6 21*efeaec36Sdrhdo_not_use_codec 22ea2844f1Sdrh 23ea2844f1Sdrh# Command: check_same_database_content TESTNAME SQL1 SQL2 SQL3 ... 24ea2844f1Sdrh# 25ea2844f1Sdrh# This command creates fresh databases using SQL1 and subsequent arguments 26ea2844f1Sdrh# and checks to make sure the content of all database files is byte-for-byte 27ea2844f1Sdrh# identical. Page 1 of the database files is allowed to be different, since 28ea2844f1Sdrh# page 1 contains the sqlite_master table which is expected to vary. 29ea2844f1Sdrh# 30ea2844f1Sdrhproc check_same_database_content {basename args} { 31ea2844f1Sdrh set i 0 32ea2844f1Sdrh set hash {} 33ea2844f1Sdrh foreach sql $args { 34ab2eca09Sdrh catch {db close} 35ea2844f1Sdrh forcedelete test.db 36ea2844f1Sdrh sqlite3 db test.db 37ea2844f1Sdrh db eval $sql 38ea2844f1Sdrh set pgsz [db one {PRAGMA page_size}] 39ea2844f1Sdrh db close 40ea2844f1Sdrh set sz [file size test.db] 41ea2844f1Sdrh set thishash [md5file test.db $pgsz [expr {$sz-$pgsz}]] 42ea2844f1Sdrh if {$i==0} { 43ea2844f1Sdrh set hash $thishash 44ea2844f1Sdrh } else { 45ea2844f1Sdrh do_test $basename-$i "set x $thishash" $hash 46ea2844f1Sdrh } 47ea2844f1Sdrh incr i 48ea2844f1Sdrh } 49ea2844f1Sdrh} 50ea2844f1Sdrh 51ea2844f1Sdrh# Command: check_different_database_content TESTNAME SQL1 SQL2 SQL3 ... 52ea2844f1Sdrh# 53ea2844f1Sdrh# This command creates fresh databases using SQL1 and subsequent arguments 54ea2844f1Sdrh# and checks to make sure the content of all database files is different 55ea2844f1Sdrh# in ways other than on page 1. 56ea2844f1Sdrh# 57ea2844f1Sdrhproc check_different_database_content {basename args} { 58ea2844f1Sdrh set i 0 59ea2844f1Sdrh set hashes {} 60ea2844f1Sdrh foreach sql $args { 61ea2844f1Sdrh forcedelete test.db 62ea2844f1Sdrh sqlite3 db test.db 63ea2844f1Sdrh db eval $sql 64ea2844f1Sdrh set pgsz [db one {PRAGMA page_size}] 65ea2844f1Sdrh db close 66ea2844f1Sdrh set sz [file size test.db] 67ea2844f1Sdrh set thishash [md5file test.db $pgsz [expr {$sz-$pgsz}]] 68ea2844f1Sdrh set j [lsearch $hashes $thishash] 69ea2844f1Sdrh if {$j>=0} { 70ea2844f1Sdrh do_test $basename-$i "set x {$i is the same as $j}" "All are different" 71ea2844f1Sdrh } else { 72ea2844f1Sdrh do_test $basename-$i "set x {All are different}" "All are different" 73ea2844f1Sdrh } 74ea2844f1Sdrh lappend hashes $thishash 75ea2844f1Sdrh incr i 76ea2844f1Sdrh } 77ea2844f1Sdrh} 78ea2844f1Sdrh 79ea2844f1Sdrhcheck_same_database_content 100 { 80ea2844f1Sdrh CREATE TABLE t1(a INTEGER PRIMARY KEY, b UNIQUE); 81ea2844f1Sdrh INSERT INTO t1(a,b) VALUES(123,'Four score and seven years ago...'); 82ea2844f1Sdrh} { 83ea2844f1Sdrh CREATE TABLE t1(xyz INTEGER, abc, PRIMARY KEY(xyz), UNIQUE(abc)); 84ea2844f1Sdrh INSERT INTO t1(xyz,abc) VALUES(123,'Four score and seven years ago...'); 85ea2844f1Sdrh} { 86ea2844f1Sdrh CREATE TABLE t1(xyz INTEGER, abc, UNIQUE(abc), PRIMARY KEY(xyz)); 87ea2844f1Sdrh INSERT INTO t1(xyz,abc) VALUES(123,'Four score and seven years ago...'); 88ea2844f1Sdrh} { 89ea2844f1Sdrh CREATE TABLE t1(a INTEGER PRIMARY KEY ASC, b UNIQUE); 90ea2844f1Sdrh INSERT INTO t1(a,b) VALUES(123,'Four score and seven years ago...'); 91ea2844f1Sdrh} { 92ea2844f1Sdrh CREATE TABLE t1(a INTEGER PRIMARY KEY, b); 93ea2844f1Sdrh CREATE UNIQUE INDEX t1b ON t1(b); 94ea2844f1Sdrh INSERT INTO t1(a,b) VALUES(123,'Four score and seven years ago...'); 95ea2844f1Sdrh} { 96ea2844f1Sdrh CREATE TABLE t1(a INTEGER PRIMARY KEY, b); 97ea2844f1Sdrh INSERT INTO t1(a,b) VALUES(123,'Four score and seven years ago...'); 98ea2844f1Sdrh CREATE UNIQUE INDEX t1b ON t1(b); 99ea2844f1Sdrh} 100ea2844f1Sdrh 101ea2844f1Sdrhcheck_same_database_content 110 { 102ea2844f1Sdrh CREATE TABLE t1(a INTEGER PRIMARY KEY UNIQUE, b UNIQUE); 103ea2844f1Sdrh INSERT INTO t1(a,b) VALUES(123,'Four score and seven years ago...'); 104ea2844f1Sdrh} { 105ea2844f1Sdrh CREATE TABLE t1(a INTEGER UNIQUE PRIMARY KEY, b UNIQUE); 106ea2844f1Sdrh INSERT INTO t1(a,b) VALUES(123,'Four score and seven years ago...'); 107ea2844f1Sdrh} { 108ea2844f1Sdrh CREATE TABLE t1(a INTEGER UNIQUE PRIMARY KEY, b UNIQUE, UNIQUE(a)); 109ea2844f1Sdrh INSERT INTO t1(a,b) VALUES(123,'Four score and seven years ago...'); 110ea2844f1Sdrh} { 111ea2844f1Sdrh CREATE TABLE t1(a INTEGER UNIQUE PRIMARY KEY, b); 112ea2844f1Sdrh CREATE UNIQUE INDEX t1b ON t1(b); 113ea2844f1Sdrh INSERT INTO t1(a,b) VALUES(123,'Four score and seven years ago...'); 114ea2844f1Sdrh} { 115ea2844f1Sdrh CREATE TABLE t1(a INTEGER UNIQUE PRIMARY KEY, b); 116ea2844f1Sdrh INSERT INTO t1(a,b) VALUES(123,'Four score and seven years ago...'); 117ea2844f1Sdrh CREATE UNIQUE INDEX t1b ON t1(b); 118ea2844f1Sdrh} 119ea2844f1Sdrh 120ea2844f1Sdrhcheck_same_database_content 120 { 121ea2844f1Sdrh CREATE TABLE t1(a INTEGER PRIMARY KEY, b UNIQUE) WITHOUT ROWID; 122ea2844f1Sdrh INSERT INTO t1(a,b) VALUES(123,'Four score and seven years ago...'); 123ea2844f1Sdrh} { 124ea2844f1Sdrh CREATE TABLE t1(xyz INTEGER, abc, PRIMARY KEY(xyz), UNIQUE(abc))WITHOUT ROWID; 125ea2844f1Sdrh INSERT INTO t1(xyz,abc) VALUES(123,'Four score and seven years ago...'); 126ea2844f1Sdrh} { 127ea2844f1Sdrh CREATE TABLE t1(xyz INTEGER, abc, UNIQUE(abc), PRIMARY KEY(xyz))WITHOUT ROWID; 128ea2844f1Sdrh INSERT INTO t1(xyz,abc) VALUES(123,'Four score and seven years ago...'); 129ea2844f1Sdrh} { 130ea2844f1Sdrh CREATE TABLE t1(a INTEGER PRIMARY KEY ASC, b UNIQUE) WITHOUT ROWID; 131ea2844f1Sdrh INSERT INTO t1(a,b) VALUES(123,'Four score and seven years ago...'); 132ea2844f1Sdrh} { 133ea2844f1Sdrh CREATE TABLE t1(a INTEGER PRIMARY KEY UNIQUE, b UNIQUE) WITHOUT ROWID; 134ea2844f1Sdrh INSERT INTO t1(a,b) VALUES(123,'Four score and seven years ago...'); 135ea2844f1Sdrh} { 136ea2844f1Sdrh CREATE TABLE t1(a INTEGER UNIQUE PRIMARY KEY, b UNIQUE) WITHOUT ROWID; 137ea2844f1Sdrh INSERT INTO t1(a,b) VALUES(123,'Four score and seven years ago...'); 138ea2844f1Sdrh} { 139ea2844f1Sdrh CREATE TABLE t1(a INTEGER UNIQUE PRIMARY KEY, b UNIQUE, UNIQUE(a)) 140ea2844f1Sdrh WITHOUT ROWID; 141ea2844f1Sdrh INSERT INTO t1(a,b) VALUES(123,'Four score and seven years ago...'); 142ea2844f1Sdrh} { 143ea2844f1Sdrh CREATE TABLE t1(a INTEGER PRIMARY KEY, b) WITHOUT ROWID; 144ea2844f1Sdrh CREATE UNIQUE INDEX t1b ON t1(b); 145ea2844f1Sdrh INSERT INTO t1(a,b) VALUES(123,'Four score and seven years ago...'); 146ea2844f1Sdrh} { 147ea2844f1Sdrh CREATE TABLE t1(a INTEGER PRIMARY KEY, b) WITHOUT ROWID; 148ea2844f1Sdrh INSERT INTO t1(a,b) VALUES(123,'Four score and seven years ago...'); 149ea2844f1Sdrh CREATE UNIQUE INDEX t1b ON t1(b); 150ea2844f1Sdrh} 151ea2844f1Sdrh 152ea2844f1Sdrhcheck_different_database_content 130 { 153ea2844f1Sdrh CREATE TABLE t1(a INTEGER PRIMARY KEY, b UNIQUE); 154ea2844f1Sdrh INSERT INTO t1(a,b) VALUES(123,'Four score and seven years ago...'); 155ea2844f1Sdrh} { 156ea2844f1Sdrh CREATE TABLE t1(a INTEGER PRIMARY KEY UNIQUE, b UNIQUE); 157ea2844f1Sdrh INSERT INTO t1(a,b) VALUES(123,'Four score and seven years ago...'); 158ea2844f1Sdrh} { 159ea2844f1Sdrh CREATE TABLE t1(a INTEGER PRIMARY KEY, b UNIQUE) WITHOUT ROWID; 160ea2844f1Sdrh INSERT INTO t1(a,b) VALUES(123,'Four score and seven years ago...'); 161ea2844f1Sdrh} 162ea2844f1Sdrh 163ea2844f1Sdrh 164ea2844f1Sdrhfinish_test 165