Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Add tests for fts5. Fix a crash that can occur in fts5 if the database content is corrupted. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
acaf426449bf6fd3140fd63141750ff6 |
User & Date: | dan 2016-01-18 17:48:28.938 |
Context
2016-01-19
| ||
16:06 | Add further fts5 tests. 100% code coverage is finally restored. (check-in: b914ece0d1 user: dan tags: trunk) | |
2016-01-18
| ||
17:48 | Add tests for fts5. Fix a crash that can occur in fts5 if the database content is corrupted. (check-in: acaf426449 user: dan tags: trunk) | |
13:18 | Avoid unnecessary calls to memset() for a small performance improvement. (check-in: 9e8c23acf7 user: drh tags: trunk) | |
Changes
Changes to ext/fts5/fts5Int.h.
︙ | ︙ | |||
221 222 223 224 225 226 227 | /* ** Buffer object for the incremental building of string data. */ typedef struct Fts5Buffer Fts5Buffer; struct Fts5Buffer { u8 *p; | | | | | | 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 | /* ** Buffer object for the incremental building of string data. */ typedef struct Fts5Buffer Fts5Buffer; struct Fts5Buffer { u8 *p; u32 n; u32 nSpace; }; int sqlite3Fts5BufferSize(int*, Fts5Buffer*, u32); void sqlite3Fts5BufferAppendVarint(int*, Fts5Buffer*, i64); void sqlite3Fts5BufferAppendBlob(int*, Fts5Buffer*, u32, const u8*); void sqlite3Fts5BufferAppendString(int *, Fts5Buffer*, const char*); void sqlite3Fts5BufferFree(Fts5Buffer*); void sqlite3Fts5BufferZero(Fts5Buffer*); void sqlite3Fts5BufferSet(int*, Fts5Buffer*, int, const u8*); void sqlite3Fts5BufferAppendPrintf(int *, Fts5Buffer*, char *zFmt, ...); char *sqlite3Fts5Mprintf(int *pRc, const char *zFmt, ...); |
︙ | ︙ |
Changes to ext/fts5/fts5_buffer.c.
︙ | ︙ | |||
11 12 13 14 15 16 17 | ****************************************************************************** */ #include "fts5Int.h" | | | | 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | ****************************************************************************** */ #include "fts5Int.h" int sqlite3Fts5BufferSize(int *pRc, Fts5Buffer *pBuf, u32 nByte){ u32 nNew = pBuf->nSpace ? pBuf->nSpace*2 : 64; u8 *pNew; while( nNew<nByte ){ nNew = nNew * 2; } pNew = sqlite3_realloc(pBuf->p, nNew); if( pNew==0 ){ *pRc = SQLITE_NOMEM; |
︙ | ︙ | |||
57 58 59 60 61 62 63 | ** Append buffer nData/pData to buffer pBuf. If an OOM error occurs, set ** the error code in p. If an error has already occurred when this function ** is called, it is a no-op. */ void sqlite3Fts5BufferAppendBlob( int *pRc, Fts5Buffer *pBuf, | | | | 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | ** Append buffer nData/pData to buffer pBuf. If an OOM error occurs, set ** the error code in p. If an error has already occurred when this function ** is called, it is a no-op. */ void sqlite3Fts5BufferAppendBlob( int *pRc, Fts5Buffer *pBuf, u32 nData, const u8 *pData ){ assert_nc( *pRc || nData>=0 ); if( fts5BufferGrow(pRc, pBuf, nData) ) return; memcpy(&pBuf->p[pBuf->n], pData, nData); pBuf->n += nData; } /* ** Append the nul-terminated string zStr to the buffer pBuf. This function |
︙ | ︙ |
Changes to ext/fts5/fts5_expr.c.
︙ | ︙ | |||
830 831 832 833 834 835 836 | int rc; assert( pNode->eType==FTS5_TERM ); assert( pNear->nPhrase==1 && pPhrase->nTerm==1 ); assert( pPhrase->aTerm[0].pSynonym==0 ); rc = sqlite3Fts5IterPoslist(pIter, pColset, | | | 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 | int rc; assert( pNode->eType==FTS5_TERM ); assert( pNear->nPhrase==1 && pPhrase->nTerm==1 ); assert( pPhrase->aTerm[0].pSynonym==0 ); rc = sqlite3Fts5IterPoslist(pIter, pColset, (const u8**)&pPhrase->poslist.p, (int*)&pPhrase->poslist.n, &pNode->iRowid ); pNode->bNomatch = (pPhrase->poslist.n==0); return rc; } /* ** All individual term iterators in pNear are guaranteed to be valid when |
︙ | ︙ |
Changes to ext/fts5/fts5_index.c.
︙ | ︙ | |||
6010 6011 6012 6013 6014 6015 6016 | int nKeep = 0; int iOff; memset(&term, 0, sizeof(Fts5Buffer)); /* Decode any entries that occur before the first term. */ if( szLeaf<n ){ | | | | | | 6010 6011 6012 6013 6014 6015 6016 6017 6018 6019 6020 6021 6022 6023 6024 6025 6026 6027 6028 6029 6030 6031 6032 6033 6034 6035 6036 6037 6038 6039 6040 6041 6042 6043 6044 6045 6046 6047 6048 6049 6050 6051 6052 6053 6054 6055 | int nKeep = 0; int iOff; memset(&term, 0, sizeof(Fts5Buffer)); /* Decode any entries that occur before the first term. */ if( szLeaf<n ){ iPgidxOff += fts5GetVarint32(&a[iPgidxOff], iTermOff); }else{ iTermOff = szLeaf; } fts5DecodeRowidList(&rc, &s, &a[4], iTermOff-4); iOff = iTermOff; while( iOff<szLeaf ){ int nAppend; /* Read the term data for the next term*/ iOff += fts5GetVarint32(&a[iOff], nAppend); term.n = nKeep; fts5BufferAppendBlob(&rc, &term, nAppend, &a[iOff]); sqlite3Fts5BufferAppendPrintf( &rc, &s, " term=%.*s", term.n, (const char*)term.p ); iOff += nAppend; /* Figure out where the doclist for this term ends */ if( iPgidxOff<n ){ int nIncr; iPgidxOff += fts5GetVarint32(&a[iPgidxOff], nIncr); iTermOff += nIncr; }else{ iTermOff = szLeaf; } fts5DecodeRowidList(&rc, &s, &a[iOff], iTermOff-iOff); iOff = iTermOff; if( iOff<szLeaf ){ iOff += fts5GetVarint32(&a[iOff], nKeep); } } fts5BufferFree(&term); }else{ Fts5Buffer term; /* Current term read from page */ int szLeaf; /* Offset of pgidx in a[] */ |
︙ | ︙ |
Added ext/fts5/test/fts5merge2.test.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | # 2014 Dec 20 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # # Test that focus on incremental merges of segments. # source [file join [file dirname [info script]] fts5_common.tcl] set testprefix fts5merge proc dump_structure {} { db eval {SELECT fts5_decode(id, block) AS t FROM t1_data WHERE id=10} { foreach lvl [lrange $t 1 end] { set seg [string repeat . [expr [llength $lvl]-2]] puts "[lrange $lvl 0 1] $seg" } } } foreach_detail_mode $testprefix { if {[detail_is_none]==0} continue do_execsql_test 1.0 { CREATE VIRTUAL TABLE t1 USING fts5(x, detail=%DETAIL%); INSERT INTO t1(t1, rank) VALUES('pgsz', 32); INSERT INTO t1(t1, rank) VALUES('crisismerge', 2); INSERT INTO t1 VALUES('1 2 3 4'); } expr srand(0) db func rnddoc fts5_rnddoc do_test 1.1 { for {set i 0} {$i < 100} {incr i} { execsql { BEGIN; DELETE FROM t1 WHERE rowid = 1; INSERT INTO t1(rowid, x) VALUES(1, '1 2 3 4'); INSERT INTO t1 VALUES(rnddoc(10)); COMMIT; } } } {} do_execsql_test 1.2 { INSERT INTO t1(t1) VALUES('integrity-check'); } } finish_test |
Changes to ext/fts5/test/fts5rowid.test.
︙ | ︙ | |||
179 180 181 182 183 184 185 186 187 188 | SELECT rowid FROM x4 WHERE x4 MATCH 'a' } {1 2 3 4} set res [db one {SELECT count(*) FROM x4_data}] do_execsql_test 5.2 { SELECT count(fts5_decode(rowid, block)) FROM x4_data; } $res finish_test | > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 214 215 | SELECT rowid FROM x4 WHERE x4 MATCH 'a' } {1 2 3 4} set res [db one {SELECT count(*) FROM x4_data}] do_execsql_test 5.2 { SELECT count(fts5_decode(rowid, block)) FROM x4_data; } $res #------------------------------------------------------------------------- # do_execsql_test 6.0 { CREATE VIRTUAL TABLE x5 USING fts5(x, detail=none); INSERT INTO x5(x5, rank) VALUES('pgsz', 32); INSERT INTO x5 VALUES('a b c d e f'); INSERT INTO x5 VALUES('a b c d e f'); INSERT INTO x5 VALUES('a b c d e f'); BEGIN; WITH s(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<100 ) INSERT INTO x5 SELECT 'a b c d e f' FROM s; COMMIT; SELECT count(fts5_decode_none(rowid, block)) FROM x5_data; } {32} do_execsql_test 6.1 { DELETE FROM x5 WHERE rowid=1; UPDATE x5 SET x='a b c d e f' WHERE rowid=2; SELECT count(fts5_decode_none(rowid, block)) FROM x5_data; } {36} #db eval {SELECT rowid, fts5_decode_none(rowid, block) aS r FROM x5_data} {puts $r} finish_test |