mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-29 08:01:23 +03:00
Cherrypick the [3475092cff] fix for 32-bit overflow with large language-ids
into trunk. FossilOrigin-Name: 2755edc7f1186ba8955f2c3550a90f40a55ddae2
This commit is contained in:
@ -434,16 +434,42 @@ int sqlite3Fts3ReadLock(Fts3Table *p){
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** FTS maintains a separate indexes for each language-id (a 32-bit integer).
|
||||
** Within each language id, a separate index is maintained to store the
|
||||
** document terms, and each configured prefix size (configured the FTS
|
||||
** "prefix=" option). And each index consists of multiple levels ("relative
|
||||
** levels").
|
||||
**
|
||||
** All three of these values (the language id, the specific index and the
|
||||
** level within the index) are encoded in 64-bit integer values stored
|
||||
** in the %_segdir table on disk. This function is used to convert three
|
||||
** separate component values into the single 64-bit integer value that
|
||||
** can be used to query the %_segdir table.
|
||||
**
|
||||
** Specifically, each language-id/index combination is allocated 1024
|
||||
** 64-bit integer level values ("absolute levels"). The main terms index
|
||||
** for language-id 0 is allocate values 0-1023. The first prefix index
|
||||
** (if any) for language-id 0 is allocated values 1024-2047. And so on.
|
||||
** Language 1 indexes are allocated immediately following language 0.
|
||||
**
|
||||
** So, for a system with nPrefix prefix indexes configured, the block of
|
||||
** absolute levels that corresponds to language-id iLangid and index
|
||||
** iIndex starts at absolute level ((iLangid * (nPrefix+1) + iIndex) * 1024).
|
||||
*/
|
||||
static sqlite3_int64 getAbsoluteLevel(
|
||||
Fts3Table *p,
|
||||
int iLangid,
|
||||
int iIndex,
|
||||
int iLevel
|
||||
){
|
||||
sqlite3_int64 iBase; /* First absolute level for iLangid/iIndex */
|
||||
assert( iLangid>=0 );
|
||||
assert( p->nIndex>0 );
|
||||
assert( iIndex>=0 && iIndex<p->nIndex );
|
||||
return (iLangid * p->nIndex + iIndex) * FTS3_SEGDIR_MAXLEVEL + iLevel;
|
||||
|
||||
iBase = ((sqlite3_int64)iLangid * p->nIndex + iIndex) * FTS3_SEGDIR_MAXLEVEL;
|
||||
return iBase + iLevel;
|
||||
}
|
||||
|
||||
|
||||
@ -468,7 +494,7 @@ int sqlite3Fts3AllSegdirs(
|
||||
Fts3Table *p, /* FTS3 table */
|
||||
int iLangid, /* Language being queried */
|
||||
int iIndex, /* Index for p->aIndex[] */
|
||||
int iLevel, /* Level to select */
|
||||
int iLevel, /* Level to select (relative level) */
|
||||
sqlite3_stmt **ppStmt /* OUT: Compiled statement */
|
||||
){
|
||||
int rc;
|
||||
@ -483,7 +509,7 @@ int sqlite3Fts3AllSegdirs(
|
||||
rc = fts3SqlStmt(p, SQL_SELECT_LEVEL_RANGE, &pStmt, 0);
|
||||
if( rc==SQLITE_OK ){
|
||||
sqlite3_bind_int64(pStmt, 1, getAbsoluteLevel(p, iLangid, iIndex, 0));
|
||||
sqlite3_bind_int(pStmt, 2,
|
||||
sqlite3_bind_int64(pStmt, 2,
|
||||
getAbsoluteLevel(p, iLangid, iIndex, FTS3_SEGDIR_MAXLEVEL-1)
|
||||
);
|
||||
}
|
||||
@ -491,7 +517,7 @@ int sqlite3Fts3AllSegdirs(
|
||||
/* "SELECT * FROM %_segdir WHERE level = ? ORDER BY ..." */
|
||||
rc = fts3SqlStmt(p, SQL_SELECT_LEVEL, &pStmt, 0);
|
||||
if( rc==SQLITE_OK ){
|
||||
sqlite3_bind_int(pStmt, 1, getAbsoluteLevel(p, iLangid, iIndex, iLevel));
|
||||
sqlite3_bind_int64(pStmt, 1, getAbsoluteLevel(p, iLangid, iIndex,iLevel));
|
||||
}
|
||||
}
|
||||
*ppStmt = pStmt;
|
||||
@ -1763,7 +1789,7 @@ static int fts3WriteSegment(
|
||||
*/
|
||||
static int fts3WriteSegdir(
|
||||
Fts3Table *p, /* Virtual table handle */
|
||||
int iLevel, /* Value for "level" field */
|
||||
sqlite3_int64 iLevel, /* Value for "level" field (absolute level) */
|
||||
int iIdx, /* Value for "idx" field */
|
||||
sqlite3_int64 iStartBlock, /* Value for "start_block" field */
|
||||
sqlite3_int64 iLeafEndBlock, /* Value for "leaves_end_block" field */
|
||||
@ -1774,7 +1800,7 @@ static int fts3WriteSegdir(
|
||||
sqlite3_stmt *pStmt;
|
||||
int rc = fts3SqlStmt(p, SQL_INSERT_SEGDIR, &pStmt, 0);
|
||||
if( rc==SQLITE_OK ){
|
||||
sqlite3_bind_int(pStmt, 1, iLevel);
|
||||
sqlite3_bind_int64(pStmt, 1, iLevel);
|
||||
sqlite3_bind_int(pStmt, 2, iIdx);
|
||||
sqlite3_bind_int64(pStmt, 3, iStartBlock);
|
||||
sqlite3_bind_int64(pStmt, 4, iLeafEndBlock);
|
||||
@ -2157,7 +2183,7 @@ static int fts3SegWriterAdd(
|
||||
static int fts3SegWriterFlush(
|
||||
Fts3Table *p, /* Virtual table handle */
|
||||
SegmentWriter *pWriter, /* SegmentWriter to flush to the db */
|
||||
int iLevel, /* Value for 'level' column of %_segdir */
|
||||
sqlite3_int64 iLevel, /* Value for 'level' column of %_segdir */
|
||||
int iIdx /* Value for 'idx' column of %_segdir */
|
||||
){
|
||||
int rc; /* Return code */
|
||||
@ -2239,7 +2265,7 @@ static int fts3SegmentMaxLevel(
|
||||
Fts3Table *p,
|
||||
int iLangid,
|
||||
int iIndex,
|
||||
int *pnMax
|
||||
sqlite3_int64 *pnMax
|
||||
){
|
||||
sqlite3_stmt *pStmt;
|
||||
int rc;
|
||||
@ -2253,12 +2279,12 @@ static int fts3SegmentMaxLevel(
|
||||
*/
|
||||
rc = fts3SqlStmt(p, SQL_SELECT_SEGDIR_MAX_LEVEL, &pStmt, 0);
|
||||
if( rc!=SQLITE_OK ) return rc;
|
||||
sqlite3_bind_int(pStmt, 1, getAbsoluteLevel(p, iLangid, iIndex, 0));
|
||||
sqlite3_bind_int(pStmt, 2,
|
||||
sqlite3_bind_int64(pStmt, 1, getAbsoluteLevel(p, iLangid, iIndex, 0));
|
||||
sqlite3_bind_int64(pStmt, 2,
|
||||
getAbsoluteLevel(p, iLangid, iIndex, FTS3_SEGDIR_MAXLEVEL-1)
|
||||
);
|
||||
if( SQLITE_ROW==sqlite3_step(pStmt) ){
|
||||
*pnMax = sqlite3_column_int(pStmt, 0);
|
||||
*pnMax = sqlite3_column_int64(pStmt, 0);
|
||||
}
|
||||
return sqlite3_reset(pStmt);
|
||||
}
|
||||
@ -2307,15 +2333,17 @@ static int fts3DeleteSegdir(
|
||||
if( iLevel==FTS3_SEGCURSOR_ALL ){
|
||||
rc = fts3SqlStmt(p, SQL_DELETE_SEGDIR_RANGE, &pDelete, 0);
|
||||
if( rc==SQLITE_OK ){
|
||||
sqlite3_bind_int(pDelete, 1, getAbsoluteLevel(p, iLangid, iIndex, 0));
|
||||
sqlite3_bind_int(pDelete, 2,
|
||||
sqlite3_bind_int64(pDelete, 1, getAbsoluteLevel(p, iLangid, iIndex, 0));
|
||||
sqlite3_bind_int64(pDelete, 2,
|
||||
getAbsoluteLevel(p, iLangid, iIndex, FTS3_SEGDIR_MAXLEVEL-1)
|
||||
);
|
||||
}
|
||||
}else{
|
||||
rc = fts3SqlStmt(p, SQL_DELETE_SEGDIR_LEVEL, &pDelete, 0);
|
||||
if( rc==SQLITE_OK ){
|
||||
sqlite3_bind_int(pDelete, 1, getAbsoluteLevel(p, iLangid, iIndex,iLevel));
|
||||
sqlite3_bind_int64(
|
||||
pDelete, 1, getAbsoluteLevel(p, iLangid, iIndex, iLevel)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2792,7 +2820,7 @@ static int fts3SegmentMerge(
|
||||
){
|
||||
int rc; /* Return code */
|
||||
int iIdx = 0; /* Index of new segment */
|
||||
int iNewLevel = 0; /* Level/index to create new segment at */
|
||||
sqlite3_int64 iNewLevel = 0; /* Level/index to create new segment at */
|
||||
SegmentWriter *pWriter = 0; /* Used to write the new, merged, segment */
|
||||
Fts3SegFilter filter; /* Segment term filter condition */
|
||||
Fts3MultiSegReader csr; /* Cursor to iterate through level(s) */
|
||||
|
Reference in New Issue
Block a user