/ Check-in [404f9d99]
Login

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

Overview
Comment:Merge latest trunk changes with this branch.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | wal2
Files: files | file ages | folders
SHA3-256: 404f9d99d325ddf82fde6d957860d30b2fb67f232c0878a3cf6df9596541f16e
User & Date: dan 2018-12-26 19:10:59
Wiki:wal2
Context
2018-12-26
20:42
Improve testing of the wal.c changes on this branch. check-in: 63483e22 user: dan tags: wal2
19:10
Merge latest trunk changes with this branch. check-in: 404f9d99 user: dan tags: wal2
18:34
Update the coverage-wal permutation to cover branches enabled by SQLITE_ENABLE_SNAPSHOT. check-in: 6821c61f user: dan tags: trunk
2018-12-22
15:50
Enhance the wal2 header comment in wal.c to explain how the wal-hook is invoked in wal2 mode. check-in: 118aa7e3 user: dan tags: wal2
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to Makefile.in.

   665    665   	$(LTLINK) -o $@ $(FUZZCHECK_OPT) $(FUZZCHECK_SRC) sqlite3.c $(TLIBS)
   666    666   
   667    667   ossshell$(TEXE):	$(TOP)/test/ossfuzz.c $(TOP)/test/ossshell.c sqlite3.c sqlite3.h
   668    668   	$(LTLINK) -o $@ $(FUZZCHECK_OPT) $(TOP)/test/ossshell.c \
   669    669                $(TOP)/test/ossfuzz.c sqlite3.c $(TLIBS)
   670    670   
   671    671   sessionfuzz$(TEXE):	$(TOP)/test/sessionfuzz.c sqlite3.c sqlite3.h
   672         -	$(CC) $(CFLAGS) -I. -o $@ $(TOP)/test/sessionfuzz.c $(TLIBS)
          672  +	$(LTLINK) -o $@ $(TOP)/test/sessionfuzz.c $(TLIBS)
   673    673   
   674    674   dbfuzz$(TEXE):	$(TOP)/test/dbfuzz.c sqlite3.c sqlite3.h
   675    675   	$(LTLINK) -o $@ $(DBFUZZ_OPT) $(TOP)/test/dbfuzz.c sqlite3.c $(TLIBS)
   676    676   
   677    677   DBFUZZ2_OPTS = \
   678    678     -DSQLITE_THREADSAFE=0 \
   679    679     -DSQLITE_OMIT_LOAD_EXTENSION \
................................................................................
   681    681     -DSQLITE_DEBUG \
   682    682     -DSQLITE_ENABLE_DBSTAT_VTAB \
   683    683     -DSQLITE_ENABLE_RTREE \
   684    684     -DSQLITE_ENABLE_FTS4 \
   685    685     -DSQLITE_EANBLE_FTS5
   686    686   
   687    687   dbfuzz2:	$(TOP)/test/dbfuzz2.c sqlite3.c sqlite3.h
   688         -	clang-6.0 -I. -g -O0 -fsanitize=fuzzer,undefined,address -o dbfuzz2 \
          688  +	clang-6.0 $(OPT_FEATURE_FLAGS) $(OPTS) -I. -g -O0 \
          689  +		-fsanitize=fuzzer,undefined,address -o dbfuzz2 \
   689    690   		$(DBFUZZ2_OPTS) $(TOP)/test/dbfuzz2.c sqlite3.c
   690    691   	mkdir -p dbfuzz2-dir
   691    692   	cp $(TOP)/test/dbfuzz2-seed* dbfuzz2-dir
   692    693   
   693    694   mptester$(TEXE):	sqlite3.lo $(TOP)/mptest/mptest.c
   694    695   	$(LTLINK) -o $@ -I. $(TOP)/mptest/mptest.c sqlite3.lo \
   695    696   		$(TLIBS) -rpath "$(libdir)"
................................................................................
  1185   1186   TESTFIXTURE_FLAGS += -DTCLSH_INIT_PROC=sqlite3TestInit
  1186   1187   TESTFIXTURE_FLAGS += -DSQLITE_SERVER=1 -DSQLITE_PRIVATE="" -DSQLITE_CORE
  1187   1188   TESTFIXTURE_FLAGS += -DBUILD_sqlite
  1188   1189   TESTFIXTURE_FLAGS += -DSQLITE_SERIES_CONSTRAINT_VERIFY=1
  1189   1190   TESTFIXTURE_FLAGS += -DSQLITE_DEFAULT_PAGE_SIZE=1024
  1190   1191   TESTFIXTURE_FLAGS += -DSQLITE_ENABLE_STMTVTAB
  1191   1192   TESTFIXTURE_FLAGS += -DSQLITE_ENABLE_DBPAGE_VTAB
         1193  +TESTFIXTURE_FLAGS += -DSQLITE_ENABLE_DESERIALIZE
  1192   1194   
  1193   1195   TESTFIXTURE_SRC0 = $(TESTSRC2) libsqlite3.la
  1194   1196   TESTFIXTURE_SRC1 = sqlite3.c
  1195   1197   TESTFIXTURE_SRC = $(TESTSRC) $(TOP)/src/tclsqlite.c
  1196   1198   TESTFIXTURE_SRC += $(TESTFIXTURE_SRC$(USE_AMALGAMATION))
  1197   1199   
  1198   1200   testfixture$(TEXE):	$(TESTFIXTURE_SRC)
................................................................................
  1286   1288   
  1287   1289   sqlite3_checker$(TEXE):	sqlite3_checker.c
  1288   1290   	$(LTLINK) sqlite3_checker.c -o $@ $(LIBTCL) $(TLIBS)
  1289   1291   
  1290   1292   dbdump$(TEXE): $(TOP)/ext/misc/dbdump.c sqlite3.lo
  1291   1293   	$(LTLINK) -DDBDUMP_STANDALONE -o $@ \
  1292   1294              $(TOP)/ext/misc/dbdump.c sqlite3.lo $(TLIBS)
         1295  +
         1296  +dbtotxt$(TEXE): $(TOP)/tool/dbtotxt.c
         1297  +	$(LTLINK)-o $@ $(TOP)/tool/dbtotxt.c
  1293   1298   
  1294   1299   showdb$(TEXE):	$(TOP)/tool/showdb.c sqlite3.lo
  1295   1300   	$(LTLINK) -o $@ $(TOP)/tool/showdb.c sqlite3.lo $(TLIBS)
  1296   1301   
  1297   1302   showstat4$(TEXE):	$(TOP)/tool/showstat4.c sqlite3.lo
  1298   1303   	$(LTLINK) -o $@ $(TOP)/tool/showstat4.c sqlite3.lo $(TLIBS)
  1299   1304   

Changes to Makefile.msc.

  2294   2294   TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_SERVER=1 -DSQLITE_PRIVATE=""
  2295   2295   TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_CORE $(NO_WARN)
  2296   2296   TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_SERIES_CONSTRAINT_VERIFY=1
  2297   2297   TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_DEFAULT_PAGE_SIZE=1024
  2298   2298   TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_ENABLE_STMTVTAB=1
  2299   2299   TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_ENABLE_DBPAGE_VTAB=1
  2300   2300   TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_ENABLE_JSON1=1
         2301  +TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_ENABLE_DESERIALIZE=1
  2301   2302   TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) $(TEST_CCONV_OPTS)
  2302   2303   
  2303   2304   TESTFIXTURE_SRC0 = $(TESTEXT) $(TESTSRC2)
  2304   2305   TESTFIXTURE_SRC1 = $(TESTEXT) $(SQLITE3C)
  2305   2306   !IF $(USE_AMALGAMATION)==0
  2306   2307   TESTFIXTURE_SRC = $(TESTSRC) $(TOP)\src\tclsqlite.c $(TESTFIXTURE_SRC0)
  2307   2308   !ELSE
................................................................................
  2421   2422   
  2422   2423   testloadext.lo:	$(TOP)\src\test_loadext.c $(SQLITE3H)
  2423   2424   	$(LTCOMPILE) $(NO_WARN) -c $(TOP)\src\test_loadext.c
  2424   2425   
  2425   2426   testloadext.dll:	testloadext.lo
  2426   2427   	$(LD) $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) /DLL /OUT:$@ testloadext.lo
  2427   2428   
         2429  +dbtotxt.exe:	$(TOP)\tool\dbtotxt.c
         2430  +	$(LTLINK) $(NO_WARN)	$(TOP)\tool\dbtotxt.c /link $(LDFLAGS) $(LTLINKOPTS)
         2431  +
  2428   2432   showdb.exe:	$(TOP)\tool\showdb.c $(SQLITE3C) $(SQLITE3H)
  2429   2433   	$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \
  2430   2434   		$(TOP)\tool\showdb.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
  2431   2435   
  2432   2436   showstat4.exe:	$(TOP)\tool\showstat4.c $(SQLITE3C) $(SQLITE3H)
  2433   2437   	$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \
  2434   2438   		$(TOP)\tool\showstat4.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)

Changes to ext/fts3/fts3.c.

   334    334     }while( vu!=0 );
   335    335     q[-1] &= 0x7f;  /* turn off high bit in final byte */
   336    336     assert( q - (unsigned char *)p <= FTS3_VARINT_MAX );
   337    337     return (int) (q - (unsigned char *)p);
   338    338   }
   339    339   
   340    340   #define GETVARINT_STEP(v, ptr, shift, mask1, mask2, var, ret) \
   341         -  v = (v & mask1) | ( (*ptr++) << shift );                    \
          341  +  v = (v & mask1) | ( (*(ptr++)) << shift );  \
   342    342     if( (v & mask2)==0 ){ var = v; return ret; }
   343    343   #define GETVARINT_INIT(v, ptr, shift, mask1, mask2, var, ret) \
   344    344     v = (*ptr++);                                               \
   345    345     if( (v & mask2)==0 ){ var = v; return ret; }
   346    346   
   347    347   /* 
   348    348   ** Read a 64-bit variable-length integer from memory starting at p[0].
................................................................................
   372    372   }
   373    373   
   374    374   /*
   375    375   ** Similar to sqlite3Fts3GetVarint(), except that the output is truncated to 
   376    376   ** a non-negative 32-bit integer before it is returned.
   377    377   */
   378    378   int sqlite3Fts3GetVarint32(const char *p, int *pi){
          379  +  const unsigned char *ptr = (const unsigned char*)p;
   379    380     u32 a;
   380    381   
   381    382   #ifndef fts3GetVarint32
   382         -  GETVARINT_INIT(a, p, 0,  0x00,     0x80, *pi, 1);
          383  +  GETVARINT_INIT(a, ptr, 0,  0x00,     0x80, *pi, 1);
   383    384   #else
   384         -  a = (*p++);
          385  +  a = (*ptr++);
   385    386     assert( a & 0x80 );
   386    387   #endif
   387    388   
   388         -  GETVARINT_STEP(a, p, 7,  0x7F,     0x4000, *pi, 2);
   389         -  GETVARINT_STEP(a, p, 14, 0x3FFF,   0x200000, *pi, 3);
   390         -  GETVARINT_STEP(a, p, 21, 0x1FFFFF, 0x10000000, *pi, 4);
          389  +  GETVARINT_STEP(a, ptr, 7,  0x7F,     0x4000, *pi, 2);
          390  +  GETVARINT_STEP(a, ptr, 14, 0x3FFF,   0x200000, *pi, 3);
          391  +  GETVARINT_STEP(a, ptr, 21, 0x1FFFFF, 0x10000000, *pi, 4);
   391    392     a = (a & 0x0FFFFFFF );
   392         -  *pi = (int)(a | ((u32)(*p & 0x07) << 28));
          393  +  *pi = (int)(a | ((u32)(*ptr & 0x07) << 28));
   393    394     assert( 0==(a & 0x80000000) );
   394    395     assert( *pi>=0 );
   395    396     return 5;
   396    397   }
   397    398   
   398    399   /*
   399    400   ** Return the number of bytes required to encode v as a varint

Changes to ext/fts3/fts3_unicode2.c.

   174    174       61726, 61784, 61800, 61816, 61836, 61880, 61896, 61914, 
   175    175       61948, 61998, 62062, 62122, 62154, 62184, 62200, 62218, 
   176    176       62252, 62302, 62364, 62410, 62442, 62478, 62536, 62554, 
   177    177       62584, 62604, 62640, 62648, 62656, 62664, 62730, 62766, 
   178    178       62830, 62890, 62924, 62974, 63032, 63050, 63082, 63118, 
   179    179       63182, 63242, 63274, 63310, 63368, 63390, 
   180    180     };
          181  +#define HIBIT ((char)0x80)
   181    182     char aChar[] = {
   182         -    '\0',      'a'|0x00,  'c'|0x00,  'e'|0x00,  'i'|0x00,  'n'|0x00,  
   183         -    'o'|0x00,  'u'|0x00,  'y'|0x00,  'y'|0x00,  'a'|0x00,  'c'|0x00,  
   184         -    'd'|0x00,  'e'|0x00,  'e'|0x00,  'g'|0x00,  'h'|0x00,  'i'|0x00,  
   185         -    'j'|0x00,  'k'|0x00,  'l'|0x00,  'n'|0x00,  'o'|0x00,  'r'|0x00,  
   186         -    's'|0x00,  't'|0x00,  'u'|0x00,  'u'|0x00,  'w'|0x00,  'y'|0x00,  
   187         -    'z'|0x00,  'o'|0x00,  'u'|0x00,  'a'|0x00,  'i'|0x00,  'o'|0x00,  
   188         -    'u'|0x00,  'u'|0x80,  'a'|0x80,  'g'|0x00,  'k'|0x00,  'o'|0x00,  
   189         -    'o'|0x80,  'j'|0x00,  'g'|0x00,  'n'|0x00,  'a'|0x80,  'a'|0x00,  
   190         -    'e'|0x00,  'i'|0x00,  'o'|0x00,  'r'|0x00,  'u'|0x00,  's'|0x00,  
   191         -    't'|0x00,  'h'|0x00,  'a'|0x00,  'e'|0x00,  'o'|0x80,  'o'|0x00,  
   192         -    'o'|0x80,  'y'|0x00,  '\0',      '\0',      '\0',      '\0',      
   193         -    '\0',      '\0',      '\0',      '\0',      'a'|0x00,  'b'|0x00,  
   194         -    'c'|0x80,  'd'|0x00,  'd'|0x00,  'e'|0x80,  'e'|0x00,  'e'|0x80,  
   195         -    'f'|0x00,  'g'|0x00,  'h'|0x00,  'h'|0x00,  'i'|0x00,  'i'|0x80,  
   196         -    'k'|0x00,  'l'|0x00,  'l'|0x80,  'l'|0x00,  'm'|0x00,  'n'|0x00,  
   197         -    'o'|0x80,  'p'|0x00,  'r'|0x00,  'r'|0x80,  'r'|0x00,  's'|0x00,  
   198         -    's'|0x80,  't'|0x00,  'u'|0x00,  'u'|0x80,  'v'|0x00,  'w'|0x00,  
   199         -    'w'|0x00,  'x'|0x00,  'y'|0x00,  'z'|0x00,  'h'|0x00,  't'|0x00,  
   200         -    'w'|0x00,  'y'|0x00,  'a'|0x00,  'a'|0x80,  'a'|0x80,  'a'|0x80,  
   201         -    'e'|0x00,  'e'|0x80,  'e'|0x80,  'i'|0x00,  'o'|0x00,  'o'|0x80,  
   202         -    'o'|0x80,  'o'|0x80,  'u'|0x00,  'u'|0x80,  'u'|0x80,  'y'|0x00,  
          183  +    '\0',      'a',       'c',       'e',       'i',       'n',       
          184  +    'o',       'u',       'y',       'y',       'a',       'c',       
          185  +    'd',       'e',       'e',       'g',       'h',       'i',       
          186  +    'j',       'k',       'l',       'n',       'o',       'r',       
          187  +    's',       't',       'u',       'u',       'w',       'y',       
          188  +    'z',       'o',       'u',       'a',       'i',       'o',       
          189  +    'u',       'u'|HIBIT, 'a'|HIBIT, 'g',       'k',       'o',       
          190  +    'o'|HIBIT, 'j',       'g',       'n',       'a'|HIBIT, 'a',       
          191  +    'e',       'i',       'o',       'r',       'u',       's',       
          192  +    't',       'h',       'a',       'e',       'o'|HIBIT, 'o',       
          193  +    'o'|HIBIT, 'y',       '\0',      '\0',      '\0',      '\0',      
          194  +    '\0',      '\0',      '\0',      '\0',      'a',       'b',       
          195  +    'c'|HIBIT, 'd',       'd',       'e'|HIBIT, 'e',       'e'|HIBIT, 
          196  +    'f',       'g',       'h',       'h',       'i',       'i'|HIBIT, 
          197  +    'k',       'l',       'l'|HIBIT, 'l',       'm',       'n',       
          198  +    'o'|HIBIT, 'p',       'r',       'r'|HIBIT, 'r',       's',       
          199  +    's'|HIBIT, 't',       'u',       'u'|HIBIT, 'v',       'w',       
          200  +    'w',       'x',       'y',       'z',       'h',       't',       
          201  +    'w',       'y',       'a',       'a'|HIBIT, 'a'|HIBIT, 'a'|HIBIT, 
          202  +    'e',       'e'|HIBIT, 'e'|HIBIT, 'i',       'o',       'o'|HIBIT, 
          203  +    'o'|HIBIT, 'o'|HIBIT, 'u',       'u'|HIBIT, 'u'|HIBIT, 'y',  
   203    204     };
   204    205   
   205    206     unsigned int key = (((unsigned int)c)<<3) | 0x00000007;
   206    207     int iRes = 0;
   207    208     int iHi = sizeof(aDia)/sizeof(aDia[0]) - 1;
   208    209     int iLo = 0;
   209    210     while( iHi>=iLo ){

Changes to ext/fts3/fts3_write.c.

   392    392     sqlite3_stmt *pStmt;
   393    393   
   394    394     assert( SizeofArray(azSql)==SizeofArray(p->aStmt) );
   395    395     assert( eStmt<SizeofArray(azSql) && eStmt>=0 );
   396    396     
   397    397     pStmt = p->aStmt[eStmt];
   398    398     if( !pStmt ){
          399  +    int f = SQLITE_PREPARE_PERSISTENT|SQLITE_PREPARE_NO_VTAB;
   399    400       char *zSql;
   400    401       if( eStmt==SQL_CONTENT_INSERT ){
   401    402         zSql = sqlite3_mprintf(azSql[eStmt], p->zDb, p->zName, p->zWriteExprlist);
   402    403       }else if( eStmt==SQL_SELECT_CONTENT_BY_ROWID ){
          404  +      f &= ~SQLITE_PREPARE_NO_VTAB;
   403    405         zSql = sqlite3_mprintf(azSql[eStmt], p->zReadExprlist);
   404    406       }else{
   405    407         zSql = sqlite3_mprintf(azSql[eStmt], p->zDb, p->zName);
   406    408       }
   407    409       if( !zSql ){
   408    410         rc = SQLITE_NOMEM;
   409    411       }else{
   410         -      rc = sqlite3_prepare_v3(p->db, zSql, -1, SQLITE_PREPARE_PERSISTENT,
   411         -                              &pStmt, NULL);
          412  +      rc = sqlite3_prepare_v3(p->db, zSql, -1, f, &pStmt, NULL);
   412    413         sqlite3_free(zSql);
   413    414         assert( rc==SQLITE_OK || pStmt==0 );
   414    415         p->aStmt[eStmt] = pStmt;
   415    416       }
   416    417     }
   417    418     if( apVal ){
   418    419       int i;
................................................................................
  1404   1405     pReader->aDoclist = pNext;
  1405   1406     pReader->pOffsetList = 0;
  1406   1407   
  1407   1408     /* Check that the doclist does not appear to extend past the end of the
  1408   1409     ** b-tree node. And that the final byte of the doclist is 0x00. If either 
  1409   1410     ** of these statements is untrue, then the data structure is corrupt.
  1410   1411     */
  1411         -  if( (&pReader->aNode[pReader->nNode] - pReader->aDoclist)<pReader->nDoclist
         1412  +  if( pReader->nDoclist > pReader->nNode-(pReader->aDoclist-pReader->aNode)
  1412   1413      || (pReader->nPopulate==0 && pReader->aDoclist[pReader->nDoclist-1])
  1413   1414     ){
  1414   1415       return FTS_CORRUPT_VTAB;
  1415   1416     }
  1416   1417     return SQLITE_OK;
  1417   1418   }
  1418   1419   
................................................................................
  1604   1605     const char *zRoot,              /* Buffer containing root node */
  1605   1606     int nRoot,                      /* Size of buffer containing root node */
  1606   1607     Fts3SegReader **ppReader        /* OUT: Allocated Fts3SegReader */
  1607   1608   ){
  1608   1609     Fts3SegReader *pReader;         /* Newly allocated SegReader object */
  1609   1610     int nExtra = 0;                 /* Bytes to allocate segment root node */
  1610   1611   
  1611         -  assert( iStartLeaf<=iEndLeaf );
         1612  +  assert( zRoot!=0 || nRoot==0 );
         1613  +#ifdef CORRUPT_DB
         1614  +  assert( zRoot!=0 || CORRUPT_DB );
         1615  +#endif
         1616  +
  1612   1617     if( iStartLeaf==0 ){
  1613   1618       nExtra = nRoot + FTS3_NODE_PADDING;
  1614   1619     }
  1615   1620   
  1616   1621     pReader = (Fts3SegReader *)sqlite3_malloc(sizeof(Fts3SegReader) + nExtra);
  1617   1622     if( !pReader ){
  1618   1623       return SQLITE_NOMEM;
................................................................................
  1625   1630     pReader->iEndBlock = iEndBlock;
  1626   1631   
  1627   1632     if( nExtra ){
  1628   1633       /* The entire segment is stored in the root node. */
  1629   1634       pReader->aNode = (char *)&pReader[1];
  1630   1635       pReader->rootOnly = 1;
  1631   1636       pReader->nNode = nRoot;
  1632         -    memcpy(pReader->aNode, zRoot, nRoot);
         1637  +    if( nRoot ) memcpy(pReader->aNode, zRoot, nRoot);
  1633   1638       memset(&pReader->aNode[nRoot], 0, FTS3_NODE_PADDING);
  1634   1639     }else{
  1635   1640       pReader->iCurrentBlock = iStartLeaf-1;
  1636   1641     }
  1637   1642     *ppReader = pReader;
  1638   1643     return SQLITE_OK;
  1639   1644   }

Changes to ext/fts5/fts5.h.

   410    410   **            same token for inputs "first" and "1st". Say that token is in
   411    411   **            fact "first", so that when the user inserts the document "I won
   412    412   **            1st place" entries are added to the index for tokens "i", "won",
   413    413   **            "first" and "place". If the user then queries for '1st + place',
   414    414   **            the tokenizer substitutes "first" for "1st" and the query works
   415    415   **            as expected.
   416    416   **
   417         -**       <li> By adding multiple synonyms for a single term to the FTS index.
   418         -**            In this case, when tokenizing query text, the tokenizer may 
   419         -**            provide multiple synonyms for a single term within the document.
   420         -**            FTS5 then queries the index for each synonym individually. For
   421         -**            example, faced with the query:
          417  +**       <li> By querying the index for all synonyms of each query term
          418  +**            separately. In this case, when tokenizing query text, the
          419  +**            tokenizer may provide multiple synonyms for a single term 
          420  +**            within the document. FTS5 then queries the index for each 
          421  +**            synonym individually. For example, faced with the query:
   422    422   **
   423    423   **   <codeblock>
   424    424   **     ... MATCH 'first place'</codeblock>
   425    425   **
   426    426   **            the tokenizer offers both "1st" and "first" as synonyms for the
   427    427   **            first token in the MATCH query and FTS5 effectively runs a query 
   428    428   **            similar to:
................................................................................
   438    438   **            Using this method, when tokenizing document text, the tokenizer
   439    439   **            provides multiple synonyms for each token. So that when a 
   440    440   **            document such as "I won first place" is tokenized, entries are
   441    441   **            added to the FTS index for "i", "won", "first", "1st" and
   442    442   **            "place".
   443    443   **
   444    444   **            This way, even if the tokenizer does not provide synonyms
   445         -**            when tokenizing query text (it should not - to do would be
          445  +**            when tokenizing query text (it should not - to do so would be
   446    446   **            inefficient), it doesn't matter if the user queries for 
   447    447   **            'first + place' or '1st + place', as there are entries in the
   448    448   **            FTS index corresponding to both forms of the first token.
   449    449   **   </ol>
   450    450   **
   451    451   **   Whether it is parsing document or query text, any call to xToken that
   452    452   **   specifies a <i>tflags</i> argument with the FTS5_TOKEN_COLOCATED bit

Changes to ext/fts5/fts5_index.c.

   686    686           rc = sqlite3_blob_read(p->pReader, aOut, nByte, 0);
   687    687         }
   688    688         if( rc!=SQLITE_OK ){
   689    689           sqlite3_free(pRet);
   690    690           pRet = 0;
   691    691         }else{
   692    692           /* TODO1: Fix this */
          693  +        pRet->p[nByte] = 0x00;
   693    694           pRet->szLeaf = fts5GetU16(&pRet->p[2]);
   694    695         }
   695    696       }
   696    697       p->rc = rc;
   697    698       p->nRead++;
   698    699     }
   699    700   
................................................................................
   725    726     Fts5Index *p,
   726    727     sqlite3_stmt **ppStmt,
   727    728     char *zSql
   728    729   ){
   729    730     if( p->rc==SQLITE_OK ){
   730    731       if( zSql ){
   731    732         p->rc = sqlite3_prepare_v3(p->pConfig->db, zSql, -1,
   732         -                                 SQLITE_PREPARE_PERSISTENT, ppStmt, 0);
          733  +          SQLITE_PREPARE_PERSISTENT|SQLITE_PREPARE_NO_VTAB,
          734  +          ppStmt, 0);
   733    735       }else{
   734    736         p->rc = SQLITE_NOMEM;
   735    737       }
   736    738     }
   737    739     sqlite3_free(zSql);
   738    740     return p->rc;
   739    741   }
................................................................................
   766    768   **
   767    769   **     DELETE FROM %_data WHERE id BETWEEN $iFirst AND $iLast
   768    770   */
   769    771   static void fts5DataDelete(Fts5Index *p, i64 iFirst, i64 iLast){
   770    772     if( p->rc!=SQLITE_OK ) return;
   771    773   
   772    774     if( p->pDeleter==0 ){
   773         -    int rc;
   774    775       Fts5Config *pConfig = p->pConfig;
   775    776       char *zSql = sqlite3_mprintf(
   776    777           "DELETE FROM '%q'.'%q_data' WHERE id>=? AND id<=?", 
   777    778             pConfig->zDb, pConfig->zName
   778    779       );
   779         -    if( zSql==0 ){
   780         -      rc = SQLITE_NOMEM;
   781         -    }else{
   782         -      rc = sqlite3_prepare_v3(pConfig->db, zSql, -1,
   783         -                              SQLITE_PREPARE_PERSISTENT, &p->pDeleter, 0);
   784         -      sqlite3_free(zSql);
   785         -    }
   786         -    if( rc!=SQLITE_OK ){
   787         -      p->rc = rc;
   788         -      return;
   789         -    }
          780  +    if( fts5IndexPrepareStmt(p, &p->pDeleter, zSql) ) return;
   790    781     }
   791    782   
   792    783     sqlite3_bind_int64(p->pDeleter, 1, iFirst);
   793    784     sqlite3_bind_int64(p->pDeleter, 2, iLast);
   794    785     sqlite3_step(p->pDeleter);
   795    786     p->rc = sqlite3_reset(p->pDeleter);
   796    787   }
................................................................................
   887    878         int iSeg;
   888    879   
   889    880         if( i>=nData ){
   890    881           rc = FTS5_CORRUPT;
   891    882         }else{
   892    883           i += fts5GetVarint32(&pData[i], pLvl->nMerge);
   893    884           i += fts5GetVarint32(&pData[i], nTotal);
   894         -        assert( nTotal>=pLvl->nMerge );
          885  +        if( nTotal<pLvl->nMerge ) rc = FTS5_CORRUPT;
   895    886           pLvl->aSeg = (Fts5StructureSegment*)sqlite3Fts5MallocZero(&rc, 
   896    887               nTotal * sizeof(Fts5StructureSegment)
   897    888           );
          889  +        nSegment -= nTotal;
   898    890         }
   899    891   
   900    892         if( rc==SQLITE_OK ){
   901    893           pLvl->nSeg = nTotal;
   902    894           for(iSeg=0; iSeg<nTotal; iSeg++){
   903    895             if( i>=nData ){
   904    896               rc = FTS5_CORRUPT;
................................................................................
   906    898             }
   907    899             i += fts5GetVarint32(&pData[i], pLvl->aSeg[iSeg].iSegid);
   908    900             i += fts5GetVarint32(&pData[i], pLvl->aSeg[iSeg].pgnoFirst);
   909    901             i += fts5GetVarint32(&pData[i], pLvl->aSeg[iSeg].pgnoLast);
   910    902           }
   911    903         }
   912    904       }
          905  +    if( nSegment!=0 && rc==SQLITE_OK ) rc = FTS5_CORRUPT;
          906  +
   913    907       if( rc!=SQLITE_OK ){
   914    908         fts5StructureRelease(pRet);
   915    909         pRet = 0;
   916    910       }
   917    911     }
   918    912   
   919    913     *ppOut = pRet;
................................................................................
  1713   1707       pIter->iLeafPgno = pSeg->pgnoFirst-1;
  1714   1708       fts5SegIterNextPage(p, pIter);
  1715   1709     }
  1716   1710   
  1717   1711     if( p->rc==SQLITE_OK ){
  1718   1712       pIter->iLeafOffset = 4;
  1719   1713       assert_nc( pIter->pLeaf->nn>4 );
  1720         -    assert( fts5LeafFirstTermOff(pIter->pLeaf)==4 );
         1714  +    assert_nc( fts5LeafFirstTermOff(pIter->pLeaf)==4 );
  1721   1715       pIter->iPgidxOff = pIter->pLeaf->szLeaf+1;
  1722   1716       fts5SegIterLoadTerm(p, pIter, 0);
  1723   1717       fts5SegIterLoadNPos(p, pIter);
  1724   1718     }
  1725   1719   }
  1726   1720   
  1727   1721   /*
................................................................................
  3583   3577         mask = aUsed[i];
  3584   3578         for(iSegid=0; mask & (1 << iSegid); iSegid++);
  3585   3579         iSegid += 1 + i*32;
  3586   3580   
  3587   3581   #ifdef SQLITE_DEBUG
  3588   3582         for(iLvl=0; iLvl<pStruct->nLevel; iLvl++){
  3589   3583           for(iSeg=0; iSeg<pStruct->aLevel[iLvl].nSeg; iSeg++){
  3590         -          assert( iSegid!=pStruct->aLevel[iLvl].aSeg[iSeg].iSegid );
         3584  +          assert_nc( iSegid!=pStruct->aLevel[iLvl].aSeg[iSeg].iSegid );
  3591   3585           }
  3592   3586         }
  3593         -      assert( iSegid>0 && iSegid<=FTS5_MAX_SEGMENT );
         3587  +      assert_nc( iSegid>0 && iSegid<=FTS5_MAX_SEGMENT );
  3594   3588   
  3595   3589         {
  3596   3590           sqlite3_stmt *pIdxSelect = fts5IdxSelectStmt(p);
  3597   3591           if( p->rc==SQLITE_OK ){
  3598   3592             u8 aBlob[2] = {0xff, 0xff};
  3599   3593             sqlite3_bind_int(pIdxSelect, 1, iSegid);
  3600   3594             sqlite3_bind_blob(pIdxSelect, 2, aBlob, 2, SQLITE_STATIC);
  3601         -          assert( sqlite3_step(pIdxSelect)!=SQLITE_ROW );
         3595  +          assert_nc( sqlite3_step(pIdxSelect)!=SQLITE_ROW );
  3602   3596             p->rc = sqlite3_reset(pIdxSelect);
  3603   3597             sqlite3_bind_null(pIdxSelect, 2);
  3604   3598           }
  3605   3599         }
  3606   3600   #endif
  3607   3601       }
  3608   3602     }
................................................................................
  5860   5854         int iOff;                   /* Offset of first term on leaf */
  5861   5855         int iRowidOff;              /* Offset of first rowid on leaf */
  5862   5856         int nTerm;                  /* Size of term on leaf in bytes */
  5863   5857         int res;                    /* Comparison of term and split-key */
  5864   5858   
  5865   5859         iOff = fts5LeafFirstTermOff(pLeaf);
  5866   5860         iRowidOff = fts5LeafFirstRowidOff(pLeaf);
  5867         -      if( iRowidOff>=iOff ){
         5861  +      if( iRowidOff>=iOff || iOff>=pLeaf->szLeaf ){
  5868   5862           p->rc = FTS5_CORRUPT;
  5869   5863         }else{
  5870   5864           iOff += fts5GetVarint32(&pLeaf->p[iOff], nTerm);
  5871   5865           res = memcmp(&pLeaf->p[iOff], zIdxTerm, MIN(nTerm, nIdxTerm));
  5872   5866           if( res==0 ) res = nTerm - nIdxTerm;
  5873   5867           if( res<0 ) p->rc = FTS5_CORRUPT;
  5874   5868         }

Changes to ext/fts5/fts5_storage.c.

   132    132           zSql = sqlite3_mprintf(azStmt[eStmt], pC->zDb, pC->zName);
   133    133           break;
   134    134       }
   135    135   
   136    136       if( zSql==0 ){
   137    137         rc = SQLITE_NOMEM;
   138    138       }else{
   139         -      rc = sqlite3_prepare_v3(pC->db, zSql, -1,
   140         -                              SQLITE_PREPARE_PERSISTENT, &p->aStmt[eStmt], 0);
          139  +      int f = SQLITE_PREPARE_PERSISTENT;
          140  +      if( eStmt>FTS5_STMT_LOOKUP ) f |= SQLITE_PREPARE_NO_VTAB;
          141  +      rc = sqlite3_prepare_v3(pC->db, zSql, -1, f, &p->aStmt[eStmt], 0);
   141    142         sqlite3_free(zSql);
   142    143         if( rc!=SQLITE_OK && pzErrMsg ){
   143    144           *pzErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(pC->db));
   144    145         }
   145    146       }
   146    147     }
   147    148   

Changes to ext/fts5/fts5_unicode2.c.

    43     43       61726, 61784, 61800, 61816, 61836, 61880, 61896, 61914, 
    44     44       61948, 61998, 62062, 62122, 62154, 62184, 62200, 62218, 
    45     45       62252, 62302, 62364, 62410, 62442, 62478, 62536, 62554, 
    46     46       62584, 62604, 62640, 62648, 62656, 62664, 62730, 62766, 
    47     47       62830, 62890, 62924, 62974, 63032, 63050, 63082, 63118, 
    48     48       63182, 63242, 63274, 63310, 63368, 63390, 
    49     49     };
           50  +#define HIBIT ((char)0x80)
    50     51     char aChar[] = {
    51         -    '\0',      'a'|0x00,  'c'|0x00,  'e'|0x00,  'i'|0x00,  'n'|0x00,  
    52         -    'o'|0x00,  'u'|0x00,  'y'|0x00,  'y'|0x00,  'a'|0x00,  'c'|0x00,  
    53         -    'd'|0x00,  'e'|0x00,  'e'|0x00,  'g'|0x00,  'h'|0x00,  'i'|0x00,  
    54         -    'j'|0x00,  'k'|0x00,  'l'|0x00,  'n'|0x00,  'o'|0x00,  'r'|0x00,  
    55         -    's'|0x00,  't'|0x00,  'u'|0x00,  'u'|0x00,  'w'|0x00,  'y'|0x00,  
    56         -    'z'|0x00,  'o'|0x00,  'u'|0x00,  'a'|0x00,  'i'|0x00,  'o'|0x00,  
    57         -    'u'|0x00,  'u'|0x80,  'a'|0x80,  'g'|0x00,  'k'|0x00,  'o'|0x00,  
    58         -    'o'|0x80,  'j'|0x00,  'g'|0x00,  'n'|0x00,  'a'|0x80,  'a'|0x00,  
    59         -    'e'|0x00,  'i'|0x00,  'o'|0x00,  'r'|0x00,  'u'|0x00,  's'|0x00,  
    60         -    't'|0x00,  'h'|0x00,  'a'|0x00,  'e'|0x00,  'o'|0x80,  'o'|0x00,  
    61         -    'o'|0x80,  'y'|0x00,  '\0',      '\0',      '\0',      '\0',      
    62         -    '\0',      '\0',      '\0',      '\0',      'a'|0x00,  'b'|0x00,  
    63         -    'c'|0x80,  'd'|0x00,  'd'|0x00,  'e'|0x80,  'e'|0x00,  'e'|0x80,  
    64         -    'f'|0x00,  'g'|0x00,  'h'|0x00,  'h'|0x00,  'i'|0x00,  'i'|0x80,  
    65         -    'k'|0x00,  'l'|0x00,  'l'|0x80,  'l'|0x00,  'm'|0x00,  'n'|0x00,  
    66         -    'o'|0x80,  'p'|0x00,  'r'|0x00,  'r'|0x80,  'r'|0x00,  's'|0x00,  
    67         -    's'|0x80,  't'|0x00,  'u'|0x00,  'u'|0x80,  'v'|0x00,  'w'|0x00,  
    68         -    'w'|0x00,  'x'|0x00,  'y'|0x00,  'z'|0x00,  'h'|0x00,  't'|0x00,  
    69         -    'w'|0x00,  'y'|0x00,  'a'|0x00,  'a'|0x80,  'a'|0x80,  'a'|0x80,  
    70         -    'e'|0x00,  'e'|0x80,  'e'|0x80,  'i'|0x00,  'o'|0x00,  'o'|0x80,  
    71         -    'o'|0x80,  'o'|0x80,  'u'|0x00,  'u'|0x80,  'u'|0x80,  'y'|0x00,  
           52  +    '\0',      'a',       'c',       'e',       'i',       'n',       
           53  +    'o',       'u',       'y',       'y',       'a',       'c',       
           54  +    'd',       'e',       'e',       'g',       'h',       'i',       
           55  +    'j',       'k',       'l',       'n',       'o',       'r',       
           56  +    's',       't',       'u',       'u',       'w',       'y',       
           57  +    'z',       'o',       'u',       'a',       'i',       'o',       
           58  +    'u',       'u'|HIBIT, 'a'|HIBIT, 'g',       'k',       'o',       
           59  +    'o'|HIBIT, 'j',       'g',       'n',       'a'|HIBIT, 'a',       
           60  +    'e',       'i',       'o',       'r',       'u',       's',       
           61  +    't',       'h',       'a',       'e',       'o'|HIBIT, 'o',       
           62  +    'o'|HIBIT, 'y',       '\0',      '\0',      '\0',      '\0',      
           63  +    '\0',      '\0',      '\0',      '\0',      'a',       'b',       
           64  +    'c'|HIBIT, 'd',       'd',       'e'|HIBIT, 'e',       'e'|HIBIT, 
           65  +    'f',       'g',       'h',       'h',       'i',       'i'|HIBIT, 
           66  +    'k',       'l',       'l'|HIBIT, 'l',       'm',       'n',       
           67  +    'o'|HIBIT, 'p',       'r',       'r'|HIBIT, 'r',       's',       
           68  +    's'|HIBIT, 't',       'u',       'u'|HIBIT, 'v',       'w',       
           69  +    'w',       'x',       'y',       'z',       'h',       't',       
           70  +    'w',       'y',       'a',       'a'|HIBIT, 'a'|HIBIT, 'a'|HIBIT, 
           71  +    'e',       'e'|HIBIT, 'e'|HIBIT, 'i',       'o',       'o'|HIBIT, 
           72  +    'o'|HIBIT, 'o'|HIBIT, 'u',       'u'|HIBIT, 'u'|HIBIT, 'y',  
    72     73     };
    73     74   
    74     75     unsigned int key = (((unsigned int)c)<<3) | 0x00000007;
    75     76     int iRes = 0;
    76     77     int iHi = sizeof(aDia)/sizeof(aDia[0]) - 1;
    77     78     int iLo = 0;
    78     79     while( iHi>=iLo ){

Changes to ext/fts5/test/fts5aa.test.

    34     34     t1_docsize {CREATE TABLE 't1_docsize'(id INTEGER PRIMARY KEY, sz BLOB)}
    35     35     t1_config {CREATE TABLE 't1_config'(k PRIMARY KEY, v) WITHOUT ROWID}
    36     36   }
    37     37   
    38     38   do_execsql_test 1.1 {
    39     39     DROP TABLE t1;
    40     40     SELECT name, sql FROM sqlite_master;
    41         -} {
    42         -}
           41  +} {}
    43     42   
    44     43   #-------------------------------------------------------------------------
    45     44   #
    46     45   
    47     46   do_execsql_test 2.0 {
    48     47     CREATE VIRTUAL TABLE t1 USING fts5(x, y, detail=%DETAIL%);
    49     48   }

Added ext/fts5/test/fts5circref.test.

            1  +# 2018 Dec 22
            2  +#
            3  +# The author disclaims copyright to this source code.  In place of
            4  +# a legal notice, here is a blessing:
            5  +#
            6  +#    May you do good and not evil.
            7  +#    May you find forgiveness for yourself and forgive others.
            8  +#    May you share freely, never taking more than you give.
            9  +#
           10  +#*************************************************************************
           11  +# This file implements regression tests for SQLite library.  The
           12  +# focus of this script is testing the FTS5 module.
           13  +#
           14  +
           15  +source [file join [file dirname [info script]] fts5_common.tcl]
           16  +set testprefix fts5circref
           17  +
           18  +# If SQLITE_ENABLE_FTS5 is not defined, omit this file.
           19  +ifcapable !fts5 {
           20  +  finish_test
           21  +  return
           22  +}
           23  +
           24  +do_execsql_test 1.0 {
           25  +  CREATE VIRTUAL TABLE tt USING fts5(a);
           26  +  SELECT name FROM sqlite_master ORDER BY 1;
           27  +} {
           28  +  tt tt_config tt_content tt_data tt_docsize tt_idx
           29  +}
           30  +db_save_and_close
           31  +
           32  +foreach {tn schema sql} {
           33  +  1 {
           34  +    CREATE TRIGGER tr1 AFTER INSERT ON tt_config BEGIN
           35  +      SELECT * FROM tt;
           36  +    END;
           37  +  } {
           38  +    INSERT INTO tt(tt, rank) VALUES('usermerge', 4);
           39  +  }
           40  +
           41  +  2 {
           42  +    CREATE TRIGGER tr1 AFTER INSERT ON tt_docsize BEGIN
           43  +      SELECT * FROM tt;
           44  +    END;
           45  +  } {
           46  +    INSERT INTO tt(a) VALUES('one two three');
           47  +  }
           48  +
           49  +  3 {
           50  +    CREATE TRIGGER tr1 AFTER INSERT ON tt_content BEGIN
           51  +      SELECT * FROM tt;
           52  +    END;
           53  +  } {
           54  +    INSERT INTO tt(a) VALUES('one two three');
           55  +  }
           56  +
           57  +  4 {
           58  +    CREATE TRIGGER tr1 AFTER INSERT ON tt_data BEGIN
           59  +      SELECT * FROM tt;
           60  +    END;
           61  +  } {
           62  +    INSERT INTO tt(a) VALUES('one two three');
           63  +  }
           64  +
           65  +  5 {
           66  +    CREATE TRIGGER tr1 AFTER INSERT ON tt_idx BEGIN
           67  +      SELECT * FROM tt;
           68  +    END;
           69  +  } {
           70  +    INSERT INTO tt(a) VALUES('one two three');
           71  +  }
           72  +} {
           73  +  db_restore_and_reopen
           74  +  do_execsql_test 1.1.$tn.1 $schema
           75  +  do_catchsql_test 1.1.$tn.2 $sql {1 {SQL logic error}}
           76  +  db close
           77  +}
           78  +
           79  +
           80  +finish_test

Changes to ext/fts5/test/fts5corrupt3.test.

   412    412     append blob "450108"      ;# first segment
   413    413     execsql "REPLACE INTO t1_data VALUES(10, X'$blob')"
   414    414   } {}
   415    415   do_catchsql_test 9.2.2 {
   416    416     SELECT * FROM t1('one AND two');
   417    417   } {1 {database disk image is malformed}}
   418    418   
          419  +#-------------------------------------------------------------------------
          420  +reset_db
          421  +do_test 10.0 {
          422  +  sqlite3 db {}
          423  +  db deserialize [decode_hexdb {
          424  +| size 32768 pagesize 4096 filename c9.db
          425  +| page 1 offset 0
          426  +|      0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00   SQLite format 3.
          427  +|     16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 07   .....@  ........
          428  +|     32: 00 00 00 00 00 00 00 00 00 00 00 07 00 00 00 04   ................
          429  +|     48: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00   ................
          430  +|     96: 00 00 00 00 0d 00 00 00 07 0d d2 00 0f c4 0f 6d   ...............m
          431  +|    112: 0f 02 0e ab 0e 4e 0d f6 0d d2 00 00 00 00 00 00   .....N..........
          432  +|   3536: 00 00 22 07 06 17 11 11 01 31 74 61 62 6c 65 74   .........1tablet
          433  +|   3552: 32 74 32 07 43 52 45 41 54 45 20 54 41 42 4c 45   2t2.CREATE TABLE
          434  +|   3568: 20 74 32 28 78 29 56 06 06 17 1f 1f 01 7d 74 61    t2(x)V.......ta
          435  +|   3584: 62 6c 65 74 31 5f 63 6f 6e 66 69 67 74 31 5f 63   blet1_configt1_c
          436  +|   3600: 6f 6e 66 69 67 06 43 52 45 41 54 45 20 54 41 42   onfig.CREATE TAB
          437  +|   3616: 4c 45 20 27 74 31 5f 63 6f 6e 66 69 67 27 28 6b   LE 't1_config'(k
          438  +|   3632: 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 76 29    PRIMARY KEY, v)
          439  +|   3648: 20 57 49 54 48 4f 55 54 20 52 4f 57 49 44 5b 05    WITHOUT ROWID[.
          440  +|   3664: 07 17 21 21 01 81 01 74 61 62 6c 65 74 31 5f 64   ..!!...tablet1_d
          441  +|   3680: 6f 63 73 69 7a 65 74 31 5f 64 6f 63 73 69 7a 65   ocsizet1_docsize
          442  +|   3696: 05 43 52 45 41 54 45 20 54 41 42 4c 45 20 27 74   .CREATE TABLE 't
          443  +|   3712: 31 5f 64 6f 63 73 69 7a 65 27 28 69 64 20 49 4e   1_docsize'(id IN
          444  +|   3728: 54 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45   TEGER PRIMARY KE
          445  +|   3744: 59 2c 20 73 7a 20 42 4c 4f 42 29 55 04 06 17 21   Y, sz BLOB)U...!
          446  +|   3760: 21 01 77 74 61 62 6c 65 74 31 5f 63 6f 6e 74 65   !.wtablet1_conte
          447  +|   3776: 6e 74 74 31 5f 63 6f 6e 74 65 6e 74 04 43 52 45   ntt1_content.CRE
          448  +|   3792: 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 63 6f   ATE TABLE 't1_co
          449  +|   3808: 6e 74 65 6e 74 27 28 69 64 20 49 4e 54 45 47 45   ntent'(id INTEGE
          450  +|   3824: 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 63   R PRIMARY KEY, c
          451  +|   3840: 30 29 69 03 07 17 19 19 01 81 2d 74 61 62 6c 65   0)i.......-table
          452  +|   3856: 74 31 5f 69 64 78 74 31 5f 69 64 78 03 43 52 45   t1_idxt1_idx.CRE
          453  +|   3872: 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 69 64   ATE TABLE 't1_id
          454  +|   3888: 78 27 28 73 65 67 69 64 2c 20 74 65 72 6d 2c 20   x'(segid, term, 
          455  +|   3904: 70 67 6e 6f 2c 20 50 52 49 4d 41 52 59 20 4b 45   pgno, PRIMARY KE
          456  +|   3920: 59 28 73 65 67 69 64 2c 20 74 65 72 6d 29 29 20   Y(segid, term)) 
          457  +|   3936: 57 49 54 48 4f 55 54 20 52 4f 57 49 44 55 02 07   WITHOUT ROWIDU..
          458  +|   3952: 17 1b 1b 01 81 01 74 61 62 6c 65 74 31 5f 64 61   ......tablet1_da
          459  +|   3968: 74 61 74 31 5f 64 61 74 61 02 43 52 45 41 54 45   tat1_data.CREATE
          460  +|   3984: 20 54 41 42 4c 45 20 27 74 31 5f 64 61 74 61 27    TABLE 't1_data'
          461  +|   4000: 28 69 64 20 49 4e 54 45 47 45 52 20 50 52 49 4d   (id INTEGER PRIM
          462  +|   4016: 41 52 59 20 4b 45 59 2c 20 62 6c 6f 63 6b 20 42   ARY KEY, block B
          463  +|   4032: 4c 4f 42 29 3a 01 06 17 11 11 08 63 74 61 62 6c   LOB):......ctabl
          464  +|   4048: 65 74 31 74 31 43 52 45 41 54 45 20 56 49 52 54   et1t1CREATE VIRT
          465  +|   4064: 55 41 4c 20 54 41 42 4c 45 20 74 31 20 55 53 49   UAL TABLE t1 USI
          466  +|   4080: 4e 47 20 66 74 73 35 28 63 6f 6e 74 65 6e 74 29   NG fts5(content)
          467  +| page 2 offset 4096
          468  +|      0: 0d 00 00 00 03 0f bd 00 0f e8 0f ef 0f bd 00 00   ................
          469  +|   4016: 00 00 00 00 00 00 00 00 00 00 00 00 00 24 84 80   .............$..
          470  +|   4032: 80 80 80 01 03 00 4e 00 00 00 1e 06 30 61 62 61   ......N.....0aba
          471  +|   4048: 63 6b 01 02 02 04 02 66 74 02 06 36 b0 a0 10 21   ck.....ft..6...!
          472  +|   4064: d6 f7 07 46 96 d6 97 a6 05 01 03 00 10 03 03 0f   ...F............
          473  +|   4080: 0a 03 00 24 00 00 00 00 01 01 01 00 01 01 01 01   ...$............
          474  +| page 3 offset 8192
          475  +|      0: 0a 00 00 00 01 0f fa 00 0f fa 00 00 00 00 00 00   ................
          476  +|   4080: 00 00 00 00 00 00 00 00 00 00 05 04 09 0c 01 02   ................
          477  +| page 4 offset 12288
          478  +|      0: 0d 00 00 00 03 0f e0 00 0f f6 0f ec 0f e0 00 00   ................
          479  +|   4064: 0a 03 03 00 1b 61 62 61 6e 64 6f 6e 08 02 03 00   .....abandon....
          480  +|   4080: 17 61 62 61 66 74 08 01 03 00 17 61 62 61 63 6b   .abaft.....aback
          481  +| page 5 offset 16384
          482  +|      0: 0d 00 00 00 03 0f ee 00 0f fa 0f f4 0f ee 00 00   ................
          483  +|   4064: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 04 03   ................
          484  +|   4080: 03 00 0e 01 04 02 03 00 0e 01 04 01 03 00 0e 01   ................
          485  +| page 6 offset 20480
          486  +|      0: 0a 00 00 00 01 0f f4 00 0f f4 00 00 00 00 00 00   ................
          487  +|   4080: 00 00 00 00 0b 03 1b 01 76 65 72 73 69 6f 6e 04   ........version.
          488  +| page 7 offset 24576
          489  +|      0: 0d 00 00 00 03 0f d6 00 0f f4 0f e1 0f d6 00 00   ................
          490  +|   4048: 00 00 00 00 00 00 09 03 02 1b 72 65 62 75 69 6c   ..........rebuil
          491  +|   4064: 64 11 02 02 2b 69 6e 74 65 67 72 69 74 79 2d 63   d...+integrity-c
          492  +|   4080: 68 65 62 6c 65 74 31 74 31 43 52 45 41 54 45 20   heblet1t1CREATE 
          493  +| page 8 offset 28672
          494  +|      0: 56 49 52 54 55 41 4c 20 54 41 42 4c 45 20 74 31   VIRTUAL TABLE t1
          495  +|     16: 20 55 53 49 4e 47 20 66 74 73 35 28 63 6f 6e 74    USING fts5(cont
          496  +|     32: 65 6e 74 29 0d 00 00 00 03 0f bd 00 0f e8 0f ef   ent)............
          497  +|     48: 0f bd 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
          498  +| end c9.db
          499  +  }]
          500  +} {}
          501  +do_catchsql_test 10.1 {
          502  +  SELECT * FROM t1 WHERE t1 MATCH 'abandon';
          503  +} {1 {database disk image is malformed}}
          504  +
          505  +#-------------------------------------------------------------------------
          506  +#
          507  +reset_db
          508  +do_test 11.0 {
          509  +  sqlite3 db {}
          510  +  db deserialize [decode_hexdb {
          511  +| size 28672 pagesize 4096 filename c10b.db
          512  +| page 1 offset 0
          513  +|      0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00   SQLite format 3.
          514  +|     16: 10 00 01 01 00 40 20 20 00 00 00 01 00 00 00 07   .....@  ........
          515  +|     32: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00   ................
          516  +|     48: 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00   ................
          517  +|     80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01   ................
          518  +|     96: 00 2e 30 38 0d 00 00 00 07 0d d2 00 0f c4 0f 6d   ..08...........m
          519  +|    112: 0f 02 0e ab 0e 4e 0d f6 0d d2 00 00 00 00 00 00   .....N..........
          520  +|   3536: 00 00 22 07 06 17 11 11 01 31 74 61 62 6c 65 74   .........1tablet
          521  +|   3552: 32 74 32 07 43 52 45 41 54 45 20 54 41 42 4c 45   2t2.CREATE TABLE
          522  +|   3568: 20 74 32 28 78 29 56 06 06 17 1f 1f 01 7d 74 61    t2(x)V.......ta
          523  +|   3584: 62 6c 65 74 31 5f 63 6f 6e 66 69 67 74 31 5f 63   blet1_configt1_c
          524  +|   3600: 6f 6e 66 69 67 06 43 52 45 41 54 45 20 54 41 42   onfig.CREATE TAB
          525  +|   3616: 4c 45 20 27 74 31 5f 63 6f 6e 66 69 67 27 28 6b   LE 't1_config'(k
          526  +|   3632: 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 76 29    PRIMARY KEY, v)
          527  +|   3648: 20 57 49 54 48 4f 55 54 20 52 4f 57 49 44 5b 05    WITHOUT ROWID[.
          528  +|   3664: 07 17 21 21 01 81 01 74 61 62 6c 65 74 31 5f 64   ..!!...tablet1_d
          529  +|   3680: 6f 63 73 69 7a 65 74 31 5f 64 6f 63 73 69 7a 65   ocsizet1_docsize
          530  +|   3696: 05 43 52 45 41 54 45 20 54 41 42 4c 45 20 27 74   .CREATE TABLE 't
          531  +|   3712: 31 5f 64 6f 63 73 69 7a 65 27 28 69 64 20 49 4e   1_docsize'(id IN
          532  +|   3728: 54 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45   TEGER PRIMARY KE
          533  +|   3744: 59 2c 20 73 7a 20 42 4c 4f 42 29 55 04 06 17 21   Y, sz BLOB)U...!
          534  +|   3760: 21 01 77 74 61 62 6c 65 74 31 5f 63 6f 6e 74 65   !.wtablet1_conte
          535  +|   3776: 6e 74 74 31 5f 63 6f 6e 74 65 6e 74 04 43 52 45   ntt1_content.CRE
          536  +|   3792: 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 63 6f   ATE TABLE 't1_co
          537  +|   3808: 6e 74 65 6e 74 27 28 69 64 20 49 4e 54 45 47 45   ntent'(id INTEGE
          538  +|   3824: 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 63   R PRIMARY KEY, c
          539  +|   3840: 30 29 69 03 07 17 19 19 01 81 2d 74 61 62 6c 65   0)i.......-table
          540  +|   3856: 74 31 5f 69 64 78 74 31 5f 69 64 78 03 43 52 45   t1_idxt1_idx.CRE
          541  +|   3872: 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 69 64   ATE TABLE 't1_id
          542  +|   3888: 78 27 28 73 65 67 69 64 2c 20 74 65 72 6d 2c 20   x'(segid, term, 
          543  +|   3904: 70 67 6e 6f 2c 20 50 52 49 4d 41 52 59 20 4b 45   pgno, PRIMARY KE
          544  +|   3920: 59 28 73 65 67 69 64 2c 20 74 65 72 6d 29 29 20   Y(segid, term)) 
          545  +|   3936: 57 49 54 48 4f 55 54 20 52 4f 57 49 44 55 02 07   WITHOUT ROWIDU..
          546  +|   3952: 17 1b 1b 01 81 01 74 61 62 6c 65 74 31 5f 64 61   ......tablet1_da
          547  +|   3968: 74 61 74 31 5f 64 61 74 61 02 43 52 45 41 54 45   tat1_data.CREATE
          548  +|   3984: 20 54 41 42 4c 45 20 27 74 31 5f 64 61 74 61 27    TABLE 't1_data'
          549  +|   4000: 28 69 64 20 49 4e 54 45 47 45 52 20 50 52 44 d9   (id INTEGER PRD.
          550  +|   4016: 41 52 59 20 4b 45 59 2c 20 62 6c 6f 63 6b 20 42   ARY KEY, block B
          551  +|   4032: 4c 4f 42 29 3a 01 06 17 11 11 08 63 74 61 62 6c   LOB):......ctabl
          552  +|   4048: 65 74 31 74 31 43 52 45 41 54 45 20 56 49 52 54   et1t1CREATE VIRT
          553  +|   4064: 55 41 4c 20 54 41 42 4c 45 20 74 31 20 55 53 49   UAL TABLE t1 USI
          554  +|   4080: 4e 47 20 66 74 73 35 28 63 6f 6e 74 65 6e 74 29   NG fts5(content)
          555  +| page 2 offset 4096
          556  +|      0: 0d 00 00 00 06 0f 59 00 0f e8 0f ef 0f bd 0f b0   ......Y.........
          557  +|     16: 0f 73 0f 59 00 00 00 00 00 00 00 00 00 00 00 00   .s.Y............
          558  +|   3920: 00 00 00 00 00 00 00 00 00 13 84 80 80 80 80 04   ................
          559  +|   3936: 03 01 2a 0a 00 00 00 00 01 02 02 00 02 01 01 01   ..*.............
          560  +|   3952: 02 01 01 36 84 80 80 80 80 03 03 05 66 00 40 00   ...6........f.@.
          561  +|   3968: 00 00 01 00 00 00 29 07 30 61 63 74 69 76 65 04   ......).0active.
          562  +|   3984: 02 02 02 03 74 6f 6d 06 02 02 05 02 69 63 07 02   ....tom.....ic..
          563  +|   4000: 02 01 06 62 6f 6f 6d 65 72 05 02 02 04 0b 08 07   ...boomer.......
          564  +|   4016: 06 84 80 80 80 80 02 03 01 10 01 07 07 24 84 80   .............$..
          565  +|   4032: 80 80 80 01 03 00 4e 00 00 00 1e 06 30 61 62 61   ......N.....0aba
          566  +|   4048: 63 6b 01 02 02 04 02 66 74 02 02 02 04 04 6e 64   ck.....ft.....nd
          567  +|   4064: 6f 6e 03 02 02 04 0a 07 05 01 03 00 10 03 03 0f   on..............
          568  +|   4080: 0a 03 00 24 00 00 00 00 01 01 01 00 01 01 01 01   ...$............
          569  +| page 3 offset 8192
          570  +|      0: 0a 00 00 00 02 0f f3 00 0f fa 0f f3 00 00 00 00   ................
          571  +|   4080: 00 00 00 06 04 01 0c 01 02 02 05 04 09 0c 01 02   ................
          572  +| page 4 offset 12288
          573  +|      0: 0d 00 00 00 07 0f b6 00 0f f6 0f ec 0f e0 0f d5   ................
          574  +|     16: 0f ca 0f c1 0f b6 00 00 00 00 00 00 00 00 00 00   ................
          575  +|   4016: 00 00 00 00 00 00 09 07 03 00 19 61 74 6f 6d 69   ...........atomi
          576  +|   4032: 63 07 06 03 00 15 61 74 6f 6d 09 05 03 00 19 62   c.....atom.....b
          577  +|   4048: 6f 6f 6d 65 72 09 04 03 00 19 61 63 74 69 76 65   oomer.....active
          578  +|   4064: 0a 03 03 00 1b 61 62 61 6e 64 6f 6e 08 02 03 00   .....abandon....
          579  +|   4080: 17 61 62 61 66 74 08 01 03 00 17 61 62 61 63 6b   .abaft.....aback
          580  +| page 5 offset 16384
          581  +|      0: 0d 00 00 00 07 0f d6 00 0f fa 0f f4 0f ee 0f e8   ................
          582  +|     16: 0f e2 0f dc 0f d6 00 00 00 00 00 00 00 00 00 00   ................
          583  +|   4048: 00 00 00 00 00 00 04 07 03 00 0e 01 04 06 03 00   ................
          584  +|   4064: 0e 01 04 05 03 00 0e 01 04 04 03 00 0e 01 04 03   ................
          585  +|   4080: 03 00 0e 01 04 02 03 00 0e 01 04 01 03 00 0e 01   ................
          586  +| page 6 offset 20480
          587  +|      0: 0a 00 00 00 01 0f f4 00 0f f4 00 00 00 00 00 00   ................
          588  +|   4080: 00 00 00 00 0b 03 1b 01 76 65 72 73 69 6f 6e 04   ........version.
          589  +| page 7 offset 24576
          590  +|      0: 0d 00 00 00 03 0f d6 00 0f f4 0f e1 0f d6 00 00   ................
          591  +|   4048: 00 00 00 00 00 00 09 03 02 1b 72 65 62 75 69 6c   ..........rebuil
          592  +|   4064: 64 11 02 02 2b 69 6e 74 65 67 72 69 74 79 2d 63   d...+integrity-c
          593  +|   4080: 68 65 63 6b 0a 01 02 1d 6f 70 74 69 6d 69 7a 65   heck....optimize
          594  +| end c10b.db
          595  +}]} {}
          596  +
          597  +# This returns SQLITE_CONSTRAINT instead of SQLITE_CORRUPT. The problem is
          598  +# that the corrupted structure-record leads fts5 to try to use a segment-id
          599  +# that is already in use. This is caught by the PRIMARY KEY constraint on
          600  +# the %_idx table.
          601  +#
          602  +do_catchsql_test 11.1 {
          603  +  UPDATE t1 SET content='abc' WHERE content='boomer';
          604  +} {1 {constraint failed}}
          605  +
          606  +#-------------------------------------------------------------------------
          607  +#
          608  +reset_db
          609  +do_test 12.0 {
          610  +  sqlite3 db {}
          611  +  db deserialize [decode_hexdb {
          612  +| size 28672 pagesize 4096 filename c2.db
          613  +| page 1 offset 0
          614  +|      0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00   SQLite format 3.
          615  +|     16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 07   .....@  ........
          616  +|     32: 00 00 00 00 00 00 00 00 00 00 00 07 00 00 00 00   ................
          617  +|     48: 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00   ................
          618  +|     96: 00 00 00 00 0d 00 00 00 07 0d d2 00 0f c4 0f 6d   ...............m
          619  +|    112: 0f 02 0e ab 0e 4e 0d f6 0d d2 00 00 00 00 00 00   .....N..........
          620  +|   3536: 00 00 22 07 06 17 11 11 01 31 74 61 62 6c 65 74   .........1tablet
          621  +|   3552: 32 74 32 07 43 52 45 41 54 45 20 54 41 42 4c 45   2t2.CREATE TABLE
          622  +|   3568: 20 74 32 28 78 29 56 06 06 17 1f 1f 01 7d 74 61    t2(x)V.......ta
          623  +|   3584: 62 6c 65 74 31 5f 63 6f 6e 66 69 67 74 31 5f 63   blet1_configt1_c
          624  +|   3600: 6f 6e 66 69 67 06 43 52 45 41 54 45 20 54 41 42   onfig.CREATE TAB
          625  +|   3616: 4c 45 20 27 74 31 5f 63 6f 6e 66 69 67 27 28 6b   LE 't1_config'(k
          626  +|   3632: 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 76 29    PRIMARY KEY, v)
          627  +|   3648: 20 57 49 54 48 4f 55 54 20 52 4f 57 49 44 5b 05    WITHOUT ROWID[.
          628  +|   3664: 07 17 21 21 01 81 01 74 61 62 6c 65 74 31 5f 64   ..!!...tablet1_d
          629  +|   3680: 6f 63 73 69 7a 65 74 31 5f 64 6f 63 73 69 7a 65   ocsizet1_docsize
          630  +|   3696: 05 43 52 45 41 54 45 20 54 41 42 4c 45 20 27 74   .CREATE TABLE 't
          631  +|   3712: 31 5f 64 6f 63 73 69 7a 65 27 28 69 64 20 49 4e   1_docsize'(id IN
          632  +|   3728: 54 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45   TEGER PRIMARY KE
          633  +|   3744: 59 2c 20 73 7a 20 42 4c 4f 42 29 55 04 06 17 21   Y, sz BLOB)U...!
          634  +|   3760: 21 01 77 74 61 62 6c 65 74 31 5f 63 6f 6e 74 65   !.wtablet1_conte
          635  +|   3776: 6e 74 74 31 5f 63 6f 6e 74 65 6e 74 04 43 52 45   ntt1_content.CRE
          636  +|   3792: 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 63 6f   ATE TABLE 't1_co
          637  +|   3808: 6e 74 65 6e 74 27 28 69 64 20 49 4e 54 45 47 45   ntent'(id INTEGE
          638  +|   3824: 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 63   R PRIMARY KEY, c
          639  +|   3840: 30 29 69 03 07 17 19 19 01 81 2d 74 61 62 6c 65   0)i.......-table
          640  +|   3856: 74 31 5f 69 64 78 74 31 5f 69 64 78 03 43 52 45   t1_idxt1_idx.CRE
          641  +|   3872: 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 69 64   ATE TABLE 't1_id
          642  +|   3888: 78 27 28 73 65 67 69 64 2c 20 74 65 72 6d 2c 20   x'(segid, term, 
          643  +|   3904: 70 67 6e 6f 2c 20 50 52 49 4d 41 52 59 20 4b 45   pgno, PRIMARY KE
          644  +|   3920: 59 28 73 65 67 69 64 2c 20 74 65 72 6d 29 29 20   Y(segid, term)) 
          645  +|   3936: 57 49 54 48 4f 55 54 20 52 4f 57 49 44 55 02 07   WITHOUT ROWIDU..
          646  +|   3952: 17 1b 1b 01 81 01 74 61 62 6c 65 74 31 5f 64 61   ......tablet1_da
          647  +|   3968: 74 61 74 31 5f 64 61 74 61 02 43 52 45 41 54 45   tat1_data.CREATE
          648  +|   3984: 20 54 41 42 4c 45 20 27 74 31 5f 64 61 74 61 27    TABLE 't1_data'
          649  +|   4000: 28 69 64 20 49 4e 54 45 47 45 52 20 50 52 49 4d   (id INTEGER PRIM
          650  +|   4016: 41 52 59 20 4b 45 59 2c 20 62 6c 6f 63 6b 20 42   ARY KEY, block B
          651  +|   4032: 4c 4f 42 29 3a 01 06 17 11 11 08 63 74 61 62 6c   LOB):......ctabl
          652  +|   4048: 65 74 31 74 31 43 52 45 41 54 45 20 56 49 52 54   et1t1CREATE VIRT
          653  +|   4064: 55 41 4c 20 54 41 42 4c 45 20 74 31 20 55 53 49   UAL TABLE t1 USI
          654  +|   4080: 4e 47 20 66 74 73 35 28 63 6f 6e 74 65 6e 74 29   NG fts5(content)
          655  +| page 2 offset 4096
          656  +|      0: 0d 00 00 00 03 0f bd 00 0f d8 0f ef 0f bd 00 00   ................
          657  +|   4016: 00 00 00 00 00 00 00 00 00 00 00 00 00 24 84 80   .............$..
          658  +|   4032: 80 80 80 01 03 00 4e 00 00 00 1e 06 30 61 62 61   ......N.....0aba
          659  +|   4048: 63 6b 01 02 02 04 02 66 74 02 02 02 04 04 6e 64   ck.....ft.....nd
          660  +|   4064: 6f 6e 03 02 02 04 0a 07 05 01 03 00 10 03 03 0f   on..............
          661  +|   4080: 0a 03 00 24 00 00 00 00 01 01 01 20 01 01 01 01   ...$....... ....
          662  +| page 3 offset 8192
          663  +|      0: 0a 00 00 00 01 0f fa 00 0f fa 00 00 00 00 00 00   ................
          664  +|   4080: 00 00 00 00 00 00 00 00 00 00 05 04 09 0c 01 02   ................
          665  +| page 4 offset 12288
          666  +|      0: 0d 00 00 00 03 0f e0 00 0f f6 0f ec 0f e0 3f e0   ..............?.
          667  +|     16: a0 30 30 01 b6 16 26 16 e6 46 f6 e0 80 20 30 01   .00...&..F... 0.
          668  +|     32: 76 16 26 16 67 40 80 10 30 01 76 16 26 16 36 b0   v.&.g@..0.v.&.6.
          669  +|     48: d0 00 00 00 30 fe e0 00 ff a0 ff 40 fe 00 00 00   ....0......@....
          670  +| page 5 offset 16384
          671  +|   4064: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 04 03   ................
          672  +|   4080: 03 00 0e 01 04 02 03 00 0e 01 04 01 03 00 0e 01   ................
          673  +| page 6 offset 20480
          674  +|      0: 0a 00 00 00 01 0f f4 00 0f f4 00 00 00 00 00 00   ................
          675  +|   4080: 00 00 00 00 0b 03 1b 01 76 65 72 73 69 6f 6e 04   ........version.
          676  +| page 7 offset 24576
          677  +|      0: 0d 00 00 00 03 0f d6 00 0f f4 0f e1 0f d6 00 00   ................
          678  +|   4048: 00 00 00 00 00 00 09 03 02 1b 72 65 62 75 69 6c   ..........rebuil
          679  +|   4064: 64 11 02 02 2b 69 6e 74 65 67 72 69 74 79 2d 63   d...+integrity-c
          680  +|   4080: 68 65 63 6b 0a 01 02 1d 6f 70 74 69 6d 69 7a 65   heck....optimize
          681  +| end c2.db
          682  +}]} {}
          683  +
          684  +do_catchsql_test 11.1 {
          685  +  SELECT * FROM t1 WHERE t1 MATCH 'abandon';
          686  +} {1 {vtable constructor failed: t1}}
          687  +
          688  +do_catchsql_test 11.2 {
          689  +  INSERT INTO t1(t1, rank) VALUES('merge', 500);
          690  +} {1 {vtable constructor failed: t1}}
          691  +
          692  +#-------------------------------------------------------------------------
          693  +#
          694  +reset_db
          695  +do_test 13.0 {
          696  +  sqlite3 db {}
          697  +  db deserialize [decode_hexdb {
          698  +| size 28672 pagesize 4096 filename c13.db
          699  +| page 1 offset 0
          700  +|      0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00   SQLite format 3.
          701  +|     16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 07   .....@  ........
          702  +|     32: 00 00 00 00 00 00 00 00 00 00 00 07 00 00 00 04   ................
          703  +|     48: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00   ................
          704  +|     96: 00 00 00 00 0d 00 00 00 07 0d d2 00 0f c4 0f 6d   ...............m
          705  +|    112: 0f 02 0e ab 0e 4e 0d f6 0d d2 00 00 00 00 00 00   .....N..........
          706  +|   3536: 00 00 22 07 06 17 11 11 01 31 74 61 62 6c 65 74   .........1tablet
          707  +|   3552: 32 74 32 07 43 52 45 41 54 45 20 54 41 42 4c 45   2t2.CREATE TABLE
          708  +|   3568: 20 74 32 28 78 29 56 06 06 17 1f 1f 01 7d 74 61    t2(x)V.......ta
          709  +|   3584: 62 6c 65 74 31 5f 63 6f 6e 66 69 67 74 31 5f 63   blet1_configt1_c
          710  +|   3600: 6f 6e 66 69 67 06 43 52 45 41 54 45 20 54 41 42   onfig.CREATE TAB
          711  +|   3616: 4c 45 20 27 74 31 5f 63 6f 6e 66 69 67 27 28 6b   LE 't1_config'(k
          712  +|   3632: 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 76 29    PRIMARY KEY, v)
          713  +|   3648: 20 57 49 54 48 4f 55 54 20 52 4f 57 49 44 5b 05    WITHOUT ROWID[.
          714  +|   3664: 07 17 21 21 01 81 01 74 61 62 6c 65 74 31 5f 64   ..!!...tablet1_d
          715  +|   3680: 6f 63 73 69 7a 65 74 31 5f 64 6f 63 73 69 7a 65   ocsizet1_docsize
          716  +|   3696: 05 43 52 45 41 54 45 20 54 41 42 4c 45 20 27 74   .CREATE TABLE 't
          717  +|   3712: 31 5f 64 6f 63 73 69 7a 65 27 28 69 64 20 49 4e   1_docsize'(id IN
          718  +|   3728: 54 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45   TEGER PRIMARY KE
          719  +|   3744: 59 2c 20 73 7a 20 42 4c 4f 42 29 55 04 06 17 21   Y, sz BLOB)U...!
          720  +|   3760: 21 01 77 74 61 62 6c 65 74 31 5f 63 6f 6e 74 65   !.wtablet1_conte
          721  +|   3776: 6e 74 74 31 5f 63 6f 6e 74 65 6e 74 04 43 52 45   ntt1_content.CRE
          722  +|   3792: 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 63 6f   ATE TABLE 't1_co
          723  +|   3808: 6e 74 65 6e 74 27 28 69 64 20 49 4e 54 45 47 45   ntent'(id INTEGE
          724  +|   3824: 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 63   R PRIMARY KEY, c
          725  +|   3840: 30 29 69 03 07 17 19 19 01 81 2d 74 61 62 6c 65   0)i.......-table
          726  +|   3856: 74 31 5f 69 64 78 74 31 5f 69 64 78 03 43 52 45   t1_idxt1_idx.CRE
          727  +|   3872: 41 54 45 20 54 41 42 4c 45 20 27 74 31 4f 69 64   ATE TABLE 't1Oid
          728  +|   3888: 78 27 28 73 65 67 69 64 2c 20 74 65 72 6d 2c 20   x'(segid, term, 
          729  +|   3904: 70 67 6e 6f 2c 20 50 52 49 4d 41 52 59 20 4b 45   pgno, PRIMARY KE
          730  +|   3920: 59 28 73 65 67 69 64 2c 20 74 65 72 6d 29 29 20   Y(segid, term)) 
          731  +|   3936: 57 49 54 48 4f 55 54 20 52 4f 57 49 44 55 02 07   WITHOUT ROWIDU..
          732  +|   3952: 17 1b 1b 01 81 01 74 61 62 6c 65 74 31 5f 64 61   ......tablet1_da
          733  +|   3968: 74 61 74 31 5f 64 61 74 61 02 43 52 45 41 54 45   tat1_data.CREATE
          734  +|   3984: 20 54 41 42 4c 45 20 27 74 31 5f 64 61 74 61 27    TABLE 't1_data'
          735  +|   4000: 28 69 64 20 49 4e 54 45 47 45 52 20 50 52 49 4d   (id INTEGER PRIM
          736  +|   4016: 41 52 59 20 4b 45 59 2c 20 62 6c 6f 63 6b 20 42   ARY KEY, block B
          737  +|   4032: 4c 4f 42 29 3a 01 06 17 11 11 08 63 74 61 62 6c   LOB):......ctabl
          738  +|   4048: 65 74 31 74 31 43 52 45 41 54 45 20 56 49 52 54   et1t1CREATE VIRT
          739  +|   4064: 55 41 4c 20 54 41 42 4c 45 20 74 31 20 55 53 49   UAL TABLE t1 USI
          740  +|   4080: 4e 47 20 66 74 73 35 28 63 6f 6e 74 65 6e 74 29   NG fts5(content)
          741  +| page 2 offset 4096
          742  +|      0: 0d 00 00 00 03 0f bd 00 0f e8 0f ef 0f bd 00 00   ................
          743  +|   4016: 00 00 00 00 00 00 00 00 00 00 00 00 00 24 84 80   .............$..
          744  +|   4032: 80 80 80 01 03 00 4e 00 00 00 1e 06 30 61 62 61   ......N.....0aba
          745  +|   4048: 63 6b 01 02 02 04 02 66 74 02 02 02 04 04 6e 64   ck.....ft.....nd
          746  +|   4064: 6f 6e 03 02 02 04 0a 07 05 01 03 00 10 03 03 0f   on..............
          747  +|   4080: 0a 03 00 24 00 eb 00 00 00 01 01 01 00 01 01 01   ...$............
          748  +| page 3 offset 8192
          749  +|      0: 01 0a 00 00 00 01 0f fa 00 0f fa 00 00 00 00 00   ................
          750  +|   4080: 00 00 00 00 00 00 00 00 00 00 05 04 09 0c 01 02   ................
          751  +| page 4 offset 12288
          752  +|      0: 0d 00 00 00 03 0f e0 00 0f f6 0f ec 0f e0 00 00   ................
          753  +|   4064: 0a 03 03 00 1b 61 62 61 6e 64 6f 6e 08 02 03 00   .....abandon....
          754  +|   4080: 17 61 62 61 66 74 08 01 03 00 17 61 62 61 63 6b   .abaft.....aback
          755  +| page 5 offset 16384
          756  +|      0: 0d 00 00 00 03 0f ee 00 0f fa 0f f2 0f ee 00 00   ................
          757  +|   4064: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 04 03   ................
          758  +|   4080: 03 00 0e 01 04 02 03 00 0e 01 04 01 03 00 0e 01   ................
          759  +| page 6 offset 20480
          760  +|      0: 0a 00 00 00 01 0f f4 00 0f f4 00 00 00 00 00 00   ................
          761  +|   4080: 00 00 00 00 0b 03 1b 01 76 65 72 73 69 6f 6e 04   ........version.
          762  +| page 7 offset 24576
          763  +|      0: 0d 00 00 00 03 0f d6 00 0f f4 0f e1 0f d6 00 00   ................
          764  +|   4048: 00 00 00 00 00 00 09 03 02 1b 72 65 62 75 69 6c   ..........rebuil
          765  +|   4064: 64 11 02 02 2b 69 6e 74 65 67 72 69 74 79 2d 63   d...+integrity-c
          766  +|   4080: 68 65 63 6b 0a 01 02 1d 6f 70 74 69 6d 69 7a 65   heck....optimize
          767  +| end c13.db
          768  +SELECT * FROM t1 WHERE t1 MATCH 'abandon';
          769  +}]} {}
          770  +
          771  +do_catchsql_test 13.1 {
          772  +  SELECT * FROM t1 WHERE t1 MATCH 'abandon'; 
          773  +} {1 {vtable constructor failed: t1}}
          774  +
          775  +#-------------------------------------------------------------------------
          776  +reset_db
          777  +do_test 14.0 {
          778  +  sqlite3 db {}
          779  +  db deserialize [decode_hexdb {
          780  +| size 28672 pagesize 4096 filename c14b.db
          781  +| page 1 offset 0
          782  +|      0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00   SQLite format 3.
          783  +|     16: 10 00 01 01 00 40 20 20 00 00 00 01 00 00 00 07   .....@  ........
          784  +|     32: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00   ................
          785  +|     48: 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00   ................
          786  +|     80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01   ................
          787  +|     96: 00 2e 30 38 0d 00 00 00 07 0d d2 00 0f c4 0f 6d   ..08...........m
          788  +|    112: 0f 02 0e ab 0e 4e 0d f6 0d d2 00 00 00 00 00 00   .....N..........
          789  +|   3536: 00 00 22 07 06 17 11 11 01 31 74 61 62 6c 65 74   .........1tablet
          790  +|   3552: 32 74 32 07 43 52 45 41 54 45 20 54 41 42 4c 45   2t2.CREATE TABLE
          791  +|   3568: 20 74 32 28 78 29 56 06 06 17 1f 1f 01 7d 74 61    t2(x)V.......ta
          792  +|   3584: 62 6c 65 74 31 5f 63 6f 6e 66 69 67 74 31 5f 63   blet1_configt1_c
          793  +|   3600: 6f 6e 66 69 67 06 43 52 45 41 54 45 20 54 41 42   onfig.CREATE TAB
          794  +|   3616: 4c 45 20 27 74 31 5f 63 6f 6e 66 69 67 27 28 6b   LE 't1_config'(k
          795  +|   3632: 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 76 29    PRIMARY KEY, v)
          796  +|   3648: 20 57 49 54 48 4f 55 54 20 52 4f 57 49 44 5b 05    WITHOUT ROWID[.
          797  +|   3664: 07 17 21 21 01 81 01 74 61 62 6c 65 74 31 5f 64   ..!!...tablet1_d
          798  +|   3680: 6f 63 73 69 7a 65 74 31 5f 64 6f 63 73 69 7a 65   ocsizet1_docsize
          799  +|   3696: 05 43 52 45 41 54 45 20 54 41 42 4c 45 20 27 74   .CREATE TABLE 't
          800  +|   3712: 31 5f 64 6f 63 73 69 7a 65 27 28 69 64 20 49 4e   1_docsize'(id IN
          801  +|   3728: 54 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45   TEGER PRIMARY KE
          802  +|   3744: 59 2c 20 73 7a 20 42 4c 4f 42 29 55 04 06 17 21   Y, sz BLOB)U...!
          803  +|   3760: 21 01 77 74 61 62 6c 65 74 31 5f 63 6f 6e 74 65   !.wtablet1_conte
          804  +|   3776: 6e 74 74 31 5f 63 6f 6e 74 65 6e 74 04 43 52 45   ntt1_content.CRE
          805  +|   3792: 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 63 6f   ATE TABLE 't1_co
          806  +|   3808: 6e 74 65 6e 74 27 28 69 64 20 49 4e 54 45 47 45   ntent'(id INTEGE
          807  +|   3824: 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 63   R PRIMARY KEY, c
          808  +|   3840: 30 29 69 03 07 17 19 19 01 81 2d 74 61 62 6c 65   0)i.......-table
          809  +|   3856: 74 31 5f 69 64 78 74 31 5f 69 64 78 03 43 52 45   t1_idxt1_idx.CRE
          810  +|   3872: 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 69 64   ATE TABLE 't1_id
          811  +|   3888: 78 27 28 73 65 67 69 64 2c 20 74 65 72 6d 2c 20   x'(segid, term, 
          812  +|   3904: 70 67 6e 6f 2c 20 50 52 49 4d 41 52 59 20 4b 45   pgno, PRIMARY KE
          813  +|   3920: 59 28 73 65 67 69 64 2c 20 74 65 72 6d 29 29 20   Y(segid, term)) 
          814  +|   3936: 57 49 54 48 4f 55 54 20 52 4f 57 49 44 55 02 07   WITHOUT ROWIDU..
          815  +|   3952: 17 1b 1b 01 81 01 74 61 62 6c 65 74 31 5f 64 61   ......tablet1_da
          816  +|   3968: 74 61 74 31 5f 64 61 74 61 02 43 52 45 41 54 45   tat1_data.CREATE
          817  +|   3984: 20 54 41 42 4c 45 20 27 74 31 5f 64 61 74 61 27    TABLE 't1_data'
          818  +|   4000: 28 69 64 20 49 4e 54 45 47 45 52 20 50 52 49 4d   (id INTEGER PRIM
          819  +|   4016: 41 52 59 20 4b 45 59 2c 20 62 6c 6f 63 6b 20 42   ARY KEY, block B
          820  +|   4032: 4c 4f 42 29 3a 01 06 17 11 11 08 63 74 61 62 6c   LOB):......ctabl
          821  +|   4048: 65 74 31 74 31 43 52 45 41 54 45 20 56 49 52 54   et1t1CREATE VIRT
          822  +|   4064: 55 41 4c 20 54 41 42 4c 45 20 74 31 20 55 53 49   UAL TABLE t1 USI
          823  +|   4080: 4e 47 20 66 74 73 35 28 63 6f 6e 74 65 6e 74 29   NG fts5(content)
          824  +| page 2 offset 4096
          825  +|      0: 0d 0f ef 00 04 0f 18 00 0f e8 0f 18 0f bd 0f 2c   ...............,
          826  +|   3856: 00 00 00 00 00 00 00 00 12 0a 03 00 2a 00 00 00   ............*...
          827  +|   3872: 00 01 02 02 00 02 01 01 01 02 01 01 81 09 88 80   ................
          828  +|   3888: 80 80 80 01 04 00 82 16 00 00 00 79 06 30 61 62   ...........y.0ab
          829  +|   3904: 61 63 6b 08 02 07 04 04 6e 64 6f 6e 08 02 05 02   ack.....ndon....
          830  +|   3920: 05 63 74 69 76 65 04 02 02 04 02 0b 02 04 6c 70   .ctive........lp
          831  +|   3936: 68 61 08 04 02 0a 02 03 74 6b 6d 06 02 02 03 02   ha......tkm.....
          832  +|   3952: 6f 6d 08 02 09 05 02 69 63 07 02 02 01 06 62 61   om.....ic.....ba
          833  +|   3968: 63 6b 75 70 08 02 04 02 05 6f 6f 6d 65 72 05 02   ckup.....oomer..
          834  +|   3984: 02 01 0c 63 68 61 6e 6e 65 62 6f 6f 6d 65 72 08   ...channeboomer.
          835  +|   4000: 02 08 07 01 6c 08 02 03 01 04 74 65 73 74 08 02   ....l.....test..
          836  +|   4016: 06 04 0a 09 0d 0a 08 07 07 0b 0a 11 06 24 84 80   .............$..
          837  +|   4032: 80 80 80 01 03 00 4e 00 00 00 1e 06 30 61 62 61   ......N.....0aba
          838  +|   4048: 63 6b 01 02 02 04 02 66 74 02 02 02 04 04 6e 64   ck.....ft.....nd
          839  +|   4064: 6f 6e 03 02 02 03 9a 07 05 01 03 00 10 08 11 00   on..............
          840  +|   4080: 00 00 11 24 00 00 00 00 01 01 01 00 01 01 01 01   ...$............
          841  +| page 3 offset 8192
          842  +|      0: 0a 00 00 00 02 0f f3 00 0f fa 0f f3 00 00 00 00   ................
          843  +|   4080: 00 00 00 06 04 01 0c 01 02 02 05 04 09 0c 01 02   ................
          844  +| page 4 offset 12288
          845  +|      0: 0d 00 00 00 08 0f 6a 00 0f f6 0f ec 0f e0 0f d5   ......j.........
          846  +|     16: 0f ca 0f c1 0f b6 0f 6a 00 00 00 00 00 00 00 00   .......j........
          847  +|   3936: 00 00 00 00 00 00 00 00 00 00 4a 08 04 00 81 19   ..........J.....
          848  +|   3952: 61 6c 70 68 61 20 63 68 61 6e 6e 65 6c 20 62 61   alpha channel ba
          849  +|   3968: 63 6b 75 70 20 61 62 61 6e 64 6f 6e 20 74 65 73   ckup abandon tes
          850  +|   3984: 74 20 61 62 61 63 6b 20 63 68 61 6e 6e 65 62 6f   t aback channebo
          851  +|   4000: 6f 6d 65 72 20 61 74 6f 6d 20 61 6c 70 68 61 20   omer atom alpha 
          852  +|   4016: 61 63 74 69 76 65 09 07 03 00 19 61 74 6f 6d 69   active.....atomi
          853  +|   4032: 63 07 06 03 00 15 61 74 6b 6d 09 05 03 00 19 62   c.....atkm.....b
          854  +|   4048: 6f 6f 6d 65 72 09 04 03 00 19 61 63 74 69 76 65   oomer.....active
          855  +|   4064: 0a 03 03 00 1b 61 62 61 6e 64 6f 6e 08 02 03 00   .....abandon....
          856  +|   4080: 17 61 62 61 66 74 08 01 03 00 17 61 62 61 63 6b   .abaft.....aback
          857  +| page 5 offset 16384
          858  +|      0: 0d 00 00 00 08 0f d0 00 0f fa 0f f4 0f ee 0f e8   ................
          859  +|     16: 0f e2 0f dc 0f d6 0f d0 00 00 00 00 00 00 00 00   ................
          860  +|   4048: 04 08 03 00 0e 0a 04 07 03 00 0e 01 04 06 03 00   ................
          861  +|   4064: 0e 01 04 05 03 00 0e 01 04 04 03 00 0e 01 04 03   ................
          862  +|   4080: 03 00 0e 01 04 02 03 00 0e 01 04 01 03 00 0e 01   ................
          863  +| page 6 offset 20480
          864  +|      0: 0a 00 00 00 01 0f f4 00 0f f4 00 00 00 00 00 00   ................
          865  +|   4080: 00 00 00 00 0b 03 1b 01 76 65 72 73 69 6f 6e 04   ........version.
          866  +| page 7 offset 24576
          867  +|      0: 0d 00 00 00 03 0f d6 00 0f f4 0f e1 0f d6 00 00   ................
          868  +|   4048: 00 00 00 00 00 00 09 03 02 1b 72 65 62 75 69 6c   ..........rebuil
          869  +|   4064: 64 11 02 02 2b 69 6e 74 65 67 72 69 74 79 2d 63   d...+integrity-c
          870  +|   4080: 68 65 63 6b 0a 01 02 1d 6f 70 74 69 6d 69 7a 65   heck....optimize
          871  +| end c14b.db
          872  +}]} {}
          873  +
          874  +do_catchsql_test 14.1 {
          875  +  INSERT INTO t1(t1) VALUES('optimize');
          876  +} {1 {database disk image is malformed}}
          877  +
          878  +#---------------------------------------------------------------------------
          879  +#
          880  +reset_db
          881  +do_test 15.0 {
          882  +  sqlite3 db {}
          883  +  db deserialize [decode_hexdb {
          884  +| size 32768 pagesize 4096 filename c16.db
          885  +| page 1 offset 0
          886  +|      0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00   SQLite format 3.
          887  +|     16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 07   .....@  ........
          888  +|     32: 00 00 00 00 00 00 00 00 00 00 00 07 00 00 00 00   ................
          889  +|     48: 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00   ................
          890  +|     96: 00 00 00 00 0d 00 00 00 07 0d d2 00 0f c4 0f 6d   ...............m
          891  +|    112: 0f 02 0e ab 0e 4e 0d f6 0d d2 00 00 00 00 00 00   .....N..........
          892  +|   3536: 00 00 22 07 06 17 11 11 01 31 74 61 62 6c 65 74   .........1tablet
          893  +|   3552: 32 74 32 07 43 52 45 41 54 45 20 54 41 42 4c 45   2t2.CREATE TABLE
          894  +|   3568: 20 74 32 28 78 29 56 06 06 17 1f 1f 01 7d 74 61    t2(x)V.......ta
          895  +|   3584: 62 6c 65 74 31 5f 63 6f 6e 66 69 67 74 31 5f 63   blet1_configt1_c
          896  +|   3600: 6f 6e 66 69 67 06 43 52 45 41 54 45 20 54 41 42   onfig.CREATE TAB
          897  +|   3616: 4c 45 20 27 74 31 5f 63 6f 6e 66 69 67 27 28 6b   LE 't1_config'(k
          898  +|   3632: 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 76 29    PRIMARY KEY, v)
          899  +|   3648: 20 57 49 54 48 4f 55 54 20 52 4f 57 49 44 5b 05    WITHOUT ROWID[.
          900  +|   3664: 07 17 21 21 01 81 01 74 61 62 6c 00 0f f6 0f ec   ..!!...tabl.....
          901  +|   3680: 0f e0 73 69 7a 65 74 31 5f 64 6f 63 73 69 7a 65   ..sizet1_docsize
          902  +|   3696: 05 43 52 45 41 54 45 20 54 41 42 4c 45 20 27 74   .CREATE TABLE 't
          903  +|   3712: 31 5f 64 6f 63 73 69 7a 65 27 28 69 64 20 49 4e   1_docsize'(id IN
          904  +|   3728: 54 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45   TEGER PRIMARY KE
          905  +|   3744: 59 2c 20 73 7a 20 42 4c 4f 42 29 55 04 06 17 21   Y, sz BLOB)U...!
          906  +|   3760: 21 01 77 74 61 62 6c 65 74 31 5f 63 6f 6e 74 65   !.wtablet1_conte
          907  +|   3776: 6e 74 74 31 5f 63 6f 6e 74 65 6e 74 04 43 52 45   ntt1_content.CRE
          908  +|   3792: 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 63 6f   ATE TABLE 't1_co
          909  +|   3808: 6e 74 65 6e 74 27 28 69 64 20 49 4e 54 45 47 45   ntent'(id INTEGE
          910  +|   3824: 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 63   R PRIMARY KEY, c
          911  +|   3840: 30 29 69 03 07 17 19 19 01 81 2d 74 61 62 6c 65   0)i.......-table
          912  +|   3856: 74 31 5f 69 64 78 74 31 5f 69 64 78 03 43 52 45   t1_idxt1_idx.CRE
          913  +|   3872: 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 69 64   ATE TABLE 't1_id
          914  +|   3888: 78 27 28 73 65 67 69 64 2c 20 74 65 72 6d 2c 20   x'(segid, term, 
          915  +|   3904: 70 67 6e 6f 2c 20 50 52 49 4d 41 52 59 20 4b 45   pgno, PRIMARY KE
          916  +|   3920: 59 28 73 65 67 69 64 2c 20 74 65 72 6d 29 29 20   Y(segid, term)) 
          917  +|   3936: 57 49 54 48 4f 55 54 20 52 4f 57 49 44 55 02 07   WITHOUT ROWIDU..
          918  +|   3952: 17 1b 1b 01 81 01 74 61 62 6c 65 74 31 5f 64 61   ......tablet1_da
          919  +|   3968: 74 61 74 31 5f 64 61 74 61 02 43 52 45 41 54 45   tat1_data.CREATE
          920  +|   3984: 20 54 41 42 4c 45 20 27 74 31 5f 64 61 74 61 27    TABLE 't1_data'
          921  +|   4000: 28 69 64 20 49 4e 54 45 47 45 52 20 50 52 49 4d   (id INTEGER PRIM
          922  +|   4016: 41 52 59 20 4b 45 59 2c 20 62 6c 6f 63 6b 20 42   ARY KEY, block B
          923  +|   4032: 4c 4f 42 29 3a 01 06 17 11 11 08 63 74 61 62 6c   LOB):......ctabl
          924  +|   4048: 65 74 31 74 31 43 52 45 41 54 45 20 56 49 52 54   et1t1CREATE VIRT
          925  +|   4064: 55 41 4c 20 54 41 42 4c 45 20 74 31 20 55 53 49   UAL TABLE t1 USI
          926  +|   4080: 4e 47 20 66 74 73 35 28 63 6f 6e 74 65 6e 74 29   NG fts5(content)
          927  +| page 2 offset 4096
          928  +|      0: 0d 00 00 00 03 0f bd 00 0f e8 0f ef 0f bd 00 00   ................
          929  +|   4016: 00 00 00 00 00 00 00 00 00 00 00 00 00 24 84 80   .............$..
          930  +|   4032: 80 80 80 01 03 00 4e 00 00 00 1e 06 30 61 62 61   ......N.....0aba
          931  +|   4048: 63 6b 01 02 02 04 02 66 74 00 02 22 04 04 6e 64   ck.....ft.....nd
          932  +|   4064: 6f 6e 04 67 90 38 2a 07 05 01 03 00 10 03 03 0f   on.g.8*.........
          933  +|   4080: 0a 03 00 24 00 00 00 00 01 01 01 00 01 01 01 01   ...$............
          934  +| page 3 offset 8192
          935  +|      0: 0a 00 00 00 01 0f fa 00 0f fa 00 00 00 00 00 00   ................
          936  +|   4080: 00 00 00 00 00 00 00 00 00 00 05 04 09 0c 01 02   ................
          937  +| page 4 offset 12288
          938  +|      0: 0d 00 00 00 03 0f e0 00 0f f6 0f ec 0f e0 00 00   ................
          939  +|   4064: 0a 03 03 00 1b 61 62 61 6e 64 6f 6e 08 02 03 00   .....abandon....
          940  +|   4080: 17 61 62 61 66 74 08 01 03 00 17 61 62 61 63 6b   .abaft.....aback
          941  +| page 5 offset 16384
          942  +|      0: 0d 00 00 00 03 0f ee 00 0f fa 0f f4 0f ee 00 00   ................
          943  +|   4064: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 04 03   ................
          944  +|   4080: 03 00 0e 01 04 02 03 00 0e 01 04 01 03 00 0e 01   ................
          945  +| page 6 offset 20480
          946  +|      0: 0a 00 00 00 01 0f f4 00 0f f4 00 00 00 00 00 00   ................
          947  +|   4080: 00 00 00 00 0b 03 1b 01 76 65 72 73 69 6f 6e 04   ........version.
          948  +| page 7 offset 24576
          949  +|      0: 0d 00 00 00 03 0f d6 00 0f f4 0f e1 0f d6 00 00   ................
          950  +|   4048: 00 00 00 00 00 00 09 03 02 1b 72 65 62 75 69 6c   ..........rebuil
          951  +|   4064: 64 11 02 02 2b 69 6e 74 65 67 72 69 74 79 2d 63   d...+integrity-c
          952  +|   4080: 68 65 63 6b 0a 01 02 1d 6f 70 74 69 6d 69 7a 65   heck....optimize
          953  +| page 8 offset 28672
          954  +|      0: 03 07 17 19 19 01 81 2d 74 61 62 6c 65 74 31 5f   .......-tablet1_
          955  +|     16: 69 64 78 74 31 5f 69 64 78 03 43 52 45 41 54 45   idxt1_idx.CREATE
          956  +|     32: 20 54 41 42 4c 45 20 27 74 31 5f 66 17 42 03 30    TABLE 't1_f.B.0
          957  +|     48: 01 00 00 10 10 04 02 02 00 00 00 00 00 00 00 00   ................
          958  +|     64: 70 00 00 00 00 00 00 00 00 00 00 00 70 00 00 00   p...........p...
          959  +| end c16.db
          960  +}]} {}
          961  +
          962  +do_catchsql_test 15.1 {
          963  +  INSERT INTO t1(t1) VALUES('integrity-check');
          964  +} {1 {database disk image is malformed}}
          965  +
   419    966   sqlite3_fts5_may_be_corrupt 0
   420    967   finish_test
          968  +

Changes to ext/fts5/test/fts5vocab.test.

    75     75   } {
    76     76     0 term {} 0 {} 0
    77     77     1 col {} 0 {} 0
    78     78     2 doc {} 0 {} 0
    79     79     3 cnt {} 0 {} 0
    80     80   }
    81     81   
    82         -do_execsql_test 1.2.1 { SELECT * FROM v1 } { }
    83         -do_execsql_test 1.2.2 { SELECT * FROM v2 } { }
           82  +do_execsql_test 1.2.1 { SELECT * FROM v1 } {}
           83  +do_execsql_test 1.2.2 { SELECT * FROM v2 } {}
    84     84   
    85     85   do_execsql_test 1.3 {
    86     86     INSERT INTO t1 VALUES('x y z');
    87     87     INSERT INTO t1 VALUES('x x x');
    88     88   }
    89     89   
    90     90   do_execsql_test 1.4.1 {

Changes to ext/fts5/test/fts5vocab2.test.

    76     76     four  2 b 0
    77     77     three 2 a 0
    78     78   }
    79     79   
    80     80   do_execsql_test 1.5 {
    81     81     DELETE FROM t1;
    82     82     SELECT * FROM v1;
    83         -} {
    84         -}
           83  +} {}
    85     84   
    86     85   #-------------------------------------------------------------------------
    87     86   #
    88     87   do_execsql_test 2.0 {
    89     88     DROP TABLE IF EXISTS t1;
    90     89     DROP TABLE IF EXISTS v1;
    91     90   
................................................................................
   139    138     four  2 b {}
   140    139     three 2 a {}
   141    140   }
   142    141   
   143    142   do_execsql_test 2.5 {
   144    143     DELETE FROM t1;
   145    144     SELECT * FROM v1;
   146         -} {
   147         -}
          145  +} {}
   148    146   
   149    147   #-------------------------------------------------------------------------
   150    148   #
   151    149   do_execsql_test 3.0 {
   152    150     DROP TABLE IF EXISTS t1;
   153    151     DROP TABLE IF EXISTS v1;
   154    152   
................................................................................
   198    196     four  2 {} {}
   199    197     three 2 {} {}
   200    198   }
   201    199   
   202    200   do_execsql_test 3.5 {
   203    201     DELETE FROM t1;
   204    202     SELECT * FROM v1;
   205         -} {
   206         -}
          203  +} {}
   207    204   
   208    205   finish_test

Changes to ext/misc/csv.c.

   617    617     pNew->tstFlags = tstFlags;
   618    618   #endif
   619    619     if( bHeader!=1 ){
   620    620       pNew->iStart = 0;
   621    621     }else if( pNew->zData ){
   622    622       pNew->iStart = (int)sRdr.iIn;
   623    623     }else{
   624         -    pNew->iStart = ftell(sRdr.in);
          624  +    pNew->iStart = ftell(sRdr.in) - sRdr.nIn + sRdr.iIn;
   625    625     }
   626    626     csv_reader_reset(&sRdr);
   627    627     rc = sqlite3_declare_vtab(db, CSV_SCHEMA);
   628    628     if( rc ){
   629    629       csv_errmsg(&sRdr, "bad schema: '%s' - %s", CSV_SCHEMA, sqlite3_errmsg(db));
   630    630       goto csvtab_connect_error;
   631    631     }

Changes to ext/rtree/rtree.c.

   124    124     u8 nDim;                    /* Number of dimensions */
   125    125     u8 nDim2;                   /* Twice the number of dimensions */
   126    126     u8 eCoordType;              /* RTREE_COORD_REAL32 or RTREE_COORD_INT32 */
   127    127     u8 nBytesPerCell;           /* Bytes consumed per cell */
   128    128     u8 inWrTrans;               /* True if inside write transaction */
   129    129     u8 nAux;                    /* # of auxiliary columns in %_rowid */
   130    130     u8 nAuxNotNull;             /* Number of initial not-null aux columns */
          131  +#ifdef SQLITE_DEBUG
          132  +  u8 bCorrupt;                /* Shadow table corruption detected */
          133  +#endif
   131    134     int iDepth;                 /* Current depth of the r-tree structure */
   132    135     char *zDb;                  /* Name of database containing r-tree table */
   133    136     char *zName;                /* Name of r-tree table */ 
   134    137     u32 nBusy;                  /* Current number of users of this structure */
   135    138     i64 nRowEst;                /* Estimated number of rows in this table */
   136    139     u32 nCursor;                /* Number of open cursors */
   137    140     u32 nNodeRef;               /* Number RtreeNodes with positive nRef */
................................................................................
   183    186   # define RTREE_ZERO 0
   184    187   #else
   185    188     typedef double RtreeDValue;              /* High accuracy coordinate */
   186    189     typedef float RtreeValue;                /* Low accuracy coordinate */
   187    190   # define RTREE_ZERO 0.0
   188    191   #endif
   189    192   
          193  +/*
          194  +** Set the Rtree.bCorrupt flag
          195  +*/
          196  +#ifdef SQLITE_DEBUG
          197  +# define RTREE_IS_CORRUPT(X) ((X)->bCorrupt = 1)
          198  +#else
          199  +# define RTREE_IS_CORRUPT(X)
          200  +#endif
          201  +
   190    202   /*
   191    203   ** When doing a search of an r-tree, instances of the following structure
   192    204   ** record intermediate results from the tree walk.
   193    205   **
   194    206   ** The id is always a node-id.  For iLevel>=1 the id is the node-id of
   195    207   ** the node that the RtreeSearchPoint represents.  When iLevel==0, however,
   196    208   ** the id is of the parent node and the cell that RtreeSearchPoint
................................................................................
   549    561     p->isDirty = 1;
   550    562   }
   551    563   
   552    564   /*
   553    565   ** Given a node number iNode, return the corresponding key to use
   554    566   ** in the Rtree.aHash table.
   555    567   */
   556         -static int nodeHash(i64 iNode){
   557         -  return iNode % HASHSIZE;
          568  +static unsigned int nodeHash(i64 iNode){
          569  +  return ((unsigned)iNode) % HASHSIZE;
   558    570   }
   559    571   
   560    572   /*
   561    573   ** Search the node hash table for node iNode. If found, return a pointer
   562    574   ** to it. Otherwise, return 0.
   563    575   */
   564    576   static RtreeNode *nodeHashLookup(Rtree *pRtree, i64 iNode){
................................................................................
   618    630   static void nodeBlobReset(Rtree *pRtree){
   619    631     if( pRtree->pNodeBlob && pRtree->inWrTrans==0 && pRtree->nCursor==0 ){
   620    632       sqlite3_blob *pBlob = pRtree->pNodeBlob;
   621    633       pRtree->pNodeBlob = 0;
   622    634       sqlite3_blob_close(pBlob);
   623    635     }
   624    636   }
          637  +
          638  +/*
          639  +** Check to see if pNode is the same as pParent or any of the parents
          640  +** of pParent.
          641  +*/
          642  +static int nodeInParentChain(const RtreeNode *pNode, const RtreeNode *pParent){
          643  +  do{
          644  +    if( pNode==pParent ) return 1;
          645  +    pParent = pParent->pParent;
          646  +  }while( pParent );
          647  +  return 0;
          648  +}
   625    649   
   626    650   /*
   627    651   ** Obtain a reference to an r-tree node.
   628    652   */
   629    653   static int nodeAcquire(
   630    654     Rtree *pRtree,             /* R-tree structure */
   631    655     i64 iNode,                 /* Node number to load */
................................................................................
   637    661   
   638    662     /* Check if the requested node is already in the hash table. If so,
   639    663     ** increase its reference count and return it.
   640    664     */
   641    665     if( (pNode = nodeHashLookup(pRtree, iNode))!=0 ){
   642    666       assert( !pParent || !pNode->pParent || pNode->pParent==pParent );
   643    667       if( pParent && !pNode->pParent ){
          668  +      if( nodeInParentChain(pNode, pParent) ){
          669  +        RTREE_IS_CORRUPT(pRtree);
          670  +        return SQLITE_CORRUPT_VTAB;
          671  +      }
   644    672         pParent->nRef++;
   645    673         pNode->pParent = pParent;
   646    674       }
   647    675       pNode->nRef++;
   648    676       *ppNode = pNode;
   649    677       return SQLITE_OK;
   650    678     }
................................................................................
   667    695       sqlite3_free(zTab);
   668    696     }
   669    697     if( rc ){
   670    698       nodeBlobReset(pRtree);
   671    699       *ppNode = 0;
   672    700       /* If unable to open an sqlite3_blob on the desired row, that can only
   673    701       ** be because the shadow tables hold erroneous data. */
   674         -    if( rc==SQLITE_ERROR ) rc = SQLITE_CORRUPT_VTAB;
          702  +    if( rc==SQLITE_ERROR ){
          703  +      rc = SQLITE_CORRUPT_VTAB;
          704  +      RTREE_IS_CORRUPT(pRtree);
          705  +    }
   675    706     }else if( pRtree->iNodeSize==sqlite3_blob_bytes(pRtree->pNodeBlob) ){
   676    707       pNode = (RtreeNode *)sqlite3_malloc(sizeof(RtreeNode)+pRtree->iNodeSize);
   677    708       if( !pNode ){
   678    709         rc = SQLITE_NOMEM;
   679    710       }else{
   680    711         pNode->pParent = pParent;
   681    712         pNode->zData = (u8 *)&pNode[1];
................................................................................
   696    727     ** are the leaves, and so on. If the depth as specified on the root node
   697    728     ** is greater than RTREE_MAX_DEPTH, the r-tree structure must be corrupt.
   698    729     */
   699    730     if( pNode && iNode==1 ){
   700    731       pRtree->iDepth = readInt16(pNode->zData);
   701    732       if( pRtree->iDepth>RTREE_MAX_DEPTH ){
   702    733         rc = SQLITE_CORRUPT_VTAB;
          734  +      RTREE_IS_CORRUPT(pRtree);
   703    735       }
   704    736     }
   705    737   
   706    738     /* If no error has occurred so far, check if the "number of entries"
   707    739     ** field on the node is too large. If so, set the return code to 
   708    740     ** SQLITE_CORRUPT_VTAB.
   709    741     */
   710    742     if( pNode && rc==SQLITE_OK ){
   711    743       if( NCELL(pNode)>((pRtree->iNodeSize-4)/pRtree->nBytesPerCell) ){
   712    744         rc = SQLITE_CORRUPT_VTAB;
          745  +      RTREE_IS_CORRUPT(pRtree);
   713    746       }
   714    747     }
   715    748   
   716    749     if( rc==SQLITE_OK ){
   717    750       if( pNode!=0 ){
   718    751         nodeHashInsert(pRtree, pNode);
   719    752       }else{
   720    753         rc = SQLITE_CORRUPT_VTAB;
          754  +      RTREE_IS_CORRUPT(pRtree);
   721    755       }
   722    756       *ppNode = pNode;
   723    757     }else{
   724    758       if( pNode ){
   725    759         pRtree->nNodeRef--;
   726    760         sqlite3_free(pNode);
   727    761       }
................................................................................
   939    973   */
   940    974   static void rtreeRelease(Rtree *pRtree){
   941    975     pRtree->nBusy--;
   942    976     if( pRtree->nBusy==0 ){
   943    977       pRtree->inWrTrans = 0;
   944    978       assert( pRtree->nCursor==0 );
   945    979       nodeBlobReset(pRtree);
   946         -    assert( pRtree->nNodeRef==0 );
          980  +    assert( pRtree->nNodeRef==0 || pRtree->bCorrupt );
   947    981       sqlite3_finalize(pRtree->pWriteNode);
   948    982       sqlite3_finalize(pRtree->pDeleteNode);
   949    983       sqlite3_finalize(pRtree->pReadRowid);
   950    984       sqlite3_finalize(pRtree->pWriteRowid);
   951    985       sqlite3_finalize(pRtree->pDeleteRowid);
   952    986       sqlite3_finalize(pRtree->pReadParent);
   953    987       sqlite3_finalize(pRtree->pWriteParent);
................................................................................
  1271   1305     assert( nCell<200 );
  1272   1306     for(ii=0; ii<nCell; ii++){
  1273   1307       if( nodeGetRowid(pRtree, pNode, ii)==iRowid ){
  1274   1308         *piIndex = ii;
  1275   1309         return SQLITE_OK;
  1276   1310       }
  1277   1311     }
         1312  +  RTREE_IS_CORRUPT(pRtree);
  1278   1313     return SQLITE_CORRUPT_VTAB;
  1279   1314   }
  1280   1315   
  1281   1316   /*
  1282   1317   ** Return the index of the cell containing a pointer to node pNode
  1283   1318   ** in its parent. If pNode is the root node, return -1.
  1284   1319   */
................................................................................
  1911   1946   
  1912   1947       if( p->usable
  1913   1948       && ((p->iColumn>0 && p->iColumn<=pRtree->nDim2)
  1914   1949           || p->op==SQLITE_INDEX_CONSTRAINT_MATCH)
  1915   1950       ){
  1916   1951         u8 op;
  1917   1952         switch( p->op ){
  1918         -        case SQLITE_INDEX_CONSTRAINT_EQ: op = RTREE_EQ; break;
  1919         -        case SQLITE_INDEX_CONSTRAINT_GT: op = RTREE_GT; break;
  1920         -        case SQLITE_INDEX_CONSTRAINT_LE: op = RTREE_LE; break;
  1921         -        case SQLITE_INDEX_CONSTRAINT_LT: op = RTREE_LT; break;
  1922         -        case SQLITE_INDEX_CONSTRAINT_GE: op = RTREE_GE; break;
  1923         -        default:
  1924         -          assert( p->op==SQLITE_INDEX_CONSTRAINT_MATCH );
  1925         -          op = RTREE_MATCH; 
  1926         -          break;
         1953  +        case SQLITE_INDEX_CONSTRAINT_EQ:    op = RTREE_EQ;    break;
         1954  +        case SQLITE_INDEX_CONSTRAINT_GT:    op = RTREE_GT;    break;
         1955  +        case SQLITE_INDEX_CONSTRAINT_LE:    op = RTREE_LE;    break;
         1956  +        case SQLITE_INDEX_CONSTRAINT_LT:    op = RTREE_LT;    break;
         1957  +        case SQLITE_INDEX_CONSTRAINT_GE:    op = RTREE_GE;    break;
         1958  +        case SQLITE_INDEX_CONSTRAINT_MATCH: op = RTREE_MATCH; break;
         1959  +        default:                            op = 0;           break;
  1927   1960         }
  1928         -      zIdxStr[iIdx++] = op;
  1929         -      zIdxStr[iIdx++] = (char)(p->iColumn - 1 + '0');
  1930         -      pIdxInfo->aConstraintUsage[ii].argvIndex = (iIdx/2);
  1931         -      pIdxInfo->aConstraintUsage[ii].omit = 1;
         1961  +      if( op ){
         1962  +        zIdxStr[iIdx++] = op;
         1963  +        zIdxStr[iIdx++] = (char)(p->iColumn - 1 + '0');
         1964  +        pIdxInfo->aConstraintUsage[ii].argvIndex = (iIdx/2);
         1965  +        pIdxInfo->aConstraintUsage[ii].omit = 1;
         1966  +      }
  1932   1967       }
  1933   1968     }
  1934   1969   
  1935   1970     pIdxInfo->idxNum = 2;
  1936   1971     pIdxInfo->needToFreeIdxStr = 1;
  1937   1972     if( iIdx>0 && 0==(pIdxInfo->idxStr = sqlite3_mprintf("%s", zIdxStr)) ){
  1938   1973       return SQLITE_NOMEM;
................................................................................
  2133   2168   */
  2134   2169   static int AdjustTree(
  2135   2170     Rtree *pRtree,                    /* Rtree table */
  2136   2171     RtreeNode *pNode,                 /* Adjust ancestry of this node. */
  2137   2172     RtreeCell *pCell                  /* This cell was just inserted */
  2138   2173   ){
  2139   2174     RtreeNode *p = pNode;
         2175  +  int cnt = 0;
  2140   2176     while( p->pParent ){
  2141   2177       RtreeNode *pParent = p->pParent;
  2142   2178       RtreeCell cell;
  2143   2179       int iCell;
  2144   2180   
  2145         -    if( nodeParentIndex(pRtree, p, &iCell) ){
         2181  +    if( (++cnt)>1000 || nodeParentIndex(pRtree, p, &iCell)  ){
         2182  +      RTREE_IS_CORRUPT(pRtree);
  2146   2183         return SQLITE_CORRUPT_VTAB;
  2147   2184       }
  2148   2185   
  2149   2186       nodeGetCell(pRtree, pParent, iCell, &cell);
  2150   2187       if( !cellContains(pRtree, &cell, pCell) ){
  2151   2188         cellUnion(pRtree, &cell, pCell);
  2152   2189         nodeOverwriteCell(pRtree, pParent, &cell, iCell);
................................................................................
  2606   2643         for(pTest=pLeaf; pTest && pTest->iNode!=iNode; pTest=pTest->pParent);
  2607   2644         if( !pTest ){
  2608   2645           rc2 = nodeAcquire(pRtree, iNode, 0, &pChild->pParent);
  2609   2646         }
  2610   2647       }
  2611   2648       rc = sqlite3_reset(pRtree->pReadParent);
  2612   2649       if( rc==SQLITE_OK ) rc = rc2;
  2613         -    if( rc==SQLITE_OK && !pChild->pParent ) rc = SQLITE_CORRUPT_VTAB;
         2650  +    if( rc==SQLITE_OK && !pChild->pParent ){
         2651  +      RTREE_IS_CORRUPT(pRtree);
         2652  +      rc = SQLITE_CORRUPT_VTAB;
         2653  +    }
  2614   2654       pChild = pChild->pParent;
  2615   2655     }
  2616   2656     return rc;
  2617   2657   }
  2618   2658   
  2619   2659   static int deleteCell(Rtree *, RtreeNode *, int, int);
  2620   2660   
................................................................................
  2919   2959   
  2920   2960     /* Obtain a reference to the leaf node that contains the entry 
  2921   2961     ** about to be deleted. 
  2922   2962     */
  2923   2963     if( rc==SQLITE_OK ){
  2924   2964       rc = findLeafNode(pRtree, iDelete, &pLeaf, 0);
  2925   2965     }
         2966  +
         2967  +#ifdef CORRUPT_DB
         2968  +  assert( pLeaf!=0 || rc!=SQLITE_OK || CORRUPT_DB );
         2969  +#endif
  2926   2970   
  2927   2971     /* Delete the cell in question from the leaf node. */
  2928         -  if( rc==SQLITE_OK ){
         2972  +  if( rc==SQLITE_OK && pLeaf ){
  2929   2973       int rc2;
  2930   2974       rc = nodeRowidIndex(pRtree, pLeaf, iDelete, &iCell);
  2931   2975       if( rc==SQLITE_OK ){
  2932   2976         rc = deleteCell(pRtree, pLeaf, iCell, 0);
  2933   2977       }
  2934   2978       rc2 = nodeRelease(pRtree, pLeaf);
  2935   2979       if( rc==SQLITE_OK ){
................................................................................
  3193   3237         pRtree->iReinsertHeight = -1;
  3194   3238         rc = rtreeInsertCell(pRtree, pLeaf, &cell, 0);
  3195   3239         rc2 = nodeRelease(pRtree, pLeaf);
  3196   3240         if( rc==SQLITE_OK ){
  3197   3241           rc = rc2;
  3198   3242         }
  3199   3243       }
  3200         -    if( pRtree->nAux ){
         3244  +    if( rc==SQLITE_OK && pRtree->nAux ){
  3201   3245         sqlite3_stmt *pUp = pRtree->pWriteAux;
  3202   3246         int jj;
  3203   3247         sqlite3_bind_int64(pUp, 1, *pRowid);
  3204   3248         for(jj=0; jj<pRtree->nAux; jj++){
  3205   3249           sqlite3_bind_value(pUp, jj+2, aData[pRtree->nDim2+3+jj]);
  3206   3250         }
  3207   3251         sqlite3_step(pUp);
................................................................................
  3391   3435       /* Read and write the xxx_parent table */
  3392   3436       "SELECT parentnode FROM '%q'.'%q_parent' WHERE nodeno = ?1",
  3393   3437       "INSERT OR REPLACE INTO '%q'.'%q_parent' VALUES(?1, ?2)",
  3394   3438       "DELETE FROM '%q'.'%q_parent' WHERE nodeno = ?1"
  3395   3439     };
  3396   3440     sqlite3_stmt **appStmt[N_STATEMENT];
  3397   3441     int i;
         3442  +  const int f = SQLITE_PREPARE_PERSISTENT|SQLITE_PREPARE_NO_VTAB;
  3398   3443   
  3399   3444     pRtree->db = db;
  3400   3445   
  3401   3446     if( isCreate ){
  3402   3447       char *zCreate;
  3403   3448       sqlite3_str *p = sqlite3_str_new(db);
  3404   3449       int ii;
................................................................................
  3447   3492          /* An UPSERT is very slightly slower than REPLACE, but it is needed
  3448   3493          ** if there are auxiliary columns */
  3449   3494          zFormat = "INSERT INTO\"%w\".\"%w_rowid\"(rowid,nodeno)VALUES(?1,?2)"
  3450   3495                     "ON CONFLICT(rowid)DO UPDATE SET nodeno=excluded.nodeno";
  3451   3496       }
  3452   3497       zSql = sqlite3_mprintf(zFormat, zDb, zPrefix);
  3453   3498       if( zSql ){
  3454         -      rc = sqlite3_prepare_v3(db, zSql, -1, SQLITE_PREPARE_PERSISTENT,
  3455         -                              appStmt[i], 0); 
         3499  +      rc = sqlite3_prepare_v3(db, zSql, -1, f, appStmt[i], 0); 
  3456   3500       }else{
  3457   3501         rc = SQLITE_NOMEM;
  3458   3502       }
  3459   3503       sqlite3_free(zSql);
  3460   3504     }
  3461   3505     if( pRtree->nAux ){
  3462   3506       pRtree->zReadAuxSql = sqlite3_mprintf(
................................................................................
  3478   3522           }
  3479   3523         }
  3480   3524         sqlite3_str_appendf(p, " WHERE rowid=?1");
  3481   3525         zSql = sqlite3_str_finish(p);
  3482   3526         if( zSql==0 ){
  3483   3527           rc = SQLITE_NOMEM;
  3484   3528         }else{
  3485         -        rc = sqlite3_prepare_v3(db, zSql, -1, SQLITE_PREPARE_PERSISTENT,
  3486         -                                &pRtree->pWriteAux, 0); 
         3529  +        rc = sqlite3_prepare_v3(db, zSql, -1, f, &pRtree->pWriteAux, 0); 
  3487   3530           sqlite3_free(zSql);
  3488   3531         }
  3489   3532       }
  3490   3533     }
  3491   3534   
  3492   3535     return rc;
  3493   3536   }
................................................................................
  3555   3598           pRtree->zDb, pRtree->zName
  3556   3599       );
  3557   3600       rc = getIntFromStmt(db, zSql, &pRtree->iNodeSize);
  3558   3601       if( rc!=SQLITE_OK ){
  3559   3602         *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db));
  3560   3603       }else if( pRtree->iNodeSize<(512-64) ){
  3561   3604         rc = SQLITE_CORRUPT_VTAB;
         3605  +      RTREE_IS_CORRUPT(pRtree);
  3562   3606         *pzErr = sqlite3_mprintf("undersize RTree blobs in \"%q_node\"",
  3563   3607                                  pRtree->zName);
  3564   3608       }
  3565   3609     }
  3566   3610   
  3567   3611     sqlite3_free(zSql);
  3568   3612     return rc;
................................................................................
  3878   3922   ** Or, if an error does occur, NULL is returned and an error code left
  3879   3923   ** in the RtreeCheck object. The final value of *pnNode is undefined in
  3880   3924   ** this case.
  3881   3925   */
  3882   3926   static u8 *rtreeCheckGetNode(RtreeCheck *pCheck, i64 iNode, int *pnNode){
  3883   3927     u8 *pRet = 0;                   /* Return value */
  3884   3928   
  3885         -  assert( pCheck->rc==SQLITE_OK );
  3886         -  if( pCheck->pGetNode==0 ){
         3929  +  if( pCheck->rc==SQLITE_OK && pCheck->pGetNode==0 ){
  3887   3930       pCheck->pGetNode = rtreeCheckPrepare(pCheck,
  3888   3931           "SELECT data FROM %Q.'%q_node' WHERE nodeno=?", 
  3889   3932           pCheck->zDb, pCheck->zTab
  3890   3933       );
  3891   3934     }
  3892   3935   
  3893   3936     if( pCheck->rc==SQLITE_OK ){

Changes to ext/rtree/rtree6.test.

    54     54       CREATE VIRTUAL TABLE t1 USING rtree(ii, x1, x2, y1, y2);
    55     55     }
    56     56   } {}
    57     57   
    58     58   do_test rtree6-1.2 {
    59     59     rtree_strategy {SELECT * FROM t1 WHERE x1>10}
    60     60   } {E0}
           61  +do_test rtree6-1.2.1 {
           62  +  rtree_strategy {SELECT * FROM t1 WHERE x1>10 AND x2 LIKE '%x%'}
           63  +} {E0}
    61     64   
    62     65   do_test rtree6-1.3 {
    63     66     rtree_strategy {SELECT * FROM t1 WHERE x1<10}
    64     67   } {C0}
    65     68   
    66     69   do_test rtree6-1.4 {
    67     70     rtree_strategy {SELECT * FROM t1,t2 WHERE k=ii AND x1<10}

Added ext/rtree/rtreecirc.test.

            1  +# 2018 Dec 22
            2  +#
            3  +# The author disclaims copyright to this source code.  In place of
            4  +# a legal notice, here is a blessing:
            5  +#
            6  +#    May you do good and not evil.
            7  +#    May you find forgiveness for yourself and forgive others.
            8  +#    May you share freely, never taking more than you give.
            9  +#
           10  +#*************************************************************************
           11  +# This file implements regression tests for SQLite library.  The
           12  +# focus of this script is testing the FTS5 module.
           13  +#
           14  +
           15  +if {![info exists testdir]} {
           16  +  set testdir [file join [file dirname [info script]] .. .. test]
           17  +}
           18  +source [file join [file dirname [info script]] rtree_util.tcl]
           19  +source $testdir/tester.tcl
           20  +set testprefix rtreecirc
           21  +
           22  +ifcapable !rtree {
           23  +  finish_test
           24  +  return
           25  +}
           26  +
           27  +do_execsql_test 1.0 {
           28  +  CREATE VIRTUAL TABLE rt USING rtree(id, x1, x2, y1, y2);
           29  +  SELECT name FROM sqlite_master ORDER BY 1;
           30  +} {
           31  +  rt rt_node rt_parent rt_rowid
           32  +}
           33  +db_save_and_close
           34  +
           35  +foreach {tn schema sql} {
           36  +  1 {
           37  +    CREATE TRIGGER tr1 AFTER INSERT ON rt_node BEGIN
           38  +      SELECT * FROM rt;
           39  +    END;
           40  +  } {
           41  +    INSERT INTO rt VALUES(1, 2, 3, 4, 5);
           42  +  }
           43  +  2 {
           44  +    CREATE TRIGGER tr1 AFTER INSERT ON rt_parent BEGIN
           45  +      SELECT * FROM rt;
           46  +    END;
           47  +  } {
           48  +    INSERT INTO rt VALUES(1, 2, 3, 4, 5);
           49  +  }
           50  +  3 {
           51  +    CREATE TRIGGER tr1 AFTER INSERT ON rt_rowid BEGIN
           52  +      SELECT * FROM rt;
           53  +    END;
           54  +  } {
           55  +    INSERT INTO rt VALUES(1, 2, 3, 4, 5);
           56  +  }
           57  +} {
           58  +  db_restore_and_reopen
           59  +  do_execsql_test  1.1.$tn.1 $schema
           60  +  do_catchsql_test 1.1.$tn.2 $sql {1 {no such table: main.rt}}
           61  +  db close
           62  +}
           63  +
           64  +
           65  +finish_test
           66  +

Added ext/rtree/rtreefuzz001.test.

            1  +# 2012-12-21
            2  +#
            3  +# The author disclaims copyright to this source code.  In place of
            4  +# a legal notice, here is a blessing:
            5  +#
            6  +#    May you do good and not evil.
            7  +#    May you find forgiveness for yourself and forgive others.
            8  +#    May you share freely, never taking more than you give.
            9  +#
           10  +#***********************************************************************
           11  +#
           12  +# Test cases for corrupt database files.
           13  +
           14  +if {![info exists testdir]} {
           15  +  set testdir [file join [file dirname [info script]] .. .. test]
           16  +} 
           17  +source $testdir/tester.tcl
           18  +
           19  +ifcapable !deserialize||!rtree {
           20  +  finish_test
           21  +  return
           22  +}
           23  +database_may_be_corrupt
           24  +
           25  +do_test rtreefuzz001-100 {
           26  +  sqlite3 db {}
           27  +  db deserialize [decode_hexdb {
           28  +| size 24576 pagesize 4096 filename c1b.db
           29  +| page 1 offset 0
           30  +|      0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00   SQLite format 3.
           31  +|     16: 10 00 01 01 00 40 20 20 00 00 00 03 00 00 00 06   .....@  ........
           32  +|     32: 00 00 00 00 00 00 00 00 00 00 00 03 00 00 00 04   ................
           33  +|     48: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00   ................
           34  +|     80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 03   ................
           35  +|     96: 00 2e 30 38 0d 00 00 00 04 0e 9c 00 0f ad 0f 4f   ..08...........O
           36  +|    112: 0e fc 0e 9c 00 00 00 00 00 00 00 00 00 00 00 00   ................
           37  +|   3728: 00 00 00 00 00 00 00 00 00 00 00 00 5e 04 07 17   ............^...
           38  +|   3744: 1f 1f 01 81 0b 74 61 62 6c 65 74 31 5f 70 61 72   .....tablet1_par
           39  +|   3760: 65 6e 74 74 31 5f 70 61 72 65 6e 74 04 43 52 45   entt1_parent.CRE
           40  +|   3776: 41 54 45 20 54 41 42 4c 45 20 22 74 31 5f 70 61   ATE TABLE .t1_pa
           41  +|   3792: 72 66 6e 74 22 28 6e 6f 64 65 6e 6f 20 49 4e 54   rfnt.(nodeno INT
           42  +|   3808: 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59   EGER PRIMARY KEY
           43  +|   3824: 2c 70 61 72 65 6e 74 6e 6f 64 65 29 51 03 06 17   ,parentnode)Q...
           44  +|   3840: 1b 1b 01 7b 74 61 62 6c 65 74 31 5f 6e 6f 64 65   ....tablet1_node
           45  +|   3856: 74 31 5f 6e 6f 64 65 03 43 52 45 41 54 45 20 54   t1_node.CREATE T
           46  +|   3872: 41 42 4c 45 20 22 74 31 5f 6e 6f 64 65 22 28 6e   ABLE .t1_node.(n
           47  +|   3888: 6f 64 65 6e 6f 20 49 4e 54 45 47 45 52 20 50 52   odeno INTEGER PR
           48  +|   3904: 49 4d 41 52 59 20 4b 45 59 2c 64 61 74 61 29 5c   IMARY KEY,data).
           49  +|   3920: 02 07 17 1d 1d 01 81 0b 74 61 62 6c 65 74 31 5f   ........tablet1_
           50  +|   3936: 72 6f 77 69 64 74 31 5f 72 6f 77 69 64 02 43 52   rowidt1_rowid.CR
           51  +|   3952: 45 41 54 45 20 54 41 42 4c 45 20 22 74 31 5f 72   EATE TABLE .t1_r
           52  +|   3968: 6f 77 69 64 22 28 72 6f 77 69 64 20 49 4e 54 45   owid.(rowid INTE
           53  +|   3984: 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c   GER PRIMARY KEY,
           54  +|   4000: 6e 6f 64 65 6e 6f 2c 61 30 2c 61 31 29 51 01 07   nodeno,a0,a1)Q..
           55  +|   4016: 17 11 11 08 81 0f 74 61 62 6c 65 74 31 74 31 43   ......tablet1t1C
           56  +|   4032: 52 45 41 54 45 20 56 49 52 54 55 41 4c 20 54 41   REATE VIRTUAL TA
           57  +|   4048: 42 4c 45 20 74 31 20 55 53 49 4e 47 20 72 74 72   BLE t1 USING rtr
           58  +|   4064: 65 65 28 69 64 2c 78 30 2c 78 31 2c 79 30 2c 79   ee(id,x0,x1,y0,y
           59  +|   4080: 31 2c 2b 6c 61 62 65 6c 2c 2b 6f 74 68 65 72 29   1,+label,+other)
           60  +| page 2 offset 4096
           61  +|      0: 0d 0c cd 00 74 08 75 01 0f e8 0c b3 0f d0 0f b7   ....t.u.........
           62  +|     16: 0f 9e 0f 91 0f 81 0f 70 0f 5e 0f 4f 0f 39 0f 29   .......p.^.O.9.)
           63  +|     32: 0f 18 0f 06 0e f7 0c 65 0e 58 0d c2 0d 2c 0c 25   .......e.X...,.%
           64  +|     48: 0b 85 0a e5 0a 45 09 a5 09 05 0c 83 0c 93 0c a3   .....E..........
           65  +|     64: 0f f0 0c 15 0b 75 0a d5 0a 35 09 95 08 f5 0e d8   .....u...5......
           66  +|     80: 0e 42 0d ac 0d 16 0c 05 0b 65 0a c5 0a 25 09 85   .B.......e...%..
           67  +|     96: 08 e5 0e c8 0e 32 0d 9c 0d 06 0b f5 0b 55 0a b5   .....2.......U..
           68  +|    112: 0a 15 09 75 08 d5 0e b8 0e 22 0d 8c 0c f6 0b e5   ...u............
           69  +|    128: 0b 45 0a a5 0a 05 09 65 08 c5 0e a8 0e 12 0d 7c   .E.....e.......|
           70  +|    144: 0c e6 0b d5 0b 35 0a 95 09 f5 09 55 08 b5 0e 98   .....5.....U....
           71  +|    160: 0e 02 0d 6c 0c d6 0b c5 0b 25 0a 85 09 e5 09 45   ...l.....%.....E
           72  +|    176: 08 a5 0e 88 0d f2 0d 5c 0c 55 0b b5 0b 15 0a 75   .........U.....u
           73  +|    192: 09 d5 09 35 08 95 0e 78 0d e2 0d 4c 0c 45 0b a5   ...5...x...L.E..
           74  +|    208: 0b 05 0a 65 09 c5 09 25 08 85 0e 68 0d d2 0d 3c   ...e...%...h...<
           75  +|    224: 0c 35 0b 95 0a f5 0a 55 09 b5 09 15 08 75 0c 75   .5.....U.....u.u
           76  +|   2160: 00 00 00 00 00 0d 8e 75 05 00 01 1b 00 04 62 6f   .......u......bo
           77  +|   2176: 78 2d 39 2c 39 0d 8e 11 05 00 01 1b 00 02 62 6f   x-9,9.........bo
           78  +|   2192: 78 2d 39 2c 38 0d 8d 2d 05 00 01 1b 00 02 62 6f   x-9,8..-......bo
           79  +|   2208: 78 2d 39 2c 37 0d 8c 49 05 00 01 1b 00 02 62 6f   x-9,7..I......bo
           80  +|   2224: 78 2d 39 2c 36 0d 8b 65 05 00 01 1b 00 02 62 6f   x-9,6..e......bo
           81  +|   2240: 78 2d 39 2c 35 0d 8b 01 05 00 01 1b 00 02 62 6f   x-9,5.........bo
           82  +|   2256: 78 2d 39 2c 34 0d 8a 1d 05 00 01 1b 00 02 62 6f   x-9,4.........bo
           83  +|   2272: 78 2d 39 2c 33 0d 89 39 05 00 01 1b 00 02 62 6f   x-9,3..9......bo
           84  +|   2288: 78 2d 39 2c 32 0d 88 55 05 00 01 1b 00 02 62 6f   x-9,2..U......bo
           85  +|   2304: 78 2d 39 2c 31 0d 87 71 05 00 01 1b 00 02 62 6f   x-9,1..q......bo
           86  +|   2320: 78 2d 39 2c 30 0d 8e 74 05 00 01 1b 00 04 62 6f   x-9,0..t......bo
           87  +|   2336: 78 2d 38 2c 39 0d 8e 10 05 00 01 1b 00 02 62 6f   x-8,9.........bo
           88  +|   2352: 78 2d 38 2c 38 0d 8d 2c 05 00 01 1b 00 02 62 6f   x-8,8..,......bo
           89  +|   2368: 78 2d 38 2c 37 0d 8c 48 05 00 01 1b 00 02 62 6f   x-8,7..H......bo
           90  +|   2384: 78 2d 38 2c 36 0d 8b 64 05 00 01 1b 00 02 62 6f   x-8,6..d......bo
           91  +|   2400: 78 2d 38 2c 35 0d 8b 00 05 00 01 1b 00 02 62 6f   x-8,5.........bo
           92  +|   2416: 78 2d 38 2c 34 0d 8a 1c 05 00 01 1b 00 02 62 6f   x-8,4.........bo
           93  +|   2432: 78 2d 38 2c 33 0d 89 38 05 00 01 1b 00 02 62 6f   x-8,3..8......bo
           94  +|   2448: 78 2d 38 2c 32 0d 88 54 05 00 01 1b 00 02 62 6f   x-8,2..T......bo
           95  +|   2464: 78 2d 38 2c 31 0d 87 70 05 00 01 1b 00 02 62 6f   x-8,1..p......bo
           96  +|   2480: 78 2d 38 2c 30 0d 8e 73 05 00 01 1b 00 05 62 6f   x-8,0..s......bo
           97  +|   2496: 78 2d 37 2c 39 0d 8e 0f 05 00 01 1b 00 05 62 6f   x-7,9.........bo
           98  +|   2512: 78 2d 37 2c 38 0d 8d 2b 05 00 01 1b 00 05 62 6f   x-7,8..+......bo
           99  +|   2528: 78 2d 37 2c 37 0d 8c 47 05 00 01 1b 00 05 62 6f   x-7,7..G......bo
          100  +|   2544: 78 2d 37 2c 36 0d 8b 63 05 00 01 1b 00 05 62 6f   x-7,6..c......bo
          101  +|   2560: 78 2d 37 2c 35 0d 8a 7f 05 00 01 1b 00 05 62 6f   x-7,5.........bo
          102  +|   2576: 78 2d 37 2c 34 0d 8a 1b 05 00 01 1b 00 05 62 6f   x-7,4.........bo
          103  +|   2592: 78 2d 37 2c 33 0d 89 37 05 00 01 1b 00 05 62 6f   x-7,3..7......bo
          104  +|   2608: 78 2d 37 2c 32 0d 88 53 05 00 01 1b 00 05 62 6f   x-7,2..S......bo
          105  +|   2624: 78 2d 37 2c 31 0d 87 6f 05 00 01 1b 00 05 62 6f   x-7,1..o......bo
          106  +|   2640: 78 2d 37 2c 30 0d 8e 72 05 00 01 1b 00 04 62 6f   x-7,0..r......bo
          107  +|   2656: 78 2d 36 2c 39 0d 8e 0e 05 00 01 1b 00 05 62 6f   x-6,9.........bo
          108  +|   2672: 78 2d 36 2c 38 0d 8d 2a 05 00 01 1b 00 05 62 6f   x-6,8..*......bo
          109  +|   2688: 78 2d 36 2c 37 0d 8c 46 05 00 01 1b 00 05 62 6f   x-6,7..F......bo
          110  +|   2704: 78 2d 36 2c 36 0d 8b 62 05 00 01 1b 00 05 62 6f   x-6,6..b......bo
          111  +|   2720: 78 2d 36 2c 35 0d 8a 7e 05 00 01 1b 00 05 62 6f   x-6,5..~......bo
          112  +|   2736: 78 2d 36 2c 34 0d 8a 1a 05 00 01 1b 00 05 62 6f   x-6,4.........bo
          113  +|   2752: 78 2d 36 2c 33 0d 89 36 05 00 01 1b 00 05 62 6f   x-6,3..6......bo
          114  +|   2768: 78 2d 36 2c 32 0d 88 52 05 00 01 1b 00 05 62 6f   x-6,2..R......bo
          115  +|   2784: 78 2d 36 2c 31 0d 87 6e 05 00 01 1b 00 05 62 6f   x-6,1..n......bo
          116  +|   2800: 78 2d 36 2c 30 0d 8e 71 05 00 01 1b 00 04 62 6f   x-6,0..q......bo
          117  +|   2816: 78 2d 35 2c 39 0d 8e 0d 05 00 01 1b 00 05 62 6f   x-5,9.........bo
          118  +|   2832: 78 2d 35 2c 38 0d 8d 29 05 00 01 1b 00 05 62 6f   x-5,8..)......bo
          119  +|   2848: 78 2d 35 2c 37 0d 8c 45 05 00 01 1b 00 05 62 6f   x-5,7..E......bo
          120  +|   2864: 78 2d 35 2c 36 0d 8b 61 05 00 01 1b 00 05 62 6f   x-5,6..a......bo
          121  +|   2880: 78 2d 35 2c 35 0d 8a 7d 05 00 01 1b 00 05 62 6f   x-5,5.........bo
          122  +|   2896: 78 2d 35 2c 34 0d 8a 19 05 00 01 1b 00 05 62 6f   x-5,4.........bo
          123  +|   2912: 78 2d 35 2c 33 0d 89 35 05 00 01 1b 00 05 62 6f   x-5,3..5......bo
          124  +|   2928: 78 2d 35 2c 32 0d 88 51 05 00 01 1b 00 05 62 6f   x-5,2..Q......bo
          125  +|   2944: 78 2d 35 2c 31 0d 87 6d 05 00 01 1b 00 05 62 6f   x-5,1..m......bo
          126  +|   2960: 78 2d 35 2c 30 0d 8e 70 05 00 01 1b 00 04 62 6f   x-5,0..p......bo
          127  +|   2976: 78 2d 34 2c 39 0d 8e 0c 05 00 01 1b 00 04 62 6f   x-4,9.........bo
          128  +|   2992: 78 2d 34 2c 38 0d 8d 28 05 00 01 1b 00 04 62 6f   x-4,8..(......bo
          129  +|   3008: 78 2d 34 2c 37 0d 8c 44 05 00 01 1b 00 04 62 6f   x-4,7..D......bo
          130  +|   3024: 78 2d 34 2c 36 0d 8b 60 05 00 01 1b 00 02 62 6f   x-4,6..`......bo
          131  +|   3040: 78 2d 34 2c 35 0d 8a 7c 05 00 01 1b 00 02 62 6f   x-4,5..|......bo
          132  +|   3056: 78 2d 34 2c 34 0d 8a 18 05 00 01 1b 00 02 62 6f   x-4,4.........bo
          133  +|   3072: 78 2d 34 2c 33 0d 89 34 05 00 01 1b 00 02 62 6f   x-4,3..4......bo
          134  +|   3088: 78 2d 34 2c 32 0d 88 50 05 00 01 1b 00 02 62 6f   x-4,2..P......bo
          135  +|   3104: 78 2d 34 2c 31 0d 87 6c 05 00 01 1b 00 02 62 6f   x-4,1..l......bo
          136  +|   3120: 78 2d 34 2c 30 0d 8e 6f 05 00 01 1b 00 04 62 6f   x-4,0..o......bo
          137  +|   3136: 78 2d 33 2c 39 0d 8e 0b 05 00 01 1b 00 04 62 6f   x-3,9.........bo
          138  +|   3152: 78 2d 33 2c 38 0d 8d 27 05 00 01 1b 00 04 62 6f   x-3,8..'......bo
          139  +|   3168: 78 2d 33 2c 37 0d 87 68 05 00 01 1b 00 03 62 6f   x-3,7..h......bo
          140  +|   3184: 78 2d 30 2c 30 06 90 d9 80 80 81 84 4c 05 00 01   x-0,0.......L...
          141  +|   3200: 00 00 03 0d 88 4c 05 00 01 1b 00 02 62 6f 78 2d   .....L......box-
          142  +|   3216: 30 2c 31 0d 88 4d 05 00 01 1b 00 02 62 6f 78 2d   0,1..M......box-
          143  +|   3232: 31 2c 31 0d 88 4e 05 00 01 1b 00 02 62 6f 78 2d   1,1..N......box-
          144  +|   3248: 32 2c 31 17 01 05 00 01 2f 00 02 6c 6f 77 65 72   2,1...../..lower
          145  +|   3264: 2d 6c 65 66 74 20 63 6f 72 6e 65 72 0d 0d 26 00   -left corner..&.
          146  +|   3280: 09 00 01 00 00 04 0d 8c 43 05 00 01 1b 00 04 62   ........C......b
          147  +|   3296: 6f 78 2d 33 2c 36 0d 8b 5f 05 00 01 1b 00 02 62   ox-3,6.._......b
          148  +|   3312: 6f 78 2d 33 2c 35 0d 8a 7b 05 00 01 1b 00 02 62   ox-3,5.........b
          149  +|   3328: 6f 78 2d 33 2c 34 0d 8a 17 05 00 01 1b 00 02 62   ox-3,4.........b
          150  +|   3344: 6f 78 2d 33 2c 33 0d 89 33 05 00 01 1b 00 02 62   ox-3,3..3......b
          151  +|   3360: 6f 78 2d 33 2c 32 0d bc 00 06 00 09 0d 87 6b 05   ox-3,2........k.
          152  +|   3376: 00 01 1b 00 03 62 6f 78 2d 33 2c 30 0d 8e 6e 05   .....box-3,0..n.
          153  +|   3392: 00 01 1b 00 04 62 6f 78 2d 32 2c 39 0d 8e 0a 05   .....box-2,9....
          154  +|   3408: 00 01 1b 00 04 62 6f 78 2d 32 2c 38 0d 8d 26 05   .....box-2,8..&.
          155  +|   3424: 00 01 1b 00 04 62 6f 78 2d 32 2c 37 0d 8c 42 05   .....box-2,7..B.
          156  +|   3440: 00 01 1b 00 04 62 6f 78 2d 32 2c 36 0d 8b 5e 05   .....box-2,6..^.
          157  +|   3456: 00 01 1b 00 02 62 6f 78 2d 32 2c 35 0d 8a 7a 05   .....box-2,5..z.
          158  +|   3472: 00 01 1b 00 02 62 6f 78 2d 32 2c 34 0d 8a 16 05   .....box-2,4....
          159  +|   3488: 00 01 1b 00 02 62 6f 78 2d 32 2c 33 0d 89 32 05   .....box-2,3..2.
          160  +|   3504: 00 01 1b 00 02 62 6f 78 2d 32 2c 32 0e 52 00 06   .....box-2,2.R..
          161  +|   3520: 00 09 0d 87 6a 05 00 01 1b 00 03 62 6f 78 2d 32   ....j......box-2
          162  +|   3536: 2c 30 0d 8e 6d 05 00 01 1b 00 04 62 6f 78 2d 31   ,0..m......box-1
          163  +|   3552: 2c 39 0d 8e 09 05 00 01 1b 00 04 62 6f 78 2d 31   ,9.........box-1
          164  +|   3568: 2c 38 0d 8d 25 05 00 01 1b 00 04 62 6f 78 2d 31   ,8..%......box-1
          165  +|   3584: 2c 37 0d 8c 41 05 00 01 1b 00 04 62 6f 78 2d 31   ,7..A......box-1
          166  +|   3600: 2c 36 0d 8b 5d 05 00 01 1b 00 02 62 6f 78 2d 31   ,6..]......box-1
          167  +|   3616: 2c 35 0d 8a 79 05 00 01 1b 00 02 62 6f 78 2d 31   ,5..y......box-1
          168  +|   3632: 2c 34 0d 8a 15 05 00 01 1b 00 02 62 6f 78 2d 31   ,4.........box-1
          169  +|   3648: 2c 33 0d 89 31 05 00 01 1b 00 02 62 6f 78 2d 31   ,3..1......box-1
          170  +|   3664: 2c 32 0e e8 00 06 00 09 0d 87 69 05 00 01 1b 00   ,2........i.....
          171  +|   3680: 03 62 6f 78 2d 31 2c 30 0d 8e 6c 05 00 01 1b 00   .box-1,0..l.....
          172  +|   3696: 04 62 6f 78 2d 30 2c 39 0d 8e 08 05 00 01 1b 00   .box-0,9........
          173  +|   3712: 04 62 6f 78 2d 30 2c 38 0d 8d 24 05 00 01 1b 00   .box-0,8..$.....
          174  +|   3728: 04 62 6f 78 2d 30 2c 37 0d 8c 40 05 00 01 1b 00   .box-0,7..@.....
          175  +|   3744: 04 62 6f 78 2d 30 2c 36 0d 8b 5c 05 00 01 1b 00   .box-0,6........
          176  +|   3760: 02 62 6f 78 2d 30 2c 35 0d 8a 78 05 00 01 1b 00   .box-0,5..x.....
          177  +|   3776: 02 62 6f 78 2d 30 2c 34 0d 8a 14 05 00 01 1b 00   .box-0,4........
          178  +|   3792: 02 62 6f 78 2d 30 2c 33 0d 89 30 05 00 01 1b 00   .box-0,3..0.....
          179  +|   3808: 02 62 6f 78 2d 30 2c 32 00 00 00 0f 00 09 1b 00   .box-0,2........
          180  +|   3824: 62 6f 78 2d 30 2c 30 0d 0e 05 00 09 1d 00 74 6f   box-0,0.......to
          181  +|   3840: 70 20 68 61 6c 66 10 0d 05 00 09 23 00 62 6f 74   p half.....#.bot
          182  +|   3856: 74 6f 6d 20 68 61 6c 66 0f 0c 02 05 09 01 00 72   tom half.......r
          183  +|   3872: 69 67 68 74 20 68 61 6c 66 0e 0b 05 00 09 1f 00   ight half.......
          184  +|   3888: 6c 65 66 74 20 68 61 6c 66 14 0a 05 00 09 2b 00   left half.....+.
          185  +|   3904: 74 68 65 20 77 68 6f 6c 65 20 74 68 69 6e 67 0d   the whole thing.
          186  +|   3920: 09 05 00 09 1d 00 74 6f 70 20 65 64 67 65 10 08   ......top edge..
          187  +|   3936: 05 00 09 23 00 62 6f 74 74 6f 6d 20 65 64 67 65   ...#.bottom edge
          188  +|   3952: 0f 07 05 00 09 21 00 72 69 67 68 74 20 65 64 67   .....!.right edg
          189  +|   3968: 65 0e 06 05 00 09 1f 00 6c 65 66 74 20 65 64 67   e.......left edg
          190  +|   3984: 65 0b 05 05 00 09 19 00 63 65 6e 74 65 72 17 04   e.......center..
          191  +|   4000: 05 00 09 31 00 75 70 70 65 72 2d 72 69 67 68 74   ...1.upper-right
          192  +|   4016: 20 63 6f 72 6e 65 72 17 03 05 00 09 31 00 6c 6f    corner.....1.lo
          193  +|   4032: 77 65 72 2d 72 69 67 68 74 20 63 6f 72 6e 65 72   wer-right corner
          194  +|   4048: 16 02 05 00 09 2f 00 75 70 70 65 72 2d 6c 65 66   ...../.upper-lef
          195  +|   4064: 74 20 63 6f 72 6e 65 72 06 00 05 00 01 00 00 03   t corner........
          196  +|   4080: 0d 88 4f 05 00 01 1b 00 02 62 6f 78 2d 33 2c 31   ..O......box-3,1
          197  +| page 3 offset 8192
          198  +|      0: 05 00 00 00 01 0f fb 00 00 00 00 06 0f fb 00 00   ................
          199  +|    384: 00 00 00 00 00 00 00 89 50 03 04 00 93 24 00 00   ........P....$..
          200  +|    400: 00 11 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
          201  +|    688: 00 00 00 00 42 c8 00 00 42 4c 00 00 42 00 00 00   ....B...BL..B...
          202  +|    720: 03 eb 40 40 00 00 40 80 00 00 00 00 00 00 3f 80   ..@@..@.......?.
          203  +|    736: 00 00 00 00 00 00 00 00 03 ea 40 00 00 00 40 40   ..........@...@@
          204  +|    752: 00 00 00 00 00 00 3f 80 00 00 00 00 00 00 00 00   ......?.........
          205  +|    768: 03 e9 3f 80 00 00 40 00 00 00 00 00 00 00 3f 80   ..?...@.......?.
          206  +|    784: 00 00 00 00 00 00 00 00 03 e8 00 00 00 00 3f 80   ..............?.
          207  +|    800: 00 00 00 00 00 00 3f 80 00 00 00 00 00 00 00 00   ......?.........
          208  +|   1616: 00 00 00 00 00 00 00 00 00 00 89 50 02 04 00 93   ...........P....
          209  +|   1632: 24 00 00 00 33 00 00 00 00 00 00 00 01 00 00 00   $...3...........
          210  +|   1648: 00 41 20 00 00 00 00 00 00 41 0e 00 00 00 00 00   .A ......A......
          211  +|   1664: 00 00 00 04 4f 40 40 00 00 40 80 00 00 3f 80 00   ....O@@..@...?..
          212  +|   1680: 00 40 00 00 00 00 00 00 00 00 00 04 4e 40 00 00   .@..........N@..
          213  +|   1696: 00 40 40 00 00 3f 80 00 00 40 00 00 00 00 00 00   .@@..?...@......
          214  +|   1712: 00 00 00 04 4d 3f 80 00 00 40 00 00 00 3f 80 00   ....M?...@...?..
          215  +|   1728: 00 40 00 00 00 00 00 00 00 00 00 04 4c 00 00 00   .@..........L...
          216  +|   1744: 00 3f 80 00 00 3f 80 00 00 40 00 00 00 00 00 00   .?...?...@......
          217  +|   1760: 00 00 00 04 b3 40 40 00 00 40 80 00 00 40 00 00   .....@@..@...@..
          218  +|   1776: 00 40 40 00 00 00 00 00 00 00 00 04 b2 40 00 00   .@@..........@..
          219  +|   1792: 00 40 40 00 00 40 00 00 00 40 40 00 00 00 00 00   .@@..@...@@.....
          220  +|   1808: 00 00 00 04 b1 3f 80 00 00 40 00 00 00 40 00 00   .....?...@...@..
          221  +|   1824: 00 40 40 00 00 00 00 00 00 00 00 04 b0 00 00 00   .@@.............
          222  +|   1840: 00 3f 80 00 00 40 00 00 00 40 40 00 00 00 00 00   .?...@...@@.....
          223  +|   1856: 00 00 00 05 17 40 40 00 00 40 80 00 00 40 40 00   .....@@..@...@@.
          224  +|   1872: 00 40 80 00 00 00 00 00 00 00 00 05 16 40 00 00   .@...........@..
          225  +|   1888: 00 40 40 00 00 40 40 00 00 40 80 00 00 00 00 00   .@@..@@..@......
          226  +|   1904: 00 00 00 05 15 3f 80 00 00 40 00 00 00 40 40 00   .....?...@...@@.
          227  +|   1920: 00 40 80 00 00 00 00 00 00 00 00 05 14 00 00 00   .@..............
          228  +|   1936: 00 3f 80 00 00 40 40 00 00 40 80 00 00 00 00 00   .?...@@..@......
          229  +|   1952: 00 00 00 05 7b 40 40 00 00 40 80 00 00 40 80 00   .....@@..@...@..
          230  +|   1968: 00 40 a0 00 00 00 00 00 00 00 00 05 7a 40 00 00   .@..........z@..
          231  +|   1984: 00 40 40 00 00 40 80 00 00 40 a0 00 00 00 00 00   .@@..@...@......
          232  +|   2000: 00 00 00 05 79 3f 80 00 00 40 00 00 00 40 80 00   ....y?...@...@..
          233  +|   2016: 00 40 a0 00 00 00 00 00 00 00 00 05 78 00 00 00   .@..........x...
          234  +|   2032: 00 3f 80 00 00 40 80 00 00 40 a0 00 00 00 00 00   .?...@...@......
          235  +|   2048: 00 00 00 05 df 40 40 00 00 40 80 00 00 40 a0 00   .....@@..@...@..
          236  +|   2064: 00 40 c0 00 00 00 00 00 00 00 00 05 de 40 00 00   .@...........@..
          237  +|   2080: 00 40 40 00 00 40 a0 00 00 40 c0 00 00 00 00 00   .@@..@...@......
          238  +|   2096: 00 00 00 05 dd 3f 80 00 00 40 00 00 00 40 a0 00   .....?...@...@..
          239  +|   2112: 00 40 c0 00 00 00 00 00 00 00 00 05 dc 00 00 00   .@..............
          240  +|   2128: 00 3f 80 00 00 40 a0 00 00 40 c0 00 00 00 00 00   .?...@...@......
          241  +|   2144: 00 00 00 06 43 40 40 00 00 40 80 00 00 40 c0 00   ....C@@..@...@..
          242  +|   2160: 00 40 e0 00 00 00 00 00 00 00 00 06 42 40 00 00   .@..........B@..
          243  +|   2176: 00 40 40 00 00 40 c0 00 00 40 e0 00 00 00 00 00   .@@..@...@......
          244  +|   2192: 00 00 00 06 41 3f 80 00 00 40 00 00 00 40 c0 00   ....A?...@...@..
          245  +|   2208: 00 40 e0 00 00 00 00 00 00 00 00 06 40 00 00 00   .@..........@...
          246  +|   2224: 00 3f 80 00 00 40 c0 00 00 40 e0 00 00 00 00 00   .?...@...@......
          247  +|   2240: 00 00 00 06 a7 40 40 00 00 40 80 00 00 40 e0 00   .....@@..@...@..
          248  +|   2256: 00 41 00 00 00 00 00 00 00 00 00 06 a6 40 00 00   .A...........@..
          249  +|   2272: 00 40 40 00 00 40 e0 00 00 41 00 00 00 00 00 00   .@@..@...A......
          250  +|   2288: 00 00 00 06 a5 3f 80 00 00 40 00 00 00 40 e0 00   .....?...@...@..
          251  +|   2304: 00 41 00 00 00 00 00 00 00 00 00 06 a4 00 00 00   .A..............
          252  +|   2320: 00 3f 80 00 00 40 e0 00 00 41 00 00 00 00 00 00   .?...@...A......
          253  +|   2336: 00 00 00 07 0a 40 00 00 00 40 40 00 00 41 00 00   .....@...@@..A..
          254  +|   2352: 00 41 10 00 00 00 00 00 00 00 00 07 09 3f 80 00   .A...........?..
          255  +|   2368: 00 40 00 00 00 41 00 00 00 41 10 00 00 00 00 00   .@...A...A......
          256  +|   2384: 00 00 00 07 08 00 00 00 00 3f 80 00 00 41 00 00   .........?...A..
          257  +|   2400: 00 41 10 00 00 00 00 00 00 00 00 07 6e 40 00 00   .A..........n@..
          258  +|   2416: 00 40 40 00 00 41 10 00 00 41 20 00 00 00 00 00   .@@..A...A .....
          259  +|   2432: 00 00 00 07 6d 3f 80 00 00 40 00 00 00 41 10 00   ....m?...@...A..
          260  +|   2448: 00 41 20 00 00 00 00 00 00 00 00 07 6c 00 00 00   .A .........l...
          261  +|   2464: 00 3f 80 00 00 41 10 00 00 41 20 00 00 00 00 00   .?...A...A .....
          262  +|   2480: 00 00 00 07 0b 40 40 00 00 40 80 00 00 41 00 00   .....@@..@...A..
          263  +|   2496: 00 41 10 00 00 00 00 00 00 00 00 07 6f 40 40 00   .A..........o@@.
          264  +|   2512: 00 40 80 00 00 41 10 00 00 41 20 00 00 00 00 00   .@...A...A .....
          265  +|   2528: 00 00 00 03 ec 40 80 00 00 40 a0 00 00 00 00 00   .....@...@......
          266  +|   2544: 00 3f 80 00 00 00 00 00 00 00 00 04 50 40 80 00   .?..........P@..
          267  +|   2560: 00 40 a0 00 00 3f 80 00 00 40 00 00 00 00 00 00   .@...?...@......
          268  +|   2576: 00 00 00 04 b4 40 80 00 00 40 a0 00 00 40 00 00   .....@...@...@..
          269  +|   2592: 00 40 40 00 00 00 00 00 00 00 00 05 18 40 80 00   .@@..........@..
          270  +|   2608: 00 40 a0 00 00 40 40 00 00 40 80 00 00 00 00 00   .@...@@..@......
          271  +|   2624: 00 00 00 05 7c 40 80 00 00 40 a0 00 00 40 80 00   ....|@...@...@..
          272  +|   2640: 00 40 a0 00 00 00 00 00 00 00 00 05 e0 40 80 00   .@...........@..
          273  +|   2656: 00 40 a0 00 00 40 a0 00 00 40 c0 00 00 00 00 00   .@...@...@......
          274  +|   2672: 00 00 00 06 44 40 80 00 00 40 a0 00 00 40 c0 00   ....D@...@...@..
          275  +|   2688: 00 40 e0 00 00 00 00 00 00 00 00 06 a8 40 80 00   .@...........@..
          276  +|   2704: 00 40 a0 00 00 40 e0 00 00 41 00 00 00 00 00 00   .@...@...A......
          277  +|   2720: 00 00 00 07 0c 40 80 00 00 40 a0 00 00 41 00 00   .....@...@...A..
          278  +|   2736: 00 41 10 00 00 00 00 00 00 00 00 07 70 40 80 00   .A..........p@..
          279  +|   2752: 00 40 a0 00 00 41 10 00 00 41 20 00 00 00 00 00   .@...A...A .....
          280  +|   2768: 00 00 00 03 ed 40 a0 00 00 40 c0 00 00 00 00 00   .....@...@......
          281  +|   2784: 00 3f 80 00 00 00 00 00 00 00 00 04 51 40 a0 00   .?..........Q@..
          282  +|   2800: 00 40 c0 00 00 3f 80 00 00 40 00 00 00 00 00 00   .@...?...@......
          283  +|   2816: 00 00 00 04 b5 40 a0 00 00 40 c0 00 00 40 00 00   .....@...@...@..
          284  +|   2832: 00 40 40 00 00 00 00 00 00 00 00 05 19 40 a0 00   .@@..........@..
          285  +|   2848: 00 40 c0 00 00 40 40 00 00 40 80 00 00 89 50 01   .@...@@..@....P.
          286  +|   2864: 04 00 93 24 00 01 00 02 00 00 00 00 00 00 00 03   ...$............
          287  +|   2880: 00 00 00 00 40 80 00 00 00 00 00 00 3f 80 00 00   ....@.......?...
          288  +|   2896: 00 00 00 00 00 00 00 02 00 00 00 00 41 20 00 00   ............A ..
          289  +|   2912: 00 00 00 00 41 20 00 00 00 00 00 00 00 00 00 00   ....A ..........
          290  +|   4080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 05 03   ................
          291  +| page 4 offset 12288
          292  +|      0: 0d 00 00 00 00 10 00 00 00 00 00 00 00 00 00 00   ................
          293  +| page 5 offset 16384
          294  +|      0: 0d 00 00 00 03 01 87 00 0b 2d 06 5a 01 87 00 00   .........-.Z....
          295  +|    384: 00 00 00 00 00 00 00 89 50 03 04 00 93 24 00 00   ........P....$..
          296  +|    400: 00 11 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
          297  +|    688: 00 00 00 00 42 c8 00 00 42 4c 00 00 42 00 00 00   ....B...BL..B...
          298  +|    720: 03 eb 40 40 00 00 40 80 00 00 00 00 00 00 3f 80   ..@@..@.......?.
          299  +|    736: 00 00 00 00 00 00 00 00 03 ea 40 00 00 00 40 40   ..........@...@@
          300  +|    752: 00 00 00 00 00 00 3f 80 00 00 00 00 00 00 00 00   ......?.........
          301  +|    768: 03 e9 3f 80 00 00 40 00 00 00 00 00 00 00 3f 80   ..?...@.......?.
          302  +|    784: 00 00 00 00 00 00 00 00 03 e8 00 00 00 00 3f 80   ..............?.
          303  +|    800: 00 00 00 00 00 00 3f 80 00 00 00 00 00 00 00 00   ......?.........
          304  +|   1616: 00 00 00 00 00 00 00 00 00 00 89 50 02 04 00 93   ...........P....
          305  +|   1632: 24 00 00 00 2d 00 00 00 00 00 00 04 4c 00 00 00   $...-.......L...
          306  +|   1648: 00 3f 80 00 00 3f 80 00 00 40 00 00 00 00 00 00   .?...?...@......
          307  +|   1664: 00 00 00 04 b0 00 00 00 00 3f 80 00 00 40 00 00   .........?...@..
          308  +|   1680: 00 40 40 00 00 00 00 00 00 00 00 05 14 00 00 00   .@@.............
          309  +|   1696: 00 3f 80 00 00 40 40 00 00 40 80 00 00 00 00 00   .?...@@..@......
          310  +|   1712: 00 00 00 05 78 00 00 00 00 3f 80 00 00 40 80 00   ....x....?...@..
          311  +|   1728: 00 40 a0 00 00 00 00 00 00 00 00 05 dc 00 00 00   .@..............
          312  +|   1744: 00 3f 80 00 00 40 a0 00 00 40 c0 00 00 00 00 00   .?...@...@......
          313  +|   1760: 00 00 00 00 01 00 00 00 00 41 20 00 00 00 00 00   .........A .....
          314  +|   1776: 00 41 0e 00 00 00 00 00 00 00 00 04 4d 3f 80 00   .A..........M?..
          315  +|   1792: 00 40 00 00 00 3f 80 00 00 40 00 00 00 00 00 00   .@...?...@......
          316  +|   1808: 00 00 00 04 b1 3f 80 00 00 40 00 00 00 40 00 00   .....?...@...@..
          317  +|   1824: 00 40 40 00 00 00 00 00 00 00 00 05 15 3f 80 00   .@@..........?..
          318  +|   1840: 00 40 00 00 00 40 40 00 00 40 80 00 00 00 00 00   .@...@@..@......
          319  +|   1856: 00 00 00 05 79 3f 80 00 00 40 00 00 00 40 80 00   ....y?...@...@..
          320  +|   1872: 00 40 a0 00 00 00 00 00 00 00 00 05 dd 3f 80 00   .@...........?..
          321  +|   1888: 00 40 00 00 00 40 a0 00 00 40 c0 00 00 00 00 00   .@...@...@......
          322  +|   1904: 00 00 00 04 4e 40 00 00 00 40 40 00 00 3f 80 00   ....N@...@@..?..
          323  +|   1920: 00 40 00 00 00 00 00 00 00 00 00 04 b2 40 00 00   .@...........@..
          324  +|   1936: 00 40 40 00 00 40 00 00 00 40 40 00 00 00 00 00   .@@..@...@@.....
          325  +|   1952: 00 00 00 05 16 40 00 00 00 40 40 00 00 40 40 00   .....@...@@..@@.
          326  +|   1968: 00 40 80 00 00 00 00 00 00 00 00 05 7a 40 00 00   .@..........z@..
          327  +|   1984: 00 40 40 00 00 40 80 00 00 40 a0 00 00 00 00 00   .@@..@...@......
          328  +|   2000: 00 00 00 05 de 40 00 00 00 40 40 00 00 40 a0 00   .....@...@@..@..
          329  +|   2016: 00 40 c0 00 00 00 00 00 00 00 00 04 4f 40 40 00   .@..........O@@.
          330  +|   2032: 00 40 80 00 00 3f 80 00 00 40 00 00 00 00 00 00   .@...?...@......
          331  +|   2048: 00 00 00 04 b3 40 40 00 00 40 80 00 00 40 00 00   .....@@..@...@..
          332  +|   2064: 00 40 40 00 00 00 00 00 00 00 00 05 17 40 40 00   .@@..........@@.
          333  +|   2080: 00 40 80 00 00 40 40 00 00 40 80 00 00 00 00 00   .@...@@..@......
          334  +|   2096: 00 00 00 05 7b 40 40 00 00 40 80 00 00 40 80 00   .....@@..@...@..
          335  +|   2112: 00 40 a0 00 00 00 00 00 00 00 00 05 df 40 40 00   .@...........@@.
          336  +|   2128: 00 40 80 00 00 40 a0 00 00 40 c0 00 00 00 00 00   .@...@...@......
          337  +|   2144: 00 00 00 03 ec 40 80 00 00 40 a0 00 00 00 00 00   .....@...@......
          338  +|   2160: 00 3f 80 00 00 00 00 00 00 00 00 04 50 40 80 00   .?..........P@..
          339  +|   2176: 00 40 a0 00 00 3f 80 00 00 40 00 00 00 00 00 00   .@...?...@......
          340  +|   2192: 00 00 00 04 b4 40 80 00 00 40 a0 00 00 40 00 00   .....@...@...@..
          341  +|   2208: 00 40 40 00 00 00 00 00 00 00 00 05 18 40 80 00   .@@..........@..
          342  +|   2224: 00 40 a0 00 00 40 40 00 00 40 80 00 00 00 00 00   .@...@@..@......
          343  +|   2240: 00 00 00 05 7c 40 80 00 00 40 a0 00 00 40 80 00   ....|@...@...@..
          344  +|   2256: 00 40 a0 00 00 00 00 00 00 00 00 05 e0 40 80 00   .@...........@..
          345  +|   2272: 00 40 a0 00 00 40 a0 00 00 40 c0 00 00 00 00 00   .@...@...@......
          346  +|   2288: 00 00 00 03 f0 41 00 00 00 41 10 00 00 00 00 00   .....A...A......
          347  +|   2304: 00 3f 80 00 00 00 00 00 00 00 00 04 54 41 00 00   .?..........TA..
          348  +|   2320: 00 41 10 00 00 3f 80 00 00 40 00 00 00 00 00 00   .A...?...@......
          349  +|   2336: 00 00 00 04 b8 41 00 00 00 41 10 00 00 40 00 00   .....A...A...@..
          350  +|   2352: 00 40 40 00 00 00 00 00 00 00 00 05 1c 41 00 00   .@@..........A..
          351  +|   2368: 00 41 10 00 00 40 40 00 00 40 80 00 00 00 00 00   .A...@@..@......
          352  +|   2384: 00 00 00 05 80 41 00 00 00 41 10 00 00 40 80 00   .....A...A...@..
          353  +|   2400: 00 40 a0 00 00 00 00 00 00 00 00 05 e4 41 00 00   .@...........A..
          354  +|   2416: 00 41 10 00 00 40 a0 00 00 40 c0 00 00 00 00 00   .A...@...@......
          355  +|   2432: 00 00 00 06 48 41 00 00 00 41 10 00 00 40 c0 00   ....HA...A...@..
          356  +|   2448: 00 40 e0 00 00 00 00 00 00 00 00 06 ac 41 00 00   .@...........A..
          357  +|   2464: 00 41 10 00 00 40 e0 00 00 41 00 00 00 00 00 00   .A...@...A......
          358  +|   2480: 00 00 00 07 10 41 00 00 00 41 10 00 00 41 00 00   .....A...A...A..
          359  +|   2496: 00 41 10 00 00 00 00 00 00 00 00 03 f1 41 10 00   .A...........A..
          360  +|   2512: 00 41 20 00 00 00 00 00 00 3f 80 00 00 00 00 00   .A ......?......
          361  +|   2528: 00 00 00 04 55 41 10 00 00 41 20 00 00 3f 80 00   ....UA...A ..?..
          362  +|   2544: 00 40 00 00 00 00 00 00 00 00 00 04 b9 41 10 00   .@...........A..
          363  +|   2560: 00 41 20 00 00 40 00 00 00 40 40 00 00 00 00 00   .A ..@...@@.....
          364  +|   2576: 00 00 00 05 1d 41 10 00 00 41 20 00 00 40 40 00   .....A...A ..@@.
          365  +|   2592: 00 40 80 00 00 00 00 00 00 00 00 05 81 41 10 00   .@...........A..
          366  +|   2608: 00 41 20 00 00 40 80 00 00 40 a0 00 00 00 00 00   .A ..@...@......
          367  +|   2624: 00 00 00 05 e5 41 10 00 00 41 20 00 00 40 a0 00   .....A...A ..@..
          368  +|   2640: 00 40 c0 00 00 00 00 00 00 00 00 06 49 41 10 00   .@..........IA..
          369  +|   2656: 00 41 20 00 00 40 c0 00 00 40 e0 00 00 00 00 00   .A ..@...@......
          370  +|   2672: 00 00 00 06 ad 41 10 00 00 41 20 00 00 40 e0 00   .....A...A ..@..
          371  +|   2688: 00 41 00 00 00 00 00 00 00 00 00 07 11 41 10 00   .A...........A..
          372  +|   2704: 00 41 20 00 00 41 00 00 00 41 10 00 00 00 00 00   .A ..A...A......
          373  +|   2848: 00 00 00 00 00 00 00 00 00 00 00 00 00 89 50 01   ..............P.
          374  +|   2864: 04 00 93 24 00 01 00 04 00 00 00 00 00 00 00 03   ...$............
          375  +|   2880: 00 00 00 00 40 80 00 00 00 00 00 00 3f 80 00 00   ....@.......?...
          376  +|   2896: 00 00 00 00 00 00 00 02 00 00 00 00 41 20 00 00   ............A ..
          377  +|   2912: 00 00 00 00 41 10 00 00 00 00 00 00 00 00 00 04   ....A...........
          378  +|   2928: 00 00 00 00 41 20 00 00 40 c0 00 00 41 20 00 00   ....A ..@...A ..
          379  +|   2944: 00 00 00 00 00 00 00 05 40 a0 00 00 41 00 00 00   ........@...A...
          380  +|   2960: 00 00 00 00 41 20 00 00 00 00 00 00 00 00 00 00   ....A ..........
          381  +| page 6 offset 20480
          382  +|      0: 0d 00 00 00 02 06 5a 00 0b 2d 06 5a 00 00 00 00   ......Z..-.Z....
          383  +|   1616: 00 00 00 00 00 00 00 00 00 00 89 50 05 04 00 93   ...........P....
          384  +|   1632: 24 00 00 00 1c 00 00 00 00 00 00 03 ed 40 a0 00   $............@..
          385  +|   1648: 00 40 c0 00 00 00 00 00 00 3f 80 00 00 00 00 00   .@.......?......
          386  +|   1664: 00 00 00 04 51 40 a0 00 00 40 c0 00 00 3f 80 00   ....Q@...@...?..
          387  +|   1680: 00 40 00 00 00 00 00 00 00 00 00 04 b5 40 a0 00   .@...........@..
          388  +|   1696: 00 40 c0 00 00 40 00 00 00 40 40 00 00 00 00 00   .@...@...@@.....
          389  +|   1712: 00 00 00 05 19 40 a0 00 00 40 c0 00 00 40 40 00   .....@...@...@@.
          390  +|   1728: 00 40 80 00 00 00 00 00 00 00 00 05 7d 40 a0 00   .@...........@..
          391  +|   1744: 00 40 c0 00 00 40 80 00 00 40 a0 00 00 00 00 00   .@...@...@......
          392  +|   1760: 00 00 00 05 e1 40 a0 00 00 40 c0 00 00 40 a0 00   .....@...@...@..
          393  +|   1776: 00 40 c0 00 00 00 00 00 00 00 00 06 45 40 a0 00   .@..........E@..
          394  +|   1792: 00 40 c0 00 00 40 c0 00 00 40 e0 00 00 00 00 00   .@...@...@......
          395  +|   1808: 00 00 00 06 a9 40 a0 00 00 40 c0 00 00 40 e0 00   .....@...@...@..
          396  +|   1824: 00 41 00 00 00 00 00 00 00 00 00 07 0d 40 a0 00   .A...........@..
          397  +|   1840: 00 40 c0 00 00 41 00 00 00 41 10 00 00 00 00 00   .@...A...A......
          398  +|   1856: 00 00 00 03 ee 40 c0 00 00 40 e0 00 00 00 00 00   .....@...@......
          399  +|   1872: 00 3f 80 00 00 00 00 00 00 00 00 04 52 40 c0 00   .?..........R@..
          400  +|   1888: 00 40 e0 00 00 3f 80 00 00 40 00 00 00 00 00 00   .@...?...@......
          401  +|   1904: 00 00 00 04 b6 40 c0 00 00 40 e0 00 00 40 00 00   .....@...@...@..
          402  +|   1920: 00 40 40 00 00 00 00 00 00 00 00 05 1a 40 c0 00   .@@..........@..
          403  +|   1936: 00 40 e0 00 00 40 40 00 00 40 80 00 00 00 00 00   .@...@@..@......
          404  +|   1952: 00 00 00 05 7e 40 c0 00 00 40 e0 00 00 40 80 00   ....~@...@...@..
          405  +|   1968: 00 40 a0 00 00 00 00 00 00 00 00 05 e2 40 c0 00   .@...........@..
          406  +|   1984: 00 40 e0 00 00 40 a0 00 00 40 c0 00 00 00 00 00   .@...@...@......
          407  +|   2000: 00 00 00 06 46 40 c0 00 00 40 e0 00 00 40 c0 00   ....F@...@...@..
          408  +|   2016: 00 40 e0 00 00 00 00 00 00 00 00 06 aa 40 c0 00   .@...........@..
          409  +|   2032: 00 40 e0 00 00 40 e0 00 00 41 00 00 00 00 00 00   .@...@...A......
          410  +|   2048: 00 00 00 07 0e 40 c0 00 00 40 e0 00 00 41 00 00   .....@...@...A..
          411  +|   2064: 00 41 10 00 00 00 00 00 00 00 00 03 ef 40 e0 00   .A...........@..
          412  +|   2080: 00 41 00 00 00 00 00 00 00 3f 80 00 00 00 00 00   .A.......?......
          413  +|   2096: 00 00 00 04 53 40 e0 00 00 41 00 00 00 3f 80 00   ....S@...A...?..
          414  +|   2112: 00 40 00 00 00 00 00 00 00 00 00 04 b7 40 e0 00   .@...........@..
          415  +|   2128: 00 41 00 00 00 40 00 00 00 40 40 00 00 00 00 00   .A...@...@@.....
          416  +|   2144: 00 00 00 05 1b 40 e0 00 00 41 00 00 00 40 40 00   .....@...A...@@.
          417  +|   2160: 00 40 80 00 00 00 00 00 00 00 00 05 7f 40 e0 00   .@...........@..
          418  +|   2176: 00 41 00 00 00 40 80 00 00 40 a0 00 00 00 00 00   .A...@...@......
          419  +|   2192: 00 00 00 05 e3 40 e0 00 00 41 00 00 00 40 a0 00   .....@...A...@..
          420  +|   2208: 00 40 c0 00 00 00 00 00 00 00 00 06 47 40 e0 00   .@..........G@..
          421  +|   2224: 00 41 00 00 00 40 c0 00 00 40 e0 00 00 00 00 00   .A...@...@......
          422  +|   2240: 00 00 00 06 ab 40 e0 00 00 41 00 00 00 40 e0 00   .....@...A...@..
          423  +|   2256: 00 41 00 00 00 00 00 00 00 00 00 07 0f 40 e0 00   .A...........@..
          424  +|   2272: 00 41 00 00 00 41 00 00 00 41 10 00 00 00 00 00   .A...A...A......
          425  +|   2288: 00 00 00 07 73 40 e0 00 00 41 00 00 00 41 10 00   ....s@...A...A..
          426  +|   2304: 00 41 20 00 00 00 00 00 00 00 00 00 00 00 00 00   .A .............
          427  +|   2848: 00 00 00 00 00 00 00 00 00 00 00 00 00 89 50 04   ..............P.
          428  +|   2864: 04 00 93 24 00 00 00 18 00 00 00 00 00 00 06 43   ...$...........C
          429  +|   2880: 40 40 00 00 40 80 00 00 40 c0 00 00 40 e0 00 00   @@..@...@...@...
          430  +|   2896: 00 00 00 00 00 00 06 42 40 00 00 00 40 40 00 00   .......B@...@@..
          431  +|   2912: 40 c0 00 00 40 e0 00 00 00 00 00 00 00 00 06 41   @...@..........A
          432  +|   2928: 3f 80 00 00 40 00 00 00 40 c0 00 00 40 e0 00 00   ?...@...@...@...
          433  +|   2944: 00 00 00 00 00 00 06 40 00 00 00 00 3f 80 00 00   .......@....?...
          434  +|   2960: 40 c0 00 00 40 e0 00 00 00 00 00 00 00 00 06 44   @...@..........D
          435  +|   2976: 40 80 00 00 40 a0 00 00 40 c0 00 00 40 e0 00 00   @...@...@...@...
          436  +|   2992: 00 00 00 00 00 00 06 a7 40 40 00 00 40 80 00 00   ........@@..@...
          437  +|   3008: 40 e0 00 00 41 00 00 00 00 00 00 00 00 00 06 a6   @...A...........
          438  +|   3024: 40 00 00 00 40 40 00 00 40 e0 00 00 41 00 00 00   @...@@..@...A...
          439  +|   3040: 00 00 00 00 00 00 06 a5 3f 80 00 00 40 00 00 00   ........?...@...
          440  +|   3056: 40 e0 00 00 41 00 00 00 00 00 00 00 00 00 06 a4   @...A...........
          441  +|   3072: 00 00 00 00 3f 80 00 00 40 e0 00 00 41 00 00 00   ....?...@...A...
          442  +|   3088: 00 00 00 00 00 00 06 a8 40 80 00 00 40 a0 00 00   ........@...@...
          443  +|   3104: 40 e0 00 00 41 00 00 00 00 00 00 00 00 00 07 0a   @...A...........
          444  +|   3120: 40 00 00 00 40 40 00 00 41 00 00 00 41 10 00 00   @...@@..A...A...
          445  +|   3136: 00 00 00 00 00 00 07 09 3f 80 00 00 40 00 00 00   ........?...@...
          446  +|   3152: 41 00 00 00 41 10 00 00 00 00 00 00 00 00 07 08   A...A...........
          447  +|   3168: 00 00 00 00 3f 80 00 00 41 00 00 00 41 10 00 00   ....?...A...A...
          448  +|   3184: 00 00 00 00 00 00 07 0b 40 40 00 00 40 80 00 00   ........@@..@...
          449  +|   3200: 41 00 00 00 41 10 00 00 00 00 00 00 00 00 07 0c   A...A...........
          450  +|   3216: 40 80 00 00 40 a0 00 00 41 00 00 00 41 10 00 00   @...@...A...A...
          451  +|   3232: 00 00 00 00 00 00 07 6e 40 00 00 00 40 40 00 00   .......n@...@@..
          452  +|   3248: 41 10 00 00 41 20 00 00 00 00 00 00 00 00 07 6d   A...A .........m
          453  +|   3264: 3f 80 00 00 40 00 00 00 41 10 00 00 41 20 00 00   ?...@...A...A ..
          454  +|   3280: 00 00 00 00 00 00 07 6c 00 00 00 00 3f 80 00 00   .......l....?...
          455  +|   3296: 41 10 00 00 41 20 00 00 00 00 00 00 00 00 07 6f   A...A .........o
          456  +|   3312: 40 40 00 00 40 80 00 00 41 10 00 00 41 20 00 00   @@..@...A...A ..
          457  +|   3328: 00 00 00 00 00 00 07 70 40 80 00 00 40 a0 00 00   .......p@...@...
          458  +|   3344: 41 10 00 00 41 20 00 00 00 00 00 00 00 00 07 71   A...A .........q
          459  +|   3360: 40 a0 00 00 40 c0 00 00 41 10 00 00 41 20 00 00   @...@...A...A ..
          460  +|   3376: 00 00 00 00 00 00 07 72 40 c0 00 00 40 e0 00 00   .......r@...@...
          461  +|   3392: 41 10 00 00 41 20 00 00 00 00 00 00 00 00 07 74   A...A .........t
          462  +|   3408: 41 00 00 00 41 10 00 00 41 10 00 00 41 20 00 00   A...A...A...A ..
          463  +|   3424: 00 00 00 00 00 00 07 75 41 10 00 00 41 20 00 00   .......uA...A ..
          464  +|   3440: 41 10 00 00 41 20 00 00 00 00 00 00 00 00 00 00   A...A ..........
          465  +| end c1b.db
          466  +  }]
          467  +  catchsql {
          468  +     SELECT rtreecheck('t1');
          469  +  }
          470  +} {1 {SQL logic error}}
          471  +
          472  +do_test rtreefuzz001-200 {
          473  +  sqlite3 db {}
          474  +  db deserialize [decode_hexdb {
          475  +| size 16384 pagesize 4096 filename c3.db
          476  +| page 1 offset 0
          477  +|      0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00   SQLite format 3.
          478  +|     16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 04   .....@  ........
          479  +|     32: 00 00 00 00 01 00 00 00 00 00 00 04 00 00 00 04   ................
          480  +|     48: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00   ................
          481  +|     96: 00 00 00 00 0d 00 00 00 04 0e 9c 00 0f ad 0f 4f   ...............O
          482  +|    112: 0e fc 0e 9c 00 00 00 00 00 00 00 00 00 00 00 00   ................
          483  +|   3728: 00 00 00 00 00 00 00 00 00 00 00 00 5e 04 07 17   ............^...
          484  +|   3744: 1f 1f 01 81 0b 74 61 62 6c 65 74 31 5f 70 61 72   .....tablet1_par
          485  +|   3760: 65 6e 74 74 31 5f 70 61 72 65 6e 74 04 43 52 45   entt1_parent.CRE
          486  +|   3776: 41 54 45 20 54 41 42 4c 45 20 22 74 31 5f 70 61   ATE TABLE .t1_pa
          487  +|   3792: 72 65 6e 74 22 28 6e 6f 64 65 6e 6f 20 49 4e 54   rent.(nodeno INT
          488  +|   3808: 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59   EGER PRIMARY KEY
          489  +|   3824: 2c 70 61 72 65 6e 74 6e 6f 64 65 29 51 03 06 17   ,parentnode)Q...
          490  +|   3840: 1b 1b 01 7b 74 61 62 6c 65 74 31 5f 6e 6f 64 65   ....tablet1_node
          491  +|   3856: 74 31 5f 6e 6f 64 65 03 43 52 45 41 54 45 20 54   t1_node.CREATE T
          492  +|   3872: 41 42 4c 45 20 22 74 31 5f 6e 6f 64 65 22 28 6e   ABLE .t1_node.(n
          493  +|   3888: 6f 64 65 6e 6f 20 49 4e 54 45 47 45 52 20 50 52   odeno INTEGER PR
          494  +|   3904: 49 4d 41 52 59 20 4b 45 59 2c 64 61 74 61 29 5c   IMARY KEY,data).
          495  +|   3920: 02 07 17 1d 1d 01 81 0b 74 61 62 6c 65 74 31 5f   ........tablet1_
          496  +|   3936: 72 6f 77 69 64 74 31 5f 72 6f 77 69 64 02 43 52   rowidt1_rowid.CR
          497  +|   3952: 45 41 54 45 20 54 41 42 4c 45 20 22 74 31 5f 72   EATE TABLE .t1_r
          498  +|   3968: 6f 77 69 64 22 28 72 6f 77 69 64 20 49 4e 54 45   owid.(rowid INTE
          499  +|   3984: 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c   GER PRIMARY KEY,
          500  +|   4000: 6e 6f 64 65 6e 6f 2c 61 30 2c 61 31 29 51 01 07   nodeno,a0,a1)Q..
          501  +|   4016: 17 11 11 08 81 0f 74 61 62 6c 65 74 31 74 31 43   ......tablet1t1C
          502  +|   4032: 52 45 41 54 45 20 56 49 52 54 55 41 4c 20 54 41   REATE VIRTUAL TA
          503  +|   4048: 42 4c 45 20 74 31 20 55 53 49 4e 47 20 72 74 72   BLE t1 USING rtr
          504  +|   4064: 65 65 28 69 64 2c 78 30 2c 78 31 2c 79 30 2c 79   ee(id,x0,x1,y0,y
          505  +|   4080: 31 2c 2b 6c 61 62 65 6c 2c 2b 6f 74 68 65 72 29   1,+label,+other)
          506  +| page 2 offset 4096
          507  +|      0: 0d 00 00 00 0e 0e f7 00 0f e8 0f d0 0f b7 0f 9e   ................
          508  +|     16: 0f 91 0f 81 0f 70 0f 5e 0f 4f 0f 39 0f 29 0f 18   .....p.^.O.9.)..
          509  +|     32: 0f 06 0e f7 00 00 00 00 00 00 00 00 00 00 00 00   ................
          510  +|   3824: 00 00 00 00 00 00 00 0d 0e 05 00 09 1d 00 74 6f   ..............to
          511  +|   3840: 70 20 68 61 6c 66 10 0d 05 00 09 23 00 62 6f 74   p half.....#.bot
          512  +|   3856: 74 6f 6d 20 68 61 6c 66 0f 0c 05 00 09 21 00 72   tom half.....!.r
          513  +|   3872: 69 67 68 74 20 68 61 6c 66 0e 0b 05 00 09 1f 00   ight half.......
          514  +|   3888: 6c 65 66 74 20 68 61 6c 66 14 0a 05 00 09 2b 00   left half.....+.
          515  +|   3904: 74 68 65 20 77 68 6f 6c 65 20 74 68 69 6e 67 0d   the whole thing.
          516  +|   3920: 09 05 00 09 1d 00 74 6f 70 20 65 64 67 65 10 08   ......top edge..
          517  +|   3936: 05 00 09 23 00 62 6f 74 74 6f 6d 20 65 64 67 65   ...#.bottom edge
          518  +|   3952: 0f 07 05 00 09 21 00 72 69 67 68 74 20 65 64 67   .....!.right edg
          519  +|   3968: 65 0e 06 05 00 09 1f 00 6c 65 66 74 20 65 64 67   e.......left edg
          520  +|   3984: 65 0b 05 05 00 09 19 00 63 65 6e 74 65 72 17 04   e.......center..
          521  +|   4000: 05 00 09 31 00 75 70 70 65 72 2d 72 69 67 68 74   ...1.upper-right
          522  +|   4016: 20 63 6f 72 6e 65 72 17 03 05 00 09 31 00 6c 6f    corner.....1.lo
          523  +|   4032: 77 65 72 2d 72 69 67 68 74 27 60 f6 32 6e 65 72   wer-right'`.2ner
          524  +|   4048: 16 02 05 00 09 2f 00 75 70 70 65 72 2d 6c 65 66   ...../.upper-lef
          525  +|   4064: 74 20 63 6f 72 6e 65 72 16 01 05 00 09 2f 00 6c   t corner...../.l
          526  +|   4080: 6f 77 65 72 2d 6c 65 66 74 20 63 6f 72 6e 65 72   ower-left corner
          527  +| page 3 offset 8192
          528  +|      0: 0d 00 00 00 02 0b 2d 00 0b 2d 00 00 00 00 00 00   ......-..-......
          529  +|   2848: 00 00 00 00 00 00 00 00 00 00 00 00 00 89 50 01   ..............P.
          530  +|   2864: 04 00 93 24 00 00 00 0e 00 00 00 00 00 00 00 01   ...$............
          531  +|   2880: 00 00 00 00 41 20 00 00 00 00 00 00 41 20 01 00   ....A ......A ..
          532  +|   2896: 00 00 00 00 00 00 00 02 00 00 00 00 41 00 00 04   ............A...
          533  +|   2912: 2b 40 00 0c 42 c8 00 00 00 00 00 00 00 00 00 03   +@..B...........
          534  +|   2928: 42 b4 00 00 42 c8 00 00 00 00 00 00 41 20 00 00   B...B.......A ..
          535  +|   2944: 00 00 00 00 00 00 00 04 42 b4 00 00 42 c8 00 00   ........B...B...
          536  +|   2960: 42 b4 00 00 42 c8 00 00 00 00 00 00 00 00 00 05   B...B...........
          537  +|   2976: 42 20 00 00 42 70 00 00 42 20 00 00 42 70 00 00   B ..Bp..B ..Bp..
          538  +|   2992: 00 00 00 00 00 00 00 60 00 00 00 04 0a 00 00 00   .......`........
          539  +|   3008: 00 00 00 42 c8 00 00 00 00 00 00 00 00 00 07 42   ...B...........B
          540  +|   3024: be 00 00 42 c8 00 00 00 00 00 00 42 c8 00 00 00   ...B.......B....
          541  +|   3040: 00 00 00 00 00 00 08 00 00 00 00 42 c8 00 00 00   ...........B....
          542  +|   3056: 00 00 00 40 a0 00 00 00 00 00 00 00 00 00 09 00   ...@............
          543  +|   3072: 00 00 00 42 c8 00 00 42 be 00 00 42 c8 00 00 00   ...B...B...B....
          544  +|   3088: 00 00 00 00 00 00 0a 00 00 00 00 42 c8 00 00 00   ...........B....
          545  +|   3104: 00 00 00 42 c8 00 00 00 00 00 00 00 00 00 0b 00   ...B............
          546  +|   3120: 00 00 00 42 48 00 00 00 00 00 04 2c 80 00 00 00   ...BH......,....
          547  +|   3136: 00 00 00 00 00 00 c4 24 c0 00 04 2c 80 00 00 00   .......$...,....
          548  +|   3152: 00 00 04 2c 80 00 00 00 00 00 00 00 00 00 d0 00   ...,............
          549  +|   3168: 00 00 04 2c 80 00 00 00 00 00 04 24 80 00 00 00   ...,.......$....
          550  +|   3184: 00 00 00 00 00 00 e0 00 00 00 04 2c 80 00 04 24   ...........,...$
          551  +|   3200: c0 00 04 2c 00 00 00 00 00 00 00 00 00 00 00 00   ...,............
          552  +| page 4 offset 12288
          553  +|      0: 0d 00 00 00 00 10 00 00 00 00 00 00 00 00 00 00   ................
          554  +| end c3.db
          555  +  }]
          556  +  catchsql {
          557  +    WITH RECURSIVE
          558  +      c1(x) AS (VALUES(0) UNION ALL SELECT x+1 FROM c1 WHERE x<99),
          559  +      c2(y) AS (VALUES(0) UNION ALL SELECT y+1 FROM c2 WHERE y<99)
          560  +    INSERT INTO t1(id, x0,x1,y0,y1,label)
          561  +      SELECT 1000+x+y*100, x, x+1, y, y+1, printf('box-%d,%d',x,y) FROM c1, c2;
          562  +  }
          563  +} {1 {database disk image is malformed}}
          564  +do_test rtreefuzz001-210 {
          565  +  catchsql {
          566  +    SELECT rtreecheck('t1');
          567  +  }
          568  +} {/1 .*corrupt.*/}
          569  +
          570  +do_test rtreefuzz001-300 {
          571  +  sqlite3 db {}
          572  +  db deserialize [decode_hexdb {
          573  +| size 16384 pagesize 4096 filename c4.db
          574  +| page 1 offset 0
          575  +|      0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00   SQLite format 3.
          576  +|     16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 04   .....@  ........
          577  +|     32: 00 00 00 00 00 00 00 00 00 00 00 04 00 00 00 04   ................
          578  +|     96: 00 00 00 00 0d 00 00 00 04 0e 9c 00 0f ad 0f 4f   ...............O
          579  +|    112: 0e fc 0e 9c 00 00 00 00 00 00 00 00 00 00 00 00   ................
          580  +|   3728: 00 00 00 00 00 00 00 00 00 00 00 00 5e 04 07 17   ............^...
          581  +|   3744: 1f 1f 01 81 0b 74 61 62 6c 65 74 31 5f 70 61 72   .....tablet1_par
          582  +|   3760: 65 6e 74 74 31 5f 70 61 72 65 6e 74 04 43 52 45   entt1_parent.CRE
          583  +|   3776: 41 54 45 20 54 41 42 4c 45 20 22 74 31 5f 70 61   ATE TABLE .t1_pa
          584  +|   3792: 72 65 6e 74 22 28 6e 6f 64 65 6e 6f 20 49 4e 54   rent.(nodeno INT
          585  +|   3808: 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59   EGER PRIMARY KEY
          586  +|   3824: 2c 70 61 72 65 6e 74 6e 6f 64 65 29 51 03 06 17   ,parentnode)Q...
          587  +|   3840: 1b 1b 01 7b 74 61 62 6c 65 74 31 5f 6e 6f 64 65   ....tablet1_node
          588  +|   3856: 74 31 5f 6e 6f 64 65 03 43 52 45 41 54 45 20 54   t1_node.CREATE T
          589  +|   3872: 41 42 4c 45 20 22 74 31 5f 6e 6f 64 65 22 28 6e   ABLE .t1_node.(n
          590  +|   3888: 6f 64 65 6e 6f 20 49 4e 54 45 47 45 52 20 50 52   odeno INTEGER PR
          591  +|   3904: 49 4d 41 52 59 20 4b 45 59 2c 64 61 74 61 29 5c   IMARY KEY,data).
          592  +|   3920: 02 07 17 1d 1d 01 81 0b 74 61 62 6c 65 74 31 5f   ........tablet1_
          593  +|   3936: 72 6f 77 69 64 74 31 5f 72 6f 77 69 64 02 43 52   rowidt1_rowid.CR
          594  +|   3952: 45 41 54 45 20 54 41 42 4c 45 20 22 74 31 5f 72   EATE TABLE .t1_r
          595  +|   3968: 6f 77 69 64 22 28 72 6f 77 69 64 20 49 4e 54 45   owid.(rowid INTE
          596  +|   3984: 47 45 72 20 50 52 49 4d 41 52 59 20 4b 45 59 2c   GEr PRIMARY KEY,
          597  +|   4000: 6e 6f 64 65 6e 6f 2c 61 30 2c 61 31 29 51 01 07   nodeno,a0,a1)Q..
          598  +|   4016: 17 11 11 08 81 0f 74 61 62 6c 65 74 31 74 31 43   ......tablet1t1C
          599  +|   4032: 52 45 41 54 45 20 56 49 52 54 55 41 4c 20 54 41   REATE VIRTUAL TA
          600  +|   4048: 42 4c 45 20 74 31 20 55 53 49 4e 47 20 72 74 72   BLE t1 USING rtr
          601  +|   4064: 65 65 28 69 64 2c 78 30 2c 78 31 2c 79 30 2c 79   ee(id,x0,x1,y0,y
          602  +|   4080: 31 2c 2b 6c 61 62 65 6c 2c 2b 6f 74 68 65 72 29   1,+label,+other)
          603  +| page 2 offset 4096
          604  +|      0: 0d 00 00 00 0e 0e f7 00 0f e8 0f 00 fb 70 f9 e0   .............p..
          605  +|     16: f9 10 f8 10 f7 00 f5 e0 f4 f0 f3 90 f2 90 f1 80   ................
          606  +|     32: f0 60 ef 00 00 00 00 00 00 00 00 00 00 00 00 00   .`..............
          607  +|   3824: 00 00 00 00 00 00 00 0d 0e 05 00 09 1d 00 74 6f   ..............to
          608  +|   3840: 70 20 68 61 6c 66 10 0d 05 00 09 23 00 62 6f 74   p half.....#.bot
          609  +|   3856: 74 6f 6d 20 68 61 6c 66 0f 0c 05 00 09 21 00 72   tom half.....!.r
          610  +|   3872: 69 67 68 74 20 68 61 6c 66 0e 0b 05 00 09 1f 00   ight half.......
          611  +|   3888: 6c 65 66 74 20 68 61 6c 66 14 0a 05 00 09 2b 00   left half.....+.
          612  +|   3904: 00 03 98 20 49 98 2f 6c 62 05 74 68 69 6e 67 0d   ... I./lb.thing.
          613  +|   3920: 09 05 00 09 1d 00 74 6f 70 20 65 64 67 65 10 08   ......top edge..
          614  +|   3936: 05 00 09 23 00 62 6f 74 74 6f 6d 20 65 64 67 65   ...#.bottom edge
          615  +|   3952: 0f 07 05 00 09 21 00 72 69 67 68 74 20 65 64 67   .....!.right edg
          616  +|   3968: 65 0e 06 05 00 09 1f 00 6c 65 66 74 20 65 64 67   e.......left edg
          617  +|   3984: 65 0b 05 05 00 09 19 00 63 65 6e 74 65 72 17 04   e.......center..
          618  +|   4000: 05 00 09 31 00 75 70 70 65 72 2d 72 69 67 68 74   ...1.upper-right
          619  +|   4016: 20 63 6f 72 6e 65 72 17 03 05 00 09 31 00 6c 6f    corner.....1.lo
          620  +|   4032: 77 65 72 2d 72 69 67 68 74 20 63 6f 72 6e 65 72   wer-right corner
          621  +|   4048: 16 02 05 00 09 2f 00 75 70 70 65 72 2d 6c 65 66   ...../.upper-lef
          622  +|   4064: 74 20 63 6f 72 6e 65 72 16 01 05 00 09 2f 00 6c   t corner...../.l
          623  +|   4080: 6f 77 65 72 2d 6c 65 66 74 20 63 6f 72 6e 65 72   ower-left corner
          624  +| page 3 offset 8192
          625  +|      0: 0d 00 00 00 01 0b 2d 00 0b 2d 00 00 00 00 00 00   ......-..-......
          626  +|   2848: 00 00 00 00 00 00 00 00 00 00 00 00 00 89 50 01   ..............P.
          627  +|   2864: 04 00 93 24 00 00 00 0e 00 00 00 00 00 00 00 01   ...$............
          628  +|   2880: 00 00 00 04 01 20 00 00 00 00 00 04 12 00 00 00   ..... ..........
          629  +|   2896: 00 00 00 00 00 00 00 23 00 00 00 00 41 20 00 00   .......#....A ..
          630  +|   2912: 42 b4 00 00 42 c8 00 00 00 00 00 00 00 00 00 03   B...B...........
          631  +|   2928: 42 b4 00 00 42 c8 00 00 00 00 00 00 41 20 00 00   B...B.......A ..
          632  +|   2944: 00 00 00 00 00 00 00 04 42 b4 00 00 42 c8 00 00   ........B...B...
          633  +|   2960: 42 b4 00 00 42 c8 00 00 00 00 00 00 00 00 00 05   B...B...........
          634  +|   2976: 42 20 00 00 42 70 00 00 42 20 00 00 42 70 00 00   B ..Bp..B ..Bp..
          635  +|   2992: 00 00 00 00 00 00 00 06 00 00 00 00 40 a0 00 00   ............@...
          636  +|   3008: 00 00 00 04 2c 80 00 00 00 00 00 00 00 00 00 74   ....,..........t
          637  +|   3024: 2b e0 00 04 2c 80 00 04 2c 80 00 00 00 00 00 00   +...,...,.......
          638  +|   3040: 00 00 00 80 00 00 00 04 2c 80 00 00 00 00 00 04   ........,.......
          639  +|   3056: 0a 00 00 00 00 00 b0 80 00 00 04 2c 80 00 04 2b   ...........,...+
          640  +|   3072: e0 00 04 2c 80 00 00 00 00 00 00 00 00 00 a0 00   ...,............
          641  +|   3088: 00 00 04 2c 80 00 00 00 00 00 04 2c 80 00 00 00   ...,.......,....
          642  +|   3104: 00 00 00 00 00 00 b0 00 00 00 04 24 80 00 00 00   ...........$....
          643  +|   3120: 00 00 04 2c 80 00 00 00 00 00 00 00 50 00 91 f0   ...,........P...
          644  +|   3136: 06 c6 56 67 42 06 86 16 c6 61 40 a0 50 00 92 b0   ..VgB....a@.P...
          645  +|   3152: 07 46 86 52 07 76 86 f6 c6 52 07 46 86 96 e6 70   .F.R.v...R.F...p
          646  +|   3168: d0 90 50 00 91 d0 07 46 f7 02 06 56 46 76 51 00   ..P....F...VFvQ.
          647  +|   3184: 80 50 00 92 30 06 26 f7 47 46 f6 d2 06 56 46 76   .P..0.&.GF...VFv
          648  +|   3200: 50 f0 70 50 00 92 10 07 26 96 76 87 42 06 56 46   P.pP....&.v.B.VF
          649  +|   3216: 76 50 e0 60 50 00 91 f0 06 c6 56 67 42 06 56 46   vP.`P.....VgB.VF
          650  +|   3232: 76 50 b0 50 50 00 91 90 06 36 56 e7 46 57 21 70   vP.PP....6V.FW!p
          651  +|   3248: 40 50 00 93 10 07 57 07 06 57 22 d7 26 96 76 87   @P....W..W..&.v.
          652  +|   3264: 42 06 36 f7 26 e6 57 21 70 30 50 00 93 10 06 c6   B.6.&.W!p0P.....
          653  +|   3280: f7 76 57 22 d7 26 96 76 87 42 06 36 f7 26 e6 57   .vW..&.v.B.6.&.W
          654  +|   3296: 21 60 20 50 00 92 f0 07 57 07 06 57 22 d6 c6 56   !` P....W..W...V
          655  +|   3312: 60 00 00 c4 24 c0 00 04 2c 80 00 00 00 00 00 04   `...$...,.......
          656  +|   3328: 2c 80 00 00 00 00 00 00 00 00 00 d0 00 00 00 04   ,...............
          657  +|   3344: 2c 80 00 00 00 00 00 04 24 80 00 00 00 00 00 00   ,.......$.......
          658  +|   3360: 00 00 00 e0 00 00 00 04 2c 80 00 04 24 c0 00 04   ........,...$...
          659  +|   3376: 2c 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ,...............
          660  +| page 4 offset 12288
          661  +|      0: 0d 00 00 00 00 10 00 00 00 00 00 00 00 00 00 00   ................
          662  +| end c4.db
          663  +  }]
          664  +  catchsql {
          665  +    UPDATE t1 SET label='x';
          666  +  }
          667  +} {1 {rtree constraint failed: t1.(y0<=y1)}}
          668  +do_test rtreefuzz001-310 {
          669  +  catchsql {
          670  +    SELECT rtreecheck('t1');
          671  +  }
          672  +} {/1 .*corrupt.*/}
          673  +
          674  +do_test rtreefuzz001-400 {
          675  +  sqlite3 db {}
          676  +  db deserialize [decode_hexdb {
          677  +| size 16384 pagesize 4096 filename c7.db
          678  +| page 1 offset 0
          679  +|      0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00   SQLite format 3.
          680  +|     16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 04   .....@  ........
          681  +|     32: 00 00 00 00 01 00 00 00 00 00 00 04 00 00 00 04   ................
          682  +|     48: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00   ................
          683  +|     96: 00 00 00 00 0d 00 00 00 04 0e 9c 00 0f ad 0f 4f   ...............O
          684  +|    112: 0e fc 0e 9c 00 00 00 00 00 00 00 00 00 00 00 00   ................
          685  +|   3728: 00 00 00 00 00 00 00 00 00 00 00 00 5e 04 07 17   ............^...
          686  +|   3744: 1f 1f 01 81 0b 74 61 62 6c 65 74 31 5f 70 61 72   .....tablet1_par
          687  +|   3760: 65 6e 74 74 31 5f 70 61 72 65 6e 74 04 43 52 45   entt1_parent.CRE
          688  +|   3776: 41 54 45 20 54 41 42 4c 45 20 22 74 31 5f 70 61   ATE TABLE .t1_pa
          689  +|   3792: 72 65 6e 74 22 28 6e 6f 64 65 6e 6f 20 49 4e 54   rent.(nodeno INT
          690  +|   3808: 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59   EGER PRIMARY KEY
          691  +|   3824: 2c 70 61 72 65 6e 74 6e 6f 64 65 29 51 03 06 17   ,parentnode)Q...
          692  +|   3840: 1b 1b 01 7b 74 61 62 6c 65 74 31 5f 6e 6f 64 65   ....tablet1_node
          693  +|   3856: 74 31 5f 6e 6f 64 65 03 43 52 45 41 54 45 20 54   t1_node.CREATE T
          694  +|   3872: 41 42 4c 45 20 22 74 31 5f 6e 6f 64 65 22 28 6e   ABLE .t1_node.(n
          695  +|   3888: 6f 64 65 6e 6f 20 49 4e 54 45 47 45 52 20 50 52   odeno INTEGER PR
          696  +|   3904: 49 4d 41 52 59 20 4b 45 59 2c 64 61 74 61 29 5c   IMARY KEY,data).
          697  +|   3920: 02 07 17 1d 1d 01 81 0b 74 61 62 6c 65 74 31 5f   ........tablet1_
          698  +|   3936: 72 6f 77 69 64 74 31 5f 72 6f 77 69 64 02 43 52   rowidt1_rowid.CR
          699  +|   3952: 45 41 54 45 20 54 41 42 4c 45 20 22 74 31 5f 72   EATE TABLE .t1_r
          700  +|   3968: 6f 77 69 64 22 28 72 6f 77 69 64 20 49 4e 54 45   owid.(rowid INTE
          701  +|   3984: 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c   GER PRIMARY KEY,
          702  +|   4000: 6e 6f 64 65 6e 6f 2c 61 30 2c 61 31 29 51 01 07   nodeno,a0,a1)Q..
          703  +|   4016: 17 11 11 08 81 0f 74 61 62 6c 65 74 31 74 31 43   ......tablet1t1C
          704  +|   4032: 52 45 41 54 45 20 56 49 52 54 55 41 4c 20 54 41   REATE VIRTUAL TA
          705  +|   4048: 42 4c 45 20 74 31 20 55 53 49 4e 47 20 72 74 72   BLE t1 USING rtr
          706  +|   4064: 65 65 28 69 64 2c 78 30 2c 78 31 2c 79 30 2c 79   ee(id,x0,x1,y0,y
          707  +|   4080: 31 2c 2b 6c 61 62 65 6c 2c 2b 6f 74 68 65 72 29   1,+label,+other)
          708  +| page 2 offset 4096
          709  +|      0: 0d 00 00 00 0e 0e f7 00 0f e8 0f d0 0f b7 0f 9e   ................
          710  +|     16: 0f 91 0f 81 0f 70 0f 5e 0f 4f 0f 39 0f 29 0f 18   .....p.^.O.9.)..
          711  +|     32: 0f 06 0e f7 00 00 00 00 00 00 00 00 00 00 00 00   ................
          712  +|   3824: 00 00 00 00 00 00 00 0d 0e 05 00 09 1d 00 74 6f   ..............to
          713  +|   3840: 70 20 68 61 6c 66 10 0d 05 00 09 23 00 62 6f 74   p half.....#.bot
          714  +|   3856: 74 6f 6d 20 68 61 6c 66 0f 0c 05 00 09 21 00 72   tom half.....!.r
          715  +|   3872: 69 67 68 74 20 68 61 6c 66 0e 0b 05 00 09 1f 00   ight half.......
          716  +|   3888: 6c 65 66 74 20 68 61 6c 66 14 0a 05 00 09 2b 00   left half.....+.
          717  +|   3904: 74 68 65 20 77 68 6f 6c 65 20 74 68 69 6e 67 0d   the whole thing.
          718  +|   3920: 09 05 00 09 1d 00 74 6f 70 20 65 64 67 65 10 08   ......top edge..
          719  +|   3936: 05 00 09 23 00 62 6f 74 74 6f 6d 20 65 64 67 65   ...#.bottom edge
          720  +|   3952: 0f 07 05 00 09 21 00 72 69 67 68 74 20 65 64 67   .....!.right edg
          721  +|   3968: 65 0e 06 05 00 09 1f 00 6c 65 66 74 20 65 64 67   e.......left edg
          722  +|   3984: 65 0b 05 05 00 09 19 00 23 65 6e 74 65 72 17 04   e.......#enter..
          723  +|   4000: 05 00 09 31 00 75 70 70 65 72 2d 72 69 67 68 74   ...1.upper-right
          724  +|   4016: 20 63 6f 72 6e 65 72 17 03 05 00 09 31 00 6c 6f    corner.....1.lo
          725  +|   4032: 77 65 72 2d 72 69 67 68 74 20 63 6f 72 6e 65 72   wer-right corner
          726  +|   4048: 16 02 05 00 09 2f 00 75 70 70 65 72 2d 6c 65 66   ...../.upper-lef
          727  +|   4064: 74 20 63 6f 72 6e 65 72 16 01 05 00 09 2f 00 6c   t corner...../.l
          728  +|   4080: 6f 77 65 72 2d 6c 65 66 74 20 63 6f 72 6e 65 72   ower-left corner
          729  +| page 3 offset 8192
          730  +|      0: 0d 00 00 00 02 0b 2d 00 0b 2d 00 00 00 00 00 00   ......-..-......
          731  +|   2848: 00 00 00 00 00 00 00 00 00 00 00 00 00 89 50 01   ..............P.
          732  +|   2864: 04 00 93 24 00 00 00 00 00 00 00 00 08 00 00 00   ...$............
          733  +|   2880: 00 42 c8 00 00 00 00 00 00 40 a0 00 00 00 00 00   .B.......@......
          734  +|   2896: 00 00 00 00 42 c8 00 00 00 00 00 00 00 00 00 07   ....B...........
          735  +|   2912: 42 be 00 00 42 c8 00 00 00 00 00 00 42 c8 00 00   B...B.......B...
          736  +|   2928: 00 00 00 00 00 00 00 08 00 00 00 00 42 c8 00 00   ............B...
          737  +|   2944: 00 00 00 00 40 a0 00 00 00 00 00 00 00 00 00 09   ....@...........
          738  +|   2960: 00 00 00 00 42 c8 00 00 42 be 00 00 42 c8 00 00   ....B...B...B...
          739  +|   2976: 00 00 00 00 00 00 00 0a 00 00 00 00 42 c8 00 00   ............B...
          740  +|   2992: 00 00 00 00 42 c8 00 00 00 00 00 00 00 00 00 0b   ....B...........
          741  +|   3008: 00 00 00 00 42 48 00 00 00 00 00 04 2c 80 00 00   ....BH......,...
          742  +|   3024: 00 00 00 00 00 00 00 c4 00 00 00 00 00 42 c8 00   .............B..
          743  +|   3040: 00 00 00 00 00 00 00 00 07 42 be 00 00 42 c8 00   .........B...B..
          744  +|   3056: 00 00 00 00 00 42 c8 00 00 00 00 00 00 00 00 00   .....B..........
          745  +|   3072: 08 00 00 00 00 42 c8 00 00 00 00 00 00 40 a0 00   .....B.......@..
          746  +|   3088: 00 00 00 00 00 00 00 00 09 00 00 00 00 42 c8 00   .............B..
          747  +|   3104: 00 42 be 00 00 42 c8 00 00 00 00 00 00 00 00 00   .B...B..........
          748  +|   3120: 0a 00 00 00 00 42 c8 00 00 00 00 00 00 42 c8 00   .....B.......B..
          749  +|   3136: 00 00 00 00 00 00 00 00 0b 00 00 00 00 42 48 00   .............BH.
          750  +|   3152: 00 00 00 00 04 2c 80 00 00 00 00 00 00 00 00 00   .....,..........
          751  +|   3168: c4 24 c0 00 04 2c 80 00 00 00 00 00 04 2c 80 00   .$...,.......,..
          752  +|   3184: 00 00 00 00 00 00 00 00 d0 00 00 00 04 2c 80 00   .............,..
          753  +|   3200: 00 00 00 00 04 24 80 00 00 00 00 00 00 00 00 00   .....$..........
          754  +|   3216: e0 00 00 00 04 2c 80 00 04 24 c0 00 04 2c 00 00   .....,...$...,..
          755  +| page 4 offset 12288
          756  +|      0: 0d 00 00 00 00 10 00 00 00 00 00 00 0e 00 00 00   ................
          757  +|     16: 00 42 c8 00 00 42 4c 00 00 42 c8 00 00 00 00 00   .B...BL..B......
          758  +|     32: 00 00 00 0a 00 00 00 00 42 c8 00 00 00 00 00 00   ........B.......
          759  +|     48: 42 c8 00 00 00 00 00 00 00 00 00 0b 00 00 00 00   B...............
          760  +|     64: 42 48 00 00 00 00 00 04 2c 80 00 00 00 00 00 00   BH......,.......
          761  +|     80: 00 00 00 c4 24 c0 00 04 2c 80 00 00 00 00 00 04   ....$...,.......
          762  +|     96: 2c 80 00 00 00 00 00 00 00 00 00 d0 00 00 00 04   ,...............
          763  +|    112: 2c 80 00 00 00 00 00 04 24 80 00 00 00 00 00 00   ,.......$.......
          764  +|    128: 00 00 00 e0 00 00 00 04 2c 80 00 04 24 c0 00 04   ........,...$...
          765  +|    144: 2c 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ,...............
          766  +| end c7.db
          767  +  }]
          768  +  catchsql {
          769  +    WITH RECURSIVE
          770  +      c1(x) AS (VALUES(0) UNION ALL SELECT x+1 FROM c1 WHERE x<8),
          771  +      c2(y) AS (VALUES(0) UNION ALL SELECT y+1 FROM c2 WHERE y<5)
          772  +    INSERT INTO t1(id, x0,x1,y0,y1,label)
          773  +      SELECT 1000+x+y*100, x, x+1, y, y+1, printf('box-%d,%d',x,y) FROM c1, c2;
          774  +  }
          775  +} {1 {database disk image is malformed}}
          776  +
          777  +finish_test

Changes to ext/session/sqlite3session.c.

  1150   1150     int op,                         /* One of SQLITE_UPDATE, INSERT, DELETE */
  1151   1151     sqlite3_session *pSession,      /* Session object pTab is attached to */
  1152   1152     SessionTable *pTab              /* Table that change applies to */
  1153   1153   ){
  1154   1154     int iHash; 
  1155   1155     int bNull = 0; 
  1156   1156     int rc = SQLITE_OK;
  1157         -  SessionStat1Ctx stat1 = {0};
         1157  +  SessionStat1Ctx stat1 = {{0,0,0,0,0},0};
  1158   1158   
  1159   1159     if( pSession->rc ) return;
  1160   1160   
  1161   1161     /* Load table details if required */
  1162   1162     if( sessionInitTable(pSession, pTab) ) return;
  1163   1163   
  1164   1164     /* Check the number of columns in this xPreUpdate call matches the 

Changes to ext/session/sqlite3session.h.

   544    544   **
   545    545   ** If argument pzTab is not NULL, then *pzTab is set to point to a
   546    546   ** nul-terminated utf-8 encoded string containing the name of the table
   547    547   ** affected by the current change. The buffer remains valid until either
   548    548   ** sqlite3changeset_next() is called on the iterator or until the 
   549    549   ** conflict-handler function returns. If pnCol is not NULL, then *pnCol is 
   550    550   ** set to the number of columns in the table affected by the change. If
   551         -** pbIncorrect is not NULL, then *pbIndirect is set to true (1) if the change
          551  +** pbIndirect is not NULL, then *pbIndirect is set to true (1) if the change
   552    552   ** is an indirect change, or false (0) otherwise. See the documentation for
   553    553   ** [sqlite3session_indirect()] for a description of direct and indirect
   554    554   ** changes. Finally, if pOp is not NULL, then *pOp is set to one of 
   555    555   ** [SQLITE_INSERT], [SQLITE_DELETE] or [SQLITE_UPDATE], depending on the 
   556    556   ** type of change that the iterator currently points to.
   557    557   **
   558    558   ** If no error occurs, SQLITE_OK is returned. If an error does occur, an

Changes to main.mk.

   973    973   TEST_EXTENSION = $(SHPREFIX)testloadext.$(SO)
   974    974   $(TEST_EXTENSION): $(TOP)/src/test_loadext.c
   975    975   	$(MKSHLIB) $(TOP)/src/test_loadext.c -o $(TEST_EXTENSION)
   976    976   
   977    977   extensiontest: testfixture$(EXE) $(TEST_EXTENSION)
   978    978   	./testfixture$(EXE) $(TOP)/test/loadext.test
   979    979   
          980  +dbtotxt$(EXE):	$(TOP)/tool/dbtotxt.c
          981  +	$(TCC) -o dbtotxt$(EXE) $(TOP)/tool/dbtotxt.c
          982  +
   980    983   showdb$(EXE):	$(TOP)/tool/showdb.c sqlite3.o
   981    984   	$(TCC) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -o showdb$(EXE) \
   982    985   		$(TOP)/tool/showdb.c sqlite3.o $(THREADLIB)
   983    986   
   984    987   showstat4$(EXE):	$(TOP)/tool/showstat4.c sqlite3.o
   985    988   	$(TCC) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -o showstat4$(EXE) \
   986    989   		$(TOP)/tool/showstat4.c sqlite3.o $(THREADLIB)

Changes to src/alter.c.

    24     24   ** Parameter zName is the name of a table that is about to be altered
    25     25   ** (either with ALTER TABLE ... RENAME TO or ALTER TABLE ... ADD COLUMN).
    26     26   ** If the table is a system table, this function leaves an error message
    27     27   ** in pParse->zErr (system tables may not be altered) and returns non-zero.
    28     28   **
    29     29   ** Or, if zName is not a system table, zero is returned.
    30     30   */
    31         -static int isSystemTable(Parse *pParse, const char *zName){
    32         -  if( 0==sqlite3StrNICmp(zName, "sqlite_", 7) ){
    33         -    sqlite3ErrorMsg(pParse, "table %s may not be altered", zName);
           31  +static int isAlterableTable(Parse *pParse, Table *pTab){
           32  +  if( 0==sqlite3StrNICmp(pTab->zName, "sqlite_", 7) 
           33  +#ifndef SQLITE_OMIT_VIRTUALTABLE
           34  +   || ( (pTab->tabFlags & TF_Shadow) 
           35  +     && (pParse->db->flags & SQLITE_Defensive)
           36  +     && pParse->db->nVdbeExec==0
           37  +   )
           38  +#endif
           39  +  ){
           40  +    sqlite3ErrorMsg(pParse, "table %s may not be altered", pTab->zName);
    34     41       return 1;
    35     42     }
    36     43     return 0;
    37     44   }
    38     45   
    39     46   /*
    40     47   ** Generate code to verify that the schemas of database zDb and, if
................................................................................
   122    129           "there is already another table or index with this name: %s", zName);
   123    130       goto exit_rename_table;
   124    131     }
   125    132   
   126    133     /* Make sure it is not a system table being altered, or a reserved name
   127    134     ** that the table is being renamed to.
   128    135     */
   129         -  if( SQLITE_OK!=isSystemTable(pParse, pTab->zName) ){
          136  +  if( SQLITE_OK!=isAlterableTable(pParse, pTab) ){
   130    137       goto exit_rename_table;
   131    138     }
   132    139     if( SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){ goto
   133    140       exit_rename_table;
   134    141     }
   135    142   
   136    143   #ifndef SQLITE_OMIT_VIEW
................................................................................
   420    427   #endif
   421    428   
   422    429     /* Make sure this is not an attempt to ALTER a view. */
   423    430     if( pTab->pSelect ){
   424    431       sqlite3ErrorMsg(pParse, "Cannot add a column to a view");
   425    432       goto exit_begin_add_column;
   426    433     }
   427         -  if( SQLITE_OK!=isSystemTable(pParse, pTab->zName) ){
          434  +  if( SQLITE_OK!=isAlterableTable(pParse, pTab) ){
   428    435       goto exit_begin_add_column;
   429    436     }
   430    437   
   431    438     assert( pTab->addColOffset>0 );
   432    439     iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
   433    440   
   434    441     /* Put a copy of the Table struct in Parse.pNewTable for the
................................................................................
   522    529     int bQuote;                     /* True to quote the new name */
   523    530   
   524    531     /* Locate the table to be altered */
   525    532     pTab = sqlite3LocateTableItem(pParse, 0, &pSrc->a[0]);
   526    533     if( !pTab ) goto exit_rename_column;
   527    534   
   528    535     /* Cannot alter a system table */
   529         -  if( SQLITE_OK!=isSystemTable(pParse, pTab->zName) ) goto exit_rename_column;
          536  +  if( SQLITE_OK!=isAlterableTable(pParse, pTab) ) goto exit_rename_column;
   530    537     if( SQLITE_OK!=isRealTable(pParse, pTab) ) goto exit_rename_column;
   531    538   
   532    539     /* Which schema holds the table to be altered */  
   533    540     iSchema = sqlite3SchemaToIndex(db, pTab->pSchema);
   534    541     assert( iSchema>=0 );
   535    542     zDb = db->aDb[iSchema].zDbSName;
   536    543   

Changes to src/btree.c.

   656    656     assert( 0==pCur->pKey );
   657    657     assert( cursorHoldsMutex(pCur) );
   658    658   
   659    659     if( pCur->curIntKey ){
   660    660       /* Only the rowid is required for a table btree */
   661    661       pCur->nKey = sqlite3BtreeIntegerKey(pCur);
   662    662     }else{
   663         -    /* For an index btree, save the complete key content */
          663  +    /* For an index btree, save the complete key content. It is possible
          664  +    ** that the current key is corrupt. In that case, it is possible that
          665  +    ** the sqlite3VdbeRecordUnpack() function may overread the buffer by
          666  +    ** up to the size of 1 varint plus 1 8-byte value when the cursor 
          667  +    ** position is restored. Hence the 17 bytes of padding allocated 
          668  +    ** below. */
   664    669       void *pKey;
   665    670       pCur->nKey = sqlite3BtreePayloadSize(pCur);
   666         -    pKey = sqlite3Malloc( pCur->nKey );
          671  +    pKey = sqlite3Malloc( pCur->nKey + 9 + 8 );
   667    672       if( pKey ){
   668    673         rc = sqlite3BtreePayload(pCur, 0, (int)pCur->nKey, pKey);
   669    674         if( rc==SQLITE_OK ){
   670    675           pCur->pKey = pKey;
   671    676         }else{
   672    677           sqlite3_free(pKey);
   673    678         }
................................................................................
   987    992       return;
   988    993     }
   989    994     iPtrmap = PTRMAP_PAGENO(pBt, key);
   990    995     rc = sqlite3PagerGet(pBt->pPager, iPtrmap, &pDbPage, 0);
   991    996     if( rc!=SQLITE_OK ){
   992    997       *pRC = rc;
   993    998       return;
          999  +  }
         1000  +  if( ((char*)sqlite3PagerGetExtra(pDbPage))[0]!=0 ){
         1001  +    /* The first byte of the extra data is the MemPage.isInit byte.
         1002  +    ** If that byte is set, it means this page is also being used
         1003  +    ** as a btree page. */
         1004  +    *pRC = SQLITE_CORRUPT_BKPT;
         1005  +    goto ptrmap_exit;
   994   1006     }
   995   1007     offset = PTRMAP_PTROFFSET(iPtrmap, key);
   996   1008     if( offset<0 ){
   997   1009       *pRC = SQLITE_CORRUPT_BKPT;
   998   1010       goto ptrmap_exit;
   999   1011     }
  1000   1012     assert( offset <= (int)pBt->usableSize-5 );
................................................................................
  1353   1365   */
  1354   1366   static void ptrmapPutOvflPtr(MemPage *pPage, u8 *pCell, int *pRC){
  1355   1367     CellInfo info;
  1356   1368     if( *pRC ) return;
  1357   1369     assert( pCell!=0 );
  1358   1370     pPage->xParseCell(pPage, pCell, &info);
  1359   1371     if( info.nLocal<info.nPayload ){
  1360         -    Pgno ovfl = get4byte(&pCell[info.nSize-4]);
         1372  +    Pgno ovfl;
         1373  +    if( SQLITE_WITHIN(pPage->aDataEnd, pCell, pCell+info.nLocal) ){
         1374  +      *pRC = SQLITE_CORRUPT_BKPT;
         1375  +      return;
         1376  +    }
         1377  +    ovfl = get4byte(&pCell[info.nSize-4]);
  1361   1378       ptrmapPut(pPage->pBt, ovfl, PTRMAP_OVERFLOW1, pPage->pgno, pRC);
  1362   1379     }
  1363   1380   }
  1364   1381   #endif
  1365   1382   
  1366   1383   
  1367   1384   /*
................................................................................
  1408   1425     /* This block handles pages with two or fewer free blocks and nMaxFrag
  1409   1426     ** or fewer fragmented bytes. In this case it is faster to move the
  1410   1427     ** two (or one) blocks of cells using memmove() and add the required
  1411   1428     ** offsets to each pointer in the cell-pointer array than it is to 
  1412   1429     ** reconstruct the entire page.  */
  1413   1430     if( (int)data[hdr+7]<=nMaxFrag ){
  1414   1431       int iFree = get2byte(&data[hdr+1]);
         1432  +
         1433  +    /* If the initial freeblock offset were out of bounds, that would
         1434  +    ** have been detected by btreeInitPage() when it was computing the
         1435  +    ** number of free bytes on the page. */
         1436  +    assert( iFree<=usableSize-4 );
  1415   1437       if( iFree ){
  1416   1438         int iFree2 = get2byte(&data[iFree]);
  1417         -
  1418         -      /* pageFindSlot() has already verified that free blocks are sorted
  1419         -      ** in order of offset within the page, and that no block extends
  1420         -      ** past the end of the page. Provided the two free slots do not 
  1421         -      ** overlap, this guarantees that the memmove() calls below will not
  1422         -      ** overwrite the usableSize byte buffer, even if the database page
  1423         -      ** is corrupt.  */
  1424         -      assert( iFree2==0 || iFree2>iFree );
  1425         -      assert( iFree+get2byte(&data[iFree+2]) <= usableSize );
  1426         -      assert( iFree2==0 || iFree2+get2byte(&data[iFree2+2]) <= usableSize );
  1427         -
         1439  +      if( iFree2>usableSize-4 ) return SQLITE_CORRUPT_PAGE(pPage);
  1428   1440         if( 0==iFree2 || (data[iFree2]==0 && data[iFree2+1]==0) ){
  1429   1441           u8 *pEnd = &data[cellOffset + nCell*2];
  1430   1442           u8 *pAddr;
  1431   1443           int sz2 = 0;
  1432   1444           int sz = get2byte(&data[iFree+2]);
  1433   1445           int top = get2byte(&data[hdr+5]);
  1434   1446           if( top>=iFree ){
  1435   1447             return SQLITE_CORRUPT_PAGE(pPage);
  1436   1448           }
  1437   1449           if( iFree2 ){
  1438         -          assert( iFree+sz<=iFree2 ); /* Verified by pageFindSlot() */
         1450  +          if( iFree+sz>iFree2 ) return SQLITE_CORRUPT_PAGE(pPage);
  1439   1451             sz2 = get2byte(&data[iFree2+2]);
  1440         -          assert( iFree+sz+sz2+iFree2-(iFree+sz) <= usableSize );
         1452  +          if( iFree2+sz2 > usableSize ) return SQLITE_CORRUPT_PAGE(pPage);
  1441   1453             memmove(&data[iFree+sz+sz2], &data[iFree+sz], iFree2-(iFree+sz));
  1442   1454             sz += sz2;
  1443   1455           }
  1444   1456           cbrk = top+sz;
  1445   1457           assert( cbrk+(iFree-top) <= usableSize );
  1446   1458           memmove(&data[cbrk], &data[top], iFree-top);
  1447   1459           for(pAddr=&data[cellOffset]; pAddr<pEnd; pAddr+=2){
................................................................................
  6746   6758     i = get2byte(&aData[hdr+5]);
  6747   6759     memcpy(&pTmp[i], &aData[i], usableSize - i);
  6748   6760   
  6749   6761     pData = pEnd;
  6750   6762     for(i=0; i<nCell; i++){
  6751   6763       u8 *pCell = apCell[i];
  6752   6764       if( SQLITE_WITHIN(pCell,aData,pEnd) ){
         6765  +      if( ((uptr)(pCell+szCell[i]))>(uptr)pEnd ) return SQLITE_CORRUPT_BKPT;
  6753   6766         pCell = &pTmp[pCell - aData];
  6754   6767       }
  6755   6768       pData -= szCell[i];
  6756   6769       put2byte(pCellptr, (pData - aData));
  6757   6770       pCellptr += 2;
  6758   6771       if( pData < pCellptr ) return SQLITE_CORRUPT_BKPT;
  6759   6772       memcpy(pData, pCell, szCell[i]);
................................................................................
  7040   7053     int rc;                              /* Return Code */
  7041   7054     Pgno pgnoNew;                        /* Page number of pNew */
  7042   7055   
  7043   7056     assert( sqlite3_mutex_held(pPage->pBt->mutex) );
  7044   7057     assert( sqlite3PagerIswriteable(pParent->pDbPage) );
  7045   7058     assert( pPage->nOverflow==1 );
  7046   7059   
  7047         -  /* This error condition is now caught prior to reaching this function */
  7048         -  if( NEVER(pPage->nCell==0) ) return SQLITE_CORRUPT_BKPT;
         7060  +  if( pPage->nCell==0 ) return SQLITE_CORRUPT_BKPT;  /* dbfuzz001.test */
  7049   7061   
  7050   7062     /* Allocate a new page. This page will become the right-sibling of 
  7051   7063     ** pPage. Make the parent page writable, so that the new divider cell
  7052   7064     ** may be inserted. If both these operations are successful, proceed.
  7053   7065     */
  7054   7066     rc = allocateBtreePage(pBt, &pNew, &pgnoNew, 0, 0);
  7055   7067   
................................................................................
  8619   8631     **
  8620   8632     ** Or, if the current delete will not cause a rebalance, then the cursor
  8621   8633     ** will be left in CURSOR_SKIPNEXT state pointing to the entry immediately
  8622   8634     ** before or after the deleted entry. In this case set bSkipnext to true.  */
  8623   8635     if( bPreserve ){
  8624   8636       if( !pPage->leaf 
  8625   8637        || (pPage->nFree+cellSizePtr(pPage,pCell)+2)>(int)(pBt->usableSize*2/3)
         8638  +     || pPage->nCell==1  /* See dbfuzz001.test for a test case */
  8626   8639       ){
  8627   8640         /* A b-tree rebalance will be required after deleting this entry.
  8628   8641         ** Save the cursor key.  */
  8629   8642         rc = saveCursorKey(pCur);
  8630   8643         if( rc ) return rc;
  8631   8644       }else{
  8632   8645         bSkipnext = 1;
................................................................................
  9397   9410       N--;
  9398   9411       if( sqlite3PagerGet(pCheck->pPager, (Pgno)iPage, &pOvflPage, 0) ){
  9399   9412         checkAppendMsg(pCheck, "failed to get page %d", iPage);
  9400   9413         break;
  9401   9414       }
  9402   9415       pOvflData = (unsigned char *)sqlite3PagerGetData(pOvflPage);
  9403   9416       if( isFreeList ){
  9404         -      int n = get4byte(&pOvflData[4]);
         9417  +      u32 n = (u32)get4byte(&pOvflData[4]);
  9405   9418   #ifndef SQLITE_OMIT_AUTOVACUUM
  9406   9419         if( pCheck->pBt->autoVacuum ){
  9407   9420           checkPtrmap(pCheck, iPage, PTRMAP_FREEPAGE, 0);
  9408   9421         }
  9409   9422   #endif
  9410         -      if( n>(int)pCheck->pBt->usableSize/4-2 ){
         9423  +      if( n>pCheck->pBt->usableSize/4-2 ){
  9411   9424           checkAppendMsg(pCheck,
  9412   9425              "freelist leaf count too big on page %d", iPage);
  9413   9426           N--;
  9414   9427         }else{
  9415         -        for(i=0; i<n; i++){
         9428  +        for(i=0; i<(int)n; i++){
  9416   9429             Pgno iFreePage = get4byte(&pOvflData[8+i*4]);
  9417   9430   #ifndef SQLITE_OMIT_AUTOVACUUM
  9418   9431             if( pCheck->pBt->autoVacuum ){
  9419   9432               checkPtrmap(pCheck, iFreePage, PTRMAP_FREEPAGE, 0);
  9420   9433             }
  9421   9434   #endif
  9422   9435             checkRef(pCheck, iFreePage);

Changes to src/build.c.

   350    350      && SQLITE_OK!=sqlite3ReadSchema(pParse)
   351    351     ){
   352    352       return 0;
   353    353     }
   354    354   
   355    355     p = sqlite3FindTable(db, zName, zDbase);
   356    356     if( p==0 ){
   357         -    const char *zMsg = flags & LOCATE_VIEW ? "no such view" : "no such table";
   358    357   #ifndef SQLITE_OMIT_VIRTUALTABLE
   359    358       /* If zName is the not the name of a table in the schema created using
   360    359       ** CREATE, then check to see if it is the name of an virtual table that
   361    360       ** can be an eponymous virtual table. */
   362         -    Module *pMod = (Module*)sqlite3HashFind(&db->aModule, zName);
   363         -    if( pMod==0 && sqlite3_strnicmp(zName, "pragma_", 7)==0 ){
   364         -      pMod = sqlite3PragmaVtabRegister(db, zName);
   365         -    }
   366         -    if( pMod && sqlite3VtabEponymousTableInit(pParse, pMod) ){
   367         -      return pMod->pEpoTab;
          361  +    if( pParse->disableVtab==0 ){
          362  +      Module *pMod = (Module*)sqlite3HashFind(&db->aModule, zName);
          363  +      if( pMod==0 && sqlite3_strnicmp(zName, "pragma_", 7)==0 ){
          364  +        pMod = sqlite3PragmaVtabRegister(db, zName);
          365  +      }
          366  +      if( pMod && sqlite3VtabEponymousTableInit(pParse, pMod) ){
          367  +        return pMod->pEpoTab;
          368  +      }
   368    369       }
   369    370   #endif
   370         -    if( (flags & LOCATE_NOERR)==0 ){
   371         -      if( zDbase ){
   372         -        sqlite3ErrorMsg(pParse, "%s: %s.%s", zMsg, zDbase, zName);
   373         -      }else{
   374         -        sqlite3ErrorMsg(pParse, "%s: %s", zMsg, zName);
   375         -      }
   376         -      pParse->checkSchema = 1;
          371  +    if( flags & LOCATE_NOERR ) return 0;
          372  +    pParse->checkSchema = 1;
          373  +  }else if( IsVirtual(p) && pParse->disableVtab ){
          374  +    p = 0;
          375  +  }
          376  +
          377  +  if( p==0 ){
          378  +    const char *zMsg = flags & LOCATE_VIEW ? "no such view" : "no such table";
          379  +    if( zDbase ){
          380  +      sqlite3ErrorMsg(pParse, "%s: %s.%s", zMsg, zDbase, zName);
          381  +    }else{
          382  +      sqlite3ErrorMsg(pParse, "%s: %s", zMsg, zName);
   377    383       }
   378    384     }
   379    385   
   380    386     return p;
   381    387   }
   382    388   
   383    389   /*

Changes to src/expr.c.

   137    137   CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){
   138    138     sqlite3 *db = pParse->db;
   139    139     CollSeq *pColl = 0;
   140    140     Expr *p = pExpr;
   141    141     while( p ){
   142    142       int op = p->op;
   143    143       if( p->flags & EP_Generic ) break;
   144         -    if( (op==TK_AGG_COLUMN || op==TK_COLUMN
   145         -          || op==TK_REGISTER || op==TK_TRIGGER)
          144  +    if( op==TK_REGISTER ) op = p->op2;
          145  +    if( (op==TK_AGG_COLUMN || op==TK_COLUMN || op==TK_TRIGGER)
   146    146        && p->y.pTab!=0
   147    147       ){
   148    148         /* op==TK_REGISTER && p->y.pTab!=0 happens when pExpr was originally
   149    149         ** a TK_COLUMN but was previously evaluated and cached in a register */
   150    150         int j = p->iColumn;
   151    151         if( j>=0 ){
   152    152           const char *zColl = p->y.pTab->aCol[j].zColl;
................................................................................
   154    154         }
   155    155         break;
   156    156       }
   157    157       if( op==TK_CAST || op==TK_UPLUS ){
   158    158         p = p->pLeft;
   159    159         continue;
   160    160       }
   161         -    if( op==TK_COLLATE || (op==TK_REGISTER && p->op2==TK_COLLATE) ){
          161  +    if( op==TK_COLLATE ){
   162    162         pColl = sqlite3GetCollSeq(pParse, ENC(db), 0, p->u.zToken);
   163    163         break;
   164    164       }
   165    165       if( p->flags & EP_Collate ){
   166    166         if( p->pLeft && (p->pLeft->flags & EP_Collate)!=0 ){
   167    167           p = p->pLeft;
   168    168         }else{
................................................................................
   477    477   **
   478    478   ** If pExpr is not a TK_SELECT expression, return 0.
   479    479   */
   480    480   static int exprCodeSubselect(Parse *pParse, Expr *pExpr){
   481    481     int reg = 0;
   482    482   #ifndef SQLITE_OMIT_SUBQUERY
   483    483     if( pExpr->op==TK_SELECT ){
   484         -    reg = sqlite3CodeSubselect(pParse, pExpr, 0, 0);
          484  +    reg = sqlite3CodeSubselect(pParse, pExpr);
   485    485     }
   486    486   #endif
   487    487     return reg;
   488    488   }
   489    489   
   490    490   /*
   491    491   ** Argument pVector points to a vector expression - either a TK_VECTOR
................................................................................
  2108   2108   ** be a small performance hit but is otherwise harmless.  On the other
  2109   2109   ** hand, a false negative (returning FALSE when the result could be NULL)
  2110   2110   ** will likely result in an incorrect answer.  So when in doubt, return
  2111   2111   ** TRUE.
  2112   2112   */
  2113   2113   int sqlite3ExprCanBeNull(const Expr *p){
  2114   2114     u8 op;
  2115         -  while( p->op==TK_UPLUS || p->op==TK_UMINUS ){ p = p->pLeft; }
         2115  +  while( p->op==TK_UPLUS || p->op==TK_UMINUS ){
         2116  +    p = p->pLeft;
         2117  +  }
  2116   2118     op = p->op;
  2117   2119     if( op==TK_REGISTER ) op = p->op2;
  2118   2120     switch( op ){
  2119   2121       case TK_INTEGER:
  2120   2122       case TK_STRING:
  2121   2123       case TK_FLOAT:
  2122   2124       case TK_BLOB:
................................................................................
  2536   2538         pParse->nQueryLoop = 0;
  2537   2539         if( pX->pLeft->iColumn<0 && !ExprHasProperty(pX, EP_xIsSelect) ){
  2538   2540           eType = IN_INDEX_ROWID;
  2539   2541         }
  2540   2542       }else if( prRhsHasNull ){
  2541   2543         *prRhsHasNull = rMayHaveNull = ++pParse->nMem;
  2542   2544       }
  2543         -    sqlite3CodeSubselect(pParse, pX, rMayHaveNull, eType==IN_INDEX_ROWID);
         2545  +    assert( pX->op==TK_IN );
         2546  +    sqlite3CodeRhsOfIN(pParse, pX, eType==IN_INDEX_ROWID);
         2547  +    if( rMayHaveNull ){
         2548  +      sqlite3SetHasNullFlag(v, pX->iTable, rMayHaveNull);
         2549  +    }
  2544   2550       pParse->nQueryLoop = savedNQueryLoop;
  2545   2551     }else{
  2546   2552       pX->iTable = iTab;
  2547   2553     }
  2548   2554   
  2549   2555     if( aiMap && eType!=IN_INDEX_INDEX_ASC && eType!=IN_INDEX_INDEX_DESC ){
  2550   2556       int i, n;
................................................................................
  2620   2626     }else
  2621   2627   #endif
  2622   2628     {
  2623   2629       sqlite3ErrorMsg(pParse, "row value misused");
  2624   2630     }
  2625   2631   }
  2626   2632   
         2633  +#ifndef SQLITE_OMIT_SUBQUERY
  2627   2634   /*
  2628         -** Generate code for scalar subqueries used as a subquery expression, EXISTS,
  2629         -** or IN operators.  Examples:
         2635  +** Generate code that will construct an ephemeral table containing all terms
         2636  +** in the RHS of an IN operator.  The IN operator can be in either of two
         2637  +** forms:
  2630   2638   **
  2631         -**     (SELECT a FROM b)          -- subquery
  2632         -**     EXISTS (SELECT a FROM b)   -- EXISTS subquery
  2633   2639   **     x IN (4,5,11)              -- IN operator with list on right-hand side
  2634   2640   **     x IN (SELECT a FROM b)     -- IN operator with subquery on the right
  2635   2641   **
  2636         -** The pExpr parameter describes the expression that contains the IN
  2637         -** operator or subquery.
  2638         -**
  2639         -** If parameter isRowid is non-zero, then expression pExpr is guaranteed
  2640         -** to be of the form "<rowid> IN (?, ?, ?)", where <rowid> is a reference
  2641         -** to some integer key column of a table B-Tree. In this case, use an
  2642         -** intkey B-Tree to store the set of IN(...) values instead of the usual
  2643         -** (slower) variable length keys B-Tree.
  2644         -**
  2645         -** If rMayHaveNull is non-zero, that means that the operation is an IN
  2646         -** (not a SELECT or EXISTS) and that the RHS might contains NULLs.
  2647         -** All this routine does is initialize the register given by rMayHaveNull
  2648         -** to NULL.  Calling routines will take care of changing this register
  2649         -** value to non-NULL if the RHS is NULL-free.
  2650         -**
  2651         -** For a SELECT or EXISTS operator, return the register that holds the
  2652         -** result.  For a multi-column SELECT, the result is stored in a contiguous
  2653         -** array of registers and the return value is the register of the left-most
  2654         -** result column.  Return 0 for IN operators or if an error occurs.
         2642  +** The pExpr parameter is the IN operator.
         2643  +**
         2644  +** If parameter isRowid is non-zero, then LHS of the IN operator is guaranteed
         2645  +** to be a non-null integer. In this case, the ephemeral table can be an
         2646  +** table B-Tree that keyed by only integers.  The more general cases uses
         2647  +** an index B-Tree which can have arbitrary keys, but is slower to both
         2648  +** read and write.
         2649  +**
         2650  +** If the LHS expression ("x" in the examples) is a column value, or
         2651  +** the SELECT statement returns a column value, then the affinity of that
         2652  +** column is used to build the index keys. If both 'x' and the
         2653  +** SELECT... statement are columns, then numeric affinity is used
         2654  +** if either column has NUMERIC or INTEGER affinity. If neither
         2655  +** 'x' nor the SELECT... statement are columns, then numeric affinity
         2656  +** is used.
         2657  +*/
         2658  +void sqlite3CodeRhsOfIN(
         2659  +  Parse *pParse,          /* Parsing context */
         2660  +  Expr *pExpr,            /* The IN operator */
         2661  +  int isRowid             /* If true, LHS is a rowid */
         2662  +){
         2663  +  int jmpIfDynamic = -1;      /* One-time test address */
         2664  +  int addr;                   /* Address of OP_OpenEphemeral instruction */
         2665  +  Expr *pLeft;                /* the LHS of the IN operator */
         2666  +  KeyInfo *pKeyInfo = 0;      /* Key information */
         2667  +  int nVal;                   /* Size of vector pLeft */
         2668  +  Vdbe *v;                    /* The prepared statement under construction */
         2669  +
         2670  +  v = sqlite3GetVdbe(pParse);
         2671  +  assert( v!=0 );
         2672  +
         2673  +  /* The evaluation of the RHS of IN operator must be repeated every time it
         2674  +  ** is encountered if any of the following is true:
         2675  +  **
         2676  +  **    *  The right-hand side is a correlated subquery
         2677  +  **    *  The right-hand side is an expression list containing variables
         2678  +  **    *  We are inside a trigger
         2679  +  **
         2680  +  ** If all of the above are false, then we can run this code just once
         2681  +  ** save the results, and reuse the same result on subsequent invocations.
         2682  +  */
         2683  +  if( !ExprHasProperty(pExpr, EP_VarSelect) ){
         2684  +    jmpIfDynamic = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
         2685  +  }
         2686  +
         2687  +  /* Check to see if this is a vector IN operator */
         2688  +  pLeft = pExpr->pLeft;
         2689  +  nVal = sqlite3ExprVectorSize(pLeft);
         2690  +  assert( !isRowid || nVal==1 );
         2691  +
         2692  +  /* Construct the ephemeral table that will contain the content of
         2693  +  ** RHS of the IN operator.
         2694  +  */
         2695  +  pExpr->iTable = pParse->nTab++;
         2696  +  addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, 
         2697  +      pExpr->iTable, (isRowid?0:nVal));
         2698  +  pKeyInfo = isRowid ? 0 : sqlite3KeyInfoAlloc(pParse->db, nVal, 1);
         2699  +
         2700  +  if( ExprHasProperty(pExpr, EP_xIsSelect) ){
         2701  +    /* Case 1:     expr IN (SELECT ...)
         2702  +    **
         2703  +    ** Generate code to write the results of the select into the temporary
         2704  +    ** table allocated and opened above.
         2705  +    */
         2706  +    Select *pSelect = pExpr->x.pSelect;
         2707  +    ExprList *pEList = pSelect->pEList;
         2708  +
         2709  +    ExplainQueryPlan((pParse, 1, "%sLIST SUBQUERY",
         2710  +        jmpIfDynamic>=0?"":"CORRELATED "
         2711  +    ));
         2712  +    assert( !isRowid );
         2713  +    /* If the LHS and RHS of the IN operator do not match, that
         2714  +    ** error will have been caught long before we reach this point. */
         2715  +    if( ALWAYS(pEList->nExpr==nVal) ){
         2716  +      SelectDest dest;
         2717  +      int i;
         2718  +      sqlite3SelectDestInit(&dest, SRT_Set, pExpr->iTable);
         2719  +      dest.zAffSdst = exprINAffinity(pParse, pExpr);
         2720  +      pSelect->iLimit = 0;
         2721  +      testcase( pSelect->selFlags & SF_Distinct );
         2722  +      testcase( pKeyInfo==0 ); /* Caused by OOM in sqlite3KeyInfoAlloc() */
         2723  +      if( sqlite3Select(pParse, pSelect, &dest) ){
         2724  +        sqlite3DbFree(pParse->db, dest.zAffSdst);
         2725  +        sqlite3KeyInfoUnref(pKeyInfo);
         2726  +        return;
         2727  +      }
         2728  +      sqlite3DbFree(pParse->db, dest.zAffSdst);
         2729  +      assert( pKeyInfo!=0 ); /* OOM will cause exit after sqlite3Select() */
         2730  +      assert( pEList!=0 );
         2731  +      assert( pEList->nExpr>0 );
         2732  +      assert( sqlite3KeyInfoIsWriteable(pKeyInfo) );
         2733  +      for(i=0; i<nVal; i++){
         2734  +        Expr *p = sqlite3VectorFieldSubexpr(pLeft, i);
         2735  +        pKeyInfo->aColl[i] = sqlite3BinaryCompareCollSeq(
         2736  +            pParse, p, pEList->a[i].pExpr
         2737  +        );
         2738  +      }
         2739  +    }
         2740  +  }else if( ALWAYS(pExpr->x.pList!=0) ){
         2741  +    /* Case 2:     expr IN (exprlist)
         2742  +    **
         2743  +    ** For each expression, build an index key from the evaluation and
         2744  +    ** store it in the temporary table. If <expr> is a column, then use
         2745  +    ** that columns affinity when building index keys. If <expr> is not
         2746  +    ** a column, use numeric affinity.
         2747  +    */
         2748  +    char affinity;            /* Affinity of the LHS of the IN */
         2749  +    int i;
         2750  +    ExprList *pList = pExpr->x.pList;
         2751  +    struct ExprList_item *pItem;
         2752  +    int r1, r2, r3;
         2753  +    affinity = sqlite3ExprAffinity(pLeft);
         2754  +    if( !affinity ){
         2755  +      affinity = SQLITE_AFF_BLOB;
         2756  +    }
         2757  +    if( pKeyInfo ){
         2758  +      assert( sqlite3KeyInfoIsWriteable(pKeyInfo) );
         2759  +      pKeyInfo->aColl[0] = sqlite3ExprCollSeq(pParse, pExpr->pLeft);
         2760  +    }
         2761  +
         2762  +    /* Loop through each expression in <exprlist>. */
         2763  +    r1 = sqlite3GetTempReg(pParse);
         2764  +    r2 = sqlite3GetTempReg(pParse);
         2765  +    if( isRowid ) sqlite3VdbeAddOp4(v, OP_Blob, 0, r2, 0, "", P4_STATIC);
         2766  +    for(i=pList->nExpr, pItem=pList->a; i>0; i--, pItem++){
         2767  +      Expr *pE2 = pItem->pExpr;
         2768  +      int iValToIns;
         2769  +
         2770  +      /* If the expression is not constant then we will need to
         2771  +      ** disable the test that was generated above that makes sure
         2772  +      ** this code only executes once.  Because for a non-constant
         2773  +      ** expression we need to rerun this code each time.
         2774  +      */
         2775  +      if( jmpIfDynamic>=0 && !sqlite3ExprIsConstant(pE2) ){
         2776  +        sqlite3VdbeChangeToNoop(v, jmpIfDynamic);
         2777  +        jmpIfDynamic = -1;
         2778  +      }
         2779  +
         2780  +      /* Evaluate the expression and insert it into the temp table */
         2781  +      if( isRowid && sqlite3ExprIsInteger(pE2, &iValToIns) ){
         2782  +        sqlite3VdbeAddOp3(v, OP_InsertInt, pExpr->iTable, r2, iValToIns);
         2783  +      }else{
         2784  +        r3 = sqlite3ExprCodeTarget(pParse, pE2, r1);
         2785  +        if( isRowid ){
         2786  +          sqlite3VdbeAddOp2(v, OP_MustBeInt, r3,
         2787  +                            sqlite3VdbeCurrentAddr(v)+2);
         2788  +          VdbeCoverage(v);
         2789  +          sqlite3VdbeAddOp3(v, OP_Insert, pExpr->iTable, r2, r3);
         2790  +        }else{
         2791  +          sqlite3VdbeAddOp4(v, OP_MakeRecord, r3, 1, r2, &affinity, 1);
         2792  +          sqlite3VdbeAddOp4Int(v, OP_IdxInsert, pExpr->iTable, r2, r3, 1);
         2793  +        }
         2794  +      }
         2795  +    }
         2796  +    sqlite3ReleaseTempReg(pParse, r1);
         2797  +    sqlite3ReleaseTempReg(pParse, r2);
         2798  +  }
         2799  +  if( pKeyInfo ){
         2800  +    sqlite3VdbeChangeP4(v, addr, (void *)pKeyInfo, P4_KEYINFO);
         2801  +  }
         2802  +  if( jmpIfDynamic>=0 ){
         2803  +    sqlite3VdbeJumpHere(v, jmpIfDynamic);
         2804  +  }
         2805  +}
         2806  +#endif /* SQLITE_OMIT_SUBQUERY */
         2807  +
         2808  +/*
         2809  +** Generate code for scalar subqueries used as a subquery expression
         2810  +** or EXISTS operator:
         2811  +**
         2812  +**     (SELECT a FROM b)          -- subquery
         2813  +**     EXISTS (SELECT a FROM b)   -- EXISTS subquery
         2814  +**
         2815  +** The pExpr parameter is the SELECT or EXISTS operator to be coded.
         2816  +**
         2817  +** The register that holds the result.  For a multi-column SELECT, 
         2818  +** the result is stored in a contiguous array of registers and the
         2819  +** return value is the register of the left-most result column.
         2820  +** Return 0 if an error occurs.
  2655   2821   */
  2656   2822   #ifndef SQLITE_OMIT_SUBQUERY
  2657         -int sqlite3CodeSubselect(
  2658         -  Parse *pParse,          /* Parsing context */
  2659         -  Expr *pExpr,            /* The IN, SELECT, or EXISTS operator */
  2660         -  int rHasNullFlag,       /* Register that records whether NULLs exist in RHS */
  2661         -  int isRowid             /* If true, LHS of IN operator is a rowid */
  2662         -){
  2663         -  int jmpIfDynamic = -1;                      /* One-time test address */
  2664         -  int rReg = 0;                           /* Register storing resulting */
         2823  +int sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){
         2824  +  int jmpIfDynamic = -1;      /* One-time test address */
         2825  +  int rReg = 0;               /* Register storing resulting */
         2826  +  Select *pSel;               /* SELECT statement to encode */
         2827  +  SelectDest dest;            /* How to deal with SELECT result */
         2828  +  int nReg;                   /* Registers to allocate */
         2829  +  Expr *pLimit;               /* New limit expression */
  2665   2830     Vdbe *v = sqlite3GetVdbe(pParse);
  2666         -  if( NEVER(v==0) ) return 0;
         2831  +  assert( v!=0 );
  2667   2832   
  2668         -  /* The evaluation of the IN/EXISTS/SELECT must be repeated every time it
         2833  +  /* The evaluation of the EXISTS/SELECT must be repeated every time it
  2669   2834     ** is encountered if any of the following is true:
  2670   2835     **
  2671   2836     **    *  The right-hand side is a correlated subquery
  2672   2837     **    *  The right-hand side is an expression list containing variables
  2673   2838     **    *  We are inside a trigger
  2674   2839     **
  2675   2840     ** If all of the above are false, then we can run this code just once
  2676   2841     ** save the results, and reuse the same result on subsequent invocations.
  2677   2842     */
  2678   2843     if( !ExprHasProperty(pExpr, EP_VarSelect) ){
  2679   2844       jmpIfDynamic = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
  2680   2845     }
  2681         -
  2682         -  switch( pExpr->op ){
  2683         -    case TK_IN: {
  2684         -      int addr;                   /* Address of OP_OpenEphemeral instruction */
  2685         -      Expr *pLeft = pExpr->pLeft; /* the LHS of the IN operator */
  2686         -      KeyInfo *pKeyInfo = 0;      /* Key information */
  2687         -      int nVal;                   /* Size of vector pLeft */
  2688         -      
  2689         -      nVal = sqlite3ExprVectorSize(pLeft);
  2690         -      assert( !isRowid || nVal==1 );
  2691         -
  2692         -      /* Whether this is an 'x IN(SELECT...)' or an 'x IN(<exprlist>)'
  2693         -      ** expression it is handled the same way.  An ephemeral table is 
  2694         -      ** filled with index keys representing the results from the 
  2695         -      ** SELECT or the <exprlist>.
  2696         -      **
  2697         -      ** If the 'x' expression is a column value, or the SELECT...
  2698         -      ** statement returns a column value, then the affinity of that
  2699         -      ** column is used to build the index keys. If both 'x' and the
  2700         -      ** SELECT... statement are columns, then numeric affinity is used
  2701         -      ** if either column has NUMERIC or INTEGER affinity. If neither
  2702         -      ** 'x' nor the SELECT... statement are columns, then numeric affinity
  2703         -      ** is used.
  2704         -      */
  2705         -      pExpr->iTable = pParse->nTab++;
  2706         -      addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, 
  2707         -          pExpr->iTable, (isRowid?0:nVal));
  2708         -      pKeyInfo = isRowid ? 0 : sqlite3KeyInfoAlloc(pParse->db, nVal, 1);
  2709         -
  2710         -      if( ExprHasProperty(pExpr, EP_xIsSelect) ){
  2711         -        /* Case 1:     expr IN (SELECT ...)
  2712         -        **
  2713         -        ** Generate code to write the results of the select into the temporary
  2714         -        ** table allocated and opened above.
  2715         -        */
  2716         -        Select *pSelect = pExpr->x.pSelect;
  2717         -        ExprList *pEList = pSelect->pEList;
  2718         -
  2719         -        ExplainQueryPlan((pParse, 1, "%sLIST SUBQUERY",
  2720         -            jmpIfDynamic>=0?"":"CORRELATED "
  2721         -        ));
  2722         -        assert( !isRowid );
  2723         -        /* If the LHS and RHS of the IN operator do not match, that
  2724         -        ** error will have been caught long before we reach this point. */
  2725         -        if( ALWAYS(pEList->nExpr==nVal) ){
  2726         -          SelectDest dest;
  2727         -          int i;
  2728         -          sqlite3SelectDestInit(&dest, SRT_Set, pExpr->iTable);
  2729         -          dest.zAffSdst = exprINAffinity(pParse, pExpr);
  2730         -          pSelect->iLimit = 0;
  2731         -          testcase( pSelect->selFlags & SF_Distinct );
  2732         -          testcase( pKeyInfo==0 ); /* Caused by OOM in sqlite3KeyInfoAlloc() */
  2733         -          if( sqlite3Select(pParse, pSelect, &dest) ){
  2734         -            sqlite3DbFree(pParse->db, dest.zAffSdst);
  2735         -            sqlite3KeyInfoUnref(pKeyInfo);
  2736         -            return 0;
  2737         -          }
  2738         -          sqlite3DbFree(pParse->db, dest.zAffSdst);
  2739         -          assert( pKeyInfo!=0 ); /* OOM will cause exit after sqlite3Select() */
  2740         -          assert( pEList!=0 );
  2741         -          assert( pEList->nExpr>0 );
  2742         -          assert( sqlite3KeyInfoIsWriteable(pKeyInfo) );
  2743         -          for(i=0; i<nVal; i++){
  2744         -            Expr *p = sqlite3VectorFieldSubexpr(pLeft, i);
  2745         -            pKeyInfo->aColl[i] = sqlite3BinaryCompareCollSeq(
  2746         -                pParse, p, pEList->a[i].pExpr
  2747         -            );
  2748         -          }
  2749         -        }
  2750         -      }else if( ALWAYS(pExpr->x.pList!=0) ){
  2751         -        /* Case 2:     expr IN (exprlist)
  2752         -        **
  2753         -        ** For each expression, build an index key from the evaluation and
  2754         -        ** store it in the temporary table. If <expr> is a column, then use
  2755         -        ** that columns affinity when building index keys. If <expr> is not
  2756         -        ** a column, use numeric affinity.
  2757         -        */
  2758         -        char affinity;            /* Affinity of the LHS of the IN */
  2759         -        int i;
  2760         -        ExprList *pList = pExpr->x.pList;
  2761         -        struct ExprList_item *pItem;
  2762         -        int r1, r2, r3;
  2763         -        affinity = sqlite3ExprAffinity(pLeft);
  2764         -        if( !affinity ){
  2765         -          affinity = SQLITE_AFF_BLOB;
  2766         -        }
  2767         -        if( pKeyInfo ){
  2768         -          assert( sqlite3KeyInfoIsWriteable(pKeyInfo) );
  2769         -          pKeyInfo->aColl[0] = sqlite3ExprCollSeq(pParse, pExpr->pLeft);
  2770         -        }
  2771         -
  2772         -        /* Loop through each expression in <exprlist>. */
  2773         -        r1 = sqlite3GetTempReg(pParse);
  2774         -        r2 = sqlite3GetTempReg(pParse);
  2775         -        if( isRowid ) sqlite3VdbeAddOp4(v, OP_Blob, 0, r2, 0, "", P4_STATIC);
  2776         -        for(i=pList->nExpr, pItem=pList->a; i>0; i--, pItem++){
  2777         -          Expr *pE2 = pItem->pExpr;
  2778         -          int iValToIns;
  2779         -
  2780         -          /* If the expression is not constant then we will need to
  2781         -          ** disable the test that was generated above that makes sure
  2782         -          ** this code only executes once.  Because for a non-constant
  2783         -          ** expression we need to rerun this code each time.
  2784         -          */
  2785         -          if( jmpIfDynamic>=0 && !sqlite3ExprIsConstant(pE2) ){
  2786         -            sqlite3VdbeChangeToNoop(v, jmpIfDynamic);
  2787         -            jmpIfDynamic = -1;
  2788         -          }
  2789         -
  2790         -          /* Evaluate the expression and insert it into the temp table */
  2791         -          if( isRowid && sqlite3ExprIsInteger(pE2, &iValToIns) ){
  2792         -            sqlite3VdbeAddOp3(v, OP_InsertInt, pExpr->iTable, r2, iValToIns);
  2793         -          }else{
  2794         -            r3 = sqlite3ExprCodeTarget(pParse, pE2, r1);
  2795         -            if( isRowid ){
  2796         -              sqlite3VdbeAddOp2(v, OP_MustBeInt, r3,
  2797         -                                sqlite3VdbeCurrentAddr(v)+2);
  2798         -              VdbeCoverage(v);
  2799         -              sqlite3VdbeAddOp3(v, OP_Insert, pExpr->iTable, r2, r3);
  2800         -            }else{
  2801         -              sqlite3VdbeAddOp4(v, OP_MakeRecord, r3, 1, r2, &affinity, 1);
  2802         -              sqlite3VdbeAddOp4Int(v, OP_IdxInsert, pExpr->iTable, r2, r3, 1);
  2803         -            }
  2804         -          }
  2805         -        }
  2806         -        sqlite3ReleaseTempReg(pParse, r1);
  2807         -        sqlite3ReleaseTempReg(pParse, r2);
  2808         -      }
  2809         -      if( pKeyInfo ){
  2810         -        sqlite3VdbeChangeP4(v, addr, (void *)pKeyInfo, P4_KEYINFO);
  2811         -      }
  2812         -      break;
  2813         -    }
  2814         -
  2815         -    case TK_EXISTS:
  2816         -    case TK_SELECT:
  2817         -    default: {
  2818         -      /* Case 3:    (SELECT ... FROM ...)
  2819         -      **     or:    EXISTS(SELECT ... FROM ...)
  2820         -      **
  2821         -      ** For a SELECT, generate code to put the values for all columns of
  2822         -      ** the first row into an array of registers and return the index of
  2823         -      ** the first register.
  2824         -      **
  2825         -      ** If this is an EXISTS, write an integer 0 (not exists) or 1 (exists)
  2826         -      ** into a register and return that register number.
  2827         -      **
  2828         -      ** In both cases, the query is augmented with "LIMIT 1".  Any 
  2829         -      ** preexisting limit is discarded in place of the new LIMIT 1.
  2830         -      */
  2831         -      Select *pSel;                         /* SELECT statement to encode */
  2832         -      SelectDest dest;                      /* How to deal with SELECT result */
  2833         -      int nReg;                             /* Registers to allocate */
  2834         -      Expr *pLimit;                         /* New limit expression */
  2835         -
  2836         -      testcase( pExpr->op==TK_EXISTS );
  2837         -      testcase( pExpr->op==TK_SELECT );
  2838         -      assert( pExpr->op==TK_EXISTS || pExpr->op==TK_SELECT );
  2839         -      assert( ExprHasProperty(pExpr, EP_xIsSelect) );
  2840         -
  2841         -      pSel = pExpr->x.pSelect;
  2842         -      ExplainQueryPlan((pParse, 1, "%sSCALAR SUBQUERY",
  2843         -            jmpIfDynamic>=0?"":"CORRELATED "));
  2844         -      nReg = pExpr->op==TK_SELECT ? pSel->pEList->nExpr : 1;
  2845         -      sqlite3SelectDestInit(&dest, 0, pParse->nMem+1);
  2846         -      pParse->nMem += nReg;
  2847         -      if( pExpr->op==TK_SELECT ){
  2848         -        dest.eDest = SRT_Mem;
  2849         -        dest.iSdst = dest.iSDParm;
  2850         -        dest.nSdst = nReg;
  2851         -        sqlite3VdbeAddOp3(v, OP_Null, 0, dest.iSDParm, dest.iSDParm+nReg-1);
  2852         -        VdbeComment((v, "Init subquery result"));
  2853         -      }else{
  2854         -        dest.eDest = SRT_Exists;
  2855         -        sqlite3VdbeAddOp2(v, OP_Integer, 0, dest.iSDParm);
  2856         -        VdbeComment((v, "Init EXISTS result"));
  2857         -      }
  2858         -      pLimit = sqlite3ExprAlloc(pParse->db, TK_INTEGER,&sqlite3IntTokens[1], 0);
  2859         -      if( pSel->pLimit ){
  2860         -        sqlite3ExprDelete(pParse->db, pSel->pLimit->pLeft);
  2861         -        pSel->pLimit->pLeft = pLimit;
  2862         -      }else{
  2863         -        pSel->pLimit = sqlite3PExpr(pParse, TK_LIMIT, pLimit, 0);
  2864         -      }
  2865         -      pSel->iLimit = 0;
  2866         -      if( sqlite3Select(pParse, pSel, &dest) ){
  2867         -        return 0;
  2868         -      }
  2869         -      rReg = dest.iSDParm;
  2870         -      ExprSetVVAProperty(pExpr, EP_NoReduce);
  2871         -      break;
  2872         -    }
  2873         -  }
  2874         -
  2875         -  if( rHasNullFlag ){
  2876         -    sqlite3SetHasNullFlag(v, pExpr->iTable, rHasNullFlag);
  2877         -  }
         2846  +  
         2847  +  /* For a SELECT, generate code to put the values for all columns of
         2848  +  ** the first row into an array of registers and return the index of
         2849  +  ** the first register.
         2850  +  **
         2851  +  ** If this is an EXISTS, write an integer 0 (not exists) or 1 (exists)
         2852  +  ** into a register and return that register number.
         2853  +  **
         2854  +  ** In both cases, the query is augmented with "LIMIT 1".  Any 
         2855  +  ** preexisting limit is discarded in place of the new LIMIT 1.
         2856  +  */
         2857  +  testcase( pExpr->op==TK_EXISTS );
         2858  +  testcase( pExpr->op==TK_SELECT );
         2859  +  assert( pExpr->op==TK_EXISTS || pExpr->op==TK_SELECT );
         2860  +  assert( ExprHasProperty(pExpr, EP_xIsSelect) );
         2861  +
         2862  +  pSel = pExpr->x.pSelect;
         2863  +  ExplainQueryPlan((pParse, 1, "%sSCALAR SUBQUERY",
         2864  +        jmpIfDynamic>=0?"":"CORRELATED "));
         2865  +  nReg = pExpr->op==TK_SELECT ? pSel->pEList->nExpr : 1;
         2866  +  sqlite3SelectDestInit(&dest, 0, pParse->nMem+1);
         2867  +  pParse->nMem += nReg;
         2868  +  if( pExpr->op==TK_SELECT ){
         2869  +    dest.eDest = SRT_Mem;
         2870  +    dest.iSdst = dest.iSDParm;
         2871  +    dest.nSdst = nReg;
         2872  +    sqlite3VdbeAddOp3(v, OP_Null, 0, dest.iSDParm, dest.iSDParm+nReg-1);
         2873  +    VdbeComment((v, "Init subquery result"));
         2874  +  }else{
         2875  +    dest.eDest = SRT_Exists;
         2876  +    sqlite3VdbeAddOp2(v, OP_Integer, 0, dest.iSDParm);
         2877  +    VdbeComment((v, "Init EXISTS result"));
         2878  +  }
         2879  +  pLimit = sqlite3ExprAlloc(pParse->db, TK_INTEGER,&sqlite3IntTokens[1], 0);
         2880  +  if( pSel->pLimit ){
         2881  +    sqlite3ExprDelete(pParse->db, pSel->pLimit->pLeft);
         2882  +    pSel->pLimit->pLeft = pLimit;
         2883  +  }else{
         2884  +    pSel->pLimit = sqlite3PExpr(pParse, TK_LIMIT, pLimit, 0);
         2885  +  }
         2886  +  pSel->iLimit = 0;
         2887  +  if( sqlite3Select(pParse, pSel, &dest) ){
         2888  +    return 0;
         2889  +  }
         2890  +  rReg = dest.iSDParm;
         2891  +  ExprSetVVAProperty(pExpr, EP_NoReduce);
  2878   2892   
  2879   2893     if( jmpIfDynamic>=0 ){
  2880   2894       sqlite3VdbeJumpHere(v, jmpIfDynamic);
  2881   2895     }
  2882   2896   
  2883   2897     return rReg;
  2884   2898   }
................................................................................
  3337   3351       iResult = sqlite3ExprCodeTemp(pParse, p, piFreeable);
  3338   3352     }else{
  3339   3353       *piFreeable = 0;
  3340   3354       if( p->op==TK_SELECT ){
  3341   3355   #if SQLITE_OMIT_SUBQUERY
  3342   3356         iResult = 0;
  3343   3357   #else
  3344         -      iResult = sqlite3CodeSubselect(pParse, p, 0, 0);
         3358  +      iResult = sqlite3CodeSubselect(pParse, p);
  3345   3359   #endif
  3346   3360       }else{
  3347   3361         int i;
  3348   3362         iResult = pParse->nMem+1;
  3349   3363         pParse->nMem += nResult;
  3350   3364         for(i=0; i<nResult; i++){
  3351   3365           sqlite3ExprCodeFactorable(pParse, p->x.pList->a[i].pExpr, i+iResult);
................................................................................
  3811   3825       case TK_SELECT: {
  3812   3826         int nCol;
  3813   3827         testcase( op==TK_EXISTS );
  3814   3828         testcase( op==TK_SELECT );
  3815   3829         if( op==TK_SELECT && (nCol = pExpr->x.pSelect->pEList->nExpr)!=1 ){
  3816   3830           sqlite3SubselectError(pParse, nCol, 1);
  3817   3831         }else{
  3818         -        return sqlite3CodeSubselect(pParse, pExpr, 0, 0);
         3832  +        return sqlite3CodeSubselect(pParse, pExpr);
  3819   3833         }
  3820   3834         break;
  3821   3835       }
  3822   3836       case TK_SELECT_COLUMN: {
  3823   3837         int n;
  3824   3838         if( pExpr->pLeft->iTable==0 ){
  3825         -        pExpr->pLeft->iTable = sqlite3CodeSubselect(pParse, pExpr->pLeft, 0, 0);
         3839  +        pExpr->pLeft->iTable = sqlite3CodeSubselect(pParse, pExpr->pLeft);
  3826   3840         }
  3827   3841         assert( pExpr->iTable==0 || pExpr->pLeft->op==TK_SELECT );
  3828   3842         if( pExpr->iTable
  3829   3843          && pExpr->iTable!=(n = sqlite3ExprVectorSize(pExpr->pLeft)) 
  3830   3844         ){
  3831   3845           sqlite3ErrorMsg(pParse, "%d columns assigned %d values",
  3832   3846                                   pExpr->iTable, n);
................................................................................
  4741   4755     combinedFlags = pA->flags | pB->flags;
  4742   4756     if( combinedFlags & EP_IntValue ){
  4743   4757       if( (pA->flags&pB->flags&EP_IntValue)!=0 && pA->u.iValue==pB->u.iValue ){
  4744   4758         return 0;
  4745   4759       }
  4746   4760       return 2;
  4747   4761     }
  4748         -  if( pA->op!=pB->op ){
         4762  +  if( pA->op!=pB->op || pA->op==TK_RAISE ){
  4749   4763       if( pA->op==TK_COLLATE && sqlite3ExprCompare(pParse, pA->pLeft,pB,iTab)<2 ){
  4750   4764         return 1;
  4751   4765       }
  4752   4766       if( pB->op==TK_COLLATE && sqlite3ExprCompare(pParse, pA,pB->pLeft,iTab)<2 ){
  4753   4767         return 1;
  4754   4768       }
  4755   4769       return 2;
................................................................................
  4774   4788       }else if( pA->op==TK_COLLATE ){
  4775   4789         if( sqlite3_stricmp(pA->u.zToken,pB->u.zToken)!=0 ) return 2;
  4776   4790       }else if( strcmp(pA->u.zToken,pB->u.zToken)!=0 ){
  4777   4791         return 2;
  4778   4792       }
  4779   4793     }
  4780   4794     if( (pA->flags & EP_Distinct)!=(pB->flags & EP_Distinct) ) return 2;
  4781         -  if( ALWAYS((combinedFlags & EP_TokenOnly)==0) ){
         4795  +  if( (combinedFlags & EP_TokenOnly)==0 ){
  4782   4796       if( combinedFlags & EP_xIsSelect ) return 2;
  4783   4797       if( (combinedFlags & EP_FixedCol)==0
  4784   4798        && sqlite3ExprCompare(pParse, pA->pLeft, pB->pLeft, iTab) ) return 2;
  4785   4799       if( sqlite3ExprCompare(pParse, pA->pRight, pB->pRight, iTab) ) return 2;
  4786   4800       if( sqlite3ExprListCompare(pA->x.pList, pB->x.pList, iTab) ) return 2;
  4787         -    assert( (combinedFlags & EP_Reduced)==0 );
  4788         -    if( pA->op!=TK_STRING && pA->op!=TK_TRUEFALSE ){
         4801  +    if( pA->op!=TK_STRING
         4802  +     && pA->op!=TK_TRUEFALSE
         4803  +     && (combinedFlags & EP_Reduced)==0
         4804  +    ){
  4789   4805         if( pA->iColumn!=pB->iColumn ) return 2;
  4790   4806         if( pA->iTable!=pB->iTable 
  4791   4807          && (pA->iTable!=iTab || NEVER(pB->iTable>=0)) ) return 2;
  4792   4808       }
  4793   4809     }
  4794   4810     return 0;
  4795   4811   }

Changes to src/fkey.c.

   598    598     ** to the WHERE clause that prevent this entry from being scanned.
   599    599     ** The added WHERE clause terms are like this:
   600    600     **
   601    601     **     $current_rowid!=rowid
   602    602     **     NOT( $current_a==a AND $current_b==b AND ... )
   603    603     **
   604    604     ** The first form is used for rowid tables.  The second form is used
   605         -  ** for WITHOUT ROWID tables.  In the second form, the primary key is
   606         -  ** (a,b,...)
          605  +  ** for WITHOUT ROWID tables. In the second form, the *parent* key is
          606  +  ** (a,b,...). Either the parent or primary key could be used to 
          607  +  ** uniquely identify the current row, but the parent key is more convenient
          608  +  ** as the required values have already been loaded into registers
          609  +  ** by the caller.
   607    610     */
   608    611     if( pTab==pFKey->pFrom && nIncr>0 ){
   609    612       Expr *pNe;                    /* Expression (pLeft != pRight) */
   610    613       Expr *pLeft;                  /* Value from parent table row */
   611    614       Expr *pRight;                 /* Column ref to child table */
   612    615       if( HasRowid(pTab) ){
   613    616         pLeft = exprTableRegister(pParse, pTab, regData, -1);
   614    617         pRight = exprTableColumn(db, pTab, pSrc->a[0].iCursor, -1);
   615    618         pNe = sqlite3PExpr(pParse, TK_NE, pLeft, pRight);
   616    619       }else{
   617    620         Expr *pEq, *pAll = 0;
   618         -      Index *pPk = sqlite3PrimaryKeyIndex(pTab);
   619    621         assert( pIdx!=0 );
   620         -      for(i=0; i<pPk->nKeyCol; i++){
          622  +      for(i=0; i<pIdx->nKeyCol; i++){
   621    623           i16 iCol = pIdx->aiColumn[i];
   622    624           assert( iCol>=0 );
   623    625           pLeft = exprTableRegister(pParse, pTab, regData, iCol);
   624         -        pRight = exprTableColumn(db, pTab, pSrc->a[0].iCursor, iCol);
   625         -        pEq = sqlite3PExpr(pParse, TK_EQ, pLeft, pRight);
          626  +        pRight = sqlite3Expr(db, TK_ID, pTab->aCol[iCol].zName);
          627  +        pEq = sqlite3PExpr(pParse, TK_IS, pLeft, pRight);
   626    628           pAll = sqlite3ExprAnd(db, pAll, pEq);
   627    629         }
   628    630         pNe = sqlite3PExpr(pParse, TK_NOT, pAll, 0);
   629    631       }
   630    632       pWhere = sqlite3ExprAnd(db, pWhere, pNe);
   631    633     }
   632    634   

Changes to src/insert.c.

  1348   1348         onError = OE_Abort;
  1349   1349       }
  1350   1350       if( onError==OE_Replace && pTab->aCol[i].pDflt==0 ){
  1351   1351         onError = OE_Abort;
  1352   1352       }
  1353   1353       assert( onError==OE_Rollback || onError==OE_Abort || onError==OE_Fail
  1354   1354           || onError==OE_Ignore || onError==OE_Replace );
         1355  +    addr1 = 0;
  1355   1356       switch( onError ){
         1357  +      case OE_Replace: {
         1358  +        assert( onError==OE_Replace );
         1359  +        addr1 = sqlite3VdbeMakeLabel(v);
         1360  +        sqlite3VdbeAddOp2(v, OP_NotNull, regNewData+1+i, addr1);
         1361  +          VdbeCoverage(v);
         1362  +        sqlite3ExprCode(pParse, pTab->aCol[i].pDflt, regNewData+1+i);
         1363  +        sqlite3VdbeAddOp2(v, OP_NotNull, regNewData+1+i, addr1);
         1364  +          VdbeCoverage(v);
         1365  +        onError = OE_Abort;
         1366  +        /* Fall through into the OE_Abort case to generate code that runs
         1367  +        ** if both the input and the default value are NULL */
         1368  +      }
  1356   1369         case OE_Abort:
  1357   1370           sqlite3MayAbort(pParse);
  1358   1371           /* Fall through */
  1359   1372         case OE_Rollback:
  1360   1373         case OE_Fail: {
  1361   1374           char *zMsg = sqlite3MPrintf(db, "%s.%s", pTab->zName,
  1362   1375                                       pTab->aCol[i].zName);
  1363   1376           sqlite3VdbeAddOp3(v, OP_HaltIfNull, SQLITE_CONSTRAINT_NOTNULL, onError,
  1364   1377                             regNewData+1+i);
  1365   1378           sqlite3VdbeAppendP4(v, zMsg, P4_DYNAMIC);
  1366   1379           sqlite3VdbeChangeP5(v, P5_ConstraintNotNull);
  1367   1380           VdbeCoverage(v);
  1368         -        break;
  1369         -      }
  1370         -      case OE_Ignore: {
  1371         -        sqlite3VdbeAddOp2(v, OP_IsNull, regNewData+1+i, ignoreDest);
  1372         -        VdbeCoverage(v);
         1381  +        if( addr1 ) sqlite3VdbeResolveLabel(v, addr1);
  1373   1382           break;
  1374   1383         }
  1375   1384         default: {
  1376         -        assert( onError==OE_Replace );
  1377         -        addr1 = sqlite3VdbeAddOp1(v, OP_NotNull, regNewData+1+i);
  1378         -           VdbeCoverage(v);
  1379         -        sqlite3ExprCode(pParse, pTab->aCol[i].pDflt, regNewData+1+i);
  1380         -        sqlite3VdbeJumpHere(v, addr1);
         1385  +        assert( onError==OE_Ignore );
         1386  +        sqlite3VdbeAddOp2(v, OP_IsNull, regNewData+1+i, ignoreDest);
         1387  +        VdbeCoverage(v);
  1381   1388           break;
  1382   1389         }
  1383   1390       }
  1384   1391     }
  1385   1392   
  1386   1393     /* Test all CHECK constraints
  1387   1394     */

Changes to src/pcache1.c.

   473    473   
   474    474   /*
   475    475   ** Malloc function used by SQLite to obtain space from the buffer configured
   476    476   ** using sqlite3_config(SQLITE_CONFIG_PAGECACHE) option. If no such buffer
   477    477   ** exists, this function falls back to sqlite3Malloc().
   478    478   */
   479    479   void *sqlite3PageMalloc(int sz){
          480  +  /* During rebalance operations on a corrupt database file, it is sometimes
          481  +  ** (rarely) possible to overread the temporary page buffer by a few bytes.
          482  +  ** Enlarge the allocation slightly so that this does not cause problems. */
   480    483     return pcache1Alloc(sz);
   481    484   }
   482    485   
   483    486   /*
   484    487   ** Free an allocated buffer obtained from sqlite3PageMalloc().
   485    488   */
   486    489   void sqlite3PageFree(void *p){

Changes to src/prepare.c.

   541    541     /* For a long-term use prepared statement avoid the use of
   542    542     ** lookaside memory.
   543    543     */
   544    544     if( prepFlags & SQLITE_PREPARE_PERSISTENT ){
   545    545       sParse.disableLookaside++;
   546    546       db->lookaside.bDisable++;
   547    547     }
          548  +  sParse.disableVtab = (prepFlags & SQLITE_PREPARE_NO_VTAB)!=0;
   548    549   
   549    550     /* Check to verify that it is possible to get a read lock on all
   550    551     ** database schemas.  The inability to get a read lock indicates that
   551    552     ** some other database connection is holding a write-lock, which in
   552    553     ** turn means that the other connection has made uncommitted changes
   553    554     ** to the schema.
   554    555     **

Changes to src/resolve.c.

    76     76     db = pParse->db;
    77     77     pDup = sqlite3ExprDup(db, pOrig, 0);
    78     78     if( pDup!=0 ){
    79     79       if( zType[0]!='G' ) incrAggFunctionDepth(pDup, nSubquery);
    80     80       if( pExpr->op==TK_COLLATE ){
    81     81         pDup = sqlite3ExprAddCollateString(pParse, pDup, pExpr->u.zToken);
    82     82       }
    83         -//    ExprSetProperty(pDup, EP_Alias);
    84     83   
    85     84       /* Before calling sqlite3ExprDelete(), set the EP_Static flag. This 
    86     85       ** prevents ExprDelete() from deleting the Expr structure itself,
    87     86       ** allowing it to be repopulated by the memcpy() on the following line.
    88     87       ** The pExpr->u.zToken might point into memory that will be freed by the
    89     88       ** sqlite3DbFree(db, pDup) on the last line of this block, so be sure to
    90     89       ** make a copy of the token before doing the sqlite3DbFree().

Changes to src/shell.c.in.

  1007   1007     u8 openMode;           /* SHELL_OPEN_NORMAL, _APPENDVFS, or _ZIPFILE */
  1008   1008     u8 doXdgOpen;          /* Invoke start/open/xdg-open in output_reset() */
  1009   1009     u8 nEqpLevel;          /* Depth of the EQP output graph */
  1010   1010     u8 eTraceType;         /* SHELL_TRACE_* value for type of trace */
  1011   1011     unsigned mEqpLines;    /* Mask of veritical lines in the EQP output graph */
  1012   1012     int outCount;          /* Revert to stdout when reaching zero */
  1013   1013     int cnt;               /* Number of records displayed so far */
         1014  +  int lineno;            /* Line number of last line read from in */
         1015  +  FILE *in;              /* Read commands from this stream */
  1014   1016     FILE *out;             /* Write results here */
  1015   1017     FILE *traceOut;        /* Output for sqlite3_trace() */
  1016   1018     int nErr;              /* Number of errors seen */
  1017   1019     int mode;              /* An output mode setting */
  1018   1020     int modePrior;         /* Saved mode */
  1019   1021     int cMode;             /* temporary output mode for the current query */
  1020   1022     int normalMode;        /* Output mode before ".explain on" */
................................................................................
  1062   1064   */
  1063   1065   #define SHELL_OPEN_UNSPEC      0      /* No open-mode specified */
  1064   1066   #define SHELL_OPEN_NORMAL      1      /* Normal database file */
  1065   1067   #define SHELL_OPEN_APPENDVFS   2      /* Use appendvfs */
  1066   1068   #define SHELL_OPEN_ZIPFILE     3      /* Use the zipfile virtual table */
  1067   1069   #define SHELL_OPEN_READONLY    4      /* Open a normal database read-only */
  1068   1070   #define SHELL_OPEN_DESERIALIZE 5      /* Open using sqlite3_deserialize() */
         1071  +#define SHELL_OPEN_HEXDB       6      /* Use "dbtotxt" output as data source */
  1069   1072   
  1070   1073   /* Allowed values for ShellState.eTraceType
  1071   1074   */
  1072   1075   #define SHELL_TRACE_PLAIN      0      /* Show input SQL text */
  1073   1076   #define SHELL_TRACE_EXPANDED   1      /* Show expanded SQL text */
  1074   1077   #define SHELL_TRACE_NORMALIZED 2      /* Show normalized SQL text */
  1075   1078   
................................................................................
  3440   3443     "       -e    Invoke system text editor",
  3441   3444     "       -x    Open in a spreadsheet",
  3442   3445     ".open ?OPTIONS? ?FILE?   Close existing database and reopen FILE",
  3443   3446     "     Options:",
  3444   3447     "        --append        Use appendvfs to append database to the end of FILE",
  3445   3448   #ifdef SQLITE_ENABLE_DESERIALIZE
  3446   3449     "        --deserialize   Load into memory useing sqlite3_deserialize()",
         3450  +  "        --hexdb         Load the output of \"dbtotxt\" as an in-memory database",
  3447   3451   #endif
  3448   3452     "        --new           Initialize FILE to an empty database",
  3449   3453     "        --readonly      Open FILE readonly",
  3450   3454     "        --zip           FILE is a ZIP archive",
  3451   3455     ".output ?FILE?           Send output to FILE or stdout if FILE is omitted",
  3452   3456     "     If FILE begins with '|' then open it as a pipe.",
  3453   3457     ".print STRING...         Print literal STRING",
................................................................................
  3589   3593       }
  3590   3594       sqlite3_free(zPat);
  3591   3595     }
  3592   3596     return n;
  3593   3597   }
  3594   3598   
  3595   3599   /* Forward reference */
  3596         -static int process_input(ShellState *p, FILE *in);
         3600  +static int process_input(ShellState *p);
  3597   3601   
  3598   3602   /*
  3599   3603   ** Read the content of file zName into memory obtained from sqlite3_malloc64()
  3600   3604   ** and return a pointer to the buffer. The caller is responsible for freeing
  3601   3605   ** the memory.
  3602   3606   **
  3603   3607   ** If parameter pnByte is not NULL, (*pnByte) is set to the number of bytes
................................................................................
  3719   3723         rc = SHELL_OPEN_ZIPFILE;
  3720   3724       }
  3721   3725     }
  3722   3726     fclose(f);
  3723   3727     return rc;  
  3724   3728   }
  3725   3729   
         3730  +#ifdef SQLITE_ENABLE_DESERIALIZE
         3731  +/*
         3732  +** Reconstruct an in-memory database using the output from the "dbtotxt"
         3733  +** program.  Read content from the file in p->zDbFilename.  If p->zDbFilename
         3734  +** is 0, then read from standard input.
         3735  +*/
         3736  +static unsigned char *readHexDb(ShellState *p, int *pnData){
         3737  +  unsigned char *a = 0;
         3738  +  int nLine;
         3739  +  int n = 0;
         3740  +  int pgsz = 0;
         3741  +  int iOffset = 0;
         3742  +  int j, k;
         3743  +  int rc;
         3744  +  FILE *in;
         3745  +  unsigned char x[16];
         3746  +  char zLine[1000];
         3747  +  if( p->zDbFilename ){
         3748  +    in = fopen(p->zDbFilename, "r");
         3749  +    if( in==0 ){
         3750  +      utf8_printf(stderr, "cannot open \"%s\" for reading\n", p->zDbFilename);
         3751  +      return 0;
         3752  +    }
         3753  +    nLine = 0;
         3754  +  }else{
         3755  +    in = p->in;
         3756  +    nLine = p->lineno;
         3757  +  }
         3758  +  *pnData = 0;
         3759  +  nLine++;
         3760  +  if( fgets(zLine, sizeof(zLine), in)==0 ) goto readHexDb_error;
         3761  +  rc = sscanf(zLine, "| size %d pagesize %d", &n, &pgsz);
         3762  +  if( rc!=2 ) goto readHexDb_error;
         3763  +  if( n<=0 ) goto readHexDb_error;
         3764  +  a = sqlite3_malloc( n );
         3765  +  if( a==0 ){
         3766  +    utf8_printf(stderr, "Out of memory!\n");
         3767  +    goto readHexDb_error;
         3768  +  }
         3769  +  memset(a, 0, n);
         3770  +  if( pgsz<512 || pgsz>65536 || (pgsz & (pgsz-1))!=0 ){
         3771  +    utf8_printf(stderr, "invalid pagesize\n");
         3772  +    goto readHexDb_error;
         3773  +  }
         3774  +  for(nLine++; fgets(zLine, sizeof(zLine), in)!=0; nLine++){
         3775  +    rc = sscanf(zLine, "| page %d offset %d", &j, &k);
         3776  +    if( rc==2 ){
         3777  +      iOffset = k;
         3778  +      continue;
         3779  +    }
         3780  +    if( strncmp(zLine, "| end ", 6)==0 ){
         3781  +      break;
         3782  +    }
         3783  +    rc = sscanf(zLine,"| %d: %hhx %hhx %hhx %hhx %hhx %hhx %hhx %hhx"
         3784  +                      "  %hhx %hhx %hhx %hhx %hhx %hhx %hhx %hhx",
         3785  +                &j, &x[0], &x[1], &x[2], &x[3], &x[4], &x[5], &x[6], &x[7],
         3786  +                &x[8], &x[9], &x[10], &x[11], &x[12], &x[13], &x[14], &x[15]);
         3787  +    if( rc==17 ){
         3788  +      k = iOffset+j;
         3789  +      if( k+16<=n ){
         3790  +        memcpy(a+k, x, 16);
         3791  +      }
         3792  +    }
         3793  +  }
         3794  +  *pnData = n;
         3795  +  if( in!=p->in ){
         3796  +    fclose(in);
         3797  +  }else{
         3798  +    p->lineno = nLine;
         3799  +  }
         3800  +  return a;
         3801  +
         3802  +readHexDb_error:
         3803  +  if( in!=stdin ){
         3804  +    fclose(in);
         3805  +  }else{
         3806  +    while( fgets(zLine, sizeof(zLine), p->in)!=0 ){
         3807  +      nLine++;
         3808  +      if(strncmp(zLine, "| end ", 6)==0 ) break;
         3809  +    }
         3810  +    p->lineno = nLine;
         3811  +  }
         3812  +  sqlite3_free(a);
         3813  +  utf8_printf(stderr,"Error on line %d of --hexdb input\n", nLine);
         3814  +  return 0;
         3815  +}
         3816  +#endif /* SQLITE_ENABLE_DESERIALIZE */
         3817  +
  3726   3818   /* Flags for open_db().
  3727   3819   **
  3728   3820   ** The default behavior of open_db() is to exit(1) if the database fails to
  3729   3821   ** open.  The OPEN_DB_KEEPALIVE flag changes that so that it prints an error
  3730   3822   ** but still returns without calling exit.
  3731   3823   **
  3732   3824   ** The OPEN_DB_ZIPFILE flag causes open_db() to prefer to open files as a
................................................................................
  3752   3844       }
  3753   3845       switch( p->openMode ){
  3754   3846         case SHELL_OPEN_APPENDVFS: {
  3755   3847           sqlite3_open_v2(p->zDbFilename, &p->db, 
  3756   3848              SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE, "apndvfs");
  3757   3849           break;
  3758   3850         }
         3851  +      case SHELL_OPEN_HEXDB:
  3759   3852         case SHELL_OPEN_DESERIALIZE: {
  3760   3853           sqlite3_open(0, &p->db);
  3761   3854           break;
  3762   3855         }
  3763   3856         case SHELL_OPEN_ZIPFILE: {
  3764   3857           sqlite3_open(":memory:", &p->db);
  3765   3858           break;
................................................................................
  3806   3899       if( p->openMode==SHELL_OPEN_ZIPFILE ){
  3807   3900         char *zSql = sqlite3_mprintf(
  3808   3901            "CREATE VIRTUAL TABLE zip USING zipfile(%Q);", p->zDbFilename);
  3809   3902         sqlite3_exec(p->db, zSql, 0, 0, 0);
  3810   3903         sqlite3_free(zSql);
  3811   3904       }
  3812   3905   #ifdef SQLITE_ENABLE_DESERIALIZE
  3813         -    else if( p->openMode==SHELL_OPEN_DESERIALIZE ){
         3906  +    else
         3907  +    if( p->openMode==SHELL_OPEN_DESERIALIZE || p->openMode==SHELL_OPEN_HEXDB ){
         3908  +      int rc;
  3814   3909         int nData = 0;
  3815         -      unsigned char *aData = (unsigned char*)readFile(p->zDbFilename, &nData);
  3816         -      int rc = sqlite3_deserialize(p->db, "main", aData, nData, nData,
         3910  +      unsigned char *aData;
         3911  +      if( p->openMode==SHELL_OPEN_DESERIALIZE ){
         3912  +        aData = (unsigned char*)readFile(p->zDbFilename, &nData);
         3913  +      }else{
         3914  +        aData = readHexDb(p, &nData);
         3915  +        if( aData==0 ){
         3916  +          utf8_printf(stderr, "Error in hexdb input\n");
         3917  +          return;
         3918  +        }
         3919  +      }
         3920  +      rc = sqlite3_deserialize(p->db, "main", aData, nData, nData,
  3817   3921                      SQLITE_DESERIALIZE_RESIZEABLE |
  3818   3922                      SQLITE_DESERIALIZE_FREEONCLOSE);
  3819   3923         if( rc ){
  3820   3924           utf8_printf(stderr, "Error: sqlite3_deserialize() returns %d\n", rc);
  3821   3925         }
  3822   3926       }
  3823   3927   #endif
................................................................................
  6745   6849         }else if( optionMatch(z, "append") ){
  6746   6850           p->openMode = SHELL_OPEN_APPENDVFS;
  6747   6851         }else if( optionMatch(z, "readonly") ){
  6748   6852           p->openMode = SHELL_OPEN_READONLY;
  6749   6853   #ifdef SQLITE_ENABLE_DESERIALIZE
  6750   6854         }else if( optionMatch(z, "deserialize") ){
  6751   6855           p->openMode = SHELL_OPEN_DESERIALIZE;
  6752         -#endif
         6856  +      }else if( optionMatch(z, "hexdb") ){
         6857  +        p->openMode = SHELL_OPEN_HEXDB;
         6858  +#endif /* SQLITE_ENABLE_DESERIALIZE */
  6753   6859         }else if( z[0]=='-' ){
  6754   6860           utf8_printf(stderr, "unknown option: %s\n", z);
  6755   6861           rc = 1;
  6756   6862           goto meta_command_exit;
  6757   6863         }
  6758   6864       }
  6759   6865       /* If a filename is specified, try to open it first */
  6760   6866       zNewFilename = nArg>iName ? sqlite3_mprintf("%s", azArg[iName]) : 0;
  6761         -    if( zNewFilename ){
         6867  +    if( zNewFilename || p->openMode==SHELL_OPEN_HEXDB ){
  6762   6868         if( newFlag ) shellDeleteFile(zNewFilename);
  6763   6869         p->zDbFilename = zNewFilename;
  6764   6870         open_db(p, OPEN_DB_KEEPALIVE);
  6765   6871         if( p->db==0 ){
  6766   6872           utf8_printf(stderr, "Error: cannot open '%s'\n", zNewFilename);
  6767   6873           sqlite3_free(zNewFilename);
  6768   6874         }else{
................................................................................
  6870   6976     }else
  6871   6977   
  6872   6978     if( c=='q' && strncmp(azArg[0], "quit", n)==0 ){
  6873   6979       rc = 2;
  6874   6980     }else
  6875   6981   
  6876   6982     if( c=='r' && n>=3 && strncmp(azArg[0], "read", n)==0 ){
  6877         -    FILE *alt;
         6983  +    FILE *inSaved = p->in;
         6984  +    int savedLineno = p->lineno;
  6878   6985       if( nArg!=2 ){
  6879   6986         raw_printf(stderr, "Usage: .read FILE\n");
  6880   6987         rc = 1;
  6881   6988         goto meta_command_exit;
  6882   6989       }
  6883         -    alt = fopen(azArg[1], "rb");
  6884         -    if( alt==0 ){
         6990  +    p->in = fopen(azArg[1], "rb");
         6991  +    if( p->in==0 ){
  6885   6992         utf8_printf(stderr,"Error: cannot open \"%s\"\n", azArg[1]);
  6886   6993         rc = 1;
  6887   6994       }else{
  6888         -      rc = process_input(p, alt);
  6889         -      fclose(alt);
         6995  +      rc = process_input(p);
         6996  +      fclose(p->in);
  6890   6997       }
         6998  +    p->in = inSaved;
         6999  +    p->lineno = savedLineno;
  6891   7000     }else
  6892   7001   
  6893   7002     if( c=='r' && n>=3 && strncmp(azArg[0], "restore", n)==0 ){
  6894   7003       const char *zSrcFile;
  6895   7004       const char *zDb;
  6896   7005       sqlite3 *pSrc;
  6897   7006       sqlite3_backup *pBackup;
................................................................................
  8224   8333   ** is interactive - the user is typing it it.  Otherwise, input
  8225   8334   ** is coming from a file or device.  A prompt is issued and history
  8226   8335   ** is saved only if input is interactive.  An interrupt signal will
  8227   8336   ** cause this routine to exit immediately, unless input is interactive.
  8228   8337   **
  8229   8338   ** Return the number of errors.
  8230   8339   */
  8231         -static int process_input(ShellState *p, FILE *in){
         8340  +static int process_input(ShellState *p){
  8232   8341     char *zLine = 0;          /* A single input line */
  8233   8342     char *zSql = 0;           /* Accumulated SQL text */
  8234   8343     int nLine;                /* Length of current line */
  8235   8344     int nSql = 0;             /* Bytes of zSql[] used */
  8236   8345     int nAlloc = 0;           /* Allocated zSql[] space */
  8237   8346     int nSqlPrior = 0;        /* Bytes of zSql[] used by prior line */
  8238   8347     int rc;                   /* Error code */
  8239   8348     int errCnt = 0;           /* Number of errors seen */
  8240         -  int lineno = 0;           /* Current line number */
  8241   8349     int startline = 0;        /* Line number for start of current input */
  8242   8350   
  8243         -  while( errCnt==0 || !bail_on_error || (in==0 && stdin_is_interactive) ){
         8351  +  p->lineno = 0;
         8352  +  while( errCnt==0 || !bail_on_error || (p->in==0 && stdin_is_interactive) ){
  8244   8353       fflush(p->out);
  8245         -    zLine = one_input_line(in, zLine, nSql>0);
         8354  +    zLine = one_input_line(p->in, zLine, nSql>0);
  8246   8355       if( zLine==0 ){
  8247   8356         /* End of input */
  8248         -      if( in==0 && stdin_is_interactive ) printf("\n");
         8357  +      if( p->in==0 && stdin_is_interactive ) printf("\n");
  8249   8358         break;
  8250   8359       }
  8251   8360       if( seenInterrupt ){
  8252         -      if( in!=0 ) break;
         8361  +      if( p->in!=0 ) break;
  8253   8362         seenInterrupt = 0;
  8254   8363       }
  8255         -    lineno++;
         8364  +    p->lineno++;
  8256   8365       if( nSql==0 && _all_whitespace(zLine) ){
  8257   8366         if( ShellHasFlag(p, SHFLG_Echo) ) printf("%s\n", zLine);
  8258   8367         continue;
  8259   8368       }
  8260   8369       if( zLine && (zLine[0]=='.' || zLine[0]=='#') && nSql==0 ){
  8261   8370         if( ShellHasFlag(p, SHFLG_Echo) ) printf("%s\n", zLine);
  8262   8371         if( zLine[0]=='.' ){
................................................................................
  8280   8389       }
  8281   8390       nSqlPrior = nSql;
  8282   8391       if( nSql==0 ){
  8283   8392         int i;
  8284   8393         for(i=0; zLine[i] && IsSpace(zLine[i]); i++){}
  8285   8394         assert( nAlloc>0 && zSql!=0 );
  8286   8395         memcpy(zSql, zLine+i, nLine+1-i);
  8287         -      startline = lineno;
         8396  +      startline = p->lineno;
  8288   8397         nSql = nLine-i;
  8289   8398       }else{
  8290   8399         zSql[nSql++] = '\n';
  8291   8400         memcpy(zSql+nSql, zLine, nLine+1);
  8292   8401         nSql += nLine;
  8293   8402       }
  8294   8403       if( nSql && line_contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior)
  8295   8404                   && sqlite3_complete(zSql) ){
  8296         -      errCnt += runOneSqlLine(p, zSql, in, startline);
         8405  +      errCnt += runOneSqlLine(p, zSql, p->in, startline);
  8297   8406         nSql = 0;
  8298   8407         if( p->outCount ){
  8299   8408           output_reset(p);
  8300   8409           p->outCount = 0;
  8301   8410         }else{
  8302   8411           clearTempFile(p);
  8303   8412         }
  8304   8413       }else if( nSql && _all_whitespace(zSql) ){
  8305   8414         if( ShellHasFlag(p, SHFLG_Echo) ) printf("%s\n", zSql);
  8306   8415         nSql = 0;
  8307   8416       }
  8308   8417     }
  8309   8418     if( nSql && !_all_whitespace(zSql) ){
  8310         -    errCnt += runOneSqlLine(p, zSql, in, startline);
         8419  +    errCnt += runOneSqlLine(p, zSql, p->in, startline);
  8311   8420     }
  8312   8421     free(zSql);
  8313   8422     free(zLine);
  8314   8423     return errCnt>0;
  8315   8424   }
  8316   8425   
  8317   8426   /*
................................................................................
  8392   8501   static void process_sqliterc(
  8393   8502     ShellState *p,                  /* Configuration data */
  8394   8503     const char *sqliterc_override   /* Name of config file. NULL to use default */
  8395   8504   ){
  8396   8505     char *home_dir = NULL;
  8397   8506     const char *sqliterc = sqliterc_override;
  8398   8507     char *zBuf = 0;
  8399         -  FILE *in = NULL;
         8508  +  FILE *inSaved = p->in;
         8509  +  int savedLineno = p->lineno;
  8400   8510   
  8401   8511     if (sqliterc == NULL) {
  8402   8512       home_dir = find_home_dir(0);
  8403   8513       if( home_dir==0 ){
  8404   8514         raw_printf(stderr, "-- warning: cannot find home directory;"
  8405   8515                         " cannot read ~/.sqliterc\n");
  8406   8516         return;
  8407   8517       }
  8408   8518       zBuf = sqlite3_mprintf("%s/.sqliterc",home_dir);
  8409   8519       sqliterc = zBuf;
  8410   8520     }
  8411         -  in = fopen(sqliterc,"rb");
  8412         -  if( in ){
         8521  +  p->in = fopen(sqliterc,"rb");
         8522  +  if( p->in ){
  8413   8523       if( stdin_is_interactive ){
  8414   8524         utf8_printf(stderr,"-- Loading resources from %s\n",sqliterc);
  8415   8525       }
  8416         -    process_input(p,in);
  8417         -    fclose(in);
         8526  +    process_input(p);
         8527  +    fclose(p->in);
  8418   8528     }
         8529  +  p->in = inSaved;
         8530  +  p->lineno = savedLineno;
  8419   8531     sqlite3_free(zBuf);
  8420   8532   }
  8421   8533   
  8422   8534   /*
  8423   8535   ** Show available command line options
  8424   8536   */
  8425   8537   static const char zOptions[] =
................................................................................
  9023   9135         }
  9024   9136         if( zHistory ){ shell_read_history(zHistory); }
  9025   9137   #if HAVE_READLINE || HAVE_EDITLINE
  9026   9138         rl_attempted_completion_function = readline_completion;
  9027   9139   #elif HAVE_LINENOISE
  9028   9140         linenoiseSetCompletionCallback(linenoise_completion);
  9029   9141   #endif
  9030         -      rc = process_input(&data, 0);
         9142  +      data.in = 0;
         9143  +      rc = process_input(&data);
  9031   9144         if( zHistory ){
  9032   9145           shell_stifle_history(2000);
  9033   9146           shell_write_history(zHistory);
  9034   9147           free(zHistory);
  9035   9148         }
  9036   9149       }else{
  9037         -      rc = process_input(&data, stdin);
         9150  +      data.in = stdin;
         9151  +      rc = process_input(&data);
  9038   9152       }
  9039   9153     }
  9040   9154     set_table_name(&data, 0);
  9041   9155     if( data.db ){
  9042   9156       session_close_all(&data);
  9043   9157       close_db(data.db);
  9044   9158     }

Changes to src/sqlite.h.in.

  3632   3632   ** [[SQLITE_PREPARE_NORMALIZE]] <dt>SQLITE_PREPARE_NORMALIZE</dt>
  3633   3633   ** <dd>The SQLITE_PREPARE_NORMALIZE flag is a no-op. This flag used
  3634   3634   ** to be required for any prepared statement that wanted to use the
  3635   3635   ** [sqlite3_normalized_sql()] interface.  However, the
  3636   3636   ** [sqlite3_normalized_sql()] interface is now available to all
  3637   3637   ** prepared statements, regardless of whether or not they use this
  3638   3638   ** flag.
         3639  +**
         3640  +** [[SQLITE_PREPARE_NO_VTAB]] <dt>SQLITE_PREPARE_NO_VTAB</dt>
         3641  +** <dd>The SQLITE_PREPARE_NO_VTAB flag causes the SQL compiler
         3642  +** to return an error (error code SQLITE_ERROR) if the statement uses
         3643  +** any virtual tables.
  3639   3644   ** </dl>
  3640   3645   */
  3641   3646   #define SQLITE_PREPARE_PERSISTENT              0x01
  3642   3647   #define SQLITE_PREPARE_NORMALIZE               0x02
         3648  +#define SQLITE_PREPARE_NO_VTAB                 0x04
  3643   3649   
  3644   3650   /*
  3645   3651   ** CAPI3REF: Compiling An SQL Statement
  3646   3652   ** KEYWORDS: {SQL statement compiler}
  3647   3653   ** METHOD: sqlite3
  3648   3654   ** CONSTRUCTOR: sqlite3_stmt
  3649   3655   **

Changes to src/sqliteInt.h.

  3055   3055     u8 nested;           /* Number of nested calls to the parser/code generator */
  3056   3056     u8 nTempReg;         /* Number of temporary registers in aTempReg[] */
  3057   3057     u8 isMultiWrite;     /* True if statement may modify/insert multiple rows */
  3058   3058     u8 mayAbort;         /* True if statement may throw an ABORT exception */
  3059   3059     u8 hasCompound;      /* Need to invoke convertCompoundSelectToSubquery() */
  3060   3060     u8 okConstFactor;    /* OK to factor out constants */
  3061   3061     u8 disableLookaside; /* Number of times lookaside has been disabled */
         3062  +  u8 disableVtab;      /* Disable all virtual tables for this parse */
  3062   3063     int nRangeReg;       /* Size of the temporary register block */
  3063   3064     int iRangeReg;       /* First register in temporary register block */
  3064   3065     int nErr;            /* Number of errors seen */
  3065   3066     int nTab;            /* Number of previously allocated VDBE cursors */
  3066   3067     int nMem;            /* Number of memory cells used so far */
  3067   3068     int nOpAlloc;        /* Number of slots allocated for Vdbe.aOp[] */
  3068   3069     int szOpAlloc;       /* Bytes of memory space allocated for Vdbe.aOp[] */
................................................................................
  4253   4254   void sqlite3Reindex(Parse*, Token*, Token*);
  4254   4255   void sqlite3AlterFunctions(void);
  4255   4256   void sqlite3AlterRenameTable(Parse*, SrcList*, Token*);
  4256   4257   void sqlite3AlterRenameColumn(Parse*, SrcList*, Token*, Token*);
  4257   4258   int sqlite3GetToken(const unsigned char *, int *);
  4258   4259   void sqlite3NestedParse(Parse*, const char*, ...);
  4259   4260   void sqlite3ExpirePreparedStatements(sqlite3*, int);
  4260         -int sqlite3CodeSubselect(Parse*, Expr *, int, int);
         4261  +void sqlite3CodeRhsOfIN(Parse*, Expr*, int);
         4262  +int sqlite3CodeSubselect(Parse*, Expr*);
  4261   4263   void sqlite3SelectPrep(Parse*, Select*, NameContext*);
  4262   4264   void sqlite3SelectWrongNumTermsError(Parse *pParse, Select *p);
  4263   4265   int sqlite3MatchSpanName(const char*, const char*, const char*, const char*);
  4264   4266   int sqlite3ResolveExprNames(NameContext*, Expr*);
  4265   4267   int sqlite3ResolveExprListNames(NameContext*, ExprList*);
  4266   4268   void sqlite3ResolveSelectNames(Parse*, Select*, NameContext*);
  4267   4269   void sqlite3ResolveSelfReference(Parse*,Table*,int,Expr*,ExprList*);

Changes to src/test1.c.

  7636   7636         zDb = Tcl_GetString(objv[2]);
  7637   7637       }
  7638   7638       rc = sqlite3_mmap_warm(db, zDb);
  7639   7639       Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3ErrName(rc), -1));
  7640   7640       return TCL_OK;
  7641   7641     }
  7642   7642   }
         7643  +
         7644  +/*
         7645  +** Usage:  decode_hexdb TEXT
         7646  +**
         7647  +** Example:   db deserialize [decode_hexdb $output_of_dbtotxt]
         7648  +**
         7649  +** This routine returns a byte-array for an SQLite database file that
         7650  +** is constructed from a text input which is the output of the "dbtotxt"
         7651  +** utility.
         7652  +*/
         7653  +static int SQLITE_TCLAPI test_decode_hexdb(
         7654  +  void * clientData,
         7655  +  Tcl_Interp *interp,
         7656  +  int objc,
         7657  +  Tcl_Obj *CONST objv[]
         7658  +){
         7659  +  const char *zIn = 0;
         7660  +  unsigned char *a = 0;
         7661  +  int n = 0;
         7662  +  int lineno = 0;
         7663  +  int i, iNext;
         7664  +  int iOffset = 0;
         7665  +  int j, k;
         7666  +  int rc;
         7667  +  unsigned char x[16];
         7668  +  if( objc!=2 ){
         7669  +    Tcl_WrongNumArgs(interp, 1, objv, "HEXDB");
         7670  +    return TCL_ERROR;
         7671  +  }
         7672  +  zIn = Tcl_GetString(objv[1]);
         7673  +  for(i=0; zIn[i]; i=iNext){
         7674  +    lineno++;
         7675  +    for(iNext=i; zIn[iNext] && zIn[iNext]!='\n'; iNext++){}
         7676  +    if( zIn[iNext]=='\n' ) iNext++;
         7677  +    while( zIn[i]==' ' || zIn[i]=='\t' ){ i++; }
         7678  +    if( a==0 ){
         7679  +      int pgsz;
         7680  +      rc = sscanf(zIn+i, "| size %d pagesize %d", &n, &pgsz);
         7681  +      if( rc!=2 ) continue;
         7682  +      if( n<512 ){
         7683  +        Tcl_AppendResult(interp, "bad 'size' field", (void*)0);
         7684  +        return TCL_ERROR;
         7685  +      }
         7686  +      a = malloc( n );
         7687  +      if( a==0 ){
         7688  +        Tcl_AppendResult(interp, "out of memory", (void*)0);
         7689  +        return TCL_ERROR;
         7690  +      }
         7691  +      memset(a, 0, n);
         7692  +      continue;
         7693  +    }
         7694  +    rc = sscanf(zIn+i, "| page %d offset %d", &j, &k);
         7695  +    if( rc==2 ){
         7696  +      iOffset = k;
         7697  +      continue;
         7698  +    }
         7699  +    rc = sscanf(zIn+i,"| %d: %hhx %hhx %hhx %hhx %hhx %hhx %hhx %hhx"
         7700  +                      "  %hhx %hhx %hhx %hhx %hhx %hhx %hhx %hhx",
         7701  +                &j, &x[0], &x[1], &x[2], &x[3], &x[4], &x[5], &x[6], &x[7],
         7702  +                &x[8], &x[9], &x[10], &x[11], &x[12], &x[13], &x[14], &x[15]);
         7703  +    if( rc==17 ){
         7704  +      k = iOffset+j;
         7705  +      if( k+16<=n ){
         7706  +        memcpy(a+k, x, 16);
         7707  +      }
         7708  +      continue;
         7709  +    }
         7710  +  }
         7711  +  Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(a, n));
         7712  +  free(a);
         7713  +  return TCL_OK;
         7714  +}
         7715  +
  7643   7716   
  7644   7717   /*
  7645   7718   ** Register commands with the TCL interpreter.
  7646   7719   */
  7647   7720   int Sqlitetest1_Init(Tcl_Interp *interp){
  7648   7721     extern int sqlite3_search_count;
  7649   7722     extern int sqlite3_found_count;
................................................................................
  7916   7989        { "sqlite3_snapshot_open_blob", test_snapshot_open_blob, 0 },
  7917   7990        { "sqlite3_snapshot_cmp_blob", test_snapshot_cmp_blob, 0 },
  7918   7991   #endif
  7919   7992        { "sqlite3_delete_database", test_delete_database,    0 },
  7920   7993        { "atomic_batch_write",      test_atomic_batch_write, 0 },
  7921   7994        { "sqlite3_mmap_warm",       test_mmap_warm,          0 },
  7922   7995        { "sqlite3_config_sorterref", test_config_sorterref,   0 },
         7996  +     { "decode_hexdb",             test_decode_hexdb,       0 },
  7923   7997     };
  7924   7998     static int bitmask_size = sizeof(Bitmask)*8;
  7925   7999     static int longdouble_size = sizeof(LONGDOUBLE_TYPE);
  7926   8000     int i;
  7927   8001     extern int sqlite3_sync_count, sqlite3_fullsync_count;
  7928   8002     extern int sqlite3_opentemp_count;
  7929   8003     extern int sqlite3_like_count;

Changes to src/test_vfs.c.

   224    224   };
   225    225   
   226    226   static int tvfsResultCode(Testvfs *p, int *pRc){
   227    227     struct errcode {
   228    228       int eCode;
   229    229       const char *zCode;
   230    230     } aCode[] = {
   231         -    { SQLITE_OK,     "SQLITE_OK"     },
   232         -    { SQLITE_ERROR,  "SQLITE_ERROR"  },
   233         -    { SQLITE_IOERR,  "SQLITE_IOERR"  },
   234         -    { SQLITE_LOCKED, "SQLITE_LOCKED" },
   235         -    { SQLITE_BUSY,   "SQLITE_BUSY"   },
          231  +    { SQLITE_OK,       "SQLITE_OK"     },
          232  +    { SQLITE_ERROR,    "SQLITE_ERROR"  },
          233  +    { SQLITE_IOERR,    "SQLITE_IOERR"  },
          234  +    { SQLITE_LOCKED,   "SQLITE_LOCKED" },
          235  +    { SQLITE_BUSY,     "SQLITE_BUSY"   },
          236  +    { SQLITE_READONLY, "SQLITE_READONLY"   },
          237  +    { SQLITE_READONLY_CANTINIT, "SQLITE_READONLY_CANTINIT"   },
   236    238     };
   237    239   
   238    240     const char *z;
   239    241     int i;
   240    242   
   241    243     z = Tcl_GetStringResult(p->interp);
   242    244     for(i=0; i<ArraySize(aCode); i++){
................................................................................
   861    863       p->pBuffer = pBuffer;
   862    864     }
   863    865   
   864    866     /* Connect the TestvfsBuffer to the new TestvfsShm handle and return. */
   865    867     pFd->pNext = pBuffer->pFile;
   866    868     pBuffer->pFile = pFd;
   867    869     pFd->pShm = pBuffer;
   868         -  return SQLITE_OK;
          870  +  return rc;
   869    871   }
   870    872   
   871    873   static void tvfsAllocPage(TestvfsBuffer *p, int iPage, int pgsz){
   872    874     assert( iPage<TESTVFS_MAX_PAGES );
   873    875     if( p->aPage[iPage]==0 ){
   874    876       p->aPage[iPage] = (u8 *)ckalloc(pgsz);
   875    877       memset(p->aPage[iPage], 0, pgsz);
................................................................................
   914    916     if( rc==SQLITE_OK && p->mask&TESTVFS_SHMMAP_MASK && tvfsInjectIoerr(p) ){
   915    917       rc = SQLITE_IOERR;
   916    918     }
   917    919   
   918    920     if( rc==SQLITE_OK && isWrite && !pFd->pShm->aPage[iPage] ){
   919    921       tvfsAllocPage(pFd->pShm, iPage, pgsz);
   920    922     }
   921         -  *pp = (void volatile *)pFd->pShm->aPage[iPage];
          923  +  if( rc==SQLITE_OK || rc==SQLITE_READONLY ){
          924  +    *pp = (void volatile *)pFd->pShm->aPage[iPage];
          925  +  }
   922    926   
   923    927     return rc;
   924    928   }
   925    929   
   926    930   
   927    931   static int tvfsShmLock(
   928    932     sqlite3_file *pFile,
................................................................................
  1558   1562   
  1559   1563     return TCL_OK;
  1560   1564   
  1561   1565    bad_args:
  1562   1566     Tcl_WrongNumArgs(interp, 1, objv, "VFSNAME ?-noshm BOOL? ?-fullshm BOOL? ?-default BOOL? ?-mxpathname INT? ?-szosfile INT? ?-iversion INT?");
  1563   1567     return TCL_ERROR;
  1564   1568   }
         1569  +
         1570  +extern int getDbPointer(Tcl_Interp *interp, const char *zA, sqlite3 **ppDb);
         1571  +extern const char *sqlite3ErrName(int);
         1572  +
         1573  +/*
         1574  +** tclcmd: vfs_shmlock DB DBNAME (shared|exclusive) (lock|unlock) OFFSET N
         1575  +*/
         1576  +static int SQLITE_TCLAPI test_vfs_shmlock(
         1577  +  void * clientData,
         1578  +  Tcl_Interp *interp,
         1579  +  int objc,
         1580  +  Tcl_Obj *CONST objv[]
         1581  +){
         1582  +  const char *azArg1[] = {"shared", "exclusive", 0};
         1583  +  const char *azArg2[] = {"lock", "unlock", 0};
         1584  +  sqlite3 *db = 0;
         1585  +  int rc = SQLITE_OK;
         1586  +  const char *zDbname = 0;
         1587  +  int iArg1 = 0;
         1588  +  int iArg2 = 0;
         1589  +  int iOffset = 0;
         1590  +  int n = 0;
         1591  +  sqlite3_file *pFd;
         1592  +
         1593  +  if( objc!=7 ){
         1594  +    Tcl_WrongNumArgs(interp, 1, objv, 
         1595  +        "DB DBNAME (shared|exclusive) (lock|unlock) OFFSET N"
         1596  +    );
         1597  +    return TCL_ERROR;
         1598  +  }
         1599  +
         1600  +  zDbname = Tcl_GetString(objv[2]);
         1601  +  if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) 
         1602  +   || Tcl_GetIndexFromObj(interp, objv[3], azArg1, "ARG", 0, &iArg1) 
         1603  +   || Tcl_GetIndexFromObj(interp, objv[4], azArg2, "ARG", 0, &iArg2) 
         1604  +   || Tcl_GetIntFromObj(interp, objv[5], &iOffset)
         1605  +   || Tcl_GetIntFromObj(interp, objv[6], &n)
         1606  +  ){
         1607  +    return TCL_ERROR;
         1608  +  }
         1609  +
         1610  +  sqlite3_file_control(db, zDbname, SQLITE_FCNTL_FILE_POINTER, (void*)&pFd);
         1611  +  if( pFd==0 ){
         1612  +    return TCL_ERROR;
         1613  +  }
         1614  +  rc = pFd->pMethods->xShmLock(pFd, iOffset, n, 
         1615  +      (iArg1==0 ? SQLITE_SHM_SHARED : SQLITE_SHM_EXCLUSIVE)
         1616  +    | (iArg2==0 ? SQLITE_SHM_LOCK : SQLITE_SHM_UNLOCK)
         1617  +  );
         1618  +  Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3ErrName(rc), -1));
         1619  +  return TCL_OK;
         1620  +}
         1621  +
         1622  +static int SQLITE_TCLAPI test_vfs_set_readmark(
         1623  +  void * clientData,
         1624  +  Tcl_Interp *interp,
         1625  +  int objc,
         1626  +  Tcl_Obj *CONST objv[]
         1627  +){
         1628  +  sqlite3 *db = 0;
         1629  +  int rc = SQLITE_OK;
         1630  +  const char *zDbname = 0;
         1631  +  int iSlot = 0;
         1632  +  int iVal = -1;
         1633  +  sqlite3_file *pFd;
         1634  +  void volatile *pShm = 0;
         1635  +  u32 *aShm;
         1636  +  int iOff;
         1637  +
         1638  +  if( objc!=4 && objc!=5 ){
         1639  +    Tcl_WrongNumArgs(interp, 1, objv, "DB DBNAME SLOT ?VALUE?");
         1640  +    return TCL_ERROR;
         1641  +  }
         1642  +
         1643  +  zDbname = Tcl_GetString(objv[2]);
         1644  +  if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) 
         1645  +   || Tcl_GetIntFromObj(interp, objv[3], &iSlot)
         1646  +   || (objc==5 && Tcl_GetIntFromObj(interp, objv[4], &iVal))
         1647  +  ){
         1648  +    return TCL_ERROR;
         1649  +  }
         1650  +
         1651  +  sqlite3_file_control(db, zDbname, SQLITE_FCNTL_FILE_POINTER, (void*)&pFd);
         1652  +  if( pFd==0 ){
         1653  +    return TCL_ERROR;
         1654  +  }
         1655  +  rc = pFd->pMethods->xShmMap(pFd, 0, 32*1024, 0, &pShm);
         1656  +  if( rc!=SQLITE_OK ){
         1657  +    Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3ErrName(rc), -1));
         1658  +    return TCL_ERROR;
         1659  +  }
         1660  +  if( pShm==0 ){
         1661  +    Tcl_AppendResult(interp, "*-shm is not yet mapped", 0);
         1662  +    return TCL_ERROR;
         1663  +  }
         1664  +  aShm = (u32*)pShm;
         1665  +  iOff = 12*2+1+iSlot;
         1666  +
         1667  +  if( objc==5 ){
         1668  +    aShm[iOff] = iVal;
         1669  +  }
         1670  +  Tcl_SetObjResult(interp, Tcl_NewIntObj(aShm[iOff]));
         1671  +
         1672  +  return TCL_OK;
         1673  +}
  1565   1674   
  1566   1675   int Sqlitetestvfs_Init(Tcl_Interp *interp){
  1567   1676     Tcl_CreateObjCommand(interp, "testvfs", testvfs_cmd, 0, 0);
         1677  +  Tcl_CreateObjCommand(interp, "vfs_shmlock", test_vfs_shmlock, 0, 0);
         1678  +  Tcl_CreateObjCommand(interp, "vfs_set_readmark", test_vfs_set_readmark, 0, 0);
  1568   1679     return TCL_OK;
  1569   1680   }
  1570   1681   
  1571   1682   #endif

Changes to src/trigger.c.

   912    912     sNC.pParse = pSubParse;
   913    913     pSubParse->db = db;
   914    914     pSubParse->pTriggerTab = pTab;
   915    915     pSubParse->pToplevel = pTop;
   916    916     pSubParse->zAuthContext = pTrigger->zName;
   917    917     pSubParse->eTriggerOp = pTrigger->op;
   918    918     pSubParse->nQueryLoop = pParse->nQueryLoop;
          919  +  pSubParse->disableVtab = pParse->disableVtab;
   919    920   
   920    921     v = sqlite3GetVdbe(pSubParse);
   921    922     if( v ){
   922    923       VdbeComment((v, "Start: %s.%s (%s %s%s%s ON %s)", 
   923    924         pTrigger->zName, onErrorText(orconf),
   924    925         (pTrigger->tr_tm==TRIGGER_BEFORE ? "BEFORE" : "AFTER"),
   925    926           (pTrigger->op==TK_UPDATE ? "UPDATE" : ""),

Changes to src/vdbe.c.

  1921   1921       if( pOp->p5 & SQLITE_NULLEQ ){
  1922   1922         /* If SQLITE_NULLEQ is set (which will only happen if the operator is
  1923   1923         ** OP_Eq or OP_Ne) then take the jump or not depending on whether
  1924   1924         ** or not both operands are null.
  1925   1925         */
  1926   1926         assert( pOp->opcode==OP_Eq || pOp->opcode==OP_Ne );
  1927   1927         assert( (flags1 & MEM_Cleared)==0 );
  1928         -      assert( (pOp->p5 & SQLITE_JUMPIFNULL)==0 );
         1928  +      assert( (pOp->p5 & SQLITE_JUMPIFNULL)==0 || CORRUPT_DB );
         1929  +      testcase( (pOp->p5 & SQLITE_JUMPIFNULL)!=0 );
  1929   1930         if( (flags1&flags3&MEM_Null)!=0
  1930   1931          && (flags3&MEM_Cleared)==0
  1931   1932         ){
  1932   1933           res = 0;  /* Operands are equal */
  1933   1934         }else{
  1934   1935           res = 1;  /* Operands are not equal */
  1935   1936         }
................................................................................
  4338   4339   case OP_NotExists:          /* jump, in3 */
  4339   4340     pIn3 = &aMem[pOp->p3];
  4340   4341     assert( (pIn3->flags & MEM_Int)!=0 || pOp->opcode==OP_SeekRowid );
  4341   4342     assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  4342   4343     pC = p->apCsr[pOp->p1];
  4343   4344     assert( pC!=0 );
  4344   4345   #ifdef SQLITE_DEBUG
  4345         -  pC->seekOp = OP_SeekRowid;
         4346  +  if( pOp->opcode==OP_SeekRowid ) pC->seekOp = OP_SeekRowid;
  4346   4347   #endif
  4347   4348     assert( pC->isTable );
  4348   4349     assert( pC->eCurType==CURTYPE_BTREE );
  4349   4350     pCrsr = pC->uc.pCursor;
  4350   4351     assert( pCrsr!=0 );
  4351   4352     res = 0;
  4352   4353     iKey = pIn3->u.i;
................................................................................
  5246   5247     assert( pOp->opcode!=OP_Prev || pOp->p4.xAdvance==sqlite3BtreePrevious );
  5247   5248   
  5248   5249     /* The Next opcode is only used after SeekGT, SeekGE, Rewind, and Found.
  5249   5250     ** The Prev opcode is only used after SeekLT, SeekLE, and Last. */
  5250   5251     assert( pOp->opcode!=OP_Next
  5251   5252          || pC->seekOp==OP_SeekGT || pC->seekOp==OP_SeekGE
  5252   5253          || pC->seekOp==OP_Rewind || pC->seekOp==OP_Found 
  5253         -       || pC->seekOp==OP_NullRow);
         5254  +       || pC->seekOp==OP_NullRow|| pC->seekOp==OP_SeekRowid);
  5254   5255     assert( pOp->opcode!=OP_Prev
  5255   5256          || pC->seekOp==OP_SeekLT || pC->seekOp==OP_SeekLE
  5256   5257          || pC->seekOp==OP_Last 
  5257   5258          || pC->seekOp==OP_NullRow);
  5258   5259   
  5259   5260     rc = pOp->p4.xAdvance(pC->uc.pCursor, pOp->p3);
  5260   5261   next_tail:

Changes to src/vdbeaux.c.

   352    352   /*
   353    353   ** Add a new OP_Explain opcode.
   354    354   **
   355    355   ** If the bPush flag is true, then make this opcode the parent for
   356    356   ** subsequent Explains until sqlite3VdbeExplainPop() is called.
   357    357   */
   358    358   void sqlite3VdbeExplain(Parse *pParse, u8 bPush, const char *zFmt, ...){
   359         -  if( pParse->explain==2 ){
          359  +#ifndef SQLITE_DEBUG
          360  +  /* Always include the OP_Explain opcodes if SQLITE_DEBUG is defined.
          361  +  ** But omit them (for performance) during production builds */
          362  +  if( pParse->explain==2 )
          363  +#endif
          364  +  {
   360    365       char *zMsg;
   361    366       Vdbe *v;
   362    367       va_list ap;
   363    368       int iThis;
   364    369       va_start(ap, zFmt);
   365    370       zMsg = sqlite3VMPrintf(pParse->db, zFmt, ap);
   366    371       va_end(ap);

Changes to src/wal.c.

  3573   3573     u32 *piRead                     /* OUT: Frame number (or zero) */
  3574   3574   ){
  3575   3575     int bWal2 = isWalMode2(pWal);
  3576   3576     int iApp = walidxGetFile(&pWal->hdr);
  3577   3577     int rc = SQLITE_OK;
  3578   3578     u32 iRead = 0;                  /* If !=0, WAL frame to return data from */
  3579   3579   
  3580         -  /* This routine is only be called from within a read transaction. */
  3581         -  assert( pWal->readLock!=WAL_LOCK_NONE );
         3580  +  /* This routine is only be called from within a read transaction. Or,
         3581  +  ** sometimes, as part of a rollback that occurs after an error reaquiring
         3582  +  ** a read-lock in walRestartLog().  */
         3583  +  assert( pWal->readLock!=WAL_LOCK_NONE || pWal->writeLock );
  3582   3584   
  3583   3585     /* If this is a wal2 system, the client must have a partial-wal lock 
  3584   3586     ** on wal file iApp. Or if it is a wal system, iApp==0 must be true.  */
  3585   3587     assert( bWal2==0 || iApp==1
  3586   3588          || pWal->readLock==WAL_LOCK_PART1 || pWal->readLock==WAL_LOCK_PART1_FULL2
  3587   3589     );
  3588   3590     assert( bWal2==0 || iApp==0

Changes to src/wherecode.c.

  1072   1072   */
  1073   1073   static void codeExprOrVector(Parse *pParse, Expr *p, int iReg, int nReg){
  1074   1074     assert( nReg>0 );
  1075   1075     if( p && sqlite3ExprIsVector(p) ){
  1076   1076   #ifndef SQLITE_OMIT_SUBQUERY
  1077   1077       if( (p->flags & EP_xIsSelect) ){
  1078   1078         Vdbe *v = pParse->pVdbe;
  1079         -      int iSelect = sqlite3CodeSubselect(pParse, p, 0, 0);
         1079  +      int iSelect;
         1080  +      assert( p->op==TK_SELECT );
         1081  +      iSelect = sqlite3CodeSubselect(pParse, p);
  1080   1082         sqlite3VdbeAddOp3(v, OP_Copy, iSelect, iReg, nReg-1);
  1081   1083       }else
  1082   1084   #endif
  1083   1085       {
  1084   1086         int i;
  1085   1087         ExprList *pList = p->x.pList;
  1086   1088         assert( nReg<=pList->nExpr );

Changes to src/whereexpr.c.

   773    773       /* Search for a table and column that appears on one side or the
   774    774       ** other of the == operator in every subterm.  That table and column
   775    775       ** will be recorded in iCursor and iColumn.  There might not be any
   776    776       ** such table and column.  Set okToChngToIN if an appropriate table
   777    777       ** and column is found but leave okToChngToIN false if not found.
   778    778       */
   779    779       for(j=0; j<2 && !okToChngToIN; j++){
          780  +      Expr *pLeft = 0;
   780    781         pOrTerm = pOrWc->a;
   781    782         for(i=pOrWc->nTerm-1; i>=0; i--, pOrTerm++){
   782    783           assert( pOrTerm->eOperator & WO_EQ );
   783    784           pOrTerm->wtFlags &= ~TERM_OR_OK;
   784    785           if( pOrTerm->leftCursor==iCursor ){
   785    786             /* This is the 2-bit case and we are on the second iteration and
   786    787             ** current term is from the first iteration.  So skip this term. */
................................................................................
   796    797             testcase( pOrTerm->wtFlags & TERM_COPIED );
   797    798             testcase( pOrTerm->wtFlags & TERM_VIRTUAL );
   798    799             assert( pOrTerm->wtFlags & (TERM_COPIED|TERM_VIRTUAL) );
   799    800             continue;
   800    801           }
   801    802           iColumn = pOrTerm->u.leftColumn;
   802    803           iCursor = pOrTerm->leftCursor;
          804  +        pLeft = pOrTerm->pExpr->pLeft;
   803    805           break;
   804    806         }
   805    807         if( i<0 ){
   806    808           /* No candidate table+column was found.  This can only occur
   807    809           ** on the second iteration */
   808    810           assert( j==1 );
   809    811           assert( IsPowerOfTwo(chngToIN) );
................................................................................
   815    817         /* We have found a candidate table and column.  Check to see if that
   816    818         ** table and column is common to every term in the OR clause */
   817    819         okToChngToIN = 1;
   818    820         for(; i>=0 && okToChngToIN; i--, pOrTerm++){
   819    821           assert( pOrTerm->eOperator & WO_EQ );
   820    822           if( pOrTerm->leftCursor!=iCursor ){
   821    823             pOrTerm->wtFlags &= ~TERM_OR_OK;
   822         -        }else if( pOrTerm->u.leftColumn!=iColumn ){
          824  +        }else if( pOrTerm->u.leftColumn!=iColumn || (iColumn==XN_EXPR 
          825  +               && sqlite3ExprCompare(pParse, pOrTerm->pExpr->pLeft, pLeft, -1)
          826  +        )){
   823    827             okToChngToIN = 0;
   824    828           }else{
   825    829             int affLeft, affRight;
   826    830             /* If the right-hand side is also a column, then the affinities
   827    831             ** of both right and left sides must be such that no type
   828    832             ** conversions are required on the right.  (Ticket #2249)
   829    833             */

Changes to test/altertab.test.

   501    501     SELECT * FROM x;
   502    502   } {x x x}
   503    503   
   504    504   do_execsql_test 15.5 {
   505    505     SELECT sql FROM sqlite_master WHERE name = 'y';
   506    506   } {{CREATE VIEW y AS SELECT f2 AS f1 FROM x}}
   507    507   
          508  +#-------------------------------------------------------------------------
          509  +# Test that it is not possible to rename a shadow table in DEFENSIVE mode.
          510  +#
          511  +ifcapable fts3 {
          512  +  proc vtab_command {method args} {
          513  +    switch -- $method {
          514  +      xConnect {
          515  +        if {[info exists ::vtab_connect_sql]} {
          516  +          execsql $::vtab_connect_sql
          517  +        }
          518  +        return "CREATE TABLE t1(a, b, c)"
          519  +      }
          520  +
          521  +      xBestIndex {
          522  +        set clist [lindex $args 0]
          523  +        if {[llength $clist]!=1} { error "unexpected constraint list" }
          524  +        catch { array unset C }
          525  +        array set C [lindex $clist 0]
          526  +        if {$C(usable)} {
          527  +          return "omit 0 cost 0 rows 1 idxnum 555 idxstr eq!"
          528  +        } else {
          529  +          return "cost 1000000 rows 0 idxnum 0 idxstr scan..."
          530  +        }
          531  +      }
          532  +    }
          533  +
          534  +    return {}
          535  +  }
          536  +
          537  +  register_tcl_module db
          538  +
          539  +  sqlite3_db_config db DEFENSIVE 1
          540  +
          541  +  do_execsql_test 16.0 {
          542  +    CREATE VIRTUAL TABLE y1 USING fts3;
          543  +  }
          544  +
          545  +  do_catchsql_test 16.1 {
          546  +    INSERT INTO y1_segments VALUES(1, X'1234567890');
          547  +  } {1 {table y1_segments may not be modified}}
          548  +
          549  +  do_catchsql_test 16.2 {
          550  +    ALTER TABLE y1_segments RENAME TO abc;
          551  +  } {1 {table y1_segments may not be altered}}
          552  +
          553  +  do_execsql_test 16.3 {
          554  +    ALTER TABLE y1 RENAME TO z1;
          555  +  }
          556  +
          557  +  do_execsql_test 16.4 {
          558  +    SELECT * FROM z1_segments;
          559  +  }
          560  +}
   508    561   
   509    562   finish_test

Changes to test/conflict.test.

     9      9   #
    10     10   #***********************************************************************
    11     11   # This file implements regression tests for SQLite library.
    12     12   #
    13     13   # This file implements tests for the conflict resolution extension
    14     14   # to SQLite.
    15     15   #
    16         -# $Id: conflict.test,v 1.32 2009/04/30 09:10:38 danielk1977 Exp $
    17     16   
    18     17   set testdir [file dirname $argv0]
    19     18   source $testdir/tester.tcl
    20     19   
    21     20   ifcapable !conflict {
    22     21     finish_test
    23     22     return
................................................................................
   820    819     execsql {
   821    820       REPLACE INTO t13 VALUES(3);
   822    821       COMMIT;
   823    822       SELECT * FROM t13;
   824    823     }
   825    824   } {1 3}
   826    825   
          826  +
          827  +# Ticket https://www.sqlite.org/src/tktview/e6f1f2e34dceeb1ed61531c7e9
          828  +# Verify that it is not possible to sneak a NULL value into a NOT NULL
          829  +# column using REPLACE.
          830  +#
          831  +do_catchsql_test conflict-14.1 {
          832  +  DROP TABLE IF EXISTS t1;
          833  +  CREATE TABLE t1(x NOT NULL DEFAULT NULL);
          834  +  REPLACE INTO t1 DEFAULT VALUES;
          835  +} {1 {NOT NULL constraint failed: t1.x}}
          836  +
   827    837   
   828    838   finish_test

Changes to test/csv01.test.

   210    210   # by Trent W. Buck.
   211    211   #
   212    212   do_execsql_test 4.4 {
   213    213     CREATE VIRTUAL TABLE temp.trent USING csv(data='1');
   214    214     SELECT * FROM trent;
   215    215   } {1}
   216    216   
          217  +# 2018-12-26
          218  +# Bug report on the mailing list
          219  +#
          220  +forcedelete csv01.csv
          221  +set fd [open csv01.csv w]
          222  +puts $fd "a,b,c,d\r\n1,2,3,4\r\none,two,three,four\r\n5,6,7,8"
          223  +close $fd
          224  +do_execsql_test 5.1 {
          225  +  CREATE VIRTUAL TABLE t5_1 USING csv(filename='csv01.csv');
          226  +  SELECT name FROM temp.pragma_table_info('t5_1');
          227  +} {c0 c1 c2 c3}
          228  +do_execsql_test 5.2 {
          229  +  SELECT *, '|' FROM t5_1;
          230  +} {a b c d | 1 2 3 4 | one two three four | 5 6 7 8 |}
          231  +do_execsql_test 5.3 {
          232  +  DROP TABLE t5_1;
          233  +  CREATE VIRTUAL TABLE t5_1 USING csv(filename='csv01.csv', header);
          234  +  SELECT name FROM temp.pragma_table_info('t5_1');
          235  +} {a b c d}
          236  +do_execsql_test 5.4 {
          237  +  SELECT *, '|' FROM t5_1;
          238  +} {1 2 3 4 | one two three four | 5 6 7 8 |}
          239  +
   217    240   finish_test

Added test/dbfuzz001.test.

            1  +# 2012-12-13
            2  +#
            3  +# The author disclaims copyright to this source code.  In place of
            4  +# a legal notice, here is a blessing:
            5  +#
            6  +#    May you do good and not evil.
            7  +#    May you find forgiveness for yourself and forgive others.
            8  +#    May you share freely, never taking more than you give.
            9  +#
           10  +#***********************************************************************
           11  +#
           12  +# Test cases for corrupt database files.
           13  +
           14  +set testdir [file dirname $argv0]
           15  +source $testdir/tester.tcl
           16  +
           17  +ifcapable !deserialize {
           18  +  finish_test
           19  +  return
           20  +}
           21  +database_may_be_corrupt
           22  +
           23  +# In the following database file, there is 384 bytes of free space
           24  +# on page 8 that does not appear on the freeblock list.
           25  +#
           26  +do_test dbfuzz001-100 {
           27  +  sqlite3 db {}
           28  +  db deserialize [decode_hexdb {
           29  +    | size 5632 pagesize 512 filename c4.db
           30  +    | page 1 offset 0
           31  +    |      0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00   SQLite format 3.
           32  +    |     16: 02 00 01 01 00 40 20 20 00 00 00 02 00 00 00 0b   .....@  ........
           33  +    |     32: 00 00 00 06 00 00 00 01 00 00 00 28 00 00 00 04   ...........(....
           34  +    |     48: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00   ................
           35  +    |     80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 02   ................
           36  +    |     96: 00 2e 30 38 0d 00 00 00 06 01 06 00 01 da 01 b0   ..08............
           37  +    |    112: 01 56 01 86 01 2a 01 06 00 00 00 00 00 00 00 00   .V...*..........
           38  +    |    256: 00 00 00 00 00 00 22 07 06 17 11 11 01 31 74 61   ......"......1ta
           39  +    |    272: 62 6c 65 74 34 74 34 07 43 52 45 41 54 45 20 54   blet4t4.CREATE T
           40  +    |    288: 41 42 4c 45 20 74 34 28 78 29 2a 06 06 17 13 11   ABLE t4(x)*.....
           41  +    |    304: 01 3f 69 6e 64 65 78 00 00 00 00 00 00 00 00 00   .?index.........
           42  +    |    336: 20 74 33 28 78 29 2e 04 06 17 15 11 01 45 69 6e    t3(x).......Ein
           43  +    |    352: 64 65 78 74 32 63 64 74 32 05 43 52 45 41 54 45   dext2cdt2.CREATE
           44  +    |    368: 20 49 4e 44 45 58 20 74 32 63 64 20 4f 4e 20 74    INDEX t2cd ON t
           45  +    |    384: 32 28 63 2c 64 29 28 05 06 17 11 11 01 3d 74 61   2(c,d)(......=ta
           46  +    |    400: 62 6c 65 74 33 74 33 04 43 52 45 41 54 45 20 54   blet3t3.CREATE T
           47  +    |    416: 41 42 4c 45 20 74 33 28 63 2c 78 2c 65 2c 66 29   ABLE t3(c,x,e,f)
           48  +    |    432: 28 02 06 17 11 11 01 3d 74 61 62 6c 65 74 32 74   (......=tablet2t
           49  +    |    448: 32 03 43 52 45 41 54 45 20 54 41 42 4c 45 20 74   2.CREATE TABLE t
           50  +    |    464: 32 28 63 2c 64 2c 65 2c 66 29 24 01 06 17 11 11   2(c,d,e,f)$.....
           51  +    |    480: 01 35 74 61 62 6c 65 74 31 74 31 02 43 52 45 41   .5tablet1t1.CREA
           52  +    |    496: 54 45 20 54 41 42 4c 45 20 74 31 28 61 2c 62 29   TE TABLE t1(a,b)
           53  +    | page 2 offset 512
           54  +    |      0: 0d 00 00 00 00 02 00 00 00 00 00 00 00 00 00 00   ................
           55  +    | page 3 offset 1024
           56  +    |      0: 0d 00 00 00 00 02 00 00 00 00 00 00 00 00 00 00   ................
           57  +    | page 4 offset 1536
           58  +    |      0: 05 00 00 00 03 01 f1 00 00 00 00 0b 01 fb 01 f6   ................
           59  +    |     16: 01 f1 00 16 00 00 09 06 05 01 01 01 01 04 04 03   ................
           60  +    |     32: 03 07 05 05 01 01 09 09 02 02 19 04 05 17 17 17   ................
           61  +    |     48: 17 73 65 76 65 6e 65 69 67 68 74 65 69 67 68 74   .seveneighteight
           62  +    |     64: 73 65 76 65 6e 25 03 05 07 07 07 07 40 14 00 00   seven%......@...
           63  +    |     80: 00 00 00 00 40 18 00 00 00 00 00 00 40 18 00 00   ....@.......@...
           64  +    |     96: 00 00 00 00 40 14 00 00 00 00 00 00 09 02 05 01   ....@...........
           65  +    |    112: 01 01 01 03 04 04 03 07 01 05 09 01 01 09 02 02   ................
           66  +    |    352: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 1a   ................
           67  +    |    496: 00 00 00 00 0a 3e 00 00 00 09 21 00 00 00 08 06   .....>....!.....
           68  +    | page 5 offset 2048
           69  +    |      0: 0a 00 00 00 00 02 00 00 00 00 00 00 00 00 00 00   ................
           70  +    | page 7 offset 3072
           71  +    |      0: 0d 00 00 00 08 01 c2 00 01 fb 01 f6 01 f1 01 ec   ................
           72  +    |     16: 01 e0 01 d4 01 cb 01 c2 00 00 00 00 00 00 00 00   ................
           73  +    |     96: 00 00 00 00 13 00 00 00 00 00 00 00 00 00 00 00   ................
           74  +    |    224: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 02   ................
           75  +    |    288: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 03   ................
           76  +    |    448: 00 00 07 08 02 17 65 69 67 68 74 07 07 02 17 65   ......eight....e
           77  +    |    464: 69 67 68 74 0a 06 02 07 40 18 00 00 00 00 00 00   ight....@.......
           78  +    |    480: 0a 05 02 07 40 18 00 00 00 00 00 00 03 04 02 01   ....@...........
           79  +    |    496: 04 03 03 02 01 04 03 02 02 01 02 03 01 02 01 02   ................
           80  +    | page 8 offset 3584
           81  +    |      0: 0d 00 21 00 01 00 16 00 00 16 00 16 00 16 00 16   ..!.............
           82  +    |     16: 00 16 00 16 00 00 09 06 05 01 01 01 01 04 04 03   ................
           83  +    |     32: 03 00 00 00 5f 01 09 09 02 02 00 00 00 56 17 17   ...._........V..
           84  +    |     48: 17 73 65 76 65 6e 65 69 67 68 74 65 69 67 68 74   .seveneighteight
           85  +    |     64: 73 65 76 65 6e 00 00 00 3b 07 07 07 40 14 00 00   seven...;...@...
           86  +    |     80: 00 00 00 00 40 18 00 00 00 00 00 00 40 18 00 00   ....@.......@...
           87  +    |     96: 00 00 00 00 40 14 00 00 00 00 00 00 00 00 00 14   ....@...........
           88  +    |    112: 01 01 01 03 04 04 03 00 00 00 09 01 01 09 02 02   ................
           89  +    |    352: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 1a   ................
           90  +    | page 9 offset 4096
           91  +    |      0: 0d 00 00 00 1b 00 47 00 01 d9 01 be 01 af 01 a0   ......G.........
           92  +    |     16: 01 91 01 82 01 73 01 64 01 55 01 46 01 37 01 28   .....s.d.U.F.7.(
           93  +    |     32: 01 19 01 0a 00 fb 00 ec 00 dd 00 ce 00 bf 00 b0   ................
           94  +    |     48: 00 a1 00 92 00 83 00 74 00 65 00 56 00 47 00 00   .......t.e.V.G..
           95  +    |     64: 00 00 00 00 00 00 00 0d 21 00 00 48 01 54 00 01   ........!..H.T..
           96  +    |     80: f7 01 ec 01 c5 01 0d 20 00 00 48 01 54 00 01 f7   ....... ..H.T...
           97  +    |     96: 01 ec 01 c5 01 0d 1f 00 00 48 01 54 00 01 f7 01   .........H.T....
           98  +    |    112: ec 01 c5 01 0d 1e 00 00 48 01 54 00 01 f7 01 ec   ........H.T.....
           99  +    |    128: 01 c5 01 0d 1d 00 00 48 01 54 00 01 f7 01 ec 01   .......H.T......
          100  +    |    144: c5 01 0d 1c 00 00 48 01 54 00 01 f7 01 ec 01 c5   ......H.T.......
          101  +    |    160: 01 0d 1b 00 00 48 01 54 00 01 f7 01 ec 01 c5 01   .....H.T........
          102  +    |    176: 0d 1a 00 00 48 01 54 00 01 f7 01 ec 01 c5 01 0d   ....H.T.........
          103  +    |    192: 19 00 00 48 01 54 00 01 f7 01 ec 01 c5 01 0d 18   ...H.T..........
          104  +    |    208: 00 00 48 01 54 00 01 f7 01 ec 01 c5 01 0d 17 00   ..H.T...........
          105  +    |    224: 00 48 01 54 00 01 f7 01 ec 01 c5 01 0d 16 00 00   .H.T............
          106  +    |    240: 48 01 54 00 01 f7 01 ec 01 c5 01 0d 15 00 00 48   H.T............H
          107  +    |    256: 01 54 00 01 f7 01 ec 01 c5 01 0d 14 00 00 48 01   .T............H.
          108  +    |    272: 54 00 01 f7 01 ec 01 c5 01 0d 13 00 00 48 01 54   T............H.T
          109  +    |    288: 00 01 f7 01 ec 01 c5 01 0d 12 00 00 48 01 54 00   ............H.T.
          110  +    |    304: 01 f7 01 ec 01 c5 01 0d 11 00 00 48 01 54 00 01   ...........H.T..
          111  +    |    320: f7 01 ec 01 c5 01 0d 10 00 00 48 01 54 00 01 f7   ..........H.T...
          112  +    |    336: 01 ec 01 c5 01 0d 0f 00 00 48 01 54 00 01 f7 01   .........H.T....
          113  +    |    352: ec 01 c5 01 0d 0e 00 00 48 01 54 00 01 f7 01 ec   ........H.T.....
          114  +    |    368: 01 c5 01 0d 0d 00 00 48 01 54 00 01 f7 01 ec 01   .......H.T......
          115  +    |    384: c5 01 0d 0c 00 00 48 01 54 00 01 f7 01 ec 01 c5   ......H.T.......
          116  +    |    400: 01 0d 0b 00 00 48 01 54 00 01 f7 01 ec 01 c5 01   .....H.T........
          117  +    |    416: 0d 0a 00 00 48 01 54 00 01 f7 01 ec 01 c5 01 0d   ....H.T.........
          118  +    |    432: 09 00 00 48 01 54 00 01 f7 01 ec 01 c5 01 19 08   ...H.T..........
          119  +    |    448: 05 17 17 17 17 65 69 67 68 74 65 69 67 68 74 73   .....eighteights
          120  +    |    464: 65 76 65 6e 73 65 76 65 6e 25 07 05 07 07 07 07   evenseven%......
          121  +    |    480: 40 18 00 00 00 00 00 00 40 18 00 00 00 00 00 00   @.......@.......
          122  +    |    496: 40 14 00 00 00 00 00 00 40 14 00 00 00 00 00 00   @.......@.......
          123  +    | page 10 offset 4608
          124  +    |      0: 0d 00 00 00 1d 00 4d 00 01 f1 01 e2 01 d3 01 c4   ......M.........
          125  +    |     16: 01 b5 01 a6 01 97 01 88 01 79 01 6a 01 5b 01 4c   .........y.j.[.L
          126  +    |     32: 01 3d 01 2e 01 1f 01 10 01 01 00 f2 00 e3 00 d4   .=..............
          127  +    |     48: 00 c5 00 b6 00 a7 00 98 00 89 00 7a 00 6b 00 5c   ...........z.k.\
          128  +    |     64: 00 4d 00 00 00 00 00 00 00 00 00 00 00 0d 3e 00   .M............>.
          129  +    |     80: 00 48 01 54 00 01 f7 01 ec 01 c5 01 0d 3d 00 00   .H.T.........=..
          130  +    |     96: 48 01 54 00 01 f7 01 ec 01 c5 01 0d 3c 00 00 48   H.T.........<..H
          131  +    |    112: 01 54 00 01 f7 01 ec 01 c5 01 0d 3b 00 00 48 01   .T.........;..H.
          132  +    |    128: 54 00 01 f7 01 ec 01 c5 01 0d 3a 00 00 48 01 54   T.........:..H.T
          133  +    |    144: 00 01 f7 01 ec 01 c5 01 0d 39 00 00 48 01 54 00   .........9..H.T.
          134  +    |    160: 01 f7 01 ec 01 c5 01 0d 38 00 00 48 01 54 00 01   ........8..H.T..
          135  +    |    176: f7 01 ec 01 c5 01 0d 37 00 00 48 01 54 00 01 f7   .......7..H.T...
          136  +    |    192: 01 ec 01 c5 01 0d 36 00 00 48 01 54 00 01 f7 01   ......6..H.T....
          137  +    |    208: ec 01 c5 01 0d 35 00 00 48 01 54 00 01 f7 01 ec   .....5..H.T.....
          138  +    |    224: 01 c5 01 0d 34 00 00 48 01 54 00 01 f7 01 ec 01   ....4..H.T......
          139  +    |    240: c5 01 0d 33 00 00 48 01 54 00 01 f7 01 ec 01 c5   ...3..H.T.......
          140  +    |    256: 01 0d 32 00 00 48 01 54 00 01 f7 01 ec 01 c5 01   ..2..H.T........
          141  +    |    272: 0d 31 00 00 48 01 54 00 01 f7 01 ec 01 c5 01 0d   .1..H.T.........
          142  +    |    288: 30 00 00 48 01 54 00 01 f7 01 ec 01 c5 01 0d 2f   0..H.T........./
          143  +    |    304: 00 00 48 01 54 00 01 f7 01 ec 01 c5 01 0d 2e 00   ..H.T...........
          144  +    |    320: 00 48 01 54 00 01 f7 01 ec 01 c5 01 0d 2d 00 00   .H.T.........-..
          145  +    |    336: 48 01 54 00 01 f7 01 ec 01 c5 01 0d 2c 00 00 48   H.T.........,..H
          146  +    |    352: 01 54 00 01 f7 01 ec 01 c5 01 0d 2b 00 00 48 01   .T.........+..H.
          147  +    |    368: 54 00 01 f7 01 ec 01 c5 01 0d 2a 00 00 48 01 54   T.........*..H.T
          148  +    |    384: 00 01 f7 01 ec 01 c5 01 0d 29 00 00 48 01 54 00   .........)..H.T.
          149  +    |    400: 01 f7 01 ec 01 c5 01 0d 28 00 00 48 01 54 00 01   ........(..H.T..
          150  +    |    416: f7 01 ec 01 c5 01 0d 27 00 00 48 01 54 00 01 f7   .......'..H.T...
          151  +    |    432: 01 ec 01 c5 01 0d 26 00 00 48 01 54 00 01 f7 01   ......&..H.T....
          152  +    |    448: ec 01 c5 01 0d 25 00 00 48 01 54 00 01 f7 01 ec   .....%..H.T.....
          153  +    |    464: 01 c5 01 0d 24 00 00 48 01 54 00 01 f7 01 ec 01   ....$..H.T......
          154  +    |    480: c5 01 0d 23 00 00 48 01 54 00 01 f7 01 ec 01 c5   ...#..H.T.......
          155  +    |    496: 01 0d 22 00 00 48 01 54 00 01 f7 01 ec 01 c5 01   .."..H.T........
          156  +    | page 11 offset 5120
          157  +    |      0: 0d 00 00 00 0a 01 6a 00 01 f1 01 e2 01 d3 01 c4   ......j.........
          158  +    |     16: 01 b5 01 a6 01 97 01 88 01 79 01 6a 00 00 00 00   .........y.j....
          159  +    |    352: 00 00 00 00 00 00 00 00 00 00 0d 48 00 00 48 01   ...........H..H.
          160  +    |    368: 54 00 01 f7 01 ec 01 c5 01 0d 47 00 00 48 01 54   T.........G..H.T
          161  +    |    384: 00 01 f7 01 ec 01 c5 01 0d 46 00 00 48 01 54 00   .........F..H.T.
          162  +    |    400: 01 f7 01 ec 01 c5 01 0d 45 00 00 48 01 54 00 01   ........E..H.T..
          163  +    |    416: f7 01 ec 01 c5 01 0d 44 00 00 48 01 54 00 01 f7   .......D..H.T...
          164  +    |    432: 01 ec 01 c5 01 0d 43 00 00 48 01 54 00 01 f7 01   ......C..H.T....
          165  +    |    448: ec 01 c5 01 0d 42 00 00 48 01 54 00 01 f7 01 ec   .....B..H.T.....
          166  +    |    464: 01 c5 01 0d 41 00 00 48 01 54 00 01 f7 01 ec 01   ....A..H.T......
          167  +    |    480: c5 01 0d 40 00 00 48 01 54 00 01 f7 01 ec 01 c5   ...@..H.T.......
          168  +    |    496: 01 0d 3f 00 00 48 01 54 00 01 f7 01 ec 01 c5 01   ..?..H.T........
          169  +    | end c4.db
          170  +  }]
          171  +  db eval {PRAGMA integrity_check}
          172  +} {/Fragmentation of 384 bytes reported as 0 on page 8/}
          173  +
          174  +# The DELETE query below deletes the very last cell from page 8.
          175  +# Prior to a certain fix to sqlite3BtreeDelete() and because of the
          176  +# corruption to the freeblock list on page 8, this would fail to
          177  +# cause a rebalance operation, which would leave the btree in a weird
          178  +# state that would lead to segfaults and or assertion faults.
          179  +#
          180  +do_execsql_test dbfuzz001-110 {
          181  +  DELETE FROM t3 WHERE x IS NOT NULL AND +rowid=6;
          182  +} {}
          183  +
          184  +# This is a dbfuzz2-generate test case that can cause a page with
          185  +# pPage->nCell==0 to enter the balancer.
          186  +#
          187  +do_test dbfuzz001-200 {
          188  +  db deserialize [decode_hexdb {
          189  +    | size 3076 pagesize 512 filename c03.db
          190  +    | page 1 offset 0
          191  +    |      0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00   SQLite format 3.
          192  +    |     16: 02 00 01 01 00 40 20 20 00 00 00 0c 00 00 00 07   .....@  ........
          193  +    |     32: 00 00 00 00 00 00 00 00 00 00 00 08 00 00 00 04   ................
          194  +    |     48: 00 00 00 00 00 00 00 03 e8 00 00 01 00 00 00 00   ................
          195  +    |     80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0c   ................
          196  +    |     96: 00 2e 2c 50 0d 00 00 00 06 01 06 00 01 da 01 b0   ..,P............
          197  +    |    112: 01 56 01 86 01 2a 01 06 00 00 00 00 00 00 00 00   .V...*..........
          198  +    |    128: 00 00 00 00 00 00 00 00 ef 00 00 00 00 00 00 00   ................
          199  +    |    192: 00 7f 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
          200  +    |    224: 00 00 00 00 00 00 00 00 00 00 00 00 00 ff e9 00   ................
          201  +    |    256: 00 00 00 00 00 00 22 07 06 17 11 11 01 31 74 61   ......"......1ta
          202  +    |    272: 62 6c 65 74 34 74 34 07 43 52 45 41 54 45 20 54   blet4t4.CREATE T
          203  +    |    288: 41 42 4c 45 20 74 34 28 78 29 2a 06 06 17 13 11   ABLE t4(x)*.....
          204  +    |    304: 01 3f 69 6e 64 65 78 74 33 78 74 33 06 43 52 45   .?indext3xt3.CRE
          205  +    |    320: 41 54 45 20 49 4e 44 45 58 20 74 33 64 20 4f 4e   ATE INDEX t3d ON
          206  +    |    336: 20 74 33 28 78 29 2e 04 06 17 15 11 01 45 69 6e    t3(x).......Ein
          207  +    |    352: 64 65 78 74 32 63 64 74 32 05 43 52 45 41 54 45   dext2cdt2.CREATE
          208  +    |    368: 20 49 4e 44 45 58 20 74 32 63 64 20 4f 4e 20 74    INDEX t2cd ON t
          209  +    |    384: 32 28 63 2c 64 29 28 05 06 17 11 11 01 3d 74 61   2(c,d)(......=ta
          210  +    |    400: 62 6c 65 74 33 74 33 04 43 52 45 41 54 45 20 54   blet3t3.CREATE T
          211  +    |    416: 41 42 4c 45 20 74 33 28 63 2c 78 2c 65 2c 66 29   ABLE t3(c,x,e,f)
          212  +    |    432: 28 02 06 17 11 11 01 3d 74 61 62 6c 65 74 32 74   (......=tablet2t
          213  +    |    448: 32 03 43 52 45 41 54 45 20 54 41 42 4c 45 20 74   2.CREATE TABLE t
          214  +    |    464: 32 28 63 2c 64 2c 65 2c 66 29 24 01 06 17 11 11   2(c,d,e,f)$.....
          215  +    |    480: 01 35 74 61 62 6c 65 74 31 74 31 02 43 52 45 41   .5tablet1t1.CREA
          216  +    |    496: 54 45 20 54 41 42 4c 45 20 74 31 28 61 2c 62 29   TE TABLE t1(a,b)
          217  +    | page 2 offset 512
          218  +    |      0: 0d 00 00 00 04 01 cf 00 01 fa 01 f3 01 de 01 cf   ................
          219  +    |    176: 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
          220  +    |    256: 00 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
          221  +    |    368: 00 00 00 00 00 00 00 00 00 00 00 00 1e 00 00 00   ................
          222  +    |    416: 00 00 00 1b 00 00 00 00 04 00 00 00 00 00 00 00   ................
          223  +    |    448: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0d   ................
          224  +    |    464: 04 03 17 17 73 65 76 65 6e 65 69 67 68 74 13 03   ....seveneight..
          225  +    |    480: 03 07 07 40 14 00 00 00 00 00 00 40 18 00 00 00   ...@.......@....
          226  +    |    496: 00 00 00 05 02 03 01 01 03 04 04 01 03 09 01 02   ................
          227  +    | page 3 offset 1024
          228  +    |      0: 0d 00 00 00 08 01 54 00 01 f7 01 ec 01 c5 01 aa   ......T.........
          229  +    |     16: 01 a1 01 96 01 6f 01 54 00 00 00 00 00 00 00 00   .....o.T........
          230  +    |     32: 00 00 00 00 00 00 00 03 e8 00 00 00 00 00 00 00   ................
          231  +    |    336: 00 00 00 00 19 08 05 16 17 17 17 65 69 67 68 74   ...........eight
          232  +    |    352: 65 69 67 68 74 73 65 76 65 6e 73 65 76 ff ff ff   eightsevensev...
          233  +    |    368: 0e 05 07 07 07 07 40 18 00 00 00 00 00 00 40 18   ......@.......@.
          234  +    |    384: 00 00 00 00 00 00 40 14 00 00 00 00 00 00 40 14   ......@.......@.
          235  +    |    400: 00 00 00 00 00 00 09 06 05 01 01 01 01 04 04 03   ................
          236  +    |    416: 03 07 05 05 01 01 09 09 02 02 19 04 05 17 17 17   ................
          237  +    |    432: 17 73 65 6f 65 6e 65 69 67 68 74 65 69 67 68 74   .seoeneighteight
          238  +    |    448: 73 65 76 65 6e 25 03 05 07 07 07 07 40 14 00 00   seven%......@...
          239  +    |    464: 00 00 00 00 40 18 00 00 00 00 00 00 40 18 00 00   ....@.......@...
          240  +    |    480: 00 00 00 00 40 14 00 00 00 00 00 00 09 02 05 01   ....@...........
          241  +    |    496: 01 01 01 03 04 04 03 07 01 05 09 01 01 09 02 02   ................
          242  +    | page 4 offset 1536
          243  +    |      0: 0d 00 00 00 00 00 10 00 00 00 00 00 00 00 00 00   ................
          244  +    |    160: 00 00 00 ea 00 00 00 00 00 00 00 00 00 00 00 00   ................
          245  +    |    336: 00 00 00 00 00 00 00 00 00 00 00 00 20 00 00 00   ............ ...
          246  +    | page 5 offset 2048
          247  +    |      0: 0a 00 00 00 08 01 96 00 01 fa 01 c4 01 f2 01 bc   ................
          248  +    |     16: 01 dc 01 a6 01 96 01 cc 00 00 00 00 00 00 00 00   ................
          249  +    |     48: 00 00 00 00 00 00 00 00 00 00 10 00 00 00 00 00   ................
          250  +    |    288: 00 00 00 00 00 00 00 00 00 64 00 00 00 2b 00 00   .........d...+..
          251  +    |    400: 00 00 00 00 00 00 0f 04 17 17 01 65 69 67 68 74   ...........eight
          252  +    |    416: 65 69 6f 68 74 08 15 04 07 07 01 40 18 00 00 00   eioht......@....
          253  +    |    432: 00 00 00 40 18 00 00 00 00 00 00 07 07 04 01 01   ...@............
          254  +    |    448: 01 04 04 06 07 04 01 01 01 02 02 05 0f 04 17 17   ................
          255  +    |    464: 01 73 65 76 65 6e 65 69 67 68 74 04 15 04 07 07   .seveneight.....
          256  +    |    480: 01 40 14 00 00 00 00 00 00 40 18 00 00 00 00 00   .@.......@......
          257  +    |    496: 00 03 07 04 01 01 01 03 04 02 05 04 09 01 09 02   ................
          258  +    | page 6 offset 2560
          259  +    |      0: 0a 00 00 00 00 02 00 00 00 00 00 00 00 0d 00 00   ................
          260  +    |     16: 00 08 01 c2 00 01 fb 01 f6 01 f1 01 ec 01 e0 01   ................
          261  +    |     32: d4 01 cb 01 c2 00 00 00 00 00 00 00 00 00 00 00   ................
          262  +    |    160: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 04 00   ................
          263  +    |    448: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 07   ................
          264  +    |    464: 08 02 17 65 69 67 68 74 07 07 02 17 65 69 67 68   ...eight....eigh
          265  +    |    480: 74 0a 06 02 07 40 18 00 00 00 00 00 00 0a 05 02   t....@..........
          266  +    |    496: 07 40 18 00 04 02 01 04 03 03 02 01 04 03 02 02   .@..............
          267  +    | end x/c03.db
          268  +  }]
          269  +  catchsql {INSERT INTO t3 SELECT * FROM t2;}
          270  +} {1 {database disk image is malformed}}
          271  +
          272  +
          273  +do_test dbfuzz001-110 {
          274  +  sqlite3 db {}
          275  +  db deserialize [decode_hexdb {
          276  +| size 3584 pagesize 512 filename x/c02.db
          277  +| page 1 offset 0
          278  +|      0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00   SQLite format 3.
          279  +|     16: 02 00 01 01 00 40 20 20 00 00 00 0c 00 00 00 07   .....@  ........
          280  +|     32: 00 00 00 00 00 00 00 00 00 00 00 08 00 00 00 04   ................
          281  +|     48: 00 00 00 00 00 00 00 04 00 00 00 01 00 00 00 00   ................
          282  +|     80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0c   ................
          283  +|     96: 00 2e 2c 50 0d 00 00 00 06 01 06 00 01 da 01 b0   ..,P............
          284  +|    112: 01 56 01 86 01 2a 01 06 00 00 00 00 00 00 00 00   .V...*..........
          285  +|    256: 00 00 00 00 00 00 22 07 06 17 11 11 01 31 74 61   ......"......1ta
          286  +|    272: 62 6c 65 74 34 74 34 07 43 52 45 41 54 45 20 54   blet4t4.CREATE T
          287  +|    288: 41 42 4c 45 20 74 34 28 78 29 2a 06 06 17 13 11   ABLE t4(x)*.....
          288  +|    304: 01 3f 69 6e 64 65 78 74 33 78 74 33 05 43 52 45   .?indext3xt3.CRE
          289  +|    320: 41 54 45 20 49 4e 44 45 58 20 74 33 78 20 4f 4e   ATE INDEX t3x ON
          290  +|    336: 20 74 33 28 78 29 2e 04 06 17 15 11 01 45 69 6e    t3(x).......Ein
          291  +|    352: 64 65 78 74 32 63 64 74 32 05 43 52 45 41 54 45   dext2cdt2.CREATE
          292  +|    368: 20 49 4e 44 45 58 20 74 32 63 64 20 4f 4e 20 74    INDEX t2cd ON t
          293  +|    384: 32 28 63 2c 64 29 28 05 06 17 11 11 01 3d 74 61   2(c,d)(......=ta
          294  +|    400: 62 6c 65 74 33 74 33 07 43 52 45 41 54 45 20 54   blet3t3.CREATE T
          295  +|    416: 41 42 4c 45 20 74 33 28 63 2c 78 2c 65 2c 66 29   ABLE t3(c,x,e,f)
          296  +|    432: 28 02 06 17 11 11 01 3d 74 61 74 65 6c 03 62 74   (......=tatel.bt
          297  +|    448: 32 32 43 52 45 41 54 45 20 54 41 42 4c 45 20 74   22CREATE TABLE t
          298  +|    464: 32 28 63 2c 64 2c 65 2c 66 29 24 01 06 17 11 11   2(c,d,e,f)$.....
          299  +|    480: 01 35 74 61 62 6c 65 74 31 74 31 02 43 52 45 41   .5tablet1t1.CREA
          300  +|    496: 54 45 20 54 41 42 4c 45 20 74 31 28 61 2c 62 29   TE TABLE t1(a,b)
          301  +| page 2 offset 512
          302  +|      0: 0d 00 00 00 04 01 cf 00 01 fa 01 f3 01 de 01 cf   ................
          303  +|    160: 00 00 20 00 00 00 00 00 00 00 00 00 00 00 00 00   .. .............
          304  +|    448: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0d   ................
          305  +|    464: 04 03 17 17 73 65 76 65 6e 65 69 67 68 74 13 03   ....seveneight..
          306  +|    480: 03 07 07 40 14 00 00 00 00 00 00 40 18 00 00 00   ...@.......@....
          307  +|    496: 00 00 00 05 02 03 01 01 03 04 04 01 03 09 01 02   ................
          308  +| page 3 offset 1024
          309  +|      0: 0d 00 00 00 08 01 54 00 01 f7 01 ec 01 c5 01 aa   ......T.........
          310  +|     16: 01 a1 01 96 01 6f 01 54 00 00 00 00 00 00 00 00   .....o.T........
          311  +|    112: 00 00 dd 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
          312  +|    336: 00 00 00 00 19 08 05 17 17 17 17 65 69 67 68 74   ...........eight
          313  +|    352: 65 69 67 68 74 73 65 76 65 6e 73 65 76 65 6e 25   eightsevenseven%
          314  +|    368: 07 05 07 07 07 07 40 18 00 00 00 00 00 00 40 18   ......@.......@.
          315  +|    384: 00 00 00 00 00 00 40 14 00 00 00 00 00 00 40 14   ......@.......@.
          316  +|    400: 00 00 00 00 00 00 09 06 05 01 01 01 01 04 04 03   ................
          317  +|    416: 03 07 05 05 01 01 09 09 02 02 19 04 05 17 17 17   ................
          318  +|    432: 17 73 65 76 65 6e 65 69 67 68 74 65 69 67 68 74   .seveneighteight
          319  +|    448: 73 65 76 65 6e 25 03 05 07 07 07 07 40 14 00 00   seven%......@...
          320  +|    464: 00 00 00 00 40 18 00 00 00 00 00 00 40 18 00 00   ....@.......@...
          321  +|    480: 00 00 00 00 40 14 00 00 00 00 00 00 09 02 05 01   ....@...........
          322  +|    496: 01 01 01 03 04 04 03 07 01 05 09 01 01 09 02 02   ................
          323  +| page 4 offset 1536
          324  +|      0: 0d 00 00 00 00 02 00 00 00 00 00 00 00 00 00 00   ................
          325  +|    192: 00 00 00 00 00 00 7f 00 00 00 00 00 00 00 00 00   ................
          326  +|    208: 00 e5 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
          327  +| page 5 offset 2048
          328  +|      0: 0a 00 00 00 08 01 96 00 01 fa 01 c4 01 f2 01 bc   ................
          329  +|     16: 01 dc 01 a6 01 96 01 cc 00 00 00 00 00 00 00 00   ................
          330  +|    240: 00 00 00 00 00 00 00 00 00 00 00 00 00 0e 00 00   ................
          331  +|    400: 00 00 00 00 00 00 0f 04 17 07 01 65 69 67 68 74   ...........eight
          332  +|    416: 65 69 67 68 74 08 15 04 07 07 01 40 18 00 00 00   eight......@....
          333  +|    432: 00 00 00 40 18 00 00 00 00 00 00 07 07 04 01 01   ...@............
          334  +|    448: 01 04 04 06 07 04 01 01 01 02 02 05 0f 04 17 17   ................
          335  +|    464: 01 73 65 76 65 6e 65 69 67 68 74 04 15 04 07 07   .seveneight.....
          336  +|    480: 01 40 14 00 00 00 00 00 00 40 18 00 00 00 00 00   .@.......@......
          337  +|    496: 00 03 07 04 01 01 01 03 04 02 05 04 09 01 09 02   ................
          338  +| page 6 offset 2560
          339  +|      0: 0a 00 00 00 00 02 00 00 00 00 00 00 00 00 00 00   ................
          340  +|    464: 00 00 00 00 00 00 00 00 00 00 7f 00 00 00 00 00   ................
          341  +| page 7 offset 3072
          342  +|      0: 0d 00 00 00 08 01 c2 00 01 fb 01 f6 01 f1 01 ec   ................
          343  +|     16: 01 e0 01 d4 01 cb 01 c2 00 00 00 00 00 00 00 00   ................
          344  +|    448: 00 00 07 08 02 17 65 69 67 68 74 07 07 02 17 65   ......eight....e
          345  +|    464: 69 67 68 74 0a 06 02 07 40 18 00 00 00 00 00 00   ight....@.......
          346  +|    480: 0a 05 02 07 40 18 00 00 00 00 00 00 03 04 02 01   ....@...........
          347  +|    496: 04 03 03 02 01 04 03 02 02 01 02 03 01 02 01 02   ................
          348  +| end x/c02.db
          349  +  }]
          350  +  execsql {
          351  +    DELETE FROM t3 WHERE x IN (SELECT x FROM t4);
          352  +  }
          353  +} {}
          354  +
          355  +finish_test

Changes to test/e_select.test.

   163    163     2002.1  "SELECT ALL 1, 2, 3 GROUP BY 2 HAVING count(*)=1" {1 2 3}
   164    164     2002.2  "SELECT ALL 1, 2, 3 GROUP BY 2 HAVING count(*)>1" {}
   165    165   
   166    166     0101.1  "SELECT count(*), max(a) FROM t1 GROUP BY b" {1 a 1 c 1 b}
   167    167     0102.1  "SELECT count(*), max(a) FROM t1 GROUP BY b HAVING count(*)=1" {
   168    168       1 a 1 c 1 b
   169    169     }
   170         -  0102.2  "SELECT count(*), max(a) FROM t1 GROUP BY b HAVING count(*)=2" { }
          170  +  0102.2  "SELECT count(*), max(a) FROM t1 GROUP BY b HAVING count(*)=2" {}
   171    171   
   172    172     1101.1  "SELECT DISTINCT count(*), max(a) FROM t1 GROUP BY b" {1 a 1 c 1 b}
   173    173     1102.1  "SELECT DISTINCT count(*), max(a) FROM t1 
   174    174              GROUP BY b HAVING count(*)=1" {
   175    175       1 a 1 c 1 b
   176    176     }
   177    177     1102.2  "SELECT DISTINCT count(*), max(a) FROM t1 
   178         -           GROUP BY b HAVING count(*)=2" { 
   179         -  }
          178  +           GROUP BY b HAVING count(*)=2" {}
   180    179   
   181    180     2101.1  "SELECT ALL count(*), max(a) FROM t1 GROUP BY b" {1 a 1 c 1 b}
   182    181     2102.1  "SELECT ALL count(*), max(a) FROM t1 
   183    182              GROUP BY b HAVING count(*)=1" {
   184    183       1 a 1 c 1 b
   185    184     }
   186    185     2102.2  "SELECT ALL count(*), max(a) FROM t1 
   187         -           GROUP BY b HAVING count(*)=2" { 
   188         -  }
          186  +           GROUP BY b HAVING count(*)=2" {}
   189    187   
   190    188     0011.1  "SELECT 1, 2, 3 WHERE 1 GROUP BY 2" {1 2 3}
   191    189     0012.1  "SELECT 1, 2, 3 WHERE 0 GROUP BY 2 HAVING count(*)=1" {}
   192    190     0012.2  "SELECT 1, 2, 3 WHERE 0 GROUP BY 2 HAVING count(*)>1" {}
   193    191   
   194    192     1011.1  "SELECT DISTINCT 1, 2, 3 WHERE 0 GROUP BY 2" {}
   195    193     1012.1  "SELECT DISTINCT 1, 2, 3 WHERE 1 GROUP BY 2 HAVING count(*)=1" 
................................................................................
   200    198     2012.1  "SELECT ALL 1, 2, 3 WHERE 0 GROUP BY 2 HAVING count(*)=1" {}
   201    199     2012.2  "SELECT ALL 1, 2, 3 WHERE 'abc' GROUP BY 2 HAVING count(*)>1" {}
   202    200   
   203    201     0111.1  "SELECT count(*), max(a) FROM t1 WHERE a='a' GROUP BY b" {1 a}
   204    202     0112.1  "SELECT count(*), max(a) FROM t1 
   205    203              WHERE a='c' GROUP BY b HAVING count(*)=1" {1 c}
   206    204     0112.2  "SELECT count(*), max(a) FROM t1 
   207         -           WHERE 0 GROUP BY b HAVING count(*)=2" { }
          205  +           WHERE 0 GROUP BY b HAVING count(*)=2" {}
   208    206     1111.1  "SELECT DISTINCT count(*), max(a) FROM t1 WHERE a<'c' GROUP BY b" 
   209    207             {1 a 1 b}
   210    208     1112.1  "SELECT DISTINCT count(*), max(a) FROM t1 WHERE a>'a'
   211    209              GROUP BY b HAVING count(*)=1" {
   212    210       1 c 1 b
   213    211     }
   214    212     1112.2  "SELECT DISTINCT count(*), max(a) FROM t1 WHERE 0
   215         -           GROUP BY b HAVING count(*)=2" { 
   216         -  }
          213  +           GROUP BY b HAVING count(*)=2" {}
   217    214   
   218    215     2111.1  "SELECT ALL count(*), max(a) FROM t1 WHERE b>'one' GROUP BY b" 
   219    216             {1 c 1 b}
   220    217     2112.1  "SELECT ALL count(*), max(a) FROM t1 WHERE a!='b'
   221    218              GROUP BY b HAVING count(*)=1" {
   222    219       1 a 1 c
   223    220     }
   224    221     2112.2  "SELECT ALL count(*), max(a) FROM t1 
   225         -           WHERE 0 GROUP BY b HAVING count(*)=2" { }
          222  +           WHERE 0 GROUP BY b HAVING count(*)=2" {}
   226    223   }
   227    224   
   228    225   
   229    226   # -- syntax diagram result-column
   230    227   #
   231    228   do_select_tests e_select-0.3 {
   232    229     1  "SELECT * FROM t1" {a one b two c three}

Changes to test/fkey8.test.

   160    160     END;
   161    161   }
   162    162   
   163    163   do_catchsql_test 2.3.1 {
   164    164     DELETE FROM p3 WHERE a=1
   165    165   } {1 {FOREIGN KEY constraint failed}}
   166    166   
          167  +
          168  +do_execsql_test 3.0 {
          169  +  PRAGMA foreign_keys=ON;
          170  +  CREATE TABLE t2(
          171  +    a PRIMARY KEY, b, c, d, e,
          172  +      FOREIGN KEY(b, c) REFERENCES t2(d, e)
          173  +  ) WITHOUT ROWID;
          174  +  CREATE UNIQUE INDEX idx ON t2(d, e);
          175  +
          176  +  INSERT INTO t2 VALUES(1, 'one', 'one', 'one', 'one'); -- row is parent of self
          177  +  INSERT INTO t2 VALUES(2, 'one', 'one', 'one', NULL);  -- parent is row 1
          178  +}
          179  +
          180  +do_catchsql_test 3.1 {
          181  +  DELETE FROM t2 WHERE a=1;
          182  +} {1 {FOREIGN KEY constraint failed}}
          183  +
          184  +do_execsql_test 4.0 {
          185  +  CREATE TABLE t1 (
          186  +      c1 PRIMARY KEY,
          187  +      c2 NUMERIC,
          188  +      FOREIGN KEY(c1) REFERENCES t1(c2)
          189  +      ) WITHOUT ROWID ;
          190  +  CREATE INDEX t1c1 ON t1(c1);
          191  +  CREATE UNIQUE INDEX t1c1unique ON t1(c2);
          192  +}
          193  +do_catchsql_test 4.1 {
          194  +  INSERT OR REPLACE INTO t1 VALUES(10000, 20000);
          195  +} {1 {FOREIGN KEY constraint failed}}
          196  +do_execsql_test 4.2 {
          197  +  INSERT OR REPLACE INTO t1 VALUES(20000, 20000);
          198  +}
          199  +
   167    200   finish_test
          201  +

Changes to test/fts3aa.test.

   246    246   do_execsql_test 9.1 {
   247    247     CREATE VIRTUAL TABLE t9 USING fts4(a, "", '---');
   248    248   }
   249    249   do_execsql_test 9.2 {
   250    250     CREATE VIRTUAL TABLE t10 USING fts3(<, b, c);
   251    251   }
   252    252   
          253  +do_execsql_test 10.0 {
          254  +  CREATE VIRTUAL TABLE z1 USING fts3;
          255  +  INSERT INTO z1 VALUES('one two three'),('four one five'),('six two five');
          256  +  CREATE TRIGGER z1r1 AFTER DELETE ON z1_content BEGIN
          257  +    DELETE FROM z1;
          258  +  END;
          259  +}
          260  +do_catchsql_test 10.1 {
          261  +  DELETE FROM z1;
          262  +} {1 {SQL logic error}}
          263  +
   253    264   expand_all_sql db
   254    265   finish_test

Changes to test/fts3corrupt4.test.

   140    140     UPDATE ft_segdir 
   141    141     SET root = blob('0101056162633132FFFFFFFF070236030132030136');
   142    142   }
   143    143   
   144    144   do_catchsql_test 3.1 {
   145    145     SELECT * FROM ft WHERE ft MATCH 'abc20'
   146    146   } {1 {database disk image is malformed}}
          147  +
          148  +#-------------------------------------------------------------------------
          149  +reset_db
          150  +do_execsql_test 4.0 {
          151  +  CREATE VIRTUAL TABLE t1 USING fts3();
          152  +  INSERT INTO t1 VALUES('one two three');
          153  +  UPDATE t1_segdir SET start_block = 1;
          154  +}
          155  +
          156  +do_catchsql_test 4.1 { 
          157  +  SELECT * FROM t1 WHERE t1 MATCH 'one'; 
          158  +} {1 {database disk image is malformed}}
          159  +do_catchsql_test 4.2 { 
          160  +  SELECT * FROM t1 WHERE t1 MATCH 'two'; 
          161  +} {1 {database disk image is malformed}}
          162  +do_catchsql_test 4.3 { 
          163  +  SELECT * FROM t1 WHERE t1 MATCH 'three'; 
          164  +} {1 {database disk image is malformed}}
          165  +do_execsql_test 4.4 {
          166  +  INSERT INTO t1(t1) VALUES('optimize');
          167  +}
          168  +
          169  +#-------------------------------------------------------------------------
          170  +reset_db
          171  +do_test 5.0 {
          172  +  sqlite3 db {}
          173  +  db deserialize [decode_hexdb {
          174  +| size 24576 pagesize 4096 filename c15.db
          175  +| page 1 offset 0
          176  +|      0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00   SQLite format 3.
          177  +|     16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 04   .....@  ........
          178  +|     32: 00 00 00 00 00 00 00 00 00 00 00 04 00 00 00 04   ................
          179  +|     48: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00   ................
          180  +|     96: 00 00 00 00 0d 0e f9 00 06 0d ec 00 0f cd 0f 69   ...............i
          181  +|    112: 0f 01 0e 10 0e c6 0d ec 00 00 00 00 00 00 00 00   ................
          182  +|   3552: 00 00 00 00 00 00 00 00 00 00 00 00 22 06 06 17   ................
          183  +|   3568: 11 11 01 31 74 61 62 6c 65 74 32 74 32 06 43 52   ...1tablet2t2.CR
          184  +|   3584: 45 41 54 45 20 54 41 42 4c 45 20 74 32 28 78 29   EATE TABLE t2(x)
          185  +|   3600: 81 33 04 07 17 1f 1f 01 82 35 74 61 62 6c 65 74   .3.......5tablet
          186  +|   3616: 31 5f 73 65 67 64 69 72 74 31 5f 73 65 67 64 69   1_segdirt1_segdi
          187  +|   3632: 72 04 43 52 45 41 54 45 20 54 41 42 4c 45 20 27   r.CREATE TABLE '
          188  +|   3648: 74 31 5f 73 65 67 64 69 72 27 28 6c 65 76 65 6c   t1_segdir'(level
          189  +|   3664: 20 49 4e 54 45 47 45 52 2c 69 64 78 20 49 4e 54    INTEGER,idx INT
          190  +|   3680: 45 47 45 52 2c 73 74 61 72 74 5f 62 6c 6f 63 6b   EGER,start_block
          191  +|   3696: 20 49 4e 54 45 47 45 52 2c 6c 65 61 76 65 73 5f    INTEGER,leaves_
          192  +|   3712: 65 6e 64 5f 62 6c 6f 63 6b 20 49 4e 54 45 47 45   end_block INTEGE
          193  +|   3728: 52 2c 65 6e 64 5f 62 6c 6f 63 6b 20 49 4e 54 45   R,end_block INTE
          194  +|   3744: 47 45 52 2c 72 6f 6f 74 20 42 4c 4f 42 2c 50 52   GER,root BLOB,PR
          195  +|   3760: 49 4d 41 52 59 20 4b 45 59 28 6c 65 76 65 6c 2c   IMARY KEY(level,
          196  +|   3776: 20 69 64 78 29 29 31 05 06 17 45 1f 01 00 69 6e    idx))1...E...in
          197  +|   3792: 64 65 78 73 71 6c 69 74 65 5f 61 75 74 6f 69 6e   dexsqlite_autoin
          198  +|   3808: 64 65 79 5f 74 31 5f 73 65 67 64 69 72 5f 31 74   dey_t1_segdir_1t
          199  +|   3824: 31 5f 73 65 67 64 69 72 05 00 00 00 08 00 00 00   1_segdir........
          200  +|   3840: 00 66 03 07 17 23 23 01 81 13 74 61 62 6c 65 74   .f...##...tablet
          201  +|   3856: 31 5f 73 65 67 6d 65 6e 74 73 74 31 5f 73 65 67   1_segmentst1_seg
          202  +|   3872: 6d 65 6e 74 73 03 43 52 45 41 54 45 20 54 41 42   ments.CREATE TAB
          203  +|   3888: 4c 45 20 27 74 31 5f 73 65 67 6d 65 6e 74 73 27   LE 't1_segments'
          204  +|   3904: 28 62 6c 6f 63 6b 69 64 20 49 4e 54 45 47 45 52   (blockid INTEGER
          205  +|   3920: 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 62 6c    PRIMARY KEY, bl
          206  +|   3936: 6f 63 6b 20 42 4c 4f 42 29 62 02 07 17 21 21 01   ock BLOB)b...!!.
          207  +|   3952: 81 0f 74 61 62 6c 65 74 31 5f 63 6f 6e 74 65 6e   ..tablet1_conten
          208  +|   3968: 74 74 31 5f 63 6f 6e 74 65 6e 74 02 43 52 45 41   tt1_content.CREA
          209  +|   3984: 54 45 20 54 41 42 4c 45 20 27 74 31 5f 63 6f 6e   TE TABLE 't1_con
          210  +|   4000: 74 65 6e 74 27 28 64 6f 63 69 64 20 49 4e 54 45   tent'(docid INTE
          211  +|   4016: 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c   GER PRIMARY KEY,
          212  +|   4032: 20 27 63 30 63 6f 6e 74 65 6e 74 27 29 31 01 06    'c0content')1..
          213  +|   4048: 17 11 11 08 51 74 61 62 6c 65 74 31 74 31 43 52   ....Qtablet1t1CR
          214  +|   4064: 45 41 54 45 20 56 49 52 54 55 41 4c 20 54 41 42   EATE VIRTUAL TAB
          215  +|   4080: 4c 45 20 74 31 20 55 53 49 4e 47 20 66 74 73 33   LE t1 USING fts3
          216  +| page 2 offset 4096
          217  +|      0: 0d 00 00 00 03 0f e0 00 0f f6 0f ec 0f e0 00 00   ................
          218  +|   4064: 0a 03 03 00 1b 61 62 61 6e 64 6f 6e 08 02 03 00   .....abandon....
          219  +|   4080: 17 61 62 61 66 74 08 01 03 00 17 61 62 61 63 6b   .abaft.....aback
          220  +| page 3 offset 8192
          221  +|      0: 0d 00 00 00 00 10 00 00 00 00 00 00 00 00 00 00   ................
          222  +| page 4 offset 12288
          223  +|      0: 0d 00 00 00 01 0f d6 00 0f d6 00 00 00 00 00 00   ................
          224  +|   4048: 00 00 00 00 00 00 28 01 07 08 08 08 08 15 46 30   ......(.......F0
          225  +|   4064: 20 32 39 00 05 61 62 61 63 6b 03 01 02 00 03 02    29..aback......
          226  +|   4080: 66 74 03 02 02 00 03 04 6e 64 6f 60 30 30 20 00   ft......ndo`00 .
          227  +| page 5 offset 16384
          228  +|      0: a0 00 00 00 10 ff b0 00 ff fb 00 00 00 00 00 00   ................
          229  +|   4080: 00 00 00 00 00 00 00 00 00 00 00 04 04 08 08 09   ................
          230  +| page 6 offset 20480
          231  +|      0: 0d 00 00 00 05 0f b8 00 0f f4 0f e9 0f d6 0f c7   ................
          232  +|     16: 0f b8 27 74 31 5f 63 6f 6e 74 65 6e 74 27 28 64   ..'t1_content'(d
          233  +|     32: 6f 63 69 64 20 49 4e 54 45 47 45 52 20 50 52 49   ocid INTEGER PRI
          234  +|     48: 4d 41 52 59 20 4b 45 59 2c 20 27 63 30 63 6f 6e   MARY KEY, 'c0con
          235  +|     64: 74 65 6e 74 27 29 31 01 06 17 11 11 08 51 74 61   tent')1......Qta
          236  +|     80: 62 6c 65 74 31 74 31 43 52 45 41 54 45 20 56 49   blet1t1CREATE VI
          237  +|     96: 52 54 55 41 4c 20 54 41 42 4c 45 20 74 31 20 55   RTUAL TABLE t1 U
          238  +|    112: 53 49 4e 47 20 66 74 73 33 0d 00 00 00 03 0f e0   SING fts3.......
          239  +|    128: 00 0f f6 0f ec 0f e0 00 00 00 00 00 00 00 00 00   ................
          240  +|   4016: 00 00 00 00 00 00 00 00 0d 05 02 23 61 75 74 6f   ...........#auto
          241  +|   4032: 6d 65 72 67 65 3d 35 0d 04 02 23 6d 65 72 67 65   merge=5...#merge
          242  +|   4048: 3d 31 30 30 2c 38 11 03 02 2b 69 6e 74 65 67 72   =100,8...+integr
          243  +|   4064: 69 74 79 2d 63 68 65 63 6b 09 02 02 1b 72 65 62   ity-check....reb
          244  +|   4080: 75 69 6c 64 0a 01 02 1d 6f 70 74 69 6d 69 7a 65   uild....optimize
          245  +| end c15.db
          246  +}]} {}
          247  +
          248  +do_catchsql_test 5.1 {
          249  +  SELECT * FROM t1 WHERE t1 MATCH 'abandon';
          250  +} {1 {database disk image is malformed}}
   147    251   
   148    252   finish_test

Added test/fts3fuzz001.test.

            1  +# 2012-12-21
            2  +#
            3  +# The author disclaims copyright to this source code.  In place of
            4  +# a legal notice, here is a blessing:
            5  +#
            6  +#    May you do good and not evil.
            7  +#    May you find forgiveness for yourself and forgive others.
            8  +#    May you share freely, never taking more than you give.
            9  +#
           10  +#***********************************************************************
           11  +#
           12  +# Test cases for corrupt database files.
           13  +
           14  +set testdir [file dirname $argv0]
           15  +source $testdir/tester.tcl
           16  +
           17  +ifcapable !deserialize||!fts3 {
           18  +  finish_test
           19  +  return
           20  +}
           21  +database_may_be_corrupt
           22  +
           23  +do_test fts3fuzz001-100 {
           24  +  sqlite3 db {}
           25  +  db deserialize [decode_hexdb {
           26  +| size 24576 pagesize 4096 filename c6.db
           27  +| page 1 offset 0
           28  +|      0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00   SQLite format 3.
           29  +|     16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 06   .....@  ........
           30  +|     32: 00 00 00 00 00 00 00 00 00 00 00 05 00 00 00 04   ................
           31  +|     48: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00   ................
           32  +|     96: 00 00 00 00 0d 0e f9 00 06 0d ec 00 0f cd 0f 69   ...............i
           33  +|    112: 0f 01 0e 10 0e c6 0d ec 00 00 00 00 00 00 00 00   ................
           34  +|   3552: 00 00 00 00 00 00 00 00 00 00 00 00 22 06 06 17   ............"...
           35  +|   3568: 11 11 01 31 74 61 62 6c 65 74 32 74 32 06 43 52   ...1tablet2t2.CR
           36  +|   3584: 45 41 54 45 20 54 41 42 4c 45 20 74 32 28 78 29   EATE TABLE t2(x)
           37  +|   3600: 81 33 04 07 17 1f 1f 01 82 35 74 61 62 6c 65 74   .3.......5tablet
           38  +|   3616: 31 5f 73 65 67 64 69 72 74 31 5f 73 65 67 64 69   1_segdirt1_segdi
           39  +|   3632: 72 04 43 52 45 41 54 45 20 54 41 42 4c 45 20 27   r.CREATE TABLE '
           40  +|   3648: 74 31 5f 73 65 67 64 69 72 27 28 6c 65 76 65 6c   t1_segdir'(level
           41  +|   3664: 20 49 4e 54 45 47 45 52 2c 69 64 78 20 49 4e 54    INTEGER,idx INT
           42  +|   3680: 45 47 45 52 2c 73 74 61 72 74 5f 62 6c 6f 63 6b   EGER,start_block
           43  +|   3696: 20 49 4e 54 45 47 45 52 2c 6c 65 61 76 65 73 5f    INTEGER,leaves_
           44  +|   3712: 65 6e 64 5f 62 6c 6f 63 6b 20 49 4e 54 45 47 45   end_block INTEGE
           45  +|   3728: 52 2c 65 6e 64 5f 62 6c 6f 63 6b 20 49 4e 54 45   R,end_block INTE
           46  +|   3744: 47 45 52 2c 72 6f 6f 74 20 42 4c 4f 42 2c 50 52   GER,root BLOB,PR
           47  +|   3760: 49 4d 41 52 59 20 4b 45 59 28 6c 65 76 65 6c 2c   IMARY KEY(level,
           48  +|   3776: 20 69 64 78 29 29 31 05 06 17 45 1f 01 00 69 6e    idx))1...E...in
           49  +|   3792: 64 65 78 73 71 6c 69 74 65 5f 61 75 74 6f 69 6e   dexsqlite_autoin
           50  +|   3808: 64 65 78 5f 74 15 f7 36 56 76 46 97 25 f3 17 43   dex_t..6VvF.%..C
           51  +|   3824: 15 5f 73 65 67 64 69 72 05 00 00 00 08 00 00 00   ._segdir........
           52  +|   3840: 00 66 03 07 17 23 23 01 81 13 74 61 62 6c 65 74   .f...##...tablet
           53  +|   3856: 31 5f 73 65 67 6d 65 6e 74 73 74 31 5f 73 65 67   1_segmentst1_seg
           54  +|   3872: 6d 65 6e 74 73 03 43 52 45 41 54 45 20 54 41 42   ments.CREATE TAB
           55  +|   3888: 4c 45 20 27 74 31 5f 73 65 67 6d 65 6e 74 73 27   LE 't1_segments'
           56  +|   3904: 28 62 6c 6f 63 6b 69 64 20 49 4e 54 45 47 45 52   (blockid INTEGER
           57  +|   3920: 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 62 6c    PRIMARY KEY, bl
           58  +|   3936: 6f 63 6b 20 42 4c 4f 42 29 62 02 07 17 21 21 01   ock BLOB)b...!!.
           59  +|   3952: 81 0f 74 61 62 6c 65 74 31 5f 63 6f 6e 74 65 6e   ..tablet1_conten
           60  +|   3968: 74 74 31 5f 63 6f 6e 74 65 6e 74 02 43 52 45 41   tt1_content.CREA
           61  +|   3984: 54 45 20 54 41 42 4c 45 20 27 74 31 5f 63 6f 6e   TE TABLE 't1_con
           62  +|   4000: 74 65 6e 74 27 28 64 6f 63 69 64 20 49 4e 54 45   tent'(docid INTE
           63  +|   4016: 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c   GER PRIMARY KEY,
           64  +|   4032: 20 27 63 30 63 6f 6e 74 65 6e 74 27 29 31 01 06    'c0content')1..
           65  +|   4048: 17 11 11 08 51 74 61 62 6c 65 74 31 74 31 43 52   ....Qtablet1t1CR
           66  +|   4064: 45 41 54 45 20 56 49 52 54 55 41 4c 20 54 41 42   EATE VIRTUAL TAB
           67  +|   4080: 4c 45 20 74 31 20 55 53 49 4e 47 20 66 74 73 33   LE t1 USING fts3
           68  +| page 2 offset 4096
           69  +|      0: 0d 00 00 00 03 0f e0 00 0f f6 0f ec 0f e0 00 00   ................
           70  +|   4064: 0a 03 03 00 1b 61 62 61 6e 64 6f 6e 08 02 03 00   .....abandon....
           71  +|   4080: 17 61 62 61 66 74 08 01 03 00 17 61 62 61 63 6b   .abaft.....aback
           72  +| page 3 offset 8192
           73  +|      0: 0d 00 00 00 00 10 00 00 00 00 00 00 00 00 00 00   ................
           74  +| page 4 offset 12288
           75  +|      0: 0d 00 00 00 01 0f d6 00 0f 00 00 00 00 00 00 00   ................
           76  +|   4048: 00 00 00 00 00 00 28 01 07 08 08 08 08 15 46 30   ......(.......F0
           77  +|   4064: 20 32 39 00 05 61 62 61 63 6b 03 01 02 00 03 02    29..aback......
           78  +|   4080: 66 74 03 02 02 00 03 04 6e 64 6f 6e 03 03 02 00   ft......ndon....
           79  +| page 5 offset 16384
           80  +|      0: 0a 00 00 00 01 0f fb 00 0f fb 00 00 00 00 00 00   ................
           81  +|   4080: 00 00 00 00 00 00 00 00 00 00 00 04 04 08 08 09   ................
           82  +| page 6 offset 20480
           83  +|      0: 0d 00 00 00 05 0f b8 00 0f f4 0f e9 0f d6 0f c7   ................
           84  +|     16: 0f b8 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
           85  +|   4016: 00 00 00 00 00 00 00 00 0d 05 02 23 61 75 74 6f   ...........#auto
           86  +|   4032: 6d 65 72 67 65 3d 35 0d 04 02 23 6d 65 72 67 65   merge=5...#merge
           87  +|   4048: 3d 31 30 30 2c 38 11 03 02 2b 69 6e 74 65 67 72   =100,8...+integr
           88  +|   4064: 69 74 79 3d 63 68 65 63 6b 09 02 02 1b 72 65 62   ity=check....reb
           89  +|   4080: 75 69 6c 64 0a 01 02 1d 6f 70 74 69 6d 69 7a 65   uild....optimize
           90  +| end c6.db
           91  +  }]
           92  +  catchsql {
           93  +    INSERT INTO t1(t1) SELECT x FROM t2;
           94  +  }
           95  +} {1 {database disk image is malformed}}
           96  +do_test fts3fuzz001-110 {
           97  +  catchsql {
           98  +    INSERT INTO t1(t1) VALUES('integrity-check');
           99  +  }
          100  +} {1 {database disk image is malformed}}
          101  +do_test fts3fuzz001-120 {
          102  +  catchsql {
          103  +    INSERT INTO t1(t1) VALUES('optimize');
          104  +  }
          105  +} {0 {}}
          106  +do_test fts3fuzz001-121 {
          107  +  catchsql {
          108  +    INSERT INTO t1(t1) VALUES('integrity-check');
          109  +  }
          110  +} {1 {database disk image is malformed}}
          111  +
          112  +
          113  +finish_test

Changes to test/fts4umlaut.test.

    18     18   
    19     19   ifcapable !fts3 {
    20     20     finish_test
    21     21     return
    22     22   }
    23     23   
    24     24   do_execsql_test 1.0 {
    25         -  CREATE VIRTUAL TABLE t1 USING fts5(x);
           25  +  CREATE VIRTUAL TABLE t1 USING fts4(x, tokenize=unicode61);
    26     26     CREATE VIRTUAL TABLE t2 USING fts4(
    27     27         x, 
    28     28         tokenize=unicode61 "remove_diacritics=2"
    29     29     );
    30     30   }
    31     31   
    32     32   foreach {tn q res1 res2} {
................................................................................
    45     45     } $res1
    46     46     do_execsql_test 1.$tn.2 {
    47     47       DELETE FROM t1;
    48     48       INSERT INTO t1(rowid, x) VALUES (1, $q);
    49     49       SELECT count(*) FROM t1 WHERE t1 MATCH 'Ha Noi'
    50     50     } $res1
    51     51   
    52         -  do_execsql_test 1.$tn.2 {
           52  +  do_execsql_test 1.$tn.3 {
    53     53       DELETE FROM t2;
    54     54       INSERT INTO t2(rowid, x) VALUES (1, 'Ha Noi');
    55     55       SELECT count(*) FROM t2 WHERE t2 MATCH $q
    56     56     } $res2
    57         -  do_execsql_test 1.$tn.2 {
           57  +  do_execsql_test 1.$tn.4 {
    58     58       DELETE FROM t2;
    59     59       INSERT INTO t2(rowid, x) VALUES (1, $q);
    60     60       SELECT count(*) FROM t2 WHERE t2 MATCH 'Ha Noi'
    61     61     } $res2
    62     62   }
    63     63   
    64     64   finish_test
    65         -

Added test/fuzz4.test.

            1  +# 2018-12-12
            2  +#
            3  +# The author disclaims copyright to this source code.  In place of
            4  +# a legal notice, here is a blessing:
            5  +#
            6  +#    May you do good and not evil.
            7  +#    May you find forgiveness for yourself and forgive others.
            8  +#    May you share freely, never taking more than you give.
            9  +#
           10  +#***********************************************************************
           11  +# 
           12  +# Test cases found by Matthew Denton's fuzzer at Chrome.
           13  +#
           14  +
           15  +
           16  +set testdir [file dirname $argv0]
           17  +source $testdir/tester.tcl
           18  +
           19  +do_execsql_test fuzz4-100 {
           20  +  CREATE TABLE Table0 (Col0  NOT NULL DEFAULT (CURRENT_TIME IS 1 > 1));
           21  +  INSERT OR REPLACE INTO Table0 DEFAULT VALUES ;
           22  +  SELECT * FROM Table0;
           23  +} {0}
           24  +
           25  +do_execsql_test fuzz4-110 {
           26  +  CREATE TABLE Table1(
           27  +    Col0 TEXT DEFAULT (CASE WHEN 1 IS 3530822107858468864 
           28  +                            THEN 1 ELSE quote(1) IS 3530822107858468864 END)
           29  +  );
           30  +  INSERT INTO Table1 DEFAULT VALUES;
           31  +  SELECT * FROM Table1;
           32  +} {0}
           33  +
           34  +do_execsql_test fuzz4-200 {
           35  +  CREATE TABLE Table2a(
           36  +     Col0  NOT NULL   DEFAULT (CURRENT_TIME IS 1  IS NOT 1  > 1)
           37  +  );
           38  +  INSERT OR REPLACE INTO Table2a DEFAULT VALUES;
           39  +  SELECT * FROM Table2a;
           40  +} {0}
           41  +
           42  +do_execsql_test fuzz4-210 {
           43  +  CREATE TABLE Table2b (Col0  NOT NULL  DEFAULT (CURRENT_TIME  IS NOT FALSE)) ;
           44  +  INSERT OR REPLACE INTO Table2b DEFAULT VALUES ;
           45  +  SELECT * FROM Table2b;
           46  +} {1}
           47  +
           48  +do_execsql_test fuzz4-300 {
           49  +  CREATE TABLE Table3 (Col0 DEFAULT (CURRENT_TIMESTAMP BETWEEN 1 AND 1));
           50  +  INSERT INTO Table3 DEFAULT VALUES;
           51  +  SELECT * FROM Table3;
           52  +} {0}
           53  +
           54  +do_execsql_test fuzz4-400 {
           55  +  CREATE TABLE Table4 (Col0 DEFAULT (1 BETWEEN CURRENT_TIMESTAMP AND 1));
           56  +  INSERT INTO Table4 DEFAULT VALUES;
           57  +  SELECT * FROM Table4;
           58  +} {0}
           59  +
           60  +do_execsql_test fuzz4-500 {
           61  +  CREATE TABLE Table5 (Col0 DEFAULT (1 BETWEEN 1 AND CURRENT_TIMESTAMP));
           62  +  INSERT INTO Table5 DEFAULT VALUES;
           63  +  SELECT * FROM Table5;
           64  +} {1}
           65  +
           66  +do_execsql_test fuzz4-600 {
           67  +  CREATE TEMPORARY TABLE Table6(
           68  +    Col0 DEFAULT (CASE x'5d' WHEN 1 THEN
           69  +        CASE CURRENT_TIMESTAMP WHEN 1 THEN 1 ELSE 1 END
           70  +        ELSE CASE WHEN 1 THEN FALSE END  END )
           71  +  );
           72  +  INSERT INTO temp.Table6 DEFAULT VALUES ;
           73  +  SELECT * FROM Table6;
           74  +} {0}
           75  +do_execsql_test fuzz4-610 {
           76  +  WITH TableX AS (SELECT DISTINCT * ORDER BY 1  , 1 COLLATE RTRIM)
           77  +      DELETE FROM Table6  WHERE Col0 || +8388608  ;
           78  +  SELECT * FROM Table6;
           79  +} {}
           80  +
           81  +
           82  +finish_test

Changes to test/fuzzcheck.c.

   443    443     if( iOfst<0 || iOfst>=pVFile->sz ){
   444    444       memset(pData, 0, iAmt);
   445    445       return SQLITE_IOERR_SHORT_READ;
   446    446     }
   447    447     if( iOfst+iAmt>pVFile->sz ){
   448    448       memset(pData, 0, iAmt);
   449    449       iAmt = (int)(pVFile->sz - iOfst);
   450         -    memcpy(pData, pVFile->a, iAmt);
          450  +    memcpy(pData, pVFile->a + iOfst, iAmt);
   451    451       return SQLITE_IOERR_SHORT_READ;
   452    452     }
   453    453     memcpy(pData, pVFile->a + iOfst, iAmt);
   454    454     return SQLITE_OK;
   455    455   }
   456    456   static int inmemWrite(
   457    457     sqlite3_file *pFile,   /* Write to this file */

Changes to test/fuzzdata7.db.

cannot compute difference between binary files

Changes to test/indexexpr2.test.

   226    226       SELECT sqlite_master.name 
   227    227         FROM sqlite_master, explain('UPDATE t2 SET c=c+1, f=NULL')
   228    228        WHERE explain.opcode LIKE 'Open%'
   229    229          AND sqlite_master.rootpage=explain.p2
   230    230        ORDER BY 1;
   231    231     } {t2 t2abc t2cd t2def}
   232    232   }
          233  +
          234  +#-------------------------------------------------------------------------
          235  +# Test that ticket [d96eba87] has been fixed.
          236  +#
          237  +do_execsql_test 5.0 {
          238  +  CREATE TABLE t5(a INTEGER, b INTEGER);
          239  +  INSERT INTO t5 VALUES(2, 4), (3, 9);
          240  +}
          241  +do_execsql_test 5.1 {
          242  +  SELECT * FROM t5 WHERE abs(a)=2 or abs(b)=9;
          243  +} {2 4 3 9}
          244  +do_execsql_test 5.2 {
          245  +  CREATE INDEX t5a ON t5( abs(a) );
          246  +  CREATE INDEX t5b ON t5( abs(b) );
          247  +}
          248  +do_execsql_test 5.4 {
          249  +  SELECT * FROM t5 WHERE abs(a)=2 or abs(b)=9;
          250  +} {2 4 3 9}
          251  +
   233    252   
   234    253   
   235    254   finish_test

Changes to test/lock_common.tcl.

    11     11   # This file contains code used by several different test scripts. The
    12     12   # code in this file allows testfixture to control another process (or
    13     13   # processes) to test locking.
    14     14   #
    15     15   
    16     16   proc do_multiclient_test {varname script} {
    17     17   
    18         -  foreach code [list {
           18  +  foreach {tn code} [list 1 {
    19     19       if {[info exists ::G(valgrind)]} { db close ; continue }
    20     20       set ::code2_chan [launch_testfixture]
    21     21       set ::code3_chan [launch_testfixture]
    22     22       proc code2 {tcl} { testfixture $::code2_chan $tcl }
    23     23       proc code3 {tcl} { testfixture $::code3_chan $tcl }
    24         -    set tn 1
    25         -  } {
           24  +  } 2 {
    26     25       proc code2 {tcl} { uplevel #0 $tcl }
    27     26       proc code3 {tcl} { uplevel #0 $tcl }
    28         -    set tn 2
    29     27     }] {
           28  +    # Do not run multi-process tests with the unix-excl VFS.
           29  +    #
           30  +    if {$tn==1 && [permutation]=="unix-excl"} continue
           31  +
    30     32       faultsim_delete_and_reopen
    31     33   
    32     34       proc code1 {tcl} { uplevel #0 $tcl }
    33     35     
    34     36       # Open connections [db2] and [db3]. Depending on which iteration this
    35     37       # is, the connections may be created in this interpreter, or in 
    36     38       # interpreters running in other OS processes. As such, the [db2] and [db3]

Changes to test/misc1.test.

   740    740     SELECT a,b,c FROM dup1;
   741    741   } {1 2 3}
   742    742   do_execsql_test misc1-27.1 {
   743    743     UPDATE dup1 SET a=7, b=8, c=9, a=10, b=11, c=12;
   744    744     SELECT a,b,c FROM dup1;
   745    745   } {10 11 12}
   746    746   
          747  +# 2018-12-20
          748  +#
          749  +# The Cursor.seekOp debugging value set incorrectly
          750  +# in OP_NotExists.
          751  +#
          752  +sqlite3 db :memory:
          753  +do_execsql_test misc1-28.0 {
          754  +  CREATE TABLE t1(x);
          755  +  CREATE UNIQUE INDEX t1x ON t1(x) WHERE x=1;
          756  +  INSERT OR ABORT INTO t1 DEFAULT VALUES;
          757  +  UPDATE OR REPLACE t1 SET x = 1;
          758  +  PRAGMA integrity_check;
          759  +  SELECT * FROM t1;
          760  +} {ok 1}
   747    761   
   748    762   finish_test

Changes to test/permutations.test.

   426    426   # Define the coverage related test suites:
   427    427   #
   428    428   #   coverage-wal
   429    429   #
   430    430   test_suite "coverage-wal" -description {
   431    431     Coverage tests for file wal.c.
   432    432   } -files {
   433         -wal2big.test wal2recover.test wal2rewrite.test
   434         -wal2simple.test wal2snapshot.test wal2.test
   435         -wal3.test wal4.test wal5.test
   436         -wal64k.test wal6.test wal7.test wal8.test wal9.test
   437         -walbak.test walbig.test walblock.test walcksum.test 
   438         -walfault.test walhook.test walmode.test walnoshm.test
   439         -waloverwrite.test walpersist.test walprotocol2.test
   440         -walprotocol.test walro2.test walrofault.test walro.test
   441         -walshared.test walslow.test wal.test
   442         -wal2savepoint.test wal2lock.test wal2recover2.test
          433  +  wal2big.test wal2recover.test wal2rewrite.test
          434  +  wal2simple.test wal2snapshot.test wal2.test
          435  +  wal3.test wal4.test wal5.test
          436  +  wal64k.test wal6.test wal7.test wal8.test wal9.test
          437  +  walbak.test walbig.test walblock.test walcksum.test 
          438  +  walfault.test walhook.test walmode.test walnoshm.test
          439  +  waloverwrite.test walpersist.test walprotocol2.test
          440  +  walprotocol.test walro2.test walrofault.test walro.test
          441  +  walshared.test walslow.test wal.test
          442  +  wal2savepoint.test wal2lock.test wal2recover2.test
          443  +  walvfs.test walfault2.test nockpt.test
          444  +  snapshot2.test snapshot3.test snapshot4.test
          445  +  snapshot_fault.test snapshot.test snapshot_up.test
          446  +  walcrash2.test walcrash3.test walcrash4.test walcrash.test
   443    447   } 
   444    448   
   445    449   test_suite "coverage-pager" -description {
   446    450     Coverage tests for file pager.c.
   447    451   } -files {
   448    452     pager1.test    pager2.test  pagerfault.test  pagerfault2.test
   449    453     walfault.test  walbak.test  journal2.test    tkt-9d68c883.test

Added test/shmlock.test.

            1  +# 2018 December 6
            2  +#
            3  +# The author disclaims copyright to this source code.  In place of
            4  +# a legal notice, here is a blessing:
            5  +#
            6  +#    May you do good and not evil.
            7  +#    May you find forgiveness for yourself and forgive others.
            8  +#    May you share freely, never taking more than you give.
            9  +#
           10  +#***********************************************************************
           11  +#
           12  +
           13  +set testdir [file dirname $argv0]
           14  +source $testdir/tester.tcl
           15  +
           16  +set testprefix shmlock
           17  +
           18  +ifcapable !wal {finish_test ; return }
           19  +
           20  +sqlite3 db2 test.db
           21  +sqlite3 db3 test.db
           22  +
           23  +do_execsql_test 1.0 {
           24  +  PRAGMA journal_mode = wal;
           25  +  CREATE TABLE t1(a, b);
           26  +  INSERT INTO t1 VALUES(1, 2);
           27  +} {wal}
           28  +do_test 1.1 { execsql { SELECT * FROM t1 } db2 } {1 2}
           29  +do_test 1.2 { execsql { SELECT * FROM t1 } db3 } {1 2}
           30  +
           31  +foreach {tn dbhandle cmd res} {
           32  +  1    db  {shared    lock   7 1}    OK
           33  +  2    db2 {exclusive lock   7 1}    BUSY
           34  +  3    db  {shared    unlock 7 1}    OK
           35  +  4    db2 {exclusive lock   7 1}    OK
           36  +  5    db  {shared    lock   7 1}    BUSY
           37  +  6    db  {exclusive lock   7 1}    BUSY
           38  +  7    db2 {exclusive unlock 7 1}    OK
           39  +
           40  +  8    db  {exclusive lock   0 8}    OK
           41  +  9    db  {exclusive unlock 0 8}    OK
           42  +  10   db2 {exclusive lock   0 8}    OK
           43  +  11   db2 {exclusive unlock 0 8}    OK
           44  +
           45  +  12   db  {shared    lock   0 1}    OK
           46  +  13   db2 {shared    lock   0 1}    OK
           47  +  14   db3 {shared    lock   0 1}    OK
           48  +  15   db3 {shared    unlock 0 1}    OK
           49  +  16   db3 {exclusive lock   0 1}    BUSY
           50  +  17   db2 {shared    unlock 0 1}    OK
           51  +  18   db3 {exclusive lock   0 1}    BUSY
           52  +  19   db  {shared    unlock 0 1}    OK
           53  +  20   db3 {exclusive lock   0 1}    OK
           54  +  21   db3 {exclusive unlock 0 1}    OK
           55  +
           56  +  22   db  {shared    lock   3 1}    OK
           57  +  23   db2 {exclusive lock   2 2}    BUSY
           58  +  24   db  {shared    lock   2 1}    OK
           59  +  25   db2 {exclusive lock   0 5}    BUSY
           60  +  26   db2 {exclusive lock   0 4}    BUSY
           61  +  27   db2 {exclusive lock   0 3}    BUSY
           62  +  28   db  {shared    unlock 3 1}    OK
           63  +  29   db2 {exclusive lock   2 2}    BUSY
           64  +  28   db  {shared    unlock 2 1}    OK
           65  +  29   db2 {exclusive lock   2 2}    OK
           66  +  29   db2 {exclusive unlock 2 2}    OK
           67  +} {
           68  +  do_test 1.3.$tn [list vfs_shmlock $dbhandle main {*}$cmd] "SQLITE_$res"
           69  +}
           70  +
           71  +db  close
           72  +db2 close
           73  +db3 close
           74  +
           75  +if {[permutation]=="unix-excl"} {
           76  +  do_test 2.0 {
           77  +    for {set i 0} {$i < 256} {incr i} { 
           78  +      sqlite3 db$i test.db 
           79  +      execsql { SELECT * FROM t1 } db$i
           80  +    }
           81  +    for {set i 0} {$i < 255} {incr i} { 
           82  +      set rc [vfs_shmlock db$i main shared lock 4 1]
           83  +      if {$rc != "SQLITE_OK"} { error $rc }
           84  +    }
           85  +
           86  +    vfs_shmlock db255 main shared lock 4 1
           87  +  } {SQLITE_BUSY}
           88  +
           89  +  do_test 2.1 { vfs_shmlock db255 main exclusive lock   4 1 } SQLITE_BUSY
           90  +  do_test 2.2 { vfs_shmlock db0   main shared    unlock 4 1 } SQLITE_OK
           91  +  do_test 2.3 { vfs_shmlock db255 main shared    lock   4 1 } SQLITE_OK
           92  +  do_test 2.4 { vfs_shmlock db255 main shared    unlock 4 1 } SQLITE_OK
           93  +  do_test 2.5 { vfs_shmlock db255 main exclusive lock   4 1 } SQLITE_BUSY
           94  +
           95  +  do_test 2.6 {
           96  +    for {set i 1} {$i < 255} {incr i} { 
           97  +      set rc [vfs_shmlock db255 main exclusive lock 4 1]
           98  +      if {$rc != "SQLITE_BUSY"} { error $rc }
           99  +      set rc [vfs_shmlock db$i main shared unlock 4 1]
          100  +      if {$rc != "SQLITE_OK"} { error $rc }
          101  +    }
          102  +
          103  +    vfs_shmlock db255 main exclusive lock 4 1
          104  +  } {SQLITE_OK}
          105  +
          106  +  vfs_shmlock db255 main exclusive unlock 4 1
          107  +
          108  +  for {set i 0} {$i < 256} {incr i} {
          109  +    db$i close
          110  +  }
          111  +}
          112  +
          113  +sqlite3 db0 test.db
          114  +sqlite3 db1 test.db
          115  +do_test 3.1 { execsql { SELECT * FROM t1 } db0 } {1 2}
          116  +do_test 3.2 { execsql { SELECT * FROM t1 } db1 } {1 2}
          117  +
          118  +set L(0) {n n n n n n n n}
          119  +set L(1) {n n n n n n n n}
          120  +proc random_lock_test {idx} {
          121  +  global L
          122  +  set iSlot [expr int(rand()*8)]
          123  +  if {[expr int(rand()*2)]} {
          124  +    # Unlock operation
          125  +    if {[lindex $L($idx) $iSlot]!="n"} {
          126  +      vfs_shmlock db$idx main [lindex $L($idx) $iSlot] unlock $iSlot 1
          127  +      lset L($idx) $iSlot n
          128  +    }
          129  +  } else {
          130  +    # Lock operation
          131  +    if {[lindex $L($idx) $iSlot]=="n"} {
          132  +      set locktype [lindex {e s} [expr int(rand()*2)]]
          133  +      set n 1
          134  +      if {$locktype=="e"} {
          135  +        for {set l $iSlot} {$l<8 && [lindex $L($idx) $l]=="n"} {incr l} {}
          136  +        set n [expr int(rand()*($l-$iSlot))+1]
          137  +        # puts "iSlot=$iSlot l=$l L=$L($idx)"
          138  +        # puts "$iSlot $n"
          139  +      }
          140  +      set res [vfs_shmlock db$idx main $locktype lock $iSlot $n]
          141  +
          142  +      set bBusy 0
          143  +      for {set i $iSlot} {$i<($iSlot+$n)} {incr i} {
          144  +        set other [lindex $L([expr ($idx+1)%2]) $i]
          145  +        if {($other!="n" && $locktype=="e")||($other=="e" && $locktype=="s")} {
          146  +          if {$res != "SQLITE_BUSY"} { error "BUSY not detected" }
          147  +          set bBusy 1
          148  +          break
          149  +        } 
          150  +      }
          151  +
          152  +      if {$bBusy==0} {
          153  +        if {$res != "SQLITE_OK"} { error "BUSY false-positive" }
          154  +        for {set i $iSlot} {$i<($iSlot+$n)} {incr i} {
          155  +          lset L($idx) $i $locktype
          156  +        }
          157  +      }
          158  +    }
          159  +  }
          160  +}
          161  +
          162  +set nStep 100000
          163  +for {set i 0} {$i < $nStep} {incr i} {
          164  +  random_lock_test 0
          165  +  random_lock_test 1
          166  +}
          167  +
          168  +db0 close
          169  +db1 close
          170  +
          171  +finish_test
          172  +
          173  +

Changes to test/snapshot_fault.test.

   217    217     db eval COMMIT
   218    218   } -body {
   219    219     sqlite3_snapshot_recover db main
   220    220   } -test {
   221    221     faultsim_test_result {0 {}} {1 SQLITE_IOERR}
   222    222   }
   223    223   
          224  +#-------------------------------------------------------------------------
          225  +# Test the handling of faults that occur within sqlite3_snapshot_get().
          226  +#
          227  +reset_db
          228  +do_execsql_test 5.0 {
          229  +  PRAGMA page_size = 512;
          230  +  PRAGMA journal_mode = wal;
          231  +  PRAGMA wal_autocheckpoint = 0;
          232  +  CREATE TABLE t1(zzz);
          233  +  INSERT INTO t1 VALUES(randomblob( 5000 ));
          234  +  PRAGMA user_version = 211;
          235  +} {wal 0}
          236  +faultsim_save_and_close
          237  +
          238  +do_faultsim_test 5 -prep {
          239  +  faultsim_restore_and_reopen
          240  +  execsql { SELECT count(*) FROM sqlite_master }
          241  +  execsql BEGIN
          242  +} -body {
          243  +  sqlite3_snapshot_get_blob db main
          244  +  set {} {}
          245  +} -test {
          246  +  execsql END
          247  +  faultsim_test_result {0 {}} {1 SQLITE_IOERR} {1 SQLITE_NOMEM}
          248  +}
   224    249   
   225    250   
   226    251   finish_test

Changes to test/triggerC.test.

  1038   1038   
  1039   1039     INSERT INTO x1 VALUES('go!');
  1040   1040   }
  1041   1041   
  1042   1042   do_execsql_test 15.2.2 { SELECT * FROM x2;       } {1 2 3 4}
  1043   1043   do_execsql_test 15.2.3 { SELECT * FROM """x2"""; } {3 11 x y}
  1044   1044   
         1045  +#-------------------------------------------------------------------------
         1046  +# At one point queries such as the following were causing segfaults.
         1047  +#
         1048  +do_catchsql_test 16.1 {
         1049  +  SELECT raise(ABORT, 'msg') FROM sqlite_master 
         1050  +  UNION SELECT 1 
         1051  +  ORDER BY raise(IGNORE);
         1052  +} {1 {1st ORDER BY term does not match any column in the result set}}
         1053  +
         1054  +do_catchsql_test 16.2 {
         1055  +  SELECT count(*) FROM sqlite_master 
         1056  +  GROUP BY raise(IGNORE) 
         1057  +  HAVING raise(ABORT, 'msg');
         1058  +} {1 {RAISE() may only be used within a trigger-program}}
         1059  +
  1045   1060   finish_test
         1061  +

Changes to test/triggerF.test.

    16     16   ifcapable {!trigger} {
    17     17     finish_test
    18     18     return
    19     19   }
    20     20   
    21     21   
    22     22   foreach {tn sql log} {
    23         -  1 { } { }
           23  +  1 {} {}
    24     24   
    25     25     2 { 
    26     26       CREATE TRIGGER trd AFTER DELETE ON t1 BEGIN
    27     27         INSERT INTO log VALUES(old.a || old.b || (SELECT count(*) FROM t1));
    28     28       END;
    29     29     } {1one2 2two1 3three1}
    30     30   

Changes to test/unionvtab.test.

   369    369   do_execsql_test 4.3.3 {
   370    370     SELECT * FROM sl WHERE rowid<=-9223372036854775808
   371    371   } {
   372    372     -9223372036854775808 one
   373    373   }
   374    374   do_execsql_test 4.3.4 {
   375    375     SELECT * FROM sl WHERE rowid<-9223372036854775808
   376         -} { }
          376  +} {}
   377    377   
   378    378   do_execsql_test 4.4.1 {
   379    379     SELECT * FROM sl WHERE rowid<9223372036854775807
   380    380   } {
   381    381     -9223372036854775808 one -9223372036854775807 two -9223372036854775806 three
   382    382      9223372036854775805 four 9223372036854775806 five
   383    383   }
................................................................................
   390    390   do_execsql_test 4.4.3 {
   391    391     SELECT * FROM sl WHERE rowid>=9223372036854775807
   392    392   } {
   393    393     9223372036854775807 six
   394    394   }
   395    395   do_execsql_test 4.4.4 {
   396    396     SELECT * FROM sl WHERE rowid>9223372036854775807
   397         -} { }
          397  +} {}
   398    398   
   399    399   #-------------------------------------------------------------------------
   400    400   # More than 8 source tables.
   401    401   #
   402    402   do_execsql_test 5.0 {
   403    403     CREATE TABLE c0(one, two INTEGER PRIMARY KEY);
   404    404     CREATE TABLE c1(one, two INTEGER PRIMARY KEY);

Changes to test/wal.test.

  1293   1293   #
  1294   1294   #   3. Using connection 1, checkpoint the database. Make sure all
  1295   1295   #      the data is present and the database is not corrupt.
  1296   1296   #
  1297   1297   # At one point, SQLite was failing to grow the mapping of the wal-index
  1298   1298   # file in step 3 and the checkpoint was corrupting the database file.
  1299   1299   #
  1300         -do_test wal-20.1 {
  1301         -  catch {db close}
  1302         -  forcedelete test.db test.db-wal test.db-journal
  1303         -  sqlite3 db test.db
  1304         -  execsql {
  1305         -    PRAGMA journal_mode = WAL;
  1306         -    CREATE TABLE t1(x);
  1307         -    INSERT INTO t1 VALUES(randomblob(900));
  1308         -    SELECT count(*) FROM t1;
  1309         -  }
  1310         -} {wal 1}
  1311         -do_test wal-20.2 {
  1312         -  set ::buddy [launch_testfixture]
  1313         -  testfixture $::buddy {
         1300  +if {[permutation]!="unix-excl"} {
         1301  +  do_test wal-20.1 {
         1302  +    catch {db close}
         1303  +    forcedelete test.db test.db-wal test.db-journal
         1304  +    sqlite3 db test.db
         1305  +    execsql {
         1306  +      PRAGMA journal_mode = WAL;
         1307  +      CREATE TABLE t1(x);
         1308  +      INSERT INTO t1 VALUES(randomblob(900));
         1309  +      SELECT count(*) FROM t1;
         1310  +    }
         1311  +  } {wal 1}
         1312  +  do_test wal-20.2 {
         1313  +    set ::buddy [launch_testfixture]
         1314  +    testfixture $::buddy {
         1315  +      sqlite3 db test.db
         1316  +      db transaction { db eval {
         1317  +        PRAGMA wal_autocheckpoint = 0;
         1318  +        INSERT INTO t1 SELECT randomblob(900) FROM t1;       /* 2 */
         1319  +        INSERT INTO t1 SELECT randomblob(900) FROM t1;       /* 4 */
         1320  +        INSERT INTO t1 SELECT randomblob(900) FROM t1;       /* 8 */
         1321  +        INSERT INTO t1 SELECT randomblob(900) FROM t1;       /* 16 */
         1322  +        INSERT INTO t1 SELECT randomblob(900) FROM t1;       /* 32 */
         1323  +        INSERT INTO t1 SELECT randomblob(900) FROM t1;       /* 64 */
         1324  +        INSERT INTO t1 SELECT randomblob(900) FROM t1;       /* 128 */
         1325  +        INSERT INTO t1 SELECT randomblob(900) FROM t1;       /* 256 */
         1326  +        INSERT INTO t1 SELECT randomblob(900) FROM t1;       /* 512 */
         1327  +        INSERT INTO t1 SELECT randomblob(900) FROM t1;       /* 1024 */
         1328  +        INSERT INTO t1 SELECT randomblob(900) FROM t1;       /* 2048 */
         1329  +        INSERT INTO t1 SELECT randomblob(900) FROM t1;       /* 4096 */
         1330  +        INSERT INTO t1 SELECT randomblob(900) FROM t1;       /* 8192 */
         1331  +        INSERT INTO t1 SELECT randomblob(900) FROM t1;       /* 16384 */
         1332  +      } }
         1333  +    }
         1334  +  } {0}
         1335  +  do_test wal-20.3 {
         1336  +    close $::buddy
         1337  +    execsql { PRAGMA wal_checkpoint }
         1338  +    execsql { SELECT count(*) FROM t1 }
         1339  +  } {16384}
         1340  +  do_test wal-20.4 {
         1341  +    db close
  1314   1342       sqlite3 db test.db
  1315         -    db transaction { db eval {
  1316         -      PRAGMA wal_autocheckpoint = 0;
  1317         -      INSERT INTO t1 SELECT randomblob(900) FROM t1;       /* 2 */
  1318         -      INSERT INTO t1 SELECT randomblob(900) FROM t1;       /* 4 */
  1319         -      INSERT INTO t1 SELECT randomblob(900) FROM t1;       /* 8 */
  1320         -      INSERT INTO t1 SELECT randomblob(900) FROM t1;       /* 16 */
  1321         -      INSERT INTO t1 SELECT randomblob(900) FROM t1;       /* 32 */
  1322         -      INSERT INTO t1 SELECT randomblob(900) FROM t1;       /* 64 */
  1323         -      INSERT INTO t1 SELECT randomblob(900) FROM t1;       /* 128 */
  1324         -      INSERT INTO t1 SELECT randomblob(900) FROM t1;       /* 256 */
  1325         -      INSERT INTO t1 SELECT randomblob(900) FROM t1;       /* 512 */
  1326         -      INSERT INTO t1 SELECT randomblob(900) FROM t1;       /* 1024 */
  1327         -      INSERT INTO t1 SELECT randomblob(900) FROM t1;       /* 2048 */
  1328         -      INSERT INTO t1 SELECT randomblob(900) FROM t1;       /* 4096 */
  1329         -      INSERT INTO t1 SELECT randomblob(900) FROM t1;       /* 8192 */
  1330         -      INSERT INTO t1 SELECT randomblob(900) FROM t1;       /* 16384 */
  1331         -    } }
  1332         -  }
  1333         -} {0}
  1334         -do_test wal-20.3 {
  1335         -  close $::buddy
  1336         -  execsql { PRAGMA wal_checkpoint }
  1337         -  execsql { SELECT count(*) FROM t1 }
  1338         -} {16384}
  1339         -do_test wal-20.4 {
  1340         -  db close
  1341         -  sqlite3 db test.db
  1342         -  execsql { SELECT count(*) FROM t1 }
  1343         -} {16384}
  1344         -integrity_check wal-20.5
         1343  +    execsql { SELECT count(*) FROM t1 }
         1344  +  } {16384}
         1345  +  integrity_check wal-20.5
         1346  +}
  1345   1347   
  1346   1348   catch { db2 close }
  1347   1349   catch { db close }
  1348   1350   
  1349   1351   do_test wal-21.1 {
  1350   1352     faultsim_delete_and_reopen
  1351   1353     execsql { 

Added test/walfault2.test.

            1  +# 2010 May 03
            2  +#
            3  +# The author disclaims copyright to this source code.  In place of
            4  +# a legal notice, here is a blessing:
            5  +#
            6  +#    May you do good and not evil.
            7  +#    May you find forgiveness for yourself and forgive others.
            8  +#    May you share freely, never taking more than you give.
            9  +#
           10  +#***********************************************************************
           11  +# This file implements regression tests for SQLite library.  The
           12  +# focus of this file is testing the operation of the library in
           13  +# "PRAGMA journal_mode=WAL" mode.
           14  +#
           15  +
           16  +set testdir [file dirname $argv0]
           17  +source $testdir/tester.tcl
           18  +source $testdir/malloc_common.tcl
           19  +source $testdir/lock_common.tcl
           20  +
           21  +ifcapable !wal {finish_test ; return }
           22  +set testprefix walfault2
           23  +
           24  +#-------------------------------------------------------------------------
           25  +# Inject faults while truncating the wal file.
           26  +#
           27  +do_execsql_test 1.0 {
           28  +  PRAGMA auto_vacuum = 0;
           29  +  CREATE TABLE t1(a, b);
           30  +  PRAGMA journal_mode = wal;
           31  +  WITH s(i) AS (
           32  +    SELECT 1 UNION ALL SELECT i+1 FROM s LIMIT 30
           33  +  )
           34  +  INSERT INTO t1 SELECT randomblob(400), randomblob(400) FROM s;
           35  +} {wal}
           36  +faultsim_save_and_close
           37  +
           38  +do_faultsim_test 1 -prep {
           39  +  faultsim_restore
           40  +  sqlite3 db file:test.db?psow=0 -uri 1
           41  +  file_control_powersafe_overwrite db 0
           42  +  execsql {
           43  +    PRAGMA wal_checkpoint;
           44  +    PRAGMA journal_size_limit = 10000;
           45  +    PRAGMA synchronous = full;
           46  +  }
           47  +} -body {
           48  +  execsql { INSERT INTO t1 VALUES(1,1) }
           49  +} -test {
           50  +  faultsim_test_result {0 {}}
           51  +}
           52  +
           53  +#-------------------------------------------------------------------------
           54  +# Inject faults while rewriting checksums.
           55  +#
           56  +reset_db
           57  +do_execsql_test 2.0 {
           58  +  PRAGMA auto_vacuum = 0;
           59  +  CREATE TABLE t1(a, b);
           60  +  PRAGMA journal_mode = wal;
           61  +  WITH s(i) AS (
           62  +    SELECT 1 UNION ALL SELECT i+1 FROM s LIMIT 30
           63  +  )
           64  +  INSERT INTO t1 SELECT randomblob(400), randomblob(400) FROM s;
           65  +} {wal}
           66  +faultsim_save_and_close
           67  +
           68  +do_faultsim_test 2 -prep {
           69  +  faultsim_restore_and_reopen
           70  +  execsql {
           71  +    PRAGMA cache_size = 2;
           72  +    BEGIN;
           73  +    UPDATE t1 SET a=randomblob(400);
           74  +    UPDATE t1 SET b=randomblob(400);
           75  +    UPDATE t1 SET a=randomblob(400);
           76  +    UPDATE t1 SET b=randomblob(400);
           77  +    UPDATE t1 SET a=randomblob(400);
           78  +    UPDATE t1 SET b=randomblob(400);
           79  +    UPDATE t1 SET a=randomblob(400);
           80  +    UPDATE t1 SET b=randomblob(400);
           81  +  }
           82  +} -body {
           83  +  execsql COMMIT
           84  +} -test {
           85  +  faultsim_test_result {0 {}}
           86  +}
           87  +
           88  +
           89  +
           90  +finish_test

Added test/walvfs.test.

            1  +# 2018 December 23
            2  +#
            3  +# The author disclaims copyright to this source code.  In place of
            4  +# a legal notice, here is a blessing:
            5  +#
            6  +#    May you do good and not evil.
            7  +#    May you find forgiveness for yourself and forgive others.
            8  +#    May you share freely, never taking more than you give.
            9  +#
           10  +#***********************************************************************
           11  +# This file implements regression tests for SQLite library.  The
           12  +# focus of this file is testing the operation of the library in
           13  +# "PRAGMA journal_mode=WAL" mode.
           14  +#
           15  +
           16  +set testdir [file dirname $argv0]
           17  +source $testdir/tester.tcl
           18  +source $testdir/lock_common.tcl
           19  +source $testdir/malloc_common.tcl
           20  +source $testdir/wal_common.tcl
           21  +set testprefix walvfs
           22  +
           23  +ifcapable !wal {finish_test ; return }
           24  +
           25  +db close
           26  +testvfs tvfs 
           27  +tvfs script xSync
           28  +tvfs filter xSync
           29  +set ::sync_count 0
           30  +proc xSync {method file args} {
           31  +  if {[file tail $file]=="test.db-wal"} {
           32  +    incr ::sync_count
           33  +  }
           34  +}
           35  +
           36  +
           37  +#-------------------------------------------------------------------------
           38  +# Test that if IOCAP_SEQUENTIAL is set, the wal-header is not synced to
           39  +# disk immediately after it is written.
           40  +#
           41  +sqlite3 db test.db -vfs tvfs
           42  +do_execsql_test 1.0 {
           43  +  PRAGMA auto_vacuum = 0;
           44  +  PRAGMA journal_mode = wal;
           45  +  PRAGMA synchronous = normal;
           46  +  CREATE TABLE t1(a, b, c);
           47  +  INSERT INTO t1 VALUES(1, 2, 3);
           48  +  INSERT INTO t1 VALUES(4, 5, 6);
           49  +  INSERT INTO t1 VALUES(7, 8, 9);
           50  +  PRAGMA wal_checkpoint;
           51  +} {wal 0 5 5}
           52  +
           53  +set ::sync_count 0
           54  +do_test 1.1 {
           55  +  execsql { INSERT INTO t1 VALUES(10, 11, 12) }
           56  +  set ::sync_count
           57  +} 1
           58  +
           59  +db close
           60  +tvfs devchar sequential
           61  +sqlite3 db test.db -vfs tvfs
           62  +do_execsql_test 1.2 {
           63  +  PRAGMA synchronous = normal;
           64  +  INSERT INTO t1 VALUES(13, 14, 15);
           65  +  INSERT INTO t1 VALUES(16, 17, 18);
           66  +  PRAGMA wal_checkpoint;
           67  +} {0 4 4}
           68  +
           69  +set ::sync_count 0
           70  +do_test 1.3 {
           71  +  execsql { INSERT INTO t1 VALUES(10, 11, 12) }
           72  +  set ::sync_count
           73  +} 0
           74  +
           75  +#-------------------------------------------------------------------------
           76  +# Test that "PRAGMA journal_size_limit" works in wal mode.
           77  +#
           78  +reset_db
           79  +do_execsql_test 2.0 {
           80  +  PRAGMA journal_size_limit = 10000;
           81  +  CREATE TABLE t1(x);
           82  +  PRAGMA journal_mode = wal;
           83  +  WITH s(i) AS (
           84  +    SELECT 1 UNION ALL SELECT i+1 FROM s LIMIT 20
           85  +  )
           86  +  INSERT INTO t1 SELECT randomblob(750) FROM s;
           87  +} {10000 wal}
           88  +do_test 2.1 {
           89  +  expr [file size test.db-wal]>12000
           90  +} {1}
           91  +do_test 2.2 {
           92  +  execsql {
           93  +    PRAGMA wal_checkpoint;
           94  +    INSERT INTO t1 VALUES(randomblob(750));
           95  +  }
           96  +  file size test.db-wal
           97  +} {10000}
           98  +do_test 2.3 {
           99  +  execsql {
          100  +    PRAGMA journal_size_limit = 8000;
          101  +    PRAGMA wal_checkpoint;
          102  +    INSERT INTO t1 VALUES(randomblob(750));
          103  +  }
          104  +  file size test.db-wal
          105  +} {8000}
          106  +
          107  +#-------------------------------------------------------------------------
          108  +# Test that a checkpoint may be interrupted using sqlite3_interrupt().
          109  +# And that the error code is SQLITE_NOMEM, not SQLITE_INTERRUPT, if
          110  +# an OOM error occurs just before the sqlite3_interrupt() call.
          111  +#
          112  +reset_db
          113  +db close
          114  +sqlite3 db test.db -vfs tvfs
          115  +tvfs filter {}
          116  +
          117  +do_execsql_test 3.0 {
          118  +  CREATE TABLE t1(x);
          119  +  PRAGMA journal_mode = wal;
          120  +  WITH s(i) AS (
          121  +    SELECT 1 UNION ALL SELECT i+1 FROM s LIMIT 20
          122  +  )
          123  +  INSERT INTO t1 SELECT randomblob(750) FROM s;
          124  +} {wal}
          125  +
          126  +tvfs filter xWrite
          127  +tvfs script xWrite
          128  +set ::cnt 2
          129  +proc xWrite {method file args} {
          130  +  if {[file tail $file]=="test.db"} {
          131  +    incr ::cnt -1
          132  +    if {$::cnt==0} {
          133  +      sqlite3_interrupt db
          134  +    }
          135  +  }
          136  +  return SQLITE_OK
          137  +}
          138  +
          139  +do_catchsql_test 3.1 {
          140  +  PRAGMA wal_checkpoint
          141  +} {1 interrupted}
          142  +
          143  +set ::cnt 2
          144  +proc xWrite {method file args} {
          145  +  if {[file tail $file]=="test.db"} {
          146  +    incr ::cnt -1
          147  +    if {$::cnt==0} {
          148  +      sqlite3_memdebug_fail 5 -repeat 0
          149  +      catchsql { SELECT 'a big long string!' }
          150  +      sqlite3_interrupt db
          151  +    }
          152  +  }
          153  +  return SQLITE_OK
          154  +}
          155  +
          156  +do_catchsql_test 3.2 {
          157  +  PRAGMA wal_checkpoint
          158  +} {1 {out of memory}}
          159  +
          160  +#-------------------------------------------------------------------------
          161  +#
          162  +reset_db
          163  +db close
          164  +do_test 4.0 {
          165  +  sqlite3 db test.db -vfs tvfs
          166  +  execsql {
          167  +    CREATE TABLE t1(x);
          168  +    PRAGMA journal_mode = wal;
          169  +    WITH s(i) AS (
          170  +        SELECT 1 UNION ALL SELECT i+1 FROM s LIMIT 20
          171  +    )
          172  +    INSERT INTO t1 SELECT randomblob(750) FROM s;
          173  +  } db
          174  +} {wal}
          175  +db close
          176  +
          177  +tvfs filter xShmMap
          178  +tvfs script xShmMap
          179  +proc xShmMap {method file args} { 
          180  +  return SQLITE_READONLY 
          181  +}
          182  +sqlite3 db test.db -vfs tvfs
          183  +do_catchsql_test 4.1 {
          184  +  SELECT count(*) FROM t1
          185  +} {1 {attempt to write a readonly database}}
          186  +
          187  +set ::cnt 5
          188  +tvfs filter {xShmMap xShmLock}
          189  +proc xShmMap {method file name args} { 
          190  +  switch -- $method {
          191  +    xShmMap {  return SQLITE_READONLY }
          192  +    xShmLock {
          193  +      if {$args == "{0 1 lock shared}"} {
          194  +        incr ::cnt -1
          195  +        if {$::cnt>0} { return SQLITE_BUSY }
          196  +      }
          197  +    }
          198  +  }
          199  +  return SQLITE_OK
          200  +}
          201  +do_catchsql_test 4.2 {
          202  +  SELECT count(*) FROM t1
          203  +} {1 {attempt to write a readonly database}}
          204  +
          205  +#-------------------------------------------------------------------------
          206  +#
          207  +reset_db
          208  +db close 
          209  +sqlite3 db test.db -vfs tvfs
          210  +tvfs filter {}
          211  +do_execsql_test 5.0 {
          212  +  PRAGMA auto_vacuum = 0;
          213  +  PRAGMA page_size = 1024;
          214  +  CREATE TABLE t1(x);
          215  +  PRAGMA journal_mode = wal;
          216  +  WITH s(i) AS (
          217  +      SELECT 1 UNION ALL SELECT i+1 FROM s LIMIT 20
          218  +  )
          219  +  INSERT INTO t1 SELECT randomblob(750) FROM s;
          220  +} {wal}
          221  +
          222  +do_execsql_test 5.1 {
          223  +  SELECT count(*) FROM t1
          224  +} {20}
          225  +
          226  +do_test 5.2 {
          227  +  vfs_set_readmark db main 1 100
          228  +  vfs_set_readmark db main 2 100
          229  +  vfs_set_readmark db main 3 100
          230  +  vfs_set_readmark db main 4 100
          231  +} {100}
          232  +
          233  +do_execsql_test 5.3 {
          234  +  SELECT count(*) FROM t1
          235  +} {20}
          236  +
          237  +do_test 5.3 {
          238  +  list [vfs_set_readmark db main 1] \
          239  +       [vfs_set_readmark db main 2] \
          240  +       [vfs_set_readmark db main 3] \
          241  +       [vfs_set_readmark db main 4] 
          242  +} {24 100 100 100}
          243  +
          244  +tvfs script xShmLock
          245  +tvfs filter xShmLock
          246  +set ::cnt 20
          247  +proc xShmLock {args} {
          248  +  incr ::cnt -1
          249  +  if {$::cnt>0} { return SQLITE_BUSY }
          250  +  return SQLITE_OK
          251  +}
          252  +
          253  +do_test 5.4 {
          254  +  vfs_set_readmark db main 1 100
          255  +  execsql { SELECT count(*) FROM t1 }
          256  +} {20}
          257  +
          258  +vfs_set_readmark db main 1 100
          259  +vfs_set_readmark db main 2 100
          260  +vfs_set_readmark db main 3 100
          261  +vfs_set_readmark db main 4 100
          262  +
          263  +tvfs script xShmMapLock
          264  +tvfs filter {xShmLock xShmMap}
          265  +proc xShmMapLock {method args} {
          266  +  if {$method=="xShmMap"} {
          267  +    return "SQLITE_READONLY"
          268  +  }
          269  +  return SQLITE_BUSY
          270  +}
          271  +
          272  +sqlite3 db2 test.db -vfs tvfs
          273  +breakpoint
          274  +do_test 5.5 {
          275  +  list [catch { execsql { SELECT count(*) FROM t1 } db2 } msg] $msg
          276  +} {1 {attempt to write a readonly database}}
          277  +
          278  +tvfs filter {}
          279  +vfs_set_readmark db main 1 1
          280  +
          281  +do_test 5.6 {
          282  +  list [catch { execsql { SELECT count(*) FROM t1 } db2 } msg] $msg
          283  +} {0 20}
          284  +db2 close
          285  +db close
          286  +
          287  +#-------------------------------------------------------------------------
          288  +# Cause an SQLITE_PROTOCOL while attempting to restart the wal file.
          289  +#
          290  +reset_db
          291  +tvfs filter {}
          292  +db close
          293  +sqlite3 db test.db -vfs tvfs
          294  +do_execsql_test 6.0 {
          295  +  PRAGMA auto_vacuum = 0;
          296  +  PRAGMA page_size = 1024;
          297  +  CREATE TABLE t1(x);
          298  +  PRAGMA journal_mode = wal;
          299  +  WITH s(i) AS (
          300  +      SELECT 1 UNION ALL SELECT i+1 FROM s LIMIT 20
          301  +  )
          302  +  INSERT INTO t1 SELECT randomblob(750) FROM s;
          303  +} {wal}
          304  +
          305  +do_test 6.1 {
          306  +  execsql { PRAGMA wal_checkpoint } 
          307  +  set {} {}
          308  +} {}
          309  +
          310  +tvfs filter xShmLock
          311  +tvfs script xShmLock
          312  +set ::flag 0
          313  +proc xShmLock {method file handle spec} {
          314  +  if {$::flag && [lrange $spec 2 end]=="lock shared"} {
          315  +    return SQLITE_BUSY
          316  +  }
          317  +  if {$spec=="3 1 unlock shared"} {
          318  +    set ::flag 1
          319  +  }
          320  +  return SQLITE_OK
          321  +}
          322  +
          323  +puts "# WARNING: This next test takes around 12 seconds"
          324  +do_catchsql_test 6.2 {
          325  +  INSERT INTO t1 VALUES(1);
          326  +} {1 {locking protocol}}
          327  +
          328  +#-------------------------------------------------------------------------
          329  +# Check that a checkpoint fails if it cannot get the CHECKPOINTER lock
          330  +#
          331  +reset_db
          332  +tvfs filter {}
          333  +db close
          334  +sqlite3 db test.db -vfs tvfs
          335  +do_execsql_test 7.0 {
          336  +  PRAGMA auto_vacuum = 0;
          337  +  PRAGMA page_size = 1024;
          338  +  CREATE TABLE t1(x);
          339  +  PRAGMA journal_mode = wal;
          340  +  WITH s(i) AS (
          341  +      SELECT 1 UNION ALL SELECT i+1 FROM s LIMIT 20
          342  +  )
          343  +  INSERT INTO t1 SELECT randomblob(750) FROM s;
          344  +} {wal}
          345  +
          346  +tvfs script xShmLock
          347  +tvfs filter xShmLock
          348  +proc xShmLock {method file handle spec} {
          349  +  if {$spec=="1 1 lock exclusive"} {
          350  +    return SQLITE_BUSY
          351  +  }
          352  +  return SQLITE_OK
          353  +}
          354  +
          355  +do_execsql_test 7.1 {
          356  +  PRAGMA wal_checkpoint
          357  +} {1 -1 -1}
          358  +
          359  +#-------------------------------------------------------------------------
          360  +# Check that the page cache is correctly flushed if a checkpointer using
          361  +# a version 2 VFS makes a checkpoint with an out-of-date cache.
          362  +#
          363  +reset_db
          364  +testvfs tvfs2 -iversion 2
          365  +db close
          366  +sqlite3 db test.db -vfs tvfs2
          367  +do_execsql_test 8.0 {
          368  +  PRAGMA auto_vacuum = 0;
          369  +  PRAGMA page_size = 1024;
          370  +  CREATE TABLE t1(x);
          371  +  PRAGMA journal_mode = wal;
          372  +  WITH s(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM s LIMIT 20 )
          373  +  INSERT INTO t1 SELECT randomblob(75) FROM s;
          374  +} {wal}
          375  +
          376  +do_execsql_test 8.1 { SELECT count(*) FROM t1 } {20}
          377  +
          378  +do_test 8.2 {
          379  +  sqlite3 db2 test.db -vfs tvfs2
          380  +  execsql {
          381  +    INSERT INTO t1 VALUES(randomblob(75));
          382  +  } db2
          383  +  db2 close
          384  +} {}
          385  +
          386  +do_execsql_test 8.3 { 
          387  +  PRAGMA wal_checkpoint;
          388  +  SELECT count(*) FROM t1 
          389  +} {0 5 5 21}
          390  +tvfs2 delete
          391  +
          392  +#-------------------------------------------------------------------------
          393  +reset_db
          394  +db close
          395  +sqlite3 db test.db -vfs tvfs
          396  +do_execsql_test 9.0 {
          397  +  PRAGMA auto_vacuum = 0;
          398  +  PRAGMA page_size = 1024;
          399  +  CREATE TABLE t1(x);
          400  +  PRAGMA journal_mode = wal;
          401  +  WITH s(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM s LIMIT 20 )
          402  +  INSERT INTO t1 SELECT randomblob(75) FROM s;
          403  +} {wal}
          404  +
          405  +sqlite3 db2 test.db -vfs tvfs
          406  +tvfs filter {xShmMap xShmLock}
          407  +tvfs script xShmMap
          408  +proc xShmMap {method file handle args} {
          409  +  switch -- $method {
          410  +    xShmMap {
          411  +      return "SQLITE_READONLY_CANTINIT"
          412  +    }
          413  +    xShmLock {
          414  +      if {$args=="{3 1 lock shared}"} {
          415  +        return "SQLITE_IOERR"
          416  +      }
          417  +    }
          418  +  }
          419  +}
          420  +
          421  +do_test 9.1 {
          422  +  catchsql { SELECT count(*) FROM t1 } db2
          423  +} {1 {disk I/O error}}
          424  +
          425  +db close
          426  +db2 close
          427  +tvfs delete
          428  +finish_test
          429  +

Changes to test/window1.test.

   587    587     1 1   2 2 
   588    588   }
   589    589   
   590    590   do_execsql_test 13.5 {
   591    591     SELECT a, rank() OVER(ORDER BY b) FROM t1
   592    592       INTERSECT 
   593    593     SELECT a, rank() OVER(ORDER BY b DESC) FROM t1;
   594         -} {
   595         -}
          594  +} {}
   596    595   
   597    596   # 2018-12-06
   598    597   # https://www.sqlite.org/src/info/f09fcd17810f65f7
   599    598   # Assertion fault when window functions are used.
   600    599   #
   601    600   # Root cause is the query flattener invoking sqlite3ExprDup() on
   602    601   # expressions that contain subqueries with window functions.  The

Added tool/dbtotxt.c.

            1  +/*
            2  +** Copyright 2008 D. Richard Hipp and Hipp, Wyrick & Company, Inc.
            3  +** All Rights Reserved
            4  +**
            5  +******************************************************************************
            6  +**
            7  +** This file implements a stand-alone utility program that converts
            8  +** a binary file (usually an SQLite database) into a text format that
            9  +** is compact and friendly to human-readers.
           10  +**
           11  +** Usage:
           12  +**
           13  +**         dbtotxt [--pagesize N] FILENAME
           14  +**
           15  +** The translation of the database appears on standard output.  If the
           16  +** --pagesize command-line option is omitted, then the page size is taken
           17  +** from the database header.
           18  +**
           19  +** Compactness is achieved by suppressing lines of all zero bytes.  This
           20  +** works well at compressing test databases that are mostly empty.  But
           21  +** the output will probably be lengthy for a real database containing lots
           22  +** of real content.  For maximum compactness, it is suggested that test
           23  +** databases be constructed with "zeroblob()" rather than "randomblob()"
           24  +** used for filler content and with "PRAGMA secure_delete=ON" selected to
           25  +** zero-out deleted content.
           26  +*/
           27  +#include <stdio.h>
           28  +#include <string.h>
           29  +#include <stdlib.h>
           30  +#include <ctype.h>
           31  + 
           32  +/* Return true if the line is all zeros */
           33  +static int allZero(unsigned char *aLine){
           34  +  int i;
           35  +  for(i=0; i<16 && aLine[i]==0; i++){}
           36  +  return i==16;
           37  +}
           38  +
           39  +int main(int argc, char **argv){
           40  +  int pgsz = 0;               /* page size */
           41  +  long szFile;                /* Size of the input file in bytes */
           42  +  FILE *in;                   /* Input file */
           43  +  int i, j;                   /* Loop counters */
           44  +  int nErr = 0;               /* Number of errors */
           45  +  const char *zInputFile = 0; /* Name of the input file */
           46  +  const char *zBaseName = 0;  /* Base name of the file */
           47  +  int lastPage = 0;           /* Last page number shown */
           48  +  int iPage;                  /* Current page number */
           49  +  unsigned char aLine[16];    /* A single line of the file */
           50  +  unsigned char aHdr[100];    /* File header */
           51  +  unsigned char bShow[256];      /* Characters ok to display */
           52  +  memset(bShow, '.', sizeof(bShow));
           53  +  for(i=' '; i<='~'; i++){
           54  +    if( i!='{' && i!='}' && i!='"' && i!='\\' ) bShow[i] = i;
           55  +  }
           56  +  for(i=1; i<argc; i++){
           57  +    if( argv[i][0]=='-' ){
           58  +      const char *z = argv[i];
           59  +      z++;
           60  +      if( z[0]=='-' ) z++;
           61  +      if( strcmp(z,"pagesize")==0 ){
           62  +        i++;
           63  +        pgsz = atoi(argv[i]);
           64  +        if( pgsz<512 || pgsz>65536 || (pgsz&(pgsz-1))!=0 ){
           65  +          fprintf(stderr, "Page size must be a power of two between"
           66  +                          " 512 and 65536.\n");
           67  +          nErr++;
           68  +        }
           69  +        continue;
           70  +      }
           71  +      fprintf(stderr, "Unknown option: %s\n", argv[i]);
           72  +      nErr++;
           73  +    }else if( zInputFile ){
           74  +      fprintf(stderr, "Already using a different input file: [%s]\n", argv[i]);
           75  +      nErr++;
           76  +    }else{
           77  +      zInputFile = argv[i];
           78  +    }
           79  +  }
           80  +  if( zInputFile==0 ){
           81  +    fprintf(stderr, "No input file specified.\n");
           82  +    nErr++;
           83  +  }
           84  +  if( nErr ){
           85  +    fprintf(stderr, "Usage: %s [--pagesize N] FILENAME\n", argv[0]);
           86  +    exit(1);
           87  +  }
           88  +  in = fopen(zInputFile, "rb");
           89  +  if( in==0 ){
           90  +    fprintf(stderr, "Cannot open input file [%s]\n", zInputFile);
           91  +    exit(1);
           92  +  }
           93  +  fseek(in, 0, SEEK_END);
           94  +  szFile = ftell(in);
           95  +  rewind(in);
           96  +  if( szFile<512 ){
           97  +    fprintf(stderr, "File too short. Minimum size is 512 bytes.\n");
           98  +    exit(1);
           99  +  }
          100  +  if( fread(aHdr, 100, 1, in)!=1 ){
          101  +    fprintf(stderr, "Cannot read file header\n");
          102  +    exit(1);
          103  +  }
          104  +  rewind(in);
          105  +  if( pgsz==0 ){
          106  +    pgsz = (aHdr[16]<<8) | aHdr[17];
          107  +    if( pgsz==1 ) pgsz = 65536;
          108  +    if( pgsz<512 || (pgsz&(pgsz-1))!=0 ){
          109  +      fprintf(stderr, "Invalid page size in header: %d\n", pgsz);
          110  +      exit(1);
          111  +    }
          112  +  }
          113  +  zBaseName = zInputFile;
          114  +  for(i=0; zInputFile[i]; i++){
          115  +    if( zInputFile[i]=='/' && zInputFile[i+1]!=0 ) zBaseName = zInputFile+1;
          116  +  }
          117  +  printf("| size %d pagesize %d filename %s\n",(int)szFile,pgsz,zBaseName);
          118  +  for(i=0; i<szFile; i+=16){
          119  +    int got = (int)fread(aLine, 1, 16, in);
          120  +    if( got!=16 ){
          121  +      static int once = 1;
          122  +      if( once ){
          123  +        fprintf(stderr, "Could not read input file starting at byte %d\n",
          124  +                         i+got);
          125  +      }
          126  +      memset(aLine+got, 0, 16-got);
          127  +    }
          128  +    if( allZero(aLine) ) continue;
          129  +    iPage = i/pgsz + 1;
          130  +    if( lastPage!=iPage ){
          131  +      printf("| page %d offset %d\n", iPage, (iPage-1)*pgsz);
          132  +      lastPage = iPage;
          133  +    }
          134  +    printf("|  %5d:", i-(iPage-1)*pgsz);
          135  +    for(j=0; j<16; j++) printf(" %02x", aLine[j]);
          136  +    printf("   ");
          137  +    for(j=0; j<16; j++){
          138  +      unsigned char c = (unsigned char)aLine[j];
          139  +      fputc( bShow[c], stdout);
          140  +    }
          141  +    fputc('\n', stdout);
          142  +  }
          143  +  fclose(in);
          144  +  printf("| end %s\n", zBaseName);
          145  +  return 0;
          146  +}

Added tool/dbtotxt.md.

            1  +<h1 align="center">The dbtotxt Tool</h1>
            2  +
            3  +The dbtotxt utility program reads an SQLite database file and writes its
            4  +raw binary content to screen as a hex dump for testing and debugging
            5  +purposes.
            6  +
            7  +The hex-dump output is formatted in such a way as to be easily readable
            8  +both by humans and by software.  The dbtotxt utility has long been a part
            9  +of the TH3 test suite.  The output of dbtotxt can be embedded in TH3 test
           10  +scripts and used to generate very specific database files, perhaps with
           11  +deliberately introduced corruption.  The cov1/corrupt*.test modules in
           12  +TH3 make extensive use of dbtotxt.
           13  +
           14  +More recently (2018-12-13) the dbtotxt utility has been added to the SQLite 
           15  +core and the command-line shell (CLI) has been augmented to be able to read 
           16  +dbtotxt output.  The CLI dot-command is:
           17  +
           18  +>     .open --hexdb  ?OPTIONAL-FILENAME?
           19  +
           20  +If the OPTIONAL-FILENAME is included, then content is read from that file.
           21  +If OPTIONAL-FILENAME is omitted, then the text is taken from the input stream,
           22  +terminated by the "| end" line of the dbtotxt text.  This allows small test
           23  +databases to be embedded directly in scripts.  Consider this example:
           24  +
           25  +>
           26  +    .open --hexdb
           27  +    | size 8192 pagesize 4096 filename x9.db
           28  +    | page 1 offset 0
           29  +    |      0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00   SQLite format 3.
           30  +    |     16: 10 00 01 01 00 40 20 20 00 00 00 04 00 00 00 02   .....@  ........
           31  +    |     32: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 04   ................
           32  +    |     48: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00   ................
           33  +    |     80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 04   ................
           34  +    |     96: 00 2e 30 38 0d 00 00 00 01 0f c0 00 0f c0 00 00   ..08............
           35  +    |   4032: 3e 01 06 17 11 11 01 69 74 61 62 6c 65 74 31 74   >......itablet1t
           36  +    |   4048: 31 02 43 52 45 41 54 45 20 54 41 42 4c 45 20 74   1.CREATE TABLE t
           37  +    |   4064: 31 28 78 2c 79 20 44 45 46 41 55 4c 54 20 78 27   1(x,y DEFAULT x'
           38  +    |   4080: 66 66 27 2c 7a 20 44 45 46 41 55 4c 54 20 30 29   ff',z DEFAULT 0)
           39  +    | page 2 offset 4096
           40  +    |      0: 0d 08 14 00 04 00 10 00 0e 05 0a 0f 04 15 00 10   ................
           41  +    |     16: 88 02 03 05 90 04 0e 08 00 00 00 00 00 00 00 00   ................
           42  +    |   1040: 00 00 00 00 ff 87 7c 02 05 8f 78 0e 08 00 00 00   ......|...x.....
           43  +    |   2064: 00 00 00 ff 0c 0a 01 fb 00 00 00 00 00 00 00 00   ................
           44  +    |   2560: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 83   ................
           45  +    |   2576: 78 01 05 87 70 0e 08 00 00 00 00 00 00 00 00 00   x...p...........
           46  +    |   3072: 00 00 00 00 00 00 00 00 00 ff 00 00 01 fb 00 00   ................
           47  +    |   3584: 00 00 00 00 00 83 78 00 05 87 70 0e 08 00 00 00   ......x...p.....
           48  +    |   4080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ff   ................
           49  +    | end x9.db
           50  +    SELECT rowid FROM t1;
           51  +    PRAGMA integrity_check;
           52  +
           53  +You can run this script to see that the database file is correctly decoded 
           54  +and loaded.  Furthermore, you can make subtle corruptions to the input
           55  +database simply by editing the hexadecimal description, then rerun the
           56  +script to verify that SQLite correctly handles the corruption.