1# 2008 June 26 2# 3# The author disclaims copyright to this source code. In place of 4# a legal notice, here is a blessing: 5# 6# May you do good and not evil. 7# May you find forgiveness for yourself and forgive others. 8# May you share freely, never taking more than you give. 9# 10#************************************************************************* 11# This file exercises some new testing functions in the FTS3 module, 12# and then uses them to do some basic tests that FTS3 is internally 13# working as expected. 14# 15 16set testdir [file dirname $argv0] 17source $testdir/tester.tcl 18source $testdir/fts3_common.tcl 19 20# If SQLITE_ENABLE_FTS3 is not defined, omit this file. 21ifcapable !fts3 { 22 finish_test 23 return 24} 25 26#************************************************************************* 27# Utility function to check for the expected terms in the segment 28# level/index. _all version does same but for entire index. 29proc check_terms {test level index terms} { 30 set where "level = $level AND idx = $index" 31 do_test $test.terms [list fts3_terms t1 $where] $terms 32} 33proc check_terms_all {test terms} { 34 do_test $test.terms [list fts3_terms t1 1] $terms 35} 36 37# Utility function to check for the expected doclist for the term in 38# segment level/index. _all version does same for entire index. 39proc check_doclist {test level index term doclist} { 40 set where "level = $level AND idx = $index" 41 do_test $test [list fts3_doclist t1 $term $where] $doclist 42} 43proc check_doclist_all {test term doclist} { 44 do_test $test [list fts3_doclist t1 $term 1] $doclist 45} 46 47#************************************************************************* 48# Test the segments resulting from straight-forward inserts. 49db eval { 50 DROP TABLE IF EXISTS t1; 51 CREATE VIRTUAL TABLE t1 USING fts3(c); 52 INSERT INTO t1 (docid, c) VALUES (1, 'This is a test'); 53 INSERT INTO t1 (docid, c) VALUES (2, 'That was a test'); 54 INSERT INTO t1 (docid, c) VALUES (3, 'This is a test'); 55} 56 57# Check for expected segments and expected matches. 58do_test fts3c-1.0.segments { 59 execsql { 60 SELECT level, idx FROM t1_segdir ORDER BY level, idx; 61 } 62} {0 0 0 1 0 2} 63do_test fts3c-1.0.matches { 64 execsql { 65 SELECT OFFSETS(t1) FROM t1 66 WHERE t1 MATCH 'this OR that OR was OR a OR is OR test' ORDER BY docid; 67 } 68} [list {0 0 0 4 0 4 5 2 0 3 8 1 0 5 10 4} \ 69 {0 1 0 4 0 2 5 3 0 3 9 1 0 5 11 4} \ 70 {0 0 0 4 0 4 5 2 0 3 8 1 0 5 10 4}] 71 72# Check the specifics of the segments constructed. 73# Logical view of entire index. 74check_terms_all fts3c-1.0.1 {a is test that this was} 75check_doclist_all fts3c-1.0.1.1 a {[1 0[2]] [2 0[2]] [3 0[2]]} 76check_doclist_all fts3c-1.0.1.2 is {[1 0[1]] [3 0[1]]} 77check_doclist_all fts3c-1.0.1.3 test {[1 0[3]] [2 0[3]] [3 0[3]]} 78check_doclist_all fts3c-1.0.1.4 that {[2 0[0]]} 79check_doclist_all fts3c-1.0.1.5 this {[1 0[0]] [3 0[0]]} 80check_doclist_all fts3c-1.0.1.6 was {[2 0[1]]} 81 82# Segment 0,0 83check_terms fts3c-1.0.2 0 0 {a is test this} 84check_doclist fts3c-1.0.2.1 0 0 a {[1 0[2]]} 85check_doclist fts3c-1.0.2.2 0 0 is {[1 0[1]]} 86check_doclist fts3c-1.0.2.3 0 0 test {[1 0[3]]} 87check_doclist fts3c-1.0.2.4 0 0 this {[1 0[0]]} 88 89# Segment 0,1 90check_terms fts3c-1.0.3 0 1 {a test that was} 91check_doclist fts3c-1.0.3.1 0 1 a {[2 0[2]]} 92check_doclist fts3c-1.0.3.2 0 1 test {[2 0[3]]} 93check_doclist fts3c-1.0.3.3 0 1 that {[2 0[0]]} 94check_doclist fts3c-1.0.3.4 0 1 was {[2 0[1]]} 95 96# Segment 0,2 97check_terms fts3c-1.0.4 0 2 {a is test this} 98check_doclist fts3c-1.0.4.1 0 2 a {[3 0[2]]} 99check_doclist fts3c-1.0.4.2 0 2 is {[3 0[1]]} 100check_doclist fts3c-1.0.4.3 0 2 test {[3 0[3]]} 101check_doclist fts3c-1.0.4.4 0 2 this {[3 0[0]]} 102 103#************************************************************************* 104# Test the segments resulting from inserts followed by a delete. 105db eval { 106 DROP TABLE IF EXISTS t1; 107 CREATE VIRTUAL TABLE t1 USING fts3(c); 108 INSERT INTO t1 (docid, c) VALUES (1, 'This is a test'); 109 INSERT INTO t1 (docid, c) VALUES (2, 'That was a test'); 110 INSERT INTO t1 (docid, c) VALUES (3, 'This is a test'); 111 DELETE FROM t1 WHERE docid = 1; 112} 113 114do_test fts3c-1.1.segments { 115 execsql { 116 SELECT level, idx FROM t1_segdir ORDER BY level, idx; 117 } 118} {0 0 0 1 0 2 0 3} 119do_test fts3c-1.1.matches { 120 execsql { 121 SELECT OFFSETS(t1) FROM t1 122 WHERE t1 MATCH 'this OR that OR was OR a OR is OR test' ORDER BY docid; 123 } 124} {{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}} 125 126check_terms_all fts3c-1.1.1 {a is test that this was} 127check_doclist_all fts3c-1.1.1.1 a {[2 0[2]] [3 0[2]]} 128check_doclist_all fts3c-1.1.1.2 is {[3 0[1]]} 129check_doclist_all fts3c-1.1.1.3 test {[2 0[3]] [3 0[3]]} 130check_doclist_all fts3c-1.1.1.4 that {[2 0[0]]} 131check_doclist_all fts3c-1.1.1.5 this {[3 0[0]]} 132check_doclist_all fts3c-1.1.1.6 was {[2 0[1]]} 133 134check_terms fts3c-1.1.2 0 0 {a is test this} 135check_doclist fts3c-1.1.2.1 0 0 a {[1 0[2]]} 136check_doclist fts3c-1.1.2.2 0 0 is {[1 0[1]]} 137check_doclist fts3c-1.1.2.3 0 0 test {[1 0[3]]} 138check_doclist fts3c-1.1.2.4 0 0 this {[1 0[0]]} 139 140check_terms fts3c-1.1.3 0 1 {a test that was} 141check_doclist fts3c-1.1.3.1 0 1 a {[2 0[2]]} 142check_doclist fts3c-1.1.3.2 0 1 test {[2 0[3]]} 143check_doclist fts3c-1.1.3.3 0 1 that {[2 0[0]]} 144check_doclist fts3c-1.1.3.4 0 1 was {[2 0[1]]} 145 146check_terms fts3c-1.1.4 0 2 {a is test this} 147check_doclist fts3c-1.1.4.1 0 2 a {[3 0[2]]} 148check_doclist fts3c-1.1.4.2 0 2 is {[3 0[1]]} 149check_doclist fts3c-1.1.4.3 0 2 test {[3 0[3]]} 150check_doclist fts3c-1.1.4.4 0 2 this {[3 0[0]]} 151 152check_terms fts3c-1.1.5 0 3 {a is test this} 153check_doclist fts3c-1.1.5.1 0 3 a {[1]} 154check_doclist fts3c-1.1.5.2 0 3 is {[1]} 155check_doclist fts3c-1.1.5.3 0 3 test {[1]} 156check_doclist fts3c-1.1.5.4 0 3 this {[1]} 157 158#************************************************************************* 159# Test results when all references to certain tokens are deleted. 160db eval { 161 DROP TABLE IF EXISTS t1; 162 CREATE VIRTUAL TABLE t1 USING fts3(c); 163 INSERT INTO t1 (docid, c) VALUES (1, 'This is a test'); 164 INSERT INTO t1 (docid, c) VALUES (2, 'That was a test'); 165 INSERT INTO t1 (docid, c) VALUES (3, 'This is a test'); 166 DELETE FROM t1 WHERE docid IN (1,3); 167} 168 169# Still 4 segments because 0,3 will contain deletes for docid 1 and 3. 170do_test fts3c-1.2.segments { 171 execsql { 172 SELECT level, idx FROM t1_segdir ORDER BY level, idx; 173 } 174} {0 0 0 1 0 2 0 3} 175do_test fts3c-1.2.matches { 176 execsql { 177 SELECT OFFSETS(t1) FROM t1 178 WHERE t1 MATCH 'this OR that OR was OR a OR is OR test' ORDER BY docid; 179 } 180} {{0 1 0 4 0 2 5 3 0 3 9 1 0 5 11 4}} 181 182check_terms_all fts3c-1.2.1 {a is test that this was} 183check_doclist_all fts3c-1.2.1.1 a {[2 0[2]]} 184check_doclist_all fts3c-1.2.1.2 is {} 185check_doclist_all fts3c-1.2.1.3 test {[2 0[3]]} 186check_doclist_all fts3c-1.2.1.4 that {[2 0[0]]} 187check_doclist_all fts3c-1.2.1.5 this {} 188check_doclist_all fts3c-1.2.1.6 was {[2 0[1]]} 189 190check_terms fts3c-1.2.2 0 0 {a is test this} 191check_doclist fts3c-1.2.2.1 0 0 a {[1 0[2]]} 192check_doclist fts3c-1.2.2.2 0 0 is {[1 0[1]]} 193check_doclist fts3c-1.2.2.3 0 0 test {[1 0[3]]} 194check_doclist fts3c-1.2.2.4 0 0 this {[1 0[0]]} 195 196check_terms fts3c-1.2.3 0 1 {a test that was} 197check_doclist fts3c-1.2.3.1 0 1 a {[2 0[2]]} 198check_doclist fts3c-1.2.3.2 0 1 test {[2 0[3]]} 199check_doclist fts3c-1.2.3.3 0 1 that {[2 0[0]]} 200check_doclist fts3c-1.2.3.4 0 1 was {[2 0[1]]} 201 202check_terms fts3c-1.2.4 0 2 {a is test this} 203check_doclist fts3c-1.2.4.1 0 2 a {[3 0[2]]} 204check_doclist fts3c-1.2.4.2 0 2 is {[3 0[1]]} 205check_doclist fts3c-1.2.4.3 0 2 test {[3 0[3]]} 206check_doclist fts3c-1.2.4.4 0 2 this {[3 0[0]]} 207 208check_terms fts3c-1.2.5 0 3 {a is test this} 209check_doclist fts3c-1.2.5.1 0 3 a {[1] [3]} 210check_doclist fts3c-1.2.5.2 0 3 is {[1] [3]} 211check_doclist fts3c-1.2.5.3 0 3 test {[1] [3]} 212check_doclist fts3c-1.2.5.4 0 3 this {[1] [3]} 213 214#************************************************************************* 215# Test results when everything is optimized manually. 216db eval { 217 DROP TABLE IF EXISTS t1; 218 CREATE VIRTUAL TABLE t1 USING fts3(c); 219 INSERT INTO t1 (docid, c) VALUES (1, 'This is a test'); 220 INSERT INTO t1 (docid, c) VALUES (2, 'That was a test'); 221 INSERT INTO t1 (docid, c) VALUES (3, 'This is a test'); 222 DELETE FROM t1 WHERE docid IN (1,3); 223 DROP TABLE IF EXISTS t1old; 224 ALTER TABLE t1 RENAME TO t1old; 225 CREATE VIRTUAL TABLE t1 USING fts3(c); 226 INSERT INTO t1 (docid, c) SELECT docid, c FROM t1old; 227 DROP TABLE t1old; 228} 229 230# Should be a single optimal segment with the same logical results. 231do_test fts3c-1.3.segments { 232 execsql { 233 SELECT level, idx FROM t1_segdir ORDER BY level, idx; 234 } 235} {0 0} 236do_test fts3c-1.3.matches { 237 execsql { 238 SELECT OFFSETS(t1) FROM t1 239 WHERE t1 MATCH 'this OR that OR was OR a OR is OR test' ORDER BY docid; 240 } 241} {{0 1 0 4 0 2 5 3 0 3 9 1 0 5 11 4}} 242 243check_terms_all fts3c-1.3.1 {a test that was} 244check_doclist_all fts3c-1.3.1.1 a {[2 0[2]]} 245check_doclist_all fts3c-1.3.1.2 test {[2 0[3]]} 246check_doclist_all fts3c-1.3.1.3 that {[2 0[0]]} 247check_doclist_all fts3c-1.3.1.4 was {[2 0[1]]} 248 249check_terms fts3c-1.3.2 0 0 {a test that was} 250check_doclist fts3c-1.3.2.1 0 0 a {[2 0[2]]} 251check_doclist fts3c-1.3.2.2 0 0 test {[2 0[3]]} 252check_doclist fts3c-1.3.2.3 0 0 that {[2 0[0]]} 253check_doclist fts3c-1.3.2.4 0 0 was {[2 0[1]]} 254 255finish_test 256