Merge performance enhancements and other patches.

FossilOrigin-Name: 44e1b55aab331933719b67f7fcf7d335234b8b79599fba6033a0a27094bcb644
diff --git a/ext/fts3/fts3_unicode2.c b/ext/fts3/fts3_unicode2.c
index c0395d9..4f92e52 100644
--- a/ext/fts3/fts3_unicode2.c
+++ b/ext/fts3/fts3_unicode2.c
@@ -200,7 +200,7 @@
     'w',       'x',       'y',       'z',       'h',       't',       
     'w',       'y',       'a',       'a'|HIBIT, 'a'|HIBIT, 'a'|HIBIT, 
     'e',       'e'|HIBIT, 'e'|HIBIT, 'i',       'o',       'o'|HIBIT, 
-    'o'|HIBIT, 'o'|HIBIT, 'u',       'u'|HIBIT, 'u'|HIBIT, 'y',  
+    'o'|HIBIT, 'o'|HIBIT, 'u',       'u'|HIBIT, 'u'|HIBIT, 'y',       
   };
 
   unsigned int key = (((unsigned int)c)<<3) | 0x00000007;
@@ -231,8 +231,8 @@
   unsigned int mask1 = 0x000361F8;
   if( c<768 || c>817 ) return 0;
   return (c < 768+32) ?
-      (mask0 & (1 << (c-768))) :
-      (mask1 & (1 << (c-768-32)));
+      (mask0 & ((unsigned int)1 << (c-768))) :
+      (mask1 & ((unsigned int)1 << (c-768-32)));
 }
 
 
diff --git a/ext/fts3/fts3_write.c b/ext/fts3/fts3_write.c
index 07d73ab..2ff9f04 100644
--- a/ext/fts3/fts3_write.c
+++ b/ext/fts3/fts3_write.c
@@ -1409,7 +1409,7 @@
   ** b-tree node. And that the final byte of the doclist is 0x00. If either 
   ** of these statements is untrue, then the data structure is corrupt.
   */
-  if( (&pReader->aNode[pReader->nNode] - pReader->aDoclist)<pReader->nDoclist
+  if( pReader->nDoclist > pReader->nNode-(pReader->aDoclist-pReader->aNode)
    || (pReader->nPopulate==0 && pReader->aDoclist[pReader->nDoclist-1])
   ){
     return FTS_CORRUPT_VTAB;
diff --git a/ext/fts3/unicode/mkunicode.tcl b/ext/fts3/unicode/mkunicode.tcl
index 8465262..872ec13 100644
--- a/ext/fts3/unicode/mkunicode.tcl
+++ b/ext/fts3/unicode/mkunicode.tcl
@@ -63,14 +63,15 @@
   }
   puts ""
   puts "  \};"
+  puts "#define HIBIT ((char)0x80)"
   puts "  char aChar\[\] = \{"
   puts -nonewline "    '\\0',      "
   set i 1
   foreach c $aChar f $aFlag {
     if { $f } {
-      set str "'$c'|0x80,  "
+      set str "'$c'|HIBIT, "
     } else {
-      set str "'$c'|0x00,  "
+      set str "'$c',       "
     }
     if {$c == ""} { set str "'\\0',      " }
 
@@ -134,8 +135,8 @@
 
   puts "  if( c<$iFirst || c>$iLast ) return 0;"
   puts "  return (c < $iFirst+32) ?"
-  puts "      (mask0 & (1 << (c-$iFirst))) :"
-  puts "      (mask1 & (1 << (c-$iFirst-32)));"
+  puts "      (mask0 & ((unsigned int)1 << (c-$iFirst))) :"
+  puts "      (mask1 & ((unsigned int)1 << (c-$iFirst-32)));"
   puts "\}"
 }
 
@@ -699,7 +700,7 @@
     static u16 aFts5UnicodeMap[] = {$aMapArray};
     static u16 aFts5UnicodeData[] = {$aDataArray};
 
-    int sqlite3Fts5UnicodeCategory(int iCode) { 
+    int sqlite3Fts5UnicodeCategory(u32 iCode) { 
       int iRes = -1;
       int iHi;
       int iLo;
@@ -782,7 +783,7 @@
           aArray[0] = 1;
         }
 
-        c = sqlite3Fts5UnicodeCategory(i);
+        c = sqlite3Fts5UnicodeCategory((u32)i);
         if( aArray[c]==0 ){
           *piCode = i;
           return 1;
diff --git a/ext/fts5/fts5Int.h b/ext/fts5/fts5Int.h
index a460a7a..b4f4b07 100644
--- a/ext/fts5/fts5Int.h
+++ b/ext/fts5/fts5Int.h
@@ -788,7 +788,7 @@
 int sqlite3Fts5UnicodeFold(int c, int bRemoveDiacritic);
 
 int sqlite3Fts5UnicodeCatParse(const char*, u8*);
-int sqlite3Fts5UnicodeCategory(int iCode);
+int sqlite3Fts5UnicodeCategory(u32 iCode);
 void sqlite3Fts5UnicodeAscii(u8*, u8*);
 /*
 ** End of interface to code in fts5_unicode2.c.
diff --git a/ext/fts5/fts5_expr.c b/ext/fts5/fts5_expr.c
index a09fe7d..b56434e 100644
--- a/ext/fts5/fts5_expr.c
+++ b/ext/fts5/fts5_expr.c
@@ -2553,7 +2553,7 @@
   sqlite3Fts5UnicodeCatParse("N*", aArr);
   sqlite3Fts5UnicodeCatParse("Co", aArr);
   iCode = sqlite3_value_int(apVal[0]);
-  sqlite3_result_int(pCtx, aArr[sqlite3Fts5UnicodeCategory(iCode)]);
+  sqlite3_result_int(pCtx, aArr[sqlite3Fts5UnicodeCategory((u32)iCode)]);
 }
 
 static void fts5ExprFold(
diff --git a/ext/fts5/fts5_index.c b/ext/fts5/fts5_index.c
index a2792f8..f786e8d 100644
--- a/ext/fts5/fts5_index.c
+++ b/ext/fts5/fts5_index.c
@@ -690,8 +690,8 @@
         pRet = 0;
       }else{
         /* TODO1: Fix this */
-        pRet->szLeaf = fts5GetU16(&pRet->p[2]);
         pRet->p[nByte] = 0x00;
+        pRet->szLeaf = fts5GetU16(&pRet->p[2]);
       }
     }
     p->rc = rc;
@@ -860,6 +860,11 @@
   ** structure record.  */
   i += fts5GetVarint32(&pData[i], nLevel);
   i += fts5GetVarint32(&pData[i], nSegment);
+  if( nLevel>FTS5_MAX_SEGMENT   || nLevel<0
+   || nSegment>FTS5_MAX_SEGMENT || nSegment<0
+  ){
+    return FTS5_CORRUPT;
+  }
   nByte = (
       sizeof(Fts5Structure) +                    /* Main structure */
       sizeof(Fts5StructureLevel) * (nLevel-1)    /* aLevel[] array */
@@ -892,13 +897,18 @@
       if( rc==SQLITE_OK ){
         pLvl->nSeg = nTotal;
         for(iSeg=0; iSeg<nTotal; iSeg++){
+          Fts5StructureSegment *pSeg = &pLvl->aSeg[iSeg];
           if( i>=nData ){
             rc = FTS5_CORRUPT;
             break;
           }
-          i += fts5GetVarint32(&pData[i], pLvl->aSeg[iSeg].iSegid);
-          i += fts5GetVarint32(&pData[i], pLvl->aSeg[iSeg].pgnoFirst);
-          i += fts5GetVarint32(&pData[i], pLvl->aSeg[iSeg].pgnoLast);
+          i += fts5GetVarint32(&pData[i], pSeg->iSegid);
+          i += fts5GetVarint32(&pData[i], pSeg->pgnoFirst);
+          i += fts5GetVarint32(&pData[i], pSeg->pgnoLast);
+          if( pSeg->pgnoLast<pSeg->pgnoFirst ){
+            rc = FTS5_CORRUPT;
+            break;
+          }
         }
       }
     }
@@ -1641,12 +1651,13 @@
   int nNew;                       /* Bytes of new data */
 
   iOff += fts5GetVarint32(&a[iOff], nNew);
-  if( iOff+nNew>pIter->pLeaf->nn ){
+  if( iOff+nNew>pIter->pLeaf->nn || nKeep>pIter->term.n ){
     p->rc = FTS5_CORRUPT;
     return;
   }
   pIter->term.n = nKeep;
   fts5BufferAppendBlob(&p->rc, &pIter->term, nNew, &a[iOff]);
+  assert( pIter->term.n<=pIter->term.nSpace );
   iOff += nNew;
   pIter->iTermLeafOffset = iOff;
   pIter->iTermLeafPgno = pIter->iLeafPgno;
@@ -1711,7 +1722,7 @@
   if( p->rc==SQLITE_OK ){
     pIter->iLeafOffset = 4;
     assert_nc( pIter->pLeaf->nn>4 );
-    assert( fts5LeafFirstTermOff(pIter->pLeaf)==4 );
+    assert_nc( fts5LeafFirstTermOff(pIter->pLeaf)==4 );
     pIter->iPgidxOff = pIter->pLeaf->szLeaf+1;
     fts5SegIterLoadTerm(p, pIter, 0);
     fts5SegIterLoadNPos(p, pIter);
@@ -3568,14 +3579,14 @@
         for(iSeg=0; iSeg<pStruct->aLevel[iLvl].nSeg; iSeg++){
           int iId = pStruct->aLevel[iLvl].aSeg[iSeg].iSegid;
           if( iId<=FTS5_MAX_SEGMENT ){
-            aUsed[(iId-1) / 32] |= 1 << ((iId-1) % 32);
+            aUsed[(iId-1) / 32] |= (u32)1 << ((iId-1) % 32);
           }
         }
       }
 
       for(i=0; aUsed[i]==0xFFFFFFFF; i++);
       mask = aUsed[i];
-      for(iSegid=0; mask & (1 << iSegid); iSegid++);
+      for(iSegid=0; mask & ((u32)1 << iSegid); iSegid++);
       iSegid += 1 + i*32;
 
 #ifdef SQLITE_DEBUG
@@ -3893,6 +3904,7 @@
   int nPrefix;                    /* Bytes of prefix compression for term */
   Fts5PageWriter *pPage = &pWriter->writer;
   Fts5Buffer *pPgidx = &pWriter->writer.pgidx;
+  int nMin = MIN(pPage->term.n, nTerm);
 
   assert( p->rc==SQLITE_OK );
   assert( pPage->buf.n>=4 );
@@ -3934,13 +3946,13 @@
       ** inefficient, but still correct.  */
       int n = nTerm;
       if( pPage->term.n ){
-        n = 1 + fts5PrefixCompress(pPage->term.n, pPage->term.p, pTerm);
+        n = 1 + fts5PrefixCompress(nMin, pPage->term.p, pTerm);
       }
       fts5WriteBtreeTerm(p, pWriter, n, pTerm);
       pPage = &pWriter->writer;
     }
   }else{
-    nPrefix = fts5PrefixCompress(pPage->term.n, pPage->term.p, pTerm);
+    nPrefix = fts5PrefixCompress(nMin, pPage->term.p, pTerm);
     fts5BufferAppendVarint(&p->rc, &pPage->buf, nPrefix);
   }
 
@@ -5858,7 +5870,7 @@
 
       iOff = fts5LeafFirstTermOff(pLeaf);
       iRowidOff = fts5LeafFirstRowidOff(pLeaf);
-      if( iRowidOff>=iOff ){
+      if( iRowidOff>=iOff || iOff>=pLeaf->szLeaf ){
         p->rc = FTS5_CORRUPT;
       }else{
         iOff += fts5GetVarint32(&pLeaf->p[iOff], nTerm);
@@ -6273,8 +6285,7 @@
   nSpace = n + FTS5_DATA_ZERO_PADDING;
   a = (u8*)sqlite3Fts5MallocZero(&rc, nSpace);
   if( a==0 ) goto decode_out;
-  memcpy(a, aBlob, n);
-
+  if( n>0 ) memcpy(a, aBlob, n);
 
   fts5DecodeRowid(iRowid, &iSegid, &bDlidx, &iHeight, &iPgno);
 
diff --git a/ext/fts5/fts5_test_tok.c b/ext/fts5/fts5_test_tok.c
index 6f71e65..3ac6e35 100644
--- a/ext/fts5/fts5_test_tok.c
+++ b/ext/fts5/fts5_test_tok.c
@@ -378,7 +378,7 @@
     if( pCsr->zInput==0 ){
       rc = SQLITE_NOMEM;
     }else{
-      memcpy(pCsr->zInput, zByte, nByte);
+      if( nByte>0 ) memcpy(pCsr->zInput, zByte, nByte);
       pCsr->zInput[nByte] = 0;
       rc = pTab->tok.xTokenize(
           pTab->pTok, (void*)pCsr, 0, zByte, nByte, fts5tokCb
diff --git a/ext/fts5/fts5_tokenize.c b/ext/fts5/fts5_tokenize.c
index 35526a3..fd574d0 100644
--- a/ext/fts5/fts5_tokenize.c
+++ b/ext/fts5/fts5_tokenize.c
@@ -262,7 +262,7 @@
       const unsigned char *zCsr = (const unsigned char*)z;
       const unsigned char *zTerm = (const unsigned char*)&z[n];
       while( zCsr<zTerm ){
-        int iCode;
+        u32 iCode;
         int bToken;
         READ_UTF8(zCsr, zTerm, iCode);
         if( iCode<128 ){
@@ -429,7 +429,7 @@
 */
 static int fts5UnicodeIsAlnum(Unicode61Tokenizer *p, int iCode){
   return (
-    p->aCategory[sqlite3Fts5UnicodeCategory(iCode)]
+    p->aCategory[sqlite3Fts5UnicodeCategory((u32)iCode)]
     ^ fts5UnicodeIsException(p, iCode)
   );
 }
@@ -458,7 +458,7 @@
   /* Each iteration of this loop gobbles up a contiguous run of separators,
   ** then the next token.  */
   while( rc==SQLITE_OK ){
-    int iCode;                    /* non-ASCII codepoint read from input */
+    u32 iCode;                    /* non-ASCII codepoint read from input */
     char *zOut = aFold;
     int is;
     int ie;
diff --git a/ext/fts5/fts5_unicode2.c b/ext/fts5/fts5_unicode2.c
index 8bb1cd9..0b0e9f7 100644
--- a/ext/fts5/fts5_unicode2.c
+++ b/ext/fts5/fts5_unicode2.c
@@ -69,7 +69,7 @@
     'w',       'x',       'y',       'z',       'h',       't',       
     'w',       'y',       'a',       'a'|HIBIT, 'a'|HIBIT, 'a'|HIBIT, 
     'e',       'e'|HIBIT, 'e'|HIBIT, 'i',       'o',       'o'|HIBIT, 
-    'o'|HIBIT, 'o'|HIBIT, 'u',       'u'|HIBIT, 'u'|HIBIT, 'y',  
+    'o'|HIBIT, 'o'|HIBIT, 'u',       'u'|HIBIT, 'u'|HIBIT, 'y',       
   };
 
   unsigned int key = (((unsigned int)c)<<3) | 0x00000007;
@@ -100,8 +100,8 @@
   unsigned int mask1 = 0x000361F8;
   if( c<768 || c>817 ) return 0;
   return (c < 768+32) ?
-      (mask0 & (1 << (c-768))) :
-      (mask1 & (1 << (c-768-32)));
+      (mask0 & ((unsigned int)1 << (c-768))) :
+      (mask1 & ((unsigned int)1 << (c-768-32)));
 }
 
 
@@ -249,6 +249,7 @@
   return ret;
 }
 
+
 int sqlite3Fts5UnicodeCatParse(const char *zCat, u8 *aArray){ 
   aArray[0] = 1;
   switch( zCat[0] ){
@@ -730,7 +731,7 @@
     34,    3074,  7692,  63,    63,    
   };
 
-int sqlite3Fts5UnicodeCategory(int iCode) { 
+int sqlite3Fts5UnicodeCategory(u32 iCode) { 
   int iRes = -1;
   int iHi;
   int iLo;
@@ -773,3 +774,4 @@
     iTbl++;
   }
 }
+
diff --git a/ext/fts5/test/fts5corrupt3.test b/ext/fts5/test/fts5corrupt3.test
index 71de3d0..32cf9ab 100644
--- a/ext/fts5/test/fts5corrupt3.test
+++ b/ext/fts5/test/fts5corrupt3.test
@@ -35,8 +35,6 @@
   }
 }
 
-if 1 {
-
 # Create a simple FTS5 table containing 100 documents. Each document 
 # contains 10 terms, each of which start with the character "x".
 #
@@ -380,8 +378,6 @@
   }
 } {}
 
-}
-
 #------------------------------------------------------------------------
 # Corruption within the structure record.
 #
@@ -768,10 +764,874 @@
 SELECT * FROM t1 WHERE t1 MATCH 'abandon';
 }]} {}
 
-do_catchsql_test 14.1 {
+do_catchsql_test 13.1 {
   SELECT * FROM t1 WHERE t1 MATCH 'abandon'; 
 } {1 {vtable constructor failed: t1}}
 
+#-------------------------------------------------------------------------
+reset_db
+do_test 14.0 {
+  sqlite3 db {}
+  db deserialize [decode_hexdb {
+| size 28672 pagesize 4096 filename c14b.db
+| page 1 offset 0
+|      0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00   SQLite format 3.
+|     16: 10 00 01 01 00 40 20 20 00 00 00 01 00 00 00 07   .....@  ........
+|     32: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00   ................
+|     48: 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00   ................
+|     80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01   ................
+|     96: 00 2e 30 38 0d 00 00 00 07 0d d2 00 0f c4 0f 6d   ..08...........m
+|    112: 0f 02 0e ab 0e 4e 0d f6 0d d2 00 00 00 00 00 00   .....N..........
+|   3536: 00 00 22 07 06 17 11 11 01 31 74 61 62 6c 65 74   .........1tablet
+|   3552: 32 74 32 07 43 52 45 41 54 45 20 54 41 42 4c 45   2t2.CREATE TABLE
+|   3568: 20 74 32 28 78 29 56 06 06 17 1f 1f 01 7d 74 61    t2(x)V.......ta
+|   3584: 62 6c 65 74 31 5f 63 6f 6e 66 69 67 74 31 5f 63   blet1_configt1_c
+|   3600: 6f 6e 66 69 67 06 43 52 45 41 54 45 20 54 41 42   onfig.CREATE TAB
+|   3616: 4c 45 20 27 74 31 5f 63 6f 6e 66 69 67 27 28 6b   LE 't1_config'(k
+|   3632: 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 76 29    PRIMARY KEY, v)
+|   3648: 20 57 49 54 48 4f 55 54 20 52 4f 57 49 44 5b 05    WITHOUT ROWID[.
+|   3664: 07 17 21 21 01 81 01 74 61 62 6c 65 74 31 5f 64   ..!!...tablet1_d
+|   3680: 6f 63 73 69 7a 65 74 31 5f 64 6f 63 73 69 7a 65   ocsizet1_docsize
+|   3696: 05 43 52 45 41 54 45 20 54 41 42 4c 45 20 27 74   .CREATE TABLE 't
+|   3712: 31 5f 64 6f 63 73 69 7a 65 27 28 69 64 20 49 4e   1_docsize'(id IN
+|   3728: 54 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45   TEGER PRIMARY KE
+|   3744: 59 2c 20 73 7a 20 42 4c 4f 42 29 55 04 06 17 21   Y, sz BLOB)U...!
+|   3760: 21 01 77 74 61 62 6c 65 74 31 5f 63 6f 6e 74 65   !.wtablet1_conte
+|   3776: 6e 74 74 31 5f 63 6f 6e 74 65 6e 74 04 43 52 45   ntt1_content.CRE
+|   3792: 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 63 6f   ATE TABLE 't1_co
+|   3808: 6e 74 65 6e 74 27 28 69 64 20 49 4e 54 45 47 45   ntent'(id INTEGE
+|   3824: 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 63   R PRIMARY KEY, c
+|   3840: 30 29 69 03 07 17 19 19 01 81 2d 74 61 62 6c 65   0)i.......-table
+|   3856: 74 31 5f 69 64 78 74 31 5f 69 64 78 03 43 52 45   t1_idxt1_idx.CRE
+|   3872: 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 69 64   ATE TABLE 't1_id
+|   3888: 78 27 28 73 65 67 69 64 2c 20 74 65 72 6d 2c 20   x'(segid, term, 
+|   3904: 70 67 6e 6f 2c 20 50 52 49 4d 41 52 59 20 4b 45   pgno, PRIMARY KE
+|   3920: 59 28 73 65 67 69 64 2c 20 74 65 72 6d 29 29 20   Y(segid, term)) 
+|   3936: 57 49 54 48 4f 55 54 20 52 4f 57 49 44 55 02 07   WITHOUT ROWIDU..
+|   3952: 17 1b 1b 01 81 01 74 61 62 6c 65 74 31 5f 64 61   ......tablet1_da
+|   3968: 74 61 74 31 5f 64 61 74 61 02 43 52 45 41 54 45   tat1_data.CREATE
+|   3984: 20 54 41 42 4c 45 20 27 74 31 5f 64 61 74 61 27    TABLE 't1_data'
+|   4000: 28 69 64 20 49 4e 54 45 47 45 52 20 50 52 49 4d   (id INTEGER PRIM
+|   4016: 41 52 59 20 4b 45 59 2c 20 62 6c 6f 63 6b 20 42   ARY KEY, block B
+|   4032: 4c 4f 42 29 3a 01 06 17 11 11 08 63 74 61 62 6c   LOB):......ctabl
+|   4048: 65 74 31 74 31 43 52 45 41 54 45 20 56 49 52 54   et1t1CREATE VIRT
+|   4064: 55 41 4c 20 54 41 42 4c 45 20 74 31 20 55 53 49   UAL TABLE t1 USI
+|   4080: 4e 47 20 66 74 73 35 28 63 6f 6e 74 65 6e 74 29   NG fts5(content)
+| page 2 offset 4096
+|      0: 0d 0f ef 00 04 0f 18 00 0f e8 0f 18 0f bd 0f 2c   ...............,
+|   3856: 00 00 00 00 00 00 00 00 12 0a 03 00 2a 00 00 00   ............*...
+|   3872: 00 01 02 02 00 02 01 01 01 02 01 01 81 09 88 80   ................
+|   3888: 80 80 80 01 04 00 82 16 00 00 00 79 06 30 61 62   ...........y.0ab
+|   3904: 61 63 6b 08 02 07 04 04 6e 64 6f 6e 08 02 05 02   ack.....ndon....
+|   3920: 05 63 74 69 76 65 04 02 02 04 02 0b 02 04 6c 70   .ctive........lp
+|   3936: 68 61 08 04 02 0a 02 03 74 6b 6d 06 02 02 03 02   ha......tkm.....
+|   3952: 6f 6d 08 02 09 05 02 69 63 07 02 02 01 06 62 61   om.....ic.....ba
+|   3968: 63 6b 75 70 08 02 04 02 05 6f 6f 6d 65 72 05 02   ckup.....oomer..
+|   3984: 02 01 0c 63 68 61 6e 6e 65 62 6f 6f 6d 65 72 08   ...channeboomer.
+|   4000: 02 08 07 01 6c 08 02 03 01 04 74 65 73 74 08 02   ....l.....test..
+|   4016: 06 04 0a 09 0d 0a 08 07 07 0b 0a 11 06 24 84 80   .............$..
+|   4032: 80 80 80 01 03 00 4e 00 00 00 1e 06 30 61 62 61   ......N.....0aba
+|   4048: 63 6b 01 02 02 04 02 66 74 02 02 02 04 04 6e 64   ck.....ft.....nd
+|   4064: 6f 6e 03 02 02 03 9a 07 05 01 03 00 10 08 11 00   on..............
+|   4080: 00 00 11 24 00 00 00 00 01 01 01 00 01 01 01 01   ...$............
+| page 3 offset 8192
+|      0: 0a 00 00 00 02 0f f3 00 0f fa 0f f3 00 00 00 00   ................
+|   4080: 00 00 00 06 04 01 0c 01 02 02 05 04 09 0c 01 02   ................
+| page 4 offset 12288
+|      0: 0d 00 00 00 08 0f 6a 00 0f f6 0f ec 0f e0 0f d5   ......j.........
+|     16: 0f ca 0f c1 0f b6 0f 6a 00 00 00 00 00 00 00 00   .......j........
+|   3936: 00 00 00 00 00 00 00 00 00 00 4a 08 04 00 81 19   ..........J.....
+|   3952: 61 6c 70 68 61 20 63 68 61 6e 6e 65 6c 20 62 61   alpha channel ba
+|   3968: 63 6b 75 70 20 61 62 61 6e 64 6f 6e 20 74 65 73   ckup abandon tes
+|   3984: 74 20 61 62 61 63 6b 20 63 68 61 6e 6e 65 62 6f   t aback channebo
+|   4000: 6f 6d 65 72 20 61 74 6f 6d 20 61 6c 70 68 61 20   omer atom alpha 
+|   4016: 61 63 74 69 76 65 09 07 03 00 19 61 74 6f 6d 69   active.....atomi
+|   4032: 63 07 06 03 00 15 61 74 6b 6d 09 05 03 00 19 62   c.....atkm.....b
+|   4048: 6f 6f 6d 65 72 09 04 03 00 19 61 63 74 69 76 65   oomer.....active
+|   4064: 0a 03 03 00 1b 61 62 61 6e 64 6f 6e 08 02 03 00   .....abandon....
+|   4080: 17 61 62 61 66 74 08 01 03 00 17 61 62 61 63 6b   .abaft.....aback
+| page 5 offset 16384
+|      0: 0d 00 00 00 08 0f d0 00 0f fa 0f f4 0f ee 0f e8   ................
+|     16: 0f e2 0f dc 0f d6 0f d0 00 00 00 00 00 00 00 00   ................
+|   4048: 04 08 03 00 0e 0a 04 07 03 00 0e 01 04 06 03 00   ................
+|   4064: 0e 01 04 05 03 00 0e 01 04 04 03 00 0e 01 04 03   ................
+|   4080: 03 00 0e 01 04 02 03 00 0e 01 04 01 03 00 0e 01   ................
+| page 6 offset 20480
+|      0: 0a 00 00 00 01 0f f4 00 0f f4 00 00 00 00 00 00   ................
+|   4080: 00 00 00 00 0b 03 1b 01 76 65 72 73 69 6f 6e 04   ........version.
+| page 7 offset 24576
+|      0: 0d 00 00 00 03 0f d6 00 0f f4 0f e1 0f d6 00 00   ................
+|   4048: 00 00 00 00 00 00 09 03 02 1b 72 65 62 75 69 6c   ..........rebuil
+|   4064: 64 11 02 02 2b 69 6e 74 65 67 72 69 74 79 2d 63   d...+integrity-c
+|   4080: 68 65 63 6b 0a 01 02 1d 6f 70 74 69 6d 69 7a 65   heck....optimize
+| end c14b.db
+}]} {}
+
+do_catchsql_test 14.1 {
+  INSERT INTO t1(t1) VALUES('optimize');
+} {1 {database disk image is malformed}}
+
+#---------------------------------------------------------------------------
+#
+reset_db
+do_test 15.0 {
+  sqlite3 db {}
+  db deserialize [decode_hexdb {
+| size 32768 pagesize 4096 filename c16.db
+| page 1 offset 0
+|      0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00   SQLite format 3.
+|     16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 07   .....@  ........
+|     32: 00 00 00 00 00 00 00 00 00 00 00 07 00 00 00 00   ................
+|     48: 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00   ................
+|     96: 00 00 00 00 0d 00 00 00 07 0d d2 00 0f c4 0f 6d   ...............m
+|    112: 0f 02 0e ab 0e 4e 0d f6 0d d2 00 00 00 00 00 00   .....N..........
+|   3536: 00 00 22 07 06 17 11 11 01 31 74 61 62 6c 65 74   .........1tablet
+|   3552: 32 74 32 07 43 52 45 41 54 45 20 54 41 42 4c 45   2t2.CREATE TABLE
+|   3568: 20 74 32 28 78 29 56 06 06 17 1f 1f 01 7d 74 61    t2(x)V.......ta
+|   3584: 62 6c 65 74 31 5f 63 6f 6e 66 69 67 74 31 5f 63   blet1_configt1_c
+|   3600: 6f 6e 66 69 67 06 43 52 45 41 54 45 20 54 41 42   onfig.CREATE TAB
+|   3616: 4c 45 20 27 74 31 5f 63 6f 6e 66 69 67 27 28 6b   LE 't1_config'(k
+|   3632: 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 76 29    PRIMARY KEY, v)
+|   3648: 20 57 49 54 48 4f 55 54 20 52 4f 57 49 44 5b 05    WITHOUT ROWID[.
+|   3664: 07 17 21 21 01 81 01 74 61 62 6c 00 0f f6 0f ec   ..!!...tabl.....
+|   3680: 0f e0 73 69 7a 65 74 31 5f 64 6f 63 73 69 7a 65   ..sizet1_docsize
+|   3696: 05 43 52 45 41 54 45 20 54 41 42 4c 45 20 27 74   .CREATE TABLE 't
+|   3712: 31 5f 64 6f 63 73 69 7a 65 27 28 69 64 20 49 4e   1_docsize'(id IN
+|   3728: 54 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45   TEGER PRIMARY KE
+|   3744: 59 2c 20 73 7a 20 42 4c 4f 42 29 55 04 06 17 21   Y, sz BLOB)U...!
+|   3760: 21 01 77 74 61 62 6c 65 74 31 5f 63 6f 6e 74 65   !.wtablet1_conte
+|   3776: 6e 74 74 31 5f 63 6f 6e 74 65 6e 74 04 43 52 45   ntt1_content.CRE
+|   3792: 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 63 6f   ATE TABLE 't1_co
+|   3808: 6e 74 65 6e 74 27 28 69 64 20 49 4e 54 45 47 45   ntent'(id INTEGE
+|   3824: 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 63   R PRIMARY KEY, c
+|   3840: 30 29 69 03 07 17 19 19 01 81 2d 74 61 62 6c 65   0)i.......-table
+|   3856: 74 31 5f 69 64 78 74 31 5f 69 64 78 03 43 52 45   t1_idxt1_idx.CRE
+|   3872: 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 69 64   ATE TABLE 't1_id
+|   3888: 78 27 28 73 65 67 69 64 2c 20 74 65 72 6d 2c 20   x'(segid, term, 
+|   3904: 70 67 6e 6f 2c 20 50 52 49 4d 41 52 59 20 4b 45   pgno, PRIMARY KE
+|   3920: 59 28 73 65 67 69 64 2c 20 74 65 72 6d 29 29 20   Y(segid, term)) 
+|   3936: 57 49 54 48 4f 55 54 20 52 4f 57 49 44 55 02 07   WITHOUT ROWIDU..
+|   3952: 17 1b 1b 01 81 01 74 61 62 6c 65 74 31 5f 64 61   ......tablet1_da
+|   3968: 74 61 74 31 5f 64 61 74 61 02 43 52 45 41 54 45   tat1_data.CREATE
+|   3984: 20 54 41 42 4c 45 20 27 74 31 5f 64 61 74 61 27    TABLE 't1_data'
+|   4000: 28 69 64 20 49 4e 54 45 47 45 52 20 50 52 49 4d   (id INTEGER PRIM
+|   4016: 41 52 59 20 4b 45 59 2c 20 62 6c 6f 63 6b 20 42   ARY KEY, block B
+|   4032: 4c 4f 42 29 3a 01 06 17 11 11 08 63 74 61 62 6c   LOB):......ctabl
+|   4048: 65 74 31 74 31 43 52 45 41 54 45 20 56 49 52 54   et1t1CREATE VIRT
+|   4064: 55 41 4c 20 54 41 42 4c 45 20 74 31 20 55 53 49   UAL TABLE t1 USI
+|   4080: 4e 47 20 66 74 73 35 28 63 6f 6e 74 65 6e 74 29   NG fts5(content)
+| page 2 offset 4096
+|      0: 0d 00 00 00 03 0f bd 00 0f e8 0f ef 0f bd 00 00   ................
+|   4016: 00 00 00 00 00 00 00 00 00 00 00 00 00 24 84 80   .............$..
+|   4032: 80 80 80 01 03 00 4e 00 00 00 1e 06 30 61 62 61   ......N.....0aba
+|   4048: 63 6b 01 02 02 04 02 66 74 00 02 22 04 04 6e 64   ck.....ft.....nd
+|   4064: 6f 6e 04 67 90 38 2a 07 05 01 03 00 10 03 03 0f   on.g.8*.........
+|   4080: 0a 03 00 24 00 00 00 00 01 01 01 00 01 01 01 01   ...$............
+| page 3 offset 8192
+|      0: 0a 00 00 00 01 0f fa 00 0f fa 00 00 00 00 00 00   ................
+|   4080: 00 00 00 00 00 00 00 00 00 00 05 04 09 0c 01 02   ................
+| page 4 offset 12288
+|      0: 0d 00 00 00 03 0f e0 00 0f f6 0f ec 0f e0 00 00   ................
+|   4064: 0a 03 03 00 1b 61 62 61 6e 64 6f 6e 08 02 03 00   .....abandon....
+|   4080: 17 61 62 61 66 74 08 01 03 00 17 61 62 61 63 6b   .abaft.....aback
+| page 5 offset 16384
+|      0: 0d 00 00 00 03 0f ee 00 0f fa 0f f4 0f ee 00 00   ................
+|   4064: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 04 03   ................
+|   4080: 03 00 0e 01 04 02 03 00 0e 01 04 01 03 00 0e 01   ................
+| page 6 offset 20480
+|      0: 0a 00 00 00 01 0f f4 00 0f f4 00 00 00 00 00 00   ................
+|   4080: 00 00 00 00 0b 03 1b 01 76 65 72 73 69 6f 6e 04   ........version.
+| page 7 offset 24576
+|      0: 0d 00 00 00 03 0f d6 00 0f f4 0f e1 0f d6 00 00   ................
+|   4048: 00 00 00 00 00 00 09 03 02 1b 72 65 62 75 69 6c   ..........rebuil
+|   4064: 64 11 02 02 2b 69 6e 74 65 67 72 69 74 79 2d 63   d...+integrity-c
+|   4080: 68 65 63 6b 0a 01 02 1d 6f 70 74 69 6d 69 7a 65   heck....optimize
+| page 8 offset 28672
+|      0: 03 07 17 19 19 01 81 2d 74 61 62 6c 65 74 31 5f   .......-tablet1_
+|     16: 69 64 78 74 31 5f 69 64 78 03 43 52 45 41 54 45   idxt1_idx.CREATE
+|     32: 20 54 41 42 4c 45 20 27 74 31 5f 66 17 42 03 30    TABLE 't1_f.B.0
+|     48: 01 00 00 10 10 04 02 02 00 00 00 00 00 00 00 00   ................
+|     64: 70 00 00 00 00 00 00 00 00 00 00 00 70 00 00 00   p...........p...
+| end c16.db
+}]} {}
+
+do_catchsql_test 15.1 {
+  INSERT INTO t1(t1) VALUES('integrity-check');
+} {1 {database disk image is malformed}}
+
+#---------------------------------------------------------------------------
+#
+reset_db
+do_test 16.0 {
+  sqlite3 db {}
+  db deserialize [decode_hexdb {
+| size 28672 pagesize 4096 filename c17.db
+| page 1 offset 0
+|      0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00   SQLite format 3.
+|     16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 07   .....@  ........
+|     32: 00 00 00 00 00 00 00 00 00 00 00 07 00 00 00 00   ................
+|     48: 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00   ................
+|     96: 00 00 00 00 0d 00 00 00 07 0d d2 00 0f c4 0f 6d   ...............m
+|    112: 0f 02 0e ab 0e 4e 0d f6 0d d2 00 00 00 00 00 00   .....N..........
+|   3536: 00 00 22 07 06 17 11 11 01 31 74 61 62 6c 65 74   .........1tablet
+|   3552: 32 74 32 07 43 52 45 41 54 45 20 54 41 42 4c 45   2t2.CREATE TABLE
+|   3568: 20 74 32 28 78 29 56 06 06 17 1f 1f 01 7d 74 61    t2(x)V.......ta
+|   3584: 62 6c 65 74 31 5f 63 6f 6e 66 69 67 74 31 5f 63   blet1_configt1_c
+|   3600: 6f 6e 66 69 67 06 43 52 45 41 54 45 20 54 41 42   onfig.CREATE TAB
+|   3616: 4c 45 20 27 74 31 5f 63 6f 6e 66 69 67 27 28 6b   LE 't1_config'(k
+|   3632: 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 76 29    PRIMARY KEY, v)
+|   3648: 20 57 49 54 48 4f 55 54 20 52 4f 57 49 44 5b 05    WITHOUT ROWID[.
+|   3664: 07 17 21 21 01 81 01 74 61 62 6c 65 74 31 5f 64   ..!!...tablet1_d
+|   3680: 6f 63 73 69 7a 65 74 31 5f 64 6f 63 73 69 7a 65   ocsizet1_docsize
+|   3696: 05 43 52 45 41 54 45 20 54 41 42 4c 45 20 27 74   .CREATE TABLE 't
+|   3712: 31 5f 64 6f 63 73 69 7a 65 27 28 69 64 20 49 4e   1_docsize'(id IN
+|   3728: 54 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45   TEGER PRIMARY KE
+|   3744: 59 2c 20 73 7a 20 42 4c 4f 42 29 55 04 06 17 21   Y, sz BLOB)U...!
+|   3760: 21 01 77 74 61 62 6c 65 74 31 5f 63 6f 6e 74 65   !.wtablet1_conte
+|   3776: 6e 74 74 31 5f 63 6f 6e 74 65 6e 74 04 43 52 45   ntt1_content.CRE
+|   3792: 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 63 6f   ATE TABLE 't1_co
+|   3808: 6e 74 65 6e 74 27 28 69 64 20 49 4e 54 45 47 45   ntent'(id INTEGE
+|   3824: 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 63   R PRIMARY KEY, c
+|   3840: 30 29 69 03 07 17 19 19 01 81 2d 74 61 62 6c 65   0)i.......-table
+|   3856: 74 31 5f 69 64 78 74 31 5f 69 64 78 03 43 52 45   t1_idxt1_idx.CRE
+|   3872: 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 69 64   ATE TABLE 't1_id
+|   3888: 78 27 28 73 65 67 69 64 2c 20 74 65 72 6d 2c 20   x'(segid, term, 
+|   3904: 70 67 6e 6f 2c 20 50 52 49 4d 41 52 59 20 4b 45   pgno, PRIMARY KE
+|   3920: 59 28 73 65 67 69 64 2c 20 74 65 72 6d 29 29 20   Y(segid, term)) 
+|   3936: 57 49 54 48 4f 55 54 20 52 4f 57 49 44 55 02 07   WITHOUT ROWIDU..
+|   3952: 17 1b 1b 01 81 01 74 61 62 6c 65 74 31 5f 64 61   ......tablet1_da
+|   3968: 74 61 74 31 5f 64 61 74 61 02 43 52 45 41 54 45   tat1_data.CREATE
+|   3984: 20 54 41 42 4c 45 20 27 74 31 5f 64 61 74 61 27    TABLE 't1_data'
+|   4000: 28 69 64 20 49 4e 54 45 47 45 52 20 50 52 49 4d   (id INTEGER PRIM
+|   4016: 41 52 59 20 4b 45 59 2c 20 62 6c 6f 63 6b 20 42   ARY KEY, block B
+|   4032: 4c 4f 42 29 3a 01 06 17 11 11 08 63 74 61 62 6c   LOB):......ctabl
+|   4048: 65 74 31 74 31 43 52 45 41 54 45 20 56 49 52 54   et1t1CREATE VIRT
+|   4064: 55 41 4c 20 54 41 42 4c 45 20 74 31 20 55 53 49   UAL TABLE t1 USI
+|   4080: 4e 47 20 66 74 73 35 28 63 6f 6e 74 65 6e 74 29   NG fts5(content)
+| page 2 offset 4096
+|      0: 0d 00 00 00 03 0f bd 00 0f e8 0f ef 0f bd 00 00   ................
+|   4016: 00 00 00 00 00 00 00 00 00 00 00 00 00 24 84 80   .............$..
+|   4032: 80 80 80 01 03 00 4e 00 00 00 1e 06 30 61 62 61   ......N.....0aba
+|   4048: 63 6b 01 02 02 04 02 66 74 00 02 22 04 04 6e 64   ck.....ft.....nd
+|   4064: 6f 6e 03 02 02 04 0a 07 05 01 03 00 10 03 03 0f   on..............
+|   4080: 0a 03 00 24 00 00 00 00 01 01 01 00 01 01 41 01   ...$..........A.
+| page 3 offset 8192
+|      0: 0a 00 00 00 01 0f fa 00 0f fa 00 00 00 00 00 00   ................
+|   4080: 00 00 00 00 00 00 00 00 00 00 05 04 09 0c 01 02   ................
+| page 4 offset 12288
+|      0: 0d 00 00 00 03 0f e0 00 0f f6 0f ec 0f e0 00 00   ................
+|   4064: 0a 03 03 00 1b 61 62 61 6e 64 6f 6e 08 02 03 00   .....abandon....
+|   4080: 17 61 62 61 66 74 08 01 03 00 17 61 62 61 63 6b   .abaft.....aback
+| page 5 offset 16384
+|      0: 0d 00 00 00 03 0f ee 00 0f fa 0f f4 0f ee 00 00   ................
+|   4064: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 04 03   ................
+|   4080: 03 00 0e 01 04 02 03 00 0e 01 04 01 03 00 0e 01   ................
+| page 6 offset 20480
+|      0: 0a 00 00 00 01 0f f4 00 0f f4 00 00 00 00 00 00   ................
+|   4080: 00 00 00 00 0b 03 1b 01 76 65 72 73 69 6f 6e 04   ........version.
+| page 7 offset 24576
+|      0: 0d 00 00 00 03 0f d6 00 0f f4 0f e1 0f d6 00 00   ................
+|   4048: 00 00 00 00 00 00 09 03 02 1b 72 65 62 75 69 6c   ..........rebuil
+|   4064: 64 11 02 02 2b 69 6e 74 65 67 72 69 74 79 2d 63   d...+integrity-c
+|   4080: 68 65 63 6b 0a 01 02 1d 6f 70 74 69 6d 69 7a 65   heck....optimize
+| end c17.db
+}]} {}
+
+do_catchsql_test 16.1 {
+INSERT INTO t1(t1) VALUES('integrity-check');
+} {1 {vtable constructor failed: t1}}
+
+#--------------------------------------------------------------------------
+reset_db
+do_test 17.0 {
+  sqlite3 db {}
+  db deserialize [decode_hexdb {
+| size 28672 pagesize 4096 filename c18.db
+| page 1 offset 0
+|      0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00   SQLite format 3.
+|     16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 07   .....@  ........
+|     32: 00 00 00 00 00 00 00 00 00 00 00 07 00 00 00 00   ................
+|     48: 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00   ................
+|     96: 00 00 00 00 0d 00 00 00 07 0d d2 00 0f c4 0f 6d   ...............m
+|    112: 0f 02 0e ab 0e 4e 0d f6 0d d2 00 00 00 00 00 00   .....N..........
+|   3536: 00 00 22 07 06 17 11 11 01 31 74 61 62 6c 65 74   .........1tablet
+|   3552: 32 74 32 07 43 52 45 41 54 45 20 54 41 42 4c 45   2t2.CREATE TABLE
+|   3568: 20 74 32 28 78 29 56 06 06 17 1f 1f 01 7d 74 61    t2(x)V.......ta
+|   3584: 62 6c 65 74 31 5f 63 6f 6e 66 69 67 74 31 5f 63   blet1_configt1_c
+|   3600: 6f 6e 66 69 67 06 43 52 45 41 54 45 20 54 41 42   onfig.CREATE TAB
+|   3616: 4c 45 20 27 74 31 5f 63 6f 6e 66 69 67 27 28 6b   LE 't1_config'(k
+|   3632: 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 76 29    PRIMARY KEY, v)
+|   3648: 20 57 49 54 48 4f 55 54 20 52 4f 57 49 44 5b 05    WITHOUT ROWID[.
+|   3664: 07 17 21 21 01 81 01 74 61 62 6c 65 74 31 5f 64   ..!!...tablet1_d
+|   3680: 6f 63 73 69 7a 65 74 31 5f 64 6f 63 73 69 7a 65   ocsizet1_docsize
+|   3696: 05 43 52 45 41 54 45 20 54 41 42 4c 45 20 27 74   .CREATE TABLE 't
+|   3712: 31 5f 64 6f 63 73 69 7a 65 27 28 69 64 20 49 4e   1_docsize'(id IN
+|   3728: 54 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45   TEGER PRIMARY KE
+|   3744: 59 2c 20 73 7a 20 42 4c 4f 42 29 55 04 06 17 21   Y, sz BLOB)U...!
+|   3760: 21 01 77 74 61 62 6c 65 74 31 5f 63 6f 6e 74 65   !.wtablet1_conte
+|   3776: 6e 74 74 31 5f 63 6f 6e 74 65 6e 74 04 43 52 45   ntt1_content.CRE
+|   3792: 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 63 6f   ATE TABLE 't1_co
+|   3808: 6e 74 65 6e 74 27 28 69 64 20 49 4e 54 45 47 45   ntent'(id INTEGE
+|   3824: 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 63   R PRIMARY KEY, c
+|   3840: 30 29 69 03 07 17 19 19 01 81 2d 74 61 62 6c 65   0)i.......-table
+|   3856: 74 31 5f 69 64 78 74 31 5f 69 64 78 03 43 52 45   t1_idxt1_idx.CRE
+|   3872: 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 69 64   ATE TABLE 't1_id
+|   3888: 78 27 28 73 65 67 69 64 2c 20 74 65 72 6d 2c 20   x'(segid, term, 
+|   3904: 70 67 6e 6f 2c 20 50 52 49 4d 41 52 59 20 4b 45   pgno, PRIMARY KE
+|   3920: 59 28 73 65 67 69 64 2c 20 74 65 72 6d 29 29 20   Y(segid, term)) 
+|   3936: 57 49 54 48 4f 55 54 20 52 4f 57 49 44 55 02 07   WITHOUT ROWIDU..
+|   3952: 17 1b 1b 01 81 01 74 61 62 6c 65 74 31 5f 64 61   ......tablet1_da
+|   3968: 74 61 74 31 5f 64 61 74 61 02 43 52 45 41 54 45   tat1_data.CREATE
+|   3984: 20 54 41 42 4c 45 20 27 74 31 5f 64 61 74 61 27    TABLE 't1_data'
+|   4000: 28 69 64 20 49 4e 54 45 47 45 52 20 50 52 49 4d   (id INTEGER PRIM
+|   4016: 41 52 59 20 4b 45 59 2c 20 62 6c 6f 63 6b 20 42   ARY KEY, block B
+|   4032: 4c 4f 42 29 3a 01 06 17 11 11 08 63 74 61 62 6c   LOB):......ctabl
+|   4048: 65 74 31 74 31 43 52 45 41 54 45 20 56 49 52 54   et1t1CREATE VIRT
+|   4064: 55 41 4c 20 54 41 42 4c 45 20 74 31 20 55 53 49   UAL TABLE t1 USI
+|   4080: 4e 47 20 66 74 73 35 28 63 6f 6e 74 65 6e 74 29   NG fts5(content)
+| page 2 offset 4096
+|      0: 0d 00 00 00 03 0f bd 00 0f e8 0f ef 0f bd 00 00   ................
+|   4016: 00 00 00 00 00 00 00 00 00 00 00 00 00 24 84 80   .............$..
+|   4032: 80 80 80 01 03 00 4e 00 00 00 1e 06 30 61 62 61   ......N.....0aba
+|   4048: 63 6b 01 02 02 04 02 66 74 00 02 22 04 04 6e 64   ck.....ft.....nd
+|   4064: 6f 6e 03 02 02 04 0a 07 05 01 03 00 10 03 03 0f   on..............
+|   4080: 0a 03 00 24 00 00 0a aa aa aa aa aa aa aa aa aa   ...$............
+| page 3 offset 8192
+|      0: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa   ................
+|     16: aa aa aa aa aa aa aa aa 00 00 10 10 10 00 10 10   ................
+|     32: 10 10 a0 00 00 00 10 ff a0 00 ff 52 05 64 95 25   ...........R.d.%
+|     48: 45 54 14 c2 05 44 14 24 c4 52 07 43 12 05 55 34   ET...D.$.R.C..U4
+|     64: 94 e4 72 06 67 47 33 52 86 36 f6 e7 46 56 e7 42   ..r.gG3R.6..FV.B
+|     80: 90 d0 00 00 00 30 fb d0 00 fe 80 fe f0 fb 00 00   .....0..........
+|   4080: 00 00 00 00 00 00 00 00 00 00 05 04 09 0c 01 02   ................
+| page 4 offset 12288
+|      0: 0d 00 00 00 03 0f e0 00 0f f6 0f ec 0f e0 00 00   ................
+|   4064: 0a 03 03 00 1b 61 62 61 6e 64 6f 6e 08 02 03 00   .....abandon....
+|   4080: 17 61 62 61 66 74 08 01 03 00 17 61 62 61 63 6b   .abaft.....aback
+| page 5 offset 16384
+|      0: 0d 00 00 00 03 0f ee 00 0f fa 0f f4 0f ee 00 00   ................
+|   4064: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 04 03   ................
+|   4080: 03 00 0e 01 04 02 03 00 0e 01 04 01 03 00 0e 01   ................
+| page 6 offset 20480
+|      0: 0a 00 00 00 01 0f f4 00 0f f4 00 00 00 00 00 00   ................
+|   4080: 00 00 00 00 0b 03 1b 01 76 65 72 73 69 6f 6e 04   ........version.
+| page 7 offset 24576
+|      0: 0d 00 00 00 03 0f d6 00 0f f4 0f e1 0f d6 00 00   ................
+|   4048: 00 00 00 00 00 00 09 03 02 1b 72 65 62 75 69 6c   ..........rebuil
+|   4064: 64 11 02 02 2b 69 6e 74 65 67 72 69 74 79 2d 63   d...+integrity-c
+|   4080: 68 65 63 6b 0a 01 02 1d 6f 70 74 69 6d 69 7a 65   heck....optimize
+| end c18.db
+}]} {}
+
+do_catchsql_test 17.1 {
+  SELECT * FROM t1 WHERE t1 MATCH 'abandon';
+} {1 {vtable constructor failed: t1}}
+
+#--------------------------------------------------------------------------
+reset_db
+do_test 18.0 {
+  sqlite3 db {}
+  db deserialize [decode_hexdb {
+| size 28672 pagesize 4096 filename c19b.db
+| page 1 offset 0
+|      0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00   SQLite format 3.
+|     16: 10 00 01 01 00 40 20 20 00 00 00 01 00 00 00 07   .....@  ........
+|     32: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00   ................
+|     48: 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00   ................
+|     80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01   ................
+|     96: 00 2e 30 38 0d 00 00 00 07 0d d2 00 0f c4 0f 6d   ..08...........m
+|    112: 0f 02 0e ab 0e 4e 0d f6 0d d2 00 00 00 00 00 00   .....N..........
+|   3536: 00 00 22 07 06 17 11 11 01 31 74 61 62 6c 65 74   .........1tablet
+|   3552: 32 74 32 07 43 52 45 41 54 45 20 54 41 42 4c 45   2t2.CREATE TABLE
+|   3568: 20 74 32 28 78 29 56 06 06 17 1f 1f 01 7d 74 61    t2(x)V.......ta
+|   3584: 62 6c 65 74 31 5f 63 6f 6e 66 69 67 74 31 5f 63   blet1_configt1_c
+|   3600: 6f 6e 66 69 67 06 43 52 45 41 54 45 20 54 41 42   onfig.CREATE TAB
+|   3616: 4c 45 20 27 74 31 5f 63 6f 6e 66 69 67 27 28 6b   LE 't1_config'(k
+|   3632: 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 76 29    PRIMARY KEY, v)
+|   3648: 20 57 49 54 48 4f 55 54 20 52 4f 57 49 44 5b 05    WITHOUT ROWID[.
+|   3664: 07 17 21 21 01 81 01 74 61 62 6c 65 74 31 5f 64   ..!!...tablet1_d
+|   3680: 6f 63 73 69 7a 65 74 31 5f 64 6f 63 73 69 7a 65   ocsizet1_docsize
+|   3696: 05 43 52 45 41 54 45 20 54 41 42 4c 45 20 27 74   .CREATE TABLE 't
+|   3712: 31 5f 64 6f 63 73 69 7a 65 27 28 69 64 20 49 4e   1_docsize'(id IN
+|   3728: 54 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45   TEGER PRIMARY KE
+|   3744: 59 2c 20 73 7a 20 42 4c 4f 42 29 55 04 06 17 21   Y, sz BLOB)U...!
+|   3760: 21 01 77 74 61 62 6c 65 74 31 5f 63 6f 6e 74 65   !.wtablet1_conte
+|   3776: 6e 74 74 31 5f 63 6f 6e 74 65 6e 74 04 43 52 45   ntt1_content.CRE
+|   3792: 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 63 6f   ATE TABLE 't1_co
+|   3808: 6e 74 65 6e 74 27 28 69 64 20 49 4e 54 45 47 45   ntent'(id INTEGE
+|   3824: 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 63   R PRIMARY KEY, c
+|   3840: 30 29 69 03 07 17 19 19 01 81 2d 74 61 62 6c 65   0)i.......-table
+|   3856: 74 31 5f 69 64 78 74 31 5f 69 64 78 03 43 52 45   t1_idxt1_idx.CRE
+|   3872: 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 69 64   ATE TABLE 't1_id
+|   3888: 78 27 28 73 65 67 69 64 2c 20 74 65 72 6d 2c 20   x'(segid, term, 
+|   3904: 70 67 6e 6f 2c 20 50 52 49 4d 41 52 59 20 4b 45   pgno, PRIMARY KE
+|   3920: 59 28 73 65 67 69 64 2c 20 74 65 72 6d 29 29 20   Y(segid, term)) 
+|   3936: 57 49 54 48 4f 55 54 20 52 4f 57 49 44 55 02 07   WITHOUT ROWIDU..
+|   3952: 17 1b 1b 01 81 01 74 61 62 6c 65 74 31 5f 64 61   ......tablet1_da
+|   3968: 74 61 74 31 5f 64 61 74 61 02 43 52 45 41 54 45   tat1_data.CREATE
+|   3984: 20 54 41 42 4c 45 20 27 74 31 5f 64 61 74 61 27    TABLE 't1_data'
+|   4000: 28 69 64 20 49 4e 54 45 47 45 52 20 50 52 49 4d   (id INTEGER PRIM
+|   4016: 41 52 59 20 4b 45 59 2c 20 62 6c 6f 63 6b 20 42   ARY KEY, block B
+|   4032: 4c 4f 42 29 3a 01 06 17 11 11 08 63 74 61 62 6c   LOB):......ctabl
+|   4048: 65 74 31 74 31 43 52 45 41 54 45 20 56 49 52 54   et1t1CREATE VIRT
+|   4064: 55 41 4c 20 54 41 42 4c 45 20 74 31 20 55 53 49   UAL TABLE t1 USI
+|   4080: 4e 47 20 66 74 73 35 28 63 6f 6e 74 65 6e 74 29   NG fts5(content)
+| page 2 offset 4096
+|      0: 0d 09 a6 00 06 09 22 00 0f e8 09 22 0f bd 0f 2c   ...............,
+|     16: 09 bd 09 3c 00 00 00 00 00 00 00 00 00 00 00 00   ...<............
+|   2336: 00 00 18 0a 03 00 36 00 00 00 00 01 04 04 00 04   ......6.........
+|   2352: 01 01 01 02 01 01 03 01 01 04 01 01 63 90 80 80   ............c...
+|   2368: 80 80 01 04 00 81 4a 00 00 00 56 06 30 61 62 61   ......J...V.0aba
+|   2384: 63 6b 08 01 04 04 6e 64 6f 6e 03 01 05 01 02 05   ck....ndon......
+|   2400: 63 74 69 76 65 08 01 02 04 6c 70 68 61 08 01 02   ctive....lpha...
+|   2416: 03 74 6f 6d 08 01 01 06 62 61 63 6b 75 70 08 01   .tom....backup..
+|   2432: 01 0c 63 68 61 6e 6e 65 62 6f 6f 6d 65 72 08 01   ..channeboomer..
+|   2448: 07 01 6c 08 01 01 04 74 65 73 74 08 01 04 09 0a   ..l....test.....
+|   2464: 09 08 07 0a 10 05 0f 18 00 17 30 00 00 00 00 01   ..........0.....
+|   2480: 03 03 00 03 01 01 01 02 01 01 03 01 01 8a 53 8c   ..............S.
+|   2496: 80 80 80 80 01 04 00 95 2a 00 00 05 35 0d 30 30   ........*...5.00
+|   2512: 31 30 66 66 61 30 30 30 66 66 61 05 02 1c 02 49   10ffa000ffa....I
+|   2528: 33 34 33 35 32 34 35 34 31 35 34 34 35 32 30 35   3435245415445205
+|   2544: 34 34 31 34 32 34 63 34 35 32 30 32 37 37 34 33   441424c452027743
+|   2560: 31 35 66 36 39 36 34 37 38 32 37 32 38 37 33 36   15f6964782728736
+|   2576: 35 36 37 36 39 36 34 32 63 32 30 37 34 36 35 37   56769642c2074657
+|   2592: 32 36 64 32 63 32 30 37 30 05 02 12 02 3b 36 31   26d2c2070....;61
+|   2608: 37 32 31 32 31 30 31 37 37 37 34 36 31 36 32 35   7212101777461625
+|   2624: 63 36 35 37 34 33 31 35 66 36 33 36 66 36 65 37   c6574315f636f6e7
+|   2640: 34 36 35 36 65 37 34 37 34 33 31 35 66 36 33 36   4656e7474315f636
+|   2656: 66 36 65 37 34 36 35 36 65 05 04 07 07 01 04 31   f6e74656e......1
+|   2672: 66 62 64 05 02 19 01 44 32 34 38 34 38 30 38 30   fbd....D24848080
+|   2688: 38 30 38 30 30 31 30 33 30 30 34 65 30 30 30 30   80800103004e0000
+|   2704: 30 30 31 65 30 36 33 30 36 31 36 32 36 31 36 33   001e063061626163
+|   2720: 36 62 30 31 30 32 30 32 30 34 30 32 36 36 37 34   6b01020204026674
+|   2736: 30 32 30 32 30 32 30 34 30 34 36 65 05 02 1a 02   02020204046e....
+|   2752: 03 66 65 72 05 02 1d 01 28 33 65 37 34 36 35 36   .fer....(3e74656
+|   2768: 65 37 34 32 39 30 64 30 30 30 30 30 30 30 33 30   e74290d000000030
+|   2784: 66 62 64 30 30 30 66 65 38 30 66 65 66 30 66 62   fbd000fe80fef0fb
+|   2800: 64 05 02 18 01 4a 34 31 35 32 35 39 32 30 34 62   d....J415259204b
+|   2816: 34 35 35 39 32 63 32 30 36 32 36 63 36 66 36 33   45592c20626c6f63
+|   2832: 36 62 32 30 34 32 34 63 34 66 34 32 32 39 33 61   6b20424c4f42293a
+|   2848: 30 31 30 36 31 37 31 31 31 31 30 38 36 33 37 34   0106171111086374
+|   2864: 36 31 36 32 36 63 36 35 37 34 33 31 37 34 33 31   61626c6574317431
+|   2880: 05 02 16 02 49 33 35 32 34 35 34 31 35 34 34 35   ....I35245415445
+|   2896: 32 30 35 36 34 39 35 32 35 34 35 35 34 31 34 63   205649525455414c
+|   2912: 32 30 35 34 34 31 34 32 34 63 34 35 32 30 37 34   205441424c452074
+|   2928: 33 31 6f 30 35 35 35 33 34 39 34 65 34 37 32 30   31o05553494e4720
+|   2944: 36 36 37 34 37 33 33 35 32 38 36 33 36 66 05 02   6674733528636f..
+|   2960: 17 02 49 35 32 30 35 34 34 31 34 32 34 63 34 35   ..I5205441424c45
+|   2976: 32 30 32 37 37 34 33 31 35 66 36 33 36 66 36 65   202774315f636f6e
+|   2992: 37 34 36 35 36 65 37 34 32 37 32 38 36 39 36 34   74656e7427286964
+|   3008: 32 30 34 39 34 65 35 34 34 35 34 37 34 35 35 32   20494e5445474552
+|   3024: 32 30 35 30 35 32 34 39 34 64 34 31 05 02 0e 44   205052494d41...D
+|   3040: 29 62 30 35 30 37 31 37 32 31 32 31 30 31 38 31   )b05071721210181
+|   3056: 30 31 37 34 36 31 36 32 36 63 36 35 37 34 33 31   017461626c657431
+|   3072: 35 66 36 34 36 66 36 33 37 33 05 02 09 01 4a 35   5f646f6373....J5
+|   3088: 32 34 35 34 31 35 34 34 35 32 30 35 34 34 31 34   2454154452054414
+|   3104: 32 34 63 34 35 32 30 32 37 37 34 33 31 35 66 36   24c45202774315f6
+|   3120: 34 36 31 37 34 36 31 32 37 32 38 36 39 36 34 32   4617461272869642
+|   3136: 30 34 39 34 65 35 34 34 35 34 37 34 35 35 32 32   0494e54454745522
+|   3152: 30 35 30 35 32 34 39 34 64 05 02 15 03 3a 35 39   05052494d....:59
+|   3168: 32 30 34 62 34 35 35 39 32 63 32 30 36 33 33 30   204b45592c206330
+|   3184: 32 39 36 39 30 33 30 37 31 37 31 39 31 39 30 31   2969030717191901
+|   3200: 38 31 32 64 37 34 36 31 36 32 36 63 36 35 37 34   812d7461626c6574
+|   3216: 33 31 35 66 36 39 79 79 05 02 0f 02 49 34 32 30   315f69yy....I420
+|   3232: 35 32 34 66 35 37 34 39 34 34 35 35 30 32 30 37   524f574944550207
+|   3248: 31 37 31 62 31 62 30 31 38 31 30 31 37 34 36 31   171b1b0181017461
+|   3264: 36 32 36 63 36 37 37 34 33 31 35 66 36 34 36 31   626c6774315f6461
+|   3280: 37 34 36 31 37 34 33 31 35 66 36 34 36 31 37 34   746174315f646174
+|   3296: 36 31 30 32 34 33 05 02 14 02 07 66 36 39 36 34   610243.....f6964
+|   3312: 37 38 05 02 11 01 4a 36 34 36 66 36 65 30 33 30   78....J646f6e030
+|   3328: 32 30 32 30 34 30 61 30 37 30 35 30 31 30 33 30   202040a070501030
+|   3344: 30 31 30 30 33 30 33 30 66 30 61 30 33 30 30 32   01003030f0a03002
+|   3360: 34 30 30 30 30 30 30 30 30 30 31 30 31 30 31 30   4000000000101010
+|   3376: 30 30 31 30 31 30 31 30 31 30 61 30 30 30 30 30   0010101010a00000
+|   3392: 30 05 02 1b 02 49 35 32 37 32 38 36 39 36 34 32   0....I5272869642
+|   3408: 30 34 39 34 65 35 34 34 35 34 37 34 35 35 32 32   0494e54454745522
+|   3424: 30 35 30 35 32 34 39 34 64 34 31 35 32 35 39 32   05052494d4152592
+|   3440: 30 34 62 34 35 35 39 32 63 32 30 37 33 37 61 32   04b45592c20737a2
+|   3456: 30 34 32 34 63 34 66 34 32 32 39 35 35 30 34 05   0424c4f42295504.
+|   3472: 04 06 07 02 49 37 36 65 36 66 32 63 32 30 35 30   ....I76e6f2c2050
+|   3488: 35 32 34 39 34 64 34 31 35 32 35 39 32 30 34 62   52494d415259204b
+|   3504: 34 35 35 39 32 38 37 33 36 35 36 37 36 39 36 34   4559287365676964
+|   3520: 32 63 32 30 37 34 36 35 37 32 36 64 32 39 32 39   2c207465726d2929
+|   3536: 32 30 35 37 34 39 35 34 34 38 34 66 35 35 05 02   20574954484f55..
+|   3552: 13 02 49 39 37 61 36 35 37 34 33 31 35 66 36 34   ..I97a6574315f64
+|   3568: 36 66 36 33 37 33 36 39 37 61 36 35 30 35 34 33   6f6373697a650543
+|   3584: 35 32 34 35 34 31 35 34 34 35 32 30 35 34 34 31   5245415445205441
+|   3600: 34 32 34 63 34 35 32 30 32 37 37 34 33 31 35 66   424c45202774315f
+|   3616: 36 34 36 66 36 33 37 33 36 39 37 61 05 04 05 07   646f6373697a....
+|   3632: 01 0e 37 34 30 34 34 33 35 32 34 35 34 31 35 34   ..74044352454154
+|   3648: 05 04 08 07 02 49 36 32 39 32 30 35 37 34 39 35   .....I6292057495
+|   3664: 34 34 38 34 66 35 35 35 34 32 30 35 32 34 66 35   4484f555420524f5
+|   3680: 37 34 39 34 34 35 62 30 35 30 37 31 37 32 31 32   749445b050717212
+|   3696: 31 30 31 38 31 30 31 37 34 36 31 36 32 36 63 36   10181017461626c6
+|   3712: 35 37 34 33 31 35 66 36 34 36 66 36 33 37 33 05   574315f646f6373.
+|   3728: 02 04 01 06 62 61 63 6b 75 70 05 02 1e 02 05 65   ....backup.....e
+|   3744: 61 6d 65 72 05 02 02 02 05 6f 6f 6d 65 72 05 01   amer.....oomer..
+|   3760: 02 40 75 6d 6d 32 34 63 34 35 32 30 32 37 37 34   .@umm24c45202774
+|   3776: 33 31 35 66 36 33 36 66 36 65 36 36 36 39 36 37   315f636f6e666967
+|   3792: 32 37 32 38 36 62 32 30 35 30 35 32 34 39 34 64   27286b205052494d
+|   3808: 34 31 35 32 35 39 32 30 34 62 34 35 35 39 32 63   415259204b45592c
+|   3824: 32 30 05 02 03 01 04 79 65 6b 72 05 02 10 04 11   20.....yekr.....
+|   3840: 4e 41 09 49 08 2d 4f 4e 4e 2e 4f 3f 4e 0c 4f 4f   NA.I.-ONN.O?N.OO
+|   3856: 4e 4f 14 4e 0b 0a 09 45 0f ef 00 14 2a 00 00 00   NO.N...E....*...
+|   3872: 00 01 02 02 00 02 01 01 01 02 01 01 81 09 88 80   ................
+|   3888: 80 80 80 01 04 00 82 16 00 00 00 79 06 30 61 62   ...........y.0ab
+|   3904: 61 63 6b 08 02 07 04 04 6e 64 6f 6e 08 02 05 02   ack.....ndon....
+|   3920: 05 63 74 69 76 65 04 02 02 04 02 0b 02 04 6c 70   .ctive........lp
+|   3936: 68 61 08 04 02 0a 02 03 74 6b 6d 06 02 02 03 02   ha......tkm.....
+|   3952: 6f 6d 08 02 09 05 02 69 63 07 02 02 01 06 62 61   om.....ic.....ba
+|   3968: 63 6b 75 70 08 02 04 02 05 6f 6f 6d 65 72 05 02   ckup.....oomer..
+|   3984: 02 01 0c 63 68 61 6e 6e 65 62 6f 6f 6d 65 72 08   ...channeboomer.
+|   4000: 02 08 07 01 6c 08 02 03 01 04 74 65 73 74 08 02   ....l.....test..
+|   4016: 06 04 0a 09 0d 0a 08 07 07 0b 0a 11 06 24 84 80   .............$..
+|   4032: 80 80 80 01 03 00 4e 00 00 00 1e 06 30 61 62 61   ......N.....0aba
+|   4048: 63 6b 01 08 02 04 02 66 74 00 02 22 04 04 6e 64   ck.....ft.....nd
+|   4064: 6f 6e 03 02 02 04 0a 07 05 01 03 00 10 06 22 00   on..............
+|   4080: 00 00 11 24 00 00 00 00 01 01 01 00 01 01 01 01   ...$............
+| page 3 offset 8192
+|      0: 0a 00 00 00 04 0f e5 00 0f fa 0f f3 0f ec 0f e5   ................
+|   4064: 00 00 00 00 00 06 04 01 0c 01 04 02 06 04 01 0c   ................
+|   4080: 01 03 02 06 04 01 0c 01 02 02 05 04 09 0c 01 02   ................
+| page 4 offset 12288
+|      0: 0d 0f 68 00 06 08 98 00 0f f6 0f ec 0f d5 08 98   ..h.............
+|     16: 0f c1 0f b6 0f 68 0f 68 00 00 00 00 00 00 00 00   .....h.h........
+|   2192: 00 00 00 00 00 00 00 00 8d 4d 05 04 00 9b 1f 62   .........M.....b
+|   2208: 65 61 6d 65 72 20 62 75 6d 6d 32 34 63 34 35 32   eamer bumm24c452
+|   2224: 30 32 37 37 34 33 31 35 66 36 33 36 66 36 65 36   02774315f636f6e6
+|   2240: 36 36 39 36 37 32 37 32 38 36 62 32 30 35 30 35   6696727286b20505
+|   2256: 32 34 39 34 64 34 31 35 32 35 39 32 30 34 62 34   2494d415259204b4
+|   2272: 35 35 39 32 63 32 30 0a 37 36 32 39 32 30 35 37   5592c20.76292057
+|   2288: 34 39 35 34 34 38 34 66 35 35 35 34 32 30 35 32   4954484f55542052
+|   2304: 34 66 35 37 34 39 34 34 35 62 30 35 30 37 31 37   4f5749445b050717
+|   2320: 32 31 32 31 30 31 38 31 30 31 37 34 36 31 36 32   2121018101746162
+|   2336: 36 63 36 35 37 34 33 31 35 66 36 34 36 66 36 33   6c6574315f646f63
+|   2352: 37 33 0a 36 39 37 61 36 35 37 34 33 31 35 66 36   73.697a6574315f6
+|   2368: 34 36 66 36 33 37 33 36 39 37 61 36 35 30 35 34   46f6373697a65054
+|   2384: 33 35 32 34 35 34 31 35 34 34 35 32 30 35 34 34   3524541544520544
+|   2400: 31 34 32 34 63 34 35 32 30 32 37 37 34 33 31 35   1424c45202774315
+|   2416: 66 36 34 36 66 36 33 37 33 36 39 37 61 0a 36 35   f646f6373697a.65
+|   2432: 32 37 32 38 36 39 36 34 32 30 34 39 34 65 35 34   2728696420494e54
+|   2448: 34 35 34 37 34 35 35 32 32 30 35 30 35 32 34 39   4547455220505249
+|   2464: 34 64 34 31 35 32 35 39 32 30 34 62 34 35 35 39   4d415259204b4559
+|   2480: 32 63 32 30 37 33 37 61 32 30 34 32 34 63 34 66   2c20737a20424c4f
+|   2496: 34 32 32 39 35 35 30 34 0a 30 36 31 37 32 31 32   42295504.0617212
+|   2512: 31 30 31 37 37 37 34 36 31 36 32 35 63 36 35 37   101777461625c657
+|   2528: 34 33 31 35 66 36 33 36 66 36 65 37 34 36 35 36   4315f636f6e74656
+|   2544: 65 37 34 37 34 33 31 35 66 36 33 36 66 36 65 37   e7474315f636f6e7
+|   2560: 34 36 35 36 65 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b   4656e...........
+|   2576: 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b   ................
+|   2592: 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b   ................
+|   2608: 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b   ................
+|   2624: 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b   ................
+|   2640: 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b   ................
+|   2656: 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 37 34 30   .............740
+|   2672: 34 34 33 35 32 34 35 34 31 35 34 0a 34 35 32 30   44352454154.4520
+|   2688: 35 34 34 31 34 32 34 63 34 35 32 30 32 37 37 34   5441424c45202774
+|   2704: 33 31 35 66 36 33 36 66 36 65 37 34 36 35 36 65   315f636f6e74656e
+|   2720: 37 34 32 37 32 38 36 39 36 34 32 30 34 39 34 65   742728696420494e
+|   2736: 35 34 34 35 34 37 34 35 35 32 32 30 35 30 35 62   544547455220505b
+|   2752: 30 35 30 37 31 37 32 31 32 31 30 31 38 31 30 31   0507172121018101
+|   2768: 37 34 36 31 36 32 36 63 36 35 37 34 33 31 35 66   7461626c6574315f
+|   2784: 36 34 36 66 36 33 37 33 0a 36 39 37 61 36 35 37   646f6373.697a657
+|   2800: 34 33 31 35 66 36 34 36 66 36 33 37 33 36 39 37   4315f646f6373697
+|   2816: 61 36 35 30 35 34 33 35 32 34 35 34 31 35 34 34   a650543524541544
+|   2832: 35 32 30 35 34 34 31 34 32 34 63 34 35 32 30 32   5205441424c45202
+|   2848: 37 37 34 33 31 35 66 36 34 36 66 36 33 37 33 36   774315f646f63736
+|   2864: 39 37 61 0a 36 35 32 37 32 38 36 39 36 34 32 30   97a.652728696420
+|   2880: 34 39 34 65 35 34 34 35 34 37 34 35 35 32 32 30   494e544547455220
+|   2896: 35 30 35 32 34 39 34 64 34 31 35 32 35 39 32 30   5052494d41525920
+|   2912: 34 62 34 35 35 39 32 63 32 30 37 33 37 61 32 30   4b45592c20737a20
+|   2928: 34 32 34 63 34 66 34 32 32 39 35 35 30 34 0a 30   424c4f42295504.0
+|   2944: 36 31 37 32 31 32 31 30 31 37 37 37 34 36 31 36   6172121017774616
+|   2960: 32 35 63 36 35 37 34 33 31 35 66 36 33 36 66 36   25c6574315f636f6
+|   2976: 65 37 34 36 35 36 65 37 34 37 34 33 31 35 66 36   e74656e7474315f6
+|   2992: 33 36 66 36 65 37 34 36 35 36 65 0b 0b 0b 0b 0b   36f6e74656e.....
+|   3008: 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b   ................
+|   3024: 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b   ................
+|   3040: 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b   ................
+|   3056: 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b   ................
+|   3072: 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b   ................
+|   3088: 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b   ................
+|   3104: 0b 0b 0b 37 34 30 34 34 33 35 32 34 35 34 31 35   ...7404435245415
+|   3120: 34 0a 34 35 32 30 35 34 34 31 34 32 34 63 34 35   4.45205441424c45
+|   3136: 32 30 32 37 37 34 33 31 35 66 36 33 36 66 36 65   202774315f636f6e
+|   3152: 37 34 36 35 36 65 37 34 32 37 32 38 36 39 36 34   74656e7427286964
+|   3168: 32 30 34 39 34 65 35 34 34 35 34 37 34 35 35 32   20494e5445474552
+|   3184: 32 30 35 30 35 32 34 39 34 64 34 31 0a 35 32 35   205052494d41.525
+|   3200: 39 32 30 34 62 34 35 35 39 32 63 32 30 36 33 33   9204b45592c20633
+|   3216: 30 32 39 36 39 30 33 30 37 31 37 31 39 31 39 30   0296903071719190
+|   3232: 31 38 31 32 64 37 34 36 31 36 32 36 63 36 35 37   1812d7461626c657
+|   3248: 34 33 31 35 66 36 39 c3 bf c3 bf 7e c3 bf c3 89   4315f69....~....
+|   3264: 4b 52 c2 81 35 66 36 39 36 34 37 38 0a 30 33 34   KR..5f696478.034
+|   3280: 33 35 32 34 35 34 31 35 34 34 35 32 30 35 34 34   3524541544520544
+|   3296: 31 34 32 34 63 34 35 32 30 32 37 37 34 33 31 35   1424c45202774315
+|   3312: 66 36 39 36 34 37 38 32 37 32 38 37 33 36 35 36   f696478272873656
+|   3328: 37 36 39 36 34 32 63 32 30 37 34 36 35 37 32 36   769642c207465726
+|   3344: 64 32 63 32 30 37 30 0a 36 37 36 65 36 66 32 63   d2c2070.676e6f2c
+|   3360: 32 30 35 30 35 32 34 39 34 64 34 31 35 32 35 39   205052494d415259
+|   3376: 32 30 34 62 34 35 35 39 32 38 37 33 36 35 36 37   204b455928736567
+|   3392: 36 39 36 34 32 63 32 30 37 34 36 35 37 32 36 64   69642c207465726d
+|   3408: 32 39 32 39 32 30 35 37 34 39 35 34 34 38 34 66   292920574954484f
+|   3424: 35 35 0a 35 34 32 30 35 32 34 66 35 37 34 39 34   55.5420524f57494
+|   3440: 34 35 35 30 32 30 37 31 37 31 62 31 62 30 31 38   4550207171b1b018
+|   3456: 31 30 31 37 34 36 31 36 32 36 63 36 37 37 34 33   1017461626c67743
+|   3472: 31 35 66 36 34 36 31 37 34 36 31 37 34 33 31 35   15f6461746174315
+|   3488: 66 36 34 36 31 37 34 36 31 30 32 34 33 0a 35 32   f646174610243.52
+|   3504: 34 35 34 31 35 34 34 35 32 30 35 34 34 31 34 32   4541544520544142
+|   3520: 34 63 34 35 32 30 32 37 37 34 33 31 35 66 36 34   4c45202774315f64
+|   3536: 36 31 37 34 36 31 32 37 32 38 36 39 36 34 32 30   6174612728696420
+|   3552: 34 39 34 65 35 34 34 35 34 37 34 35 35 32 32 30   494e544547455220
+|   3568: 35 30 35 32 34 39 34 64 0a 34 31 35 32 35 39 32   5052494d.4152592
+|   3584: 30 34 62 34 35 35 39 32 63 32 30 36 32 36 63 36   04b45592c20626c6
+|   3600: 66 36 33 36 62 32 30 34 32 34 63 34 66 34 32 32   f636b20424c4f422
+|   3616: 39 33 61 30 31 30 36 31 37 31 31 31 31 30 38 36   93a0106171111086
+|   3632: 33 37 34 36 31 36 32 36 63 36 35 37 34 33 31 37   37461626c6574317
+|   3648: 34 33 31 0a 34 33 35 32 34 35 34 31 35 34 34 35   431.435245415445
+|   3664: 32 30 35 36 34 39 35 32 35 34 35 35 34 31 34 63   205649525455414c
+|   3680: 32 30 35 34 34 31 34 32 34 63 34 35 32 30 37 34   205441424c452074
+|   3696: 33 31 c3 94 30 35 35 35 33 34 39 34 65 34 37 32   31..05553494e472
+|   3712: 30 36 36 37 34 37 33 33 35 32 38 36 33 36 66 0a   06674733528636f.
+|   3728: 33 65 37 34 36 35 36 65 37 34 32 39 30 64 30 30   3e74656e74290d00
+|   3744: 30 30 30 30 30 33 30 66 62 64 30 30 30 66 65 38   0000030fbd000fe8
+|   3760: 30 66 65 66 30 66 62 64 0a 5b 31 66 62 64 5d 32   0fef0fbd.[1fbd]2
+|   3776: 34 38 34 38 30 38 30 38 30 38 30 30 31 30 33 30   4848080808001030
+|   3792: 30 34 65 30 30 30 30 30 30 31 65 30 36 33 30 36   04e0000001e06306
+|   3808: 31 36 32 36 31 36 33 36 62 30 31 30 32 30 32 30   16261636b0102020
+|   3824: 34 30 32 36 36 37 34 30 32 30 32 30 32 30 34 30   4026674020202040
+|   3840: 34 36 65 0a 36 34 36 66 36 65 30 33 30 32 30 32   46e.646f6e030202
+|   3856: 30 34 30 61 30 37 30 35 30 31 30 33 30 30 31 30   040a070501030010
+|   3872: 30 33 30 33 30 66 30 61 30 33 30 30 32 34 30 30   03030f0a03002400
+|   3888: 30 30 30 30 30 30 30 31 30 31 30 31 30 30 30 31   0000000101010001
+|   3904: 30 31 30 31 30 31 30 61 30 30 30 30 30 30 0a 30   0101010a000000.0
+|   3920: 31 30 66 66 61 30 30 30 66 66 61 0a 5b 32 66 65   10ffa000ffa.[2fe
+|   3936: 72 20 62 61 63 6b 75 70 0f ca 00 4e 81 1d 61 6c   r backup...N..al
+|   3952: 70 68 61 20 63 68 61 6e 6e 65 6c 20 c2 af 62 61   pha channel ..ba
+|   3968: 63 6b 75 70 20 61 62 61 6e 64 6f 6e 20 74 65 73   ckup abandon tes
+|   3984: 74 20 61 62 61 63 6b 20 63 68 61 6e 6e 65 62 6f   t aback channebo
+|   4000: 6f 6d 65 72 20 61 74 6f 6d 20 61 6c 70 68 61 20   omer atom alpha 
+|   4016: 61 63 74 69 76 65 09 07 03 00 19 61 74 6f 6d 69   active.....atomi
+|   4032: 63 07 06 03 00 15 61 74 6b 6d 0f e0 00 0b 19 62   c.....atkm.....b
+|   4048: 6f 6f 6d 65 72 09 04 03 00 19 61 63 74 69 76 65   oomer.....active
+|   4064: 00 00 00 0c 1b 61 62 61 6e 64 6f 6e 08 02 03 00   .....abandon....
+|   4080: 17 61 66 21 66 74 08 01 03 00 17 61 62 61 63 6b   .af!ft.....aback
+| page 5 offset 16384
+|      0: 0d 0f ee 00 06 0f d6 00 0f fa 0f f4 0f e8 0f e2   ................
+|     16: 0f dc 0f d6 0f d0 0f d0 00 00 00 00 00 00 00 00   ................
+|   4048: 0f ee 00 06 0e 0a 04 07 03 00 0e 01 04 06 03 00   ................
+|   4064: 0e 01 04 05 03 00 0e 1d 04 04 03 00 0e 01 00 00   ................
+|   4080: 00 06 0e 01 04 02 03 00 0e 01 04 01 03 00 0e 01   ................
+| page 6 offset 20480
+|      0: 0a 00 00 00 01 0f f4 00 0f f4 00 00 00 00 00 00   ................
+|   4080: 00 00 00 00 0b 03 1b 01 76 65 72 73 69 6f 6e 04   ........version.
+| page 7 offset 24576
+|      0: 0d 00 00 00 03 0f d6 00 0f f4 0f e1 0f d6 00 00   ................
+|   4048: 00 00 00 00 00 00 09 03 02 1b 72 65 62 75 69 6c   ..........rebuil
+|   4064: 64 11 02 02 2b 69 6e 74 65 67 72 69 74 79 2d 63   d...+integrity-c
+|   4080: 68 65 63 6b 0a 01 02 1d 6f 70 74 69 6d 69 7a 65   heck....optimize
+| end c19b.db
+}]} {}
+
+do_catchsql_test 18.1 {
+  INSERT INTO t1(t1) VALUES('optimize');
+} {1 {database disk image is malformed}}
+
+#--------------------------------------------------------------------------
+reset_db
+do_test 19.0 {
+  sqlite3 db {}
+  db deserialize [decode_hexdb {
+| size 28672 pagesize 4096 filename c20b.db
+| page 1 offset 0
+|      0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00   SQLite format 3.
+|     16: 10 00 01 01 00 40 20 20 00 00 00 01 00 00 00 07   .....@  ........
+|     32: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00   ................
+|     48: 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00   ................
+|     80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01   ................
+|     96: 00 2e 30 38 0d 00 00 00 07 0d d2 00 0f c4 0f 6d   ..08...........m
+|    112: 0f 02 0e ab 0e 4e 0d f6 0d d2 00 00 00 00 00 00   .....N..........
+|   3536: 00 00 22 07 06 17 11 11 01 31 74 61 62 6c 65 74   .........1tablet
+|   3552: 32 74 32 07 43 52 45 41 54 45 20 54 41 42 4c 45   2t2.CREATE TABLE
+|   3568: 20 74 32 28 78 29 56 06 06 17 1f 1f 01 7d 74 61    t2(x)V.......ta
+|   3584: 62 6c 65 74 31 5f 63 6f 6e 66 69 67 74 31 5f 63   blet1_configt1_c
+|   3600: 6f 6e 66 69 67 06 43 52 45 41 54 45 20 54 41 42   onfig.CREATE TAB
+|   3616: 4c 45 20 27 74 31 5f 63 6f 6e 66 69 67 27 28 6b   LE 't1_config'(k
+|   3632: 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 76 29    PRIMARY KEY, v)
+|   3648: 20 57 49 54 48 4f 55 54 20 52 4f 57 49 44 5b 05    WITHOUT ROWID[.
+|   3664: 07 17 21 21 01 81 01 74 61 62 6c 65 74 31 5f 64   ..!!...tablet1_d
+|   3680: 6f 63 73 69 7a 65 74 31 5f 64 6f 63 73 69 7a 65   ocsizet1_docsize
+|   3696: 05 43 52 45 41 54 45 20 54 41 42 4c 45 20 27 74   .CREATE TABLE 't
+|   3712: 31 5f 64 6f 63 73 69 7a 65 27 28 69 64 20 49 4e   1_docsize'(id IN
+|   3728: 54 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45   TEGER PRIMARY KE
+|   3744: 59 2c 20 73 7a 20 42 4c 4f 42 29 55 04 06 17 21   Y, sz BLOB)U...!
+|   3760: 21 01 77 74 61 62 6c 65 74 31 5f 63 6f 6e 74 65   !.wtablet1_conte
+|   3776: 6e 74 74 31 5f 63 6f 6e 74 65 6e 74 04 43 52 45   ntt1_content.CRE
+|   3792: 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 63 6f   ATE TABLE 't1_co
+|   3808: 6e 74 65 6e 74 27 28 69 64 20 49 4e 54 45 47 45   ntent'(id INTEGE
+|   3824: 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 63   R PRIMARY KEY, c
+|   3840: 30 29 69 03 07 17 19 19 01 81 2d 74 61 62 6c 65   0)i.......-table
+|   3856: 74 31 5f 69 64 78 74 31 5f 69 64 78 03 43 52 45   t1_idxt1_idx.CRE
+|   3872: 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 69 64   ATE TABLE 't1_id
+|   3888: 78 27 28 73 65 67 69 64 2c 20 74 65 72 6d 2c 20   x'(segid, term, 
+|   3904: 70 67 6e 6f 2c 20 50 52 49 4d 41 52 59 20 4b 45   pgno, PRIMARY KE
+|   3920: 59 28 73 65 67 69 64 2c 20 74 65 72 6d 29 29 20   Y(segid, term)) 
+|   3936: 57 49 54 48 4f 55 54 20 52 4f 57 49 44 55 02 07   WITHOUT ROWIDU..
+|   3952: 17 1b 1b 01 81 01 74 61 62 6c 65 74 31 5f 64 61   ......tablet1_da
+|   3968: 74 61 74 31 5f 64 61 74 61 02 43 52 45 41 54 45   tat1_data.CREATE
+|   3984: 20 54 41 42 4c 45 20 27 74 31 5f 64 61 74 61 27    TABLE 't1_data'
+|   4000: 28 69 64 20 49 4e 54 45 47 45 52 20 50 52 49 4d   (id INTEGER PRIM
+|   4016: 41 52 59 20 4b 45 59 2c 20 62 6c 6f 63 6b 20 42   ARY KEY, block B
+|   4032: 4c 4f 42 29 3a 01 06 17 11 11 08 63 74 61 62 6c   LOB):......ctabl
+|   4048: 65 74 31 74 31 43 52 45 41 54 45 20 56 49 52 54   et1t1CREATE VIRT
+|   4064: 55 41 4c 20 54 41 42 4c 45 20 74 31 20 55 53 49   UAL TABLE t1 USI
+|   4080: 4e 47 20 66 74 73 35 28 63 6f 6e 74 65 6e 74 29   NG fts5(content)
+| page 2 offset 4096
+|      0: 0d 0f 20 00 05 0e a0 00 0f e8 0e a0 0f bd 0f 34   .. ............4
+|     16: 0e b7 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
+|   3744: 15 0a 03 00 30 00 00 00 00 01 03 03 00 03 01 01   ....0...........
+|   3760: 01 02 01 01 03 01 01 62 8c 80 80 80 80 01 04 00   .......b........
+|   3776: 81 48 00 00 00 55 06 30 61 62 61 63 6b 08 01 04   .H...U.0aback...
+|   3792: 04 6e 64 6f 6e 03 01 05 01 02 05 63 74 69 76 65   .ndon......ctive
+|   3808: 08 01 02 04 6c 70 68 61 08 01 02 03 74 6f 6d 08   ....lpha....tom.
+|   3824: 01 01 06 62 61 63 6b 75 70 08 01 02 05 6f 6f 6d   ...backup....oom
+|   3840: 65 72 08 01 01 07 63 68 61 6e 6e 65 6c 08 01 01   er....channel...
+|   3856: 04 74 65 73 74 08 01 04 09 0a 09 08 07 0a 09 0b   .test...........
+|   3872: 0f ef 00 14 2a 00 00 00 00 01 02 02 00 02 01 01   ....*...........
+|   3888: 01 02 01 01 81 01 88 80 80 80 80 01 04 00 82 06   ................
+|   3904: 00 00 00 72 06 30 61 62 61 63 6b 08 02 07 04 04   ...r.0aback.....
+|   3920: 6e 64 6f 6e 08 02 05 02 05 63 74 69 76 65 04 02   ndon.....ctive..
+|   3936: 02 04 02 0b 02 04 6c 70 68 61 08 04 02 0a 02 03   ......lpha......
+|   3952: 74 6f 6d 06 02 02 02 02 09 05 02 69 63 07 02 02   tom........ic...
+|   3968: 01 06 62 61 63 6b 75 70 08 02 04 02 05 6f 6f 66   ..backup.....oof
+|   3984: 65 72 05 02 02 04 03 6d 65 72 08 02 08 01 07 63   er.....mer.....c
+|   4000: 68 61 6e 6e 65 6c 08 02 03 01 04 74 65 73 74 08   hannel.....test.
+|   4016: 02 06 04 0a 09 0d 0a 0b 07 0b 0a 08 0c 24 84 80   .............$..
+|   4032: 80 80 80 01 03 00 4e 00 00 00 1e 06 30 61 62 61   ......N.....0aba
+|   4048: 63 6b 01 02 66 04 00 22 74 00 02 22 04 04 6e 64   ck..f...t.....nd
+|   4064: 6f 6e 03 02 02 04 0a 07 05 01 03 00 10 06 06 00   on..............
+|   4080: 00 00 11 24 00 00 00 00 01 01 01 00 01 01 01 01   ...$............
+| page 3 offset 8192
+|      0: 0a 00 00 00 03 0f ec 00 0f fa 0f f3 0f ec 00 00   ................
+|   4064: 00 00 00 00 00 00 00 00 00 00 00 00 06 04 01 0c   ................
+|   4080: 01 03 02 06 04 01 0c 01 02 02 05 04 09 0c 01 02   ................
+| page 4 offset 12288
+|      0: 0d 0f e0 00 06 0f b6 00 0f f6 0f ec 0f d5 0f ca   ................
+|     16: 0f c1 0f b6 0f 70 0f 70 00 00 00 00 00 00 00 00   .....p.p........
+|   3952: 0f e0 00 46 81 0d 61 6c 70 68 61 20 63 68 61 6e   ...F..alpha chan
+|   3968: 6e 65 6c 20 62 61 63 6b 75 70 20 61 62 61 6e 64   nel backup aband
+|   3984: 6f 6e 20 74 65 73 74 20 61 62 61 63 6b 20 62 6f   on test aback bo
+|   4000: 6f 6d 65 72 20 61 74 6f 6d 20 61 6c 70 68 61 20   omer atom alpha 
+|   4016: 61 63 74 69 76 65 09 07 03 00 19 61 74 6f 6d 69   active.....atomi
+|   4032: 63 07 06 03 00 15 61 74 6f 6d 09 05 03 00 19 62   c.....atom.....b
+|   4048: 6f 6f 66 65 72 09 04 03 00 19 61 63 74 69 76 65   oofer.....active
+|   4064: 00 00 00 0c 1b 61 62 61 6e 64 6f 6e 08 02 03 00   .....abandon....
+|   4080: 17 61 62 61 66 74 08 01 03 00 17 61 62 61 63 6b   .abaft.....aback
+| page 5 offset 16384
+|      0: 0d 0f ee 00 06 0f d6 00 0f fa 0f f4 0f e8 0f e2   ................
+|     16: 0f dc 0f d6 0f d0 0f d0 00 00 00 00 00 00 00 00   ................
+|   4048: 0f ee 00 06 0e 0a 04 07 03 00 0e 01 04 06 03 00   ................
+|   4064: 0e 01 04 05 03 00 0e 01 04 04 03 00 0e 01 00 00   ................
+|   4080: 00 06 0e 01 04 02 03 00 0e 01 04 01 03 00 0e 01   ................
+| page 6 offset 20480
+|      0: 0a 00 00 00 01 0f f4 00 0f f4 00 00 00 00 00 00   ................
+|   4080: 00 00 00 00 0b 03 1b 01 76 65 72 73 69 6f 6e 04   ........version.
+| page 7 offset 24576
+|      0: 0d 00 00 00 03 0f d6 00 0f f4 0f e1 0f d6 00 00   ................
+|   4048: 00 00 00 00 00 00 09 03 02 1b 72 65 62 75 69 6c   ..........rebuil
+|   4064: 64 11 02 02 2b 69 6e 74 65 67 72 69 74 79 2d 63   d...+integrity-c
+|   4080: 86 65 63 6b 0a 01 02 1d 6f 70 74 69 6d 69 7a 65   .eck....optimize
+| end c20b.db
+}]} {}
+
+do_catchsql_test 19.1 {
+  INSERT INTO t1(t1) VALUES('optimize');
+} {1 {database disk image is malformed}}
+
+#--------------------------------------------------------------------------
+reset_db
+do_test 20.0 {
+  sqlite3 db {}
+  db deserialize [decode_hexdb {
+| size 28672 pagesize 4096 filename crash-cf347c523f793c.db
+| page 1 offset 0
+|      0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00   SQLite format 3.
+|     16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 07   .....@  ........
+|     32: 00 00 00 00 00 00 00 00 00 00 00 07 00 00 00 00   ................
+|     48: 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00   ................
+|     96: 00 00 00 00 0d 00 00 00 07 0d d2 00 0f c4 0f 6d   ...............m
+|    112: 0f 02 0e ab 0e 4e 0d f6 0d d2 00 00 00 00 00 00   .....N..........
+|   3536: 00 00 22 07 06 17 11 11 01 31 74 61 62 6c 65 74   .........1tablet
+|   3552: 32 74 32 07 43 52 45 41 54 45 20 54 41 42 4c 45   2t2.CREATE TABLE
+|   3568: 20 74 32 28 78 29 56 06 06 17 1f 1f 01 7d 74 61    t2(x)V.......ta
+|   3584: 62 6c 65 74 31 5f 63 6f 6e 66 69 67 74 31 5f 63   blet1_configt1_c
+|   3600: 6f 6e 66 69 67 06 43 52 45 41 54 45 20 54 41 42   onfig.CREATE TAB
+|   3616: 4c 45 20 27 74 31 5f 63 6f 6e 66 69 67 27 28 6b   LE 't1_config'(k
+|   3632: 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 76 29    PRIMARY KEY, v)
+|   3648: 20 57 49 54 48 4f 55 54 20 52 4f 57 49 44 5b 05    WITHOUT ROWID[.
+|   3664: 07 17 21 21 01 81 01 74 61 62 6c 65 74 31 5f 64   ..!!...tablet1_d
+|   3680: 6f 63 73 69 7a 65 74 31 5f 64 6f 63 73 69 7a 65   ocsizet1_docsize
+|   3696: 05 43 52 45 41 54 45 20 54 41 42 4c 45 20 27 74   .CREATE TABLE 't
+|   3712: 31 5f 64 6f 63 73 69 7a 65 27 28 69 64 20 49 4e   1_docsize'(id IN
+|   3728: 54 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45   TEGER PRIMARY KE
+|   3744: 59 2c 20 73 7a 20 42 4c 4f 42 29 55 04 06 17 21   Y, sz BLOB)U...!
+|   3760: 21 01 77 74 61 62 6c 65 74 31 5f 63 6f 6e 74 65   !.wtablet1_conte
+|   3776: 6e 74 74 31 5f 63 6f 6e 74 65 6e 74 04 43 52 45   ntt1_content.CRE
+|   3792: 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 63 6f   ATE TABLE 't1_co
+|   3808: 6e 74 65 6e 74 27 28 69 64 20 49 4e 54 45 47 45   ntent'(id INTEGE
+|   3824: 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 63   R PRIMARY KEY, c
+|   3840: 30 29 69 03 07 17 19 19 01 81 2d 74 61 62 6c 65   0)i.......-table
+|   3856: 74 31 5f 69 64 78 74 31 5f 69 64 78 03 43 52 45   t1_idxt1_idx.CRE
+|   3872: 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 69 64   ATE TABLE 't1_id
+|   3888: 78 27 28 73 65 67 69 64 2c 20 74 65 72 6d 2c 20   x'(segid, term, 
+|   3904: 70 67 6e 6f 2c 20 50 52 49 4d 41 52 59 20 4b 45   pgno, PRIMARY KE
+|   3920: 59 28 73 65 67 69 64 2c 20 74 65 72 6d 29 29 20   Y(segid, term)) 
+|   3936: 57 49 54 48 4f 55 54 20 52 4f 57 49 44 55 02 07   WITHOUT ROWIDU..
+|   3952: 17 1b 1b 01 81 01 74 61 62 6c 65 74 31 5f 64 61   ......tablet1_da
+|   3968: 74 61 74 31 5f 64 61 74 61 02 43 52 45 41 54 45   tat1_data.CREATE
+|   3984: 20 54 41 42 4c 45 20 27 74 31 5f 64 61 74 61 27    TABLE 't1_data'
+|   4000: 28 69 64 20 49 4e 54 45 47 45 52 20 50 52 49 4d   (id INTEGER PRIM
+|   4016: 41 52 59 20 4b 45 59 2c 20 62 6c 6f 63 6b 20 42   ARY KEY, block B
+|   4032: 4c 4f 42 29 3a 01 06 17 11 11 08 63 74 61 62 6c   LOB):......ctabl
+|   4048: 65 74 31 74 31 43 52 45 41 54 45 20 56 49 52 54   et1t1CREATE VIRT
+|   4064: 55 41 4c 20 54 41 42 4c 45 20 74 31 20 55 53 49   UAL TABLE t1 USI
+|   4080: 4e 47 20 66 74 73 35 28 63 6f 6e 74 65 6e 74 29   NG fts5(content)
+| page 2 offset 4096
+|      0: 0d 00 00 00 03 0f bd 00 0f e8 0f ef 0f bd 00 00   ................
+|   4016: 00 00 00 00 00 00 00 00 00 00 00 00 00 24 84 80   .............$..
+|   4032: 80 80 80 01 03 00 4e 00 00 00 1e 06 30 61 62 61   ......N.....0aba
+|   4048: 63 6b 01 02 02 04 02 66 74 02 02 02 04 04 6e 64   ck.....ft.....nd
+|   4064: 6f 6e 03 02 02 04 0a 07 05 01 03 00 10 03 03 0f   on..............
+|   4080: 0a 03 00 24 00 00 00 0e ee ee ee ee ee ee ee ee   ...$............
+| page 3 offset 8192
+|      0: ee ee ee ee ee ee ee ee ee ee ee ee ee ee ee ee   ................
+|     16: ee ee ee ee ee ee ee ee ee ee ee ee ee ee ee ee   ................
+|     32: ee ee ee ee ee ee ee ee ee ee ee ee 00 10 10 10   ................
+|     48: 00 10 10 10 10 a0 00 00 00 10 ff a0 00 ff 00 00   ................
+|   4080: 00 00 00 00 00 00 00 00 00 00 05 04 09 0c 01 02   ................
+| page 4 offset 12288
+|      0: 0d 00 00 00 03 0f e0 00 0f f6 0f ec 0f e0 00 00   ................
+|   4064: 0a 03 03 00 1b 61 62 61 6e 64 6f 6e 08 02 03 00   .....abandon....
+|   4080: 17 61 62 61 66 74 08 01 03 00 17 61 62 61 63 6b   .abaft.....aback
+| page 5 offset 16384
+|      0: 0d 00 00 00 03 0f ee 00 0f fa 0f f4 0f ee 00 00   ................
+|   4064: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 04 03   ................
+|   4080: 03 00 0e 01 04 02 03 00 0e 01 04 01 03 00 0e 01   ................
+| page 6 offset 20480
+|      0: 0a 00 00 00 01 0f f4 00 0f f4 00 00 00 00 00 00   ................
+|   4080: 00 00 00 00 0b 03 1b 01 76 65 72 73 69 6f 6e 04   ........version.
+| page 7 offset 24576
+|      0: 0d 00 00 00 03 0f d6 00 0f f4 0f e1 0f d6 00 00   ................
+|   4048: 00 00 00 00 00 00 09 03 02 1b 72 65 62 75 69 6c   ..........rebuil
+|   4064: 64 11 02 02 2b 69 6e 74 65 67 72 69 74 79 2d 63   d...+integrity-c
+|   4080: 68 65 63 6b 0a 01 02 1d 6f 70 74 69 6d 69 7a 65   heck....optimize
+| end crash-cf347c523f793c.db
+}]} {}
+
+do_catchsql_test 20.1 {
+  SELECT * FROM t1 WHERE t1 MATCH 'abandon';
+} {1 {vtable constructor failed: t1}}
+
+
 sqlite3_fts5_may_be_corrupt 0
 finish_test
 
diff --git a/ext/fts5/test/fts5unicode3.test b/ext/fts5/test/fts5unicode3.test
index ed89624..30eb3c4 100644
--- a/ext/fts5/test/fts5unicode3.test
+++ b/ext/fts5/test/fts5unicode3.test
@@ -21,7 +21,7 @@
 }
 
 proc fts3_unicode_path {file} {
-  file join [file dirname [info script]] .. .. fts3 unicode $file
+  file join .. [file dirname [info script]] .. .. fts3 unicode $file
 }
 
 source [fts3_unicode_path parseunicode.tcl]
diff --git a/ext/misc/csv.c b/ext/misc/csv.c
index 8cca8ae..963e41c 100644
--- a/ext/misc/csv.c
+++ b/ext/misc/csv.c
@@ -621,7 +621,7 @@
   }else if( pNew->zData ){
     pNew->iStart = (int)sRdr.iIn;
   }else{
-    pNew->iStart = ftell(sRdr.in);
+    pNew->iStart = ftell(sRdr.in) - sRdr.nIn + sRdr.iIn;
   }
   csv_reader_reset(&sRdr);
   rc = sqlite3_declare_vtab(db, CSV_SCHEMA);
diff --git a/ext/session/sqlite3session.h b/ext/session/sqlite3session.h
index 3d1df42..e9c2989 100644
--- a/ext/session/sqlite3session.h
+++ b/ext/session/sqlite3session.h
@@ -548,7 +548,7 @@
 ** sqlite3changeset_next() is called on the iterator or until the 
 ** conflict-handler function returns. If pnCol is not NULL, then *pnCol is 
 ** set to the number of columns in the table affected by the change. If
-** pbIncorrect is not NULL, then *pbIndirect is set to true (1) if the change
+** pbIndirect is not NULL, then *pbIndirect is set to true (1) if the change
 ** is an indirect change, or false (0) otherwise. See the documentation for
 ** [sqlite3session_indirect()] for a description of direct and indirect
 ** changes. Finally, if pOp is not NULL, then *pOp is set to one of 
diff --git a/manifest b/manifest
index 8969f65..ec69408 100644
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Here\sis\sthe\sbeginnings\sof\san\seffort\sto\sfactor\sout\sthe\simplementation\sof\nscalar\ssubqueries\sto\sbe\simplemented\sas\ssubroutines\sat\sthe\send\sof\sthe\smain\nbody\sof\sbytecode,\safter\sthe\sjump\sback\sto\sthe\sOP_Init\sopcode.\s\sThis\sis\san\nincremental\scheck-in\sthat\scontains\sonly\spreliminary\schanges.
-D 2018-12-26T15:04:43.407
+C Merge\sperformance\senhancements\sand\sother\spatches.
+D 2018-12-28T21:40:46.050
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F Makefile.in d8b254f8bb81bab43c340d70d17dc3babab40fcc8a348c8255881f780a45fee6
@@ -97,32 +97,32 @@
 F ext/fts3/fts3_tokenizer.h 64c6ef6c5272c51ebe60fc607a896e84288fcbc3
 F ext/fts3/fts3_tokenizer1.c 5c98225a53705e5ee34824087478cf477bdb7004
 F ext/fts3/fts3_unicode.c b1902e9ad47a6569fbb8ecb5ce52f20fe59b590d5c5e3bbdd56b10b03bdf632b
-F ext/fts3/fts3_unicode2.c e49f9e015f239bf5faf2f4fa483bbf1b08a9978f0ad1f31159d952f8b8a10d08
-F ext/fts3/fts3_write.c 8e67961f4452024b5b75c18aa46317e0f2ad30bf2c5c18381528d211cc10f90d
+F ext/fts3/fts3_unicode2.c faf0c750a1d0e9c9902f947212fc88f84e9450cddb3d1ffdbacbd0084b91d647
+F ext/fts3/fts3_write.c e36d2f7e8f180e8030e92a5c2d09ccf87021afedcc5148a9d823b496667bf2f2
 F ext/fts3/fts3speed.tcl b54caf6a18d38174f1a6e84219950d85e98bb1e9
 F ext/fts3/mkfts3amal.tcl 252ecb7fe6467854f2aa237bf2c390b74e71f100
 F ext/fts3/tool/fts3cov.sh c331d006359456cf6f8f953e37f2b9c7d568f3863f00bb5f7eb87fea4ac01b73
 F ext/fts3/tool/fts3view.c 202801a2056995b763864d60c2dee744d46f1677
 F ext/fts3/unicode/CaseFolding.txt 8c678ca52ecc95e16bc7afc2dbf6fc9ffa05db8c
 F ext/fts3/unicode/UnicodeData.txt cd07314edb62d49fde34debdaf92fa2aa69011e7
-F ext/fts3/unicode/mkunicode.tcl 2ea30d8122ccf1e33142c9cc8913d8cad9eb6668db359a228f10aeb37e2ab863
+F ext/fts3/unicode/mkunicode.tcl 2315b3f8c83dcb09091009db01b321fb401d98d8c5489c147c1a7c5a54d21e20
 F ext/fts3/unicode/parseunicode.tcl a981bd6466d12dd17967515801c3ff23f74a281be1a03cf1e6f52a6959fc77eb
 F ext/fts5/extract_api_docs.tcl a36e54ec777172ddd3f9a88daf593b00848368e0
 F ext/fts5/fts5.h 4f5d19b7973dae23de368728f06d3eb1fe9f5cca2990366b40e9379996f35e61
-F ext/fts5/fts5Int.h 39f12034b598df4e0f59bbe6cf03af03a905a534b04f182d155641a04e1eb797
+F ext/fts5/fts5Int.h 8590e08a485c98a7e3075ed72abe3452fe944a9e58e63dfa51b732cced344cab
 F ext/fts5/fts5_aux.c ca666a3bbe07c5a3bbe9fffaea19c935a1efaf337333e28bad7bdd1971ffd093
 F ext/fts5/fts5_buffer.c 1dd1ec0446b3acfc2d7d407eb894762a461613e2695273f48e449bfd13e973ff
 F ext/fts5/fts5_config.c 5af9c360e99669d29f06492c370892394aba0857
-F ext/fts5/fts5_expr.c 5aef080ba3c8947e22f38ce1ff9fe548e4a740e72b77241f35ed941ae128d2c7
+F ext/fts5/fts5_expr.c 0eff5bad90838be83c5cc16837ca215a961abe05cfbf741a285ba62a79ad586f
 F ext/fts5/fts5_hash.c 32be400cf761868c9db33efe81a06eb19a17c5402ad477ee9efb51301546dd55
-F ext/fts5/fts5_index.c bcf2ef1365a658ded91dc2577942ca6b374f66bf998616b3ef89490bcc39d874
+F ext/fts5/fts5_index.c 2fdfbf4194ced051487712a9182fc44c760b0bccea663633073d1c3f1801d879
 F ext/fts5/fts5_main.c 287a1a56580df304d7fa2fc1890f85b9cb6ac6b9e7c8af7dfa2151528db4b059
 F ext/fts5/fts5_storage.c 5862f1b785a983acb8420281340f3f424896ab48f396f6fd8540787be7459139
 F ext/fts5/fts5_tcl.c 39bcbae507f594aad778172fa914cad0f585bf92fd3b078c686e249282db0d95
 F ext/fts5/fts5_test_mi.c 65864ba1e5c34a61d409c4c587e0bbe0466eb4f8f478d85dc42a92caad1338e6
-F ext/fts5/fts5_test_tok.c 80de1a4b1a3caa216c3be8862440f0117a8357dd9b7cfc5a2a2ce11fe6eb64ae
-F ext/fts5/fts5_tokenize.c ca2b6a033794945ac505241a86b0aa978709c23aa2e6121984d3e3ede96003c8
-F ext/fts5/fts5_unicode2.c 03bc8ebf44d825d0b7ac519f7b16139cf8e879ae7a27e62fb6326f0d68e8bdd3
+F ext/fts5/fts5_test_tok.c 6a5574354ce61a98737e150fd4f7a002000db0cb4bcd655dc8694cb3e035381d
+F ext/fts5/fts5_tokenize.c d49f479ca109dc7fb6a99dd482439cae175c5082920757b9286f6e057339bd50
+F ext/fts5/fts5_unicode2.c 3f1bad6f2924ad13e25408f00301edd12d4216388a11daa518cb28f79b337f5e
 F ext/fts5/fts5_varint.c a5aceacda04dafcbae725413d7a16818ecd65738
 F ext/fts5/fts5_vocab.c fbe38044889b2d2d99babeeef239c620fb0332bb928a84506ac748d81500b354
 F ext/fts5/fts5parse.y eb526940f892ade5693f22ffd6c4f2702543a9059942772526eac1fde256bb05
@@ -156,7 +156,7 @@
 F ext/fts5/test/fts5content.test 688d5ac7af194ebc67495daea76a69e3cd5480122c2320e72d41241b423b4116
 F ext/fts5/test/fts5corrupt.test 77ae6f41a7eba10620efb921cf7dbe218b0ef232b04519deb43581cb17a57ebe
 F ext/fts5/test/fts5corrupt2.test 7453752ba12ce91690c469a6449d412561cc604b1dec994e16ab132952e7805f
-F ext/fts5/test/fts5corrupt3.test 0a94ebcbc4bdb96e28d4808bb02afa1a04b068e554eb3e4dfaaf38f08768ba94
+F ext/fts5/test/fts5corrupt3.test b6e0cbad885f311eb6b2871f47d1e7e838192a7fe6d39c2d851bef9df79cb7f8
 F ext/fts5/test/fts5delete.test cbf87e3b8867c4d5cfcaed975c7475fd3f99d072bce2075fcedf43d1f82af775
 F ext/fts5/test/fts5detail.test 31b240dbf6d44ac3507e2f8b65f29fdc12465ffd531212378c7ce1066766f54e
 F ext/fts5/test/fts5determin.test 1b77879b2ae818b5b71c859e534ee334dac088b7cf3ff3bf76a2c82b1c788d11
@@ -211,7 +211,7 @@
 F ext/fts5/test/fts5umlaut.test a42fe2fe6387c40c49ab27ccbd070e1ae38e07f38d05926482cc0bccac9ad602
 F ext/fts5/test/fts5unicode.test 17056f4efe6b0a5d4f41fdf7a7dc9af2873004562eaa899d40633b93dc95f5a9
 F ext/fts5/test/fts5unicode2.test 9b3df486de05fb4bde4aa7ee8de2e6dae1df6eb90e3f2e242c9383b95d314e3e
-F ext/fts5/test/fts5unicode3.test 9cbc82e2b02e2e3b7504103580c90f095e07fe8230b1951a9ed7558717b5feb7
+F ext/fts5/test/fts5unicode3.test 590c72e18195bda2446133f9d82d04a4e89d094bba58c75ae10f4afc6faa0744
 F ext/fts5/test/fts5unicode4.test 6463301d669f963c83988017aa354108be0b947d325aef58d3abddf27147b687
 F ext/fts5/test/fts5unindexed.test 9021af86a0fb9fc616f7a69a996db0116e7936d0db63892db6bafabbec21af4d
 F ext/fts5/test/fts5update.test 0737876e20e97a6a6abf45de19fc99315727bcee6a83fadcada1cc080b9aa8f0
@@ -280,7 +280,7 @@
 F ext/misc/closure.c 9f8fa11aa6c6e2f6d7296ffa88f103df4b46abd9602bcab3ea2f8fc24f334f63
 F ext/misc/completion.c cec672d40604075bb341a7f11ac48393efdcd90a979269b8fe7977ea62d0547f
 F ext/misc/compress.c dd4f8a6d0baccff3c694757db5b430f3bbd821d8686d1fc24df55cf9f035b189
-F ext/misc/csv.c 88333dc9f7dcf6a8148406f10ae04261e24e3b4c721550ae33e9e71f1265c1f1
+F ext/misc/csv.c a8e779a3a0039abecddc6784095cc875d820ea65dcda158daa13e6b43d966e0f
 F ext/misc/dbdump.c 12389a10c410fadf1e68eeb382def92d5a7fa9ce7cce4fb86a736fa2bac1000a
 F ext/misc/eval.c 6ea9b22a5fa0dd973b67ca4e53555be177bc0b7b263aadf1024429457c82c0e3
 F ext/misc/explain.c d5c12962d79913ef774b297006872af1fccda388f61a11d37758f9179a09551f
@@ -424,7 +424,7 @@
 F ext/session/sessionstat1.test 218d351cf9fcd6648f125a26b607b140310160184723c2666091b54450a68fb5
 F ext/session/sessionwor.test 07f0b304dc4df5454906069140bf6ec67edcaa3c548f3683354003cf2c22b64a
 F ext/session/sqlite3session.c f88c4bd0404da56246b08f5d584462f8979ba6aedf8c30762b553f7ae91f51cf
-F ext/session/sqlite3session.h 05351d2f50a1203fdffbeb590fdbbc796c9a6bfcd0c9b26cf6db3854e3eb4294
+F ext/session/sqlite3session.h 54d6356f5769d3695e5f63d719c6ee27671b2614973a2b675a3ff4d30d574233
 F ext/session/test_session.c 98797aba475a799376c9a42214f2d1debf2d0c3cb657d9c8bbf4f70bf3fb4aec
 F ext/userauth/sqlite3userauth.h 7f3ea8c4686db8e40b0a0e7a8e0b00fac13aa7a3
 F ext/userauth/user-auth.txt e6641021a9210364665fe625d067617d03f27b04
@@ -454,7 +454,7 @@
 F src/btree.c 4429a1615440f0253d470b59f955fe84787fd6f709ae114c0a12d132ae725599
 F src/btree.h febb2e817be499570b7a2e32a9bbb4b607a9234f6b84bb9ae84916d4806e96f2
 F src/btreeInt.h 620ab4c7235f43572cf3ac2ac8723cbdf68073be4d29da24897c7b77dda5fd96
-F src/build.c b620091357744710ae9940f03947b4bd69c2d5bf7cd76746e5a7cd5a8787beec
+F src/build.c f5968d8081182ddfee1629d7465c232c1d4f5d54687a632b188ae2cef5d32368
 F src/callback.c 25dda5e1c2334a367b94a64077b1d06b2553369f616261ca6783c48bcb6bda73
 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
 F src/ctime.c 109e58d00f62e8e71ee1eb5944ac18b90171c928ab2e082e058056e1137cc20b
@@ -510,12 +510,12 @@
 F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384
 F src/resolve.c 72fe8cae7326b979e7258ab4c531956951e1a5f3fe8644c646abaec1b2eb6d95
 F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93
-F src/select.c 8c7317d5ee920516a56b8b4ca79fbfca70a1f8b52d67e884c808ea3a016c04e3
+F src/select.c c6a71c619db529e1af6b30d9ff59ec75dac2511f155e45bb6e49c07d9d5e79c0
 F src/shell.c.in 207da30342db0b6fac8b2487abd60b059a5ea80cc9494bd1db76a1dd4aae7cca
 F src/sqlite.h.in b54cd42d2f3b739a00de540cafe2dcd0de3b8e1748a2db33a68def487e9e602f
 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
 F src/sqlite3ext.h 960f1b86c3610fa23cb6a267572a97dcf286e77aa0dd3b9b23292ffaa1ea8683
-F src/sqliteInt.h 0e8cc89b4a589d2bb7de085ddce04ba53a2ad926c7a71ac194114c02cc9810fc
+F src/sqliteInt.h 1da81c69ce881019fe00565c75406265cf40be92a17f323f9045bf034e719ecb
 F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b
 F src/status.c 46e7aec11f79dad50965a5ca5fa9de009f7d6bde08be2156f1538a0a296d4d0e
 F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34
@@ -566,7 +566,7 @@
 F src/test_tclsh.c 06317648b0d85a85fd823f7973b55535c59a3156c1ef59394fe511f932cfa78d
 F src/test_tclvar.c 33ff42149494a39c5fbb0df3d25d6fafb2f668888e41c0688d07273dcb268dfc
 F src/test_thread.c 911d15fb14e19c0c542bdc8aabf981c2f10a4858
-F src/test_vfs.c 4e31a7b98a401431c55590a0ac05f001f520f716d0707ec916b4022b8937fd06
+F src/test_vfs.c c6c6a58f66b26876c7b5769fb323a58b2c7120299b5084e7212c4116f902cbaa
 F src/test_vfstrace.c bab9594adc976cbe696ff3970728830b4c5ed698
 F src/test_windirent.c a895e2c068a06644eef91a7f0a32182445a893b9a0f33d0cdb4283dca2486ac1
 F src/test_windirent.h 90dfbe95442c9762357fe128dc7ae3dc199d006de93eb33ba3972e0a90484215
@@ -574,18 +574,18 @@
 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c
 F src/tokenize.c c8af4feebd8bf5a4d60a14018d91f61013f658ec864dfce7661bae73d86b3191
-F src/treeview.c 7b12ac059de54c939b6eb0dbffc9410c29c80d2470cee5cbe07d5ff9ea2d9253
+F src/treeview.c c6ff90da4cc1813ff2d9bb11f17d4d927db62c47e552faa1835edc47269d753d
 F src/trigger.c 252b650375dd1f47e787fddf5fc0ad14bc298c7af7e6e1b70748df604f2ccb37
 F src/update.c 1816d56c1bca1ba4e0ef98cac2f49be62858e9df1dc08844c7067eb41cc44274
 F src/upsert.c 0dd81b40206841814d46942a7337786932475f085716042d0cb2fc7791bf8ca4
 F src/utf.c 810fbfebe12359f10bc2a011520a6e10879ab2a163bcb26c74768eab82ea62a5
 F src/util.c d9eb0a6c4aae1b00a7369eadd7ca0bbe946cb4c953b6751aa20d357c2f482157
 F src/vacuum.c 3ffe64ecfc94b7528c5d7bdb1c3a19d72fec63f2aa846e3b90f8de5dbbddf5aa
-F src/vdbe.c 8d11da49bda1f504927df424923a415043f5825388e02722c4ac4c6eefc87a47
+F src/vdbe.c 149521430c7d7b9f2d43f6cdb2d2de36e7f35537914aede13e0f94f91113710d
 F src/vdbe.h 55f9ef5d48f6b4b2aa84cba08dab1217400b499e9131d8603289b6ae485bb0d8
-F src/vdbeInt.h 73f5051923f3f29779bfc374c0c68e23b8e5e3792def2e33e51b427edb890abd
+F src/vdbeInt.h a76d5eed62c76bcd8de7afd3147fac1bc40c5a870582664bcd7d071ef437c37f
 F src/vdbeapi.c 57a2d794a8833f269b878dbc24e955369bdb379af6c4e93ebc5ce1a20fa3daf4
-F src/vdbeaux.c dfbedc7b39ca2109d9369d21ecaf8c4f8b3b3365c354c6d783ce65d6f9d61aad
+F src/vdbeaux.c 01631f90d84751911f328dd78ae13e1e811c35d4d99864673eef4bba9dccc349
 F src/vdbeblob.c f5c70f973ea3a9e915d1693278a5f890dc78594300cf4d54e64f2b0917c94191
 F src/vdbemem.c 7b3305bc4a5139f4536ac9b5f61da0f915e49d2e3fdfa87dfdfa9d7aba8bc1e9
 F src/vdbesort.c 90aad5a92608f2dd771c96749beabdb562c9d881131a860a7a5bccf66dc3be7f
@@ -697,7 +697,7 @@
 F test/boundary4.tcl 0bb4b1a94f4fc5ae59b79b9a2b7a140c405e2983
 F test/boundary4.test 89e02fa66397b8a325d5eb102b5806f961f8ec4b
 F test/btree01.test e08b3613540145b353f20c81cb18ead54ff12e0f
-F test/btree02.test a0f33669ba76632247c14718af32db939fa6de5cd13890798ad3f2a362cf7fe4
+F test/btree02.test 7555a5440453d900410160a52554fe6478af4faf53098f7235f1f443d5a1d6cc
 F test/btreefault.test c2bcb542685eea44621275cfedbd8a13f65201e3
 F test/busy.test 510dc6daaad18bcbbc085bcc6217d6dc418def5e73f72ce1475eea0cb7834727
 F test/cache.test 13bc046b26210471ca6f2889aceb1ea52dc717de
@@ -768,7 +768,7 @@
 F test/crashtest1.c 09c1c7d728ccf4feb9e481671e29dda5669bbcc2
 F test/createtab.test b5de160630b209c4b8925bdcbbaf48cc90b67fe8
 F test/cse.test 277350a26264495e86b1785f34d2d0c8600e021c
-F test/csv01.test 4a92840619ef435b905e6d3f35cd0644df23225d7b7967d7940b40f06d6a90a6
+F test/csv01.test 5b54e03d74c0e1966b841b0415062457569aacbe0f41962a41454ac01e8d4496
 F test/ctime.test 78749e6c9a5f0010d67985be80788f841e3cd2da18114e2ed6010399a7d807f3
 F test/cursorhint.test 7bc346788390475e77a345da2b92270d04d35856
 F test/cursorhint2.test 6f3aa9cb19e7418967a10ec6905209bcbb5968054da855fc36c8beee9ae9c42f
@@ -912,7 +912,7 @@
 F test/fts3corrupt.test 46b9ddda7f6588fd5a5b1f4bb4fc0618dc45010e7dddb8a3a188baf3197177ae
 F test/fts3corrupt2.test bf55c3fa0b0dc8ea1c0fe5543623bd27714585da6a129038fd6999fe3b0d25f3
 F test/fts3corrupt3.test 0d5b69a0998b4adf868cc301fc78f3d0707745f1d984ce044c205cdb764b491f
-F test/fts3corrupt4.test 789d97d9c7886c1c287cf51666061973b6cae04be5168a8d8b8bdc1a3fd20a8a
+F test/fts3corrupt4.test eff323c4f93b211424d17f01ac6ace8772fbb712b5c9c578192cedd450023c4b
 F test/fts3cov.test cb932743da52a1c79a1ab8983e26c8121cf02263d6ff16e1f642e6f9b8348338
 F test/fts3d.test 2bd8c97bcb9975f2334147173b4872505b6a41359a4f9068960a36afe07a679f
 F test/fts3defer.test f4c20e4c7153d20a98ee49ee5f3faef624fefc9a067f8d8d629db380c4d9f1de
@@ -1084,7 +1084,7 @@
 F test/lock5.test c6c5e0ebcb21c61a572870cc86c0cb9f14cede38
 F test/lock6.test ad5b387a3a8096afd3c68a55b9535056431b0cf5
 F test/lock7.test 49f1eaff1cdc491cc5dee3669f3c671d9f172431
-F test/lock_common.tcl 7ffb45accf6ee91c736df9bafe0806a44358f035
+F test/lock_common.tcl 2f3f7f2e9637f93ccf609df48ef5b27a50278b6b1cd752b445d52262e5841413
 F test/lookaside.test 5a828e7256f1ee4da8e1bdaa03373a3ccdb0f1ff98dfa82e9b76cb41a45b1083
 F test/main.test 6bbb3999fd461eb8fb335cbab97409a3d7f91bbb8da60635e8be3e4a04a77772
 F test/make-where7.tcl 05c16b5d4f5d6512881dfec560cb793915932ef9
@@ -1187,7 +1187,7 @@
 F test/pcache.test c8acbedd3b6fd0f9a7ca887a83b11d24a007972b
 F test/pcache2.test af7f3deb1a819f77a6d0d81534e97d1cf62cd442
 F test/percentile.test 4243af26b8f3f4555abe166f723715a1f74c77ff
-F test/permutations.test 1f244543fbf05f3ef9a4596d7e7fe5d832b6d973c53a87189515e3c15db562a5
+F test/permutations.test 61c0f61d9b26ebb4643b2ed848e9b3f55492f74e0addab66c7dcd70b081d7b03
 F test/pg_common.tcl 301ac19c1a52fd55166d26db929b3b89165c634d52b5f8ad76ea8cb06960db30
 F test/pragma.test c267bf02742c823a191960895b3d52933cebd7beee26757d1ed694f213fcd867
 F test/pragma2.test e5d5c176360c321344249354c0c16aec46214c9f
@@ -1291,6 +1291,7 @@
 F test/shell6.test 1ceb51b2678c472ba6cf1e5da96679ce8347889fe2c3bf93a0e0fa73f00b00d3
 F test/shell7.test 115132f66d0463417f408562cc2cf534f6bbc6d83a6d50f0072a9eb171bae97f
 F test/shell8.test 96be02ea0c21f05b24c1883d7b711a1fa8525a68ab7b636aacf6057876941013
+F test/shmlock.test 3d1868f0386923c0592a235f2dd87ae52286b217bc695fbfd9d39a828e7be374
 F test/shortread1.test bb591ef20f0fd9ed26d0d12e80eee6d7ac8897a3
 F test/show_speedtest1_rtree.tcl 32e6c5f073d7426148a6936a0408f4b5b169aba5
 F test/shrink.test 1b4330b1fd9e818c04726d45cb28db73087535ce
@@ -1304,7 +1305,7 @@
 F test/snapshot2.test 8d6ff5dd9cc503f6e12d408a30409c3f9c653507b24408d9cd7195931c89bc54
 F test/snapshot3.test 8744313270c55f6e18574283553d3c5c5fe4c5970585663613a0e75c151e599b
 F test/snapshot4.test d4e9347ef2fcabc491fc893506c7bbaf334da3be111d6eb4f3a97cc623b78322
-F test/snapshot_fault.test 508ae6f211d4991e9ff3b5080aeb0a179bf6755138aabeac4bca8083044d895a
+F test/snapshot_fault.test f6c5ef7cb93bf92fbb4e864ecc5c87df7d3a250064838822db5b4d3a5563ede4
 F test/snapshot_up.test a0a29c4cf33475fcef07c3f8e64af795e24ab91b4cc68295863402a393cdd41c
 F test/soak.test 18944cf21b94a7fe0df02016a6ee1e9632bc4e8d095a0cb49d95e15d5cca2d5c
 F test/softheap1.test 843cd84db9891b2d01b9ab64cef3e9020f98d087
@@ -1599,7 +1600,8 @@
 F test/vtab_alter.test 736e66fb5ec7b4fee58229aa3ada2f27ec58bc58c00edae4836890c3784c6783
 F test/vtab_err.test dcc8b7b9cb67522b3fe7a272c73856829dae4ab7fdb30399aea1b6981bda2b65
 F test/vtab_shared.test 5253bff2355a9a3f014c15337da7e177ab0ef8ad
-F test/wal.test 613efec03e517e1775d86b993a54877d2e29a477
+F test/vtabdrop.test 65d4cf6722972e5499bdaf0c0d70ee3b8133944a4e4bc31862563f32a7edca12
+F test/wal.test cdf0ca6cc0447520d19ef1c83287824ebeb3e82d75af856511ba96841a79fc9b
 F test/wal2.test 155b9efa999bdb38ce1cd729b9a4fcdbffd6b88be27f039bad1d2929d287d918
 F test/wal3.test 2a93004bc0fb2b5c29888964024695bade278ab2
 F test/wal4.test 4744e155cd6299c6bd99d3eab1c82f77db9cdb3c
@@ -1619,6 +1621,7 @@
 F test/walcrash3.test e426aa58122d20f2b9fbe9a507f9eb8cab85b8af
 F test/walcrash4.test e7b6e7639a950a0cca8e210e248c8dad4d63bf20
 F test/walfault.test 09b8ad7e52d2f54bce50e31aa7ea51412bb9f70ac13c74e669ddcd8b48b0d98d
+F test/walfault2.test 39337e9ca6906b3942734ab212e099edd7d331b2819a04dbf3b2bd4d58526251
 F test/walhook.test ed00a40ba7255da22d6b66433ab61fab16a63483
 F test/walmode.test cd6e7cff618eaaa5910ce57c3657aa50110397f86213886a2400afb9bfec7b7b
 F test/walnoshm.test 84ca10c544632a756467336b7c3b864d493ee496
@@ -1632,7 +1635,7 @@
 F test/walshared.test 0befc811dcf0b287efae21612304d15576e35417
 F test/walslow.test c05c68d4dc2700a982f89133ce103a1a84cc285f
 F test/walthread.test 14b20fcfa6ae152f5d8e12f5dc8a8a724b7ef189f5d8ef1e2ceab79f2af51747
-F test/walvfs.test 0e24b923a772f4f118bd717cbce5a4f3ca072c36d0bb1775e59802e6415e5f1b
+F test/walvfs.test c0faffda13d045a96dfc541347886bb1a3d6f3205857fc98e683edfab766ea88
 F test/where.test 8215d220633f08da331781cf9ede7fb7aed50eb113473c10acd39a643fd258ba
 F test/where2.test 478d2170637b9211f593120648858593bf2445a1
 F test/where3.test 2341a294e17193a6b1699ea7f192124a5286ca6acfcc3f4b06d16c931fbcda2c
@@ -1673,7 +1676,7 @@
 F test/window5.test d328dd18221217c49c144181975eea17339eaeaf0e9aa558cee3afb84652821e
 F test/window6.test 5eae4ae7a590ccf1e605880969ca0bad3955616ac91cad3031baea38748badb3
 F test/windowfault.test 12ceb6bbb355d13e8fcd88c5731a57256dfdf77b9a7ae20842a76fcd4623df5b
-F test/with1.test 2465d98ffce80d00553ac7135697c18b0369275b6ecc750daa2af320b8c812ca
+F test/with1.test 64fcb1a81685b8a67da61af260a2d8f2afbf3530d39fa451831faf5a9ba6ea45
 F test/with2.test e0030e2f0267a910d6c0e4f46f2dfe941c1cc0d4f659ba69b3597728e7e8f1ab
 F test/with3.test 8d26920c88283e0a473ceebd3451554922108ce7b2a6a1157c47eb0a7011212c
 F test/with4.test 257be66c0c67fee1defbbac0f685c3465e2cad037f21ce65f23f86084f198205
@@ -1700,7 +1703,7 @@
 F tool/cg_anno.tcl f95b0006c52cf7f0496b506343415b6ee3cdcdd3 x
 F tool/checkSpacing.c 810e51703529a204fc4e1eb060e9ab663e3c06d2
 F tool/dbhash.c a06228aa21ebc4e6ea8daa486601d938499238a5
-F tool/dbtotxt.c 249536df1f4b540b275d3e20fbe1421e28e5a92db3498c0fb065d88b60bf6eb8
+F tool/dbtotxt.c 126da0c130f446106d0e9894d0d86640214d5a7f159c99985088e51cde4f5a09
 F tool/dbtotxt.md c9a57af8739957ef36d2cfad5c4b1443ff3688ed33e4901ee200c8b651f43f3c
 F tool/extract.c 054069d81b095fbdc189a6f5d4466e40380505e2
 F tool/fast_vacuum.c 5ba0d6f5963a0a63bdc42840f678bad75b2ebce1
@@ -1792,10 +1795,7 @@
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P 3c2ad0e915e835b1cb2962879beff50b2745d0cefe1cfc89ef90b7879c139ce6
-R 7253304d573583193fd660d5a38c4b33
-T *branch * factor-out-scalar-subselect
-T *sym-factor-out-scalar-subselect *
-T -sym-reuse-subqueries *
+P 50e5f390fbab4189c9700a2c62c951ab9acbf0a03c491e88f3e3bcf19a2311cc 0f1b9ff9e1e6f13e03045fcb7d0907227085054f9eb0b0b8471fb26b0094b13a
+R 447360c957ed3833b50528f10575cb30
 U drh
-Z 7394ebc147279ea7d69a4b85835f879c
+Z e14093037f7573306bc3a2513169a16b
diff --git a/manifest.uuid b/manifest.uuid
index 734f7bf..509dc3d 100644
--- a/manifest.uuid
+++ b/manifest.uuid
@@ -1 +1 @@
-50e5f390fbab4189c9700a2c62c951ab9acbf0a03c491e88f3e3bcf19a2311cc
\ No newline at end of file
+44e1b55aab331933719b67f7fcf7d335234b8b79599fba6033a0a27094bcb644
\ No newline at end of file
diff --git a/src/build.c b/src/build.c
index 0f6670a..23b35d2 100644
--- a/src/build.c
+++ b/src/build.c
@@ -2646,6 +2646,7 @@
   */
   if( IsVirtual(pTab) ){
     sqlite3VdbeAddOp4(v, OP_VDestroy, iDb, 0, 0, pTab->zName, 0);
+    sqlite3MayAbort(pParse);
   }
   sqlite3VdbeAddOp4(v, OP_DropTable, iDb, 0, 0, pTab->zName, 0);
   sqlite3ChangeCookie(pParse, iDb);
diff --git a/src/select.c b/src/select.c
index 5e30504..447a5b0 100644
--- a/src/select.c
+++ b/src/select.c
@@ -5466,14 +5466,19 @@
 ){
   struct SrcList_item *pItem;
   for(pItem = pTabList->a; pItem<pThis; pItem++){
+    Select *pS1;
     if( pItem->pSelect==0 ) continue;
     if( pItem->fg.viaCoroutine ) continue;
     if( pItem->zName==0 ) continue;
     if( sqlite3_stricmp(pItem->zDatabase, pThis->zDatabase)!=0 ) continue;
     if( sqlite3_stricmp(pItem->zName, pThis->zName)!=0 ) continue;
-    if( sqlite3ExprCompare(0, 
-          pThis->pSelect->pWhere, pItem->pSelect->pWhere, -1) 
-    ){
+    pS1 = pItem->pSelect;
+    if( pThis->pSelect->selId!=pS1->selId ){
+      /* The query flattener left two different CTE tables with identical
+      ** names in the same FROM clause. */
+      continue;
+    }
+    if( sqlite3ExprCompare(0, pThis->pSelect->pWhere, pS1->pWhere, -1) ){
       /* The view was modified by some other optimization such as
       ** pushDownWhereTerms() */
       continue;
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index 2ca1de6..2246f84 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -3071,7 +3071,6 @@
   int nErr;            /* Number of errors seen */
   int nTab;            /* Number of previously allocated VDBE cursors */
   int nMem;            /* Number of memory cells used so far */
-  int nOpAlloc;        /* Number of slots allocated for Vdbe.aOp[] */
   int szOpAlloc;       /* Bytes of memory space allocated for Vdbe.aOp[] */
   int iSelfTab;        /* Table associated with an index on expr, or negative
                        ** of the base register during check-constraint eval */
diff --git a/src/test_vfs.c b/src/test_vfs.c
index 10d4032..bf9fa6b 100644
--- a/src/test_vfs.c
+++ b/src/test_vfs.c
@@ -234,6 +234,7 @@
     { SQLITE_LOCKED,   "SQLITE_LOCKED" },
     { SQLITE_BUSY,     "SQLITE_BUSY"   },
     { SQLITE_READONLY, "SQLITE_READONLY"   },
+    { SQLITE_READONLY_CANTINIT, "SQLITE_READONLY_CANTINIT"   },
   };
 
   const char *z;
@@ -919,7 +920,9 @@
   if( rc==SQLITE_OK && isWrite && !pFd->pShm->aPage[iPage] ){
     tvfsAllocPage(pFd->pShm, iPage, pgsz);
   }
-  *pp = (void volatile *)pFd->pShm->aPage[iPage];
+  if( rc==SQLITE_OK || rc==SQLITE_READONLY ){
+    *pp = (void volatile *)pFd->pShm->aPage[iPage];
+  }
 
   return rc;
 }
@@ -1564,8 +1567,115 @@
   return TCL_ERROR;
 }
 
+extern int getDbPointer(Tcl_Interp *interp, const char *zA, sqlite3 **ppDb);
+extern const char *sqlite3ErrName(int);
+
+/*
+** tclcmd: vfs_shmlock DB DBNAME (shared|exclusive) (lock|unlock) OFFSET N
+*/
+static int SQLITE_TCLAPI test_vfs_shmlock(
+  void * clientData,
+  Tcl_Interp *interp,
+  int objc,
+  Tcl_Obj *CONST objv[]
+){
+  const char *azArg1[] = {"shared", "exclusive", 0};
+  const char *azArg2[] = {"lock", "unlock", 0};
+  sqlite3 *db = 0;
+  int rc = SQLITE_OK;
+  const char *zDbname = 0;
+  int iArg1 = 0;
+  int iArg2 = 0;
+  int iOffset = 0;
+  int n = 0;
+  sqlite3_file *pFd;
+
+  if( objc!=7 ){
+    Tcl_WrongNumArgs(interp, 1, objv, 
+        "DB DBNAME (shared|exclusive) (lock|unlock) OFFSET N"
+    );
+    return TCL_ERROR;
+  }
+
+  zDbname = Tcl_GetString(objv[2]);
+  if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) 
+   || Tcl_GetIndexFromObj(interp, objv[3], azArg1, "ARG", 0, &iArg1) 
+   || Tcl_GetIndexFromObj(interp, objv[4], azArg2, "ARG", 0, &iArg2) 
+   || Tcl_GetIntFromObj(interp, objv[5], &iOffset)
+   || Tcl_GetIntFromObj(interp, objv[6], &n)
+  ){
+    return TCL_ERROR;
+  }
+
+  sqlite3_file_control(db, zDbname, SQLITE_FCNTL_FILE_POINTER, (void*)&pFd);
+  if( pFd==0 ){
+    return TCL_ERROR;
+  }
+  rc = pFd->pMethods->xShmLock(pFd, iOffset, n, 
+      (iArg1==0 ? SQLITE_SHM_SHARED : SQLITE_SHM_EXCLUSIVE)
+    | (iArg2==0 ? SQLITE_SHM_LOCK : SQLITE_SHM_UNLOCK)
+  );
+  Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3ErrName(rc), -1));
+  return TCL_OK;
+}
+
+static int SQLITE_TCLAPI test_vfs_set_readmark(
+  void * clientData,
+  Tcl_Interp *interp,
+  int objc,
+  Tcl_Obj *CONST objv[]
+){
+  sqlite3 *db = 0;
+  int rc = SQLITE_OK;
+  const char *zDbname = 0;
+  int iSlot = 0;
+  int iVal = -1;
+  sqlite3_file *pFd;
+  void volatile *pShm = 0;
+  u32 *aShm;
+  int iOff;
+
+  if( objc!=4 && objc!=5 ){
+    Tcl_WrongNumArgs(interp, 1, objv, "DB DBNAME SLOT ?VALUE?");
+    return TCL_ERROR;
+  }
+
+  zDbname = Tcl_GetString(objv[2]);
+  if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) 
+   || Tcl_GetIntFromObj(interp, objv[3], &iSlot)
+   || (objc==5 && Tcl_GetIntFromObj(interp, objv[4], &iVal))
+  ){
+    return TCL_ERROR;
+  }
+
+  sqlite3_file_control(db, zDbname, SQLITE_FCNTL_FILE_POINTER, (void*)&pFd);
+  if( pFd==0 ){
+    return TCL_ERROR;
+  }
+  rc = pFd->pMethods->xShmMap(pFd, 0, 32*1024, 0, &pShm);
+  if( rc!=SQLITE_OK ){
+    Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3ErrName(rc), -1));
+    return TCL_ERROR;
+  }
+  if( pShm==0 ){
+    Tcl_AppendResult(interp, "*-shm is not yet mapped", 0);
+    return TCL_ERROR;
+  }
+  aShm = (u32*)pShm;
+  iOff = 12*2+1+iSlot;
+
+  if( objc==5 ){
+    aShm[iOff] = iVal;
+  }
+  Tcl_SetObjResult(interp, Tcl_NewIntObj(aShm[iOff]));
+
+  return TCL_OK;
+}
+
 int Sqlitetestvfs_Init(Tcl_Interp *interp){
   Tcl_CreateObjCommand(interp, "testvfs", testvfs_cmd, 0, 0);
+  Tcl_CreateObjCommand(interp, "vfs_shmlock", test_vfs_shmlock, 0, 0);
+  Tcl_CreateObjCommand(interp, "vfs_set_readmark", test_vfs_set_readmark, 0, 0);
   return TCL_OK;
 }
 
diff --git a/src/treeview.c b/src/treeview.c
index 16fe5c2..743c3b1 100644
--- a/src/treeview.c
+++ b/src/treeview.c
@@ -138,7 +138,8 @@
       sqlite3_str_appendf(&x, " %s", pItem->zName);
     }
     if( pItem->pTab ){
-      sqlite3_str_appendf(&x, " tabname=%Q", pItem->pTab->zName);
+      sqlite3_str_appendf(&x, " tab=%Q nCol=%d ptr=%p",
+           pItem->pTab->zName, pItem->pTab->nCol, pItem->pTab);
     }
     if( pItem->zAlias ){
       sqlite3_str_appendf(&x, " (AS %s)", pItem->zAlias);
diff --git a/src/vdbe.c b/src/vdbe.c
index 007147d..c538bfc 100644
--- a/src/vdbe.c
+++ b/src/vdbe.c
@@ -6852,6 +6852,7 @@
   db->nVDestroy++;
   rc = sqlite3VtabCallDestroy(db, pOp->p1, pOp->p4.z);
   db->nVDestroy--;
+  assert( p->errorAction==OE_Abort && p->usesStmtJournal );
   if( rc ) goto abort_due_to_error;
   break;
 }
diff --git a/src/vdbeInt.h b/src/vdbeInt.h
index 7054352..acc7f5a 100644
--- a/src/vdbeInt.h
+++ b/src/vdbeInt.h
@@ -385,23 +385,24 @@
   i64 nFkConstraint;      /* Number of imm. FK constraints this VM */
   i64 nStmtDefCons;       /* Number of def. constraints when stmt started */
   i64 nStmtDefImmCons;    /* Number of def. imm constraints when stmt started */
+  Mem *aMem;              /* The memory locations */
+  Mem **apArg;            /* Arguments to currently executing user function */
+  VdbeCursor **apCsr;     /* One element of this array for each open cursor */
+  Mem *aVar;              /* Values for the OP_Variable opcode. */
 
   /* When allocating a new Vdbe object, all of the fields below should be
   ** initialized to zero or NULL */
 
   Op *aOp;                /* Space to hold the virtual machine's program */
-  Mem *aMem;              /* The memory locations */
-  Mem **apArg;            /* Arguments to currently executing user function */
+  int nOp;                /* Number of instructions in the program */
+  int nOpAlloc;           /* Slots allocated for aOp[] */
   Mem *aColName;          /* Column names to return */
   Mem *pResultSet;        /* Pointer to an array of results */
   char *zErrMsg;          /* Error message written here */
-  VdbeCursor **apCsr;     /* One element of this array for each open cursor */
-  Mem *aVar;              /* Values for the OP_Variable opcode. */
   VList *pVList;          /* Name of variables */
 #ifndef SQLITE_OMIT_TRACE
   i64 startTime;          /* Time when query started - used for profiling */
 #endif
-  int nOp;                /* Number of instructions in the program */
 #ifdef SQLITE_DEBUG
   int rcApp;              /* errcode set by sqlite3_result_error_code() */
   u32 nWrite;             /* Number of write operations that have occurred */
diff --git a/src/vdbeaux.c b/src/vdbeaux.c
index 286d4e9..c3b8e8b 100644
--- a/src/vdbeaux.c
+++ b/src/vdbeaux.c
@@ -36,7 +36,7 @@
   pParse->pVdbe = p;
   assert( pParse->aLabel==0 );
   assert( pParse->nLabel==0 );
-  assert( pParse->nOpAlloc==0 );
+  assert( p->nOpAlloc==0 );
   assert( pParse->szOpAlloc==0 );
   sqlite3VdbeAddOp2(p, OP_Init, 0, 1);
   return p;
@@ -139,7 +139,7 @@
 ** to 1024/sizeof(Op).
 **
 ** If an out-of-memory error occurs while resizing the array, return
-** SQLITE_NOMEM. In this case Vdbe.aOp and Parse.nOpAlloc remain 
+** SQLITE_NOMEM. In this case Vdbe.aOp and Vdbe.nOpAlloc remain 
 ** unchanged (this is so that any opcodes already allocated can be 
 ** correctly deallocated along with the rest of the Vdbe).
 */
@@ -155,9 +155,9 @@
   ** operation (without SQLITE_TEST_REALLOC_STRESS) is to double the current
   ** size of the op array or add 1KB of space, whichever is smaller. */
 #ifdef SQLITE_TEST_REALLOC_STRESS
-  int nNew = (p->nOpAlloc>=512 ? p->nOpAlloc*2 : p->nOpAlloc+nOp);
+  int nNew = (v->nOpAlloc>=512 ? v->nOpAlloc*2 : v->nOpAlloc+nOp);
 #else
-  int nNew = (p->nOpAlloc ? p->nOpAlloc*2 : (int)(1024/sizeof(Op)));
+  int nNew = (v->nOpAlloc ? v->nOpAlloc*2 : (int)(1024/sizeof(Op)));
   UNUSED_PARAMETER(nOp);
 #endif
 
@@ -168,11 +168,11 @@
   }
 
   assert( nOp<=(1024/sizeof(Op)) );
-  assert( nNew>=(p->nOpAlloc+nOp) );
+  assert( nNew>=(v->nOpAlloc+nOp) );
   pNew = sqlite3DbRealloc(p->db, v->aOp, nNew*sizeof(Op));
   if( pNew ){
     p->szOpAlloc = sqlite3DbMallocSize(p->db, pNew);
-    p->nOpAlloc = p->szOpAlloc/sizeof(Op);
+    v->nOpAlloc = p->szOpAlloc/sizeof(Op);
     v->aOp = pNew;
   }
   return (pNew ? SQLITE_OK : SQLITE_NOMEM_BKPT);
@@ -206,9 +206,9 @@
 ** operand.
 */
 static SQLITE_NOINLINE int growOp3(Vdbe *p, int op, int p1, int p2, int p3){
-  assert( p->pParse->nOpAlloc<=p->nOp );
+  assert( p->nOpAlloc<=p->nOp );
   if( growOpArray(p, 1) ) return 1;
-  assert( p->pParse->nOpAlloc>p->nOp );
+  assert( p->nOpAlloc>p->nOp );
   return sqlite3VdbeAddOp3(p, op, p1, p2, p3);
 }
 int sqlite3VdbeAddOp3(Vdbe *p, int op, int p1, int p2, int p3){
@@ -218,7 +218,7 @@
   i = p->nOp;
   assert( p->magic==VDBE_MAGIC_INIT );
   assert( op>=0 && op<0xff );
-  if( p->pParse->nOpAlloc<=i ){
+  if( p->nOpAlloc<=i ){
     return growOp3(p, op, p1, p2, p3);
   }
   p->nOp++;
@@ -367,7 +367,9 @@
 ** subsequent Explains until sqlite3VdbeExplainPop() is called.
 */
 void sqlite3VdbeExplain(Parse *pParse, u8 bPush, const char *zFmt, ...){
-#if !defined(SQLITE_DEBUG)
+#ifndef SQLITE_DEBUG
+  /* Always include the OP_Explain opcodes if SQLITE_DEBUG is defined.
+  ** But omit them (for performance) during production builds */
   if( pParse->explain==2 )
 #endif
   {
@@ -616,6 +618,7 @@
   while( (pOp = opIterNext(&sIter))!=0 ){
     int opcode = pOp->opcode;
     if( opcode==OP_Destroy || opcode==OP_VUpdate || opcode==OP_VRename 
+     || opcode==OP_VDestroy
      || ((opcode==OP_Halt || opcode==OP_HaltIfNull) 
       && ((pOp->p1&0xff)==SQLITE_CONSTRAINT && pOp->p2==OE_Abort))
     ){
@@ -805,7 +808,7 @@
 */
 #if defined(SQLITE_DEBUG) && !defined(SQLITE_TEST_REALLOC_STRESS)
 void sqlite3VdbeVerifyNoMallocRequired(Vdbe *p, int N){
-  assert( p->nOp + N <= p->pParse->nOpAlloc );
+  assert( p->nOp + N <= p->nOpAlloc );
 }
 #endif
 
@@ -877,7 +880,7 @@
   VdbeOp *pOut, *pFirst;
   assert( nOp>0 );
   assert( p->magic==VDBE_MAGIC_INIT );
-  if( p->nOp + nOp > p->pParse->nOpAlloc && growOpArray(p, nOp) ){
+  if( p->nOp + nOp > p->nOpAlloc && growOpArray(p, nOp) ){
     return 0;
   }
   pFirst = pOut = &p->aOp[p->nOp];
@@ -2199,19 +2202,27 @@
   ** the leftover memory at the end of the opcode array.  This can significantly
   ** reduce the amount of memory held by a prepared statement.
   */
-  do {
-    x.nNeeded = 0;
-    p->aMem = allocSpace(&x, p->aMem, nMem*sizeof(Mem));
-    p->aVar = allocSpace(&x, p->aVar, nVar*sizeof(Mem));
-    p->apArg = allocSpace(&x, p->apArg, nArg*sizeof(Mem*));
-    p->apCsr = allocSpace(&x, p->apCsr, nCursor*sizeof(VdbeCursor*));
+  x.nNeeded = 0;
+  p->aMem = allocSpace(&x, 0, nMem*sizeof(Mem));
+  p->aVar = allocSpace(&x, 0, nVar*sizeof(Mem));
+  p->apArg = allocSpace(&x, 0, nArg*sizeof(Mem*));
+  p->apCsr = allocSpace(&x, 0, nCursor*sizeof(VdbeCursor*));
 #ifdef SQLITE_ENABLE_STMT_SCANSTATUS
-    p->anExec = allocSpace(&x, p->anExec, p->nOp*sizeof(i64));
+  p->anExec = allocSpace(&x, 0, p->nOp*sizeof(i64));
 #endif
-    if( x.nNeeded==0 ) break;
+  if( x.nNeeded ){
     x.pSpace = p->pFree = sqlite3DbMallocRawNN(db, x.nNeeded);
     x.nFree = x.nNeeded;
-  }while( !db->mallocFailed );
+    if( !db->mallocFailed ){
+      p->aMem = allocSpace(&x, p->aMem, nMem*sizeof(Mem));
+      p->aVar = allocSpace(&x, p->aVar, nVar*sizeof(Mem));
+      p->apArg = allocSpace(&x, p->apArg, nArg*sizeof(Mem*));
+      p->apCsr = allocSpace(&x, p->apCsr, nCursor*sizeof(VdbeCursor*));
+#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
+      p->anExec = allocSpace(&x, p->anExec, p->nOp*sizeof(i64));
+#endif
+    }
+  }
 
   p->pVList = pParse->pVList;
   pParse->pVList =  0;
diff --git a/test/btree02.test b/test/btree02.test
index da35c7f..c1fede5 100644
--- a/test/btree02.test
+++ b/test/btree02.test
@@ -21,7 +21,7 @@
 do_execsql_test btree02-100 {
   CREATE TABLE t1(a TEXT, ax INTEGER, b INT, PRIMARY KEY(a,ax)) WITHOUT ROWID;
   WITH RECURSIVE c(i) AS (VALUES(1) UNION ALL SELECT i+1 FROM c WHERE i<10)
-    INSERT INTO t1(a,ax,b) SELECT printf('%02x',i), random(), i FROM c;
+    INSERT INTO t1(a,ax,b) SELECT printf('%02x',i+160), random(), i FROM c;
   CREATE INDEX t1a ON t1(a);
   CREATE TABLE t2(x,y);
   CREATE TABLE t3(cnt);
@@ -29,26 +29,34 @@
     INSERT INTO t3(cnt) SELECT i FROM c;
   SELECT count(*) FROM t1;
 } {10}
+
+proc showt1 {} {
+  puts -nonewline "t1: "
+  puts [db eval {SELECT printf('(%s,%s)',quote(a),quote(b)) FROM t1}]
+}
+
 do_test btree02-110 {
   db eval BEGIN
   set i 0
+  # showt1
   db eval {SELECT a, ax, b, cnt FROM t1 CROSS JOIN t3 WHERE b IS NOT NULL} {
-    if {$a==""} {set a 0}
-    if {$b==""} {set b 0}    
+    if {$a==""} continue
     db eval {INSERT INTO t2(x,y) VALUES($b,$cnt)}
     # puts "a,b,cnt = ($a,$b,$cnt)"
     incr i
     if {$i%2==1} {
       set bx [expr {$b+1000}]
-      # puts "INSERT ($a),$bx"
+      #  puts "INSERT ($a),$bx"
       db eval {INSERT INTO t1(a,ax,b) VALUES(printf('(%s)',$a),random(),$bx)}
+      # showt1
     } else {
       # puts "DELETE a=$a"
       db eval {DELETE FROM t1 WHERE a=$a}
+      # showt1
     }
     db eval {COMMIT; BEGIN}
   }  
   db one {COMMIT; SELECT count(*) FROM t1;}
-} {27}
+} {10}
 
 finish_test
diff --git a/test/csv01.test b/test/csv01.test
index 13a4b48..eb484f8 100644
--- a/test/csv01.test
+++ b/test/csv01.test
@@ -214,4 +214,27 @@
   SELECT * FROM trent;
 } {1}
 
+# 2018-12-26
+# Bug report on the mailing list
+#
+forcedelete csv01.csv
+set fd [open csv01.csv w]
+puts $fd "a,b,c,d\r\n1,2,3,4\r\none,two,three,four\r\n5,6,7,8"
+close $fd
+do_execsql_test 5.1 {
+  CREATE VIRTUAL TABLE t5_1 USING csv(filename='csv01.csv');
+  SELECT name FROM temp.pragma_table_info('t5_1');
+} {c0 c1 c2 c3}
+do_execsql_test 5.2 {
+  SELECT *, '|' FROM t5_1;
+} {a b c d | 1 2 3 4 | one two three four | 5 6 7 8 |}
+do_execsql_test 5.3 {
+  DROP TABLE t5_1;
+  CREATE VIRTUAL TABLE t5_1 USING csv(filename='csv01.csv', header);
+  SELECT name FROM temp.pragma_table_info('t5_1');
+} {a b c d}
+do_execsql_test 5.4 {
+  SELECT *, '|' FROM t5_1;
+} {1 2 3 4 | one two three four | 5 6 7 8 |}
+
 finish_test
diff --git a/test/fts3corrupt4.test b/test/fts3corrupt4.test
index 79077c2..2718aef 100644
--- a/test/fts3corrupt4.test
+++ b/test/fts3corrupt4.test
@@ -166,5 +166,87 @@
   INSERT INTO t1(t1) VALUES('optimize');
 }
 
+#-------------------------------------------------------------------------
+reset_db
+do_test 5.0 {
+  sqlite3 db {}
+  db deserialize [decode_hexdb {
+| size 24576 pagesize 4096 filename c15.db
+| page 1 offset 0
+|      0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00   SQLite format 3.
+|     16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 04   .....@  ........
+|     32: 00 00 00 00 00 00 00 00 00 00 00 04 00 00 00 04   ................
+|     48: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00   ................
+|     96: 00 00 00 00 0d 0e f9 00 06 0d ec 00 0f cd 0f 69   ...............i
+|    112: 0f 01 0e 10 0e c6 0d ec 00 00 00 00 00 00 00 00   ................
+|   3552: 00 00 00 00 00 00 00 00 00 00 00 00 22 06 06 17   ................
+|   3568: 11 11 01 31 74 61 62 6c 65 74 32 74 32 06 43 52   ...1tablet2t2.CR
+|   3584: 45 41 54 45 20 54 41 42 4c 45 20 74 32 28 78 29   EATE TABLE t2(x)
+|   3600: 81 33 04 07 17 1f 1f 01 82 35 74 61 62 6c 65 74   .3.......5tablet
+|   3616: 31 5f 73 65 67 64 69 72 74 31 5f 73 65 67 64 69   1_segdirt1_segdi
+|   3632: 72 04 43 52 45 41 54 45 20 54 41 42 4c 45 20 27   r.CREATE TABLE '
+|   3648: 74 31 5f 73 65 67 64 69 72 27 28 6c 65 76 65 6c   t1_segdir'(level
+|   3664: 20 49 4e 54 45 47 45 52 2c 69 64 78 20 49 4e 54    INTEGER,idx INT
+|   3680: 45 47 45 52 2c 73 74 61 72 74 5f 62 6c 6f 63 6b   EGER,start_block
+|   3696: 20 49 4e 54 45 47 45 52 2c 6c 65 61 76 65 73 5f    INTEGER,leaves_
+|   3712: 65 6e 64 5f 62 6c 6f 63 6b 20 49 4e 54 45 47 45   end_block INTEGE
+|   3728: 52 2c 65 6e 64 5f 62 6c 6f 63 6b 20 49 4e 54 45   R,end_block INTE
+|   3744: 47 45 52 2c 72 6f 6f 74 20 42 4c 4f 42 2c 50 52   GER,root BLOB,PR
+|   3760: 49 4d 41 52 59 20 4b 45 59 28 6c 65 76 65 6c 2c   IMARY KEY(level,
+|   3776: 20 69 64 78 29 29 31 05 06 17 45 1f 01 00 69 6e    idx))1...E...in
+|   3792: 64 65 78 73 71 6c 69 74 65 5f 61 75 74 6f 69 6e   dexsqlite_autoin
+|   3808: 64 65 79 5f 74 31 5f 73 65 67 64 69 72 5f 31 74   dey_t1_segdir_1t
+|   3824: 31 5f 73 65 67 64 69 72 05 00 00 00 08 00 00 00   1_segdir........
+|   3840: 00 66 03 07 17 23 23 01 81 13 74 61 62 6c 65 74   .f...##...tablet
+|   3856: 31 5f 73 65 67 6d 65 6e 74 73 74 31 5f 73 65 67   1_segmentst1_seg
+|   3872: 6d 65 6e 74 73 03 43 52 45 41 54 45 20 54 41 42   ments.CREATE TAB
+|   3888: 4c 45 20 27 74 31 5f 73 65 67 6d 65 6e 74 73 27   LE 't1_segments'
+|   3904: 28 62 6c 6f 63 6b 69 64 20 49 4e 54 45 47 45 52   (blockid INTEGER
+|   3920: 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 62 6c    PRIMARY KEY, bl
+|   3936: 6f 63 6b 20 42 4c 4f 42 29 62 02 07 17 21 21 01   ock BLOB)b...!!.
+|   3952: 81 0f 74 61 62 6c 65 74 31 5f 63 6f 6e 74 65 6e   ..tablet1_conten
+|   3968: 74 74 31 5f 63 6f 6e 74 65 6e 74 02 43 52 45 41   tt1_content.CREA
+|   3984: 54 45 20 54 41 42 4c 45 20 27 74 31 5f 63 6f 6e   TE TABLE 't1_con
+|   4000: 74 65 6e 74 27 28 64 6f 63 69 64 20 49 4e 54 45   tent'(docid INTE
+|   4016: 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c   GER PRIMARY KEY,
+|   4032: 20 27 63 30 63 6f 6e 74 65 6e 74 27 29 31 01 06    'c0content')1..
+|   4048: 17 11 11 08 51 74 61 62 6c 65 74 31 74 31 43 52   ....Qtablet1t1CR
+|   4064: 45 41 54 45 20 56 49 52 54 55 41 4c 20 54 41 42   EATE VIRTUAL TAB
+|   4080: 4c 45 20 74 31 20 55 53 49 4e 47 20 66 74 73 33   LE t1 USING fts3
+| page 2 offset 4096
+|      0: 0d 00 00 00 03 0f e0 00 0f f6 0f ec 0f e0 00 00   ................
+|   4064: 0a 03 03 00 1b 61 62 61 6e 64 6f 6e 08 02 03 00   .....abandon....
+|   4080: 17 61 62 61 66 74 08 01 03 00 17 61 62 61 63 6b   .abaft.....aback
+| page 3 offset 8192
+|      0: 0d 00 00 00 00 10 00 00 00 00 00 00 00 00 00 00   ................
+| page 4 offset 12288
+|      0: 0d 00 00 00 01 0f d6 00 0f d6 00 00 00 00 00 00   ................
+|   4048: 00 00 00 00 00 00 28 01 07 08 08 08 08 15 46 30   ......(.......F0
+|   4064: 20 32 39 00 05 61 62 61 63 6b 03 01 02 00 03 02    29..aback......
+|   4080: 66 74 03 02 02 00 03 04 6e 64 6f 60 30 30 20 00   ft......ndo`00 .
+| page 5 offset 16384
+|      0: a0 00 00 00 10 ff b0 00 ff fb 00 00 00 00 00 00   ................
+|   4080: 00 00 00 00 00 00 00 00 00 00 00 04 04 08 08 09   ................
+| page 6 offset 20480
+|      0: 0d 00 00 00 05 0f b8 00 0f f4 0f e9 0f d6 0f c7   ................
+|     16: 0f b8 27 74 31 5f 63 6f 6e 74 65 6e 74 27 28 64   ..'t1_content'(d
+|     32: 6f 63 69 64 20 49 4e 54 45 47 45 52 20 50 52 49   ocid INTEGER PRI
+|     48: 4d 41 52 59 20 4b 45 59 2c 20 27 63 30 63 6f 6e   MARY KEY, 'c0con
+|     64: 74 65 6e 74 27 29 31 01 06 17 11 11 08 51 74 61   tent')1......Qta
+|     80: 62 6c 65 74 31 74 31 43 52 45 41 54 45 20 56 49   blet1t1CREATE VI
+|     96: 52 54 55 41 4c 20 54 41 42 4c 45 20 74 31 20 55   RTUAL TABLE t1 U
+|    112: 53 49 4e 47 20 66 74 73 33 0d 00 00 00 03 0f e0   SING fts3.......
+|    128: 00 0f f6 0f ec 0f e0 00 00 00 00 00 00 00 00 00   ................
+|   4016: 00 00 00 00 00 00 00 00 0d 05 02 23 61 75 74 6f   ...........#auto
+|   4032: 6d 65 72 67 65 3d 35 0d 04 02 23 6d 65 72 67 65   merge=5...#merge
+|   4048: 3d 31 30 30 2c 38 11 03 02 2b 69 6e 74 65 67 72   =100,8...+integr
+|   4064: 69 74 79 2d 63 68 65 63 6b 09 02 02 1b 72 65 62   ity-check....reb
+|   4080: 75 69 6c 64 0a 01 02 1d 6f 70 74 69 6d 69 7a 65   uild....optimize
+| end c15.db
+}]} {}
+
+do_catchsql_test 5.1 {
+  SELECT * FROM t1 WHERE t1 MATCH 'abandon';
+} {1 {database disk image is malformed}}
 
 finish_test
diff --git a/test/lock_common.tcl b/test/lock_common.tcl
index a758e7a..3e1821b 100644
--- a/test/lock_common.tcl
+++ b/test/lock_common.tcl
@@ -15,18 +15,20 @@
 
 proc do_multiclient_test {varname script} {
 
-  foreach code [list {
+  foreach {tn code} [list 1 {
     if {[info exists ::G(valgrind)]} { db close ; continue }
     set ::code2_chan [launch_testfixture]
     set ::code3_chan [launch_testfixture]
     proc code2 {tcl} { testfixture $::code2_chan $tcl }
     proc code3 {tcl} { testfixture $::code3_chan $tcl }
-    set tn 1
-  } {
+  } 2 {
     proc code2 {tcl} { uplevel #0 $tcl }
     proc code3 {tcl} { uplevel #0 $tcl }
-    set tn 2
   }] {
+    # Do not run multi-process tests with the unix-excl VFS.
+    #
+    if {$tn==1 && [permutation]=="unix-excl"} continue
+
     faultsim_delete_and_reopen
 
     proc code1 {tcl} { uplevel #0 $tcl }
diff --git a/test/permutations.test b/test/permutations.test
index 1c8c1e6..bb522f0 100644
--- a/test/permutations.test
+++ b/test/permutations.test
@@ -437,8 +437,11 @@
   walmode.test walnoshm.test waloverwrite.test walpersist.test 
   walprotocol2.test walprotocol.test walro2.test walrofault.test 
   walro.test walshared.test walslow.test walvfs.test
-
+  walfault2.test
   nockpt.test
+
+  snapshot2.test snapshot3.test snapshot4.test
+  snapshot_fault.test snapshot.test snapshot_up.test
 } 
 
 test_suite "coverage-pager" -description {
diff --git a/test/shmlock.test b/test/shmlock.test
new file mode 100644
index 0000000..6910758
--- /dev/null
+++ b/test/shmlock.test
@@ -0,0 +1,173 @@
+# 2018 December 6
+#
+# 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.
+#
+#***********************************************************************
+#
+
+set testdir [file dirname $argv0]
+source $testdir/tester.tcl
+
+set testprefix shmlock
+
+ifcapable !wal {finish_test ; return }
+
+sqlite3 db2 test.db
+sqlite3 db3 test.db
+
+do_execsql_test 1.0 {
+  PRAGMA journal_mode = wal;
+  CREATE TABLE t1(a, b);
+  INSERT INTO t1 VALUES(1, 2);
+} {wal}
+do_test 1.1 { execsql { SELECT * FROM t1 } db2 } {1 2}
+do_test 1.2 { execsql { SELECT * FROM t1 } db3 } {1 2}
+
+foreach {tn dbhandle cmd res} {
+  1    db  {shared    lock   7 1}    OK
+  2    db2 {exclusive lock   7 1}    BUSY
+  3    db  {shared    unlock 7 1}    OK
+  4    db2 {exclusive lock   7 1}    OK
+  5    db  {shared    lock   7 1}    BUSY
+  6    db  {exclusive lock   7 1}    BUSY
+  7    db2 {exclusive unlock 7 1}    OK
+
+  8    db  {exclusive lock   0 8}    OK
+  9    db  {exclusive unlock 0 8}    OK
+  10   db2 {exclusive lock   0 8}    OK
+  11   db2 {exclusive unlock 0 8}    OK
+
+  12   db  {shared    lock   0 1}    OK
+  13   db2 {shared    lock   0 1}    OK
+  14   db3 {shared    lock   0 1}    OK
+  15   db3 {shared    unlock 0 1}    OK
+  16   db3 {exclusive lock   0 1}    BUSY
+  17   db2 {shared    unlock 0 1}    OK
+  18   db3 {exclusive lock   0 1}    BUSY
+  19   db  {shared    unlock 0 1}    OK
+  20   db3 {exclusive lock   0 1}    OK
+  21   db3 {exclusive unlock 0 1}    OK
+
+  22   db  {shared    lock   3 1}    OK
+  23   db2 {exclusive lock   2 2}    BUSY
+  24   db  {shared    lock   2 1}    OK
+  25   db2 {exclusive lock   0 5}    BUSY
+  26   db2 {exclusive lock   0 4}    BUSY
+  27   db2 {exclusive lock   0 3}    BUSY
+  28   db  {shared    unlock 3 1}    OK
+  29   db2 {exclusive lock   2 2}    BUSY
+  28   db  {shared    unlock 2 1}    OK
+  29   db2 {exclusive lock   2 2}    OK
+  29   db2 {exclusive unlock 2 2}    OK
+} {
+  do_test 1.3.$tn [list vfs_shmlock $dbhandle main {*}$cmd] "SQLITE_$res"
+}
+
+db  close
+db2 close
+db3 close
+
+if {[permutation]=="unix-excl"} {
+  do_test 2.0 {
+    for {set i 0} {$i < 256} {incr i} { 
+      sqlite3 db$i test.db 
+      execsql { SELECT * FROM t1 } db$i
+    }
+    for {set i 0} {$i < 255} {incr i} { 
+      set rc [vfs_shmlock db$i main shared lock 4 1]
+      if {$rc != "SQLITE_OK"} { error $rc }
+    }
+
+    vfs_shmlock db255 main shared lock 4 1
+  } {SQLITE_BUSY}
+
+  do_test 2.1 { vfs_shmlock db255 main exclusive lock   4 1 } SQLITE_BUSY
+  do_test 2.2 { vfs_shmlock db0   main shared    unlock 4 1 } SQLITE_OK
+  do_test 2.3 { vfs_shmlock db255 main shared    lock   4 1 } SQLITE_OK
+  do_test 2.4 { vfs_shmlock db255 main shared    unlock 4 1 } SQLITE_OK
+  do_test 2.5 { vfs_shmlock db255 main exclusive lock   4 1 } SQLITE_BUSY
+
+  do_test 2.6 {
+    for {set i 1} {$i < 255} {incr i} { 
+      set rc [vfs_shmlock db255 main exclusive lock 4 1]
+      if {$rc != "SQLITE_BUSY"} { error $rc }
+      set rc [vfs_shmlock db$i main shared unlock 4 1]
+      if {$rc != "SQLITE_OK"} { error $rc }
+    }
+
+    vfs_shmlock db255 main exclusive lock 4 1
+  } {SQLITE_OK}
+
+  vfs_shmlock db255 main exclusive unlock 4 1
+
+  for {set i 0} {$i < 256} {incr i} {
+    db$i close
+  }
+}
+
+sqlite3 db0 test.db
+sqlite3 db1 test.db
+do_test 3.1 { execsql { SELECT * FROM t1 } db0 } {1 2}
+do_test 3.2 { execsql { SELECT * FROM t1 } db1 } {1 2}
+
+set L(0) {n n n n n n n n}
+set L(1) {n n n n n n n n}
+proc random_lock_test {idx} {
+  global L
+  set iSlot [expr int(rand()*8)]
+  if {[expr int(rand()*2)]} {
+    # Unlock operation
+    if {[lindex $L($idx) $iSlot]!="n"} {
+      vfs_shmlock db$idx main [lindex $L($idx) $iSlot] unlock $iSlot 1
+      lset L($idx) $iSlot n
+    }
+  } else {
+    # Lock operation
+    if {[lindex $L($idx) $iSlot]=="n"} {
+      set locktype [lindex {e s} [expr int(rand()*2)]]
+      set n 1
+      if {$locktype=="e"} {
+        for {set l $iSlot} {$l<8 && [lindex $L($idx) $l]=="n"} {incr l} {}
+        set n [expr int(rand()*($l-$iSlot))+1]
+        # puts "iSlot=$iSlot l=$l L=$L($idx)"
+        # puts "$iSlot $n"
+      }
+      set res [vfs_shmlock db$idx main $locktype lock $iSlot $n]
+
+      set bBusy 0
+      for {set i $iSlot} {$i<($iSlot+$n)} {incr i} {
+        set other [lindex $L([expr ($idx+1)%2]) $i]
+        if {($other!="n" && $locktype=="e")||($other=="e" && $locktype=="s")} {
+          if {$res != "SQLITE_BUSY"} { error "BUSY not detected" }
+          set bBusy 1
+          break
+        } 
+      }
+
+      if {$bBusy==0} {
+        if {$res != "SQLITE_OK"} { error "BUSY false-positive" }
+        for {set i $iSlot} {$i<($iSlot+$n)} {incr i} {
+          lset L($idx) $i $locktype
+        }
+      }
+    }
+  }
+}
+
+set nStep 100000
+for {set i 0} {$i < $nStep} {incr i} {
+  random_lock_test 0
+  random_lock_test 1
+}
+
+db0 close
+db1 close
+
+finish_test
+
+
diff --git a/test/snapshot_fault.test b/test/snapshot_fault.test
index c0df4ec..2adb793 100644
--- a/test/snapshot_fault.test
+++ b/test/snapshot_fault.test
@@ -221,6 +221,31 @@
   faultsim_test_result {0 {}} {1 SQLITE_IOERR}
 }
 
+#-------------------------------------------------------------------------
+# Test the handling of faults that occur within sqlite3_snapshot_get().
+#
+reset_db
+do_execsql_test 5.0 {
+  PRAGMA page_size = 512;
+  PRAGMA journal_mode = wal;
+  PRAGMA wal_autocheckpoint = 0;
+  CREATE TABLE t1(zzz);
+  INSERT INTO t1 VALUES(randomblob( 5000 ));
+  PRAGMA user_version = 211;
+} {wal 0}
+faultsim_save_and_close
+
+do_faultsim_test 5 -prep {
+  faultsim_restore_and_reopen
+  execsql { SELECT count(*) FROM sqlite_master }
+  execsql BEGIN
+} -body {
+  sqlite3_snapshot_get_blob db main
+  set {} {}
+} -test {
+  execsql END
+  faultsim_test_result {0 {}} {1 SQLITE_IOERR} {1 SQLITE_NOMEM}
+}
 
 
 finish_test
diff --git a/test/vtabdrop.test b/test/vtabdrop.test
new file mode 100644
index 0000000..1f9309e
--- /dev/null
+++ b/test/vtabdrop.test
@@ -0,0 +1,127 @@
+# 2018 December 28
+#
+#    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.
+#
+#***********************************************************************
+#
+# The tests in this file test edge cases surrounding DROP TABLE on 
+# virtual tables.
+#
+
+set testdir [file dirname $argv0]
+source $testdir/tester.tcl
+
+ifcapable !vtab { finish_test ; return }
+source $testdir/fts3_common.tcl
+source $testdir/malloc_common.tcl
+
+set testprefix vtabdrop
+
+#-------------------------------------------------------------------------
+# Test that if a DROP TABLE is executed against an rtree table, but the
+# xDestroy() call fails, the rtree table is not dropped, the sqlite_master
+# table is not modified and the internal schema remains intact.
+# 
+ifcapable rtree {
+  do_execsql_test 1.0 {
+    CREATE VIRTUAL TABLE rt USING rtree(id, x1, x2);
+    CREATE TABLE t1(x, y);
+    INSERT INTO t1 VALUES(1, 2);
+  }
+  
+  do_test 1.1 {
+    execsql {
+      BEGIN;
+        INSERT INTO t1 VALUES(3, 4);
+    }
+    db eval { SELECT * FROM t1 } {
+      catchsql { DROP TABLE rt }
+    }
+    execsql COMMIT
+  } {}
+  
+  do_execsql_test 1.2 {
+    SELECT name FROM sqlite_master ORDER BY 1;
+    SELECT * FROM t1;
+    SELECT * FROM rt;
+  } {rt rt_node rt_parent rt_rowid t1 1 2 3 4}
+  
+  db close
+  sqlite3 db test.db
+  
+  do_execsql_test 1.3 {
+    SELECT name FROM sqlite_master ORDER BY 1;
+  } {rt rt_node rt_parent rt_rowid t1}
+}
+
+#-------------------------------------------------------------------------
+# Same as tests 1.*, except with fts5 instead of rtree.
+# 
+ifcapable fts5 {
+  reset_db
+  do_execsql_test 2.0 {
+    CREATE VIRTUAL TABLE ft USING fts5(x);
+    CREATE TABLE t1(x, y);
+    INSERT INTO t1 VALUES(1, 2);
+  }
+  
+  do_test 2.1 {
+    execsql {
+      BEGIN;
+        INSERT INTO t1 VALUES(3, 4);
+    }
+    db eval { SELECT * FROM t1 } {
+      catchsql { DROP TABLE ft }
+    }
+    execsql COMMIT
+  } {}
+  
+  do_execsql_test 2.2 {
+    SELECT name FROM sqlite_master ORDER BY 1;
+  } {ft ft_config ft_content ft_data ft_docsize ft_idx t1}
+  
+  db close
+  sqlite3 db test.db
+  
+  do_execsql_test 2.3 {
+    SELECT name FROM sqlite_master ORDER BY 1;
+  } {ft ft_config ft_content ft_data ft_docsize ft_idx t1}
+}
+
+#-------------------------------------------------------------------------
+# Same as tests 1.*, except with fts3 instead of rtree.
+# 
+ifcapable fts3 {
+  reset_db
+  do_execsql_test 2.0 {
+    CREATE VIRTUAL TABLE ft USING fts3(x);
+    CREATE TABLE t1(x, y);
+    INSERT INTO t1 VALUES(1, 2);
+  }
+  
+  do_test 2.1 {
+    execsql {
+      BEGIN;
+        INSERT INTO t1 VALUES(3, 4);
+    }
+    db eval { SELECT * FROM t1 } {
+      catchsql { DROP TABLE ft }
+    }
+    execsql COMMIT
+  } {}
+  
+  do_execsql_test 2.2 {
+    SELECT name FROM sqlite_master ORDER BY 1;
+  } {ft ft_content ft_segdir ft_segments sqlite_autoindex_ft_segdir_1 t1}
+  
+  db close
+  sqlite3 db test.db
+  
+  do_execsql_test 2.3 {
+    SELECT name FROM sqlite_master ORDER BY 1;
+  } {ft ft_content ft_segdir ft_segments sqlite_autoindex_ft_segdir_1 t1}
+}
+
+finish_test
diff --git a/test/wal.test b/test/wal.test
index bb164bb..a003b6a 100644
--- a/test/wal.test
+++ b/test/wal.test
@@ -1297,51 +1297,53 @@
 # At one point, SQLite was failing to grow the mapping of the wal-index
 # file in step 3 and the checkpoint was corrupting the database file.
 #
-do_test wal-20.1 {
-  catch {db close}
-  forcedelete test.db test.db-wal test.db-journal
-  sqlite3 db test.db
-  execsql {
-    PRAGMA journal_mode = WAL;
-    CREATE TABLE t1(x);
-    INSERT INTO t1 VALUES(randomblob(900));
-    SELECT count(*) FROM t1;
-  }
-} {wal 1}
-do_test wal-20.2 {
-  set ::buddy [launch_testfixture]
-  testfixture $::buddy {
+if {[permutation]!="unix-excl"} {
+  do_test wal-20.1 {
+    catch {db close}
+    forcedelete test.db test.db-wal test.db-journal
     sqlite3 db test.db
-    db transaction { db eval {
-      PRAGMA wal_autocheckpoint = 0;
-      INSERT INTO t1 SELECT randomblob(900) FROM t1;       /* 2 */
-      INSERT INTO t1 SELECT randomblob(900) FROM t1;       /* 4 */
-      INSERT INTO t1 SELECT randomblob(900) FROM t1;       /* 8 */
-      INSERT INTO t1 SELECT randomblob(900) FROM t1;       /* 16 */
-      INSERT INTO t1 SELECT randomblob(900) FROM t1;       /* 32 */
-      INSERT INTO t1 SELECT randomblob(900) FROM t1;       /* 64 */
-      INSERT INTO t1 SELECT randomblob(900) FROM t1;       /* 128 */
-      INSERT INTO t1 SELECT randomblob(900) FROM t1;       /* 256 */
-      INSERT INTO t1 SELECT randomblob(900) FROM t1;       /* 512 */
-      INSERT INTO t1 SELECT randomblob(900) FROM t1;       /* 1024 */
-      INSERT INTO t1 SELECT randomblob(900) FROM t1;       /* 2048 */
-      INSERT INTO t1 SELECT randomblob(900) FROM t1;       /* 4096 */
-      INSERT INTO t1 SELECT randomblob(900) FROM t1;       /* 8192 */
-      INSERT INTO t1 SELECT randomblob(900) FROM t1;       /* 16384 */
-    } }
-  }
-} {0}
-do_test wal-20.3 {
-  close $::buddy
-  execsql { PRAGMA wal_checkpoint }
-  execsql { SELECT count(*) FROM t1 }
-} {16384}
-do_test wal-20.4 {
-  db close
-  sqlite3 db test.db
-  execsql { SELECT count(*) FROM t1 }
-} {16384}
-integrity_check wal-20.5
+    execsql {
+      PRAGMA journal_mode = WAL;
+      CREATE TABLE t1(x);
+      INSERT INTO t1 VALUES(randomblob(900));
+      SELECT count(*) FROM t1;
+    }
+  } {wal 1}
+  do_test wal-20.2 {
+    set ::buddy [launch_testfixture]
+    testfixture $::buddy {
+      sqlite3 db test.db
+      db transaction { db eval {
+        PRAGMA wal_autocheckpoint = 0;
+        INSERT INTO t1 SELECT randomblob(900) FROM t1;       /* 2 */
+        INSERT INTO t1 SELECT randomblob(900) FROM t1;       /* 4 */
+        INSERT INTO t1 SELECT randomblob(900) FROM t1;       /* 8 */
+        INSERT INTO t1 SELECT randomblob(900) FROM t1;       /* 16 */
+        INSERT INTO t1 SELECT randomblob(900) FROM t1;       /* 32 */
+        INSERT INTO t1 SELECT randomblob(900) FROM t1;       /* 64 */
+        INSERT INTO t1 SELECT randomblob(900) FROM t1;       /* 128 */
+        INSERT INTO t1 SELECT randomblob(900) FROM t1;       /* 256 */
+        INSERT INTO t1 SELECT randomblob(900) FROM t1;       /* 512 */
+        INSERT INTO t1 SELECT randomblob(900) FROM t1;       /* 1024 */
+        INSERT INTO t1 SELECT randomblob(900) FROM t1;       /* 2048 */
+        INSERT INTO t1 SELECT randomblob(900) FROM t1;       /* 4096 */
+        INSERT INTO t1 SELECT randomblob(900) FROM t1;       /* 8192 */
+        INSERT INTO t1 SELECT randomblob(900) FROM t1;       /* 16384 */
+      } }
+    }
+  } {0}
+  do_test wal-20.3 {
+    close $::buddy
+    execsql { PRAGMA wal_checkpoint }
+    execsql { SELECT count(*) FROM t1 }
+  } {16384}
+  do_test wal-20.4 {
+    db close
+    sqlite3 db test.db
+    execsql { SELECT count(*) FROM t1 }
+  } {16384}
+  integrity_check wal-20.5
+}
 
 catch { db2 close }
 catch { db close }
diff --git a/test/walfault2.test b/test/walfault2.test
new file mode 100644
index 0000000..239370a
--- /dev/null
+++ b/test/walfault2.test
@@ -0,0 +1,90 @@
+# 2010 May 03
+#
+# 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 implements regression tests for SQLite library.  The
+# focus of this file is testing the operation of the library in
+# "PRAGMA journal_mode=WAL" mode.
+#
+
+set testdir [file dirname $argv0]
+source $testdir/tester.tcl
+source $testdir/malloc_common.tcl
+source $testdir/lock_common.tcl
+
+ifcapable !wal {finish_test ; return }
+set testprefix walfault2
+
+#-------------------------------------------------------------------------
+# Inject faults while truncating the wal file.
+#
+do_execsql_test 1.0 {
+  PRAGMA auto_vacuum = 0;
+  CREATE TABLE t1(a, b);
+  PRAGMA journal_mode = wal;
+  WITH s(i) AS (
+    SELECT 1 UNION ALL SELECT i+1 FROM s LIMIT 30
+  )
+  INSERT INTO t1 SELECT randomblob(400), randomblob(400) FROM s;
+} {wal}
+faultsim_save_and_close
+
+do_faultsim_test 1 -prep {
+  faultsim_restore
+  sqlite3 db file:test.db?psow=0 -uri 1
+  file_control_powersafe_overwrite db 0
+  execsql {
+    PRAGMA wal_checkpoint;
+    PRAGMA journal_size_limit = 10000;
+    PRAGMA synchronous = full;
+  }
+} -body {
+  execsql { INSERT INTO t1 VALUES(1,1) }
+} -test {
+  faultsim_test_result {0 {}}
+}
+
+#-------------------------------------------------------------------------
+# Inject faults while rewriting checksums.
+#
+reset_db
+do_execsql_test 2.0 {
+  PRAGMA auto_vacuum = 0;
+  CREATE TABLE t1(a, b);
+  PRAGMA journal_mode = wal;
+  WITH s(i) AS (
+    SELECT 1 UNION ALL SELECT i+1 FROM s LIMIT 30
+  )
+  INSERT INTO t1 SELECT randomblob(400), randomblob(400) FROM s;
+} {wal}
+faultsim_save_and_close
+
+do_faultsim_test 2 -prep {
+  faultsim_restore_and_reopen
+  execsql {
+    PRAGMA cache_size = 2;
+    BEGIN;
+    UPDATE t1 SET a=randomblob(400);
+    UPDATE t1 SET b=randomblob(400);
+    UPDATE t1 SET a=randomblob(400);
+    UPDATE t1 SET b=randomblob(400);
+    UPDATE t1 SET a=randomblob(400);
+    UPDATE t1 SET b=randomblob(400);
+    UPDATE t1 SET a=randomblob(400);
+    UPDATE t1 SET b=randomblob(400);
+  }
+} -body {
+  execsql COMMIT
+} -test {
+  faultsim_test_result {0 {}}
+}
+
+
+
+finish_test
diff --git a/test/walvfs.test b/test/walvfs.test
index 9fac6a3..cb8005c 100644
--- a/test/walvfs.test
+++ b/test/walvfs.test
@@ -33,6 +33,7 @@
   }
 }
 
+
 #-------------------------------------------------------------------------
 # Test that if IOCAP_SEQUENTIAL is set, the wal-header is not synced to
 # disk immediately after it is written.
@@ -105,6 +106,8 @@
 
 #-------------------------------------------------------------------------
 # Test that a checkpoint may be interrupted using sqlite3_interrupt().
+# And that the error code is SQLITE_NOMEM, not SQLITE_INTERRUPT, if
+# an OOM error occurs just before the sqlite3_interrupt() call.
 #
 reset_db
 db close
@@ -137,6 +140,23 @@
   PRAGMA wal_checkpoint
 } {1 interrupted}
 
+set ::cnt 2
+proc xWrite {method file args} {
+  if {[file tail $file]=="test.db"} {
+    incr ::cnt -1
+    if {$::cnt==0} {
+      sqlite3_memdebug_fail 5 -repeat 0
+      catchsql { SELECT 'a big long string!' }
+      sqlite3_interrupt db
+    }
+  }
+  return SQLITE_OK
+}
+
+do_catchsql_test 3.2 {
+  PRAGMA wal_checkpoint
+} {1 {out of memory}}
+
 #-------------------------------------------------------------------------
 #
 reset_db
@@ -182,6 +202,228 @@
   SELECT count(*) FROM t1
 } {1 {attempt to write a readonly database}}
 
+#-------------------------------------------------------------------------
+#
+reset_db
+db close 
+sqlite3 db test.db -vfs tvfs
+tvfs filter {}
+do_execsql_test 5.0 {
+  PRAGMA auto_vacuum = 0;
+  PRAGMA page_size = 1024;
+  CREATE TABLE t1(x);
+  PRAGMA journal_mode = wal;
+  WITH s(i) AS (
+      SELECT 1 UNION ALL SELECT i+1 FROM s LIMIT 20
+  )
+  INSERT INTO t1 SELECT randomblob(750) FROM s;
+} {wal}
+
+do_execsql_test 5.1 {
+  SELECT count(*) FROM t1
+} {20}
+
+do_test 5.2 {
+  vfs_set_readmark db main 1 100
+  vfs_set_readmark db main 2 100
+  vfs_set_readmark db main 3 100
+  vfs_set_readmark db main 4 100
+} {100}
+
+do_execsql_test 5.3 {
+  SELECT count(*) FROM t1
+} {20}
+
+do_test 5.3 {
+  list [vfs_set_readmark db main 1] \
+       [vfs_set_readmark db main 2] \
+       [vfs_set_readmark db main 3] \
+       [vfs_set_readmark db main 4] 
+} {24 100 100 100}
+
+tvfs script xShmLock
+tvfs filter xShmLock
+set ::cnt 20
+proc xShmLock {args} {
+  incr ::cnt -1
+  if {$::cnt>0} { return SQLITE_BUSY }
+  return SQLITE_OK
+}
+
+do_test 5.4 {
+  vfs_set_readmark db main 1 100
+  execsql { SELECT count(*) FROM t1 }
+} {20}
+
+vfs_set_readmark db main 1 100
+vfs_set_readmark db main 2 100
+vfs_set_readmark db main 3 100
+vfs_set_readmark db main 4 100
+
+tvfs script xShmMapLock
+tvfs filter {xShmLock xShmMap}
+proc xShmMapLock {method args} {
+  if {$method=="xShmMap"} {
+    return "SQLITE_READONLY"
+  }
+  return SQLITE_BUSY
+}
+
+sqlite3 db2 test.db -vfs tvfs
+breakpoint
+do_test 5.5 {
+  list [catch { execsql { SELECT count(*) FROM t1 } db2 } msg] $msg
+} {1 {attempt to write a readonly database}}
+
+tvfs filter {}
+vfs_set_readmark db main 1 1
+
+do_test 5.6 {
+  list [catch { execsql { SELECT count(*) FROM t1 } db2 } msg] $msg
+} {0 20}
+db2 close
 db close
+
+#-------------------------------------------------------------------------
+# Cause an SQLITE_PROTOCOL while attempting to restart the wal file.
+#
+reset_db
+tvfs filter {}
+db close
+sqlite3 db test.db -vfs tvfs
+do_execsql_test 6.0 {
+  PRAGMA auto_vacuum = 0;
+  PRAGMA page_size = 1024;
+  CREATE TABLE t1(x);
+  PRAGMA journal_mode = wal;
+  WITH s(i) AS (
+      SELECT 1 UNION ALL SELECT i+1 FROM s LIMIT 20
+  )
+  INSERT INTO t1 SELECT randomblob(750) FROM s;
+} {wal}
+
+do_test 6.1 {
+  execsql { PRAGMA wal_checkpoint } 
+  set {} {}
+} {}
+
+tvfs filter xShmLock
+tvfs script xShmLock
+set ::flag 0
+proc xShmLock {method file handle spec} {
+  if {$::flag && [lrange $spec 2 end]=="lock shared"} {
+    return SQLITE_BUSY
+  }
+  if {$spec=="3 1 unlock shared"} {
+    set ::flag 1
+  }
+  return SQLITE_OK
+}
+
+puts "# WARNING: This next test takes around 12 seconds"
+do_catchsql_test 6.2 {
+  INSERT INTO t1 VALUES(1);
+} {1 {locking protocol}}
+
+#-------------------------------------------------------------------------
+# Check that a checkpoint fails if it cannot get the CHECKPOINTER lock
+#
+reset_db
+tvfs filter {}
+db close
+sqlite3 db test.db -vfs tvfs
+do_execsql_test 7.0 {
+  PRAGMA auto_vacuum = 0;
+  PRAGMA page_size = 1024;
+  CREATE TABLE t1(x);
+  PRAGMA journal_mode = wal;
+  WITH s(i) AS (
+      SELECT 1 UNION ALL SELECT i+1 FROM s LIMIT 20
+  )
+  INSERT INTO t1 SELECT randomblob(750) FROM s;
+} {wal}
+
+tvfs script xShmLock
+tvfs filter xShmLock
+proc xShmLock {method file handle spec} {
+  if {$spec=="1 1 lock exclusive"} {
+    return SQLITE_BUSY
+  }
+  return SQLITE_OK
+}
+
+do_execsql_test 7.1 {
+  PRAGMA wal_checkpoint
+} {1 -1 -1}
+
+#-------------------------------------------------------------------------
+# Check that the page cache is correctly flushed if a checkpointer using
+# a version 2 VFS makes a checkpoint with an out-of-date cache.
+#
+reset_db
+testvfs tvfs2 -iversion 2
+db close
+sqlite3 db test.db -vfs tvfs2
+do_execsql_test 8.0 {
+  PRAGMA auto_vacuum = 0;
+  PRAGMA page_size = 1024;
+  CREATE TABLE t1(x);
+  PRAGMA journal_mode = wal;
+  WITH s(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM s LIMIT 20 )
+  INSERT INTO t1 SELECT randomblob(75) FROM s;
+} {wal}
+
+do_execsql_test 8.1 { SELECT count(*) FROM t1 } {20}
+
+do_test 8.2 {
+  sqlite3 db2 test.db -vfs tvfs2
+  execsql {
+    INSERT INTO t1 VALUES(randomblob(75));
+  } db2
+  db2 close
+} {}
+
+do_execsql_test 8.3 { 
+  PRAGMA wal_checkpoint;
+  SELECT count(*) FROM t1 
+} {0 5 5 21}
+tvfs2 delete
+
+#-------------------------------------------------------------------------
+reset_db
+db close
+sqlite3 db test.db -vfs tvfs
+do_execsql_test 9.0 {
+  PRAGMA auto_vacuum = 0;
+  PRAGMA page_size = 1024;
+  CREATE TABLE t1(x);
+  PRAGMA journal_mode = wal;
+  WITH s(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM s LIMIT 20 )
+  INSERT INTO t1 SELECT randomblob(75) FROM s;
+} {wal}
+
+sqlite3 db2 test.db -vfs tvfs
+tvfs filter {xShmMap xShmLock}
+tvfs script xShmMap
+proc xShmMap {method file handle args} {
+  switch -- $method {
+    xShmMap {
+      return "SQLITE_READONLY_CANTINIT"
+    }
+    xShmLock {
+      if {$args=="{3 1 lock shared}"} {
+        return "SQLITE_IOERR"
+      }
+    }
+  }
+}
+
+do_test 9.1 {
+  catchsql { SELECT count(*) FROM t1 } db2
+} {1 {disk I/O error}}
+
+db close
+db2 close
 tvfs delete
 finish_test
+
diff --git a/test/with1.test b/test/with1.test
index f9b41ff..517d858 100644
--- a/test/with1.test
+++ b/test/with1.test
@@ -1044,4 +1044,23 @@
   WITH c(i)AS(VALUES(5)UNIoN SELECT 0)SELECT min(1)-i fROM c;
 } {1}
 
+# 2018-12-26
+# Two different CTE tables with the same name appear in within a single FROM
+# clause due to the query-flattener optimization.  make sure this does not cause
+# problems.  This problem was discovered by Matt Denton.
+#
+do_execsql_test 21.1 {
+   WITH RECURSIVE t21(a,b) AS (
+    WITH t21(x) AS (VALUES(1))
+    SELECT x, x FROM t21 ORDER BY 1
+  )
+  SELECT * FROM t21 AS tA, t21 AS tB
+} {1 1 1 1}
+do_execsql_test 21.2 {
+  SELECT printf('',
+     EXISTS (WITH RECURSIVE Table0 AS (WITH Table0 AS (SELECT DISTINCT 1)
+                                       SELECT *, * FROM Table0 ORDER BY 1 DESC)
+             SELECT * FROM Table0  NATURAL JOIN  Table0));
+} {{}}
+
 finish_test
diff --git a/tool/dbtotxt.c b/tool/dbtotxt.c
index 98a8cdc..41bcb4c 100644
--- a/tool/dbtotxt.c
+++ b/tool/dbtotxt.c
@@ -112,7 +112,7 @@
   }
   zBaseName = zInputFile;
   for(i=0; zInputFile[i]; i++){
-    if( zInputFile[i]=='/' && zInputFile[i+1]!=0 ) zBaseName = zInputFile+1;
+    if( zInputFile[i]=='/' && zInputFile[i+1]!=0 ) zBaseName = zInputFile+i+1;
   }
   printf("| size %d pagesize %d filename %s\n",(int)szFile,pgsz,zBaseName);
   for(i=0; i<szFile; i+=16){