diff --git a/ext/fts5/fts5_index.c b/ext/fts5/fts5_index.c index a1735a1104..7d98ef72ff 100644 --- a/ext/fts5/fts5_index.c +++ b/ext/fts5/fts5_index.c @@ -550,18 +550,23 @@ struct Fts5NodeIter { ** of a doclist-index record. ** ** pData: -** A reference to the dlidx record. +** Record containing the doclist-index data. +** +** bEof: +** Set to true once iterator has reached EOF. +** +** iOff: +** Set to the current offset within record pData. */ struct Fts5DlidxIter { Fts5Data *pData; /* Data for doclist index, if any */ int iOff; /* Current offset into pDlidx */ - int bRowidValid; /* iRowid is valid */ int bEof; /* At EOF already */ + int iFirstOff; /* Used by reverse iterators only */ /* Output variables */ int iLeafPgno; /* Page number of current leaf page */ - int bZero; /* True if current leaf has no rowids */ - i64 iRowid; /* If bZero==0, first rowid on leaf */ + i64 iRowid; /* First rowid on leaf iLeafPgno */ }; @@ -1124,14 +1129,83 @@ static void fts5NodeIterFree(Fts5NodeIter *pIter){ } /* -** Return non-zero if EOF is reached. +** The iterator passed as the first argument has the following fields set +** as follows. This function sets up the rest of the iterator so that it +** points to the first rowid in the doclist-index. +** +** pData: pointer to doclist-index record, +** iLeafPgno: page number that this doclist-index is associated with. */ -static int fts5DlidxIterNext(Fts5DlidxIter *pIter, int bRev){ - if( bRev ){ +static int fts5DlidxIterFirst(Fts5DlidxIter *pIter){ + Fts5Data *pData = pIter->pData; + int i; + + assert( pIter->pData ); + assert( pIter->iLeafPgno>0 ); + + /* Count the number of leading 0x00 bytes. Then set iLeafPgno. */ + for(i=0; in; i++){ + if( pData->p[i] ) break; + } + pIter->iLeafPgno += (i+1); + pIter->iOff = i; + + /* Unless we are already at the end of the doclist-index, load the first + ** rowid value. */ + if( pIter->iOffn ){ + pIter->iOff += getVarint(&pData->p[pIter->iOff], (u64*)&pIter->iRowid); + }else{ + pIter->bEof = 1; + } + pIter->iFirstOff = pIter->iOff; + return pIter->bEof; +} + +/* +** Advance the iterator passed as the only argument. +*/ +static int fts5DlidxIterNext(Fts5DlidxIter *pIter){ + Fts5Data *pData = pIter->pData; + int iOff; + + for(iOff=pIter->iOff; iOffn; iOff++){ + if( pData->p[iOff] ) break; + } + + if( iOffn ){ i64 iVal; - int iOff = pIter->iOff; - int iLimit; + pIter->iLeafPgno += (iOff - pIter->iOff) + 1; + iOff += getVarint(&pData->p[iOff], (u64*)&iVal); + pIter->iRowid -= iVal; + pIter->iOff = iOff; + }else{ + pIter->bEof = 1; + } + + return pIter->bEof; +} + +static int fts5DlidxIterEof(Fts5Index *p, Fts5DlidxIter *pIter){ + return (p->rc!=SQLITE_OK || pIter->bEof); +} + +static void fts5DlidxIterLast(Fts5DlidxIter *pIter){ + if( fts5DlidxIterFirst(pIter)==0 ){ + while( 0==fts5DlidxIterNext(pIter) ); + pIter->bEof = 0; + } +} + +static int fts5DlidxIterPrev(Fts5DlidxIter *pIter){ + int iOff = pIter->iOff; + + assert( pIter->bEof==0 ); + if( iOff<=pIter->iFirstOff ){ + pIter->bEof = 1; + }else{ u8 *a = pIter->pData->p; + i64 iVal; + int iLimit; /* Currently iOff points to the first byte of a varint. This block ** decrements iOff until it points to the first byte of the previous @@ -1141,53 +1215,19 @@ static int fts5DlidxIterNext(Fts5DlidxIter *pIter, int bRev){ for(iOff--; iOff>iLimit; iOff--){ if( (a[iOff-1] & 0x80)==0 ) break; } - pIter->iOff = iOff; - - if( iOff<=0 ){ - pIter->bEof = 1; - return 1; - } getVarint(&a[iOff], (u64*)&iVal); - if( iVal==0 ){ - pIter->bZero = 1; - }else if( iOff==0 ){ - pIter->iRowid = iVal; - }else{ - pIter->iRowid += iVal; - } + pIter->iRowid += iVal; pIter->iLeafPgno--; - }else{ - i64 iVal; - if( pIter->iOff>=pIter->pData->n ){ - pIter->bEof = 1; - return 1; + + while( a[iOff-1]==0x00 ){ + iOff--; + pIter->iLeafPgno--; } - pIter->iOff += getVarint(&pIter->pData->p[pIter->iOff], (u64*)&iVal); - if( iVal==0 ){ - pIter->bZero = 1; - }else{ - pIter->bZero = 0; - if( pIter->bRowidValid ){ - pIter->iRowid -= iVal; - }else{ - pIter->bRowidValid = 1; - pIter->iRowid = iVal; - } - } - pIter->iLeafPgno++; + pIter->iOff = iOff; } - return 0; -} -static void fts5DlidxIterLast(Fts5DlidxIter *pIter){ - while( 0==fts5DlidxIterNext(pIter, 0) ); - assert( pIter->iOff==pIter->pData->n && pIter->bEof==1 ); - pIter->bEof = 0; -} - -static int fts5DlidxIterEof(Fts5Index *p, Fts5DlidxIter *pIter){ - return (p->rc!=SQLITE_OK || pIter->bEof); + return pIter->bEof; } static void fts5DlidxIterInit( @@ -1213,10 +1253,9 @@ static void fts5DlidxIterInit( } pIter->pData = pDlidx; - pIter->iLeafPgno = iLeafPgno; if( bRev==0 ){ - fts5DlidxIterNext(pIter, 0); + fts5DlidxIterFirst(pIter); }else{ fts5DlidxIterLast(pIter); } @@ -1438,44 +1477,6 @@ static void fts5SegIterNext( pIter->iRowid += iDelta; }else{ fts5SegIterReverseNewPage(p, pIter); -#if 0 - fts5DataRelease(pIter->pLeaf); - pIter->pLeaf = 0; - while( p->rc==SQLITE_OK && pIter->iLeafPgno>pIter->iTermLeafPgno ){ - Fts5Data *pNew; - pIter->iLeafPgno--; - pNew = fts5DataRead(p, FTS5_SEGMENT_ROWID( - pIter->iIdx, pIter->pSeg->iSegid, 0, pIter->iLeafPgno - )); - if( pNew ){ - if( pIter->iLeafPgno==pIter->iTermLeafPgno ){ - if( pIter->iTermLeafOffsetn ){ - pIter->pLeaf = pNew; - pIter->iLeafOffset = pIter->iTermLeafOffset; - } - }else{ - int iRowidOff, dummy; - fts5LeafHeader(pNew, &iRowidOff, &dummy); - if( iRowidOff ){ - pIter->pLeaf = pNew; - pIter->iLeafOffset = iRowidOff; - } - } - - if( pIter->pLeaf ){ - u8 *a = &pIter->pLeaf->p[pIter->iLeafOffset]; - pIter->iLeafOffset += getVarint(a, (u64*)&pIter->iRowid); - break; - }else{ - fts5DataRelease(pNew); - } - } - } - - if( pIter->pLeaf ){ - fts5SegIterReverseInitPage(p, pIter); - } -#endif } }else{ Fts5Data *pLeaf = pIter->pLeaf; @@ -1555,43 +1556,49 @@ static void fts5SegIterReverse(Fts5Index *p, int iIdx, Fts5SegIter *pIter){ /* Move to the page that contains the last rowid in this doclist. */ pLeaf = pIter->pLeaf; - while( iOffn ){ - int nPos; - i64 iDelta; + if( pIter->pDlidx ){ + int iSegid = pIter->pSeg->iSegid; + pgnoLast = pIter->pDlidx->iLeafPgno; + pLast = fts5DataRead(p, FTS5_SEGMENT_ROWID(iIdx, iSegid, 0, pgnoLast)); + }else{ + while( iOffn ){ + int nPos; + i64 iDelta; - /* Position list size in bytes */ - iOff += getVarint32(&pLeaf->p[iOff], nPos); - iOff += nPos; - if( iOff>=pLeaf->n ) break; + /* Position list size in bytes */ + iOff += getVarint32(&pLeaf->p[iOff], nPos); + iOff += nPos; + if( iOff>=pLeaf->n ) break; - /* Rowid delta. Or, if 0x00, the end of doclist marker. */ - nPos = getVarint(&pLeaf->p[iOff], (u64*)&iDelta); - if( iDelta==0 ) break; - iOff += nPos; - } + /* Rowid delta. Or, if 0x00, the end of doclist marker. */ + nPos = getVarint(&pLeaf->p[iOff], (u64*)&iDelta); + if( iDelta==0 ) break; + iOff += nPos; + } - if( iOff>=pLeaf->n ){ - Fts5StructureSegment *pSeg = pIter->pSeg; - i64 iAbs = FTS5_SEGMENT_ROWID(iIdx, pSeg->iSegid, 0, pIter->iLeafPgno); - i64 iLast = FTS5_SEGMENT_ROWID(iIdx, pSeg->iSegid, 0, pSeg->pgnoLast); + if( iOff>=pLeaf->n ){ + Fts5StructureSegment *pSeg = pIter->pSeg; + i64 iAbs = FTS5_SEGMENT_ROWID(iIdx, pSeg->iSegid, 0, pIter->iLeafPgno); + i64 iLast = FTS5_SEGMENT_ROWID(iIdx, pSeg->iSegid, 0, pSeg->pgnoLast); - /* The last rowid in the doclist may not be on the current page. Search - ** forward to find the page containing the last rowid. */ - for(iAbs++; p->rc==SQLITE_OK && iAbs<=iLast; iAbs++){ - Fts5Data *pNew = fts5DataRead(p, iAbs); - if( pNew ){ - int iRowid, iTerm; - fts5LeafHeader(pNew, &iRowid, &iTerm); - if( iRowid ){ - Fts5Data *pTmp = pLast; - pLast = pNew; - pNew = pTmp; - pgnoLast = iAbs & (((i64)1 << FTS5_DATA_PAGE_B) - 1); + /* The last rowid in the doclist may not be on the current page. Search + ** forward to find the page containing the last rowid. */ + for(iAbs++; p->rc==SQLITE_OK && iAbs<=iLast; iAbs++){ + Fts5Data *pNew = fts5DataRead(p, iAbs); + if( pNew ){ + int iRowid, iTerm; + fts5LeafHeader(pNew, &iRowid, &iTerm); + if( iRowid ){ + Fts5Data *pTmp = pLast; + pLast = pNew; + pNew = pTmp; + pgnoLast = iAbs & (((i64)1 << FTS5_DATA_PAGE_B) - 1); + } + if( iTerm ){ + iAbs = iLast; + } + fts5DataRelease(pNew); } - if( iTerm ){ - iAbs = iLast; - } - fts5DataRelease(pNew); } } } @@ -1615,7 +1622,6 @@ static void fts5SegIterReverse(Fts5Index *p, int iIdx, Fts5SegIter *pIter){ } fts5SegIterReverseInitPage(p, pIter); - pIter->flags |= FTS5_SEGITER_REVERSE; } /* @@ -1733,6 +1739,9 @@ static void fts5SegIterSeekInit( if( bGe==0 ){ pIter->flags |= FTS5_SEGITER_ONETERM; if( pIter->pLeaf ){ + if( flags & FTS5INDEX_QUERY_ASC ){ + pIter->flags |= FTS5_SEGITER_REVERSE; + } if( bDlidx ){ fts5SegIterLoadDlidx(p, iIdx, pIter); } @@ -1879,37 +1888,44 @@ static void fts5SegIterNextFrom( int bRev = (pIter->flags & FTS5_SEGITER_REVERSE); Fts5DlidxIter *pDlidx = pIter->pDlidx; int iLeafPgno = pIter->iLeafPgno; + int bMove = 1; assert( pIter->flags & FTS5_SEGITER_ONETERM ); assert( pIter->pDlidx ); assert( pIter->pLeaf ); - if( bRev==0 ){ while( fts5DlidxIterEof(p, pDlidx)==0 && iMatchiRowid ){ - if( pDlidx->bZero==0 ) iLeafPgno = pDlidx->iLeafPgno; - fts5DlidxIterNext(pDlidx, 0); + iLeafPgno = pDlidx->iLeafPgno; + fts5DlidxIterNext(pDlidx); } assert( iLeafPgno>=pIter->iLeafPgno || p->rc ); if( iLeafPgno>pIter->iLeafPgno ){ fts5SegIterGotoPage(p, pIter, iLeafPgno); + bMove = 0; } - }else if( 0 ){ + }else{ + assert( iMatch>pIter->iRowid ); while( fts5DlidxIterEof(p, pDlidx)==0 && iMatch>pDlidx->iRowid ){ - fts5DlidxIterNext(pDlidx, 0); - if( pDlidx->bZero==0 ) iLeafPgno = pDlidx->iLeafPgno; + fts5DlidxIterPrev(pDlidx); } - assert( iLeafPgno<=pIter->iLeafPgno || p->rc ); + iLeafPgno = pDlidx->iLeafPgno; + + assert( fts5DlidxIterEof(p, pDlidx) || iLeafPgno<=pIter->iLeafPgno ); + if( iLeafPgnoiLeafPgno ){ - fts5SegIterGotoPage(p, pIter, iLeafPgno); + pIter->iLeafPgno = iLeafPgno+1; + fts5SegIterReverseNewPage(p, pIter); + bMove = 0; } } while( 1 ){ - fts5SegIterNext(p, pIter); + if( bMove ) fts5SegIterNext(p, pIter); if( pIter->pLeaf==0 ) break; if( bRev==0 && pIter->iRowid<=iMatch ) break; if( bRev!=0 && pIter->iRowid>=iMatch ) break; + bMove = 1; } } @@ -3377,7 +3393,50 @@ static void fts5BtreeIterFree(Fts5BtreeIter *pIter){ fts5BufferFree(&pIter->term); } +/* +** This function is purely an internal test. It does not contribute to +** FTS functionality, or even the integrity-check, in any way. +** +** Instead, it tests that the same set of pgno/rowid combinations are +** visited regardless of whether the doclist-index identified by parameters +** iIdx/iSegid/iLeaf is iterated in forwards or reverse order. +*/ +#ifdef SQLITE_DEBUG +static void fts5DlidxIterTestReverse( + Fts5Index *p, + int iIdx, /* Index to load doclist-index from */ + int iSegid, /* Segment id to load from */ + int iLeaf /* Load doclist-index for this leaf */ +){ + Fts5DlidxIter *pDlidx = 0; + i64 cksum1 = 13; + i64 cksum2 = 13; + for(fts5DlidxIterInit(p, 0, iIdx, iSegid, iLeaf, &pDlidx); + fts5DlidxIterEof(p, pDlidx)==0; + fts5DlidxIterNext(pDlidx) + ){ + cksum1 = (cksum1 ^ ( (i64)(pDlidx->iLeafPgno) << 32 )); + cksum1 = (cksum1 ^ pDlidx->iRowid); + } + fts5DlidxIterFree(pDlidx); + pDlidx = 0; + + for(fts5DlidxIterInit(p, 1, iIdx, iSegid, iLeaf, &pDlidx); + fts5DlidxIterEof(p, pDlidx)==0; + fts5DlidxIterPrev(pDlidx) + ){ + cksum2 = (cksum2 ^ ( (i64)(pDlidx->iLeafPgno) << 32 )); + cksum2 = (cksum2 ^ pDlidx->iRowid); + } + fts5DlidxIterFree(pDlidx); + pDlidx = 0; + + if( p->rc==SQLITE_OK && cksum1!=cksum2 ) p->rc = FTS5_CORRUPT; +} +#else +# define fts5DlidxIterTestReverse(w,x,y,z) +#endif static void fts5IndexIntegrityCheckSegment( Fts5Index *p, /* FTS5 backend object */ @@ -3421,7 +3480,6 @@ static void fts5IndexIntegrityCheckSegment( fts5DataRelease(pLeaf); if( p->rc ) break; - /* Now check that the iter.nEmpty leaves following the current leaf ** (a) exist and (b) contain no terms. */ for(i=1; p->rc==SQLITE_OK && i<=iter.nEmpty; i++){ @@ -3435,35 +3493,52 @@ static void fts5IndexIntegrityCheckSegment( /* If there is a doclist-index, check that it looks right. */ if( iter.bDlidx ){ Fts5DlidxIter *pDlidx = 0; /* For iterating through doclist index */ - int nEntry = 0; + int iPrevLeaf = iter.iLeaf; int iSegid = pSeg->iSegid; - int bRev = 0; + int iPg; + i64 iKey; - for(fts5DlidxIterInit(p, bRev, iIdx, iSegid, iter.iLeaf, &pDlidx); + for(fts5DlidxIterInit(p, 0, iIdx, iSegid, iter.iLeaf, &pDlidx); fts5DlidxIterEof(p, pDlidx)==0; - fts5DlidxIterNext(pDlidx, bRev) + fts5DlidxIterNext(pDlidx) ){ - i64 iKey = FTS5_SEGMENT_ROWID(iIdx, iSegid, 0, pDlidx->iLeafPgno); + + /* Check any rowid-less pages that occur before the current leaf. */ + for(iPg=iPrevLeaf+1; iPgiLeafPgno; iPg++){ + iKey = FTS5_SEGMENT_ROWID(iIdx, iSegid, 0, iPg); + pLeaf = fts5DataRead(p, iKey); + if( pLeaf ){ + if( fts5GetU16(&pLeaf->p[0])!=0 ) p->rc = FTS5_CORRUPT; + fts5DataRelease(pLeaf); + } + } + iPrevLeaf = pDlidx->iLeafPgno; + + /* Check that the leaf page indicated by the iterator really does + ** contain the rowid suggested by the same. */ + iKey = FTS5_SEGMENT_ROWID(iIdx, iSegid, 0, pDlidx->iLeafPgno); pLeaf = fts5DataRead(p, iKey); if( pLeaf ){ + i64 iRowid; int iRowidOff = fts5GetU16(&pLeaf->p[0]); - if( pDlidx->bZero ){ - if( iRowidOff!=0 ) p->rc = FTS5_CORRUPT; - }else{ - i64 iRowid; - getVarint(&pLeaf->p[iRowidOff], (u64*)&iRowid); - if( iRowid!=pDlidx->iRowid ) p->rc = FTS5_CORRUPT; - } + getVarint(&pLeaf->p[iRowidOff], (u64*)&iRowid); + if( iRowid!=pDlidx->iRowid ) p->rc = FTS5_CORRUPT; fts5DataRelease(pLeaf); } - nEntry++; + } - /* Check that the doclist-index was the right length */ - if( p->rc==SQLITE_OK && nEntry!=iter.nEmpty && nEntry!=iter.nEmpty+1 ){ - p->rc = FTS5_CORRUPT; + for(iPg=iPrevLeaf+1; iPg<=(iter.iLeaf + iter.nEmpty); iPg++){ + iKey = FTS5_SEGMENT_ROWID(iIdx, iSegid, 0, iPg); + pLeaf = fts5DataRead(p, iKey); + if( pLeaf ){ + if( fts5GetU16(&pLeaf->p[0])!=0 ) p->rc = FTS5_CORRUPT; + fts5DataRelease(pLeaf); + } } + fts5DlidxIterFree(pDlidx); + fts5DlidxIterTestReverse(p, iIdx, iSegid, iter.iLeaf); } } diff --git a/manifest b/manifest index bd1784eeb1..cca7f70664 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sfts5_index.c\sto\suse\sdoclist-indexes\swhen\spossible.\sOnly\ssome\scases\swork\sso\sfar. -D 2014-08-04T20:07:40.532 +C Use\sdoclist-indexes\swith\s"ORDER\sBY\srowid\sASC"\sfts5\squeries\sas\swell. +D 2014-08-05T19:00:22.438 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in b03432313a3aad96c706f8164fb9f5307eaf19f5 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -110,7 +110,7 @@ F ext/fts5/fts5_aux.c 366057c7186bc3615deb5ecc0ff61de50b6d2dbc F ext/fts5/fts5_buffer.c 248c61ac9fec001602efc72a45704f3b8d367c00 F ext/fts5/fts5_config.c f4ebf143e141b8c77355e3b15aba81b7be51d710 F ext/fts5/fts5_expr.c 9402474456732ddb5019f83a77907852f108a96a -F ext/fts5/fts5_index.c 3578823a9a43fcc77ce46c7f6efddfd155544053 +F ext/fts5/fts5_index.c 40d9086948d6f1420a078bd9fb0b5372e54ec791 F ext/fts5/fts5_storage.c 2866e7e1de9dc851756c3a9c76b6e1d75e0facb7 F ext/fts5/fts5parse.y 777da8e5819f75c217982c79c29d014c293acac9 F ext/icu/README.txt d9fbbad0c2f647c3fdf715fc9fd64af53aedfc43 @@ -595,14 +595,14 @@ F test/fts4merge3.test aab02a09f50fe6baaddc2e159c3eabc116d45fc7 F test/fts4merge4.test d895b1057a7798b67e03455d0fa50e9ea836c47b F test/fts4noti.test 524807f0c36d49deea7920cdd4cd687408b58849 F test/fts4unicode.test 01ec3fe2a7c3cfff3b4c0581b83caa11b33efa36 -F test/fts5aa.test f54245091fee924030722234070fcba95a493549 +F test/fts5aa.test 2d136b61c4523ec018699e59b35c005313569b9e F test/fts5ab.test dc04ed48cf93ca957d174406e6c192f2ff4f3397 -F test/fts5ac.test 9be418d037763f4cc5d86f4239db41fc86bb4f85 +F test/fts5ac.test 399533fe52b7383053368ab8ba01ae182391e5d7 F test/fts5ad.test 2ed38bbc865678cb2905247120d02ebba7f20e07 F test/fts5ae.test cb37b3135a00d3afd5492ec534ecf654be5ff69e F test/fts5af.test 9ebe23aa3875896076952c7bc6e8308813a63c74 F test/fts5ag.test 0747bf3bade16d5165810cf891f875933b28b420 -F test/fts5ah.test ca1f12b5738992c2edbdeb6c16133d41cfb9c031 +F test/fts5ah.test 009b993a9b7ebc43f84c10e53bd778b1dc8ffbe7 F test/fts5ea.test ff43b40f8879ba50b82def70f2ab67c195d1a1d4 F test/full.test 6b3c8fb43c6beab6b95438c1675374b95fab245d F test/func.test ae97561957aba6ca9e3a7b8a13aac41830d701ef @@ -1199,7 +1199,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f -P b8864da95db2c0e611116304d607e35a86c9247d -R 2807aba63fb0a8821d708dc4cbc7f577 +P 90b82d3ef613b2915e0e280dc1d2e5a2b617d59c +R 0266e2e08ce753d75d582fc91e12512e U dan -Z 6114a7973c3151dffa74bd597b78489f +Z 1a32a19af984c36e1b27a239a8950f8a diff --git a/manifest.uuid b/manifest.uuid index a558eb6008..42fda03308 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -90b82d3ef613b2915e0e280dc1d2e5a2b617d59c \ No newline at end of file +d028ba6589f3122b635474c2683c0f93d5bc6c7c \ No newline at end of file diff --git a/test/fts5aa.test b/test/fts5aa.test index 3d1fc99289..5bd0912435 100644 --- a/test/fts5aa.test +++ b/test/fts5aa.test @@ -148,6 +148,7 @@ do_execsql_test 6.2 { #------------------------------------------------------------------------- # reset_db +expr srand(0) do_execsql_test 7.0 { CREATE VIRTUAL TABLE t1 USING fts5(x,y,z); INSERT INTO t1(t1) VALUES('pgsz=32'); @@ -173,7 +174,7 @@ proc dump_structure {} { for {set i 1} {$i <= 10} {incr i} { do_test 7.$i { - for {set j 0} {$j < 100} {incr j} { + for {set j 0} {$j < 10} {incr j} { set x [doc] set y [doc] set z [doc] diff --git a/test/fts5ac.test b/test/fts5ac.test index ae6e56e7e7..b137e3a938 100644 --- a/test/fts5ac.test +++ b/test/fts5ac.test @@ -364,6 +364,10 @@ foreach {tn expr tclexpr} { #------------------------------------------------------------------------- # +do_execsql_test 6.integrity { + INSERT INTO xx(xx) VALUES('integrity-check'); +} +#db eval {SELECT rowid, fts5_decode(rowid, block) aS r FROM xx_data} {puts $r} foreach {bAsc sql} { 0 {SELECT rowid FROM xx WHERE xx MATCH $expr} 1 {SELECT rowid FROM xx WHERE xx MATCH $expr ORDER BY rowid ASC} diff --git a/test/fts5ah.test b/test/fts5ah.test index 3f217d9f86..f5e25848ab 100644 --- a/test/fts5ah.test +++ b/test/fts5ah.test @@ -53,6 +53,12 @@ proc reads {} { db one {SELECT t1 FROM t1 WHERE t1 MATCH '*reads'} } +proc execsql_reads {sql} { + set nRead [reads] + execsql $sql + expr [reads] - $nRead +} + do_test 1.4 { set nRead [reads] execsql { SELECT rowid FROM t1 WHERE t1 MATCH 'x' } @@ -60,6 +66,14 @@ do_test 1.4 { expr $nReadX>1000 } {1} +do_test 1.5 { + set fwd [execsql_reads {SELECT rowid FROM t1 WHERE t1 MATCH 'x' }] + set bwd [execsql_reads { + SELECT rowid FROM t1 WHERE t1 MATCH 'x' ORDER BY 1 ASC + }] + expr {$bwd < $fwd + 10} +} {1} + foreach {tn q res} " 1 { SELECT rowid FROM t1 WHERE t1 MATCH 'w + x' } [list $W] 2 { SELECT rowid FROM t1 WHERE t1 MATCH 'x + w' } [list $W] @@ -67,22 +81,18 @@ foreach {tn q res} " 4 { SELECT rowid FROM t1 WHERE t1 MATCH 'y AND x' } [list $Y] " { - do_test 1.5.$tn.1 { - set nRead [reads] - execsql $q - set n [expr [reads] - $nRead] + do_test 1.6.$tn.1 { + set n [execsql_reads $q] expr {$n < ($nReadX / 10)} } {1} - do_test 1.5.$tn.2 { - set nRead [reads] - execsql "$q ORDER BY rowid ASC" - set n [expr [reads] - $nRead] + do_test 1.6.$tn.2 { + set n [execsql_reads "$q ORDER BY rowid ASC"] expr {$n < ($nReadX / 10)} } {1} - do_execsql_test 1.5.$tn.3 $q [lsort -int -decr $res] - do_execsql_test 1.5.$tn.4 "$q ORDER BY rowid ASC" [lsort -int -incr $res] + do_execsql_test 1.6.$tn.3 $q [lsort -int -decr $res] + do_execsql_test 1.6.$tn.4 "$q ORDER BY rowid ASC" [lsort -int -incr $res] } #db eval {SELECT rowid, fts5_decode(rowid, block) aS r FROM t1_data} {puts $r}