Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Merge latest trunk changes into this branch. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | begin-concurrent-wal2 |
Files: | files | file ages | folders |
SHA3-256: |
b3a163b46cad19a2e6a90cdd5b4c2e94 |
User & Date: | dan 2018-12-18 17:32:08.747 |
Context
2018-12-27
| ||
17:11 | Merge latest wal2 changes with this branch. (check-in: ea96001e80 user: dan tags: begin-concurrent-wal2) | |
2018-12-18
| ||
18:01 | Merge the wal2 feature into this branch. (check-in: a2c618c0a4 user: dan tags: begin-concurrent-pnu-wal2) | |
17:32 | Merge latest trunk changes into this branch. (check-in: b3a163b46c user: dan tags: begin-concurrent-wal2) | |
16:24 | Add the ".integrity_check" command to tserver. (check-in: fa46fa3bfc user: dan tags: begin-concurrent-wal2) | |
2018-12-17
| ||
22:19 | Move variable declaration to address compilation issue (C89). (check-in: d64f248da3 user: mistachkin tags: trunk) | |
Changes
Changes to Makefile.in.
︙ | ︙ | |||
665 666 667 668 669 670 671 | $(LTLINK) -o $@ $(FUZZCHECK_OPT) $(FUZZCHECK_SRC) sqlite3.c $(TLIBS) ossshell$(TEXE): $(TOP)/test/ossfuzz.c $(TOP)/test/ossshell.c sqlite3.c sqlite3.h $(LTLINK) -o $@ $(FUZZCHECK_OPT) $(TOP)/test/ossshell.c \ $(TOP)/test/ossfuzz.c sqlite3.c $(TLIBS) sessionfuzz$(TEXE): $(TOP)/test/sessionfuzz.c sqlite3.c sqlite3.h | | > | | 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 | $(LTLINK) -o $@ $(FUZZCHECK_OPT) $(FUZZCHECK_SRC) sqlite3.c $(TLIBS) ossshell$(TEXE): $(TOP)/test/ossfuzz.c $(TOP)/test/ossshell.c sqlite3.c sqlite3.h $(LTLINK) -o $@ $(FUZZCHECK_OPT) $(TOP)/test/ossshell.c \ $(TOP)/test/ossfuzz.c sqlite3.c $(TLIBS) sessionfuzz$(TEXE): $(TOP)/test/sessionfuzz.c sqlite3.c sqlite3.h $(LTLINK) -o $@ $(TOP)/test/sessionfuzz.c $(TLIBS) dbfuzz$(TEXE): $(TOP)/test/dbfuzz.c sqlite3.c sqlite3.h $(LTLINK) -o $@ $(DBFUZZ_OPT) $(TOP)/test/dbfuzz.c sqlite3.c $(TLIBS) DBFUZZ2_OPTS = \ -DSQLITE_THREADSAFE=0 \ -DSQLITE_OMIT_LOAD_EXTENSION \ -DSQLITE_ENABLE_DESERIALIZE \ -DSQLITE_DEBUG \ -DSQLITE_ENABLE_DBSTAT_VTAB \ -DSQLITE_ENABLE_RTREE \ -DSQLITE_ENABLE_FTS4 \ -DSQLITE_EANBLE_FTS5 dbfuzz2: $(TOP)/test/dbfuzz2.c sqlite3.c sqlite3.h clang-6.0 $(OPT_FEATURE_FLAGS) $(OPTS) -I. -g -O0 \ -fsanitize=fuzzer,undefined,address -o dbfuzz2 \ $(DBFUZZ2_OPTS) $(TOP)/test/dbfuzz2.c sqlite3.c mkdir -p dbfuzz2-dir cp $(TOP)/test/dbfuzz2-seed* dbfuzz2-dir mptester$(TEXE): sqlite3.lo $(TOP)/mptest/mptest.c $(LTLINK) -o $@ -I. $(TOP)/mptest/mptest.c sqlite3.lo \ $(TLIBS) -rpath "$(libdir)" |
︙ | ︙ | |||
1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 | TESTFIXTURE_FLAGS += -DTCLSH_INIT_PROC=sqlite3TestInit TESTFIXTURE_FLAGS += -DSQLITE_SERVER=1 -DSQLITE_PRIVATE="" -DSQLITE_CORE TESTFIXTURE_FLAGS += -DBUILD_sqlite TESTFIXTURE_FLAGS += -DSQLITE_SERIES_CONSTRAINT_VERIFY=1 TESTFIXTURE_FLAGS += -DSQLITE_DEFAULT_PAGE_SIZE=1024 TESTFIXTURE_FLAGS += -DSQLITE_ENABLE_STMTVTAB TESTFIXTURE_FLAGS += -DSQLITE_ENABLE_DBPAGE_VTAB TESTFIXTURE_SRC0 = $(TESTSRC2) libsqlite3.la TESTFIXTURE_SRC1 = sqlite3.c TESTFIXTURE_SRC = $(TESTSRC) $(TOP)/src/tclsqlite.c TESTFIXTURE_SRC += $(TESTFIXTURE_SRC$(USE_AMALGAMATION)) testfixture$(TEXE): $(TESTFIXTURE_SRC) | > | 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 | TESTFIXTURE_FLAGS += -DTCLSH_INIT_PROC=sqlite3TestInit TESTFIXTURE_FLAGS += -DSQLITE_SERVER=1 -DSQLITE_PRIVATE="" -DSQLITE_CORE TESTFIXTURE_FLAGS += -DBUILD_sqlite TESTFIXTURE_FLAGS += -DSQLITE_SERIES_CONSTRAINT_VERIFY=1 TESTFIXTURE_FLAGS += -DSQLITE_DEFAULT_PAGE_SIZE=1024 TESTFIXTURE_FLAGS += -DSQLITE_ENABLE_STMTVTAB TESTFIXTURE_FLAGS += -DSQLITE_ENABLE_DBPAGE_VTAB TESTFIXTURE_FLAGS += -DSQLITE_ENABLE_DESERIALIZE TESTFIXTURE_SRC0 = $(TESTSRC2) libsqlite3.la TESTFIXTURE_SRC1 = sqlite3.c TESTFIXTURE_SRC = $(TESTSRC) $(TOP)/src/tclsqlite.c TESTFIXTURE_SRC += $(TESTFIXTURE_SRC$(USE_AMALGAMATION)) testfixture$(TEXE): $(TESTFIXTURE_SRC) |
︙ | ︙ | |||
1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 | sqlite3_checker$(TEXE): sqlite3_checker.c $(LTLINK) sqlite3_checker.c -o $@ $(LIBTCL) $(TLIBS) dbdump$(TEXE): $(TOP)/ext/misc/dbdump.c sqlite3.lo $(LTLINK) -DDBDUMP_STANDALONE -o $@ \ $(TOP)/ext/misc/dbdump.c sqlite3.lo $(TLIBS) showdb$(TEXE): $(TOP)/tool/showdb.c sqlite3.lo $(LTLINK) -o $@ $(TOP)/tool/showdb.c sqlite3.lo $(TLIBS) showstat4$(TEXE): $(TOP)/tool/showstat4.c sqlite3.lo $(LTLINK) -o $@ $(TOP)/tool/showstat4.c sqlite3.lo $(TLIBS) | > > > | 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 | sqlite3_checker$(TEXE): sqlite3_checker.c $(LTLINK) sqlite3_checker.c -o $@ $(LIBTCL) $(TLIBS) dbdump$(TEXE): $(TOP)/ext/misc/dbdump.c sqlite3.lo $(LTLINK) -DDBDUMP_STANDALONE -o $@ \ $(TOP)/ext/misc/dbdump.c sqlite3.lo $(TLIBS) dbtotxt$(TEXE): $(TOP)/tool/dbtotxt.c $(LTLINK)-o $@ $(TOP)/tool/dbtotxt.c showdb$(TEXE): $(TOP)/tool/showdb.c sqlite3.lo $(LTLINK) -o $@ $(TOP)/tool/showdb.c sqlite3.lo $(TLIBS) showstat4$(TEXE): $(TOP)/tool/showstat4.c sqlite3.lo $(LTLINK) -o $@ $(TOP)/tool/showstat4.c sqlite3.lo $(TLIBS) |
︙ | ︙ |
Changes to Makefile.msc.
︙ | ︙ | |||
2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 | TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_SERVER=1 -DSQLITE_PRIVATE="" TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_CORE $(NO_WARN) TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_SERIES_CONSTRAINT_VERIFY=1 TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_DEFAULT_PAGE_SIZE=1024 TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_ENABLE_STMTVTAB=1 TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_ENABLE_DBPAGE_VTAB=1 TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_ENABLE_JSON1=1 TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) $(TEST_CCONV_OPTS) TESTFIXTURE_SRC0 = $(TESTEXT) $(TESTSRC2) TESTFIXTURE_SRC1 = $(TESTEXT) $(SQLITE3C) !IF $(USE_AMALGAMATION)==0 TESTFIXTURE_SRC = $(TESTSRC) $(TOP)\src\tclsqlite.c $(TESTFIXTURE_SRC0) !ELSE | > | 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 | TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_SERVER=1 -DSQLITE_PRIVATE="" TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_CORE $(NO_WARN) TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_SERIES_CONSTRAINT_VERIFY=1 TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_DEFAULT_PAGE_SIZE=1024 TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_ENABLE_STMTVTAB=1 TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_ENABLE_DBPAGE_VTAB=1 TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_ENABLE_JSON1=1 TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_ENABLE_DESERIALIZE=1 TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) $(TEST_CCONV_OPTS) TESTFIXTURE_SRC0 = $(TESTEXT) $(TESTSRC2) TESTFIXTURE_SRC1 = $(TESTEXT) $(SQLITE3C) !IF $(USE_AMALGAMATION)==0 TESTFIXTURE_SRC = $(TESTSRC) $(TOP)\src\tclsqlite.c $(TESTFIXTURE_SRC0) !ELSE |
︙ | ︙ | |||
2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 | testloadext.lo: $(TOP)\src\test_loadext.c $(SQLITE3H) $(LTCOMPILE) $(NO_WARN) -c $(TOP)\src\test_loadext.c testloadext.dll: testloadext.lo $(LD) $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) /DLL /OUT:$@ testloadext.lo showdb.exe: $(TOP)\tool\showdb.c $(SQLITE3C) $(SQLITE3H) $(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \ $(TOP)\tool\showdb.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS) showstat4.exe: $(TOP)\tool\showstat4.c $(SQLITE3C) $(SQLITE3H) $(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \ $(TOP)\tool\showstat4.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS) | > > > | 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 | testloadext.lo: $(TOP)\src\test_loadext.c $(SQLITE3H) $(LTCOMPILE) $(NO_WARN) -c $(TOP)\src\test_loadext.c testloadext.dll: testloadext.lo $(LD) $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) /DLL /OUT:$@ testloadext.lo dbtotxt.exe: $(TOP)\tool\dbtotxt.c $(LTLINK) $(NO_WARN) $(TOP)\tool\dbtotxt.c /link $(LDFLAGS) $(LTLINKOPTS) showdb.exe: $(TOP)\tool\showdb.c $(SQLITE3C) $(SQLITE3H) $(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \ $(TOP)\tool\showdb.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS) showstat4.exe: $(TOP)\tool\showstat4.c $(SQLITE3C) $(SQLITE3H) $(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \ $(TOP)\tool\showstat4.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS) |
︙ | ︙ |
Changes to ext/fts3/fts3_unicode2.c.
︙ | ︙ | |||
174 175 176 177 178 179 180 181 | 61726, 61784, 61800, 61816, 61836, 61880, 61896, 61914, 61948, 61998, 62062, 62122, 62154, 62184, 62200, 62218, 62252, 62302, 62364, 62410, 62442, 62478, 62536, 62554, 62584, 62604, 62640, 62648, 62656, 62664, 62730, 62766, 62830, 62890, 62924, 62974, 63032, 63050, 63082, 63118, 63182, 63242, 63274, 63310, 63368, 63390, }; char aChar[] = { | > | < | | | | | | | | > | | < | | | | | | | | > | 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 | 61726, 61784, 61800, 61816, 61836, 61880, 61896, 61914, 61948, 61998, 62062, 62122, 62154, 62184, 62200, 62218, 62252, 62302, 62364, 62410, 62442, 62478, 62536, 62554, 62584, 62604, 62640, 62648, 62656, 62664, 62730, 62766, 62830, 62890, 62924, 62974, 63032, 63050, 63082, 63118, 63182, 63242, 63274, 63310, 63368, 63390, }; #define HIBIT ((char)0x80) char aChar[] = { '\0', 'a', 'c', 'e', 'i', 'n', 'o', 'u', 'y', 'y', 'a', 'c', 'd', 'e', 'e', 'g', 'h', 'i', 'j', 'k', 'l', 'n', 'o', 'r', 's', 't', 'u', 'u', 'w', 'y', 'z', 'o', 'u', 'a', 'i', 'o', 'u', 'u'|HIBIT, 'a'|HIBIT, 'g', 'k', 'o', 'o'|HIBIT, 'j', 'g', 'n', 'a'|HIBIT, 'a', 'e', 'i', 'o', 'r', 'u', 's', 't', 'h', 'a', 'e', 'o'|HIBIT, 'o', 'o'|HIBIT, 'y', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', 'a', 'b', 'c'|HIBIT, 'd', 'd', 'e'|HIBIT, 'e', 'e'|HIBIT, 'f', 'g', 'h', 'h', 'i', 'i'|HIBIT, 'k', 'l', 'l'|HIBIT, 'l', 'm', 'n', 'o'|HIBIT, 'p', 'r', 'r'|HIBIT, 'r', 's', 's'|HIBIT, 't', 'u', 'u'|HIBIT, 'v', 'w', 'w', 'x', 'y', 'z', 'h', 't', 'w', 'y', 'a', 'a'|HIBIT, 'a'|HIBIT, 'a'|HIBIT, 'e', 'e'|HIBIT, 'e'|HIBIT, 'i', 'o', 'o'|HIBIT, 'o'|HIBIT, 'o'|HIBIT, 'u', 'u'|HIBIT, 'u'|HIBIT, 'y', }; unsigned int key = (((unsigned int)c)<<3) | 0x00000007; int iRes = 0; int iHi = sizeof(aDia)/sizeof(aDia[0]) - 1; int iLo = 0; while( iHi>=iLo ){ |
︙ | ︙ |
Changes to ext/fts5/fts5.h.
︙ | ︙ | |||
410 411 412 413 414 415 416 | ** same token for inputs "first" and "1st". Say that token is in ** fact "first", so that when the user inserts the document "I won ** 1st place" entries are added to the index for tokens "i", "won", ** "first" and "place". If the user then queries for '1st + place', ** the tokenizer substitutes "first" for "1st" and the query works ** as expected. ** | | | | | | | 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 | ** same token for inputs "first" and "1st". Say that token is in ** fact "first", so that when the user inserts the document "I won ** 1st place" entries are added to the index for tokens "i", "won", ** "first" and "place". If the user then queries for '1st + place', ** the tokenizer substitutes "first" for "1st" and the query works ** as expected. ** ** <li> By querying the index for all synonyms of each query term ** separately. In this case, when tokenizing query text, the ** tokenizer may provide multiple synonyms for a single term ** within the document. FTS5 then queries the index for each ** synonym individually. For example, faced with the query: ** ** <codeblock> ** ... MATCH 'first place'</codeblock> ** ** the tokenizer offers both "1st" and "first" as synonyms for the ** first token in the MATCH query and FTS5 effectively runs a query ** similar to: |
︙ | ︙ | |||
438 439 440 441 442 443 444 | ** Using this method, when tokenizing document text, the tokenizer ** provides multiple synonyms for each token. So that when a ** document such as "I won first place" is tokenized, entries are ** added to the FTS index for "i", "won", "first", "1st" and ** "place". ** ** This way, even if the tokenizer does not provide synonyms | | | 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 | ** Using this method, when tokenizing document text, the tokenizer ** provides multiple synonyms for each token. So that when a ** document such as "I won first place" is tokenized, entries are ** added to the FTS index for "i", "won", "first", "1st" and ** "place". ** ** This way, even if the tokenizer does not provide synonyms ** when tokenizing query text (it should not - to do so would be ** inefficient), it doesn't matter if the user queries for ** 'first + place' or '1st + place', as there are entries in the ** FTS index corresponding to both forms of the first token. ** </ol> ** ** Whether it is parsing document or query text, any call to xToken that ** specifies a <i>tflags</i> argument with the FTS5_TOKEN_COLOCATED bit |
︙ | ︙ |
Changes to ext/fts5/fts5_unicode2.c.
︙ | ︙ | |||
43 44 45 46 47 48 49 50 | 61726, 61784, 61800, 61816, 61836, 61880, 61896, 61914, 61948, 61998, 62062, 62122, 62154, 62184, 62200, 62218, 62252, 62302, 62364, 62410, 62442, 62478, 62536, 62554, 62584, 62604, 62640, 62648, 62656, 62664, 62730, 62766, 62830, 62890, 62924, 62974, 63032, 63050, 63082, 63118, 63182, 63242, 63274, 63310, 63368, 63390, }; char aChar[] = { | > | < | | | | | | | | > | | < | | | | | | | | > | 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 | 61726, 61784, 61800, 61816, 61836, 61880, 61896, 61914, 61948, 61998, 62062, 62122, 62154, 62184, 62200, 62218, 62252, 62302, 62364, 62410, 62442, 62478, 62536, 62554, 62584, 62604, 62640, 62648, 62656, 62664, 62730, 62766, 62830, 62890, 62924, 62974, 63032, 63050, 63082, 63118, 63182, 63242, 63274, 63310, 63368, 63390, }; #define HIBIT ((char)0x80) char aChar[] = { '\0', 'a', 'c', 'e', 'i', 'n', 'o', 'u', 'y', 'y', 'a', 'c', 'd', 'e', 'e', 'g', 'h', 'i', 'j', 'k', 'l', 'n', 'o', 'r', 's', 't', 'u', 'u', 'w', 'y', 'z', 'o', 'u', 'a', 'i', 'o', 'u', 'u'|HIBIT, 'a'|HIBIT, 'g', 'k', 'o', 'o'|HIBIT, 'j', 'g', 'n', 'a'|HIBIT, 'a', 'e', 'i', 'o', 'r', 'u', 's', 't', 'h', 'a', 'e', 'o'|HIBIT, 'o', 'o'|HIBIT, 'y', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', 'a', 'b', 'c'|HIBIT, 'd', 'd', 'e'|HIBIT, 'e', 'e'|HIBIT, 'f', 'g', 'h', 'h', 'i', 'i'|HIBIT, 'k', 'l', 'l'|HIBIT, 'l', 'm', 'n', 'o'|HIBIT, 'p', 'r', 'r'|HIBIT, 'r', 's', 's'|HIBIT, 't', 'u', 'u'|HIBIT, 'v', 'w', 'w', 'x', 'y', 'z', 'h', 't', 'w', 'y', 'a', 'a'|HIBIT, 'a'|HIBIT, 'a'|HIBIT, 'e', 'e'|HIBIT, 'e'|HIBIT, 'i', 'o', 'o'|HIBIT, 'o'|HIBIT, 'o'|HIBIT, 'u', 'u'|HIBIT, 'u'|HIBIT, 'y', }; unsigned int key = (((unsigned int)c)<<3) | 0x00000007; int iRes = 0; int iHi = sizeof(aDia)/sizeof(aDia[0]) - 1; int iLo = 0; while( iHi>=iLo ){ |
︙ | ︙ |
Changes to ext/session/sqlite3session.c.
︙ | ︙ | |||
1157 1158 1159 1160 1161 1162 1163 | int op, /* One of SQLITE_UPDATE, INSERT, DELETE */ sqlite3_session *pSession, /* Session object pTab is attached to */ SessionTable *pTab /* Table that change applies to */ ){ int iHash; int bNull = 0; int rc = SQLITE_OK; | | | 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 | int op, /* One of SQLITE_UPDATE, INSERT, DELETE */ sqlite3_session *pSession, /* Session object pTab is attached to */ SessionTable *pTab /* Table that change applies to */ ){ int iHash; int bNull = 0; int rc = SQLITE_OK; SessionStat1Ctx stat1 = {{0,0,0,0,0},0}; if( pSession->rc ) return; /* Load table details if required */ if( sessionInitTable(pSession, pTab) ) return; /* Check the number of columns in this xPreUpdate call matches the |
︙ | ︙ |
Changes to main.mk.
︙ | ︙ | |||
977 978 979 980 981 982 983 984 985 986 987 988 989 990 | TEST_EXTENSION = $(SHPREFIX)testloadext.$(SO) $(TEST_EXTENSION): $(TOP)/src/test_loadext.c $(MKSHLIB) $(TOP)/src/test_loadext.c -o $(TEST_EXTENSION) extensiontest: testfixture$(EXE) $(TEST_EXTENSION) ./testfixture$(EXE) $(TOP)/test/loadext.test showdb$(EXE): $(TOP)/tool/showdb.c sqlite3.o $(TCC) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -o showdb$(EXE) \ $(TOP)/tool/showdb.c sqlite3.o $(THREADLIB) showstat4$(EXE): $(TOP)/tool/showstat4.c sqlite3.o $(TCC) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -o showstat4$(EXE) \ $(TOP)/tool/showstat4.c sqlite3.o $(THREADLIB) | > > > | 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 | TEST_EXTENSION = $(SHPREFIX)testloadext.$(SO) $(TEST_EXTENSION): $(TOP)/src/test_loadext.c $(MKSHLIB) $(TOP)/src/test_loadext.c -o $(TEST_EXTENSION) extensiontest: testfixture$(EXE) $(TEST_EXTENSION) ./testfixture$(EXE) $(TOP)/test/loadext.test dbtotxt$(EXE): $(TOP)/tool/dbtotxt.c $(TCC) -o dbtotxt$(EXE) $(TOP)/tool/dbtotxt.c showdb$(EXE): $(TOP)/tool/showdb.c sqlite3.o $(TCC) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -o showdb$(EXE) \ $(TOP)/tool/showdb.c sqlite3.o $(THREADLIB) showstat4$(EXE): $(TOP)/tool/showstat4.c sqlite3.o $(TCC) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -o showstat4$(EXE) \ $(TOP)/tool/showstat4.c sqlite3.o $(THREADLIB) |
︙ | ︙ |
Changes to src/btree.c.
︙ | ︙ | |||
889 890 891 892 893 894 895 | assert( 0==pCur->pKey ); assert( cursorHoldsMutex(pCur) ); if( pCur->curIntKey ){ /* Only the rowid is required for a table btree */ pCur->nKey = sqlite3BtreeIntegerKey(pCur); }else{ | | > > > > > | | 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 | assert( 0==pCur->pKey ); assert( cursorHoldsMutex(pCur) ); if( pCur->curIntKey ){ /* Only the rowid is required for a table btree */ pCur->nKey = sqlite3BtreeIntegerKey(pCur); }else{ /* For an index btree, save the complete key content. It is possible ** that the current key is corrupt. In that case, it is possible that ** the sqlite3VdbeRecordUnpack() function may overread the buffer by ** up to the size of 1 varint plus 1 8-byte value when the cursor ** position is restored. Hence the 17 bytes of padding allocated ** below. */ void *pKey; pCur->nKey = sqlite3BtreePayloadSize(pCur); pKey = sqlite3Malloc( pCur->nKey + 9 + 8 ); if( pKey ){ rc = sqlite3BtreePayload(pCur, 0, (int)pCur->nKey, pKey); if( rc==SQLITE_OK ){ pCur->pKey = pKey; }else{ sqlite3_free(pKey); } |
︙ | ︙ | |||
1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 | return; } iPtrmap = PTRMAP_PAGENO(pBt, key); rc = sqlite3PagerGet(pBt->pPager, iPtrmap, &pDbPage, 0); if( rc!=SQLITE_OK ){ *pRC = rc; return; } offset = PTRMAP_PTROFFSET(iPtrmap, key); if( offset<0 ){ *pRC = SQLITE_CORRUPT_BKPT; goto ptrmap_exit; } assert( offset <= (int)pBt->usableSize-5 ); | > > > > > > > | 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 | return; } iPtrmap = PTRMAP_PAGENO(pBt, key); rc = sqlite3PagerGet(pBt->pPager, iPtrmap, &pDbPage, 0); if( rc!=SQLITE_OK ){ *pRC = rc; return; } if( ((char*)sqlite3PagerGetExtra(pDbPage))[0]!=0 ){ /* The first byte of the extra data is the MemPage.isInit byte. ** If that byte is set, it means this page is also being used ** as a btree page. */ *pRC = SQLITE_CORRUPT_BKPT; goto ptrmap_exit; } offset = PTRMAP_PTROFFSET(iPtrmap, key); if( offset<0 ){ *pRC = SQLITE_CORRUPT_BKPT; goto ptrmap_exit; } assert( offset <= (int)pBt->usableSize-5 ); |
︙ | ︙ | |||
1593 1594 1595 1596 1597 1598 1599 | */ static void ptrmapPutOvflPtr(MemPage *pPage, u8 *pCell, int *pRC){ CellInfo info; if( *pRC ) return; assert( pCell!=0 ); pPage->xParseCell(pPage, pCell, &info); if( info.nLocal<info.nPayload ){ | > > > > > | | 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 | */ static void ptrmapPutOvflPtr(MemPage *pPage, u8 *pCell, int *pRC){ CellInfo info; if( *pRC ) return; assert( pCell!=0 ); pPage->xParseCell(pPage, pCell, &info); if( info.nLocal<info.nPayload ){ Pgno ovfl; if( SQLITE_WITHIN(pPage->aDataEnd, pCell, pCell+info.nLocal) ){ *pRC = SQLITE_CORRUPT_BKPT; return; } ovfl = get4byte(&pCell[info.nSize-4]); ptrmapPut(pPage->pBt, ovfl, PTRMAP_OVERFLOW1, pPage->pgno, pRC); } } #endif /* |
︙ | ︙ | |||
1648 1649 1650 1651 1652 1653 1654 | /* This block handles pages with two or fewer free blocks and nMaxFrag ** or fewer fragmented bytes. In this case it is faster to move the ** two (or one) blocks of cells using memmove() and add the required ** offsets to each pointer in the cell-pointer array than it is to ** reconstruct the entire page. */ if( (int)data[hdr+7]<=nMaxFrag ){ int iFree = get2byte(&data[hdr+1]); | < < < < > > | < < < | | | | | | | 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 | /* This block handles pages with two or fewer free blocks and nMaxFrag ** or fewer fragmented bytes. In this case it is faster to move the ** two (or one) blocks of cells using memmove() and add the required ** offsets to each pointer in the cell-pointer array than it is to ** reconstruct the entire page. */ if( (int)data[hdr+7]<=nMaxFrag ){ int iFree = get2byte(&data[hdr+1]); /* If the initial freeblock offset were out of bounds, that would ** have been detected by btreeInitPage() when it was computing the ** number of free bytes on the page. */ assert( iFree<=usableSize-4 ); if( iFree ){ int iFree2 = get2byte(&data[iFree]); if( iFree2>usableSize-4 ) return SQLITE_CORRUPT_PAGE(pPage); if( 0==iFree2 || (data[iFree2]==0 && data[iFree2+1]==0) ){ u8 *pEnd = &data[cellOffset + nCell*2]; u8 *pAddr; int sz2 = 0; int sz = get2byte(&data[iFree+2]); int top = get2byte(&data[hdr+5]); if( top>=iFree ){ return SQLITE_CORRUPT_PAGE(pPage); } if( iFree2 ){ if( iFree+sz>iFree2 ) return SQLITE_CORRUPT_PAGE(pPage); sz2 = get2byte(&data[iFree2+2]); if( iFree2+sz2 > usableSize ) return SQLITE_CORRUPT_PAGE(pPage); memmove(&data[iFree+sz+sz2], &data[iFree+sz], iFree2-(iFree+sz)); sz += sz2; } cbrk = top+sz; assert( cbrk+(iFree-top) <= usableSize ); memmove(&data[cbrk], &data[top], iFree-top); for(pAddr=&data[cellOffset]; pAddr<pEnd; pAddr+=2){ |
︙ | ︙ | |||
7212 7213 7214 7215 7216 7217 7218 7219 7220 7221 7222 7223 7224 7225 | i = get2byte(&aData[hdr+5]); memcpy(&pTmp[i], &aData[i], usableSize - i); pData = pEnd; for(i=0; i<nCell; i++){ u8 *pCell = apCell[i]; if( SQLITE_WITHIN(pCell,aData,pEnd) ){ pCell = &pTmp[pCell - aData]; } pData -= szCell[i]; put2byte(pCellptr, (pData - aData)); pCellptr += 2; if( pData < pCellptr ) return SQLITE_CORRUPT_BKPT; memcpy(pData, pCell, szCell[i]); | > | 7224 7225 7226 7227 7228 7229 7230 7231 7232 7233 7234 7235 7236 7237 7238 | i = get2byte(&aData[hdr+5]); memcpy(&pTmp[i], &aData[i], usableSize - i); pData = pEnd; for(i=0; i<nCell; i++){ u8 *pCell = apCell[i]; if( SQLITE_WITHIN(pCell,aData,pEnd) ){ if( ((uptr)(pCell+szCell[i]))>(uptr)pEnd ) return SQLITE_CORRUPT_BKPT; pCell = &pTmp[pCell - aData]; } pData -= szCell[i]; put2byte(pCellptr, (pData - aData)); pCellptr += 2; if( pData < pCellptr ) return SQLITE_CORRUPT_BKPT; memcpy(pData, pCell, szCell[i]); |
︙ | ︙ | |||
7506 7507 7508 7509 7510 7511 7512 | int rc; /* Return Code */ Pgno pgnoNew; /* Page number of pNew */ assert( sqlite3_mutex_held(pPage->pBt->mutex) ); assert( sqlite3PagerIswriteable(pParent->pDbPage) ); assert( pPage->nOverflow==1 ); | < | | 7519 7520 7521 7522 7523 7524 7525 7526 7527 7528 7529 7530 7531 7532 7533 | int rc; /* Return Code */ Pgno pgnoNew; /* Page number of pNew */ assert( sqlite3_mutex_held(pPage->pBt->mutex) ); assert( sqlite3PagerIswriteable(pParent->pDbPage) ); assert( pPage->nOverflow==1 ); if( pPage->nCell==0 ) return SQLITE_CORRUPT_BKPT; /* dbfuzz001.test */ /* Allocate a new page. This page will become the right-sibling of ** pPage. Make the parent page writable, so that the new divider cell ** may be inserted. If both these operations are successful, proceed. */ rc = allocateBtreePage(pBt, &pNew, &pgnoNew, 0, 0); |
︙ | ︙ | |||
9088 9089 9090 9091 9092 9093 9094 9095 9096 9097 9098 9099 9100 9101 | ** ** Or, if the current delete will not cause a rebalance, then the cursor ** will be left in CURSOR_SKIPNEXT state pointing to the entry immediately ** before or after the deleted entry. In this case set bSkipnext to true. */ if( bPreserve ){ if( !pPage->leaf || (pPage->nFree+cellSizePtr(pPage,pCell)+2)>(int)(pBt->usableSize*2/3) ){ /* A b-tree rebalance will be required after deleting this entry. ** Save the cursor key. */ rc = saveCursorKey(pCur); if( rc ) return rc; }else{ bSkipnext = 1; | > | 9100 9101 9102 9103 9104 9105 9106 9107 9108 9109 9110 9111 9112 9113 9114 | ** ** Or, if the current delete will not cause a rebalance, then the cursor ** will be left in CURSOR_SKIPNEXT state pointing to the entry immediately ** before or after the deleted entry. In this case set bSkipnext to true. */ if( bPreserve ){ if( !pPage->leaf || (pPage->nFree+cellSizePtr(pPage,pCell)+2)>(int)(pBt->usableSize*2/3) || pPage->nCell==1 /* See dbfuzz001.test for a test case */ ){ /* A b-tree rebalance will be required after deleting this entry. ** Save the cursor key. */ rc = saveCursorKey(pCur); if( rc ) return rc; }else{ bSkipnext = 1; |
︙ | ︙ | |||
9870 9871 9872 9873 9874 9875 9876 | N--; if( sqlite3PagerGet(pCheck->pPager, (Pgno)iPage, &pOvflPage, 0) ){ checkAppendMsg(pCheck, "failed to get page %d", iPage); break; } pOvflData = (unsigned char *)sqlite3PagerGetData(pOvflPage); if( isFreeList ){ | | | | | 9883 9884 9885 9886 9887 9888 9889 9890 9891 9892 9893 9894 9895 9896 9897 9898 9899 9900 9901 9902 9903 9904 9905 9906 9907 9908 | N--; if( sqlite3PagerGet(pCheck->pPager, (Pgno)iPage, &pOvflPage, 0) ){ checkAppendMsg(pCheck, "failed to get page %d", iPage); break; } pOvflData = (unsigned char *)sqlite3PagerGetData(pOvflPage); if( isFreeList ){ u32 n = (u32)get4byte(&pOvflData[4]); #ifndef SQLITE_OMIT_AUTOVACUUM if( pCheck->pBt->autoVacuum ){ checkPtrmap(pCheck, iPage, PTRMAP_FREEPAGE, 0); } #endif if( n>pCheck->pBt->usableSize/4-2 ){ checkAppendMsg(pCheck, "freelist leaf count too big on page %d", iPage); N--; }else{ for(i=0; i<(int)n; i++){ Pgno iFreePage = get4byte(&pOvflData[8+i*4]); #ifndef SQLITE_OMIT_AUTOVACUUM if( pCheck->pBt->autoVacuum ){ checkPtrmap(pCheck, iFreePage, PTRMAP_FREEPAGE, 0); } #endif checkRef(pCheck, iFreePage); |
︙ | ︙ |
Changes to src/expr.c.
︙ | ︙ | |||
137 138 139 140 141 142 143 | CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){ sqlite3 *db = pParse->db; CollSeq *pColl = 0; Expr *p = pExpr; while( p ){ int op = p->op; if( p->flags & EP_Generic ) break; | > | < | | 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 | CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){ sqlite3 *db = pParse->db; CollSeq *pColl = 0; Expr *p = pExpr; while( p ){ int op = p->op; if( p->flags & EP_Generic ) break; if( op==TK_REGISTER ) op = p->op2; if( (op==TK_AGG_COLUMN || op==TK_COLUMN || op==TK_TRIGGER) && p->y.pTab!=0 ){ /* op==TK_REGISTER && p->y.pTab!=0 happens when pExpr was originally ** a TK_COLUMN but was previously evaluated and cached in a register */ int j = p->iColumn; if( j>=0 ){ const char *zColl = p->y.pTab->aCol[j].zColl; pColl = sqlite3FindCollSeq(db, ENC(db), zColl, 0); } break; } if( op==TK_CAST || op==TK_UPLUS ){ p = p->pLeft; continue; } if( op==TK_COLLATE ){ pColl = sqlite3GetCollSeq(pParse, ENC(db), 0, p->u.zToken); break; } if( p->flags & EP_Collate ){ if( p->pLeft && (p->pLeft->flags & EP_Collate)!=0 ){ p = p->pLeft; }else{ |
︙ | ︙ | |||
4774 4775 4776 4777 4778 4779 4780 | }else if( pA->op==TK_COLLATE ){ if( sqlite3_stricmp(pA->u.zToken,pB->u.zToken)!=0 ) return 2; }else if( strcmp(pA->u.zToken,pB->u.zToken)!=0 ){ return 2; } } if( (pA->flags & EP_Distinct)!=(pB->flags & EP_Distinct) ) return 2; | | < | > > > | 4774 4775 4776 4777 4778 4779 4780 4781 4782 4783 4784 4785 4786 4787 4788 4789 4790 4791 4792 4793 4794 4795 4796 4797 | }else if( pA->op==TK_COLLATE ){ if( sqlite3_stricmp(pA->u.zToken,pB->u.zToken)!=0 ) return 2; }else if( strcmp(pA->u.zToken,pB->u.zToken)!=0 ){ return 2; } } if( (pA->flags & EP_Distinct)!=(pB->flags & EP_Distinct) ) return 2; if( (combinedFlags & EP_TokenOnly)==0 ){ if( combinedFlags & EP_xIsSelect ) return 2; if( (combinedFlags & EP_FixedCol)==0 && sqlite3ExprCompare(pParse, pA->pLeft, pB->pLeft, iTab) ) return 2; if( sqlite3ExprCompare(pParse, pA->pRight, pB->pRight, iTab) ) return 2; if( sqlite3ExprListCompare(pA->x.pList, pB->x.pList, iTab) ) return 2; if( pA->op!=TK_STRING && pA->op!=TK_TRUEFALSE && (combinedFlags & EP_Reduced)==0 ){ if( pA->iColumn!=pB->iColumn ) return 2; if( pA->iTable!=pB->iTable && (pA->iTable!=iTab || NEVER(pB->iTable>=0)) ) return 2; } } return 0; } |
︙ | ︙ |
Changes to src/pcache1.c.
︙ | ︙ | |||
473 474 475 476 477 478 479 480 481 482 483 484 485 486 | /* ** Malloc function used by SQLite to obtain space from the buffer configured ** using sqlite3_config(SQLITE_CONFIG_PAGECACHE) option. If no such buffer ** exists, this function falls back to sqlite3Malloc(). */ void *sqlite3PageMalloc(int sz){ return pcache1Alloc(sz); } /* ** Free an allocated buffer obtained from sqlite3PageMalloc(). */ void sqlite3PageFree(void *p){ | > > > | 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 | /* ** Malloc function used by SQLite to obtain space from the buffer configured ** using sqlite3_config(SQLITE_CONFIG_PAGECACHE) option. If no such buffer ** exists, this function falls back to sqlite3Malloc(). */ void *sqlite3PageMalloc(int sz){ /* During rebalance operations on a corrupt database file, it is sometimes ** (rarely) possible to overread the temporary page buffer by a few bytes. ** Enlarge the allocation slightly so that this does not cause problems. */ return pcache1Alloc(sz); } /* ** Free an allocated buffer obtained from sqlite3PageMalloc(). */ void sqlite3PageFree(void *p){ |
︙ | ︙ |
Changes to src/resolve.c.
︙ | ︙ | |||
76 77 78 79 80 81 82 | db = pParse->db; pDup = sqlite3ExprDup(db, pOrig, 0); if( pDup!=0 ){ if( zType[0]!='G' ) incrAggFunctionDepth(pDup, nSubquery); if( pExpr->op==TK_COLLATE ){ pDup = sqlite3ExprAddCollateString(pParse, pDup, pExpr->u.zToken); } | < | 76 77 78 79 80 81 82 83 84 85 86 87 88 89 | db = pParse->db; pDup = sqlite3ExprDup(db, pOrig, 0); if( pDup!=0 ){ if( zType[0]!='G' ) incrAggFunctionDepth(pDup, nSubquery); if( pExpr->op==TK_COLLATE ){ pDup = sqlite3ExprAddCollateString(pParse, pDup, pExpr->u.zToken); } /* Before calling sqlite3ExprDelete(), set the EP_Static flag. This ** prevents ExprDelete() from deleting the Expr structure itself, ** allowing it to be repopulated by the memcpy() on the following line. ** The pExpr->u.zToken might point into memory that will be freed by the ** sqlite3DbFree(db, pDup) on the last line of this block, so be sure to ** make a copy of the token before doing the sqlite3DbFree(). |
︙ | ︙ |
Changes to src/shell.c.in.
︙ | ︙ | |||
1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 | u8 openMode; /* SHELL_OPEN_NORMAL, _APPENDVFS, or _ZIPFILE */ u8 doXdgOpen; /* Invoke start/open/xdg-open in output_reset() */ u8 nEqpLevel; /* Depth of the EQP output graph */ u8 eTraceType; /* SHELL_TRACE_* value for type of trace */ unsigned mEqpLines; /* Mask of veritical lines in the EQP output graph */ int outCount; /* Revert to stdout when reaching zero */ int cnt; /* Number of records displayed so far */ FILE *out; /* Write results here */ FILE *traceOut; /* Output for sqlite3_trace() */ int nErr; /* Number of errors seen */ int mode; /* An output mode setting */ int modePrior; /* Saved mode */ int cMode; /* temporary output mode for the current query */ int normalMode; /* Output mode before ".explain on" */ | > > | 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 | u8 openMode; /* SHELL_OPEN_NORMAL, _APPENDVFS, or _ZIPFILE */ u8 doXdgOpen; /* Invoke start/open/xdg-open in output_reset() */ u8 nEqpLevel; /* Depth of the EQP output graph */ u8 eTraceType; /* SHELL_TRACE_* value for type of trace */ unsigned mEqpLines; /* Mask of veritical lines in the EQP output graph */ int outCount; /* Revert to stdout when reaching zero */ int cnt; /* Number of records displayed so far */ int lineno; /* Line number of last line read from in */ FILE *in; /* Read commands from this stream */ FILE *out; /* Write results here */ FILE *traceOut; /* Output for sqlite3_trace() */ int nErr; /* Number of errors seen */ int mode; /* An output mode setting */ int modePrior; /* Saved mode */ int cMode; /* temporary output mode for the current query */ int normalMode; /* Output mode before ".explain on" */ |
︙ | ︙ | |||
1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 | */ #define SHELL_OPEN_UNSPEC 0 /* No open-mode specified */ #define SHELL_OPEN_NORMAL 1 /* Normal database file */ #define SHELL_OPEN_APPENDVFS 2 /* Use appendvfs */ #define SHELL_OPEN_ZIPFILE 3 /* Use the zipfile virtual table */ #define SHELL_OPEN_READONLY 4 /* Open a normal database read-only */ #define SHELL_OPEN_DESERIALIZE 5 /* Open using sqlite3_deserialize() */ /* Allowed values for ShellState.eTraceType */ #define SHELL_TRACE_PLAIN 0 /* Show input SQL text */ #define SHELL_TRACE_EXPANDED 1 /* Show expanded SQL text */ #define SHELL_TRACE_NORMALIZED 2 /* Show normalized SQL text */ | > | 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 | */ #define SHELL_OPEN_UNSPEC 0 /* No open-mode specified */ #define SHELL_OPEN_NORMAL 1 /* Normal database file */ #define SHELL_OPEN_APPENDVFS 2 /* Use appendvfs */ #define SHELL_OPEN_ZIPFILE 3 /* Use the zipfile virtual table */ #define SHELL_OPEN_READONLY 4 /* Open a normal database read-only */ #define SHELL_OPEN_DESERIALIZE 5 /* Open using sqlite3_deserialize() */ #define SHELL_OPEN_HEXDB 6 /* Use "dbtotxt" output as data source */ /* Allowed values for ShellState.eTraceType */ #define SHELL_TRACE_PLAIN 0 /* Show input SQL text */ #define SHELL_TRACE_EXPANDED 1 /* Show expanded SQL text */ #define SHELL_TRACE_NORMALIZED 2 /* Show normalized SQL text */ |
︙ | ︙ | |||
3440 3441 3442 3443 3444 3445 3446 3447 3448 3449 3450 3451 3452 3453 | " -e Invoke system text editor", " -x Open in a spreadsheet", ".open ?OPTIONS? ?FILE? Close existing database and reopen FILE", " Options:", " --append Use appendvfs to append database to the end of FILE", #ifdef SQLITE_ENABLE_DESERIALIZE " --deserialize Load into memory useing sqlite3_deserialize()", #endif " --new Initialize FILE to an empty database", " --readonly Open FILE readonly", " --zip FILE is a ZIP archive", ".output ?FILE? Send output to FILE or stdout if FILE is omitted", " If FILE begins with '|' then open it as a pipe.", ".print STRING... Print literal STRING", | > | 3443 3444 3445 3446 3447 3448 3449 3450 3451 3452 3453 3454 3455 3456 3457 | " -e Invoke system text editor", " -x Open in a spreadsheet", ".open ?OPTIONS? ?FILE? Close existing database and reopen FILE", " Options:", " --append Use appendvfs to append database to the end of FILE", #ifdef SQLITE_ENABLE_DESERIALIZE " --deserialize Load into memory useing sqlite3_deserialize()", " --hexdb Load the output of \"dbtotxt\" as an in-memory database", #endif " --new Initialize FILE to an empty database", " --readonly Open FILE readonly", " --zip FILE is a ZIP archive", ".output ?FILE? Send output to FILE or stdout if FILE is omitted", " If FILE begins with '|' then open it as a pipe.", ".print STRING... Print literal STRING", |
︙ | ︙ | |||
3589 3590 3591 3592 3593 3594 3595 | } sqlite3_free(zPat); } return n; } /* Forward reference */ | | | 3593 3594 3595 3596 3597 3598 3599 3600 3601 3602 3603 3604 3605 3606 3607 | } sqlite3_free(zPat); } return n; } /* Forward reference */ static int process_input(ShellState *p); /* ** Read the content of file zName into memory obtained from sqlite3_malloc64() ** and return a pointer to the buffer. The caller is responsible for freeing ** the memory. ** ** If parameter pnByte is not NULL, (*pnByte) is set to the number of bytes |
︙ | ︙ | |||
3719 3720 3721 3722 3723 3724 3725 3726 3727 3728 3729 3730 3731 3732 | rc = SHELL_OPEN_ZIPFILE; } } fclose(f); return rc; } /* Flags for open_db(). ** ** The default behavior of open_db() is to exit(1) if the database fails to ** open. The OPEN_DB_KEEPALIVE flag changes that so that it prints an error ** but still returns without calling exit. ** ** The OPEN_DB_ZIPFILE flag causes open_db() to prefer to open files as a | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 3723 3724 3725 3726 3727 3728 3729 3730 3731 3732 3733 3734 3735 3736 3737 3738 3739 3740 3741 3742 3743 3744 3745 3746 3747 3748 3749 3750 3751 3752 3753 3754 3755 3756 3757 3758 3759 3760 3761 3762 3763 3764 3765 3766 3767 3768 3769 3770 3771 3772 3773 3774 3775 3776 3777 3778 3779 3780 3781 3782 3783 3784 3785 3786 3787 3788 3789 3790 3791 3792 3793 3794 3795 3796 3797 3798 3799 3800 3801 3802 3803 3804 3805 3806 3807 3808 3809 3810 3811 3812 3813 3814 3815 3816 3817 3818 3819 3820 3821 3822 3823 3824 | rc = SHELL_OPEN_ZIPFILE; } } fclose(f); return rc; } #ifdef SQLITE_ENABLE_DESERIALIZE /* ** Reconstruct an in-memory database using the output from the "dbtotxt" ** program. Read content from the file in p->zDbFilename. If p->zDbFilename ** is 0, then read from standard input. */ static unsigned char *readHexDb(ShellState *p, int *pnData){ unsigned char *a = 0; int nLine; int n = 0; int pgsz = 0; int iOffset = 0; int j, k; int rc; FILE *in; unsigned char x[16]; char zLine[1000]; if( p->zDbFilename ){ in = fopen(p->zDbFilename, "r"); if( in==0 ){ utf8_printf(stderr, "cannot open \"%s\" for reading\n", p->zDbFilename); return 0; } nLine = 0; }else{ in = p->in; nLine = p->lineno; } *pnData = 0; nLine++; if( fgets(zLine, sizeof(zLine), in)==0 ) goto readHexDb_error; rc = sscanf(zLine, "| size %d pagesize %d", &n, &pgsz); if( rc!=2 ) goto readHexDb_error; if( n<=0 ) goto readHexDb_error; a = sqlite3_malloc( n ); if( a==0 ){ utf8_printf(stderr, "Out of memory!\n"); goto readHexDb_error; } memset(a, 0, n); if( pgsz<512 || pgsz>65536 || (pgsz & (pgsz-1))!=0 ){ utf8_printf(stderr, "invalid pagesize\n"); goto readHexDb_error; } for(nLine++; fgets(zLine, sizeof(zLine), in)!=0; nLine++){ rc = sscanf(zLine, "| page %d offset %d", &j, &k); if( rc==2 ){ iOffset = k; continue; } if( strncmp(zLine, "| end ", 6)==0 ){ break; } rc = sscanf(zLine,"| %d: %hhx %hhx %hhx %hhx %hhx %hhx %hhx %hhx" " %hhx %hhx %hhx %hhx %hhx %hhx %hhx %hhx", &j, &x[0], &x[1], &x[2], &x[3], &x[4], &x[5], &x[6], &x[7], &x[8], &x[9], &x[10], &x[11], &x[12], &x[13], &x[14], &x[15]); if( rc==17 ){ k = iOffset+j; if( k+16<=n ){ memcpy(a+k, x, 16); } } } *pnData = n; if( in!=p->in ){ fclose(in); }else{ p->lineno = nLine; } return a; readHexDb_error: if( in!=stdin ){ fclose(in); }else{ while( fgets(zLine, sizeof(zLine), p->in)!=0 ){ nLine++; if(strncmp(zLine, "| end ", 6)==0 ) break; } p->lineno = nLine; } sqlite3_free(a); utf8_printf(stderr,"Error on line %d of --hexdb input\n", nLine); return 0; } #endif /* SQLITE_ENABLE_DESERIALIZE */ /* Flags for open_db(). ** ** The default behavior of open_db() is to exit(1) if the database fails to ** open. The OPEN_DB_KEEPALIVE flag changes that so that it prints an error ** but still returns without calling exit. ** ** The OPEN_DB_ZIPFILE flag causes open_db() to prefer to open files as a |
︙ | ︙ | |||
3752 3753 3754 3755 3756 3757 3758 3759 3760 3761 3762 3763 3764 3765 | } switch( p->openMode ){ case SHELL_OPEN_APPENDVFS: { sqlite3_open_v2(p->zDbFilename, &p->db, SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE, "apndvfs"); break; } case SHELL_OPEN_DESERIALIZE: { sqlite3_open(0, &p->db); break; } case SHELL_OPEN_ZIPFILE: { sqlite3_open(":memory:", &p->db); break; | > | 3844 3845 3846 3847 3848 3849 3850 3851 3852 3853 3854 3855 3856 3857 3858 | } switch( p->openMode ){ case SHELL_OPEN_APPENDVFS: { sqlite3_open_v2(p->zDbFilename, &p->db, SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE, "apndvfs"); break; } case SHELL_OPEN_HEXDB: case SHELL_OPEN_DESERIALIZE: { sqlite3_open(0, &p->db); break; } case SHELL_OPEN_ZIPFILE: { sqlite3_open(":memory:", &p->db); break; |
︙ | ︙ | |||
3806 3807 3808 3809 3810 3811 3812 | if( p->openMode==SHELL_OPEN_ZIPFILE ){ char *zSql = sqlite3_mprintf( "CREATE VIRTUAL TABLE zip USING zipfile(%Q);", p->zDbFilename); sqlite3_exec(p->db, zSql, 0, 0, 0); sqlite3_free(zSql); } #ifdef SQLITE_ENABLE_DESERIALIZE | > | > > > | > > > > > > > | | 3899 3900 3901 3902 3903 3904 3905 3906 3907 3908 3909 3910 3911 3912 3913 3914 3915 3916 3917 3918 3919 3920 3921 3922 3923 3924 3925 3926 3927 | if( p->openMode==SHELL_OPEN_ZIPFILE ){ char *zSql = sqlite3_mprintf( "CREATE VIRTUAL TABLE zip USING zipfile(%Q);", p->zDbFilename); sqlite3_exec(p->db, zSql, 0, 0, 0); sqlite3_free(zSql); } #ifdef SQLITE_ENABLE_DESERIALIZE else if( p->openMode==SHELL_OPEN_DESERIALIZE || p->openMode==SHELL_OPEN_HEXDB ){ int rc; int nData = 0; unsigned char *aData; if( p->openMode==SHELL_OPEN_DESERIALIZE ){ aData = (unsigned char*)readFile(p->zDbFilename, &nData); }else{ aData = readHexDb(p, &nData); if( aData==0 ){ utf8_printf(stderr, "Error in hexdb input\n"); return; } } rc = sqlite3_deserialize(p->db, "main", aData, nData, nData, SQLITE_DESERIALIZE_RESIZEABLE | SQLITE_DESERIALIZE_FREEONCLOSE); if( rc ){ utf8_printf(stderr, "Error: sqlite3_deserialize() returns %d\n", rc); } } #endif |
︙ | ︙ | |||
6745 6746 6747 6748 6749 6750 6751 | }else if( optionMatch(z, "append") ){ p->openMode = SHELL_OPEN_APPENDVFS; }else if( optionMatch(z, "readonly") ){ p->openMode = SHELL_OPEN_READONLY; #ifdef SQLITE_ENABLE_DESERIALIZE }else if( optionMatch(z, "deserialize") ){ p->openMode = SHELL_OPEN_DESERIALIZE; | > > | | | 6849 6850 6851 6852 6853 6854 6855 6856 6857 6858 6859 6860 6861 6862 6863 6864 6865 6866 6867 6868 6869 6870 6871 6872 6873 6874 | }else if( optionMatch(z, "append") ){ p->openMode = SHELL_OPEN_APPENDVFS; }else if( optionMatch(z, "readonly") ){ p->openMode = SHELL_OPEN_READONLY; #ifdef SQLITE_ENABLE_DESERIALIZE }else if( optionMatch(z, "deserialize") ){ p->openMode = SHELL_OPEN_DESERIALIZE; }else if( optionMatch(z, "hexdb") ){ p->openMode = SHELL_OPEN_HEXDB; #endif /* SQLITE_ENABLE_DESERIALIZE */ }else if( z[0]=='-' ){ utf8_printf(stderr, "unknown option: %s\n", z); rc = 1; goto meta_command_exit; } } /* If a filename is specified, try to open it first */ zNewFilename = nArg>iName ? sqlite3_mprintf("%s", azArg[iName]) : 0; if( zNewFilename || p->openMode==SHELL_OPEN_HEXDB ){ if( newFlag ) shellDeleteFile(zNewFilename); p->zDbFilename = zNewFilename; open_db(p, OPEN_DB_KEEPALIVE); if( p->db==0 ){ utf8_printf(stderr, "Error: cannot open '%s'\n", zNewFilename); sqlite3_free(zNewFilename); }else{ |
︙ | ︙ | |||
6870 6871 6872 6873 6874 6875 6876 | }else if( c=='q' && strncmp(azArg[0], "quit", n)==0 ){ rc = 2; }else if( c=='r' && n>=3 && strncmp(azArg[0], "read", n)==0 ){ | | > | | | | > > | 6976 6977 6978 6979 6980 6981 6982 6983 6984 6985 6986 6987 6988 6989 6990 6991 6992 6993 6994 6995 6996 6997 6998 6999 7000 7001 7002 7003 7004 7005 7006 | }else if( c=='q' && strncmp(azArg[0], "quit", n)==0 ){ rc = 2; }else if( c=='r' && n>=3 && strncmp(azArg[0], "read", n)==0 ){ FILE *inSaved = p->in; int savedLineno = p->lineno; if( nArg!=2 ){ raw_printf(stderr, "Usage: .read FILE\n"); rc = 1; goto meta_command_exit; } p->in = fopen(azArg[1], "rb"); if( p->in==0 ){ utf8_printf(stderr,"Error: cannot open \"%s\"\n", azArg[1]); rc = 1; }else{ rc = process_input(p); fclose(p->in); } p->in = inSaved; p->lineno = savedLineno; }else if( c=='r' && n>=3 && strncmp(azArg[0], "restore", n)==0 ){ const char *zSrcFile; const char *zDb; sqlite3 *pSrc; sqlite3_backup *pBackup; |
︙ | ︙ | |||
8224 8225 8226 8227 8228 8229 8230 | ** is interactive - the user is typing it it. Otherwise, input ** is coming from a file or device. A prompt is issued and history ** is saved only if input is interactive. An interrupt signal will ** cause this routine to exit immediately, unless input is interactive. ** ** Return the number of errors. */ | | < > | | | | | | 8333 8334 8335 8336 8337 8338 8339 8340 8341 8342 8343 8344 8345 8346 8347 8348 8349 8350 8351 8352 8353 8354 8355 8356 8357 8358 8359 8360 8361 8362 8363 8364 8365 8366 8367 8368 8369 8370 8371 | ** is interactive - the user is typing it it. Otherwise, input ** is coming from a file or device. A prompt is issued and history ** is saved only if input is interactive. An interrupt signal will ** cause this routine to exit immediately, unless input is interactive. ** ** Return the number of errors. */ static int process_input(ShellState *p){ char *zLine = 0; /* A single input line */ char *zSql = 0; /* Accumulated SQL text */ int nLine; /* Length of current line */ int nSql = 0; /* Bytes of zSql[] used */ int nAlloc = 0; /* Allocated zSql[] space */ int nSqlPrior = 0; /* Bytes of zSql[] used by prior line */ int rc; /* Error code */ int errCnt = 0; /* Number of errors seen */ int startline = 0; /* Line number for start of current input */ p->lineno = 0; while( errCnt==0 || !bail_on_error || (p->in==0 && stdin_is_interactive) ){ fflush(p->out); zLine = one_input_line(p->in, zLine, nSql>0); if( zLine==0 ){ /* End of input */ if( p->in==0 && stdin_is_interactive ) printf("\n"); break; } if( seenInterrupt ){ if( p->in!=0 ) break; seenInterrupt = 0; } p->lineno++; if( nSql==0 && _all_whitespace(zLine) ){ if( ShellHasFlag(p, SHFLG_Echo) ) printf("%s\n", zLine); continue; } if( zLine && (zLine[0]=='.' || zLine[0]=='#') && nSql==0 ){ if( ShellHasFlag(p, SHFLG_Echo) ) printf("%s\n", zLine); if( zLine[0]=='.' ){ |
︙ | ︙ | |||
8280 8281 8282 8283 8284 8285 8286 | } nSqlPrior = nSql; if( nSql==0 ){ int i; for(i=0; zLine[i] && IsSpace(zLine[i]); i++){} assert( nAlloc>0 && zSql!=0 ); memcpy(zSql, zLine+i, nLine+1-i); | | | | | 8389 8390 8391 8392 8393 8394 8395 8396 8397 8398 8399 8400 8401 8402 8403 8404 8405 8406 8407 8408 8409 8410 8411 8412 8413 8414 8415 8416 8417 8418 8419 8420 8421 8422 8423 8424 8425 8426 | } nSqlPrior = nSql; if( nSql==0 ){ int i; for(i=0; zLine[i] && IsSpace(zLine[i]); i++){} assert( nAlloc>0 && zSql!=0 ); memcpy(zSql, zLine+i, nLine+1-i); startline = p->lineno; nSql = nLine-i; }else{ zSql[nSql++] = '\n'; memcpy(zSql+nSql, zLine, nLine+1); nSql += nLine; } if( nSql && line_contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior) && sqlite3_complete(zSql) ){ errCnt += runOneSqlLine(p, zSql, p->in, startline); nSql = 0; if( p->outCount ){ output_reset(p); p->outCount = 0; }else{ clearTempFile(p); } }else if( nSql && _all_whitespace(zSql) ){ if( ShellHasFlag(p, SHFLG_Echo) ) printf("%s\n", zSql); nSql = 0; } } if( nSql && !_all_whitespace(zSql) ){ errCnt += runOneSqlLine(p, zSql, p->in, startline); } free(zSql); free(zLine); return errCnt>0; } /* |
︙ | ︙ | |||
8392 8393 8394 8395 8396 8397 8398 | static void process_sqliterc( ShellState *p, /* Configuration data */ const char *sqliterc_override /* Name of config file. NULL to use default */ ){ char *home_dir = NULL; const char *sqliterc = sqliterc_override; char *zBuf = 0; | | > | | | | > > | 8501 8502 8503 8504 8505 8506 8507 8508 8509 8510 8511 8512 8513 8514 8515 8516 8517 8518 8519 8520 8521 8522 8523 8524 8525 8526 8527 8528 8529 8530 8531 8532 8533 8534 8535 8536 8537 | static void process_sqliterc( ShellState *p, /* Configuration data */ const char *sqliterc_override /* Name of config file. NULL to use default */ ){ char *home_dir = NULL; const char *sqliterc = sqliterc_override; char *zBuf = 0; FILE *inSaved = p->in; int savedLineno = p->lineno; if (sqliterc == NULL) { home_dir = find_home_dir(0); if( home_dir==0 ){ raw_printf(stderr, "-- warning: cannot find home directory;" " cannot read ~/.sqliterc\n"); return; } zBuf = sqlite3_mprintf("%s/.sqliterc",home_dir); sqliterc = zBuf; } p->in = fopen(sqliterc,"rb"); if( p->in ){ if( stdin_is_interactive ){ utf8_printf(stderr,"-- Loading resources from %s\n",sqliterc); } process_input(p); fclose(p->in); } p->in = inSaved; p->lineno = savedLineno; sqlite3_free(zBuf); } /* ** Show available command line options */ static const char zOptions[] = |
︙ | ︙ | |||
9023 9024 9025 9026 9027 9028 9029 | } if( zHistory ){ shell_read_history(zHistory); } #if HAVE_READLINE || HAVE_EDITLINE rl_attempted_completion_function = readline_completion; #elif HAVE_LINENOISE linenoiseSetCompletionCallback(linenoise_completion); #endif | > | > | | 9135 9136 9137 9138 9139 9140 9141 9142 9143 9144 9145 9146 9147 9148 9149 9150 9151 9152 9153 9154 9155 9156 9157 9158 | } if( zHistory ){ shell_read_history(zHistory); } #if HAVE_READLINE || HAVE_EDITLINE rl_attempted_completion_function = readline_completion; #elif HAVE_LINENOISE linenoiseSetCompletionCallback(linenoise_completion); #endif data.in = 0; rc = process_input(&data); if( zHistory ){ shell_stifle_history(2000); shell_write_history(zHistory); free(zHistory); } }else{ data.in = stdin; rc = process_input(&data); } } set_table_name(&data, 0); if( data.db ){ session_close_all(&data); close_db(data.db); } |
︙ | ︙ |
Changes to src/test1.c.
︙ | ︙ | |||
7671 7672 7673 7674 7675 7676 7677 7678 7679 7680 7681 7682 7683 7684 | zDb = Tcl_GetString(objv[2]); } rc = sqlite3_mmap_warm(db, zDb); Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3ErrName(rc), -1)); return TCL_OK; } } /* ** Register commands with the TCL interpreter. */ int Sqlitetest1_Init(Tcl_Interp *interp){ extern int sqlite3_search_count; extern int sqlite3_found_count; | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 7671 7672 7673 7674 7675 7676 7677 7678 7679 7680 7681 7682 7683 7684 7685 7686 7687 7688 7689 7690 7691 7692 7693 7694 7695 7696 7697 7698 7699 7700 7701 7702 7703 7704 7705 7706 7707 7708 7709 7710 7711 7712 7713 7714 7715 7716 7717 7718 7719 7720 7721 7722 7723 7724 7725 7726 7727 7728 7729 7730 7731 7732 7733 7734 7735 7736 7737 7738 7739 7740 7741 7742 7743 7744 7745 7746 7747 7748 7749 7750 7751 7752 7753 7754 7755 7756 7757 | zDb = Tcl_GetString(objv[2]); } rc = sqlite3_mmap_warm(db, zDb); Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3ErrName(rc), -1)); return TCL_OK; } } /* ** Usage: decode_hexdb TEXT ** ** Example: db deserialize [decode_hexdb $output_of_dbtotxt] ** ** This routine returns a byte-array for an SQLite database file that ** is constructed from a text input which is the output of the "dbtotxt" ** utility. */ static int SQLITE_TCLAPI test_decode_hexdb( void * clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[] ){ const char *zIn = 0; unsigned char *a = 0; int n = 0; int lineno = 0; int i, iNext; int iOffset = 0; int j, k; int rc; unsigned char x[16]; if( objc!=2 ){ Tcl_WrongNumArgs(interp, 1, objv, "HEXDB"); return TCL_ERROR; } zIn = Tcl_GetString(objv[1]); for(i=0; zIn[i]; i=iNext){ lineno++; for(iNext=i; zIn[iNext] && zIn[iNext]!='\n'; iNext++){} if( zIn[iNext]=='\n' ) iNext++; while( zIn[i]==' ' || zIn[i]=='\t' ){ i++; } if( a==0 ){ int pgsz; rc = sscanf(zIn+i, "| size %d pagesize %d", &n, &pgsz); if( rc!=2 ) continue; if( n<512 ){ Tcl_AppendResult(interp, "bad 'size' field", (void*)0); return TCL_ERROR; } a = malloc( n ); if( a==0 ){ Tcl_AppendResult(interp, "out of memory", (void*)0); return TCL_ERROR; } memset(a, 0, n); continue; } rc = sscanf(zIn+i, "| page %d offset %d", &j, &k); if( rc==2 ){ iOffset = k; continue; } rc = sscanf(zIn+i,"| %d: %hhx %hhx %hhx %hhx %hhx %hhx %hhx %hhx" " %hhx %hhx %hhx %hhx %hhx %hhx %hhx %hhx", &j, &x[0], &x[1], &x[2], &x[3], &x[4], &x[5], &x[6], &x[7], &x[8], &x[9], &x[10], &x[11], &x[12], &x[13], &x[14], &x[15]); if( rc==17 ){ k = iOffset+j; if( k+16<=n ){ memcpy(a+k, x, 16); } continue; } } Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(a, n)); free(a); return TCL_OK; } /* ** Register commands with the TCL interpreter. */ int Sqlitetest1_Init(Tcl_Interp *interp){ extern int sqlite3_search_count; extern int sqlite3_found_count; |
︙ | ︙ | |||
7952 7953 7954 7955 7956 7957 7958 7959 7960 7961 7962 7963 7964 7965 | { "sqlite3_snapshot_cmp_blob", test_snapshot_cmp_blob, 0 }, #endif { "sqlite3_delete_database", test_delete_database, 0 }, { "sqlite3_wal_info", test_wal_info, 0 }, { "atomic_batch_write", test_atomic_batch_write, 0 }, { "sqlite3_mmap_warm", test_mmap_warm, 0 }, { "sqlite3_config_sorterref", test_config_sorterref, 0 }, }; static int bitmask_size = sizeof(Bitmask)*8; static int longdouble_size = sizeof(LONGDOUBLE_TYPE); int i; extern int sqlite3_sync_count, sqlite3_fullsync_count; extern int sqlite3_opentemp_count; extern int sqlite3_like_count; | > | 8025 8026 8027 8028 8029 8030 8031 8032 8033 8034 8035 8036 8037 8038 8039 | { "sqlite3_snapshot_cmp_blob", test_snapshot_cmp_blob, 0 }, #endif { "sqlite3_delete_database", test_delete_database, 0 }, { "sqlite3_wal_info", test_wal_info, 0 }, { "atomic_batch_write", test_atomic_batch_write, 0 }, { "sqlite3_mmap_warm", test_mmap_warm, 0 }, { "sqlite3_config_sorterref", test_config_sorterref, 0 }, { "decode_hexdb", test_decode_hexdb, 0 }, }; static int bitmask_size = sizeof(Bitmask)*8; static int longdouble_size = sizeof(LONGDOUBLE_TYPE); int i; extern int sqlite3_sync_count, sqlite3_fullsync_count; extern int sqlite3_opentemp_count; extern int sqlite3_like_count; |
︙ | ︙ |
Changes to src/whereexpr.c.
︙ | ︙ | |||
773 774 775 776 777 778 779 780 781 782 783 784 785 786 | /* Search for a table and column that appears on one side or the ** other of the == operator in every subterm. That table and column ** will be recorded in iCursor and iColumn. There might not be any ** such table and column. Set okToChngToIN if an appropriate table ** and column is found but leave okToChngToIN false if not found. */ for(j=0; j<2 && !okToChngToIN; j++){ pOrTerm = pOrWc->a; for(i=pOrWc->nTerm-1; i>=0; i--, pOrTerm++){ assert( pOrTerm->eOperator & WO_EQ ); pOrTerm->wtFlags &= ~TERM_OR_OK; if( pOrTerm->leftCursor==iCursor ){ /* This is the 2-bit case and we are on the second iteration and ** current term is from the first iteration. So skip this term. */ | > | 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 | /* Search for a table and column that appears on one side or the ** other of the == operator in every subterm. That table and column ** will be recorded in iCursor and iColumn. There might not be any ** such table and column. Set okToChngToIN if an appropriate table ** and column is found but leave okToChngToIN false if not found. */ for(j=0; j<2 && !okToChngToIN; j++){ Expr *pLeft = 0; pOrTerm = pOrWc->a; for(i=pOrWc->nTerm-1; i>=0; i--, pOrTerm++){ assert( pOrTerm->eOperator & WO_EQ ); pOrTerm->wtFlags &= ~TERM_OR_OK; if( pOrTerm->leftCursor==iCursor ){ /* This is the 2-bit case and we are on the second iteration and ** current term is from the first iteration. So skip this term. */ |
︙ | ︙ | |||
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 | testcase( pOrTerm->wtFlags & TERM_COPIED ); testcase( pOrTerm->wtFlags & TERM_VIRTUAL ); assert( pOrTerm->wtFlags & (TERM_COPIED|TERM_VIRTUAL) ); continue; } iColumn = pOrTerm->u.leftColumn; iCursor = pOrTerm->leftCursor; break; } if( i<0 ){ /* No candidate table+column was found. This can only occur ** on the second iteration */ assert( j==1 ); assert( IsPowerOfTwo(chngToIN) ); assert( chngToIN==sqlite3WhereGetMask(&pWInfo->sMaskSet, iCursor) ); break; } testcase( j==1 ); /* We have found a candidate table and column. Check to see if that ** table and column is common to every term in the OR clause */ okToChngToIN = 1; for(; i>=0 && okToChngToIN; i--, pOrTerm++){ assert( pOrTerm->eOperator & WO_EQ ); if( pOrTerm->leftCursor!=iCursor ){ pOrTerm->wtFlags &= ~TERM_OR_OK; | > | > > | 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 | testcase( pOrTerm->wtFlags & TERM_COPIED ); testcase( pOrTerm->wtFlags & TERM_VIRTUAL ); assert( pOrTerm->wtFlags & (TERM_COPIED|TERM_VIRTUAL) ); continue; } iColumn = pOrTerm->u.leftColumn; iCursor = pOrTerm->leftCursor; pLeft = pOrTerm->pExpr->pLeft; break; } if( i<0 ){ /* No candidate table+column was found. This can only occur ** on the second iteration */ assert( j==1 ); assert( IsPowerOfTwo(chngToIN) ); assert( chngToIN==sqlite3WhereGetMask(&pWInfo->sMaskSet, iCursor) ); break; } testcase( j==1 ); /* We have found a candidate table and column. Check to see if that ** table and column is common to every term in the OR clause */ okToChngToIN = 1; for(; i>=0 && okToChngToIN; i--, pOrTerm++){ assert( pOrTerm->eOperator & WO_EQ ); if( pOrTerm->leftCursor!=iCursor ){ pOrTerm->wtFlags &= ~TERM_OR_OK; }else if( pOrTerm->u.leftColumn!=iColumn || (iColumn==XN_EXPR && sqlite3ExprCompare(pParse, pOrTerm->pExpr->pLeft, pLeft, -1) )){ okToChngToIN = 0; }else{ int affLeft, affRight; /* If the right-hand side is also a column, then the affinities ** of both right and left sides must be such that no type ** conversions are required on the right. (Ticket #2249) */ |
︙ | ︙ |
Added test/dbfuzz001.test.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 | # 2012-12-13 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # # Test cases for corrupt database files. set testdir [file dirname $argv0] source $testdir/tester.tcl ifcapable !deserialize { finish_test return } database_may_be_corrupt # In the following database file, there is 384 bytes of free space # on page 8 that does not appear on the freeblock list. # do_test dbfuzz001-100 { sqlite3 db {} db deserialize [decode_hexdb { | size 5632 pagesize 512 filename c4.db | page 1 offset 0 | 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3. | 16: 02 00 01 01 00 40 20 20 00 00 00 02 00 00 00 0b .....@ ........ | 32: 00 00 00 06 00 00 00 01 00 00 00 28 00 00 00 04 ...........(.... | 48: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 ................ | 80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 02 ................ | 96: 00 2e 30 38 0d 00 00 00 06 01 06 00 01 da 01 b0 ..08............ | 112: 01 56 01 86 01 2a 01 06 00 00 00 00 00 00 00 00 .V...*.......... | 256: 00 00 00 00 00 00 22 07 06 17 11 11 01 31 74 61 ......"......1ta | 272: 62 6c 65 74 34 74 34 07 43 52 45 41 54 45 20 54 blet4t4.CREATE T | 288: 41 42 4c 45 20 74 34 28 78 29 2a 06 06 17 13 11 ABLE t4(x)*..... | 304: 01 3f 69 6e 64 65 78 00 00 00 00 00 00 00 00 00 .?index......... | 336: 20 74 33 28 78 29 2e 04 06 17 15 11 01 45 69 6e t3(x).......Ein | 352: 64 65 78 74 32 63 64 74 32 05 43 52 45 41 54 45 dext2cdt2.CREATE | 368: 20 49 4e 44 45 58 20 74 32 63 64 20 4f 4e 20 74 INDEX t2cd ON t | 384: 32 28 63 2c 64 29 28 05 06 17 11 11 01 3d 74 61 2(c,d)(......=ta | 400: 62 6c 65 74 33 74 33 04 43 52 45 41 54 45 20 54 blet3t3.CREATE T | 416: 41 42 4c 45 20 74 33 28 63 2c 78 2c 65 2c 66 29 ABLE t3(c,x,e,f) | 432: 28 02 06 17 11 11 01 3d 74 61 62 6c 65 74 32 74 (......=tablet2t | 448: 32 03 43 52 45 41 54 45 20 54 41 42 4c 45 20 74 2.CREATE TABLE t | 464: 32 28 63 2c 64 2c 65 2c 66 29 24 01 06 17 11 11 2(c,d,e,f)$..... | 480: 01 35 74 61 62 6c 65 74 31 74 31 02 43 52 45 41 .5tablet1t1.CREA | 496: 54 45 20 54 41 42 4c 45 20 74 31 28 61 2c 62 29 TE TABLE t1(a,b) | page 2 offset 512 | 0: 0d 00 00 00 00 02 00 00 00 00 00 00 00 00 00 00 ................ | page 3 offset 1024 | 0: 0d 00 00 00 00 02 00 00 00 00 00 00 00 00 00 00 ................ | page 4 offset 1536 | 0: 05 00 00 00 03 01 f1 00 00 00 00 0b 01 fb 01 f6 ................ | 16: 01 f1 00 16 00 00 09 06 05 01 01 01 01 04 04 03 ................ | 32: 03 07 05 05 01 01 09 09 02 02 19 04 05 17 17 17 ................ | 48: 17 73 65 76 65 6e 65 69 67 68 74 65 69 67 68 74 .seveneighteight | 64: 73 65 76 65 6e 25 03 05 07 07 07 07 40 14 00 00 seven%......@... | 80: 00 00 00 00 40 18 00 00 00 00 00 00 40 18 00 00 ....@.......@... | 96: 00 00 00 00 40 14 00 00 00 00 00 00 09 02 05 01 ....@........... | 112: 01 01 01 03 04 04 03 07 01 05 09 01 01 09 02 02 ................ | 352: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 1a ................ | 496: 00 00 00 00 0a 3e 00 00 00 09 21 00 00 00 08 06 .....>....!..... | page 5 offset 2048 | 0: 0a 00 00 00 00 02 00 00 00 00 00 00 00 00 00 00 ................ | page 7 offset 3072 | 0: 0d 00 00 00 08 01 c2 00 01 fb 01 f6 01 f1 01 ec ................ | 16: 01 e0 01 d4 01 cb 01 c2 00 00 00 00 00 00 00 00 ................ | 96: 00 00 00 00 13 00 00 00 00 00 00 00 00 00 00 00 ................ | 224: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 02 ................ | 288: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 03 ................ | 448: 00 00 07 08 02 17 65 69 67 68 74 07 07 02 17 65 ......eight....e | 464: 69 67 68 74 0a 06 02 07 40 18 00 00 00 00 00 00 ight....@....... | 480: 0a 05 02 07 40 18 00 00 00 00 00 00 03 04 02 01 ....@........... | 496: 04 03 03 02 01 04 03 02 02 01 02 03 01 02 01 02 ................ | page 8 offset 3584 | 0: 0d 00 21 00 01 00 16 00 00 16 00 16 00 16 00 16 ..!............. | 16: 00 16 00 16 00 00 09 06 05 01 01 01 01 04 04 03 ................ | 32: 03 00 00 00 5f 01 09 09 02 02 00 00 00 56 17 17 ...._........V.. | 48: 17 73 65 76 65 6e 65 69 67 68 74 65 69 67 68 74 .seveneighteight | 64: 73 65 76 65 6e 00 00 00 3b 07 07 07 40 14 00 00 seven...;...@... | 80: 00 00 00 00 40 18 00 00 00 00 00 00 40 18 00 00 ....@.......@... | 96: 00 00 00 00 40 14 00 00 00 00 00 00 00 00 00 14 ....@........... | 112: 01 01 01 03 04 04 03 00 00 00 09 01 01 09 02 02 ................ | 352: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 1a ................ | page 9 offset 4096 | 0: 0d 00 00 00 1b 00 47 00 01 d9 01 be 01 af 01 a0 ......G......... | 16: 01 91 01 82 01 73 01 64 01 55 01 46 01 37 01 28 .....s.d.U.F.7.( | 32: 01 19 01 0a 00 fb 00 ec 00 dd 00 ce 00 bf 00 b0 ................ | 48: 00 a1 00 92 00 83 00 74 00 65 00 56 00 47 00 00 .......t.e.V.G.. | 64: 00 00 00 00 00 00 00 0d 21 00 00 48 01 54 00 01 ........!..H.T.. | 80: f7 01 ec 01 c5 01 0d 20 00 00 48 01 54 00 01 f7 ....... ..H.T... | 96: 01 ec 01 c5 01 0d 1f 00 00 48 01 54 00 01 f7 01 .........H.T.... | 112: ec 01 c5 01 0d 1e 00 00 48 01 54 00 01 f7 01 ec ........H.T..... | 128: 01 c5 01 0d 1d 00 00 48 01 54 00 01 f7 01 ec 01 .......H.T...... | 144: c5 01 0d 1c 00 00 48 01 54 00 01 f7 01 ec 01 c5 ......H.T....... | 160: 01 0d 1b 00 00 48 01 54 00 01 f7 01 ec 01 c5 01 .....H.T........ | 176: 0d 1a 00 00 48 01 54 00 01 f7 01 ec 01 c5 01 0d ....H.T......... | 192: 19 00 00 48 01 54 00 01 f7 01 ec 01 c5 01 0d 18 ...H.T.......... | 208: 00 00 48 01 54 00 01 f7 01 ec 01 c5 01 0d 17 00 ..H.T........... | 224: 00 48 01 54 00 01 f7 01 ec 01 c5 01 0d 16 00 00 .H.T............ | 240: 48 01 54 00 01 f7 01 ec 01 c5 01 0d 15 00 00 48 H.T............H | 256: 01 54 00 01 f7 01 ec 01 c5 01 0d 14 00 00 48 01 .T............H. | 272: 54 00 01 f7 01 ec 01 c5 01 0d 13 00 00 48 01 54 T............H.T | 288: 00 01 f7 01 ec 01 c5 01 0d 12 00 00 48 01 54 00 ............H.T. | 304: 01 f7 01 ec 01 c5 01 0d 11 00 00 48 01 54 00 01 ...........H.T.. | 320: f7 01 ec 01 c5 01 0d 10 00 00 48 01 54 00 01 f7 ..........H.T... | 336: 01 ec 01 c5 01 0d 0f 00 00 48 01 54 00 01 f7 01 .........H.T.... | 352: ec 01 c5 01 0d 0e 00 00 48 01 54 00 01 f7 01 ec ........H.T..... | 368: 01 c5 01 0d 0d 00 00 48 01 54 00 01 f7 01 ec 01 .......H.T...... | 384: c5 01 0d 0c 00 00 48 01 54 00 01 f7 01 ec 01 c5 ......H.T....... | 400: 01 0d 0b 00 00 48 01 54 00 01 f7 01 ec 01 c5 01 .....H.T........ | 416: 0d 0a 00 00 48 01 54 00 01 f7 01 ec 01 c5 01 0d ....H.T......... | 432: 09 00 00 48 01 54 00 01 f7 01 ec 01 c5 01 19 08 ...H.T.......... | 448: 05 17 17 17 17 65 69 67 68 74 65 69 67 68 74 73 .....eighteights | 464: 65 76 65 6e 73 65 76 65 6e 25 07 05 07 07 07 07 evenseven%...... | 480: 40 18 00 00 00 00 00 00 40 18 00 00 00 00 00 00 @.......@....... | 496: 40 14 00 00 00 00 00 00 40 14 00 00 00 00 00 00 @.......@....... | page 10 offset 4608 | 0: 0d 00 00 00 1d 00 4d 00 01 f1 01 e2 01 d3 01 c4 ......M......... | 16: 01 b5 01 a6 01 97 01 88 01 79 01 6a 01 5b 01 4c .........y.j.[.L | 32: 01 3d 01 2e 01 1f 01 10 01 01 00 f2 00 e3 00 d4 .=.............. | 48: 00 c5 00 b6 00 a7 00 98 00 89 00 7a 00 6b 00 5c ...........z.k.\ | 64: 00 4d 00 00 00 00 00 00 00 00 00 00 00 0d 3e 00 .M............>. | 80: 00 48 01 54 00 01 f7 01 ec 01 c5 01 0d 3d 00 00 .H.T.........=.. | 96: 48 01 54 00 01 f7 01 ec 01 c5 01 0d 3c 00 00 48 H.T.........<..H | 112: 01 54 00 01 f7 01 ec 01 c5 01 0d 3b 00 00 48 01 .T.........;..H. | 128: 54 00 01 f7 01 ec 01 c5 01 0d 3a 00 00 48 01 54 T.........:..H.T | 144: 00 01 f7 01 ec 01 c5 01 0d 39 00 00 48 01 54 00 .........9..H.T. | 160: 01 f7 01 ec 01 c5 01 0d 38 00 00 48 01 54 00 01 ........8..H.T.. | 176: f7 01 ec 01 c5 01 0d 37 00 00 48 01 54 00 01 f7 .......7..H.T... | 192: 01 ec 01 c5 01 0d 36 00 00 48 01 54 00 01 f7 01 ......6..H.T.... | 208: ec 01 c5 01 0d 35 00 00 48 01 54 00 01 f7 01 ec .....5..H.T..... | 224: 01 c5 01 0d 34 00 00 48 01 54 00 01 f7 01 ec 01 ....4..H.T...... | 240: c5 01 0d 33 00 00 48 01 54 00 01 f7 01 ec 01 c5 ...3..H.T....... | 256: 01 0d 32 00 00 48 01 54 00 01 f7 01 ec 01 c5 01 ..2..H.T........ | 272: 0d 31 00 00 48 01 54 00 01 f7 01 ec 01 c5 01 0d .1..H.T......... | 288: 30 00 00 48 01 54 00 01 f7 01 ec 01 c5 01 0d 2f 0..H.T........./ | 304: 00 00 48 01 54 00 01 f7 01 ec 01 c5 01 0d 2e 00 ..H.T........... | 320: 00 48 01 54 00 01 f7 01 ec 01 c5 01 0d 2d 00 00 .H.T.........-.. | 336: 48 01 54 00 01 f7 01 ec 01 c5 01 0d 2c 00 00 48 H.T.........,..H | 352: 01 54 00 01 f7 01 ec 01 c5 01 0d 2b 00 00 48 01 .T.........+..H. | 368: 54 00 01 f7 01 ec 01 c5 01 0d 2a 00 00 48 01 54 T.........*..H.T | 384: 00 01 f7 01 ec 01 c5 01 0d 29 00 00 48 01 54 00 .........)..H.T. | 400: 01 f7 01 ec 01 c5 01 0d 28 00 00 48 01 54 00 01 ........(..H.T.. | 416: f7 01 ec 01 c5 01 0d 27 00 00 48 01 54 00 01 f7 .......'..H.T... | 432: 01 ec 01 c5 01 0d 26 00 00 48 01 54 00 01 f7 01 ......&..H.T.... | 448: ec 01 c5 01 0d 25 00 00 48 01 54 00 01 f7 01 ec .....%..H.T..... | 464: 01 c5 01 0d 24 00 00 48 01 54 00 01 f7 01 ec 01 ....$..H.T...... | 480: c5 01 0d 23 00 00 48 01 54 00 01 f7 01 ec 01 c5 ...#..H.T....... | 496: 01 0d 22 00 00 48 01 54 00 01 f7 01 ec 01 c5 01 .."..H.T........ | page 11 offset 5120 | 0: 0d 00 00 00 0a 01 6a 00 01 f1 01 e2 01 d3 01 c4 ......j......... | 16: 01 b5 01 a6 01 97 01 88 01 79 01 6a 00 00 00 00 .........y.j.... | 352: 00 00 00 00 00 00 00 00 00 00 0d 48 00 00 48 01 ...........H..H. | 368: 54 00 01 f7 01 ec 01 c5 01 0d 47 00 00 48 01 54 T.........G..H.T | 384: 00 01 f7 01 ec 01 c5 01 0d 46 00 00 48 01 54 00 .........F..H.T. | 400: 01 f7 01 ec 01 c5 01 0d 45 00 00 48 01 54 00 01 ........E..H.T.. | 416: f7 01 ec 01 c5 01 0d 44 00 00 48 01 54 00 01 f7 .......D..H.T... | 432: 01 ec 01 c5 01 0d 43 00 00 48 01 54 00 01 f7 01 ......C..H.T.... | 448: ec 01 c5 01 0d 42 00 00 48 01 54 00 01 f7 01 ec .....B..H.T..... | 464: 01 c5 01 0d 41 00 00 48 01 54 00 01 f7 01 ec 01 ....A..H.T...... | 480: c5 01 0d 40 00 00 48 01 54 00 01 f7 01 ec 01 c5 ...@..H.T....... | 496: 01 0d 3f 00 00 48 01 54 00 01 f7 01 ec 01 c5 01 ..?..H.T........ | end c4.db }] db eval {PRAGMA integrity_check} } {/Fragmentation of 384 bytes reported as 0 on page 8/} # The DELETE query below deletes the very last cell from page 8. # Prior to a certain fix to sqlite3BtreeDelete() and because of the # corruption to the freeblock list on page 8, this would fail to # cause a rebalance operation, which would leave the btree in a weird # state that would lead to segfaults and or assertion faults. # do_execsql_test dbfuzz001-110 { DELETE FROM t3 WHERE x IS NOT NULL AND +rowid=6; } {} # This is a dbfuzz2-generate test case that can cause a page with # pPage->nCell==0 to enter the balancer. # do_test dbfuzz001-200 { db deserialize [decode_hexdb { | size 3076 pagesize 512 filename c03.db | page 1 offset 0 | 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3. | 16: 02 00 01 01 00 40 20 20 00 00 00 0c 00 00 00 07 .....@ ........ | 32: 00 00 00 00 00 00 00 00 00 00 00 08 00 00 00 04 ................ | 48: 00 00 00 00 00 00 00 03 e8 00 00 01 00 00 00 00 ................ | 80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0c ................ | 96: 00 2e 2c 50 0d 00 00 00 06 01 06 00 01 da 01 b0 ..,P............ | 112: 01 56 01 86 01 2a 01 06 00 00 00 00 00 00 00 00 .V...*.......... | 128: 00 00 00 00 00 00 00 00 ef 00 00 00 00 00 00 00 ................ | 192: 00 7f 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ | 224: 00 00 00 00 00 00 00 00 00 00 00 00 00 ff e9 00 ................ | 256: 00 00 00 00 00 00 22 07 06 17 11 11 01 31 74 61 ......"......1ta | 272: 62 6c 65 74 34 74 34 07 43 52 45 41 54 45 20 54 blet4t4.CREATE T | 288: 41 42 4c 45 20 74 34 28 78 29 2a 06 06 17 13 11 ABLE t4(x)*..... | 304: 01 3f 69 6e 64 65 78 74 33 78 74 33 06 43 52 45 .?indext3xt3.CRE | 320: 41 54 45 20 49 4e 44 45 58 20 74 33 64 20 4f 4e ATE INDEX t3d ON | 336: 20 74 33 28 78 29 2e 04 06 17 15 11 01 45 69 6e t3(x).......Ein | 352: 64 65 78 74 32 63 64 74 32 05 43 52 45 41 54 45 dext2cdt2.CREATE | 368: 20 49 4e 44 45 58 20 74 32 63 64 20 4f 4e 20 74 INDEX t2cd ON t | 384: 32 28 63 2c 64 29 28 05 06 17 11 11 01 3d 74 61 2(c,d)(......=ta | 400: 62 6c 65 74 33 74 33 04 43 52 45 41 54 45 20 54 blet3t3.CREATE T | 416: 41 42 4c 45 20 74 33 28 63 2c 78 2c 65 2c 66 29 ABLE t3(c,x,e,f) | 432: 28 02 06 17 11 11 01 3d 74 61 62 6c 65 74 32 74 (......=tablet2t | 448: 32 03 43 52 45 41 54 45 20 54 41 42 4c 45 20 74 2.CREATE TABLE t | 464: 32 28 63 2c 64 2c 65 2c 66 29 24 01 06 17 11 11 2(c,d,e,f)$..... | 480: 01 35 74 61 62 6c 65 74 31 74 31 02 43 52 45 41 .5tablet1t1.CREA | 496: 54 45 20 54 41 42 4c 45 20 74 31 28 61 2c 62 29 TE TABLE t1(a,b) | page 2 offset 512 | 0: 0d 00 00 00 04 01 cf 00 01 fa 01 f3 01 de 01 cf ................ | 176: 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ | 256: 00 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ | 368: 00 00 00 00 00 00 00 00 00 00 00 00 1e 00 00 00 ................ | 416: 00 00 00 1b 00 00 00 00 04 00 00 00 00 00 00 00 ................ | 448: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0d ................ | 464: 04 03 17 17 73 65 76 65 6e 65 69 67 68 74 13 03 ....seveneight.. | 480: 03 07 07 40 14 00 00 00 00 00 00 40 18 00 00 00 ...@.......@.... | 496: 00 00 00 05 02 03 01 01 03 04 04 01 03 09 01 02 ................ | page 3 offset 1024 | 0: 0d 00 00 00 08 01 54 00 01 f7 01 ec 01 c5 01 aa ......T......... | 16: 01 a1 01 96 01 6f 01 54 00 00 00 00 00 00 00 00 .....o.T........ | 32: 00 00 00 00 00 00 00 03 e8 00 00 00 00 00 00 00 ................ | 336: 00 00 00 00 19 08 05 16 17 17 17 65 69 67 68 74 ...........eight | 352: 65 69 67 68 74 73 65 76 65 6e 73 65 76 ff ff ff eightsevensev... | 368: 0e 05 07 07 07 07 40 18 00 00 00 00 00 00 40 18 ......@.......@. | 384: 00 00 00 00 00 00 40 14 00 00 00 00 00 00 40 14 ......@.......@. | 400: 00 00 00 00 00 00 09 06 05 01 01 01 01 04 04 03 ................ | 416: 03 07 05 05 01 01 09 09 02 02 19 04 05 17 17 17 ................ | 432: 17 73 65 6f 65 6e 65 69 67 68 74 65 69 67 68 74 .seoeneighteight | 448: 73 65 76 65 6e 25 03 05 07 07 07 07 40 14 00 00 seven%......@... | 464: 00 00 00 00 40 18 00 00 00 00 00 00 40 18 00 00 ....@.......@... | 480: 00 00 00 00 40 14 00 00 00 00 00 00 09 02 05 01 ....@........... | 496: 01 01 01 03 04 04 03 07 01 05 09 01 01 09 02 02 ................ | page 4 offset 1536 | 0: 0d 00 00 00 00 00 10 00 00 00 00 00 00 00 00 00 ................ | 160: 00 00 00 ea 00 00 00 00 00 00 00 00 00 00 00 00 ................ | 336: 00 00 00 00 00 00 00 00 00 00 00 00 20 00 00 00 ............ ... | page 5 offset 2048 | 0: 0a 00 00 00 08 01 96 00 01 fa 01 c4 01 f2 01 bc ................ | 16: 01 dc 01 a6 01 96 01 cc 00 00 00 00 00 00 00 00 ................ | 48: 00 00 00 00 00 00 00 00 00 00 10 00 00 00 00 00 ................ | 288: 00 00 00 00 00 00 00 00 00 64 00 00 00 2b 00 00 .........d...+.. | 400: 00 00 00 00 00 00 0f 04 17 17 01 65 69 67 68 74 ...........eight | 416: 65 69 6f 68 74 08 15 04 07 07 01 40 18 00 00 00 eioht......@.... | 432: 00 00 00 40 18 00 00 00 00 00 00 07 07 04 01 01 ...@............ | 448: 01 04 04 06 07 04 01 01 01 02 02 05 0f 04 17 17 ................ | 464: 01 73 65 76 65 6e 65 69 67 68 74 04 15 04 07 07 .seveneight..... | 480: 01 40 14 00 00 00 00 00 00 40 18 00 00 00 00 00 .@.......@...... | 496: 00 03 07 04 01 01 01 03 04 02 05 04 09 01 09 02 ................ | page 6 offset 2560 | 0: 0a 00 00 00 00 02 00 00 00 00 00 00 00 0d 00 00 ................ | 16: 00 08 01 c2 00 01 fb 01 f6 01 f1 01 ec 01 e0 01 ................ | 32: d4 01 cb 01 c2 00 00 00 00 00 00 00 00 00 00 00 ................ | 160: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 04 00 ................ | 448: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 07 ................ | 464: 08 02 17 65 69 67 68 74 07 07 02 17 65 69 67 68 ...eight....eigh | 480: 74 0a 06 02 07 40 18 00 00 00 00 00 00 0a 05 02 t....@.......... | 496: 07 40 18 00 04 02 01 04 03 03 02 01 04 03 02 02 .@.............. | end x/c03.db }] catchsql {INSERT INTO t3 SELECT * FROM t2;} } {1 {database disk image is malformed}} do_test dbfuzz001-110 { sqlite3 db {} db deserialize [decode_hexdb { | size 3584 pagesize 512 filename x/c02.db | page 1 offset 0 | 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3. | 16: 02 00 01 01 00 40 20 20 00 00 00 0c 00 00 00 07 .....@ ........ | 32: 00 00 00 00 00 00 00 00 00 00 00 08 00 00 00 04 ................ | 48: 00 00 00 00 00 00 00 04 00 00 00 01 00 00 00 00 ................ | 80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0c ................ | 96: 00 2e 2c 50 0d 00 00 00 06 01 06 00 01 da 01 b0 ..,P............ | 112: 01 56 01 86 01 2a 01 06 00 00 00 00 00 00 00 00 .V...*.......... | 256: 00 00 00 00 00 00 22 07 06 17 11 11 01 31 74 61 ......"......1ta | 272: 62 6c 65 74 34 74 34 07 43 52 45 41 54 45 20 54 blet4t4.CREATE T | 288: 41 42 4c 45 20 74 34 28 78 29 2a 06 06 17 13 11 ABLE t4(x)*..... | 304: 01 3f 69 6e 64 65 78 74 33 78 74 33 05 43 52 45 .?indext3xt3.CRE | 320: 41 54 45 20 49 4e 44 45 58 20 74 33 78 20 4f 4e ATE INDEX t3x ON | 336: 20 74 33 28 78 29 2e 04 06 17 15 11 01 45 69 6e t3(x).......Ein | 352: 64 65 78 74 32 63 64 74 32 05 43 52 45 41 54 45 dext2cdt2.CREATE | 368: 20 49 4e 44 45 58 20 74 32 63 64 20 4f 4e 20 74 INDEX t2cd ON t | 384: 32 28 63 2c 64 29 28 05 06 17 11 11 01 3d 74 61 2(c,d)(......=ta | 400: 62 6c 65 74 33 74 33 07 43 52 45 41 54 45 20 54 blet3t3.CREATE T | 416: 41 42 4c 45 20 74 33 28 63 2c 78 2c 65 2c 66 29 ABLE t3(c,x,e,f) | 432: 28 02 06 17 11 11 01 3d 74 61 74 65 6c 03 62 74 (......=tatel.bt | 448: 32 32 43 52 45 41 54 45 20 54 41 42 4c 45 20 74 22CREATE TABLE t | 464: 32 28 63 2c 64 2c 65 2c 66 29 24 01 06 17 11 11 2(c,d,e,f)$..... | 480: 01 35 74 61 62 6c 65 74 31 74 31 02 43 52 45 41 .5tablet1t1.CREA | 496: 54 45 20 54 41 42 4c 45 20 74 31 28 61 2c 62 29 TE TABLE t1(a,b) | page 2 offset 512 | 0: 0d 00 00 00 04 01 cf 00 01 fa 01 f3 01 de 01 cf ................ | 160: 00 00 20 00 00 00 00 00 00 00 00 00 00 00 00 00 .. ............. | 448: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0d ................ | 464: 04 03 17 17 73 65 76 65 6e 65 69 67 68 74 13 03 ....seveneight.. | 480: 03 07 07 40 14 00 00 00 00 00 00 40 18 00 00 00 ...@.......@.... | 496: 00 00 00 05 02 03 01 01 03 04 04 01 03 09 01 02 ................ | page 3 offset 1024 | 0: 0d 00 00 00 08 01 54 00 01 f7 01 ec 01 c5 01 aa ......T......... | 16: 01 a1 01 96 01 6f 01 54 00 00 00 00 00 00 00 00 .....o.T........ | 112: 00 00 dd 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ | 336: 00 00 00 00 19 08 05 17 17 17 17 65 69 67 68 74 ...........eight | 352: 65 69 67 68 74 73 65 76 65 6e 73 65 76 65 6e 25 eightsevenseven% | 368: 07 05 07 07 07 07 40 18 00 00 00 00 00 00 40 18 ......@.......@. | 384: 00 00 00 00 00 00 40 14 00 00 00 00 00 00 40 14 ......@.......@. | 400: 00 00 00 00 00 00 09 06 05 01 01 01 01 04 04 03 ................ | 416: 03 07 05 05 01 01 09 09 02 02 19 04 05 17 17 17 ................ | 432: 17 73 65 76 65 6e 65 69 67 68 74 65 69 67 68 74 .seveneighteight | 448: 73 65 76 65 6e 25 03 05 07 07 07 07 40 14 00 00 seven%......@... | 464: 00 00 00 00 40 18 00 00 00 00 00 00 40 18 00 00 ....@.......@... | 480: 00 00 00 00 40 14 00 00 00 00 00 00 09 02 05 01 ....@........... | 496: 01 01 01 03 04 04 03 07 01 05 09 01 01 09 02 02 ................ | page 4 offset 1536 | 0: 0d 00 00 00 00 02 00 00 00 00 00 00 00 00 00 00 ................ | 192: 00 00 00 00 00 00 7f 00 00 00 00 00 00 00 00 00 ................ | 208: 00 e5 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ | page 5 offset 2048 | 0: 0a 00 00 00 08 01 96 00 01 fa 01 c4 01 f2 01 bc ................ | 16: 01 dc 01 a6 01 96 01 cc 00 00 00 00 00 00 00 00 ................ | 240: 00 00 00 00 00 00 00 00 00 00 00 00 00 0e 00 00 ................ | 400: 00 00 00 00 00 00 0f 04 17 07 01 65 69 67 68 74 ...........eight | 416: 65 69 67 68 74 08 15 04 07 07 01 40 18 00 00 00 eight......@.... | 432: 00 00 00 40 18 00 00 00 00 00 00 07 07 04 01 01 ...@............ | 448: 01 04 04 06 07 04 01 01 01 02 02 05 0f 04 17 17 ................ | 464: 01 73 65 76 65 6e 65 69 67 68 74 04 15 04 07 07 .seveneight..... | 480: 01 40 14 00 00 00 00 00 00 40 18 00 00 00 00 00 .@.......@...... | 496: 00 03 07 04 01 01 01 03 04 02 05 04 09 01 09 02 ................ | page 6 offset 2560 | 0: 0a 00 00 00 00 02 00 00 00 00 00 00 00 00 00 00 ................ | 464: 00 00 00 00 00 00 00 00 00 00 7f 00 00 00 00 00 ................ | page 7 offset 3072 | 0: 0d 00 00 00 08 01 c2 00 01 fb 01 f6 01 f1 01 ec ................ | 16: 01 e0 01 d4 01 cb 01 c2 00 00 00 00 00 00 00 00 ................ | 448: 00 00 07 08 02 17 65 69 67 68 74 07 07 02 17 65 ......eight....e | 464: 69 67 68 74 0a 06 02 07 40 18 00 00 00 00 00 00 ight....@....... | 480: 0a 05 02 07 40 18 00 00 00 00 00 00 03 04 02 01 ....@........... | 496: 04 03 03 02 01 04 03 02 02 01 02 03 01 02 01 02 ................ | end x/c02.db }] execsql { DELETE FROM t3 WHERE x IN (SELECT x FROM t4); } } {} finish_test |
Added test/fuzz4.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 | # 2018-12-12 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: # # May you do good and not evil. # May you find forgiveness for yourself and forgive others. # May you share freely, never taking more than you give. # #*********************************************************************** # # Test cases found by Matthew Denton's fuzzer at Chrome. # set testdir [file dirname $argv0] source $testdir/tester.tcl do_execsql_test fuzz4-100 { CREATE TABLE Table0 (Col0 NOT NULL DEFAULT (CURRENT_TIME IS 1 > 1)); INSERT OR REPLACE INTO Table0 DEFAULT VALUES ; SELECT * FROM Table0; } {0} do_execsql_test fuzz4-110 { CREATE TABLE Table1( Col0 TEXT DEFAULT (CASE WHEN 1 IS 3530822107858468864 THEN 1 ELSE quote(1) IS 3530822107858468864 END) ); INSERT INTO Table1 DEFAULT VALUES; SELECT * FROM Table1; } {0} do_execsql_test fuzz4-200 { CREATE TABLE Table2a( Col0 NOT NULL DEFAULT (CURRENT_TIME IS 1 IS NOT 1 > 1) ); INSERT OR REPLACE INTO Table2a DEFAULT VALUES; SELECT * FROM Table2a; } {0} do_execsql_test fuzz4-210 { CREATE TABLE Table2b (Col0 NOT NULL DEFAULT (CURRENT_TIME IS NOT FALSE)) ; INSERT OR REPLACE INTO Table2b DEFAULT VALUES ; SELECT * FROM Table2b; } {1} do_execsql_test fuzz4-300 { CREATE TABLE Table3 (Col0 DEFAULT (CURRENT_TIMESTAMP BETWEEN 1 AND 1)); INSERT INTO Table3 DEFAULT VALUES; SELECT * FROM Table3; } {0} do_execsql_test fuzz4-400 { CREATE TABLE Table4 (Col0 DEFAULT (1 BETWEEN CURRENT_TIMESTAMP AND 1)); INSERT INTO Table4 DEFAULT VALUES; SELECT * FROM Table4; } {0} do_execsql_test fuzz4-500 { CREATE TABLE Table5 (Col0 DEFAULT (1 BETWEEN 1 AND CURRENT_TIMESTAMP)); INSERT INTO Table5 DEFAULT VALUES; SELECT * FROM Table5; } {1} do_execsql_test fuzz4-600 { CREATE TEMPORARY TABLE Table6( Col0 DEFAULT (CASE x'5d' WHEN 1 THEN CASE CURRENT_TIMESTAMP WHEN 1 THEN 1 ELSE 1 END ELSE CASE WHEN 1 THEN FALSE END END ) ); INSERT INTO temp.Table6 DEFAULT VALUES ; SELECT * FROM Table6; } {0} do_execsql_test fuzz4-610 { WITH TableX AS (SELECT DISTINCT * ORDER BY 1 , 1 COLLATE RTRIM) DELETE FROM Table6 WHERE Col0 || +8388608 ; SELECT * FROM Table6; } {} finish_test |
Changes to test/fuzzcheck.c.
︙ | ︙ | |||
443 444 445 446 447 448 449 | if( iOfst<0 || iOfst>=pVFile->sz ){ memset(pData, 0, iAmt); return SQLITE_IOERR_SHORT_READ; } if( iOfst+iAmt>pVFile->sz ){ memset(pData, 0, iAmt); iAmt = (int)(pVFile->sz - iOfst); | | | 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 | if( iOfst<0 || iOfst>=pVFile->sz ){ memset(pData, 0, iAmt); return SQLITE_IOERR_SHORT_READ; } if( iOfst+iAmt>pVFile->sz ){ memset(pData, 0, iAmt); iAmt = (int)(pVFile->sz - iOfst); memcpy(pData, pVFile->a + iOfst, iAmt); return SQLITE_IOERR_SHORT_READ; } memcpy(pData, pVFile->a + iOfst, iAmt); return SQLITE_OK; } static int inmemWrite( sqlite3_file *pFile, /* Write to this file */ |
︙ | ︙ |
Changes to test/fuzzdata7.db.
cannot compute difference between binary files
Changes to test/indexexpr2.test.
︙ | ︙ | |||
226 227 228 229 230 231 232 233 234 235 | SELECT sqlite_master.name FROM sqlite_master, explain('UPDATE t2 SET c=c+1, f=NULL') WHERE explain.opcode LIKE 'Open%' AND sqlite_master.rootpage=explain.p2 ORDER BY 1; } {t2 t2abc t2cd t2def} } finish_test | > > > > > > > > > > > > > > > > > > > | 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 | SELECT sqlite_master.name FROM sqlite_master, explain('UPDATE t2 SET c=c+1, f=NULL') WHERE explain.opcode LIKE 'Open%' AND sqlite_master.rootpage=explain.p2 ORDER BY 1; } {t2 t2abc t2cd t2def} } #------------------------------------------------------------------------- # Test that ticket [d96eba87] has been fixed. # do_execsql_test 5.0 { CREATE TABLE t5(a INTEGER, b INTEGER); INSERT INTO t5 VALUES(2, 4), (3, 9); } do_execsql_test 5.1 { SELECT * FROM t5 WHERE abs(a)=2 or abs(b)=9; } {2 4 3 9} do_execsql_test 5.2 { CREATE INDEX t5a ON t5( abs(a) ); CREATE INDEX t5b ON t5( abs(b) ); } do_execsql_test 5.4 { SELECT * FROM t5 WHERE abs(a)=2 or abs(b)=9; } {2 4 3 9} finish_test |
Added tool/dbtotxt.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 | /* ** Copyright 2008 D. Richard Hipp and Hipp, Wyrick & Company, Inc. ** All Rights Reserved ** ****************************************************************************** ** ** This file implements a stand-alone utility program that converts ** a binary file (usually an SQLite database) into a text format that ** is compact and friendly to human-readers. ** ** Usage: ** ** dbtotxt [--pagesize N] FILENAME ** ** The translation of the database appears on standard output. If the ** --pagesize command-line option is omitted, then the page size is taken ** from the database header. ** ** Compactness is achieved by suppressing lines of all zero bytes. This ** works well at compressing test databases that are mostly empty. But ** the output will probably be lengthy for a real database containing lots ** of real content. For maximum compactness, it is suggested that test ** databases be constructed with "zeroblob()" rather than "randomblob()" ** used for filler content and with "PRAGMA secure_delete=ON" selected to ** zero-out deleted content. */ #include <stdio.h> #include <string.h> #include <stdlib.h> /* Return true if the line is all zeros */ static int allZero(unsigned char *aLine){ int i; for(i=0; i<16 && aLine[i]==0; i++){} return i==16; } int main(int argc, char **argv){ int pgsz = 0; /* page size */ long szFile; /* Size of the input file in bytes */ FILE *in; /* Input file */ int i, j; /* Loop counters */ int nErr = 0; /* Number of errors */ const char *zInputFile = 0; /* Name of the input file */ const char *zBaseName = 0; /* Base name of the file */ int lastPage = 0; /* Last page number shown */ int iPage; /* Current page number */ unsigned char aLine[16]; /* A single line of the file */ unsigned char aHdr[100]; /* File header */ for(i=1; i<argc; i++){ if( argv[i][0]=='-' ){ const char *z = argv[i]; z++; if( z[0]=='-' ) z++; if( strcmp(z,"pagesize")==0 ){ i++; pgsz = atoi(argv[i]); if( pgsz<512 || pgsz>65536 || (pgsz&(pgsz-1))!=0 ){ fprintf(stderr, "Page size must be a power of two between" " 512 and 65536.\n"); nErr++; } continue; } fprintf(stderr, "Unknown option: %s\n", argv[i]); nErr++; }else if( zInputFile ){ fprintf(stderr, "Already using a different input file: [%s]\n", argv[i]); nErr++; }else{ zInputFile = argv[i]; } } if( zInputFile==0 ){ fprintf(stderr, "No input file specified.\n"); nErr++; } if( nErr ){ fprintf(stderr, "Usage: %s [--pagesize N] FILENAME\n", argv[0]); exit(1); } in = fopen(zInputFile, "rb"); if( in==0 ){ fprintf(stderr, "Cannot open input file [%s]\n", zInputFile); exit(1); } fseek(in, 0, SEEK_END); szFile = ftell(in); rewind(in); if( szFile<512 ){ fprintf(stderr, "File too short. Minimum size is 512 bytes.\n"); exit(1); } if( fread(aHdr, 100, 1, in)!=1 ){ fprintf(stderr, "Cannot read file header\n"); exit(1); } rewind(in); if( pgsz==0 ){ pgsz = (aHdr[16]<<8) | aHdr[17]; if( pgsz==1 ) pgsz = 65536; if( pgsz<512 || (pgsz&(pgsz-1))!=0 ){ fprintf(stderr, "Invalid page size in header: %d\n", pgsz); exit(1); } } zBaseName = zInputFile; for(i=0; zInputFile[i]; i++){ if( zInputFile[i]=='/' && zInputFile[i+1]!=0 ) zBaseName = zInputFile+1; } printf("| size %d pagesize %d filename %s\n",(int)szFile,pgsz,zBaseName); for(i=0; i<szFile; i+=16){ int got = (int)fread(aLine, 1, 16, in); if( got!=16 ){ static int once = 1; if( once ){ fprintf(stderr, "Could not read input file starting at byte %d\n", i+got); } memset(aLine+got, 0, 16-got); } if( allZero(aLine) ) continue; iPage = i/pgsz + 1; if( lastPage!=iPage ){ printf("| page %d offset %d\n", iPage, (iPage-1)*pgsz); lastPage = iPage; } printf("| %5d:", i-(iPage-1)*pgsz); for(j=0; j<16; j++) printf(" %02x", aLine[j]); printf(" "); for(j=0; j<16; j++){ char c = aLine[j]; fputc(c>=0x20 && c<=0x7e ? c : '.', stdout); } fputc('\n', stdout); } fclose(in); printf("| end %s\n", zBaseName); return 0; } |
Added tool/dbtotxt.md.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 | <h1 align="center">The dbtotxt Tool</h1> The dbtotxt utility program reads an SQLite database file and writes its raw binary content to screen as a hex dump for testing and debugging purposes. The hex-dump output is formatted in such a way as to be easily readable both by humans and by software. The dbtotxt utility has long been a part of the TH3 test suite. The output of dbtotxt can be embedded in TH3 test scripts and used to generate very specific database files, perhaps with deliberately introduced corruption. The cov1/corrupt*.test modules in TH3 make extensive use of dbtotxt. More recently (2018-12-13) the dbtotxt utility has been added to the SQLite core and the command-line shell (CLI) has been augmented to be able to read dbtotxt output. The CLI dot-command is: > .open --hexdb ?OPTIONAL-FILENAME? If the OPTIONAL-FILENAME is included, then content is read from that file. If OPTIONAL-FILENAME is omitted, then the text is taken from the input stream, terminated by the "| end" line of the dbtotxt text. This allows small test databases to be embedded directly in scripts. Consider this example: > .open --hexdb | size 8192 pagesize 4096 filename x9.db | page 1 offset 0 | 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3. | 16: 10 00 01 01 00 40 20 20 00 00 00 04 00 00 00 02 .....@ ........ | 32: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 04 ................ | 48: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 ................ | 80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 04 ................ | 96: 00 2e 30 38 0d 00 00 00 01 0f c0 00 0f c0 00 00 ..08............ | 4032: 3e 01 06 17 11 11 01 69 74 61 62 6c 65 74 31 74 >......itablet1t | 4048: 31 02 43 52 45 41 54 45 20 54 41 42 4c 45 20 74 1.CREATE TABLE t | 4064: 31 28 78 2c 79 20 44 45 46 41 55 4c 54 20 78 27 1(x,y DEFAULT x' | 4080: 66 66 27 2c 7a 20 44 45 46 41 55 4c 54 20 30 29 ff',z DEFAULT 0) | page 2 offset 4096 | 0: 0d 08 14 00 04 00 10 00 0e 05 0a 0f 04 15 00 10 ................ | 16: 88 02 03 05 90 04 0e 08 00 00 00 00 00 00 00 00 ................ | 1040: 00 00 00 00 ff 87 7c 02 05 8f 78 0e 08 00 00 00 ......|...x..... | 2064: 00 00 00 ff 0c 0a 01 fb 00 00 00 00 00 00 00 00 ................ | 2560: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 83 ................ | 2576: 78 01 05 87 70 0e 08 00 00 00 00 00 00 00 00 00 x...p........... | 3072: 00 00 00 00 00 00 00 00 00 ff 00 00 01 fb 00 00 ................ | 3584: 00 00 00 00 00 83 78 00 05 87 70 0e 08 00 00 00 ......x...p..... | 4080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ff ................ | end x9.db SELECT rowid FROM t1; PRAGMA integrity_check; You can run this script to see that the database file is correctly decoded and loaded. Furthermore, you can make subtle corruptions to the input database simply by editing the hexadecimal description, then rerun the script to verify that SQLite correctly handles the corruption. |