/ Check-in [8358af36]
Login

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

Overview
Comment:Add a debugging function to print human-readable versions of fts5 detail=none leaf pages.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 8358af3658d888516cdef5f8c8d89e9bdee53f91
User & Date: dan 2016-01-18 09:08:56
Context
2016-01-18
13:18
Avoid unnecessary calls to memset() for a small performance improvement. check-in: 9e8c23ac user: drh tags: trunk
09:08
Add a debugging function to print human-readable versions of fts5 detail=none leaf pages. check-in: 8358af36 user: dan tags: trunk
00:46
Simplification of the VDBE bytecode for incremental blob I/O. check-in: d23849f6 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to ext/fts5/fts5_index.c.

  5899   5899         iDocid += iDelta;
  5900   5900         sqlite3Fts5BufferAppendPrintf(pRc, pBuf, " id=%lld", iDocid);
  5901   5901       }
  5902   5902     }
  5903   5903   
  5904   5904     return iOff;
  5905   5905   }
         5906  +
         5907  +/*
         5908  +** This function is part of the fts5_decode() debugging function. It is 
         5909  +** only ever used with detail=none tables.
         5910  +**
         5911  +** Buffer (pData/nData) contains a doclist in the format used by detail=none
         5912  +** tables. This function appends a human-readable version of that list to
         5913  +** buffer pBuf.
         5914  +**
         5915  +** If *pRc is other than SQLITE_OK when this function is called, it is a
         5916  +** no-op. If an OOM or other error occurs within this function, *pRc is
         5917  +** set to an SQLite error code before returning. The final state of buffer
         5918  +** pBuf is undefined in this case.
         5919  +*/
         5920  +static void fts5DecodeRowidList(
         5921  +  int *pRc,                       /* IN/OUT: Error code */
         5922  +  Fts5Buffer *pBuf,               /* Buffer to append text to */
         5923  +  const u8 *pData, int nData      /* Data to decode list-of-rowids from */
         5924  +){
         5925  +  int i = 0;
         5926  +  i64 iRowid = 0;
         5927  +
         5928  +  while( i<nData ){
         5929  +    const char *zApp = "";
         5930  +    u64 iVal;
         5931  +    i += sqlite3Fts5GetVarint(&pData[i], &iVal);
         5932  +    iRowid += iVal;
         5933  +
         5934  +    if( i<nData && pData[i]==0x00 ){
         5935  +      i++;
         5936  +      if( i<nData && pData[i]==0x00 ){
         5937  +        i++;
         5938  +        zApp = "+";
         5939  +      }else{
         5940  +        zApp = "*";
         5941  +      }
         5942  +    }
         5943  +
         5944  +    sqlite3Fts5BufferAppendPrintf(pRc, pBuf, " %lld%s", iRowid, zApp);
         5945  +  }
         5946  +}
  5906   5947   
  5907   5948   /*
  5908   5949   ** The implementation of user-defined scalar function fts5_decode().
  5909   5950   */
  5910   5951   static void fts5DecodeFunction(
  5911   5952     sqlite3_context *pCtx,          /* Function call context */
  5912   5953     int nArg,                       /* Number of args (always 2) */
................................................................................
  5915   5956     i64 iRowid;                     /* Rowid for record being decoded */
  5916   5957     int iSegid,iHeight,iPgno,bDlidx;/* Rowid components */
  5917   5958     const u8 *aBlob; int n;         /* Record to decode */
  5918   5959     u8 *a = 0;
  5919   5960     Fts5Buffer s;                   /* Build up text to return here */
  5920   5961     int rc = SQLITE_OK;             /* Return code */
  5921   5962     int nSpace = 0;
         5963  +  int eDetailNone = (sqlite3_user_data(pCtx)!=0);
  5922   5964   
  5923   5965     assert( nArg==2 );
  5924   5966     memset(&s, 0, sizeof(Fts5Buffer));
  5925   5967     iRowid = sqlite3_value_int64(apVal[0]);
  5926   5968   
  5927   5969     /* Make a copy of the second argument (a blob) in aBlob[]. The aBlob[]
  5928   5970     ** copy is followed by FTS5_DATA_ZERO_PADDING 0x00 bytes, which prevents
................................................................................
  5956   5998       }
  5957   5999     }else if( iSegid==0 ){
  5958   6000       if( iRowid==FTS5_AVERAGES_ROWID ){
  5959   6001         fts5DecodeAverages(&rc, &s, a, n);
  5960   6002       }else{
  5961   6003         fts5DecodeStructure(&rc, &s, a, n);
  5962   6004       }
         6005  +  }else if( eDetailNone ){
         6006  +    Fts5Buffer term;              /* Current term read from page */
         6007  +    int szLeaf;
         6008  +    int iPgidxOff = szLeaf = fts5GetU16(&a[2]);
         6009  +    int iTermOff;
         6010  +    int nKeep = 0;
         6011  +    int iOff;
         6012  +
         6013  +    memset(&term, 0, sizeof(Fts5Buffer));
         6014  +
         6015  +    /* Decode any entries that occur before the first term. */
         6016  +    if( szLeaf<n ){
         6017  +      fts5FastGetVarint32(a, iPgidxOff, iTermOff);
         6018  +    }else{
         6019  +      iTermOff = szLeaf;
         6020  +    }
         6021  +    fts5DecodeRowidList(&rc, &s, &a[4], iTermOff-4);
         6022  +
         6023  +    iOff = iTermOff;
         6024  +    while( iOff<szLeaf ){
         6025  +      int nAppend;
         6026  +
         6027  +      /* Read the term data for the next term*/
         6028  +      fts5FastGetVarint32(a, iOff, nAppend);
         6029  +      term.n = nKeep;
         6030  +      fts5BufferAppendBlob(&rc, &term, nAppend, &a[iOff]);
         6031  +      sqlite3Fts5BufferAppendPrintf(
         6032  +          &rc, &s, " term=%.*s", term.n, (const char*)term.p
         6033  +      );
         6034  +      iOff += nAppend;
         6035  +
         6036  +      /* Figure out where the doclist for this term ends */
         6037  +      if( iPgidxOff<n ){
         6038  +        int nIncr;
         6039  +        fts5FastGetVarint32(a, iPgidxOff, nIncr);
         6040  +        iTermOff += nIncr;
         6041  +      }else{
         6042  +        iTermOff = szLeaf;
         6043  +      }
         6044  +
         6045  +      fts5DecodeRowidList(&rc, &s, &a[iOff], iTermOff-iOff);
         6046  +      iOff = iTermOff;
         6047  +      if( iOff<szLeaf ){
         6048  +        fts5FastGetVarint32(a, iOff, nKeep);
         6049  +      }
         6050  +    }
         6051  +
         6052  +    fts5BufferFree(&term);
  5963   6053     }else{
  5964   6054       Fts5Buffer term;              /* Current term read from page */
  5965   6055       int szLeaf;                   /* Offset of pgidx in a[] */
  5966   6056       int iPgidxOff;
  5967   6057       int iPgidxPrev = 0;           /* Previous value read from pgidx */
  5968   6058       int iTermOff = 0;
  5969   6059       int iRowidOff = 0;
................................................................................
  6083   6173   ** If successful, SQLITE_OK is returned. If an error occurs, some other
  6084   6174   ** SQLite error code is returned instead.
  6085   6175   */
  6086   6176   int sqlite3Fts5IndexInit(sqlite3 *db){
  6087   6177     int rc = sqlite3_create_function(
  6088   6178         db, "fts5_decode", 2, SQLITE_UTF8, 0, fts5DecodeFunction, 0, 0
  6089   6179     );
         6180  +
         6181  +  if( rc==SQLITE_OK ){
         6182  +    rc = sqlite3_create_function(
         6183  +        db, "fts5_decode_none", 2, 
         6184  +        SQLITE_UTF8, (void*)db, fts5DecodeFunction, 0, 0
         6185  +    );
         6186  +  }
         6187  +
  6090   6188     if( rc==SQLITE_OK ){
  6091   6189       rc = sqlite3_create_function(
  6092   6190           db, "fts5_rowid", -1, SQLITE_UTF8, 0, fts5RowidFunction, 0, 0
  6093   6191       );
  6094   6192     }
  6095   6193     return rc;
  6096   6194   }

Changes to ext/fts5/test/fts5_common.tcl.

    15     15   }
    16     16   source $testdir/tester.tcl
    17     17   
    18     18   catch { 
    19     19     sqlite3_fts5_may_be_corrupt 0 
    20     20     reset_db
    21     21   }
           22  +
           23  +# If SQLITE_ENABLE_FTS5 is not defined, skip this test.
           24  +ifcapable !fts5 {
           25  +  finish_test
           26  +  return
           27  +}
    22     28   
    23     29   proc fts5_test_poslist {cmd} {
    24     30     set res [list]
    25     31     for {set i 0} {$i < [$cmd xInstCount]} {incr i} {
    26     32       lappend res [string map {{ } .} [$cmd xInst $i]]
    27     33     }
    28     34     set res

Changes to ext/fts5/test/fts5simple2.test.

    15     15   
    16     16   # If SQLITE_ENABLE_FTS5 is defined, omit this file.
    17     17   ifcapable !fts5 {
    18     18     finish_test
    19     19     return
    20     20   }
    21     21   
    22         -if 1 {
    23         -
    24     22   do_execsql_test 1.0 {
    25     23     CREATE VIRTUAL TABLE t1 USING fts5(a, detail=none);
    26     24     INSERT INTO t1 VALUES('a b c');
    27     25   }
    28     26   do_execsql_test 1.1 {
    29     27     SELECT rowid FROM t1('c a b')
    30     28   } {1}
................................................................................
   294    292     SELECT rowid FROM t1('sqlite') ORDER BY rowid DESC;
   295    293   } {}
   296    294   
   297    295   do_test 15.4 {
   298    296     execsql { INSERT INTO t1(t1) VALUES('integrity-check') }
   299    297   } {}
   300    298   
   301         -}
   302         -
   303    299   #-------------------------------------------------------------------------
   304    300   #
   305    301   reset_db
   306    302   do_execsql_test 16.0 {
   307    303     CREATE VIRTUAL TABLE t2 USING fts5(x, detail=none);
   308    304     BEGIN;
   309    305       INSERT INTO t2(rowid, x) VALUES(1, 'a b c');
................................................................................
   317    313     INSERT INTO t2(t2) VALUES('integrity-check');
   318    314   } {}
   319    315   
   320    316   do_execsql_test 16.2 {
   321    317     SELECT rowid FROM t2('b') ORDER BY rowid DESC
   322    318   } {1000 456 1}
   323    319   
          320  +
          321  +#-------------------------------------------------------------------------
          322  +#
          323  +reset_db
          324  +do_execsql_test 16.0 {
          325  +  CREATE VIRTUAL TABLE t2 USING fts5(x, detail=none);
          326  +  BEGIN;
          327  +    INSERT INTO t2(rowid, x) VALUES(1, 'a b c');
          328  +    INSERT INTO t2(rowid, x) VALUES(456, 'a b c');
          329  +    INSERT INTO t2(rowid, x) VALUES(1000, 'a b c');
          330  +  COMMIT;
          331  +  UPDATE t2 SET x=x;
          332  +  DELETE FROM t2;
          333  +}
          334  +
          335  +#db eval {SELECT rowid, fts5_decode_none(rowid, block) aS r FROM t2_data} {puts $r}
   324    336     
   325    337   finish_test
   326    338