/ Check-in [fb3ee1b7]
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

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

Overview
Comment:Merge all the enhancements and bug fixes from trunk, since none are destablizing. Call this the second beta.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | branch-3.21
Files: files | file ages | folders
SHA3-256: fb3ee1b7cac09e4950e4f48b44c277e4f391cb6c8f069644732d2389ca653da4
User & Date: drh 2017-10-21 17:17:17
Context
2017-10-22
07:58
Avoid running tests that use sqlite_dbpage with SQLITE_OMIT_VIRTUAL_TABLE builds. check-in: 6dde8d61 user: dan tags: branch-3.21
2017-10-21
17:17
Merge all the enhancements and bug fixes from trunk, since none are destablizing. Call this the second beta. check-in: fb3ee1b7 user: drh tags: branch-3.21
14:17
Catch and avoid a 16-bit integer overflow on the number of columns in a common table expression. This fixes a problem found by OSS-Fuzz. The test case is in TH3. check-in: 6ee8cb6a user: drh tags: trunk
2017-10-14
19:58
Updates to the Makefiles for MSVC. Cherrypick of [ac8786f3f9f35cb6]. check-in: 92eb721f user: mistachkin tags: branch-3.21
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to Makefile.in.

   162    162   
   163    163   USE_AMALGAMATION = @USE_AMALGAMATION@
   164    164   
   165    165   # Object files for the SQLite library (non-amalgamation).
   166    166   #
   167    167   LIBOBJS0 = alter.lo analyze.lo attach.lo auth.lo \
   168    168            backup.lo bitvec.lo btmutex.lo btree.lo build.lo \
   169         -         callback.lo complete.lo ctime.lo date.lo dbstat.lo delete.lo \
          169  +         callback.lo complete.lo ctime.lo \
          170  +         date.lo dbpage.lo dbstat.lo delete.lo \
   170    171            expr.lo fault.lo fkey.lo \
   171    172            fts3.lo fts3_aux.lo fts3_expr.lo fts3_hash.lo fts3_icu.lo \
   172    173            fts3_porter.lo fts3_snippet.lo fts3_tokenizer.lo fts3_tokenizer1.lo \
   173    174            fts3_tokenize_vtab.lo \
   174    175            fts3_unicode.lo fts3_unicode2.lo fts3_write.lo \
   175    176   	 fts5.lo \
   176    177            func.lo global.lo hash.lo \
................................................................................
   211    212     $(TOP)/src/btree.h \
   212    213     $(TOP)/src/btreeInt.h \
   213    214     $(TOP)/src/build.c \
   214    215     $(TOP)/src/callback.c \
   215    216     $(TOP)/src/complete.c \
   216    217     $(TOP)/src/ctime.c \
   217    218     $(TOP)/src/date.c \
          219  +  $(TOP)/src/dbpage.c \
   218    220     $(TOP)/src/dbstat.c \
   219    221     $(TOP)/src/delete.c \
   220    222     $(TOP)/src/expr.c \
   221    223     $(TOP)/src/fault.c \
   222    224     $(TOP)/src/fkey.c \
   223    225     $(TOP)/src/func.c \
   224    226     $(TOP)/src/global.c \
................................................................................
   390    392     $(TOP)/src/test_fs.c \
   391    393     $(TOP)/src/test_func.c \
   392    394     $(TOP)/src/test_hexio.c \
   393    395     $(TOP)/src/test_init.c \
   394    396     $(TOP)/src/test_intarray.c \
   395    397     $(TOP)/src/test_journal.c \
   396    398     $(TOP)/src/test_malloc.c \
          399  +  $(TOP)/src/test_md5.c \
   397    400     $(TOP)/src/test_multiplex.c \
   398    401     $(TOP)/src/test_mutex.c \
   399    402     $(TOP)/src/test_onefile.c \
   400    403     $(TOP)/src/test_osinst.c \
   401    404     $(TOP)/src/test_pcache.c \
   402    405     $(TOP)/src/test_quota.c \
   403    406     $(TOP)/src/test_rtree.c \
   404    407     $(TOP)/src/test_schema.c \
   405    408     $(TOP)/src/test_server.c \
   406    409     $(TOP)/src/test_superlock.c \
   407    410     $(TOP)/src/test_syscall.c \
          411  +  $(TOP)/src/test_tclsh.c \
   408    412     $(TOP)/src/test_tclvar.c \
   409    413     $(TOP)/src/test_thread.c \
   410    414     $(TOP)/src/test_vfs.c \
   411    415     $(TOP)/src/test_windirent.c \
   412    416     $(TOP)/src/test_wsd.c       \
   413    417     $(TOP)/ext/fts3/fts3_term.c \
   414    418     $(TOP)/ext/fts3/fts3_test.c  \
................................................................................
   446    450     $(TOP)/src/attach.c \
   447    451     $(TOP)/src/backup.c \
   448    452     $(TOP)/src/bitvec.c \
   449    453     $(TOP)/src/btree.c \
   450    454     $(TOP)/src/build.c \
   451    455     $(TOP)/src/ctime.c \
   452    456     $(TOP)/src/date.c \
          457  +  $(TOP)/src/dbpage.c \
   453    458     $(TOP)/src/dbstat.c \
   454    459     $(TOP)/src/expr.c \
   455    460     $(TOP)/src/func.c \
   456    461     $(TOP)/src/insert.c \
   457    462     $(TOP)/src/wal.c \
   458    463     $(TOP)/src/main.c \
   459    464     $(TOP)/src/mem5.c \
................................................................................
   566    571   # Extra compiler options for various shell tools
   567    572   #
   568    573   SHELL_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS4
   569    574   # SHELL_OPT += -DSQLITE_ENABLE_FTS5
   570    575   SHELL_OPT += -DSQLITE_ENABLE_EXPLAIN_COMMENTS
   571    576   SHELL_OPT += -DSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
   572    577   SHELL_OPT += -DSQLITE_ENABLE_STMTVTAB
          578  +SHELL_OPT += -DSQLITE_ENABLE_DBPAGE_VTAB
          579  +SHELL_OPT += -DSQLITE_ENABLE_DBSTAT_VTAB
   573    580   FUZZERSHELL_OPT = -DSQLITE_ENABLE_JSON1
   574    581   FUZZCHECK_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5 -DSQLITE_OSS_FUZZ
   575    582   FUZZCHECK_OPT += -DSQLITE_MAX_MEMORY=50000000
   576    583   FUZZCHECK_SRC = $(TOP)/test/fuzzcheck.c $(TOP)/test/ossfuzz.c
   577    584   DBFUZZ_OPT = 
   578    585   
   579    586   # This is the default Makefile target.  The objects listed here
................................................................................
   749    756   
   750    757   ctime.lo:	$(TOP)/src/ctime.c $(HDR)
   751    758   	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/ctime.c
   752    759   
   753    760   date.lo:	$(TOP)/src/date.c $(HDR)
   754    761   	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/date.c
   755    762   
          763  +dbpage.lo:	$(TOP)/src/dbpage.c $(HDR)
          764  +	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/dbpage.c
          765  +
   756    766   dbstat.lo:	$(TOP)/src/dbstat.c $(HDR)
   757    767   	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/dbstat.c
   758    768   
   759    769   delete.lo:	$(TOP)/src/delete.c $(HDR)
   760    770   	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/delete.c
   761    771   
   762    772   expr.lo:	$(TOP)/src/expr.c $(HDR)
................................................................................
   933    943   whereexpr.lo:	$(TOP)/src/whereexpr.c $(HDR)
   934    944   	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/whereexpr.c
   935    945   
   936    946   tclsqlite.lo:	$(TOP)/src/tclsqlite.c $(HDR)
   937    947   	$(LTCOMPILE) -DUSE_TCL_STUBS=1 -c $(TOP)/src/tclsqlite.c
   938    948   
   939    949   tclsqlite-shell.lo:	$(TOP)/src/tclsqlite.c $(HDR)
   940         -	$(LTCOMPILE) -DTCLSH=1 -o $@ -c $(TOP)/src/tclsqlite.c
          950  +	$(LTCOMPILE) -DTCLSH -o $@ -c $(TOP)/src/tclsqlite.c
   941    951   
   942    952   tclsqlite-stubs.lo:	$(TOP)/src/tclsqlite.c $(HDR)
   943    953   	$(LTCOMPILE) -DUSE_TCL_STUBS=1 -o $@ -c $(TOP)/src/tclsqlite.c
   944    954   
   945    955   tclsqlite3$(TEXE):	tclsqlite-shell.lo libsqlite3.la
   946    956   	$(LTLINK) -o $@ tclsqlite-shell.lo \
   947    957   		 libsqlite3.la $(LIBTCL)
................................................................................
  1099   1109   # Rules to build the 'testfixture' application.
  1100   1110   #
  1101   1111   # If using the amalgamation, use sqlite3.c directly to build the test
  1102   1112   # fixture.  Otherwise link against libsqlite3.la.  (This distinction is
  1103   1113   # necessary because the test fixture requires non-API symbols which are
  1104   1114   # hidden when the library is built via the amalgamation).
  1105   1115   #
  1106         -TESTFIXTURE_FLAGS  = -DTCLSH=1 -DSQLITE_TEST=1 -DSQLITE_CRASH_TEST=1
         1116  +TESTFIXTURE_FLAGS  = -DSQLITE_TEST=1 -DSQLITE_CRASH_TEST=1
         1117  +TESTFIXTURE_FLAGS += -DTCLSH_INIT_PROC=sqlite3TestInit
  1107   1118   TESTFIXTURE_FLAGS += -DSQLITE_SERVER=1 -DSQLITE_PRIVATE="" -DSQLITE_CORE 
  1108   1119   TESTFIXTURE_FLAGS += -DBUILD_sqlite
  1109   1120   TESTFIXTURE_FLAGS += -DSQLITE_SERIES_CONSTRAINT_VERIFY=1
  1110   1121   TESTFIXTURE_FLAGS += -DSQLITE_DEFAULT_PAGE_SIZE=1024
  1111   1122   TESTFIXTURE_FLAGS += -DSQLITE_ENABLE_STMTVTAB
         1123  +TESTFIXTURE_FLAGS += -DSQLITE_ENABLE_DBPAGE_VTAB
  1112   1124   
  1113   1125   TESTFIXTURE_SRC0 = $(TESTSRC2) libsqlite3.la
  1114   1126   TESTFIXTURE_SRC1 = sqlite3.c
  1115   1127   TESTFIXTURE_SRC = $(TESTSRC) $(TOP)/src/tclsqlite.c
  1116   1128   TESTFIXTURE_SRC += $(TESTFIXTURE_SRC$(USE_AMALGAMATION))
  1117   1129   
  1118   1130   testfixture$(TEXE):	$(TESTFIXTURE_SRC)
................................................................................
  1165   1177   # A very fast test that checks basic sanity.  The name comes from
  1166   1178   # the 60s-era electronics testing:  "Turn it on and see if smoke
  1167   1179   # comes out."
  1168   1180   #
  1169   1181   smoketest:	$(TESTPROGS) fuzzcheck$(TEXE)
  1170   1182   	./testfixture$(TEXE) $(TOP)/test/main.test $(TESTOPTS)
  1171   1183   
  1172         -sqlite3_analyzer.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/spaceanal.tcl
  1173         -	echo "#define TCLSH 2" > $@
  1174         -	echo "#define SQLITE_ENABLE_DBSTAT_VTAB 1" >> $@
  1175         -	cat sqlite3.c $(TOP)/src/tclsqlite.c >> $@
  1176         -	echo "static const char *tclsh_main_loop(void){" >> $@
  1177         -	echo "static const char *zMainloop = " >> $@
  1178         -	$(TCLSH_CMD) $(TOP)/tool/tostr.tcl $(TOP)/tool/spaceanal.tcl >> $@
  1179         -	echo "; return zMainloop; }" >> $@
         1184  +sqlite3_analyzer.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/spaceanal.tcl $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqlite3_analyzer.c.in
         1185  +	$(TCLSH_CMD) $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqlite3_analyzer.c.in >sqlite3_analyzer.c
  1180   1186   
  1181   1187   sqlite3_analyzer$(TEXE): sqlite3_analyzer.c
  1182   1188   	$(LTLINK) sqlite3_analyzer.c -o $@ $(LIBTCL) $(TLIBS)
  1183   1189   
  1184   1190   dbdump$(TEXE): $(TOP)/ext/misc/dbdump.c sqlite3.lo
  1185   1191   	$(LTLINK) -DDBDUMP_STANDALONE -o $@ \
  1186   1192              $(TOP)/ext/misc/dbdump.c sqlite3.lo $(TLIBS)

Changes to Makefile.msc.

  1087   1087   ###############################################################################
  1088   1088   
  1089   1089   # <<mark>>
  1090   1090   # Object files for the SQLite library (non-amalgamation).
  1091   1091   #
  1092   1092   LIBOBJS0 = vdbe.lo parse.lo alter.lo analyze.lo attach.lo auth.lo \
  1093   1093            backup.lo bitvec.lo btmutex.lo btree.lo build.lo \
  1094         -         callback.lo complete.lo ctime.lo date.lo dbstat.lo delete.lo \
         1094  +         callback.lo complete.lo ctime.lo \
         1095  +         date.lo dbpage.lo dbstat.lo delete.lo \
  1095   1096            expr.lo fault.lo fkey.lo \
  1096   1097            fts3.lo fts3_aux.lo fts3_expr.lo fts3_hash.lo fts3_icu.lo \
  1097   1098            fts3_porter.lo fts3_snippet.lo fts3_tokenizer.lo fts3_tokenizer1.lo \
  1098   1099            fts3_tokenize_vtab.lo fts3_unicode.lo fts3_unicode2.lo fts3_write.lo \
  1099   1100            fts5.lo \
  1100   1101            func.lo global.lo hash.lo \
  1101   1102            icu.lo insert.lo legacy.lo loadext.lo \
................................................................................
  1150   1151     $(TOP)\src\btmutex.c \
  1151   1152     $(TOP)\src\btree.c \
  1152   1153     $(TOP)\src\build.c \
  1153   1154     $(TOP)\src\callback.c \
  1154   1155     $(TOP)\src\complete.c \
  1155   1156     $(TOP)\src\ctime.c \
  1156   1157     $(TOP)\src\date.c \
         1158  +  $(TOP)\src\dbpage.c \
  1157   1159     $(TOP)\src\dbstat.c \
  1158   1160     $(TOP)\src\delete.c \
  1159   1161     $(TOP)\src\expr.c \
  1160   1162     $(TOP)\src\fault.c \
  1161   1163     $(TOP)\src\fkey.c \
  1162   1164     $(TOP)\src\func.c \
  1163   1165     $(TOP)\src\global.c \
................................................................................
  1368   1370     $(TOP)\src\test_fs.c \
  1369   1371     $(TOP)\src\test_func.c \
  1370   1372     $(TOP)\src\test_hexio.c \
  1371   1373     $(TOP)\src\test_init.c \
  1372   1374     $(TOP)\src\test_intarray.c \
  1373   1375     $(TOP)\src\test_journal.c \
  1374   1376     $(TOP)\src\test_malloc.c \
         1377  +  $(TOP)\src\test_md5.c \
  1375   1378     $(TOP)\src\test_multiplex.c \
  1376   1379     $(TOP)\src\test_mutex.c \
  1377   1380     $(TOP)\src\test_onefile.c \
  1378   1381     $(TOP)\src\test_osinst.c \
  1379   1382     $(TOP)\src\test_pcache.c \
  1380   1383     $(TOP)\src\test_quota.c \
  1381   1384     $(TOP)\src\test_rtree.c \
  1382   1385     $(TOP)\src\test_schema.c \
  1383   1386     $(TOP)\src\test_server.c \
  1384   1387     $(TOP)\src\test_superlock.c \
  1385   1388     $(TOP)\src\test_syscall.c \
         1389  +  $(TOP)\src\test_tclsh.c \
  1386   1390     $(TOP)\src\test_tclvar.c \
  1387   1391     $(TOP)\src\test_thread.c \
  1388   1392     $(TOP)\src\test_vfs.c \
  1389   1393     $(TOP)\src\test_windirent.c \
  1390   1394     $(TOP)\src\test_wsd.c \
  1391   1395     $(TOP)\ext\fts3\fts3_term.c \
  1392   1396     $(TOP)\ext\fts3\fts3_test.c \
................................................................................
  1501   1505   # <</mark>>
  1502   1506   
  1503   1507   # Additional compiler options for the shell.  These are only effective
  1504   1508   # when the shell is not being dynamically linked.
  1505   1509   #
  1506   1510   !IF $(DYNAMIC_SHELL)==0 && $(FOR_WIN10)==0
  1507   1511   SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_STMTVTAB
         1512  +SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_DBPAGE_VTAB -DSQLITE_ENABLE_DBSTAT_VTAB
  1508   1513   !ENDIF
  1509   1514   
  1510   1515   # <<mark>>
  1511   1516   # Extra compiler options for various test tools.
  1512   1517   #
  1513   1518   MPTESTER_COMPILE_OPTS = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS5
  1514   1519   FUZZERSHELL_COMPILE_OPTS = -DSQLITE_ENABLE_JSON1
................................................................................
  1738   1743   
  1739   1744   ctime.lo:	$(TOP)\src\ctime.c $(HDR)
  1740   1745   	$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\ctime.c
  1741   1746   
  1742   1747   date.lo:	$(TOP)\src\date.c $(HDR)
  1743   1748   	$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\date.c
  1744   1749   
  1745         -dbstat.lo:	$(TOP)\src\date.c $(HDR)
         1750  +dbpage.lo:	$(TOP)\src\dbpage.c $(HDR)
         1751  +	$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\dbpage.c
         1752  +
         1753  +dbstat.lo:	$(TOP)\src\dbstat.c $(HDR)
  1746   1754   	$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\dbstat.c
  1747   1755   
  1748   1756   delete.lo:	$(TOP)\src\delete.c $(HDR)
  1749   1757   	$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\delete.c
  1750   1758   
  1751   1759   expr.lo:	$(TOP)\src\expr.c $(HDR)
  1752   1760   	$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\expr.c
................................................................................
  1922   1930   whereexpr.lo:	$(TOP)\src\whereexpr.c $(HDR)
  1923   1931   	$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\whereexpr.c
  1924   1932   
  1925   1933   tclsqlite.lo:	$(TOP)\src\tclsqlite.c $(HDR) $(SQLITE_TCL_DEP)
  1926   1934   	$(LTCOMPILE) $(NO_WARN) -DUSE_TCL_STUBS=1 -DBUILD_sqlite -I$(TCLINCDIR) -c $(TOP)\src\tclsqlite.c
  1927   1935   
  1928   1936   tclsqlite-shell.lo:	$(TOP)\src\tclsqlite.c $(HDR) $(SQLITE_TCL_DEP)
  1929         -	$(LTCOMPILE) $(NO_WARN) -DTCLSH=1 -DBUILD_sqlite -I$(TCLINCDIR) -c $(TOP)\src\tclsqlite.c
         1937  +	$(LTCOMPILE) $(NO_WARN) -DTCLSH -DBUILD_sqlite -I$(TCLINCDIR) -c $(TOP)\src\tclsqlite.c
  1930   1938   
  1931   1939   tclsqlite3.exe:	tclsqlite-shell.lo $(SQLITE3C) $(SQLITE3H) $(LIBRESOBJS)
  1932   1940   	$(LTLINK) $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) /OUT:$@ tclsqlite-shell.lo $(LIBRESOBJS) $(LTLIBS) $(TLIBS)
  1933   1941   
  1934   1942   # Rules to build opcodes.c and opcodes.h
  1935   1943   #
  1936   1944   opcodes.c:	opcodes.h $(TOP)\tool\mkopcodec.tcl
................................................................................
  2093   2101   # Rules to build the 'testfixture' application.
  2094   2102   #
  2095   2103   # If using the amalgamation, use sqlite3.c directly to build the test
  2096   2104   # fixture.  Otherwise link against libsqlite3.lib.  (This distinction is
  2097   2105   # necessary because the test fixture requires non-API symbols which are
  2098   2106   # hidden when the library is built via the amalgamation).
  2099   2107   #
  2100         -TESTFIXTURE_FLAGS = -DTCLSH=1 -DSQLITE_TEST=1 -DSQLITE_CRASH_TEST=1
         2108  +TESTFIXTURE_FLAGS = -DTCLSH_INIT_PROC=sqlite3TestInit -DSQLITE_TEST=1 -DSQLITE_CRASH_TEST=1
  2101   2109   TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_SERVER=1 -DSQLITE_PRIVATE=""
  2102   2110   TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_CORE $(NO_WARN)
  2103   2111   TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_SERIES_CONSTRAINT_VERIFY=1
  2104   2112   TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_DEFAULT_PAGE_SIZE=1024
  2105   2113   TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_ENABLE_STMTVTAB
         2114  +TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_ENABLE_DBPAGE_VTAB
  2106   2115   TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) $(TEST_CCONV_OPTS)
  2107   2116   
  2108   2117   TESTFIXTURE_SRC0 = $(TESTEXT) $(TESTSRC2)
  2109   2118   TESTFIXTURE_SRC1 = $(TESTEXT) $(SQLITE3C)
  2110   2119   !IF $(USE_AMALGAMATION)==0
  2111   2120   TESTFIXTURE_SRC = $(TESTSRC) $(TOP)\src\tclsqlite.c $(TESTFIXTURE_SRC0)
  2112   2121   !ELSE
................................................................................
  2178   2187   	@set PATH=$(LIBTCLPATH);$(PATH)
  2179   2188   	.\testfixture.exe $(TOP)\test\veryquick.test $(TESTOPTS)
  2180   2189   
  2181   2190   smoketest:	$(TESTPROGS)
  2182   2191   	@set PATH=$(LIBTCLPATH);$(PATH)
  2183   2192   	.\testfixture.exe $(TOP)\test\main.test $(TESTOPTS)
  2184   2193   
  2185         -sqlite3_analyzer.c:	$(SQLITE3C) $(SQLITE3H) $(TOP)\src\tclsqlite.c $(TOP)\tool\spaceanal.tcl $(SQLITE_TCL_DEP)
  2186         -	echo #define TCLSH 2 > $@
  2187         -	echo #define SQLITE_ENABLE_DBSTAT_VTAB 1 >> $@
  2188         -	copy $@ + $(SQLITE3C) + $(TOP)\src\tclsqlite.c $@
  2189         -	echo static const char *tclsh_main_loop(void){ >> $@
  2190         -	echo static const char *zMainloop = >> $@
  2191         -	$(TCLSH_CMD) $(TOP)\tool\tostr.tcl $(TOP)\tool\spaceanal.tcl >> $@
  2192         -	echo ; return zMainloop; } >> $@
         2194  +sqlite3_analyzer.c:	$(SQLITE3C) $(SQLITE3H) $(TOP)\src\tclsqlite.c $(TOP)\tool\spaceanal.tcl $(TOP)\tool\mkccode.tcl $(TOP)\tool\sqlite3_analyzer.c.in $(SQLITE_TCL_DEP)
         2195  +	$(TCLSH_CMD) $(TOP)\tool\mkccode.tcl $(TOP)\tool\sqlite3_analyzer.c.in > $@
  2193   2196   
  2194   2197   sqlite3_analyzer.exe:	sqlite3_analyzer.c $(LIBRESOBJS)
  2195   2198   	$(LTLINK) $(NO_WARN) -DBUILD_sqlite -I$(TCLINCDIR) sqlite3_analyzer.c \
  2196   2199   		/link $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LTLIBS) $(TLIBS)
  2197   2200   
  2198   2201   dbdump.exe:	$(TOP)\ext\misc\dbdump.c $(SQLITE3C) $(SQLITE3H)
  2199   2202   	$(LTLINK) $(NO_WARN) -DDBDUMP_STANDALONE $(TOP)\ext\misc\dbdump.c $(SQLITE3C) \

Changes to autoconf/Makefile.msc.

   924    924   
   925    925   
   926    926   # Additional compiler options for the shell.  These are only effective
   927    927   # when the shell is not being dynamically linked.
   928    928   #
   929    929   !IF $(DYNAMIC_SHELL)==0 && $(FOR_WIN10)==0
   930    930   SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_STMTVTAB
          931  +SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_DBPAGE_VTAB -DSQLITE_ENABLE_DBSTAT_VTAB
   931    932   !ENDIF
   932    933   
   933    934   
   934    935   # This is the default Makefile target.  The objects listed here
   935    936   # are what get build when you type just "make" with no arguments.
   936    937   #
   937    938   all:	dll shell

Added ext/repair/README.md.

            1  +This folder contains extensions and utility programs intended to analyze
            2  +live database files, detect problems, and possibly fix them.
            3  +
            4  +As SQLite is being used on larger and larger databases, database sizes
            5  +are growing into the terabyte range.  At that size, hardware malfunctions
            6  +and/or cosmic rays will occasionally corrupt a database file.  Detecting 
            7  +problems and fixing errors a terabyte-sized databases can take hours or days,
            8  +and it is undesirable to take applications that depend on the databases 
            9  +off-line for such a long time.
           10  +The utilities in the folder are intended to provide mechanisms for
           11  +detecting and fixing problems in large databases while those databases
           12  +are in active use.
           13  +
           14  +The utilities and extensions in this folder are experimental and under
           15  +active development at the time of this writing (2017-10-12).  If and when
           16  +they stabilize, this README will be updated to reflect that fact.

Added ext/repair/checkfreelist.c.

            1  +/*
            2  +** 2017 October 11
            3  +**
            4  +** The author disclaims copyright to this source code.  In place of
            5  +** a legal notice, here is a blessing:
            6  +**
            7  +**    May you do good and not evil.
            8  +**    May you find forgiveness for yourself and forgive others.
            9  +**    May you share freely, never taking more than you give.
           10  +**
           11  +*************************************************************************
           12  +**
           13  +** This module exports a single C function:
           14  +**
           15  +**   int sqlite3_check_freelist(sqlite3 *db, const char *zDb);
           16  +**
           17  +** This function checks the free-list in database zDb (one of "main", 
           18  +** "temp", etc.) and reports any errors by invoking the sqlite3_log()
           19  +** function. It returns SQLITE_OK if successful, or an SQLite error
           20  +** code otherwise. It is not an error if the free-list is corrupted but
           21  +** no IO or OOM errors occur.
           22  +**
           23  +** If this file is compiled and loaded as an SQLite loadable extension,
           24  +** it adds an SQL function "checkfreelist" to the database handle, to
           25  +** be invoked as follows:
           26  +**
           27  +**   SELECT checkfreelist(<database-name>);
           28  +**
           29  +** This function performs the same checks as sqlite3_check_freelist(),
           30  +** except that it returns all error messages as a single text value,
           31  +** separated by newline characters. If the freelist is not corrupted
           32  +** in any way, an empty string is returned.
           33  +**
           34  +** To compile this module for use as an SQLite loadable extension:
           35  +**
           36  +**   gcc -Os -fPIC -shared checkfreelist.c -o checkfreelist.so
           37  +*/
           38  +
           39  +#include "sqlite3ext.h"
           40  +SQLITE_EXTENSION_INIT1
           41  +
           42  +#ifndef SQLITE_AMALGAMATION
           43  +# include <string.h>
           44  +# include <stdio.h>
           45  +# include <stdlib.h>
           46  +# include <assert.h>
           47  +# define ALWAYS(X)  1
           48  +# define NEVER(X)   0
           49  +  typedef unsigned char u8;
           50  +  typedef unsigned short u16;
           51  +  typedef unsigned int u32;
           52  +#define get4byte(x) (        \
           53  +    ((u32)((x)[0])<<24) +    \
           54  +    ((u32)((x)[1])<<16) +    \
           55  +    ((u32)((x)[2])<<8) +     \
           56  +    ((u32)((x)[3]))          \
           57  +)
           58  +#endif
           59  +
           60  +/*
           61  +** Execute a single PRAGMA statement and return the integer value returned
           62  +** via output parameter (*pnOut).
           63  +**
           64  +** The SQL statement passed as the third argument should be a printf-style
           65  +** format string containing a single "%s" which will be replace by the
           66  +** value passed as the second argument. e.g.
           67  +**
           68  +**   sqlGetInteger(db, "main", "PRAGMA %s.page_count", pnOut)
           69  +**
           70  +** executes "PRAGMA main.page_count" and stores the results in (*pnOut).
           71  +*/
           72  +static int sqlGetInteger(
           73  +  sqlite3 *db,                    /* Database handle */
           74  +  const char *zDb,                /* Database name ("main", "temp" etc.) */
           75  +  const char *zFmt,               /* SQL statement format */
           76  +  u32 *pnOut                      /* OUT: Integer value */
           77  +){
           78  +  int rc, rc2;
           79  +  char *zSql;
           80  +  sqlite3_stmt *pStmt = 0;
           81  +  int bOk = 0;
           82  +
           83  +  zSql = sqlite3_mprintf(zFmt, zDb);
           84  +  if( zSql==0 ){
           85  +    rc = SQLITE_NOMEM;
           86  +  }else{
           87  +    rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
           88  +    sqlite3_free(zSql);
           89  +  }
           90  +
           91  +  if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
           92  +    *pnOut = (u32)sqlite3_column_int(pStmt, 0);
           93  +    bOk = 1;
           94  +  }
           95  +
           96  +  rc2 = sqlite3_finalize(pStmt);
           97  +  if( rc==SQLITE_OK ) rc = rc2;
           98  +  if( rc==SQLITE_OK && bOk==0 ) rc = SQLITE_ERROR;
           99  +  return rc;
          100  +}
          101  +
          102  +/*
          103  +** Argument zFmt must be a printf-style format string and must be 
          104  +** followed by its required arguments. If argument pzOut is NULL, 
          105  +** then the results of printf()ing the format string are passed to
          106  +** sqlite3_log(). Otherwise, they are appended to the string
          107  +** at (*pzOut).
          108  +*/
          109  +static int checkFreelistError(char **pzOut, const char *zFmt, ...){
          110  +  int rc = SQLITE_OK;
          111  +  char *zErr = 0;
          112  +  va_list ap;
          113  +
          114  +  va_start(ap, zFmt);
          115  +  zErr = sqlite3_vmprintf(zFmt, ap);
          116  +  if( zErr==0 ){
          117  +    rc = SQLITE_NOMEM;
          118  +  }else{
          119  +    if( pzOut ){
          120  +      *pzOut = sqlite3_mprintf("%s%z%s", *pzOut?"\n":"", *pzOut, zErr);
          121  +      if( *pzOut==0 ) rc = SQLITE_NOMEM;
          122  +    }else{
          123  +      sqlite3_log(SQLITE_ERROR, "checkfreelist: %s", zErr);
          124  +    }
          125  +    sqlite3_free(zErr);
          126  +  }
          127  +  va_end(ap);
          128  +  return rc;
          129  +}
          130  +
          131  +static int checkFreelist(
          132  +  sqlite3 *db, 
          133  +  const char *zDb,
          134  +  char **pzOut
          135  +){
          136  +  /* This query returns one row for each page on the free list. Each row has
          137  +  ** two columns - the page number and page content.  */
          138  +  const char *zTrunk = 
          139  +    "WITH freelist_trunk(i, d, n) AS ("
          140  +      "SELECT 1, NULL, sqlite_readint32(data, 32) "
          141  +      "FROM sqlite_dbpage(:1) WHERE pgno=1 "
          142  +        "UNION ALL "
          143  +      "SELECT n, data, sqlite_readint32(data) "
          144  +      "FROM freelist_trunk, sqlite_dbpage(:1) WHERE pgno=n "
          145  +    ")"
          146  +    "SELECT i, d FROM freelist_trunk WHERE i!=1;";
          147  +
          148  +  int rc, rc2;                    /* Return code */
          149  +  sqlite3_stmt *pTrunk = 0;       /* Compilation of zTrunk */
          150  +  u32 nPage = 0;                  /* Number of pages in db */
          151  +  u32 nExpected = 0;              /* Expected number of free pages */
          152  +  u32 nFree = 0;                  /* Number of pages on free list */
          153  +
          154  +  if( zDb==0 ) zDb = "main";
          155  +
          156  +  if( (rc = sqlGetInteger(db, zDb, "PRAGMA %s.page_count", &nPage))
          157  +   || (rc = sqlGetInteger(db, zDb, "PRAGMA %s.freelist_count", &nExpected))
          158  +  ){
          159  +    return rc;
          160  +  }
          161  +
          162  +  rc = sqlite3_prepare_v2(db, zTrunk, -1, &pTrunk, 0);
          163  +  if( rc!=SQLITE_OK ) return rc;
          164  +  sqlite3_bind_text(pTrunk, 1, zDb, -1, SQLITE_STATIC);
          165  +  while( rc==SQLITE_OK && sqlite3_step(pTrunk)==SQLITE_ROW ){
          166  +    u32 i;
          167  +    u32 iTrunk = (u32)sqlite3_column_int(pTrunk, 0);
          168  +    const u8 *aData = (const u8*)sqlite3_column_blob(pTrunk, 1);
          169  +    int nData = sqlite3_column_bytes(pTrunk, 1);
          170  +    u32 iNext = get4byte(&aData[0]);
          171  +    u32 nLeaf = get4byte(&aData[4]);
          172  +
          173  +    if( nLeaf>((nData/4)-2-6) ){
          174  +      rc = checkFreelistError(pzOut, 
          175  +          "leaf count out of range (%d) on trunk page %d", 
          176  +          (int)nLeaf, (int)iTrunk
          177  +      );
          178  +      nLeaf = (nData/4) - 2 - 6;
          179  +    }
          180  +
          181  +    nFree += 1+nLeaf;
          182  +    if( iNext>nPage ){
          183  +      rc = checkFreelistError(pzOut, 
          184  +          "trunk page %d is out of range", (int)iNext
          185  +      );
          186  +    }
          187  +
          188  +    for(i=0; rc==SQLITE_OK && i<nLeaf; i++){
          189  +      u32 iLeaf = get4byte(&aData[8 + 4*i]);
          190  +      if( iLeaf==0 || iLeaf>nPage ){
          191  +        rc = checkFreelistError(pzOut,
          192  +            "leaf page %d is out of range (child %d of trunk page %d)", 
          193  +            (int)iLeaf, (int)i, (int)iTrunk
          194  +        );
          195  +      }
          196  +    }
          197  +  }
          198  +
          199  +  if( rc==SQLITE_OK && nFree!=nExpected ){
          200  +    rc = checkFreelistError(pzOut,
          201  +        "free-list count mismatch: actual=%d header=%d", 
          202  +        (int)nFree, (int)nExpected
          203  +    );
          204  +  }
          205  +
          206  +  rc2 = sqlite3_finalize(pTrunk);
          207  +  if( rc==SQLITE_OK ) rc = rc2;
          208  +  return rc;
          209  +}
          210  +
          211  +int sqlite3_check_freelist(sqlite3 *db, const char *zDb){
          212  +  return checkFreelist(db, zDb, 0);
          213  +}
          214  +
          215  +static void checkfreelist_function(
          216  +  sqlite3_context *pCtx,
          217  +  int nArg,
          218  +  sqlite3_value **apArg
          219  +){
          220  +  const char *zDb;
          221  +  int rc;
          222  +  char *zOut = 0;
          223  +  sqlite3 *db = sqlite3_context_db_handle(pCtx);
          224  +
          225  +  assert( nArg==1 );
          226  +  zDb = (const char*)sqlite3_value_text(apArg[0]);
          227  +  rc = checkFreelist(db, zDb, &zOut);
          228  +  if( rc==SQLITE_OK ){
          229  +    sqlite3_result_text(pCtx, zOut?zOut:"ok", -1, SQLITE_TRANSIENT);
          230  +  }else{
          231  +    sqlite3_result_error_code(pCtx, rc);
          232  +  }
          233  +
          234  +  sqlite3_free(zOut);
          235  +}
          236  +
          237  +/*
          238  +** An SQL function invoked as follows:
          239  +**
          240  +**   sqlite_readint32(BLOB)           -- Decode 32-bit integer from start of blob
          241  +*/
          242  +static void readint_function(
          243  +  sqlite3_context *pCtx,
          244  +  int nArg,
          245  +  sqlite3_value **apArg
          246  +){
          247  +  const u8 *zBlob;
          248  +  int nBlob;
          249  +  int iOff = 0;
          250  +  u32 iRet = 0;
          251  +
          252  +  if( nArg!=1 && nArg!=2 ){
          253  +    sqlite3_result_error(
          254  +        pCtx, "wrong number of arguments to function sqlite_readint32()", -1
          255  +    );
          256  +    return;
          257  +  }
          258  +  if( nArg==2 ){
          259  +    iOff = sqlite3_value_int(apArg[1]);
          260  +  }
          261  +
          262  +  zBlob = sqlite3_value_blob(apArg[0]);
          263  +  nBlob = sqlite3_value_bytes(apArg[0]);
          264  +
          265  +  if( nBlob>=(iOff+4) ){
          266  +    iRet = get4byte(&zBlob[iOff]);
          267  +  }
          268  +
          269  +  sqlite3_result_int64(pCtx, (sqlite3_int64)iRet);
          270  +}
          271  +
          272  +/*
          273  +** Register the SQL functions.
          274  +*/
          275  +static int cflRegister(sqlite3 *db){
          276  +  int rc = sqlite3_create_function(
          277  +      db, "sqlite_readint32", -1, SQLITE_UTF8, 0, readint_function, 0, 0
          278  +  );
          279  +  if( rc!=SQLITE_OK ) return rc;
          280  +  rc = sqlite3_create_function(
          281  +      db, "checkfreelist", 1, SQLITE_UTF8, 0, checkfreelist_function, 0, 0
          282  +  );
          283  +  return rc;
          284  +}
          285  +
          286  +/*
          287  +** Extension load function.
          288  +*/
          289  +#ifdef _WIN32
          290  +__declspec(dllexport)
          291  +#endif
          292  +int sqlite3_checkfreelist_init(
          293  +  sqlite3 *db, 
          294  +  char **pzErrMsg, 
          295  +  const sqlite3_api_routines *pApi
          296  +){
          297  +  SQLITE_EXTENSION_INIT2(pApi);
          298  +  return cflRegister(db);
          299  +}

Changes to main.mk.

    51     51   THREADLIB += $(LIBS)
    52     52   
    53     53   # Object files for the SQLite library.
    54     54   #
    55     55   LIBOBJ+= vdbe.o parse.o \
    56     56            alter.o analyze.o attach.o auth.o \
    57     57            backup.o bitvec.o btmutex.o btree.o build.o \
    58         -         callback.o complete.o ctime.o date.o dbstat.o delete.o expr.o \
           58  +         callback.o complete.o ctime.o \
           59  +         date.o dbpage.o dbstat.o delete.o expr.o \
    59     60   	 fault.o fkey.o \
    60     61            fts3.o fts3_aux.o fts3_expr.o fts3_hash.o fts3_icu.o fts3_porter.o \
    61     62            fts3_snippet.o fts3_tokenizer.o fts3_tokenizer1.o \
    62     63            fts3_tokenize_vtab.o \
    63     64   	 fts3_unicode.o fts3_unicode2.o \
    64     65            fts3_write.o fts5.o func.o global.o hash.o \
    65     66            icu.o insert.o json1.o legacy.o loadext.o \
................................................................................
    92     93     $(TOP)/src/btree.h \
    93     94     $(TOP)/src/btreeInt.h \
    94     95     $(TOP)/src/build.c \
    95     96     $(TOP)/src/callback.c \
    96     97     $(TOP)/src/complete.c \
    97     98     $(TOP)/src/ctime.c \
    98     99     $(TOP)/src/date.c \
          100  +  $(TOP)/src/dbpage.c \
    99    101     $(TOP)/src/dbstat.c \
   100    102     $(TOP)/src/delete.c \
   101    103     $(TOP)/src/expr.c \
   102    104     $(TOP)/src/fault.c \
   103    105     $(TOP)/src/fkey.c \
   104    106     $(TOP)/src/func.c \
   105    107     $(TOP)/src/global.c \
................................................................................
   302    304     $(TOP)/src/test_fs.c \
   303    305     $(TOP)/src/test_func.c \
   304    306     $(TOP)/src/test_hexio.c \
   305    307     $(TOP)/src/test_init.c \
   306    308     $(TOP)/src/test_intarray.c \
   307    309     $(TOP)/src/test_journal.c \
   308    310     $(TOP)/src/test_malloc.c \
          311  +  $(TOP)/src/test_md5.c \
   309    312     $(TOP)/src/test_multiplex.c \
   310    313     $(TOP)/src/test_mutex.c \
   311    314     $(TOP)/src/test_onefile.c \
   312    315     $(TOP)/src/test_osinst.c \
   313    316     $(TOP)/src/test_pcache.c \
   314    317     $(TOP)/src/test_quota.c \
   315    318     $(TOP)/src/test_rtree.c \
   316    319     $(TOP)/src/test_schema.c \
   317    320     $(TOP)/src/test_server.c \
   318    321     $(TOP)/src/test_sqllog.c \
   319    322     $(TOP)/src/test_superlock.c \
   320    323     $(TOP)/src/test_syscall.c \
          324  +  $(TOP)/src/test_tclsh.c \
   321    325     $(TOP)/src/test_tclvar.c \
   322    326     $(TOP)/src/test_thread.c \
   323    327     $(TOP)/src/test_vfs.c \
   324    328     $(TOP)/src/test_windirent.c \
   325    329     $(TOP)/src/test_wsd.c
   326    330   
   327    331   # Extensions to be statically loaded.
................................................................................
   356    360   
   357    361   TESTSRC2 = \
   358    362     $(TOP)/src/attach.c \
   359    363     $(TOP)/src/backup.c \
   360    364     $(TOP)/src/btree.c \
   361    365     $(TOP)/src/build.c \
   362    366     $(TOP)/src/date.c \
          367  +  $(TOP)/src/dbpage.c \
   363    368     $(TOP)/src/dbstat.c \
   364    369     $(TOP)/src/expr.c \
   365    370     $(TOP)/src/func.c \
   366    371     $(TOP)/src/insert.c \
   367    372     $(TOP)/src/wal.c \
   368    373     $(TOP)/src/main.c \
   369    374     $(TOP)/src/mem5.c \
................................................................................
   477    482   
   478    483   # Extra compiler options for various shell tools
   479    484   #
   480    485   SHELL_OPT += -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS5
   481    486   SHELL_OPT += -DSQLITE_ENABLE_EXPLAIN_COMMENTS
   482    487   SHELL_OPT += -DSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
   483    488   SHELL_OPT += -DSQLITE_ENABLE_STMTVTAB
          489  +SHELL_OPT += -DSQLITE_ENABLE_DBPAGE_VTAB
          490  +SHELL_OPT += -DSQLITE_ENABLE_DBSTAT_VTAB
   484    491   FUZZERSHELL_OPT = -DSQLITE_ENABLE_JSON1
   485    492   FUZZCHECK_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5
   486    493   FUZZCHECK_OPT += -DSQLITE_MAX_MEMORY=50000000
   487    494   DBFUZZ_OPT =
   488    495   KV_OPT = -DSQLITE_THREADSAFE=0 -DSQLITE_DIRECT_OVERFLOW_READ
   489    496   ST_OPT = -DSQLITE_THREADSAFE=0
   490    497   
................................................................................
   766    773   
   767    774   sqlite3rbu.o:	$(TOP)/ext/rbu/sqlite3rbu.c $(HDR) $(EXTHDR)
   768    775   	$(TCCX) -DSQLITE_CORE -c $(TOP)/ext/rbu/sqlite3rbu.c
   769    776   
   770    777   # Rules for building test programs and for running tests
   771    778   #
   772    779   tclsqlite3:	$(TOP)/src/tclsqlite.c libsqlite3.a
   773         -	$(TCCX) $(TCL_FLAGS) -DTCLSH=1 -o tclsqlite3 \
          780  +	$(TCCX) $(TCL_FLAGS) -DTCLSH -o tclsqlite3 \
   774    781   		$(TOP)/src/tclsqlite.c libsqlite3.a $(LIBTCL) $(THREADLIB)
   775    782   
   776         -sqlite3_analyzer.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/spaceanal.tcl
   777         -	echo "#define TCLSH 2" > $@
   778         -	echo "#define SQLITE_ENABLE_DBSTAT_VTAB 1" >> $@
   779         -	cat sqlite3.c $(TOP)/src/tclsqlite.c >> $@
   780         -	echo "static const char *tclsh_main_loop(void){" >> $@
   781         -	echo "static const char *zMainloop = " >> $@
   782         -	tclsh $(TOP)/tool/tostr.tcl $(TOP)/tool/spaceanal.tcl >> $@
   783         -	echo "; return zMainloop; }" >> $@
          783  +sqlite3_analyzer.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/spaceanal.tcl $(TOP)/tool/sqlite3_analyzer.c.in $(TOP)/tool/mkccode.tcl
          784  +	tclsh $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqlite3_analyzer.c.in >sqlite3_analyzer.c
   784    785   
   785    786   sqlite3_analyzer$(EXE): sqlite3_analyzer.c
   786    787   	$(TCCX) $(TCL_FLAGS) sqlite3_analyzer.c -o $@ $(LIBTCL) $(THREADLIB) 
   787    788   
   788    789   dbdump$(EXE):	$(TOP)/ext/misc/dbdump.c sqlite3.o
   789    790   	$(TCCX) -DDBDUMP_STANDALONE -o dbdump$(EXE) \
   790    791               $(TOP)/ext/misc/dbdump.c sqlite3.o $(THREADLIB)
................................................................................
   792    793   # Rules to build the 'testfixture' application.
   793    794   #
   794    795   TESTFIXTURE_FLAGS  = -DSQLITE_TEST=1 -DSQLITE_CRASH_TEST=1
   795    796   TESTFIXTURE_FLAGS += -DSQLITE_SERVER=1 -DSQLITE_PRIVATE="" -DSQLITE_CORE
   796    797   TESTFIXTURE_FLAGS += -DSQLITE_SERIES_CONSTRAINT_VERIFY=1
   797    798   TESTFIXTURE_FLAGS += -DSQLITE_DEFAULT_PAGE_SIZE=1024
   798    799   TESTFIXTURE_FLAGS += -DSQLITE_ENABLE_STMTVTAB
          800  +TESTFIXTURE_FLAGS += -DSQLITE_ENABLE_DBPAGE_VTAB
          801  +TESTFIXTURE_FLAGS += -DTCLSH_INIT_PROC=sqlite3TestInit
   799    802   
   800    803   testfixture$(EXE): $(TESTSRC2) libsqlite3.a $(TESTSRC) $(TOP)/src/tclsqlite.c
   801         -	$(TCCX) $(TCL_FLAGS) -DTCLSH=1 $(TESTFIXTURE_FLAGS)                  \
          804  +	$(TCCX) $(TCL_FLAGS) $(TESTFIXTURE_FLAGS)                            \
   802    805   		$(TESTSRC) $(TESTSRC2) $(TOP)/src/tclsqlite.c                \
   803    806   		-o testfixture$(EXE) $(LIBTCL) libsqlite3.a $(THREADLIB)
   804    807   
   805    808   amalgamation-testfixture$(EXE): sqlite3.c $(TESTSRC) $(TOP)/src/tclsqlite.c  \
   806    809   				$(TOP)/ext/session/test_session.c
   807         -	$(TCCX) $(TCL_FLAGS) -DTCLSH=1 $(TESTFIXTURE_FLAGS)                  \
          810  +	$(TCCX) $(TCL_FLAGS) $(TESTFIXTURE_FLAGS)                            \
   808    811   		$(TESTSRC) $(TOP)/src/tclsqlite.c sqlite3.c                  \
   809    812   		$(TOP)/ext/session/test_session.c                            \
   810    813   		-o testfixture$(EXE) $(LIBTCL) $(THREADLIB)
   811    814   
   812    815   fts3-testfixture$(EXE): sqlite3.c fts3amal.c $(TESTSRC) $(TOP)/src/tclsqlite.c
   813         -	$(TCCX) $(TCL_FLAGS) -DTCLSH=1 $(TESTFIXTURE_FLAGS)                  \
          816  +	$(TCCX) $(TCL_FLAGS) $(TESTFIXTURE_FLAGS)                            \
   814    817   	-DSQLITE_ENABLE_FTS3=1                                               \
   815    818   		$(TESTSRC) $(TOP)/src/tclsqlite.c sqlite3.c fts3amal.c       \
   816    819   		-o testfixture$(EXE) $(LIBTCL) $(THREADLIB)
   817    820   
   818    821   fulltest:	$(TESTPROGS) fuzztest
   819    822   	./testfixture$(EXE) $(TOP)/test/all.test $(TESTOPTS)
   820    823   

Changes to src/btree.c.

  4820   4820   ** page of the database.  The data might change or move the next time
  4821   4821   ** any btree routine is called.
  4822   4822   */
  4823   4823   static const void *fetchPayload(
  4824   4824     BtCursor *pCur,      /* Cursor pointing to entry to read from */
  4825   4825     u32 *pAmt            /* Write the number of available bytes here */
  4826   4826   ){
  4827         -  u32 amt;
         4827  +  int amt;
  4828   4828     assert( pCur!=0 && pCur->iPage>=0 && pCur->pPage);
  4829   4829     assert( pCur->eState==CURSOR_VALID );
  4830   4830     assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) );
  4831   4831     assert( cursorOwnsBtShared(pCur) );
  4832   4832     assert( pCur->ix<pCur->pPage->nCell );
  4833   4833     assert( pCur->info.nSize>0 );
  4834   4834     assert( pCur->info.pPayload>pCur->pPage->aData || CORRUPT_DB );
  4835   4835     assert( pCur->info.pPayload<pCur->pPage->aDataEnd ||CORRUPT_DB);
  4836         -  amt = (int)(pCur->pPage->aDataEnd - pCur->info.pPayload);
  4837         -  if( pCur->info.nLocal<amt ) amt = pCur->info.nLocal;
  4838         -  *pAmt = amt;
         4836  +  amt = pCur->info.nLocal;
         4837  +  if( amt>(int)(pCur->pPage->aDataEnd - pCur->info.pPayload) ){
         4838  +    /* There is too little space on the page for the expected amount
         4839  +    ** of local content. Database must be corrupt. */
         4840  +    assert( CORRUPT_DB );
         4841  +    amt = MAX(0, (int)(pCur->pPage->aDataEnd - pCur->info.pPayload));
         4842  +  }
         4843  +  *pAmt = (u32)amt;
  4839   4844     return (void*)pCur->info.pPayload;
  4840   4845   }
  4841   4846   
  4842   4847   
  4843   4848   /*
  4844   4849   ** For the entry that cursor pCur is point to, return as
  4845   4850   ** many bytes of the key or data as are available on the local

Changes to src/build.c.

  1059   1059     Table *p;
  1060   1060     int i;
  1061   1061     char *z;
  1062   1062     char *zType;
  1063   1063     Column *pCol;
  1064   1064     sqlite3 *db = pParse->db;
  1065   1065     if( (p = pParse->pNewTable)==0 ) return;
  1066         -#if SQLITE_MAX_COLUMN
  1067   1066     if( p->nCol+1>db->aLimit[SQLITE_LIMIT_COLUMN] ){
  1068   1067       sqlite3ErrorMsg(pParse, "too many columns on %s", p->zName);
  1069   1068       return;
  1070   1069     }
  1071         -#endif
  1072   1070     z = sqlite3DbMallocRaw(db, pName->n + pType->n + 2);
  1073   1071     if( z==0 ) return;
  1074   1072     memcpy(z, pName->z, pName->n);
  1075   1073     z[pName->n] = 0;
  1076   1074     sqlite3Dequote(z);
  1077   1075     for(i=0; i<p->nCol; i++){
  1078   1076       if( sqlite3_stricmp(z, p->aCol[i].zName)==0 ){

Added src/dbpage.c.

            1  +/*
            2  +** 2017-10-11
            3  +**
            4  +** The author disclaims copyright to this source code.  In place of
            5  +** a legal notice, here is a blessing:
            6  +**
            7  +**    May you do good and not evil.
            8  +**    May you find forgiveness for yourself and forgive others.
            9  +**    May you share freely, never taking more than you give.
           10  +**
           11  +******************************************************************************
           12  +**
           13  +** This file contains an implementation of the "sqlite_dbpage" virtual table.
           14  +**
           15  +** The sqlite_dbpage virtual table is used to read or write whole raw
           16  +** pages of the database file.  The pager interface is used so that 
           17  +** uncommitted changes and changes recorded in the WAL file are correctly
           18  +** retrieved.
           19  +**
           20  +** Usage example:
           21  +**
           22  +**    SELECT data FROM sqlite_dbpage('aux1') WHERE pgno=123;
           23  +**
           24  +** This is an eponymous virtual table so it does not need to be created before
           25  +** use.  The optional argument to the sqlite_dbpage() table name is the
           26  +** schema for the database file that is to be read.  The default schema is
           27  +** "main".
           28  +**
           29  +** The data field of sqlite_dbpage table can be updated.  The new
           30  +** value must be a BLOB which is the correct page size, otherwise the
           31  +** update fails.  Rows may not be deleted or inserted.
           32  +*/
           33  +
           34  +#include "sqliteInt.h"   /* Requires access to internal data structures */
           35  +#if (defined(SQLITE_ENABLE_DBPAGE_VTAB) || defined(SQLITE_TEST)) \
           36  +    && !defined(SQLITE_OMIT_VIRTUALTABLE)
           37  +
           38  +typedef struct DbpageTable DbpageTable;
           39  +typedef struct DbpageCursor DbpageCursor;
           40  +
           41  +struct DbpageCursor {
           42  +  sqlite3_vtab_cursor base;       /* Base class.  Must be first */
           43  +  int pgno;                       /* Current page number */
           44  +  int mxPgno;                     /* Last page to visit on this scan */
           45  +};
           46  +
           47  +struct DbpageTable {
           48  +  sqlite3_vtab base;              /* Base class.  Must be first */
           49  +  sqlite3 *db;                    /* The database */
           50  +  Pager *pPager;                  /* Pager being read/written */
           51  +  int iDb;                        /* Index of database to analyze */
           52  +  int szPage;                     /* Size of each page in bytes */
           53  +  int nPage;                      /* Number of pages in the file */
           54  +};
           55  +
           56  +/*
           57  +** Connect to or create a dbpagevfs virtual table.
           58  +*/
           59  +static int dbpageConnect(
           60  +  sqlite3 *db,
           61  +  void *pAux,
           62  +  int argc, const char *const*argv,
           63  +  sqlite3_vtab **ppVtab,
           64  +  char **pzErr
           65  +){
           66  +  DbpageTable *pTab = 0;
           67  +  int rc = SQLITE_OK;
           68  +  int iDb;
           69  +
           70  +  if( argc>=4 ){
           71  +    Token nm;
           72  +    sqlite3TokenInit(&nm, (char*)argv[3]);
           73  +    iDb = sqlite3FindDb(db, &nm);
           74  +    if( iDb<0 ){
           75  +      *pzErr = sqlite3_mprintf("no such schema: %s", argv[3]);
           76  +      return SQLITE_ERROR;
           77  +    }
           78  +  }else{
           79  +    iDb = 0;
           80  +  }
           81  +  rc = sqlite3_declare_vtab(db, 
           82  +          "CREATE TABLE x(pgno INTEGER PRIMARY KEY, data BLOB, schema HIDDEN)");
           83  +  if( rc==SQLITE_OK ){
           84  +    pTab = (DbpageTable *)sqlite3_malloc64(sizeof(DbpageTable));
           85  +    if( pTab==0 ) rc = SQLITE_NOMEM_BKPT;
           86  +  }
           87  +
           88  +  assert( rc==SQLITE_OK || pTab==0 );
           89  +  if( rc==SQLITE_OK ){
           90  +    Btree *pBt = db->aDb[iDb].pBt;
           91  +    memset(pTab, 0, sizeof(DbpageTable));
           92  +    pTab->db = db;
           93  +    pTab->iDb = iDb;
           94  +    pTab->pPager = pBt ? sqlite3BtreePager(pBt) : 0;
           95  +  }
           96  +
           97  +  *ppVtab = (sqlite3_vtab*)pTab;
           98  +  return rc;
           99  +}
          100  +
          101  +/*
          102  +** Disconnect from or destroy a dbpagevfs virtual table.
          103  +*/
          104  +static int dbpageDisconnect(sqlite3_vtab *pVtab){
          105  +  sqlite3_free(pVtab);
          106  +  return SQLITE_OK;
          107  +}
          108  +
          109  +/*
          110  +** idxNum:
          111  +**
          112  +**     0     full table scan
          113  +**     1     pgno=?1
          114  +*/
          115  +static int dbpageBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
          116  +  int i;
          117  +  pIdxInfo->estimatedCost = 1.0e6;  /* Initial cost estimate */
          118  +  for(i=0; i<pIdxInfo->nConstraint; i++){
          119  +    struct sqlite3_index_constraint *p = &pIdxInfo->aConstraint[i];
          120  +    if( p->usable && p->iColumn<=0 && p->op==SQLITE_INDEX_CONSTRAINT_EQ ){
          121  +      pIdxInfo->estimatedRows = 1;
          122  +      pIdxInfo->idxFlags = SQLITE_INDEX_SCAN_UNIQUE;
          123  +      pIdxInfo->estimatedCost = 1.0;
          124  +      pIdxInfo->idxNum = 1;
          125  +      pIdxInfo->aConstraintUsage[i].argvIndex = 1;
          126  +      pIdxInfo->aConstraintUsage[i].omit = 1;
          127  +      break;
          128  +    }
          129  +  }
          130  +  if( pIdxInfo->nOrderBy>=1
          131  +   && pIdxInfo->aOrderBy[0].iColumn<=0
          132  +   && pIdxInfo->aOrderBy[0].desc==0
          133  +  ){
          134  +    pIdxInfo->orderByConsumed = 1;
          135  +  }
          136  +  return SQLITE_OK;
          137  +}
          138  +
          139  +/*
          140  +** Open a new dbpagevfs cursor.
          141  +*/
          142  +static int dbpageOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
          143  +  DbpageCursor *pCsr;
          144  +
          145  +  pCsr = (DbpageCursor *)sqlite3_malloc64(sizeof(DbpageCursor));
          146  +  if( pCsr==0 ){
          147  +    return SQLITE_NOMEM_BKPT;
          148  +  }else{
          149  +    memset(pCsr, 0, sizeof(DbpageCursor));
          150  +    pCsr->base.pVtab = pVTab;
          151  +    pCsr->pgno = -1;
          152  +  }
          153  +
          154  +  *ppCursor = (sqlite3_vtab_cursor *)pCsr;
          155  +  return SQLITE_OK;
          156  +}
          157  +
          158  +/*
          159  +** Close a dbpagevfs cursor.
          160  +*/
          161  +static int dbpageClose(sqlite3_vtab_cursor *pCursor){
          162  +  DbpageCursor *pCsr = (DbpageCursor *)pCursor;
          163  +  sqlite3_free(pCsr);
          164  +  return SQLITE_OK;
          165  +}
          166  +
          167  +/*
          168  +** Move a dbpagevfs cursor to the next entry in the file.
          169  +*/
          170  +static int dbpageNext(sqlite3_vtab_cursor *pCursor){
          171  +  int rc = SQLITE_OK;
          172  +  DbpageCursor *pCsr = (DbpageCursor *)pCursor;
          173  +  pCsr->pgno++;
          174  +  return rc;
          175  +}
          176  +
          177  +static int dbpageEof(sqlite3_vtab_cursor *pCursor){
          178  +  DbpageCursor *pCsr = (DbpageCursor *)pCursor;
          179  +  return pCsr->pgno > pCsr->mxPgno;
          180  +}
          181  +
          182  +static int dbpageFilter(
          183  +  sqlite3_vtab_cursor *pCursor, 
          184  +  int idxNum, const char *idxStr,
          185  +  int argc, sqlite3_value **argv
          186  +){
          187  +  DbpageCursor *pCsr = (DbpageCursor *)pCursor;
          188  +  DbpageTable *pTab = (DbpageTable *)pCursor->pVtab;
          189  +  int rc = SQLITE_OK;
          190  +  Btree *pBt = pTab->db->aDb[pTab->iDb].pBt;
          191  +
          192  +  pTab->szPage = sqlite3BtreeGetPageSize(pBt);
          193  +  pTab->nPage = sqlite3BtreeLastPage(pBt);
          194  +  if( idxNum==1 ){
          195  +    pCsr->pgno = sqlite3_value_int(argv[0]);
          196  +    if( pCsr->pgno<1 || pCsr->pgno>pTab->nPage ){
          197  +      pCsr->pgno = 1;
          198  +      pCsr->mxPgno = 0;
          199  +    }else{
          200  +      pCsr->mxPgno = pCsr->pgno;
          201  +    }
          202  +  }else{
          203  +    pCsr->pgno = 1;
          204  +    pCsr->mxPgno = pTab->nPage;
          205  +  }
          206  +  return rc;
          207  +}
          208  +
          209  +static int dbpageColumn(
          210  +  sqlite3_vtab_cursor *pCursor, 
          211  +  sqlite3_context *ctx, 
          212  +  int i
          213  +){
          214  +  DbpageCursor *pCsr = (DbpageCursor *)pCursor;
          215  +  DbpageTable *pTab = (DbpageTable *)pCursor->pVtab;
          216  +  int rc = SQLITE_OK;
          217  +  switch( i ){
          218  +    case 0: {           /* pgno */
          219  +      sqlite3_result_int(ctx, pCsr->pgno);
          220  +      break;
          221  +    }
          222  +    case 1: {           /* data */
          223  +      DbPage *pDbPage = 0;
          224  +      rc = sqlite3PagerGet(pTab->pPager, pCsr->pgno, (DbPage**)&pDbPage, 0);
          225  +      if( rc==SQLITE_OK ){
          226  +        sqlite3_result_blob(ctx, sqlite3PagerGetData(pDbPage), pTab->szPage,
          227  +                            SQLITE_TRANSIENT);
          228  +      }
          229  +      sqlite3PagerUnref(pDbPage);
          230  +      break;
          231  +    }
          232  +    default: {          /* schema */
          233  +      sqlite3 *db = sqlite3_context_db_handle(ctx);
          234  +      sqlite3_result_text(ctx, db->aDb[pTab->iDb].zDbSName, -1, SQLITE_STATIC);
          235  +      break;
          236  +    }
          237  +  }
          238  +  return SQLITE_OK;
          239  +}
          240  +
          241  +static int dbpageRowid(sqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid){
          242  +  DbpageCursor *pCsr = (DbpageCursor *)pCursor;
          243  +  *pRowid = pCsr->pgno;
          244  +  return SQLITE_OK;
          245  +}
          246  +
          247  +static int dbpageUpdate(
          248  +  sqlite3_vtab *pVtab,
          249  +  int argc,
          250  +  sqlite3_value **argv,
          251  +  sqlite_int64 *pRowid
          252  +){
          253  +  DbpageTable *pTab = (DbpageTable *)pVtab;
          254  +  int pgno;
          255  +  DbPage *pDbPage = 0;
          256  +  int rc = SQLITE_OK;
          257  +  char *zErr = 0;
          258  +
          259  +  if( argc==1 ){
          260  +    zErr = "cannot delete";
          261  +    goto update_fail;
          262  +  }
          263  +  pgno = sqlite3_value_int(argv[0]);
          264  +  if( pgno<1 || pgno>pTab->nPage ){
          265  +    zErr = "bad page number";
          266  +    goto update_fail;
          267  +  }
          268  +  if( sqlite3_value_int(argv[1])!=pgno ){
          269  +    zErr = "cannot insert";
          270  +    goto update_fail;
          271  +  }
          272  +  if( sqlite3_value_type(argv[3])!=SQLITE_BLOB 
          273  +   || sqlite3_value_bytes(argv[3])!=pTab->szPage 
          274  +  ){
          275  +    zErr = "bad page value";
          276  +    goto update_fail;
          277  +  }
          278  +  rc = sqlite3PagerGet(pTab->pPager, pgno, (DbPage**)&pDbPage, 0);
          279  +  if( rc==SQLITE_OK ){
          280  +    rc = sqlite3PagerWrite(pDbPage);
          281  +    if( rc==SQLITE_OK ){
          282  +      memcpy(sqlite3PagerGetData(pDbPage),
          283  +             sqlite3_value_blob(argv[3]),
          284  +             pTab->szPage);
          285  +    }
          286  +  }
          287  +  sqlite3PagerUnref(pDbPage);
          288  +  return rc;
          289  +
          290  +update_fail:
          291  +  sqlite3_free(pVtab->zErrMsg);
          292  +  pVtab->zErrMsg = sqlite3_mprintf("%s", zErr);
          293  +  return SQLITE_ERROR;
          294  +}
          295  +
          296  +/*
          297  +** Invoke this routine to register the "dbpage" virtual table module
          298  +*/
          299  +int sqlite3DbpageRegister(sqlite3 *db){
          300  +  static sqlite3_module dbpage_module = {
          301  +    0,                            /* iVersion */
          302  +    dbpageConnect,                /* xCreate */
          303  +    dbpageConnect,                /* xConnect */
          304  +    dbpageBestIndex,              /* xBestIndex */
          305  +    dbpageDisconnect,             /* xDisconnect */
          306  +    dbpageDisconnect,             /* xDestroy */
          307  +    dbpageOpen,                   /* xOpen - open a cursor */
          308  +    dbpageClose,                  /* xClose - close a cursor */
          309  +    dbpageFilter,                 /* xFilter - configure scan constraints */
          310  +    dbpageNext,                   /* xNext - advance a cursor */
          311  +    dbpageEof,                    /* xEof - check for end of scan */
          312  +    dbpageColumn,                 /* xColumn - read data */
          313  +    dbpageRowid,                  /* xRowid - read data */
          314  +    dbpageUpdate,                 /* xUpdate */
          315  +    0,                            /* xBegin */
          316  +    0,                            /* xSync */
          317  +    0,                            /* xCommit */
          318  +    0,                            /* xRollback */
          319  +    0,                            /* xFindMethod */
          320  +    0,                            /* xRename */
          321  +    0,                            /* xSavepoint */
          322  +    0,                            /* xRelease */
          323  +    0,                            /* xRollbackTo */
          324  +  };
          325  +  return sqlite3_create_module(db, "sqlite_dbpage", &dbpage_module, 0);
          326  +}
          327  +#elif defined(SQLITE_ENABLE_DBPAGE_VTAB)
          328  +int sqlite3DbpageRegister(sqlite3 *db){ return SQLITE_OK; }
          329  +#endif /* SQLITE_ENABLE_DBSTAT_VTAB */

Changes to src/main.c.

  3049   3049   #endif
  3050   3050   
  3051   3051   #ifdef SQLITE_ENABLE_RTREE
  3052   3052     if( !db->mallocFailed && rc==SQLITE_OK){
  3053   3053       rc = sqlite3RtreeInit(db);
  3054   3054     }
  3055   3055   #endif
         3056  +
         3057  +#ifdef SQLITE_ENABLE_DBPAGE_VTAB
         3058  +  if( !db->mallocFailed && rc==SQLITE_OK){
         3059  +    rc = sqlite3DbpageRegister(db);
         3060  +  }
         3061  +#endif
  3056   3062   
  3057   3063   #ifdef SQLITE_ENABLE_DBSTAT_VTAB
  3058   3064     if( !db->mallocFailed && rc==SQLITE_OK){
  3059   3065       rc = sqlite3DbstatRegister(db);
  3060   3066     }
  3061   3067   #endif
  3062   3068   

Changes to src/resolve.c.

   955    955     ExprList *pEList;
   956    956     sqlite3 *db;
   957    957     int moreToDo = 1;
   958    958   
   959    959     pOrderBy = pSelect->pOrderBy;
   960    960     if( pOrderBy==0 ) return 0;
   961    961     db = pParse->db;
   962         -#if SQLITE_MAX_COLUMN
   963    962     if( pOrderBy->nExpr>db->aLimit[SQLITE_LIMIT_COLUMN] ){
   964    963       sqlite3ErrorMsg(pParse, "too many terms in ORDER BY clause");
   965    964       return 1;
   966    965     }
   967         -#endif
   968    966     for(i=0; i<pOrderBy->nExpr; i++){
   969    967       pOrderBy->a[i].done = 0;
   970    968     }
   971    969     pSelect->pNext = 0;
   972    970     while( pSelect->pPrior ){
   973    971       pSelect->pPrior->pNext = pSelect;
   974    972       pSelect = pSelect->pPrior;
................................................................................
  1052   1050   ){
  1053   1051     int i;
  1054   1052     sqlite3 *db = pParse->db;
  1055   1053     ExprList *pEList;
  1056   1054     struct ExprList_item *pItem;
  1057   1055   
  1058   1056     if( pOrderBy==0 || pParse->db->mallocFailed ) return 0;
  1059         -#if SQLITE_MAX_COLUMN
  1060   1057     if( pOrderBy->nExpr>db->aLimit[SQLITE_LIMIT_COLUMN] ){
  1061   1058       sqlite3ErrorMsg(pParse, "too many terms in %s BY clause", zType);
  1062   1059       return 1;
  1063   1060     }
  1064         -#endif
  1065   1061     pEList = pSelect->pEList;
  1066   1062     assert( pEList!=0 );  /* sqlite3SelectNew() guarantees this */
  1067   1063     for(i=0, pItem=pOrderBy->a; i<pOrderBy->nExpr; i++, pItem++){
  1068   1064       if( pItem->u.x.iOrderByCol ){
  1069   1065         if( pItem->u.x.iOrderByCol>pEList->nExpr ){
  1070   1066           resolveOutOfRangeError(pParse, zType, i+1, pEList->nExpr);
  1071   1067           return 1;

Changes to src/select.c.

  1685   1685     Hash ht;                    /* Hash table of column names */
  1686   1686   
  1687   1687     sqlite3HashInit(&ht);
  1688   1688     if( pEList ){
  1689   1689       nCol = pEList->nExpr;
  1690   1690       aCol = sqlite3DbMallocZero(db, sizeof(aCol[0])*nCol);
  1691   1691       testcase( aCol==0 );
         1692  +    if( nCol>32767 ) nCol = 32767;
  1692   1693     }else{
  1693   1694       nCol = 0;
  1694   1695       aCol = 0;
  1695   1696     }
  1696   1697     assert( nCol==(i16)nCol );
  1697   1698     *pnCol = nCol;
  1698   1699     *paCol = aCol;
................................................................................
  4592   4593             }
  4593   4594           }
  4594   4595         }
  4595   4596       }
  4596   4597       sqlite3ExprListDelete(db, pEList);
  4597   4598       p->pEList = pNew;
  4598   4599     }
  4599         -#if SQLITE_MAX_COLUMN
  4600   4600     if( p->pEList && p->pEList->nExpr>db->aLimit[SQLITE_LIMIT_COLUMN] ){
  4601   4601       sqlite3ErrorMsg(pParse, "too many columns in result set");
  4602   4602       return WRC_Abort;
  4603   4603     }
  4604         -#endif
  4605   4604     return WRC_Continue;
  4606   4605   }
  4607   4606   
  4608   4607   /*
  4609   4608   ** No-op routine for the parse-tree walker.
  4610   4609   **
  4611   4610   ** When this routine is the Walker.xExprCallback then expression trees

Changes to src/shell.c.in.

  3607   3607        { "number of triggers:",
  3608   3608          "SELECT count(*) FROM %s WHERE type='trigger'" },
  3609   3609        { "number of views:",
  3610   3610          "SELECT count(*) FROM %s WHERE type='view'" },
  3611   3611        { "schema size:",
  3612   3612          "SELECT total(length(sql)) FROM %s" },
  3613   3613     };
  3614         -  sqlite3_file *pFile = 0;
  3615   3614     int i;
  3616   3615     char *zSchemaTab;
  3617   3616     char *zDb = nArg>=2 ? azArg[1] : "main";
         3617  +  sqlite3_stmt *pStmt = 0;
  3618   3618     unsigned char aHdr[100];
  3619   3619     open_db(p, 0);
  3620   3620     if( p->db==0 ) return 1;
  3621         -  sqlite3_file_control(p->db, zDb, SQLITE_FCNTL_FILE_POINTER, &pFile);
  3622         -  if( pFile==0 || pFile->pMethods==0 || pFile->pMethods->xRead==0 ){
  3623         -    return 1;
  3624         -  }
  3625         -  i = pFile->pMethods->xRead(pFile, aHdr, 100, 0);
  3626         -  if( i!=SQLITE_OK ){
         3621  +  sqlite3_prepare_v2(p->db,"SELECT data FROM sqlite_dbpage(?1) WHERE pgno=1",
         3622  +                     -1, &pStmt, 0);
         3623  +  sqlite3_bind_text(pStmt, 1, zDb, -1, SQLITE_STATIC);
         3624  +  if( sqlite3_step(pStmt)==SQLITE_ROW
         3625  +   && sqlite3_column_bytes(pStmt,0)>100
         3626  +  ){
         3627  +    memcpy(aHdr, sqlite3_column_blob(pStmt,0), 100);
         3628  +    sqlite3_finalize(pStmt);
         3629  +  }else{
  3627   3630       raw_printf(stderr, "unable to read database header\n");
         3631  +    sqlite3_finalize(pStmt);
  3628   3632       return 1;
  3629   3633     }
  3630   3634     i = get2byteInt(aHdr+16);
  3631   3635     if( i==1 ) i = 65536;
  3632   3636     utf8_printf(p->out, "%-20s %d\n", "database page size:", i);
  3633   3637     utf8_printf(p->out, "%-20s %d\n", "write format:", aHdr[18]);
  3634   3638     utf8_printf(p->out, "%-20s %d\n", "read format:", aHdr[19]);
................................................................................
  4240   4244       }else if( (zRes = readFile("testcase-out.txt", 0))==0 ){
  4241   4245         raw_printf(stderr, "Error: cannot read 'testcase-out.txt'\n");
  4242   4246         rc = 2;
  4243   4247       }else if( testcase_glob(azArg[1],zRes)==0 ){
  4244   4248         utf8_printf(stderr,
  4245   4249                    "testcase-%s FAILED\n Expected: [%s]\n      Got: [%s]\n",
  4246   4250                    p->zTestcase, azArg[1], zRes);
  4247         -      rc = 2;
         4251  +      rc = 1;
  4248   4252       }else{
  4249   4253         utf8_printf(stdout, "testcase-%s ok\n", p->zTestcase);
  4250   4254         p->nCheck++;
  4251   4255       }
  4252   4256       sqlite3_free(zRes);
  4253   4257     }else
  4254   4258   

Changes to src/sqlite3ext.h.

   130    130     void  (*result_text16be)(sqlite3_context*,const void*,int,void(*)(void*));
   131    131     void  (*result_text16le)(sqlite3_context*,const void*,int,void(*)(void*));
   132    132     void  (*result_value)(sqlite3_context*,sqlite3_value*);
   133    133     void * (*rollback_hook)(sqlite3*,void(*)(void*),void*);
   134    134     int  (*set_authorizer)(sqlite3*,int(*)(void*,int,const char*,const char*,
   135    135                            const char*,const char*),void*);
   136    136     void  (*set_auxdata)(sqlite3_context*,int,void*,void (*)(void*));
   137         -  char * (*snprintf)(int,char*,const char*,...);
          137  +  char * (*xsnprintf)(int,char*,const char*,...);
   138    138     int  (*step)(sqlite3_stmt*);
   139    139     int  (*table_column_metadata)(sqlite3*,const char*,const char*,const char*,
   140    140                                   char const**,char const**,int*,int*,int*);
   141    141     void  (*thread_cleanup)(void);
   142    142     int  (*total_changes)(sqlite3*);
   143    143     void * (*trace)(sqlite3*,void(*xTrace)(void*,const char*),void*);
   144    144     int  (*transfer_bindings)(sqlite3_stmt*,sqlite3_stmt*);
................................................................................
   414    414   #define sqlite3_result_text16          sqlite3_api->result_text16
   415    415   #define sqlite3_result_text16be        sqlite3_api->result_text16be
   416    416   #define sqlite3_result_text16le        sqlite3_api->result_text16le
   417    417   #define sqlite3_result_value           sqlite3_api->result_value
   418    418   #define sqlite3_rollback_hook          sqlite3_api->rollback_hook
   419    419   #define sqlite3_set_authorizer         sqlite3_api->set_authorizer
   420    420   #define sqlite3_set_auxdata            sqlite3_api->set_auxdata
   421         -#define sqlite3_snprintf               sqlite3_api->snprintf
          421  +#define sqlite3_snprintf               sqlite3_api->xsnprintf
   422    422   #define sqlite3_step                   sqlite3_api->step
   423    423   #define sqlite3_table_column_metadata  sqlite3_api->table_column_metadata
   424    424   #define sqlite3_thread_cleanup         sqlite3_api->thread_cleanup
   425    425   #define sqlite3_total_changes          sqlite3_api->total_changes
   426    426   #define sqlite3_trace                  sqlite3_api->trace
   427    427   #ifndef SQLITE_OMIT_DEPRECATED
   428    428   #define sqlite3_transfer_bindings      sqlite3_api->transfer_bindings

Changes to src/sqliteInt.h.

  4396   4396   ** Threading interface
  4397   4397   */
  4398   4398   #if SQLITE_MAX_WORKER_THREADS>0
  4399   4399   int sqlite3ThreadCreate(SQLiteThread**,void*(*)(void*),void*);
  4400   4400   int sqlite3ThreadJoin(SQLiteThread*, void**);
  4401   4401   #endif
  4402   4402   
         4403  +#if defined(SQLITE_ENABLE_DBPAGE_VTAB) || defined(SQLITE_TEST)
         4404  +int sqlite3DbpageRegister(sqlite3*);
         4405  +#endif
  4403   4406   #if defined(SQLITE_ENABLE_DBSTAT_VTAB) || defined(SQLITE_TEST)
  4404   4407   int sqlite3DbstatRegister(sqlite3*);
  4405   4408   #endif
  4406   4409   
  4407   4410   int sqlite3ExprVectorSize(Expr *pExpr);
  4408   4411   int sqlite3ExprIsVector(Expr *pExpr);
  4409   4412   Expr *sqlite3VectorFieldSubexpr(Expr*, int);

Changes to src/tclsqlite.c.

    10     10   **
    11     11   *************************************************************************
    12     12   ** A TCL Interface to SQLite.  Append this file to sqlite3.c and
    13     13   ** compile the whole thing to build a TCL-enabled version of SQLite.
    14     14   **
    15     15   ** Compile-time options:
    16     16   **
    17         -**  -DTCLSH=1             Add a "main()" routine that works as a tclsh.
           17  +**  -DTCLSH         Add a "main()" routine that works as a tclsh.
    18     18   **
    19         -**  -DSQLITE_TCLMD5       When used in conjuction with -DTCLSH=1, add
    20         -**                        four new commands to the TCL interpreter for
    21         -**                        generating MD5 checksums:  md5, md5file,
    22         -**                        md5-10x8, and md5file-10x8.
           19  +**  -DTCLSH_INIT_PROC=name
    23     20   **
    24         -**  -DSQLITE_TEST         When used in conjuction with -DTCLSH=1, add
    25         -**                        hundreds of new commands used for testing
    26         -**                        SQLite.  This option implies -DSQLITE_TCLMD5.
           21  +**                  Invoke name(interp) to initialize the Tcl interpreter.
           22  +**                  If name(interp) returns a non-NULL string, then run
           23  +**                  that string as a Tcl script to launch the application.
           24  +**                  If name(interp) returns NULL, then run the regular
           25  +**                  tclsh-emulator code.
    27     26   */
           27  +#ifdef TCLSH_INIT_PROC
           28  +# define TCLSH 1
           29  +#endif
    28     30   
    29     31   /*
    30     32   ** If requested, include the SQLite compiler options file for MSVC.
    31     33   */
    32     34   #if defined(INCLUDE_MSVC_H)
    33     35   # include "msvc.h"
    34     36   #endif
................................................................................
  3282   3284     }
  3283   3285   
  3284   3286     /*    $db version
  3285   3287     **
  3286   3288     ** Return the version string for this database.
  3287   3289     */
  3288   3290     case DB_VERSION: {
  3289         -    Tcl_SetResult(interp, (char *)sqlite3_libversion(), TCL_STATIC);
         3291  +    int i;
         3292  +    for(i=2; i<objc; i++){
         3293  +      const char *zArg = Tcl_GetString(objv[i]);
         3294  +      /* Optional arguments to $db version are used for testing purpose */
         3295  +#ifdef SQLITE_TEST
         3296  +      /* $db version -use-legacy-prepare BOOLEAN
         3297  +      **
         3298  +      ** Turn the use of legacy sqlite3_prepare() on or off.
         3299  +      */
         3300  +      if( strcmp(zArg, "-use-legacy-prepare")==0 && i+1<objc ){
         3301  +        i++;
         3302  +        if( Tcl_GetBooleanFromObj(interp, objv[i], &pDb->bLegacyPrepare) ){
         3303  +          return TCL_ERROR;
         3304  +        }
         3305  +      }else
         3306  +
         3307  +      /* $db version -last-stmt-ptr
         3308  +      **
         3309  +      ** Return a string which is a hex encoding of the pointer to the
         3310  +      ** most recent sqlite3_stmt in the statement cache.
         3311  +      */
         3312  +      if( strcmp(zArg, "-last-stmt-ptr")==0 ){
         3313  +        char zBuf[100];
         3314  +        sqlite3_snprintf(sizeof(zBuf), zBuf, "%p",
         3315  +                         pDb->stmtList ? pDb->stmtList->pStmt: 0);
         3316  +        Tcl_SetResult(interp, zBuf, TCL_VOLATILE);
         3317  +      }else
         3318  +#endif /* SQLITE_TEST */
         3319  +      {
         3320  +        Tcl_AppendResult(interp, "unknown argument: ", zArg, (char*)0);
         3321  +        return TCL_ERROR;
         3322  +      }
         3323  +    }
         3324  +    if( i==2 ){   
         3325  +      Tcl_SetResult(interp, (char *)sqlite3_libversion(), TCL_STATIC);
         3326  +    }
  3290   3327       break;
  3291   3328     }
  3292   3329   
  3293   3330   
  3294   3331     } /* End of the SWITCH statement */
  3295   3332     return rc;
  3296   3333   }
................................................................................
  3542   3579   #ifndef SQLITE_3_SUFFIX_ONLY
  3543   3580   int Sqlite_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp); }
  3544   3581   int Tclsqlite_Init(Tcl_Interp *interp){ return Sqlite3_Init(interp); }
  3545   3582   int Sqlite_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; }
  3546   3583   int Tclsqlite_Unload(Tcl_Interp *interp, int flags){ return TCL_OK; }
  3547   3584   #endif
  3548   3585   
  3549         -#ifdef TCLSH
  3550         -/*****************************************************************************
  3551         -** All of the code that follows is used to build standalone TCL interpreters
  3552         -** that are statically linked with SQLite.  Enable these by compiling
  3553         -** with -DTCLSH=n where n can be 1 or 2.  An n of 1 generates a standard
  3554         -** tclsh but with SQLite built in.  An n of 2 generates the SQLite space
  3555         -** analysis program.
         3586  +/*
         3587  +** If the TCLSH macro is defined, add code to make a stand-alone program.
  3556   3588   */
         3589  +#if defined(TCLSH)
  3557   3590   
  3558         -#if defined(SQLITE_TEST) || defined(SQLITE_TCLMD5)
  3559         -/*
  3560         - * This code implements the MD5 message-digest algorithm.
  3561         - * The algorithm is due to Ron Rivest.  This code was
  3562         - * written by Colin Plumb in 1993, no copyright is claimed.
  3563         - * This code is in the public domain; do with it what you wish.
  3564         - *
  3565         - * Equivalent code is available from RSA Data Security, Inc.
  3566         - * This code has been tested against that, and is equivalent,
  3567         - * except that you don't need to include two pages of legalese
  3568         - * with every copy.
  3569         - *
  3570         - * To compute the message digest of a chunk of bytes, declare an
  3571         - * MD5Context structure, pass it to MD5Init, call MD5Update as
  3572         - * needed on buffers full of bytes, and then call MD5Final, which
  3573         - * will fill a supplied 16-byte array with the digest.
  3574         - */
  3575         -
  3576         -/*
  3577         - * If compiled on a machine that doesn't have a 32-bit integer,
  3578         - * you just set "uint32" to the appropriate datatype for an
  3579         - * unsigned 32-bit integer.  For example:
  3580         - *
  3581         - *       cc -Duint32='unsigned long' md5.c
  3582         - *
  3583         - */
  3584         -#ifndef uint32
  3585         -#  define uint32 unsigned int
  3586         -#endif
  3587         -
  3588         -struct MD5Context {
  3589         -  int isInit;
  3590         -  uint32 buf[4];
  3591         -  uint32 bits[2];
  3592         -  unsigned char in[64];
  3593         -};
  3594         -typedef struct MD5Context MD5Context;
  3595         -
  3596         -/*
  3597         - * Note: this code is harmless on little-endian machines.
  3598         - */
  3599         -static void byteReverse (unsigned char *buf, unsigned longs){
  3600         -        uint32 t;
  3601         -        do {
  3602         -                t = (uint32)((unsigned)buf[3]<<8 | buf[2]) << 16 |
  3603         -                            ((unsigned)buf[1]<<8 | buf[0]);
  3604         -                *(uint32 *)buf = t;
  3605         -                buf += 4;
  3606         -        } while (--longs);
  3607         -}
  3608         -/* The four core functions - F1 is optimized somewhat */
  3609         -
  3610         -/* #define F1(x, y, z) (x & y | ~x & z) */
  3611         -#define F1(x, y, z) (z ^ (x & (y ^ z)))
  3612         -#define F2(x, y, z) F1(z, x, y)
  3613         -#define F3(x, y, z) (x ^ y ^ z)
  3614         -#define F4(x, y, z) (y ^ (x | ~z))
  3615         -
  3616         -/* This is the central step in the MD5 algorithm. */
  3617         -#define MD5STEP(f, w, x, y, z, data, s) \
  3618         -        ( w += f(x, y, z) + data,  w = w<<s | w>>(32-s),  w += x )
  3619         -
  3620         -/*
  3621         - * The core of the MD5 algorithm, this alters an existing MD5 hash to
  3622         - * reflect the addition of 16 longwords of new data.  MD5Update blocks
  3623         - * the data and converts bytes into longwords for this routine.
  3624         - */
  3625         -static void MD5Transform(uint32 buf[4], const uint32 in[16]){
  3626         -        register uint32 a, b, c, d;
  3627         -
  3628         -        a = buf[0];
  3629         -        b = buf[1];
  3630         -        c = buf[2];
  3631         -        d = buf[3];
  3632         -
  3633         -        MD5STEP(F1, a, b, c, d, in[ 0]+0xd76aa478,  7);
  3634         -        MD5STEP(F1, d, a, b, c, in[ 1]+0xe8c7b756, 12);
  3635         -        MD5STEP(F1, c, d, a, b, in[ 2]+0x242070db, 17);
  3636         -        MD5STEP(F1, b, c, d, a, in[ 3]+0xc1bdceee, 22);
  3637         -        MD5STEP(F1, a, b, c, d, in[ 4]+0xf57c0faf,  7);
  3638         -        MD5STEP(F1, d, a, b, c, in[ 5]+0x4787c62a, 12);
  3639         -        MD5STEP(F1, c, d, a, b, in[ 6]+0xa8304613, 17);
  3640         -        MD5STEP(F1, b, c, d, a, in[ 7]+0xfd469501, 22);
  3641         -        MD5STEP(F1, a, b, c, d, in[ 8]+0x698098d8,  7);
  3642         -        MD5STEP(F1, d, a, b, c, in[ 9]+0x8b44f7af, 12);
  3643         -        MD5STEP(F1, c, d, a, b, in[10]+0xffff5bb1, 17);
  3644         -        MD5STEP(F1, b, c, d, a, in[11]+0x895cd7be, 22);
  3645         -        MD5STEP(F1, a, b, c, d, in[12]+0x6b901122,  7);
  3646         -        MD5STEP(F1, d, a, b, c, in[13]+0xfd987193, 12);
  3647         -        MD5STEP(F1, c, d, a, b, in[14]+0xa679438e, 17);
  3648         -        MD5STEP(F1, b, c, d, a, in[15]+0x49b40821, 22);
  3649         -
  3650         -        MD5STEP(F2, a, b, c, d, in[ 1]+0xf61e2562,  5);
  3651         -        MD5STEP(F2, d, a, b, c, in[ 6]+0xc040b340,  9);
  3652         -        MD5STEP(F2, c, d, a, b, in[11]+0x265e5a51, 14);
  3653         -        MD5STEP(F2, b, c, d, a, in[ 0]+0xe9b6c7aa, 20);
  3654         -        MD5STEP(F2, a, b, c, d, in[ 5]+0xd62f105d,  5);
  3655         -        MD5STEP(F2, d, a, b, c, in[10]+0x02441453,  9);
  3656         -        MD5STEP(F2, c, d, a, b, in[15]+0xd8a1e681, 14);
  3657         -        MD5STEP(F2, b, c, d, a, in[ 4]+0xe7d3fbc8, 20);
  3658         -        MD5STEP(F2, a, b, c, d, in[ 9]+0x21e1cde6,  5);
  3659         -        MD5STEP(F2, d, a, b, c, in[14]+0xc33707d6,  9);
  3660         -        MD5STEP(F2, c, d, a, b, in[ 3]+0xf4d50d87, 14);
  3661         -        MD5STEP(F2, b, c, d, a, in[ 8]+0x455a14ed, 20);
  3662         -        MD5STEP(F2, a, b, c, d, in[13]+0xa9e3e905,  5);
  3663         -        MD5STEP(F2, d, a, b, c, in[ 2]+0xfcefa3f8,  9);
  3664         -        MD5STEP(F2, c, d, a, b, in[ 7]+0x676f02d9, 14);
  3665         -        MD5STEP(F2, b, c, d, a, in[12]+0x8d2a4c8a, 20);
  3666         -
  3667         -        MD5STEP(F3, a, b, c, d, in[ 5]+0xfffa3942,  4);
  3668         -        MD5STEP(F3, d, a, b, c, in[ 8]+0x8771f681, 11);
  3669         -        MD5STEP(F3, c, d, a, b, in[11]+0x6d9d6122, 16);
  3670         -        MD5STEP(F3, b, c, d, a, in[14]+0xfde5380c, 23);
  3671         -        MD5STEP(F3, a, b, c, d, in[ 1]+0xa4beea44,  4);
  3672         -        MD5STEP(F3, d, a, b, c, in[ 4]+0x4bdecfa9, 11);
  3673         -        MD5STEP(F3, c, d, a, b, in[ 7]+0xf6bb4b60, 16);
  3674         -        MD5STEP(F3, b, c, d, a, in[10]+0xbebfbc70, 23);
  3675         -        MD5STEP(F3, a, b, c, d, in[13]+0x289b7ec6,  4);
  3676         -        MD5STEP(F3, d, a, b, c, in[ 0]+0xeaa127fa, 11);
  3677         -        MD5STEP(F3, c, d, a, b, in[ 3]+0xd4ef3085, 16);
  3678         -        MD5STEP(F3, b, c, d, a, in[ 6]+0x04881d05, 23);
  3679         -        MD5STEP(F3, a, b, c, d, in[ 9]+0xd9d4d039,  4);
  3680         -        MD5STEP(F3, d, a, b, c, in[12]+0xe6db99e5, 11);
  3681         -        MD5STEP(F3, c, d, a, b, in[15]+0x1fa27cf8, 16);
  3682         -        MD5STEP(F3, b, c, d, a, in[ 2]+0xc4ac5665, 23);
  3683         -
  3684         -        MD5STEP(F4, a, b, c, d, in[ 0]+0xf4292244,  6);
  3685         -        MD5STEP(F4, d, a, b, c, in[ 7]+0x432aff97, 10);
  3686         -        MD5STEP(F4, c, d, a, b, in[14]+0xab9423a7, 15);
  3687         -        MD5STEP(F4, b, c, d, a, in[ 5]+0xfc93a039, 21);
  3688         -        MD5STEP(F4, a, b, c, d, in[12]+0x655b59c3,  6);
  3689         -        MD5STEP(F4, d, a, b, c, in[ 3]+0x8f0ccc92, 10);
  3690         -        MD5STEP(F4, c, d, a, b, in[10]+0xffeff47d, 15);
  3691         -        MD5STEP(F4, b, c, d, a, in[ 1]+0x85845dd1, 21);
  3692         -        MD5STEP(F4, a, b, c, d, in[ 8]+0x6fa87e4f,  6);
  3693         -        MD5STEP(F4, d, a, b, c, in[15]+0xfe2ce6e0, 10);
  3694         -        MD5STEP(F4, c, d, a, b, in[ 6]+0xa3014314, 15);
  3695         -        MD5STEP(F4, b, c, d, a, in[13]+0x4e0811a1, 21);
  3696         -        MD5STEP(F4, a, b, c, d, in[ 4]+0xf7537e82,  6);
  3697         -        MD5STEP(F4, d, a, b, c, in[11]+0xbd3af235, 10);
  3698         -        MD5STEP(F4, c, d, a, b, in[ 2]+0x2ad7d2bb, 15);
  3699         -        MD5STEP(F4, b, c, d, a, in[ 9]+0xeb86d391, 21);
  3700         -
  3701         -        buf[0] += a;
  3702         -        buf[1] += b;
  3703         -        buf[2] += c;
  3704         -        buf[3] += d;
  3705         -}
  3706         -
  3707         -/*
  3708         - * Start MD5 accumulation.  Set bit count to 0 and buffer to mysterious
  3709         - * initialization constants.
  3710         - */
  3711         -static void MD5Init(MD5Context *ctx){
  3712         -        ctx->isInit = 1;
  3713         -        ctx->buf[0] = 0x67452301;
  3714         -        ctx->buf[1] = 0xefcdab89;
  3715         -        ctx->buf[2] = 0x98badcfe;
  3716         -        ctx->buf[3] = 0x10325476;
  3717         -        ctx->bits[0] = 0;
  3718         -        ctx->bits[1] = 0;
  3719         -}
  3720         -
  3721         -/*
  3722         - * Update context to reflect the concatenation of another buffer full
  3723         - * of bytes.
  3724         - */
  3725         -static
  3726         -void MD5Update(MD5Context *ctx, const unsigned char *buf, unsigned int len){
  3727         -        uint32 t;
  3728         -
  3729         -        /* Update bitcount */
  3730         -
  3731         -        t = ctx->bits[0];
  3732         -        if ((ctx->bits[0] = t + ((uint32)len << 3)) < t)
  3733         -                ctx->bits[1]++; /* Carry from low to high */
  3734         -        ctx->bits[1] += len >> 29;
  3735         -
  3736         -        t = (t >> 3) & 0x3f;    /* Bytes already in shsInfo->data */
  3737         -
  3738         -        /* Handle any leading odd-sized chunks */
  3739         -
  3740         -        if ( t ) {
  3741         -                unsigned char *p = (unsigned char *)ctx->in + t;
  3742         -
  3743         -                t = 64-t;
  3744         -                if (len < t) {
  3745         -                        memcpy(p, buf, len);
  3746         -                        return;
  3747         -                }
  3748         -                memcpy(p, buf, t);
  3749         -                byteReverse(ctx->in, 16);
  3750         -                MD5Transform(ctx->buf, (uint32 *)ctx->in);
  3751         -                buf += t;
  3752         -                len -= t;
  3753         -        }
  3754         -
  3755         -        /* Process data in 64-byte chunks */
  3756         -
  3757         -        while (len >= 64) {
  3758         -                memcpy(ctx->in, buf, 64);
  3759         -                byteReverse(ctx->in, 16);
  3760         -                MD5Transform(ctx->buf, (uint32 *)ctx->in);
  3761         -                buf += 64;
  3762         -                len -= 64;
  3763         -        }
  3764         -
  3765         -        /* Handle any remaining bytes of data. */
  3766         -
  3767         -        memcpy(ctx->in, buf, len);
  3768         -}
  3769         -
  3770         -/*
  3771         - * Final wrapup - pad to 64-byte boundary with the bit pattern
  3772         - * 1 0* (64-bit count of bits processed, MSB-first)
  3773         - */
  3774         -static void MD5Final(unsigned char digest[16], MD5Context *ctx){
  3775         -        unsigned count;
  3776         -        unsigned char *p;
  3777         -
  3778         -        /* Compute number of bytes mod 64 */
  3779         -        count = (ctx->bits[0] >> 3) & 0x3F;
  3780         -
  3781         -        /* Set the first char of padding to 0x80.  This is safe since there is
  3782         -           always at least one byte free */
  3783         -        p = ctx->in + count;
  3784         -        *p++ = 0x80;
  3785         -
  3786         -        /* Bytes of padding needed to make 64 bytes */
  3787         -        count = 64 - 1 - count;
  3788         -
  3789         -        /* Pad out to 56 mod 64 */
  3790         -        if (count < 8) {
  3791         -                /* Two lots of padding:  Pad the first block to 64 bytes */
  3792         -                memset(p, 0, count);
  3793         -                byteReverse(ctx->in, 16);
  3794         -                MD5Transform(ctx->buf, (uint32 *)ctx->in);
  3795         -
  3796         -                /* Now fill the next block with 56 bytes */
  3797         -                memset(ctx->in, 0, 56);
  3798         -        } else {
  3799         -                /* Pad block to 56 bytes */
  3800         -                memset(p, 0, count-8);
  3801         -        }
  3802         -        byteReverse(ctx->in, 14);
  3803         -
  3804         -        /* Append length in bits and transform */
  3805         -        memcpy(ctx->in + 14*4, ctx->bits, 8);
  3806         -
  3807         -        MD5Transform(ctx->buf, (uint32 *)ctx->in);
  3808         -        byteReverse((unsigned char *)ctx->buf, 4);
  3809         -        memcpy(digest, ctx->buf, 16);
  3810         -}
  3811         -
  3812         -/*
  3813         -** Convert a 128-bit MD5 digest into a 32-digit base-16 number.
  3814         -*/
  3815         -static void MD5DigestToBase16(unsigned char *digest, char *zBuf){
  3816         -  static char const zEncode[] = "0123456789abcdef";
  3817         -  int i, j;
  3818         -
  3819         -  for(j=i=0; i<16; i++){
  3820         -    int a = digest[i];
  3821         -    zBuf[j++] = zEncode[(a>>4)&0xf];
  3822         -    zBuf[j++] = zEncode[a & 0xf];
  3823         -  }
  3824         -  zBuf[j] = 0;
  3825         -}
  3826         -
  3827         -
  3828         -/*
  3829         -** Convert a 128-bit MD5 digest into sequency of eight 5-digit integers
  3830         -** each representing 16 bits of the digest and separated from each
  3831         -** other by a "-" character.
  3832         -*/
  3833         -static void MD5DigestToBase10x8(unsigned char digest[16], char zDigest[50]){
  3834         -  int i, j;
  3835         -  unsigned int x;
  3836         -  for(i=j=0; i<16; i+=2){
  3837         -    x = digest[i]*256 + digest[i+1];
  3838         -    if( i>0 ) zDigest[j++] = '-';
  3839         -    sqlite3_snprintf(50-j, &zDigest[j], "%05u", x);
  3840         -    j += 5;
  3841         -  }
  3842         -  zDigest[j] = 0;
  3843         -}
  3844         -
  3845         -/*
  3846         -** A TCL command for md5.  The argument is the text to be hashed.  The
  3847         -** Result is the hash in base64.
  3848         -*/
  3849         -static int SQLITE_TCLAPI md5_cmd(
  3850         -  void*cd,
  3851         -  Tcl_Interp *interp,
  3852         -  int argc,
  3853         -  const char **argv
  3854         -){
  3855         -  MD5Context ctx;
  3856         -  unsigned char digest[16];
  3857         -  char zBuf[50];
  3858         -  void (*converter)(unsigned char*, char*);
  3859         -
  3860         -  if( argc!=2 ){
  3861         -    Tcl_AppendResult(interp,"wrong # args: should be \"", argv[0],
  3862         -        " TEXT\"", (char*)0);
  3863         -    return TCL_ERROR;
  3864         -  }
  3865         -  MD5Init(&ctx);
  3866         -  MD5Update(&ctx, (unsigned char*)argv[1], (unsigned)strlen(argv[1]));
  3867         -  MD5Final(digest, &ctx);
  3868         -  converter = (void(*)(unsigned char*,char*))cd;
  3869         -  converter(digest, zBuf);
  3870         -  Tcl_AppendResult(interp, zBuf, (char*)0);
  3871         -  return TCL_OK;
  3872         -}
  3873         -
  3874         -/*
  3875         -** A TCL command to take the md5 hash of a file.  The argument is the
  3876         -** name of the file.
  3877         -*/
  3878         -static int SQLITE_TCLAPI md5file_cmd(
  3879         -  void*cd,
  3880         -  Tcl_Interp *interp,
  3881         -  int argc,
  3882         -  const char **argv
  3883         -){
  3884         -  FILE *in;
  3885         -  int ofst;
  3886         -  int amt;
  3887         -  MD5Context ctx;
  3888         -  void (*converter)(unsigned char*, char*);
  3889         -  unsigned char digest[16];
  3890         -  char zBuf[10240];
  3891         -
  3892         -  if( argc!=2 && argc!=4 ){
  3893         -    Tcl_AppendResult(interp,"wrong # args: should be \"", argv[0],
  3894         -        " FILENAME [OFFSET AMT]\"", (char*)0);
  3895         -    return TCL_ERROR;
  3896         -  }
  3897         -  if( argc==4 ){
  3898         -    ofst = atoi(argv[2]);
  3899         -    amt = atoi(argv[3]);
  3900         -  }else{
  3901         -    ofst = 0;
  3902         -    amt = 2147483647;
  3903         -  }
  3904         -  in = fopen(argv[1],"rb");
  3905         -  if( in==0 ){
  3906         -    Tcl_AppendResult(interp,"unable to open file \"", argv[1],
  3907         -         "\" for reading", (char*)0);
  3908         -    return TCL_ERROR;
  3909         -  }
  3910         -  fseek(in, ofst, SEEK_SET);
  3911         -  MD5Init(&ctx);
  3912         -  while( amt>0 ){
  3913         -    int n;
  3914         -    n = (int)fread(zBuf, 1, sizeof(zBuf)<=amt ? sizeof(zBuf) : amt, in);
  3915         -    if( n<=0 ) break;
  3916         -    MD5Update(&ctx, (unsigned char*)zBuf, (unsigned)n);
  3917         -    amt -= n;
  3918         -  }
  3919         -  fclose(in);
  3920         -  MD5Final(digest, &ctx);
  3921         -  converter = (void(*)(unsigned char*,char*))cd;
  3922         -  converter(digest, zBuf);
  3923         -  Tcl_AppendResult(interp, zBuf, (char*)0);
  3924         -  return TCL_OK;
  3925         -}
  3926         -
  3927         -/*
  3928         -** Register the four new TCL commands for generating MD5 checksums
  3929         -** with the TCL interpreter.
  3930         -*/
  3931         -int Md5_Init(Tcl_Interp *interp){
  3932         -  Tcl_CreateCommand(interp, "md5", (Tcl_CmdProc*)md5_cmd,
  3933         -                    MD5DigestToBase16, 0);
  3934         -  Tcl_CreateCommand(interp, "md5-10x8", (Tcl_CmdProc*)md5_cmd,
  3935         -                    MD5DigestToBase10x8, 0);
  3936         -  Tcl_CreateCommand(interp, "md5file", (Tcl_CmdProc*)md5file_cmd,
  3937         -                    MD5DigestToBase16, 0);
  3938         -  Tcl_CreateCommand(interp, "md5file-10x8", (Tcl_CmdProc*)md5file_cmd,
  3939         -                    MD5DigestToBase10x8, 0);
  3940         -  return TCL_OK;
  3941         -}
  3942         -#endif /* defined(SQLITE_TEST) || defined(SQLITE_TCLMD5) */
  3943         -
  3944         -#if defined(SQLITE_TEST)
  3945         -/*
  3946         -** During testing, the special md5sum() aggregate function is available.
  3947         -** inside SQLite.  The following routines implement that function.
  3948         -*/
  3949         -static void md5step(sqlite3_context *context, int argc, sqlite3_value **argv){
  3950         -  MD5Context *p;
  3951         -  int i;
  3952         -  if( argc<1 ) return;
  3953         -  p = sqlite3_aggregate_context(context, sizeof(*p));
  3954         -  if( p==0 ) return;
  3955         -  if( !p->isInit ){
  3956         -    MD5Init(p);
  3957         -  }
  3958         -  for(i=0; i<argc; i++){
  3959         -    const char *zData = (char*)sqlite3_value_text(argv[i]);
  3960         -    if( zData ){
  3961         -      MD5Update(p, (unsigned char*)zData, (int)strlen(zData));
  3962         -    }
  3963         -  }
  3964         -}
  3965         -static void md5finalize(sqlite3_context *context){
  3966         -  MD5Context *p;
  3967         -  unsigned char digest[16];
  3968         -  char zBuf[33];
  3969         -  p = sqlite3_aggregate_context(context, sizeof(*p));
  3970         -  MD5Final(digest,p);
  3971         -  MD5DigestToBase16(digest, zBuf);
  3972         -  sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
  3973         -}
  3974         -int Md5_Register(
  3975         -  sqlite3 *db,
  3976         -  char **pzErrMsg,
  3977         -  const sqlite3_api_routines *pThunk
  3978         -){
  3979         -  int rc = sqlite3_create_function(db, "md5sum", -1, SQLITE_UTF8, 0, 0,
  3980         -                                 md5step, md5finalize);
  3981         -  sqlite3_overload_function(db, "md5sum", -1);  /* To exercise this API */
  3982         -  return rc;
  3983         -}
  3984         -#endif /* defined(SQLITE_TEST) */
  3985         -
  3986         -
  3987         -/*
  3988         -** If the macro TCLSH is one, then put in code this for the
  3989         -** "main" routine that will initialize Tcl and take input from
  3990         -** standard input, or if a file is named on the command line
  3991         -** the TCL interpreter reads and evaluates that file.
  3992         -*/
  3993         -#if TCLSH==1
         3591  +/* This is the main routine for an ordinary TCL shell.  If there are
         3592  +** are arguments, run the first argument as a script.  Otherwise,
         3593  +** read TCL commands from standard input
         3594  +*/
  3994   3595   static const char *tclsh_main_loop(void){
  3995   3596     static const char zMainloop[] =
  3996         -    "set line {}\n"
  3997         -    "while {![eof stdin]} {\n"
  3998         -      "if {$line!=\"\"} {\n"
  3999         -        "puts -nonewline \"> \"\n"
  4000         -      "} else {\n"
  4001         -        "puts -nonewline \"% \"\n"
  4002         -      "}\n"
  4003         -      "flush stdout\n"
  4004         -      "append line [gets stdin]\n"
  4005         -      "if {[info complete $line]} {\n"
  4006         -        "if {[catch {uplevel #0 $line} result]} {\n"
  4007         -          "puts stderr \"Error: $result\"\n"
  4008         -        "} elseif {$result!=\"\"} {\n"
  4009         -          "puts $result\n"
         3597  +    "if {[llength $argv]>=1} {\n"
         3598  +      "set argv0 [lindex $argv 0]\n"
         3599  +      "set argv [lrange $argv 1 end]\n"
         3600  +      "source $argv0\n"
         3601  +    "} else {\n"
         3602  +      "set line {}\n"
         3603  +      "while {![eof stdin]} {\n"
         3604  +        "if {$line!=\"\"} {\n"
         3605  +          "puts -nonewline \"> \"\n"
         3606  +        "} else {\n"
         3607  +          "puts -nonewline \"% \"\n"
  4010   3608           "}\n"
  4011         -        "set line {}\n"
  4012         -      "} else {\n"
  4013         -        "append line \\n\n"
         3609  +        "flush stdout\n"
         3610  +        "append line [gets stdin]\n"
         3611  +        "if {[info complete $line]} {\n"
         3612  +          "if {[catch {uplevel #0 $line} result]} {\n"
         3613  +            "puts stderr \"Error: $result\"\n"
         3614  +          "} elseif {$result!=\"\"} {\n"
         3615  +            "puts $result\n"
         3616  +          "}\n"
         3617  +          "set line {}\n"
         3618  +        "} else {\n"
         3619  +          "append line \\n\n"
         3620  +        "}\n"
  4014   3621         "}\n"
  4015   3622       "}\n"
  4016   3623     ;
  4017   3624     return zMainloop;
  4018   3625   }
  4019         -#endif
  4020         -#if TCLSH==2
  4021         -static const char *tclsh_main_loop(void);
  4022         -#endif
  4023         -
  4024         -#ifdef SQLITE_TEST
  4025         -static void init_all(Tcl_Interp *);
  4026         -static int SQLITE_TCLAPI init_all_cmd(
  4027         -  ClientData cd,
  4028         -  Tcl_Interp *interp,
  4029         -  int objc,
  4030         -  Tcl_Obj *CONST objv[]
  4031         -){
  4032         -
  4033         -  Tcl_Interp *slave;
  4034         -  if( objc!=2 ){
  4035         -    Tcl_WrongNumArgs(interp, 1, objv, "SLAVE");
  4036         -    return TCL_ERROR;
  4037         -  }
  4038         -
  4039         -  slave = Tcl_GetSlave(interp, Tcl_GetString(objv[1]));
  4040         -  if( !slave ){
  4041         -    return TCL_ERROR;
  4042         -  }
  4043         -
  4044         -  init_all(slave);
  4045         -  return TCL_OK;
  4046         -}
  4047         -
  4048         -/*
  4049         -** Tclcmd: db_use_legacy_prepare DB BOOLEAN
  4050         -**
  4051         -**   The first argument to this command must be a database command created by
  4052         -**   [sqlite3]. If the second argument is true, then the handle is configured
  4053         -**   to use the sqlite3_prepare_v2() function to prepare statements. If it
  4054         -**   is false, sqlite3_prepare().
  4055         -*/
  4056         -static int SQLITE_TCLAPI db_use_legacy_prepare_cmd(
  4057         -  ClientData cd,
  4058         -  Tcl_Interp *interp,
  4059         -  int objc,
  4060         -  Tcl_Obj *CONST objv[]
  4061         -){
  4062         -  Tcl_CmdInfo cmdInfo;
  4063         -  SqliteDb *pDb;
  4064         -  int bPrepare;
  4065         -
  4066         -  if( objc!=3 ){
  4067         -    Tcl_WrongNumArgs(interp, 1, objv, "DB BOOLEAN");
  4068         -    return TCL_ERROR;
  4069         -  }
  4070         -
  4071         -  if( !Tcl_GetCommandInfo(interp, Tcl_GetString(objv[1]), &cmdInfo) ){
  4072         -    Tcl_AppendResult(interp, "no such db: ", Tcl_GetString(objv[1]), (char*)0);
  4073         -    return TCL_ERROR;
  4074         -  }
  4075         -  pDb = (SqliteDb*)cmdInfo.objClientData;
  4076         -  if( Tcl_GetBooleanFromObj(interp, objv[2], &bPrepare) ){
  4077         -    return TCL_ERROR;
  4078         -  }
  4079         -
  4080         -  pDb->bLegacyPrepare = bPrepare;
  4081         -
  4082         -  Tcl_ResetResult(interp);
  4083         -  return TCL_OK;
  4084         -}
  4085         -
  4086         -/*
  4087         -** Tclcmd: db_last_stmt_ptr DB
  4088         -**
  4089         -**   If the statement cache associated with database DB is not empty,
  4090         -**   return the text representation of the most recently used statement
  4091         -**   handle.
  4092         -*/
  4093         -static int SQLITE_TCLAPI db_last_stmt_ptr(
  4094         -  ClientData cd,
  4095         -  Tcl_Interp *interp,
  4096         -  int objc,
  4097         -  Tcl_Obj *CONST objv[]
  4098         -){
  4099         -  extern int sqlite3TestMakePointerStr(Tcl_Interp*, char*, void*);
  4100         -  Tcl_CmdInfo cmdInfo;
  4101         -  SqliteDb *pDb;
  4102         -  sqlite3_stmt *pStmt = 0;
  4103         -  char zBuf[100];
  4104         -
  4105         -  if( objc!=2 ){
  4106         -    Tcl_WrongNumArgs(interp, 1, objv, "DB");
  4107         -    return TCL_ERROR;
  4108         -  }
  4109         -
  4110         -  if( !Tcl_GetCommandInfo(interp, Tcl_GetString(objv[1]), &cmdInfo) ){
  4111         -    Tcl_AppendResult(interp, "no such db: ", Tcl_GetString(objv[1]), (char*)0);
  4112         -    return TCL_ERROR;
  4113         -  }
  4114         -  pDb = (SqliteDb*)cmdInfo.objClientData;
  4115         -
  4116         -  if( pDb->stmtList ) pStmt = pDb->stmtList->pStmt;
  4117         -  if( sqlite3TestMakePointerStr(interp, zBuf, pStmt) ){
  4118         -    return TCL_ERROR;
  4119         -  }
  4120         -  Tcl_SetResult(interp, zBuf, TCL_VOLATILE);
  4121         -
  4122         -  return TCL_OK;
  4123         -}
  4124         -#endif /* SQLITE_TEST */
  4125         -
  4126         -/*
  4127         -** Configure the interpreter passed as the first argument to have access
  4128         -** to the commands and linked variables that make up:
  4129         -**
  4130         -**   * the [sqlite3] extension itself,
  4131         -**
  4132         -**   * If SQLITE_TCLMD5 or SQLITE_TEST is defined, the Md5 commands, and
  4133         -**
  4134         -**   * If SQLITE_TEST is set, the various test interfaces used by the Tcl
  4135         -**     test suite.
  4136         -*/
  4137         -static void init_all(Tcl_Interp *interp){
  4138         -  Sqlite3_Init(interp);
  4139         -
  4140         -#if defined(SQLITE_TEST) || defined(SQLITE_TCLMD5)
  4141         -  Md5_Init(interp);
  4142         -#endif
  4143         -
  4144         -#ifdef SQLITE_TEST
  4145         -  {
  4146         -    extern int Sqliteconfig_Init(Tcl_Interp*);
  4147         -    extern int Sqlitetest1_Init(Tcl_Interp*);
  4148         -    extern int Sqlitetest2_Init(Tcl_Interp*);
  4149         -    extern int Sqlitetest3_Init(Tcl_Interp*);
  4150         -    extern int Sqlitetest4_Init(Tcl_Interp*);
  4151         -    extern int Sqlitetest5_Init(Tcl_Interp*);
  4152         -    extern int Sqlitetest6_Init(Tcl_Interp*);
  4153         -    extern int Sqlitetest7_Init(Tcl_Interp*);
  4154         -    extern int Sqlitetest8_Init(Tcl_Interp*);
  4155         -    extern int Sqlitetest9_Init(Tcl_Interp*);
  4156         -    extern int Sqlitetestasync_Init(Tcl_Interp*);
  4157         -    extern int Sqlitetest_autoext_Init(Tcl_Interp*);
  4158         -    extern int Sqlitetest_blob_Init(Tcl_Interp*);
  4159         -    extern int Sqlitetest_demovfs_Init(Tcl_Interp *);
  4160         -    extern int Sqlitetest_func_Init(Tcl_Interp*);
  4161         -    extern int Sqlitetest_hexio_Init(Tcl_Interp*);
  4162         -    extern int Sqlitetest_init_Init(Tcl_Interp*);
  4163         -    extern int Sqlitetest_malloc_Init(Tcl_Interp*);
  4164         -    extern int Sqlitetest_mutex_Init(Tcl_Interp*);
  4165         -    extern int Sqlitetestschema_Init(Tcl_Interp*);
  4166         -    extern int Sqlitetestsse_Init(Tcl_Interp*);
  4167         -    extern int Sqlitetesttclvar_Init(Tcl_Interp*);
  4168         -    extern int Sqlitetestfs_Init(Tcl_Interp*);
  4169         -    extern int SqlitetestThread_Init(Tcl_Interp*);
  4170         -    extern int SqlitetestOnefile_Init();
  4171         -    extern int SqlitetestOsinst_Init(Tcl_Interp*);
  4172         -    extern int Sqlitetestbackup_Init(Tcl_Interp*);
  4173         -    extern int Sqlitetestintarray_Init(Tcl_Interp*);
  4174         -    extern int Sqlitetestvfs_Init(Tcl_Interp *);
  4175         -    extern int Sqlitetestrtree_Init(Tcl_Interp*);
  4176         -    extern int Sqlitequota_Init(Tcl_Interp*);
  4177         -    extern int Sqlitemultiplex_Init(Tcl_Interp*);
  4178         -    extern int SqliteSuperlock_Init(Tcl_Interp*);
  4179         -    extern int SqlitetestSyscall_Init(Tcl_Interp*);
  4180         -#if defined(SQLITE_ENABLE_SESSION) && defined(SQLITE_ENABLE_PREUPDATE_HOOK)
  4181         -    extern int TestSession_Init(Tcl_Interp*);
  4182         -#endif
  4183         -    extern int Fts5tcl_Init(Tcl_Interp *);
  4184         -    extern int SqliteRbu_Init(Tcl_Interp*);
  4185         -    extern int Sqlitetesttcl_Init(Tcl_Interp*);
  4186         -#if defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4)
  4187         -    extern int Sqlitetestfts3_Init(Tcl_Interp *interp);
  4188         -#endif
  4189         -
  4190         -#ifdef SQLITE_ENABLE_ZIPVFS
  4191         -    extern int Zipvfs_Init(Tcl_Interp*);
  4192         -    Zipvfs_Init(interp);
  4193         -#endif
  4194         -
  4195         -    Sqliteconfig_Init(interp);
  4196         -    Sqlitetest1_Init(interp);
  4197         -    Sqlitetest2_Init(interp);
  4198         -    Sqlitetest3_Init(interp);
  4199         -    Sqlitetest4_Init(interp);
  4200         -    Sqlitetest5_Init(interp);
  4201         -    Sqlitetest6_Init(interp);
  4202         -    Sqlitetest7_Init(interp);
  4203         -    Sqlitetest8_Init(interp);
  4204         -    Sqlitetest9_Init(interp);
  4205         -    Sqlitetestasync_Init(interp);
  4206         -    Sqlitetest_autoext_Init(interp);
  4207         -    Sqlitetest_blob_Init(interp);
  4208         -    Sqlitetest_demovfs_Init(interp);
  4209         -    Sqlitetest_func_Init(interp);
  4210         -    Sqlitetest_hexio_Init(interp);
  4211         -    Sqlitetest_init_Init(interp);
  4212         -    Sqlitetest_malloc_Init(interp);
  4213         -    Sqlitetest_mutex_Init(interp);
  4214         -    Sqlitetestschema_Init(interp);
  4215         -    Sqlitetesttclvar_Init(interp);
  4216         -    Sqlitetestfs_Init(interp);
  4217         -    SqlitetestThread_Init(interp);
  4218         -    SqlitetestOnefile_Init();
  4219         -    SqlitetestOsinst_Init(interp);
  4220         -    Sqlitetestbackup_Init(interp);
  4221         -    Sqlitetestintarray_Init(interp);
  4222         -    Sqlitetestvfs_Init(interp);
  4223         -    Sqlitetestrtree_Init(interp);
  4224         -    Sqlitequota_Init(interp);
  4225         -    Sqlitemultiplex_Init(interp);
  4226         -    SqliteSuperlock_Init(interp);
  4227         -    SqlitetestSyscall_Init(interp);
  4228         -#if defined(SQLITE_ENABLE_SESSION) && defined(SQLITE_ENABLE_PREUPDATE_HOOK)
  4229         -    TestSession_Init(interp);
  4230         -#endif
  4231         -    Fts5tcl_Init(interp);
  4232         -    SqliteRbu_Init(interp);
  4233         -    Sqlitetesttcl_Init(interp);
  4234         -
  4235         -#if defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4)
  4236         -    Sqlitetestfts3_Init(interp);
  4237         -#endif
  4238         -
  4239         -    Tcl_CreateObjCommand(
  4240         -        interp, "load_testfixture_extensions", init_all_cmd, 0, 0
  4241         -    );
  4242         -    Tcl_CreateObjCommand(
  4243         -        interp, "db_use_legacy_prepare", db_use_legacy_prepare_cmd, 0, 0
  4244         -    );
  4245         -    Tcl_CreateObjCommand(
  4246         -        interp, "db_last_stmt_ptr", db_last_stmt_ptr, 0, 0
  4247         -    );
  4248         -
  4249         -#ifdef SQLITE_SSE
  4250         -    Sqlitetestsse_Init(interp);
  4251         -#endif
  4252         -  }
  4253         -#endif
  4254         -}
  4255         -
  4256         -/* Needed for the setrlimit() system call on unix */
  4257         -#if defined(unix)
  4258         -#include <sys/resource.h>
  4259         -#endif
  4260   3626   
  4261   3627   #define TCLSH_MAIN main   /* Needed to fake out mktclapp */
  4262   3628   int SQLITE_CDECL TCLSH_MAIN(int argc, char **argv){
  4263   3629     Tcl_Interp *interp;
         3630  +  int i;
         3631  +  const char *zScript = 0;
         3632  +  char zArgc[32];
         3633  +#if defined(TCLSH_INIT_PROC)
         3634  +  extern const char *TCLSH_INIT_PROC(Tcl_Interp*);
         3635  +#endif
  4264   3636   
  4265   3637   #if !defined(_WIN32_WCE)
  4266   3638     if( getenv("BREAK") ){
  4267   3639       fprintf(stderr,
  4268   3640           "attach debugger to process %d and press any key to continue.\n",
  4269   3641           GETPID());
  4270   3642       fgetc(stdin);
  4271   3643     }
  4272   3644   #endif
  4273         -
  4274         -  /* Since the primary use case for this binary is testing of SQLite,
  4275         -  ** be sure to generate core files if we crash */
  4276         -#if defined(SQLITE_TEST) && defined(unix)
  4277         -  { struct rlimit x;
  4278         -    getrlimit(RLIMIT_CORE, &x);
  4279         -    x.rlim_cur = x.rlim_max;
  4280         -    setrlimit(RLIMIT_CORE, &x);
  4281         -  }
  4282         -#endif /* SQLITE_TEST && unix */
  4283         -
  4284   3645   
  4285   3646     /* Call sqlite3_shutdown() once before doing anything else. This is to
  4286   3647     ** test that sqlite3_shutdown() can be safely called by a process before
  4287   3648     ** sqlite3_initialize() is. */
  4288   3649     sqlite3_shutdown();
  4289   3650   
  4290   3651     Tcl_FindExecutable(argv[0]);
  4291   3652     Tcl_SetSystemEncoding(NULL, "utf-8");
  4292   3653     interp = Tcl_CreateInterp();
  4293         -
  4294         -#if TCLSH==2
  4295         -  sqlite3_config(SQLITE_CONFIG_SINGLETHREAD);
  4296         -#endif
         3654  +  Sqlite3_Init(interp);
  4297   3655   
  4298         -  init_all(interp);
  4299         -  if( argc>=2 ){
  4300         -    int i;
  4301         -    char zArgc[32];
  4302         -    sqlite3_snprintf(sizeof(zArgc), zArgc, "%d", argc-(3-TCLSH));
  4303         -    Tcl_SetVar(interp,"argc", zArgc, TCL_GLOBAL_ONLY);
  4304         -    Tcl_SetVar(interp,"argv0",argv[1],TCL_GLOBAL_ONLY);
  4305         -    Tcl_SetVar(interp,"argv", "", TCL_GLOBAL_ONLY);
  4306         -    for(i=3-TCLSH; i<argc; i++){
  4307         -      Tcl_SetVar(interp, "argv", argv[i],
  4308         -          TCL_GLOBAL_ONLY | TCL_LIST_ELEMENT | TCL_APPEND_VALUE);
  4309         -    }
  4310         -    if( TCLSH==1 && Tcl_EvalFile(interp, argv[1])!=TCL_OK ){
  4311         -      const char *zInfo = Tcl_GetVar(interp, "errorInfo", TCL_GLOBAL_ONLY);
  4312         -      if( zInfo==0 ) zInfo = Tcl_GetStringResult(interp);
  4313         -      fprintf(stderr,"%s: %s\n", *argv, zInfo);
  4314         -      return 1;
  4315         -    }
         3656  +  sqlite3_snprintf(sizeof(zArgc), zArgc, "%d", argc-1);
         3657  +  Tcl_SetVar(interp,"argc", zArgc, TCL_GLOBAL_ONLY);
         3658  +  Tcl_SetVar(interp,"argv0",argv[0],TCL_GLOBAL_ONLY);
         3659  +  Tcl_SetVar(interp,"argv", "", TCL_GLOBAL_ONLY);
         3660  +  for(i=1; i<argc; i++){
         3661  +    Tcl_SetVar(interp, "argv", argv[i],
         3662  +        TCL_GLOBAL_ONLY | TCL_LIST_ELEMENT | TCL_APPEND_VALUE);
         3663  +  }
         3664  +#if defined(TCLSH_INIT_PROC)
         3665  +  zScript = TCLSH_INIT_PROC(interp);
         3666  +#endif
         3667  +  if( zScript==0 ){
         3668  +    zScript = tclsh_main_loop();
  4316   3669     }
  4317         -  if( TCLSH==2 || argc<=1 ){
  4318         -    Tcl_GlobalEval(interp, tclsh_main_loop());
         3670  +  if( Tcl_GlobalEval(interp, zScript)!=TCL_OK ){
         3671  +    const char *zInfo = Tcl_GetVar(interp, "errorInfo", TCL_GLOBAL_ONLY);
         3672  +    if( zInfo==0 ) zInfo = Tcl_GetStringResult(interp);
         3673  +    fprintf(stderr,"%s: %s\n", *argv, zInfo);
         3674  +    return 1;
  4319   3675     }
  4320   3676     return 0;
  4321   3677   }
  4322   3678   #endif /* TCLSH */

Added src/test_md5.c.

            1  +/*
            2  +** 2017-10-13
            3  +**
            4  +** The author disclaims copyright to this source code.  In place of
            5  +** a legal notice, here is a blessing:
            6  +**
            7  +**    May you do good and not evil.
            8  +**    May you find forgiveness for yourself and forgive others.
            9  +**    May you share freely, never taking more than you give.
           10  +**
           11  +*************************************************************************
           12  +**
           13  +** This file contains code to implement an MD5 extension to TCL.
           14  +*/
           15  +#include "sqlite3.h"
           16  +#include <stdlib.h>
           17  +#include <string.h>
           18  +#include "sqlite3.h"
           19  +#if defined(INCLUDE_SQLITE_TCL_H)
           20  +# include "sqlite_tcl.h"
           21  +#else
           22  +# include "tcl.h"
           23  +# ifndef SQLITE_TCLAPI
           24  +#  define SQLITE_TCLAPI
           25  +# endif
           26  +#endif
           27  +
           28  +/*
           29  + * This code implements the MD5 message-digest algorithm.
           30  + * The algorithm is due to Ron Rivest.  This code was
           31  + * written by Colin Plumb in 1993, no copyright is claimed.
           32  + * This code is in the public domain; do with it what you wish.
           33  + *
           34  + * Equivalent code is available from RSA Data Security, Inc.
           35  + * This code has been tested against that, and is equivalent,
           36  + * except that you don't need to include two pages of legalese
           37  + * with every copy.
           38  + *
           39  + * To compute the message digest of a chunk of bytes, declare an
           40  + * MD5Context structure, pass it to MD5Init, call MD5Update as
           41  + * needed on buffers full of bytes, and then call MD5Final, which
           42  + * will fill a supplied 16-byte array with the digest.
           43  + */
           44  +
           45  +/*
           46  + * If compiled on a machine that doesn't have a 32-bit integer,
           47  + * you just set "uint32" to the appropriate datatype for an
           48  + * unsigned 32-bit integer.  For example:
           49  + *
           50  + *       cc -Duint32='unsigned long' md5.c
           51  + *
           52  + */
           53  +#ifndef uint32
           54  +#  define uint32 unsigned int
           55  +#endif
           56  +
           57  +struct MD5Context {
           58  +  int isInit;
           59  +  uint32 buf[4];
           60  +  uint32 bits[2];
           61  +  unsigned char in[64];
           62  +};
           63  +typedef struct MD5Context MD5Context;
           64  +
           65  +/*
           66  + * Note: this code is harmless on little-endian machines.
           67  + */
           68  +static void byteReverse (unsigned char *buf, unsigned longs){
           69  +        uint32 t;
           70  +        do {
           71  +                t = (uint32)((unsigned)buf[3]<<8 | buf[2]) << 16 |
           72  +                            ((unsigned)buf[1]<<8 | buf[0]);
           73  +                *(uint32 *)buf = t;
           74  +                buf += 4;
           75  +        } while (--longs);
           76  +}
           77  +/* The four core functions - F1 is optimized somewhat */
           78  +
           79  +/* #define F1(x, y, z) (x & y | ~x & z) */
           80  +#define F1(x, y, z) (z ^ (x & (y ^ z)))
           81  +#define F2(x, y, z) F1(z, x, y)
           82  +#define F3(x, y, z) (x ^ y ^ z)
           83  +#define F4(x, y, z) (y ^ (x | ~z))
           84  +
           85  +/* This is the central step in the MD5 algorithm. */
           86  +#define MD5STEP(f, w, x, y, z, data, s) \
           87  +        ( w += f(x, y, z) + data,  w = w<<s | w>>(32-s),  w += x )
           88  +
           89  +/*
           90  + * The core of the MD5 algorithm, this alters an existing MD5 hash to
           91  + * reflect the addition of 16 longwords of new data.  MD5Update blocks
           92  + * the data and converts bytes into longwords for this routine.
           93  + */
           94  +static void MD5Transform(uint32 buf[4], const uint32 in[16]){
           95  +        register uint32 a, b, c, d;
           96  +
           97  +        a = buf[0];
           98  +        b = buf[1];
           99  +        c = buf[2];
          100  +        d = buf[3];
          101  +
          102  +        MD5STEP(F1, a, b, c, d, in[ 0]+0xd76aa478,  7);
          103  +        MD5STEP(F1, d, a, b, c, in[ 1]+0xe8c7b756, 12);
          104  +        MD5STEP(F1, c, d, a, b, in[ 2]+0x242070db, 17);
          105  +        MD5STEP(F1, b, c, d, a, in[ 3]+0xc1bdceee, 22);
          106  +        MD5STEP(F1, a, b, c, d, in[ 4]+0xf57c0faf,  7);
          107  +        MD5STEP(F1, d, a, b, c, in[ 5]+0x4787c62a, 12);
          108  +        MD5STEP(F1, c, d, a, b, in[ 6]+0xa8304613, 17);
          109  +        MD5STEP(F1, b, c, d, a, in[ 7]+0xfd469501, 22);
          110  +        MD5STEP(F1, a, b, c, d, in[ 8]+0x698098d8,  7);
          111  +        MD5STEP(F1, d, a, b, c, in[ 9]+0x8b44f7af, 12);
          112  +        MD5STEP(F1, c, d, a, b, in[10]+0xffff5bb1, 17);
          113  +        MD5STEP(F1, b, c, d, a, in[11]+0x895cd7be, 22);
          114  +        MD5STEP(F1, a, b, c, d, in[12]+0x6b901122,  7);
          115  +        MD5STEP(F1, d, a, b, c, in[13]+0xfd987193, 12);
          116  +        MD5STEP(F1, c, d, a, b, in[14]+0xa679438e, 17);
          117  +        MD5STEP(F1, b, c, d, a, in[15]+0x49b40821, 22);
          118  +
          119  +        MD5STEP(F2, a, b, c, d, in[ 1]+0xf61e2562,  5);
          120  +        MD5STEP(F2, d, a, b, c, in[ 6]+0xc040b340,  9);
          121  +        MD5STEP(F2, c, d, a, b, in[11]+0x265e5a51, 14);
          122  +        MD5STEP(F2, b, c, d, a, in[ 0]+0xe9b6c7aa, 20);
          123  +        MD5STEP(F2, a, b, c, d, in[ 5]+0xd62f105d,  5);
          124  +        MD5STEP(F2, d, a, b, c, in[10]+0x02441453,  9);
          125  +        MD5STEP(F2, c, d, a, b, in[15]+0xd8a1e681, 14);
          126  +        MD5STEP(F2, b, c, d, a, in[ 4]+0xe7d3fbc8, 20);
          127  +        MD5STEP(F2, a, b, c, d, in[ 9]+0x21e1cde6,  5);
          128  +        MD5STEP(F2, d, a, b, c, in[14]+0xc33707d6,  9);
          129  +        MD5STEP(F2, c, d, a, b, in[ 3]+0xf4d50d87, 14);
          130  +        MD5STEP(F2, b, c, d, a, in[ 8]+0x455a14ed, 20);
          131  +        MD5STEP(F2, a, b, c, d, in[13]+0xa9e3e905,  5);
          132  +        MD5STEP(F2, d, a, b, c, in[ 2]+0xfcefa3f8,  9);
          133  +        MD5STEP(F2, c, d, a, b, in[ 7]+0x676f02d9, 14);
          134  +        MD5STEP(F2, b, c, d, a, in[12]+0x8d2a4c8a, 20);
          135  +
          136  +        MD5STEP(F3, a, b, c, d, in[ 5]+0xfffa3942,  4);
          137  +        MD5STEP(F3, d, a, b, c, in[ 8]+0x8771f681, 11);
          138  +        MD5STEP(F3, c, d, a, b, in[11]+0x6d9d6122, 16);
          139  +        MD5STEP(F3, b, c, d, a, in[14]+0xfde5380c, 23);
          140  +        MD5STEP(F3, a, b, c, d, in[ 1]+0xa4beea44,  4);
          141  +        MD5STEP(F3, d, a, b, c, in[ 4]+0x4bdecfa9, 11);
          142  +        MD5STEP(F3, c, d, a, b, in[ 7]+0xf6bb4b60, 16);
          143  +        MD5STEP(F3, b, c, d, a, in[10]+0xbebfbc70, 23);
          144  +        MD5STEP(F3, a, b, c, d, in[13]+0x289b7ec6,  4);
          145  +        MD5STEP(F3, d, a, b, c, in[ 0]+0xeaa127fa, 11);
          146  +        MD5STEP(F3, c, d, a, b, in[ 3]+0xd4ef3085, 16);
          147  +        MD5STEP(F3, b, c, d, a, in[ 6]+0x04881d05, 23);
          148  +        MD5STEP(F3, a, b, c, d, in[ 9]+0xd9d4d039,  4);
          149  +        MD5STEP(F3, d, a, b, c, in[12]+0xe6db99e5, 11);
          150  +        MD5STEP(F3, c, d, a, b, in[15]+0x1fa27cf8, 16);
          151  +        MD5STEP(F3, b, c, d, a, in[ 2]+0xc4ac5665, 23);
          152  +
          153  +        MD5STEP(F4, a, b, c, d, in[ 0]+0xf4292244,  6);
          154  +        MD5STEP(F4, d, a, b, c, in[ 7]+0x432aff97, 10);
          155  +        MD5STEP(F4, c, d, a, b, in[14]+0xab9423a7, 15);
          156  +        MD5STEP(F4, b, c, d, a, in[ 5]+0xfc93a039, 21);
          157  +        MD5STEP(F4, a, b, c, d, in[12]+0x655b59c3,  6);
          158  +        MD5STEP(F4, d, a, b, c, in[ 3]+0x8f0ccc92, 10);
          159  +        MD5STEP(F4, c, d, a, b, in[10]+0xffeff47d, 15);
          160  +        MD5STEP(F4, b, c, d, a, in[ 1]+0x85845dd1, 21);
          161  +        MD5STEP(F4, a, b, c, d, in[ 8]+0x6fa87e4f,  6);
          162  +        MD5STEP(F4, d, a, b, c, in[15]+0xfe2ce6e0, 10);
          163  +        MD5STEP(F4, c, d, a, b, in[ 6]+0xa3014314, 15);
          164  +        MD5STEP(F4, b, c, d, a, in[13]+0x4e0811a1, 21);
          165  +        MD5STEP(F4, a, b, c, d, in[ 4]+0xf7537e82,  6);
          166  +        MD5STEP(F4, d, a, b, c, in[11]+0xbd3af235, 10);
          167  +        MD5STEP(F4, c, d, a, b, in[ 2]+0x2ad7d2bb, 15);
          168  +        MD5STEP(F4, b, c, d, a, in[ 9]+0xeb86d391, 21);
          169  +
          170  +        buf[0] += a;
          171  +        buf[1] += b;
          172  +        buf[2] += c;
          173  +        buf[3] += d;
          174  +}
          175  +
          176  +/*
          177  + * Start MD5 accumulation.  Set bit count to 0 and buffer to mysterious
          178  + * initialization constants.
          179  + */
          180  +static void MD5Init(MD5Context *ctx){
          181  +        ctx->isInit = 1;
          182  +        ctx->buf[0] = 0x67452301;
          183  +        ctx->buf[1] = 0xefcdab89;
          184  +        ctx->buf[2] = 0x98badcfe;
          185  +        ctx->buf[3] = 0x10325476;
          186  +        ctx->bits[0] = 0;
          187  +        ctx->bits[1] = 0;
          188  +}
          189  +
          190  +/*
          191  + * Update context to reflect the concatenation of another buffer full
          192  + * of bytes.
          193  + */
          194  +static
          195  +void MD5Update(MD5Context *ctx, const unsigned char *buf, unsigned int len){
          196  +        uint32 t;
          197  +
          198  +        /* Update bitcount */
          199  +
          200  +        t = ctx->bits[0];
          201  +        if ((ctx->bits[0] = t + ((uint32)len << 3)) < t)
          202  +                ctx->bits[1]++; /* Carry from low to high */
          203  +        ctx->bits[1] += len >> 29;
          204  +
          205  +        t = (t >> 3) & 0x3f;    /* Bytes already in shsInfo->data */
          206  +
          207  +        /* Handle any leading odd-sized chunks */
          208  +
          209  +        if ( t ) {
          210  +                unsigned char *p = (unsigned char *)ctx->in + t;
          211  +
          212  +                t = 64-t;
          213  +                if (len < t) {
          214  +                        memcpy(p, buf, len);
          215  +                        return;
          216  +                }
          217  +                memcpy(p, buf, t);
          218  +                byteReverse(ctx->in, 16);
          219  +                MD5Transform(ctx->buf, (uint32 *)ctx->in);
          220  +                buf += t;
          221  +                len -= t;
          222  +        }
          223  +
          224  +        /* Process data in 64-byte chunks */
          225  +
          226  +        while (len >= 64) {
          227  +                memcpy(ctx->in, buf, 64);
          228  +                byteReverse(ctx->in, 16);
          229  +                MD5Transform(ctx->buf, (uint32 *)ctx->in);
          230  +                buf += 64;
          231  +                len -= 64;
          232  +        }
          233  +
          234  +        /* Handle any remaining bytes of data. */
          235  +
          236  +        memcpy(ctx->in, buf, len);
          237  +}
          238  +
          239  +/*
          240  + * Final wrapup - pad to 64-byte boundary with the bit pattern
          241  + * 1 0* (64-bit count of bits processed, MSB-first)
          242  + */
          243  +static void MD5Final(unsigned char digest[16], MD5Context *ctx){
          244  +        unsigned count;
          245  +        unsigned char *p;
          246  +
          247  +        /* Compute number of bytes mod 64 */
          248  +        count = (ctx->bits[0] >> 3) & 0x3F;
          249  +
          250  +        /* Set the first char of padding to 0x80.  This is safe since there is
          251  +           always at least one byte free */
          252  +        p = ctx->in + count;
          253  +        *p++ = 0x80;
          254  +
          255  +        /* Bytes of padding needed to make 64 bytes */
          256  +        count = 64 - 1 - count;
          257  +
          258  +        /* Pad out to 56 mod 64 */
          259  +        if (count < 8) {
          260  +                /* Two lots of padding:  Pad the first block to 64 bytes */
          261  +                memset(p, 0, count);
          262  +                byteReverse(ctx->in, 16);
          263  +                MD5Transform(ctx->buf, (uint32 *)ctx->in);
          264  +
          265  +                /* Now fill the next block with 56 bytes */
          266  +                memset(ctx->in, 0, 56);
          267  +        } else {
          268  +                /* Pad block to 56 bytes */
          269  +                memset(p, 0, count-8);
          270  +        }
          271  +        byteReverse(ctx->in, 14);
          272  +
          273  +        /* Append length in bits and transform */
          274  +        memcpy(ctx->in + 14*4, ctx->bits, 8);
          275  +
          276  +        MD5Transform(ctx->buf, (uint32 *)ctx->in);
          277  +        byteReverse((unsigned char *)ctx->buf, 4);
          278  +        memcpy(digest, ctx->buf, 16);
          279  +}
          280  +
          281  +/*
          282  +** Convert a 128-bit MD5 digest into a 32-digit base-16 number.
          283  +*/
          284  +static void MD5DigestToBase16(unsigned char *digest, char *zBuf){
          285  +  static char const zEncode[] = "0123456789abcdef";
          286  +  int i, j;
          287  +
          288  +  for(j=i=0; i<16; i++){
          289  +    int a = digest[i];
          290  +    zBuf[j++] = zEncode[(a>>4)&0xf];
          291  +    zBuf[j++] = zEncode[a & 0xf];
          292  +  }
          293  +  zBuf[j] = 0;
          294  +}
          295  +
          296  +
          297  +/*
          298  +** Convert a 128-bit MD5 digest into sequency of eight 5-digit integers
          299  +** each representing 16 bits of the digest and separated from each
          300  +** other by a "-" character.
          301  +*/
          302  +static void MD5DigestToBase10x8(unsigned char digest[16], char zDigest[50]){
          303  +  int i, j;
          304  +  unsigned int x;
          305  +  for(i=j=0; i<16; i+=2){
          306  +    x = digest[i]*256 + digest[i+1];
          307  +    if( i>0 ) zDigest[j++] = '-';
          308  +    sqlite3_snprintf(50-j, &zDigest[j], "%05u", x);
          309  +    j += 5;
          310  +  }
          311  +  zDigest[j] = 0;
          312  +}
          313  +
          314  +/*
          315  +** A TCL command for md5.  The argument is the text to be hashed.  The
          316  +** Result is the hash in base64.
          317  +*/
          318  +static int SQLITE_TCLAPI md5_cmd(
          319  +  void*cd,
          320  +  Tcl_Interp *interp,
          321  +  int argc,
          322  +  const char **argv
          323  +){
          324  +  MD5Context ctx;
          325  +  unsigned char digest[16];
          326  +  char zBuf[50];
          327  +  void (*converter)(unsigned char*, char*);
          328  +
          329  +  if( argc!=2 ){
          330  +    Tcl_AppendResult(interp,"wrong # args: should be \"", argv[0],
          331  +        " TEXT\"", (char*)0);
          332  +    return TCL_ERROR;
          333  +  }
          334  +  MD5Init(&ctx);
          335  +  MD5Update(&ctx, (unsigned char*)argv[1], (unsigned)strlen(argv[1]));
          336  +  MD5Final(digest, &ctx);
          337  +  converter = (void(*)(unsigned char*,char*))cd;
          338  +  converter(digest, zBuf);
          339  +  Tcl_AppendResult(interp, zBuf, (char*)0);
          340  +  return TCL_OK;
          341  +}
          342  +
          343  +/*
          344  +** A TCL command to take the md5 hash of a file.  The argument is the
          345  +** name of the file.
          346  +*/
          347  +static int SQLITE_TCLAPI md5file_cmd(
          348  +  void*cd,
          349  +  Tcl_Interp *interp,
          350  +  int argc,
          351  +  const char **argv
          352  +){
          353  +  FILE *in;
          354  +  int ofst;
          355  +  int amt;
          356  +  MD5Context ctx;
          357  +  void (*converter)(unsigned char*, char*);
          358  +  unsigned char digest[16];
          359  +  char zBuf[10240];
          360  +
          361  +  if( argc!=2 && argc!=4 ){
          362  +    Tcl_AppendResult(interp,"wrong # args: should be \"", argv[0],
          363  +        " FILENAME [OFFSET AMT]\"", (char*)0);
          364  +    return TCL_ERROR;
          365  +  }
          366  +  if( argc==4 ){
          367  +    ofst = atoi(argv[2]);
          368  +    amt = atoi(argv[3]);
          369  +  }else{
          370  +    ofst = 0;
          371  +    amt = 2147483647;
          372  +  }
          373  +  in = fopen(argv[1],"rb");
          374  +  if( in==0 ){
          375  +    Tcl_AppendResult(interp,"unable to open file \"", argv[1],
          376  +         "\" for reading", (char*)0);
          377  +    return TCL_ERROR;
          378  +  }
          379  +  fseek(in, ofst, SEEK_SET);
          380  +  MD5Init(&ctx);
          381  +  while( amt>0 ){
          382  +    int n;
          383  +    n = (int)fread(zBuf, 1, sizeof(zBuf)<=amt ? sizeof(zBuf) : amt, in);
          384  +    if( n<=0 ) break;
          385  +    MD5Update(&ctx, (unsigned char*)zBuf, (unsigned)n);
          386  +    amt -= n;
          387  +  }
          388  +  fclose(in);
          389  +  MD5Final(digest, &ctx);
          390  +  converter = (void(*)(unsigned char*,char*))cd;
          391  +  converter(digest, zBuf);
          392  +  Tcl_AppendResult(interp, zBuf, (char*)0);
          393  +  return TCL_OK;
          394  +}
          395  +
          396  +/*
          397  +** Register the four new TCL commands for generating MD5 checksums
          398  +** with the TCL interpreter.
          399  +*/
          400  +int Md5_Init(Tcl_Interp *interp){
          401  +  Tcl_CreateCommand(interp, "md5", (Tcl_CmdProc*)md5_cmd,
          402  +                    MD5DigestToBase16, 0);
          403  +  Tcl_CreateCommand(interp, "md5-10x8", (Tcl_CmdProc*)md5_cmd,
          404  +                    MD5DigestToBase10x8, 0);
          405  +  Tcl_CreateCommand(interp, "md5file", (Tcl_CmdProc*)md5file_cmd,
          406  +                    MD5DigestToBase16, 0);
          407  +  Tcl_CreateCommand(interp, "md5file-10x8", (Tcl_CmdProc*)md5file_cmd,
          408  +                    MD5DigestToBase10x8, 0);
          409  +  return TCL_OK;
          410  +}
          411  +
          412  +/*
          413  +** During testing, the special md5sum() aggregate function is available.
          414  +** inside SQLite.  The following routines implement that function.
          415  +*/
          416  +static void md5step(sqlite3_context *context, int argc, sqlite3_value **argv){
          417  +  MD5Context *p;
          418  +  int i;
          419  +  if( argc<1 ) return;
          420  +  p = sqlite3_aggregate_context(context, sizeof(*p));
          421  +  if( p==0 ) return;
          422  +  if( !p->isInit ){
          423  +    MD5Init(p);
          424  +  }
          425  +  for(i=0; i<argc; i++){
          426  +    const char *zData = (char*)sqlite3_value_text(argv[i]);
          427  +    if( zData ){
          428  +      MD5Update(p, (unsigned char*)zData, (int)strlen(zData));
          429  +    }
          430  +  }
          431  +}
          432  +static void md5finalize(sqlite3_context *context){
          433  +  MD5Context *p;
          434  +  unsigned char digest[16];
          435  +  char zBuf[33];
          436  +  p = sqlite3_aggregate_context(context, sizeof(*p));
          437  +  MD5Final(digest,p);
          438  +  MD5DigestToBase16(digest, zBuf);
          439  +  sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
          440  +}
          441  +int Md5_Register(
          442  +  sqlite3 *db,
          443  +  char **pzErrMsg,
          444  +  const sqlite3_api_routines *pThunk
          445  +){
          446  +  int rc = sqlite3_create_function(db, "md5sum", -1, SQLITE_UTF8, 0, 0,
          447  +                                 md5step, md5finalize);
          448  +  sqlite3_overload_function(db, "md5sum", -1);  /* To exercise this API */
          449  +  return rc;
          450  +}

Added src/test_tclsh.c.

            1  +/*
            2  +** 2017-10-13
            3  +**
            4  +** The author disclaims copyright to this source code.  In place of
            5  +** a legal notice, here is a blessing:
            6  +**
            7  +**    May you do good and not evil.
            8  +**    May you find forgiveness for yourself and forgive others.
            9  +**    May you share freely, never taking more than you give.
           10  +**
           11  +*************************************************************************
           12  +**
           13  +** This file contains extensions to the the "tclsqlite.c" module used for
           14  +** testing.  Basically, all of the other "test_*.c" modules are linked
           15  +** into the enhanced tclsh used for testing (and named "testfixture" or
           16  +** "testfixture.exe") using logic encoded by this file.
           17  +**
           18  +** The code in this file used to be found in tclsqlite3.c, contained within
           19  +** #if SQLITE_TEST ... #endif.  It is factored out into this separate module
           20  +** in an effort to keep the tclsqlite.c file pure.
           21  +*/
           22  +#include "sqlite3.h"
           23  +#if defined(INCLUDE_SQLITE_TCL_H)
           24  +# include "sqlite_tcl.h"
           25  +#else
           26  +# include "tcl.h"
           27  +# ifndef SQLITE_TCLAPI
           28  +#  define SQLITE_TCLAPI
           29  +# endif
           30  +#endif
           31  +
           32  +/* Needed for the setrlimit() system call on unix */
           33  +#if defined(unix)
           34  +#include <sys/resource.h>
           35  +#endif
           36  +
           37  +/* Forward declaration */
           38  +static int SQLITE_TCLAPI load_testfixture_extensions(
           39  +  ClientData cd,
           40  +  Tcl_Interp *interp,
           41  +  int objc,
           42  +  Tcl_Obj *CONST objv[]
           43  +);
           44  +
           45  +/*
           46  +** This routine is the primary export of this file.
           47  +**
           48  +** Configure the interpreter passed as the first argument to have access
           49  +** to the commands and linked variables that make up:
           50  +**
           51  +**   * the [sqlite3] extension itself,
           52  +**
           53  +**   * If SQLITE_TCLMD5 or SQLITE_TEST is defined, the Md5 commands, and
           54  +**
           55  +**   * If SQLITE_TEST is set, the various test interfaces used by the Tcl
           56  +**     test suite.
           57  +*/
           58  +const char *sqlite3TestInit(Tcl_Interp *interp){
           59  +  extern int Sqlite3_Init(Tcl_Interp*);
           60  +  extern int Sqliteconfig_Init(Tcl_Interp*);
           61  +  extern int Sqlitetest1_Init(Tcl_Interp*);
           62  +  extern int Sqlitetest2_Init(Tcl_Interp*);
           63  +  extern int Sqlitetest3_Init(Tcl_Interp*);
           64  +  extern int Sqlitetest4_Init(Tcl_Interp*);
           65  +  extern int Sqlitetest5_Init(Tcl_Interp*);
           66  +  extern int Sqlitetest6_Init(Tcl_Interp*);
           67  +  extern int Sqlitetest7_Init(Tcl_Interp*);
           68  +  extern int Sqlitetest8_Init(Tcl_Interp*);
           69  +  extern int Sqlitetest9_Init(Tcl_Interp*);
           70  +  extern int Sqlitetestasync_Init(Tcl_Interp*);
           71  +  extern int Sqlitetest_autoext_Init(Tcl_Interp*);
           72  +  extern int Sqlitetest_blob_Init(Tcl_Interp*);
           73  +  extern int Sqlitetest_demovfs_Init(Tcl_Interp *);
           74  +  extern int Sqlitetest_func_Init(Tcl_Interp*);
           75  +  extern int Sqlitetest_hexio_Init(Tcl_Interp*);
           76  +  extern int Sqlitetest_init_Init(Tcl_Interp*);
           77  +  extern int Sqlitetest_malloc_Init(Tcl_Interp*);
           78  +  extern int Sqlitetest_mutex_Init(Tcl_Interp*);
           79  +  extern int Sqlitetestschema_Init(Tcl_Interp*);
           80  +  extern int Sqlitetestsse_Init(Tcl_Interp*);
           81  +  extern int Sqlitetesttclvar_Init(Tcl_Interp*);
           82  +  extern int Sqlitetestfs_Init(Tcl_Interp*);
           83  +  extern int SqlitetestThread_Init(Tcl_Interp*);
           84  +  extern int SqlitetestOnefile_Init();
           85  +  extern int SqlitetestOsinst_Init(Tcl_Interp*);
           86  +  extern int Sqlitetestbackup_Init(Tcl_Interp*);
           87  +  extern int Sqlitetestintarray_Init(Tcl_Interp*);
           88  +  extern int Sqlitetestvfs_Init(Tcl_Interp *);
           89  +  extern int Sqlitetestrtree_Init(Tcl_Interp*);
           90  +  extern int Sqlitequota_Init(Tcl_Interp*);
           91  +  extern int Sqlitemultiplex_Init(Tcl_Interp*);
           92  +  extern int SqliteSuperlock_Init(Tcl_Interp*);
           93  +  extern int SqlitetestSyscall_Init(Tcl_Interp*);
           94  +#if defined(SQLITE_ENABLE_SESSION) && defined(SQLITE_ENABLE_PREUPDATE_HOOK)
           95  +  extern int TestSession_Init(Tcl_Interp*);
           96  +#endif
           97  +  extern int Md5_Init(Tcl_Interp*);
           98  +  extern int Fts5tcl_Init(Tcl_Interp *);
           99  +  extern int SqliteRbu_Init(Tcl_Interp*);
          100  +  extern int Sqlitetesttcl_Init(Tcl_Interp*);
          101  +#if defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4)
          102  +  extern int Sqlitetestfts3_Init(Tcl_Interp *interp);
          103  +#endif
          104  +#ifdef SQLITE_ENABLE_ZIPVFS
          105  +  extern int Zipvfs_Init(Tcl_Interp*);
          106  +#endif
          107  +  Tcl_CmdInfo cmdInfo;
          108  +
          109  +  /* Since the primary use case for this binary is testing of SQLite,
          110  +  ** be sure to generate core files if we crash */
          111  +#if defined(unix)
          112  +  { struct rlimit x;
          113  +    getrlimit(RLIMIT_CORE, &x);
          114  +    x.rlim_cur = x.rlim_max;
          115  +    setrlimit(RLIMIT_CORE, &x);
          116  +  }
          117  +#endif /* unix */
          118  +
          119  +  if( Tcl_GetCommandInfo(interp, "sqlite3", &cmdInfo)==0 ){
          120  +    Sqlite3_Init(interp);
          121  +  }
          122  +#ifdef SQLITE_ENABLE_ZIPVFS
          123  +  Zipvfs_Init(interp);
          124  +#endif
          125  +  Md5_Init(interp);
          126  +  Sqliteconfig_Init(interp);
          127  +  Sqlitetest1_Init(interp);
          128  +  Sqlitetest2_Init(interp);
          129  +  Sqlitetest3_Init(interp);
          130  +  Sqlitetest4_Init(interp);
          131  +  Sqlitetest5_Init(interp);
          132  +  Sqlitetest6_Init(interp);
          133  +  Sqlitetest7_Init(interp);
          134  +  Sqlitetest8_Init(interp);
          135  +  Sqlitetest9_Init(interp);
          136  +  Sqlitetestasync_Init(interp);
          137  +  Sqlitetest_autoext_Init(interp);
          138  +  Sqlitetest_blob_Init(interp);
          139  +  Sqlitetest_demovfs_Init(interp);
          140  +  Sqlitetest_func_Init(interp);
          141  +  Sqlitetest_hexio_Init(interp);
          142  +  Sqlitetest_init_Init(interp);
          143  +  Sqlitetest_malloc_Init(interp);
          144  +  Sqlitetest_mutex_Init(interp);
          145  +  Sqlitetestschema_Init(interp);
          146  +  Sqlitetesttclvar_Init(interp);
          147  +  Sqlitetestfs_Init(interp);
          148  +  SqlitetestThread_Init(interp);
          149  +  SqlitetestOnefile_Init();
          150  +  SqlitetestOsinst_Init(interp);
          151  +  Sqlitetestbackup_Init(interp);
          152  +  Sqlitetestintarray_Init(interp);
          153  +  Sqlitetestvfs_Init(interp);
          154  +  Sqlitetestrtree_Init(interp);
          155  +  Sqlitequota_Init(interp);
          156  +  Sqlitemultiplex_Init(interp);
          157  +  SqliteSuperlock_Init(interp);
          158  +  SqlitetestSyscall_Init(interp);
          159  +#if defined(SQLITE_ENABLE_SESSION) && defined(SQLITE_ENABLE_PREUPDATE_HOOK)
          160  +  TestSession_Init(interp);
          161  +#endif
          162  +  Fts5tcl_Init(interp);
          163  +  SqliteRbu_Init(interp);
          164  +  Sqlitetesttcl_Init(interp);
          165  +
          166  +#if defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4)
          167  +  Sqlitetestfts3_Init(interp);
          168  +#endif
          169  +
          170  +  Tcl_CreateObjCommand(
          171  +      interp, "load_testfixture_extensions", load_testfixture_extensions,0,0
          172  +  );
          173  +  return 0;
          174  +}
          175  +
          176  +/* tclcmd:   load_testfixture_extensions
          177  +*/
          178  +static int SQLITE_TCLAPI load_testfixture_extensions(
          179  +  ClientData cd,
          180  +  Tcl_Interp *interp,
          181  +  int objc,
          182  +  Tcl_Obj *CONST objv[]
          183  +){
          184  +
          185  +  Tcl_Interp *slave;
          186  +  if( objc!=2 ){
          187  +    Tcl_WrongNumArgs(interp, 1, objv, "SLAVE");
          188  +    return TCL_ERROR;
          189  +  }
          190  +
          191  +  slave = Tcl_GetSlave(interp, Tcl_GetString(objv[1]));
          192  +  if( !slave ){
          193  +    return TCL_ERROR;
          194  +  }
          195  +
          196  +  (void)sqlite3TestInit(slave);
          197  +  return TCL_OK;
          198  +}

Changes to src/where.c.

  1881   1881     }
  1882   1882   }
  1883   1883   
  1884   1884   /*
  1885   1885   ** Return TRUE if all of the following are true:
  1886   1886   **
  1887   1887   **   (1)  X has the same or lower cost that Y
  1888         -**   (2)  X is a proper subset of Y
  1889         -**   (3)  X skips at least as many columns as Y
         1888  +**   (2)  X uses fewer WHERE clause terms than Y
         1889  +**   (3)  Every WHERE clause term used by X is also used by Y
         1890  +**   (4)  X skips at least as many columns as Y
         1891  +**   (5)  If X is a covering index, than Y is too
  1890   1892   **
  1891         -** By "proper subset" we mean that X uses fewer WHERE clause terms
  1892         -** than Y and that every WHERE clause term used by X is also used
  1893         -** by Y.
  1894         -**
         1893  +** Conditions (2) and (3) mean that X is a "proper subset" of Y.
  1895   1894   ** If X is a proper subset of Y then Y is a better choice and ought
  1896   1895   ** to have a lower cost.  This routine returns TRUE when that cost 
  1897         -** relationship is inverted and needs to be adjusted.  The third rule
         1896  +** relationship is inverted and needs to be adjusted.  Constraint (4)
  1898   1897   ** was added because if X uses skip-scan less than Y it still might
  1899         -** deserve a lower cost even if it is a proper subset of Y.
         1898  +** deserve a lower cost even if it is a proper subset of Y.  Constraint (5)
         1899  +** was added because a covering index probably deserves to have a lower cost
         1900  +** than a non-covering index even if it is a proper subset.
  1900   1901   */
  1901   1902   static int whereLoopCheaperProperSubset(
  1902   1903     const WhereLoop *pX,       /* First WhereLoop to compare */
  1903   1904     const WhereLoop *pY        /* Compare against this WhereLoop */
  1904   1905   ){
  1905   1906     int i, j;
  1906   1907     if( pX->nLTerm-pX->nSkip >= pY->nLTerm-pY->nSkip ){
................................................................................
  1913   1914     }
  1914   1915     for(i=pX->nLTerm-1; i>=0; i--){
  1915   1916       if( pX->aLTerm[i]==0 ) continue;
  1916   1917       for(j=pY->nLTerm-1; j>=0; j--){
  1917   1918         if( pY->aLTerm[j]==pX->aLTerm[i] ) break;
  1918   1919       }
  1919   1920       if( j<0 ) return 0;  /* X not a subset of Y since term X[i] not used by Y */
         1921  +  }
         1922  +  if( (pX->wsFlags&WHERE_IDX_ONLY)!=0 
         1923  +   && (pY->wsFlags&WHERE_IDX_ONLY)==0 ){
         1924  +    return 0;  /* Constraint (5) */
  1920   1925     }
  1921   1926     return 1;  /* All conditions meet */
  1922   1927   }
  1923   1928   
  1924   1929   /*
  1925   1930   ** Try to adjust the cost of WhereLoop pTemplate upwards or downwards so
  1926   1931   ** that:

Changes to test/analyze9.test.

  1048   1048     INSERT INTO t4 SELECT a, b, c, d, e, f FROM data;
  1049   1049     ANALYZE;
  1050   1050   } {}
  1051   1051   
  1052   1052   do_eqp_test 23.1 {
  1053   1053     SELECT * FROM t4 WHERE 
  1054   1054       (e=1 AND b='xyz' AND c='zyx' AND a<'AEA') AND f<300
         1055  +  -- Formerly used index i41.  But i41 is not a covering index whereas
         1056  +  -- the PRIMARY KEY is a covering index, and so as of 2017-10-15, the
         1057  +  -- PRIMARY KEY is preferred.
  1055   1058   } {
  1056         -  0 0 0 {SEARCH TABLE t4 USING INDEX i41 (e=? AND c=? AND b=? AND a<?)}
         1059  +  0 0 0 {SEARCH TABLE t4 USING PRIMARY KEY (c=? AND b=? AND a<?)}
  1057   1060   }
  1058   1061   do_eqp_test 23.2 {
  1059   1062     SELECT * FROM t4 WHERE 
  1060   1063       (e=1 AND b='xyz' AND c='zyx' AND a<'JJJ') AND f<300
  1061   1064   } {
  1062   1065     0 0 0 {SEARCH TABLE t4 USING INDEX i42 (f<?)}
  1063   1066   }

Added test/checkfreelist.test.

            1  +# 2017-10-11
            2  +#
            3  +# The author disclaims copyright to this source code.  In place of
            4  +# a legal notice, here is a blessing:
            5  +#
            6  +#    May you do good and not evil.
            7  +#    May you find forgiveness for yourself and forgive others.
            8  +#    May you share freely, never taking more than you give.
            9  +#
           10  +#***********************************************************************
           11  +# This file implements regression tests for SQLite library.  The
           12  +# focus of this file is testing the checkfreelist extension.
           13  +#
           14  +
           15  +set testdir [file dirname $argv0]
           16  +source $testdir/tester.tcl
           17  +set testprefix checkfreelist
           18  +
           19  +ifcapable !vtab||!compound {
           20  +  finish_test
           21  +  return
           22  +}
           23  +
           24  +if {[file exists ../checkfreelist.so]==0} {
           25  +  finish_test
           26  +  return
           27  +}
           28  +
           29  +do_execsql_test 1.0 {
           30  +  CREATE TABLE t1(a, b);
           31  +}
           32  +
           33  +db enable_load_extension 1
           34  +do_execsql_test 1.1 {
           35  +  SELECT load_extension('../checkfreelist.so');
           36  +} {{}}
           37  +
           38  +do_execsql_test 1.2 { SELECT checkfreelist('main') } {ok}
           39  +do_execsql_test 1.3 {
           40  +  WITH s(i) AS (
           41  +    SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<10000
           42  +  )
           43  +  INSERT INTO t1 SELECT randomblob(400), randomblob(400) FROM s;
           44  +  DELETE FROM t1 WHERE rowid%3;
           45  +  PRAGMA freelist_count;
           46  +} {6726}
           47  +
           48  +do_execsql_test 1.4 { SELECT checkfreelist('main') } {ok}
           49  +do_execsql_test 1.5 {
           50  +  WITH freelist_trunk(i, d, n) AS (
           51  +    SELECT 1, NULL, sqlite_readint32(data, 32) FROM sqlite_dbpage WHERE pgno=1
           52  +      UNION ALL
           53  +    SELECT n, data, sqlite_readint32(data) 
           54  +    FROM freelist_trunk, sqlite_dbpage WHERE pgno=n
           55  +  )
           56  +  SELECT i FROM freelist_trunk WHERE i!=1;
           57  +} {
           58  +  10010 9716 9344 8970 8596 8223 7848 7475 7103 6728 6355 5983 5609 5235
           59  +  4861 4488 4113 3741 3368 2993 2620 2248 1873 1500 1126 753 378 5
           60  +}
           61  +
           62  +do_execsql_test 1.6 { SELECT checkfreelist('main') } {ok}
           63  +
           64  +proc set_int {blob idx newval} {
           65  +  binary scan $blob I* ints
           66  +  lset ints $idx $newval
           67  +  binary format I* $ints
           68  +}
           69  +db func set_int set_int
           70  +
           71  +proc get_int {blob idx} {
           72  +  binary scan $blob I* ints
           73  +  lindex $ints $idx
           74  +}
           75  +db func get_int get_int
           76  +
           77  +do_execsql_test 1.7 {
           78  +  BEGIN;
           79  +    UPDATE sqlite_dbpage 
           80  +      SET data = set_int(data, 1, get_int(data, 1)-1) 
           81  +      WHERE pgno=4861;
           82  +    SELECT checkfreelist('main');
           83  +  ROLLBACK;
           84  +} {{free-list count mismatch: actual=6725 header=6726}}
           85  +
           86  +do_execsql_test 1.8 {
           87  +  BEGIN;
           88  +    UPDATE sqlite_dbpage 
           89  +      SET data = set_int(data, 5, (SELECT * FROM pragma_page_count)+1)
           90  +      WHERE pgno=4861;
           91  +    SELECT checkfreelist('main');
           92  +  ROLLBACK;
           93  +} {{leaf page 10093 is out of range (child 3 of trunk page 4861)}}
           94  +
           95  +do_execsql_test 1.9 {
           96  +  BEGIN;
           97  +    UPDATE sqlite_dbpage 
           98  +      SET data = set_int(data, 5, 0)
           99  +      WHERE pgno=4861;
          100  +    SELECT checkfreelist('main');
          101  +  ROLLBACK;
          102  +} {{leaf page 0 is out of range (child 3 of trunk page 4861)}}
          103  +
          104  +do_execsql_test 1.10 {
          105  +  BEGIN;
          106  +    UPDATE sqlite_dbpage 
          107  +      SET data = set_int(data, get_int(data, 1)+1, 0)
          108  +      WHERE pgno=5;
          109  +    SELECT checkfreelist('main');
          110  +  ROLLBACK;
          111  +} {{leaf page 0 is out of range (child 247 of trunk page 5)}}
          112  +
          113  +do_execsql_test 1.11 {
          114  +  BEGIN;
          115  +    UPDATE sqlite_dbpage 
          116  +      SET data = set_int(data, 1, 249)
          117  +      WHERE pgno=5;
          118  +    SELECT checkfreelist('main');
          119  +  ROLLBACK;
          120  +} {{leaf count out of range (249) on trunk page 5}}
          121  +
          122  +finish_test
          123  +

Changes to test/corruptK.test.

   103    103     close $fd
   104    104   } {}
   105    105   
   106    106   do_catchsql_test 2.3 {
   107    107     INSERT INTO t1 VALUES(randomblob(900));
   108    108   } {1 {database disk image is malformed}}
   109    109   
          110  +#-------------------------------------------------------------------------
          111  +
          112  +proc hex2blob {hex} {
          113  +  # Split on newlines:
          114  +  set bytes [list]
          115  +  foreach l [split $hex "\n"] {
          116  +    if {[string is space $l]} continue
          117  +    set L [list]
          118  +    foreach b [split $l] {
          119  +      if {[string is xdigit $b] && [string length $b]==2} { 
          120  +        lappend L [expr "0x$b"]
          121  +      }
          122  +    }
          123  +    if {[llength $L]!=16} {
          124  +      error "Badly formed hex (1)"
          125  +    }
          126  +    set bytes [concat $bytes $L]
          127  +  }
          128  +
          129  +  binary format c* $bytes
          130  +}
          131  +
          132  +reset_db
          133  +db func hex2blob hex2blob
          134  +
          135  +do_execsql_test 3.1 {
          136  +  PRAGMA page_size=1024;
          137  +  CREATE TABLE t1(a, b, c);
          138  +  CREATE TABLE t2(a, b, c);
          139  +  CREATE TABLE t3(a, b, c);
          140  +  CREATE TABLE t4(a, b, c);
          141  +  CREATE TABLE t5(a, b, c);
          142  +}
          143  +
          144  +do_execsql_test 3.2 {
          145  +  UPDATE sqlite_dbpage SET data = hex2blob('
          146  + 000: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3.
          147  + 010: 04 00 01 01 20 40 20 20 00 00 3e d9 00 00 00 06 .... @  ..>.....
          148  + 020: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 04 ................
          149  + 030: 0f 00 00 00 00 00 00 00 00 00 00 01 00 00 83 00 ................
          150  + 040: 00 00 00 00 00 00 00 00 00 00 00 00 00 38 00 00 .............8..
          151  + 050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 3e d9 ..............>.
          152  + 060: 00 2d e6 07 0d 00 00 00 01 03 a0 00 03 e0 00 00 .-..............
          153  + 070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
          154  + 080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
          155  + 090: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
          156  + 0a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
          157  + 0b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
          158  + 0c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
          159  + 0d0: 00 00 00 00 00 c1 00 00 00 00 00 00 00 00 00 00 ................
          160  + 0e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
          161  + 0f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
          162  + 100: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
          163  + 110: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
          164  + 120: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
          165  + 130: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
          166  + 140: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
          167  + 150: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
          168  + 160: 00 83 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
          169  + 170: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
          170  + 180: 00 00 00 00 00 00 00 00 00 00 07 00 30 00 00 00 ............0...
          171  + 190: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
          172  + 1a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
          173  + 1b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
          174  + 1c0: 02 00 00 00 00 00 00 00 00 00 00 02 00 00 00 00 ................
          175  + 1d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
          176  + 1e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
          177  + 1f0: 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
          178  + 200: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
          179  + 210: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
          180  + 220: 00 00 0e 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
          181  + 230: 0c 00 00 00 00 00 00 60 00 00 00 06 00 00 c3 00 .......`........
          182  + 240: 00 06 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
          183  + 250: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
          184  + 260: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
          185  + 270: 00 00 00 18 00 00 00 00 00 00 00 00 00 00 00 00 ................
          186  + 280: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
          187  + 290: 04 00 0e 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
          188  + 2a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
          189  + 2b0: 00 00 00 00 83 00 8c 00 00 00 00 00 00 00 00 00 ................
          190  + 2c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
          191  + 2d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
          192  + 2e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
          193  + 2f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
          194  + 300: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
          195  + 310: 00 78 00 00 00 00 00 00 00 00 00 00 00 00 70 00 .x............p.
          196  + 320: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
          197  + 330: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
          198  + 340: 00 00 00 04 00 00 00 00 00 00 00 00 00 00 00 00 ................
          199  + 350: 00 00 00 00 00 68 00 00 00 00 00 00 00 00 00 00 .....h..........
          200  + 360: 00 00 00 00 00 03 00 00 00 00 00 00 00 00 00 00 ................
          201  + 370: 00 00 00 00 00 00 00 00 00 00 00 00 00 08 00 00 ................
          202  + 380: 00 00 00 00 70 00 00 00 00 00 00 00 00 00 00 00 ....p...........
          203  + 390: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
          204  + 3a0: 5e 01 07 17 1b 1b 01 81 13 74 61 62 6c 65 73 65 ^........tablese
          205  + 3b0: 6e 73 6f 32 73 73 65 6e 73 6f 72 73 02 43 52 45 nso2ssensors.CRE
          206  + 3c0: 41 54 45 20 54 41 42 4c 45 20 73 65 6e 73 6f 72 ATE TABLE sensor
          207  + 3d0: 73 20 0a 20 20 24 20 20 20 20 20 20 20 20 20 20 s .  $          
          208  + 3e0: b8 6e 61 6d 65 21 74 65 78 74 2c 20 79 61 6c 20 .name!text, yal 
          209  + 3f0: 72 65 61 6c 2c 20 74 69 6d 65 20 74 65 78 74 29 real, time text)
          210  +  ') WHERE pgno=1
          211  +}
          212  +
          213  +db close
          214  +sqlite3 db test.db
          215  +
          216  +do_catchsql_test 3.3 {
          217  +  PRAGMA integrity_check;
          218  +} {1 {database disk image is malformed}}
   110    219   
   111    220   
   112    221   
   113    222   finish_test

Added test/dbpage.test.

            1  +# 2017-10-11
            2  +#
            3  +# The author disclaims copyright to this source code.  In place of
            4  +# a legal notice, here is a blessing:
            5  +#
            6  +#    May you do good and not evil.
            7  +#    May you find forgiveness for yourself and forgive others.
            8  +#    May you share freely, never taking more than you give.
            9  +#
           10  +#***********************************************************************
           11  +# This file implements regression tests for SQLite library.  The
           12  +# focus of this file is testing the sqlite_dbpage virtual table.
           13  +#
           14  +
           15  +set testdir [file dirname $argv0]
           16  +source $testdir/tester.tcl
           17  +set testprefix dbpage
           18  +
           19  +ifcapable !vtab||!compound {
           20  +  finish_test
           21  +  return
           22  +}
           23  +
           24  +do_execsql_test 100 {
           25  +  PRAGMA page_size=4096;
           26  +  PRAGMA journal_mode=WAL;
           27  +  CREATE TABLE t1(a,b);
           28  +  WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<100)
           29  +  INSERT INTO t1(a,b) SELECT x, printf('%d-x%.*c',x,x,'x') FROM c;
           30  +  PRAGMA integrity_check;
           31  +} {wal ok}
           32  +do_execsql_test 110 {
           33  +  SELECT pgno, quote(substr(data,1,5)) FROM sqlite_dbpage('main') ORDER BY pgno;
           34  +} {1 X'53514C6974' 2 X'0500000001' 3 X'0D0000004E' 4 X'0D00000016'}
           35  +do_execsql_test 120 {
           36  +  SELECT pgno, quote(substr(data,1,5)) FROM sqlite_dbpage WHERE pgno=2;
           37  +} {2 X'0500000001'}
           38  +do_execsql_test 130 {
           39  +  SELECT pgno, quote(substr(data,1,5)) FROM sqlite_dbpage WHERE pgno=4;
           40  +} {4 X'0D00000016'}
           41  +do_execsql_test 140 {
           42  +  SELECT pgno, quote(substr(data,1,5)) FROM sqlite_dbpage WHERE pgno=5;
           43  +} {}
           44  +do_execsql_test 150 {
           45  +  SELECT pgno, quote(substr(data,1,5)) FROM sqlite_dbpage WHERE pgno=0;
           46  +} {}
           47  +
           48  +do_execsql_test 200 {
           49  +  CREATE TEMP TABLE saved_content(x);
           50  +  INSERT INTO saved_content(x) SELECT data FROM sqlite_dbpage WHERE pgno=4;
           51  +  UPDATE sqlite_dbpage SET data=zeroblob(4096) WHERE pgno=4;
           52  +} {}
           53  +do_catchsql_test 210 {
           54  +  PRAGMA integrity_check;
           55  +} {1 {database disk image is malformed}}
           56  +do_execsql_test 220 {
           57  +  SELECT pgno, quote(substr(data,1,5)) FROM sqlite_dbpage('main') ORDER BY pgno;
           58  +} {1 X'53514C6974' 2 X'0500000001' 3 X'0D0000004E' 4 X'0000000000'}
           59  +do_execsql_test 230 {
           60  +  UPDATE sqlite_dbpage SET data=(SELECT x FROM saved_content) WHERE pgno=4;
           61  +} {}
           62  +do_catchsql_test 230 {
           63  +  PRAGMA integrity_check;
           64  +} {0 ok}
           65  +
           66  +
           67  +
           68  +
           69  +finish_test

Changes to test/permutations.test.

   190    190   
   191    191   test_suite "valgrind" -prefix "" -description {
   192    192     Run the "veryquick" test suite with a couple of multi-process tests (that
   193    193     fail under valgrind) omitted.
   194    194   } -files [
   195    195     test_set $allquicktests -exclude *malloc* *ioerr* *fault* *_err* wal.test \
   196    196                 shell*.test crash8.test atof1.test selectG.test \
   197         -              tkt-fc62af4523.test numindex1.test
          197  +              tkt-fc62af4523.test numindex1.test corruptK.test
   198    198   ] -initialize {
   199    199     set ::G(valgrind) 1
   200    200   } -shutdown {
   201    201     unset -nocomplain ::G(valgrind)
   202    202   }
   203    203   
   204    204   test_suite "valgrind-nolookaside" -prefix "" -description {
................................................................................
  1061   1061   } -dbconfig {
  1062   1062     optimization_control $::dbhandle all 0
  1063   1063   }
  1064   1064   
  1065   1065   test_suite "prepare" -description {
  1066   1066     Run tests with the db connection using sqlite3_prepare() instead of _v2().
  1067   1067   } -dbconfig {
  1068         -  db_use_legacy_prepare $::dbhandle 1
         1068  +  $::dbhandle version -use-legacy-prepare 1
  1069   1069     #$::dbhandle cache size 0
  1070   1070   } -files [
  1071   1071     test_set $allquicktests -exclude *malloc* *ioerr* *fault* \
  1072   1072         stmtvtab1.test index9.test
  1073   1073   ]
  1074   1074   
  1075   1075   # End of tests

Changes to test/scanstatus.test.

    26     26     INSERT INTO t1 VALUES(3, 4);
    27     27     INSERT INTO t2 VALUES('a', 'b');
    28     28     INSERT INTO t2 VALUES('c', 'd');
    29     29     INSERT INTO t2 VALUES('e', 'f');
    30     30   }
    31     31   
    32     32   proc do_scanstatus_test {tn res} {
    33         -  set stmt [db_last_stmt_ptr db]
           33  +  set stmt [db version -last-stmt-ptr]
    34     34     set idx 0
    35     35     set ret [list]
    36     36     while {1} {
    37     37       set r [sqlite3_stmt_scanstatus $stmt $idx]
    38     38       if {[llength $r]==0} break
    39     39       lappend ret {*}$r
    40     40       incr idx
................................................................................
    75     75   do_scanstatus_test 1.9 {
    76     76     nLoop 2 nVisit 4 nEst 2.0 zName t2 zExplain 
    77     77     {SEARCH TABLE t2 USING INTEGER PRIMARY KEY (rowid>?)}
    78     78     nLoop 4 nVisit 8 nEst 2.0 zName t1 zExplain {SCAN TABLE t1}
    79     79   }
    80     80   
    81     81   do_test 1.9 {
    82         -  sqlite3_stmt_scanstatus_reset [db_last_stmt_ptr db]
           82  +  sqlite3_stmt_scanstatus_reset [db version -last-stmt-ptr]
    83     83   } {}
    84     84   
    85     85   do_scanstatus_test 1.10 {
    86     86     nLoop 0 nVisit 0 nEst 2.0 zName t2 zExplain 
    87     87     {SEARCH TABLE t2 USING INTEGER PRIMARY KEY (rowid>?)}
    88     88     nLoop 0 nVisit 0 nEst 2.0 zName t1 zExplain {SCAN TABLE t1}
    89     89   }

Added tool/mkccode.tcl.

            1  +#!/usr/bin/tclsh
            2  +#
            3  +# Use this script to build C-language source code for a program that uses
            4  +# tclsqlite.c together with custom TCL scripts and/or C extensions for
            5  +# either SQLite or TCL.
            6  +#
            7  +# Usage example:
            8  +#
            9  +#     tclsh mktclsqliteprog.tcl demoapp.c.in >demoapp.c
           10  +#
           11  +# The demoapp.c.in file contains a mixture of C code, TCL script, and
           12  +# processing directives used by mktclsqliteprog.tcl to build the final C-code
           13  +# output file.  Most lines of demoapp.c.in are copied straight through into
           14  +# the output.  The following control directives are recognized:
           15  +#
           16  +# BEGIN_STRING
           17  +#
           18  +#      This marks the beginning of large string literal - usually a TCL
           19  +#      script of some kind.  Subsequent lines of text through the first
           20  +#      line that begins with END_STRING are converted into a C-language
           21  +#      string literal.
           22  +#
           23  +# INCLUDE path
           24  +#
           25  +#      The path argument is the name of a file to be inserted in place of
           26  +#      the INCLUDE line.  The path can begin with $ROOT to signify the
           27  +#      root of the SQLite source tree, or $HOME to signify the directory
           28  +#      that contains the demoapp.c.in input script itself.  If the path does
           29  +#      not begin with either $ROOT or $HOME, then it is interpreted relative
           30  +#      to the current working directory.
           31  +#
           32  +#      If the INCLUDE occurs in the middle of BEGIN_STRING...END_STRING
           33  +#      then all of the text in the input file is converted into C-language
           34  +#      string literals.
           35  +#
           36  +# None of the control directives described above will nest.  Only the
           37  +# top-level input file ("demoapp.c.in" in the example) is interpreted.
           38  +# referenced files are copied verbatim.
           39  +#
           40  +if {[llength $argv]!=1} {
           41  +  puts stderr "Usage: $argv0 TEMPLATE >OUTPUT"
           42  +  exit 1
           43  +}
           44  +set infile [lindex $argv 0]
           45  +set ROOT [file normalize [file dir $argv0]/..]
           46  +set HOME [file normalize [file dir $infile]]
           47  +set in [open $infile rb]
           48  +puts [subst {/* DO NOT EDIT
           49  +**
           50  +** This file was generated by \"$argv0 $infile\".
           51  +** To make changes, edit $infile then rerun the generator
           52  +** command.
           53  +*/}]
           54  +set instr 0
           55  +while {1} {
           56  +  set line [gets $in]
           57  +  if {[eof $in]} break
           58  +  if {[regexp {^INCLUDE (.*)} $line all path]} {
           59  +    regsub {^\$ROOT\y} $path $ROOT path
           60  +    regsub {^\$HOME\y} $path $HOME path
           61  +    set in2 [open $path rb]
           62  +    puts "/* INCLUDE $path */"
           63  +    if {$instr} {
           64  +      while {1} {
           65  +        set line [gets $in2]
           66  +        if {[eof $in2]} break
           67  +        set x [string map "\\\\ \\\\\\\\ \\\" \\\\\"" $line]
           68  +        puts "\"$x\\n\""
           69  +      }
           70  +    } else {
           71  +      puts [read $in2]
           72  +    }
           73  +    puts "/* END $path */"
           74  +    close $in2
           75  +    continue
           76  +  }
           77  +  if {[regexp {^BEGIN_STRING} $line]} {
           78  +    set instr 1
           79  +    puts "/* BEGIN_STRING */"
           80  +    continue
           81  +  }
           82  +  if {[regexp {^END_STRING} $line]} {
           83  +    set instr 0
           84  +    puts "/* END_STRING */"
           85  +    continue
           86  +  }
           87  +  if {$instr} {
           88  +    set x [string map "\\\\ \\\\\\\\ \\\" \\\\\"" $line]
           89  +    puts "\"$x\\n\""
           90  +  } else {
           91  +    puts $line
           92  +  }
           93  +}

Changes to tool/mksqlite3c.tcl.

   390    390      fts3_unicode2.c
   391    391   
   392    392      rtree.c
   393    393      icu.c
   394    394      fts3_icu.c
   395    395      sqlite3rbu.c
   396    396      dbstat.c
          397  +   dbpage.c
   397    398      sqlite3session.c
   398    399      json1.c
   399    400      fts5.c
   400    401      stmt.c
   401    402   } {
   402    403     copy_file tsrc/$file
   403    404   }

Changes to tool/split-sqlite3c.tcl.

    11     11   set MAX 32768    ;# Maximum number of lines per file.
    12     12   
    13     13   set BEGIN {^/\*+ Begin file ([a-zA-Z0-9_.]+) \*+/}
    14     14   set END   {^/\*+ End of %s \*+/}
    15     15   
    16     16   set in [open sqlite3.c]
    17     17   set out1 [open sqlite3-all.c w]
           18  +fconfigure $out1 -translation lf
    18     19   
    19     20   # Copy the header from sqlite3.c into sqlite3-all.c
    20     21   #
    21     22   while {[gets $in line]} {
    22     23     if {[regexp $BEGIN $line]} break
    23     24     puts $out1 $line
    24     25   }
................................................................................
    44     45   # Also add an appropriate #include to sqlite3-all.c
    45     46   #
    46     47   set filecnt 0
    47     48   proc write_one_file {content} {
    48     49     global filecnt
    49     50     incr filecnt
    50     51     set out [open sqlite3-$filecnt.c w]
           52  +  fconfigure $out -translation lf
    51     53     puts -nonewline $out $content
    52     54     close $out
    53     55     puts $::out1 "#include \"sqlite3-$filecnt.c\""
    54     56   }
    55     57   
    56     58   # Continue reading input.  Store chunks in separate files and add
    57     59   # the #includes to the main sqlite3-all.c file as necessary to reference

Added tool/sqlite3_analyzer.c.in.

            1  +/*
            2  +** Read an SQLite database file and analyze its space utilization.  Generate
            3  +** text on standard output.
            4  +*/
            5  +#define TCLSH_INIT_PROC sqlite3_analyzer_init_proc
            6  +#define SQLITE_ENABLE_DBSTAT_VTAB 1
            7  +#undef SQLITE_THREADSAFE
            8  +#define SQLITE_THREADSAFE 0
            9  +#undef SQLITE_ENABLE_COLUMN_METADATA
           10  +#define SQLITE_OMIT_DECLTYPE 1
           11  +#define SQLITE_OMIT_DEPRECATED 1
           12  +#define SQLITE_OMIT_PROGRESS_CALLBACK 1
           13  +#define SQLITE_OMIT_SHARED_CACHE 1
           14  +#define SQLITE_DEFAULT_MEMSTATUS 0
           15  +#define SQLITE_MAX_EXPR_DEPTH 0
           16  +#define SQLITE_OMIT_LOAD_EXTENSION 1
           17  +INCLUDE sqlite3.c
           18  +INCLUDE $ROOT/src/tclsqlite.c
           19  +
           20  +const char *sqlite3_analyzer_init_proc(Tcl_Interp *interp){
           21  +  (void)interp;
           22  +  return
           23  +BEGIN_STRING
           24  +INCLUDE $ROOT/tool/spaceanal.tcl
           25  +END_STRING
           26  +;
           27  +}

Deleted tool/tostr.tcl.

     1         -#!/usr/bin/tcl
     2         -#
     3         -# Convert input text into a C string
     4         -#
     5         -set in [open [lindex $argv 0] rb]
     6         -while {![eof $in]} {
     7         -  set line [gets $in]
     8         -  if {[eof $in]} break;
     9         -  set x [string map "\\\\ \\\\\\\\ \\\" \\\\\"" $line]
    10         -  puts "\"$x\\n\""
    11         -}
    12         -close $in