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 16 set testdir [file dirname $argv0] 17 source $testdir/tester.tcl 18 source $testdir/fts3_common.tcl 19 20 # If SQLITE_ENABLE_FTS3 is not defined, omit this file. 21 ifcapable !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. 29 proc 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 } 33 proc 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. 39 proc 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 } 43 proc 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. 49 db 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. 58 do_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} 63 do_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. 74 check_terms_all fts3c-1.0.1 {a is test that this was} 75 check_doclist_all fts3c-1.0.1.1 a {[1 0[2]] [2 0[2]] [3 0[2]]} 76 check_doclist_all fts3c-1.0.1.2 is {[1 0[1]] [3 0[1]]} 77 check_doclist_all fts3c-1.0.1.3 test {[1 0[3]] [2 0[3]] [3 0[3]]} 78 check_doclist_all fts3c-1.0.1.4 that {[2 0[0]]} 79 check_doclist_all fts3c-1.0.1.5 this {[1 0[0]] [3 0[0]]} 80 check_doclist_all fts3c-1.0.1.6 was {[2 0[1]]} 81 82 # Segment 0,0 83 check_terms fts3c-1.0.2 0 0 {a is test this} 84 check_doclist fts3c-1.0.2.1 0 0 a {[1 0[2]]} 85 check_doclist fts3c-1.0.2.2 0 0 is {[1 0[1]]} 86 check_doclist fts3c-1.0.2.3 0 0 test {[1 0[3]]} 87 check_doclist fts3c-1.0.2.4 0 0 this {[1 0[0]]} 88 89 # Segment 0,1 90 check_terms fts3c-1.0.3 0 1 {a test that was} 91 check_doclist fts3c-1.0.3.1 0 1 a {[2 0[2]]} 92 check_doclist fts3c-1.0.3.2 0 1 test {[2 0[3]]} 93 check_doclist fts3c-1.0.3.3 0 1 that {[2 0[0]]} 94 check_doclist fts3c-1.0.3.4 0 1 was {[2 0[1]]} 95 96 # Segment 0,2 97 check_terms fts3c-1.0.4 0 2 {a is test this} 98 check_doclist fts3c-1.0.4.1 0 2 a {[3 0[2]]} 99 check_doclist fts3c-1.0.4.2 0 2 is {[3 0[1]]} 100 check_doclist fts3c-1.0.4.3 0 2 test {[3 0[3]]} 101 check_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. 105 db 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 114 do_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} 119 do_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 126 check_terms_all fts3c-1.1.1 {a is test that this was} 127 check_doclist_all fts3c-1.1.1.1 a {[2 0[2]] [3 0[2]]} 128 check_doclist_all fts3c-1.1.1.2 is {[3 0[1]]} 129 check_doclist_all fts3c-1.1.1.3 test {[2 0[3]] [3 0[3]]} 130 check_doclist_all fts3c-1.1.1.4 that {[2 0[0]]} 131 check_doclist_all fts3c-1.1.1.5 this {[3 0[0]]} 132 check_doclist_all fts3c-1.1.1.6 was {[2 0[1]]} 133 134 check_terms fts3c-1.1.2 0 0 {a is test this} 135 check_doclist fts3c-1.1.2.1 0 0 a {[1 0[2]]} 136 check_doclist fts3c-1.1.2.2 0 0 is {[1 0[1]]} 137 check_doclist fts3c-1.1.2.3 0 0 test {[1 0[3]]} 138 check_doclist fts3c-1.1.2.4 0 0 this {[1 0[0]]} 139 140 check_terms fts3c-1.1.3 0 1 {a test that was} 141 check_doclist fts3c-1.1.3.1 0 1 a {[2 0[2]]} 142 check_doclist fts3c-1.1.3.2 0 1 test {[2 0[3]]} 143 check_doclist fts3c-1.1.3.3 0 1 that {[2 0[0]]} 144 check_doclist fts3c-1.1.3.4 0 1 was {[2 0[1]]} 145 146 check_terms fts3c-1.1.4 0 2 {a is test this} 147 check_doclist fts3c-1.1.4.1 0 2 a {[3 0[2]]} 148 check_doclist fts3c-1.1.4.2 0 2 is {[3 0[1]]} 149 check_doclist fts3c-1.1.4.3 0 2 test {[3 0[3]]} 150 check_doclist fts3c-1.1.4.4 0 2 this {[3 0[0]]} 151 152 check_terms fts3c-1.1.5 0 3 {a is test this} 153 check_doclist fts3c-1.1.5.1 0 3 a {[1]} 154 check_doclist fts3c-1.1.5.2 0 3 is {[1]} 155 check_doclist fts3c-1.1.5.3 0 3 test {[1]} 156 check_doclist fts3c-1.1.5.4 0 3 this {[1]} 157 158 #************************************************************************* 159 # Test results when all references to certain tokens are deleted. 160 db 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. 170 do_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} 175 do_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 182 check_terms_all fts3c-1.2.1 {a is test that this was} 183 check_doclist_all fts3c-1.2.1.1 a {[2 0[2]]} 184 check_doclist_all fts3c-1.2.1.2 is {} 185 check_doclist_all fts3c-1.2.1.3 test {[2 0[3]]} 186 check_doclist_all fts3c-1.2.1.4 that {[2 0[0]]} 187 check_doclist_all fts3c-1.2.1.5 this {} 188 check_doclist_all fts3c-1.2.1.6 was {[2 0[1]]} 189 190 check_terms fts3c-1.2.2 0 0 {a is test this} 191 check_doclist fts3c-1.2.2.1 0 0 a {[1 0[2]]} 192 check_doclist fts3c-1.2.2.2 0 0 is {[1 0[1]]} 193 check_doclist fts3c-1.2.2.3 0 0 test {[1 0[3]]} 194 check_doclist fts3c-1.2.2.4 0 0 this {[1 0[0]]} 195 196 check_terms fts3c-1.2.3 0 1 {a test that was} 197 check_doclist fts3c-1.2.3.1 0 1 a {[2 0[2]]} 198 check_doclist fts3c-1.2.3.2 0 1 test {[2 0[3]]} 199 check_doclist fts3c-1.2.3.3 0 1 that {[2 0[0]]} 200 check_doclist fts3c-1.2.3.4 0 1 was {[2 0[1]]} 201 202 check_terms fts3c-1.2.4 0 2 {a is test this} 203 check_doclist fts3c-1.2.4.1 0 2 a {[3 0[2]]} 204 check_doclist fts3c-1.2.4.2 0 2 is {[3 0[1]]} 205 check_doclist fts3c-1.2.4.3 0 2 test {[3 0[3]]} 206 check_doclist fts3c-1.2.4.4 0 2 this {[3 0[0]]} 207 208 check_terms fts3c-1.2.5 0 3 {a is test this} 209 check_doclist fts3c-1.2.5.1 0 3 a {[1] [3]} 210 check_doclist fts3c-1.2.5.2 0 3 is {[1] [3]} 211 check_doclist fts3c-1.2.5.3 0 3 test {[1] [3]} 212 check_doclist fts3c-1.2.5.4 0 3 this {[1] [3]} 213 214 #************************************************************************* 215 # Test results when everything is optimized manually. 216 db 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. 231 do_test fts3c-1.3.segments { 232 execsql { 233 SELECT level, idx FROM t1_segdir ORDER BY level, idx; 234 } 235 } {0 0} 236 do_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 243 check_terms_all fts3c-1.3.1 {a test that was} 244 check_doclist_all fts3c-1.3.1.1 a {[2 0[2]]} 245 check_doclist_all fts3c-1.3.1.2 test {[2 0[3]]} 246 check_doclist_all fts3c-1.3.1.3 that {[2 0[0]]} 247 check_doclist_all fts3c-1.3.1.4 was {[2 0[1]]} 248 249 check_terms fts3c-1.3.2 0 0 {a test that was} 250 check_doclist fts3c-1.3.2.1 0 0 a {[2 0[2]]} 251 check_doclist fts3c-1.3.2.2 0 0 test {[2 0[3]]} 252 check_doclist fts3c-1.3.2.3 0 0 that {[2 0[0]]} 253 check_doclist fts3c-1.3.2.4 0 0 was {[2 0[1]]} 254 255 finish_test 256