/ Check-in [e0d61442]
Login

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

Overview
Comment:Fix an fts5 issue with loading doclist-indexes for a term that is the last thing on its leaf page.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | fts5
Files: files | file ages | folders
SHA1: e0d614425f7f5ffe266fdc03642931b1ec19ad25
User & Date: dan 2015-01-21 18:23:25
Context
2015-01-21
20:30
Further tests and fixes for fts5. check-in: c020a291 user: dan tags: fts5
18:23
Fix an fts5 issue with loading doclist-indexes for a term that is the last thing on its leaf page. check-in: e0d61442 user: dan tags: fts5
17:20
Merge trunk changes with this branch. check-in: f8699a1a user: dan tags: fts5
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to ext/fts5/fts5_index.c.

  1821   1821   ** Iterator pIter currently points to the first rowid of a doclist within
  1822   1822   ** index iIdx. There is a doclist-index associated with the final term on
  1823   1823   ** the current page. If the current term is the last term on the page, 
  1824   1824   ** load the doclist-index from disk and initialize an iterator at 
  1825   1825   ** (pIter->pDlidx).
  1826   1826   */
  1827   1827   static void fts5SegIterLoadDlidx(Fts5Index *p, int iIdx, Fts5SegIter *pIter){
  1828         -  int iSegid = pIter->pSeg->iSegid;
         1828  +  int iSeg = pIter->pSeg->iSegid;
  1829   1829     int bRev = (pIter->flags & FTS5_SEGITER_REVERSE);
  1830   1830     Fts5Data *pLeaf = pIter->pLeaf; /* Current leaf data */
  1831   1831     int iOff = pIter->iLeafOffset;  /* Byte offset within current leaf */
  1832   1832   
  1833   1833     assert( pIter->flags & FTS5_SEGITER_ONETERM );
  1834   1834     assert( pIter->pDlidx==0 );
  1835   1835   
  1836   1836     /* Check if the current doclist ends on this page. If it does, return
  1837   1837     ** early without loading the doclist-index (as it belongs to a different
  1838   1838     ** term. */
  1839         -  while( iOff<pLeaf->n ){
  1840         -    i64 iDelta;
  1841         -    int nPoslist;
         1839  +  if( pIter->iTermLeafPgno==pIter->iLeafPgno ){
         1840  +    while( iOff<pLeaf->n ){
         1841  +      i64 iDelta;
         1842  +      int nPoslist;
  1842   1843   
  1843         -    /* iOff is currently the offset of the size field of a position list. */
  1844         -    iOff += getVarint32(&pLeaf->p[iOff], nPoslist);
  1845         -    iOff += nPoslist;
         1844  +      /* iOff is currently the offset of the size field of a position list. */
         1845  +      iOff += getVarint32(&pLeaf->p[iOff], nPoslist);
         1846  +      iOff += nPoslist;
  1846   1847   
  1847         -    if( iOff<pLeaf->n ){
  1848         -      iOff += getVarint(&pLeaf->p[iOff], (u64*)&iDelta);
  1849         -      if( iDelta==0 ) return;
         1848  +      if( iOff<pLeaf->n ){
         1849  +        iOff += getVarint(&pLeaf->p[iOff], (u64*)&iDelta);
         1850  +        if( iDelta==0 ) return;
         1851  +      }
  1850   1852       }
  1851   1853     }
  1852   1854   
  1853         -  fts5DlidxIterInit(p, bRev, iIdx, iSegid, pIter->iLeafPgno, &pIter->pDlidx);
         1855  +  fts5DlidxIterInit(p, bRev, iIdx, iSeg, pIter->iTermLeafPgno, &pIter->pDlidx);
  1854   1856   }
  1855   1857   
  1856   1858   /*
  1857   1859   ** Initialize the object pIter to point to term pTerm/nTerm within segment
  1858   1860   ** pSeg, index iIdx. If there is no such term in the index, the iterator
  1859   1861   ** is set to EOF.
  1860   1862   **

Changes to ext/fts5/test/fts5rowid.test.

   115    115     } [expr $tn+1]
   116    116   }
   117    117   
   118    118   set res [db one {SELECT count(*) FROM x2_data}]
   119    119   do_execsql_test 3.2 {
   120    120     SELECT count(fts5_decode(rowid, block)) FROM x2_data;
   121    121   } $res
          122  +
          123  +#-------------------------------------------------------------------------
          124  +# Leaf pages with no terms or rowids at all.
          125  +#
          126  +set strlist [list \
          127  +  "[string repeat {w } 400]"  \
          128  +  "[string repeat {x } 400]"  \
          129  +  "[string repeat {y } 400]"  \
          130  +  "[string repeat {z } 400]"  \
          131  +]
          132  +do_test 4.0 {
          133  +  execsql {
          134  +    BEGIN;
          135  +    CREATE VIRTUAL TABLE x3 USING fts5(a);
          136  +    INSERT INTO x3(x3, rank) VALUES('pgsz', 32);
          137  +  }
          138  +  foreach str $strlist { execsql { INSERT INTO x3 VALUES($str) } }
          139  +  execsql COMMIT
          140  +} {}
          141  +
          142  +for {set tn 0} {$tn<[llength $strlist]} {incr tn} {
          143  +  set str [lindex $strlist $tn]
          144  +  do_execsql_test 4.1.$tn {
          145  +    SELECT rowid FROM x3 WHERE x3 MATCH $str
          146  +  } [expr $tn+1]
          147  +}
          148  +
          149  +set res [db one {SELECT count(*) FROM x3_data}]
          150  +do_execsql_test 4.2 {
          151  +  SELECT count(fts5_decode(rowid, block)) FROM x3_data;
          152  +} $res
   122    153   
   123    154   finish_test
   124    155