SQLite

Check-in [5bf212f1a7]
Login

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

Overview
Comment:Merge latest trunk changes into this branch.
Timelines: family | ancestors | descendants | both | begin-concurrent
Files: files | file ages | folders
SHA3-256: 5bf212f1a754fde90af0af82dd76f636754829c7372e19df1fd4fa579f0926aa
User & Date: dan 2019-01-02 16:08:14.536
Context
2019-01-11
15:06
Add new documentation file begin_concurrent.md. (check-in: fdbf97e611 user: dan tags: begin-concurrent)
2019-01-02
16:08
Merge latest trunk changes into this branch. (check-in: 5bf212f1a7 user: dan tags: begin-concurrent)
16:01
Add another test case to vacuum-into.test. (check-in: 0465d2fc0d user: dan tags: trunk)
2018-12-29
20:42
Fix a problem causing a corrupt pager-cache if an OOM or IO error was encountered while committing a concurrent transacation. (check-in: 48ca30f9d7 user: dan tags: begin-concurrent)
Changes
Unified Diff Ignore Whitespace Patch
Changes to ext/expert/expert1.test.
239
240
241
242
243
244
245

246

247
248
249
250
251
252
253
254
  CREATE TABLE t7(a, b);
} {
  SELECT * FROM t7 WHERE a=? OR b=?
} {
  CREATE INDEX t7_idx_00000062 ON t7(b);
  CREATE INDEX t7_idx_00000061 ON t7(a);
  MULTI-INDEX OR

    SEARCH TABLE t7 USING INDEX t7_idx_00000061 (a=?) 

    SEARCH TABLE t7 USING INDEX t7_idx_00000062 (b=?)
}

# rowid terms.
#
do_setup_rec_test $tn.13.1 {
  CREATE TABLE t8(a, b);
} {







>
|
>
|







239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
  CREATE TABLE t7(a, b);
} {
  SELECT * FROM t7 WHERE a=? OR b=?
} {
  CREATE INDEX t7_idx_00000062 ON t7(b);
  CREATE INDEX t7_idx_00000061 ON t7(a);
  MULTI-INDEX OR
    INDEX 1
      SEARCH TABLE t7 USING INDEX t7_idx_00000061 (a=?) 
    INDEX 2
      SEARCH TABLE t7 USING INDEX t7_idx_00000062 (b=?)
}

# rowid terms.
#
do_setup_rec_test $tn.13.1 {
  CREATE TABLE t8(a, b);
} {
Changes to ext/fts3/fts3.c.
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
  }while( vu!=0 );
  q[-1] &= 0x7f;  /* turn off high bit in final byte */
  assert( q - (unsigned char *)p <= FTS3_VARINT_MAX );
  return (int) (q - (unsigned char *)p);
}

#define GETVARINT_STEP(v, ptr, shift, mask1, mask2, var, ret) \
  v = (v & mask1) | ( (*ptr++) << shift );                    \
  if( (v & mask2)==0 ){ var = v; return ret; }
#define GETVARINT_INIT(v, ptr, shift, mask1, mask2, var, ret) \
  v = (*ptr++);                                               \
  if( (v & mask2)==0 ){ var = v; return ret; }

/* 
** Read a 64-bit variable-length integer from memory starting at p[0].







|







334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
  }while( vu!=0 );
  q[-1] &= 0x7f;  /* turn off high bit in final byte */
  assert( q - (unsigned char *)p <= FTS3_VARINT_MAX );
  return (int) (q - (unsigned char *)p);
}

#define GETVARINT_STEP(v, ptr, shift, mask1, mask2, var, ret) \
  v = (v & mask1) | ( (*(ptr++)) << shift );  \
  if( (v & mask2)==0 ){ var = v; return ret; }
#define GETVARINT_INIT(v, ptr, shift, mask1, mask2, var, ret) \
  v = (*ptr++);                                               \
  if( (v & mask2)==0 ){ var = v; return ret; }

/* 
** Read a 64-bit variable-length integer from memory starting at p[0].
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
}

/*
** Similar to sqlite3Fts3GetVarint(), except that the output is truncated to 
** a non-negative 32-bit integer before it is returned.
*/
int sqlite3Fts3GetVarint32(const char *p, int *pi){

  u32 a;

#ifndef fts3GetVarint32
  GETVARINT_INIT(a, p, 0,  0x00,     0x80, *pi, 1);
#else
  a = (*p++);
  assert( a & 0x80 );
#endif

  GETVARINT_STEP(a, p, 7,  0x7F,     0x4000, *pi, 2);
  GETVARINT_STEP(a, p, 14, 0x3FFF,   0x200000, *pi, 3);
  GETVARINT_STEP(a, p, 21, 0x1FFFFF, 0x10000000, *pi, 4);
  a = (a & 0x0FFFFFFF );
  *pi = (int)(a | ((u32)(*p & 0x07) << 28));
  assert( 0==(a & 0x80000000) );
  assert( *pi>=0 );
  return 5;
}

/*
** Return the number of bytes required to encode v as a varint







>



|

|



|
|
|

|







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
}

/*
** Similar to sqlite3Fts3GetVarint(), except that the output is truncated to 
** a non-negative 32-bit integer before it is returned.
*/
int sqlite3Fts3GetVarint32(const char *p, int *pi){
  const unsigned char *ptr = (const unsigned char*)p;
  u32 a;

#ifndef fts3GetVarint32
  GETVARINT_INIT(a, ptr, 0,  0x00,     0x80, *pi, 1);
#else
  a = (*ptr++);
  assert( a & 0x80 );
#endif

  GETVARINT_STEP(a, ptr, 7,  0x7F,     0x4000, *pi, 2);
  GETVARINT_STEP(a, ptr, 14, 0x3FFF,   0x200000, *pi, 3);
  GETVARINT_STEP(a, ptr, 21, 0x1FFFFF, 0x10000000, *pi, 4);
  a = (a & 0x0FFFFFFF );
  *pi = (int)(a | ((u32)(*ptr & 0x07) << 28));
  assert( 0==(a & 0x80000000) );
  assert( *pi>=0 );
  return 5;
}

/*
** Return the number of bytes required to encode v as a varint
Changes to ext/fts3/fts3_unicode2.c.
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
    '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 ){







|







196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
    '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 ){
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
** 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.







|
|







227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
** 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.
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
  sqlite3_stmt *pStmt;

  assert( SizeofArray(azSql)==SizeofArray(p->aStmt) );
  assert( eStmt<SizeofArray(azSql) && eStmt>=0 );
  
  pStmt = p->aStmt[eStmt];
  if( !pStmt ){

    char *zSql;
    if( eStmt==SQL_CONTENT_INSERT ){
      zSql = sqlite3_mprintf(azSql[eStmt], p->zDb, p->zName, p->zWriteExprlist);
    }else if( eStmt==SQL_SELECT_CONTENT_BY_ROWID ){

      zSql = sqlite3_mprintf(azSql[eStmt], p->zReadExprlist);
    }else{
      zSql = sqlite3_mprintf(azSql[eStmt], p->zDb, p->zName);
    }
    if( !zSql ){
      rc = SQLITE_NOMEM;
    }else{
      rc = sqlite3_prepare_v3(p->db, zSql, -1, SQLITE_PREPARE_PERSISTENT,
                              &pStmt, NULL);
      sqlite3_free(zSql);
      assert( rc==SQLITE_OK || pStmt==0 );
      p->aStmt[eStmt] = pStmt;
    }
  }
  if( apVal ){
    int i;







>




>







|
<







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
  sqlite3_stmt *pStmt;

  assert( SizeofArray(azSql)==SizeofArray(p->aStmt) );
  assert( eStmt<SizeofArray(azSql) && eStmt>=0 );
  
  pStmt = p->aStmt[eStmt];
  if( !pStmt ){
    int f = SQLITE_PREPARE_PERSISTENT|SQLITE_PREPARE_NO_VTAB;
    char *zSql;
    if( eStmt==SQL_CONTENT_INSERT ){
      zSql = sqlite3_mprintf(azSql[eStmt], p->zDb, p->zName, p->zWriteExprlist);
    }else if( eStmt==SQL_SELECT_CONTENT_BY_ROWID ){
      f &= ~SQLITE_PREPARE_NO_VTAB;
      zSql = sqlite3_mprintf(azSql[eStmt], p->zReadExprlist);
    }else{
      zSql = sqlite3_mprintf(azSql[eStmt], p->zDb, p->zName);
    }
    if( !zSql ){
      rc = SQLITE_NOMEM;
    }else{
      rc = sqlite3_prepare_v3(p->db, zSql, -1, f, &pStmt, NULL);

      sqlite3_free(zSql);
      assert( rc==SQLITE_OK || pStmt==0 );
      p->aStmt[eStmt] = pStmt;
    }
  }
  if( apVal ){
    int i;
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
  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;
}

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
  const char *zRoot,              /* Buffer containing root node */
  int nRoot,                      /* Size of buffer containing root node */
  Fts3SegReader **ppReader        /* OUT: Allocated Fts3SegReader */
){
  Fts3SegReader *pReader;         /* Newly allocated SegReader object */
  int nExtra = 0;                 /* Bytes to allocate segment root node */





  assert( iStartLeaf<=iEndLeaf );
  if( iStartLeaf==0 ){
    nExtra = nRoot + FTS3_NODE_PADDING;
  }

  pReader = (Fts3SegReader *)sqlite3_malloc(sizeof(Fts3SegReader) + nExtra);
  if( !pReader ){
    return SQLITE_NOMEM;
  }
  memset(pReader, 0, sizeof(Fts3SegReader));
  pReader->iIdx = iAge;
  pReader->bLookup = bLookup!=0;
  pReader->iStartBlock = iStartLeaf;
  pReader->iLeafEndBlock = iEndLeaf;
  pReader->iEndBlock = iEndBlock;

  if( nExtra ){
    /* The entire segment is stored in the root node. */
    pReader->aNode = (char *)&pReader[1];
    pReader->rootOnly = 1;
    pReader->nNode = nRoot;
    memcpy(pReader->aNode, zRoot, nRoot);
    memset(&pReader->aNode[nRoot], 0, FTS3_NODE_PADDING);
  }else{
    pReader->iCurrentBlock = iStartLeaf-1;
  }
  *ppReader = pReader;
  return SQLITE_OK;
}







>
>
>
>
|




















|







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
  const char *zRoot,              /* Buffer containing root node */
  int nRoot,                      /* Size of buffer containing root node */
  Fts3SegReader **ppReader        /* OUT: Allocated Fts3SegReader */
){
  Fts3SegReader *pReader;         /* Newly allocated SegReader object */
  int nExtra = 0;                 /* Bytes to allocate segment root node */

  assert( zRoot!=0 || nRoot==0 );
#ifdef CORRUPT_DB
  assert( zRoot!=0 || CORRUPT_DB );
#endif

  if( iStartLeaf==0 ){
    nExtra = nRoot + FTS3_NODE_PADDING;
  }

  pReader = (Fts3SegReader *)sqlite3_malloc(sizeof(Fts3SegReader) + nExtra);
  if( !pReader ){
    return SQLITE_NOMEM;
  }
  memset(pReader, 0, sizeof(Fts3SegReader));
  pReader->iIdx = iAge;
  pReader->bLookup = bLookup!=0;
  pReader->iStartBlock = iStartLeaf;
  pReader->iLeafEndBlock = iEndLeaf;
  pReader->iEndBlock = iEndBlock;

  if( nExtra ){
    /* The entire segment is stored in the root node. */
    pReader->aNode = (char *)&pReader[1];
    pReader->rootOnly = 1;
    pReader->nNode = nRoot;
    if( nRoot ) memcpy(pReader->aNode, zRoot, nRoot);
    memset(&pReader->aNode[nRoot], 0, FTS3_NODE_PADDING);
  }else{
    pReader->iCurrentBlock = iStartLeaf-1;
  }
  *ppReader = pReader;
  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
    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"
  }







>





|

|







59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
    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"
  }
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
  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 {} {







|
|







131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
  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 {} {
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
  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) ){







|







696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
  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) ){
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
        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;







|







779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
        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
        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]);
      }
    }
    p->rc = rc;
    p->nRead++;
  }








>







686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
        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++;
  }

725
726
727
728
729
730
731
732

733
734
735
736
737
738
739
  Fts5Index *p,
  sqlite3_stmt **ppStmt,
  char *zSql
){
  if( p->rc==SQLITE_OK ){
    if( zSql ){
      p->rc = sqlite3_prepare_v3(p->pConfig->db, zSql, -1,
                                 SQLITE_PREPARE_PERSISTENT, ppStmt, 0);

    }else{
      p->rc = SQLITE_NOMEM;
    }
  }
  sqlite3_free(zSql);
  return p->rc;
}







|
>







726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
  Fts5Index *p,
  sqlite3_stmt **ppStmt,
  char *zSql
){
  if( p->rc==SQLITE_OK ){
    if( zSql ){
      p->rc = sqlite3_prepare_v3(p->pConfig->db, zSql, -1,
          SQLITE_PREPARE_PERSISTENT|SQLITE_PREPARE_NO_VTAB,
          ppStmt, 0);
    }else{
      p->rc = SQLITE_NOMEM;
    }
  }
  sqlite3_free(zSql);
  return p->rc;
}
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
**
**     DELETE FROM %_data WHERE id BETWEEN $iFirst AND $iLast
*/
static void fts5DataDelete(Fts5Index *p, i64 iFirst, i64 iLast){
  if( p->rc!=SQLITE_OK ) return;

  if( p->pDeleter==0 ){
    int rc;
    Fts5Config *pConfig = p->pConfig;
    char *zSql = sqlite3_mprintf(
        "DELETE FROM '%q'.'%q_data' WHERE id>=? AND id<=?", 
          pConfig->zDb, pConfig->zName
    );
    if( zSql==0 ){
      rc = SQLITE_NOMEM;
    }else{
      rc = sqlite3_prepare_v3(pConfig->db, zSql, -1,
                              SQLITE_PREPARE_PERSISTENT, &p->pDeleter, 0);
      sqlite3_free(zSql);
    }
    if( rc!=SQLITE_OK ){
      p->rc = rc;
      return;
    }
  }

  sqlite3_bind_int64(p->pDeleter, 1, iFirst);
  sqlite3_bind_int64(p->pDeleter, 2, iLast);
  sqlite3_step(p->pDeleter);
  p->rc = sqlite3_reset(p->pDeleter);
}







<





<
<
<
<
|
<
<
<
<
<
<







768
769
770
771
772
773
774

775
776
777
778
779




780






781
782
783
784
785
786
787
**
**     DELETE FROM %_data WHERE id BETWEEN $iFirst AND $iLast
*/
static void fts5DataDelete(Fts5Index *p, i64 iFirst, i64 iLast){
  if( p->rc!=SQLITE_OK ) return;

  if( p->pDeleter==0 ){

    Fts5Config *pConfig = p->pConfig;
    char *zSql = sqlite3_mprintf(
        "DELETE FROM '%q'.'%q_data' WHERE id>=? AND id<=?", 
          pConfig->zDb, pConfig->zName
    );




    if( fts5IndexPrepareStmt(p, &p->pDeleter, zSql) ) return;






  }

  sqlite3_bind_int64(p->pDeleter, 1, iFirst);
  sqlite3_bind_int64(p->pDeleter, 2, iLast);
  sqlite3_step(p->pDeleter);
  p->rc = sqlite3_reset(p->pDeleter);
}
865
866
867
868
869
870
871





872
873
874
875
876
877
878
  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 ){







>
>
>
>
>







856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
  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 ){
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
      int iSeg;

      if( i>=nData ){
        rc = FTS5_CORRUPT;
      }else{
        i += fts5GetVarint32(&pData[i], pLvl->nMerge);
        i += fts5GetVarint32(&pData[i], nTotal);
        assert( nTotal>=pLvl->nMerge );
        pLvl->aSeg = (Fts5StructureSegment*)sqlite3Fts5MallocZero(&rc, 
            nTotal * sizeof(Fts5StructureSegment)
        );

      }

      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( rc!=SQLITE_OK ){
      fts5StructureRelease(pRet);
      pRet = 0;
    }
  }

  *ppOut = pRet;







|



>





>




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







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
      int iSeg;

      if( i>=nData ){
        rc = FTS5_CORRUPT;
      }else{
        i += fts5GetVarint32(&pData[i], pLvl->nMerge);
        i += fts5GetVarint32(&pData[i], nTotal);
        if( nTotal<pLvl->nMerge ) rc = FTS5_CORRUPT;
        pLvl->aSeg = (Fts5StructureSegment*)sqlite3Fts5MallocZero(&rc, 
            nTotal * sizeof(Fts5StructureSegment)
        );
        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( iLvl>0 && pLvl[-1].nMerge && nTotal==0 ) rc = FTS5_CORRUPT;
        if( iLvl==nLevel-1 && pLvl->nMerge ) rc = FTS5_CORRUPT;
      }
    }
    if( nSegment!=0 && rc==SQLITE_OK ) rc = FTS5_CORRUPT;

    if( rc!=SQLITE_OK ){
      fts5StructureRelease(pRet);
      pRet = 0;
    }
  }

  *ppOut = pRet;
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655

1656
1657
1658
1659
1660
1661
1662
*/
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;







|





>







1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
*/
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;
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
    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);
  }
}

/*







|







1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
    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);
  }
}

/*
2302
2303
2304
2305
2306
2307
2308

2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322




2323
2324
2325
2326
2327
2328
2329
      if( pIter->pLeaf==0 ) return;
      a = pIter->pLeaf->p;
      if( fts5LeafIsTermless(pIter->pLeaf)==0 ){
        iPgidx = pIter->pLeaf->szLeaf;
        iPgidx += fts5GetVarint32(&pIter->pLeaf->p[iPgidx], iOff);
        if( iOff<4 || iOff>=pIter->pLeaf->szLeaf ){
          p->rc = FTS5_CORRUPT;

        }else{
          nKeep = 0;
          iTermOff = iOff;
          n = pIter->pLeaf->nn;
          iOff += fts5GetVarint32(&a[iOff], nNew);
          break;
        }
      }
    }while( 1 );
  }

 search_success:

  pIter->iLeafOffset = iOff + nNew;




  pIter->iTermLeafOffset = pIter->iLeafOffset;
  pIter->iTermLeafPgno = pIter->iLeafPgno;

  fts5BufferSet(&p->rc, &pIter->term, nKeep, pTerm);
  fts5BufferAppendBlob(&p->rc, &pIter->term, nNew, &a[iOff]);

  if( iPgidx>=n ){







>












<

>
>
>
>







2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328

2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
      if( pIter->pLeaf==0 ) return;
      a = pIter->pLeaf->p;
      if( fts5LeafIsTermless(pIter->pLeaf)==0 ){
        iPgidx = pIter->pLeaf->szLeaf;
        iPgidx += fts5GetVarint32(&pIter->pLeaf->p[iPgidx], iOff);
        if( iOff<4 || iOff>=pIter->pLeaf->szLeaf ){
          p->rc = FTS5_CORRUPT;
          return;
        }else{
          nKeep = 0;
          iTermOff = iOff;
          n = pIter->pLeaf->nn;
          iOff += fts5GetVarint32(&a[iOff], nNew);
          break;
        }
      }
    }while( 1 );
  }

 search_success:

  pIter->iLeafOffset = iOff + nNew;
  if( pIter->iLeafOffset>n ){
    p->rc = FTS5_CORRUPT;
    return;
  }
  pIter->iTermLeafOffset = pIter->iLeafOffset;
  pIter->iTermLeafPgno = pIter->iLeafPgno;

  fts5BufferSet(&p->rc, &pIter->term, nKeep, pTerm);
  fts5BufferAppendBlob(&p->rc, &pIter->term, nNew, &a[iOff]);

  if( iPgidx>=n ){
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
      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( iSegid!=pStruct->aLevel[iLvl].aSeg[iSeg].iSegid );
        }
      }
      assert( iSegid>0 && iSegid<=FTS5_MAX_SEGMENT );

      {
        sqlite3_stmt *pIdxSelect = fts5IdxSelectStmt(p);
        if( p->rc==SQLITE_OK ){
          u8 aBlob[2] = {0xff, 0xff};
          sqlite3_bind_int(pIdxSelect, 1, iSegid);
          sqlite3_bind_blob(pIdxSelect, 2, aBlob, 2, SQLITE_STATIC);
          assert( sqlite3_step(pIdxSelect)!=SQLITE_ROW );
          p->rc = sqlite3_reset(pIdxSelect);
          sqlite3_bind_null(pIdxSelect, 2);
        }
      }
#endif
    }
  }







|






|





|


|







|







3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
      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 );
        }
      }
      assert_nc( iSegid>0 && iSegid<=FTS5_MAX_SEGMENT );

      {
        sqlite3_stmt *pIdxSelect = fts5IdxSelectStmt(p);
        if( p->rc==SQLITE_OK ){
          u8 aBlob[2] = {0xff, 0xff};
          sqlite3_bind_int(pIdxSelect, 1, iSegid);
          sqlite3_bind_blob(pIdxSelect, 2, aBlob, 2, SQLITE_STATIC);
          assert_nc( sqlite3_step(pIdxSelect)!=SQLITE_ROW );
          p->rc = sqlite3_reset(pIdxSelect);
          sqlite3_bind_null(pIdxSelect, 2);
        }
      }
#endif
    }
  }
3895
3896
3897
3898
3899
3900
3901

3902
3903
3904
3905
3906
3907
3908
  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 ){







>







3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
  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 ){
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
      ** 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]);







|





|







3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
      ** 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]);
5860
5861
5862
5863
5864
5865
5866
5867
5868
5869
5870
5871
5872
5873
5874
      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;
      }







|







5872
5873
5874
5875
5876
5877
5878
5879
5880
5881
5882
5883
5884
5885
5886
      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;
      }
6275
6276
6277
6278
6279
6280
6281
6282
6283
6284
6285
6286
6287
6288
6289
6290
  ** 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;







|
<







6287
6288
6289
6290
6291
6292
6293
6294

6295
6296
6297
6298
6299
6300
6301
  ** 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_storage.c.
132
133
134
135
136
137
138


139
140
141
142
143
144
145
146
147
        zSql = sqlite3_mprintf(azStmt[eStmt], pC->zDb, pC->zName);
        break;
    }

    if( zSql==0 ){
      rc = SQLITE_NOMEM;
    }else{


      rc = sqlite3_prepare_v3(pC->db, zSql, -1,
                              SQLITE_PREPARE_PERSISTENT, &p->aStmt[eStmt], 0);
      sqlite3_free(zSql);
      if( rc!=SQLITE_OK && pzErrMsg ){
        *pzErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(pC->db));
      }
    }
  }








>
>
|
<







132
133
134
135
136
137
138
139
140
141

142
143
144
145
146
147
148
        zSql = sqlite3_mprintf(azStmt[eStmt], pC->zDb, pC->zName);
        break;
    }

    if( zSql==0 ){
      rc = SQLITE_NOMEM;
    }else{
      int f = SQLITE_PREPARE_PERSISTENT;
      if( eStmt>FTS5_STMT_LOOKUP ) f |= SQLITE_PREPARE_NO_VTAB;
      rc = sqlite3_prepare_v3(pC->db, zSql, -1, f, &p->aStmt[eStmt], 0);

      sqlite3_free(zSql);
      if( rc!=SQLITE_OK && pzErrMsg ){
        *pzErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(pC->db));
      }
    }
  }

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
273
274
275
276
277
278
279
280
281
282
283
284
  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) ); 
          assert( (bTokenChars==0 || bTokenChars==1) );
          if( bToken!=bTokenChars && sqlite3Fts5UnicodeIsdiacritic(iCode)==0 ){
            int i;
            for(i=0; i<nNew; i++){
              if( aNew[i]>iCode ) break;
            }
            memmove(&aNew[i+1], &aNew[i], (nNew-i)*sizeof(int));
            aNew[i] = iCode;
            nNew++;
          }
        }
      }







|











|







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
  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) ); 
          assert( (bTokenChars==0 || bTokenChars==1) );
          if( bToken!=bTokenChars && sqlite3Fts5UnicodeIsdiacritic(iCode)==0 ){
            int i;
            for(i=0; i<nNew; i++){
              if( (u32)aNew[i]>iCode ) break;
            }
            memmove(&aNew[i+1], &aNew[i], (nNew-i)*sizeof(int));
            aNew[i] = iCode;
            nNew++;
          }
        }
      }
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
/*
** 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,







|







425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
/*
** 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,
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
  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;







|







454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
  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;
1280
1281
1282
1283
1284
1285
1286
1287
1288
        &aBuiltin[i].x,
        0
    );
  }

  return rc;
}









<
<
1280
1281
1282
1283
1284
1285
1286


        &aBuiltin[i].x,
        0
    );
  }

  return rc;
}


Changes to ext/fts5/fts5_unicode2.c.
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
    '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 ){







|







65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
    '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 ){
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
** 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.







|
|







96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
** 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.
244
245
246
247
248
249
250

251
252
253
254
255
256
257
  
  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;







>







244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
  
  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;
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
    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) ){







|







727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
    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) ){
769
770
771
772
773
774
775

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








>
770
771
772
773
774
775
776
777
    int n = (aFts5UnicodeData[iTbl] >> 5) + i;
    for(; i<128 && i<n; i++){
      aAscii[i] = bToken;
    }
    iTbl++;
  }
}

Changes to ext/fts5/test/fts5aa.test.
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
  t1_docsize {CREATE TABLE 't1_docsize'(id INTEGER PRIMARY KEY, sz BLOB)}
  t1_config {CREATE TABLE 't1_config'(k PRIMARY KEY, v) WITHOUT ROWID}
}

do_execsql_test 1.1 {
  DROP TABLE t1;
  SELECT name, sql FROM sqlite_master;
} {
}

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

do_execsql_test 2.0 {
  CREATE VIRTUAL TABLE t1 USING fts5(x, y, detail=%DETAIL%);
}







|
<







34
35
36
37
38
39
40
41

42
43
44
45
46
47
48
  t1_docsize {CREATE TABLE 't1_docsize'(id INTEGER PRIMARY KEY, sz BLOB)}
  t1_config {CREATE TABLE 't1_config'(k PRIMARY KEY, v) WITHOUT ROWID}
}

do_execsql_test 1.1 {
  DROP TABLE t1;
  SELECT name, sql FROM sqlite_master;
} {}


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

do_execsql_test 2.0 {
  CREATE VIRTUAL TABLE t1 USING fts5(x, y, detail=%DETAIL%);
}
Added ext/fts5/test/fts5circref.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
# 2018 Dec 22
#
# 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 script is testing the FTS5 module.
#

source [file join [file dirname [info script]] fts5_common.tcl]
set testprefix fts5circref

# If SQLITE_ENABLE_FTS5 is not defined, omit this file.
ifcapable !fts5 {
  finish_test
  return
}

do_execsql_test 1.0 {
  CREATE VIRTUAL TABLE tt USING fts5(a);
  SELECT name FROM sqlite_master ORDER BY 1;
} {
  tt tt_config tt_content tt_data tt_docsize tt_idx
}
db_save_and_close

foreach {tn schema sql} {
  1 {
    CREATE TRIGGER tr1 AFTER INSERT ON tt_config BEGIN
      SELECT * FROM tt;
    END;
  } {
    INSERT INTO tt(tt, rank) VALUES('usermerge', 4);
  }

  2 {
    CREATE TRIGGER tr1 AFTER INSERT ON tt_docsize BEGIN
      SELECT * FROM tt;
    END;
  } {
    INSERT INTO tt(a) VALUES('one two three');
  }

  3 {
    CREATE TRIGGER tr1 AFTER INSERT ON tt_content BEGIN
      SELECT * FROM tt;
    END;
  } {
    INSERT INTO tt(a) VALUES('one two three');
  }

  4 {
    CREATE TRIGGER tr1 AFTER INSERT ON tt_data BEGIN
      SELECT * FROM tt;
    END;
  } {
    INSERT INTO tt(a) VALUES('one two three');
  }

  5 {
    CREATE TRIGGER tr1 AFTER INSERT ON tt_idx BEGIN
      SELECT * FROM tt;
    END;
  } {
    INSERT INTO tt(a) VALUES('one two three');
  }
} {
  db_restore_and_reopen
  do_execsql_test 1.1.$tn.1 $schema
  do_catchsql_test 1.1.$tn.2 $sql {1 {SQL logic error}}
  db close
}


finish_test
Changes to ext/fts5/test/fts5corrupt3.test.
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
    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.







<
<







31
32
33
34
35
36
37


38
39
40
41
42
43
44
    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.
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
    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');







<
<







374
375
376
377
378
379
380


381
382
383
384
385
386
387
    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');
412
413
414
415
416
417
418

























































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































419
420

  append blob "450108"      ;# first segment
  execsql "REPLACE INTO t1_data VALUES(10, X'$blob')"
} {}
do_catchsql_test 9.2.2 {
  SELECT * FROM t1('one AND two');
} {1 {database disk image is malformed}}


























































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































sqlite3_fts5_may_be_corrupt 0
finish_test








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


>
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
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
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
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
  append blob "450108"      ;# first segment
  execsql "REPLACE INTO t1_data VALUES(10, X'$blob')"
} {}
do_catchsql_test 9.2.2 {
  SELECT * FROM t1('one AND two');
} {1 {database disk image is malformed}}

#-------------------------------------------------------------------------
reset_db
do_test 10.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
| size 32768 pagesize 4096 filename c9.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 04   ................
|     48: 00 00 00 00 00 00 00 00 00 00 00 01 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 06 36 b0 a0 10 21   ck.....ft..6...!
|   4064: d6 f7 07 46 96 d6 97 a6 05 01 03 00 10 03 03 0f   ...F............
|   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 62 6c 65 74 31 74 31 43 52 45 41 54 45 20   heblet1t1CREATE 
| page 8 offset 28672
|      0: 56 49 52 54 55 41 4c 20 54 41 42 4c 45 20 74 31   VIRTUAL TABLE t1
|     16: 20 55 53 49 4e 47 20 66 74 73 35 28 63 6f 6e 74    USING fts5(cont
|     32: 65 6e 74 29 0d 00 00 00 03 0f bd 00 0f e8 0f ef   ent)............
|     48: 0f bd 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
| end c9.db
  }]
} {}
do_catchsql_test 10.1 {
  SELECT * FROM t1 WHERE t1 MATCH 'abandon';
} {1 {database disk image is malformed}}

#-------------------------------------------------------------------------
#
reset_db
do_test 11.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
| size 28672 pagesize 4096 filename c10b.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 44 d9   (id INTEGER PRD.
|   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 06 0f 59 00 0f e8 0f ef 0f bd 0f b0   ......Y.........
|     16: 0f 73 0f 59 00 00 00 00 00 00 00 00 00 00 00 00   .s.Y............
|   3920: 00 00 00 00 00 00 00 00 00 13 84 80 80 80 80 04   ................
|   3936: 03 01 2a 0a 00 00 00 00 01 02 02 00 02 01 01 01   ..*.............
|   3952: 02 01 01 36 84 80 80 80 80 03 03 05 66 00 40 00   ...6........f.@.
|   3968: 00 00 01 00 00 00 29 07 30 61 63 74 69 76 65 04   ......).0active.
|   3984: 02 02 02 03 74 6f 6d 06 02 02 05 02 69 63 07 02   ....tom.....ic..
|   4000: 02 01 06 62 6f 6f 6d 65 72 05 02 02 04 0b 08 07   ...boomer.......
|   4016: 06 84 80 80 80 80 02 03 01 10 01 07 07 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 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 07 0f b6 00 0f f6 0f ec 0f e0 0f d5   ................
|     16: 0f ca 0f c1 0f b6 00 00 00 00 00 00 00 00 00 00   ................
|   4016: 00 00 00 00 00 00 09 07 03 00 19 61 74 6f 6d 69   ...........atomi
|   4032: 63 07 06 03 00 15 61 74 6f 6d 09 05 03 00 19 62   c.....atom.....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 07 0f d6 00 0f fa 0f f4 0f ee 0f e8   ................
|     16: 0f e2 0f dc 0f d6 00 00 00 00 00 00 00 00 00 00   ................
|   4048: 00 00 00 00 00 00 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 c10b.db
}]} {}

# This returns SQLITE_CONSTRAINT instead of SQLITE_CORRUPT. The problem is
# that the corrupted structure-record leads fts5 to try to use a segment-id
# that is already in use. This is caught by the PRIMARY KEY constraint on
# the %_idx table.
#
do_catchsql_test 11.1 {
  UPDATE t1 SET content='abc' WHERE content='boomer';
} {1 {constraint failed}}

#-------------------------------------------------------------------------
#
reset_db
do_test 12.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
| size 28672 pagesize 4096 filename c2.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 d8 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 00 01 01 01 20 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 3f e0   ..............?.
|     16: a0 30 30 01 b6 16 26 16 e6 46 f6 e0 80 20 30 01   .00...&..F... 0.
|     32: 76 16 26 16 67 40 80 10 30 01 76 16 26 16 36 b0   v.&.g@..0.v.&.6.
|     48: d0 00 00 00 30 fe e0 00 ff a0 ff 40 fe 00 00 00   ....0......@....
| page 5 offset 16384
|   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 c2.db
}]} {}

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

do_catchsql_test 11.2 {
  INSERT INTO t1(t1, rank) VALUES('merge', 500);
} {1 {vtable constructor failed: t1}}

#-------------------------------------------------------------------------
#
reset_db
do_test 13.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
| size 28672 pagesize 4096 filename c13.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 04   ................
|     48: 00 00 00 00 00 00 00 00 00 00 00 01 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 4f 69 64   ATE TABLE 't1Oid
|   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 eb 00 00 00 01 01 01 00 01 01 01   ...$............
| page 3 offset 8192
|      0: 01 0a 00 00 00 01 0f fa 00 0f fa 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 f2 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 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}}

#-------------------------------------------------------------------------
reset_db
do_test 21.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
| size 28672 pagesize 4096 filename c22b.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 0e 8e 00 06 0e 2f 00 0f e8 0e 2f 0f bd 0f 3b   ....../..../...;
|     16: 0e a5 0e 49 00 00 00 00 00 00 00 00 00 00 00 00   ...I............
|   3616: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 18   ................
|   3632: 0a 03 00 36 00 00 00 00 01 04 04 00 04 01 01 01   ...6............
|   3648: 02 01 01 03 01 01 04 01 01 3e 90 80 80 80 80 01   .........>......
|   3664: 04 00 81 00 00 00 00 36 06 30 62 61 63 6b 75 05   .......6.0backu.
|   3680: 02 04 05 02 04 02 05 65 61 6d 65 72 05 02 02 05   .......eamer....
|   3696: 02 02 02 05 6f 6f 6d 65 72 05 01 05 01 02 05 75   ....oomer......u
|   3712: 6d 6d 65 72 05 02 03 05 02 03 04 0d 0d 0b 0f 27   mmer...........'
|   3728: 00 17 30 00 00 00 00 01 03 03 00 03 01 01 01 02   ..0.............
|   3744: 01 01 03 01 01 7b 8c 80 80 80 80 01 04 00 81 7a   ...............z
|   3760: 00 00 00 6d 06 30 61 62 61 63 6b 0d 02 07 04 04   ...m.0aback.....
|   3776: 6e 64 6f 6e 0d 02 05 02 05 63 74 69 76 65 09 02   ndon.....ctive..
|   3792: 02 04 02 0b 02 04 6c 70 68 61 0d 04 02 0a 02 03   ......lpha......
|   3808: 74 6f 6d 0b 02 02 02 02 09 05 02 69 63 0c 02 02   tom........ic...
|   3824: 01 06 62 61 63 6b 75 70 0d 02 04 02 05 6f 6f 6d   ..backup.....oom
|   3840: 65 72 0a 02 02 03 02 08 01 07 63 68 61 6e 6e 65   er........channe
|   3856: 6c 0d 02 03 01 04 74 65 73 74 0d 02 06 04 0a 09   l.....test......
|   3872: 0d 0a 0b 07 0b 0d 0c 0f ef 00 14 2a 00 00 00 00   ...........*....
|   3888: 01 02 02 00 02 01 01 01 02 01 01 7b 88 80 80 80   ................
|   3904: 80 01 04 00 81 7a 00 00 00 6d 06 30 61 62 61 63   .....z...m.0abac
|   3920: 6b 08 02 07 04 04 6e 64 6f 6e 08 02 05 02 05 63   k.....ndon.....c
|   3936: 74 69 76 65 04 02 02 04 02 0b 02 04 6c 70 68 61   tive........lpha
|   3952: 08 04 02 0a 02 03 74 6f 6d 06 02 02 02 02 09 05   ......tom.......
|   3968: 02 69 63 07 02 02 01 06 62 61 63 6b 75 70 08 02   .ic.....backup..
|   3984: 04 02 05 6f 6f 6d 65 72 05 02 02 03 02 08 01 07   ...oomer........
|   4000: 63 68 61 6e 6e 65 6c 08 02 03 01 04 74 65 73 74   channel.....test
|   4016: 08 02 06 04 0a 09 0d 0a 0b 07 0b 0d 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 02 04 02 66 74 00 02 22 04 04 6e 64   ck.....ft.....nd
|   4064: 6f 6e 03 02 02 08 0a 07 05 01 03 00 10 0d 23 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 5a 00 0d 0e ce 00 0f f6 0f ec 0f e0 0f d5   ..Z.............
|     16: 0e e7 0f c1 0f b6 0f 70 0f 65 0e ce 0f 51 0f 46   .......p.e...Q.F
|     32: 0f 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
|   3776: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 17 0a   ................
|   3792: 03 00 35 62 65 61 6d 65 72 20 62 75 6d 6d 65 72   ..5beamer bummer
|   3808: 20 62 61 63 6b 75 29 17 05 03 00 35 62 65 61 6d    backu)....5beam
|   3824: 65 72 20 62 75 6d 6d 65 72 20 62 61 63 6b 75 29   er bummer backu)
|   3840: 44 0d 04 00 81 0d 61 6c 70 68 61 20 63 68 61 6e   D.....alpha chan
|   3856: 6e 65 6c 20 62 61 63 6b 75 70 20 61 62 61 6e 64   nel backup aband
|   3872: 6f 6e 20 74 65 73 74 20 61 62 61 63 6b 20 62 6f   on test aback bo
|   3888: 6f 6d 65 72 20 61 74 6f 6d 20 61 6c 70 68 61 20   omer atom alpha 
|   3904: 61 63 74 69 76 65 09 0c 03 00 19 61 74 6f 6d 69   active.....atomi
|   3920: 63 07 0b 03 00 15 61 74 6f 6d 0f ca 00 0b 19 62   c.....atom.....b
|   3936: 6f 6f 6d 65 72 09 09 03 00 19 61 63 74 69 76 65   oomer.....active
|   3952: 44 08 04 00 81 0d 61 6c 70 68 61 20 63 68 61 6e   D.....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 00 00 00 0b 19 62   c.....atom.....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 0d 0f b2 00 0f fa 0f f4 0f ee 0f e8   ................
|     16: 0f e2 0f dc 0f d6 0f d0 0f ca 0f c4 0f be 0f b8   ................
|     32: 0f b2 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
|   4016: 00 00 04 0d 03 00 0e 0a 04 0c 03 00 0e 01 04 0b   ................
|   4032: 03 00 0e 01 04 0a 03 00 0e 03 04 09 03 00 0e 01   ................
|   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 03 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 c22b.db
}]} {}

do_catchsql_test 21.1 {
  DELETE FROM t1 WHERE t1 MATCH 'ab*ndon';
} {1 {database disk image is malformed}}

#-------------------------------------------------------------------------
#
reset_db
do_test 22.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
| size 28672 pagesize 4096 filename c22b.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 02 00 00 00 07   .....@  ........
|     32: 00 00 00 00 00 00 00 00 00 00 00 02 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 02   ................
|     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 41 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: 75 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 15 00 05 08 4e 00 0f e8 08 4e 0f bd 0f 29   ......N....N...)
|     16: 08 65 00 00 00 00 00 00 00 00 00 00 00 00 00 00   .e..............
|   2112: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 15 0a   ................
|   2128: 03 00 30 00 00 00 00 01 03 02 01 03 01 01 01 02   ..0.............
|   2144: 01 01 03 01 01 8d 28 8c 80 80 80 80 01 04 00 9a   ......(.........
|   2160: 54 00 00 06 77 19 30 30 30 30 30 30 33 30 66 65   T...w.00000030fe
|   2176: 65 30 30 30 66 66 61 30 66 66 34 30 66 65 65 05   e000ffa0ff40fee.
|   2192: 02 19 02 0b 31 30 66 66 61 30 30 30 66 66 61 05   ....10ffa000ffa.
|   2208: 06 13 18 09 02 25 33 34 33 35 32 34 35 34 31 35   .....%3435245415
|   2224: 34 34 35 32 30 35 34 34 31 34 32 34 63 34 35 32   445205441424c452
|   2240: 30 32 37 37 34 33 31 35 66 36 39 05 02 07 02 37   02774315f69....7
|   2256: 34 30 33 30 33 30 30 30 65 30 31 30 34 30 32 30   40303000e0104020
|   2272: 33 30 30 30 65 30 31 30 34 30 31 30 33 30 30 30   3000e01040103000
|   2288: 65 30 31 30 61 30 30 30 30 30 30 30 31 30 66 66   e010a000000010ff
|   2304: 34 30 30 30 66 66 34 05 02 1b 02 27 35 30 34 30   4000ff4....'5040
|   2320: 39 30 63 30 31 30 32 30 64 30 30 30 30 30 30 30   90c01020d0000000
|   2336: 33 30 66 65 30 30 30 30 66 66 36 30 66 65 63 30   30fe0000ff60fec0
|   2352: 66 65 30 05 02 2c 27 02 66 30 05 02 16 02 1d 36   fe0..,'.f0.....6
|   2368: 31 37 31 31 31 31 30 38 36 33 37 34 36 31 36 32   1711110863746162
|   2384: 36 63 36 35 37 34 33 31 37 34 33 31 05 02 0d 02   6c6574317431....
|   2400: 29 39 30 33 30 32 31 62 37 32 36 35 36 32 37 35   )903021b72656275
|   2416: 36 34 36 31 37 34 36 31 37 34 33 31 35 66 36 34   6461746174315f64
|   2432: 36 31 37 34 36 31 30 32 34 33 05 02 1f 02 43 61   6174610243....Ca
|   2448: 30 33 30 33 30 30 31 62 36 31 36 32 36 31 36 65   0303001b6162616e
|   2464: 36 34 36 66 36 65 30 38 30 32 30 33 30 30 31 37   646f6e0802030017
|   2480: 36 31 36 32 36 31 36 36 37 34 30 38 30 31 30 33   6162616674080103
|   2496: 30 30 31 37 36 31 36 32 36 31 36 33 36 62 30 64   0017616261636b0d
|   2512: 30 30 05 02 18 34 1d 33 36 62 30 31 30 32 30 32   00...4.36b010202
|   2528: 30 34 30 32 36 36 37 34 30 32 30 32 30 32 30 34   0402667402020204
|   2544: 30 34 36 65 05 02 2e 02 33 62 30 33 31 62 30 31   046e....3b031b01
|   2560: 37 36 36 35 37 32 37 33 36 39 36 66 36 65 30 34   76657273696f6e04
|   2576: 30 64 30 30 30 30 30 30 30 33 30 66 64 36 30 30   0d000000030fd600
|   2592: 30 66 66 34 30 66 65 31 30 66 64 36 05 02 1d 01   0ff40fe10fd6....
|   2608: 04 31 66 62 64 05 04 10 18 01 01 32 05 02 14 02   .1fbd......2....
|   2624: 43 34 38 34 38 30 38 30 38 30 38 30 30 31 30 33   C484808080800103
|   2640: 30 30 34 65 30 30 30 30 30 30 31 65 30 36 33 30   004e0000001e0630
|   2656: 36 31 36 32 36 31 36 33 36 62 30 31 30 32 30 32   616261636b010202
|   2672: 30 34 30 32 36 36 37 34 30 32 30 32 30 32 30 34   0402667402020204
|   2688: 30 34 36 65 05 04 11 18 02 01 66 05 02 2a 03 02   046e......f..*..
|   2704: 65 72 05 02 31 01 08 33 35 32 38 36 33 36 66 05   er..1..3528636f.
|   2720: 02 24 02 03 66 65 30 05 04 17 18 01 2b 34 31 35   .$..fe0.....+415
|   2736: 32 35 39 32 30 34 62 34 35 35 39 32 63 32 30 36   259204b45592c206
|   2752: 32 36 63 36 66 36 33 36 62 32 30 34 32 34 63 34   26c6f636b20424c4
|   2768: 66 34 32 32 39 33 61 30 05 02 0c 2c 1f 31 30 36   f42293a0...,.106
|   2784: 31 37 31 31 31 31 30 38 36 33 37 34 36 31 36 32   1711110863746162
|   2800: 36 63 36 35 37 34 33 31 37 34 33 31 05 02 22 02   6c6574317431....
|   2816: 40 33 35 32 34 35 34 31 35 34 34 35 32 30 35 36   @352454154452056
|   2832: 34 39 35 32 35 34 37 35 34 31 34 63 32 30 35 34   49525475414c2054
|   2848: 34 31 34 32 34 63 34 35 32 30 37 34 33 31 32 30   41424c4520743120
|   2864: 35 35 35 33 34 39 34 65 34 37 32 30 36 36 37 34   5553494e47206674
|   2880: 37 05 02 23 42 09 33 33 35 32 38 36 33 36 66 05   7..#B.33528636f.
|   2896: 02 0e 02 03 66 65 65 05 02 1a 01 34 35 32 34 35   ....fee....45245
|   2912: 34 31 35 34 34 35 32 30 35 34 34 31 34 32 34 63   415445205441424c
|   2928: 34 35 32 30 32 37 37 34 33 31 35 66 36 34 36 31   45202774315f6461
|   2944: 37 34 36 31 32 37 32 38 36 39 36 34 32 30 34 39   7461272869642049
|   2960: 05 02 20 16 37 c3 b0 35 32 30 32 37 37 34 33 31   .. .7..520277431
|   2976: 35 66 36 34 36 31 37 34 36 31 32 37 32 38 36 39   5f64617461272869
|   2992: 36 34 32 30 34 39 34 65 35 34 34 35 34 37 34 35   6420494e54454745
|   3008: 35 32 32 30 35 30 35 32 34 39 34 64 05 02 0b 03   52205052494d....
|   3024: 48 35 39 32 30 34 62 34 35 35 39 32 63 32 30 36   H59204b45592c206
|   3040: 33 33 30 32 39 36 39 30 33 30 30 30 31 35 37 35   3302969030001575
|   3056: 33 31 31 39 32 36 64 37 34 36 31 36 32 36 63 36   311926d7461626c6
|   3072: 35 37 34 33 31 35 66 36 39 36 34 37 38 37 34 33   574315f696478743
|   3088: 31 35 66 36 39 36 34 37 38 05 02 06 02 38 34 32   15f696478....842
|   3104: 30 35 32 34 66 35 37 34 39 34 34 35 35 30 32 30   0524f57494455020
|   3120: 37 31 37 31 62 31 62 30 31 38 31 30 31 37 34 36   7171b1b018101746
|   3136: 31 36 32 36 63 36 35 37 34 33 31 35 66 31 37 34   1626c6574315f174
|   3152: 36 31 30 32 34 33 05 02 0a 02 03 66 66 34 05 02   610243.....ff4..
|   3168: 1c 01 4a 36 34 36 66 36 65 30 33 30 32 30 32 30   ..J646f6e0302020
|   3184: 34 30 61 30 37 30 35 30 31 30 33 30 30 31 30 30   40a0705010300100
|   3200: 33 30 33 30 66 30 61 30 33 30 30 32 34 30 30 30   3030f0a030024000
|   3216: 30 30 30 30 30 30 31 30 31 30 31 30 30 30 31 30   0000001010100010
|   3232: 31 30 31 30 30 39 61 30 30 30 30 30 30 05 02 2f   101009a000000../
|   3248: 42 09 31 30 61 30 30 30 30 30 30 05 02 28 08 43   B.10a000000..(.C
|   3264: 74 30 32 30 32 30 34 30 61 30 37 30 35 30 31 30   t0202040a0705010
|   3280: 33 30 30 31 30 30 33 30 33 30 66 30 61 30 33 30   3001003030f0a030
|   3296: 30 32 34 30 30 30 30 30 30 30 30 30 31 30 31 30   0240000000001010
|   3312: 31 30 30 30 31 30 31 30 31 30 31 30 61 30 30 30   100010101010a000
|   3328: 30 30 30 05 02 12 02 49 37 36 65 36 66 32 63 32   000....I76e6f2c2
|   3344: 30 35 30 35 32 34 39 34 64 34 31 35 32 35 39 32   05052494d4152592
|   3360: 30 34 62 34 35 35 39 32 38 37 33 36 35 36 37 36   04b4559287365676
|   3376: 39 36 34 32 63 32 30 37 34 36 35 37 32 36 64 32   9642c207465726d2
|   3392: 39 32 39 32 30 35 37 34 39 35 34 34 38 34 66 35   92920574954484f5
|   3408: 35 05 02 09 02 4c 39 37 61 36 35 37 34 33 31 35   5....L97a6574315
|   3424: 66 36 34 36 66 36 33 37 33 36 39 37 61 36 35 30   f646f6373697a650
|   3440: 35 34 33 35 32 34 35 34 31 35 34 34 35 32 30 35   5435245415445205
|   3456: 34 38 36 39 36 34 32 30 34 39 34 65 35 34 34 35   48696420494e5445
|   3472: 34 37 34 35 35 32 32 30 35 30 35 32 34 39 34 34   4745522050524944
|   3488: 64 31 05 02 05 02 27 65 37 34 36 35 36 65 37 34   d1....'e74656e74
|   3504: 32 39 30 64 30 30 30 30 30 30 30 33 30 66 62 64   290d000000030fbd
|   3520: 30 30 30 62 65 38 30 66 65 66 30 66 62 64 05 02   000be80fef0fbd..
|   3536: 0f 1e 0b 66 65 38 30 66 65 66 30 66 62 64 05 02   ...fe80fef0fbd..
|   3552: 25 02 03 66 64 36 05 02 1e 01 4a 37 36 32 39 32   %..fd6....J76292
|   3568: 30 35 37 34 39 35 34 34 38 34 66 35 35 35 34 32   0574954484f55542
|   3584: 30 35 32 34 66 35 37 34 39 34 34 35 62 30 35 30   0524f5749445b050
|   3600: 37 31 37 32 31 32 31 30 31 38 31 30 31 37 34 36   7172121018101746
|   3616: 31 36 32 36 63 36 35 37 34 33 31 35 66 36 34 36   1626c6574315f646
|   3632: 66 36 33 37 33 05 02 04 02 21 38 32 37 32 38 37   f6373....!827287
|   3648: 33 36 35 36 37 36 39 36 34 32 63 32 30 37 34 36   3656769642c20746
|   3664: 35 37 32 36 64 32 63 32 30 37 30 05 02 08 01 01   5726d2c2070.....
|   3680: 61 05 02 2b 01 06 62 61 63 6b 75 70 05 02 32 02   a..+..backup..2.
|   3696: 05 65 61 6d 65 72 05 02 02 02 05 6f 6f 6d 65 72   .eamer.....oomer
|   3712: 05 01 02 40 75 6d 6d 32 34 63 34 35 32 30 32 37   ...@umm24c452027
|   3728: 37 34 33 31 35 66 36 33 36 66 36 65 36 36 36 39   74315f636f6e6669
|   3744: 36 37 32 37 32 38 36 62 32 30 35 30 35 32 34 39   6727286b20505249
|   3760: 34 64 34 31 35 32 35 39 32 30 34 62 34 35 35 39   4d415259204b4559
|   3776: 32 63 32 30 05 02 03 01 15 65 35 34 34 35 34 37   2c20.....e544547
|   3792: 34 35 35 32 32 30 35 30 35 32 34 39 34 64 05 02   4552205052494d..
|   3808: 21 01 02 66 61 05 02 15 04 1d 12 2a 3c 2c 07 22   !..fa......*<,..
|   3824: 2e 48 22 38 0a 06 49 06 07 0d 09 30 24 45 0e 08   .H.8..I....0$E..
|   3840: 39 3c 4d 3d 08 4f 0e 48 4e 51 2c 10 08 4f 26 06   9<M=.O.HNQ,..O&.
|   3856: 0b 0a 09 45 1a 0f ef 00 14 2a 00 00 00 00 01 02   ...E.....*......
|   3872: 01 01 02 01 01 01 02 01 01 81 0c 88 80 80 80 80   ................
|   3888: 01 04 00 82 1c 00 00 00 7c 08 30 61 62 61 6e 64   ........|.0aband
|   3904: 6f 6e 08 02 05 02 05 63 74 69 76 65 04 02 02 04   on.....ctive....
|   3920: 02 0b 02 04 6c 70 68 61 08 04 02 0a 02 03 74 6b   ....lpha......tk
|   3936: 6d 06 02 02 03 02 6f 6d 08 02 09 05 02 69 63 07   m.....om.....ic.
|   3952: 02 02 01 06 62 61 63 6b 75 70 08 02 04 02 05 6f   ....backup.....o
|   3968: 6f 6d 65 72 05 02 02 01 0c 63 68 61 6e 6e 65 62   omer.....channeb
|   3984: 6f 6f 6d 65 72 08 02 08 07 01 6c 08 02 03 01 06   oomer.....l.....
|   4000: 73 74 61 61 63 6b 08 02 07 01 03 74 65 62 08 02   staack.....teb..
|   4016: 06 04 0c 0d 0a 08 07 07 0b 0a 11 06 0b 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 08 41 00   on............A.
|   4080: 00 00 11 24 00 00 00 00 01 01 00 01 01 01 01 01   ...$............
| page 3 offset 8192
|      0: 0a 00 00 00 03 0f ec 00 ff 00 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 ca 00 08 07 e1 00 0f f6 0f ec 0f e0 0f d5   ................
|     16: 07 e1 0f c1 0f b6 0f 6a 00 00 00 00 00 00 00 00   .......j........
|   2016: 00 8f 06 05 04 00 9e 11 62 65 61 6d 65 72 20 62   ........beamer b
|   2032: 75 6d 6d 32 34 63 34 35 32 30 32 37 37 34 33 31   umm24c4520277431
|   2048: 35 66 36 33 36 66 36 65 36 36 36 39 36 37 32 37   5f636f6e66696727
|   2064: 32 38 36 62 32 30 35 30 35 32 34 39 34 64 34 31   286b205052494d41
|   2080: 35 32 35 39 32 30 34 62 34 35 35 39 32 63 32 30   5259204b45592c20
|   2096: 0a 37 36 32 39 32 30 35 37 34 39 35 34 34 38 34   .762920574954484
|   2112: 66 35 35 35 34 32 30 35 32 34 66 35 37 34 39 34   f555420524f57494
|   2128: 34 35 62 30 35 30 37 31 37 32 31 32 31 30 31 38   45b0507172121018
|   2144: 31 30 31 37 34 36 31 36 32 36 63 36 35 37 34 33   1017461626c65743
|   2160: 31 35 66 36 34 36 66 36 33 37 33 0a 36 39 37 61   15f646f6373.697a
|   2176: 36 35 37 34 33 31 35 66 36 34 36 66 36 33 37 33   6574315f646f6373
|   2192: 36 39 37 61 36 35 30 35 34 33 35 32 34 35 34 31   697a650543524541
|   2208: 35 34 34 35 32 30 35 34 38 36 39 36 34 32 30 34   5445205486964204
|   2224: 39 34 65 35 34 34 35 34 37 34 35 35 32 32 30 35   94e5445474552205
|   2240: 30 35 32 34 39 34 34 64 31 0a 35 32 35 39 32 30   0524944d1.525920
|   2256: 34 62 34 35 35 39 32 63 32 30 36 33 33 30 32 39   4b45592c20633029
|   2272: 36 39 30 33 30 30 30 31 35 37 35 33 31 31 39 32   6903000157531192
|   2288: 36 64 37 34 36 31 36 32 36 63 36 35 37 34 33 31   6d7461626c657431
|   2304: 35 66 36 39 36 34 37 38 37 34 33 31 35 66 36 39   5f69647874315f69
|   2320: 36 34 37 38 0a 30 33 34 33 35 32 34 35 34 31 35   6478.03435245415
|   2336: 34 34 35 32 30 35 34 34 31 34 32 34 63 34 35 32   445205441424c452
|   2352: 30 32 37 37 34 33 31 35 66 36 39 01 0e 37 38 32   02774315f69..782
|   2368: 37 32 38 37 33 36 35 36 37 36 39 36 34 32 63 32   72873656769642c2
|   2384: 30 37 34 36 35 37 32 36 64 32 63 32 30 37 30 0a   07465726d2c2070.
|   2400: 36 37 36 65 36 66 32 63 32 30 35 30 35 32 34 39   676e6f2c20505249
|   2416: 34 64 34 31 35 32 35 39 32 30 34 62 34 35 35 39   4d415259204b4559
|   2432: 32 38 37 33 36 35 36 37 36 39 36 34 32 63 32 30   2873656769642c20
|   2448: 37 34 36 35 37 32 36 64 32 39 32 39 32 30 35 37   7465726d29292057
|   2464: 34 39 35 34 34 38 34 66 35 35 0a 35 34 32 30 35   4954484f55.54205
|   2480: 32 34 66 35 37 34 39 34 34 35 35 30 32 30 37 31   24f5749445502071
|   2496: 37 31 62 31 62 30 31 38 31 30 31 37 34 36 31 36   71b1b01810174616
|   2512: 32 36 63 36 35 37 34 33 31 35 66 31 37 34 36 31   26c6574315f17461
|   2528: 30 32 34 33 0a 35 32 34 35 34 31 35 34 34 35 32   0243.52454154452
|   2544: 30 35 34 34 31 34 32 34 63 34 c3 b0 35 32 30 32   05441424c4..5202
|   2560: 37 37 34 33 31 35 66 36 34 36 31 37 34 36 31 32   774315f646174612
|   2576: 37 32 38 36 39 36 34 32 30 34 39 34 65 35 34 34   728696420494e544
|   2592: 35 34 37 34 35 35 32 32 30 35 30 35 32 34 39 34   5474552205052494
|   2608: 64 0a 34 31 35 32 35 39 32 30 34 62 34 35 35 39   d.415259204b4559
|   2624: 32 63 32 30 36 32 36 63 36 66 36 33 36 62 32 30   2c20626c6f636b20
|   2640: 34 32 34 63 34 66 34 32 32 39 33 61 30 21 30 36   424c4f42293a0!06
|   2656: 31 37 31 31 31 31 30 38 36 33 37 34 36 31 36 32   1711110863746162
|   2672: 36 63 36 35 37 34 33 31 37 34 33 31 0a 34 33 35   6c6574317431.435
|   2688: 32 34 35 34 31 35 34 34 35 32 30 35 36 34 39 35   2454154452056495
|   2704: 32 35 34 37 35 34 31 34 63 32 30 35 34 34 31 34   25475414c2054414
|   2720: 32 34 63 34 35 32 30 37 34 33 31 32 30 35 35 35   24c4520743120555
|   2736: 33 34 39 34 65 34 37 32 30 36 36 37 34 37 33 33   3494e47206674733
|   2752: 35 32 38 36 33 36 66 0a 36 65 37 34 36 35 36 65   528636f.6e74656e
|   2768: 37 34 32 39 30 64 30 30 30 30 30 30 30 33 30 66   74290d000000030f
|   2784: 62 64 30 30 30 62 65 38 30 66 65 66 30 66 62 64   bd000be80fef0fbd
|   2800: 0a 5b 31 66 62 64 5d 32 34 38 34 38 30 38 30 38   .[1fbd]248480808
|   2816: 30 38 30 30 31 30 33 30 30 34 65 30 30 30 30 30   0800103004e00000
|   2832: 30 31 65 30 36 33 30 36 31 36 32 36 31 36 33 36   01e0630616261636
|   2848: 62 30 31 30 32 30 32 30 34 30 32 36 36 37 34 30   b010202040266740
|   2864: 32 30 32 30 32 30 34 30 34 36 65 0a 36 34 36 66   2020204046e.646f
|   2880: 36 65 30 54 30 32 30 32 30 34 30 61 30 37 30 35   6e0T0202040a0705
|   2896: 30 31 30 33 30 30 31 30 30 33 30 33 30 66 30 61   0103001003030f0a
|   2912: 30 33 30 30 32 34 30 30 30 30 30 30 30 30 30 31   0300240000000001
|   2928: 30 31 30 31 30 30 30 31 30 31 30 31 30 31 30 61   010100010101010a
|   2944: 30 30 30 30 30 30 0a 30 31 30 66 66 61 30 30 30   000000.010ffa000
|   2960: 66 66 61 0a 5b 32 21 66 61 5d 30 35 30 34 30 39   ffa.[2!fa]050409
|   2976: 30 63 30 31 30 32 30 64 30 30 30 30 30 30 30 33   0c01020d00000003
|   2992: 30 66 65 30 30 30 30 66 66 36 30 66 65 63 30 66   0fe0000ff60fec0f
|   3008: 66 30 0a 5b 33 66 65 30 5d 30 61 30 33 30 33 30   f0.[3fe0]0a03030
|   3024: 30 31 62 36 31 36 32 36 31 36 65 36 34 36 66 36   01b6162616e646f6
|   3040: 65 30 38 30 32 30 33 30 30 31 37 36 31 36 32 36   e080203001761626
|   3056: 31 36 36 37 34 30 38 30 31 30 33 30 30 31 37 36   1667408010300176
|   3072: 31 36 32 36 31 36 33 36 62 30 64 30 30 0a 30 30   16261636b0d00.00
|   3088: 30 30 30 33 30 66 65 65 30 30 30 66 66 61 30 66   00030fee000ffa0f
|   3104: 66 34 30 66 65 65 0a 5b 34 66 65 65 5d 30 34 30   f40fee.[4fee]040
|   3120: 33 30 33 30 30 30 65 30 31 30 34 30 32 30 33 30   303000e010402030
|   3136: 30 30 65 30 31 30 34 30 31 30 33 30 30 30 65 30   00e01040103000e0
|   3152: 31 30 61 30 30 30 30 30 30 30 31 30 66 66 34 30   10a000000010ff40
|   3168: 30 30 66 66 34 0a 5b 35 66 66 34 5d 30 62 30 33   00ff4.[5ff4]0b03
|   3184: 31 62 30 31 37 36 36 35 37 32 37 33 36 39 36 66   1b0176657273696f
|   3200: 36 65 30 34 30 64 30 30 30 30 30 30 30 33 30 66   6e040d000000030f
|   3216: 64 36 30 30 30 66 66 34 30 66 65 31 30 66 64 36   d6000ff40fe10fd6
|   3232: 0a 5b 36 66 64 36 5d 30 39 30 33 30 32 31 62 37   .[6fd6]0903021b7
|   3248: 32 36 35 36 32 37 35 36 34 36 31 37 34 36 31 37   2656275646174617
|   3264: 34 33 31 35 66 36 34 36 31 37 34 36 31 30 32 34   4315f64617461024
|   3280: 33 0a 35 32 34 35 34 31 35 34 34 35 32 30 35 34   3.52454154452054
|   3296: 34 31 34 32 34 63 34 35 32 30 32 37 37 34 33 31   41424c4520277431
|   3312: 35 66 36 34 36 31 37 34 36 31 32 37 32 38 36 39   5f64617461272869
|   3328: 36 34 32 30 34 39 c2 81 65 35 34 34 35 34 37 34   642049..e5445474
|   3344: 35 35 32 32 30 35 30 35 32 34 39 34 64 0a 34 31   552205052494d.41
|   3360: 35 32 35 39 32 30 34 62 34 35 35 39 32 63 32 30   5259204b45592c20
|   3376: 36 32 36 63 36 66 36 33 36 62 32 30 34 32 34 63   626c6f636b20424c
|   3392: 34 66 34 32 32 39 33 61 30 31 30 36 31 37 31 31   4f42293a01061711
|   3408: 31 31 30 38 36 33 37 34 36 31 36 32 36 63 36 35   1108637461626c65
|   3424: 37 34 33 31 37 34 33 31 0a 34 33 35 32 34 35 34   74317431.4352454
|   3440: 31 35 34 34 35 32 30 35 36 34 39 35 32 35 34 37   1544520564952547
|   3456: 35 34 31 34 63 32 30 35 34 34 31 34 32 34 63 34   5414c205441424c4
|   3472: 35 32 30 37 34 33 31 32 30 35 35 35 33 34 39 34   5207431205553494
|   3488: 65 34 37 32 30 36 36 37 34 37 3b 33 35 32 38 36   e472066747;35286
|   3504: 33 36 66 0a 36 65 37 34 36 35 36 65 37 34 32 39   36f.6e74656e7429
|   3520: 30 64 30 30 30 30 30 30 30 33 30 66 62 64 30 30   0d000000030fbd00
|   3536: 30 66 65 38 30 66 65 66 30 66 62 64 0a 5b 31 66   0fe80fef0fbd.[1f
|   3552: 62 64 5d 32 34 38 34 38 30 38 30 38 30 38 30 30   bd]2484808080800
|   3568: 31 30 33 30 30 34 65 30 30 30 30 30 30 31 65 30   103004e0000001e0
|   3584: 36 33 30 36 31 36 32 36 31 36 33 36 62 30 31 30   630616261636b010
|   3600: 32 30 32 30 34 30 32 36 36 37 34 30 32 30 32 30   2020402667402020
|   3616: 32 30 34 30 34 36 65 0a 36 34 36 66 36 65 30 33   204046e.646f6e03
|   3632: 30 32 30 32 30 34 30 61 30 37 30 35 30 31 30 33   0202040a07050103
|   3648: 30 30 31 30 30 33 30 33 30 66 30 61 30 33 30 30   001003030f0a0300
|   3664: 32 34 30 30 30 30 30 30 30 30 30 31 30 31 30 31   2400000000010101
|   3680: 30 30 30 31 30 31 30 31 30 31 30 61 30 30 30 30   00010101010a0000
|   3696: 30 30 0a 30 31 30 66 66 61 30 30 30 66 66 61 0a   00.010ffa000ffa.
|   3712: 5b 32 66 29 61 5d 30 35 30 34 30 39 30 63 30 31   [2f)a]0504090c01
|   3728: 30 32 30 64 30 30 30 30 30 30 30 33 30 66 65 30   020d000000030fe0
|   3744: 30 30 30 66 66 36 30 66 65 63 30 66 65 30 0a 5b   000ff60fec0fe0.[
|   3760: 33 66 65 30 5d 30 61 30 33 30 33 30 30 31 62 36   3fe0]0a0303001b6
|   3776: 31 36 32 36 31 36 65 36 34 36 66 36 65 30 38 30   162616e646f6e080
|   3792: 32 30 33 30 30 31 37 36 31 36 32 36 31 36 36 37   2030017616261667
|   3808: 34 30 38 30 31 30 33 30 33 36 62 30 31 30 32 30   4080103036b01020
|   3824: 32 30 34 30 32 36 36 37 34 30 32 30 32 30 32 30   2040266740202020
|   3840: 34 30 34 36 65 0a 36 34 36 66 36 65 30 33 30 32   4046e.646f6e0302
|   3856: 30 32 30 34 30 61 30 37 30 35 30 31 30 33 30 30   02040a0705010300
|   3872: 31 30 30 33 30 33 30 66 30 61 30 33 30 30 32 34   1003030f0a030024
|   3888: 30 30 30 30 30 30 30 30 30 31 30 31 30 31 30 30   0000000001010100
|   3904: 30 31 30 31 30 31 30 30 39 61 30 30 30 30 30 30   010101009a000000
|   3920: 0a 30 31 30 66 66 61 30 30 30 66 66 61 0a 5b 32   .010ffa000ffa.[2
|   3936: 66 65 72 20 62 61 63 6b 75 70 4a 08 04 00 81 19   fer backupJ.....
|   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 62   ckup abandon teb
|   3984: 20 73 74 61 61 63 6b 20 63 68 61 6e 6e 65 62 6f    staack 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 00 00 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: 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 31 04 04 03 00 0e 01 04 03   .......1........
|   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 c22b.db
}]} {}


do_catchsql_test 22.1 {
  INSERT INTO t1(t1) VALUES('optimize');
} {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/fts5/test/fts5vocab.test.
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
} {
  0 term {} 0 {} 0
  1 col {} 0 {} 0
  2 doc {} 0 {} 0
  3 cnt {} 0 {} 0
}

do_execsql_test 1.2.1 { SELECT * FROM v1 } { }
do_execsql_test 1.2.2 { SELECT * FROM v2 } { }

do_execsql_test 1.3 {
  INSERT INTO t1 VALUES('x y z');
  INSERT INTO t1 VALUES('x x x');
}

do_execsql_test 1.4.1 {







|
|







75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
} {
  0 term {} 0 {} 0
  1 col {} 0 {} 0
  2 doc {} 0 {} 0
  3 cnt {} 0 {} 0
}

do_execsql_test 1.2.1 { SELECT * FROM v1 } {}
do_execsql_test 1.2.2 { SELECT * FROM v2 } {}

do_execsql_test 1.3 {
  INSERT INTO t1 VALUES('x y z');
  INSERT INTO t1 VALUES('x x x');
}

do_execsql_test 1.4.1 {
Changes to ext/fts5/test/fts5vocab2.test.
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
  four  2 b 0
  three 2 a 0
}

do_execsql_test 1.5 {
  DELETE FROM t1;
  SELECT * FROM v1;
} {
}

#-------------------------------------------------------------------------
#
do_execsql_test 2.0 {
  DROP TABLE IF EXISTS t1;
  DROP TABLE IF EXISTS v1;








|
<







76
77
78
79
80
81
82
83

84
85
86
87
88
89
90
  four  2 b 0
  three 2 a 0
}

do_execsql_test 1.5 {
  DELETE FROM t1;
  SELECT * FROM v1;
} {}


#-------------------------------------------------------------------------
#
do_execsql_test 2.0 {
  DROP TABLE IF EXISTS t1;
  DROP TABLE IF EXISTS v1;

139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
  four  2 b {}
  three 2 a {}
}

do_execsql_test 2.5 {
  DELETE FROM t1;
  SELECT * FROM v1;
} {
}

#-------------------------------------------------------------------------
#
do_execsql_test 3.0 {
  DROP TABLE IF EXISTS t1;
  DROP TABLE IF EXISTS v1;








|
<







138
139
140
141
142
143
144
145

146
147
148
149
150
151
152
  four  2 b {}
  three 2 a {}
}

do_execsql_test 2.5 {
  DELETE FROM t1;
  SELECT * FROM v1;
} {}


#-------------------------------------------------------------------------
#
do_execsql_test 3.0 {
  DROP TABLE IF EXISTS t1;
  DROP TABLE IF EXISTS v1;

198
199
200
201
202
203
204
205
206
207
208
  four  2 {} {}
  three 2 {} {}
}

do_execsql_test 3.5 {
  DELETE FROM t1;
  SELECT * FROM v1;
} {
}

finish_test







|
|
<

196
197
198
199
200
201
202
203
204

205
  four  2 {} {}
  three 2 {} {}
}

do_execsql_test 3.5 {
  DELETE FROM t1;
  SELECT * FROM v1;
} {}


finish_test
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/rtree/rtree.c.
124
125
126
127
128
129
130



131
132
133
134
135
136
137
  u8 nDim;                    /* Number of dimensions */
  u8 nDim2;                   /* Twice the number of dimensions */
  u8 eCoordType;              /* RTREE_COORD_REAL32 or RTREE_COORD_INT32 */
  u8 nBytesPerCell;           /* Bytes consumed per cell */
  u8 inWrTrans;               /* True if inside write transaction */
  u8 nAux;                    /* # of auxiliary columns in %_rowid */
  u8 nAuxNotNull;             /* Number of initial not-null aux columns */



  int iDepth;                 /* Current depth of the r-tree structure */
  char *zDb;                  /* Name of database containing r-tree table */
  char *zName;                /* Name of r-tree table */ 
  u32 nBusy;                  /* Current number of users of this structure */
  i64 nRowEst;                /* Estimated number of rows in this table */
  u32 nCursor;                /* Number of open cursors */
  u32 nNodeRef;               /* Number RtreeNodes with positive nRef */







>
>
>







124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
  u8 nDim;                    /* Number of dimensions */
  u8 nDim2;                   /* Twice the number of dimensions */
  u8 eCoordType;              /* RTREE_COORD_REAL32 or RTREE_COORD_INT32 */
  u8 nBytesPerCell;           /* Bytes consumed per cell */
  u8 inWrTrans;               /* True if inside write transaction */
  u8 nAux;                    /* # of auxiliary columns in %_rowid */
  u8 nAuxNotNull;             /* Number of initial not-null aux columns */
#ifdef SQLITE_DEBUG
  u8 bCorrupt;                /* Shadow table corruption detected */
#endif
  int iDepth;                 /* Current depth of the r-tree structure */
  char *zDb;                  /* Name of database containing r-tree table */
  char *zName;                /* Name of r-tree table */ 
  u32 nBusy;                  /* Current number of users of this structure */
  i64 nRowEst;                /* Estimated number of rows in this table */
  u32 nCursor;                /* Number of open cursors */
  u32 nNodeRef;               /* Number RtreeNodes with positive nRef */
183
184
185
186
187
188
189









190
191
192
193
194
195
196
# define RTREE_ZERO 0
#else
  typedef double RtreeDValue;              /* High accuracy coordinate */
  typedef float RtreeValue;                /* Low accuracy coordinate */
# define RTREE_ZERO 0.0
#endif










/*
** When doing a search of an r-tree, instances of the following structure
** record intermediate results from the tree walk.
**
** The id is always a node-id.  For iLevel>=1 the id is the node-id of
** the node that the RtreeSearchPoint represents.  When iLevel==0, however,
** the id is of the parent node and the cell that RtreeSearchPoint







>
>
>
>
>
>
>
>
>







186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
# define RTREE_ZERO 0
#else
  typedef double RtreeDValue;              /* High accuracy coordinate */
  typedef float RtreeValue;                /* Low accuracy coordinate */
# define RTREE_ZERO 0.0
#endif

/*
** Set the Rtree.bCorrupt flag
*/
#ifdef SQLITE_DEBUG
# define RTREE_IS_CORRUPT(X) ((X)->bCorrupt = 1)
#else
# define RTREE_IS_CORRUPT(X)
#endif

/*
** When doing a search of an r-tree, instances of the following structure
** record intermediate results from the tree walk.
**
** The id is always a node-id.  For iLevel>=1 the id is the node-id of
** the node that the RtreeSearchPoint represents.  When iLevel==0, however,
** the id is of the parent node and the cell that RtreeSearchPoint
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
  p->isDirty = 1;
}

/*
** Given a node number iNode, return the corresponding key to use
** in the Rtree.aHash table.
*/
static int nodeHash(i64 iNode){
  return iNode % HASHSIZE;
}

/*
** Search the node hash table for node iNode. If found, return a pointer
** to it. Otherwise, return 0.
*/
static RtreeNode *nodeHashLookup(Rtree *pRtree, i64 iNode){







|
|







561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
  p->isDirty = 1;
}

/*
** Given a node number iNode, return the corresponding key to use
** in the Rtree.aHash table.
*/
static unsigned int nodeHash(i64 iNode){
  return ((unsigned)iNode) % HASHSIZE;
}

/*
** Search the node hash table for node iNode. If found, return a pointer
** to it. Otherwise, return 0.
*/
static RtreeNode *nodeHashLookup(Rtree *pRtree, i64 iNode){
618
619
620
621
622
623
624












625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643




644
645
646
647
648
649
650
static void nodeBlobReset(Rtree *pRtree){
  if( pRtree->pNodeBlob && pRtree->inWrTrans==0 && pRtree->nCursor==0 ){
    sqlite3_blob *pBlob = pRtree->pNodeBlob;
    pRtree->pNodeBlob = 0;
    sqlite3_blob_close(pBlob);
  }
}













/*
** Obtain a reference to an r-tree node.
*/
static int nodeAcquire(
  Rtree *pRtree,             /* R-tree structure */
  i64 iNode,                 /* Node number to load */
  RtreeNode *pParent,        /* Either the parent node or NULL */
  RtreeNode **ppNode         /* OUT: Acquired node */
){
  int rc = SQLITE_OK;
  RtreeNode *pNode = 0;

  /* Check if the requested node is already in the hash table. If so,
  ** increase its reference count and return it.
  */
  if( (pNode = nodeHashLookup(pRtree, iNode))!=0 ){
    assert( !pParent || !pNode->pParent || pNode->pParent==pParent );
    if( pParent && !pNode->pParent ){




      pParent->nRef++;
      pNode->pParent = pParent;
    }
    pNode->nRef++;
    *ppNode = pNode;
    return SQLITE_OK;
  }







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



















>
>
>
>







630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
static void nodeBlobReset(Rtree *pRtree){
  if( pRtree->pNodeBlob && pRtree->inWrTrans==0 && pRtree->nCursor==0 ){
    sqlite3_blob *pBlob = pRtree->pNodeBlob;
    pRtree->pNodeBlob = 0;
    sqlite3_blob_close(pBlob);
  }
}

/*
** Check to see if pNode is the same as pParent or any of the parents
** of pParent.
*/
static int nodeInParentChain(const RtreeNode *pNode, const RtreeNode *pParent){
  do{
    if( pNode==pParent ) return 1;
    pParent = pParent->pParent;
  }while( pParent );
  return 0;
}

/*
** Obtain a reference to an r-tree node.
*/
static int nodeAcquire(
  Rtree *pRtree,             /* R-tree structure */
  i64 iNode,                 /* Node number to load */
  RtreeNode *pParent,        /* Either the parent node or NULL */
  RtreeNode **ppNode         /* OUT: Acquired node */
){
  int rc = SQLITE_OK;
  RtreeNode *pNode = 0;

  /* Check if the requested node is already in the hash table. If so,
  ** increase its reference count and return it.
  */
  if( (pNode = nodeHashLookup(pRtree, iNode))!=0 ){
    assert( !pParent || !pNode->pParent || pNode->pParent==pParent );
    if( pParent && !pNode->pParent ){
      if( nodeInParentChain(pNode, pParent) ){
        RTREE_IS_CORRUPT(pRtree);
        return SQLITE_CORRUPT_VTAB;
      }
      pParent->nRef++;
      pNode->pParent = pParent;
    }
    pNode->nRef++;
    *ppNode = pNode;
    return SQLITE_OK;
  }
667
668
669
670
671
672
673
674



675
676
677
678
679
680
681
    sqlite3_free(zTab);
  }
  if( rc ){
    nodeBlobReset(pRtree);
    *ppNode = 0;
    /* If unable to open an sqlite3_blob on the desired row, that can only
    ** be because the shadow tables hold erroneous data. */
    if( rc==SQLITE_ERROR ) rc = SQLITE_CORRUPT_VTAB;



  }else if( pRtree->iNodeSize==sqlite3_blob_bytes(pRtree->pNodeBlob) ){
    pNode = (RtreeNode *)sqlite3_malloc(sizeof(RtreeNode)+pRtree->iNodeSize);
    if( !pNode ){
      rc = SQLITE_NOMEM;
    }else{
      pNode->pParent = pParent;
      pNode->zData = (u8 *)&pNode[1];







|
>
>
>







695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
    sqlite3_free(zTab);
  }
  if( rc ){
    nodeBlobReset(pRtree);
    *ppNode = 0;
    /* If unable to open an sqlite3_blob on the desired row, that can only
    ** be because the shadow tables hold erroneous data. */
    if( rc==SQLITE_ERROR ){
      rc = SQLITE_CORRUPT_VTAB;
      RTREE_IS_CORRUPT(pRtree);
    }
  }else if( pRtree->iNodeSize==sqlite3_blob_bytes(pRtree->pNodeBlob) ){
    pNode = (RtreeNode *)sqlite3_malloc(sizeof(RtreeNode)+pRtree->iNodeSize);
    if( !pNode ){
      rc = SQLITE_NOMEM;
    }else{
      pNode->pParent = pParent;
      pNode->zData = (u8 *)&pNode[1];
696
697
698
699
700
701
702

703
704
705
706
707
708
709
710
711
712

713
714
715
716
717
718
719
720

721
722
723
724
725
726
727
  ** are the leaves, and so on. If the depth as specified on the root node
  ** is greater than RTREE_MAX_DEPTH, the r-tree structure must be corrupt.
  */
  if( pNode && iNode==1 ){
    pRtree->iDepth = readInt16(pNode->zData);
    if( pRtree->iDepth>RTREE_MAX_DEPTH ){
      rc = SQLITE_CORRUPT_VTAB;

    }
  }

  /* If no error has occurred so far, check if the "number of entries"
  ** field on the node is too large. If so, set the return code to 
  ** SQLITE_CORRUPT_VTAB.
  */
  if( pNode && rc==SQLITE_OK ){
    if( NCELL(pNode)>((pRtree->iNodeSize-4)/pRtree->nBytesPerCell) ){
      rc = SQLITE_CORRUPT_VTAB;

    }
  }

  if( rc==SQLITE_OK ){
    if( pNode!=0 ){
      nodeHashInsert(pRtree, pNode);
    }else{
      rc = SQLITE_CORRUPT_VTAB;

    }
    *ppNode = pNode;
  }else{
    if( pNode ){
      pRtree->nNodeRef--;
      sqlite3_free(pNode);
    }







>










>








>







727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
  ** are the leaves, and so on. If the depth as specified on the root node
  ** is greater than RTREE_MAX_DEPTH, the r-tree structure must be corrupt.
  */
  if( pNode && iNode==1 ){
    pRtree->iDepth = readInt16(pNode->zData);
    if( pRtree->iDepth>RTREE_MAX_DEPTH ){
      rc = SQLITE_CORRUPT_VTAB;
      RTREE_IS_CORRUPT(pRtree);
    }
  }

  /* If no error has occurred so far, check if the "number of entries"
  ** field on the node is too large. If so, set the return code to 
  ** SQLITE_CORRUPT_VTAB.
  */
  if( pNode && rc==SQLITE_OK ){
    if( NCELL(pNode)>((pRtree->iNodeSize-4)/pRtree->nBytesPerCell) ){
      rc = SQLITE_CORRUPT_VTAB;
      RTREE_IS_CORRUPT(pRtree);
    }
  }

  if( rc==SQLITE_OK ){
    if( pNode!=0 ){
      nodeHashInsert(pRtree, pNode);
    }else{
      rc = SQLITE_CORRUPT_VTAB;
      RTREE_IS_CORRUPT(pRtree);
    }
    *ppNode = pNode;
  }else{
    if( pNode ){
      pRtree->nNodeRef--;
      sqlite3_free(pNode);
    }
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
*/
static void rtreeRelease(Rtree *pRtree){
  pRtree->nBusy--;
  if( pRtree->nBusy==0 ){
    pRtree->inWrTrans = 0;
    assert( pRtree->nCursor==0 );
    nodeBlobReset(pRtree);
    assert( pRtree->nNodeRef==0 );
    sqlite3_finalize(pRtree->pWriteNode);
    sqlite3_finalize(pRtree->pDeleteNode);
    sqlite3_finalize(pRtree->pReadRowid);
    sqlite3_finalize(pRtree->pWriteRowid);
    sqlite3_finalize(pRtree->pDeleteRowid);
    sqlite3_finalize(pRtree->pReadParent);
    sqlite3_finalize(pRtree->pWriteParent);







|







973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
*/
static void rtreeRelease(Rtree *pRtree){
  pRtree->nBusy--;
  if( pRtree->nBusy==0 ){
    pRtree->inWrTrans = 0;
    assert( pRtree->nCursor==0 );
    nodeBlobReset(pRtree);
    assert( pRtree->nNodeRef==0 || pRtree->bCorrupt );
    sqlite3_finalize(pRtree->pWriteNode);
    sqlite3_finalize(pRtree->pDeleteNode);
    sqlite3_finalize(pRtree->pReadRowid);
    sqlite3_finalize(pRtree->pWriteRowid);
    sqlite3_finalize(pRtree->pDeleteRowid);
    sqlite3_finalize(pRtree->pReadParent);
    sqlite3_finalize(pRtree->pWriteParent);
1271
1272
1273
1274
1275
1276
1277

1278
1279
1280
1281
1282
1283
1284
  assert( nCell<200 );
  for(ii=0; ii<nCell; ii++){
    if( nodeGetRowid(pRtree, pNode, ii)==iRowid ){
      *piIndex = ii;
      return SQLITE_OK;
    }
  }

  return SQLITE_CORRUPT_VTAB;
}

/*
** Return the index of the cell containing a pointer to node pNode
** in its parent. If pNode is the root node, return -1.
*/







>







1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
  assert( nCell<200 );
  for(ii=0; ii<nCell; ii++){
    if( nodeGetRowid(pRtree, pNode, ii)==iRowid ){
      *piIndex = ii;
      return SQLITE_OK;
    }
  }
  RTREE_IS_CORRUPT(pRtree);
  return SQLITE_CORRUPT_VTAB;
}

/*
** Return the index of the cell containing a pointer to node pNode
** in its parent. If pNode is the root node, return -1.
*/
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927

1928
1929
1930
1931

1932
1933
1934
1935
1936
1937
1938

    if( p->usable
    && ((p->iColumn>0 && p->iColumn<=pRtree->nDim2)
        || p->op==SQLITE_INDEX_CONSTRAINT_MATCH)
    ){
      u8 op;
      switch( p->op ){
        case SQLITE_INDEX_CONSTRAINT_EQ: op = RTREE_EQ; break;
        case SQLITE_INDEX_CONSTRAINT_GT: op = RTREE_GT; break;
        case SQLITE_INDEX_CONSTRAINT_LE: op = RTREE_LE; break;
        case SQLITE_INDEX_CONSTRAINT_LT: op = RTREE_LT; break;
        case SQLITE_INDEX_CONSTRAINT_GE: op = RTREE_GE; break;
        default:
          assert( p->op==SQLITE_INDEX_CONSTRAINT_MATCH );
          op = RTREE_MATCH; 
          break;
      }

      zIdxStr[iIdx++] = op;
      zIdxStr[iIdx++] = (char)(p->iColumn - 1 + '0');
      pIdxInfo->aConstraintUsage[ii].argvIndex = (iIdx/2);
      pIdxInfo->aConstraintUsage[ii].omit = 1;

    }
  }

  pIdxInfo->idxNum = 2;
  pIdxInfo->needToFreeIdxStr = 1;
  if( iIdx>0 && 0==(pIdxInfo->idxStr = sqlite3_mprintf("%s", zIdxStr)) ){
    return SQLITE_NOMEM;







|
|
|
|
|
<
|
<
|

>
|
|
|
|
>







1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957

1958

1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973

    if( p->usable
    && ((p->iColumn>0 && p->iColumn<=pRtree->nDim2)
        || p->op==SQLITE_INDEX_CONSTRAINT_MATCH)
    ){
      u8 op;
      switch( p->op ){
        case SQLITE_INDEX_CONSTRAINT_EQ:    op = RTREE_EQ;    break;
        case SQLITE_INDEX_CONSTRAINT_GT:    op = RTREE_GT;    break;
        case SQLITE_INDEX_CONSTRAINT_LE:    op = RTREE_LE;    break;
        case SQLITE_INDEX_CONSTRAINT_LT:    op = RTREE_LT;    break;
        case SQLITE_INDEX_CONSTRAINT_GE:    op = RTREE_GE;    break;

        case SQLITE_INDEX_CONSTRAINT_MATCH: op = RTREE_MATCH; break;

        default:                            op = 0;           break;
      }
      if( op ){
        zIdxStr[iIdx++] = op;
        zIdxStr[iIdx++] = (char)(p->iColumn - 1 + '0');
        pIdxInfo->aConstraintUsage[ii].argvIndex = (iIdx/2);
        pIdxInfo->aConstraintUsage[ii].omit = 1;
      }
    }
  }

  pIdxInfo->idxNum = 2;
  pIdxInfo->needToFreeIdxStr = 1;
  if( iIdx>0 && 0==(pIdxInfo->idxStr = sqlite3_mprintf("%s", zIdxStr)) ){
    return SQLITE_NOMEM;
2133
2134
2135
2136
2137
2138
2139

2140
2141
2142
2143
2144
2145

2146
2147
2148
2149
2150
2151
2152
*/
static int AdjustTree(
  Rtree *pRtree,                    /* Rtree table */
  RtreeNode *pNode,                 /* Adjust ancestry of this node. */
  RtreeCell *pCell                  /* This cell was just inserted */
){
  RtreeNode *p = pNode;

  while( p->pParent ){
    RtreeNode *pParent = p->pParent;
    RtreeCell cell;
    int iCell;

    if( nodeParentIndex(pRtree, p, &iCell) ){

      return SQLITE_CORRUPT_VTAB;
    }

    nodeGetCell(pRtree, pParent, iCell, &cell);
    if( !cellContains(pRtree, &cell, pCell) ){
      cellUnion(pRtree, &cell, pCell);
      nodeOverwriteCell(pRtree, pParent, &cell, iCell);







>





|
>







2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
*/
static int AdjustTree(
  Rtree *pRtree,                    /* Rtree table */
  RtreeNode *pNode,                 /* Adjust ancestry of this node. */
  RtreeCell *pCell                  /* This cell was just inserted */
){
  RtreeNode *p = pNode;
  int cnt = 0;
  while( p->pParent ){
    RtreeNode *pParent = p->pParent;
    RtreeCell cell;
    int iCell;

    if( (++cnt)>1000 || nodeParentIndex(pRtree, p, &iCell)  ){
      RTREE_IS_CORRUPT(pRtree);
      return SQLITE_CORRUPT_VTAB;
    }

    nodeGetCell(pRtree, pParent, iCell, &cell);
    if( !cellContains(pRtree, &cell, pCell) ){
      cellUnion(pRtree, &cell, pCell);
      nodeOverwriteCell(pRtree, pParent, &cell, iCell);
2606
2607
2608
2609
2610
2611
2612
2613



2614
2615
2616
2617
2618
2619
2620
      for(pTest=pLeaf; pTest && pTest->iNode!=iNode; pTest=pTest->pParent);
      if( !pTest ){
        rc2 = nodeAcquire(pRtree, iNode, 0, &pChild->pParent);
      }
    }
    rc = sqlite3_reset(pRtree->pReadParent);
    if( rc==SQLITE_OK ) rc = rc2;
    if( rc==SQLITE_OK && !pChild->pParent ) rc = SQLITE_CORRUPT_VTAB;



    pChild = pChild->pParent;
  }
  return rc;
}

static int deleteCell(Rtree *, RtreeNode *, int, int);








|
>
>
>







2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
      for(pTest=pLeaf; pTest && pTest->iNode!=iNode; pTest=pTest->pParent);
      if( !pTest ){
        rc2 = nodeAcquire(pRtree, iNode, 0, &pChild->pParent);
      }
    }
    rc = sqlite3_reset(pRtree->pReadParent);
    if( rc==SQLITE_OK ) rc = rc2;
    if( rc==SQLITE_OK && !pChild->pParent ){
      RTREE_IS_CORRUPT(pRtree);
      rc = SQLITE_CORRUPT_VTAB;
    }
    pChild = pChild->pParent;
  }
  return rc;
}

static int deleteCell(Rtree *, RtreeNode *, int, int);

2919
2920
2921
2922
2923
2924
2925
2926




2927
2928
2929
2930
2931
2932
2933
2934
2935

  /* Obtain a reference to the leaf node that contains the entry 
  ** about to be deleted. 
  */
  if( rc==SQLITE_OK ){
    rc = findLeafNode(pRtree, iDelete, &pLeaf, 0);
  }





  /* Delete the cell in question from the leaf node. */
  if( rc==SQLITE_OK ){
    int rc2;
    rc = nodeRowidIndex(pRtree, pLeaf, iDelete, &iCell);
    if( rc==SQLITE_OK ){
      rc = deleteCell(pRtree, pLeaf, iCell, 0);
    }
    rc2 = nodeRelease(pRtree, pLeaf);
    if( rc==SQLITE_OK ){








>
>
>
>

|







2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979

  /* Obtain a reference to the leaf node that contains the entry 
  ** about to be deleted. 
  */
  if( rc==SQLITE_OK ){
    rc = findLeafNode(pRtree, iDelete, &pLeaf, 0);
  }

#ifdef CORRUPT_DB
  assert( pLeaf!=0 || rc!=SQLITE_OK || CORRUPT_DB );
#endif

  /* Delete the cell in question from the leaf node. */
  if( rc==SQLITE_OK && pLeaf ){
    int rc2;
    rc = nodeRowidIndex(pRtree, pLeaf, iDelete, &iCell);
    if( rc==SQLITE_OK ){
      rc = deleteCell(pRtree, pLeaf, iCell, 0);
    }
    rc2 = nodeRelease(pRtree, pLeaf);
    if( rc==SQLITE_OK ){
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
      pRtree->iReinsertHeight = -1;
      rc = rtreeInsertCell(pRtree, pLeaf, &cell, 0);
      rc2 = nodeRelease(pRtree, pLeaf);
      if( rc==SQLITE_OK ){
        rc = rc2;
      }
    }
    if( pRtree->nAux ){
      sqlite3_stmt *pUp = pRtree->pWriteAux;
      int jj;
      sqlite3_bind_int64(pUp, 1, *pRowid);
      for(jj=0; jj<pRtree->nAux; jj++){
        sqlite3_bind_value(pUp, jj+2, aData[pRtree->nDim2+3+jj]);
      }
      sqlite3_step(pUp);







|







3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
      pRtree->iReinsertHeight = -1;
      rc = rtreeInsertCell(pRtree, pLeaf, &cell, 0);
      rc2 = nodeRelease(pRtree, pLeaf);
      if( rc==SQLITE_OK ){
        rc = rc2;
      }
    }
    if( rc==SQLITE_OK && pRtree->nAux ){
      sqlite3_stmt *pUp = pRtree->pWriteAux;
      int jj;
      sqlite3_bind_int64(pUp, 1, *pRowid);
      for(jj=0; jj<pRtree->nAux; jj++){
        sqlite3_bind_value(pUp, jj+2, aData[pRtree->nDim2+3+jj]);
      }
      sqlite3_step(pUp);
3391
3392
3393
3394
3395
3396
3397

3398
3399
3400
3401
3402
3403
3404
    /* Read and write the xxx_parent table */
    "SELECT parentnode FROM '%q'.'%q_parent' WHERE nodeno = ?1",
    "INSERT OR REPLACE INTO '%q'.'%q_parent' VALUES(?1, ?2)",
    "DELETE FROM '%q'.'%q_parent' WHERE nodeno = ?1"
  };
  sqlite3_stmt **appStmt[N_STATEMENT];
  int i;


  pRtree->db = db;

  if( isCreate ){
    char *zCreate;
    sqlite3_str *p = sqlite3_str_new(db);
    int ii;







>







3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
    /* Read and write the xxx_parent table */
    "SELECT parentnode FROM '%q'.'%q_parent' WHERE nodeno = ?1",
    "INSERT OR REPLACE INTO '%q'.'%q_parent' VALUES(?1, ?2)",
    "DELETE FROM '%q'.'%q_parent' WHERE nodeno = ?1"
  };
  sqlite3_stmt **appStmt[N_STATEMENT];
  int i;
  const int f = SQLITE_PREPARE_PERSISTENT|SQLITE_PREPARE_NO_VTAB;

  pRtree->db = db;

  if( isCreate ){
    char *zCreate;
    sqlite3_str *p = sqlite3_str_new(db);
    int ii;
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
       /* An UPSERT is very slightly slower than REPLACE, but it is needed
       ** if there are auxiliary columns */
       zFormat = "INSERT INTO\"%w\".\"%w_rowid\"(rowid,nodeno)VALUES(?1,?2)"
                  "ON CONFLICT(rowid)DO UPDATE SET nodeno=excluded.nodeno";
    }
    zSql = sqlite3_mprintf(zFormat, zDb, zPrefix);
    if( zSql ){
      rc = sqlite3_prepare_v3(db, zSql, -1, SQLITE_PREPARE_PERSISTENT,
                              appStmt[i], 0); 
    }else{
      rc = SQLITE_NOMEM;
    }
    sqlite3_free(zSql);
  }
  if( pRtree->nAux ){
    pRtree->zReadAuxSql = sqlite3_mprintf(







|
<







3492
3493
3494
3495
3496
3497
3498
3499

3500
3501
3502
3503
3504
3505
3506
       /* An UPSERT is very slightly slower than REPLACE, but it is needed
       ** if there are auxiliary columns */
       zFormat = "INSERT INTO\"%w\".\"%w_rowid\"(rowid,nodeno)VALUES(?1,?2)"
                  "ON CONFLICT(rowid)DO UPDATE SET nodeno=excluded.nodeno";
    }
    zSql = sqlite3_mprintf(zFormat, zDb, zPrefix);
    if( zSql ){
      rc = sqlite3_prepare_v3(db, zSql, -1, f, appStmt[i], 0); 

    }else{
      rc = SQLITE_NOMEM;
    }
    sqlite3_free(zSql);
  }
  if( pRtree->nAux ){
    pRtree->zReadAuxSql = sqlite3_mprintf(
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
        }
      }
      sqlite3_str_appendf(p, " WHERE rowid=?1");
      zSql = sqlite3_str_finish(p);
      if( zSql==0 ){
        rc = SQLITE_NOMEM;
      }else{
        rc = sqlite3_prepare_v3(db, zSql, -1, SQLITE_PREPARE_PERSISTENT,
                                &pRtree->pWriteAux, 0); 
        sqlite3_free(zSql);
      }
    }
  }

  return rc;
}







|
<







3522
3523
3524
3525
3526
3527
3528
3529

3530
3531
3532
3533
3534
3535
3536
        }
      }
      sqlite3_str_appendf(p, " WHERE rowid=?1");
      zSql = sqlite3_str_finish(p);
      if( zSql==0 ){
        rc = SQLITE_NOMEM;
      }else{
        rc = sqlite3_prepare_v3(db, zSql, -1, f, &pRtree->pWriteAux, 0); 

        sqlite3_free(zSql);
      }
    }
  }

  return rc;
}
3555
3556
3557
3558
3559
3560
3561

3562
3563
3564
3565
3566
3567
3568
        pRtree->zDb, pRtree->zName
    );
    rc = getIntFromStmt(db, zSql, &pRtree->iNodeSize);
    if( rc!=SQLITE_OK ){
      *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db));
    }else if( pRtree->iNodeSize<(512-64) ){
      rc = SQLITE_CORRUPT_VTAB;

      *pzErr = sqlite3_mprintf("undersize RTree blobs in \"%q_node\"",
                               pRtree->zName);
    }
  }

  sqlite3_free(zSql);
  return rc;







>







3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
        pRtree->zDb, pRtree->zName
    );
    rc = getIntFromStmt(db, zSql, &pRtree->iNodeSize);
    if( rc!=SQLITE_OK ){
      *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db));
    }else if( pRtree->iNodeSize<(512-64) ){
      rc = SQLITE_CORRUPT_VTAB;
      RTREE_IS_CORRUPT(pRtree);
      *pzErr = sqlite3_mprintf("undersize RTree blobs in \"%q_node\"",
                               pRtree->zName);
    }
  }

  sqlite3_free(zSql);
  return rc;
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
** Or, if an error does occur, NULL is returned and an error code left
** in the RtreeCheck object. The final value of *pnNode is undefined in
** this case.
*/
static u8 *rtreeCheckGetNode(RtreeCheck *pCheck, i64 iNode, int *pnNode){
  u8 *pRet = 0;                   /* Return value */

  assert( pCheck->rc==SQLITE_OK );
  if( pCheck->pGetNode==0 ){
    pCheck->pGetNode = rtreeCheckPrepare(pCheck,
        "SELECT data FROM %Q.'%q_node' WHERE nodeno=?", 
        pCheck->zDb, pCheck->zTab
    );
  }

  if( pCheck->rc==SQLITE_OK ){







|
<







3922
3923
3924
3925
3926
3927
3928
3929

3930
3931
3932
3933
3934
3935
3936
** Or, if an error does occur, NULL is returned and an error code left
** in the RtreeCheck object. The final value of *pnNode is undefined in
** this case.
*/
static u8 *rtreeCheckGetNode(RtreeCheck *pCheck, i64 iNode, int *pnNode){
  u8 *pRet = 0;                   /* Return value */

  if( pCheck->rc==SQLITE_OK && pCheck->pGetNode==0 ){

    pCheck->pGetNode = rtreeCheckPrepare(pCheck,
        "SELECT data FROM %Q.'%q_node' WHERE nodeno=?", 
        pCheck->zDb, pCheck->zTab
    );
  }

  if( pCheck->rc==SQLITE_OK ){
Changes to ext/rtree/rtree6.test.
54
55
56
57
58
59
60



61
62
63
64
65
66
67
    CREATE VIRTUAL TABLE t1 USING rtree(ii, x1, x2, y1, y2);
  }
} {}

do_test rtree6-1.2 {
  rtree_strategy {SELECT * FROM t1 WHERE x1>10}
} {E0}




do_test rtree6-1.3 {
  rtree_strategy {SELECT * FROM t1 WHERE x1<10}
} {C0}

do_test rtree6-1.4 {
  rtree_strategy {SELECT * FROM t1,t2 WHERE k=ii AND x1<10}







>
>
>







54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
    CREATE VIRTUAL TABLE t1 USING rtree(ii, x1, x2, y1, y2);
  }
} {}

do_test rtree6-1.2 {
  rtree_strategy {SELECT * FROM t1 WHERE x1>10}
} {E0}
do_test rtree6-1.2.1 {
  rtree_strategy {SELECT * FROM t1 WHERE x1>10 AND x2 LIKE '%x%'}
} {E0}

do_test rtree6-1.3 {
  rtree_strategy {SELECT * FROM t1 WHERE x1<10}
} {C0}

do_test rtree6-1.4 {
  rtree_strategy {SELECT * FROM t1,t2 WHERE k=ii AND x1<10}
Added ext/rtree/rtreecirc.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
# 2018 Dec 22
#
# 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 script is testing the FTS5 module.
#

if {![info exists testdir]} {
  set testdir [file join [file dirname [info script]] .. .. test]
}
source [file join [file dirname [info script]] rtree_util.tcl]
source $testdir/tester.tcl
set testprefix rtreecirc

ifcapable !rtree {
  finish_test
  return
}

do_execsql_test 1.0 {
  CREATE VIRTUAL TABLE rt USING rtree(id, x1, x2, y1, y2);
  SELECT name FROM sqlite_master ORDER BY 1;
} {
  rt rt_node rt_parent rt_rowid
}
db_save_and_close

foreach {tn schema sql} {
  1 {
    CREATE TRIGGER tr1 AFTER INSERT ON rt_node BEGIN
      SELECT * FROM rt;
    END;
  } {
    INSERT INTO rt VALUES(1, 2, 3, 4, 5);
  }
  2 {
    CREATE TRIGGER tr1 AFTER INSERT ON rt_parent BEGIN
      SELECT * FROM rt;
    END;
  } {
    INSERT INTO rt VALUES(1, 2, 3, 4, 5);
  }
  3 {
    CREATE TRIGGER tr1 AFTER INSERT ON rt_rowid BEGIN
      SELECT * FROM rt;
    END;
  } {
    INSERT INTO rt VALUES(1, 2, 3, 4, 5);
  }
} {
  db_restore_and_reopen
  do_execsql_test  1.1.$tn.1 $schema
  do_catchsql_test 1.1.$tn.2 $sql {1 {no such table: main.rt}}
  db close
}


finish_test

Added ext/rtree/rtreefuzz001.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
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
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
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
# 2012-12-21
#
# 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.
#
#***********************************************************************
#
# Test cases for corrupt database files.

if {![info exists testdir]} {
  set testdir [file join [file dirname [info script]] .. .. test]
} 
source $testdir/tester.tcl

ifcapable !deserialize||!rtree {
  finish_test
  return
}
database_may_be_corrupt

do_test rtreefuzz001-100 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
| size 24576 pagesize 4096 filename c1b.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 03 00 00 00 06   .....@  ........
|     32: 00 00 00 00 00 00 00 00 00 00 00 03 00 00 00 04   ................
|     48: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00   ................
|     80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 03   ................
|     96: 00 2e 30 38 0d 00 00 00 04 0e 9c 00 0f ad 0f 4f   ..08...........O
|    112: 0e fc 0e 9c 00 00 00 00 00 00 00 00 00 00 00 00   ................
|   3728: 00 00 00 00 00 00 00 00 00 00 00 00 5e 04 07 17   ............^...
|   3744: 1f 1f 01 81 0b 74 61 62 6c 65 74 31 5f 70 61 72   .....tablet1_par
|   3760: 65 6e 74 74 31 5f 70 61 72 65 6e 74 04 43 52 45   entt1_parent.CRE
|   3776: 41 54 45 20 54 41 42 4c 45 20 22 74 31 5f 70 61   ATE TABLE .t1_pa
|   3792: 72 66 6e 74 22 28 6e 6f 64 65 6e 6f 20 49 4e 54   rfnt.(nodeno INT
|   3808: 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59   EGER PRIMARY KEY
|   3824: 2c 70 61 72 65 6e 74 6e 6f 64 65 29 51 03 06 17   ,parentnode)Q...
|   3840: 1b 1b 01 7b 74 61 62 6c 65 74 31 5f 6e 6f 64 65   ....tablet1_node
|   3856: 74 31 5f 6e 6f 64 65 03 43 52 45 41 54 45 20 54   t1_node.CREATE T
|   3872: 41 42 4c 45 20 22 74 31 5f 6e 6f 64 65 22 28 6e   ABLE .t1_node.(n
|   3888: 6f 64 65 6e 6f 20 49 4e 54 45 47 45 52 20 50 52   odeno INTEGER PR
|   3904: 49 4d 41 52 59 20 4b 45 59 2c 64 61 74 61 29 5c   IMARY KEY,data).
|   3920: 02 07 17 1d 1d 01 81 0b 74 61 62 6c 65 74 31 5f   ........tablet1_
|   3936: 72 6f 77 69 64 74 31 5f 72 6f 77 69 64 02 43 52   rowidt1_rowid.CR
|   3952: 45 41 54 45 20 54 41 42 4c 45 20 22 74 31 5f 72   EATE TABLE .t1_r
|   3968: 6f 77 69 64 22 28 72 6f 77 69 64 20 49 4e 54 45   owid.(rowid INTE
|   3984: 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c   GER PRIMARY KEY,
|   4000: 6e 6f 64 65 6e 6f 2c 61 30 2c 61 31 29 51 01 07   nodeno,a0,a1)Q..
|   4016: 17 11 11 08 81 0f 74 61 62 6c 65 74 31 74 31 43   ......tablet1t1C
|   4032: 52 45 41 54 45 20 56 49 52 54 55 41 4c 20 54 41   REATE VIRTUAL TA
|   4048: 42 4c 45 20 74 31 20 55 53 49 4e 47 20 72 74 72   BLE t1 USING rtr
|   4064: 65 65 28 69 64 2c 78 30 2c 78 31 2c 79 30 2c 79   ee(id,x0,x1,y0,y
|   4080: 31 2c 2b 6c 61 62 65 6c 2c 2b 6f 74 68 65 72 29   1,+label,+other)
| page 2 offset 4096
|      0: 0d 0c cd 00 74 08 75 01 0f e8 0c b3 0f d0 0f b7   ....t.u.........
|     16: 0f 9e 0f 91 0f 81 0f 70 0f 5e 0f 4f 0f 39 0f 29   .......p.^.O.9.)
|     32: 0f 18 0f 06 0e f7 0c 65 0e 58 0d c2 0d 2c 0c 25   .......e.X...,.%
|     48: 0b 85 0a e5 0a 45 09 a5 09 05 0c 83 0c 93 0c a3   .....E..........
|     64: 0f f0 0c 15 0b 75 0a d5 0a 35 09 95 08 f5 0e d8   .....u...5......
|     80: 0e 42 0d ac 0d 16 0c 05 0b 65 0a c5 0a 25 09 85   .B.......e...%..
|     96: 08 e5 0e c8 0e 32 0d 9c 0d 06 0b f5 0b 55 0a b5   .....2.......U..
|    112: 0a 15 09 75 08 d5 0e b8 0e 22 0d 8c 0c f6 0b e5   ...u............
|    128: 0b 45 0a a5 0a 05 09 65 08 c5 0e a8 0e 12 0d 7c   .E.....e.......|
|    144: 0c e6 0b d5 0b 35 0a 95 09 f5 09 55 08 b5 0e 98   .....5.....U....
|    160: 0e 02 0d 6c 0c d6 0b c5 0b 25 0a 85 09 e5 09 45   ...l.....%.....E
|    176: 08 a5 0e 88 0d f2 0d 5c 0c 55 0b b5 0b 15 0a 75   .........U.....u
|    192: 09 d5 09 35 08 95 0e 78 0d e2 0d 4c 0c 45 0b a5   ...5...x...L.E..
|    208: 0b 05 0a 65 09 c5 09 25 08 85 0e 68 0d d2 0d 3c   ...e...%...h...<
|    224: 0c 35 0b 95 0a f5 0a 55 09 b5 09 15 08 75 0c 75   .5.....U.....u.u
|   2160: 00 00 00 00 00 0d 8e 75 05 00 01 1b 00 04 62 6f   .......u......bo
|   2176: 78 2d 39 2c 39 0d 8e 11 05 00 01 1b 00 02 62 6f   x-9,9.........bo
|   2192: 78 2d 39 2c 38 0d 8d 2d 05 00 01 1b 00 02 62 6f   x-9,8..-......bo
|   2208: 78 2d 39 2c 37 0d 8c 49 05 00 01 1b 00 02 62 6f   x-9,7..I......bo
|   2224: 78 2d 39 2c 36 0d 8b 65 05 00 01 1b 00 02 62 6f   x-9,6..e......bo
|   2240: 78 2d 39 2c 35 0d 8b 01 05 00 01 1b 00 02 62 6f   x-9,5.........bo
|   2256: 78 2d 39 2c 34 0d 8a 1d 05 00 01 1b 00 02 62 6f   x-9,4.........bo
|   2272: 78 2d 39 2c 33 0d 89 39 05 00 01 1b 00 02 62 6f   x-9,3..9......bo
|   2288: 78 2d 39 2c 32 0d 88 55 05 00 01 1b 00 02 62 6f   x-9,2..U......bo
|   2304: 78 2d 39 2c 31 0d 87 71 05 00 01 1b 00 02 62 6f   x-9,1..q......bo
|   2320: 78 2d 39 2c 30 0d 8e 74 05 00 01 1b 00 04 62 6f   x-9,0..t......bo
|   2336: 78 2d 38 2c 39 0d 8e 10 05 00 01 1b 00 02 62 6f   x-8,9.........bo
|   2352: 78 2d 38 2c 38 0d 8d 2c 05 00 01 1b 00 02 62 6f   x-8,8..,......bo
|   2368: 78 2d 38 2c 37 0d 8c 48 05 00 01 1b 00 02 62 6f   x-8,7..H......bo
|   2384: 78 2d 38 2c 36 0d 8b 64 05 00 01 1b 00 02 62 6f   x-8,6..d......bo
|   2400: 78 2d 38 2c 35 0d 8b 00 05 00 01 1b 00 02 62 6f   x-8,5.........bo
|   2416: 78 2d 38 2c 34 0d 8a 1c 05 00 01 1b 00 02 62 6f   x-8,4.........bo
|   2432: 78 2d 38 2c 33 0d 89 38 05 00 01 1b 00 02 62 6f   x-8,3..8......bo
|   2448: 78 2d 38 2c 32 0d 88 54 05 00 01 1b 00 02 62 6f   x-8,2..T......bo
|   2464: 78 2d 38 2c 31 0d 87 70 05 00 01 1b 00 02 62 6f   x-8,1..p......bo
|   2480: 78 2d 38 2c 30 0d 8e 73 05 00 01 1b 00 05 62 6f   x-8,0..s......bo
|   2496: 78 2d 37 2c 39 0d 8e 0f 05 00 01 1b 00 05 62 6f   x-7,9.........bo
|   2512: 78 2d 37 2c 38 0d 8d 2b 05 00 01 1b 00 05 62 6f   x-7,8..+......bo
|   2528: 78 2d 37 2c 37 0d 8c 47 05 00 01 1b 00 05 62 6f   x-7,7..G......bo
|   2544: 78 2d 37 2c 36 0d 8b 63 05 00 01 1b 00 05 62 6f   x-7,6..c......bo
|   2560: 78 2d 37 2c 35 0d 8a 7f 05 00 01 1b 00 05 62 6f   x-7,5.........bo
|   2576: 78 2d 37 2c 34 0d 8a 1b 05 00 01 1b 00 05 62 6f   x-7,4.........bo
|   2592: 78 2d 37 2c 33 0d 89 37 05 00 01 1b 00 05 62 6f   x-7,3..7......bo
|   2608: 78 2d 37 2c 32 0d 88 53 05 00 01 1b 00 05 62 6f   x-7,2..S......bo
|   2624: 78 2d 37 2c 31 0d 87 6f 05 00 01 1b 00 05 62 6f   x-7,1..o......bo
|   2640: 78 2d 37 2c 30 0d 8e 72 05 00 01 1b 00 04 62 6f   x-7,0..r......bo
|   2656: 78 2d 36 2c 39 0d 8e 0e 05 00 01 1b 00 05 62 6f   x-6,9.........bo
|   2672: 78 2d 36 2c 38 0d 8d 2a 05 00 01 1b 00 05 62 6f   x-6,8..*......bo
|   2688: 78 2d 36 2c 37 0d 8c 46 05 00 01 1b 00 05 62 6f   x-6,7..F......bo
|   2704: 78 2d 36 2c 36 0d 8b 62 05 00 01 1b 00 05 62 6f   x-6,6..b......bo
|   2720: 78 2d 36 2c 35 0d 8a 7e 05 00 01 1b 00 05 62 6f   x-6,5..~......bo
|   2736: 78 2d 36 2c 34 0d 8a 1a 05 00 01 1b 00 05 62 6f   x-6,4.........bo
|   2752: 78 2d 36 2c 33 0d 89 36 05 00 01 1b 00 05 62 6f   x-6,3..6......bo
|   2768: 78 2d 36 2c 32 0d 88 52 05 00 01 1b 00 05 62 6f   x-6,2..R......bo
|   2784: 78 2d 36 2c 31 0d 87 6e 05 00 01 1b 00 05 62 6f   x-6,1..n......bo
|   2800: 78 2d 36 2c 30 0d 8e 71 05 00 01 1b 00 04 62 6f   x-6,0..q......bo
|   2816: 78 2d 35 2c 39 0d 8e 0d 05 00 01 1b 00 05 62 6f   x-5,9.........bo
|   2832: 78 2d 35 2c 38 0d 8d 29 05 00 01 1b 00 05 62 6f   x-5,8..)......bo
|   2848: 78 2d 35 2c 37 0d 8c 45 05 00 01 1b 00 05 62 6f   x-5,7..E......bo
|   2864: 78 2d 35 2c 36 0d 8b 61 05 00 01 1b 00 05 62 6f   x-5,6..a......bo
|   2880: 78 2d 35 2c 35 0d 8a 7d 05 00 01 1b 00 05 62 6f   x-5,5.........bo
|   2896: 78 2d 35 2c 34 0d 8a 19 05 00 01 1b 00 05 62 6f   x-5,4.........bo
|   2912: 78 2d 35 2c 33 0d 89 35 05 00 01 1b 00 05 62 6f   x-5,3..5......bo
|   2928: 78 2d 35 2c 32 0d 88 51 05 00 01 1b 00 05 62 6f   x-5,2..Q......bo
|   2944: 78 2d 35 2c 31 0d 87 6d 05 00 01 1b 00 05 62 6f   x-5,1..m......bo
|   2960: 78 2d 35 2c 30 0d 8e 70 05 00 01 1b 00 04 62 6f   x-5,0..p......bo
|   2976: 78 2d 34 2c 39 0d 8e 0c 05 00 01 1b 00 04 62 6f   x-4,9.........bo
|   2992: 78 2d 34 2c 38 0d 8d 28 05 00 01 1b 00 04 62 6f   x-4,8..(......bo
|   3008: 78 2d 34 2c 37 0d 8c 44 05 00 01 1b 00 04 62 6f   x-4,7..D......bo
|   3024: 78 2d 34 2c 36 0d 8b 60 05 00 01 1b 00 02 62 6f   x-4,6..`......bo
|   3040: 78 2d 34 2c 35 0d 8a 7c 05 00 01 1b 00 02 62 6f   x-4,5..|......bo
|   3056: 78 2d 34 2c 34 0d 8a 18 05 00 01 1b 00 02 62 6f   x-4,4.........bo
|   3072: 78 2d 34 2c 33 0d 89 34 05 00 01 1b 00 02 62 6f   x-4,3..4......bo
|   3088: 78 2d 34 2c 32 0d 88 50 05 00 01 1b 00 02 62 6f   x-4,2..P......bo
|   3104: 78 2d 34 2c 31 0d 87 6c 05 00 01 1b 00 02 62 6f   x-4,1..l......bo
|   3120: 78 2d 34 2c 30 0d 8e 6f 05 00 01 1b 00 04 62 6f   x-4,0..o......bo
|   3136: 78 2d 33 2c 39 0d 8e 0b 05 00 01 1b 00 04 62 6f   x-3,9.........bo
|   3152: 78 2d 33 2c 38 0d 8d 27 05 00 01 1b 00 04 62 6f   x-3,8..'......bo
|   3168: 78 2d 33 2c 37 0d 87 68 05 00 01 1b 00 03 62 6f   x-3,7..h......bo
|   3184: 78 2d 30 2c 30 06 90 d9 80 80 81 84 4c 05 00 01   x-0,0.......L...
|   3200: 00 00 03 0d 88 4c 05 00 01 1b 00 02 62 6f 78 2d   .....L......box-
|   3216: 30 2c 31 0d 88 4d 05 00 01 1b 00 02 62 6f 78 2d   0,1..M......box-
|   3232: 31 2c 31 0d 88 4e 05 00 01 1b 00 02 62 6f 78 2d   1,1..N......box-
|   3248: 32 2c 31 17 01 05 00 01 2f 00 02 6c 6f 77 65 72   2,1...../..lower
|   3264: 2d 6c 65 66 74 20 63 6f 72 6e 65 72 0d 0d 26 00   -left corner..&.
|   3280: 09 00 01 00 00 04 0d 8c 43 05 00 01 1b 00 04 62   ........C......b
|   3296: 6f 78 2d 33 2c 36 0d 8b 5f 05 00 01 1b 00 02 62   ox-3,6.._......b
|   3312: 6f 78 2d 33 2c 35 0d 8a 7b 05 00 01 1b 00 02 62   ox-3,5.........b
|   3328: 6f 78 2d 33 2c 34 0d 8a 17 05 00 01 1b 00 02 62   ox-3,4.........b
|   3344: 6f 78 2d 33 2c 33 0d 89 33 05 00 01 1b 00 02 62   ox-3,3..3......b
|   3360: 6f 78 2d 33 2c 32 0d bc 00 06 00 09 0d 87 6b 05   ox-3,2........k.
|   3376: 00 01 1b 00 03 62 6f 78 2d 33 2c 30 0d 8e 6e 05   .....box-3,0..n.
|   3392: 00 01 1b 00 04 62 6f 78 2d 32 2c 39 0d 8e 0a 05   .....box-2,9....
|   3408: 00 01 1b 00 04 62 6f 78 2d 32 2c 38 0d 8d 26 05   .....box-2,8..&.
|   3424: 00 01 1b 00 04 62 6f 78 2d 32 2c 37 0d 8c 42 05   .....box-2,7..B.
|   3440: 00 01 1b 00 04 62 6f 78 2d 32 2c 36 0d 8b 5e 05   .....box-2,6..^.
|   3456: 00 01 1b 00 02 62 6f 78 2d 32 2c 35 0d 8a 7a 05   .....box-2,5..z.
|   3472: 00 01 1b 00 02 62 6f 78 2d 32 2c 34 0d 8a 16 05   .....box-2,4....
|   3488: 00 01 1b 00 02 62 6f 78 2d 32 2c 33 0d 89 32 05   .....box-2,3..2.
|   3504: 00 01 1b 00 02 62 6f 78 2d 32 2c 32 0e 52 00 06   .....box-2,2.R..
|   3520: 00 09 0d 87 6a 05 00 01 1b 00 03 62 6f 78 2d 32   ....j......box-2
|   3536: 2c 30 0d 8e 6d 05 00 01 1b 00 04 62 6f 78 2d 31   ,0..m......box-1
|   3552: 2c 39 0d 8e 09 05 00 01 1b 00 04 62 6f 78 2d 31   ,9.........box-1
|   3568: 2c 38 0d 8d 25 05 00 01 1b 00 04 62 6f 78 2d 31   ,8..%......box-1
|   3584: 2c 37 0d 8c 41 05 00 01 1b 00 04 62 6f 78 2d 31   ,7..A......box-1
|   3600: 2c 36 0d 8b 5d 05 00 01 1b 00 02 62 6f 78 2d 31   ,6..]......box-1
|   3616: 2c 35 0d 8a 79 05 00 01 1b 00 02 62 6f 78 2d 31   ,5..y......box-1
|   3632: 2c 34 0d 8a 15 05 00 01 1b 00 02 62 6f 78 2d 31   ,4.........box-1
|   3648: 2c 33 0d 89 31 05 00 01 1b 00 02 62 6f 78 2d 31   ,3..1......box-1
|   3664: 2c 32 0e e8 00 06 00 09 0d 87 69 05 00 01 1b 00   ,2........i.....
|   3680: 03 62 6f 78 2d 31 2c 30 0d 8e 6c 05 00 01 1b 00   .box-1,0..l.....
|   3696: 04 62 6f 78 2d 30 2c 39 0d 8e 08 05 00 01 1b 00   .box-0,9........
|   3712: 04 62 6f 78 2d 30 2c 38 0d 8d 24 05 00 01 1b 00   .box-0,8..$.....
|   3728: 04 62 6f 78 2d 30 2c 37 0d 8c 40 05 00 01 1b 00   .box-0,7..@.....
|   3744: 04 62 6f 78 2d 30 2c 36 0d 8b 5c 05 00 01 1b 00   .box-0,6........
|   3760: 02 62 6f 78 2d 30 2c 35 0d 8a 78 05 00 01 1b 00   .box-0,5..x.....
|   3776: 02 62 6f 78 2d 30 2c 34 0d 8a 14 05 00 01 1b 00   .box-0,4........
|   3792: 02 62 6f 78 2d 30 2c 33 0d 89 30 05 00 01 1b 00   .box-0,3..0.....
|   3808: 02 62 6f 78 2d 30 2c 32 00 00 00 0f 00 09 1b 00   .box-0,2........
|   3824: 62 6f 78 2d 30 2c 30 0d 0e 05 00 09 1d 00 74 6f   box-0,0.......to
|   3840: 70 20 68 61 6c 66 10 0d 05 00 09 23 00 62 6f 74   p half.....#.bot
|   3856: 74 6f 6d 20 68 61 6c 66 0f 0c 02 05 09 01 00 72   tom half.......r
|   3872: 69 67 68 74 20 68 61 6c 66 0e 0b 05 00 09 1f 00   ight half.......
|   3888: 6c 65 66 74 20 68 61 6c 66 14 0a 05 00 09 2b 00   left half.....+.
|   3904: 74 68 65 20 77 68 6f 6c 65 20 74 68 69 6e 67 0d   the whole thing.
|   3920: 09 05 00 09 1d 00 74 6f 70 20 65 64 67 65 10 08   ......top edge..
|   3936: 05 00 09 23 00 62 6f 74 74 6f 6d 20 65 64 67 65   ...#.bottom edge
|   3952: 0f 07 05 00 09 21 00 72 69 67 68 74 20 65 64 67   .....!.right edg
|   3968: 65 0e 06 05 00 09 1f 00 6c 65 66 74 20 65 64 67   e.......left edg
|   3984: 65 0b 05 05 00 09 19 00 63 65 6e 74 65 72 17 04   e.......center..
|   4000: 05 00 09 31 00 75 70 70 65 72 2d 72 69 67 68 74   ...1.upper-right
|   4016: 20 63 6f 72 6e 65 72 17 03 05 00 09 31 00 6c 6f    corner.....1.lo
|   4032: 77 65 72 2d 72 69 67 68 74 20 63 6f 72 6e 65 72   wer-right corner
|   4048: 16 02 05 00 09 2f 00 75 70 70 65 72 2d 6c 65 66   ...../.upper-lef
|   4064: 74 20 63 6f 72 6e 65 72 06 00 05 00 01 00 00 03   t corner........
|   4080: 0d 88 4f 05 00 01 1b 00 02 62 6f 78 2d 33 2c 31   ..O......box-3,1
| page 3 offset 8192
|      0: 05 00 00 00 01 0f fb 00 00 00 00 06 0f fb 00 00   ................
|    384: 00 00 00 00 00 00 00 89 50 03 04 00 93 24 00 00   ........P....$..
|    400: 00 11 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
|    688: 00 00 00 00 42 c8 00 00 42 4c 00 00 42 00 00 00   ....B...BL..B...
|    720: 03 eb 40 40 00 00 40 80 00 00 00 00 00 00 3f 80   ..@@..@.......?.
|    736: 00 00 00 00 00 00 00 00 03 ea 40 00 00 00 40 40   ..........@...@@
|    752: 00 00 00 00 00 00 3f 80 00 00 00 00 00 00 00 00   ......?.........
|    768: 03 e9 3f 80 00 00 40 00 00 00 00 00 00 00 3f 80   ..?...@.......?.
|    784: 00 00 00 00 00 00 00 00 03 e8 00 00 00 00 3f 80   ..............?.
|    800: 00 00 00 00 00 00 3f 80 00 00 00 00 00 00 00 00   ......?.........
|   1616: 00 00 00 00 00 00 00 00 00 00 89 50 02 04 00 93   ...........P....
|   1632: 24 00 00 00 33 00 00 00 00 00 00 00 01 00 00 00   $...3...........
|   1648: 00 41 20 00 00 00 00 00 00 41 0e 00 00 00 00 00   .A ......A......
|   1664: 00 00 00 04 4f 40 40 00 00 40 80 00 00 3f 80 00   ....O@@..@...?..
|   1680: 00 40 00 00 00 00 00 00 00 00 00 04 4e 40 00 00   .@..........N@..
|   1696: 00 40 40 00 00 3f 80 00 00 40 00 00 00 00 00 00   .@@..?...@......
|   1712: 00 00 00 04 4d 3f 80 00 00 40 00 00 00 3f 80 00   ....M?...@...?..
|   1728: 00 40 00 00 00 00 00 00 00 00 00 04 4c 00 00 00   .@..........L...
|   1744: 00 3f 80 00 00 3f 80 00 00 40 00 00 00 00 00 00   .?...?...@......
|   1760: 00 00 00 04 b3 40 40 00 00 40 80 00 00 40 00 00   .....@@..@...@..
|   1776: 00 40 40 00 00 00 00 00 00 00 00 04 b2 40 00 00   .@@..........@..
|   1792: 00 40 40 00 00 40 00 00 00 40 40 00 00 00 00 00   .@@..@...@@.....
|   1808: 00 00 00 04 b1 3f 80 00 00 40 00 00 00 40 00 00   .....?...@...@..
|   1824: 00 40 40 00 00 00 00 00 00 00 00 04 b0 00 00 00   .@@.............
|   1840: 00 3f 80 00 00 40 00 00 00 40 40 00 00 00 00 00   .?...@...@@.....
|   1856: 00 00 00 05 17 40 40 00 00 40 80 00 00 40 40 00   .....@@..@...@@.
|   1872: 00 40 80 00 00 00 00 00 00 00 00 05 16 40 00 00   .@...........@..
|   1888: 00 40 40 00 00 40 40 00 00 40 80 00 00 00 00 00   .@@..@@..@......
|   1904: 00 00 00 05 15 3f 80 00 00 40 00 00 00 40 40 00   .....?...@...@@.
|   1920: 00 40 80 00 00 00 00 00 00 00 00 05 14 00 00 00   .@..............
|   1936: 00 3f 80 00 00 40 40 00 00 40 80 00 00 00 00 00   .?...@@..@......
|   1952: 00 00 00 05 7b 40 40 00 00 40 80 00 00 40 80 00   .....@@..@...@..
|   1968: 00 40 a0 00 00 00 00 00 00 00 00 05 7a 40 00 00   .@..........z@..
|   1984: 00 40 40 00 00 40 80 00 00 40 a0 00 00 00 00 00   .@@..@...@......
|   2000: 00 00 00 05 79 3f 80 00 00 40 00 00 00 40 80 00   ....y?...@...@..
|   2016: 00 40 a0 00 00 00 00 00 00 00 00 05 78 00 00 00   .@..........x...
|   2032: 00 3f 80 00 00 40 80 00 00 40 a0 00 00 00 00 00   .?...@...@......
|   2048: 00 00 00 05 df 40 40 00 00 40 80 00 00 40 a0 00   .....@@..@...@..
|   2064: 00 40 c0 00 00 00 00 00 00 00 00 05 de 40 00 00   .@...........@..
|   2080: 00 40 40 00 00 40 a0 00 00 40 c0 00 00 00 00 00   .@@..@...@......
|   2096: 00 00 00 05 dd 3f 80 00 00 40 00 00 00 40 a0 00   .....?...@...@..
|   2112: 00 40 c0 00 00 00 00 00 00 00 00 05 dc 00 00 00   .@..............
|   2128: 00 3f 80 00 00 40 a0 00 00 40 c0 00 00 00 00 00   .?...@...@......
|   2144: 00 00 00 06 43 40 40 00 00 40 80 00 00 40 c0 00   ....C@@..@...@..
|   2160: 00 40 e0 00 00 00 00 00 00 00 00 06 42 40 00 00   .@..........B@..
|   2176: 00 40 40 00 00 40 c0 00 00 40 e0 00 00 00 00 00   .@@..@...@......
|   2192: 00 00 00 06 41 3f 80 00 00 40 00 00 00 40 c0 00   ....A?...@...@..
|   2208: 00 40 e0 00 00 00 00 00 00 00 00 06 40 00 00 00   .@..........@...
|   2224: 00 3f 80 00 00 40 c0 00 00 40 e0 00 00 00 00 00   .?...@...@......
|   2240: 00 00 00 06 a7 40 40 00 00 40 80 00 00 40 e0 00   .....@@..@...@..
|   2256: 00 41 00 00 00 00 00 00 00 00 00 06 a6 40 00 00   .A...........@..
|   2272: 00 40 40 00 00 40 e0 00 00 41 00 00 00 00 00 00   .@@..@...A......
|   2288: 00 00 00 06 a5 3f 80 00 00 40 00 00 00 40 e0 00   .....?...@...@..
|   2304: 00 41 00 00 00 00 00 00 00 00 00 06 a4 00 00 00   .A..............
|   2320: 00 3f 80 00 00 40 e0 00 00 41 00 00 00 00 00 00   .?...@...A......
|   2336: 00 00 00 07 0a 40 00 00 00 40 40 00 00 41 00 00   .....@...@@..A..
|   2352: 00 41 10 00 00 00 00 00 00 00 00 07 09 3f 80 00   .A...........?..
|   2368: 00 40 00 00 00 41 00 00 00 41 10 00 00 00 00 00   .@...A...A......
|   2384: 00 00 00 07 08 00 00 00 00 3f 80 00 00 41 00 00   .........?...A..
|   2400: 00 41 10 00 00 00 00 00 00 00 00 07 6e 40 00 00   .A..........n@..
|   2416: 00 40 40 00 00 41 10 00 00 41 20 00 00 00 00 00   .@@..A...A .....
|   2432: 00 00 00 07 6d 3f 80 00 00 40 00 00 00 41 10 00   ....m?...@...A..
|   2448: 00 41 20 00 00 00 00 00 00 00 00 07 6c 00 00 00   .A .........l...
|   2464: 00 3f 80 00 00 41 10 00 00 41 20 00 00 00 00 00   .?...A...A .....
|   2480: 00 00 00 07 0b 40 40 00 00 40 80 00 00 41 00 00   .....@@..@...A..
|   2496: 00 41 10 00 00 00 00 00 00 00 00 07 6f 40 40 00   .A..........o@@.
|   2512: 00 40 80 00 00 41 10 00 00 41 20 00 00 00 00 00   .@...A...A .....
|   2528: 00 00 00 03 ec 40 80 00 00 40 a0 00 00 00 00 00   .....@...@......
|   2544: 00 3f 80 00 00 00 00 00 00 00 00 04 50 40 80 00   .?..........P@..
|   2560: 00 40 a0 00 00 3f 80 00 00 40 00 00 00 00 00 00   .@...?...@......
|   2576: 00 00 00 04 b4 40 80 00 00 40 a0 00 00 40 00 00   .....@...@...@..
|   2592: 00 40 40 00 00 00 00 00 00 00 00 05 18 40 80 00   .@@..........@..
|   2608: 00 40 a0 00 00 40 40 00 00 40 80 00 00 00 00 00   .@...@@..@......
|   2624: 00 00 00 05 7c 40 80 00 00 40 a0 00 00 40 80 00   ....|@...@...@..
|   2640: 00 40 a0 00 00 00 00 00 00 00 00 05 e0 40 80 00   .@...........@..
|   2656: 00 40 a0 00 00 40 a0 00 00 40 c0 00 00 00 00 00   .@...@...@......
|   2672: 00 00 00 06 44 40 80 00 00 40 a0 00 00 40 c0 00   ....D@...@...@..
|   2688: 00 40 e0 00 00 00 00 00 00 00 00 06 a8 40 80 00   .@...........@..
|   2704: 00 40 a0 00 00 40 e0 00 00 41 00 00 00 00 00 00   .@...@...A......
|   2720: 00 00 00 07 0c 40 80 00 00 40 a0 00 00 41 00 00   .....@...@...A..
|   2736: 00 41 10 00 00 00 00 00 00 00 00 07 70 40 80 00   .A..........p@..
|   2752: 00 40 a0 00 00 41 10 00 00 41 20 00 00 00 00 00   .@...A...A .....
|   2768: 00 00 00 03 ed 40 a0 00 00 40 c0 00 00 00 00 00   .....@...@......
|   2784: 00 3f 80 00 00 00 00 00 00 00 00 04 51 40 a0 00   .?..........Q@..
|   2800: 00 40 c0 00 00 3f 80 00 00 40 00 00 00 00 00 00   .@...?...@......
|   2816: 00 00 00 04 b5 40 a0 00 00 40 c0 00 00 40 00 00   .....@...@...@..
|   2832: 00 40 40 00 00 00 00 00 00 00 00 05 19 40 a0 00   .@@..........@..
|   2848: 00 40 c0 00 00 40 40 00 00 40 80 00 00 89 50 01   .@...@@..@....P.
|   2864: 04 00 93 24 00 01 00 02 00 00 00 00 00 00 00 03   ...$............
|   2880: 00 00 00 00 40 80 00 00 00 00 00 00 3f 80 00 00   ....@.......?...
|   2896: 00 00 00 00 00 00 00 02 00 00 00 00 41 20 00 00   ............A ..
|   2912: 00 00 00 00 41 20 00 00 00 00 00 00 00 00 00 00   ....A ..........
|   4080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 05 03   ................
| page 4 offset 12288
|      0: 0d 00 00 00 00 10 00 00 00 00 00 00 00 00 00 00   ................
| page 5 offset 16384
|      0: 0d 00 00 00 03 01 87 00 0b 2d 06 5a 01 87 00 00   .........-.Z....
|    384: 00 00 00 00 00 00 00 89 50 03 04 00 93 24 00 00   ........P....$..
|    400: 00 11 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
|    688: 00 00 00 00 42 c8 00 00 42 4c 00 00 42 00 00 00   ....B...BL..B...
|    720: 03 eb 40 40 00 00 40 80 00 00 00 00 00 00 3f 80   ..@@..@.......?.
|    736: 00 00 00 00 00 00 00 00 03 ea 40 00 00 00 40 40   ..........@...@@
|    752: 00 00 00 00 00 00 3f 80 00 00 00 00 00 00 00 00   ......?.........
|    768: 03 e9 3f 80 00 00 40 00 00 00 00 00 00 00 3f 80   ..?...@.......?.
|    784: 00 00 00 00 00 00 00 00 03 e8 00 00 00 00 3f 80   ..............?.
|    800: 00 00 00 00 00 00 3f 80 00 00 00 00 00 00 00 00   ......?.........
|   1616: 00 00 00 00 00 00 00 00 00 00 89 50 02 04 00 93   ...........P....
|   1632: 24 00 00 00 2d 00 00 00 00 00 00 04 4c 00 00 00   $...-.......L...
|   1648: 00 3f 80 00 00 3f 80 00 00 40 00 00 00 00 00 00   .?...?...@......
|   1664: 00 00 00 04 b0 00 00 00 00 3f 80 00 00 40 00 00   .........?...@..
|   1680: 00 40 40 00 00 00 00 00 00 00 00 05 14 00 00 00   .@@.............
|   1696: 00 3f 80 00 00 40 40 00 00 40 80 00 00 00 00 00   .?...@@..@......
|   1712: 00 00 00 05 78 00 00 00 00 3f 80 00 00 40 80 00   ....x....?...@..
|   1728: 00 40 a0 00 00 00 00 00 00 00 00 05 dc 00 00 00   .@..............
|   1744: 00 3f 80 00 00 40 a0 00 00 40 c0 00 00 00 00 00   .?...@...@......
|   1760: 00 00 00 00 01 00 00 00 00 41 20 00 00 00 00 00   .........A .....
|   1776: 00 41 0e 00 00 00 00 00 00 00 00 04 4d 3f 80 00   .A..........M?..
|   1792: 00 40 00 00 00 3f 80 00 00 40 00 00 00 00 00 00   .@...?...@......
|   1808: 00 00 00 04 b1 3f 80 00 00 40 00 00 00 40 00 00   .....?...@...@..
|   1824: 00 40 40 00 00 00 00 00 00 00 00 05 15 3f 80 00   .@@..........?..
|   1840: 00 40 00 00 00 40 40 00 00 40 80 00 00 00 00 00   .@...@@..@......
|   1856: 00 00 00 05 79 3f 80 00 00 40 00 00 00 40 80 00   ....y?...@...@..
|   1872: 00 40 a0 00 00 00 00 00 00 00 00 05 dd 3f 80 00   .@...........?..
|   1888: 00 40 00 00 00 40 a0 00 00 40 c0 00 00 00 00 00   .@...@...@......
|   1904: 00 00 00 04 4e 40 00 00 00 40 40 00 00 3f 80 00   ....N@...@@..?..
|   1920: 00 40 00 00 00 00 00 00 00 00 00 04 b2 40 00 00   .@...........@..
|   1936: 00 40 40 00 00 40 00 00 00 40 40 00 00 00 00 00   .@@..@...@@.....
|   1952: 00 00 00 05 16 40 00 00 00 40 40 00 00 40 40 00   .....@...@@..@@.
|   1968: 00 40 80 00 00 00 00 00 00 00 00 05 7a 40 00 00   .@..........z@..
|   1984: 00 40 40 00 00 40 80 00 00 40 a0 00 00 00 00 00   .@@..@...@......
|   2000: 00 00 00 05 de 40 00 00 00 40 40 00 00 40 a0 00   .....@...@@..@..
|   2016: 00 40 c0 00 00 00 00 00 00 00 00 04 4f 40 40 00   .@..........O@@.
|   2032: 00 40 80 00 00 3f 80 00 00 40 00 00 00 00 00 00   .@...?...@......
|   2048: 00 00 00 04 b3 40 40 00 00 40 80 00 00 40 00 00   .....@@..@...@..
|   2064: 00 40 40 00 00 00 00 00 00 00 00 05 17 40 40 00   .@@..........@@.
|   2080: 00 40 80 00 00 40 40 00 00 40 80 00 00 00 00 00   .@...@@..@......
|   2096: 00 00 00 05 7b 40 40 00 00 40 80 00 00 40 80 00   .....@@..@...@..
|   2112: 00 40 a0 00 00 00 00 00 00 00 00 05 df 40 40 00   .@...........@@.
|   2128: 00 40 80 00 00 40 a0 00 00 40 c0 00 00 00 00 00   .@...@...@......
|   2144: 00 00 00 03 ec 40 80 00 00 40 a0 00 00 00 00 00   .....@...@......
|   2160: 00 3f 80 00 00 00 00 00 00 00 00 04 50 40 80 00   .?..........P@..
|   2176: 00 40 a0 00 00 3f 80 00 00 40 00 00 00 00 00 00   .@...?...@......
|   2192: 00 00 00 04 b4 40 80 00 00 40 a0 00 00 40 00 00   .....@...@...@..
|   2208: 00 40 40 00 00 00 00 00 00 00 00 05 18 40 80 00   .@@..........@..
|   2224: 00 40 a0 00 00 40 40 00 00 40 80 00 00 00 00 00   .@...@@..@......
|   2240: 00 00 00 05 7c 40 80 00 00 40 a0 00 00 40 80 00   ....|@...@...@..
|   2256: 00 40 a0 00 00 00 00 00 00 00 00 05 e0 40 80 00   .@...........@..
|   2272: 00 40 a0 00 00 40 a0 00 00 40 c0 00 00 00 00 00   .@...@...@......
|   2288: 00 00 00 03 f0 41 00 00 00 41 10 00 00 00 00 00   .....A...A......
|   2304: 00 3f 80 00 00 00 00 00 00 00 00 04 54 41 00 00   .?..........TA..
|   2320: 00 41 10 00 00 3f 80 00 00 40 00 00 00 00 00 00   .A...?...@......
|   2336: 00 00 00 04 b8 41 00 00 00 41 10 00 00 40 00 00   .....A...A...@..
|   2352: 00 40 40 00 00 00 00 00 00 00 00 05 1c 41 00 00   .@@..........A..
|   2368: 00 41 10 00 00 40 40 00 00 40 80 00 00 00 00 00   .A...@@..@......
|   2384: 00 00 00 05 80 41 00 00 00 41 10 00 00 40 80 00   .....A...A...@..
|   2400: 00 40 a0 00 00 00 00 00 00 00 00 05 e4 41 00 00   .@...........A..
|   2416: 00 41 10 00 00 40 a0 00 00 40 c0 00 00 00 00 00   .A...@...@......
|   2432: 00 00 00 06 48 41 00 00 00 41 10 00 00 40 c0 00   ....HA...A...@..
|   2448: 00 40 e0 00 00 00 00 00 00 00 00 06 ac 41 00 00   .@...........A..
|   2464: 00 41 10 00 00 40 e0 00 00 41 00 00 00 00 00 00   .A...@...A......
|   2480: 00 00 00 07 10 41 00 00 00 41 10 00 00 41 00 00   .....A...A...A..
|   2496: 00 41 10 00 00 00 00 00 00 00 00 03 f1 41 10 00   .A...........A..
|   2512: 00 41 20 00 00 00 00 00 00 3f 80 00 00 00 00 00   .A ......?......
|   2528: 00 00 00 04 55 41 10 00 00 41 20 00 00 3f 80 00   ....UA...A ..?..
|   2544: 00 40 00 00 00 00 00 00 00 00 00 04 b9 41 10 00   .@...........A..
|   2560: 00 41 20 00 00 40 00 00 00 40 40 00 00 00 00 00   .A ..@...@@.....
|   2576: 00 00 00 05 1d 41 10 00 00 41 20 00 00 40 40 00   .....A...A ..@@.
|   2592: 00 40 80 00 00 00 00 00 00 00 00 05 81 41 10 00   .@...........A..
|   2608: 00 41 20 00 00 40 80 00 00 40 a0 00 00 00 00 00   .A ..@...@......
|   2624: 00 00 00 05 e5 41 10 00 00 41 20 00 00 40 a0 00   .....A...A ..@..
|   2640: 00 40 c0 00 00 00 00 00 00 00 00 06 49 41 10 00   .@..........IA..
|   2656: 00 41 20 00 00 40 c0 00 00 40 e0 00 00 00 00 00   .A ..@...@......
|   2672: 00 00 00 06 ad 41 10 00 00 41 20 00 00 40 e0 00   .....A...A ..@..
|   2688: 00 41 00 00 00 00 00 00 00 00 00 07 11 41 10 00   .A...........A..
|   2704: 00 41 20 00 00 41 00 00 00 41 10 00 00 00 00 00   .A ..A...A......
|   2848: 00 00 00 00 00 00 00 00 00 00 00 00 00 89 50 01   ..............P.
|   2864: 04 00 93 24 00 01 00 04 00 00 00 00 00 00 00 03   ...$............
|   2880: 00 00 00 00 40 80 00 00 00 00 00 00 3f 80 00 00   ....@.......?...
|   2896: 00 00 00 00 00 00 00 02 00 00 00 00 41 20 00 00   ............A ..
|   2912: 00 00 00 00 41 10 00 00 00 00 00 00 00 00 00 04   ....A...........
|   2928: 00 00 00 00 41 20 00 00 40 c0 00 00 41 20 00 00   ....A ..@...A ..
|   2944: 00 00 00 00 00 00 00 05 40 a0 00 00 41 00 00 00   ........@...A...
|   2960: 00 00 00 00 41 20 00 00 00 00 00 00 00 00 00 00   ....A ..........
| page 6 offset 20480
|      0: 0d 00 00 00 02 06 5a 00 0b 2d 06 5a 00 00 00 00   ......Z..-.Z....
|   1616: 00 00 00 00 00 00 00 00 00 00 89 50 05 04 00 93   ...........P....
|   1632: 24 00 00 00 1c 00 00 00 00 00 00 03 ed 40 a0 00   $............@..
|   1648: 00 40 c0 00 00 00 00 00 00 3f 80 00 00 00 00 00   .@.......?......
|   1664: 00 00 00 04 51 40 a0 00 00 40 c0 00 00 3f 80 00   ....Q@...@...?..
|   1680: 00 40 00 00 00 00 00 00 00 00 00 04 b5 40 a0 00   .@...........@..
|   1696: 00 40 c0 00 00 40 00 00 00 40 40 00 00 00 00 00   .@...@...@@.....
|   1712: 00 00 00 05 19 40 a0 00 00 40 c0 00 00 40 40 00   .....@...@...@@.
|   1728: 00 40 80 00 00 00 00 00 00 00 00 05 7d 40 a0 00   .@...........@..
|   1744: 00 40 c0 00 00 40 80 00 00 40 a0 00 00 00 00 00   .@...@...@......
|   1760: 00 00 00 05 e1 40 a0 00 00 40 c0 00 00 40 a0 00   .....@...@...@..
|   1776: 00 40 c0 00 00 00 00 00 00 00 00 06 45 40 a0 00   .@..........E@..
|   1792: 00 40 c0 00 00 40 c0 00 00 40 e0 00 00 00 00 00   .@...@...@......
|   1808: 00 00 00 06 a9 40 a0 00 00 40 c0 00 00 40 e0 00   .....@...@...@..
|   1824: 00 41 00 00 00 00 00 00 00 00 00 07 0d 40 a0 00   .A...........@..
|   1840: 00 40 c0 00 00 41 00 00 00 41 10 00 00 00 00 00   .@...A...A......
|   1856: 00 00 00 03 ee 40 c0 00 00 40 e0 00 00 00 00 00   .....@...@......
|   1872: 00 3f 80 00 00 00 00 00 00 00 00 04 52 40 c0 00   .?..........R@..
|   1888: 00 40 e0 00 00 3f 80 00 00 40 00 00 00 00 00 00   .@...?...@......
|   1904: 00 00 00 04 b6 40 c0 00 00 40 e0 00 00 40 00 00   .....@...@...@..
|   1920: 00 40 40 00 00 00 00 00 00 00 00 05 1a 40 c0 00   .@@..........@..
|   1936: 00 40 e0 00 00 40 40 00 00 40 80 00 00 00 00 00   .@...@@..@......
|   1952: 00 00 00 05 7e 40 c0 00 00 40 e0 00 00 40 80 00   ....~@...@...@..
|   1968: 00 40 a0 00 00 00 00 00 00 00 00 05 e2 40 c0 00   .@...........@..
|   1984: 00 40 e0 00 00 40 a0 00 00 40 c0 00 00 00 00 00   .@...@...@......
|   2000: 00 00 00 06 46 40 c0 00 00 40 e0 00 00 40 c0 00   ....F@...@...@..
|   2016: 00 40 e0 00 00 00 00 00 00 00 00 06 aa 40 c0 00   .@...........@..
|   2032: 00 40 e0 00 00 40 e0 00 00 41 00 00 00 00 00 00   .@...@...A......
|   2048: 00 00 00 07 0e 40 c0 00 00 40 e0 00 00 41 00 00   .....@...@...A..
|   2064: 00 41 10 00 00 00 00 00 00 00 00 03 ef 40 e0 00   .A...........@..
|   2080: 00 41 00 00 00 00 00 00 00 3f 80 00 00 00 00 00   .A.......?......
|   2096: 00 00 00 04 53 40 e0 00 00 41 00 00 00 3f 80 00   ....S@...A...?..
|   2112: 00 40 00 00 00 00 00 00 00 00 00 04 b7 40 e0 00   .@...........@..
|   2128: 00 41 00 00 00 40 00 00 00 40 40 00 00 00 00 00   .A...@...@@.....
|   2144: 00 00 00 05 1b 40 e0 00 00 41 00 00 00 40 40 00   .....@...A...@@.
|   2160: 00 40 80 00 00 00 00 00 00 00 00 05 7f 40 e0 00   .@...........@..
|   2176: 00 41 00 00 00 40 80 00 00 40 a0 00 00 00 00 00   .A...@...@......
|   2192: 00 00 00 05 e3 40 e0 00 00 41 00 00 00 40 a0 00   .....@...A...@..
|   2208: 00 40 c0 00 00 00 00 00 00 00 00 06 47 40 e0 00   .@..........G@..
|   2224: 00 41 00 00 00 40 c0 00 00 40 e0 00 00 00 00 00   .A...@...@......
|   2240: 00 00 00 06 ab 40 e0 00 00 41 00 00 00 40 e0 00   .....@...A...@..
|   2256: 00 41 00 00 00 00 00 00 00 00 00 07 0f 40 e0 00   .A...........@..
|   2272: 00 41 00 00 00 41 00 00 00 41 10 00 00 00 00 00   .A...A...A......
|   2288: 00 00 00 07 73 40 e0 00 00 41 00 00 00 41 10 00   ....s@...A...A..
|   2304: 00 41 20 00 00 00 00 00 00 00 00 00 00 00 00 00   .A .............
|   2848: 00 00 00 00 00 00 00 00 00 00 00 00 00 89 50 04   ..............P.
|   2864: 04 00 93 24 00 00 00 18 00 00 00 00 00 00 06 43   ...$...........C
|   2880: 40 40 00 00 40 80 00 00 40 c0 00 00 40 e0 00 00   @@..@...@...@...
|   2896: 00 00 00 00 00 00 06 42 40 00 00 00 40 40 00 00   .......B@...@@..
|   2912: 40 c0 00 00 40 e0 00 00 00 00 00 00 00 00 06 41   @...@..........A
|   2928: 3f 80 00 00 40 00 00 00 40 c0 00 00 40 e0 00 00   ?...@...@...@...
|   2944: 00 00 00 00 00 00 06 40 00 00 00 00 3f 80 00 00   .......@....?...
|   2960: 40 c0 00 00 40 e0 00 00 00 00 00 00 00 00 06 44   @...@..........D
|   2976: 40 80 00 00 40 a0 00 00 40 c0 00 00 40 e0 00 00   @...@...@...@...
|   2992: 00 00 00 00 00 00 06 a7 40 40 00 00 40 80 00 00   ........@@..@...
|   3008: 40 e0 00 00 41 00 00 00 00 00 00 00 00 00 06 a6   @...A...........
|   3024: 40 00 00 00 40 40 00 00 40 e0 00 00 41 00 00 00   @...@@..@...A...
|   3040: 00 00 00 00 00 00 06 a5 3f 80 00 00 40 00 00 00   ........?...@...
|   3056: 40 e0 00 00 41 00 00 00 00 00 00 00 00 00 06 a4   @...A...........
|   3072: 00 00 00 00 3f 80 00 00 40 e0 00 00 41 00 00 00   ....?...@...A...
|   3088: 00 00 00 00 00 00 06 a8 40 80 00 00 40 a0 00 00   ........@...@...
|   3104: 40 e0 00 00 41 00 00 00 00 00 00 00 00 00 07 0a   @...A...........
|   3120: 40 00 00 00 40 40 00 00 41 00 00 00 41 10 00 00   @...@@..A...A...
|   3136: 00 00 00 00 00 00 07 09 3f 80 00 00 40 00 00 00   ........?...@...
|   3152: 41 00 00 00 41 10 00 00 00 00 00 00 00 00 07 08   A...A...........
|   3168: 00 00 00 00 3f 80 00 00 41 00 00 00 41 10 00 00   ....?...A...A...
|   3184: 00 00 00 00 00 00 07 0b 40 40 00 00 40 80 00 00   ........@@..@...
|   3200: 41 00 00 00 41 10 00 00 00 00 00 00 00 00 07 0c   A...A...........
|   3216: 40 80 00 00 40 a0 00 00 41 00 00 00 41 10 00 00   @...@...A...A...
|   3232: 00 00 00 00 00 00 07 6e 40 00 00 00 40 40 00 00   .......n@...@@..
|   3248: 41 10 00 00 41 20 00 00 00 00 00 00 00 00 07 6d   A...A .........m
|   3264: 3f 80 00 00 40 00 00 00 41 10 00 00 41 20 00 00   ?...@...A...A ..
|   3280: 00 00 00 00 00 00 07 6c 00 00 00 00 3f 80 00 00   .......l....?...
|   3296: 41 10 00 00 41 20 00 00 00 00 00 00 00 00 07 6f   A...A .........o
|   3312: 40 40 00 00 40 80 00 00 41 10 00 00 41 20 00 00   @@..@...A...A ..
|   3328: 00 00 00 00 00 00 07 70 40 80 00 00 40 a0 00 00   .......p@...@...
|   3344: 41 10 00 00 41 20 00 00 00 00 00 00 00 00 07 71   A...A .........q
|   3360: 40 a0 00 00 40 c0 00 00 41 10 00 00 41 20 00 00   @...@...A...A ..
|   3376: 00 00 00 00 00 00 07 72 40 c0 00 00 40 e0 00 00   .......r@...@...
|   3392: 41 10 00 00 41 20 00 00 00 00 00 00 00 00 07 74   A...A .........t
|   3408: 41 00 00 00 41 10 00 00 41 10 00 00 41 20 00 00   A...A...A...A ..
|   3424: 00 00 00 00 00 00 07 75 41 10 00 00 41 20 00 00   .......uA...A ..
|   3440: 41 10 00 00 41 20 00 00 00 00 00 00 00 00 00 00   A...A ..........
| end c1b.db
  }]
  catchsql {
     SELECT rtreecheck('t1');
  }
} {1 {SQL logic error}}

do_test rtreefuzz001-200 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
| size 16384 pagesize 4096 filename c3.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 01 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 00 00 00 04 0e 9c 00 0f ad 0f 4f   ...............O
|    112: 0e fc 0e 9c 00 00 00 00 00 00 00 00 00 00 00 00   ................
|   3728: 00 00 00 00 00 00 00 00 00 00 00 00 5e 04 07 17   ............^...
|   3744: 1f 1f 01 81 0b 74 61 62 6c 65 74 31 5f 70 61 72   .....tablet1_par
|   3760: 65 6e 74 74 31 5f 70 61 72 65 6e 74 04 43 52 45   entt1_parent.CRE
|   3776: 41 54 45 20 54 41 42 4c 45 20 22 74 31 5f 70 61   ATE TABLE .t1_pa
|   3792: 72 65 6e 74 22 28 6e 6f 64 65 6e 6f 20 49 4e 54   rent.(nodeno INT
|   3808: 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59   EGER PRIMARY KEY
|   3824: 2c 70 61 72 65 6e 74 6e 6f 64 65 29 51 03 06 17   ,parentnode)Q...
|   3840: 1b 1b 01 7b 74 61 62 6c 65 74 31 5f 6e 6f 64 65   ....tablet1_node
|   3856: 74 31 5f 6e 6f 64 65 03 43 52 45 41 54 45 20 54   t1_node.CREATE T
|   3872: 41 42 4c 45 20 22 74 31 5f 6e 6f 64 65 22 28 6e   ABLE .t1_node.(n
|   3888: 6f 64 65 6e 6f 20 49 4e 54 45 47 45 52 20 50 52   odeno INTEGER PR
|   3904: 49 4d 41 52 59 20 4b 45 59 2c 64 61 74 61 29 5c   IMARY KEY,data).
|   3920: 02 07 17 1d 1d 01 81 0b 74 61 62 6c 65 74 31 5f   ........tablet1_
|   3936: 72 6f 77 69 64 74 31 5f 72 6f 77 69 64 02 43 52   rowidt1_rowid.CR
|   3952: 45 41 54 45 20 54 41 42 4c 45 20 22 74 31 5f 72   EATE TABLE .t1_r
|   3968: 6f 77 69 64 22 28 72 6f 77 69 64 20 49 4e 54 45   owid.(rowid INTE
|   3984: 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c   GER PRIMARY KEY,
|   4000: 6e 6f 64 65 6e 6f 2c 61 30 2c 61 31 29 51 01 07   nodeno,a0,a1)Q..
|   4016: 17 11 11 08 81 0f 74 61 62 6c 65 74 31 74 31 43   ......tablet1t1C
|   4032: 52 45 41 54 45 20 56 49 52 54 55 41 4c 20 54 41   REATE VIRTUAL TA
|   4048: 42 4c 45 20 74 31 20 55 53 49 4e 47 20 72 74 72   BLE t1 USING rtr
|   4064: 65 65 28 69 64 2c 78 30 2c 78 31 2c 79 30 2c 79   ee(id,x0,x1,y0,y
|   4080: 31 2c 2b 6c 61 62 65 6c 2c 2b 6f 74 68 65 72 29   1,+label,+other)
| page 2 offset 4096
|      0: 0d 00 00 00 0e 0e f7 00 0f e8 0f d0 0f b7 0f 9e   ................
|     16: 0f 91 0f 81 0f 70 0f 5e 0f 4f 0f 39 0f 29 0f 18   .....p.^.O.9.)..
|     32: 0f 06 0e f7 00 00 00 00 00 00 00 00 00 00 00 00   ................
|   3824: 00 00 00 00 00 00 00 0d 0e 05 00 09 1d 00 74 6f   ..............to
|   3840: 70 20 68 61 6c 66 10 0d 05 00 09 23 00 62 6f 74   p half.....#.bot
|   3856: 74 6f 6d 20 68 61 6c 66 0f 0c 05 00 09 21 00 72   tom half.....!.r
|   3872: 69 67 68 74 20 68 61 6c 66 0e 0b 05 00 09 1f 00   ight half.......
|   3888: 6c 65 66 74 20 68 61 6c 66 14 0a 05 00 09 2b 00   left half.....+.
|   3904: 74 68 65 20 77 68 6f 6c 65 20 74 68 69 6e 67 0d   the whole thing.
|   3920: 09 05 00 09 1d 00 74 6f 70 20 65 64 67 65 10 08   ......top edge..
|   3936: 05 00 09 23 00 62 6f 74 74 6f 6d 20 65 64 67 65   ...#.bottom edge
|   3952: 0f 07 05 00 09 21 00 72 69 67 68 74 20 65 64 67   .....!.right edg
|   3968: 65 0e 06 05 00 09 1f 00 6c 65 66 74 20 65 64 67   e.......left edg
|   3984: 65 0b 05 05 00 09 19 00 63 65 6e 74 65 72 17 04   e.......center..
|   4000: 05 00 09 31 00 75 70 70 65 72 2d 72 69 67 68 74   ...1.upper-right
|   4016: 20 63 6f 72 6e 65 72 17 03 05 00 09 31 00 6c 6f    corner.....1.lo
|   4032: 77 65 72 2d 72 69 67 68 74 27 60 f6 32 6e 65 72   wer-right'`.2ner
|   4048: 16 02 05 00 09 2f 00 75 70 70 65 72 2d 6c 65 66   ...../.upper-lef
|   4064: 74 20 63 6f 72 6e 65 72 16 01 05 00 09 2f 00 6c   t corner...../.l
|   4080: 6f 77 65 72 2d 6c 65 66 74 20 63 6f 72 6e 65 72   ower-left corner
| page 3 offset 8192
|      0: 0d 00 00 00 02 0b 2d 00 0b 2d 00 00 00 00 00 00   ......-..-......
|   2848: 00 00 00 00 00 00 00 00 00 00 00 00 00 89 50 01   ..............P.
|   2864: 04 00 93 24 00 00 00 0e 00 00 00 00 00 00 00 01   ...$............
|   2880: 00 00 00 00 41 20 00 00 00 00 00 00 41 20 01 00   ....A ......A ..
|   2896: 00 00 00 00 00 00 00 02 00 00 00 00 41 00 00 04   ............A...
|   2912: 2b 40 00 0c 42 c8 00 00 00 00 00 00 00 00 00 03   +@..B...........
|   2928: 42 b4 00 00 42 c8 00 00 00 00 00 00 41 20 00 00   B...B.......A ..
|   2944: 00 00 00 00 00 00 00 04 42 b4 00 00 42 c8 00 00   ........B...B...
|   2960: 42 b4 00 00 42 c8 00 00 00 00 00 00 00 00 00 05   B...B...........
|   2976: 42 20 00 00 42 70 00 00 42 20 00 00 42 70 00 00   B ..Bp..B ..Bp..
|   2992: 00 00 00 00 00 00 00 60 00 00 00 04 0a 00 00 00   .......`........
|   3008: 00 00 00 42 c8 00 00 00 00 00 00 00 00 00 07 42   ...B...........B
|   3024: be 00 00 42 c8 00 00 00 00 00 00 42 c8 00 00 00   ...B.......B....
|   3040: 00 00 00 00 00 00 08 00 00 00 00 42 c8 00 00 00   ...........B....
|   3056: 00 00 00 40 a0 00 00 00 00 00 00 00 00 00 09 00   ...@............
|   3072: 00 00 00 42 c8 00 00 42 be 00 00 42 c8 00 00 00   ...B...B...B....
|   3088: 00 00 00 00 00 00 0a 00 00 00 00 42 c8 00 00 00   ...........B....
|   3104: 00 00 00 42 c8 00 00 00 00 00 00 00 00 00 0b 00   ...B............
|   3120: 00 00 00 42 48 00 00 00 00 00 04 2c 80 00 00 00   ...BH......,....
|   3136: 00 00 00 00 00 00 c4 24 c0 00 04 2c 80 00 00 00   .......$...,....
|   3152: 00 00 04 2c 80 00 00 00 00 00 00 00 00 00 d0 00   ...,............
|   3168: 00 00 04 2c 80 00 00 00 00 00 04 24 80 00 00 00   ...,.......$....
|   3184: 00 00 00 00 00 00 e0 00 00 00 04 2c 80 00 04 24   ...........,...$
|   3200: c0 00 04 2c 00 00 00 00 00 00 00 00 00 00 00 00   ...,............
| page 4 offset 12288
|      0: 0d 00 00 00 00 10 00 00 00 00 00 00 00 00 00 00   ................
| end c3.db
  }]
  catchsql {
    WITH RECURSIVE
      c1(x) AS (VALUES(0) UNION ALL SELECT x+1 FROM c1 WHERE x<99),
      c2(y) AS (VALUES(0) UNION ALL SELECT y+1 FROM c2 WHERE y<99)
    INSERT INTO t1(id, x0,x1,y0,y1,label)
      SELECT 1000+x+y*100, x, x+1, y, y+1, printf('box-%d,%d',x,y) FROM c1, c2;
  }
} {1 {database disk image is malformed}}
do_test rtreefuzz001-210 {
  catchsql {
    SELECT rtreecheck('t1');
  }
} {/1 .*corrupt.*/}

do_test rtreefuzz001-300 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
| size 16384 pagesize 4096 filename c4.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   ................
|     96: 00 00 00 00 0d 00 00 00 04 0e 9c 00 0f ad 0f 4f   ...............O
|    112: 0e fc 0e 9c 00 00 00 00 00 00 00 00 00 00 00 00   ................
|   3728: 00 00 00 00 00 00 00 00 00 00 00 00 5e 04 07 17   ............^...
|   3744: 1f 1f 01 81 0b 74 61 62 6c 65 74 31 5f 70 61 72   .....tablet1_par
|   3760: 65 6e 74 74 31 5f 70 61 72 65 6e 74 04 43 52 45   entt1_parent.CRE
|   3776: 41 54 45 20 54 41 42 4c 45 20 22 74 31 5f 70 61   ATE TABLE .t1_pa
|   3792: 72 65 6e 74 22 28 6e 6f 64 65 6e 6f 20 49 4e 54   rent.(nodeno INT
|   3808: 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59   EGER PRIMARY KEY
|   3824: 2c 70 61 72 65 6e 74 6e 6f 64 65 29 51 03 06 17   ,parentnode)Q...
|   3840: 1b 1b 01 7b 74 61 62 6c 65 74 31 5f 6e 6f 64 65   ....tablet1_node
|   3856: 74 31 5f 6e 6f 64 65 03 43 52 45 41 54 45 20 54   t1_node.CREATE T
|   3872: 41 42 4c 45 20 22 74 31 5f 6e 6f 64 65 22 28 6e   ABLE .t1_node.(n
|   3888: 6f 64 65 6e 6f 20 49 4e 54 45 47 45 52 20 50 52   odeno INTEGER PR
|   3904: 49 4d 41 52 59 20 4b 45 59 2c 64 61 74 61 29 5c   IMARY KEY,data).
|   3920: 02 07 17 1d 1d 01 81 0b 74 61 62 6c 65 74 31 5f   ........tablet1_
|   3936: 72 6f 77 69 64 74 31 5f 72 6f 77 69 64 02 43 52   rowidt1_rowid.CR
|   3952: 45 41 54 45 20 54 41 42 4c 45 20 22 74 31 5f 72   EATE TABLE .t1_r
|   3968: 6f 77 69 64 22 28 72 6f 77 69 64 20 49 4e 54 45   owid.(rowid INTE
|   3984: 47 45 72 20 50 52 49 4d 41 52 59 20 4b 45 59 2c   GEr PRIMARY KEY,
|   4000: 6e 6f 64 65 6e 6f 2c 61 30 2c 61 31 29 51 01 07   nodeno,a0,a1)Q..
|   4016: 17 11 11 08 81 0f 74 61 62 6c 65 74 31 74 31 43   ......tablet1t1C
|   4032: 52 45 41 54 45 20 56 49 52 54 55 41 4c 20 54 41   REATE VIRTUAL TA
|   4048: 42 4c 45 20 74 31 20 55 53 49 4e 47 20 72 74 72   BLE t1 USING rtr
|   4064: 65 65 28 69 64 2c 78 30 2c 78 31 2c 79 30 2c 79   ee(id,x0,x1,y0,y
|   4080: 31 2c 2b 6c 61 62 65 6c 2c 2b 6f 74 68 65 72 29   1,+label,+other)
| page 2 offset 4096
|      0: 0d 00 00 00 0e 0e f7 00 0f e8 0f 00 fb 70 f9 e0   .............p..
|     16: f9 10 f8 10 f7 00 f5 e0 f4 f0 f3 90 f2 90 f1 80   ................
|     32: f0 60 ef 00 00 00 00 00 00 00 00 00 00 00 00 00   .`..............
|   3824: 00 00 00 00 00 00 00 0d 0e 05 00 09 1d 00 74 6f   ..............to
|   3840: 70 20 68 61 6c 66 10 0d 05 00 09 23 00 62 6f 74   p half.....#.bot
|   3856: 74 6f 6d 20 68 61 6c 66 0f 0c 05 00 09 21 00 72   tom half.....!.r
|   3872: 69 67 68 74 20 68 61 6c 66 0e 0b 05 00 09 1f 00   ight half.......
|   3888: 6c 65 66 74 20 68 61 6c 66 14 0a 05 00 09 2b 00   left half.....+.
|   3904: 00 03 98 20 49 98 2f 6c 62 05 74 68 69 6e 67 0d   ... I./lb.thing.
|   3920: 09 05 00 09 1d 00 74 6f 70 20 65 64 67 65 10 08   ......top edge..
|   3936: 05 00 09 23 00 62 6f 74 74 6f 6d 20 65 64 67 65   ...#.bottom edge
|   3952: 0f 07 05 00 09 21 00 72 69 67 68 74 20 65 64 67   .....!.right edg
|   3968: 65 0e 06 05 00 09 1f 00 6c 65 66 74 20 65 64 67   e.......left edg
|   3984: 65 0b 05 05 00 09 19 00 63 65 6e 74 65 72 17 04   e.......center..
|   4000: 05 00 09 31 00 75 70 70 65 72 2d 72 69 67 68 74   ...1.upper-right
|   4016: 20 63 6f 72 6e 65 72 17 03 05 00 09 31 00 6c 6f    corner.....1.lo
|   4032: 77 65 72 2d 72 69 67 68 74 20 63 6f 72 6e 65 72   wer-right corner
|   4048: 16 02 05 00 09 2f 00 75 70 70 65 72 2d 6c 65 66   ...../.upper-lef
|   4064: 74 20 63 6f 72 6e 65 72 16 01 05 00 09 2f 00 6c   t corner...../.l
|   4080: 6f 77 65 72 2d 6c 65 66 74 20 63 6f 72 6e 65 72   ower-left corner
| page 3 offset 8192
|      0: 0d 00 00 00 01 0b 2d 00 0b 2d 00 00 00 00 00 00   ......-..-......
|   2848: 00 00 00 00 00 00 00 00 00 00 00 00 00 89 50 01   ..............P.
|   2864: 04 00 93 24 00 00 00 0e 00 00 00 00 00 00 00 01   ...$............
|   2880: 00 00 00 04 01 20 00 00 00 00 00 04 12 00 00 00   ..... ..........
|   2896: 00 00 00 00 00 00 00 23 00 00 00 00 41 20 00 00   .......#....A ..
|   2912: 42 b4 00 00 42 c8 00 00 00 00 00 00 00 00 00 03   B...B...........
|   2928: 42 b4 00 00 42 c8 00 00 00 00 00 00 41 20 00 00   B...B.......A ..
|   2944: 00 00 00 00 00 00 00 04 42 b4 00 00 42 c8 00 00   ........B...B...
|   2960: 42 b4 00 00 42 c8 00 00 00 00 00 00 00 00 00 05   B...B...........
|   2976: 42 20 00 00 42 70 00 00 42 20 00 00 42 70 00 00   B ..Bp..B ..Bp..
|   2992: 00 00 00 00 00 00 00 06 00 00 00 00 40 a0 00 00   ............@...
|   3008: 00 00 00 04 2c 80 00 00 00 00 00 00 00 00 00 74   ....,..........t
|   3024: 2b e0 00 04 2c 80 00 04 2c 80 00 00 00 00 00 00   +...,...,.......
|   3040: 00 00 00 80 00 00 00 04 2c 80 00 00 00 00 00 04   ........,.......
|   3056: 0a 00 00 00 00 00 b0 80 00 00 04 2c 80 00 04 2b   ...........,...+
|   3072: e0 00 04 2c 80 00 00 00 00 00 00 00 00 00 a0 00   ...,............
|   3088: 00 00 04 2c 80 00 00 00 00 00 04 2c 80 00 00 00   ...,.......,....
|   3104: 00 00 00 00 00 00 b0 00 00 00 04 24 80 00 00 00   ...........$....
|   3120: 00 00 04 2c 80 00 00 00 00 00 00 00 50 00 91 f0   ...,........P...
|   3136: 06 c6 56 67 42 06 86 16 c6 61 40 a0 50 00 92 b0   ..VgB....a@.P...
|   3152: 07 46 86 52 07 76 86 f6 c6 52 07 46 86 96 e6 70   .F.R.v...R.F...p
|   3168: d0 90 50 00 91 d0 07 46 f7 02 06 56 46 76 51 00   ..P....F...VFvQ.
|   3184: 80 50 00 92 30 06 26 f7 47 46 f6 d2 06 56 46 76   .P..0.&.GF...VFv
|   3200: 50 f0 70 50 00 92 10 07 26 96 76 87 42 06 56 46   P.pP....&.v.B.VF
|   3216: 76 50 e0 60 50 00 91 f0 06 c6 56 67 42 06 56 46   vP.`P.....VgB.VF
|   3232: 76 50 b0 50 50 00 91 90 06 36 56 e7 46 57 21 70   vP.PP....6V.FW!p
|   3248: 40 50 00 93 10 07 57 07 06 57 22 d7 26 96 76 87   @P....W..W..&.v.
|   3264: 42 06 36 f7 26 e6 57 21 70 30 50 00 93 10 06 c6   B.6.&.W!p0P.....
|   3280: f7 76 57 22 d7 26 96 76 87 42 06 36 f7 26 e6 57   .vW..&.v.B.6.&.W
|   3296: 21 60 20 50 00 92 f0 07 57 07 06 57 22 d6 c6 56   !` P....W..W...V
|   3312: 60 00 00 c4 24 c0 00 04 2c 80 00 00 00 00 00 04   `...$...,.......
|   3328: 2c 80 00 00 00 00 00 00 00 00 00 d0 00 00 00 04   ,...............
|   3344: 2c 80 00 00 00 00 00 04 24 80 00 00 00 00 00 00   ,.......$.......
|   3360: 00 00 00 e0 00 00 00 04 2c 80 00 04 24 c0 00 04   ........,...$...
|   3376: 2c 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ,...............
| page 4 offset 12288
|      0: 0d 00 00 00 00 10 00 00 00 00 00 00 00 00 00 00   ................
| end c4.db
  }]
  catchsql {
    UPDATE t1 SET label='x';
  }
} {1 {rtree constraint failed: t1.(y0<=y1)}}
do_test rtreefuzz001-310 {
  catchsql {
    SELECT rtreecheck('t1');
  }
} {/1 .*corrupt.*/}

do_test rtreefuzz001-400 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
| size 16384 pagesize 4096 filename c7.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 01 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 00 00 00 04 0e 9c 00 0f ad 0f 4f   ...............O
|    112: 0e fc 0e 9c 00 00 00 00 00 00 00 00 00 00 00 00   ................
|   3728: 00 00 00 00 00 00 00 00 00 00 00 00 5e 04 07 17   ............^...
|   3744: 1f 1f 01 81 0b 74 61 62 6c 65 74 31 5f 70 61 72   .....tablet1_par
|   3760: 65 6e 74 74 31 5f 70 61 72 65 6e 74 04 43 52 45   entt1_parent.CRE
|   3776: 41 54 45 20 54 41 42 4c 45 20 22 74 31 5f 70 61   ATE TABLE .t1_pa
|   3792: 72 65 6e 74 22 28 6e 6f 64 65 6e 6f 20 49 4e 54   rent.(nodeno INT
|   3808: 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59   EGER PRIMARY KEY
|   3824: 2c 70 61 72 65 6e 74 6e 6f 64 65 29 51 03 06 17   ,parentnode)Q...
|   3840: 1b 1b 01 7b 74 61 62 6c 65 74 31 5f 6e 6f 64 65   ....tablet1_node
|   3856: 74 31 5f 6e 6f 64 65 03 43 52 45 41 54 45 20 54   t1_node.CREATE T
|   3872: 41 42 4c 45 20 22 74 31 5f 6e 6f 64 65 22 28 6e   ABLE .t1_node.(n
|   3888: 6f 64 65 6e 6f 20 49 4e 54 45 47 45 52 20 50 52   odeno INTEGER PR
|   3904: 49 4d 41 52 59 20 4b 45 59 2c 64 61 74 61 29 5c   IMARY KEY,data).
|   3920: 02 07 17 1d 1d 01 81 0b 74 61 62 6c 65 74 31 5f   ........tablet1_
|   3936: 72 6f 77 69 64 74 31 5f 72 6f 77 69 64 02 43 52   rowidt1_rowid.CR
|   3952: 45 41 54 45 20 54 41 42 4c 45 20 22 74 31 5f 72   EATE TABLE .t1_r
|   3968: 6f 77 69 64 22 28 72 6f 77 69 64 20 49 4e 54 45   owid.(rowid INTE
|   3984: 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c   GER PRIMARY KEY,
|   4000: 6e 6f 64 65 6e 6f 2c 61 30 2c 61 31 29 51 01 07   nodeno,a0,a1)Q..
|   4016: 17 11 11 08 81 0f 74 61 62 6c 65 74 31 74 31 43   ......tablet1t1C
|   4032: 52 45 41 54 45 20 56 49 52 54 55 41 4c 20 54 41   REATE VIRTUAL TA
|   4048: 42 4c 45 20 74 31 20 55 53 49 4e 47 20 72 74 72   BLE t1 USING rtr
|   4064: 65 65 28 69 64 2c 78 30 2c 78 31 2c 79 30 2c 79   ee(id,x0,x1,y0,y
|   4080: 31 2c 2b 6c 61 62 65 6c 2c 2b 6f 74 68 65 72 29   1,+label,+other)
| page 2 offset 4096
|      0: 0d 00 00 00 0e 0e f7 00 0f e8 0f d0 0f b7 0f 9e   ................
|     16: 0f 91 0f 81 0f 70 0f 5e 0f 4f 0f 39 0f 29 0f 18   .....p.^.O.9.)..
|     32: 0f 06 0e f7 00 00 00 00 00 00 00 00 00 00 00 00   ................
|   3824: 00 00 00 00 00 00 00 0d 0e 05 00 09 1d 00 74 6f   ..............to
|   3840: 70 20 68 61 6c 66 10 0d 05 00 09 23 00 62 6f 74   p half.....#.bot
|   3856: 74 6f 6d 20 68 61 6c 66 0f 0c 05 00 09 21 00 72   tom half.....!.r
|   3872: 69 67 68 74 20 68 61 6c 66 0e 0b 05 00 09 1f 00   ight half.......
|   3888: 6c 65 66 74 20 68 61 6c 66 14 0a 05 00 09 2b 00   left half.....+.
|   3904: 74 68 65 20 77 68 6f 6c 65 20 74 68 69 6e 67 0d   the whole thing.
|   3920: 09 05 00 09 1d 00 74 6f 70 20 65 64 67 65 10 08   ......top edge..
|   3936: 05 00 09 23 00 62 6f 74 74 6f 6d 20 65 64 67 65   ...#.bottom edge
|   3952: 0f 07 05 00 09 21 00 72 69 67 68 74 20 65 64 67   .....!.right edg
|   3968: 65 0e 06 05 00 09 1f 00 6c 65 66 74 20 65 64 67   e.......left edg
|   3984: 65 0b 05 05 00 09 19 00 23 65 6e 74 65 72 17 04   e.......#enter..
|   4000: 05 00 09 31 00 75 70 70 65 72 2d 72 69 67 68 74   ...1.upper-right
|   4016: 20 63 6f 72 6e 65 72 17 03 05 00 09 31 00 6c 6f    corner.....1.lo
|   4032: 77 65 72 2d 72 69 67 68 74 20 63 6f 72 6e 65 72   wer-right corner
|   4048: 16 02 05 00 09 2f 00 75 70 70 65 72 2d 6c 65 66   ...../.upper-lef
|   4064: 74 20 63 6f 72 6e 65 72 16 01 05 00 09 2f 00 6c   t corner...../.l
|   4080: 6f 77 65 72 2d 6c 65 66 74 20 63 6f 72 6e 65 72   ower-left corner
| page 3 offset 8192
|      0: 0d 00 00 00 02 0b 2d 00 0b 2d 00 00 00 00 00 00   ......-..-......
|   2848: 00 00 00 00 00 00 00 00 00 00 00 00 00 89 50 01   ..............P.
|   2864: 04 00 93 24 00 00 00 00 00 00 00 00 08 00 00 00   ...$............
|   2880: 00 42 c8 00 00 00 00 00 00 40 a0 00 00 00 00 00   .B.......@......
|   2896: 00 00 00 00 42 c8 00 00 00 00 00 00 00 00 00 07   ....B...........
|   2912: 42 be 00 00 42 c8 00 00 00 00 00 00 42 c8 00 00   B...B.......B...
|   2928: 00 00 00 00 00 00 00 08 00 00 00 00 42 c8 00 00   ............B...
|   2944: 00 00 00 00 40 a0 00 00 00 00 00 00 00 00 00 09   ....@...........
|   2960: 00 00 00 00 42 c8 00 00 42 be 00 00 42 c8 00 00   ....B...B...B...
|   2976: 00 00 00 00 00 00 00 0a 00 00 00 00 42 c8 00 00   ............B...
|   2992: 00 00 00 00 42 c8 00 00 00 00 00 00 00 00 00 0b   ....B...........
|   3008: 00 00 00 00 42 48 00 00 00 00 00 04 2c 80 00 00   ....BH......,...
|   3024: 00 00 00 00 00 00 00 c4 00 00 00 00 00 42 c8 00   .............B..
|   3040: 00 00 00 00 00 00 00 00 07 42 be 00 00 42 c8 00   .........B...B..
|   3056: 00 00 00 00 00 42 c8 00 00 00 00 00 00 00 00 00   .....B..........
|   3072: 08 00 00 00 00 42 c8 00 00 00 00 00 00 40 a0 00   .....B.......@..
|   3088: 00 00 00 00 00 00 00 00 09 00 00 00 00 42 c8 00   .............B..
|   3104: 00 42 be 00 00 42 c8 00 00 00 00 00 00 00 00 00   .B...B..........
|   3120: 0a 00 00 00 00 42 c8 00 00 00 00 00 00 42 c8 00   .....B.......B..
|   3136: 00 00 00 00 00 00 00 00 0b 00 00 00 00 42 48 00   .............BH.
|   3152: 00 00 00 00 04 2c 80 00 00 00 00 00 00 00 00 00   .....,..........
|   3168: c4 24 c0 00 04 2c 80 00 00 00 00 00 04 2c 80 00   .$...,.......,..
|   3184: 00 00 00 00 00 00 00 00 d0 00 00 00 04 2c 80 00   .............,..
|   3200: 00 00 00 00 04 24 80 00 00 00 00 00 00 00 00 00   .....$..........
|   3216: e0 00 00 00 04 2c 80 00 04 24 c0 00 04 2c 00 00   .....,...$...,..
| page 4 offset 12288
|      0: 0d 00 00 00 00 10 00 00 00 00 00 00 0e 00 00 00   ................
|     16: 00 42 c8 00 00 42 4c 00 00 42 c8 00 00 00 00 00   .B...BL..B......
|     32: 00 00 00 0a 00 00 00 00 42 c8 00 00 00 00 00 00   ........B.......
|     48: 42 c8 00 00 00 00 00 00 00 00 00 0b 00 00 00 00   B...............
|     64: 42 48 00 00 00 00 00 04 2c 80 00 00 00 00 00 00   BH......,.......
|     80: 00 00 00 c4 24 c0 00 04 2c 80 00 00 00 00 00 04   ....$...,.......
|     96: 2c 80 00 00 00 00 00 00 00 00 00 d0 00 00 00 04   ,...............
|    112: 2c 80 00 00 00 00 00 04 24 80 00 00 00 00 00 00   ,.......$.......
|    128: 00 00 00 e0 00 00 00 04 2c 80 00 04 24 c0 00 04   ........,...$...
|    144: 2c 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ,...............
| end c7.db
  }]
  catchsql {
    WITH RECURSIVE
      c1(x) AS (VALUES(0) UNION ALL SELECT x+1 FROM c1 WHERE x<8),
      c2(y) AS (VALUES(0) UNION ALL SELECT y+1 FROM c2 WHERE y<5)
    INSERT INTO t1(id, x0,x1,y0,y1,label)
      SELECT 1000+x+y*100, x, x+1, y, y+1, printf('box-%d,%d',x,y) FROM c1, c2;
  }
} {1 {database disk image is malformed}}

finish_test
Changes to ext/session/sqlite3session.h.
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
**
** 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







|







557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
**
** 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/alter.c.
24
25
26
27
28
29
30
31
32







33
34
35
36
37
38
39
40
** Parameter zName is the name of a table that is about to be altered
** (either with ALTER TABLE ... RENAME TO or ALTER TABLE ... ADD COLUMN).
** If the table is a system table, this function leaves an error message
** in pParse->zErr (system tables may not be altered) and returns non-zero.
**
** Or, if zName is not a system table, zero is returned.
*/
static int isSystemTable(Parse *pParse, const char *zName){
  if( 0==sqlite3StrNICmp(zName, "sqlite_", 7) ){







    sqlite3ErrorMsg(pParse, "table %s may not be altered", zName);
    return 1;
  }
  return 0;
}

/*
** Generate code to verify that the schemas of database zDb and, if







|
|
>
>
>
>
>
>
>
|







24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
** Parameter zName is the name of a table that is about to be altered
** (either with ALTER TABLE ... RENAME TO or ALTER TABLE ... ADD COLUMN).
** If the table is a system table, this function leaves an error message
** in pParse->zErr (system tables may not be altered) and returns non-zero.
**
** Or, if zName is not a system table, zero is returned.
*/
static int isAlterableTable(Parse *pParse, Table *pTab){
  if( 0==sqlite3StrNICmp(pTab->zName, "sqlite_", 7) 
#ifndef SQLITE_OMIT_VIRTUALTABLE
   || ( (pTab->tabFlags & TF_Shadow) 
     && (pParse->db->flags & SQLITE_Defensive)
     && pParse->db->nVdbeExec==0
   )
#endif
  ){
    sqlite3ErrorMsg(pParse, "table %s may not be altered", pTab->zName);
    return 1;
  }
  return 0;
}

/*
** Generate code to verify that the schemas of database zDb and, if
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
        "there is already another table or index with this name: %s", zName);
    goto exit_rename_table;
  }

  /* Make sure it is not a system table being altered, or a reserved name
  ** that the table is being renamed to.
  */
  if( SQLITE_OK!=isSystemTable(pParse, pTab->zName) ){
    goto exit_rename_table;
  }
  if( SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){ goto
    exit_rename_table;
  }

#ifndef SQLITE_OMIT_VIEW







|







129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
        "there is already another table or index with this name: %s", zName);
    goto exit_rename_table;
  }

  /* Make sure it is not a system table being altered, or a reserved name
  ** that the table is being renamed to.
  */
  if( SQLITE_OK!=isAlterableTable(pParse, pTab) ){
    goto exit_rename_table;
  }
  if( SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){ goto
    exit_rename_table;
  }

#ifndef SQLITE_OMIT_VIEW
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
#endif

  /* Make sure this is not an attempt to ALTER a view. */
  if( pTab->pSelect ){
    sqlite3ErrorMsg(pParse, "Cannot add a column to a view");
    goto exit_begin_add_column;
  }
  if( SQLITE_OK!=isSystemTable(pParse, pTab->zName) ){
    goto exit_begin_add_column;
  }

  assert( pTab->addColOffset>0 );
  iDb = sqlite3SchemaToIndex(db, pTab->pSchema);

  /* Put a copy of the Table struct in Parse.pNewTable for the







|







427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
#endif

  /* Make sure this is not an attempt to ALTER a view. */
  if( pTab->pSelect ){
    sqlite3ErrorMsg(pParse, "Cannot add a column to a view");
    goto exit_begin_add_column;
  }
  if( SQLITE_OK!=isAlterableTable(pParse, pTab) ){
    goto exit_begin_add_column;
  }

  assert( pTab->addColOffset>0 );
  iDb = sqlite3SchemaToIndex(db, pTab->pSchema);

  /* Put a copy of the Table struct in Parse.pNewTable for the
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
  int bQuote;                     /* True to quote the new name */

  /* Locate the table to be altered */
  pTab = sqlite3LocateTableItem(pParse, 0, &pSrc->a[0]);
  if( !pTab ) goto exit_rename_column;

  /* Cannot alter a system table */
  if( SQLITE_OK!=isSystemTable(pParse, pTab->zName) ) goto exit_rename_column;
  if( SQLITE_OK!=isRealTable(pParse, pTab) ) goto exit_rename_column;

  /* Which schema holds the table to be altered */  
  iSchema = sqlite3SchemaToIndex(db, pTab->pSchema);
  assert( iSchema>=0 );
  zDb = db->aDb[iSchema].zDbSName;








|







529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
  int bQuote;                     /* True to quote the new name */

  /* Locate the table to be altered */
  pTab = sqlite3LocateTableItem(pParse, 0, &pSrc->a[0]);
  if( !pTab ) goto exit_rename_column;

  /* Cannot alter a system table */
  if( SQLITE_OK!=isAlterableTable(pParse, pTab) ) goto exit_rename_column;
  if( SQLITE_OK!=isRealTable(pParse, pTab) ) goto exit_rename_column;

  /* Which schema holds the table to be altered */  
  iSchema = sqlite3SchemaToIndex(db, pTab->pSchema);
  assert( iSchema>=0 );
  zDb = db->aDb[iSchema].zDbSName;

Changes to src/analyze.c.
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
    */
    addrRewind = sqlite3VdbeAddOp1(v, OP_Rewind, iIdxCur);
    VdbeCoverage(v);
    sqlite3VdbeAddOp2(v, OP_Integer, 0, regChng);
    addrNextRow = sqlite3VdbeCurrentAddr(v);

    if( nColTest>0 ){
      int endDistinctTest = sqlite3VdbeMakeLabel(v);
      int *aGotoChng;               /* Array of jump instruction addresses */
      aGotoChng = sqlite3DbMallocRawNN(db, sizeof(int)*nColTest);
      if( aGotoChng==0 ) continue;

      /*
      **  next_row:
      **   regChng = 0







|







1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
    */
    addrRewind = sqlite3VdbeAddOp1(v, OP_Rewind, iIdxCur);
    VdbeCoverage(v);
    sqlite3VdbeAddOp2(v, OP_Integer, 0, regChng);
    addrNextRow = sqlite3VdbeCurrentAddr(v);

    if( nColTest>0 ){
      int endDistinctTest = sqlite3VdbeMakeLabel(pParse);
      int *aGotoChng;               /* Array of jump instruction addresses */
      aGotoChng = sqlite3DbMallocRawNN(db, sizeof(int)*nColTest);
      if( aGotoChng==0 ) continue;

      /*
      **  next_row:
      **   regChng = 0
Changes to src/btree.c.
4863
4864
4865
4866
4867
4868
4869

4870
4871
4872
4873
4874
4875
4876
      }while( ALWAYS(pPrev) );
    }
    btreeReleaseAllCursorPages(pCur);
    unlockBtreeIfUnused(pBt);
    sqlite3_free(pCur->aOverflow);
    sqlite3_free(pCur->pKey);
    sqlite3BtreeLeave(pBtree);

  }
  return SQLITE_OK;
}

/*
** Make sure the BtCursor* given in the argument has a valid
** BtCursor.info structure.  If it is not already valid, call







>







4863
4864
4865
4866
4867
4868
4869
4870
4871
4872
4873
4874
4875
4876
4877
      }while( ALWAYS(pPrev) );
    }
    btreeReleaseAllCursorPages(pCur);
    unlockBtreeIfUnused(pBt);
    sqlite3_free(pCur->aOverflow);
    sqlite3_free(pCur->pKey);
    sqlite3BtreeLeave(pBtree);
    pCur->pBtree = 0;
  }
  return SQLITE_OK;
}

/*
** Make sure the BtCursor* given in the argument has a valid
** BtCursor.info structure.  If it is not already valid, call
Changes to src/build.c.
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
   && SQLITE_OK!=sqlite3ReadSchema(pParse)
  ){
    return 0;
  }

  p = sqlite3FindTable(db, zName, zDbase);
  if( p==0 ){
    const char *zMsg = flags & LOCATE_VIEW ? "no such view" : "no such table";
#ifndef SQLITE_OMIT_VIRTUALTABLE
    /* If zName is the not the name of a table in the schema created using
    ** CREATE, then check to see if it is the name of an virtual table that
    ** can be an eponymous virtual table. */

    Module *pMod = (Module*)sqlite3HashFind(&db->aModule, zName);
    if( pMod==0 && sqlite3_strnicmp(zName, "pragma_", 7)==0 ){
      pMod = sqlite3PragmaVtabRegister(db, zName);
    }
    if( pMod && sqlite3VtabEponymousTableInit(pParse, pMod) ){
      return pMod->pEpoTab;
    }

#endif
    if( (flags & LOCATE_NOERR)==0 ){







      if( zDbase ){
        sqlite3ErrorMsg(pParse, "%s: %s.%s", zMsg, zDbase, zName);
      }else{
        sqlite3ErrorMsg(pParse, "%s: %s", zMsg, zName);
      }
      pParse->checkSchema = 1;
    }
  }

  return p;
}

/*







<




>
|
|
|
|
|
|
|
>

|
>
>
>
>
>
>
>
|
|
|
|
<
<







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
   && SQLITE_OK!=sqlite3ReadSchema(pParse)
  ){
    return 0;
  }

  p = sqlite3FindTable(db, zName, zDbase);
  if( p==0 ){

#ifndef SQLITE_OMIT_VIRTUALTABLE
    /* If zName is the not the name of a table in the schema created using
    ** CREATE, then check to see if it is the name of an virtual table that
    ** can be an eponymous virtual table. */
    if( pParse->disableVtab==0 ){
      Module *pMod = (Module*)sqlite3HashFind(&db->aModule, zName);
      if( pMod==0 && sqlite3_strnicmp(zName, "pragma_", 7)==0 ){
        pMod = sqlite3PragmaVtabRegister(db, zName);
      }
      if( pMod && sqlite3VtabEponymousTableInit(pParse, pMod) ){
        return pMod->pEpoTab;
      }
    }
#endif
    if( flags & LOCATE_NOERR ) return 0;
    pParse->checkSchema = 1;
  }else if( IsVirtual(p) && pParse->disableVtab ){
    p = 0;
  }

  if( p==0 ){
    const char *zMsg = flags & LOCATE_VIEW ? "no such view" : "no such table";
    if( zDbase ){
      sqlite3ErrorMsg(pParse, "%s: %s.%s", zMsg, zDbase, zName);
    }else{
      sqlite3ErrorMsg(pParse, "%s: %s", zMsg, zName);


    }
  }

  return p;
}

/*
2630
2631
2632
2633
2634
2635
2636

2637
2638
2639
2640
2641
2642
2643
  }

  /* 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);
}

/*







>







2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
  }

  /* 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/delete.c.
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
        sqlite3VdbeAddOp2(v, OP_RowSetAdd, iRowSet, iKey);
      }
    }
  
    /* If this DELETE cannot use the ONEPASS strategy, this is the 
    ** end of the WHERE loop */
    if( eOnePass!=ONEPASS_OFF ){
      addrBypass = sqlite3VdbeMakeLabel(v);
    }else{
      sqlite3WhereEnd(pWInfo);
    }
  
    /* Unless this is a view, open cursors for the table we are 
    ** deleting from and all its indices. If this is a view, then the
    ** only effect this statement has is to fire the INSTEAD OF 







|







513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
        sqlite3VdbeAddOp2(v, OP_RowSetAdd, iRowSet, iKey);
      }
    }
  
    /* If this DELETE cannot use the ONEPASS strategy, this is the 
    ** end of the WHERE loop */
    if( eOnePass!=ONEPASS_OFF ){
      addrBypass = sqlite3VdbeMakeLabel(pParse);
    }else{
      sqlite3WhereEnd(pWInfo);
    }
  
    /* Unless this is a view, open cursors for the table we are 
    ** deleting from and all its indices. If this is a view, then the
    ** only effect this statement has is to fire the INSTEAD OF 
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
  assert( v );
  VdbeModuleComment((v, "BEGIN: GenRowDel(%d,%d,%d,%d)",
                         iDataCur, iIdxCur, iPk, (int)nPk));

  /* Seek cursor iCur to the row to delete. If this row no longer exists 
  ** (this can happen if a trigger program has already deleted it), do
  ** not attempt to delete it or fire any DELETE triggers.  */
  iLabel = sqlite3VdbeMakeLabel(v);
  opSeek = HasRowid(pTab) ? OP_NotExists : OP_NotFound;
  if( eMode==ONEPASS_OFF ){
    sqlite3VdbeAddOp4Int(v, opSeek, iDataCur, iLabel, iPk, nPk);
    VdbeCoverageIf(v, opSeek==OP_NotExists);
    VdbeCoverageIf(v, opSeek==OP_NotFound);
  }
 







|







702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
  assert( v );
  VdbeModuleComment((v, "BEGIN: GenRowDel(%d,%d,%d,%d)",
                         iDataCur, iIdxCur, iPk, (int)nPk));

  /* Seek cursor iCur to the row to delete. If this row no longer exists 
  ** (this can happen if a trigger program has already deleted it), do
  ** not attempt to delete it or fire any DELETE triggers.  */
  iLabel = sqlite3VdbeMakeLabel(pParse);
  opSeek = HasRowid(pTab) ? OP_NotExists : OP_NotFound;
  if( eMode==ONEPASS_OFF ){
    sqlite3VdbeAddOp4Int(v, opSeek, iDataCur, iLabel, iPk, nPk);
    VdbeCoverageIf(v, opSeek==OP_NotExists);
    VdbeCoverageIf(v, opSeek==OP_NotFound);
  }
 
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
  Vdbe *v = pParse->pVdbe;
  int j;
  int regBase;
  int nCol;

  if( piPartIdxLabel ){
    if( pIdx->pPartIdxWhere ){
      *piPartIdxLabel = sqlite3VdbeMakeLabel(v);
      pParse->iSelfTab = iDataCur + 1;
      sqlite3ExprIfFalseDup(pParse, pIdx->pPartIdxWhere, *piPartIdxLabel, 
                            SQLITE_JUMPIFNULL);
      pParse->iSelfTab = 0;
    }else{
      *piPartIdxLabel = 0;
    }







|







908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
  Vdbe *v = pParse->pVdbe;
  int j;
  int regBase;
  int nCol;

  if( piPartIdxLabel ){
    if( pIdx->pPartIdxWhere ){
      *piPartIdxLabel = sqlite3VdbeMakeLabel(pParse);
      pParse->iSelfTab = iDataCur + 1;
      sqlite3ExprIfFalseDup(pParse, pIdx->pPartIdxWhere, *piPartIdxLabel, 
                            SQLITE_JUMPIFNULL);
      pParse->iSelfTab = 0;
    }else{
      *piPartIdxLabel = 0;
    }
Changes to src/expr.c.
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
**
** If pExpr is not a TK_SELECT expression, return 0.
*/
static int exprCodeSubselect(Parse *pParse, Expr *pExpr){
  int reg = 0;
#ifndef SQLITE_OMIT_SUBQUERY
  if( pExpr->op==TK_SELECT ){
    reg = sqlite3CodeSubselect(pParse, pExpr, 0, 0);
  }
#endif
  return reg;
}

/*
** Argument pVector points to a vector expression - either a TK_VECTOR







|







477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
**
** If pExpr is not a TK_SELECT expression, return 0.
*/
static int exprCodeSubselect(Parse *pParse, Expr *pExpr){
  int reg = 0;
#ifndef SQLITE_OMIT_SUBQUERY
  if( pExpr->op==TK_SELECT ){
    reg = sqlite3CodeSubselect(pParse, pExpr);
  }
#endif
  return reg;
}

/*
** Argument pVector points to a vector expression - either a TK_VECTOR
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
  Expr *pLeft = pExpr->pLeft;
  Expr *pRight = pExpr->pRight;
  int nLeft = sqlite3ExprVectorSize(pLeft);
  int i;
  int regLeft = 0;
  int regRight = 0;
  u8 opx = op;
  int addrDone = sqlite3VdbeMakeLabel(v);

  if( nLeft!=sqlite3ExprVectorSize(pRight) ){
    sqlite3ErrorMsg(pParse, "row value misused");
    return;
  }
  assert( pExpr->op==TK_EQ || pExpr->op==TK_NE 
       || pExpr->op==TK_IS || pExpr->op==TK_ISNOT 







|







549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
  Expr *pLeft = pExpr->pLeft;
  Expr *pRight = pExpr->pRight;
  int nLeft = sqlite3ExprVectorSize(pLeft);
  int i;
  int regLeft = 0;
  int regRight = 0;
  u8 opx = op;
  int addrDone = sqlite3VdbeMakeLabel(pParse);

  if( nLeft!=sqlite3ExprVectorSize(pRight) ){
    sqlite3ErrorMsg(pParse, "row value misused");
    return;
  }
  assert( pExpr->op==TK_EQ || pExpr->op==TK_NE 
       || pExpr->op==TK_IS || pExpr->op==TK_ISNOT 
2108
2109
2110
2111
2112
2113
2114
2115


2116
2117
2118
2119
2120
2121
2122
** be a small performance hit but is otherwise harmless.  On the other
** hand, a false negative (returning FALSE when the result could be NULL)
** will likely result in an incorrect answer.  So when in doubt, return
** TRUE.
*/
int sqlite3ExprCanBeNull(const Expr *p){
  u8 op;
  while( p->op==TK_UPLUS || p->op==TK_UMINUS ){ p = p->pLeft; }


  op = p->op;
  if( op==TK_REGISTER ) op = p->op2;
  switch( op ){
    case TK_INTEGER:
    case TK_STRING:
    case TK_FLOAT:
    case TK_BLOB:







|
>
>







2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
** be a small performance hit but is otherwise harmless.  On the other
** hand, a false negative (returning FALSE when the result could be NULL)
** will likely result in an incorrect answer.  So when in doubt, return
** TRUE.
*/
int sqlite3ExprCanBeNull(const Expr *p){
  u8 op;
  while( p->op==TK_UPLUS || p->op==TK_UMINUS ){
    p = p->pLeft;
  }
  op = p->op;
  if( op==TK_REGISTER ) op = p->op2;
  switch( op ){
    case TK_INTEGER:
    case TK_STRING:
    case TK_FLOAT:
    case TK_BLOB:
2344
2345
2346
2347
2348
2349
2350
2351

2352
2353
2354
2355
2356
2357
2358
*/
#ifndef SQLITE_OMIT_SUBQUERY
int sqlite3FindInIndex(
  Parse *pParse,             /* Parsing context */
  Expr *pX,                  /* The right-hand side (RHS) of the IN operator */
  u32 inFlags,               /* IN_INDEX_LOOP, _MEMBERSHIP, and/or _NOOP_OK */
  int *prRhsHasNull,         /* Register holding NULL status.  See notes */
  int *aiMap                 /* Mapping from Index fields to RHS fields */

){
  Select *p;                            /* SELECT to the right of IN operator */
  int eType = 0;                        /* Type of RHS table. IN_INDEX_* */
  int iTab = pParse->nTab++;            /* Cursor of the RHS table */
  int mustBeUnique;                     /* True if RHS must be unique */
  Vdbe *v = sqlite3GetVdbe(pParse);     /* Virtual machine being coded */








|
>







2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
*/
#ifndef SQLITE_OMIT_SUBQUERY
int sqlite3FindInIndex(
  Parse *pParse,             /* Parsing context */
  Expr *pX,                  /* The right-hand side (RHS) of the IN operator */
  u32 inFlags,               /* IN_INDEX_LOOP, _MEMBERSHIP, and/or _NOOP_OK */
  int *prRhsHasNull,         /* Register holding NULL status.  See notes */
  int *aiMap,                /* Mapping from Index fields to RHS fields */
  int *piTab                 /* OUT: index to use */
){
  Select *p;                            /* SELECT to the right of IN operator */
  int eType = 0;                        /* Type of RHS table. IN_INDEX_* */
  int iTab = pParse->nTab++;            /* Cursor of the RHS table */
  int mustBeUnique;                     /* True if RHS must be unique */
  Vdbe *v = sqlite3GetVdbe(pParse);     /* Virtual machine being coded */

2536
2537
2538
2539
2540
2541
2542

2543



2544
2545
2546
2547
2548
2549
2550
2551
2552
2553

2554
2555
2556
2557
2558
2559
2560
      pParse->nQueryLoop = 0;
      if( pX->pLeft->iColumn<0 && !ExprHasProperty(pX, EP_xIsSelect) ){
        eType = IN_INDEX_ROWID;
      }
    }else if( prRhsHasNull ){
      *prRhsHasNull = rMayHaveNull = ++pParse->nMem;
    }

    sqlite3CodeSubselect(pParse, pX, rMayHaveNull, eType==IN_INDEX_ROWID);



    pParse->nQueryLoop = savedNQueryLoop;
  }else{
    pX->iTable = iTab;
  }

  if( aiMap && eType!=IN_INDEX_INDEX_ASC && eType!=IN_INDEX_INDEX_DESC ){
    int i, n;
    n = sqlite3ExprVectorSize(pX->pLeft);
    for(i=0; i<n; i++) aiMap[i] = i;
  }

  return eType;
}
#endif

#ifndef SQLITE_OMIT_SUBQUERY
/*
** Argument pExpr is an (?, ?...) IN(...) expression. This 







>
|
>
>
>

<
<







>







2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551


2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
      pParse->nQueryLoop = 0;
      if( pX->pLeft->iColumn<0 && !ExprHasProperty(pX, EP_xIsSelect) ){
        eType = IN_INDEX_ROWID;
      }
    }else if( prRhsHasNull ){
      *prRhsHasNull = rMayHaveNull = ++pParse->nMem;
    }
    assert( pX->op==TK_IN );
    sqlite3CodeRhsOfIN(pParse, pX, iTab, eType==IN_INDEX_ROWID);
    if( rMayHaveNull ){
      sqlite3SetHasNullFlag(v, iTab, rMayHaveNull);
    }
    pParse->nQueryLoop = savedNQueryLoop;


  }

  if( aiMap && eType!=IN_INDEX_INDEX_ASC && eType!=IN_INDEX_INDEX_DESC ){
    int i, n;
    n = sqlite3ExprVectorSize(pX->pLeft);
    for(i=0; i<n; i++) aiMap[i] = i;
  }
  *piTab = iTab;
  return eType;
}
#endif

#ifndef SQLITE_OMIT_SUBQUERY
/*
** Argument pExpr is an (?, ?...) IN(...) expression. This 
2620
2621
2622
2623
2624
2625
2626

2627
2628
2629

2630
2631
2632
2633
2634
2635
2636
2637



2638
2639

























2640


2641



























2642






2643

























2644


























































2645







2646









2647
























2648





2649



2650





2651
2652
2653
2654
2655
2656
2657
2658
2659
2660

2661
2662
2663

2664
2665
2666





2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880

2881
2882
2883
2884
2885
2886
2887
  }else
#endif
  {
    sqlite3ErrorMsg(pParse, "row value misused");
  }
}


/*
** Generate code for scalar subqueries used as a subquery expression, EXISTS,
** or IN operators.  Examples:

**
**     (SELECT a FROM b)          -- subquery
**     EXISTS (SELECT a FROM b)   -- EXISTS subquery
**     x IN (4,5,11)              -- IN operator with list on right-hand side
**     x IN (SELECT a FROM b)     -- IN operator with subquery on the right
**
** The pExpr parameter describes the expression that contains the IN
** operator or subquery.



**
** If parameter isRowid is non-zero, then expression pExpr is guaranteed

























** to be of the form "<rowid> IN (?, ?, ?)", where <rowid> is a reference


** to some integer key column of a table B-Tree. In this case, use an



























** intkey B-Tree to store the set of IN(...) values instead of the usual






** (slower) variable length keys B-Tree.

























**


























































** If rMayHaveNull is non-zero, that means that the operation is an IN







** (not a SELECT or EXISTS) and that the RHS might contains NULLs.









** All this routine does is initialize the register given by rMayHaveNull
























** to NULL.  Calling routines will take care of changing this register





** value to non-NULL if the RHS is NULL-free.



**





** For a SELECT or EXISTS operator, return the register that holds the
** result.  For a multi-column SELECT, the result is stored in a contiguous
** array of registers and the return value is the register of the left-most
** result column.  Return 0 for IN operators or if an error occurs.
*/
#ifndef SQLITE_OMIT_SUBQUERY
int sqlite3CodeSubselect(
  Parse *pParse,          /* Parsing context */
  Expr *pExpr,            /* The IN, SELECT, or EXISTS operator */
  int rHasNullFlag,       /* Register that records whether NULLs exist in RHS */

  int isRowid             /* If true, LHS of IN operator is a rowid */
){
  int jmpIfDynamic = -1;                      /* One-time test address */

  int rReg = 0;                           /* Register storing resulting */
  Vdbe *v = sqlite3GetVdbe(pParse);
  if( NEVER(v==0) ) return 0;






  /* The evaluation of the IN/EXISTS/SELECT must be repeated every time it
  ** is encountered if any of the following is true:
  **
  **    *  The right-hand side is a correlated subquery
  **    *  The right-hand side is an expression list containing variables
  **    *  We are inside a trigger
  **
  ** If all of the above are false, then we can run this code just once
  ** save the results, and reuse the same result on subsequent invocations.
  */
  if( !ExprHasProperty(pExpr, EP_VarSelect) ){
    jmpIfDynamic = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
  }

  switch( pExpr->op ){
    case TK_IN: {
      int addr;                   /* Address of OP_OpenEphemeral instruction */
      Expr *pLeft = pExpr->pLeft; /* the LHS of the IN operator */
      KeyInfo *pKeyInfo = 0;      /* Key information */
      int nVal;                   /* Size of vector pLeft */
      
      nVal = sqlite3ExprVectorSize(pLeft);
      assert( !isRowid || nVal==1 );

      /* Whether this is an 'x IN(SELECT...)' or an 'x IN(<exprlist>)'
      ** expression it is handled the same way.  An ephemeral table is 
      ** filled with index keys representing the results from the 
      ** SELECT or the <exprlist>.
      **
      ** If the 'x' expression is a column value, or the SELECT...
      ** statement returns a column value, then the affinity of that
      ** column is used to build the index keys. If both 'x' and the
      ** SELECT... statement are columns, then numeric affinity is used
      ** if either column has NUMERIC or INTEGER affinity. If neither
      ** 'x' nor the SELECT... statement are columns, then numeric affinity
      ** is used.
      */
      pExpr->iTable = pParse->nTab++;
      addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, 
          pExpr->iTable, (isRowid?0:nVal));
      pKeyInfo = isRowid ? 0 : sqlite3KeyInfoAlloc(pParse->db, nVal, 1);

      if( ExprHasProperty(pExpr, EP_xIsSelect) ){
        /* Case 1:     expr IN (SELECT ...)
        **
        ** Generate code to write the results of the select into the temporary
        ** table allocated and opened above.
        */
        Select *pSelect = pExpr->x.pSelect;
        ExprList *pEList = pSelect->pEList;

        ExplainQueryPlan((pParse, 1, "%sLIST SUBQUERY",
            jmpIfDynamic>=0?"":"CORRELATED "
        ));
        assert( !isRowid );
        /* If the LHS and RHS of the IN operator do not match, that
        ** error will have been caught long before we reach this point. */
        if( ALWAYS(pEList->nExpr==nVal) ){
          SelectDest dest;
          int i;
          sqlite3SelectDestInit(&dest, SRT_Set, pExpr->iTable);
          dest.zAffSdst = exprINAffinity(pParse, pExpr);
          pSelect->iLimit = 0;
          testcase( pSelect->selFlags & SF_Distinct );
          testcase( pKeyInfo==0 ); /* Caused by OOM in sqlite3KeyInfoAlloc() */
          if( sqlite3Select(pParse, pSelect, &dest) ){
            sqlite3DbFree(pParse->db, dest.zAffSdst);
            sqlite3KeyInfoUnref(pKeyInfo);
            return 0;
          }
          sqlite3DbFree(pParse->db, dest.zAffSdst);
          assert( pKeyInfo!=0 ); /* OOM will cause exit after sqlite3Select() */
          assert( pEList!=0 );
          assert( pEList->nExpr>0 );
          assert( sqlite3KeyInfoIsWriteable(pKeyInfo) );
          for(i=0; i<nVal; i++){
            Expr *p = sqlite3VectorFieldSubexpr(pLeft, i);
            pKeyInfo->aColl[i] = sqlite3BinaryCompareCollSeq(
                pParse, p, pEList->a[i].pExpr
            );
          }
        }
      }else if( ALWAYS(pExpr->x.pList!=0) ){
        /* Case 2:     expr IN (exprlist)
        **
        ** For each expression, build an index key from the evaluation and
        ** store it in the temporary table. If <expr> is a column, then use
        ** that columns affinity when building index keys. If <expr> is not
        ** a column, use numeric affinity.
        */
        char affinity;            /* Affinity of the LHS of the IN */
        int i;
        ExprList *pList = pExpr->x.pList;
        struct ExprList_item *pItem;
        int r1, r2, r3;
        affinity = sqlite3ExprAffinity(pLeft);
        if( !affinity ){
          affinity = SQLITE_AFF_BLOB;
        }
        if( pKeyInfo ){
          assert( sqlite3KeyInfoIsWriteable(pKeyInfo) );
          pKeyInfo->aColl[0] = sqlite3ExprCollSeq(pParse, pExpr->pLeft);
        }

        /* Loop through each expression in <exprlist>. */
        r1 = sqlite3GetTempReg(pParse);
        r2 = sqlite3GetTempReg(pParse);
        if( isRowid ) sqlite3VdbeAddOp4(v, OP_Blob, 0, r2, 0, "", P4_STATIC);
        for(i=pList->nExpr, pItem=pList->a; i>0; i--, pItem++){
          Expr *pE2 = pItem->pExpr;
          int iValToIns;

          /* If the expression is not constant then we will need to
          ** disable the test that was generated above that makes sure
          ** this code only executes once.  Because for a non-constant
          ** expression we need to rerun this code each time.
          */
          if( jmpIfDynamic>=0 && !sqlite3ExprIsConstant(pE2) ){
            sqlite3VdbeChangeToNoop(v, jmpIfDynamic);
            jmpIfDynamic = -1;
          }

          /* Evaluate the expression and insert it into the temp table */
          if( isRowid && sqlite3ExprIsInteger(pE2, &iValToIns) ){
            sqlite3VdbeAddOp3(v, OP_InsertInt, pExpr->iTable, r2, iValToIns);
          }else{
            r3 = sqlite3ExprCodeTarget(pParse, pE2, r1);
            if( isRowid ){
              sqlite3VdbeAddOp2(v, OP_MustBeInt, r3,
                                sqlite3VdbeCurrentAddr(v)+2);
              VdbeCoverage(v);
              sqlite3VdbeAddOp3(v, OP_Insert, pExpr->iTable, r2, r3);
            }else{
              sqlite3VdbeAddOp4(v, OP_MakeRecord, r3, 1, r2, &affinity, 1);
              sqlite3VdbeAddOp4Int(v, OP_IdxInsert, pExpr->iTable, r2, r3, 1);
            }
          }
        }
        sqlite3ReleaseTempReg(pParse, r1);
        sqlite3ReleaseTempReg(pParse, r2);
      }
      if( pKeyInfo ){
        sqlite3VdbeChangeP4(v, addr, (void *)pKeyInfo, P4_KEYINFO);
      }
      break;
    }

    case TK_EXISTS:
    case TK_SELECT:
    default: {
      /* Case 3:    (SELECT ... FROM ...)
      **     or:    EXISTS(SELECT ... FROM ...)
      **
      ** For a SELECT, generate code to put the values for all columns of
      ** the first row into an array of registers and return the index of
      ** the first register.
      **
      ** If this is an EXISTS, write an integer 0 (not exists) or 1 (exists)
      ** into a register and return that register number.
      **
      ** In both cases, the query is augmented with "LIMIT 1".  Any 
      ** preexisting limit is discarded in place of the new LIMIT 1.
      */
      Select *pSel;                         /* SELECT statement to encode */
      SelectDest dest;                      /* How to deal with SELECT result */
      int nReg;                             /* Registers to allocate */
      Expr *pLimit;                         /* New limit expression */

      testcase( pExpr->op==TK_EXISTS );
      testcase( pExpr->op==TK_SELECT );
      assert( pExpr->op==TK_EXISTS || pExpr->op==TK_SELECT );
      assert( ExprHasProperty(pExpr, EP_xIsSelect) );

      pSel = pExpr->x.pSelect;
      ExplainQueryPlan((pParse, 1, "%sSCALAR SUBQUERY",
            jmpIfDynamic>=0?"":"CORRELATED "));
      nReg = pExpr->op==TK_SELECT ? pSel->pEList->nExpr : 1;
      sqlite3SelectDestInit(&dest, 0, pParse->nMem+1);
      pParse->nMem += nReg;
      if( pExpr->op==TK_SELECT ){
        dest.eDest = SRT_Mem;
        dest.iSdst = dest.iSDParm;
        dest.nSdst = nReg;
        sqlite3VdbeAddOp3(v, OP_Null, 0, dest.iSDParm, dest.iSDParm+nReg-1);
        VdbeComment((v, "Init subquery result"));
      }else{
        dest.eDest = SRT_Exists;
        sqlite3VdbeAddOp2(v, OP_Integer, 0, dest.iSDParm);
        VdbeComment((v, "Init EXISTS result"));
      }
      pLimit = sqlite3ExprAlloc(pParse->db, TK_INTEGER,&sqlite3IntTokens[1], 0);
      if( pSel->pLimit ){
        sqlite3ExprDelete(pParse->db, pSel->pLimit->pLeft);
        pSel->pLimit->pLeft = pLimit;
      }else{
        pSel->pLimit = sqlite3PExpr(pParse, TK_LIMIT, pLimit, 0);
      }
      pSel->iLimit = 0;
      if( sqlite3Select(pParse, pSel, &dest) ){
        return 0;
      }
      rReg = dest.iSDParm;
      ExprSetVVAProperty(pExpr, EP_NoReduce);
      break;
    }
  }

  if( rHasNullFlag ){
    sqlite3SetHasNullFlag(v, pExpr->iTable, rHasNullFlag);
  }

  if( jmpIfDynamic>=0 ){
    sqlite3VdbeJumpHere(v, jmpIfDynamic);

  }

  return rReg;
}
#endif /* SQLITE_OMIT_SUBQUERY */

#ifndef SQLITE_OMIT_SUBQUERY







>

|
|
>

<
<



|
|
>
>
>

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

>
>
>
>
>
|
|
|
|


|
|
<
|
>
|
<
|
>
|
|
|
>
>
>
>
>

|










<
<
|
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
|
|
<
<
<
<
<
<
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
|
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
|
<
<
|
<
<
<
|
<
|
<
<
<
<
|
<
<
<
<
<
<
|
|
<
|
<
<
<
<
<
<
<
|
|
|
|
|
|
|
|
|
|
<
<
<
<
<
<
<
<
<
<
<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<
<
<
|
<
|
|
|
<
|
>







2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638


2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863

2864
2865
2866

2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888


2889






2890





















2891








2892








2893
2894






2895
2896




























2897




2898







2899









2900


2901



2902

2903




2904






2905
2906

2907







2908
2909
2910
2911
2912
2913
2914
2915
2916
2917











2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946



2947

2948
2949
2950

2951
2952
2953
2954
2955
2956
2957
2958
2959
  }else
#endif
  {
    sqlite3ErrorMsg(pParse, "row value misused");
  }
}

#ifndef SQLITE_OMIT_SUBQUERY
/*
** Generate code that will construct an ephemeral table containing all terms
** in the RHS of an IN operator.  The IN operator can be in either of two
** forms:
**


**     x IN (4,5,11)              -- IN operator with list on right-hand side
**     x IN (SELECT a FROM b)     -- IN operator with subquery on the right
**
** The pExpr parameter is the IN operator.  The cursor number for the
** constructed ephermeral table is returned.  The first time the ephemeral
** table is computed, the cursor number is also stored in pExpr->iTable,
** however the cursor number returned might not be the same, as it might
** have been duplicated using OP_OpenDup.
**
** If parameter isRowid is non-zero, then LHS of the IN operator is guaranteed
** to be a non-null integer. In this case, the ephemeral table can be an
** table B-Tree that keyed by only integers.  The more general cases uses
** an index B-Tree which can have arbitrary keys, but is slower to both
** read and write.
**
** If the LHS expression ("x" in the examples) is a column value, or
** the SELECT statement returns a column value, then the affinity of that
** column is used to build the index keys. If both 'x' and the
** SELECT... statement are columns, then numeric affinity is used
** if either column has NUMERIC or INTEGER affinity. If neither
** 'x' nor the SELECT... statement are columns, then numeric affinity
** is used.
*/
void sqlite3CodeRhsOfIN(
  Parse *pParse,          /* Parsing context */
  Expr *pExpr,            /* The IN operator */
  int iTab,               /* Use this cursor number */
  int isRowid             /* If true, LHS is a rowid */
){
  int addrOnce = 0;           /* Address of the OP_Once instruction at top */
  int addr;                   /* Address of OP_OpenEphemeral instruction */
  Expr *pLeft;                /* the LHS of the IN operator */
  KeyInfo *pKeyInfo = 0;      /* Key information */
  int nVal;                   /* Size of vector pLeft */
  Vdbe *v;                    /* The prepared statement under construction */

  v = pParse->pVdbe;
  assert( v!=0 );

  /* The evaluation of the IN must be repeated every time it
  ** is encountered if any of the following is true:
  **
  **    *  The right-hand side is a correlated subquery
  **    *  The right-hand side is an expression list containing variables
  **    *  We are inside a trigger
  **
  ** If all of the above are false, then we can compute the RHS just once
  ** and reuse it many names.
  */
  if( !ExprHasProperty(pExpr, EP_VarSelect) && pParse->iSelfTab==0 ){
    /* Reuse of the RHS is allowed */
    /* If this routine has already been coded, but the previous code
    ** might not have been invoked yet, so invoke it now as a subroutine. 
    */
    if( ExprHasProperty(pExpr, EP_Subrtn) ){
      addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
      if( ExprHasProperty(pExpr, EP_xIsSelect) ){
        ExplainQueryPlan((pParse, 0, "REUSE LIST SUBQUERY %d",
              pExpr->x.pSelect->selId));
      }
      sqlite3VdbeAddOp2(v, OP_Gosub, pExpr->y.sub.regReturn,
                        pExpr->y.sub.iAddr);
      sqlite3VdbeAddOp2(v, OP_OpenDup, iTab, pExpr->iTable);
      sqlite3VdbeJumpHere(v, addrOnce);
      return;
    }

    /* Begin coding the subroutine */
    ExprSetProperty(pExpr, EP_Subrtn);
    pExpr->y.sub.regReturn = ++pParse->nMem;
    pExpr->y.sub.iAddr =
      sqlite3VdbeAddOp2(v, OP_Integer, 0, pExpr->y.sub.regReturn) + 1;
    VdbeComment((v, "return address"));

    addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
  }

  /* Check to see if this is a vector IN operator */
  pLeft = pExpr->pLeft;
  nVal = sqlite3ExprVectorSize(pLeft);
  assert( !isRowid || nVal==1 );

  /* Construct the ephemeral table that will contain the content of
  ** RHS of the IN operator.
  */
  pExpr->iTable = iTab;
  addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, 
      pExpr->iTable, (isRowid?0:nVal));
#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
  if( ExprHasProperty(pExpr, EP_xIsSelect) ){
    VdbeComment((v, "Result of SELECT %u", pExpr->x.pSelect->selId));
  }else{
    VdbeComment((v, "RHS of IN operator"));
  }
#endif
  pKeyInfo = isRowid ? 0 : sqlite3KeyInfoAlloc(pParse->db, nVal, 1);

  if( ExprHasProperty(pExpr, EP_xIsSelect) ){
    /* Case 1:     expr IN (SELECT ...)
    **
    ** Generate code to write the results of the select into the temporary
    ** table allocated and opened above.
    */
    Select *pSelect = pExpr->x.pSelect;
    ExprList *pEList = pSelect->pEList;

    ExplainQueryPlan((pParse, 1, "%sLIST SUBQUERY %d",
        addrOnce?"":"CORRELATED ", pSelect->selId
    ));
    assert( !isRowid );
    /* If the LHS and RHS of the IN operator do not match, that
    ** error will have been caught long before we reach this point. */
    if( ALWAYS(pEList->nExpr==nVal) ){
      SelectDest dest;
      int i;
      sqlite3SelectDestInit(&dest, SRT_Set, iTab);
      dest.zAffSdst = exprINAffinity(pParse, pExpr);
      pSelect->iLimit = 0;
      testcase( pSelect->selFlags & SF_Distinct );
      testcase( pKeyInfo==0 ); /* Caused by OOM in sqlite3KeyInfoAlloc() */
      if( sqlite3Select(pParse, pSelect, &dest) ){
        sqlite3DbFree(pParse->db, dest.zAffSdst);
        sqlite3KeyInfoUnref(pKeyInfo);
        return;
      }
      sqlite3DbFree(pParse->db, dest.zAffSdst);
      assert( pKeyInfo!=0 ); /* OOM will cause exit after sqlite3Select() */
      assert( pEList!=0 );
      assert( pEList->nExpr>0 );
      assert( sqlite3KeyInfoIsWriteable(pKeyInfo) );
      for(i=0; i<nVal; i++){
        Expr *p = sqlite3VectorFieldSubexpr(pLeft, i);
        pKeyInfo->aColl[i] = sqlite3BinaryCompareCollSeq(
            pParse, p, pEList->a[i].pExpr
        );
      }
    }
  }else if( ALWAYS(pExpr->x.pList!=0) ){
    /* Case 2:     expr IN (exprlist)
    **
    ** For each expression, build an index key from the evaluation and
    ** store it in the temporary table. If <expr> is a column, then use
    ** that columns affinity when building index keys. If <expr> is not
    ** a column, use numeric affinity.
    */
    char affinity;            /* Affinity of the LHS of the IN */
    int i;
    ExprList *pList = pExpr->x.pList;
    struct ExprList_item *pItem;
    int r1, r2, r3;
    affinity = sqlite3ExprAffinity(pLeft);
    if( !affinity ){
      affinity = SQLITE_AFF_BLOB;
    }
    if( pKeyInfo ){
      assert( sqlite3KeyInfoIsWriteable(pKeyInfo) );
      pKeyInfo->aColl[0] = sqlite3ExprCollSeq(pParse, pExpr->pLeft);
    }

    /* Loop through each expression in <exprlist>. */
    r1 = sqlite3GetTempReg(pParse);
    r2 = sqlite3GetTempReg(pParse);
    if( isRowid ) sqlite3VdbeAddOp4(v, OP_Blob, 0, r2, 0, "", P4_STATIC);
    for(i=pList->nExpr, pItem=pList->a; i>0; i--, pItem++){
      Expr *pE2 = pItem->pExpr;
      int iValToIns;

      /* If the expression is not constant then we will need to
      ** disable the test that was generated above that makes sure
      ** this code only executes once.  Because for a non-constant
      ** expression we need to rerun this code each time.
      */
      if( addrOnce && !sqlite3ExprIsConstant(pE2) ){
        sqlite3VdbeChangeToNoop(v, addrOnce);
        addrOnce = 0;
      }

      /* Evaluate the expression and insert it into the temp table */
      if( isRowid && sqlite3ExprIsInteger(pE2, &iValToIns) ){
        sqlite3VdbeAddOp3(v, OP_InsertInt, iTab, r2, iValToIns);
      }else{
        r3 = sqlite3ExprCodeTarget(pParse, pE2, r1);
        if( isRowid ){
          sqlite3VdbeAddOp2(v, OP_MustBeInt, r3,
                            sqlite3VdbeCurrentAddr(v)+2);
          VdbeCoverage(v);
          sqlite3VdbeAddOp3(v, OP_Insert, iTab, r2, r3);
        }else{
          sqlite3VdbeAddOp4(v, OP_MakeRecord, r3, 1, r2, &affinity, 1);
          sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iTab, r2, r3, 1);
        }
      }
    }
    sqlite3ReleaseTempReg(pParse, r1);
    sqlite3ReleaseTempReg(pParse, r2);
  }
  if( pKeyInfo ){
    sqlite3VdbeChangeP4(v, addr, (void *)pKeyInfo, P4_KEYINFO);
  }
  if( addrOnce ){
    sqlite3VdbeJumpHere(v, addrOnce);
    /* Subroutine return */
    sqlite3VdbeAddOp1(v, OP_Return, pExpr->y.sub.regReturn);
    sqlite3VdbeChangeP1(v, pExpr->y.sub.iAddr-1, sqlite3VdbeCurrentAddr(v)-1);
  }
}
#endif /* SQLITE_OMIT_SUBQUERY */

/*
** Generate code for scalar subqueries used as a subquery expression
** or EXISTS operator:
**
**     (SELECT a FROM b)          -- subquery
**     EXISTS (SELECT a FROM b)   -- EXISTS subquery
**
** The pExpr parameter is the SELECT or EXISTS operator to be coded.
**
** The register that holds the result.  For a multi-column SELECT, 
** the result is stored in a contiguous array of registers and the
** return value is the register of the left-most result column.
** Return 0 if an error occurs.
*/
#ifndef SQLITE_OMIT_SUBQUERY
int sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){
  int addrOnce = 0;           /* Address of OP_Once at top of subroutine */

  int rReg = 0;               /* Register storing resulting */
  Select *pSel;               /* SELECT statement to encode */
  SelectDest dest;            /* How to deal with SELECT result */

  int nReg;                   /* Registers to allocate */
  Expr *pLimit;               /* New limit expression */

  Vdbe *v = pParse->pVdbe;
  assert( v!=0 );
  testcase( pExpr->op==TK_EXISTS );
  testcase( pExpr->op==TK_SELECT );
  assert( pExpr->op==TK_EXISTS || pExpr->op==TK_SELECT );
  assert( ExprHasProperty(pExpr, EP_xIsSelect) );
  pSel = pExpr->x.pSelect;

  /* The evaluation of the EXISTS/SELECT must be repeated every time it
  ** is encountered if any of the following is true:
  **
  **    *  The right-hand side is a correlated subquery
  **    *  The right-hand side is an expression list containing variables
  **    *  We are inside a trigger
  **
  ** If all of the above are false, then we can run this code just once
  ** save the results, and reuse the same result on subsequent invocations.
  */
  if( !ExprHasProperty(pExpr, EP_VarSelect) ){


    /* If this routine has already been coded, then invoke it as a






    ** subroutine. */





















    if( ExprHasProperty(pExpr, EP_Subrtn) ){








      ExplainQueryPlan((pParse, 0, "REUSE SUBQUERY %d", pSel->selId));








      sqlite3VdbeAddOp2(v, OP_Gosub, pExpr->y.sub.regReturn,
                        pExpr->y.sub.iAddr);






      return pExpr->iTable;
    }

































    /* Begin coding the subroutine */







    ExprSetProperty(pExpr, EP_Subrtn);









    pExpr->y.sub.regReturn = ++pParse->nMem;


    pExpr->y.sub.iAddr =



      sqlite3VdbeAddOp2(v, OP_Integer, 0, pExpr->y.sub.regReturn) + 1;

    VdbeComment((v, "return address"));











    addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
  }

  







  /* For a SELECT, generate code to put the values for all columns of
  ** the first row into an array of registers and return the index of
  ** the first register.
  **
  ** If this is an EXISTS, write an integer 0 (not exists) or 1 (exists)
  ** into a register and return that register number.
  **
  ** In both cases, the query is augmented with "LIMIT 1".  Any 
  ** preexisting limit is discarded in place of the new LIMIT 1.
  */











  ExplainQueryPlan((pParse, 1, "%sSCALAR SUBQUERY %d",
        addrOnce?"":"CORRELATED ", pSel->selId));
  nReg = pExpr->op==TK_SELECT ? pSel->pEList->nExpr : 1;
  sqlite3SelectDestInit(&dest, 0, pParse->nMem+1);
  pParse->nMem += nReg;
  if( pExpr->op==TK_SELECT ){
    dest.eDest = SRT_Mem;
    dest.iSdst = dest.iSDParm;
    dest.nSdst = nReg;
    sqlite3VdbeAddOp3(v, OP_Null, 0, dest.iSDParm, dest.iSDParm+nReg-1);
    VdbeComment((v, "Init subquery result"));
  }else{
    dest.eDest = SRT_Exists;
    sqlite3VdbeAddOp2(v, OP_Integer, 0, dest.iSDParm);
    VdbeComment((v, "Init EXISTS result"));
  }
  pLimit = sqlite3ExprAlloc(pParse->db, TK_INTEGER,&sqlite3IntTokens[1], 0);
  if( pSel->pLimit ){
    sqlite3ExprDelete(pParse->db, pSel->pLimit->pLeft);
    pSel->pLimit->pLeft = pLimit;
  }else{
    pSel->pLimit = sqlite3PExpr(pParse, TK_LIMIT, pLimit, 0);
  }
  pSel->iLimit = 0;
  if( sqlite3Select(pParse, pSel, &dest) ){
    return 0;
  }
  pExpr->iTable = rReg = dest.iSDParm;
  ExprSetVVAProperty(pExpr, EP_NoReduce);



  if( addrOnce ){

    sqlite3VdbeJumpHere(v, addrOnce);

    /* Subroutine return */

    sqlite3VdbeAddOp1(v, OP_Return, pExpr->y.sub.regReturn);
    sqlite3VdbeChangeP1(v, pExpr->y.sub.iAddr-1, sqlite3VdbeCurrentAddr(v)-1);
  }

  return rReg;
}
#endif /* SQLITE_OMIT_SUBQUERY */

#ifndef SQLITE_OMIT_SUBQUERY
2950
2951
2952
2953
2954
2955
2956

2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976

2977
2978
2979
2980
2981
2982
2983
  Expr *pLeft;          /* The LHS of the IN operator */
  int i;                /* loop counter */
  int destStep2;        /* Where to jump when NULLs seen in step 2 */
  int destStep6 = 0;    /* Start of code for Step 6 */
  int addrTruthOp;      /* Address of opcode that determines the IN is true */
  int destNotNull;      /* Jump here if a comparison is not true in step 6 */
  int addrTop;          /* Top of the step-6 loop */ 


  pLeft = pExpr->pLeft;
  if( sqlite3ExprCheckIN(pParse, pExpr) ) return;
  zAff = exprINAffinity(pParse, pExpr);
  nVector = sqlite3ExprVectorSize(pExpr->pLeft);
  aiMap = (int*)sqlite3DbMallocZero(
      pParse->db, nVector*(sizeof(int) + sizeof(char)) + 1
  );
  if( pParse->db->mallocFailed ) goto sqlite3ExprCodeIN_oom_error;

  /* Attempt to compute the RHS. After this step, if anything other than
  ** IN_INDEX_NOOP is returned, the table opened ith cursor pExpr->iTable 
  ** contains the values that make up the RHS. If IN_INDEX_NOOP is returned,
  ** the RHS has not yet been coded.  */
  v = pParse->pVdbe;
  assert( v!=0 );       /* OOM detected prior to this routine */
  VdbeNoopComment((v, "begin IN expr"));
  eType = sqlite3FindInIndex(pParse, pExpr,
                             IN_INDEX_MEMBERSHIP | IN_INDEX_NOOP_OK,
                             destIfFalse==destIfNull ? 0 : &rRhsHasNull, aiMap);


  assert( pParse->nErr || nVector==1 || eType==IN_INDEX_EPH
       || eType==IN_INDEX_INDEX_ASC || eType==IN_INDEX_INDEX_DESC 
  );
#ifdef SQLITE_DEBUG
  /* Confirm that aiMap[] contains nVector integer values between 0 and
  ** nVector-1. */







>











|







|
>







3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
  Expr *pLeft;          /* The LHS of the IN operator */
  int i;                /* loop counter */
  int destStep2;        /* Where to jump when NULLs seen in step 2 */
  int destStep6 = 0;    /* Start of code for Step 6 */
  int addrTruthOp;      /* Address of opcode that determines the IN is true */
  int destNotNull;      /* Jump here if a comparison is not true in step 6 */
  int addrTop;          /* Top of the step-6 loop */ 
  int iTab = 0;         /* Index to use */

  pLeft = pExpr->pLeft;
  if( sqlite3ExprCheckIN(pParse, pExpr) ) return;
  zAff = exprINAffinity(pParse, pExpr);
  nVector = sqlite3ExprVectorSize(pExpr->pLeft);
  aiMap = (int*)sqlite3DbMallocZero(
      pParse->db, nVector*(sizeof(int) + sizeof(char)) + 1
  );
  if( pParse->db->mallocFailed ) goto sqlite3ExprCodeIN_oom_error;

  /* Attempt to compute the RHS. After this step, if anything other than
  ** IN_INDEX_NOOP is returned, the table opened with cursor iTab
  ** contains the values that make up the RHS. If IN_INDEX_NOOP is returned,
  ** the RHS has not yet been coded.  */
  v = pParse->pVdbe;
  assert( v!=0 );       /* OOM detected prior to this routine */
  VdbeNoopComment((v, "begin IN expr"));
  eType = sqlite3FindInIndex(pParse, pExpr,
                             IN_INDEX_MEMBERSHIP | IN_INDEX_NOOP_OK,
                             destIfFalse==destIfNull ? 0 : &rRhsHasNull,
                             aiMap, &iTab);

  assert( pParse->nErr || nVector==1 || eType==IN_INDEX_EPH
       || eType==IN_INDEX_INDEX_ASC || eType==IN_INDEX_INDEX_DESC 
  );
#ifdef SQLITE_DEBUG
  /* Confirm that aiMap[] contains nVector integer values between 0 and
  ** nVector-1. */
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
  ** sequence of comparisons.
  **
  ** This is step (1) in the in-operator.md optimized algorithm.
  */
  if( eType==IN_INDEX_NOOP ){
    ExprList *pList = pExpr->x.pList;
    CollSeq *pColl = sqlite3ExprCollSeq(pParse, pExpr->pLeft);
    int labelOk = sqlite3VdbeMakeLabel(v);
    int r2, regToFree;
    int regCkNull = 0;
    int ii;
    assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
    if( destIfNull!=destIfFalse ){
      regCkNull = sqlite3GetTempReg(pParse);
      sqlite3VdbeAddOp3(v, OP_BitAnd, rLhs, rLhs, regCkNull);







|







3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
  ** sequence of comparisons.
  **
  ** This is step (1) in the in-operator.md optimized algorithm.
  */
  if( eType==IN_INDEX_NOOP ){
    ExprList *pList = pExpr->x.pList;
    CollSeq *pColl = sqlite3ExprCollSeq(pParse, pExpr->pLeft);
    int labelOk = sqlite3VdbeMakeLabel(pParse);
    int r2, regToFree;
    int regCkNull = 0;
    int ii;
    assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
    if( destIfNull!=destIfFalse ){
      regCkNull = sqlite3GetTempReg(pParse);
      sqlite3VdbeAddOp3(v, OP_BitAnd, rLhs, rLhs, regCkNull);
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
  /* Step 2: Check to see if the LHS contains any NULL columns.  If the
  ** LHS does contain NULLs then the result must be either FALSE or NULL.
  ** We will then skip the binary search of the RHS.
  */
  if( destIfNull==destIfFalse ){
    destStep2 = destIfFalse;
  }else{
    destStep2 = destStep6 = sqlite3VdbeMakeLabel(v);
  }
  for(i=0; i<nVector; i++){
    Expr *p = sqlite3VectorFieldSubexpr(pExpr->pLeft, i);
    if( sqlite3ExprCanBeNull(p) ){
      sqlite3VdbeAddOp2(v, OP_IsNull, rLhs+i, destStep2);
      VdbeCoverage(v);
    }
  }

  /* Step 3.  The LHS is now known to be non-NULL.  Do the binary search
  ** of the RHS using the LHS as a probe.  If found, the result is
  ** true.
  */
  if( eType==IN_INDEX_ROWID ){
    /* In this case, the RHS is the ROWID of table b-tree and so we also
    ** know that the RHS is non-NULL.  Hence, we combine steps 3 and 4
    ** into a single opcode. */
    sqlite3VdbeAddOp3(v, OP_SeekRowid, pExpr->iTable, destIfFalse, rLhs);
    VdbeCoverage(v);
    addrTruthOp = sqlite3VdbeAddOp0(v, OP_Goto);  /* Return True */
  }else{
    sqlite3VdbeAddOp4(v, OP_Affinity, rLhs, nVector, 0, zAff, nVector);
    if( destIfFalse==destIfNull ){
      /* Combine Step 3 and Step 5 into a single opcode */
      sqlite3VdbeAddOp4Int(v, OP_NotFound, pExpr->iTable, destIfFalse,
                           rLhs, nVector); VdbeCoverage(v);
      goto sqlite3ExprCodeIN_finished;
    }
    /* Ordinary Step 3, for the case where FALSE and NULL are distinct */
    addrTruthOp = sqlite3VdbeAddOp4Int(v, OP_Found, pExpr->iTable, 0,
                                      rLhs, nVector); VdbeCoverage(v);
  }

  /* Step 4.  If the RHS is known to be non-NULL and we did not find
  ** an match on the search above, then the result must be FALSE.
  */
  if( rRhsHasNull && nVector==1 ){







|

















|






|




|







3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
  /* Step 2: Check to see if the LHS contains any NULL columns.  If the
  ** LHS does contain NULLs then the result must be either FALSE or NULL.
  ** We will then skip the binary search of the RHS.
  */
  if( destIfNull==destIfFalse ){
    destStep2 = destIfFalse;
  }else{
    destStep2 = destStep6 = sqlite3VdbeMakeLabel(pParse);
  }
  for(i=0; i<nVector; i++){
    Expr *p = sqlite3VectorFieldSubexpr(pExpr->pLeft, i);
    if( sqlite3ExprCanBeNull(p) ){
      sqlite3VdbeAddOp2(v, OP_IsNull, rLhs+i, destStep2);
      VdbeCoverage(v);
    }
  }

  /* Step 3.  The LHS is now known to be non-NULL.  Do the binary search
  ** of the RHS using the LHS as a probe.  If found, the result is
  ** true.
  */
  if( eType==IN_INDEX_ROWID ){
    /* In this case, the RHS is the ROWID of table b-tree and so we also
    ** know that the RHS is non-NULL.  Hence, we combine steps 3 and 4
    ** into a single opcode. */
    sqlite3VdbeAddOp3(v, OP_SeekRowid, iTab, destIfFalse, rLhs);
    VdbeCoverage(v);
    addrTruthOp = sqlite3VdbeAddOp0(v, OP_Goto);  /* Return True */
  }else{
    sqlite3VdbeAddOp4(v, OP_Affinity, rLhs, nVector, 0, zAff, nVector);
    if( destIfFalse==destIfNull ){
      /* Combine Step 3 and Step 5 into a single opcode */
      sqlite3VdbeAddOp4Int(v, OP_NotFound, iTab, destIfFalse,
                           rLhs, nVector); VdbeCoverage(v);
      goto sqlite3ExprCodeIN_finished;
    }
    /* Ordinary Step 3, for the case where FALSE and NULL are distinct */
    addrTruthOp = sqlite3VdbeAddOp4Int(v, OP_Found, iTab, 0,
                                      rLhs, nVector); VdbeCoverage(v);
  }

  /* Step 4.  If the RHS is known to be non-NULL and we did not find
  ** an match on the search above, then the result must be FALSE.
  */
  if( rRhsHasNull && nVector==1 ){
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
  ** If any comparison is NULL, then the result is NULL.  If all
  ** comparisons are FALSE then the final result is FALSE.
  **
  ** For a scalar LHS, it is sufficient to check just the first row
  ** of the RHS.
  */
  if( destStep6 ) sqlite3VdbeResolveLabel(v, destStep6);
  addrTop = sqlite3VdbeAddOp2(v, OP_Rewind, pExpr->iTable, destIfFalse);
  VdbeCoverage(v);
  if( nVector>1 ){
    destNotNull = sqlite3VdbeMakeLabel(v);
  }else{
    /* For nVector==1, combine steps 6 and 7 by immediately returning
    ** FALSE if the first comparison is not NULL */
    destNotNull = destIfFalse;
  }
  for(i=0; i<nVector; i++){
    Expr *p;
    CollSeq *pColl;
    int r3 = sqlite3GetTempReg(pParse);
    p = sqlite3VectorFieldSubexpr(pLeft, i);
    pColl = sqlite3ExprCollSeq(pParse, p);
    sqlite3VdbeAddOp3(v, OP_Column, pExpr->iTable, i, r3);
    sqlite3VdbeAddOp4(v, OP_Ne, rLhs+i, destNotNull, r3,
                      (void*)pColl, P4_COLLSEQ);
    VdbeCoverage(v);
    sqlite3ReleaseTempReg(pParse, r3);
  }
  sqlite3VdbeAddOp2(v, OP_Goto, 0, destIfNull);
  if( nVector>1 ){
    sqlite3VdbeResolveLabel(v, destNotNull);
    sqlite3VdbeAddOp2(v, OP_Next, pExpr->iTable, addrTop+1);
    VdbeCoverage(v);

    /* Step 7:  If we reach this point, we know that the result must
    ** be false. */
    sqlite3VdbeAddOp2(v, OP_Goto, 0, destIfFalse);
  }








|


|











|








|







3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
  ** If any comparison is NULL, then the result is NULL.  If all
  ** comparisons are FALSE then the final result is FALSE.
  **
  ** For a scalar LHS, it is sufficient to check just the first row
  ** of the RHS.
  */
  if( destStep6 ) sqlite3VdbeResolveLabel(v, destStep6);
  addrTop = sqlite3VdbeAddOp2(v, OP_Rewind, iTab, destIfFalse);
  VdbeCoverage(v);
  if( nVector>1 ){
    destNotNull = sqlite3VdbeMakeLabel(pParse);
  }else{
    /* For nVector==1, combine steps 6 and 7 by immediately returning
    ** FALSE if the first comparison is not NULL */
    destNotNull = destIfFalse;
  }
  for(i=0; i<nVector; i++){
    Expr *p;
    CollSeq *pColl;
    int r3 = sqlite3GetTempReg(pParse);
    p = sqlite3VectorFieldSubexpr(pLeft, i);
    pColl = sqlite3ExprCollSeq(pParse, p);
    sqlite3VdbeAddOp3(v, OP_Column, iTab, i, r3);
    sqlite3VdbeAddOp4(v, OP_Ne, rLhs+i, destNotNull, r3,
                      (void*)pColl, P4_COLLSEQ);
    VdbeCoverage(v);
    sqlite3ReleaseTempReg(pParse, r3);
  }
  sqlite3VdbeAddOp2(v, OP_Goto, 0, destIfNull);
  if( nVector>1 ){
    sqlite3VdbeResolveLabel(v, destNotNull);
    sqlite3VdbeAddOp2(v, OP_Next, iTab, addrTop+1);
    VdbeCoverage(v);

    /* Step 7:  If we reach this point, we know that the result must
    ** be false. */
    sqlite3VdbeAddOp2(v, OP_Goto, 0, destIfFalse);
  }

3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
    iResult = sqlite3ExprCodeTemp(pParse, p, piFreeable);
  }else{
    *piFreeable = 0;
    if( p->op==TK_SELECT ){
#if SQLITE_OMIT_SUBQUERY
      iResult = 0;
#else
      iResult = sqlite3CodeSubselect(pParse, p, 0, 0);
#endif
    }else{
      int i;
      iResult = pParse->nMem+1;
      pParse->nMem += nResult;
      for(i=0; i<nResult; i++){
        sqlite3ExprCodeFactorable(pParse, p->x.pList->a[i].pExpr, i+iResult);







|







3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
    iResult = sqlite3ExprCodeTemp(pParse, p, piFreeable);
  }else{
    *piFreeable = 0;
    if( p->op==TK_SELECT ){
#if SQLITE_OMIT_SUBQUERY
      iResult = 0;
#else
      iResult = sqlite3CodeSubselect(pParse, p);
#endif
    }else{
      int i;
      iResult = pParse->nMem+1;
      pParse->nMem += nResult;
      for(i=0; i<nResult; i++){
        sqlite3ExprCodeFactorable(pParse, p->x.pList->a[i].pExpr, i+iResult);
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
      }

      /* Attempt a direct implementation of the built-in COALESCE() and
      ** IFNULL() functions.  This avoids unnecessary evaluation of
      ** arguments past the first non-NULL argument.
      */
      if( pDef->funcFlags & SQLITE_FUNC_COALESCE ){
        int endCoalesce = sqlite3VdbeMakeLabel(v);
        assert( nFarg>=2 );
        sqlite3ExprCode(pParse, pFarg->a[0].pExpr, target);
        for(i=1; i<nFarg; i++){
          sqlite3VdbeAddOp2(v, OP_NotNull, target, endCoalesce);
          VdbeCoverage(v);
          sqlite3ExprCode(pParse, pFarg->a[i].pExpr, target);
        }







|







3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
      }

      /* Attempt a direct implementation of the built-in COALESCE() and
      ** IFNULL() functions.  This avoids unnecessary evaluation of
      ** arguments past the first non-NULL argument.
      */
      if( pDef->funcFlags & SQLITE_FUNC_COALESCE ){
        int endCoalesce = sqlite3VdbeMakeLabel(pParse);
        assert( nFarg>=2 );
        sqlite3ExprCode(pParse, pFarg->a[0].pExpr, target);
        for(i=1; i<nFarg; i++){
          sqlite3VdbeAddOp2(v, OP_NotNull, target, endCoalesce);
          VdbeCoverage(v);
          sqlite3ExprCode(pParse, pFarg->a[i].pExpr, target);
        }
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
    case TK_SELECT: {
      int nCol;
      testcase( op==TK_EXISTS );
      testcase( op==TK_SELECT );
      if( op==TK_SELECT && (nCol = pExpr->x.pSelect->pEList->nExpr)!=1 ){
        sqlite3SubselectError(pParse, nCol, 1);
      }else{
        return sqlite3CodeSubselect(pParse, pExpr, 0, 0);
      }
      break;
    }
    case TK_SELECT_COLUMN: {
      int n;
      if( pExpr->pLeft->iTable==0 ){
        pExpr->pLeft->iTable = sqlite3CodeSubselect(pParse, pExpr->pLeft, 0, 0);
      }
      assert( pExpr->iTable==0 || pExpr->pLeft->op==TK_SELECT );
      if( pExpr->iTable
       && pExpr->iTable!=(n = sqlite3ExprVectorSize(pExpr->pLeft)) 
      ){
        sqlite3ErrorMsg(pParse, "%d columns assigned %d values",
                                pExpr->iTable, n);
      }
      return pExpr->pLeft->iTable + pExpr->iColumn;
    }
    case TK_IN: {
      int destIfFalse = sqlite3VdbeMakeLabel(v);
      int destIfNull = sqlite3VdbeMakeLabel(v);
      sqlite3VdbeAddOp2(v, OP_Null, 0, target);
      sqlite3ExprCodeIN(pParse, pExpr, destIfFalse, destIfNull);
      sqlite3VdbeAddOp2(v, OP_Integer, 1, target);
      sqlite3VdbeResolveLabel(v, destIfFalse);
      sqlite3VdbeAddOp2(v, OP_AddImm, target, 0);
      sqlite3VdbeResolveLabel(v, destIfNull);
      return target;







|






|











|
|







3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
    case TK_SELECT: {
      int nCol;
      testcase( op==TK_EXISTS );
      testcase( op==TK_SELECT );
      if( op==TK_SELECT && (nCol = pExpr->x.pSelect->pEList->nExpr)!=1 ){
        sqlite3SubselectError(pParse, nCol, 1);
      }else{
        return sqlite3CodeSubselect(pParse, pExpr);
      }
      break;
    }
    case TK_SELECT_COLUMN: {
      int n;
      if( pExpr->pLeft->iTable==0 ){
        pExpr->pLeft->iTable = sqlite3CodeSubselect(pParse, pExpr->pLeft);
      }
      assert( pExpr->iTable==0 || pExpr->pLeft->op==TK_SELECT );
      if( pExpr->iTable
       && pExpr->iTable!=(n = sqlite3ExprVectorSize(pExpr->pLeft)) 
      ){
        sqlite3ErrorMsg(pParse, "%d columns assigned %d values",
                                pExpr->iTable, n);
      }
      return pExpr->pLeft->iTable + pExpr->iColumn;
    }
    case TK_IN: {
      int destIfFalse = sqlite3VdbeMakeLabel(pParse);
      int destIfNull = sqlite3VdbeMakeLabel(pParse);
      sqlite3VdbeAddOp2(v, OP_Null, 0, target);
      sqlite3ExprCodeIN(pParse, pExpr, destIfFalse, destIfNull);
      sqlite3VdbeAddOp2(v, OP_Integer, 1, target);
      sqlite3VdbeResolveLabel(v, destIfFalse);
      sqlite3VdbeAddOp2(v, OP_AddImm, target, 0);
      sqlite3VdbeResolveLabel(v, destIfNull);
      return target;
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
      Expr *pTest = 0;                  /* X==Ei (form A) or just Ei (form B) */

      assert( !ExprHasProperty(pExpr, EP_xIsSelect) && pExpr->x.pList );
      assert(pExpr->x.pList->nExpr > 0);
      pEList = pExpr->x.pList;
      aListelem = pEList->a;
      nExpr = pEList->nExpr;
      endLabel = sqlite3VdbeMakeLabel(v);
      if( (pX = pExpr->pLeft)!=0 ){
        tempX = *pX;
        testcase( pX->op==TK_COLUMN );
        exprToRegister(&tempX, exprCodeVector(pParse, &tempX, &regFree1));
        testcase( regFree1==0 );
        memset(&opCompare, 0, sizeof(opCompare));
        opCompare.op = TK_EQ;







|







4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
      Expr *pTest = 0;                  /* X==Ei (form A) or just Ei (form B) */

      assert( !ExprHasProperty(pExpr, EP_xIsSelect) && pExpr->x.pList );
      assert(pExpr->x.pList->nExpr > 0);
      pEList = pExpr->x.pList;
      aListelem = pEList->a;
      nExpr = pEList->nExpr;
      endLabel = sqlite3VdbeMakeLabel(pParse);
      if( (pX = pExpr->pLeft)!=0 ){
        tempX = *pX;
        testcase( pX->op==TK_COLUMN );
        exprToRegister(&tempX, exprCodeVector(pParse, &tempX, &regFree1));
        testcase( regFree1==0 );
        memset(&opCompare, 0, sizeof(opCompare));
        opCompare.op = TK_EQ;
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
      for(i=0; i<nExpr-1; i=i+2){
        if( pX ){
          assert( pTest!=0 );
          opCompare.pRight = aListelem[i].pExpr;
        }else{
          pTest = aListelem[i].pExpr;
        }
        nextCase = sqlite3VdbeMakeLabel(v);
        testcase( pTest->op==TK_COLUMN );
        sqlite3ExprIfFalse(pParse, pTest, nextCase, SQLITE_JUMPIFNULL);
        testcase( aListelem[i+1].pExpr->op==TK_COLUMN );
        sqlite3ExprCode(pParse, aListelem[i+1].pExpr, target);
        sqlite3VdbeGoto(v, endLabel);
        sqlite3VdbeResolveLabel(v, nextCase);
      }







|







4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
      for(i=0; i<nExpr-1; i=i+2){
        if( pX ){
          assert( pTest!=0 );
          opCompare.pRight = aListelem[i].pExpr;
        }else{
          pTest = aListelem[i].pExpr;
        }
        nextCase = sqlite3VdbeMakeLabel(pParse);
        testcase( pTest->op==TK_COLUMN );
        sqlite3ExprIfFalse(pParse, pTest, nextCase, SQLITE_JUMPIFNULL);
        testcase( aListelem[i+1].pExpr->op==TK_COLUMN );
        sqlite3ExprCode(pParse, aListelem[i+1].pExpr, target);
        sqlite3VdbeGoto(v, endLabel);
        sqlite3VdbeResolveLabel(v, nextCase);
      }
4363
4364
4365
4366
4367
4368
4369
4370
4371
4372
4373
4374
4375
4376
4377

  assert( jumpIfNull==SQLITE_JUMPIFNULL || jumpIfNull==0 );
  if( NEVER(v==0) )     return;  /* Existence of VDBE checked by caller */
  if( NEVER(pExpr==0) ) return;  /* No way this can happen */
  op = pExpr->op;
  switch( op ){
    case TK_AND: {
      int d2 = sqlite3VdbeMakeLabel(v);
      testcase( jumpIfNull==0 );
      sqlite3ExprIfFalse(pParse, pExpr->pLeft, d2,jumpIfNull^SQLITE_JUMPIFNULL);
      sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull);
      sqlite3VdbeResolveLabel(v, d2);
      break;
    }
    case TK_OR: {







|







4437
4438
4439
4440
4441
4442
4443
4444
4445
4446
4447
4448
4449
4450
4451

  assert( jumpIfNull==SQLITE_JUMPIFNULL || jumpIfNull==0 );
  if( NEVER(v==0) )     return;  /* Existence of VDBE checked by caller */
  if( NEVER(pExpr==0) ) return;  /* No way this can happen */
  op = pExpr->op;
  switch( op ){
    case TK_AND: {
      int d2 = sqlite3VdbeMakeLabel(pParse);
      testcase( jumpIfNull==0 );
      sqlite3ExprIfFalse(pParse, pExpr->pLeft, d2,jumpIfNull^SQLITE_JUMPIFNULL);
      sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull);
      sqlite3VdbeResolveLabel(v, d2);
      break;
    }
    case TK_OR: {
4449
4450
4451
4452
4453
4454
4455
4456
4457
4458
4459
4460
4461
4462
4463
    case TK_BETWEEN: {
      testcase( jumpIfNull==0 );
      exprCodeBetween(pParse, pExpr, dest, sqlite3ExprIfTrue, jumpIfNull);
      break;
    }
#ifndef SQLITE_OMIT_SUBQUERY
    case TK_IN: {
      int destIfFalse = sqlite3VdbeMakeLabel(v);
      int destIfNull = jumpIfNull ? dest : destIfFalse;
      sqlite3ExprCodeIN(pParse, pExpr, destIfFalse, destIfNull);
      sqlite3VdbeGoto(v, dest);
      sqlite3VdbeResolveLabel(v, destIfFalse);
      break;
    }
#endif







|







4523
4524
4525
4526
4527
4528
4529
4530
4531
4532
4533
4534
4535
4536
4537
    case TK_BETWEEN: {
      testcase( jumpIfNull==0 );
      exprCodeBetween(pParse, pExpr, dest, sqlite3ExprIfTrue, jumpIfNull);
      break;
    }
#ifndef SQLITE_OMIT_SUBQUERY
    case TK_IN: {
      int destIfFalse = sqlite3VdbeMakeLabel(pParse);
      int destIfNull = jumpIfNull ? dest : destIfFalse;
      sqlite3ExprCodeIN(pParse, pExpr, destIfFalse, destIfNull);
      sqlite3VdbeGoto(v, dest);
      sqlite3VdbeResolveLabel(v, destIfFalse);
      break;
    }
#endif
4536
4537
4538
4539
4540
4541
4542
4543
4544
4545
4546
4547
4548
4549
4550
    case TK_AND: {
      testcase( jumpIfNull==0 );
      sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull);
      sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull);
      break;
    }
    case TK_OR: {
      int d2 = sqlite3VdbeMakeLabel(v);
      testcase( jumpIfNull==0 );
      sqlite3ExprIfTrue(pParse, pExpr->pLeft, d2, jumpIfNull^SQLITE_JUMPIFNULL);
      sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull);
      sqlite3VdbeResolveLabel(v, d2);
      break;
    }
    case TK_NOT: {







|







4610
4611
4612
4613
4614
4615
4616
4617
4618
4619
4620
4621
4622
4623
4624
    case TK_AND: {
      testcase( jumpIfNull==0 );
      sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull);
      sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull);
      break;
    }
    case TK_OR: {
      int d2 = sqlite3VdbeMakeLabel(pParse);
      testcase( jumpIfNull==0 );
      sqlite3ExprIfTrue(pParse, pExpr->pLeft, d2, jumpIfNull^SQLITE_JUMPIFNULL);
      sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull);
      sqlite3VdbeResolveLabel(v, d2);
      break;
    }
    case TK_NOT: {
4620
4621
4622
4623
4624
4625
4626
4627
4628
4629
4630
4631
4632
4633
4634
      break;
    }
#ifndef SQLITE_OMIT_SUBQUERY
    case TK_IN: {
      if( jumpIfNull ){
        sqlite3ExprCodeIN(pParse, pExpr, dest, dest);
      }else{
        int destIfNull = sqlite3VdbeMakeLabel(v);
        sqlite3ExprCodeIN(pParse, pExpr, dest, destIfNull);
        sqlite3VdbeResolveLabel(v, destIfNull);
      }
      break;
    }
#endif
    default: {







|







4694
4695
4696
4697
4698
4699
4700
4701
4702
4703
4704
4705
4706
4707
4708
      break;
    }
#ifndef SQLITE_OMIT_SUBQUERY
    case TK_IN: {
      if( jumpIfNull ){
        sqlite3ExprCodeIN(pParse, pExpr, dest, dest);
      }else{
        int destIfNull = sqlite3VdbeMakeLabel(pParse);
        sqlite3ExprCodeIN(pParse, pExpr, dest, destIfNull);
        sqlite3VdbeResolveLabel(v, destIfNull);
      }
      break;
    }
#endif
    default: {
4741
4742
4743
4744
4745
4746
4747
4748
4749
4750
4751
4752
4753
4754
4755
  combinedFlags = pA->flags | pB->flags;
  if( combinedFlags & EP_IntValue ){
    if( (pA->flags&pB->flags&EP_IntValue)!=0 && pA->u.iValue==pB->u.iValue ){
      return 0;
    }
    return 2;
  }
  if( pA->op!=pB->op ){
    if( pA->op==TK_COLLATE && sqlite3ExprCompare(pParse, pA->pLeft,pB,iTab)<2 ){
      return 1;
    }
    if( pB->op==TK_COLLATE && sqlite3ExprCompare(pParse, pA,pB->pLeft,iTab)<2 ){
      return 1;
    }
    return 2;







|







4815
4816
4817
4818
4819
4820
4821
4822
4823
4824
4825
4826
4827
4828
4829
  combinedFlags = pA->flags | pB->flags;
  if( combinedFlags & EP_IntValue ){
    if( (pA->flags&pB->flags&EP_IntValue)!=0 && pA->u.iValue==pB->u.iValue ){
      return 0;
    }
    return 2;
  }
  if( pA->op!=pB->op || pA->op==TK_RAISE ){
    if( pA->op==TK_COLLATE && sqlite3ExprCompare(pParse, pA->pLeft,pB,iTab)<2 ){
      return 1;
    }
    if( pB->op==TK_COLLATE && sqlite3ExprCompare(pParse, pA,pB->pLeft,iTab)<2 ){
      return 1;
    }
    return 2;
Changes to src/fkey.c.
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
  int regData,          /* Address of array containing child table row */
  int nIncr,            /* Increment constraint counter by this */
  int isIgnore          /* If true, pretend pTab contains all NULL values */
){
  int i;                                    /* Iterator variable */
  Vdbe *v = sqlite3GetVdbe(pParse);         /* Vdbe to add code to */
  int iCur = pParse->nTab - 1;              /* Cursor number to use */
  int iOk = sqlite3VdbeMakeLabel(v);        /* jump here if parent key found */

  sqlite3VdbeVerifyAbortable(v,
    (!pFKey->isDeferred
      && !(pParse->db->flags & SQLITE_DeferFKs)
      && !pParse->pToplevel 
      && !pParse->isMultiWrite) ? OE_Abort : OE_Ignore);








|







325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
  int regData,          /* Address of array containing child table row */
  int nIncr,            /* Increment constraint counter by this */
  int isIgnore          /* If true, pretend pTab contains all NULL values */
){
  int i;                                    /* Iterator variable */
  Vdbe *v = sqlite3GetVdbe(pParse);         /* Vdbe to add code to */
  int iCur = pParse->nTab - 1;              /* Cursor number to use */
  int iOk = sqlite3VdbeMakeLabel(pParse);   /* jump here if parent key found */

  sqlite3VdbeVerifyAbortable(v,
    (!pFKey->isDeferred
      && !(pParse->db->flags & SQLITE_DeferFKs)
      && !pParse->pToplevel 
      && !pParse->isMultiWrite) ? OE_Abort : OE_Ignore);

598
599
600
601
602
603
604
605
606



607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
  ** to the WHERE clause that prevent this entry from being scanned.
  ** The added WHERE clause terms are like this:
  **
  **     $current_rowid!=rowid
  **     NOT( $current_a==a AND $current_b==b AND ... )
  **
  ** The first form is used for rowid tables.  The second form is used
  ** for WITHOUT ROWID tables.  In the second form, the primary key is
  ** (a,b,...)



  */
  if( pTab==pFKey->pFrom && nIncr>0 ){
    Expr *pNe;                    /* Expression (pLeft != pRight) */
    Expr *pLeft;                  /* Value from parent table row */
    Expr *pRight;                 /* Column ref to child table */
    if( HasRowid(pTab) ){
      pLeft = exprTableRegister(pParse, pTab, regData, -1);
      pRight = exprTableColumn(db, pTab, pSrc->a[0].iCursor, -1);
      pNe = sqlite3PExpr(pParse, TK_NE, pLeft, pRight);
    }else{
      Expr *pEq, *pAll = 0;
      Index *pPk = sqlite3PrimaryKeyIndex(pTab);
      assert( pIdx!=0 );
      for(i=0; i<pPk->nKeyCol; i++){
        i16 iCol = pIdx->aiColumn[i];
        assert( iCol>=0 );
        pLeft = exprTableRegister(pParse, pTab, regData, iCol);
        pRight = exprTableColumn(db, pTab, pSrc->a[0].iCursor, iCol);
        pEq = sqlite3PExpr(pParse, TK_EQ, pLeft, pRight);
        pAll = sqlite3ExprAnd(db, pAll, pEq);
      }
      pNe = sqlite3PExpr(pParse, TK_NOT, pAll, 0);
    }
    pWhere = sqlite3ExprAnd(db, pWhere, pNe);
  }








|
|
>
>
>











<

|



|
|







598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620

621
622
623
624
625
626
627
628
629
630
631
632
633
634
  ** to the WHERE clause that prevent this entry from being scanned.
  ** The added WHERE clause terms are like this:
  **
  **     $current_rowid!=rowid
  **     NOT( $current_a==a AND $current_b==b AND ... )
  **
  ** The first form is used for rowid tables.  The second form is used
  ** for WITHOUT ROWID tables. In the second form, the *parent* key is
  ** (a,b,...). Either the parent or primary key could be used to 
  ** uniquely identify the current row, but the parent key is more convenient
  ** as the required values have already been loaded into registers
  ** by the caller.
  */
  if( pTab==pFKey->pFrom && nIncr>0 ){
    Expr *pNe;                    /* Expression (pLeft != pRight) */
    Expr *pLeft;                  /* Value from parent table row */
    Expr *pRight;                 /* Column ref to child table */
    if( HasRowid(pTab) ){
      pLeft = exprTableRegister(pParse, pTab, regData, -1);
      pRight = exprTableColumn(db, pTab, pSrc->a[0].iCursor, -1);
      pNe = sqlite3PExpr(pParse, TK_NE, pLeft, pRight);
    }else{
      Expr *pEq, *pAll = 0;

      assert( pIdx!=0 );
      for(i=0; i<pIdx->nKeyCol; i++){
        i16 iCol = pIdx->aiColumn[i];
        assert( iCol>=0 );
        pLeft = exprTableRegister(pParse, pTab, regData, iCol);
        pRight = sqlite3Expr(db, TK_ID, pTab->aCol[iCol].zName);
        pEq = sqlite3PExpr(pParse, TK_IS, pLeft, pRight);
        pAll = sqlite3ExprAnd(db, pAll, pEq);
      }
      pNe = sqlite3PExpr(pParse, TK_NOT, pAll, 0);
    }
    pWhere = sqlite3ExprAnd(db, pWhere, pNe);
  }

723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
      ** the entire DELETE if there are no outstanding deferred constraints
      ** when this statement is run.  */
      FKey *p;
      for(p=pTab->pFKey; p; p=p->pNextFrom){
        if( p->isDeferred || (db->flags & SQLITE_DeferFKs) ) break;
      }
      if( !p ) return;
      iSkip = sqlite3VdbeMakeLabel(v);
      sqlite3VdbeAddOp2(v, OP_FkIfZero, 1, iSkip); VdbeCoverage(v);
    }

    pParse->disableTriggers = 1;
    sqlite3DeleteFrom(pParse, sqlite3SrcListDup(db, pName, 0), 0, 0, 0);
    pParse->disableTriggers = 0;








|







725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
      ** the entire DELETE if there are no outstanding deferred constraints
      ** when this statement is run.  */
      FKey *p;
      for(p=pTab->pFKey; p; p=p->pNextFrom){
        if( p->isDeferred || (db->flags & SQLITE_DeferFKs) ) break;
      }
      if( !p ) return;
      iSkip = sqlite3VdbeMakeLabel(pParse);
      sqlite3VdbeAddOp2(v, OP_FkIfZero, 1, iSkip); VdbeCoverage(v);
    }

    pParse->disableTriggers = 1;
    sqlite3DeleteFrom(pParse, sqlite3SrcListDup(db, pName, 0), 0, 0, 0);
    pParse->disableTriggers = 0;

Changes to src/insert.c.
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
    */
    addrInsTop = addrCont = sqlite3VdbeAddOp1(v, OP_Yield, dest.iSDParm);
    VdbeCoverage(v);
  }

  /* Run the BEFORE and INSTEAD OF triggers, if there are any
  */
  endOfLoop = sqlite3VdbeMakeLabel(v);
  if( tmask & TRIGGER_BEFORE ){
    int regCols = sqlite3GetTempRange(pParse, pTab->nCol+1);

    /* build the NEW.* reference row.  Note that if there is an INTEGER
    ** PRIMARY KEY into which a NULL is being inserted, that NULL will be
    ** translated into a unique ID for the row.  But on a BEFORE trigger,
    ** we do not know what the unique ID will be (because the insert has







|







862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
    */
    addrInsTop = addrCont = sqlite3VdbeAddOp1(v, OP_Yield, dest.iSDParm);
    VdbeCoverage(v);
  }

  /* Run the BEFORE and INSTEAD OF triggers, if there are any
  */
  endOfLoop = sqlite3VdbeMakeLabel(pParse);
  if( tmask & TRIGGER_BEFORE ){
    int regCols = sqlite3GetTempRange(pParse, pTab->nCol+1);

    /* build the NEW.* reference row.  Note that if there is an INTEGER
    ** PRIMARY KEY into which a NULL is being inserted, that NULL will be
    ** translated into a unique ID for the row.  But on a BEFORE trigger,
    ** we do not know what the unique ID will be (because the insert has
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
      onError = OE_Abort;
    }
    if( onError==OE_Replace && pTab->aCol[i].pDflt==0 ){
      onError = OE_Abort;
    }
    assert( onError==OE_Rollback || onError==OE_Abort || onError==OE_Fail
        || onError==OE_Ignore || onError==OE_Replace );

    switch( onError ){












      case OE_Abort:
        sqlite3MayAbort(pParse);
        /* Fall through */
      case OE_Rollback:
      case OE_Fail: {
        char *zMsg = sqlite3MPrintf(db, "%s.%s", pTab->zName,
                                    pTab->aCol[i].zName);
        sqlite3VdbeAddOp3(v, OP_HaltIfNull, SQLITE_CONSTRAINT_NOTNULL, onError,
                          regNewData+1+i);
        sqlite3VdbeAppendP4(v, zMsg, P4_DYNAMIC);
        sqlite3VdbeChangeP5(v, P5_ConstraintNotNull);
        VdbeCoverage(v);
        break;
      }
      case OE_Ignore: {
        sqlite3VdbeAddOp2(v, OP_IsNull, regNewData+1+i, ignoreDest);
        VdbeCoverage(v);
        break;
      }
      default: {
        assert( onError==OE_Replace );
        addr1 = sqlite3VdbeAddOp1(v, OP_NotNull, regNewData+1+i);
           VdbeCoverage(v);
        sqlite3ExprCode(pParse, pTab->aCol[i].pDflt, regNewData+1+i);
        sqlite3VdbeJumpHere(v, addr1);
        break;
      }
    }
  }

  /* Test all CHECK constraints
  */







>

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












<
<
<
|
<



|
|
|
<
<







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
      onError = OE_Abort;
    }
    if( onError==OE_Replace && pTab->aCol[i].pDflt==0 ){
      onError = OE_Abort;
    }
    assert( onError==OE_Rollback || onError==OE_Abort || onError==OE_Fail
        || onError==OE_Ignore || onError==OE_Replace );
    addr1 = 0;
    switch( onError ){
      case OE_Replace: {
        assert( onError==OE_Replace );
        addr1 = sqlite3VdbeMakeLabel(pParse);
        sqlite3VdbeAddOp2(v, OP_NotNull, regNewData+1+i, addr1);
          VdbeCoverage(v);
        sqlite3ExprCode(pParse, pTab->aCol[i].pDflt, regNewData+1+i);
        sqlite3VdbeAddOp2(v, OP_NotNull, regNewData+1+i, addr1);
          VdbeCoverage(v);
        onError = OE_Abort;
        /* Fall through into the OE_Abort case to generate code that runs
        ** if both the input and the default value are NULL */
      }
      case OE_Abort:
        sqlite3MayAbort(pParse);
        /* Fall through */
      case OE_Rollback:
      case OE_Fail: {
        char *zMsg = sqlite3MPrintf(db, "%s.%s", pTab->zName,
                                    pTab->aCol[i].zName);
        sqlite3VdbeAddOp3(v, OP_HaltIfNull, SQLITE_CONSTRAINT_NOTNULL, onError,
                          regNewData+1+i);
        sqlite3VdbeAppendP4(v, zMsg, P4_DYNAMIC);
        sqlite3VdbeChangeP5(v, P5_ConstraintNotNull);
        VdbeCoverage(v);



        if( addr1 ) sqlite3VdbeResolveLabel(v, addr1);

        break;
      }
      default: {
        assert( onError==OE_Ignore );
        sqlite3VdbeAddOp2(v, OP_IsNull, regNewData+1+i, ignoreDest);
        VdbeCoverage(v);


        break;
      }
    }
  }

  /* Test all CHECK constraints
  */
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
      if( aiChng
       && !sqlite3ExprReferencesUpdatedColumn(pExpr, aiChng, pkChng)
      ){
        /* The check constraints do not reference any of the columns being
        ** updated so there is no point it verifying the check constraint */
        continue;
      }
      allOk = sqlite3VdbeMakeLabel(v);
      sqlite3VdbeVerifyAbortable(v, onError);
      sqlite3ExprIfTrue(pParse, pExpr, allOk, SQLITE_JUMPIFNULL);
      if( onError==OE_Ignore ){
        sqlite3VdbeGoto(v, ignoreDest);
      }else{
        char *zName = pCheck->a[i].zName;
        if( zName==0 ) zName = pTab->zName;







|







1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
      if( aiChng
       && !sqlite3ExprReferencesUpdatedColumn(pExpr, aiChng, pkChng)
      ){
        /* The check constraints do not reference any of the columns being
        ** updated so there is no point it verifying the check constraint */
        continue;
      }
      allOk = sqlite3VdbeMakeLabel(pParse);
      sqlite3VdbeVerifyAbortable(v, onError);
      sqlite3ExprIfTrue(pParse, pExpr, allOk, SQLITE_JUMPIFNULL);
      if( onError==OE_Ignore ){
        sqlite3VdbeGoto(v, ignoreDest);
      }else{
        char *zName = pCheck->a[i].zName;
        if( zName==0 ) zName = pTab->zName;
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
    }
  }

  /* If rowid is changing, make sure the new rowid does not previously
  ** exist in the table.
  */
  if( pkChng && pPk==0 ){
    int addrRowidOk = sqlite3VdbeMakeLabel(v);

    /* Figure out what action to take in case of a rowid collision */
    onError = pTab->keyConf;
    if( overrideError!=OE_Default ){
      onError = overrideError;
    }else if( onError==OE_Default ){
      onError = OE_Abort;







|







1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
    }
  }

  /* If rowid is changing, make sure the new rowid does not previously
  ** exist in the table.
  */
  if( pkChng && pPk==0 ){
    int addrRowidOk = sqlite3VdbeMakeLabel(pParse);

    /* Figure out what action to take in case of a rowid collision */
    onError = pTab->keyConf;
    if( overrideError!=OE_Default ){
      onError = overrideError;
    }else if( onError==OE_Default ){
      onError = OE_Abort;
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
    if( aRegIdx[ix]==0 ) continue;  /* Skip indices that do not change */
    if( pUpIdx==pIdx ){
      addrUniqueOk = upsertJump+1;
      upsertBypass = sqlite3VdbeGoto(v, 0);
      VdbeComment((v, "Skip upsert subroutine"));
      sqlite3VdbeJumpHere(v, upsertJump);
    }else{
      addrUniqueOk = sqlite3VdbeMakeLabel(v);
    }
    if( bAffinityDone==0 && (pUpIdx==0 || pUpIdx==pIdx) ){
      sqlite3TableAffinity(v, pTab, regNewData+1);
      bAffinityDone = 1;
    }
    VdbeNoopComment((v, "uniqueness check for %s", pIdx->zName));
    iThisCur = iIdxCur+ix;







|







1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
    if( aRegIdx[ix]==0 ) continue;  /* Skip indices that do not change */
    if( pUpIdx==pIdx ){
      addrUniqueOk = upsertJump+1;
      upsertBypass = sqlite3VdbeGoto(v, 0);
      VdbeComment((v, "Skip upsert subroutine"));
      sqlite3VdbeJumpHere(v, upsertJump);
    }else{
      addrUniqueOk = sqlite3VdbeMakeLabel(pParse);
    }
    if( bAffinityDone==0 && (pUpIdx==0 || pUpIdx==pIdx) ){
      sqlite3TableAffinity(v, pTab, regNewData+1);
      bAffinityDone = 1;
    }
    VdbeNoopComment((v, "uniqueness check for %s", pIdx->zName));
    iThisCur = iIdxCur+ix;
Changes to src/pragma.c.
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
        pParent = sqlite3FindTable(db, pFK->zTo, zDb);
        pIdx = 0;
        aiCols = 0;
        if( pParent ){
          x = sqlite3FkLocateIndex(pParse, pParent, pFK, &pIdx, &aiCols);
          assert( x==0 );
        }
        addrOk = sqlite3VdbeMakeLabel(v);

        /* Generate code to read the child key values into registers
        ** regRow..regRow+n. If any of the child key values are NULL, this 
        ** row cannot cause an FK violation. Jump directly to addrOk in 
        ** this case. */
        for(j=0; j<pFK->nCol; j++){
          int iCol = aiCols ? aiCols[j] : pFK->aCol[j].iFrom;







|







1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
        pParent = sqlite3FindTable(db, pFK->zTo, zDb);
        pIdx = 0;
        aiCols = 0;
        if( pParent ){
          x = sqlite3FkLocateIndex(pParse, pParent, pFK, &pIdx, &aiCols);
          assert( x==0 );
        }
        addrOk = sqlite3VdbeMakeLabel(pParse);

        /* Generate code to read the child key values into registers
        ** regRow..regRow+n. If any of the child key values are NULL, this 
        ** row cannot cause an FK violation. Jump directly to addrOk in 
        ** this case. */
        for(j=0; j<pFK->nCol; j++){
          int iCol = aiCols ? aiCols[j] : pFK->aCol[j].iFrom;
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
          integrityCheckResultRow(v);
          sqlite3VdbeJumpHere(v, jmp2);
        }
        /* Verify CHECK constraints */
        if( pTab->pCheck && (db->flags & SQLITE_IgnoreChecks)==0 ){
          ExprList *pCheck = sqlite3ExprListDup(db, pTab->pCheck, 0);
          if( db->mallocFailed==0 ){
            int addrCkFault = sqlite3VdbeMakeLabel(v);
            int addrCkOk = sqlite3VdbeMakeLabel(v);
            char *zErr;
            int k;
            pParse->iSelfTab = iDataCur + 1;
            for(k=pCheck->nExpr-1; k>0; k--){
              sqlite3ExprIfFalse(pParse, pCheck->a[k].pExpr, addrCkFault, 0);
            }
            sqlite3ExprIfTrue(pParse, pCheck->a[0].pExpr, addrCkOk, 







|
|







1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
          integrityCheckResultRow(v);
          sqlite3VdbeJumpHere(v, jmp2);
        }
        /* Verify CHECK constraints */
        if( pTab->pCheck && (db->flags & SQLITE_IgnoreChecks)==0 ){
          ExprList *pCheck = sqlite3ExprListDup(db, pTab->pCheck, 0);
          if( db->mallocFailed==0 ){
            int addrCkFault = sqlite3VdbeMakeLabel(pParse);
            int addrCkOk = sqlite3VdbeMakeLabel(pParse);
            char *zErr;
            int k;
            pParse->iSelfTab = iDataCur + 1;
            for(k=pCheck->nExpr-1; k>0; k--){
              sqlite3ExprIfFalse(pParse, pCheck->a[k].pExpr, addrCkFault, 0);
            }
            sqlite3ExprIfTrue(pParse, pCheck->a[0].pExpr, addrCkOk, 
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
          }
          sqlite3ExprListDelete(db, pCheck);
        }
        if( !isQuick ){ /* Omit the remaining tests for quick_check */
          /* Validate index entries for the current row */
          for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
            int jmp2, jmp3, jmp4, jmp5;
            int ckUniq = sqlite3VdbeMakeLabel(v);
            if( pPk==pIdx ) continue;
            r1 = sqlite3GenerateIndexKey(pParse, pIdx, iDataCur, 0, 0, &jmp3,
                                         pPrior, r1);
            pPrior = pIdx;
            sqlite3VdbeAddOp2(v, OP_AddImm, 8+j, 1);/* increment entry count */
            /* Verify that an index entry exists for the current table row */
            jmp2 = sqlite3VdbeAddOp4Int(v, OP_Found, iIdxCur+j, ckUniq, r1,
                                        pIdx->nColumn); VdbeCoverage(v);
            sqlite3VdbeLoadString(v, 3, "row ");
            sqlite3VdbeAddOp3(v, OP_Concat, 7, 3, 3);
            sqlite3VdbeLoadString(v, 4, " missing from index ");
            sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 3);
            jmp5 = sqlite3VdbeLoadString(v, 4, pIdx->zName);
            sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 3);
            jmp4 = integrityCheckResultRow(v);
            sqlite3VdbeJumpHere(v, jmp2);
            /* For UNIQUE indexes, verify that only one entry exists with the
            ** current key.  The entry is unique if (1) any column is NULL
            ** or (2) the next entry has a different key */
            if( IsUniqueIndex(pIdx) ){
              int uniqOk = sqlite3VdbeMakeLabel(v);
              int jmp6;
              int kk;
              for(kk=0; kk<pIdx->nKeyCol; kk++){
                int iCol = pIdx->aiColumn[kk];
                assert( iCol!=XN_ROWID && iCol<pTab->nCol );
                if( iCol>=0 && pTab->aCol[iCol].notNull ) continue;
                sqlite3VdbeAddOp2(v, OP_IsNull, r1+kk, uniqOk);







|




















|







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
          }
          sqlite3ExprListDelete(db, pCheck);
        }
        if( !isQuick ){ /* Omit the remaining tests for quick_check */
          /* Validate index entries for the current row */
          for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
            int jmp2, jmp3, jmp4, jmp5;
            int ckUniq = sqlite3VdbeMakeLabel(pParse);
            if( pPk==pIdx ) continue;
            r1 = sqlite3GenerateIndexKey(pParse, pIdx, iDataCur, 0, 0, &jmp3,
                                         pPrior, r1);
            pPrior = pIdx;
            sqlite3VdbeAddOp2(v, OP_AddImm, 8+j, 1);/* increment entry count */
            /* Verify that an index entry exists for the current table row */
            jmp2 = sqlite3VdbeAddOp4Int(v, OP_Found, iIdxCur+j, ckUniq, r1,
                                        pIdx->nColumn); VdbeCoverage(v);
            sqlite3VdbeLoadString(v, 3, "row ");
            sqlite3VdbeAddOp3(v, OP_Concat, 7, 3, 3);
            sqlite3VdbeLoadString(v, 4, " missing from index ");
            sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 3);
            jmp5 = sqlite3VdbeLoadString(v, 4, pIdx->zName);
            sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 3);
            jmp4 = integrityCheckResultRow(v);
            sqlite3VdbeJumpHere(v, jmp2);
            /* For UNIQUE indexes, verify that only one entry exists with the
            ** current key.  The entry is unique if (1) any column is NULL
            ** or (2) the next entry has a different key */
            if( IsUniqueIndex(pIdx) ){
              int uniqOk = sqlite3VdbeMakeLabel(pParse);
              int jmp6;
              int kk;
              for(kk=0; kk<pIdx->nKeyCol; kk++){
                int iCol = pIdx->aiColumn[kk];
                assert( iCol!=XN_ROWID && iCol<pTab->nCol );
                if( iCol>=0 && pTab->aCol[iCol].notNull ) continue;
                sqlite3VdbeAddOp2(v, OP_IsNull, r1+kk, uniqOk);
Changes to src/prepare.c.
541
542
543
544
545
546
547

548
549
550
551
552
553
554
  /* For a long-term use prepared statement avoid the use of
  ** lookaside memory.
  */
  if( prepFlags & SQLITE_PREPARE_PERSISTENT ){
    sParse.disableLookaside++;
    db->lookaside.bDisable++;
  }


  /* Check to verify that it is possible to get a read lock on all
  ** database schemas.  The inability to get a read lock indicates that
  ** some other database connection is holding a write-lock, which in
  ** turn means that the other connection has made uncommitted changes
  ** to the schema.
  **







>







541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
  /* For a long-term use prepared statement avoid the use of
  ** lookaside memory.
  */
  if( prepFlags & SQLITE_PREPARE_PERSISTENT ){
    sParse.disableLookaside++;
    db->lookaside.bDisable++;
  }
  sParse.disableVtab = (prepFlags & SQLITE_PREPARE_NO_VTAB)!=0;

  /* Check to verify that it is possible to get a read lock on all
  ** database schemas.  The inability to get a read lock indicates that
  ** some other database connection is holding a write-lock, which in
  ** turn means that the other connection has made uncommitted changes
  ** to the schema.
  **
Changes to src/resolve.c.
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
1683

1684

1685
1686
1687

1688
1689
1690
1691

1692
1693
1694
1695
1696

1697
  w.xSelectCallback2 = 0;
  w.pParse = pParse;
  w.u.pNC = pOuterNC;
  sqlite3WalkSelect(&w, p);
}

/*
** Resolve names in expressions that can only reference a single table:

**
**    *   CHECK constraints
**    *   WHERE clauses on partial indices


**
** The Expr.iTable value for Expr.op==TK_COLUMN nodes of the expression
** is set to -1 and the Expr.iColumn value is set to the column number.

**
** Any errors cause an error message to be set in pParse.
*/
void sqlite3ResolveSelfReference(
  Parse *pParse,      /* Parsing context */
  Table *pTab,        /* The table being referenced */
  int type,           /* NC_IsCheck or NC_PartIdx or NC_IdxExpr */
  Expr *pExpr,        /* Expression to resolve.  May be NULL. */
  ExprList *pList     /* Expression list to resolve.  May be NULL. */
){
  SrcList sSrc;                   /* Fake SrcList for pParse->pNewTable */
  NameContext sNC;                /* Name context for pParse->pNewTable */



  assert( type==NC_IsCheck || type==NC_PartIdx || type==NC_IdxExpr );
  memset(&sNC, 0, sizeof(sNC));
  memset(&sSrc, 0, sizeof(sSrc));

  sSrc.nSrc = 1;
  sSrc.a[0].zName = pTab->zName;
  sSrc.a[0].pTab = pTab;
  sSrc.a[0].iCursor = -1;

  sNC.pParse = pParse;
  sNC.pSrcList = &sSrc;
  sNC.ncFlags = type;
  if( sqlite3ResolveExprNames(&sNC, pExpr) ) return;
  if( pList ) sqlite3ResolveExprListNames(&sNC, pList);

}







|
>

|
|
>
>

|
|
>



|

|
|





>

>
|


>
|
|
|
|
>



|
|
>

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
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
  w.xSelectCallback2 = 0;
  w.pParse = pParse;
  w.u.pNC = pOuterNC;
  sqlite3WalkSelect(&w, p);
}

/*
** Resolve names in expressions that can only reference a single table
** or which cannot reference any tables at all.  Examples:
**
**    (1)   CHECK constraints
**    (2)   WHERE clauses on partial indices
**    (3)   Expressions in indexes on expressions
**    (4)   Expression arguments to VACUUM INTO.
**
** In all cases except (4), the Expr.iTable value for Expr.op==TK_COLUMN
** nodes of the expression is set to -1 and the Expr.iColumn value is
** set to the column number.  In case (4), TK_COLUMN nodes cause an error.
**
** Any errors cause an error message to be set in pParse.
*/
int sqlite3ResolveSelfReference(
  Parse *pParse,      /* Parsing context */
  Table *pTab,        /* The table being referenced, or NULL */
  int type,           /* NC_IsCheck or NC_PartIdx or NC_IdxExpr, or 0 */
  Expr *pExpr,        /* Expression to resolve.  May be NULL. */
  ExprList *pList     /* Expression list to resolve.  May be NULL. */
){
  SrcList sSrc;                   /* Fake SrcList for pParse->pNewTable */
  NameContext sNC;                /* Name context for pParse->pNewTable */
  int rc;

  assert( type==0 || pTab!=0 );
  assert( type==NC_IsCheck || type==NC_PartIdx || type==NC_IdxExpr || pTab==0 );
  memset(&sNC, 0, sizeof(sNC));
  memset(&sSrc, 0, sizeof(sSrc));
  if( pTab ){
    sSrc.nSrc = 1;
    sSrc.a[0].zName = pTab->zName;
    sSrc.a[0].pTab = pTab;
    sSrc.a[0].iCursor = -1;
  }
  sNC.pParse = pParse;
  sNC.pSrcList = &sSrc;
  sNC.ncFlags = type;
  if( (rc = sqlite3ResolveExprNames(&sNC, pExpr))!=SQLITE_OK ) return rc;
  if( pList ) rc = sqlite3ResolveExprListNames(&sNC, pList);
  return rc;
}
Changes to src/select.c.
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
    regBase = regData - nPrefixReg;
  }else{
    regBase = pParse->nMem + 1;
    pParse->nMem += nBase;
  }
  assert( pSelect->iOffset==0 || pSelect->iLimit!=0 );
  iLimit = pSelect->iOffset ? pSelect->iOffset+1 : pSelect->iLimit;
  pSort->labelDone = sqlite3VdbeMakeLabel(v);
  sqlite3ExprCodeExprList(pParse, pSort->pOrderBy, regBase, regOrigData,
                          SQLITE_ECEL_DUP | (regOrigData? SQLITE_ECEL_REF : 0));
  if( bSeq ){
    sqlite3VdbeAddOp2(v, OP_Sequence, pSort->iECursor, regBase+nExpr);
  }
  if( nPrefixReg==0 && nData>0 ){
    sqlite3ExprCodeMove(pParse, regData, regBase+nExpr+bSeq, nData);







|







627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
    regBase = regData - nPrefixReg;
  }else{
    regBase = pParse->nMem + 1;
    pParse->nMem += nBase;
  }
  assert( pSelect->iOffset==0 || pSelect->iLimit!=0 );
  iLimit = pSelect->iOffset ? pSelect->iOffset+1 : pSelect->iLimit;
  pSort->labelDone = sqlite3VdbeMakeLabel(pParse);
  sqlite3ExprCodeExprList(pParse, pSort->pOrderBy, regBase, regOrigData,
                          SQLITE_ECEL_DUP | (regOrigData? SQLITE_ECEL_REF : 0));
  if( bSeq ){
    sqlite3VdbeAddOp2(v, OP_Sequence, pSort->iECursor, regBase+nExpr);
  }
  if( nPrefixReg==0 && nData>0 ){
    sqlite3ExprCodeMove(pParse, regData, regBase+nExpr+bSeq, nData);
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
    memset(pKI->aSortOrder, 0, pKI->nKeyField); /* Makes OP_Jump testable */
    sqlite3VdbeChangeP4(v, -1, (char*)pKI, P4_KEYINFO);
    testcase( pKI->nAllField > pKI->nKeyField+2 );
    pOp->p4.pKeyInfo = sqlite3KeyInfoFromExprList(pParse,pSort->pOrderBy,nOBSat,
                                           pKI->nAllField-pKI->nKeyField-1);
    addrJmp = sqlite3VdbeCurrentAddr(v);
    sqlite3VdbeAddOp3(v, OP_Jump, addrJmp+1, 0, addrJmp+1); VdbeCoverage(v);
    pSort->labelBkOut = sqlite3VdbeMakeLabel(v);
    pSort->regReturn = ++pParse->nMem;
    sqlite3VdbeAddOp2(v, OP_Gosub, pSort->regReturn, pSort->labelBkOut);
    sqlite3VdbeAddOp1(v, OP_ResetSorter, pSort->iECursor);
    if( iLimit ){
      sqlite3VdbeAddOp2(v, OP_IfNot, iLimit, pSort->labelDone);
      VdbeCoverage(v);
    }







|







666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
    memset(pKI->aSortOrder, 0, pKI->nKeyField); /* Makes OP_Jump testable */
    sqlite3VdbeChangeP4(v, -1, (char*)pKI, P4_KEYINFO);
    testcase( pKI->nAllField > pKI->nKeyField+2 );
    pOp->p4.pKeyInfo = sqlite3KeyInfoFromExprList(pParse,pSort->pOrderBy,nOBSat,
                                           pKI->nAllField-pKI->nKeyField-1);
    addrJmp = sqlite3VdbeCurrentAddr(v);
    sqlite3VdbeAddOp3(v, OP_Jump, addrJmp+1, 0, addrJmp+1); VdbeCoverage(v);
    pSort->labelBkOut = sqlite3VdbeMakeLabel(pParse);
    pSort->regReturn = ++pParse->nMem;
    sqlite3VdbeAddOp2(v, OP_Gosub, pSort->regReturn, pSort->labelBkOut);
    sqlite3VdbeAddOp1(v, OP_ResetSorter, pSort->iECursor);
    if( iLimit ){
      sqlite3VdbeAddOp2(v, OP_IfNot, iLimit, pSort->labelDone);
      VdbeCoverage(v);
    }
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
  Select *p,        /* The SELECT statement */
  SortCtx *pSort,   /* Information on the ORDER BY clause */
  int nColumn,      /* Number of columns of data */
  SelectDest *pDest /* Write the sorted results here */
){
  Vdbe *v = pParse->pVdbe;                     /* The prepared statement */
  int addrBreak = pSort->labelDone;            /* Jump here to exit loop */
  int addrContinue = sqlite3VdbeMakeLabel(v);  /* Jump here for next cycle */
  int addr;                       /* Top of output loop. Jump for Next. */
  int addrOnce = 0;
  int iTab;
  ExprList *pOrderBy = pSort->pOrderBy;
  int eDest = pDest->eDest;
  int iParm = pDest->iSDParm;
  int regRow;







|







1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
  Select *p,        /* The SELECT statement */
  SortCtx *pSort,   /* Information on the ORDER BY clause */
  int nColumn,      /* Number of columns of data */
  SelectDest *pDest /* Write the sorted results here */
){
  Vdbe *v = pParse->pVdbe;                     /* The prepared statement */
  int addrBreak = pSort->labelDone;            /* Jump here to exit loop */
  int addrContinue = sqlite3VdbeMakeLabel(pParse);/* Jump here for next cycle */
  int addr;                       /* Top of output loop. Jump for Next. */
  int addrOnce = 0;
  int iTab;
  ExprList *pOrderBy = pSort->pOrderBy;
  int eDest = pDest->eDest;
  int iParm = pDest->iSDParm;
  int regRow;
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
  }
#endif

  /* Obtain authorization to do a recursive query */
  if( sqlite3AuthCheck(pParse, SQLITE_RECURSIVE, 0, 0, 0) ) return;

  /* Process the LIMIT and OFFSET clauses, if they exist */
  addrBreak = sqlite3VdbeMakeLabel(v);
  p->nSelectRow = 320;  /* 4 billion rows */
  computeLimitRegisters(pParse, p, addrBreak);
  pLimit = p->pLimit;
  regLimit = p->iLimit;
  regOffset = p->iOffset;
  p->pLimit = 0;
  p->iLimit = p->iOffset = 0;







|







2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
  }
#endif

  /* Obtain authorization to do a recursive query */
  if( sqlite3AuthCheck(pParse, SQLITE_RECURSIVE, 0, 0, 0) ) return;

  /* Process the LIMIT and OFFSET clauses, if they exist */
  addrBreak = sqlite3VdbeMakeLabel(pParse);
  p->nSelectRow = 320;  /* 4 billion rows */
  computeLimitRegisters(pParse, p, addrBreak);
  pLimit = p->pLimit;
  regLimit = p->iLimit;
  regOffset = p->iOffset;
  p->pLimit = 0;
  p->iLimit = p->iOffset = 0;
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
    sqlite3VdbeAddOp3(v, OP_Column, iQueue, pOrderBy->nExpr+1, regCurrent);
  }else{
    sqlite3VdbeAddOp2(v, OP_RowData, iQueue, regCurrent);
  }
  sqlite3VdbeAddOp1(v, OP_Delete, iQueue);

  /* Output the single row in Current */
  addrCont = sqlite3VdbeMakeLabel(v);
  codeOffset(v, regOffset, addrCont);
  selectInnerLoop(pParse, p, iCurrent,
      0, 0, pDest, addrCont, addrBreak);
  if( regLimit ){
    sqlite3VdbeAddOp2(v, OP_DecrJumpZero, regLimit, addrBreak);
    VdbeCoverage(v);
  }







|







2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
    sqlite3VdbeAddOp3(v, OP_Column, iQueue, pOrderBy->nExpr+1, regCurrent);
  }else{
    sqlite3VdbeAddOp2(v, OP_RowData, iQueue, regCurrent);
  }
  sqlite3VdbeAddOp1(v, OP_Delete, iQueue);

  /* Output the single row in Current */
  addrCont = sqlite3VdbeMakeLabel(pParse);
  codeOffset(v, regOffset, addrCont);
  selectInnerLoop(pParse, p, iCurrent,
      0, 0, pDest, addrCont, addrBreak);
  if( regLimit ){
    sqlite3VdbeAddOp2(v, OP_DecrJumpZero, regLimit, addrBreak);
    VdbeCoverage(v);
  }
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
        /* Convert the data in the temporary table into whatever form
        ** it is that we currently need.
        */
        assert( unionTab==dest.iSDParm || dest.eDest!=priorOp );
        if( dest.eDest!=priorOp ){
          int iCont, iBreak, iStart;
          assert( p->pEList );
          iBreak = sqlite3VdbeMakeLabel(v);
          iCont = sqlite3VdbeMakeLabel(v);
          computeLimitRegisters(pParse, p, iBreak);
          sqlite3VdbeAddOp2(v, OP_Rewind, unionTab, iBreak); VdbeCoverage(v);
          iStart = sqlite3VdbeCurrentAddr(v);
          selectInnerLoop(pParse, p, unionTab,
                          0, 0, &dest, iCont, iBreak);
          sqlite3VdbeResolveLabel(v, iCont);
          sqlite3VdbeAddOp2(v, OP_Next, unionTab, iStart); VdbeCoverage(v);







|
|







2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
        /* Convert the data in the temporary table into whatever form
        ** it is that we currently need.
        */
        assert( unionTab==dest.iSDParm || dest.eDest!=priorOp );
        if( dest.eDest!=priorOp ){
          int iCont, iBreak, iStart;
          assert( p->pEList );
          iBreak = sqlite3VdbeMakeLabel(pParse);
          iCont = sqlite3VdbeMakeLabel(pParse);
          computeLimitRegisters(pParse, p, iBreak);
          sqlite3VdbeAddOp2(v, OP_Rewind, unionTab, iBreak); VdbeCoverage(v);
          iStart = sqlite3VdbeCurrentAddr(v);
          selectInnerLoop(pParse, p, unionTab,
                          0, 0, &dest, iCont, iBreak);
          sqlite3VdbeResolveLabel(v, iCont);
          sqlite3VdbeAddOp2(v, OP_Next, unionTab, iStart); VdbeCoverage(v);
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
        sqlite3ExprDelete(db, p->pLimit);
        p->pLimit = pLimit;
  
        /* Generate code to take the intersection of the two temporary
        ** tables.
        */
        assert( p->pEList );
        iBreak = sqlite3VdbeMakeLabel(v);
        iCont = sqlite3VdbeMakeLabel(v);
        computeLimitRegisters(pParse, p, iBreak);
        sqlite3VdbeAddOp2(v, OP_Rewind, tab1, iBreak); VdbeCoverage(v);
        r1 = sqlite3GetTempReg(pParse);
        iStart = sqlite3VdbeAddOp2(v, OP_RowData, tab1, r1);
        sqlite3VdbeAddOp4Int(v, OP_NotFound, tab2, iCont, r1, 0);
        VdbeCoverage(v);
        sqlite3ReleaseTempReg(pParse, r1);







|
|







2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
        sqlite3ExprDelete(db, p->pLimit);
        p->pLimit = pLimit;
  
        /* Generate code to take the intersection of the two temporary
        ** tables.
        */
        assert( p->pEList );
        iBreak = sqlite3VdbeMakeLabel(pParse);
        iCont = sqlite3VdbeMakeLabel(pParse);
        computeLimitRegisters(pParse, p, iBreak);
        sqlite3VdbeAddOp2(v, OP_Rewind, tab1, iBreak); VdbeCoverage(v);
        r1 = sqlite3GetTempReg(pParse);
        iStart = sqlite3VdbeAddOp2(v, OP_RowData, tab1, r1);
        sqlite3VdbeAddOp4Int(v, OP_NotFound, tab2, iCont, r1, 0);
        VdbeCoverage(v);
        sqlite3ReleaseTempReg(pParse, r1);
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
  int iBreak              /* Jump here if we hit the LIMIT */
){
  Vdbe *v = pParse->pVdbe;
  int iContinue;
  int addr;

  addr = sqlite3VdbeCurrentAddr(v);
  iContinue = sqlite3VdbeMakeLabel(v);

  /* Suppress duplicates for UNION, EXCEPT, and INTERSECT 
  */
  if( regPrev ){
    int addr1, addr2;
    addr1 = sqlite3VdbeAddOp1(v, OP_IfNot, regPrev); VdbeCoverage(v);
    addr2 = sqlite3VdbeAddOp4(v, OP_Compare, pIn->iSdst, regPrev+1, pIn->nSdst,







|







2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
  int iBreak              /* Jump here if we hit the LIMIT */
){
  Vdbe *v = pParse->pVdbe;
  int iContinue;
  int addr;

  addr = sqlite3VdbeCurrentAddr(v);
  iContinue = sqlite3VdbeMakeLabel(pParse);

  /* Suppress duplicates for UNION, EXCEPT, and INTERSECT 
  */
  if( regPrev ){
    int addr1, addr2;
    addr1 = sqlite3VdbeAddOp1(v, OP_IfNot, regPrev); VdbeCoverage(v);
    addr2 = sqlite3VdbeAddOp4(v, OP_Compare, pIn->iSdst, regPrev+1, pIn->nSdst,
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
  int *aPermute;        /* Mapping from ORDER BY terms to result set columns */

  assert( p->pOrderBy!=0 );
  assert( pKeyDup==0 ); /* "Managed" code needs this.  Ticket #3382. */
  db = pParse->db;
  v = pParse->pVdbe;
  assert( v!=0 );       /* Already thrown the error if VDBE alloc failed */
  labelEnd = sqlite3VdbeMakeLabel(v);
  labelCmpr = sqlite3VdbeMakeLabel(v);


  /* Patch up the ORDER BY clause
  */
  op = p->op;  
  pPrior = p->pPrior;
  assert( pPrior->pOrderBy==0 );







|
|







3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
  int *aPermute;        /* Mapping from ORDER BY terms to result set columns */

  assert( p->pOrderBy!=0 );
  assert( pKeyDup==0 ); /* "Managed" code needs this.  Ticket #3382. */
  db = pParse->db;
  v = pParse->pVdbe;
  assert( v!=0 );       /* Already thrown the error if VDBE alloc failed */
  labelEnd = sqlite3VdbeMakeLabel(pParse);
  labelCmpr = sqlite3VdbeMakeLabel(pParse);


  /* Patch up the ORDER BY clause
  */
  op = p->op;  
  pPrior = p->pPrior;
  assert( pPrior->pOrderBy==0 );
5326
5327
5328
5329
5330
5331
5332
5333
5334
5335
5336
5337
5338
5339
5340
      regAgg = sqlite3GetTempRange(pParse, nArg);
      sqlite3ExprCodeExprList(pParse, pList, regAgg, 0, SQLITE_ECEL_DUP);
    }else{
      nArg = 0;
      regAgg = 0;
    }
    if( pF->iDistinct>=0 ){
      addrNext = sqlite3VdbeMakeLabel(v);
      testcase( nArg==0 );  /* Error condition */
      testcase( nArg>1 );   /* Also an error */
      codeDistinct(pParse, pF->iDistinct, addrNext, 1, regAgg);
    }
    if( pF->pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL ){
      CollSeq *pColl = 0;
      struct ExprList_item *pItem;







|







5326
5327
5328
5329
5330
5331
5332
5333
5334
5335
5336
5337
5338
5339
5340
      regAgg = sqlite3GetTempRange(pParse, nArg);
      sqlite3ExprCodeExprList(pParse, pList, regAgg, 0, SQLITE_ECEL_DUP);
    }else{
      nArg = 0;
      regAgg = 0;
    }
    if( pF->iDistinct>=0 ){
      addrNext = sqlite3VdbeMakeLabel(pParse);
      testcase( nArg==0 );  /* Error condition */
      testcase( nArg>1 );   /* Also an error */
      codeDistinct(pParse, pF->iDistinct, addrNext, 1, regAgg);
    }
    if( pF->pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL ){
      CollSeq *pColl = 0;
      struct ExprList_item *pItem;
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;
5826
5827
5828
5829
5830
5831
5832
5833
5834
5835
5836
5837
5838
5839
5840
5841
5842
5843
5844
5845
5846
5847
5848
5849
5850
5851
5852
5853
5854
5855

#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
    /* Generate code for all sub-queries in the FROM clause
    */
    pSub = pItem->pSelect;
    if( pSub==0 ) continue;

    /* Sometimes the code for a subquery will be generated more than
    ** once, if the subquery is part of the WHERE clause in a LEFT JOIN,
    ** for example.  In that case, do not regenerate the code to manifest
    ** a view or the co-routine to implement a view.  The first instance
    ** is sufficient, though the subroutine to manifest the view does need
    ** to be invoked again. */
    if( pItem->addrFillSub ){
      if( pItem->fg.viaCoroutine==0 ){
        /* The subroutine that manifests the view might be a one-time routine,
        ** or it might need to be rerun on each iteration because it
        ** encodes a correlated subquery. */
        testcase( sqlite3VdbeGetOp(v, pItem->addrFillSub)->opcode==OP_Once );
        sqlite3VdbeAddOp2(v, OP_Gosub, pItem->regReturn, pItem->addrFillSub);
      }
      continue;
    }

    /* Increment Parse.nHeight by the height of the largest expression
    ** tree referred to by this, the parent select. The child select
    ** may contain expression trees of at most
    ** (SQLITE_MAX_EXPR_DEPTH-Parse.nHeight) height. This is a bit
    ** more conservative than necessary, but much easier than enforcing
    ** an exact limit.







|
|
|
|
<
|
|
<
<
<
<
<
<
<
<
<







5831
5832
5833
5834
5835
5836
5837
5838
5839
5840
5841

5842
5843









5844
5845
5846
5847
5848
5849
5850

#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
    /* Generate code for all sub-queries in the FROM clause
    */
    pSub = pItem->pSelect;
    if( pSub==0 ) continue;

    /* The code for a subquery should only be generated once, though it is
    ** technically harmless for it to be generated multiple times. The
    ** following assert() will detect if something changes to cause
    ** the same subquery to be coded multiple times, as a signal to the

    ** developers to try to optimize the situation. */
    assert( pItem->addrFillSub==0 );










    /* Increment Parse.nHeight by the height of the largest expression
    ** tree referred to by this, the parent select. The child select
    ** may contain expression trees of at most
    ** (SQLITE_MAX_EXPR_DEPTH-Parse.nHeight) height. This is a bit
    ** more conservative than necessary, but much easier than enforcing
    ** an exact limit.
6029
6030
6031
6032
6033
6034
6035
6036
6037
6038
6039
6040
6041
6042
6043
  */
  if( pDest->eDest==SRT_EphemTab ){
    sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pDest->iSDParm, pEList->nExpr);
  }

  /* Set the limiter.
  */
  iEnd = sqlite3VdbeMakeLabel(v);
  if( (p->selFlags & SF_FixedLimit)==0 ){
    p->nSelectRow = 320;  /* 4 billion rows */
  }
  computeLimitRegisters(pParse, p, iEnd);
  if( p->iLimit==0 && sSort.addrSortIndex>=0 ){
    sqlite3VdbeChangeOpcode(v, sSort.addrSortIndex, OP_SorterOpen);
    sSort.sortFlags |= SORTFLAG_UseSorter;







|







6024
6025
6026
6027
6028
6029
6030
6031
6032
6033
6034
6035
6036
6037
6038
  */
  if( pDest->eDest==SRT_EphemTab ){
    sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pDest->iSDParm, pEList->nExpr);
  }

  /* Set the limiter.
  */
  iEnd = sqlite3VdbeMakeLabel(pParse);
  if( (p->selFlags & SF_FixedLimit)==0 ){
    p->nSelectRow = 320;  /* 4 billion rows */
  }
  computeLimitRegisters(pParse, p, iEnd);
  if( p->iLimit==0 && sSort.addrSortIndex>=0 ){
    sqlite3VdbeChangeOpcode(v, sSort.addrSortIndex, OP_SorterOpen);
    sSort.sortFlags |= SORTFLAG_UseSorter;
6096
6097
6098
6099
6100
6101
6102
6103
6104
6105
6106
6107
6108
6109
6110
6111
6112
    if( sSort.addrSortIndex>=0 && sSort.pOrderBy==0 ){
      sqlite3VdbeChangeToNoop(v, sSort.addrSortIndex);
    }

    assert( p->pEList==pEList );
#ifndef SQLITE_OMIT_WINDOWFUNC
    if( pWin ){
      int addrGosub = sqlite3VdbeMakeLabel(v);
      int iCont = sqlite3VdbeMakeLabel(v);
      int iBreak = sqlite3VdbeMakeLabel(v);
      int regGosub = ++pParse->nMem;

      sqlite3WindowCodeStep(pParse, p, pWInfo, regGosub, addrGosub);

      sqlite3VdbeAddOp2(v, OP_Goto, 0, iBreak);
      sqlite3VdbeResolveLabel(v, addrGosub);
      VdbeNoopComment((v, "inner-loop subroutine"));







|
|
|







6091
6092
6093
6094
6095
6096
6097
6098
6099
6100
6101
6102
6103
6104
6105
6106
6107
    if( sSort.addrSortIndex>=0 && sSort.pOrderBy==0 ){
      sqlite3VdbeChangeToNoop(v, sSort.addrSortIndex);
    }

    assert( p->pEList==pEList );
#ifndef SQLITE_OMIT_WINDOWFUNC
    if( pWin ){
      int addrGosub = sqlite3VdbeMakeLabel(pParse);
      int iCont = sqlite3VdbeMakeLabel(pParse);
      int iBreak = sqlite3VdbeMakeLabel(pParse);
      int regGosub = ++pParse->nMem;

      sqlite3WindowCodeStep(pParse, p, pWInfo, regGosub, addrGosub);

      sqlite3VdbeAddOp2(v, OP_Goto, 0, iBreak);
      sqlite3VdbeResolveLabel(v, addrGosub);
      VdbeNoopComment((v, "inner-loop subroutine"));
6173
6174
6175
6176
6177
6178
6179
6180
6181
6182
6183
6184
6185
6186
6187
    ** ORDER BY and GROUP BY clauses are the same by setting the orderByGrp
    ** variable.  */
    if( sqlite3ExprListCompare(pGroupBy, sSort.pOrderBy, -1)==0 ){
      orderByGrp = 1;
    }
 
    /* Create a label to jump to when we want to abort the query */
    addrEnd = sqlite3VdbeMakeLabel(v);

    /* Convert TK_COLUMN nodes into TK_AGG_COLUMN and make entries in
    ** sAggInfo for all TK_AGG_FUNCTION nodes in expressions of the
    ** SELECT statement.
    */
    memset(&sNC, 0, sizeof(sNC));
    sNC.pParse = pParse;







|







6168
6169
6170
6171
6172
6173
6174
6175
6176
6177
6178
6179
6180
6181
6182
    ** ORDER BY and GROUP BY clauses are the same by setting the orderByGrp
    ** variable.  */
    if( sqlite3ExprListCompare(pGroupBy, sSort.pOrderBy, -1)==0 ){
      orderByGrp = 1;
    }
 
    /* Create a label to jump to when we want to abort the query */
    addrEnd = sqlite3VdbeMakeLabel(pParse);

    /* Convert TK_COLUMN nodes into TK_AGG_COLUMN and make entries in
    ** sAggInfo for all TK_AGG_FUNCTION nodes in expressions of the
    ** SELECT statement.
    */
    memset(&sNC, 0, sizeof(sNC));
    sNC.pParse = pParse;
6262
6263
6264
6265
6266
6267
6268
6269
6270
6271
6272
6273
6274
6275
6276
6277
6278
          0, (char*)pKeyInfo, P4_KEYINFO);

      /* Initialize memory locations used by GROUP BY aggregate processing
      */
      iUseFlag = ++pParse->nMem;
      iAbortFlag = ++pParse->nMem;
      regOutputRow = ++pParse->nMem;
      addrOutputRow = sqlite3VdbeMakeLabel(v);
      regReset = ++pParse->nMem;
      addrReset = sqlite3VdbeMakeLabel(v);
      iAMem = pParse->nMem + 1;
      pParse->nMem += pGroupBy->nExpr;
      iBMem = pParse->nMem + 1;
      pParse->nMem += pGroupBy->nExpr;
      sqlite3VdbeAddOp2(v, OP_Integer, 0, iAbortFlag);
      VdbeComment((v, "clear abort flag"));
      sqlite3VdbeAddOp3(v, OP_Null, 0, iAMem, iAMem+pGroupBy->nExpr-1);







|

|







6257
6258
6259
6260
6261
6262
6263
6264
6265
6266
6267
6268
6269
6270
6271
6272
6273
          0, (char*)pKeyInfo, P4_KEYINFO);

      /* Initialize memory locations used by GROUP BY aggregate processing
      */
      iUseFlag = ++pParse->nMem;
      iAbortFlag = ++pParse->nMem;
      regOutputRow = ++pParse->nMem;
      addrOutputRow = sqlite3VdbeMakeLabel(pParse);
      regReset = ++pParse->nMem;
      addrReset = sqlite3VdbeMakeLabel(pParse);
      iAMem = pParse->nMem + 1;
      pParse->nMem += pGroupBy->nExpr;
      iBMem = pParse->nMem + 1;
      pParse->nMem += pGroupBy->nExpr;
      sqlite3VdbeAddOp2(v, OP_Integer, 0, iAbortFlag);
      VdbeComment((v, "clear abort flag"));
      sqlite3VdbeAddOp3(v, OP_Null, 0, iAMem, iAMem+pGroupBy->nExpr-1);
Changes to src/sqlite.h.in.
3632
3633
3634
3635
3636
3637
3638





3639
3640
3641
3642

3643
3644
3645
3646
3647
3648
3649
** [[SQLITE_PREPARE_NORMALIZE]] <dt>SQLITE_PREPARE_NORMALIZE</dt>
** <dd>The SQLITE_PREPARE_NORMALIZE flag is a no-op. This flag used
** to be required for any prepared statement that wanted to use the
** [sqlite3_normalized_sql()] interface.  However, the
** [sqlite3_normalized_sql()] interface is now available to all
** prepared statements, regardless of whether or not they use this
** flag.





** </dl>
*/
#define SQLITE_PREPARE_PERSISTENT              0x01
#define SQLITE_PREPARE_NORMALIZE               0x02


/*
** CAPI3REF: Compiling An SQL Statement
** KEYWORDS: {SQL statement compiler}
** METHOD: sqlite3
** CONSTRUCTOR: sqlite3_stmt
**







>
>
>
>
>




>







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

/*
** CAPI3REF: Compiling An SQL Statement
** KEYWORDS: {SQL statement compiler}
** METHOD: sqlite3
** CONSTRUCTOR: sqlite3_stmt
**
Changes to src/sqliteInt.h.
2482
2483
2484
2485
2486
2487
2488




2489
2490
2491
2492
2493
2494
2495
                         ** TK_COLUMN: the value of p5 for OP_Column
                         ** TK_AGG_FUNCTION: nesting depth */
  AggInfo *pAggInfo;     /* Used by TK_AGG_COLUMN and TK_AGG_FUNCTION */
  union {
    Table *pTab;           /* TK_COLUMN: Table containing column. Can be NULL
                           ** for a column of an index on an expression */
    Window *pWin;          /* TK_FUNCTION: Window definition for the func */




  } y;
};

/*
** The following are the meanings of bits in the Expr.flags field.
*/
#define EP_FromJoin  0x000001 /* Originates in ON/USING clause of outer join */







>
>
>
>







2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
                         ** TK_COLUMN: the value of p5 for OP_Column
                         ** TK_AGG_FUNCTION: nesting depth */
  AggInfo *pAggInfo;     /* Used by TK_AGG_COLUMN and TK_AGG_FUNCTION */
  union {
    Table *pTab;           /* TK_COLUMN: Table containing column. Can be NULL
                           ** for a column of an index on an expression */
    Window *pWin;          /* TK_FUNCTION: Window definition for the func */
    struct {               /* TK_IN, TK_SELECT, and TK_EXISTS */
      int iAddr;             /* Subroutine entry address */
      int regReturn;         /* Register used to hold return address */
    } sub;
  } y;
};

/*
** The following are the meanings of bits in the Expr.flags field.
*/
#define EP_FromJoin  0x000001 /* Originates in ON/USING clause of outer join */
2513
2514
2515
2516
2517
2518
2519

2520
2521
2522
2523
2524
2525
2526
#define EP_Unlikely  0x040000 /* unlikely() or likelihood() function */
#define EP_ConstFunc 0x080000 /* A SQLITE_FUNC_CONSTANT or _SLOCHNG function */
#define EP_CanBeNull 0x100000 /* Can be null despite NOT NULL constraint */
#define EP_Subquery  0x200000 /* Tree contains a TK_SELECT operator */
#define EP_Alias     0x400000 /* Is an alias for a result set column */
#define EP_Leaf      0x800000 /* Expr.pLeft, .pRight, .u.pSelect all NULL */
#define EP_WinFunc  0x1000000 /* TK_FUNCTION with Expr.y.pWin set */


/*
** The EP_Propagate mask is a set of properties that automatically propagate
** upwards into parent nodes.
*/
#define EP_Propagate (EP_Collate|EP_Subquery|EP_HasFunc)








>







2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
#define EP_Unlikely  0x040000 /* unlikely() or likelihood() function */
#define EP_ConstFunc 0x080000 /* A SQLITE_FUNC_CONSTANT or _SLOCHNG function */
#define EP_CanBeNull 0x100000 /* Can be null despite NOT NULL constraint */
#define EP_Subquery  0x200000 /* Tree contains a TK_SELECT operator */
#define EP_Alias     0x400000 /* Is an alias for a result set column */
#define EP_Leaf      0x800000 /* Expr.pLeft, .pRight, .u.pSelect all NULL */
#define EP_WinFunc  0x1000000 /* TK_FUNCTION with Expr.y.pWin set */
#define EP_Subrtn   0x2000000 /* Uses Expr.y.sub. TK_IN, _SELECT, or _EXISTS */

/*
** The EP_Propagate mask is a set of properties that automatically propagate
** upwards into parent nodes.
*/
#define EP_Propagate (EP_Collate|EP_Subquery|EP_HasFunc)

3056
3057
3058
3059
3060
3061
3062

3063
3064
3065
3066
3067
3068
3069
3070
3071
3072

3073
3074
3075
3076
3077
3078
3079
  u8 nested;           /* Number of nested calls to the parser/code generator */
  u8 nTempReg;         /* Number of temporary registers in aTempReg[] */
  u8 isMultiWrite;     /* True if statement may modify/insert multiple rows */
  u8 mayAbort;         /* True if statement may throw an ABORT exception */
  u8 hasCompound;      /* Need to invoke convertCompoundSelectToSubquery() */
  u8 okConstFactor;    /* OK to factor out constants */
  u8 disableLookaside; /* Number of times lookaside has been disabled */

  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 *pConstExpr;/* Constant expressions */
  Token constraintName;/* Name of the constraint currently being parsed */
  yDbMask writeMask;   /* Start a write transaction on these databases */
  yDbMask cookieMask;  /* Bitmask of schema verified databases */
  int regRowid;        /* Register holding rowid of CREATE TABLE entry */
  int regRoot;         /* Register holding root page number for new objects */







>





<



|
>







3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073

3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
  u8 nested;           /* Number of nested calls to the parser/code generator */
  u8 nTempReg;         /* Number of temporary registers in aTempReg[] */
  u8 isMultiWrite;     /* True if statement may modify/insert multiple rows */
  u8 mayAbort;         /* True if statement may throw an ABORT exception */
  u8 hasCompound;      /* Need to invoke convertCompoundSelectToSubquery() */
  u8 okConstFactor;    /* OK to factor out constants */
  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;          /* The *negative* of the number of labels used */
  int nLabelAlloc;     /* Number of slots in aLabel */
  int *aLabel;         /* Space to hold the labels */
  ExprList *pConstExpr;/* Constant expressions */
  Token constraintName;/* Name of the constraint currently being parsed */
  yDbMask writeMask;   /* Start a write transaction on these databases */
  yDbMask cookieMask;  /* Bitmask of schema verified databases */
  int regRowid;        /* Register holding rowid of CREATE TABLE entry */
  int regRoot;         /* Register holding root page number for new objects */
4254
4255
4256
4257
4258
4259
4260

4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
void sqlite3Reindex(Parse*, Token*, Token*);
void sqlite3AlterFunctions(void);
void sqlite3AlterRenameTable(Parse*, SrcList*, Token*);
void sqlite3AlterRenameColumn(Parse*, SrcList*, Token*, Token*);
int sqlite3GetToken(const unsigned char *, int *);
void sqlite3NestedParse(Parse*, const char*, ...);
void sqlite3ExpirePreparedStatements(sqlite3*, int);

int sqlite3CodeSubselect(Parse*, Expr *, int, int);
void sqlite3SelectPrep(Parse*, Select*, NameContext*);
void sqlite3SelectWrongNumTermsError(Parse *pParse, Select *p);
int sqlite3MatchSpanName(const char*, const char*, const char*, const char*);
int sqlite3ResolveExprNames(NameContext*, Expr*);
int sqlite3ResolveExprListNames(NameContext*, ExprList*);
void sqlite3ResolveSelectNames(Parse*, Select*, NameContext*);
void sqlite3ResolveSelfReference(Parse*,Table*,int,Expr*,ExprList*);
int sqlite3ResolveOrderGroupBy(Parse*, Select*, ExprList*, const char*);
void sqlite3ColumnDefault(Vdbe *, Table *, int, int);
void sqlite3AlterFinishAddColumn(Parse *, Token *);
void sqlite3AlterBeginAddColumn(Parse *, SrcList *);
void *sqlite3RenameTokenMap(Parse*, void*, Token*);
void sqlite3RenameTokenRemap(Parse*, void *pTo, void *pFrom);
void sqlite3RenameExprUnmap(Parse*, Expr*);







>
|






|







4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
void sqlite3Reindex(Parse*, Token*, Token*);
void sqlite3AlterFunctions(void);
void sqlite3AlterRenameTable(Parse*, SrcList*, Token*);
void sqlite3AlterRenameColumn(Parse*, SrcList*, Token*, Token*);
int sqlite3GetToken(const unsigned char *, int *);
void sqlite3NestedParse(Parse*, const char*, ...);
void sqlite3ExpirePreparedStatements(sqlite3*, int);
void sqlite3CodeRhsOfIN(Parse*, Expr*, int, int);
int sqlite3CodeSubselect(Parse*, Expr*);
void sqlite3SelectPrep(Parse*, Select*, NameContext*);
void sqlite3SelectWrongNumTermsError(Parse *pParse, Select *p);
int sqlite3MatchSpanName(const char*, const char*, const char*, const char*);
int sqlite3ResolveExprNames(NameContext*, Expr*);
int sqlite3ResolveExprListNames(NameContext*, ExprList*);
void sqlite3ResolveSelectNames(Parse*, Select*, NameContext*);
int sqlite3ResolveSelfReference(Parse*,Table*,int,Expr*,ExprList*);
int sqlite3ResolveOrderGroupBy(Parse*, Select*, ExprList*, const char*);
void sqlite3ColumnDefault(Vdbe *, Table *, int, int);
void sqlite3AlterFinishAddColumn(Parse *, Token *);
void sqlite3AlterBeginAddColumn(Parse *, SrcList *);
void *sqlite3RenameTokenMap(Parse*, void*, Token*);
void sqlite3RenameTokenRemap(Parse*, void *pTo, void *pFrom);
void sqlite3RenameExprUnmap(Parse*, Expr*);
4506
4507
4508
4509
4510
4511
4512
4513
4514
4515
4516
4517
4518
4519
4520
#define IN_INDEX_NOOP         5   /* No table available. Use comparisons */
/*
** Allowed flags for the 3rd parameter to sqlite3FindInIndex().
*/
#define IN_INDEX_NOOP_OK     0x0001  /* OK to return IN_INDEX_NOOP */
#define IN_INDEX_MEMBERSHIP  0x0002  /* IN operator used for membership test */
#define IN_INDEX_LOOP        0x0004  /* IN operator used as a loop */
int sqlite3FindInIndex(Parse *, Expr *, u32, int*, int*);

int sqlite3JournalOpen(sqlite3_vfs *, const char *, sqlite3_file *, int, int);
int sqlite3JournalSize(sqlite3_vfs *);
#if defined(SQLITE_ENABLE_ATOMIC_WRITE) \
 || defined(SQLITE_ENABLE_BATCH_ATOMIC_WRITE)
  int sqlite3JournalCreate(sqlite3_file *);
#endif







|







4513
4514
4515
4516
4517
4518
4519
4520
4521
4522
4523
4524
4525
4526
4527
#define IN_INDEX_NOOP         5   /* No table available. Use comparisons */
/*
** Allowed flags for the 3rd parameter to sqlite3FindInIndex().
*/
#define IN_INDEX_NOOP_OK     0x0001  /* OK to return IN_INDEX_NOOP */
#define IN_INDEX_MEMBERSHIP  0x0002  /* IN operator used for membership test */
#define IN_INDEX_LOOP        0x0004  /* IN operator used as a loop */
int sqlite3FindInIndex(Parse *, Expr *, u32, int*, int*, int*);

int sqlite3JournalOpen(sqlite3_vfs *, const char *, sqlite3_file *, int, int);
int sqlite3JournalSize(sqlite3_vfs *);
#if defined(SQLITE_ENABLE_ATOMIC_WRITE) \
 || defined(SQLITE_ENABLE_BATCH_ATOMIC_WRITE)
  int sqlite3JournalCreate(sqlite3_file *);
#endif
Changes to src/test_vfs.c.
224
225
226
227
228
229
230
231
232
233
234
235


236
237
238
239
240
241
242
};

static int tvfsResultCode(Testvfs *p, int *pRc){
  struct errcode {
    int eCode;
    const char *zCode;
  } aCode[] = {
    { SQLITE_OK,     "SQLITE_OK"     },
    { SQLITE_ERROR,  "SQLITE_ERROR"  },
    { SQLITE_IOERR,  "SQLITE_IOERR"  },
    { SQLITE_LOCKED, "SQLITE_LOCKED" },
    { SQLITE_BUSY,   "SQLITE_BUSY"   },


  };

  const char *z;
  int i;

  z = Tcl_GetStringResult(p->interp);
  for(i=0; i<ArraySize(aCode); i++){







|
|
|
|
|
>
>







224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
};

static int tvfsResultCode(Testvfs *p, int *pRc){
  struct errcode {
    int eCode;
    const char *zCode;
  } 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++){
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
    p->pBuffer = pBuffer;
  }

  /* Connect the TestvfsBuffer to the new TestvfsShm handle and return. */
  pFd->pNext = pBuffer->pFile;
  pBuffer->pFile = pFd;
  pFd->pShm = pBuffer;
  return SQLITE_OK;
}

static void tvfsAllocPage(TestvfsBuffer *p, int iPage, int pgsz){
  assert( iPage<TESTVFS_MAX_PAGES );
  if( p->aPage[iPage]==0 ){
    p->aPage[iPage] = (u8 *)ckalloc(pgsz);
    memset(p->aPage[iPage], 0, pgsz);







|







863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
    p->pBuffer = pBuffer;
  }

  /* Connect the TestvfsBuffer to the new TestvfsShm handle and return. */
  pFd->pNext = pBuffer->pFile;
  pBuffer->pFile = pFd;
  pFd->pShm = pBuffer;
  return rc;
}

static void tvfsAllocPage(TestvfsBuffer *p, int iPage, int pgsz){
  assert( iPage<TESTVFS_MAX_PAGES );
  if( p->aPage[iPage]==0 ){
    p->aPage[iPage] = (u8 *)ckalloc(pgsz);
    memset(p->aPage[iPage], 0, pgsz);
914
915
916
917
918
919
920

921

922
923
924
925
926
927
928
  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,







>
|
>







916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
  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,
1558
1559
1560
1561
1562
1563
1564
1565









































































































1566
1567


1568
1569
1570
1571

  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








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


>
>




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

  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/trigger.c.
912
913
914
915
916
917
918

919
920
921
922
923
924
925
  sNC.pParse = pSubParse;
  pSubParse->db = db;
  pSubParse->pTriggerTab = pTab;
  pSubParse->pToplevel = pTop;
  pSubParse->zAuthContext = pTrigger->zName;
  pSubParse->eTriggerOp = pTrigger->op;
  pSubParse->nQueryLoop = pParse->nQueryLoop;


  v = sqlite3GetVdbe(pSubParse);
  if( v ){
    VdbeComment((v, "Start: %s.%s (%s %s%s%s ON %s)", 
      pTrigger->zName, onErrorText(orconf),
      (pTrigger->tr_tm==TRIGGER_BEFORE ? "BEFORE" : "AFTER"),
        (pTrigger->op==TK_UPDATE ? "UPDATE" : ""),







>







912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
  sNC.pParse = pSubParse;
  pSubParse->db = db;
  pSubParse->pTriggerTab = pTab;
  pSubParse->pToplevel = pTop;
  pSubParse->zAuthContext = pTrigger->zName;
  pSubParse->eTriggerOp = pTrigger->op;
  pSubParse->nQueryLoop = pParse->nQueryLoop;
  pSubParse->disableVtab = pParse->disableVtab;

  v = sqlite3GetVdbe(pSubParse);
  if( v ){
    VdbeComment((v, "Start: %s.%s (%s %s%s%s ON %s)", 
      pTrigger->zName, onErrorText(orconf),
      (pTrigger->tr_tm==TRIGGER_BEFORE ? "BEFORE" : "AFTER"),
        (pTrigger->op==TK_UPDATE ? "UPDATE" : ""),
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
    ** (or NULL) the sub-vdbe is immediately halted by jumping to the 
    ** OP_Halt inserted at the end of the program.  */
    if( pTrigger->pWhen ){
      pWhen = sqlite3ExprDup(db, pTrigger->pWhen, 0);
      if( SQLITE_OK==sqlite3ResolveExprNames(&sNC, pWhen) 
       && db->mallocFailed==0 
      ){
        iEndTrigger = sqlite3VdbeMakeLabel(v);
        sqlite3ExprIfFalse(pSubParse, pWhen, iEndTrigger, SQLITE_JUMPIFNULL);
      }
      sqlite3ExprDelete(db, pWhen);
    }

    /* Code the trigger program into the sub-vdbe. */
    codeTriggerProgram(pSubParse, pTrigger->step_list, orconf);







|







940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
    ** (or NULL) the sub-vdbe is immediately halted by jumping to the 
    ** OP_Halt inserted at the end of the program.  */
    if( pTrigger->pWhen ){
      pWhen = sqlite3ExprDup(db, pTrigger->pWhen, 0);
      if( SQLITE_OK==sqlite3ResolveExprNames(&sNC, pWhen) 
       && db->mallocFailed==0 
      ){
        iEndTrigger = sqlite3VdbeMakeLabel(pSubParse);
        sqlite3ExprIfFalse(pSubParse, pWhen, iEndTrigger, SQLITE_JUMPIFNULL);
      }
      sqlite3ExprDelete(db, pWhen);
    }

    /* Code the trigger program into the sub-vdbe. */
    codeTriggerProgram(pSubParse, pTrigger->step_list, orconf);
Changes to src/update.c.
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
    updateVirtualTable(pParse, pTabList, pTab, pChanges, pRowidExpr, aXRef,
                       pWhere, onError);
    goto update_cleanup;
  }
#endif

  /* Jump to labelBreak to abandon further processing of this UPDATE */
  labelContinue = labelBreak = sqlite3VdbeMakeLabel(v);

  /* Not an UPSERT.  Normal processing.  Begin by
  ** initialize the count of updated rows */
  if( (db->flags&SQLITE_CountRows)!=0
   && !pParse->pTriggerTab
   && !pParse->nested
   && pUpsert==0







|







437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
    updateVirtualTable(pParse, pTabList, pTab, pChanges, pRowidExpr, aXRef,
                       pWhere, onError);
    goto update_cleanup;
  }
#endif

  /* Jump to labelBreak to abandon further processing of this UPDATE */
  labelContinue = labelBreak = sqlite3VdbeMakeLabel(pParse);

  /* Not an UPSERT.  Normal processing.  Begin by
  ** initialize the count of updated rows */
  if( (db->flags&SQLITE_CountRows)!=0
   && !pParse->pTriggerTab
   && !pParse->nested
   && pUpsert==0
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
    if( eOnePass!=ONEPASS_OFF ){
      if( !isView && aiCurOnePass[0]!=iDataCur && aiCurOnePass[1]!=iDataCur ){
        assert( pPk );
        sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelBreak, regKey,nKey);
        VdbeCoverage(v);
      }
      if( eOnePass!=ONEPASS_SINGLE ){
        labelContinue = sqlite3VdbeMakeLabel(v);
      }
      sqlite3VdbeAddOp2(v, OP_IsNull, pPk ? regKey : regOldRowid, labelBreak);
      VdbeCoverageIf(v, pPk==0);
      VdbeCoverageIf(v, pPk!=0);
    }else if( pPk ){
      labelContinue = sqlite3VdbeMakeLabel(v);
      sqlite3VdbeAddOp2(v, OP_Rewind, iEph, labelBreak); VdbeCoverage(v);
      addrTop = sqlite3VdbeAddOp2(v, OP_RowData, iEph, regKey);
      sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelContinue, regKey, 0);
      VdbeCoverage(v);
    }else{
      labelContinue = sqlite3VdbeAddOp3(v, OP_RowSetRead, regRowSet,labelBreak,
                               regOldRowid);







|





|







572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
    if( eOnePass!=ONEPASS_OFF ){
      if( !isView && aiCurOnePass[0]!=iDataCur && aiCurOnePass[1]!=iDataCur ){
        assert( pPk );
        sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelBreak, regKey,nKey);
        VdbeCoverage(v);
      }
      if( eOnePass!=ONEPASS_SINGLE ){
        labelContinue = sqlite3VdbeMakeLabel(pParse);
      }
      sqlite3VdbeAddOp2(v, OP_IsNull, pPk ? regKey : regOldRowid, labelBreak);
      VdbeCoverageIf(v, pPk==0);
      VdbeCoverageIf(v, pPk!=0);
    }else if( pPk ){
      labelContinue = sqlite3VdbeMakeLabel(pParse);
      sqlite3VdbeAddOp2(v, OP_Rewind, iEph, labelBreak); VdbeCoverage(v);
      addrTop = sqlite3VdbeAddOp2(v, OP_RowData, iEph, regKey);
      sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, labelContinue, regKey, 0);
      VdbeCoverage(v);
    }else{
      labelContinue = sqlite3VdbeAddOp3(v, OP_RowSetRead, regRowSet,labelBreak,
                               regOldRowid);
Changes to src/vacuum.c.
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
    ** legacy applications. */
    iDb = sqlite3FindDb(pParse->db, pNm);
    if( iDb<0 ) iDb = 0;
#endif
  }
  if( iDb!=1 ){
    int iIntoReg = 0;
    if( pInto ){
      iIntoReg = ++pParse->nMem;
      sqlite3ExprCode(pParse, pInto, iIntoReg);
    }
    sqlite3VdbeAddOp2(v, OP_Vacuum, iDb, iIntoReg);
    sqlite3VdbeUsesBtree(v, iDb);
  }
build_vacuum_end:







|







120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
    ** legacy applications. */
    iDb = sqlite3FindDb(pParse->db, pNm);
    if( iDb<0 ) iDb = 0;
#endif
  }
  if( iDb!=1 ){
    int iIntoReg = 0;
    if( pInto && sqlite3ResolveSelfReference(pParse,0,0,pInto,0)==0 ){
      iIntoReg = ++pParse->nMem;
      sqlite3ExprCode(pParse, pInto, iIntoReg);
    }
    sqlite3VdbeAddOp2(v, OP_Vacuum, iDb, iIntoReg);
    sqlite3VdbeUsesBtree(v, iDb);
  }
build_vacuum_end:
Changes to src/vdbe.c.
236
237
238
239
240
241
242





243
244
245
246
247
248
249
  VdbeCursor *pCx = 0;
  nByte = 
      ROUND8(sizeof(VdbeCursor)) + 2*sizeof(u32)*nField + 
      (eCurType==CURTYPE_BTREE?sqlite3BtreeCursorSize():0);

  assert( iCur>=0 && iCur<p->nCursor );
  if( p->apCsr[iCur] ){ /*OPTIMIZATION-IF-FALSE*/





    sqlite3VdbeFreeCursor(p, p->apCsr[iCur]);
    p->apCsr[iCur] = 0;
  }
  if( SQLITE_OK==sqlite3VdbeMemClearAndResize(pMem, nByte) ){
    p->apCsr[iCur] = pCx = (VdbeCursor*)pMem->z;
    memset(pCx, 0, offsetof(VdbeCursor,pAltCursor));
    pCx->eCurType = eCurType;







>
>
>
>
>







236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
  VdbeCursor *pCx = 0;
  nByte = 
      ROUND8(sizeof(VdbeCursor)) + 2*sizeof(u32)*nField + 
      (eCurType==CURTYPE_BTREE?sqlite3BtreeCursorSize():0);

  assert( iCur>=0 && iCur<p->nCursor );
  if( p->apCsr[iCur] ){ /*OPTIMIZATION-IF-FALSE*/
    /* Before calling sqlite3VdbeFreeCursor(), ensure the isEphemeral flag
    ** is clear. Otherwise, if this is an ephemeral cursor created by 
    ** OP_OpenDup, the cursor will not be closed and will still be part
    ** of a BtShared.pCursor list.  */
    p->apCsr[iCur]->isEphemeral = 0;
    sqlite3VdbeFreeCursor(p, p->apCsr[iCur]);
    p->apCsr[iCur] = 0;
  }
  if( SQLITE_OK==sqlite3VdbeMemClearAndResize(pMem, nByte) ){
    p->apCsr[iCur] = pCx = (VdbeCursor*)pMem->z;
    memset(pCx, 0, offsetof(VdbeCursor,pAltCursor));
    pCx->eCurType = eCurType;
1921
1922
1923
1924
1925
1926
1927
1928

1929
1930
1931
1932
1933
1934
1935
    if( pOp->p5 & SQLITE_NULLEQ ){
      /* If SQLITE_NULLEQ is set (which will only happen if the operator is
      ** OP_Eq or OP_Ne) then take the jump or not depending on whether
      ** or not both operands are null.
      */
      assert( pOp->opcode==OP_Eq || pOp->opcode==OP_Ne );
      assert( (flags1 & MEM_Cleared)==0 );
      assert( (pOp->p5 & SQLITE_JUMPIFNULL)==0 );

      if( (flags1&flags3&MEM_Null)!=0
       && (flags3&MEM_Cleared)==0
      ){
        res = 0;  /* Operands are equal */
      }else{
        res = 1;  /* Operands are not equal */
      }







|
>







1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
    if( pOp->p5 & SQLITE_NULLEQ ){
      /* If SQLITE_NULLEQ is set (which will only happen if the operator is
      ** OP_Eq or OP_Ne) then take the jump or not depending on whether
      ** or not both operands are null.
      */
      assert( pOp->opcode==OP_Eq || pOp->opcode==OP_Ne );
      assert( (flags1 & MEM_Cleared)==0 );
      assert( (pOp->p5 & SQLITE_JUMPIFNULL)==0 || CORRUPT_DB );
      testcase( (pOp->p5 & SQLITE_JUMPIFNULL)!=0 );
      if( (flags1&flags3&MEM_Null)!=0
       && (flags3&MEM_Cleared)==0
      ){
        res = 0;  /* Operands are equal */
      }else{
        res = 1;  /* Operands are not equal */
      }
3636
3637
3638
3639
3640
3641
3642

3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659



3660
3661
3662
3663
3664
3665
3666

  pCx = allocateCursor(p, pOp->p1, pOrig->nField, -1, CURTYPE_BTREE);
  if( pCx==0 ) goto no_mem;
  pCx->nullRow = 1;
  pCx->isEphemeral = 1;
  pCx->pKeyInfo = pOrig->pKeyInfo;
  pCx->isTable = pOrig->isTable;

  rc = sqlite3BtreeCursor(pOrig->pBtx, MASTER_ROOT, BTREE_WRCSR,
                          pCx->pKeyInfo, pCx->uc.pCursor);
  /* The sqlite3BtreeCursor() routine can only fail for the first cursor
  ** opened for a database.  Since there is already an open cursor when this
  ** opcode is run, the sqlite3BtreeCursor() cannot fail */
  assert( rc==SQLITE_OK );
  break;
}


/* Opcode: OpenEphemeral P1 P2 * P4 P5
** Synopsis: nColumn=P2
**
** Open a new cursor P1 to a transient table.
** The cursor is always opened read/write even if 
** the main database is read-only.  The ephemeral
** table is deleted automatically when the cursor is closed.



**
** P2 is the number of columns in the ephemeral table.
** The cursor points to a BTree table if P4==0 and to a BTree index
** if P4 is not 0.  If P4 is not NULL, it points to a KeyInfo structure
** that defines the format of keys in the index.
**
** The P5 parameter can be a mask of the BTREE_* flags defined







>
|
















>
>
>







3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676

  pCx = allocateCursor(p, pOp->p1, pOrig->nField, -1, CURTYPE_BTREE);
  if( pCx==0 ) goto no_mem;
  pCx->nullRow = 1;
  pCx->isEphemeral = 1;
  pCx->pKeyInfo = pOrig->pKeyInfo;
  pCx->isTable = pOrig->isTable;
  pCx->pgnoRoot = pOrig->pgnoRoot;
  rc = sqlite3BtreeCursor(pOrig->pBtx, pCx->pgnoRoot, BTREE_WRCSR,
                          pCx->pKeyInfo, pCx->uc.pCursor);
  /* The sqlite3BtreeCursor() routine can only fail for the first cursor
  ** opened for a database.  Since there is already an open cursor when this
  ** opcode is run, the sqlite3BtreeCursor() cannot fail */
  assert( rc==SQLITE_OK );
  break;
}


/* Opcode: OpenEphemeral P1 P2 * P4 P5
** Synopsis: nColumn=P2
**
** Open a new cursor P1 to a transient table.
** The cursor is always opened read/write even if 
** the main database is read-only.  The ephemeral
** table is deleted automatically when the cursor is closed.
**
** If the cursor P1 is already opened on an ephermal table, the table
** is cleared (all content is erased).
**
** P2 is the number of columns in the ephemeral table.
** The cursor points to a BTree table if P4==0 and to a BTree index
** if P4 is not 0.  If P4 is not NULL, it points to a KeyInfo structure
** that defines the format of keys in the index.
**
** The P5 parameter can be a mask of the BTREE_* flags defined
3685
3686
3687
3688
3689
3690
3691






3692
3693
3694
3695
3696
3697

3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710

3711
3712
3713
3714
3715
3716
3717
3718
3719

3720
3721
3722
3723
3724
3725
3726


3727
3728
3729
3730
3731
3732
3733
      SQLITE_OPEN_READWRITE |
      SQLITE_OPEN_CREATE |
      SQLITE_OPEN_EXCLUSIVE |
      SQLITE_OPEN_DELETEONCLOSE |
      SQLITE_OPEN_TRANSIENT_DB;
  assert( pOp->p1>=0 );
  assert( pOp->p2>=0 );






  pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, CURTYPE_BTREE);
  if( pCx==0 ) goto no_mem;
  pCx->nullRow = 1;
  pCx->isEphemeral = 1;
  rc = sqlite3BtreeOpen(db->pVfs, 0, db, &pCx->pBtx, 
                        BTREE_OMIT_JOURNAL | BTREE_SINGLE | pOp->p5, vfsFlags);

  if( rc==SQLITE_OK ){
    rc = sqlite3BtreeBeginTrans(pCx->pBtx, 1, 0);
  }
  if( rc==SQLITE_OK ){
    /* If a transient index is required, create it by calling
    ** sqlite3BtreeCreateTable() with the BTREE_BLOBKEY flag before
    ** opening it. If a transient table is required, just use the
    ** automatically created table with root-page 1 (an BLOB_INTKEY table).
    */
    if( (pCx->pKeyInfo = pKeyInfo = pOp->p4.pKeyInfo)!=0 ){
      int pgno;
      assert( pOp->p4type==P4_KEYINFO );
      rc = sqlite3BtreeCreateTable(pCx->pBtx, &pgno, BTREE_BLOBKEY | pOp->p5); 

      if( rc==SQLITE_OK ){
        assert( pgno==MASTER_ROOT+1 );
        assert( pKeyInfo->db==db );
        assert( pKeyInfo->enc==ENC(db) );
        rc = sqlite3BtreeCursor(pCx->pBtx, pgno, BTREE_WRCSR,
                                pKeyInfo, pCx->uc.pCursor);
      }
      pCx->isTable = 0;
    }else{

      rc = sqlite3BtreeCursor(pCx->pBtx, MASTER_ROOT, BTREE_WRCSR,
                              0, pCx->uc.pCursor);
      pCx->isTable = 1;
    }
  }
  if( rc ) goto abort_due_to_error;
  pCx->isOrdered = (pOp->p5!=BTREE_UNORDERED);


  break;
}

/* Opcode: SorterOpen P1 P2 P3 P4 *
**
** This opcode works like OP_OpenEphemeral except that it opens
** a transient index that is specifically designed to sort large







>
>
>
>
>
>
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
|
|
<
|
|
>
|
|
|
|
|
|
|
|
|
>
|
|
|
|
|
<
|
>
>







3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724

3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742

3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
      SQLITE_OPEN_READWRITE |
      SQLITE_OPEN_CREATE |
      SQLITE_OPEN_EXCLUSIVE |
      SQLITE_OPEN_DELETEONCLOSE |
      SQLITE_OPEN_TRANSIENT_DB;
  assert( pOp->p1>=0 );
  assert( pOp->p2>=0 );
  pCx = p->apCsr[pOp->p1];
  if( pCx ){
    /* If the ephermeral table is already open, erase all existing content
    ** so that the table is empty again, rather than creating a new table. */
    rc = sqlite3BtreeClearTable(pCx->pBtx, pCx->pgnoRoot, 0);
  }else{
    pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, CURTYPE_BTREE);
    if( pCx==0 ) goto no_mem;
    pCx->nullRow = 1;
    pCx->isEphemeral = 1;
    rc = sqlite3BtreeOpen(db->pVfs, 0, db, &pCx->pBtx, 
                          BTREE_OMIT_JOURNAL | BTREE_SINGLE | pOp->p5,
                          vfsFlags);
    if( rc==SQLITE_OK ){
      rc = sqlite3BtreeBeginTrans(pCx->pBtx, 1, 0);
    }
    if( rc==SQLITE_OK ){
      /* If a transient index is required, create it by calling
      ** sqlite3BtreeCreateTable() with the BTREE_BLOBKEY flag before
      ** opening it. If a transient table is required, just use the
      ** automatically created table with root-page 1 (an BLOB_INTKEY table).
      */
      if( (pCx->pKeyInfo = pKeyInfo = pOp->p4.pKeyInfo)!=0 ){

        assert( pOp->p4type==P4_KEYINFO );
        rc = sqlite3BtreeCreateTable(pCx->pBtx, (int*)&pCx->pgnoRoot,
                                     BTREE_BLOBKEY | pOp->p5); 
        if( rc==SQLITE_OK ){
          assert( pCx->pgnoRoot==MASTER_ROOT+1 );
          assert( pKeyInfo->db==db );
          assert( pKeyInfo->enc==ENC(db) );
          rc = sqlite3BtreeCursor(pCx->pBtx, pCx->pgnoRoot, BTREE_WRCSR,
                                  pKeyInfo, pCx->uc.pCursor);
        }
        pCx->isTable = 0;
      }else{
        pCx->pgnoRoot = MASTER_ROOT;
        rc = sqlite3BtreeCursor(pCx->pBtx, MASTER_ROOT, BTREE_WRCSR,
                                0, pCx->uc.pCursor);
        pCx->isTable = 1;
      }
    }

    pCx->isOrdered = (pOp->p5!=BTREE_UNORDERED);
  }
  if( rc ) goto abort_due_to_error;
  break;
}

/* Opcode: SorterOpen P1 P2 P3 P4 *
**
** This opcode works like OP_OpenEphemeral except that it opens
** a transient index that is specifically designed to sort large
4369
4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
case OP_NotExists:          /* jump, in3 */
  pIn3 = &aMem[pOp->p3];
  assert( (pIn3->flags & MEM_Int)!=0 || pOp->opcode==OP_SeekRowid );
  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  pC = p->apCsr[pOp->p1];
  assert( pC!=0 );
#ifdef SQLITE_DEBUG
  pC->seekOp = OP_SeekRowid;
#endif
  assert( pC->isTable );
  assert( pC->eCurType==CURTYPE_BTREE );
  pCrsr = pC->uc.pCursor;
  assert( pCrsr!=0 );
  res = 0;
  iKey = pIn3->u.i;







|







4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
case OP_NotExists:          /* jump, in3 */
  pIn3 = &aMem[pOp->p3];
  assert( (pIn3->flags & MEM_Int)!=0 || pOp->opcode==OP_SeekRowid );
  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  pC = p->apCsr[pOp->p1];
  assert( pC!=0 );
#ifdef SQLITE_DEBUG
  if( pOp->opcode==OP_SeekRowid ) pC->seekOp = OP_SeekRowid;
#endif
  assert( pC->isTable );
  assert( pC->eCurType==CURTYPE_BTREE );
  pCrsr = pC->uc.pCursor;
  assert( pCrsr!=0 );
  res = 0;
  iKey = pIn3->u.i;
5277
5278
5279
5280
5281
5282
5283
5284
5285
5286
5287
5288
5289
5290
5291
  assert( pOp->opcode!=OP_Prev || pOp->p4.xAdvance==sqlite3BtreePrevious );

  /* The Next opcode is only used after SeekGT, SeekGE, Rewind, and Found.
  ** The Prev opcode is only used after SeekLT, SeekLE, and Last. */
  assert( pOp->opcode!=OP_Next
       || pC->seekOp==OP_SeekGT || pC->seekOp==OP_SeekGE
       || pC->seekOp==OP_Rewind || pC->seekOp==OP_Found 
       || pC->seekOp==OP_NullRow);
  assert( pOp->opcode!=OP_Prev
       || pC->seekOp==OP_SeekLT || pC->seekOp==OP_SeekLE
       || pC->seekOp==OP_Last 
       || pC->seekOp==OP_NullRow);

  rc = pOp->p4.xAdvance(pC->uc.pCursor, pOp->p3);
next_tail:







|







5296
5297
5298
5299
5300
5301
5302
5303
5304
5305
5306
5307
5308
5309
5310
  assert( pOp->opcode!=OP_Prev || pOp->p4.xAdvance==sqlite3BtreePrevious );

  /* The Next opcode is only used after SeekGT, SeekGE, Rewind, and Found.
  ** The Prev opcode is only used after SeekLT, SeekLE, and Last. */
  assert( pOp->opcode!=OP_Next
       || pC->seekOp==OP_SeekGT || pC->seekOp==OP_SeekGE
       || pC->seekOp==OP_Rewind || pC->seekOp==OP_Found 
       || pC->seekOp==OP_NullRow|| pC->seekOp==OP_SeekRowid);
  assert( pOp->opcode!=OP_Prev
       || pC->seekOp==OP_SeekLT || pC->seekOp==OP_SeekLE
       || pC->seekOp==OP_Last 
       || pC->seekOp==OP_NullRow);

  rc = pOp->p4.xAdvance(pC->uc.pCursor, pOp->p3);
next_tail:
6883
6884
6885
6886
6887
6888
6889

6890
6891
6892
6893
6894
6895
6896
** 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 *







>







6902
6903
6904
6905
6906
6907
6908
6909
6910
6911
6912
6913
6914
6915
6916
** 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/vdbe.h.
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
#   define COLNAME_N      1      /* Store only the name */
# else
#   define COLNAME_N      2      /* Store the name and decltype */
# endif
#endif

/*
** The following macro converts a relative address in the p2 field
** of a VdbeOp structure into a negative number so that 
** sqlite3VdbeAddOpList() knows that the address is relative.  Calling
** the macro again restores the address.
*/
#define ADDR(X)  (-1-(X))

/*
** The makefile scans the vdbe.c source file and creates the "opcodes.h"
** header file that defines a number for each opcode used by the VDBE.
*/
#include "opcodes.h"








|
|
<
|

|







152
153
154
155
156
157
158
159
160

161
162
163
164
165
166
167
168
169
170
#   define COLNAME_N      1      /* Store only the name */
# else
#   define COLNAME_N      2      /* Store the name and decltype */
# endif
#endif

/*
** The following macro converts a label returned by sqlite3VdbeMakeLabel()
** into an index into the Parse.aLabel[] array that contains the resolved

** address of that label.
*/
#define ADDR(X)  (~(X))

/*
** The makefile scans the vdbe.c source file and creates the "opcodes.h"
** header file that defines a number for each opcode used by the VDBE.
*/
#include "opcodes.h"

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
# define ExplainQueryPlan(P)        sqlite3VdbeExplain P
# define ExplainQueryPlanPop(P)     sqlite3VdbeExplainPop(P)
# define ExplainQueryPlanParent(P)  sqlite3VdbeExplainParent(P)
#else
# define ExplainQueryPlan(P)
# define ExplainQueryPlanPop(P)
# define ExplainQueryPlanParent(P) 0






#endif
void sqlite3VdbeAddParseSchemaOp(Vdbe*,int,char*);
void sqlite3VdbeChangeOpcode(Vdbe*, u32 addr, u8);
void sqlite3VdbeChangeP1(Vdbe*, u32 addr, int P1);
void sqlite3VdbeChangeP2(Vdbe*, u32 addr, int P2);
void sqlite3VdbeChangeP3(Vdbe*, u32 addr, int P3);
void sqlite3VdbeChangeP5(Vdbe*, u16 P5);
void sqlite3VdbeJumpHere(Vdbe*, int addr);
int sqlite3VdbeChangeToNoop(Vdbe*, int addr);
int sqlite3VdbeDeletePriorOpcode(Vdbe*, u8 op);
void sqlite3VdbeChangeP4(Vdbe*, int addr, const char *zP4, int N);
void sqlite3VdbeAppendP4(Vdbe*, void *pP4, int p4type);
void sqlite3VdbeSetP4KeyInfo(Parse*, Index*);
void sqlite3VdbeUsesBtree(Vdbe*, int);
VdbeOp *sqlite3VdbeGetOp(Vdbe*, int);
int sqlite3VdbeMakeLabel(Vdbe*);
void sqlite3VdbeRunOnlyOnce(Vdbe*);
void sqlite3VdbeReusable(Vdbe*);
void sqlite3VdbeDelete(Vdbe*);
void sqlite3VdbeClearObject(sqlite3*,Vdbe*);
void sqlite3VdbeMakeReady(Vdbe*,Parse*);
int sqlite3VdbeFinalize(Vdbe*);
void sqlite3VdbeResolveLabel(Vdbe*, int);







>
>
>
>
>
>















|







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
# define ExplainQueryPlan(P)        sqlite3VdbeExplain P
# define ExplainQueryPlanPop(P)     sqlite3VdbeExplainPop(P)
# define ExplainQueryPlanParent(P)  sqlite3VdbeExplainParent(P)
#else
# define ExplainQueryPlan(P)
# define ExplainQueryPlanPop(P)
# define ExplainQueryPlanParent(P) 0
# define sqlite3ExplainBreakpoint(A,B) /*no-op*/
#endif
#if defined(SQLITE_DEBUG) && !defined(SQLITE_OMIT_EXPLAIN)
  void sqlite3ExplainBreakpoint(const char*,const char*);
#else
# define sqlite3ExplainBreakpoint(A,B) /*no-op*/
#endif
void sqlite3VdbeAddParseSchemaOp(Vdbe*,int,char*);
void sqlite3VdbeChangeOpcode(Vdbe*, u32 addr, u8);
void sqlite3VdbeChangeP1(Vdbe*, u32 addr, int P1);
void sqlite3VdbeChangeP2(Vdbe*, u32 addr, int P2);
void sqlite3VdbeChangeP3(Vdbe*, u32 addr, int P3);
void sqlite3VdbeChangeP5(Vdbe*, u16 P5);
void sqlite3VdbeJumpHere(Vdbe*, int addr);
int sqlite3VdbeChangeToNoop(Vdbe*, int addr);
int sqlite3VdbeDeletePriorOpcode(Vdbe*, u8 op);
void sqlite3VdbeChangeP4(Vdbe*, int addr, const char *zP4, int N);
void sqlite3VdbeAppendP4(Vdbe*, void *pP4, int p4type);
void sqlite3VdbeSetP4KeyInfo(Parse*, Index*);
void sqlite3VdbeUsesBtree(Vdbe*, int);
VdbeOp *sqlite3VdbeGetOp(Vdbe*, int);
int sqlite3VdbeMakeLabel(Parse*);
void sqlite3VdbeRunOnlyOnce(Vdbe*);
void sqlite3VdbeReusable(Vdbe*);
void sqlite3VdbeDelete(Vdbe*);
void sqlite3VdbeClearObject(sqlite3*,Vdbe*);
void sqlite3VdbeMakeReady(Vdbe*,Parse*);
int sqlite3VdbeFinalize(Vdbe*);
void sqlite3VdbeResolveLabel(Vdbe*, int);
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
  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







|







32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
  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
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
174
175
176
177
178
179
180
181
182

/*
** 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;

  /* The SQLITE_TEST_REALLOC_STRESS compile-time option is designed to force
  ** 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







|















|

|










|



|







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
174
175
176
177
178
179
180
181
182

/*
** 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;

  /* The SQLITE_TEST_REALLOC_STRESS compile-time option is designed to force
  ** 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
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
**    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;







|

|









|







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
**    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;
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
  VdbeOp *pOp;
  if( pParse->addrExplain==0 ) return 0;
  pOp = sqlite3VdbeGetOp(pParse->pVdbe, pParse->addrExplain);
  return pOp->p2;
}

/*











** Add a new OP_Explain 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( pParse->explain==2 ){


    char *zMsg;
    Vdbe *v;
    va_list ap;
    int iThis;
    va_start(ap, zFmt);
    zMsg = sqlite3VMPrintf(pParse->db, zFmt, ap);
    va_end(ap);
    v = pParse->pVdbe;
    iThis = v->nOp;
    sqlite3VdbeAddOp4(v, OP_Explain, iThis, pParse->addrExplain, 0,
                      zMsg, P4_DYNAMIC);


    if( bPush) pParse->addrExplain = iThis;

  }
}

/*
** Pop the EXPLAIN QUERY PLAN stack one level.
*/
void sqlite3VdbeExplainPop(Parse *pParse){

  pParse->addrExplain = sqlite3VdbeExplainParent(pParse);
}
#endif /* SQLITE_OMIT_EXPLAIN */

/*
** Add an OP_ParseSchema opcode.  This routine is broken out from
** sqlite3VdbeAddOp4() since it needs to also needs to mark all btrees







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





>
>
>
|
>
>











>
>
|
>







>







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
  VdbeOp *pOp;
  if( pParse->addrExplain==0 ) return 0;
  pOp = sqlite3VdbeGetOp(pParse->pVdbe, pParse->addrExplain);
  return pOp->p2;
}

/*
** Set a debugger breakpoint on the following routine in order to
** monitor the EXPLAIN QUERY PLAN code generation.
*/
#if defined(SQLITE_DEBUG)
void sqlite3ExplainBreakpoint(const char *z1, const char *z2){
  (void)z1;
  (void)z2;
}
#endif

/*
** 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;
    va_start(ap, zFmt);
    zMsg = sqlite3VMPrintf(pParse->db, zFmt, ap);
    va_end(ap);
    v = pParse->pVdbe;
    iThis = v->nOp;
    sqlite3VdbeAddOp4(v, OP_Explain, iThis, pParse->addrExplain, 0,
                      zMsg, P4_DYNAMIC);
    sqlite3ExplainBreakpoint(bPush?"PUSH":"", sqlite3VdbeGetOp(v,-1)->p4.z);
    if( bPush){
      pParse->addrExplain = iThis;
    }
  }
}

/*
** Pop the EXPLAIN QUERY PLAN stack one level.
*/
void sqlite3VdbeExplainPop(Parse *pParse){
  sqlite3ExplainBreakpoint("POP", 0);
  pParse->addrExplain = sqlite3VdbeExplainParent(pParse);
}
#endif /* SQLITE_OMIT_EXPLAIN */

/*
** Add an OP_ParseSchema opcode.  This routine is broken out from
** sqlite3VdbeAddOp4() since it needs to also needs to mark all btrees
436
437
438
439
440
441
442


443

444








445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464















465
466
467
468
469
470
471
472
473
474
475
476



477
478
479
480
481
482
483
** the label is resolved to a specific address, the VDBE will scan
** through its operation list and change all values of P2 which match
** the label into the resolved address.
**
** The VDBE knows that a P2 value is a label because labels are
** always negative and P2 values are suppose to be non-negative.
** Hence, a negative P2 value is a label that has yet to be resolved.


**

** Zero is returned if a malloc() fails.








*/
int sqlite3VdbeMakeLabel(Vdbe *v){
  Parse *p = v->pParse;
  int i = p->nLabel++;
  assert( v->magic==VDBE_MAGIC_INIT );
  if( (i & (i-1))==0 ){
    p->aLabel = sqlite3DbReallocOrFree(p->db, p->aLabel, 
                                       (i*2+1)*sizeof(p->aLabel[0]));
  }
  if( p->aLabel ){
    p->aLabel[i] = -1;
  }
  return ADDR(i);
}

/*
** Resolve label "x" to be the address of the next instruction to
** be inserted.  The parameter "x" must have been obtained from
** a prior call to sqlite3VdbeMakeLabel().
*/















void sqlite3VdbeResolveLabel(Vdbe *v, int x){
  Parse *p = v->pParse;
  int j = ADDR(x);
  assert( v->magic==VDBE_MAGIC_INIT );
  assert( j<p->nLabel );
  assert( j>=0 );
  if( p->aLabel ){
#ifdef SQLITE_DEBUG
    if( p->db->flags & SQLITE_VdbeAddopTrace ){
      printf("RESOLVE LABEL %d to %d\n", x, v->nOp);
    }
#endif



    assert( p->aLabel[j]==(-1) ); /* Labels may only be resolved once */
    p->aLabel[j] = v->nOp;
  }
}

/*
** Mark the VDBE as one that can only be run one time.







>
>

>
|
>
>
>
>
>
>
>
>

|
<
|
<
<
<
<
<
<
<
<
<







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




|

<

|
|
|

>
>
>







456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477

478









479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506

507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
** the label is resolved to a specific address, the VDBE will scan
** through its operation list and change all values of P2 which match
** the label into the resolved address.
**
** The VDBE knows that a P2 value is a label because labels are
** always negative and P2 values are suppose to be non-negative.
** Hence, a negative P2 value is a label that has yet to be resolved.
** (Later:) This is only true for opcodes that have the OPFLG_JUMP
** property.
**
** Variable usage notes:
**
**     Parse.aLabel[x]     Stores the address that the x-th label resolves
**                         into.  For testing (SQLITE_DEBUG), unresolved
**                         labels stores -1, but that is not required.
**     Parse.nLabelAlloc   Number of slots allocated to Parse.aLabel[]
**     Parse.nLabel        The *negative* of the number of labels that have
**                         been issued.  The negative is stored because
**                         that gives a performance improvement over storing
**                         the equivalent positive value.
*/
int sqlite3VdbeMakeLabel(Parse *pParse){

  return --pParse->nLabel;









}

/*
** Resolve label "x" to be the address of the next instruction to
** be inserted.  The parameter "x" must have been obtained from
** a prior call to sqlite3VdbeMakeLabel().
*/
static SQLITE_NOINLINE void resizeResolveLabel(Parse *p, Vdbe *v, int j){
  int nNewSize = 10 - p->nLabel;
  p->aLabel = sqlite3DbReallocOrFree(p->db, p->aLabel,
                     nNewSize*sizeof(p->aLabel[0]));
  if( p->aLabel==0 ){
    p->nLabelAlloc = 0;
  }else{
#ifdef SQLITE_DEBUG
    int i;
    for(i=p->nLabelAlloc; i<nNewSize; i++) p->aLabel[i] = -1;
#endif
    p->nLabelAlloc = nNewSize;
    p->aLabel[j] = v->nOp;
  }
}
void sqlite3VdbeResolveLabel(Vdbe *v, int x){
  Parse *p = v->pParse;
  int j = ADDR(x);
  assert( v->magic==VDBE_MAGIC_INIT );
  assert( j<-p->nLabel );
  assert( j>=0 );

#ifdef SQLITE_DEBUG
  if( p->db->flags & SQLITE_VdbeAddopTrace ){
    printf("RESOLVE LABEL %d to %d\n", x, v->nOp);
  }
#endif
  if( p->nLabelAlloc + p->nLabel < 0 ){
    resizeResolveLabel(p,v,j);
  }else{
    assert( p->aLabel[j]==(-1) ); /* Labels may only be resolved once */
    p->aLabel[j] = v->nOp;
  }
}

/*
** Mark the VDBE as one that can only be run one time.
594
595
596
597
598
599
600

601
602
603
604
605
606
607
  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;







>







632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
  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;
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
#endif
        default: {
          if( pOp->p2<0 ){
            /* The mkopcodeh.tcl script has so arranged things that the only
            ** non-jump opcodes less than SQLITE_MX_JUMP_CODE are guaranteed to
            ** have non-negative values for P2. */
            assert( (sqlite3OpcodeProperty[pOp->opcode] & OPFLG_JUMP)!=0 );
            assert( ADDR(pOp->p2)<pParse->nLabel );
            pOp->p2 = aLabel[ADDR(pOp->p2)];
          }
          break;
        }
      }
      /* The mkopcodeh.tcl script has so arranged things that the only
      ** non-jump opcodes less than SQLITE_MX_JUMP_CODE are guaranteed to







|







783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
#endif
        default: {
          if( pOp->p2<0 ){
            /* The mkopcodeh.tcl script has so arranged things that the only
            ** non-jump opcodes less than SQLITE_MX_JUMP_CODE are guaranteed to
            ** have non-negative values for P2. */
            assert( (sqlite3OpcodeProperty[pOp->opcode] & OPFLG_JUMP)!=0 );
            assert( ADDR(pOp->p2)<-pParse->nLabel );
            pOp->p2 = aLabel[ADDR(pOp->p2)];
          }
          break;
        }
      }
      /* The mkopcodeh.tcl script has so arranged things that the only
      ** non-jump opcodes less than SQLITE_MX_JUMP_CODE are guaranteed to
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
** 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







|







822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
** 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
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
  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;







|







894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
  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;
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196









2197
2198
2199
2200
2201
2202
2203
  ** 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;







<
|
|
|
|
|

|

|


|
>
>
>
>
>
>
>
>
>







2216
2217
2218
2219
2220
2221
2222

2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
  ** 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 src/where.c.
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
    addrTop =  sqlite3VdbeAddOp1(v, OP_Yield, regYield);
    VdbeCoverage(v);
    VdbeComment((v, "next row of %s", pTabItem->pTab->zName));
  }else{
    addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, pLevel->iTabCur); VdbeCoverage(v);
  }
  if( pPartial ){
    iContinue = sqlite3VdbeMakeLabel(v);
    sqlite3ExprIfFalse(pParse, pPartial, iContinue, SQLITE_JUMPIFNULL);
    pLoop->wsFlags |= WHERE_PARTIALIDX;
  }
  regRecord = sqlite3GetTempReg(pParse);
  regBase = sqlite3GenerateIndexKey(
      pParse, pIdx, pLevel->iTabCur, regRecord, 0, 0, 0, 0
  );
  sqlite3VdbeAddOp2(v, OP_IdxInsert, pLevel->iIdxCur, regRecord);
  sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
  if( pPartial ) sqlite3VdbeResolveLabel(v, iContinue);
  if( pTabItem->fg.viaCoroutine ){
    sqlite3VdbeChangeP2(v, addrCounter, regBase+n);
    testcase( pParse->db->mallocFailed );
    translateColumnToCopy(pParse, addrTop, pLevel->iTabCur,
                          pTabItem->regResult, 1);
    sqlite3VdbeGoto(v, addrTop);

  }else{
    sqlite3VdbeAddOp2(v, OP_Next, pLevel->iTabCur, addrTop+1); VdbeCoverage(v);
  }
  sqlite3VdbeChangeP5(v, SQLITE_STMTSTATUS_AUTOINDEX);
  sqlite3VdbeJumpHere(v, addrTop);
  sqlite3ReleaseTempReg(pParse, regRecord);
  







|
















>







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
    addrTop =  sqlite3VdbeAddOp1(v, OP_Yield, regYield);
    VdbeCoverage(v);
    VdbeComment((v, "next row of %s", pTabItem->pTab->zName));
  }else{
    addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, pLevel->iTabCur); VdbeCoverage(v);
  }
  if( pPartial ){
    iContinue = sqlite3VdbeMakeLabel(pParse);
    sqlite3ExprIfFalse(pParse, pPartial, iContinue, SQLITE_JUMPIFNULL);
    pLoop->wsFlags |= WHERE_PARTIALIDX;
  }
  regRecord = sqlite3GetTempReg(pParse);
  regBase = sqlite3GenerateIndexKey(
      pParse, pIdx, pLevel->iTabCur, regRecord, 0, 0, 0, 0
  );
  sqlite3VdbeAddOp2(v, OP_IdxInsert, pLevel->iIdxCur, regRecord);
  sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
  if( pPartial ) sqlite3VdbeResolveLabel(v, iContinue);
  if( pTabItem->fg.viaCoroutine ){
    sqlite3VdbeChangeP2(v, addrCounter, regBase+n);
    testcase( pParse->db->mallocFailed );
    translateColumnToCopy(pParse, addrTop, pLevel->iTabCur,
                          pTabItem->regResult, 1);
    sqlite3VdbeGoto(v, addrTop);
    pTabItem->fg.viaCoroutine = 0;
  }else{
    sqlite3VdbeAddOp2(v, OP_Next, pLevel->iTabCur, addrTop+1); VdbeCoverage(v);
  }
  sqlite3VdbeChangeP5(v, SQLITE_STMTSTATUS_AUTOINDEX);
  sqlite3VdbeJumpHere(v, addrTop);
  sqlite3ReleaseTempReg(pParse, regRecord);
  
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
4649
4650
4651
4652
4653
  pWInfo->pParse = pParse;
  pWInfo->pTabList = pTabList;
  pWInfo->pOrderBy = pOrderBy;
  pWInfo->pWhere = pWhere;
  pWInfo->pResultSet = pResultSet;
  pWInfo->aiCurOnePass[0] = pWInfo->aiCurOnePass[1] = -1;
  pWInfo->nLevel = nTabList;
  pWInfo->iBreak = pWInfo->iContinue = sqlite3VdbeMakeLabel(v);
  pWInfo->wctrlFlags = wctrlFlags;
  pWInfo->iLimit = iAuxArg;
  pWInfo->savedNQueryLoop = pParse->nQueryLoop;
  memset(&pWInfo->nOBSat, 0, 
         offsetof(WhereInfo,sWC) - offsetof(WhereInfo,nOBSat));
  memset(&pWInfo->a[0], 0, sizeof(WhereLoop)+nTabList*sizeof(WhereLevel));
  assert( pWInfo->eOnePass==ONEPASS_OFF );  /* ONEPASS defaults to OFF */







|







4640
4641
4642
4643
4644
4645
4646
4647
4648
4649
4650
4651
4652
4653
4654
  pWInfo->pParse = pParse;
  pWInfo->pTabList = pTabList;
  pWInfo->pOrderBy = pOrderBy;
  pWInfo->pWhere = pWhere;
  pWInfo->pResultSet = pResultSet;
  pWInfo->aiCurOnePass[0] = pWInfo->aiCurOnePass[1] = -1;
  pWInfo->nLevel = nTabList;
  pWInfo->iBreak = pWInfo->iContinue = sqlite3VdbeMakeLabel(pParse);
  pWInfo->wctrlFlags = wctrlFlags;
  pWInfo->iLimit = iAuxArg;
  pWInfo->savedNQueryLoop = pParse->nQueryLoop;
  memset(&pWInfo->nOBSat, 0, 
         offsetof(WhereInfo,sWC) - offsetof(WhereInfo,nOBSat));
  memset(&pWInfo->a[0], 0, sizeof(WhereLoop)+nTabList*sizeof(WhereLevel));
  assert( pWInfo->eOnePass==ONEPASS_OFF );  /* ONEPASS defaults to OFF */
5070
5071
5072
5073
5074
5075
5076
5077
5078
5079
5080
5081
5082
5083
5084
      if( db->mallocFailed ) goto whereBeginError;
    }
#endif
    addrExplain = sqlite3WhereExplainOneScan(
        pParse, pTabList, pLevel, wctrlFlags
    );
    pLevel->addrBody = sqlite3VdbeCurrentAddr(v);
    notReady = sqlite3WhereCodeOneLoopStart(pWInfo, ii, notReady);
    pWInfo->iContinue = pLevel->addrCont;
    if( (wsFlags&WHERE_MULTI_OR)==0 && (wctrlFlags&WHERE_OR_SUBCLAUSE)==0 ){
      sqlite3WhereAddScanStatus(v, pTabList, pLevel, addrExplain);
    }
  }

  /* Done. */







|







5071
5072
5073
5074
5075
5076
5077
5078
5079
5080
5081
5082
5083
5084
5085
      if( db->mallocFailed ) goto whereBeginError;
    }
#endif
    addrExplain = sqlite3WhereExplainOneScan(
        pParse, pTabList, pLevel, wctrlFlags
    );
    pLevel->addrBody = sqlite3VdbeCurrentAddr(v);
    notReady = sqlite3WhereCodeOneLoopStart(pParse,v,pWInfo,ii,pLevel,notReady);
    pWInfo->iContinue = pLevel->addrCont;
    if( (wsFlags&WHERE_MULTI_OR)==0 && (wctrlFlags&WHERE_OR_SUBCLAUSE)==0 ){
      sqlite3WhereAddScanStatus(v, pTabList, pLevel, addrExplain);
    }
  }

  /* Done. */
Changes to src/whereInt.h.
503
504
505
506
507
508
509


510
511

512
513
514
515
516
517
518
  WhereLevel *pLvl,               /* Level to add scanstatus() entry for */
  int addrExplain                 /* Address of OP_Explain (or 0) */
);
#else
# define sqlite3WhereAddScanStatus(a, b, c, d) ((void)d)
#endif
Bitmask sqlite3WhereCodeOneLoopStart(


  WhereInfo *pWInfo,   /* Complete information about the WHERE clause */
  int iLevel,          /* Which level of pWInfo->a[] should be coded */

  Bitmask notReady     /* Which tables are currently available */
);

/* whereexpr.c: */
void sqlite3WhereClauseInit(WhereClause*,WhereInfo*);
void sqlite3WhereClauseClear(WhereClause*);
void sqlite3WhereSplit(WhereClause*,Expr*,u8);







>
>


>







503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
  WhereLevel *pLvl,               /* Level to add scanstatus() entry for */
  int addrExplain                 /* Address of OP_Explain (or 0) */
);
#else
# define sqlite3WhereAddScanStatus(a, b, c, d) ((void)d)
#endif
Bitmask sqlite3WhereCodeOneLoopStart(
  Parse *pParse,       /* Parsing context */
  Vdbe *v,             /* Prepared statement under construction */
  WhereInfo *pWInfo,   /* Complete information about the WHERE clause */
  int iLevel,          /* Which level of pWInfo->a[] should be coded */
  WhereLevel *pLevel,  /* The current level pointer */
  Bitmask notReady     /* Which tables are currently available */
);

/* whereexpr.c: */
void sqlite3WhereClauseInit(WhereClause*,WhereInfo*);
void sqlite3WhereClauseClear(WhereClause*);
void sqlite3WhereSplit(WhereClause*,Expr*,u8);
Changes to src/wherecode.c.
209
210
211
212
213
214
215

216
217
218
219
220
221
222
      sqlite3_str_appendf(&str, " (~%llu rows)",
             sqlite3LogEstToInt(pLoop->nOut));
    }else{
      sqlite3_str_append(&str, " (~1 row)", 9);
    }
#endif
    zMsg = sqlite3StrAccumFinish(&str);

    ret = sqlite3VdbeAddOp4(v, OP_Explain, sqlite3VdbeCurrentAddr(v),
                            pParse->addrExplain, 0, zMsg,P4_DYNAMIC);
  }
  return ret;
}
#endif /* SQLITE_OMIT_EXPLAIN */








>







209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
      sqlite3_str_appendf(&str, " (~%llu rows)",
             sqlite3LogEstToInt(pLoop->nOut));
    }else{
      sqlite3_str_append(&str, " (~1 row)", 9);
    }
#endif
    zMsg = sqlite3StrAccumFinish(&str);
    sqlite3ExplainBreakpoint("",zMsg);
    ret = sqlite3VdbeAddOp4(v, OP_Explain, sqlite3VdbeCurrentAddr(v),
                            pParse->addrExplain, 0, zMsg,P4_DYNAMIC);
  }
  return ret;
}
#endif /* SQLITE_OMIT_EXPLAIN */

534
535
536
537
538
539
540

541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
      }
    }
    for(i=iEq;i<pLoop->nLTerm; i++){
      assert( pLoop->aLTerm[i]!=0 );
      if( pLoop->aLTerm[i]->pExpr==pX ) nEq++;
    }


    if( (pX->flags & EP_xIsSelect)==0 || pX->x.pSelect->pEList->nExpr==1 ){
      eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, 0);
    }else{
      sqlite3 *db = pParse->db;
      pX = removeUnindexableInClauseTerms(pParse, iEq, pLoop, pX);

      if( !db->mallocFailed ){
        aiMap = (int*)sqlite3DbMallocZero(pParse->db, sizeof(int)*nEq);
        eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, aiMap);
        pTerm->pExpr->iTable = pX->iTable;
      }
      sqlite3ExprDelete(db, pX);
      pX = pTerm->pExpr;
    }

    if( eType==IN_INDEX_INDEX_DESC ){
      testcase( bRev );
      bRev = !bRev;
    }
    iTab = pX->iTable;
    sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iTab, 0);
    VdbeCoverageIf(v, bRev);
    VdbeCoverageIf(v, !bRev);
    assert( (pLoop->wsFlags & WHERE_MULTI_OR)==0 );

    pLoop->wsFlags |= WHERE_IN_ABLE;
    if( pLevel->u.in.nIn==0 ){
      pLevel->addrNxt = sqlite3VdbeMakeLabel(v);
    }

    i = pLevel->u.in.nIn;
    pLevel->u.in.nIn += nEq;
    pLevel->u.in.aInLoop =
       sqlite3DbReallocOrFree(pParse->db, pLevel->u.in.aInLoop,
                              sizeof(pLevel->u.in.aInLoop[0])*pLevel->u.in.nIn);







>

|






|
|









<







|







535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561

562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
      }
    }
    for(i=iEq;i<pLoop->nLTerm; i++){
      assert( pLoop->aLTerm[i]!=0 );
      if( pLoop->aLTerm[i]->pExpr==pX ) nEq++;
    }

    iTab = 0;
    if( (pX->flags & EP_xIsSelect)==0 || pX->x.pSelect->pEList->nExpr==1 ){
      eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, 0, &iTab);
    }else{
      sqlite3 *db = pParse->db;
      pX = removeUnindexableInClauseTerms(pParse, iEq, pLoop, pX);

      if( !db->mallocFailed ){
        aiMap = (int*)sqlite3DbMallocZero(pParse->db, sizeof(int)*nEq);
        eType = sqlite3FindInIndex(pParse, pX, IN_INDEX_LOOP, 0, aiMap, &iTab);
        pTerm->pExpr->iTable = iTab;
      }
      sqlite3ExprDelete(db, pX);
      pX = pTerm->pExpr;
    }

    if( eType==IN_INDEX_INDEX_DESC ){
      testcase( bRev );
      bRev = !bRev;
    }

    sqlite3VdbeAddOp2(v, bRev ? OP_Last : OP_Rewind, iTab, 0);
    VdbeCoverageIf(v, bRev);
    VdbeCoverageIf(v, !bRev);
    assert( (pLoop->wsFlags & WHERE_MULTI_OR)==0 );

    pLoop->wsFlags |= WHERE_IN_ABLE;
    if( pLevel->u.in.nIn==0 ){
      pLevel->addrNxt = sqlite3VdbeMakeLabel(pParse);
    }

    i = pLevel->u.in.nIn;
    pLevel->u.in.nIn += nEq;
    pLevel->u.in.aInLoop =
       sqlite3DbReallocOrFree(pParse->db, pLevel->u.in.aInLoop,
                              sizeof(pLevel->u.in.aInLoop[0])*pLevel->u.in.nIn);
1072
1073
1074
1075
1076
1077
1078


1079
1080
1081
1082
1083
1084
1085
1086
*/
static void codeExprOrVector(Parse *pParse, Expr *p, int iReg, int nReg){
  assert( nReg>0 );
  if( p && sqlite3ExprIsVector(p) ){
#ifndef SQLITE_OMIT_SUBQUERY
    if( (p->flags & EP_xIsSelect) ){
      Vdbe *v = pParse->pVdbe;


      int iSelect = sqlite3CodeSubselect(pParse, p, 0, 0);
      sqlite3VdbeAddOp3(v, OP_Copy, iSelect, iReg, nReg-1);
    }else
#endif
    {
      int i;
      ExprList *pList = p->x.pList;
      assert( nReg<=pList->nExpr );







>
>
|







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

/*
** Generate code for the start of the iLevel-th loop in the WHERE clause
** implementation described by pWInfo.
*/
Bitmask sqlite3WhereCodeOneLoopStart(


  WhereInfo *pWInfo,   /* Complete information about the WHERE clause */
  int iLevel,          /* Which level of pWInfo->a[] should be coded */

  Bitmask notReady     /* Which tables are currently available */
){
  int j, k;            /* Loop counters */
  int iCur;            /* The VDBE cursor for the table */
  int addrNxt;         /* Where to jump to continue with the next IN case */
  int omitTable;       /* True if we use the index only */
  int bRev;            /* True if we need to scan in reverse order */
  WhereLevel *pLevel;  /* The where level to be coded */
  WhereLoop *pLoop;    /* The WhereLoop object being coded */
  WhereClause *pWC;    /* Decomposition of the entire WHERE clause */
  WhereTerm *pTerm;               /* A WHERE clause term */
  Parse *pParse;                  /* Parsing context */
  sqlite3 *db;                    /* Database connection */
  Vdbe *v;                        /* The prepared stmt under constructions */
  struct SrcList_item *pTabItem;  /* FROM clause term being coded */
  int addrBrk;                    /* Jump here to break out of the loop */
  int addrHalt;                   /* addrBrk for the outermost loop */
  int addrCont;                   /* Jump here to continue with next cycle */
  int iRowidReg = 0;        /* Rowid is stored in this register, if not zero */
  int iReleaseReg = 0;      /* Temp register to free before returning */
  Index *pIdx = 0;          /* Index used by loop (if any) */
  int iLoop;                /* Iteration of constraint generator loop */

  pParse = pWInfo->pParse;
  v = pParse->pVdbe;
  pWC = &pWInfo->sWC;
  db = pParse->db;
  pLevel = &pWInfo->a[iLevel];
  pLoop = pLevel->pWLoop;
  pTabItem = &pWInfo->pTabList->a[pLevel->iFrom];
  iCur = pTabItem->iCursor;
  pLevel->notReady = notReady & ~sqlite3WhereGetMask(&pWInfo->sMaskSet, iCur);
  bRev = (pWInfo->revMask>>iLevel)&1;
  omitTable = (pLoop->wsFlags & WHERE_IDX_ONLY)!=0 
           && (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)==0;
  VdbeModuleComment((v, "Begin WHERE-loop%d: %s",iLevel,pTabItem->pTab->zName));

  /* Create labels for the "break" and "continue" instructions
  ** for the current loop.  Jump to addrBrk to break out of a loop.
  ** Jump to cont to go immediately to the next iteration of the
  ** loop.
  **
  ** When there is an IN operator, we also have a "addrNxt" label that
  ** means to continue with the next IN value combination.  When
  ** there are no IN operators in the constraints, the "addrNxt" label
  ** is the same as "addrBrk".
  */
  addrBrk = pLevel->addrBrk = pLevel->addrNxt = sqlite3VdbeMakeLabel(v);
  addrCont = pLevel->addrCont = sqlite3VdbeMakeLabel(v);

  /* If this is the right table of a LEFT OUTER JOIN, allocate and
  ** initialize a memory cell that records if this table matches any
  ** row of the left table of the join.
  */
  assert( (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)
       || pLevel->iFrom>0 || (pTabItem[0].fg.jointype & JT_LEFT)==0







>
>


>





<

<



<

<









<
<


<





<
<












|
|







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
}

/*
** Generate code for the start of the iLevel-th loop in the WHERE clause
** implementation described by pWInfo.
*/
Bitmask sqlite3WhereCodeOneLoopStart(
  Parse *pParse,       /* Parsing context */
  Vdbe *v,             /* Prepared statement under construction */
  WhereInfo *pWInfo,   /* Complete information about the WHERE clause */
  int iLevel,          /* Which level of pWInfo->a[] should be coded */
  WhereLevel *pLevel,  /* The current level pointer */
  Bitmask notReady     /* Which tables are currently available */
){
  int j, k;            /* Loop counters */
  int iCur;            /* The VDBE cursor for the table */
  int addrNxt;         /* Where to jump to continue with the next IN case */

  int bRev;            /* True if we need to scan in reverse order */

  WhereLoop *pLoop;    /* The WhereLoop object being coded */
  WhereClause *pWC;    /* Decomposition of the entire WHERE clause */
  WhereTerm *pTerm;               /* A WHERE clause term */

  sqlite3 *db;                    /* Database connection */

  struct SrcList_item *pTabItem;  /* FROM clause term being coded */
  int addrBrk;                    /* Jump here to break out of the loop */
  int addrHalt;                   /* addrBrk for the outermost loop */
  int addrCont;                   /* Jump here to continue with next cycle */
  int iRowidReg = 0;        /* Rowid is stored in this register, if not zero */
  int iReleaseReg = 0;      /* Temp register to free before returning */
  Index *pIdx = 0;          /* Index used by loop (if any) */
  int iLoop;                /* Iteration of constraint generator loop */



  pWC = &pWInfo->sWC;
  db = pParse->db;

  pLoop = pLevel->pWLoop;
  pTabItem = &pWInfo->pTabList->a[pLevel->iFrom];
  iCur = pTabItem->iCursor;
  pLevel->notReady = notReady & ~sqlite3WhereGetMask(&pWInfo->sMaskSet, iCur);
  bRev = (pWInfo->revMask>>iLevel)&1;


  VdbeModuleComment((v, "Begin WHERE-loop%d: %s",iLevel,pTabItem->pTab->zName));

  /* Create labels for the "break" and "continue" instructions
  ** for the current loop.  Jump to addrBrk to break out of a loop.
  ** Jump to cont to go immediately to the next iteration of the
  ** loop.
  **
  ** When there is an IN operator, we also have a "addrNxt" label that
  ** means to continue with the next IN value combination.  When
  ** there are no IN operators in the constraints, the "addrNxt" label
  ** is the same as "addrBrk".
  */
  addrBrk = pLevel->addrBrk = pLevel->addrNxt = sqlite3VdbeMakeLabel(pParse);
  addrCont = pLevel->addrCont = sqlite3VdbeMakeLabel(pParse);

  /* If this is the right table of a LEFT OUTER JOIN, allocate and
  ** initialize a memory cell that records if this table matches any
  ** row of the left table of the join.
  */
  assert( (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)
       || pLevel->iFrom>0 || (pTabItem[0].fg.jointype & JT_LEFT)==0
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
    **          we reference multiple rows using a "rowid IN (...)"
    **          construct.
    */
    assert( pLoop->u.btree.nEq==1 );
    pTerm = pLoop->aLTerm[0];
    assert( pTerm!=0 );
    assert( pTerm->pExpr!=0 );
    assert( omitTable==0 );
    testcase( pTerm->wtFlags & TERM_VIRTUAL );
    iReleaseReg = ++pParse->nMem;
    iRowidReg = codeEqualityTerm(pParse, pTerm, pLevel, 0, bRev, iReleaseReg);
    if( iRowidReg!=iReleaseReg ) sqlite3ReleaseTempReg(pParse, iReleaseReg);
    addrNxt = pLevel->addrNxt;
    sqlite3VdbeAddOp3(v, OP_SeekRowid, iCur, addrNxt, iRowidReg);
    VdbeCoverage(v);
    pLevel->op = OP_Noop;
  }else if( (pLoop->wsFlags & WHERE_IPK)!=0
         && (pLoop->wsFlags & WHERE_COLUMN_RANGE)!=0
  ){
    /* Case 3:  We have an inequality comparison against the ROWID field.
    */
    int testOp = OP_Noop;
    int start;
    int memEndValue = 0;
    WhereTerm *pStart, *pEnd;

    assert( omitTable==0 );
    j = 0;
    pStart = pEnd = 0;
    if( pLoop->wsFlags & WHERE_BTM_LIMIT ) pStart = pLoop->aLTerm[j++];
    if( pLoop->wsFlags & WHERE_TOP_LIMIT ) pEnd = pLoop->aLTerm[j++];
    assert( pStart!=0 || pEnd!=0 );
    if( bRev ){
      pTerm = pStart;







<


















<







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
    **          we reference multiple rows using a "rowid IN (...)"
    **          construct.
    */
    assert( pLoop->u.btree.nEq==1 );
    pTerm = pLoop->aLTerm[0];
    assert( pTerm!=0 );
    assert( pTerm->pExpr!=0 );

    testcase( pTerm->wtFlags & TERM_VIRTUAL );
    iReleaseReg = ++pParse->nMem;
    iRowidReg = codeEqualityTerm(pParse, pTerm, pLevel, 0, bRev, iReleaseReg);
    if( iRowidReg!=iReleaseReg ) sqlite3ReleaseTempReg(pParse, iReleaseReg);
    addrNxt = pLevel->addrNxt;
    sqlite3VdbeAddOp3(v, OP_SeekRowid, iCur, addrNxt, iRowidReg);
    VdbeCoverage(v);
    pLevel->op = OP_Noop;
  }else if( (pLoop->wsFlags & WHERE_IPK)!=0
         && (pLoop->wsFlags & WHERE_COLUMN_RANGE)!=0
  ){
    /* Case 3:  We have an inequality comparison against the ROWID field.
    */
    int testOp = OP_Noop;
    int start;
    int memEndValue = 0;
    WhereTerm *pStart, *pEnd;


    j = 0;
    pStart = pEnd = 0;
    if( pLoop->wsFlags & WHERE_BTM_LIMIT ) pStart = pLoop->aLTerm[j++];
    if( pLoop->wsFlags & WHERE_TOP_LIMIT ) pEnd = pLoop->aLTerm[j++];
    assert( pStart!=0 || pEnd!=0 );
    if( bRev ){
      pTerm = pStart;
1518
1519
1520
1521
1522
1523
1524


1525
1526
1527
1528
1529
1530
1531
    int iIdxCur;                 /* The VDBE cursor for the index */
    int nExtraReg = 0;           /* Number of extra registers needed */
    int op;                      /* Instruction opcode */
    char *zStartAff;             /* Affinity for start of range constraint */
    char *zEndAff = 0;           /* Affinity for end of range constraint */
    u8 bSeekPastNull = 0;        /* True to seek past initial nulls */
    u8 bStopAtNull = 0;          /* Add condition to terminate at NULLs */



    pIdx = pLoop->u.btree.pIndex;
    iIdxCur = pLevel->iIdxCur;
    assert( nEq>=pLoop->nSkip );

    /* If this loop satisfies a sort order (pOrderBy) request that 
    ** was passed to this function to implement a "SELECT min(x) ..." 







>
>







1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
    int iIdxCur;                 /* The VDBE cursor for the index */
    int nExtraReg = 0;           /* Number of extra registers needed */
    int op;                      /* Instruction opcode */
    char *zStartAff;             /* Affinity for start of range constraint */
    char *zEndAff = 0;           /* Affinity for end of range constraint */
    u8 bSeekPastNull = 0;        /* True to seek past initial nulls */
    u8 bStopAtNull = 0;          /* Add condition to terminate at NULLs */
    int omitTable;               /* True if we use the index only */


    pIdx = pLoop->u.btree.pIndex;
    iIdxCur = pLevel->iIdxCur;
    assert( nEq>=pLoop->nSkip );

    /* If this loop satisfies a sort order (pOrderBy) request that 
    ** was passed to this function to implement a "SELECT min(x) ..." 
1719
1720
1721
1722
1723
1724
1725


1726
1727
1728
1729
1730
1731
1732
    }

    if( pLoop->wsFlags & WHERE_IN_EARLYOUT ){
      sqlite3VdbeAddOp2(v, OP_SeekHit, iIdxCur, 1);
    }

    /* Seek the table cursor, if required */


    if( omitTable ){
      /* pIdx is a covering index.  No need to access the main table. */
    }else if( HasRowid(pIdx->pTable) ){
      if( (pWInfo->wctrlFlags & WHERE_SEEK_TABLE) || (
          (pWInfo->wctrlFlags & WHERE_SEEK_UNIQ_TABLE) 
       && (pWInfo->eOnePass==ONEPASS_SINGLE)
      )){







>
>







1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
    }

    if( pLoop->wsFlags & WHERE_IN_EARLYOUT ){
      sqlite3VdbeAddOp2(v, OP_SeekHit, iIdxCur, 1);
    }

    /* Seek the table cursor, if required */
    omitTable = (pLoop->wsFlags & WHERE_IDX_ONLY)!=0 
           && (pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE)==0;
    if( omitTable ){
      /* pIdx is a covering index.  No need to access the main table. */
    }else if( HasRowid(pIdx->pTable) ){
      if( (pWInfo->wctrlFlags & WHERE_SEEK_TABLE) || (
          (pWInfo->wctrlFlags & WHERE_SEEK_UNIQ_TABLE) 
       && (pWInfo->eOnePass==ONEPASS_SINGLE)
      )){
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
    SrcList *pOrTab;       /* Shortened table list or OR-clause generation */
    Index *pCov = 0;             /* Potential covering index (or NULL) */
    int iCovCur = pParse->nTab++;  /* Cursor used for index scans (if any) */

    int regReturn = ++pParse->nMem;           /* Register used with OP_Gosub */
    int regRowset = 0;                        /* Register for RowSet object */
    int regRowid = 0;                         /* Register holding rowid */
    int iLoopBody = sqlite3VdbeMakeLabel(v);  /* Start of loop body */
    int iRetInit;                             /* Address of regReturn init */
    int untestedTerms = 0;             /* Some terms not completely tested */
    int ii;                            /* Loop counter */
    u16 wctrlFlags;                    /* Flags for sub-WHERE clause */
    Expr *pAndExpr = 0;                /* An ".. AND (...)" expression */
    Table *pTab = pTabItem->pTab;








|







1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
    SrcList *pOrTab;       /* Shortened table list or OR-clause generation */
    Index *pCov = 0;             /* Potential covering index (or NULL) */
    int iCovCur = pParse->nTab++;  /* Cursor used for index scans (if any) */

    int regReturn = ++pParse->nMem;           /* Register used with OP_Gosub */
    int regRowset = 0;                        /* Register for RowSet object */
    int regRowid = 0;                         /* Register holding rowid */
    int iLoopBody = sqlite3VdbeMakeLabel(pParse);/* Start of loop body */
    int iRetInit;                             /* Address of regReturn init */
    int untestedTerms = 0;             /* Some terms not completely tested */
    int ii;                            /* Loop counter */
    u16 wctrlFlags;                    /* Flags for sub-WHERE clause */
    Expr *pAndExpr = 0;                /* An ".. AND (...)" expression */
    Table *pTab = pTabItem->pTab;

1945
1946
1947
1948
1949
1950
1951

1952
1953
1954
1955
1956
1957
1958
             || ExprHasProperty(pOrExpr, EP_FromJoin) 
        );
        if( pAndExpr ){
          pAndExpr->pLeft = pOrExpr;
          pOrExpr = pAndExpr;
        }
        /* Loop through table entries that match term pOrTerm. */

        WHERETRACE(0xffff, ("Subplan for OR-clause:\n"));
        pSubWInfo = sqlite3WhereBegin(pParse, pOrTab, pOrExpr, 0, 0,
                                      wctrlFlags, iCovCur);
        assert( pSubWInfo || pParse->nErr || db->mallocFailed );
        if( pSubWInfo ){
          WhereLoop *pSubLoop;
          int addrExplain = sqlite3WhereExplainOneScan(







>







1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
             || ExprHasProperty(pOrExpr, EP_FromJoin) 
        );
        if( pAndExpr ){
          pAndExpr->pLeft = pOrExpr;
          pOrExpr = pAndExpr;
        }
        /* Loop through table entries that match term pOrTerm. */
        ExplainQueryPlan((pParse, 1, "INDEX %d", ii+1));
        WHERETRACE(0xffff, ("Subplan for OR-clause:\n"));
        pSubWInfo = sqlite3WhereBegin(pParse, pOrTab, pOrExpr, 0, 0,
                                      wctrlFlags, iCovCur);
        assert( pSubWInfo || pParse->nErr || db->mallocFailed );
        if( pSubWInfo ){
          WhereLoop *pSubLoop;
          int addrExplain = sqlite3WhereExplainOneScan(
2048
2049
2050
2051
2052
2053
2054

2055
2056
2057
2058
2059
2060
2061
            pCov = pSubLoop->u.btree.pIndex;
          }else{
            pCov = 0;
          }

          /* Finish the loop through table entries that match term pOrTerm. */
          sqlite3WhereEnd(pSubWInfo);

        }
      }
    }
    ExplainQueryPlanPop(pParse);
    pLevel->u.pCovidx = pCov;
    if( pCov ) pLevel->iIdxCur = iCovCur;
    if( pAndExpr ){







>







2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
            pCov = pSubLoop->u.btree.pIndex;
          }else{
            pCov = 0;
          }

          /* Finish the loop through table entries that match term pOrTerm. */
          sqlite3WhereEnd(pSubWInfo);
          ExplainQueryPlanPop(pParse);
        }
      }
    }
    ExplainQueryPlanPop(pParse);
    pLevel->u.pCovidx = pCov;
    if( pCov ) pLevel->iIdxCur = iCovCur;
    if( pAndExpr ){
Changes to src/window.c.
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
  Window *pWin;
  for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
    FuncDef *pFunc = pWin->pFunc;
    if( pFunc->zName==nth_valueName
     || pFunc->zName==first_valueName
    ){
      int csr = pWin->csrApp;
      int lbl = sqlite3VdbeMakeLabel(v);
      int tmpReg = sqlite3GetTempReg(pParse);
      sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regResult);

      if( pFunc->zName==nth_valueName ){
        sqlite3VdbeAddOp3(v, OP_Column, pMWin->iEphCsr, pWin->iArgCol+1,tmpReg);
        windowCheckIntValue(pParse, tmpReg, 2);
      }else{







|







1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
  Window *pWin;
  for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
    FuncDef *pFunc = pWin->pFunc;
    if( pFunc->zName==nth_valueName
     || pFunc->zName==first_valueName
    ){
      int csr = pWin->csrApp;
      int lbl = sqlite3VdbeMakeLabel(pParse);
      int tmpReg = sqlite3GetTempReg(pParse);
      sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regResult);

      if( pFunc->zName==nth_valueName ){
        sqlite3VdbeAddOp3(v, OP_Column, pMWin->iEphCsr, pWin->iArgCol+1,tmpReg);
        windowCheckIntValue(pParse, tmpReg, 2);
      }else{
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
      sqlite3VdbeResolveLabel(v, lbl);
      sqlite3ReleaseTempReg(pParse, tmpReg);
    }
    else if( pFunc->zName==leadName || pFunc->zName==lagName ){
      int nArg = pWin->pOwner->x.pList->nExpr;
      int iEph = pMWin->iEphCsr;
      int csr = pWin->csrApp;
      int lbl = sqlite3VdbeMakeLabel(v);
      int tmpReg = sqlite3GetTempReg(pParse);

      if( nArg<3 ){
        sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regResult);
      }else{
        sqlite3VdbeAddOp3(v, OP_Column, iEph, pWin->iArgCol+2, pWin->regResult);
      }







|







1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
      sqlite3VdbeResolveLabel(v, lbl);
      sqlite3ReleaseTempReg(pParse, tmpReg);
    }
    else if( pFunc->zName==leadName || pFunc->zName==lagName ){
      int nArg = pWin->pOwner->x.pList->nExpr;
      int iEph = pMWin->iEphCsr;
      int csr = pWin->csrApp;
      int lbl = sqlite3VdbeMakeLabel(pParse);
      int tmpReg = sqlite3GetTempReg(pParse);

      if( nArg<3 ){
        sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regResult);
      }else{
        sqlite3VdbeAddOp3(v, OP_Column, iEph, pWin->iArgCol+2, pWin->regResult);
      }
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
       || pMWin->eEnd==TK_CURRENT 
       || pMWin->eEnd==TK_UNBOUNDED 
       || pMWin->eEnd==TK_PRECEDING 
  );

  /* Allocate register and label for the "flush_partition" sub-routine. */
  regFlushPart = ++pParse->nMem;
  lblFlushPart = sqlite3VdbeMakeLabel(v);
  lblFlushDone = sqlite3VdbeMakeLabel(v);

  regStart = ++pParse->nMem;
  regEnd = ++pParse->nMem;

  windowPartitionCache(pParse, p, pWInfo, regFlushPart, lblFlushPart, &regSize);

  addrGoto = sqlite3VdbeAddOp0(v, OP_Goto);







|
|







1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
       || pMWin->eEnd==TK_CURRENT 
       || pMWin->eEnd==TK_UNBOUNDED 
       || pMWin->eEnd==TK_PRECEDING 
  );

  /* Allocate register and label for the "flush_partition" sub-routine. */
  regFlushPart = ++pParse->nMem;
  lblFlushPart = sqlite3VdbeMakeLabel(pParse);
  lblFlushDone = sqlite3VdbeMakeLabel(pParse);

  regStart = ++pParse->nMem;
  regEnd = ++pParse->nMem;

  windowPartitionCache(pParse, p, pWInfo, regFlushPart, lblFlushPart, &regSize);

  addrGoto = sqlite3VdbeAddOp0(v, OP_Goto);
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
    sqlite3VdbeJumpHere(v, addrIfPos2);
  }

  if( pMWin->eStart==TK_CURRENT 
   || pMWin->eStart==TK_PRECEDING 
   || pMWin->eStart==TK_FOLLOWING 
  ){
    int lblSkipInverse = sqlite3VdbeMakeLabel(v);;
    if( pMWin->eStart==TK_PRECEDING ){
      sqlite3VdbeAddOp3(v, OP_IfPos, regStart, lblSkipInverse, 1);
      VdbeCoverage(v);
    }
    if( pMWin->eStart==TK_FOLLOWING ){
      sqlite3VdbeAddOp2(v, OP_Next, csrStart, sqlite3VdbeCurrentAddr(v)+2);
      VdbeCoverage(v);







|







1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
    sqlite3VdbeJumpHere(v, addrIfPos2);
  }

  if( pMWin->eStart==TK_CURRENT 
   || pMWin->eStart==TK_PRECEDING 
   || pMWin->eStart==TK_FOLLOWING 
  ){
    int lblSkipInverse = sqlite3VdbeMakeLabel(pParse);;
    if( pMWin->eStart==TK_PRECEDING ){
      sqlite3VdbeAddOp3(v, OP_IfPos, regStart, lblSkipInverse, 1);
      VdbeCoverage(v);
    }
    if( pMWin->eStart==TK_FOLLOWING ){
      sqlite3VdbeAddOp2(v, OP_Next, csrStart, sqlite3VdbeCurrentAddr(v)+2);
      VdbeCoverage(v);
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906

  assert( (pMWin->eStart==TK_UNBOUNDED && pMWin->eEnd==TK_CURRENT) 
       || (pMWin->eStart==TK_UNBOUNDED && pMWin->eEnd==TK_UNBOUNDED) 
       || (pMWin->eStart==TK_CURRENT && pMWin->eEnd==TK_CURRENT) 
       || (pMWin->eStart==TK_CURRENT && pMWin->eEnd==TK_UNBOUNDED) 
  );

  lblEmpty = sqlite3VdbeMakeLabel(v);
  regNewPeer = pParse->nMem+1;
  pParse->nMem += nPeer;

  /* Allocate register and label for the "flush_partition" sub-routine. */
  regFlushPart = ++pParse->nMem;
  lblFlushPart = sqlite3VdbeMakeLabel(v);

  csrLead = pParse->nTab++;
  regCtr = ++pParse->nMem;

  windowPartitionCache(pParse, p, pWInfo, regFlushPart, lblFlushPart, &regSize);
  addrGoto = sqlite3VdbeAddOp0(v, OP_Goto);








|





|







1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906

  assert( (pMWin->eStart==TK_UNBOUNDED && pMWin->eEnd==TK_CURRENT) 
       || (pMWin->eStart==TK_UNBOUNDED && pMWin->eEnd==TK_UNBOUNDED) 
       || (pMWin->eStart==TK_CURRENT && pMWin->eEnd==TK_CURRENT) 
       || (pMWin->eStart==TK_CURRENT && pMWin->eEnd==TK_UNBOUNDED) 
  );

  lblEmpty = sqlite3VdbeMakeLabel(pParse);
  regNewPeer = pParse->nMem+1;
  pParse->nMem += nPeer;

  /* Allocate register and label for the "flush_partition" sub-routine. */
  regFlushPart = ++pParse->nMem;
  lblFlushPart = sqlite3VdbeMakeLabel(pParse);

  csrLead = pParse->nTab++;
  regCtr = ++pParse->nMem;

  windowPartitionCache(pParse, p, pWInfo, regFlushPart, lblFlushPart, &regSize);
  addrGoto = sqlite3VdbeAddOp0(v, OP_Goto);

Changes to test/altertab.test.
501
502
503
504
505
506
507





















































508
509
  SELECT * FROM x;
} {x x x}

do_execsql_test 15.5 {
  SELECT sql FROM sqlite_master WHERE name = 'y';
} {{CREATE VIEW y AS SELECT f2 AS f1 FROM x}}























































finish_test







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


501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
  SELECT * FROM x;
} {x x x}

do_execsql_test 15.5 {
  SELECT sql FROM sqlite_master WHERE name = 'y';
} {{CREATE VIEW y AS SELECT f2 AS f1 FROM x}}

#-------------------------------------------------------------------------
# Test that it is not possible to rename a shadow table in DEFENSIVE mode.
#
ifcapable fts3 {
  proc vtab_command {method args} {
    switch -- $method {
      xConnect {
        if {[info exists ::vtab_connect_sql]} {
          execsql $::vtab_connect_sql
        }
        return "CREATE TABLE t1(a, b, c)"
      }

      xBestIndex {
        set clist [lindex $args 0]
        if {[llength $clist]!=1} { error "unexpected constraint list" }
        catch { array unset C }
        array set C [lindex $clist 0]
        if {$C(usable)} {
          return "omit 0 cost 0 rows 1 idxnum 555 idxstr eq!"
        } else {
          return "cost 1000000 rows 0 idxnum 0 idxstr scan..."
        }
      }
    }

    return {}
  }

  register_tcl_module db

  sqlite3_db_config db DEFENSIVE 1

  do_execsql_test 16.0 {
    CREATE VIRTUAL TABLE y1 USING fts3;
  }

  do_catchsql_test 16.1 {
    INSERT INTO y1_segments VALUES(1, X'1234567890');
  } {1 {table y1_segments may not be modified}}

  do_catchsql_test 16.2 {
    ALTER TABLE y1_segments RENAME TO abc;
  } {1 {table y1_segments may not be altered}}

  do_execsql_test 16.3 {
    ALTER TABLE y1 RENAME TO z1;
  }

  do_execsql_test 16.4 {
    SELECT * FROM z1_segments;
  }
}

finish_test
Changes to test/autoindex1.test.
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
}
do_eqp_test autoindex1-500.1 {
  SELECT b FROM t501
   WHERE t501.a IN (SELECT x FROM t502 WHERE y=?);
} {
  QUERY PLAN
  |--SEARCH TABLE t501 USING INTEGER PRIMARY KEY (rowid=?)
  `--LIST SUBQUERY
     `--SCAN TABLE t502
}
do_eqp_test autoindex1-501 {
  SELECT b FROM t501
   WHERE t501.a IN (SELECT x FROM t502 WHERE y=t501.b);
} {
  QUERY PLAN
  |--SCAN TABLE t501
  `--CORRELATED LIST SUBQUERY
     `--SEARCH TABLE t502 USING AUTOMATIC COVERING INDEX (y=?)
}
do_eqp_test autoindex1-502 {
  SELECT b FROM t501
   WHERE t501.a=123
     AND t501.a IN (SELECT x FROM t502 WHERE y=t501.b);
} {
  QUERY PLAN
  |--SEARCH TABLE t501 USING INTEGER PRIMARY KEY (rowid=?)
  `--CORRELATED LIST SUBQUERY
     `--SCAN TABLE t502
}

# The following code checks a performance regression reported on the
# mailing list on 2010-10-19.  The problem is that the nRowEst field
# of ephermeral tables was not being initialized correctly and so no
# automatic index was being created for the emphemeral table when it was







|








|









|







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
}
do_eqp_test autoindex1-500.1 {
  SELECT b FROM t501
   WHERE t501.a IN (SELECT x FROM t502 WHERE y=?);
} {
  QUERY PLAN
  |--SEARCH TABLE t501 USING INTEGER PRIMARY KEY (rowid=?)
  `--LIST SUBQUERY xxxxxx
     `--SCAN TABLE t502
}
do_eqp_test autoindex1-501 {
  SELECT b FROM t501
   WHERE t501.a IN (SELECT x FROM t502 WHERE y=t501.b);
} {
  QUERY PLAN
  |--SCAN TABLE t501
  `--CORRELATED LIST SUBQUERY xxxxxx
     `--SEARCH TABLE t502 USING AUTOMATIC COVERING INDEX (y=?)
}
do_eqp_test autoindex1-502 {
  SELECT b FROM t501
   WHERE t501.a=123
     AND t501.a IN (SELECT x FROM t502 WHERE y=t501.b);
} {
  QUERY PLAN
  |--SEARCH TABLE t501 USING INTEGER PRIMARY KEY (rowid=?)
  `--CORRELATED LIST SUBQUERY xxxxxx
     `--SCAN TABLE t502
}

# The following code checks a performance regression reported on the
# mailing list on 2010-10-19.  The problem is that the nRowEst field
# of ephermeral tables was not being initialized correctly and so no
# automatic index was being created for the emphemeral table when it was
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
   WHERE y.sheep_no IS NULL
   ORDER BY x.registering_flock;
} {
  QUERY PLAN
  |--MATERIALIZE xxxxxx
  |  |--SCAN TABLE sheep AS s
  |  |--SEARCH TABLE flock_owner AS prev USING INDEX sqlite_autoindex_flock_owner_1 (flock_no=? AND owner_change_date<?)
  |  `--CORRELATED SCALAR SUBQUERY
  |     `--SEARCH TABLE flock_owner AS later USING COVERING INDEX sqlite_autoindex_flock_owner_1 (flock_no=? AND owner_change_date>? AND owner_change_date<?)
  |--SCAN TABLE sheep AS x USING INDEX sheep_reg_flock_index
  `--SEARCH SUBQUERY xxxxxx AS y USING AUTOMATIC COVERING INDEX (sheep_no=?)
}


do_execsql_test autoindex1-700 {







|







276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
   WHERE y.sheep_no IS NULL
   ORDER BY x.registering_flock;
} {
  QUERY PLAN
  |--MATERIALIZE xxxxxx
  |  |--SCAN TABLE sheep AS s
  |  |--SEARCH TABLE flock_owner AS prev USING INDEX sqlite_autoindex_flock_owner_1 (flock_no=? AND owner_change_date<?)
  |  `--CORRELATED SCALAR SUBQUERY xxxxxx
  |     `--SEARCH TABLE flock_owner AS later USING COVERING INDEX sqlite_autoindex_flock_owner_1 (flock_no=? AND owner_change_date>? AND owner_change_date<?)
  |--SCAN TABLE sheep AS x USING INDEX sheep_reg_flock_index
  `--SEARCH SUBQUERY xxxxxx AS y USING AUTOMATIC COVERING INDEX (sheep_no=?)
}


do_execsql_test autoindex1-700 {
Changes to test/bestindex3.test.
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
} {SCAN TABLE t1 VIRTUAL TABLE INDEX 0:a EQ ?}

do_eqp_test 1.3 {
  SELECT * FROM t1 WHERE a = 'abc' OR b = 'def';
} {
  QUERY PLAN
  `--MULTI-INDEX OR

     |--SCAN TABLE t1 VIRTUAL TABLE INDEX 0:a EQ ?

     `--SCAN TABLE t1 VIRTUAL TABLE INDEX 0:b EQ ?
}

do_eqp_test 1.4 {
  SELECT * FROM t1 WHERE a LIKE 'abc%' OR b = 'def';
} {
  QUERY PLAN
  `--MULTI-INDEX OR

     |--SCAN TABLE t1 VIRTUAL TABLE INDEX 0:a LIKE ?

     `--SCAN TABLE t1 VIRTUAL TABLE INDEX 0:b EQ ?
}

do_execsql_test 1.5 {
  CREATE TABLE ttt(a, b, c);

  INSERT INTO ttt VALUES(1, 'two',   'three');
  INSERT INTO ttt VALUES(2, 'one',   'two');







>
|
>
|







>
|
>
|







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
} {SCAN TABLE t1 VIRTUAL TABLE INDEX 0:a EQ ?}

do_eqp_test 1.3 {
  SELECT * FROM t1 WHERE a = 'abc' OR b = 'def';
} {
  QUERY PLAN
  `--MULTI-INDEX OR
     |--INDEX 1
     |  `--SCAN TABLE t1 VIRTUAL TABLE INDEX 0:a EQ ?
     `--INDEX 2
        `--SCAN TABLE t1 VIRTUAL TABLE INDEX 0:b EQ ?
}

do_eqp_test 1.4 {
  SELECT * FROM t1 WHERE a LIKE 'abc%' OR b = 'def';
} {
  QUERY PLAN
  `--MULTI-INDEX OR
     |--INDEX 1
     |  `--SCAN TABLE t1 VIRTUAL TABLE INDEX 0:a LIKE ?
     `--INDEX 2
        `--SCAN TABLE t1 VIRTUAL TABLE INDEX 0:b EQ ?
}

do_execsql_test 1.5 {
  CREATE TABLE ttt(a, b, c);

  INSERT INTO ttt VALUES(1, 'two',   'three');
  INSERT INTO ttt VALUES(2, 'one',   'two');
146
147
148
149
150
151
152

153

154
155
156
157
158
159
160
161
  }

  do_eqp_test 2.2 {
    SELECT * FROM t2 WHERE x LIKE 'abc%' OR y = 'def'
  } [string map {"\n  " \n} {
    QUERY PLAN
    `--MULTI-INDEX OR

       |--SEARCH TABLE t2 USING INDEX t2x (x>? AND x<?)

       `--SEARCH TABLE t2 USING INDEX t2y (y=?)
  }]
}

#-------------------------------------------------------------------------
# Test that any PRIMARY KEY within a sqlite3_decl_vtab() CREATE TABLE 
# statement is currently ignored.
#







>
|
>
|







150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
  }

  do_eqp_test 2.2 {
    SELECT * FROM t2 WHERE x LIKE 'abc%' OR y = 'def'
  } [string map {"\n  " \n} {
    QUERY PLAN
    `--MULTI-INDEX OR
       |--INDEX 1
       |  `--SEARCH TABLE t2 USING INDEX t2x (x>? AND x<?)
       `--INDEX 2
          `--SEARCH TABLE t2 USING INDEX t2y (y=?)
  }]
}

#-------------------------------------------------------------------------
# Test that any PRIMARY KEY within a sqlite3_decl_vtab() CREATE TABLE 
# statement is currently ignored.
#
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/conflict.test.
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#
#***********************************************************************
# This file implements regression tests for SQLite library.
#
# This file implements tests for the conflict resolution extension
# to SQLite.
#
# $Id: conflict.test,v 1.32 2009/04/30 09:10:38 danielk1977 Exp $

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

ifcapable !conflict {
  finish_test
  return







<







9
10
11
12
13
14
15

16
17
18
19
20
21
22
#
#***********************************************************************
# This file implements regression tests for SQLite library.
#
# This file implements tests for the conflict resolution extension
# to SQLite.
#


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

ifcapable !conflict {
  finish_test
  return
820
821
822
823
824
825
826
827











828
  execsql {
    REPLACE INTO t13 VALUES(3);
    COMMIT;
    SELECT * FROM t13;
  }
} {1 3}













finish_test








>
>
>
>
>
>
>
>
>
>
>

819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
  execsql {
    REPLACE INTO t13 VALUES(3);
    COMMIT;
    SELECT * FROM t13;
  }
} {1 3}


# Ticket https://www.sqlite.org/src/tktview/e6f1f2e34dceeb1ed61531c7e9
# Verify that it is not possible to sneak a NULL value into a NOT NULL
# column using REPLACE.
#
do_catchsql_test conflict-14.1 {
  DROP TABLE IF EXISTS t1;
  CREATE TABLE t1(x NOT NULL DEFAULT NULL);
  REPLACE INTO t1 DEFAULT VALUES;
} {1 {NOT NULL constraint failed: t1.x}}


finish_test
Changes to test/cost.test.
54
55
56
57
58
59
60

61

62

63
64
65
66
67
68
69
70
do_eqp_test 3.2 {
  SELECT a FROM t5 
  WHERE b IS NULL OR c IS NULL OR d IS NULL 
  ORDER BY a;
} {
  QUERY PLAN
  |--MULTI-INDEX OR

  |  |--SEARCH TABLE t5 USING INDEX t5b (b=?)

  |  |--SEARCH TABLE t5 USING INDEX t5c (c=?)

  |  `--SEARCH TABLE t5 USING INDEX t5d (d=?)
  `--USE TEMP B-TREE FOR ORDER BY
}

#-------------------------------------------------------------------------
# If there is no likelihood() or stat3 data, SQLite assumes that a closed
# range scan (e.g. one constrained by "col BETWEEN ? AND ?" constraint)
# visits 1/64 of the rows in a table.







>
|
>
|
>
|







54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
do_eqp_test 3.2 {
  SELECT a FROM t5 
  WHERE b IS NULL OR c IS NULL OR d IS NULL 
  ORDER BY a;
} {
  QUERY PLAN
  |--MULTI-INDEX OR
  |  |--INDEX 1
  |  |  `--SEARCH TABLE t5 USING INDEX t5b (b=?)
  |  |--INDEX 2
  |  |  `--SEARCH TABLE t5 USING INDEX t5c (c=?)
  |  `--INDEX 3
  |     `--SEARCH TABLE t5 USING INDEX t5d (d=?)
  `--USE TEMP B-TREE FOR ORDER BY
}

#-------------------------------------------------------------------------
# If there is no likelihood() or stat3 data, SQLite assumes that a closed
# range scan (e.g. one constrained by "col BETWEEN ? AND ?" constraint)
# visits 1/64 of the rows in a table.
120
121
122
123
124
125
126

127

128
129
130
131
132
133
134
135
}

do_eqp_test 6.2 {
  SELECT a FROM t3 WHERE (b BETWEEN 2 AND 4) OR c=100 ORDER BY a
} {
  QUERY PLAN
  |--MULTI-INDEX OR

  |  |--SEARCH TABLE t3 USING INDEX t3i1 (b>? AND b<?)

  |  `--SEARCH TABLE t3 USING INDEX t3i2 (c=?)
  `--USE TEMP B-TREE FOR ORDER BY
}

#-------------------------------------------------------------------------
#
reset_db
do_execsql_test 7.1 {







>
|
>
|







123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
}

do_eqp_test 6.2 {
  SELECT a FROM t3 WHERE (b BETWEEN 2 AND 4) OR c=100 ORDER BY a
} {
  QUERY PLAN
  |--MULTI-INDEX OR
  |  |--INDEX 1
  |  |  `--SEARCH TABLE t3 USING INDEX t3i1 (b>? AND b<?)
  |  `--INDEX 2
  |     `--SEARCH TABLE t3 USING INDEX t3i2 (c=?)
  `--USE TEMP B-TREE FOR ORDER BY
}

#-------------------------------------------------------------------------
#
reset_db
do_execsql_test 7.1 {
145
146
147
148
149
150
151

152

153
154
155
156
157
158
159
160
do_eqp_test 7.2 {
  SELECT a FROM t1
     WHERE (b>=950 AND b<=1010) OR (b IS NULL AND c NOT NULL)
  ORDER BY a
} {
  QUERY PLAN
  |--MULTI-INDEX OR

  |  |--SEARCH TABLE t1 USING INDEX t1b (b>? AND b<?)

  |  `--SEARCH TABLE t1 USING INDEX t1b (b=?)
  `--USE TEMP B-TREE FOR ORDER BY
}

do_eqp_test 7.3 {
  SELECT rowid FROM t1
  WHERE (+b IS NULL AND c NOT NULL AND d NOT NULL)
        OR (b NOT NULL AND c IS NULL AND d NOT NULL)







>
|
>
|







150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
do_eqp_test 7.2 {
  SELECT a FROM t1
     WHERE (b>=950 AND b<=1010) OR (b IS NULL AND c NOT NULL)
  ORDER BY a
} {
  QUERY PLAN
  |--MULTI-INDEX OR
  |  |--INDEX 1
  |  |  `--SEARCH TABLE t1 USING INDEX t1b (b>? AND b<?)
  |  `--INDEX 2
  |     `--SEARCH TABLE t1 USING INDEX t1b (b=?)
  `--USE TEMP B-TREE FOR ORDER BY
}

do_eqp_test 7.3 {
  SELECT rowid FROM t1
  WHERE (+b IS NULL AND c NOT NULL AND d NOT NULL)
        OR (b NOT NULL AND c IS NULL AND d NOT NULL)
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/e_select.test.
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
  2002.1  "SELECT ALL 1, 2, 3 GROUP BY 2 HAVING count(*)=1" {1 2 3}
  2002.2  "SELECT ALL 1, 2, 3 GROUP BY 2 HAVING count(*)>1" {}

  0101.1  "SELECT count(*), max(a) FROM t1 GROUP BY b" {1 a 1 c 1 b}
  0102.1  "SELECT count(*), max(a) FROM t1 GROUP BY b HAVING count(*)=1" {
    1 a 1 c 1 b
  }
  0102.2  "SELECT count(*), max(a) FROM t1 GROUP BY b HAVING count(*)=2" { }

  1101.1  "SELECT DISTINCT count(*), max(a) FROM t1 GROUP BY b" {1 a 1 c 1 b}
  1102.1  "SELECT DISTINCT count(*), max(a) FROM t1 
           GROUP BY b HAVING count(*)=1" {
    1 a 1 c 1 b
  }
  1102.2  "SELECT DISTINCT count(*), max(a) FROM t1 
           GROUP BY b HAVING count(*)=2" { 
  }

  2101.1  "SELECT ALL count(*), max(a) FROM t1 GROUP BY b" {1 a 1 c 1 b}
  2102.1  "SELECT ALL count(*), max(a) FROM t1 
           GROUP BY b HAVING count(*)=1" {
    1 a 1 c 1 b
  }
  2102.2  "SELECT ALL count(*), max(a) FROM t1 
           GROUP BY b HAVING count(*)=2" { 
  }

  0011.1  "SELECT 1, 2, 3 WHERE 1 GROUP BY 2" {1 2 3}
  0012.1  "SELECT 1, 2, 3 WHERE 0 GROUP BY 2 HAVING count(*)=1" {}
  0012.2  "SELECT 1, 2, 3 WHERE 0 GROUP BY 2 HAVING count(*)>1" {}

  1011.1  "SELECT DISTINCT 1, 2, 3 WHERE 0 GROUP BY 2" {}
  1012.1  "SELECT DISTINCT 1, 2, 3 WHERE 1 GROUP BY 2 HAVING count(*)=1" 
          {1 2 3}
  1012.2  "SELECT DISTINCT 1, 2, 3 WHERE NULL GROUP BY 2 HAVING count(*)>1" {}

  2011.1  "SELECT ALL 1, 2, 3 WHERE 1 GROUP BY 2" {1 2 3}
  2012.1  "SELECT ALL 1, 2, 3 WHERE 0 GROUP BY 2 HAVING count(*)=1" {}
  2012.2  "SELECT ALL 1, 2, 3 WHERE 'abc' GROUP BY 2 HAVING count(*)>1" {}

  0111.1  "SELECT count(*), max(a) FROM t1 WHERE a='a' GROUP BY b" {1 a}
  0112.1  "SELECT count(*), max(a) FROM t1 
           WHERE a='c' GROUP BY b HAVING count(*)=1" {1 c}
  0112.2  "SELECT count(*), max(a) FROM t1 
           WHERE 0 GROUP BY b HAVING count(*)=2" { }
  1111.1  "SELECT DISTINCT count(*), max(a) FROM t1 WHERE a<'c' GROUP BY b" 
          {1 a 1 b}
  1112.1  "SELECT DISTINCT count(*), max(a) FROM t1 WHERE a>'a'
           GROUP BY b HAVING count(*)=1" {
    1 c 1 b
  }
  1112.2  "SELECT DISTINCT count(*), max(a) FROM t1 WHERE 0
           GROUP BY b HAVING count(*)=2" { 
  }

  2111.1  "SELECT ALL count(*), max(a) FROM t1 WHERE b>'one' GROUP BY b" 
          {1 c 1 b}
  2112.1  "SELECT ALL count(*), max(a) FROM t1 WHERE a!='b'
           GROUP BY b HAVING count(*)=1" {
    1 a 1 c
  }
  2112.2  "SELECT ALL count(*), max(a) FROM t1 
           WHERE 0 GROUP BY b HAVING count(*)=2" { }
}


# -- syntax diagram result-column
#
do_select_tests e_select-0.3 {
  1  "SELECT * FROM t1" {a one b two c three}







|







|
<







|
<


















|







|
<








|







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
  2002.1  "SELECT ALL 1, 2, 3 GROUP BY 2 HAVING count(*)=1" {1 2 3}
  2002.2  "SELECT ALL 1, 2, 3 GROUP BY 2 HAVING count(*)>1" {}

  0101.1  "SELECT count(*), max(a) FROM t1 GROUP BY b" {1 a 1 c 1 b}
  0102.1  "SELECT count(*), max(a) FROM t1 GROUP BY b HAVING count(*)=1" {
    1 a 1 c 1 b
  }
  0102.2  "SELECT count(*), max(a) FROM t1 GROUP BY b HAVING count(*)=2" {}

  1101.1  "SELECT DISTINCT count(*), max(a) FROM t1 GROUP BY b" {1 a 1 c 1 b}
  1102.1  "SELECT DISTINCT count(*), max(a) FROM t1 
           GROUP BY b HAVING count(*)=1" {
    1 a 1 c 1 b
  }
  1102.2  "SELECT DISTINCT count(*), max(a) FROM t1 
           GROUP BY b HAVING count(*)=2" {}


  2101.1  "SELECT ALL count(*), max(a) FROM t1 GROUP BY b" {1 a 1 c 1 b}
  2102.1  "SELECT ALL count(*), max(a) FROM t1 
           GROUP BY b HAVING count(*)=1" {
    1 a 1 c 1 b
  }
  2102.2  "SELECT ALL count(*), max(a) FROM t1 
           GROUP BY b HAVING count(*)=2" {}


  0011.1  "SELECT 1, 2, 3 WHERE 1 GROUP BY 2" {1 2 3}
  0012.1  "SELECT 1, 2, 3 WHERE 0 GROUP BY 2 HAVING count(*)=1" {}
  0012.2  "SELECT 1, 2, 3 WHERE 0 GROUP BY 2 HAVING count(*)>1" {}

  1011.1  "SELECT DISTINCT 1, 2, 3 WHERE 0 GROUP BY 2" {}
  1012.1  "SELECT DISTINCT 1, 2, 3 WHERE 1 GROUP BY 2 HAVING count(*)=1" 
          {1 2 3}
  1012.2  "SELECT DISTINCT 1, 2, 3 WHERE NULL GROUP BY 2 HAVING count(*)>1" {}

  2011.1  "SELECT ALL 1, 2, 3 WHERE 1 GROUP BY 2" {1 2 3}
  2012.1  "SELECT ALL 1, 2, 3 WHERE 0 GROUP BY 2 HAVING count(*)=1" {}
  2012.2  "SELECT ALL 1, 2, 3 WHERE 'abc' GROUP BY 2 HAVING count(*)>1" {}

  0111.1  "SELECT count(*), max(a) FROM t1 WHERE a='a' GROUP BY b" {1 a}
  0112.1  "SELECT count(*), max(a) FROM t1 
           WHERE a='c' GROUP BY b HAVING count(*)=1" {1 c}
  0112.2  "SELECT count(*), max(a) FROM t1 
           WHERE 0 GROUP BY b HAVING count(*)=2" {}
  1111.1  "SELECT DISTINCT count(*), max(a) FROM t1 WHERE a<'c' GROUP BY b" 
          {1 a 1 b}
  1112.1  "SELECT DISTINCT count(*), max(a) FROM t1 WHERE a>'a'
           GROUP BY b HAVING count(*)=1" {
    1 c 1 b
  }
  1112.2  "SELECT DISTINCT count(*), max(a) FROM t1 WHERE 0
           GROUP BY b HAVING count(*)=2" {}


  2111.1  "SELECT ALL count(*), max(a) FROM t1 WHERE b>'one' GROUP BY b" 
          {1 c 1 b}
  2112.1  "SELECT ALL count(*), max(a) FROM t1 WHERE a!='b'
           GROUP BY b HAVING count(*)=1" {
    1 a 1 c
  }
  2112.2  "SELECT ALL count(*), max(a) FROM t1 
           WHERE 0 GROUP BY b HAVING count(*)=2" {}
}


# -- syntax diagram result-column
#
do_select_tests e_select-0.3 {
  1  "SELECT * FROM t1" {a one b two c three}
Changes to test/eqp.test.
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
}

do_eqp_test 1.2 {
  SELECT * FROM t2, t1 WHERE t1.a=1 OR t1.b=2;
} {
  QUERY PLAN
  |--MULTI-INDEX OR

  |  |--SEARCH TABLE t1 USING INDEX i1 (a=?)

  |  `--SEARCH TABLE t1 USING INDEX i2 (b=?)
  `--SCAN TABLE t2
}
do_eqp_test 1.3 {
  SELECT * FROM t2 CROSS JOIN t1 WHERE t1.a=1 OR t1.b=2;
} {
  QUERY PLAN
  |--SCAN TABLE t2
  `--MULTI-INDEX OR

     |--SEARCH TABLE t1 USING INDEX i1 (a=?)

     `--SEARCH TABLE t1 USING INDEX i2 (b=?)
}
do_eqp_test 1.3 {
  SELECT a FROM t1 ORDER BY a
} {
  QUERY PLAN
  `--SCAN TABLE t1 USING COVERING INDEX i1
}







>
|
>
|








>
|
>
|







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
}

do_eqp_test 1.2 {
  SELECT * FROM t2, t1 WHERE t1.a=1 OR t1.b=2;
} {
  QUERY PLAN
  |--MULTI-INDEX OR
  |  |--INDEX 1
  |  |  `--SEARCH TABLE t1 USING INDEX i1 (a=?)
  |  `--INDEX 2
  |     `--SEARCH TABLE t1 USING INDEX i2 (b=?)
  `--SCAN TABLE t2
}
do_eqp_test 1.3 {
  SELECT * FROM t2 CROSS JOIN t1 WHERE t1.a=1 OR t1.b=2;
} {
  QUERY PLAN
  |--SCAN TABLE t2
  `--MULTI-INDEX OR
     |--INDEX 1
     |  `--SEARCH TABLE t1 USING INDEX i1 (a=?)
     `--INDEX 2
        `--SEARCH TABLE t1 USING INDEX i2 (b=?)
}
do_eqp_test 1.3 {
  SELECT a FROM t1 ORDER BY a
} {
  QUERY PLAN
  `--SCAN TABLE t1 USING COVERING INDEX i1
}
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
# Test cases eqp-3.* - tests for select statements that use sub-selects.
#
do_eqp_test 3.1.1 {
  SELECT (SELECT x FROM t1 AS sub) FROM t1;
} {
  QUERY PLAN
  |--SCAN TABLE t1
  `--SCALAR SUBQUERY
     `--SCAN TABLE t1 AS sub
}
do_eqp_test 3.1.2 {
  SELECT * FROM t1 WHERE (SELECT x FROM t1 AS sub);
} {
  QUERY PLAN
  |--SCAN TABLE t1
  `--SCALAR SUBQUERY
     `--SCAN TABLE t1 AS sub
}
do_eqp_test 3.1.3 {
  SELECT * FROM t1 WHERE (SELECT x FROM t1 AS sub ORDER BY y);
} {
  QUERY PLAN
  |--SCAN TABLE t1
  `--SCALAR SUBQUERY
     |--SCAN TABLE t1 AS sub
     `--USE TEMP B-TREE FOR ORDER BY
}
do_eqp_test 3.1.4 {
  SELECT * FROM t1 WHERE (SELECT x FROM t2 ORDER BY x);
} {
  QUERY PLAN
  |--SCAN TABLE t1
  `--SCALAR SUBQUERY
     `--SCAN TABLE t2 USING COVERING INDEX t2i1
}

det 3.2.1 {
  SELECT * FROM (SELECT * FROM t1 ORDER BY x LIMIT 10) ORDER BY y LIMIT 5
} {
  QUERY PLAN







|







|







|








|







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
# Test cases eqp-3.* - tests for select statements that use sub-selects.
#
do_eqp_test 3.1.1 {
  SELECT (SELECT x FROM t1 AS sub) FROM t1;
} {
  QUERY PLAN
  |--SCAN TABLE t1
  `--SCALAR SUBQUERY xxxxxx
     `--SCAN TABLE t1 AS sub
}
do_eqp_test 3.1.2 {
  SELECT * FROM t1 WHERE (SELECT x FROM t1 AS sub);
} {
  QUERY PLAN
  |--SCAN TABLE t1
  `--SCALAR SUBQUERY xxxxxx
     `--SCAN TABLE t1 AS sub
}
do_eqp_test 3.1.3 {
  SELECT * FROM t1 WHERE (SELECT x FROM t1 AS sub ORDER BY y);
} {
  QUERY PLAN
  |--SCAN TABLE t1
  `--SCALAR SUBQUERY xxxxxx
     |--SCAN TABLE t1 AS sub
     `--USE TEMP B-TREE FOR ORDER BY
}
do_eqp_test 3.1.4 {
  SELECT * FROM t1 WHERE (SELECT x FROM t2 ORDER BY x);
} {
  QUERY PLAN
  |--SCAN TABLE t1
  `--SCALAR SUBQUERY xxxxxx
     `--SCAN TABLE t2 USING COVERING INDEX t2i1
}

det 3.2.1 {
  SELECT * FROM (SELECT * FROM t1 ORDER BY x LIMIT 10) ORDER BY y LIMIT 5
} {
  QUERY PLAN
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
}

det 3.3.1 {
  SELECT * FROM t1 WHERE y IN (SELECT y FROM t2)
} {
  QUERY PLAN
  |--SCAN TABLE t1
  `--LIST SUBQUERY
     `--SCAN TABLE t2
}
det 3.3.2 {
  SELECT * FROM t1 WHERE y IN (SELECT y FROM t2 WHERE t1.x!=t2.x)
} {
  QUERY PLAN
  |--SCAN TABLE t1
  `--CORRELATED LIST SUBQUERY
     `--SCAN TABLE t2
}
det 3.3.3 {
  SELECT * FROM t1 WHERE EXISTS (SELECT y FROM t2 WHERE t1.x!=t2.x)
} {
  QUERY PLAN
  |--SCAN TABLE t1
  `--CORRELATED SCALAR SUBQUERY
     `--SCAN TABLE t2
}

#-------------------------------------------------------------------------
# Test cases eqp-4.* - tests for composite select statements.
#
do_eqp_test 4.1.1 {







|







|







|







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
}

det 3.3.1 {
  SELECT * FROM t1 WHERE y IN (SELECT y FROM t2)
} {
  QUERY PLAN
  |--SCAN TABLE t1
  `--LIST SUBQUERY xxxxxx
     `--SCAN TABLE t2
}
det 3.3.2 {
  SELECT * FROM t1 WHERE y IN (SELECT y FROM t2 WHERE t1.x!=t2.x)
} {
  QUERY PLAN
  |--SCAN TABLE t1
  `--CORRELATED LIST SUBQUERY xxxxxx
     `--SCAN TABLE t2
}
det 3.3.3 {
  SELECT * FROM t1 WHERE EXISTS (SELECT y FROM t2 WHERE t1.x!=t2.x)
} {
  QUERY PLAN
  |--SCAN TABLE t1
  `--CORRELATED SCALAR SUBQUERY xxxxxx
     `--SCAN TABLE t2
}

#-------------------------------------------------------------------------
# Test cases eqp-4.* - tests for composite select statements.
#
do_eqp_test 4.1.1 {
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
    AND event.objid=thread.last
  ORDER BY 1;
} {
  QUERY PLAN
  |--MATERIALIZE xxxxxx
  |  |--SCAN TABLE forumpost AS x USING INDEX forumthread
  |  |--USING ROWID SEARCH ON TABLE private FOR IN-OPERATOR
  |  |--CORRELATED SCALAR SUBQUERY
  |  |  |--SEARCH TABLE forumpost USING COVERING INDEX forumthread (froot=?)
  |  |  `--USING ROWID SEARCH ON TABLE private FOR IN-OPERATOR
  |  `--USE TEMP B-TREE FOR ORDER BY
  |--SCAN SUBQUERY xxxxxx
  |--SEARCH TABLE blob USING INTEGER PRIMARY KEY (rowid=?)
  |--SEARCH TABLE event USING INTEGER PRIMARY KEY (rowid=?)
  `--USE TEMP B-TREE FOR ORDER BY
}

finish_test







|










813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
    AND event.objid=thread.last
  ORDER BY 1;
} {
  QUERY PLAN
  |--MATERIALIZE xxxxxx
  |  |--SCAN TABLE forumpost AS x USING INDEX forumthread
  |  |--USING ROWID SEARCH ON TABLE private FOR IN-OPERATOR
  |  |--CORRELATED SCALAR SUBQUERY xxxxxx
  |  |  |--SEARCH TABLE forumpost USING COVERING INDEX forumthread (froot=?)
  |  |  `--USING ROWID SEARCH ON TABLE private FOR IN-OPERATOR
  |  `--USE TEMP B-TREE FOR ORDER BY
  |--SCAN SUBQUERY xxxxxx
  |--SEARCH TABLE blob USING INTEGER PRIMARY KEY (rowid=?)
  |--SEARCH TABLE event USING INTEGER PRIMARY KEY (rowid=?)
  `--USE TEMP B-TREE FOR ORDER BY
}

finish_test
Changes to test/fkey8.test.
160
161
162
163
164
165
166

































167

  END;
}

do_catchsql_test 2.3.1 {
  DELETE FROM p3 WHERE a=1
} {1 {FOREIGN KEY constraint failed}}


































finish_test








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

>
160
161
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
  END;
}

do_catchsql_test 2.3.1 {
  DELETE FROM p3 WHERE a=1
} {1 {FOREIGN KEY constraint failed}}


do_execsql_test 3.0 {
  PRAGMA foreign_keys=ON;
  CREATE TABLE t2(
    a PRIMARY KEY, b, c, d, e,
      FOREIGN KEY(b, c) REFERENCES t2(d, e)
  ) WITHOUT ROWID;
  CREATE UNIQUE INDEX idx ON t2(d, e);

  INSERT INTO t2 VALUES(1, 'one', 'one', 'one', 'one'); -- row is parent of self
  INSERT INTO t2 VALUES(2, 'one', 'one', 'one', NULL);  -- parent is row 1
}

do_catchsql_test 3.1 {
  DELETE FROM t2 WHERE a=1;
} {1 {FOREIGN KEY constraint failed}}

do_execsql_test 4.0 {
  CREATE TABLE t1 (
      c1 PRIMARY KEY,
      c2 NUMERIC,
      FOREIGN KEY(c1) REFERENCES t1(c2)
      ) WITHOUT ROWID ;
  CREATE INDEX t1c1 ON t1(c1);
  CREATE UNIQUE INDEX t1c1unique ON t1(c2);
}
do_catchsql_test 4.1 {
  INSERT OR REPLACE INTO t1 VALUES(10000, 20000);
} {1 {FOREIGN KEY constraint failed}}
do_execsql_test 4.2 {
  INSERT OR REPLACE INTO t1 VALUES(20000, 20000);
}

finish_test

Changes to test/fts3aa.test.
246
247
248
249
250
251
252











253
254
do_execsql_test 9.1 {
  CREATE VIRTUAL TABLE t9 USING fts4(a, "", '---');
}
do_execsql_test 9.2 {
  CREATE VIRTUAL TABLE t10 USING fts3(<, b, c);
}












expand_all_sql db
finish_test







>
>
>
>
>
>
>
>
>
>
>


246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
do_execsql_test 9.1 {
  CREATE VIRTUAL TABLE t9 USING fts4(a, "", '---');
}
do_execsql_test 9.2 {
  CREATE VIRTUAL TABLE t10 USING fts3(<, b, c);
}

do_execsql_test 10.0 {
  CREATE VIRTUAL TABLE z1 USING fts3;
  INSERT INTO z1 VALUES('one two three'),('four one five'),('six two five');
  CREATE TRIGGER z1r1 AFTER DELETE ON z1_content BEGIN
    DELETE FROM z1;
  END;
}
do_catchsql_test 10.1 {
  DELETE FROM z1;
} {1 {SQL logic error}}

expand_all_sql db
finish_test
Changes to test/fts3corrupt4.test.
140
141
142
143
144
145
146








































































































147
148
  UPDATE ft_segdir 
  SET root = blob('0101056162633132FFFFFFFF070236030132030136');
}

do_catchsql_test 3.1 {
  SELECT * FROM ft WHERE ft MATCH 'abc20'
} {1 {database disk image is malformed}}









































































































finish_test







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


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
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
  UPDATE ft_segdir 
  SET root = blob('0101056162633132FFFFFFFF070236030132030136');
}

do_catchsql_test 3.1 {
  SELECT * FROM ft WHERE ft MATCH 'abc20'
} {1 {database disk image is malformed}}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 4.0 {
  CREATE VIRTUAL TABLE t1 USING fts3();
  INSERT INTO t1 VALUES('one two three');
  UPDATE t1_segdir SET start_block = 1;
}

do_catchsql_test 4.1 { 
  SELECT * FROM t1 WHERE t1 MATCH 'one'; 
} {1 {database disk image is malformed}}
do_catchsql_test 4.2 { 
  SELECT * FROM t1 WHERE t1 MATCH 'two'; 
} {1 {database disk image is malformed}}
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
Added test/fts3fuzz001.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
# 2012-12-21
#
# 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.
#
#***********************************************************************
#
# Test cases for corrupt database files.

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

ifcapable !deserialize||!fts3 {
  finish_test
  return
}
database_may_be_corrupt

do_test fts3fuzz001-100 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
| size 24576 pagesize 4096 filename c6.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 06   .....@  ........
|     32: 00 00 00 00 00 00 00 00 00 00 00 05 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 78 5f 74 15 f7 36 56 76 46 97 25 f3 17 43   dex_t..6VvF.%..C
|   3824: 15 5f 73 65 67 64 69 72 05 00 00 00 08 00 00 00   ._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 00 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 6e 03 03 02 00   ft......ndon....
| page 5 offset 16384
|      0: 0a 00 00 00 01 0f fb 00 0f 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 00 00 00 00 00 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 3d 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 c6.db
  }]
  catchsql {
    INSERT INTO t1(t1) SELECT x FROM t2;
  }
} {1 {database disk image is malformed}}
do_test fts3fuzz001-110 {
  catchsql {
    INSERT INTO t1(t1) VALUES('integrity-check');
  }
} {1 {database disk image is malformed}}
do_test fts3fuzz001-120 {
  catchsql {
    INSERT INTO t1(t1) VALUES('optimize');
  }
} {0 {}}
do_test fts3fuzz001-121 {
  catchsql {
    INSERT INTO t1(t1) VALUES('integrity-check');
  }
} {1 {database disk image is malformed}}


finish_test
Changes to test/fts4umlaut.test.
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

ifcapable !fts3 {
  finish_test
  return
}

do_execsql_test 1.0 {
  CREATE VIRTUAL TABLE t1 USING fts5(x);
  CREATE VIRTUAL TABLE t2 USING fts4(
      x, 
      tokenize=unicode61 "remove_diacritics=2"
  );
}

foreach {tn q res1 res2} {







|







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

ifcapable !fts3 {
  finish_test
  return
}

do_execsql_test 1.0 {
  CREATE VIRTUAL TABLE t1 USING fts4(x, tokenize=unicode61);
  CREATE VIRTUAL TABLE t2 USING fts4(
      x, 
      tokenize=unicode61 "remove_diacritics=2"
  );
}

foreach {tn q res1 res2} {
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
  } $res1
  do_execsql_test 1.$tn.2 {
    DELETE FROM t1;
    INSERT INTO t1(rowid, x) VALUES (1, $q);
    SELECT count(*) FROM t1 WHERE t1 MATCH 'Ha Noi'
  } $res1

  do_execsql_test 1.$tn.2 {
    DELETE FROM t2;
    INSERT INTO t2(rowid, x) VALUES (1, 'Ha Noi');
    SELECT count(*) FROM t2 WHERE t2 MATCH $q
  } $res2
  do_execsql_test 1.$tn.2 {
    DELETE FROM t2;
    INSERT INTO t2(rowid, x) VALUES (1, $q);
    SELECT count(*) FROM t2 WHERE t2 MATCH 'Ha Noi'
  } $res2
}

finish_test








|




|







<
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64

  } $res1
  do_execsql_test 1.$tn.2 {
    DELETE FROM t1;
    INSERT INTO t1(rowid, x) VALUES (1, $q);
    SELECT count(*) FROM t1 WHERE t1 MATCH 'Ha Noi'
  } $res1

  do_execsql_test 1.$tn.3 {
    DELETE FROM t2;
    INSERT INTO t2(rowid, x) VALUES (1, 'Ha Noi');
    SELECT count(*) FROM t2 WHERE t2 MATCH $q
  } $res2
  do_execsql_test 1.$tn.4 {
    DELETE FROM t2;
    INSERT INTO t2(rowid, x) VALUES (1, $q);
    SELECT count(*) FROM t2 WHERE t2 MATCH 'Ha Noi'
  } $res2
}

finish_test

Changes to test/join5.test.
263
264
265
266
267
268
269

270

271
272
273
274
275
276
277
278
  SELECT * FROM t1 LEFT JOIN t2 ON (
    t2.x = t1.x AND (t2.y=? OR (t2.y=? AND t2.z IS NOT NULL))
  );
} {
  QUERY PLAN
  |--SCAN TABLE t1
  `--MULTI-INDEX OR

     |--SEARCH TABLE t2 USING INDEX t2xy (x=? AND y=?)

     `--SEARCH TABLE t2 USING INDEX t2xy (x=? AND y=?)
}

do_execsql_test 7.3 {
  CREATE TABLE t3(x);

  CREATE TABLE t4(x, y, z);
  CREATE INDEX t4xy ON t4(x, y);







>
|
>
|







263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
  SELECT * FROM t1 LEFT JOIN t2 ON (
    t2.x = t1.x AND (t2.y=? OR (t2.y=? AND t2.z IS NOT NULL))
  );
} {
  QUERY PLAN
  |--SCAN TABLE t1
  `--MULTI-INDEX OR
     |--INDEX 1
     |  `--SEARCH TABLE t2 USING INDEX t2xy (x=? AND y=?)
     `--INDEX 2
        `--SEARCH TABLE t2 USING INDEX t2xy (x=? AND y=?)
}

do_execsql_test 7.3 {
  CREATE TABLE t3(x);

  CREATE TABLE t4(x, y, z);
  CREATE INDEX t4xy ON t4(x, y);
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/misc1.test.
740
741
742
743
744
745
746














747
748
  SELECT a,b,c FROM dup1;
} {1 2 3}
do_execsql_test misc1-27.1 {
  UPDATE dup1 SET a=7, b=8, c=9, a=10, b=11, c=12;
  SELECT a,b,c FROM dup1;
} {10 11 12}
















finish_test







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


740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
  SELECT a,b,c FROM dup1;
} {1 2 3}
do_execsql_test misc1-27.1 {
  UPDATE dup1 SET a=7, b=8, c=9, a=10, b=11, c=12;
  SELECT a,b,c FROM dup1;
} {10 11 12}

# 2018-12-20
#
# The Cursor.seekOp debugging value set incorrectly
# in OP_NotExists.
#
sqlite3 db :memory:
do_execsql_test misc1-28.0 {
  CREATE TABLE t1(x);
  CREATE UNIQUE INDEX t1x ON t1(x) WHERE x=1;
  INSERT OR ABORT INTO t1 DEFAULT VALUES;
  UPDATE OR REPLACE t1 SET x = 1;
  PRAGMA integrity_check;
  SELECT * FROM t1;
} {ok 1}

finish_test
Changes to test/permutations.test.
426
427
428
429
430
431
432
433

434




435
436



437
438
439
440
441
442
443
# Define the coverage related test suites:
#
#   coverage-wal
#
test_suite "coverage-wal" -description {
  Coverage tests for file wal.c.
} -files {
  wal.test       wal2.test     wal3.test       walmode.test    

  walbak.test    walhook.test  walcrash2.test  walcksum.test




  walfault.test  walbig.test   walnoshm.test
  wal5.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







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







426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
# Define the coverage related test suites:
#
#   coverage-wal
#
test_suite "coverage-wal" -description {
  Coverage tests for file wal.c.
} -files {
  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
Changes to test/rowvalue4.test.
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
do_eqp_test 5.1 {
  SELECT * FROM d2 WHERE 
    (a, b) IN (SELECT x, y FROM d1) AND
    (c) IN (SELECT y FROM d1)
} {
  QUERY PLAN
  |--SEARCH TABLE d2 USING INDEX d2ab (a=? AND b=?)
  |--LIST SUBQUERY
  |  `--SCAN TABLE d1
  `--LIST SUBQUERY
     `--SCAN TABLE d1
}

do_execsql_test 6.0 {
  CREATE TABLE e1(a, b, c, d, e);
  CREATE INDEX e1ab ON e1(a, b);
  CREATE INDEX e1cde ON e1(c, d, e);







|

|







231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
do_eqp_test 5.1 {
  SELECT * FROM d2 WHERE 
    (a, b) IN (SELECT x, y FROM d1) AND
    (c) IN (SELECT y FROM d1)
} {
  QUERY PLAN
  |--SEARCH TABLE d2 USING INDEX d2ab (a=? AND b=?)
  |--LIST SUBQUERY xxxxxx
  |  `--SCAN TABLE d1
  `--LIST SUBQUERY xxxxxx
     `--SCAN TABLE d1
}

do_execsql_test 6.0 {
  CREATE TABLE e1(a, b, c, d, e);
  CREATE INDEX e1ab ON e1(a, b);
  CREATE INDEX e1cde ON e1(c, d, e);
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
Changes to test/tkt-80ba201079.test.
106
107
108
109
110
111
112


113
114
115
116
117
118
119
             AND entry_id IN (SELECT change_id
                              FROM object_changes
                               WHERE obj_context = 'exported_pools'));
  }
} {300 object_change 2048}
do_test tkt-80ba2-201 {
  db eval {


    CREATE INDEX timeline_entry_id_idx on timeline(entry_id);
    SELECT entry_type,
           entry_types.name,
           entry_id
      FROM timeline JOIN entry_types ON entry_type = entry_types.id
     WHERE (entry_types.name = 'cli_command' AND entry_id=2114)
        OR (entry_types.name = 'object_change'







>
>







106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
             AND entry_id IN (SELECT change_id
                              FROM object_changes
                               WHERE obj_context = 'exported_pools'));
  }
} {300 object_change 2048}
do_test tkt-80ba2-201 {
  db eval {
PRAGMA vdbe_debug=on;
PRAGMA vdbe_addoptrace=on;
    CREATE INDEX timeline_entry_id_idx on timeline(entry_id);
    SELECT entry_type,
           entry_types.name,
           entry_id
      FROM timeline JOIN entry_types ON entry_type = entry_types.id
     WHERE (entry_types.name = 'cli_command' AND entry_id=2114)
        OR (entry_types.name = 'object_change'
Changes to test/triggerC.test.
1038
1039
1040
1041
1042
1043
1044















1045


  INSERT INTO x1 VALUES('go!');
}

do_execsql_test 15.2.2 { SELECT * FROM x2;       } {1 2 3 4}
do_execsql_test 15.2.3 { SELECT * FROM """x2"""; } {3 11 x y}
















finish_test








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

>
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061

  INSERT INTO x1 VALUES('go!');
}

do_execsql_test 15.2.2 { SELECT * FROM x2;       } {1 2 3 4}
do_execsql_test 15.2.3 { SELECT * FROM """x2"""; } {3 11 x y}

#-------------------------------------------------------------------------
# At one point queries such as the following were causing segfaults.
#
do_catchsql_test 16.1 {
  SELECT raise(ABORT, 'msg') FROM sqlite_master 
  UNION SELECT 1 
  ORDER BY raise(IGNORE);
} {1 {1st ORDER BY term does not match any column in the result set}}

do_catchsql_test 16.2 {
  SELECT count(*) FROM sqlite_master 
  GROUP BY raise(IGNORE) 
  HAVING raise(ABORT, 'msg');
} {1 {RAISE() may only be used within a trigger-program}}

finish_test

Changes to test/triggerF.test.
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
ifcapable {!trigger} {
  finish_test
  return
}


foreach {tn sql log} {
  1 { } { }

  2 { 
    CREATE TRIGGER trd AFTER DELETE ON t1 BEGIN
      INSERT INTO log VALUES(old.a || old.b || (SELECT count(*) FROM t1));
    END;
  } {1one2 2two1 3three1}








|







16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
ifcapable {!trigger} {
  finish_test
  return
}


foreach {tn sql log} {
  1 {} {}

  2 { 
    CREATE TRIGGER trd AFTER DELETE ON t1 BEGIN
      INSERT INTO log VALUES(old.a || old.b || (SELECT count(*) FROM t1));
    END;
  } {1one2 2two1 3three1}

Changes to test/unionvtab.test.
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
do_execsql_test 4.3.3 {
  SELECT * FROM sl WHERE rowid<=-9223372036854775808
} {
  -9223372036854775808 one
}
do_execsql_test 4.3.4 {
  SELECT * FROM sl WHERE rowid<-9223372036854775808
} { }

do_execsql_test 4.4.1 {
  SELECT * FROM sl WHERE rowid<9223372036854775807
} {
  -9223372036854775808 one -9223372036854775807 two -9223372036854775806 three
   9223372036854775805 four 9223372036854775806 five
}
do_execsql_test 4.4.2 {
  SELECT * FROM sl WHERE rowid<=9223372036854775807
} {
  -9223372036854775808 one -9223372036854775807 two -9223372036854775806 three
   9223372036854775805 four 9223372036854775806 five 9223372036854775807 six
}
do_execsql_test 4.4.3 {
  SELECT * FROM sl WHERE rowid>=9223372036854775807
} {
  9223372036854775807 six
}
do_execsql_test 4.4.4 {
  SELECT * FROM sl WHERE rowid>9223372036854775807
} { }

#-------------------------------------------------------------------------
# More than 8 source tables.
#
do_execsql_test 5.0 {
  CREATE TABLE c0(one, two INTEGER PRIMARY KEY);
  CREATE TABLE c1(one, two INTEGER PRIMARY KEY);







|




















|







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
do_execsql_test 4.3.3 {
  SELECT * FROM sl WHERE rowid<=-9223372036854775808
} {
  -9223372036854775808 one
}
do_execsql_test 4.3.4 {
  SELECT * FROM sl WHERE rowid<-9223372036854775808
} {}

do_execsql_test 4.4.1 {
  SELECT * FROM sl WHERE rowid<9223372036854775807
} {
  -9223372036854775808 one -9223372036854775807 two -9223372036854775806 three
   9223372036854775805 four 9223372036854775806 five
}
do_execsql_test 4.4.2 {
  SELECT * FROM sl WHERE rowid<=9223372036854775807
} {
  -9223372036854775808 one -9223372036854775807 two -9223372036854775806 three
   9223372036854775805 four 9223372036854775806 five 9223372036854775807 six
}
do_execsql_test 4.4.3 {
  SELECT * FROM sl WHERE rowid>=9223372036854775807
} {
  9223372036854775807 six
}
do_execsql_test 4.4.4 {
  SELECT * FROM sl WHERE rowid>9223372036854775807
} {}

#-------------------------------------------------------------------------
# More than 8 source tables.
#
do_execsql_test 5.0 {
  CREATE TABLE c0(one, two INTEGER PRIMARY KEY);
  CREATE TABLE c1(one, two INTEGER PRIMARY KEY);
Changes to test/vacuum-into.test.
61
62
63
64
65
66
67





















68
69
  CREATE TABLE t2(name TEXT);
  INSERT INTO t2 VALUES(':memory:');
  VACUUM main INTO (SELECT name FROM t2);
} {}
do_catchsql_test vacuum-into-310 {
  VACUUM INTO null;
} {1 {non-text filename}}






















finish_test







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


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
  CREATE TABLE t2(name TEXT);
  INSERT INTO t2 VALUES(':memory:');
  VACUUM main INTO (SELECT name FROM t2);
} {}
do_catchsql_test vacuum-into-310 {
  VACUUM INTO null;
} {1 {non-text filename}}
do_catchsql_test vacuum-into-320 {
  VACUUM INTO x;
} {1 {no such column: x}}
do_catchsql_test vacuum-into-330 {
  VACUUM INTO t1.nosuchcol;
} {1 {no such column: t1.nosuchcol}}
do_catchsql_test vacuum-into-340 {
  VACUUM INTO main.t1.nosuchcol;
} {1 {no such column: main.t1.nosuchcol}}

forcedelete test.db2
db func target target
proc target {} { return "test.db2" }
do_test vacuum-into-410 {
  execsql { VACUUM INTO target() }
  file exists test.db2
} 1
do_catchsql_test vacuum-into-420 {
  VACUUM INTO target2()
} {1 {no such function: target2}}


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
Added test/walvfs.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
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
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
# 2018 December 23
#
# 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/lock_common.tcl
source $testdir/malloc_common.tcl
source $testdir/wal_common.tcl
set testprefix walvfs

ifcapable !wal {finish_test ; return }

db close
testvfs tvfs 
tvfs script xSync
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 {
  PRAGMA auto_vacuum = 0;
  PRAGMA journal_mode = wal;
  PRAGMA synchronous = normal;
  CREATE TABLE t1(a, b, c);
  INSERT INTO t1 VALUES(1, 2, 3);
  INSERT INTO t1 VALUES(4, 5, 6);
  INSERT INTO t1 VALUES(7, 8, 9);
  PRAGMA wal_checkpoint;
} {wal 0 5 5}

set ::sync_count 0
do_test 1.1 {
  execsql { INSERT INTO t1 VALUES(10, 11, 12) }
  set ::sync_count
} 1

db close
tvfs devchar sequential
sqlite3 db test.db -vfs tvfs
do_execsql_test 1.2 {
  PRAGMA synchronous = normal;
  INSERT INTO t1 VALUES(13, 14, 15);
  INSERT INTO t1 VALUES(16, 17, 18);
  PRAGMA wal_checkpoint;
} {0 4 4}

set ::sync_count 0
do_test 1.3 {
  execsql { INSERT INTO t1 VALUES(10, 11, 12) }
  set ::sync_count
} 0

#-------------------------------------------------------------------------
# Test that "PRAGMA journal_size_limit" works in wal mode.
#
reset_db
do_execsql_test 2.0 {
  PRAGMA journal_size_limit = 10000;
  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;
} {10000 wal}
do_test 2.1 {
  expr [file size test.db-wal]>12000
} {1}
do_test 2.2 {
  execsql {
    PRAGMA wal_checkpoint;
    INSERT INTO t1 VALUES(randomblob(750));
  }
  file size test.db-wal
} {10000}
do_test 2.3 {
  execsql {
    PRAGMA journal_size_limit = 8000;
    PRAGMA wal_checkpoint;
    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 {
  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 filter xWrite
tvfs script xWrite
set ::cnt 2
proc xWrite {method file args} {
  if {[file tail $file]=="test.db"} {
    incr ::cnt -1
    if {$::cnt==0} {
      sqlite3_interrupt db
    }
  }
  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 {
    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;
  } db
} {wal}
db close

tvfs filter xShmMap
tvfs script xShmMap
proc xShmMap {method file args} { 
  return SQLITE_READONLY 
}
sqlite3 db test.db -vfs tvfs
do_catchsql_test 4.1 {
  SELECT count(*) FROM t1
} {1 {attempt to write a readonly database}}

set ::cnt 5
tvfs filter {xShmMap xShmLock}
proc xShmMap {method file name args} { 
  switch -- $method {
    xShmMap {  return SQLITE_READONLY }
    xShmLock {
      if {$args == "{0 1 lock shared}"} {
        incr ::cnt -1
        if {$::cnt>0} { return SQLITE_BUSY }
      }
    }
  }
  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/where7.test.
23349
23350
23351
23352
23353
23354
23355

23356

23357
23358
23359
23360
23361
23362
      AND t302.c3 > 1287603136
      AND (t301.c4 = 1407449685622784
           OR t301.c8 = 1407424651264000)
   ORDER BY t302.c5 LIMIT 200;
} {
  QUERY PLAN
  |--MULTI-INDEX OR

  |  |--SEARCH TABLE t301 USING COVERING INDEX t301_c4 (c4=?)

  |  `--SEARCH TABLE t301 USING INTEGER PRIMARY KEY (rowid=?)
  |--SEARCH TABLE t302 USING INDEX t302_c8_c3 (c8=? AND c3>?)
  `--USE TEMP B-TREE FOR ORDER BY
}

finish_test







>
|
>
|





23349
23350
23351
23352
23353
23354
23355
23356
23357
23358
23359
23360
23361
23362
23363
23364
      AND t302.c3 > 1287603136
      AND (t301.c4 = 1407449685622784
           OR t301.c8 = 1407424651264000)
   ORDER BY t302.c5 LIMIT 200;
} {
  QUERY PLAN
  |--MULTI-INDEX OR
  |  |--INDEX 1
  |  |  `--SEARCH TABLE t301 USING COVERING INDEX t301_c4 (c4=?)
  |  `--INDEX 2
  |     `--SEARCH TABLE t301 USING INTEGER PRIMARY KEY (rowid=?)
  |--SEARCH TABLE t302 USING INDEX t302_c8_c3 (c8=? AND c3>?)
  `--USE TEMP B-TREE FOR ORDER BY
}

finish_test
Changes to test/where9.test.
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
  do_eqp_test where9-3.1 {
    SELECT t2.a FROM t1, t2
    WHERE t1.a=80 AND ((t1.c=t2.c AND t1.d=t2.d) OR t1.f=t2.f)
  } [string map {"\n  " \n} {
    QUERY PLAN
    |--SEARCH TABLE t1 USING INTEGER PRIMARY KEY (rowid=?)
    `--MULTI-INDEX OR

       |--SEARCH TABLE t2 USING INDEX t2d (d=?)

       `--SEARCH TABLE t2 USING COVERING INDEX t2f (f=?)
  }]
  do_eqp_test where9-3.2 {
    SELECT coalesce(t2.a,9999)
    FROM t1 LEFT JOIN t2 ON (t1.c+1=t2.c AND t1.d=t2.d) OR (t1.f||'x')=t2.f
    WHERE t1.a=80
  } [string map {"\n  " \n} {
    QUERY PLAN
    |--SEARCH TABLE t1 USING INTEGER PRIMARY KEY (rowid=?)
    `--MULTI-INDEX OR

       |--SEARCH TABLE t2 USING INDEX t2d (d=?)

       `--SEARCH TABLE t2 USING COVERING INDEX t2f (f=?)
  }]
} 

# Make sure that INDEXED BY and multi-index OR clauses play well with
# one another.
#
do_test where9-4.1 {







>
|
>
|









>
|
>
|







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
  do_eqp_test where9-3.1 {
    SELECT t2.a FROM t1, t2
    WHERE t1.a=80 AND ((t1.c=t2.c AND t1.d=t2.d) OR t1.f=t2.f)
  } [string map {"\n  " \n} {
    QUERY PLAN
    |--SEARCH TABLE t1 USING INTEGER PRIMARY KEY (rowid=?)
    `--MULTI-INDEX OR
       |--INDEX 1
       |  `--SEARCH TABLE t2 USING INDEX t2d (d=?)
       `--INDEX 3
          `--SEARCH TABLE t2 USING COVERING INDEX t2f (f=?)
  }]
  do_eqp_test where9-3.2 {
    SELECT coalesce(t2.a,9999)
    FROM t1 LEFT JOIN t2 ON (t1.c+1=t2.c AND t1.d=t2.d) OR (t1.f||'x')=t2.f
    WHERE t1.a=80
  } [string map {"\n  " \n} {
    QUERY PLAN
    |--SEARCH TABLE t1 USING INTEGER PRIMARY KEY (rowid=?)
    `--MULTI-INDEX OR
       |--INDEX 1
       |  `--SEARCH TABLE t2 USING INDEX t2d (d=?)
       `--INDEX 2
          `--SEARCH TABLE t2 USING COVERING INDEX t2f (f=?)
  }]
} 

# Make sure that INDEXED BY and multi-index OR clauses play well with
# one another.
#
do_test where9-4.1 {
452
453
454
455
456
457
458

459

460
461
462
463
464
465
466
467
# the former is an equality test which is expected to return fewer rows.
#
do_eqp_test where9-5.1 {
  SELECT a FROM t1 WHERE b>1000 AND (c=31031 OR d IS NULL)
} {
  QUERY PLAN
  `--MULTI-INDEX OR

     |--SEARCH TABLE t1 USING INDEX t1c (c=?)

     `--SEARCH TABLE t1 USING INDEX t1d (d=?)
}

# In contrast, b=1000 is preferred over any OR-clause.
#
do_eqp_test where9-5.2 {
  SELECT a FROM t1 WHERE b=1000 AND (c=31031 OR d IS NULL)
} {SEARCH TABLE t1 USING INDEX t1b (b=?)}







>
|
>
|







456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
# the former is an equality test which is expected to return fewer rows.
#
do_eqp_test where9-5.1 {
  SELECT a FROM t1 WHERE b>1000 AND (c=31031 OR d IS NULL)
} {
  QUERY PLAN
  `--MULTI-INDEX OR
     |--INDEX 1
     |  `--SEARCH TABLE t1 USING INDEX t1c (c=?)
     `--INDEX 2
        `--SEARCH TABLE t1 USING INDEX t1d (d=?)
}

# In contrast, b=1000 is preferred over any OR-clause.
#
do_eqp_test where9-5.2 {
  SELECT a FROM t1 WHERE b=1000 AND (c=31031 OR d IS NULL)
} {SEARCH TABLE t1 USING INDEX t1b (b=?)}
Changes to test/whereI.test.
27
28
29
30
31
32
33

34

35
36
37
38
39
40
41
42
}

do_eqp_test 1.1 {
  SELECT a FROM t1 WHERE b='b' OR c='x'
} {
  QUERY PLAN
  `--MULTI-INDEX OR

     |--SEARCH TABLE t1 USING INDEX i1 (b=?)

     `--SEARCH TABLE t1 USING INDEX i2 (c=?)
}

do_execsql_test 1.2 {
  SELECT a FROM t1 WHERE b='b' OR c='x'
} {2 3}

do_execsql_test 1.3 {







>
|
>
|







27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
}

do_eqp_test 1.1 {
  SELECT a FROM t1 WHERE b='b' OR c='x'
} {
  QUERY PLAN
  `--MULTI-INDEX OR
     |--INDEX 1
     |  `--SEARCH TABLE t1 USING INDEX i1 (b=?)
     `--INDEX 2
        `--SEARCH TABLE t1 USING INDEX i2 (c=?)
}

do_execsql_test 1.2 {
  SELECT a FROM t1 WHERE b='b' OR c='x'
} {2 3}

do_execsql_test 1.3 {
57
58
59
60
61
62
63

64

65
66
67
68
69
70
71
72
}

do_eqp_test 2.1 {
  SELECT a FROM t2 WHERE b='b' OR c='x'
} {
  QUERY PLAN
  `--MULTI-INDEX OR

     |--SEARCH TABLE t2 USING INDEX i3 (b=?)

     `--SEARCH TABLE t2 USING INDEX i4 (c=?)
}

do_execsql_test 2.2 {
  SELECT a FROM t2 WHERE b='b' OR c='x'
} {ii iii}

do_execsql_test 2.3 {







>
|
>
|







59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
}

do_eqp_test 2.1 {
  SELECT a FROM t2 WHERE b='b' OR c='x'
} {
  QUERY PLAN
  `--MULTI-INDEX OR
     |--INDEX 1
     |  `--SEARCH TABLE t2 USING INDEX i3 (b=?)
     `--INDEX 2
        `--SEARCH TABLE t2 USING INDEX i4 (c=?)
}

do_execsql_test 2.2 {
  SELECT a FROM t2 WHERE b='b' OR c='x'
} {ii iii}

do_execsql_test 2.3 {
Changes to test/window1.test.
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
  1 1   2 2 
}

do_execsql_test 13.5 {
  SELECT a, rank() OVER(ORDER BY b) FROM t1
    INTERSECT 
  SELECT a, rank() OVER(ORDER BY b DESC) FROM t1;
} {
}

# 2018-12-06
# https://www.sqlite.org/src/info/f09fcd17810f65f7
# Assertion fault when window functions are used.
#
# Root cause is the query flattener invoking sqlite3ExprDup() on
# expressions that contain subqueries with window functions.  The







|
<







587
588
589
590
591
592
593
594

595
596
597
598
599
600
601
  1 1   2 2 
}

do_execsql_test 13.5 {
  SELECT a, rank() OVER(ORDER BY b) FROM t1
    INTERSECT 
  SELECT a, rank() OVER(ORDER BY b DESC) FROM t1;
} {}


# 2018-12-06
# https://www.sqlite.org/src/info/f09fcd17810f65f7
# Assertion fault when window functions are used.
#
# Root cause is the query flattener invoking sqlite3ExprDup() on
# expressions that contain subqueries with window functions.  The
616
617
618
619
620
621
622
623





















































624
  CREATE TABLE t2(c); INSERT INTO t2(c) VALUES(1);
  SELECT y, y+1, y+2 FROM (
    SELECT c IN (
      SELECT (row_number() OVER()) FROM t1
    ) AS y FROM t2
  );
} {1 2 3}






















































finish_test








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

615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
  CREATE TABLE t2(c); INSERT INTO t2(c) VALUES(1);
  SELECT y, y+1, y+2 FROM (
    SELECT c IN (
      SELECT (row_number() OVER()) FROM t1
    ) AS y FROM t2
  );
} {1 2 3}

# 2018-12-31
# https://www.sqlite.org/src/info/d0866b26f83e9c55
# Window function in correlated subquery causes assertion fault 
#
do_catchsql_test 15.0 {
  WITH t(id, parent) AS (
  SELECT CAST(1 AS INT), CAST(NULL AS INT)
  UNION ALL
  SELECT 2, NULL
  UNION ALL
  SELECT 3, 1
  UNION ALL
  SELECT 4, 1
  UNION ALL
  SELECT 5, 2
  UNION ALL
  SELECT 6, 2
  ), q AS (
  SELECT t.*, ROW_NUMBER() OVER (ORDER BY t.id) AS rn
    FROM t
   WHERE parent IS NULL
   UNION ALL
  SELECT t.*, ROW_NUMBER() OVER (ORDER BY t.id) AS rn
    FROM q
    JOIN t
      ON t.parent = q.id
  )
  SELECT *
    FROM q;
} {1 {cannot use window functions in recursive queries}}
do_execsql_test 15.1 {
  DROP TABLE IF EXISTS t1;
  DROP TABLE IF EXISTS t2;
  CREATE TABLE t1(x);
  INSERT INTO t1 VALUES('a'), ('b'), ('c');
  CREATE TABLE t2(a, b);
  INSERT INTO t2 VALUES('X', 1), ('X', 2), ('Y', 2), ('Y', 3);
  SELECT x, (
    SELECT sum(b)
      OVER (PARTITION BY a ROWS BETWEEN UNBOUNDED PRECEDING
                                    AND UNBOUNDED FOLLOWING)
    FROM t2 WHERE b<x
  ) FROM t1;
} {a 3 b 3 c 3}

do_execsql_test 15.2 {
  SELECT(
    WITH c AS(
      VALUES(1)
    ) SELECT '' FROM c,c
  ) x WHERE x+x;
} {}

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 test/with3.test.
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
     SELECT * FROM c, w2, w1
     WHERE c.id=w2.pk AND c.id=w1.pk;
} {
  QUERY PLAN
  |--MATERIALIZE xxxxxx
  |  |--SETUP
  |  |  |--SCAN CONSTANT ROW
  |  |  `--SCALAR SUBQUERY
  |  |     `--SCAN TABLE w2
  |  `--RECURSIVE STEP
  |     |--SCAN TABLE w1
  |     `--SCAN TABLE c
  |--SCAN SUBQUERY xxxxxx
  |--SEARCH TABLE w2 USING INTEGER PRIMARY KEY (rowid=?)
  `--SEARCH TABLE w1 USING INTEGER PRIMARY KEY (rowid=?)







|







116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
     SELECT * FROM c, w2, w1
     WHERE c.id=w2.pk AND c.id=w1.pk;
} {
  QUERY PLAN
  |--MATERIALIZE xxxxxx
  |  |--SETUP
  |  |  |--SCAN CONSTANT ROW
  |  |  `--SCALAR SUBQUERY xxxxxx
  |  |     `--SCAN TABLE w2
  |  `--RECURSIVE STEP
  |     |--SCAN TABLE w1
  |     `--SCAN TABLE c
  |--SCAN SUBQUERY xxxxxx
  |--SEARCH TABLE w2 USING INTEGER PRIMARY KEY (rowid=?)
  `--SEARCH TABLE w1 USING INTEGER PRIMARY KEY (rowid=?)
Changes to tool/dbtotxt.c.
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
** databases be constructed with "zeroblob()" rather than "randomblob()"
** used for filler content and with "PRAGMA secure_delete=ON" selected to
** zero-out deleted content.
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

 
/* Return true if the line is all zeros */
static int allZero(unsigned char *aLine){
  int i;
  for(i=0; i<16 && aLine[i]==0; i++){}
  return i==16;
}

int main(int argc, char **argv){
  int pgsz = 0;               /* page size */
  long szFile;                /* Size of the input file in bytes */
  FILE *in;                   /* Input file */
  int i, j;                   /* Loop counters */
  int nErr = 0;               /* Number of errors */
  const char *zInputFile = 0; /* Name of the input file */
  const char *zBaseName = 0;  /* Base name of the file */
  int lastPage = 0;           /* Last page number shown */
  int iPage;                  /* Current page number */
  unsigned char aLine[16];    /* A single line of the file */
  unsigned char aHdr[100];    /* File header */





  for(i=1; i<argc; i++){
    if( argv[i][0]=='-' ){
      const char *z = argv[i];
      z++;
      if( z[0]=='-' ) z++;
      if( strcmp(z,"pagesize")==0 ){
        i++;







>




















>
>
>
>
>







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
** databases be constructed with "zeroblob()" rather than "randomblob()"
** used for filler content and with "PRAGMA secure_delete=ON" selected to
** zero-out deleted content.
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
 
/* Return true if the line is all zeros */
static int allZero(unsigned char *aLine){
  int i;
  for(i=0; i<16 && aLine[i]==0; i++){}
  return i==16;
}

int main(int argc, char **argv){
  int pgsz = 0;               /* page size */
  long szFile;                /* Size of the input file in bytes */
  FILE *in;                   /* Input file */
  int i, j;                   /* Loop counters */
  int nErr = 0;               /* Number of errors */
  const char *zInputFile = 0; /* Name of the input file */
  const char *zBaseName = 0;  /* Base name of the file */
  int lastPage = 0;           /* Last page number shown */
  int iPage;                  /* Current page number */
  unsigned char aLine[16];    /* A single line of the file */
  unsigned char aHdr[100];    /* File header */
  unsigned char bShow[256];      /* Characters ok to display */
  memset(bShow, '.', sizeof(bShow));
  for(i=' '; i<='~'; i++){
    if( i!='{' && i!='}' && i!='"' && i!='\\' ) bShow[i] = i;
  }
  for(i=1; i<argc; i++){
    if( argv[i][0]=='-' ){
      const char *z = argv[i];
      z++;
      if( z[0]=='-' ) z++;
      if( strcmp(z,"pagesize")==0 ){
        i++;
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
    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 ){
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
      printf("| page %d offset %d\n", iPage, (iPage-1)*pgsz);
      lastPage = iPage;
    }
    printf("|  %5d:", i-(iPage-1)*pgsz);
    for(j=0; j<16; j++) printf(" %02x", aLine[j]);
    printf("   ");
    for(j=0; j<16; j++){
      char c = aLine[j];
      fputc(c>=0x20 && c<=0x7e ? c : '.', stdout);
    }
    fputc('\n', stdout);
  }
  fclose(in);
  printf("| end %s\n", zBaseName);
  return 0;
}







|
|







131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
      printf("| page %d offset %d\n", iPage, (iPage-1)*pgsz);
      lastPage = iPage;
    }
    printf("|  %5d:", i-(iPage-1)*pgsz);
    for(j=0; j<16; j++) printf(" %02x", aLine[j]);
    printf("   ");
    for(j=0; j<16; j++){
      unsigned char c = (unsigned char)aLine[j];
      fputc( bShow[c], stdout);
    }
    fputc('\n', stdout);
  }
  fclose(in);
  printf("| end %s\n", zBaseName);
  return 0;
}