Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Changes In Branch initmode-testctrl Excluding Merge-Ins
This is equivalent to a diff from 85dc12625d to 3a6e2afe40
2015-01-30
| ||
15:52 | Added SQLITE_TESTCTRL_INITMODE for improved testability. (check-in: 98e029134d user: drh tags: trunk) | |
15:40 | Add a few simple test cases for SQLITE_TESTCTRL_INITMODE - cases which also test PRAGMA integrity_check. (Closed-Leaf check-in: 3a6e2afe40 user: drh tags: initmode-testctrl) | |
2015-01-29
| ||
18:38 | Split up the SRC variable in Makefile.msc to avoid over-long cmd.exe commands when TOP is set to a long pathname. (check-in: 7d70ac65c1 user: drh tags: trunk) | |
17:54 | Add the INITMODE test-control. (check-in: 5940af8e78 user: drh tags: initmode-testctrl) | |
11:52 | Optimize range constraints on the rowid column of fts3/4 tables even if there is no MATCH clause in the query. (check-in: 85dc12625d user: dan tags: trunk) | |
2015-01-27
| ||
21:24 | Fix harmless compiler warnings. (check-in: e7d2ec048c user: mistachkin tags: trunk) | |
Changes to src/main.c.
︙ | ︙ | |||
3593 3594 3595 3596 3597 3598 3599 3600 3601 3602 3603 3604 3605 3606 | ** Return SQLITE_OK if SQLite has been initialized and SQLITE_ERROR if ** not. */ case SQLITE_TESTCTRL_ISINIT: { if( sqlite3GlobalConfig.isInit==0 ) rc = SQLITE_ERROR; break; } } va_end(ap); #endif /* SQLITE_OMIT_BUILTIN_TEST */ return rc; } /* | > > > > > > > > > > > > | 3593 3594 3595 3596 3597 3598 3599 3600 3601 3602 3603 3604 3605 3606 3607 3608 3609 3610 3611 3612 3613 3614 3615 3616 3617 3618 | ** Return SQLITE_OK if SQLite has been initialized and SQLITE_ERROR if ** not. */ case SQLITE_TESTCTRL_ISINIT: { if( sqlite3GlobalConfig.isInit==0 ) rc = SQLITE_ERROR; break; } /* sqlite3_test_control(SQLITE_TESTCTRL_INITMODE, db, busy, iDb, newTnum); ** ** Set the db->init.busy, db->init.iDb, and db->init.tnum fields. */ case SQLITE_TESTCTRL_INITMODE: { sqlite3 *db = va_arg(ap, sqlite3*); db->init.busy = va_arg(ap,int); db->init.iDb = va_arg(ap,int); db->init.newTnum = va_arg(ap,int); break; } } va_end(ap); #endif /* SQLITE_OMIT_BUILTIN_TEST */ return rc; } /* |
︙ | ︙ |
Changes to src/shell.c.
︙ | ︙ | |||
3532 3533 3534 3535 3536 3537 3538 3539 3540 3541 3542 3543 3544 3545 | { "always", SQLITE_TESTCTRL_ALWAYS }, { "reserve", SQLITE_TESTCTRL_RESERVE }, { "optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS }, { "iskeyword", SQLITE_TESTCTRL_ISKEYWORD }, { "scratchmalloc", SQLITE_TESTCTRL_SCRATCHMALLOC }, { "byteorder", SQLITE_TESTCTRL_BYTEORDER }, { "never_corrupt", SQLITE_TESTCTRL_NEVER_CORRUPT }, }; int testctrl = -1; int rc = 0; int i, n; open_db(p, 0); /* convert testctrl text option to value. allow any unique prefix | > | 3532 3533 3534 3535 3536 3537 3538 3539 3540 3541 3542 3543 3544 3545 3546 | { "always", SQLITE_TESTCTRL_ALWAYS }, { "reserve", SQLITE_TESTCTRL_RESERVE }, { "optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS }, { "iskeyword", SQLITE_TESTCTRL_ISKEYWORD }, { "scratchmalloc", SQLITE_TESTCTRL_SCRATCHMALLOC }, { "byteorder", SQLITE_TESTCTRL_BYTEORDER }, { "never_corrupt", SQLITE_TESTCTRL_NEVER_CORRUPT }, { "initmode", SQLITE_TESTCTRL_INITMODE }, }; int testctrl = -1; int rc = 0; int i, n; open_db(p, 0); /* convert testctrl text option to value. allow any unique prefix |
︙ | ︙ | |||
3623 3624 3625 3626 3627 3628 3629 3630 3631 3632 3633 3634 3635 3636 | fprintf(p->out, "%d (0x%08x)\n", rc, rc); } else { fprintf(stderr,"Error: testctrl %s takes a single char * option\n", azArg[1]); } break; #endif case SQLITE_TESTCTRL_BITVEC_TEST: case SQLITE_TESTCTRL_FAULT_INSTALL: case SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS: case SQLITE_TESTCTRL_SCRATCHMALLOC: default: fprintf(stderr,"Error: CLI support for testctrl %s not implemented\n", | > > > > > > > > > > > > | 3624 3625 3626 3627 3628 3629 3630 3631 3632 3633 3634 3635 3636 3637 3638 3639 3640 3641 3642 3643 3644 3645 3646 3647 3648 3649 | fprintf(p->out, "%d (0x%08x)\n", rc, rc); } else { fprintf(stderr,"Error: testctrl %s takes a single char * option\n", azArg[1]); } break; #endif case SQLITE_TESTCTRL_INITMODE: if( nArg==5 ){ rc = sqlite3_test_control(testctrl, p->db, integerValue(azArg[2]), integerValue(azArg[3]), integerValue(azArg[4])); }else{ fprintf(stderr,"Usage: .testctrl initmode fBusy iDb newTnum\n"); rc = 1; } break; case SQLITE_TESTCTRL_BITVEC_TEST: case SQLITE_TESTCTRL_FAULT_INSTALL: case SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS: case SQLITE_TESTCTRL_SCRATCHMALLOC: default: fprintf(stderr,"Error: CLI support for testctrl %s not implemented\n", |
︙ | ︙ |
Changes to src/sqlite.h.in.
︙ | ︙ | |||
6256 6257 6258 6259 6260 6261 6262 | #define SQLITE_TESTCTRL_LOCALTIME_FAULT 18 #define SQLITE_TESTCTRL_EXPLAIN_STMT 19 /* NOT USED */ #define SQLITE_TESTCTRL_NEVER_CORRUPT 20 #define SQLITE_TESTCTRL_VDBE_COVERAGE 21 #define SQLITE_TESTCTRL_BYTEORDER 22 #define SQLITE_TESTCTRL_ISINIT 23 #define SQLITE_TESTCTRL_SORTER_MMAP 24 | > | | 6256 6257 6258 6259 6260 6261 6262 6263 6264 6265 6266 6267 6268 6269 6270 6271 | #define SQLITE_TESTCTRL_LOCALTIME_FAULT 18 #define SQLITE_TESTCTRL_EXPLAIN_STMT 19 /* NOT USED */ #define SQLITE_TESTCTRL_NEVER_CORRUPT 20 #define SQLITE_TESTCTRL_VDBE_COVERAGE 21 #define SQLITE_TESTCTRL_BYTEORDER 22 #define SQLITE_TESTCTRL_ISINIT 23 #define SQLITE_TESTCTRL_SORTER_MMAP 24 #define SQLITE_TESTCTRL_INITMODE 25 #define SQLITE_TESTCTRL_LAST 25 /* ** CAPI3REF: SQLite Runtime Status ** ** ^This interface is used to retrieve runtime status information ** about the performance of SQLite, and optionally to reset various ** highwater marks. ^The first argument is an integer code for |
︙ | ︙ |
Changes to src/test1.c.
︙ | ︙ | |||
5910 5911 5912 5913 5914 5915 5916 | Tcl_Obj *CONST objv[] ){ struct Verb { const char *zName; int i; } aVerb[] = { { "SQLITE_TESTCTRL_LOCALTIME_FAULT", SQLITE_TESTCTRL_LOCALTIME_FAULT }, | | > | 5910 5911 5912 5913 5914 5915 5916 5917 5918 5919 5920 5921 5922 5923 5924 5925 | Tcl_Obj *CONST objv[] ){ struct Verb { const char *zName; int i; } aVerb[] = { { "SQLITE_TESTCTRL_LOCALTIME_FAULT", SQLITE_TESTCTRL_LOCALTIME_FAULT }, { "SQLITE_TESTCTRL_SORTER_MMAP", SQLITE_TESTCTRL_SORTER_MMAP }, { "SQLITE_TESTCTRL_INITMODE", SQLITE_TESTCTRL_INITMODE }, }; int iVerb; int iFlag; int rc; if( objc<2 ){ Tcl_WrongNumArgs(interp, 1, objv, "VERB ARGS..."); |
︙ | ︙ | |||
5951 5952 5953 5954 5955 5956 5957 5958 5959 5960 5961 5962 5963 5964 | return TCL_ERROR; } if( getDbPointer(interp, Tcl_GetString(objv[2]), &db) ) return TCL_ERROR; if( Tcl_GetIntFromObj(interp, objv[3], &val) ) return TCL_ERROR; sqlite3_test_control(SQLITE_TESTCTRL_SORTER_MMAP, db, val); break; } } Tcl_ResetResult(interp); return TCL_OK; } #if SQLITE_OS_UNIX | > > > > > > > > > > > > > > > | 5952 5953 5954 5955 5956 5957 5958 5959 5960 5961 5962 5963 5964 5965 5966 5967 5968 5969 5970 5971 5972 5973 5974 5975 5976 5977 5978 5979 5980 | return TCL_ERROR; } if( getDbPointer(interp, Tcl_GetString(objv[2]), &db) ) return TCL_ERROR; if( Tcl_GetIntFromObj(interp, objv[3], &val) ) return TCL_ERROR; sqlite3_test_control(SQLITE_TESTCTRL_SORTER_MMAP, db, val); break; } case SQLITE_TESTCTRL_INITMODE: { int fBusy, iDb, newTnum; sqlite3 *db; if( objc!=6 ){ Tcl_WrongNumArgs(interp, 2, objv, "DB fBusy iDb newTnum"); return TCL_ERROR; } if( getDbPointer(interp, Tcl_GetString(objv[2]), &db) ) return TCL_ERROR; if( Tcl_GetIntFromObj(interp, objv[3], &fBusy) ) return TCL_ERROR; if( Tcl_GetIntFromObj(interp, objv[4], &iDb) ) return TCL_ERROR; if( Tcl_GetIntFromObj(interp, objv[5], &newTnum) ) return TCL_ERROR; sqlite3_test_control(SQLITE_TESTCTRL_INITMODE, db, fBusy, iDb, newTnum); break; } } Tcl_ResetResult(interp); return TCL_OK; } #if SQLITE_OS_UNIX |
︙ | ︙ |
Added test/initmode.test.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 | # 2015-01-30 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # # This file implements tests for SQLite library. # # The focus of this file is adding extra entries in the symbol table # using sqlite3_test_control(SQLITE_TESTCTRL_INITMODE) and verifying that # SQLite handles those as expected. # set testdir [file dirname $argv0] source $testdir/tester.tcl set testprefix initmode # Create a bunch of data to sort against # do_test initmode-1.0 { execsql { CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c, d NOT NULL); CREATE INDEX t1b ON t1(b); CREATE UNIQUE INDEX t1c ON t1(c); WITH RECURSIVE c(i) AS (VALUES(1) UNION ALL SELECT i+1 FROM c WHERE i<30) INSERT INTO t1(a,b,c,d) SELECT i,1000+i,2000+i,3000+i FROM c; } set t1_root [db one {SELECT rootpage FROM sqlite_master WHERE name='t1'}] set t1a_root [db one {SELECT rootpage FROM sqlite_master WHERE name='t1a'}] set t1b_root [db one {SELECT rootpage FROM sqlite_master WHERE name='t1b'}] # Create a shadow table that uses the same b-tree as t1 but which does # not have the indexes # sqlite3_test_control SQLITE_TESTCTRL_INITMODE db 1 0 $t1_root db eval {CREATE TABLE xt1(a,b,c,d)} sqlite3_test_control SQLITE_TESTCTRL_INITMODE db 0 0 0 # Create triggers to record changes to xt1. # db eval { CREATE TEMP TABLE chnglog(desc TEXT); CREATE TEMP TRIGGER xt1_del AFTER DELETE ON xt1 BEGIN INSERT INTO chnglog VALUES( printf('DELETE t1: rowid=%d, a=%s, b=%s, c=%s, d=%s', old.rowid, quote(old.a), quote(old.b), quote(old.c), quote(old.d))); END; CREATE TEMP TRIGGER xt1_ins AFTER INSERT ON xt1 BEGIN INSERT INTO chnglog VALUES( printf('INSERT t1: rowid=%d, a=%s, b=%s, c=%s, d=%s', new.rowid, quote(new.a), quote(new.b), quote(new.c), quote(new.d))); END; } } {} # The xt1 table has separate xt1.rowid and xt1.a columns. The xt1.rowid # column corresponds to t1.rowid and t1.a, but the xt1.a column is always # NULL # do_execsql_test initmode-1.1 { SELECT rowid FROM xt1 WHERE a IS NOT NULL; } {} do_execsql_test initmode-1.2 { SELECT a,b,c,d FROM t1 EXCEPT SELECT rowid,b,c,d FROM xt1; SELECT rowid,b,c,d FROM xt1 EXCEPT SELECT a,b,c,d FROM t1; } {} # Make changes via the xt1 shadow table. This will not update the # indexes on t1 nor check the uniqueness constraint on t1.c nor check # the NOT NULL constraint on t1.d, resulting in a logically inconsistent # database. # do_execsql_test initmode-1.3 { DELETE FROM xt1 WHERE rowid=5; INSERT INTO xt1(rowid,a,b,c,d) VALUES(99,'hello',1099,2022,NULL); SELECT * FROM chnglog ORDER BY rowid; } [list \ {DELETE t1: rowid=5, a=NULL, b=1005, c=2005, d=3005} \ {INSERT t1: rowid=99, a='hello', b=1099, c=2022, d=NULL} \ ] do_execsql_test initmode-1.4a { PRAGMA integrity_check; } {/NULL value in t1.d/} do_execsql_test initmode-1.4b { PRAGMA integrity_check; } {/row # missing from index t1b/} do_execsql_test initmode-1.4c { PRAGMA integrity_check; } {/row # missing from index t1c/} finish_test |