/ Check-in [0147d973]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Add missing file fts3_aux.c.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | fts4aux
Files: files | file ages | folders
SHA1:0147d9739f318a02721d3ae0e7be339a19231f60
User & Date: dan 2011-02-02 04:26:46
Context
2011-02-02
04:40
Merge fts4aux branch. check-in: c6d9f7d8 user: dan tags: trunk
04:26
Add missing file fts3_aux.c. Closed-Leaf check-in: 0147d973 user: dan tags: fts4aux
2011-02-01
18:59
Remove extra instances of the text "checked out." from sqlite.h.in. Also add new file fts3_aux.c to mksqlite3c.tcl. check-in: 9897da22 user: dan tags: fts4aux
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Added ext/fts3/fts3_aux.c.

            1  +/*
            2  +** 2011 Jan 27
            3  +**
            4  +** The author disclaims copyright to this source code.  In place of
            5  +** a legal notice, here is a blessing:
            6  +**
            7  +**    May you do good and not evil.
            8  +**    May you find forgiveness for yourself and forgive others.
            9  +**    May you share freely, never taking more than you give.
           10  +**
           11  +******************************************************************************
           12  +**
           13  +*/
           14  +
           15  +#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3)
           16  +
           17  +#include "fts3Int.h"
           18  +#include <string.h>
           19  +#include <assert.h>
           20  +
           21  +typedef struct Fts3auxTable Fts3auxTable;
           22  +typedef struct Fts3auxCursor Fts3auxCursor;
           23  +
           24  +struct Fts3auxTable {
           25  +  sqlite3_vtab base;              /* Base class used by SQLite core */
           26  +  Fts3Table *pFts3Tab;
           27  +};
           28  +
           29  +struct Fts3auxCursor {
           30  +  sqlite3_vtab_cursor base;       /* Base class used by SQLite core */
           31  +
           32  +  Fts3SegFilter filter;
           33  +  Fts3SegReaderCursor csr;
           34  +  int isEof;
           35  +
           36  +  sqlite3_int64 iRowid;
           37  +  sqlite3_int64 nDoc;
           38  +  sqlite3_int64 nOcc;
           39  +};
           40  +
           41  +/*
           42  +** Schema of the terms table.
           43  +*/
           44  +#define FTS3_TERMS_SCHEMA "CREATE TABLE x(term, documents, occurrences)"
           45  +
           46  +/*
           47  +** This function does all the work for both the xConnect and xCreate methods.
           48  +** These tables have no persistent representation of their own, so xConnect
           49  +** and xCreate are identical operations.
           50  +*/
           51  +static int fts3auxConnectMethod(
           52  +  sqlite3 *db,                    /* Database connection */
           53  +  void *pUnused,                  /* Unused */
           54  +  int argc,                       /* Number of elements in argv array */
           55  +  const char * const *argv,       /* xCreate/xConnect argument array */
           56  +  sqlite3_vtab **ppVtab,          /* OUT: New sqlite3_vtab object */
           57  +  char **pzErr                    /* OUT: sqlite3_malloc'd error message */
           58  +){
           59  +  char const *zDb;                /* Name of database (e.g. "main") */
           60  +  char const *zFts3;              /* Name of fts3 table */
           61  +  int nDb;                        /* Result of strlen(zDb) */
           62  +  int nFts3;                      /* Result of strlen(zFts3) */
           63  +  int nByte;                      /* Bytes of space to allocate here */
           64  +  int rc;                         /* value returned by declare_vtab() */
           65  +  Fts3auxTable *p;                /* Virtual table object to return */
           66  +
           67  +  /* The user should specify a single argument - the name of an fts3 table. */
           68  +  if( argc!=4 ){
           69  +    *pzErr = sqlite3_mprintf("wrong number of arguments");
           70  +    return SQLITE_ERROR;
           71  +  }
           72  +
           73  +  zDb = argv[1]; 
           74  +  nDb = strlen(zDb);
           75  +  zFts3 = argv[3];
           76  +  nFts3 = strlen(zFts3);
           77  +
           78  +  rc = sqlite3_declare_vtab(db, FTS3_TERMS_SCHEMA);
           79  +  if( rc!=SQLITE_OK ) return rc;
           80  +
           81  +  nByte = sizeof(Fts3auxTable) + sizeof(Fts3Table) + nDb + nFts3 + 2;
           82  +  p = (Fts3auxTable *)sqlite3_malloc(nByte);
           83  +  if( !p ) return SQLITE_NOMEM;
           84  +  memset(p, 0, nByte);
           85  +
           86  +  p->pFts3Tab = (Fts3Table *)&p[1];
           87  +  p->pFts3Tab->zDb = (char *)&p->pFts3Tab[1];
           88  +  p->pFts3Tab->zName = &p->pFts3Tab->zDb[nDb+1];
           89  +  p->pFts3Tab->db = db;
           90  +
           91  +  memcpy((char *)p->pFts3Tab->zDb, zDb, nDb);
           92  +  memcpy((char *)p->pFts3Tab->zName, zFts3, nFts3);
           93  +
           94  +  *ppVtab = (sqlite3_vtab *)p;
           95  +  return SQLITE_OK;
           96  +}
           97  +
           98  +/*
           99  +** This function does the work for both the xDisconnect and xDestroy methods.
          100  +** These tables have no persistent representation of their own, so xDisconnect
          101  +** and xDestroy are identical operations.
          102  +*/
          103  +static int fts3auxDisconnectMethod(sqlite3_vtab *pVtab){
          104  +  Fts3auxTable *p = (Fts3auxTable *)pVtab;
          105  +  Fts3Table *pFts3 = p->pFts3Tab;
          106  +  int i;
          107  +
          108  +  /* Free any prepared statements held */
          109  +  for(i=0; i<SizeofArray(pFts3->aStmt); i++){
          110  +    sqlite3_finalize(pFts3->aStmt[i]);
          111  +  }
          112  +  sqlite3_free(pFts3->zSegmentsTbl);
          113  +  sqlite3_free(p);
          114  +  return SQLITE_OK;
          115  +}
          116  +
          117  +/*
          118  +** xBestIndex - Analyze a WHERE and ORDER BY clause.
          119  +*/
          120  +static int fts3auxBestIndexMethod(
          121  +  sqlite3_vtab *pVTab, 
          122  +  sqlite3_index_info *pInfo
          123  +){
          124  +
          125  +  /* This vtab delivers always results in "ORDER BY term ASC" order. */
          126  +  if( pInfo->nOrderBy==1 
          127  +   && pInfo->aOrderBy[0].iColumn==0 
          128  +   && pInfo->aOrderBy[0].desc==0
          129  +  ){
          130  +    pInfo->orderByConsumed = 1;
          131  +  }
          132  +
          133  +  pInfo->estimatedCost = 20000;
          134  +  return SQLITE_OK;
          135  +}
          136  +
          137  +/*
          138  +** xOpen - Open a cursor.
          139  +*/
          140  +static int fts3auxOpenMethod(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCsr){
          141  +  Fts3auxCursor *pCsr;            /* Pointer to cursor object to return */
          142  +
          143  +  pCsr = (Fts3auxCursor *)sqlite3_malloc(sizeof(Fts3auxCursor));
          144  +  if( !pCsr ) return SQLITE_NOMEM;
          145  +  memset(pCsr, 0, sizeof(Fts3auxCursor));
          146  +
          147  +  *ppCsr = (sqlite3_vtab_cursor *)pCsr;
          148  +  return SQLITE_OK;
          149  +}
          150  +
          151  +/*
          152  +** xClose - Close a cursor.
          153  +*/
          154  +static int fts3auxCloseMethod(sqlite3_vtab_cursor *pCursor){
          155  +  Fts3Table *pFts3 = ((Fts3auxTable *)pCursor->pVtab)->pFts3Tab;
          156  +  Fts3auxCursor *pCsr = (Fts3auxCursor *)pCursor;
          157  +
          158  +  sqlite3Fts3SegmentsClose(pFts3);
          159  +  sqlite3Fts3SegReaderFinish(&pCsr->csr);
          160  +  sqlite3_free(pCsr);
          161  +  return SQLITE_OK;
          162  +}
          163  +
          164  +/*
          165  +** xNext - Advance the cursor to the next row, if any.
          166  +*/
          167  +static int fts3auxNextMethod(sqlite3_vtab_cursor *pCursor){
          168  +  Fts3auxCursor *pCsr = (Fts3auxCursor *)pCursor;
          169  +  Fts3Table *pFts3 = ((Fts3auxTable *)pCursor->pVtab)->pFts3Tab;
          170  +  int rc;
          171  +
          172  +  rc = sqlite3Fts3SegReaderStep(pFts3, &pCsr->csr);
          173  +  if( rc==SQLITE_ROW ){
          174  +    int i;
          175  +    int isIgnore = 1;
          176  +    int nDoclist = pCsr->csr.nDoclist;
          177  +    char *aDoclist = pCsr->csr.aDoclist;
          178  +
          179  +    /* Now count the number of documents and positions in the doclist
          180  +    ** in pCsr->csr.aDoclist[]. Store the number of documents in pCsr->nDoc
          181  +    ** and the number of occurrences in pCsr->nOcc.  */
          182  +    pCsr->nDoc = 0;
          183  +    pCsr->nOcc = 0;
          184  +    i = 0;
          185  +    while( i<nDoclist ){
          186  +      sqlite3_int64 v = 0;
          187  +      i += sqlite3Fts3GetVarint(&aDoclist[i], &v);
          188  +      if( isIgnore ){
          189  +        isIgnore = 0;
          190  +      }else if( v>1 ){
          191  +        pCsr->nOcc++;
          192  +      }else{
          193  +        if( v==0 ) pCsr->nDoc++;
          194  +        isIgnore = 1;
          195  +      }
          196  +    }
          197  +
          198  +    rc = SQLITE_OK;
          199  +    pCsr->iRowid++;
          200  +  }else{
          201  +    pCsr->isEof = 1;
          202  +  }
          203  +  return rc;
          204  +}
          205  +
          206  +/*
          207  +** xFilter - Initialize a cursor to point at the start of its data.
          208  +*/
          209  +static int fts3auxFilterMethod(
          210  +  sqlite3_vtab_cursor *pCursor,   /* The cursor used for this query */
          211  +  int idxNum,                     /* Strategy index */
          212  +  const char *idxStr,             /* Unused */
          213  +  int nVal,                       /* Number of elements in apVal */
          214  +  sqlite3_value **apVal           /* Arguments for the indexing scheme */
          215  +){
          216  +  Fts3auxCursor *pCsr = (Fts3auxCursor *)pCursor;
          217  +  Fts3Table *pFts3 = ((Fts3auxTable *)pCursor->pVtab)->pFts3Tab;
          218  +  int rc;
          219  +
          220  +  sqlite3Fts3SegReaderFinish(&pCsr->csr);
          221  +  memset(&pCsr->csr, 0, sizeof(Fts3SegReaderCursor));
          222  +  pCsr->isEof = 0;
          223  +  pCsr->iRowid = 0;
          224  +  pCsr->filter.flags = FTS3_SEGMENT_REQUIRE_POS|FTS3_SEGMENT_IGNORE_EMPTY;
          225  +
          226  +  rc = sqlite3Fts3SegReaderCursor(pFts3, FTS3_SEGCURSOR_ALL, 0, 0,1,&pCsr->csr);
          227  +  if( rc==SQLITE_OK ){
          228  +    rc = sqlite3Fts3SegReaderStart(pFts3, &pCsr->csr, &pCsr->filter);
          229  +  }
          230  +
          231  +  if( rc==SQLITE_OK ) rc = fts3auxNextMethod(pCursor);
          232  +  return rc;
          233  +}
          234  +
          235  +/*
          236  +** xEof - Return true if the cursor is at EOF, or false otherwise.
          237  +*/
          238  +static int fts3auxEofMethod(sqlite3_vtab_cursor *pCursor){
          239  +  Fts3auxCursor *pCsr = (Fts3auxCursor *)pCursor;
          240  +  return pCsr->isEof;
          241  +}
          242  +
          243  +/*
          244  +** xColumn - Return a column value.
          245  +*/
          246  +static int fts3auxColumnMethod(
          247  +  sqlite3_vtab_cursor *pCursor,   /* Cursor to retrieve value from */
          248  +  sqlite3_context *pContext,      /* Context for sqlite3_result_xxx() calls */
          249  +  int iCol                        /* Index of column to read value from */
          250  +){
          251  +  Fts3auxCursor *p = (Fts3auxCursor *)pCursor;
          252  +
          253  +  assert( p->isEof==0 );
          254  +  if( iCol==0 ){        /* Column "term" */
          255  +    sqlite3_result_text(pContext, p->csr.zTerm, p->csr.nTerm, SQLITE_TRANSIENT);
          256  +  }else if( iCol==1 ){  /* Column "documents" */
          257  +    sqlite3_result_int64(pContext, p->nDoc);
          258  +  }else{                /* Column "occurrences" */
          259  +    sqlite3_result_int64(pContext, p->nOcc);
          260  +  }
          261  +
          262  +  return SQLITE_OK;
          263  +}
          264  +
          265  +/*
          266  +** xRowid - Return the current rowid for the cursor.
          267  +*/
          268  +static int fts3auxRowidMethod(
          269  +  sqlite3_vtab_cursor *pCursor,   /* Cursor to retrieve value from */
          270  +  sqlite_int64 *pRowid            /* OUT: Rowid value */
          271  +){
          272  +  Fts3auxCursor *pCsr = (Fts3auxCursor *)pCursor;
          273  +  *pRowid = pCsr->iRowid;
          274  +  return SQLITE_OK;
          275  +}
          276  +
          277  +/*
          278  +** Register the fts3aux module with database connection db. Return SQLITE_OK
          279  +** if successful or an error code if sqlite3_create_module() fails.
          280  +*/
          281  +int sqlite3Fts3InitAux(sqlite3 *db){
          282  +  static const sqlite3_module fts3aux_module = {
          283  +     0,                           /* iVersion      */
          284  +     fts3auxConnectMethod,        /* xCreate       */
          285  +     fts3auxConnectMethod,        /* xConnect      */
          286  +     fts3auxBestIndexMethod,      /* xBestIndex    */
          287  +     fts3auxDisconnectMethod,     /* xDisconnect   */
          288  +     fts3auxDisconnectMethod,     /* xDestroy      */
          289  +     fts3auxOpenMethod,           /* xOpen         */
          290  +     fts3auxCloseMethod,          /* xClose        */
          291  +     fts3auxFilterMethod,         /* xFilter       */
          292  +     fts3auxNextMethod,           /* xNext         */
          293  +     fts3auxEofMethod,            /* xEof          */
          294  +     fts3auxColumnMethod,         /* xColumn       */
          295  +     fts3auxRowidMethod,          /* xRowid        */
          296  +     0,                           /* xUpdate       */
          297  +     0,                           /* xBegin        */
          298  +     0,                           /* xSync         */
          299  +     0,                           /* xCommit       */
          300  +     0,                           /* xRollback     */
          301  +     0,                           /* xFindFunction */
          302  +     0                            /* xRename       */
          303  +  };
          304  +  int rc;                         /* Return code */
          305  +
          306  +  rc = sqlite3_create_module(db, "fts4aux", &fts3aux_module, 0);
          307  +  return rc;
          308  +}
          309  +
          310  +#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */