modernc.org/cc@v1.0.1/v2/testdata/_sqlite/test/fts4opt.test (about) 1 # 2016 March 8 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 # 12 13 set testdir [file dirname $argv0] 14 source $testdir/tester.tcl 15 source $testdir/fts3_common.tcl 16 set ::testprefix fts4opt 17 18 # If SQLITE_ENABLE_FTS3 is defined, omit this file. 19 ifcapable !fts3 { 20 finish_test 21 return 22 } 23 24 # Create the fts_kjv_genesis procedure which fills and FTS3/4 table 25 # with the complete text of the Book of Genesis. 26 # 27 source $testdir/genesis.tcl 28 29 do_execsql_test 1.0 { CREATE TABLE t1(docid, words) } 30 fts_kjv_genesis 31 32 #------------------------------------------------------------------------- 33 # Argument $db is an open database handle. $tbl is the name of an FTS3/4 34 # table with the database. This command rearranges the contents of the 35 # %_segdir table so that all segments within each index are on the same 36 # level. This means that the 'merge' command can then be used for an 37 # incremental optimize routine. 38 # 39 proc prepare_for_optimize {db tbl} { 40 $db eval [string map [list % $tbl] { 41 BEGIN; 42 CREATE TEMP TABLE tmp_segdir( 43 level, idx, start_block, leaves_end_block, end_block, root 44 ); 45 46 INSERT INTO temp.tmp_segdir 47 SELECT 48 1024*(o.level / 1024) + 32, -- level 49 sum(o.level<i.level OR (o.level=i.level AND o.idx>i.idx)), -- idx 50 o.start_block, o.leaves_end_block, o.end_block, o.root -- other 51 FROM %_segdir o, %_segdir i 52 WHERE (o.level / 1024) = (i.level / 1024) 53 GROUP BY o.level, o.idx; 54 55 DELETE FROM %_segdir; 56 INSERT INTO %_segdir SELECT * FROM temp.tmp_segdir; 57 DROP TABLE temp.tmp_segdir; 58 59 COMMIT; 60 }] 61 } 62 63 do_test 1.1 { 64 execsql { CREATE VIRTUAL TABLE t2 USING fts4(words, prefix="1,2,3") } 65 foreach {docid words} [db eval { SELECT * FROM t1 }] { 66 execsql { INSERT INTO t2(docid, words) VALUES($docid, $words) } 67 } 68 } {} 69 70 do_execsql_test 1.2 { 71 SELECT level, count(*) FROM t2_segdir GROUP BY level 72 } { 73 0 13 1 15 2 5 74 1024 13 1025 15 1026 5 75 2048 13 2049 15 2050 5 76 3072 13 3073 15 3074 5 77 } 78 79 do_execsql_test 1.3 { INSERT INTO t2(t2) VALUES('integrity-check') } 80 prepare_for_optimize db t2 81 do_execsql_test 1.4 { INSERT INTO t2(t2) VALUES('integrity-check') } 82 83 do_execsql_test 1.5 { 84 SELECT level, count(*) FROM t2_segdir GROUP BY level 85 } { 86 32 33 87 1056 33 88 2080 33 89 3104 33 90 } 91 92 do_test 1.6 { 93 while 1 { 94 set tc1 [db total_changes] 95 execsql { INSERT INTO t2(t2) VALUES('merge=5,2') } 96 set tc2 [db total_changes] 97 if {($tc2 - $tc1) < 2} break 98 } 99 execsql { SELECT level, count(*) FROM t2_segdir GROUP BY level } 100 } {33 1 1057 1 2081 1 3105 1} 101 do_execsql_test 1.7 { INSERT INTO t2(t2) VALUES('integrity-check') } 102 103 do_execsql_test 1.8 { 104 INSERT INTO t2(words) SELECT words FROM t1; 105 SELECT level, count(*) FROM t2_segdir GROUP BY level; 106 } {0 2 1024 2 2048 2 3072 2} 107 108 #------------------------------------------------------------------------- 109 110 do_execsql_test 2.0 { 111 DELETE FROM t2; 112 } 113 do_test 2.1 { 114 foreach {docid words} [db eval { SELECT * FROM t1 }] { 115 execsql { INSERT INTO t2(docid, words) VALUES($docid, $words) } 116 } 117 118 set i 0 119 foreach {docid words} [db eval { SELECT * FROM t1 }] { 120 if {[incr i] % 2} { execsql { DELETE FROM t2 WHERE docid = $docid } } 121 } 122 123 set i 0 124 foreach {docid words} [db eval { SELECT * FROM t1 }] { 125 if {[incr i] % 3} { 126 execsql { INSERT OR REPLACE INTO t2(docid, words) VALUES($docid, $words) } 127 } 128 } 129 } {} 130 131 do_execsql_test 2.2 { 132 SELECT level, count(*) FROM t2_segdir GROUP BY level 133 } { 134 0 10 1 15 2 12 135 1024 10 1025 15 1026 12 136 2048 10 2049 15 2050 12 137 3072 10 3073 15 3074 12 138 } 139 140 do_execsql_test 2.3 { INSERT INTO t2(t2) VALUES('integrity-check') } 141 prepare_for_optimize db t2 142 do_execsql_test 2.4 { INSERT INTO t2(t2) VALUES('integrity-check') } 143 144 do_execsql_test 2.5 { 145 SELECT level, count(*) FROM t2_segdir GROUP BY level 146 } { 147 32 37 148 1056 37 149 2080 37 150 3104 37 151 } 152 153 do_test 2.6 { 154 while 1 { 155 set tc1 [db total_changes] 156 execsql { INSERT INTO t2(t2) VALUES('merge=5,2') } 157 set tc2 [db total_changes] 158 if {($tc2 - $tc1) < 2} break 159 } 160 execsql { SELECT level, count(*) FROM t2_segdir GROUP BY level } 161 } {33 1 1057 1 2081 1 3105 1} 162 do_execsql_test 2.7 { INSERT INTO t2(t2) VALUES('integrity-check') } 163 164 do_execsql_test 2.8 { 165 INSERT INTO t2(words) SELECT words FROM t1; 166 SELECT level, count(*) FROM t2_segdir GROUP BY level; 167 } {0 2 1024 2 2048 2 3072 2} 168 169 #------------------------------------------------------------------------- 170 # Check that 'optimize' works when there is data in the in-memory hash 171 # table, but no segments at all on disk. 172 # 173 do_execsql_test 3.1 { 174 CREATE VIRTUAL TABLE fts USING fts4 (t); 175 INSERT INTO fts (fts) VALUES ('optimize'); 176 } 177 do_execsql_test 3.2 { 178 INSERT INTO fts(fts) VALUES('integrity-check'); 179 SELECT count(*) FROM fts_segdir; 180 } {0} 181 do_execsql_test 3.3 { 182 BEGIN; 183 INSERT INTO fts (rowid, t) VALUES (2, 'test'); 184 INSERT INTO fts (fts) VALUES ('optimize'); 185 COMMIT; 186 SELECT level, idx FROM fts_segdir; 187 } {0 0} 188 do_execsql_test 3.4 { 189 INSERT INTO fts(fts) VALUES('integrity-check'); 190 SELECT rowid FROM fts WHERE fts MATCH 'test'; 191 } {2} 192 do_execsql_test 3.5 { 193 INSERT INTO fts (fts) VALUES ('optimize'); 194 INSERT INTO fts(fts) VALUES('integrity-check'); 195 } 196 do_test 3.6 { 197 set c1 [db total_changes] 198 execsql { INSERT INTO fts (fts) VALUES ('optimize') } 199 expr {[db total_changes] - $c1} 200 } {1} 201 do_test 3.7 { 202 execsql { INSERT INTO fts (rowid, t) VALUES (3, 'xyz') } 203 set c1 [db total_changes] 204 execsql { INSERT INTO fts (fts) VALUES ('optimize') } 205 expr {([db total_changes] - $c1) > 1} 206 } {1} 207 do_test 3.8 { 208 set c1 [db total_changes] 209 execsql { INSERT INTO fts (fts) VALUES ('optimize') } 210 expr {[db total_changes] - $c1} 211 } {1} 212 213 finish_test