2021SC@SDUSC
简介
本文我们介绍分词器部分的最后一个内容fts3_expr.c;fts3_expr.c这个文件主要是实现查询字符串功能(MATCH函数)。MATCH运算符用在全文检索中。例如这两句:
SELECT title, body FROM pages WHERE pages MATCH 'world';
SELECT title, body FROM pages WHERE title MATCH 'world';
这两句,前一个 MATCH 左边写了表名,后一个写的是列名。后一个仅搜索title列,前一个是搜索全部列(docid 列以外)。MATCH右侧的表达式支持模糊查询、支持指定列查询、支持 AND/OR/NEAR/NOT 等运算,例如:
SELECT title, body FROM pages WHERE pages MATCH 'hel*';
SELECT title, body FROM pages WHERE pages MATCH 'title:hello';
SELECT title, body FROM pages WHERE pages MATCH 'hello AND world';
SELECT title, body FROM pages WHERE pages MATCH '(hello NEAR world) OR (program AND language)';
源码分析
fts3_expr.c文件中包含下列几个函数
//检查参数c是否为空格字符
static int fts3isspace(char c){
return c==' ' || c=='\t' || c=='\n' || c=='\r' || c=='\v' || c=='\f';
}
//分配内存字节
static void *fts3MallocZero(sqlite3_int64 nByte){
void *pRet = sqlite3_malloc64(nByte);
if( pRet ) memset(pRet, 0, nByte);
return pRet;
}
//打开分词器
int sqlite3Fts3OpenTokenizer(
sqlite3_tokenizer *pTokenizer,
int iLangid,
const char *z,
int n,
sqlite3_tokenizer_cursor **ppCsr
){
sqlite3_tokenizer_module const *pModule = pTokenizer->pModule;
sqlite3_tokenizer_cursor *pCsr = 0;
int rc;
rc = pModule->xOpen(pTokenizer, z, n, &pCsr);
assert( rc==SQLITE_OK || pCsr==0 );
if( rc==SQLITE_OK ){
pCsr->pTokenizer = pTokenizer;
if( pModule->iVersion>=1 ){
rc = pModule->xLanguageid(pCsr, iLangid);
if( rc!=SQLITE_OK ){
pModule->xClose(pCsr);
pCsr = 0;
}
}
}
*ppCsr = pCsr;
return rc;
}
//提取下一个标记和其他语法分析的信息
static int getNextToken(
ParseContext *pParse, /* fts3 query parse context */
int iCol, /* Value for Fts3Phrase.iColumn */
const char *z, int n, /* Input string */
Fts3Expr **ppExpr, /* OUT: expression */
int *pnConsumed /* OUT: Number of bytes consumed */
){
sqlite3_tokenizer *pTokenizer = pParse->pTokenizer;
sqlite3_tokenizer_module const *pModule = pTokenizer