Fix things so that the fts5 extension API works with "ORDER BY rank" queries.

FossilOrigin-Name: f1b4e1a98d49ecaba962beba16f8224175e4ba59
This commit is contained in:
dan
2014-07-30 20:26:24 +00:00
parent fdb4a30af2
commit 3fc4a856a2
4 changed files with 85 additions and 19 deletions
+69 -11
View File
@@ -73,7 +73,7 @@ struct Fts5MatchPhrase {
struct Fts5Sorter {
sqlite3_stmt *pStmt;
i64 iRowid; /* Current rowid */
u8 *aPoslist; /* Position lists for current row */
const u8 *aPoslist; /* Position lists for current row */
int nIdx; /* Number of entries in aIdx[] */
int aIdx[0]; /* Offsets into aPoslist for current row */
};
@@ -404,8 +404,22 @@ static int fts5SorterNext(Fts5Cursor *pCsr){
rc = SQLITE_OK;
CsrFlagSet(pCsr, FTS5CSR_EOF);
}else if( rc==SQLITE_ROW ){
const u8 *a;
const u8 *aBlob;
int nBlob;
int i;
rc = SQLITE_OK;
pSorter->iRowid = sqlite3_column_int64(pSorter->pStmt, 0);
nBlob = sqlite3_column_bytes(pSorter->pStmt, 1);
aBlob = a = sqlite3_column_blob(pSorter->pStmt, 1);
for(i=0; i<(pSorter->nIdx-1); i++){
a += getVarint32(a, pSorter->aIdx[i]);
}
pSorter->aIdx[i] = &aBlob[nBlob] - a;
pSorter->aPoslist = a;
CsrFlagSet(pCsr, FTS5CSR_REQUIRE_CONTENT | FTS5CSR_REQUIRE_DOCSIZE );
}
return rc;
@@ -467,7 +481,7 @@ static int fts5CursorFirstSorted(Fts5Table *pTab, Fts5Cursor *pCsr, int bAsc){
if( pSorter==0 ) return SQLITE_NOMEM;
memset(pSorter, 0, nByte);
zSql = sqlite3_mprintf("SELECT rowid, %Q FROM %Q.%Q ORDER BY +%s %s",
zSql = sqlite3_mprintf("SELECT rowid, %s FROM %Q.%Q ORDER BY +%s %s",
pConfig->zName, pConfig->zDb, pConfig->zName, FTS5_RANK_NAME,
bAsc ? "ASC" : "DESC"
);
@@ -571,6 +585,21 @@ static int fts5EofMethod(sqlite3_vtab_cursor *pCursor){
return (CsrFlagTest(pCsr, FTS5CSR_EOF) ? 1 : 0);
}
/*
** Return the rowid that the cursor currently points to.
*/
static i64 fts5CursorRowid(Fts5Cursor *pCsr){
assert( FTS5_PLAN(pCsr->idxNum)==FTS5_PLAN_MATCH
|| FTS5_PLAN(pCsr->idxNum)==FTS5_PLAN_SORTED_MATCH
|| FTS5_PLAN(pCsr->idxNum)==FTS5_PLAN_SOURCE
);
if( pCsr->pSorter ){
return pCsr->pSorter->iRowid;
}else{
return sqlite3Fts5ExprRowid(pCsr->pExpr);
}
}
/*
** This is the xRowid method. The SQLite core calls this routine to
** retrieve the rowid for the current row of the result set. fts5
@@ -585,11 +614,8 @@ static int fts5RowidMethod(sqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid){
switch( ePlan ){
case FTS5_PLAN_SOURCE:
case FTS5_PLAN_MATCH:
*pRowid = sqlite3Fts5ExprRowid(pCsr->pExpr);
break;
case FTS5_PLAN_SORTED_MATCH:
*pRowid = pCsr->pSorter->iRowid;
*pRowid = fts5CursorRowid(pCsr);
break;
default:
@@ -609,7 +635,7 @@ static int fts5SeekCursor(Fts5Cursor *pCsr){
if( CsrFlagTest(pCsr, FTS5CSR_REQUIRE_CONTENT) ){
assert( pCsr->pExpr );
sqlite3_reset(pCsr->pStmt);
sqlite3_bind_int64(pCsr->pStmt, 1, sqlite3Fts5ExprRowid(pCsr->pExpr));
sqlite3_bind_int64(pCsr->pStmt, 1, fts5CursorRowid(pCsr));
rc = sqlite3_step(pCsr->pStmt);
if( rc==SQLITE_ROW ){
rc = SQLITE_OK;
@@ -786,7 +812,7 @@ static int fts5ApiPhraseSize(Fts5Context *pCtx, int iPhrase){
static sqlite3_int64 fts5ApiRowid(Fts5Context *pCtx){
Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
return sqlite3Fts5ExprRowid(pCsr->pExpr);
return fts5CursorRowid((Fts5Cursor*)pCtx);
}
static int fts5ApiColumnText(
@@ -810,7 +836,7 @@ static int fts5ApiColumnSize(Fts5Context *pCtx, int iCol, int *pnToken){
int rc = SQLITE_OK;
if( CsrFlagTest(pCsr, FTS5CSR_REQUIRE_DOCSIZE) ){
i64 iRowid = sqlite3Fts5ExprRowid(pCsr->pExpr);
i64 iRowid = fts5CursorRowid(pCsr);
rc = sqlite3Fts5StorageDocsize(pTab->pStorage, iRowid, pCsr->aColumnSize);
}
if( iCol>=0 && iCol<pTab->pConfig->nCol ){
@@ -829,7 +855,14 @@ static int fts5ApiPoslist(
){
Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
const u8 *a; int n; /* Poslist for phrase iPhrase */
n = sqlite3Fts5ExprPoslist(pCsr->pExpr, iPhrase, &a);
if( pCsr->pSorter ){
Fts5Sorter *pSorter = pCsr->pSorter;
int i1 = (iPhrase ? 0 : pSorter->aIdx[iPhrase-1]);
n = pSorter->aIdx[iPhrase] - i1;
a = &pSorter->aPoslist[i1];
}else{
n = sqlite3Fts5ExprPoslist(pCsr->pExpr, iPhrase, &a);
}
return sqlite3Fts5PoslistNext64(a, n, pi, piPos);
}
@@ -983,6 +1016,31 @@ static void fts5ApiCallback(
}
}
static int fts5PoslistBlob(sqlite3_context *pCtx, Fts5Cursor *pCsr){
int i;
int rc = SQLITE_OK;
int nPhrase = sqlite3Fts5ExprPhraseCount(pCsr->pExpr);
Fts5Buffer val;
int iOff = 0;
memset(&val, 0, sizeof(Fts5Buffer));
for(i=0; i<nPhrase; i++){
const u8 *dummy;
if( i ) sqlite3Fts5BufferAppendVarint(&rc, &val, iOff);
iOff += sqlite3Fts5ExprPoslist(pCsr->pExpr, i, &dummy);
}
for(i=0; i<nPhrase; i++){
const u8 *pPoslist;
int nPoslist;
nPoslist = sqlite3Fts5ExprPoslist(pCsr->pExpr, i, &pPoslist);
sqlite3Fts5BufferAppendBlob(&rc, &val, nPoslist, pPoslist);
}
sqlite3_result_blob(pCtx, val.p, val.n, sqlite3_free);
return rc;
}
/*
** This is the xColumn method, called by SQLite to request a value from
** the row that the supplied cursor currently points to.
@@ -1000,7 +1058,7 @@ static int fts5ColumnMethod(
if( iCol==pConfig->nCol ){
if( FTS5_PLAN(pCsr->idxNum)==FTS5_PLAN_SOURCE ){
/* todo */
fts5PoslistBlob(pCtx, pCsr);
}else{
/* User is requesting the value of the special column with the same name
** as the table. Return the cursor integer id number. This value is only
+7 -7
View File
@@ -1,5 +1,5 @@
C Add\shidden\scolumn\s"rank".\sCurrently\sthis\salways\sreturns\sthe\ssame\svalue\sas\sthe\sbm25()\sfunction.
D 2014-07-30T19:41:58.841
C Fix\sthings\sso\sthat\sthe\sfts5\sextension\sAPI\sworks\swith\s"ORDER\sBY\srank"\squeries.
D 2014-07-30T20:26:24.443
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in b03432313a3aad96c706f8164fb9f5307eaf19f5
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -103,7 +103,7 @@ F ext/fts3/tool/fts3view.c 6cfc5b67a5f0e09c0d698f9fd012c784bfaa9197
F ext/fts3/unicode/CaseFolding.txt 8c678ca52ecc95e16bc7afc2dbf6fc9ffa05db8c
F ext/fts3/unicode/UnicodeData.txt cd07314edb62d49fde34debdaf92fa2aa69011e7
F ext/fts3/unicode/mkunicode.tcl dc6f268eb526710e2c6e496c372471d773d0c368
F ext/fts5/fts5.c f786dd1a3d091f7cb6572f6ee95f10f09de52224
F ext/fts5/fts5.c f322286c6a37dcea4b46b00677e9aad2e59abe9d
F ext/fts5/fts5.h 8ace10d5b249a3baa983c79e7a1306d2a79cfd6a
F ext/fts5/fts5Int.h 9a195c1706876c538902f007149b39e982e9da53
F ext/fts5/fts5_aux.c 3cae4225d458af41b64bb40ed9dcc052eb41b9a0
@@ -600,7 +600,7 @@ F test/fts5ab.test dc04ed48cf93ca957d174406e6c192f2ff4f3397
F test/fts5ac.test 9be418d037763f4cc5d86f4239db41fc86bb4f85
F test/fts5ad.test 2ed38bbc865678cb2905247120d02ebba7f20e07
F test/fts5ae.test cb37b3135a00d3afd5492ec534ecf654be5ff69e
F test/fts5af.test 5f53d0a52280b63caf5a519d6994c4d428835155
F test/fts5af.test 9ebe23aa3875896076952c7bc6e8308813a63c74
F test/fts5ea.test ff43b40f8879ba50b82def70f2ab67c195d1a1d4
F test/full.test 6b3c8fb43c6beab6b95438c1675374b95fab245d
F test/func.test ae97561957aba6ca9e3a7b8a13aac41830d701ef
@@ -1197,7 +1197,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 770b9540c19ad1e3d24adff382332bf032065efd
R b6911e3c357a5fea00c97182f6d0088b
P 4cc048c3651e830a6aeded924c7f3a60b634e133
R e80b35a7b7fca0c8edda241edc415407
U dan
Z 526c63f1e91d68c01d64fde27fedef0b
Z fdc04c3e2e7e600dae907e07830ae6e8
+1 -1
View File
@@ -1 +1 @@
4cc048c3651e830a6aeded924c7f3a60b634e133
f1b4e1a98d49ecaba962beba16f8224175e4ba59
+8
View File
@@ -47,6 +47,14 @@ proc do_snippet_test {tn doc match res} {
SELECT snippet(t1, '[', ']', '...', 7) FROM t1 WHERE t1 MATCH $v2;
} [list $res]
do_execsql_test $tn.3 {
DELETE FROM t1;
INSERT INTO t1 VALUES($v1, NULL);
SELECT snippet(t1, '[', ']', '...', 7) FROM t1 WHERE t1 MATCH $v2
ORDER BY rank DESC;
} [list $res]
}