Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4)

Side by Side Diff: third_party/sqlite/sqlite-src-3100200/ext/fts5/test/fts5corrupt2.test

Issue 1610543003: [sql] Import reference version of SQLite 3.10.2. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 # 2015 Apr 24
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 # This file tests that FTS5 handles corrupt databases (i.e. internal
13 # inconsistencies in the backing tables) correctly. In this case
14 # "correctly" means without crashing.
15 #
16
17 source [file join [file dirname [info script]] fts5_common.tcl]
18 set testprefix fts5corrupt2
19
20 # If SQLITE_ENABLE_FTS5 is defined, omit this file.
21 ifcapable !fts5 {
22 finish_test
23 return
24 }
25 sqlite3_fts5_may_be_corrupt 1
26
27 # Create a simple FTS5 table containing 100 documents. Each document
28 # contains 10 terms, each of which start with the character "x".
29 #
30 expr srand(0)
31 db func rnddoc fts5_rnddoc
32 do_execsql_test 1.0 {
33 CREATE VIRTUAL TABLE t1 USING fts5(x);
34 INSERT INTO t1(t1, rank) VALUES('pgsz', 32);
35 WITH ii(i) AS (SELECT 1 UNION SELECT i+1 FROM ii WHERE i<100)
36 INSERT INTO t1 SELECT rnddoc(10) FROM ii;
37 }
38 set mask [expr 31 << 31]
39
40 if 1 {
41
42 # Test 1:
43 #
44 # For each page in the t1_data table, open a transaction and DELETE
45 # the t1_data entry. Then run:
46 #
47 # * an integrity-check, and
48 # * unless the deleted block was a b-tree node, a query for "t1 MATCH 'x*'"
49 #
50 # and check that the corruption is detected in both cases. The
51 # rollback the transaction.
52 #
53 # Test 2:
54 #
55 # Same thing, except instead of deleting a row from t1_data, replace its
56 # blob content with integer value 14.
57 #
58 foreach {tno stmt} {
59 1 { DELETE FROM t1_data WHERE rowid=$rowid }
60 2 { UPDATE t1_data SET block=14 WHERE rowid=$rowid }
61 } {
62 set tn 0
63 foreach rowid [db eval {SELECT rowid FROM t1_data WHERE rowid>10}] {
64 incr tn
65 #if {$tn!=224} continue
66
67 do_test 1.$tno.$tn.1.$rowid {
68 execsql { BEGIN }
69 execsql $stmt
70 catchsql { INSERT INTO t1(t1) VALUES('integrity-check') }
71 } {1 {database disk image is malformed}}
72
73 if {($rowid & $mask)==0} {
74 # Node is a leaf node, not a b-tree node.
75 do_catchsql_test 1.$tno.$tn.2.$rowid {
76 SELECT rowid FROM t1 WHERE t1 MATCH 'x*'
77 } {1 {database disk image is malformed}}
78 }
79
80 do_execsql_test 1.$tno.$tn.3.$rowid {
81 ROLLBACK;
82 INSERT INTO t1(t1) VALUES('integrity-check');
83 } {}
84 }
85 }
86
87 # Using the same database as the 1.* tests.
88 #
89 # Run N-1 tests, where N is the number of bytes in the rightmost leaf page
90 # of the fts index. For test $i, truncate the rightmost leafpage to $i
91 # bytes. Then test both the integrity-check detects the corruption.
92 #
93 # Also tested is that "MATCH 'x*'" does not crash and sometimes reports
94 # corruption. It may not report the db as corrupt because truncating the
95 # final leaf to some sizes may create a valid leaf page.
96 #
97 set lrowid [db one {SELECT max(rowid) FROM t1_data WHERE (rowid & $mask)=0}]
98 set nbyte [db one {SELECT length(block) FROM t1_data WHERE rowid=$lrowid}]
99 set all [db eval {SELECT rowid FROM t1}]
100 for {set i [expr $nbyte-2]} {$i>=0} {incr i -1} {
101 do_execsql_test 2.$i.1 {
102 BEGIN;
103 UPDATE t1_data SET block = substr(block, 1, $i) WHERE rowid=$lrowid;
104 }
105
106 do_catchsql_test 2.$i.2 {
107 INSERT INTO t1(t1) VALUES('integrity-check');
108 } {1 {database disk image is malformed}}
109
110 do_test 2.$i.3 {
111 set res [catchsql {SELECT rowid FROM t1 WHERE t1 MATCH 'x*'}]
112 expr {
113 $res=="1 {database disk image is malformed}"
114 || $res=="0 {$all}"
115 }
116 } 1
117
118 do_execsql_test 2.$i.4 {
119 ROLLBACK;
120 INSERT INTO t1(t1) VALUES('integrity-check');
121 } {}
122 }
123
124 #-------------------------------------------------------------------------
125 # Test that corruption in leaf page headers is detected by queries that use
126 # doclist-indexes.
127 #
128 set doc "A B C D E F G H I J "
129 do_execsql_test 3.0 {
130 CREATE VIRTUAL TABLE x3 USING fts5(tt);
131 INSERT INTO x3(x3, rank) VALUES('pgsz', 32);
132 WITH ii(i) AS (SELECT 1 UNION ALL SELECT i+1 FROM ii WHERE i<1000)
133 INSERT INTO x3
134 SELECT ($doc || CASE WHEN (i%50)==0 THEN 'X' ELSE 'Y' END) FROM ii;
135 }
136
137 foreach {tn hdr} {
138 1 "\x00\x00\x00\x00"
139 2 "\xFF\xFF\xFF\xFF"
140 3 "\x44\x45"
141 } {
142 set tn2 0
143 set nCorrupt 0
144 set nCorrupt2 0
145 foreach rowid [db eval {SELECT rowid FROM x3_data WHERE rowid>10}] {
146 if {$rowid & $mask} continue
147 incr tn2
148 do_test 3.$tn.$tn2.1 {
149 execsql BEGIN
150
151 set fd [db incrblob main x3_data block $rowid]
152 fconfigure $fd -encoding binary -translation binary
153 set existing [read $fd [string length $hdr]]
154 seek $fd 0
155 puts -nonewline $fd $hdr
156 close $fd
157
158 set res [catchsql {SELECT rowid FROM x3 WHERE x3 MATCH 'x AND a'}]
159 if {$res == "1 {database disk image is malformed}"} {incr nCorrupt}
160 set {} 1
161 } {1}
162
163 if {($tn2 % 10)==0 && $existing != $hdr} {
164 do_test 3.$tn.$tn2.2 {
165 catchsql { INSERT INTO x3(x3) VALUES('integrity-check') }
166 } {1 {database disk image is malformed}}
167 }
168
169 execsql ROLLBACK
170 }
171
172 do_test 3.$tn.x { expr $nCorrupt>0 } 1
173 }
174
175 #--------------------------------------------------------------------
176 #
177 set doc "A B C D E F G H I J "
178 do_execsql_test 4.0 {
179 CREATE VIRTUAL TABLE x4 USING fts5(tt);
180 INSERT INTO x4(x4, rank) VALUES('pgsz', 32);
181 WITH ii(i) AS (SELECT 1 UNION ALL SELECT i+1 FROM ii WHERE i<10)
182 INSERT INTO x4
183 SELECT ($doc || CASE WHEN (i%50)==0 THEN 'X' ELSE 'Y' END) FROM ii;
184 }
185
186 foreach {tn nCut} {
187 1 1
188 2 10
189 } {
190 set tn2 0
191 set nCorrupt 0
192 foreach rowid [db eval {SELECT rowid FROM x4_data WHERE rowid>10}] {
193 if {$rowid & $mask} continue
194 incr tn2
195 do_test 4.$tn.$tn2 {
196 execsql {
197 BEGIN;
198 UPDATE x4_data SET block = substr(block, 1, length(block)-$nCut)
199 WHERE id = $rowid;
200 }
201
202 set res [catchsql {
203 SELECT rowid FROM x4 WHERE x4 MATCH 'a' ORDER BY 1 DESC
204 }]
205 if {$res == "1 {database disk image is malformed}"} {incr nCorrupt}
206 set {} 1
207 } {1}
208
209 execsql ROLLBACK
210 }
211
212 # do_test 4.$tn.x { expr $nCorrupt>0 } 1
213 }
214
215 }
216
217 set doc [string repeat "A B C " 1000]
218 do_execsql_test 5.0 {
219 CREATE VIRTUAL TABLE x5 USING fts5(tt);
220 INSERT INTO x5(x5, rank) VALUES('pgsz', 32);
221 WITH ii(i) AS (SELECT 1 UNION ALL SELECT i+1 FROM ii WHERE i<10)
222 INSERT INTO x5 SELECT $doc FROM ii;
223 }
224
225 foreach {tn hdr} {
226 1 "\x00\x01"
227 } {
228 set tn2 0
229 set nCorrupt 0
230 foreach rowid [db eval {SELECT rowid FROM x5_data WHERE rowid>10}] {
231 if {$rowid & $mask} continue
232 incr tn2
233 do_test 5.$tn.$tn2 {
234 execsql BEGIN
235
236 set fd [db incrblob main x5_data block $rowid]
237 fconfigure $fd -encoding binary -translation binary
238 puts -nonewline $fd $hdr
239 close $fd
240
241 catchsql { INSERT INTO x5(x5) VALUES('integrity-check') }
242 set {} {}
243 } {}
244
245 execsql ROLLBACK
246 }
247 }
248
249 #--------------------------------------------------------------------
250 reset_db
251 do_execsql_test 6.1 {
252 CREATE VIRTUAL TABLE x5 USING fts5(tt);
253 INSERT INTO x5 VALUES('a');
254 INSERT INTO x5 VALUES('a a');
255 INSERT INTO x5 VALUES('a a a');
256 INSERT INTO x5 VALUES('a a a a');
257
258 UPDATE x5_docsize SET sz = X'' WHERE id=3;
259 }
260 proc colsize {cmd i} {
261 $cmd xColumnSize $i
262 }
263 sqlite3_fts5_create_function db colsize colsize
264
265 do_catchsql_test 6.2 {
266 SELECT colsize(x5, 0) FROM x5 WHERE x5 MATCH 'a'
267 } {1 SQLITE_CORRUPT_VTAB}
268
269
270 sqlite3_fts5_may_be_corrupt 0
271 finish_test
272
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698