Fix things so that the fts5 extension API works with "ORDER BY rank" queries.
FossilOrigin-Name: f1b4e1a98d49ecaba962beba16f8224175e4ba59
This commit is contained in:
+69
-11
@@ -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
|
||||
|
||||
@@ -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
@@ -1 +1 @@
|
||||
4cc048c3651e830a6aeded924c7f3a60b634e133
|
||||
f1b4e1a98d49ecaba962beba16f8224175e4ba59
|
||||
@@ -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]
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user