/ Check-in [9c685171]
Login

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

Overview
Comment:Add support for read-only shadow tables on virtual tables. Added the SQLITE_DEFAULT_DEFENSIVE compile-time option that can put SQLite in defensive mode by default.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256:9c685171c4d7ae8615d1489c9621aba79fe4ef1f0e56b75823b88c3e70d127df
User & Date: drh 2018-11-10 18:23:32
Context
2018-11-12
13:20
Fix a use-after-free problem in the fts5vocab virtual table. check-in: ac69d169 user: dan tags: trunk
2018-11-10
20:07
Merge the read-only shadow table and defensive mode enhancments from trunk. Leaf check-in: 977fc44e user: drh tags: apple-osx
18:23
Add support for read-only shadow tables on virtual tables. Added the SQLITE_DEFAULT_DEFENSIVE compile-time option that can put SQLite in defensive mode by default. check-in: 9c685171 user: drh tags: trunk
17:37
Add the "changesetfuzz" program. For fuzzing changeset blobs. check-in: 2bae0e7c user: dan tags: trunk
04:14
Remove a NEVER() that is reachable after all. Reverts checkin [9292d3351c40339]. Closed-Leaf check-in: c5dc7fb8 user: drh tags: read-only-shadow
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to ext/expert/sqlite3expert.c.

640
641
642
643
644
645
646

647
648
649
650
651
652
653
    0,                            /* xCommit - commit transaction */
    0,                            /* xRollback - rollback transaction */
    0,                            /* xFindFunction - function overloading */
    0,                            /* xRename - rename the table */
    0,                            /* xSavepoint */
    0,                            /* xRelease */
    0,                            /* xRollbackTo */

  };

  return sqlite3_create_module(p->dbv, "expert", &expertModule, (void*)p);
}
/*
** End of virtual table implementation.
*************************************************************************/







>







640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
    0,                            /* xCommit - commit transaction */
    0,                            /* xRollback - rollback transaction */
    0,                            /* xFindFunction - function overloading */
    0,                            /* xRename - rename the table */
    0,                            /* xSavepoint */
    0,                            /* xRelease */
    0,                            /* xRollbackTo */
    0,                            /* xShadowName */
  };

  return sqlite3_create_module(p->dbv, "expert", &expertModule, (void*)p);
}
/*
** End of virtual table implementation.
*************************************************************************/

Changes to ext/fts3/fts3.c.

3841
3842
3843
3844
3845
3846
3847
3848















3849
3850
3851
3852
3853
3854
3855
3856
3857
....
3866
3867
3868
3869
3870
3871
3872

3873
3874
3875
3876
3877
3878
3879
  UNUSED_PARAMETER(iSavepoint);
  assert( p->inTransaction );
  assert( p->mxSavepoint >= iSavepoint );
  TESTONLY( p->mxSavepoint = iSavepoint );
  sqlite3Fts3PendingTermsClear(p);
  return SQLITE_OK;
}
















static const sqlite3_module fts3Module = {
  /* iVersion      */ 2,
  /* xCreate       */ fts3CreateMethod,
  /* xConnect      */ fts3ConnectMethod,
  /* xBestIndex    */ fts3BestIndexMethod,
  /* xDisconnect   */ fts3DisconnectMethod,
  /* xDestroy      */ fts3DestroyMethod,
  /* xOpen         */ fts3OpenMethod,
  /* xClose        */ fts3CloseMethod,
................................................................................
  /* xCommit       */ fts3CommitMethod,
  /* xRollback     */ fts3RollbackMethod,
  /* xFindFunction */ fts3FindFunctionMethod,
  /* xRename */       fts3RenameMethod,
  /* xSavepoint    */ fts3SavepointMethod,
  /* xRelease      */ fts3ReleaseMethod,
  /* xRollbackTo   */ fts3RollbackToMethod,

};

/*
** This function is registered as the module destructor (called when an
** FTS3 enabled database connection is closed). It frees the memory
** allocated for the tokenizer hash table.
*/








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

|







 







>







3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
....
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
  UNUSED_PARAMETER(iSavepoint);
  assert( p->inTransaction );
  assert( p->mxSavepoint >= iSavepoint );
  TESTONLY( p->mxSavepoint = iSavepoint );
  sqlite3Fts3PendingTermsClear(p);
  return SQLITE_OK;
}

/*
** Return true if zName is the extension on one of the shadow tables used
** by this module.
*/
static int fts3ShadowName(const char *zName){
  static const char *azName[] = {
    "content", "docsize", "segdir", "segments", "stat", 
  };
  unsigned int i;
  for(i=0; i<sizeof(azName)/sizeof(azName[0]); i++){
    if( sqlite3_stricmp(zName, azName[i])==0 ) return 1;
  }
  return 0;
}

static const sqlite3_module fts3Module = {
  /* iVersion      */ 3,
  /* xCreate       */ fts3CreateMethod,
  /* xConnect      */ fts3ConnectMethod,
  /* xBestIndex    */ fts3BestIndexMethod,
  /* xDisconnect   */ fts3DisconnectMethod,
  /* xDestroy      */ fts3DestroyMethod,
  /* xOpen         */ fts3OpenMethod,
  /* xClose        */ fts3CloseMethod,
................................................................................
  /* xCommit       */ fts3CommitMethod,
  /* xRollback     */ fts3RollbackMethod,
  /* xFindFunction */ fts3FindFunctionMethod,
  /* xRename */       fts3RenameMethod,
  /* xSavepoint    */ fts3SavepointMethod,
  /* xRelease      */ fts3ReleaseMethod,
  /* xRollbackTo   */ fts3RollbackToMethod,
  /* xShadowName   */ fts3ShadowName,
};

/*
** This function is registered as the module destructor (called when an
** FTS3 enabled database connection is closed). It frees the memory
** allocated for the tokenizer hash table.
*/

Changes to ext/fts3/fts3_aux.c.

535
536
537
538
539
540
541
542

543
544
545
546
547
548
549
550
     0,                           /* xSync         */
     0,                           /* xCommit       */
     0,                           /* xRollback     */
     0,                           /* xFindFunction */
     0,                           /* xRename       */
     0,                           /* xSavepoint    */
     0,                           /* xRelease      */
     0                            /* xRollbackTo   */

  };
  int rc;                         /* Return code */

  rc = sqlite3_create_module(db, "fts4aux", &fts3aux_module, 0);
  return rc;
}

#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */







|
>








535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
     0,                           /* xSync         */
     0,                           /* xCommit       */
     0,                           /* xRollback     */
     0,                           /* xFindFunction */
     0,                           /* xRename       */
     0,                           /* xSavepoint    */
     0,                           /* xRelease      */
     0,                           /* xRollbackTo   */
     0                            /* xShadowName   */
  };
  int rc;                         /* Return code */

  rc = sqlite3_create_module(db, "fts4aux", &fts3aux_module, 0);
  return rc;
}

#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */

Changes to ext/fts3/fts3_term.c.

357
358
359
360
361
362
363
364

365
366
367
368
369
370
371
372
373
     0,                           /* xSync         */
     0,                           /* xCommit       */
     0,                           /* xRollback     */
     0,                           /* xFindFunction */
     0,                           /* xRename       */
     0,                           /* xSavepoint    */
     0,                           /* xRelease      */
     0                            /* xRollbackTo   */

  };
  int rc;                         /* Return code */

  rc = sqlite3_create_module(db, "fts4term", &fts3term_module, 0);
  return rc;
}

#endif
#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */







|
>









357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
     0,                           /* xSync         */
     0,                           /* xCommit       */
     0,                           /* xRollback     */
     0,                           /* xFindFunction */
     0,                           /* xRename       */
     0,                           /* xSavepoint    */
     0,                           /* xRelease      */
     0,                           /* xRollbackTo   */
     0                            /* xShadowName   */
  };
  int rc;                         /* Return code */

  rc = sqlite3_create_module(db, "fts4term", &fts3term_module, 0);
  return rc;
}

#endif
#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */

Changes to ext/fts3/fts3_tokenize_vtab.c.

439
440
441
442
443
444
445
446

447
448
449
450
451
452
453
454
     0,                           /* xSync         */
     0,                           /* xCommit       */
     0,                           /* xRollback     */
     0,                           /* xFindFunction */
     0,                           /* xRename       */
     0,                           /* xSavepoint    */
     0,                           /* xRelease      */
     0                            /* xRollbackTo   */

  };
  int rc;                         /* Return code */

  rc = sqlite3_create_module(db, "fts3tokenize", &fts3tok_module, (void*)pHash);
  return rc;
}

#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */







|
>








439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
     0,                           /* xSync         */
     0,                           /* xCommit       */
     0,                           /* xRollback     */
     0,                           /* xFindFunction */
     0,                           /* xRename       */
     0,                           /* xSavepoint    */
     0,                           /* xRelease      */
     0,                           /* xRollbackTo   */
     0                            /* xShadowName   */
  };
  int rc;                         /* Return code */

  rc = sqlite3_create_module(db, "fts3tokenize", &fts3tok_module, (void*)pHash);
  return rc;
}

#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */

Changes to ext/fts5/fts5_main.c.

2640
2641
2642
2643
2644
2645
2646















2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
....
2666
2667
2668
2669
2670
2671
2672

2673
2674
2675
2676
2677
2678
2679
  int nArg,                       /* Number of args */
  sqlite3_value **apUnused        /* Function arguments */
){
  assert( nArg==0 );
  UNUSED_PARAM2(nArg, apUnused);
  sqlite3_result_text(pCtx, "--FTS5-SOURCE-ID--", -1, SQLITE_TRANSIENT);
}
















static int fts5Init(sqlite3 *db){
  static const sqlite3_module fts5Mod = {
    /* iVersion      */ 2,
    /* xCreate       */ fts5CreateMethod,
    /* xConnect      */ fts5ConnectMethod,
    /* xBestIndex    */ fts5BestIndexMethod,
    /* xDisconnect   */ fts5DisconnectMethod,
    /* xDestroy      */ fts5DestroyMethod,
    /* xOpen         */ fts5OpenMethod,
    /* xClose        */ fts5CloseMethod,
................................................................................
    /* xCommit       */ fts5CommitMethod,
    /* xRollback     */ fts5RollbackMethod,
    /* xFindFunction */ fts5FindFunctionMethod,
    /* xRename       */ fts5RenameMethod,
    /* xSavepoint    */ fts5SavepointMethod,
    /* xRelease      */ fts5ReleaseMethod,
    /* xRollbackTo   */ fts5RollbackToMethod,

  };

  int rc;
  Fts5Global *pGlobal = 0;

  pGlobal = (Fts5Global*)sqlite3_malloc(sizeof(Fts5Global));
  if( pGlobal==0 ){







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



|







 







>







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
....
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
  int nArg,                       /* Number of args */
  sqlite3_value **apUnused        /* Function arguments */
){
  assert( nArg==0 );
  UNUSED_PARAM2(nArg, apUnused);
  sqlite3_result_text(pCtx, "--FTS5-SOURCE-ID--", -1, SQLITE_TRANSIENT);
}

/*
** Return true if zName is the extension on one of the shadow tables used
** by this module.
*/
static int fts5ShadowName(const char *zName){
  static const char *azName[] = {
    "config", "content", "data", "docsize", "idx"
  };
  unsigned int i;
  for(i=0; i<sizeof(azName)/sizeof(azName[0]); i++){
    if( sqlite3_stricmp(zName, azName[i])==0 ) return 1;
  }
  return 0;
}

static int fts5Init(sqlite3 *db){
  static const sqlite3_module fts5Mod = {
    /* iVersion      */ 3,
    /* xCreate       */ fts5CreateMethod,
    /* xConnect      */ fts5ConnectMethod,
    /* xBestIndex    */ fts5BestIndexMethod,
    /* xDisconnect   */ fts5DisconnectMethod,
    /* xDestroy      */ fts5DestroyMethod,
    /* xOpen         */ fts5OpenMethod,
    /* xClose        */ fts5CloseMethod,
................................................................................
    /* xCommit       */ fts5CommitMethod,
    /* xRollback     */ fts5RollbackMethod,
    /* xFindFunction */ fts5FindFunctionMethod,
    /* xRename       */ fts5RenameMethod,
    /* xSavepoint    */ fts5SavepointMethod,
    /* xRelease      */ fts5ReleaseMethod,
    /* xRollbackTo   */ fts5RollbackToMethod,
    /* xShadowName   */ fts5ShadowName
  };

  int rc;
  Fts5Global *pGlobal = 0;

  pGlobal = (Fts5Global*)sqlite3_malloc(sizeof(Fts5Global));
  if( pGlobal==0 ){

Changes to ext/fts5/fts5_test_tok.c.

467
468
469
470
471
472
473
474

475
476
477
478
479
480
481
482
     0,                           /* xSync         */
     0,                           /* xCommit       */
     0,                           /* xRollback     */
     0,                           /* xFindFunction */
     0,                           /* xRename       */
     0,                           /* xSavepoint    */
     0,                           /* xRelease      */
     0                            /* xRollbackTo   */

  };
  int rc;                         /* Return code */

  rc = sqlite3_create_module(db, "fts5tokenize", &fts5tok_module, (void*)pApi);
  return rc;
}

#endif /* defined(SQLITE_TEST) && defined(SQLITE_ENABLE_FTS5) */







|
>








467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
     0,                           /* xSync         */
     0,                           /* xCommit       */
     0,                           /* xRollback     */
     0,                           /* xFindFunction */
     0,                           /* xRename       */
     0,                           /* xSavepoint    */
     0,                           /* xRelease      */
     0,                           /* xRollbackTo   */
     0                            /* xShadowName   */
  };
  int rc;                         /* Return code */

  rc = sqlite3_create_module(db, "fts5tokenize", &fts5tok_module, (void*)pApi);
  return rc;
}

#endif /* defined(SQLITE_TEST) && defined(SQLITE_ENABLE_FTS5) */

Changes to ext/fts5/fts5_vocab.c.

751
752
753
754
755
756
757

758
759
760
761
762
763
764
    /* xCommit       */ 0,
    /* xRollback     */ 0,
    /* xFindFunction */ 0,
    /* xRename       */ 0,
    /* xSavepoint    */ 0,
    /* xRelease      */ 0,
    /* xRollbackTo   */ 0,

  };
  void *p = (void*)pGlobal;

  return sqlite3_create_module_v2(db, "fts5vocab", &fts5Vocab, p, 0);
}









>





<
<
751
752
753
754
755
756
757
758
759
760
761
762
763


    /* xCommit       */ 0,
    /* xRollback     */ 0,
    /* xFindFunction */ 0,
    /* xRename       */ 0,
    /* xSavepoint    */ 0,
    /* xRelease      */ 0,
    /* xRollbackTo   */ 0,
    /* xShadowName   */ 0
  };
  void *p = (void*)pGlobal;

  return sqlite3_create_module_v2(db, "fts5vocab", &fts5Vocab, p, 0);
}


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

405
406
407
408
409
410
411

412
413
414
415
416
417
418
  }
  set nRow
} {200}

do_execsql_test 15.0 {
  INSERT INTO t1(t1) VALUES('integrity-check');
}

do_execsql_test 15.1 {
  UPDATE t1_content SET c1 = 'xyz xyz xyz xyz xyz abc' WHERE rowid = 1;
}
do_catchsql_test 15.2 {
  INSERT INTO t1(t1) VALUES('integrity-check');
} {1 {database disk image is malformed}}








>







405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
  }
  set nRow
} {200}

do_execsql_test 15.0 {
  INSERT INTO t1(t1) VALUES('integrity-check');
}
sqlite3_db_config db DEFENSIVE 0
do_execsql_test 15.1 {
  UPDATE t1_content SET c1 = 'xyz xyz xyz xyz xyz abc' WHERE rowid = 1;
}
do_catchsql_test 15.2 {
  INSERT INTO t1(t1) VALUES('integrity-check');
} {1 {database disk image is malformed}}

Changes to ext/fts5/test/fts5connect.test.

240
241
242
243
244
245
246
247

  do_execsql_test 4.$tn.3 {
    INSERT INTO ft3(ft3) VALUES('integrity-check');
  }
}

finish_test








<
240
241
242
243
244
245
246


  do_execsql_test 4.$tn.3 {
    INSERT INTO ft3(ft3) VALUES('integrity-check');
  }
}

finish_test

Changes to ext/fts5/test/fts5corrupt.test.

37
38
39
40
41
42
43

44
45
46
47
48
49
50
51
52

53
54
55
56
57
58
59
..
85
86
87
88
89
90
91
92
93
94
95
96
97
98
  fts5_level_segs t1
} {1}
db_save

do_execsql_test 1.2 { INSERT INTO t1(t1) VALUES('integrity-check') }
set segid [lindex [fts5_level_segids t1] 0]


do_test 1.3 {
  execsql {
    DELETE FROM t1_data WHERE rowid = fts5_rowid('segment', $segid, 4);
  }
  catchsql { INSERT INTO t1(t1) VALUES('integrity-check') }
} {1 {database disk image is malformed}}

do_test 1.4 {
  db_restore_and_reopen

  execsql {
    UPDATE t1_data set block = X'00000000' || substr(block, 5) WHERE
    rowid = fts5_rowid('segment', $segid, 4);
  }
  catchsql { INSERT INTO t1(t1) VALUES('integrity-check') }
} {1 {database disk image is malformed}}

................................................................................
  INSERT INTO t3 VALUES('three o');
  INSERT INTO t3 VALUES('four e');
  INSERT INTO t3 VALUES('five o');
}
do_execsql_test 3.1 {
  SELECT * FROM t3 WHERE t3 MATCH 'o'
} {{one o} {three o} {five o}}

do_catchsql_test 3.1 {
  DELETE FROM t3_content WHERE rowid = 3;
  SELECT * FROM t3 WHERE t3 MATCH 'o';
} {1 {database disk image is malformed}}

finish_test







>









>







 







|






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
..
87
88
89
90
91
92
93
94
95
96
97
98
99
100
  fts5_level_segs t1
} {1}
db_save

do_execsql_test 1.2 { INSERT INTO t1(t1) VALUES('integrity-check') }
set segid [lindex [fts5_level_segids t1] 0]

sqlite3_db_config db DEFENSIVE 0
do_test 1.3 {
  execsql {
    DELETE FROM t1_data WHERE rowid = fts5_rowid('segment', $segid, 4);
  }
  catchsql { INSERT INTO t1(t1) VALUES('integrity-check') }
} {1 {database disk image is malformed}}

do_test 1.4 {
  db_restore_and_reopen
  sqlite3_db_config db DEFENSIVE 0
  execsql {
    UPDATE t1_data set block = X'00000000' || substr(block, 5) WHERE
    rowid = fts5_rowid('segment', $segid, 4);
  }
  catchsql { INSERT INTO t1(t1) VALUES('integrity-check') }
} {1 {database disk image is malformed}}

................................................................................
  INSERT INTO t3 VALUES('three o');
  INSERT INTO t3 VALUES('four e');
  INSERT INTO t3 VALUES('five o');
}
do_execsql_test 3.1 {
  SELECT * FROM t3 WHERE t3 MATCH 'o'
} {{one o} {three o} {five o}}
sqlite3_db_config db DEFENSIVE 0
do_catchsql_test 3.1 {
  DELETE FROM t3_content WHERE rowid = 3;
  SELECT * FROM t3 WHERE t3 MATCH 'o';
} {1 {database disk image is malformed}}

finish_test

Changes to ext/fts5/test/fts5corrupt2.test.

95
96
97
98
99
100
101

102
103
104
105
106
107
108
...
244
245
246
247
248
249
250

251
252
253
254
255
256
257
# Also tested is that "MATCH 'x*'" does not crash and sometimes reports
# corruption. It may not report the db as corrupt because truncating the
# final leaf to some sizes may create a valid leaf page.
#
set lrowid [db one {SELECT max(rowid) FROM t1_data WHERE (rowid & $mask)=0}] 
set nbyte [db one {SELECT length(block) FROM t1_data WHERE rowid=$lrowid}]
set all [db eval {SELECT rowid FROM t1}]

for {set i [expr $nbyte-2]} {$i>=0} {incr i -1} {
  do_execsql_test 2.$i.1 {
    BEGIN;
      UPDATE t1_data SET block = substr(block, 1, $i) WHERE rowid=$lrowid;
  }

  do_catchsql_test 2.$i.2 {
................................................................................

    execsql ROLLBACK
  }
}

#--------------------------------------------------------------------
reset_db

do_execsql_test 6.1 {
  CREATE VIRTUAL TABLE x5 USING fts5(tt);
  INSERT INTO x5 VALUES('a');
  INSERT INTO x5 VALUES('a a');
  INSERT INTO x5 VALUES('a a a');
  INSERT INTO x5 VALUES('a a a a');








>







 







>







95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
...
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
# Also tested is that "MATCH 'x*'" does not crash and sometimes reports
# corruption. It may not report the db as corrupt because truncating the
# final leaf to some sizes may create a valid leaf page.
#
set lrowid [db one {SELECT max(rowid) FROM t1_data WHERE (rowid & $mask)=0}] 
set nbyte [db one {SELECT length(block) FROM t1_data WHERE rowid=$lrowid}]
set all [db eval {SELECT rowid FROM t1}]
sqlite3_db_config db DEFENSIVE 0
for {set i [expr $nbyte-2]} {$i>=0} {incr i -1} {
  do_execsql_test 2.$i.1 {
    BEGIN;
      UPDATE t1_data SET block = substr(block, 1, $i) WHERE rowid=$lrowid;
  }

  do_catchsql_test 2.$i.2 {
................................................................................

    execsql ROLLBACK
  }
}

#--------------------------------------------------------------------
reset_db
sqlite3_db_config db DEFENSIVE 0
do_execsql_test 6.1 {
  CREATE VIRTUAL TABLE x5 USING fts5(tt);
  INSERT INTO x5 VALUES('a');
  INSERT INTO x5 VALUES('a a');
  INSERT INTO x5 VALUES('a a a');
  INSERT INTO x5 VALUES('a a a a');

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

47
48
49
50
51
52
53

54
55
56
57
58
59
60
..
82
83
84
85
86
87
88

89
90
91
92
93
94
95
...
154
155
156
157
158
159
160

161
162
163
164
165
166
167
...
178
179
180
181
182
183
184

185
186
187
188
189
190
191
...
253
254
255
256
257
258
259

260
261
262
263
264
265
266
...
269
270
271
272
273
274
275

276
277
278
279
280
281
282
...
284
285
286
287
288
289
290

291
292
293
294
295
296
297
...
358
359
360
361
362
363
364

365
366
367
368
369
370
371
...
379
380
381
382
383
384
385

386
387
388
389
390
391
392
  set rowid [db one {
    SELECT max(rowid) FROM t1_data WHERE ((rowid>>31) & 0x0F)==1
  }]
  set L [db one {SELECT length(block) FROM t1_data WHERE rowid = $rowid}]
  set {} {}
} {} 


for {set i 0} {$i < $L} {incr i} {
  do_test 1.2.$i {
    catchsql {
      BEGIN;
      UPDATE t1_data SET block = substr(block, 1, $i) WHERE id = $rowid;
      INSERT INTO t1(t1) VALUES('integrity-check');
    }
................................................................................


#-------------------------------------------------------------------------
# Test that missing leaf pages are recognized as corruption.
#
reset_db
do_test 3.0 { create_t1 } {}


do_execsql_test 3.1 {
  SELECT count(*) FROM t1_data;
} {105}

proc do_3_test {tn} {
  set i 0
................................................................................

do_3_test 3.10

#-------------------------------------------------------------------------
# Test that segments that end unexpectedly are identified as corruption.
#
reset_db

do_test 4.0 {
  execsql { 
    CREATE VIRTUAL TABLE t1 USING fts5(x);
    INSERT INTO t1(t1, rank) VALUES('pgsz', 32);
  }
  for {set i 0} {$i < 100} {incr i} {
    set rnd [expr int(rand() * 100)]
................................................................................
  set end [lindex $var end]
  if {$end<=$i} break
  lset var end [expr $end - $i]
  set struct [binary format c* $var]

  db close
  sqlite3 db test.db


  db eval {
    BEGIN;
    UPDATE t1_data SET block = $struct WHERE id=10;
  }
  do_test 4.1.$i {
    incr nErr [catch { db eval { SELECT rowid FROM t1 WHERE t1 MATCH 'x*' } }]
................................................................................
    catch { db eval ROLLBACK }
  }
}

#------------------------------------------------------------------------
#
reset_db

do_execsql_test 6.1.0 {
  CREATE VIRTUAL TABLE t1 USING fts5(a);
  INSERT INTO t1 VALUES('bbbbb ccccc');
  SELECT quote(block) FROM t1_data WHERE rowid>100;
} {X'000000180630626262626201020201056363636363010203040A'}
do_execsql_test 6.1.1 {
  UPDATE t1_data SET block = 
................................................................................
}
do_catchsql_test 6.1.2 {
  INSERT INTO t1(t1) VALUES('integrity-check');
} {1 {database disk image is malformed}}

#-------
reset_db

do_execsql_test 6.2.0 {
  CREATE VIRTUAL TABLE t1 USING fts5(a);
  INSERT INTO t1(t1, rank) VALUES('pgsz', 32);
  INSERT INTO t1 VALUES('aa bb cc dd ee');
  SELECT pgno, quote(term) FROM t1_idx;
} {2 X'' 4 X'3064'}
do_execsql_test 6.2.1 {
................................................................................
}
do_catchsql_test 6.2.2 {
  INSERT INTO t1(t1) VALUES('integrity-check');
} {1 {database disk image is malformed}}

#-------
reset_db

do_execsql_test 6.3.0 {
  CREATE VIRTUAL TABLE t1 USING fts5(a);
  INSERT INTO t1 VALUES('abc abcdef abcdefghi');
  SELECT quote(block) FROM t1_data WHERE id>100;
}    {X'0000001C043061626301020204036465660102030703676869010204040808'}
do_execsql_test 6.3.1 {
  BEGIN;
................................................................................
    INSERT INTO t5 VALUES( rnddoc(10000) );
    INSERT INTO t5 VALUES( rnddoc(10000) );
    INSERT INTO t5 VALUES( rnddoc(10000) );
    INSERT INTO t5(t5) VALUES('optimize');
  }
} {}


do_test 7.1 {
  foreach i [db eval { SELECT rowid FROM t5_data WHERE rowid>100 }] {
    db eval BEGIN  
    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  
................................................................................
#
reset_db
do_execsql_test 8.1 {
  CREATE VIRTUAL TABLE t1 USING fts5(x, y);
  INSERT INTO t1 VALUES('one', 'two');
}


do_test 9.1.1 {
  set    blob "12345678"    ;# cookie
  append blob "0105"        ;# 1 level, total of 5 segments
  append blob "06"          ;# write counter
  append blob "0002"        ;# first level has 0 segments merging, 2 other.
  append blob "450108"      ;# first segment
  execsql "REPLACE INTO t1_data VALUES(10, X'$blob')"







>







 







>







 







>







 







>







 







>







 







>







 







>







 







>







 







>







47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
..
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
...
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
...
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
...
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
...
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
...
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
...
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
...
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
  set rowid [db one {
    SELECT max(rowid) FROM t1_data WHERE ((rowid>>31) & 0x0F)==1
  }]
  set L [db one {SELECT length(block) FROM t1_data WHERE rowid = $rowid}]
  set {} {}
} {} 

sqlite3_db_config db DEFENSIVE 0
for {set i 0} {$i < $L} {incr i} {
  do_test 1.2.$i {
    catchsql {
      BEGIN;
      UPDATE t1_data SET block = substr(block, 1, $i) WHERE id = $rowid;
      INSERT INTO t1(t1) VALUES('integrity-check');
    }
................................................................................


#-------------------------------------------------------------------------
# Test that missing leaf pages are recognized as corruption.
#
reset_db
do_test 3.0 { create_t1 } {}
sqlite3_db_config db DEFENSIVE 0

do_execsql_test 3.1 {
  SELECT count(*) FROM t1_data;
} {105}

proc do_3_test {tn} {
  set i 0
................................................................................

do_3_test 3.10

#-------------------------------------------------------------------------
# Test that segments that end unexpectedly are identified as corruption.
#
reset_db
sqlite3_db_config db DEFENSIVE 0
do_test 4.0 {
  execsql { 
    CREATE VIRTUAL TABLE t1 USING fts5(x);
    INSERT INTO t1(t1, rank) VALUES('pgsz', 32);
  }
  for {set i 0} {$i < 100} {incr i} {
    set rnd [expr int(rand() * 100)]
................................................................................
  set end [lindex $var end]
  if {$end<=$i} break
  lset var end [expr $end - $i]
  set struct [binary format c* $var]

  db close
  sqlite3 db test.db
  sqlite3_db_config db DEFENSIVE 0

  db eval {
    BEGIN;
    UPDATE t1_data SET block = $struct WHERE id=10;
  }
  do_test 4.1.$i {
    incr nErr [catch { db eval { SELECT rowid FROM t1 WHERE t1 MATCH 'x*' } }]
................................................................................
    catch { db eval ROLLBACK }
  }
}

#------------------------------------------------------------------------
#
reset_db
sqlite3_db_config db DEFENSIVE 0
do_execsql_test 6.1.0 {
  CREATE VIRTUAL TABLE t1 USING fts5(a);
  INSERT INTO t1 VALUES('bbbbb ccccc');
  SELECT quote(block) FROM t1_data WHERE rowid>100;
} {X'000000180630626262626201020201056363636363010203040A'}
do_execsql_test 6.1.1 {
  UPDATE t1_data SET block = 
................................................................................
}
do_catchsql_test 6.1.2 {
  INSERT INTO t1(t1) VALUES('integrity-check');
} {1 {database disk image is malformed}}

#-------
reset_db
sqlite3_db_config db DEFENSIVE 0
do_execsql_test 6.2.0 {
  CREATE VIRTUAL TABLE t1 USING fts5(a);
  INSERT INTO t1(t1, rank) VALUES('pgsz', 32);
  INSERT INTO t1 VALUES('aa bb cc dd ee');
  SELECT pgno, quote(term) FROM t1_idx;
} {2 X'' 4 X'3064'}
do_execsql_test 6.2.1 {
................................................................................
}
do_catchsql_test 6.2.2 {
  INSERT INTO t1(t1) VALUES('integrity-check');
} {1 {database disk image is malformed}}

#-------
reset_db
sqlite3_db_config db DEFENSIVE 0
do_execsql_test 6.3.0 {
  CREATE VIRTUAL TABLE t1 USING fts5(a);
  INSERT INTO t1 VALUES('abc abcdef abcdefghi');
  SELECT quote(block) FROM t1_data WHERE id>100;
}    {X'0000001C043061626301020204036465660102030703676869010204040808'}
do_execsql_test 6.3.1 {
  BEGIN;
................................................................................
    INSERT INTO t5 VALUES( rnddoc(10000) );
    INSERT INTO t5 VALUES( rnddoc(10000) );
    INSERT INTO t5 VALUES( rnddoc(10000) );
    INSERT INTO t5(t5) VALUES('optimize');
  }
} {}

sqlite3_db_config db DEFENSIVE 0
do_test 7.1 {
  foreach i [db eval { SELECT rowid FROM t5_data WHERE rowid>100 }] {
    db eval BEGIN  
    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  
................................................................................
#
reset_db
do_execsql_test 8.1 {
  CREATE VIRTUAL TABLE t1 USING fts5(x, y);
  INSERT INTO t1 VALUES('one', 'two');
}

sqlite3_db_config db DEFENSIVE 0
do_test 9.1.1 {
  set    blob "12345678"    ;# cookie
  append blob "0105"        ;# 1 level, total of 5 segments
  append blob "06"          ;# write counter
  append blob "0002"        ;# first level has 0 segments merging, 2 other.
  append blob "450108"      ;# first segment
  execsql "REPLACE INTO t1_data VALUES(10, X'$blob')"

Changes to ext/fts5/test/fts5first.test.

89
90
91
92
93
94
95
96
  SELECT * FROM x2('a + b');
} {1 {fts5: phrase queries are not supported (detail!=full)}}

do_catchsql_test 3.3 {
  SELECT * FROM x2('^a');
} {1 {fts5: phrase queries are not supported (detail!=full)}}
finish_test








<
89
90
91
92
93
94
95

  SELECT * FROM x2('a + b');
} {1 {fts5: phrase queries are not supported (detail!=full)}}

do_catchsql_test 3.3 {
  SELECT * FROM x2('^a');
} {1 {fts5: phrase queries are not supported (detail!=full)}}
finish_test

Changes to ext/fts5/test/fts5integrity.test.

67
68
69
70
71
72
73

74
75
76
77
78
79
80
  INSERT INTO aa(zz) VALUES('a');
  SELECT length(sz) FROM aa_docsize;
} {1 1 1 1 1}
do_execsql_test 4.1 { 
  INSERT INTO aa(aa) VALUES('integrity-check'); 
}


do_catchsql_test 4.2 { 
  BEGIN;
    UPDATE aa_docsize SET sz = X'44' WHERE rowid = 3;
    INSERT INTO aa(aa) VALUES('integrity-check'); 
} {1 {database disk image is malformed}}

do_catchsql_test 4.3 { 







>







67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
  INSERT INTO aa(zz) VALUES('a');
  SELECT length(sz) FROM aa_docsize;
} {1 1 1 1 1}
do_execsql_test 4.1 { 
  INSERT INTO aa(aa) VALUES('integrity-check'); 
}

sqlite3_db_config db DEFENSIVE 0
do_catchsql_test 4.2 { 
  BEGIN;
    UPDATE aa_docsize SET sz = X'44' WHERE rowid = 3;
    INSERT INTO aa(aa) VALUES('integrity-check'); 
} {1 {database disk image is malformed}}

do_catchsql_test 4.3 { 

Changes to ext/fts5/test/fts5rank.test.

159
160
161
162
163
164
165
166
}

do_execsql_test 5.1 {
  SELECT rowid FROM ttt('word') WHERE rowid BETWEEN 30 AND 40 ORDER BY rank;
} {30 31 32 33 34 35 36 37 38 39 40}

finish_test








<
159
160
161
162
163
164
165

}

do_execsql_test 5.1 {
  SELECT rowid FROM ttt('word') WHERE rowid BETWEEN 30 AND 40 ORDER BY rank;
} {30 31 32 33 34 35 36 37 38 39 40}

finish_test

Changes to ext/fts5/test/fts5rebuild.test.

35
36
37
38
39
40
41

42
43
44
45
46
47
48
  INSERT INTO f1(f1) VALUES('rebuild');
} {}

do_execsql_test 1.4 {
  INSERT INTO f1(f1) VALUES('integrity-check');
} {}


do_execsql_test 1.5 {
  DELETE FROM f1_data;
} {}

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







>







35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
  INSERT INTO f1(f1) VALUES('rebuild');
} {}

do_execsql_test 1.4 {
  INSERT INTO f1(f1) VALUES('integrity-check');
} {}

sqlite3_db_config db DEFENSIVE 0
do_execsql_test 1.5 {
  DELETE FROM f1_data;
} {}

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

Changes to ext/fts5/test/fts5rowid.test.

66
67
68
69
70
71
72

73
74
75
76
77
78
79
  DELETE FROM x1 WHERE (rowid%2);
}

set res [db one {SELECT count(*) FROM x1_data}]
do_execsql_test 2.3 {
  SELECT count(fts5_decode(rowid, block)) FROM x1_data;
} $res

do_execsql_test 2.4 {
  UPDATE x1_data SET block = X'';
  SELECT count(fts5_decode(rowid, block)) FROM x1_data;
} $res

do_execsql_test 2.5 {
  INSERT INTO x1(x1, rank) VALUES('pgsz', 1024);







>







66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
  DELETE FROM x1 WHERE (rowid%2);
}

set res [db one {SELECT count(*) FROM x1_data}]
do_execsql_test 2.3 {
  SELECT count(fts5_decode(rowid, block)) FROM x1_data;
} $res
sqlite3_db_config db DEFENSIVE 0
do_execsql_test 2.4 {
  UPDATE x1_data SET block = X'';
  SELECT count(fts5_decode(rowid, block)) FROM x1_data;
} $res

do_execsql_test 2.5 {
  INSERT INTO x1(x1, rank) VALUES('pgsz', 1024);

Changes to ext/fts5/test/fts5version.test.

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
  SELECT * FROM t1_config WHERE k='version'
} {version 4}

do_execsql_test 1.3 {
  SELECT rowid FROM t1 WHERE t1 MATCH 'a';
} {1}


do_execsql_test 1.4 {
  UPDATE t1_config set v=5 WHERE k='version';
} 

do_test 1.5 {
  db close
  sqlite3 db test.db
  catchsql { SELECT * FROM t1 WHERE t1 MATCH 'a' }
} {1 {invalid fts5 file format (found 5, expected 4) - run 'rebuild'}}

................................................................................
do_test 1.6 {
  db close
  sqlite3 db test.db
  catchsql { INSERT INTO t1 VALUES('x y z') }
} {1 {invalid fts5 file format (found 5, expected 4) - run 'rebuild'}}

do_test 1.7 {

  execsql { DELETE FROM t1_config WHERE k='version' }
  db close
  sqlite3 db test.db
  catchsql { SELECT * FROM t1 WHERE t1 MATCH 'a' }
} {1 {invalid fts5 file format (found 0, expected 4) - run 'rebuild'}}


finish_test







>


|







 







>








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
  SELECT * FROM t1_config WHERE k='version'
} {version 4}

do_execsql_test 1.3 {
  SELECT rowid FROM t1 WHERE t1 MATCH 'a';
} {1}

sqlite3_db_config db DEFENSIVE 0
do_execsql_test 1.4 {
  UPDATE t1_config set v=5 WHERE k='version';
}

do_test 1.5 {
  db close
  sqlite3 db test.db
  catchsql { SELECT * FROM t1 WHERE t1 MATCH 'a' }
} {1 {invalid fts5 file format (found 5, expected 4) - run 'rebuild'}}

................................................................................
do_test 1.6 {
  db close
  sqlite3 db test.db
  catchsql { INSERT INTO t1 VALUES('x y z') }
} {1 {invalid fts5 file format (found 5, expected 4) - run 'rebuild'}}

do_test 1.7 {
  sqlite3_db_config db DEFENSIVE 0
  execsql { DELETE FROM t1_config WHERE k='version' }
  db close
  sqlite3 db test.db
  catchsql { SELECT * FROM t1 WHERE t1 MATCH 'a' }
} {1 {invalid fts5 file format (found 0, expected 4) - run 'rebuild'}}


finish_test

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

416
417
418
419
420
421
422

423
424
425
426
427
428
429
...
477
478
479
480
481
482
483
484
  i a 1 1 i b 1 1 i c 1 1
}]
if {[detail_is_none]} { set resc [row_to_col $resr] }

do_execsql_test 8.1.1 { SELECT * FROM x1_r; } $resr
do_execsql_test 8.1.2 { SELECT * FROM x1_c } $resc


do_execsql_test 8.2 {
  PRAGMA writable_schema = 1;
  UPDATE sqlite_master 
  SET sql = 'CREATE VIRTUAL TABLE x1 USING fts5(a, detail=%DETAIL%)'
  WHERE name = 'x1';
}
db close
................................................................................
  set e2 [db eval { EXPLAIN SELECT * FROM rrr ORDER BY term DESC }]
  expr [lsearch $e2 SorterSort]<0
} 0



finish_test








>







 







<
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
...
478
479
480
481
482
483
484

  i a 1 1 i b 1 1 i c 1 1
}]
if {[detail_is_none]} { set resc [row_to_col $resr] }

do_execsql_test 8.1.1 { SELECT * FROM x1_r; } $resr
do_execsql_test 8.1.2 { SELECT * FROM x1_c } $resc

sqlite3_db_config db DEFENSIVE 0
do_execsql_test 8.2 {
  PRAGMA writable_schema = 1;
  UPDATE sqlite_master 
  SET sql = 'CREATE VIRTUAL TABLE x1 USING fts5(a, detail=%DETAIL%)'
  WHERE name = 'x1';
}
db close
................................................................................
  set e2 [db eval { EXPLAIN SELECT * FROM rrr ORDER BY term DESC }]
  expr [lsearch $e2 SorterSort]<0
} 0



finish_test

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

202
203
204
205
206
207
208
209
do_execsql_test 3.5 {
  DELETE FROM t1;
  SELECT * FROM v1;
} {
}

finish_test








<
202
203
204
205
206
207
208

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

finish_test

Changes to ext/misc/amatch.c.

1469
1470
1471
1472
1473
1474
1475
1476

1477
1478
1479
1480
1481
1482
1483
  0,                      /* xSync */
  0,                      /* xCommit */
  0,                      /* xRollback */
  0,                      /* xFindMethod */
  0,                      /* xRename */
  0,                      /* xSavepoint */
  0,                      /* xRelease */
  0                       /* xRollbackTo */

};

#endif /* SQLITE_OMIT_VIRTUALTABLE */

/*
** Register the amatch virtual table
*/







|
>







1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
  0,                      /* xSync */
  0,                      /* xCommit */
  0,                      /* xRollback */
  0,                      /* xFindMethod */
  0,                      /* xRename */
  0,                      /* xSavepoint */
  0,                      /* xRelease */
  0,                      /* xRollbackTo */
  0                       /* xShadowName */
};

#endif /* SQLITE_OMIT_VIRTUALTABLE */

/*
** Register the amatch virtual table
*/

Changes to ext/misc/btreeinfo.c.

407
408
409
410
411
412
413

414
415
416
417
418
419
420
    0,                           /* xCommit */
    0,                           /* xRollback */
    0,                           /* xFindMethod */
    0,                           /* xRename */
    0,                           /* xSavepoint */
    0,                           /* xRelease */
    0,                           /* xRollbackTo */

  };
  return sqlite3_create_module(db, "sqlite_btreeinfo", &binfo_module, 0);
}

#ifdef _WIN32
__declspec(dllexport)
#endif







>







407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
    0,                           /* xCommit */
    0,                           /* xRollback */
    0,                           /* xFindMethod */
    0,                           /* xRename */
    0,                           /* xSavepoint */
    0,                           /* xRelease */
    0,                           /* xRollbackTo */
    0                            /* xShadowName */
  };
  return sqlite3_create_module(db, "sqlite_btreeinfo", &binfo_module, 0);
}

#ifdef _WIN32
__declspec(dllexport)
#endif

Changes to ext/misc/closure.c.

934
935
936
937
938
939
940
941

942
943
944
945
946
947
948
  0,                      /* xSync */
  0,                      /* xCommit */
  0,                      /* xRollback */
  0,                      /* xFindMethod */
  0,                      /* xRename */
  0,                      /* xSavepoint */
  0,                      /* xRelease */
  0                       /* xRollbackTo */

};

#endif /* SQLITE_OMIT_VIRTUALTABLE */

/*
** Register the closure virtual table
*/







|
>







934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
  0,                      /* xSync */
  0,                      /* xCommit */
  0,                      /* xRollback */
  0,                      /* xFindMethod */
  0,                      /* xRename */
  0,                      /* xSavepoint */
  0,                      /* xRelease */
  0,                      /* xRollbackTo */
  0                       /* xShadowName */
};

#endif /* SQLITE_OMIT_VIRTUALTABLE */

/*
** Register the closure virtual table
*/

Changes to ext/misc/completion.c.

464
465
466
467
468
469
470
471

472
473
474
475
476
477
478
  0,                         /* xSync */
  0,                         /* xCommit */
  0,                         /* xRollback */
  0,                         /* xFindMethod */
  0,                         /* xRename */
  0,                         /* xSavepoint */
  0,                         /* xRelease */
  0                          /* xRollbackTo */

};

#endif /* SQLITE_OMIT_VIRTUALTABLE */

int sqlite3CompletionVtabInit(sqlite3 *db){
  int rc = SQLITE_OK;
#ifndef SQLITE_OMIT_VIRTUALTABLE







|
>







464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
  0,                         /* xSync */
  0,                         /* xCommit */
  0,                         /* xRollback */
  0,                         /* xFindMethod */
  0,                         /* xRename */
  0,                         /* xSavepoint */
  0,                         /* xRelease */
  0,                         /* xRollbackTo */
  0                          /* xShadowName */
};

#endif /* SQLITE_OMIT_VIRTUALTABLE */

int sqlite3CompletionVtabInit(sqlite3 *db){
  int rc = SQLITE_OK;
#ifndef SQLITE_OMIT_VIRTUALTABLE

Changes to ext/misc/explain.c.

276
277
278
279
280
281
282

283
284
285
286
287
288
289
  0,                         /* xCommit */
  0,                         /* xRollback */
  0,                         /* xFindMethod */
  0,                         /* xRename */
  0,                         /* xSavepoint */
  0,                         /* xRelease */
  0,                         /* xRollbackTo */

};

#endif /* SQLITE_OMIT_VIRTUALTABLE */

int sqlite3ExplainVtabInit(sqlite3 *db){
  int rc = SQLITE_OK;
#ifndef SQLITE_OMIT_VIRTUALTABLE







>







276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
  0,                         /* xCommit */
  0,                         /* xRollback */
  0,                         /* xFindMethod */
  0,                         /* xRename */
  0,                         /* xSavepoint */
  0,                         /* xRelease */
  0,                         /* xRollbackTo */
  0,                         /* xShadowName */
};

#endif /* SQLITE_OMIT_VIRTUALTABLE */

int sqlite3ExplainVtabInit(sqlite3 *db){
  int rc = SQLITE_OK;
#ifndef SQLITE_OMIT_VIRTUALTABLE

Changes to ext/misc/fileio.c.

884
885
886
887
888
889
890
891

892
893
894
895
896
897
898
    0,                         /* xSync */
    0,                         /* xCommit */
    0,                         /* xRollback */
    0,                         /* xFindMethod */
    0,                         /* xRename */
    0,                         /* xSavepoint */
    0,                         /* xRelease */
    0                          /* xRollbackTo */

  };

  int rc = sqlite3_create_module(db, "fsdir", &fsdirModule, 0);
  return rc;
}
#else         /* SQLITE_OMIT_VIRTUALTABLE */
# define fsdirRegister(x) SQLITE_OK







|
>







884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
    0,                         /* xSync */
    0,                         /* xCommit */
    0,                         /* xRollback */
    0,                         /* xFindMethod */
    0,                         /* xRename */
    0,                         /* xSavepoint */
    0,                         /* xRelease */
    0,                         /* xRollbackTo */
    0,                         /* xShadowName */
  };

  int rc = sqlite3_create_module(db, "fsdir", &fsdirModule, 0);
  return rc;
}
#else         /* SQLITE_OMIT_VIRTUALTABLE */
# define fsdirRegister(x) SQLITE_OK

Changes to ext/misc/json1.c.

2384
2385
2386
2387
2388
2389
2390
2391

2392
2393
2394
2395
2396
2397
2398
....
2411
2412
2413
2414
2415
2416
2417
2418

2419
2420
2421
2422
2423
2424
2425
  0,                         /* xSync */
  0,                         /* xCommit */
  0,                         /* xRollback */
  0,                         /* xFindMethod */
  0,                         /* xRename */
  0,                         /* xSavepoint */
  0,                         /* xRelease */
  0                          /* xRollbackTo */

};

/* The methods of the json_tree virtual table. */
static sqlite3_module jsonTreeModule = {
  0,                         /* iVersion */
  0,                         /* xCreate */
  jsonEachConnect,           /* xConnect */
................................................................................
  0,                         /* xSync */
  0,                         /* xCommit */
  0,                         /* xRollback */
  0,                         /* xFindMethod */
  0,                         /* xRename */
  0,                         /* xSavepoint */
  0,                         /* xRelease */
  0                          /* xRollbackTo */

};
#endif /* SQLITE_OMIT_VIRTUALTABLE */

/****************************************************************************
** The following routines are the only publically visible identifiers in this
** file.  Call the following routines in order to register the various SQL
** functions and the virtual table implemented by this file.







|
>







 







|
>







2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
....
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
  0,                         /* xSync */
  0,                         /* xCommit */
  0,                         /* xRollback */
  0,                         /* xFindMethod */
  0,                         /* xRename */
  0,                         /* xSavepoint */
  0,                         /* xRelease */
  0,                         /* xRollbackTo */
  0                          /* xShadowName */
};

/* The methods of the json_tree virtual table. */
static sqlite3_module jsonTreeModule = {
  0,                         /* iVersion */
  0,                         /* xCreate */
  jsonEachConnect,           /* xConnect */
................................................................................
  0,                         /* xSync */
  0,                         /* xCommit */
  0,                         /* xRollback */
  0,                         /* xFindMethod */
  0,                         /* xRename */
  0,                         /* xSavepoint */
  0,                         /* xRelease */
  0,                         /* xRollbackTo */
  0                          /* xShadowName */
};
#endif /* SQLITE_OMIT_VIRTUALTABLE */

/****************************************************************************
** The following routines are the only publically visible identifiers in this
** file.  Call the following routines in order to register the various SQL
** functions and the virtual table implemented by this file.

Changes to ext/misc/memstat.c.

391
392
393
394
395
396
397

398
399
400
401
402
403
404
  0,                         /* xCommit */
  0,                         /* xRollback */
  0,                         /* xFindMethod */
  0,                         /* xRename */
  0,                         /* xSavepoint */
  0,                         /* xRelease */
  0,                         /* xRollbackTo */

};

#endif /* SQLITE_OMIT_VIRTUALTABLE */

int sqlite3MemstatVtabInit(sqlite3 *db){
  int rc = SQLITE_OK;
#ifndef SQLITE_OMIT_VIRTUALTABLE







>







391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
  0,                         /* xCommit */
  0,                         /* xRollback */
  0,                         /* xFindMethod */
  0,                         /* xRename */
  0,                         /* xSavepoint */
  0,                         /* xRelease */
  0,                         /* xRollbackTo */
  0,                         /* xShadowName */
};

#endif /* SQLITE_OMIT_VIRTUALTABLE */

int sqlite3MemstatVtabInit(sqlite3 *db){
  int rc = SQLITE_OK;
#ifndef SQLITE_OMIT_VIRTUALTABLE

Changes to ext/misc/stmt.c.

262
263
264
265
266
267
268

269
270
271
272
273
274
275
  0,                         /* xCommit */
  0,                         /* xRollback */
  0,                         /* xFindMethod */
  0,                         /* xRename */
  0,                         /* xSavepoint */
  0,                         /* xRelease */
  0,                         /* xRollbackTo */

};

#endif /* SQLITE_OMIT_VIRTUALTABLE */

int sqlite3StmtVtabInit(sqlite3 *db){
  int rc = SQLITE_OK;
#ifndef SQLITE_OMIT_VIRTUALTABLE







>







262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
  0,                         /* xCommit */
  0,                         /* xRollback */
  0,                         /* xFindMethod */
  0,                         /* xRename */
  0,                         /* xSavepoint */
  0,                         /* xRelease */
  0,                         /* xRollbackTo */
  0,                         /* xShadowName */
};

#endif /* SQLITE_OMIT_VIRTUALTABLE */

int sqlite3StmtVtabInit(sqlite3 *db){
  int rc = SQLITE_OK;
#ifndef SQLITE_OMIT_VIRTUALTABLE

Changes to ext/misc/templatevtab.c.

244
245
246
247
248
249
250
251

252
253
254
255
256
257
258
  /* xSync       */ 0,
  /* xCommit     */ 0,
  /* xRollback   */ 0,
  /* xFindMethod */ 0,
  /* xRename     */ 0,
  /* xSavepoint  */ 0,
  /* xRelease    */ 0,
  /* xRollbackTo */ 0

};


#ifdef _WIN32
__declspec(dllexport)
#endif
int sqlite3_templatevtab_init(







|
>







244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
  /* xSync       */ 0,
  /* xCommit     */ 0,
  /* xRollback   */ 0,
  /* xFindMethod */ 0,
  /* xRename     */ 0,
  /* xSavepoint  */ 0,
  /* xRelease    */ 0,
  /* xRollbackTo */ 0,
  /* xShadowName */ 0
};


#ifdef _WIN32
__declspec(dllexport)
#endif
int sqlite3_templatevtab_init(

Changes to ext/misc/unionvtab.c.

1346
1347
1348
1349
1350
1351
1352
1353

1354
1355
1356
1357
1358
1359
1360
    0,                            /* xSync */
    0,                            /* xCommit */
    0,                            /* xRollback */
    0,                            /* xFindMethod */
    0,                            /* xRename */
    0,                            /* xSavepoint */
    0,                            /* xRelease */
    0                             /* xRollbackTo */

  };
  int rc;

  rc = sqlite3_create_module(db, "unionvtab", &unionModule, 0);
  if( rc==SQLITE_OK ){
    rc = sqlite3_create_module(db, "swarmvtab", &unionModule, (void*)db);
  }







|
>







1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
    0,                            /* xSync */
    0,                            /* xCommit */
    0,                            /* xRollback */
    0,                            /* xFindMethod */
    0,                            /* xRename */
    0,                            /* xSavepoint */
    0,                            /* xRelease */
    0,                            /* xRollbackTo */
    0                             /* xShadowName */
  };
  int rc;

  rc = sqlite3_create_module(db, "unionvtab", &unionModule, 0);
  if( rc==SQLITE_OK ){
    rc = sqlite3_create_module(db, "swarmvtab", &unionModule, (void*)db);
  }

Changes to ext/misc/vtablog.c.

488
489
490
491
492
493
494

495
496
497
498
499
500
501
  0,                         /* xCommit */
  0,                         /* xRollback */
  0,                         /* xFindMethod */
  0,                         /* xRename */
  0,                         /* xSavepoint */
  0,                         /* xRelease */
  0,                         /* xRollbackTo */

};

#ifdef _WIN32
__declspec(dllexport)
#endif
int sqlite3_vtablog_init(
  sqlite3 *db, 







>







488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
  0,                         /* xCommit */
  0,                         /* xRollback */
  0,                         /* xFindMethod */
  0,                         /* xRename */
  0,                         /* xSavepoint */
  0,                         /* xRelease */
  0,                         /* xRollbackTo */
  0,                         /* xShadowName */
};

#ifdef _WIN32
__declspec(dllexport)
#endif
int sqlite3_vtablog_init(
  sqlite3 *db, 

Changes to ext/rbu/rbu1.test.

666
667
668
669
670
671
672
673

  catch { db close }
  eval $destroy_vfs
}


finish_test








<
666
667
668
669
670
671
672


  catch { db close }
  eval $destroy_vfs
}


finish_test

Changes to ext/rbu/rbu10.test.

181
182
183
184
185
186
187
188
    INSERT INTO data_t3 VALUES(1, 'abc', '-6.0', 0);
  }
  list [catch { apply_rbu $rbu } msg] $msg
} {0 SQLITE_DONE}


finish_test








<
181
182
183
184
185
186
187

    INSERT INTO data_t3 VALUES(1, 'abc', '-6.0', 0);
  }
  list [catch { apply_rbu $rbu } msg] $msg
} {0 SQLITE_DONE}


finish_test

Changes to ext/rbu/rbu11.test.

191
192
193
194
195
196
197
198
  rbu step
} {SQLITE_ERROR}
do_test 4.7.2 {
  list [catch {rbu close} msg] $msg
} {1 {SQLITE_ERROR - rbu_state mismatch error}}

finish_test








<
191
192
193
194
195
196
197

  rbu step
} {SQLITE_ERROR}
do_test 4.7.2 {
  list [catch {rbu close} msg] $msg
} {1 {SQLITE_ERROR - rbu_state mismatch error}}

finish_test

Changes to ext/rbu/rbu12.test.

228
229
230
231
232
233
234
235
  do_test 2.$tn.6 {
    list [sql1 {PRAGMA data_version}] [sql2 {PRAGMA data_version}]
  } [list $V1 $V2]

}

finish_test








<
228
229
230
231
232
233
234

  do_test 2.$tn.6 {
    list [sql1 {PRAGMA data_version}] [sql2 {PRAGMA data_version}]
  } [list $V1 $V2]

}

finish_test

Changes to ext/rbu/rbu13.test.

58
59
60
61
62
63
64
65
do_execsql_test 1.4 {
  SELECT count(*) FROM t1 WHERE
  a == ( (b<<6) + (c<<5) + (d<<4) + (e<<3) + (f<<2) + (g<<1) + (h<<0) )
} {128}


finish_test








<
58
59
60
61
62
63
64

do_execsql_test 1.4 {
  SELECT count(*) FROM t1 WHERE
  a == ( (b<<6) + (c<<5) + (d<<4) + (e<<3) + (f<<2) + (g<<1) + (h<<0) )
} {128}


finish_test

Changes to ext/rbu/rbu14.test.

88
89
90
91
92
93
94
95
  } {4 5 6 50 50 50}

  integrity_check $tn.4
}


finish_test








<
88
89
90
91
92
93
94

  } {4 5 6 50 50 50}

  integrity_check $tn.4
}


finish_test

Changes to ext/rbu/rbu3.test.

199
200
201
202
203
204
205
206
207
do_test 5.3 {
  expr {[file size test.db-wal] > (1024 * 1200)}
} 1

do_test 6.1 { sqlite3rbu_internal_test } {}

finish_test









<
<
199
200
201
202
203
204
205


do_test 5.3 {
  expr {[file size test.db-wal] > (1024 * 1200)}
} 1

do_test 6.1 { sqlite3rbu_internal_test } {}

finish_test


Changes to ext/rbu/rbu5.test.

296
297
298
299
300
301
302
303
304
305
306

    db close
  }
}


finish_test











<
<
<
<
296
297
298
299
300
301
302





    db close
  }
}


finish_test




Changes to ext/rbu/rbu6.test.

96
97
98
99
100
101
102
103
  do_execsql_test 1.$nStep.5 {
    SELECT * FROM t1;
  } {1 t1 5 hello}
}


finish_test








<
96
97
98
99
100
101
102

  do_execsql_test 1.$nStep.5 {
    SELECT * FROM t1;
  } {1 t1 5 hello}
}


finish_test

Changes to ext/rbu/rbu7.test.

102
103
104
105
106
107
108
109
110
    2 2 d
    3 1 e
    3 2 f
  }
}

finish_test









<
<
102
103
104
105
106
107
108


    2 2 d
    3 1 e
    3 2 f
  }
}

finish_test


Changes to ext/rbu/rbu8.test.

68
69
70
71
72
73
74
75
  {}   2 2
  _iii 3 three-III
}
integrity_check 1.3.3


finish_test








<
68
69
70
71
72
73
74

  {}   2 2
  _iii 3 three-III
}
integrity_check 1.3.3


finish_test

Changes to ext/rbu/rbu9.test.

121
122
123
124
125
126
127
128
  }
  
  integrity_check 2.$tn.4
}


finish_test








<
121
122
123
124
125
126
127

  }
  
  integrity_check 2.$tn.4
}


finish_test

Changes to ext/rbu/rbuA.test.

76
77
78
79
80
81
82
83

do_test 2.2 {
  list [catch { rbu close } msg] $msg
} {1 {SQLITE_ERROR - cannot update wal mode database}}


finish_test








<
76
77
78
79
80
81
82


do_test 2.2 {
  list [catch { rbu close } msg] $msg
} {1 {SQLITE_ERROR - cannot update wal mode database}}


finish_test

Changes to ext/rbu/rbuB.test.

55
56
57
58
59
60
61
62
} {1 2 3 4 5 6 7 8 9}

db close
sqlite3_shutdown
test_sqlite3_log 
sqlite3_initialize
finish_test








<
55
56
57
58
59
60
61

} {1 2 3 4 5 6 7 8 9}

db close
sqlite3_shutdown
test_sqlite3_log 
sqlite3_initialize
finish_test

Changes to ext/rbu/rbuC.test.

135
136
137
138
139
140
141
142
  
  integrity_check 3.$tn.4
}



finish_test








<
135
136
137
138
139
140
141

  
  integrity_check 3.$tn.4
}



finish_test

Changes to ext/rbu/rbucollate.test.

56
57
58
59
60
61
62
63
  }
  rbu close
  db eval { SELECT * FROM t1 }
} {a one 1 b two 2 c three 3}

#forcedelete testrbu.db
finish_test








<
56
57
58
59
60
61
62

  }
  rbu close
  db eval { SELECT * FROM t1 }
} {a one 1 b two 2 c three 3}

#forcedelete testrbu.db
finish_test

Changes to ext/rbu/rbucrash.test.

141
142
143
144
145
146
147
148
for {set nPre 0} {$nPre < $rbu_num_steps} {incr nPre} {
  for {set is 1} {$is <= ($rbu_num_steps - $nPre)} {incr is} {
    do_rbu_crash_test 2.pre=$nPre.step=$is $nPre $is
  }
}

finish_test








<
141
142
143
144
145
146
147

for {set nPre 0} {$nPre < $rbu_num_steps} {incr nPre} {
  for {set is 1} {$is <= ($rbu_num_steps - $nPre)} {incr is} {
    do_rbu_crash_test 2.pre=$nPre.step=$is $nPre $is
  }
}

finish_test

Changes to ext/rbu/rbucrash2.test.

99
100
101
102
103
104
105
106
      sqlite3rbu rbu test.db test.db2
    }
    rbu close
  }
}

finish_test








<
99
100
101
102
103
104
105

      sqlite3rbu rbu test.db test.db2
    }
    rbu close
  }
}

finish_test

Changes to ext/rbu/rbudiff.test.

296
297
298
299
300
301
302
303
    db close
    db2 close
  }
}


finish_test








<
296
297
298
299
300
301
302

    db close
    db2 close
  }
}


finish_test

Changes to ext/rbu/rbudor.test.

52
53
54
55
56
57
58
59
} {SQLITE_DONE}

do_execsql_test 1.4 {
  SELECT * FROM t1 
} [list 1 $bigA 2 $bigB]

finish_test








<
52
53
54
55
56
57
58

} {SQLITE_DONE}

do_execsql_test 1.4 {
  SELECT * FROM t1 
} [list 1 $bigA 2 $bigB]

finish_test

Changes to ext/rbu/rbufault.test.

230
231
232
233
234
235
236
237
        }
      }
    }
  }
}

finish_test








<
230
231
232
233
234
235
236

        }
      }
    }
  }
}

finish_test

Changes to ext/rbu/rbufault2.test.

51
52
53
54
55
56
57
58
      {1 {SQLITE_NOMEM - out of memory}} 
}




finish_test








<
51
52
53
54
55
56
57

      {1 {SQLITE_NOMEM - out of memory}} 
}




finish_test

Changes to ext/rbu/rbufault3.test.

91
92
93
94
95
96
97
98
  } -test {
    eval [list faultsim_test_result {0 SQLITE_OK} {*}$::errlist]
  }

}

finish_test








<
91
92
93
94
95
96
97

  } -test {
    eval [list faultsim_test_result {0 SQLITE_OK} {*}$::errlist]
  }

}

finish_test

Changes to ext/rbu/rbufault4.test.

59
60
61
62
63
64
65
66
    if {$rc!="ok"} { error "Got $rc instead of ok!" }
  }
}



finish_test








<
59
60
61
62
63
64
65

    if {$rc!="ok"} { error "Got $rc instead of ok!" }
  }
}



finish_test

Changes to ext/rbu/rbufts.test.

127
128
129
130
131
132
133
134
    INSERT INTO data_ft VALUES('7 8 9', 1, 'x');
  } } msg] $msg]
} {1 {SQLITE_ERROR - SQL logic error]}}



finish_test








<
127
128
129
130
131
132
133

    INSERT INTO data_ft VALUES('7 8 9', 1, 'x');
  } } msg] $msg]
} {1 {SQLITE_ERROR - SQL logic error]}}



finish_test

Changes to ext/rbu/rbumulti.test.

168
169
170
171
172
173
174
175
    sqlite3rbu_destroy_vfs myrbu
  }

}


finish_test








<
168
169
170
171
172
173
174

    sqlite3rbu_destroy_vfs myrbu
  }

}


finish_test

Changes to ext/rbu/rbuprogress.test.

412
413
414
415
416
417
418
419
      do_sp_test 5.$tn.$bReopen.$tn2.1 $bReopen test.db rbu.db $R($tn)
    }
  }
}


finish_test








<
412
413
414
415
416
417
418

      do_sp_test 5.$tn.$bReopen.$tn2.1 $bReopen test.db rbu.db $R($tn)
    }
  }
}


finish_test

Changes to ext/rbu/rburesume.test.

247
248
249
250
251
252
253
254
      PRAGMA integrity_check;
    }
  } {60 ok}
  db2 close
}

finish_test








<
247
248
249
250
251
252
253

      PRAGMA integrity_check;
    }
  } {60 ok}
  db2 close
}

finish_test

Changes to ext/rbu/rbusave.test.

98
99
100
101
102
103
104
105

do_execsql_test 1.5 {
  SELECT * FROM t1;
  SELECT * FROM t2;
} {1 one 1 3 3 3 4 4 4 1 one 1 3 3 3 4 4 4}

finish_test








<
98
99
100
101
102
103
104


do_execsql_test 1.5 {
  SELECT * FROM t1;
  SELECT * FROM t2;
} {1 one 1 3 3 3 4 4 4 1 one 1 3 3 3 4 4 4}

finish_test

Changes to ext/rbu/rbusplit.test.

88
89
90
91
92
93
94
95
    1 1 1 2 2 2 3 3 3 4 4 4
    5 5 5 6 6 6 7 7 7 8 8 8
    9 9 9
  }
}

finish_test








<
88
89
90
91
92
93
94

    1 1 1 2 2 2 3 3 3 4 4 4
    5 5 5 6 6 6 7 7 7 8 8 8
    9 9 9
  }
}

finish_test

Changes to ext/rbu/rbutemplimit.test.

122
123
124
125
126
127
128
129
  setup_databases
  unset -nocomplain ::A
  step_rbu_cachesize test.db test.db2 1000 10 1400000
} {1 SQLITE_FULL}
do_test 1.6.2 { info commands rbu } {}

finish_test








<
122
123
124
125
126
127
128

  setup_databases
  unset -nocomplain ::A
  step_rbu_cachesize test.db test.db2 1000 10 1400000
} {1 SQLITE_FULL}
do_test 1.6.2 { info commands rbu } {}

finish_test

Changes to ext/rbu/rbuvacuum.test.

393
394
395
396
397
398
399
400

  while {[rbu step]=="SQLITE_OK"} {}
  list [catch { rbu close } msg] $msg
} {0 SQLITE_DONE}

catch { db close }
finish_test








<
393
394
395
396
397
398
399


  while {[rbu step]=="SQLITE_OK"} {}
  list [catch { rbu close } msg] $msg
} {0 SQLITE_DONE}

catch { db close }
finish_test

Changes to ext/rbu/rbuvacuum2.test.

228
229
230
231
232
233
234
235
  sqlite3rbu_vacuum rbu test.db test.db2
  while {[rbu step]!="SQLITE_DONE"} { rbu step }
  rbu close
  execsql { PRAGMA integrity_check }
} {ok}

finish_test








<
228
229
230
231
232
233
234

  sqlite3rbu_vacuum rbu test.db test.db2
  while {[rbu step]!="SQLITE_DONE"} { rbu step }
  rbu close
  execsql { PRAGMA integrity_check }
} {ok}

finish_test

Changes to ext/repair/test/checkindex01.test.

343
344
345
346
347
348
349
350
351
}
do_index_check_test 7.3 t7i3 {
  {} 1,1 {} 3,3
}
do_index_check_test 7.4 t7i4 {
  {} 1,1 {} 3,3
}









<
<
343
344
345
346
347
348
349


}
do_index_check_test 7.3 t7i3 {
  {} 1,1 {} 3,3
}
do_index_check_test 7.4 t7i4 {
  {} 1,1 {} 3,3
}


Changes to ext/rtree/geopoly.c.

1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
....
1744
1745
1746
1747
1748
1749
1750

1751
1752
1753
1754
1755
1756
1757
    return SQLITE_INDEX_CONSTRAINT_FUNCTION+1;
  }
  return 0;
}


static sqlite3_module geopolyModule = {
  2,                          /* iVersion */
  geopolyCreate,              /* xCreate - create a table */
  geopolyConnect,             /* xConnect - connect to an existing table */
  geopolyBestIndex,           /* xBestIndex - Determine search strategy */
  rtreeDisconnect,            /* xDisconnect - Disconnect from a table */
  rtreeDestroy,               /* xDestroy - Drop a table */
  rtreeOpen,                  /* xOpen - open a cursor */
  rtreeClose,                 /* xClose - close a cursor */
................................................................................
  rtreeEndTransaction,        /* xCommit - commit transaction */
  rtreeEndTransaction,        /* xRollback - rollback transaction */
  geopolyFindFunction,        /* xFindFunction - function overloading */
  rtreeRename,                /* xRename - rename the table */
  rtreeSavepoint,             /* xSavepoint */
  0,                          /* xRelease */
  0,                          /* xRollbackTo */

};

static int sqlite3_geopoly_init(sqlite3 *db){
  int rc = SQLITE_OK;
  static const struct {
    void (*xFunc)(sqlite3_context*,int,sqlite3_value**);
    signed char nArg;







|







 







>







1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
....
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
    return SQLITE_INDEX_CONSTRAINT_FUNCTION+1;
  }
  return 0;
}


static sqlite3_module geopolyModule = {
  3,                          /* iVersion */
  geopolyCreate,              /* xCreate - create a table */
  geopolyConnect,             /* xConnect - connect to an existing table */
  geopolyBestIndex,           /* xBestIndex - Determine search strategy */
  rtreeDisconnect,            /* xDisconnect - Disconnect from a table */
  rtreeDestroy,               /* xDestroy - Drop a table */
  rtreeOpen,                  /* xOpen - open a cursor */
  rtreeClose,                 /* xClose - close a cursor */
................................................................................
  rtreeEndTransaction,        /* xCommit - commit transaction */
  rtreeEndTransaction,        /* xRollback - rollback transaction */
  geopolyFindFunction,        /* xFindFunction - function overloading */
  rtreeRename,                /* xRename - rename the table */
  rtreeSavepoint,             /* xSavepoint */
  0,                          /* xRelease */
  0,                          /* xRollbackTo */
  rtreeShadowName             /* xShadowName */
};

static int sqlite3_geopoly_init(sqlite3 *db){
  int rc = SQLITE_OK;
  static const struct {
    void (*xFunc)(sqlite3_context*,int,sqlite3_value**);
    signed char nArg;

Changes to ext/rtree/rtree.c.

3321
3322
3323
3324
3325
3326
3327
















3328
3329
3330
3331
3332
3333
3334
3335
3336
....
3345
3346
3347
3348
3349
3350
3351

3352
3353
3354
3355
3356
3357
3358
    }
    sqlite3_free(zSql);
  }

  return rc;
}

















static sqlite3_module rtreeModule = {
  2,                          /* iVersion */
  rtreeCreate,                /* xCreate - create a table */
  rtreeConnect,               /* xConnect - connect to an existing table */
  rtreeBestIndex,             /* xBestIndex - Determine search strategy */
  rtreeDisconnect,            /* xDisconnect - Disconnect from a table */
  rtreeDestroy,               /* xDestroy - Drop a table */
  rtreeOpen,                  /* xOpen - open a cursor */
  rtreeClose,                 /* xClose - close a cursor */
................................................................................
  rtreeEndTransaction,        /* xCommit - commit transaction */
  rtreeEndTransaction,        /* xRollback - rollback transaction */
  0,                          /* xFindFunction - function overloading */
  rtreeRename,                /* xRename - rename the table */
  rtreeSavepoint,             /* xSavepoint */
  0,                          /* xRelease */
  0,                          /* xRollbackTo */

};

static int rtreeSqlInit(
  Rtree *pRtree, 
  sqlite3 *db, 
  const char *zDb, 
  const char *zPrefix, 







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

|







 







>







3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
....
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
    }
    sqlite3_free(zSql);
  }

  return rc;
}


/*
** Return true if zName is the extension on one of the shadow tables used
** by this module.
*/
static int rtreeShadowName(const char *zName){
  static const char *azName[] = {
    "node", "parent", "rowid"
  };
  unsigned int i;
  for(i=0; i<sizeof(azName)/sizeof(azName[0]); i++){
    if( sqlite3_stricmp(zName, azName[i])==0 ) return 1;
  }
  return 0;
}

static sqlite3_module rtreeModule = {
  3,                          /* iVersion */
  rtreeCreate,                /* xCreate - create a table */
  rtreeConnect,               /* xConnect - connect to an existing table */
  rtreeBestIndex,             /* xBestIndex - Determine search strategy */
  rtreeDisconnect,            /* xDisconnect - Disconnect from a table */
  rtreeDestroy,               /* xDestroy - Drop a table */
  rtreeOpen,                  /* xOpen - open a cursor */
  rtreeClose,                 /* xClose - close a cursor */
................................................................................
  rtreeEndTransaction,        /* xCommit - commit transaction */
  rtreeEndTransaction,        /* xRollback - rollback transaction */
  0,                          /* xFindFunction - function overloading */
  rtreeRename,                /* xRename - rename the table */
  rtreeSavepoint,             /* xSavepoint */
  0,                          /* xRelease */
  0,                          /* xRollbackTo */
  rtreeShadowName             /* xShadowName */
};

static int rtreeSqlInit(
  Rtree *pRtree, 
  sqlite3 *db, 
  const char *zDb, 
  const char *zPrefix, 

Changes to ext/rtree/rtree8.test.

97
98
99
100
101
102
103

104
105
106
107
108
109
110
...
117
118
119
120
121
122
123

124
125
126
127
128
129
130
# The following block of tests - rtree8-2.* - test a couple of database
# corruption cases. In this case things are not corrupted at the b-tree
# level, but the contents of the various tables used internally by an
# r-tree table are inconsistent.
#
populate_t1 50
do_execsql_test rtree8-2.1.1 { SELECT max(nodeno) FROM t1_node } {5}

do_execsql_test rtree8-2.1.2 { DELETE FROM t1_node } {}
for {set i 1} {$i <= 50} {incr i} {
  do_catchsql_test rtree8-2.1.3.$i { 
    SELECT * FROM t1 WHERE id = $i 
  } {1 {database disk image is malformed}}
}
do_catchsql_test rtree8-2.1.4 { 
................................................................................
do_execsql_test rtree8-2.1.6 { 
  DROP TABLE t1;
  CREATE VIRTUAL TABLE t1 USING rtree_i32(id, x1, x2);
} {}


populate_t1 50

do_execsql_test rtree8-2.2.1 {
  DELETE FROM t1_parent
} {}
do_catchsql_test rtree8-2.2.2 {
  DELETE FROM t1 WHERE id=25
} {1 {database disk image is malformed}}
do_execsql_test rtree8-2.2.3 { 







>







 







>







97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
...
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
# The following block of tests - rtree8-2.* - test a couple of database
# corruption cases. In this case things are not corrupted at the b-tree
# level, but the contents of the various tables used internally by an
# r-tree table are inconsistent.
#
populate_t1 50
do_execsql_test rtree8-2.1.1 { SELECT max(nodeno) FROM t1_node } {5}
sqlite3_db_config db DEFENSIVE 0
do_execsql_test rtree8-2.1.2 { DELETE FROM t1_node } {}
for {set i 1} {$i <= 50} {incr i} {
  do_catchsql_test rtree8-2.1.3.$i { 
    SELECT * FROM t1 WHERE id = $i 
  } {1 {database disk image is malformed}}
}
do_catchsql_test rtree8-2.1.4 { 
................................................................................
do_execsql_test rtree8-2.1.6 { 
  DROP TABLE t1;
  CREATE VIRTUAL TABLE t1 USING rtree_i32(id, x1, x2);
} {}


populate_t1 50
sqlite3_db_config db DEFENSIVE 0
do_execsql_test rtree8-2.2.1 {
  DELETE FROM t1_parent
} {}
do_catchsql_test rtree8-2.2.2 {
  DELETE FROM t1 WHERE id=25
} {1 {database disk image is malformed}}
do_execsql_test rtree8-2.2.3 { 

Changes to ext/rtree/rtreeA.test.

32
33
34
35
36
37
38

39
40
41
42
43
44
45
...
242
243
244
245
246
247
248

249
250
251
252
253
254
255
256
257
258
259
260
261
  execsql BEGIN
  for {set i 0} {$i < 500} {incr i} {
    set x2 [expr $i+5]
    set y2 [expr $i+5]
    execsql { INSERT INTO t1 VALUES($i, $i, $x2, $i, $y2) }
  }
  execsql COMMIT

}

proc truncate_node {nodeno nTrunc} {
  set blob [db one {SELECT data FROM t1_node WHERE nodeno=$nodeno}]
  if {$nTrunc<0} {set nTrunc "end-$nTrunc"}
  set blob [string range $blob 0 $nTrunc]
  db eval { UPDATE t1_node SET data = $blob WHERE nodeno=$nodeno }
................................................................................

#-------------------------------------------------------------------------
# Truncated blobs in the _node table.
#
create_t1
populate_t1
sqlite3 db test.db

do_execsql_test rtreeA-7.100 { 
  UPDATE t1_node SET data=x'' WHERE rowid=1;
} {}
do_catchsql_test rtreeA-7.110 {
  SELECT * FROM t1 WHERE x1>0 AND x1<100 AND x2>0 AND x2<100;
} {1 {undersize RTree blobs in "t1_node"}}
do_test rtreeA-7.120 {
  sqlite3_extended_errcode db
} {SQLITE_CORRUPT_VTAB}


finish_test








>







 







>












<
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
...
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262

  execsql BEGIN
  for {set i 0} {$i < 500} {incr i} {
    set x2 [expr $i+5]
    set y2 [expr $i+5]
    execsql { INSERT INTO t1 VALUES($i, $i, $x2, $i, $y2) }
  }
  execsql COMMIT
  sqlite3_db_config db DEFENSIVE 0
}

proc truncate_node {nodeno nTrunc} {
  set blob [db one {SELECT data FROM t1_node WHERE nodeno=$nodeno}]
  if {$nTrunc<0} {set nTrunc "end-$nTrunc"}
  set blob [string range $blob 0 $nTrunc]
  db eval { UPDATE t1_node SET data = $blob WHERE nodeno=$nodeno }
................................................................................

#-------------------------------------------------------------------------
# Truncated blobs in the _node table.
#
create_t1
populate_t1
sqlite3 db test.db
sqlite3_db_config db DEFENSIVE 0
do_execsql_test rtreeA-7.100 { 
  UPDATE t1_node SET data=x'' WHERE rowid=1;
} {}
do_catchsql_test rtreeA-7.110 {
  SELECT * FROM t1 WHERE x1>0 AND x1<100 AND x2>0 AND x2<100;
} {1 {undersize RTree blobs in "t1_node"}}
do_test rtreeA-7.120 {
  sqlite3_extended_errcode db
} {SQLITE_CORRUPT_VTAB}


finish_test

Changes to ext/rtree/rtreecheck.test.

57
58
59
60
61
62
63

64
65
66
67
68
69
70
...
108
109
110
111
112
113
114

115
116
117
118
119
120
121
...
136
137
138
139
140
141
142

143
144
145
146
147
148
149
...
151
152
153
154
155
156
157
158
    CREATE VIRTUAL TABLE r1 USING $module (id, x1, x2, y1, y2);
    INSERT INTO r1 VALUES(1,  5, 5, 5, 5);  --  3
    INSERT INTO r1 VALUES(2,  6, 6, 6, 6);  --  9
    INSERT INTO r1 VALUES(3,  7, 7, 7, 7);  -- 15
    INSERT INTO r1 VALUES(4,  8, 8, 8, 8);  -- 21
    INSERT INTO r1 VALUES(5,  9, 9, 9, 9);  -- 27
  "

}

setup_simple_db
do_execsql_test 2.1 { 
  SELECT rtreecheck('r1') 
} {ok}

................................................................................

do_execsql_test 3.1 { 
  CREATE VIRTUAL TABLE r2 USING rtree_i32(id, x1, x2);
  INSERT INTO r2 VALUES(2, -1*(1<<31), -1*(1<<31)+5);
  SELECT rtreecheck('r2') 
} {ok}


do_execsql_test 3.2 {
  BEGIN;
    UPDATE r2_node SET data = X'123456';
    SELECT rtreecheck('r2')!="ok";
} {1}

do_execsql_test 3.3 {
................................................................................
do_execsql_test 5.0 {
  CREATE VIRTUAL TABLE r3 USING rtree_i32(id, x1, x2, y1, y2);
  WITH x(i) AS (
    SELECT 1 UNION ALL SELECT i+1 FROM x WHERE i<1000
  )
  INSERT INTO r3 SELECT i, i, i, i, i FROM x;
}

do_execsql_test 5.1 {
  BEGIN;
    UPDATE r3_node SET data = set_int32(data, 3, 5000);
    UPDATE r3_node SET data = set_int32(data, 4, 5000);
    SELECT rtreecheck('r3')=='ok'
} 0
do_execsql_test 5.2 {
................................................................................
  BEGIN;
    UPDATE r3_node SET data = set_int32(data, 3, 0);
    UPDATE r3_node SET data = set_int32(data, 4, 0);
    SELECT rtreecheck('r3')=='ok'
} 0

finish_test








>







 







>







 







>







 







<
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
...
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
...
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
...
154
155
156
157
158
159
160

    CREATE VIRTUAL TABLE r1 USING $module (id, x1, x2, y1, y2);
    INSERT INTO r1 VALUES(1,  5, 5, 5, 5);  --  3
    INSERT INTO r1 VALUES(2,  6, 6, 6, 6);  --  9
    INSERT INTO r1 VALUES(3,  7, 7, 7, 7);  -- 15
    INSERT INTO r1 VALUES(4,  8, 8, 8, 8);  -- 21
    INSERT INTO r1 VALUES(5,  9, 9, 9, 9);  -- 27
  "
  sqlite3_db_config db DEFENSIVE 0
}

setup_simple_db
do_execsql_test 2.1 { 
  SELECT rtreecheck('r1') 
} {ok}

................................................................................

do_execsql_test 3.1 { 
  CREATE VIRTUAL TABLE r2 USING rtree_i32(id, x1, x2);
  INSERT INTO r2 VALUES(2, -1*(1<<31), -1*(1<<31)+5);
  SELECT rtreecheck('r2') 
} {ok}

sqlite3_db_config db DEFENSIVE 0
do_execsql_test 3.2 {
  BEGIN;
    UPDATE r2_node SET data = X'123456';
    SELECT rtreecheck('r2')!="ok";
} {1}

do_execsql_test 3.3 {
................................................................................
do_execsql_test 5.0 {
  CREATE VIRTUAL TABLE r3 USING rtree_i32(id, x1, x2, y1, y2);
  WITH x(i) AS (
    SELECT 1 UNION ALL SELECT i+1 FROM x WHERE i<1000
  )
  INSERT INTO r3 SELECT i, i, i, i, i FROM x;
}
sqlite3_db_config db DEFENSIVE 0
do_execsql_test 5.1 {
  BEGIN;
    UPDATE r3_node SET data = set_int32(data, 3, 5000);
    UPDATE r3_node SET data = set_int32(data, 4, 5000);
    SELECT rtreecheck('r3')=='ok'
} 0
do_execsql_test 5.2 {
................................................................................
  BEGIN;
    UPDATE r3_node SET data = set_int32(data, 3, 0);
    UPDATE r3_node SET data = set_int32(data, 4, 0);
    SELECT rtreecheck('r3')=='ok'
} 0

finish_test

Changes to ext/session/sessionC.test.

191
192
193
194
195
196
197
198
    SELECT * FROM t3;
  }
} {1 1 3 3}



finish_test








<
191
192
193
194
195
196
197

    SELECT * FROM t3;
  }
} {1 1 3 3}



finish_test

Changes to ext/session/sessionD.test.

251
252
253
254
255
256
257
258
} {0 {}}
S delete
do_catchsql_test 4.5.2 {
  SELECT * FROM ixua.i8;
} {1 {no such table: ixua.i8}}

finish_test








<
251
252
253
254
255
256
257

} {0 {}}
S delete
do_catchsql_test 4.5.2 {
  SELECT * FROM ixua.i8;
} {1 {no such table: ixua.i8}}

finish_test

Changes to ext/session/sessionE.test.

107
108
109
110
111
112
113
114
115
  {INSERT t2 0 X. {} {i 7 i 8}}
}


S delete

finish_test









<
<
107
108
109
110
111
112
113


  {INSERT t2 0 X. {} {i 7 i 8}}
}


S delete

finish_test


Changes to ext/session/sessionF.test.

288
289
290
291
292
293
294
295
  }

  do_test 3.$tn { set res } [list {*}$result]
}


finish_test








<
288
289
290
291
292
293
294

  }

  do_test 3.$tn { set res } [list {*}$result]
}


finish_test

Changes to ext/session/sessionG.test.

244
245
246
247
248
249
250
251
  SELECT count(*) FROM t1 WHERE number_name(a+1) IS NOT b; 
} {0}

# db eval { SELECT * FROM t1 } { puts "$a || $b" }


finish_test








<
244
245
246
247
248
249
250

  SELECT count(*) FROM t1 WHERE number_name(a+1) IS NOT b; 
} {0}

# db eval { SELECT * FROM t1 } { puts "$a || $b" }


finish_test

Changes to ext/session/sessionH.test.

32
33
34
35
36
37
38
39
    INSERT INTO t1 SELECT 'abcde', randomblob(16), i FROM s;
  }
  compare_db db db2
} {}


finish_test








<
32
33
34
35
36
37
38

    INSERT INTO t1 SELECT 'abcde', randomblob(16), i FROM s;
  }
  compare_db db db2
} {}


finish_test

Changes to ext/session/sessionfault2.test.

278
279
280
281
282
283
284
285
} -test {
  catch { R delete } 
  faultsim_test_result {0 {}} {1 SQLITE_NOMEM}
}


finish_test








<
278
279
280
281
282
283
284

} -test {
  catch { R delete } 
  faultsim_test_result {0 {}} {1 SQLITE_NOMEM}
}


finish_test

Changes to ext/session/sessionrebase.test.

470
471
472
473
474
475
476
477
    R configure $::rebase
    expr [catch {R rebase $P}]==0
  } $rebasable

  catch { R delete }
}
finish_test








<
470
471
472
473
474
475
476

    R configure $::rebase
    expr [catch {R rebase $P}]==0
  } $rebasable

  catch { R delete }
}
finish_test

Changes to ext/session/sessionstat1.test.

304
305
306
307
308
309
310
311
    return "REPLACE"
  }
  sqlite3changeset_apply db2 $C xConflict
  execsql { SELECT * FROM sqlite_stat1 ORDER BY 1,2 } db2
} {t3 null 3}

finish_test








<
304
305
306
307
308
309
310

    return "REPLACE"
  }
  sqlite3changeset_apply db2 $C xConflict
  execsql { SELECT * FROM sqlite_stat1 ORDER BY 1,2 } db2
} {t3 null 3}

finish_test

Changes to ext/session/sessionwor.test.

50
51
52
53
54
55
56
57
do_iterator_test 1.3 t1 {
  DELETE FROM t1;
} {
  {DELETE t1 0 X. {t one t three} {}}
}

finish_test








<
50
51
52
53
54
55
56

do_iterator_test 1.3 t1 {
  DELETE FROM t1;
} {
  {DELETE t1 0 X. {t one t three} {}}
}

finish_test

Changes to src/build.c.

1889
1890
1891
1892
1893
1894
1895


























1896
1897
1898
1899
1900
1901
1902
....
1928
1929
1930
1931
1932
1933
1934




1935
1936
1937
1938
1939
1940
1941
    assert( pPk->nColumn==j );
    assert( pTab->nCol==j );
  }else{
    pPk->nColumn = pTab->nCol;
  }
  recomputeColumnsNotIndexed(pPk);
}



























/*
** This routine is called to report the final ")" that terminates
** a CREATE TABLE statement.
**
** The table structure that other action routines have been building
** is added to the internal hash tables, assuming no errors have
................................................................................

  if( pEnd==0 && pSelect==0 ){
    return;
  }
  assert( !db->mallocFailed );
  p = pParse->pNewTable;
  if( p==0 ) return;





  /* If the db->init.busy is 1 it means we are reading the SQL off the
  ** "sqlite_master" or "sqlite_temp_master" table on the disk.
  ** So do not write to the disk again.  Extract the root page number
  ** for the table from the db->init.newTnum field.  (The page number
  ** should have been put there by the sqliteOpenCb routine.)
  **







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







 







>
>
>
>







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
....
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
    assert( pPk->nColumn==j );
    assert( pTab->nCol==j );
  }else{
    pPk->nColumn = pTab->nCol;
  }
  recomputeColumnsNotIndexed(pPk);
}

/*
** Return true if zName is a shadow table name in the current database
** connection.
**
** zName is temporarily modified while this routine is running, but is
** restored to its original value prior to this routine returning.
*/
static int isShadowTableName(sqlite3 *db, char *zName){
  char *zTail;                  /* Pointer to the last "_" in zName */
  Table *pTab;                  /* Table that zName is a shadow of */
  Module *pMod;                 /* Module for the virtual table */

  zTail = strrchr(zName, '_');
  if( zTail==0 ) return 0;
  *zTail = 0;
  pTab = sqlite3FindTable(db, zName, 0);
  *zTail = '_';
  if( pTab==0 ) return 0;
  if( !IsVirtual(pTab) ) return 0;
  pMod = (Module*)sqlite3HashFind(&db->aModule, pTab->azModuleArg[0]);
  if( pMod==0 ) return 0;
  if( pMod->pModule->iVersion<3 ) return 0;
  if( pMod->pModule->xShadowName==0 ) return 0;
  return pMod->pModule->xShadowName(zTail+1);
}

/*
** This routine is called to report the final ")" that terminates
** a CREATE TABLE statement.
**
** The table structure that other action routines have been building
** is added to the internal hash tables, assuming no errors have
................................................................................

  if( pEnd==0 && pSelect==0 ){
    return;
  }
  assert( !db->mallocFailed );
  p = pParse->pNewTable;
  if( p==0 ) return;

  if( pSelect==0 && isShadowTableName(db, p->zName) ){
    p->tabFlags |= TF_Shadow;
  }

  /* If the db->init.busy is 1 it means we are reading the SQL off the
  ** "sqlite_master" or "sqlite_temp_master" table on the disk.
  ** So do not write to the disk again.  Extract the root page number
  ** for the table from the db->init.newTnum field.  (The page number
  ** should have been put there by the sqliteOpenCb routine.)
  **

Changes to src/dbpage.c.

403
404
405
406
407
408
409

410
411
412
413
414
415
    0,                            /* xCommit */
    0,                            /* xRollback */
    0,                            /* xFindMethod */
    0,                            /* xRename */
    0,                            /* xSavepoint */
    0,                            /* xRelease */
    0,                            /* xRollbackTo */

  };
  return sqlite3_create_module(db, "sqlite_dbpage", &dbpage_module, 0);
}
#elif defined(SQLITE_ENABLE_DBPAGE_VTAB)
int sqlite3DbpageRegister(sqlite3 *db){ return SQLITE_OK; }
#endif /* SQLITE_ENABLE_DBSTAT_VTAB */







>






403
404
405
406
407
408
409
410
411
412
413
414
415
416
    0,                            /* xCommit */
    0,                            /* xRollback */
    0,                            /* xFindMethod */
    0,                            /* xRename */
    0,                            /* xSavepoint */
    0,                            /* xRelease */
    0,                            /* xRollbackTo */
    0                             /* xShadowName */
  };
  return sqlite3_create_module(db, "sqlite_dbpage", &dbpage_module, 0);
}
#elif defined(SQLITE_ENABLE_DBPAGE_VTAB)
int sqlite3DbpageRegister(sqlite3 *db){ return SQLITE_OK; }
#endif /* SQLITE_ENABLE_DBSTAT_VTAB */

Changes to src/dbstat.c.

716
717
718
719
720
721
722

723
724
725
726
727
728
    0,                            /* xCommit */
    0,                            /* xRollback */
    0,                            /* xFindMethod */
    0,                            /* xRename */
    0,                            /* xSavepoint */
    0,                            /* xRelease */
    0,                            /* xRollbackTo */

  };
  return sqlite3_create_module(db, "dbstat", &dbstat_module, 0);
}
#elif defined(SQLITE_ENABLE_DBSTAT_VTAB)
int sqlite3DbstatRegister(sqlite3 *db){ return SQLITE_OK; }
#endif /* SQLITE_ENABLE_DBSTAT_VTAB */







>






716
717
718
719
720
721
722
723
724
725
726
727
728
729
    0,                            /* xCommit */
    0,                            /* xRollback */
    0,                            /* xFindMethod */
    0,                            /* xRename */
    0,                            /* xSavepoint */
    0,                            /* xRelease */
    0,                            /* xRollbackTo */
    0                             /* xShadowName */
  };
  return sqlite3_create_module(db, "dbstat", &dbstat_module, 0);
}
#elif defined(SQLITE_ENABLE_DBSTAT_VTAB)
int sqlite3DbstatRegister(sqlite3 *db){ return SQLITE_OK; }
#endif /* SQLITE_ENABLE_DBSTAT_VTAB */

Changes to src/delete.c.

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
    pTab->nTabRef++;
  }
  if( sqlite3IndexedByLookup(pParse, pItem) ){
    pTab = 0;
  }
  return pTab;
}
































/*
** Check to make sure the given table is writable.  If it is not
** writable, generate an error message and return 1.  If it is
** writable return 0;
*/
int sqlite3IsReadOnly(Parse *pParse, Table *pTab, int viewOk){
  /* A table is not writable under the following circumstances:
  **
  **   1) It is a virtual table and no implementation of the xUpdate method
  **      has been provided, or
  **   2) It is a system table (i.e. sqlite_master), this call is not
  **      part of a nested parse and writable_schema pragma has not 
  **      been specified.
  **
  ** In either case leave an error message in pParse and return non-zero.
  */
  if( ( IsVirtual(pTab) 
     && sqlite3GetVTable(pParse->db, pTab)->pMod->pModule->xUpdate==0 )
   || ( (pTab->tabFlags & TF_Readonly)!=0
     && sqlite3WritableSchema(pParse->db)==0
     && pParse->nested==0)
  ){
    sqlite3ErrorMsg(pParse, "table %s may not be modified", pTab->zName);
    return 1;
  }

#ifndef SQLITE_OMIT_VIEW
  if( !viewOk && pTab->pSelect ){
    sqlite3ErrorMsg(pParse,"cannot modify %s because it is a view",pTab->zName);
    return 1;
  }
#endif
  return 0;







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







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



<







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
    pTab->nTabRef++;
  }
  if( sqlite3IndexedByLookup(pParse, pItem) ){
    pTab = 0;
  }
  return pTab;
}

/* Return true if table pTab is read-only.
**
** A table is read-only if any of the following are true:
**
**   1) It is a virtual table and no implementation of the xUpdate method
**      has been provided
**
**   2) It is a system table (i.e. sqlite_master), this call is not
**      part of a nested parse and writable_schema pragma has not 
**      been specified
**
**   3) The table is a shadow table, the database connection is in
**      defensive mode, and the current sqlite3_prepare()
**      is for a top-level SQL statement.
*/
static int tabIsReadOnly(Parse *pParse, Table *pTab){
  sqlite3 *db;
  if( IsVirtual(pTab) ){
    return sqlite3GetVTable(pParse->db, pTab)->pMod->pModule->xUpdate==0;
  }
  if( (pTab->tabFlags & (TF_Readonly|TF_Shadow))==0 ) return 0;
  db = pParse->db;
  if( (pTab->tabFlags & TF_Readonly)!=0 ){
    return sqlite3WritableSchema(db)==0 && pParse->nested==0;
  }
  assert( pTab->tabFlags & TF_Shadow );
  return (db->flags & SQLITE_Defensive)!=0
           && db->nVdbeExec==0
           && db->pVtabCtx==0;
}

/*
** Check to make sure the given table is writable.  If it is not
** writable, generate an error message and return 1.  If it is
** writable return 0;
*/
int sqlite3IsReadOnly(Parse *pParse, Table *pTab, int viewOk){
  if( tabIsReadOnly(pParse, pTab) ){















    sqlite3ErrorMsg(pParse, "table %s may not be modified", pTab->zName);
    return 1;
  }

#ifndef SQLITE_OMIT_VIEW
  if( !viewOk && pTab->pSelect ){
    sqlite3ErrorMsg(pParse,"cannot modify %s because it is a view",pTab->zName);
    return 1;
  }
#endif
  return 0;

Changes to src/main.c.

3058
3059
3060
3061
3062
3063
3064



3065
3066
3067
3068
3069
3070
3071
                 | SQLITE_CellSizeCk
#endif
#if defined(SQLITE_ENABLE_FTS3_TOKENIZER)
                 | SQLITE_Fts3Tokenizer
#endif
#if defined(SQLITE_ENABLE_QPSG)
                 | SQLITE_EnableQPSG



#endif
      ;
  sqlite3HashInit(&db->aCollSeq);
#ifndef SQLITE_OMIT_VIRTUALTABLE
  sqlite3HashInit(&db->aModule);
#endif








>
>
>







3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
                 | SQLITE_CellSizeCk
#endif
#if defined(SQLITE_ENABLE_FTS3_TOKENIZER)
                 | SQLITE_Fts3Tokenizer
#endif
#if defined(SQLITE_ENABLE_QPSG)
                 | SQLITE_EnableQPSG
#endif
#if defined(SQLITE_DEFAULT_DEFENSIVE)
                 | SQLITE_Defensive
#endif
      ;
  sqlite3HashInit(&db->aCollSeq);
#ifndef SQLITE_OMIT_VIRTUALTABLE
  sqlite3HashInit(&db->aModule);
#endif

Changes to src/pragma.c.

2473
2474
2475
2476
2477
2478
2479
2480

2481
2482
2483
2484
2485
2486
2487
  0,                           /* xSync - sync transaction */
  0,                           /* xCommit - commit transaction */
  0,                           /* xRollback - rollback transaction */
  0,                           /* xFindFunction - function overloading */
  0,                           /* xRename - rename the table */
  0,                           /* xSavepoint */
  0,                           /* xRelease */
  0                            /* xRollbackTo */

};

/*
** Check to see if zTabName is really the name of a pragma.  If it is,
** then register an eponymous virtual table for that pragma and return
** a pointer to the Module object for the new virtual table.
*/







|
>







2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
  0,                           /* xSync - sync transaction */
  0,                           /* xCommit - commit transaction */
  0,                           /* xRollback - rollback transaction */
  0,                           /* xFindFunction - function overloading */
  0,                           /* xRename - rename the table */
  0,                           /* xSavepoint */
  0,                           /* xRelease */
  0,                           /* xRollbackTo */
  0                            /* xShadowName */
};

/*
** Check to see if zTabName is really the name of a pragma.  If it is,
** then register an eponymous virtual table for that pragma and return
** a pointer to the Module object for the new virtual table.
*/

Changes to src/sqlite.h.in.

2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172

2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
....
6318
6319
6320
6321
6322
6323
6324



6325
6326
6327
6328
6329
6330
6331
** <li> sqlite3_db_config(db, SQLITE_DBCONFIG_RESET_DATABASE, 0, 0);
** </ol>
** Because resetting a database is destructive and irreversible, the
** process requires the use of this obscure API and multiple steps to help
** ensure that it does not happen by accident.
**
** <dt>SQLITE_DBCONFIG_DEFENSIVE</dt>
** <dd>The SQLITE_DBCONFIG_DEFENSIVE option actives or deactivates the
** "defensive" flag for a database connection.  When the defensive
** flag is enabled, some obscure features of SQLite are disabled in order
** to reduce the attack surface. Applications that run untrusted SQL
** can activate this flag to reduce the risk of zero-day exploits.
** <p>
** Features disabled by the defensive flag include:
** <ul>
** <li>The [PRAGMA writable_schema=ON] statement.
** <li>Writes to the [sqlite_dbpage] virtual table.

** </ul>
** New restrictions may be added in future releases.
** <p>
** To be clear: It should never be possible for hostile SQL to cause
** arbitrary memory reads, memory leaks, buffer overflows, assertion
** faults, arbitrary code execution, crashes, or other mischief, regardless
** of the value of the defensive flag.  Any occurrance of these problems
** is considered a serious bug and will be fixed promptly.  It is not
** necessary to enable the defensive flag in order to make SQLite secure
** against attack. The defensive flag merely provides an additional layer
** of defense against unknown vulnerabilities.
** </dd>
** </dl>
*/
#define SQLITE_DBCONFIG_MAINDBNAME            1000 /* const char* */
#define SQLITE_DBCONFIG_LOOKASIDE             1001 /* void* int int */
#define SQLITE_DBCONFIG_ENABLE_FKEY           1002 /* int int* */
#define SQLITE_DBCONFIG_ENABLE_TRIGGER        1003 /* int int* */
................................................................................
                       void **ppArg);
  int (*xRename)(sqlite3_vtab *pVtab, const char *zNew);
  /* The methods above are in version 1 of the sqlite_module object. Those 
  ** below are for version 2 and greater. */
  int (*xSavepoint)(sqlite3_vtab *pVTab, int);
  int (*xRelease)(sqlite3_vtab *pVTab, int);
  int (*xRollbackTo)(sqlite3_vtab *pVTab, int);



};

/*
** CAPI3REF: Virtual Table Indexing Information
** KEYWORDS: sqlite3_index_info
**
** The sqlite3_index_info structure and its substructures is used as part







|

|
|
|
<
<

|
|
>

<
<
<
<
<
<
<
<
<
<







 







>
>
>







2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167


2168
2169
2170
2171
2172










2173
2174
2175
2176
2177
2178
2179
....
6307
6308
6309
6310
6311
6312
6313
6314
6315
6316
6317
6318
6319
6320
6321
6322
6323
** <li> sqlite3_db_config(db, SQLITE_DBCONFIG_RESET_DATABASE, 0, 0);
** </ol>
** Because resetting a database is destructive and irreversible, the
** process requires the use of this obscure API and multiple steps to help
** ensure that it does not happen by accident.
**
** <dt>SQLITE_DBCONFIG_DEFENSIVE</dt>
** <dd>The SQLITE_DBCONFIG_DEFENSIVE option activates or deactivates the
** "defensive" flag for a database connection.  When the defensive
** flag is enabled, language features that allow ordinary SQL to 
** deliberately corrupt the database file are disabled.  The disabled
** features include but are not limited to the following:


** <ul>
** <li> The [PRAGMA writable_schema=ON] statement.
** <li> Writes to the [sqlite_dbpage] virtual table.
** <li> Direct writes to shadow tables.
** </ul>










** </dd>
** </dl>
*/
#define SQLITE_DBCONFIG_MAINDBNAME            1000 /* const char* */
#define SQLITE_DBCONFIG_LOOKASIDE             1001 /* void* int int */
#define SQLITE_DBCONFIG_ENABLE_FKEY           1002 /* int int* */
#define SQLITE_DBCONFIG_ENABLE_TRIGGER        1003 /* int int* */
................................................................................
                       void **ppArg);
  int (*xRename)(sqlite3_vtab *pVtab, const char *zNew);
  /* The methods above are in version 1 of the sqlite_module object. Those 
  ** below are for version 2 and greater. */
  int (*xSavepoint)(sqlite3_vtab *pVTab, int);
  int (*xRelease)(sqlite3_vtab *pVTab, int);
  int (*xRollbackTo)(sqlite3_vtab *pVTab, int);
  /* The methods above are in versions 1 and 2 of the sqlite_module object.
  ** Those below are for version 3 and greater. */
  int (*xShadowName)(const char*);
};

/*
** CAPI3REF: Virtual Table Indexing Information
** KEYWORDS: sqlite3_index_info
**
** The sqlite3_index_info structure and its substructures is used as part

Changes to src/sqliteInt.h.

1997
1998
1999
2000
2001
2002
2003

2004
2005
2006
2007
2008
2009
2010
#define TF_HasStat1        0x0010    /* nRowLogEst set from sqlite_stat1 */
#define TF_WithoutRowid    0x0020    /* No rowid.  PRIMARY KEY is the key */
#define TF_NoVisibleRowid  0x0040    /* No user-visible "rowid" column */
#define TF_OOOHidden       0x0080    /* Out-of-Order hidden columns */
#define TF_StatsUsed       0x0100    /* Query planner decisions affected by
                                     ** Index.aiRowLogEst[] values */
#define TF_HasNotNull      0x0200    /* Contains NOT NULL constraints */


/*
** Test to see whether or not a table is a virtual table.  This is
** done as a macro so that it will be optimized out when virtual
** table support is omitted from the build.
*/
#ifndef SQLITE_OMIT_VIRTUALTABLE







>







1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
#define TF_HasStat1        0x0010    /* nRowLogEst set from sqlite_stat1 */
#define TF_WithoutRowid    0x0020    /* No rowid.  PRIMARY KEY is the key */
#define TF_NoVisibleRowid  0x0040    /* No user-visible "rowid" column */
#define TF_OOOHidden       0x0080    /* Out-of-Order hidden columns */
#define TF_StatsUsed       0x0100    /* Query planner decisions affected by
                                     ** Index.aiRowLogEst[] values */
#define TF_HasNotNull      0x0200    /* Contains NOT NULL constraints */
#define TF_Shadow          0x0400    /* True for a shadow table */

/*
** Test to see whether or not a table is a virtual table.  This is
** done as a macro so that it will be optimized out when virtual
** table support is omitted from the build.
*/
#ifndef SQLITE_OMIT_VIRTUALTABLE

Changes to src/vacuum.c.

162
163
164
165
166
167
168
169

170
171
172
173
174
175
176
  saved_flags = db->flags;
  saved_mDbFlags = db->mDbFlags;
  saved_nChange = db->nChange;
  saved_nTotalChange = db->nTotalChange;
  saved_mTrace = db->mTrace;
  db->flags |= SQLITE_WriteSchema | SQLITE_IgnoreChecks;
  db->mDbFlags |= DBFLAG_PreferBuiltin | DBFLAG_Vacuum;
  db->flags &= ~(SQLITE_ForeignKeys | SQLITE_ReverseOrder | SQLITE_CountRows);

  db->mTrace = 0;

  zDbMain = db->aDb[iDb].zDbSName;
  pMain = db->aDb[iDb].pBt;
  isMemDb = sqlite3PagerIsMemdb(sqlite3BtreePager(pMain));

  /* Attach the temporary database as 'vacuum_db'. The synchronous pragma







|
>







162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
  saved_flags = db->flags;
  saved_mDbFlags = db->mDbFlags;
  saved_nChange = db->nChange;
  saved_nTotalChange = db->nTotalChange;
  saved_mTrace = db->mTrace;
  db->flags |= SQLITE_WriteSchema | SQLITE_IgnoreChecks;
  db->mDbFlags |= DBFLAG_PreferBuiltin | DBFLAG_Vacuum;
  db->flags &= ~(SQLITE_ForeignKeys | SQLITE_ReverseOrder
                   | SQLITE_Defensive | SQLITE_CountRows);
  db->mTrace = 0;

  zDbMain = db->aDb[iDb].zDbSName;
  pMain = db->aDb[iDb].pBt;
  isMemDb = sqlite3PagerIsMemdb(sqlite3BtreePager(pMain));

  /* Attach the temporary database as 'vacuum_db'. The synchronous pragma

Changes to test/alter2.test.

60
61
62
63
64
65
66

67
68
69
70
71
72
73
..
87
88
89
90
91
92
93

94
95
96
97
98
99
100
# to the supplied value. This is 2 if the added column has a default that is
# NULL, or 3 otherwise. 
#
proc alter_table {tbl sql {file_format 2}} {
  sqlite3 dbat test.db
  set s [string map {' ''} $sql]
  set t [string map {' ''} $tbl]

  dbat eval [subst {
    PRAGMA writable_schema = 1;
    UPDATE sqlite_master SET sql = '$s' WHERE name = '$t' AND type = 'table';
    PRAGMA writable_schema = 0;
  }]
  dbat close
  set_file_format 2
................................................................................
  catchsql {SELECT substr('abcdefg',1,3)}
} {1 {bad function}}


#-----------------------------------------------------------------------
# Some basic tests to make sure short rows are handled.
#

do_test alter2-1.1 {
  execsql {
    CREATE TABLE abc(a, b);
    INSERT INTO abc VALUES(1, 2);
    INSERT INTO abc VALUES(3, 4);
    INSERT INTO abc VALUES(5, 6);
  }







>







 







>







60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
..
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# to the supplied value. This is 2 if the added column has a default that is
# NULL, or 3 otherwise. 
#
proc alter_table {tbl sql {file_format 2}} {
  sqlite3 dbat test.db
  set s [string map {' ''} $sql]
  set t [string map {' ''} $tbl]
  sqlite3_db_config dbat DEFENSIVE 0
  dbat eval [subst {
    PRAGMA writable_schema = 1;
    UPDATE sqlite_master SET sql = '$s' WHERE name = '$t' AND type = 'table';
    PRAGMA writable_schema = 0;
  }]
  dbat close
  set_file_format 2
................................................................................
  catchsql {SELECT substr('abcdefg',1,3)}
} {1 {bad function}}


#-----------------------------------------------------------------------
# Some basic tests to make sure short rows are handled.
#
sqlite3_db_config db DEFENSIVE 0
do_test alter2-1.1 {
  execsql {
    CREATE TABLE abc(a, b);
    INSERT INTO abc VALUES(1, 2);
    INSERT INTO abc VALUES(3, 4);
    INSERT INTO abc VALUES(5, 6);
  }

Changes to test/altercol.test.

549
550
551
552
553
554
555

556
557
558
559
560
561
562

do_execsql_test 13.1.3 {
  DROP TRIGGER tr1;
  CREATE INDEX x1i ON x1(i);
  SELECT sql FROM sqlite_master WHERE name='x1i';
} {{CREATE INDEX x1i ON x1(i)}}


do_execsql_test 13.1.4 {
  PRAGMA writable_schema = 1;
  UPDATE sqlite_master SET sql = 'CREATE INDEX x1i ON x1(j)' WHERE name='x1i';
} {}

do_catchsql_test 13.1.5 {
  ALTER TABLE x1 RENAME COLUMN t TO ttt;







>







549
550
551
552
553
554
555
556
557
558
559
560
561
562
563

do_execsql_test 13.1.3 {
  DROP TRIGGER tr1;
  CREATE INDEX x1i ON x1(i);
  SELECT sql FROM sqlite_master WHERE name='x1i';
} {{CREATE INDEX x1i ON x1(i)}}

sqlite3_db_config db DEFENSIVE 0
do_execsql_test 13.1.4 {
  PRAGMA writable_schema = 1;
  UPDATE sqlite_master SET sql = 'CREATE INDEX x1i ON x1(j)' WHERE name='x1i';
} {}

do_catchsql_test 13.1.5 {
  ALTER TABLE x1 RENAME COLUMN t TO ttt;

Changes to test/alterlegacy.test.

463
464
465
466
467
468
469
470
}
do_execsql_test 14.6 {
  ALTER TABLE t1 RENAME TO tt1;
}


finish_test








<
463
464
465
466
467
468
469

}
do_execsql_test 14.6 {
  ALTER TABLE t1 RENAME TO tt1;
}


finish_test

Changes to test/altertab.test.

501
502
503
504
505
506
507
508

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


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

Changes to test/altertab2.test.

83
84
85
86
87
88
89
90
  {CREATE TABLE c1(x REFERENCES "p3")}
  {CREATE TABLE c2(x, FOREIGN KEY (x) REFERENCES "p3")}
  {CREATE TABLE c3(x, FOREIGN KEY (x) REFERENCES "p3"(a))}
}


finish_test








<
83
84
85
86
87
88
89

  {CREATE TABLE c1(x REFERENCES "p3")}
  {CREATE TABLE c2(x, FOREIGN KEY (x) REFERENCES "p3")}
  {CREATE TABLE c3(x, FOREIGN KEY (x) REFERENCES "p3"(a))}
}


finish_test

Changes to test/analyze.test.

346
347
348
349
350
351
352

353
354
355
356
357
358
359
  } {t4i1 t4i2 t4}
}

# This test corrupts the database file so it must be the last test
# in the series.
#
do_test analyze-5.99 {

  execsql {
    PRAGMA writable_schema=on;
    UPDATE sqlite_master SET sql='nonsense' WHERE name='sqlite_stat1';
  }
  db close
  catch { sqlite3 db test.db }
  catchsql {







>







346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
  } {t4i1 t4i2 t4}
}

# This test corrupts the database file so it must be the last test
# in the series.
#
do_test analyze-5.99 {
  sqlite3_db_config db DEFENSIVE 0
  execsql {
    PRAGMA writable_schema=on;
    UPDATE sqlite_master SET sql='nonsense' WHERE name='sqlite_stat1';
  }
  db close
  catch { sqlite3 db test.db }
  catchsql {

Changes to test/autoinc.test.

693
694
695
696
697
698
699

700
701
702
703
704
705
706
...
714
715
716
717
718
719
720

721
722
723
724
725
726
727
...
740
741
742
743
744
745
746

747
748
749
750
751
752
753
...
768
769
770
771
772
773
774

775
776
777
778
779
780
781
...
787
788
789
790
791
792
793

794
795
796
797
798
799
800
...
806
807
808
809
810
811
812

813
814
815
816
817
818
819
...
827
828
829
830
831
832
833

834
835
836
837
838
839
840
# Does not crash if the sqlite_sequence table schema is missing
# or corrupt.
#
do_test autoinc-12.1 {
  db close
  forcedelete test.db
  sqlite3 db test.db

  db eval {
    CREATE TABLE fake_sequence(name TEXT PRIMARY KEY,seq) WITHOUT ROWID;
    PRAGMA writable_schema=on;
    UPDATE sqlite_master SET
     sql=replace(sql,'fake_','sqlite_'),
     name='sqlite_sequence',
     tbl_name='sqlite_sequence'
................................................................................
  }} msg]
  lappend res $msg
} {1 {database disk image is malformed}}
do_test autoinc-12.2 {
  db close
  forcedelete test.db
  sqlite3 db test.db

  db eval {
   CREATE TABLE t1(a INTEGER PRIMARY KEY AUTOINCREMENT, b TEXT);
   INSERT INTO t1(b) VALUES('one');
   PRAGMA writable_schema=on;
   UPDATE sqlite_master SET
     sql=replace(sql,'sqlite_','x_'),
     name='x_sequence',
................................................................................
} else {
  set err {malformed database schema (sqlite_sequence) - near "VIRTUAL": syntax error}
}
do_test autoinc-12.3 {
  db close
  forcedelete test.db
  sqlite3 db test.db

  db eval {
   CREATE TABLE t1(a INTEGER PRIMARY KEY AUTOINCREMENT, b TEXT);
   INSERT INTO t1(b) VALUES('one');
   PRAGMA writable_schema=on;
   UPDATE sqlite_master SET
     sql='CREATE VIRTUAL TABLE sqlite_sequence USING sqlite_dbpage'
    WHERE name='sqlite_sequence';
................................................................................
    INSERT INTO t1(b) VALUES('one');
    CREATE TABLE fake(name TEXT PRIMARY KEY,seq) WITHOUT ROWID;
  }
  set root1 [db one {SELECT rootpage FROM sqlite_master
                     WHERE name='sqlite_sequence'}]
  set root2 [db one {SELECT rootpage FROM sqlite_master
                     WHERE name='fake'}]

  db eval {
   PRAGMA writable_schema=on;
   UPDATE sqlite_master SET rootpage=$root2
    WHERE name='sqlite_sequence';
   UPDATE sqlite_master SET rootpage=$root1
    WHERE name='fake';
  }
................................................................................
  lappend res $msg
} {1 {database disk image is malformed}}
breakpoint
do_test autoinc-12.5 {
  db close
  forcedelete test.db
  sqlite3 db test.db

  db eval {
    CREATE TABLE t1(a INTEGER PRIMARY KEY AUTOINCREMENT, b TEXT);
    INSERT INTO t1(b) VALUES('one');
    PRAGMA writable_schema=on;
    UPDATE sqlite_master SET
       sql='CREATE TABLE sqlite_sequence(x)'
      WHERE name='sqlite_sequence';
................................................................................
  }} msg]
  lappend res $msg
} {1 {database disk image is malformed}}
do_test autoinc-12.6 {
  db close
  forcedelete test.db
  sqlite3 db test.db

  db eval {
    CREATE TABLE t1(a INTEGER PRIMARY KEY AUTOINCREMENT, b TEXT);
    INSERT INTO t1(b) VALUES('one');
    PRAGMA writable_schema=on;
    UPDATE sqlite_master SET
       sql='CREATE TABLE sqlite_sequence(x,y INTEGER PRIMARY KEY)'
      WHERE name='sqlite_sequence';
................................................................................
  }} msg]
  lappend res $msg
} {0 ok}
do_test autoinc-12.7 {
  db close
  forcedelete test.db
  sqlite3 db test.db

  db eval {
    CREATE TABLE t1(a INTEGER PRIMARY KEY AUTOINCREMENT, b TEXT);
    INSERT INTO t1(b) VALUES('one');
    PRAGMA writable_schema=on;
    UPDATE sqlite_master SET
       sql='CREATE TABLE sqlite_sequence(y INTEGER PRIMARY KEY,x)'
      WHERE name='sqlite_sequence';







>







 







>







 







>







 







>







 







>







 







>







 







>







693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
...
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
...
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
...
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
...
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
...
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
...
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
# Does not crash if the sqlite_sequence table schema is missing
# or corrupt.
#
do_test autoinc-12.1 {
  db close
  forcedelete test.db
  sqlite3 db test.db
  sqlite3_db_config db DEFENSIVE 0
  db eval {
    CREATE TABLE fake_sequence(name TEXT PRIMARY KEY,seq) WITHOUT ROWID;
    PRAGMA writable_schema=on;
    UPDATE sqlite_master SET
     sql=replace(sql,'fake_','sqlite_'),
     name='sqlite_sequence',
     tbl_name='sqlite_sequence'
................................................................................
  }} msg]
  lappend res $msg
} {1 {database disk image is malformed}}
do_test autoinc-12.2 {
  db close
  forcedelete test.db
  sqlite3 db test.db
  sqlite3_db_config db DEFENSIVE 0
  db eval {
   CREATE TABLE t1(a INTEGER PRIMARY KEY AUTOINCREMENT, b TEXT);
   INSERT INTO t1(b) VALUES('one');
   PRAGMA writable_schema=on;
   UPDATE sqlite_master SET
     sql=replace(sql,'sqlite_','x_'),
     name='x_sequence',
................................................................................
} else {
  set err {malformed database schema (sqlite_sequence) - near "VIRTUAL": syntax error}
}
do_test autoinc-12.3 {
  db close
  forcedelete test.db
  sqlite3 db test.db
  sqlite3_db_config db DEFENSIVE 0
  db eval {
   CREATE TABLE t1(a INTEGER PRIMARY KEY AUTOINCREMENT, b TEXT);
   INSERT INTO t1(b) VALUES('one');
   PRAGMA writable_schema=on;
   UPDATE sqlite_master SET
     sql='CREATE VIRTUAL TABLE sqlite_sequence USING sqlite_dbpage'
    WHERE name='sqlite_sequence';
................................................................................
    INSERT INTO t1(b) VALUES('one');
    CREATE TABLE fake(name TEXT PRIMARY KEY,seq) WITHOUT ROWID;
  }
  set root1 [db one {SELECT rootpage FROM sqlite_master
                     WHERE name='sqlite_sequence'}]
  set root2 [db one {SELECT rootpage FROM sqlite_master
                     WHERE name='fake'}]
  sqlite3_db_config db DEFENSIVE 0
  db eval {
   PRAGMA writable_schema=on;
   UPDATE sqlite_master SET rootpage=$root2
    WHERE name='sqlite_sequence';
   UPDATE sqlite_master SET rootpage=$root1
    WHERE name='fake';
  }
................................................................................
  lappend res $msg
} {1 {database disk image is malformed}}
breakpoint
do_test autoinc-12.5 {
  db close
  forcedelete test.db
  sqlite3 db test.db
  sqlite3_db_config db DEFENSIVE 0
  db eval {
    CREATE TABLE t1(a INTEGER PRIMARY KEY AUTOINCREMENT, b TEXT);
    INSERT INTO t1(b) VALUES('one');
    PRAGMA writable_schema=on;
    UPDATE sqlite_master SET
       sql='CREATE TABLE sqlite_sequence(x)'
      WHERE name='sqlite_sequence';
................................................................................
  }} msg]
  lappend res $msg
} {1 {database disk image is malformed}}
do_test autoinc-12.6 {
  db close
  forcedelete test.db
  sqlite3 db test.db
  sqlite3_db_config db DEFENSIVE 0
  db eval {
    CREATE TABLE t1(a INTEGER PRIMARY KEY AUTOINCREMENT, b TEXT);
    INSERT INTO t1(b) VALUES('one');
    PRAGMA writable_schema=on;
    UPDATE sqlite_master SET
       sql='CREATE TABLE sqlite_sequence(x,y INTEGER PRIMARY KEY)'
      WHERE name='sqlite_sequence';
................................................................................
  }} msg]
  lappend res $msg
} {0 ok}
do_test autoinc-12.7 {
  db close
  forcedelete test.db
  sqlite3 db test.db
  sqlite3_db_config db DEFENSIVE 0
  db eval {
    CREATE TABLE t1(a INTEGER PRIMARY KEY AUTOINCREMENT, b TEXT);
    INSERT INTO t1(b) VALUES('one');
    PRAGMA writable_schema=on;
    UPDATE sqlite_master SET
       sql='CREATE TABLE sqlite_sequence(y INTEGER PRIMARY KEY,x)'
      WHERE name='sqlite_sequence';

Changes to test/bestindex5.test.

243
244
245
246
247
248
249
250
do_execsql_test 3.3 { SELECT rowid, * FROM t4 WHERE x!=245; } {}
do_execsql_test 3.4 { SELECT rowid, * FROM t4 WHERE x!='245'; } {}

do_execsql_test 3.5 { SELECT rowid, * FROM t4 WHERE rowid!=1 OR x!='245'; } {}


finish_test








<
243
244
245
246
247
248
249

do_execsql_test 3.3 { SELECT rowid, * FROM t4 WHERE x!=245; } {}
do_execsql_test 3.4 { SELECT rowid, * FROM t4 WHERE x!='245'; } {}

do_execsql_test 3.5 { SELECT rowid, * FROM t4 WHERE rowid!=1 OR x!='245'; } {}


finish_test

Changes to test/capi3.test.

737
738
739
740
741
742
743

744
745
746
747
748
749
750
...
755
756
757
758
759
760
761

762
763
764
765
766
767
768
    execsql {
      CREATE TABLE t1(a);
    }
    db close
  } {}
  do_test capi3-8.2 {
    sqlite3 db test.db

    execsql {
      PRAGMA writable_schema=ON;
      INSERT INTO sqlite_master VALUES(NULL,NULL,NULL,NULL,NULL);
    }
    db close
  } {}
  do_test capi3-8.3 {
................................................................................
  } {1 {malformed database schema (?)}}
  do_test capi3-8.4 {
    # Build a 5-field row record. The first field is a string 'table', and
    # subsequent fields are all NULL.
    db close
    forcedelete test.db test.db-journal
    sqlite3 db test.db

    execsql {
      CREATE TABLE t1(a);
      PRAGMA writable_schema=ON;
      INSERT INTO sqlite_master VALUES('table',NULL,NULL,NULL,NULL);
    }
    db close
  } {};







>







 







>







737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
...
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
    execsql {
      CREATE TABLE t1(a);
    }
    db close
  } {}
  do_test capi3-8.2 {
    sqlite3 db test.db
    sqlite3_db_config db DEFENSIVE 0
    execsql {
      PRAGMA writable_schema=ON;
      INSERT INTO sqlite_master VALUES(NULL,NULL,NULL,NULL,NULL);
    }
    db close
  } {}
  do_test capi3-8.3 {
................................................................................
  } {1 {malformed database schema (?)}}
  do_test capi3-8.4 {
    # Build a 5-field row record. The first field is a string 'table', and
    # subsequent fields are all NULL.
    db close
    forcedelete test.db test.db-journal
    sqlite3 db test.db
    sqlite3_db_config db DEFENSIVE 0
    execsql {
      CREATE TABLE t1(a);
      PRAGMA writable_schema=ON;
      INSERT INTO sqlite_master VALUES('table',NULL,NULL,NULL,NULL);
    }
    db close
  } {};

Changes to test/capi3c.test.

682
683
684
685
686
687
688

689
690
691
692
693
694
695
...
700
701
702
703
704
705
706

707
708
709
710
711
712
713
    execsql {
      CREATE TABLE t1(a);
    }
    db close
  } {}
  do_test capi3c-8.2 {
    sqlite3 db test.db

    execsql {
      PRAGMA writable_schema=ON;
      INSERT INTO sqlite_master VALUES(NULL,NULL,NULL,NULL,NULL);
    }
    db close
  } {}
  do_test capi3c-8.3 {
................................................................................
  } {1 {malformed database schema (?)}}
  do_test capi3c-8.4 {
    # Build a 5-field row record. The first field is a string 'table', and
    # subsequent fields are all NULL.
    db close
    forcedelete test.db test.db-journal
    sqlite3 db test.db

    execsql {
      CREATE TABLE t1(a);
      PRAGMA writable_schema=ON;
      INSERT INTO sqlite_master VALUES('table',NULL,NULL,NULL,NULL);
    }
    db close
  } {};







>







 







>







682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
...
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
    execsql {
      CREATE TABLE t1(a);
    }
    db close
  } {}
  do_test capi3c-8.2 {
    sqlite3 db test.db
    sqlite3_db_config db DEFENSIVE 0
    execsql {
      PRAGMA writable_schema=ON;
      INSERT INTO sqlite_master VALUES(NULL,NULL,NULL,NULL,NULL);
    }
    db close
  } {}
  do_test capi3c-8.3 {
................................................................................
  } {1 {malformed database schema (?)}}
  do_test capi3c-8.4 {
    # Build a 5-field row record. The first field is a string 'table', and
    # subsequent fields are all NULL.
    db close
    forcedelete test.db test.db-journal
    sqlite3 db test.db
    sqlite3_db_config db DEFENSIVE 0
    execsql {
      CREATE TABLE t1(a);
      PRAGMA writable_schema=ON;
      INSERT INTO sqlite_master VALUES('table',NULL,NULL,NULL,NULL);
    }
    db close
  } {};

Changes to test/corrupt.test.

128
129
130
131
132
133
134

135
136
137
138
139
140
141
  sqlite3 db test.db
  list
} {}
do_test corrupt-3.2 {
  set t1_r [execsql {SELECT rootpage FROM sqlite_master WHERE name = 't1i1'}]
  set t1i1_r [execsql {SELECT rootpage FROM sqlite_master WHERE name = 't1'}]
  set cookie [expr [execsql {PRAGMA schema_version}] + 1]

  execsql "
    PRAGMA writable_schema = 1;
    UPDATE sqlite_master SET rootpage = $t1_r WHERE name = 't1';
    UPDATE sqlite_master SET rootpage = $t1i1_r WHERE name = 't1i1';
    PRAGMA writable_schema = 0;
    PRAGMA schema_version = $cookie;
  "







>







128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
  sqlite3 db test.db
  list
} {}
do_test corrupt-3.2 {
  set t1_r [execsql {SELECT rootpage FROM sqlite_master WHERE name = 't1i1'}]
  set t1i1_r [execsql {SELECT rootpage FROM sqlite_master WHERE name = 't1'}]
  set cookie [expr [execsql {PRAGMA schema_version}] + 1]
  sqlite3_db_config db DEFENSIVE 0
  execsql "
    PRAGMA writable_schema = 1;
    UPDATE sqlite_master SET rootpage = $t1_r WHERE name = 't1';
    UPDATE sqlite_master SET rootpage = $t1i1_r WHERE name = 't1i1';
    PRAGMA writable_schema = 0;
    PRAGMA schema_version = $cookie;
  "

Changes to test/corrupt2.test.

129
130
131
132
133
134
135

136
137
138
139
140
141
142
...
261
262
263
264
265
266
267

268
269
270
271
272
273
274
do_test corrupt2-2.1 {

  forcedelete corrupt.db
  forcedelete corrupt.db-journal
  forcecopy test.db corrupt.db

  sqlite3 db2 corrupt.db 

  execsql "
    $::presql
    CREATE INDEX a1 ON abc(a);
    CREATE INDEX a2 ON abc(b);
    PRAGMA writable_schema = 1;
    UPDATE sqlite_master 
      SET name = 'a3', sql = 'CREATE INDEX a3' || substr(sql, 16, 10000)
................................................................................
  array set A $args

  catch {db close}
  forcedelete corrupt.db
  forcedelete corrupt.db-journal

  sqlite3 db corrupt.db 

  db eval $::presql
  eval $A(-tclprep)
  db eval $A(-sqlprep)
  db close

  eval $A(-corrupt)








>







 







>







129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
...
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
do_test corrupt2-2.1 {

  forcedelete corrupt.db
  forcedelete corrupt.db-journal
  forcecopy test.db corrupt.db

  sqlite3 db2 corrupt.db 
  sqlite3_db_config db2 DEFENSIVE 0
  execsql "
    $::presql
    CREATE INDEX a1 ON abc(a);
    CREATE INDEX a2 ON abc(b);
    PRAGMA writable_schema = 1;
    UPDATE sqlite_master 
      SET name = 'a3', sql = 'CREATE INDEX a3' || substr(sql, 16, 10000)
................................................................................
  array set A $args

  catch {db close}
  forcedelete corrupt.db
  forcedelete corrupt.db-journal

  sqlite3 db corrupt.db 
  sqlite3_db_config db DEFENSIVE 0
  db eval $::presql
  eval $A(-tclprep)
  db eval $A(-sqlprep)
  db close

  eval $A(-corrupt)

Changes to test/corrupt5.test.

29
30
31
32
33
34
35

36
37
38
39
40
41
42
  finish_test
  return
}

# Create a database with a freelist containing at least two pages.
#
do_test corrupt5-1.1 {

  execsql {
    CREATE TABLE t1(a,b,c);
    CREATE INDEX i1 ON t1(a,b);
    PRAGMA writable_schema=ON;
    UPDATE sqlite_master SET name=NULL, sql=NULL WHERE name='i1';
  }
  db close







>







29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
  finish_test
  return
}

# Create a database with a freelist containing at least two pages.
#
do_test corrupt5-1.1 {
  sqlite3_db_config db DEFENSIVE 0
  execsql {
    CREATE TABLE t1(a,b,c);
    CREATE INDEX i1 ON t1(a,b);
    PRAGMA writable_schema=ON;
    UPDATE sqlite_master SET name=NULL, sql=NULL WHERE name='i1';
  }
  db close

Changes to test/corruptI.test.

218
219
220
221
222
223
224

225
226
227
228
229
230
231
  PRAGMA auto_vacuum=0;
  CREATE TABLE t1(x PRIMARY KEY, y);
  INSERT INTO t1 VALUES('a', 'A');
  INSERT INTO t1 VALUES('b', 'A');
  INSERT INTO t1 VALUES('c', 'A');
  SELECT name FROM sqlite_master;
} {t1 sqlite_autoindex_t1_1}

do_execsql_test 7.1 {
  PRAGMA writable_schema = 1;
  DELETE FROM sqlite_master WHERE name = 'sqlite_autoindex_t1_1';
}
do_test 7.2 {
  db close
  sqlite3 db test.db







>







218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
  PRAGMA auto_vacuum=0;
  CREATE TABLE t1(x PRIMARY KEY, y);
  INSERT INTO t1 VALUES('a', 'A');
  INSERT INTO t1 VALUES('b', 'A');
  INSERT INTO t1 VALUES('c', 'A');
  SELECT name FROM sqlite_master;
} {t1 sqlite_autoindex_t1_1}
sqlite3_db_config db DEFENSIVE 0
do_execsql_test 7.1 {
  PRAGMA writable_schema = 1;
  DELETE FROM sqlite_master WHERE name = 'sqlite_autoindex_t1_1';
}
do_test 7.2 {
  db close
  sqlite3 db test.db

Changes to test/corruptK.test.

139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
    PRAGMA page_size=1024;
    CREATE TABLE t1(a, b, c);
    CREATE TABLE t2(a, b, c);
    CREATE TABLE t3(a, b, c);
    CREATE TABLE t4(a, b, c);
    CREATE TABLE t5(a, b, c);
  }
  
  do_execsql_test 3.2 {
    UPDATE sqlite_dbpage SET data = hex2blob('
   000: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3.
   010: 04 00 01 01 20 40 20 20 00 00 3e d9 00 00 00 06 .... @  ..>.....
   020: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 04 ................
   030: 0f 00 00 00 00 00 00 00 00 00 00 01 00 00 83 00 ................
   040: 00 00 00 00 00 00 00 00 00 00 00 00 00 38 00 00 .............8..







|







139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
    PRAGMA page_size=1024;
    CREATE TABLE t1(a, b, c);
    CREATE TABLE t2(a, b, c);
    CREATE TABLE t3(a, b, c);
    CREATE TABLE t4(a, b, c);
    CREATE TABLE t5(a, b, c);
  }
  sqlite3_db_config db DEFENSIVE 0
  do_execsql_test 3.2 {
    UPDATE sqlite_dbpage SET data = hex2blob('
   000: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3.
   010: 04 00 01 01 20 40 20 20 00 00 3e d9 00 00 00 06 .... @  ..>.....
   020: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 04 ................
   030: 0f 00 00 00 00 00 00 00 00 00 00 01 00 00 83 00 ................
   040: 00 00 00 00 00 00 00 00 00 00 00 00 00 38 00 00 .............8..

Changes to test/countofview.test.

37
38
39
40
41
42
43
44
do_execsql_test 1.3 {
  select count(*) from (
    select c from t2 union all select f from t3
  )
} {3}

finish_test








<
37
38
39
40
41
42
43

do_execsql_test 1.3 {
  select count(*) from (
    select c from t2 union all select f from t3
  )
} {3}

finish_test

Changes to test/dbpage.test.

17
18
19
20
21
22
23

24
25
26
27
28
29
30
set testprefix dbpage

ifcapable !vtab||!compound {
  finish_test
  return
}


do_test 100 {
  execsql {
    PRAGMA auto_vacuum=0;
    PRAGMA page_size=4096;
    PRAGMA journal_mode=WAL;
  }
  execsql { 







>







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

ifcapable !vtab||!compound {
  finish_test
  return
}

sqlite3_db_config db DEFENSIVE 0
do_test 100 {
  execsql {
    PRAGMA auto_vacuum=0;
    PRAGMA page_size=4096;
    PRAGMA journal_mode=WAL;
  }
  execsql { 

Changes to test/default.test.

102
103
104
105
106
107
108

109
110
111
112
113
114
115
# Do now allow bound parameters in new DEFAULT values. 
# Silently convert bound parameters to NULL in DEFAULT causes
# in the sqlite_master table, for backwards compatibility.
#
db close
forcedelete test.db
sqlite3 db test.db

do_execsql_test default-4.0 {
  CREATE TABLE t1(a TEXT, b TEXT DEFAULT(99));
  PRAGMA writable_schema=ON;
  UPDATE sqlite_master SET sql='CREATE TABLE t1(a TEXT, b TEXT DEFAULT(:xyz))';
} {}
db close 
sqlite3 db test.db







>







102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# Do now allow bound parameters in new DEFAULT values. 
# Silently convert bound parameters to NULL in DEFAULT causes
# in the sqlite_master table, for backwards compatibility.
#
db close
forcedelete test.db
sqlite3 db test.db
sqlite3_db_config db DEFENSIVE 0
do_execsql_test default-4.0 {
  CREATE TABLE t1(a TEXT, b TEXT DEFAULT(99));
  PRAGMA writable_schema=ON;
  UPDATE sqlite_master SET sql='CREATE TABLE t1(a TEXT, b TEXT DEFAULT(:xyz))';
} {}
db close 
sqlite3 db test.db

Changes to test/e_fts3.test.

673
674
675
676
677
678
679

680
681
682
683
684
685
686
#
set DO_MALLOC_TEST 0
ddl_test   10.1.1 { CREATE VIRTUAL TABLE ta USING fts3 }
write_test 10.1.2 ta_content { 
  INSERT INTO ta VALUES('During a summer vacation in 1790') }
write_test 10.1.3 ta_content {
  INSERT INTO ta VALUES('Wordsworth went on a walking tour') }

write_test 10.1.4 ta_content { DELETE FROM ta_content WHERE rowid = 2 }
read_test  10.1.5 {
  SELECT * FROM ta WHERE ta MATCH 'summer'
} {{During a summer vacation in 1790}}
error_test 10.1.6 {
  SELECT * FROM ta WHERE ta MATCH 'walking'
} {database disk image is malformed}







>







673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
#
set DO_MALLOC_TEST 0
ddl_test   10.1.1 { CREATE VIRTUAL TABLE ta USING fts3 }
write_test 10.1.2 ta_content { 
  INSERT INTO ta VALUES('During a summer vacation in 1790') }
write_test 10.1.3 ta_content {
  INSERT INTO ta VALUES('Wordsworth went on a walking tour') }
sqlite3_db_config db DEFENSIVE 0
write_test 10.1.4 ta_content { DELETE FROM ta_content WHERE rowid = 2 }
read_test  10.1.5 {
  SELECT * FROM ta WHERE ta MATCH 'summer'
} {{During a summer vacation in 1790}}
error_test 10.1.6 {
  SELECT * FROM ta WHERE ta MATCH 'walking'
} {database disk image is malformed}

Changes to test/e_reindex.test.

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

# EVIDENCE-OF: R-52173-44778 The REINDEX command is used to delete and
# recreate indices from scratch.
#
#    Test this by corrupting some database indexes, running REINDEX, and
#    observing that the corruption is gone.
#

do_execsql_test e_reindex-1.1 {
  INSERT INTO t1 VALUES(1, 2);
  INSERT INTO t1 VALUES(3, 4);
  INSERT INTO t1 VALUES(5, 6);

  CREATE TABLE saved(a,b,c,d,e);
  INSERT INTO saved SELECT * FROM sqlite_master WHERE type = 'index';
  PRAGMA writable_schema = 1;
  DELETE FROM sqlite_master WHERE type = 'index';
} {}

db close
sqlite3 db test.db

do_execsql_test e_reindex-1.2 {
  DELETE FROM t1 WHERE a = 3;
  INSERT INTO t1 VALUES(7, 8);
  INSERT INTO t1 VALUES(9, 10);
  PRAGMA writable_schema = 1;
  INSERT INTO sqlite_master SELECT * FROM saved;
  DROP TABLE saved;







>













>







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

# EVIDENCE-OF: R-52173-44778 The REINDEX command is used to delete and
# recreate indices from scratch.
#
#    Test this by corrupting some database indexes, running REINDEX, and
#    observing that the corruption is gone.
#
sqlite3_db_config db DEFENSIVE 0
do_execsql_test e_reindex-1.1 {
  INSERT INTO t1 VALUES(1, 2);
  INSERT INTO t1 VALUES(3, 4);
  INSERT INTO t1 VALUES(5, 6);

  CREATE TABLE saved(a,b,c,d,e);
  INSERT INTO saved SELECT * FROM sqlite_master WHERE type = 'index';
  PRAGMA writable_schema = 1;
  DELETE FROM sqlite_master WHERE type = 'index';
} {}

db close
sqlite3 db test.db
sqlite3_db_config db DEFENSIVE 0
do_execsql_test e_reindex-1.2 {
  DELETE FROM t1 WHERE a = 3;
  INSERT INTO t1 VALUES(7, 8);
  INSERT INTO t1 VALUES(9, 10);
  PRAGMA writable_schema = 1;
  INSERT INTO sqlite_master SELECT * FROM saved;
  DROP TABLE saved;

Changes to test/fts3auto.test.

130
131
132
133
134
135
136

137
138
139
140
141
142
143

  return [expr $nRow*$pgsz]
}

#    fts3_zero_long_segments TABLE ?LIMIT?
#
proc fts3_zero_long_segments {tbl limit} {

  execsql " 
    UPDATE ${tbl}_segments 
    SET block = zeroblob(length(block)) 
    WHERE length(block)>$limit
  "
  return [db changes]
}







>







130
131
132
133
134
135
136
137
138
139
140
141
142
143
144

  return [expr $nRow*$pgsz]
}

#    fts3_zero_long_segments TABLE ?LIMIT?
#
proc fts3_zero_long_segments {tbl limit} {
  sqlite3_db_config db DEFENSIVE 0
  execsql " 
    UPDATE ${tbl}_segments 
    SET block = zeroblob(length(block)) 
    WHERE length(block)>$limit
  "
  return [db changes]
}

Changes to test/fts3corrupt.test.

19
20
21
22
23
24
25

26
27
28
29
30
31
32
set ::testprefix fts3corrupt


# Test that a doclist with a length field that indicates that the doclist
# extends past the end of the node on which it resides is correctly identified
# as database corruption.
#

do_execsql_test 1.0 {
  CREATE VIRTUAL TABLE t1 USING fts3;
  INSERT INTO t1 VALUES('hello');
} {}
do_test fts3corrupt-1.1 {
  set blob [db one {SELECT root from t1_segdir}]
  set blob [binary format a7ca* $blob 24 [string range $blob 8 end]]







>







19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
set ::testprefix fts3corrupt


# Test that a doclist with a length field that indicates that the doclist
# extends past the end of the node on which it resides is correctly identified
# as database corruption.
#
sqlite3_db_config db DEFENSIVE 0
do_execsql_test 1.0 {
  CREATE VIRTUAL TABLE t1 USING fts3;
  INSERT INTO t1 VALUES('hello');
} {}
do_test fts3corrupt-1.1 {
  set blob [db one {SELECT root from t1_segdir}]
  set blob [binary format a7ca* $blob 24 [string range $blob 8 end]]

Changes to test/fts3corrupt2.test.

45
46
47
48
49
50
51

52
53
54
55
56
57
58
   "ayjafsraz addjj agsj asejtziqws acatvhegu aoxdjqblsvv aekdmmbs aaobe"
   "abjjvzubkwt alczv ati awz auyxgcxeb aymjoym anqoukprtyt atwfhpmbooh"
   "ajfqz aethlgir aclcx aowlyvetby aproqm afjlqtkv anebfy akzrcpfrrvw"
   "aoledfotm aiwlfm aeejlaej anz abgbvk aktfn aayoh anpywgdvgz"
   "acvmldguld asdvz aqb aeomsyzyu aggylhprbdz asrfkwz auipybpsn agsnszzfb"
}


do_test fts3corrupt2-1.0 {
  execsql BEGIN
  execsql { CREATE VIRTUAL TABLE t2 USING FTS3(a, b); }
  execsql { INSERT INTO t2(t2) VALUES('nodesize=32') }
  foreach d $data {
    execsql { INSERT INTO t2 VALUES($d, $d) }
  }







>







45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
   "ayjafsraz addjj agsj asejtziqws acatvhegu aoxdjqblsvv aekdmmbs aaobe"
   "abjjvzubkwt alczv ati awz auyxgcxeb aymjoym anqoukprtyt atwfhpmbooh"
   "ajfqz aethlgir aclcx aowlyvetby aproqm afjlqtkv anebfy akzrcpfrrvw"
   "aoledfotm aiwlfm aeejlaej anz abgbvk aktfn aayoh anpywgdvgz"
   "acvmldguld asdvz aqb aeomsyzyu aggylhprbdz asrfkwz auipybpsn agsnszzfb"
}

sqlite3_db_config db DEFENSIVE 0
do_test fts3corrupt2-1.0 {
  execsql BEGIN
  execsql { CREATE VIRTUAL TABLE t2 USING FTS3(a, b); }
  execsql { INSERT INTO t2(t2) VALUES('nodesize=32') }
  foreach d $data {
    execsql { INSERT INTO t2 VALUES($d, $d) }
  }

Changes to test/fts3corrupt3.test.

29
30
31
32
33
34
35

36
37
38
39
40
41
42
    INSERT INTO t1 VALUES('one');
    INSERT INTO t1 VALUES('one');
  COMMIT;
}
do_execsql_test 1.1 {
  SELECT quote(root) from t1_segdir;
} {X'00036F6E6509010200010200010200'}

do_execsql_test 1.2 {
  UPDATE t1_segdir SET root = X'00036F6E650EFFFFFFFFFFFFFFFFFFFFFFFF0200';
}
do_catchsql_test 1.3 {
  SELECT rowid FROM t1 WHERE t1 MATCH 'one'
} {0 -1}








>







29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
    INSERT INTO t1 VALUES('one');
    INSERT INTO t1 VALUES('one');
  COMMIT;
}
do_execsql_test 1.1 {
  SELECT quote(root) from t1_segdir;
} {X'00036F6E6509010200010200010200'}
sqlite3_db_config db DEFENSIVE 0
do_execsql_test 1.2 {
  UPDATE t1_segdir SET root = X'00036F6E650EFFFFFFFFFFFFFFFFFFFFFFFF0200';
}
do_catchsql_test 1.3 {
  SELECT rowid FROM t1 WHERE t1 MATCH 'one'
} {0 -1}

Changes to test/fts3corrupt4.test.

36
37
38
39
40
41
42

43
44
45
46
47
48
49
..
79
80
81
82
83
84
85

86
87
88
89
90
91
92
...
129
130
131
132
133
134
135

136
137
138
139
140
141
142
143
144
145
146
147
proc blob {a} { binary decode hex $a }
db func blob blob

do_execsql_test 1.1 {
  SELECT quote(root) FROM ft_segdir;
} {X'0005616261636B03010200030266740302020003046E646F6E03030200'}


do_execsql_test 1.2 {
  UPDATE ft_segdir SET root = blob(
    '0005616261636B03010200 FFFFFFFF0702 66740302020003046E646F6E03030200'
  );
}

do_catchsql_test 1.3 {
................................................................................
} {12 3}

do_execsql_test 2.2 {
  SELECT quote(block) FROM ft_segments WHERE blockid=2
} {X'00056162633130031F0200'}

db func blob blob

do_execsql_test 2.3.1 {
  UPDATE ft_segments SET block = 
    blob('00056162633130031F0200 FFFFFFFF07FF55 66740302020003046E646F6E03030200')
    WHERE blockid=2;
} {}
do_catchsql_test 2.3.2 {
  INSERT INTO ft(ft) VALUES('merge=1,4');
................................................................................
} {1 5}

do_execsql_test 3.1 {
  SELECT quote(root) FROM ft_segdir
} {X'0101056162633132040136030132030136'}

db func blob blob

do_execsql_test 3.2 {
  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









>







 







>







 







>










<
<
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
..
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
...
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148


proc blob {a} { binary decode hex $a }
db func blob blob

do_execsql_test 1.1 {
  SELECT quote(root) FROM ft_segdir;
} {X'0005616261636B03010200030266740302020003046E646F6E03030200'}

sqlite3_db_config db DEFENSIVE 0
do_execsql_test 1.2 {
  UPDATE ft_segdir SET root = blob(
    '0005616261636B03010200 FFFFFFFF0702 66740302020003046E646F6E03030200'
  );
}

do_catchsql_test 1.3 {
................................................................................
} {12 3}

do_execsql_test 2.2 {
  SELECT quote(block) FROM ft_segments WHERE blockid=2
} {X'00056162633130031F0200'}

db func blob blob
sqlite3_db_config db DEFENSIVE 0
do_execsql_test 2.3.1 {
  UPDATE ft_segments SET block = 
    blob('00056162633130031F0200 FFFFFFFF07FF55 66740302020003046E646F6E03030200')
    WHERE blockid=2;
} {}
do_catchsql_test 2.3.2 {
  INSERT INTO ft(ft) VALUES('merge=1,4');
................................................................................
} {1 5}

do_execsql_test 3.1 {
  SELECT quote(root) FROM ft_segdir
} {X'0101056162633132040136030132030136'}

db func blob blob
sqlite3_db_config db DEFENSIVE 0
do_execsql_test 3.2 {
  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


Changes to test/fts3cov.test.

85
86
87
88
89
90
91

92
93
94
95
96
97
98
...
401
402
403
404
405
406
407

408
409
410
411
412
413
414
  execsql {
    INSERT INTO t1(t1) VALUES('optimize');
    SELECT substr(hex(root), 1, 2) FROM t1_segdir;
  }
} {03}

# Test the "missing entry" case:

do_test fts3cov-2.2 {
  set root [db one {SELECT root FROM t1_segdir}]
  read_fts3varint [string range $root 1 end] left_child
  execsql { DELETE FROM t1_segments WHERE blockid = $left_child }
} {}
do_error_test fts3cov-2.3 {
  SELECT * FROM t1 WHERE t1 MATCH 'c*'
................................................................................
}
do_execsql_test 15.1 {
  SELECT rowid FROM t15 WHERE t15 MATCH '"abc* def2"'
} {1 2}

# Test a corruption case.
#

do_execsql_test 16.1 {
  CREATE VIRTUAL TABLE t16 USING fts4;
  INSERT INTO t16 VALUES('theoretical work to examine the relationship');
  INSERT INTO t16 VALUES('solution of our problems on the invisible');
  DELETE FROM t16_content WHERE rowid = 2;
}
do_catchsql_test 16.2 {







>







 







>







85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
...
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
  execsql {
    INSERT INTO t1(t1) VALUES('optimize');
    SELECT substr(hex(root), 1, 2) FROM t1_segdir;
  }
} {03}

# Test the "missing entry" case:
sqlite3_db_config db DEFENSIVE 0
do_test fts3cov-2.2 {
  set root [db one {SELECT root FROM t1_segdir}]
  read_fts3varint [string range $root 1 end] left_child
  execsql { DELETE FROM t1_segments WHERE blockid = $left_child }
} {}
do_error_test fts3cov-2.3 {
  SELECT * FROM t1 WHERE t1 MATCH 'c*'
................................................................................
}
do_execsql_test 15.1 {
  SELECT rowid FROM t15 WHERE t15 MATCH '"abc* def2"'
} {1 2}

# Test a corruption case.
#
sqlite3_db_config db DEFENSIVE 0
do_execsql_test 16.1 {
  CREATE VIRTUAL TABLE t16 USING fts4;
  INSERT INTO t16 VALUES('theoretical work to examine the relationship');
  INSERT INTO t16 VALUES('solution of our problems on the invisible');
  DELETE FROM t16_content WHERE rowid = 2;
}
do_catchsql_test 16.2 {

Changes to test/fts3d.test.

292
293
294
295
296
297
298

299
300
301
302
303
304
305
  execsql {
    SELECT OPTIMIZE(t1) FROM t1 LIMIT 1;
    SELECT level, idx FROM t1_segdir ORDER BY level, idx;
  }
} {{Index already optimal} 1 0}

# Even if we move things around, still does nothing.

do_test fts3d-5.1 {
  execsql {
    UPDATE t1_segdir SET level = 2 WHERE level = 1 AND idx = 0;
    SELECT OPTIMIZE(t1) FROM t1 LIMIT 1;
    SELECT level, idx FROM t1_segdir ORDER BY level, idx;
  }
} {{Index already optimal} 2 0}







>







292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
  execsql {
    SELECT OPTIMIZE(t1) FROM t1 LIMIT 1;
    SELECT level, idx FROM t1_segdir ORDER BY level, idx;
  }
} {{Index already optimal} 1 0}

# Even if we move things around, still does nothing.
sqlite3_db_config db DEFENSIVE 0
do_test fts3d-5.1 {
  execsql {
    UPDATE t1_segdir SET level = 2 WHERE level = 1 AND idx = 0;
    SELECT OPTIMIZE(t1) FROM t1 LIMIT 1;
    SELECT level, idx FROM t1_segdir ORDER BY level, idx;
  }
} {{Index already optimal} 2 0}

Changes to test/fts3defer.test.

55
56
57
58
59
60
61

62
63
64
65
66
67
68
...
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
  4  {SELECT snippet(t1) FROM t1 WHERE t1 MATCH '"a longer phrase"'}  
     {"an instance of <b>a</b> <b>longer</b> <b>phrase</b>"}
  5  {SELECT rowid FROM t1 WHERE t1 MATCH 'a dog'}                   {1}
}

do_select_tests 1.2 $tests


do_execsql_test 1.3 {
  SELECT count(*) FROM t1_segments WHERE length(block)>10000;
  UPDATE t1_segments 
    SET block = zeroblob(length(block)) 
    WHERE length(block)>10000;
} {1}

................................................................................
    foreach doc $data { execsql { INSERT INTO t1 VALUES($doc) } }
  }
  3 {
    set dmt_modes {0 1 2}
    execsql { CREATE VIRTUAL TABLE t1 USING FTS4 }
    foreach doc $data { execsql { INSERT INTO t1 VALUES($doc) } }
    add_empty_records 1000

    execsql $zero_long_doclists
  }
  4 {
    set dmt_modes 0
    execsql { CREATE VIRTUAL TABLE t1 USING FTS4 }
    foreach doc $data { execsql { INSERT INTO t1 VALUES($doc) } }
    add_empty_records 1000
    execsql "INSERT INTO t1(t1) VALUES('optimize')"

    execsql $zero_long_doclists
  }
  5 {
    set dmt_modes 0
    execsql { CREATE VIRTUAL TABLE t1 USING FTS4(matchinfo=fts3) }
    foreach doc $data { execsql { INSERT INTO t1 VALUES($doc) } }
    add_empty_records 1000

    execsql $zero_long_doclists
  }
} {

  execsql { DROP TABLE IF EXISTS t1 }
  eval $setup
  set ::testprefix fts3defer-2.$tn







>







 







>








>







>







55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
...
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
  4  {SELECT snippet(t1) FROM t1 WHERE t1 MATCH '"a longer phrase"'}  
     {"an instance of <b>a</b> <b>longer</b> <b>phrase</b>"}
  5  {SELECT rowid FROM t1 WHERE t1 MATCH 'a dog'}                   {1}
}

do_select_tests 1.2 $tests

sqlite3_db_config db DEFENSIVE 0
do_execsql_test 1.3 {
  SELECT count(*) FROM t1_segments WHERE length(block)>10000;
  UPDATE t1_segments 
    SET block = zeroblob(length(block)) 
    WHERE length(block)>10000;
} {1}

................................................................................
    foreach doc $data { execsql { INSERT INTO t1 VALUES($doc) } }
  }
  3 {
    set dmt_modes {0 1 2}
    execsql { CREATE VIRTUAL TABLE t1 USING FTS4 }
    foreach doc $data { execsql { INSERT INTO t1 VALUES($doc) } }
    add_empty_records 1000
    sqlite3_db_config db DEFENSIVE 0
    execsql $zero_long_doclists
  }
  4 {
    set dmt_modes 0
    execsql { CREATE VIRTUAL TABLE t1 USING FTS4 }
    foreach doc $data { execsql { INSERT INTO t1 VALUES($doc) } }
    add_empty_records 1000
    execsql "INSERT INTO t1(t1) VALUES('optimize')"
    sqlite3_db_config db DEFENSIVE 0
    execsql $zero_long_doclists
  }
  5 {
    set dmt_modes 0
    execsql { CREATE VIRTUAL TABLE t1 USING FTS4(matchinfo=fts3) }
    foreach doc $data { execsql { INSERT INTO t1 VALUES($doc) } }
    add_empty_records 1000
    sqlite3_db_config db DEFENSIVE 0
    execsql $zero_long_doclists
  }
} {

  execsql { DROP TABLE IF EXISTS t1 }
  eval $setup
  set ::testprefix fts3defer-2.$tn

Changes to test/fts3defer2.test.

42
43
44
45
46
47
48

49
50
51
52
53
54
55
..
94
95
96
97
98
99
100

101
102
103
104
105
106
107
...
148
149
150
151
152
153
154

155
156
157
158
159
160
161
162
  INSERT INTO t1 VALUES('');
  INSERT INTO t1 VALUES('');
  INSERT INTO t1 VALUES('');
  INSERT INTO t1 VALUES('');
  INSERT INTO t1 VALUES('');
  INSERT INTO t1(t1) VALUES('optimize');
}

do_execsql_test 1.1.4 {
  SELECT count(*) FROM t1_segments WHERE length(block)>10000;
  UPDATE t1_segments SET block = zeroblob(length(block)) WHERE length(block)>10000;
} {2}

do_execsql_test 1.2.0 {
  SELECT content FROM t1 WHERE t1 MATCH 'f (e a)';
................................................................................
foreach {tn sql} {
  1 {}
  2 { INSERT INTO t2(t2) VALUES('optimize') }
  3 { UPDATE t2_segments SET block = zeroblob(length(block)) 
      WHERE length(block)>10000;
  }
} {

  execsql $sql

  do_execsql_test 2.2.$tn.1 {
    SELECT mit(matchinfo(t2, 'pcxnal')) FROM t2 WHERE t2 MATCH 'a b';
  } [list                                          \
    [list 2 1  1 54 54  1 3 3  54 372 8]        \
    [list 2 1  1 54 54  1 3 3  54 372 7]        \
................................................................................
foreach {tn sql} {
  1 {}
  2 { INSERT INTO t3(t3) VALUES('optimize') }
  3 { UPDATE t3_segments SET block = zeroblob(length(block)) 
      WHERE length(block)>10000;
  }
} {

  execsql $sql
  do_execsql_test 2.4.$tn {
    SELECT docid, mit(matchinfo(t3, 'pcxnal')) FROM t3 WHERE t3 MATCH '"a b c"';
  } {1 {1 1 1 4 4 11 912 6} 3 {1 1 1 4 4 11 912 6}}
}


finish_test







>







 







>







 







>








42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
..
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
...
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
  INSERT INTO t1 VALUES('');
  INSERT INTO t1 VALUES('');
  INSERT INTO t1 VALUES('');
  INSERT INTO t1 VALUES('');
  INSERT INTO t1 VALUES('');
  INSERT INTO t1(t1) VALUES('optimize');
}
sqlite3_db_config db DEFENSIVE 0
do_execsql_test 1.1.4 {
  SELECT count(*) FROM t1_segments WHERE length(block)>10000;
  UPDATE t1_segments SET block = zeroblob(length(block)) WHERE length(block)>10000;
} {2}

do_execsql_test 1.2.0 {
  SELECT content FROM t1 WHERE t1 MATCH 'f (e a)';
................................................................................
foreach {tn sql} {
  1 {}
  2 { INSERT INTO t2(t2) VALUES('optimize') }
  3 { UPDATE t2_segments SET block = zeroblob(length(block)) 
      WHERE length(block)>10000;
  }
} {
  sqlite3_db_config db DEFENSIVE 0
  execsql $sql

  do_execsql_test 2.2.$tn.1 {
    SELECT mit(matchinfo(t2, 'pcxnal')) FROM t2 WHERE t2 MATCH 'a b';
  } [list                                          \
    [list 2 1  1 54 54  1 3 3  54 372 8]        \
    [list 2 1  1 54 54  1 3 3  54 372 7]        \
................................................................................
foreach {tn sql} {
  1 {}
  2 { INSERT INTO t3(t3) VALUES('optimize') }
  3 { UPDATE t3_segments SET block = zeroblob(length(block)) 
      WHERE length(block)>10000;
  }
} {
  sqlite3_db_config db DEFENSIVE 0
  execsql $sql
  do_execsql_test 2.4.$tn {
    SELECT docid, mit(matchinfo(t3, 'pcxnal')) FROM t3 WHERE t3 MATCH '"a b c"';
  } {1 {1 1 1 4 4 11 912 6} 3 {1 1 1 4 4 11 912 6}}
}


finish_test

Changes to test/fts3matchinfo.test.

274
275
276
277
278
279
280

281
282
283
284
285
286
287
...
335
336
337
338
339
340
341

342
343
344
345
346
347
348
...
388
389
390
391
392
393
394

395
396
397
398
399
400
401
do_matchinfo_test 4.3.4 t5 {t5 MATCH 'a a a'}       { s {3 1} }
do_matchinfo_test 4.3.5 t5 {t5 MATCH '"a b" "a b"'} { s {2} }
do_matchinfo_test 4.3.6 t5 {t5 MATCH 'a OR b'}      { s {1 2 1 1} }

do_execsql_test 4.4.0.1 { INSERT INTO t5(t5) VALUES('optimize') }

ifcapable fts4_deferred {

  do_execsql_test 4.4.0.2 {
    UPDATE t5_segments 
    SET block = zeroblob(length(block)) 
    WHERE length(block)>10000;
  }
}

................................................................................
  CREATE VIRTUAL TABLE t9 USING fts4;
  INSERT INTO t9 VALUES(
    'this record is used to try to dectect corruption'
  );
  SELECT offsets(t9) FROM t9 WHERE t9 MATCH 'to';
} {{0 0 20 2 0 0 27 2}}


do_catchsql_test 6.2 {
  UPDATE t9_content SET c0content = 'this record is used to'; 
  SELECT offsets(t9) FROM t9 WHERE t9 MATCH 'to';
} {1 {database disk image is malformed}}

#-------------------------------------------------------------------------
# Test the outcome of matchinfo() when used within a query that does not
................................................................................
  execsql { INSERT INTO t11(t11) VALUES('optimize') }
} {}
do_execsql_test 8.3 {
  SELECT mit(matchinfo(t11, 'nxa')) FROM t11 WHERE t11 MATCH 'a*'
} {{204 1 3 3 0} {204 1 3 3 0} {204 1 3 3 0}}

# Corruption related tests.

do_execsql_test  8.4.1.1 { UPDATE t11_stat SET value = X'0000'; }
do_catchsql_test 8.5.1.2 {
  SELECT mit(matchinfo(t11, 'nxa')) FROM t11 WHERE t11 MATCH 'a*'
} {1 {database disk image is malformed}}

do_execsql_test  8.4.2.1 { UPDATE t11_stat SET value = X'00'; }
do_catchsql_test 8.5.2.2 {







>







 







>







 







>







274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
...
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
...
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
do_matchinfo_test 4.3.4 t5 {t5 MATCH 'a a a'}       { s {3 1} }
do_matchinfo_test 4.3.5 t5 {t5 MATCH '"a b" "a b"'} { s {2} }
do_matchinfo_test 4.3.6 t5 {t5 MATCH 'a OR b'}      { s {1 2 1 1} }

do_execsql_test 4.4.0.1 { INSERT INTO t5(t5) VALUES('optimize') }

ifcapable fts4_deferred {
  sqlite3_db_config db DEFENSIVE 0
  do_execsql_test 4.4.0.2 {
    UPDATE t5_segments 
    SET block = zeroblob(length(block)) 
    WHERE length(block)>10000;
  }
}

................................................................................
  CREATE VIRTUAL TABLE t9 USING fts4;
  INSERT INTO t9 VALUES(
    'this record is used to try to dectect corruption'
  );
  SELECT offsets(t9) FROM t9 WHERE t9 MATCH 'to';
} {{0 0 20 2 0 0 27 2}}

sqlite3_db_config db DEFENSIVE 0
do_catchsql_test 6.2 {
  UPDATE t9_content SET c0content = 'this record is used to'; 
  SELECT offsets(t9) FROM t9 WHERE t9 MATCH 'to';
} {1 {database disk image is malformed}}

#-------------------------------------------------------------------------
# Test the outcome of matchinfo() when used within a query that does not
................................................................................
  execsql { INSERT INTO t11(t11) VALUES('optimize') }
} {}
do_execsql_test 8.3 {
  SELECT mit(matchinfo(t11, 'nxa')) FROM t11 WHERE t11 MATCH 'a*'
} {{204 1 3 3 0} {204 1 3 3 0} {204 1 3 3 0}}

# Corruption related tests.
sqlite3_db_config db DEFENSIVE 0
do_execsql_test  8.4.1.1 { UPDATE t11_stat SET value = X'0000'; }
do_catchsql_test 8.5.1.2 {
  SELECT mit(matchinfo(t11, 'nxa')) FROM t11 WHERE t11 MATCH 'a*'
} {1 {database disk image is malformed}}

do_execsql_test  8.4.2.1 { UPDATE t11_stat SET value = X'00'; }
do_catchsql_test 8.5.2.2 {

Changes to test/fts3misc.test.

156
157
158
159
160
161
162

163
164
165
166
167
168
169
  }
  do_execsql_test 4.1 {
    SELECT count(*) FROM t4 WHERE t4 MATCH '"a b c" OR "c a b"'
  } {8000}
  do_execsql_test 4.2 {
    SELECT quote(value) from t4_stat where id=0
  } {X'C03EC0B204C0A608'}

  do_execsql_test 4.3 {
    UPDATE t4_stat SET value = X'C03EC0B204C0A60800' WHERE id=0;
  }
  do_catchsql_test 4.4 {
    SELECT count(*) FROM t4 WHERE t4 MATCH '"a b c" OR "c a b"'
  } {1 {database disk image is malformed}}
  do_execsql_test 4.5 {







>







156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
  }
  do_execsql_test 4.1 {
    SELECT count(*) FROM t4 WHERE t4 MATCH '"a b c" OR "c a b"'
  } {8000}
  do_execsql_test 4.2 {
    SELECT quote(value) from t4_stat where id=0
  } {X'C03EC0B204C0A608'}
  sqlite3_db_config db DEFENSIVE 0
  do_execsql_test 4.3 {
    UPDATE t4_stat SET value = X'C03EC0B204C0A60800' WHERE id=0;
  }
  do_catchsql_test 4.4 {
    SELECT count(*) FROM t4 WHERE t4 MATCH '"a b c" OR "c a b"'
  } {1 {database disk image is malformed}}
  do_execsql_test 4.5 {

Changes to test/fts3query.test.

163
164
165
166
167
168
169

170
171
172
173
174
175
176
  illegal first argument to %s
} {
  1 "SELECT matchinfo(content) FROM t2 WHERE t2 MATCH 'history'" matchinfo
  2 "SELECT offsets(content) FROM t2 WHERE t2 MATCH 'history'"   offsets
  3 "SELECT snippet(content) FROM t2 WHERE t2 MATCH 'history'"   snippet
  4 "SELECT optimize(content) FROM t2 WHERE t2 MATCH 'history'"  optimize
}

do_execsql_test 5.4.0 { UPDATE t2_content SET c0content = X'1234' }
do_select_tests 5.4 -errorformat {
  illegal first argument to %s
} {
  1 "SELECT matchinfo(content) FROM t2 WHERE t2 MATCH 'history'" matchinfo
  2 "SELECT offsets(content) FROM t2 WHERE t2 MATCH 'history'"   offsets
  3 "SELECT snippet(content) FROM t2 WHERE t2 MATCH 'history'"   snippet







>







163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
  illegal first argument to %s
} {
  1 "SELECT matchinfo(content) FROM t2 WHERE t2 MATCH 'history'" matchinfo
  2 "SELECT offsets(content) FROM t2 WHERE t2 MATCH 'history'"   offsets
  3 "SELECT snippet(content) FROM t2 WHERE t2 MATCH 'history'"   snippet
  4 "SELECT optimize(content) FROM t2 WHERE t2 MATCH 'history'"  optimize
}
sqlite3_db_config db DEFENSIVE 0
do_execsql_test 5.4.0 { UPDATE t2_content SET c0content = X'1234' }
do_select_tests 5.4 -errorformat {
  illegal first argument to %s
} {
  1 "SELECT matchinfo(content) FROM t2 WHERE t2 MATCH 'history'" matchinfo
  2 "SELECT offsets(content) FROM t2 WHERE t2 MATCH 'history'"   offsets
  3 "SELECT snippet(content) FROM t2 WHERE t2 MATCH 'history'"   snippet

Changes to test/fts3snippet.test.

180
181
182
183
184
185
186

187
188
189
190
191
192
193
  do_offsets_test $T.2.1 {twohundred} [list 1 0 $off 10]

  set off [string first "onehundred " $numbers]
  do_offsets_test $T.2.2 {onehundred} \
    [list 0 0 $off 10 1 0 $off 10] [list 0 0 $off 10]

  # Test a corruption case:

  execsql { UPDATE ft_content SET c1b = 'hello world' WHERE c1b = $numbers }
  do_error_test $T.2.3 {
    SELECT offsets(ft) FROM ft WHERE ft MATCH 'onehundred'
  } {database disk image is malformed}
  
  ##########################################################################
  # Test the snippet function.







>







180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
  do_offsets_test $T.2.1 {twohundred} [list 1 0 $off 10]

  set off [string first "onehundred " $numbers]
  do_offsets_test $T.2.2 {onehundred} \
    [list 0 0 $off 10 1 0 $off 10] [list 0 0 $off 10]

  # Test a corruption case:
  sqlite3_db_config db DEFENSIVE 0
  execsql { UPDATE ft_content SET c1b = 'hello world' WHERE c1b = $numbers }
  do_error_test $T.2.3 {
    SELECT offsets(ft) FROM ft WHERE ft MATCH 'onehundred'
  } {database disk image is malformed}
  
  ##########################################################################
  # Test the snippet function.

Changes to test/fts4check.test.

62
63
64
65
66
67
68

69
70
71
72
73
74
75
..
96
97
98
99
100
101
102

103
104
105
106
107
108
109
...
141
142
143
144
145
146
147

148
149
150
151
152
153
154
...
159
160
161
162
163
164
165

166
167
168
169
170
171
172
...
193
194
195
196
197
198
199

200
201
202
203
204
205
206
207
208
209
210
211
212
  }
  3 {
    DELETE FROM t1_segdir WHERE level=0 AND idx=(
      SELECT max(idx) FROM t1_segdir WHERE level=0
    );
  }
} {

  do_execsql_test  1.2.1.$tn "BEGIN; $disruption"
  do_catchsql_test 1.2.2.$tn {
    INSERT INTO t1 (t1) VALUES('integrity-check')
  } {1 {database disk image is malformed}}
  do_execsql_test  1.2.3.$tn "ROLLBACK"
}

................................................................................
  }
  3 {
    DELETE FROM t2_segdir WHERE level=0 AND idx=(
      SELECT max(idx) FROM t2_segdir WHERE level=1024
    );
  }
} {

  do_execsql_test  2.2.1.$tn "BEGIN; $disruption"
  do_catchsql_test 2.2.2.$tn {
    INSERT INTO t2 (t2) VALUES('integrity-check')
  } {1 {database disk image is malformed}}
  do_execsql_test  2.2.3.$tn "ROLLBACK"
}

................................................................................
  }
  2 {
    UPDATE t3_content SET langid=langid+1 WHERE rowid = (
      SELECT max(rowid) FROM t3_content
    )
  }
} {

  do_execsql_test  3.2.1.$tn "BEGIN; $disruption"
  do_catchsql_test 3.2.2.$tn {
    INSERT INTO t3 (t3) VALUES('integrity-check')
  } {1 {database disk image is malformed}}
  do_execsql_test  3.2.3.$tn "ROLLBACK"
}

................................................................................
#
do_execsql_test 4.0 {
  CREATE VIRTUAL TABLE t4 USING fts4(a, b, c, notindexed=b);
  INSERT INTO t4 VALUES('text one', 'text two', 'text three');
  INSERT INTO t4(t4) VALUES('integrity-check');
}


do_execsql_test 4.1 {
  PRAGMA writable_schema = 1;
  UPDATE sqlite_master 
    SET sql = 'CREATE VIRTUAL TABLE t4 USING fts4(a, b, c)' 
    WHERE name = 't4';
}

................................................................................
  INSERT INTO t5 VALUES('and the stockmen tell the story of his ride');
}

do_execsql_test 5.1 {
  INSERT INTO t5(t5) VALUES('integrity-check');
} {}


do_catchsql_test 5.2 {
  INSERT INTO t5_content VALUES(5, 'his hardy mountain pony');
  INSERT INTO t5(t5) VALUES('integrity-check');
} {1 {database disk image is malformed}}

do_execsql_test 5.3 ROLLBACK

do_execsql_test 5.4 {
  CREATE VIRTUAL TABLE t5 USING fts4(a, prefix="1,2,3");
  INSERT INTO t5(t5) VALUES('integrity-check');
} {}

finish_test







>







 







>







 







>







 







>







 







>













62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
..
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
...
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
...
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
...
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
  }
  3 {
    DELETE FROM t1_segdir WHERE level=0 AND idx=(
      SELECT max(idx) FROM t1_segdir WHERE level=0
    );
  }
} {
  sqlite3_db_config db DEFENSIVE 0
  do_execsql_test  1.2.1.$tn "BEGIN; $disruption"
  do_catchsql_test 1.2.2.$tn {
    INSERT INTO t1 (t1) VALUES('integrity-check')
  } {1 {database disk image is malformed}}
  do_execsql_test  1.2.3.$tn "ROLLBACK"
}

................................................................................
  }
  3 {
    DELETE FROM t2_segdir WHERE level=0 AND idx=(
      SELECT max(idx) FROM t2_segdir WHERE level=1024
    );
  }
} {
  sqlite3_db_config db DEFENSIVE 0
  do_execsql_test  2.2.1.$tn "BEGIN; $disruption"
  do_catchsql_test 2.2.2.$tn {
    INSERT INTO t2 (t2) VALUES('integrity-check')
  } {1 {database disk image is malformed}}
  do_execsql_test  2.2.3.$tn "ROLLBACK"
}

................................................................................
  }
  2 {
    UPDATE t3_content SET langid=langid+1 WHERE rowid = (
      SELECT max(rowid) FROM t3_content
    )
  }
} {
  sqlite3_db_config db DEFENSIVE 0
  do_execsql_test  3.2.1.$tn "BEGIN; $disruption"
  do_catchsql_test 3.2.2.$tn {
    INSERT INTO t3 (t3) VALUES('integrity-check')
  } {1 {database disk image is malformed}}
  do_execsql_test  3.2.3.$tn "ROLLBACK"
}

................................................................................
#
do_execsql_test 4.0 {
  CREATE VIRTUAL TABLE t4 USING fts4(a, b, c, notindexed=b);
  INSERT INTO t4 VALUES('text one', 'text two', 'text three');
  INSERT INTO t4(t4) VALUES('integrity-check');
}

sqlite3_db_config db DEFENSIVE 0
do_execsql_test 4.1 {
  PRAGMA writable_schema = 1;
  UPDATE sqlite_master 
    SET sql = 'CREATE VIRTUAL TABLE t4 USING fts4(a, b, c)' 
    WHERE name = 't4';
}

................................................................................
  INSERT INTO t5 VALUES('and the stockmen tell the story of his ride');
}

do_execsql_test 5.1 {
  INSERT INTO t5(t5) VALUES('integrity-check');
} {}

sqlite3_db_config db DEFENSIVE 0
do_catchsql_test 5.2 {
  INSERT INTO t5_content VALUES(5, 'his hardy mountain pony');
  INSERT INTO t5(t5) VALUES('integrity-check');
} {1 {database disk image is malformed}}

do_execsql_test 5.3 ROLLBACK

do_execsql_test 5.4 {
  CREATE VIRTUAL TABLE t5 USING fts4(a, prefix="1,2,3");
  INSERT INTO t5(t5) VALUES('integrity-check');
} {}

finish_test

Changes to test/fts4growth.test.

21
22
23
24
25
26
27

28
29
30
31
32
33
34
ifcapable !fts3 {
  finish_test
  return
}

source $testdir/genesis.tcl


do_execsql_test 1.1 { CREATE VIRTUAL TABLE x1 USING fts3; }

do_test 1.2 {
  foreach L {
    {"See here, young man," said Mulga Bill, "from Walgett to the sea,}
    {From Conroy's Gap to Castlereagh, there's none can ride like me.}
    {I'm good all round at everything as everybody knows,}







>







21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
ifcapable !fts3 {
  finish_test
  return
}

source $testdir/genesis.tcl

sqlite3_db_config db DEFENSIVE 0
do_execsql_test 1.1 { CREATE VIRTUAL TABLE x1 USING fts3; }

do_test 1.2 {
  foreach L {
    {"See here, young man," said Mulga Bill, "from Walgett to the sea,}
    {From Conroy's Gap to Castlereagh, there's none can ride like me.}
    {I'm good all round at everything as everybody knows,}

Changes to test/fts4merge.test.

152
153
154
155
156
157
158

159
160
161
162
163
164
165
    } $expect
  }
  
  do_execsql_test 4.4.1 {
    SELECT quote(value) FROM t4_stat WHERE rowid=1
  } {X'0006'}
  

  do_execsql_test 4.4.2 {
    DELETE FROM t4_stat WHERE rowid=1;
    INSERT INTO t4(t4) VALUES('merge=1,12');
    SELECT level, group_concat(idx, ' ') FROM t4_segdir GROUP BY level;
  } "0 {0 1 2 3 4 5}                     1 0"
  
  







>







152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
    } $expect
  }
  
  do_execsql_test 4.4.1 {
    SELECT quote(value) FROM t4_stat WHERE rowid=1
  } {X'0006'}
  
  sqlite3_db_config db DEFENSIVE 0
  do_execsql_test 4.4.2 {
    DELETE FROM t4_stat WHERE rowid=1;
    INSERT INTO t4(t4) VALUES('merge=1,12');
    SELECT level, group_concat(idx, ' ') FROM t4_segdir GROUP BY level;
  } "0 {0 1 2 3 4 5}                     1 0"
  
  

Changes to test/fts4opt.test.

33
34
35
36
37
38
39

40
41
42
43
44
45
46
# Argument $db is an open database handle. $tbl is the name of an FTS3/4
# table with the database. This command rearranges the contents of the
# %_segdir table so that all segments within each index are on the same
# level. This means that the 'merge' command can then be used for an
# incremental optimize routine.
#
proc prepare_for_optimize {db tbl} {

  $db eval [string map [list % $tbl] {
    BEGIN;
      CREATE TEMP TABLE tmp_segdir(
        level, idx, start_block, leaves_end_block, end_block, root
      );

      INSERT INTO temp.tmp_segdir 







>







33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# Argument $db is an open database handle. $tbl is the name of an FTS3/4
# table with the database. This command rearranges the contents of the
# %_segdir table so that all segments within each index are on the same
# level. This means that the 'merge' command can then be used for an
# incremental optimize routine.
#
proc prepare_for_optimize {db tbl} {
  sqlite3_db_config $db DEFENSIVE 0
  $db eval [string map [list % $tbl] {
    BEGIN;
      CREATE TEMP TABLE tmp_segdir(
        level, idx, start_block, leaves_end_block, end_block, root
      );

      INSERT INTO temp.tmp_segdir 

Changes to test/index.test.

622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
# tested somewhere.
do_test index-18.1 {
  catchsql {
    CREATE TABLE sqlite_t1(a, b, c);
  }
} {1 {object name reserved for internal use: sqlite_t1}}
do_test index-18.1.2 {
  sqlite3_db_config db DEFENSIVE 1
  catchsql {
    CREATE TABLE sqlite_t1(a, b, c);
  }
} {1 {object name reserved for internal use: sqlite_t1}}
sqlite3_db_config db DEFENSIVE 0
do_test index-18.2 {
  catchsql {







<







622
623
624
625
626
627
628

629
630
631
632
633
634
635
# tested somewhere.
do_test index-18.1 {
  catchsql {
    CREATE TABLE sqlite_t1(a, b, c);
  }
} {1 {object name reserved for internal use: sqlite_t1}}
do_test index-18.1.2 {

  catchsql {
    CREATE TABLE sqlite_t1(a, b, c);
  }
} {1 {object name reserved for internal use: sqlite_t1}}
sqlite3_db_config db DEFENSIVE 0
do_test index-18.2 {
  catchsql {

Changes to test/index3.test.

79
80
81
82
83
84
85

86
87
88
89
90
91
92
93
94
95



# This test corrupts the database file so it must be the last test
# in the series.
#
do_test index3-99.1 {

  execsql {
    PRAGMA writable_schema=on;
    UPDATE sqlite_master SET sql='nonsense' WHERE name='t1d'
  }
  db close
  catch { sqlite3 db test.db }
  catchsql { DROP INDEX t1c }
} {1 {malformed database schema (t1d)}}

finish_test







>










79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96



# This test corrupts the database file so it must be the last test
# in the series.
#
do_test index3-99.1 {
  sqlite3_db_config db DEFENSIVE 0
  execsql {
    PRAGMA writable_schema=on;
    UPDATE sqlite_master SET sql='nonsense' WHERE name='t1d'
  }
  db close
  catch { sqlite3 db test.db }
  catchsql { DROP INDEX t1c }
} {1 {malformed database schema (t1d)}}

finish_test

Changes to test/misc1.test.

655
656
657
658
659
660
661

662
663
664
665
666
667
668
...
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
  SELECT ""+3 FROM (SELECT ""+5);
} {3}

# 2015-04-19: NULL pointer dereference on a corrupt schema
#
db close
sqlite3 db :memory:

do_execsql_test misc1-23.1 {
  CREATE TABLE t1(x);
  PRAGMA writable_schema=ON;
  UPDATE sqlite_master SET sql='CREATE table t(d CHECK(T(#0)';
  BEGIN;
  CREATE TABLE t2(y);
  ROLLBACK;
................................................................................
} {}

# 2015-04-19:  Faulty assert() statement
#
db close
database_may_be_corrupt
sqlite3 db :memory:

do_catchsql_test misc1-23.2 {
  CREATE TABLE t1(x UNIQUE);
  PRAGMA writable_schema=ON;
  UPDATE sqlite_master SET sql='CREATE TABLE IF not EXISTS t(c)';
  BEGIN;
  CREATE TABLE t2(x);
  ROLLBACK;
  DROP TABLE F;
} {1 {no such table: F}}
db close
sqlite3 db :memory:

do_catchsql_test misc1-23.3 {
  CREATE TABLE t1(x UNIQUE);
  PRAGMA writable_schema=ON;
  UPDATE sqlite_master SET sql='CREATE table y(a TEXT, a TEXT)';
  BEGIN;
  CREATE TABLE t2(y);
  ROLLBACK;







>







 







>











>







655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
...
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
  SELECT ""+3 FROM (SELECT ""+5);
} {3}

# 2015-04-19: NULL pointer dereference on a corrupt schema
#
db close
sqlite3 db :memory:
sqlite3_db_config db DEFENSIVE 0
do_execsql_test misc1-23.1 {
  CREATE TABLE t1(x);
  PRAGMA writable_schema=ON;
  UPDATE sqlite_master SET sql='CREATE table t(d CHECK(T(#0)';
  BEGIN;
  CREATE TABLE t2(y);
  ROLLBACK;
................................................................................
} {}

# 2015-04-19:  Faulty assert() statement
#
db close
database_may_be_corrupt
sqlite3 db :memory:
sqlite3_db_config db DEFENSIVE 0
do_catchsql_test misc1-23.2 {
  CREATE TABLE t1(x UNIQUE);
  PRAGMA writable_schema=ON;
  UPDATE sqlite_master SET sql='CREATE TABLE IF not EXISTS t(c)';
  BEGIN;
  CREATE TABLE t2(x);
  ROLLBACK;
  DROP TABLE F;
} {1 {no such table: F}}
db close
sqlite3 db :memory:
sqlite3_db_config db DEFENSIVE 0
do_catchsql_test misc1-23.3 {
  CREATE TABLE t1(x UNIQUE);
  PRAGMA writable_schema=ON;
  UPDATE sqlite_master SET sql='CREATE table y(a TEXT, a TEXT)';
  BEGIN;
  CREATE TABLE t2(y);
  ROLLBACK;

Changes to test/misc4.test.

208
209
210
211
212
213
214

215
216
217
218
219
220
221
  }
} {1}

# 2015-05-15.  Error message formatting problem.
#
db close
sqlite3 db :memory:

do_catchsql_test misc4-7.1 {
  CREATE TABLE t7(x);
  PRAGMA writable_schema=ON;
  UPDATE sqlite_master SET sql='CREATE TABLE [M%s%s%s%s%s%s%s%s%s%s%s%s%s';
  VACUUM;
} {1 {unrecognized token: "[M%s%s%s%s%s%s%s%s%s%s%s%s%s"}}








>







208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
  }
} {1}

# 2015-05-15.  Error message formatting problem.
#
db close
sqlite3 db :memory:
sqlite3_db_config db DEFENSIVE 0
do_catchsql_test misc4-7.1 {
  CREATE TABLE t7(x);
  PRAGMA writable_schema=ON;
  UPDATE sqlite_master SET sql='CREATE TABLE [M%s%s%s%s%s%s%s%s%s%s%s%s%s';
  VACUUM;
} {1 {unrecognized token: "[M%s%s%s%s%s%s%s%s%s%s%s%s%s"}}

Changes to test/misc5.test.

586
587
588
589
590
591
592

593
594
595
596
597
598
599
} {1 {parser stack overflow}}

# Parser stack overflow is silently ignored when it occurs while parsing the
# schema and PRAGMA writable_schema is turned on.
#
do_test misc5-7.2 {
  sqlite3 db2 :memory:

  catchsql {
    CREATE TABLE t1(x UNIQUE);
    PRAGMA writable_schema=ON;
    UPDATE sqlite_master SET sql='CREATE table t(o CHECK(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((;VALUES(o)';
    BEGIN;
    CREATE TABLE t2(y);
    ROLLBACK;







>







586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
} {1 {parser stack overflow}}

# Parser stack overflow is silently ignored when it occurs while parsing the
# schema and PRAGMA writable_schema is turned on.
#
do_test misc5-7.2 {
  sqlite3 db2 :memory:
  sqlite3_db_config db2 DEFENSIVE 0
  catchsql {
    CREATE TABLE t1(x UNIQUE);
    PRAGMA writable_schema=ON;
    UPDATE sqlite_master SET sql='CREATE table t(o CHECK(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((;VALUES(o)';
    BEGIN;
    CREATE TABLE t2(y);
    ROLLBACK;

Changes to test/misc7.test.

430
431
432
433
434
435
436

437
438
439
440
441
442
443
      }
    } {0 32}
    
    # sqlite3_test_control_pending_page [expr ($::sqlite_pending_byte / 1024) + 1]
    set ::pending_byte_page [expr ($::sqlite_pending_byte / 1024) + 1]
    sqlite3_test_control_pending_byte $::sqlite_pending_byte 
    do_test misc7-17.3 {

      db eval {
        pragma writable_schema = true;
        UPDATE sqlite_master 
          SET rootpage = $pending_byte_page
          WHERE type = 'table' AND name = 't3';
      }
      execsql {







>







430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
      }
    } {0 32}
    
    # sqlite3_test_control_pending_page [expr ($::sqlite_pending_byte / 1024) + 1]
    set ::pending_byte_page [expr ($::sqlite_pending_byte / 1024) + 1]
    sqlite3_test_control_pending_byte $::sqlite_pending_byte 
    do_test misc7-17.3 {
      sqlite3_db_config db DEFENSIVE 0
      db eval {
        pragma writable_schema = true;
        UPDATE sqlite_master 
          SET rootpage = $pending_byte_page
          WHERE type = 'table' AND name = 't3';
      }
      execsql {

Changes to test/mjournal.test.

156
157
158
159
160
161
162
163
  BEGIN;
    INSERT INTO t1 VALUES(1);
    INSERT INTO t4 VALUES(1);
  COMMIT;
} {0}

finish_test








<
156
157
158
159
160
161
162

  BEGIN;
    INSERT INTO t1 VALUES(1);
    INSERT INTO t4 VALUES(1);
  COMMIT;
} {0}

finish_test

Changes to test/notnull.test.

602
603
604
605
606
607
608
609
do_uses_op_next_test notnull-6.7 "SELECT * FROM t7 WHERE a IS ?" 0
do_uses_op_next_test notnull-6.8 "SELECT * FROM t8 WHERE a IS ?" 0

do_uses_op_next_test notnull-6.9 "SELECT * FROM t8 WHERE a IS ?" 0
do_uses_op_next_test notnull-6.10 "SELECT * FROM t8 WHERE a IS ?" 0

finish_test








<
602
603
604
605
606
607
608

do_uses_op_next_test notnull-6.7 "SELECT * FROM t7 WHERE a IS ?" 0
do_uses_op_next_test notnull-6.8 "SELECT * FROM t8 WHERE a IS ?" 0

do_uses_op_next_test notnull-6.9 "SELECT * FROM t8 WHERE a IS ?" 0
do_uses_op_next_test notnull-6.10 "SELECT * FROM t8 WHERE a IS ?" 0

finish_test

Changes to test/pager1.test.

1875
1876
1877
1878
1879
1880
1881

1882
1883
1884
1885
1886
1887
1888
....
1927
1928
1929
1930
1931
1932
1933

1934
1935
1936
1937
1938
1939
1940
    INSERT INTO t1 SELECT a_string(500), a_string(200) FROM t1;
    INSERT INTO t1 SELECT a_string(500), a_string(200) FROM t1;
  }
} {}
do_test pager1-18.2 {
  set root [db one "SELECT rootpage FROM sqlite_master"]
  set lockingpage [expr (0x10000/1024) + 1]

  execsql {
    PRAGMA writable_schema = 1;
    UPDATE sqlite_master SET rootpage = $lockingpage;
  }
  sqlite3 db2 test.db
  catchsql { SELECT count(*) FROM t1 } db2
} {1 {database disk image is malformed}}
................................................................................
  hexio_write test.db [expr ($pgno-1)*1024] 90000000
  sqlite3 db2 test.db
  catchsql { SELECT length(x||'') FROM t2 } db2
} {1 {database disk image is malformed}}
db2 close
do_test pager1-18.5 {
  sqlite3 db ""

  execsql {
    CREATE TABLE t1(a, b);
    CREATE TABLE t2(a, b);
    PRAGMA writable_schema = 1;
    UPDATE sqlite_master SET rootpage=5 WHERE tbl_name = 't1';
    PRAGMA writable_schema = 0;
    ALTER TABLE t1 RENAME TO x1;







>







 







>







1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
....
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
    INSERT INTO t1 SELECT a_string(500), a_string(200) FROM t1;
    INSERT INTO t1 SELECT a_string(500), a_string(200) FROM t1;
  }
} {}
do_test pager1-18.2 {
  set root [db one "SELECT rootpage FROM sqlite_master"]
  set lockingpage [expr (0x10000/1024) + 1]
  sqlite3_db_config db DEFENSIVE 0
  execsql {
    PRAGMA writable_schema = 1;
    UPDATE sqlite_master SET rootpage = $lockingpage;
  }
  sqlite3 db2 test.db
  catchsql { SELECT count(*) FROM t1 } db2
} {1 {database disk image is malformed}}
................................................................................
  hexio_write test.db [expr ($pgno-1)*1024] 90000000
  sqlite3 db2 test.db
  catchsql { SELECT length(x||'') FROM t2 } db2
} {1 {database disk image is malformed}}
db2 close
do_test pager1-18.5 {
  sqlite3 db ""
  sqlite3_db_config db DEFENSIVE 0
  execsql {
    CREATE TABLE t1(a, b);
    CREATE TABLE t2(a, b);
    PRAGMA writable_schema = 1;
    UPDATE sqlite_master SET rootpage=5 WHERE tbl_name = 't1';
    PRAGMA writable_schema = 0;
    ALTER TABLE t1 RENAME TO x1;

Changes to test/parser1.test.

24
25
26
27
28
29
30

31
32
33
34
35
36
37
} {1 {syntax error after column name "b"}}


# Verify that a legacy schema in the sqlite_master file is allowed to have
# COLLATE, ASC, and DESC keywords on the id list of a FK constraint, and that
# those keywords are silently ignored.
#

do_execsql_test parser1-1.2 {
  CREATE TABLE t1(
    a TEXT PRIMARY KEY,
    b TEXT,
    FOREIGN KEY(b) REFERENCES t1(a)
  );
  INSERT INTO t1 VALUES('abc',NULL),('xyz','abc');







>







24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
} {1 {syntax error after column name "b"}}


# Verify that a legacy schema in the sqlite_master file is allowed to have
# COLLATE, ASC, and DESC keywords on the id list of a FK constraint, and that
# those keywords are silently ignored.
#
sqlite3_db_config db DEFENSIVE 0
do_execsql_test parser1-1.2 {
  CREATE TABLE t1(
    a TEXT PRIMARY KEY,
    b TEXT,
    FOREIGN KEY(b) REFERENCES t1(a)
  );
  INSERT INTO t1 VALUES('abc',NULL),('xyz','abc');

Changes to test/pragma.test.

493
494
495
496
497
498
499

500
501
502
503
504
505
506
    db eval {PRAGMA integrity_check}
  } {ok}
}

# Verify that PRAGMA integrity_check catches UNIQUE and NOT NULL
# constraint violations.
#

do_execsql_test pragma-3.20 {
  CREATE TABLE t1(a,b);
  CREATE INDEX t1a ON t1(a);
  INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(2,4),(NULL,5),(NULL,6);
  PRAGMA writable_schema=ON;
  UPDATE sqlite_master SET sql='CREATE UNIQUE INDEX t1a ON t1(a)'
   WHERE name='t1a';







>







493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
    db eval {PRAGMA integrity_check}
  } {ok}
}

# Verify that PRAGMA integrity_check catches UNIQUE and NOT NULL
# constraint violations.
#
sqlite3_db_config db DEFENSIVE 0
do_execsql_test pragma-3.20 {
  CREATE TABLE t1(a,b);
  CREATE INDEX t1a ON t1(a);
  INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(2,4),(NULL,5),(NULL,6);
  PRAGMA writable_schema=ON;
  UPDATE sqlite_master SET sql='CREATE UNIQUE INDEX t1a ON t1(a)'
   WHERE name='t1a';

Changes to test/resetdb.test.

61
62
63
64
65
66
67

68
69
70
71
72
73
74
...
121
122
123
124
125
126
127

128
129
130
131
132
133
134
...
224
225
226
227
228
229
230

231
232
233
234
235
236
237
    PRAGMA page_count;
  } db2
} {210 6000 ok delete 8}

do_test 200 {
  # Thoroughly corrupt the database file by overwriting the first
  # page with randomness.

  catchsql {
    UPDATE sqlite_dbpage SET data=randomblob(4096) WHERE pgno=1;
    PRAGMA quick_check;
  }
} {1 {unsupported file format}}
do_test 201 {
  catchsql {
................................................................................
    PRAGMA journal_mode;
    PRAGMA page_size;
    PRAGMA page_count;
  } db2
} {210 26000 ok wal 8192 12}

# Corrupt the database again

do_catchsql_test 320 {
  UPDATE sqlite_dbpage SET data=randomblob(8192) WHERE pgno=1;
  PRAGMA quick_check
} {1 {file is not a database}}

do_test 330 {
  catchsql {
................................................................................
} {19 ok}

if {[nonzero_reserved_bytes]} {
  finish_test
  return
}


do_execsql_test 710 {
  UPDATE sqlite_dbpage SET data=
    X'53514C69746520666F726D61742033000200030100402020000000000000001300000000000000000000000300000004000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000D00000003017C0001D801AC017C00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002E03061715110145696E6465787431626374310443524541544520494E4445582074316263204F4E20743128622C63292A0206171311013F696E64657874316174310343524541544520494E44455820743161204F4E20743128612926010617111101397461626C657431743102435245415445205441424C4520743128612C622C6329' WHERE pgno=1;
}

do_execsql_test 720 {
  PRAGMA integrity_check;







>







 







>







 







>







61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
...
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
...
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
    PRAGMA page_count;
  } db2
} {210 6000 ok delete 8}

do_test 200 {
  # Thoroughly corrupt the database file by overwriting the first
  # page with randomness.
  sqlite3_db_config db DEFENSIVE 0
  catchsql {
    UPDATE sqlite_dbpage SET data=randomblob(4096) WHERE pgno=1;
    PRAGMA quick_check;
  }
} {1 {unsupported file format}}
do_test 201 {
  catchsql {
................................................................................
    PRAGMA journal_mode;
    PRAGMA page_size;
    PRAGMA page_count;
  } db2
} {210 26000 ok wal 8192 12}

# Corrupt the database again
sqlite3_db_config db DEFENSIVE 0
do_catchsql_test 320 {
  UPDATE sqlite_dbpage SET data=randomblob(8192) WHERE pgno=1;
  PRAGMA quick_check
} {1 {file is not a database}}

do_test 330 {
  catchsql {
................................................................................
} {19 ok}

if {[nonzero_reserved_bytes]} {
  finish_test
  return
}

sqlite3_db_config db DEFENSIVE 0
do_execsql_test 710 {
  UPDATE sqlite_dbpage SET data=
    X'53514C69746520666F726D61742033000200030100402020000000000000001300000000000000000000000300000004000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000D00000003017C0001D801AC017C00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002E03061715110145696E6465787431626374310443524541544520494E4445582074316263204F4E20743128622C63292A0206171311013F696E64657874316174310343524541544520494E44455820743161204F4E20743128612926010617111101397461626C657431743102435245415445205441424C4520743128612C622C6329' WHERE pgno=1;
}

do_execsql_test 720 {
  PRAGMA integrity_check;

Changes to test/shared8.test.

58
59
60
61
62
63
64

65
66
67
68
69
70
71
    INSERT INTO t1 VALUES(4, 4);
    CREATE VIEW v1 AS SELECT a, roman(b) FROM t1;
    SELECT * FROM v1;
  } db1
} {1 i 2 ii 3 iii 4 iv}

do_test 1.1 {

  execsql { 
    PRAGMA writable_schema = 1;
    DELETE FROM sqlite_master WHERE 1;
    PRAGMA writable_schema = 0;
    SELECT * FROM sqlite_master;
  } db1
} {}







>







58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
    INSERT INTO t1 VALUES(4, 4);
    CREATE VIEW v1 AS SELECT a, roman(b) FROM t1;
    SELECT * FROM v1;
  } db1
} {1 i 2 ii 3 iii 4 iv}

do_test 1.1 {
  sqlite3_db_config db1 DEFENSIVE 0
  execsql { 
    PRAGMA writable_schema = 1;
    DELETE FROM sqlite_master WHERE 1;
    PRAGMA writable_schema = 0;
    SELECT * FROM sqlite_master;
  } db1
} {}

Changes to test/snapshot2.test.

234
235
236
237
238
239
240
241
  execsql { INSERT INTO t2 VALUES('jkl') } 
  execsql BEGIN db2
  list [catch { sqlite3_snapshot_open_blob db2 main $snap } msg] $msg
} {1 SQLITE_ERROR_SNAPSHOT}


finish_test








<
234
235
236
237
238
239
240

  execsql { INSERT INTO t2 VALUES('jkl') } 
  execsql BEGIN db2
  list [catch { sqlite3_snapshot_open_blob db2 main $snap } msg] $msg
} {1 SQLITE_ERROR_SNAPSHOT}


finish_test

Changes to test/snapshot3.test.

93
94
95
96
97
98
99
100

do_test 1.8 {
  execsql BEGIN db3
  list [catch { sqlite3_snapshot_open_blob db3 main $snap } msg] $msg
} {1 SQLITE_ERROR_SNAPSHOT}

finish_test








<
93
94
95
96
97
98
99


do_test 1.8 {
  execsql BEGIN db3
  list [catch { sqlite3_snapshot_open_blob db3 main $snap } msg] $msg
} {1 SQLITE_ERROR_SNAPSHOT}

finish_test

Changes to test/snapshot4.test.

68
69
70
71
72
73
74
75
  execsql {
    SELECT count(*) FROM t1
  } 
} {100}


finish_test








<
68
69
70
71
72
73
74

  execsql {
    SELECT count(*) FROM t1
  } 
} {100}


finish_test

Changes to test/snapshot_up.test.

177
178
179
180
181
182
183
184
  set ::res
} {1 SQLITE_BUSY}

sqlite3_snapshot_free $::snap1
sqlite3_snapshot_free $::snap2

finish_test








<
177
178
179
180
181
182
183

  set ::res
} {1 SQLITE_BUSY}

sqlite3_snapshot_free $::snap1
sqlite3_snapshot_free $::snap2

finish_test

Changes to test/swarmvtab3.test.

227
228
229
230
231
232
233
234
}

db close
forcedelete {*}[glob test.db*]
forcedelete {*}[glob test_remote.db*]

finish_test








<
227
228
229
230
231
232
233

}

db close
forcedelete {*}[glob test.db*]
forcedelete {*}[glob test_remote.db*]

finish_test

Changes to test/swarmvtabfault.test.

59
60
61
62
63
64
65
66
} -body {
  execsql { SELECT a FROM xyz }
} -test {
  faultsim_test_result {0 {1 2 9}} {1 {sql error: out of memory}}
}

finish_test








<
59
60
61
62
63
64
65

} -body {
  execsql { SELECT a FROM xyz }
} -test {
  faultsim_test_result {0 {1 2 9}} {1 {sql error: out of memory}}
}

finish_test

Changes to test/table.test.

272
273
274
275
276
277
278

279
280
281
282
283
284
285
  }
} {}

do_test table-5.2.2 {
  db close
  forcedelete test.db
  sqlite3 db test.db

  db eval {
    CREATE TABLE t0(a,b);
    CREATE INDEX t ON t0(a);
    PRAGMA writable_schema=ON;
    UPDATE sqlite_master SET sql='CREATE TABLE a.b(a UNIQUE';
    BEGIN;
    CREATE TABLE t1(x);







>







272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
  }
} {}

do_test table-5.2.2 {
  db close
  forcedelete test.db
  sqlite3 db test.db
  sqlite3_db_config db DEFENSIVE 0
  db eval {
    CREATE TABLE t0(a,b);
    CREATE INDEX t ON t0(a);
    PRAGMA writable_schema=ON;
    UPDATE sqlite_master SET sql='CREATE TABLE a.b(a UNIQUE';
    BEGIN;
    CREATE TABLE t1(x);

Changes to test/trigger7.test.

102
103
104
105
106
107
108

109
110
111
112
113
114
115
116
117
118
  }
} {}

# This test corrupts the database file so it must be the last test
# in the series.
#
do_test trigger7-99.1 {

  execsql {
    PRAGMA writable_schema=on;
    UPDATE sqlite_master SET sql='nonsense';
  }
  db close
  catch { sqlite3 db test.db }
  catchsql { DROP TRIGGER t2r5 }
} {/1 {malformed database schema .*}/}

finish_test







>










102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
  }
} {}

# This test corrupts the database file so it must be the last test
# in the series.
#
do_test trigger7-99.1 {
  sqlite3_db_config db DEFENSIVE 0
  execsql {
    PRAGMA writable_schema=on;
    UPDATE sqlite_master SET sql='nonsense';
  }
  db close
  catch { sqlite3 db test.db }
  catchsql { DROP TRIGGER t2r5 }
} {/1 {malformed database schema .*}/}

finish_test

Changes to test/triggerE.test.

64
65
66
67
68
69
70

71
72
73
74
75
76
77
  do_catchsql_test 1.2.$tn "CREATE TEMP TRIGGER tr1 $defn" [list 1 $errmsg]
}

#-------------------------------------------------------------------------
# Test that variable references within trigger definitions loaded from 
# the sqlite_master table are automatically converted to NULL.
#

do_execsql_test 2.1 {
  PRAGMA writable_schema = 1;
  INSERT INTO sqlite_master VALUES('trigger', 'tr1', 't1', 0,
    'CREATE TRIGGER tr1 AFTER INSERT ON t1 BEGIN 
        INSERT INTO t2 VALUES(?1, ?2); 
     END'
  );







>







64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
  do_catchsql_test 1.2.$tn "CREATE TEMP TRIGGER tr1 $defn" [list 1 $errmsg]
}

#-------------------------------------------------------------------------
# Test that variable references within trigger definitions loaded from 
# the sqlite_master table are automatically converted to NULL.
#
sqlite3_db_config db DEFENSIVE 0
do_execsql_test 2.1 {
  PRAGMA writable_schema = 1;
  INSERT INTO sqlite_master VALUES('trigger', 'tr1', 't1', 0,
    'CREATE TRIGGER tr1 AFTER INSERT ON t1 BEGIN 
        INSERT INTO t2 VALUES(?1, ?2); 
     END'
  );

Changes to test/unionvtab.test.

451
452
453
454
455
456
457
458
} {five six seven eight nine}

do_execsql_test 5.4 {
  SELECT * FROM cc WHERE two LIKE '6'
} {six 6}

finish_test








<
451
452
453
454
455
456
457

} {five six seven eight nine}

do_execsql_test 5.4 {
  SELECT * FROM cc WHERE two LIKE '6'
} {six 6}

finish_test

Changes to test/unionvtabfault.test.

77
78
79
80
81
82
83
84
} -test {
  faultsim_test_result {0 {}} {1 {initialization of unionvtab failed: }}
}



finish_test








<
77
78
79
80
81
82
83

} -test {
  faultsim_test_result {0 {}} {1 {initialization of unionvtab failed: }}
}



finish_test

Changes to test/vtab1.test.

1249
1250
1251
1252
1253
1254
1255

1256
1257
1258
1259
1260
1261
1262

# The following test case exposes an instance in sqlite3_declare_vtab()
# an error message was set using a call similar to sqlite3_mprintf(zErr),
# where zErr is an arbitrary string. This is no good if the string contains
# characters that can be mistaken for printf() formatting directives.
#
do_test vtab1-17.1 {

  execsql { 
    PRAGMA writable_schema = 1;
    INSERT INTO sqlite_master VALUES(
      'table', 't3', 't3', 0, 'INSERT INTO "%s%s" VALUES(1)'
    );
  }
  catchsql { CREATE VIRTUAL TABLE t4 USING echo(t3); }







>







1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263

# The following test case exposes an instance in sqlite3_declare_vtab()
# an error message was set using a call similar to sqlite3_mprintf(zErr),
# where zErr is an arbitrary string. This is no good if the string contains
# characters that can be mistaken for printf() formatting directives.
#
do_test vtab1-17.1 {
  sqlite3_db_config db DEFENSIVE 0
  execsql { 
    PRAGMA writable_schema = 1;
    INSERT INTO sqlite_master VALUES(
      'table', 't3', 't3', 0, 'INSERT INTO "%s%s" VALUES(1)'
    );
  }
  catchsql { CREATE VIRTUAL TABLE t4 USING echo(t3); }

Changes to test/wherelimit2.test.

293
294
295
296
297
298
299
300
  set ::log {}
  execsql { UPDATE "v w" SET "a b" = "a b" || 'x' ORDER BY "a b" LIMIT 5; }
  set ::log
} {ax a bx b cx c dx d ex a}


finish_test








<
293
294
295
296
297
298
299

  set ::log {}
  execsql { UPDATE "v w" SET "a b" = "a b" || 'x' ORDER BY "a b" LIMIT 5; }
  set ::log
} {ax a bx b cx c dx d ex a}


finish_test

Changes to test/window5.test.

90
91
92
93
94
95
96
97
} {1 {sum() may not be used as a window function}}
do_execsql_test 3.1 {
  SELECT sum(a) FROM t1;
} {21}


finish_test








<
90
91
92
93
94
95
96

} {1 {sum() may not be used as a window function}}
do_execsql_test 3.1 {
  SELECT sum(a) FROM t1;
} {21}


finish_test

Changes to test/windowfault.test.

159
160
161
162
163
164
165
166
    ORDER BY a;
  }
} -test {
  faultsim_test_result {0 {1 2 5 6 9 10}}
}

finish_test








<
159
160
161
162
163
164
165

    ORDER BY a;
  }
} -test {
  faultsim_test_result {0 {1 2 5 6 9 10}}
}

finish_test

Changes to test/zipfile2.test.

237
238
239
240
241
242
243
244
  INSERT INTO temp.zip (name,data) VALUES ('test1','test'); 
  INSERT INTO temp.zip (name,data) VALUES ('test2','test'); 
  UPDATE OR REPLACE zip SET name='test2' WHERE name='test1';
  SELECT name FROM zip;
} {test2}

finish_test








<
237
238
239
240
241
242
243

  INSERT INTO temp.zip (name,data) VALUES ('test1','test'); 
  INSERT INTO temp.zip (name,data) VALUES ('test2','test'); 
  UPDATE OR REPLACE zip SET name='test2' WHERE name='test1';
  SELECT name FROM zip;
} {test2}

finish_test

Changes to tool/genfkey.test.

347
348
349
350
351
352
353
354
} {1 {constraint failed}}
do_test genfkey-6.7 {
  execsql {
    SELECT * FROM parent;
    SELECT * FROM child;
  }
} {1 1}








<
347
348
349
350
351
352
353

} {1 {constraint failed}}
do_test genfkey-6.7 {
  execsql {
    SELECT * FROM parent;
    SELECT * FROM child;
  }
} {1 1}