]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Improve test coverage of fts5_index.c.
authordan <dan@noemail.net>
Fri, 15 May 2015 18:13:14 +0000 (18:13 +0000)
committerdan <dan@noemail.net>
Fri, 15 May 2015 18:13:14 +0000 (18:13 +0000)
FossilOrigin-Name: 7aea8c6d99737c6c72078e0b4b9c5f8186021aa0

ext/fts5/fts5_index.c
ext/fts5/test/fts5corrupt2.test
ext/fts5/test/fts5corrupt3.test [new file with mode: 0644]
ext/fts5/test/fts5merge.test
manifest
manifest.uuid

index e2796d9c784f1d6300a108870c607bf25681ea10..f9317ddd66acd30c2281ffe897aea4745f2634a6 100644 (file)
@@ -3462,9 +3462,6 @@ static void fts5WriteInitForAppend(
         fts5NodeIterFree(&ss);
       }
     }
-    if( pSeg->nHeight==1 ){
-      pWriter->nEmpty = pSeg->pgnoLast-1;
-    }
     assert( p->rc!=SQLITE_OK || (pgno+pWriter->nEmpty)==pSeg->pgnoLast );
     pWriter->bFirstTermInPage = 1;
     assert( pWriter->aWriter[0].term.n==0 );
@@ -4051,8 +4048,10 @@ int sqlite3Fts5IndexMerge(Fts5Index *p, int nMerge){
   Fts5Structure *pStruct;
 
   pStruct = fts5StructureRead(p);
-  fts5IndexMerge(p, &pStruct, nMerge);
-  fts5StructureWrite(p, pStruct);
+  if( pStruct && pStruct->nLevel ){
+    fts5IndexMerge(p, &pStruct, nMerge);
+    fts5StructureWrite(p, pStruct);
+  }
   fts5StructureRelease(pStruct);
 
   return fts5IndexReturn(p);
@@ -4533,21 +4532,21 @@ int sqlite3Fts5IndexQuery(
     memcpy(&buf.p[1], pToken, nToken);
   }
 
+#ifdef SQLITE_DEBUG
+  if( flags & FTS5INDEX_QUERY_TEST_NOIDX ){
+    assert( flags & FTS5INDEX_QUERY_PREFIX );
+    iIdx = 1+pConfig->nPrefix;
+  }else
+#endif
   if( flags & FTS5INDEX_QUERY_PREFIX ){
-    if( flags & FTS5INDEX_QUERY_TEST_NOIDX ){
-      iIdx = 1+pConfig->nPrefix;
-    }else{
-      int nChar = fts5IndexCharlen(pToken, nToken);
-      for(iIdx=1; iIdx<=pConfig->nPrefix; iIdx++){
-        if( pConfig->aPrefix[iIdx-1]==nChar ) break;
-      }
+    int nChar = fts5IndexCharlen(pToken, nToken);
+    for(iIdx=1; iIdx<=pConfig->nPrefix; iIdx++){
+      if( pConfig->aPrefix[iIdx-1]==nChar ) break;
     }
   }
 
   pRet = (Fts5IndexIter*)sqlite3Fts5MallocZero(&p->rc, sizeof(Fts5IndexIter));
   if( pRet ){
-    memset(pRet, 0, sizeof(Fts5IndexIter));
-
     pRet->pIndex = p;
     if( iIdx<=pConfig->nPrefix ){
       buf.p[0] = FTS5_MAIN_PREFIX + iIdx;
@@ -4890,6 +4889,7 @@ static void fts5BtreeIterFree(Fts5BtreeIter *pIter){
   fts5BufferFree(&pIter->term);
 }
 
+#ifdef SQLITE_DEBUG
 /*
 ** This function is purely an internal test. It does not contribute to 
 ** FTS functionality, or even the integrity-check, in any way.
@@ -4898,8 +4898,7 @@ static void fts5BtreeIterFree(Fts5BtreeIter *pIter){
 ** visited regardless of whether the doclist-index identified by parameters
 ** iSegid/iLeaf is iterated in forwards or reverse order.
 */
-#ifdef SQLITE_DEBUG
-static void fts5DlidxIterTestReverse(
+static void fts5TestDlidxReverse(
   Fts5Index *p, 
   int iSegid,                     /* Segment id to load from */
   int iLeaf                       /* Load doclist-index for this leaf */
@@ -4934,8 +4933,107 @@ static void fts5DlidxIterTestReverse(
 
   if( p->rc==SQLITE_OK && cksum1!=cksum2 ) p->rc = FTS5_CORRUPT;
 }
+
+static int fts5QueryCksum(
+  Fts5Index *p,                   /* Fts5 index object */
+  int iIdx,
+  const char *z,                  /* Index key to query for */
+  int n,                          /* Size of index key in bytes */
+  int flags,                      /* Flags for Fts5IndexQuery */
+  u64 *pCksum                     /* IN/OUT: Checksum value */
+){
+  u64 cksum = *pCksum;
+  Fts5IndexIter *pIdxIter = 0;
+  int rc = sqlite3Fts5IndexQuery(p, z, n, flags, &pIdxIter);
+
+  while( rc==SQLITE_OK && 0==sqlite3Fts5IterEof(pIdxIter) ){
+    const u8 *pPos;
+    int nPos;
+    i64 rowid = sqlite3Fts5IterRowid(pIdxIter);
+    rc = sqlite3Fts5IterPoslist(pIdxIter, &pPos, &nPos);
+    if( rc==SQLITE_OK ){
+      Fts5PoslistReader sReader;
+      for(sqlite3Fts5PoslistReaderInit(-1, pPos, nPos, &sReader);
+          sReader.bEof==0;
+          sqlite3Fts5PoslistReaderNext(&sReader)
+      ){
+        int iCol = FTS5_POS2COLUMN(sReader.iPos);
+        int iOff = FTS5_POS2OFFSET(sReader.iPos);
+        cksum ^= fts5IndexEntryCksum(rowid, iCol, iOff, iIdx, z, n);
+      }
+      rc = sqlite3Fts5IterNext(pIdxIter);
+    }
+  }
+  sqlite3Fts5IterClose(pIdxIter);
+
+  *pCksum = cksum;
+  return rc;
+}
+
+
+/*
+** This function is also purely an internal test. It does not contribute to 
+** FTS functionality, or even the integrity-check, in any way.
+*/
+static void fts5TestTerm(
+  Fts5Index *p, 
+  Fts5Buffer *pPrev,              /* Previous term */
+  const char *z, int n,           /* Possibly new term to test */
+  u64 expected,
+  u64 *pCksum
+){
+  int rc = p->rc;
+  if( pPrev->n==0 ){
+    fts5BufferSet(&rc, pPrev, n, (const u8*)z);
+  }else
+  if( rc==SQLITE_OK && (pPrev->n!=n || memcmp(pPrev->p, z, n)) ){
+    u32 cksum3 = *pCksum;
+    const char *zTerm = &pPrev->p[1];  /* The term without the prefix-byte */
+    int nTerm = pPrev->n-1;            /* Size of zTerm in bytes */
+    int iIdx = (pPrev->p[0] - FTS5_MAIN_PREFIX);
+    int flags = (iIdx==0 ? 0 : FTS5INDEX_QUERY_PREFIX);
+    int rc;
+    u64 ck1 = 0;
+    u64 ck2 = 0;
+
+    /* Check that the results returned for ASC and DESC queries are
+    ** the same. If not, call this corruption.  */
+    rc = fts5QueryCksum(p, iIdx, zTerm, nTerm, flags, &ck1);
+    if( rc==SQLITE_OK ){
+      int f = flags|FTS5INDEX_QUERY_DESC;
+      rc = fts5QueryCksum(p, iIdx, zTerm, nTerm, f, &ck2);
+    }
+    if( rc==SQLITE_OK && ck1!=ck2 ) rc = FTS5_CORRUPT;
+
+    /* If this is a prefix query, check that the results returned if the
+    ** the index is disabled are the same. In both ASC and DESC order. */
+    if( iIdx>0 && rc==SQLITE_OK ){
+      int f = flags|FTS5INDEX_QUERY_TEST_NOIDX;
+      ck2 = 0;
+      rc = fts5QueryCksum(p, iIdx, zTerm, nTerm, f, &ck2);
+      if( rc==SQLITE_OK && ck1!=ck2 ) rc = FTS5_CORRUPT;
+    }
+    if( iIdx>0 && rc==SQLITE_OK ){
+      int f = flags|FTS5INDEX_QUERY_TEST_NOIDX|FTS5INDEX_QUERY_DESC;
+      ck2 = 0;
+      rc = fts5QueryCksum(p, iIdx, zTerm, nTerm, f, &ck2);
+      if( rc==SQLITE_OK && ck1!=ck2 ) rc = FTS5_CORRUPT;
+    }
+
+    cksum3 ^= ck1;
+    fts5BufferSet(&rc, pPrev, n, (const u8*)z);
+
+    if( rc==SQLITE_OK && cksum3!=expected ){
+      rc = FTS5_CORRUPT;
+    }
+    *pCksum = cksum3;
+  }
+  p->rc = rc;
+}
 #else
-# define fts5DlidxIterTestReverse(x,y,z)
+# define fts5TestDlidxReverse(x,y,z)
+# define fts5TestTerm(u,v,w,x,y,z)
 #endif
 
 static void fts5IndexIntegrityCheckSegment(
@@ -5046,17 +5144,12 @@ static void fts5IndexIntegrityCheckSegment(
       }
 
       fts5DlidxIterFree(pDlidx);
-      fts5DlidxIterTestReverse(p, iSegid, iter.iLeaf);
+      fts5TestDlidxReverse(p, iSegid, iter.iLeaf);
     }
   }
 
-  /* Either iter.iLeaf must be the rightmost leaf-page in the segment, or 
-  ** else the segment has been completely emptied by an ongoing merge
-  ** operation. */
-  if( p->rc==SQLITE_OK 
-   && iter.iLeaf!=pSeg->pgnoLast 
-   && (pSeg->pgnoFirst || pSeg->pgnoLast) 
-  ){
+  /* Page iter.iLeaf must now be the rightmost leaf-page in the segment */
+  if( p->rc==SQLITE_OK && iter.iLeaf!=pSeg->pgnoLast ){
     p->rc = FTS5_CORRUPT;
   }
 
@@ -5064,42 +5157,6 @@ static void fts5IndexIntegrityCheckSegment(
 }
 
 
-static int fts5QueryCksum(
-  Fts5Index *p,                   /* Fts5 index object */
-  int iIdx,
-  const char *z,                  /* Index key to query for */
-  int n,                          /* Size of index key in bytes */
-  int flags,                      /* Flags for Fts5IndexQuery */
-  u64 *pCksum                     /* IN/OUT: Checksum value */
-){
-  u64 cksum = *pCksum;
-  Fts5IndexIter *pIdxIter = 0;
-  int rc = sqlite3Fts5IndexQuery(p, z, n, flags, &pIdxIter);
-
-  while( rc==SQLITE_OK && 0==sqlite3Fts5IterEof(pIdxIter) ){
-    const u8 *pPos;
-    int nPos;
-    i64 rowid = sqlite3Fts5IterRowid(pIdxIter);
-    rc = sqlite3Fts5IterPoslist(pIdxIter, &pPos, &nPos);
-    if( rc==SQLITE_OK ){
-      Fts5PoslistReader sReader;
-      for(sqlite3Fts5PoslistReaderInit(-1, pPos, nPos, &sReader);
-          sReader.bEof==0;
-          sqlite3Fts5PoslistReaderNext(&sReader)
-      ){
-        int iCol = FTS5_POS2COLUMN(sReader.iPos);
-        int iOff = FTS5_POS2OFFSET(sReader.iPos);
-        cksum ^= fts5IndexEntryCksum(rowid, iCol, iOff, iIdx, z, n);
-      }
-      rc = sqlite3Fts5IterNext(pIdxIter);
-    }
-  }
-  sqlite3Fts5IterClose(pIdxIter);
-
-  *pCksum = cksum;
-  return rc;
-}
-
 /*
 ** Run internal checks to ensure that the FTS index (a) is internally 
 ** consistent and (b) contains entries for which the XOR of the checksums
@@ -5112,11 +5169,13 @@ static int fts5QueryCksum(
 */
 int sqlite3Fts5IndexIntegrityCheck(Fts5Index *p, u64 cksum){
   u64 cksum2 = 0;                 /* Checksum based on contents of indexes */
-  u64 cksum3 = 0;                 /* Checksum based on contents of indexes */
-  Fts5Buffer term = {0,0,0};      /* Buffer used to hold most recent term */
   Fts5Buffer poslist = {0,0,0};   /* Buffer used to hold a poslist */
   Fts5MultiSegIter *pIter;        /* Used to iterate through entire index */
   Fts5Structure *pStruct;         /* Index structure */
+
+  /* Used by extra internal tests only run if NDEBUG is not defined */
+  u64 cksum3 = 0;                 /* Checksum based on contents of indexes */
+  Fts5Buffer term = {0,0,0};      /* Buffer used to hold most recent term */
   
   /* Load the FTS index structure */
   pStruct = fts5StructureRead(p);
@@ -5164,48 +5223,12 @@ int sqlite3Fts5IndexIntegrityCheck(Fts5Index *p, u64 cksum){
     }
 
     /* If this is a new term, query for it. Update cksum3 with the results. */
-    if( p->rc==SQLITE_OK && (term.n!=n || memcmp(term.p, z, n)) ){
-      const char *zTerm = &z[1];     /* The term without the prefix-byte */
-      int nTerm = n-1;               /* Size of zTerm in bytes */
-      int iIdx = (z[0] - FTS5_MAIN_PREFIX);
-      int flags = (iIdx==0 ? 0 : FTS5INDEX_QUERY_PREFIX);
-      int rc;
-      u64 ck1 = 0;
-      u64 ck2 = 0;
-
-      /* Check that the results returned for ASC and DESC queries are
-      ** the same. If not, call this corruption.  */
-      rc = fts5QueryCksum(p, iIdx, zTerm, nTerm, flags, &ck1);
-      if( rc==SQLITE_OK ){
-        int f = flags|FTS5INDEX_QUERY_DESC;
-        rc = fts5QueryCksum(p, iIdx, zTerm, nTerm, f, &ck2);
-      }
-      if( rc==SQLITE_OK && ck1!=ck2 ) rc = FTS5_CORRUPT;
-
-      /* If this is a prefix query, check that the results returned if the
-      ** the index is disabled are the same. In both ASC and DESC order. */
-      if( iIdx>0 && rc==SQLITE_OK ){
-        int f = flags|FTS5INDEX_QUERY_TEST_NOIDX;
-        ck2 = 0;
-        rc = fts5QueryCksum(p, iIdx, zTerm, nTerm, f, &ck2);
-        if( rc==SQLITE_OK && ck1!=ck2 ) rc = FTS5_CORRUPT;
-      }
-      if( iIdx>0 && rc==SQLITE_OK ){
-        int f = flags|FTS5INDEX_QUERY_TEST_NOIDX|FTS5INDEX_QUERY_DESC;
-        ck2 = 0;
-        rc = fts5QueryCksum(p, iIdx, zTerm, nTerm, f, &ck2);
-        if( rc==SQLITE_OK && ck1!=ck2 ) rc = FTS5_CORRUPT;
-      }
-
-      cksum3 ^= ck1;
-      fts5BufferSet(&rc, &term, n, (const u8*)z);
-      p->rc = rc;
-    }
+    fts5TestTerm(p, &term, z, n, cksum2, &cksum3);
   }
-  fts5MultiIterFree(p, pIter);
+  fts5TestTerm(p, &term, 0, 0, cksum2, &cksum3);
 
+  fts5MultiIterFree(p, pIter);
   if( p->rc==SQLITE_OK && cksum!=cksum2 ) p->rc = FTS5_CORRUPT;
-  if( p->rc==SQLITE_OK && cksum!=cksum3 ) p->rc = FTS5_CORRUPT;
 
   fts5StructureRelease(pStruct);
   fts5BufferFree(&term);
index df22f61b93ce69bf46f307793b037cc9f171723d..099b966945f6267ad546f6ed65a81a92eebe8b5c 100644 (file)
@@ -115,8 +115,6 @@ for {set i [expr $nbyte-2]} {$i>=0} {incr i -1} {
   } {}
 }
 
-}
-
 #-------------------------------------------------------------------------
 # Test that corruption in leaf page headers is detected by queries that use
 # doclist-indexes.
@@ -208,6 +206,40 @@ foreach {tn nCut} {
   do_test 4.$tn.x { expr $nCorrupt>0 } 1
 }
 
+}
+
+set doc [string repeat "A B C " 1000]
+do_execsql_test 4.0 {
+  CREATE VIRTUAL TABLE x5 USING fts5(tt);
+  INSERT INTO x5(x5, rank) VALUES('pgsz', 32);
+  WITH ii(i) AS (SELECT 1 UNION ALL SELECT i+1 FROM ii WHERE i<10) 
+  INSERT INTO x5 SELECT $doc FROM ii;
+}
+
+foreach {tn hdr} {
+  1 "\x00\x01"
+} {
+  set tn2 0
+  set nCorrupt 0
+  foreach rowid [db eval {SELECT rowid FROM x5_data WHERE rowid>10}] {
+    if {$rowid & $mask} continue
+    incr tn2
+    do_test 4.$tn.$tn2 {
+      execsql BEGIN
+
+      set fd [db incrblob main x5_data block $rowid]
+      fconfigure $fd -encoding binary -translation binary
+      puts -nonewline $fd $hdr
+      close $fd
+
+      catchsql { INSERT INTO x5(x5) VALUES('integrity-check') }
+      set {} {}
+    } {}
+
+    execsql ROLLBACK
+  }
+}
+
 
 sqlite3_fts5_may_be_corrupt 0
 finish_test
diff --git a/ext/fts5/test/fts5corrupt3.test b/ext/fts5/test/fts5corrupt3.test
new file mode 100644 (file)
index 0000000..1df8b3e
--- /dev/null
@@ -0,0 +1,57 @@
+# 2015 Apr 24
+#
+# 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 file tests that FTS5 handles corrupt databases (i.e. internal
+# inconsistencies in the backing tables) correctly. In this case 
+# "correctly" means without crashing.
+#
+
+source [file join [file dirname [info script]] fts5_common.tcl]
+set testprefix fts5corrupt3
+sqlite3_fts5_may_be_corrupt 1
+
+# Create a simple FTS5 table containing 100 documents. Each document 
+# contains 10 terms, each of which start with the character "x".
+#
+expr srand(0)
+db func rnddoc fts5_rnddoc
+do_execsql_test 1.0 {
+  CREATE VIRTUAL TABLE t1 USING fts5(x);
+  INSERT INTO t1(t1, rank) VALUES('pgsz', 64);
+  WITH ii(i) AS (SELECT 1 UNION SELECT i+1 FROM ii WHERE i<100)
+  INSERT INTO t1 SELECT rnddoc(10) FROM ii;
+}
+set mask [expr 31 << 31]
+
+do_test 1.1 {
+  # Pick out the rowid of the right-most b-tree leaf in the new segment.
+  set rowid [db one {
+    SELECT max(rowid) FROM t1_data WHERE ((rowid>>31) & 0x0F)==1
+  }]
+  set L [db one {SELECT length(block) FROM t1_data WHERE rowid = $rowid}]
+  set {} {}
+} {} 
+
+for {set i 0} {$i < $L} {incr i} {
+  do_test 1.2.$i {
+    catchsql {
+      BEGIN;
+      UPDATE t1_data SET block = substr(block, 1, $i) WHERE id = $rowid;
+      INSERT INTO t1(t1) VALUES('integrity-check');
+    }
+  } {1 {database disk image is malformed}}
+  catchsql ROLLBACK
+}
+
+sqlite3_fts5_may_be_corrupt 0
+finish_test
+
index 1c048be8edb608a76b879ad9bd70831091c76913..d869c6cedbda393289d951a85f3741732554d6c3 100644 (file)
@@ -135,5 +135,54 @@ do_test 3.4 {
   fts5_level_segs x8
 } {0 1}
 
+#-------------------------------------------------------------------------
+#
+proc mydoc {} {
+  set x [lindex {a b c d e f g h i j} [expr int(rand()*10)]]
+  return [string repeat "$x " 30]
+}
+db func mydoc mydoc
+
+proc mycount {} {
+  set res [list]
+  foreach x {a b c d e f g h i j} {
+    lappend res [db one {SELECT count(*) FROM x8 WHERE x8 MATCH $x}]
+  }
+  set res
+}
+
+  #1 32
+foreach {tn pgsz} {
+  2 1000
+} {
+  do_execsql_test 4.$tn.1 {
+    DROP TABLE IF EXISTS x8;
+    CREATE VIRTUAL TABLE x8 USING fts5(i);
+    INSERT INTO x8(x8, rank) VALUES('pgsz', $pgsz);
+  }
+
+  do_execsql_test 4.$tn.2 {
+    INSERT INTO x8(x8, rank) VALUES('merge', 1);
+  }
+
+  do_execsql_test 4.$tn.3 {
+    WITH ii(i) AS (SELECT 1 UNION ALL SELECT i+1 FROM ii WHERE i<100)
+      INSERT INTO x8 SELECT mydoc() FROM ii;
+    WITH ii(i) AS (SELECT 1 UNION ALL SELECT i+1 FROM ii WHERE i<100)
+      INSERT INTO x8 SELECT mydoc() FROM ii;
+    INSERT INTO x8(x8, rank) VALUES('automerge', 2);
+  }
+
+  set expect [mycount]
+    for {set i 0} {$i < 20} {incr i} {
+      do_test 4.$tn.4.$i {
+        execsql { INSERT INTO x8(x8, rank) VALUES('merge', 1); }
+        mycount
+      } $expect
+      break
+    }
+  db eval {SELECT fts5_decode(rowid, block) AS r FROM x8_data} { puts $r }
+}
+
 finish_test
 
index 46ffb625b44c07127ad4c18a7bf11fc2d6ea68bf..aaac042c6af10e0c47c6fccfbd575e61b8ba9876 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Add\stest\scases.\sAnd\ssome\sfixes.
-D 2015-05-15T12:18:39.221
+C Improve\stest\scoverage\sof\sfts5_index.c.
+D 2015-05-15T18:13:14.380
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in edfc69769e613a6359c42c06ea1d42c3bece1736
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -112,7 +112,7 @@ F ext/fts5/fts5_buffer.c 70b971e13503566f1e257941c60817ba0920a16b
 F ext/fts5/fts5_config.c 05811f0bd80c396afcf3ceea68da16149a9a3258
 F ext/fts5/fts5_expr.c 3fe1170453d6a322d2de8a3fd0aed3edff7b8b09
 F ext/fts5/fts5_hash.c 54dd25348a46ea62ea96322c572e08cd1fb37304
-F ext/fts5/fts5_index.c 71d5ce47464f176e8708c7ec02d18613eb5eebda
+F ext/fts5/fts5_index.c 6e0ac5835ab33a2cf97efd591acd4fc130490e0f
 F ext/fts5/fts5_storage.c cb8b585bfb7870a36101f1a8fa0b0777f4d1b68d
 F ext/fts5/fts5_tcl.c f18eeb125d733f4e815a11679b971fa61cd7ec77
 F ext/fts5/fts5_tokenize.c 830eae0d35a5a5a90af34df65da3427f46d942fc
@@ -138,7 +138,8 @@ F ext/fts5/test/fts5auxdata.test c69b86092bf1a157172de5f9169731af3403179b
 F ext/fts5/test/fts5bigpl.test b1cfd00561350ab04994ba7dd9d48468e5e0ec3b
 F ext/fts5/test/fts5content.test 532e15b541254410adc7bfb51f94631cfe82de8f
 F ext/fts5/test/fts5corrupt.test 35bfdbbb3cdcea46ae7385f6432e9b5c574e70a1
-F ext/fts5/test/fts5corrupt2.test 88942d27ed581314f2867ef37352c72372c543df
+F ext/fts5/test/fts5corrupt2.test 7000030df189f1f3ca58b555b459bcbf9b8f8f77
+F ext/fts5/test/fts5corrupt3.test fe42c0ce0b58b7ad487a469049f91419d22c7459
 F ext/fts5/test/fts5dlidx.test 070531bd45685e545e3e6021deb543f730a4011b
 F ext/fts5/test/fts5doclist.test 635b80ac785627841a59c583bac702b55d49fdc5
 F ext/fts5/test/fts5ea.test ed163ed820fd503354bd7dcf9d3b0e3801ade962
@@ -151,7 +152,7 @@ F ext/fts5/test/fts5fault5.test 98e7e77bc1d8bb47c955e7d6dc870ab5736536e3
 F ext/fts5/test/fts5full.test 0924bdca5416a242103239ace79c6f5aa34bab8d
 F ext/fts5/test/fts5hash.test adb7b0442cc1c77c507f07e16d11490486e75dfa
 F ext/fts5/test/fts5integrity.test 98801bd0fb7c53a40bc770280134865d61724f3a
-F ext/fts5/test/fts5merge.test 453a0717881aa7784885217b2040f3f275caff03
+F ext/fts5/test/fts5merge.test b985b6891e093a4b4c3c9683fe3cba7498fed690
 F ext/fts5/test/fts5near.test 3f9f64e16cac82725d03d4e04c661090f0b3b947
 F ext/fts5/test/fts5optimize.test 0028c90a7817d3e576d1148fc8dff17d89054e54
 F ext/fts5/test/fts5plan.test 89783f70dab89ff936ed6f21d88959b49c853a47
@@ -1325,7 +1326,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
-P b5f0e8c5b4bc018d672617ffd342d12b228548b9
-R bdc9509f45810e2b38f3396d130ff7ee
+P adee788586197445672013d434e7ba47ce510b59
+R 5c5f538830728743e22dc39869e34f52
 U dan
-Z 2d21c26b247bac296f85906c81a77b9c
+Z ae5179a6b1088d2fd3b13e20090e807a
index 6c7bb30f6e95298d86e7cc88c7f82b51a8eceb55..90a0fbd3cb2fcabb600bb86b55b9b6e71c15b156 100644 (file)
@@ -1 +1 @@
-adee788586197445672013d434e7ba47ce510b59
\ No newline at end of file
+7aea8c6d99737c6c72078e0b4b9c5f8186021aa0
\ No newline at end of file