1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-07-30 19:03:16 +03:00

Add tests for the matchinfo-like test function. Fix problems found in test and fts5 code by doing so.

FossilOrigin-Name: 9e3aafe44a0813aa2a0c6172fdba1440b8a973ec
This commit is contained in:
dan
2015-08-05 19:35:59 +00:00
parent b20a42e316
commit 50b5491771
9 changed files with 594 additions and 61 deletions

View File

@ -169,6 +169,11 @@ struct Fts5Sorter {
*/
struct Fts5Cursor {
sqlite3_vtab_cursor base; /* Base class used by SQLite core */
Fts5Cursor *pNext; /* Next cursor in Fts5Cursor.pCsr list */
int *aColumnSize; /* Values for xColumnSize() */
i64 iCsrId; /* Cursor id */
/* Zero from this point onwards on cursor reset */
int ePlan; /* FTS5_PLAN_XXX value */
int bDesc; /* True for "ORDER BY rowid DESC" queries */
i64 iFirstRowid; /* Return no rowids earlier than this */
@ -177,7 +182,6 @@ struct Fts5Cursor {
Fts5Expr *pExpr; /* Expression for MATCH queries */
Fts5Sorter *pSorter; /* Sorter for "ORDER BY rank" queries */
int csrflags; /* Mask of cursor flags (see below) */
Fts5Cursor *pNext; /* Next cursor in Fts5Cursor.pCsr list */
i64 iSpecial; /* Result of special query */
/* "rank" function. Populated on demand from vtab.xColumn(). */
@ -188,11 +192,9 @@ struct Fts5Cursor {
sqlite3_value **apRankArg; /* Array of trailing arguments */
sqlite3_stmt *pRankArgStmt; /* Origin of objects in apRankArg[] */
/* Variables used by auxiliary functions */
i64 iCsrId; /* Cursor id */
/* Auxiliary data storage */
Fts5Auxiliary *pAux; /* Currently executing extension function */
Fts5Auxdata *pAuxdata; /* First in linked list of saved aux-data */
int *aColumnSize; /* Values for xColumnSize() */
/* Cache used by auxiliary functions xInst() and xInstCount() */
int nInstCount; /* Number of phrase instances */
@ -429,12 +431,12 @@ static int fts5CreateMethod(
/*
** The different query plans.
*/
#define FTS5_PLAN_MATCH 0 /* (<tbl> MATCH ?) */
#define FTS5_PLAN_SOURCE 1 /* A source cursor for SORTED_MATCH */
#define FTS5_PLAN_SPECIAL 2 /* An internal query */
#define FTS5_PLAN_SORTED_MATCH 3 /* (<tbl> MATCH ? ORDER BY rank) */
#define FTS5_PLAN_SCAN 4 /* No usable constraint */
#define FTS5_PLAN_ROWID 5 /* (rowid = ?) */
#define FTS5_PLAN_MATCH 1 /* (<tbl> MATCH ?) */
#define FTS5_PLAN_SOURCE 2 /* A source cursor for SORTED_MATCH */
#define FTS5_PLAN_SPECIAL 3 /* An internal query */
#define FTS5_PLAN_SORTED_MATCH 4 /* (<tbl> MATCH ? ORDER BY rank) */
#define FTS5_PLAN_SCAN 5 /* No usable constraint */
#define FTS5_PLAN_ROWID 6 /* (rowid = ?) */
/*
** Implementation of the xBestIndex method for FTS5 tables. Within the
@ -610,6 +612,44 @@ static void fts5CsrNewrow(Fts5Cursor *pCsr){
);
}
static void fts5FreeCursorComponents(Fts5Cursor *pCsr){
Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab);
Fts5Auxdata *pData;
Fts5Auxdata *pNext;
sqlite3_free(pCsr->aInst);
if( pCsr->pStmt ){
int eStmt = fts5StmtType(pCsr);
sqlite3Fts5StorageStmtRelease(pTab->pStorage, eStmt, pCsr->pStmt);
}
if( pCsr->pSorter ){
Fts5Sorter *pSorter = pCsr->pSorter;
sqlite3_finalize(pSorter->pStmt);
sqlite3_free(pSorter);
}
if( pCsr->ePlan!=FTS5_PLAN_SOURCE ){
sqlite3Fts5ExprFree(pCsr->pExpr);
}
for(pData=pCsr->pAuxdata; pData; pData=pNext){
pNext = pData->pNext;
if( pData->xDelete ) pData->xDelete(pData->pPtr);
sqlite3_free(pData);
}
sqlite3_finalize(pCsr->pRankArgStmt);
sqlite3_free(pCsr->apRankArg);
if( CsrFlagTest(pCsr, FTS5CSR_FREE_ZRANK) ){
sqlite3_free(pCsr->zRank);
sqlite3_free(pCsr->zRankArgs);
}
memset(&pCsr->ePlan, 0, sizeof(Fts5Cursor) - ((u8*)&pCsr->ePlan - (u8*)pCsr));
}
/*
** Close the cursor. For additional information see the documentation
** on the xClose method of the virtual table interface.
@ -619,41 +659,12 @@ static int fts5CloseMethod(sqlite3_vtab_cursor *pCursor){
Fts5Table *pTab = (Fts5Table*)(pCursor->pVtab);
Fts5Cursor *pCsr = (Fts5Cursor*)pCursor;
Fts5Cursor **pp;
Fts5Auxdata *pData;
Fts5Auxdata *pNext;
sqlite3_free(pCsr->aInst);
if( pCsr->pStmt ){
int eStmt = fts5StmtType(pCsr);
sqlite3Fts5StorageStmtRelease(pTab->pStorage, eStmt, pCsr->pStmt);
}
if( pCsr->pSorter ){
Fts5Sorter *pSorter = pCsr->pSorter;
sqlite3_finalize(pSorter->pStmt);
sqlite3_free(pSorter);
}
if( pCsr->ePlan!=FTS5_PLAN_SOURCE ){
sqlite3Fts5ExprFree(pCsr->pExpr);
}
for(pData=pCsr->pAuxdata; pData; pData=pNext){
pNext = pData->pNext;
if( pData->xDelete ) pData->xDelete(pData->pPtr);
sqlite3_free(pData);
}
fts5FreeCursorComponents(pCsr);
/* Remove the cursor from the Fts5Global.pCsr list */
for(pp=&pTab->pGlobal->pCsr; (*pp)!=pCsr; pp=&(*pp)->pNext);
*pp = pCsr->pNext;
sqlite3_finalize(pCsr->pRankArgStmt);
sqlite3_free(pCsr->apRankArg);
if( CsrFlagTest(pCsr, FTS5CSR_FREE_ZRANK) ){
sqlite3_free(pCsr->zRank);
sqlite3_free(pCsr->zRankArgs);
}
sqlite3_free(pCsr);
}
return SQLITE_OK;
@ -757,11 +768,11 @@ static int fts5NextMethod(sqlite3_vtab_cursor *pCursor){
Fts5Cursor *pCsr = (Fts5Cursor*)pCursor;
int rc = SQLITE_OK;
assert( (pCsr->ePlan<2)==
assert( (pCsr->ePlan<3)==
(pCsr->ePlan==FTS5_PLAN_MATCH || pCsr->ePlan==FTS5_PLAN_SOURCE)
);
if( pCsr->ePlan<2 ){
if( pCsr->ePlan<3 ){
int bSkip = 0;
if( (rc = fts5CursorReseek(pCsr, &bSkip)) || bSkip ) return rc;
rc = sqlite3Fts5ExprNext(pCsr->pExpr, pCsr->iLastRowid);
@ -1042,6 +1053,11 @@ static int fts5FilterMethod(
sqlite3_value *pRowidGe = 0; /* rowid >= ? expression (or NULL) */
char **pzErrmsg = pConfig->pzErrmsg;
if( pCsr->ePlan ){
fts5FreeCursorComponents(pCsr);
memset(&pCsr->ePlan, 0, sizeof(Fts5Cursor) - ((u8*)&pCsr->ePlan-(u8*)pCsr));
}
assert( pCsr->pStmt==0 );
assert( pCsr->pExpr==0 );
assert( pCsr->csrflags==0 );