Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Merge the read-only shadow table and defensive mode enhancments from trunk. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | apple-osx |
Files: | files | file ages | folders |
SHA3-256: |
977fc44e65f831d4c6184073f4470856 |
User & Date: | drh 2018-11-10 20:07:51.971 |
Context
2018-11-26
| ||
23:35 | Merge recent enhancements from trunk. (check-in: e8c20a88c1 user: drh tags: apple-osx) | |
2018-11-10
| ||
20:07 | Merge the read-only shadow table and defensive mode enhancments from trunk. (check-in: 977fc44e65 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: 9c685171c4 user: drh tags: trunk) | |
2018-11-09
| ||
23:45 | Merge fixes from trunk. (check-in: e3e9b85ead user: drh tags: apple-osx) | |
Changes
Changes to Makefile.in.
︙ | ︙ | |||
1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 | showshm$(TEXE): $(TOP)/tool/showshm.c $(LTLINK) -o $@ $(TOP)/tool/showshm.c changeset$(TEXE): $(TOP)/ext/session/changeset.c sqlite3.lo $(LTLINK) -o $@ $(TOP)/ext/session/changeset.c sqlite3.lo $(TLIBS) rollback-test$(TEXE): $(TOP)/tool/rollback-test.c sqlite3.lo $(LTLINK) -o $@ $(TOP)/tool/rollback-test.c sqlite3.lo $(TLIBS) atrc$(TEXX): $(TOP)/test/atrc.c sqlite3.lo $(LTLINK) -o $@ $(TOP)/test/atrc.c sqlite3.lo $(TLIBS) LogEst$(TEXE): $(TOP)/tool/logest.c sqlite3.h | > > > | 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 | showshm$(TEXE): $(TOP)/tool/showshm.c $(LTLINK) -o $@ $(TOP)/tool/showshm.c changeset$(TEXE): $(TOP)/ext/session/changeset.c sqlite3.lo $(LTLINK) -o $@ $(TOP)/ext/session/changeset.c sqlite3.lo $(TLIBS) changesetfuzz$(TEXE): $(TOP)/ext/session/changesetfuzz.c sqlite3.lo $(LTLINK) -o $@ $(TOP)/ext/session/changesetfuzz.c sqlite3.lo $(TLIBS) rollback-test$(TEXE): $(TOP)/tool/rollback-test.c sqlite3.lo $(LTLINK) -o $@ $(TOP)/tool/rollback-test.c sqlite3.lo $(TLIBS) atrc$(TEXX): $(TOP)/test/atrc.c sqlite3.lo $(LTLINK) -o $@ $(TOP)/test/atrc.c sqlite3.lo $(TLIBS) LogEst$(TEXE): $(TOP)/tool/logest.c sqlite3.h |
︙ | ︙ |
Changes to Makefile.msc.
︙ | ︙ | |||
2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 | $(LTLINK) $(NO_WARN) $(TOP)\tool\showshm.c /link $(LDFLAGS) $(LTLINKOPTS) changeset.exe: $(TOP)\ext\session\changeset.c $(SQLITE3C) $(SQLITE3H) $(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \ -DSQLITE_ENABLE_SESSION=1 -DSQLITE_ENABLE_PREUPDATE_HOOK=1 \ $(TOP)\ext\session\changeset.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS) fts3view.exe: $(TOP)\ext\fts3\tool\fts3view.c $(SQLITE3C) $(SQLITE3H) $(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \ $(TOP)\ext\fts3\tool\fts3view.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS) rollback-test.exe: $(TOP)\tool\rollback-test.c $(SQLITE3C) $(SQLITE3H) $(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \ $(TOP)\tool\rollback-test.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS) | > > > > > | 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 | $(LTLINK) $(NO_WARN) $(TOP)\tool\showshm.c /link $(LDFLAGS) $(LTLINKOPTS) changeset.exe: $(TOP)\ext\session\changeset.c $(SQLITE3C) $(SQLITE3H) $(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \ -DSQLITE_ENABLE_SESSION=1 -DSQLITE_ENABLE_PREUPDATE_HOOK=1 \ $(TOP)\ext\session\changeset.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS) changesetfuzz.exe: $(TOP)\ext\session\changesetfuzz.c $(SQLITE3C) $(SQLITE3H) $(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \ -DSQLITE_ENABLE_SESSION=1 -DSQLITE_ENABLE_PREUPDATE_HOOK=1 \ $(TOP)\ext\session\changesetfuzz.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS) fts3view.exe: $(TOP)\ext\fts3\tool\fts3view.c $(SQLITE3C) $(SQLITE3H) $(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \ $(TOP)\ext\fts3\tool\fts3view.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS) rollback-test.exe: $(TOP)\tool\rollback-test.c $(SQLITE3C) $(SQLITE3H) $(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \ $(TOP)\tool\rollback-test.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS) |
︙ | ︙ |
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 | UNUSED_PARAMETER(iSavepoint); assert( p->inTransaction ); assert( p->mxSavepoint >= iSavepoint ); TESTONLY( p->mxSavepoint = iSavepoint ); sqlite3Fts3PendingTermsClear(p); return SQLITE_OK; } static const sqlite3_module fts3Module = { | > > > > > > > > > > > > > > > | | 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 | 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, |
︙ | ︙ | |||
3866 3867 3868 3869 3870 3871 3872 3873 3874 3875 3876 3877 3878 3879 | /* 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. */ | > | 3881 3882 3883 3884 3885 3886 3887 3888 3889 3890 3891 3892 3893 3894 3895 | /* 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 | 0, /* xSync */ 0, /* xCommit */ 0, /* xRollback */ 0, /* xFindFunction */ 0, /* xRename */ 0, /* xSavepoint */ 0, /* xRelease */ | | > | 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 */ 0 /* xShadowName */ }; int rc; /* Return code */ rc = sqlite3_create_module(db, "fts4aux", &fts3aux_module, 0); return rc; } |
︙ | ︙ |
Changes to ext/fts3/fts3_term.c.
︙ | ︙ | |||
357 358 359 360 361 362 363 | 0, /* xSync */ 0, /* xCommit */ 0, /* xRollback */ 0, /* xFindFunction */ 0, /* xRename */ 0, /* xSavepoint */ 0, /* xRelease */ | | > | 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 | 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; } |
︙ | ︙ |
Changes to ext/fts3/fts3_tokenize_vtab.c.
︙ | ︙ | |||
439 440 441 442 443 444 445 | 0, /* xSync */ 0, /* xCommit */ 0, /* xRollback */ 0, /* xFindFunction */ 0, /* xRename */ 0, /* xSavepoint */ 0, /* xRelease */ | | > | 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 */ 0 /* xShadowName */ }; int rc; /* Return code */ rc = sqlite3_create_module(db, "fts3tokenize", &fts3tok_module, (void*)pHash); return rc; } |
︙ | ︙ |
Changes to ext/fts5/fts5_main.c.
︙ | ︙ | |||
2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 | 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 = { | > > > > > > > > > > > > > > > | | 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 | 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, |
︙ | ︙ | |||
2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 | /* 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 ){ | > | 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 | /* 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 | 0, /* xSync */ 0, /* xCommit */ 0, /* xRollback */ 0, /* xFindFunction */ 0, /* xRename */ 0, /* xSavepoint */ 0, /* xRelease */ | | > | 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 */ 0 /* xShadowName */ }; int rc; /* Return code */ rc = sqlite3_create_module(db, "fts5tokenize", &fts5tok_module, (void*)pApi); return rc; } |
︙ | ︙ |
Changes to ext/fts5/fts5_vocab.c.
︙ | ︙ | |||
751 752 753 754 755 756 757 758 759 760 761 762 | /* 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 | 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 | 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}} | > > | 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 | 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}} |
︙ | ︙ | |||
85 86 87 88 89 90 91 | 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}} | | | 87 88 89 90 91 92 93 94 95 96 97 98 99 100 | 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 | # 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 { | > | 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 | # 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 { |
︙ | ︙ | |||
244 245 246 247 248 249 250 251 252 253 254 255 256 257 | 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'); | > | 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 | 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 | 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'); } | > | 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | 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'); } |
︙ | ︙ | |||
82 83 84 85 86 87 88 89 90 91 92 93 94 95 | #------------------------------------------------------------------------- # 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 | > | 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 | #------------------------------------------------------------------------- # 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 |
︙ | ︙ | |||
154 155 156 157 158 159 160 161 162 163 164 165 166 167 | 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)] | > | 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 | 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)] |
︙ | ︙ | |||
178 179 180 181 182 183 184 185 186 187 188 189 190 191 | 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*' } }] | > | 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 | 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*' } }] |
︙ | ︙ | |||
253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 | 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 = X'000000180630626262626201020201056161616161010203040A' WHERE rowid>100; } 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 { UPDATE t1_idx SET term = X'3065' WHERE pgno=4; } 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; | > > > | 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 | 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 = X'000000180630626262626201020201056161616161010203040A' WHERE rowid>100; } 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 { UPDATE t1_idx SET term = X'3065' WHERE pgno=4; } 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; |
︙ | ︙ | |||
358 359 360 361 362 363 364 365 366 367 368 369 370 371 | 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 | > | 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 | 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 |
︙ | ︙ | |||
379 380 381 382 383 384 385 386 387 388 389 390 391 392 | # 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')" | > | 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 | # 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 | 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 | } 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 | 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'; | > | > | 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 | 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 | > | 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 | 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 |
︙ | ︙ | |||
477 478 479 480 481 482 483 | set e2 [db eval { EXPLAIN SELECT * FROM rrr ORDER BY term DESC }] expr [lsearch $e2 SorterSort]<0 } 0 finish_test | < | 478 479 480 481 482 483 484 | 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 | 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 | 0, /* xSync */ 0, /* xCommit */ 0, /* xRollback */ 0, /* xFindMethod */ 0, /* xRename */ 0, /* xSavepoint */ 0, /* xRelease */ | | > | 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 | 0, /* xSync */ 0, /* xCommit */ 0, /* xRollback */ 0, /* xFindMethod */ 0, /* xRename */ 0, /* xSavepoint */ 0, /* xRelease */ | | > | 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 | 0, /* xSync */ 0, /* xCommit */ 0, /* xRollback */ 0, /* xFindMethod */ 0, /* xRename */ 0, /* xSavepoint */ 0, /* xRelease */ | | > | 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 | 0, /* xSync */ 0, /* xCommit */ 0, /* xRollback */ 0, /* xFindMethod */ 0, /* xRename */ 0, /* xSavepoint */ 0, /* xRelease */ | | > | 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 | 0, /* xSync */ 0, /* xCommit */ 0, /* xRollback */ 0, /* xFindMethod */ 0, /* xRename */ 0, /* xSavepoint */ 0, /* xRelease */ | | > | 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 | 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 */ |
︙ | ︙ | |||
2411 2412 2413 2414 2415 2416 2417 | 0, /* xSync */ 0, /* xCommit */ 0, /* xRollback */ 0, /* xFindMethod */ 0, /* xRename */ 0, /* xSavepoint */ 0, /* xRelease */ | | > | 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 */ }; #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 | /* xSync */ 0, /* xCommit */ 0, /* xRollback */ 0, /* xFindMethod */ 0, /* xRename */ 0, /* xSavepoint */ 0, /* xRelease */ 0, | | > | 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 | 0, /* xSync */ 0, /* xCommit */ 0, /* xRollback */ 0, /* xFindMethod */ 0, /* xRename */ 0, /* xSavepoint */ 0, /* xRelease */ | | > | 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 | 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 | 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 | 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 | 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 | 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 | } {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 | 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 | 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 | 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 | 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 | {} 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 | } 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 | 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 | } {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 | 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 | } 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 | 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 | 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 | 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 | } {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 | } } } } } finish_test | < | 230 231 232 233 234 235 236 | } } } } } finish_test |
Changes to ext/rbu/rbufault2.test.
︙ | ︙ | |||
51 52 53 54 55 56 57 | {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 | } -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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | } 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 | return SQLITE_INDEX_CONSTRAINT_FUNCTION+1; } return 0; } static sqlite3_module geopolyModule = { | | | 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 | 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 */ |
︙ | ︙ | |||
1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 | 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; | > | 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 | 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.
︙ | ︙ | |||
3322 3323 3324 3325 3326 3327 3328 3329 | } sqlite3_free(zSql); } return rc; } static sqlite3_module rtreeModule = { | > > > > > > > > > > > > > > > > | | 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 3353 | } 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 */ |
︙ | ︙ | |||
3346 3347 3348 3349 3350 3351 3352 3353 3354 3355 3356 3357 3358 3359 | 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, | > | 3362 3363 3364 3365 3366 3367 3368 3369 3370 3371 3372 3373 3374 3375 3376 | 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 111 112 113 114 115 116 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 { SELECT * FROM t1 } {1 {database disk image is malformed}} do_catchsql_test rtree8-2.1.5 { DELETE FROM t1 } {1 {database disk image is malformed}} 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 112 113 114 115 116 117 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 { SELECT * FROM t1 } {1 {database disk image is malformed}} do_catchsql_test rtree8-2.1.5 { DELETE FROM t1 } {1 {database disk image is malformed}} 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 | 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 } | > | 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | 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 } |
︙ | ︙ | |||
242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 | #------------------------------------------------------------------------- # 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 | > < | 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 | #------------------------------------------------------------------------- # 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 | 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} | > | 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | 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} |
︙ | ︙ | |||
108 109 110 111 112 113 114 115 116 117 118 119 120 121 | 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 { | > | 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 | 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 { |
︙ | ︙ | |||
136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 | 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 { ROLLBACK; 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 | > < | 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 | 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 { ROLLBACK; 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 |
Added ext/session/changesetfuzz.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 | /* ** 2018-11-01 ** ** The author disclaims copyright to this source code. In place of ** a legal notice, here is a blessing: ** ** May you do good and not evil. ** May you find forgiveness for yourself and forgive others. ** May you share freely, never taking more than you give. ** ************************************************************************* ** This file contains code to implement the "changesetfuzz" command ** line utility for fuzzing changeset blobs without corrupting them. */ /************************************************************************ ** USAGE: ** ** This program may be invoked in two ways: ** ** changesetfuzz INPUT ** changesetfuzz INPUT SEED N ** ** Argument INPUT must be the name of a file containing a binary changeset. ** In the first form above, this program outputs a human-readable version ** of the same changeset. This is chiefly for debugging. ** ** As well as changesets, this program can also dump and fuzz patchsets. ** The term "changeset" is used for both patchsets and changesets from this ** point on. ** ** In the second form, arguments SEED and N must both be integers. In this ** case, this program writes N binary changesets to disk. Each output ** changeset is a slightly modified - "fuzzed" - version of the input. ** The output changesets are written to files name "INPUT-$n", where $n is ** an integer between 0 and N-1, inclusive. Output changesets are always ** well-formed. Parameter SEED is used to seed the PRNG - any two ** invocations of this program with the same SEED and input changeset create ** the same N output changesets. ** ** The ways in which an input changeset may be fuzzed are as follows: ** ** 1. Any two values within the changeset may be exchanged. ** ** 2. Any TEXT, BLOB, INTEGER or REAL value within the changeset ** may have a single bit of its content flipped. ** ** 3. Any value within a changeset may be replaced by a pseudo-randomly ** generated value. ** ** The above operations never set a PRIMARY KEY column to NULL. Nor do they ** set any value to "undefined", or replace any "undefined" value with ** another. Any such operation risks producing a changeset that is not ** well-formed. ** ** 4. A single change may be duplicated. ** ** 5. A single change may be removed, so long as this does not mean that ** there are zero changes following a table-header within the changeset. ** ** 6. A single change may have its type (INSERT, DELETE, UPDATE) changed. ** If an INSERT is changed to a DELETE (or vice versa), the type is ** simply changed - no other modifications are required. If an INSERT ** or DELETE is changed to an UPDATE, then the single record is duplicated ** (as both the old.* and new.* records of the new UPDATE change). If an ** UPDATE is changed to a DELETE or INSERT, the new.* record is discarded ** and any "undefined" fields replaced with pseudo-randomly generated ** values. ** ** 7. An UPDATE change that modifies N table columns may be modified so ** that it updates N-1 columns, so long as (N>1). ** ** 8. The "indirect" flag may be toggled for any change. ** ** Entire group of changes may also be operated on: ** ** 9. Duplicate an existing group. ** ** 10. Remove an existing group. ** ** 11. The positions of two groups may be exchanged. ** ** There are also schema changes: ** ** 12. A non-PK column may be added to a table. In this case a NULL ** value is appended to all records. ** ** 13. A PK column may be added to a table. In this case a non-NULL ** value is appended to all INSERT, DELETE and UPDATE old.* records. ** An "undefined" is appended to new.* UPDATE records. ** ** 14. A column may be removed from a table, provided that it is not the ** only PRIMARY KEY column in the table. In this case the corresponding ** field is removed from all records. In cases where this leaves an UPDATE ** with no non-PK, non-undefined fields, the entire change is removed. */ #include "sqlite3.h" #include <stdio.h> #include <stdlib.h> #include <string.h> #include <assert.h> #include <ctype.h> #define FUZZ_VALUE_SUB 1 /* Replace one value with a copy of another */ #define FUZZ_VALUE_MOD 2 /* Modify content by 1 bit */ #define FUZZ_VALUE_RND 3 /* Replace with pseudo-random value */ #define FUZZ_CHANGE_DUP 4 /* Duplicate an existing change */ #define FUZZ_CHANGE_DEL 5 /* Completely remove one change */ #define FUZZ_CHANGE_TYPE 6 /* Change the type of one change */ #define FUZZ_CHANGE_FIELD 7 /* Change an UPDATE to modify fewer columns */ #define FUZZ_CHANGE_INDIRECT 8 /* Toggle the "indirect" flag of a change */ #define FUZZ_GROUP_DUP 9 /* Duplicate a change group */ #define FUZZ_GROUP_DEL 10 /* Delete an entire change group */ #define FUZZ_GROUP_SWAP 11 /* Exchange the position of two groups */ #define FUZZ_COLUMN_ADD 12 /* Add column to table definition */ #define FUZZ_COLUMN_ADDPK 13 /* Add PK column to table definition */ #define FUZZ_COLUMN_DEL 14 /* Remove column from table definition */ typedef unsigned char u8; typedef sqlite3_uint64 u64; typedef sqlite3_int64 i64; typedef unsigned int u32; /* ** Show a usage message on stderr then quit. */ static void usage(const char *argv0){ fprintf(stderr, "Usage: %s FILENAME ?SEED N?\n", argv0); exit(1); } /* ** Read the content of a disk file into an in-memory buffer */ static void fuzzReadFile(const char *zFilename, int *pSz, void **ppBuf){ FILE *f; int sz; void *pBuf; f = fopen(zFilename, "rb"); if( f==0 ){ fprintf(stderr, "cannot open \"%s\" for reading\n", zFilename); exit(1); } fseek(f, 0, SEEK_END); sz = (int)ftell(f); rewind(f); pBuf = sqlite3_malloc( sz ? sz : 1 ); if( pBuf==0 ){ fprintf(stderr, "cannot allocate %d to hold content of \"%s\"\n", sz, zFilename); exit(1); } if( sz>0 ){ if( fread(pBuf, sz, 1, f)!=1 ){ fprintf(stderr, "cannot read all %d bytes of \"%s\"\n", sz, zFilename); exit(1); } fclose(f); } *pSz = sz; *ppBuf = pBuf; } /* ** Write the contents of buffer pBuf, size nBuf bytes, into file zFilename ** on disk. zFilename, if it already exists, is clobbered. */ static void fuzzWriteFile(const char *zFilename, void *pBuf, int nBuf){ FILE *f; f = fopen(zFilename, "wb"); if( f==0 ){ fprintf(stderr, "cannot open \"%s\" for writing\n", zFilename); exit(1); } if( fwrite(pBuf, nBuf, 1, f)!=1 ){ fprintf(stderr, "cannot write to \"%s\"\n", zFilename); exit(1); } fclose(f); } static int fuzzCorrupt(){ return SQLITE_CORRUPT; } /************************************************************************* ** The following block is a copy of the implementation of SQLite function ** sqlite3_randomness. This version has two important differences: ** ** 1. It always uses the same seed. So the sequence of random data output ** is the same for every run of the program. ** ** 2. It is not threadsafe. */ static struct sqlite3PrngType { unsigned char i, j; /* State variables */ unsigned char s[256]; /* State variables */ } sqlite3Prng = { 0xAF, 0x28, { 0x71, 0xF5, 0xB4, 0x6E, 0x80, 0xAB, 0x1D, 0xB8, 0xFB, 0xB7, 0x49, 0xBF, 0xFF, 0x72, 0x2D, 0x14, 0x79, 0x09, 0xE3, 0x78, 0x76, 0xB0, 0x2C, 0x0A, 0x8E, 0x23, 0xEE, 0xDF, 0xE0, 0x9A, 0x2F, 0x67, 0xE1, 0xBE, 0x0E, 0xA7, 0x08, 0x97, 0xEB, 0x77, 0x78, 0xBA, 0x9D, 0xCA, 0x49, 0x4C, 0x60, 0x9A, 0xF6, 0xBD, 0xDA, 0x7F, 0xBC, 0x48, 0x58, 0x52, 0xE5, 0xCD, 0x83, 0x72, 0x23, 0x52, 0xFF, 0x6D, 0xEF, 0x0F, 0x82, 0x29, 0xA0, 0x83, 0x3F, 0x7D, 0xA4, 0x88, 0x31, 0xE7, 0x88, 0x92, 0x3B, 0x9B, 0x3B, 0x2C, 0xC2, 0x4C, 0x71, 0xA2, 0xB0, 0xEA, 0x36, 0xD0, 0x00, 0xF1, 0xD3, 0x39, 0x17, 0x5D, 0x2A, 0x7A, 0xE4, 0xAD, 0xE1, 0x64, 0xCE, 0x0F, 0x9C, 0xD9, 0xF5, 0xED, 0xB0, 0x22, 0x5E, 0x62, 0x97, 0x02, 0xA3, 0x8C, 0x67, 0x80, 0xFC, 0x88, 0x14, 0x0B, 0x15, 0x10, 0x0F, 0xC7, 0x40, 0xD4, 0xF1, 0xF9, 0x0E, 0x1A, 0xCE, 0xB9, 0x1E, 0xA1, 0x72, 0x8E, 0xD7, 0x78, 0x39, 0xCD, 0xF4, 0x5D, 0x2A, 0x59, 0x26, 0x34, 0xF2, 0x73, 0x0B, 0xA0, 0x02, 0x51, 0x2C, 0x03, 0xA3, 0xA7, 0x43, 0x13, 0xE8, 0x98, 0x2B, 0xD2, 0x53, 0xF8, 0xEE, 0x91, 0x7D, 0xE7, 0xE3, 0xDA, 0xD5, 0xBB, 0xC0, 0x92, 0x9D, 0x98, 0x01, 0x2C, 0xF9, 0xB9, 0xA0, 0xEB, 0xCF, 0x32, 0xFA, 0x01, 0x49, 0xA5, 0x1D, 0x9A, 0x76, 0x86, 0x3F, 0x40, 0xD4, 0x89, 0x8F, 0x9C, 0xE2, 0xE3, 0x11, 0x31, 0x37, 0xB2, 0x49, 0x28, 0x35, 0xC0, 0x99, 0xB6, 0xD0, 0xBC, 0x66, 0x35, 0xF7, 0x83, 0x5B, 0xD7, 0x37, 0x1A, 0x2B, 0x18, 0xA6, 0xFF, 0x8D, 0x7C, 0x81, 0xA8, 0xFC, 0x9E, 0xC4, 0xEC, 0x80, 0xD0, 0x98, 0xA7, 0x76, 0xCC, 0x9C, 0x2F, 0x7B, 0xFF, 0x8E, 0x0E, 0xBB, 0x90, 0xAE, 0x13, 0x06, 0xF5, 0x1C, 0x4E, 0x52, 0xF7 } }; /* ** Generate and return single random byte */ static unsigned char fuzzRandomByte(void){ unsigned char t; sqlite3Prng.i++; t = sqlite3Prng.s[sqlite3Prng.i]; sqlite3Prng.j += t; sqlite3Prng.s[sqlite3Prng.i] = sqlite3Prng.s[sqlite3Prng.j]; sqlite3Prng.s[sqlite3Prng.j] = t; t += sqlite3Prng.s[sqlite3Prng.i]; return sqlite3Prng.s[t]; } /* ** Return N random bytes. */ static void fuzzRandomBlob(int nBuf, unsigned char *zBuf){ int i; for(i=0; i<nBuf; i++){ zBuf[i] = fuzzRandomByte(); } } /* ** Return a random integer between 0 and nRange (not inclusive). */ static unsigned int fuzzRandomInt(unsigned int nRange){ unsigned int ret; assert( nRange>0 ); fuzzRandomBlob(sizeof(ret), (unsigned char*)&ret); return (ret % nRange); } static u64 fuzzRandomU64(){ u64 ret; fuzzRandomBlob(sizeof(ret), (unsigned char*)&ret); return ret; } static void fuzzRandomSeed(unsigned int iSeed){ int i; for(i=0; i<256; i+=4){ sqlite3Prng.s[i] ^= ((iSeed >> 24) & 0xFF); sqlite3Prng.s[i+1] ^= ((iSeed >> 16) & 0xFF); sqlite3Prng.s[i+2] ^= ((iSeed >> 8) & 0xFF); sqlite3Prng.s[i+3] ^= ((iSeed >> 0) & 0xFF); } } /* ** End of code for generating pseudo-random values. *************************************************************************/ typedef struct FuzzChangeset FuzzChangeset; typedef struct FuzzChangesetGroup FuzzChangesetGroup; typedef struct FuzzChange FuzzChange; /* ** Object containing partially parsed changeset. */ struct FuzzChangeset { int bPatchset; /* True for a patchset */ FuzzChangesetGroup **apGroup; /* Array of groups in changeset */ int nGroup; /* Number of items in list pGroup */ u8 **apVal; /* Array of all values in changeset */ int nVal; /* Number of used slots in apVal[] */ int nChange; /* Number of changes in changeset */ int nUpdate; /* Number of UPDATE changes in changeset */ }; /* ** There is one object of this type for each change-group (table header) ** in the input changeset. */ struct FuzzChangesetGroup { const char *zTab; /* Name of table */ int nCol; /* Number of columns in table */ u8 *aPK; /* PK array for this table */ u8 *aChange; /* Buffer containing array of changes */ int szChange; /* Size of buffer aChange[] in bytes */ int nChange; /* Number of changes in buffer aChange[] */ }; /* ** Description of a fuzz change to be applied to a changeset. */ struct FuzzChange { int eType; /* One of the FUZZ_* constants above */ int iChange; /* Change or UPDATE to modify */ int iGroup; /* Group to modify */ int iDelete; /* Field to remove (FUZZ_COLUMN_DEL) */ u8 *pSub1; /* Replace this value with pSub2 */ u8 *pSub2; /* And this one with pSub1 */ u8 aSub[128]; /* Buffer for substitute value */ int iCurrent; /* Current change number */ }; /* ** Allocate and return nByte bytes of zeroed memory. */ static void *fuzzMalloc(int nByte){ void *pRet = sqlite3_malloc(nByte); if( pRet ){ memset(pRet, 0, nByte); } return pRet; } /* ** Free the buffer indicated by the first argument. This function is used ** to free buffers allocated by fuzzMalloc(). */ static void fuzzFree(void *p){ sqlite3_free(p); } /* ** Argument p points to a buffer containing an SQLite varint that, assuming the ** input is not corrupt, may be between 0 and 0x7FFFFFFF, inclusive. Before ** returning, this function sets (*pnVal) to the value of that varint, and ** returns the number of bytes of space that it takes up. */ static int fuzzGetVarint(u8 *p, int *pnVal){ int i; sqlite3_uint64 nVal = 0; for(i=0; i<9; i++){ nVal = (nVal<<7) + (p[i] & 0x7F); if( (p[i] & 0x80)==0 ){ i++; break; } } *pnVal = (int)nVal; return i; } /* ** Write value nVal into the buffer indicated by argument p as an SQLite ** varint. nVal is guaranteed to be between 0 and (2^21-1), inclusive. ** Return the number of bytes written to buffer p. */ static int fuzzPutVarint(u8 *p, int nVal){ assert( nVal>0 && nVal<2097152 ); if( nVal<128 ){ p[0] = nVal; return 1; } if( nVal<16384 ){ p[0] = ((nVal >> 7) & 0x7F) | 0x80; p[1] = (nVal & 0x7F); return 2; } p[0] = ((nVal >> 14) & 0x7F) | 0x80; p[1] = ((nVal >> 7) & 0x7F) | 0x80; p[2] = (nVal & 0x7F); return 3; } /* ** Read a 64-bit big-endian integer value from buffer aRec[]. Return ** the value read. */ static i64 fuzzGetI64(u8 *aRec){ return (i64)( (((u64)aRec[0]) << 56) + (((u64)aRec[1]) << 48) + (((u64)aRec[2]) << 40) + (((u64)aRec[3]) << 32) + (((u64)aRec[4]) << 24) + (((u64)aRec[5]) << 16) + (((u64)aRec[6]) << 8) + (((u64)aRec[7]) << 0) ); } /* ** Write value iVal to buffer aRec[] as an unsigned 64-bit big-endian integer. */ static void fuzzPutU64(u8 *aRec, u64 iVal){ aRec[0] = (iVal>>56) & 0xFF; aRec[1] = (iVal>>48) & 0xFF; aRec[2] = (iVal>>40) & 0xFF; aRec[3] = (iVal>>32) & 0xFF; aRec[4] = (iVal>>24) & 0xFF; aRec[5] = (iVal>>16) & 0xFF; aRec[6] = (iVal>> 8) & 0xFF; aRec[7] = (iVal) & 0xFF; } /* ** Parse a single table-header from the input. Allocate a new change-group ** object with the results. Return SQLITE_OK if successful, or an error code ** otherwise. */ static int fuzzParseHeader( FuzzChangeset *pParse, /* Changeset parse object */ u8 **ppHdr, /* IN/OUT: Iterator */ u8 *pEnd, /* 1 byte past EOF */ FuzzChangesetGroup **ppGrp /* OUT: New change-group object */ ){ int rc = SQLITE_OK; FuzzChangesetGroup *pGrp; u8 cHdr = (pParse->bPatchset ? 'P' : 'T'); assert( pEnd>(*ppHdr) ); pGrp = (FuzzChangesetGroup*)fuzzMalloc(sizeof(FuzzChangesetGroup)); if( !pGrp ){ rc = SQLITE_NOMEM; }else{ u8 *p = *ppHdr; if( p[0]!=cHdr ){ rc = fuzzCorrupt(); }else{ p++; p += fuzzGetVarint(p, &pGrp->nCol); pGrp->aPK = p; p += pGrp->nCol; pGrp->zTab = (const char*)p; p = &p[strlen(p)+1]; if( p>=pEnd ){ rc = fuzzCorrupt(); } } *ppHdr = p; } if( rc!=SQLITE_OK ){ fuzzFree(pGrp); pGrp = 0; } *ppGrp = pGrp; return rc; } /* ** Argument p points to a buffer containing a single changeset-record value. ** This function attempts to determine the size of the value in bytes. If ** successful, it sets (*pSz) to the size and returns SQLITE_OK. Or, if the ** buffer does not contain a valid value, SQLITE_CORRUPT is returned and ** the final value of (*pSz) is undefined. */ static int fuzzChangeSize(u8 *p, int *pSz){ u8 eType = p[0]; switch( eType ){ case 0x00: /* undefined */ case 0x05: /* null */ *pSz = 1; break; case 0x01: /* integer */ case 0x02: /* real */ *pSz = 9; break; case 0x03: /* text */ case 0x04: { /* blob */ int nTxt; int sz; sz = fuzzGetVarint(&p[1], &nTxt); *pSz = 1 + sz + nTxt; break; } default: return fuzzCorrupt(); } return SQLITE_OK; } /* ** When this function is called, (*ppRec) points to the start of a ** record in a changeset being parsed. This function adds entries ** to the pParse->apVal[] array for all values and advances (*ppRec) ** to one byte past the end of the record. Argument pEnd points to ** one byte past the end of the input changeset. ** ** Argument bPkOnly is true if the record being parsed is part of ** a DELETE record in a patchset. In this case, all non-primary-key ** fields have been omitted from the record. ** ** SQLITE_OK is returned if successful, or an SQLite error code otherwise. */ static int fuzzParseRecord( u8 **ppRec, /* IN/OUT: Iterator */ u8 *pEnd, /* One byte after end of input data */ FuzzChangeset *pParse, /* Changeset parse context */ int bPkOnly /* True if non-PK fields omitted */ ){ int rc = SQLITE_OK; FuzzChangesetGroup *pGrp = pParse->apGroup[pParse->nGroup-1]; int i; u8 *p = *ppRec; for(i=0; rc==SQLITE_OK && i<pGrp->nCol; i++){ if( bPkOnly==0 || pGrp->aPK[i] ){ int sz; if( p>=pEnd ) break; if( (pParse->nVal & (pParse->nVal-1))==0 ){ int nNew = pParse->nVal ? pParse->nVal*2 : 4; u8 **apNew = (u8**)sqlite3_realloc(pParse->apVal, nNew*sizeof(u8*)); if( apNew==0 ) return SQLITE_NOMEM; pParse->apVal = apNew; } pParse->apVal[pParse->nVal++] = p; rc = fuzzChangeSize(p, &sz); p += sz; } } if( rc==SQLITE_OK && i<pGrp->nCol ){ rc = fuzzCorrupt(); } *ppRec = p; return rc; } /* ** Parse the array of changes starting at (*ppData) and add entries for ** all values to the pParse->apVal[] array. Argument pEnd points to one byte ** past the end of the input changeset. If successful, set (*ppData) to point ** to one byte past the end of the change array and return SQLITE_OK. ** Otherwise, return an SQLite error code. The final value of (*ppData) is ** undefined in this case. */ static int fuzzParseChanges(u8 **ppData, u8 *pEnd, FuzzChangeset *pParse){ u8 cHdr = (pParse->bPatchset ? 'P' : 'T'); FuzzChangesetGroup *pGrp = pParse->apGroup[pParse->nGroup-1]; int rc = SQLITE_OK; u8 *p = *ppData; pGrp->aChange = p; while( rc==SQLITE_OK && p<pEnd && p[0]!=cHdr ){ u8 eOp = p[0]; u8 bIndirect = p[1]; p += 2; if( eOp==SQLITE_UPDATE ){ pParse->nUpdate++; if( pParse->bPatchset==0 ){ rc = fuzzParseRecord(&p, pEnd, pParse, 0); } }else if( eOp!=SQLITE_INSERT && eOp!=SQLITE_DELETE ){ rc = fuzzCorrupt(); } if( rc==SQLITE_OK ){ int bPkOnly = (eOp==SQLITE_DELETE && pParse->bPatchset); rc = fuzzParseRecord(&p, pEnd, pParse, bPkOnly); } pGrp->nChange++; pParse->nChange++; } pGrp->szChange = p - pGrp->aChange; *ppData = p; return rc; } /* ** Parse the changeset stored in buffer pChangeset (nChangeset bytes in ** size). If successful, write the results into (*pParse) and return ** SQLITE_OK. Or, if an error occurs, return an SQLite error code. The ** final state of (*pParse) is undefined in this case. */ static int fuzzParseChangeset( u8 *pChangeset, /* Buffer containing changeset */ int nChangeset, /* Size of buffer in bytes */ FuzzChangeset *pParse /* OUT: Results of parse */ ){ u8 *pEnd = &pChangeset[nChangeset]; u8 *p = pChangeset; int rc = SQLITE_OK; memset(pParse, 0, sizeof(FuzzChangeset)); if( nChangeset>0 ){ pParse->bPatchset = (pChangeset[0]=='P'); } while( rc==SQLITE_OK && p<pEnd ){ FuzzChangesetGroup *pGrp = 0; /* Read a table-header from the changeset */ rc = fuzzParseHeader(pParse, &p, pEnd, &pGrp); assert( (rc==SQLITE_OK)==(pGrp!=0) ); /* If the table-header was successfully parsed, add the new change-group ** to the array and parse the associated changes. */ if( rc==SQLITE_OK ){ FuzzChangesetGroup **apNew = (FuzzChangesetGroup**)sqlite3_realloc( pParse->apGroup, sizeof(FuzzChangesetGroup*)*(pParse->nGroup+1) ); if( apNew==0 ){ rc = SQLITE_NOMEM; }else{ apNew[pParse->nGroup] = pGrp; pParse->apGroup = apNew; pParse->nGroup++; } rc = fuzzParseChanges(&p, pEnd, pParse); } } return rc; } /* ** When this function is called, (*ppRec) points to the first byte of ** a record that is part of change-group pGrp. This function attempts ** to output a human-readable version of the record to stdout and advance ** (*ppRec) to point to the first byte past the end of the record before ** returning. If successful, SQLITE_OK is returned. Otherwise, an SQLite ** error code. ** ** If parameter bPkOnly is non-zero, then all non-primary-key fields have ** been omitted from the record. This occurs for records that are part ** of DELETE changes in patchsets. */ static int fuzzPrintRecord(FuzzChangesetGroup *pGrp, u8 **ppRec, int bPKOnly){ int rc = SQLITE_OK; u8 *p = *ppRec; int i; const char *zPre = " ("; for(i=0; i<pGrp->nCol; i++){ if( bPKOnly==0 || pGrp->aPK[i] ){ u8 eType = p++[0]; switch( eType ){ case 0x00: /* undefined */ printf("%sn/a", zPre); break; case 0x01: { /* integer */ sqlite3_int64 iVal = 0; iVal = fuzzGetI64(p); printf("%s%lld", zPre, iVal); p += 8; break; } case 0x02: { /* real */ sqlite3_int64 iVal = 0; double fVal = 0.0; iVal = fuzzGetI64(p); memcpy(&fVal, &iVal, 8); printf("%s%f", zPre, fVal); p += 8; break; } case 0x03: /* text */ case 0x04: { /* blob */ int nTxt; int sz; int i; p += fuzzGetVarint(p, &nTxt); printf("%s%s", zPre, eType==0x03 ? "'" : "X'"); for(i=0; i<nTxt; i++){ if( eType==0x03 ){ printf("%c", p[i]); }else{ char aHex[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; printf("%c", aHex[ p[i]>>4 ]); printf("%c", aHex[ p[i] & 0x0F ]); } } printf("'"); p += nTxt; break; } case 0x05: /* null */ printf("%sNULL", zPre); break; } zPre = ", "; } } printf(")"); *ppRec = p; return rc; } /* ** Print a human-readable version of the table-header and all changes in the ** change-group passed as the second argument. */ static void fuzzPrintGroup(FuzzChangeset *pParse, FuzzChangesetGroup *pGrp){ int i; u8 *p; /* The table header */ printf("TABLE: %s nCol=%d aPK=", pGrp->zTab, pGrp->nCol); for(i=0; i<pGrp->nCol; i++){ printf("%d", (int)pGrp->aPK[i]); } printf("\n"); /* The array of changes */ p = pGrp->aChange; for(i=0; i<pGrp->nChange; i++){ u8 eType = p[0]; u8 bIndirect = p[1]; printf("%s (ind=%d):", (eType==SQLITE_INSERT) ? "INSERT" : (eType==SQLITE_DELETE ? "DELETE" : "UPDATE"), bIndirect ); p += 2; if( pParse->bPatchset==0 && eType==SQLITE_UPDATE ){ fuzzPrintRecord(pGrp, &p, 0); } fuzzPrintRecord(pGrp, &p, eType==SQLITE_DELETE && pParse->bPatchset); printf("\n"); } } /* ** Initialize the object passed as the second parameter with details ** of the change that will be attempted (type of change, to which part of the ** changeset it applies etc.). If successful, return SQLITE_OK. Or, if an ** error occurs, return an SQLite error code. ** ** If a negative value is returned, then the selected change would have ** produced a non-well-formed changeset. In this case the caller should ** call this function again. */ static int fuzzSelectChange(FuzzChangeset *pParse, FuzzChange *pChange){ int iSub; memset(pChange, 0, sizeof(FuzzChange)); pChange->eType = fuzzRandomInt(FUZZ_COLUMN_DEL) + 1; assert( pChange->eType==FUZZ_VALUE_SUB || pChange->eType==FUZZ_VALUE_MOD || pChange->eType==FUZZ_VALUE_RND || pChange->eType==FUZZ_CHANGE_DUP || pChange->eType==FUZZ_CHANGE_DEL || pChange->eType==FUZZ_CHANGE_TYPE || pChange->eType==FUZZ_CHANGE_FIELD || pChange->eType==FUZZ_CHANGE_INDIRECT || pChange->eType==FUZZ_GROUP_DUP || pChange->eType==FUZZ_GROUP_DEL || pChange->eType==FUZZ_GROUP_SWAP || pChange->eType==FUZZ_COLUMN_ADD || pChange->eType==FUZZ_COLUMN_ADDPK || pChange->eType==FUZZ_COLUMN_DEL ); pChange->iGroup = fuzzRandomInt(pParse->nGroup); pChange->iChange = fuzzRandomInt(pParse->nChange); if( pChange->eType==FUZZ_CHANGE_FIELD ){ if( pParse->nUpdate==0 ) return -1; pChange->iChange = fuzzRandomInt(pParse->nUpdate); } pChange->iDelete = -1; if( pChange->eType==FUZZ_COLUMN_DEL ){ FuzzChangesetGroup *pGrp = pParse->apGroup[pChange->iGroup]; int i; pChange->iDelete = fuzzRandomInt(pGrp->nCol); for(i=pGrp->nCol-1; i>=0; i--){ if( pGrp->aPK[i] && pChange->iDelete!=i ) break; } if( i<0 ) return -1; } if( pChange->eType==FUZZ_GROUP_SWAP ){ FuzzChangesetGroup *pGrp; int iGrp = pChange->iGroup; if( pParse->nGroup==1 ) return -1; while( iGrp==pChange->iGroup ){ iGrp = fuzzRandomInt(pParse->nGroup); } pGrp = pParse->apGroup[pChange->iGroup]; pParse->apGroup[pChange->iGroup] = pParse->apGroup[iGrp]; pParse->apGroup[iGrp] = pGrp; } if( pChange->eType==FUZZ_VALUE_SUB || pChange->eType==FUZZ_VALUE_MOD || pChange->eType==FUZZ_VALUE_RND ){ iSub = fuzzRandomInt(pParse->nVal); pChange->pSub1 = pParse->apVal[iSub]; if( pChange->eType==FUZZ_VALUE_SUB ){ iSub = fuzzRandomInt(pParse->nVal); pChange->pSub2 = pParse->apVal[iSub]; }else{ pChange->pSub2 = pChange->aSub; } if( pChange->eType==FUZZ_VALUE_RND ){ pChange->aSub[0] = (u8)(fuzzRandomInt(5) + 1); switch( pChange->aSub[0] ){ case 0x01: { /* integer */ u64 iVal = fuzzRandomU64(); fuzzPutU64(&pChange->aSub[1], iVal); break; } case 0x02: { /* real */ u64 iVal1 = fuzzRandomU64(); u64 iVal2 = fuzzRandomU64(); double d = (double)iVal1 / (double)iVal2; memcpy(&iVal1, &d, sizeof(iVal1)); fuzzPutU64(&pChange->aSub[1], iVal1); break; } case 0x03: /* text */ case 0x04: { /* blob */ int nByte = fuzzRandomInt(48); pChange->aSub[1] = nByte; fuzzRandomBlob(nByte, &pChange->aSub[2]); if( pChange->aSub[0]==0x03 ){ int i; for(i=0; i<nByte; i++){ pChange->aSub[2+i] &= 0x7F; } } break; } } } if( pChange->eType==FUZZ_VALUE_MOD ){ int sz; int iMod = -1; fuzzChangeSize(pChange->pSub1, &sz); memcpy(pChange->aSub, pChange->pSub1, sz); switch( pChange->aSub[0] ){ case 0x01: case 0x02: iMod = fuzzRandomInt(8) + 1; break; case 0x03: /* text */ case 0x04: { /* blob */ int nByte; int iFirst = 1 + fuzzGetVarint(&pChange->aSub[1], &nByte); if( nByte>0 ){ iMod = fuzzRandomInt(nByte) + iFirst; } break; } } if( iMod>=0 ){ u8 mask = (1 << fuzzRandomInt(8 - (pChange->aSub[0]==0x03))); pChange->aSub[iMod] ^= mask; } } } return SQLITE_OK; } /* ** Copy a single change from the input to the output changeset, making ** any modifications specified by (*pFuzz). */ static int fuzzCopyChange( FuzzChangeset *pParse, int iGrp, FuzzChange *pFuzz, u8 **pp, u8 **ppOut /* IN/OUT: Input and output pointers */ ){ int bPS = pParse->bPatchset; FuzzChangesetGroup *pGrp = pParse->apGroup[iGrp]; u8 *p = *pp; u8 *pOut = *ppOut; u8 eType = p++[0]; int iRec; int nRec = ((eType==SQLITE_UPDATE && !bPS) ? 2 : 1); int iUndef = -1; int nUpdate = 0; u8 eNew = eType; if( pFuzz->iCurrent==pFuzz->iChange && pFuzz->eType==FUZZ_CHANGE_TYPE ){ switch( eType ){ case SQLITE_INSERT: eNew = SQLITE_DELETE; break; case SQLITE_DELETE: eNew = SQLITE_UPDATE; break; case SQLITE_UPDATE: eNew = SQLITE_INSERT; break; } } if( pFuzz->iCurrent==pFuzz->iChange && pFuzz->eType==FUZZ_CHANGE_FIELD && eType==SQLITE_UPDATE ){ int sz; int i; int nDef = 0; u8 *pCsr = p+1; for(i=0; i<pGrp->nCol; i++){ if( pCsr[0] && pGrp->aPK[i]==0 ) nDef++; fuzzChangeSize(pCsr, &sz); pCsr += sz; } if( nDef<=1 ) return -1; nDef = fuzzRandomInt(nDef); pCsr = p+1; for(i=0; i<pGrp->nCol; i++){ if( pCsr[0] && pGrp->aPK[i]==0 ){ if( nDef==0 ) iUndef = i; nDef--; } fuzzChangeSize(pCsr, &sz); pCsr += sz; } } /* Copy the change type and indirect flag. If the fuzz mode is ** FUZZ_CHANGE_INDIRECT, and the current change is the one selected for ** fuzzing, invert the indirect flag. */ *(pOut++) = eNew; if( pFuzz->eType==FUZZ_CHANGE_INDIRECT && pFuzz->iCurrent==pFuzz->iChange ){ *(pOut++) = !(*(p++)); }else{ *(pOut++) = *(p++); } for(iRec=0; iRec<nRec; iRec++){ int i; /* Copy the next record from the output to the input. */ for(i=0; i<pGrp->nCol; i++){ int sz; u8 *pCopy = p; /* If this is a patchset, and the input is a DELETE, then the only ** fields present are the PK fields. So, if this is not a PK, skip to ** the next column. If the current fuzz is FUZZ_CHANGE_TYPE, then ** write a randomly selected value to the output. */ if( bPS && eType==SQLITE_DELETE && pGrp->aPK[i]==0 ){ if( eType!=eNew ){ assert( eNew==SQLITE_UPDATE ); do { pCopy = pParse->apVal[fuzzRandomInt(pParse->nVal)]; }while( pCopy[0]==0x00 ); fuzzChangeSize(pCopy, &sz); memcpy(pOut, pCopy, sz); pOut += sz; } continue; } if( p==pFuzz->pSub1 ){ pCopy = pFuzz->pSub2; }else if( p==pFuzz->pSub2 ){ pCopy = pFuzz->pSub1; }else if( i==iUndef ){ pCopy = "\0"; } if( pCopy[0]==0x00 && eNew!=eType && eType==SQLITE_UPDATE && iRec==0 ){ while( pCopy[0]==0x00 ){ pCopy = pParse->apVal[fuzzRandomInt(pParse->nVal)]; } }else if( p[0]==0x00 && pCopy[0]!=0x00 ){ return -1; }else{ if( pGrp->aPK[i]>0 && pCopy[0]==0x05 ) return -1; } if( (pFuzz->iGroup!=iGrp || i!=pFuzz->iDelete) && (eNew==eType || eType!=SQLITE_UPDATE || iRec==0) && (eNew==eType || eNew!=SQLITE_DELETE || !bPS || pGrp->aPK[i]) ){ fuzzChangeSize(pCopy, &sz); memcpy(pOut, pCopy, sz); pOut += sz; nUpdate += (pGrp->aPK[i]==0 && pCopy[0]!=0x00); } fuzzChangeSize(p, &sz); p += sz; } if( iGrp==pFuzz->iGroup ){ if( pFuzz->eType==FUZZ_COLUMN_ADD ){ if( !bPS || eType!=SQLITE_DELETE ) *(pOut++) = 0x05; }else if( pFuzz->eType==FUZZ_COLUMN_ADDPK ){ if( iRec==1 ){ *(pOut++) = 0x00; }else{ u8 *pNew; int szNew; do { pNew = pParse->apVal[fuzzRandomInt(pParse->nVal)]; }while( pNew[0]==0x00 || pNew[0]==0x05 ); fuzzChangeSize(pNew, &szNew); memcpy(pOut, pNew, szNew); pOut += szNew; } } } } if( pFuzz->iCurrent==pFuzz->iChange ){ if( pFuzz->eType==FUZZ_CHANGE_DUP ){ int nByte = pOut - (*ppOut); memcpy(pOut, *ppOut, nByte); pOut += nByte; } if( pFuzz->eType==FUZZ_CHANGE_DEL ){ pOut = *ppOut; } if( eNew!=eType && eNew==SQLITE_UPDATE && !bPS ){ int i; u8 *pCsr = (*ppOut) + 2; for(i=0; i<pGrp->nCol; i++){ int sz; u8 *pCopy = pCsr; if( pGrp->aPK[i] ) pCopy = "\0"; fuzzChangeSize(pCopy, &sz); memcpy(pOut, pCopy, sz); pOut += sz; fuzzChangeSize(pCsr, &sz); pCsr += sz; } } } /* If a column is being deleted from this group, and this change was an ** UPDATE, and there are now no non-PK, non-undefined columns in the ** change, remove it altogether. */ if( pFuzz->eType==FUZZ_COLUMN_DEL && pFuzz->iGroup==iGrp && eType==SQLITE_UPDATE && nUpdate==0 ){ pOut = *ppOut; } *pp = p; *ppOut = pOut; pFuzz->iCurrent += (eType==SQLITE_UPDATE || pFuzz->eType!=FUZZ_CHANGE_FIELD); return SQLITE_OK; } /* ** Fuzz the changeset parsed into object pParse and write the results ** to file zOut on disk. Argument pBuf points to a buffer that is guaranteed ** to be large enough to hold the fuzzed changeset. ** ** Return SQLITE_OK if successful, or an SQLite error code if an error occurs. */ static int fuzzDoOneFuzz( const char *zOut, /* Filename to write modified changeset to */ u8 *pBuf, /* Buffer to use for modified changeset */ FuzzChangeset *pParse /* Parse of input changeset */ ){ FuzzChange change; int iGrp; int rc = -1; while( rc<0 ){ u8 *pOut = pBuf; rc = fuzzSelectChange(pParse, &change); for(iGrp=0; rc==SQLITE_OK && iGrp<pParse->nGroup; iGrp++){ FuzzChangesetGroup *pGrp = pParse->apGroup[iGrp]; int nTab = strlen(pGrp->zTab) + 1; int j; int nRep = 1; /* If this is the group to delete for a FUZZ_GROUP_DEL change, jump to ** the next group. Unless this is the only group in the changeset - in ** that case this change cannot be applied. ** ** Or, if this is a FUZZ_GROUP_DUP, set nRep to 2 to output two ** copies of the group. */ if( change.iGroup==iGrp ){ if( change.eType==FUZZ_GROUP_DEL ){ if( pParse->nGroup==1 ) rc = -1; continue; } else if( change.eType==FUZZ_GROUP_DUP ){ nRep = 2; } } for(j=0; j<nRep; j++){ int i; u8 *pSaved; u8 *p = pGrp->aChange; int nCol = pGrp->nCol; int iPKDel = 0; if( iGrp==change.iGroup ){ if( change.eType==FUZZ_COLUMN_ADD || change.eType==FUZZ_COLUMN_ADDPK ){ nCol++; }else if( change.eType==FUZZ_COLUMN_DEL ){ nCol--; iPKDel = pGrp->aPK[change.iDelete]; } } /* Output a table header */ pOut++[0] = pParse->bPatchset ? 'P' : 'T'; pOut += fuzzPutVarint(pOut, nCol); for(i=0; i<pGrp->nCol; i++){ if( iGrp!=change.iGroup || i!=change.iDelete ){ u8 v = pGrp->aPK[i]; if( iPKDel && v>iPKDel ) v--; *(pOut++) = v; } } if( nCol>pGrp->nCol ){ if( change.eType==FUZZ_COLUMN_ADD ){ *(pOut++) = 0x00; }else{ u8 max = 0; for(i=0; i<pGrp->nCol; i++){ if( pGrp->aPK[i]>max ) max = pGrp->aPK[i]; } *(pOut++) = max+1; } } memcpy(pOut, pGrp->zTab, nTab); pOut += nTab; /* Output the change array. */ pSaved = pOut; for(i=0; rc==SQLITE_OK && i<pGrp->nChange; i++){ rc = fuzzCopyChange(pParse, iGrp, &change, &p, &pOut); } if( pOut==pSaved ) rc = -1; } } if( rc==SQLITE_OK ){ fuzzWriteFile(zOut, pBuf, pOut-pBuf); } } return rc; } int main(int argc, char **argv){ int nRepeat = 0; /* Number of output files */ int iSeed = 0; /* Value of PRNG seed */ const char *zInput; /* Name of input file */ void *pChangeset = 0; /* Input changeset */ int nChangeset = 0; /* Size of input changeset in bytes */ int i; /* Current output file */ FuzzChangeset changeset; /* Partially parsed changeset */ int rc; u8 *pBuf = 0; if( argc!=4 && argc!=2 ) usage(argv[0]); zInput = argv[1]; fuzzReadFile(zInput, &nChangeset, &pChangeset); rc = fuzzParseChangeset(pChangeset, nChangeset, &changeset); if( rc==SQLITE_OK ){ if( argc==2 ){ for(i=0; i<changeset.nGroup; i++){ fuzzPrintGroup(&changeset, changeset.apGroup[i]); } }else{ pBuf = (u8*)fuzzMalloc(nChangeset*2 + 1024); if( pBuf==0 ){ rc = SQLITE_NOMEM; }else{ iSeed = atoi(argv[2]); nRepeat = atoi(argv[3]); fuzzRandomSeed((unsigned int)iSeed); for(i=0; rc==SQLITE_OK && i<nRepeat; i++){ char *zOut = sqlite3_mprintf("%s-%d", zInput, i); rc = fuzzDoOneFuzz(zOut, pBuf, &changeset); sqlite3_free(zOut); } fuzzFree(pBuf); } } } if( rc!=SQLITE_OK ){ fprintf(stderr, "error while processing changeset: %d\n", rc); } return rc; } |
Added ext/session/changesetfuzz1.test.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 | # 2018 November 08 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # if {![info exists testdir]} { set testdir [file join [file dirname [info script]] .. .. test] } source [file join [file dirname [info script]] session_common.tcl] source $testdir/tester.tcl ifcapable !session {finish_test; return} set testprefix changesetfuzz1 set CF [test_find_binary changesetfuzz] if {$CF==""} { finish_test return } proc writefile {zFile data} { set fd [open $zFile w] fconfigure $fd -translation binary -encoding binary puts -nonewline $fd $data close $fd } do_execsql_test 1.0 { CREATE TABLE t1(a, b, c, d, PRIMARY KEY(c, d)); CREATE TABLE t2(a INTEGER PRIMARY KEY, b, c); INSERT INTO t1 VALUES ('one', 'two', 'three', 'four'), ('five', 'six', 'seven', 'eight'), ('nine', 'ten', 'eleven', 'twelve'); INSERT INTO t2 VALUES (1, 2, 3), (4, 5, 6), (7, 8, 9); } set C [changeset_from_sql { INSERT INTO t2 VALUES(10, 11, 12); DELETE FROM t2 WHERE a=1; UPDATE t1 SET b='forty-five' WHERE a='one'; UPDATE t1 SET a='twenty-nine', b='seventy' WHERE a='five'; }] writefile c1.changeset $C do_test 1.1 { for {set j 0} {$j < 200} {incr j} { forcecopy c1.changeset input.changeset for {set i 0} {$i < 6} {incr i} { exec $CF input.changeset $i 1 exec $CF input.changeset-0 forcecopy input.changeset-0 input.changeset } } } {} set P [patchset_from_sql { INSERT INTO t2 VALUES(13, 14, 15); DELETE FROM t2 WHERE a=4; UPDATE t1 SET b='thirteen' WHERE a='one'; UPDATE t1 SET a='ninety-seven', b='twenty' WHERE a='five'; }] writefile p1.patchset $P do_test 1.2 { for {set j 0} {$j < 200} {incr j} { forcecopy p1.patchset input.patchset for {set i 0} {$i < 6} {incr i} { exec $CF input.patchset $i 1 exec $CF input.patchset-0 forcecopy input.patchset-0 input.patchset } } } {} finish_test |
Changes to ext/session/sessionC.test.
︙ | ︙ | |||
191 192 193 194 195 196 197 | 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 | } {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 | {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 | } 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 | 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 | 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 | } -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 | 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 | 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 | 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 main.mk.
︙ | ︙ | |||
998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 | showshm$(EXE): $(TOP)/tool/showshm.c $(TCC) -o showshm$(EXE) $(TOP)/tool/showshm.c changeset$(EXE): $(TOP)/ext/session/changeset.c sqlite3.o $(TCC) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -o changeset$(EXE) \ $(TOP)/ext/session/changeset.c sqlite3.o $(THREADLIB) fts3view$(EXE): $(TOP)/ext/fts3/tool/fts3view.c sqlite3.o $(TCC) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -o fts3view$(EXE) \ $(TOP)/ext/fts3/tool/fts3view.c sqlite3.o $(THREADLIB) rollback-test$(EXE): $(TOP)/tool/rollback-test.c sqlite3.o $(TCC) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -o rollback-test$(EXE) \ | > > > > | 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 | showshm$(EXE): $(TOP)/tool/showshm.c $(TCC) -o showshm$(EXE) $(TOP)/tool/showshm.c changeset$(EXE): $(TOP)/ext/session/changeset.c sqlite3.o $(TCC) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -o changeset$(EXE) \ $(TOP)/ext/session/changeset.c sqlite3.o $(THREADLIB) changesetfuzz$(EXE): $(TOP)/ext/session/changesetfuzz.c sqlite3.o $(TCC) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -o changesetfuzz$(EXE) \ $(TOP)/ext/session/changesetfuzz.c sqlite3.o $(THREADLIB) fts3view$(EXE): $(TOP)/ext/fts3/tool/fts3view.c sqlite3.o $(TCC) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -o fts3view$(EXE) \ $(TOP)/ext/fts3/tool/fts3view.c sqlite3.o $(THREADLIB) rollback-test$(EXE): $(TOP)/tool/rollback-test.c sqlite3.o $(TCC) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -o rollback-test$(EXE) \ |
︙ | ︙ |
Changes to src/build.c.
︙ | ︙ | |||
1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 | 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 | > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 | 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 |
︙ | ︙ | |||
1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 | 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.) ** | > > > > | 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 | 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 | 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){ | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > < < < < < < < < < < < < < < | < < | 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.
︙ | ︙ | |||
3155 3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 3167 3168 | | 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 | > > > | 3155 3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 | | 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 | 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 */ | | > | 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.
︙ | ︙ | |||
2157 2158 2159 2160 2161 2162 2163 | ** <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> | | | | < < | | | > < < < < < < < < < < | 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 | ** <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* */ |
︙ | ︙ | |||
6319 6320 6321 6322 6323 6324 6325 6326 6327 6328 6329 6330 6331 6332 | 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 | > > > | 6308 6309 6310 6311 6312 6313 6314 6315 6316 6317 6318 6319 6320 6321 6322 6323 6324 | 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.
︙ | ︙ | |||
2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 | #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 | > | 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 | #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 | 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; | | > | 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 | # 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 | > | 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | # 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 |
︙ | ︙ | |||
87 88 89 90 91 92 93 94 95 96 97 98 99 100 | 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); } | > | 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | 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 | } 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 | 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 | {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 | # 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' | > | 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 | # 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' |
︙ | ︙ | |||
714 715 716 717 718 719 720 721 722 723 724 725 726 727 | }} 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', | > | 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 | }} 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', |
︙ | ︙ | |||
740 741 742 743 744 745 746 747 748 749 750 751 752 753 | } 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'; | > | 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 | } 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'; |
︙ | ︙ | |||
768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 | 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'; } db close sqlite3 db test.db set res [catch {db eval { INSERT INTO t1(b) VALUES('two'); }} msg] 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'; } db close sqlite3 db test.db set res [catch {db eval { INSERT INTO t1(b) VALUES('two'); }} 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'; | > > > | 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 | 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'; } db close sqlite3 db test.db set res [catch {db eval { INSERT INTO t1(b) VALUES('two'); }} msg] 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'; } db close sqlite3 db test.db set res [catch {db eval { INSERT INTO t1(b) VALUES('two'); }} 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'; |
︙ | ︙ | |||
827 828 829 830 831 832 833 834 835 836 837 838 839 840 | }} 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'; | > | 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 | }} 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 | 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 751 752 753 754 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 { catch { sqlite3 db test.db } catchsql { SELECT * FROM sqlite_master; } } {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 752 753 754 755 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 { catch { sqlite3 db test.db } catchsql { SELECT * FROM sqlite_master; } } {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 696 697 698 699 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 { catch { sqlite3 db test.db } catchsql { SELECT * FROM sqlite_master; } } {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 697 698 699 700 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 { catch { sqlite3 db test.db } catchsql { SELECT * FROM sqlite_master; } } {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 | 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) | > | 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 | 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) |
︙ | ︙ | |||
261 262 263 264 265 266 267 268 269 270 271 272 273 274 | 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) | > | 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 | 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 | 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); } | | | 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 | 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 | 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 { | > | 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | 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 { |
︙ | ︙ | |||
79 80 81 82 83 84 85 86 87 88 89 90 91 92 | } {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'); | > | 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 | } {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'); |
︙ | ︙ | |||
129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 | } {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 | > < < | 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 | } {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 | 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*' | > | 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 | 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*' |
︙ | ︙ | |||
401 402 403 404 405 406 407 408 409 410 411 412 413 414 | } 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 { | > | 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 | } 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 | 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} | > | 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | 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} |
︙ | ︙ | |||
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 | 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 | > > > | 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 | 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 | 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)'; | > | 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | 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)'; |
︙ | ︙ | |||
94 95 96 97 98 99 100 101 102 103 104 105 106 107 | 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] \ | > | 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 | 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] \ |
︙ | ︙ | |||
148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 | 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 | > | 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 | 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 | 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; } } | > | 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 | 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; } } |
︙ | ︙ | |||
335 336 337 338 339 340 341 342 343 344 345 346 347 348 | 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 | > | 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 | 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 |
︙ | ︙ | |||
388 389 390 391 392 393 394 395 396 397 398 399 400 401 | 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 { | > | 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 | 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 | } 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" } | > | 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | } 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" } |
︙ | ︙ | |||
96 97 98 99 100 101 102 103 104 105 106 107 108 109 | } 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" } | > | 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 | } 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" } |
︙ | ︙ | |||
141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 | } 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" } #-------------------------------------------------------------------------- # Test case 4.* # # Test that the integrity-check works if there are "notindexed" columns. # 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'; } | > > | 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 | } 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" } #-------------------------------------------------------------------------- # Test case 4.* # # Test that the integrity-check works if there are "notindexed" columns. # 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'; } |
︙ | ︙ | |||
193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 | 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 | > | 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 | 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 | # 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 { | < | 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 | # 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 } | > | 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 | # 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 } |
︙ | ︙ |
Changes to test/misc1.test.
︙ | ︙ | |||
655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 | 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; DROP TABLE IF EXISTS t3; } {} # 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 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 | 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; DROP TABLE IF EXISTS t3; } {} # 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 | 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 | 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.
︙ | ︙ | |||
1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 | 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}} | > | 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 | 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}} |
︙ | ︙ | |||
1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 | 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; | > | 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948 | 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 | 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 { | > | 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 | 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 { |
︙ | ︙ | |||
121 122 123 124 125 126 127 128 129 130 131 132 133 134 | 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 { | > | 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 | 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 { |
︙ | ︙ | |||
224 225 226 227 228 229 230 231 232 233 234 235 236 237 | } {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; | > | 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 | } {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 | 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 | 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 | 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 | 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 | } 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 | } -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 | } } {} # 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 } | > | 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 | } } {} # 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 } |
︙ | ︙ |
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 | } {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 | } -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 | 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 | } {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 | 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 | 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 | } {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} |