sqlite/test/pragma.test
drh 6c62608fc6 The SQLITE_OMIT_UTF16 macro now removes lots of code and all tests still pass. (CVS 2100)
FossilOrigin-Name: 98c7a55478f7c465b219edc1a33eee222586fd65
2004-11-14 21:56:29 +00:00

577 lines
12 KiB
Plaintext

# 2002 March 6
#
# 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 regression tests for SQLite library.
#
# This file implements tests for the PRAGMA command.
#
# $Id: pragma.test,v 1.24 2004/11/14 21:56:31 drh Exp $
set testdir [file dirname $argv0]
source $testdir/tester.tcl
# Test organization:
#
# pragma-1.*: Test cache_size, default_cache_size and synchronous on main db.
# pragma-2.*: Test synchronous on attached db.
# pragma-3.*: Test detection of table/index inconsistency by integrity_check.
# pragma-4.*: Test cache_size and default_cache_size on attached db.
# pragma-5.*: Test that pragma synchronous may not be used inside of a
# transaction.
#
# Delete the preexisting database to avoid the special setup
# that the "all.test" script does.
#
db close
file delete test.db
set DB [sqlite3 db test.db]
do_test pragma-1.1 {
execsql {
PRAGMA cache_size;
PRAGMA default_cache_size;
PRAGMA synchronous;
}
} {2000 2000 2}
do_test pragma-1.2 {
execsql {
PRAGMA cache_size=1234;
PRAGMA cache_size;
PRAGMA default_cache_size;
PRAGMA synchronous;
}
} {1234 2000 2}
do_test pragma-1.3 {
db close
sqlite3 db test.db
execsql {
PRAGMA cache_size;
PRAGMA default_cache_size;
PRAGMA synchronous;
}
} {2000 2000 2}
do_test pragma-1.4 {
execsql {
PRAGMA synchronous=OFF;
PRAGMA cache_size;
PRAGMA default_cache_size;
PRAGMA synchronous;
}
} {2000 2000 0}
do_test pragma-1.5 {
execsql {
PRAGMA cache_size=4321;
PRAGMA cache_size;
PRAGMA default_cache_size;
PRAGMA synchronous;
}
} {4321 2000 0}
do_test pragma-1.6 {
execsql {
PRAGMA synchronous=ON;
PRAGMA cache_size;
PRAGMA default_cache_size;
PRAGMA synchronous;
}
} {4321 2000 1}
do_test pragma-1.7 {
db close
sqlite3 db test.db
execsql {
PRAGMA cache_size;
PRAGMA default_cache_size;
PRAGMA synchronous;
}
} {2000 2000 2}
do_test pragma-1.8 {
execsql {
PRAGMA default_cache_size=123;
PRAGMA cache_size;
PRAGMA default_cache_size;
PRAGMA synchronous;
}
} {123 123 2}
do_test pragma-1.9 {
db close
set ::DB [sqlite3 db test.db]
execsql {
PRAGMA cache_size;
PRAGMA default_cache_size;
PRAGMA synchronous;
}
} {123 123 2}
do_test pragma-1.10 {
execsql {
PRAGMA synchronous=NORMAL;
PRAGMA cache_size;
PRAGMA default_cache_size;
PRAGMA synchronous;
}
} {123 123 1}
do_test pragma-1.11 {
execsql {
PRAGMA synchronous=FULL;
PRAGMA cache_size;
PRAGMA default_cache_size;
PRAGMA synchronous;
}
} {123 123 2}
do_test pragma-1.12 {
db close
set ::DB [sqlite3 db test.db]
execsql {
PRAGMA cache_size;
PRAGMA default_cache_size;
PRAGMA synchronous;
}
} {123 123 2}
# Make sure the pragma handler understands numeric values in addition
# to keywords like "off" and "full".
#
do_test pragma-1.13 {
execsql {
PRAGMA synchronous=0;
PRAGMA synchronous;
}
} {0}
do_test pragma-1.14 {
execsql {
PRAGMA synchronous=2;
PRAGMA synchronous;
}
} {2}
# Test turning "flag" pragmas on and off.
#
do_test pragma-1.15 {
execsql {
PRAGMA vdbe_listing=YES;
PRAGMA vdbe_listing;
}
} {1}
do_test pragma-1.16 {
execsql {
PRAGMA vdbe_listing=NO;
PRAGMA vdbe_listing;
}
} {0}
do_test pragma-1.17 {
execsql {
PRAGMA parser_trace=ON;
PRAGMA parser_trace=OFF;
}
} {}
do_test pragma-1.18 {
execsql {
PRAGMA bogus = -1234; -- Parsing of negative values
}
} {}
# Test modifying the safety_level of an attached database.
do_test pragma-2.1 {
file delete -force test2.db
file delete -force test2.db-journal
execsql {
ATTACH 'test2.db' AS aux;
}
} {}
do_test pragma-2.2 {
execsql {
pragma aux.synchronous;
}
} {2}
do_test pragma-2.3 {
execsql {
pragma aux.synchronous = OFF;
pragma aux.synchronous;
pragma synchronous;
}
} {0 2}
do_test pragma-2.4 {
execsql {
pragma aux.synchronous = ON;
pragma synchronous;
pragma aux.synchronous;
}
} {2 1}
# Construct a corrupted index and make sure the integrity_check
# pragma finds it.
#
# These tests won't work if the database is encrypted
#
do_test pragma-3.1 {
execsql {
BEGIN;
CREATE TABLE t2(a,b,c);
CREATE INDEX i2 ON t2(a);
INSERT INTO t2 VALUES(11,2,3);
INSERT INTO t2 VALUES(22,3,4);
COMMIT;
SELECT rowid, * from t2;
}
} {1 11 2 3 2 22 3 4}
if {![sqlite3 -has-codec] && $sqlite_options(integrityck)} {
do_test pragma-3.2 {
set rootpage [execsql {SELECT rootpage FROM sqlite_master WHERE name='i2'}]
set db [btree_open test.db 100 0]
btree_begin_transaction $db
set c [btree_cursor $db $rootpage 1]
btree_first $c
btree_delete $c
btree_commit $db
btree_close $db
execsql {PRAGMA integrity_check}
} {{rowid 1 missing from index i2} {wrong # of entries in index i2}}
}
do_test pragma-3.3 {
execsql {
DROP INDEX i2;
}
} {}
# Test modifying the cache_size of an attached database.
do_test pragma-4.1 {
execsql {
pragma aux.cache_size;
pragma aux.default_cache_size;
}
} {2000 2000}
do_test pragma-4.2 {
execsql {
pragma aux.cache_size = 50;
pragma aux.cache_size;
pragma aux.default_cache_size;
}
} {50 2000}
do_test pragma-4.3 {
execsql {
pragma aux.default_cache_size = 456;
pragma aux.cache_size;
pragma aux.default_cache_size;
}
} {456 456}
do_test pragma-4.4 {
execsql {
pragma cache_size;
pragma default_cache_size;
}
} {123 123}
do_test pragma-4.5 {
execsql {
DETACH aux;
ATTACH 'test3.db' AS aux;
pragma aux.cache_size;
pragma aux.default_cache_size;
}
} {2000 2000}
do_test pragma-4.6 {
execsql {
DETACH aux;
ATTACH 'test2.db' AS aux;
pragma aux.cache_size;
pragma aux.default_cache_size;
}
} {456 456}
# Test that modifying the sync-level in the middle of a transaction is
# disallowed.
do_test pragma-5.0 {
execsql {
pragma synchronous;
}
} {2}
do_test pragma-5.1 {
catchsql {
BEGIN;
pragma synchronous = OFF;
}
} {1 {Safety level may not be changed inside a transaction}}
do_test pragma-5.2 {
execsql {
pragma synchronous;
}
} {2}
catchsql {COMMIT;}
# Test schema-query pragmas
#
do_test pragma-6.1 {
set res {}
execsql {SELECT * FROM sqlite_temp_master}
foreach {idx name file} [execsql {pragma database_list}] {
lappend res $idx $name
}
set res
} {0 main 1 temp 2 aux}
do_test pragma-6.2 {
execsql {
pragma table_info(t2)
}
} {0 a numeric 0 {} 0 1 b numeric 0 {} 0 2 c numeric 0 {} 0}
ifcapable {foreignkey} {
do_test pragma-6.3 {
execsql {
CREATE TABLE t3(a int references t2(b), b UNIQUE);
pragma foreign_key_list(t3);
}
} {0 0 t2 a b}
do_test pragma-6.4 {
execsql {
pragma index_list(t3);
}
} {0 sqlite_autoindex_t3_1 1}
}
ifcapable {!foreignkey} {
execsql {CREATE TABLE t3(a,b UNIQUE)}
}
do_test pragma-6.5 {
execsql {
CREATE INDEX t3i1 ON t3(a,b);
pragma index_info(t3i1);
}
} {0 0 a 1 1 b}
# Miscellaneous tests
#
do_test pragma-7.1 {
# Make sure a pragma knows to read the schema if it needs to
db close
sqlite3 db test.db
execsql {
pragma index_list(t3);
}
} {0 t3i1 0 1 sqlite_autoindex_t3_1 1}
ifcapable {utf16} {
do_test pragma-7.2 {
db close
sqlite3 db test.db
catchsql {
pragma encoding=bogus;
}
} {1 {unsupported encoding: bogus}}
}
do_test pragma-7.3 {
db close
sqlite3 db test.db
execsql {
pragma lock_status;
}
} {main unlocked temp closed}
#----------------------------------------------------------------------
# Test cases pragma-8.* test the "PRAGMA schema_version" and "PRAGMA
# user_version" statements.
#
# pragma-8.1: PRAGMA schema_version
# pragma-8.2: PRAGMA user_version
#
# First check that we can set the schema version and then retrieve the
# same value.
do_test pragma-8.1.1 {
execsql {
PRAGMA schema_version = 105;
}
} {}
do_test pragma-8.1.2 {
execsql {
PRAGMA schema_version;
}
} 105
do_test pragma-8.1.3 {
execsql {
PRAGMA schema_version = 106;
}
} {}
do_test pragma-8.1.4 {
execsql {
PRAGMA schema_version;
}
} 106
# Check that creating a table modifies the schema-version (this is really
# to verify that the value being read is in fact the schema version).
do_test pragma-8.1.5 {
execsql {
CREATE TABLE t4(a, b, c);
INSERT INTO t4 VALUES(1, 2, 3);
SELECT * FROM t4;
}
} {1 2 3}
do_test pragma-8.1.6 {
execsql {
PRAGMA schema_version;
}
} 107
# Now open a second connection to the database. Ensure that changing the
# schema-version using the first connection forces the second connection
# to reload the schema. This has to be done using the C-API test functions,
# because the TCL API accounts for SCHEMA_ERROR and retries the query.
do_test pragma-8.1.7 {
set ::DB2 [sqlite3 db2 test.db]
execsql {
SELECT * FROM t4;
} db2
} {1 2 3}
do_test pragma-8.1.8 {
execsql {
PRAGMA schema_version = 108;
}
} {}
do_test pragma-8.1.9 {
set ::STMT [sqlite3_prepare $::DB2 "SELECT * FROM t4" -1 DUMMY]
sqlite3_step $::STMT
} SQLITE_ERROR
do_test pragma-8.1.10 {
sqlite3_finalize $::STMT
} SQLITE_SCHEMA
# Make sure the schema-version can be manipulated in an attached database.
file delete -force test2.db
file delete -force test2.db-journal
do_test pragma-8.1.11 {
execsql {
ATTACH 'test2.db' AS aux;
CREATE TABLE aux.t1(a, b, c);
PRAGMA aux.schema_version = 205;
}
} {}
do_test pragma-8.1.12 {
execsql {
PRAGMA aux.schema_version;
}
} 205
do_test pragma-8.1.13 {
execsql {
PRAGMA schema_version;
}
} 108
# And check that modifying the schema-version in an attached database
# forces the second connection to reload the schema.
do_test pragma-8.1.14 {
set ::DB2 [sqlite3 db2 test.db]
execsql {
ATTACH 'test2.db' AS aux;
SELECT * FROM aux.t1;
} db2
} {}
do_test pragma-8.1.15 {
execsql {
PRAGMA aux.schema_version = 206;
}
} {}
do_test pragma-8.1.16 {
set ::STMT [sqlite3_prepare $::DB2 "SELECT * FROM aux.t1" -1 DUMMY]
sqlite3_step $::STMT
} SQLITE_ERROR
do_test pragma-8.1.17 {
sqlite3_finalize $::STMT
} SQLITE_SCHEMA
do_test pragma-8.1.18 {
db2 close
} {}
# Now test that the user-version can be read and written (and that we aren't
# accidentally manipulating the schema-version instead).
do_test pragma-8.2.1 {
execsql {
PRAGMA user_version;
}
} {0}
do_test pragma-8.2.2 {
execsql {
PRAGMA user_version = 2;
}
} {}
do_test pragma-8.2.3 {
execsql {
PRAGMA user_version;
}
} {2}
do_test pragma-8.2.4 {
execsql {
PRAGMA schema_version;
}
} {108}
# Check that the user-version in the auxilary database can be manipulated (
# and that we aren't accidentally manipulating the same in the main db).
do_test pragma-8.2.5 {
execsql {
PRAGMA aux.user_version;
}
} {0}
do_test pragma-8.2.6 {
execsql {
PRAGMA aux.user_version = 3;
}
} {}
do_test pragma-8.2.7 {
execsql {
PRAGMA aux.user_version;
}
} {3}
do_test pragma-8.2.8 {
execsql {
PRAGMA main.user_version;
}
} {2}
# Now check that a ROLLBACK resets the user-version if it has been modified
# within a transaction.
do_test pragma-8.2.9 {
execsql {
BEGIN;
PRAGMA aux.user_version = 10;
PRAGMA user_version = 11;
}
} {}
do_test pragma-8.2.10 {
execsql {
PRAGMA aux.user_version;
}
} {10}
do_test pragma-8.2.11 {
execsql {
PRAGMA main.user_version;
}
} {11}
do_test pragma-8.2.12 {
execsql {
ROLLBACK;
PRAGMA aux.user_version;
}
} {3}
do_test pragma-8.2.13 {
execsql {
PRAGMA main.user_version;
}
} {2}
# Try a negative value for the user-version
do_test pragma-8.2.14 {
execsql {
PRAGMA user_version = -450;
}
} {}
do_test pragma-8.2.15 {
execsql {
PRAGMA user_version;
}
} {-450}
finish_test