1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-08 14:02:16 +03:00

Merge recent trunk enhancements into the begin-concurrent branch.

FossilOrigin-Name: 5bd26fea6a0720897a6c8384249b1e41c1838ef98f8f48d463d0cdde631477b9
This commit is contained in:
drh
2023-06-22 13:28:30 +00:00
159 changed files with 8895 additions and 34530 deletions

View File

@@ -377,4 +377,23 @@ do_execsql_test analyze-6.1 {
SELECT tbl FROM sqlite_stat1 WHERE idx IS NULL ORDER BY tbl;
} {SQLiteDemo2 sqliteDemo t1}
# The following caused a small buffer overread in STAT4 processing prior
# to check-in [b99135288b157044].
#
ifcapable stat4 {
reset_db
database_may_be_corrupt
do_execsql_test analyze-7.1 {
CREATE TABLE t1(a INTEGER PRIMARY KEY, b INTEGER);
INSERT INTO t1 VALUES(1, 7223372036854775);
INSERT INTO t1 VALUES(2, 7223372036854776);
INSERT INTO t1 VALUES(3, 7223372036854777);
CREATE INDEX i1 ON t1(b);
ANALYZE;
UPDATE sqlite_stat4 SET sample = substr(sample, 0, 4);
ANALYZE sqlite_schema;
SELECT * FROM t1 WHERE b>7223372036854775
} {2 7223372036854776 3 7223372036854777}
}
finish_test

View File

@@ -141,7 +141,7 @@ foreach {id data1 data2 jointype onclause whereclause answer} {
{coalesce(y,4)==4}
{3 4 3 4}
5
5.1
VALUES(1,2),(3,4),(NULL,4)
VALUES(1,2),(3,4)
{LEFT JOIN}
@@ -149,6 +149,22 @@ foreach {id data1 data2 jointype onclause whereclause answer} {
{y=4 OR y IS NULL}
{3 4 3 4 {} 4 {} {}}
5.2
VALUES(1,2),(3,4),(NULL,4)
VALUES(1,2),(3,4)
{LEFT JOIN}
a=x
{y NOT IN ()}
{1 2 1 2 3 4 3 4 {} 4 {} {}}
5.3
VALUES(1,2),(3,4),(NULL,4)
VALUES(1,2),(3,4)
{LEFT JOIN}
a=x
{y NOT IN (SELECT 1 WHERE false)}
{1 2 1 2 3 4 3 4 {} 4 {} {}}
6
VALUES(1,2),(3,4)
VALUES(1,2),(3,4),(NULL,4)
@@ -193,6 +209,12 @@ foreach {id data1 data2 jointype onclause whereclause answer} {
db eval {PRAGMA automatic_index=OFF;}
db eval $sql
} $answer
do_test autoindex4-4.$id.3 {
db eval {PRAGMA automatic_index=ON;}
optimization_control db all 0
db eval $sql
} $answer
optimization_control db all 1
}

View File

@@ -248,7 +248,7 @@ do_test corrupt2-5.1 {
}
set result
} {{*** in database main ***
Tree 11 page 2 cell 0: 2nd reference to page 10
Tree 2 page 2 cell 0: 2nd reference to page 10
Page 4: never used}}
db2 close

View File

@@ -1,186 +0,0 @@
# 2006 September 9
#
# 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 FTS1 module.
#
# $Id: fts1a.test,v 1.4 2006/09/28 19:43:32 drh Exp $
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
# If SQLITE_ENABLE_FTS1 is defined, omit this file.
ifcapable !fts1 {
finish_test
return
}
# Construct a full-text search table containing five keywords:
# one, two, three, four, and five, in various combinations. The
# rowid for each will be a bitmask for the elements it contains.
#
db eval {
CREATE VIRTUAL TABLE t1 USING fts1(content);
INSERT INTO t1(content) VALUES('one');
INSERT INTO t1(content) VALUES('two');
INSERT INTO t1(content) VALUES('one two');
INSERT INTO t1(content) VALUES('three');
INSERT INTO t1(content) VALUES('one three');
INSERT INTO t1(content) VALUES('two three');
INSERT INTO t1(content) VALUES('one two three');
INSERT INTO t1(content) VALUES('four');
INSERT INTO t1(content) VALUES('one four');
INSERT INTO t1(content) VALUES('two four');
INSERT INTO t1(content) VALUES('one two four');
INSERT INTO t1(content) VALUES('three four');
INSERT INTO t1(content) VALUES('one three four');
INSERT INTO t1(content) VALUES('two three four');
INSERT INTO t1(content) VALUES('one two three four');
INSERT INTO t1(content) VALUES('five');
INSERT INTO t1(content) VALUES('one five');
INSERT INTO t1(content) VALUES('two five');
INSERT INTO t1(content) VALUES('one two five');
INSERT INTO t1(content) VALUES('three five');
INSERT INTO t1(content) VALUES('one three five');
INSERT INTO t1(content) VALUES('two three five');
INSERT INTO t1(content) VALUES('one two three five');
INSERT INTO t1(content) VALUES('four five');
INSERT INTO t1(content) VALUES('one four five');
INSERT INTO t1(content) VALUES('two four five');
INSERT INTO t1(content) VALUES('one two four five');
INSERT INTO t1(content) VALUES('three four five');
INSERT INTO t1(content) VALUES('one three four five');
INSERT INTO t1(content) VALUES('two three four five');
INSERT INTO t1(content) VALUES('one two three four five');
}
do_test fts1a-1.1 {
execsql {SELECT rowid FROM t1 WHERE content MATCH 'one'}
} {1 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31}
do_test fts1a-1.2 {
execsql {SELECT rowid FROM t1 WHERE content MATCH 'one two'}
} {3 7 11 15 19 23 27 31}
do_test fts1a-1.3 {
execsql {SELECT rowid FROM t1 WHERE content MATCH 'two one'}
} {3 7 11 15 19 23 27 31}
do_test fts1a-1.4 {
execsql {SELECT rowid FROM t1 WHERE content MATCH 'one two three'}
} {7 15 23 31}
do_test fts1a-1.5 {
execsql {SELECT rowid FROM t1 WHERE content MATCH 'one three two'}
} {7 15 23 31}
do_test fts1a-1.6 {
execsql {SELECT rowid FROM t1 WHERE content MATCH 'two three one'}
} {7 15 23 31}
do_test fts1a-1.7 {
execsql {SELECT rowid FROM t1 WHERE content MATCH 'two one three'}
} {7 15 23 31}
do_test fts1a-1.8 {
execsql {SELECT rowid FROM t1 WHERE content MATCH 'three one two'}
} {7 15 23 31}
do_test fts1a-1.9 {
execsql {SELECT rowid FROM t1 WHERE content MATCH 'three two one'}
} {7 15 23 31}
do_test fts1a-1.10 {
execsql {SELECT rowid FROM t1 WHERE content MATCH 'one two THREE'}
} {7 15 23 31}
do_test fts1a-1.11 {
execsql {SELECT rowid FROM t1 WHERE content MATCH ' ONE Two three '}
} {7 15 23 31}
do_test fts1a-2.1 {
execsql {SELECT rowid FROM t1 WHERE content MATCH '"one"'}
} {1 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31}
do_test fts1a-2.2 {
execsql {SELECT rowid FROM t1 WHERE content MATCH '"one two"'}
} {3 7 11 15 19 23 27 31}
do_test fts1a-2.3 {
execsql {SELECT rowid FROM t1 WHERE content MATCH '"two one"'}
} {}
do_test fts1a-2.4 {
execsql {SELECT rowid FROM t1 WHERE content MATCH '"one two three"'}
} {7 15 23 31}
do_test fts1a-2.5 {
execsql {SELECT rowid FROM t1 WHERE content MATCH '"one three two"'}
} {}
do_test fts1a-2.6 {
execsql {SELECT rowid FROM t1 WHERE content MATCH '"one two three four"'}
} {15 31}
do_test fts1a-2.7 {
execsql {SELECT rowid FROM t1 WHERE content MATCH '"one three two four"'}
} {}
do_test fts1a-2.8 {
execsql {SELECT rowid FROM t1 WHERE content MATCH '"one three five"'}
} {21}
do_test fts1a-2.9 {
execsql {SELECT rowid FROM t1 WHERE content MATCH '"one three" five'}
} {21 29}
do_test fts1a-2.10 {
execsql {SELECT rowid FROM t1 WHERE content MATCH 'five "one three"'}
} {21 29}
do_test fts1a-2.11 {
execsql {SELECT rowid FROM t1 WHERE content MATCH 'five "one three" four'}
} {29}
do_test fts1a-2.12 {
execsql {SELECT rowid FROM t1 WHERE content MATCH 'five four "one three"'}
} {29}
do_test fts1a-2.13 {
execsql {SELECT rowid FROM t1 WHERE content MATCH '"one three" four five'}
} {29}
do_test fts1a-3.1 {
execsql {SELECT rowid FROM t1 WHERE content MATCH 'one'}
} {1 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31}
do_test fts1a-3.2 {
execsql {SELECT rowid FROM t1 WHERE content MATCH 'one -two'}
} {1 5 9 13 17 21 25 29}
do_test fts1a-3.3 {
execsql {SELECT rowid FROM t1 WHERE content MATCH '-two one'}
} {1 5 9 13 17 21 25 29}
do_test fts1a-4.1 {
execsql {SELECT rowid FROM t1 WHERE content MATCH 'one OR two'}
} {1 2 3 5 6 7 9 10 11 13 14 15 17 18 19 21 22 23 25 26 27 29 30 31}
do_test fts1a-4.2 {
execsql {SELECT rowid FROM t1 WHERE content MATCH '"one two" OR three'}
} {3 4 5 6 7 11 12 13 14 15 19 20 21 22 23 27 28 29 30 31}
do_test fts1a-4.3 {
execsql {SELECT rowid FROM t1 WHERE content MATCH 'three OR "one two"'}
} {3 4 5 6 7 11 12 13 14 15 19 20 21 22 23 27 28 29 30 31}
do_test fts1a-4.4 {
execsql {SELECT rowid FROM t1 WHERE content MATCH 'one two OR three'}
} {3 5 7 11 13 15 19 21 23 27 29 31}
do_test fts1a-4.5 {
execsql {SELECT rowid FROM t1 WHERE content MATCH 'three OR two one'}
} {3 5 7 11 13 15 19 21 23 27 29 31}
do_test fts1a-4.6 {
execsql {SELECT rowid FROM t1 WHERE content MATCH 'one two OR three OR four'}
} {3 5 7 9 11 13 15 19 21 23 25 27 29 31}
do_test fts1a-4.7 {
execsql {SELECT rowid FROM t1 WHERE content MATCH 'two OR three OR four one'}
} {3 5 7 9 11 13 15 19 21 23 25 27 29 31}
# Test the ability to handle NULL content
#
do_test fts1a-5.1 {
execsql {INSERT INTO t1(content) VALUES(NULL)}
} {}
do_test fts1a-5.2 {
set rowid [db last_insert_rowid]
execsql {SELECT content FROM t1 WHERE rowid=$rowid}
} {{}}
do_test fts1a-5.3 {
execsql {SELECT rowid FROM t1 WHERE content MATCH NULL}
} {}
finish_test

View File

@@ -1,147 +0,0 @@
# 2006 September 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 regression tests for SQLite library. The
# focus of this script is testing the FTS1 module.
#
# $Id: fts1b.test,v 1.4 2006/09/18 02:12:48 drh Exp $
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
# If SQLITE_ENABLE_FTS1 is defined, omit this file.
ifcapable !fts1 {
finish_test
return
}
# Fill the full-text index "t1" with phrases in english, spanish,
# and german. For the i-th row, fill in the names for the bits
# that are set in the value of i. The least significant bit is
# 1. For example, the value 5 is 101 in binary which will be
# converted to "one three" in english.
#
proc fill_multilanguage_fulltext_t1 {} {
set english {one two three four five}
set spanish {un dos tres cuatro cinco}
set german {eine zwei drei vier funf}
for {set i 1} {$i<=31} {incr i} {
set cmd "INSERT INTO t1 VALUES"
set vset {}
foreach lang {english spanish german} {
set words {}
for {set j 0; set k 1} {$j<5} {incr j; incr k $k} {
if {$k&$i} {lappend words [lindex [set $lang] $j]}
}
lappend vset "'$words'"
}
set sql "INSERT INTO t1(english,spanish,german) VALUES([join $vset ,])"
# puts $sql
db eval $sql
}
}
# Construct a full-text search table containing five keywords:
# one, two, three, four, and five, in various combinations. The
# rowid for each will be a bitmask for the elements it contains.
#
db eval {
CREATE VIRTUAL TABLE t1 USING fts1(english,spanish,german);
}
fill_multilanguage_fulltext_t1
do_test fts1b-1.1 {
execsql {SELECT rowid FROM t1 WHERE english MATCH 'one'}
} {1 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31}
do_test fts1b-1.2 {
execsql {SELECT rowid FROM t1 WHERE spanish MATCH 'one'}
} {}
do_test fts1b-1.3 {
execsql {SELECT rowid FROM t1 WHERE german MATCH 'one'}
} {}
do_test fts1b-1.4 {
execsql {SELECT rowid FROM t1 WHERE t1 MATCH 'one'}
} {1 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31}
do_test fts1b-1.5 {
execsql {SELECT rowid FROM t1 WHERE t1 MATCH 'one dos drei'}
} {7 15 23 31}
do_test fts1b-1.6 {
execsql {SELECT english, spanish, german FROM t1 WHERE rowid=1}
} {one un eine}
do_test fts1b-1.7 {
execsql {SELECT rowid FROM t1 WHERE t1 MATCH '"one un"'}
} {}
do_test fts1b-2.1 {
execsql {
CREATE VIRTUAL TABLE t2 USING fts1(from,to);
INSERT INTO t2([from],[to]) VALUES ('one two three', 'four five six');
SELECT [from], [to] FROM t2
}
} {{one two three} {four five six}}
# Compute an SQL string that contains the words one, two, three,... to
# describe bits set in the value $i. Only the lower 5 bits are examined.
#
proc wordset {i} {
set x {}
for {set j 0; set k 1} {$j<5} {incr j; incr k $k} {
if {$k&$i} {lappend x [lindex {one two three four five} $j]}
}
return '$x'
}
# Create a new FTS table with three columns:
#
# norm: words for the bits of rowid
# plusone: words for the bits of rowid+1
# invert: words for the bits of ~rowid
#
db eval {
CREATE VIRTUAL TABLE t4 USING fts1([norm],'plusone',"invert");
}
for {set i 1} {$i<=15} {incr i} {
set vset [list [wordset $i] [wordset [expr {$i+1}]] [wordset [expr {~$i}]]]
db eval "INSERT INTO t4(norm,plusone,invert) VALUES([join $vset ,]);"
}
do_test fts1b-4.1 {
execsql {SELECT rowid FROM t4 WHERE t4 MATCH 'norm:one'}
} {1 3 5 7 9 11 13 15}
do_test fts1b-4.2 {
execsql {SELECT rowid FROM t4 WHERE norm MATCH 'one'}
} {1 3 5 7 9 11 13 15}
do_test fts1b-4.3 {
execsql {SELECT rowid FROM t4 WHERE t4 MATCH 'one'}
} {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15}
do_test fts1b-4.4 {
execsql {SELECT rowid FROM t4 WHERE t4 MATCH 'plusone:one'}
} {2 4 6 8 10 12 14}
do_test fts1b-4.5 {
execsql {SELECT rowid FROM t4 WHERE plusone MATCH 'one'}
} {2 4 6 8 10 12 14}
do_test fts1b-4.6 {
execsql {SELECT rowid FROM t4 WHERE t4 MATCH 'norm:one plusone:two'}
} {1 5 9 13}
do_test fts1b-4.7 {
execsql {SELECT rowid FROM t4 WHERE t4 MATCH 'norm:one two'}
} {1 3 5 7 9 11 13 15}
do_test fts1b-4.8 {
execsql {SELECT rowid FROM t4 WHERE t4 MATCH 'plusone:two norm:one'}
} {1 5 9 13}
do_test fts1b-4.9 {
execsql {SELECT rowid FROM t4 WHERE t4 MATCH 'two norm:one'}
} {1 3 5 7 9 11 13 15}
finish_test

File diff suppressed because it is too large Load Diff

View File

@@ -1,65 +0,0 @@
# 2006 October 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 testing the FTS1 module, and in particular
# the Porter stemmer.
#
# $Id: fts1d.test,v 1.1 2006/10/01 18:41:21 drh Exp $
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
# If SQLITE_ENABLE_FTS1 is defined, omit this file.
ifcapable !fts1 {
finish_test
return
}
do_test fts1d-1.1 {
execsql {
CREATE VIRTUAL TABLE t1 USING fts1(content, tokenize porter);
INSERT INTO t1(rowid, content) VALUES(1, 'running and jumping');
SELECT rowid FROM t1 WHERE content MATCH 'run jump';
}
} {1}
do_test fts1d-1.2 {
execsql {
SELECT snippet(t1) FROM t1 WHERE t1 MATCH 'run jump';
}
} {{<b>running</b> and <b>jumping</b>}}
do_test fts1d-1.3 {
execsql {
INSERT INTO t1(rowid, content)
VALUES(2, 'abcdefghijklmnopqrstuvwyxz');
SELECT rowid, snippet(t1) FROM t1 WHERE t1 MATCH 'abcdefghijqrstuvwyxz'
}
} {2 <b>abcdefghijklmnopqrstuvwyxz</b>}
do_test fts1d-1.4 {
execsql {
SELECT rowid, snippet(t1) FROM t1 WHERE t1 MATCH 'abcdefghijXXXXqrstuvwyxz'
}
} {2 <b>abcdefghijklmnopqrstuvwyxz</b>}
do_test fts1d-1.5 {
execsql {
INSERT INTO t1(rowid, content)
VALUES(3, 'The value is 123456789');
SELECT rowid, snippet(t1) FROM t1 WHERE t1 MATCH '123789'
}
} {3 {The value is <b>123456789</b>}}
do_test fts1d-1.6 {
execsql {
SELECT rowid, snippet(t1) FROM t1 WHERE t1 MATCH '123000000789'
}
} {3 {The value is <b>123456789</b>}}
finish_test

View File

@@ -1,85 +0,0 @@
# 2006 October 19
#
# The author disclaims copyright to this source code.
#
#*************************************************************************
# This file implements regression tests for SQLite library. The
# focus of this script is testing deletions in the FTS1 module.
#
# $Id: fts1e.test,v 1.1 2006/10/19 23:28:35 shess Exp $
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
# If SQLITE_ENABLE_FTS1 is defined, omit this file.
ifcapable !fts1 {
finish_test
return
}
# Construct a full-text search table containing keywords which are the
# ordinal numbers of the bit positions set for a sequence of integers,
# which are used for the rowid. There are a total of 30 INSERT and
# DELETE statements, so that we'll test both the segmentMerge() merge
# (over the first 16) and the termSelect() merge (over the level-1
# segment and 14 level-0 segments).
db eval {
CREATE VIRTUAL TABLE t1 USING fts1(content);
INSERT INTO t1 (rowid, content) VALUES(1, 'one');
INSERT INTO t1 (rowid, content) VALUES(2, 'two');
INSERT INTO t1 (rowid, content) VALUES(3, 'one two');
INSERT INTO t1 (rowid, content) VALUES(4, 'three');
DELETE FROM t1 WHERE rowid = 1;
INSERT INTO t1 (rowid, content) VALUES(5, 'one three');
INSERT INTO t1 (rowid, content) VALUES(6, 'two three');
INSERT INTO t1 (rowid, content) VALUES(7, 'one two three');
DELETE FROM t1 WHERE rowid = 4;
INSERT INTO t1 (rowid, content) VALUES(8, 'four');
INSERT INTO t1 (rowid, content) VALUES(9, 'one four');
INSERT INTO t1 (rowid, content) VALUES(10, 'two four');
DELETE FROM t1 WHERE rowid = 7;
INSERT INTO t1 (rowid, content) VALUES(11, 'one two four');
INSERT INTO t1 (rowid, content) VALUES(12, 'three four');
INSERT INTO t1 (rowid, content) VALUES(13, 'one three four');
DELETE FROM t1 WHERE rowid = 10;
INSERT INTO t1 (rowid, content) VALUES(14, 'two three four');
INSERT INTO t1 (rowid, content) VALUES(15, 'one two three four');
INSERT INTO t1 (rowid, content) VALUES(16, 'five');
DELETE FROM t1 WHERE rowid = 13;
INSERT INTO t1 (rowid, content) VALUES(17, 'one five');
INSERT INTO t1 (rowid, content) VALUES(18, 'two five');
INSERT INTO t1 (rowid, content) VALUES(19, 'one two five');
DELETE FROM t1 WHERE rowid = 16;
INSERT INTO t1 (rowid, content) VALUES(20, 'three five');
INSERT INTO t1 (rowid, content) VALUES(21, 'one three five');
INSERT INTO t1 (rowid, content) VALUES(22, 'two three five');
DELETE FROM t1 WHERE rowid = 19;
DELETE FROM t1 WHERE rowid = 22;
}
do_test fts1f-1.1 {
execsql {SELECT COUNT(*) FROM t1}
} {14}
do_test fts1e-2.1 {
execsql {SELECT rowid FROM t1 WHERE content MATCH 'one'}
} {3 5 9 11 15 17 21}
do_test fts1e-2.2 {
execsql {SELECT rowid FROM t1 WHERE content MATCH 'two'}
} {2 3 6 11 14 15 18}
do_test fts1e-2.3 {
execsql {SELECT rowid FROM t1 WHERE content MATCH 'three'}
} {5 6 12 14 15 20 21}
do_test fts1e-2.4 {
execsql {SELECT rowid FROM t1 WHERE content MATCH 'four'}
} {8 9 11 12 14 15}
do_test fts1e-2.5 {
execsql {SELECT rowid FROM t1 WHERE content MATCH 'five'}
} {17 18 20 21}
finish_test

View File

@@ -1,90 +0,0 @@
# 2006 October 19
#
# The author disclaims copyright to this source code.
#
#*************************************************************************
# This file implements regression tests for SQLite library. The
# focus of this script is testing updates in the FTS1 module.
#
# $Id: fts1f.test,v 1.2 2007/02/23 00:14:06 shess Exp $
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
# If SQLITE_ENABLE_FTS1 is defined, omit this file.
ifcapable !fts1 {
finish_test
return
}
# Construct a full-text search table containing keywords which are the
# ordinal numbers of the bit positions set for a sequence of integers,
# which are used for the rowid. There are a total of 31 INSERT,
# UPDATE, and DELETE statements, so that we'll test both the
# segmentMerge() merge (over the first 16) and the termSelect() merge
# (over the level-1 segment and 15 level-0 segments).
db eval {
CREATE VIRTUAL TABLE t1 USING fts1(content);
INSERT INTO t1 (rowid, content) VALUES(1, 'one');
INSERT INTO t1 (rowid, content) VALUES(2, 'two');
INSERT INTO t1 (rowid, content) VALUES(3, 'one two');
INSERT INTO t1 (rowid, content) VALUES(4, 'three');
INSERT INTO t1 (rowid, content) VALUES(5, 'one three');
INSERT INTO t1 (rowid, content) VALUES(6, 'two three');
INSERT INTO t1 (rowid, content) VALUES(7, 'one two three');
DELETE FROM t1 WHERE rowid = 4;
INSERT INTO t1 (rowid, content) VALUES(8, 'four');
UPDATE t1 SET content = 'update one three' WHERE rowid = 1;
INSERT INTO t1 (rowid, content) VALUES(9, 'one four');
INSERT INTO t1 (rowid, content) VALUES(10, 'two four');
DELETE FROM t1 WHERE rowid = 7;
INSERT INTO t1 (rowid, content) VALUES(11, 'one two four');
INSERT INTO t1 (rowid, content) VALUES(12, 'three four');
INSERT INTO t1 (rowid, content) VALUES(13, 'one three four');
DELETE FROM t1 WHERE rowid = 10;
INSERT INTO t1 (rowid, content) VALUES(14, 'two three four');
INSERT INTO t1 (rowid, content) VALUES(15, 'one two three four');
UPDATE t1 SET content = 'update two five' WHERE rowid = 8;
INSERT INTO t1 (rowid, content) VALUES(16, 'five');
DELETE FROM t1 WHERE rowid = 13;
INSERT INTO t1 (rowid, content) VALUES(17, 'one five');
INSERT INTO t1 (rowid, content) VALUES(18, 'two five');
INSERT INTO t1 (rowid, content) VALUES(19, 'one two five');
DELETE FROM t1 WHERE rowid = 16;
INSERT INTO t1 (rowid, content) VALUES(20, 'three five');
INSERT INTO t1 (rowid, content) VALUES(21, 'one three five');
INSERT INTO t1 (rowid, content) VALUES(22, 'two three five');
DELETE FROM t1 WHERE rowid = 19;
UPDATE t1 SET content = 'update' WHERE rowid = 15;
}
do_test fts1f-1.1 {
execsql {SELECT COUNT(*) FROM t1}
} {16}
do_test fts1f-2.0 {
execsql {SELECT rowid FROM t1 WHERE content MATCH 'update'}
} {1 8 15}
do_test fts1f-2.1 {
execsql {SELECT rowid FROM t1 WHERE content MATCH 'one'}
} {1 3 5 9 11 17 21}
do_test fts1f-2.2 {
execsql {SELECT rowid FROM t1 WHERE content MATCH 'two'}
} {2 3 6 8 11 14 18 22}
do_test fts1f-2.3 {
execsql {SELECT rowid FROM t1 WHERE content MATCH 'three'}
} {1 5 6 12 14 20 21 22}
do_test fts1f-2.4 {
execsql {SELECT rowid FROM t1 WHERE content MATCH 'four'}
} {9 11 12 14}
do_test fts1f-2.5 {
execsql {SELECT rowid FROM t1 WHERE content MATCH 'five'}
} {8 17 18 20 21 22}
finish_test

View File

@@ -1,88 +0,0 @@
# 2007 January 17
#
# The author disclaims copyright to this source code.
#
#*************************************************************************
# This file implements regression tests for SQLite fts1 library. The
# focus here is testing handling of UPDATE when using UTF-16-encoded
# databases.
#
# $Id: fts1i.test,v 1.2 2007/01/24 03:43:20 drh Exp $
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
# If SQLITE_ENABLE_FTS1 is defined, omit this file.
ifcapable !fts1 {
finish_test
return
}
# Return the UTF-16 representation of the supplied UTF-8 string $str.
# If $nt is true, append two 0x00 bytes as a nul terminator.
# NOTE(shess) Copied from capi3.test.
proc utf16 {str {nt 1}} {
set r [encoding convertto unicode $str]
if {$nt} {
append r "\x00\x00"
}
return $r
}
db eval {
PRAGMA encoding = "UTF-16le";
CREATE VIRTUAL TABLE t1 USING fts1(content);
}
do_test fts1i-1.0 {
execsql {PRAGMA encoding}
} {UTF-16le}
do_test fts1i-1.1 {
execsql {INSERT INTO t1 (rowid, content) VALUES(1, 'one')}
execsql {SELECT content FROM t1 WHERE rowid = 1}
} {one}
do_test fts1i-1.2 {
set sql "INSERT INTO t1 (rowid, content) VALUES(2, 'two')"
set STMT [sqlite3_prepare $DB $sql -1 TAIL]
sqlite3_step $STMT
sqlite3_finalize $STMT
execsql {SELECT content FROM t1 WHERE rowid = 2}
} {two}
do_test fts1i-1.3 {
set sql "INSERT INTO t1 (rowid, content) VALUES(3, 'three')"
set STMT [sqlite3_prepare $DB $sql -1 TAIL]
sqlite3_step $STMT
sqlite3_finalize $STMT
set sql "UPDATE t1 SET content = 'trois' WHERE rowid = 3"
set STMT [sqlite3_prepare $DB $sql -1 TAIL]
sqlite3_step $STMT
sqlite3_finalize $STMT
execsql {SELECT content FROM t1 WHERE rowid = 3}
} {trois}
do_test fts1i-1.4 {
set sql16 [utf16 {INSERT INTO t1 (rowid, content) VALUES(4, 'four')}]
set STMT [sqlite3_prepare16 $DB $sql16 -1 TAIL]
sqlite3_step $STMT
sqlite3_finalize $STMT
execsql {SELECT content FROM t1 WHERE rowid = 4}
} {four}
do_test fts1i-1.5 {
set sql16 [utf16 {INSERT INTO t1 (rowid, content) VALUES(5, 'five')}]
set STMT [sqlite3_prepare16 $DB $sql16 -1 TAIL]
sqlite3_step $STMT
sqlite3_finalize $STMT
set sql "UPDATE t1 SET content = 'cinq' WHERE rowid = 5"
set STMT [sqlite3_prepare $DB $sql -1 TAIL]
sqlite3_step $STMT
sqlite3_finalize $STMT
execsql {SELECT content FROM t1 WHERE rowid = 5}
} {cinq}
finish_test

View File

@@ -1,89 +0,0 @@
# 2007 February 6
#
# The author disclaims copyright to this source code.
#
#*************************************************************************
# This file implements regression tests for SQLite library. This
# tests creating fts1 tables in an attached database.
#
# $Id: fts1j.test,v 1.1 2007/02/07 01:01:18 shess Exp $
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
# If SQLITE_ENABLE_FTS1 is defined, omit this file.
ifcapable !fts1 {
finish_test
return
}
# Clean up anything left over from a previous pass.
forcedelete test2.db
forcedelete test2.db-journal
sqlite3 db2 test2.db
db eval {
CREATE VIRTUAL TABLE t3 USING fts1(content);
INSERT INTO t3 (rowid, content) VALUES(1, "hello world");
}
db2 eval {
CREATE VIRTUAL TABLE t1 USING fts1(content);
INSERT INTO t1 (rowid, content) VALUES(1, "hello world");
INSERT INTO t1 (rowid, content) VALUES(2, "hello there");
INSERT INTO t1 (rowid, content) VALUES(3, "cruel world");
}
# This has always worked because the t1_* tables used by fts1 will be
# the defaults.
do_test fts1j-1.1 {
execsql {
ATTACH DATABASE 'test2.db' AS two;
SELECT rowid FROM t1 WHERE t1 MATCH 'hello';
DETACH DATABASE two;
}
} {1 2}
# Make certain we're detached if there was an error.
catch {db eval {DETACH DATABASE two}}
# In older code, this appears to work fine, but the t2_* tables used
# by fts1 will be created in database 'main' instead of database
# 'two'. It appears to work fine because the tables end up being the
# defaults, but obviously is badly broken if you hope to use things
# other than in the exact same ATTACH setup.
do_test fts1j-1.2 {
execsql {
ATTACH DATABASE 'test2.db' AS two;
CREATE VIRTUAL TABLE two.t2 USING fts1(content);
INSERT INTO t2 (rowid, content) VALUES(1, "hello world");
INSERT INTO t2 (rowid, content) VALUES(2, "hello there");
INSERT INTO t2 (rowid, content) VALUES(3, "cruel world");
SELECT rowid FROM t2 WHERE t2 MATCH 'hello';
DETACH DATABASE two;
}
} {1 2}
catch {db eval {DETACH DATABASE two}}
# In older code, this broke because the fts1 code attempted to create
# t3_* tables in database 'main', but they already existed. Normally
# this wouldn't happen without t3 itself existing, in which case the
# fts1 code would never be called in the first place.
do_test fts1j-1.3 {
execsql {
ATTACH DATABASE 'test2.db' AS two;
CREATE VIRTUAL TABLE two.t3 USING fts1(content);
INSERT INTO two.t3 (rowid, content) VALUES(2, "hello there");
INSERT INTO two.t3 (rowid, content) VALUES(3, "cruel world");
SELECT rowid FROM two.t3 WHERE t3 MATCH 'hello';
DETACH DATABASE two;
} db2
} {2}
catch {db eval {DETACH DATABASE two}}
catch {db2 close}
forcedelete test2.db
finish_test

View File

@@ -1,69 +0,0 @@
# 2007 March 28
#
# The author disclaims copyright to this source code.
#
#*************************************************************************
# This file implements regression tests for SQLite library. The focus
# of this script is testing isspace/isalnum/tolower problems with the
# FTS1 module. Unfortunately, this code isn't a really principled set
# of tests, because it is impossible to know where new uses of these
# functions might appear.
#
# $Id: fts1k.test,v 1.2 2007/12/13 21:54:11 drh Exp $
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
# If SQLITE_ENABLE_FTS1 is defined, omit this file.
ifcapable !fts1 {
finish_test
return
}
# Tests that startsWith() (calls isspace, tolower, isalnum) can handle
# hi-bit chars. parseSpec() also calls isalnum here.
do_test fts1k-1.1 {
execsql "CREATE VIRTUAL TABLE t1 USING fts1(content, \x80)"
} {}
# Additionally tests isspace() call in getToken(), and isalnum() call
# in tokenListToIdList().
do_test fts1k-1.2 {
catch {
execsql "CREATE VIRTUAL TABLE t2 USING fts1(content, tokenize \x80)"
}
sqlite3_errmsg $DB
} "unknown tokenizer: \x80"
# Additionally test final isalnum() in startsWith().
do_test fts1k-1.3 {
execsql "CREATE VIRTUAL TABLE t3 USING fts1(content, tokenize\x80)"
} {}
# The snippet-generation code has calls to isspace() which are sort of
# hard to get to. It finds convenient breakpoints by starting ~40
# chars before and after the matched term, and scanning ~10 chars
# around that position for isspace() characters. The long word with
# embedded hi-bit chars causes one of these isspace() calls to be
# exercised. The version with a couple extra spaces should cause the
# other isspace() call to be exercised. [Both cases have been tested
# in the debugger, but I'm hoping to continue to catch it if simple
# constant changes change things slightly.
#
# The trailing and leading hi-bit chars help with code which tests for
# isspace() to coalesce multiple spaces.
set word "\x80xxxxx\x80xxxxx\x80xxxxx\x80xxxxx\x80xxxxx\x80xxxxx\x80"
set phrase1 "$word $word $word target $word $word $word"
set phrase2 "$word $word $word target $word $word $word"
db eval {CREATE VIRTUAL TABLE t4 USING fts1(content)}
db eval "INSERT INTO t4 (content) VALUES ('$phrase1')"
db eval "INSERT INTO t4 (content) VALUES ('$phrase2')"
do_test fts1k-1.4 {
execsql {SELECT rowid, length(snippet(t4)) FROM t4 WHERE t4 MATCH 'target'}
} {1 111 2 117}
finish_test

View File

@@ -1,65 +0,0 @@
# 2007 April 9
#
# The author disclaims copyright to this source code.
#
#*************************************************************************
# This file implements regression tests for SQLite library. fts1
# DELETE handling assumed all fields were non-null. This was not
# the intention at all.
#
# $Id: fts1l.test,v 1.1 2007/04/09 20:45:42 shess Exp $
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
# If SQLITE_ENABLE_FTS1 is defined, omit this file.
ifcapable !fts1 {
finish_test
return
}
db eval {
CREATE VIRTUAL TABLE t1 USING fts1(col_a, col_b);
INSERT INTO t1(rowid, col_a, col_b) VALUES(1, 'testing', 'testing');
INSERT INTO t1(rowid, col_a, col_b) VALUES(2, 'only a', null);
INSERT INTO t1(rowid, col_a, col_b) VALUES(3, null, 'only b');
INSERT INTO t1(rowid, col_a, col_b) VALUES(4, null, null);
}
do_test fts1m-1.0 {
execsql {
SELECT COUNT(col_a), COUNT(col_b), COUNT(*) FROM t1;
}
} {2 2 4}
do_test fts1m-1.1 {
execsql {
DELETE FROM t1 WHERE rowid = 1;
SELECT COUNT(col_a), COUNT(col_b), COUNT(*) FROM t1;
}
} {1 1 3}
do_test fts1m-1.2 {
execsql {
DELETE FROM t1 WHERE rowid = 2;
SELECT COUNT(col_a), COUNT(col_b), COUNT(*) FROM t1;
}
} {0 1 2}
do_test fts1m-1.3 {
execsql {
DELETE FROM t1 WHERE rowid = 3;
SELECT COUNT(col_a), COUNT(col_b), COUNT(*) FROM t1;
}
} {0 0 1}
do_test fts1m-1.4 {
execsql {
DELETE FROM t1 WHERE rowid = 4;
SELECT COUNT(col_a), COUNT(col_b), COUNT(*) FROM t1;
}
} {0 0 0}
finish_test

View File

@@ -1,50 +0,0 @@
# 2007 July 27
#
# 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 FTS1 module, specifically snippet
# generation. Extracted from fts2o.test.
#
# $Id: fts1m.test,v 1.1 2007/07/25 00:25:20 shess Exp $
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
# If SQLITE_ENABLE_FTS1 is not defined, omit this file.
ifcapable !fts1 {
finish_test
return
}
#---------------------------------------------------------------------
# These tests, fts1m-1.*, test that ticket #2429 is fixed.
#
db eval {
CREATE VIRTUAL TABLE t1 USING fts1(a, b, c);
INSERT INTO t1(a, b, c) VALUES('one three four', 'one four', 'one four two');
}
do_test fts1m-1.1 {
execsql {
SELECT rowid, snippet(t1) FROM t1 WHERE c MATCH 'four';
}
} {1 {one <b>four</b> two}}
do_test fts1m-1.2 {
execsql {
SELECT rowid, snippet(t1) FROM t1 WHERE b MATCH 'four';
}
} {1 {one <b>four</b>}}
do_test fts1m-1.3 {
execsql {
SELECT rowid, snippet(t1) FROM t1 WHERE a MATCH 'four';
}
} {1 {one three <b>four</b>}}
finish_test

View File

@@ -1,45 +0,0 @@
# 2007 July 24
#
# 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 FTS1 module for errors in the handling
# of SQLITE_SCHEMA.
#
# $Id: fts1n.test,v 1.1 2007/07/25 00:38:06 shess Exp $
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
# If SQLITE_ENABLE_FTS1 is not defined, omit this file.
ifcapable !fts1 {
finish_test
return
}
do_test fts1m-1.1 {
execsql {
CREATE VIRTUAL TABLE t1 USING fts1(a, b, c);
INSERT INTO t1(a, b, c) VALUES('one three four', 'one four', 'one two');
SELECT a, b, c FROM t1 WHERE c MATCH 'two';
}
} {{one three four} {one four} {one two}}
# This test was crashing at one point.
#
do_test fts1m-1.2 {
execsql {
SELECT a, b, c FROM t1 WHERE c MATCH 'two';
CREATE TABLE t3(a, b, c);
SELECT a, b, c FROM t1 WHERE c MATCH 'two';
}
} {{one three four} {one four} {one two} {one three four} {one four} {one two}}
finish_test

View File

@@ -1,138 +0,0 @@
# 2007 July 24
#
# 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 FTS1 module rename functionality. Mostly
# copied from fts2o.test.
#
# $Id: fts1o.test,v 1.2 2007/08/30 20:01:33 shess Exp $
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
# If SQLITE_ENABLE_FTS1 is not defined, omit this file.
ifcapable !fts1 {
finish_test
return
}
db eval {
CREATE VIRTUAL TABLE t1 USING fts1(a, b, c);
INSERT INTO t1(a, b, c) VALUES('one three four', 'one four', 'one four two');
}
#---------------------------------------------------------------------
# Test that it is possible to rename an fts1 table.
#
do_test fts1o-1.1 {
execsql { SELECT tbl_name FROM sqlite_master WHERE type = 'table'}
} {t1 t1_content t1_term}
do_test fts1o-1.2 {
execsql { ALTER TABLE t1 RENAME to fts_t1; }
} {}
do_test fts1o-1.3 {
execsql { SELECT rowid, snippet(fts_t1) FROM fts_t1 WHERE a MATCH 'four'; }
} {1 {one three <b>four</b>}}
do_test fts1o-1.4 {
execsql { SELECT tbl_name FROM sqlite_master WHERE type = 'table'}
} {fts_t1 fts_t1_content fts_t1_term}
# See what happens when renaming the fts1 table fails.
#
do_test fts1o-2.1 {
catchsql {
CREATE TABLE t1_term(a, b, c);
ALTER TABLE fts_t1 RENAME to t1;
}
} {1 {SQL logic error}}
do_test fts1o-2.2 {
execsql { SELECT rowid, snippet(fts_t1) FROM fts_t1 WHERE a MATCH 'four'; }
} {1 {one three <b>four</b>}}
do_test fts1o-2.3 {
execsql { SELECT tbl_name FROM sqlite_master WHERE type = 'table'}
} {fts_t1 fts_t1_content fts_t1_term t1_term}
# See what happens when renaming the fts1 table fails inside a transaction.
#
do_test fts1o-3.1 {
execsql {
BEGIN;
INSERT INTO fts_t1(a, b, c) VALUES('one two three', 'one four', 'one two');
}
} {}
do_test fts1o-3.2 {
catchsql {
ALTER TABLE fts_t1 RENAME to t1;
}
} {1 {SQL logic error}}
# NOTE(shess) rowid AS rowid to defeat caching. Otherwise, this
# seg-faults, I suspect that there's something up with a stale
# virtual-table reference, but I'm not quite sure how it happens here
# but not for fts2o.test.
do_test fts1o-3.3 {
execsql { SELECT rowid AS rowid, snippet(fts_t1) FROM fts_t1 WHERE a MATCH 'four'; }
} {1 {one three <b>four</b>}}
do_test fts1o-3.4 {
execsql { SELECT tbl_name FROM sqlite_master WHERE type = 'table'}
} {fts_t1 fts_t1_content fts_t1_term t1_term}
do_test fts1o-3.5 {
execsql COMMIT
execsql {SELECT a FROM fts_t1}
} {{one three four} {one two three}}
do_test fts1o-3.6 {
execsql { SELECT a, b, c FROM fts_t1 WHERE c MATCH 'four'; }
} {{one three four} {one four} {one four two}}
#---------------------------------------------------------------------
# Test that it is possible to rename an fts1 table in an attached
# database.
#
forcedelete test2.db test2.db-journal
do_test fts1o-4.1 {
execsql {
DROP TABLE t1_term;
ALTER TABLE fts_t1 RENAME to t1;
SELECT a, b, c FROM t1 WHERE c MATCH 'two';
}
} {{one three four} {one four} {one four two} {one two three} {one four} {one two}}
do_test fts1o-4.2 {
execsql {
ATTACH 'test2.db' AS aux;
CREATE VIRTUAL TABLE aux.t1 USING fts1(a, b, c);
INSERT INTO aux.t1(a, b, c) VALUES(
'neung song sahm', 'neung see', 'neung see song'
);
}
} {}
do_test fts1o-4.3 {
execsql { SELECT a, b, c FROM aux.t1 WHERE a MATCH 'song'; }
} {{neung song sahm} {neung see} {neung see song}}
do_test fts1o-4.4 {
execsql { SELECT a, b, c FROM t1 WHERE c MATCH 'two'; }
} {{one three four} {one four} {one four two} {one two three} {one four} {one two}}
do_test fts1o-4.5 {
execsql { ALTER TABLE aux.t1 RENAME TO t2 }
} {}
do_test fts1o-4.6 {
execsql { SELECT a, b, c FROM t2 WHERE a MATCH 'song'; }
} {{neung song sahm} {neung see} {neung see song}}
do_test fts1o-4.7 {
execsql { SELECT a, b, c FROM t1 WHERE c MATCH 'two'; }
} {{one three four} {one four} {one four two} {one two three} {one four} {one two}}
finish_test

File diff suppressed because it is too large Load Diff

View File

@@ -1,67 +0,0 @@
# 2008 July 22
#
# 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 runs all tests.
#
# $Id: fts2.test,v 1.2 2008/07/23 18:17:32 drh Exp $
proc lshift {lvar} {
upvar $lvar l
set ret [lindex $l 0]
set l [lrange $l 1 end]
return $ret
}
while {[set arg [lshift argv]] != ""} {
switch -- $arg {
-sharedpagercache {
sqlite3_enable_shared_cache 1
}
-soak {
set G(issoak) 1
}
default {
set argv [linsert $argv 0 $arg]
break
}
}
}
set testdir [file dirname $argv0]
source $testdir/tester.tcl
# If SQLITE_ENABLE_FTS2 is defined, omit this file.
ifcapable !fts2 {
return
}
rename finish_test really_finish_test
proc finish_test {} {}
set G(isquick) 1
set EXCLUDE {
fts2.test
}
# Files to include in the test. If this list is empty then everything
# that is not in the EXCLUDE list is run.
#
set INCLUDE {
}
foreach testfile [lsort -dictionary [glob $testdir/fts2*.test]] {
set tail [file tail $testfile]
if {[lsearch -exact $EXCLUDE $tail]>=0} continue
if {[llength $INCLUDE]>0 && [lsearch -exact $INCLUDE $tail]<0} continue
source $testfile
catch {db close}
if {$sqlite_open_file_count>0} {
puts "$tail did not close all files: $sqlite_open_file_count"
fail_test $tail
set sqlite_open_file_count 0
}
}
set sqlite_open_file_count 0
really_finish_test

View File

@@ -1,202 +0,0 @@
# 2006 September 9
#
# 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 FTS2 module.
#
# $Id: fts2a.test,v 1.2 2007/05/21 21:59:18 shess Exp $
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
# If SQLITE_ENABLE_FTS2 is defined, omit this file.
ifcapable !fts2 {
finish_test
return
}
# Construct a full-text search table containing five keywords:
# one, two, three, four, and five, in various combinations. The
# rowid for each will be a bitmask for the elements it contains.
#
db eval {
CREATE VIRTUAL TABLE t1 USING fts2(content);
INSERT INTO t1(content) VALUES('one');
INSERT INTO t1(content) VALUES('two');
INSERT INTO t1(content) VALUES('one two');
INSERT INTO t1(content) VALUES('three');
INSERT INTO t1(content) VALUES('one three');
INSERT INTO t1(content) VALUES('two three');
INSERT INTO t1(content) VALUES('one two three');
INSERT INTO t1(content) VALUES('four');
INSERT INTO t1(content) VALUES('one four');
INSERT INTO t1(content) VALUES('two four');
INSERT INTO t1(content) VALUES('one two four');
INSERT INTO t1(content) VALUES('three four');
INSERT INTO t1(content) VALUES('one three four');
INSERT INTO t1(content) VALUES('two three four');
INSERT INTO t1(content) VALUES('one two three four');
INSERT INTO t1(content) VALUES('five');
INSERT INTO t1(content) VALUES('one five');
INSERT INTO t1(content) VALUES('two five');
INSERT INTO t1(content) VALUES('one two five');
INSERT INTO t1(content) VALUES('three five');
INSERT INTO t1(content) VALUES('one three five');
INSERT INTO t1(content) VALUES('two three five');
INSERT INTO t1(content) VALUES('one two three five');
INSERT INTO t1(content) VALUES('four five');
INSERT INTO t1(content) VALUES('one four five');
INSERT INTO t1(content) VALUES('two four five');
INSERT INTO t1(content) VALUES('one two four five');
INSERT INTO t1(content) VALUES('three four five');
INSERT INTO t1(content) VALUES('one three four five');
INSERT INTO t1(content) VALUES('two three four five');
INSERT INTO t1(content) VALUES('one two three four five');
}
do_test fts2a-1.1 {
execsql {SELECT rowid FROM t1 WHERE content MATCH 'one'}
} {1 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31}
do_test fts2a-1.2 {
execsql {SELECT rowid FROM t1 WHERE content MATCH 'one two'}
} {3 7 11 15 19 23 27 31}
do_test fts2a-1.3 {
execsql {SELECT rowid FROM t1 WHERE content MATCH 'two one'}
} {3 7 11 15 19 23 27 31}
do_test fts2a-1.4 {
execsql {SELECT rowid FROM t1 WHERE content MATCH 'one two three'}
} {7 15 23 31}
do_test fts2a-1.5 {
execsql {SELECT rowid FROM t1 WHERE content MATCH 'one three two'}
} {7 15 23 31}
do_test fts2a-1.6 {
execsql {SELECT rowid FROM t1 WHERE content MATCH 'two three one'}
} {7 15 23 31}
do_test fts2a-1.7 {
execsql {SELECT rowid FROM t1 WHERE content MATCH 'two one three'}
} {7 15 23 31}
do_test fts2a-1.8 {
execsql {SELECT rowid FROM t1 WHERE content MATCH 'three one two'}
} {7 15 23 31}
do_test fts2a-1.9 {
execsql {SELECT rowid FROM t1 WHERE content MATCH 'three two one'}
} {7 15 23 31}
do_test fts2a-1.10 {
execsql {SELECT rowid FROM t1 WHERE content MATCH 'one two THREE'}
} {7 15 23 31}
do_test fts2a-1.11 {
execsql {SELECT rowid FROM t1 WHERE content MATCH ' ONE Two three '}
} {7 15 23 31}
do_test fts2a-2.1 {
execsql {SELECT rowid FROM t1 WHERE content MATCH '"one"'}
} {1 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31}
do_test fts2a-2.2 {
execsql {SELECT rowid FROM t1 WHERE content MATCH '"one two"'}
} {3 7 11 15 19 23 27 31}
do_test fts2a-2.3 {
execsql {SELECT rowid FROM t1 WHERE content MATCH '"two one"'}
} {}
do_test fts2a-2.4 {
execsql {SELECT rowid FROM t1 WHERE content MATCH '"one two three"'}
} {7 15 23 31}
do_test fts2a-2.5 {
execsql {SELECT rowid FROM t1 WHERE content MATCH '"one three two"'}
} {}
do_test fts2a-2.6 {
execsql {SELECT rowid FROM t1 WHERE content MATCH '"one two three four"'}
} {15 31}
do_test fts2a-2.7 {
execsql {SELECT rowid FROM t1 WHERE content MATCH '"one three two four"'}
} {}
do_test fts2a-2.8 {
execsql {SELECT rowid FROM t1 WHERE content MATCH '"one three five"'}
} {21}
do_test fts2a-2.9 {
execsql {SELECT rowid FROM t1 WHERE content MATCH '"one three" five'}
} {21 29}
do_test fts2a-2.10 {
execsql {SELECT rowid FROM t1 WHERE content MATCH 'five "one three"'}
} {21 29}
do_test fts2a-2.11 {
execsql {SELECT rowid FROM t1 WHERE content MATCH 'five "one three" four'}
} {29}
do_test fts2a-2.12 {
execsql {SELECT rowid FROM t1 WHERE content MATCH 'five four "one three"'}
} {29}
do_test fts2a-2.13 {
execsql {SELECT rowid FROM t1 WHERE content MATCH '"one three" four five'}
} {29}
do_test fts2a-3.1 {
execsql {SELECT rowid FROM t1 WHERE content MATCH 'one'}
} {1 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31}
do_test fts2a-3.2 {
execsql {SELECT rowid FROM t1 WHERE content MATCH 'one -two'}
} {1 5 9 13 17 21 25 29}
do_test fts2a-3.3 {
execsql {SELECT rowid FROM t1 WHERE content MATCH '-two one'}
} {1 5 9 13 17 21 25 29}
do_test fts2a-4.1 {
execsql {SELECT rowid FROM t1 WHERE content MATCH 'one OR two'}
} {1 2 3 5 6 7 9 10 11 13 14 15 17 18 19 21 22 23 25 26 27 29 30 31}
do_test fts2a-4.2 {
execsql {SELECT rowid FROM t1 WHERE content MATCH '"one two" OR three'}
} {3 4 5 6 7 11 12 13 14 15 19 20 21 22 23 27 28 29 30 31}
do_test fts2a-4.3 {
execsql {SELECT rowid FROM t1 WHERE content MATCH 'three OR "one two"'}
} {3 4 5 6 7 11 12 13 14 15 19 20 21 22 23 27 28 29 30 31}
do_test fts2a-4.4 {
execsql {SELECT rowid FROM t1 WHERE content MATCH 'one two OR three'}
} {3 5 7 11 13 15 19 21 23 27 29 31}
do_test fts2a-4.5 {
execsql {SELECT rowid FROM t1 WHERE content MATCH 'three OR two one'}
} {3 5 7 11 13 15 19 21 23 27 29 31}
do_test fts2a-4.6 {
execsql {SELECT rowid FROM t1 WHERE content MATCH 'one two OR three OR four'}
} {3 5 7 9 11 13 15 19 21 23 25 27 29 31}
do_test fts2a-4.7 {
execsql {SELECT rowid FROM t1 WHERE content MATCH 'two OR three OR four one'}
} {3 5 7 9 11 13 15 19 21 23 25 27 29 31}
# Test the ability to handle NULL content
#
do_test fts2a-5.1 {
execsql {INSERT INTO t1(content) VALUES(NULL)}
} {}
do_test fts2a-5.2 {
set rowid [db last_insert_rowid]
execsql {SELECT content FROM t1 WHERE rowid=$rowid}
} {{}}
do_test fts2a-5.3 {
execsql {SELECT rowid FROM t1 WHERE content MATCH NULL}
} {}
# Test the ability to handle non-positive rowids
#
do_test fts2a-6.0 {
execsql {INSERT INTO t1(rowid, content) VALUES(0, 'four five')}
} {}
do_test fts2a-6.1 {
execsql {SELECT content FROM t1 WHERE rowid = 0}
} {{four five}}
do_test fts2a-6.2 {
execsql {INSERT INTO t1(rowid, content) VALUES(-1, 'three four')}
} {}
do_test fts2a-6.3 {
execsql {SELECT content FROM t1 WHERE rowid = -1}
} {{three four}}
do_test fts2a-6.4 {
execsql {SELECT rowid FROM t1 WHERE t1 MATCH 'four'}
} {-1 0 8 9 10 11 12 13 14 15 24 25 26 27 28 29 30 31}
finish_test

View File

@@ -1,147 +0,0 @@
# 2006 September 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 regression tests for SQLite library. The
# focus of this script is testing the FTS2 module.
#
# $Id: fts2b.test,v 1.1 2006/10/19 23:36:26 shess Exp $
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
# If SQLITE_ENABLE_FTS2 is defined, omit this file.
ifcapable !fts2 {
finish_test
return
}
# Fill the full-text index "t1" with phrases in english, spanish,
# and german. For the i-th row, fill in the names for the bits
# that are set in the value of i. The least significant bit is
# 1. For example, the value 5 is 101 in binary which will be
# converted to "one three" in english.
#
proc fill_multilanguage_fulltext_t1 {} {
set english {one two three four five}
set spanish {un dos tres cuatro cinco}
set german {eine zwei drei vier funf}
for {set i 1} {$i<=31} {incr i} {
set cmd "INSERT INTO t1 VALUES"
set vset {}
foreach lang {english spanish german} {
set words {}
for {set j 0; set k 1} {$j<5} {incr j; incr k $k} {
if {$k&$i} {lappend words [lindex [set $lang] $j]}
}
lappend vset "'$words'"
}
set sql "INSERT INTO t1(english,spanish,german) VALUES([join $vset ,])"
# puts $sql
db eval $sql
}
}
# Construct a full-text search table containing five keywords:
# one, two, three, four, and five, in various combinations. The
# rowid for each will be a bitmask for the elements it contains.
#
db eval {
CREATE VIRTUAL TABLE t1 USING fts2(english,spanish,german);
}
fill_multilanguage_fulltext_t1
do_test fts2b-1.1 {
execsql {SELECT rowid FROM t1 WHERE english MATCH 'one'}
} {1 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31}
do_test fts2b-1.2 {
execsql {SELECT rowid FROM t1 WHERE spanish MATCH 'one'}
} {}
do_test fts2b-1.3 {
execsql {SELECT rowid FROM t1 WHERE german MATCH 'one'}
} {}
do_test fts2b-1.4 {
execsql {SELECT rowid FROM t1 WHERE t1 MATCH 'one'}
} {1 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31}
do_test fts2b-1.5 {
execsql {SELECT rowid FROM t1 WHERE t1 MATCH 'one dos drei'}
} {7 15 23 31}
do_test fts2b-1.6 {
execsql {SELECT english, spanish, german FROM t1 WHERE rowid=1}
} {one un eine}
do_test fts2b-1.7 {
execsql {SELECT rowid FROM t1 WHERE t1 MATCH '"one un"'}
} {}
do_test fts2b-2.1 {
execsql {
CREATE VIRTUAL TABLE t2 USING fts2(from,to);
INSERT INTO t2([from],[to]) VALUES ('one two three', 'four five six');
SELECT [from], [to] FROM t2
}
} {{one two three} {four five six}}
# Compute an SQL string that contains the words one, two, three,... to
# describe bits set in the value $i. Only the lower 5 bits are examined.
#
proc wordset {i} {
set x {}
for {set j 0; set k 1} {$j<5} {incr j; incr k $k} {
if {$k&$i} {lappend x [lindex {one two three four five} $j]}
}
return '$x'
}
# Create a new FTS table with three columns:
#
# norm: words for the bits of rowid
# plusone: words for the bits of rowid+1
# invert: words for the bits of ~rowid
#
db eval {
CREATE VIRTUAL TABLE t4 USING fts2([norm],'plusone',"invert");
}
for {set i 1} {$i<=15} {incr i} {
set vset [list [wordset $i] [wordset [expr {$i+1}]] [wordset [expr {~$i}]]]
db eval "INSERT INTO t4(norm,plusone,invert) VALUES([join $vset ,]);"
}
do_test fts2b-4.1 {
execsql {SELECT rowid FROM t4 WHERE t4 MATCH 'norm:one'}
} {1 3 5 7 9 11 13 15}
do_test fts2b-4.2 {
execsql {SELECT rowid FROM t4 WHERE norm MATCH 'one'}
} {1 3 5 7 9 11 13 15}
do_test fts2b-4.3 {
execsql {SELECT rowid FROM t4 WHERE t4 MATCH 'one'}
} {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15}
do_test fts2b-4.4 {
execsql {SELECT rowid FROM t4 WHERE t4 MATCH 'plusone:one'}
} {2 4 6 8 10 12 14}
do_test fts2b-4.5 {
execsql {SELECT rowid FROM t4 WHERE plusone MATCH 'one'}
} {2 4 6 8 10 12 14}
do_test fts2b-4.6 {
execsql {SELECT rowid FROM t4 WHERE t4 MATCH 'norm:one plusone:two'}
} {1 5 9 13}
do_test fts2b-4.7 {
execsql {SELECT rowid FROM t4 WHERE t4 MATCH 'norm:one two'}
} {1 3 5 7 9 11 13 15}
do_test fts2b-4.8 {
execsql {SELECT rowid FROM t4 WHERE t4 MATCH 'plusone:two norm:one'}
} {1 5 9 13}
do_test fts2b-4.9 {
execsql {SELECT rowid FROM t4 WHERE t4 MATCH 'two norm:one'}
} {1 3 5 7 9 11 13 15}
finish_test

File diff suppressed because it is too large Load Diff

View File

@@ -1,65 +0,0 @@
# 2006 October 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 testing the FTS2 module, and in particular
# the Porter stemmer.
#
# $Id: fts2d.test,v 1.1 2006/10/19 23:36:26 shess Exp $
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
# If SQLITE_ENABLE_FTS2 is defined, omit this file.
ifcapable !fts2 {
finish_test
return
}
do_test fts2d-1.1 {
execsql {
CREATE VIRTUAL TABLE t1 USING fts2(content, tokenize porter);
INSERT INTO t1(rowid, content) VALUES(1, 'running and jumping');
SELECT rowid FROM t1 WHERE content MATCH 'run jump';
}
} {1}
do_test fts2d-1.2 {
execsql {
SELECT snippet(t1) FROM t1 WHERE t1 MATCH 'run jump';
}
} {{<b>running</b> and <b>jumping</b>}}
do_test fts2d-1.3 {
execsql {
INSERT INTO t1(rowid, content)
VALUES(2, 'abcdefghijklmnopqrstuvwyxz');
SELECT rowid, snippet(t1) FROM t1 WHERE t1 MATCH 'abcdefghijqrstuvwyxz'
}
} {2 <b>abcdefghijklmnopqrstuvwyxz</b>}
do_test fts2d-1.4 {
execsql {
SELECT rowid, snippet(t1) FROM t1 WHERE t1 MATCH 'abcdefghijXXXXqrstuvwyxz'
}
} {2 <b>abcdefghijklmnopqrstuvwyxz</b>}
do_test fts2d-1.5 {
execsql {
INSERT INTO t1(rowid, content)
VALUES(3, 'The value is 123456789');
SELECT rowid, snippet(t1) FROM t1 WHERE t1 MATCH '123789'
}
} {3 {The value is <b>123456789</b>}}
do_test fts2d-1.6 {
execsql {
SELECT rowid, snippet(t1) FROM t1 WHERE t1 MATCH '123000000789'
}
} {3 {The value is <b>123456789</b>}}
finish_test

View File

@@ -1,85 +0,0 @@
# 2006 October 19
#
# The author disclaims copyright to this source code.
#
#*************************************************************************
# This file implements regression tests for SQLite library. The
# focus of this script is testing deletions in the FTS2 module.
#
# $Id: fts2e.test,v 1.1 2006/10/19 23:36:26 shess Exp $
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
# If SQLITE_ENABLE_FTS2 is defined, omit this file.
ifcapable !fts2 {
finish_test
return
}
# Construct a full-text search table containing keywords which are the
# ordinal numbers of the bit positions set for a sequence of integers,
# which are used for the rowid. There are a total of 30 INSERT and
# DELETE statements, so that we'll test both the segmentMerge() merge
# (over the first 16) and the termSelect() merge (over the level-1
# segment and 14 level-0 segments).
db eval {
CREATE VIRTUAL TABLE t1 USING fts2(content);
INSERT INTO t1 (rowid, content) VALUES(1, 'one');
INSERT INTO t1 (rowid, content) VALUES(2, 'two');
INSERT INTO t1 (rowid, content) VALUES(3, 'one two');
INSERT INTO t1 (rowid, content) VALUES(4, 'three');
DELETE FROM t1 WHERE rowid = 1;
INSERT INTO t1 (rowid, content) VALUES(5, 'one three');
INSERT INTO t1 (rowid, content) VALUES(6, 'two three');
INSERT INTO t1 (rowid, content) VALUES(7, 'one two three');
DELETE FROM t1 WHERE rowid = 4;
INSERT INTO t1 (rowid, content) VALUES(8, 'four');
INSERT INTO t1 (rowid, content) VALUES(9, 'one four');
INSERT INTO t1 (rowid, content) VALUES(10, 'two four');
DELETE FROM t1 WHERE rowid = 7;
INSERT INTO t1 (rowid, content) VALUES(11, 'one two four');
INSERT INTO t1 (rowid, content) VALUES(12, 'three four');
INSERT INTO t1 (rowid, content) VALUES(13, 'one three four');
DELETE FROM t1 WHERE rowid = 10;
INSERT INTO t1 (rowid, content) VALUES(14, 'two three four');
INSERT INTO t1 (rowid, content) VALUES(15, 'one two three four');
INSERT INTO t1 (rowid, content) VALUES(16, 'five');
DELETE FROM t1 WHERE rowid = 13;
INSERT INTO t1 (rowid, content) VALUES(17, 'one five');
INSERT INTO t1 (rowid, content) VALUES(18, 'two five');
INSERT INTO t1 (rowid, content) VALUES(19, 'one two five');
DELETE FROM t1 WHERE rowid = 16;
INSERT INTO t1 (rowid, content) VALUES(20, 'three five');
INSERT INTO t1 (rowid, content) VALUES(21, 'one three five');
INSERT INTO t1 (rowid, content) VALUES(22, 'two three five');
DELETE FROM t1 WHERE rowid = 19;
DELETE FROM t1 WHERE rowid = 22;
}
do_test fts2f-1.1 {
execsql {SELECT COUNT(*) FROM t1}
} {14}
do_test fts2e-2.1 {
execsql {SELECT rowid FROM t1 WHERE content MATCH 'one'}
} {3 5 9 11 15 17 21}
do_test fts2e-2.2 {
execsql {SELECT rowid FROM t1 WHERE content MATCH 'two'}
} {2 3 6 11 14 15 18}
do_test fts2e-2.3 {
execsql {SELECT rowid FROM t1 WHERE content MATCH 'three'}
} {5 6 12 14 15 20 21}
do_test fts2e-2.4 {
execsql {SELECT rowid FROM t1 WHERE content MATCH 'four'}
} {8 9 11 12 14 15}
do_test fts2e-2.5 {
execsql {SELECT rowid FROM t1 WHERE content MATCH 'five'}
} {17 18 20 21}
finish_test

View File

@@ -1,90 +0,0 @@
# 2006 October 19
#
# The author disclaims copyright to this source code.
#
#*************************************************************************
# This file implements regression tests for SQLite library. The
# focus of this script is testing updates in the FTS2 module.
#
# $Id: fts2f.test,v 1.2 2007/02/23 00:14:06 shess Exp $
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
# If SQLITE_ENABLE_FTS2 is defined, omit this file.
ifcapable !fts2 {
finish_test
return
}
# Construct a full-text search table containing keywords which are the
# ordinal numbers of the bit positions set for a sequence of integers,
# which are used for the rowid. There are a total of 31 INSERT,
# UPDATE, and DELETE statements, so that we'll test both the
# segmentMerge() merge (over the first 16) and the termSelect() merge
# (over the level-1 segment and 15 level-0 segments).
db eval {
CREATE VIRTUAL TABLE t1 USING fts2(content);
INSERT INTO t1 (rowid, content) VALUES(1, 'one');
INSERT INTO t1 (rowid, content) VALUES(2, 'two');
INSERT INTO t1 (rowid, content) VALUES(3, 'one two');
INSERT INTO t1 (rowid, content) VALUES(4, 'three');
INSERT INTO t1 (rowid, content) VALUES(5, 'one three');
INSERT INTO t1 (rowid, content) VALUES(6, 'two three');
INSERT INTO t1 (rowid, content) VALUES(7, 'one two three');
DELETE FROM t1 WHERE rowid = 4;
INSERT INTO t1 (rowid, content) VALUES(8, 'four');
UPDATE t1 SET content = 'update one three' WHERE rowid = 1;
INSERT INTO t1 (rowid, content) VALUES(9, 'one four');
INSERT INTO t1 (rowid, content) VALUES(10, 'two four');
DELETE FROM t1 WHERE rowid = 7;
INSERT INTO t1 (rowid, content) VALUES(11, 'one two four');
INSERT INTO t1 (rowid, content) VALUES(12, 'three four');
INSERT INTO t1 (rowid, content) VALUES(13, 'one three four');
DELETE FROM t1 WHERE rowid = 10;
INSERT INTO t1 (rowid, content) VALUES(14, 'two three four');
INSERT INTO t1 (rowid, content) VALUES(15, 'one two three four');
UPDATE t1 SET content = 'update two five' WHERE rowid = 8;
INSERT INTO t1 (rowid, content) VALUES(16, 'five');
DELETE FROM t1 WHERE rowid = 13;
INSERT INTO t1 (rowid, content) VALUES(17, 'one five');
INSERT INTO t1 (rowid, content) VALUES(18, 'two five');
INSERT INTO t1 (rowid, content) VALUES(19, 'one two five');
DELETE FROM t1 WHERE rowid = 16;
INSERT INTO t1 (rowid, content) VALUES(20, 'three five');
INSERT INTO t1 (rowid, content) VALUES(21, 'one three five');
INSERT INTO t1 (rowid, content) VALUES(22, 'two three five');
DELETE FROM t1 WHERE rowid = 19;
UPDATE t1 SET content = 'update' WHERE rowid = 15;
}
do_test fts2f-1.1 {
execsql {SELECT COUNT(*) FROM t1}
} {16}
do_test fts2f-2.0 {
execsql {SELECT rowid FROM t1 WHERE content MATCH 'update'}
} {1 8 15}
do_test fts2f-2.1 {
execsql {SELECT rowid FROM t1 WHERE content MATCH 'one'}
} {1 3 5 9 11 17 21}
do_test fts2f-2.2 {
execsql {SELECT rowid FROM t1 WHERE content MATCH 'two'}
} {2 3 6 8 11 14 18 22}
do_test fts2f-2.3 {
execsql {SELECT rowid FROM t1 WHERE content MATCH 'three'}
} {1 5 6 12 14 20 21 22}
do_test fts2f-2.4 {
execsql {SELECT rowid FROM t1 WHERE content MATCH 'four'}
} {9 11 12 14}
do_test fts2f-2.5 {
execsql {SELECT rowid FROM t1 WHERE content MATCH 'five'}
} {8 17 18 20 21 22}
finish_test

View File

@@ -1,93 +0,0 @@
# 2006 October 19
#
# The author disclaims copyright to this source code.
#
#*************************************************************************
# This file implements regression tests for SQLite library. The focus
# of this script is testing handling of edge cases for various doclist
# merging functions in the FTS2 module query logic.
#
# $Id: fts2g.test,v 1.3 2007/11/16 00:23:08 shess Exp $
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
# If SQLITE_ENABLE_FTS2 is defined, omit this file.
ifcapable !fts2 {
finish_test
return
}
db eval {
CREATE VIRTUAL TABLE t1 USING fts2(content);
INSERT INTO t1 (rowid, content) VALUES(1, 'this is a test');
INSERT INTO t1 (rowid, content) VALUES(2, 'also a test');
}
# No hits at all. Returns empty doclists from termSelect().
do_test fts2g-1.1 {
execsql {SELECT rowid FROM t1 WHERE t1 MATCH 'something'}
} {}
# Empty left in docListExceptMerge().
do_test fts2g-1.2 {
execsql {SELECT rowid FROM t1 WHERE t1 MATCH '-this something'}
} {}
# Empty right in docListExceptMerge().
do_test fts2g-1.3 {
execsql {SELECT rowid FROM t1 WHERE t1 MATCH 'this -something'}
} {1}
# Empty left in docListPhraseMerge().
do_test fts2g-1.4 {
execsql {SELECT rowid FROM t1 WHERE t1 MATCH '"this something"'}
} {}
# Empty right in docListPhraseMerge().
do_test fts2g-1.5 {
execsql {SELECT rowid FROM t1 WHERE t1 MATCH '"something is"'}
} {}
# Empty left in docListOrMerge().
do_test fts2g-1.6 {
execsql {SELECT rowid FROM t1 WHERE t1 MATCH 'something OR this'}
} {1}
# Empty right in docListOrMerge().
do_test fts2g-1.7 {
execsql {SELECT rowid FROM t1 WHERE t1 MATCH 'this OR something'}
} {1}
# Empty left in docListAndMerge().
do_test fts2g-1.8 {
execsql {SELECT rowid FROM t1 WHERE t1 MATCH 'something this'}
} {}
# Empty right in docListAndMerge().
do_test fts2g-1.9 {
execsql {SELECT rowid FROM t1 WHERE t1 MATCH 'this something'}
} {}
# No support for all-except queries.
do_test fts2g-1.10 {
catchsql {SELECT rowid FROM t1 WHERE t1 MATCH '-this -something'}
} {1 {SQL logic error}}
# Test that docListOrMerge() correctly handles reaching the end of one
# doclist before it reaches the end of the other.
do_test fts2g-1.11 {
execsql {SELECT rowid FROM t1 WHERE t1 MATCH 'this OR also'}
} {1 2}
do_test fts2g-1.12 {
execsql {SELECT rowid FROM t1 WHERE t1 MATCH 'also OR this'}
} {1 2}
# Empty left and right in docListOrMerge(). Each term matches neither
# row, and when combined there was an assertion failure.
do_test fts2g-1.13 {
execsql {SELECT rowid FROM t1 WHERE t1 MATCH 'something OR nothing'}
} {}
finish_test

View File

@@ -1,76 +0,0 @@
# 2006 October 31 (scaaarey)
#
# The author disclaims copyright to this source code.
#
#*************************************************************************
# This file implements regression tests for SQLite library. The focus
# here is testing correct handling of excessively long terms.
#
# $Id: fts2h.test,v 1.1 2006/11/29 21:03:01 shess Exp $
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
# If SQLITE_ENABLE_FTS2 is defined, omit this file.
ifcapable !fts2 {
finish_test
return
}
# Generate a term of len copies of char.
proc bigterm {char len} {
for {set term ""} {$len>0} {incr len -1} {
append term $char
}
return $term
}
# Generate a document of bigterms based on characters from the list
# chars.
proc bigtermdoc {chars len} {
set doc ""
foreach char $chars {
append doc " " [bigterm $char $len]
}
return $doc
}
set len 5000
set doc1 [bigtermdoc {a b c d} $len]
set doc2 [bigtermdoc {b d e f} $len]
set doc3 [bigtermdoc {a c e} $len]
set aterm [bigterm a $len]
set bterm [bigterm b $len]
set xterm [bigterm x $len]
db eval {
CREATE VIRTUAL TABLE t1 USING fts2(content);
INSERT INTO t1 (rowid, content) VALUES(1, $doc1);
INSERT INTO t1 (rowid, content) VALUES(2, $doc2);
INSERT INTO t1 (rowid, content) VALUES(3, $doc3);
}
# No hits at all. Returns empty doclists from termSelect().
do_test fts2h-1.1 {
execsql {SELECT rowid FROM t1 WHERE t1 MATCH 'something'}
} {}
do_test fts2h-1.2 {
execsql {SELECT rowid FROM t1 WHERE t1 MATCH $aterm}
} {1 3}
do_test fts2h-1.2 {
execsql {SELECT rowid FROM t1 WHERE t1 MATCH $xterm}
} {}
do_test fts2h-1.3 {
execsql "SELECT rowid FROM t1 WHERE t1 MATCH '$aterm -$xterm'"
} {1 3}
do_test fts2h-1.4 {
execsql "SELECT rowid FROM t1 WHERE t1 MATCH '\"$aterm $bterm\"'"
} {1}
finish_test

View File

@@ -1,87 +0,0 @@
# 2007 January 17
#
# The author disclaims copyright to this source code.
#
#*************************************************************************
# This file implements regression tests for SQLite fts2 library. The
# focus here is testing handling of UPDATE when using UTF-16-encoded
# databases.
#
# $Id: fts2i.test,v 1.2 2007/01/24 03:46:35 drh Exp $
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
# If SQLITE_ENABLE_FTS2 is defined, omit this file.
ifcapable !fts2 {
finish_test
return
}
# Return the UTF-16 representation of the supplied UTF-8 string $str.
# If $nt is true, append two 0x00 bytes as a nul terminator.
# NOTE(shess) Copied from capi3.test.
proc utf16 {str {nt 1}} {
set r [encoding convertto unicode $str]
if {$nt} {
append r "\x00\x00"
}
return $r
}
db eval {
PRAGMA encoding = "UTF-16le";
CREATE VIRTUAL TABLE t1 USING fts2(content);
}
do_test fts2i-1.0 {
execsql {PRAGMA encoding}
} {UTF-16le}
do_test fts2i-1.1 {
execsql {INSERT INTO t1 (rowid, content) VALUES(1, 'one')}
execsql {SELECT content FROM t1 WHERE rowid = 1}
} {one}
do_test fts2i-1.2 {
set sql "INSERT INTO t1 (rowid, content) VALUES(2, 'two')"
set STMT [sqlite3_prepare $DB $sql -1 TAIL]
sqlite3_step $STMT
sqlite3_finalize $STMT
execsql {SELECT content FROM t1 WHERE rowid = 2}
} {two}
do_test fts2i-1.3 {
set sql "INSERT INTO t1 (rowid, content) VALUES(3, 'three')"
set STMT [sqlite3_prepare $DB $sql -1 TAIL]
sqlite3_step $STMT
sqlite3_finalize $STMT
set sql "UPDATE t1 SET content = 'trois' WHERE rowid = 3"
set STMT [sqlite3_prepare $DB $sql -1 TAIL]
sqlite3_step $STMT
sqlite3_finalize $STMT
execsql {SELECT content FROM t1 WHERE rowid = 3}
} {trois}
do_test fts2i-1.4 {
set sql16 [utf16 {INSERT INTO t1 (rowid, content) VALUES(4, 'four')}]
set STMT [sqlite3_prepare16 $DB $sql16 -1 TAIL]
sqlite3_step $STMT
sqlite3_finalize $STMT
execsql {SELECT content FROM t1 WHERE rowid = 4}
} {four}
do_test fts2i-1.5 {
set sql16 [utf16 {INSERT INTO t1 (rowid, content) VALUES(5, 'five')}]
set STMT [sqlite3_prepare16 $DB $sql16 -1 TAIL]
sqlite3_step $STMT
sqlite3_finalize $STMT
set sql "UPDATE t1 SET content = 'cinq' WHERE rowid = 5"
set STMT [sqlite3_prepare $DB $sql -1 TAIL]
sqlite3_step $STMT
sqlite3_finalize $STMT
execsql {SELECT content FROM t1 WHERE rowid = 5}
} {cinq}
finish_test

View File

@@ -1,89 +0,0 @@
# 2007 February 6
#
# The author disclaims copyright to this source code.
#
#*************************************************************************
# This file implements regression tests for SQLite library. This
# tests creating fts2 tables in an attached database.
#
# $Id: fts2j.test,v 1.1 2007/02/07 01:01:18 shess Exp $
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
# If SQLITE_ENABLE_FTS2 is defined, omit this file.
ifcapable !fts2 {
finish_test
return
}
# Clean up anything left over from a previous pass.
forcedelete test2.db
forcedelete test2.db-journal
sqlite3 db2 test2.db
db eval {
CREATE VIRTUAL TABLE t3 USING fts2(content);
INSERT INTO t3 (rowid, content) VALUES(1, "hello world");
}
db2 eval {
CREATE VIRTUAL TABLE t1 USING fts2(content);
INSERT INTO t1 (rowid, content) VALUES(1, "hello world");
INSERT INTO t1 (rowid, content) VALUES(2, "hello there");
INSERT INTO t1 (rowid, content) VALUES(3, "cruel world");
}
# This has always worked because the t1_* tables used by fts2 will be
# the defaults.
do_test fts2j-1.1 {
execsql {
ATTACH DATABASE 'test2.db' AS two;
SELECT rowid FROM t1 WHERE t1 MATCH 'hello';
DETACH DATABASE two;
}
} {1 2}
# Make certain we're detached if there was an error.
catch {db eval {DETACH DATABASE two}}
# In older code, this appears to work fine, but the t2_* tables used
# by fts2 will be created in database 'main' instead of database
# 'two'. It appears to work fine because the tables end up being the
# defaults, but obviously is badly broken if you hope to use things
# other than in the exact same ATTACH setup.
do_test fts2j-1.2 {
execsql {
ATTACH DATABASE 'test2.db' AS two;
CREATE VIRTUAL TABLE two.t2 USING fts2(content);
INSERT INTO t2 (rowid, content) VALUES(1, "hello world");
INSERT INTO t2 (rowid, content) VALUES(2, "hello there");
INSERT INTO t2 (rowid, content) VALUES(3, "cruel world");
SELECT rowid FROM t2 WHERE t2 MATCH 'hello';
DETACH DATABASE two;
}
} {1 2}
catch {db eval {DETACH DATABASE two}}
# In older code, this broke because the fts2 code attempted to create
# t3_* tables in database 'main', but they already existed. Normally
# this wouldn't happen without t3 itself existing, in which case the
# fts2 code would never be called in the first place.
do_test fts2j-1.3 {
execsql {
ATTACH DATABASE 'test2.db' AS two;
CREATE VIRTUAL TABLE two.t3 USING fts2(content);
INSERT INTO two.t3 (rowid, content) VALUES(2, "hello there");
INSERT INTO two.t3 (rowid, content) VALUES(3, "cruel world");
SELECT rowid FROM two.t3 WHERE t3 MATCH 'hello';
DETACH DATABASE two;
} db2
} {2}
catch {db eval {DETACH DATABASE two}}
catch {db2 close}
forcedelete test2.db
finish_test

View File

@@ -1,105 +0,0 @@
# 2007 March 9
#
# The author disclaims copyright to this source code.
#
#*************************************************************************
# This file implements regression tests for SQLite library. These
# make sure that fts2 insertion buffering is fully transparent when
# using transactions.
#
# $Id: fts2k.test,v 1.2 2007/08/10 23:47:04 shess Exp $
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
# If SQLITE_ENABLE_FTS2 is defined, omit this file.
ifcapable !fts2 {
finish_test
return
}
db eval {
CREATE VIRTUAL TABLE t1 USING fts2(content);
INSERT INTO t1 (rowid, content) VALUES(1, "hello world");
INSERT INTO t1 (rowid, content) VALUES(2, "hello there");
INSERT INTO t1 (rowid, content) VALUES(3, "cruel world");
}
# Test that possibly-buffered inserts went through after commit.
do_test fts2k-1.1 {
execsql {
BEGIN TRANSACTION;
INSERT INTO t1 (rowid, content) VALUES(4, "false world");
INSERT INTO t1 (rowid, content) VALUES(5, "false door");
COMMIT TRANSACTION;
SELECT rowid FROM t1 WHERE t1 MATCH 'world';
}
} {1 3 4}
# Test that buffered inserts are seen by selects in the same
# transaction.
do_test fts2k-1.2 {
execsql {
BEGIN TRANSACTION;
INSERT INTO t1 (rowid, content) VALUES(6, "another world");
INSERT INTO t1 (rowid, content) VALUES(7, "another test");
SELECT rowid FROM t1 WHERE t1 MATCH 'world';
COMMIT TRANSACTION;
}
} {1 3 4 6}
# Test that buffered inserts are seen within a transaction. This is
# really the same test as 1.2.
do_test fts2k-1.3 {
execsql {
BEGIN TRANSACTION;
INSERT INTO t1 (rowid, content) VALUES(8, "second world");
INSERT INTO t1 (rowid, content) VALUES(9, "second sight");
SELECT rowid FROM t1 WHERE t1 MATCH 'world';
ROLLBACK TRANSACTION;
}
} {1 3 4 6 8}
# Double-check that the previous result doesn't persist past the
# rollback!
do_test fts2k-1.4 {
execsql {
SELECT rowid FROM t1 WHERE t1 MATCH 'world';
}
} {1 3 4 6}
# Test it all together.
do_test fts2k-1.5 {
execsql {
BEGIN TRANSACTION;
INSERT INTO t1 (rowid, content) VALUES(10, "second world");
INSERT INTO t1 (rowid, content) VALUES(11, "second sight");
ROLLBACK TRANSACTION;
SELECT rowid FROM t1 WHERE t1 MATCH 'world';
}
} {1 3 4 6}
# Test that the obvious case works.
do_test fts2k-1.6 {
execsql {
BEGIN;
INSERT INTO t1 (rowid, content) VALUES(12, "third world");
COMMIT;
SELECT rowid FROM t1 WHERE t1 MATCH 'third';
}
} {12}
# This is exactly the same as the previous test, except that older
# code loses the INSERT due to an SQLITE_SCHEMA error.
do_test fts2k-1.7 {
execsql {
BEGIN;
INSERT INTO t1 (rowid, content) VALUES(13, "third dimension");
CREATE TABLE x (c);
COMMIT;
SELECT rowid FROM t1 WHERE t1 MATCH 'dimension';
}
} {13}
finish_test

View File

@@ -1,69 +0,0 @@
# 2007 March 28
#
# The author disclaims copyright to this source code.
#
#*************************************************************************
# This file implements regression tests for SQLite library. The focus
# of this script is testing isspace/isalnum/tolower problems with the
# FTS2 module. Unfortunately, this code isn't a really principled set
# of tests, because it is impossible to know where new uses of these
# functions might appear.
#
# $Id: fts2l.test,v 1.2 2007/12/13 21:54:11 drh Exp $
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
# If SQLITE_ENABLE_FTS2 is defined, omit this file.
ifcapable !fts2 {
finish_test
return
}
# Tests that startsWith() (calls isspace, tolower, isalnum) can handle
# hi-bit chars. parseSpec() also calls isalnum here.
do_test fts2l-1.1 {
execsql "CREATE VIRTUAL TABLE t1 USING fts2(content, \x80)"
} {}
# Additionally tests isspace() call in getToken(), and isalnum() call
# in tokenListToIdList().
do_test fts2l-1.2 {
catch {
execsql "CREATE VIRTUAL TABLE t2 USING fts2(content, tokenize \x80)"
}
sqlite3_errmsg $DB
} "unknown tokenizer: \x80"
# Additionally test final isalnum() in startsWith().
do_test fts2l-1.3 {
execsql "CREATE VIRTUAL TABLE t3 USING fts2(content, tokenize\x80)"
} {}
# The snippet-generation code has calls to isspace() which are sort of
# hard to get to. It finds convenient breakpoints by starting ~40
# chars before and after the matched term, and scanning ~10 chars
# around that position for isspace() characters. The long word with
# embedded hi-bit chars causes one of these isspace() calls to be
# exercised. The version with a couple extra spaces should cause the
# other isspace() call to be exercised. [Both cases have been tested
# in the debugger, but I'm hoping to continue to catch it if simple
# constant changes change things slightly.
#
# The trailing and leading hi-bit chars help with code which tests for
# isspace() to coalesce multiple spaces.
set word "\x80xxxxx\x80xxxxx\x80xxxxx\x80xxxxx\x80xxxxx\x80xxxxx\x80"
set phrase1 "$word $word $word target $word $word $word"
set phrase2 "$word $word $word target $word $word $word"
db eval {CREATE VIRTUAL TABLE t4 USING fts2(content)}
db eval "INSERT INTO t4 (content) VALUES ('$phrase1')"
db eval "INSERT INTO t4 (content) VALUES ('$phrase2')"
do_test fts2l-1.4 {
execsql {SELECT rowid, length(snippet(t4)) FROM t4 WHERE t4 MATCH 'target'}
} {1 111 2 117}
finish_test

View File

@@ -1,65 +0,0 @@
# 2007 April 9
#
# The author disclaims copyright to this source code.
#
#*************************************************************************
# This file implements regression tests for SQLite library. fts2
# DELETE handling assumed all fields were non-null. This was not
# the intention at all.
#
# $Id: fts2m.test,v 1.1 2007/04/09 20:45:42 shess Exp $
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
# If SQLITE_ENABLE_FTS2 is defined, omit this file.
ifcapable !fts2 {
finish_test
return
}
db eval {
CREATE VIRTUAL TABLE t1 USING fts2(col_a, col_b);
INSERT INTO t1(rowid, col_a, col_b) VALUES(1, 'testing', 'testing');
INSERT INTO t1(rowid, col_a, col_b) VALUES(2, 'only a', null);
INSERT INTO t1(rowid, col_a, col_b) VALUES(3, null, 'only b');
INSERT INTO t1(rowid, col_a, col_b) VALUES(4, null, null);
}
do_test fts2m-1.0 {
execsql {
SELECT COUNT(col_a), COUNT(col_b), COUNT(*) FROM t1;
}
} {2 2 4}
do_test fts2m-1.1 {
execsql {
DELETE FROM t1 WHERE rowid = 1;
SELECT COUNT(col_a), COUNT(col_b), COUNT(*) FROM t1;
}
} {1 1 3}
do_test fts2m-1.2 {
execsql {
DELETE FROM t1 WHERE rowid = 2;
SELECT COUNT(col_a), COUNT(col_b), COUNT(*) FROM t1;
}
} {0 1 2}
do_test fts2m-1.3 {
execsql {
DELETE FROM t1 WHERE rowid = 3;
SELECT COUNT(col_a), COUNT(col_b), COUNT(*) FROM t1;
}
} {0 0 1}
do_test fts2m-1.4 {
execsql {
DELETE FROM t1 WHERE rowid = 4;
SELECT COUNT(col_a), COUNT(col_b), COUNT(*) FROM t1;
}
} {0 0 0}
finish_test

View File

@@ -1,196 +0,0 @@
# 2007 April 26
#
# The author disclaims copyright to this source code.
#
#*************************************************************************
# This file implements tests for prefix-searching in the fts2
# component of the SQLite library.
#
# $Id: fts2n.test,v 1.2 2007/12/13 21:54:11 drh Exp $
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
# If SQLITE_ENABLE_FTS2 is defined, omit this file.
ifcapable !fts2 {
finish_test
return
}
# A large string to prime the pump with.
set text {
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas
iaculis mollis ipsum. Praesent rhoncus placerat justo. Duis non quam
sed turpis posuere placerat. Curabitur et lorem in lorem porttitor
aliquet. Pellentesque bibendum tincidunt diam. Vestibulum blandit
ante nec elit. In sapien diam, facilisis eget, dictum sed, viverra
at, felis. Vestibulum magna. Sed magna dolor, vestibulum rhoncus,
ornare vel, vulputate sit amet, felis. Integer malesuada, tellus at
luctus gravida, diam nunc porta nibh, nec imperdiet massa metus eu
lectus. Aliquam nisi. Nunc fringilla nulla at lectus. Suspendisse
potenti. Cum sociis natoque penatibus et magnis dis parturient
montes, nascetur ridiculus mus. Pellentesque odio nulla, feugiat eu,
suscipit nec, consequat quis, risus.
}
db eval {
CREATE VIRTUAL TABLE t1 USING fts2(c);
INSERT INTO t1(rowid, c) VALUES(1, $text);
INSERT INTO t1(rowid, c) VALUES(2, 'Another lovely row');
}
# Exact match
do_test fts2n-1.1 {
execsql "SELECT rowid FROM t1 WHERE t1 MATCH 'lorem'"
} {1}
# And a prefix
do_test fts2n-1.2 {
execsql "SELECT rowid FROM t1 WHERE t1 MATCH 'lore*'"
} {1}
# Prefix includes exact match
do_test fts2n-1.3 {
execsql "SELECT rowid FROM t1 WHERE t1 MATCH 'lorem*'"
} {1}
# Make certain everything isn't considered a prefix!
do_test fts2n-1.4 {
execsql "SELECT rowid FROM t1 WHERE t1 MATCH 'lore'"
} {}
# Prefix across multiple rows.
do_test fts2n-1.5 {
execsql "SELECT rowid FROM t1 WHERE t1 MATCH 'lo*'"
} {1 2}
# Likewise, with multiple hits in one document.
do_test fts2n-1.6 {
execsql "SELECT rowid FROM t1 WHERE t1 MATCH 'l*'"
} {1 2}
# Prefix which should only hit one document.
do_test fts2n-1.7 {
execsql "SELECT rowid FROM t1 WHERE t1 MATCH 'lov*'"
} {2}
# * not at end is dropped.
do_test fts2n-1.8 {
execsql "SELECT rowid FROM t1 WHERE t1 MATCH 'lo *'"
} {}
# Stand-alone * is dropped.
do_test fts2n-1.9 {
execsql "SELECT rowid FROM t1 WHERE t1 MATCH '*'"
} {}
# Phrase-query prefix.
do_test fts2n-1.10 {
execsql "SELECT rowid FROM t1 WHERE t1 MATCH '\"lovely r*\"'"
} {2}
do_test fts2n-1.11 {
execsql "SELECT rowid FROM t1 WHERE t1 MATCH '\"lovely r\"'"
} {}
# Phrase query with multiple prefix matches.
do_test fts2n-1.12 {
execsql "SELECT rowid FROM t1 WHERE t1 MATCH '\"a* l*\"'"
} {1 2}
# Phrase query with multiple prefix matches.
do_test fts2n-1.13 {
execsql "SELECT rowid FROM t1 WHERE t1 MATCH '\"a* l* row\"'"
} {2}
# Test across updates (and, by implication, deletes).
# Version of text without "lorem".
regsub -all {[Ll]orem} $text '' ntext
db eval {
CREATE VIRTUAL TABLE t2 USING fts2(c);
INSERT INTO t2(rowid, c) VALUES(1, $text);
INSERT INTO t2(rowid, c) VALUES(2, 'Another lovely row');
UPDATE t2 SET c = $ntext WHERE rowid = 1;
}
# Can't see lorem as an exact match.
do_test fts2n-2.1 {
execsql "SELECT rowid FROM t2 WHERE t2 MATCH 'lorem'"
} {}
# Can't see a prefix of lorem, either.
do_test fts2n-2.2 {
execsql "SELECT rowid FROM t2 WHERE t2 MATCH 'lore*'"
} {}
# Can see lovely in the other document.
do_test fts2n-2.3 {
execsql "SELECT rowid FROM t2 WHERE t2 MATCH 'lo*'"
} {2}
# Can still see other hits.
do_test fts2n-2.4 {
execsql "SELECT rowid FROM t2 WHERE t2 MATCH 'l*'"
} {1 2}
# Prefix which should only hit one document.
do_test fts2n-2.5 {
execsql "SELECT rowid FROM t2 WHERE t2 MATCH 'lov*'"
} {2}
# Test with a segment which will have multiple levels in the tree.
# Build a big document with lots of unique terms.
set bigtext $text
foreach c {a b c d e} {
regsub -all {[A-Za-z]+} $bigtext "&$c" t
append bigtext $t
}
# Populate a table with many copies of the big document, so that we
# can test the number of hits found. Populate $ret with the expected
# hit counts for each row. offsets() returns 4 elements for every
# hit. We'll have 6 hits for row 1, 1 for row 2, and 6*(2^5)==192 for
# $bigtext.
set ret {6 1}
db eval {
BEGIN;
CREATE VIRTUAL TABLE t3 USING fts2(c);
INSERT INTO t3(rowid, c) VALUES(1, $text);
INSERT INTO t3(rowid, c) VALUES(2, 'Another lovely row');
}
for {set i 0} {$i<100} {incr i} {
db eval {INSERT INTO t3(rowid, c) VALUES(3+$i, $bigtext)}
lappend ret 192
}
db eval {COMMIT;}
# Test that we get the expected number of hits.
do_test fts2n-3.1 {
set t {}
db eval {SELECT offsets(t3) as o FROM t3 WHERE t3 MATCH 'l*'} {
set l [llength $o]
lappend t [expr {$l/4}]
}
set t
} $ret
# TODO(shess) It would be useful to test a couple edge cases, but I
# don't know if we have the precision to manage it from here at this
# time. Prefix hits can cross leaves, which the code above _should_
# hit by virtue of size. There are two variations on this. If the
# tree is 2 levels high, the code will find the leaf-node extent
# directly, but if its higher, the code will have to follow two
# separate interior branches down the tree. Both should be tested.
finish_test

View File

@@ -1,169 +0,0 @@
# 2007 June 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.
#
#*************************************************************************
# This file implements regression tests for SQLite library. The
# focus of this script is testing the FTS2 module.
#
# $Id: fts2o.test,v 1.4 2007/07/02 10:16:50 danielk1977 Exp $
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
# If SQLITE_ENABLE_FTS2 is not defined, omit this file.
ifcapable !fts2 {
finish_test
return
}
#---------------------------------------------------------------------
# These tests, fts2o-1.*, test that ticket #2429 is fixed.
#
db eval {
CREATE VIRTUAL TABLE t1 USING fts2(a, b, c);
INSERT INTO t1(a, b, c) VALUES('one three four', 'one four', 'one four two');
}
do_test fts2o-1.1 {
execsql {
SELECT rowid, snippet(t1) FROM t1 WHERE c MATCH 'four';
}
} {1 {one <b>four</b> two}}
do_test fts2o-1.2 {
execsql {
SELECT rowid, snippet(t1) FROM t1 WHERE b MATCH 'four';
}
} {1 {one <b>four</b>}}
do_test fts2o-1.3 {
execsql {
SELECT rowid, snippet(t1) FROM t1 WHERE a MATCH 'four';
}
} {1 {one three <b>four</b>}}
#---------------------------------------------------------------------
# Test that it is possible to rename an fts2 table.
#
do_test fts2o-2.1 {
execsql { SELECT tbl_name FROM sqlite_master WHERE type = 'table'}
} {t1 t1_content t1_segments t1_segdir}
do_test fts2o-2.2 {
execsql { ALTER TABLE t1 RENAME to fts_t1; }
} {}
do_test fts2o-2.3 {
execsql { SELECT rowid, snippet(fts_t1) FROM fts_t1 WHERE a MATCH 'four'; }
} {1 {one three <b>four</b>}}
do_test fts2o-2.4 {
execsql { SELECT tbl_name FROM sqlite_master WHERE type = 'table'}
} {fts_t1 fts_t1_content fts_t1_segments fts_t1_segdir}
# See what happens when renaming the fts2 table fails.
#
do_test fts2o-2.5 {
catchsql {
CREATE TABLE t1_segdir(a, b, c);
ALTER TABLE fts_t1 RENAME to t1;
}
} {1 {SQL logic error}}
do_test fts2o-2.6 {
execsql { SELECT rowid, snippet(fts_t1) FROM fts_t1 WHERE a MATCH 'four'; }
} {1 {one three <b>four</b>}}
do_test fts2o-2.7 {
execsql { SELECT tbl_name FROM sqlite_master WHERE type = 'table'}
} {fts_t1 fts_t1_content fts_t1_segments fts_t1_segdir t1_segdir}
# See what happens when renaming the fts2 table fails inside a transaction.
#
do_test fts2o-2.8 {
execsql {
BEGIN;
INSERT INTO fts_t1(a, b, c) VALUES('one two three', 'one four', 'one two');
}
} {}
do_test fts2o-2.9 {
catchsql {
ALTER TABLE fts_t1 RENAME to t1;
}
} {1 {SQL logic error}}
do_test fts2o-2.10 {
execsql { SELECT rowid, snippet(fts_t1) FROM fts_t1 WHERE a MATCH 'four'; }
} {1 {one three <b>four</b>}}
do_test fts2o-2.11 {
execsql { SELECT tbl_name FROM sqlite_master WHERE type = 'table'}
} {fts_t1 fts_t1_content fts_t1_segments fts_t1_segdir t1_segdir}
do_test fts2o-2.12 {
execsql COMMIT
execsql {SELECT a FROM fts_t1}
} {{one three four} {one two three}}
do_test fts2o-2.12 {
execsql { SELECT a, b, c FROM fts_t1 WHERE c MATCH 'four'; }
} {{one three four} {one four} {one four two}}
#-------------------------------------------------------------------
# Close, delete and reopen the database. The following test should
# be run on an initially empty db.
#
db close
forcedelete test.db test.db-journal
sqlite3 db test.db
do_test fts2o-3.1 {
execsql {
CREATE VIRTUAL TABLE t1 USING fts2(a, b, c);
INSERT INTO t1(a, b, c) VALUES('one three four', 'one four', 'one two');
SELECT a, b, c FROM t1 WHERE c MATCH 'two';
}
} {{one three four} {one four} {one two}}
# This test was crashing at one point.
#
do_test fts2o-3.2 {
execsql {
SELECT a, b, c FROM t1 WHERE c MATCH 'two';
CREATE TABLE t3(a, b, c);
SELECT a, b, c FROM t1 WHERE c MATCH 'two';
}
} {{one three four} {one four} {one two} {one three four} {one four} {one two}}
#---------------------------------------------------------------------
# Test that it is possible to rename an fts2 table in an attached
# database.
#
forcedelete test2.db test2.db-journal
do_test fts2o-3.1 {
execsql {
ATTACH 'test2.db' AS aux;
CREATE VIRTUAL TABLE aux.t1 USING fts2(a, b, c);
INSERT INTO aux.t1(a, b, c) VALUES(
'neung song sahm', 'neung see', 'neung see song'
);
}
} {}
do_test fts2o-3.2 {
execsql { SELECT a, b, c FROM aux.t1 WHERE a MATCH 'song'; }
} {{neung song sahm} {neung see} {neung see song}}
do_test fts2o-3.3 {
execsql { SELECT a, b, c FROM t1 WHERE c MATCH 'two'; }
} {{one three four} {one four} {one two}}
do_test fts2o-3.4 {
execsql { ALTER TABLE aux.t1 RENAME TO t2 }
} {}
do_test fts2o-3.2 {
execsql { SELECT a, b, c FROM t2 WHERE a MATCH 'song'; }
} {{neung song sahm} {neung see} {neung see song}}
do_test fts2o-3.3 {
execsql { SELECT a, b, c FROM t1 WHERE c MATCH 'two'; }
} {{one three four} {one four} {one two}}
finish_test

View File

@@ -1,357 +0,0 @@
# 2008 June 26
#
# 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 exercises some new testing functions in the FTS2 module,
# and then uses them to do some basic tests that FTS2 is internally
# working as expected.
#
# $Id: fts2p.test,v 1.1 2008/07/22 23:32:28 shess Exp $
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
# If SQLITE_ENABLE_FTS2 is not defined, omit this file.
ifcapable !fts2 {
finish_test
return
}
#*************************************************************************
# Probe to see if support for these functions is compiled in.
# TODO(shess): Change main.mk to do the right thing and remove this test.
db eval {
DROP TABLE IF EXISTS t1;
CREATE VIRTUAL TABLE t1 USING fts2(c);
INSERT INTO t1 (rowid, c) VALUES (1, 'x');
}
set s {SELECT dump_terms(t1, 1) FROM t1 LIMIT 1}
set r {1 {unable to use function dump_terms in the requested context}}
if {[catchsql $s]==$r} {
finish_test
return
}
#*************************************************************************
# Test that the new functions give appropriate errors.
do_test fts2p-0.0 {
catchsql {
SELECT dump_terms(t1, 1) FROM t1 LIMIT 1;
}
} {1 {dump_terms: incorrect arguments}}
do_test fts2p-0.1 {
catchsql {
SELECT dump_terms(t1, 0, 0, 0) FROM t1 LIMIT 1;
}
} {1 {dump_terms: incorrect arguments}}
do_test fts2p-0.2 {
catchsql {
SELECT dump_terms(1, t1) FROM t1 LIMIT 1;
}
} {1 {unable to use function dump_terms in the requested context}}
do_test fts2p-0.3 {
catchsql {
SELECT dump_terms(t1, 16, 16) FROM t1 LIMIT 1;
}
} {1 {dump_terms: segment not found}}
do_test fts2p-0.4 {
catchsql {
SELECT dump_doclist(t1) FROM t1 LIMIT 1;
}
} {1 {dump_doclist: incorrect arguments}}
do_test fts2p-0.5 {
catchsql {
SELECT dump_doclist(t1, NULL) FROM t1 LIMIT 1;
}
} {1 {dump_doclist: empty second argument}}
do_test fts2p-0.6 {
catchsql {
SELECT dump_doclist(t1, '') FROM t1 LIMIT 1;
}
} {1 {dump_doclist: empty second argument}}
do_test fts2p-0.7 {
catchsql {
SELECT dump_doclist(t1, 'a', 0) FROM t1 LIMIT 1;
}
} {1 {dump_doclist: incorrect arguments}}
do_test fts2p-0.8 {
catchsql {
SELECT dump_doclist(t1, 'a', 0, 0, 0) FROM t1 LIMIT 1;
}
} {1 {dump_doclist: incorrect arguments}}
do_test fts2p-0.9 {
catchsql {
SELECT dump_doclist(t1, 'a', 16, 16) FROM t1 LIMIT 1;
}
} {1 {dump_doclist: segment not found}}
#*************************************************************************
# Utility function to check for the expected terms in the segment
# level/index. _all version does same but for entire index.
proc check_terms {test level index terms} {
# TODO(shess): Figure out why uplevel in do_test can't catch
# $level and $index directly.
set ::level $level
set ::index $index
do_test $test.terms {
execsql {
SELECT dump_terms(t1, $::level, $::index) FROM t1 LIMIT 1;
}
} [list $terms]
}
proc check_terms_all {test terms} {
do_test $test.terms {
execsql {
SELECT dump_terms(t1) FROM t1 LIMIT 1;
}
} [list $terms]
}
# Utility function to check for the expected doclist for the term in
# segment level/index. _all version does same for entire index.
proc check_doclist {test level index term doclist} {
# TODO(shess): Again, why can't the non-:: versions work?
set ::term $term
set ::level $level
set ::index $index
do_test $test {
execsql {
SELECT dump_doclist(t1, $::term, $::level, $::index) FROM t1 LIMIT 1;
}
} [list $doclist]
}
proc check_doclist_all {test term doclist} {
set ::term $term
do_test $test {
execsql {
SELECT dump_doclist(t1, $::term) FROM t1 LIMIT 1;
}
} [list $doclist]
}
#*************************************************************************
# Test the segments resulting from straight-forward inserts.
db eval {
DROP TABLE IF EXISTS t1;
CREATE VIRTUAL TABLE t1 USING fts2(c);
INSERT INTO t1 (rowid, c) VALUES (1, 'This is a test');
INSERT INTO t1 (rowid, c) VALUES (2, 'That was a test');
INSERT INTO t1 (rowid, c) VALUES (3, 'This is a test');
}
# Check for expected segments and expected matches.
do_test fts2p-1.0.segments {
execsql {
SELECT level, idx FROM t1_segdir ORDER BY level, idx;
}
} {0 0 0 1 0 2}
do_test fts2p-1.0.matches {
execsql {
SELECT OFFSETS(t1) FROM t1
WHERE t1 MATCH 'this OR that OR was OR a OR is OR test' ORDER BY rowid;
}
} [list {0 0 0 4 0 4 5 2 0 3 8 1 0 5 10 4} \
{0 1 0 4 0 2 5 3 0 3 9 1 0 5 11 4} \
{0 0 0 4 0 4 5 2 0 3 8 1 0 5 10 4}]
# Check the specifics of the segments constructed.
# Logical view of entire index.
check_terms_all fts2p-1.0.1 {a is test that this was}
check_doclist_all fts2p-1.0.1.1 a {[1 0[2]] [2 0[2]] [3 0[2]]}
check_doclist_all fts2p-1.0.1.2 is {[1 0[1]] [3 0[1]]}
check_doclist_all fts2p-1.0.1.3 test {[1 0[3]] [2 0[3]] [3 0[3]]}
check_doclist_all fts2p-1.0.1.4 that {[2 0[0]]}
check_doclist_all fts2p-1.0.1.5 this {[1 0[0]] [3 0[0]]}
check_doclist_all fts2p-1.0.1.6 was {[2 0[1]]}
# Segment 0,0
check_terms fts2p-1.0.2 0 0 {a is test this}
check_doclist fts2p-1.0.2.1 0 0 a {[1 0[2]]}
check_doclist fts2p-1.0.2.2 0 0 is {[1 0[1]]}
check_doclist fts2p-1.0.2.3 0 0 test {[1 0[3]]}
check_doclist fts2p-1.0.2.4 0 0 this {[1 0[0]]}
# Segment 0,1
check_terms fts2p-1.0.3 0 1 {a test that was}
check_doclist fts2p-1.0.3.1 0 1 a {[2 0[2]]}
check_doclist fts2p-1.0.3.2 0 1 test {[2 0[3]]}
check_doclist fts2p-1.0.3.3 0 1 that {[2 0[0]]}
check_doclist fts2p-1.0.3.4 0 1 was {[2 0[1]]}
# Segment 0,2
check_terms fts2p-1.0.4 0 2 {a is test this}
check_doclist fts2p-1.0.4.1 0 2 a {[3 0[2]]}
check_doclist fts2p-1.0.4.2 0 2 is {[3 0[1]]}
check_doclist fts2p-1.0.4.3 0 2 test {[3 0[3]]}
check_doclist fts2p-1.0.4.4 0 2 this {[3 0[0]]}
#*************************************************************************
# Test the segments resulting from inserts followed by a delete.
db eval {
DROP TABLE IF EXISTS t1;
CREATE VIRTUAL TABLE t1 USING fts2(c);
INSERT INTO t1 (rowid, c) VALUES (1, 'This is a test');
INSERT INTO t1 (rowid, c) VALUES (2, 'That was a test');
INSERT INTO t1 (rowid, c) VALUES (3, 'This is a test');
DELETE FROM t1 WHERE rowid = 1;
}
do_test fts2p-1.1.segments {
execsql {
SELECT level, idx FROM t1_segdir ORDER BY level, idx;
}
} {0 0 0 1 0 2 0 3}
do_test fts2p-1.1.matches {
execsql {
SELECT OFFSETS(t1) FROM t1
WHERE t1 MATCH 'this OR that OR was OR a OR is OR test' ORDER BY rowid;
}
} {{0 1 0 4 0 2 5 3 0 3 9 1 0 5 11 4} {0 0 0 4 0 4 5 2 0 3 8 1 0 5 10 4}}
check_terms_all fts2p-1.1.1 {a is test that this was}
check_doclist_all fts2p-1.1.1.1 a {[2 0[2]] [3 0[2]]}
check_doclist_all fts2p-1.1.1.2 is {[3 0[1]]}
check_doclist_all fts2p-1.1.1.3 test {[2 0[3]] [3 0[3]]}
check_doclist_all fts2p-1.1.1.4 that {[2 0[0]]}
check_doclist_all fts2p-1.1.1.5 this {[3 0[0]]}
check_doclist_all fts2p-1.1.1.6 was {[2 0[1]]}
check_terms fts2p-1.1.2 0 0 {a is test this}
check_doclist fts2p-1.1.2.1 0 0 a {[1 0[2]]}
check_doclist fts2p-1.1.2.2 0 0 is {[1 0[1]]}
check_doclist fts2p-1.1.2.3 0 0 test {[1 0[3]]}
check_doclist fts2p-1.1.2.4 0 0 this {[1 0[0]]}
check_terms fts2p-1.1.3 0 1 {a test that was}
check_doclist fts2p-1.1.3.1 0 1 a {[2 0[2]]}
check_doclist fts2p-1.1.3.2 0 1 test {[2 0[3]]}
check_doclist fts2p-1.1.3.3 0 1 that {[2 0[0]]}
check_doclist fts2p-1.1.3.4 0 1 was {[2 0[1]]}
check_terms fts2p-1.1.4 0 2 {a is test this}
check_doclist fts2p-1.1.4.1 0 2 a {[3 0[2]]}
check_doclist fts2p-1.1.4.2 0 2 is {[3 0[1]]}
check_doclist fts2p-1.1.4.3 0 2 test {[3 0[3]]}
check_doclist fts2p-1.1.4.4 0 2 this {[3 0[0]]}
check_terms fts2p-1.1.5 0 3 {a is test this}
check_doclist fts2p-1.1.5.1 0 3 a {[1]}
check_doclist fts2p-1.1.5.2 0 3 is {[1]}
check_doclist fts2p-1.1.5.3 0 3 test {[1]}
check_doclist fts2p-1.1.5.4 0 3 this {[1]}
#*************************************************************************
# Test results when all references to certain tokens are deleted.
db eval {
DROP TABLE IF EXISTS t1;
CREATE VIRTUAL TABLE t1 USING fts2(c);
INSERT INTO t1 (rowid, c) VALUES (1, 'This is a test');
INSERT INTO t1 (rowid, c) VALUES (2, 'That was a test');
INSERT INTO t1 (rowid, c) VALUES (3, 'This is a test');
DELETE FROM t1 WHERE rowid IN (1,3);
}
# Still 4 segments because 0,3 will contain deletes for rowid 1 and 3.
do_test fts2p-1.2.segments {
execsql {
SELECT level, idx FROM t1_segdir ORDER BY level, idx;
}
} {0 0 0 1 0 2 0 3}
do_test fts2p-1.2.matches {
execsql {
SELECT OFFSETS(t1) FROM t1
WHERE t1 MATCH 'this OR that OR was OR a OR is OR test' ORDER BY rowid;
}
} {{0 1 0 4 0 2 5 3 0 3 9 1 0 5 11 4}}
check_terms_all fts2p-1.2.1 {a is test that this was}
check_doclist_all fts2p-1.2.1.1 a {[2 0[2]]}
check_doclist_all fts2p-1.2.1.2 is {}
check_doclist_all fts2p-1.2.1.3 test {[2 0[3]]}
check_doclist_all fts2p-1.2.1.4 that {[2 0[0]]}
check_doclist_all fts2p-1.2.1.5 this {}
check_doclist_all fts2p-1.2.1.6 was {[2 0[1]]}
check_terms fts2p-1.2.2 0 0 {a is test this}
check_doclist fts2p-1.2.2.1 0 0 a {[1 0[2]]}
check_doclist fts2p-1.2.2.2 0 0 is {[1 0[1]]}
check_doclist fts2p-1.2.2.3 0 0 test {[1 0[3]]}
check_doclist fts2p-1.2.2.4 0 0 this {[1 0[0]]}
check_terms fts2p-1.2.3 0 1 {a test that was}
check_doclist fts2p-1.2.3.1 0 1 a {[2 0[2]]}
check_doclist fts2p-1.2.3.2 0 1 test {[2 0[3]]}
check_doclist fts2p-1.2.3.3 0 1 that {[2 0[0]]}
check_doclist fts2p-1.2.3.4 0 1 was {[2 0[1]]}
check_terms fts2p-1.2.4 0 2 {a is test this}
check_doclist fts2p-1.2.4.1 0 2 a {[3 0[2]]}
check_doclist fts2p-1.2.4.2 0 2 is {[3 0[1]]}
check_doclist fts2p-1.2.4.3 0 2 test {[3 0[3]]}
check_doclist fts2p-1.2.4.4 0 2 this {[3 0[0]]}
check_terms fts2p-1.2.5 0 3 {a is test this}
check_doclist fts2p-1.2.5.1 0 3 a {[1] [3]}
check_doclist fts2p-1.2.5.2 0 3 is {[1] [3]}
check_doclist fts2p-1.2.5.3 0 3 test {[1] [3]}
check_doclist fts2p-1.2.5.4 0 3 this {[1] [3]}
#*************************************************************************
# Test results when everything is optimized manually.
db eval {
DROP TABLE IF EXISTS t1;
CREATE VIRTUAL TABLE t1 USING fts2(c);
INSERT INTO t1 (rowid, c) VALUES (1, 'This is a test');
INSERT INTO t1 (rowid, c) VALUES (2, 'That was a test');
INSERT INTO t1 (rowid, c) VALUES (3, 'This is a test');
DELETE FROM t1 WHERE rowid IN (1,3);
DROP TABLE IF EXISTS t1old;
ALTER TABLE t1 RENAME TO t1old;
CREATE VIRTUAL TABLE t1 USING fts2(c);
INSERT INTO t1 (rowid, c) SELECT rowid, c FROM t1old;
DROP TABLE t1old;
}
# Should be a single optimal segment with the same logical results.
do_test fts2p-1.3.segments {
execsql {
SELECT level, idx FROM t1_segdir ORDER BY level, idx;
}
} {0 0}
do_test fts2p-1.3.matches {
execsql {
SELECT OFFSETS(t1) FROM t1
WHERE t1 MATCH 'this OR that OR was OR a OR is OR test' ORDER BY rowid;
}
} {{0 1 0 4 0 2 5 3 0 3 9 1 0 5 11 4}}
check_terms_all fts2p-1.3.1 {a test that was}
check_doclist_all fts2p-1.3.1.1 a {[2 0[2]]}
check_doclist_all fts2p-1.3.1.2 test {[2 0[3]]}
check_doclist_all fts2p-1.3.1.3 that {[2 0[0]]}
check_doclist_all fts2p-1.3.1.4 was {[2 0[1]]}
check_terms fts2p-1.3.2 0 0 {a test that was}
check_doclist fts2p-1.3.2.1 0 0 a {[2 0[2]]}
check_doclist fts2p-1.3.2.2 0 0 test {[2 0[3]]}
check_doclist fts2p-1.3.2.3 0 0 that {[2 0[0]]}
check_doclist fts2p-1.3.2.4 0 0 was {[2 0[1]]}
finish_test

View File

@@ -1,346 +0,0 @@
# 2008 June 26
#
# 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 FTS2 module's optimize() function.
#
# $Id: fts2q.test,v 1.2 2008/07/22 23:49:44 shess Exp $
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
# If SQLITE_ENABLE_FTS2 is not defined, omit this file.
ifcapable !fts2 {
finish_test
return
}
#*************************************************************************
# Probe to see if support for the FTS2 dump_* functions is compiled in.
# TODO(shess): Change main.mk to do the right thing and remove this test.
db eval {
DROP TABLE IF EXISTS t1;
CREATE VIRTUAL TABLE t1 USING fts2(c);
INSERT INTO t1 (rowid, c) VALUES (1, 'x');
}
set s {SELECT dump_terms(t1, 1) FROM t1 LIMIT 1}
set r {1 {unable to use function dump_terms in the requested context}}
if {[catchsql $s]==$r} {
finish_test
return
}
#*************************************************************************
# Utility function to check for the expected terms in the segment
# level/index. _all version does same but for entire index.
proc check_terms {test level index terms} {
# TODO(shess): Figure out why uplevel in do_test can't catch
# $level and $index directly.
set ::level $level
set ::index $index
do_test $test.terms {
execsql {
SELECT dump_terms(t1, $::level, $::index) FROM t1 LIMIT 1;
}
} [list $terms]
}
proc check_terms_all {test terms} {
do_test $test.terms {
execsql {
SELECT dump_terms(t1) FROM t1 LIMIT 1;
}
} [list $terms]
}
# Utility function to check for the expected doclist for the term in
# segment level/index. _all version does same for entire index.
proc check_doclist {test level index term doclist} {
# TODO(shess): Again, why can't the non-:: versions work?
set ::term $term
set ::level $level
set ::index $index
do_test $test {
execsql {
SELECT dump_doclist(t1, $::term, $::level, $::index) FROM t1 LIMIT 1;
}
} [list $doclist]
}
proc check_doclist_all {test term doclist} {
set ::term $term
do_test $test {
execsql {
SELECT dump_doclist(t1, $::term) FROM t1 LIMIT 1;
}
} [list $doclist]
}
#*************************************************************************
# Test results when all rows are deleted and one is added back.
# Previously older segments would continue to exist, but now the index
# should be dropped when the table is empty. The results should look
# exactly like we never added the earlier rows in the first place.
db eval {
DROP TABLE IF EXISTS t1;
CREATE VIRTUAL TABLE t1 USING fts2(c);
INSERT INTO t1 (rowid, c) VALUES (1, 'This is a test');
INSERT INTO t1 (rowid, c) VALUES (2, 'That was a test');
INSERT INTO t1 (rowid, c) VALUES (3, 'This is a test');
DELETE FROM t1 WHERE 1=1; -- Delete each row rather than dropping table.
INSERT INTO t1 (rowid, c) VALUES (1, 'This is a test');
}
# Should be a single initial segment.
do_test fts2q-1.segments {
execsql {
SELECT level, idx FROM t1_segdir ORDER BY level, idx;
}
} {0 0}
do_test fts2q-1.matches {
execsql {
SELECT OFFSETS(t1) FROM t1
WHERE t1 MATCH 'this OR that OR was OR a OR is OR test' ORDER BY rowid;
}
} {{0 0 0 4 0 4 5 2 0 3 8 1 0 5 10 4}}
check_terms_all fts2q-1.1 {a is test this}
check_doclist_all fts2q-1.1.1 a {[1 0[2]]}
check_doclist_all fts2q-1.1.2 is {[1 0[1]]}
check_doclist_all fts2q-1.1.3 test {[1 0[3]]}
check_doclist_all fts2q-1.1.4 this {[1 0[0]]}
check_terms fts2q-1.2 0 0 {a is test this}
check_doclist fts2q-1.2.1 0 0 a {[1 0[2]]}
check_doclist fts2q-1.2.2 0 0 is {[1 0[1]]}
check_doclist fts2q-1.2.3 0 0 test {[1 0[3]]}
check_doclist fts2q-1.2.4 0 0 this {[1 0[0]]}
#*************************************************************************
# Test results when everything is optimized manually.
# NOTE(shess): This is a copy of fts2c-1.3. I've pulled a copy here
# because fts2q-2 and fts2q-3 should have identical results.
db eval {
DROP TABLE IF EXISTS t1;
CREATE VIRTUAL TABLE t1 USING fts2(c);
INSERT INTO t1 (rowid, c) VALUES (1, 'This is a test');
INSERT INTO t1 (rowid, c) VALUES (2, 'That was a test');
INSERT INTO t1 (rowid, c) VALUES (3, 'This is a test');
DELETE FROM t1 WHERE rowid IN (1,3);
DROP TABLE IF EXISTS t1old;
ALTER TABLE t1 RENAME TO t1old;
CREATE VIRTUAL TABLE t1 USING fts2(c);
INSERT INTO t1 (rowid, c) SELECT rowid, c FROM t1old;
DROP TABLE t1old;
}
# Should be a single optimal segment with the same logical results.
do_test fts2q-2.segments {
execsql {
SELECT level, idx FROM t1_segdir ORDER BY level, idx;
}
} {0 0}
do_test fts2q-2.matches {
execsql {
SELECT OFFSETS(t1) FROM t1
WHERE t1 MATCH 'this OR that OR was OR a OR is OR test' ORDER BY rowid;
}
} {{0 1 0 4 0 2 5 3 0 3 9 1 0 5 11 4}}
check_terms_all fts2q-2.1 {a test that was}
check_doclist_all fts2q-2.1.1 a {[2 0[2]]}
check_doclist_all fts2q-2.1.2 test {[2 0[3]]}
check_doclist_all fts2q-2.1.3 that {[2 0[0]]}
check_doclist_all fts2q-2.1.4 was {[2 0[1]]}
check_terms fts2q-2.2 0 0 {a test that was}
check_doclist fts2q-2.2.1 0 0 a {[2 0[2]]}
check_doclist fts2q-2.2.2 0 0 test {[2 0[3]]}
check_doclist fts2q-2.2.3 0 0 that {[2 0[0]]}
check_doclist fts2q-2.2.4 0 0 was {[2 0[1]]}
#*************************************************************************
# Test results when everything is optimized via optimize().
db eval {
DROP TABLE IF EXISTS t1;
CREATE VIRTUAL TABLE t1 USING fts2(c);
INSERT INTO t1 (rowid, c) VALUES (1, 'This is a test');
INSERT INTO t1 (rowid, c) VALUES (2, 'That was a test');
INSERT INTO t1 (rowid, c) VALUES (3, 'This is a test');
DELETE FROM t1 WHERE rowid IN (1,3);
SELECT OPTIMIZE(t1) FROM t1 LIMIT 1;
}
# Should be a single optimal segment with the same logical results.
do_test fts2q-3.segments {
execsql {
SELECT level, idx FROM t1_segdir ORDER BY level, idx;
}
} {0 0}
do_test fts2q-3.matches {
execsql {
SELECT OFFSETS(t1) FROM t1
WHERE t1 MATCH 'this OR that OR was OR a OR is OR test' ORDER BY rowid;
}
} {{0 1 0 4 0 2 5 3 0 3 9 1 0 5 11 4}}
check_terms_all fts2q-3.1 {a test that was}
check_doclist_all fts2q-3.1.1 a {[2 0[2]]}
check_doclist_all fts2q-3.1.2 test {[2 0[3]]}
check_doclist_all fts2q-3.1.3 that {[2 0[0]]}
check_doclist_all fts2q-3.1.4 was {[2 0[1]]}
check_terms fts2q-3.2 0 0 {a test that was}
check_doclist fts2q-3.2.1 0 0 a {[2 0[2]]}
check_doclist fts2q-3.2.2 0 0 test {[2 0[3]]}
check_doclist fts2q-3.2.3 0 0 that {[2 0[0]]}
check_doclist fts2q-3.2.4 0 0 was {[2 0[1]]}
#*************************************************************************
# Test optimize() against a table involving segment merges.
# NOTE(shess): Since there's no transaction, each of the INSERT/UPDATE
# statements generates a segment.
db eval {
DROP TABLE IF EXISTS t1;
CREATE VIRTUAL TABLE t1 USING fts2(c);
INSERT INTO t1 (rowid, c) VALUES (1, 'This is a test');
INSERT INTO t1 (rowid, c) VALUES (2, 'That was a test');
INSERT INTO t1 (rowid, c) VALUES (3, 'This is a test');
UPDATE t1 SET c = 'This is a test one' WHERE rowid = 1;
UPDATE t1 SET c = 'That was a test one' WHERE rowid = 2;
UPDATE t1 SET c = 'This is a test one' WHERE rowid = 3;
UPDATE t1 SET c = 'This is a test two' WHERE rowid = 1;
UPDATE t1 SET c = 'That was a test two' WHERE rowid = 2;
UPDATE t1 SET c = 'This is a test two' WHERE rowid = 3;
UPDATE t1 SET c = 'This is a test three' WHERE rowid = 1;
UPDATE t1 SET c = 'That was a test three' WHERE rowid = 2;
UPDATE t1 SET c = 'This is a test three' WHERE rowid = 3;
UPDATE t1 SET c = 'This is a test four' WHERE rowid = 1;
UPDATE t1 SET c = 'That was a test four' WHERE rowid = 2;
UPDATE t1 SET c = 'This is a test four' WHERE rowid = 3;
UPDATE t1 SET c = 'This is a test' WHERE rowid = 1;
UPDATE t1 SET c = 'That was a test' WHERE rowid = 2;
UPDATE t1 SET c = 'This is a test' WHERE rowid = 3;
}
# 2 segments in level 0, 1 in level 1 (18 segments created, 16
# merged).
do_test fts2q-4.segments {
execsql {
SELECT level, idx FROM t1_segdir ORDER BY level, idx;
}
} {0 0 0 1 1 0}
do_test fts2q-4.matches {
execsql {
SELECT OFFSETS(t1) FROM t1
WHERE t1 MATCH 'this OR that OR was OR a OR is OR test' ORDER BY rowid;
}
} [list {0 0 0 4 0 4 5 2 0 3 8 1 0 5 10 4} \
{0 1 0 4 0 2 5 3 0 3 9 1 0 5 11 4} \
{0 0 0 4 0 4 5 2 0 3 8 1 0 5 10 4}]
check_terms_all fts2q-4.1 {a four is one test that this three two was}
check_doclist_all fts2q-4.1.1 a {[1 0[2]] [2 0[2]] [3 0[2]]}
check_doclist_all fts2q-4.1.2 four {}
check_doclist_all fts2q-4.1.3 is {[1 0[1]] [3 0[1]]}
check_doclist_all fts2q-4.1.4 one {}
check_doclist_all fts2q-4.1.5 test {[1 0[3]] [2 0[3]] [3 0[3]]}
check_doclist_all fts2q-4.1.6 that {[2 0[0]]}
check_doclist_all fts2q-4.1.7 this {[1 0[0]] [3 0[0]]}
check_doclist_all fts2q-4.1.8 three {}
check_doclist_all fts2q-4.1.9 two {}
check_doclist_all fts2q-4.1.10 was {[2 0[1]]}
check_terms fts2q-4.2 0 0 {a four test that was}
check_doclist fts2q-4.2.1 0 0 a {[2 0[2]]}
check_doclist fts2q-4.2.2 0 0 four {[2]}
check_doclist fts2q-4.2.3 0 0 test {[2 0[3]]}
check_doclist fts2q-4.2.4 0 0 that {[2 0[0]]}
check_doclist fts2q-4.2.5 0 0 was {[2 0[1]]}
check_terms fts2q-4.3 0 1 {a four is test this}
check_doclist fts2q-4.3.1 0 1 a {[3 0[2]]}
check_doclist fts2q-4.3.2 0 1 four {[3]}
check_doclist fts2q-4.3.3 0 1 is {[3 0[1]]}
check_doclist fts2q-4.3.4 0 1 test {[3 0[3]]}
check_doclist fts2q-4.3.5 0 1 this {[3 0[0]]}
check_terms fts2q-4.4 1 0 {a four is one test that this three two was}
check_doclist fts2q-4.4.1 1 0 a {[1 0[2]] [2 0[2]] [3 0[2]]}
check_doclist fts2q-4.4.2 1 0 four {[1] [2 0[4]] [3 0[4]]}
check_doclist fts2q-4.4.3 1 0 is {[1 0[1]] [3 0[1]]}
check_doclist fts2q-4.4.4 1 0 one {[1] [2] [3]}
check_doclist fts2q-4.4.5 1 0 test {[1 0[3]] [2 0[3]] [3 0[3]]}
check_doclist fts2q-4.4.6 1 0 that {[2 0[0]]}
check_doclist fts2q-4.4.7 1 0 this {[1 0[0]] [3 0[0]]}
check_doclist fts2q-4.4.8 1 0 three {[1] [2] [3]}
check_doclist fts2q-4.4.9 1 0 two {[1] [2] [3]}
check_doclist fts2q-4.4.10 1 0 was {[2 0[1]]}
# Optimize should leave the result in the level of the highest-level
# prior segment.
do_test fts2q-4.5 {
execsql {
SELECT OPTIMIZE(t1) FROM t1 LIMIT 1;
SELECT level, idx FROM t1_segdir ORDER BY level, idx;
}
} {{Index optimized} 1 0}
# Identical to fts2q-4.matches.
do_test fts2q-4.5.matches {
execsql {
SELECT OFFSETS(t1) FROM t1
WHERE t1 MATCH 'this OR that OR was OR a OR is OR test' ORDER BY rowid;
}
} [list {0 0 0 4 0 4 5 2 0 3 8 1 0 5 10 4} \
{0 1 0 4 0 2 5 3 0 3 9 1 0 5 11 4} \
{0 0 0 4 0 4 5 2 0 3 8 1 0 5 10 4}]
check_terms_all fts2q-4.5.1 {a is test that this was}
check_doclist_all fts2q-4.5.1.1 a {[1 0[2]] [2 0[2]] [3 0[2]]}
check_doclist_all fts2q-4.5.1.2 is {[1 0[1]] [3 0[1]]}
check_doclist_all fts2q-4.5.1.3 test {[1 0[3]] [2 0[3]] [3 0[3]]}
check_doclist_all fts2q-4.5.1.4 that {[2 0[0]]}
check_doclist_all fts2q-4.5.1.5 this {[1 0[0]] [3 0[0]]}
check_doclist_all fts2q-4.5.1.6 was {[2 0[1]]}
check_terms fts2q-4.5.2 1 0 {a is test that this was}
check_doclist fts2q-4.5.2.1 1 0 a {[1 0[2]] [2 0[2]] [3 0[2]]}
check_doclist fts2q-4.5.2.2 1 0 is {[1 0[1]] [3 0[1]]}
check_doclist fts2q-4.5.2.3 1 0 test {[1 0[3]] [2 0[3]] [3 0[3]]}
check_doclist fts2q-4.5.2.4 1 0 that {[2 0[0]]}
check_doclist fts2q-4.5.2.5 1 0 this {[1 0[0]] [3 0[0]]}
check_doclist fts2q-4.5.2.6 1 0 was {[2 0[1]]}
# Re-optimizing does nothing.
do_test fts2q-5.0 {
execsql {
SELECT OPTIMIZE(t1) FROM t1 LIMIT 1;
SELECT level, idx FROM t1_segdir ORDER BY level, idx;
}
} {{Index already optimal} 1 0}
# Even if we move things around, still does nothing.
do_test fts2q-5.1 {
execsql {
UPDATE t1_segdir SET level = 2 WHERE level = 1 AND idx = 0;
SELECT OPTIMIZE(t1) FROM t1 LIMIT 1;
SELECT level, idx FROM t1_segdir ORDER BY level, idx;
}
} {{Index already optimal} 2 0}
finish_test

View File

@@ -1,121 +0,0 @@
# 2008 July 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.
#
#*************************************************************************
# These tests exercise the various types of fts2 cursors.
#
# $Id: fts2r.test,v 1.1 2008/07/29 20:38:18 shess Exp $
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
# If SQLITE_ENABLE_FTS2 is not defined, omit this file.
ifcapable !fts2 {
finish_test
return
}
#*************************************************************************
# Test table scan (QUERY_GENERIC). This kind of query happens for
# queries with no WHERE clause, or for WHERE clauses which cannot be
# satisfied by an index.
db eval {
DROP TABLE IF EXISTS t1;
CREATE VIRTUAL TABLE t1 USING fts2(c);
INSERT INTO t1 (rowid, c) VALUES (1, 'This is a test');
INSERT INTO t1 (rowid, c) VALUES (2, 'That was a test');
INSERT INTO t1 (rowid, c) VALUES (3, 'This is a test');
}
do_test fts2e-1.1 {
execsql {
SELECT rowid FROM t1 ORDER BY rowid;
}
} {1 2 3}
do_test fts2e-1.2 {
execsql {
SELECT rowid FROM t1 WHERE c LIKE '%test' ORDER BY rowid;
}
} {1 2 3}
do_test fts2e-1.3 {
execsql {
SELECT rowid FROM t1 WHERE c LIKE 'That%' ORDER BY rowid;
}
} {2}
#*************************************************************************
# Test lookup by rowid (QUERY_ROWID). This kind of query happens for
# queries which select by the rowid implicit index.
db eval {
DROP TABLE IF EXISTS t1;
DROP TABLE IF EXISTS t2;
CREATE VIRTUAL TABLE t1 USING fts2(c);
CREATE TABLE t2(id INTEGER PRIMARY KEY AUTOINCREMENT, weight INTEGER UNIQUE);
INSERT INTO t2 VALUES (null, 10);
INSERT INTO t1 (rowid, c) VALUES (last_insert_rowid(), 'This is a test');
INSERT INTO t2 VALUES (null, 5);
INSERT INTO t1 (rowid, c) VALUES (last_insert_rowid(), 'That was a test');
INSERT INTO t2 VALUES (null, 20);
INSERT INTO t1 (rowid, c) VALUES (last_insert_rowid(), 'This is a test');
}
# TODO(shess): This actually is doing QUERY_GENERIC? I'd have
# expected QUERY_ROWID in this case, as for a very large table the
# full scan is less efficient.
do_test fts2e-2.1 {
execsql {
SELECT rowid FROM t1 WHERE rowid in (1, 2, 10);
}
} {1 2}
do_test fts2e-2.2 {
execsql {
SELECT t1.rowid, weight FROM t1, t2 WHERE t2.id = t1.rowid ORDER BY weight;
}
} {2 5 1 10 3 20}
do_test fts2e-2.3 {
execsql {
SELECT t1.rowid, weight FROM t1, t2
WHERE t2.weight>5 AND t2.id = t1.rowid ORDER BY weight;
}
} {1 10 3 20}
#*************************************************************************
# Test lookup by MATCH (QUERY_FULLTEXT). This is the fulltext index.
db eval {
DROP TABLE IF EXISTS t1;
DROP TABLE IF EXISTS t2;
CREATE VIRTUAL TABLE t1 USING fts2(c);
CREATE TABLE t2(id INTEGER PRIMARY KEY AUTOINCREMENT, weight INTEGER UNIQUE);
INSERT INTO t2 VALUES (null, 10);
INSERT INTO t1 (rowid, c) VALUES (last_insert_rowid(), 'This is a test');
INSERT INTO t2 VALUES (null, 5);
INSERT INTO t1 (rowid, c) VALUES (last_insert_rowid(), 'That was a test');
INSERT INTO t2 VALUES (null, 20);
INSERT INTO t1 (rowid, c) VALUES (last_insert_rowid(), 'This is a test');
}
do_test fts2e-3.1 {
execsql {
SELECT rowid FROM t1 WHERE t1 MATCH 'this' ORDER BY rowid;
}
} {1 3}
do_test fts2e-3.2 {
execsql {
SELECT t1.rowid, weight FROM t1, t2
WHERE t1 MATCH 'this' AND t1.rowid = t2.id ORDER BY weight;
}
} {1 10 3 20}
finish_test

View File

@@ -1,174 +0,0 @@
# 2007 June 21
#
# 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 pluggable tokeniser feature of the
# FTS2 module.
#
# $Id: fts2token.test,v 1.3 2007/06/25 12:05:40 danielk1977 Exp $
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
# If SQLITE_ENABLE_FTS2 is defined, omit this file.
ifcapable !fts2 {
finish_test
return
}
proc escape_string {str} {
set out ""
foreach char [split $str ""] {
scan $char %c i
if {$i<=127} {
append out $char
} else {
append out [format {\x%.4x} $i]
}
}
set out
}
#--------------------------------------------------------------------------
# Test cases fts2token-1.* are the warm-body test for the SQL scalar
# function fts2_tokenizer(). The procedure is as follows:
#
# 1: Verify that there is no such fts2 tokenizer as 'blah'.
#
# 2: Query for the built-in tokenizer 'simple'. Insert a copy of the
# retrieved value as tokenizer 'blah'.
#
# 3: Test that the value returned for tokenizer 'blah' is now the
# same as that retrieved for 'simple'.
#
# 4: Test that it is now possible to create an fts2 table using
# tokenizer 'blah' (it was not possible in step 1).
#
# 5: Test that the table created to use tokenizer 'blah' is usable.
#
do_test fts2token-1.1 {
catchsql {
CREATE VIRTUAL TABLE t1 USING fts2(content, tokenize blah);
}
} {1 {unknown tokenizer: blah}}
do_test fts2token-1.2 {
execsql {
SELECT fts2_tokenizer('blah', fts2_tokenizer('simple')) IS NULL;
}
} {0}
do_test fts2token-1.3 {
execsql {
SELECT fts2_tokenizer('blah') == fts2_tokenizer('simple');
}
} {1}
do_test fts2token-1.4 {
catchsql {
CREATE VIRTUAL TABLE t1 USING fts2(content, tokenize blah);
}
} {0 {}}
do_test fts2token-1.5 {
execsql {
INSERT INTO t1(content) VALUES('There was movement at the station');
INSERT INTO t1(content) VALUES('For the word has passed around');
INSERT INTO t1(content) VALUES('That the colt from ol regret had got away');
SELECT content FROM t1 WHERE content MATCH 'movement'
}
} {{There was movement at the station}}
#--------------------------------------------------------------------------
# Test cases fts2token-2.* test error cases in the scalar function based
# API for getting and setting tokenizers.
#
do_test fts2token-2.1 {
catchsql {
SELECT fts2_tokenizer('nosuchtokenizer');
}
} {1 {unknown tokenizer: nosuchtokenizer}}
#--------------------------------------------------------------------------
# Test cases fts2token-3.* test the three built-in tokenizers with a
# simple input string via the built-in test function. This is as much
# to test the test function as the tokenizer implementations.
#
do_test fts2token-3.1 {
execsql {
SELECT fts2_tokenizer_test('simple', 'I don''t see how');
}
} {{0 i I 1 don don 2 t t 3 see see 4 how how}}
do_test fts2token-3.2 {
execsql {
SELECT fts2_tokenizer_test('porter', 'I don''t see how');
}
} {{0 i I 1 don don 2 t t 3 see see 4 how how}}
ifcapable icu {
do_test fts2token-3.3 {
execsql {
SELECT fts2_tokenizer_test('icu', 'I don''t see how');
}
} {{0 i I 1 don't don't 2 see see 3 how how}}
}
#--------------------------------------------------------------------------
# Test cases fts2token-4.* test the ICU tokenizer. In practice, this
# tokenizer only has two modes - "thai" and "everybody else". Some other
# Asian languages (Lao, Khmer etc.) require the same special treatment as
# Thai, but ICU doesn't support them yet.
#
ifcapable icu {
proc do_icu_test {name locale input output} {
set ::out [db eval { SELECT fts2_tokenizer_test('icu', $locale, $input) }]
do_test $name {
lindex $::out 0
} $output
}
do_icu_test fts2token-4.1 en_US {} {}
do_icu_test fts2token-4.2 en_US {Test cases fts2} [list \
0 test Test 1 cases cases 2 fts2 fts2
]
# The following test shows that ICU is smart enough to recognise
# Thai chararacters, even when the locale is set to English/United
# States.
#
set input "\u0e2d\u0e30\u0e44\u0e23\u0e19\u0e30\u0e04\u0e23\u0e31\u0e1a"
set output "0 \u0e2d\u0e30\u0e44\u0e23 \u0e2d\u0e30\u0e44\u0e23 "
append output "1 \u0e19\u0e30 \u0e19\u0e30 "
append output "2 \u0e04\u0e23\u0e31\u0e1a \u0e04\u0e23\u0e31\u0e1a"
do_icu_test fts2token-4.3 th_TH $input $output
do_icu_test fts2token-4.4 en_US $input $output
# ICU handles an unknown locale by falling back to the default.
# So this is not an error.
do_icu_test fts2token-4.5 MiddleOfTheOcean $input $output
set longtoken "AReallyReallyLongTokenOneThatWillSurelyRequire"
append longtoken "AReallocInTheIcuTokenizerCode"
set input "short tokens then "
append input $longtoken
set output "0 short short "
append output "1 tokens tokens "
append output "2 then then "
append output "3 [string tolower $longtoken] $longtoken"
do_icu_test fts2token-4.6 MiddleOfTheOcean $input $output
do_icu_test fts2token-4.7 th_TH $input $output
do_icu_test fts2token-4.8 en_US $input $output
}
do_test fts2token-internal {
execsql { SELECT fts2_tokenizer_internal_test() }
} {ok}
finish_test

View File

@@ -1130,6 +1130,44 @@ static int runDbSql(sqlite3 *db, const char *zSql, unsigned int *pBtsFlags){
return sqlite3_finalize(pStmt);
}
/* Mappings into dbconfig settings for bits taken from bytes 72..75 of
** the input database.
**
** This should be the same as in dbsqlfuzz.c. Make sure those codes stay
** in sync.
*/
static const struct {
unsigned int mask;
int iSetting;
char *zName;
} aDbConfigSettings[] = {
{ 0x0001, SQLITE_DBCONFIG_ENABLE_FKEY, "enable_fkey" },
{ 0x0002, SQLITE_DBCONFIG_ENABLE_TRIGGER, "enable_trigger" },
{ 0x0004, SQLITE_DBCONFIG_ENABLE_VIEW, "enable_view" },
{ 0x0008, SQLITE_DBCONFIG_ENABLE_QPSG, "enable_qpsg" },
{ 0x0010, SQLITE_DBCONFIG_TRIGGER_EQP, "trigger_eqp" },
{ 0x0020, SQLITE_DBCONFIG_DEFENSIVE, "defensive" },
{ 0x0040, SQLITE_DBCONFIG_WRITABLE_SCHEMA, "writable_schema" },
{ 0x0080, SQLITE_DBCONFIG_LEGACY_ALTER_TABLE, "legacy_alter_table" },
{ 0x0100, SQLITE_DBCONFIG_STMT_SCANSTATUS, "stmt_scanstatus" },
{ 0x0200, SQLITE_DBCONFIG_REVERSE_SCANORDER, "reverse_scanorder" },
#ifdef SQLITE_DBCONFIG_STRICT_AGGREGATE
{ 0x0400, SQLITE_DBCONFIG_STRICT_AGGREGATE, "strict_aggregate" },
#endif
{ 0x0800, SQLITE_DBCONFIG_DQS_DML, "dqs_dml" },
{ 0x1000, SQLITE_DBCONFIG_DQS_DDL, "dqs_ddl" },
{ 0x2000, SQLITE_DBCONFIG_TRUSTED_SCHEMA, "trusted_schema" },
};
/* Toggle a dbconfig setting
*/
static void toggleDbConfig(sqlite3 *db, int iSetting){
int v = 0;
sqlite3_db_config(db, iSetting, -1, &v);
v = !v;
sqlite3_db_config(db, iSetting, v, 0);
}
/* Invoke this routine to run a single test case */
int runCombinedDbSqlInput(
const uint8_t *aData, /* Combined DB+SQL content */
@@ -1148,6 +1186,9 @@ int runCombinedDbSqlInput(
int nSql; /* Bytes of SQL text */
FuzzCtx cx; /* Fuzzing context */
unsigned int btsFlags = 0; /* Parsing flags */
unsigned int dbFlags = 0; /* Flag values from db offset 72..75 */
unsigned int dbOpt = 0; /* Flag values from db offset 76..79 */
if( nByte<10 ) return 0;
if( sqlite3_initialize() ) return 0;
@@ -1163,6 +1204,12 @@ int runCombinedDbSqlInput(
memset(&cx, 0, sizeof(cx));
iSql = decodeDatabase((unsigned char*)aData, (int)nByte, &aDb, &nDb);
if( iSql<0 ) return 0;
if( nDb>=75 ){
dbFlags = (aDb[72]<<24) + (aDb[73]<<16) + (aDb[74]<<8) + aDb[75];
}
if( nDb>=79 ){
dbOpt = (aDb[76]<<24) + (aDb[77]<<16) + (aDb[78]<<8) + aDb[79];
}
nSql = (int)(nByte - iSql);
if( bScript ){
char zName[100];
@@ -1183,7 +1230,12 @@ int runCombinedDbSqlInput(
sqlite3_free(aDb);
return 1;
}
sqlite3_db_config(cx.db, SQLITE_DBCONFIG_STMT_SCANSTATUS, 1, 0);
sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS, cx.db, dbOpt);
for(i=0; i<sizeof(aDbConfigSettings)/sizeof(aDbConfigSettings[0]); i++){
if( dbFlags & aDbConfigSettings[i].mask ){
toggleDbConfig(cx.db, aDbConfigSettings[i].iSetting);
}
}
if( bVdbeDebug ){
sqlite3_exec(cx.db, "PRAGMA vdbe_debug=ON", 0, 0, 0);
}

View File

@@ -302,14 +302,34 @@ do_execsql_test 7.3 {
ANALYZE sqlite_schema;
}
# If both sides of the OR reference the right-hand side of the LEFT JOIN
# then simplify the LEFT JOIN.
#
do_eqp_test 7.4 {
SELECT * FROM t3 LEFT JOIN t4 ON (t4.x = t3.x) WHERE (t4.y = ? OR t4.z = ?);
} {
QUERY PLAN
|--SCAN t4
`--SEARCH t3 USING COVERING INDEX t3x (x=?)
}
# If only one side of the OR references the right-hand side of the LEFT JOIN
# then do not do the simplification
#
do_eqp_test 7.4b {
SELECT * FROM t3 LEFT JOIN t4 ON (t4.x = t3.x) WHERE (t4.y = ? OR t3.x = ?);
} {
QUERY PLAN
|--SCAN t3
`--SEARCH t4 USING INDEX t4xz (x=?) LEFT-JOIN
}
do_eqp_test 7.4b {
do_eqp_test 7.4c {
SELECT * FROM t3 LEFT JOIN t4 ON (t4.x = t3.x) WHERE (t3.x = ? OR t4.z = ?);
} {
QUERY PLAN
|--SCAN t3
`--SEARCH t4 USING INDEX t4xz (x=?) LEFT-JOIN
}
do_eqp_test 7.4d {
SELECT * FROM t3 CROSS JOIN t4 ON (t4.x = t3.x) WHERE (+t4.y = ? OR t4.z = ?);
} {
QUERY PLAN

View File

@@ -210,5 +210,68 @@ foreach {id schema} {
18 28 38 48 - - -
19 - 29 39 - 49 -
}
# Verified by PG-14
do_execsql_test joinA-$id.201 {
SELECT a,b,c,d,t2.e,f,t3.e,t1.a
FROM t1
FULL JOIN t2 USING(c,d)
FULL JOIN t3 USING(a,b,f)
FULL JOIN t4 USING(a,c,d,f)
WHERE t1.a!=0
ORDER BY 1 nulls first, 3 nulls first;
} {
11 21 31 41 - - - 11
12 22 32 42 - - - 12
15 25 35 45 - - - 15
18 28 38 48 - - - 18
}
# Verified by PG-14
do_execsql_test joinA-$id.202 {
SELECT a,b,c,d,t2.e,f,t3.e,t3.a
FROM t1
FULL JOIN t2 USING(c,d)
FULL JOIN t3 USING(a,b,f)
FULL JOIN t4 USING(a,c,d,f)
WHERE t3.a!=0
ORDER BY 1 nulls first, 3 nulls first;
} {
14 24 - - - 44 34 14
15 25 - - - 45 35 15
16 26 - - - 46 36 16
}
# Verified by PG-14
do_execsql_test joinA-$id.203 {
SELECT a,b,c,d,t2.e,f,t3.e,t4.a
FROM t1
FULL JOIN t2 USING(c,d)
FULL JOIN t3 USING(a,b,f)
FULL JOIN t4 USING(a,c,d,f)
WHERE t4.a!=0
ORDER BY 1 nulls first, 3 nulls first;
} {
11 - 21 31 - 41 - 11
13 - 23 33 - 43 - 13
16 - 26 36 - 46 - 16
19 - 29 39 - 49 - 19
}
# Verified by PG-14
do_execsql_test joinA-$id.204 {
SELECT a,b,c,d,t2.e,f,t3.e
FROM t1
FULL JOIN t2 USING(c,d)
FULL JOIN t3 USING(a,b,f)
FULL JOIN t4 USING(a,c,d,f)
WHERE t2.e!=0
ORDER BY 1 nulls first, 3 nulls first;
} {
- - 12 22 32 42 -
- - 13 23 33 43 -
- - 15 25 35 45 -
- - 17 27 37 47 -
}
}
finish_test

View File

@@ -120,4 +120,16 @@ do_execsql_test 5.5 {
SELECT * FROM t0 RIGHT JOIN t1 INNER JOIN t2 ON (0)
} {}
reset_db
db null NULL
do_execsql_test 6.0 {
CREATE TABLE t1(a INT);
CREATE TABLE t2(b INT);
INSERT INTO t1 VALUES(3);
SELECT CASE WHEN t2.b THEN 0 ELSE 1 END FROM t1 LEFT JOIN t2 ON true;
} {1}
do_execsql_test 6.1 {
SELECT * FROM t1 LEFT JOIN t2 ON true WHERE CASE WHEN t2.b THEN 0 ELSE 1 END;
} {3 NULL}
finish_test

View File

@@ -161,7 +161,7 @@ static const char zHelp[] =
#endif
/*
** Show thqe help text and quit.
** Show the help text and quit.
*/
static void showHelp(void){
fprintf(stdout, "%s", zHelp);

View File

@@ -63,4 +63,26 @@ CREATE TABLE t3(a,b,c);
INSERT INTO t3(rowid,a,b,c) VALUES(1,111,222,333);
DROP TABLE t4;}
db close
forcedelete test.db test2.db
sqlite3 db test.db
do_test sqldiff-2.0 {
db eval {
CREATE TABLE t1(a INTEGER PRIMARY KEY);
}
db close
sqlite3 db test2.db
db eval {
CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
}
db close
set line "exec $PROG test.db test2.db"
unset -nocomplain ::MSG
catch {eval $line} ::MSG
} {0}
do_test sqldiff-2.1 {
set ::MSG
} {ALTER TABLE t1 ADD COLUMN b;}
finish_test

222
test/timediff1.test Normal file
View File

@@ -0,0 +1,222 @@
# 2023-05-30
#
# 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 file is testing date and time functions.
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
# Skip this whole file if date and time functions are omitted
# at compile-time
#
ifcapable {!datetime} {
finish_test
return
}
proc datetest {tnum expr result} {
do_test timediff-$tnum [subst {
execsql "SELECT coalesce($expr,'NULL')"
}] [list $result]
}
set tcl_precision 15
# February overflow on a leap year
datetest 1.1 {datetime('2000-01-31','+1 month')} {2000-03-02 00:00:00}
datetest 1.2 {datetime('2004-01-29','+1 month')} {2004-02-29 00:00:00}
datetest 1.3 {datetime('2000-03-01','-1 day')} {2000-02-29 00:00:00}
datetest 1.4 {datetime('2000-03-31','-1 month')} {2000-03-02 00:00:00}
datetest 1.5 {datetime('2000-03-30','-1 month')} {2000-03-01 00:00:00}
datetest 1.6 {datetime('2000-03-29','-1 month')} {2000-02-29 00:00:00}
datetest 1.7 {datetime('2000-03-28','-1 month')} {2000-02-28 00:00:00}
datetest 1.8 {datetime('2000-02-29','+1 year')} {2001-03-01 00:00:00}
datetest 1.9 {datetime('2000-02-29','+4 years')} {2004-02-29 00:00:00}
datetest 1.10 {datetime('1998-11-10','+0001-03-19 12:34:56')} \
{2000-02-29 12:34:56}
datetest 1.11 {datetime('2000-01-31','+0004-01-00 12:34:56')} \
{2004-03-02 12:34:56}
datetest 1.12 {datetime('2000-01-29','+0008-01-00 12:34:56')} \
{2008-02-29 12:34:56}
datetest 1.13 {datetime('2001-03-31','-0001-01-00 06:10')} \
{2000-03-01 17:50:00}
# February overflow on a non-leap year
datetest 2.1 {datetime('2001-01-31','+1 month')} {2001-03-03 00:00:00}
datetest 2.2 {datetime('2005-01-29','+1 month')} {2005-03-01 00:00:00}
datetest 2.3 {datetime('2001-03-01','-1 day')} {2001-02-28 00:00:00}
datetest 2.4 {datetime('2001-03-31','-1 month')} {2001-03-03 00:00:00}
datetest 2.5 {datetime('2001-03-30','-1 month')} {2001-03-02 00:00:00}
datetest 2.6 {datetime('2001-03-29','-1 month')} {2001-03-01 00:00:00}
datetest 2.7 {datetime('2001-03-28','-1 month')} {2001-02-28 00:00:00}
datetest 2.10 {datetime('1999-11-10','+0001-03-19 12:34:56')} \
{2001-03-01 12:34:56}
datetest 2.11 {datetime('2000-01-31','+0005-01-00 12:34:56')} \
{2005-03-03 12:34:56}
datetest 2.12 {datetime('2000-01-29','+0009-01-00 12:34:56')} \
{2009-03-01 12:34:56}
datetest 2.13 {datetime('2002-03-31','-0001-01-00 06:10')} \
{2001-03-02 17:50:00}
# timediff
datetest 3.1 {timediff('2000-03-02','2000-01-31')} {+0000-01-00 00:00:00.000}
datetest 3.2 {timediff('2000-01-31','2000-03-02')} {-0000-01-02 00:00:00.000}
datetest 3.3 {timediff('2000-03-02','1999-01-31')} {+0001-01-00 00:00:00.000}
datetest 3.4 {timediff('1999-01-31','2000-03-02')} {-0001-01-02 00:00:00.000}
unset -nocomplain p1
unset -nocomplain p2
set p1 {
0 {-4713-11-24 12:00:00}
1 {-2000-04-30 05:19:26}
2 {0000-01-01 12:34:56}
3 {1776-07-04 13:00:00}
4 {1969-07-20 20:17}
5 {2440587.5}
6 {2000-05-29 14:26}
7 {2023-05-29 18:11}
8 {2050-05-29 14:26}
9 {4796-02-29 11:23:55.46}
}
set p2 {
A {1066-10-14}
B {1900-02-28 11:00}
C {1900-03-01 12:00}
D {1904-02-29 11:25}
E {2000-02-29 13:00}
E {2000-03-01 14:00}
F {2001-03-31 15:15}
G {2002-04-01 16:59}
H {2003-04-30 17:00}
I {2004-05-01 23:59:59}
J {2005-06-01}
K {2006-06-30 01:23:45}
L {2007-12-31 02:00}
M {2008-01-01 01:59}
N {3152-07-04 12:00}
P {9999-12-31 23:59:59}
}
foreach {x1 d1} $p1 {
foreach {x2 d2} $p2 {
set r1 [db one {SELECT datetime($d1)}]
do_execsql_test timediff-4-$x1$x2 {
SELECT datetime($d2, timediff($d1,$d2));
} [list $r1]
set r2 [db one {SELECT datetime($d2)}]
do_execsql_test timediff-4-$x2$x1 {
SELECT datetime($d1, timediff($d2,$d1));
} [list $r2]
}
}
# Partial time-diffs as modifiers
#
datetest 5-1 {datetime('2000-01-01','+0001-02-03')} {2001-03-04 00:00:00}
datetest 5-2 {datetime('2000-01-01','+0001-02-03x')} {NULL}
datetest 5-3 {datetime('2000-01-01','+0001-11-03')} {2001-12-04 00:00:00}
datetest 5-4 {datetime('2000-01-01','+0001-12-03')} {NULL}
datetest 5-5 {datetime('2000-01-01','+0001-02-30')} {2001-03-31 00:00:00}
datetest 5-6 {datetime('2000-01-01','+0001-02-31')} {NULL}
datetest 5-7 {datetime('2000-01-01','+0001-02-03 0')} {NULL}
datetest 5-8 {datetime('2000-01-01','+0001-02-03 01')} {NULL}
datetest 5-9 {datetime('2000-01-01','+0001-02-03 01:')} {NULL}
datetest 5-10 {datetime('2000-01-01','+0001-02-03 01:0')} {NULL}
datetest 5-11 {datetime('2000-01-01','+0001-02-03 01:02')} {2001-03-04 01:02:00}
datetest 5-12 {datetime('2000-01-01','+0001-02-03 01:02:')} {NULL}
datetest 5-13 {datetime('2000-01-01','+0001-02-03 01:02:0')} {NULL}
datetest 5-14 {datetime('2000-01-01','+0001-02-03 01:02:03')} \
{2001-03-04 01:02:03}
datetest 5-15 {datetime('2000-01-01','+0001-02-03 01:02:03.')} NULL
datetest 5-16 {datetime('2000-01-01','+0001-02-03 01:02:03.5')} \
{2001-03-04 01:02:03}
datetest 5-17 {datetime('2000-01-01','+0001-02-03 01:02:03.50')} \
{2001-03-04 01:02:03}
datetest 5-18 {datetime('2000-01-01','+0001-02-03 01:02:03.500')} \
{2001-03-04 01:02:03}
datetest 5-19 {datetime('2000-01-01','+0001-02-03 01:02:03.500x')} {NULL}
datetest 5-20 {datetime('2000-01-01','+0001-02-03 01:02:03.500 x')} {NULL}
unset -nocomplain p1
unset -nocomplain p2
set p1 {
a {2000-01-01 00:00:00}
b {2000-01-31 23:59:59}
c {2000-02-01 00:00:00}
d {2000-02-29 23:59:59}
e {2000-03-01 00:00:00}
f {2000-03-31 23:59:59}
g {2000-04-01 00:00:00}
h {2000-04-30 23:59:59}
i {2000-05-01 00:00:00}
j {2000-05-31 23:59:59}
k {2000-06-01 00:00:00}
l {2000-06-30 23:59:59}
m {2000-07-01 00:00:00}
n {2000-07-31 23:59:59}
o {2000-08-01 00:00:00}
p {2000-08-31 23:59:59}
q {2000-09-01 00:00:00}
r {2000-09-30 23:59:59}
s {2000-10-01 00:00:00}
t {2000-10-31 23:59:59}
u {2000-11-01 00:00:00}
v {2000-11-30 23:59:59}
w {2000-12-01 00:00:00}
x {2000-12-31 23:59:59}
}
set p2 {
A {2001-01-01 00:00:00}
B {2001-01-31 23:59:59}
C {2001-02-01 00:00:00}
D {2001-02-28 23:59:59}
E {2001-03-01 00:00:00}
F {2001-03-31 23:59:59}
G {2001-04-01 00:00:00}
H {2001-04-30 23:59:59}
I {2001-05-01 00:00:00}
J {2001-05-31 23:59:59}
K {2001-06-01 00:00:00}
L {2001-06-30 23:59:59}
M {2001-07-01 00:00:00}
N {2001-07-31 23:59:59}
O {2001-08-01 00:00:00}
P {2001-08-31 23:59:59}
Q {2001-09-01 00:00:00}
R {2001-09-30 23:59:59}
S {2001-10-01 00:00:00}
T {2001-10-31 23:59:59}
U {2001-11-01 00:00:00}
V {2001-11-30 23:59:59}
W {2001-12-01 00:00:00}
X {2001-12-31 23:59:59}
}
foreach {x1 d1} $p1 {
foreach {x2 d2} $p2 {
set r1 [db one {SELECT datetime($d1)}]
do_execsql_test timediff-6-$x1$x2 {
SELECT datetime($d2, timediff($d1,$d2));
} [list $r1]
set r2 [db one {SELECT datetime($d2)}]
do_execsql_test timediff-6-$x2$x1 {
SELECT datetime($d1, timediff($d2,$d1));
} [list $r2]
}
}
finish_test

View File

@@ -127,4 +127,30 @@ do_execsql_test 400 {
1000 - - -
}
# Forum post https://sqlite.org/forum/forumpost/36ff78b2a3
#
ifcapable update_delete_limit {
reset_db
do_execsql_test 500 {
CREATE TABLE t1(abc INT, def INT);
INSERT INTO t1 VALUES(0,0);
INSERT INTO t1 VALUES(0,0);
INSERT INTO t1 VALUES(0,0);
CREATE TABLE dual(dummy TEXT);
INSERT INTO dual(dummy) VALUES('X');
} {}
do_execsql_test 510 {
UPDATE t1
SET (abc, def)=(SELECT x, 123)
FROM dual LEFT JOIN (SELECT 789 AS 'x' FROM dual) AS d2
LIMIT 2
}
do_execsql_test 520 {
SELECT * FROM t1
} {789 123 789 123 0 0}
}
finish_test

View File

@@ -299,5 +299,35 @@ do_test 5.5 {
set ::log
} {ax a bx b cx c dx d ex a}
#-----------------------------------------------------------------------
reset_db
do_execsql_test 6.0 {
CREATE TABLE t2(x);
INSERT INTO t2(x) VALUES(1),(2),(3),(5),(8),(13);
} {}
do_execsql_test 6.1 {
WITH t2 AS MATERIALIZED (VALUES(5))
DELETE FROM t2 ORDER BY rank()OVER() LIMIT 2;
}
do_execsql_test 6.2 {
SELECT * FROM t2;
} {3 5 8 13}
#-------------------------------------------------------------------------
do_execsql_test 7.0 {
CREATE TABLE t1(a INT); INSERT INTO t1(a) VALUES(0);
} {}
do_execsql_test 7.1 {
WITH t1(b) AS (SELECT * FROM (SELECT * FROM (VALUES(2))))
UPDATE t1 SET a=3 LIMIT 1;
}
do_execsql_test 7.2 {
SELECT * FROM t1;
} {3}
finish_test

View File

@@ -2363,4 +2363,17 @@ do_execsql_test 76.5 {
SELECT (SELECT max(y)+sum(0) OVER ()) FROM t3 LEFT JOIN t4 ON x=y GROUP BY x;
} {100 {} 400}
# 2023-05-23 https://sqlite.org/forum/forumpost/fbfe330a20
#
reset_db
do_execsql_test 77.1 {
CREATE TABLE t1(x INT);
CREATE INDEX t1x ON t1(likely(x));
INSERT INTO t1 VALUES(1),(2),(4),(8);
}
do_execsql_test 77.2 {
SELECT max(~likely(x)) FILTER (WHERE true) FROM t1 INDEXED BY t1x GROUP BY x;
} {-2 -3 -5 -9}
finish_test