blob: 3cd693209d909a6983f52b282903d2d875f0dcb6 [file] [log] [blame]
dan593c9822012-03-08 18:39:03 +00001# 2012 March 06
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 implements regression tests for SQLite library. The
12# focus of this script is testing the incremental merge function.
13#
14
15set testdir [file dirname $argv0]
16source $testdir/tester.tcl
17source $testdir/fts3_common.tcl
dan593c9822012-03-08 18:39:03 +000018
19# If SQLITE_ENABLE_FTS3 is defined, omit this file.
20ifcapable !fts3 {
21 finish_test
22 return
23}
24
dancbcd9f52012-03-26 10:36:55 +000025proc fts3_integrity_check {tbl} {
26 db eval "INSERT INTO $tbl ($tbl) VALUES('integrity-check')"
27 return "ok"
28}
29
dan311ec022012-03-27 15:00:06 +000030foreach mod {fts3 fts4} {
31 set ::testprefix fts4merge-$mod
dan5730ef52012-03-14 20:01:52 +000032 reset_db
dan5730ef52012-03-14 20:01:52 +000033
dan311ec022012-03-27 15:00:06 +000034 #-------------------------------------------------------------------------
35 # Test cases 1.*
36 #
37 do_test 1.0 { fts3_build_db_1 -module $mod 1004 } {}
38 do_test 1.1 { fts3_integrity_check t1 } {ok}
39 do_execsql_test 1.1 {
40 SELECT level, group_concat(idx, ' ') FROM t1_segdir GROUP BY level
41 } {
42 0 {0 1 2 3 4 5 6 7 8 9 10 11}
43 1 {0 1 2 3 4 5 6 7 8 9 10 11 12 13}
44 2 {0 1 2}
dane81eaec2012-03-22 16:48:12 +000045 }
dan311ec022012-03-27 15:00:06 +000046
47 for {set i 0} {$i<20} {incr i} {
48 do_execsql_test 1.2.$i.1 { INSERT INTO t1(t1) VALUES('merge=1') }
49 do_test 1.2.$i.2 { fts3_integrity_check t1 } ok
50 do_execsql_test 1.2.$i.3 {
51 SELECT docid FROM t1 WHERE t1 MATCH 'zero one two three'
52 } {123 132 213 231 312 321}
53 }
54
55 do_execsql_test 1.3 {
56 SELECT level, group_concat(idx, ' ') FROM t1_segdir GROUP BY level
57 } {
dan311ec022012-03-27 15:00:06 +000058 2 {0 1 2 3}
59 }
60
61 for {set i 0} {$i<100} {incr i} {
62 do_execsql_test 1.4.$i { INSERT INTO t1(t1) VALUES('merge=1,4') }
63 do_test 1.4.$i.2 { fts3_integrity_check t1 } ok
64 do_execsql_test 1.4.$i.3 {
65 SELECT docid FROM t1 WHERE t1 MATCH 'zero one two three'
66 } {123 132 213 231 312 321}
67 }
68
69 do_execsql_test 1.5 {
70 SELECT level, group_concat(idx, ' ') FROM t1_segdir GROUP BY level
71 } {
dan311ec022012-03-27 15:00:06 +000072 3 0
73 }
74
75 #-------------------------------------------------------------------------
76 # Test cases 2.* test that errors in the xxx part of the 'merge=xxx' are
77 # handled correctly.
78 #
79 do_execsql_test 2.0 "CREATE VIRTUAL TABLE t2 USING $mod"
80
81 foreach {tn arg} {
82 1 {merge=abc}
83 2 {merge=%%%}
84 3 {merge=,}
85 4 {merge=5,}
86 5 {merge=6,%}
87 6 {merge=6,six}
88 7 {merge=6,1}
dan311ec022012-03-27 15:00:06 +000089 } {
90 do_catchsql_test 2.$tn {
91 INSERT INTO t2(t2) VALUES($arg);
drha690ff32017-07-07 19:43:23 +000092 } {1 {SQL logic error}}
dan311ec022012-03-27 15:00:06 +000093 }
94
95 #-------------------------------------------------------------------------
96 # Test cases 3.*
97 #
98 do_test 3.0 {
99 reset_db
100 execsql { PRAGMA page_size = 512 }
101 fts3_build_db_2 -module $mod 30040
102 } {}
103 do_test 3.1 { fts3_integrity_check t2 } {ok}
104
105 do_execsql_test 3.2 {
106 SELECT level, group_concat(idx, ' ') FROM t2_segdir GROUP BY level
107 } {
108 0 {0 1 2 3 4 5 6}
109 1 {0 1 2 3 4}
110 2 {0 1 2 3 4}
111 3 {0 1 2 3 4 5 6}
112 }
113
114 do_execsql_test 3.3 {
115 INSERT INTO t2(t2) VALUES('merge=1000000,2');
116 SELECT level, group_concat(idx, ' ') FROM t2_segdir GROUP BY level
117 } {
dan311ec022012-03-27 15:00:06 +0000118 4 0
dan311ec022012-03-27 15:00:06 +0000119 }
120
121 #-------------------------------------------------------------------------
122 # Test cases 4.*
123 #
124 reset_db
125 do_execsql_test 4.1 "
126 PRAGMA page_size = 512;
127 CREATE VIRTUAL TABLE t4 USING $mod;
128 PRAGMA main.page_size;
129 " {512}
130
131 do_test 4.2 {
132 foreach x {a c b d e f g h i j k l m n o p} {
133 execsql "INSERT INTO t4 VALUES('[string repeat $x 600]')"
134 }
135 execsql {SELECT level, group_concat(idx, ' ') FROM t4_segdir GROUP BY level}
136 } {0 {0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15}}
137
138 foreach {tn expect} {
139 1 "0 {0 1 2 3 4 5 6 7 8 9 10 11 12 13} 1 0"
140 2 "0 {0 1 2 3 4 5 6 7 8 9 10 11 12} 1 0"
141 3 "0 {0 1 2 3 4 5 6 7 8 9 10 11} 1 0"
142 4 "0 {0 1 2 3 4 5 6 7 8 9 10} 1 0"
143 5 "0 {0 1 2 3 4 5 6 7 8 9} 1 0"
144 6 "0 {0 1 2 3 4 5 6 7 8} 1 0"
145 7 "0 {0 1 2 3 4 5 6 7} 1 0"
146 8 "0 {0 1 2 3 4 5 6} 1 0"
147 9 "0 {0 1 2 3 4 5} 1 0"
148 } {
149 do_execsql_test 4.3.$tn {
150 INSERT INTO t4(t4) VALUES('merge=1,16');
151 SELECT level, group_concat(idx, ' ') FROM t4_segdir GROUP BY level;
152 } $expect
153 }
154
155 do_execsql_test 4.4.1 {
156 SELECT quote(value) FROM t4_stat WHERE rowid=1
157 } {X'0006'}
158
drh0f0d3dd2018-11-06 19:26:04 +0000159 sqlite3_db_config db DEFENSIVE 0
dan311ec022012-03-27 15:00:06 +0000160 do_execsql_test 4.4.2 {
161 DELETE FROM t4_stat WHERE rowid=1;
162 INSERT INTO t4(t4) VALUES('merge=1,12');
dane81eaec2012-03-22 16:48:12 +0000163 SELECT level, group_concat(idx, ' ') FROM t4_segdir GROUP BY level;
dan311ec022012-03-27 15:00:06 +0000164 } "0 {0 1 2 3 4 5} 1 0"
165
166
167 #-------------------------------------------------------------------------
168 # Test cases 5.*
169 #
170 # Test that if a crisis-merge occurs that disrupts an ongoing incremental
171 # merge, the next call to "merge=A,B" identifies this and starts a new
172 # incremental merge. There are two scenarios:
173 #
174 # * There are less segments on the input level that the disrupted
175 # incremental merge operated on, or
176 #
177 # * Sufficient segments exist on the input level but the segments
178 # contain keys smaller than the largest key in the potential output
179 # segment.
180 #
181 do_test 5.1 {
182 reset_db
183 fts3_build_db_1 -module $mod 1000
184 } {}
185
186 do_execsql_test 5.2 {
187 SELECT level, group_concat(idx, ' ') FROM t1_segdir GROUP BY level;
188 } {
189 0 {0 1 2 3 4 5 6 7}
190 1 {0 1 2 3 4 5 6 7 8 9 10 11 12 13}
191 2 {0 1 2}
dan185c1fb2012-03-22 17:48:00 +0000192 }
dan311ec022012-03-27 15:00:06 +0000193
194 do_execsql_test 5.3 {
195 INSERT INTO t1(t1) VALUES('merge=1,5');
196 INSERT INTO t1(t1) VALUES('merge=1,5');
197 SELECT level, group_concat(idx, ' ') FROM t1_segdir GROUP BY level;
198 } {
dan311ec022012-03-27 15:00:06 +0000199 1 {0 1 2 3 4 5 6 7 8 9 10 11 12 13 14}
200 2 {0 1 2 3}
dan185c1fb2012-03-22 17:48:00 +0000201 }
dan311ec022012-03-27 15:00:06 +0000202
danc7dbce02016-03-08 15:37:48 +0000203 do_execsql_test 5.4 {SELECT quote(value) from t1_stat WHERE rowid=1} {X'010F'}
dan311ec022012-03-27 15:00:06 +0000204 do_test 5.5 {
205 foreach docid [execsql {SELECT docid FROM t1}] {
206 execsql {INSERT INTO t1 SELECT * FROM t1 WHERE docid=$docid}
207 }
208 } {}
209
danc7dbce02016-03-08 15:37:48 +0000210 do_execsql_test 5.6 {SELECT quote(value) from t1_stat WHERE rowid=1} {X'010F'}
dan311ec022012-03-27 15:00:06 +0000211
212 do_execsql_test 5.7 {
213 SELECT level, group_concat(idx, ' ') FROM t1_segdir GROUP BY level;
214 SELECT quote(value) from t1_stat WHERE rowid=1;
215 } {
danc7dbce02016-03-08 15:37:48 +0000216 0 {0 1 2 3 4 5 6 7}
dan311ec022012-03-27 15:00:06 +0000217 1 {0 1 2 3 4 5 6 7 8 9 10 11 12}
danc7dbce02016-03-08 15:37:48 +0000218 2 {0 1 2 3 4 5 6 7}
219 X'010F'
dan3501a912012-03-23 14:38:49 +0000220 }
dan311ec022012-03-27 15:00:06 +0000221
222 do_execsql_test 5.8 {
223 INSERT INTO t1(t1) VALUES('merge=1,6');
224 INSERT INTO t1(t1) VALUES('merge=1,6');
225 SELECT level, group_concat(idx, ' ') FROM t1_segdir GROUP BY level;
226 SELECT quote(value) from t1_stat WHERE rowid=1;
227 } {
dan311ec022012-03-27 15:00:06 +0000228 1 {0 1 2 3 4 5 6 7 8 9 10 11 12 13}
danc7dbce02016-03-08 15:37:48 +0000229 2 {0 1 2 3 4 5 6 7 8} X'010E'
dan3501a912012-03-23 14:38:49 +0000230 }
dan311ec022012-03-27 15:00:06 +0000231
232 do_test 5.8.1 { fts3_integrity_check t1 } ok
233
234 do_test 5.9 {
235 set L [expr 16*16*7 + 16*3 + 12]
236 foreach docid [execsql {
237 SELECT docid FROM t1 UNION ALL SELECT docid FROM t1 LIMIT $L
238 }] {
239 execsql {INSERT INTO t1 SELECT * FROM t1 WHERE docid=$docid}
240 }
241 } {}
242
243 do_execsql_test 5.10 {
244 SELECT level, group_concat(idx, ' ') FROM t1_segdir GROUP BY level;
245 SELECT quote(value) from t1_stat WHERE rowid=1;
246 } {
danc7dbce02016-03-08 15:37:48 +0000247 0 {0 1 2 3 4 5 6 7 8 9 10 11} 1 0 2 0 3 0 X'010E'
dan311ec022012-03-27 15:00:06 +0000248 }
249
250 do_execsql_test 5.11 {
251 INSERT INTO t1(t1) VALUES('merge=1,6');
252 SELECT level, group_concat(idx, ' ') FROM t1_segdir GROUP BY level;
253 SELECT quote(value) from t1_stat WHERE rowid=1;
254 } {
danc7dbce02016-03-08 15:37:48 +0000255 1 {0 1} 2 0 3 0 X'010E'
dan311ec022012-03-27 15:00:06 +0000256 }
257
258 #-------------------------------------------------------------------------
259 # Test cases 6.*
260 #
261 # At one point the following test caused an assert() to fail (because the
262 # second 'merge=1,2' operation below actually "merges" a single input
263 # segment, which was unexpected).
264 #
265 do_test 6.1 {
266 reset_db
267 set a [string repeat a 900]
268 set b [string repeat b 900]
269 set c [string repeat c 900]
270 set d [string repeat d 900]
dane81eaec2012-03-22 16:48:12 +0000271
dan311ec022012-03-27 15:00:06 +0000272 execsql "CREATE VIRTUAL TABLE t1 USING $mod"
273 execsql {
274 BEGIN;
275 INSERT INTO t1 VALUES($a);
276 INSERT INTO t1 VALUES($b);
277 COMMIT;
278 BEGIN;
279 INSERT INTO t1 VALUES($c);
280 INSERT INTO t1 VALUES($d);
281 COMMIT;
282 }
283
284 execsql {
285 INSERT INTO t1(t1) VALUES('merge=1,2');
286 INSERT INTO t1(t1) VALUES('merge=1,2');
287 }
288 } {}
289
290 #-------------------------------------------------------------------------
291 # Test cases 7.*
292 #
293 # Test that the value returned by sqlite3_total_changes() increases by
294 # 1 following a no-op "merge=A,B", or by more than 1 if actual work is
295 # performed.
296 #
297 do_test 7.0 {
298 reset_db
299 fts3_build_db_1 -module $mod 1000
300 } {}
301
302 do_execsql_test 7.1 {
303 SELECT level, group_concat(idx, ' ') FROM t1_segdir GROUP BY level
304 } {
305 0 {0 1 2 3 4 5 6 7}
306 1 {0 1 2 3 4 5 6 7 8 9 10 11 12 13}
307 2 {0 1 2}
308 }
309 do_test 7.2 {
310 set x [db total_changes]
311 execsql { INSERT INTO t1(t1) VALUES('merge=2,10') }
312 expr { ([db total_changes] - $x)>1 }
313 } {1}
314 do_test 7.3 {
315 set x [db total_changes]
316 execsql { INSERT INTO t1(t1) VALUES('merge=200,10') }
317 expr { ([db total_changes] - $x)>1 }
318 } {1}
319 do_test 7.4 {
320 set x [db total_changes]
321 execsql { INSERT INTO t1(t1) VALUES('merge=200,10') }
322 expr { ([db total_changes] - $x)>1 }
323 } {0}
324 do_test 7.5 {
325 set x [db total_changes]
326 execsql { INSERT INTO t1(t1) VALUES('merge=200,10') }
327 expr { ([db total_changes] - $x)>1 }
328 } {0}
danb2075012019-10-17 15:41:36 +0000329}
danba512b02012-03-23 15:38:43 +0000330
danb2075012019-10-17 15:41:36 +0000331#-------------------------------------------------------------------------
332# Test cases 8.* - ticket [bf1aab89].
333#
334set testprefix fts4merge
335reset_db
336do_execsql_test 8.0 {
337 CREATE VIRTUAL TABLE t1 USING fts4(a, order=DESC);
338 INSERT INTO t1(a) VALUES (0);
339 INSERT INTO t1(a) VALUES (0);
340 UPDATE t1 SET a = NULL;
341}
342
343do_execsql_test 8.1 {
344 INSERT INTO t1(t1) VALUES('merge=1,4');
danba512b02012-03-23 15:38:43 +0000345}
danba512b02012-03-23 15:38:43 +0000346
dane81eaec2012-03-22 16:48:12 +0000347finish_test