]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Fix a problem with OOM handling when setting an fts5 configuration option.
authordan <dan@noemail.net>
Sat, 26 Mar 2016 20:11:04 +0000 (20:11 +0000)
committerdan <dan@noemail.net>
Sat, 26 Mar 2016 20:11:04 +0000 (20:11 +0000)
FossilOrigin-Name: 53b80a6d054a1c87311b3dc1c2bcfcc1b676b05a

ext/fts5/fts5Int.h
ext/fts5/fts5_index.c
ext/fts5/fts5_main.c
ext/fts5/fts5_storage.c
ext/fts5/test/fts5fault4.test
ext/fts5/test/fts5faultC.test [new file with mode: 0644]
ext/fts5/test/fts5simple.test
manifest
manifest.uuid

index c4e7506fb15385a8a518640b7ea51177115a522e..9e68b5a11105aab0784ae817d0c0c57d0c53fcc9 100644 (file)
@@ -473,7 +473,7 @@ int sqlite3Fts5IndexIntegrityCheck(Fts5Index*, u64 cksum);
 */
 int sqlite3Fts5IndexInit(sqlite3*);
 
-int sqlite3Fts5IndexSetCookie(Fts5Index*, int);
+int sqlite3Fts5IndexIncrCookie(Fts5Index*);
 
 /*
 ** Return the total number of entries read from the %_data table by 
@@ -484,10 +484,12 @@ int sqlite3Fts5IndexReads(Fts5Index *p);
 int sqlite3Fts5IndexReinit(Fts5Index *p);
 int sqlite3Fts5IndexOptimize(Fts5Index *p);
 int sqlite3Fts5IndexMerge(Fts5Index *p, int nMerge);
-int sqlite3Fts5IndexReset(Fts5Index *p);
+int sqlite3Fts5IndexNewTrans(Fts5Index *p);
 
 int sqlite3Fts5IndexLoadConfig(Fts5Index *p);
 
+void sqlite3Fts5IndexCloseReader(Fts5Index*);
+
 /*
 ** End of interface to code in fts5_index.c.
 **************************************************************************/
index 1200f5707ba206a017118d16bc45ceaf1b784470..8fd1f1cdcb9293e06a7e17ebb418c7152cd3b820 100644 (file)
@@ -12,8 +12,8 @@
 **
 ** Low level access to the FTS index stored in the database file. The 
 ** routines in this file file implement all read and write access to the
-** %_data table. Other parts of the system access this functionality via
-** the interface defined in fts5Int.h.
+** %_data and %_idx tables. Other parts of the system access this 
+** functionality via the interface defined in fts5Int.h.
 */
 
 
 /*
 ** Overview:
 **
-** The %_data table contains all the FTS indexes for an FTS5 virtual table.
-** As well as the main term index, there may be up to 31 prefix indexes.
-** The format is similar to FTS3/4, except that:
+** The %_data table contains the FTS index for an FTS5 virtual table.
+** All entries, for terms and prefixes, are stored in a single data
+** structure. The format is similar to FTS3/4, but differs in the 
+** following ways:
 **
 **   * all segment b-tree leaf data is stored in fixed size page records 
 **     (e.g. 1000 bytes). A single doclist may span multiple pages. Care is 
 **
 **   * extra fields in the "structure record" record the state of ongoing
 **     incremental merge operations.
-**
 */
 
 
-#define FTS5_OPT_WORK_UNIT  1000  /* Number of leaf pages per optimize step */
-#define FTS5_WORK_UNIT      64    /* Number of leaf pages in unit of work */
-
-#define FTS5_MIN_DLIDX_SIZE 4     /* Add dlidx if this many empty pages */
-
-#define FTS5_MAIN_PREFIX '0'
-
-#if FTS5_MAX_PREFIX_INDEXES > 31
-# error "FTS5_MAX_PREFIX_INDEXES is too large"
-#endif
-
 /*
-** Details:
+** Contents of %_data table:
 **
 ** The %_data table managed by this module,
 **
 **     CREATE TABLE %_data(id INTEGER PRIMARY KEY, block BLOB);
 **
-** , contains the following 5 types of records. See the comments surrounding
+** , contains the following 4 types of records. See the comments surrounding
 ** the FTS5_*_ROWID macros below for a description of how %_data rowids are 
-** assigned to each fo them.
+** assigned to each of them.
 **
 ** 1. Structure Records:
 **
 **             varint : size of first term
 **             blob:    first term data
 **
-** 5. Segment doclist indexes:
+** 4. Segment doclist indexes:
 **
 **   Doclist indexes are themselves b-trees, however they usually consist of
 **   a single leaf record only. The format of each doclist index leaf page 
 **
 */
 
+
+#define FTS5_OPT_WORK_UNIT  1000  /* Number of leaf pages per optimize step */
+#define FTS5_WORK_UNIT      64    /* Number of leaf pages in unit of work */
+#define FTS5_MIN_DLIDX_SIZE 4     /* Add dlidx if this many empty pages */
+
+/* All entries for regular terms in the FTS index are prefixed with '0'.
+** Entries for the first prefix index are prefixed with '1'. And so on, 
+** up to ('0'+31).  */
+#define FTS5_MAIN_PREFIX '0'
+
+#if FTS5_MAX_PREFIX_INDEXES > 31
+# error "FTS5_MAX_PREFIX_INDEXES is too large"
+#endif
+
+
 /*
 ** Rowids for the averages and structure records in the %_data table.
 */
@@ -305,7 +309,8 @@ struct Fts5Index {
   sqlite3_stmt *pIdxSelect;
   int nRead;                      /* Total number of blocks read */
 
-  sqlite3_stmt *pDataVersion;
+  /* In-memory cache of the 'structure' record */
+  sqlite3_stmt *pDataVersion;     /* PRAGMA <db>.data_version */
   i64 iStructVersion;             /* data_version when pStruct read */
   Fts5Structure *pStruct;         /* Current db structure (or NULL) */
 };
@@ -620,7 +625,7 @@ static int fts5LeafFirstTermOff(Fts5Data *pLeaf){
 /*
 ** Close the read-only blob handle, if it is open.
 */
-static void fts5CloseReader(Fts5Index *p){
+void sqlite3Fts5IndexCloseReader(Fts5Index *p){
   if( p->pReader ){
     sqlite3_blob *pReader = p->pReader;
     p->pReader = 0;
@@ -650,7 +655,7 @@ static Fts5Data *fts5DataRead(Fts5Index *p, i64 iRowid){
       assert( p->pReader==0 );
       p->pReader = pBlob;
       if( rc!=SQLITE_OK ){
-        fts5CloseReader(p);
+        sqlite3Fts5IndexCloseReader(p);
       }
       if( rc==SQLITE_ABORT ) rc = SQLITE_OK;
     }
@@ -994,7 +999,7 @@ static i64 fts5IndexDataVersion(Fts5Index *p){
     if( p->pDataVersion==0 ){
       p->rc = fts5IndexPrepareStmt(p, &p->pDataVersion, 
           sqlite3_mprintf("PRAGMA %Q.data_version", p->pConfig->zDb)
-          );
+      );
       if( p->rc ) return 0;
     }
 
@@ -1007,6 +1012,19 @@ static i64 fts5IndexDataVersion(Fts5Index *p){
   return iVersion;
 }
 
+/*
+** If there is currently no cache of the index structure in memory, load
+** one from the database.
+*/
+static void fts5StructureCache(Fts5Index *p){
+  if( p->pStruct==0 ){
+    p->iStructVersion = fts5IndexDataVersion(p);
+    if( p->rc==SQLITE_OK ){
+      p->pStruct = fts5StructureReadUncached(p);
+    }
+  }
+}
+
 /*
 ** Read, deserialize and return the structure record.
 **
@@ -1019,13 +1037,7 @@ static i64 fts5IndexDataVersion(Fts5Index *p){
 ** is called, it is a no-op.
 */
 static Fts5Structure *fts5StructureRead(Fts5Index *p){
-
-  if( p->pStruct==0 ){
-    p->iStructVersion = fts5IndexDataVersion(p);
-    if( p->rc==SQLITE_OK ){
-      p->pStruct = fts5StructureReadUncached(p);
-    }
-  }
+  fts5StructureCache(p);
 
 #if 0
   else{
@@ -4396,12 +4408,6 @@ static int fts5IndexReturn(Fts5Index *p){
   return rc;
 }
 
-typedef struct Fts5FlushCtx Fts5FlushCtx;
-struct Fts5FlushCtx {
-  Fts5Index *pIdx;
-  Fts5SegWriter writer; 
-};
-
 /*
 ** Buffer aBuf[] contains a list of varints, all small enough to fit
 ** in a 32-bit integer. Return the size of the largest prefix of this 
@@ -5104,7 +5110,7 @@ int sqlite3Fts5IndexBeginWrite(Fts5Index *p, int bDelete, i64 iRowid){
 int sqlite3Fts5IndexSync(Fts5Index *p, int bCommit){
   assert( p->rc==SQLITE_OK );
   fts5IndexFlush(p);
-  if( bCommit ) fts5CloseReader(p);
+  if( bCommit ) sqlite3Fts5IndexCloseReader(p);
   return fts5IndexReturn(p);
 }
 
@@ -5115,9 +5121,10 @@ int sqlite3Fts5IndexSync(Fts5Index *p, int bCommit){
 ** records must be invalidated.
 */
 int sqlite3Fts5IndexRollback(Fts5Index *p){
-  fts5CloseReader(p);
+  sqlite3Fts5IndexCloseReader(p);
   fts5IndexDiscardData(p);
   fts5StructureInvalidate(p);
+  p->pConfig->iCookie = -1;
   /* assert( p->rc==SQLITE_OK ); */
   return SQLITE_OK;
 }
@@ -5352,7 +5359,7 @@ int sqlite3Fts5IndexQuery(
     if( p->rc ){
       sqlite3Fts5IterClose(&pRet->base);
       pRet = 0;
-      fts5CloseReader(p);
+      sqlite3Fts5IndexCloseReader(p);
     }
 
     *ppIter = &pRet->base;
@@ -5425,7 +5432,7 @@ void sqlite3Fts5IterClose(Fts5IndexIter *pIndexIter){
     Fts5Iter *pIter = (Fts5Iter*)pIndexIter;
     Fts5Index *pIndex = pIter->pIndex;
     fts5MultiIterFree(pIter);
-    fts5CloseReader(pIndex);
+    sqlite3Fts5IndexCloseReader(pIndex);
   }
 }
 
@@ -5467,46 +5474,43 @@ int sqlite3Fts5IndexSetAverages(Fts5Index *p, const u8 *pData, int nData){
 
 /*
 ** Return the total number of blocks this module has read from the %_data
-** table since it was created.
+** table (since it was created by sqlite3Fts5IndexOpen).
 */
 int sqlite3Fts5IndexReads(Fts5Index *p){
   return p->nRead;
 }
 
 /*
-** Set the 32-bit cookie value stored at the start of all structure 
-** records to the value passed as the second argument.
-**
-** Return SQLITE_OK if successful, or an SQLite error code if an error
-** occurs.
+** Increment the value of the configuration cookie stored as the first 
+** 32-bits of the structure record in the database. This is done after
+** modifying the contents of the %_config table.
 */
-int sqlite3Fts5IndexSetCookie(Fts5Index *p, int iNew){
-  int rc;                              /* Return code */
-  Fts5Config *pConfig = p->pConfig;    /* Configuration object */
-  u8 aCookie[4];                       /* Binary representation of iNew */
-  sqlite3_blob *pBlob = 0;
-
-  assert( p->rc==SQLITE_OK );
-  sqlite3Fts5Put32(aCookie, iNew);
-
-  rc = sqlite3_blob_open(pConfig->db, pConfig->zDb, p->zDataTbl, 
-      "block", FTS5_STRUCTURE_ROWID, 1, &pBlob
-  );
-  if( rc==SQLITE_OK ){
-    sqlite3_blob_write(pBlob, aCookie, 4, 0);
-    rc = sqlite3_blob_close(pBlob);
-  }
-
-  return rc;
-}
-
-int sqlite3Fts5IndexLoadConfig(Fts5Index *p){
+int sqlite3Fts5IndexIncrCookie(Fts5Index *p){
   Fts5Structure *pStruct;
   pStruct = fts5StructureRead(p);
+  p->pConfig->iCookie++;
+  fts5StructureWrite(p, pStruct);
   fts5StructureRelease(pStruct);
   return fts5IndexReturn(p);
 }
 
+/*
+** Ensure the contents of the %_config table have been loaded into memory.
+*/
+int sqlite3Fts5IndexLoadConfig(Fts5Index *p){
+  fts5StructureCache(p);
+  return fts5IndexReturn(p);
+}
+
+int sqlite3Fts5IndexNewTrans(Fts5Index *p){
+  assert( p->pStruct==0 || p->iStructVersion!=0 );
+  if( p->pConfig->iCookie<0 || fts5IndexDataVersion(p)!=p->iStructVersion ){
+    fts5StructureInvalidate(p);
+  }
+  return fts5IndexReturn(p);
+}
+
+
 
 /*************************************************************************
 **************************************************************************
@@ -6451,11 +6455,3 @@ int sqlite3Fts5IndexInit(sqlite3 *db){
   return rc;
 }
 
-
-int sqlite3Fts5IndexReset(Fts5Index *p){
-  assert( p->pStruct==0 || p->iStructVersion!=0 );
-  if( fts5IndexDataVersion(p)!=p->iStructVersion ){
-    fts5StructureInvalidate(p);
-  }
-  return fts5IndexReturn(p);
-}
index 4feb3e1a2f9a8025c4e37cd8e4c05f6c3e38ec24..eaa01938d57eedc1eff8a724aa390b1345a9b785 100644 (file)
@@ -602,7 +602,7 @@ static int fts5NewTransaction(Fts5Table *pTab){
   for(pCsr=pTab->pGlobal->pCsr; pCsr; pCsr=pCsr->pNext){
     if( pCsr->base.pVtab==(sqlite3_vtab*)pTab ) return SQLITE_OK;
   }
-  return sqlite3Fts5StorageReset(pTab->pStorage);
+  return sqlite3Fts5IndexNewTrans(pTab->pIndex);
 }
 
 /*
@@ -616,6 +616,9 @@ static int fts5OpenMethod(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCsr){
   int rc;                         /* Return code */
 
   rc = fts5NewTransaction(pTab);
+  if( rc==SQLITE_OK ){
+    rc = sqlite3Fts5IndexLoadConfig(pTab->pIndex);
+  }
   if( rc==SQLITE_OK ){
     nByte = sizeof(Fts5Cursor) + pConfig->nCol * sizeof(int);
     pCsr = (Fts5Cursor*)sqlite3_malloc(nByte);
@@ -630,6 +633,9 @@ static int fts5OpenMethod(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCsr){
       rc = SQLITE_NOMEM;
     }
   }
+  if( rc!=SQLITE_OK ){
+    sqlite3Fts5IndexCloseReader(pTab->pIndex);
+  }
   *ppCsr = (sqlite3_vtab_cursor*)pCsr;
   return rc;
 }
@@ -710,6 +716,7 @@ static int fts5CloseMethod(sqlite3_vtab_cursor *pCursor){
     *pp = pCsr->pNext;
 
     sqlite3_free(pCsr);
+    sqlite3Fts5IndexCloseReader(pTab->pIndex);
   }
   return SQLITE_OK;
 }
@@ -1589,9 +1596,16 @@ static int fts5SyncMethod(sqlite3_vtab *pVtab){
 ** Implementation of xBegin() method. 
 */
 static int fts5BeginMethod(sqlite3_vtab *pVtab){
-  fts5CheckTransactionState((Fts5Table*)pVtab, FTS5_BEGIN, 0);
-  fts5NewTransaction((Fts5Table*)pVtab);
-  return SQLITE_OK;
+  Fts5Table *pTab = (Fts5Table*)pVtab;
+  int rc;
+  rc = fts5NewTransaction(pTab);
+  if( rc!=SQLITE_OK ){
+    sqlite3Fts5IndexCloseReader(pTab->pIndex);
+  }
+#ifdef SQLITE_DEBUG
+  if( rc==SQLITE_OK ) fts5CheckTransactionState(pTab, FTS5_BEGIN, 0);
+#endif
+  return rc;
 }
 
 /*
index 90df3396c352473beb969b2109daaab3ef2b3583..e8a865a7c6af1a77ff5c1aac4b9cc66a057c97d7 100644 (file)
@@ -641,10 +641,6 @@ int sqlite3Fts5StorageMerge(Fts5Storage *p, int nMerge){
   return sqlite3Fts5IndexMerge(p->pIndex, nMerge);
 }
 
-int sqlite3Fts5StorageReset(Fts5Storage *p){
-  return sqlite3Fts5IndexReset(p->pIndex);
-}
-
 /*
 ** Allocate a new rowid. This is used for "external content" tables when
 ** a NULL value is inserted into the rowid column. The new rowid is allocated
@@ -1120,11 +1116,7 @@ int sqlite3Fts5StorageConfigValue(
     rc = sqlite3_reset(pReplace);
   }
   if( rc==SQLITE_OK && pVal ){
-    int iNew = p->pConfig->iCookie + 1;
-    rc = sqlite3Fts5IndexSetCookie(p->pIndex, iNew);
-    if( rc==SQLITE_OK ){
-      p->pConfig->iCookie = iNew;
-    }
+    rc = sqlite3Fts5IndexIncrCookie(p->pIndex);
   }
   return rc;
 }
index bfa54a5b04c75d97dd88c32901d660ca37895b34..acc43ebfc65a8da76455d6c460d2380de6ec74c5 100644 (file)
@@ -86,7 +86,7 @@ set ::res [db eval {SELECT rowid, x1 FROM x1 WHERE x1 MATCH '*reads'}]
 do_faultsim_test 4 -faults oom-* -body {
   db eval {SELECT rowid, x, x1 FROM x1 WHERE x1 MATCH '*reads'}
 } -test {
-  faultsim_test_result {0 {0 {} 3}}
+  faultsim_test_result {0 {0 {} 4}}
 }
 
 #-------------------------------------------------------------------------
diff --git a/ext/fts5/test/fts5faultC.test b/ext/fts5/test/fts5faultC.test
new file mode 100644 (file)
index 0000000..a9c94a4
--- /dev/null
@@ -0,0 +1,79 @@
+# 2016 March 26
+#
+# 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 is focused on OOM errors.
+#
+
+source [file join [file dirname [info script]] fts5_common.tcl]
+source $testdir/malloc_common.tcl
+set testprefix fts5faultC
+return_if_no_fts5
+
+#--------------------------------------------------------------------------
+# Test that if an OOM error occurs while trying to set a configuration
+# option, the in-memory and on-disk configurations are not left in an 
+# inconsistent state.
+#
+
+
+
+proc posrowid {cmd} { $cmd xRowid }
+proc negrowid {cmd} { expr -1 * [$cmd xRowid] }
+
+sqlite3_fts5_create_function db posrowid posrowid
+sqlite3_fts5_create_function db negrowid negrowid
+
+do_execsql_test 1.0.0 {
+  CREATE VIRTUAL TABLE t1 USING fts5(x);
+  INSERT INTO t1 VALUES('a b c');
+  INSERT INTO t1 VALUES('d a d');
+  INSERT INTO t1 VALUES('c b a');
+}
+do_execsql_test 1.0.1 {
+  INSERT INTO t1(t1, rank) VALUES('rank', 'posrowid()');
+  SELECT rowid FROM t1('a') ORDER BY rank;
+} {1 2 3}
+do_execsql_test 1.0.2 {
+  INSERT INTO t1(t1, rank) VALUES('rank', 'negrowid()');
+  SELECT rowid FROM t1('a') ORDER BY rank;
+} {3 2 1}
+
+faultsim_save_and_close 
+do_faultsim_test 1.1 -faults oom-* -prep {
+  faultsim_restore_and_reopen
+  sqlite3_fts5_create_function db posrowid posrowid
+  sqlite3_fts5_create_function db negrowid negrowid
+  execsql { SELECT * FROM t1('*reads') }
+} -body {
+  execsql { INSERT INTO t1(t1, rank) VALUES('rank', 'posrowid()') }
+} -test {
+
+  faultsim_test_result [list 0 {}]
+  sqlite3 db2 test.db
+  set ex [db2 one { SELECT v FROM t1_config WHERE k='rank' }]
+  switch -- $ex {
+    "posrowid()" { set ex {1 2 3} }
+    "negrowid()" { set ex {3 2 1} }
+    default { error 1 }
+  }
+  
+  set res [db eval { SELECT rowid FROM t1('a') ORDER BY rank }]
+  if {$res != $ex} {
+    error "2: expected {$ex} got {$res}"
+  }
+  db2 close
+}
+
+
+
+
+finish_test
+
index 2bc02cf49afe32945be7d95b77c145fd46a0602f..67475fe6301aaa6d744ccc82644d22fc79e63aae 100644 (file)
@@ -350,7 +350,7 @@ do_execsql_test 14.3 {
 
 do_execsql_test 14.4 {
   SELECT rowid, x, x1 FROM x1 WHERE x1 MATCH '*reads'
-} {0 {} 3}
+} {0 {} 4}
 
 #-------------------------------------------------------------------------
 reset_db
index 8d623daff5f59334a9b9c8279103f91e806389bc..5533f5693d90950f6dedeba658509d5229a89152 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C More\schanges\sto\sthe\sshellN.test\sscripts\sto\sget\sthem\sworking\son\sall\svariations\nof\sWindows.
-D 2016-03-26T15:36:36.768
+C Fix\sa\sproblem\swith\sOOM\shandling\swhen\ssetting\san\sfts5\sconfiguration\soption.
+D 2016-03-26T20:11:04.128
 F Makefile.in f53429fb2f313c099283659d0df6f20f932c861f
 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
 F Makefile.msc df0bf9ff7f8b3f4dd9fb4cc43f92fe58f6ec5c66
@@ -98,15 +98,15 @@ F ext/fts3/unicode/mkunicode.tcl 2debed3f582d77b3fdd0b8830880250021571fd8
 F ext/fts3/unicode/parseunicode.tcl da577d1384810fb4e2b209bf3313074353193e95
 F ext/fts5/extract_api_docs.tcl a36e54ec777172ddd3f9a88daf593b00848368e0
 F ext/fts5/fts5.h ff9c2782e8ed890b0de2f697a8d63971939e70c7
-F ext/fts5/fts5Int.h 3677076aecbf645a7f2a019115c6a4ec3272dd78
+F ext/fts5/fts5Int.h dde3c47b9f0e1603ab17cb6603b9409e426ce21d
 F ext/fts5/fts5_aux.c daa57fb45216491814520bbb587e97bf81ced458
 F ext/fts5/fts5_buffer.c 4c1502d4c956cd092c89ce4480867f9d8bf325cd
 F ext/fts5/fts5_config.c 5af9c360e99669d29f06492c370892394aba0857
 F ext/fts5/fts5_expr.c 5ca4bafe29aa3d27683c90e836192e4aefd20a3f
 F ext/fts5/fts5_hash.c f3a7217c86eb8f272871be5f6aa1b6798960a337
-F ext/fts5/fts5_index.c fdd82bb421a5d1e64d004acb43f4dd9970c8d2b3
-F ext/fts5/fts5_main.c b4a0fc5bf17f2f1f056ee76cdd7d2af08b360f55
-F ext/fts5/fts5_storage.c 3309c6a8e34b974513016fd1ef47c83f5898f94c
+F ext/fts5/fts5_index.c 9019595c2dd17e1e109e0cfa7fc8bc449770f03e
+F ext/fts5/fts5_main.c 1e1e6e2d6df6b224fe9b2c75bcbe265c73b8712d
+F ext/fts5/fts5_storage.c e0aa8509e01eb22ae8e198c1de9c3200755c0d94
 F ext/fts5/fts5_tcl.c f8731e0508299bd43f1a2eff7dbeaac870768966
 F ext/fts5/fts5_test_mi.c 783b86697ebf773c18fc109992426c0173a055bc
 F ext/fts5/fts5_test_tok.c db08af63673c3a7d39f053b36fd6e065017706be
@@ -151,7 +151,7 @@ F ext/fts5/test/fts5eb.test c516ae0c934be6fd29ec95ea8b5f11f461311535
 F ext/fts5/test/fts5fault1.test e09040d3e17b8c0837101e8c79c8a874c4376fb7
 F ext/fts5/test/fts5fault2.test d8c6c7f916ccbdfc10b2c69530e9dd3bc8313232
 F ext/fts5/test/fts5fault3.test d6e9577d4312e331a913c72931bf131704efc8f3
-F ext/fts5/test/fts5fault4.test dcbe3043c5611edd350191ea03a8daa190f0de5a
+F ext/fts5/test/fts5fault4.test 532b6dacb963016cbf7003196bd87fb366540277
 F ext/fts5/test/fts5fault5.test 10c13a783de3f42a21e3e53e123b62ed0c3a1618
 F ext/fts5/test/fts5fault6.test 9682664d679643ac6736e90c225526cc84073cda
 F ext/fts5/test/fts5fault7.test cb14ea3c1f42394f06f2284abc58eecee6ff8080
@@ -159,6 +159,7 @@ F ext/fts5/test/fts5fault8.test 6785af34bd1760de74e2824ea9c161965af78f85
 F ext/fts5/test/fts5fault9.test e10e395428a9ea0596ebe752ff7123d16ab78e08
 F ext/fts5/test/fts5faultA.test fa5d59c0ff62b7125cd14eee38ded1c46e15a7ea
 F ext/fts5/test/fts5faultB.test 92ae906284062bf081b6c854afa54dcb1aa9ef88
+F ext/fts5/test/fts5faultC.test 10da76c6b69df05ff9095c7e56dc3a4b8d0e8f20
 F ext/fts5/test/fts5full.test 6f6143af0c6700501d9fd597189dfab1555bb741
 F ext/fts5/test/fts5fuzz1.test bece4695fc169b61ab236ada7931c6e4942cbef9
 F ext/fts5/test/fts5hash.test 06f9309ccb4d5050a131594e9e47d0b21456837d
@@ -180,7 +181,7 @@ F ext/fts5/test/fts5rank.test 7e9e64eac7245637f6f2033aec4b292aaf611aab
 F ext/fts5/test/fts5rebuild.test 03935f617ace91ed23a6099c7c74d905227ff29b
 F ext/fts5/test/fts5restart.test c17728fdea26e7d0f617d22ad5b4b2862b994c17
 F ext/fts5/test/fts5rowid.test 16908a99d6efc9ba21081b4f2b86b3fc699839a6
-F ext/fts5/test/fts5simple.test cd23d4072ea095d652c9b6db12284cc642e49c98
+F ext/fts5/test/fts5simple.test f157c8b068f5e68473ad86bfe220b07a84e0209f
 F ext/fts5/test/fts5simple2.test 98377ae1ff7749a42c21fe1a139c1ed312522c46
 F ext/fts5/test/fts5simple3.test 8e71733b3d1b0e695011d02c68ebc5ca40b6124e
 F ext/fts5/test/fts5synonym.test 6475d189c2e20d60795808f83e36bf9318708d48
@@ -1459,7 +1460,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P 3bd499d3bdf4e80f83513966c2ee9dd11e67cbd1
-R 0f980ceb534899c3d74e7aadbdc990e8
-U drh
-Z 6df6f858842cee4837ac5cccff369bba
+P 8213c2f58167243411d29cc58e303b4be656f756
+R be57f13787d59ee7ecd47b81dbe52717
+T *branch * fts5
+T *sym-fts5 *
+T -sym-trunk *
+U dan
+Z 9cae65c93dd0ffab0ada61227cd993a5
index 23fb133ea29069a18559fcd340b2169fa8c686b1..8024331f68c679de8dbcf0268038d574050c702a 100644 (file)
@@ -1 +1 @@
-8213c2f58167243411d29cc58e303b4be656f756
\ No newline at end of file
+53b80a6d054a1c87311b3dc1c2bcfcc1b676b05a
\ No newline at end of file