upstream 3.7.9

This commit is contained in:
Stephen Lombardo
2011-12-26 14:52:17 -05:00
parent 12069ec913
commit ddb595fbc9
329 changed files with 14622 additions and 8785 deletions
+4 -4
View File
@@ -67,8 +67,8 @@ do_test 8_3_names-2.1 {
file exists test.nal
} 1
forcedelete test2.db test2.nal test2.db-journal
file copy test.db test2.db
file copy test.nal test2.nal
copy_file test.db test2.db
copy_file test.nal test2.nal
do_test 8_3_names-2.2 {
db eval {
COMMIT;
@@ -101,8 +101,8 @@ do_test 8_3_names-3.1 {
file exists test.nal
} 0
forcedelete test2.db test2.nal test2.db-journal
file copy test.db test2.db
file copy test.db-journal test2.db-journal
copy_file test.db test2.db
copy_file test.db-journal test2.db-journal
do_test 8_3_names-3.2 {
db eval {
COMMIT;
+1
View File
@@ -38,6 +38,7 @@ run_test_suite pcache10
run_test_suite pcache50
run_test_suite pcache90
run_test_suite pcache100
run_test_suite prepare
if {$::tcl_platform(platform)=="unix"} {
ifcapable !default_autovacuum {
+5 -5
View File
@@ -221,8 +221,8 @@ do_test alter-1.7 {
#
ifcapable attach {
do_test alter-1.8.1 {
file delete -force test2.db
file delete -force test2.db-journal
forcedelete test2.db
forcedelete test2.db-journal
execsql {
ATTACH 'test2.db' AS aux;
}
@@ -412,8 +412,8 @@ do_test alter-3.1.8 {
# Make sure "ON" cannot be used as a database, table or column name without
# quoting. Otherwise the sqlite_alter_trigger() function might not work.
file delete -force test3.db
file delete -force test3.db-journal
forcedelete test3.db
forcedelete test3.db-journal
ifcapable attach {
do_test alter-3.2.1 {
catchsql {
@@ -846,7 +846,7 @@ do_test alter-14.2 {
set system_table_list {1 sqlite_master}
catchsql ANALYZE
ifcapable analyze { lappend system_table_list 2 sqlite_stat1 }
ifcapable stat2 { lappend system_table_list 3 sqlite_stat2 }
ifcapable stat3 { lappend system_table_list 4 sqlite_stat3 }
foreach {tn tbl} $system_table_list {
do_test alter-15.$tn.1 {
+3 -2
View File
@@ -137,6 +137,7 @@ do_test alter2-1.8 {
do_test alter2-1.9 {
# ALTER TABLE abc ADD COLUMN d;
alter_table abc {CREATE TABLE abc(a, b, c, d);}
if {[permutation] == "prepare"} { db cache flush }
execsql { SELECT * FROM abc; }
execsql {
UPDATE abc SET d = 11 WHERE c IS NULL AND a<4;
@@ -314,8 +315,8 @@ do_test alter2-6.1 {
} {2}
ifcapable attach {
do_test alter2-6.2 {
file delete -force test2.db-journal
file delete -force test2.db
forcedelete test2.db-journal
forcedelete test2.db
execsql {
ATTACH 'test2.db' AS aux;
CREATE TABLE aux.t1(a, b);
+3 -3
View File
@@ -196,7 +196,7 @@ ifcapable schema_version {
do_test alter3-4.1 {
db close
file delete -force test.db
forcedelete test.db
set ::DB [sqlite3 db test.db]
execsql {
PRAGMA legacy_file_format=ON;
@@ -237,8 +237,8 @@ do_test alter3-4.99 {
ifcapable attach {
do_test alter3-5.1 {
file delete -force test2.db
file delete -force test2.db-journal
forcedelete test2.db
forcedelete test2.db-journal
execsql {
CREATE TABLE t1(a, b);
INSERT INTO t1 VALUES(1, 'one');
+3 -3
View File
@@ -178,7 +178,7 @@ ifcapable schema_version {
do_test alter4-4.1 {
db close
file delete -force test.db
forcedelete test.db
set ::DB [sqlite3 db test.db]
execsql {
CREATE TEMP TABLE t1(a, b);
@@ -213,8 +213,8 @@ do_test alter4-4.99 {
ifcapable attach {
do_test alter4-5.1 {
file delete -force test2.db
file delete -force test2.db-journal
forcedelete test2.db
forcedelete test2.db-journal
execsql {
CREATE TEMP TABLE t1(a, b);
INSERT INTO t1 VALUES(1, 'one');
+58
View File
@@ -287,6 +287,64 @@ do_test analyze-4.3 {
}
} {}
# Verify that DROP TABLE and DROP INDEX remove entries from the
# sqlite_stat1 and sqlite_stat3 tables.
#
do_test analyze-5.0 {
execsql {
DELETE FROM t3;
DELETE FROM t4;
INSERT INTO t3 VALUES(1,2,3,4);
INSERT INTO t3 VALUES(5,6,7,8);
INSERT INTO t3 SELECT a+8, b+8, c+8, d+8 FROM t3;
INSERT INTO t3 SELECT a+16, b+16, c+16, d+16 FROM t3;
INSERT INTO t3 SELECT a+32, b+32, c+32, d+32 FROM t3;
INSERT INTO t3 SELECT a+64, b+64, c+64, d+64 FROM t3;
INSERT INTO t4 SELECT a, b, c FROM t3;
ANALYZE;
SELECT DISTINCT idx FROM sqlite_stat1 ORDER BY 1;
SELECT DISTINCT tbl FROM sqlite_stat1 ORDER BY 1;
}
} {t3i1 t3i2 t3i3 t4i1 t4i2 t3 t4}
ifcapable stat3 {
do_test analyze-5.1 {
execsql {
SELECT DISTINCT idx FROM sqlite_stat3 ORDER BY 1;
SELECT DISTINCT tbl FROM sqlite_stat3 ORDER BY 1;
}
} {t3i1 t3i2 t3i3 t4i1 t4i2 t3 t4}
}
do_test analyze-5.2 {
execsql {
DROP INDEX t3i2;
SELECT DISTINCT idx FROM sqlite_stat1 ORDER BY 1;
SELECT DISTINCT tbl FROM sqlite_stat1 ORDER BY 1;
}
} {t3i1 t3i3 t4i1 t4i2 t3 t4}
ifcapable stat3 {
do_test analyze-5.3 {
execsql {
SELECT DISTINCT idx FROM sqlite_stat3 ORDER BY 1;
SELECT DISTINCT tbl FROM sqlite_stat3 ORDER BY 1;
}
} {t3i1 t3i3 t4i1 t4i2 t3 t4}
}
do_test analyze-5.4 {
execsql {
DROP TABLE t3;
SELECT DISTINCT idx FROM sqlite_stat1 ORDER BY 1;
SELECT DISTINCT tbl FROM sqlite_stat1 ORDER BY 1;
}
} {t4i1 t4i2 t4}
ifcapable stat3 {
do_test analyze-5.5 {
execsql {
SELECT DISTINCT idx FROM sqlite_stat3 ORDER BY 1;
SELECT DISTINCT tbl FROM sqlite_stat3 ORDER BY 1;
}
} {t4i1 t4i2 t4}
}
# This test corrupts the database file so it must be the last test
# in the series.
#
-554
View File
@@ -1,554 +0,0 @@
# 2009 August 06
#
# 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 extra functionality provided by the ANALYZE
# command when the library is compiled with SQLITE_ENABLE_STAT2 defined.
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
ifcapable !stat2 {
finish_test
return
}
set testprefix analyze2
# Do not use a codec for tests in this file, as the database file is
# manipulated directly using tcl scripts (using the [hexio_write] command).
#
do_not_use_codec
#--------------------------------------------------------------------
# Test organization:
#
# analyze2-1.*: Tests to verify that ANALYZE creates and populates the
# sqlite_stat2 table as expected.
#
# analyze2-2.*: Test that when a table has two indexes on it and either
# index may be used for the scan, the index suggested by
# the contents of sqlite_stat2 table is prefered.
#
# analyze2-3.*: Similar to the previous block of tests, but using tables
# that contain a mixture of NULL, numeric, text and blob
# values.
#
# analyze2-4.*: Check that when an indexed column uses a collation other
# than BINARY, the collation is taken into account when
# using the contents of sqlite_stat2 to estimate the cost
# of a range scan.
#
# analyze2-5.*: Check that collation sequences are used as described above
# even when the only available version of the collation
# function require UTF-16 encoded arguments.
#
# analyze2-6.*: Check that the library behaves correctly when one of the
# sqlite_stat2 or sqlite_stat1 tables are missing.
#
# analyze2-7.*: Check that in a shared-schema situation, nothing goes
# wrong if sqlite_stat2 data is read by one connection,
# and freed by another.
#
proc eqp {sql {db db}} {
uplevel execsql [list "EXPLAIN QUERY PLAN $sql"] $db
}
do_test analyze2-1.1 {
execsql { CREATE TABLE t1(x PRIMARY KEY) }
for {set i 0} {$i < 1000} {incr i} {
execsql { INSERT INTO t1 VALUES($i) }
}
execsql {
ANALYZE;
SELECT * FROM sqlite_stat2;
}
} [list t1 sqlite_autoindex_t1_1 0 50 \
t1 sqlite_autoindex_t1_1 1 149 \
t1 sqlite_autoindex_t1_1 2 249 \
t1 sqlite_autoindex_t1_1 3 349 \
t1 sqlite_autoindex_t1_1 4 449 \
t1 sqlite_autoindex_t1_1 5 549 \
t1 sqlite_autoindex_t1_1 6 649 \
t1 sqlite_autoindex_t1_1 7 749 \
t1 sqlite_autoindex_t1_1 8 849 \
t1 sqlite_autoindex_t1_1 9 949 \
]
do_test analyze2-1.2 {
execsql {
DELETE FROM t1 WHERe x>9;
ANALYZE;
SELECT tbl, idx, group_concat(sample, ' ') FROM sqlite_stat2;
}
} {t1 sqlite_autoindex_t1_1 {0 1 2 3 4 5 6 7 8 9}}
do_test analyze2-1.3 {
execsql {
DELETE FROM t1 WHERE x>8;
ANALYZE;
SELECT * FROM sqlite_stat2;
}
} {}
do_test analyze2-1.4 {
execsql {
DELETE FROM t1;
ANALYZE;
SELECT * FROM sqlite_stat2;
}
} {}
do_test analyze2-2.1 {
execsql {
BEGIN;
DROP TABLE t1;
CREATE TABLE t1(x, y);
CREATE INDEX t1_x ON t1(x);
CREATE INDEX t1_y ON t1(y);
}
for {set i 0} {$i < 1000} {incr i} {
execsql { INSERT INTO t1 VALUES($i, $i) }
}
execsql COMMIT
execsql ANALYZE
} {}
do_eqp_test 2.2 {
SELECT * FROM t1 WHERE x>500 AND y>700
} {
0 0 0 {SEARCH TABLE t1 USING INDEX t1_y (y>?) (~100 rows)}
}
do_eqp_test 2.3 {
SELECT * FROM t1 WHERE x>700 AND y>500
} {
0 0 0 {SEARCH TABLE t1 USING INDEX t1_x (x>?) (~100 rows)}
}
do_eqp_test 2.3 {
SELECT * FROM t1 WHERE y>700 AND x>500
} {
0 0 0 {SEARCH TABLE t1 USING INDEX t1_y (y>?) (~100 rows)}
}
do_eqp_test 2.4 {
SELECT * FROM t1 WHERE y>500 AND x>700
} {
0 0 0 {SEARCH TABLE t1 USING INDEX t1_x (x>?) (~100 rows)}
}
do_eqp_test 2.5 {
SELECT * FROM t1 WHERE x BETWEEN 100 AND 200 AND y BETWEEN 400 AND 700
} {
0 0 0 {SEARCH TABLE t1 USING INDEX t1_x (x>? AND x<?) (~25 rows)}
}
do_eqp_test 2.6 {
SELECT * FROM t1 WHERE x BETWEEN 100 AND 500 AND y BETWEEN 400 AND 700
} {
0 0 0 {SEARCH TABLE t1 USING INDEX t1_y (y>? AND y<?) (~75 rows)}
}
do_eqp_test 2.7 {
SELECT * FROM t1 WHERE x BETWEEN -400 AND -300 AND y BETWEEN 100 AND 300
} {
0 0 0 {SEARCH TABLE t1 USING INDEX t1_x (x>? AND x<?) (~12 rows)}
}
do_eqp_test 2.8 {
SELECT * FROM t1 WHERE x BETWEEN 100 AND 300 AND y BETWEEN -400 AND -300
} {
0 0 0 {SEARCH TABLE t1 USING INDEX t1_y (y>? AND y<?) (~12 rows)}
}
do_eqp_test 2.9 {
SELECT * FROM t1 WHERE x BETWEEN 500 AND 100 AND y BETWEEN 100 AND 300
} {
0 0 0 {SEARCH TABLE t1 USING INDEX t1_x (x>? AND x<?) (~12 rows)}
}
do_eqp_test 2.10 {
SELECT * FROM t1 WHERE x BETWEEN 100 AND 300 AND y BETWEEN 500 AND 100
} {
0 0 0 {SEARCH TABLE t1 USING INDEX t1_y (y>? AND y<?) (~12 rows)}
}
do_test analyze2-3.1 {
set alphabet [list a b c d e f g h i j]
execsql BEGIN
for {set i 0} {$i < 1000} {incr i} {
set str [lindex $alphabet [expr ($i/100)%10]]
append str [lindex $alphabet [expr ($i/ 10)%10]]
append str [lindex $alphabet [expr ($i/ 1)%10]]
execsql { INSERT INTO t1 VALUES($str, $str) }
}
execsql COMMIT
execsql ANALYZE
execsql {
SELECT tbl,idx,group_concat(sample,' ')
FROM sqlite_stat2
WHERE idx = 't1_x'
GROUP BY tbl,idx
}
} {t1 t1_x {100 299 499 699 899 ajj cjj ejj gjj ijj}}
do_test analyze2-3.2 {
execsql {
SELECT tbl,idx,group_concat(sample,' ')
FROM sqlite_stat2
WHERE idx = 't1_y'
GROUP BY tbl,idx
}
} {t1 t1_y {100 299 499 699 899 ajj cjj ejj gjj ijj}}
do_eqp_test 3.3 {
SELECT * FROM t1 WHERE x BETWEEN 100 AND 500 AND y BETWEEN 'a' AND 'b'
} {
0 0 0 {SEARCH TABLE t1 USING INDEX t1_y (y>? AND y<?) (~50 rows)}
}
do_eqp_test 3.4 {
SELECT * FROM t1 WHERE x BETWEEN 100 AND 400 AND y BETWEEN 'a' AND 'h'
} {
0 0 0 {SEARCH TABLE t1 USING INDEX t1_x (x>? AND x<?) (~100 rows)}
}
do_eqp_test 3.5 {
SELECT * FROM t1 WHERE x<'a' AND y>'h'
} {
0 0 0 {SEARCH TABLE t1 USING INDEX t1_y (y>?) (~66 rows)}
}
do_eqp_test 3.6 {
SELECT * FROM t1 WHERE x<444 AND y>'h'
} {
0 0 0 {SEARCH TABLE t1 USING INDEX t1_y (y>?) (~66 rows)}
}
do_eqp_test 3.7 {
SELECT * FROM t1 WHERE x<221 AND y>'g'
} {
0 0 0 {SEARCH TABLE t1 USING INDEX t1_x (x<?) (~66 rows)}
}
do_test analyze2-4.1 {
execsql { CREATE TABLE t3(a COLLATE nocase, b) }
execsql { CREATE INDEX t3a ON t3(a) }
execsql { CREATE INDEX t3b ON t3(b) }
set alphabet [list A b C d E f G h I j]
execsql BEGIN
for {set i 0} {$i < 1000} {incr i} {
set str [lindex $alphabet [expr ($i/100)%10]]
append str [lindex $alphabet [expr ($i/ 10)%10]]
append str [lindex $alphabet [expr ($i/ 1)%10]]
execsql { INSERT INTO t3 VALUES($str, $str) }
}
execsql COMMIT
execsql ANALYZE
} {}
do_test analyze2-4.2 {
execsql {
PRAGMA automatic_index=OFF;
SELECT tbl,idx,group_concat(sample,' ')
FROM sqlite_stat2
WHERE idx = 't3a'
GROUP BY tbl,idx;
PRAGMA automatic_index=ON;
}
} {t3 t3a {AfA bEj CEj dEj EEj fEj GEj hEj IEj jEj}}
do_test analyze2-4.3 {
execsql {
SELECT tbl,idx,group_concat(sample,' ')
FROM sqlite_stat2
WHERE idx = 't3b'
GROUP BY tbl,idx
}
} {t3 t3b {AbA CIj EIj GIj IIj bIj dIj fIj hIj jIj}}
do_eqp_test 4.4 {
SELECT * FROM t3 WHERE a > 'A' AND a < 'C' AND b > 'A' AND b < 'C'
} {
0 0 0 {SEARCH TABLE t3 USING INDEX t3b (b>? AND b<?) (~11 rows)}
}
do_eqp_test 4.5 {
SELECT * FROM t3 WHERE a > 'A' AND a < 'c' AND b > 'A' AND b < 'c'
} {
0 0 0 {SEARCH TABLE t3 USING INDEX t3a (a>? AND a<?) (~22 rows)}
}
ifcapable utf16 {
proc test_collate {enc lhs rhs} {
# puts $enc
return [string compare $lhs $rhs]
}
do_test analyze2-5.1 {
add_test_collate db 0 0 1
execsql { CREATE TABLE t4(x COLLATE test_collate) }
execsql { CREATE INDEX t4x ON t4(x) }
set alphabet [list a b c d e f g h i j]
execsql BEGIN
for {set i 0} {$i < 1000} {incr i} {
set str [lindex $alphabet [expr ($i/100)%10]]
append str [lindex $alphabet [expr ($i/ 10)%10]]
append str [lindex $alphabet [expr ($i/ 1)%10]]
execsql { INSERT INTO t4 VALUES($str) }
}
execsql COMMIT
execsql ANALYZE
} {}
do_test analyze2-5.2 {
execsql {
SELECT tbl,idx,group_concat(sample,' ')
FROM sqlite_stat2
WHERE tbl = 't4'
GROUP BY tbl,idx
}
} {t4 t4x {afa bej cej dej eej fej gej hej iej jej}}
do_eqp_test 5.3 {
SELECT * FROM t4 WHERE x>'ccc'
} {0 0 0 {SEARCH TABLE t4 USING COVERING INDEX t4x (x>?) (~800 rows)}}
do_eqp_test 5.4 {
SELECT * FROM t4 AS t41, t4 AS t42 WHERE t41.x>'ccc' AND t42.x>'ggg'
} {
0 0 1 {SEARCH TABLE t4 AS t42 USING COVERING INDEX t4x (x>?) (~300 rows)}
0 1 0 {SEARCH TABLE t4 AS t41 USING COVERING INDEX t4x (x>?) (~800 rows)}
}
do_eqp_test 5.5 {
SELECT * FROM t4 AS t41, t4 AS t42 WHERE t41.x>'ddd' AND t42.x>'ccc'
} {
0 0 0 {SEARCH TABLE t4 AS t41 USING COVERING INDEX t4x (x>?) (~700 rows)}
0 1 1 {SEARCH TABLE t4 AS t42 USING COVERING INDEX t4x (x>?) (~800 rows)}
}
}
#--------------------------------------------------------------------
# These tests, analyze2-6.*, verify that the library behaves correctly
# when one of the sqlite_stat1 and sqlite_stat2 tables is missing.
#
# If the sqlite_stat1 table is not present, then the sqlite_stat2
# table is not read. However, if it is the sqlite_stat2 table that
# is missing, the data in the sqlite_stat1 table is still used.
#
# Tests analyze2-6.1.* test the libary when the sqlite_stat2 table
# is missing. Tests analyze2-6.2.* test the library when sqlite_stat1
# is not present.
#
do_test analyze2-6.0 {
execsql {
DROP TABLE IF EXISTS t4;
CREATE TABLE t5(a, b); CREATE INDEX t5i ON t5(a, b);
CREATE TABLE t6(a, b); CREATE INDEX t6i ON t6(a, b);
}
for {set ii 0} {$ii < 20} {incr ii} {
execsql {
INSERT INTO t5 VALUES($ii, $ii);
INSERT INTO t6 VALUES($ii/10, $ii/10);
}
}
execsql {
CREATE TABLE master AS
SELECT * FROM sqlite_master WHERE name LIKE 'sqlite_stat%'
}
} {}
do_test analyze2-6.1.1 {
eqp {SELECT * FROM t5,t6 WHERE t5.rowid=t6.rowid AND
t5.a = 1 AND
t6.a = 1 AND t6.b = 1
}
} {0 0 1 {SEARCH TABLE t6 USING COVERING INDEX t6i (a=? AND b=?) (~9 rows)} 0 1 0 {SEARCH TABLE t5 USING INTEGER PRIMARY KEY (rowid=?) (~1 rows)}}
do_test analyze2-6.1.2 {
db cache flush
execsql ANALYZE
eqp {SELECT * FROM t5,t6 WHERE t5.rowid=t6.rowid AND
t5.a = 1 AND
t6.a = 1 AND t6.b = 1
}
} {0 0 0 {SEARCH TABLE t5 USING COVERING INDEX t5i (a=?) (~1 rows)} 0 1 1 {SEARCH TABLE t6 USING INTEGER PRIMARY KEY (rowid=?) (~1 rows)}}
do_test analyze2-6.1.3 {
sqlite3 db test.db
eqp { SELECT * FROM t5,t6 WHERE t5.rowid=t6.rowid AND
t5.a = 1 AND
t6.a = 1 AND t6.b = 1
}
} {0 0 0 {SEARCH TABLE t5 USING COVERING INDEX t5i (a=?) (~1 rows)} 0 1 1 {SEARCH TABLE t6 USING INTEGER PRIMARY KEY (rowid=?) (~1 rows)}}
do_test analyze2-6.1.4 {
execsql {
PRAGMA writable_schema = 1;
DELETE FROM sqlite_master WHERE tbl_name = 'sqlite_stat2';
}
sqlite3 db test.db
eqp { SELECT * FROM t5,t6 WHERE t5.rowid=t6.rowid AND
t5.a = 1 AND
t6.a = 1 AND t6.b = 1
}
} {0 0 0 {SEARCH TABLE t5 USING COVERING INDEX t5i (a=?) (~1 rows)} 0 1 1 {SEARCH TABLE t6 USING INTEGER PRIMARY KEY (rowid=?) (~1 rows)}}
do_test analyze2-6.1.5 {
execsql {
PRAGMA writable_schema = 1;
DELETE FROM sqlite_master WHERE tbl_name = 'sqlite_stat1';
}
sqlite3 db test.db
eqp { SELECT * FROM t5,t6 WHERE t5.rowid=t6.rowid AND
t5.a = 1 AND
t6.a = 1 AND t6.b = 1
}
} {0 0 1 {SEARCH TABLE t6 USING COVERING INDEX t6i (a=? AND b=?) (~9 rows)} 0 1 0 {SEARCH TABLE t5 USING INTEGER PRIMARY KEY (rowid=?) (~1 rows)}}
do_test analyze2-6.1.6 {
execsql {
PRAGMA writable_schema = 1;
INSERT INTO sqlite_master SELECT * FROM master;
}
sqlite3 db test.db
eqp { SELECT * FROM t5,t6 WHERE t5.rowid=t6.rowid AND
t5.a = 1 AND
t6.a = 1 AND t6.b = 1
}
} {0 0 0 {SEARCH TABLE t5 USING COVERING INDEX t5i (a=?) (~1 rows)} 0 1 1 {SEARCH TABLE t6 USING INTEGER PRIMARY KEY (rowid=?) (~1 rows)}}
do_test analyze2-6.2.1 {
execsql {
DELETE FROM sqlite_stat1;
DELETE FROM sqlite_stat2;
}
sqlite3 db test.db
eqp { SELECT * FROM t5,t6 WHERE t5.rowid=t6.rowid AND
t5.a>1 AND t5.a<15 AND
t6.a>1
}
} {0 0 0 {SEARCH TABLE t5 USING COVERING INDEX t5i (a>? AND a<?) (~60000 rows)} 0 1 1 {SEARCH TABLE t6 USING INTEGER PRIMARY KEY (rowid=?) (~1 rows)}}
do_test analyze2-6.2.2 {
db cache flush
execsql ANALYZE
eqp { SELECT * FROM t5,t6 WHERE t5.rowid=t6.rowid AND
t5.a>1 AND t5.a<15 AND
t6.a>1
}
} {0 0 1 {SEARCH TABLE t6 USING COVERING INDEX t6i (a>?) (~1 rows)} 0 1 0 {SEARCH TABLE t5 USING INTEGER PRIMARY KEY (rowid=?) (~1 rows)}}
do_test analyze2-6.2.3 {
sqlite3 db test.db
eqp { SELECT * FROM t5,t6 WHERE t5.rowid=t6.rowid AND
t5.a>1 AND t5.a<15 AND
t6.a>1
}
} {0 0 1 {SEARCH TABLE t6 USING COVERING INDEX t6i (a>?) (~1 rows)} 0 1 0 {SEARCH TABLE t5 USING INTEGER PRIMARY KEY (rowid=?) (~1 rows)}}
do_test analyze2-6.2.4 {
execsql {
PRAGMA writable_schema = 1;
DELETE FROM sqlite_master WHERE tbl_name = 'sqlite_stat1';
}
sqlite3 db test.db
eqp { SELECT * FROM t5,t6 WHERE t5.rowid=t6.rowid AND
t5.a>1 AND t5.a<15 AND
t6.a>1
}
} {0 0 0 {SEARCH TABLE t5 USING COVERING INDEX t5i (a>? AND a<?) (~60000 rows)} 0 1 1 {SEARCH TABLE t6 USING INTEGER PRIMARY KEY (rowid=?) (~1 rows)}}
do_test analyze2-6.2.5 {
execsql {
PRAGMA writable_schema = 1;
DELETE FROM sqlite_master WHERE tbl_name = 'sqlite_stat2';
}
sqlite3 db test.db
eqp { SELECT * FROM t5,t6 WHERE t5.rowid=t6.rowid AND
t5.a>1 AND t5.a<15 AND
t6.a>1
}
} {0 0 0 {SEARCH TABLE t5 USING COVERING INDEX t5i (a>? AND a<?) (~60000 rows)} 0 1 1 {SEARCH TABLE t6 USING INTEGER PRIMARY KEY (rowid=?) (~1 rows)}}
do_test analyze2-6.2.6 {
execsql {
PRAGMA writable_schema = 1;
INSERT INTO sqlite_master SELECT * FROM master;
}
sqlite3 db test.db
execsql ANALYZE
eqp { SELECT * FROM t5,t6 WHERE t5.rowid=t6.rowid AND
t5.a>1 AND t5.a<15 AND
t6.a>1
}
} {0 0 1 {SEARCH TABLE t6 USING COVERING INDEX t6i (a>?) (~1 rows)} 0 1 0 {SEARCH TABLE t5 USING INTEGER PRIMARY KEY (rowid=?) (~1 rows)}}
#--------------------------------------------------------------------
# These tests, analyze2-7.*, test that the sqlite_stat2 functionality
# works in shared-cache mode. Note that these tests reuse the database
# created for the analyze2-6.* tests.
#
ifcapable shared_cache {
db close
set ::enable_shared_cache [sqlite3_enable_shared_cache 1]
proc incr_schema_cookie {zDb} {
foreach iOffset {24 40} {
set cookie [hexio_get_int [hexio_read $zDb $iOffset 4]]
incr cookie
hexio_write $zDb $iOffset [hexio_render_int32 $cookie]
}
}
do_test analyze2-7.1 {
sqlite3 db1 test.db
sqlite3 db2 test.db
db1 cache size 0
db2 cache size 0
execsql { SELECT count(*) FROM t5 } db1
} {20}
do_test analyze2-7.2 {
incr_schema_cookie test.db
execsql { SELECT count(*) FROM t5 } db2
} {20}
do_test analyze2-7.3 {
incr_schema_cookie test.db
execsql { SELECT count(*) FROM t5 } db1
} {20}
do_test analyze2-7.4 {
incr_schema_cookie test.db
execsql { SELECT count(*) FROM t5 } db2
} {20}
do_test analyze2-7.5 {
eqp { SELECT * FROM t5,t6 WHERE t5.rowid=t6.rowid AND
t5.a>1 AND t5.a<15 AND
t6.a>1
} db1
} {0 0 1 {SEARCH TABLE t6 USING COVERING INDEX t6i (a>?) (~1 rows)} 0 1 0 {SEARCH TABLE t5 USING INTEGER PRIMARY KEY (rowid=?) (~1 rows)}}
do_test analyze2-7.6 {
incr_schema_cookie test.db
execsql { SELECT * FROM sqlite_master } db2
eqp { SELECT * FROM t5,t6 WHERE t5.rowid=t6.rowid AND
t5.a>1 AND t5.a<15 AND
t6.a>1
} db2
} {0 0 1 {SEARCH TABLE t6 USING COVERING INDEX t6i (a>?) (~1 rows)} 0 1 0 {SEARCH TABLE t5 USING INTEGER PRIMARY KEY (rowid=?) (~1 rows)}}
do_test analyze2-7.7 {
incr_schema_cookie test.db
execsql { SELECT * FROM sqlite_master } db1
eqp { SELECT * FROM t5,t6 WHERE t5.rowid=t6.rowid AND
t5.a>1 AND t5.a<15 AND
t6.a>1
} db1
} {0 0 1 {SEARCH TABLE t6 USING COVERING INDEX t6i (a>?) (~1 rows)} 0 1 0 {SEARCH TABLE t5 USING INTEGER PRIMARY KEY (rowid=?) (~1 rows)}}
do_test analyze2-7.8 {
execsql { DELETE FROM sqlite_stat2 } db2
execsql { SELECT * FROM sqlite_master } db1
eqp { SELECT * FROM t5,t6 WHERE t5.rowid=t6.rowid AND
t5.a>1 AND t5.a<15 AND
t6.a>1
} db1
} {0 0 1 {SEARCH TABLE t6 USING COVERING INDEX t6i (a>?) (~1 rows)} 0 1 0 {SEARCH TABLE t5 USING INTEGER PRIMARY KEY (rowid=?) (~1 rows)}}
do_test analyze2-7.9 {
execsql { SELECT * FROM sqlite_master } db2
eqp { SELECT * FROM t5,t6 WHERE t5.rowid=t6.rowid AND
t5.a>1 AND t5.a<15 AND
t6.a>1
} db2
} {0 0 1 {SEARCH TABLE t6 USING COVERING INDEX t6i (a>?) (~1 rows)} 0 1 0 {SEARCH TABLE t5 USING INTEGER PRIMARY KEY (rowid=?) (~1 rows)}}
do_test analyze2-7.10 {
incr_schema_cookie test.db
execsql { SELECT * FROM sqlite_master } db1
eqp { SELECT * FROM t5,t6 WHERE t5.rowid=t6.rowid AND
t5.a>1 AND t5.a<15 AND
t6.a>1
} db1
} {0 0 0 {SEARCH TABLE t5 USING COVERING INDEX t5i (a>? AND a<?) (~1 rows)} 0 1 1 {SEARCH TABLE t6 USING INTEGER PRIMARY KEY (rowid=?) (~1 rows)}}
db1 close
db2 close
sqlite3_enable_shared_cache $::enable_shared_cache
}
finish_test
+18 -18
View File
@@ -17,7 +17,7 @@
set testdir [file dirname $argv0]
source $testdir/tester.tcl
ifcapable !stat2 {
ifcapable !stat3 {
finish_test
return
}
@@ -70,7 +70,7 @@ proc sf_execsql {sql {db db}} {
# Show that there are two possible plans for querying the table with
# a range constraint on the indexed column - "full table scan" or "use
# the index". When the range is specified using literal values, SQLite
# is able to pick the best plan based on the samples in sqlite_stat2.
# is able to pick the best plan based on the samples in sqlite_stat3.
#
# analyze3-1.1.4 - 3.1.9
# Show that using SQL variables produces the same results as using
@@ -97,10 +97,10 @@ do_test analyze3-1.1.1 {
do_eqp_test analyze3-1.1.2 {
SELECT sum(y) FROM t1 WHERE x>200 AND x<300
} {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (x>? AND x<?) (~100 rows)}}
} {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (x>? AND x<?) (~179 rows)}}
do_eqp_test analyze3-1.1.3 {
SELECT sum(y) FROM t1 WHERE x>0 AND x<1100
} {0 0 0 {SCAN TABLE t1 (~111 rows)}}
} {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (x>? AND x<?) (~959 rows)}}
do_test analyze3-1.1.4 {
sf_execsql { SELECT sum(y) FROM t1 WHERE x>200 AND x<300 }
@@ -117,17 +117,17 @@ do_test analyze3-1.1.6 {
} {199 0 14850}
do_test analyze3-1.1.7 {
sf_execsql { SELECT sum(y) FROM t1 WHERE x>0 AND x<1100 }
} {999 999 499500}
} {2000 0 499500}
do_test analyze3-1.1.8 {
set l [string range "0" 0 end]
set u [string range "1100" 0 end]
sf_execsql { SELECT sum(y) FROM t1 WHERE x>$l AND x<$u }
} {999 999 499500}
} {2000 0 499500}
do_test analyze3-1.1.9 {
set l [expr int(0)]
set u [expr int(1100)]
sf_execsql { SELECT sum(y) FROM t1 WHERE x>$l AND x<$u }
} {999 999 499500}
} {2000 0 499500}
# The following tests are similar to the block above. The difference is
@@ -146,10 +146,10 @@ do_test analyze3-1.2.1 {
} {}
do_eqp_test analyze3-1.2.2 {
SELECT sum(y) FROM t2 WHERE x>1 AND x<2
} {0 0 0 {SEARCH TABLE t2 USING INDEX i2 (x>? AND x<?) (~200 rows)}}
} {0 0 0 {SEARCH TABLE t2 USING INDEX i2 (x>? AND x<?) (~196 rows)}}
do_eqp_test analyze3-1.2.3 {
SELECT sum(y) FROM t2 WHERE x>0 AND x<99
} {0 0 0 {SCAN TABLE t2 (~111 rows)}}
} {0 0 0 {SEARCH TABLE t2 USING INDEX i2 (x>? AND x<?) (~968 rows)}}
do_test analyze3-1.2.4 {
sf_execsql { SELECT sum(y) FROM t2 WHERE x>12 AND x<20 }
} {161 0 4760}
@@ -165,17 +165,17 @@ do_test analyze3-1.2.6 {
} {161 0 integer integer 4760}
do_test analyze3-1.2.7 {
sf_execsql { SELECT sum(y) FROM t2 WHERE x>0 AND x<99 }
} {999 999 490555}
} {1981 0 490555}
do_test analyze3-1.2.8 {
set l [string range "0" 0 end]
set u [string range "99" 0 end]
sf_execsql {SELECT typeof($l), typeof($u), sum(y) FROM t2 WHERE x>$l AND x<$u}
} {999 999 text text 490555}
} {1981 0 text text 490555}
do_test analyze3-1.2.9 {
set l [expr int(0)]
set u [expr int(99)]
sf_execsql {SELECT typeof($l), typeof($u), sum(y) FROM t2 WHERE x>$l AND x<$u}
} {999 999 integer integer 490555}
} {1981 0 integer integer 490555}
# Same tests a third time. This time, column x has INTEGER affinity and
# is not the leftmost column of the table. This triggered a bug causing
@@ -193,10 +193,10 @@ do_test analyze3-1.3.1 {
} {}
do_eqp_test analyze3-1.3.2 {
SELECT sum(y) FROM t3 WHERE x>200 AND x<300
} {0 0 0 {SEARCH TABLE t3 USING INDEX i3 (x>? AND x<?) (~100 rows)}}
} {0 0 0 {SEARCH TABLE t3 USING INDEX i3 (x>? AND x<?) (~156 rows)}}
do_eqp_test analyze3-1.3.3 {
SELECT sum(y) FROM t3 WHERE x>0 AND x<1100
} {0 0 0 {SCAN TABLE t3 (~111 rows)}}
} {0 0 0 {SEARCH TABLE t3 USING INDEX i3 (x>? AND x<?) (~989 rows)}}
do_test analyze3-1.3.4 {
sf_execsql { SELECT sum(y) FROM t3 WHERE x>200 AND x<300 }
@@ -213,17 +213,17 @@ do_test analyze3-1.3.6 {
} {199 0 14850}
do_test analyze3-1.3.7 {
sf_execsql { SELECT sum(y) FROM t3 WHERE x>0 AND x<1100 }
} {999 999 499500}
} {2000 0 499500}
do_test analyze3-1.3.8 {
set l [string range "0" 0 end]
set u [string range "1100" 0 end]
sf_execsql { SELECT sum(y) FROM t3 WHERE x>$l AND x<$u }
} {999 999 499500}
} {2000 0 499500}
do_test analyze3-1.3.9 {
set l [expr int(0)]
set u [expr int(1100)]
sf_execsql { SELECT sum(y) FROM t3 WHERE x>$l AND x<$u }
} {999 999 499500}
} {2000 0 499500}
#-------------------------------------------------------------------------
# Test that the values of bound SQL variables may be used for the LIKE
@@ -248,7 +248,7 @@ do_test analyze3-2.1 {
} {}
do_eqp_test analyze3-2.2 {
SELECT count(a) FROM t1 WHERE b LIKE 'a%'
} {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (b>? AND b<?) (~30000 rows)}}
} {0 0 0 {SEARCH TABLE t1 USING INDEX i1 (b>? AND b<?) (~31250 rows)}}
do_eqp_test analyze3-2.3 {
SELECT count(a) FROM t1 WHERE b LIKE '%a'
} {0 0 0 {SCAN TABLE t1 (~500000 rows)}}
+68 -78
View File
@@ -10,14 +10,14 @@
#***********************************************************************
#
# This file implements tests for SQLite library. The focus of the tests
# in this file is the use of the sqlite_stat2 histogram data on tables
# in this file is the use of the sqlite_stat3 histogram data on tables
# with many repeated values and only a few distinct values.
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
ifcapable !stat2 {
ifcapable !stat3 {
finish_test
return
}
@@ -55,114 +55,102 @@ do_test analyze5-1.0 {
CREATE INDEX t1y ON t1(y); -- integers 0 and very few 1s
CREATE INDEX t1z ON t1(z); -- integers 0, 1, 2, and 3
ANALYZE;
SELECT sample FROM sqlite_stat2 WHERE idx='t1u' ORDER BY sampleno;
SELECT sample FROM sqlite_stat3 WHERE idx='t1u' ORDER BY nlt;
}
} {alpha alpha alpha alpha bravo bravo bravo charlie charlie delta}
do_test analyze5-1.1 {
string tolower \
[db eval {SELECT sample from sqlite_stat2 WHERE idx='t1v' ORDER BY sampleno}]
} {alpha alpha alpha alpha bravo bravo bravo charlie charlie delta}
do_test analyze5-1.2 {
db eval {SELECT sample from sqlite_stat2 WHERE idx='t1w' ORDER BY sampleno}
} {{} 0 0 0 0 1 1 1 2 2}
do_test analyze5-1.3 {
db eval {SELECT sample from sqlite_stat2 WHERE idx='t1x' ORDER BY sampleno}
} {{} {} {} {} 1 1 1 2 2 3}
do_test analyze5-1.4 {
db eval {SELECT sample from sqlite_stat2 WHERE idx='t1y' ORDER BY sampleno}
} {0 0 0 0 0 0 0 0 0 0}
do_test analyze5-1.5 {
db eval {SELECT sample from sqlite_stat2 WHERE idx='t1z' ORDER BY sampleno}
} {0 0 0 0 1 1 1 2 2 3}
do_test analyze5-1.6 {
db eval {SELECT sample from sqlite_stat2 WHERE idx='t1t' ORDER BY sampleno}
} {0.5 0.5 0.5 0.5 1.5 1.5 1.5 2.5 2.5 3.5}
} {alpha bravo charlie delta}
do_test analyze5-1.1 {
db eval {SELECT DISTINCT lower(sample) FROM sqlite_stat3 WHERE idx='t1v'
ORDER BY 1}
} {alpha bravo charlie delta}
do_test analyze5-1.2 {
db eval {SELECT idx, count(*) FROM sqlite_stat3 GROUP BY 1 ORDER BY 1}
} {t1t 4 t1u 4 t1v 4 t1w 4 t1x 4 t1y 2 t1z 4}
# Verify that range queries generate the correct row count estimates
#
foreach {testid where index rows} {
1 {z>=0 AND z<=0} t1z 400
2 {z>=1 AND z<=1} t1z 300
3 {z>=2 AND z<=2} t1z 200
4 {z>=3 AND z<=3} t1z 100
5 {z>=4 AND z<=4} t1z 50
6 {z>=-1 AND z<=-1} t1z 50
7 {z>1 AND z<3} t1z 200
3 {z>=2 AND z<=2} t1z 175
4 {z>=3 AND z<=3} t1z 125
5 {z>=4 AND z<=4} t1z 1
6 {z>=-1 AND z<=-1} t1z 1
7 {z>1 AND z<3} t1z 175
8 {z>0 AND z<100} t1z 600
9 {z>=1 AND z<100} t1z 600
10 {z>1 AND z<100} t1z 300
11 {z>=2 AND z<100} t1z 300
12 {z>2 AND z<100} t1z 100
13 {z>=3 AND z<100} t1z 100
14 {z>3 AND z<100} t1z 50
15 {z>=4 AND z<100} t1z 50
16 {z>=-100 AND z<=-1} t1z 50
12 {z>2 AND z<100} t1z 125
13 {z>=3 AND z<100} t1z 125
14 {z>3 AND z<100} t1z 1
15 {z>=4 AND z<100} t1z 1
16 {z>=-100 AND z<=-1} t1z 1
17 {z>=-100 AND z<=0} t1z 400
18 {z>=-100 AND z<0} t1z 50
18 {z>=-100 AND z<0} t1z 1
19 {z>=-100 AND z<=1} t1z 700
20 {z>=-100 AND z<2} t1z 700
21 {z>=-100 AND z<=2} t1z 900
22 {z>=-100 AND z<3} t1z 900
21 {z>=-100 AND z<=2} t1z 875
22 {z>=-100 AND z<3} t1z 875
31 {z>=0.0 AND z<=0.0} t1z 400
32 {z>=1.0 AND z<=1.0} t1z 300
33 {z>=2.0 AND z<=2.0} t1z 200
34 {z>=3.0 AND z<=3.0} t1z 100
35 {z>=4.0 AND z<=4.0} t1z 50
36 {z>=-1.0 AND z<=-1.0} t1z 50
37 {z>1.5 AND z<3.0} t1z 200
38 {z>0.5 AND z<100} t1z 600
33 {z>=2.0 AND z<=2.0} t1z 175
34 {z>=3.0 AND z<=3.0} t1z 125
35 {z>=4.0 AND z<=4.0} t1z 1
36 {z>=-1.0 AND z<=-1.0} t1z 1
37 {z>1.5 AND z<3.0} t1z 174
38 {z>0.5 AND z<100} t1z 599
39 {z>=1.0 AND z<100} t1z 600
40 {z>1.5 AND z<100} t1z 300
40 {z>1.5 AND z<100} t1z 299
41 {z>=2.0 AND z<100} t1z 300
42 {z>2.1 AND z<100} t1z 100
43 {z>=3.0 AND z<100} t1z 100
44 {z>3.2 AND z<100} t1z 50
45 {z>=4.0 AND z<100} t1z 50
46 {z>=-100 AND z<=-1.0} t1z 50
42 {z>2.1 AND z<100} t1z 124
43 {z>=3.0 AND z<100} t1z 125
44 {z>3.2 AND z<100} t1z 1
45 {z>=4.0 AND z<100} t1z 1
46 {z>=-100 AND z<=-1.0} t1z 1
47 {z>=-100 AND z<=0.0} t1z 400
48 {z>=-100 AND z<0.0} t1z 50
48 {z>=-100 AND z<0.0} t1z 1
49 {z>=-100 AND z<=1.0} t1z 700
50 {z>=-100 AND z<2.0} t1z 700
51 {z>=-100 AND z<=2.0} t1z 900
52 {z>=-100 AND z<3.0} t1z 900
51 {z>=-100 AND z<=2.0} t1z 875
52 {z>=-100 AND z<3.0} t1z 875
101 {z=-1} t1z 50
101 {z=-1} t1z 1
102 {z=0} t1z 400
103 {z=1} t1z 300
104 {z=2} t1z 200
105 {z=3} t1z 100
106 {z=4} t1z 50
107 {z=-10.0} t1z 50
104 {z=2} t1z 175
105 {z=3} t1z 125
106 {z=4} t1z 1
107 {z=-10.0} t1z 1
108 {z=0.0} t1z 400
109 {z=1.0} t1z 300
110 {z=2.0} t1z 200
111 {z=3.0} t1z 100
112 {z=4.0} t1z 50
113 {z=1.5} t1z 50
114 {z=2.5} t1z 50
110 {z=2.0} t1z 175
111 {z=3.0} t1z 125
112 {z=4.0} t1z 1
113 {z=1.5} t1z 1
114 {z=2.5} t1z 1
201 {z IN (-1)} t1z 50
201 {z IN (-1)} t1z 1
202 {z IN (0)} t1z 400
203 {z IN (1)} t1z 300
204 {z IN (2)} t1z 200
205 {z IN (3)} t1z 100
206 {z IN (4)} t1z 50
207 {z IN (0.5)} t1z 50
204 {z IN (2)} t1z 175
205 {z IN (3)} t1z 125
206 {z IN (4)} t1z 1
207 {z IN (0.5)} t1z 1
208 {z IN (0,1)} t1z 700
209 {z IN (0,1,2)} t1z 900
209 {z IN (0,1,2)} t1z 875
210 {z IN (0,1,2,3)} {} 100
211 {z IN (0,1,2,3,4,5)} {} 100
212 {z IN (1,2)} t1z 500
212 {z IN (1,2)} t1z 475
213 {z IN (2,3)} t1z 300
214 {z=3 OR z=2} t1z 300
215 {z IN (-1,3)} t1z 150
216 {z=-1 OR z=3} t1z 150
215 {z IN (-1,3)} t1z 126
216 {z=-1 OR z=3} t1z 126
300 {y=0} {} 100
301 {y=1} t1y 50
302 {y=0.1} t1y 50
300 {y=0} t1y 974
301 {y=1} t1y 26
302 {y=0.1} t1y 1
400 {x IS NULL} t1x 400
@@ -204,16 +192,17 @@ db eval {
# Verify that range queries generate the correct row count estimates
#
foreach {testid where index rows} {
500 {x IS NULL AND u='charlie'} t1u 20
501 {x=1 AND u='charlie'} t1x 5
502 {x IS NULL} {} 100
503 {x=1} t1x 50
504 {x IS NOT NULL} t1x 25
500 {x IS NULL AND u='charlie'} t1u 17
501 {x=1 AND u='charlie'} t1x 1
502 {x IS NULL} t1x 995
503 {x=1} t1x 1
504 {x IS NOT NULL} t1x 2
505 {+x IS NOT NULL} {} 500
506 {upper(x) IS NOT NULL} {} 500
} {
# Verify that the expected index is used with the expected row count
if {$testid==50299} {breakpoint; set sqlite_where_trace 1}
do_test analyze5-1.${testid}a {
set x [lindex [eqp "SELECT * FROM t1 WHERE $where"] 3]
set idx {}
@@ -221,6 +210,7 @@ foreach {testid where index rows} {
regexp {~([0-9]+) rows} $x all nrow
list $idx $nrow
} [list $index $rows]
if {$testid==50299} exit
# Verify that the same result is achieved regardless of whether or not
# the index is used
+1 -1
View File
@@ -17,7 +17,7 @@
set testdir [file dirname $argv0]
source $testdir/tester.tcl
ifcapable !stat2 {
ifcapable !stat3 {
finish_test
return
}
+12 -10
View File
@@ -82,14 +82,14 @@ do_test analyze7-3.1 {
do_test analyze7-3.2.1 {
execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE c=?;}
} {0 0 0 {SEARCH TABLE t1 USING INDEX t1cd (c=?) (~86 rows)}}
ifcapable stat2 {
# If ENABLE_STAT2 is defined, SQLite comes up with a different estimated
ifcapable stat3 {
# If ENABLE_STAT3 is defined, SQLite comes up with a different estimated
# row count for (c=2) than it does for (c=?).
do_test analyze7-3.2.2 {
execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE c=2;}
} {0 0 0 {SEARCH TABLE t1 USING INDEX t1cd (c=?) (~51 rows)}}
} {0 0 0 {SEARCH TABLE t1 USING INDEX t1cd (c=?) (~57 rows)}}
} else {
# If ENABLE_STAT2 is not defined, the expected row count for (c=2) is the
# If ENABLE_STAT3 is not defined, the expected row count for (c=2) is the
# same as that for (c=?).
do_test analyze7-3.2.3 {
execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE c=2;}
@@ -98,12 +98,14 @@ ifcapable stat2 {
do_test analyze7-3.3 {
execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE a=123 AND b=123}
} {0 0 0 {SEARCH TABLE t1 USING INDEX t1a (a=?) (~1 rows)}}
do_test analyze7-3.4 {
execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE c=123 AND b=123}
} {0 0 0 {SEARCH TABLE t1 USING INDEX t1b (b=?) (~2 rows)}}
do_test analyze7-3.5 {
execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE a=123 AND c=123}
} {0 0 0 {SEARCH TABLE t1 USING INDEX t1a (a=?) (~1 rows)}}
ifcapable {!stat3} {
do_test analyze7-3.4 {
execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE c=123 AND b=123}
} {0 0 0 {SEARCH TABLE t1 USING INDEX t1b (b=?) (~2 rows)}}
do_test analyze7-3.5 {
execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE a=123 AND c=123}
} {0 0 0 {SEARCH TABLE t1 USING INDEX t1a (a=?) (~1 rows)}}
}
do_test analyze7-3.6 {
execsql {EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE c=123 AND d=123 AND b=123}
} {0 0 0 {SEARCH TABLE t1 USING INDEX t1cd (c=? AND d=?) (~1 rows)}}
+103
View File
@@ -0,0 +1,103 @@
# 2011 August 13
#
# 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 tests for SQLite library. The focus of the tests
# in this file is testing the capabilities of sqlite_stat3.
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
ifcapable !stat3 {
finish_test
return
}
set testprefix analyze8
proc eqp {sql {db db}} {
uplevel execsql [list "EXPLAIN QUERY PLAN $sql"] $db
}
# Scenario:
#
# Two indices. One has mostly singleton entries, but for a few
# values there are hundreds of entries. The other has 10-20
# entries per value.
#
# Verify that the query planner chooses the first index for the singleton
# entries and the second index for the others.
#
do_test 1.0 {
db eval {
CREATE TABLE t1(a,b,c,d);
CREATE INDEX t1a ON t1(a);
CREATE INDEX t1b ON t1(b);
CREATE INDEX t1c ON t1(c);
}
for {set i 0} {$i<1000} {incr i} {
if {$i%2==0} {set a $i} {set a [expr {($i%8)*100}]}
set b [expr {$i/10}]
set c [expr {$i/8}]
set c [expr {$c*$c*$c}]
db eval {INSERT INTO t1 VALUES($a,$b,$c,$i)}
}
db eval {ANALYZE}
} {}
# The a==100 comparison is expensive because there are many rows
# with a==100. And so for those cases, choose the t1b index.
#
# Buf ro a==99 and a==101, there are far fewer rows so choose
# the t1a index.
#
do_test 1.1 {
eqp {SELECT * FROM t1 WHERE a=100 AND b=55}
} {0 0 0 {SEARCH TABLE t1 USING INDEX t1b (b=?) (~2 rows)}}
do_test 1.2 {
eqp {SELECT * FROM t1 WHERE a=99 AND b=55}
} {0 0 0 {SEARCH TABLE t1 USING INDEX t1a (a=?) (~1 rows)}}
do_test 1.3 {
eqp {SELECT * FROM t1 WHERE a=101 AND b=55}
} {0 0 0 {SEARCH TABLE t1 USING INDEX t1a (a=?) (~1 rows)}}
do_test 1.4 {
eqp {SELECT * FROM t1 WHERE a=100 AND b=56}
} {0 0 0 {SEARCH TABLE t1 USING INDEX t1b (b=?) (~2 rows)}}
do_test 1.5 {
eqp {SELECT * FROM t1 WHERE a=99 AND b=56}
} {0 0 0 {SEARCH TABLE t1 USING INDEX t1a (a=?) (~1 rows)}}
do_test 1.6 {
eqp {SELECT * FROM t1 WHERE a=101 AND b=56}
} {0 0 0 {SEARCH TABLE t1 USING INDEX t1a (a=?) (~1 rows)}}
do_test 2.1 {
eqp {SELECT * FROM t1 WHERE a=100 AND b BETWEEN 50 AND 54}
} {0 0 0 {SEARCH TABLE t1 USING INDEX t1b (b>? AND b<?) (~2 rows)}}
# There are many more values of c between 0 and 100000 than there are
# between 800000 and 900000. So t1c is more selective for the latter
# range.
#
do_test 3.1 {
eqp {SELECT * FROM t1 WHERE b BETWEEN 50 AND 54 AND c BETWEEN 0 AND 100000}
} {0 0 0 {SEARCH TABLE t1 USING INDEX t1b (b>? AND b<?) (~6 rows)}}
do_test 3.2 {
eqp {SELECT * FROM t1
WHERE b BETWEEN 50 AND 54 AND c BETWEEN 800000 AND 900000}
} {0 0 0 {SEARCH TABLE t1 USING INDEX t1c (c>? AND c<?) (~4 rows)}}
do_test 3.3 {
eqp {SELECT * FROM t1 WHERE a=100 AND c BETWEEN 0 AND 100000}
} {0 0 0 {SEARCH TABLE t1 USING INDEX t1a (a=?) (~63 rows)}}
do_test 3.4 {
eqp {SELECT * FROM t1
WHERE a=100 AND c BETWEEN 800000 AND 900000}
} {0 0 0 {SEARCH TABLE t1 USING INDEX t1c (c>? AND c<?) (~2 rows)}}
finish_test
+1 -1
View File
@@ -68,7 +68,7 @@ foreach testfile [lsort -dictionary [glob $testdir/*.test]] {
# Make sure everything is flushed through. This is because [source]ing
# the next test file will delete the database file on disk (using
# [file delete]). If the asynchronous backend still has the file
# [delete_file]). If the asynchronous backend still has the file
# open, it will become confused.
#
flush_async_queue
+1 -1
View File
@@ -51,7 +51,7 @@ foreach err [list ioerr malloc-transient malloc-persistent] {
for {set n 1} {$::go} {incr n} {
set ::sqlite_io_error_pending 0
sqlite3_memdebug_fail -1
file delete -force test.db test.db-journal
forcedelete test.db test.db-journal
sqlite3 db test.db
execsql $::setup_script
db close
+2 -2
View File
@@ -41,8 +41,8 @@ set paths {
do_test async3-1.0 {
file mkdir [file join chocolate banana vanilla]
file delete -force chocolate/banana/vanilla/file.db
file delete -force chocolate/banana/vanilla/file.db-journal
forcedelete chocolate/banana/vanilla/file.db
forcedelete chocolate/banana/vanilla/file.db-journal
} {}
do_test async3-1.1 {
+1 -1
View File
@@ -20,7 +20,7 @@ if {[info commands sqlite3async_initialize] eq ""} {
}
db close
file delete -force test2.db
forcedelete test2.db
sqlite3async_initialize "" 1
sqlite3async_control halt never
sqlite3 db test.db
+11 -11
View File
@@ -24,8 +24,8 @@ ifcapable !attach {
}
for {set i 2} {$i<=15} {incr i} {
file delete -force test$i.db
file delete -force test$i.db-journal
forcedelete test$i.db
forcedelete test$i.db-journal
}
do_test attach-1.1 {
@@ -628,7 +628,7 @@ do_test attach-5.1 {
db close
sqlite3 db test.db
db2 close
file delete -force test2.db
forcedelete test2.db
sqlite3 db2 test2.db
catchsql {
ATTACH DATABASE 'test.db' AS orig;
@@ -725,7 +725,7 @@ if {$tcl_platform(platform)=="unix"} {
file attributes cannot-read -permission 0000
if {[file writable cannot-read]} {
puts "\n**** Tests do not work when run as root ****"
file delete -force cannot-read
forcedelete cannot-read
exit 1
}
catchsql {
@@ -735,7 +735,7 @@ if {$tcl_platform(platform)=="unix"} {
do_test attach-6.2.2 {
db errorcode
} {14}
file delete -force cannot-read
forcedelete cannot-read
}
# Check the error message if we try to access a database that has
@@ -749,12 +749,12 @@ for {set i 2} {$i<=15} {incr i} {
catch {db$i close}
}
db close
file delete -force test2.db
file delete -force no-such-file
forcedelete test2.db
forcedelete no-such-file
ifcapable subquery {
do_test attach-7.1 {
file delete -force test.db test.db-journal
forcedelete test.db test.db-journal
sqlite3 db test.db
catchsql {
DETACH RAISE ( IGNORE ) IN ( SELECT "AAAAAA" . * ORDER BY
@@ -777,7 +777,7 @@ do_test attach-8.1 {
do_test attach-8.2 {
db errorcode
} {26}
file delete -force test2.db
forcedelete test2.db
do_test attach-8.3 {
sqlite3 db2 test2.db
db2 eval {CREATE TABLE t1(x); BEGIN EXCLUSIVE}
@@ -789,13 +789,13 @@ do_test attach-8.4 {
db errorcode
} {5}
db2 close
file delete -force test2.db
forcedelete test2.db
# Test that it is possible to attach the same database more than
# once when not in shared-cache mode. That this is not possible in
# shared-cache mode is tested in shared7.test.
do_test attach-9.1 {
file delete -force test4.db
forcedelete test4.db
execsql {
ATTACH 'test4.db' AS aux1;
CREATE TABLE aux1.t1(a, b);
+4 -4
View File
@@ -33,8 +33,8 @@ do_test attach2-1.1 {
CREATE TABLE t1(a,b);
CREATE INDEX x1 ON t1(a);
}
file delete -force test2.db
file delete -force test2.db-journal
forcedelete test2.db
forcedelete test2.db-journal
sqlite3 db2 test2.db
db2 eval {
CREATE TABLE t1(a,b);
@@ -327,7 +327,7 @@ do_test attach2-4.15 {
db close
db2 close
file delete -force test2.db
forcedelete test2.db
sqlite3_soft_heap_limit $soft_limit
# These tests - attach2-5.* - check that the master journal file is deleted
@@ -335,7 +335,7 @@ sqlite3_soft_heap_limit $soft_limit
#
# Update: It's not actually created if a rollback occurs, so that test
# doesn't really prove too much.
foreach f [glob test.db*] {file delete -force $f}
foreach f [glob test.db*] {forcedelete $f}
do_test attach2-5.1 {
sqlite3 db test.db
execsql {
+2 -2
View File
@@ -35,8 +35,8 @@ execsql {
}
# Create tables t1 and t2 in database file test2.db
file delete -force test2.db
file delete -force test2.db-journal
forcedelete test2.db
forcedelete test2.db-journal
sqlite3 db2 test2.db
execsql {
CREATE TABLE t1(a, b);
+4 -2
View File
@@ -75,10 +75,12 @@ set L [list]
set S ""
foreach {name f} $files {
if {[permutation] == "journaltest"} {
lappend L delete
set mode delete
} else {
lappend L wal
set mode wal
}
ifcapable !wal { set mode delete }
lappend L $mode
append S "
PRAGMA $name.journal_mode = WAL;
UPDATE $name.tbl SET x = '$name';
+4 -4
View File
@@ -29,8 +29,8 @@ do_malloc_test attachmalloc-1 -tclprep {
catch { db close }
for {set i 2} {$i<=4} {incr i} {
catch { db$i close }
file delete -force test$i.db
file delete -force test$i.db-journal
forcedelete test$i.db
forcedelete test$i.db-journal
}
} -tclbody {
if {[catch {sqlite3 db test.db}]} {
@@ -48,8 +48,8 @@ do_malloc_test attachmalloc-1 -tclprep {
}
do_malloc_test attachmalloc-2 -tclprep {
file delete -force test2.db
file delete -force test2.db-journal
forcedelete test2.db
forcedelete test2.db-journal
sqlite3 db2 test2.db
db2 eval {
CREATE TABLE t1(a, b, c);
+4 -4
View File
@@ -2321,10 +2321,10 @@ ifcapable compound&&subquery {
}
}
}
ifcapable stat2 {
set stat2 "sqlite_stat2 "
ifcapable stat3 {
set stat3 "sqlite_stat3 "
} else {
set stat2 ""
set stat3 ""
}
do_test auth-5.2 {
execsql {
@@ -2333,7 +2333,7 @@ ifcapable compound&&subquery {
WHERE type='table'
ORDER BY name
}
} "sqlite_stat1 ${stat2}t1 t2 t3 t4"
} "sqlite_stat1 ${stat3}t1 t2 t3 t4"
}
# Ticket #3944
+3 -3
View File
@@ -427,8 +427,8 @@ ifcapable tempdb {
#
ifcapable tempdb&&attach {
do_test autoinc-5.1 {
file delete -force test2.db
file delete -force test2.db-journal
forcedelete test2.db
forcedelete test2.db-journal
sqlite3 db2 test2.db
execsql {
CREATE TABLE t4(m INTEGER PRIMARY KEY AUTOINCREMENT, n);
@@ -520,7 +520,7 @@ do_test autoinc-7.2 {
do_test autoinc-8.1 {
catch {db2 close}
catch {db close}
file delete -force test.db
forcedelete test.db
sqlite3 db test.db
set DB [sqlite3_connection_pointer db]
set STMT [sqlite3_prepare $DB {
+10
View File
@@ -248,4 +248,14 @@ do_execsql_test autoindex1-600 {
0 1 1 {SEARCH SUBQUERY 1 AS y USING AUTOMATIC COVERING INDEX (sheep_no=?) (~8 rows)}
}
do_execsql_test autoindex1-700 {
CREATE TABLE t5(a, b, c);
EXPLAIN QUERY PLAN SELECT a FROM t5 WHERE b=10 ORDER BY c;
} {
0 0 0 {SCAN TABLE t5 (~100000 rows)}
0 0 0 {USE TEMP B-TREE FOR ORDER BY}
}
finish_test
+4 -4
View File
@@ -467,7 +467,7 @@ do_test autovacuum-3.3 {
do_test autovacuum-3.4 {
db close
file delete -force test.db
forcedelete test.db
sqlite3 db test.db
execsql {
PRAGMA auto_vacuum;
@@ -502,7 +502,7 @@ do_test autovacuum-4.0 {
# Reset everything just in case.
#
db close
file delete -force test.db test.db-journal
forcedelete test.db test.db-journal
sqlite3 db test.db
execsql {
PRAGMA auto_vacuum = 1;
@@ -599,8 +599,8 @@ do_test autovacuum-6.1 {
#
do_test autovacuum-7.1 {
db close
file delete -force test.db
file delete -force test.db-journal
forcedelete test.db
forcedelete test.db-journal
sqlite3 db test.db
execsql {
+4 -4
View File
@@ -75,7 +75,7 @@ do_ioerr_test autovacuum-ioerr2-3 -sqlprep {
DROP TABLE abc2;
}
file delete -force backup.db
forcedelete backup.db
ifcapable subquery {
do_ioerr_test autovacuum-ioerr2-4 -tclprep {
if {![file exists backup.db]} {
@@ -99,9 +99,9 @@ ifcapable subquery {
dbb close
}
db close
file delete -force test.db
file delete -force test.db-journal
copy_file backup.db test.db
forcedelete test.db
forcedelete test.db-journal
forcecopy backup.db test.db
set ::DB [sqlite3 db test.db]
execsql {
PRAGMA cache_size = 10;
+2 -2
View File
@@ -61,7 +61,7 @@ foreach bin $binaries {
proc do_backcompat_test {rv bin1 bin2 script} {
file delete -force test.db
forcedelete test.db
if {$bin1 != ""} { set ::bc_chan1 [launch_testfixture $bin1] }
set ::bc_chan2 [launch_testfixture $bin2]
@@ -152,7 +152,7 @@ proc read_file_system {} {
proc write_file_system {data} {
foreach f {test.db test.db-journal test.db-wal} d $data {
if {[string length $d] == 0} {
file delete -force $f
forcedelete $f
} else {
write_file $f $d
}
+26 -26
View File
@@ -73,7 +73,7 @@ test_contents backup-1.2 db main db main
# Check that it is possible to create and finish backup operations.
#
do_test backup-1.3.1 {
file delete test2.db
delete_file test2.db
sqlite3 db2 test2.db
sqlite3_backup B db2 main db main
} {B}
@@ -168,8 +168,8 @@ foreach pgsz_dest {512 1024 2048} {
foreach nPagePerStep {1 200} {
# Open the databases.
catch { file delete test.db }
catch { file delete test2.db }
catch { delete_file test.db }
catch { delete_file test2.db }
eval $zOpenScript
# Set to true if copying to an in-memory destination. Copying to an
@@ -279,8 +279,8 @@ foreach nSrcPg {10 64 65 66 100} {
foreach nDestRow {10 100} {
foreach nDestPgsz {512 1024 2048 4096} {
catch { file delete test.db }
catch { file delete test2.db }
catch { delete_file test.db }
catch { delete_file test2.db }
sqlite3 db test.db
sqlite3 db2 test2.db
@@ -327,8 +327,8 @@ foreach nDestPgsz {512 1024 2048 4096} {
#--------------------------------------------------------------------
do_test backup-3.$iTest.1 {
catch { file delete -force test.db }
catch { file delete -force test2.db }
catch { forcedelete test.db }
catch { forcedelete test2.db }
sqlite3 db test.db
set iTab 1
@@ -392,8 +392,8 @@ do_test backup-4.1.4 {
} {unknown database aux}
do_test backup-4.2.1 {
catch { file delete -force test3.db }
catch { file delete -force test4.db }
catch { forcedelete test3.db }
catch { forcedelete test4.db }
execsql {
ATTACH 'test3.db' AS aux1;
CREATE TABLE aux1.t1(a, b);
@@ -439,7 +439,7 @@ db close
db2 close
do_test backup-4.5.1 {
catch { file delete -force test.db }
catch { forcedelete test.db }
sqlite3 db test.db
sqlite3 db2 :memory:
execsql {
@@ -491,12 +491,12 @@ db2 close
# 3) Backing up memory-to-file.
#
set iTest 0
file delete -force bak.db-wal
forcedelete bak.db-wal
foreach {writer file} {db test.db db3 test.db db :memory:} {
incr iTest
catch { file delete bak.db }
catch { delete_file bak.db }
sqlite3 db2 bak.db
catch { file delete $file }
catch { delete_file $file }
sqlite3 db $file
sqlite3 db3 $file
@@ -597,9 +597,9 @@ foreach {writer file} {db test.db db3 test.db db :memory:} {
catch {db close}
catch {db2 close}
catch {db3 close}
catch { file delete bak.db }
catch { delete_file bak.db }
sqlite3 db2 bak.db
catch { file delete $file }
catch { delete_file $file }
sqlite3 db $file
sqlite3 db3 $file
do_test backup-5.$iTest.5.1 {
@@ -644,8 +644,8 @@ foreach {writer file} {db test.db db3 test.db db :memory:} {
# Test the sqlite3_backup_remaining() and backup_pagecount() APIs.
#
do_test backup-6.1 {
catch { file delete -force test.db }
catch { file delete -force test2.db }
catch { forcedelete test.db }
catch { forcedelete test2.db }
sqlite3 db test.db
sqlite3 db2 test2.db
execsql {
@@ -701,8 +701,8 @@ catch {db2 close}
# backup-7.3.*: Destination database is externally locked (return SQLITE_BUSY).
#
do_test backup-7.0 {
catch { file delete -force test.db }
catch { file delete -force test2.db }
catch { forcedelete test.db }
catch { forcedelete test2.db }
sqlite3 db2 test2.db
sqlite3 db test.db
execsql {
@@ -754,7 +754,7 @@ integrity_check backup-7.3.6 db2
do_test backup-7.3.1 {
db2 close
db3 close
file delete -force test2.db
forcedelete test2.db
sqlite3 db2 test2.db
sqlite3 db3 test2.db
@@ -783,8 +783,8 @@ catch { db3 close }
# These tests reuse the database "test.db" left over from backup-7.*.
#
do_test backup-8.1 {
catch { file delete -force test2.db }
catch { file delete -force test3.db }
catch { forcedelete test2.db }
catch { forcedelete test3.db }
sqlite3 db2 test2.db
sqlite3 db3 test3.db
@@ -865,8 +865,8 @@ catch {db2 close}
ifcapable memorymanage {
db close
file delete -force test.db
file delete -force bak.db
forcedelete test.db
forcedelete bak.db
sqlite3 db test.db
sqlite3 db2 test.db
@@ -918,7 +918,7 @@ ifcapable memorymanage {
# 10.2.*: If the db is a file, the backup is not restarted.
#
db close
file delete -force test.db test.db-journal
forcedelete test.db test.db-journal
foreach {tn file rc} {
1 test.db SQLITE_DONE
2 :memory: SQLITE_OK
@@ -948,7 +948,7 @@ foreach {tn file rc} {
} {1}
do_test backup-10.$tn.3 {
file delete -force bak.db bak.db-journal
forcedelete bak.db bak.db-journal
sqlite3 db2 bak.db
sqlite3_backup B db2 main db main
B step 50
+9 -9
View File
@@ -61,7 +61,7 @@ set cksum [dbcksum db main]
# is identical to the original.
#
do_test backup2-2 {
file delete -force bu1.db
forcedelete bu1.db
db backup bu1.db
sqlite3 db2 bu1.db
dbcksum db2 main
@@ -72,7 +72,7 @@ do_test backup2-2 {
#
do_test backup2-3.1 {
db close
file delete -force test.db test.db-journal
forcedelete test.db test.db-journal
sqlite3 db test.db
db2 eval {BEGIN EXCLUSIVE}
set rc [catch {db restore bu1.db} res]
@@ -82,7 +82,7 @@ do_test backup2-3.1 {
} {1 {restore failed: source database busy}}
do_test backup2-3.2 {
db close
file delete -force test.db test.db-journal
forcedelete test.db test.db-journal
sqlite3 db test.db
db restore bu1.db
dbcksum db main
@@ -96,7 +96,7 @@ do_test backup2-4 {
} $cksum
do_test backup2-5 {
db2 close
file delete -force bu1.db bu2.db
forcedelete bu1.db bu2.db
db backup temp bu2.db
sqlite3 db2 bu2.db
dbcksum db2 main
@@ -127,7 +127,7 @@ do_test backup2-7 {
# Try to backup database that does not exist
#
do_test backup2-8 {
file delete -force bu1.db
forcedelete bu1.db
set rc [catch {db backup aux1 bu1.db} res]
lappend rc $res
} {1 {backup failed: unknown database aux1}}
@@ -143,7 +143,7 @@ do_test backup2-9 {
#
if {$tcl_platform(platform)=="windows"} {
do_test backup2-10 {
file delete -force bu3.db
forcedelete bu3.db
file mkdir bu3.db
set rc [catch {db restore temp bu3.db} res]
lappend rc $res
@@ -151,7 +151,7 @@ if {$tcl_platform(platform)=="windows"} {
}
if {$tcl_platform(platform)!="windows"} {
do_test backup2-10 {
file delete -force bu3.db
forcedelete bu3.db
file mkdir bu3.db
set rc [catch {db restore temp bu3.db} res]
lappend rc $res
@@ -172,7 +172,7 @@ do_test backup2-12 {
lappend rc $res
} {1 {restore failed: unknown database aux1}}
do_test backup2-13 {
file delete -force bu4.db
forcedelete bu4.db
set rc [catch {db restore bu4.db} res]
lappend rc $res
} {1 {cannot open source database: unable to open database file}}
@@ -184,6 +184,6 @@ do_test backup2-14 {
lappend rc $res
} {1 {wrong # args: should be "db restore ?DATABASE? FILENAME"}}
file delete -force bu1.db bu2.db bu3.db bu4.db
forcedelete bu1.db bu2.db bu3.db bu4.db
finish_test
+3 -3
View File
@@ -60,7 +60,7 @@ do_test backup_ioerr-1.2 {
} {1}
do_test backup_ioerr-1.3 {
db close
file delete -force test.db
forcedelete test.db
} {}
# Turn off IO error simulation.
@@ -155,8 +155,8 @@ for {set iError 1} {$bStop == 0} {incr iError} {
catch { ddb close }
catch { sdb close }
catch { file delete -force test.db }
catch { file delete -force bak.db }
catch { forcedelete test.db }
catch { forcedelete bak.db }
# Open the source and destination databases.
sqlite3 sdb test.db
+4 -4
View File
@@ -697,7 +697,7 @@ if {![sqlite3 -has-codec]} {
# Now test that the library correctly handles bogus entries in the
# sqlite_master table (schema corruption).
do_test capi3-8.1 {
file delete -force test.db test.db-journal
forcedelete test.db test.db-journal
sqlite3 db test.db
execsql {
CREATE TABLE t1(a);
@@ -722,7 +722,7 @@ if {![sqlite3 -has-codec]} {
# Build a 5-field row record. The first field is a string 'table', and
# subsequent fields are all NULL.
db close
file delete -force test.db test.db-journal
forcedelete test.db test.db-journal
sqlite3 db test.db
execsql {
CREATE TABLE t1(a);
@@ -739,8 +739,8 @@ if {![sqlite3 -has-codec]} {
} {1 {malformed database schema (?)}}
db close
}
file delete -force test.db
file delete -force test.db-journal
forcedelete test.db
forcedelete test.db-journal
# Test the english language string equivalents for sqlite error codes
+4 -4
View File
@@ -670,7 +670,7 @@ if {![sqlite3 -has-codec]} {
# Now test that the library correctly handles bogus entries in the
# sqlite_master table (schema corruption).
do_test capi3c-8.1 {
file delete -force test.db test.db-journal
forcedelete test.db test.db-journal
sqlite3 db test.db
execsql {
CREATE TABLE t1(a);
@@ -695,7 +695,7 @@ if {![sqlite3 -has-codec]} {
# Build a 5-field row record. The first field is a string 'table', and
# subsequent fields are all NULL.
db close
file delete -force test.db test.db-journal
forcedelete test.db test.db-journal
sqlite3 db test.db
execsql {
CREATE TABLE t1(a);
@@ -712,8 +712,8 @@ if {![sqlite3 -has-codec]} {
} {1 {malformed database schema (?)}}
db close
}
file delete -force test.db
file delete -force test.db-journal
forcedelete test.db
forcedelete test.db-journal
# Test the english language string equivalents for sqlite error codes
+3 -3
View File
@@ -57,17 +57,17 @@ do_test collate5-1.1 {
execsql {
SELECT DISTINCT a FROM collate5t1;
}
} {A B N}
} {a b n}
do_test collate5-1.2 {
execsql {
SELECT DISTINCT b FROM collate5t1;
}
} {{} Apple apple banana}
} {apple Apple banana {}}
do_test collate5-1.3 {
execsql {
SELECT DISTINCT a, b FROM collate5t1;
}
} {A Apple a apple B banana N {}}
} {a apple A Apple b banana n {}}
# Ticket #3376
#
+1 -1
View File
@@ -44,7 +44,7 @@ do_test collate7-1.4 {
} {2}
do_test collate7-2.1 {
file delete -force test.db test.db-journal
forcedelete test.db test.db-journal
sqlite3 db test.db
sqlite3_create_collation_v2 db CASELESS caseless_cmp {incr ::caseless_del}
execsql {
+10 -22
View File
@@ -15,7 +15,7 @@
#
# $Id: corrupt.test,v 1.12 2009/07/13 09:41:45 danielk1977 Exp $
catch {file delete -force test.db test.db-journal test.bu}
catch {forcedelete test.db test.db-journal test.bu}
set testdir [file dirname $argv0]
source $testdir/tester.tcl
@@ -51,22 +51,10 @@ do_test corrupt-1.1 {
} {}
integrity_check corrupt-1.2
# Copy file $from into $to
#
proc copy_file {from to} {
set f [open $from]
fconfigure $f -translation binary
set t [open $to w]
fconfigure $t -translation binary
puts -nonewline $t [read $f [file size $from]]
close $t
close $f
}
# Setup for the tests. Make a backup copy of the good database in test.bu.
# Create a string of garbage data that is 256 bytes long.
#
copy_file test.db test.bu
forcecopy test.db test.bu
set fsize [file size test.db]
set junk "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
while {[string length $junk]<256} {append junk $junk}
@@ -79,7 +67,7 @@ set junk [string range $junk 0 255]
for {set i [expr {1*256}]} {$i<$fsize-256} {incr i 256} {
set tn [expr {$i/256}]
db close
copy_file test.bu test.db
forcecopy test.bu test.db
set fd [open test.db r+]
fconfigure $fd -translation binary
seek $fd $i
@@ -132,7 +120,7 @@ for {set i [expr {1*256}]} {$i<$fsize-256} {incr i 256} {
#
do_test corrupt-3.1 {
db close
copy_file test.bu test.db
forcecopy test.bu test.db
sqlite3 db test.db
list
} {}
@@ -181,7 +169,7 @@ do_test corrupt-3.6 {
do_test corrupt-4.1 {
db close
file delete -force test.db test.db-journal
forcedelete test.db test.db-journal
sqlite3 db test.db
execsql {
PRAGMA page_size = 1024;
@@ -213,7 +201,7 @@ do_test corrupt-4.2 {
do_test corrupt-5.1 {
db close
file delete -force test.db test.db-journal
forcedelete test.db test.db-journal
sqlite3 db test.db
execsql { PRAGMA page_size = 1024 }
@@ -236,7 +224,7 @@ do_test corrupt-5.2 {
# running this testcase under valgrind revealed the problem.
do_test corrupt-6.1 {
db close
file delete -force test.db test.db-journal
forcedelete test.db test.db-journal
sqlite3 db test.db
execsql {
PRAGMA page_size = 1024; CREATE TABLE t1(x);
@@ -264,7 +252,7 @@ do_test corrupt-6.1 {
ifcapable oversize_cell_check {
db close
file delete -force test.db test.db-journal
forcedelete test.db test.db-journal
sqlite3 db test.db
execsql {
PRAGMA page_size = 1024; CREATE TABLE t1(x);
@@ -317,7 +305,7 @@ ifcapable oversize_cell_check {
}
db close
file delete -force test.db test.db-journal
forcedelete test.db test.db-journal
do_test corrupt-8.1 {
sqlite3 db test.db
execsql {
@@ -335,7 +323,7 @@ do_test corrupt-8.1 {
} {1 {database disk image is malformed}}
db close
file delete -force test.db test.db-journal
forcedelete test.db test.db-journal
do_test corrupt-8.2 {
sqlite3 db test.db
execsql {
+21 -21
View File
@@ -41,9 +41,9 @@ do_test corrupt2-1.1 {
do_test corrupt2-1.2 {
# Corrupt the 16 byte magic string at the start of the file
file delete -force corrupt.db
file delete -force corrupt.db-journal
copy_file test.db corrupt.db
forcedelete corrupt.db
forcedelete corrupt.db-journal
forcecopy test.db corrupt.db
set f [open corrupt.db RDWR]
seek $f 8 start
puts $f blah
@@ -60,9 +60,9 @@ do_test corrupt2-1.3 {
db2 close
# Corrupt the page-size (bytes 16 and 17 of page 1).
file delete -force corrupt.db
file delete -force corrupt.db-journal
copy_file test.db corrupt.db
forcedelete corrupt.db
forcedelete corrupt.db-journal
forcecopy test.db corrupt.db
set f [open corrupt.db RDWR]
fconfigure $f -encoding binary
seek $f 16 start
@@ -80,9 +80,9 @@ do_test corrupt2-1.4 {
db2 close
# Corrupt the free-block list on page 1.
file delete -force corrupt.db
file delete -force corrupt.db-journal
copy_file test.db corrupt.db
forcedelete corrupt.db
forcedelete corrupt.db-journal
forcecopy test.db corrupt.db
set f [open corrupt.db RDWR]
fconfigure $f -encoding binary
seek $f 101 start
@@ -100,9 +100,9 @@ do_test corrupt2-1.5 {
db2 close
# Corrupt the free-block list on page 1.
file delete -force corrupt.db
file delete -force corrupt.db-journal
copy_file test.db corrupt.db
forcedelete corrupt.db
forcedelete corrupt.db-journal
forcecopy test.db corrupt.db
set f [open corrupt.db RDWR]
fconfigure $f -encoding binary
seek $f 101 start
@@ -123,9 +123,9 @@ db2 close
# Corrupt a database by having 2 indices of the same name:
do_test corrupt2-2.1 {
file delete -force corrupt.db
file delete -force corrupt.db-journal
copy_file test.db corrupt.db
forcedelete corrupt.db
forcedelete corrupt.db-journal
forcecopy test.db corrupt.db
sqlite3 db2 corrupt.db
execsql "
@@ -150,8 +150,8 @@ do_test corrupt2-2.1 {
db2 close
do_test corrupt2-3.1 {
file delete -force corrupt.db
file delete -force corrupt.db-journal
forcedelete corrupt.db
forcedelete corrupt.db-journal
sqlite3 db2 corrupt.db
execsql "
@@ -200,8 +200,8 @@ db2 close
unset -nocomplain result
do_test corrupt2-5.1 {
file delete -force corrupt.db
file delete -force corrupt.db-journal
forcedelete corrupt.db
forcedelete corrupt.db-journal
sqlite3 db2 corrupt.db
execsql "
@@ -257,8 +257,8 @@ proc corruption_test {args} {
array set A $args
catch {db close}
file delete -force corrupt.db
file delete -force corrupt.db-journal
forcedelete corrupt.db
forcedelete corrupt.db-journal
sqlite3 db corrupt.db
db eval $::presql
+1 -1
View File
@@ -25,7 +25,7 @@ do_not_use_codec
# We must have the page_size pragma for these tests to work.
#
ifcapable !pager_pragmas {
ifcapable !pager_pragmas||direct_read {
finish_test
return
}
+3 -3
View File
@@ -86,7 +86,7 @@ integrity_check corrupt9-1.2
# Make sure the corruption is detected.
#
db close
file copy -force test.db test.db-template
forcecopy test.db test.db-template
corrupt_freelist test.db 1
sqlite3 db test.db
@@ -103,7 +103,7 @@ do_test corrupt9-2.2 {
db close
file copy -force test.db-template test.db
forcecopy test.db-template test.db
corrupt_freelist test.db 2
sqlite3 db test.db
do_test corrupt9-3.1 {
@@ -118,7 +118,7 @@ do_test corrupt9-3.2 {
} {1 {database disk image is malformed}}
db close
file copy -force test.db-template test.db
forcecopy test.db-template test.db
corrupt_freelist test.db 3
sqlite3 db test.db
do_test corrupt9-4.1 {
+5 -5
View File
@@ -40,12 +40,12 @@ integrity_check corruptA-1.2
# is detected when opening the database file.
#
db close
file copy -force test.db test.db-template
forcecopy test.db test.db-template
set unreadable_version 02
ifcapable wal { set unreadable_version 03 }
do_test corruptA-2.1 {
file copy -force test.db-template test.db
forcecopy test.db-template test.db
hexio_write test.db 19 $unreadable_version ;# the read format number
sqlite3 db test.db
catchsql {SELECT * FROM t1}
@@ -53,7 +53,7 @@ do_test corruptA-2.1 {
do_test corruptA-2.2 {
db close
file copy -force test.db-template test.db
forcecopy test.db-template test.db
hexio_write test.db 21 41 ;# max embedded payload fraction
sqlite3 db test.db
catchsql {SELECT * FROM t1}
@@ -61,7 +61,7 @@ do_test corruptA-2.2 {
do_test corruptA-2.3 {
db close
file copy -force test.db-template test.db
forcecopy test.db-template test.db
hexio_write test.db 22 1f ;# min embedded payload fraction
sqlite3 db test.db
catchsql {SELECT * FROM t1}
@@ -69,7 +69,7 @@ do_test corruptA-2.3 {
do_test corruptA-2.4 {
db close
file copy -force test.db-template test.db
forcecopy test.db-template test.db
hexio_write test.db 23 21 ;# min leaf payload fraction
sqlite3 db test.db
catchsql {SELECT * FROM t1}
+8 -8
View File
@@ -46,7 +46,7 @@ do_test corruptB-1.1 {
} {1}
integrity_check corruptB-1.2
file copy -force test.db bak.db
forcecopy test.db bak.db
# Set the right-child of a B-Tree rootpage to refer to the root-page itself.
#
@@ -65,7 +65,7 @@ do_test corruptB-1.3.2 {
#
do_test corruptB-1.4.1 {
db close
file copy -force bak.db test.db
forcecopy bak.db test.db
set cell_offset [hexio_get_int [hexio_read test.db [expr $offset+12] 2]]
hexio_write test.db [expr $offset+$cell_offset] [hexio_render_int32 $::root]
} {4}
@@ -78,7 +78,7 @@ do_test corruptB-1.4.2 {
#
do_test corruptB-1.5.1 {
db close
file copy -force bak.db test.db
forcecopy bak.db test.db
sqlite3 db test.db
execsql {
INSERT INTO t1 SELECT randomblob(200) FROM t1;
@@ -91,7 +91,7 @@ do_test corruptB-1.5.1 {
}
} {}
file copy -force test.db bak.db
forcecopy test.db bak.db
# Set the right-child pointer of the right-child of the root page to point
# back to the root page.
@@ -112,7 +112,7 @@ do_test corruptB-1.6.2 {
#
do_test corruptB-1.7.1 {
db close
file copy -force bak.db test.db
forcecopy bak.db test.db
set cell_offset [hexio_get_int [hexio_read test.db [expr $c_offset+12] 2]]
hexio_write test.db [expr $c_offset+$cell_offset] [hexio_render_int32 $::root]
} {4}
@@ -140,7 +140,7 @@ do_test corruptB-1.8.2 {
#
do_test corruptB-1.9.1 {
db close
file copy -force bak.db test.db
forcecopy bak.db test.db
set cell_offset [hexio_get_int [hexio_read test.db [expr $c_offset+12] 2]]
hexio_write test.db [expr $c_offset+$cell_offset] [hexio_render_int32 $::root]
} {4}
@@ -153,7 +153,7 @@ do_test corruptB-1.9.2 {
do_test corruptB-2.1.1 {
db close
file copy -force bak.db test.db
forcecopy bak.db test.db
hexio_write test.db [expr $offset+8] [hexio_render_int32 0x6FFFFFFF]
} {4}
do_test corruptB-2.1.2 {
@@ -167,7 +167,7 @@ do_test corruptB-2.1.2 {
#
do_test corruptB-3.1.1 {
db close
file copy -force bak.db test.db
forcecopy bak.db test.db
sqlite3 db test.db
set v [string repeat abcdefghij 200]
execsql {
+18 -24
View File
@@ -17,7 +17,7 @@
#
# $Id: corruptC.test,v 1.14 2009/07/11 06:55:34 danielk1977 Exp $
catch {file delete -force test.db test.db-journal test.bu}
catch {forcedelete test.db test.db-journal test.bu}
set testdir [file dirname $argv0]
source $testdir/tester.tcl
@@ -58,16 +58,10 @@ proc random {range} {
return [expr {round(rand()*$range)}]
}
# Copy file $from into $to
#
proc copy_file {from to} {
file copy -force $from $to
}
# Setup for the tests. Make a backup copy of the good database in test.bu.
#
db close
copy_file test.db test.bu
forcecopy test.db test.bu
sqlite3 db test.db
set fsize [file size test.db]
@@ -92,7 +86,7 @@ expr srand($qseed)
# test that a corrupt content offset size is handled (seed 5577)
do_test corruptC-2.1 {
db close
copy_file test.bu test.db
forcecopy test.bu test.db
# insert corrupt byte(s)
hexio_write test.db 2053 [format %02x 0x04]
@@ -104,7 +98,7 @@ do_test corruptC-2.1 {
# test that a corrupt content offset size is handled (seed 5649)
do_test corruptC-2.2 {
db close
copy_file test.bu test.db
forcecopy test.bu test.db
# insert corrupt byte(s)
hexio_write test.db 27 [format %02x 0x08]
@@ -125,7 +119,7 @@ do_test corruptC-2.2 {
# test that a corrupt free cell size is handled (seed 13329)
do_test corruptC-2.3 {
db close
copy_file test.bu test.db
forcecopy test.bu test.db
# insert corrupt byte(s)
hexio_write test.db 1094 [format %02x 0x76]
@@ -137,7 +131,7 @@ do_test corruptC-2.3 {
# test that a corrupt free cell size is handled (seed 169571)
do_test corruptC-2.4 {
db close
copy_file test.bu test.db
forcecopy test.bu test.db
# insert corrupt byte(s)
hexio_write test.db 3119 [format %02x 0xdf]
@@ -149,7 +143,7 @@ do_test corruptC-2.4 {
# test that a corrupt free cell size is handled (seed 169571)
do_test corruptC-2.5 {
db close
copy_file test.bu test.db
forcecopy test.bu test.db
# insert corrupt byte(s)
hexio_write test.db 3119 [format %02x 0xdf]
@@ -169,7 +163,7 @@ Page 4: btreeInitPage() returns error code 11}}}
# test that a corrupt free cell size is handled (seed 169595)
do_test corruptC-2.6 {
db close
copy_file test.bu test.db
forcecopy test.bu test.db
# insert corrupt byte(s)
hexio_write test.db 619 [format %02x 0xe2]
@@ -182,7 +176,7 @@ do_test corruptC-2.6 {
# corruption (seed 178692)
do_test corruptC-2.7 {
db close
copy_file test.bu test.db
forcecopy test.bu test.db
# insert corrupt byte(s)
hexio_write test.db 3074 [format %02x 0xa0]
@@ -194,7 +188,7 @@ do_test corruptC-2.7 {
# corruption (seed 179069)
do_test corruptC-2.8 {
db close
copy_file test.bu test.db
forcecopy test.bu test.db
# insert corrupt byte(s)
hexio_write test.db 1393 [format %02x 0x7d]
@@ -210,7 +204,7 @@ do_test corruptC-2.8 {
# corruption (seed 170434)
do_test corruptC-2.9 {
db close
copy_file test.bu test.db
forcecopy test.bu test.db
# insert corrupt byte(s)
hexio_write test.db 2095 [format %02x 0xd6]
@@ -222,7 +216,7 @@ do_test corruptC-2.9 {
# corruption (seed 186504)
do_test corruptC-2.10 {
db close
copy_file test.bu test.db
forcecopy test.bu test.db
# insert corrupt byte(s)
hexio_write test.db 3130 [format %02x 0x02]
@@ -234,7 +228,7 @@ do_test corruptC-2.10 {
# corruption (seed 1589)
do_test corruptC-2.11 {
db close
copy_file test.bu test.db
forcecopy test.bu test.db
# insert corrupt byte(s)
hexio_write test.db 55 [format %02x 0xa7]
@@ -246,7 +240,7 @@ do_test corruptC-2.11 {
# corruption (seed 14166)
do_test corruptC-2.12 {
db close
copy_file test.bu test.db
forcecopy test.bu test.db
# insert corrupt byte(s)
hexio_write test.db 974 [format %02x 0x2e]
@@ -258,7 +252,7 @@ do_test corruptC-2.12 {
# corruption (seed 218803)
do_test corruptC-2.13 {
db close
copy_file test.bu test.db
forcecopy test.bu test.db
# insert corrupt byte(s)
hexio_write test.db 102 [format %02x 0x12]
@@ -269,7 +263,7 @@ do_test corruptC-2.13 {
do_test corruptC-2.14 {
db close
copy_file test.bu test.db
forcecopy test.bu test.db
sqlite3 db test.db
set blob [string repeat abcdefghij 10000]
@@ -286,7 +280,7 @@ do_test corruptC-2.14 {
#
do_test corruptC-2.15 {
db close
copy_file test.bu test.db
forcecopy test.bu test.db
hexio_write test.db 986 b9
sqlite3 db test.db
catchsql {SELECT count(*) FROM sqlite_master;}
@@ -300,7 +294,7 @@ for {set tn 0} {$tn<$fsize} {incr tn 1} {
# setup for test
db close
copy_file test.bu test.db
forcecopy test.bu test.db
sqlite3 db test.db
# Seek to a random location in the file, and write a random single byte
+2 -2
View File
@@ -85,7 +85,7 @@ do_test corruptD-1.0 {
DELETE FROM t1 WHERE a = 30;
DELETE FROM t1 WHERE a = 40;
}
copy_file test.db test.bu
forcecopy test.db test.bu
} {}
proc incr_change_counter {} {
@@ -96,7 +96,7 @@ proc incr_change_counter {} {
proc restore_file {} {
db close
copy_file test.bu test.db
forcecopy test.bu test.db
sqlite3 db test.db
}
+6 -14
View File
@@ -16,8 +16,6 @@
#
# $Id: corruptE.test,v 1.14 2009/07/11 06:55:34 danielk1977 Exp $
catch {file delete -force test.db test.db-journal test.bu}
set testdir [file dirname $argv0]
source $testdir/tester.tcl
@@ -60,23 +58,17 @@ ifcapable {integrityck} {
integrity_check corruptE-1.2
}
# Copy file $from into $to
#
proc copy_file {from to} {
file copy -force $from $to
}
# Setup for the tests. Make a backup copy of the good database in test.bu.
#
db close
copy_file test.db test.bu
forcecopy test.db test.bu
sqlite3 db test.db
set fsize [file size test.db]
do_test corruptE-2.1 {
db close
copy_file test.bu test.db
forcecopy test.bu test.db
# insert corrupt byte(s)
hexio_write test.db 2041 [format %02x 0x2e]
@@ -92,7 +84,7 @@ do_test corruptE-2.1 {
do_test corruptE-2.2 {
db close
copy_file test.bu test.db
forcecopy test.bu test.db
# insert corrupt byte(s)
hexio_write test.db 2047 [format %02x 0x84]
@@ -108,7 +100,7 @@ do_test corruptE-2.2 {
do_test corruptE-2.3 {
db close
copy_file test.bu test.db
forcecopy test.bu test.db
# insert corrupt byte(s)
hexio_write test.db 7420 [format %02x 0xa8]
@@ -124,7 +116,7 @@ do_test corruptE-2.3 {
do_test corruptE-2.4 {
db close
copy_file test.bu test.db
forcecopy test.bu test.db
# insert corrupt byte(s)
hexio_write test.db 10233 [format %02x 0xd0]
@@ -165,7 +157,7 @@ set tc 1
foreach test $tests {
do_test corruptE-3.$tc {
db close
copy_file test.bu test.db
forcecopy test.bu test.db
# insert corrupt byte(s)
hexio_write test.db [lindex $test 0] [format %02x [lindex $test 1]]
+3 -3
View File
@@ -215,8 +215,8 @@ for {set i 1} {$i < $repeats} {incr i} {
#
ifcapable attach {
do_test crash-4.0 {
file delete -force test2.db
file delete -force test2.db-journal
forcedelete test2.db
forcedelete test2.db-journal
execsql {
ATTACH 'test2.db' AS aux;
PRAGMA aux.default_cache_size = 10;
@@ -318,7 +318,7 @@ ifcapable attach {
# in test crash-5.3 for details.
#
db close
file delete -force test.db
forcedelete test.db
sqlite3 db test.db
do_test crash-5.1 {
execsql {
+3 -3
View File
@@ -73,7 +73,7 @@ foreach {sql res2} [list \
for {set ii 0} {$ii < 10} {incr ii} {
db close
file delete -force test.db test.db-journal
forcedelete test.db test.db-journal
sqlite3 db test.db
do_test crash3-1.$tn.1 {
execsql {
@@ -106,7 +106,7 @@ foreach {sql res2} [list \
# This block tests both the IOCAP_SEQUENTIAL and IOCAP_SAFE_APPEND flags.
#
db close
file delete -force test.db test.db-journal
forcedelete test.db test.db-journal
sqlite3 db test.db
do_test crash3-2.0 {
execsql {
@@ -177,7 +177,7 @@ foreach {::crashfile ::delay ::char} {
#
for {set ii 0} {$ii < 10} {incr ii} {
db close
file delete -force test.db test.db-journal
forcedelete test.db test.db-journal
crashsql -file test.db -char {sequential atomic} {
CREATE TABLE abc(a, b, c);
}
+1 -1
View File
@@ -63,7 +63,7 @@ foreach cmd $sql_cmd_list {
#
for {set cnt 1; set fin 0} {!$fin} {incr cnt} {
db close
file delete -force test.db test.db-journal
forcedelete test.db test.db-journal
do_test crash4-1.$cnt.1 {
set seed [expr {int(abs(rand()*10000))}]
set delay [expr {int($cnt/50)+1}]
+1 -1
View File
@@ -34,7 +34,7 @@ for {set ii 0} {$ii < 10} {incr ii} {
# Set up the database so that it is an auto-vacuum database
# containing a single table (root page 3) with a single row.
# The row has an overflow page (page 4).
file delete -force test.db test.db-journal
forcedelete test.db test.db-journal
sqlite3 db test.db
set c [string repeat 3 1500]
db eval {
+3 -3
View File
@@ -23,7 +23,7 @@ ifcapable !crashtest {
for {set ii 0} {$ii < 10} {incr ii} {
catch {db close}
file delete -force test.db test.db-journal
forcedelete test.db test.db-journal
crashsql -delay 2 -file test.db {
PRAGMA auto_vacuum=OFF;
PRAGMA page_size=4096;
@@ -40,7 +40,7 @@ for {set ii 0} {$ii < 10} {incr ii} {
for {set ii 0} {$ii < 10} {incr ii} {
catch {db close}
file delete -force test.db test.db-journal
forcedelete test.db test.db-journal
sqlite3 db test.db
execsql {
PRAGMA auto_vacuum=OFF;
@@ -66,7 +66,7 @@ proc signature {} {
#
for {set ii 0} {$ii < 30} {incr ii} {
db close
file delete -force test.db
forcedelete test.db
sqlite3 db test.db
set pagesize [expr 1024 << ($ii % 4)]
+1 -1
View File
@@ -26,7 +26,7 @@ proc signature {} {
foreach f [list test.db test.db-journal] {
for {set ii 1} {$ii < 64} {incr ii} {
db close
file delete test.db
delete_file test.db
sqlite3 db test.db
set from_size [expr 1024 << ($ii&3)]
+7 -7
View File
@@ -243,7 +243,7 @@ do_test crash8-3.11 {
#
ifcapable pragma {
reset_db
file delete -force test2.db
forcedelete test2.db
do_test crash8-4.1 {
execsql {
@@ -336,14 +336,14 @@ ifcapable pragma {
} {def}
do_test crash8-4.10 {
file delete $zMasterJournal
delete_file $zMasterJournal
execsql { SELECT b FROM main.ab WHERE a = 0 }
} {jkl}
}
for {set i 1} {$i < 10} {incr i} {
catch { db close }
file delete -force test.db test.db-journal
forcedelete test.db test.db-journal
sqlite3 db test.db
do_test crash8-5.$i.1 {
execsql {
@@ -367,7 +367,7 @@ for {set i 1} {$i < 10} {incr i} {
} {ok}
catch { db close }
file delete -force test.db test.db-journal
forcedelete test.db test.db-journal
sqlite3 db test.db
do_test crash8-5.$i.2 {
execsql {
@@ -383,9 +383,9 @@ for {set i 1} {$i < 10} {incr i} {
BEGIN;
UPDATE t1 SET x = randomblob(900);
}
file delete -force testX.db testX.db-journal testX.db-wal
copy_file test.db testX.db
copy_file test.db-journal testX.db-journal
forcedelete testX.db testX.db-journal testX.db-wal
forcecopy test.db testX.db
forcecopy test.db-journal testX.db-journal
db close
crashsql -file test.db -delay [expr ($::i%2) + 1] {
+1 -1
View File
@@ -27,7 +27,7 @@ ifcapable autovacuum {
#
for {set av 0} {$av<=$upperBound} {incr av} {
db close
file delete -force test.db test.db-journal
forcedelete test.db test.db-journal
sqlite3 db test.db
# Create a table that spans multiple pages. It is important
+14 -4
View File
@@ -56,6 +56,12 @@ proc lookaside {db} {
}
}
ifcapable stat3 {
set STAT3 1
} else {
set STAT3 0
}
#---------------------------------------------------------------------------
# Run the dbstatus-2 and dbstatus-3 tests with several of different
# lookaside buffer sizes.
@@ -118,7 +124,7 @@ foreach ::lookaside_buffer_size {0 64 120} {
CREATE TABLE t2(c, d);
CREATE VIEW v1 AS SELECT * FROM t1 UNION SELECT * FROM t2;
}
6 {
6y {
CREATE TABLE t1(a, b);
CREATE INDEX i1 ON t1(a);
CREATE INDEX i2 ON t1(a,b);
@@ -155,7 +161,7 @@ foreach ::lookaside_buffer_size {0 64 120} {
# Step 1.
db close
file delete -force test.db
forcedelete test.db
sqlite3 db test.db
sqlite3_db_config_lookaside db 0 $::lookaside_buffer_size 500
db cache size 0
@@ -198,7 +204,11 @@ foreach ::lookaside_buffer_size {0 64 120} {
# much greater than just that reported by DBSTATUS_SCHEMA_USED in this
# case.
#
if {[string match *x $tn] || $AUTOVACUUM} {
# Some of the memory used for sqlite_stat3 is unaccounted for by
# dbstatus.
#
if {[string match *x $tn] || $AUTOVACUUM
|| ([string match *y $tn] && $STAT3)} {
do_test dbstatus-2.$tn.ax { expr {($nSchema1-$nSchema2)<=$nFree} } 1
} else {
do_test dbstatus-2.$tn.a { expr {$nSchema1-$nSchema2} } $nFree
@@ -287,7 +297,7 @@ foreach ::lookaside_buffer_size {0 64 120} {
# Step 1.
db close
file delete -force test.db
forcedelete test.db
sqlite3 db test.db
sqlite3_db_config_lookaside db 0 $::lookaside_buffer_size 500
db cache size 1000
+76
View File
@@ -0,0 +1,76 @@
# 2011 September 20
#
# 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.
#
#***********************************************************************
#
# Tests for the sqlite3_stmt_status() function
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set ::testprefix dbstatus2
do_execsql_test 1.0 {
PRAGMA page_size = 1024;
PRAGMA auto_vacuum = 0;
CREATE TABLE t1(a PRIMARY KEY, b);
INSERT INTO t1 VALUES(1, randomblob(600));
INSERT INTO t1 VALUES(2, randomblob(600));
INSERT INTO t1 VALUES(3, randomblob(600));
}
proc db_hit_miss {db {reset 0}} {
set nHit [sqlite3_db_status $db CACHE_HIT $reset]
set nMiss [sqlite3_db_status $db CACHE_MISS $reset]
list $nHit $nMiss
}
do_test 1.1 {
db close
sqlite3 db test.db
expr {[file size test.db] / 1024}
} 6
do_test 1.2 {
execsql { SELECT b FROM t1 WHERE a=2 }
db_hit_miss db
} {{0 2 0} {0 4 0}}
do_test 1.3 {
execsql { SELECT b FROM t1 WHERE a=2 }
db_hit_miss db
} {{0 6 0} {0 4 0}}
do_test 1.4 {
execsql { SELECT b FROM t1 WHERE a=2 }
db_hit_miss db
} {{0 10 0} {0 4 0}}
do_test 1.5 {
db_hit_miss db 1
} {{0 10 0} {0 4 0}}
do_test 1.6 {
db_hit_miss db 0
} {{0 0 0} {0 0 0}}
do_test 1.7 {
set fd [db incrblob main t1 b 1]
fconfigure $fd -translation binary
set len [string length [read $fd]]
close $fd
set len
} 600
do_test 1.8 { sqlite3_db_status db CACHE_HIT 0 } {0 2 0}
do_test 1.9 { sqlite3_db_status db CACHE_MISS 0 } {0 1 0}
finish_test
+3 -3
View File
@@ -275,7 +275,7 @@ do_test delete-8.0 {
}
} {123}
db close
catch {file delete -force test.db-journal}
catch {forcedelete test.db-journal}
catch {file attributes test.db -permissions 0444}
catch {file attributes test.db -readonly 1}
sqlite3 db test.db
@@ -312,12 +312,12 @@ do_test delete-8.6 {
integrity_check delete-8.7
# Need to do the following for tcl 8.5 on mac. On that configuration, the
# -readonly flag is taken so seriously that a subsequent [file delete -force]
# -readonly flag is taken so seriously that a subsequent [forcedelete]
# (required before the next test file can be executed) will fail.
#
catch {file attributes test.db -readonly 0}
db close
file delete -force test.db test.db-journal
forcedelete test.db test.db-journal
# The following tests verify that SQLite correctly handles the case
# where an index B-Tree is being scanned, the rowid column being read
+3 -3
View File
@@ -297,14 +297,14 @@ do_test descidx1-5.9 {
ifcapable legacyformat {
do_test descidx1-6.1 {
db close
file delete -force test.db test.db-journal
forcedelete test.db test.db-journal
sqlite3 db test.db
execsql {PRAGMA legacy_file_format}
} {1}
} else {
do_test descidx1-6.1 {
db close
file delete -force test.db test.db-journal
forcedelete test.db test.db-journal
sqlite3 db test.db
execsql {PRAGMA legacy_file_format}
} {0}
@@ -328,7 +328,7 @@ ifcapable vacuum {
}
do_test descidx1-6.4 {
db close
file delete -force test.db test.db-journal
forcedelete test.db test.db-journal
sqlite3 db test.db
execsql {PRAGMA legacy_file_format=NO}
execsql {PRAGMA legacy_file_format}
+2 -2
View File
@@ -82,8 +82,8 @@ proc do_diskfull_test {prefix sql} {
do_diskfull_test diskfull-2 VACUUM
# db close
# file delete -force test.db
# file delete -force test.db-journal
# forcedelete test.db
# forcedelete test.db-journal
# sqlite3 db test.db
#
# do_test diskfull-3.1 {
+166
View File
@@ -0,0 +1,166 @@
# 2011 July 1
#
# 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. The
# focus of this script is the DISTINCT modifier.
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix distinct
proc is_distinct_noop {sql} {
set sql1 $sql
set sql2 [string map {DISTINCT ""} $sql]
set program1 [list]
set program2 [list]
db eval "EXPLAIN $sql1" {
if {$opcode != "Noop"} { lappend program1 $opcode }
}
db eval "EXPLAIN $sql2" {
if {$opcode != "Noop"} { lappend program2 $opcode }
}
return [expr {$program1==$program2}]
}
proc do_distinct_noop_test {tn sql} {
uplevel [list do_test $tn [list is_distinct_noop $sql] 1]
}
proc do_distinct_not_noop_test {tn sql} {
uplevel [list do_test $tn [list is_distinct_noop $sql] 0]
}
proc do_temptables_test {tn sql temptables} {
uplevel [list do_test $tn [subst -novar {
set ret ""
db eval "EXPLAIN [set sql]" {
if {$opcode == "OpenEphemeral" || $opcode == "SorterOpen"} {
if {$p5 != "10" && $p5!="00"} { error "p5 = $p5" }
if {$p5 == "10"} {
lappend ret hash
} else {
lappend ret btree
}
}
}
set ret
}] $temptables]
}
#-------------------------------------------------------------------------
# The following tests - distinct-1.* - check that the planner correctly
# detects cases where a UNIQUE index means that a DISTINCT clause is
# redundant. Currently the planner only detects such cases when there
# is a single table in the FROM clause.
#
do_execsql_test 1.0 {
CREATE TABLE t1(a, b, c, d);
CREATE UNIQUE INDEX i1 ON t1(b, c);
CREATE UNIQUE INDEX i2 ON t1(d COLLATE nocase);
CREATE TABLE t2(x INTEGER PRIMARY KEY, y);
CREATE TABLE t3(c1 PRIMARY KEY, c2);
CREATE INDEX i3 ON t3(c2);
}
foreach {tn noop sql} {
1 1 "SELECT DISTINCT b, c FROM t1"
2 1 "SELECT DISTINCT c FROM t1 WHERE b = ?"
3 1 "SELECT DISTINCT rowid FROM t1"
4 1 "SELECT DISTINCT rowid, a FROM t1"
5 1 "SELECT DISTINCT x FROM t2"
6 1 "SELECT DISTINCT * FROM t2"
7 1 "SELECT DISTINCT * FROM (SELECT * FROM t2)"
8 1 "SELECT DISTINCT * FROM t1"
8 0 "SELECT DISTINCT a, b FROM t1"
9 0 "SELECT DISTINCT c FROM t1 WHERE b IN (1,2)"
10 0 "SELECT DISTINCT c FROM t1"
11 0 "SELECT DISTINCT b FROM t1"
12 0 "SELECT DISTINCT a, d FROM t1"
13 0 "SELECT DISTINCT a, b, c COLLATE nocase FROM t1"
14 1 "SELECT DISTINCT a, d COLLATE nocase FROM t1"
15 0 "SELECT DISTINCT a, d COLLATE binary FROM t1"
16 1 "SELECT DISTINCT a, b, c COLLATE binary FROM t1"
16 0 "SELECT DISTINCT t1.rowid FROM t1, t2"
17 0 { /* Technically, it would be possible to detect that DISTINCT
** is a no-op in cases like the following. But SQLite does not
** do so. */
SELECT DISTINCT t1.rowid FROM t1, t2 WHERE t1.rowid=t2.rowid }
18 1 "SELECT DISTINCT c1, c2 FROM t3"
19 1 "SELECT DISTINCT c1 FROM t3"
20 1 "SELECT DISTINCT * FROM t3"
21 0 "SELECT DISTINCT c2 FROM t3"
22 0 "SELECT DISTINCT * FROM (SELECT 1, 2, 3 UNION SELECT 4, 5, 6)"
23 1 "SELECT DISTINCT rowid FROM (SELECT 1, 2, 3 UNION SELECT 4, 5, 6)"
24 0 "SELECT DISTINCT rowid/2 FROM t1"
25 1 "SELECT DISTINCT rowid/2, rowid FROM t1"
26 1 "SELECT DISTINCT rowid/2, b FROM t1 WHERE c = ?"
} {
if {$noop} {
do_distinct_noop_test 1.$tn $sql
} else {
do_distinct_not_noop_test 1.$tn $sql
}
}
#-------------------------------------------------------------------------
# The following tests - distinct-2.* - test cases where an index is
# used to deliver results in order of the DISTINCT expressions.
#
drop_all_tables
do_execsql_test 2.0 {
CREATE TABLE t1(a, b, c);
CREATE INDEX i1 ON t1(a, b);
CREATE INDEX i2 ON t1(b COLLATE nocase, c COLLATE nocase);
INSERT INTO t1 VALUES('a', 'b', 'c');
INSERT INTO t1 VALUES('A', 'B', 'C');
INSERT INTO t1 VALUES('a', 'b', 'c');
INSERT INTO t1 VALUES('A', 'B', 'C');
}
foreach {tn sql temptables res} {
1 "a, b FROM t1" {} {A B a b}
2 "b, a FROM t1" {} {B A b a}
3 "a, b, c FROM t1" {hash} {a b c A B C}
4 "a, b, c FROM t1 ORDER BY a, b, c" {btree} {A B C a b c}
5 "b FROM t1 WHERE a = 'a'" {} {b}
6 "b FROM t1" {hash} {b B}
7 "a FROM t1" {} {A a}
8 "b COLLATE nocase FROM t1" {} {b}
9 "b COLLATE nocase FROM t1 ORDER BY b COLLATE nocase" {} {B}
} {
do_execsql_test 2.$tn.1 "SELECT DISTINCT $sql" $res
do_temptables_test 2.$tn.2 "SELECT DISTINCT $sql" $temptables
}
do_execsql_test 2.A {
SELECT (SELECT DISTINCT o.a FROM t1 AS i) FROM t1 AS o;
} {a A a A}
finish_test
+3 -3
View File
@@ -657,7 +657,7 @@ set sqlite_current_time 0
# EVIDENCE-OF: R-57598-59332 -- syntax diagram expr
#
file delete -force test.db2
forcedelete test.db2
execsql {
ATTACH 'test.db2' AS dbname;
CREATE TABLE dbname.tblname(cname);
@@ -1675,7 +1675,7 @@ db3 close
# Test statements related to the EXISTS and NOT EXISTS operators.
#
catch { db close }
file delete -force test.db
forcedelete test.db
sqlite3 db test.db
do_execsql_test e_expr-34.1 {
@@ -1756,7 +1756,7 @@ foreach {tn e1 e2} {
#
catch { db close }
file delete -force test.db
forcedelete test.db
sqlite3 db test.db
do_test e_expr-35.0 {
execsql {
+2 -2
View File
@@ -60,7 +60,7 @@ foreach {DO_MALLOC_TEST enc} {
# [foreach] loop is testing with OOM errors, disable the lookaside buffer.
#
db close
file delete -force test.db test.db-journal
forcedelete test.db test.db-journal
sqlite3 db test.db
if {$DO_MALLOC_TEST} { sqlite3_db_config_lookaside db 0 0 0 }
db eval "PRAGMA encoding = '$enc'"
@@ -637,7 +637,7 @@ read_test 8.2.2 { PRAGMA table_info(t9c) } {0 c\"1 {} 0 {} 0 1 c'2 {} 0 {} 0}
#
foreach DO_MALLOC_TEST {0 1 2} {
db close
file delete -force test.db test.db-journal
forcedelete test.db test.db-journal
sqlite3 db test.db
if {$DO_MALLOC_TEST} { sqlite3_db_config_lookaside db 0 0 0 }
+6 -6
View File
@@ -1238,8 +1238,8 @@ do_select_tests e_select-5 {
3.1 "SELECT x FROM h2" {One Two Three Four one two three four}
3.2 "SELECT x FROM h1, h2 ON (x=b)" {One one Four four}
4.1 "SELECT DISTINCT x FROM h2" {four one three two}
4.2 "SELECT DISTINCT x FROM h1, h2 ON (x=b)" {four one}
4.1 "SELECT DISTINCT x FROM h2" {One Two Three Four}
4.2 "SELECT DISTINCT x FROM h1, h2 ON (x=b)" {One Four}
}
# EVIDENCE-OF: R-02054-15343 For the purposes of detecting duplicate
@@ -1253,11 +1253,11 @@ do_select_tests e_select-5.5 {
# sequence to compare text values with apply.
#
do_select_tests e_select-5.6 {
1 "SELECT DISTINCT b FROM h1" {I IV four i iv one}
2 "SELECT DISTINCT b COLLATE nocase FROM h1" {four i iv one}
3 "SELECT DISTINCT x FROM h2" {four one three two}
1 "SELECT DISTINCT b FROM h1" {one I i four IV iv}
2 "SELECT DISTINCT b COLLATE nocase FROM h1" {one I four IV}
3 "SELECT DISTINCT x FROM h2" {One Two Three Four}
4 "SELECT DISTINCT x COLLATE binary FROM h2" {
Four One Three Two four one three two
One Two Three Four one two three four
}
}
+13 -13
View File
@@ -142,7 +142,7 @@ set encodings [list UTF-8 UTF-16le UTF-16be]
set sqlite_os_trace 0
set i 1
foreach enc $encodings {
file delete -force test.db
forcedelete test.db
sqlite3 db test.db
db eval "PRAGMA encoding = \"$enc\""
execsql $dbcontents
@@ -172,13 +172,13 @@ foreach enc $encodings {
# encoding to the main database.
ifcapable attach {
do_test enc2-4.1 {
file delete -force test.db
forcedelete test.db
sqlite3 db test.db
db eval "PRAGMA encoding = 'UTF-8'"
db eval "CREATE TABLE abc(a, b, c);"
} {}
do_test enc2-4.2 {
file delete -force test2.db
forcedelete test2.db
sqlite3 db2 test2.db
db2 eval "PRAGMA encoding = 'UTF-16'"
db2 eval "CREATE TABLE abc(a, b, c);"
@@ -206,7 +206,7 @@ proc test_collate {enc lhs rhs} {
return $res
}
file delete -force test.db
forcedelete test.db
sqlite3 db test.db; set DB [sqlite3_connection_pointer db]
do_test enc2-5.0 {
execsql {
@@ -235,7 +235,7 @@ do_test enc2-5.3 {
} {one two three four five UTF-16BE}
db close
file delete -force test.db
forcedelete test.db
sqlite3 db test.db; set DB [sqlite3_connection_pointer db]
execsql {pragma encoding = 'UTF-16LE'}
do_test enc2-5.4 {
@@ -265,7 +265,7 @@ do_test enc2-5.7 {
} {one two three four five UTF-8}
db close
file delete -force test.db
forcedelete test.db
sqlite3 db test.db; set DB [sqlite3_connection_pointer db]
execsql {pragma encoding = 'UTF-16BE'}
do_test enc2-5.8 {
@@ -311,7 +311,7 @@ do_test enc2-5.14 {
} test_collate
db close
file delete -force test.db
forcedelete test.db
do_test enc2-5.15 {
sqlite3 db test.db; set ::DB [sqlite3_connection_pointer db]
@@ -333,7 +333,7 @@ proc test_function {enc arg} {
}
db close
file delete -force test.db
forcedelete test.db
sqlite3 db test.db; set DB [sqlite3_connection_pointer db]
execsql {pragma encoding = 'UTF-8'}
do_test enc2-6.0 {
@@ -366,7 +366,7 @@ do_test enc2-6.3 {
} {{UTF-16BE sqlite}}
db close
file delete -force test.db
forcedelete test.db
sqlite3 db test.db; set DB [sqlite3_connection_pointer db]
execsql {pragma encoding = 'UTF-16LE'}
do_test enc2-6.3 {
@@ -399,7 +399,7 @@ do_test enc2-6.6 {
} {{UTF-16BE sqlite}}
db close
file delete -force test.db
forcedelete test.db
sqlite3 db test.db; set DB [sqlite3_connection_pointer db]
execsql {pragma encoding = 'UTF-16BE'}
do_test enc2-6.7 {
@@ -433,7 +433,7 @@ do_test enc2-6.10 {
db close
file delete -force test.db
forcedelete test.db
# The following tests - enc2-7.* - function as follows:
#
@@ -493,7 +493,7 @@ ifcapable {complete} {
# Test that the encoding of an empty database may still be set after the
# (empty) schema has been initialized.
file delete -force test.db
forcedelete test.db
do_test enc2-9.1 {
sqlite3 db test.db
execsql {
@@ -537,7 +537,7 @@ do_test enc2-9.5 {
#
do_test enc2-10.1 {
db close
file delete -force test.db test.db-journal
forcedelete test.db test.db-journal
sqlite3 db test.db
db eval {
PRAGMA encoding=UTF16;
+2 -2
View File
@@ -81,7 +81,7 @@ ifcapable {bloblit && utf16} {
#
ifcapable {utf16 && shared_cache} {
db close
file delete -force test8.db test8.db-journal
forcedelete test8.db test8.db-journal
set ::enable_shared_cache [sqlite3_enable_shared_cache 1]
sqlite3 dbaux test8.db
sqlite3 db test.db
@@ -100,7 +100,7 @@ ifcapable {utf16 && shared_cache} {
} dbaux
} {1 {attached databases must use the same text encoding as main database}}
dbaux close
file delete -force test8.db test8.db-journal
forcedelete test8.db test8.db-journal
sqlite3_enable_shared_cache $::enable_shared_cache
}
+2 -2
View File
@@ -43,7 +43,7 @@ set vals [list\
set i 1
foreach enc $encodings {
file delete -force test.db
forcedelete test.db
sqlite3 db test.db
db eval "PRAGMA encoding = \"$enc\""
@@ -93,7 +93,7 @@ foreach enc $encodings {
incr i
}
file delete -force test.db
forcedelete test.db
sqlite3 db test.db
do_test enc4-4.1 {
+116
View File
@@ -0,0 +1,116 @@
# 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.
#
#***********************************************************************
# Test that if sqlite3_prepare_v2() is used to prepare a query, the
# error-message associated with an sqlite3_step() error is available
# immediately. Whereas if sqlite3_prepare() is used, it is not available
# until sqlite3_finalize() or sqlite3_reset() has been called.
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix errmsg
# Test organization:
#
# errmsg-1.* User-defined SQL function errors
# errmsg-2.* Errors generated by the VDBE (constraint failures etc.)
# errmsg-3.* SQLITE_SCHEMA and statement recompilation errors.
#
proc error_messages_worker {prepare sql schema} {
set ret [list]
set stmt [$prepare db $sql -1 dummy]
execsql $schema
lappend ret [sqlite3_step $stmt]
lappend ret [sqlite3_errmsg db]
lappend ret [sqlite3_finalize $stmt]
lappend ret [sqlite3_errmsg db]
set ret
}
proc error_messages_v2 {sql {schema {}}} {
error_messages_worker sqlite3_prepare_v2 $sql $schema
}
proc error_messages {sql {schema {}}} {
error_messages_worker sqlite3_prepare $sql $schema
}
proc sql_error {msg} { error $msg }
db func sql_error sql_error
#-------------------------------------------------------------------------
# Test error messages returned by user-defined SQL functions.
#
do_test 1.1 {
error_messages "SELECT sql_error('custom message')"
} [list {*}{
SQLITE_ERROR {SQL logic error or missing database}
SQLITE_ERROR {custom message}
}]
do_test 1.2 {
error_messages_v2 "SELECT sql_error('custom message')"
} [list {*}{
SQLITE_ERROR {custom message}
SQLITE_ERROR {custom message}
}]
#-------------------------------------------------------------------------
# Test error messages generated directly by VDBE code (e.g. constraint
# failures).
#
do_execsql_test 2.1 {
CREATE TABLE t1(a PRIMARY KEY, b UNIQUE);
INSERT INTO t1 VALUES('abc', 'def');
}
do_test 2.2 {
error_messages "INSERT INTO t1 VALUES('ghi', 'def')"
} [list {*}{
SQLITE_ERROR {SQL logic error or missing database}
SQLITE_CONSTRAINT {column b is not unique}
}]
do_test 2.3 {
error_messages_v2 "INSERT INTO t1 VALUES('ghi', 'def')"
} [list {*}{
SQLITE_CONSTRAINT {column b is not unique}
SQLITE_CONSTRAINT {column b is not unique}
}]
#-------------------------------------------------------------------------
# Test SQLITE_SCHEMA errors. And, for _v2(), test that if the schema
# change invalidates the SQL statement itself the error message is returned
# correctly.
#
do_execsql_test 3.1.1 {
CREATE TABLE t2(a PRIMARY KEY, b UNIQUE);
INSERT INTO t2 VALUES('abc', 'def');
}
do_test 3.1.2 {
error_messages "SELECT a FROM t2" "DROP TABLE t2"
} [list {*}{
SQLITE_ERROR {SQL logic error or missing database}
SQLITE_SCHEMA {database schema has changed}
}]
do_execsql_test 3.2.1 {
CREATE TABLE t2(a PRIMARY KEY, b UNIQUE);
INSERT INTO t2 VALUES('abc', 'def');
}
do_test 3.2.2 {
error_messages_v2 "SELECT a FROM t2" "DROP TABLE t2"
} [list {*}{
SQLITE_ERROR {no such table: t2}
SQLITE_ERROR {no such table: t2}
}]
finish_test
+8 -8
View File
@@ -22,12 +22,12 @@ ifcapable {!pager_pragmas} {
return
}
file delete -force test2.db-journal
file delete -force test2.db
file delete -force test3.db-journal
file delete -force test3.db
file delete -force test4.db-journal
file delete -force test4.db
forcedelete test2.db-journal
forcedelete test2.db
forcedelete test3.db-journal
forcedelete test3.db
forcedelete test4.db-journal
forcedelete test4.db
#----------------------------------------------------------------------
# Test cases exclusive-1.X test the PRAGMA logic.
@@ -481,8 +481,8 @@ do_execsql_test exclusive-6.1 {
}
do_test exclusive-6.2 {
forcedelete test2.db test2.db-journal
file copy test.db test2.db
file copy test.db-journal test2.db-journal
copy_file test.db test2.db
copy_file test.db-journal test2.db-journal
sqlite3 db test2.db
} {}
+2 -2
View File
@@ -259,8 +259,8 @@ do_test exclusive2-2.8 {
db close
catch {close $::fd}
file delete -force test.db
file delete -force test.db-journal
forcedelete test.db
forcedelete test.db-journal
do_test exclusive2-3.0 {
sqlite3 db test.db
+1 -1
View File
@@ -159,7 +159,7 @@ foreach jm {rollback wal} {
sql1 { DROP INDEX IF EXISTS i2 }
sql2 { CREATE INDEX aux.i2 ON t2(x) }
sql1 { DROP INDEX IF EXISTS i2 }
sql2 { SELECT name FROM aux.sqlite_master WHERE type = 'index' }
sql2 { SELECT * FROM aux.sqlite_master WHERE type = 'index' }
} {}
# VIEW objects.
+1 -1
View File
@@ -79,7 +79,7 @@ ifcapable !wal { set skipwaltests 1 }
if {!$skipwaltests} {
db close
file delete -force test.db
forcedelete test.db
sqlite3 db test.db
file_control_chunksize_test db main [expr 32*1024]
+1 -1
View File
@@ -37,5 +37,5 @@ do_test filectrl-1.5 {
file_control_lockproxy_test db [pwd]
} {}
db close
file delete -force .test_control_lockproxy.db-conch test.proxy
forcedelete .test_control_lockproxy.db-conch test.proxy
finish_test
+5 -5
View File
@@ -23,7 +23,7 @@ source $testdir/tester.tcl
do_not_use_codec
db close
file delete -force test.db test.db-journal
forcedelete test.db test.db-journal
# Database begins with valid 16-byte header string.
#
@@ -63,7 +63,7 @@ ifcapable pager_pragmas {
&& $pagesize>$SQLITE_MAX_PAGE_SIZE} continue
do_test filefmt-1.5.$pagesize.1 {
db close
file delete -force test.db
forcedelete test.db
sqlite3 db test.db
db eval "PRAGMA auto_vacuum=OFF"
db eval "PRAGMA page_size=$pagesize"
@@ -105,7 +105,7 @@ do_test filefmt-1.7 {
ifcapable pager_pragmas {
do_test filefmt-1.8 {
db close
file delete -force test.db
forcedelete test.db
sqlite3 db test.db
db eval {PRAGMA page_size=512; CREATE TABLE t1(x)}
db close
@@ -125,7 +125,7 @@ ifcapable pager_pragmas {
# always derives this from the size of the file.
#
db close
file delete -force test.db
forcedelete test.db
set a_string_counter 1
proc a_string {n} {
@@ -157,7 +157,7 @@ integrity_check filefmt-2.1.5
do_test filefmt-2.1.6 { hexio_read test.db 28 4 } {00000010}
db close
file delete -force test.db
forcedelete test.db
sqlite3 db test.db
db func a_string a_string
+1 -1
View File
@@ -68,7 +68,7 @@ proc catch_fk_error {zSql} {
if {[string match {*foreign key*} $msg]} {
return ""
}
if {$msg eq "out of memory"} {
if {$msg eq "out of memory" || $msg eq "constraint failed"} {
error 1
}
error $msg
+59
View File
@@ -0,0 +1,59 @@
# 2011 October 13
#
# 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 the FTS SQLite module.
#
# This file implements tests to verify that ticket [9fd058691] has been
# fixed.
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
# If SQLITE_ENABLE_FTS3 is defined, omit this file.
ifcapable !fts3 {
finish_test
return
}
set ::testprefix fts3-9fd058691
do_execsql_test 1.0 {
CREATE VIRTUAL TABLE fts USING fts3( tags TEXT);
INSERT INTO fts (tags) VALUES ('tag1');
SELECT * FROM fts WHERE tags MATCH 'tag1';
} {tag1}
do_test 1.1 {
db close
sqlite3 db test.db
execsql {
UPDATE fts SET tags = 'tag1' WHERE rowid = 1;
SELECT * FROM fts WHERE tags MATCH 'tag1';
}
} {tag1}
db close
forcedelete test.db
sqlite3 db test.db
do_execsql_test 2.0 {
CREATE VIRTUAL TABLE fts USING fts3(tags TEXT);
INSERT INTO fts (docid, tags) VALUES (1, 'tag1');
INSERT INTO fts (docid, tags) VALUES (2, NULL);
INSERT INTO fts (docid, tags) VALUES (3, 'three');
} {}
do_test 2.1 {
execsql {
UPDATE fts SET tags = 'two' WHERE rowid = 2;
SELECT * FROM fts WHERE tags MATCH 'two';
}
} {two}
finish_test
+3 -3
View File
@@ -19,8 +19,8 @@ ifcapable !fts1 {
}
# Clean up anything left over from a previous pass.
file delete -force test2.db
file delete -force test2.db-journal
forcedelete test2.db
forcedelete test2.db-journal
sqlite3 db2 test2.db
db eval {
@@ -84,6 +84,6 @@ do_test fts1j-1.3 {
catch {db eval {DETACH DATABASE two}}
catch {db2 close}
file delete -force test2.db
forcedelete test2.db
finish_test
+1 -1
View File
@@ -95,7 +95,7 @@ do_test fts1o-3.6 {
# Test that it is possible to rename an fts1 table in an attached
# database.
#
file delete -force test2.db test2.db-journal
forcedelete test2.db test2.db-journal
do_test fts1o-4.1 {
execsql {
+3 -3
View File
@@ -19,8 +19,8 @@ ifcapable !fts2 {
}
# Clean up anything left over from a previous pass.
file delete -force test2.db
file delete -force test2.db-journal
forcedelete test2.db
forcedelete test2.db-journal
sqlite3 db2 test2.db
db eval {
@@ -84,6 +84,6 @@ do_test fts2j-1.3 {
catch {db eval {DETACH DATABASE two}}
catch {db2 close}
file delete -force test2.db
forcedelete test2.db
finish_test
+2 -2
View File
@@ -109,7 +109,7 @@ do_test fts2o-2.12 {
# be run on an initially empty db.
#
db close
file delete -force test.db test.db-journal
forcedelete test.db test.db-journal
sqlite3 db test.db
do_test fts2o-3.1 {
@@ -134,7 +134,7 @@ do_test fts2o-3.2 {
# Test that it is possible to rename an fts2 table in an attached
# database.
#
file delete -force test2.db test2.db-journal
forcedelete test2.db test2.db-journal
do_test fts2o-3.1 {
execsql {
+3 -3
View File
@@ -19,8 +19,8 @@ ifcapable !fts3 {
}
# Clean up anything left over from a previous pass.
file delete -force test2.db
file delete -force test2.db-journal
forcedelete test2.db
forcedelete test2.db-journal
sqlite3 db2 test2.db
db eval {
@@ -84,6 +84,6 @@ do_test fts3aj-1.3 {
catch {db eval {DETACH DATABASE two}}
catch {db2 close}
file delete -force test2.db
forcedelete test2.db
finish_test
+5 -2
View File
@@ -111,7 +111,7 @@ do_test fts3ao-2.12 {
# be run on an initially empty db.
#
db close
file delete -force test.db test.db-journal
forcedelete test.db test.db-journal
sqlite3 db test.db
do_test fts3ao-3.1 {
@@ -136,7 +136,7 @@ do_test fts3ao-3.2 {
# Test that it is possible to rename an fts3 table in an attached
# database.
#
file delete -force test2.db test2.db-journal
forcedelete test2.db test2.db-journal
do_test fts3ao-3.1 {
execsql {
@@ -200,6 +200,9 @@ do_test fts3ao-4.7 {
SELECT * FROM t5;
}
} {{the quick brown fox} {jumped over the} {lazy dog}}
do_execsql_test fts3ao-4.8 {
SELECT snippet(t5, '[', ']') FROM t5 WHERE t5 MATCH 'the'
} {{[the] quick brown fox} {jumped over [the]}}
# Test that it is possible to rename an FTS4 table. Renaming an FTS4 table
# involves renaming the extra %_docsize and %_stat tables.
+49 -3
View File
@@ -107,15 +107,17 @@ proc do_fts3query_test {tn args} {
" $matchinfo_asc
}
# fts3_make_deferrable TABLE TOKEN
# fts3_make_deferrable TABLE TOKEN ?NROW?
#
proc fts3_make_deferrable {tbl token} {
proc fts3_make_deferrable {tbl token {nRow 0}} {
set stmt [sqlite3_prepare db "SELECT * FROM $tbl" -1 dummy]
set name [sqlite3_column_name $stmt 0]
sqlite3_finalize $stmt
set nRow [db one "SELECT count(*) FROM $tbl"]
if {$nRow==0} {
set nRow [db one "SELECT count(*) FROM $tbl"]
}
set pgsz [db one "PRAGMA page_size"]
execsql BEGIN
for {set i 0} {$i < ($nRow * $pgsz * 1.2)/100} {incr i} {
@@ -653,6 +655,50 @@ foreach {tn pending create} {
catchsql { COMMIT }
}
foreach {tn create} {
1 "fts4(x)"
2 "fts4(x, order=DESC)"
} {
execsql [subst {
DROP TABLE IF EXISTS t1;
CREATE VIRTUAL TABLE t1 USING $create;
}]
foreach {x} {
"F E N O T K X V A X I E X A P G Q V H U"
"R V A E T C V Q N I E L O N U G J K L U"
"U Y I G W M V F J L X I D C H F P J Q B"
"S G D Z X R P G S S Y B K A S G A I L L"
"L S I C H T Z S R Q P R N K J X L F M J"
"C C C D P X B Z C M A D A C X S B T X V"
"W Y J M D R G V R K B X S A W R I T N C"
"P K L W T M S P O Y Y V V O E H Q A I R"
"C D Y I C Z F H J C O Y A Q F L S B D K"
"P G S C Y C Y V I M B D S Z D D Y W I E"
"Z K Z U E E S F Y X T U A L W O U J C Q"
"P A T Z S W L P L Q V Y Y I P W U X S S"
"I U I H U O F Z F R H R F T N D X A G M"
"N A B M S H K X S O Y D T X S B R Y H Z"
"L U D A S K I L S V Z J P U B E B Y H M"
} {
execsql { INSERT INTO t1 VALUES($x) }
}
# Add extra documents to the database such that token "B" will be considered
# deferrable if considering the other tokens means that 2 or fewer documents
# will be loaded into memory.
#
fts3_make_deferrable t1 B 2
# B is not deferred in either of the first two tests below, since filtering
# on "M" or "D" returns 10 documents or so. But filtering on "M * D" only
# returns 2, so B is deferred in this case.
#
do_fts3query_test 7.$tn.1 t1 {"M B"}
do_fts3query_test 7.$tn.2 t1 {"B D"}
do_fts3query_test 7.$tn.3 -deferred B t1 {"M B D"}
}
set sqlite_fts3_enable_parentheses $sfep
finish_test
+53
View File
@@ -304,4 +304,57 @@ do_test fts3d-5.1 {
}
} {{Index already optimal} 2 0}
# ALTER TABLE RENAME should work regardless of the database encoding.
#
do_test fts3d-6.0 {
db close
forcedelete test.db
sqlite3 db test.db
db eval {
PRAGMA encoding=UTF8;
CREATE VIRTUAL TABLE fts USING fts3(a,b,c);
SELECT name FROM sqlite_master WHERE name GLOB '???_*' ORDER BY 1;
}
} {fts_content fts_segdir fts_segments}
do_test fts3d-6.1 {
db eval {
ALTER TABLE fts RENAME TO xyz;
SELECT name FROM sqlite_master WHERE name GLOB '???_*' ORDER BY 1;
}
} {xyz_content xyz_segdir xyz_segments}
do_test fts3d-6.2 {
db close
forcedelete test.db
sqlite3 db test.db
db eval {
PRAGMA encoding=UTF16le;
CREATE VIRTUAL TABLE fts USING fts3(a,b,c);
SELECT name FROM sqlite_master WHERE name GLOB '???_*' ORDER BY 1;
}
} {fts_content fts_segdir fts_segments}
do_test fts3d-6.3 {
db eval {
ALTER TABLE fts RENAME TO xyz;
SELECT name FROM sqlite_master WHERE name GLOB '???_*' ORDER BY 1;
}
} {xyz_content xyz_segdir xyz_segments}
do_test fts3d-6.4 {
db close
forcedelete test.db
sqlite3 db test.db
db eval {
PRAGMA encoding=UTF16be;
CREATE VIRTUAL TABLE fts USING fts3(a,b,c);
SELECT name FROM sqlite_master WHERE name GLOB '???_*' ORDER BY 1;
}
} {fts_content fts_segdir fts_segments}
do_test fts3d-6.5 {
db eval {
ALTER TABLE fts RENAME TO xyz;
SELECT name FROM sqlite_master WHERE name GLOB '???_*' ORDER BY 1;
}
} {xyz_content xyz_segdir xyz_segments}
finish_test
+40
View File
@@ -426,6 +426,18 @@ foreach {tn setup} {
SELECT rowid FROM t1 WHERE t1 MATCH '"jk xduvfhk" OR "zm azavwm"'
} {8 15 26 92 96}
}
if {$tn>1} {
# These tests will not work with $tn==1, as in this case table t1 is
# created using FTS3. The ^ syntax is only available with FTS4 tables.
#
do_select_test 7.1 {
SELECT rowid FROM t1 WHERE t1 MATCH '^zm mjpavjuhw'
} {56 62}
do_select_test 7.2 {
SELECT rowid FROM t1 WHERE t1 MATCH '^azavwm zm'
} {43}
}
}
set testprefix fts3defer
@@ -449,5 +461,33 @@ do_execsql_test 3.3 {
SELECT count(*) FROM x1 WHERE x1 MATCH '"d e f"'
} {16}
# At one point the following was causing a floating-point exception.
#
do_execsql_test 4.1 {
CREATE VIRTUAL TABLE x2 USING FTS4(x);
BEGIN;
INSERT INTO x2 VALUES('m m m m m m m m m m m m m m m m m m m m m m m m m m');
INSERT INTO x2 SELECT * FROM x2;
INSERT INTO x2 SELECT * FROM x2;
INSERT INTO x2 SELECT * FROM x2;
INSERT INTO x2 SELECT * FROM x2;
INSERT INTO x2 SELECT * FROM x2;
INSERT INTO x2 SELECT * FROM x2;
INSERT INTO x2 SELECT * FROM x2;
INSERT INTO x2 SELECT * FROM x2;
INSERT INTO x2 SELECT * FROM x2;
INSERT INTO x2 SELECT * FROM x2;
INSERT INTO x2 SELECT * FROM x2;
INSERT INTO x2 SELECT * FROM x2;
INSERT INTO x2 SELECT * FROM x2;
INSERT INTO x2 SELECT * FROM x2;
INSERT INTO x2 SELECT * FROM x2;
INSERT INTO x2 VALUES('a b c d e f g h i j k l m n o p q r s t u v w x y m');
COMMIT;
}
do_execsql_test 4.2 {
SELECT * FROM x2 WHERE x2 MATCH 'a b c d e f g h i j k l m n o p q r s';
} {{a b c d e f g h i j k l m n o p q r s t u v w x y m}}
finish_test
+61
View File
@@ -0,0 +1,61 @@
# 2011 October 29
#
# 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. The
# focus of this script is testing the FTS3 module. More specifically,
# that DROP TABLE commands can co-exist with savepoints inside transactions.
# See ticket [48f299634a] for details.
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix fts3drop
# If SQLITE_ENABLE_FTS3 is defined, omit this file.
ifcapable !fts3 {
finish_test
return
}
do_execsql_test 1.1 {
CREATE VIRTUAL TABLE f1 USING fts3;
INSERT INTO f1 VALUES('a b c');
}
do_execsql_test 1.2 {
BEGIN;
INSERT INTO f1 VALUES('d e f');
SAVEPOINT one;
INSERT INTO f1 VALUES('g h i');
DROP TABLE f1;
ROLLBACK TO one;
COMMIT;
}
do_execsql_test 1.3 {
SELECT * FROM f1;
} {{a b c} {d e f}}
do_execsql_test 1.4 {
BEGIN;
INSERT INTO f1 VALUES('g h i');
SAVEPOINT one;
INSERT INTO f1 VALUES('j k l');
DROP TABLE f1;
RELEASE one;
ROLLBACK;
}
do_execsql_test 1.5 {
SELECT * FROM f1;
} {{a b c} {d e f}}
finish_test
+4 -6
View File
@@ -18,8 +18,6 @@ set ::testprefix fts3fault
# If SQLITE_ENABLE_FTS3 is not defined, omit this file.
ifcapable !fts3 { finish_test ; return }
if 1 {
# Test error handling in the sqlite3Fts3Init() function. This is the
# function that registers the FTS3 module and various support functions
# with SQLite.
@@ -146,7 +144,8 @@ do_faultsim_test 7.2 -prep {
execsql { CREATE VIRTUAL TABLE t1 USING fts4(a, b, matchinfo=fs3) }
} -test {
faultsim_test_result {1 {unrecognized matchinfo: fs3}} \
{1 {vtable constructor failed: t1}}
{1 {vtable constructor failed: t1}} \
{1 {SQL logic error or missing database}}
}
do_faultsim_test 7.3 -prep {
faultsim_delete_and_reopen
@@ -154,9 +153,8 @@ do_faultsim_test 7.3 -prep {
execsql { CREATE VIRTUAL TABLE t1 USING fts4(a, b, matchnfo=fts3) }
} -test {
faultsim_test_result {1 {unrecognized parameter: matchnfo=fts3}} \
{1 {vtable constructor failed: t1}}
}
{1 {vtable constructor failed: t1}} \
{1 {SQL logic error or missing database}}
}
proc mit {blob} {
+49
View File
@@ -82,4 +82,53 @@ do_faultsim_test 2.1 -prep {
faultsim_test_result {0 {a * 1 1 a 0 1 1 b * 1 1 b 0 1 1 c * 1 1 c 0 1 1 x * 1 1 x 1 1 1 y * 1 1 y 1 1 1 z * 1 1 z 1 1 1}}
}
do_faultsim_test 3.0 -faults oom* -prep {
faultsim_delete_and_reopen
db eval { CREATE TABLE 'xx yy'(a, b); }
} -body {
execsql {
CREATE VIRTUAL TABLE tt USING fts4(content="xx yy");
}
} -test {
faultsim_test_result {0 {}}
}
do_faultsim_test 3.1 -faults oom* -prep {
faultsim_delete_and_reopen
db func zip zip
db func unzip unzip
} -body {
execsql {
CREATE VIRTUAL TABLE tt USING fts4(compress=zip, uncompress=unzip);
}
} -test {
faultsim_test_result {0 {}}
}
do_test 4.0 {
faultsim_delete_and_reopen
execsql {
CREATE VIRTUAL TABLE ft USING fts4(a, b);
INSERT INTO ft VALUES('U U T C O', 'F N D E S');
INSERT INTO ft VALUES('P H X G B', 'I D M R U');
INSERT INTO ft VALUES('P P X D M', 'Y V N T C');
INSERT INTO ft VALUES('Z L Q O W', 'D F U N Q');
INSERT INTO ft VALUES('A J D U P', 'C H M Q E');
INSERT INTO ft VALUES('P S A O H', 'S Z C W D');
INSERT INTO ft VALUES('T B N L W', 'C A K T I');
INSERT INTO ft VALUES('K E Z L O', 'L L Y C E');
INSERT INTO ft VALUES('C R E S V', 'Q V F W P');
INSERT INTO ft VALUES('S K H G W', 'R W Q F G');
}
faultsim_save_and_close
} {}
do_faultsim_test 4.1 -prep {
faultsim_restore_and_reopen
db eval {SELECT * FROM sqlite_master}
} -body {
execsql { INSERT INTO ft(ft) VALUES('rebuild') }
} -test {
faultsim_test_result {0 {}}
}
finish_test
+163
View File
@@ -0,0 +1,163 @@
# 2011 October 18
#
# 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.
#
#***********************************************************************
set testdir [file dirname $argv0]
source $testdir/tester.tcl
source $testdir/malloc_common.tcl
ifcapable !fts3 {
finish_test
return
}
set testprefix fts3first
proc lreverse {L} {
set res [list]
for {set ii [expr [llength $L]-1]} {$ii>=0} {incr ii -1} {
lappend res [lindex $L $ii]
}
set res
}
proc mit {blob} {
set scan(littleEndian) i*
set scan(bigEndian) I*
binary scan $blob $scan($::tcl_platform(byteOrder)) r
return $r
}
db func mit mit
do_execsql_test 1.0 {
CREATE VIRTUAL TABLE x1 USING FTS4(a, b, c);
INSERT INTO x1(docid,a,b,c) VALUES(0, 'K H D S T', 'V M N Y K', 'S Z N Q S');
INSERT INTO x1(docid,a,b,c) VALUES(1, 'K N J L W', 'S Z W J Q', 'D U W S E');
INSERT INTO x1(docid,a,b,c) VALUES(2, 'B P M O I', 'R P H W S', 'R J L L E');
INSERT INTO x1(docid,a,b,c) VALUES(3, 'U R Q M L', 'M J K A V', 'Q W J T J');
INSERT INTO x1(docid,a,b,c) VALUES(4, 'N J C Y N', 'R U D X V', 'B O U A Q');
INSERT INTO x1(docid,a,b,c) VALUES(5, 'Q L X L U', 'I F N X S', 'U Q A N Y');
INSERT INTO x1(docid,a,b,c) VALUES(6, 'M R G U T', 'U V I Q P', 'X Y D L S');
INSERT INTO x1(docid,a,b,c) VALUES(7, 'D Y P O I', 'X J P K R', 'V O T H V');
INSERT INTO x1(docid,a,b,c) VALUES(8, 'R Y D L R', 'U U E S J', 'N W L M R');
INSERT INTO x1(docid,a,b,c) VALUES(9, 'Z P F N P', 'W A X D U', 'V A E Q A');
INSERT INTO x1(docid,a,b,c) VALUES(10, 'Q I A Q M', 'N D K H C', 'A H T Q Z');
INSERT INTO x1(docid,a,b,c) VALUES(11, 'T E R Q B', 'C I B C B', 'F Z U W R');
INSERT INTO x1(docid,a,b,c) VALUES(12, 'E S V U W', 'T P F W H', 'A M D J Q');
INSERT INTO x1(docid,a,b,c) VALUES(13, 'X S B X Y', 'U D N D P', 'X Z Y G F');
INSERT INTO x1(docid,a,b,c) VALUES(14, 'K H A B L', 'S R C C Z', 'D W E H J');
INSERT INTO x1(docid,a,b,c) VALUES(15, 'C E U C C', 'W F M N M', 'T Z U X T');
INSERT INTO x1(docid,a,b,c) VALUES(16, 'Q G C G H', 'H N N B H', 'B Q I H Y');
INSERT INTO x1(docid,a,b,c) VALUES(17, 'Q T S K B', 'W B D Y N', 'V J P E C');
INSERT INTO x1(docid,a,b,c) VALUES(18, 'A J M O Q', 'L G Y Y A', 'G N M R N');
INSERT INTO x1(docid,a,b,c) VALUES(19, 'T R Y P Y', 'N V Y B X', 'L Z T N T');
CREATE VIRTUAL TABLE x2 USING FTS4(a, b, c, order=DESC);
INSERT INTO x2(docid, a, b, c) SELECT docid, a, b, c FROM x1;
}
# Test queries.
#
foreach x {1 2} {
foreach {tn match res} {
1 "^K" {0 1 14}
2 "^S" {0 1 14}
3 "^W" {9 15 17}
4 "^J" {}
5 "^E" {12}
6 "V ^-E" {0 3 4 6 7 9 17 19}
7 "V -^E" {0 3 4 6 7 9 17 19}
8 "^-E V" {0 3 4 6 7 9 17 19}
9 "-^E V" {0 3 4 6 7 9 17 19}
10 "V" {0 3 4 6 7 9 12 17 19}
11 {"^K H"} {0 14}
12 {"K H"} {0 10 14}
13 {"K ^H"} {}
} {
set rev [lreverse $res]
do_execsql_test 1.$x.$tn.1 {SELECT docid FROM x1 WHERE x1 MATCH $match} $res
do_execsql_test 1.$x.$tn.2 {SELECT docid FROM x2 WHERE x2 MATCH $match} $rev
}
do_execsql_test 1.$x.[expr $tn+1] {
INSERT INTO x1(x1) VALUES('optimize');
INSERT INTO x2(x2) VALUES('optimize');
} {}
}
# Test the snippet() function.
#
foreach {tn match res} {
1 {^K} {{[K] H D S T} {[K] N J L W} {[K] H A B L}}
2 {^X} {{[X] Y D L S} {[X] J P K R} {[X] S B X Y}}
3 {^X Y} {{[X] [Y] D L S} {D [Y] P O I...[X] J P K R} {[X] S B X [Y]}}
} {
set rev [lreverse $res]
do_execsql_test 1.3.$tn.1 {
SELECT snippet(x1, '[', ']', '...') FROM x1 WHERE x1 MATCH $match
} $res
do_execsql_test 1.3.$tn.2 {
SELECT snippet(x2, '[', ']', '...') FROM x2 WHERE x2 MATCH $match
} $rev
}
# Test matchinfo().
#
foreach {tn match res} {
1 {^K} {
{1 3 3 0 0 0 0 0 0}
{1 3 3 0 0 0 0 0 0}
{1 3 3 0 0 0 0 0 0}
}
2 {^X} {
{0 1 1 0 1 1 1 2 2}
{0 1 1 1 1 1 0 2 2}
{1 1 1 0 1 1 1 2 2}
}
3 {^X Y} {
{0 1 1 0 1 1 1 2 2 0 6 5 0 5 4 1 4 4}
{0 1 1 1 1 1 0 2 2 1 6 5 0 5 4 0 4 4}
{1 1 1 0 1 1 1 2 2 1 6 5 0 5 4 1 4 4}
}
} {
set rev [lreverse $res]
do_execsql_test 1.3.$tn.1 {
SELECT mit(matchinfo(x1, 'x')) FROM x1 WHERE x1 MATCH $match
} $res
do_execsql_test 1.3.$tn.2 {
SELECT mit(matchinfo(x2, 'x')) FROM x2 WHERE x2 MATCH $match
} $rev
}
# Test that ^ is ignored for FTS3 tables.
#
do_execsql_test 2.1 {
CREATE VIRTUAL TABLE x3 USING fts3;
INSERT INTO x3 VALUES('A B C');
INSERT INTO x3 VALUES('B A C');
CREATE VIRTUAL TABLE x4 USING fts4;
INSERT INTO x4 VALUES('A B C');
INSERT INTO x4 VALUES('B A C');
}
do_execsql_test 2.2.1 {
SELECT * FROM x3 WHERE x3 MATCH '^A';
} {{A B C} {B A C}}
do_execsql_test 2.2.2 {
SELECT * FROM x4 WHERE x4 MATCH '^A';
} {{A B C}}
finish_test
+1
View File
@@ -294,6 +294,7 @@ do_write_test fts3_malloc-5.1 ft_content {
do_test fts3_malloc-5.2 {
execsql { CREATE VIRTUAL TABLE ft8 USING fts3(x, tokenize porter) }
} {}
do_write_test fts3_malloc-5.3 ft_content {
INSERT INTO ft8 VALUES('short alongertoken reallyquitealotlongerimeanit andthistokenisjustsolongthatonemightbeforgivenforimaginingthatitwasmerelyacontrivedexampleandnotarealtoken')
}
+16
View File
@@ -19,6 +19,7 @@ source $testdir/tester.tcl
ifcapable !fts3 { finish_test ; return }
set testprefix fts3matchinfo
set sqlite_fts3_enable_parentheses 0
proc mit {blob} {
set scan(littleEndian) i*
@@ -57,6 +58,9 @@ do_catchsql_test 2.0 {
do_catchsql_test 2.1 {
CREATE VIRTUAL TABLE x2 USING fts4(mtchinfo=fts3);
} {1 {unrecognized parameter: mtchinfo=fts3}}
do_catchsql_test 2.2 {
CREATE VIRTUAL TABLE x2 USING fts4(matchinfo=fts5);
} {1 {unrecognized matchinfo: fts5}}
# Check that with fts3, the "=" character is permitted in column definitions.
#
@@ -224,6 +228,18 @@ do_matchinfo_test 4.1.3 t4 {t4 MATCH 'a b'} { s {{2 0} {0 2}} }
do_matchinfo_test 4.1.4 t4 {t4 MATCH '"a b" c'} { s {{2 0} {0 2}} }
do_matchinfo_test 4.1.5 t4 {t4 MATCH 'a "b c"'} { s {{2 0} {0 2}} }
do_matchinfo_test 4.1.6 t4 {t4 MATCH 'd d'} { s {{1 0} {0 1}} }
do_matchinfo_test 4.1.7 t4 {t4 MATCH 'f OR abcd'} {
x {
{0 1 1 1 1 1 0 0 0 0 0 0}
{1 1 1 0 1 1 0 0 0 0 0 0}
}
}
do_matchinfo_test 4.1.8 t4 {t4 MATCH 'f -abcd'} {
x {
{0 1 1 1 1 1}
{1 1 1 0 1 1}
}
}
do_execsql_test 4.2.0 {
CREATE VIRTUAL TABLE t5 USING fts4;
+10
View File
@@ -200,4 +200,14 @@ do_execsql_test 4.6 {
SELECT * FROM t3 WHERE t3 MATCH 'one*'
} {{one two three}}
#-------------------------------------------------------------------------
# Syntax tests.
#
do_catchsql_test 5.1 {
CREATE VIRTUAL TABLE t4 USING fts4(prefix="abc");
} {1 {error parsing prefix parameter: abc}}
do_catchsql_test 5.2 {
CREATE VIRTUAL TABLE t4 USING fts4(prefix="");
} {0 {}}
finish_test
+1 -1
View File
@@ -131,7 +131,7 @@ foreach {DO_MALLOC_TEST enc} {
} {
db close
file delete -force test.db
forcedelete test.db
sqlite3 db test.db
sqlite3_db_config_lookaside db 0 0 0
db eval "PRAGMA encoding = \"$enc\""
+23
View File
@@ -138,6 +138,8 @@ foreach {tn param res} {
3 "order=dec" {1 {unrecognized order: dec}}
4 "order=xxx, order=asc" {1 {unrecognized order: xxx}}
5 "order=desc, order=asc" {0 {}}
6 "order=xxxx, order=asc" {1 {unrecognized order: xxxx}}
7 "order=desk" {1 {unrecognized order: desk}}
} {
execsql { DROP TABLE IF EXISTS t1 }
do_catchsql_test 2.1.$tn "
@@ -157,6 +159,27 @@ do_execsql_test 2.2 {
do_execsql_test 2.3 {
SELECT docid FROM t2 WHERE t2 MATCH 'aa';
} {3 1}
do_execsql_test 2.4 {
SELECT docid FROM t2 WHERE t2 MATCH 'aa' ORDER BY content;
} {1 3}
#-------------------------------------------------------------------------
# Test that ticket [56be976859] has been fixed.
#
do_execsql_test 3.1 {
CREATE VIRTUAL TABLE t3 USING fts4(x, order=DESC);
INSERT INTO t3(docid, x) VALUES(113382409004785664, 'aa');
INSERT INTO t3(docid, x) VALUES(1, 'ab');
SELECT rowid FROM t3 WHERE x MATCH 'a*' ORDER BY docid DESC;
} {113382409004785664 1}
do_execsql_test 3.2 {
CREATE VIRTUAL TABLE t4 USING fts4(x);
INSERT INTO t4(docid, x) VALUES(-113382409004785664, 'aa');
INSERT INTO t4(docid, x) VALUES(1, 'ab');
SELECT rowid FROM t4 WHERE x MATCH 'a*';
} {-113382409004785664 1}
finish_test
+1 -1
View File
@@ -1686,7 +1686,7 @@ foreach {q r} [array get fts4aa_res] {
#
do_test fts4aa-3.0 {
db close
file delete -force test.db
forcedelete test.db
sqlite3 db test.db
db eval {
PRAGMA page_size=65536;
+501
View File
@@ -0,0 +1,501 @@
# 2011 October 03
#
# 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. The
# focus of this script is testing the content=xxx FTS4 option.
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set ::testprefix fts4content
# If SQLITE_ENABLE_FTS3 is defined, omit this file.
ifcapable !fts3 {
finish_test
return
}
#-------------------------------------------------------------------------
# Test organization:
#
# 1.* - Warm-body tests.
#
# 2.* - Querying a content=xxx FTS table.
#
# 3.* - Writing to a content=xxx FTS table.
#
# 4.* - The "INSERT INTO fts(fts) VALUES('rebuild')" command.
#
# 5.* - Check that CREATE TABLE, DROP TABLE and ALTER TABLE correctly
# ignore any %_content table when used with the content=xxx option.
#
# 6.* - Test the effects of messing with the schema of table xxx after
# creating a content=xxx FTS index.
#
# 7.* - Test that if content=xxx is specified and table xxx does not
# exist, the FTS table can still be used for INSERT and some
# SELECT statements.
#
do_execsql_test 1.1.1 {
CREATE TABLE t1(a, b, c);
INSERT INTO t1 VALUES('w x', 'x y', 'y z');
CREATE VIRTUAL TABLE ft1 USING fts4(content=t1);
}
do_execsql_test 1.1.2 {
PRAGMA table_info(ft1);
} {
0 a {} 0 {} 0
1 b {} 0 {} 0
2 c {} 0 {} 0
}
do_execsql_test 1.1.3 { SELECT *, rowid FROM ft1 } {{w x} {x y} {y z} 1}
do_execsql_test 1.1.4 { SELECT a, c FROM ft1 WHERE rowid=1 } {{w x} {y z}}
do_execsql_test 1.1.5 { INSERT INTO ft1(ft1) VALUES('rebuild') } {}
do_execsql_test 1.1.6 { SELECT rowid FROM ft1 WHERE ft1 MATCH 'x' } {1}
do_execsql_test 1.1.7 { SELECT rowid FROM ft1 WHERE ft1 MATCH 'a' } {}
do_execsql_test 1.2.1 {
DROP TABLE ft1;
CREATE VIRTUAL TABLE ft1 USING fts4(content=t1, b);
PRAGMA table_info(ft1);
} {
0 b {} 0 {} 0
}
do_execsql_test 1.2.2 {
SELECT *, rowid FROM ft1
} {{x y} 1}
#-------------------------------------------------------------------------
# The following block of tests - 2.* - test that a content=xxx FTS table
# can be queried. Also tested are cases where rows identified in the FTS
# are missing from the content table, and cases where the index is
# inconsistent with the content table.
#
do_execsql_test 2.0 {
CREATE TABLE t2(x);
INSERT INTO t2 VALUES('O S W W F U C R Q I C N P Z Y Y E Y Y E'); -- 1
INSERT INTO t2 VALUES('Y X U V L B E H Y J C Y A I A P V F V K'); -- 2
INSERT INTO t2 VALUES('P W I N J H I I N I F B K D U Q B Z S F'); -- 3
INSERT INTO t2 VALUES('N R O R H J R H G M D I U U B O M P A U'); -- 4
INSERT INTO t2 VALUES('Y O V O G T P N G T N F I V B U M J M G'); -- 5
INSERT INTO t2 VALUES('J O B N K N E C H Z R K J O U G M K L S'); -- 6
INSERT INTO t2 VALUES('S Z S R I Q U A P W R X H K C Z U L S P'); -- 7
INSERT INTO t2 VALUES('J C H N R C K R V N M O F Z M Z A I H W'); -- 8
INSERT INTO t2 VALUES('O Y G I S J U U W O D Z F J K N R P R L'); -- 9
INSERT INTO t2 VALUES('B G L K U R U P V X Z I H V R W C Q A S'); -- 10
INSERT INTO t2 VALUES('T F T J F F Y V F W N X K Q A Y L X W G'); -- 11
INSERT INTO t2 VALUES('C J U H B Q X L C M M Y E G V F W V Z C'); -- 12
INSERT INTO t2 VALUES('B W L T F S G X D P H N G M R I O A X I'); -- 13
INSERT INTO t2 VALUES('N G Y O K Q K Z N M H U J E D H U W R K'); -- 14
INSERT INTO t2 VALUES('U D T R U Y F J D S J X E H Q G V A S Z'); -- 15
INSERT INTO t2 VALUES('M I W P J S H R J D Q I C G P C T P H R'); -- 16
INSERT INTO t2 VALUES('J M N I S L X Q C A B F C B Y D H V R J'); -- 17
INSERT INTO t2 VALUES('F V Z W J Q L P X Y E W B U Q N H X K T'); -- 18
INSERT INTO t2 VALUES('R F S R Y O F Q E I E G H C B H R X Y N'); -- 19
INSERT INTO t2 VALUES('U Q Q Q T E P D M F X P J G H X C Q D L'); -- 20
}
do_execsql_test 2.1 {
CREATE VIRTUAL TABLE ft2 USING fts4(content=t2);
INSERT INTO ft2(ft2) VALUES('rebuild');
-- Modify the backing table a bit: Row 17 is missing and the contents
-- of row 20 do not match the FTS index contents.
DELETE FROM t2 WHERE rowid = 17;
UPDATE t2 SET x = 'a b c d e f g h i j' WHERE rowid = 20;
}
foreach {tn match rowidlist} {
1 {S} {1 3 6 7 9 10 13 15 16 17 19}
2 {"S R"} {7 19}
3 {"N K N"} {6}
4 {"Q Q"} {20}
5 {"B Y D"} {17}
} {
do_execsql_test 2.2.1.$tn {
SELECT rowid FROM ft2 WHERE ft2 MATCH $match
} $rowidlist
do_execsql_test 2.2.2.$tn {
SELECT docid FROM ft2 WHERE ft2 MATCH $match
} $rowidlist
}
foreach {tn match result} {
1 {"N K N"} {{J O B N K N E C H Z R K J O U G M K L S}}
2 {"Q Q"} {{a b c d e f g h i j}}
3 {"B Y D"} {{}}
} {
do_execsql_test 2.3.$tn {
SELECT * FROM ft2 WHERE ft2 MATCH $match
} $result
}
foreach {tn match result} {
1 {"N K N"} {{..O B [N] [K] [N] E..}}
2 {"B Y D"} {{}}
3 {"Q Q"} {{a [b] [c] [d] e f..}}
} {
do_execsql_test 2.4.$tn {
SELECT snippet(ft2, '[', ']', '..', -1, 6) FROM ft2 WHERE ft2 MATCH $match
} $result
}
foreach {tn match result} {
1 {"N K N"} {{0 0 6 1 0 1 8 1 0 2 10 1}}
2 {"B Y D"} {{}}
3 {"Q Q"} {{0 0 2 1 0 0 4 1 0 1 4 1 0 1 6 1}}
4 {"Q D L"} {{}}
} {
do_execsql_test 2.5.$tn {
SELECT offsets(ft2) FROM ft2 WHERE ft2 MATCH $match
} $result
}
#-------------------------------------------------------------------------
# The following block of tests - 3.* - test that the FTS index can be
# modified by writing to the table. But that this has no effect on the
# content table.
#
do_execsql_test 3.1 {
CREATE TABLE t3(x, y);
CREATE VIRTUAL TABLE ft3 USING fts4(content=t3);
}
do_catchsql_test 3.1.1 {
INSERT INTO ft3 VALUES('a b c', 'd e f');
} {1 {constraint failed}}
do_execsql_test 3.1.2 {
INSERT INTO ft3(docid, x, y) VALUES(21, 'a b c', 'd e f');
SELECT rowid FROM ft3 WHERE ft3 MATCH '"a b c"';
} {21}
do_execsql_test 3.1.3 { SELECT * FROM t3 } {}
# This DELETE does not work, since there is no row in [t3] to base the
# DELETE on. So the SELECT on [ft3] still returns rowid 21.
do_execsql_test 3.1.4 {
DELETE FROM ft3;
SELECT rowid FROM ft3 WHERE ft3 MATCH '"a b c"';
} {21}
# If the row is added to [t3] before the DELETE on [ft3], it works.
do_execsql_test 3.1.5 {
INSERT INTO t3(rowid, x, y) VALUES(21, 'a b c', 'd e f');
DELETE FROM ft3;
SELECT rowid FROM ft3 WHERE ft3 MATCH '"a b c"';
} {}
do_execsql_test 3.1.6 { SELECT rowid FROM t3 } {21}
do_execsql_test 3.2.1 {
INSERT INTO ft3(rowid, x, y) VALUES(0, 'R T M S M', 'A F O K H');
INSERT INTO ft3(rowid, x, y) VALUES(1, 'C Z J O X', 'U S Q D K');
INSERT INTO ft3(rowid, x, y) VALUES(2, 'N G H P O', 'N O P O C');
INSERT INTO ft3(rowid, x, y) VALUES(3, 'V H S D R', 'K N G E C');
INSERT INTO ft3(rowid, x, y) VALUES(4, 'J T R V U', 'U X S L C');
INSERT INTO ft3(rowid, x, y) VALUES(5, 'N A Y N G', 'X D G P Y');
INSERT INTO ft3(rowid, x, y) VALUES(6, 'I Q I S P', 'D R O Q B');
INSERT INTO ft3(rowid, x, y) VALUES(7, 'T K T Z J', 'B W D G O');
INSERT INTO ft3(rowid, x, y) VALUES(8, 'Y K F X T', 'D F G V G');
INSERT INTO ft3(rowid, x, y) VALUES(9, 'E L E T L', 'P W N F Z');
INSERT INTO ft3(rowid, x, y) VALUES(10, 'O G J G X', 'G J F E P');
INSERT INTO ft3(rowid, x, y) VALUES(11, 'O L N N Z', 'K E Z F D');
INSERT INTO ft3(rowid, x, y) VALUES(12, 'R Z M R J', 'X G I M Z');
INSERT INTO ft3(rowid, x, y) VALUES(13, 'L X N N X', 'R R N S T');
INSERT INTO ft3(rowid, x, y) VALUES(14, 'F L B J H', 'K W F L C');
INSERT INTO ft3(rowid, x, y) VALUES(15, 'P E B M V', 'E A A B U');
INSERT INTO ft3(rowid, x, y) VALUES(16, 'V E C F P', 'L U T V K');
INSERT INTO ft3(rowid, x, y) VALUES(17, 'T N O Z N', 'T P Q X N');
INSERT INTO ft3(rowid, x, y) VALUES(18, 'V W U W R', 'H O A A V');
INSERT INTO ft3(rowid, x, y) VALUES(19, 'A H N L F', 'I G H B O');
}
foreach {tn match rowidlist} {
1 "N A" {5 19}
2 "x:O" {1 2 10 11 17}
3 "y:O" {0 2 6 7 18 19}
} {
set res [list]
foreach rowid $rowidlist { lappend res $rowid {} {} }
do_execsql_test 3.2.2.$tn {
SELECT rowid, * FROM ft3 WHERE ft3 MATCH $match
} $res
do_execsql_test 3.2.3.$tn {
SELECT docid, * FROM ft3 WHERE ft3 MATCH $match
} $res
}
do_execsql_test 3.3.1 {
INSERT INTO t3(rowid, x, y) VALUES(0, 'R T M S M', 'A F O K H');
INSERT INTO t3(rowid, x, y) VALUES(1, 'C Z J O X', 'U S Q D K');
INSERT INTO t3(rowid, x, y) VALUES(2, 'N G H P O', 'N O P O C');
INSERT INTO t3(rowid, x, y) VALUES(3, 'V H S D R', 'K N G E C');
INSERT INTO t3(rowid, x, y) VALUES(4, 'J T R V U', 'U X S L C');
INSERT INTO t3(rowid, x, y) VALUES(5, 'N A Y N G', 'X D G P Y');
UPDATE ft3 SET x = y, y = x;
DELETE FROM t3;
}
foreach {tn match rowidlist} {
1 "N A" {5 19}
2 "x:O" {0 2 10 11 17}
3 "y:O" {1 2 6 7 18 19}
} {
set res [list]
foreach rowid $rowidlist { lappend res $rowid {} {} }
do_execsql_test 3.3.2.$tn {
SELECT rowid, * FROM ft3 WHERE ft3 MATCH $match
} $res
do_execsql_test 3.3.3.$tn {
SELECT docid, * FROM ft3 WHERE ft3 MATCH $match
} $res
}
do_execsql_test 3.3.1 {
INSERT INTO t3(rowid, x, y) VALUES(15, 'P E B M V', 'E A A B U');
INSERT INTO t3(rowid, x, y) VALUES(16, 'V E C F P', 'L U T V K');
INSERT INTO t3(rowid, x, y) VALUES(17, 'T N O Z N', 'T P Q X N');
INSERT INTO t3(rowid, x, y) VALUES(18, 'V W U W R', 'H O A A V');
INSERT INTO t3(rowid, x, y) VALUES(19, 'A H N L F', 'I G H B O');
DELETE FROM ft3;
}
foreach {tn match rowidlist} {
1 "N A" {5}
2 "x:O" {0 2 10 11}
3 "y:O" {1 2 6 7}
} {
set res [list]
foreach rowid $rowidlist { lappend res $rowid {} {} }
do_execsql_test 3.3.2.$tn {
SELECT rowid, * FROM ft3 WHERE ft3 MATCH $match
} $res
do_execsql_test 3.3.3.$tn {
SELECT docid, * FROM ft3 WHERE ft3 MATCH $match
} $res
}
#-------------------------------------------------------------------------
# Test cases 4.* test the 'rebuild' command. On content=xxx and regular
# FTS tables.
#
do_execsql_test 4.0 {
CREATE TABLE t4(x);
CREATE VIRTUAL TABLE ft4 USING fts4(content=t4);
CREATE VIRTUAL TABLE ft4x USING fts4(x);
}
do_execsql_test 4.1.1 {
INSERT INTO ft4x(ft4x) VALUES('rebuild');
INSERT INTO ft4(ft4) VALUES('rebuild');
} {}
do_execsql_test 4.1.2 {
SELECT id, quote(value) FROM ft4_stat
} {0 X'000000'}
do_execsql_test 4.1.3 {
SELECT id, quote(value) FROM ft4x_stat
} {0 X'000000'}
do_execsql_test 4.2.1 {
INSERT INTO ft4x VALUES('M G M F T');
INSERT INTO ft4x VALUES('Z Q C A U');
INSERT INTO ft4x VALUES('N L L V');
INSERT INTO ft4x VALUES('T F D X D');
INSERT INTO ft4x VALUES('Z H I S D');
SELECT id, quote(value) FROM ft4x_stat
} {0 X'05182B'}
do_execsql_test 4.2.2 {
INSERT INTO ft4(rowid, x) SELECT rowid, * FROM ft4x;
SELECT id, quote(value) FROM ft4_stat
} {0 X'05182B'}
do_execsql_test 4.2.3 {
SELECT docid, quote(size) FROM ft4_docsize
} {1 X'05' 2 X'05' 3 X'04' 4 X'05' 5 X'05'}
do_execsql_test 4.2.4 {
INSERT INTO ft4x(ft4x) VALUES('rebuild');
SELECT id, quote(value) FROM ft4x_stat;
SELECT docid, quote(size) FROM ft4x_docsize
} {0 X'05182B' 1 X'05' 2 X'05' 3 X'04' 4 X'05' 5 X'05'}
do_execsql_test 4.2.5 {
INSERT INTO ft4(ft4) VALUES('rebuild');
SELECT id, quote(value) FROM ft4_stat;
SELECT docid, quote(size) FROM ft4_docsize
} {0 X'000000'}
do_execsql_test 4.2.6 {
INSERT INTO t4(rowid, x) SELECT rowid, x FROM ft4x;
INSERT INTO ft4(ft4) VALUES('rebuild');
SELECT id, quote(value) FROM ft4_stat;
SELECT docid, quote(size) FROM ft4_docsize
} {0 X'05182B' 1 X'05' 2 X'05' 3 X'04' 4 X'05' 5 X'05'}
#-------------------------------------------------------------------------
# Test cases 5.* test that the following commands do not create/move or
# delete a %_content table when used with a content=xxx FTS table.
#
do_execsql_test 5.1.1 {
CREATE TABLE t5(a, b, c, d);
CREATE VIRTUAL TABLE ft5 USING fts4(content=t5);
SELECT name FROM sqlite_master WHERE name LIKE '%t5%';
} {
t5 ft5 ft5_segments ft5_segdir
sqlite_autoindex_ft5_segdir_1 ft5_docsize ft5_stat
}
do_execsql_test 5.1.2 {
ALTER TABLE ft5 RENAME TO ft6;
SELECT name FROM sqlite_master WHERE name LIKE '%t5%';
} {
t5
}
do_execsql_test 5.1.3 {
SELECT name FROM sqlite_master WHERE name LIKE '%t6%';
} {
ft6 ft6_segments ft6_segdir
sqlite_autoindex_ft6_segdir_1 ft6_docsize ft6_stat
}
do_execsql_test 5.1.4 {
INSERT INTO t5 VALUES('a', 'b', 'c', 'd');
INSERT INTO ft6(ft6) VALUES('rebuild');
SELECT rowid FROM ft6 WHERE ft6 MATCH 'b';
} {1}
do_execsql_test 5.1.5 {
DROP TABLE ft6;
SELECT * FROM t5;
} {a b c d}
do_execsql_test 5.1.6 {
SELECT name FROM sqlite_master WHERE name LIKE '%t6%';
} {
}
do_execsql_test 5.1.7 {
CREATE VIRTUAL TABLE ft5 USING fts4(content=t5);
CREATE TABLE t5_content(a, b);
DROP TABLE ft5;
SELECT name FROM sqlite_master WHERE name LIKE '%t5%';
} {
t5 t5_content
}
#-------------------------------------------------------------------------
# Test cases 6.* test
#
do_catchsql_test 6.1.1 {
CREATE VIRTUAL TABLE ft7 USING fts4(content=t7);
} {1 {vtable constructor failed: ft7}}
do_execsql_test 6.2.1 {
CREATE TABLE t7(one, two);
CREATE VIRTUAL TABLE ft7 USING fts4(content=t7);
INSERT INTO t7 VALUES('A B', 'B A');
INSERT INTO t7 VALUES('C D', 'A A');
SELECT * FROM ft7;
} {
{A B} {B A} {C D} {A A}
}
do_catchsql_test 6.2.2 {
DROP TABLE t7;
SELECT * FROM ft7;
} {1 {SQL logic error or missing database}}
db close
sqlite3 db test.db
do_execsql_test 6.2.3 {
SELECT name FROM sqlite_master WHERE name LIKE '%t7%'
} {
ft7 ft7_segments ft7_segdir sqlite_autoindex_ft7_segdir_1
ft7_docsize ft7_stat
}
do_catchsql_test 6.2.4 {
SELECT * FROM ft7;
} {1 {vtable constructor failed: ft7}}
do_execsql_test 6.2.5 {
CREATE TABLE t7(x, y);
INSERT INTO t7 VALUES('A B', 'B A');
INSERT INTO t7 VALUES('C D', 'A A');
SELECT * FROM ft7;
} {
{A B} {B A} {C D} {A A}
}
do_execsql_test 6.2.6 {
INSERT INTO ft7(ft7) VALUES('rebuild');
SELECT rowid FROM ft7 WHERE ft7 MATCH '"A A"';
} {2}
do_execsql_test 6.2.7 {
DROP TABLE t7;
CREATE TABLE t7(x);
}
do_catchsql_test 6.2.8 {
SELECT * FROM ft7 WHERE ft7 MATCH '"A A"';
} {1 {SQL logic error or missing database}}
do_catchsql_test 6.2.9 {
SELECT * FROM ft7 WHERE ft7 MATCH '"A A"';
} {1 {SQL logic error or missing database}}
db close
sqlite3 db test.db
do_catchsql_test 6.2.10 {
SELECT rowid FROM ft7 WHERE ft7 MATCH '"A A"';
} {0 2}
do_catchsql_test 6.2.11 {
SELECT rowid, * FROM ft7 WHERE ft7 MATCH '"A A"';
} {0 {2 {}}}
#-------------------------------------------------------------------------
# Test cases 7.*
#
do_execsql_test 7.1.1 {
CREATE VIRTUAL TABLE ft8 USING fts4(content=nosuchtable, x);
INSERT INTO ft8(docid, x) VALUES(13, 'U O N X G');
INSERT INTO ft8(docid, x) VALUES(14, 'C J J U B');
INSERT INTO ft8(docid, x) VALUES(15, 'N J Y G X');
INSERT INTO ft8(docid, x) VALUES(16, 'R Y D O R');
INSERT INTO ft8(docid, x) VALUES(17, 'I Y T Q O');
}
do_execsql_test 7.1.2 {
SELECT docid FROM ft8 WHERE ft8 MATCH 'N';
} {13 15}
do_execsql_test 7.2.1 {
CREATE VIRTUAL TABLE ft9 USING fts4(content=, x);
INSERT INTO ft9(docid, x) VALUES(13, 'U O N X G');
INSERT INTO ft9(docid, x) VALUES(14, 'C J J U B');
INSERT INTO ft9(docid, x) VALUES(15, 'N J Y G X');
INSERT INTO ft9(docid, x) VALUES(16, 'R Y D O R');
INSERT INTO ft9(docid, x) VALUES(17, 'I Y T Q O');
}
do_execsql_test 7.2.2 {
SELECT docid FROM ft9 WHERE ft9 MATCH 'N';
} {13 15}
do_execsql_test 7.2.3 {
SELECT name FROM sqlite_master WHERE name LIKE 'ft9_%';
} {ft9_segments ft9_segdir ft9_docsize ft9_stat}
do_catchsql_test 7.2.4 {
SELECT * FROM ft9 WHERE ft9 MATCH 'N';
} {1 {SQL logic error or missing database}}
finish_test
+20 -18
View File
@@ -17,24 +17,26 @@ set testdir [file dirname $argv0]
source $testdir/tester.tcl
do_test func3-1.1 {
set destroyed 0
proc destroy {} { set ::destroyed 1 }
sqlite3_create_function_v2 db f2 -1 any -func f2 -destroy destroy
set destroyed
} 0
do_test func3-1.2 {
sqlite3_create_function_v2 db f2 -1 utf8 -func f2
set destroyed
} 0
do_test func3-1.3 {
sqlite3_create_function_v2 db f2 -1 utf16le -func f2
set destroyed
} 0
do_test func3-1.4 {
sqlite3_create_function_v2 db f2 -1 utf16be -func f2
set destroyed
} 1
ifcapable utf16 {
do_test func3-1.1 {
set destroyed 0
proc destroy {} { set ::destroyed 1 }
sqlite3_create_function_v2 db f2 -1 any -func f2 -destroy destroy
set destroyed
} 0
do_test func3-1.2 {
sqlite3_create_function_v2 db f2 -1 utf8 -func f2
set destroyed
} 0
do_test func3-1.3 {
sqlite3_create_function_v2 db f2 -1 utf16le -func f2
set destroyed
} 0
do_test func3-1.4 {
sqlite3_create_function_v2 db f2 -1 utf16be -func f2
set destroyed
} 1
}
do_test func3-2.1 {
set destroyed 0
+1 -1
View File
@@ -47,7 +47,7 @@ proc do_fuzzy_malloc_test {testname args} {
sqlite3_memdebug_fail -1
db close
file delete test.db test.db-journal
delete_file test.db test.db-journal
sqlite3 db test.db
set ::prep $::fuzzyopts(-sqlprep)
execsql $::prep
+1 -1
View File
@@ -1376,7 +1376,7 @@ do_test fuzzer1-2.3 {
AND f2.distance<=200
AND streetname.n>=f2.word AND streetname.n<=(f2.word || x'F7BFBFBF')
}
} {steelewood tallia tallu talwyn taymouth thelema trailer {tyler finley}}
} {{tyler finley} trailer taymouth steelewood tallia tallu talwyn thelema}
finish_test
+2 -2
View File
@@ -95,7 +95,7 @@ do_test hook-3.9 {
# Ticket #3564.
#
do_test hook-3.10 {
file delete -force test2.db test2.db-journal
forcedelete test2.db test2.db-journal
sqlite3 db2 test2.db
proc commit_hook {} {
set y [db2 one {SELECT y FROM t3 WHERE y>10}]
@@ -217,7 +217,7 @@ ifcapable trigger {
set ::update_hook {}
ifcapable attach {
do_test hook-4.2.3 {
file delete -force test2.db
forcedelete test2.db
execsql {
ATTACH 'test2.db' AS aux;
CREATE TABLE aux.t3(a INTEGER PRIMARY KEY, b);
+3 -3
View File
@@ -120,7 +120,7 @@ foreach AutoVacuumMode [list 0 1] {
}
db close
file delete -force test.db test.db-journal
forcedelete test.db test.db-journal
sqlite3 db test.db
execsql "PRAGMA auto_vacuum = $AutoVacuumMode"
@@ -379,7 +379,7 @@ ifcapable vtab {
#
ifcapable attach {
do_test incrblob-5.1 {
file delete -force test2.db test2.db-journal
forcedelete test2.db test2.db-journal
set ::size [expr [file size [info script]]]
execsql {
ATTACH 'test2.db' AS aux;
@@ -584,7 +584,7 @@ set ::data [read $fd 14000]
close $fd
db close
file delete -force test.db test.db-journal
forcedelete test.db test.db-journal
sqlite3 db test.db
do_test incrblob-7.2.1 {
+4 -2
View File
@@ -35,6 +35,7 @@ do_malloc_test 1 -tclprep {
}
} -tclbody {
set ::blob [db incrblob blobs v 1]
fconfigure $::blob -translation binary
set rc [catch {puts -nonewline $::blob $::data}]
if {$rc} { error "out of memory" }
}
@@ -71,8 +72,7 @@ do_malloc_test 3 -tclprep {
if {$rc} {
error "out of memory"
}
}
}
do_ioerr_test incrblob_err-4 -cksum 1 -sqlprep {
CREATE TABLE blobs(k, v BLOB);
@@ -87,6 +87,7 @@ do_ioerr_test incrblob_err-5 -cksum 1 -sqlprep {
INSERT INTO blobs VALUES(1, zeroblob(length(CAST($::data AS BLOB))));
} -tclbody {
set ::blob [db incrblob blobs v 1]
fconfigure $::blob -translation binary
puts -nonewline $::blob $::data
close $::blob
}
@@ -96,6 +97,7 @@ do_ioerr_test incrblob_err-6 -cksum 1 -sqlprep {
INSERT INTO blobs VALUES(1, $::data || $::data || $::data);
} -tclbody {
set ::blob [db incrblob blobs v 1]
fconfigure $::blob -translation binary
seek $::blob -20 end
puts -nonewline $::blob "12345678900987654321"
close $::blob
+6 -6
View File
@@ -331,7 +331,7 @@ proc compare_dbs {A B tname} {
set ::str1 [string repeat abcdefghij 130]
set ::str2 [string repeat 1234567890 105]
file delete -force test1.db test1.db-journal test2.db test2.db-journal
forcedelete test1.db test1.db-journal test2.db test2.db-journal
sqlite3 db1 test1.db
sqlite3 db2 test2.db
execsql { PRAGMA auto_vacuum = 'none' } db1
@@ -475,7 +475,7 @@ do_test incrvacuum-8.1 {
#
do_test incrvacuum-9.1 {
db close
file delete -force test.db test.db-journal
forcedelete test.db test.db-journal
sqlite3 db test.db
execsql {
@@ -593,7 +593,7 @@ do_test incrvacuum-10.8 {
# vacuum mode.
#
db close
file delete -force test.db test.db-journal
forcedelete test.db test.db-journal
sqlite3 db test.db
ifcapable default_autovacuum {
@@ -651,7 +651,7 @@ do_test incrvacuum-11.7 {
# auto_vacuum = XXX" statement is executed.
#
db close
file delete -force test.db test.db-journal
forcedelete test.db test.db-journal
sqlite3 db test.db
do_test incrvacuum-12.1 {
@@ -692,7 +692,7 @@ do_test incrvacuum-12.5 {
#
db2 close
db close
file delete -force test.db test.db-journal
forcedelete test.db test.db-journal
sqlite3 db test.db ; set ::DB [sqlite3_connection_pointer db]
sqlite3 db2 test.db
@@ -743,7 +743,7 @@ if {[permutation] == ""} {
do_test incrvacuum-15.1 {
db close
db2 close
file delete -force test.db
forcedelete test.db
sqlite3 db test.db
set str [string repeat "abcdefghij" 500]

Some files were not shown because too many files have changed in this diff Show More