From: dan Date: Tue, 23 Nov 2010 19:16:47 +0000 (+0000) Subject: Experimental changes to fts3 function matchinfo(). X-Git-Tag: version-3.7.4~36^2~7 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=1e66e40eb9ba66f8e1e7fd932964682f30f11238;p=thirdparty%2Fsqlite.git Experimental changes to fts3 function matchinfo(). FossilOrigin-Name: 9cf0f2b76bc68c168e3fa861b7235f384db21d38 --- diff --git a/ext/fts3/fts3.c b/ext/fts3/fts3.c index 5618934695..29a577bcd0 100644 --- a/ext/fts3/fts3.c +++ b/ext/fts3/fts3.c @@ -3273,9 +3273,10 @@ static void fts3MatchinfoFunc( sqlite3_value **apVal /* Array of arguments */ ){ Fts3Cursor *pCsr; /* Cursor handle passed through apVal[0] */ - assert( nVal==1 ); + assert( nVal==1 || nVal==2 ); if( SQLITE_OK==fts3FunctionArg(pContext, "matchinfo", apVal[0], &pCsr) ){ - sqlite3Fts3Matchinfo(pContext, pCsr); + const char *zArg = (nVal>1 ? sqlite3_value_text(apVal[1]) : 0); + sqlite3Fts3Matchinfo(pContext, pCsr, zArg); } } @@ -3464,6 +3465,7 @@ int sqlite3Fts3Init(sqlite3 *db){ && SQLITE_OK==(rc = sqlite3_overload_function(db, "snippet", -1)) && SQLITE_OK==(rc = sqlite3_overload_function(db, "offsets", 1)) && SQLITE_OK==(rc = sqlite3_overload_function(db, "matchinfo", 1)) + && SQLITE_OK==(rc = sqlite3_overload_function(db, "matchinfo", 2)) && SQLITE_OK==(rc = sqlite3_overload_function(db, "optimize", 1)) ){ rc = sqlite3_create_module_v2( diff --git a/ext/fts3/fts3Int.h b/ext/fts3/fts3Int.h index 8ad560e316..e561663dff 100644 --- a/ext/fts3/fts3Int.h +++ b/ext/fts3/fts3Int.h @@ -162,15 +162,19 @@ struct Fts3Cursor { u8 isRequireSeek; /* True if must seek pStmt to %_content row */ sqlite3_stmt *pStmt; /* Prepared statement in use by the cursor */ Fts3Expr *pExpr; /* Parsed MATCH query string */ + int nPhrase; /* Number of matchable phrases in query */ Fts3DeferredToken *pDeferred; /* Deferred search tokens, if any */ sqlite3_int64 iPrevId; /* Previous id read from aDoclist */ char *pNextId; /* Pointer into the body of aDoclist */ char *aDoclist; /* List of docids for full-text queries */ int nDoclist; /* Size of buffer at aDoclist */ - int isMatchinfoNeeded; /* True when aMatchinfo[] needs filling in */ - u32 *aMatchinfo; /* Information about most recent match */ int eEvalmode; /* An FTS3_EVAL_XX constant */ int nRowAvg; /* Average size of database rows, in pages */ + + int isMatchinfoNeeded; /* True when aMatchinfo[] needs filling in */ + u32 *aMatchinfo; /* Information about most recent match */ + int nMatchinfo; /* Number of elements in aMatchinfo[] */ + char *zMatchinfo; /* Matchinfo specification */ }; #define FTS3_EVAL_FILTER 0 @@ -292,6 +296,9 @@ int sqlite3Fts3MatchinfoDocsizeGlobal(Fts3Cursor*, u32*); int sqlite3Fts3ReadLock(Fts3Table *); int sqlite3Fts3ReadBlock(Fts3Table*, sqlite3_int64, char **, int*); +int sqlite3Fts3SelectDoctotal(Fts3Table *, sqlite3_stmt **); +int sqlite3Fts3SelectDocsize(Fts3Table *, sqlite3_int64, sqlite3_stmt **); + void sqlite3Fts3FreeDeferredTokens(Fts3Cursor *); int sqlite3Fts3DeferToken(Fts3Cursor *, Fts3PhraseToken *, int); int sqlite3Fts3CacheDeferredDoclists(Fts3Cursor *); @@ -339,7 +346,7 @@ void sqlite3Fts3Offsets(sqlite3_context*, Fts3Cursor*); void sqlite3Fts3Snippet(sqlite3_context *, Fts3Cursor *, const char *, const char *, const char *, int, int ); -void sqlite3Fts3Matchinfo(sqlite3_context *, Fts3Cursor *); +void sqlite3Fts3Matchinfo(sqlite3_context *, Fts3Cursor *, const char *); /* fts3_expr.c */ int sqlite3Fts3ExprParse(sqlite3_tokenizer *, diff --git a/ext/fts3/fts3_snippet.c b/ext/fts3/fts3_snippet.c index 2873d67f10..34d0b0201a 100644 --- a/ext/fts3/fts3_snippet.c +++ b/ext/fts3/fts3_snippet.c @@ -17,6 +17,22 @@ #include #include +/* +** Characters that may appear in the second argument to matchinfo(). +*/ +#define FTS3_MATCHINFO_NPHRASE 'p' /* 1 value */ +#define FTS3_MATCHINFO_NCOL 'c' /* 1 value */ +#define FTS3_MATCHINFO_NDOC 'n' /* 1 value */ +#define FTS3_MATCHINFO_AVGLENGTH 'a' /* nCol values */ +#define FTS3_MATCHINFO_LENGTH 'l' /* nCol values */ +#define FTS3_MATCHINFO_LCS 's' /* nCol values */ +#define FTS3_MATCHINFO_HITS 'x' /* 3*nCol*nPhrase values */ + +/* +** The default value for the second argument to matchinfo(). +*/ +#define FTS3_MATCHINFO_DEFAULT "pcx" + /* ** Used as an fts3ExprIterate() context when loading phrase doclists to @@ -70,6 +86,8 @@ typedef struct MatchInfo MatchInfo; struct MatchInfo { Fts3Cursor *pCursor; /* FTS3 Cursor */ int nCol; /* Number of columns in table */ + int nPhrase; /* Number of matchable phrases in query */ + sqlite3_int64 nDoc; /* Number of docs in database */ u32 *aMatchinfo; /* Pre-allocated buffer */ }; @@ -783,10 +801,26 @@ static void fts3LoadColumnlistCounts(char **pp, u32 *aOut, int isGlobal){ /* ** fts3ExprIterate() callback used to collect the "global" matchinfo stats -** for a single query. The "global" stats are those elements of the matchinfo -** array that are constant for all rows returned by the current query. +** for a single query. +** +** fts3ExprIterate() callback to load the 'global' elements of a +** FTS3_MATCHINFO_HITS matchinfo array. The global stats are those elements +** of the matchinfo array that are constant for all rows returned by the +** current query. +** +** Argument pCtx is actually a pointer to a struct of type MatchInfo. This +** function populates Matchinfo.aMatchinfo[] as follows: +** +** for(iCol=0; iColnCol * 3) + 1; + u32 *aOut = &p->aMatchinfo[3*iPhrase*p->nCol]; assert( pExpr->isLoaded ); assert( pExpr->eType==FTSQUERY_PHRASE ); @@ -814,10 +848,10 @@ static int fts3ExprGlobalMatchinfoCb( pIter = pFree; pEnd = &pFree[nFree]; }else{ - int nDoc = p->aMatchinfo[2 + 3*p->nCol*p->aMatchinfo[0]]; - for(ii=0; iinCol; ii++){ - p->aMatchinfo[iStart + ii*3] = nDoc; - p->aMatchinfo[iStart + ii*3 + 1] = nDoc; + int iCol; /* Column index */ + for(iCol=0; iColnCol; iCol++){ + aOut[iCol*3 + 1] = (u32)p->nDoc; + aOut[iCol*3 + 2] = (u32)p->nDoc; } return SQLITE_OK; } @@ -829,7 +863,7 @@ static int fts3ExprGlobalMatchinfoCb( /* Fill in the global hit count matrix row for this phrase. */ while( pIteraMatchinfo[iStart], 1); + fts3LoadColumnlistCounts(&pIter, &aOut[1], 1); } sqlite3_free(pFree); @@ -837,11 +871,11 @@ static int fts3ExprGlobalMatchinfoCb( } /* -** fts3ExprIterate() callback used to collect the "local" matchinfo stats -** for a single query. The "local" stats are those elements of the matchinfo +** fts3ExprIterate() callback used to collect the "local" part of the +** FTS3_MATCHINFO_HITS array. The local stats are those elements of the ** array that are different for each row returned by the query. */ -static int fts3ExprLocalMatchinfoCb( +static int fts3ExprLocalHitsCb( Fts3Expr *pExpr, /* Phrase expression node */ int iPhrase, /* Phrase number */ void *pCtx /* Pointer to MatchInfo structure */ @@ -850,7 +884,7 @@ static int fts3ExprLocalMatchinfoCb( if( pExpr->aDoclist ){ char *pCsr; - int iStart = 2 + (iPhrase * p->nCol * 3); + int iStart = iPhrase * p->nCol * 3; int i; for(i=0; inCol; i++) p->aMatchinfo[iStart+i*3] = 0; @@ -864,66 +898,230 @@ static int fts3ExprLocalMatchinfoCb( return SQLITE_OK; } +static int fts3MatchinfoCheck( + Fts3Table *pTab, + char cArg, + char **pzErr +){ + if( cArg==FTS3_MATCHINFO_NPHRASE + || cArg==FTS3_MATCHINFO_NCOL + || cArg==FTS3_MATCHINFO_NDOC && pTab->bHasStat + || cArg==FTS3_MATCHINFO_AVGLENGTH && pTab->bHasStat + || cArg==FTS3_MATCHINFO_LENGTH && pTab->bHasDocsize + || cArg==FTS3_MATCHINFO_LCS + || cArg==FTS3_MATCHINFO_HITS + ){ + return SQLITE_OK; + } + *pzErr = sqlite3_mprintf("unrecognized matchinfo request: %c", cArg); + return SQLITE_ERROR; +} + +static int fts3MatchinfoSize(MatchInfo *pInfo, char cArg){ + int nVal; /* Number of integers output by cArg */ + + switch( cArg ){ + case FTS3_MATCHINFO_NDOC: + case FTS3_MATCHINFO_NPHRASE: + case FTS3_MATCHINFO_NCOL: + nVal = 1; + break; + + case FTS3_MATCHINFO_AVGLENGTH: + case FTS3_MATCHINFO_LENGTH: + case FTS3_MATCHINFO_LCS: + nVal = pInfo->nCol; + break; + + case FTS3_MATCHINFO_HITS: + nVal = pInfo->nCol * pInfo->nPhrase * 3; + break; + } + + return nVal; +} + +static int fts3MatchinfoSelectDoctotal( + Fts3Table *pTab, + sqlite3_stmt **ppStmt, + sqlite3_int64 *pnDoc, + const char **paLen +){ + sqlite3_stmt *pStmt; + const char *a; + sqlite3_int64 nDoc; + + if( !*ppStmt ){ + int rc = sqlite3Fts3SelectDoctotal(pTab, ppStmt); + if( rc!=SQLITE_OK ) return rc; + } + pStmt = *ppStmt; + + a = sqlite3_column_blob(pStmt, 0); + a += sqlite3Fts3GetVarint(a, &nDoc); + *pnDoc = (u32)nDoc; + + if( paLen ) *paLen = a; + return SQLITE_OK; +} + + +static int fts3MatchinfoValues( + Fts3Cursor *pCsr, /* FTS3 cursor object */ + int bGlobal, /* True to grab the global stats */ + MatchInfo *pInfo, /* Matchinfo context object */ + const char *zArg /* Matchinfo format string */ +){ + int rc = SQLITE_OK; + int i; + Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab; + + sqlite3_stmt *pSelect = 0; + + for(i=0; zArg[i]; i++){ + + switch( zArg[i] ){ + case FTS3_MATCHINFO_NPHRASE: + if( bGlobal ) pInfo->aMatchinfo[0] = pInfo->nPhrase; + break; + + case FTS3_MATCHINFO_NCOL: + if( bGlobal ) pInfo->aMatchinfo[0] = pInfo->nCol; + break; + + case FTS3_MATCHINFO_NDOC: + if( bGlobal ){ + sqlite3_int64 nDoc; + rc = fts3MatchinfoSelectDoctotal(pTab, &pSelect, &nDoc, 0); + pInfo->aMatchinfo[0] = (u32)nDoc; + } + break; + + case FTS3_MATCHINFO_AVGLENGTH: + if( bGlobal ){ + sqlite3_int64 nDoc; /* Number of rows in table */ + const char *a; /* Aggregate column length array */ + + rc = fts3MatchinfoSelectDoctotal(pTab, &pSelect, &nDoc, &a); + if( rc==SQLITE_OK ){ + int iCol; + for(iCol=0; iColnCol; iCol++){ + sqlite3_int64 nToken; + a += sqlite3Fts3GetVarint(a, &nToken); + pInfo->aMatchinfo[iCol] = ((u32)(nToken&0xffffffff)+nDoc/2)/nDoc; + } + } + } + break; + + case FTS3_MATCHINFO_LENGTH: { + sqlite3_stmt *pSelectDocsize = 0; + rc = sqlite3Fts3SelectDocsize(pTab, pCsr->iPrevId, &pSelectDocsize); + if( rc==SQLITE_OK ){ + int iCol; + const char *a = sqlite3_column_blob(pSelectDocsize, 0); + for(iCol=0; iColnCol; iCol++){ + sqlite3_int64 nToken; + a += sqlite3Fts3GetVarint(a, &nToken); + pInfo->aMatchinfo[iCol] = (u32)nToken; + } + } + sqlite3_reset(pSelectDocsize); + break; + } + + case FTS3_MATCHINFO_HITS: { + Fts3Expr *pExpr = pCsr->pExpr; + if( bGlobal ){ + if( pCsr->pDeferred ){ + rc = fts3MatchinfoSelectDoctotal(pTab, &pSelect, &pInfo->nDoc, 0); + } + (void)fts3ExprIterate(pExpr, fts3ExprGlobalHitsCb,(void*)pInfo); + } + (void)fts3ExprIterate(pExpr, fts3ExprLocalHitsCb,(void*)pInfo); + break; + } + + + default: + assert( zArg[i]==FTS3_MATCHINFO_LCS ); + } + + pInfo->aMatchinfo += fts3MatchinfoSize(pInfo, zArg[i]); + } + + sqlite3_reset(pSelect); + return rc; +} + + /* ** Populate pCsr->aMatchinfo[] with data for the current row. The ** 'matchinfo' data is an array of 32-bit unsigned integers (C type u32). */ -static int fts3GetMatchinfo(Fts3Cursor *pCsr){ +static int fts3GetMatchinfo( + Fts3Cursor *pCsr, /* FTS3 Cursor object */ + const char *zArg /* Second argument to matchinfo() function */ +){ MatchInfo sInfo; Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab; int rc = SQLITE_OK; + int bGlobal = 0; /* Collect 'global' stats as well as local */ + memset(&sInfo, 0, sizeof(MatchInfo)); sInfo.pCursor = pCsr; sInfo.nCol = pTab->nColumn; + /* If there is cached matchinfo() data, but the format string for the + ** cache does not match the format string for this request, discard + ** the cached data. */ + if( pCsr->zMatchinfo && strcmp(pCsr->zMatchinfo, zArg) ){ + assert( pCsr->aMatchinfo ); + sqlite3_free(pCsr->aMatchinfo); + pCsr->zMatchinfo = 0; + pCsr->aMatchinfo = 0; + } + + /* If Fts3Cursor.aMatchinfo[] is NULL, then this is the first time the + ** matchinfo function has been called for this query. In this case + ** allocate the array used to accumulate the matchinfo data and + ** initialize those elements that are constant for every row. + */ if( pCsr->aMatchinfo==0 ){ - /* If Fts3Cursor.aMatchinfo[] is NULL, then this is the first time the - ** matchinfo function has been called for this query. In this case - ** allocate the array used to accumulate the matchinfo data and - ** initialize those elements that are constant for every row. - */ - int nPhrase; /* Number of phrases */ - int nMatchinfo; /* Number of u32 elements in match-info */ + int nMatchinfo = 0; /* Number of u32 elements in match-info */ + int nArg; /* Bytes in zArg */ + int i; /* Used to iterate through zArg */ /* Load doclists for each phrase in the query. */ - rc = fts3ExprLoadDoclists(pCsr, &nPhrase, 0); - if( rc!=SQLITE_OK ){ - return rc; - } - nMatchinfo = 2 + 3*sInfo.nCol*nPhrase; - if( pTab->bHasDocsize ){ - nMatchinfo += 1 + 2*pTab->nColumn; - } + rc = fts3ExprLoadDoclists(pCsr, &pCsr->nPhrase, 0); + if( rc!=SQLITE_OK ) return rc; + sInfo.nPhrase = pCsr->nPhrase; - sInfo.aMatchinfo = (u32 *)sqlite3_malloc(sizeof(u32)*nMatchinfo); - if( !sInfo.aMatchinfo ){ - return SQLITE_NOMEM; + for(i=0; zArg[i]; i++){ + nMatchinfo += fts3MatchinfoSize(&sInfo, zArg[i]); } - memset(sInfo.aMatchinfo, 0, sizeof(u32)*nMatchinfo); - - /* First element of match-info is the number of phrases in the query */ - sInfo.aMatchinfo[0] = nPhrase; - sInfo.aMatchinfo[1] = sInfo.nCol; - if( pTab->bHasDocsize ){ - int ofst = 2 + 3*sInfo.aMatchinfo[0]*sInfo.aMatchinfo[1]; - rc = sqlite3Fts3MatchinfoDocsizeGlobal(pCsr, &sInfo.aMatchinfo[ofst]); - } - (void)fts3ExprIterate(pCsr->pExpr, fts3ExprGlobalMatchinfoCb,(void*)&sInfo); - pCsr->aMatchinfo = sInfo.aMatchinfo; + + /* Allocate space for Fts3Cursor.aMatchinfo[] and Fts3Cursor.zMatchinfo. */ + nArg = strlen(zArg); + pCsr->aMatchinfo = (u32 *)sqlite3_malloc(sizeof(u32)*nMatchinfo + nArg + 1); + if( !pCsr->aMatchinfo ) return SQLITE_NOMEM; + + pCsr->zMatchinfo = (char *)&pCsr->aMatchinfo[nMatchinfo]; + pCsr->nMatchinfo = nMatchinfo; + memcpy(pCsr->zMatchinfo, zArg, nArg+1); + memset(pCsr->aMatchinfo, 0, sizeof(u32)*nMatchinfo); pCsr->isMatchinfoNeeded = 1; + bGlobal = 1; } sInfo.aMatchinfo = pCsr->aMatchinfo; + sInfo.nPhrase = pCsr->nPhrase; if( rc==SQLITE_OK && pCsr->isMatchinfoNeeded ){ - (void)fts3ExprIterate(pCsr->pExpr, fts3ExprLocalMatchinfoCb, (void*)&sInfo); - if( pTab->bHasDocsize ){ - int ofst = 2 + 3*sInfo.aMatchinfo[0]*sInfo.aMatchinfo[1]; - rc = sqlite3Fts3MatchinfoDocsizeLocal(pCsr, &sInfo.aMatchinfo[ofst]); - } + rc = fts3MatchinfoValues(pCsr, bGlobal, &sInfo, zArg); pCsr->isMatchinfoNeeded = 0; } - return SQLITE_OK; + return rc; } /* @@ -1211,22 +1409,43 @@ void sqlite3Fts3Offsets( /* ** Implementation of matchinfo() function. */ -void sqlite3Fts3Matchinfo(sqlite3_context *pContext, Fts3Cursor *pCsr){ +void sqlite3Fts3Matchinfo( + sqlite3_context *pContext, /* Function call context */ + Fts3Cursor *pCsr, /* FTS3 table cursor */ + const char *zArg /* Second arg to matchinfo() function */ +){ + Fts3Table *pTab = (Fts3Table *)pCsr->base.pVtab; int rc; + int i; + const char *zFormat; + + if( zArg ){ + for(i=0; zArg[i]; i++){ + char *zErr = 0; + if( fts3MatchinfoCheck(pTab, zArg[i], &zErr) ){ + sqlite3_result_error(pContext, zErr, -1); + sqlite3_free(zErr); + return; + } + } + zFormat = zArg; + }else{ + zFormat = FTS3_MATCHINFO_DEFAULT; + } + if( !pCsr->pExpr ){ sqlite3_result_blob(pContext, "", 0, SQLITE_STATIC); return; } - rc = fts3GetMatchinfo(pCsr); - sqlite3Fts3SegmentsClose((Fts3Table *)pCsr->base.pVtab ); + + /* Retrieve matchinfo() data. */ + rc = fts3GetMatchinfo(pCsr, zFormat); + sqlite3Fts3SegmentsClose(pTab); + if( rc!=SQLITE_OK ){ sqlite3_result_error_code(pContext, rc); }else{ - Fts3Table *pTab = (Fts3Table*)pCsr->base.pVtab; - int n = sizeof(u32)*(2+pCsr->aMatchinfo[0]*pCsr->aMatchinfo[1]*3); - if( pTab->bHasDocsize ){ - n += sizeof(u32)*(1 + 2*pTab->nColumn); - } + int n = pCsr->nMatchinfo * sizeof(u32); sqlite3_result_blob(pContext, pCsr->aMatchinfo, n, SQLITE_TRANSIENT); } } diff --git a/ext/fts3/fts3_write.c b/ext/fts3/fts3_write.c index 91699bedb7..05f46f24e2 100644 --- a/ext/fts3/fts3_write.c +++ b/ext/fts3/fts3_write.c @@ -283,6 +283,51 @@ static int fts3SqlStmt( return rc; } +static int fts3SelectDocsize( + Fts3Table *pTab, /* FTS3 table handle */ + int eStmt, /* Either SQL_SELECT_DOCSIZE or DOCTOTAL */ + sqlite3_int64 iDocid, /* Docid to bind for SQL_SELECT_DOCSIZE */ + sqlite3_stmt **ppStmt /* OUT: Statement handle */ +){ + sqlite3_stmt *pStmt = 0; /* Statement requested from fts3SqlStmt() */ + int rc; /* Return code */ + + assert( eStmt==SQL_SELECT_DOCSIZE || eStmt==SQL_SELECT_DOCTOTAL ); + + rc = fts3SqlStmt(pTab, eStmt, &pStmt, 0); + if( rc==SQLITE_OK ){ + if( eStmt==SQL_SELECT_DOCSIZE ){ + sqlite3_bind_int64(pStmt, 1, iDocid); + } + rc = sqlite3_step(pStmt); + if( rc!=SQLITE_ROW ){ + rc = sqlite3_reset(pStmt); + if( rc==SQLITE_OK ) rc = SQLITE_CORRUPT; + pStmt = 0; + }else{ + rc = SQLITE_OK; + } + } + + *ppStmt = pStmt; + return rc; +} + +int sqlite3Fts3SelectDoctotal( + Fts3Table *pTab, /* Fts3 table handle */ + sqlite3_stmt **ppStmt /* OUT: Statement handle */ +){ + return fts3SelectDocsize(pTab, SQL_SELECT_DOCTOTAL, 0, ppStmt); +} + +int sqlite3Fts3SelectDocsize( + Fts3Table *pTab, /* Fts3 table handle */ + sqlite3_int64 iDocid, /* Docid to read size data for */ + sqlite3_stmt **ppStmt /* OUT: Statement handle */ +){ + return fts3SelectDocsize(pTab, SQL_SELECT_DOCSIZE, iDocid, ppStmt); +} + /* ** Similar to fts3SqlStmt(). Except, after binding the parameters in ** array apVal[] to the SQL statement identified by eStmt, the statement diff --git a/manifest b/manifest index ac73ebad1a..5ef19efb6a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\stypo\sin\sunixCurrentTimeInt64()\spreventing\scompilation\swith\sNO_GETTOD\sdefined. -D 2010-11-22T17:26:07 +C Experimental\schanges\sto\sfts3\sfunction\smatchinfo(). +D 2010-11-23T19:16:48 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in e7a59672eaeb04408d1fa8501618d7501a3c5e39 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -61,19 +61,19 @@ F ext/fts2/mkfts2amal.tcl 974d5d438cb3f7c4a652639262f82418c1e4cff0 F ext/fts3/README.syntax a19711dc5458c20734b8e485e75fb1981ec2427a F ext/fts3/README.tokenizers 998756696647400de63d5ba60e9655036cb966e9 F ext/fts3/README.txt 8c18f41574404623b76917b9da66fcb0ab38328d -F ext/fts3/fts3.c 7e01fd82fa289decbc21bcebb924d44d307eb757 +F ext/fts3/fts3.c 591b6fdb563dd00cd05b57ea27272f388e8156c8 F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe -F ext/fts3/fts3Int.h bbcd6d671228c9ae2ed5514723fcc6217821d0a6 +F ext/fts3/fts3Int.h 0f7b9f189bcb0eed43a9489d2251b99acf06b833 F ext/fts3/fts3_expr.c ee48b9278b8b2432a05a03320fbcacba151dbaa5 F ext/fts3/fts3_hash.c 3c8f6387a4a7f5305588b203fa7c887d753e1f1c F ext/fts3/fts3_hash.h 8331fb2206c609f9fc4c4735b9ab5ad6137c88ec F ext/fts3/fts3_icu.c ac494aed69835008185299315403044664bda295 F ext/fts3/fts3_porter.c 8df6f6efcc4e9e31f8bf73a4007c2e9abca1dfba -F ext/fts3/fts3_snippet.c 300c12b7f0a2a6ae0491bb2d00e2d5ff9c28f685 +F ext/fts3/fts3_snippet.c aa0a76088024a693ab6a51d0d383e06f97e4fd8c F ext/fts3/fts3_tokenizer.c 1301b0ee3ef414caae3257a702215925cc48cd9c F ext/fts3/fts3_tokenizer.h 13ffd9fcb397fec32a05ef5cd9e0fa659bf3dbd3 F ext/fts3/fts3_tokenizer1.c 6e5cbaa588924ac578263a598e4fb9f5c9bb179d -F ext/fts3/fts3_write.c 3d12dad6cbe788ff7214ef227520fb6600ff5112 +F ext/fts3/fts3_write.c f5e7db79057ea46c1f3d15a4e2c8b658d306e37f F ext/fts3/fts3speed.tcl b54caf6a18d38174f1a6e84219950d85e98bb1e9 F ext/fts3/mkfts3amal.tcl 252ecb7fe6467854f2aa237bf2c390b74e71f100 F ext/icu/README.txt bf8461d8cdc6b8f514c080e4e10dc3b2bbdfefa9 @@ -440,15 +440,15 @@ F test/fts3corrupt2.test 6d96efae2f8a6af3eeaf283aba437e6d0e5447ba F test/fts3cov.test e0fb00d8b715ddae4a94c305992dfc3ef70353d7 F test/fts3d.test 95fb3c862cbc4297c93fceb9a635543744e9ef52 F test/fts3defer.test d6cb0db9b5997ecf863d96ff419f83f8f2c87f4f -F test/fts3defer2.test d3c7db6584aab06a2781b8de58747c33b23cb19c +F test/fts3defer2.test 548eb2ca7e6a1515a7bc151721e223be14c51f9d F test/fts3e.test 1f6c6ac9cc8b772ca256e6b22aaeed50c9350851 F test/fts3expr.test 5e745b2b6348499d9ef8d59015de3182072c564c F test/fts3expr2.test 18da930352e5693eaa163a3eacf96233b7290d1a F test/fts3fault.test 81fd40ceb12f33f9d16c5637d0f8d95d4556c456 F test/fts3malloc.test 9c8cc3f885bb4dfc66d0460c52f68f45e4710d1b -F test/fts3matchinfo.test 211b04434926bce9cc2b3cc5f58725affefe5165 +F test/fts3matchinfo.test 051bc3d09152998cedb7b9bdfd5b0730b5c0a939 F test/fts3near.test 2e318ee434d32babd27c167142e2b94ddbab4844 -F test/fts3query.test df864f4c9b14927daa7199242d82cff44599327b +F test/fts3query.test ef79d31fdb355d094baec1c1b24b60439a1fb8a2 F test/fts3rnd.test 707533ce943f490443ce5e696236bb1675a37635 F test/fts3shared.test 8bb266521d7c5495c0ae522bb4d376ad5387d4a2 F test/fts3snippet.test a12f22a3ba4dd59751a57c79b031d07ab5f51ddd @@ -889,7 +889,10 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P e38c81cc18d2ceaa1644aaba64530ba5d1fbf2cf -R d7dd6f7536f2f168157ffbcee03e168e +P 3df3e79b56821201b4f5ecd23f94d485745c48c3 +R d2823d2eb839cb4c673b301711f75566 +T *branch * fts3-experimental +T *sym-fts3-experimental * +T -sym-trunk * U dan -Z 238874a9476b4d03764b69cbc465de50 +Z cb34d18554c4ac084411d81cdabfad29 diff --git a/manifest.uuid b/manifest.uuid index c846832a9a..1e10a20f1a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3df3e79b56821201b4f5ecd23f94d485745c48c3 \ No newline at end of file +9cf0f2b76bc68c168e3fa861b7235f384db21d38 \ No newline at end of file diff --git a/test/fts3defer2.test b/test/fts3defer2.test index ccae5bc3da..32f044b1c7 100644 --- a/test/fts3defer2.test +++ b/test/fts3defer2.test @@ -53,7 +53,7 @@ do_execsql_test 1.2.1 { } {{a b c d e f a x y}} do_execsql_test 1.2.2 { - SELECT snippet(t1, '[', ']'), offsets(t1), mit(matchinfo(t1)) + SELECT snippet(t1, '[', ']'), offsets(t1), mit(matchinfo(t1, 'pcxnal')) FROM t1 WHERE t1 MATCH 'f (e NEAR/2 a)'; } [list \ {a b c d [e] [f] [a] x y} \ @@ -62,7 +62,7 @@ do_execsql_test 1.2.2 { ] do_execsql_test 1.2.3 { - SELECT snippet(t1, '[', ']'), offsets(t1), mit(matchinfo(t1)) + SELECT snippet(t1, '[', ']'), offsets(t1), mit(matchinfo(t1, 'pcxnal')) FROM t1 WHERE t1 MATCH 'f (e NEAR/3 a)'; } [list \ {[a] b c d [e] [f] [a] x y} \ @@ -92,7 +92,7 @@ foreach {tn sql} { } { execsql $sql do_execsql_test 2.2.$tn { - SELECT mit(matchinfo(t2)) FROM t2 WHERE t2 MATCH 'a b'; + SELECT mit(matchinfo(t2, 'pcxnal')) FROM t2 WHERE t2 MATCH 'a b'; } [list \ [list 2 1 1 54 54 1 3 3 54 372 7] \ [list 2 1 1 54 54 1 3 3 54 372 7] \ @@ -124,7 +124,7 @@ foreach {tn sql} { } { execsql $sql do_execsql_test 2.4.$tn { - SELECT docid, mit(matchinfo(t3)) FROM t3 WHERE t3 MATCH '"a b c"'; + SELECT docid, mit(matchinfo(t3, 'pcxnal')) FROM t3 WHERE t3 MATCH '"a b c"'; } {1 {1 1 1 4 4 11 912 6} 3 {1 1 1 4 4 11 912 6}} } diff --git a/test/fts3matchinfo.test b/test/fts3matchinfo.test index 43f5147cdd..36b85aed5d 100644 --- a/test/fts3matchinfo.test +++ b/test/fts3matchinfo.test @@ -41,15 +41,13 @@ do_execsql_test 1.1 { SELECT mit(matchinfo(t1)) FROM t1 WHERE t1 MATCH 'I'; } {{1 1 1 2 2} {1 1 1 2 2}} -# Now create an FTS4 table that does not specify matchinfo=fts3. The -# %_docsize table is created in this case and the array of integers returned -# by matchinfo() includes the extra data. +# Now create an FTS4 table that does not specify matchinfo=fts3. # do_execsql_test 1.2 { CREATE VIRTUAL TABLE t2 USING fts4; INSERT INTO t2 SELECT * FROM t1; SELECT mit(matchinfo(t2)) FROM t2 WHERE t2 MATCH 'I'; -} {{1 1 1 2 2 4 7 6} {1 1 1 2 2 4 7 8}} +} {{1 1 1 2 2} {1 1 1 2 2}} # Test some syntax-error handling. # diff --git a/test/fts3query.test b/test/fts3query.test index 95cb1f39b1..c8f8686bff 100644 --- a/test/fts3query.test +++ b/test/fts3query.test @@ -152,8 +152,6 @@ do_select_tests 5.2 -errorformat { wrong number of arguments to function %s() } { 1 "SELECT matchinfo() FROM t2 WHERE t2 MATCH 'history'" matchinfo - 2 "SELECT matchinfo(t2, t2) FROM t2 WHERE t2 MATCH 'history'" matchinfo - 3 "SELECT snippet(t2, 1, 2, 3, 4, 5, 6) FROM t2 WHERE t2 MATCH 'history'" snippet } @@ -174,8 +172,13 @@ do_select_tests 5.4 -errorformat { 3 "SELECT snippet(content) FROM t2 WHERE t2 MATCH 'history'" snippet 4 "SELECT optimize(content) FROM t2 WHERE t2 MATCH 'history'" optimize } +do_catchsql_test 5.5.1 { + SELECT matchinfo(t2, 'abc') FROM t2 WHERE t2 MATCH 'history' +} {1 {unrecognized matchinfo request: b}} + do_execsql_test 5.5 { DROP TABLE t2 } + # Test the snippet() function with 1 to 6 arguments. # do_execsql_test 6.1 {