15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 2009 Nov 12
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The author disclaims copyright to this source code.  In place of
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** a legal notice, here is a blessing:
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**    May you do good and not evil.
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**    May you find forgiveness for yourself and forgive others.
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**    May you share freely, never taking more than you give.
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)******************************************************************************
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef _FTSINT_H
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define _FTSINT_H
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(NDEBUG) && !defined(SQLITE_DEBUG)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# define NDEBUG 1
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sqlite3.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "fts3_tokenizer.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "fts3_hash.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** This constant controls how often segments are merged. Once there are
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** FTS3_MERGE_COUNT segments of level N, they are merged into a single
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** segment of level N+1.
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define FTS3_MERGE_COUNT 16
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** This is the maximum amount of data (in bytes) to store in the
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Fts3Table.pendingTerms hash table. Normally, the hash table is
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** populated as documents are inserted/updated/deleted in a transaction
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** and used to create a new segment when the transaction is committed.
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** However if this limit is reached midway through a transaction, a new
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** segment is created and the hash table cleared immediately.
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define FTS3_MAX_PENDING_DATA (1*1024*1024)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Macro to return the number of elements in an array. SQLite has a
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** similar macro called ArraySize(). Use a different name to avoid
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** a collision when building an amalgamation with built-in FTS3.
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SizeofArray(X) ((int)(sizeof(X)/sizeof(X[0])))
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Maximum length of a varint encoded integer. The varint format is different
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** from that used by SQLite, so the maximum length is 10, not 9.
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define FTS3_VARINT_MAX 10
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The testcase() macro is only used by the amalgamation.  If undefined,
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** make it a no-op.
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef testcase
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# define testcase(X)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Terminator values for position-lists and column-lists.
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define POS_COLUMN  (1)     /* Column-list terminator */
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define POS_END     (0)     /* Position-list terminator */
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** This section provides definitions to allow the
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** FTS3 extension to be compiled outside of the
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** amalgamation.
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef SQLITE_AMALGAMATION
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Macros indicating that conditional expressions are always true or
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** false.
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef SQLITE_COVERAGE_TEST
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# define ALWAYS(x) (1)
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# define NEVER(X)  (0)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# define ALWAYS(x) (x)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# define NEVER(X)  (x)
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Internal types used by SQLite.
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef unsigned char u8;         /* 1-byte (or larger) unsigned integer */
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef short int i16;            /* 2-byte (or larger) signed integer */
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef unsigned int u32;         /* 4-byte unsigned integer */
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef sqlite3_uint64 u64;       /* 8-byte unsigned integer */
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Macro used to suppress compiler warnings for unused parameters.
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define UNUSED_PARAMETER(x) (void)(x)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct Fts3Table Fts3Table;
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct Fts3Cursor Fts3Cursor;
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct Fts3Expr Fts3Expr;
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct Fts3Phrase Fts3Phrase;
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct Fts3PhraseToken Fts3PhraseToken;
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct Fts3SegFilter Fts3SegFilter;
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct Fts3DeferredToken Fts3DeferredToken;
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct Fts3SegReader Fts3SegReader;
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct Fts3SegReaderCursor Fts3SegReaderCursor;
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** A connection to a fulltext index is an instance of the following
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** structure. The xCreate and xConnect methods create an instance
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** of this structure and xDestroy and xDisconnect free that instance.
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** All other methods receive a pointer to the structure as one of their
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** arguments.
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct Fts3Table {
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_vtab base;              /* Base class used by SQLite core */
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3 *db;                    /* The database connection */
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char *zDb;                /* logical database name */
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char *zName;              /* virtual table name */
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int nColumn;                    /* number of named columns in virtual table */
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char **azColumn;                /* column names.  malloced */
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_tokenizer *pTokenizer;  /* tokenizer for inserts and queries */
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /* Precompiled statements used by the implementation. Each of these
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ** statements is run and reset within a single virtual table API call.
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  */
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_stmt *aStmt[24];
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char *zReadExprlist;
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char *zWriteExprlist;
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int nNodeSize;                  /* Soft limit for node size */
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  u8 bHasStat;                    /* True if %_stat table exists */
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  u8 bHasDocsize;                 /* True if %_docsize table exists */
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int nPgsz;                      /* Page size for host database */
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char *zSegmentsTbl;             /* Name of %_segments table */
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_blob *pSegments;        /* Blob handle open on %_segments table */
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /* The following hash table is used to buffer pending index updates during
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ** transactions. Variable nPendingData estimates the memory size of the
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ** pending data, including hash table overhead, but not malloc overhead.
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ** When nPendingData exceeds nMaxPendingData, the buffer is flushed
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ** automatically. Variable iPrevDocid is the docid of the most recently
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ** inserted record.
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  */
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int nMaxPendingData;
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int nPendingData;
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite_int64 iPrevDocid;
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Fts3Hash pendingTerms;
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** When the core wants to read from the virtual table, it creates a
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** virtual table cursor (an instance of the following structure) using
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** the xOpen method. Cursors are destroyed using the xClose method.
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct Fts3Cursor {
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_vtab_cursor base;       /* Base class used by SQLite core */
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  i16 eSearch;                    /* Search strategy (see below) */
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  u8 isEof;                       /* True if at End Of Results */
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  u8 isRequireSeek;               /* True if must seek pStmt to %_content row */
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_stmt *pStmt;            /* Prepared statement in use by the cursor */
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Fts3Expr *pExpr;                /* Parsed MATCH query string */
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int nPhrase;                    /* Number of matchable phrases in query */
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Fts3DeferredToken *pDeferred;   /* Deferred search tokens, if any */
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_int64 iPrevId;          /* Previous id read from aDoclist */
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char *pNextId;                  /* Pointer into the body of aDoclist */
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char *aDoclist;                 /* List of docids for full-text queries */
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int nDoclist;                   /* Size of buffer at aDoclist */
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int eEvalmode;                  /* An FTS3_EVAL_XX constant */
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int nRowAvg;                    /* Average size of database rows, in pages */
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int isMatchinfoNeeded;          /* True when aMatchinfo[] needs filling in */
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  u32 *aMatchinfo;                /* Information about most recent match */
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int nMatchinfo;                 /* Number of elements in aMatchinfo[] */
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char *zMatchinfo;               /* Matchinfo specification */
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define FTS3_EVAL_FILTER    0
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define FTS3_EVAL_NEXT      1
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define FTS3_EVAL_MATCHINFO 2
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The Fts3Cursor.eSearch member is always set to one of the following.
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Actualy, Fts3Cursor.eSearch can be greater than or equal to
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** FTS3_FULLTEXT_SEARCH.  If so, then Fts3Cursor.eSearch - 2 is the index
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** of the column to be searched.  For example, in
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**     CREATE VIRTUAL TABLE ex1 USING fts3(a,b,c,d);
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**     SELECT docid FROM ex1 WHERE b MATCH 'one two three';
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Because the LHS of the MATCH operator is 2nd column "b",
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Fts3Cursor.eSearch will be set to FTS3_FULLTEXT_SEARCH+1.  (+0 for a,
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** +1 for b, +2 for c, +3 for d.)  If the LHS of MATCH were "ex1"
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** indicating that all columns should be searched,
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** then eSearch would be set to FTS3_FULLTEXT_SEARCH+4.
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define FTS3_FULLSCAN_SEARCH 0    /* Linear scan of %_content table */
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define FTS3_DOCID_SEARCH    1    /* Lookup by rowid on %_content table */
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define FTS3_FULLTEXT_SEARCH 2    /* Full-text index search */
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** A "phrase" is a sequence of one or more tokens that must match in
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** sequence.  A single token is the base case and the most common case.
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** For a sequence of tokens contained in double-quotes (i.e. "one two three")
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** nToken will be the number of tokens in the string.
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The nDocMatch and nMatch variables contain data that may be used by the
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** matchinfo() function. They are populated when the full-text index is
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** queried for hits on the phrase. If one or more tokens in the phrase
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** are deferred, the nDocMatch and nMatch variables are populated based
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** on the assumption that the
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct Fts3PhraseToken {
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char *z;                        /* Text of the token */
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int n;                          /* Number of bytes in buffer z */
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int isPrefix;                   /* True if token ends with a "*" character */
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int bFulltext;                  /* True if full-text index was used */
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Fts3SegReaderCursor *pSegcsr;   /* Segment-reader for this token */
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Fts3DeferredToken *pDeferred;   /* Deferred token object for this token */
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct Fts3Phrase {
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /* Variables populated by fts3_expr.c when parsing a MATCH expression */
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int nToken;                /* Number of tokens in the phrase */
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int iColumn;               /* Index of column this phrase must match */
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int isNot;                 /* Phrase prefixed by unary not (-) operator */
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Fts3PhraseToken aToken[1]; /* One entry for each token in the phrase */
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** A tree of these objects forms the RHS of a MATCH operator.
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** If Fts3Expr.eType is either FTSQUERY_NEAR or FTSQUERY_PHRASE and isLoaded
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** is true, then aDoclist points to a malloced buffer, size nDoclist bytes,
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** containing the results of the NEAR or phrase query in FTS3 doclist
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** format. As usual, the initial "Length" field found in doclists stored
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** on disk is omitted from this buffer.
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Variable pCurrent always points to the start of a docid field within
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** aDoclist. Since the doclist is usually scanned in docid order, this can
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** be used to accelerate seeking to the required docid within the doclist.
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct Fts3Expr {
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int eType;                 /* One of the FTSQUERY_XXX values defined below */
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int nNear;                 /* Valid if eType==FTSQUERY_NEAR */
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Fts3Expr *pParent;         /* pParent->pLeft==this or pParent->pRight==this */
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Fts3Expr *pLeft;           /* Left operand */
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Fts3Expr *pRight;          /* Right operand */
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Fts3Phrase *pPhrase;       /* Valid if eType==FTSQUERY_PHRASE */
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int isLoaded;              /* True if aDoclist/nDoclist are initialized. */
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char *aDoclist;            /* Buffer containing doclist */
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int nDoclist;              /* Size of aDoclist in bytes */
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_int64 iCurrent;
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char *pCurrent;
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Candidate values for Fts3Query.eType. Note that the order of the first
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** four values is in order of precedence when parsing expressions. For
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** example, the following:
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**   "a OR b AND c NOT d NEAR e"
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** is equivalent to:
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**   "a OR (b AND (c NOT (d NEAR e)))"
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define FTSQUERY_NEAR   1
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define FTSQUERY_NOT    2
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define FTSQUERY_AND    3
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define FTSQUERY_OR     4
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define FTSQUERY_PHRASE 5
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* fts3_write.c */
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int sqlite3Fts3UpdateMethod(sqlite3_vtab*,int,sqlite3_value**,sqlite3_int64*);
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int sqlite3Fts3PendingTermsFlush(Fts3Table *);
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void sqlite3Fts3PendingTermsClear(Fts3Table *);
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int sqlite3Fts3Optimize(Fts3Table *);
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int sqlite3Fts3SegReaderNew(int, sqlite3_int64,
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_int64, sqlite3_int64, const char *, int, Fts3SegReader**);
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int sqlite3Fts3SegReaderPending(Fts3Table*,const char*,int,int,Fts3SegReader**);
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void sqlite3Fts3SegReaderFree(Fts3SegReader *);
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int sqlite3Fts3SegReaderCost(Fts3Cursor *, Fts3SegReader *, int *);
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int sqlite3Fts3AllSegdirs(Fts3Table*, int, sqlite3_stmt **);
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int sqlite3Fts3ReadLock(Fts3Table *);
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int sqlite3Fts3ReadBlock(Fts3Table*, sqlite3_int64, char **, int*);
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int sqlite3Fts3SelectDoctotal(Fts3Table *, sqlite3_stmt **);
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int sqlite3Fts3SelectDocsize(Fts3Table *, sqlite3_int64, sqlite3_stmt **);
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void sqlite3Fts3FreeDeferredTokens(Fts3Cursor *);
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int sqlite3Fts3DeferToken(Fts3Cursor *, Fts3PhraseToken *, int);
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int sqlite3Fts3CacheDeferredDoclists(Fts3Cursor *);
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void sqlite3Fts3FreeDeferredDoclists(Fts3Cursor *);
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)char *sqlite3Fts3DeferredDoclist(Fts3DeferredToken *, int *);
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void sqlite3Fts3SegmentsClose(Fts3Table *);
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define FTS3_SEGCURSOR_PENDING -1
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define FTS3_SEGCURSOR_ALL     -2
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int sqlite3Fts3SegReaderStart(Fts3Table*, Fts3SegReaderCursor*, Fts3SegFilter*);
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int sqlite3Fts3SegReaderStep(Fts3Table *, Fts3SegReaderCursor *);
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void sqlite3Fts3SegReaderFinish(Fts3SegReaderCursor *);
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int sqlite3Fts3SegReaderCursor(
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Fts3Table *, int, const char *, int, int, int, Fts3SegReaderCursor *);
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Flags allowed as part of the 4th argument to SegmentReaderIterate() */
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define FTS3_SEGMENT_REQUIRE_POS   0x00000001
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define FTS3_SEGMENT_IGNORE_EMPTY  0x00000002
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define FTS3_SEGMENT_COLUMN_FILTER 0x00000004
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define FTS3_SEGMENT_PREFIX        0x00000008
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define FTS3_SEGMENT_SCAN          0x00000010
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Type passed as 4th argument to SegmentReaderIterate() */
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct Fts3SegFilter {
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char *zTerm;
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int nTerm;
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int iCol;
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int flags;
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct Fts3SegReaderCursor {
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /* Used internally by sqlite3Fts3SegReaderXXX() calls */
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Fts3SegReader **apSegment;      /* Array of Fts3SegReader objects */
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int nSegment;                   /* Size of apSegment array */
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int nAdvance;                   /* How many seg-readers to advance */
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Fts3SegFilter *pFilter;         /* Pointer to filter object */
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char *aBuffer;                  /* Buffer to merge doclists in */
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int nBuffer;                    /* Allocated size of aBuffer[] in bytes */
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /* Cost of running this iterator. Used by fts3.c only. */
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int nCost;
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /* Output values. Valid only after Fts3SegReaderStep() returns SQLITE_ROW. */
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char *zTerm;                    /* Pointer to term buffer */
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int nTerm;                      /* Size of zTerm in bytes */
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char *aDoclist;                 /* Pointer to doclist buffer */
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int nDoclist;                   /* Size of aDoclist[] in bytes */
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* fts3.c */
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int sqlite3Fts3PutVarint(char *, sqlite3_int64);
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int sqlite3Fts3GetVarint(const char *, sqlite_int64 *);
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int sqlite3Fts3GetVarint32(const char *, int *);
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int sqlite3Fts3VarintLen(sqlite3_uint64);
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void sqlite3Fts3Dequote(char *);
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)char *sqlite3Fts3FindPositions(Fts3Expr *, sqlite3_int64, int);
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int sqlite3Fts3ExprLoadDoclist(Fts3Cursor *, Fts3Expr *);
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int sqlite3Fts3ExprLoadFtDoclist(Fts3Cursor *, Fts3Expr *, char **, int *);
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int sqlite3Fts3ExprNearTrim(Fts3Expr *, Fts3Expr *, int);
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* fts3_tokenizer.c */
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char *sqlite3Fts3NextToken(const char *, int *);
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int sqlite3Fts3InitHashTable(sqlite3 *, Fts3Hash *, const char *);
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int sqlite3Fts3InitTokenizer(Fts3Hash *pHash, const char *,
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3_tokenizer **, char **
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles));
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int sqlite3Fts3IsIdChar(char);
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* fts3_snippet.c */
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void sqlite3Fts3Offsets(sqlite3_context*, Fts3Cursor*);
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void sqlite3Fts3Snippet(sqlite3_context *, Fts3Cursor *, const char *,
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char *, const char *, int, int
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles));
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void sqlite3Fts3Matchinfo(sqlite3_context *, Fts3Cursor *, const char *);
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* fts3_expr.c */
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int sqlite3Fts3ExprParse(sqlite3_tokenizer *,
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char **, int, int, const char *, int, Fts3Expr **
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles));
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void sqlite3Fts3ExprFree(Fts3Expr *);
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef SQLITE_TEST
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int sqlite3Fts3ExprInitTestInterface(sqlite3 *db);
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* fts3_aux.c */
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int sqlite3Fts3InitAux(sqlite3 *db);
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* _FTSINT_H */
389