mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-29 08:01:23 +03:00
Fix the xColumnSize() extension API.
FossilOrigin-Name: 19504c4108472d2ad1281221642b8bd06eb69f4e
This commit is contained in:
@ -619,8 +619,9 @@ static int fts5ApiColumnCount(Fts5Context *pCtx){
|
||||
}
|
||||
|
||||
static int fts5ApiColumnAvgSize(Fts5Context *pCtx, int iCol, int *pnToken){
|
||||
assert( 0 );
|
||||
return 0;
|
||||
Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
|
||||
Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab);
|
||||
return sqlite3Fts5StorageAvgsize(pTab->pStorage, iCol, pnToken);
|
||||
}
|
||||
|
||||
static int fts5ApiTokenize(
|
||||
|
@ -267,6 +267,9 @@ int sqlite3Fts5IndexInit(sqlite3*);
|
||||
|
||||
void sqlite3Fts5IndexPgsz(Fts5Index *p, int pgsz);
|
||||
|
||||
int sqlite3Fts5IndexGetAverages(Fts5Index *p, Fts5Buffer *pBuf);
|
||||
int sqlite3Fts5IndexSetAverages(Fts5Index *p, const u8*, int);
|
||||
|
||||
/*
|
||||
** End of interface to code in fts5_index.c.
|
||||
**************************************************************************/
|
||||
@ -297,7 +300,7 @@ int sqlite3Fts5StorageStmt(Fts5Storage *p, int eStmt, sqlite3_stmt **);
|
||||
void sqlite3Fts5StorageStmtRelease(Fts5Storage *p, int eStmt, sqlite3_stmt*);
|
||||
|
||||
int sqlite3Fts5StorageDocsize(Fts5Storage *p, i64 iRowid, int *aCol);
|
||||
int sqlite3Fts5StorageAvgsize(Fts5Storage *p, int *aCol);
|
||||
int sqlite3Fts5StorageAvgsize(Fts5Storage *p, int iCol, int *pnAvg);
|
||||
|
||||
|
||||
/*
|
||||
|
@ -43,11 +43,24 @@ static void fts5TestFunction(
|
||||
}
|
||||
|
||||
memset(&s, 0, sizeof(Fts5Buffer));
|
||||
nCol = pApi->xColumnCount(pFts);
|
||||
|
||||
if( zReq==0 ){
|
||||
sqlite3Fts5BufferAppendPrintf(&rc, &s, "columnavgsize ");
|
||||
}
|
||||
if( 0==zReq || 0==sqlite3_stricmp(zReq, "columnavgsize") ){
|
||||
if( zReq==0 && nCol>1 ) sqlite3Fts5BufferAppendPrintf(&rc, &s, "{");
|
||||
for(i=0; rc==SQLITE_OK && i<nCol; i++){
|
||||
int colsz = 0;
|
||||
rc = pApi->xColumnAvgSize(pFts, i, &colsz);
|
||||
sqlite3Fts5BufferAppendPrintf(&rc, &s, "%s%d", i==0?"":" ", colsz);
|
||||
}
|
||||
if( zReq==0 && nCol>1 ) sqlite3Fts5BufferAppendPrintf(&rc, &s, "}");
|
||||
}
|
||||
|
||||
if( zReq==0 ){
|
||||
sqlite3Fts5BufferAppendPrintf(&rc, &s, "columncount ");
|
||||
}
|
||||
nCol = pApi->xColumnCount(pFts);
|
||||
if( 0==zReq || 0==sqlite3_stricmp(zReq, "columncount") ){
|
||||
sqlite3Fts5BufferAppendPrintf(&rc, &s, "%d", nCol);
|
||||
}
|
||||
|
@ -734,7 +734,7 @@ static void fts5DataReference(Fts5Data *pData){
|
||||
/*
|
||||
** INSERT OR REPLACE a record into the %_data table.
|
||||
*/
|
||||
static void fts5DataWrite(Fts5Index *p, i64 iRowid, u8 *pData, int nData){
|
||||
static void fts5DataWrite(Fts5Index *p, i64 iRowid, const u8 *pData, int nData){
|
||||
if( p->rc!=SQLITE_OK ) return;
|
||||
|
||||
if( p->pWriter==0 ){
|
||||
@ -2734,6 +2734,7 @@ int sqlite3Fts5IndexOpen(
|
||||
}
|
||||
rc = p->rc;
|
||||
}
|
||||
sqlite3Fts5IndexSetAverages(p, (const u8*)"", 0);
|
||||
}
|
||||
|
||||
if( rc ){
|
||||
@ -3619,3 +3620,22 @@ void sqlite3Fts5IterClose(Fts5IndexIter *pIter){
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Read the "averages" record into the buffer supplied as the second
|
||||
** argument. Return SQLITE_OK if successful, or an SQLite error code
|
||||
** if an error occurs.
|
||||
*/
|
||||
int sqlite3Fts5IndexGetAverages(Fts5Index *p, Fts5Buffer *pBuf){
|
||||
fts5DataReadOrBuffer(p, pBuf, FTS5_AVERAGES_ROWID);
|
||||
return p->rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** Replace the current "averages" record with the contents of the buffer
|
||||
** supplied as the second argument.
|
||||
*/
|
||||
int sqlite3Fts5IndexSetAverages(Fts5Index *p, const u8 *pData, int nData){
|
||||
fts5DataWrite(p, FTS5_AVERAGES_ROWID, pData, nData);
|
||||
return p->rc;
|
||||
}
|
||||
|
||||
|
@ -17,6 +17,8 @@
|
||||
struct Fts5Storage {
|
||||
Fts5Config *pConfig;
|
||||
Fts5Index *pIndex;
|
||||
i64 nTotalRow; /* Total number of rows in FTS table */
|
||||
i64 *aTotalSize; /* Total sizes of each column */
|
||||
sqlite3_stmt *aStmt[9];
|
||||
};
|
||||
|
||||
@ -168,11 +170,15 @@ int sqlite3Fts5StorageOpen(
|
||||
){
|
||||
int rc;
|
||||
Fts5Storage *p; /* New object */
|
||||
int nByte; /* Bytes of space to allocate */
|
||||
|
||||
*pp = p = (Fts5Storage*)sqlite3_malloc(sizeof(Fts5Storage));
|
||||
nByte = sizeof(Fts5Storage) /* Fts5Storage object */
|
||||
+ pConfig->nCol * sizeof(i64); /* Fts5Storage.aTotalSize[] */
|
||||
*pp = p = (Fts5Storage*)sqlite3_malloc(nByte);
|
||||
if( !p ) return SQLITE_NOMEM;
|
||||
|
||||
memset(p, 0, sizeof(Fts5Storage));
|
||||
memset(p, 0, nByte);
|
||||
p->aTotalSize = (i64*)&p[1];
|
||||
p->pConfig = pConfig;
|
||||
p->pIndex = pIndex;
|
||||
|
||||
@ -285,7 +291,9 @@ static int fts5StorageDeleteFromIndex(Fts5Storage *p, i64 iDel){
|
||||
(void*)&ctx,
|
||||
fts5StorageInsertCallback
|
||||
);
|
||||
p->aTotalSize[iCol-1] -= (i64)ctx.szCol;
|
||||
}
|
||||
p->nTotalRow--;
|
||||
}
|
||||
rc2 = sqlite3_reset(pSeek);
|
||||
if( rc==SQLITE_OK ) rc = rc2;
|
||||
@ -315,6 +323,62 @@ static int fts5StorageInsertDocsize(
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** Load the contents of the "averages" record from disk into the
|
||||
** p->nTotalRow and p->aTotalSize[] variables.
|
||||
**
|
||||
** Return SQLITE_OK if successful, or an SQLite error code if an error
|
||||
** occurs.
|
||||
*/
|
||||
static int fts5StorageLoadTotals(Fts5Storage *p){
|
||||
int nCol = p->pConfig->nCol;
|
||||
Fts5Buffer buf;
|
||||
int rc;
|
||||
memset(&buf, 0, sizeof(buf));
|
||||
|
||||
memset(p->aTotalSize, 0, sizeof(i64) * nCol);
|
||||
p->nTotalRow = 0;
|
||||
rc = sqlite3Fts5IndexGetAverages(p->pIndex, &buf);
|
||||
if( rc==SQLITE_OK && buf.n ){
|
||||
int i = 0;
|
||||
int iCol;
|
||||
i += getVarint(&buf.p[i], (u64*)&p->nTotalRow);
|
||||
for(iCol=0; i<buf.n && iCol<nCol; iCol++){
|
||||
i += getVarint(&buf.p[i], (u64*)&p->aTotalSize[iCol]);
|
||||
}
|
||||
}
|
||||
sqlite3_free(buf.p);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** Store the current contents of the p->nTotalRow and p->aTotalSize[]
|
||||
** variables in the "averages" record on disk.
|
||||
**
|
||||
** Return SQLITE_OK if successful, or an SQLite error code if an error
|
||||
** occurs.
|
||||
*/
|
||||
static int fts5StorageSaveTotals(Fts5Storage *p){
|
||||
int nCol = p->pConfig->nCol;
|
||||
int i;
|
||||
Fts5Buffer buf;
|
||||
int rc = SQLITE_OK;
|
||||
memset(&buf, 0, sizeof(buf));
|
||||
|
||||
sqlite3Fts5BufferAppendVarint(&rc, &buf, p->nTotalRow);
|
||||
for(i=0; i<nCol; i++){
|
||||
sqlite3Fts5BufferAppendVarint(&rc, &buf, p->aTotalSize[i]);
|
||||
}
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sqlite3Fts5IndexSetAverages(p->pIndex, buf.p, buf.n);
|
||||
}
|
||||
sqlite3_free(buf.p);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
** Insert a new row into the FTS table.
|
||||
*/
|
||||
@ -333,15 +397,18 @@ int sqlite3Fts5StorageInsert(
|
||||
Fts5Buffer buf; /* Buffer used to build up %_docsize blob */
|
||||
|
||||
memset(&buf, 0, sizeof(Fts5Buffer));
|
||||
rc = fts5StorageLoadTotals(p);
|
||||
|
||||
/* Insert the new row into the %_content table. */
|
||||
if( eConflict==SQLITE_REPLACE ){
|
||||
eStmt = FTS5_STMT_REPLACE_CONTENT;
|
||||
if( sqlite3_value_type(apVal[1])==SQLITE_INTEGER ){
|
||||
rc = fts5StorageDeleteFromIndex(p, sqlite3_value_int64(apVal[1]));
|
||||
if( rc==SQLITE_OK ){
|
||||
if( eConflict==SQLITE_REPLACE ){
|
||||
eStmt = FTS5_STMT_REPLACE_CONTENT;
|
||||
if( sqlite3_value_type(apVal[1])==SQLITE_INTEGER ){
|
||||
rc = fts5StorageDeleteFromIndex(p, sqlite3_value_int64(apVal[1]));
|
||||
}
|
||||
}else{
|
||||
eStmt = FTS5_STMT_INSERT_CONTENT;
|
||||
}
|
||||
}else{
|
||||
eStmt = FTS5_STMT_INSERT_CONTENT;
|
||||
}
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = fts5StorageGetStmt(p, eStmt, &pInsert);
|
||||
@ -367,7 +434,9 @@ int sqlite3Fts5StorageInsert(
|
||||
fts5StorageInsertCallback
|
||||
);
|
||||
sqlite3Fts5BufferAppendVarint(&rc, &buf, ctx.szCol);
|
||||
p->aTotalSize[ctx.iCol] += (i64)ctx.szCol;
|
||||
}
|
||||
p->nTotalRow++;
|
||||
|
||||
/* Write the %_docsize record */
|
||||
if( rc==SQLITE_OK ){
|
||||
@ -375,6 +444,11 @@ int sqlite3Fts5StorageInsert(
|
||||
}
|
||||
sqlite3_free(buf.p);
|
||||
|
||||
/* Write the averages record */
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = fts5StorageSaveTotals(p);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
@ -538,7 +612,16 @@ int sqlite3Fts5StorageDocsize(Fts5Storage *p, i64 iRowid, int *aCol){
|
||||
return rc;
|
||||
}
|
||||
|
||||
int sqlite3Fts5StorageAvgsize(Fts5Storage *p, int *aCol){
|
||||
return 0;
|
||||
int sqlite3Fts5StorageAvgsize(Fts5Storage *p, int iCol, int *pnAvg){
|
||||
int rc = fts5StorageLoadTotals(p);
|
||||
if( rc==SQLITE_OK ){
|
||||
int nAvg = 1;
|
||||
if( p->nTotalRow ){
|
||||
nAvg = (int)((p->aTotalSize[iCol] + (p->nTotalRow/2)) / p->nTotalRow);
|
||||
if( nAvg<1 ) nAvg = 1;
|
||||
*pnAvg = nAvg;
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user