/ Check-in [456df336]
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 recent enhancements from trunk. Default page size is 4096. Writes to statement journals are avoided.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | sessions
Files: files | file ages | folders
SHA1: 456df3365e2df60e34762f2024bb551538b3f72b
User & Date: drh 2016-03-04 16:42:43
Context
2016-03-07
17:49
Merge the virtual table query planner enhancement, the RTREE cost estimate fix, and the statement journal spill delay enhancement from trunk. check-in: 17fd8f3c user: drh tags: sessions
2016-03-04
16:42
Merge recent enhancements from trunk. Default page size is 4096. Writes to statement journals are avoided. check-in: 456df336 user: drh tags: sessions
14:43
Defer opening and writing statement journals until the size reaches a threshold (currently 64KiB). check-in: cb9302cc user: drh tags: trunk
2016-02-25
19:52
Disable the RESTRICT foreign key action if "PRAGMA defer_foreign_keys" is set. check-in: 8fea1166 user: dan tags: sessions
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to Makefile.in.

   376    376     $(TOP)/src/test6.c \
   377    377     $(TOP)/src/test7.c \
   378    378     $(TOP)/src/test8.c \
   379    379     $(TOP)/src/test9.c \
   380    380     $(TOP)/src/test_autoext.c \
   381    381     $(TOP)/src/test_async.c \
   382    382     $(TOP)/src/test_backup.c \
          383  +  $(TOP)/src/test_bestindex.c \
   383    384     $(TOP)/src/test_blob.c \
   384    385     $(TOP)/src/test_btree.c \
   385    386     $(TOP)/src/test_config.c \
   386    387     $(TOP)/src/test_demovfs.c \
   387    388     $(TOP)/src/test_devsym.c \
   388    389     $(TOP)/src/test_fs.c \
   389    390     $(TOP)/src/test_func.c \
................................................................................
  1056   1057   # fixture.  Otherwise link against libsqlite3.la.  (This distinction is
  1057   1058   # necessary because the test fixture requires non-API symbols which are
  1058   1059   # hidden when the library is built via the amalgamation).
  1059   1060   #
  1060   1061   TESTFIXTURE_FLAGS  = -DTCLSH=1 -DSQLITE_TEST=1 -DSQLITE_CRASH_TEST=1
  1061   1062   TESTFIXTURE_FLAGS += -DSQLITE_SERVER=1 -DSQLITE_PRIVATE="" -DSQLITE_CORE 
  1062   1063   TESTFIXTURE_FLAGS += -DBUILD_sqlite
         1064  +TESTFIXTURE_FLAGS += -DSQLITE_SERIES_CONSTRAINT_VERIFY=1
         1065  +TESTFIXTURE_FLAGS += -DSQLITE_DEFAULT_PAGE_SIZE=1024
  1063   1066   
  1064   1067   TESTFIXTURE_SRC0 = $(TESTSRC2) libsqlite3.la
  1065   1068   TESTFIXTURE_SRC1 = sqlite3.c
  1066   1069   TESTFIXTURE_SRC = $(TESTSRC) $(TOP)/src/tclsqlite.c
  1067   1070   TESTFIXTURE_SRC += $(TESTFIXTURE_SRC$(USE_AMALGAMATION))
  1068   1071   
  1069   1072   testfixture$(TEXE):	$(TESTFIXTURE_SRC)

Changes to Makefile.msc.

   301    301   # Check for the predefined command macro CC.  This should point to the compiler
   302    302   # binary for the target platform.  If it is not defined, simply define it to
   303    303   # the legacy default value 'cl.exe'.
   304    304   #
   305    305   !IFNDEF CC
   306    306   CC = cl.exe
   307    307   !ENDIF
          308  +
          309  +# Check for the predefined command macro CSC.  This should point to a working
          310  +# C Sharp compiler binary.  If it is not defined, simply define it to the
          311  +# legacy default value 'csc.exe'.
          312  +#
          313  +!IFNDEF CSC
          314  +CSC = csc.exe
          315  +!ENDIF
   308    316   
   309    317   # Check for the command macro LD.  This should point to the linker binary for
   310    318   # the target platform.  If it is not defined, simply define it to the legacy
   311    319   # default value 'link.exe'.
   312    320   #
   313    321   !IFNDEF LD
   314    322   LD = link.exe
................................................................................
   468    476   !ENDIF
   469    477   !ENDIF
   470    478   
   471    479   # These are the additional targets that the core library should depend on
   472    480   # when linking.
   473    481   #
   474    482   !IFNDEF CORE_LINK_DEP
   475         -!IF $(DYNAMIC_SHELL)!=0 || $(FOR_WIN10)!=0
          483  +!IF $(DYNAMIC_SHELL)!=0
   476    484   CORE_LINK_DEP =
   477         -!ELSE
          485  +!ELSEIF $(FOR_WIN10)==0 || "$(PLATFORM)"=="x86"
   478    486   CORE_LINK_DEP = sqlite3.def
          487  +!ELSE
          488  +CORE_LINK_DEP =
   479    489   !ENDIF
   480    490   !ENDIF
   481    491   
   482    492   # These are additional linker options used for the core library.
   483    493   #
   484    494   !IFNDEF CORE_LINK_OPTS
   485         -!IF $(DYNAMIC_SHELL)!=0 || $(FOR_WIN10)!=0
          495  +!IF $(DYNAMIC_SHELL)!=0
   486    496   CORE_LINK_OPTS =
   487         -!ELSE
          497  +!ELSEIF $(FOR_WIN10)==0 || "$(PLATFORM)"=="x86"
   488    498   CORE_LINK_OPTS = /DEF:sqlite3.def
          499  +!ELSE
          500  +CORE_LINK_OPTS =
   489    501   !ENDIF
   490    502   !ENDIF
   491    503   
   492    504   # These are additional compiler options used for the shell executable.
   493    505   #
   494    506   !IFNDEF SHELL_COMPILE_OPTS
   495    507   !IF $(DYNAMIC_SHELL)!=0 || $(FOR_WIN10)!=0
................................................................................
  1234   1246     $(TOP)\src\test6.c \
  1235   1247     $(TOP)\src\test7.c \
  1236   1248     $(TOP)\src\test8.c \
  1237   1249     $(TOP)\src\test9.c \
  1238   1250     $(TOP)\src\test_autoext.c \
  1239   1251     $(TOP)\src\test_async.c \
  1240   1252     $(TOP)\src\test_backup.c \
         1253  +  $(TOP)\src\test_bestindex.c \
  1241   1254     $(TOP)\src\test_blob.c \
  1242   1255     $(TOP)\src\test_btree.c \
  1243   1256     $(TOP)\src\test_config.c \
  1244   1257     $(TOP)\src\test_demovfs.c \
  1245   1258     $(TOP)\src\test_devsym.c \
  1246   1259     $(TOP)\src\test_fs.c \
  1247   1260     $(TOP)\src\test_func.c \
................................................................................
  1408   1421   # This is the default Makefile target.  The objects listed here
  1409   1422   # are what get build when you type just "make" with no arguments.
  1410   1423   #
  1411   1424   all:	dll libsqlite3.lib shell $(ALL_TCL_TARGETS)
  1412   1425   
  1413   1426   # Dynamic link library section.
  1414   1427   #
  1415         -dll: $(SQLITE3DLL)
         1428  +dll:	$(SQLITE3DLL)
  1416   1429   
  1417   1430   # Shell executable.
  1418   1431   #
  1419         -shell: $(SQLITE3EXE)
         1432  +shell:	$(SQLITE3EXE)
  1420   1433   
  1421   1434   # <<mark>>
  1422   1435   libsqlite3.lib:	$(LIBOBJ)
  1423   1436   	$(LTLIB) $(LTLIBOPTS) /OUT:$@ $(LIBOBJ) $(TLIBS)
  1424   1437   
  1425   1438   libtclsqlite3.lib:	tclsqlite.lo libsqlite3.lib
  1426   1439   	$(LTLIB) $(LTLIBOPTS) $(LTLIBPATHS) /OUT:$@ tclsqlite.lo libsqlite3.lib $(LIBTCLSTUB) $(TLIBS)
  1427   1440   # <</mark>>
  1428   1441   
  1429         -$(SQLITE3DLL): $(LIBOBJ) $(LIBRESOBJS) $(CORE_LINK_DEP)
         1442  +$(SQLITE3DLL):	$(LIBOBJ) $(LIBRESOBJS) $(CORE_LINK_DEP)
  1430   1443   	$(LD) $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) /DLL $(CORE_LINK_OPTS) /OUT:$@ $(LIBOBJ) $(LIBRESOBJS) $(LTLIBS) $(TLIBS)
  1431   1444   
  1432         -# <<mark>>
  1433         -sqlite3.def: libsqlite3.lib
         1445  +# <<block2>>
         1446  +sqlite3.def:	libsqlite3.lib
  1434   1447   	echo EXPORTS > sqlite3.def
  1435   1448   	dumpbin /all libsqlite3.lib \
  1436         -		| $(TCLSH_CMD) $(TOP)\tool\replace.tcl include "^\s+1 _?(sqlite3_.*)$$" \1 \
         1449  +		| $(TCLSH_CMD) $(TOP)\tool\replace.tcl include "^\s+1 _?(sqlite3_[^@]*)(?:@\d+)?$$" \1 \
  1437   1450   		| sort >> sqlite3.def
  1438         -# <</mark>>
         1451  +# <</block2>>
  1439   1452   
  1440   1453   $(SQLITE3EXE):	$(TOP)\src\shell.c $(SHELL_CORE_DEP) $(LIBRESOBJS) $(SHELL_CORE_SRC) $(SQLITE3H)
  1441   1454   	$(LTLINK) $(SHELL_COMPILE_OPTS) $(READLINE_FLAGS) $(TOP)\src\shell.c $(SHELL_CORE_SRC) \
  1442   1455   		/link $(SQLITE3EXEPDB) $(LDFLAGS) $(LTLINKOPTS) $(SHELL_LINK_OPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LIBREADLINE) $(LTLIBS) $(TLIBS)
  1443   1456   
  1444   1457   # <<mark>>
  1445   1458   sqldiff.exe:	$(TOP)\tool\sqldiff.c $(SQLITE3C) $(SQLITE3H)
................................................................................
  1806   1819   	.\lemon.exe $(REQ_FEATURE_FLAGS) $(OPT_FEATURE_FLAGS) $(EXT_FEATURE_FLAGS) $(OPTS) parse.y
  1807   1820   	move parse.h parse.h.temp
  1808   1821   	$(TCLSH_CMD) $(TOP)\tool\addopcodes.tcl parse.h.temp > parse.h
  1809   1822   
  1810   1823   $(SQLITE3H):	$(TOP)\src\sqlite.h.in $(TOP)\manifest.uuid $(TOP)\VERSION
  1811   1824   	$(TCLSH_CMD) $(TOP)\tool\mksqlite3h.tcl $(TOP:\=/) > $(SQLITE3H)
  1812   1825   
  1813         -sqlite3ext.h: .target_source
         1826  +sqlite3ext.h:	.target_source
  1814   1827   	copy tsrc\sqlite3ext.h .
  1815   1828   
  1816   1829   mkkeywordhash.exe:	$(TOP)\tool\mkkeywordhash.c
  1817   1830   	$(BCC) $(NO_WARN) -Fe$@ $(REQ_FEATURE_FLAGS) $(OPT_FEATURE_FLAGS) $(EXT_FEATURE_FLAGS) $(OPTS) \
  1818   1831   		$(TOP)\tool\mkkeywordhash.c /link $(LDFLAGS) $(NLTLINKOPTS) $(NLTLIBPATHS)
  1819   1832   
  1820   1833   keywordhash.h:	$(TOP)\tool\mkkeywordhash.c mkkeywordhash.exe
................................................................................
  1910   1923      $(TOP)\ext\fts5\fts5_vocab.c
  1911   1924   
  1912   1925   fts5parse.c:	$(TOP)\ext\fts5\fts5parse.y lemon.exe
  1913   1926   	copy $(TOP)\ext\fts5\fts5parse.y .
  1914   1927   	del /Q fts5parse.h 2>NUL
  1915   1928   	.\lemon.exe $(REQ_FEATURE_FLAGS) $(OPT_FEATURE_FLAGS) $(EXT_FEATURE_FLAGS) $(OPTS) fts5parse.y
  1916   1929   
  1917         -fts5parse.h: fts5parse.c
         1930  +fts5parse.h:	fts5parse.c
  1918   1931   
  1919         -fts5.c: $(FTS5_SRC)
         1932  +fts5.c:	$(FTS5_SRC)
  1920   1933   	$(TCLSH_CMD) $(TOP)\ext\fts5\tool\mkfts5c.tcl
  1921   1934   	copy $(TOP)\ext\fts5\fts5.h .
  1922   1935   
  1923   1936   fts5.lo:	fts5.c $(HDR) $(EXTHDR)
  1924   1937   	$(LTCOMPILE) $(CORE_COMPILE_OPTS) $(NO_WARN) -DSQLITE_CORE -c fts5.c
  1925   1938   
  1926   1939   fts5_ext.lo:	fts5.c $(HDR) $(EXTHDR)
................................................................................
  1938   1951   # fixture.  Otherwise link against libsqlite3.lib.  (This distinction is
  1939   1952   # necessary because the test fixture requires non-API symbols which are
  1940   1953   # hidden when the library is built via the amalgamation).
  1941   1954   #
  1942   1955   TESTFIXTURE_FLAGS = -DTCLSH=1 -DSQLITE_TEST=1 -DSQLITE_CRASH_TEST=1
  1943   1956   TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_SERVER=1 -DSQLITE_PRIVATE=""
  1944   1957   TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_CORE $(NO_WARN)
         1958  +TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_SERIES_CONSTRAINT_VERIFY=1
         1959  +TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_DEFAULT_PAGE_SIZE=1024
  1945   1960   
  1946   1961   TESTFIXTURE_SRC0 = $(TESTEXT) $(TESTSRC2)
  1947   1962   TESTFIXTURE_SRC1 = $(TESTEXT) $(TESTSRC3) $(SQLITE3C)
  1948   1963   !IF $(USE_AMALGAMATION)==0
  1949   1964   TESTFIXTURE_SRC = $(TESTSRC) $(TOP)\src\tclsqlite.c $(TESTFIXTURE_SRC0)
  1950   1965   !ELSE
  1951   1966   TESTFIXTURE_SRC = $(TESTSRC) $(TOP)\src\tclsqlite.c $(TESTFIXTURE_SRC1)
................................................................................
  1953   1968   
  1954   1969   testfixture.exe:	$(TESTFIXTURE_SRC) $(SQLITE3H) $(LIBRESOBJS) $(HDR)
  1955   1970   	$(LTLINK) -DSQLITE_NO_SYNC=1 $(TESTFIXTURE_FLAGS) \
  1956   1971   		-DBUILD_sqlite -I$(TCLINCDIR) \
  1957   1972   		$(TESTFIXTURE_SRC) \
  1958   1973   		/link $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LTLIBS) $(TLIBS)
  1959   1974   
  1960         -extensiontest: testfixture.exe testloadext.dll
         1975  +extensiontest:	testfixture.exe testloadext.dll
  1961   1976   	@set PATH=$(LIBTCLPATH);$(PATH)
  1962   1977   	.\testfixture.exe $(TOP)\test\loadext.test $(TESTOPTS)
  1963   1978   
  1964   1979   fulltest:	$(TESTPROGS) fuzztest
  1965   1980   	@set PATH=$(LIBTCLPATH);$(PATH)
  1966   1981   	.\testfixture.exe $(TOP)\test\all.test $(TESTOPTS)
  1967   1982   
................................................................................
  1996   2011   	@set PATH=$(LIBTCLPATH);$(PATH)
  1997   2012   	.\testfixture.exe $(TOP)\test\veryquick.test $(TESTOPTS)
  1998   2013   
  1999   2014   smoketest:	$(TESTPROGS)
  2000   2015   	@set PATH=$(LIBTCLPATH);$(PATH)
  2001   2016   	.\testfixture.exe $(TOP)\test\main.test $(TESTOPTS)
  2002   2017   
  2003         -sqlite3_analyzer.c: $(SQLITE3C) $(SQLITE3H) $(TOP)\src\tclsqlite.c $(TOP)\tool\spaceanal.tcl
         2018  +sqlite3_analyzer.c:	$(SQLITE3C) $(SQLITE3H) $(TOP)\src\tclsqlite.c $(TOP)\tool\spaceanal.tcl
  2004   2019   	echo #define TCLSH 2 > $@
  2005   2020   	echo #define SQLITE_ENABLE_DBSTAT_VTAB 1 >> $@
  2006   2021   	copy $@ + $(SQLITE3C) + $(TOP)\src\tclsqlite.c $@
  2007   2022   	echo static const char *tclsh_main_loop(void){ >> $@
  2008   2023   	echo static const char *zMainloop = >> $@
  2009   2024   	$(TCLSH_CMD) $(TOP)\tool\tostr.tcl $(TOP)\tool\spaceanal.tcl >> $@
  2010   2025   	echo ; return zMainloop; } >> $@
................................................................................
  2012   2027   sqlite3_analyzer.exe:	sqlite3_analyzer.c $(LIBRESOBJS)
  2013   2028   	$(LTLINK) $(NO_WARN) -DBUILD_sqlite -I$(TCLINCDIR) sqlite3_analyzer.c \
  2014   2029   		/link $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LTLIBS) $(TLIBS)
  2015   2030   
  2016   2031   testloadext.lo:	$(TOP)\src\test_loadext.c
  2017   2032   	$(LTCOMPILE) $(NO_WARN) -c $(TOP)\src\test_loadext.c
  2018   2033   
  2019         -testloadext.dll: testloadext.lo
         2034  +testloadext.dll:	testloadext.lo
  2020   2035   	$(LD) $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) /DLL /OUT:$@ testloadext.lo
  2021   2036   
  2022   2037   showdb.exe:	$(TOP)\tool\showdb.c $(SQLITE3C) $(SQLITE3H)
  2023   2038   	$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \
  2024   2039   		$(TOP)\tool\showdb.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
  2025   2040   
  2026   2041   showstat4.exe:	$(TOP)\tool\showstat4.c $(SQLITE3C) $(SQLITE3H)
................................................................................
  2054   2069   	$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \
  2055   2070   		$(TOP)\test\wordcount.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
  2056   2071   
  2057   2072   speedtest1.exe:	$(TOP)\test\speedtest1.c $(SQLITE3C) $(SQLITE3H)
  2058   2073   	$(LTLINK) $(NO_WARN) -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \
  2059   2074   		$(TOP)\test\speedtest1.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
  2060   2075   
  2061         -rbu.exe: $(TOP)\ext\rbu\rbu.c $(TOP)\ext\rbu\sqlite3rbu.c $(SQLITE3C) $(SQLITE3H)
         2076  +rbu.exe:	$(TOP)\ext\rbu\rbu.c $(TOP)\ext\rbu\sqlite3rbu.c $(SQLITE3C) $(SQLITE3H)
  2062   2077   	$(LTLINK) $(NO_WARN) -DSQLITE_ENABLE_RBU -Fe$@ \
  2063   2078   		$(TOP)\ext\rbu\rbu.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
         2079  +
         2080  +moreclean:	clean
         2081  +	del /Q $(SQLITE3C) $(SQLITE3H) 2>NUL
  2064   2082   # <</mark>>
  2065   2083   
  2066   2084   clean:
  2067   2085   	del /Q *.exp *.lo *.ilk *.lib *.obj *.ncb *.pdb *.sdf *.suo 2>NUL
  2068   2086   	del /Q *.bsc *.def *.cod *.da *.bb *.bbg *.vc gmon.out 2>NUL
  2069         -	del /Q $(SQLITE3EXE) $(SQLITE3DLL) 2>NUL
         2087  +	del /Q $(SQLITE3EXE) $(SQLITE3DLL) Replace.exe 2>NUL
  2070   2088   # <<mark>>
  2071         -	del /Q $(SQLITE3C) $(SQLITE3H) opcodes.c opcodes.h 2>NUL
         2089  +	del /Q sqlite3.c sqlite3.h 2>NUL
         2090  +	del /Q opcodes.c opcodes.h 2>NUL
  2072   2091   	del /Q lemon.* lempar.c parse.* 2>NUL
  2073   2092   	del /Q mkkeywordhash.* keywordhash.h 2>NUL
  2074   2093   	del /Q notasharedlib.* 2>NUL
  2075   2094   	-rmdir /Q/S .deps 2>NUL
  2076   2095   	-rmdir /Q/S .libs 2>NUL
  2077   2096   	-rmdir /Q/S quota2a 2>NUL
  2078   2097   	-rmdir /Q/S quota2b 2>NUL

Changes to autoconf/Makefile.am.

     9      9   sqlite3_SOURCES = shell.c sqlite3.c sqlite3.h
    10     10   sqlite3_LDADD = @READLINE_LIBS@
    11     11   sqlite3_DEPENDENCIES = @EXTRA_SHELL_OBJ@
    12     12   sqlite3_CFLAGS = $(AM_CFLAGS) -DSQLITE_ENABLE_EXPLAIN_COMMENTS
    13     13   
    14     14   include_HEADERS = sqlite3.h sqlite3ext.h
    15     15   
    16         -EXTRA_DIST = sqlite3.1 tea Makefile.msc sqlite3.rc README.txt
           16  +EXTRA_DIST = sqlite3.1 tea Makefile.msc sqlite3.rc README.txt Replace.cs
    17     17   pkgconfigdir = ${libdir}/pkgconfig
    18     18   pkgconfig_DATA = sqlite3.pc
    19     19   
    20     20   man_MANS = sqlite3.1

Changes to autoconf/Makefile.msc.

   286    286   # Check for the predefined command macro CC.  This should point to the compiler
   287    287   # binary for the target platform.  If it is not defined, simply define it to
   288    288   # the legacy default value 'cl.exe'.
   289    289   #
   290    290   !IFNDEF CC
   291    291   CC = cl.exe
   292    292   !ENDIF
          293  +
          294  +# Check for the predefined command macro CSC.  This should point to a working
          295  +# C Sharp compiler binary.  If it is not defined, simply define it to the
          296  +# legacy default value 'csc.exe'.
          297  +#
          298  +!IFNDEF CSC
          299  +CSC = csc.exe
          300  +!ENDIF
   293    301   
   294    302   # Check for the command macro LD.  This should point to the linker binary for
   295    303   # the target platform.  If it is not defined, simply define it to the legacy
   296    304   # default value 'link.exe'.
   297    305   #
   298    306   !IFNDEF LD
   299    307   LD = link.exe
................................................................................
   453    461   !ENDIF
   454    462   !ENDIF
   455    463   
   456    464   # These are the additional targets that the core library should depend on
   457    465   # when linking.
   458    466   #
   459    467   !IFNDEF CORE_LINK_DEP
   460         -!IF $(DYNAMIC_SHELL)!=0 || $(FOR_WIN10)!=0
          468  +!IF $(DYNAMIC_SHELL)!=0
   461    469   CORE_LINK_DEP =
          470  +!ELSEIF $(FOR_WIN10)==0 || "$(PLATFORM)"=="x86"
          471  +CORE_LINK_DEP = sqlite3.def
   462    472   !ELSE
   463    473   CORE_LINK_DEP =
   464    474   !ENDIF
   465    475   !ENDIF
   466    476   
   467    477   # These are additional linker options used for the core library.
   468    478   #
   469    479   !IFNDEF CORE_LINK_OPTS
   470         -!IF $(DYNAMIC_SHELL)!=0 || $(FOR_WIN10)!=0
          480  +!IF $(DYNAMIC_SHELL)!=0
   471    481   CORE_LINK_OPTS =
          482  +!ELSEIF $(FOR_WIN10)==0 || "$(PLATFORM)"=="x86"
          483  +CORE_LINK_OPTS = /DEF:sqlite3.def
   472    484   !ELSE
   473    485   CORE_LINK_OPTS =
   474    486   !ENDIF
   475    487   !ENDIF
   476    488   
   477    489   # These are additional compiler options used for the shell executable.
   478    490   #
................................................................................
   870    882   # This is the default Makefile target.  The objects listed here
   871    883   # are what get build when you type just "make" with no arguments.
   872    884   #
   873    885   all:	dll shell
   874    886   
   875    887   # Dynamic link library section.
   876    888   #
   877         -dll: $(SQLITE3DLL)
          889  +dll:	$(SQLITE3DLL)
   878    890   
   879    891   # Shell executable.
   880    892   #
   881         -shell: $(SQLITE3EXE)
          893  +shell:	$(SQLITE3EXE)
   882    894   
   883    895   
   884         -$(SQLITE3DLL): $(LIBOBJ) $(LIBRESOBJS) $(CORE_LINK_DEP)
          896  +$(SQLITE3DLL):	$(LIBOBJ) $(LIBRESOBJS) $(CORE_LINK_DEP)
   885    897   	$(LD) $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) /DLL $(CORE_LINK_OPTS) /OUT:$@ $(LIBOBJ) $(LIBRESOBJS) $(LTLIBS) $(TLIBS)
   886    898   
          899  +Replace.exe:
          900  +	$(CSC) /target:exe $(TOP)\Replace.cs
          901  +
          902  +sqlite3.def:	Replace.exe $(LIBOBJ)
          903  +	echo EXPORTS > sqlite3.def
          904  +	dumpbin /all $(LIBOBJ) \
          905  +		| .\Replace.exe "^\s+/EXPORT:_?(sqlite3_[^@,]*)(?:@\d+|,DATA)?$$" $$1 true \
          906  +		| sort >> sqlite3.def
   887    907   
   888    908   $(SQLITE3EXE):	$(TOP)\shell.c $(SHELL_CORE_DEP) $(LIBRESOBJS) $(SHELL_CORE_SRC) $(SQLITE3H)
   889    909   	$(LTLINK) $(SHELL_COMPILE_OPTS) $(READLINE_FLAGS) $(TOP)\shell.c $(SHELL_CORE_SRC) \
   890    910   		/link $(SQLITE3EXEPDB) $(LDFLAGS) $(LTLINKOPTS) $(SHELL_LINK_OPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LIBREADLINE) $(LTLIBS) $(TLIBS)
   891    911   
   892    912   
   893    913   # Rule to build the amalgamation
................................................................................
   919    939   	$(LTRCOMPILE) -fo $(LIBRESOBJS) -DRC_VERONLY $(TOP)\sqlite3.rc
   920    940   !ENDIF
   921    941   
   922    942   
   923    943   clean:
   924    944   	del /Q *.exp *.lo *.ilk *.lib *.obj *.ncb *.pdb *.sdf *.suo 2>NUL
   925    945   	del /Q *.bsc *.def *.cod *.da *.bb *.bbg *.vc gmon.out 2>NUL
   926         -	del /Q $(SQLITE3EXE) $(SQLITE3DLL) 2>NUL
          946  +	del /Q $(SQLITE3EXE) $(SQLITE3DLL) Replace.exe 2>NUL

Changes to autoconf/README.txt.

     2      2   
     3      3    * the SQLite library amalgamation source code file: sqlite3.c
     4      4    * the sqlite3.h and sqlite3ext.h header files that define the C-language
     5      5      interface to the sqlite3.c library file
     6      6    * the shell.c file used to build the sqlite3 command-line shell program
     7      7    * autoconf/automake installation infrastucture for building on POSIX
     8      8      compliant systems
     9         - * a Makefile.msc and sqlite3.rc for building with Microsoft Visual C++ on
    10         -   Windows
            9  + * a Makefile.msc, sqlite3.rc, and Replace.cs for building with Microsoft
           10  +   Visual C++ on Windows
    11     11   
    12     12   SUMMARY OF HOW TO BUILD
    13     13   =======================
    14     14   
    15     15     Unix:      ./configure; make
    16     16     Windows:   nmake /f Makefile.msc
    17     17   

Changes to config.h.in.

    40     40   #undef HAVE_MALLOC_H
    41     41   
    42     42   /* Define to 1 if you have the `malloc_usable_size' function. */
    43     43   #undef HAVE_MALLOC_USABLE_SIZE
    44     44   
    45     45   /* Define to 1 if you have the <memory.h> header file. */
    46     46   #undef HAVE_MEMORY_H
           47  +
           48  +/* Define to 1 if you have the pread() function. */
           49  +#undef HAVE_PREAD
           50  +
           51  +/* Define to 1 if you have the pread64() function. */
           52  +#undef HAVE_PREAD64
           53  +
           54  +/* Define to 1 if you have the pwrite() function. */
           55  +#undef HAVE_PWRITE
           56  +
           57  +/* Define to 1 if you have the pwrite64() function. */
           58  +#undef HAVE_PWRITE64
    47     59   
    48     60   /* Define to 1 if you have the <stdint.h> header file. */
    49     61   #undef HAVE_STDINT_H
    50     62   
    51     63   /* Define to 1 if you have the <stdlib.h> header file. */
    52     64   #undef HAVE_STDLIB_H
    53     65   

Changes to configure.

 10269  10269   
 10270  10270   done
 10271  10271   
 10272  10272   
 10273  10273   #########
 10274  10274   # Figure out whether or not we have these functions
 10275  10275   #
 10276         -for ac_func in fdatasync gmtime_r isnan localtime_r localtime_s malloc_usable_size strchrnul usleep utime
        10276  +for ac_func in fdatasync gmtime_r isnan localtime_r localtime_s malloc_usable_size strchrnul usleep utime pread pread64 pwrite pwrite64
 10277  10277   do :
 10278  10278     as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
 10279  10279   ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
 10280  10280   if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
 10281  10281     cat >>confdefs.h <<_ACEOF
 10282  10282   #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
 10283  10283   _ACEOF

Changes to configure.ac.

   104    104   #########
   105    105   # Check for needed/wanted headers
   106    106   AC_CHECK_HEADERS([sys/types.h stdlib.h stdint.h inttypes.h malloc.h])
   107    107   
   108    108   #########
   109    109   # Figure out whether or not we have these functions
   110    110   #
   111         -AC_CHECK_FUNCS([fdatasync gmtime_r isnan localtime_r localtime_s malloc_usable_size strchrnul usleep utime])
          111  +AC_CHECK_FUNCS([fdatasync gmtime_r isnan localtime_r localtime_s malloc_usable_size strchrnul usleep utime pread pread64 pwrite pwrite64])
   112    112   
   113    113   #########
   114    114   # By default, we use the amalgamation (this may be changed below...)
   115    115   #
   116    116   USE_AMALGAMATION=1
   117    117   
   118    118   #########

Changes to ext/fts3/fts3_tokenizer.c.

    24     24   **       SQLite (in which case SQLITE_ENABLE_FTS3 is defined).
    25     25   */
    26     26   #include "fts3Int.h"
    27     27   #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3)
    28     28   
    29     29   #include <assert.h>
    30     30   #include <string.h>
           31  +
           32  +/*
           33  +** Return true if the two-argument version of fts3_tokenizer()
           34  +** has been activated via a prior call to sqlite3_db_config(db,
           35  +** SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER, 1, 0);
           36  +*/
           37  +static int fts3TokenizerEnabled(sqlite3_context *context){
           38  +  sqlite3 *db = sqlite3_context_db_handle(context);
           39  +  int isEnabled = 0;
           40  +  sqlite3_db_config(db,SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER,-1,&isEnabled);
           41  +  return isEnabled;
           42  +}
    31     43   
    32     44   /*
    33     45   ** Implementation of the SQL scalar function for accessing the underlying 
    34     46   ** hash table. This function may be called as follows:
    35     47   **
    36     48   **   SELECT <function-name>(<key-name>);
    37     49   **   SELECT <function-name>(<key-name>, <pointer>);
................................................................................
    45     57   ** the string <key-name> must already exist in the has table. Otherwise,
    46     58   ** an error is returned.
    47     59   **
    48     60   ** Whether or not the <pointer> argument is specified, the value returned
    49     61   ** is a blob containing the pointer stored as the hash data corresponding
    50     62   ** to string <key-name> (after the hash-table is updated, if applicable).
    51     63   */
    52         -static void scalarFunc(
           64  +static void fts3TokenizerFunc(
    53     65     sqlite3_context *context,
    54     66     int argc,
    55     67     sqlite3_value **argv
    56     68   ){
    57     69     Fts3Hash *pHash;
    58     70     void *pPtr = 0;
    59     71     const unsigned char *zName;
................................................................................
    63     75   
    64     76     pHash = (Fts3Hash *)sqlite3_user_data(context);
    65     77   
    66     78     zName = sqlite3_value_text(argv[0]);
    67     79     nName = sqlite3_value_bytes(argv[0])+1;
    68     80   
    69     81     if( argc==2 ){
    70         -#ifdef SQLITE_ENABLE_FTS3_TOKENIZER
    71         -    void *pOld;
    72         -    int n = sqlite3_value_bytes(argv[1]);
    73         -    if( zName==0 || n!=sizeof(pPtr) ){
    74         -      sqlite3_result_error(context, "argument type mismatch", -1);
    75         -      return;
    76         -    }
    77         -    pPtr = *(void **)sqlite3_value_blob(argv[1]);
    78         -    pOld = sqlite3Fts3HashInsert(pHash, (void *)zName, nName, pPtr);
    79         -    if( pOld==pPtr ){
    80         -      sqlite3_result_error(context, "out of memory", -1);
           82  +    if( fts3TokenizerEnabled(context) ){
           83  +      void *pOld;
           84  +      int n = sqlite3_value_bytes(argv[1]);
           85  +      if( zName==0 || n!=sizeof(pPtr) ){
           86  +        sqlite3_result_error(context, "argument type mismatch", -1);
           87  +        return;
           88  +      }
           89  +      pPtr = *(void **)sqlite3_value_blob(argv[1]);
           90  +      pOld = sqlite3Fts3HashInsert(pHash, (void *)zName, nName, pPtr);
           91  +      if( pOld==pPtr ){
           92  +        sqlite3_result_error(context, "out of memory", -1);
           93  +      }
           94  +    }else{
           95  +      sqlite3_result_error(context, "fts3tokenize disabled", -1);
    81     96         return;
    82     97       }
    83         -#else
    84         -    sqlite3_result_error(context, "fts3tokenize: " 
    85         -        "disabled - rebuild with -DSQLITE_ENABLE_FTS3_TOKENIZER", -1
    86         -    );
    87         -    return;
    88         -#endif /* SQLITE_ENABLE_FTS3_TOKENIZER */
    89         -  }else
    90         -  {
           98  +  }else{
    91     99       if( zName ){
    92    100         pPtr = sqlite3Fts3HashFind(pHash, zName, nName);
    93    101       }
    94    102       if( !pPtr ){
    95    103         char *zErr = sqlite3_mprintf("unknown tokenizer: %s", zName);
    96    104         sqlite3_result_error(context, zErr, -1);
    97    105         sqlite3_free(zErr);
    98    106         return;
    99    107       }
   100    108     }
   101         -
   102    109     sqlite3_result_blob(context, (void *)&pPtr, sizeof(pPtr), SQLITE_TRANSIENT);
   103    110   }
   104    111   
   105    112   int sqlite3Fts3IsIdChar(char c){
   106    113     static const char isFtsIdChar[] = {
   107    114         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  /* 0x */
   108    115         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  /* 1x */
................................................................................
   332    339       sqlite3_result_error(context, zErr, -1);
   333    340     }else{
   334    341       sqlite3_result_text(context, Tcl_GetString(pRet), -1, SQLITE_TRANSIENT);
   335    342     }
   336    343     Tcl_DecrRefCount(pRet);
   337    344   }
   338    345   
   339         -#ifdef SQLITE_ENABLE_FTS3_TOKENIZER
   340    346   static
   341    347   int registerTokenizer(
   342    348     sqlite3 *db, 
   343    349     char *zName, 
   344    350     const sqlite3_tokenizer_module *p
   345    351   ){
   346    352     int rc;
................................................................................
   354    360   
   355    361     sqlite3_bind_text(pStmt, 1, zName, -1, SQLITE_STATIC);
   356    362     sqlite3_bind_blob(pStmt, 2, &p, sizeof(p), SQLITE_STATIC);
   357    363     sqlite3_step(pStmt);
   358    364   
   359    365     return sqlite3_finalize(pStmt);
   360    366   }
   361         -#endif /* SQLITE_ENABLE_FTS3_TOKENIZER */
   362    367   
   363    368   
   364    369   static
   365    370   int queryTokenizer(
   366    371     sqlite3 *db, 
   367    372     char *zName,  
   368    373     const sqlite3_tokenizer_module **pp
................................................................................
   427    432     assert( p1==p2 );
   428    433     rc = queryTokenizer(db, "nosuchtokenizer", &p2);
   429    434     assert( rc==SQLITE_ERROR );
   430    435     assert( p2==0 );
   431    436     assert( 0==strcmp(sqlite3_errmsg(db), "unknown tokenizer: nosuchtokenizer") );
   432    437   
   433    438     /* Test the storage function */
   434         -#ifdef SQLITE_ENABLE_FTS3_TOKENIZER
   435         -  rc = registerTokenizer(db, "nosuchtokenizer", p1);
   436         -  assert( rc==SQLITE_OK );
   437         -  rc = queryTokenizer(db, "nosuchtokenizer", &p2);
   438         -  assert( rc==SQLITE_OK );
   439         -  assert( p2==p1 );
   440         -#endif
          439  +  if( fts3TokenizerEnabled(context) ){
          440  +    rc = registerTokenizer(db, "nosuchtokenizer", p1);
          441  +    assert( rc==SQLITE_OK );
          442  +    rc = queryTokenizer(db, "nosuchtokenizer", &p2);
          443  +    assert( rc==SQLITE_OK );
          444  +    assert( p2==p1 );
          445  +  }
   441    446   
   442    447     sqlite3_result_text(context, "ok", -1, SQLITE_STATIC);
   443    448   }
   444    449   
   445    450   #endif
   446    451   
   447    452   /*
................................................................................
   449    454   ** the hash table pointed to by argument pHash. The hash table must
   450    455   ** been initialized to use string keys, and to take a private copy 
   451    456   ** of the key when a value is inserted. i.e. by a call similar to:
   452    457   **
   453    458   **    sqlite3Fts3HashInit(pHash, FTS3_HASH_STRING, 1);
   454    459   **
   455    460   ** This function adds a scalar function (see header comment above
   456         -** scalarFunc() in this file for details) and, if ENABLE_TABLE is
          461  +** fts3TokenizerFunc() in this file for details) and, if ENABLE_TABLE is
   457    462   ** defined at compilation time, a temporary virtual table (see header 
   458    463   ** comment above struct HashTableVtab) to the database schema. Both 
   459    464   ** provide read/write access to the contents of *pHash.
   460    465   **
   461    466   ** The third argument to this function, zName, is used as the name
   462    467   ** of both the scalar and, if created, the virtual table.
   463    468   */
................................................................................
   478    483     zTest2 = sqlite3_mprintf("%s_internal_test", zName);
   479    484     if( !zTest || !zTest2 ){
   480    485       rc = SQLITE_NOMEM;
   481    486     }
   482    487   #endif
   483    488   
   484    489     if( SQLITE_OK==rc ){
   485         -    rc = sqlite3_create_function(db, zName, 1, any, p, scalarFunc, 0, 0);
          490  +    rc = sqlite3_create_function(db, zName, 1, any, p, fts3TokenizerFunc, 0, 0);
   486    491     }
   487    492     if( SQLITE_OK==rc ){
   488         -    rc = sqlite3_create_function(db, zName, 2, any, p, scalarFunc, 0, 0);
          493  +    rc = sqlite3_create_function(db, zName, 2, any, p, fts3TokenizerFunc, 0, 0);
   489    494     }
   490    495   #ifdef SQLITE_TEST
   491    496     if( SQLITE_OK==rc ){
   492    497       rc = sqlite3_create_function(db, zTest, -1, any, p, testFunc, 0, 0);
   493    498     }
   494    499     if( SQLITE_OK==rc ){
   495    500       rc = sqlite3_create_function(db, zTest2, 0, any, pdb, intTestFunc, 0, 0);

Changes to ext/fts5/fts5_index.c.

   693    693       p->rc = rc;
   694    694       p->nRead++;
   695    695     }
   696    696   
   697    697     assert( (pRet==0)==(p->rc!=SQLITE_OK) );
   698    698     return pRet;
   699    699   }
          700  +
   700    701   
   701    702   /*
   702    703   ** Release a reference to data record returned by an earlier call to
   703    704   ** fts5DataRead().
   704    705   */
   705    706   static void fts5DataRelease(Fts5Data *pData){
   706    707     sqlite3_free(pData);
................................................................................
  2150   2151     int bEndOfPage = 0;
  2151   2152   
  2152   2153     assert( p->rc==SQLITE_OK );
  2153   2154   
  2154   2155     iPgidx = szLeaf;
  2155   2156     iPgidx += fts5GetVarint32(&a[iPgidx], iTermOff);
  2156   2157     iOff = iTermOff;
         2158  +  if( iOff>n ){
         2159  +    p->rc = FTS5_CORRUPT;
         2160  +    return;
         2161  +  }
  2157   2162   
  2158   2163     while( 1 ){
  2159   2164   
  2160   2165       /* Figure out how many new bytes are in this term */
  2161   2166       fts5FastGetVarint32(a, iOff, nNew);
  2162   2167       if( nKeep<nMatch ){
  2163   2168         goto search_failed;
................................................................................
  4495   4500       pNew->nRef = 1;
  4496   4501       pNew->nWriteCounter = pStruct->nWriteCounter;
  4497   4502       pLvl = &pNew->aLevel[pStruct->nLevel];
  4498   4503       pLvl->aSeg = (Fts5StructureSegment*)sqlite3Fts5MallocZero(&p->rc, nByte);
  4499   4504       if( pLvl->aSeg ){
  4500   4505         int iLvl, iSeg;
  4501   4506         int iSegOut = 0;
  4502         -      for(iLvl=0; iLvl<pStruct->nLevel; iLvl++){
         4507  +      /* Iterate through all segments, from oldest to newest. Add them to
         4508  +      ** the new Fts5Level object so that pLvl->aSeg[0] is the oldest
         4509  +      ** segment in the data structure.  */
         4510  +      for(iLvl=pStruct->nLevel-1; iLvl>=0; iLvl--){
  4503   4511           for(iSeg=0; iSeg<pStruct->aLevel[iLvl].nSeg; iSeg++){
  4504   4512             pLvl->aSeg[iSegOut] = pStruct->aLevel[iLvl].aSeg[iSeg];
  4505   4513             iSegOut++;
  4506   4514           }
  4507   4515         }
  4508   4516         pNew->nSegment = pLvl->nSeg = nSeg;
  4509   4517       }else{

Changes to ext/fts5/test/fts5_common.tcl.

    12     12   
    13     13   if {![info exists testdir]} {
    14     14     set testdir [file join [file dirname [info script]] .. .. .. test]
    15     15   }
    16     16   source $testdir/tester.tcl
    17     17   
    18     18   ifcapable !fts5 {
    19         -  finish_test
           19  +  proc return_if_no_fts5 {} {
           20  +    finish_test
           21  +    return -code return
           22  +  }
    20     23     return
           24  +} else {
           25  +  proc return_if_no_fts5 {} {}
    21     26   }
    22     27   
    23     28   catch { 
    24     29     sqlite3_fts5_may_be_corrupt 0 
    25     30     reset_db
    26     31   }
    27     32   
    28         -# If SQLITE_ENABLE_FTS5 is not defined, skip this test.
    29         -ifcapable !fts5 {
    30         -  finish_test
    31         -  return
    32         -}
    33         -
    34     33   proc fts5_test_poslist {cmd} {
    35     34     set res [list]
    36     35     for {set i 0} {$i < [$cmd xInstCount]} {incr i} {
    37     36       lappend res [string map {{ } .} [$cmd xInst $i]]
    38     37     }
    39     38     set res
    40     39   }

Changes to ext/fts5/test/fts5bigtok.test.

    10     10   #*************************************************************************
    11     11   # This file implements regression tests for SQLite library.  The
    12     12   # focus of this script is testing the FTS5 module.
    13     13   #
    14     14   
    15     15   source [file join [file dirname [info script]] fts5_common.tcl]
    16     16   set testprefix fts5bigtok
           17  +return_if_no_fts5
    17     18   
    18     19   proc rndterm {} {
    19     20     set L [list a b c d e f g h i j k l m n o p q r s t u v w x y z]
    20     21     set l [lindex $L [expr int(rand() * [llength $L])]]
    21     22     string repeat $l [expr int(rand() * 5) + 60]
    22     23   }
    23     24   

Changes to ext/fts5/test/fts5merge2.test.

     9      9   #
    10     10   #***********************************************************************
    11     11   #
    12     12   # Test that focus on incremental merges of segments.
    13     13   #
    14     14   
    15     15   source [file join [file dirname [info script]] fts5_common.tcl]
    16         -set testprefix fts5merge
           16  +set testprefix fts5merge2
           17  +return_if_no_fts5
    17     18   
    18     19   proc dump_structure {} {
    19     20     db eval {SELECT fts5_decode(id, block) AS t FROM t1_data WHERE id=10} {
    20     21       foreach lvl [lrange $t 1 end] {
    21     22         set seg [string repeat . [expr [llength $lvl]-2]]
    22     23         puts "[lrange $lvl 0 1] $seg"
    23     24       }
    24     25     }
    25     26   }
    26     27   
    27     28   foreach_detail_mode $testprefix {
    28     29   
    29         -if {[detail_is_none]==0} continue
    30         -
    31     30   do_execsql_test 1.0 {
    32     31     CREATE VIRTUAL TABLE t1 USING fts5(x, detail=%DETAIL%);
    33     32     INSERT INTO t1(t1, rank) VALUES('pgsz', 32);
    34     33     INSERT INTO t1(t1, rank) VALUES('crisismerge', 2);
    35     34     INSERT INTO t1 VALUES('1 2 3 4');
    36     35   }
    37     36   

Changes to ext/fts5/test/fts5simple.test.

   405    405     CREATE VIRTUAL TABLE x1 USING fts5(a,b,c);
   406    406   }
   407    407   
   408    408   do_catchsql_test 19.2 {
   409    409     SELECT * FROM x1 WHERE x1 MATCH 'c0 AND (c1 AND (c2 AND (c3 AND (c4 AND (c5 AND (c6 AND (c7 AND (c8 AND (c9 AND (c10 AND (c11 AND (c12 AND (c13 AND (c14 AND (c15 AND (c16 AND (c17 AND (c18 AND (c19 AND (c20 AND (c21 AND (c22 AND (c23 AND (c24 AND (c25 AND (c26 AND (c27 AND (c28 AND (c29 AND (c30 AND (c31 AND (c32 AND (c33 AND (c34 AND (c35 AND (c36 AND (c37 AND (c38 AND (c39 AND (c40 AND (c41 AND (c42 AND (c43 AND (c44 AND (c45 AND (c46 AND (c47 AND (c48 AND (c49 AND (c50 AND (c51 AND (c52 AND (c53 AND (c54 AND (c55 AND (c56 AND (c57 AND (c58 AND (c59 AND (c60 AND (c61 AND (c62 AND (c63 AND (c64 AND (c65 AND (c66 AND (c67 AND (c68 AND (c69 AND (c70 AND (c71 AND (c72 AND (c73 AND (c74 AND (c75 AND (c76 AND (c77 AND (c78 AND (c79 AND (c80 AND (c81 AND (c82 AND (c83 AND (c84 AND (c85 AND (c86 AND (c87 AND (c88 AND (c89 AND (c90 AND (c91 AND (c92 AND (c93 AND (c94 AND (c95 AND (c96 AND (c97 AND (c98 AND (c99 AND (c100 AND (c101 AND (c102 AND (c103 AND (c104 AND (c105 AND (c106 AND (c107 AND (c108 AND (c109 AND (c110 AND (c111 AND (c112 AND (c113 AND (c114 AND (c115 AND (c116 AND (c117 AND (c118 AND (c119 AND (c120 AND (c121 AND (c122 AND (c123 AND (c124 AND (c125 AND (c126 AND (c127 AND (c128 AND (c129 AND (c130 AND (c131 AND (c132 AND (c133 AND (c134 AND (c135 AND (c136 AND (c137 AND (c138 AND (c139 AND (c140 AND (c141 AND (c142 AND (c143 AND (c144 AND (c145 AND (c146 AND (c147 AND (c148 AND (c149 AND (c150 AND (c151 AND (c152 AND (c153 AND (c154 AND (c155 AND (c156 AND (c157 AND (c158 AND (c159 AND (c160 AND (c161 AND (c162 AND (c163 AND (c164 AND (c165 AND (c166 AND (c167 AND (c168 AND (c169 AND (c170 AND (c171 AND (c172 AND (c173 AND (c174 AND (c175 AND (c176 AND (c177 AND (c178 AND (c179 AND (c180 AND (c181 AND (c182 AND (c183 AND (c184 AND (c185 AND (c186 AND (c187 AND (c188 AND (c189 AND (c190 AND (c191 AND (c192 AND (c193 AND (c194 AND (c195 AND (c196 AND (c197 AND (c198 AND (c199 AND c200)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))';
   410    410   } {1 {fts5: parser stack overflow}}
   411    411   
   412         -finish_test
          412  +#-------------------------------------------------------------------------
          413  +reset_db
          414  +breakpoint
          415  +do_execsql_test 20.0 {
          416  +  CREATE VIRTUAL TABLE x1 USING fts5(x);
          417  +  INSERT INTO x1(x1, rank) VALUES('pgsz', 32);
          418  +  INSERT INTO x1(rowid, x) VALUES(11111, 'onetwothree');
          419  +}
          420  +do_test 20.1 {
          421  +  for {set i 1} {$i <= 200} {incr i} {
          422  +    execsql { INSERT INTO x1(rowid, x) VALUES($i, 'one two three'); }
          423  +  }
          424  +  execsql { INSERT INTO x1(x1) VALUES('optimize'); }
          425  +  execsql { DELETE FROM x1 WHERE rowid = 4; }
          426  +} {}
          427  +do_execsql_test 20.2 {
          428  +  INSERT INTO x1(x1) VALUES('optimize');
          429  +  INSERT INTO x1(x1) VALUES('integrity-check');
          430  +} {}
          431  +
          432  +#-------------------------------------------------------------------------
          433  +reset_db
          434  +do_execsql_test 20.0 {
          435  +  CREATE VIRTUAL TABLE x1 USING fts5(x);
          436  +  INSERT INTO x1(x1, rank) VALUES('pgsz', 32);
          437  +  INSERT INTO x1(rowid, x) VALUES(11111, 'onetwothree');
          438  +}
          439  +do_test 20.1 {
          440  +  for {set i 1} {$i <= 200} {incr i} {
          441  +    execsql { INSERT INTO x1(rowid, x) VALUES($i, 'one two three'); }
          442  +  }
          443  +  execsql { INSERT INTO x1(x1) VALUES('optimize'); }
          444  +  execsql { DELETE FROM x1 WHERE rowid = 4; }
          445  +} {}
          446  +do_execsql_test 20.2 {
          447  +  INSERT INTO x1(x1) VALUES('optimize');
          448  +  INSERT INTO x1(x1) VALUES('integrity-check');
          449  +} {}
   413    450   
          451  +finish_test

Changes to ext/icu/icu.c.

    55     55   
    56     56   /*
    57     57   ** Version of sqlite3_free() that is always a function, never a macro.
    58     58   */
    59     59   static void xFree(void *p){
    60     60     sqlite3_free(p);
    61     61   }
           62  +
           63  +/*
           64  +** This lookup table is used to help decode the first byte of
           65  +** a multi-byte UTF8 character. It is copied here from SQLite source
           66  +** code file utf8.c.
           67  +*/
           68  +static const unsigned char icuUtf8Trans1[] = {
           69  +  0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
           70  +  0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
           71  +  0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
           72  +  0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
           73  +  0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
           74  +  0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
           75  +  0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
           76  +  0x00, 0x01, 0x02, 0x03, 0x00, 0x01, 0x00, 0x00,
           77  +};
           78  +
           79  +#define SQLITE_ICU_READ_UTF8(zIn, c)                       \
           80  +  c = *(zIn++);                                            \
           81  +  if( c>=0xc0 ){                                           \
           82  +    c = icuUtf8Trans1[c-0xc0];                             \
           83  +    while( (*zIn & 0xc0)==0x80 ){                          \
           84  +      c = (c<<6) + (0x3f & *(zIn++));                      \
           85  +    }                                                      \
           86  +  }
           87  +
           88  +#define SQLITE_ICU_SKIP_UTF8(zIn)                          \
           89  +  assert( *zIn );                                          \
           90  +  if( *(zIn++)>=0xc0 ){                                    \
           91  +    while( (*zIn & 0xc0)==0x80 ){zIn++;}                   \
           92  +  }
           93  +
    62     94   
    63     95   /*
    64     96   ** Compare two UTF-8 strings for equality where the first string is
    65     97   ** a "LIKE" expression. Return true (1) if they are the same and 
    66     98   ** false (0) if they are different.
    67     99   */
    68    100   static int icuLikeCompare(
................................................................................
    69    101     const uint8_t *zPattern,   /* LIKE pattern */
    70    102     const uint8_t *zString,    /* The UTF-8 string to compare against */
    71    103     const UChar32 uEsc         /* The escape character */
    72    104   ){
    73    105     static const int MATCH_ONE = (UChar32)'_';
    74    106     static const int MATCH_ALL = (UChar32)'%';
    75    107   
    76         -  int iPattern = 0;       /* Current byte index in zPattern */
    77         -  int iString = 0;        /* Current byte index in zString */
    78         -
    79    108     int prevEscape = 0;     /* True if the previous character was uEsc */
    80    109   
    81         -  while( zPattern[iPattern]!=0 ){
          110  +  while( 1 ){
    82    111   
    83    112       /* Read (and consume) the next character from the input pattern. */
    84    113       UChar32 uPattern;
    85         -    U8_NEXT_UNSAFE(zPattern, iPattern, uPattern);
          114  +    SQLITE_ICU_READ_UTF8(zPattern, uPattern);
          115  +    if( uPattern==0 ) break;
    86    116   
    87    117       /* There are now 4 possibilities:
    88    118       **
    89    119       **     1. uPattern is an unescaped match-all character "%",
    90    120       **     2. uPattern is an unescaped match-one character "_",
    91    121       **     3. uPattern is an unescaped escape character, or
    92    122       **     4. uPattern is to be handled as an ordinary character
................................................................................
    95    125         /* Case 1. */
    96    126         uint8_t c;
    97    127   
    98    128         /* Skip any MATCH_ALL or MATCH_ONE characters that follow a
    99    129         ** MATCH_ALL. For each MATCH_ONE, skip one character in the 
   100    130         ** test string.
   101    131         */
   102         -      while( (c=zPattern[iPattern]) == MATCH_ALL || c == MATCH_ONE ){
          132  +      while( (c=*zPattern) == MATCH_ALL || c == MATCH_ONE ){
   103    133           if( c==MATCH_ONE ){
   104         -          if( zString[iString]==0 ) return 0;
   105         -          U8_FWD_1_UNSAFE(zString, iString);
          134  +          if( *zString==0 ) return 0;
          135  +          SQLITE_ICU_SKIP_UTF8(zString);
   106    136           }
   107         -        iPattern++;
          137  +        zPattern++;
   108    138         }
   109    139   
   110         -      if( zPattern[iPattern]==0 ) return 1;
          140  +      if( *zPattern==0 ) return 1;
   111    141   
   112         -      while( zString[iString] ){
   113         -        if( icuLikeCompare(&zPattern[iPattern], &zString[iString], uEsc) ){
          142  +      while( *zString ){
          143  +        if( icuLikeCompare(zPattern, zString, uEsc) ){
   114    144             return 1;
   115    145           }
   116         -        U8_FWD_1_UNSAFE(zString, iString);
          146  +        SQLITE_ICU_SKIP_UTF8(zString);
   117    147         }
   118    148         return 0;
   119    149   
   120    150       }else if( !prevEscape && uPattern==MATCH_ONE ){
   121    151         /* Case 2. */
   122         -      if( zString[iString]==0 ) return 0;
   123         -      U8_FWD_1_UNSAFE(zString, iString);
          152  +      if( *zString==0 ) return 0;
          153  +      SQLITE_ICU_SKIP_UTF8(zString);
   124    154   
   125    155       }else if( !prevEscape && uPattern==uEsc){
   126    156         /* Case 3. */
   127    157         prevEscape = 1;
   128    158   
   129    159       }else{
   130    160         /* Case 4. */
   131    161         UChar32 uString;
   132         -      U8_NEXT_UNSAFE(zString, iString, uString);
          162  +      SQLITE_ICU_READ_UTF8(zString, uString);
   133    163         uString = u_foldCase(uString, U_FOLD_CASE_DEFAULT);
   134    164         uPattern = u_foldCase(uPattern, U_FOLD_CASE_DEFAULT);
   135    165         if( uString!=uPattern ){
   136    166           return 0;
   137    167         }
   138    168         prevEscape = 0;
   139    169       }
   140    170     }
   141    171   
   142         -  return zString[iString]==0;
          172  +  return *zString==0;
   143    173   }
   144    174   
   145    175   /*
   146    176   ** Implementation of the like() SQL function.  This function implements
   147    177   ** the build-in LIKE operator.  The first argument to the function is the
   148    178   ** pattern and the second argument is the string.  So, the SQL statements:
   149    179   **
................................................................................
   321    351   **     lower('I', 'en_us') -> 'i'
   322    352   **     lower('I', 'tr_tr') -> 'ı' (small dotless i)
   323    353   **
   324    354   ** http://www.icu-project.org/userguide/posix.html#case_mappings
   325    355   */
   326    356   static void icuCaseFunc16(sqlite3_context *p, int nArg, sqlite3_value **apArg){
   327    357     const UChar *zInput;
   328         -  UChar *zOutput;
          358  +  UChar *zOutput = 0;
   329    359     int nInput;
   330         -  int nOutput;
   331         -
   332         -  UErrorCode status = U_ZERO_ERROR;
          360  +  int nOut;
          361  +  int cnt;
          362  +  UErrorCode status;
   333    363     const char *zLocale = 0;
   334    364   
   335    365     assert(nArg==1 || nArg==2);
   336    366     if( nArg==2 ){
   337    367       zLocale = (const char *)sqlite3_value_text(apArg[1]);
   338    368     }
   339    369   
   340    370     zInput = sqlite3_value_text16(apArg[0]);
   341    371     if( !zInput ){
   342    372       return;
   343    373     }
   344         -  nInput = sqlite3_value_bytes16(apArg[0]);
   345         -
   346         -  nOutput = nInput * 2 + 2;
   347         -  zOutput = sqlite3_malloc(nOutput);
   348         -  if( !zOutput ){
          374  +  nOut = nInput = sqlite3_value_bytes16(apArg[0]);
          375  +  if( nOut==0 ){
          376  +    sqlite3_result_text16(p, "", 0, SQLITE_STATIC);
   349    377       return;
   350    378     }
   351    379   
   352         -  if( sqlite3_user_data(p) ){
   353         -    u_strToUpper(zOutput, nOutput/2, zInput, nInput/2, zLocale, &status);
   354         -  }else{
   355         -    u_strToLower(zOutput, nOutput/2, zInput, nInput/2, zLocale, &status);
   356         -  }
   357         -
   358         -  if( !U_SUCCESS(status) ){
   359         -    icuFunctionError(p, "u_strToLower()/u_strToUpper", status);
   360         -    return;
          380  +  for(cnt=0; cnt<2; cnt++){
          381  +    UChar *zNew = sqlite3_realloc(zOutput, nOut);
          382  +    if( zNew==0 ){
          383  +      sqlite3_free(zOutput);
          384  +      sqlite3_result_error_nomem(p);
          385  +      return;
          386  +    }
          387  +    zOutput = zNew;
          388  +    status = U_ZERO_ERROR;
          389  +    if( sqlite3_user_data(p) ){
          390  +      nOut = 2*u_strToUpper(zOutput,nOut/2,zInput,nInput/2,zLocale,&status);
          391  +    }else{
          392  +      nOut = 2*u_strToLower(zOutput,nOut/2,zInput,nInput/2,zLocale,&status);
          393  +    }
          394  +    if( !U_SUCCESS(status) ){
          395  +      if( status==U_BUFFER_OVERFLOW_ERROR ) continue;
          396  +      icuFunctionError(p,
          397  +          sqlite3_user_data(p) ? "u_strToUpper" : "u_strToLower", status);
          398  +      return;
          399  +    }
   361    400     }
   362         -
   363         -  sqlite3_result_text16(p, zOutput, -1, xFree);
          401  +  sqlite3_result_text16(p, zOutput, nOut, xFree);
   364    402   }
   365    403   
   366    404   /*
   367    405   ** Collation sequence destructor function. The pCtx argument points to
   368    406   ** a UCollator structure previously allocated using ucol_open().
   369    407   */
   370    408   static void icuCollationDel(void *pCtx){

Changes to ext/misc/series.c.

   213    213     if( pCur->isDesc ){
   214    214       return pCur->iValue < pCur->mnValue;
   215    215     }else{
   216    216       return pCur->iValue > pCur->mxValue;
   217    217     }
   218    218   }
   219    219   
          220  +/* True to cause run-time checking of the start=, stop=, and/or step= 
          221  +** parameters.  The only reason to do this is for testing the
          222  +** constraint checking logic for virtual tables in the SQLite core.
          223  +*/
          224  +#ifndef SQLITE_SERIES_CONSTRAINT_VERIFY
          225  +# define SQLITE_SERIES_CONSTRAINT_VERIFY 0
          226  +#endif
          227  +
   220    228   /*
   221    229   ** This method is called to "rewind" the series_cursor object back
   222    230   ** to the first row of output.  This method is always called at least
   223    231   ** once prior to any call to seriesColumn() or seriesRowid() or 
   224    232   ** seriesEof().
   225    233   **
   226    234   ** The query plan selected by seriesBestIndex is passed in the idxNum
................................................................................
   320    328           stepIdx = i;
   321    329           idxNum |= 4;
   322    330           break;
   323    331       }
   324    332     }
   325    333     if( startIdx>=0 ){
   326    334       pIdxInfo->aConstraintUsage[startIdx].argvIndex = ++nArg;
   327         -    pIdxInfo->aConstraintUsage[startIdx].omit = 1;
          335  +    pIdxInfo->aConstraintUsage[startIdx].omit= !SQLITE_SERIES_CONSTRAINT_VERIFY;
   328    336     }
   329    337     if( stopIdx>=0 ){
   330    338       pIdxInfo->aConstraintUsage[stopIdx].argvIndex = ++nArg;
   331         -    pIdxInfo->aConstraintUsage[stopIdx].omit = 1;
          339  +    pIdxInfo->aConstraintUsage[stopIdx].omit = !SQLITE_SERIES_CONSTRAINT_VERIFY;
   332    340     }
   333    341     if( stepIdx>=0 ){
   334    342       pIdxInfo->aConstraintUsage[stepIdx].argvIndex = ++nArg;
   335         -    pIdxInfo->aConstraintUsage[stepIdx].omit = 1;
          343  +    pIdxInfo->aConstraintUsage[stepIdx].omit = !SQLITE_SERIES_CONSTRAINT_VERIFY;
   336    344     }
   337    345     if( (idxNum & 3)==3 ){
   338    346       /* Both start= and stop= boundaries are available.  This is the 
   339    347       ** the preferred case */
   340         -    pIdxInfo->estimatedCost = (double)1;
          348  +    pIdxInfo->estimatedCost = (double)(2 - ((idxNum&4)!=0));
   341    349       pIdxInfo->estimatedRows = 1000;
   342    350       if( pIdxInfo->nOrderBy==1 ){
   343    351         if( pIdxInfo->aOrderBy[0].desc ) idxNum |= 8;
   344    352         pIdxInfo->orderByConsumed = 1;
   345    353       }
   346    354     }else{
   347    355       /* If either boundary is missing, we have to generate a huge span

Changes to ext/misc/spellfix.c.

  1771   1771   /* End transliterate
  1772   1772   ******************************************************************************
  1773   1773   ******************************************************************************
  1774   1774   ** Begin spellfix1 virtual table.
  1775   1775   */
  1776   1776   
  1777   1777   /* Maximum length of a phonehash used for querying the shadow table */
  1778         -#define SPELLFIX_MX_HASH  8
         1778  +#define SPELLFIX_MX_HASH  32
  1779   1779   
  1780   1780   /* Maximum number of hash strings to examine per query */
  1781   1781   #define SPELLFIX_MX_RUN   1
  1782   1782   
  1783   1783   typedef struct spellfix1_vtab spellfix1_vtab;
  1784   1784   typedef struct spellfix1_cursor spellfix1_cursor;
  1785   1785   

Changes to main.mk.

   286    286     $(TOP)/src/test6.c \
   287    287     $(TOP)/src/test7.c \
   288    288     $(TOP)/src/test8.c \
   289    289     $(TOP)/src/test9.c \
   290    290     $(TOP)/src/test_autoext.c \
   291    291     $(TOP)/src/test_async.c \
   292    292     $(TOP)/src/test_backup.c \
          293  +  $(TOP)/src/test_bestindex.c \
   293    294     $(TOP)/src/test_blob.c \
   294    295     $(TOP)/src/test_btree.c \
   295    296     $(TOP)/src/test_config.c \
   296    297     $(TOP)/src/test_demovfs.c \
   297    298     $(TOP)/src/test_devsym.c \
   298    299     $(TOP)/src/test_fs.c \
   299    300     $(TOP)/src/test_func.c \
................................................................................
   732    733   
   733    734   sqlite3_analyzer$(EXE): sqlite3_analyzer.c
   734    735   	$(TCCX) $(TCL_FLAGS) sqlite3_analyzer.c -o $@ $(LIBTCL) $(THREADLIB) 
   735    736   
   736    737   # Rules to build the 'testfixture' application.
   737    738   #
   738    739   TESTFIXTURE_FLAGS  = -DSQLITE_TEST=1 -DSQLITE_CRASH_TEST=1
   739         -TESTFIXTURE_FLAGS += -DSQLITE_SERVER=1 -DSQLITE_PRIVATE="" -DSQLITE_CORE 
          740  +TESTFIXTURE_FLAGS += -DSQLITE_SERVER=1 -DSQLITE_PRIVATE="" -DSQLITE_CORE
          741  +TESTFIXTURE_FLAGS += -DSQLITE_SERIES_CONSTRAINT_VERIFY=1
          742  +TESTFIXTURE_FLAGS += -DSQLITE_DEFAULT_PAGE_SIZE=1024
   740    743   
   741    744   testfixture$(EXE): $(TESTSRC2) libsqlite3.a $(TESTSRC) $(TOP)/src/tclsqlite.c
   742    745   	$(TCCX) $(TCL_FLAGS) -DTCLSH=1 $(TESTFIXTURE_FLAGS)                  \
   743    746   		$(TESTSRC) $(TESTSRC2) $(TOP)/src/tclsqlite.c                \
   744    747   		-o testfixture$(EXE) $(LIBTCL) libsqlite3.a $(THREADLIB)
   745    748   
   746    749   amalgamation-testfixture$(EXE): sqlite3.c $(TESTSRC) $(TOP)/src/tclsqlite.c  \

Changes to src/alter.c.

   624    624     }
   625    625   #endif
   626    626   
   627    627     /* If the default value for the new column was specified with a 
   628    628     ** literal NULL, then set pDflt to 0. This simplifies checking
   629    629     ** for an SQL NULL default below.
   630    630     */
   631         -  if( pDflt && pDflt->op==TK_NULL ){
          631  +  assert( pDflt==0 || pDflt->op==TK_SPAN );
          632  +  if( pDflt && pDflt->pLeft->op==TK_NULL ){
   632    633       pDflt = 0;
   633    634     }
   634    635   
   635    636     /* Check that the new column is not specified as PRIMARY KEY or UNIQUE.
   636    637     ** If there is a NOT NULL constraint, then the default value for the
   637    638     ** column must not be NULL.
   638    639     */
................................................................................
   781    782       goto exit_begin_add_column;
   782    783     }
   783    784     memcpy(pNew->aCol, pTab->aCol, sizeof(Column)*pNew->nCol);
   784    785     for(i=0; i<pNew->nCol; i++){
   785    786       Column *pCol = &pNew->aCol[i];
   786    787       pCol->zName = sqlite3DbStrDup(db, pCol->zName);
   787    788       pCol->zColl = 0;
   788         -    pCol->zType = 0;
   789    789       pCol->pDflt = 0;
   790         -    pCol->zDflt = 0;
   791    790     }
   792    791     pNew->pSchema = db->aDb[iDb].pSchema;
   793    792     pNew->addColOffset = pTab->addColOffset;
   794    793     pNew->nRef = 1;
   795    794   
   796    795     /* Begin a transaction and increment the schema cookie.  */
   797    796     sqlite3BeginWriteOperation(pParse, 0, iDb);

Changes to src/build.c.

   567    567     int i;
   568    568     Column *pCol;
   569    569     assert( pTable!=0 );
   570    570     if( (pCol = pTable->aCol)!=0 ){
   571    571       for(i=0; i<pTable->nCol; i++, pCol++){
   572    572         sqlite3DbFree(db, pCol->zName);
   573    573         sqlite3ExprDelete(db, pCol->pDflt);
   574         -      sqlite3DbFree(db, pCol->zDflt);
   575         -      sqlite3DbFree(db, pCol->zType);
   576    574         sqlite3DbFree(db, pCol->zColl);
   577    575       }
   578    576       sqlite3DbFree(db, pTable->aCol);
   579    577     }
   580    578   }
   581    579   
   582    580   /*
................................................................................
  1035   1033   ** Add a new column to the table currently being constructed.
  1036   1034   **
  1037   1035   ** The parser calls this routine once for each column declaration
  1038   1036   ** in a CREATE TABLE statement.  sqlite3StartTable() gets called
  1039   1037   ** first to get things going.  Then this routine is called for each
  1040   1038   ** column.
  1041   1039   */
  1042         -void sqlite3AddColumn(Parse *pParse, Token *pName){
         1040  +void sqlite3AddColumn(Parse *pParse, Token *pName, Token *pType){
  1043   1041     Table *p;
  1044   1042     int i;
  1045   1043     char *z;
         1044  +  char *zType;
  1046   1045     Column *pCol;
  1047   1046     sqlite3 *db = pParse->db;
  1048   1047     if( (p = pParse->pNewTable)==0 ) return;
  1049   1048   #if SQLITE_MAX_COLUMN
  1050   1049     if( p->nCol+1>db->aLimit[SQLITE_LIMIT_COLUMN] ){
  1051   1050       sqlite3ErrorMsg(pParse, "too many columns on %s", p->zName);
  1052   1051       return;
  1053   1052     }
  1054   1053   #endif
  1055         -  z = sqlite3NameFromToken(db, pName);
         1054  +  z = sqlite3DbMallocRaw(db, pName->n + pType->n + 2);
  1056   1055     if( z==0 ) return;
         1056  +  memcpy(z, pName->z, pName->n);
         1057  +  z[pName->n] = 0;
         1058  +  sqlite3Dequote(z);
         1059  +  zType = z + sqlite3Strlen30(z) + 1;
         1060  +  memcpy(zType, pType->z, pType->n);
         1061  +  zType[pType->n] = 0;
  1057   1062     for(i=0; i<p->nCol; i++){
  1058   1063       if( sqlite3_stricmp(z, p->aCol[i].zName)==0 ){
  1059   1064         sqlite3ErrorMsg(pParse, "duplicate column name: %s", z);
  1060   1065         sqlite3DbFree(db, z);
  1061   1066         return;
  1062   1067       }
  1063   1068     }
................................................................................
  1071   1076       p->aCol = aNew;
  1072   1077     }
  1073   1078     pCol = &p->aCol[p->nCol];
  1074   1079     memset(pCol, 0, sizeof(p->aCol[0]));
  1075   1080     pCol->zName = z;
  1076   1081     sqlite3ColumnPropertiesFromName(p, pCol);
  1077   1082    
  1078         -  /* If there is no type specified, columns have the default affinity
  1079         -  ** 'BLOB'. If there is a type specified, then sqlite3AddColumnType() will
  1080         -  ** be called next to set pCol->affinity correctly.
  1081         -  */
  1082         -  pCol->affinity = SQLITE_AFF_BLOB;
  1083         -  pCol->szEst = 1;
         1083  +  if( pType->n==0 ){
         1084  +    /* If there is no type specified, columns have the default affinity
         1085  +    ** 'BLOB'. */
         1086  +    pCol->affinity = SQLITE_AFF_BLOB;
         1087  +    pCol->szEst = 1;
         1088  +  }else{
         1089  +    pCol->affinity = sqlite3AffinityType(zType, &pCol->szEst);
         1090  +  }
  1084   1091     p->nCol++;
         1092  +  pParse->constraintName.n = 0;
  1085   1093   }
  1086   1094   
  1087   1095   /*
  1088   1096   ** This routine is called by the parser while in the middle of
  1089   1097   ** parsing a CREATE TABLE statement.  A "NOT NULL" constraint has
  1090   1098   ** been seen on a column.  This routine sets the notNull flag on
  1091   1099   ** the column currently under construction.
................................................................................
  1180   1188           *pszEst = 5;   /* BLOB, TEXT, CLOB -> r=5  (approx 20 bytes)*/
  1181   1189         }
  1182   1190       }
  1183   1191     }
  1184   1192     return aff;
  1185   1193   }
  1186   1194   
  1187         -/*
  1188         -** This routine is called by the parser while in the middle of
  1189         -** parsing a CREATE TABLE statement.  The pFirst token is the first
  1190         -** token in the sequence of tokens that describe the type of the
  1191         -** column currently under construction.   pLast is the last token
  1192         -** in the sequence.  Use this information to construct a string
  1193         -** that contains the typename of the column and store that string
  1194         -** in zType.
  1195         -*/ 
  1196         -void sqlite3AddColumnType(Parse *pParse, Token *pType){
  1197         -  Table *p;
  1198         -  Column *pCol;
  1199         -
  1200         -  p = pParse->pNewTable;
  1201         -  if( p==0 || NEVER(p->nCol<1) ) return;
  1202         -  pCol = &p->aCol[p->nCol-1];
  1203         -  assert( pCol->zType==0 || CORRUPT_DB );
  1204         -  sqlite3DbFree(pParse->db, pCol->zType);
  1205         -  pCol->zType = sqlite3NameFromToken(pParse->db, pType);
  1206         -  pCol->affinity = sqlite3AffinityType(pCol->zType, &pCol->szEst);
  1207         -}
  1208         -
  1209   1195   /*
  1210   1196   ** The expression is the default value for the most recently added column
  1211   1197   ** of the table currently under construction.
  1212   1198   **
  1213   1199   ** Default value expressions must be constant.  Raise an exception if this
  1214   1200   ** is not the case.
  1215   1201   **
................................................................................
  1227   1213         sqlite3ErrorMsg(pParse, "default value of column [%s] is not constant",
  1228   1214             pCol->zName);
  1229   1215       }else{
  1230   1216         /* A copy of pExpr is used instead of the original, as pExpr contains
  1231   1217         ** tokens that point to volatile memory. The 'span' of the expression
  1232   1218         ** is required by pragma table_info.
  1233   1219         */
         1220  +      Expr x;
  1234   1221         sqlite3ExprDelete(db, pCol->pDflt);
  1235         -      pCol->pDflt = sqlite3ExprDup(db, pSpan->pExpr, EXPRDUP_REDUCE);
  1236         -      sqlite3DbFree(db, pCol->zDflt);
  1237         -      pCol->zDflt = sqlite3DbStrNDup(db, (char*)pSpan->zStart,
  1238         -                                     (int)(pSpan->zEnd - pSpan->zStart));
         1222  +      memset(&x, 0, sizeof(x));
         1223  +      x.op = TK_SPAN;
         1224  +      x.u.zToken = sqlite3DbStrNDup(db, (char*)pSpan->zStart,
         1225  +                                    (int)(pSpan->zEnd - pSpan->zStart));
         1226  +      x.pLeft = pSpan->pExpr;
         1227  +      x.flags = EP_Skip;
         1228  +      pCol->pDflt = sqlite3ExprDup(db, &x, EXPRDUP_REDUCE);
         1229  +      sqlite3DbFree(db, x.u.zToken);
  1239   1230       }
  1240   1231     }
  1241   1232     sqlite3ExprDelete(db, pSpan->pExpr);
  1242   1233   }
  1243   1234   
  1244   1235   /*
  1245   1236   ** Backwards Compatibility Hack:
................................................................................
  1287   1278     Parse *pParse,    /* Parsing context */
  1288   1279     ExprList *pList,  /* List of field names to be indexed */
  1289   1280     int onError,      /* What to do with a uniqueness conflict */
  1290   1281     int autoInc,      /* True if the AUTOINCREMENT keyword is present */
  1291   1282     int sortOrder     /* SQLITE_SO_ASC or SQLITE_SO_DESC */
  1292   1283   ){
  1293   1284     Table *pTab = pParse->pNewTable;
  1294         -  char *zType = 0;
         1285  +  const char *zName = 0;
  1295   1286     int iCol = -1, i;
  1296   1287     int nTerm;
  1297   1288     if( pTab==0 || IN_DECLARE_VTAB ) goto primary_key_exit;
  1298   1289     if( pTab->tabFlags & TF_HasPrimaryKey ){
  1299   1290       sqlite3ErrorMsg(pParse, 
  1300   1291         "table \"%s\" has more than one primary key", pTab->zName);
  1301   1292       goto primary_key_exit;
  1302   1293     }
  1303   1294     pTab->tabFlags |= TF_HasPrimaryKey;
  1304   1295     if( pList==0 ){
  1305   1296       iCol = pTab->nCol - 1;
  1306   1297       pTab->aCol[iCol].colFlags |= COLFLAG_PRIMKEY;
  1307         -    zType = pTab->aCol[iCol].zType;
         1298  +    zName = pTab->aCol[iCol].zName;
  1308   1299       nTerm = 1;
  1309   1300     }else{
  1310   1301       nTerm = pList->nExpr;
  1311   1302       for(i=0; i<nTerm; i++){
  1312   1303         Expr *pCExpr = sqlite3ExprSkipCollate(pList->a[i].pExpr);
  1313   1304         assert( pCExpr!=0 );
  1314   1305         sqlite3StringToId(pCExpr);
  1315   1306         if( pCExpr->op==TK_ID ){
  1316   1307           const char *zCName = pCExpr->u.zToken;
  1317   1308           for(iCol=0; iCol<pTab->nCol; iCol++){
  1318   1309             if( sqlite3StrICmp(zCName, pTab->aCol[iCol].zName)==0 ){
  1319   1310               pTab->aCol[iCol].colFlags |= COLFLAG_PRIMKEY;
  1320         -            zType = pTab->aCol[iCol].zType;
         1311  +            zName = pTab->aCol[iCol].zName;
  1321   1312               break;
  1322   1313             }
  1323   1314           }
  1324   1315         }
  1325   1316       }
  1326   1317     }
  1327   1318     if( nTerm==1
  1328         -   && zType && sqlite3StrICmp(zType, "INTEGER")==0
         1319  +   && zName
         1320  +   && sqlite3StrICmp(sqlite3StrNext(zName), "INTEGER")==0
  1329   1321      && sortOrder!=SQLITE_SO_DESC
  1330   1322     ){
  1331   1323       pTab->iPKey = iCol;
  1332   1324       pTab->keyConf = (u8)onError;
  1333   1325       assert( autoInc==0 || autoInc==1 );
  1334   1326       pTab->tabFlags |= autoInc*TF_Autoincrement;
  1335   1327       if( pList ) pParse->iPkSortOrder = pList->a[0].sortOrder;

Changes to src/expr.c.

  3066   3066         codeCompare(pParse, pLeft, pRight, OP_Le, r1, r2, r4, SQLITE_STOREP2);
  3067   3067         VdbeCoverage(v);
  3068   3068         sqlite3VdbeAddOp3(v, OP_And, r3, r4, target);
  3069   3069         sqlite3ReleaseTempReg(pParse, r3);
  3070   3070         sqlite3ReleaseTempReg(pParse, r4);
  3071   3071         break;
  3072   3072       }
         3073  +    case TK_SPAN:
  3073   3074       case TK_COLLATE: 
  3074   3075       case TK_UPLUS: {
  3075   3076         inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target);
  3076   3077         break;
  3077   3078       }
  3078   3079   
  3079   3080       case TK_TRIGGER: {

Changes to src/fkey.c.

  1158   1158   ){
  1159   1159     sqlite3 *db = pParse->db;       /* Database handle */
  1160   1160     int action;                     /* One of OE_None, OE_Cascade etc. */
  1161   1161     Trigger *pTrigger;              /* Trigger definition to return */
  1162   1162     int iAction = (pChanges!=0);    /* 1 for UPDATE, 0 for DELETE */
  1163   1163   
  1164   1164     action = pFKey->aAction[iAction];
         1165  +  if( action==OE_Restrict && (db->flags & SQLITE_DeferFKs) ){
         1166  +    return 0;
         1167  +  }
         1168  +
  1165   1169     pTrigger = pFKey->apTrigger[iAction];
  1166   1170     if( (db->flags & SQLITE_DeferFKs) && action==OE_Restrict ){
  1167   1171       return 0;
  1168   1172     }
  1169   1173   
  1170   1174     if( action!=OE_None && !pTrigger ){
  1171   1175       char const *zFrom;            /* Name of child table */

Changes to src/insert.c.

  2004   2004       if( sqlite3_stricmp(pDestCol->zColl, pSrcCol->zColl)!=0 ){
  2005   2005         return 0;    /* Collating sequence must be the same on all columns */
  2006   2006       }
  2007   2007       if( pDestCol->notNull && !pSrcCol->notNull ){
  2008   2008         return 0;    /* tab2 must be NOT NULL if tab1 is */
  2009   2009       }
  2010   2010       /* Default values for second and subsequent columns need to match. */
  2011         -    if( i>0
  2012         -     && ((pDestCol->zDflt==0)!=(pSrcCol->zDflt==0) 
  2013         -         || (pDestCol->zDflt && strcmp(pDestCol->zDflt, pSrcCol->zDflt)!=0))
  2014         -    ){
  2015         -      return 0;    /* Default values must be the same for all columns */
         2011  +    if( i>0 ){
         2012  +      assert( pDestCol->pDflt==0 || pDestCol->pDflt->op==TK_SPAN );
         2013  +      assert( pSrcCol->pDflt==0 || pSrcCol->pDflt->op==TK_SPAN );
         2014  +      if( (pDestCol->pDflt==0)!=(pSrcCol->pDflt==0) 
         2015  +       || (pDestCol->pDflt && strcmp(pDestCol->pDflt->u.zToken,
         2016  +                                       pSrcCol->pDflt->u.zToken)!=0)
         2017  +      ){
         2018  +        return 0;    /* Default values must be the same for all columns */
         2019  +      }
  2016   2020       }
  2017   2021     }
  2018   2022     for(pDestIdx=pDest->pIndex; pDestIdx; pDestIdx=pDestIdx->pNext){
  2019   2023       if( IsUniqueIndex(pDestIdx) ){
  2020   2024         destHasUniqueIdx = 1;
  2021   2025       }
  2022   2026       for(pSrcIdx=pSrc->pIndex; pSrcIdx; pSrcIdx=pSrcIdx->pNext){

Changes to src/journal.c.

    20     20   ** be used to service read() and write() requests. The actual file
    21     21   ** on disk is not created or populated until either:
    22     22   **
    23     23   **   1) The in-memory representation grows too large for the allocated 
    24     24   **      buffer, or
    25     25   **   2) The sqlite3JournalCreate() function is called.
    26     26   */
           27  +#if 0 
    27     28   #ifdef SQLITE_ENABLE_ATOMIC_WRITE
    28     29   #include "sqliteInt.h"
    29     30   
    30     31   
    31     32   /*
    32     33   ** A JournalFile object is a subclass of sqlite3_file used by
    33     34   ** as an open file handle for journal files.
................................................................................
   249    250   /* 
   250    251   ** Return the number of bytes required to store a JournalFile that uses vfs
   251    252   ** pVfs to create the underlying on-disk files.
   252    253   */
   253    254   int sqlite3JournalSize(sqlite3_vfs *pVfs){
   254    255     return (pVfs->szOsFile+sizeof(JournalFile));
   255    256   }
          257  +#endif
   256    258   #endif

Changes to src/main.c.

   792    792         break;
   793    793       }
   794    794       default: {
   795    795         static const struct {
   796    796           int op;      /* The opcode */
   797    797           u32 mask;    /* Mask of the bit in sqlite3.flags to set/clear */
   798    798         } aFlagOp[] = {
   799         -        { SQLITE_DBCONFIG_ENABLE_FKEY,    SQLITE_ForeignKeys    },
   800         -        { SQLITE_DBCONFIG_ENABLE_TRIGGER, SQLITE_EnableTrigger  },
          799  +        { SQLITE_DBCONFIG_ENABLE_FKEY,           SQLITE_ForeignKeys    },
          800  +        { SQLITE_DBCONFIG_ENABLE_TRIGGER,        SQLITE_EnableTrigger  },
          801  +        { SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER, SQLITE_Fts3Tokenizer  },
   801    802         };
   802    803         unsigned int i;
   803    804         rc = SQLITE_ERROR; /* IMP: R-42790-23372 */
   804    805         for(i=0; i<ArraySize(aFlagOp); i++){
   805    806           if( aFlagOp[i].op==op ){
   806    807             int onoff = va_arg(ap, int);
   807    808             int *pRes = va_arg(ap, int*);
................................................................................
  2829   2830   #endif
  2830   2831   #if defined(SQLITE_REVERSE_UNORDERED_SELECTS)
  2831   2832                    | SQLITE_ReverseOrder
  2832   2833   #endif
  2833   2834   #if defined(SQLITE_ENABLE_OVERSIZE_CELL_CHECK)
  2834   2835                    | SQLITE_CellSizeCk
  2835   2836   #endif
         2837  +#if defined(SQLITE_ENABLE_FTS3_TOKENIZER)
         2838  +                 | SQLITE_Fts3Tokenizer
         2839  +#endif
  2836   2840         ;
  2837   2841     sqlite3HashInit(&db->aCollSeq);
  2838   2842   #ifndef SQLITE_OMIT_VIRTUALTABLE
  2839   2843     sqlite3HashInit(&db->aModule);
  2840   2844   #endif
  2841   2845   
  2842   2846     /* Add the default collation sequence BINARY. BINARY works for both UTF-8
................................................................................
  3348   3352     **     1. The specified column name was rowid", "oid" or "_rowid_" 
  3349   3353     **        and there is no explicitly declared IPK column. 
  3350   3354     **
  3351   3355     **     2. The table is not a view and the column name identified an 
  3352   3356     **        explicitly declared column. Copy meta information from *pCol.
  3353   3357     */ 
  3354   3358     if( pCol ){
  3355         -    zDataType = pCol->zType;
         3359  +    zDataType = sqlite3StrNext(pCol->zName);
         3360  +    if( zDataType[0]==0 ) zDataType = 0;
  3356   3361       zCollSeq = pCol->zColl;
  3357   3362       notnull = pCol->notNull!=0;
  3358   3363       primarykey  = (pCol->colFlags & COLFLAG_PRIMKEY)!=0;
  3359   3364       autoinc = pTab->iPKey==iCol && (pTab->tabFlags & TF_Autoincrement)!=0;
  3360   3365     }else{
  3361   3366       zDataType = "INTEGER";
  3362   3367       primarykey = 1;

Changes to src/memjournal.c.

    17     17   #include "sqliteInt.h"
    18     18   
    19     19   /* Forward references to internal structures */
    20     20   typedef struct MemJournal MemJournal;
    21     21   typedef struct FilePoint FilePoint;
    22     22   typedef struct FileChunk FileChunk;
    23     23   
    24         -/* Space to hold the rollback journal is allocated in increments of
    25         -** this many bytes.
    26         -**
    27         -** The size chosen is a little less than a power of two.  That way,
    28         -** the FileChunk object will have a size that almost exactly fills
    29         -** a power-of-two allocation.  This minimizes wasted space in power-of-two
    30         -** memory allocators.
    31         -*/
    32         -#define JOURNAL_CHUNKSIZE ((int)(1024-sizeof(FileChunk*)))
    33         -
    34     24   /*
    35     25   ** The rollback journal is composed of a linked list of these structures.
           26  +**
           27  +** The zChunk array is always at least 8 bytes in size - usually much more.
           28  +** Its actual size is stored in the MemJournal.nChunkSize variable.
    36     29   */
    37     30   struct FileChunk {
    38     31     FileChunk *pNext;               /* Next chunk in the journal */
    39         -  u8 zChunk[JOURNAL_CHUNKSIZE];   /* Content of this chunk */
           32  +  u8 zChunk[8];                   /* Content of this chunk */
    40     33   };
    41     34   
           35  +/*
           36  +** By default, allocate this many bytes of memory for each FileChunk object.
           37  +*/
           38  +#define MEMJOURNAL_DFLT_FILECHUNKSIZE 1024
           39  +
           40  +/*
           41  +** For chunk size nChunkSize, return the number of bytes that should
           42  +** be allocated for each FileChunk structure.
           43  +*/
           44  +#define fileChunkSize(nChunkSize) (sizeof(FileChunk) + ((nChunkSize)-8))
           45  +
    42     46   /*
    43     47   ** An instance of this object serves as a cursor into the rollback journal.
    44     48   ** The cursor can be either for reading or writing.
    45     49   */
    46     50   struct FilePoint {
    47     51     sqlite3_int64 iOffset;          /* Offset from the beginning of the file */
    48     52     FileChunk *pChunk;              /* Specific chunk into which cursor points */
    49     53   };
    50     54   
    51     55   /*
    52         -** This subclass is a subclass of sqlite3_file.  Each open memory-journal
           56  +** This structure is a subclass of sqlite3_file. Each open memory-journal
    53     57   ** is an instance of this class.
    54     58   */
    55     59   struct MemJournal {
    56         -  sqlite3_io_methods *pMethod;    /* Parent class. MUST BE FIRST */
           60  +  const sqlite3_io_methods *pMethod; /* Parent class. MUST BE FIRST */
           61  +  int nChunkSize;                 /* In-memory chunk-size */
           62  +
           63  +  int nBuf;                       /* Bytes of data before flushing */
           64  +  int nSize;                      /* Bytes of data currently in memory */
    57     65     FileChunk *pFirst;              /* Head of in-memory chunk-list */
    58     66     FilePoint endpoint;             /* Pointer to the end of the file */
    59     67     FilePoint readpoint;            /* Pointer to the end of the last xRead() */
           68  +
           69  +  int flags;                      /* xOpen flags */
           70  +  sqlite3_vfs *pVfs;              /* The "real" underlying VFS */
           71  +  const char *zJournal;           /* Name of the journal file */
           72  +  sqlite3_file *pReal;            /* The "real" underlying file descriptor */
    60     73   };
    61     74   
    62     75   /*
    63     76   ** Read data from the in-memory journal file.  This is the implementation
    64     77   ** of the sqlite3_vfs.xRead method.
    65     78   */
    66     79   static int memjrnlRead(
    67     80     sqlite3_file *pJfd,    /* The journal file from which to read */
    68     81     void *zBuf,            /* Put the results here */
    69     82     int iAmt,              /* Number of bytes to read */
    70     83     sqlite_int64 iOfst     /* Begin reading at this offset */
    71     84   ){
    72     85     MemJournal *p = (MemJournal *)pJfd;
    73         -  u8 *zOut = zBuf;
    74         -  int nRead = iAmt;
    75         -  int iChunkOffset;
    76         -  FileChunk *pChunk;
           86  +  if( p->pReal ){
           87  +    return sqlite3OsRead(p->pReal, zBuf, iAmt, iOfst);
           88  +  }else if( (iAmt+iOfst)>p->endpoint.iOffset ){
           89  +    return SQLITE_IOERR_SHORT_READ;
           90  +  }else{
           91  +    u8 *zOut = zBuf;
           92  +    int nRead = iAmt;
           93  +    int iChunkOffset;
           94  +    FileChunk *pChunk;
    77     95   
    78         -  /* SQLite never tries to read past the end of a rollback journal file */
    79         -  assert( iOfst+iAmt<=p->endpoint.iOffset );
    80         -
    81         -  if( p->readpoint.iOffset!=iOfst || iOfst==0 ){
    82         -    sqlite3_int64 iOff = 0;
    83         -    for(pChunk=p->pFirst; 
    84         -        ALWAYS(pChunk) && (iOff+JOURNAL_CHUNKSIZE)<=iOfst;
    85         -        pChunk=pChunk->pNext
    86         -    ){
    87         -      iOff += JOURNAL_CHUNKSIZE;
           96  +    if( p->readpoint.iOffset!=iOfst || iOfst==0 ){
           97  +      sqlite3_int64 iOff = 0;
           98  +      for(pChunk=p->pFirst; 
           99  +          ALWAYS(pChunk) && (iOff+p->nChunkSize)<=iOfst;
          100  +          pChunk=pChunk->pNext
          101  +      ){
          102  +        iOff += p->nChunkSize;
          103  +      }
          104  +    }else{
          105  +      pChunk = p->readpoint.pChunk;
    88    106       }
    89         -  }else{
    90         -    pChunk = p->readpoint.pChunk;
          107  +
          108  +    iChunkOffset = (int)(iOfst%p->nChunkSize);
          109  +    do {
          110  +      int iSpace = p->nChunkSize - iChunkOffset;
          111  +      int nCopy = MIN(nRead, (p->nChunkSize - iChunkOffset));
          112  +      memcpy(zOut, &pChunk->zChunk[iChunkOffset], nCopy);
          113  +      zOut += nCopy;
          114  +      nRead -= iSpace;
          115  +      iChunkOffset = 0;
          116  +    } while( nRead>=0 && (pChunk=pChunk->pNext)!=0 && nRead>0 );
          117  +    p->readpoint.iOffset = iOfst+iAmt;
          118  +    p->readpoint.pChunk = pChunk;
    91    119     }
    92    120   
    93         -  iChunkOffset = (int)(iOfst%JOURNAL_CHUNKSIZE);
    94         -  do {
    95         -    int iSpace = JOURNAL_CHUNKSIZE - iChunkOffset;
    96         -    int nCopy = MIN(nRead, (JOURNAL_CHUNKSIZE - iChunkOffset));
    97         -    memcpy(zOut, &pChunk->zChunk[iChunkOffset], nCopy);
    98         -    zOut += nCopy;
    99         -    nRead -= iSpace;
   100         -    iChunkOffset = 0;
   101         -  } while( nRead>=0 && (pChunk=pChunk->pNext)!=0 && nRead>0 );
   102         -  p->readpoint.iOffset = iOfst+iAmt;
   103         -  p->readpoint.pChunk = pChunk;
   104         -
   105    121     return SQLITE_OK;
   106    122   }
          123  +
          124  +/*
          125  +** Free the list of FileChunk structures headed at MemJournal.pFirst.
          126  +*/
          127  +static void memjrnlFreeChunks(MemJournal *p){
          128  +  FileChunk *pIter;
          129  +  FileChunk *pNext;
          130  +  for(pIter=p->pFirst; pIter; pIter=pNext){
          131  +    pNext = pIter->pNext;
          132  +    sqlite3_free(pIter);
          133  +  } 
          134  +  p->pFirst = 0;
          135  +}
          136  +
          137  +/*
          138  +** Flush the contents of memory to a real file on disk.
          139  +*/
          140  +static int createFile(MemJournal *p){
          141  +  int rc = SQLITE_OK;
          142  +  if( !p->pReal ){
          143  +    sqlite3_file *pReal = (sqlite3_file *)&p[1];
          144  +    rc = sqlite3OsOpen(p->pVfs, p->zJournal, pReal, p->flags, 0);
          145  +    if( rc==SQLITE_OK ){
          146  +      int nChunk = p->nChunkSize;
          147  +      i64 iOff = 0;
          148  +      FileChunk *pIter;
          149  +      p->pReal = pReal;
          150  +      for(pIter=p->pFirst; pIter && rc==SQLITE_OK; pIter=pIter->pNext){
          151  +        int nWrite = nChunk;
          152  +        if( pIter==p->endpoint.pChunk ){
          153  +          nWrite = p->endpoint.iOffset % p->nChunkSize;
          154  +          if( nWrite==0 ) nWrite = p->nChunkSize;
          155  +        }
          156  +        rc = sqlite3OsWrite(pReal, pIter->zChunk, nWrite, iOff);
          157  +        iOff += nWrite;
          158  +      }
          159  +      if( rc!=SQLITE_OK ){
          160  +        /* If an error occurred while writing to the file, close it before
          161  +        ** returning. This way, SQLite uses the in-memory journal data to 
          162  +        ** roll back changes made to the internal page-cache before this
          163  +        ** function was called.  */
          164  +        sqlite3OsClose(pReal);
          165  +        p->pReal = 0;
          166  +      }else{
          167  +        /* No error has occurred. Free the in-memory buffers. */
          168  +        memjrnlFreeChunks(p);
          169  +      }
          170  +    }
          171  +  }
          172  +  return rc;
          173  +}
          174  +
   107    175   
   108    176   /*
   109    177   ** Write data to the file.
   110    178   */
   111    179   static int memjrnlWrite(
   112    180     sqlite3_file *pJfd,    /* The journal file into which to write */
   113    181     const void *zBuf,      /* Take data to be written from here */
................................................................................
   114    182     int iAmt,              /* Number of bytes to write */
   115    183     sqlite_int64 iOfst     /* Begin writing at this offset into the file */
   116    184   ){
   117    185     MemJournal *p = (MemJournal *)pJfd;
   118    186     int nWrite = iAmt;
   119    187     u8 *zWrite = (u8 *)zBuf;
   120    188   
   121         -  /* An in-memory journal file should only ever be appended to. Random
   122         -  ** access writes are not required by sqlite.
   123         -  */
   124         -  assert( iOfst==p->endpoint.iOffset );
   125         -  UNUSED_PARAMETER(iOfst);
          189  +  /* If the file has already been created on disk. */
          190  +  if( p->pReal ){
          191  +    return sqlite3OsWrite(p->pReal, zBuf, iAmt, iOfst);
          192  +  }
   126    193   
   127         -  while( nWrite>0 ){
   128         -    FileChunk *pChunk = p->endpoint.pChunk;
   129         -    int iChunkOffset = (int)(p->endpoint.iOffset%JOURNAL_CHUNKSIZE);
   130         -    int iSpace = MIN(nWrite, JOURNAL_CHUNKSIZE - iChunkOffset);
   131         -
   132         -    if( iChunkOffset==0 ){
   133         -      /* New chunk is required to extend the file. */
   134         -      FileChunk *pNew = sqlite3_malloc(sizeof(FileChunk));
   135         -      if( !pNew ){
   136         -        return SQLITE_IOERR_NOMEM_BKPT;
   137         -      }
   138         -      pNew->pNext = 0;
   139         -      if( pChunk ){
   140         -        assert( p->pFirst );
   141         -        pChunk->pNext = pNew;
   142         -      }else{
   143         -        assert( !p->pFirst );
   144         -        p->pFirst = pNew;
   145         -      }
   146         -      p->endpoint.pChunk = pNew;
          194  +  /* If the file should be created now. */
          195  +  else if( p->nBuf>0 && (iAmt+iOfst)>p->nBuf ){
          196  +    int rc = createFile(p);
          197  +    if( rc==SQLITE_OK ){
          198  +      rc = memjrnlWrite(pJfd, zBuf, iAmt, iOfst);
   147    199       }
          200  +    return rc;
          201  +  }
   148    202   
   149         -    memcpy(&p->endpoint.pChunk->zChunk[iChunkOffset], zWrite, iSpace);
   150         -    zWrite += iSpace;
   151         -    nWrite -= iSpace;
   152         -    p->endpoint.iOffset += iSpace;
          203  +  /* If the contents of this write should be stored in memory */
          204  +  else{
          205  +    /* An in-memory journal file should only ever be appended to. Random
          206  +    ** access writes are not required. The only exception to this is when
          207  +    ** the in-memory journal is being used by a connection using the
          208  +    ** atomic-write optimization. In this case the first 28 bytes of the
          209  +    ** journal file may be written as part of committing the transaction. */ 
          210  +    assert( iOfst==p->endpoint.iOffset || iOfst==0 );
          211  +    if( iOfst==0 && p->pFirst ){
          212  +      assert( p->nChunkSize>iAmt );
          213  +      memcpy(p->pFirst->zChunk, zBuf, iAmt);
          214  +    }else{
          215  +      while( nWrite>0 ){
          216  +        FileChunk *pChunk = p->endpoint.pChunk;
          217  +        int iChunkOffset = (int)(p->endpoint.iOffset%p->nChunkSize);
          218  +        int iSpace = MIN(nWrite, p->nChunkSize - iChunkOffset);
          219  +
          220  +        if( iChunkOffset==0 ){
          221  +          /* New chunk is required to extend the file. */
          222  +          FileChunk *pNew = sqlite3_malloc(fileChunkSize(p->nChunkSize));
          223  +          if( !pNew ){
          224  +            return SQLITE_IOERR_NOMEM_BKPT;
          225  +          }
          226  +          pNew->pNext = 0;
          227  +          if( pChunk ){
          228  +            assert( p->pFirst );
          229  +            pChunk->pNext = pNew;
          230  +          }else{
          231  +            assert( !p->pFirst );
          232  +            p->pFirst = pNew;
          233  +          }
          234  +          p->endpoint.pChunk = pNew;
          235  +        }
          236  +
          237  +        memcpy(&p->endpoint.pChunk->zChunk[iChunkOffset], zWrite, iSpace);
          238  +        zWrite += iSpace;
          239  +        nWrite -= iSpace;
          240  +        p->endpoint.iOffset += iSpace;
          241  +      }
          242  +      p->nSize = iAmt + iOfst;
          243  +    }
   153    244     }
   154    245   
   155    246     return SQLITE_OK;
   156    247   }
   157    248   
   158    249   /*
   159    250   ** Truncate the file.
          251  +**
          252  +** If the journal file is already on disk, truncate it there. Or, if it
          253  +** is still in main memory but is being truncated to zero bytes in size,
          254  +** ignore 
   160    255   */
   161    256   static int memjrnlTruncate(sqlite3_file *pJfd, sqlite_int64 size){
   162    257     MemJournal *p = (MemJournal *)pJfd;
   163         -  FileChunk *pChunk;
   164         -  assert(size==0);
   165         -  UNUSED_PARAMETER(size);
   166         -  pChunk = p->pFirst;
   167         -  while( pChunk ){
   168         -    FileChunk *pTmp = pChunk;
   169         -    pChunk = pChunk->pNext;
   170         -    sqlite3_free(pTmp);
          258  +  if( p->pReal ){
          259  +    return sqlite3OsTruncate(p->pReal, size);
          260  +  }else if( size==0 ){
          261  +    memjrnlFreeChunks(p);
          262  +    p->nSize = 0;
          263  +    p->endpoint.pChunk = 0;
          264  +    p->endpoint.iOffset = 0;
          265  +    p->readpoint.pChunk = 0;
          266  +    p->readpoint.iOffset = 0;
   171    267     }
   172         -  sqlite3MemJournalOpen(pJfd);
   173    268     return SQLITE_OK;
   174    269   }
   175    270   
   176    271   /*
   177    272   ** Close the file.
   178    273   */
   179    274   static int memjrnlClose(sqlite3_file *pJfd){
   180         -  memjrnlTruncate(pJfd, 0);
          275  +  MemJournal *p = (MemJournal *)pJfd;
          276  +  memjrnlFreeChunks(p);
          277  +  if( p->pReal ) sqlite3OsClose(p->pReal);
   181    278     return SQLITE_OK;
   182    279   }
   183         -
   184    280   
   185    281   /*
   186    282   ** Sync the file.
   187    283   **
   188         -** Syncing an in-memory journal is a no-op.  And, in fact, this routine
   189         -** is never called in a working implementation.  This implementation
   190         -** exists purely as a contingency, in case some malfunction in some other
   191         -** part of SQLite causes Sync to be called by mistake.
          284  +** If the real file has been created, call its xSync method. Otherwise, 
          285  +** syncing an in-memory journal is a no-op. 
   192    286   */
   193         -static int memjrnlSync(sqlite3_file *NotUsed, int NotUsed2){
   194         -  UNUSED_PARAMETER2(NotUsed, NotUsed2);
          287  +static int memjrnlSync(sqlite3_file *pJfd, int flags){
          288  +  MemJournal *p = (MemJournal *)pJfd;
          289  +  if( p->pReal ){
          290  +    return sqlite3OsSync(p->pReal, flags);
          291  +  }
   195    292     return SQLITE_OK;
   196    293   }
   197    294   
   198    295   /*
   199    296   ** Query the size of the file in bytes.
   200    297   */
   201    298   static int memjrnlFileSize(sqlite3_file *pJfd, sqlite_int64 *pSize){
   202    299     MemJournal *p = (MemJournal *)pJfd;
          300  +  if( p->pReal ){
          301  +    return sqlite3OsFileSize(p->pReal, pSize);
          302  +  }
   203    303     *pSize = (sqlite_int64) p->endpoint.iOffset;
   204    304     return SQLITE_OK;
   205    305   }
   206    306   
   207    307   /*
   208    308   ** Table of methods for MemJournal sqlite3_file object.
   209    309   */
................................................................................
   226    326     0,                /* xShmBarrier */
   227    327     0,                /* xShmUnmap */
   228    328     0,                /* xFetch */
   229    329     0                 /* xUnfetch */
   230    330   };
   231    331   
   232    332   /* 
   233         -** Open a journal file.
          333  +** Open a journal file. 
          334  +**
          335  +** The behaviour of the journal file depends on the value of parameter 
          336  +** nBuf. If nBuf is 0, then the journal file is always create and 
          337  +** accessed using the underlying VFS. If nBuf is less than zero, then
          338  +** all content is always stored in main-memory. Finally, if nBuf is a
          339  +** positive value, then the journal file is initially created in-memory
          340  +** but may be flushed to disk later on. In this case the journal file is
          341  +** flushed to disk either when it grows larger than nBuf bytes in size,
          342  +** or when sqlite3JournalCreate() is called.
          343  +*/
          344  +int sqlite3JournalOpen(
          345  +  sqlite3_vfs *pVfs,         /* The VFS to use for actual file I/O */
          346  +  const char *zName,         /* Name of the journal file */
          347  +  sqlite3_file *pJfd,        /* Preallocated, blank file handle */
          348  +  int flags,                 /* Opening flags */
          349  +  int nBuf                   /* Bytes buffered before opening the file */
          350  +){
          351  +  MemJournal *p = (MemJournal*)pJfd;
          352  +
          353  +  /* Zero the file-handle object. If nBuf was passed zero, initialize
          354  +  ** it using the sqlite3OsOpen() function of the underlying VFS. In this
          355  +  ** case none of the code in this module is executed as a result of calls
          356  +  ** made on the journal file-handle.  */
          357  +  memset(p, 0, sizeof(MemJournal) + (pVfs ? pVfs->szOsFile : 0));
          358  +  if( nBuf==0 ){
          359  +    return sqlite3OsOpen(pVfs, zName, pJfd, flags, 0);
          360  +  }
          361  +
          362  +  if( nBuf>0 ){
          363  +    p->nChunkSize = nBuf;
          364  +  }else{
          365  +    p->nChunkSize = 8 + MEMJOURNAL_DFLT_FILECHUNKSIZE - sizeof(FileChunk);
          366  +    assert( MEMJOURNAL_DFLT_FILECHUNKSIZE==fileChunkSize(p->nChunkSize) );
          367  +  }
          368  +
          369  +  p->pMethod = (const sqlite3_io_methods*)&MemJournalMethods;
          370  +  p->nBuf = nBuf;
          371  +  p->flags = flags;
          372  +  p->zJournal = zName;
          373  +  p->pVfs = pVfs;
          374  +  return SQLITE_OK;
          375  +}
          376  +
          377  +/*
          378  +** Open an in-memory journal file.
   234    379   */
   235    380   void sqlite3MemJournalOpen(sqlite3_file *pJfd){
   236         -  MemJournal *p = (MemJournal *)pJfd;
   237         -  assert( EIGHT_BYTE_ALIGNMENT(p) );
   238         -  memset(p, 0, sqlite3MemJournalSize());
   239         -  p->pMethod = (sqlite3_io_methods*)&MemJournalMethods;
          381  +  sqlite3JournalOpen(0, 0, pJfd, 0, -1);
          382  +}
          383  +
          384  +#ifdef SQLITE_ENABLE_ATOMIC_WRITE
          385  +/*
          386  +** If the argument p points to a MemJournal structure that is not an 
          387  +** in-memory-only journal file (i.e. is one that was opened with a +ve
          388  +** nBuf parameter), and the underlying file has not yet been created, 
          389  +** create it now.
          390  +*/
          391  +int sqlite3JournalCreate(sqlite3_file *p){
          392  +  int rc = SQLITE_OK;
          393  +  if( p->pMethods==&MemJournalMethods && ((MemJournal*)p)->nBuf>0 ){
          394  +    rc = createFile((MemJournal*)p);
          395  +  }
          396  +  return rc;
   240    397   }
          398  +#endif
   241    399   
   242    400   /*
   243         -** Return true if the file-handle passed as an argument is 
   244         -** an in-memory journal 
          401  +** The file-handle passed as the only argument is open on a journal file.
          402  +** Return true if this "journal file" is currently stored in heap memory,
          403  +** or false otherwise.
   245    404   */
   246         -int sqlite3IsMemJournal(sqlite3_file *pJfd){
   247         -  return pJfd->pMethods==&MemJournalMethods;
          405  +int sqlite3JournalIsInMemory(sqlite3_file *p){
          406  +  return p->pMethods==&MemJournalMethods && ((MemJournal*)p)->pReal==0;
   248    407   }
   249    408   
   250    409   /* 
   251         -** Return the number of bytes required to store a MemJournal file descriptor.
          410  +** Return the number of bytes required to store a JournalFile that uses vfs
          411  +** pVfs to create the underlying on-disk files.
   252    412   */
   253         -int sqlite3MemJournalSize(void){
   254         -  return sizeof(MemJournal);
          413  +int sqlite3JournalSize(sqlite3_vfs *pVfs){
          414  +  return pVfs->szOsFile + sizeof(MemJournal);
   255    415   }

Changes to src/os.c.

    62     62   **     sqlite3OsAccess()
    63     63   **     sqlite3OsFullPathname()
    64     64   **
    65     65   */
    66     66   #if defined(SQLITE_TEST)
    67     67   int sqlite3_memdebug_vfs_oom_test = 1;
    68     68     #define DO_OS_MALLOC_TEST(x)                                       \
    69         -  if (sqlite3_memdebug_vfs_oom_test && (!x || !sqlite3IsMemJournal(x))) {  \
           69  +  if (sqlite3_memdebug_vfs_oom_test && (!x || !sqlite3JournalIsInMemory(x))) { \
    70     70       void *pTstAlloc = sqlite3Malloc(10);                             \
    71     71       if (!pTstAlloc) return SQLITE_IOERR_NOMEM_BKPT;                  \
    72     72       sqlite3_free(pTstAlloc);                                         \
    73     73     }
    74     74   #else
    75     75     #define DO_OS_MALLOC_TEST(x)
    76     76   #endif

Changes to src/os_unix.c.

    66     66   #if !defined(SQLITE_ENABLE_LOCKING_STYLE)
    67     67   #  if defined(__APPLE__)
    68     68   #    define SQLITE_ENABLE_LOCKING_STYLE 1
    69     69   #  else
    70     70   #    define SQLITE_ENABLE_LOCKING_STYLE 0
    71     71   #  endif
    72     72   #endif
           73  +
           74  +/* Use pread() and pwrite() if they are available */
           75  +#if defined(__APPLE__)
           76  +# define HAVE_PREAD 1
           77  +# define HAVE_PWRITE 1
           78  +#endif
           79  +#if defined(HAVE_PREAD64) && defined(HAVE_PWRITE64)
           80  +# undef USE_PREAD
           81  +# define USE_PREAD64 1
           82  +#elif defined(HAVE_PREAD) && defined(HAVE_PWRITE)
           83  +# undef USE_PREAD64
           84  +# define USE_PREAD 1
           85  +#endif
    73     86   
    74     87   /*
    75     88   ** standard include files.
    76     89   */
    77     90   #include <sys/types.h>
    78     91   #include <sys/stat.h>
    79     92   #include <fcntl.h>

Changes to src/pager.c.

  1339   1339   **
  1340   1340   ** If an IO error occurs, abandon processing and return the IO error code.
  1341   1341   ** Otherwise, return SQLITE_OK.
  1342   1342   */
  1343   1343   static int zeroJournalHdr(Pager *pPager, int doTruncate){
  1344   1344     int rc = SQLITE_OK;                               /* Return code */
  1345   1345     assert( isOpen(pPager->jfd) );
         1346  +  assert( !sqlite3JournalIsInMemory(pPager->jfd) );
  1346   1347     if( pPager->journalOff ){
  1347   1348       const i64 iLimit = pPager->journalSizeLimit;    /* Local cache of jsl */
  1348   1349   
  1349   1350       IOTRACE(("JZEROHDR %p\n", pPager))
  1350   1351       if( doTruncate || iLimit==0 ){
  1351   1352         rc = sqlite3OsTruncate(pPager->jfd, 0);
  1352   1353       }else{
................................................................................
  1720   1721   ** if it is open and the pager is not in exclusive mode.
  1721   1722   */
  1722   1723   static void releaseAllSavepoints(Pager *pPager){
  1723   1724     int ii;               /* Iterator for looping through Pager.aSavepoint */
  1724   1725     for(ii=0; ii<pPager->nSavepoint; ii++){
  1725   1726       sqlite3BitvecDestroy(pPager->aSavepoint[ii].pInSavepoint);
  1726   1727     }
  1727         -  if( !pPager->exclusiveMode || sqlite3IsMemJournal(pPager->sjfd) ){
         1728  +  if( !pPager->exclusiveMode || sqlite3JournalIsInMemory(pPager->sjfd) ){
  1728   1729       sqlite3OsClose(pPager->sjfd);
  1729   1730     }
  1730   1731     sqlite3_free(pPager->aSavepoint);
  1731   1732     pPager->aSavepoint = 0;
  1732   1733     pPager->nSavepoint = 0;
  1733   1734     pPager->nSubRec = 0;
  1734   1735   }
................................................................................
  1958   1959   
  1959   1960     releaseAllSavepoints(pPager);
  1960   1961     assert( isOpen(pPager->jfd) || pPager->pInJournal==0 );
  1961   1962     if( isOpen(pPager->jfd) ){
  1962   1963       assert( !pagerUseWal(pPager) );
  1963   1964   
  1964   1965       /* Finalize the journal file. */
  1965         -    if( sqlite3IsMemJournal(pPager->jfd) ){
  1966         -      assert( pPager->journalMode==PAGER_JOURNALMODE_MEMORY );
         1966  +    if( sqlite3JournalIsInMemory(pPager->jfd) ){
         1967  +      /* assert( pPager->journalMode==PAGER_JOURNALMODE_MEMORY ); */
  1967   1968         sqlite3OsClose(pPager->jfd);
  1968   1969       }else if( pPager->journalMode==PAGER_JOURNALMODE_TRUNCATE ){
  1969   1970         if( pPager->journalOff==0 ){
  1970   1971           rc = SQLITE_OK;
  1971   1972         }else{
  1972   1973           rc = sqlite3OsTruncate(pPager->jfd, 0);
  1973   1974           if( rc==SQLITE_OK && pPager->fullSync ){
................................................................................
  1985   1986       ){
  1986   1987         rc = zeroJournalHdr(pPager, hasMaster);
  1987   1988         pPager->journalOff = 0;
  1988   1989       }else{
  1989   1990         /* This branch may be executed with Pager.journalMode==MEMORY if
  1990   1991         ** a hot-journal was just rolled back. In this case the journal
  1991   1992         ** file should be closed and deleted. If this connection writes to
  1992         -      ** the database file, it will do so using an in-memory journal. 
         1993  +      ** the database file, it will do so using an in-memory journal.
  1993   1994         */
  1994         -      int bDelete = (!pPager->tempFile && sqlite3JournalExists(pPager->jfd));
         1995  +      int bDelete = !pPager->tempFile;
         1996  +      assert( sqlite3JournalIsInMemory(pPager->jfd)==0 );
  1995   1997         assert( pPager->journalMode==PAGER_JOURNALMODE_DELETE 
  1996   1998              || pPager->journalMode==PAGER_JOURNALMODE_MEMORY 
  1997   1999              || pPager->journalMode==PAGER_JOURNALMODE_WAL 
  1998   2000         );
  1999   2001         sqlite3OsClose(pPager->jfd);
  2000   2002         if( bDelete ){
  2001   2003           rc = sqlite3OsDelete(pPager->pVfs, pPager->zJournal, pPager->extraSync);
................................................................................
  2725   2727     ** If a master journal file name is specified, but the file is not
  2726   2728     ** present on disk, then the journal is not hot and does not need to be
  2727   2729     ** played back.
  2728   2730     **
  2729   2731     ** TODO: Technically the following is an error because it assumes that
  2730   2732     ** buffer Pager.pTmpSpace is (mxPathname+1) bytes or larger. i.e. that
  2731   2733     ** (pPager->pageSize >= pPager->pVfs->mxPathname+1). Using os_unix.c,
  2732         -  **  mxPathname is 512, which is the same as the minimum allowable value
         2734  +  ** mxPathname is 512, which is the same as the minimum allowable value
  2733   2735     ** for pageSize.
  2734   2736     */
  2735   2737     zMaster = pPager->pTmpSpace;
  2736   2738     rc = readMasterJournal(pPager->jfd, zMaster, pPager->pVfs->mxPathname+1);
  2737   2739     if( rc==SQLITE_OK && zMaster[0] ){
  2738   2740       rc = sqlite3OsAccess(pVfs, zMaster, SQLITE_ACCESS_EXISTS, &res);
  2739   2741     }
................................................................................
  4349   4351   ** SQLITE_OK is returned if everything goes according to plan. An 
  4350   4352   ** SQLITE_IOERR_XXX error code is returned if a call to sqlite3OsOpen() 
  4351   4353   ** fails.
  4352   4354   */
  4353   4355   static int openSubJournal(Pager *pPager){
  4354   4356     int rc = SQLITE_OK;
  4355   4357     if( !isOpen(pPager->sjfd) ){
         4358  +    const int flags =  SQLITE_OPEN_SUBJOURNAL | SQLITE_OPEN_READWRITE 
         4359  +      | SQLITE_OPEN_CREATE | SQLITE_OPEN_EXCLUSIVE 
         4360  +      | SQLITE_OPEN_DELETEONCLOSE;
         4361  +    int nBuf = 64*1024;
  4356   4362       if( pPager->journalMode==PAGER_JOURNALMODE_MEMORY || pPager->subjInMemory ){
  4357         -      sqlite3MemJournalOpen(pPager->sjfd);
  4358         -    }else{
  4359         -      rc = pagerOpentemp(pPager, pPager->sjfd, SQLITE_OPEN_SUBJOURNAL);
         4363  +      nBuf = -1;
  4360   4364       }
         4365  +    rc = sqlite3JournalOpen(pPager->pVfs, 0, pPager->sjfd, flags, nBuf);
  4361   4366     }
  4362   4367     return rc;
  4363   4368   }
  4364   4369   
  4365   4370   /*
  4366   4371   ** Append a record of the current state of page pPg to the sub-journal. 
  4367   4372   **
................................................................................
  4574   4579     int useJournal = (flags & PAGER_OMIT_JOURNAL)==0; /* False to omit journal */
  4575   4580     int pcacheSize = sqlite3PcacheSize();       /* Bytes to allocate for PCache */
  4576   4581     u32 szPageDflt = SQLITE_DEFAULT_PAGE_SIZE;  /* Default page size */
  4577   4582     const char *zUri = 0;    /* URI args to copy */
  4578   4583     int nUri = 0;            /* Number of bytes of URI args at *zUri */
  4579   4584   
  4580   4585     /* Figure out how much space is required for each journal file-handle
  4581         -  ** (there are two of them, the main journal and the sub-journal). This
  4582         -  ** is the maximum space required for an in-memory journal file handle 
  4583         -  ** and a regular journal file-handle. Note that a "regular journal-handle"
  4584         -  ** may be a wrapper capable of caching the first portion of the journal
  4585         -  ** file in memory to implement the atomic-write optimization (see 
  4586         -  ** source file journal.c).
  4587         -  */
  4588         -  if( sqlite3JournalSize(pVfs)>sqlite3MemJournalSize() ){
  4589         -    journalFileSize = ROUND8(sqlite3JournalSize(pVfs));
  4590         -  }else{
  4591         -    journalFileSize = ROUND8(sqlite3MemJournalSize());
  4592         -  }
         4586  +  ** (there are two of them, the main journal and the sub-journal).  */
         4587  +  journalFileSize = ROUND8(sqlite3JournalSize(pVfs));
  4593   4588   
  4594   4589     /* Set the output variable to NULL in case an error occurs. */
  4595   4590     *ppPager = 0;
  4596   4591   
  4597   4592   #ifndef SQLITE_OMIT_MEMORYDB
  4598   4593     if( flags & PAGER_MEMORY ){
  4599   4594       memDb = 1;
................................................................................
  6663   6658       pPager->nSavepoint = nNew;
  6664   6659   
  6665   6660       /* If this is a release of the outermost savepoint, truncate 
  6666   6661       ** the sub-journal to zero bytes in size. */
  6667   6662       if( op==SAVEPOINT_RELEASE ){
  6668   6663         if( nNew==0 && isOpen(pPager->sjfd) ){
  6669   6664           /* Only truncate if it is an in-memory sub-journal. */
  6670         -        if( sqlite3IsMemJournal(pPager->sjfd) ){
         6665  +        if( sqlite3JournalIsInMemory(pPager->sjfd) ){
  6671   6666             rc = sqlite3OsTruncate(pPager->sjfd, 0);
  6672   6667             assert( rc==SQLITE_OK );
  6673   6668           }
  6674   6669           pPager->nSubRec = 0;
  6675   6670         }
  6676   6671       }
  6677   6672       /* Else this is a rollback operation, playback the specified savepoint.

Changes to src/parse.y.

   186    186     if( X.n==5 && sqlite3_strnicmp(X.z,"rowid",5)==0 ){
   187    187       A = TF_WithoutRowid | TF_NoVisibleRowid;
   188    188     }else{
   189    189       A = 0;
   190    190       sqlite3ErrorMsg(pParse, "unknown table option: %.*s", X.n, X.z);
   191    191     }
   192    192   }
   193         -columnlist ::= columnlist COMMA column.
   194         -columnlist ::= column.
   195         -
   196         -// A "column" is a complete description of a single column in a
   197         -// CREATE TABLE statement.  This includes the column name, its
   198         -// datatype, and other keywords such as PRIMARY KEY, UNIQUE, REFERENCES,
   199         -// NOT NULL and so forth.
   200         -//
   201         -column(A) ::= columnid(A) type carglist. {
   202         -  A.n = (int)(pParse->sLastToken.z-A.z) + pParse->sLastToken.n;
   203         -}
   204         -columnid(A) ::= nm(A). {
   205         -  sqlite3AddColumn(pParse,&A);
   206         -  pParse->constraintName.n = 0;
   207         -}
   208         -
          193  +columnlist ::= columnlist COMMA columnname carglist.
          194  +columnlist ::= columnname carglist.
          195  +columnname(A) ::= nm(A) typetoken(Y). {sqlite3AddColumn(pParse,&A,&Y);}
   209    196   
   210    197   // An IDENTIFIER can be a generic identifier, or one of several
   211    198   // keywords.  Any non-standard keyword can also be an identifier.
   212    199   //
   213    200   %token_class id  ID|INDEXED.
   214    201   
   215    202   // The following directive causes tokens ABORT, AFTER, ASC, etc. to
................................................................................
   260    247   // The name of a column or table can be any of the following:
   261    248   //
   262    249   %type nm {Token}
   263    250   nm(A) ::= id(A).
   264    251   nm(A) ::= STRING(A).
   265    252   nm(A) ::= JOIN_KW(A).
   266    253   
   267         -// A typetoken is really one or more tokens that form a type name such
          254  +// A typetoken is really zero or more tokens that form a type name such
   268    255   // as can be found after the column name in a CREATE TABLE statement.
   269    256   // Multiple tokens are concatenated to form the value of the typetoken.
   270    257   //
   271    258   %type typetoken {Token}
   272         -type ::= .
   273         -type ::= typetoken(X).                   {sqlite3AddColumnType(pParse,&X);}
          259  +typetoken(A) ::= .   {A.n = 0; A.z = 0;}
   274    260   typetoken(A) ::= typename(A).
   275    261   typetoken(A) ::= typename(A) LP signed RP(Y). {
   276    262     A.n = (int)(&Y.z[Y.n] - A.z);
   277    263   }
   278    264   typetoken(A) ::= typename(A) LP signed COMMA signed RP(Y). {
   279    265     A.n = (int)(&Y.z[Y.n] - A.z);
   280    266   }
................................................................................
   576    562   
   577    563   // An option "AS <id>" phrase that can follow one of the expressions that
   578    564   // define the result set, or one of the tables in the FROM clause.
   579    565   //
   580    566   %type as {Token}
   581    567   as(X) ::= AS nm(Y).    {X = Y;}
   582    568   as(X) ::= ids(X).
   583         -as(X) ::= .            {X.n = 0;}
          569  +as(X) ::= .            {X.n = 0; X.z = 0;}
   584    570   
   585    571   
   586    572   %type seltablist {SrcList*}
   587    573   %destructor seltablist {sqlite3SrcListDelete(pParse->db, $$);}
   588    574   %type stl_prefix {SrcList*}
   589    575   %destructor stl_prefix {sqlite3SrcListDelete(pParse->db, $$);}
   590    576   %type from {SrcList*}
................................................................................
  1495   1481   %endif
  1496   1482   
  1497   1483   //////////////////////// ALTER TABLE table ... ////////////////////////////////
  1498   1484   %ifndef SQLITE_OMIT_ALTERTABLE
  1499   1485   cmd ::= ALTER TABLE fullname(X) RENAME TO nm(Z). {
  1500   1486     sqlite3AlterRenameTable(pParse,X,&Z);
  1501   1487   }
  1502         -cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt column(Y). {
         1488  +cmd ::= ALTER TABLE add_column_fullname
         1489  +        ADD kwcolumn_opt columnname(Y) carglist. {
         1490  +  Y.n = (int)(pParse->sLastToken.z-Y.z) + pParse->sLastToken.n;
  1503   1491     sqlite3AlterFinishAddColumn(pParse, &Y);
  1504   1492   }
  1505   1493   add_column_fullname ::= fullname(X). {
  1506   1494     disableLookaside(pParse);
  1507   1495     sqlite3AlterBeginAddColumn(pParse, X);
  1508   1496   }
  1509   1497   kwcolumn_opt ::= .

Changes to src/pragma.c.

  1061   1061         Column *pCol;
  1062   1062         Index *pPk = sqlite3PrimaryKeyIndex(pTab);
  1063   1063         pParse->nMem = 6;
  1064   1064         sqlite3CodeVerifySchema(pParse, iDb);
  1065   1065         setAllColumnNames(v, 6, azCol); assert( 6==ArraySize(azCol) );
  1066   1066         sqlite3ViewGetColumnNames(pParse, pTab);
  1067   1067         for(i=0, pCol=pTab->aCol; i<pTab->nCol; i++, pCol++){
         1068  +        const char *zName;
  1068   1069           if( IsHiddenColumn(pCol) ){
  1069   1070             nHidden++;
  1070   1071             continue;
  1071   1072           }
  1072   1073           if( (pCol->colFlags & COLFLAG_PRIMKEY)==0 ){
  1073   1074             k = 0;
  1074   1075           }else if( pPk==0 ){
  1075   1076             k = 1;
  1076   1077           }else{
  1077   1078             for(k=1; k<=pTab->nCol && pPk->aiColumn[k-1]!=i; k++){}
  1078   1079           }
         1080  +        assert( pCol->pDflt==0 || pCol->pDflt->op==TK_SPAN );
         1081  +        zName = pCol->zName;
  1079   1082           sqlite3VdbeMultiLoad(v, 1, "issisi",
  1080   1083                  i-nHidden,
  1081         -               pCol->zName,
  1082         -               pCol->zType ? pCol->zType : "",
         1084  +               zName,
         1085  +               sqlite3StrNext(zName),
  1083   1086                  pCol->notNull ? 1 : 0,
  1084         -               pCol->zDflt,
         1087  +               pCol->pDflt ? pCol->pDflt->u.zToken : 0,
  1085   1088                  k);
  1086   1089           sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 6);
  1087   1090         }
  1088   1091       }
  1089   1092     }
  1090   1093     break;
  1091   1094   
................................................................................
  1098   1101       sqlite3CodeVerifySchema(pParse, iDb);
  1099   1102       setAllColumnNames(v, 4, azCol);  assert( 4==ArraySize(azCol) );
  1100   1103       for(i=sqliteHashFirst(&pDb->pSchema->tblHash); i; i=sqliteHashNext(i)){
  1101   1104         Table *pTab = sqliteHashData(i);
  1102   1105         sqlite3VdbeMultiLoad(v, 1, "ssii",
  1103   1106              pTab->zName,
  1104   1107              0,
  1105         -           (int)sqlite3LogEstToInt(pTab->szTabRow),
  1106         -           (int)sqlite3LogEstToInt(pTab->nRowLogEst));
         1108  +           pTab->szTabRow,
         1109  +           pTab->nRowLogEst);
  1107   1110         sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 4);
  1108   1111         for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
  1109   1112           sqlite3VdbeMultiLoad(v, 2, "sii",
  1110   1113              pIdx->zName,
  1111         -           (int)sqlite3LogEstToInt(pIdx->szIdxRow),
  1112         -           (int)sqlite3LogEstToInt(pIdx->aiRowLogEst[0]));
         1114  +           pIdx->szIdxRow,
         1115  +           pIdx->aiRowLogEst[0]);
  1113   1116           sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 4);
  1114   1117         }
  1115   1118       }
  1116   1119     }
  1117   1120     break;
  1118   1121   
  1119   1122     case PragTyp_INDEX_INFO: if( zRight ){

Changes to src/select.c.

  1425   1425           if( iCol<0 ) iCol = pTab->iPKey;
  1426   1426           assert( iCol==-1 || (iCol>=0 && iCol<pTab->nCol) );
  1427   1427   #ifdef SQLITE_ENABLE_COLUMN_METADATA
  1428   1428           if( iCol<0 ){
  1429   1429             zType = "INTEGER";
  1430   1430             zOrigCol = "rowid";
  1431   1431           }else{
  1432         -          zType = pTab->aCol[iCol].zType;
  1433   1432             zOrigCol = pTab->aCol[iCol].zName;
         1433  +          zType = sqlite3StrNext(zOrigCol);
  1434   1434             estWidth = pTab->aCol[iCol].szEst;
  1435   1435           }
  1436   1436           zOrigTab = pTab->zName;
  1437   1437           if( pNC->pParse ){
  1438   1438             int iDb = sqlite3SchemaToIndex(pNC->pParse->db, pTab->pSchema);
  1439   1439             zOrigDb = pNC->pParse->db->aDb[iDb].zName;
  1440   1440           }
  1441   1441   #else
  1442   1442           if( iCol<0 ){
  1443   1443             zType = "INTEGER";
  1444   1444           }else{
  1445         -          zType = pTab->aCol[iCol].zType;
         1445  +          zType = sqlite3StrNext(pTab->aCol[iCol].zName);
  1446   1446             estWidth = pTab->aCol[iCol].szEst;
  1447   1447           }
  1448   1448   #endif
  1449   1449         }
  1450   1450         break;
  1451   1451       }
  1452   1452   #ifndef SQLITE_OMIT_SUBQUERY
................................................................................
  1723   1723     assert( pTab->nCol==pSelect->pEList->nExpr || db->mallocFailed );
  1724   1724     if( db->mallocFailed ) return;
  1725   1725     memset(&sNC, 0, sizeof(sNC));
  1726   1726     sNC.pSrcList = pSelect->pSrc;
  1727   1727     a = pSelect->pEList->a;
  1728   1728     for(i=0, pCol=pTab->aCol; i<pTab->nCol; i++, pCol++){
  1729   1729       p = a[i].pExpr;
  1730         -    if( pCol->zType==0 ){
  1731         -      pCol->zType = sqlite3DbStrDup(db, 
  1732         -                        columnType(&sNC, p,0,0,0, &pCol->szEst));
  1733         -    }
         1730  +    columnType(&sNC, p, 0, 0, 0, &pCol->szEst);
  1734   1731       szAll += pCol->szEst;
  1735   1732       pCol->affinity = sqlite3ExprAffinity(p);
  1736   1733       if( pCol->affinity==0 ) pCol->affinity = SQLITE_AFF_BLOB;
  1737   1734       pColl = sqlite3ExprCollSeq(pParse, p);
  1738   1735       if( pColl && pCol->zColl==0 ){
  1739   1736         pCol->zColl = sqlite3DbStrDup(db, pColl->zName);
  1740   1737       }
................................................................................
  2221   2218     assert( v!=0 );  /* The VDBE already created by calling function */
  2222   2219   
  2223   2220     /* Create the destination temporary table if necessary
  2224   2221     */
  2225   2222     if( dest.eDest==SRT_EphemTab ){
  2226   2223       assert( p->pEList );
  2227   2224       sqlite3VdbeAddOp2(v, OP_OpenEphemeral, dest.iSDParm, p->pEList->nExpr);
  2228         -    sqlite3VdbeChangeP5(v, BTREE_UNORDERED);
  2229   2225       dest.eDest = SRT_Table;
  2230   2226     }
  2231   2227   
  2232   2228     /* Special handling for a compound-select that originates as a VALUES clause.
  2233   2229     */
  2234   2230     if( p->selFlags & SF_MultiValue ){
  2235   2231       rc = multiSelectValues(pParse, p, &dest);

Changes to src/shell.c.

  1296   1296     int nErrMsg = 1+strlen30(sqlite3_errmsg(db));
  1297   1297     char *zErrMsg = sqlite3_malloc64(nErrMsg);
  1298   1298     if( zErrMsg ){
  1299   1299       memcpy(zErrMsg, sqlite3_errmsg(db), nErrMsg);
  1300   1300     }
  1301   1301     return zErrMsg;
  1302   1302   }
         1303  +
         1304  +#ifdef __linux__
         1305  +/*
         1306  +** Attempt to display I/O stats on Linux using /proc/PID/io
         1307  +*/
         1308  +static void displayLinuxIoStats(FILE *out){
         1309  +  FILE *in;
         1310  +  char z[200];
         1311  +  sqlite3_snprintf(sizeof(z), z, "/proc/%d/io", getpid());
         1312  +  in = fopen(z, "rb");
         1313  +  if( in==0 ) return;
         1314  +  while( fgets(z, sizeof(z), in)!=0 ){
         1315  +    static const struct {
         1316  +      const char *zPattern;
         1317  +      const char *zDesc;
         1318  +    } aTrans[] = {
         1319  +      { "rchar: ",                  "Bytes received by read():" },
         1320  +      { "wchar: ",                  "Bytes sent to write():"    },
         1321  +      { "syscr: ",                  "Read() system calls:"      },
         1322  +      { "syscw: ",                  "Write() system calls:"     },
         1323  +      { "read_bytes: ",             "Bytes read from storage:"  },
         1324  +      { "write_bytes: ",            "Bytes written to storage:" },
         1325  +      { "cancelled_write_bytes: ",  "Cancelled write bytes:"    },
         1326  +    };
         1327  +    int i;
         1328  +    for(i=0; i<ArraySize(aTrans); i++){
         1329  +      int n = (int)strlen(aTrans[i].zPattern);
         1330  +      if( strncmp(aTrans[i].zPattern, z, n)==0 ){
         1331  +        raw_printf(out, "%-36s %s", aTrans[i].zDesc, &z[n]);
         1332  +        break;
         1333  +      }
         1334  +    }
         1335  +  }
         1336  +  fclose(in);
         1337  +}   
         1338  +#endif
         1339  +
  1303   1340   
  1304   1341   /*
  1305   1342   ** Display memory stats.
  1306   1343   */
  1307   1344   static int display_stats(
  1308   1345     sqlite3 *db,                /* Database to query */
  1309   1346     ShellState *pArg,           /* Pointer to ShellState */
................................................................................
  1418   1455       iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_SORT, bReset);
  1419   1456       raw_printf(pArg->out, "Sort Operations:                     %d\n", iCur);
  1420   1457       iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_AUTOINDEX,bReset);
  1421   1458       raw_printf(pArg->out, "Autoindex Inserts:                   %d\n", iCur);
  1422   1459       iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_VM_STEP, bReset);
  1423   1460       raw_printf(pArg->out, "Virtual Machine Steps:               %d\n", iCur);
  1424   1461     }
         1462  +
         1463  +#ifdef __linux__
         1464  +  displayLinuxIoStats(pArg->out);
         1465  +#endif
  1425   1466   
  1426   1467     /* Do not remove this machine readable comment: extra-stats-output-here */
  1427   1468   
  1428   1469     return 0;
  1429   1470   }
  1430   1471   
  1431   1472   /*
................................................................................
  1973   2014     ".separator COL ?ROW?   Change the column separator and optionally the row\n"
  1974   2015     "                         separator for both the output mode and .import\n"
  1975   2016   #if defined(SQLITE_ENABLE_SESSION)
  1976   2017     ".session CMD ...       Create or control sessions\n"
  1977   2018   #endif
  1978   2019     ".shell CMD ARGS...     Run CMD ARGS... in a system shell\n"
  1979   2020     ".show                  Show the current values for various settings\n"
  1980         -  ".stats on|off          Turn stats on or off\n"
         2021  +  ".stats ?on|off?        Show stats or turn stats on or off\n"
  1981   2022     ".system CMD ARGS...    Run CMD ARGS... in a system shell\n"
  1982   2023     ".tables ?TABLE?        List names of tables\n"
  1983   2024     "                         If TABLE specified, only list tables matching\n"
  1984   2025     "                         LIKE pattern TABLE.\n"
  1985   2026     ".timeout MS            Try opening locked tables for MS milliseconds\n"
  1986   2027     ".timer on|off          Turn SQL timer on or off\n"
  1987   2028     ".trace FILE|off        Output each SQL statement as it is run\n"
................................................................................
  4112   4153       }
  4113   4154       raw_printf(p->out, "\n");
  4114   4155     }else
  4115   4156   
  4116   4157     if( c=='s' && strncmp(azArg[0], "stats", n)==0 ){
  4117   4158       if( nArg==2 ){
  4118   4159         p->statsOn = booleanValue(azArg[1]);
         4160  +    }else if( nArg==1 ){
         4161  +      display_stats(p->db, p, 0);
  4119   4162       }else{
  4120         -      raw_printf(stderr, "Usage: .stats on|off\n");
         4163  +      raw_printf(stderr, "Usage: .stats ?on|off?\n");
  4121   4164         rc = 1;
  4122   4165       }
  4123   4166     }else
  4124   4167   
  4125   4168     if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 ){
  4126   4169       sqlite3_stmt *pStmt;
  4127   4170       char **azResult;

Changes to src/sqlite.h.in.

  1224   1224     ** Those below are for version 3 and greater.
  1225   1225     */
  1226   1226     int (*xSetSystemCall)(sqlite3_vfs*, const char *zName, sqlite3_syscall_ptr);
  1227   1227     sqlite3_syscall_ptr (*xGetSystemCall)(sqlite3_vfs*, const char *zName);
  1228   1228     const char *(*xNextSystemCall)(sqlite3_vfs*, const char *zName);
  1229   1229     /*
  1230   1230     ** The methods above are in versions 1 through 3 of the sqlite_vfs object.
  1231         -  ** New fields may be appended in figure versions.  The iVersion
         1231  +  ** New fields may be appended in future versions.  The iVersion
  1232   1232     ** value will increment whenever this happens. 
  1233   1233     */
  1234   1234   };
  1235   1235   
  1236   1236   /*
  1237   1237   ** CAPI3REF: Flags for the xAccess VFS method
  1238   1238   **
................................................................................
  1900   1900   ** The first argument is an integer which is 0 to disable triggers,
  1901   1901   ** positive to enable triggers or negative to leave the setting unchanged.
  1902   1902   ** The second parameter is a pointer to an integer into which
  1903   1903   ** is written 0 or 1 to indicate whether triggers are disabled or enabled
  1904   1904   ** following this call.  The second parameter may be a NULL pointer, in
  1905   1905   ** which case the trigger setting is not reported back. </dd>
  1906   1906   **
         1907  +** <dt>SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER</dt>
         1908  +** <dd> ^This option is used to enable or disable the two-argument
         1909  +** version of the [fts3_tokenizer()] function which is part of the
         1910  +** [FTS3] full-text search engine extension.
         1911  +** There should be two additional arguments.
         1912  +** The first argument is an integer which is 0 to disable fts3_tokenizer() or
         1913  +** positive to enable fts3_tokenizer() or negative to leave the setting
         1914  +** unchanged.
         1915  +** The second parameter is a pointer to an integer into which
         1916  +** is written 0 or 1 to indicate whether fts3_tokenizer is disabled or enabled
         1917  +** following this call.  The second parameter may be a NULL pointer, in
         1918  +** which case the new setting is not reported back. </dd>
         1919  +**
  1907   1920   ** </dl>
  1908   1921   */
  1909         -#define SQLITE_DBCONFIG_LOOKASIDE       1001  /* void* int int */
  1910         -#define SQLITE_DBCONFIG_ENABLE_FKEY     1002  /* int int* */
  1911         -#define SQLITE_DBCONFIG_ENABLE_TRIGGER  1003  /* int int* */
         1922  +#define SQLITE_DBCONFIG_LOOKASIDE             1001 /* void* int int */
         1923  +#define SQLITE_DBCONFIG_ENABLE_FKEY           1002 /* int int* */
         1924  +#define SQLITE_DBCONFIG_ENABLE_TRIGGER        1003 /* int int* */
         1925  +#define SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER 1004 /* int int* */
  1912   1926   
  1913   1927   
  1914   1928   /*
  1915   1929   ** CAPI3REF: Enable Or Disable Extended Result Codes
  1916   1930   ** METHOD: sqlite3
  1917   1931   **
  1918   1932   ** ^The sqlite3_extended_result_codes() routine enables or disables the
................................................................................
  8045   8059   ** ^The [sqlite3_snapshot_open()] interface returns SQLITE_OK on success
  8046   8060   ** or an appropriate [error code] if it fails.
  8047   8061   **
  8048   8062   ** ^In order to succeed, a call to [sqlite3_snapshot_open(D,S,P)] must be
  8049   8063   ** the first operation, apart from other sqlite3_snapshot_open() calls,
  8050   8064   ** following the [BEGIN] that starts a new read transaction.
  8051   8065   ** ^A [snapshot] will fail to open if it has been overwritten by a 
  8052         -** [checkpoint].  
         8066  +** [checkpoint].
         8067  +** ^A [snapshot] will fail to open if the database connection D has not
         8068  +** previously completed at least one read operation against the database 
         8069  +** file.  (Hint: Run "[PRAGMA application_id]" against a newly opened
         8070  +** database connection in order to make it ready to use snapshots.)
  8053   8071   **
  8054   8072   ** The [sqlite3_snapshot_open()] interface is only available when the
  8055   8073   ** SQLITE_ENABLE_SNAPSHOT compile-time option is used.
  8056   8074   */
  8057   8075   SQLITE_EXPERIMENTAL int sqlite3_snapshot_open(
  8058   8076     sqlite3 *db,
  8059   8077     const char *zSchema,

Changes to src/sqliteInt.h.

  1331   1331   #define SQLITE_LoadExtension  0x00400000  /* Enable load_extension */
  1332   1332   #define SQLITE_EnableTrigger  0x00800000  /* True to enable triggers */
  1333   1333   #define SQLITE_DeferFKs       0x01000000  /* Defer all FK constraints */
  1334   1334   #define SQLITE_QueryOnly      0x02000000  /* Disable database changes */
  1335   1335   #define SQLITE_VdbeEQP        0x04000000  /* Debug EXPLAIN QUERY PLAN */
  1336   1336   #define SQLITE_Vacuum         0x08000000  /* Currently in a VACUUM */
  1337   1337   #define SQLITE_CellSizeCk     0x10000000  /* Check btree cell sizes on load */
         1338  +#define SQLITE_Fts3Tokenizer  0x20000000  /* Enable fts3_tokenizer(2) */
  1338   1339   
  1339   1340   
  1340   1341   /*
  1341   1342   ** Bits of the sqlite3.dbOptFlags field that are used by the
  1342   1343   ** sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS,...) interface to
  1343   1344   ** selectively disable various optimizations.
  1344   1345   */
................................................................................
  1546   1547   };
  1547   1548   
  1548   1549   /*
  1549   1550   ** information about each column of an SQL table is held in an instance
  1550   1551   ** of this structure.
  1551   1552   */
  1552   1553   struct Column {
  1553         -  char *zName;     /* Name of this column */
         1554  +  char *zName;     /* Name of this column, \000, then the type */
  1554   1555     Expr *pDflt;     /* Default value of this column */
  1555         -  char *zDflt;     /* Original text of the default value */
  1556         -  char *zType;     /* Data type for this column */
  1557   1556     char *zColl;     /* Collating sequence.  If NULL, use the default */
  1558   1557     u8 notNull;      /* An OE_ code for handling a NOT NULL constraint */
  1559   1558     char affinity;   /* One of the SQLITE_AFF_... values */
  1560   1559     u8 szEst;        /* Estimated size of value in this column. sizeof(INT)==1 */
  1561   1560     u8 colFlags;     /* Boolean properties.  See COLFLAG_ defines below */
  1562   1561   };
  1563   1562   
................................................................................
  3266   3265   #endif
  3267   3266   
  3268   3267   /*
  3269   3268   ** Internal function prototypes
  3270   3269   */
  3271   3270   int sqlite3StrICmp(const char*,const char*);
  3272   3271   int sqlite3Strlen30(const char*);
         3272  +const char *sqlite3StrNext(const char*);
  3273   3273   #define sqlite3StrNICmp sqlite3_strnicmp
  3274   3274   
  3275   3275   int sqlite3MallocInit(void);
  3276   3276   void sqlite3MallocEnd(void);
  3277   3277   void *sqlite3Malloc(u64);
  3278   3278   void *sqlite3MallocZero(u64);
  3279   3279   void *sqlite3DbMallocZero(sqlite3*, u64);
................................................................................
  3421   3421   i16 sqlite3ColumnOfIndex(Index*, i16);
  3422   3422   void sqlite3StartTable(Parse*,Token*,Token*,int,int,int,int);
  3423   3423   #if SQLITE_ENABLE_HIDDEN_COLUMNS
  3424   3424     void sqlite3ColumnPropertiesFromName(Table*, Column*);
  3425   3425   #else
  3426   3426   # define sqlite3ColumnPropertiesFromName(T,C) /* no-op */
  3427   3427   #endif
  3428         -void sqlite3AddColumn(Parse*,Token*);
         3428  +void sqlite3AddColumn(Parse*,Token*,Token*);
  3429   3429   void sqlite3AddNotNull(Parse*, int);
  3430   3430   void sqlite3AddPrimaryKey(Parse*, ExprList*, int, int, int);
  3431   3431   void sqlite3AddCheckConstraint(Parse*, Expr*);
  3432         -void sqlite3AddColumnType(Parse*,Token*);
  3433   3432   void sqlite3AddDefaultValue(Parse*,ExprSpan*);
  3434   3433   void sqlite3AddCollateType(Parse*, Token*);
  3435   3434   void sqlite3EndTable(Parse*,Token*,Token*,u8,Select*);
  3436   3435   int sqlite3ParseUri(const char*,const char*,unsigned int*,
  3437   3436                       sqlite3_vfs**,char**,char **);
  3438   3437   Btree *sqlite3DbNameToBtree(sqlite3*,const char*);
  3439   3438   int sqlite3CodeOnce(Parse *);
................................................................................
  3694   3693   int sqlite3Utf8CharLen(const char *pData, int nByte);
  3695   3694   u32 sqlite3Utf8Read(const u8**);
  3696   3695   LogEst sqlite3LogEst(u64);
  3697   3696   LogEst sqlite3LogEstAdd(LogEst,LogEst);
  3698   3697   #ifndef SQLITE_OMIT_VIRTUALTABLE
  3699   3698   LogEst sqlite3LogEstFromDouble(double);
  3700   3699   #endif
         3700  +#if defined(SQLITE_ENABLE_STMT_SCANSTAT) || \
         3701  +    defined(SQLITE_ENABLE_STAT3_OR_STAT4) || \
         3702  +    defined(SQLITE_EXPLAIN_ESTIMATED_ROWS)
  3701   3703   u64 sqlite3LogEstToInt(LogEst);
         3704  +#endif
  3702   3705   
  3703   3706   /*
  3704   3707   ** Routines to read and write variable-length integers.  These used to
  3705   3708   ** be defined locally, but now we use the varint routines in the util.c
  3706   3709   ** file.
  3707   3710   */
  3708   3711   int sqlite3PutVarint(unsigned char*, u64);
................................................................................
  4003   4006   ** Allowed flags for the 3rd parameter to sqlite3FindInIndex().
  4004   4007   */
  4005   4008   #define IN_INDEX_NOOP_OK     0x0001  /* OK to return IN_INDEX_NOOP */
  4006   4009   #define IN_INDEX_MEMBERSHIP  0x0002  /* IN operator used for membership test */
  4007   4010   #define IN_INDEX_LOOP        0x0004  /* IN operator used as a loop */
  4008   4011   int sqlite3FindInIndex(Parse *, Expr *, u32, int*);
  4009   4012   
         4013  +int sqlite3JournalOpen(sqlite3_vfs *, const char *, sqlite3_file *, int, int);
         4014  +int sqlite3JournalSize(sqlite3_vfs *);
  4010   4015   #ifdef SQLITE_ENABLE_ATOMIC_WRITE
  4011         -  int sqlite3JournalOpen(sqlite3_vfs *, const char *, sqlite3_file *, int, int);
  4012         -  int sqlite3JournalSize(sqlite3_vfs *);
  4013   4016     int sqlite3JournalCreate(sqlite3_file *);
  4014         -  int sqlite3JournalExists(sqlite3_file *p);
  4015         -#else
  4016         -  #define sqlite3JournalSize(pVfs) ((pVfs)->szOsFile)
  4017         -  #define sqlite3JournalExists(p) 1
  4018   4017   #endif
  4019   4018   
         4019  +int sqlite3JournalIsInMemory(sqlite3_file *p);
  4020   4020   void sqlite3MemJournalOpen(sqlite3_file *);
  4021         -int sqlite3MemJournalSize(void);
  4022         -int sqlite3IsMemJournal(sqlite3_file *);
  4023   4021   
  4024   4022   void sqlite3ExprSetHeightAndFlags(Parse *pParse, Expr *p);
  4025   4023   #if SQLITE_MAX_EXPR_DEPTH>0
  4026   4024     int sqlite3SelectExprHeight(Select *);
  4027   4025     int sqlite3ExprCheckHeight(Parse*, int);
  4028   4026   #else
  4029   4027     #define sqlite3SelectExprHeight(x) 0

Changes to src/sqliteLimit.h.

    98     98   #endif
    99     99   
   100    100   /*
   101    101   ** The suggested maximum number of in-memory pages to use for
   102    102   ** the main database table and for temporary tables.
   103    103   **
   104    104   ** IMPLEMENTATION-OF: R-31093-59126 The default suggested cache size
   105         -** is 2000 pages.
          105  +** is 2000*1024 bytes.
   106    106   ** IMPLEMENTATION-OF: R-48205-43578 The default suggested cache size can be
   107    107   ** altered using the SQLITE_DEFAULT_CACHE_SIZE compile-time options.
   108    108   */
   109    109   #ifndef SQLITE_DEFAULT_CACHE_SIZE
   110         -# define SQLITE_DEFAULT_CACHE_SIZE  2000
          110  +# define SQLITE_DEFAULT_CACHE_SIZE  -2000
   111    111   #endif
   112    112   
   113    113   /*
   114    114   ** The default number of frames to accumulate in the log file before
   115    115   ** checkpointing the database in WAL mode.
   116    116   */
   117    117   #ifndef SQLITE_DEFAULT_WAL_AUTOCHECKPOINT
   118    118   # define SQLITE_DEFAULT_WAL_AUTOCHECKPOINT  1000
   119    119   #endif
   120    120   
   121    121   /*
   122    122   ** The maximum number of attached databases.  This must be between 0
   123         -** and 62.  The upper bound on 62 is because a 64-bit integer bitmap
   124         -** is used internally to track attached databases.
          123  +** and 125.  The upper bound of 125 is because the attached databases are
          124  +** counted using a signed 8-bit integer which has a maximum value of 127
          125  +** and we have to allow 2 extra counts for the "main" and "temp" databases.
   125    126   */
   126    127   #ifndef SQLITE_MAX_ATTACHED
   127    128   # define SQLITE_MAX_ATTACHED 10
   128    129   #endif
   129    130   
   130    131   
   131    132   /*
................................................................................
   152    153   #define SQLITE_MAX_PAGE_SIZE 65536
   153    154   
   154    155   
   155    156   /*
   156    157   ** The default size of a database page.
   157    158   */
   158    159   #ifndef SQLITE_DEFAULT_PAGE_SIZE
   159         -# define SQLITE_DEFAULT_PAGE_SIZE 1024
          160  +# define SQLITE_DEFAULT_PAGE_SIZE 4096
   160    161   #endif
   161    162   #if SQLITE_DEFAULT_PAGE_SIZE>SQLITE_MAX_PAGE_SIZE
   162    163   # undef SQLITE_DEFAULT_PAGE_SIZE
   163    164   # define SQLITE_DEFAULT_PAGE_SIZE SQLITE_MAX_PAGE_SIZE
   164    165   #endif
   165    166   
   166    167   /*

Changes to src/tclsqlite.c.

  3919   3919       extern int SqliteSuperlock_Init(Tcl_Interp*);
  3920   3920       extern int SqlitetestSyscall_Init(Tcl_Interp*);
  3921   3921   #if defined(SQLITE_ENABLE_SESSION) && defined(SQLITE_ENABLE_PREUPDATE_HOOK)
  3922   3922       extern int TestSession_Init(Tcl_Interp*);
  3923   3923   #endif
  3924   3924       extern int Fts5tcl_Init(Tcl_Interp *);
  3925   3925       extern int SqliteRbu_Init(Tcl_Interp*);
         3926  +    extern int Sqlitetesttcl_Init(Tcl_Interp*);
  3926   3927   #if defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4)
  3927   3928       extern int Sqlitetestfts3_Init(Tcl_Interp *interp);
  3928   3929   #endif
  3929   3930   
  3930   3931   #ifdef SQLITE_ENABLE_ZIPVFS
  3931   3932       extern int Zipvfs_Init(Tcl_Interp*);
  3932   3933       Zipvfs_Init(interp);
................................................................................
  3966   3967       SqliteSuperlock_Init(interp);
  3967   3968       SqlitetestSyscall_Init(interp);
  3968   3969   #if defined(SQLITE_ENABLE_SESSION) && defined(SQLITE_ENABLE_PREUPDATE_HOOK)
  3969   3970       TestSession_Init(interp);
  3970   3971   #endif
  3971   3972       Fts5tcl_Init(interp);
  3972   3973       SqliteRbu_Init(interp);
         3974  +    Sqlitetesttcl_Init(interp);
  3973   3975   
  3974   3976   #if defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4)
  3975   3977       Sqlitetestfts3_Init(interp);
  3976   3978   #endif
  3977   3979   
  3978   3980       Tcl_CreateObjCommand(
  3979   3981           interp, "load_testfixture_extensions", init_all_cmd, 0, 0

Changes to src/test1.c.

  6915   6915     if( Tcl_GetCommandInfo(interp, zDb, &cmdInfo) ){
  6916   6916       sqlite3* db = ((struct SqliteDb*)cmdInfo.objClientData)->db;
  6917   6917       sqlite3DbstatRegister(db);
  6918   6918     }
  6919   6919     return TCL_OK;
  6920   6920   #endif /* SQLITE_OMIT_VIRTUALTABLE */
  6921   6921   }
         6922  +
         6923  +/*
         6924  +** tclcmd:   sqlite3_db_config DB SETTING VALUE
         6925  +**
         6926  +** Invoke sqlite3_db_config() for one of the setting values.
         6927  +*/
         6928  +static int test_sqlite3_db_config(
         6929  +  void *clientData,
         6930  +  Tcl_Interp *interp,
         6931  +  int objc,
         6932  +  Tcl_Obj *CONST objv[]
         6933  +){
         6934  +  static const struct {
         6935  +    const char *zName;
         6936  +    int eVal;
         6937  +  } aSetting[] = {
         6938  +    { "FKEY",            SQLITE_DBCONFIG_ENABLE_FKEY },
         6939  +    { "TRIGGER",         SQLITE_DBCONFIG_ENABLE_TRIGGER },
         6940  +    { "FTS3_TOKENIZER",  SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER },
         6941  +  };
         6942  +  int i;
         6943  +  int v;
         6944  +  const char *zSetting;
         6945  +  sqlite3 *db;
         6946  +
         6947  +  if( objc!=4 ){
         6948  +    Tcl_WrongNumArgs(interp, 1, objv, "DB SETTING VALUE");
         6949  +    return TCL_ERROR;
         6950  +  }
         6951  +  if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
         6952  +  zSetting = Tcl_GetString(objv[2]);
         6953  +  if( sqlite3_strglob("SQLITE_*", zSetting)==0 ) zSetting += 7;
         6954  +  if( sqlite3_strglob("DBCONFIG_*", zSetting)==0 ) zSetting += 9;
         6955  +  if( sqlite3_strglob("ENABLE_*", zSetting)==0 ) zSetting += 7;
         6956  +  for(i=0; i<ArraySize(aSetting); i++){
         6957  +    if( strcmp(zSetting, aSetting[i].zName)==0 ) break;
         6958  +  }
         6959  +  if( i>=ArraySize(aSetting) ){
         6960  +    Tcl_SetObjResult(interp,
         6961  +      Tcl_NewStringObj("unknown sqlite3_db_config setting", -1));
         6962  +    return TCL_ERROR;
         6963  +  }
         6964  +  if( Tcl_GetIntFromObj(interp, objv[3], &v) ) return TCL_ERROR;
         6965  +  sqlite3_db_config(db, aSetting[i].eVal, v, &v);
         6966  +  Tcl_SetObjResult(interp, Tcl_NewIntObj(v));
         6967  +  return TCL_OK;
         6968  +}
  6922   6969   
  6923   6970   /*
  6924   6971   ** Register commands with the TCL interpreter.
  6925   6972   */
  6926   6973   int Sqlitetest1_Init(Tcl_Interp *interp){
  6927   6974     extern int sqlite3_search_count;
  6928   6975     extern int sqlite3_found_count;
................................................................................
  6985   7032        { "clang_sanitize_address",        (Tcl_CmdProc*)clang_sanitize_address },
  6986   7033     };
  6987   7034     static struct {
  6988   7035        char *zName;
  6989   7036        Tcl_ObjCmdProc *xProc;
  6990   7037        void *clientData;
  6991   7038     } aObjCmd[] = {
         7039  +     { "sqlite3_db_config",             test_sqlite3_db_config, 0 },
  6992   7040        { "bad_behavior",                  test_bad_behavior,  (void*)&iZero },
  6993   7041        { "register_dbstat_vtab",          test_register_dbstat_vtab  },
  6994   7042        { "sqlite3_connection_pointer",    get_sqlite_pointer, 0 },
  6995   7043        { "sqlite3_bind_int",              test_bind_int,      0 },
  6996   7044        { "sqlite3_bind_zeroblob",         test_bind_zeroblob, 0 },
  6997   7045        { "sqlite3_bind_zeroblob64",       test_bind_zeroblob64, 0 },
  6998   7046        { "sqlite3_bind_int64",            test_bind_int64,    0 },

Added src/test_bestindex.c.

            1  +/*
            2  +** 2016-03-01
            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  +** Code for testing the virtual table xBestIndex method and the query
           13  +** planner.
           14  +*/
           15  +
           16  +
           17  +/*
           18  +** INSTRUCTIONS
           19  +**
           20  +** This module exports a single tcl command - [register_tcl_module]. When
           21  +** invoked, it registers a special virtual table module with a database
           22  +** connection.
           23  +**
           24  +** The virtual table is currently read-only. And always returns zero rows.
           25  +** It is created with a single argument - the name of a Tcl command - as
           26  +** follows:
           27  +**
           28  +**   CREATE VIRTUAL TABLE x1 USING tcl(tcl_command);
           29  +**
           30  +** The command [tcl_command] is invoked when the table is first created (or
           31  +** connected), when the xBestIndex() method is invoked and when the xFilter()
           32  +** method is called. When it is created (or connected), it is invoked as
           33  +** follows:
           34  +**
           35  +**   tcl_command xConnect
           36  +**
           37  +** In this case the return value of the script is passed to the
           38  +** sqlite3_declare_vtab() function to create the virtual table schema.
           39  +**
           40  +** When the xBestIndex() method is called by SQLite, the Tcl command is
           41  +** invoked as:
           42  +**
           43  +**   tcl_command xBestIndex CONSTRAINTS ORDERBY MASK
           44  +**
           45  +** where CONSTRAINTS is a tcl representation of the aConstraints[] array,
           46  +** ORDERBY is a representation of the contents of the aOrderBy[] array and
           47  +** MASK is a copy of sqlite3_index_info.colUsed. For example if the virtual
           48  +** table is declared as:
           49  +**
           50  +**   CREATE TABLE x1(a, b, c)
           51  +**
           52  +** and the query is:
           53  +**
           54  +**   SELECT * FROM x1 WHERE a=? AND c<? ORDER BY b, c;
           55  +**
           56  +** then the Tcl command is:
           57  +**
           58  +**   tcl_command xBestIndex                                  \
           59  +**     {{op eq column 0 usable 1} {op lt column 2 usable 1}} \
           60  +**     {{column 1 desc 0} {column 2 desc 0}}                 \
           61  +**     7
           62  +**
           63  +** The return value of the script is a list of key-value pairs used to
           64  +** populate the output fields of the sqlite3_index_info structure. Possible
           65  +** keys and the usage of the accompanying values are:
           66  +** 
           67  +**   "orderby"          (value of orderByConsumed flag)
           68  +**   "cost"             (value of estimatedCost field)
           69  +**   "rows"             (value of estimatedRows field)
           70  +**   "use"              (index of used constraint in aConstraint[])
           71  +**   "omit"             (like "use", but also sets omit flag)
           72  +**   "idxnum"           (value of idxNum field)
           73  +**   "idxstr"           (value of idxStr field)
           74  +**
           75  +** Refer to code below for further details.
           76  +**
           77  +** When SQLite calls the xFilter() method, this module invokes the following
           78  +** Tcl script:
           79  +**
           80  +**   tcl_command xFilter IDXNUM IDXSTR ARGLIST
           81  +**
           82  +** IDXNUM and IDXSTR are the values of the idxNum and idxStr parameters
           83  +** passed to xFilter. ARGLIST is a Tcl list containing each of the arguments
           84  +** passed to xFilter in text form.
           85  +**
           86  +** As with xBestIndex(), the return value of the script is interpreted as a
           87  +** list of key-value pairs. There is currently only one key defined - "sql".
           88  +** The value must be the full text of an SQL statement that returns the data
           89  +** for the current scan. The leftmost column returned by the SELECT is assumed
           90  +** to contain the rowid. Other columns must follow, in order from left to
           91  +** right.
           92  +*/
           93  +
           94  +
           95  +#include "sqliteInt.h"
           96  +#include "tcl.h"
           97  +
           98  +#ifndef SQLITE_OMIT_VIRTUALTABLE
           99  +
          100  +typedef struct tcl_vtab tcl_vtab;
          101  +typedef struct tcl_cursor tcl_cursor;
          102  +
          103  +/* 
          104  +** A fs virtual-table object 
          105  +*/
          106  +struct tcl_vtab {
          107  +  sqlite3_vtab base;
          108  +  Tcl_Interp *interp;
          109  +  Tcl_Obj *pCmd;
          110  +  sqlite3 *db;
          111  +};
          112  +
          113  +/* A tcl cursor object */
          114  +struct tcl_cursor {
          115  +  sqlite3_vtab_cursor base;
          116  +  sqlite3_stmt *pStmt;            /* Read data from here */
          117  +};
          118  +
          119  +/*
          120  +** This function is the implementation of both the xConnect and xCreate
          121  +** methods of the fs virtual table.
          122  +**
          123  +** The argv[] array contains the following:
          124  +**
          125  +**   argv[0]   -> module name  ("fs")
          126  +**   argv[1]   -> database name
          127  +**   argv[2]   -> table name
          128  +**   argv[...] -> other module argument fields.
          129  +*/
          130  +static int tclConnect(
          131  +  sqlite3 *db,
          132  +  void *pAux,
          133  +  int argc, const char *const*argv,
          134  +  sqlite3_vtab **ppVtab,
          135  +  char **pzErr
          136  +){
          137  +  Tcl_Interp *interp = (Tcl_Interp*)pAux;
          138  +  tcl_vtab *pTab;
          139  +  const char *zCmd;
          140  +  Tcl_Obj *pScript = 0;
          141  +  int rc;
          142  +
          143  +  if( argc!=4 ){
          144  +    *pzErr = sqlite3_mprintf("wrong number of arguments");
          145  +    return SQLITE_ERROR;
          146  +  }
          147  +  zCmd = argv[3];
          148  +
          149  +  pTab = (tcl_vtab*)sqlite3_malloc(sizeof(tcl_vtab));
          150  +  if( pTab==0 ) return SQLITE_NOMEM;
          151  +  memset(pTab, 0, sizeof(tcl_vtab));
          152  +
          153  +  pTab->pCmd = Tcl_NewStringObj(zCmd, -1);
          154  +  pTab->interp = interp;
          155  +  pTab->db = db;
          156  +  Tcl_IncrRefCount(pTab->pCmd);
          157  +
          158  +  pScript = Tcl_DuplicateObj(pTab->pCmd);
          159  +  Tcl_IncrRefCount(pScript);
          160  +  Tcl_ListObjAppendElement(interp, pScript, Tcl_NewStringObj("xConnect", -1));
          161  +
          162  +  rc = Tcl_EvalObjEx(interp, pScript, TCL_EVAL_GLOBAL);
          163  +  if( rc!=TCL_OK ){
          164  +    *pzErr = sqlite3_mprintf("%s", Tcl_GetStringResult(interp));
          165  +    rc = SQLITE_ERROR;
          166  +  }else{
          167  +    rc = sqlite3_declare_vtab(db, Tcl_GetStringResult(interp));
          168  +  }
          169  +
          170  +  if( rc!=SQLITE_OK ){
          171  +    sqlite3_free(pTab);
          172  +    pTab = 0;
          173  +  }
          174  +
          175  +  *ppVtab = &pTab->base;
          176  +  return rc;
          177  +}
          178  +
          179  +/* The xDisconnect and xDestroy methods are also the same */
          180  +static int tclDisconnect(sqlite3_vtab *pVtab){
          181  +  tcl_vtab *pTab = (tcl_vtab*)pVtab;
          182  +  Tcl_DecrRefCount(pTab->pCmd);
          183  +  sqlite3_free(pTab);
          184  +  return SQLITE_OK;
          185  +}
          186  +
          187  +/*
          188  +** Open a new tcl cursor.
          189  +*/
          190  +static int tclOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
          191  +  tcl_cursor *pCur;
          192  +  pCur = sqlite3_malloc(sizeof(tcl_cursor));
          193  +  if( pCur==0 ) return SQLITE_NOMEM;
          194  +  memset(pCur, 0, sizeof(tcl_cursor));
          195  +  *ppCursor = &pCur->base;
          196  +  return SQLITE_OK;
          197  +}
          198  +
          199  +/*
          200  +** Close a tcl cursor.
          201  +*/
          202  +static int tclClose(sqlite3_vtab_cursor *cur){
          203  +  tcl_cursor *pCur = (tcl_cursor *)cur;
          204  +  if( pCur ){
          205  +    sqlite3_finalize(pCur->pStmt);
          206  +    sqlite3_free(pCur);
          207  +  }
          208  +  return SQLITE_OK;
          209  +}
          210  +
          211  +static int tclNext(sqlite3_vtab_cursor *pVtabCursor){
          212  +  tcl_cursor *pCsr = (tcl_cursor*)pVtabCursor;
          213  +  if( pCsr->pStmt ){
          214  +    tcl_vtab *pTab = (tcl_vtab*)(pVtabCursor->pVtab);
          215  +    int rc = sqlite3_step(pCsr->pStmt);
          216  +    if( rc!=SQLITE_ROW ){
          217  +      const char *zErr;
          218  +      rc = sqlite3_finalize(pCsr->pStmt);
          219  +      pCsr->pStmt = 0;
          220  +      if( rc!=SQLITE_OK ){
          221  +        zErr = sqlite3_errmsg(pTab->db);
          222  +        pTab->base.zErrMsg = sqlite3_mprintf("%s", zErr);
          223  +      }
          224  +    }
          225  +  }
          226  +  return SQLITE_OK;
          227  +}
          228  +
          229  +static int tclFilter(
          230  +  sqlite3_vtab_cursor *pVtabCursor, 
          231  +  int idxNum, const char *idxStr,
          232  +  int argc, sqlite3_value **argv
          233  +){
          234  +  tcl_cursor *pCsr = (tcl_cursor*)pVtabCursor;
          235  +  tcl_vtab *pTab = (tcl_vtab*)(pVtabCursor->pVtab);
          236  +  Tcl_Interp *interp = pTab->interp;
          237  +  Tcl_Obj *pScript;
          238  +  Tcl_Obj *pArg;
          239  +  int ii;
          240  +  int rc;
          241  +
          242  +  pScript = Tcl_DuplicateObj(pTab->pCmd);
          243  +  Tcl_IncrRefCount(pScript);
          244  +  Tcl_ListObjAppendElement(interp, pScript, Tcl_NewStringObj("xFilter", -1));
          245  +  Tcl_ListObjAppendElement(interp, pScript, Tcl_NewIntObj(idxNum));
          246  +  if( idxStr ){
          247  +    Tcl_ListObjAppendElement(interp, pScript, Tcl_NewStringObj(idxStr, -1));
          248  +  }else{
          249  +    Tcl_ListObjAppendElement(interp, pScript, Tcl_NewStringObj("", -1));
          250  +  }
          251  +
          252  +  pArg = Tcl_NewObj();
          253  +  Tcl_IncrRefCount(pArg);
          254  +  for(ii=0; ii<argc; ii++){
          255  +    const char *zVal = (const char*)sqlite3_value_text(argv[ii]);
          256  +    Tcl_Obj *pVal;
          257  +    if( zVal==0 ){
          258  +      pVal = Tcl_NewObj();
          259  +    }else{
          260  +      pVal = Tcl_NewStringObj(zVal, -1);
          261  +    }
          262  +    Tcl_ListObjAppendElement(interp, pArg, pVal);
          263  +  }
          264  +  Tcl_ListObjAppendElement(interp, pScript, pArg);
          265  +  Tcl_DecrRefCount(pArg);
          266  +
          267  +  rc = Tcl_EvalObjEx(interp, pScript, TCL_EVAL_GLOBAL);
          268  +  if( rc!=TCL_OK ){
          269  +    const char *zErr = Tcl_GetStringResult(interp);
          270  +    rc = SQLITE_ERROR;
          271  +    pTab->base.zErrMsg = sqlite3_mprintf("%s", zErr);
          272  +  }else{
          273  +    /* Analyze the scripts return value. The return value should be a tcl 
          274  +    ** list object with an even number of elements. The first element of each
          275  +    ** pair must be one of:
          276  +    ** 
          277  +    **   "sql"          (SQL statement to return data)
          278  +    */
          279  +    Tcl_Obj *pRes = Tcl_GetObjResult(interp);
          280  +    Tcl_Obj **apElem = 0;
          281  +    int nElem;
          282  +    rc = Tcl_ListObjGetElements(interp, pRes, &nElem, &apElem);
          283  +    if( rc!=TCL_OK ){
          284  +      const char *zErr = Tcl_GetStringResult(interp);
          285  +      rc = SQLITE_ERROR;
          286  +      pTab->base.zErrMsg = sqlite3_mprintf("%s", zErr);
          287  +    }else{
          288  +      for(ii=0; rc==SQLITE_OK && ii<nElem; ii+=2){
          289  +        const char *zCmd = Tcl_GetString(apElem[ii]);
          290  +        Tcl_Obj *p = apElem[ii+1];
          291  +        if( sqlite3_stricmp("sql", zCmd)==0 ){
          292  +          const char *zSql = Tcl_GetString(p);
          293  +          rc = sqlite3_prepare_v2(pTab->db, zSql, -1, &pCsr->pStmt, 0);
          294  +          if( rc!=SQLITE_OK ){
          295  +            const char *zErr = sqlite3_errmsg(pTab->db);
          296  +            pTab->base.zErrMsg = sqlite3_mprintf("unexpected: %s", zErr);
          297  +          }
          298  +        }else{
          299  +          rc = SQLITE_ERROR;
          300  +          pTab->base.zErrMsg = sqlite3_mprintf("unexpected: %s", zCmd);
          301  +        }
          302  +      }
          303  +    }
          304  +  }
          305  +
          306  +  if( rc==SQLITE_OK ){
          307  +    rc = tclNext(pVtabCursor);
          308  +  }
          309  +  return rc;
          310  +}
          311  +
          312  +static int tclColumn(
          313  +  sqlite3_vtab_cursor *pVtabCursor, 
          314  +  sqlite3_context *ctx, 
          315  +  int i
          316  +){
          317  +  tcl_cursor *pCsr = (tcl_cursor*)pVtabCursor;
          318  +  sqlite3_result_value(ctx, sqlite3_column_value(pCsr->pStmt, i+1));
          319  +  return SQLITE_OK;
          320  +}
          321  +
          322  +static int tclRowid(sqlite3_vtab_cursor *pVtabCursor, sqlite_int64 *pRowid){
          323  +  tcl_cursor *pCsr = (tcl_cursor*)pVtabCursor;
          324  +  *pRowid = sqlite3_column_int64(pCsr->pStmt, 0);
          325  +  return SQLITE_OK;
          326  +}
          327  +
          328  +static int tclEof(sqlite3_vtab_cursor *pVtabCursor){
          329  +  tcl_cursor *pCsr = (tcl_cursor*)pVtabCursor;
          330  +  return (pCsr->pStmt==0);
          331  +}
          332  +
          333  +static int tclBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
          334  +  tcl_vtab *pTab = (tcl_vtab*)tab;
          335  +  Tcl_Interp *interp = pTab->interp;
          336  +  Tcl_Obj *pArg;
          337  +  Tcl_Obj *pScript;
          338  +  int ii;
          339  +  int rc = SQLITE_OK;
          340  +
          341  +  pScript = Tcl_DuplicateObj(pTab->pCmd);
          342  +  Tcl_IncrRefCount(pScript);
          343  +  Tcl_ListObjAppendElement(interp, pScript, Tcl_NewStringObj("xBestIndex", -1));
          344  +
          345  +  pArg = Tcl_NewObj();
          346  +  Tcl_IncrRefCount(pArg);
          347  +  for(ii=0; ii<pIdxInfo->nConstraint; ii++){
          348  +    struct sqlite3_index_constraint const *pCons = &pIdxInfo->aConstraint[ii];
          349  +    Tcl_Obj *pElem = Tcl_NewObj();
          350  +    const char *zOp = "?";
          351  +
          352  +    Tcl_IncrRefCount(pElem);
          353  +
          354  +    switch( pCons->op ){
          355  +      case SQLITE_INDEX_CONSTRAINT_EQ:
          356  +        zOp = "eq"; break;
          357  +      case SQLITE_INDEX_CONSTRAINT_GT:
          358  +        zOp = "gt"; break;
          359  +      case SQLITE_INDEX_CONSTRAINT_LE:
          360  +        zOp = "le"; break;
          361  +      case SQLITE_INDEX_CONSTRAINT_LT:
          362  +        zOp = "lt"; break;
          363  +      case SQLITE_INDEX_CONSTRAINT_GE:
          364  +        zOp = "ge"; break;
          365  +      case SQLITE_INDEX_CONSTRAINT_MATCH:
          366  +        zOp = "match"; break;
          367  +      case SQLITE_INDEX_CONSTRAINT_LIKE:
          368  +        zOp = "like"; break;
          369  +      case SQLITE_INDEX_CONSTRAINT_GLOB:
          370  +        zOp = "glob"; break;
          371  +      case SQLITE_INDEX_CONSTRAINT_REGEXP:
          372  +        zOp = "regexp"; break;
          373  +    }
          374  +
          375  +    Tcl_ListObjAppendElement(0, pElem, Tcl_NewStringObj("op", -1));
          376  +    Tcl_ListObjAppendElement(0, pElem, Tcl_NewStringObj(zOp, -1));
          377  +    Tcl_ListObjAppendElement(0, pElem, Tcl_NewStringObj("column", -1));
          378  +    Tcl_ListObjAppendElement(0, pElem, Tcl_NewIntObj(pCons->iColumn));
          379  +    Tcl_ListObjAppendElement(0, pElem, Tcl_NewStringObj("usable", -1));
          380  +    Tcl_ListObjAppendElement(0, pElem, Tcl_NewIntObj(pCons->usable));
          381  +
          382  +    Tcl_ListObjAppendElement(0, pArg, pElem);
          383  +    Tcl_DecrRefCount(pElem);
          384  +  }
          385  +
          386  +  Tcl_ListObjAppendElement(0, pScript, pArg);
          387  +  Tcl_DecrRefCount(pArg);
          388  +
          389  +  pArg = Tcl_NewObj();
          390  +  Tcl_IncrRefCount(pArg);
          391  +  for(ii=0; ii<pIdxInfo->nOrderBy; ii++){
          392  +    struct sqlite3_index_orderby const *pOrder = &pIdxInfo->aOrderBy[ii];
          393  +    Tcl_Obj *pElem = Tcl_NewObj();
          394  +    Tcl_IncrRefCount(pElem);
          395  +
          396  +    Tcl_ListObjAppendElement(0, pElem, Tcl_NewStringObj("column", -1));
          397  +    Tcl_ListObjAppendElement(0, pElem, Tcl_NewIntObj(pOrder->iColumn));
          398  +    Tcl_ListObjAppendElement(0, pElem, Tcl_NewStringObj("desc", -1));
          399  +    Tcl_ListObjAppendElement(0, pElem, Tcl_NewIntObj(pOrder->desc));
          400  +
          401  +    Tcl_ListObjAppendElement(0, pArg, pElem);
          402  +    Tcl_DecrRefCount(pElem);
          403  +  }
          404  +
          405  +  Tcl_ListObjAppendElement(0, pScript, pArg);
          406  +  Tcl_DecrRefCount(pArg);
          407  +
          408  +  Tcl_ListObjAppendElement(0, pScript, Tcl_NewWideIntObj(pIdxInfo->colUsed));
          409  +
          410  +  rc = Tcl_EvalObjEx(interp, pScript, TCL_EVAL_GLOBAL);
          411  +  Tcl_DecrRefCount(pScript);
          412  +  if( rc!=TCL_OK ){
          413  +    const char *zErr = Tcl_GetStringResult(interp);
          414  +    rc = SQLITE_ERROR;
          415  +    pTab->base.zErrMsg = sqlite3_mprintf("%s", zErr);
          416  +  }else{
          417  +    /* Analyze the scripts return value. The return value should be a tcl 
          418  +    ** list object with an even number of elements. The first element of each
          419  +    ** pair must be one of:
          420  +    ** 
          421  +    **   "orderby"          (value of orderByConsumed flag)
          422  +    **   "cost"             (value of estimatedCost field)
          423  +    **   "rows"             (value of estimatedRows field)
          424  +    **   "use"              (index of used constraint in aConstraint[])
          425  +    **   "idxnum"           (value of idxNum field)
          426  +    **   "idxstr"           (value of idxStr field)
          427  +    **   "omit"             (index of omitted constraint in aConstraint[])
          428  +    */
          429  +    Tcl_Obj *pRes = Tcl_GetObjResult(interp);
          430  +    Tcl_Obj **apElem = 0;
          431  +    int nElem;
          432  +    rc = Tcl_ListObjGetElements(interp, pRes, &nElem, &apElem);
          433  +    if( rc!=TCL_OK ){
          434  +      const char *zErr = Tcl_GetStringResult(interp);
          435  +      rc = SQLITE_ERROR;
          436  +      pTab->base.zErrMsg = sqlite3_mprintf("%s", zErr);
          437  +    }else{
          438  +      int iArgv = 1;
          439  +      for(ii=0; rc==SQLITE_OK && ii<nElem; ii+=2){
          440  +        const char *zCmd = Tcl_GetString(apElem[ii]);
          441  +        Tcl_Obj *p = apElem[ii+1];
          442  +        if( sqlite3_stricmp("cost", zCmd)==0 ){
          443  +          rc = Tcl_GetDoubleFromObj(interp, p, &pIdxInfo->estimatedCost);
          444  +        }else
          445  +        if( sqlite3_stricmp("orderby", zCmd)==0 ){
          446  +          rc = Tcl_GetIntFromObj(interp, p, &pIdxInfo->orderByConsumed);
          447  +        }else
          448  +        if( sqlite3_stricmp("idxnum", zCmd)==0 ){
          449  +          rc = Tcl_GetIntFromObj(interp, p, &pIdxInfo->idxNum);
          450  +        }else
          451  +        if( sqlite3_stricmp("idxstr", zCmd)==0 ){
          452  +          sqlite3_free(pIdxInfo->idxStr);
          453  +          pIdxInfo->idxStr = sqlite3_mprintf("%s", Tcl_GetString(p));
          454  +          pIdxInfo->needToFreeIdxStr = 1;
          455  +        }else
          456  +        if( sqlite3_stricmp("rows", zCmd)==0 ){
          457  +          rc = Tcl_GetWideIntFromObj(interp, p, &pIdxInfo->estimatedRows);
          458  +        }else
          459  +        if( sqlite3_stricmp("use", zCmd)==0 
          460  +         || sqlite3_stricmp("omit", zCmd)==0 
          461  +        ){
          462  +          int iCons;
          463  +          rc = Tcl_GetIntFromObj(interp, p, &iCons);
          464  +          if( rc==SQLITE_OK ){
          465  +            if( iCons<0 || iCons>=pIdxInfo->nConstraint ){
          466  +              rc = SQLITE_ERROR;
          467  +              pTab->base.zErrMsg = sqlite3_mprintf("unexpected: %d", iCons);
          468  +            }else{
          469  +              int bOmit = (zCmd[0]=='o' || zCmd[0]=='O');
          470  +              pIdxInfo->aConstraintUsage[iCons].argvIndex = iArgv++;
          471  +              pIdxInfo->aConstraintUsage[iCons].omit = bOmit;
          472  +            }
          473  +          }
          474  +        }else{
          475  +          rc = SQLITE_ERROR;
          476  +          pTab->base.zErrMsg = sqlite3_mprintf("unexpected: %s", zCmd);
          477  +        }
          478  +        if( rc!=SQLITE_OK && pTab->base.zErrMsg==0 ){
          479  +          const char *zErr = Tcl_GetStringResult(interp);
          480  +          pTab->base.zErrMsg = sqlite3_mprintf("%s", zErr);
          481  +        }
          482  +      }
          483  +    }
          484  +  }
          485  +
          486  +  return rc;
          487  +}
          488  +
          489  +/*
          490  +** A virtual table module that provides read-only access to a
          491  +** Tcl global variable namespace.
          492  +*/
          493  +static sqlite3_module tclModule = {
          494  +  0,                         /* iVersion */
          495  +  tclConnect,
          496  +  tclConnect,
          497  +  tclBestIndex,
          498  +  tclDisconnect, 
          499  +  tclDisconnect,
          500  +  tclOpen,                      /* xOpen - open a cursor */
          501  +  tclClose,                     /* xClose - close a cursor */
          502  +  tclFilter,                    /* xFilter - configure scan constraints */
          503  +  tclNext,                      /* xNext - advance a cursor */
          504  +  tclEof,                       /* xEof - check for end of scan */
          505  +  tclColumn,                    /* xColumn - read data */
          506  +  tclRowid,                     /* xRowid - read data */
          507  +  0,                           /* xUpdate */
          508  +  0,                           /* xBegin */
          509  +  0,                           /* xSync */
          510  +  0,                           /* xCommit */
          511  +  0,                           /* xRollback */
          512  +  0,                           /* xFindMethod */
          513  +  0,                           /* xRename */
          514  +};
          515  +
          516  +/*
          517  +** Decode a pointer to an sqlite3 object.
          518  +*/
          519  +extern int getDbPointer(Tcl_Interp *interp, const char *zA, sqlite3 **ppDb);
          520  +
          521  +/*
          522  +** Register the echo virtual table module.
          523  +*/
          524  +static int register_tcl_module(
          525  +  ClientData clientData, /* Pointer to sqlite3_enable_XXX function */
          526  +  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
          527  +  int objc,              /* Number of arguments */
          528  +  Tcl_Obj *CONST objv[]  /* Command arguments */
          529  +){
          530  +  sqlite3 *db;
          531  +  if( objc!=2 ){
          532  +    Tcl_WrongNumArgs(interp, 1, objv, "DB");
          533  +    return TCL_ERROR;
          534  +  }
          535  +  if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
          536  +#ifndef SQLITE_OMIT_VIRTUALTABLE
          537  +  sqlite3_create_module(db, "tcl", &tclModule, (void *)interp);
          538  +#endif
          539  +  return TCL_OK;
          540  +}
          541  +
          542  +#endif
          543  +
          544  +
          545  +/*
          546  +** Register commands with the TCL interpreter.
          547  +*/
          548  +int Sqlitetesttcl_Init(Tcl_Interp *interp){
          549  +#ifndef SQLITE_OMIT_VIRTUALTABLE
          550  +  static struct {
          551  +     char *zName;
          552  +     Tcl_ObjCmdProc *xProc;
          553  +     void *clientData;
          554  +  } aObjCmd[] = {
          555  +     { "register_tcl_module",   register_tcl_module, 0 },
          556  +  };
          557  +  int i;
          558  +  for(i=0; i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){
          559  +    Tcl_CreateObjCommand(interp, aObjCmd[i].zName, 
          560  +        aObjCmd[i].xProc, aObjCmd[i].clientData, 0);
          561  +  }
          562  +#endif
          563  +  return TCL_OK;
          564  +}

Changes to src/test_config.c.

   372    372   
   373    373   #ifdef SQLITE_ENABLE_FTS3
   374    374     Tcl_SetVar2(interp, "sqlite_options", "fts3", "1", TCL_GLOBAL_ONLY);
   375    375   #else
   376    376     Tcl_SetVar2(interp, "sqlite_options", "fts3", "0", TCL_GLOBAL_ONLY);
   377    377   #endif
   378    378   
   379         -#ifdef SQLITE_ENABLE_FTS3_TOKENIZER
   380         -  Tcl_SetVar2(interp, "sqlite_options", "fts3_tokenizer", "1", TCL_GLOBAL_ONLY);
   381         -#else
   382         -  Tcl_SetVar2(interp, "sqlite_options", "fts3_tokenizer", "0", TCL_GLOBAL_ONLY);
   383         -#endif
   384         -
   385    379   #ifdef SQLITE_ENABLE_FTS5
   386    380     Tcl_SetVar2(interp, "sqlite_options", "fts5", "1", TCL_GLOBAL_ONLY);
   387    381   #else
   388    382     Tcl_SetVar2(interp, "sqlite_options", "fts5", "0", TCL_GLOBAL_ONLY);
   389    383   #endif
   390    384   
   391    385   #if defined(SQLITE_ENABLE_FTS3) && !defined(SQLITE_DISABLE_FTS3_UNICODE)

Changes to src/treeview.c.

   334    334   
   335    335       case TK_UMINUS:  zUniOp = "UMINUS"; break;
   336    336       case TK_UPLUS:   zUniOp = "UPLUS";  break;
   337    337       case TK_BITNOT:  zUniOp = "BITNOT"; break;
   338    338       case TK_NOT:     zUniOp = "NOT";    break;
   339    339       case TK_ISNULL:  zUniOp = "ISNULL"; break;
   340    340       case TK_NOTNULL: zUniOp = "NOTNULL"; break;
          341  +
          342  +    case TK_SPAN: {
          343  +      sqlite3TreeViewLine(pView, "SPAN %Q", pExpr->u.zToken);
          344  +      sqlite3TreeViewExpr(pView, pExpr->pLeft, 0);
          345  +      break;
          346  +    }
   341    347   
   342    348       case TK_COLLATE: {
   343    349         sqlite3TreeViewLine(pView, "COLLATE %Q", pExpr->u.zToken);
   344    350         sqlite3TreeViewExpr(pView, pExpr->pLeft, 0);
   345    351         break;
   346    352       }
   347    353   

Changes to src/util.c.

   104    104   ** than the actual length of the string.  For very long strings (greater
   105    105   ** than 1GiB) the value returned might be less than the true string length.
   106    106   */
   107    107   int sqlite3Strlen30(const char *z){
   108    108     if( z==0 ) return 0;
   109    109     return 0x3fffffff & (int)strlen(z);
   110    110   }
          111  +
          112  +/*
          113  +** The string z[] is followed immediately by another string.  Return
          114  +** a poiner to that other string.
          115  +*/
          116  +const char *sqlite3StrNext(const char *z){
          117  +  return z + strlen(z) + 1;
          118  +}
   111    119   
   112    120   /*
   113    121   ** Set the current error code to err_code and clear any prior error message.
   114    122   */
   115    123   void sqlite3Error(sqlite3 *db, int err_code){
   116    124     assert( db!=0 );
   117    125     db->errCode = err_code;
................................................................................
  1396   1404     if( x<=2000000000 ) return sqlite3LogEst((u64)x);
  1397   1405     memcpy(&a, &x, 8);
  1398   1406     e = (a>>52) - 1022;
  1399   1407     return e*10;
  1400   1408   }
  1401   1409   #endif /* SQLITE_OMIT_VIRTUALTABLE */
  1402   1410   
         1411  +#if defined(SQLITE_ENABLE_STMT_SCANSTAT) || \
         1412  +    defined(SQLITE_ENABLE_STAT3_OR_STAT4) || \
         1413  +    defined(SQLITE_EXPLAIN_ESTIMATED_ROWS)
  1403   1414   /*
  1404   1415   ** Convert a LogEst into an integer.
         1416  +**
         1417  +** Note that this routine is only used when one or more of various
         1418  +** non-standard compile-time options is enabled.
  1405   1419   */
  1406   1420   u64 sqlite3LogEstToInt(LogEst x){
  1407   1421     u64 n;
  1408   1422     if( x<10 ) return 1;
  1409   1423     n = x%10;
  1410   1424     x /= 10;
  1411   1425     if( n>=5 ) n -= 2;
  1412   1426     else if( n>=1 ) n -= 1;
  1413   1427     if( x>=3 ){
  1414   1428       return x>60 ? (u64)LARGEST_INT64 : (n+8)<<(x-3);
  1415   1429     }
  1416   1430     return (n+8)>>(3-x);
  1417   1431   }
         1432  +#endif /* defined SCANSTAT or STAT4 or ESTIMATED_ROWS */

Changes to src/vdbeInt.h.

    83     83     u8 isTable;           /* True for rowid tables.  False for indexes */
    84     84   #ifdef SQLITE_DEBUG
    85     85     u8 seekOp;            /* Most recent seek operation on this cursor */
    86     86     u8 wrFlag;            /* The wrFlag argument to sqlite3BtreeCursor() */
    87     87   #endif
    88     88     Bool isEphemeral:1;   /* True for an ephemeral table */
    89     89     Bool useRandomRowid:1;/* Generate new record numbers semi-randomly */
    90         -  Bool isOrdered:1;     /* True if the underlying table is BTREE_UNORDERED */
           90  +  Bool isOrdered:1;     /* True if the table is not BTREE_UNORDERED */
    91     91     Pgno pgnoRoot;        /* Root page of the open btree cursor */
    92     92     i16 nField;           /* Number of fields in the header */
    93     93     u16 nHdrParsed;       /* Number of header fields parsed so far */
    94     94     union {
    95     95       BtCursor *pCursor;          /* CURTYPE_BTREE.  Btree cursor */
    96     96       sqlite3_vtab_cursor *pVCur; /* CURTYPE_VTAB.   Vtab cursor */
    97     97       int pseudoTableReg;         /* CURTYPE_PSEUDO. Reg holding content. */

Changes to src/vdbemem.c.

  1277   1277     const char *zNeg = "";
  1278   1278     int rc = SQLITE_OK;
  1279   1279   
  1280   1280     if( !pExpr ){
  1281   1281       *ppVal = 0;
  1282   1282       return SQLITE_OK;
  1283   1283     }
  1284         -  while( (op = pExpr->op)==TK_UPLUS ) pExpr = pExpr->pLeft;
         1284  +  while( (op = pExpr->op)==TK_UPLUS || op==TK_SPAN ) pExpr = pExpr->pLeft;
  1285   1285     if( NEVER(op==TK_REGISTER) ) op = pExpr->op2;
  1286   1286   
  1287   1287     /* Compressed expressions only appear when parsing the DEFAULT clause
  1288   1288     ** on a table column definition, and hence only when pCtx==0.  This
  1289   1289     ** check ensures that an EP_TokenOnly expression is never passed down
  1290   1290     ** into valueFromFunction(). */
  1291   1291     assert( (pExpr->flags & EP_TokenOnly)==0 || pCtx==0 );

Changes to src/vtab.c.

   560    560         ** columns of the table to see if any of them contain the token "hidden".
   561    561         ** If so, set the Column COLFLAG_HIDDEN flag and remove the token from
   562    562         ** the type string.  */
   563    563         pVTable->pNext = pTab->pVTable;
   564    564         pTab->pVTable = pVTable;
   565    565   
   566    566         for(iCol=0; iCol<pTab->nCol; iCol++){
   567         -        char *zType = pTab->aCol[iCol].zType;
          567  +        char *zType = (char*)sqlite3StrNext(pTab->aCol[iCol].zName);
   568    568           int nType;
   569    569           int i = 0;
   570         -        if( !zType ){
          570  +        if( !zType[0] ){
   571    571             pTab->tabFlags |= oooHidden;
   572    572             continue;
   573    573           }
   574    574           nType = sqlite3Strlen30(zType);
   575    575           if( sqlite3StrNICmp("hidden", zType, 6)||(zType[6] && zType[6]!=' ') ){
   576    576             for(i=0; i<nType; i++){
   577    577               if( (0==sqlite3StrNICmp(" hidden", &zType[i], 7))

Changes to src/where.c.

  1557   1557     rc = sqlite3Stat4ProbeSetValue(pParse, p, &pRec, pExpr, aff, nEq-1, &bOk);
  1558   1558     pBuilder->pRec = pRec;
  1559   1559     if( rc!=SQLITE_OK ) return rc;
  1560   1560     if( bOk==0 ) return SQLITE_NOTFOUND;
  1561   1561     pBuilder->nRecValid = nEq;
  1562   1562   
  1563   1563     whereKeyStats(pParse, p, pRec, 0, a);
  1564         -  WHERETRACE(0x10,("equality scan regions: %d\n", (int)a[1]));
         1564  +  WHERETRACE(0x10,("equality scan regions %s(%d): %d\n",
         1565  +                   p->zName, nEq-1, (int)a[1]));
  1565   1566     *pnRow = a[1];
  1566   1567     
  1567   1568     return rc;
  1568   1569   }
  1569   1570   #endif /* SQLITE_ENABLE_STAT3_OR_STAT4 */
  1570   1571   
  1571   1572   #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
................................................................................
  2893   2894           assert( iTerm<pNew->nLSlot );
  2894   2895           pNew->aLTerm[iTerm] = pTerm;
  2895   2896           if( iTerm>mxTerm ) mxTerm = iTerm;
  2896   2897           testcase( iTerm==15 );
  2897   2898           testcase( iTerm==16 );
  2898   2899           if( iTerm<16 && pUsage[i].omit ) pNew->u.vtab.omitMask |= 1<<iTerm;
  2899   2900           if( (pTerm->eOperator & WO_IN)!=0 ){
  2900         -          if( pUsage[i].omit==0 ){
  2901         -            /* Do not attempt to use an IN constraint if the virtual table
  2902         -            ** says that the equivalent EQ constraint cannot be safely omitted.
  2903         -            ** If we do attempt to use such a constraint, some rows might be
  2904         -            ** repeated in the output. */
  2905         -            break;
  2906         -          }
  2907   2901             /* A virtual table that is constrained by an IN clause may not
  2908   2902             ** consume the ORDER BY clause because (1) the order of IN terms
  2909   2903             ** is not necessarily related to the order of output terms and
  2910   2904             ** (2) Multiple outputs from a single IN value will not merge
  2911   2905             ** together.  */
  2912   2906             pIdxInfo->orderByConsumed = 0;
  2913   2907             pIdxInfo->idxFlags &= ~SQLITE_INDEX_SCAN_UNIQUE;
................................................................................
  3459   3453     LogEst rScale, rSortCost;
  3460   3454     assert( nOrderBy>0 && 66==sqlite3LogEst(100) );
  3461   3455     rScale = sqlite3LogEst((nOrderBy-nSorted)*100/nOrderBy) - 66;
  3462   3456     rSortCost = nRow + rScale + 16;
  3463   3457   
  3464   3458     /* Multiple by log(M) where M is the number of output rows.
  3465   3459     ** Use the LIMIT for M if it is smaller */
  3466         -  if( (pWInfo->wctrlFlags & WHERE_USE_LIMIT)!=0 ){
  3467         -    LogEst m = sqlite3LogEst(pWInfo->iLimit);
  3468         -    if( m<nRow ) nRow = m;
         3460  +  if( (pWInfo->wctrlFlags & WHERE_USE_LIMIT)!=0 && pWInfo->iLimit<nRow ){
         3461  +    nRow = pWInfo->iLimit;
  3469   3462     }
  3470   3463     rSortCost += estLog(nRow);
  3471   3464     return rSortCost;
  3472   3465   }
  3473   3466   
  3474   3467   /*
  3475   3468   ** Given the list of WhereLoop objects at pWInfo->pLoops, this routine

Changes to src/wherecode.c.

   870    870     if(  (pLoop->wsFlags & WHERE_VIRTUALTABLE)!=0 ){
   871    871       /* Case 1:  The table is a virtual-table.  Use the VFilter and VNext
   872    872       **          to access the data.
   873    873       */
   874    874       int iReg;   /* P3 Value for OP_VFilter */
   875    875       int addrNotFound;
   876    876       int nConstraint = pLoop->nLTerm;
          877  +    int iIn;    /* Counter for IN constraints */
   877    878   
   878    879       sqlite3ExprCachePush(pParse);
   879    880       iReg = sqlite3GetTempRange(pParse, nConstraint+2);
   880    881       addrNotFound = pLevel->addrBrk;
   881    882       for(j=0; j<nConstraint; j++){
   882    883         int iTarget = iReg+j+2;
   883    884         pTerm = pLoop->aLTerm[j];
................................................................................
   892    893       sqlite3VdbeAddOp2(v, OP_Integer, pLoop->u.vtab.idxNum, iReg);
   893    894       sqlite3VdbeAddOp2(v, OP_Integer, nConstraint, iReg+1);
   894    895       sqlite3VdbeAddOp4(v, OP_VFilter, iCur, addrNotFound, iReg,
   895    896                         pLoop->u.vtab.idxStr,
   896    897                         pLoop->u.vtab.needFree ? P4_MPRINTF : P4_STATIC);
   897    898       VdbeCoverage(v);
   898    899       pLoop->u.vtab.needFree = 0;
   899         -    for(j=0; j<nConstraint && j<16; j++){
   900         -      if( (pLoop->u.vtab.omitMask>>j)&1 ){
   901         -        disableTerm(pLevel, pLoop->aLTerm[j]);
   902         -      }
   903         -    }
   904    900       pLevel->p1 = iCur;
   905    901       pLevel->op = pWInfo->eOnePass ? OP_Noop : OP_VNext;
   906    902       pLevel->p2 = sqlite3VdbeCurrentAddr(v);
          903  +    iIn = pLevel->u.in.nIn;
          904  +    for(j=nConstraint-1; j>=0; j--){
          905  +      pTerm = pLoop->aLTerm[j];
          906  +      if( j<16 && (pLoop->u.vtab.omitMask>>j)&1 ){
          907  +        disableTerm(pLevel, pTerm);
          908  +      }else if( (pTerm->eOperator & WO_IN)!=0 ){
          909  +        Expr *pCompare;  /* The comparison operator */
          910  +        Expr *pRight;    /* RHS of the comparison */
          911  +        VdbeOp *pOp;     /* Opcode to access the value of the IN constraint */
          912  +
          913  +        /* Reload the constraint value into reg[iReg+j+2].  The same value
          914  +        ** was loaded into the same register prior to the OP_VFilter, but
          915  +        ** the xFilter implementation might have changed the datatype or
          916  +        ** encoding of the value in the register, so it *must* be reloaded. */
          917  +        assert( pLevel->u.in.aInLoop!=0 || db->mallocFailed );
          918  +        if( pLevel->u.in.aInLoop!=0 ){
          919  +          assert( iIn>0 );
          920  +          pOp = sqlite3VdbeGetOp(v, pLevel->u.in.aInLoop[--iIn].addrInTop);
          921  +          assert( pOp->opcode==OP_Column || pOp->opcode==OP_Rowid );
          922  +          assert( pOp->opcode!=OP_Column || pOp->p3==iReg+j+2 );
          923  +          assert( pOp->opcode!=OP_Rowid || pOp->p2==iReg+j+2 );
          924  +          testcase( pOp->opcode==OP_Rowid );
          925  +          sqlite3VdbeAddOp3(v, pOp->opcode, pOp->p1, pOp->p2, pOp->p3);
          926  +        }
          927  +
          928  +        /* Generate code that will continue to the next row if 
          929  +        ** the IN constraint is not satisfied */
          930  +        pCompare = sqlite3PExpr(pParse, TK_EQ, 0, 0, 0);
          931  +        assert( pCompare!=0 || db->mallocFailed );
          932  +        if( pCompare ){
          933  +          pCompare->pLeft = pTerm->pExpr->pLeft;
          934  +          pCompare->pRight = pRight = sqlite3Expr(db, TK_REGISTER, 0);
          935  +          if( pRight ) pRight->iTable = iReg+j+2;
          936  +          sqlite3ExprIfFalse(pParse, pCompare, pLevel->addrCont, 0);
          937  +          pCompare->pLeft = 0;
          938  +          sqlite3ExprDelete(db, pCompare);
          939  +        }
          940  +      }
          941  +    }
   907    942       sqlite3ReleaseTempRange(pParse, iReg, nConstraint+2);
   908    943       sqlite3ExprCachePop(pParse);
   909    944     }else
   910    945   #endif /* SQLITE_OMIT_VIRTUALTABLE */
   911    946   
   912    947     if( (pLoop->wsFlags & WHERE_IPK)!=0
   913    948      && (pLoop->wsFlags & (WHERE_COLUMN_IN|WHERE_COLUMN_EQ))!=0

Changes to test/analyze9.test.

  1176   1176   #
  1177   1177   # And it should be. The analyzer has a stat4 sample as follows:
  1178   1178   #
  1179   1179   #   sample=(x=10000, y=100) nLt=(10000 10099)
  1180   1180   #
  1181   1181   # There should be no other samples that start with (x=10000). So it knows 
  1182   1182   # that (x=10000 AND y<50) must match somewhere between 0 and 99 rows, but
  1183         -# know more than that. Guessing less than 20 is therefore unreasonable.
         1183  +# no more than that. Guessing less than 20 is therefore unreasonable.
  1184   1184   #
  1185   1185   # At one point though, due to a problem in whereKeyStats(), the planner was
  1186   1186   # estimating that (x=10000 AND y<50) would match only 2 rows.
  1187   1187   #
  1188   1188   do_eqp_test 26.1.4 {
  1189   1189     SELECT * FROM t1 WHERE x = 10000 AND y < 50 AND z = 444;
  1190   1190   } {

Changes to test/analyzeD.test.

     1         -# 2005 July 22
            1  +# 2014-10-04
     2      2   #
     3      3   # The author disclaims copyright to this source code.  In place of
     4      4   # a legal notice, here is a blessing:
     5      5   #
     6      6   #    May you do good and not evil.
     7      7   #    May you find forgiveness for yourself and forgive others.
     8      8   #    May you share freely, never taking more than you give.
     9      9   #
    10     10   #***********************************************************************
    11     11   # This file implements regression tests for SQLite library.
    12     12   # This file implements tests for the ANALYZE command.
    13     13   #
    14         -# $Id: analyze.test,v 1.9 2008/08/11 18:44:58 drh Exp $
    15     14   
    16     15   set testdir [file dirname $argv0]
    17     16   source $testdir/tester.tcl
    18     17   set ::testprefix analyzeD
    19     18   
    20     19   ifcapable {!stat4} {
    21     20     finish_test
................................................................................
    71     70   do_test 1.3 {
    72     71     execsql { DELETE FROM sqlite_stat1 }
    73     72     db close
    74     73     sqlite3 db test.db
    75     74   } {}
    76     75   
    77     76   # Without stat1, because 3001 is larger than all samples in the stat4
    78         -# table, SQLite things that a=3001 matches just 1 row. So it (incorrectly)
           77  +# table, SQLite thinks that a=3001 matches just 1 row. So it (incorrectly)
    79     78   # chooses it over the c=150 index (5 rows). Even with stat1 data, things
    80     79   # worked this way before commit [e6f7f97dbc].
    81     80   #
    82     81   do_eqp_test 1.4 {
    83     82     SELECT * FROM t1 WHERE a=3001 AND c=150;
    84     83   } {
    85     84     0 0 0 {SEARCH TABLE t1 USING INDEX t1_ab (a=?)}

Added test/bestindex1.test.

            1  +# 2016-03-01
            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  +# 
           12  +#
           13  +
           14  +set testdir [file dirname $argv0]
           15  +source $testdir/tester.tcl
           16  +set testprefix bestindex1
           17  +
           18  +register_tcl_module db
           19  +
           20  +proc vtab_command {method args} {
           21  +  switch -- $method {
           22  +    xConnect {
           23  +      return "CREATE TABLE t1(a, b, c)"
           24  +    }
           25  +
           26  +    xBestIndex {
           27  +      set clist [lindex $args 0]
           28  +      if {[llength $clist]!=1} { error "unexpected constraint list" }
           29  +      catch { array unset C }
           30  +      array set C [lindex $clist 0]
           31  +      if {$C(usable)} {
           32  +        return "omit 0 cost 0 rows 1 idxnum 555 idxstr eq!"
           33  +      } else {
           34  +        return "cost 1000000 rows 0 idxnum 0 idxstr scan..."
           35  +      }
           36  +    }
           37  +
           38  +  }
           39  +
           40  +  return {}
           41  +}
           42  +
           43  +do_execsql_test 1.0 {
           44  +  CREATE VIRTUAL TABLE x1 USING tcl(vtab_command);
           45  +} {}
           46  +
           47  +do_eqp_test 1.1 {
           48  +  SELECT * FROM x1 WHERE a = 'abc'
           49  +} {
           50  +  0 0 0 {SCAN TABLE x1 VIRTUAL TABLE INDEX 555:eq!}
           51  +}
           52  +
           53  +do_eqp_test 1.2 {
           54  +  SELECT * FROM x1 WHERE a IN ('abc', 'def');
           55  +} {
           56  +  0 0 0 {SCAN TABLE x1 VIRTUAL TABLE INDEX 555:eq!}
           57  +  0 0 0 {EXECUTE LIST SUBQUERY 1}
           58  +}
           59  +
           60  +#-------------------------------------------------------------------------
           61  +#
           62  +reset_db
           63  +register_tcl_module db
           64  +
           65  +# Parameter $mode may be one of:
           66  +#
           67  +#   "omit" - Implement filtering. Set the omit flag.
           68  +#   "use"  - Implement filtering. Use the constraint, but do not set omit.
           69  +#   "use2" - Do not implement filtering. Use the constraint anyway.
           70  +#
           71  +#   
           72  +proc t1_vtab {mode method args} {
           73  +  switch -- $method {
           74  +    xConnect {
           75  +      return "CREATE TABLE t1(a, b)"
           76  +    }
           77  +
           78  +    xBestIndex {
           79  +      set SQL_FILTER {SELECT * FROM t1x WHERE a='%1%'}
           80  +      set SQL_SCAN   {SELECT * FROM t1x}
           81  +
           82  +      set clist [lindex $args 0]
           83  +      set idx 0
           84  +      for {set idx 0} {$idx < [llength $clist]} {incr idx} {
           85  +        array unset C
           86  +        array set C [lindex $clist $idx]
           87  +        if {$C(column)==0 && $C(op)=="eq" && $C(usable)} {
           88  +          switch -- $mode {
           89  +            "omit" {
           90  +              return [list omit $idx rows 10 cost 10 idxstr $SQL_FILTER]
           91  +            }
           92  +            "use" {
           93  +              return [list use $idx rows 10 cost 10 idxstr $SQL_FILTER]
           94  +            }
           95  +            "use2" {
           96  +              return [list use $idx rows 10 cost 10 idxstr $SQL_SCAN]
           97  +            }
           98  +            default {
           99  +              error "Bad mode - $mode"
          100  +            }
          101  +          }
          102  +        }
          103  +      }
          104  +
          105  +      return [list idxstr {SELECT * FROM t1x}]
          106  +    }
          107  +
          108  +    xFilter {
          109  +      set map [list %1% [lindex $args 2 0]]
          110  +      set sql [string map $map [lindex $args 1]]
          111  +      return [list sql $sql]
          112  +    }
          113  +  }
          114  +
          115  +  return {}
          116  +}
          117  +
          118  +do_execsql_test 2.1 {
          119  +  CREATE TABLE t1x(i INTEGER PRIMARY KEY, a, b);
          120  +  INSERT INTO t1x VALUES(1, 'one', 1);
          121  +  INSERT INTO t1x VALUES(2, 'two', 2);
          122  +  INSERT INTO t1x VALUES(3, 'three', 3);
          123  +  INSERT INTO t1x VALUES(4, 'four', 4);
          124  +}
          125  +
          126  +foreach {tn mode} {
          127  +  1 use 2 omit 3 use2
          128  +} {
          129  +  do_execsql_test 2.2.$mode.1 "
          130  +    DROP TABLE IF EXISTS t1;
          131  +    CREATE VIRTUAL TABLE t1 USING tcl(t1_vtab $mode);
          132  +  "
          133  +
          134  +  do_execsql_test 2.2.$mode.2 {SELECT * FROM t1} {one 1 two 2 three 3 four 4}
          135  +  do_execsql_test 2.2.$mode.3 {SELECT rowid FROM t1} {1 2 3 4}
          136  +  do_execsql_test 2.2.$mode.4 {SELECT rowid FROM t1 WHERE a='two'} {2} 
          137  +
          138  +  do_execsql_test 2.2.$mode.5 {
          139  +    SELECT rowid FROM t1 WHERE a IN ('one', 'four') ORDER BY +rowid
          140  +  } {1 4} 
          141  +
          142  +  set plan(use) {
          143  +    0 0 0 {SCAN TABLE t1 VIRTUAL TABLE INDEX 0:SELECT * FROM t1x WHERE a='%1%'}
          144  +    0 0 0 {EXECUTE LIST SUBQUERY 1}
          145  +    0 0 0 {USE TEMP B-TREE FOR ORDER BY}
          146  +  }
          147  +  set plan(omit) {
          148  +    0 0 0 {SCAN TABLE t1 VIRTUAL TABLE INDEX 0:SELECT * FROM t1x WHERE a='%1%'}
          149  +    0 0 0 {EXECUTE LIST SUBQUERY 1}
          150  +    0 0 0 {USE TEMP B-TREE FOR ORDER BY}
          151  +  }
          152  +  set plan(use2) {
          153  +    0 0 0 {SCAN TABLE t1 VIRTUAL TABLE INDEX 0:SELECT * FROM t1x}
          154  +    0 0 0 {EXECUTE LIST SUBQUERY 1}
          155  +    0 0 0 {USE TEMP B-TREE FOR ORDER BY}
          156  +  }
          157  +
          158  +  do_eqp_test 2.2.$mode.6 { 
          159  +    SELECT rowid FROM t1 WHERE a IN ('one', 'four') ORDER BY +rowid
          160  +  } $plan($mode)
          161  +}
          162  +
          163  +finish_test
          164  +
          165  +

Changes to test/conflict.test.

   281    281   #   cmd    An UPDATE command to execute against table t1
   282    282   #   t0     True if there is an error from $cmd
   283    283   #   t1     Content of "b" column of t1 assuming no error in $cmd
   284    284   #   t2     Content of "x" column of t3
   285    285   #   t3     Number of temporary files for tables
   286    286   #   t4     Number of temporary files for statement journals
   287    287   #
   288         -# Update: Since temporary table files are now opened lazily, and none
   289         -# of the following tests use large quantities of data, t3 is always 0.
          288  +# Update (2007-08-21): Since temporary table files are now opened lazily, 
          289  +# and none of the following tests use large quantities of data, t3 is always 0.
          290  +#
          291  +# Update (2016-03-04): Subjournals now also open lazily, so t4 is also always 0.
   290    292   #
   291    293   foreach {i conf1 cmd t0 t1 t2 t3 t4} {
   292         -  1 {}       UPDATE                  1 {6 7 8 9}  1 0 1
          294  +  1 {}       UPDATE                  1 {6 7 8 9}  1 0 0
   293    295     2 REPLACE  UPDATE                  0 {7 6 9}    1 0 0
   294    296     3 IGNORE   UPDATE                  0 {6 7 3 9}  1 0 0
   295    297     4 FAIL     UPDATE                  1 {6 7 3 4}  1 0 0
   296         -  5 ABORT    UPDATE                  1 {1 2 3 4}  1 0 1
          298  +  5 ABORT    UPDATE                  1 {1 2 3 4}  1 0 0
   297    299     6 ROLLBACK UPDATE                  1 {1 2 3 4}  0 0 0
   298    300     7 REPLACE  {UPDATE OR IGNORE}      0 {6 7 3 9}  1 0 0
   299    301     8 IGNORE   {UPDATE OR REPLACE}     0 {7 6 9}    1 0 0
   300    302     9 FAIL     {UPDATE OR IGNORE}      0 {6 7 3 9}  1 0 0
   301    303    10 ABORT    {UPDATE OR REPLACE}     0 {7 6 9}    1 0 0
   302    304    11 ROLLBACK {UPDATE OR IGNORE}      0 {6 7 3 9}  1 0 0
   303    305    12 {}       {UPDATE OR IGNORE}      0 {6 7 3 9}  1 0 0
   304    306    13 {}       {UPDATE OR REPLACE}     0 {7 6 9}    1 0 0
   305    307    14 {}       {UPDATE OR FAIL}        1 {6 7 3 4}  1 0 0
   306         - 15 {}       {UPDATE OR ABORT}       1 {1 2 3 4}  1 0 1
          308  + 15 {}       {UPDATE OR ABORT}       1 {1 2 3 4}  1 0 0
   307    309    16 {}       {UPDATE OR ROLLBACK}    1 {1 2 3 4}  0 0 0
   308    310   } {
   309    311     if {$t0} {set t1 {UNIQUE constraint failed: t1.a}}
   310    312     if {[info exists TEMP_STORE] && $TEMP_STORE==3} {
   311    313       set t3 0
   312    314     } else {
   313    315       set t3 [expr {$t3+$t4}]

Changes to test/conflict2.test.

   282    282   #   t1     Content of "b" column of t1 assuming no error in $cmd
   283    283   #   t2     Content of "x" column of t3
   284    284   #   t3     Number of temporary files for tables
   285    285   #   t4     Number of temporary files for statement journals
   286    286   #
   287    287   # Update: Since temporary table files are now opened lazily, and none
   288    288   # of the following tests use large quantities of data, t3 is always 0.
          289  +#
          290  +# Update (2016-03-04): Subjournals now only open when their size
          291  +# exceeds 64KB.
   289    292   #
   290    293   foreach {i conf1 cmd t0 t1 t2 t3 t4} {
   291         -  1 {}       UPDATE                  1 {6 7 8 9}  1 0 1
   292         -  2 REPLACE  UPDATE                  0 {7 6 9}    1 0 1
   293         -  3 IGNORE   UPDATE                  0 {6 7 3 9}  1 0 1
   294         -  4 FAIL     UPDATE                  1 {6 7 3 4}  1 0 1
   295         -  5 ABORT    UPDATE                  1 {1 2 3 4}  1 0 1
   296         -  6 ROLLBACK UPDATE                  1 {1 2 3 4}  0 0 1
          294  +  1 {}       UPDATE                  1 {6 7 8 9}  1 0 0
          295  +  2 REPLACE  UPDATE                  0 {7 6 9}    1 0 0
          296  +  3 IGNORE   UPDATE                  0 {6 7 3 9}  1 0 0
          297  +  4 FAIL     UPDATE                  1 {6 7 3 4}  1 0 0
          298  +  5 ABORT    UPDATE                  1 {1 2 3 4}  1 0 0
          299  +  6 ROLLBACK UPDATE                  1 {1 2 3 4}  0 0 0
   297    300     7 REPLACE  {UPDATE OR IGNORE}      0 {6 7 3 9}  1 0 0
   298         -  8 IGNORE   {UPDATE OR REPLACE}     0 {7 6 9}    1 0 1
          301  +  8 IGNORE   {UPDATE OR REPLACE}     0 {7 6 9}    1 0 0
   299    302     9 FAIL     {UPDATE OR IGNORE}      0 {6 7 3 9}  1 0 0
   300         - 10 ABORT    {UPDATE OR REPLACE}     0 {7 6 9}    1 0 1
          303  + 10 ABORT    {UPDATE OR REPLACE}     0 {7 6 9}    1 0 0
   301    304    11 ROLLBACK {UPDATE OR IGNORE}      0 {6 7 3 9}  1 0 0
   302    305    12 {}       {UPDATE OR IGNORE}      0 {6 7 3 9}  1 0 0
   303         - 13 {}       {UPDATE OR REPLACE}     0 {7 6 9}    1 0 1
          306  + 13 {}       {UPDATE OR REPLACE}     0 {7 6 9}    1 0 0
   304    307    14 {}       {UPDATE OR FAIL}        1 {6 7 3 4}  1 0 0
   305         - 15 {}       {UPDATE OR ABORT}       1 {1 2 3 4}  1 0 1
          308  + 15 {}       {UPDATE OR ABORT}       1 {1 2 3 4}  1 0 0
   306    309    16 {}       {UPDATE OR ROLLBACK}    1 {1 2 3 4}  0 0 0
   307    310   } {
   308    311   
   309    312     # When using in-memory journals, no temporary files are required for
   310    313     # statement journals.
   311    314     if {[permutation] == "inmemory_journal"} { set t4 0 }
   312    315   

Changes to test/e_walhook.test.

   157    157   do_test 5.2 {
   158    158     execsql { INSERT INTO t1 VALUES(11) }
   159    159     set ::old_wal_hook
   160    160   } {1}
   161    161   
   162    162   
   163    163   
   164         -# EVIDENCE-OF: R-42842-27162 Note that the sqlite3_wal_autocheckpoint()
          164  +# EVIDENCE-OF: R-57445-43425 Note that the sqlite3_wal_autocheckpoint()
   165    165   # interface and the wal_autocheckpoint pragma both invoke
   166         -# sqlite3_wal_hook() and will those overwrite any prior
   167         -# sqlite3_wal_hook() settings.
          166  +# sqlite3_wal_hook() and will overwrite any prior sqlite3_wal_hook()
          167  +# settings.
   168    168   #
   169    169   set ::old_wal_hook 0
   170    170   proc my_old_wal_hook {args} { incr ::old_wal_hook ; return 0 }
   171    171   db wal_hook my_old_wal_hook
   172    172   do_test 6.1.1 {
   173    173     execsql { INSERT INTO t1 VALUES(12) }
   174    174     set ::old_wal_hook

Changes to test/exclusive.test.

   416    416       BEGIN;
   417    417       INSERT INTO abc VALUES(1, 2, 3);
   418    418       INSERT INTO abc SELECT a+1, b+1, c+1 FROM abc;
   419    419     }
   420    420   } {}
   421    421   do_test exclusive-5.1 {
   422    422     # Three files are open: The db, journal and statement-journal.
          423  +  # (2016-03-04) The statement-journal is now opened lazily
   423    424     set sqlite_open_file_count
   424    425     expr $sqlite_open_file_count-$extrafds
   425         -} [expr 3 - ($TEMP_STORE>=2)]
          426  +} [expr 2 - ($TEMP_STORE>=2)]
   426    427   do_test exclusive-5.2 {
   427    428     execsql {
   428    429       COMMIT;
   429    430     }
   430    431     # One file open: the db.
   431    432     set sqlite_open_file_count
   432    433     expr $sqlite_open_file_count-$extrafds
................................................................................
   442    443     expr $sqlite_open_file_count-$extrafds
   443    444   } {2}
   444    445   do_test exclusive-5.4 {
   445    446     execsql {
   446    447       INSERT INTO abc SELECT a+10, b+10, c+10 FROM abc;
   447    448     }
   448    449     # Three files are open: The db, journal and statement-journal.
          450  +  # 2016-03-04: The statement-journal open is deferred
   449    451     set sqlite_open_file_count
   450    452     expr $sqlite_open_file_count-$extrafds
   451         -} [expr 3 - ($TEMP_STORE>=2)]
          453  +} [expr 2 - ($TEMP_STORE>=2)]
   452    454   do_test exclusive-5.5 {
   453    455     execsql {
   454    456       COMMIT;
   455    457     }
   456    458     # Three files are still open: The db, journal and statement-journal.
          459  +  # 2016-03-04: The statement-journal open is deferred
   457    460     set sqlite_open_file_count
   458    461     expr $sqlite_open_file_count-$extrafds
   459         -} [expr 3 - ($TEMP_STORE>=2)]
          462  +} [expr 2 - ($TEMP_STORE>=2)]
   460    463   do_test exclusive-5.6 {
   461    464     execsql {
   462    465       PRAGMA locking_mode = normal;
   463    466       SELECT * FROM abc;
   464    467     }
   465    468   } {normal 1 2 3 2 3 4 5 6 7 11 12 13 12 13 14 15 16 17}
   466    469   do_test exclusive-5.7 {

Changes to test/fts3atoken.test.

    52     52   #      same as that retrieved for 'simple'.
    53     53   #
    54     54   #   4: Test that it is now possible to create an fts3 table using 
    55     55   #      tokenizer 'blah' (it was not possible in step 1).
    56     56   #
    57     57   #   5: Test that the table created to use tokenizer 'blah' is usable.
    58     58   #
    59         -ifcapable fts3_tokenizer {
    60         -  do_test fts3atoken-1.1 {
    61         -    catchsql {
    62         -      CREATE VIRTUAL TABLE t1 USING fts3(content, tokenize blah);
    63         -    }
    64         -  } {1 {unknown tokenizer: blah}}
    65         -  do_test fts3atoken-1.2 {
    66         -    execsql {
    67         -      SELECT fts3_tokenizer('blah', fts3_tokenizer('simple')) IS NULL;
    68         -    }
    69         -  } {0}
    70         -  do_test fts3atoken-1.3 {
    71         -    execsql {
    72         -      SELECT fts3_tokenizer('blah') == fts3_tokenizer('simple');
    73         -    }
    74         -  } {1}
    75         -  do_test fts3atoken-1.4 {
    76         -    catchsql {
    77         -      CREATE VIRTUAL TABLE t1 USING fts3(content, tokenize blah);
    78         -    }
    79         -  } {0 {}}
    80         -  do_test fts3atoken-1.5 {
    81         -    execsql {
    82         -      INSERT INTO t1(content) VALUES('There was movement at the station');
    83         -      INSERT INTO t1(content) VALUES('For the word has passed around');
    84         -      INSERT INTO t1(content) VALUES('That the colt from ol regret had got');
    85         -      SELECT content FROM t1 WHERE content MATCH 'movement'
    86         -    }
    87         -  } {{There was movement at the station}}
    88         -} else {
    89         -  do_catchsql_test 1.6 {
           59  +sqlite3_db_config db SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER 1
           60  +do_test fts3atoken-1.1 {
           61  +  catchsql {
           62  +    CREATE VIRTUAL TABLE t1 USING fts3(content, tokenize blah);
           63  +  }
           64  +} {1 {unknown tokenizer: blah}}
           65  +do_test fts3atoken-1.2 {
           66  +  execsql {
    90     67       SELECT fts3_tokenizer('blah', fts3_tokenizer('simple')) IS NULL;
    91         -  } {1 {fts3tokenize: disabled - rebuild with -DSQLITE_ENABLE_FTS3_TOKENIZER}}
    92         -}
           68  +  }
           69  +} {0}
           70  +do_test fts3atoken-1.3 {
           71  +  execsql {
           72  +    SELECT fts3_tokenizer('blah') == fts3_tokenizer('simple');
           73  +  }
           74  +} {1}
           75  +do_test fts3atoken-1.4 {
           76  +  catchsql {
           77  +    CREATE VIRTUAL TABLE t1 USING fts3(content, tokenize blah);
           78  +  }
           79  +} {0 {}}
           80  +do_test fts3atoken-1.5 {
           81  +  execsql {
           82  +    INSERT INTO t1(content) VALUES('There was movement at the station');
           83  +    INSERT INTO t1(content) VALUES('For the word has passed around');
           84  +    INSERT INTO t1(content) VALUES('That the colt from ol regret had got');
           85  +    SELECT content FROM t1 WHERE content MATCH 'movement'
           86  +  }
           87  +} {{There was movement at the station}}
           88  +
           89  +sqlite3_db_config db SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER 0
           90  +do_catchsql_test 1.6 {
           91  +  SELECT fts3_tokenizer('blah', fts3_tokenizer('simple')) IS NULL;
           92  +} {1 {fts3tokenize disabled}}
           93  +
    93     94   
    94     95   #--------------------------------------------------------------------------
    95     96   # Test cases fts3atoken-2.* test error cases in the scalar function based
    96     97   # API for getting and setting tokenizers.
    97     98   #
    98     99   do_test fts3atoken-2.1 {
    99    100     catchsql {
................................................................................
   208    209   do_catchsql_test 6.1.3 {
   209    210     CREATE VIRTUAL TABLE t3 USING fts4(tokenize="   ");
   210    211   } {1 {unknown tokenizer:    }}
   211    212   
   212    213   do_catchsql_test 6.2.1 {
   213    214     SELECT fts3_tokenizer(NULL);
   214    215   } {1 {unknown tokenizer: }}
   215         -ifcapable fts3_tokenizer {
   216         -  do_catchsql_test 6.2.2 {
   217         -    SELECT fts3_tokenizer(NULL, X'1234567812345678');
   218         -  } {1 {argument type mismatch}}
   219         -  do_catchsql_test 6.2.3 {
   220         -    SELECT fts3_tokenizer(NULL, X'12345678');
   221         -  } {1 {argument type mismatch}}
   222         -}
          216  +
          217  +sqlite3_db_config db SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER 1
          218  +do_catchsql_test 6.2.2 {
          219  +  SELECT fts3_tokenizer(NULL, X'1234567812345678');
          220  +} {1 {argument type mismatch}}
          221  +do_catchsql_test 6.2.3 {
          222  +  SELECT fts3_tokenizer(NULL, X'12345678');
          223  +} {1 {argument type mismatch}}
   223    224   
   224    225   
   225    226   finish_test

Changes to test/fts4langid.test.

   354    354     for {set i 0} {$i < 50} {incr i} {
   355    355       execsql { 
   356    356         INSERT INTO t4(docid, content, lid) VALUES($i, 'The Quick Brown Fox', $i) 
   357    357       }
   358    358     }
   359    359   }
   360    360   
   361         -ifcapable fts3_tokenizer {
   362         -  do_test 4.1.0 {
   363         -    reset_db
   364         -    set ptr [fts3_test_tokenizer]
   365         -    execsql { SELECT fts3_tokenizer('testtokenizer', $ptr) }
   366         -    build_multilingual_db_2 db
   367         -  } {}
   368         -  do_execsql_test 4.1.1 {
   369         -    SELECT docid FROM t4 WHERE t4 MATCH 'quick';
   370         -  } {0}
   371         -  do_execsql_test 4.1.2 {
   372         -    SELECT docid FROM t4 WHERE t4 MATCH 'quick' AND lid=1;
   373         -  } {}
   374         -  do_execsql_test 4.1.3 {
   375         -    SELECT docid FROM t4 WHERE t4 MATCH 'Quick' AND lid=1;
   376         -  } {1}
   377         -  for {set i 0} {$i < 50} {incr i} {
   378         -    do_execsql_test 4.1.4.$i {
   379         -      SELECT count(*) FROM t4 WHERE t4 MATCH 'fox' AND lid=$i;
   380         -    } [expr 0==($i%2)]
   381         -  }
   382         -  do_catchsql_test 4.1.5 {
   383         -    INSERT INTO t4(content, lid) VALUES('hello world', 101)
   384         -  } {1 {SQL logic error or missing database}}
          361  +do_test 4.1.0 {
          362  +  reset_db
          363  +  set ptr [fts3_test_tokenizer]
          364  +  sqlite3_db_config db SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER 1
          365  +  execsql { SELECT fts3_tokenizer('testtokenizer', $ptr) }
          366  +  build_multilingual_db_2 db
          367  +} {}
          368  +do_execsql_test 4.1.1 {
          369  +  SELECT docid FROM t4 WHERE t4 MATCH 'quick';
          370  +} {0}
          371  +do_execsql_test 4.1.2 {
          372  +  SELECT docid FROM t4 WHERE t4 MATCH 'quick' AND lid=1;
          373  +} {}
          374  +do_execsql_test 4.1.3 {
          375  +  SELECT docid FROM t4 WHERE t4 MATCH 'Quick' AND lid=1;
          376  +} {1}
          377  +for {set i 0} {$i < 50} {incr i} {
          378  +  do_execsql_test 4.1.4.$i {
          379  +    SELECT count(*) FROM t4 WHERE t4 MATCH 'fox' AND lid=$i;
          380  +  } [expr 0==($i%2)]
   385    381   }
          382  +do_catchsql_test 4.1.5 {
          383  +  INSERT INTO t4(content, lid) VALUES('hello world', 101)
          384  +} {1 {SQL logic error or missing database}}
   386    385   
   387    386   #-------------------------------------------------------------------------
   388    387   # Test cases 5.*
   389    388   #
   390    389   # The following test cases are designed to detect a 32-bit overflow bug
   391    390   # that existed at one point.
   392    391   #

Changes to test/icu.test.

    67     67   test_expr icu-2.3 {i1=$::EGRAVE} {lower(i1)}     $::egrave
    68     68   test_expr icu-2.4 {i1=$::EGRAVE} {upper(i1)}     $::EGRAVE
    69     69   test_expr icu-2.5 {i1=$::OGRAVE} {lower(i1)}     $::ograve
    70     70   test_expr icu-2.6 {i1=$::OGRAVE} {upper(i1)}     $::OGRAVE
    71     71   
    72     72   test_expr icu-2.7 {i1=$::szlig} {upper(i1)}      "SS"
    73     73   test_expr icu-2.8 {i1='SS'} {lower(i1)}          "ss"
           74  +
           75  +do_execsql_test icu-2.9 {
           76  +  SELECT upper(char(0xfb04,0xfb04,0xfb04,0xfb04));
           77  +} {FFLFFLFFLFFL}
    74     78   
    75     79   # In turkish (locale="tr_TR"), the lower case version of I
    76     80   # is "small dotless i" (code point 0x131 (decimal 305)).
    77     81   #
    78     82   set ::small_dotless_i "\u0131"
    79     83   test_expr icu-3.1 {i1='I'} {lower(i1)}           "i"
    80     84   test_expr icu-3.2 {i1='I'} {lower(i1, 'tr_tr')}  $::small_dotless_i
................................................................................
   129    133   } {1 {wrong number of arguments to function regexp()}}
   130    134   do_catchsql_test icu-5.4 { 
   131    135     SELECT 'abc' REGEXP 'a[abc]c.*'
   132    136   } {0 1}
   133    137   do_catchsql_test icu-5.4 { SELECT 'abc' REGEXP }    {1 {near " ": syntax error}}
   134    138   do_catchsql_test icu-5.5 { SELECT 'abc' REGEXP, 1 } {1 {near ",": syntax error}}
   135    139   
          140  +
          141  +do_malloc_test icu-6.10 -sqlbody {
          142  +  SELECT upper(char(0xfb04,0xdf,0xfb04,0xe8,0xfb04));
          143  +}
          144  +
   136    145   finish_test

Changes to test/misc8.test.

    90     90     0 6 {} 10 {} {} 
    91     91     0 7 {} 10 {} {} 
    92     92     0 8 {} 10 {} {}
    93     93     0 9 {} 10 {} {} 
    94     94     0 10 {} 10 {} {}
    95     95   }
    96     96   
           97  +# 2016-02-26: An assertion fault found by the libFuzzer project
           98  +#
           99  +do_execsql_test misc8-3.0 {
          100  +  SELECT *
          101  +    FROM
          102  +         (
          103  +           (SELECT 0 AS i) AS x1,
          104  +           (SELECT 1) AS x2
          105  +         ) AS x3,
          106  +         (SELECT 6 AS j UNION ALL SELECT 7) AS x4
          107  +   WHERE i<rowid
          108  +   ORDER BY 1;
          109  +} {0 1 6 0 1 7}
    97    110   
    98    111   finish_test

Changes to test/permutations.test.

    82     82   # various test scripts:
    83     83   #
    84     84   #   $alltests
    85     85   #   $allquicktests
    86     86   #
    87     87   set alltests [list]
    88     88   foreach f [glob $testdir/*.test] { lappend alltests [file tail $f] }
    89         -foreach f [glob -nocomplain $testdir/../ext/rtree/*.test] { 
           89  +foreach f [glob -nocomplain       \
           90  +    $testdir/../ext/rtree/*.test  \
           91  +    $testdir/../ext/fts5/test/*.test   \
           92  +] { 
    90     93     lappend alltests $f 
    91     94   }
    92     95   foreach f [glob -nocomplain $testdir/../ext/session/*.test] { 
    93     96     lappend alltests $f 
    94     97   }
    95     98   
    96     99   if {$::tcl_platform(platform)!="unix"} {
................................................................................
   157    160   lappend ::testsuitelist xxx
   158    161   
   159    162   test_suite "veryquick" -prefix "" -description {
   160    163     "Very" quick test suite. Runs in minutes on a workstation.
   161    164     This test suite is the same as the "quick" tests, except that some files
   162    165     that test malloc and IO errors are omitted.
   163    166   } -files [
   164         -  test_set $allquicktests -exclude *malloc* *ioerr* *fault* *bigfile* *_err*
          167  +  test_set $allquicktests -exclude *malloc* *ioerr* *fault* *bigfile* *_err* \
          168  +      *fts5corrupt* *fts5big* *fts5aj*
   165    169   ]
   166    170   
   167    171   test_suite "extraquick" -prefix "" -description {
   168    172     "Extra" quick test suite. Runs in a few minutes on a workstation.
   169    173     This test suite is the same as the "veryquick" tests, except that
   170    174     slower tests are omitted.
   171    175   } -files [
................................................................................
   612    616       memdb.test minmax.test misc1.test misc2.test misc3.test notnull.test
   613    617       null.test progress.test quote.test rowid.test select1.test select2.test
   614    618       select3.test select4.test select5.test select6.test sort.test 
   615    619       subselect.test tableapi.test table.test temptable.test
   616    620       trace.test trigger1.test trigger2.test trigger3.test
   617    621       trigger4.test types2.test types.test unique.test update.test
   618    622       vacuum.test view.test where.test
          623  +    bestindex1.test
   619    624   }
   620    625   
   621    626   # Run some tests in exclusive locking mode.
   622    627   #
   623    628   test_suite "exclusive" -description {
   624    629     Run tests in exclusive locking mode.
   625    630   } -presql {

Changes to test/releasetest.tcl.

   199    199       -DSQLITE_MAX_ATTACHED=62
   200    200     }
   201    201     "Devkit" {
   202    202       -DSQLITE_DEFAULT_FILE_FORMAT=4
   203    203       -DSQLITE_MAX_ATTACHED=30
   204    204       -DSQLITE_ENABLE_COLUMN_METADATA
   205    205       -DSQLITE_ENABLE_FTS4
          206  +    -DSQLITE_ENABLE_FTS5
   206    207       -DSQLITE_ENABLE_FTS4_PARENTHESIS
   207    208       -DSQLITE_DISABLE_FTS4_DEFERRED
   208    209       -DSQLITE_ENABLE_RTREE
   209    210       --enable-json1 --enable-fts5
   210    211     }
   211    212     "No-lookaside" {
   212    213       -DSQLITE_TEST_REALLOC_STRESS=1

Changes to test/shell1.test.

   621    621   } {1 1 1 1 1 1 1 1 1 1}
   622    622   do_test shell1-3.23.2 {
   623    623     # too many arguments
   624    624     catchcmd "test.db" ".show BAD"
   625    625   } {1 {Usage: .show}}
   626    626   
   627    627   # .stats ON|OFF          Turn stats on or off
   628         -do_test shell1-3.23b.1 {
   629         -  catchcmd "test.db" ".stats"
   630         -} {1 {Usage: .stats on|off}}
          628  +#do_test shell1-3.23b.1 {
          629  +#  catchcmd "test.db" ".stats"
          630  +#} {1 {Usage: .stats on|off}}
   631    631   do_test shell1-3.23b.2 {
   632    632     catchcmd "test.db" ".stats ON"
   633    633   } {0 {}}
   634    634   do_test shell1-3.23b.3 {
   635    635     catchcmd "test.db" ".stats OFF"
   636    636   } {0 {}}
   637    637   do_test shell1-3.23b.4 {
   638    638     # too many arguments
   639    639     catchcmd "test.db" ".stats OFF BAD"
   640         -} {1 {Usage: .stats on|off}}
          640  +} {1 {Usage: .stats ?on|off?}}
   641    641   
   642    642   # .tables ?TABLE?        List names of tables
   643    643   #                          If TABLE specified, only list tables matching
   644    644   #                          LIKE pattern TABLE.
   645    645   do_test shell1-3.24.1 {
   646    646     catchcmd "test.db" ".tables"
   647    647   } {0 {}}

Changes to test/shell4.test.

    57     57   
    58     58   do_test shell4-1.2.2 {
    59     59     set res [catchcmd "-stats test.db" ".show"]
    60     60     list [regexp {stats: off} $res]
    61     61   } {0}
    62     62   
    63     63   # .stats ON|OFF          Turn stats on or off
    64         -do_test shell4-1.3.1 {
    65         -  catchcmd "test.db" ".stats"
    66         -} {1 {Usage: .stats on|off}}
           64  +#do_test shell4-1.3.1 {
           65  +#  catchcmd "test.db" ".stats"
           66  +#} {1 {Usage: .stats on|off}}
    67     67   do_test shell4-1.3.2 {
    68     68     catchcmd "test.db" ".stats ON"
    69     69   } {0 {}}
    70     70   do_test shell4-1.3.3 {
    71     71     catchcmd "test.db" ".stats OFF"
    72     72   } {0 {}}
    73     73   do_test shell4-1.3.4 {
    74     74     # too many arguments
    75     75     catchcmd "test.db" ".stats OFF BAD"
    76         -} {1 {Usage: .stats on|off}}
           76  +} {1 {Usage: .stats ?on|off?}}
    77     77   
    78     78   # NB. whitespace is important
    79     79   do_test shell4-1.4.1 {
    80     80     set res [catchcmd "test.db" {.show}]
    81     81     list [regexp {stats: off} $res]
    82     82   } {1}
    83     83   

Changes to test/snapshot.test.

   330    330   } {}
   331    331   do_test 6.3 {
   332    332     sqlite3 db2 test.db 
   333    333     db2 eval "PRAGMA user_version ; BEGIN"
   334    334     sqlite3_snapshot_open db2 main $::snapshot
   335    335     db2 eval { SELECT * FROM x1 }
   336    336   } {z zz zzz}
          337  +do_test 6.4 {
          338  +  db2 close
          339  +  sqlite3 db2 test.db 
          340  +  db2 eval "PRAGMA application_id"
          341  +  db2 eval "BEGIN"
          342  +  sqlite3_snapshot_open db2 main $::snapshot
          343  +  db2 eval { SELECT * FROM x1 }
          344  +} {z zz zzz}
          345  +
          346  +# EVIDENCE-OF: R-55491-50411 A snapshot will fail to open if the
          347  +# database connection D has not previously completed at least one read
          348  +# operation against the database file.
          349  +#
          350  +do_test 6.5 {
          351  +  db2 close
          352  +  sqlite3 db2 test.db 
          353  +  db2 eval "BEGIN"
          354  +  list [catch {sqlite3_snapshot_open db2 main $::snapshot} msg] $msg
          355  +} {1 SQLITE_ERROR}
          356  +
   337    357   sqlite3_snapshot_free $snapshot
   338    358   
   339    359   finish_test

Changes to test/speedtest1.c.

  1162   1162     for(i=1; i<=n; i++){
  1163   1163       x1 = swizzle(i, n);
  1164   1164       x2 = swizzle(x1, n);
  1165   1165       speedtest1_numbername(x1, zNum, sizeof(zNum));
  1166   1166       printf("%5d %5d %5d %s\n", i, x1, x2, zNum);
  1167   1167     }
  1168   1168   }
         1169  +
         1170  +#ifdef __linux__
         1171  +#include <sys/types.h>
         1172  +#include <unistd.h>
         1173  +
         1174  +/*
         1175  +** Attempt to display I/O stats on Linux using /proc/PID/io
         1176  +*/
         1177  +static void displayLinuxIoStats(FILE *out){
         1178  +  FILE *in;
         1179  +  char z[200];
         1180  +  sqlite3_snprintf(sizeof(z), z, "/proc/%d/io", getpid());
         1181  +  in = fopen(z, "rb");
         1182  +  if( in==0 ) return;
         1183  +  while( fgets(z, sizeof(z), in)!=0 ){
         1184  +    static const struct {
         1185  +      const char *zPattern;
         1186  +      const char *zDesc;
         1187  +    } aTrans[] = {
         1188  +      { "rchar: ",                  "Bytes received by read():" },
         1189  +      { "wchar: ",                  "Bytes sent to write():"    },
         1190  +      { "syscr: ",                  "Read() system calls:"      },
         1191  +      { "syscw: ",                  "Write() system calls:"     },
         1192  +      { "read_bytes: ",             "Bytes rcvd from storage:"  },
         1193  +      { "write_bytes: ",            "Bytes sent to storage:"    },
         1194  +      { "cancelled_write_bytes: ",  "Cancelled write bytes:"    },
         1195  +    };
         1196  +    int i;
         1197  +    for(i=0; i<sizeof(aTrans)/sizeof(aTrans[0]); i++){
         1198  +      int n = (int)strlen(aTrans[i].zPattern);
         1199  +      if( strncmp(aTrans[i].zPattern, z, n)==0 ){
         1200  +        fprintf(out, "-- %-28s %s", aTrans[i].zDesc, &z[n]);
         1201  +        break;
         1202  +      }
         1203  +    }
         1204  +  }
         1205  +  fclose(in);
         1206  +}   
         1207  +#endif
  1169   1208   
  1170   1209   int main(int argc, char **argv){
  1171   1210     int doAutovac = 0;            /* True for --autovacuum */
  1172   1211     int cacheSize = 0;            /* Desired cache size.  0 means default */
  1173   1212     int doExclusive = 0;          /* True for --exclusive */
  1174   1213     int nHeap = 0, mnHeap = 0;    /* Heap size from --heap */
  1175   1214     int doIncrvac = 0;            /* True for --incrvacuum */
................................................................................
  1455   1494       printf("-- Largest Allocation:          %d bytes\n",iHi);
  1456   1495       sqlite3_status(SQLITE_STATUS_PAGECACHE_SIZE, &iCur, &iHi, 0);
  1457   1496       printf("-- Largest Pcache Allocation:   %d bytes\n",iHi);
  1458   1497       sqlite3_status(SQLITE_STATUS_SCRATCH_SIZE, &iCur, &iHi, 0);
  1459   1498       printf("-- Largest Scratch Allocation:  %d bytes\n", iHi);
  1460   1499     }
  1461   1500   #endif
         1501  +
         1502  +#ifdef __linux__
         1503  +  if( showStats ){
         1504  +    displayLinuxIoStats(stdout);
         1505  +  }
         1506  +#endif
  1462   1507   
  1463   1508     /* Release memory */
  1464   1509     free( pLook );
  1465   1510     free( pPCache );
  1466   1511     free( pScratch );
  1467   1512     free( pHeap );
  1468   1513     return 0;
  1469   1514   }

Changes to test/stmt.test.

    42     42     set sqlite_open_file_count
    43     43   } {2}
    44     44   do_test stmt-1.4 {
    45     45     execsql {
    46     46       INSERT INTO t1 SELECT a+1, b+1 FROM t1;
    47     47     }
    48     48     set sqlite_open_file_count
    49         -} {3}
           49  +  # 2016-03-04: statement-journal open deferred
           50  +} {2}
    50     51   do_test stmt-1.5 {
    51     52     execsql COMMIT
    52     53     set sqlite_open_file_count
    53     54   } {1}
    54     55   do_test stmt-1.6.1 {
    55     56     execsql {
    56     57       BEGIN;
................................................................................
    57     58         INSERT INTO t1 SELECT a+2, b+2 FROM t1;
    58     59     }
    59     60     set sqlite_open_file_count
    60     61   } {2}
    61     62   do_test stmt-1.6.2 {
    62     63     execsql { INSERT INTO t1 SELECT a+4, b+4 FROM t1 }
    63     64     set sqlite_open_file_count
    64         -} {3}
           65  +  # 2016-03-04: statement-journal open deferred
           66  +} {2}
    65     67   do_test stmt-1.7 {
    66     68     execsql COMMIT
    67     69     set sqlite_open_file_count
    68     70   } {1}
    69     71   
    70     72   
    71     73   proc filecount {testname sql expected} {
................................................................................
    80     82   
    81     83   filecount stmt-2.1 { INSERT INTO t1 VALUES(9, 9)  } 2
    82     84   filecount stmt-2.2 { REPLACE INTO t1 VALUES(9, 9) } 2
    83     85   filecount stmt-2.3 { INSERT INTO t1 SELECT 9, 9   } 2
    84     86   filecount stmt-2.4 { 
    85     87       INSERT INTO t1 SELECT 9, 9;
    86     88       INSERT INTO t1 SELECT 10, 10;
    87         -} 3
           89  +} 2
    88     90   
    89     91   do_test stmt-2.5 {
    90     92     execsql { CREATE INDEX i1 ON t1(b) }
    91     93   } {}
    92     94   filecount stmt-2.6 { 
    93     95     REPLACE INTO t1 VALUES(5, 5);
    94     96     REPLACE INTO t1 VALUES(5, 5); 
    95         -} 3
           97  +} 2
    96     98   
    97     99   finish_test

Changes to test/tabfunc01.test.

   115    115     SELECT * FROM temp.generate_series(1,4)
   116    116   } {1 {no such table: temp.generate_series}}
   117    117   do_catchsql_test tabfunc01-4.3 {
   118    118     ATTACH ':memory:' AS aux1;
   119    119     CREATE TABLE aux1.t1(a,b,c);
   120    120     SELECT * FROM aux1.generate_series(1,4)
   121    121   } {1 {no such table: aux1.generate_series}}
          122  +
          123  +# The next series of tests is verifying that virtual table are able
          124  +# to optimize the IN operator, even on terms that are not marked "omit".
          125  +# When the generate_series virtual table is compiled for the testfixture,
          126  +# the special -DSQLITE_SERIES_CONSTRAINT_VERIFY=1 option is used, which
          127  +# causes the xBestIndex method of generate_series to leave the
          128  +# sqlite3_index_constraint_usage.omit flag set to 0, which should cause
          129  +# the SQLite core to verify the start=, stop=, and step= constraints on
          130  +# each step of output.  At one point, the IN operator could not be used
          131  +# by virtual tables unless omit was set.
          132  +#
          133  +do_execsql_test tabfunc01-500 {
          134  +  SELECT * FROM generate_series WHERE start IN (1,7) AND stop=20 AND step=10
          135  +  ORDER BY +1;
          136  +} {1 7 11 17}
   122    137   
   123    138   finish_test

Changes to test/tempdb.test.

    72     72         INSERT INTO t1 VALUES(1, 2, 3);
    73     73         INSERT INTO t1 VALUES(4, 5, 6);
    74     74         INSERT INTO t2 VALUES(7, 8, 9);
    75     75         INSERT INTO t2 SELECT * FROM t1;
    76     76     }
    77     77     catchsql { INSERT INTO t1 SELECT * FROM t2 }
    78     78     set sqlite_open_file_count
    79         -} [expr 1 + (0==$jrnl_in_memory) + (0==$subj_in_memory)]
           79  +} [expr 1 + (0==$jrnl_in_memory)]
    80     80   do_test tempdb-2.3 {
    81     81     execsql {
    82     82       PRAGMA temp_store = 'memory';
    83     83       ROLLBACK;
    84     84       BEGIN;
    85     85         INSERT INTO t1 VALUES(1, 2, 3);
    86     86         INSERT INTO t1 VALUES(4, 5, 6);

Changes to test/where.test.

   569    569     }
   570    570   } {1 100 4 2 99 9 3 98 16 nosort}
   571    571   do_test where-6.6 {
   572    572     cksort {
   573    573       SELECT * FROM t3 WHERE a>0 ORDER BY a LIMIT 3
   574    574     }
   575    575   } {1 100 4 2 99 9 3 98 16 nosort}
   576         -do_test where-6.7 {
          576  +do_test where-6.7.1 {
   577    577     cksort {
   578         -    SELECT * FROM t3 WHERE b>0 ORDER BY a LIMIT 3
          578  +    SELECT * FROM t3 WHERE b>0 ORDER BY a LIMIT 10
   579    579     }
   580         -} {1 100 4 2 99 9 3 98 16 nosort}
          580  +} {/1 100 4 2 99 9 3 98 16 .* nosort/}
          581  +do_test where-6.7.2 {
          582  +  cksort {
          583  +    SELECT * FROM t3 WHERE b>0 ORDER BY a LIMIT 1
          584  +  }
          585  +} {1 100 4 sort}
   581    586   ifcapable subquery {
   582    587     do_test where-6.8a {
   583    588       cksort {
   584    589         SELECT * FROM t3 WHERE a IN (3,5,7,1,9,4,2) ORDER BY a LIMIT 3
   585    590       }
   586    591     } {1 100 4 2 99 9 3 98 16 nosort}
   587    592     do_test where-6.8b {

Added tool/Replace.cs.

            1  +/*
            2  +** 2016 February 26
            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  +** This file contains C# code to perform regular expression replacements
           13  +** using the standard input and output channels.
           14  +*/
           15  +
           16  +using System;
           17  +using System.Diagnostics;
           18  +using System.IO;
           19  +using System.Reflection;
           20  +using System.Runtime.InteropServices;
           21  +using System.Text.RegularExpressions;
           22  +
           23  +///////////////////////////////////////////////////////////////////////////////
           24  +
           25  +#region Assembly Metadata
           26  +[assembly: AssemblyTitle("Replace Tool")]
           27  +[assembly: AssemblyDescription("Replace text using standard input/output.")]
           28  +[assembly: AssemblyCompany("SQLite Development Team")]
           29  +[assembly: AssemblyProduct("SQLite")]
           30  +[assembly: AssemblyCopyright("Public Domain")]
           31  +[assembly: ComVisible(false)]
           32  +[assembly: Guid("95a0513f-8863-48cd-a76f-cb80868cb578")]
           33  +[assembly: AssemblyVersion("1.0.*")]
           34  +
           35  +#if DEBUG
           36  +[assembly: AssemblyConfiguration("Debug")]
           37  +#else
           38  +[assembly: AssemblyConfiguration("Release")]
           39  +#endif
           40  +#endregion
           41  +
           42  +///////////////////////////////////////////////////////////////////////////////
           43  +
           44  +namespace Replace
           45  +{
           46  +    /// <summary>
           47  +    /// This enumeration is used to represent all the possible exit codes from
           48  +    /// this tool.
           49  +    /// </summary>
           50  +    internal enum ExitCode
           51  +    {
           52  +        /// <summary>
           53  +        /// The file download was a success.
           54  +        /// </summary>
           55  +        Success = 0,
           56  +
           57  +        /// <summary>
           58  +        /// The command line arguments are missing (i.e. null).  Generally,
           59  +        /// this should not happen.
           60  +        /// </summary>
           61  +        MissingArgs = 1,
           62  +
           63  +        /// <summary>
           64  +        /// The wrong number of command line arguments was supplied.
           65  +        /// </summary>
           66  +        WrongNumArgs = 2,
           67  +
           68  +        /// <summary>
           69  +        /// The "matchingOnly" flag could not be converted to a value of the
           70  +        /// <see cref="Boolean"/> type.
           71  +        /// </summary>
           72  +        BadMatchingOnlyFlag = 3,
           73  +
           74  +        /// <summary>
           75  +        /// An exception was caught in <see cref="Main" />.  Generally, this
           76  +        /// should not happen.
           77  +        /// </summary>
           78  +        Exception = 4
           79  +    }
           80  +
           81  +    ///////////////////////////////////////////////////////////////////////////
           82  +
           83  +    internal static class Replace
           84  +    {
           85  +        #region Private Support Methods
           86  +        /// <summary>
           87  +        /// This method displays an error message to the console and/or
           88  +        /// displays the command line usage information for this tool.
           89  +        /// </summary>
           90  +        /// <param name="message">
           91  +        /// The error message to display, if any.
           92  +        /// </param>
           93  +        /// <param name="usage">
           94  +        /// Non-zero to display the command line usage information.
           95  +        /// </param>
           96  +        private static void Error(
           97  +            string message,
           98  +            bool usage
           99  +            )
          100  +        {
          101  +            if (message != null)
          102  +                Console.WriteLine(message);
          103  +
          104  +            string fileName = Path.GetFileName(
          105  +                Process.GetCurrentProcess().MainModule.FileName);
          106  +
          107  +            Console.WriteLine(String.Format(
          108  +                "usage: {0} <regExPattern> <regExSubSpec> <matchingOnly>",
          109  +                fileName));
          110  +        }
          111  +        #endregion
          112  +
          113  +        ///////////////////////////////////////////////////////////////////////
          114  +
          115  +        #region Program Entry Point
          116  +        /// <summary>
          117  +        /// This is the entry-point for this tool.  It handles processing the
          118  +        /// command line arguments, reading from the standard input channel,
          119  +        /// replacing any matching lines of text, and writing to the standard
          120  +        /// output channel.
          121  +        /// </summary>
          122  +        /// <param name="args">
          123  +        /// The command line arguments.
          124  +        /// </param>
          125  +        /// <returns>
          126  +        /// Zero upon success; non-zero on failure.  This will be one of the
          127  +        /// values from the <see cref="ExitCode" /> enumeration.
          128  +        /// </returns>
          129  +        private static int Main(
          130  +            string[] args
          131  +            )
          132  +        {
          133  +            //
          134  +            // NOTE: Sanity check the command line arguments.
          135  +            //
          136  +            if (args == null)
          137  +            {
          138  +                Error(null, true);
          139  +                return (int)ExitCode.MissingArgs;
          140  +            }
          141  +
          142  +            if (args.Length != 3)
          143  +            {
          144  +                Error(null, true);
          145  +                return (int)ExitCode.WrongNumArgs;
          146  +            }
          147  +
          148  +            try
          149  +            {
          150  +                //
          151  +                // NOTE: Create a regular expression from the first command
          152  +                //       line argument.  Then, grab the replacement string,
          153  +                //       which is the second argument.
          154  +                //
          155  +                Regex regEx = new Regex(args[0]);
          156  +                string replacement = args[1];
          157  +
          158  +                //
          159  +                // NOTE: Attempt to convert the third argument to a boolean.
          160  +                //
          161  +                bool matchingOnly;
          162  +
          163  +                if (!bool.TryParse(args[2], out matchingOnly))
          164  +                {
          165  +                    Error(null, true);
          166  +                    return (int)ExitCode.BadMatchingOnlyFlag;
          167  +                }
          168  +
          169  +                //
          170  +                // NOTE: Grab the standard input and output channels from the
          171  +                //       console.
          172  +                //
          173  +                TextReader inputTextReader = Console.In;
          174  +                TextWriter outputTextWriter = Console.Out;
          175  +
          176  +                //
          177  +                // NOTE: Loop until end-of-file is hit on the standard input
          178  +                //       stream.
          179  +                //
          180  +                while (true)
          181  +                {
          182  +                    //
          183  +                    // NOTE: Read a line from the standard input channel.  If
          184  +                    //       null is returned here, there is no more input and
          185  +                    //       we are done.
          186  +                    //
          187  +                    string inputLine = inputTextReader.ReadLine();
          188  +
          189  +                    if (inputLine == null)
          190  +                        break;
          191  +
          192  +                    //
          193  +                    // NOTE: Perform regular expression replacements on this
          194  +                    //       line, if any.  Then, write the modified line to
          195  +                    //       the standard output channel.
          196  +                    //
          197  +                    string outputLine = regEx.Replace(inputLine, replacement);
          198  +
          199  +                    if (!matchingOnly || !String.Equals(
          200  +                            inputLine, outputLine, StringComparison.Ordinal))
          201  +                    {
          202  +                        outputTextWriter.WriteLine(outputLine);
          203  +                    }
          204  +                }
          205  +
          206  +                //
          207  +                // NOTE: At this point, everything has succeeded.
          208  +                //
          209  +                return (int)ExitCode.Success;
          210  +            }
          211  +            catch (Exception e)
          212  +            {
          213  +                //
          214  +                // NOTE: An exception was caught.  Report it via the console
          215  +                //       and return failure.
          216  +                //
          217  +                Error(e.ToString(), false);
          218  +                return (int)ExitCode.Exception;
          219  +            }
          220  +        }
          221  +        #endregion
          222  +    }
          223  +}

Changes to tool/addopcodes.tcl.

    34     34     COLUMN
    35     35     AGG_FUNCTION
    36     36     AGG_COLUMN
    37     37     UMINUS
    38     38     UPLUS
    39     39     REGISTER
    40     40     ASTERISK
           41  +  SPAN
    41     42     SPACE
    42     43     ILLEGAL
    43     44   }
    44     45   if {[lrange $extras end-1 end]!="SPACE ILLEGAL"} {
    45     46     error "SPACE and ILLEGAL must be the last two token codes and they\
    46     47            must be in that order"
    47     48   }

Changes to tool/mkautoconfamal.sh.

    49     49   cp sqlite3.c              $TMPSPACE
    50     50   cp sqlite3.h              $TMPSPACE
    51     51   cp sqlite3ext.h           $TMPSPACE
    52     52   cp $TOP/sqlite3.1         $TMPSPACE
    53     53   cp $TOP/sqlite3.pc.in     $TMPSPACE
    54     54   cp $TOP/src/shell.c       $TMPSPACE
    55     55   cp $TOP/src/sqlite3.rc    $TMPSPACE
           56  +cp $TOP/tool/Replace.cs   $TMPSPACE
    56     57   
    57     58   cat $TMPSPACE/configure.ac |
    58     59   sed "s/--SQLITE-VERSION--/$VERSION/" > $TMPSPACE/tmp
    59     60   mv $TMPSPACE/tmp $TMPSPACE/configure.ac
    60     61   
    61     62   cd $TMPSPACE
    62     63   autoreconf -i

Changes to tool/mkmsvcmin.tcl.

    68     68   $(LIBRESOBJS):	$(TOP)\sqlite3.rc rcver.vc $(SQLITE3H)
    69     69   	echo #ifndef SQLITE_RESOURCE_VERSION > sqlite3rc.h
    70     70   	echo #define SQLITE_RESOURCE_VERSION $(RESOURCE_VERSION) >> sqlite3rc.h
    71     71   	echo #endif >> sqlite3rc.h
    72     72   	$(LTRCOMPILE) -fo $(LIBRESOBJS) -DRC_VERONLY $(TOP)\sqlite3.rc
    73     73   }]]
    74     74   
           75  +#
           76  +# NOTE: This block is used to replace the section marked <<block2>> in
           77  +#       the Makefile, if it exists.
           78  +#
           79  +set blocks(2) [string trimleft [string map [list \\\\ \\] {
           80  +Replace.exe:
           81  +	$(CSC) /target:exe $(TOP)\Replace.cs
           82  +
           83  +sqlite3.def:	Replace.exe $(LIBOBJ)
           84  +	echo EXPORTS > sqlite3.def
           85  +	dumpbin /all $(LIBOBJ) \\
           86  +		| .\Replace.exe "^\s+/EXPORT:_?(sqlite3_[^@,]*)(?:@\d+|,DATA)?$$" $$1 true \\
           87  +		| sort >> sqlite3.def
           88  +}]]
           89  +
    75     90   set data "#### DO NOT EDIT ####\n"
    76     91   append data "# This makefile is automatically "
    77     92   append data "generated from the [file tail $fromFileName] at\n"
    78     93   append data "# the root of the canonical SQLite source tree (not the\n"
    79     94   append data "# amalgamation tarball) using the tool/[file tail $argv0]\n"
    80     95   append data "# script.\n#\n\n"
    81     96   append data [readFile $fromFileName]
................................................................................
    86    101   foreach i [lsort -integer [array names blocks]] {
    87    102     regsub -all -- [substVars \
    88    103         {# <<block${i}>>\n.*?# <</block${i}>>\n}] \
    89    104         $data [escapeSubSpec $blocks($i)] data
    90    105   }
    91    106   
    92    107   set data [string map [list " -I\$(TOP)\\src" ""] $data]
    93         -set data [string map [list " /DEF:sqlite3.def" ""] $data]
    94         -set data [string map [list " sqlite3.def" ""] $data]
    95    108   set data [string map [list " libsqlite3.lib" ""] $data]
    96    109   set data [string map [list " \$(ALL_TCL_TARGETS)" ""] $data]
    97    110   set data [string map [list "\$(TOP)\\src\\" "\$(TOP)\\"] $data]
    98    111   
    99    112   writeFile $toFileName $data

Changes to tool/srcck1.c.

   107    107   
   108    108   /* Search for instances of assert(...), ALWAYS(...), NEVER(...), and/or
   109    109   ** testcase(...) where the argument contains side effects.
   110    110   **
   111    111   ** Print error messages whenever a side effect is found.  Return the number
   112    112   ** of problems seen.
   113    113   */
   114         -static unsigned int findAllSideEffects(const char *z){
          114  +static unsigned int findAllSideEffects(const unsigned char *z){
   115    115     unsigned int lineno = 1;   /* Line number */
   116    116     unsigned int i;
   117    117     unsigned int nErr = 0;
   118         -  char c, prevC = 0;
          118  +  unsigned char c, prevC = 0;
   119    119     for(i=0; (c = z[i])!=0; prevC=c, i++){
   120    120       if( c=='\n' ){ lineno++; continue; }
   121    121       if( isalpha(c) && !isalpha(prevC) ){
   122    122         if( strncmp(&z[i],"assert(",7)==0
   123    123          || strncmp(&z[i],"ALWAYS(",7)==0
   124    124          || strncmp(&z[i],"NEVER(",6)==0
   125    125          || strncmp(&z[i],"testcase(",9)==0
   126    126         ){
   127    127           unsigned int n;
   128         -        const char *z2 = &z[i+5];
          128  +        unsigned const char *z2 = &z[i+5];
   129    129           while( z2[0]!='(' ){ z2++; }
   130    130           z2++;
   131    131           n = findCloseParen(z2);
   132    132           if( hasSideEffect(z2, n) ){
   133    133             nErr++;
   134    134             fprintf(stderr, "side-effect line %u: %.*s\n", lineno,
   135    135                     (int)(&z2[n+1] - &z[i]), &z[i]);
................................................................................
   137    137         }
   138    138       }
   139    139     }
   140    140     return nErr;
   141    141   }
   142    142   
   143    143   int main(int argc, char **argv){
   144         -  char *z;
          144  +  unsigned char *z;
   145    145     unsigned int nErr = 0;
   146    146     if( argc!=2 ){
   147    147       fprintf(stderr, "Usage: %s FILENAME\n", argv[0]);
   148    148       return 1;
   149    149     }
   150    150     z = readFile(argv[1]);
   151    151     nErr = findAllSideEffects(z);

Added vsixtest/App.xaml.

            1  +<Application
            2  +    x:Class="vsixtest.App"
            3  +    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            4  +    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            5  +    xmlns:local="using:vsixtest"
            6  +    RequestedTheme="Light">
            7  +
            8  +</Application>

Added vsixtest/App.xaml.cpp.

            1  +//
            2  +// App.xaml.cpp
            3  +// Implementation of the App class.
            4  +//
            5  +
            6  +#include "pch.h"
            7  +#include "MainPage.xaml.h"
            8  +
            9  +using namespace vsixtest;
           10  +
           11  +using namespace Platform;
           12  +using namespace Windows::ApplicationModel;
           13  +using namespace Windows::ApplicationModel::Activation;
           14  +using namespace Windows::Foundation;
           15  +using namespace Windows::Foundation::Collections;
           16  +using namespace Windows::UI::Xaml;
           17  +using namespace Windows::UI::Xaml::Controls;
           18  +using namespace Windows::UI::Xaml::Controls::Primitives;
           19  +using namespace Windows::UI::Xaml::Data;
           20  +using namespace Windows::UI::Xaml::Input;
           21  +using namespace Windows::UI::Xaml::Interop;
           22  +using namespace Windows::UI::Xaml::Media;
           23  +using namespace Windows::UI::Xaml::Navigation;
           24  +
           25  +/// <summary>
           26  +/// Initializes the singleton application object.  This is the first line of authored code
           27  +/// executed, and as such is the logical equivalent of main() or WinMain().
           28  +/// </summary>
           29  +App::App()
           30  +{
           31  +	InitializeComponent();
           32  +	Suspending += ref new SuspendingEventHandler(this, &App::OnSuspending);
           33  +}
           34  +
           35  +/// <summary>
           36  +/// Invoked when the application is launched normally by the end user.	Other entry points
           37  +/// will be used such as when the application is launched to open a specific file.
           38  +/// </summary>
           39  +/// <param name="e">Details about the launch request and process.</param>
           40  +void App::OnLaunched(Windows::ApplicationModel::Activation::LaunchActivatedEventArgs^ e)
           41  +{
           42  +
           43  +#if _DEBUG
           44  +		// Show graphics profiling information while debugging.
           45  +		if (IsDebuggerPresent())
           46  +		{
           47  +			// Display the current frame rate counters
           48  +			 DebugSettings->EnableFrameRateCounter = true;
           49  +		}
           50  +#endif
           51  +
           52  +	auto rootFrame = dynamic_cast<Frame^>(Window::Current->Content);
           53  +
           54  +	// Do not repeat app initialization when the Window already has content,
           55  +	// just ensure that the window is active
           56  +	if (rootFrame == nullptr)
           57  +	{
           58  +		// Create a Frame to act as the navigation context and associate it with
           59  +		// a SuspensionManager key
           60  +		rootFrame = ref new Frame();
           61  +
           62  +		rootFrame->NavigationFailed += ref new Windows::UI::Xaml::Navigation::NavigationFailedEventHandler(this, &App::OnNavigationFailed);
           63  +
           64  +		if (e->PreviousExecutionState == ApplicationExecutionState::Terminated)
           65  +		{
           66  +			// TODO: Restore the saved session state only when appropriate, scheduling the
           67  +			// final launch steps after the restore is complete
           68  +
           69  +		}
           70  +
           71  +		if (rootFrame->Content == nullptr)
           72  +		{
           73  +			// When the navigation stack isn't restored navigate to the first page,
           74  +			// configuring the new page by passing required information as a navigation
           75  +			// parameter
           76  +			rootFrame->Navigate(TypeName(MainPage::typeid), e->Arguments);
           77  +		}
           78  +		// Place the frame in the current Window
           79  +		Window::Current->Content = rootFrame;
           80  +		// Ensure the current window is active
           81  +		Window::Current->Activate();
           82  +	}
           83  +	else
           84  +	{
           85  +		if (rootFrame->Content == nullptr)
           86  +		{
           87  +			// When the navigation stack isn't restored navigate to the first page,
           88  +			// configuring the new page by passing required information as a navigation
           89  +			// parameter
           90  +			rootFrame->Navigate(TypeName(MainPage::typeid), e->Arguments);
           91  +		}
           92  +		// Ensure the current window is active
           93  +		Window::Current->Activate();
           94  +	}
           95  +}
           96  +
           97  +/// <summary>
           98  +/// Invoked when application execution is being suspended.	Application state is saved
           99  +/// without knowing whether the application will be terminated or resumed with the contents
          100  +/// of memory still intact.
          101  +/// </summary>
          102  +/// <param name="sender">The source of the suspend request.</param>
          103  +/// <param name="e">Details about the suspend request.</param>
          104  +void App::OnSuspending(Object^ sender, SuspendingEventArgs^ e)
          105  +{
          106  +	(void) sender;	// Unused parameter
          107  +	(void) e;	// Unused parameter
          108  +
          109  +	//TODO: Save application state and stop any background activity
          110  +}
          111  +
          112  +/// <summary>
          113  +/// Invoked when Navigation to a certain page fails
          114  +/// </summary>
          115  +/// <param name="sender">The Frame which failed navigation</param>
          116  +/// <param name="e">Details about the navigation failure</param>
          117  +void App::OnNavigationFailed(Platform::Object ^sender, Windows::UI::Xaml::Navigation::NavigationFailedEventArgs ^e)
          118  +{
          119  +	throw ref new FailureException("Failed to load Page " + e->SourcePageType.Name);
          120  +}

Added vsixtest/App.xaml.h.

            1  +//
            2  +// App.xaml.h
            3  +// Declaration of the App class.
            4  +//
            5  +
            6  +#pragma once
            7  +
            8  +#include "App.g.h"
            9  +
           10  +namespace vsixtest
           11  +{
           12  +	/// <summary>
           13  +	/// Provides application-specific behavior to supplement the default Application class.
           14  +	/// </summary>
           15  +	ref class App sealed
           16  +	{
           17  +	protected:
           18  +		virtual void OnLaunched(Windows::ApplicationModel::Activation::LaunchActivatedEventArgs^ e) override;
           19  +
           20  +	internal:
           21  +		App();
           22  +
           23  +	private:
           24  +		void OnSuspending(Platform::Object^ sender, Windows::ApplicationModel::SuspendingEventArgs^ e);
           25  +		void OnNavigationFailed(Platform::Object ^sender, Windows::UI::Xaml::Navigation::NavigationFailedEventArgs ^e);
           26  +	};
           27  +}

Added vsixtest/Assets/LockScreenLogo.scale-200.png.

cannot compute difference between binary files

Added vsixtest/Assets/SplashScreen.scale-200.png.

cannot compute difference between binary files

Added vsixtest/Assets/Square150x150Logo.scale-200.png.

cannot compute difference between binary files

Added vsixtest/Assets/Square44x44Logo.scale-200.png.

cannot compute difference between binary files

Added vsixtest/Assets/Square44x44Logo.targetsize-24_altform-unplated.png.

cannot compute difference between binary files

Added vsixtest/Assets/StoreLogo.png.

cannot compute difference between binary files

Added vsixtest/Assets/Wide310x150Logo.scale-200.png.

cannot compute difference between binary files

Added vsixtest/MainPage.xaml.

            1  +<Page
            2  +    x:Class="vsixtest.MainPage"
            3  +    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            4  +    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            5  +    xmlns:local="using:vsixtest"
            6  +    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            7  +    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            8  +    mc:Ignorable="d">
            9  +
           10  +    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
           11  +
           12  +    </Grid>
           13  +</Page>

Added vsixtest/MainPage.xaml.cpp.

            1  +//
            2  +// MainPage.xaml.cpp
            3  +// Implementation of the MainPage class.
            4  +//
            5  +
            6  +#include "pch.h"
            7  +#include "MainPage.xaml.h"
            8  +#include "sqlite3.h"
            9  +
           10  +using namespace vsixtest;
           11  +
           12  +using namespace Platform;
           13  +using namespace Windows::Foundation;
           14  +using namespace Windows::Foundation::Collections;
           15  +using namespace Windows::UI::Xaml;
           16  +using namespace Windows::UI::Xaml::Controls;
           17  +using namespace Windows::UI::Xaml::Controls::Primitives;
           18  +using namespace Windows::UI::Xaml::Data;
           19  +using namespace Windows::UI::Xaml::Input;
           20  +using namespace Windows::UI::Xaml::Media;
           21  +using namespace Windows::UI::Xaml::Navigation;
           22  +
           23  +// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409
           24  +
           25  +MainPage::MainPage()
           26  +{
           27  +	InitializeComponent();
           28  +	UseSQLite();
           29  +}
           30  +
           31  +void MainPage::UseSQLite(void)
           32  +{
           33  +    int rc = SQLITE_OK;
           34  +    sqlite3 *pDb = nullptr;
           35  +
           36  +    rc = sqlite3_open_v2("test.db", &pDb,
           37  +	SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, nullptr);
           38  +
           39  +    if (rc != SQLITE_OK)
           40  +	throw ref new FailureException("Failed to open database.");
           41  +
           42  +    rc = sqlite3_exec(pDb, "VACUUM;", nullptr, nullptr, nullptr);
           43  +
           44  +    if (rc != SQLITE_OK)
           45  +	throw ref new FailureException("Failed to vacuum database.");
           46  +
           47  +    rc = sqlite3_close(pDb);
           48  +
           49  +    if (rc != SQLITE_OK)
           50  +	throw ref new FailureException("Failed to close database.");
           51  +
           52  +    pDb = nullptr;
           53  +}

Added vsixtest/MainPage.xaml.h.

            1  +//
            2  +// MainPage.xaml.h
            3  +// Declaration of the MainPage class.
            4  +//
            5  +
            6  +#pragma once
            7  +
            8  +#include "MainPage.g.h"
            9  +
           10  +namespace vsixtest
           11  +{
           12  +	/// <summary>
           13  +	/// An empty page that can be used on its own or navigated to within a Frame.
           14  +	/// </summary>
           15  +	public ref class MainPage sealed
           16  +	{
           17  +	public:
           18  +		MainPage();
           19  +		void UseSQLite(void);
           20  +
           21  +	};
           22  +}

Added vsixtest/Package.appxmanifest.

            1  +<?xml version="1.0" encoding="utf-8"?>
            2  +
            3  +<Package
            4  +  xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
            5  +  xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest"
            6  +  xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
            7  +  IgnorableNamespaces="uap mp">
            8  +
            9  +  <Identity
           10  +    Name="bb52b3e1-5c8a-4516-a5ff-8b9f9baadef7"
           11  +    Publisher="CN=mistachkin"
           12  +    Version="1.0.0.0" />
           13  +
           14  +  <mp:PhoneIdentity PhoneProductId="bb52b3e1-5c8a-4516-a5ff-8b9f9baadef7" PhonePublisherId="00000000-0000-0000-0000-000000000000"/>
           15  +
           16  +  <Properties>
           17  +    <DisplayName>vsixtest</DisplayName>
           18  +    <PublisherDisplayName>mistachkin</PublisherDisplayName>
           19  +    <Logo>Assets\StoreLogo.png</Logo>
           20  +  </Properties>
           21  +
           22  +  <Dependencies>
           23  +    <TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.0.0" MaxVersionTested="10.0.0.0" />
           24  +  </Dependencies>
           25  +
           26  +  <Resources>
           27  +    <Resource Language="x-generate"/>
           28  +  </Resources>
           29  +
           30  +  <Applications>
           31  +    <Application Id="App"
           32  +      Executable="$targetnametoken$.exe"
           33  +      EntryPoint="vsixtest.App">
           34  +      <uap:VisualElements
           35  +        DisplayName="vsixtest"
           36  +        Square150x150Logo="Assets\Square150x150Logo.png"
           37  +        Square44x44Logo="Assets\Square44x44Logo.png"
           38  +        Description="vsixtest"
           39  +        BackgroundColor="transparent">
           40  +        <uap:DefaultTile Wide310x150Logo="Assets\Wide310x150Logo.png"/>
           41  +        <uap:SplashScreen Image="Assets\SplashScreen.png" />
           42  +      </uap:VisualElements>
           43  +    </Application>
           44  +  </Applications>
           45  +
           46  +  <Capabilities>
           47  +    <Capability Name="internetClient" />
           48  +  </Capabilities>
           49  +</Package>

Added vsixtest/pch.cpp.

            1  +//
            2  +// pch.cpp
            3  +// Include the standard header and generate the precompiled header.
            4  +//
            5  +
            6  +#include "pch.h"

Added vsixtest/pch.h.

            1  +//
            2  +// pch.h
            3  +// Header for standard system include files.
            4  +//
            5  +
            6  +#pragma once
            7  +
            8  +#include <collection.h>
            9  +#include <ppltasks.h>
           10  +
           11  +#include "App.xaml.h"

Added vsixtest/vsixtest.sln.

            1  +Microsoft Visual Studio Solution File, Format Version 12.00
            2  +# Visual Studio 14
            3  +VisualStudioVersion = 14.0.24720.0
            4  +MinimumVisualStudioVersion = 10.0.40219.1
            5  +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vsixtest", "vsixtest.vcxproj", "{60BB14A5-0871-4656-BC38-4F0958230F9A}"
            6  +EndProject
            7  +Global
            8  +	GlobalSection(SolutionConfigurationPlatforms) = preSolution
            9  +		Debug|ARM = Debug|ARM
           10  +		Debug|x64 = Debug|x64
           11  +		Debug|x86 = Debug|x86
           12  +		Release|ARM = Release|ARM
           13  +		Release|x64 = Release|x64
           14  +		Release|x86 = Release|x86
           15  +	EndGlobalSection
           16  +	GlobalSection(ProjectConfigurationPlatforms) = postSolution
           17  +		{60BB14A5-0871-4656-BC38-4F0958230F9A}.Debug|ARM.ActiveCfg = Debug|ARM
           18  +		{60BB14A5-0871-4656-BC38-4F0958230F9A}.Debug|ARM.Build.0 = Debug|ARM
           19  +		{60BB14A5-0871-4656-BC38-4F0958230F9A}.Debug|ARM.Deploy.0 = Debug|ARM
           20  +		{60BB14A5-0871-4656-BC38-4F0958230F9A}.Debug|x64.ActiveCfg = Debug|x64
           21  +		{60BB14A5-0871-4656-BC38-4F0958230F9A}.Debug|x64.Build.0 = Debug|x64
           22  +		{60BB14A5-0871-4656-BC38-4F0958230F9A}.Debug|x64.Deploy.0 = Debug|x64
           23  +		{60BB14A5-0871-4656-BC38-4F0958230F9A}.Debug|x86.ActiveCfg = Debug|Win32
           24  +		{60BB14A5-0871-4656-BC38-4F0958230F9A}.Debug|x86.Build.0 = Debug|Win32
           25  +		{60BB14A5-0871-4656-BC38-4F0958230F9A}.Debug|x86.Deploy.0 = Debug|Win32
           26  +		{60BB14A5-0871-4656-BC38-4F0958230F9A}.Release|ARM.ActiveCfg = Release|ARM
           27  +		{60BB14A5-0871-4656-BC38-4F0958230F9A}.Release|ARM.Build.0 = Release|ARM
           28  +		{60BB14A5-0871-4656-BC38-4F0958230F9A}.Release|ARM.Deploy.0 = Release|ARM
           29  +		{60BB14A5-0871-4656-BC38-4F0958230F9A}.Release|x64.ActiveCfg = Release|x64
           30  +		{60BB14A5-0871-4656-BC38-4F0958230F9A}.Release|x64.Build.0 = Release|x64
           31  +		{60BB14A5-0871-4656-BC38-4F0958230F9A}.Release|x64.Deploy.0 = Release|x64
           32  +		{60BB14A5-0871-4656-BC38-4F0958230F9A}.Release|x86.ActiveCfg = Release|Win32
           33  +		{60BB14A5-0871-4656-BC38-4F0958230F9A}.Release|x86.Build.0 = Release|Win32
           34  +		{60BB14A5-0871-4656-BC38-4F0958230F9A}.Release|x86.Deploy.0 = Release|Win32
           35  +	EndGlobalSection
           36  +	GlobalSection(SolutionProperties) = preSolution
           37  +		HideSolutionNode = FALSE
           38  +	EndGlobalSection
           39  +EndGlobal

Added vsixtest/vsixtest.tcl.

            1  +#!/usr/bin/tclsh
            2  +#
            3  +# This script is used to quickly test a VSIX (Visual Studio Extension) file
            4  +# with Visual Studio 2015 on Windows.
            5  +#
            6  +# PREREQUISITES
            7  +#
            8  +# 1. This tool is Windows only.
            9  +#
           10  +# 2. This tool must be executed with "elevated administrator" privileges.
           11  +#
           12  +# 3. Tcl 8.4 and later are supported, earlier versions have not been tested.
           13  +#
           14  +# 4. The "sqlite-UWP-output.vsix" file is assumed to exist in the parent
           15  +#    directory of the directory containing this script.  The [optional] first
           16  +#    command line argument to this script may be used to specify an alternate
           17  +#    file.  However, currently, the file must be compatible with both Visual
           18  +#    Studio 2015 and the Universal Windows Platform.
           19  +#
           20  +# 5. The "VERSION" file is assumed to exist in the parent directory of the
           21  +#    directory containing this script.  It must contain a version number that
           22  +#    matches the VSIX file being tested.
           23  +#
           24  +# 6. The temporary directory specified in the TEMP or TMP environment variables
           25  +#    must refer to an existing directory writable by the current user.
           26  +#
           27  +# 7. The VS140COMNTOOLS environment variable must refer to the Visual Studio
           28  +#    2015 common tools directory.
           29  +#
           30  +# USAGE
           31  +#
           32  +# The first argument to this script is optional.  If specified, it must be the
           33  +# name of the VSIX file to test.
           34  +#
           35  +package require Tcl 8.4
           36  +
           37  +proc fail { {error ""} {usage false} } {
           38  +  if {[string length $error] > 0} then {
           39  +    puts stdout $error
           40  +    if {!$usage} then {exit 1}
           41  +  }
           42  +
           43  +  puts stdout "usage:\
           44  +[file tail [info nameofexecutable]]\
           45  +[file tail [info script]] \[vsixFile\]"
           46  +
           47  +  exit 1
           48  +}
           49  +
           50  +proc isWindows {} {
           51  +  #
           52  +  # NOTE: Returns non-zero only when running on Windows.
           53  +  #
           54  +  return [expr {[info exists ::tcl_platform(platform)] && \
           55  +      $::tcl_platform(platform) eq "windows"}]
           56  +}
           57  +
           58  +proc isAdministrator {} {
           59  +  #
           60  +  # NOTE: Returns non-zero only when running as "elevated administrator".
           61  +  #
           62  +  if {[isWindows]} then {
           63  +    if {[catch {exec -- whoami /groups} groups] == 0} then {
           64  +      set groups [string map [list \r\n \n] $groups]
           65  +
           66  +      foreach group [split $groups \n] {
           67  +        #
           68  +        # NOTE: Match this group line against the "well-known" SID for
           69  +        #       the "Administrators" group on Windows.
           70  +        #
           71  +        if {[regexp -- {\sS-1-5-32-544\s} $group]} then {
           72  +          #
           73  +          # NOTE: Match this group line against the attributes column
           74  +          #       sub-value that should be present when running with
           75  +          #       elevated administrator credentials.
           76  +          #
           77  +          if {[regexp -- {\sEnabled group(?:,|\s)} $group]} then {
           78  +            return true
           79  +          }
           80  +        }
           81  +      }
           82  +    }
           83  +  }
           84  +
           85  +  return false
           86  +}
           87  +
           88  +proc getEnvironmentVariable { name } {
           89  +  #
           90  +  # NOTE: Returns the value of the specified environment variable or an empty
           91  +  #       string for environment variables that do not exist in the current
           92  +  #       process environment.
           93  +  #
           94  +  return [expr {[info exists ::env($name)] ? $::env($name) : ""}]
           95  +}
           96  +
           97  +proc getTemporaryPath {} {
           98  +  #
           99  +  # NOTE: Returns the normalized path to the first temporary directory found
          100  +  #       in the typical set of environment variables used for that purpose
          101  +  #       or an empty string to signal a failure to locate such a directory.
          102  +  #
          103  +  set names [list]
          104  +
          105  +  foreach name [list TEMP TMP] {
          106  +    lappend names [string toupper $name] [string tolower $name] \
          107  +        [string totitle $name]
          108  +  }
          109  +
          110  +  foreach name $names {
          111  +    set value [getEnvironmentVariable $name]
          112  +
          113  +    if {[string length $value] > 0} then {
          114  +      return [file normalize $value]
          115  +    }
          116  +  }
          117  +
          118  +  return ""
          119  +}
          120  +
          121  +proc appendArgs { args } {
          122  +  #
          123  +  # NOTE: Returns all passed arguments joined together as a single string
          124  +  #       with no intervening spaces between arguments.
          125  +  #
          126  +  eval append result $args
          127  +}
          128  +
          129  +proc readFile { fileName } {
          130  +  #
          131  +  # NOTE: Reads and returns the entire contents of the specified file, which
          132  +  #       may contain binary data.
          133  +  #
          134  +  set file_id [open $fileName RDONLY]
          135  +  fconfigure $file_id -encoding binary -translation binary
          136  +  set result [read $file_id]
          137  +  close $file_id
          138  +  return $result
          139  +}
          140  +
          141  +proc writeFile { fileName data } {
          142  +  #
          143  +  # NOTE: Writes the entire contents of the specified file, which may contain
          144  +  #       binary data.
          145  +  #
          146  +  set file_id [open $fileName {WRONLY CREAT TRUNC}]
          147  +  fconfigure $file_id -encoding binary -translation binary
          148  +  puts -nonewline $file_id $data
          149  +  close $file_id
          150  +  return ""
          151  +}
          152  +
          153  +proc putsAndEval { command } {
          154  +  #
          155  +  # NOTE: Outputs a command to the standard output channel and then evaluates
          156  +  #       it in the callers context.
          157  +  #
          158  +  catch {
          159  +    puts stdout [appendArgs "Running: " [lrange $command 1 end] ...\n]
          160  +  }
          161  +
          162  +  return [uplevel 1 $command]
          163  +}
          164  +
          165  +proc isBadDirectory { directory } {
          166  +  #
          167  +  # NOTE: Returns non-zero if the directory is empty, does not exist, -OR- is
          168  +  #       not a directory.
          169  +  #
          170  +  catch {
          171  +    puts stdout [appendArgs "Checking directory \"" $directory \"...\n]
          172  +  }
          173  +
          174  +  return [expr {[string length $directory] == 0 || \
          175  +      ![file exists $directory] || ![file isdirectory $directory]}]
          176  +}
          177  +
          178  +proc isBadFile { fileName } {
          179  +  #
          180  +  # NOTE: Returns non-zero if the file name is empty, does not exist, -OR- is
          181  +  #       not a regular file.
          182  +  #
          183  +  catch {
          184  +    puts stdout [appendArgs "Checking file \"" $fileName \"...\n]
          185  +  }
          186  +
          187  +  return [expr {[string length $fileName] == 0 || \
          188  +      ![file exists $fileName] || ![file isfile $fileName]}]
          189  +}
          190  +
          191  +#
          192  +# NOTE: This is the entry point for this script.
          193  +#
          194  +set script [file normalize [info script]]
          195  +
          196  +if {[string length $script] == 0} then {
          197  +  fail "script file currently being evaluated is unknown" true
          198  +}
          199  +
          200  +if {![isWindows]} then {
          201  +  fail "this tool only works properly on Windows"
          202  +}
          203  +
          204  +if {![isAdministrator]} then {
          205  +  fail "this tool must run with \"elevated administrator\" privileges"
          206  +}
          207  +
          208  +set path [file normalize [file dirname $script]]
          209  +set argc [llength $argv]; if {$argc > 1} then {fail "" true}
          210  +
          211  +if {$argc == 1} then {
          212  +  set vsixFileName [lindex $argv 0]
          213  +} else {
          214  +  set vsixFileName [file join \
          215  +      [file dirname $path] sqlite-UWP-output.vsix]
          216  +}
          217  +
          218  +###############################################################################
          219  +
          220  +if {[isBadFile $vsixFileName]} then {
          221  +  fail [appendArgs \
          222  +      "VSIX file \"" $vsixFileName "\" does not exist"]
          223  +}
          224  +
          225  +set versionFileName [file join [file dirname $path] VERSION]
          226  +
          227  +if {[isBadFile $versionFileName]} then {
          228  +  fail [appendArgs \
          229  +      "Version file \"" $versionFileName "\" does not exist"]
          230  +}
          231  +
          232  +set projectTemplateFileName [file join $path vsixtest.vcxproj.data]
          233  +
          234  +if {[isBadFile $projectTemplateFileName]} then {
          235  +  fail [appendArgs \
          236  +      "Project template file \"" $projectTemplateFileName \
          237  +      "\" does not exist"]
          238  +}
          239  +
          240  +set envVarName VS140COMNTOOLS
          241  +set vsDirectory [getEnvironmentVariable $envVarName]
          242  +
          243  +if {[isBadDirectory $vsDirectory]} then {
          244  +  fail [appendArgs \
          245  +      "Visual Studio 2015 directory \"" $vsDirectory \
          246  +      "\" from environment variable \"" $envVarName \
          247  +      "\" does not exist"]
          248  +}
          249  +
          250  +set vsixInstaller [file join \
          251  +    [file dirname $vsDirectory] IDE VSIXInstaller.exe]
          252  +
          253  +if {[isBadFile $vsixInstaller]} then {
          254  +  fail [appendArgs \
          255  +      "Visual Studio 2015 VSIX installer \"" $vsixInstaller \
          256  +      "\" does not exist"]
          257  +}
          258  +
          259  +set envVarName ProgramFiles
          260  +set programFiles [getEnvironmentVariable $envVarName]
          261  +
          262  +if {[isBadDirectory $programFiles]} then {
          263  +  fail [appendArgs \
          264  +      "Program Files directory \"" $programFiles \
          265  +      "\" from environment variable \"" $envVarName \
          266  +      "\" does not exist"]
          267  +}
          268  +
          269  +set msBuild [file join $programFiles MSBuild 14.0 Bin MSBuild.exe]
          270  +
          271  +if {[isBadFile $msBuild]} then {
          272  +  fail [appendArgs \
          273  +      "MSBuild v14.0 executable file \"" $msBuild \
          274  +      "\" does not exist"]
          275  +}
          276  +
          277  +set temporaryDirectory [getTemporaryPath]
          278  +
          279  +if {[isBadDirectory $temporaryDirectory]} then {
          280  +  fail [appendArgs \
          281  +      "Temporary directory \"" $temporaryDirectory \
          282  +      "\" does not exist"]
          283  +}
          284  +
          285  +###############################################################################
          286  +
          287  +set installLogFileName [appendArgs \
          288  +    [file rootname [file tail $vsixFileName]] \
          289  +    -install- [pid] .log]
          290  +
          291  +set commands(1) [list exec [file nativename $vsixInstaller]]
          292  +
          293  +lappend commands(1) /quiet /norepair
          294  +lappend commands(1) [appendArgs /logFile: $installLogFileName]
          295  +lappend commands(1) [file nativename $vsixFileName]
          296  +
          297  +###############################################################################
          298  +
          299  +set buildLogFileName [appendArgs \
          300  +    [file rootname [file tail $vsixFileName]] \
          301  +    -build-%configuration%-%platform%- [pid] .log]
          302  +
          303  +set commands(2) [list exec [file nativename $msBuild]]
          304  +
          305  +lappend commands(2) [file nativename [file join $path vsixtest.sln]]
          306  +lappend commands(2) /target:Rebuild
          307  +lappend commands(2) /property:Configuration=%configuration%
          308  +lappend commands(2) /property:Platform=%platform%
          309  +
          310  +lappend commands(2) [appendArgs \
          311  +    /logger:FileLogger,Microsoft.Build.Engine\;Logfile= \
          312  +    [file nativename [file join $temporaryDirectory \
          313  +    $buildLogFileName]] \;Verbosity=diagnostic]
          314  +
          315  +###############################################################################
          316  +
          317  +set uninstallLogFileName [appendArgs \
          318  +    [file rootname [file tail $vsixFileName]] \
          319  +    -uninstall- [pid] .log]
          320  +
          321  +set commands(3) [list exec [file nativename $vsixInstaller]]
          322  +
          323  +lappend commands(3) /quiet /norepair
          324  +lappend commands(3) [appendArgs /logFile: $uninstallLogFileName]
          325  +lappend commands(3) [appendArgs /uninstall:SQLite.UWP.2015]
          326  +
          327  +###############################################################################
          328  +
          329  +if {1} then {
          330  +  catch {
          331  +    puts stdout [appendArgs \
          332  +        "Install log: \"" [file nativename [file join \
          333  +        $temporaryDirectory $installLogFileName]] \"\n]
          334  +  }
          335  +
          336  +  catch {
          337  +    puts stdout [appendArgs \
          338  +        "Build logs: \"" [file nativename [file join \
          339  +        $temporaryDirectory $buildLogFileName]] \"\n]
          340  +  }
          341  +
          342  +  catch {
          343  +    puts stdout [appendArgs \
          344  +        "Uninstall log: \"" [file nativename [file join \
          345  +        $temporaryDirectory $uninstallLogFileName]] \"\n]
          346  +  }
          347  +}
          348  +
          349  +###############################################################################
          350  +
          351  +if {1} then {
          352  +  putsAndEval $commands(1)
          353  +
          354  +  set versionNumber [string trim [readFile $versionFileName]]
          355  +  set data [readFile $projectTemplateFileName]
          356  +  set data [string map [list %versionNumber% $versionNumber] $data]
          357  +
          358  +  set projectFileName [file join $path vsixtest.vcxproj]
          359  +  writeFile $projectFileName $data
          360  +
          361  +  set platforms [list x86 x64 ARM]
          362  +  set configurations [list Debug Release]
          363  +
          364  +  foreach platform $platforms {
          365  +    foreach configuration $configurations {
          366  +      putsAndEval [string map [list \
          367  +          %platform% $platform %configuration% $configuration] \
          368  +          $commands(2)]
          369  +    }
          370  +  }
          371  +
          372  +  putsAndEval $commands(3)
          373  +}

Added vsixtest/vsixtest.vcxproj.data.

            1  +<?xml version="1.0" encoding="utf-8"?>
            2  +<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
            3  +  <PropertyGroup Label="Globals">
            4  +    <ProjectGuid>{60bb14a5-0871-4656-bc38-4f0958230f9a}</ProjectGuid>
            5  +    <RootNamespace>vsixtest</RootNamespace>
            6  +    <DefaultLanguage>en-US</DefaultLanguage>
            7  +    <MinimumVisualStudioVersion>14.0</MinimumVisualStudioVersion>
            8  +    <AppContainerApplication>true</AppContainerApplication>
            9  +    <ApplicationType>Windows Store</ApplicationType>
           10  +    <WindowsTargetPlatformVersion>10.0.10586.0</WindowsTargetPlatformVersion>
           11  +    <WindowsTargetPlatformMinVersion>10.0.10586.0</WindowsTargetPlatformMinVersion>
           12  +    <ApplicationTypeRevision>10.0</ApplicationTypeRevision>
           13  +  </PropertyGroup>
           14  +  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
           15  +  <ItemGroup Label="ProjectConfigurations">
           16  +    <ProjectConfiguration Include="Debug|ARM">
           17  +      <Configuration>Debug</Configuration>
           18  +      <Platform>ARM</Platform>
           19  +    </ProjectConfiguration>
           20  +    <ProjectConfiguration Include="Debug|Win32">
           21  +      <Configuration>Debug</Configuration>
           22  +      <Platform>Win32</Platform>
           23  +    </ProjectConfiguration>
           24  +    <ProjectConfiguration Include="Debug|x64">
           25  +      <Configuration>Debug</Configuration>
           26  +      <Platform>x64</Platform>
           27  +    </ProjectConfiguration>
           28  +    <ProjectConfiguration Include="Release|ARM">
           29  +      <Configuration>Release</Configuration>
           30  +      <Platform>ARM</Platform>
           31  +    </ProjectConfiguration>
           32  +    <ProjectConfiguration Include="Release|Win32">
           33  +      <Configuration>Release</Configuration>
           34  +      <Platform>Win32</Platform>
           35  +    </ProjectConfiguration>
           36  +    <ProjectConfiguration Include="Release|x64">
           37  +      <Configuration>Release</Configuration>
           38  +      <Platform>x64</Platform>
           39  +    </ProjectConfiguration>
           40  +  </ItemGroup>
           41  +  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
           42  +    <ConfigurationType>Application</ConfigurationType>
           43  +    <UseDebugLibraries>true</UseDebugLibraries>
           44  +    <PlatformToolset>v140</PlatformToolset>
           45  +  </PropertyGroup>
           46  +  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="Configuration">
           47  +    <ConfigurationType>Application</ConfigurationType>
           48  +    <UseDebugLibraries>true</UseDebugLibraries>
           49  +    <PlatformToolset>v140</PlatformToolset>
           50  +  </PropertyGroup>
           51  +  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
           52  +    <ConfigurationType>Application</ConfigurationType>
           53  +    <UseDebugLibraries>true</UseDebugLibraries>
           54  +    <PlatformToolset>v140</PlatformToolset>
           55  +  </PropertyGroup>
           56  +  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
           57  +    <ConfigurationType>Application</ConfigurationType>
           58  +    <UseDebugLibraries>false</UseDebugLibraries>
           59  +    <WholeProgramOptimization>true</WholeProgramOptimization>
           60  +    <PlatformToolset>v140</PlatformToolset>
           61  +    <UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
           62  +  </PropertyGroup>
           63  +  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration">
           64  +    <ConfigurationType>Application</ConfigurationType>
           65  +    <UseDebugLibraries>false</UseDebugLibraries>
           66  +    <WholeProgramOptimization>true</WholeProgramOptimization>
           67  +    <PlatformToolset>v140</PlatformToolset>
           68  +    <UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
           69  +  </PropertyGroup>
           70  +  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
           71  +    <ConfigurationType>Application</ConfigurationType>
           72  +    <UseDebugLibraries>false</UseDebugLibraries>
           73  +    <WholeProgramOptimization>true</WholeProgramOptimization>
           74  +    <PlatformToolset>v140</PlatformToolset>
           75  +    <UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
           76  +  </PropertyGroup>
           77  +  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
           78  +  <ImportGroup Label="ExtensionSettings">
           79  +  </ImportGroup>
           80  +  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
           81  +    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
           82  +    <Import Project="$([Microsoft.Build.Utilities.ToolLocationHelper]::GetPlatformExtensionSDKLocation(`SQLite.UWP.2015, Version=%versionNumber%`, $(TargetPlatformIdentifier), $(TargetPlatformVersion),  $(SDKReferenceDirectoryRoot), $(SDKExtensionDirectoryRoot), $(SDKReferenceRegistryRoot)))\DesignTime\CommonConfiguration\Neutral\SQLite.UWP.2015.props" Condition="exists('$([Microsoft.Build.Utilities.ToolLocationHelper]::GetPlatformExtensionSDKLocation(`SQLite.UWP.2015, Version=%versionNumber%`, $(TargetPlatformIdentifier), $(TargetPlatformVersion),  $(SDKReferenceDirectoryRoot), $(SDKExtensionDirectoryRoot), $(SDKReferenceRegistryRoot)))\DesignTime\CommonConfiguration\Neutral\SQLite.UWP.2015.props')" />
           83  +  </ImportGroup>
           84  +  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
           85  +    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
           86  +    <Import Project="$([Microsoft.Build.Utilities.ToolLocationHelper]::GetPlatformExtensionSDKLocation(`SQLite.UWP.2015, Version=%versionNumber%`, $(TargetPlatformIdentifier), $(TargetPlatformVersion),  $(SDKReferenceDirectoryRoot), $(SDKExtensionDirectoryRoot), $(SDKReferenceRegistryRoot)))\DesignTime\CommonConfiguration\Neutral\SQLite.UWP.2015.props" Condition="exists('$([Microsoft.Build.Utilities.ToolLocationHelper]::GetPlatformExtensionSDKLocation(`SQLite.UWP.2015, Version=%versionNumber%`, $(TargetPlatformIdentifier), $(TargetPlatformVersion),  $(SDKReferenceDirectoryRoot), $(SDKExtensionDirectoryRoot), $(SDKReferenceRegistryRoot)))\DesignTime\CommonConfiguration\Neutral\SQLite.UWP.2015.props')" />
           87  +  </ImportGroup>
           88  +  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
           89  +    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
           90  +    <Import Project="$([Microsoft.Build.Utilities.ToolLocationHelper]::GetPlatformExtensionSDKLocation(`SQLite.UWP.2015, Version=%versionNumber%`, $(TargetPlatformIdentifier), $(TargetPlatformVersion),  $(SDKReferenceDirectoryRoot), $(SDKExtensionDirectoryRoot), $(SDKReferenceRegistryRoot)))\DesignTime\CommonConfiguration\Neutral\SQLite.UWP.2015.props" Condition="exists('$([Microsoft.Build.Utilities.ToolLocationHelper]::GetPlatformExtensionSDKLocation(`SQLite.UWP.2015, Version=%versionNumber%`, $(TargetPlatformIdentifier), $(TargetPlatformVersion),  $(SDKReferenceDirectoryRoot), $(SDKExtensionDirectoryRoot), $(SDKReferenceRegistryRoot)))\DesignTime\CommonConfiguration\Neutral\SQLite.UWP.2015.props')" />
           91  +  </ImportGroup>
           92  +  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
           93  +    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
           94  +    <Import Project="$([Microsoft.Build.Utilities.ToolLocationHelper]::GetPlatformExtensionSDKLocation(`SQLite.UWP.2015, Version=%versionNumber%`, $(TargetPlatformIdentifier), $(TargetPlatformVersion),  $(SDKReferenceDirectoryRoot), $(SDKExtensionDirectoryRoot), $(SDKReferenceRegistryRoot)))\DesignTime\CommonConfiguration\Neutral\SQLite.UWP.2015.props" Condition="exists('$([Microsoft.Build.Utilities.ToolLocationHelper]::GetPlatformExtensionSDKLocation(`SQLite.UWP.2015, Version=%versionNumber%`, $(TargetPlatformIdentifier), $(TargetPlatformVersion),  $(SDKReferenceDirectoryRoot), $(SDKExtensionDirectoryRoot), $(SDKReferenceRegistryRoot)))\DesignTime\CommonConfiguration\Neutral\SQLite.UWP.2015.props')" />
           95  +  </ImportGroup>
           96  +  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
           97  +    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
           98  +    <Import Project="$([Microsoft.Build.Utilities.ToolLocationHelper]::GetPlatformExtensionSDKLocation(`SQLite.UWP.2015, Version=%versionNumber%`, $(TargetPlatformIdentifier), $(TargetPlatformVersion),  $(SDKReferenceDirectoryRoot), $(SDKExtensionDirectoryRoot), $(SDKReferenceRegistryRoot)))\DesignTime\CommonConfiguration\Neutral\SQLite.UWP.2015.props" Condition="exists('$([Microsoft.Build.Utilities.ToolLocationHelper]::GetPlatformExtensionSDKLocation(`SQLite.UWP.2015, Version=%versionNumber%`, $(TargetPlatformIdentifier), $(TargetPlatformVersion),  $(SDKReferenceDirectoryRoot), $(SDKExtensionDirectoryRoot), $(SDKReferenceRegistryRoot)))\DesignTime\CommonConfiguration\Neutral\SQLite.UWP.2015.props')" />
           99  +  </ImportGroup>
          100  +  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
          101  +    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
          102  +    <Import Project="$([Microsoft.Build.Utilities.ToolLocationHelper]::GetPlatformExtensionSDKLocation(`SQLite.UWP.2015, Version=%versionNumber%`, $(TargetPlatformIdentifier), $(TargetPlatformVersion),  $(SDKReferenceDirectoryRoot), $(SDKExtensionDirectoryRoot), $(SDKReferenceRegistryRoot)))\DesignTime\CommonConfiguration\Neutral\SQLite.UWP.2015.props" Condition="exists('$([Microsoft.Build.Utilities.ToolLocationHelper]::GetPlatformExtensionSDKLocation(`SQLite.UWP.2015, Version=%versionNumber%`, $(TargetPlatformIdentifier), $(TargetPlatformVersion),  $(SDKReferenceDirectoryRoot), $(SDKExtensionDirectoryRoot), $(SDKReferenceRegistryRoot)))\DesignTime\CommonConfiguration\Neutral\SQLite.UWP.2015.props')" />
          103  +  </ImportGroup>
          104  +  <PropertyGroup Label="UserMacros" />
          105  +  <PropertyGroup>
          106  +    <PackageCertificateKeyFile>vsixtest_TemporaryKey.pfx</PackageCertificateKeyFile>
          107  +  </PropertyGroup>
          108  +  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
          109  +    <ClCompile>
          110  +      <AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
          111  +      <DisableSpecificWarnings>4453;28204</DisableSpecificWarnings>
          112  +    </ClCompile>
          113  +  </ItemDefinitionGroup>
          114  +  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
          115  +    <ClCompile>
          116  +      <AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
          117  +      <DisableSpecificWarnings>4453;28204</DisableSpecificWarnings>
          118  +    </ClCompile>
          119  +  </ItemDefinitionGroup>
          120  +  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
          121  +    <ClCompile>
          122  +      <AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
          123  +      <DisableSpecificWarnings>4453;28204</DisableSpecificWarnings>
          124  +    </ClCompile>
          125  +  </ItemDefinitionGroup>
          126  +  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
          127  +    <ClCompile>
          128  +      <AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
          129  +      <DisableSpecificWarnings>4453;28204</DisableSpecificWarnings>
          130  +    </ClCompile>
          131  +  </ItemDefinitionGroup>
          132  +  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
          133  +    <ClCompile>
          134  +      <AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
          135  +      <DisableSpecificWarnings>4453;28204</DisableSpecificWarnings>
          136  +    </ClCompile>
          137  +  </ItemDefinitionGroup>
          138  +  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
          139  +    <ClCompile>
          140  +      <AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
          141  +      <DisableSpecificWarnings>4453;28204</DisableSpecificWarnings>
          142  +    </ClCompile>
          143  +  </ItemDefinitionGroup>
          144  +  <ItemGroup>
          145  +    <ClInclude Include="pch.h" />
          146  +    <ClInclude Include="App.xaml.h">
          147  +      <DependentUpon>App.xaml</DependentUpon>
          148  +    </ClInclude>
          149  +    <ClInclude Include="MainPage.xaml.h">
          150  +      <DependentUpon>MainPage.xaml</DependentUpon>
          151  +    </ClInclude>
          152  +  </ItemGroup>
          153  +  <ItemGroup>
          154  +    <ApplicationDefinition Include="App.xaml">
          155  +      <SubType>Designer</SubType>
          156  +    </ApplicationDefinition>
          157  +    <Page Include="MainPage.xaml">
          158  +      <SubType>Designer</SubType>
          159  +    </Page>
          160  +  </ItemGroup>
          161  +  <ItemGroup>
          162  +    <AppxManifest Include="Package.appxmanifest">
          163  +      <SubType>Designer</SubType>
          164  +    </AppxManifest>
          165  +    <None Include="vsixtest_TemporaryKey.pfx" />
          166  +  </ItemGroup>
          167  +  <ItemGroup>
          168  +    <Image Include="Assets\LockScreenLogo.scale-200.png" />
          169  +    <Image Include="Assets\SplashScreen.scale-200.png" />
          170  +    <Image Include="Assets\Square150x150Logo.scale-200.png" />
          171  +    <Image Include="Assets\Square44x44Logo.scale-200.png" />
          172  +    <Image Include="Assets\Square44x44Logo.targetsize-24_altform-unplated.png" />
          173  +    <Image Include="Assets\StoreLogo.png" />
          174  +    <Image Include="Assets\Wide310x150Logo.scale-200.png" />
          175  +  </ItemGroup>
          176  +  <ItemGroup>
          177  +    <ClCompile Include="App.xaml.cpp">
          178  +      <DependentUpon>App.xaml</DependentUpon>
          179  +    </ClCompile>
          180  +    <ClCompile Include="MainPage.xaml.cpp">
          181  +      <DependentUpon>MainPage.xaml</DependentUpon>
          182  +    </ClCompile>
          183  +    <ClCompile Include="pch.cpp">
          184  +      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
          185  +      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
          186  +      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">Create</PrecompiledHeader>
          187  +      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">Create</PrecompiledHeader>
          188  +      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
          189  +      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
          190  +    </ClCompile>
          191  +  </ItemGroup>
          192  +  <ItemGroup>
          193  +    <SDKReference Include="SQLite.UWP.2015, Version=%versionNumber%" />
          194  +  </ItemGroup>
          195  +  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
          196  +  <ImportGroup Label="ExtensionTargets">
          197  +  </ImportGroup>
          198  +</Project>

Added vsixtest/vsixtest.vcxproj.filters.

            1  +<?xml version="1.0" encoding="utf-8"?>
            2  +<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
            3  +  <ItemGroup>
            4  +    <Filter Include="Common">
            5  +      <UniqueIdentifier>60bb14a5-0871-4656-bc38-4f0958230f9a</UniqueIdentifier>
            6  +    </Filter>
            7  +    <Filter Include="Assets">
            8  +      <UniqueIdentifier>e6271362-8f96-476d-907f-4da227b02435</UniqueIdentifier>
            9  +      <Extensions>bmp;fbx;gif;jpg;jpeg;tga;tiff;tif;png</Extensions>
           10  +    </Filter>
           11  +  </ItemGroup>
           12  +  <ItemGroup>
           13  +    <ApplicationDefinition Include="App.xaml" />
           14  +  </ItemGroup>
           15  +  <ItemGroup>
           16  +    <ClCompile Include="App.xaml.cpp" />
           17  +    <ClCompile Include="MainPage.xaml.cpp" />
           18  +    <ClCompile Include="pch.cpp" />
           19  +  </ItemGroup>
           20  +  <ItemGroup>
           21  +    <ClInclude Include="pch.h" />
           22  +    <ClInclude Include="App.xaml.h" />
           23  +    <ClInclude Include="MainPage.xaml.h" />
           24  +  </ItemGroup>
           25  +  <ItemGroup>
           26  +    <Image Include="Assets\LockScreenLogo.scale-200.png">
           27  +      <Filter>Assets</Filter>
           28  +    </Image>
           29  +    <Image Include="Assets\SplashScreen.scale-200.png">
           30  +      <Filter>Assets</Filter>
           31  +    </Image>
           32  +    <Image Include="Assets\Square150x150Logo.scale-200.png">
           33  +      <Filter>Assets</Filter>
           34  +    </Image>
           35  +    <Image Include="Assets\Square44x44Logo.scale-200.png">
           36  +      <Filter>Assets</Filter>
           37  +    </Image>
           38  +    <Image Include="Assets\Square44x44Logo.targetsize-24_altform-unplated.png">
           39  +      <Filter>Assets</Filter>
           40  +    </Image>
           41  +    <Image Include="Assets\StoreLogo.png">
           42  +      <Filter>Assets</Filter>
           43  +    </Image>
           44  +    <Image Include="Assets\Wide310x150Logo.scale-200.png">
           45  +      <Filter>Assets</Filter>
           46  +    </Image>
           47  +  </ItemGroup>
           48  +  <ItemGroup>
           49  +    <AppxManifest Include="Package.appxmanifest" />
           50  +  </ItemGroup>
           51  +  <ItemGroup>
           52  +    <None Include="vsixtest_TemporaryKey.pfx" />
           53  +  </ItemGroup>
           54  +  <ItemGroup>
           55  +    <Page Include="MainPage.xaml" />
           56  +  </ItemGroup>
           57  +</Project>

Added vsixtest/vsixtest_TemporaryKey.pfx.

cannot compute difference between binary files