aboutsummaryrefslogtreecommitdiff
path: root/ext/fts3/fts3_snippet.c
diff options
context:
space:
mode:
authordan <dan@noemail.net>2015-05-04 12:29:50 +0000
committerdan <dan@noemail.net>2015-05-04 12:29:50 +0000
commitc722cf7d03ff6784f9ba4c8fadd6bf0621812238 (patch)
treef0aa1666c2f84f59d6371453fed1ef64d1a400a2 /ext/fts3/fts3_snippet.c
parent1a57c17d0f818fadfce2fc592bc33d9cdf050fed (diff)
parent28f98455f436c8efc6b6d9eccc1b78f6ea97a991 (diff)
downloadsqlite-c722cf7d03ff6784f9ba4c8fadd6bf0621812238.tar.gz
sqlite-c722cf7d03ff6784f9ba4c8fadd6bf0621812238.zip
Add the 'y' flag to the fts3/4 matchinfo() function.
FossilOrigin-Name: aef1e8f47123e2e865432a0abf194dea4f23447a
Diffstat (limited to 'ext/fts3/fts3_snippet.c')
-rw-r--r--ext/fts3/fts3_snippet.c55
1 files changed, 55 insertions, 0 deletions
diff --git a/ext/fts3/fts3_snippet.c b/ext/fts3/fts3_snippet.c
index 84f0079fb..6abb169eb 100644
--- a/ext/fts3/fts3_snippet.c
+++ b/ext/fts3/fts3_snippet.c
@@ -27,6 +27,7 @@
#define FTS3_MATCHINFO_LENGTH 'l' /* nCol values */
#define FTS3_MATCHINFO_LCS 's' /* nCol values */
#define FTS3_MATCHINFO_HITS 'x' /* 3*nCol*nPhrase values */
+#define FTS3_MATCHINFO_LHITS 'y' /* nCol*nPhrase values */
/*
** The default value for the second argument to matchinfo().
@@ -809,6 +810,51 @@ static int fts3ExprLocalHitsCb(
return rc;
}
+/*
+** fts3ExprIterate() callback used to gather information for the matchinfo
+** directive 'y'.
+*/
+static int fts3ExprLHitsCb(
+ Fts3Expr *pExpr, /* Phrase expression node */
+ int iPhrase, /* Phrase number */
+ void *pCtx /* Pointer to MatchInfo structure */
+){
+ MatchInfo *p = (MatchInfo *)pCtx;
+ Fts3Table *pTab = (Fts3Table *)p->pCursor->base.pVtab;
+ int rc = SQLITE_OK;
+ int iStart = iPhrase * p->nCol;
+ Fts3Expr *pEof; /* Ancestor node already at EOF */
+
+ /* This must be a phrase */
+ assert( pExpr->pPhrase );
+
+ /* Initialize all output integers to zero. */
+ memset(&p->aMatchinfo[iStart], 0, sizeof(u32) * p->nCol);
+
+ /* Check if this or any parent node is at EOF. If so, then all output
+ ** values are zero. */
+ for(pEof=pExpr; pEof && pEof->bEof==0; pEof=pEof->pParent);
+
+ if( pEof==0 && pExpr->iDocid==p->pCursor->iPrevId ){
+ Fts3Phrase *pPhrase = pExpr->pPhrase;
+ char *pIter = pPhrase->doclist.pList;
+ int iCol = 0;
+
+ while( 1 ){
+ int nHit = fts3ColumnlistCount(&pIter);
+ if( (pPhrase->iColumn>=pTab->nColumn || pPhrase->iColumn==iCol) ){
+ p->aMatchinfo[iStart + iCol] = (u32)nHit;
+ }
+ assert( *pIter==0x00 || *pIter==0x01 );
+ if( *pIter!=0x01 ) break;
+ pIter++;
+ pIter += fts3GetVarint32(pIter, &iCol);
+ }
+ }
+
+ return rc;
+}
+
static int fts3MatchinfoCheck(
Fts3Table *pTab,
char cArg,
@@ -821,6 +867,7 @@ static int fts3MatchinfoCheck(
|| (cArg==FTS3_MATCHINFO_LENGTH && pTab->bHasDocsize)
|| (cArg==FTS3_MATCHINFO_LCS)
|| (cArg==FTS3_MATCHINFO_HITS)
+ || (cArg==FTS3_MATCHINFO_LHITS)
){
return SQLITE_OK;
}
@@ -844,6 +891,10 @@ static int fts3MatchinfoSize(MatchInfo *pInfo, char cArg){
nVal = pInfo->nCol;
break;
+ case FTS3_MATCHINFO_LHITS:
+ nVal = pInfo->nCol * pInfo->nPhrase;
+ break;
+
default:
assert( cArg==FTS3_MATCHINFO_HITS );
nVal = pInfo->nCol * pInfo->nPhrase * 3;
@@ -1098,6 +1149,10 @@ static int fts3MatchinfoValues(
}
break;
+ case FTS3_MATCHINFO_LHITS:
+ (void)fts3ExprIterate(pCsr->pExpr, fts3ExprLHitsCb, (void*)pInfo);
+ break;
+
default: {
Fts3Expr *pExpr;
assert( zArg[i]==FTS3_MATCHINFO_HITS );