Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Fix a problem causing the fts3 integrity-check to fail if run inside a transaction. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
3b925189a75eae875da256b6e54999ca |
User & Date: | dan 2015-04-23 11:52:04.753 |
References
2015-05-20
| ||
20:34 | Fix a problem causing the fts3 integrity-check to fail if run inside a transaction. Cherrypick of [3b925189a75e]. (check-in: 7d7d633c71 user: dan tags: branch-3.8.6) | |
Context
2015-05-20
| ||
20:34 | Fix a problem causing the fts3 integrity-check to fail if run inside a transaction. Cherrypick of [3b925189a75e]. (check-in: 7d7d633c71 user: dan tags: branch-3.8.6) | |
2015-04-23
| ||
13:00 | Improvement to "ID" formatting on the ".selecttrace 0x1ff" debugging function. (check-in: 01c50cee37 user: drh tags: trunk) | |
11:52 | Fix a problem causing the fts3 integrity-check to fail if run inside a transaction. (check-in: 3b925189a7 user: dan tags: trunk) | |
2015-04-22
| ||
13:16 | Improved filtering of input for fuzzershell for modes other than generic. (check-in: 025e8370dd user: drh tags: trunk) | |
Changes
Changes to ext/fts3/fts3.c.
︙ | ︙ | |||
2806 2807 2808 2809 2810 2811 2812 | ** for the pending-terms. If this is a scan, then this call must be being ** made by an fts4aux module, not an FTS table. In this case calling ** Fts3SegReaderPending might segfault, as the data structures used by ** fts4aux are not completely populated. So it's easiest to filter these ** calls out here. */ if( iLevel<0 && p->aIndex ){ Fts3SegReader *pSeg = 0; | | | 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 | ** for the pending-terms. If this is a scan, then this call must be being ** made by an fts4aux module, not an FTS table. In this case calling ** Fts3SegReaderPending might segfault, as the data structures used by ** fts4aux are not completely populated. So it's easiest to filter these ** calls out here. */ if( iLevel<0 && p->aIndex ){ Fts3SegReader *pSeg = 0; rc = sqlite3Fts3SegReaderPending(p, iIndex, zTerm, nTerm, isPrefix||isScan, &pSeg); if( rc==SQLITE_OK && pSeg ){ rc = fts3SegReaderCursorAppend(pCsr, pSeg); } } if( iLevel!=FTS3_SEGCURSOR_PENDING ){ if( rc==SQLITE_OK ){ |
︙ | ︙ |
Changes to ext/fts3/fts3_write.c.
︙ | ︙ | |||
322 323 324 325 326 327 328 | /* 21 */ "SELECT size FROM %Q.'%q_docsize' WHERE docid=?", /* 22 */ "SELECT value FROM %Q.'%q_stat' WHERE id=?", /* 23 */ "REPLACE INTO %Q.'%q_stat' VALUES(?,?)", /* 24 */ "", /* 25 */ "", /* 26 */ "DELETE FROM %Q.'%q_segdir' WHERE level BETWEEN ? AND ?", | | | 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 | /* 21 */ "SELECT size FROM %Q.'%q_docsize' WHERE docid=?", /* 22 */ "SELECT value FROM %Q.'%q_stat' WHERE id=?", /* 23 */ "REPLACE INTO %Q.'%q_stat' VALUES(?,?)", /* 24 */ "", /* 25 */ "", /* 26 */ "DELETE FROM %Q.'%q_segdir' WHERE level BETWEEN ? AND ?", /* 27 */ "SELECT ? UNION SELECT level / (1024 * ?) FROM %Q.'%q_segdir'", /* This statement is used to determine which level to read the input from ** when performing an incremental merge. It returns the absolute level number ** of the oldest level in the db that contains at least ? segments. Or, ** if no level in the FTS index contains more than ? segments, the statement ** returns zero rows. */ /* 28 */ "SELECT level FROM %Q.'%q_segdir' GROUP BY level HAVING count(*)>=?" |
︙ | ︙ | |||
3440 3441 3442 3443 3444 3445 3446 | int bSeenDone = 0; int rc; sqlite3_stmt *pAllLangid = 0; rc = fts3SqlStmt(p, SQL_SELECT_ALL_LANGID, &pAllLangid, 0); if( rc==SQLITE_OK ){ int rc2; | | > | 3440 3441 3442 3443 3444 3445 3446 3447 3448 3449 3450 3451 3452 3453 3454 3455 | int bSeenDone = 0; int rc; sqlite3_stmt *pAllLangid = 0; rc = fts3SqlStmt(p, SQL_SELECT_ALL_LANGID, &pAllLangid, 0); if( rc==SQLITE_OK ){ int rc2; sqlite3_bind_int(pAllLangid, 1, p->iPrevLangid); sqlite3_bind_int(pAllLangid, 2, p->nIndex); while( sqlite3_step(pAllLangid)==SQLITE_ROW ){ int i; int iLangid = sqlite3_column_int(pAllLangid, 0); for(i=0; rc==SQLITE_OK && i<p->nIndex; i++){ rc = fts3SegmentMerge(p, iLangid, i, FTS3_SEGCURSOR_ALL); if( rc==SQLITE_DONE ){ bSeenDone = 1; |
︙ | ︙ | |||
4772 4773 4774 4775 4776 4777 4778 | i = pHint->n-2; while( i>0 && (pHint->a[i-1] & 0x80) ) i--; while( i>0 && (pHint->a[i-1] & 0x80) ) i--; pHint->n = i; i += sqlite3Fts3GetVarint(&pHint->a[i], piAbsLevel); i += fts3GetVarint32(&pHint->a[i], pnInput); | | | 4773 4774 4775 4776 4777 4778 4779 4780 4781 4782 4783 4784 4785 4786 4787 | i = pHint->n-2; while( i>0 && (pHint->a[i-1] & 0x80) ) i--; while( i>0 && (pHint->a[i-1] & 0x80) ) i--; pHint->n = i; i += sqlite3Fts3GetVarint(&pHint->a[i], piAbsLevel); i += fts3GetVarint32(&pHint->a[i], pnInput); if( i!=nHint ) return FTS_CORRUPT_VTAB; return SQLITE_OK; } /* ** Attempt an incremental merge that writes nMerge leaf blocks. |
︙ | ︙ | |||
5140 5141 5142 5143 5144 5145 5146 | u64 cksum2 = 0; /* Checksum based on %_content contents */ sqlite3_stmt *pAllLangid = 0; /* Statement to return all language-ids */ /* This block calculates the checksum according to the FTS index. */ rc = fts3SqlStmt(p, SQL_SELECT_ALL_LANGID, &pAllLangid, 0); if( rc==SQLITE_OK ){ int rc2; | | > < | 5141 5142 5143 5144 5145 5146 5147 5148 5149 5150 5151 5152 5153 5154 5155 5156 5157 5158 5159 5160 5161 5162 5163 5164 5165 5166 5167 5168 | u64 cksum2 = 0; /* Checksum based on %_content contents */ sqlite3_stmt *pAllLangid = 0; /* Statement to return all language-ids */ /* This block calculates the checksum according to the FTS index. */ rc = fts3SqlStmt(p, SQL_SELECT_ALL_LANGID, &pAllLangid, 0); if( rc==SQLITE_OK ){ int rc2; sqlite3_bind_int(pAllLangid, 1, p->iPrevLangid); sqlite3_bind_int(pAllLangid, 2, p->nIndex); while( rc==SQLITE_OK && sqlite3_step(pAllLangid)==SQLITE_ROW ){ int iLangid = sqlite3_column_int(pAllLangid, 0); int i; for(i=0; i<p->nIndex; i++){ cksum1 = cksum1 ^ fts3ChecksumIndex(p, iLangid, i, &rc); } } rc2 = sqlite3_reset(pAllLangid); if( rc==SQLITE_OK ) rc = rc2; } /* This block calculates the checksum according to the %_content table */ if( rc==SQLITE_OK ){ sqlite3_tokenizer_module const *pModule = p->pTokenizer->pModule; sqlite3_stmt *pStmt = 0; char *zSql; zSql = sqlite3_mprintf("SELECT %s" , p->zReadExprlist); if( !zSql ){ |
︙ | ︙ | |||
5250 5251 5252 5253 5254 5255 5256 | */ static int fts3DoIntegrityCheck( Fts3Table *p /* FTS3 table handle */ ){ int rc; int bOk = 0; rc = fts3IntegrityCheck(p, &bOk); | | | 5251 5252 5253 5254 5255 5256 5257 5258 5259 5260 5261 5262 5263 5264 5265 | */ static int fts3DoIntegrityCheck( Fts3Table *p /* FTS3 table handle */ ){ int rc; int bOk = 0; rc = fts3IntegrityCheck(p, &bOk); if( rc==SQLITE_OK && bOk==0 ) rc = FTS_CORRUPT_VTAB; return rc; } /* ** Handle a 'special' INSERT of the form: ** ** "INSERT INTO tbl(tbl) VALUES(<expr>)" |
︙ | ︙ |
Changes to test/fts4check.test.
︙ | ︙ | |||
174 175 176 177 178 179 180 181 182 183 | db close sqlite3 db test.db catchsql { INSERT INTO t4(t4) VALUES('integrity-check'); } } {1 {database disk image is malformed}} reset_db finish_test | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 | db close sqlite3 db test.db catchsql { INSERT INTO t4(t4) VALUES('integrity-check'); } } {1 {database disk image is malformed}} reset_db #-------------------------------------------------------------------------- # Test case 5.* # # Test that the integrity-check works if there is uncommitted data. # do_execsql_test 5.0 { BEGIN; CREATE VIRTUAL TABLE t5 USING fts4(a, prefix="1,2,3"); INSERT INTO t5 VALUES('And down by Kosiosko, where the reed-banks sweep'); INSERT INTO t5 VALUES('and sway, and the rolling plains are wide, the'); INSERT INTO t5 VALUES('man from snowy river is a household name today,'); INSERT INTO t5 VALUES('and the stockmen tell the story of his ride'); } do_execsql_test 5.1 { INSERT INTO t5(t5) VALUES('integrity-check'); } {} do_catchsql_test 5.2 { INSERT INTO t5_content VALUES(5, 'his hardy mountain pony'); INSERT INTO t5(t5) VALUES('integrity-check'); } {1 {database disk image is malformed}} do_execsql_test 5.3 ROLLBACK do_execsql_test 5.4 { CREATE VIRTUAL TABLE t5 USING fts4(a, prefix="1,2,3"); INSERT INTO t5(t5) VALUES('integrity-check'); } {} finish_test |
Changes to test/trace2.test.
︙ | ︙ | |||
139 140 141 142 143 144 145 | "-- SELECT level, idx, end_block FROM 'main'.'x1_segdir' WHERE level BETWEEN ? AND ? ORDER BY level DESC, idx ASC" } do_trace_test 2.3 { INSERT INTO x1(x1) VALUES('optimize'); } { "INSERT INTO x1(x1) VALUES('optimize');" | | | 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 | "-- SELECT level, idx, end_block FROM 'main'.'x1_segdir' WHERE level BETWEEN ? AND ? ORDER BY level DESC, idx ASC" } do_trace_test 2.3 { INSERT INTO x1(x1) VALUES('optimize'); } { "INSERT INTO x1(x1) VALUES('optimize');" "-- SELECT ? UNION SELECT level / (1024 * ?) FROM 'main'.'x1_segdir'" "-- SELECT idx, start_block, leaves_end_block, end_block, root FROM 'main'.'x1_segdir' WHERE level BETWEEN ? AND ?ORDER BY level DESC, idx ASC" "-- SELECT max(level) FROM 'main'.'x1_segdir' WHERE level BETWEEN ? AND ?" "-- SELECT coalesce((SELECT max(blockid) FROM 'main'.'x1_segments') + 1, 1)" "-- DELETE FROM 'main'.'x1_segdir' WHERE level BETWEEN ? AND ?" "-- REPLACE INTO 'main'.'x1_segdir' VALUES(?,?,?,?,?,?)" } } |
︙ | ︙ |