Index: third_party/sqlite/sqlite-src-3100200/ext/fts5/fts5_vocab.c |
diff --git a/third_party/sqlite/sqlite-src-3100200/ext/fts5/fts5_vocab.c b/third_party/sqlite/sqlite-src-3100200/ext/fts5/fts5_vocab.c |
deleted file mode 100644 |
index 860cfedb9bc4b6a0ff4c069e9a6f50cec2a73415..0000000000000000000000000000000000000000 |
--- a/third_party/sqlite/sqlite-src-3100200/ext/fts5/fts5_vocab.c |
+++ /dev/null |
@@ -1,600 +0,0 @@ |
-/* |
-** 2015 May 08 |
-** |
-** The author disclaims copyright to this source code. In place of |
-** a legal notice, here is a blessing: |
-** |
-** May you do good and not evil. |
-** May you find forgiveness for yourself and forgive others. |
-** May you share freely, never taking more than you give. |
-** |
-****************************************************************************** |
-** |
-** This is an SQLite virtual table module implementing direct access to an |
-** existing FTS5 index. The module may create several different types of |
-** tables: |
-** |
-** col: |
-** CREATE TABLE vocab(term, col, doc, cnt, PRIMARY KEY(term, col)); |
-** |
-** One row for each term/column combination. The value of $doc is set to |
-** the number of fts5 rows that contain at least one instance of term |
-** $term within column $col. Field $cnt is set to the total number of |
-** instances of term $term in column $col (in any row of the fts5 table). |
-** |
-** row: |
-** CREATE TABLE vocab(term, doc, cnt, PRIMARY KEY(term)); |
-** |
-** One row for each term in the database. The value of $doc is set to |
-** the number of fts5 rows that contain at least one instance of term |
-** $term. Field $cnt is set to the total number of instances of term |
-** $term in the database. |
-*/ |
- |
- |
-#include "fts5Int.h" |
- |
- |
-typedef struct Fts5VocabTable Fts5VocabTable; |
-typedef struct Fts5VocabCursor Fts5VocabCursor; |
- |
-struct Fts5VocabTable { |
- sqlite3_vtab base; |
- char *zFts5Tbl; /* Name of fts5 table */ |
- char *zFts5Db; /* Db containing fts5 table */ |
- sqlite3 *db; /* Database handle */ |
- Fts5Global *pGlobal; /* FTS5 global object for this database */ |
- int eType; /* FTS5_VOCAB_COL or ROW */ |
-}; |
- |
-struct Fts5VocabCursor { |
- sqlite3_vtab_cursor base; |
- sqlite3_stmt *pStmt; /* Statement holding lock on pIndex */ |
- Fts5Index *pIndex; /* Associated FTS5 index */ |
- |
- int bEof; /* True if this cursor is at EOF */ |
- Fts5IndexIter *pIter; /* Term/rowid iterator object */ |
- |
- int nLeTerm; /* Size of zLeTerm in bytes */ |
- char *zLeTerm; /* (term <= $zLeTerm) paramater, or NULL */ |
- |
- /* These are used by 'col' tables only */ |
- Fts5Config *pConfig; /* Fts5 table configuration */ |
- int iCol; |
- i64 *aCnt; |
- i64 *aDoc; |
- |
- /* Output values used by 'row' and 'col' tables */ |
- i64 rowid; /* This table's current rowid value */ |
- Fts5Buffer term; /* Current value of 'term' column */ |
-}; |
- |
-#define FTS5_VOCAB_COL 0 |
-#define FTS5_VOCAB_ROW 1 |
- |
-#define FTS5_VOCAB_COL_SCHEMA "term, col, doc, cnt" |
-#define FTS5_VOCAB_ROW_SCHEMA "term, doc, cnt" |
- |
-/* |
-** Bits for the mask used as the idxNum value by xBestIndex/xFilter. |
-*/ |
-#define FTS5_VOCAB_TERM_EQ 0x01 |
-#define FTS5_VOCAB_TERM_GE 0x02 |
-#define FTS5_VOCAB_TERM_LE 0x04 |
- |
- |
-/* |
-** Translate a string containing an fts5vocab table type to an |
-** FTS5_VOCAB_XXX constant. If successful, set *peType to the output |
-** value and return SQLITE_OK. Otherwise, set *pzErr to an error message |
-** and return SQLITE_ERROR. |
-*/ |
-static int fts5VocabTableType(const char *zType, char **pzErr, int *peType){ |
- int rc = SQLITE_OK; |
- char *zCopy = sqlite3Fts5Strndup(&rc, zType, -1); |
- if( rc==SQLITE_OK ){ |
- sqlite3Fts5Dequote(zCopy); |
- if( sqlite3_stricmp(zCopy, "col")==0 ){ |
- *peType = FTS5_VOCAB_COL; |
- }else |
- |
- if( sqlite3_stricmp(zCopy, "row")==0 ){ |
- *peType = FTS5_VOCAB_ROW; |
- }else |
- { |
- *pzErr = sqlite3_mprintf("fts5vocab: unknown table type: %Q", zCopy); |
- rc = SQLITE_ERROR; |
- } |
- sqlite3_free(zCopy); |
- } |
- |
- return rc; |
-} |
- |
- |
-/* |
-** The xDisconnect() virtual table method. |
-*/ |
-static int fts5VocabDisconnectMethod(sqlite3_vtab *pVtab){ |
- Fts5VocabTable *pTab = (Fts5VocabTable*)pVtab; |
- sqlite3_free(pTab); |
- return SQLITE_OK; |
-} |
- |
-/* |
-** The xDestroy() virtual table method. |
-*/ |
-static int fts5VocabDestroyMethod(sqlite3_vtab *pVtab){ |
- Fts5VocabTable *pTab = (Fts5VocabTable*)pVtab; |
- sqlite3_free(pTab); |
- return SQLITE_OK; |
-} |
- |
-/* |
-** This function is the implementation of both the xConnect and xCreate |
-** methods of the FTS3 virtual table. |
-** |
-** The argv[] array contains the following: |
-** |
-** argv[0] -> module name ("fts5vocab") |
-** argv[1] -> database name |
-** argv[2] -> table name |
-** |
-** then: |
-** |
-** argv[3] -> name of fts5 table |
-** argv[4] -> type of fts5vocab table |
-** |
-** or, for tables in the TEMP schema only. |
-** |
-** argv[3] -> name of fts5 tables database |
-** argv[4] -> name of fts5 table |
-** argv[5] -> type of fts5vocab table |
-*/ |
-static int fts5VocabInitVtab( |
- sqlite3 *db, /* The SQLite database connection */ |
- void *pAux, /* Pointer to Fts5Global object */ |
- int argc, /* Number of elements in argv array */ |
- const char * const *argv, /* xCreate/xConnect argument array */ |
- sqlite3_vtab **ppVTab, /* Write the resulting vtab structure here */ |
- char **pzErr /* Write any error message here */ |
-){ |
- const char *azSchema[] = { |
- "CREATE TABlE vocab(" FTS5_VOCAB_COL_SCHEMA ")", |
- "CREATE TABlE vocab(" FTS5_VOCAB_ROW_SCHEMA ")" |
- }; |
- |
- Fts5VocabTable *pRet = 0; |
- int rc = SQLITE_OK; /* Return code */ |
- int bDb; |
- |
- bDb = (argc==6 && strlen(argv[1])==4 && memcmp("temp", argv[1], 4)==0); |
- |
- if( argc!=5 && bDb==0 ){ |
- *pzErr = sqlite3_mprintf("wrong number of vtable arguments"); |
- rc = SQLITE_ERROR; |
- }else{ |
- int nByte; /* Bytes of space to allocate */ |
- const char *zDb = bDb ? argv[3] : argv[1]; |
- const char *zTab = bDb ? argv[4] : argv[3]; |
- const char *zType = bDb ? argv[5] : argv[4]; |
- int nDb = (int)strlen(zDb)+1; |
- int nTab = (int)strlen(zTab)+1; |
- int eType = 0; |
- |
- rc = fts5VocabTableType(zType, pzErr, &eType); |
- if( rc==SQLITE_OK ){ |
- assert( eType>=0 && eType<sizeof(azSchema)/sizeof(azSchema[0]) ); |
- rc = sqlite3_declare_vtab(db, azSchema[eType]); |
- } |
- |
- nByte = sizeof(Fts5VocabTable) + nDb + nTab; |
- pRet = sqlite3Fts5MallocZero(&rc, nByte); |
- if( pRet ){ |
- pRet->pGlobal = (Fts5Global*)pAux; |
- pRet->eType = eType; |
- pRet->db = db; |
- pRet->zFts5Tbl = (char*)&pRet[1]; |
- pRet->zFts5Db = &pRet->zFts5Tbl[nTab]; |
- memcpy(pRet->zFts5Tbl, zTab, nTab); |
- memcpy(pRet->zFts5Db, zDb, nDb); |
- sqlite3Fts5Dequote(pRet->zFts5Tbl); |
- sqlite3Fts5Dequote(pRet->zFts5Db); |
- } |
- } |
- |
- *ppVTab = (sqlite3_vtab*)pRet; |
- return rc; |
-} |
- |
- |
-/* |
-** The xConnect() and xCreate() methods for the virtual table. All the |
-** work is done in function fts5VocabInitVtab(). |
-*/ |
-static int fts5VocabConnectMethod( |
- sqlite3 *db, /* Database connection */ |
- void *pAux, /* Pointer to tokenizer hash table */ |
- int argc, /* Number of elements in argv array */ |
- const char * const *argv, /* xCreate/xConnect argument array */ |
- sqlite3_vtab **ppVtab, /* OUT: New sqlite3_vtab object */ |
- char **pzErr /* OUT: sqlite3_malloc'd error message */ |
-){ |
- return fts5VocabInitVtab(db, pAux, argc, argv, ppVtab, pzErr); |
-} |
-static int fts5VocabCreateMethod( |
- sqlite3 *db, /* Database connection */ |
- void *pAux, /* Pointer to tokenizer hash table */ |
- int argc, /* Number of elements in argv array */ |
- const char * const *argv, /* xCreate/xConnect argument array */ |
- sqlite3_vtab **ppVtab, /* OUT: New sqlite3_vtab object */ |
- char **pzErr /* OUT: sqlite3_malloc'd error message */ |
-){ |
- return fts5VocabInitVtab(db, pAux, argc, argv, ppVtab, pzErr); |
-} |
- |
-/* |
-** Implementation of the xBestIndex method. |
-*/ |
-static int fts5VocabBestIndexMethod( |
- sqlite3_vtab *pVTab, |
- sqlite3_index_info *pInfo |
-){ |
- int i; |
- int iTermEq = -1; |
- int iTermGe = -1; |
- int iTermLe = -1; |
- int idxNum = 0; |
- int nArg = 0; |
- |
- for(i=0; i<pInfo->nConstraint; i++){ |
- struct sqlite3_index_constraint *p = &pInfo->aConstraint[i]; |
- if( p->usable==0 ) continue; |
- if( p->iColumn==0 ){ /* term column */ |
- if( p->op==SQLITE_INDEX_CONSTRAINT_EQ ) iTermEq = i; |
- if( p->op==SQLITE_INDEX_CONSTRAINT_LE ) iTermLe = i; |
- if( p->op==SQLITE_INDEX_CONSTRAINT_LT ) iTermLe = i; |
- if( p->op==SQLITE_INDEX_CONSTRAINT_GE ) iTermGe = i; |
- if( p->op==SQLITE_INDEX_CONSTRAINT_GT ) iTermGe = i; |
- } |
- } |
- |
- if( iTermEq>=0 ){ |
- idxNum |= FTS5_VOCAB_TERM_EQ; |
- pInfo->aConstraintUsage[iTermEq].argvIndex = ++nArg; |
- pInfo->estimatedCost = 100; |
- }else{ |
- pInfo->estimatedCost = 1000000; |
- if( iTermGe>=0 ){ |
- idxNum |= FTS5_VOCAB_TERM_GE; |
- pInfo->aConstraintUsage[iTermGe].argvIndex = ++nArg; |
- pInfo->estimatedCost = pInfo->estimatedCost / 2; |
- } |
- if( iTermLe>=0 ){ |
- idxNum |= FTS5_VOCAB_TERM_LE; |
- pInfo->aConstraintUsage[iTermLe].argvIndex = ++nArg; |
- pInfo->estimatedCost = pInfo->estimatedCost / 2; |
- } |
- } |
- |
- pInfo->idxNum = idxNum; |
- |
- return SQLITE_OK; |
-} |
- |
-/* |
-** Implementation of xOpen method. |
-*/ |
-static int fts5VocabOpenMethod( |
- sqlite3_vtab *pVTab, |
- sqlite3_vtab_cursor **ppCsr |
-){ |
- Fts5VocabTable *pTab = (Fts5VocabTable*)pVTab; |
- Fts5Index *pIndex = 0; |
- Fts5Config *pConfig = 0; |
- Fts5VocabCursor *pCsr = 0; |
- int rc = SQLITE_OK; |
- sqlite3_stmt *pStmt = 0; |
- char *zSql = 0; |
- |
- zSql = sqlite3Fts5Mprintf(&rc, |
- "SELECT t.%Q FROM %Q.%Q AS t WHERE t.%Q MATCH '*id'", |
- pTab->zFts5Tbl, pTab->zFts5Db, pTab->zFts5Tbl, pTab->zFts5Tbl |
- ); |
- if( zSql ){ |
- rc = sqlite3_prepare_v2(pTab->db, zSql, -1, &pStmt, 0); |
- } |
- sqlite3_free(zSql); |
- assert( rc==SQLITE_OK || pStmt==0 ); |
- if( rc==SQLITE_ERROR ) rc = SQLITE_OK; |
- |
- if( pStmt && sqlite3_step(pStmt)==SQLITE_ROW ){ |
- i64 iId = sqlite3_column_int64(pStmt, 0); |
- pIndex = sqlite3Fts5IndexFromCsrid(pTab->pGlobal, iId, &pConfig); |
- } |
- |
- if( rc==SQLITE_OK && pIndex==0 ){ |
- rc = sqlite3_finalize(pStmt); |
- pStmt = 0; |
- if( rc==SQLITE_OK ){ |
- pVTab->zErrMsg = sqlite3_mprintf( |
- "no such fts5 table: %s.%s", pTab->zFts5Db, pTab->zFts5Tbl |
- ); |
- rc = SQLITE_ERROR; |
- } |
- } |
- |
- if( rc==SQLITE_OK ){ |
- int nByte = pConfig->nCol * sizeof(i64) * 2 + sizeof(Fts5VocabCursor); |
- pCsr = (Fts5VocabCursor*)sqlite3Fts5MallocZero(&rc, nByte); |
- } |
- |
- if( pCsr ){ |
- pCsr->pIndex = pIndex; |
- pCsr->pStmt = pStmt; |
- pCsr->pConfig = pConfig; |
- pCsr->aCnt = (i64*)&pCsr[1]; |
- pCsr->aDoc = &pCsr->aCnt[pConfig->nCol]; |
- }else{ |
- sqlite3_finalize(pStmt); |
- } |
- |
- *ppCsr = (sqlite3_vtab_cursor*)pCsr; |
- return rc; |
-} |
- |
-static void fts5VocabResetCursor(Fts5VocabCursor *pCsr){ |
- pCsr->rowid = 0; |
- sqlite3Fts5IterClose(pCsr->pIter); |
- pCsr->pIter = 0; |
- sqlite3_free(pCsr->zLeTerm); |
- pCsr->nLeTerm = -1; |
- pCsr->zLeTerm = 0; |
-} |
- |
-/* |
-** Close the cursor. For additional information see the documentation |
-** on the xClose method of the virtual table interface. |
-*/ |
-static int fts5VocabCloseMethod(sqlite3_vtab_cursor *pCursor){ |
- Fts5VocabCursor *pCsr = (Fts5VocabCursor*)pCursor; |
- fts5VocabResetCursor(pCsr); |
- sqlite3Fts5BufferFree(&pCsr->term); |
- sqlite3_finalize(pCsr->pStmt); |
- sqlite3_free(pCsr); |
- return SQLITE_OK; |
-} |
- |
- |
-/* |
-** Advance the cursor to the next row in the table. |
-*/ |
-static int fts5VocabNextMethod(sqlite3_vtab_cursor *pCursor){ |
- Fts5VocabCursor *pCsr = (Fts5VocabCursor*)pCursor; |
- Fts5VocabTable *pTab = (Fts5VocabTable*)pCursor->pVtab; |
- int rc = SQLITE_OK; |
- int nCol = pCsr->pConfig->nCol; |
- |
- pCsr->rowid++; |
- |
- if( pTab->eType==FTS5_VOCAB_COL ){ |
- for(pCsr->iCol++; pCsr->iCol<nCol; pCsr->iCol++){ |
- if( pCsr->aCnt[pCsr->iCol] ) break; |
- } |
- } |
- |
- if( pTab->eType==FTS5_VOCAB_ROW || pCsr->iCol>=nCol ){ |
- if( sqlite3Fts5IterEof(pCsr->pIter) ){ |
- pCsr->bEof = 1; |
- }else{ |
- const char *zTerm; |
- int nTerm; |
- |
- zTerm = sqlite3Fts5IterTerm(pCsr->pIter, &nTerm); |
- if( pCsr->nLeTerm>=0 ){ |
- int nCmp = MIN(nTerm, pCsr->nLeTerm); |
- int bCmp = memcmp(pCsr->zLeTerm, zTerm, nCmp); |
- if( bCmp<0 || (bCmp==0 && pCsr->nLeTerm<nTerm) ){ |
- pCsr->bEof = 1; |
- return SQLITE_OK; |
- } |
- } |
- |
- sqlite3Fts5BufferSet(&rc, &pCsr->term, nTerm, (const u8*)zTerm); |
- memset(pCsr->aCnt, 0, nCol * sizeof(i64)); |
- memset(pCsr->aDoc, 0, nCol * sizeof(i64)); |
- pCsr->iCol = 0; |
- |
- assert( pTab->eType==FTS5_VOCAB_COL || pTab->eType==FTS5_VOCAB_ROW ); |
- while( rc==SQLITE_OK ){ |
- i64 dummy; |
- const u8 *pPos; int nPos; /* Position list */ |
- i64 iPos = 0; /* 64-bit position read from poslist */ |
- int iOff = 0; /* Current offset within position list */ |
- |
- rc = sqlite3Fts5IterPoslist(pCsr->pIter, 0, &pPos, &nPos, &dummy); |
- if( rc==SQLITE_OK ){ |
- if( pTab->eType==FTS5_VOCAB_ROW ){ |
- while( 0==sqlite3Fts5PoslistNext64(pPos, nPos, &iOff, &iPos) ){ |
- pCsr->aCnt[0]++; |
- } |
- pCsr->aDoc[0]++; |
- }else{ |
- int iCol = -1; |
- while( 0==sqlite3Fts5PoslistNext64(pPos, nPos, &iOff, &iPos) ){ |
- int ii = FTS5_POS2COLUMN(iPos); |
- pCsr->aCnt[ii]++; |
- if( iCol!=ii ){ |
- pCsr->aDoc[ii]++; |
- iCol = ii; |
- } |
- } |
- } |
- rc = sqlite3Fts5IterNextScan(pCsr->pIter); |
- } |
- |
- if( rc==SQLITE_OK ){ |
- zTerm = sqlite3Fts5IterTerm(pCsr->pIter, &nTerm); |
- if( nTerm!=pCsr->term.n || memcmp(zTerm, pCsr->term.p, nTerm) ){ |
- break; |
- } |
- if( sqlite3Fts5IterEof(pCsr->pIter) ) break; |
- } |
- } |
- } |
- } |
- |
- if( pCsr->bEof==0 && pTab->eType==FTS5_VOCAB_COL ){ |
- while( pCsr->aCnt[pCsr->iCol]==0 ) pCsr->iCol++; |
- assert( pCsr->iCol<pCsr->pConfig->nCol ); |
- } |
- return rc; |
-} |
- |
-/* |
-** This is the xFilter implementation for the virtual table. |
-*/ |
-static int fts5VocabFilterMethod( |
- sqlite3_vtab_cursor *pCursor, /* The cursor used for this query */ |
- int idxNum, /* Strategy index */ |
- const char *idxStr, /* Unused */ |
- int nVal, /* Number of elements in apVal */ |
- sqlite3_value **apVal /* Arguments for the indexing scheme */ |
-){ |
- Fts5VocabCursor *pCsr = (Fts5VocabCursor*)pCursor; |
- int rc = SQLITE_OK; |
- |
- int iVal = 0; |
- int f = FTS5INDEX_QUERY_SCAN; |
- const char *zTerm = 0; |
- int nTerm = 0; |
- |
- sqlite3_value *pEq = 0; |
- sqlite3_value *pGe = 0; |
- sqlite3_value *pLe = 0; |
- |
- fts5VocabResetCursor(pCsr); |
- if( idxNum & FTS5_VOCAB_TERM_EQ ) pEq = apVal[iVal++]; |
- if( idxNum & FTS5_VOCAB_TERM_GE ) pGe = apVal[iVal++]; |
- if( idxNum & FTS5_VOCAB_TERM_LE ) pLe = apVal[iVal++]; |
- |
- if( pEq ){ |
- zTerm = (const char *)sqlite3_value_text(pEq); |
- nTerm = sqlite3_value_bytes(pEq); |
- f = 0; |
- }else{ |
- if( pGe ){ |
- zTerm = (const char *)sqlite3_value_text(pGe); |
- nTerm = sqlite3_value_bytes(pGe); |
- } |
- if( pLe ){ |
- const char *zCopy = (const char *)sqlite3_value_text(pLe); |
- pCsr->nLeTerm = sqlite3_value_bytes(pLe); |
- pCsr->zLeTerm = sqlite3_malloc(pCsr->nLeTerm+1); |
- if( pCsr->zLeTerm==0 ){ |
- rc = SQLITE_NOMEM; |
- }else{ |
- memcpy(pCsr->zLeTerm, zCopy, pCsr->nLeTerm+1); |
- } |
- } |
- } |
- |
- |
- if( rc==SQLITE_OK ){ |
- rc = sqlite3Fts5IndexQuery(pCsr->pIndex, zTerm, nTerm, f, 0, &pCsr->pIter); |
- } |
- if( rc==SQLITE_OK ){ |
- rc = fts5VocabNextMethod(pCursor); |
- } |
- |
- return rc; |
-} |
- |
-/* |
-** This is the xEof method of the virtual table. SQLite calls this |
-** routine to find out if it has reached the end of a result set. |
-*/ |
-static int fts5VocabEofMethod(sqlite3_vtab_cursor *pCursor){ |
- Fts5VocabCursor *pCsr = (Fts5VocabCursor*)pCursor; |
- return pCsr->bEof; |
-} |
- |
-static int fts5VocabColumnMethod( |
- sqlite3_vtab_cursor *pCursor, /* Cursor to retrieve value from */ |
- sqlite3_context *pCtx, /* Context for sqlite3_result_xxx() calls */ |
- int iCol /* Index of column to read value from */ |
-){ |
- Fts5VocabCursor *pCsr = (Fts5VocabCursor*)pCursor; |
- |
- if( iCol==0 ){ |
- sqlite3_result_text( |
- pCtx, (const char*)pCsr->term.p, pCsr->term.n, SQLITE_TRANSIENT |
- ); |
- } |
- else if( ((Fts5VocabTable*)(pCursor->pVtab))->eType==FTS5_VOCAB_COL ){ |
- assert( iCol==1 || iCol==2 || iCol==3 ); |
- if( iCol==1 ){ |
- const char *z = pCsr->pConfig->azCol[pCsr->iCol]; |
- sqlite3_result_text(pCtx, z, -1, SQLITE_STATIC); |
- }else if( iCol==2 ){ |
- sqlite3_result_int64(pCtx, pCsr->aDoc[pCsr->iCol]); |
- }else{ |
- sqlite3_result_int64(pCtx, pCsr->aCnt[pCsr->iCol]); |
- } |
- }else{ |
- assert( iCol==1 || iCol==2 ); |
- if( iCol==1 ){ |
- sqlite3_result_int64(pCtx, pCsr->aDoc[0]); |
- }else{ |
- sqlite3_result_int64(pCtx, pCsr->aCnt[0]); |
- } |
- } |
- return SQLITE_OK; |
-} |
- |
-/* |
-** This is the xRowid method. The SQLite core calls this routine to |
-** retrieve the rowid for the current row of the result set. The |
-** rowid should be written to *pRowid. |
-*/ |
-static int fts5VocabRowidMethod( |
- sqlite3_vtab_cursor *pCursor, |
- sqlite_int64 *pRowid |
-){ |
- Fts5VocabCursor *pCsr = (Fts5VocabCursor*)pCursor; |
- *pRowid = pCsr->rowid; |
- return SQLITE_OK; |
-} |
- |
-int sqlite3Fts5VocabInit(Fts5Global *pGlobal, sqlite3 *db){ |
- static const sqlite3_module fts5Vocab = { |
- /* iVersion */ 2, |
- /* xCreate */ fts5VocabCreateMethod, |
- /* xConnect */ fts5VocabConnectMethod, |
- /* xBestIndex */ fts5VocabBestIndexMethod, |
- /* xDisconnect */ fts5VocabDisconnectMethod, |
- /* xDestroy */ fts5VocabDestroyMethod, |
- /* xOpen */ fts5VocabOpenMethod, |
- /* xClose */ fts5VocabCloseMethod, |
- /* xFilter */ fts5VocabFilterMethod, |
- /* xNext */ fts5VocabNextMethod, |
- /* xEof */ fts5VocabEofMethod, |
- /* xColumn */ fts5VocabColumnMethod, |
- /* xRowid */ fts5VocabRowidMethod, |
- /* xUpdate */ 0, |
- /* xBegin */ 0, |
- /* xSync */ 0, |
- /* xCommit */ 0, |
- /* xRollback */ 0, |
- /* xFindFunction */ 0, |
- /* xRename */ 0, |
- /* xSavepoint */ 0, |
- /* xRelease */ 0, |
- /* xRollbackTo */ 0, |
- }; |
- void *p = (void*)pGlobal; |
- |
- return sqlite3_create_module_v2(db, "fts5vocab", &fts5Vocab, p, 0); |
-} |
- |
- |