Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Merge all recent trunk changes, and especially the SQLITE_TESTCTRL_INITMODE enhancement. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | ota-update |
Files: | files | file ages | folders |
SHA1: |
36436dde74ce2536a9a430b445821649 |
User & Date: | drh 2015-01-30 16:36:17.286 |
Context
2015-01-30
| ||
21:00 | Merge the SQLITE_TESTCTRL_IMPOSTER changes from trunk. (check-in: 3ed6eb2fab user: drh tags: ota-update) | |
16:36 | Merge all recent trunk changes, and especially the SQLITE_TESTCTRL_INITMODE enhancement. (check-in: 36436dde74 user: drh tags: ota-update) | |
15:52 | Added SQLITE_TESTCTRL_INITMODE for improved testability. (check-in: 98e029134d user: drh tags: trunk) | |
2015-01-28
| ||
20:37 | Add missing VdbeCoverage() macros to the sqlite3_index_writer() implementation. (check-in: 6f8cda26e9 user: drh tags: ota-update) | |
Changes
Changes to Makefile.msc.
︙ | ︙ | |||
710 711 712 713 714 715 716 | LIBRESOBJS = sqlite3res.lo !ELSE LIBRESOBJS = !ENDIF # All of the source code files. # | | | 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 | LIBRESOBJS = sqlite3res.lo !ELSE LIBRESOBJS = !ENDIF # All of the source code files. # SRC1 = \ $(TOP)\src\alter.c \ $(TOP)\src\analyze.c \ $(TOP)\src\attach.c \ $(TOP)\src\auth.c \ $(TOP)\src\backup.c \ $(TOP)\src\bitvec.c \ $(TOP)\src\btmutex.c \ |
︙ | ︙ | |||
760 761 762 763 764 765 766 | $(TOP)\src\notify.c \ $(TOP)\src\os.c \ $(TOP)\src\os.h \ $(TOP)\src\os_common.h \ $(TOP)\src\os_setup.h \ $(TOP)\src\os_unix.c \ $(TOP)\src\os_win.c \ | | > | 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 | $(TOP)\src\notify.c \ $(TOP)\src\os.c \ $(TOP)\src\os.h \ $(TOP)\src\os_common.h \ $(TOP)\src\os_setup.h \ $(TOP)\src\os_unix.c \ $(TOP)\src\os_win.c \ $(TOP)\src\os_win.h SRC2 = \ $(TOP)\src\pager.c \ $(TOP)\src\pager.h \ $(TOP)\src\parse.y \ $(TOP)\src\pcache.c \ $(TOP)\src\pcache.h \ $(TOP)\src\pcache1.c \ $(TOP)\src\pragma.c \ |
︙ | ︙ | |||
807 808 809 810 811 812 813 | $(TOP)\src\wal.h \ $(TOP)\src\walker.c \ $(TOP)\src\where.c \ $(TOP)\src\whereInt.h # Source code for extensions # | | | < | | < | < | > > > > | 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 | $(TOP)\src\wal.h \ $(TOP)\src\walker.c \ $(TOP)\src\where.c \ $(TOP)\src\whereInt.h # Source code for extensions # SRC3 = \ $(TOP)\ext\fts1\fts1.c \ $(TOP)\ext\fts1\fts1.h \ $(TOP)\ext\fts1\fts1_hash.c \ $(TOP)\ext\fts1\fts1_hash.h \ $(TOP)\ext\fts1\fts1_porter.c \ $(TOP)\ext\fts1\fts1_tokenizer.h \ $(TOP)\ext\fts1\fts1_tokenizer1.c \ $(TOP)\ext\fts2\fts2.c \ $(TOP)\ext\fts2\fts2.h \ $(TOP)\ext\fts2\fts2_hash.c \ $(TOP)\ext\fts2\fts2_hash.h \ $(TOP)\ext\fts2\fts2_icu.c \ $(TOP)\ext\fts2\fts2_porter.c \ $(TOP)\ext\fts2\fts2_tokenizer.h \ $(TOP)\ext\fts2\fts2_tokenizer.c \ $(TOP)\ext\fts2\fts2_tokenizer1.c SRC4 = \ $(TOP)\ext\fts3\fts3.c \ $(TOP)\ext\fts3\fts3.h \ $(TOP)\ext\fts3\fts3Int.h \ $(TOP)\ext\fts3\fts3_aux.c \ $(TOP)\ext\fts3\fts3_expr.c \ $(TOP)\ext\fts3\fts3_hash.c \ $(TOP)\ext\fts3\fts3_hash.h \ $(TOP)\ext\fts3\fts3_icu.c \ $(TOP)\ext\fts3\fts3_porter.c \ $(TOP)\ext\fts3\fts3_snippet.c \ $(TOP)\ext\fts3\fts3_tokenizer.h \ $(TOP)\ext\fts3\fts3_tokenizer.c \ $(TOP)\ext\fts3\fts3_tokenizer1.c \ $(TOP)\ext\fts3\fts3_tokenize_vtab.c \ $(TOP)\ext\fts3\fts3_unicode.c \ $(TOP)\ext\fts3\fts3_unicode2.c \ $(TOP)\ext\fts3\fts3_write.c \ $(TOP)\ext\icu\sqliteicu.h \ $(TOP)\ext\icu\icu.c \ $(TOP)\ext\rtree\rtree.h \ $(TOP)\ext\rtree\rtree.c # Generated source code files # SRC5 = \ keywordhash.h \ opcodes.c \ opcodes.h \ parse.c \ parse.h \ sqlite3.h # All source code files. # SRC = $(SRC1) $(SRC2) $(SRC3) $(SRC4) $(SRC5) # Source code to the test files. # TESTSRC = \ $(TOP)\src\test1.c \ $(TOP)\src\test2.c \ $(TOP)\src\test3.c \ $(TOP)\src\test4.c \ |
︙ | ︙ | |||
1048 1049 1050 1051 1052 1053 1054 | # build on the target system. Some of the C source code and header # files are automatically generated. This target takes care of # all that automatic generation. # .target_source: $(SRC) $(TOP)\tool\vdbe-compress.tcl -rmdir /S/Q tsrc -mkdir tsrc | | > > > > | 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 | # build on the target system. Some of the C source code and header # files are automatically generated. This target takes care of # all that automatic generation. # .target_source: $(SRC) $(TOP)\tool\vdbe-compress.tcl -rmdir /S/Q tsrc -mkdir tsrc for %i in ($(SRC1)) do copy /Y %i tsrc for %i in ($(SRC2)) do copy /Y %i tsrc for %i in ($(SRC3)) do copy /Y %i tsrc for %i in ($(SRC4)) do copy /Y %i tsrc for %i in ($(SRC5)) do copy /Y %i tsrc del /Q tsrc\sqlite.h.in tsrc\parse.y $(TCLSH_CMD) $(TOP)\tool\vdbe-compress.tcl $(OPTS) < tsrc\vdbe.c > vdbe.new move vdbe.new tsrc\vdbe.c echo > .target_source sqlite3.c: .target_source $(TOP)\tool\mksqlite3c.tcl $(TCLSH_CMD) $(TOP)\tool\mksqlite3c.tcl $(MKSQLITE3C_ARGS) |
︙ | ︙ |
Changes to ext/fts3/fts3.c.
︙ | ︙ | |||
3160 3161 3162 3163 3164 3165 3166 | /* Compile a SELECT statement for this cursor. For a full-table-scan, the ** statement loops through all rows of the %_content table. For a ** full-text query or docid lookup, the statement retrieves a single ** row by docid. */ if( eSearch==FTS3_FULLSCAN_SEARCH ){ | > | > > > > > | | | > | 3160 3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177 3178 3179 3180 3181 3182 3183 3184 | /* Compile a SELECT statement for this cursor. For a full-table-scan, the ** statement loops through all rows of the %_content table. For a ** full-text query or docid lookup, the statement retrieves a single ** row by docid. */ if( eSearch==FTS3_FULLSCAN_SEARCH ){ if( pDocidGe || pDocidLe ){ zSql = sqlite3_mprintf( "SELECT %s WHERE rowid BETWEEN %lld AND %lld ORDER BY rowid %s", p->zReadExprlist, pCsr->iMinDocid, pCsr->iMaxDocid, (pCsr->bDesc ? "DESC" : "ASC") ); }else{ zSql = sqlite3_mprintf("SELECT %s ORDER BY rowid %s", p->zReadExprlist, (pCsr->bDesc ? "DESC" : "ASC") ); } if( zSql ){ rc = sqlite3_prepare_v2(p->db, zSql, -1, &pCsr->pStmt, 0); sqlite3_free(zSql); }else{ rc = SQLITE_NOMEM; } }else if( eSearch==FTS3_DOCID_SEARCH ){ |
︙ | ︙ |
Changes to ext/ota/ota2.test.
︙ | ︙ | |||
27 28 29 30 31 32 33 | do_execsql_test 1.2 { PRAGMA pager_ota_mode = 1; INSERT INTO t1 VALUES(3, 4); INSERT INTO t1 VALUES(5, 6); SELECT * FROM t1; } {1 2 3 4 5 6} | | | 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | do_execsql_test 1.2 { PRAGMA pager_ota_mode = 1; INSERT INTO t1 VALUES(3, 4); INSERT INTO t1 VALUES(5, 6); SELECT * FROM t1; } {1 2 3 4 5 6} do_test 1.3 { lsort [glob test.db*] } {test.db test.db-oal} do_test 1.4 { sqlite3 db2 test.db db2 eval { SELECT * FROM t1 } } {1 2} do_test 1.5 { |
︙ | ︙ | |||
68 69 70 71 72 73 74 | } {1 2} do_test 1.10 { execsql { COMMIT; SELECT * FROM t1 } db2 } {1 2 3 4 5 6 7 8} finish_test | < | 68 69 70 71 72 73 74 | } {1 2} do_test 1.10 { execsql { COMMIT; SELECT * FROM t1 } db2 } {1 2 3 4 5 6 7 8} finish_test |
Changes to src/main.c.
︙ | ︙ | |||
1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 | if( zDb && zDb[0] ){ iDb = sqlite3FindDbName(db, zDb); } if( iDb<0 ){ rc = SQLITE_ERROR; sqlite3ErrorWithMsg(db, SQLITE_ERROR, "unknown database: %s", zDb); }else{ rc = sqlite3Checkpoint(db, iDb, eMode, pnLog, pnCkpt); sqlite3Error(db, rc); } rc = sqlite3ApiExit(db, rc); sqlite3_mutex_leave(db->mutex); return rc; #endif | > | 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 | if( zDb && zDb[0] ){ iDb = sqlite3FindDbName(db, zDb); } if( iDb<0 ){ rc = SQLITE_ERROR; sqlite3ErrorWithMsg(db, SQLITE_ERROR, "unknown database: %s", zDb); }else{ db->busyHandler.nBusy = 0; rc = sqlite3Checkpoint(db, iDb, eMode, pnLog, pnCkpt); sqlite3Error(db, rc); } rc = sqlite3ApiExit(db, rc); sqlite3_mutex_leave(db->mutex); return rc; #endif |
︙ | ︙ | |||
3620 3621 3622 3623 3624 3625 3626 3627 3628 3629 3630 3631 3632 3633 | ** 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; } /* | > > > > > > > > > > > > | 3621 3622 3623 3624 3625 3626 3627 3628 3629 3630 3631 3632 3633 3634 3635 3636 3637 3638 3639 3640 3641 3642 3643 3644 3645 3646 | ** 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.
︙ | ︙ | |||
6261 6262 6263 6264 6265 6266 6267 | #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 | > | | 6261 6262 6263 6264 6265 6266 6267 6268 6269 6270 6271 6272 6273 6274 6275 6276 | #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 |
︙ | ︙ |
Changes to src/wal.c.
︙ | ︙ | |||
1926 1927 1928 1929 1930 1931 1932 | if( rc==SQLITE_OK && eMode!=SQLITE_CHECKPOINT_PASSIVE ){ assert( pWal->writeLock ); if( sC.pInfo->nBackfill<pWal->hdr.mxFrame ){ rc = SQLITE_BUSY; }else if( eMode>=SQLITE_CHECKPOINT_RESTART ){ u32 salt1; sqlite3_randomness(4, &salt1); | | | 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940 | if( rc==SQLITE_OK && eMode!=SQLITE_CHECKPOINT_PASSIVE ){ assert( pWal->writeLock ); if( sC.pInfo->nBackfill<pWal->hdr.mxFrame ){ rc = SQLITE_BUSY; }else if( eMode>=SQLITE_CHECKPOINT_RESTART ){ u32 salt1; sqlite3_randomness(4, &salt1); assert( sC.pInfo->nBackfill==pWal->hdr.mxFrame ); rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(1), WAL_NREADER-1); if( rc==SQLITE_OK ){ if( eMode==SQLITE_CHECKPOINT_TRUNCATE ){ /* IMPLEMENTATION-OF: R-44699-57140 This mode works the same way as ** SQLITE_CHECKPOINT_RESTART with the addition that it also ** truncates the log file to zero bytes just prior to a ** successful return. |
︙ | ︙ |
Changes to test/fts3query.test.
︙ | ︙ | |||
204 205 206 207 208 209 210 | 6 "SELECT snippet(t3, 'XXX', 'YYY', 'ZZZ', 0) FROM t3 WHERE t3 MATCH 'gestures'" {{no XXXgesturesYYY}} 7 "SELECT snippet(t3, 'XXX', 'YYY', 'ZZZ', 1, 5) FROM t3 WHERE t3 MATCH 'gestures'" {{ZZZthe hand XXXgesturesYYY (called beatsZZZ}} } | > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 | 6 "SELECT snippet(t3, 'XXX', 'YYY', 'ZZZ', 0) FROM t3 WHERE t3 MATCH 'gestures'" {{no XXXgesturesYYY}} 7 "SELECT snippet(t3, 'XXX', 'YYY', 'ZZZ', 1, 5) FROM t3 WHERE t3 MATCH 'gestures'" {{ZZZthe hand XXXgesturesYYY (called beatsZZZ}} } # Test some range queries on the rowid field. # do_execsql_test 7.1 { CREATE VIRTUAL TABLE ft4 USING fts4(x); CREATE TABLE t4(x); } set SMALLINT -9223372036854775808 set LARGEINT 9223372036854775807 do_test 7.2 { db transaction { foreach {iFirst nEntry} [subst { 0 100 $SMALLINT 100 [expr $LARGEINT - 99] 100 }] { for {set i 0} {$i < $nEntry} {incr i} { set iRowid [expr $i + $iFirst] execsql { INSERT INTO ft4(rowid, x) VALUES($iRowid, 'x y z'); INSERT INTO t4(rowid, x) VALUES($iRowid, 'x y z'); } } } } } {} foreach {tn iFirst iLast} [subst { 1 5 10 2 $SMALLINT [expr $SMALLINT+5] 3 $SMALLINT [expr $SMALLINT+50] 4 [expr $LARGEINT-5] $LARGEINT 5 $LARGEINT $LARGEINT 6 $SMALLINT $LARGEINT 7 $SMALLINT $SMALLINT 8 $LARGEINT $SMALLINT }] { set res [db eval { SELECT rowid FROM t4 WHERE rowid BETWEEN $iFirst AND $iLast } ] do_execsql_test 7.2.$tn.1.[llength $res] { SELECT rowid FROM ft4 WHERE rowid BETWEEN $iFirst AND $iLast } $res do_execsql_test 7.2.$tn.2.[llength $res] { SELECT rowid FROM ft4 WHERE rowid BETWEEN $iFirst AND $iLast ORDER BY rowid DESC } [lsort -decr -integer $res] } foreach ii [db eval {SELECT rowid FROM t4}] { set res1 [db eval {SELECT rowid FROM t4 WHERE rowid > $ii}] set res2 [db eval {SELECT rowid FROM t4 WHERE rowid < $ii}] do_execsql_test 7.3.$ii.1 { SELECT rowid FROM ft4 WHERE rowid > $ii } $res1 do_execsql_test 7.3.$ii.2 { SELECT rowid FROM ft4 WHERE rowid < $ii } $res2 do_execsql_test 7.3.$ii.3 { SELECT rowid FROM ft4 WHERE rowid > $ii ORDER BY rowid DESC } [lsort -integer -decr $res1] do_execsql_test 7.3.$ii.4 { SELECT rowid FROM ft4 WHERE rowid < $ii ORDER BY rowid DESC } [lsort -integer -decr $res2] } finish_test |
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 |
Changes to test/wal5.test.
︙ | ︙ | |||
386 387 388 389 390 391 392 393 394 395 396 | do_test 4.$tn.5 { sql2 { INSERT INTO t1 VALUES('a', 'b') } file size test.db-wal } [wal_file_size 2 1024] } } finish_test | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 | do_test 4.$tn.5 { sql2 { INSERT INTO t1 VALUES('a', 'b') } file size test.db-wal } [wal_file_size 2 1024] } # Test that FULL, RESTART and TRUNCATE callbacks block on other clients # and truncate the wal file as required even if the entire wal file has # already been checkpointed when they are invoked. # do_multiclient_test tn { code1 $do_wal_checkpoint code2 $do_wal_checkpoint code3 $do_wal_checkpoint do_test 5.$tn.1 { sql1 { PRAGMA page_size = 1024; PRAGMA auto_vacuum = 0; PRAGMA journal_mode = WAL; PRAGMA synchronous = normal; CREATE TABLE t1(x, y); CREATE INDEX i1 ON t1(x, y); INSERT INTO t1 VALUES(1, 2); INSERT INTO t1 VALUES(3, 4); INSERT INTO t1 VALUES(5, 6); } file size test.db-wal } [wal_file_size 10 1024] do_test 5.$tn.2 { sql2 { BEGIN; SELECT * FROM t1 } } {1 2 3 4 5 6} do_test 5.$tn.3 { do_wal_checkpoint db -mode passive } {0 10 10} do_test 5.$tn.4 { sql3 { BEGIN; INSERT INTO t1 VALUES(7, 8); } } {} do_test 5.$tn.5 { do_wal_checkpoint db -mode passive } {0 10 10} do_test 5.$tn.6 { do_wal_checkpoint db -mode full } {1 10 10} do_test 5.$tn.7 { sql3 { ROLLBACK } } {} do_test 5.$tn.8 { do_wal_checkpoint db -mode full } {0 10 10} do_test 5.$tn.9 { do_wal_checkpoint db -mode truncate } {1 10 10} do_test 5.$tn.10 { file size test.db-wal } [wal_file_size 10 1024] proc xBusyHandler {n} { sql2 { COMMIT } ; return 0 } db busy xBusyHandler do_test 5.$tn.11 { do_wal_checkpoint db -mode truncate } {0 0 0} do_test 5.$tn.12 { file size test.db-wal } 0 do_test 5.$tn.13 { sql1 { INSERT INTO t1 VALUES(7, 8); INSERT INTO t1 VALUES(9, 10); SELECT * FROM t1; } } {1 2 3 4 5 6 7 8 9 10} do_test 5.$tn.14 { sql2 { BEGIN; SELECT * FROM t1 } } {1 2 3 4 5 6 7 8 9 10} proc xBusyHandler {n} { return 1 } do_test 5.$tn.15 { do_wal_checkpoint db -mode truncate } {1 4 4} do_test 5.$tn.16 { file size test.db-wal } [wal_file_size 4 1024] do_test 5.$tn.17 { do_wal_checkpoint db -mode restart } {1 4 4} proc xBusyHandler {n} { sql2 { COMMIT } ; return 0 } db busy xBusyHandler do_test 5.$tn.18 { do_wal_checkpoint db -mode restart } {0 4 4} do_test 5.$tn.19 { file size test.db-wal } [wal_file_size 4 1024] do_test 5.$tn.20 { do_wal_checkpoint db -mode truncate } {0 0 0} do_test 5.$tn.21 { file size test.db-wal } 0 } } finish_test |