/ Check-in [44e1b55a]
Login

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

Overview
Comment:Merge performance enhancements and other patches.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | factor-out-scalar-subselect
Files: files | file ages | folders
SHA3-256: 44e1b55aab331933719b67f7fcf7d335234b8b79599fba6033a0a27094bcb644
User & Date: drh 2018-12-28 21:40:46
Context
2018-12-28
21:40
Merge performance enhancements and other patches. Leaf check-in: 44e1b55a user: drh tags: factor-out-scalar-subselect
21:32
Merge performance enhancements from trunk. check-in: 0f1b9ff9 user: drh tags: reuse-subqueries
2018-12-26
15:04
Here is the beginnings of an effort to factor out the implementation of scalar subqueries to be implemented as subroutines at the end of the main body of bytecode, after the jump back to the OP_Init opcode. This is an incremental check-in that contains only preliminary changes. check-in: 50e5f390 user: drh tags: factor-out-scalar-subselect
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to ext/fts3/fts3_unicode2.c.

196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
...
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
    'f',       'g',       'h',       'h',       'i',       'i'|HIBIT, 
    'k',       'l',       'l'|HIBIT, 'l',       'm',       'n',       
    'o'|HIBIT, 'p',       'r',       'r'|HIBIT, 'r',       's',       
    's'|HIBIT, 't',       'u',       'u'|HIBIT, 'v',       'w',       
    'w',       'x',       'y',       'z',       'h',       't',       
    'w',       'y',       'a',       'a'|HIBIT, 'a'|HIBIT, 'a'|HIBIT, 
    'e',       'e'|HIBIT, 'e'|HIBIT, 'i',       'o',       'o'|HIBIT, 
    'o'|HIBIT, 'o'|HIBIT, 'u',       'u'|HIBIT, 'u'|HIBIT, 'y',  
  };

  unsigned int key = (((unsigned int)c)<<3) | 0x00000007;
  int iRes = 0;
  int iHi = sizeof(aDia)/sizeof(aDia[0]) - 1;
  int iLo = 0;
  while( iHi>=iLo ){
................................................................................
** is a diacritical modifier character.
*/
int sqlite3FtsUnicodeIsdiacritic(int c){
  unsigned int mask0 = 0x08029FDF;
  unsigned int mask1 = 0x000361F8;
  if( c<768 || c>817 ) return 0;
  return (c < 768+32) ?
      (mask0 & (1 << (c-768))) :
      (mask1 & (1 << (c-768-32)));
}


/*
** Interpret the argument as a unicode codepoint. If the codepoint
** is an upper case character that has a lower case equivalent,
** return the codepoint corresponding to the lower case version.







|







 







|
|







196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
...
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
    'f',       'g',       'h',       'h',       'i',       'i'|HIBIT, 
    'k',       'l',       'l'|HIBIT, 'l',       'm',       'n',       
    'o'|HIBIT, 'p',       'r',       'r'|HIBIT, 'r',       's',       
    's'|HIBIT, 't',       'u',       'u'|HIBIT, 'v',       'w',       
    'w',       'x',       'y',       'z',       'h',       't',       
    'w',       'y',       'a',       'a'|HIBIT, 'a'|HIBIT, 'a'|HIBIT, 
    'e',       'e'|HIBIT, 'e'|HIBIT, 'i',       'o',       'o'|HIBIT, 
    'o'|HIBIT, 'o'|HIBIT, 'u',       'u'|HIBIT, 'u'|HIBIT, 'y',       
  };

  unsigned int key = (((unsigned int)c)<<3) | 0x00000007;
  int iRes = 0;
  int iHi = sizeof(aDia)/sizeof(aDia[0]) - 1;
  int iLo = 0;
  while( iHi>=iLo ){
................................................................................
** is a diacritical modifier character.
*/
int sqlite3FtsUnicodeIsdiacritic(int c){
  unsigned int mask0 = 0x08029FDF;
  unsigned int mask1 = 0x000361F8;
  if( c<768 || c>817 ) return 0;
  return (c < 768+32) ?
      (mask0 & ((unsigned int)1 << (c-768))) :
      (mask1 & ((unsigned int)1 << (c-768-32)));
}


/*
** Interpret the argument as a unicode codepoint. If the codepoint
** is an upper case character that has a lower case equivalent,
** return the codepoint corresponding to the lower case version.

Changes to ext/fts3/fts3_write.c.

1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
  pReader->aDoclist = pNext;
  pReader->pOffsetList = 0;

  /* Check that the doclist does not appear to extend past the end of the
  ** b-tree node. And that the final byte of the doclist is 0x00. If either 
  ** of these statements is untrue, then the data structure is corrupt.
  */
  if( (&pReader->aNode[pReader->nNode] - pReader->aDoclist)<pReader->nDoclist
   || (pReader->nPopulate==0 && pReader->aDoclist[pReader->nDoclist-1])
  ){
    return FTS_CORRUPT_VTAB;
  }
  return SQLITE_OK;
}








|







1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
  pReader->aDoclist = pNext;
  pReader->pOffsetList = 0;

  /* Check that the doclist does not appear to extend past the end of the
  ** b-tree node. And that the final byte of the doclist is 0x00. If either 
  ** of these statements is untrue, then the data structure is corrupt.
  */
  if( pReader->nDoclist > pReader->nNode-(pReader->aDoclist-pReader->aNode)
   || (pReader->nPopulate==0 && pReader->aDoclist[pReader->nDoclist-1])
  ){
    return FTS_CORRUPT_VTAB;
  }
  return SQLITE_OK;
}

Changes to ext/fts3/unicode/mkunicode.tcl.

59
60
61
62
63
64
65

66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
...
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
...
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
...
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
    incr i

    puts -nonewline [format "%5d" [expr ($iCode<<3) + $nRange-1]]
    puts -nonewline ", "
  }
  puts ""
  puts "  \};"

  puts "  char aChar\[\] = \{"
  puts -nonewline "    '\\0',      "
  set i 1
  foreach c $aChar f $aFlag {
    if { $f } {
      set str "'$c'|0x80,  "
    } else {
      set str "'$c'|0x00,  "
    }
    if {$c == ""} { set str "'\\0',      " }

    if {($i % 6)==0} {puts "" ; puts -nonewline "    " }
    incr i
    puts -nonewline "$str"
  }
................................................................................
  puts "*/"
  puts "int ${zFunc}\(int c)\{"
  puts "  unsigned int mask0 = [format "0x%08X" $i1];"
  puts "  unsigned int mask1 = [format "0x%08X" $i2];"

  puts "  if( c<$iFirst || c>$iLast ) return 0;"
  puts "  return (c < $iFirst+32) ?"
  puts "      (mask0 & (1 << (c-$iFirst))) :"
  puts "      (mask1 & (1 << (c-$iFirst-32)));"
  puts "\}"
}


#-------------------------------------------------------------------------

proc an_load_separator_ranges {} {
................................................................................
  set aMapArray [intarray $aMap]
  set aDataArray [intarray $aData]
  puts [code {
    static u16 aFts5UnicodeBlock[] = {$aBlockArray};
    static u16 aFts5UnicodeMap[] = {$aMapArray};
    static u16 aFts5UnicodeData[] = {$aDataArray};

    int sqlite3Fts5UnicodeCategory(int iCode) { 
      int iRes = -1;
      int iHi;
      int iLo;
      int ret;
      u16 iKey;

      if( iCode>=(1<<20) ){
................................................................................
        if( aCP[iCP].iCode==i ){
          sqlite3Fts5UnicodeCatParse(aCP[iCP].zCat, aArray);
          iCP++;
        }else{
          aArray[0] = 1;
        }

        c = sqlite3Fts5UnicodeCategory(i);
        if( aArray[c]==0 ){
          *piCode = i;
          return 1;
        }
      }

      return 0;







>





|

|







 







|
|







 







|







 







|







59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
...
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
...
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
...
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
    incr i

    puts -nonewline [format "%5d" [expr ($iCode<<3) + $nRange-1]]
    puts -nonewline ", "
  }
  puts ""
  puts "  \};"
  puts "#define HIBIT ((char)0x80)"
  puts "  char aChar\[\] = \{"
  puts -nonewline "    '\\0',      "
  set i 1
  foreach c $aChar f $aFlag {
    if { $f } {
      set str "'$c'|HIBIT, "
    } else {
      set str "'$c',       "
    }
    if {$c == ""} { set str "'\\0',      " }

    if {($i % 6)==0} {puts "" ; puts -nonewline "    " }
    incr i
    puts -nonewline "$str"
  }
................................................................................
  puts "*/"
  puts "int ${zFunc}\(int c)\{"
  puts "  unsigned int mask0 = [format "0x%08X" $i1];"
  puts "  unsigned int mask1 = [format "0x%08X" $i2];"

  puts "  if( c<$iFirst || c>$iLast ) return 0;"
  puts "  return (c < $iFirst+32) ?"
  puts "      (mask0 & ((unsigned int)1 << (c-$iFirst))) :"
  puts "      (mask1 & ((unsigned int)1 << (c-$iFirst-32)));"
  puts "\}"
}


#-------------------------------------------------------------------------

proc an_load_separator_ranges {} {
................................................................................
  set aMapArray [intarray $aMap]
  set aDataArray [intarray $aData]
  puts [code {
    static u16 aFts5UnicodeBlock[] = {$aBlockArray};
    static u16 aFts5UnicodeMap[] = {$aMapArray};
    static u16 aFts5UnicodeData[] = {$aDataArray};

    int sqlite3Fts5UnicodeCategory(u32 iCode) { 
      int iRes = -1;
      int iHi;
      int iLo;
      int ret;
      u16 iKey;

      if( iCode>=(1<<20) ){
................................................................................
        if( aCP[iCP].iCode==i ){
          sqlite3Fts5UnicodeCatParse(aCP[iCP].zCat, aArray);
          iCP++;
        }else{
          aArray[0] = 1;
        }

        c = sqlite3Fts5UnicodeCategory((u32)i);
        if( aArray[c]==0 ){
          *piCode = i;
          return 1;
        }
      }

      return 0;

Changes to ext/fts5/fts5Int.h.

784
785
786
787
788
789
790
791
792
793
794
795
796
797
/**************************************************************************
** Interface to automatically generated code in fts5_unicode2.c. 
*/
int sqlite3Fts5UnicodeIsdiacritic(int c);
int sqlite3Fts5UnicodeFold(int c, int bRemoveDiacritic);

int sqlite3Fts5UnicodeCatParse(const char*, u8*);
int sqlite3Fts5UnicodeCategory(int iCode);
void sqlite3Fts5UnicodeAscii(u8*, u8*);
/*
** End of interface to code in fts5_unicode2.c.
**************************************************************************/

#endif







|






784
785
786
787
788
789
790
791
792
793
794
795
796
797
/**************************************************************************
** Interface to automatically generated code in fts5_unicode2.c. 
*/
int sqlite3Fts5UnicodeIsdiacritic(int c);
int sqlite3Fts5UnicodeFold(int c, int bRemoveDiacritic);

int sqlite3Fts5UnicodeCatParse(const char*, u8*);
int sqlite3Fts5UnicodeCategory(u32 iCode);
void sqlite3Fts5UnicodeAscii(u8*, u8*);
/*
** End of interface to code in fts5_unicode2.c.
**************************************************************************/

#endif

Changes to ext/fts5/fts5_expr.c.

2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
    return;
  }
  memset(aArr, 0, sizeof(aArr));
  sqlite3Fts5UnicodeCatParse("L*", aArr);
  sqlite3Fts5UnicodeCatParse("N*", aArr);
  sqlite3Fts5UnicodeCatParse("Co", aArr);
  iCode = sqlite3_value_int(apVal[0]);
  sqlite3_result_int(pCtx, aArr[sqlite3Fts5UnicodeCategory(iCode)]);
}

static void fts5ExprFold(
  sqlite3_context *pCtx,          /* Function call context */
  int nArg,                       /* Number of args */
  sqlite3_value **apVal           /* Function arguments */
){







|







2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
    return;
  }
  memset(aArr, 0, sizeof(aArr));
  sqlite3Fts5UnicodeCatParse("L*", aArr);
  sqlite3Fts5UnicodeCatParse("N*", aArr);
  sqlite3Fts5UnicodeCatParse("Co", aArr);
  iCode = sqlite3_value_int(apVal[0]);
  sqlite3_result_int(pCtx, aArr[sqlite3Fts5UnicodeCategory((u32)iCode)]);
}

static void fts5ExprFold(
  sqlite3_context *pCtx,          /* Function call context */
  int nArg,                       /* Number of args */
  sqlite3_value **apVal           /* Function arguments */
){

Changes to ext/fts5/fts5_index.c.

686
687
688
689
690
691
692
693
694

695
696
697
698
699
700
701
...
856
857
858
859
860
861
862





863
864
865
866
867
868
869
...
888
889
890
891
892
893
894

895
896
897
898
899
900
901




902
903
904
905
906
907
908
....
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649

1650
1651
1652
1653
1654
1655
1656
....
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
....
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
....
3889
3890
3891
3892
3893
3894
3895

3896
3897
3898
3899
3900
3901
3902
....
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
....
5854
5855
5856
5857
5858
5859
5860
5861
5862
5863
5864
5865
5866
5867
5868
....
6269
6270
6271
6272
6273
6274
6275
6276
6277
6278
6279
6280
6281
6282
6283
6284
        rc = sqlite3_blob_read(p->pReader, aOut, nByte, 0);
      }
      if( rc!=SQLITE_OK ){
        sqlite3_free(pRet);
        pRet = 0;
      }else{
        /* TODO1: Fix this */
        pRet->szLeaf = fts5GetU16(&pRet->p[2]);
        pRet->p[nByte] = 0x00;

      }
    }
    p->rc = rc;
    p->nRead++;
  }

  assert( (pRet==0)==(p->rc!=SQLITE_OK) );
................................................................................
  if( piCookie ) *piCookie = sqlite3Fts5Get32(pData);
  i = 4;

  /* Read the total number of levels and segments from the start of the
  ** structure record.  */
  i += fts5GetVarint32(&pData[i], nLevel);
  i += fts5GetVarint32(&pData[i], nSegment);





  nByte = (
      sizeof(Fts5Structure) +                    /* Main structure */
      sizeof(Fts5StructureLevel) * (nLevel-1)    /* aLevel[] array */
  );
  pRet = (Fts5Structure*)sqlite3Fts5MallocZero(&rc, nByte);

  if( pRet ){
................................................................................
        );
        nSegment -= nTotal;
      }

      if( rc==SQLITE_OK ){
        pLvl->nSeg = nTotal;
        for(iSeg=0; iSeg<nTotal; iSeg++){

          if( i>=nData ){
            rc = FTS5_CORRUPT;
            break;
          }
          i += fts5GetVarint32(&pData[i], pLvl->aSeg[iSeg].iSegid);
          i += fts5GetVarint32(&pData[i], pLvl->aSeg[iSeg].pgnoFirst);
          i += fts5GetVarint32(&pData[i], pLvl->aSeg[iSeg].pgnoLast);




        }
      }
    }
    if( nSegment!=0 && rc==SQLITE_OK ) rc = FTS5_CORRUPT;

    if( rc!=SQLITE_OK ){
      fts5StructureRelease(pRet);
................................................................................
*/
static void fts5SegIterLoadTerm(Fts5Index *p, Fts5SegIter *pIter, int nKeep){
  u8 *a = pIter->pLeaf->p;        /* Buffer to read data from */
  int iOff = pIter->iLeafOffset;  /* Offset to read at */
  int nNew;                       /* Bytes of new data */

  iOff += fts5GetVarint32(&a[iOff], nNew);
  if( iOff+nNew>pIter->pLeaf->nn ){
    p->rc = FTS5_CORRUPT;
    return;
  }
  pIter->term.n = nKeep;
  fts5BufferAppendBlob(&p->rc, &pIter->term, nNew, &a[iOff]);

  iOff += nNew;
  pIter->iTermLeafOffset = iOff;
  pIter->iTermLeafPgno = pIter->iLeafPgno;
  pIter->iLeafOffset = iOff;

  if( pIter->iPgidxOff>=pIter->pLeaf->nn ){
    pIter->iEndofDoclist = pIter->pLeaf->nn+1;
................................................................................
    pIter->iLeafPgno = pSeg->pgnoFirst-1;
    fts5SegIterNextPage(p, pIter);
  }

  if( p->rc==SQLITE_OK ){
    pIter->iLeafOffset = 4;
    assert_nc( pIter->pLeaf->nn>4 );
    assert( fts5LeafFirstTermOff(pIter->pLeaf)==4 );
    pIter->iPgidxOff = pIter->pLeaf->szLeaf+1;
    fts5SegIterLoadTerm(p, pIter, 0);
    fts5SegIterLoadNPos(p, pIter);
  }
}

/*
................................................................................
      int i;
      u32 mask;
      memset(aUsed, 0, sizeof(aUsed));
      for(iLvl=0; iLvl<pStruct->nLevel; iLvl++){
        for(iSeg=0; iSeg<pStruct->aLevel[iLvl].nSeg; iSeg++){
          int iId = pStruct->aLevel[iLvl].aSeg[iSeg].iSegid;
          if( iId<=FTS5_MAX_SEGMENT ){
            aUsed[(iId-1) / 32] |= 1 << ((iId-1) % 32);
          }
        }
      }

      for(i=0; aUsed[i]==0xFFFFFFFF; i++);
      mask = aUsed[i];
      for(iSegid=0; mask & (1 << iSegid); iSegid++);
      iSegid += 1 + i*32;

#ifdef SQLITE_DEBUG
      for(iLvl=0; iLvl<pStruct->nLevel; iLvl++){
        for(iSeg=0; iSeg<pStruct->aLevel[iLvl].nSeg; iSeg++){
          assert_nc( iSegid!=pStruct->aLevel[iLvl].aSeg[iSeg].iSegid );
        }
................................................................................
  Fts5Index *p, 
  Fts5SegWriter *pWriter,
  int nTerm, const u8 *pTerm 
){
  int nPrefix;                    /* Bytes of prefix compression for term */
  Fts5PageWriter *pPage = &pWriter->writer;
  Fts5Buffer *pPgidx = &pWriter->writer.pgidx;


  assert( p->rc==SQLITE_OK );
  assert( pPage->buf.n>=4 );
  assert( pPage->buf.n>4 || pWriter->bFirstTermInPage );

  /* If the current leaf page is full, flush it to disk. */
  if( (pPage->buf.n + pPgidx->n + nTerm + 2)>=p->pConfig->pgsz ){
................................................................................
      ** Usually, the previous term is available in pPage->term. The exception
      ** is if this is the first term written in an incremental-merge step.
      ** In this case the previous term is not available, so just write a
      ** copy of (pTerm/nTerm) into the parent node. This is slightly
      ** inefficient, but still correct.  */
      int n = nTerm;
      if( pPage->term.n ){
        n = 1 + fts5PrefixCompress(pPage->term.n, pPage->term.p, pTerm);
      }
      fts5WriteBtreeTerm(p, pWriter, n, pTerm);
      pPage = &pWriter->writer;
    }
  }else{
    nPrefix = fts5PrefixCompress(pPage->term.n, pPage->term.p, pTerm);
    fts5BufferAppendVarint(&p->rc, &pPage->buf, nPrefix);
  }

  /* Append the number of bytes of new data, then the term data itself
  ** to the page. */
  fts5BufferAppendVarint(&p->rc, &pPage->buf, nTerm - nPrefix);
  fts5BufferAppendBlob(&p->rc, &pPage->buf, nTerm - nPrefix, &pTerm[nPrefix]);
................................................................................
      int iOff;                   /* Offset of first term on leaf */
      int iRowidOff;              /* Offset of first rowid on leaf */
      int nTerm;                  /* Size of term on leaf in bytes */
      int res;                    /* Comparison of term and split-key */

      iOff = fts5LeafFirstTermOff(pLeaf);
      iRowidOff = fts5LeafFirstRowidOff(pLeaf);
      if( iRowidOff>=iOff ){
        p->rc = FTS5_CORRUPT;
      }else{
        iOff += fts5GetVarint32(&pLeaf->p[iOff], nTerm);
        res = memcmp(&pLeaf->p[iOff], zIdxTerm, MIN(nTerm, nIdxTerm));
        if( res==0 ) res = nTerm - nIdxTerm;
        if( res<0 ) p->rc = FTS5_CORRUPT;
      }
................................................................................
  ** copy is followed by FTS5_DATA_ZERO_PADDING 0x00 bytes, which prevents
  ** buffer overreads even if the record is corrupt.  */
  n = sqlite3_value_bytes(apVal[1]);
  aBlob = sqlite3_value_blob(apVal[1]);
  nSpace = n + FTS5_DATA_ZERO_PADDING;
  a = (u8*)sqlite3Fts5MallocZero(&rc, nSpace);
  if( a==0 ) goto decode_out;
  memcpy(a, aBlob, n);


  fts5DecodeRowid(iRowid, &iSegid, &bDlidx, &iHeight, &iPgno);

  fts5DebugRowid(&rc, &s, iRowid);
  if( bDlidx ){
    Fts5Data dlidx;
    Fts5DlidxLvl lvl;







<

>







 







>
>
>
>
>







 







>




|
|
|
>
>
>
>







 







|





>







 







|







 







|






|







 







>







 







|





|







 







|







 







|
<







686
687
688
689
690
691
692

693
694
695
696
697
698
699
700
701
...
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
...
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
....
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
....
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
....
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
....
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
....
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
....
5866
5867
5868
5869
5870
5871
5872
5873
5874
5875
5876
5877
5878
5879
5880
....
6281
6282
6283
6284
6285
6286
6287
6288

6289
6290
6291
6292
6293
6294
6295
        rc = sqlite3_blob_read(p->pReader, aOut, nByte, 0);
      }
      if( rc!=SQLITE_OK ){
        sqlite3_free(pRet);
        pRet = 0;
      }else{
        /* TODO1: Fix this */

        pRet->p[nByte] = 0x00;
        pRet->szLeaf = fts5GetU16(&pRet->p[2]);
      }
    }
    p->rc = rc;
    p->nRead++;
  }

  assert( (pRet==0)==(p->rc!=SQLITE_OK) );
................................................................................
  if( piCookie ) *piCookie = sqlite3Fts5Get32(pData);
  i = 4;

  /* Read the total number of levels and segments from the start of the
  ** structure record.  */
  i += fts5GetVarint32(&pData[i], nLevel);
  i += fts5GetVarint32(&pData[i], nSegment);
  if( nLevel>FTS5_MAX_SEGMENT   || nLevel<0
   || nSegment>FTS5_MAX_SEGMENT || nSegment<0
  ){
    return FTS5_CORRUPT;
  }
  nByte = (
      sizeof(Fts5Structure) +                    /* Main structure */
      sizeof(Fts5StructureLevel) * (nLevel-1)    /* aLevel[] array */
  );
  pRet = (Fts5Structure*)sqlite3Fts5MallocZero(&rc, nByte);

  if( pRet ){
................................................................................
        );
        nSegment -= nTotal;
      }

      if( rc==SQLITE_OK ){
        pLvl->nSeg = nTotal;
        for(iSeg=0; iSeg<nTotal; iSeg++){
          Fts5StructureSegment *pSeg = &pLvl->aSeg[iSeg];
          if( i>=nData ){
            rc = FTS5_CORRUPT;
            break;
          }
          i += fts5GetVarint32(&pData[i], pSeg->iSegid);
          i += fts5GetVarint32(&pData[i], pSeg->pgnoFirst);
          i += fts5GetVarint32(&pData[i], pSeg->pgnoLast);
          if( pSeg->pgnoLast<pSeg->pgnoFirst ){
            rc = FTS5_CORRUPT;
            break;
          }
        }
      }
    }
    if( nSegment!=0 && rc==SQLITE_OK ) rc = FTS5_CORRUPT;

    if( rc!=SQLITE_OK ){
      fts5StructureRelease(pRet);
................................................................................
*/
static void fts5SegIterLoadTerm(Fts5Index *p, Fts5SegIter *pIter, int nKeep){
  u8 *a = pIter->pLeaf->p;        /* Buffer to read data from */
  int iOff = pIter->iLeafOffset;  /* Offset to read at */
  int nNew;                       /* Bytes of new data */

  iOff += fts5GetVarint32(&a[iOff], nNew);
  if( iOff+nNew>pIter->pLeaf->nn || nKeep>pIter->term.n ){
    p->rc = FTS5_CORRUPT;
    return;
  }
  pIter->term.n = nKeep;
  fts5BufferAppendBlob(&p->rc, &pIter->term, nNew, &a[iOff]);
  assert( pIter->term.n<=pIter->term.nSpace );
  iOff += nNew;
  pIter->iTermLeafOffset = iOff;
  pIter->iTermLeafPgno = pIter->iLeafPgno;
  pIter->iLeafOffset = iOff;

  if( pIter->iPgidxOff>=pIter->pLeaf->nn ){
    pIter->iEndofDoclist = pIter->pLeaf->nn+1;
................................................................................
    pIter->iLeafPgno = pSeg->pgnoFirst-1;
    fts5SegIterNextPage(p, pIter);
  }

  if( p->rc==SQLITE_OK ){
    pIter->iLeafOffset = 4;
    assert_nc( pIter->pLeaf->nn>4 );
    assert_nc( fts5LeafFirstTermOff(pIter->pLeaf)==4 );
    pIter->iPgidxOff = pIter->pLeaf->szLeaf+1;
    fts5SegIterLoadTerm(p, pIter, 0);
    fts5SegIterLoadNPos(p, pIter);
  }
}

/*
................................................................................
      int i;
      u32 mask;
      memset(aUsed, 0, sizeof(aUsed));
      for(iLvl=0; iLvl<pStruct->nLevel; iLvl++){
        for(iSeg=0; iSeg<pStruct->aLevel[iLvl].nSeg; iSeg++){
          int iId = pStruct->aLevel[iLvl].aSeg[iSeg].iSegid;
          if( iId<=FTS5_MAX_SEGMENT ){
            aUsed[(iId-1) / 32] |= (u32)1 << ((iId-1) % 32);
          }
        }
      }

      for(i=0; aUsed[i]==0xFFFFFFFF; i++);
      mask = aUsed[i];
      for(iSegid=0; mask & ((u32)1 << iSegid); iSegid++);
      iSegid += 1 + i*32;

#ifdef SQLITE_DEBUG
      for(iLvl=0; iLvl<pStruct->nLevel; iLvl++){
        for(iSeg=0; iSeg<pStruct->aLevel[iLvl].nSeg; iSeg++){
          assert_nc( iSegid!=pStruct->aLevel[iLvl].aSeg[iSeg].iSegid );
        }
................................................................................
  Fts5Index *p, 
  Fts5SegWriter *pWriter,
  int nTerm, const u8 *pTerm 
){
  int nPrefix;                    /* Bytes of prefix compression for term */
  Fts5PageWriter *pPage = &pWriter->writer;
  Fts5Buffer *pPgidx = &pWriter->writer.pgidx;
  int nMin = MIN(pPage->term.n, nTerm);

  assert( p->rc==SQLITE_OK );
  assert( pPage->buf.n>=4 );
  assert( pPage->buf.n>4 || pWriter->bFirstTermInPage );

  /* If the current leaf page is full, flush it to disk. */
  if( (pPage->buf.n + pPgidx->n + nTerm + 2)>=p->pConfig->pgsz ){
................................................................................
      ** Usually, the previous term is available in pPage->term. The exception
      ** is if this is the first term written in an incremental-merge step.
      ** In this case the previous term is not available, so just write a
      ** copy of (pTerm/nTerm) into the parent node. This is slightly
      ** inefficient, but still correct.  */
      int n = nTerm;
      if( pPage->term.n ){
        n = 1 + fts5PrefixCompress(nMin, pPage->term.p, pTerm);
      }
      fts5WriteBtreeTerm(p, pWriter, n, pTerm);
      pPage = &pWriter->writer;
    }
  }else{
    nPrefix = fts5PrefixCompress(nMin, pPage->term.p, pTerm);
    fts5BufferAppendVarint(&p->rc, &pPage->buf, nPrefix);
  }

  /* Append the number of bytes of new data, then the term data itself
  ** to the page. */
  fts5BufferAppendVarint(&p->rc, &pPage->buf, nTerm - nPrefix);
  fts5BufferAppendBlob(&p->rc, &pPage->buf, nTerm - nPrefix, &pTerm[nPrefix]);
................................................................................
      int iOff;                   /* Offset of first term on leaf */
      int iRowidOff;              /* Offset of first rowid on leaf */
      int nTerm;                  /* Size of term on leaf in bytes */
      int res;                    /* Comparison of term and split-key */

      iOff = fts5LeafFirstTermOff(pLeaf);
      iRowidOff = fts5LeafFirstRowidOff(pLeaf);
      if( iRowidOff>=iOff || iOff>=pLeaf->szLeaf ){
        p->rc = FTS5_CORRUPT;
      }else{
        iOff += fts5GetVarint32(&pLeaf->p[iOff], nTerm);
        res = memcmp(&pLeaf->p[iOff], zIdxTerm, MIN(nTerm, nIdxTerm));
        if( res==0 ) res = nTerm - nIdxTerm;
        if( res<0 ) p->rc = FTS5_CORRUPT;
      }
................................................................................
  ** copy is followed by FTS5_DATA_ZERO_PADDING 0x00 bytes, which prevents
  ** buffer overreads even if the record is corrupt.  */
  n = sqlite3_value_bytes(apVal[1]);
  aBlob = sqlite3_value_blob(apVal[1]);
  nSpace = n + FTS5_DATA_ZERO_PADDING;
  a = (u8*)sqlite3Fts5MallocZero(&rc, nSpace);
  if( a==0 ) goto decode_out;
  if( n>0 ) memcpy(a, aBlob, n);


  fts5DecodeRowid(iRowid, &iSegid, &bDlidx, &iHeight, &iPgno);

  fts5DebugRowid(&rc, &s, iRowid);
  if( bDlidx ){
    Fts5Data dlidx;
    Fts5DlidxLvl lvl;

Changes to ext/fts5/fts5_test_tok.c.

374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
  if( idxNum==1 ){
    const char *zByte = (const char *)sqlite3_value_text(apVal[0]);
    int nByte = sqlite3_value_bytes(apVal[0]);
    pCsr->zInput = sqlite3_malloc(nByte+1);
    if( pCsr->zInput==0 ){
      rc = SQLITE_NOMEM;
    }else{
      memcpy(pCsr->zInput, zByte, nByte);
      pCsr->zInput[nByte] = 0;
      rc = pTab->tok.xTokenize(
          pTab->pTok, (void*)pCsr, 0, zByte, nByte, fts5tokCb
      );
    }
  }








|







374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
  if( idxNum==1 ){
    const char *zByte = (const char *)sqlite3_value_text(apVal[0]);
    int nByte = sqlite3_value_bytes(apVal[0]);
    pCsr->zInput = sqlite3_malloc(nByte+1);
    if( pCsr->zInput==0 ){
      rc = SQLITE_NOMEM;
    }else{
      if( nByte>0 ) memcpy(pCsr->zInput, zByte, nByte);
      pCsr->zInput[nByte] = 0;
      rc = pTab->tok.xTokenize(
          pTab->pTok, (void*)pCsr, 0, zByte, nByte, fts5tokCb
      );
    }
  }

Changes to ext/fts5/fts5_tokenize.c.

258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
...
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
...
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
  if( n>0 ){
    aNew = (int*)sqlite3_realloc(p->aiException, (n+p->nException)*sizeof(int));
    if( aNew ){
      int nNew = p->nException;
      const unsigned char *zCsr = (const unsigned char*)z;
      const unsigned char *zTerm = (const unsigned char*)&z[n];
      while( zCsr<zTerm ){
        int iCode;
        int bToken;
        READ_UTF8(zCsr, zTerm, iCode);
        if( iCode<128 ){
          p->aTokenChar[iCode] = (unsigned char)bTokenChars;
        }else{
          bToken = p->aCategory[sqlite3Fts5UnicodeCategory(iCode)];
          assert( (bToken==0 || bToken==1) ); 
................................................................................
/*
** Return true if, for the purposes of tokenizing with the tokenizer
** passed as the first argument, codepoint iCode is considered a token 
** character (not a separator).
*/
static int fts5UnicodeIsAlnum(Unicode61Tokenizer *p, int iCode){
  return (
    p->aCategory[sqlite3Fts5UnicodeCategory(iCode)]
    ^ fts5UnicodeIsException(p, iCode)
  );
}

static int fts5UnicodeTokenize(
  Fts5Tokenizer *pTokenizer,
  void *pCtx,
................................................................................
  const char *pEnd = &aFold[nFold-6];

  UNUSED_PARAM(iUnused);

  /* Each iteration of this loop gobbles up a contiguous run of separators,
  ** then the next token.  */
  while( rc==SQLITE_OK ){
    int iCode;                    /* non-ASCII codepoint read from input */
    char *zOut = aFold;
    int is;
    int ie;

    /* Skip any separator characters. */
    while( 1 ){
      if( zCsr>=zTerm ) goto tokenize_done;







|







 







|







 







|







258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
...
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
...
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
  if( n>0 ){
    aNew = (int*)sqlite3_realloc(p->aiException, (n+p->nException)*sizeof(int));
    if( aNew ){
      int nNew = p->nException;
      const unsigned char *zCsr = (const unsigned char*)z;
      const unsigned char *zTerm = (const unsigned char*)&z[n];
      while( zCsr<zTerm ){
        u32 iCode;
        int bToken;
        READ_UTF8(zCsr, zTerm, iCode);
        if( iCode<128 ){
          p->aTokenChar[iCode] = (unsigned char)bTokenChars;
        }else{
          bToken = p->aCategory[sqlite3Fts5UnicodeCategory(iCode)];
          assert( (bToken==0 || bToken==1) ); 
................................................................................
/*
** Return true if, for the purposes of tokenizing with the tokenizer
** passed as the first argument, codepoint iCode is considered a token 
** character (not a separator).
*/
static int fts5UnicodeIsAlnum(Unicode61Tokenizer *p, int iCode){
  return (
    p->aCategory[sqlite3Fts5UnicodeCategory((u32)iCode)]
    ^ fts5UnicodeIsException(p, iCode)
  );
}

static int fts5UnicodeTokenize(
  Fts5Tokenizer *pTokenizer,
  void *pCtx,
................................................................................
  const char *pEnd = &aFold[nFold-6];

  UNUSED_PARAM(iUnused);

  /* Each iteration of this loop gobbles up a contiguous run of separators,
  ** then the next token.  */
  while( rc==SQLITE_OK ){
    u32 iCode;                    /* non-ASCII codepoint read from input */
    char *zOut = aFold;
    int is;
    int ie;

    /* Skip any separator characters. */
    while( 1 ){
      if( zCsr>=zTerm ) goto tokenize_done;

Changes to ext/fts5/fts5_unicode2.c.

65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
..
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
...
244
245
246
247
248
249
250

251
252
253
254
255
256
257
...
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
...
769
770
771
772
773
774
775

    'f',       'g',       'h',       'h',       'i',       'i'|HIBIT, 
    'k',       'l',       'l'|HIBIT, 'l',       'm',       'n',       
    'o'|HIBIT, 'p',       'r',       'r'|HIBIT, 'r',       's',       
    's'|HIBIT, 't',       'u',       'u'|HIBIT, 'v',       'w',       
    'w',       'x',       'y',       'z',       'h',       't',       
    'w',       'y',       'a',       'a'|HIBIT, 'a'|HIBIT, 'a'|HIBIT, 
    'e',       'e'|HIBIT, 'e'|HIBIT, 'i',       'o',       'o'|HIBIT, 
    'o'|HIBIT, 'o'|HIBIT, 'u',       'u'|HIBIT, 'u'|HIBIT, 'y',  
  };

  unsigned int key = (((unsigned int)c)<<3) | 0x00000007;
  int iRes = 0;
  int iHi = sizeof(aDia)/sizeof(aDia[0]) - 1;
  int iLo = 0;
  while( iHi>=iLo ){
................................................................................
** is a diacritical modifier character.
*/
int sqlite3Fts5UnicodeIsdiacritic(int c){
  unsigned int mask0 = 0x08029FDF;
  unsigned int mask1 = 0x000361F8;
  if( c<768 || c>817 ) return 0;
  return (c < 768+32) ?
      (mask0 & (1 << (c-768))) :
      (mask1 & (1 << (c-768-32)));
}


/*
** Interpret the argument as a unicode codepoint. If the codepoint
** is an upper case character that has a lower case equivalent,
** return the codepoint corresponding to the lower case version.
................................................................................
  
  else if( c>=66560 && c<66600 ){
    ret = c + 40;
  }

  return ret;
}


int sqlite3Fts5UnicodeCatParse(const char *zCat, u8 *aArray){ 
  aArray[0] = 1;
  switch( zCat[0] ){
    case 'C':
          switch( zCat[1] ){
            case 'c': aArray[1] = 1; break;
................................................................................
    89,    1434,  3226,  506,   474,   506,   506,   367,   1018,  1946,  
    1402,  954,   1402,  314,   90,    1082,  218,   2266,  666,   1210,  
    186,   570,   2042,  58,    5850,  154,   2010,  154,   794,   2266,  
    378,   2266,  3738,  39,    39,    39,    39,    39,    39,    17351, 
    34,    3074,  7692,  63,    63,    
  };

int sqlite3Fts5UnicodeCategory(int iCode) { 
  int iRes = -1;
  int iHi;
  int iLo;
  int ret;
  u16 iKey;

  if( iCode>=(1<<20) ){
................................................................................
    int n = (aFts5UnicodeData[iTbl] >> 5) + i;
    for(; i<128 && i<n; i++){
      aAscii[i] = bToken;
    }
    iTbl++;
  }
}








|







 







|
|







 







>







 







|







 







>
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
..
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
...
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
...
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
...
770
771
772
773
774
775
776
777
    'f',       'g',       'h',       'h',       'i',       'i'|HIBIT, 
    'k',       'l',       'l'|HIBIT, 'l',       'm',       'n',       
    'o'|HIBIT, 'p',       'r',       'r'|HIBIT, 'r',       's',       
    's'|HIBIT, 't',       'u',       'u'|HIBIT, 'v',       'w',       
    'w',       'x',       'y',       'z',       'h',       't',       
    'w',       'y',       'a',       'a'|HIBIT, 'a'|HIBIT, 'a'|HIBIT, 
    'e',       'e'|HIBIT, 'e'|HIBIT, 'i',       'o',       'o'|HIBIT, 
    'o'|HIBIT, 'o'|HIBIT, 'u',       'u'|HIBIT, 'u'|HIBIT, 'y',       
  };

  unsigned int key = (((unsigned int)c)<<3) | 0x00000007;
  int iRes = 0;
  int iHi = sizeof(aDia)/sizeof(aDia[0]) - 1;
  int iLo = 0;
  while( iHi>=iLo ){
................................................................................
** is a diacritical modifier character.
*/
int sqlite3Fts5UnicodeIsdiacritic(int c){
  unsigned int mask0 = 0x08029FDF;
  unsigned int mask1 = 0x000361F8;
  if( c<768 || c>817 ) return 0;
  return (c < 768+32) ?
      (mask0 & ((unsigned int)1 << (c-768))) :
      (mask1 & ((unsigned int)1 << (c-768-32)));
}


/*
** Interpret the argument as a unicode codepoint. If the codepoint
** is an upper case character that has a lower case equivalent,
** return the codepoint corresponding to the lower case version.
................................................................................
  
  else if( c>=66560 && c<66600 ){
    ret = c + 40;
  }

  return ret;
}


int sqlite3Fts5UnicodeCatParse(const char *zCat, u8 *aArray){ 
  aArray[0] = 1;
  switch( zCat[0] ){
    case 'C':
          switch( zCat[1] ){
            case 'c': aArray[1] = 1; break;
................................................................................
    89,    1434,  3226,  506,   474,   506,   506,   367,   1018,  1946,  
    1402,  954,   1402,  314,   90,    1082,  218,   2266,  666,   1210,  
    186,   570,   2042,  58,    5850,  154,   2010,  154,   794,   2266,  
    378,   2266,  3738,  39,    39,    39,    39,    39,    39,    17351, 
    34,    3074,  7692,  63,    63,    
  };

int sqlite3Fts5UnicodeCategory(u32 iCode) { 
  int iRes = -1;
  int iHi;
  int iLo;
  int ret;
  u16 iKey;

  if( iCode>=(1<<20) ){
................................................................................
    int n = (aFts5UnicodeData[iTbl] >> 5) + i;
    for(; i<128 && i<n; i++){
      aAscii[i] = bToken;
    }
    iTbl++;
  }
}

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

31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
...
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
...
764
765
766
767
768
769
770







































































































771
































































































































































































































































772
773
774

























































































































































































































































































































































































































































































































775
776
777
    CREATE VIRTUAL TABLE t1 USING fts5(x);
    INSERT INTO t1(t1, rank) VALUES('pgsz', 64);
    WITH ii(i) AS (SELECT 1 UNION SELECT i+1 FROM ii WHERE i<100)
      INSERT INTO t1 SELECT rnddoc(10) FROM ii;
  }
}

if 1 {

# Create a simple FTS5 table containing 100 documents. Each document 
# contains 10 terms, each of which start with the character "x".
#
do_test 1.0 { create_t1 } {}

do_test 1.1 {
  # Pick out the rowid of the right-most b-tree leaf in the new segment.
................................................................................
    db eval {DELETE FROM t5_data WHERE rowid = $i}
    set r [catchsql { INSERT INTO t5(t5) VALUES('integrity-check')} ]
    if {$r != "1 {database disk image is malformed}"} { error $r }
    db eval ROLLBACK  
  }
} {}

}

#------------------------------------------------------------------------
# Corruption within the structure record.
#
reset_db
do_execsql_test 8.1 {
  CREATE VIRTUAL TABLE t1 USING fts5(x, y);
  INSERT INTO t1 VALUES('one', 'two');
................................................................................
|   4048: 00 00 00 00 00 00 09 03 02 1b 72 65 62 75 69 6c   ..........rebuil
|   4064: 64 11 02 02 2b 69 6e 74 65 67 72 69 74 79 2d 63   d...+integrity-c
|   4080: 68 65 63 6b 0a 01 02 1d 6f 70 74 69 6d 69 7a 65   heck....optimize
| end c13.db
SELECT * FROM t1 WHERE t1 MATCH 'abandon';
}]} {}








































































































do_catchsql_test 14.1 {
































































































































































































































































  SELECT * FROM t1 WHERE t1 MATCH 'abandon'; 
} {1 {vtable constructor failed: t1}}


























































































































































































































































































































































































































































































































sqlite3_fts5_may_be_corrupt 0
finish_test








<
<







 







<
<







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|


>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>



31
32
33
34
35
36
37


38
39
40
41
42
43
44
...
374
375
376
377
378
379
380


381
382
383
384
385
386
387
...
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
    CREATE VIRTUAL TABLE t1 USING fts5(x);
    INSERT INTO t1(t1, rank) VALUES('pgsz', 64);
    WITH ii(i) AS (SELECT 1 UNION SELECT i+1 FROM ii WHERE i<100)
      INSERT INTO t1 SELECT rnddoc(10) FROM ii;
  }
}



# Create a simple FTS5 table containing 100 documents. Each document 
# contains 10 terms, each of which start with the character "x".
#
do_test 1.0 { create_t1 } {}

do_test 1.1 {
  # Pick out the rowid of the right-most b-tree leaf in the new segment.
................................................................................
    db eval {DELETE FROM t5_data WHERE rowid = $i}
    set r [catchsql { INSERT INTO t5(t5) VALUES('integrity-check')} ]
    if {$r != "1 {database disk image is malformed}"} { error $r }
    db eval ROLLBACK  
  }
} {}



#------------------------------------------------------------------------
# Corruption within the structure record.
#
reset_db
do_execsql_test 8.1 {
  CREATE VIRTUAL TABLE t1 USING fts5(x, y);
  INSERT INTO t1 VALUES('one', 'two');
................................................................................
|   4048: 00 00 00 00 00 00 09 03 02 1b 72 65 62 75 69 6c   ..........rebuil
|   4064: 64 11 02 02 2b 69 6e 74 65 67 72 69 74 79 2d 63   d...+integrity-c
|   4080: 68 65 63 6b 0a 01 02 1d 6f 70 74 69 6d 69 7a 65   heck....optimize
| end c13.db
SELECT * FROM t1 WHERE t1 MATCH 'abandon';
}]} {}

do_catchsql_test 13.1 {
  SELECT * FROM t1 WHERE t1 MATCH 'abandon'; 
} {1 {vtable constructor failed: t1}}

#-------------------------------------------------------------------------
reset_db
do_test 14.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
| size 28672 pagesize 4096 filename c14b.db
| page 1 offset 0
|      0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00   SQLite format 3.
|     16: 10 00 01 01 00 40 20 20 00 00 00 01 00 00 00 07   .....@  ........
|     32: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00   ................
|     48: 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00   ................
|     80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01   ................
|     96: 00 2e 30 38 0d 00 00 00 07 0d d2 00 0f c4 0f 6d   ..08...........m
|    112: 0f 02 0e ab 0e 4e 0d f6 0d d2 00 00 00 00 00 00   .....N..........
|   3536: 00 00 22 07 06 17 11 11 01 31 74 61 62 6c 65 74   .........1tablet
|   3552: 32 74 32 07 43 52 45 41 54 45 20 54 41 42 4c 45   2t2.CREATE TABLE
|   3568: 20 74 32 28 78 29 56 06 06 17 1f 1f 01 7d 74 61    t2(x)V.......ta
|   3584: 62 6c 65 74 31 5f 63 6f 6e 66 69 67 74 31 5f 63   blet1_configt1_c
|   3600: 6f 6e 66 69 67 06 43 52 45 41 54 45 20 54 41 42   onfig.CREATE TAB
|   3616: 4c 45 20 27 74 31 5f 63 6f 6e 66 69 67 27 28 6b   LE 't1_config'(k
|   3632: 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 76 29    PRIMARY KEY, v)
|   3648: 20 57 49 54 48 4f 55 54 20 52 4f 57 49 44 5b 05    WITHOUT ROWID[.
|   3664: 07 17 21 21 01 81 01 74 61 62 6c 65 74 31 5f 64   ..!!...tablet1_d
|   3680: 6f 63 73 69 7a 65 74 31 5f 64 6f 63 73 69 7a 65   ocsizet1_docsize
|   3696: 05 43 52 45 41 54 45 20 54 41 42 4c 45 20 27 74   .CREATE TABLE 't
|   3712: 31 5f 64 6f 63 73 69 7a 65 27 28 69 64 20 49 4e   1_docsize'(id IN
|   3728: 54 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45   TEGER PRIMARY KE
|   3744: 59 2c 20 73 7a 20 42 4c 4f 42 29 55 04 06 17 21   Y, sz BLOB)U...!
|   3760: 21 01 77 74 61 62 6c 65 74 31 5f 63 6f 6e 74 65   !.wtablet1_conte
|   3776: 6e 74 74 31 5f 63 6f 6e 74 65 6e 74 04 43 52 45   ntt1_content.CRE
|   3792: 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 63 6f   ATE TABLE 't1_co
|   3808: 6e 74 65 6e 74 27 28 69 64 20 49 4e 54 45 47 45   ntent'(id INTEGE
|   3824: 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 63   R PRIMARY KEY, c
|   3840: 30 29 69 03 07 17 19 19 01 81 2d 74 61 62 6c 65   0)i.......-table
|   3856: 74 31 5f 69 64 78 74 31 5f 69 64 78 03 43 52 45   t1_idxt1_idx.CRE
|   3872: 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 69 64   ATE TABLE 't1_id
|   3888: 78 27 28 73 65 67 69 64 2c 20 74 65 72 6d 2c 20   x'(segid, term, 
|   3904: 70 67 6e 6f 2c 20 50 52 49 4d 41 52 59 20 4b 45   pgno, PRIMARY KE
|   3920: 59 28 73 65 67 69 64 2c 20 74 65 72 6d 29 29 20   Y(segid, term)) 
|   3936: 57 49 54 48 4f 55 54 20 52 4f 57 49 44 55 02 07   WITHOUT ROWIDU..
|   3952: 17 1b 1b 01 81 01 74 61 62 6c 65 74 31 5f 64 61   ......tablet1_da
|   3968: 74 61 74 31 5f 64 61 74 61 02 43 52 45 41 54 45   tat1_data.CREATE
|   3984: 20 54 41 42 4c 45 20 27 74 31 5f 64 61 74 61 27    TABLE 't1_data'
|   4000: 28 69 64 20 49 4e 54 45 47 45 52 20 50 52 49 4d   (id INTEGER PRIM
|   4016: 41 52 59 20 4b 45 59 2c 20 62 6c 6f 63 6b 20 42   ARY KEY, block B
|   4032: 4c 4f 42 29 3a 01 06 17 11 11 08 63 74 61 62 6c   LOB):......ctabl
|   4048: 65 74 31 74 31 43 52 45 41 54 45 20 56 49 52 54   et1t1CREATE VIRT
|   4064: 55 41 4c 20 54 41 42 4c 45 20 74 31 20 55 53 49   UAL TABLE t1 USI
|   4080: 4e 47 20 66 74 73 35 28 63 6f 6e 74 65 6e 74 29   NG fts5(content)
| page 2 offset 4096
|      0: 0d 0f ef 00 04 0f 18 00 0f e8 0f 18 0f bd 0f 2c   ...............,
|   3856: 00 00 00 00 00 00 00 00 12 0a 03 00 2a 00 00 00   ............*...
|   3872: 00 01 02 02 00 02 01 01 01 02 01 01 81 09 88 80   ................
|   3888: 80 80 80 01 04 00 82 16 00 00 00 79 06 30 61 62   ...........y.0ab
|   3904: 61 63 6b 08 02 07 04 04 6e 64 6f 6e 08 02 05 02   ack.....ndon....
|   3920: 05 63 74 69 76 65 04 02 02 04 02 0b 02 04 6c 70   .ctive........lp
|   3936: 68 61 08 04 02 0a 02 03 74 6b 6d 06 02 02 03 02   ha......tkm.....
|   3952: 6f 6d 08 02 09 05 02 69 63 07 02 02 01 06 62 61   om.....ic.....ba
|   3968: 63 6b 75 70 08 02 04 02 05 6f 6f 6d 65 72 05 02   ckup.....oomer..
|   3984: 02 01 0c 63 68 61 6e 6e 65 62 6f 6f 6d 65 72 08   ...channeboomer.
|   4000: 02 08 07 01 6c 08 02 03 01 04 74 65 73 74 08 02   ....l.....test..
|   4016: 06 04 0a 09 0d 0a 08 07 07 0b 0a 11 06 24 84 80   .............$..
|   4032: 80 80 80 01 03 00 4e 00 00 00 1e 06 30 61 62 61   ......N.....0aba
|   4048: 63 6b 01 02 02 04 02 66 74 02 02 02 04 04 6e 64   ck.....ft.....nd
|   4064: 6f 6e 03 02 02 03 9a 07 05 01 03 00 10 08 11 00   on..............
|   4080: 00 00 11 24 00 00 00 00 01 01 01 00 01 01 01 01   ...$............
| page 3 offset 8192
|      0: 0a 00 00 00 02 0f f3 00 0f fa 0f f3 00 00 00 00   ................
|   4080: 00 00 00 06 04 01 0c 01 02 02 05 04 09 0c 01 02   ................
| page 4 offset 12288
|      0: 0d 00 00 00 08 0f 6a 00 0f f6 0f ec 0f e0 0f d5   ......j.........
|     16: 0f ca 0f c1 0f b6 0f 6a 00 00 00 00 00 00 00 00   .......j........
|   3936: 00 00 00 00 00 00 00 00 00 00 4a 08 04 00 81 19   ..........J.....
|   3952: 61 6c 70 68 61 20 63 68 61 6e 6e 65 6c 20 62 61   alpha channel ba
|   3968: 63 6b 75 70 20 61 62 61 6e 64 6f 6e 20 74 65 73   ckup abandon tes
|   3984: 74 20 61 62 61 63 6b 20 63 68 61 6e 6e 65 62 6f   t aback channebo
|   4000: 6f 6d 65 72 20 61 74 6f 6d 20 61 6c 70 68 61 20   omer atom alpha 
|   4016: 61 63 74 69 76 65 09 07 03 00 19 61 74 6f 6d 69   active.....atomi
|   4032: 63 07 06 03 00 15 61 74 6b 6d 09 05 03 00 19 62   c.....atkm.....b
|   4048: 6f 6f 6d 65 72 09 04 03 00 19 61 63 74 69 76 65   oomer.....active
|   4064: 0a 03 03 00 1b 61 62 61 6e 64 6f 6e 08 02 03 00   .....abandon....
|   4080: 17 61 62 61 66 74 08 01 03 00 17 61 62 61 63 6b   .abaft.....aback
| page 5 offset 16384
|      0: 0d 00 00 00 08 0f d0 00 0f fa 0f f4 0f ee 0f e8   ................
|     16: 0f e2 0f dc 0f d6 0f d0 00 00 00 00 00 00 00 00   ................
|   4048: 04 08 03 00 0e 0a 04 07 03 00 0e 01 04 06 03 00   ................
|   4064: 0e 01 04 05 03 00 0e 01 04 04 03 00 0e 01 04 03   ................
|   4080: 03 00 0e 01 04 02 03 00 0e 01 04 01 03 00 0e 01   ................
| page 6 offset 20480
|      0: 0a 00 00 00 01 0f f4 00 0f f4 00 00 00 00 00 00   ................
|   4080: 00 00 00 00 0b 03 1b 01 76 65 72 73 69 6f 6e 04   ........version.
| page 7 offset 24576
|      0: 0d 00 00 00 03 0f d6 00 0f f4 0f e1 0f d6 00 00   ................
|   4048: 00 00 00 00 00 00 09 03 02 1b 72 65 62 75 69 6c   ..........rebuil
|   4064: 64 11 02 02 2b 69 6e 74 65 67 72 69 74 79 2d 63   d...+integrity-c
|   4080: 68 65 63 6b 0a 01 02 1d 6f 70 74 69 6d 69 7a 65   heck....optimize
| end c14b.db
}]} {}

do_catchsql_test 14.1 {
  INSERT INTO t1(t1) VALUES('optimize');
} {1 {database disk image is malformed}}

#---------------------------------------------------------------------------
#
reset_db
do_test 15.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
| size 32768 pagesize 4096 filename c16.db
| page 1 offset 0
|      0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00   SQLite format 3.
|     16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 07   .....@  ........
|     32: 00 00 00 00 00 00 00 00 00 00 00 07 00 00 00 00   ................
|     48: 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00   ................
|     96: 00 00 00 00 0d 00 00 00 07 0d d2 00 0f c4 0f 6d   ...............m
|    112: 0f 02 0e ab 0e 4e 0d f6 0d d2 00 00 00 00 00 00   .....N..........
|   3536: 00 00 22 07 06 17 11 11 01 31 74 61 62 6c 65 74   .........1tablet
|   3552: 32 74 32 07 43 52 45 41 54 45 20 54 41 42 4c 45   2t2.CREATE TABLE
|   3568: 20 74 32 28 78 29 56 06 06 17 1f 1f 01 7d 74 61    t2(x)V.......ta
|   3584: 62 6c 65 74 31 5f 63 6f 6e 66 69 67 74 31 5f 63   blet1_configt1_c
|   3600: 6f 6e 66 69 67 06 43 52 45 41 54 45 20 54 41 42   onfig.CREATE TAB
|   3616: 4c 45 20 27 74 31 5f 63 6f 6e 66 69 67 27 28 6b   LE 't1_config'(k
|   3632: 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 76 29    PRIMARY KEY, v)
|   3648: 20 57 49 54 48 4f 55 54 20 52 4f 57 49 44 5b 05    WITHOUT ROWID[.
|   3664: 07 17 21 21 01 81 01 74 61 62 6c 00 0f f6 0f ec   ..!!...tabl.....
|   3680: 0f e0 73 69 7a 65 74 31 5f 64 6f 63 73 69 7a 65   ..sizet1_docsize
|   3696: 05 43 52 45 41 54 45 20 54 41 42 4c 45 20 27 74   .CREATE TABLE 't
|   3712: 31 5f 64 6f 63 73 69 7a 65 27 28 69 64 20 49 4e   1_docsize'(id IN
|   3728: 54 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45   TEGER PRIMARY KE
|   3744: 59 2c 20 73 7a 20 42 4c 4f 42 29 55 04 06 17 21   Y, sz BLOB)U...!
|   3760: 21 01 77 74 61 62 6c 65 74 31 5f 63 6f 6e 74 65   !.wtablet1_conte
|   3776: 6e 74 74 31 5f 63 6f 6e 74 65 6e 74 04 43 52 45   ntt1_content.CRE
|   3792: 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 63 6f   ATE TABLE 't1_co
|   3808: 6e 74 65 6e 74 27 28 69 64 20 49 4e 54 45 47 45   ntent'(id INTEGE
|   3824: 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 63   R PRIMARY KEY, c
|   3840: 30 29 69 03 07 17 19 19 01 81 2d 74 61 62 6c 65   0)i.......-table
|   3856: 74 31 5f 69 64 78 74 31 5f 69 64 78 03 43 52 45   t1_idxt1_idx.CRE
|   3872: 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 69 64   ATE TABLE 't1_id
|   3888: 78 27 28 73 65 67 69 64 2c 20 74 65 72 6d 2c 20   x'(segid, term, 
|   3904: 70 67 6e 6f 2c 20 50 52 49 4d 41 52 59 20 4b 45   pgno, PRIMARY KE
|   3920: 59 28 73 65 67 69 64 2c 20 74 65 72 6d 29 29 20   Y(segid, term)) 
|   3936: 57 49 54 48 4f 55 54 20 52 4f 57 49 44 55 02 07   WITHOUT ROWIDU..
|   3952: 17 1b 1b 01 81 01 74 61 62 6c 65 74 31 5f 64 61   ......tablet1_da
|   3968: 74 61 74 31 5f 64 61 74 61 02 43 52 45 41 54 45   tat1_data.CREATE
|   3984: 20 54 41 42 4c 45 20 27 74 31 5f 64 61 74 61 27    TABLE 't1_data'
|   4000: 28 69 64 20 49 4e 54 45 47 45 52 20 50 52 49 4d   (id INTEGER PRIM
|   4016: 41 52 59 20 4b 45 59 2c 20 62 6c 6f 63 6b 20 42   ARY KEY, block B
|   4032: 4c 4f 42 29 3a 01 06 17 11 11 08 63 74 61 62 6c   LOB):......ctabl
|   4048: 65 74 31 74 31 43 52 45 41 54 45 20 56 49 52 54   et1t1CREATE VIRT
|   4064: 55 41 4c 20 54 41 42 4c 45 20 74 31 20 55 53 49   UAL TABLE t1 USI
|   4080: 4e 47 20 66 74 73 35 28 63 6f 6e 74 65 6e 74 29   NG fts5(content)
| page 2 offset 4096
|      0: 0d 00 00 00 03 0f bd 00 0f e8 0f ef 0f bd 00 00   ................
|   4016: 00 00 00 00 00 00 00 00 00 00 00 00 00 24 84 80   .............$..
|   4032: 80 80 80 01 03 00 4e 00 00 00 1e 06 30 61 62 61   ......N.....0aba
|   4048: 63 6b 01 02 02 04 02 66 74 00 02 22 04 04 6e 64   ck.....ft.....nd
|   4064: 6f 6e 04 67 90 38 2a 07 05 01 03 00 10 03 03 0f   on.g.8*.........
|   4080: 0a 03 00 24 00 00 00 00 01 01 01 00 01 01 01 01   ...$............
| page 3 offset 8192
|      0: 0a 00 00 00 01 0f fa 00 0f fa 00 00 00 00 00 00   ................
|   4080: 00 00 00 00 00 00 00 00 00 00 05 04 09 0c 01 02   ................
| page 4 offset 12288
|      0: 0d 00 00 00 03 0f e0 00 0f f6 0f ec 0f e0 00 00   ................
|   4064: 0a 03 03 00 1b 61 62 61 6e 64 6f 6e 08 02 03 00   .....abandon....
|   4080: 17 61 62 61 66 74 08 01 03 00 17 61 62 61 63 6b   .abaft.....aback
| page 5 offset 16384
|      0: 0d 00 00 00 03 0f ee 00 0f fa 0f f4 0f ee 00 00   ................
|   4064: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 04 03   ................
|   4080: 03 00 0e 01 04 02 03 00 0e 01 04 01 03 00 0e 01   ................
| page 6 offset 20480
|      0: 0a 00 00 00 01 0f f4 00 0f f4 00 00 00 00 00 00   ................
|   4080: 00 00 00 00 0b 03 1b 01 76 65 72 73 69 6f 6e 04   ........version.
| page 7 offset 24576
|      0: 0d 00 00 00 03 0f d6 00 0f f4 0f e1 0f d6 00 00   ................
|   4048: 00 00 00 00 00 00 09 03 02 1b 72 65 62 75 69 6c   ..........rebuil
|   4064: 64 11 02 02 2b 69 6e 74 65 67 72 69 74 79 2d 63   d...+integrity-c
|   4080: 68 65 63 6b 0a 01 02 1d 6f 70 74 69 6d 69 7a 65   heck....optimize
| page 8 offset 28672
|      0: 03 07 17 19 19 01 81 2d 74 61 62 6c 65 74 31 5f   .......-tablet1_
|     16: 69 64 78 74 31 5f 69 64 78 03 43 52 45 41 54 45   idxt1_idx.CREATE
|     32: 20 54 41 42 4c 45 20 27 74 31 5f 66 17 42 03 30    TABLE 't1_f.B.0
|     48: 01 00 00 10 10 04 02 02 00 00 00 00 00 00 00 00   ................
|     64: 70 00 00 00 00 00 00 00 00 00 00 00 70 00 00 00   p...........p...
| end c16.db
}]} {}

do_catchsql_test 15.1 {
  INSERT INTO t1(t1) VALUES('integrity-check');
} {1 {database disk image is malformed}}

#---------------------------------------------------------------------------
#
reset_db
do_test 16.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
| size 28672 pagesize 4096 filename c17.db
| page 1 offset 0
|      0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00   SQLite format 3.
|     16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 07   .....@  ........
|     32: 00 00 00 00 00 00 00 00 00 00 00 07 00 00 00 00   ................
|     48: 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00   ................
|     96: 00 00 00 00 0d 00 00 00 07 0d d2 00 0f c4 0f 6d   ...............m
|    112: 0f 02 0e ab 0e 4e 0d f6 0d d2 00 00 00 00 00 00   .....N..........
|   3536: 00 00 22 07 06 17 11 11 01 31 74 61 62 6c 65 74   .........1tablet
|   3552: 32 74 32 07 43 52 45 41 54 45 20 54 41 42 4c 45   2t2.CREATE TABLE
|   3568: 20 74 32 28 78 29 56 06 06 17 1f 1f 01 7d 74 61    t2(x)V.......ta
|   3584: 62 6c 65 74 31 5f 63 6f 6e 66 69 67 74 31 5f 63   blet1_configt1_c
|   3600: 6f 6e 66 69 67 06 43 52 45 41 54 45 20 54 41 42   onfig.CREATE TAB
|   3616: 4c 45 20 27 74 31 5f 63 6f 6e 66 69 67 27 28 6b   LE 't1_config'(k
|   3632: 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 76 29    PRIMARY KEY, v)
|   3648: 20 57 49 54 48 4f 55 54 20 52 4f 57 49 44 5b 05    WITHOUT ROWID[.
|   3664: 07 17 21 21 01 81 01 74 61 62 6c 65 74 31 5f 64   ..!!...tablet1_d
|   3680: 6f 63 73 69 7a 65 74 31 5f 64 6f 63 73 69 7a 65   ocsizet1_docsize
|   3696: 05 43 52 45 41 54 45 20 54 41 42 4c 45 20 27 74   .CREATE TABLE 't
|   3712: 31 5f 64 6f 63 73 69 7a 65 27 28 69 64 20 49 4e   1_docsize'(id IN
|   3728: 54 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45   TEGER PRIMARY KE
|   3744: 59 2c 20 73 7a 20 42 4c 4f 42 29 55 04 06 17 21   Y, sz BLOB)U...!
|   3760: 21 01 77 74 61 62 6c 65 74 31 5f 63 6f 6e 74 65   !.wtablet1_conte
|   3776: 6e 74 74 31 5f 63 6f 6e 74 65 6e 74 04 43 52 45   ntt1_content.CRE
|   3792: 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 63 6f   ATE TABLE 't1_co
|   3808: 6e 74 65 6e 74 27 28 69 64 20 49 4e 54 45 47 45   ntent'(id INTEGE
|   3824: 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 63   R PRIMARY KEY, c
|   3840: 30 29 69 03 07 17 19 19 01 81 2d 74 61 62 6c 65   0)i.......-table
|   3856: 74 31 5f 69 64 78 74 31 5f 69 64 78 03 43 52 45   t1_idxt1_idx.CRE
|   3872: 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 69 64   ATE TABLE 't1_id
|   3888: 78 27 28 73 65 67 69 64 2c 20 74 65 72 6d 2c 20   x'(segid, term, 
|   3904: 70 67 6e 6f 2c 20 50 52 49 4d 41 52 59 20 4b 45   pgno, PRIMARY KE
|   3920: 59 28 73 65 67 69 64 2c 20 74 65 72 6d 29 29 20   Y(segid, term)) 
|   3936: 57 49 54 48 4f 55 54 20 52 4f 57 49 44 55 02 07   WITHOUT ROWIDU..
|   3952: 17 1b 1b 01 81 01 74 61 62 6c 65 74 31 5f 64 61   ......tablet1_da
|   3968: 74 61 74 31 5f 64 61 74 61 02 43 52 45 41 54 45   tat1_data.CREATE
|   3984: 20 54 41 42 4c 45 20 27 74 31 5f 64 61 74 61 27    TABLE 't1_data'
|   4000: 28 69 64 20 49 4e 54 45 47 45 52 20 50 52 49 4d   (id INTEGER PRIM
|   4016: 41 52 59 20 4b 45 59 2c 20 62 6c 6f 63 6b 20 42   ARY KEY, block B
|   4032: 4c 4f 42 29 3a 01 06 17 11 11 08 63 74 61 62 6c   LOB):......ctabl
|   4048: 65 74 31 74 31 43 52 45 41 54 45 20 56 49 52 54   et1t1CREATE VIRT
|   4064: 55 41 4c 20 54 41 42 4c 45 20 74 31 20 55 53 49   UAL TABLE t1 USI
|   4080: 4e 47 20 66 74 73 35 28 63 6f 6e 74 65 6e 74 29   NG fts5(content)
| page 2 offset 4096
|      0: 0d 00 00 00 03 0f bd 00 0f e8 0f ef 0f bd 00 00   ................
|   4016: 00 00 00 00 00 00 00 00 00 00 00 00 00 24 84 80   .............$..
|   4032: 80 80 80 01 03 00 4e 00 00 00 1e 06 30 61 62 61   ......N.....0aba
|   4048: 63 6b 01 02 02 04 02 66 74 00 02 22 04 04 6e 64   ck.....ft.....nd
|   4064: 6f 6e 03 02 02 04 0a 07 05 01 03 00 10 03 03 0f   on..............
|   4080: 0a 03 00 24 00 00 00 00 01 01 01 00 01 01 41 01   ...$..........A.
| page 3 offset 8192
|      0: 0a 00 00 00 01 0f fa 00 0f fa 00 00 00 00 00 00   ................
|   4080: 00 00 00 00 00 00 00 00 00 00 05 04 09 0c 01 02   ................
| page 4 offset 12288
|      0: 0d 00 00 00 03 0f e0 00 0f f6 0f ec 0f e0 00 00   ................
|   4064: 0a 03 03 00 1b 61 62 61 6e 64 6f 6e 08 02 03 00   .....abandon....
|   4080: 17 61 62 61 66 74 08 01 03 00 17 61 62 61 63 6b   .abaft.....aback
| page 5 offset 16384
|      0: 0d 00 00 00 03 0f ee 00 0f fa 0f f4 0f ee 00 00   ................
|   4064: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 04 03   ................
|   4080: 03 00 0e 01 04 02 03 00 0e 01 04 01 03 00 0e 01   ................
| page 6 offset 20480
|      0: 0a 00 00 00 01 0f f4 00 0f f4 00 00 00 00 00 00   ................
|   4080: 00 00 00 00 0b 03 1b 01 76 65 72 73 69 6f 6e 04   ........version.
| page 7 offset 24576
|      0: 0d 00 00 00 03 0f d6 00 0f f4 0f e1 0f d6 00 00   ................
|   4048: 00 00 00 00 00 00 09 03 02 1b 72 65 62 75 69 6c   ..........rebuil
|   4064: 64 11 02 02 2b 69 6e 74 65 67 72 69 74 79 2d 63   d...+integrity-c
|   4080: 68 65 63 6b 0a 01 02 1d 6f 70 74 69 6d 69 7a 65   heck....optimize
| end c17.db
}]} {}

do_catchsql_test 16.1 {
INSERT INTO t1(t1) VALUES('integrity-check');
} {1 {vtable constructor failed: t1}}

#--------------------------------------------------------------------------
reset_db
do_test 17.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
| size 28672 pagesize 4096 filename c18.db
| page 1 offset 0
|      0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00   SQLite format 3.
|     16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 07   .....@  ........
|     32: 00 00 00 00 00 00 00 00 00 00 00 07 00 00 00 00   ................
|     48: 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00   ................
|     96: 00 00 00 00 0d 00 00 00 07 0d d2 00 0f c4 0f 6d   ...............m
|    112: 0f 02 0e ab 0e 4e 0d f6 0d d2 00 00 00 00 00 00   .....N..........
|   3536: 00 00 22 07 06 17 11 11 01 31 74 61 62 6c 65 74   .........1tablet
|   3552: 32 74 32 07 43 52 45 41 54 45 20 54 41 42 4c 45   2t2.CREATE TABLE
|   3568: 20 74 32 28 78 29 56 06 06 17 1f 1f 01 7d 74 61    t2(x)V.......ta
|   3584: 62 6c 65 74 31 5f 63 6f 6e 66 69 67 74 31 5f 63   blet1_configt1_c
|   3600: 6f 6e 66 69 67 06 43 52 45 41 54 45 20 54 41 42   onfig.CREATE TAB
|   3616: 4c 45 20 27 74 31 5f 63 6f 6e 66 69 67 27 28 6b   LE 't1_config'(k
|   3632: 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 76 29    PRIMARY KEY, v)
|   3648: 20 57 49 54 48 4f 55 54 20 52 4f 57 49 44 5b 05    WITHOUT ROWID[.
|   3664: 07 17 21 21 01 81 01 74 61 62 6c 65 74 31 5f 64   ..!!...tablet1_d
|   3680: 6f 63 73 69 7a 65 74 31 5f 64 6f 63 73 69 7a 65   ocsizet1_docsize
|   3696: 05 43 52 45 41 54 45 20 54 41 42 4c 45 20 27 74   .CREATE TABLE 't
|   3712: 31 5f 64 6f 63 73 69 7a 65 27 28 69 64 20 49 4e   1_docsize'(id IN
|   3728: 54 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45   TEGER PRIMARY KE
|   3744: 59 2c 20 73 7a 20 42 4c 4f 42 29 55 04 06 17 21   Y, sz BLOB)U...!
|   3760: 21 01 77 74 61 62 6c 65 74 31 5f 63 6f 6e 74 65   !.wtablet1_conte
|   3776: 6e 74 74 31 5f 63 6f 6e 74 65 6e 74 04 43 52 45   ntt1_content.CRE
|   3792: 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 63 6f   ATE TABLE 't1_co
|   3808: 6e 74 65 6e 74 27 28 69 64 20 49 4e 54 45 47 45   ntent'(id INTEGE
|   3824: 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 63   R PRIMARY KEY, c
|   3840: 30 29 69 03 07 17 19 19 01 81 2d 74 61 62 6c 65   0)i.......-table
|   3856: 74 31 5f 69 64 78 74 31 5f 69 64 78 03 43 52 45   t1_idxt1_idx.CRE
|   3872: 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 69 64   ATE TABLE 't1_id
|   3888: 78 27 28 73 65 67 69 64 2c 20 74 65 72 6d 2c 20   x'(segid, term, 
|   3904: 70 67 6e 6f 2c 20 50 52 49 4d 41 52 59 20 4b 45   pgno, PRIMARY KE
|   3920: 59 28 73 65 67 69 64 2c 20 74 65 72 6d 29 29 20   Y(segid, term)) 
|   3936: 57 49 54 48 4f 55 54 20 52 4f 57 49 44 55 02 07   WITHOUT ROWIDU..
|   3952: 17 1b 1b 01 81 01 74 61 62 6c 65 74 31 5f 64 61   ......tablet1_da
|   3968: 74 61 74 31 5f 64 61 74 61 02 43 52 45 41 54 45   tat1_data.CREATE
|   3984: 20 54 41 42 4c 45 20 27 74 31 5f 64 61 74 61 27    TABLE 't1_data'
|   4000: 28 69 64 20 49 4e 54 45 47 45 52 20 50 52 49 4d   (id INTEGER PRIM
|   4016: 41 52 59 20 4b 45 59 2c 20 62 6c 6f 63 6b 20 42   ARY KEY, block B
|   4032: 4c 4f 42 29 3a 01 06 17 11 11 08 63 74 61 62 6c   LOB):......ctabl
|   4048: 65 74 31 74 31 43 52 45 41 54 45 20 56 49 52 54   et1t1CREATE VIRT
|   4064: 55 41 4c 20 54 41 42 4c 45 20 74 31 20 55 53 49   UAL TABLE t1 USI
|   4080: 4e 47 20 66 74 73 35 28 63 6f 6e 74 65 6e 74 29   NG fts5(content)
| page 2 offset 4096
|      0: 0d 00 00 00 03 0f bd 00 0f e8 0f ef 0f bd 00 00   ................
|   4016: 00 00 00 00 00 00 00 00 00 00 00 00 00 24 84 80   .............$..
|   4032: 80 80 80 01 03 00 4e 00 00 00 1e 06 30 61 62 61   ......N.....0aba
|   4048: 63 6b 01 02 02 04 02 66 74 00 02 22 04 04 6e 64   ck.....ft.....nd
|   4064: 6f 6e 03 02 02 04 0a 07 05 01 03 00 10 03 03 0f   on..............
|   4080: 0a 03 00 24 00 00 0a aa aa aa aa aa aa aa aa aa   ...$............
| page 3 offset 8192
|      0: aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa aa   ................
|     16: aa aa aa aa aa aa aa aa 00 00 10 10 10 00 10 10   ................
|     32: 10 10 a0 00 00 00 10 ff a0 00 ff 52 05 64 95 25   ...........R.d.%
|     48: 45 54 14 c2 05 44 14 24 c4 52 07 43 12 05 55 34   ET...D.$.R.C..U4
|     64: 94 e4 72 06 67 47 33 52 86 36 f6 e7 46 56 e7 42   ..r.gG3R.6..FV.B
|     80: 90 d0 00 00 00 30 fb d0 00 fe 80 fe f0 fb 00 00   .....0..........
|   4080: 00 00 00 00 00 00 00 00 00 00 05 04 09 0c 01 02   ................
| page 4 offset 12288
|      0: 0d 00 00 00 03 0f e0 00 0f f6 0f ec 0f e0 00 00   ................
|   4064: 0a 03 03 00 1b 61 62 61 6e 64 6f 6e 08 02 03 00   .....abandon....
|   4080: 17 61 62 61 66 74 08 01 03 00 17 61 62 61 63 6b   .abaft.....aback
| page 5 offset 16384
|      0: 0d 00 00 00 03 0f ee 00 0f fa 0f f4 0f ee 00 00   ................
|   4064: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 04 03   ................
|   4080: 03 00 0e 01 04 02 03 00 0e 01 04 01 03 00 0e 01   ................
| page 6 offset 20480
|      0: 0a 00 00 00 01 0f f4 00 0f f4 00 00 00 00 00 00   ................
|   4080: 00 00 00 00 0b 03 1b 01 76 65 72 73 69 6f 6e 04   ........version.
| page 7 offset 24576
|      0: 0d 00 00 00 03 0f d6 00 0f f4 0f e1 0f d6 00 00   ................
|   4048: 00 00 00 00 00 00 09 03 02 1b 72 65 62 75 69 6c   ..........rebuil
|   4064: 64 11 02 02 2b 69 6e 74 65 67 72 69 74 79 2d 63   d...+integrity-c
|   4080: 68 65 63 6b 0a 01 02 1d 6f 70 74 69 6d 69 7a 65   heck....optimize
| end c18.db
}]} {}

do_catchsql_test 17.1 {
  SELECT * FROM t1 WHERE t1 MATCH 'abandon';
} {1 {vtable constructor failed: t1}}

#--------------------------------------------------------------------------
reset_db
do_test 18.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
| size 28672 pagesize 4096 filename c19b.db
| page 1 offset 0
|      0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00   SQLite format 3.
|     16: 10 00 01 01 00 40 20 20 00 00 00 01 00 00 00 07   .....@  ........
|     32: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00   ................
|     48: 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00   ................
|     80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01   ................
|     96: 00 2e 30 38 0d 00 00 00 07 0d d2 00 0f c4 0f 6d   ..08...........m
|    112: 0f 02 0e ab 0e 4e 0d f6 0d d2 00 00 00 00 00 00   .....N..........
|   3536: 00 00 22 07 06 17 11 11 01 31 74 61 62 6c 65 74   .........1tablet
|   3552: 32 74 32 07 43 52 45 41 54 45 20 54 41 42 4c 45   2t2.CREATE TABLE
|   3568: 20 74 32 28 78 29 56 06 06 17 1f 1f 01 7d 74 61    t2(x)V.......ta
|   3584: 62 6c 65 74 31 5f 63 6f 6e 66 69 67 74 31 5f 63   blet1_configt1_c
|   3600: 6f 6e 66 69 67 06 43 52 45 41 54 45 20 54 41 42   onfig.CREATE TAB
|   3616: 4c 45 20 27 74 31 5f 63 6f 6e 66 69 67 27 28 6b   LE 't1_config'(k
|   3632: 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 76 29    PRIMARY KEY, v)
|   3648: 20 57 49 54 48 4f 55 54 20 52 4f 57 49 44 5b 05    WITHOUT ROWID[.
|   3664: 07 17 21 21 01 81 01 74 61 62 6c 65 74 31 5f 64   ..!!...tablet1_d
|   3680: 6f 63 73 69 7a 65 74 31 5f 64 6f 63 73 69 7a 65   ocsizet1_docsize
|   3696: 05 43 52 45 41 54 45 20 54 41 42 4c 45 20 27 74   .CREATE TABLE 't
|   3712: 31 5f 64 6f 63 73 69 7a 65 27 28 69 64 20 49 4e   1_docsize'(id IN
|   3728: 54 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45   TEGER PRIMARY KE
|   3744: 59 2c 20 73 7a 20 42 4c 4f 42 29 55 04 06 17 21   Y, sz BLOB)U...!
|   3760: 21 01 77 74 61 62 6c 65 74 31 5f 63 6f 6e 74 65   !.wtablet1_conte
|   3776: 6e 74 74 31 5f 63 6f 6e 74 65 6e 74 04 43 52 45   ntt1_content.CRE
|   3792: 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 63 6f   ATE TABLE 't1_co
|   3808: 6e 74 65 6e 74 27 28 69 64 20 49 4e 54 45 47 45   ntent'(id INTEGE
|   3824: 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 63   R PRIMARY KEY, c
|   3840: 30 29 69 03 07 17 19 19 01 81 2d 74 61 62 6c 65   0)i.......-table
|   3856: 74 31 5f 69 64 78 74 31 5f 69 64 78 03 43 52 45   t1_idxt1_idx.CRE
|   3872: 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 69 64   ATE TABLE 't1_id
|   3888: 78 27 28 73 65 67 69 64 2c 20 74 65 72 6d 2c 20   x'(segid, term, 
|   3904: 70 67 6e 6f 2c 20 50 52 49 4d 41 52 59 20 4b 45   pgno, PRIMARY KE
|   3920: 59 28 73 65 67 69 64 2c 20 74 65 72 6d 29 29 20   Y(segid, term)) 
|   3936: 57 49 54 48 4f 55 54 20 52 4f 57 49 44 55 02 07   WITHOUT ROWIDU..
|   3952: 17 1b 1b 01 81 01 74 61 62 6c 65 74 31 5f 64 61   ......tablet1_da
|   3968: 74 61 74 31 5f 64 61 74 61 02 43 52 45 41 54 45   tat1_data.CREATE
|   3984: 20 54 41 42 4c 45 20 27 74 31 5f 64 61 74 61 27    TABLE 't1_data'
|   4000: 28 69 64 20 49 4e 54 45 47 45 52 20 50 52 49 4d   (id INTEGER PRIM
|   4016: 41 52 59 20 4b 45 59 2c 20 62 6c 6f 63 6b 20 42   ARY KEY, block B
|   4032: 4c 4f 42 29 3a 01 06 17 11 11 08 63 74 61 62 6c   LOB):......ctabl
|   4048: 65 74 31 74 31 43 52 45 41 54 45 20 56 49 52 54   et1t1CREATE VIRT
|   4064: 55 41 4c 20 54 41 42 4c 45 20 74 31 20 55 53 49   UAL TABLE t1 USI
|   4080: 4e 47 20 66 74 73 35 28 63 6f 6e 74 65 6e 74 29   NG fts5(content)
| page 2 offset 4096
|      0: 0d 09 a6 00 06 09 22 00 0f e8 09 22 0f bd 0f 2c   ...............,
|     16: 09 bd 09 3c 00 00 00 00 00 00 00 00 00 00 00 00   ...<............
|   2336: 00 00 18 0a 03 00 36 00 00 00 00 01 04 04 00 04   ......6.........
|   2352: 01 01 01 02 01 01 03 01 01 04 01 01 63 90 80 80   ............c...
|   2368: 80 80 01 04 00 81 4a 00 00 00 56 06 30 61 62 61   ......J...V.0aba
|   2384: 63 6b 08 01 04 04 6e 64 6f 6e 03 01 05 01 02 05   ck....ndon......
|   2400: 63 74 69 76 65 08 01 02 04 6c 70 68 61 08 01 02   ctive....lpha...
|   2416: 03 74 6f 6d 08 01 01 06 62 61 63 6b 75 70 08 01   .tom....backup..
|   2432: 01 0c 63 68 61 6e 6e 65 62 6f 6f 6d 65 72 08 01   ..channeboomer..
|   2448: 07 01 6c 08 01 01 04 74 65 73 74 08 01 04 09 0a   ..l....test.....
|   2464: 09 08 07 0a 10 05 0f 18 00 17 30 00 00 00 00 01   ..........0.....
|   2480: 03 03 00 03 01 01 01 02 01 01 03 01 01 8a 53 8c   ..............S.
|   2496: 80 80 80 80 01 04 00 95 2a 00 00 05 35 0d 30 30   ........*...5.00
|   2512: 31 30 66 66 61 30 30 30 66 66 61 05 02 1c 02 49   10ffa000ffa....I
|   2528: 33 34 33 35 32 34 35 34 31 35 34 34 35 32 30 35   3435245415445205
|   2544: 34 34 31 34 32 34 63 34 35 32 30 32 37 37 34 33   441424c452027743
|   2560: 31 35 66 36 39 36 34 37 38 32 37 32 38 37 33 36   15f6964782728736
|   2576: 35 36 37 36 39 36 34 32 63 32 30 37 34 36 35 37   56769642c2074657
|   2592: 32 36 64 32 63 32 30 37 30 05 02 12 02 3b 36 31   26d2c2070....;61
|   2608: 37 32 31 32 31 30 31 37 37 37 34 36 31 36 32 35   7212101777461625
|   2624: 63 36 35 37 34 33 31 35 66 36 33 36 66 36 65 37   c6574315f636f6e7
|   2640: 34 36 35 36 65 37 34 37 34 33 31 35 66 36 33 36   4656e7474315f636
|   2656: 66 36 65 37 34 36 35 36 65 05 04 07 07 01 04 31   f6e74656e......1
|   2672: 66 62 64 05 02 19 01 44 32 34 38 34 38 30 38 30   fbd....D24848080
|   2688: 38 30 38 30 30 31 30 33 30 30 34 65 30 30 30 30   80800103004e0000
|   2704: 30 30 31 65 30 36 33 30 36 31 36 32 36 31 36 33   001e063061626163
|   2720: 36 62 30 31 30 32 30 32 30 34 30 32 36 36 37 34   6b01020204026674
|   2736: 30 32 30 32 30 32 30 34 30 34 36 65 05 02 1a 02   02020204046e....
|   2752: 03 66 65 72 05 02 1d 01 28 33 65 37 34 36 35 36   .fer....(3e74656
|   2768: 65 37 34 32 39 30 64 30 30 30 30 30 30 30 33 30   e74290d000000030
|   2784: 66 62 64 30 30 30 66 65 38 30 66 65 66 30 66 62   fbd000fe80fef0fb
|   2800: 64 05 02 18 01 4a 34 31 35 32 35 39 32 30 34 62   d....J415259204b
|   2816: 34 35 35 39 32 63 32 30 36 32 36 63 36 66 36 33   45592c20626c6f63
|   2832: 36 62 32 30 34 32 34 63 34 66 34 32 32 39 33 61   6b20424c4f42293a
|   2848: 30 31 30 36 31 37 31 31 31 31 30 38 36 33 37 34   0106171111086374
|   2864: 36 31 36 32 36 63 36 35 37 34 33 31 37 34 33 31   61626c6574317431
|   2880: 05 02 16 02 49 33 35 32 34 35 34 31 35 34 34 35   ....I35245415445
|   2896: 32 30 35 36 34 39 35 32 35 34 35 35 34 31 34 63   205649525455414c
|   2912: 32 30 35 34 34 31 34 32 34 63 34 35 32 30 37 34   205441424c452074
|   2928: 33 31 6f 30 35 35 35 33 34 39 34 65 34 37 32 30   31o05553494e4720
|   2944: 36 36 37 34 37 33 33 35 32 38 36 33 36 66 05 02   6674733528636f..
|   2960: 17 02 49 35 32 30 35 34 34 31 34 32 34 63 34 35   ..I5205441424c45
|   2976: 32 30 32 37 37 34 33 31 35 66 36 33 36 66 36 65   202774315f636f6e
|   2992: 37 34 36 35 36 65 37 34 32 37 32 38 36 39 36 34   74656e7427286964
|   3008: 32 30 34 39 34 65 35 34 34 35 34 37 34 35 35 32   20494e5445474552
|   3024: 32 30 35 30 35 32 34 39 34 64 34 31 05 02 0e 44   205052494d41...D
|   3040: 29 62 30 35 30 37 31 37 32 31 32 31 30 31 38 31   )b05071721210181
|   3056: 30 31 37 34 36 31 36 32 36 63 36 35 37 34 33 31   017461626c657431
|   3072: 35 66 36 34 36 66 36 33 37 33 05 02 09 01 4a 35   5f646f6373....J5
|   3088: 32 34 35 34 31 35 34 34 35 32 30 35 34 34 31 34   2454154452054414
|   3104: 32 34 63 34 35 32 30 32 37 37 34 33 31 35 66 36   24c45202774315f6
|   3120: 34 36 31 37 34 36 31 32 37 32 38 36 39 36 34 32   4617461272869642
|   3136: 30 34 39 34 65 35 34 34 35 34 37 34 35 35 32 32   0494e54454745522
|   3152: 30 35 30 35 32 34 39 34 64 05 02 15 03 3a 35 39   05052494d....:59
|   3168: 32 30 34 62 34 35 35 39 32 63 32 30 36 33 33 30   204b45592c206330
|   3184: 32 39 36 39 30 33 30 37 31 37 31 39 31 39 30 31   2969030717191901
|   3200: 38 31 32 64 37 34 36 31 36 32 36 63 36 35 37 34   812d7461626c6574
|   3216: 33 31 35 66 36 39 79 79 05 02 0f 02 49 34 32 30   315f69yy....I420
|   3232: 35 32 34 66 35 37 34 39 34 34 35 35 30 32 30 37   524f574944550207
|   3248: 31 37 31 62 31 62 30 31 38 31 30 31 37 34 36 31   171b1b0181017461
|   3264: 36 32 36 63 36 37 37 34 33 31 35 66 36 34 36 31   626c6774315f6461
|   3280: 37 34 36 31 37 34 33 31 35 66 36 34 36 31 37 34   746174315f646174
|   3296: 36 31 30 32 34 33 05 02 14 02 07 66 36 39 36 34   610243.....f6964
|   3312: 37 38 05 02 11 01 4a 36 34 36 66 36 65 30 33 30   78....J646f6e030
|   3328: 32 30 32 30 34 30 61 30 37 30 35 30 31 30 33 30   202040a070501030
|   3344: 30 31 30 30 33 30 33 30 66 30 61 30 33 30 30 32   01003030f0a03002
|   3360: 34 30 30 30 30 30 30 30 30 30 31 30 31 30 31 30   4000000000101010
|   3376: 30 30 31 30 31 30 31 30 31 30 61 30 30 30 30 30   0010101010a00000
|   3392: 30 05 02 1b 02 49 35 32 37 32 38 36 39 36 34 32   0....I5272869642
|   3408: 30 34 39 34 65 35 34 34 35 34 37 34 35 35 32 32   0494e54454745522
|   3424: 30 35 30 35 32 34 39 34 64 34 31 35 32 35 39 32   05052494d4152592
|   3440: 30 34 62 34 35 35 39 32 63 32 30 37 33 37 61 32   04b45592c20737a2
|   3456: 30 34 32 34 63 34 66 34 32 32 39 35 35 30 34 05   0424c4f42295504.
|   3472: 04 06 07 02 49 37 36 65 36 66 32 63 32 30 35 30   ....I76e6f2c2050
|   3488: 35 32 34 39 34 64 34 31 35 32 35 39 32 30 34 62   52494d415259204b
|   3504: 34 35 35 39 32 38 37 33 36 35 36 37 36 39 36 34   4559287365676964
|   3520: 32 63 32 30 37 34 36 35 37 32 36 64 32 39 32 39   2c207465726d2929
|   3536: 32 30 35 37 34 39 35 34 34 38 34 66 35 35 05 02   20574954484f55..
|   3552: 13 02 49 39 37 61 36 35 37 34 33 31 35 66 36 34   ..I97a6574315f64
|   3568: 36 66 36 33 37 33 36 39 37 61 36 35 30 35 34 33   6f6373697a650543
|   3584: 35 32 34 35 34 31 35 34 34 35 32 30 35 34 34 31   5245415445205441
|   3600: 34 32 34 63 34 35 32 30 32 37 37 34 33 31 35 66   424c45202774315f
|   3616: 36 34 36 66 36 33 37 33 36 39 37 61 05 04 05 07   646f6373697a....
|   3632: 01 0e 37 34 30 34 34 33 35 32 34 35 34 31 35 34   ..74044352454154
|   3648: 05 04 08 07 02 49 36 32 39 32 30 35 37 34 39 35   .....I6292057495
|   3664: 34 34 38 34 66 35 35 35 34 32 30 35 32 34 66 35   4484f555420524f5
|   3680: 37 34 39 34 34 35 62 30 35 30 37 31 37 32 31 32   749445b050717212
|   3696: 31 30 31 38 31 30 31 37 34 36 31 36 32 36 63 36   10181017461626c6
|   3712: 35 37 34 33 31 35 66 36 34 36 66 36 33 37 33 05   574315f646f6373.
|   3728: 02 04 01 06 62 61 63 6b 75 70 05 02 1e 02 05 65   ....backup.....e
|   3744: 61 6d 65 72 05 02 02 02 05 6f 6f 6d 65 72 05 01   amer.....oomer..
|   3760: 02 40 75 6d 6d 32 34 63 34 35 32 30 32 37 37 34   .@umm24c45202774
|   3776: 33 31 35 66 36 33 36 66 36 65 36 36 36 39 36 37   315f636f6e666967
|   3792: 32 37 32 38 36 62 32 30 35 30 35 32 34 39 34 64   27286b205052494d
|   3808: 34 31 35 32 35 39 32 30 34 62 34 35 35 39 32 63   415259204b45592c
|   3824: 32 30 05 02 03 01 04 79 65 6b 72 05 02 10 04 11   20.....yekr.....
|   3840: 4e 41 09 49 08 2d 4f 4e 4e 2e 4f 3f 4e 0c 4f 4f   NA.I.-ONN.O?N.OO
|   3856: 4e 4f 14 4e 0b 0a 09 45 0f ef 00 14 2a 00 00 00   NO.N...E....*...
|   3872: 00 01 02 02 00 02 01 01 01 02 01 01 81 09 88 80   ................
|   3888: 80 80 80 01 04 00 82 16 00 00 00 79 06 30 61 62   ...........y.0ab
|   3904: 61 63 6b 08 02 07 04 04 6e 64 6f 6e 08 02 05 02   ack.....ndon....
|   3920: 05 63 74 69 76 65 04 02 02 04 02 0b 02 04 6c 70   .ctive........lp
|   3936: 68 61 08 04 02 0a 02 03 74 6b 6d 06 02 02 03 02   ha......tkm.....
|   3952: 6f 6d 08 02 09 05 02 69 63 07 02 02 01 06 62 61   om.....ic.....ba
|   3968: 63 6b 75 70 08 02 04 02 05 6f 6f 6d 65 72 05 02   ckup.....oomer..
|   3984: 02 01 0c 63 68 61 6e 6e 65 62 6f 6f 6d 65 72 08   ...channeboomer.
|   4000: 02 08 07 01 6c 08 02 03 01 04 74 65 73 74 08 02   ....l.....test..
|   4016: 06 04 0a 09 0d 0a 08 07 07 0b 0a 11 06 24 84 80   .............$..
|   4032: 80 80 80 01 03 00 4e 00 00 00 1e 06 30 61 62 61   ......N.....0aba
|   4048: 63 6b 01 08 02 04 02 66 74 00 02 22 04 04 6e 64   ck.....ft.....nd
|   4064: 6f 6e 03 02 02 04 0a 07 05 01 03 00 10 06 22 00   on..............
|   4080: 00 00 11 24 00 00 00 00 01 01 01 00 01 01 01 01   ...$............
| page 3 offset 8192
|      0: 0a 00 00 00 04 0f e5 00 0f fa 0f f3 0f ec 0f e5   ................
|   4064: 00 00 00 00 00 06 04 01 0c 01 04 02 06 04 01 0c   ................
|   4080: 01 03 02 06 04 01 0c 01 02 02 05 04 09 0c 01 02   ................
| page 4 offset 12288
|      0: 0d 0f 68 00 06 08 98 00 0f f6 0f ec 0f d5 08 98   ..h.............
|     16: 0f c1 0f b6 0f 68 0f 68 00 00 00 00 00 00 00 00   .....h.h........
|   2192: 00 00 00 00 00 00 00 00 8d 4d 05 04 00 9b 1f 62   .........M.....b
|   2208: 65 61 6d 65 72 20 62 75 6d 6d 32 34 63 34 35 32   eamer bumm24c452
|   2224: 30 32 37 37 34 33 31 35 66 36 33 36 66 36 65 36   02774315f636f6e6
|   2240: 36 36 39 36 37 32 37 32 38 36 62 32 30 35 30 35   6696727286b20505
|   2256: 32 34 39 34 64 34 31 35 32 35 39 32 30 34 62 34   2494d415259204b4
|   2272: 35 35 39 32 63 32 30 0a 37 36 32 39 32 30 35 37   5592c20.76292057
|   2288: 34 39 35 34 34 38 34 66 35 35 35 34 32 30 35 32   4954484f55542052
|   2304: 34 66 35 37 34 39 34 34 35 62 30 35 30 37 31 37   4f5749445b050717
|   2320: 32 31 32 31 30 31 38 31 30 31 37 34 36 31 36 32   2121018101746162
|   2336: 36 63 36 35 37 34 33 31 35 66 36 34 36 66 36 33   6c6574315f646f63
|   2352: 37 33 0a 36 39 37 61 36 35 37 34 33 31 35 66 36   73.697a6574315f6
|   2368: 34 36 66 36 33 37 33 36 39 37 61 36 35 30 35 34   46f6373697a65054
|   2384: 33 35 32 34 35 34 31 35 34 34 35 32 30 35 34 34   3524541544520544
|   2400: 31 34 32 34 63 34 35 32 30 32 37 37 34 33 31 35   1424c45202774315
|   2416: 66 36 34 36 66 36 33 37 33 36 39 37 61 0a 36 35   f646f6373697a.65
|   2432: 32 37 32 38 36 39 36 34 32 30 34 39 34 65 35 34   2728696420494e54
|   2448: 34 35 34 37 34 35 35 32 32 30 35 30 35 32 34 39   4547455220505249
|   2464: 34 64 34 31 35 32 35 39 32 30 34 62 34 35 35 39   4d415259204b4559
|   2480: 32 63 32 30 37 33 37 61 32 30 34 32 34 63 34 66   2c20737a20424c4f
|   2496: 34 32 32 39 35 35 30 34 0a 30 36 31 37 32 31 32   42295504.0617212
|   2512: 31 30 31 37 37 37 34 36 31 36 32 35 63 36 35 37   101777461625c657
|   2528: 34 33 31 35 66 36 33 36 66 36 65 37 34 36 35 36   4315f636f6e74656
|   2544: 65 37 34 37 34 33 31 35 66 36 33 36 66 36 65 37   e7474315f636f6e7
|   2560: 34 36 35 36 65 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b   4656e...........
|   2576: 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b   ................
|   2592: 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b   ................
|   2608: 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b   ................
|   2624: 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b   ................
|   2640: 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b   ................
|   2656: 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 37 34 30   .............740
|   2672: 34 34 33 35 32 34 35 34 31 35 34 0a 34 35 32 30   44352454154.4520
|   2688: 35 34 34 31 34 32 34 63 34 35 32 30 32 37 37 34   5441424c45202774
|   2704: 33 31 35 66 36 33 36 66 36 65 37 34 36 35 36 65   315f636f6e74656e
|   2720: 37 34 32 37 32 38 36 39 36 34 32 30 34 39 34 65   742728696420494e
|   2736: 35 34 34 35 34 37 34 35 35 32 32 30 35 30 35 62   544547455220505b
|   2752: 30 35 30 37 31 37 32 31 32 31 30 31 38 31 30 31   0507172121018101
|   2768: 37 34 36 31 36 32 36 63 36 35 37 34 33 31 35 66   7461626c6574315f
|   2784: 36 34 36 66 36 33 37 33 0a 36 39 37 61 36 35 37   646f6373.697a657
|   2800: 34 33 31 35 66 36 34 36 66 36 33 37 33 36 39 37   4315f646f6373697
|   2816: 61 36 35 30 35 34 33 35 32 34 35 34 31 35 34 34   a650543524541544
|   2832: 35 32 30 35 34 34 31 34 32 34 63 34 35 32 30 32   5205441424c45202
|   2848: 37 37 34 33 31 35 66 36 34 36 66 36 33 37 33 36   774315f646f63736
|   2864: 39 37 61 0a 36 35 32 37 32 38 36 39 36 34 32 30   97a.652728696420
|   2880: 34 39 34 65 35 34 34 35 34 37 34 35 35 32 32 30   494e544547455220
|   2896: 35 30 35 32 34 39 34 64 34 31 35 32 35 39 32 30   5052494d41525920
|   2912: 34 62 34 35 35 39 32 63 32 30 37 33 37 61 32 30   4b45592c20737a20
|   2928: 34 32 34 63 34 66 34 32 32 39 35 35 30 34 0a 30   424c4f42295504.0
|   2944: 36 31 37 32 31 32 31 30 31 37 37 37 34 36 31 36   6172121017774616
|   2960: 32 35 63 36 35 37 34 33 31 35 66 36 33 36 66 36   25c6574315f636f6
|   2976: 65 37 34 36 35 36 65 37 34 37 34 33 31 35 66 36   e74656e7474315f6
|   2992: 33 36 66 36 65 37 34 36 35 36 65 0b 0b 0b 0b 0b   36f6e74656e.....
|   3008: 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b   ................
|   3024: 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b   ................
|   3040: 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b   ................
|   3056: 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b   ................
|   3072: 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b   ................
|   3088: 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b 0b   ................
|   3104: 0b 0b 0b 37 34 30 34 34 33 35 32 34 35 34 31 35   ...7404435245415
|   3120: 34 0a 34 35 32 30 35 34 34 31 34 32 34 63 34 35   4.45205441424c45
|   3136: 32 30 32 37 37 34 33 31 35 66 36 33 36 66 36 65   202774315f636f6e
|   3152: 37 34 36 35 36 65 37 34 32 37 32 38 36 39 36 34   74656e7427286964
|   3168: 32 30 34 39 34 65 35 34 34 35 34 37 34 35 35 32   20494e5445474552
|   3184: 32 30 35 30 35 32 34 39 34 64 34 31 0a 35 32 35   205052494d41.525
|   3200: 39 32 30 34 62 34 35 35 39 32 63 32 30 36 33 33   9204b45592c20633
|   3216: 30 32 39 36 39 30 33 30 37 31 37 31 39 31 39 30   0296903071719190
|   3232: 31 38 31 32 64 37 34 36 31 36 32 36 63 36 35 37   1812d7461626c657
|   3248: 34 33 31 35 66 36 39 c3 bf c3 bf 7e c3 bf c3 89   4315f69....~....
|   3264: 4b 52 c2 81 35 66 36 39 36 34 37 38 0a 30 33 34   KR..5f696478.034
|   3280: 33 35 32 34 35 34 31 35 34 34 35 32 30 35 34 34   3524541544520544
|   3296: 31 34 32 34 63 34 35 32 30 32 37 37 34 33 31 35   1424c45202774315
|   3312: 66 36 39 36 34 37 38 32 37 32 38 37 33 36 35 36   f696478272873656
|   3328: 37 36 39 36 34 32 63 32 30 37 34 36 35 37 32 36   769642c207465726
|   3344: 64 32 63 32 30 37 30 0a 36 37 36 65 36 66 32 63   d2c2070.676e6f2c
|   3360: 32 30 35 30 35 32 34 39 34 64 34 31 35 32 35 39   205052494d415259
|   3376: 32 30 34 62 34 35 35 39 32 38 37 33 36 35 36 37   204b455928736567
|   3392: 36 39 36 34 32 63 32 30 37 34 36 35 37 32 36 64   69642c207465726d
|   3408: 32 39 32 39 32 30 35 37 34 39 35 34 34 38 34 66   292920574954484f
|   3424: 35 35 0a 35 34 32 30 35 32 34 66 35 37 34 39 34   55.5420524f57494
|   3440: 34 35 35 30 32 30 37 31 37 31 62 31 62 30 31 38   4550207171b1b018
|   3456: 31 30 31 37 34 36 31 36 32 36 63 36 37 37 34 33   1017461626c67743
|   3472: 31 35 66 36 34 36 31 37 34 36 31 37 34 33 31 35   15f6461746174315
|   3488: 66 36 34 36 31 37 34 36 31 30 32 34 33 0a 35 32   f646174610243.52
|   3504: 34 35 34 31 35 34 34 35 32 30 35 34 34 31 34 32   4541544520544142
|   3520: 34 63 34 35 32 30 32 37 37 34 33 31 35 66 36 34   4c45202774315f64
|   3536: 36 31 37 34 36 31 32 37 32 38 36 39 36 34 32 30   6174612728696420
|   3552: 34 39 34 65 35 34 34 35 34 37 34 35 35 32 32 30   494e544547455220
|   3568: 35 30 35 32 34 39 34 64 0a 34 31 35 32 35 39 32   5052494d.4152592
|   3584: 30 34 62 34 35 35 39 32 63 32 30 36 32 36 63 36   04b45592c20626c6
|   3600: 66 36 33 36 62 32 30 34 32 34 63 34 66 34 32 32   f636b20424c4f422
|   3616: 39 33 61 30 31 30 36 31 37 31 31 31 31 30 38 36   93a0106171111086
|   3632: 33 37 34 36 31 36 32 36 63 36 35 37 34 33 31 37   37461626c6574317
|   3648: 34 33 31 0a 34 33 35 32 34 35 34 31 35 34 34 35   431.435245415445
|   3664: 32 30 35 36 34 39 35 32 35 34 35 35 34 31 34 63   205649525455414c
|   3680: 32 30 35 34 34 31 34 32 34 63 34 35 32 30 37 34   205441424c452074
|   3696: 33 31 c3 94 30 35 35 35 33 34 39 34 65 34 37 32   31..05553494e472
|   3712: 30 36 36 37 34 37 33 33 35 32 38 36 33 36 66 0a   06674733528636f.
|   3728: 33 65 37 34 36 35 36 65 37 34 32 39 30 64 30 30   3e74656e74290d00
|   3744: 30 30 30 30 30 33 30 66 62 64 30 30 30 66 65 38   0000030fbd000fe8
|   3760: 30 66 65 66 30 66 62 64 0a 5b 31 66 62 64 5d 32   0fef0fbd.[1fbd]2
|   3776: 34 38 34 38 30 38 30 38 30 38 30 30 31 30 33 30   4848080808001030
|   3792: 30 34 65 30 30 30 30 30 30 31 65 30 36 33 30 36   04e0000001e06306
|   3808: 31 36 32 36 31 36 33 36 62 30 31 30 32 30 32 30   16261636b0102020
|   3824: 34 30 32 36 36 37 34 30 32 30 32 30 32 30 34 30   4026674020202040
|   3840: 34 36 65 0a 36 34 36 66 36 65 30 33 30 32 30 32   46e.646f6e030202
|   3856: 30 34 30 61 30 37 30 35 30 31 30 33 30 30 31 30   040a070501030010
|   3872: 30 33 30 33 30 66 30 61 30 33 30 30 32 34 30 30   03030f0a03002400
|   3888: 30 30 30 30 30 30 30 31 30 31 30 31 30 30 30 31   0000000101010001
|   3904: 30 31 30 31 30 31 30 61 30 30 30 30 30 30 0a 30   0101010a000000.0
|   3920: 31 30 66 66 61 30 30 30 66 66 61 0a 5b 32 66 65   10ffa000ffa.[2fe
|   3936: 72 20 62 61 63 6b 75 70 0f ca 00 4e 81 1d 61 6c   r backup...N..al
|   3952: 70 68 61 20 63 68 61 6e 6e 65 6c 20 c2 af 62 61   pha channel ..ba
|   3968: 63 6b 75 70 20 61 62 61 6e 64 6f 6e 20 74 65 73   ckup abandon tes
|   3984: 74 20 61 62 61 63 6b 20 63 68 61 6e 6e 65 62 6f   t aback channebo
|   4000: 6f 6d 65 72 20 61 74 6f 6d 20 61 6c 70 68 61 20   omer atom alpha 
|   4016: 61 63 74 69 76 65 09 07 03 00 19 61 74 6f 6d 69   active.....atomi
|   4032: 63 07 06 03 00 15 61 74 6b 6d 0f e0 00 0b 19 62   c.....atkm.....b
|   4048: 6f 6f 6d 65 72 09 04 03 00 19 61 63 74 69 76 65   oomer.....active
|   4064: 00 00 00 0c 1b 61 62 61 6e 64 6f 6e 08 02 03 00   .....abandon....
|   4080: 17 61 66 21 66 74 08 01 03 00 17 61 62 61 63 6b   .af!ft.....aback
| page 5 offset 16384
|      0: 0d 0f ee 00 06 0f d6 00 0f fa 0f f4 0f e8 0f e2   ................
|     16: 0f dc 0f d6 0f d0 0f d0 00 00 00 00 00 00 00 00   ................
|   4048: 0f ee 00 06 0e 0a 04 07 03 00 0e 01 04 06 03 00   ................
|   4064: 0e 01 04 05 03 00 0e 1d 04 04 03 00 0e 01 00 00   ................
|   4080: 00 06 0e 01 04 02 03 00 0e 01 04 01 03 00 0e 01   ................
| page 6 offset 20480
|      0: 0a 00 00 00 01 0f f4 00 0f f4 00 00 00 00 00 00   ................
|   4080: 00 00 00 00 0b 03 1b 01 76 65 72 73 69 6f 6e 04   ........version.
| page 7 offset 24576
|      0: 0d 00 00 00 03 0f d6 00 0f f4 0f e1 0f d6 00 00   ................
|   4048: 00 00 00 00 00 00 09 03 02 1b 72 65 62 75 69 6c   ..........rebuil
|   4064: 64 11 02 02 2b 69 6e 74 65 67 72 69 74 79 2d 63   d...+integrity-c
|   4080: 68 65 63 6b 0a 01 02 1d 6f 70 74 69 6d 69 7a 65   heck....optimize
| end c19b.db
}]} {}

do_catchsql_test 18.1 {
  INSERT INTO t1(t1) VALUES('optimize');
} {1 {database disk image is malformed}}

#--------------------------------------------------------------------------
reset_db
do_test 19.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
| size 28672 pagesize 4096 filename c20b.db
| page 1 offset 0
|      0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00   SQLite format 3.
|     16: 10 00 01 01 00 40 20 20 00 00 00 01 00 00 00 07   .....@  ........
|     32: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00   ................
|     48: 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00   ................
|     80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01   ................
|     96: 00 2e 30 38 0d 00 00 00 07 0d d2 00 0f c4 0f 6d   ..08...........m
|    112: 0f 02 0e ab 0e 4e 0d f6 0d d2 00 00 00 00 00 00   .....N..........
|   3536: 00 00 22 07 06 17 11 11 01 31 74 61 62 6c 65 74   .........1tablet
|   3552: 32 74 32 07 43 52 45 41 54 45 20 54 41 42 4c 45   2t2.CREATE TABLE
|   3568: 20 74 32 28 78 29 56 06 06 17 1f 1f 01 7d 74 61    t2(x)V.......ta
|   3584: 62 6c 65 74 31 5f 63 6f 6e 66 69 67 74 31 5f 63   blet1_configt1_c
|   3600: 6f 6e 66 69 67 06 43 52 45 41 54 45 20 54 41 42   onfig.CREATE TAB
|   3616: 4c 45 20 27 74 31 5f 63 6f 6e 66 69 67 27 28 6b   LE 't1_config'(k
|   3632: 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 76 29    PRIMARY KEY, v)
|   3648: 20 57 49 54 48 4f 55 54 20 52 4f 57 49 44 5b 05    WITHOUT ROWID[.
|   3664: 07 17 21 21 01 81 01 74 61 62 6c 65 74 31 5f 64   ..!!...tablet1_d
|   3680: 6f 63 73 69 7a 65 74 31 5f 64 6f 63 73 69 7a 65   ocsizet1_docsize
|   3696: 05 43 52 45 41 54 45 20 54 41 42 4c 45 20 27 74   .CREATE TABLE 't
|   3712: 31 5f 64 6f 63 73 69 7a 65 27 28 69 64 20 49 4e   1_docsize'(id IN
|   3728: 54 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45   TEGER PRIMARY KE
|   3744: 59 2c 20 73 7a 20 42 4c 4f 42 29 55 04 06 17 21   Y, sz BLOB)U...!
|   3760: 21 01 77 74 61 62 6c 65 74 31 5f 63 6f 6e 74 65   !.wtablet1_conte
|   3776: 6e 74 74 31 5f 63 6f 6e 74 65 6e 74 04 43 52 45   ntt1_content.CRE
|   3792: 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 63 6f   ATE TABLE 't1_co
|   3808: 6e 74 65 6e 74 27 28 69 64 20 49 4e 54 45 47 45   ntent'(id INTEGE
|   3824: 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 63   R PRIMARY KEY, c
|   3840: 30 29 69 03 07 17 19 19 01 81 2d 74 61 62 6c 65   0)i.......-table
|   3856: 74 31 5f 69 64 78 74 31 5f 69 64 78 03 43 52 45   t1_idxt1_idx.CRE
|   3872: 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 69 64   ATE TABLE 't1_id
|   3888: 78 27 28 73 65 67 69 64 2c 20 74 65 72 6d 2c 20   x'(segid, term, 
|   3904: 70 67 6e 6f 2c 20 50 52 49 4d 41 52 59 20 4b 45   pgno, PRIMARY KE
|   3920: 59 28 73 65 67 69 64 2c 20 74 65 72 6d 29 29 20   Y(segid, term)) 
|   3936: 57 49 54 48 4f 55 54 20 52 4f 57 49 44 55 02 07   WITHOUT ROWIDU..
|   3952: 17 1b 1b 01 81 01 74 61 62 6c 65 74 31 5f 64 61   ......tablet1_da
|   3968: 74 61 74 31 5f 64 61 74 61 02 43 52 45 41 54 45   tat1_data.CREATE
|   3984: 20 54 41 42 4c 45 20 27 74 31 5f 64 61 74 61 27    TABLE 't1_data'
|   4000: 28 69 64 20 49 4e 54 45 47 45 52 20 50 52 49 4d   (id INTEGER PRIM
|   4016: 41 52 59 20 4b 45 59 2c 20 62 6c 6f 63 6b 20 42   ARY KEY, block B
|   4032: 4c 4f 42 29 3a 01 06 17 11 11 08 63 74 61 62 6c   LOB):......ctabl
|   4048: 65 74 31 74 31 43 52 45 41 54 45 20 56 49 52 54   et1t1CREATE VIRT
|   4064: 55 41 4c 20 54 41 42 4c 45 20 74 31 20 55 53 49   UAL TABLE t1 USI
|   4080: 4e 47 20 66 74 73 35 28 63 6f 6e 74 65 6e 74 29   NG fts5(content)
| page 2 offset 4096
|      0: 0d 0f 20 00 05 0e a0 00 0f e8 0e a0 0f bd 0f 34   .. ............4
|     16: 0e b7 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
|   3744: 15 0a 03 00 30 00 00 00 00 01 03 03 00 03 01 01   ....0...........
|   3760: 01 02 01 01 03 01 01 62 8c 80 80 80 80 01 04 00   .......b........
|   3776: 81 48 00 00 00 55 06 30 61 62 61 63 6b 08 01 04   .H...U.0aback...
|   3792: 04 6e 64 6f 6e 03 01 05 01 02 05 63 74 69 76 65   .ndon......ctive
|   3808: 08 01 02 04 6c 70 68 61 08 01 02 03 74 6f 6d 08   ....lpha....tom.
|   3824: 01 01 06 62 61 63 6b 75 70 08 01 02 05 6f 6f 6d   ...backup....oom
|   3840: 65 72 08 01 01 07 63 68 61 6e 6e 65 6c 08 01 01   er....channel...
|   3856: 04 74 65 73 74 08 01 04 09 0a 09 08 07 0a 09 0b   .test...........
|   3872: 0f ef 00 14 2a 00 00 00 00 01 02 02 00 02 01 01   ....*...........
|   3888: 01 02 01 01 81 01 88 80 80 80 80 01 04 00 82 06   ................
|   3904: 00 00 00 72 06 30 61 62 61 63 6b 08 02 07 04 04   ...r.0aback.....
|   3920: 6e 64 6f 6e 08 02 05 02 05 63 74 69 76 65 04 02   ndon.....ctive..
|   3936: 02 04 02 0b 02 04 6c 70 68 61 08 04 02 0a 02 03   ......lpha......
|   3952: 74 6f 6d 06 02 02 02 02 09 05 02 69 63 07 02 02   tom........ic...
|   3968: 01 06 62 61 63 6b 75 70 08 02 04 02 05 6f 6f 66   ..backup.....oof
|   3984: 65 72 05 02 02 04 03 6d 65 72 08 02 08 01 07 63   er.....mer.....c
|   4000: 68 61 6e 6e 65 6c 08 02 03 01 04 74 65 73 74 08   hannel.....test.
|   4016: 02 06 04 0a 09 0d 0a 0b 07 0b 0a 08 0c 24 84 80   .............$..
|   4032: 80 80 80 01 03 00 4e 00 00 00 1e 06 30 61 62 61   ......N.....0aba
|   4048: 63 6b 01 02 66 04 00 22 74 00 02 22 04 04 6e 64   ck..f...t.....nd
|   4064: 6f 6e 03 02 02 04 0a 07 05 01 03 00 10 06 06 00   on..............
|   4080: 00 00 11 24 00 00 00 00 01 01 01 00 01 01 01 01   ...$............
| page 3 offset 8192
|      0: 0a 00 00 00 03 0f ec 00 0f fa 0f f3 0f ec 00 00   ................
|   4064: 00 00 00 00 00 00 00 00 00 00 00 00 06 04 01 0c   ................
|   4080: 01 03 02 06 04 01 0c 01 02 02 05 04 09 0c 01 02   ................
| page 4 offset 12288
|      0: 0d 0f e0 00 06 0f b6 00 0f f6 0f ec 0f d5 0f ca   ................
|     16: 0f c1 0f b6 0f 70 0f 70 00 00 00 00 00 00 00 00   .....p.p........
|   3952: 0f e0 00 46 81 0d 61 6c 70 68 61 20 63 68 61 6e   ...F..alpha chan
|   3968: 6e 65 6c 20 62 61 63 6b 75 70 20 61 62 61 6e 64   nel backup aband
|   3984: 6f 6e 20 74 65 73 74 20 61 62 61 63 6b 20 62 6f   on test aback bo
|   4000: 6f 6d 65 72 20 61 74 6f 6d 20 61 6c 70 68 61 20   omer atom alpha 
|   4016: 61 63 74 69 76 65 09 07 03 00 19 61 74 6f 6d 69   active.....atomi
|   4032: 63 07 06 03 00 15 61 74 6f 6d 09 05 03 00 19 62   c.....atom.....b
|   4048: 6f 6f 66 65 72 09 04 03 00 19 61 63 74 69 76 65   oofer.....active
|   4064: 00 00 00 0c 1b 61 62 61 6e 64 6f 6e 08 02 03 00   .....abandon....
|   4080: 17 61 62 61 66 74 08 01 03 00 17 61 62 61 63 6b   .abaft.....aback
| page 5 offset 16384
|      0: 0d 0f ee 00 06 0f d6 00 0f fa 0f f4 0f e8 0f e2   ................
|     16: 0f dc 0f d6 0f d0 0f d0 00 00 00 00 00 00 00 00   ................
|   4048: 0f ee 00 06 0e 0a 04 07 03 00 0e 01 04 06 03 00   ................
|   4064: 0e 01 04 05 03 00 0e 01 04 04 03 00 0e 01 00 00   ................
|   4080: 00 06 0e 01 04 02 03 00 0e 01 04 01 03 00 0e 01   ................
| page 6 offset 20480
|      0: 0a 00 00 00 01 0f f4 00 0f f4 00 00 00 00 00 00   ................
|   4080: 00 00 00 00 0b 03 1b 01 76 65 72 73 69 6f 6e 04   ........version.
| page 7 offset 24576
|      0: 0d 00 00 00 03 0f d6 00 0f f4 0f e1 0f d6 00 00   ................
|   4048: 00 00 00 00 00 00 09 03 02 1b 72 65 62 75 69 6c   ..........rebuil
|   4064: 64 11 02 02 2b 69 6e 74 65 67 72 69 74 79 2d 63   d...+integrity-c
|   4080: 86 65 63 6b 0a 01 02 1d 6f 70 74 69 6d 69 7a 65   .eck....optimize
| end c20b.db
}]} {}

do_catchsql_test 19.1 {
  INSERT INTO t1(t1) VALUES('optimize');
} {1 {database disk image is malformed}}

#--------------------------------------------------------------------------
reset_db
do_test 20.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
| size 28672 pagesize 4096 filename crash-cf347c523f793c.db
| page 1 offset 0
|      0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00   SQLite format 3.
|     16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 07   .....@  ........
|     32: 00 00 00 00 00 00 00 00 00 00 00 07 00 00 00 00   ................
|     48: 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00   ................
|     96: 00 00 00 00 0d 00 00 00 07 0d d2 00 0f c4 0f 6d   ...............m
|    112: 0f 02 0e ab 0e 4e 0d f6 0d d2 00 00 00 00 00 00   .....N..........
|   3536: 00 00 22 07 06 17 11 11 01 31 74 61 62 6c 65 74   .........1tablet
|   3552: 32 74 32 07 43 52 45 41 54 45 20 54 41 42 4c 45   2t2.CREATE TABLE
|   3568: 20 74 32 28 78 29 56 06 06 17 1f 1f 01 7d 74 61    t2(x)V.......ta
|   3584: 62 6c 65 74 31 5f 63 6f 6e 66 69 67 74 31 5f 63   blet1_configt1_c
|   3600: 6f 6e 66 69 67 06 43 52 45 41 54 45 20 54 41 42   onfig.CREATE TAB
|   3616: 4c 45 20 27 74 31 5f 63 6f 6e 66 69 67 27 28 6b   LE 't1_config'(k
|   3632: 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 76 29    PRIMARY KEY, v)
|   3648: 20 57 49 54 48 4f 55 54 20 52 4f 57 49 44 5b 05    WITHOUT ROWID[.
|   3664: 07 17 21 21 01 81 01 74 61 62 6c 65 74 31 5f 64   ..!!...tablet1_d
|   3680: 6f 63 73 69 7a 65 74 31 5f 64 6f 63 73 69 7a 65   ocsizet1_docsize
|   3696: 05 43 52 45 41 54 45 20 54 41 42 4c 45 20 27 74   .CREATE TABLE 't
|   3712: 31 5f 64 6f 63 73 69 7a 65 27 28 69 64 20 49 4e   1_docsize'(id IN
|   3728: 54 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45   TEGER PRIMARY KE
|   3744: 59 2c 20 73 7a 20 42 4c 4f 42 29 55 04 06 17 21   Y, sz BLOB)U...!
|   3760: 21 01 77 74 61 62 6c 65 74 31 5f 63 6f 6e 74 65   !.wtablet1_conte
|   3776: 6e 74 74 31 5f 63 6f 6e 74 65 6e 74 04 43 52 45   ntt1_content.CRE
|   3792: 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 63 6f   ATE TABLE 't1_co
|   3808: 6e 74 65 6e 74 27 28 69 64 20 49 4e 54 45 47 45   ntent'(id INTEGE
|   3824: 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 63   R PRIMARY KEY, c
|   3840: 30 29 69 03 07 17 19 19 01 81 2d 74 61 62 6c 65   0)i.......-table
|   3856: 74 31 5f 69 64 78 74 31 5f 69 64 78 03 43 52 45   t1_idxt1_idx.CRE
|   3872: 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 69 64   ATE TABLE 't1_id
|   3888: 78 27 28 73 65 67 69 64 2c 20 74 65 72 6d 2c 20   x'(segid, term, 
|   3904: 70 67 6e 6f 2c 20 50 52 49 4d 41 52 59 20 4b 45   pgno, PRIMARY KE
|   3920: 59 28 73 65 67 69 64 2c 20 74 65 72 6d 29 29 20   Y(segid, term)) 
|   3936: 57 49 54 48 4f 55 54 20 52 4f 57 49 44 55 02 07   WITHOUT ROWIDU..
|   3952: 17 1b 1b 01 81 01 74 61 62 6c 65 74 31 5f 64 61   ......tablet1_da
|   3968: 74 61 74 31 5f 64 61 74 61 02 43 52 45 41 54 45   tat1_data.CREATE
|   3984: 20 54 41 42 4c 45 20 27 74 31 5f 64 61 74 61 27    TABLE 't1_data'
|   4000: 28 69 64 20 49 4e 54 45 47 45 52 20 50 52 49 4d   (id INTEGER PRIM
|   4016: 41 52 59 20 4b 45 59 2c 20 62 6c 6f 63 6b 20 42   ARY KEY, block B
|   4032: 4c 4f 42 29 3a 01 06 17 11 11 08 63 74 61 62 6c   LOB):......ctabl
|   4048: 65 74 31 74 31 43 52 45 41 54 45 20 56 49 52 54   et1t1CREATE VIRT
|   4064: 55 41 4c 20 54 41 42 4c 45 20 74 31 20 55 53 49   UAL TABLE t1 USI
|   4080: 4e 47 20 66 74 73 35 28 63 6f 6e 74 65 6e 74 29   NG fts5(content)
| page 2 offset 4096
|      0: 0d 00 00 00 03 0f bd 00 0f e8 0f ef 0f bd 00 00   ................
|   4016: 00 00 00 00 00 00 00 00 00 00 00 00 00 24 84 80   .............$..
|   4032: 80 80 80 01 03 00 4e 00 00 00 1e 06 30 61 62 61   ......N.....0aba
|   4048: 63 6b 01 02 02 04 02 66 74 02 02 02 04 04 6e 64   ck.....ft.....nd
|   4064: 6f 6e 03 02 02 04 0a 07 05 01 03 00 10 03 03 0f   on..............
|   4080: 0a 03 00 24 00 00 00 0e ee ee ee ee ee ee ee ee   ...$............
| page 3 offset 8192
|      0: ee ee ee ee ee ee ee ee ee ee ee ee ee ee ee ee   ................
|     16: ee ee ee ee ee ee ee ee ee ee ee ee ee ee ee ee   ................
|     32: ee ee ee ee ee ee ee ee ee ee ee ee 00 10 10 10   ................
|     48: 00 10 10 10 10 a0 00 00 00 10 ff a0 00 ff 00 00   ................
|   4080: 00 00 00 00 00 00 00 00 00 00 05 04 09 0c 01 02   ................
| page 4 offset 12288
|      0: 0d 00 00 00 03 0f e0 00 0f f6 0f ec 0f e0 00 00   ................
|   4064: 0a 03 03 00 1b 61 62 61 6e 64 6f 6e 08 02 03 00   .....abandon....
|   4080: 17 61 62 61 66 74 08 01 03 00 17 61 62 61 63 6b   .abaft.....aback
| page 5 offset 16384
|      0: 0d 00 00 00 03 0f ee 00 0f fa 0f f4 0f ee 00 00   ................
|   4064: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 04 03   ................
|   4080: 03 00 0e 01 04 02 03 00 0e 01 04 01 03 00 0e 01   ................
| page 6 offset 20480
|      0: 0a 00 00 00 01 0f f4 00 0f f4 00 00 00 00 00 00   ................
|   4080: 00 00 00 00 0b 03 1b 01 76 65 72 73 69 6f 6e 04   ........version.
| page 7 offset 24576
|      0: 0d 00 00 00 03 0f d6 00 0f f4 0f e1 0f d6 00 00   ................
|   4048: 00 00 00 00 00 00 09 03 02 1b 72 65 62 75 69 6c   ..........rebuil
|   4064: 64 11 02 02 2b 69 6e 74 65 67 72 69 74 79 2d 63   d...+integrity-c
|   4080: 68 65 63 6b 0a 01 02 1d 6f 70 74 69 6d 69 7a 65   heck....optimize
| end crash-cf347c523f793c.db
}]} {}

do_catchsql_test 20.1 {
  SELECT * FROM t1 WHERE t1 MATCH 'abandon';
} {1 {vtable constructor failed: t1}}


sqlite3_fts5_may_be_corrupt 0
finish_test

Changes to ext/fts5/test/fts5unicode3.test.

17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# If SQLITE_ENABLE_FTS5 is defined, omit this file.
ifcapable !fts5 {
  finish_test
  return
}

proc fts3_unicode_path {file} {
  file join [file dirname [info script]] .. .. fts3 unicode $file
}

source [fts3_unicode_path parseunicode.tcl]
set testprefix fts5unicode3

set CF [fts3_unicode_path CaseFolding.txt]
set UD [fts3_unicode_path UnicodeData.txt]







|







17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# If SQLITE_ENABLE_FTS5 is defined, omit this file.
ifcapable !fts5 {
  finish_test
  return
}

proc fts3_unicode_path {file} {
  file join .. [file dirname [info script]] .. .. fts3 unicode $file
}

source [fts3_unicode_path parseunicode.tcl]
set testprefix fts5unicode3

set CF [fts3_unicode_path CaseFolding.txt]
set UD [fts3_unicode_path UnicodeData.txt]

Changes to ext/misc/csv.c.

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







|







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

Changes to ext/session/sqlite3session.h.

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







|







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

Changes to src/build.c.

2642
2643
2644
2645
2646
2647
2648

2649
2650
2651
2652
2653
2654
2655
  }

  /* Remove the table entry from SQLite's internal schema and modify
  ** the schema cookie.
  */
  if( IsVirtual(pTab) ){
    sqlite3VdbeAddOp4(v, OP_VDestroy, iDb, 0, 0, pTab->zName, 0);

  }
  sqlite3VdbeAddOp4(v, OP_DropTable, iDb, 0, 0, pTab->zName, 0);
  sqlite3ChangeCookie(pParse, iDb);
  sqliteViewResetAll(db, iDb);
}

/*







>







2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
  }

  /* Remove the table entry from SQLite's internal schema and modify
  ** the schema cookie.
  */
  if( IsVirtual(pTab) ){
    sqlite3VdbeAddOp4(v, OP_VDestroy, iDb, 0, 0, pTab->zName, 0);
    sqlite3MayAbort(pParse);
  }
  sqlite3VdbeAddOp4(v, OP_DropTable, iDb, 0, 0, pTab->zName, 0);
  sqlite3ChangeCookie(pParse, iDb);
  sqliteViewResetAll(db, iDb);
}

/*

Changes to src/select.c.

5462
5463
5464
5465
5466
5467
5468

5469
5470
5471
5472
5473
5474
5475
5476




5477
5478
5479
5480
5481
5482
5483
*/
static struct SrcList_item *isSelfJoinView(
  SrcList *pTabList,           /* Search for self-joins in this FROM clause */
  struct SrcList_item *pThis   /* Search for prior reference to this subquery */
){
  struct SrcList_item *pItem;
  for(pItem = pTabList->a; pItem<pThis; pItem++){

    if( pItem->pSelect==0 ) continue;
    if( pItem->fg.viaCoroutine ) continue;
    if( pItem->zName==0 ) continue;
    if( sqlite3_stricmp(pItem->zDatabase, pThis->zDatabase)!=0 ) continue;
    if( sqlite3_stricmp(pItem->zName, pThis->zName)!=0 ) continue;
    if( sqlite3ExprCompare(0, 
          pThis->pSelect->pWhere, pItem->pSelect->pWhere, -1) 
    ){




      /* The view was modified by some other optimization such as
      ** pushDownWhereTerms() */
      continue;
    }
    return pItem;
  }
  return 0;







>





|
|
|
>
>
>
>







5462
5463
5464
5465
5466
5467
5468
5469
5470
5471
5472
5473
5474
5475
5476
5477
5478
5479
5480
5481
5482
5483
5484
5485
5486
5487
5488
*/
static struct SrcList_item *isSelfJoinView(
  SrcList *pTabList,           /* Search for self-joins in this FROM clause */
  struct SrcList_item *pThis   /* Search for prior reference to this subquery */
){
  struct SrcList_item *pItem;
  for(pItem = pTabList->a; pItem<pThis; pItem++){
    Select *pS1;
    if( pItem->pSelect==0 ) continue;
    if( pItem->fg.viaCoroutine ) continue;
    if( pItem->zName==0 ) continue;
    if( sqlite3_stricmp(pItem->zDatabase, pThis->zDatabase)!=0 ) continue;
    if( sqlite3_stricmp(pItem->zName, pThis->zName)!=0 ) continue;
    pS1 = pItem->pSelect;
    if( pThis->pSelect->selId!=pS1->selId ){
      /* The query flattener left two different CTE tables with identical
      ** names in the same FROM clause. */
      continue;
    }
    if( sqlite3ExprCompare(0, pThis->pSelect->pWhere, pS1->pWhere, -1) ){
      /* The view was modified by some other optimization such as
      ** pushDownWhereTerms() */
      continue;
    }
    return pItem;
  }
  return 0;

Changes to src/sqliteInt.h.

3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
  u8 disableLookaside; /* Number of times lookaside has been disabled */
  u8 disableVtab;      /* Disable all virtual tables for this parse */
  int nRangeReg;       /* Size of the temporary register block */
  int iRangeReg;       /* First register in temporary register block */
  int nErr;            /* Number of errors seen */
  int nTab;            /* Number of previously allocated VDBE cursors */
  int nMem;            /* Number of memory cells used so far */
  int nOpAlloc;        /* Number of slots allocated for Vdbe.aOp[] */
  int szOpAlloc;       /* Bytes of memory space allocated for Vdbe.aOp[] */
  int iSelfTab;        /* Table associated with an index on expr, or negative
                       ** of the base register during check-constraint eval */
  int nLabel;          /* Number of labels used */
  int *aLabel;         /* Space to hold the labels */
  ExprList *pAuxExpr;  /* Exprs coded at initialization or as subroutines */
  Token constraintName;/* Name of the constraint currently being parsed */







<







3067
3068
3069
3070
3071
3072
3073

3074
3075
3076
3077
3078
3079
3080
  u8 disableLookaside; /* Number of times lookaside has been disabled */
  u8 disableVtab;      /* Disable all virtual tables for this parse */
  int nRangeReg;       /* Size of the temporary register block */
  int iRangeReg;       /* First register in temporary register block */
  int nErr;            /* Number of errors seen */
  int nTab;            /* Number of previously allocated VDBE cursors */
  int nMem;            /* Number of memory cells used so far */

  int szOpAlloc;       /* Bytes of memory space allocated for Vdbe.aOp[] */
  int iSelfTab;        /* Table associated with an index on expr, or negative
                       ** of the base register during check-constraint eval */
  int nLabel;          /* Number of labels used */
  int *aLabel;         /* Space to hold the labels */
  ExprList *pAuxExpr;  /* Exprs coded at initialization or as subroutines */
  Token constraintName;/* Name of the constraint currently being parsed */

Changes to src/test_vfs.c.

230
231
232
233
234
235
236

237
238
239
240
241
242
243
...
915
916
917
918
919
920
921

922

923
924
925
926
927
928
929
....
1559
1560
1561
1562
1563
1564
1565
1566









































































































1567
1568


1569
1570
1571
1572
  } aCode[] = {
    { SQLITE_OK,       "SQLITE_OK"     },
    { SQLITE_ERROR,    "SQLITE_ERROR"  },
    { SQLITE_IOERR,    "SQLITE_IOERR"  },
    { SQLITE_LOCKED,   "SQLITE_LOCKED" },
    { SQLITE_BUSY,     "SQLITE_BUSY"   },
    { SQLITE_READONLY, "SQLITE_READONLY"   },

  };

  const char *z;
  int i;

  z = Tcl_GetStringResult(p->interp);
  for(i=0; i<ArraySize(aCode); i++){
................................................................................
  if( rc==SQLITE_OK && p->mask&TESTVFS_SHMMAP_MASK && tvfsInjectIoerr(p) ){
    rc = SQLITE_IOERR;
  }

  if( rc==SQLITE_OK && isWrite && !pFd->pShm->aPage[iPage] ){
    tvfsAllocPage(pFd->pShm, iPage, pgsz);
  }

  *pp = (void volatile *)pFd->pShm->aPage[iPage];


  return rc;
}


static int tvfsShmLock(
  sqlite3_file *pFile,
................................................................................

  return TCL_OK;

 bad_args:
  Tcl_WrongNumArgs(interp, 1, objv, "VFSNAME ?-noshm BOOL? ?-fullshm BOOL? ?-default BOOL? ?-mxpathname INT? ?-szosfile INT? ?-iversion INT?");
  return TCL_ERROR;
}










































































































int Sqlitetestvfs_Init(Tcl_Interp *interp){
  Tcl_CreateObjCommand(interp, "testvfs", testvfs_cmd, 0, 0);


  return TCL_OK;
}

#endif







>







 







>
|
>







 








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


>
>




230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
...
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
....
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
  } aCode[] = {
    { SQLITE_OK,       "SQLITE_OK"     },
    { SQLITE_ERROR,    "SQLITE_ERROR"  },
    { SQLITE_IOERR,    "SQLITE_IOERR"  },
    { SQLITE_LOCKED,   "SQLITE_LOCKED" },
    { SQLITE_BUSY,     "SQLITE_BUSY"   },
    { SQLITE_READONLY, "SQLITE_READONLY"   },
    { SQLITE_READONLY_CANTINIT, "SQLITE_READONLY_CANTINIT"   },
  };

  const char *z;
  int i;

  z = Tcl_GetStringResult(p->interp);
  for(i=0; i<ArraySize(aCode); i++){
................................................................................
  if( rc==SQLITE_OK && p->mask&TESTVFS_SHMMAP_MASK && tvfsInjectIoerr(p) ){
    rc = SQLITE_IOERR;
  }

  if( rc==SQLITE_OK && isWrite && !pFd->pShm->aPage[iPage] ){
    tvfsAllocPage(pFd->pShm, iPage, pgsz);
  }
  if( rc==SQLITE_OK || rc==SQLITE_READONLY ){
    *pp = (void volatile *)pFd->pShm->aPage[iPage];
  }

  return rc;
}


static int tvfsShmLock(
  sqlite3_file *pFile,
................................................................................

  return TCL_OK;

 bad_args:
  Tcl_WrongNumArgs(interp, 1, objv, "VFSNAME ?-noshm BOOL? ?-fullshm BOOL? ?-default BOOL? ?-mxpathname INT? ?-szosfile INT? ?-iversion INT?");
  return TCL_ERROR;
}

extern int getDbPointer(Tcl_Interp *interp, const char *zA, sqlite3 **ppDb);
extern const char *sqlite3ErrName(int);

/*
** tclcmd: vfs_shmlock DB DBNAME (shared|exclusive) (lock|unlock) OFFSET N
*/
static int SQLITE_TCLAPI test_vfs_shmlock(
  void * clientData,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
){
  const char *azArg1[] = {"shared", "exclusive", 0};
  const char *azArg2[] = {"lock", "unlock", 0};
  sqlite3 *db = 0;
  int rc = SQLITE_OK;
  const char *zDbname = 0;
  int iArg1 = 0;
  int iArg2 = 0;
  int iOffset = 0;
  int n = 0;
  sqlite3_file *pFd;

  if( objc!=7 ){
    Tcl_WrongNumArgs(interp, 1, objv, 
        "DB DBNAME (shared|exclusive) (lock|unlock) OFFSET N"
    );
    return TCL_ERROR;
  }

  zDbname = Tcl_GetString(objv[2]);
  if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) 
   || Tcl_GetIndexFromObj(interp, objv[3], azArg1, "ARG", 0, &iArg1) 
   || Tcl_GetIndexFromObj(interp, objv[4], azArg2, "ARG", 0, &iArg2) 
   || Tcl_GetIntFromObj(interp, objv[5], &iOffset)
   || Tcl_GetIntFromObj(interp, objv[6], &n)
  ){
    return TCL_ERROR;
  }

  sqlite3_file_control(db, zDbname, SQLITE_FCNTL_FILE_POINTER, (void*)&pFd);
  if( pFd==0 ){
    return TCL_ERROR;
  }
  rc = pFd->pMethods->xShmLock(pFd, iOffset, n, 
      (iArg1==0 ? SQLITE_SHM_SHARED : SQLITE_SHM_EXCLUSIVE)
    | (iArg2==0 ? SQLITE_SHM_LOCK : SQLITE_SHM_UNLOCK)
  );
  Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3ErrName(rc), -1));
  return TCL_OK;
}

static int SQLITE_TCLAPI test_vfs_set_readmark(
  void * clientData,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
){
  sqlite3 *db = 0;
  int rc = SQLITE_OK;
  const char *zDbname = 0;
  int iSlot = 0;
  int iVal = -1;
  sqlite3_file *pFd;
  void volatile *pShm = 0;
  u32 *aShm;
  int iOff;

  if( objc!=4 && objc!=5 ){
    Tcl_WrongNumArgs(interp, 1, objv, "DB DBNAME SLOT ?VALUE?");
    return TCL_ERROR;
  }

  zDbname = Tcl_GetString(objv[2]);
  if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) 
   || Tcl_GetIntFromObj(interp, objv[3], &iSlot)
   || (objc==5 && Tcl_GetIntFromObj(interp, objv[4], &iVal))
  ){
    return TCL_ERROR;
  }

  sqlite3_file_control(db, zDbname, SQLITE_FCNTL_FILE_POINTER, (void*)&pFd);
  if( pFd==0 ){
    return TCL_ERROR;
  }
  rc = pFd->pMethods->xShmMap(pFd, 0, 32*1024, 0, &pShm);
  if( rc!=SQLITE_OK ){
    Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3ErrName(rc), -1));
    return TCL_ERROR;
  }
  if( pShm==0 ){
    Tcl_AppendResult(interp, "*-shm is not yet mapped", 0);
    return TCL_ERROR;
  }
  aShm = (u32*)pShm;
  iOff = 12*2+1+iSlot;

  if( objc==5 ){
    aShm[iOff] = iVal;
  }
  Tcl_SetObjResult(interp, Tcl_NewIntObj(aShm[iOff]));

  return TCL_OK;
}

int Sqlitetestvfs_Init(Tcl_Interp *interp){
  Tcl_CreateObjCommand(interp, "testvfs", testvfs_cmd, 0, 0);
  Tcl_CreateObjCommand(interp, "vfs_shmlock", test_vfs_shmlock, 0, 0);
  Tcl_CreateObjCommand(interp, "vfs_set_readmark", test_vfs_set_readmark, 0, 0);
  return TCL_OK;
}

#endif

Changes to src/treeview.c.

134
135
136
137
138
139
140
141

142
143
144
145
146
147
148
    sqlite3_str_appendf(&x, "{%d,*}", pItem->iCursor);
    if( pItem->zDatabase ){
      sqlite3_str_appendf(&x, " %s.%s", pItem->zDatabase, pItem->zName);
    }else if( pItem->zName ){
      sqlite3_str_appendf(&x, " %s", pItem->zName);
    }
    if( pItem->pTab ){
      sqlite3_str_appendf(&x, " tabname=%Q", pItem->pTab->zName);

    }
    if( pItem->zAlias ){
      sqlite3_str_appendf(&x, " (AS %s)", pItem->zAlias);
    }
    if( pItem->fg.jointype & JT_LEFT ){
      sqlite3_str_appendf(&x, " LEFT-JOIN");
    }







|
>







134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
    sqlite3_str_appendf(&x, "{%d,*}", pItem->iCursor);
    if( pItem->zDatabase ){
      sqlite3_str_appendf(&x, " %s.%s", pItem->zDatabase, pItem->zName);
    }else if( pItem->zName ){
      sqlite3_str_appendf(&x, " %s", pItem->zName);
    }
    if( pItem->pTab ){
      sqlite3_str_appendf(&x, " tab=%Q nCol=%d ptr=%p",
           pItem->pTab->zName, pItem->pTab->nCol, pItem->pTab);
    }
    if( pItem->zAlias ){
      sqlite3_str_appendf(&x, " (AS %s)", pItem->zAlias);
    }
    if( pItem->fg.jointype & JT_LEFT ){
      sqlite3_str_appendf(&x, " LEFT-JOIN");
    }

Changes to src/vdbe.c.

6848
6849
6850
6851
6852
6853
6854

6855
6856
6857
6858
6859
6860
6861
** P4 is the name of a virtual table in database P1.  Call the xDestroy method
** of that table.
*/
case OP_VDestroy: {
  db->nVDestroy++;
  rc = sqlite3VtabCallDestroy(db, pOp->p1, pOp->p4.z);
  db->nVDestroy--;

  if( rc ) goto abort_due_to_error;
  break;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */

#ifndef SQLITE_OMIT_VIRTUALTABLE
/* Opcode: VOpen P1 * * P4 *







>







6848
6849
6850
6851
6852
6853
6854
6855
6856
6857
6858
6859
6860
6861
6862
** P4 is the name of a virtual table in database P1.  Call the xDestroy method
** of that table.
*/
case OP_VDestroy: {
  db->nVDestroy++;
  rc = sqlite3VtabCallDestroy(db, pOp->p1, pOp->p4.z);
  db->nVDestroy--;
  assert( p->errorAction==OE_Abort && p->usesStmtJournal );
  if( rc ) goto abort_due_to_error;
  break;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */

#ifndef SQLITE_OMIT_VIRTUALTABLE
/* Opcode: VOpen P1 * * P4 *

Changes to src/vdbeInt.h.

381
382
383
384
385
386
387




388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
  int rc;                 /* Value to return */
  int nChange;            /* Number of db changes made since last reset */
  int iStatement;         /* Statement number (or 0 if has no opened stmt) */
  i64 iCurrentTime;       /* Value of julianday('now') for this statement */
  i64 nFkConstraint;      /* Number of imm. FK constraints this VM */
  i64 nStmtDefCons;       /* Number of def. constraints when stmt started */
  i64 nStmtDefImmCons;    /* Number of def. imm constraints when stmt started */





  /* When allocating a new Vdbe object, all of the fields below should be
  ** initialized to zero or NULL */

  Op *aOp;                /* Space to hold the virtual machine's program */
  Mem *aMem;              /* The memory locations */
  Mem **apArg;            /* Arguments to currently executing user function */
  Mem *aColName;          /* Column names to return */
  Mem *pResultSet;        /* Pointer to an array of results */
  char *zErrMsg;          /* Error message written here */
  VdbeCursor **apCsr;     /* One element of this array for each open cursor */
  Mem *aVar;              /* Values for the OP_Variable opcode. */
  VList *pVList;          /* Name of variables */
#ifndef SQLITE_OMIT_TRACE
  i64 startTime;          /* Time when query started - used for profiling */
#endif
  int nOp;                /* Number of instructions in the program */
#ifdef SQLITE_DEBUG
  int rcApp;              /* errcode set by sqlite3_result_error_code() */
  u32 nWrite;             /* Number of write operations that have occurred */
#endif
  u16 nResColumn;         /* Number of columns in one row of the result set */
  u8 errorAction;         /* Recovery action to do in case of an error */
  u8 minWriteFileFormat;  /* Minimum file format for writable database files */







>
>
>
>





|
|



<
<




<







381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401


402
403
404
405

406
407
408
409
410
411
412
  int rc;                 /* Value to return */
  int nChange;            /* Number of db changes made since last reset */
  int iStatement;         /* Statement number (or 0 if has no opened stmt) */
  i64 iCurrentTime;       /* Value of julianday('now') for this statement */
  i64 nFkConstraint;      /* Number of imm. FK constraints this VM */
  i64 nStmtDefCons;       /* Number of def. constraints when stmt started */
  i64 nStmtDefImmCons;    /* Number of def. imm constraints when stmt started */
  Mem *aMem;              /* The memory locations */
  Mem **apArg;            /* Arguments to currently executing user function */
  VdbeCursor **apCsr;     /* One element of this array for each open cursor */
  Mem *aVar;              /* Values for the OP_Variable opcode. */

  /* When allocating a new Vdbe object, all of the fields below should be
  ** initialized to zero or NULL */

  Op *aOp;                /* Space to hold the virtual machine's program */
  int nOp;                /* Number of instructions in the program */
  int nOpAlloc;           /* Slots allocated for aOp[] */
  Mem *aColName;          /* Column names to return */
  Mem *pResultSet;        /* Pointer to an array of results */
  char *zErrMsg;          /* Error message written here */


  VList *pVList;          /* Name of variables */
#ifndef SQLITE_OMIT_TRACE
  i64 startTime;          /* Time when query started - used for profiling */
#endif

#ifdef SQLITE_DEBUG
  int rcApp;              /* errcode set by sqlite3_result_error_code() */
  u32 nWrite;             /* Number of write operations that have occurred */
#endif
  u16 nResColumn;         /* Number of columns in one row of the result set */
  u8 errorAction;         /* Recovery action to do in case of an error */
  u8 minWriteFileFormat;  /* Minimum file format for writable database files */

Changes to src/vdbeaux.c.

32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
...
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
...
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
...
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
...
363
364
365
366
367
368
369
370


371
372
373
374
375
376
377
...
612
613
614
615
616
617
618

619
620
621
622
623
624
625
...
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
...
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
....
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214









2215
2216
2217
2218
2219
2220
2221
  p->pPrev = 0;
  db->pVdbe = p;
  p->magic = VDBE_MAGIC_INIT;
  p->pParse = pParse;
  pParse->pVdbe = p;
  assert( pParse->aLabel==0 );
  assert( pParse->nLabel==0 );
  assert( pParse->nOpAlloc==0 );
  assert( pParse->szOpAlloc==0 );
  sqlite3VdbeAddOp2(p, OP_Init, 0, 1);
  return p;
}

/*
** Change the error string stored in Vdbe.zErrMsg
................................................................................

/*
** Resize the Vdbe.aOp array so that it is at least nOp elements larger 
** than its current size. nOp is guaranteed to be less than or equal
** to 1024/sizeof(Op).
**
** If an out-of-memory error occurs while resizing the array, return
** SQLITE_NOMEM. In this case Vdbe.aOp and Parse.nOpAlloc remain 
** unchanged (this is so that any opcodes already allocated can be 
** correctly deallocated along with the rest of the Vdbe).
*/
static int growOpArray(Vdbe *v, int nOp){
  VdbeOp *pNew;
  Parse *p = v->pParse;

................................................................................
  ** more frequent reallocs and hence provide more opportunities for 
  ** simulated OOM faults.  SQLITE_TEST_REALLOC_STRESS is generally used
  ** during testing only.  With SQLITE_TEST_REALLOC_STRESS grow the op array
  ** by the minimum* amount required until the size reaches 512.  Normal
  ** operation (without SQLITE_TEST_REALLOC_STRESS) is to double the current
  ** size of the op array or add 1KB of space, whichever is smaller. */
#ifdef SQLITE_TEST_REALLOC_STRESS
  int nNew = (p->nOpAlloc>=512 ? p->nOpAlloc*2 : p->nOpAlloc+nOp);
#else
  int nNew = (p->nOpAlloc ? p->nOpAlloc*2 : (int)(1024/sizeof(Op)));
  UNUSED_PARAMETER(nOp);
#endif

  /* Ensure that the size of a VDBE does not grow too large */
  if( nNew > p->db->aLimit[SQLITE_LIMIT_VDBE_OP] ){
    sqlite3OomFault(p->db);
    return SQLITE_NOMEM;
  }

  assert( nOp<=(1024/sizeof(Op)) );
  assert( nNew>=(p->nOpAlloc+nOp) );
  pNew = sqlite3DbRealloc(p->db, v->aOp, nNew*sizeof(Op));
  if( pNew ){
    p->szOpAlloc = sqlite3DbMallocSize(p->db, pNew);
    p->nOpAlloc = p->szOpAlloc/sizeof(Op);
    v->aOp = pNew;
  }
  return (pNew ? SQLITE_OK : SQLITE_NOMEM_BKPT);
}

#ifdef SQLITE_DEBUG
/* This routine is just a convenient place to set a breakpoint that will
................................................................................
**    p1, p2, p3      Operands
**
** Use the sqlite3VdbeResolveLabel() function to fix an address and
** the sqlite3VdbeChangeP4() function to change the value of the P4
** operand.
*/
static SQLITE_NOINLINE int growOp3(Vdbe *p, int op, int p1, int p2, int p3){
  assert( p->pParse->nOpAlloc<=p->nOp );
  if( growOpArray(p, 1) ) return 1;
  assert( p->pParse->nOpAlloc>p->nOp );
  return sqlite3VdbeAddOp3(p, op, p1, p2, p3);
}
int sqlite3VdbeAddOp3(Vdbe *p, int op, int p1, int p2, int p3){
  int i;
  VdbeOp *pOp;

  i = p->nOp;
  assert( p->magic==VDBE_MAGIC_INIT );
  assert( op>=0 && op<0xff );
  if( p->pParse->nOpAlloc<=i ){
    return growOp3(p, op, p1, p2, p3);
  }
  p->nOp++;
  pOp = &p->aOp[i];
  pOp->opcode = (u8)op;
  pOp->p5 = 0;
  pOp->p1 = p1;
................................................................................
/*
** Add a new OP_ opcode.
**
** If the bPush flag is true, then make this opcode the parent for
** subsequent Explains until sqlite3VdbeExplainPop() is called.
*/
void sqlite3VdbeExplain(Parse *pParse, u8 bPush, const char *zFmt, ...){
#if !defined(SQLITE_DEBUG)


  if( pParse->explain==2 )
#endif
  {
    char *zMsg;
    Vdbe *v;
    va_list ap;
    int iThis;
................................................................................
  VdbeOpIter sIter;
  memset(&sIter, 0, sizeof(sIter));
  sIter.v = v;

  while( (pOp = opIterNext(&sIter))!=0 ){
    int opcode = pOp->opcode;
    if( opcode==OP_Destroy || opcode==OP_VUpdate || opcode==OP_VRename 

     || ((opcode==OP_Halt || opcode==OP_HaltIfNull) 
      && ((pOp->p1&0xff)==SQLITE_CONSTRAINT && pOp->p2==OE_Abort))
    ){
      hasAbort = 1;
      break;
    }
    if( opcode==OP_CreateBtree && pOp->p3==BTREE_INTKEY ) hasCreateTable = 1;
................................................................................
** SQLITE_TEST_REALLOC_STRESS).  This interface is used during testing
** to verify that certain calls to sqlite3VdbeAddOpList() can never
** fail due to a OOM fault and hence that the return value from
** sqlite3VdbeAddOpList() will always be non-NULL.
*/
#if defined(SQLITE_DEBUG) && !defined(SQLITE_TEST_REALLOC_STRESS)
void sqlite3VdbeVerifyNoMallocRequired(Vdbe *p, int N){
  assert( p->nOp + N <= p->pParse->nOpAlloc );
}
#endif

/*
** Verify that the VM passed as the only argument does not contain
** an OP_ResultRow opcode. Fail an assert() if it does. This is used
** by code in pragma.c to ensure that the implementation of certain
................................................................................
  VdbeOpList const *aOp,       /* The opcodes to be added */
  int iLineno                  /* Source-file line number of first opcode */
){
  int i;
  VdbeOp *pOut, *pFirst;
  assert( nOp>0 );
  assert( p->magic==VDBE_MAGIC_INIT );
  if( p->nOp + nOp > p->pParse->nOpAlloc && growOpArray(p, nOp) ){
    return 0;
  }
  pFirst = pOut = &p->aOp[p->nOp];
  for(i=0; i<nOp; i++, aOp++, pOut++){
    pOut->opcode = aOp->opcode;
    pOut->p1 = aOp->p1;
    pOut->p2 = aOp->p2;
................................................................................
  ** requirements by reusing the opcode array tail, then the second
  ** pass will fill in the remainder using a fresh memory allocation.  
  **
  ** This two-pass approach that reuses as much memory as possible from
  ** the leftover memory at the end of the opcode array.  This can significantly
  ** reduce the amount of memory held by a prepared statement.
  */
  do {
    x.nNeeded = 0;
    p->aMem = allocSpace(&x, p->aMem, nMem*sizeof(Mem));
    p->aVar = allocSpace(&x, p->aVar, nVar*sizeof(Mem));
    p->apArg = allocSpace(&x, p->apArg, nArg*sizeof(Mem*));
    p->apCsr = allocSpace(&x, p->apCsr, nCursor*sizeof(VdbeCursor*));
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
    p->anExec = allocSpace(&x, p->anExec, p->nOp*sizeof(i64));
#endif
    if( x.nNeeded==0 ) break;
    x.pSpace = p->pFree = sqlite3DbMallocRawNN(db, x.nNeeded);
    x.nFree = x.nNeeded;
  }while( !db->mallocFailed );










  p->pVList = pParse->pVList;
  pParse->pVList =  0;
  p->explain = pParse->explain;
  if( db->mallocFailed ){
    p->nVar = 0;
    p->nCursor = 0;







|







 







|







 







|

|










|



|







 







|

|









|







 







|
>
>







 







>







 







|







 







|







 







<
|
|
|
|
|

|

|


|
>
>
>
>
>
>
>
>
>







32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
...
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
...
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
...
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
...
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
...
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
...
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
...
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
....
2198
2199
2200
2201
2202
2203
2204

2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
  p->pPrev = 0;
  db->pVdbe = p;
  p->magic = VDBE_MAGIC_INIT;
  p->pParse = pParse;
  pParse->pVdbe = p;
  assert( pParse->aLabel==0 );
  assert( pParse->nLabel==0 );
  assert( p->nOpAlloc==0 );
  assert( pParse->szOpAlloc==0 );
  sqlite3VdbeAddOp2(p, OP_Init, 0, 1);
  return p;
}

/*
** Change the error string stored in Vdbe.zErrMsg
................................................................................

/*
** Resize the Vdbe.aOp array so that it is at least nOp elements larger 
** than its current size. nOp is guaranteed to be less than or equal
** to 1024/sizeof(Op).
**
** If an out-of-memory error occurs while resizing the array, return
** SQLITE_NOMEM. In this case Vdbe.aOp and Vdbe.nOpAlloc remain 
** unchanged (this is so that any opcodes already allocated can be 
** correctly deallocated along with the rest of the Vdbe).
*/
static int growOpArray(Vdbe *v, int nOp){
  VdbeOp *pNew;
  Parse *p = v->pParse;

................................................................................
  ** more frequent reallocs and hence provide more opportunities for 
  ** simulated OOM faults.  SQLITE_TEST_REALLOC_STRESS is generally used
  ** during testing only.  With SQLITE_TEST_REALLOC_STRESS grow the op array
  ** by the minimum* amount required until the size reaches 512.  Normal
  ** operation (without SQLITE_TEST_REALLOC_STRESS) is to double the current
  ** size of the op array or add 1KB of space, whichever is smaller. */
#ifdef SQLITE_TEST_REALLOC_STRESS
  int nNew = (v->nOpAlloc>=512 ? v->nOpAlloc*2 : v->nOpAlloc+nOp);
#else
  int nNew = (v->nOpAlloc ? v->nOpAlloc*2 : (int)(1024/sizeof(Op)));
  UNUSED_PARAMETER(nOp);
#endif

  /* Ensure that the size of a VDBE does not grow too large */
  if( nNew > p->db->aLimit[SQLITE_LIMIT_VDBE_OP] ){
    sqlite3OomFault(p->db);
    return SQLITE_NOMEM;
  }

  assert( nOp<=(1024/sizeof(Op)) );
  assert( nNew>=(v->nOpAlloc+nOp) );
  pNew = sqlite3DbRealloc(p->db, v->aOp, nNew*sizeof(Op));
  if( pNew ){
    p->szOpAlloc = sqlite3DbMallocSize(p->db, pNew);
    v->nOpAlloc = p->szOpAlloc/sizeof(Op);
    v->aOp = pNew;
  }
  return (pNew ? SQLITE_OK : SQLITE_NOMEM_BKPT);
}

#ifdef SQLITE_DEBUG
/* This routine is just a convenient place to set a breakpoint that will
................................................................................
**    p1, p2, p3      Operands
**
** Use the sqlite3VdbeResolveLabel() function to fix an address and
** the sqlite3VdbeChangeP4() function to change the value of the P4
** operand.
*/
static SQLITE_NOINLINE int growOp3(Vdbe *p, int op, int p1, int p2, int p3){
  assert( p->nOpAlloc<=p->nOp );
  if( growOpArray(p, 1) ) return 1;
  assert( p->nOpAlloc>p->nOp );
  return sqlite3VdbeAddOp3(p, op, p1, p2, p3);
}
int sqlite3VdbeAddOp3(Vdbe *p, int op, int p1, int p2, int p3){
  int i;
  VdbeOp *pOp;

  i = p->nOp;
  assert( p->magic==VDBE_MAGIC_INIT );
  assert( op>=0 && op<0xff );
  if( p->nOpAlloc<=i ){
    return growOp3(p, op, p1, p2, p3);
  }
  p->nOp++;
  pOp = &p->aOp[i];
  pOp->opcode = (u8)op;
  pOp->p5 = 0;
  pOp->p1 = p1;
................................................................................
/*
** Add a new OP_ opcode.
**
** If the bPush flag is true, then make this opcode the parent for
** subsequent Explains until sqlite3VdbeExplainPop() is called.
*/
void sqlite3VdbeExplain(Parse *pParse, u8 bPush, const char *zFmt, ...){
#ifndef SQLITE_DEBUG
  /* Always include the OP_Explain opcodes if SQLITE_DEBUG is defined.
  ** But omit them (for performance) during production builds */
  if( pParse->explain==2 )
#endif
  {
    char *zMsg;
    Vdbe *v;
    va_list ap;
    int iThis;
................................................................................
  VdbeOpIter sIter;
  memset(&sIter, 0, sizeof(sIter));
  sIter.v = v;

  while( (pOp = opIterNext(&sIter))!=0 ){
    int opcode = pOp->opcode;
    if( opcode==OP_Destroy || opcode==OP_VUpdate || opcode==OP_VRename 
     || opcode==OP_VDestroy
     || ((opcode==OP_Halt || opcode==OP_HaltIfNull) 
      && ((pOp->p1&0xff)==SQLITE_CONSTRAINT && pOp->p2==OE_Abort))
    ){
      hasAbort = 1;
      break;
    }
    if( opcode==OP_CreateBtree && pOp->p3==BTREE_INTKEY ) hasCreateTable = 1;
................................................................................
** SQLITE_TEST_REALLOC_STRESS).  This interface is used during testing
** to verify that certain calls to sqlite3VdbeAddOpList() can never
** fail due to a OOM fault and hence that the return value from
** sqlite3VdbeAddOpList() will always be non-NULL.
*/
#if defined(SQLITE_DEBUG) && !defined(SQLITE_TEST_REALLOC_STRESS)
void sqlite3VdbeVerifyNoMallocRequired(Vdbe *p, int N){
  assert( p->nOp + N <= p->nOpAlloc );
}
#endif

/*
** Verify that the VM passed as the only argument does not contain
** an OP_ResultRow opcode. Fail an assert() if it does. This is used
** by code in pragma.c to ensure that the implementation of certain
................................................................................
  VdbeOpList const *aOp,       /* The opcodes to be added */
  int iLineno                  /* Source-file line number of first opcode */
){
  int i;
  VdbeOp *pOut, *pFirst;
  assert( nOp>0 );
  assert( p->magic==VDBE_MAGIC_INIT );
  if( p->nOp + nOp > p->nOpAlloc && growOpArray(p, nOp) ){
    return 0;
  }
  pFirst = pOut = &p->aOp[p->nOp];
  for(i=0; i<nOp; i++, aOp++, pOut++){
    pOut->opcode = aOp->opcode;
    pOut->p1 = aOp->p1;
    pOut->p2 = aOp->p2;
................................................................................
  ** requirements by reusing the opcode array tail, then the second
  ** pass will fill in the remainder using a fresh memory allocation.  
  **
  ** This two-pass approach that reuses as much memory as possible from
  ** the leftover memory at the end of the opcode array.  This can significantly
  ** reduce the amount of memory held by a prepared statement.
  */

  x.nNeeded = 0;
  p->aMem = allocSpace(&x, 0, nMem*sizeof(Mem));
  p->aVar = allocSpace(&x, 0, nVar*sizeof(Mem));
  p->apArg = allocSpace(&x, 0, nArg*sizeof(Mem*));
  p->apCsr = allocSpace(&x, 0, nCursor*sizeof(VdbeCursor*));
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
  p->anExec = allocSpace(&x, 0, p->nOp*sizeof(i64));
#endif
  if( x.nNeeded ){
    x.pSpace = p->pFree = sqlite3DbMallocRawNN(db, x.nNeeded);
    x.nFree = x.nNeeded;
    if( !db->mallocFailed ){
      p->aMem = allocSpace(&x, p->aMem, nMem*sizeof(Mem));
      p->aVar = allocSpace(&x, p->aVar, nVar*sizeof(Mem));
      p->apArg = allocSpace(&x, p->apArg, nArg*sizeof(Mem*));
      p->apCsr = allocSpace(&x, p->apCsr, nCursor*sizeof(VdbeCursor*));
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
      p->anExec = allocSpace(&x, p->anExec, p->nOp*sizeof(i64));
#endif
    }
  }

  p->pVList = pParse->pVList;
  pParse->pVList =  0;
  p->explain = pParse->explain;
  if( db->mallocFailed ){
    p->nVar = 0;
    p->nCursor = 0;

Changes to test/btree02.test.

17
18
19
20
21
22
23
24
25
26
27
28
29
30
31






32
33
34
35
36
37
38
39
40
41
42
43
44

45
46
47

48
49
50
51
52
53
54
set testdir [file dirname $argv0]
source $testdir/tester.tcl

load_static_extension db eval
do_execsql_test btree02-100 {
  CREATE TABLE t1(a TEXT, ax INTEGER, b INT, PRIMARY KEY(a,ax)) WITHOUT ROWID;
  WITH RECURSIVE c(i) AS (VALUES(1) UNION ALL SELECT i+1 FROM c WHERE i<10)
    INSERT INTO t1(a,ax,b) SELECT printf('%02x',i), random(), i FROM c;
  CREATE INDEX t1a ON t1(a);
  CREATE TABLE t2(x,y);
  CREATE TABLE t3(cnt);
  WITH RECURSIVE c(i) AS (VALUES(1) UNION ALL SELECT i+1 FROM c WHERE i<4)
    INSERT INTO t3(cnt) SELECT i FROM c;
  SELECT count(*) FROM t1;
} {10}






do_test btree02-110 {
  db eval BEGIN
  set i 0
  db eval {SELECT a, ax, b, cnt FROM t1 CROSS JOIN t3 WHERE b IS NOT NULL} {
    if {$a==""} {set a 0}
    if {$b==""} {set b 0}    
    db eval {INSERT INTO t2(x,y) VALUES($b,$cnt)}
    # puts "a,b,cnt = ($a,$b,$cnt)"
    incr i
    if {$i%2==1} {
      set bx [expr {$b+1000}]
      # puts "INSERT ($a),$bx"
      db eval {INSERT INTO t1(a,ax,b) VALUES(printf('(%s)',$a),random(),$bx)}

    } else {
      # puts "DELETE a=$a"
      db eval {DELETE FROM t1 WHERE a=$a}

    }
    db eval {COMMIT; BEGIN}
  }  
  db one {COMMIT; SELECT count(*) FROM t1;}
} {27}

finish_test







|







>
>
>
>
>
>



|
|
|





|

>



>




|


17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
set testdir [file dirname $argv0]
source $testdir/tester.tcl

load_static_extension db eval
do_execsql_test btree02-100 {
  CREATE TABLE t1(a TEXT, ax INTEGER, b INT, PRIMARY KEY(a,ax)) WITHOUT ROWID;
  WITH RECURSIVE c(i) AS (VALUES(1) UNION ALL SELECT i+1 FROM c WHERE i<10)
    INSERT INTO t1(a,ax,b) SELECT printf('%02x',i+160), random(), i FROM c;
  CREATE INDEX t1a ON t1(a);
  CREATE TABLE t2(x,y);
  CREATE TABLE t3(cnt);
  WITH RECURSIVE c(i) AS (VALUES(1) UNION ALL SELECT i+1 FROM c WHERE i<4)
    INSERT INTO t3(cnt) SELECT i FROM c;
  SELECT count(*) FROM t1;
} {10}

proc showt1 {} {
  puts -nonewline "t1: "
  puts [db eval {SELECT printf('(%s,%s)',quote(a),quote(b)) FROM t1}]
}

do_test btree02-110 {
  db eval BEGIN
  set i 0
  # showt1
  db eval {SELECT a, ax, b, cnt FROM t1 CROSS JOIN t3 WHERE b IS NOT NULL} {
    if {$a==""} continue
    db eval {INSERT INTO t2(x,y) VALUES($b,$cnt)}
    # puts "a,b,cnt = ($a,$b,$cnt)"
    incr i
    if {$i%2==1} {
      set bx [expr {$b+1000}]
      #  puts "INSERT ($a),$bx"
      db eval {INSERT INTO t1(a,ax,b) VALUES(printf('(%s)',$a),random(),$bx)}
      # showt1
    } else {
      # puts "DELETE a=$a"
      db eval {DELETE FROM t1 WHERE a=$a}
      # showt1
    }
    db eval {COMMIT; BEGIN}
  }  
  db one {COMMIT; SELECT count(*) FROM t1;}
} {10}

finish_test

Changes to test/csv01.test.

210
211
212
213
214
215
216























217
# by Trent W. Buck.
#
do_execsql_test 4.4 {
  CREATE VIRTUAL TABLE temp.trent USING csv(data='1');
  SELECT * FROM trent;
} {1}
























finish_test







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
# by Trent W. Buck.
#
do_execsql_test 4.4 {
  CREATE VIRTUAL TABLE temp.trent USING csv(data='1');
  SELECT * FROM trent;
} {1}

# 2018-12-26
# Bug report on the mailing list
#
forcedelete csv01.csv
set fd [open csv01.csv w]
puts $fd "a,b,c,d\r\n1,2,3,4\r\none,two,three,four\r\n5,6,7,8"
close $fd
do_execsql_test 5.1 {
  CREATE VIRTUAL TABLE t5_1 USING csv(filename='csv01.csv');
  SELECT name FROM temp.pragma_table_info('t5_1');
} {c0 c1 c2 c3}
do_execsql_test 5.2 {
  SELECT *, '|' FROM t5_1;
} {a b c d | 1 2 3 4 | one two three four | 5 6 7 8 |}
do_execsql_test 5.3 {
  DROP TABLE t5_1;
  CREATE VIRTUAL TABLE t5_1 USING csv(filename='csv01.csv', header);
  SELECT name FROM temp.pragma_table_info('t5_1');
} {a b c d}
do_execsql_test 5.4 {
  SELECT *, '|' FROM t5_1;
} {1 2 3 4 | one two three four | 5 6 7 8 |}

finish_test

Changes to test/fts3corrupt4.test.

162
163
164
165
166
167
168














































































169




170
do_catchsql_test 4.3 { 
  SELECT * FROM t1 WHERE t1 MATCH 'three'; 
} {1 {database disk image is malformed}}
do_execsql_test 4.4 {
  INSERT INTO t1(t1) VALUES('optimize');
}




















































































finish_test







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

>
>
>
>

162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
do_catchsql_test 4.3 { 
  SELECT * FROM t1 WHERE t1 MATCH 'three'; 
} {1 {database disk image is malformed}}
do_execsql_test 4.4 {
  INSERT INTO t1(t1) VALUES('optimize');
}

#-------------------------------------------------------------------------
reset_db
do_test 5.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
| size 24576 pagesize 4096 filename c15.db
| page 1 offset 0
|      0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00   SQLite format 3.
|     16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 04   .....@  ........
|     32: 00 00 00 00 00 00 00 00 00 00 00 04 00 00 00 04   ................
|     48: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00   ................
|     96: 00 00 00 00 0d 0e f9 00 06 0d ec 00 0f cd 0f 69   ...............i
|    112: 0f 01 0e 10 0e c6 0d ec 00 00 00 00 00 00 00 00   ................
|   3552: 00 00 00 00 00 00 00 00 00 00 00 00 22 06 06 17   ................
|   3568: 11 11 01 31 74 61 62 6c 65 74 32 74 32 06 43 52   ...1tablet2t2.CR
|   3584: 45 41 54 45 20 54 41 42 4c 45 20 74 32 28 78 29   EATE TABLE t2(x)
|   3600: 81 33 04 07 17 1f 1f 01 82 35 74 61 62 6c 65 74   .3.......5tablet
|   3616: 31 5f 73 65 67 64 69 72 74 31 5f 73 65 67 64 69   1_segdirt1_segdi
|   3632: 72 04 43 52 45 41 54 45 20 54 41 42 4c 45 20 27   r.CREATE TABLE '
|   3648: 74 31 5f 73 65 67 64 69 72 27 28 6c 65 76 65 6c   t1_segdir'(level
|   3664: 20 49 4e 54 45 47 45 52 2c 69 64 78 20 49 4e 54    INTEGER,idx INT
|   3680: 45 47 45 52 2c 73 74 61 72 74 5f 62 6c 6f 63 6b   EGER,start_block
|   3696: 20 49 4e 54 45 47 45 52 2c 6c 65 61 76 65 73 5f    INTEGER,leaves_
|   3712: 65 6e 64 5f 62 6c 6f 63 6b 20 49 4e 54 45 47 45   end_block INTEGE
|   3728: 52 2c 65 6e 64 5f 62 6c 6f 63 6b 20 49 4e 54 45   R,end_block INTE
|   3744: 47 45 52 2c 72 6f 6f 74 20 42 4c 4f 42 2c 50 52   GER,root BLOB,PR
|   3760: 49 4d 41 52 59 20 4b 45 59 28 6c 65 76 65 6c 2c   IMARY KEY(level,
|   3776: 20 69 64 78 29 29 31 05 06 17 45 1f 01 00 69 6e    idx))1...E...in
|   3792: 64 65 78 73 71 6c 69 74 65 5f 61 75 74 6f 69 6e   dexsqlite_autoin
|   3808: 64 65 79 5f 74 31 5f 73 65 67 64 69 72 5f 31 74   dey_t1_segdir_1t
|   3824: 31 5f 73 65 67 64 69 72 05 00 00 00 08 00 00 00   1_segdir........
|   3840: 00 66 03 07 17 23 23 01 81 13 74 61 62 6c 65 74   .f...##...tablet
|   3856: 31 5f 73 65 67 6d 65 6e 74 73 74 31 5f 73 65 67   1_segmentst1_seg
|   3872: 6d 65 6e 74 73 03 43 52 45 41 54 45 20 54 41 42   ments.CREATE TAB
|   3888: 4c 45 20 27 74 31 5f 73 65 67 6d 65 6e 74 73 27   LE 't1_segments'
|   3904: 28 62 6c 6f 63 6b 69 64 20 49 4e 54 45 47 45 52   (blockid INTEGER
|   3920: 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 62 6c    PRIMARY KEY, bl
|   3936: 6f 63 6b 20 42 4c 4f 42 29 62 02 07 17 21 21 01   ock BLOB)b...!!.
|   3952: 81 0f 74 61 62 6c 65 74 31 5f 63 6f 6e 74 65 6e   ..tablet1_conten
|   3968: 74 74 31 5f 63 6f 6e 74 65 6e 74 02 43 52 45 41   tt1_content.CREA
|   3984: 54 45 20 54 41 42 4c 45 20 27 74 31 5f 63 6f 6e   TE TABLE 't1_con
|   4000: 74 65 6e 74 27 28 64 6f 63 69 64 20 49 4e 54 45   tent'(docid INTE
|   4016: 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c   GER PRIMARY KEY,
|   4032: 20 27 63 30 63 6f 6e 74 65 6e 74 27 29 31 01 06    'c0content')1..
|   4048: 17 11 11 08 51 74 61 62 6c 65 74 31 74 31 43 52   ....Qtablet1t1CR
|   4064: 45 41 54 45 20 56 49 52 54 55 41 4c 20 54 41 42   EATE VIRTUAL TAB
|   4080: 4c 45 20 74 31 20 55 53 49 4e 47 20 66 74 73 33   LE t1 USING fts3
| page 2 offset 4096
|      0: 0d 00 00 00 03 0f e0 00 0f f6 0f ec 0f e0 00 00   ................
|   4064: 0a 03 03 00 1b 61 62 61 6e 64 6f 6e 08 02 03 00   .....abandon....
|   4080: 17 61 62 61 66 74 08 01 03 00 17 61 62 61 63 6b   .abaft.....aback
| page 3 offset 8192
|      0: 0d 00 00 00 00 10 00 00 00 00 00 00 00 00 00 00   ................
| page 4 offset 12288
|      0: 0d 00 00 00 01 0f d6 00 0f d6 00 00 00 00 00 00   ................
|   4048: 00 00 00 00 00 00 28 01 07 08 08 08 08 15 46 30   ......(.......F0
|   4064: 20 32 39 00 05 61 62 61 63 6b 03 01 02 00 03 02    29..aback......
|   4080: 66 74 03 02 02 00 03 04 6e 64 6f 60 30 30 20 00   ft......ndo`00 .
| page 5 offset 16384
|      0: a0 00 00 00 10 ff b0 00 ff fb 00 00 00 00 00 00   ................
|   4080: 00 00 00 00 00 00 00 00 00 00 00 04 04 08 08 09   ................
| page 6 offset 20480
|      0: 0d 00 00 00 05 0f b8 00 0f f4 0f e9 0f d6 0f c7   ................
|     16: 0f b8 27 74 31 5f 63 6f 6e 74 65 6e 74 27 28 64   ..'t1_content'(d
|     32: 6f 63 69 64 20 49 4e 54 45 47 45 52 20 50 52 49   ocid INTEGER PRI
|     48: 4d 41 52 59 20 4b 45 59 2c 20 27 63 30 63 6f 6e   MARY KEY, 'c0con
|     64: 74 65 6e 74 27 29 31 01 06 17 11 11 08 51 74 61   tent')1......Qta
|     80: 62 6c 65 74 31 74 31 43 52 45 41 54 45 20 56 49   blet1t1CREATE VI
|     96: 52 54 55 41 4c 20 54 41 42 4c 45 20 74 31 20 55   RTUAL TABLE t1 U
|    112: 53 49 4e 47 20 66 74 73 33 0d 00 00 00 03 0f e0   SING fts3.......
|    128: 00 0f f6 0f ec 0f e0 00 00 00 00 00 00 00 00 00   ................
|   4016: 00 00 00 00 00 00 00 00 0d 05 02 23 61 75 74 6f   ...........#auto
|   4032: 6d 65 72 67 65 3d 35 0d 04 02 23 6d 65 72 67 65   merge=5...#merge
|   4048: 3d 31 30 30 2c 38 11 03 02 2b 69 6e 74 65 67 72   =100,8...+integr
|   4064: 69 74 79 2d 63 68 65 63 6b 09 02 02 1b 72 65 62   ity-check....reb
|   4080: 75 69 6c 64 0a 01 02 1d 6f 70 74 69 6d 69 7a 65   uild....optimize
| end c15.db
}]} {}

do_catchsql_test 5.1 {
  SELECT * FROM t1 WHERE t1 MATCH 'abandon';
} {1 {database disk image is malformed}}

finish_test

Changes to test/lock_common.tcl.

11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29




30
31
32
33
34
35
36
# This file contains code used by several different test scripts. The
# code in this file allows testfixture to control another process (or
# processes) to test locking.
#

proc do_multiclient_test {varname script} {

  foreach code [list {
    if {[info exists ::G(valgrind)]} { db close ; continue }
    set ::code2_chan [launch_testfixture]
    set ::code3_chan [launch_testfixture]
    proc code2 {tcl} { testfixture $::code2_chan $tcl }
    proc code3 {tcl} { testfixture $::code3_chan $tcl }
    set tn 1
  } {
    proc code2 {tcl} { uplevel #0 $tcl }
    proc code3 {tcl} { uplevel #0 $tcl }
    set tn 2
  }] {




    faultsim_delete_and_reopen

    proc code1 {tcl} { uplevel #0 $tcl }
  
    # Open connections [db2] and [db3]. Depending on which iteration this
    # is, the connections may be created in this interpreter, or in 
    # interpreters running in other OS processes. As such, the [db2] and [db3]







|





<
|


<

>
>
>
>







11
12
13
14
15
16
17
18
19
20
21
22
23

24
25
26

27
28
29
30
31
32
33
34
35
36
37
38
# This file contains code used by several different test scripts. The
# code in this file allows testfixture to control another process (or
# processes) to test locking.
#

proc do_multiclient_test {varname script} {

  foreach {tn code} [list 1 {
    if {[info exists ::G(valgrind)]} { db close ; continue }
    set ::code2_chan [launch_testfixture]
    set ::code3_chan [launch_testfixture]
    proc code2 {tcl} { testfixture $::code2_chan $tcl }
    proc code3 {tcl} { testfixture $::code3_chan $tcl }

  } 2 {
    proc code2 {tcl} { uplevel #0 $tcl }
    proc code3 {tcl} { uplevel #0 $tcl }

  }] {
    # Do not run multi-process tests with the unix-excl VFS.
    #
    if {$tn==1 && [permutation]=="unix-excl"} continue

    faultsim_delete_and_reopen

    proc code1 {tcl} { uplevel #0 $tcl }
  
    # Open connections [db2] and [db3]. Depending on which iteration this
    # is, the connections may be created in this interpreter, or in 
    # interpreters running in other OS processes. As such, the [db2] and [db3]

Changes to test/permutations.test.

433
434
435
436
437
438
439
440

441



442
443
444
445
446
447
448
  wal.test wal2.test wal3.test wal4.test wal5.test
  wal64k.test wal6.test wal7.test wal8.test wal9.test
  walbak.test walbig.test walblock.test walcksum.test walcrash2.test
  walcrash3.test walcrash4.test walcrash.test walfault.test walhook.test
  walmode.test walnoshm.test waloverwrite.test walpersist.test 
  walprotocol2.test walprotocol.test walro2.test walrofault.test 
  walro.test walshared.test walslow.test walvfs.test


  nockpt.test



} 

test_suite "coverage-pager" -description {
  Coverage tests for file pager.c.
} -files {
  pager1.test    pager2.test  pagerfault.test  pagerfault2.test
  walfault.test  walbak.test  journal2.test    tkt-9d68c883.test







<
>

>
>
>







433
434
435
436
437
438
439

440
441
442
443
444
445
446
447
448
449
450
451
  wal.test wal2.test wal3.test wal4.test wal5.test
  wal64k.test wal6.test wal7.test wal8.test wal9.test
  walbak.test walbig.test walblock.test walcksum.test walcrash2.test
  walcrash3.test walcrash4.test walcrash.test walfault.test walhook.test
  walmode.test walnoshm.test waloverwrite.test walpersist.test 
  walprotocol2.test walprotocol.test walro2.test walrofault.test 
  walro.test walshared.test walslow.test walvfs.test

  walfault2.test
  nockpt.test

  snapshot2.test snapshot3.test snapshot4.test
  snapshot_fault.test snapshot.test snapshot_up.test
} 

test_suite "coverage-pager" -description {
  Coverage tests for file pager.c.
} -files {
  pager1.test    pager2.test  pagerfault.test  pagerfault2.test
  walfault.test  walbak.test  journal2.test    tkt-9d68c883.test

Added test/shmlock.test.



























































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
# 2018 December 6
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl

set testprefix shmlock

ifcapable !wal {finish_test ; return }

sqlite3 db2 test.db
sqlite3 db3 test.db

do_execsql_test 1.0 {
  PRAGMA journal_mode = wal;
  CREATE TABLE t1(a, b);
  INSERT INTO t1 VALUES(1, 2);
} {wal}
do_test 1.1 { execsql { SELECT * FROM t1 } db2 } {1 2}
do_test 1.2 { execsql { SELECT * FROM t1 } db3 } {1 2}

foreach {tn dbhandle cmd res} {
  1    db  {shared    lock   7 1}    OK
  2    db2 {exclusive lock   7 1}    BUSY
  3    db  {shared    unlock 7 1}    OK
  4    db2 {exclusive lock   7 1}    OK
  5    db  {shared    lock   7 1}    BUSY
  6    db  {exclusive lock   7 1}    BUSY
  7    db2 {exclusive unlock 7 1}    OK

  8    db  {exclusive lock   0 8}    OK
  9    db  {exclusive unlock 0 8}    OK
  10   db2 {exclusive lock   0 8}    OK
  11   db2 {exclusive unlock 0 8}    OK

  12   db  {shared    lock   0 1}    OK
  13   db2 {shared    lock   0 1}    OK
  14   db3 {shared    lock   0 1}    OK
  15   db3 {shared    unlock 0 1}    OK
  16   db3 {exclusive lock   0 1}    BUSY
  17   db2 {shared    unlock 0 1}    OK
  18   db3 {exclusive lock   0 1}    BUSY
  19   db  {shared    unlock 0 1}    OK
  20   db3 {exclusive lock   0 1}    OK
  21   db3 {exclusive unlock 0 1}    OK

  22   db  {shared    lock   3 1}    OK
  23   db2 {exclusive lock   2 2}    BUSY
  24   db  {shared    lock   2 1}    OK
  25   db2 {exclusive lock   0 5}    BUSY
  26   db2 {exclusive lock   0 4}    BUSY
  27   db2 {exclusive lock   0 3}    BUSY
  28   db  {shared    unlock 3 1}    OK
  29   db2 {exclusive lock   2 2}    BUSY
  28   db  {shared    unlock 2 1}    OK
  29   db2 {exclusive lock   2 2}    OK
  29   db2 {exclusive unlock 2 2}    OK
} {
  do_test 1.3.$tn [list vfs_shmlock $dbhandle main {*}$cmd] "SQLITE_$res"
}

db  close
db2 close
db3 close

if {[permutation]=="unix-excl"} {
  do_test 2.0 {
    for {set i 0} {$i < 256} {incr i} { 
      sqlite3 db$i test.db 
      execsql { SELECT * FROM t1 } db$i
    }
    for {set i 0} {$i < 255} {incr i} { 
      set rc [vfs_shmlock db$i main shared lock 4 1]
      if {$rc != "SQLITE_OK"} { error $rc }
    }

    vfs_shmlock db255 main shared lock 4 1
  } {SQLITE_BUSY}

  do_test 2.1 { vfs_shmlock db255 main exclusive lock   4 1 } SQLITE_BUSY
  do_test 2.2 { vfs_shmlock db0   main shared    unlock 4 1 } SQLITE_OK
  do_test 2.3 { vfs_shmlock db255 main shared    lock   4 1 } SQLITE_OK
  do_test 2.4 { vfs_shmlock db255 main shared    unlock 4 1 } SQLITE_OK
  do_test 2.5 { vfs_shmlock db255 main exclusive lock   4 1 } SQLITE_BUSY

  do_test 2.6 {
    for {set i 1} {$i < 255} {incr i} { 
      set rc [vfs_shmlock db255 main exclusive lock 4 1]
      if {$rc != "SQLITE_BUSY"} { error $rc }
      set rc [vfs_shmlock db$i main shared unlock 4 1]
      if {$rc != "SQLITE_OK"} { error $rc }
    }

    vfs_shmlock db255 main exclusive lock 4 1
  } {SQLITE_OK}

  vfs_shmlock db255 main exclusive unlock 4 1

  for {set i 0} {$i < 256} {incr i} {
    db$i close
  }
}

sqlite3 db0 test.db
sqlite3 db1 test.db
do_test 3.1 { execsql { SELECT * FROM t1 } db0 } {1 2}
do_test 3.2 { execsql { SELECT * FROM t1 } db1 } {1 2}

set L(0) {n n n n n n n n}
set L(1) {n n n n n n n n}
proc random_lock_test {idx} {
  global L
  set iSlot [expr int(rand()*8)]
  if {[expr int(rand()*2)]} {
    # Unlock operation
    if {[lindex $L($idx) $iSlot]!="n"} {
      vfs_shmlock db$idx main [lindex $L($idx) $iSlot] unlock $iSlot 1
      lset L($idx) $iSlot n
    }
  } else {
    # Lock operation
    if {[lindex $L($idx) $iSlot]=="n"} {
      set locktype [lindex {e s} [expr int(rand()*2)]]
      set n 1
      if {$locktype=="e"} {
        for {set l $iSlot} {$l<8 && [lindex $L($idx) $l]=="n"} {incr l} {}
        set n [expr int(rand()*($l-$iSlot))+1]
        # puts "iSlot=$iSlot l=$l L=$L($idx)"
        # puts "$iSlot $n"
      }
      set res [vfs_shmlock db$idx main $locktype lock $iSlot $n]

      set bBusy 0
      for {set i $iSlot} {$i<($iSlot+$n)} {incr i} {
        set other [lindex $L([expr ($idx+1)%2]) $i]
        if {($other!="n" && $locktype=="e")||($other=="e" && $locktype=="s")} {
          if {$res != "SQLITE_BUSY"} { error "BUSY not detected" }
          set bBusy 1
          break
        } 
      }

      if {$bBusy==0} {
        if {$res != "SQLITE_OK"} { error "BUSY false-positive" }
        for {set i $iSlot} {$i<($iSlot+$n)} {incr i} {
          lset L($idx) $i $locktype
        }
      }
    }
  }
}

set nStep 100000
for {set i 0} {$i < $nStep} {incr i} {
  random_lock_test 0
  random_lock_test 1
}

db0 close
db1 close

finish_test


Changes to test/snapshot_fault.test.

217
218
219
220
221
222
223


224










225













226
  db eval COMMIT
} -body {
  sqlite3_snapshot_recover db main
} -test {
  faultsim_test_result {0 {}} {1 SQLITE_IOERR}
}




























finish_test







>
>
|
>
>
>
>
>
>
>
>
>
>

>
>
>
>
>
>
>
>
>
>
>
>
>

217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
  db eval COMMIT
} -body {
  sqlite3_snapshot_recover db main
} -test {
  faultsim_test_result {0 {}} {1 SQLITE_IOERR}
}

#-------------------------------------------------------------------------
# Test the handling of faults that occur within sqlite3_snapshot_get().
#
reset_db
do_execsql_test 5.0 {
  PRAGMA page_size = 512;
  PRAGMA journal_mode = wal;
  PRAGMA wal_autocheckpoint = 0;
  CREATE TABLE t1(zzz);
  INSERT INTO t1 VALUES(randomblob( 5000 ));
  PRAGMA user_version = 211;
} {wal 0}
faultsim_save_and_close

do_faultsim_test 5 -prep {
  faultsim_restore_and_reopen
  execsql { SELECT count(*) FROM sqlite_master }
  execsql BEGIN
} -body {
  sqlite3_snapshot_get_blob db main
  set {} {}
} -test {
  execsql END
  faultsim_test_result {0 {}} {1 SQLITE_IOERR} {1 SQLITE_NOMEM}
}


finish_test

Added test/vtabdrop.test.































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
# 2018 December 28
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
#
# The tests in this file test edge cases surrounding DROP TABLE on 
# virtual tables.
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl

ifcapable !vtab { finish_test ; return }
source $testdir/fts3_common.tcl
source $testdir/malloc_common.tcl

set testprefix vtabdrop

#-------------------------------------------------------------------------
# Test that if a DROP TABLE is executed against an rtree table, but the
# xDestroy() call fails, the rtree table is not dropped, the sqlite_master
# table is not modified and the internal schema remains intact.
# 
ifcapable rtree {
  do_execsql_test 1.0 {
    CREATE VIRTUAL TABLE rt USING rtree(id, x1, x2);
    CREATE TABLE t1(x, y);
    INSERT INTO t1 VALUES(1, 2);
  }
  
  do_test 1.1 {
    execsql {
      BEGIN;
        INSERT INTO t1 VALUES(3, 4);
    }
    db eval { SELECT * FROM t1 } {
      catchsql { DROP TABLE rt }
    }
    execsql COMMIT
  } {}
  
  do_execsql_test 1.2 {
    SELECT name FROM sqlite_master ORDER BY 1;
    SELECT * FROM t1;
    SELECT * FROM rt;
  } {rt rt_node rt_parent rt_rowid t1 1 2 3 4}
  
  db close
  sqlite3 db test.db
  
  do_execsql_test 1.3 {
    SELECT name FROM sqlite_master ORDER BY 1;
  } {rt rt_node rt_parent rt_rowid t1}
}

#-------------------------------------------------------------------------
# Same as tests 1.*, except with fts5 instead of rtree.
# 
ifcapable fts5 {
  reset_db
  do_execsql_test 2.0 {
    CREATE VIRTUAL TABLE ft USING fts5(x);
    CREATE TABLE t1(x, y);
    INSERT INTO t1 VALUES(1, 2);
  }
  
  do_test 2.1 {
    execsql {
      BEGIN;
        INSERT INTO t1 VALUES(3, 4);
    }
    db eval { SELECT * FROM t1 } {
      catchsql { DROP TABLE ft }
    }
    execsql COMMIT
  } {}
  
  do_execsql_test 2.2 {
    SELECT name FROM sqlite_master ORDER BY 1;
  } {ft ft_config ft_content ft_data ft_docsize ft_idx t1}
  
  db close
  sqlite3 db test.db
  
  do_execsql_test 2.3 {
    SELECT name FROM sqlite_master ORDER BY 1;
  } {ft ft_config ft_content ft_data ft_docsize ft_idx t1}
}

#-------------------------------------------------------------------------
# Same as tests 1.*, except with fts3 instead of rtree.
# 
ifcapable fts3 {
  reset_db
  do_execsql_test 2.0 {
    CREATE VIRTUAL TABLE ft USING fts3(x);
    CREATE TABLE t1(x, y);
    INSERT INTO t1 VALUES(1, 2);
  }
  
  do_test 2.1 {
    execsql {
      BEGIN;
        INSERT INTO t1 VALUES(3, 4);
    }
    db eval { SELECT * FROM t1 } {
      catchsql { DROP TABLE ft }
    }
    execsql COMMIT
  } {}
  
  do_execsql_test 2.2 {
    SELECT name FROM sqlite_master ORDER BY 1;
  } {ft ft_content ft_segdir ft_segments sqlite_autoindex_ft_segdir_1 t1}
  
  db close
  sqlite3 db test.db
  
  do_execsql_test 2.3 {
    SELECT name FROM sqlite_master ORDER BY 1;
  } {ft ft_content ft_segdir ft_segments sqlite_autoindex_ft_segdir_1 t1}
}

finish_test

Changes to test/wal.test.

1293
1294
1295
1296
1297
1298
1299

1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344

1345
1346
1347
1348
1349
1350
1351
#
#   3. Using connection 1, checkpoint the database. Make sure all
#      the data is present and the database is not corrupt.
#
# At one point, SQLite was failing to grow the mapping of the wal-index
# file in step 3 and the checkpoint was corrupting the database file.
#

do_test wal-20.1 {
  catch {db close}
  forcedelete test.db test.db-wal test.db-journal
  sqlite3 db test.db
  execsql {
    PRAGMA journal_mode = WAL;
    CREATE TABLE t1(x);
    INSERT INTO t1 VALUES(randomblob(900));
    SELECT count(*) FROM t1;
  }
} {wal 1}
do_test wal-20.2 {
  set ::buddy [launch_testfixture]
  testfixture $::buddy {
    sqlite3 db test.db
    db transaction { db eval {
      PRAGMA wal_autocheckpoint = 0;
      INSERT INTO t1 SELECT randomblob(900) FROM t1;       /* 2 */
      INSERT INTO t1 SELECT randomblob(900) FROM t1;       /* 4 */
      INSERT INTO t1 SELECT randomblob(900) FROM t1;       /* 8 */
      INSERT INTO t1 SELECT randomblob(900) FROM t1;       /* 16 */
      INSERT INTO t1 SELECT randomblob(900) FROM t1;       /* 32 */
      INSERT INTO t1 SELECT randomblob(900) FROM t1;       /* 64 */
      INSERT INTO t1 SELECT randomblob(900) FROM t1;       /* 128 */
      INSERT INTO t1 SELECT randomblob(900) FROM t1;       /* 256 */
      INSERT INTO t1 SELECT randomblob(900) FROM t1;       /* 512 */
      INSERT INTO t1 SELECT randomblob(900) FROM t1;       /* 1024 */
      INSERT INTO t1 SELECT randomblob(900) FROM t1;       /* 2048 */
      INSERT INTO t1 SELECT randomblob(900) FROM t1;       /* 4096 */
      INSERT INTO t1 SELECT randomblob(900) FROM t1;       /* 8192 */
      INSERT INTO t1 SELECT randomblob(900) FROM t1;       /* 16384 */
    } }
  }
} {0}
do_test wal-20.3 {
  close $::buddy
  execsql { PRAGMA wal_checkpoint }
  execsql { SELECT count(*) FROM t1 }
} {16384}
do_test wal-20.4 {
  db close
  sqlite3 db test.db
  execsql { SELECT count(*) FROM t1 }
} {16384}
integrity_check wal-20.5


catch { db2 close }
catch { db close }

do_test wal-21.1 {
  faultsim_delete_and_reopen
  execsql { 







>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>







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

catch { db2 close }
catch { db close }

do_test wal-21.1 {
  faultsim_delete_and_reopen
  execsql { 

Added test/walfault2.test.





















































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# 2010 May 03
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is testing the operation of the library in
# "PRAGMA journal_mode=WAL" mode.
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
source $testdir/malloc_common.tcl
source $testdir/lock_common.tcl

ifcapable !wal {finish_test ; return }
set testprefix walfault2

#-------------------------------------------------------------------------
# Inject faults while truncating the wal file.
#
do_execsql_test 1.0 {
  PRAGMA auto_vacuum = 0;
  CREATE TABLE t1(a, b);
  PRAGMA journal_mode = wal;
  WITH s(i) AS (
    SELECT 1 UNION ALL SELECT i+1 FROM s LIMIT 30
  )
  INSERT INTO t1 SELECT randomblob(400), randomblob(400) FROM s;
} {wal}
faultsim_save_and_close

do_faultsim_test 1 -prep {
  faultsim_restore
  sqlite3 db file:test.db?psow=0 -uri 1
  file_control_powersafe_overwrite db 0
  execsql {
    PRAGMA wal_checkpoint;
    PRAGMA journal_size_limit = 10000;
    PRAGMA synchronous = full;
  }
} -body {
  execsql { INSERT INTO t1 VALUES(1,1) }
} -test {
  faultsim_test_result {0 {}}
}

#-------------------------------------------------------------------------
# Inject faults while rewriting checksums.
#
reset_db
do_execsql_test 2.0 {
  PRAGMA auto_vacuum = 0;
  CREATE TABLE t1(a, b);
  PRAGMA journal_mode = wal;
  WITH s(i) AS (
    SELECT 1 UNION ALL SELECT i+1 FROM s LIMIT 30
  )
  INSERT INTO t1 SELECT randomblob(400), randomblob(400) FROM s;
} {wal}
faultsim_save_and_close

do_faultsim_test 2 -prep {
  faultsim_restore_and_reopen
  execsql {
    PRAGMA cache_size = 2;
    BEGIN;
    UPDATE t1 SET a=randomblob(400);
    UPDATE t1 SET b=randomblob(400);
    UPDATE t1 SET a=randomblob(400);
    UPDATE t1 SET b=randomblob(400);
    UPDATE t1 SET a=randomblob(400);
    UPDATE t1 SET b=randomblob(400);
    UPDATE t1 SET a=randomblob(400);
    UPDATE t1 SET b=randomblob(400);
  }
} -body {
  execsql COMMIT
} -test {
  faultsim_test_result {0 {}}
}



finish_test

Changes to test/walvfs.test.

28
29
30
31
32
33
34

35
36
37
38
39
40
41
...
101
102
103
104
105
106
107


108
109
110
111
112
113
114
...
133
134
135
136
137
138
139

















140
141
142
143
144
145
146
...
178
179
180
181
182
183
184



185


























































































































































































































186
187

tvfs filter xSync
set ::sync_count 0
proc xSync {method file args} {
  if {[file tail $file]=="test.db-wal"} {
    incr ::sync_count
  }
}


#-------------------------------------------------------------------------
# Test that if IOCAP_SEQUENTIAL is set, the wal-header is not synced to
# disk immediately after it is written.
#
sqlite3 db test.db -vfs tvfs
do_execsql_test 1.0 {
................................................................................
    INSERT INTO t1 VALUES(randomblob(750));
  }
  file size test.db-wal
} {8000}

#-------------------------------------------------------------------------
# Test that a checkpoint may be interrupted using sqlite3_interrupt().


#
reset_db
db close
sqlite3 db test.db -vfs tvfs
tvfs filter {}

do_execsql_test 3.0 {
................................................................................
  return SQLITE_OK
}

do_catchsql_test 3.1 {
  PRAGMA wal_checkpoint
} {1 interrupted}


















#-------------------------------------------------------------------------
#
reset_db
db close
do_test 4.0 {
  sqlite3 db test.db -vfs tvfs
  execsql {
................................................................................
  }
  return SQLITE_OK
}
do_catchsql_test 4.2 {
  SELECT count(*) FROM t1
} {1 {attempt to write a readonly database}}




db close


























































































































































































































tvfs delete
finish_test








>







 







>
>







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


>
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
...
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
...
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
...
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
tvfs filter xSync
set ::sync_count 0
proc xSync {method file args} {
  if {[file tail $file]=="test.db-wal"} {
    incr ::sync_count
  }
}


#-------------------------------------------------------------------------
# Test that if IOCAP_SEQUENTIAL is set, the wal-header is not synced to
# disk immediately after it is written.
#
sqlite3 db test.db -vfs tvfs
do_execsql_test 1.0 {
................................................................................
    INSERT INTO t1 VALUES(randomblob(750));
  }
  file size test.db-wal
} {8000}

#-------------------------------------------------------------------------
# Test that a checkpoint may be interrupted using sqlite3_interrupt().
# And that the error code is SQLITE_NOMEM, not SQLITE_INTERRUPT, if
# an OOM error occurs just before the sqlite3_interrupt() call.
#
reset_db
db close
sqlite3 db test.db -vfs tvfs
tvfs filter {}

do_execsql_test 3.0 {
................................................................................
  return SQLITE_OK
}

do_catchsql_test 3.1 {
  PRAGMA wal_checkpoint
} {1 interrupted}

set ::cnt 2
proc xWrite {method file args} {
  if {[file tail $file]=="test.db"} {
    incr ::cnt -1
    if {$::cnt==0} {
      sqlite3_memdebug_fail 5 -repeat 0
      catchsql { SELECT 'a big long string!' }
      sqlite3_interrupt db
    }
  }
  return SQLITE_OK
}

do_catchsql_test 3.2 {
  PRAGMA wal_checkpoint
} {1 {out of memory}}

#-------------------------------------------------------------------------
#
reset_db
db close
do_test 4.0 {
  sqlite3 db test.db -vfs tvfs
  execsql {
................................................................................
  }
  return SQLITE_OK
}
do_catchsql_test 4.2 {
  SELECT count(*) FROM t1
} {1 {attempt to write a readonly database}}

#-------------------------------------------------------------------------
#
reset_db
db close 
sqlite3 db test.db -vfs tvfs
tvfs filter {}
do_execsql_test 5.0 {
  PRAGMA auto_vacuum = 0;
  PRAGMA page_size = 1024;
  CREATE TABLE t1(x);
  PRAGMA journal_mode = wal;
  WITH s(i) AS (
      SELECT 1 UNION ALL SELECT i+1 FROM s LIMIT 20
  )
  INSERT INTO t1 SELECT randomblob(750) FROM s;
} {wal}

do_execsql_test 5.1 {
  SELECT count(*) FROM t1
} {20}

do_test 5.2 {
  vfs_set_readmark db main 1 100
  vfs_set_readmark db main 2 100
  vfs_set_readmark db main 3 100
  vfs_set_readmark db main 4 100
} {100}

do_execsql_test 5.3 {
  SELECT count(*) FROM t1
} {20}

do_test 5.3 {
  list [vfs_set_readmark db main 1] \
       [vfs_set_readmark db main 2] \
       [vfs_set_readmark db main 3] \
       [vfs_set_readmark db main 4] 
} {24 100 100 100}

tvfs script xShmLock
tvfs filter xShmLock
set ::cnt 20
proc xShmLock {args} {
  incr ::cnt -1
  if {$::cnt>0} { return SQLITE_BUSY }
  return SQLITE_OK
}

do_test 5.4 {
  vfs_set_readmark db main 1 100
  execsql { SELECT count(*) FROM t1 }
} {20}

vfs_set_readmark db main 1 100
vfs_set_readmark db main 2 100
vfs_set_readmark db main 3 100
vfs_set_readmark db main 4 100

tvfs script xShmMapLock
tvfs filter {xShmLock xShmMap}
proc xShmMapLock {method args} {
  if {$method=="xShmMap"} {
    return "SQLITE_READONLY"
  }
  return SQLITE_BUSY
}

sqlite3 db2 test.db -vfs tvfs
breakpoint
do_test 5.5 {
  list [catch { execsql { SELECT count(*) FROM t1 } db2 } msg] $msg
} {1 {attempt to write a readonly database}}

tvfs filter {}
vfs_set_readmark db main 1 1

do_test 5.6 {
  list [catch { execsql { SELECT count(*) FROM t1 } db2 } msg] $msg
} {0 20}
db2 close
db close

#-------------------------------------------------------------------------
# Cause an SQLITE_PROTOCOL while attempting to restart the wal file.
#
reset_db
tvfs filter {}
db close
sqlite3 db test.db -vfs tvfs
do_execsql_test 6.0 {
  PRAGMA auto_vacuum = 0;
  PRAGMA page_size = 1024;
  CREATE TABLE t1(x);
  PRAGMA journal_mode = wal;
  WITH s(i) AS (
      SELECT 1 UNION ALL SELECT i+1 FROM s LIMIT 20
  )
  INSERT INTO t1 SELECT randomblob(750) FROM s;
} {wal}

do_test 6.1 {
  execsql { PRAGMA wal_checkpoint } 
  set {} {}
} {}

tvfs filter xShmLock
tvfs script xShmLock
set ::flag 0
proc xShmLock {method file handle spec} {
  if {$::flag && [lrange $spec 2 end]=="lock shared"} {
    return SQLITE_BUSY
  }
  if {$spec=="3 1 unlock shared"} {
    set ::flag 1
  }
  return SQLITE_OK
}

puts "# WARNING: This next test takes around 12 seconds"
do_catchsql_test 6.2 {
  INSERT INTO t1 VALUES(1);
} {1 {locking protocol}}

#-------------------------------------------------------------------------
# Check that a checkpoint fails if it cannot get the CHECKPOINTER lock
#
reset_db
tvfs filter {}
db close
sqlite3 db test.db -vfs tvfs
do_execsql_test 7.0 {
  PRAGMA auto_vacuum = 0;
  PRAGMA page_size = 1024;
  CREATE TABLE t1(x);
  PRAGMA journal_mode = wal;
  WITH s(i) AS (
      SELECT 1 UNION ALL SELECT i+1 FROM s LIMIT 20
  )
  INSERT INTO t1 SELECT randomblob(750) FROM s;
} {wal}

tvfs script xShmLock
tvfs filter xShmLock
proc xShmLock {method file handle spec} {
  if {$spec=="1 1 lock exclusive"} {
    return SQLITE_BUSY
  }
  return SQLITE_OK
}

do_execsql_test 7.1 {
  PRAGMA wal_checkpoint
} {1 -1 -1}

#-------------------------------------------------------------------------
# Check that the page cache is correctly flushed if a checkpointer using
# a version 2 VFS makes a checkpoint with an out-of-date cache.
#
reset_db
testvfs tvfs2 -iversion 2
db close
sqlite3 db test.db -vfs tvfs2
do_execsql_test 8.0 {
  PRAGMA auto_vacuum = 0;
  PRAGMA page_size = 1024;
  CREATE TABLE t1(x);
  PRAGMA journal_mode = wal;
  WITH s(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM s LIMIT 20 )
  INSERT INTO t1 SELECT randomblob(75) FROM s;
} {wal}

do_execsql_test 8.1 { SELECT count(*) FROM t1 } {20}

do_test 8.2 {
  sqlite3 db2 test.db -vfs tvfs2
  execsql {
    INSERT INTO t1 VALUES(randomblob(75));
  } db2
  db2 close
} {}

do_execsql_test 8.3 { 
  PRAGMA wal_checkpoint;
  SELECT count(*) FROM t1 
} {0 5 5 21}
tvfs2 delete

#-------------------------------------------------------------------------
reset_db
db close
sqlite3 db test.db -vfs tvfs
do_execsql_test 9.0 {
  PRAGMA auto_vacuum = 0;
  PRAGMA page_size = 1024;
  CREATE TABLE t1(x);
  PRAGMA journal_mode = wal;
  WITH s(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM s LIMIT 20 )
  INSERT INTO t1 SELECT randomblob(75) FROM s;
} {wal}

sqlite3 db2 test.db -vfs tvfs
tvfs filter {xShmMap xShmLock}
tvfs script xShmMap
proc xShmMap {method file handle args} {
  switch -- $method {
    xShmMap {
      return "SQLITE_READONLY_CANTINIT"
    }
    xShmLock {
      if {$args=="{3 1 lock shared}"} {
        return "SQLITE_IOERR"
      }
    }
  }
}

do_test 9.1 {
  catchsql { SELECT count(*) FROM t1 } db2
} {1 {disk I/O error}}

db close
db2 close
tvfs delete
finish_test

Changes to test/with1.test.

1039
1040
1041
1042
1043
1044
1045
1046



















1047
#
do_execsql_test 20.1 {
  WITH c(i)AS(VALUES(9)UNION SELECT~i FROM c)SELECT max(5)>i fROM c;
} {0}
do_execsql_test 20.2 {
  WITH c(i)AS(VALUES(5)UNIoN SELECT 0)SELECT min(1)-i fROM c;
} {1}




















finish_test








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
#
do_execsql_test 20.1 {
  WITH c(i)AS(VALUES(9)UNION SELECT~i FROM c)SELECT max(5)>i fROM c;
} {0}
do_execsql_test 20.2 {
  WITH c(i)AS(VALUES(5)UNIoN SELECT 0)SELECT min(1)-i fROM c;
} {1}

# 2018-12-26
# Two different CTE tables with the same name appear in within a single FROM
# clause due to the query-flattener optimization.  make sure this does not cause
# problems.  This problem was discovered by Matt Denton.
#
do_execsql_test 21.1 {
   WITH RECURSIVE t21(a,b) AS (
    WITH t21(x) AS (VALUES(1))
    SELECT x, x FROM t21 ORDER BY 1
  )
  SELECT * FROM t21 AS tA, t21 AS tB
} {1 1 1 1}
do_execsql_test 21.2 {
  SELECT printf('',
     EXISTS (WITH RECURSIVE Table0 AS (WITH Table0 AS (SELECT DISTINCT 1)
                                       SELECT *, * FROM Table0 ORDER BY 1 DESC)
             SELECT * FROM Table0  NATURAL JOIN  Table0));
} {{}}

finish_test

Changes to tool/dbtotxt.c.

108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
    if( pgsz<512 || (pgsz&(pgsz-1))!=0 ){
      fprintf(stderr, "Invalid page size in header: %d\n", pgsz);
      exit(1);
    }
  }
  zBaseName = zInputFile;
  for(i=0; zInputFile[i]; i++){
    if( zInputFile[i]=='/' && zInputFile[i+1]!=0 ) zBaseName = zInputFile+1;
  }
  printf("| size %d pagesize %d filename %s\n",(int)szFile,pgsz,zBaseName);
  for(i=0; i<szFile; i+=16){
    int got = (int)fread(aLine, 1, 16, in);
    if( got!=16 ){
      static int once = 1;
      if( once ){







|







108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
    if( pgsz<512 || (pgsz&(pgsz-1))!=0 ){
      fprintf(stderr, "Invalid page size in header: %d\n", pgsz);
      exit(1);
    }
  }
  zBaseName = zInputFile;
  for(i=0; zInputFile[i]; i++){
    if( zInputFile[i]=='/' && zInputFile[i+1]!=0 ) zBaseName = zInputFile+i+1;
  }
  printf("| size %d pagesize %d filename %s\n",(int)szFile,pgsz,zBaseName);
  for(i=0; i<szFile; i+=16){
    int got = (int)fread(aLine, 1, 16, in);
    if( got!=16 ){
      static int once = 1;
      if( once ){