mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-29 08:01:23 +03:00
Fix an fts5 integrity-check problem that affects offsets=0 tables with prefix indexes.
FossilOrigin-Name: 609a0bc7f34e6dae74ce756aff920f3df78fe828
This commit is contained in:
@ -4373,7 +4373,9 @@ static void fts5MergePrefixLists(
|
||||
sqlite3Fts5PoslistNext64(a1, i1.nPoslist, &iOff1,&iPos1);
|
||||
}
|
||||
}
|
||||
p->rc = sqlite3Fts5PoslistWriterAppend(&tmp, &writer, iNew);
|
||||
if( iNew!=writer.iPrev || tmp.n==0 ){
|
||||
p->rc = sqlite3Fts5PoslistWriterAppend(&tmp, &writer, iNew);
|
||||
}
|
||||
}
|
||||
|
||||
/* WRITEPOSLISTSIZE */
|
||||
@ -4608,7 +4610,11 @@ int sqlite3Fts5IndexClose(Fts5Index *p){
|
||||
** size. Return the number of bytes in the nChar character prefix of the
|
||||
** buffer, or 0 if there are less than nChar characters in total.
|
||||
*/
|
||||
static int fts5IndexCharlenToBytelen(const char *p, int nByte, int nChar){
|
||||
static int sqlite3Fts5IndexCharlenToBytelen(
|
||||
const char *p,
|
||||
int nByte,
|
||||
int nChar
|
||||
){
|
||||
int n = 0;
|
||||
int i;
|
||||
for(i=0; i<nChar; i++){
|
||||
@ -4665,7 +4671,8 @@ int sqlite3Fts5IndexWrite(
|
||||
);
|
||||
|
||||
for(i=0; i<pConfig->nPrefix && rc==SQLITE_OK; i++){
|
||||
int nByte = fts5IndexCharlenToBytelen(pToken, nToken, pConfig->aPrefix[i]);
|
||||
const int nChar = pConfig->aPrefix[i];
|
||||
int nByte = sqlite3Fts5IndexCharlenToBytelen(pToken, nToken, nChar);
|
||||
if( nByte ){
|
||||
rc = sqlite3Fts5HashWrite(p->pHash,
|
||||
p->iWriteRowid, iCol, iPos, (char)(FTS5_MAIN_PREFIX+i+1), pToken,
|
||||
@ -4983,7 +4990,7 @@ int sqlite3Fts5IndexLoadConfig(Fts5Index *p){
|
||||
/*
|
||||
** Return a simple checksum value based on the arguments.
|
||||
*/
|
||||
static u64 fts5IndexEntryCksum(
|
||||
u64 sqlite3Fts5IndexEntryCksum(
|
||||
i64 iRowid,
|
||||
int iCol,
|
||||
int iPos,
|
||||
@ -5071,7 +5078,7 @@ static int fts5QueryCksum(
|
||||
){
|
||||
int iCol = FTS5_POS2COLUMN(sReader.iPos);
|
||||
int iOff = FTS5_POS2OFFSET(sReader.iPos);
|
||||
cksum ^= fts5IndexEntryCksum(rowid, iCol, iOff, iIdx, z, n);
|
||||
cksum ^= sqlite3Fts5IndexEntryCksum(rowid, iCol, iOff, iIdx, z, n);
|
||||
}
|
||||
rc = sqlite3Fts5IterNext(pIdxIter);
|
||||
}
|
||||
@ -5370,7 +5377,7 @@ static void fts5IndexIntegrityCheckSegment(
|
||||
/*
|
||||
** Run internal checks to ensure that the FTS index (a) is internally
|
||||
** consistent and (b) contains entries for which the XOR of the checksums
|
||||
** as calculated by fts5IndexEntryCksum() is cksum.
|
||||
** as calculated by sqlite3Fts5IndexEntryCksum() is cksum.
|
||||
**
|
||||
** Return SQLITE_CORRUPT if any of the internal checks fail, or if the
|
||||
** checksum does not match. Return SQLITE_OK if all checks pass without
|
||||
@ -5434,7 +5441,7 @@ int sqlite3Fts5IndexIntegrityCheck(Fts5Index *p, u64 cksum){
|
||||
while( 0==sqlite3Fts5PoslistNext64(poslist.p, poslist.n, &iOff, &iPos) ){
|
||||
int iCol = FTS5_POS2COLUMN(iPos);
|
||||
int iTokOff = FTS5_POS2OFFSET(iPos);
|
||||
cksum2 ^= fts5IndexEntryCksum(iRowid, iCol, iTokOff, -1, z, n);
|
||||
cksum2 ^= sqlite3Fts5IndexEntryCksum(iRowid, iCol, iTokOff, -1, z, n);
|
||||
}
|
||||
}
|
||||
fts5TestTerm(p, &term, 0, 0, cksum2, &cksum3);
|
||||
@ -5450,34 +5457,6 @@ int sqlite3Fts5IndexIntegrityCheck(Fts5Index *p, u64 cksum){
|
||||
return fts5IndexReturn(p);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Calculate and return a checksum that is the XOR of the index entry
|
||||
** checksum of all entries that would be generated by the token specified
|
||||
** by the final 5 arguments.
|
||||
*/
|
||||
u64 sqlite3Fts5IndexCksum(
|
||||
Fts5Config *pConfig, /* Configuration object */
|
||||
i64 iRowid, /* Document term appears in */
|
||||
int iCol, /* Column term appears in */
|
||||
int iPos, /* Position term appears in */
|
||||
const char *pTerm, int nTerm /* Term at iPos */
|
||||
){
|
||||
u64 ret = 0; /* Return value */
|
||||
int iIdx; /* For iterating through indexes */
|
||||
|
||||
ret = fts5IndexEntryCksum(iRowid, iCol, iPos, 0, pTerm, nTerm);
|
||||
|
||||
for(iIdx=0; iIdx<pConfig->nPrefix; iIdx++){
|
||||
int nByte = fts5IndexCharlenToBytelen(pTerm, nTerm, pConfig->aPrefix[iIdx]);
|
||||
if( nByte ){
|
||||
ret ^= fts5IndexEntryCksum(iRowid, iCol, iPos, iIdx+1, pTerm, nByte);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
**************************************************************************
|
||||
** Below this point is the implementation of the fts5_decode() scalar
|
||||
|
Reference in New Issue
Block a user