/ Check-in [2f0c195c]
Login

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

Overview
Comment:Merge recent enhancements from trunk, and especially the changes that reduce the heap-memory footprint of schemas, and defer opening and writing to statement journals.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | apple-osx
Files: files | file ages | folders
SHA1:2f0c195ccc3c9550f0664223fc355b1c27063eba
User & Date: drh 2016-03-04 14:57:51
Context
2016-03-07
20:48
Merge recent enhancements from trunk. check-in: 84f09f00 user: drh tags: apple-osx
2016-03-04
14:57
Merge recent enhancements from trunk, and especially the changes that reduce the heap-memory footprint of schemas, and defer opening and writing to statement journals. check-in: 2f0c195c user: drh tags: apple-osx
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-26
16:14
Merge all recent enhancements from trunk, and in particular the SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER change. check-in: 4fb4aee8 user: drh tags: apple-osx
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to Makefile.in.

   374    374     $(TOP)/src/test6.c \
   375    375     $(TOP)/src/test7.c \
   376    376     $(TOP)/src/test8.c \
   377    377     $(TOP)/src/test9.c \
   378    378     $(TOP)/src/test_autoext.c \
   379    379     $(TOP)/src/test_async.c \
   380    380     $(TOP)/src/test_backup.c \
          381  +  $(TOP)/src/test_bestindex.c \
   381    382     $(TOP)/src/test_blob.c \
   382    383     $(TOP)/src/test_btree.c \
   383    384     $(TOP)/src/test_config.c \
   384    385     $(TOP)/src/test_demovfs.c \
   385    386     $(TOP)/src/test_devsym.c \
   386    387     $(TOP)/src/test_fs.c \
   387    388     $(TOP)/src/test_func.c \
................................................................................
  1058   1059   # fixture.  Otherwise link against libsqlite3.la.  (This distinction is
  1059   1060   # necessary because the test fixture requires non-API symbols which are
  1060   1061   # hidden when the library is built via the amalgamation).
  1061   1062   #
  1062   1063   TESTFIXTURE_FLAGS  = -DTCLSH=1 -DSQLITE_TEST=1 -DSQLITE_CRASH_TEST=1
  1063   1064   TESTFIXTURE_FLAGS += -DSQLITE_SERVER=1 -DSQLITE_PRIVATE="" -DSQLITE_CORE 
  1064   1065   TESTFIXTURE_FLAGS += -DBUILD_sqlite
         1066  +TESTFIXTURE_FLAGS += -DSQLITE_SERIES_CONSTRAINT_VERIFY=1
         1067  +TESTFIXTURE_FLAGS += -DSQLITE_DEFAULT_PAGE_SIZE=1024
  1065   1068   
  1066   1069   TESTFIXTURE_SRC0 = $(TESTSRC2) libsqlite3.la
  1067   1070   TESTFIXTURE_SRC1 = sqlite3.c
  1068   1071   TESTFIXTURE_SRC = $(TESTSRC) $(TOP)/src/tclsqlite.c
  1069   1072   TESTFIXTURE_SRC += $(TESTFIXTURE_SRC$(USE_AMALGAMATION))
  1070   1073   
  1071   1074   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
................................................................................
  1220   1232     $(TOP)\src\test6.c \
  1221   1233     $(TOP)\src\test7.c \
  1222   1234     $(TOP)\src\test8.c \
  1223   1235     $(TOP)\src\test9.c \
  1224   1236     $(TOP)\src\test_autoext.c \
  1225   1237     $(TOP)\src\test_async.c \
  1226   1238     $(TOP)\src\test_backup.c \
         1239  +  $(TOP)\src\test_bestindex.c \
  1227   1240     $(TOP)\src\test_blob.c \
  1228   1241     $(TOP)\src\test_btree.c \
  1229   1242     $(TOP)\src\test_config.c \
  1230   1243     $(TOP)\src\test_demovfs.c \
  1231   1244     $(TOP)\src\test_devsym.c \
  1232   1245     $(TOP)\src\test_fs.c \
  1233   1246     $(TOP)\src\test_func.c \
................................................................................
  1383   1396   # This is the default Makefile target.  The objects listed here
  1384   1397   # are what get build when you type just "make" with no arguments.
  1385   1398   #
  1386   1399   all:	dll libsqlite3.lib shell $(ALL_TCL_TARGETS)
  1387   1400   
  1388   1401   # Dynamic link library section.
  1389   1402   #
  1390         -dll: $(SQLITE3DLL)
         1403  +dll:	$(SQLITE3DLL)
  1391   1404   
  1392   1405   # Shell executable.
  1393   1406   #
  1394         -shell: $(SQLITE3EXE)
         1407  +shell:	$(SQLITE3EXE)
  1395   1408   
  1396   1409   # <<mark>>
  1397   1410   libsqlite3.lib:	$(LIBOBJ)
  1398   1411   	$(LTLIB) $(LTLIBOPTS) /OUT:$@ $(LIBOBJ) $(TLIBS)
  1399   1412   
  1400   1413   libtclsqlite3.lib:	tclsqlite.lo libsqlite3.lib
  1401   1414   	$(LTLIB) $(LTLIBOPTS) $(LTLIBPATHS) /OUT:$@ tclsqlite.lo libsqlite3.lib $(LIBTCLSTUB) $(TLIBS)
  1402   1415   # <</mark>>
  1403   1416   
  1404         -$(SQLITE3DLL): $(LIBOBJ) $(LIBRESOBJS) $(CORE_LINK_DEP)
         1417  +$(SQLITE3DLL):	$(LIBOBJ) $(LIBRESOBJS) $(CORE_LINK_DEP)
  1405   1418   	$(LD) $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) /DLL $(CORE_LINK_OPTS) /OUT:$@ $(LIBOBJ) $(LIBRESOBJS) $(LTLIBS) $(TLIBS)
  1406   1419   
  1407         -# <<mark>>
  1408         -sqlite3.def: libsqlite3.lib
         1420  +# <<block2>>
         1421  +sqlite3.def:	libsqlite3.lib
  1409   1422   	echo EXPORTS > sqlite3.def
  1410   1423   	dumpbin /all libsqlite3.lib \
  1411         -		| $(TCLSH_CMD) $(TOP)\tool\replace.tcl include "^\s+1 _?(sqlite3_.*)$$" \1 \
         1424  +		| $(TCLSH_CMD) $(TOP)\tool\replace.tcl include "^\s+1 _?(sqlite3_[^@]*)(?:@\d+)?$$" \1 \
  1412   1425   		| sort >> sqlite3.def
  1413         -# <</mark>>
         1426  +# <</block2>>
  1414   1427   
  1415   1428   $(SQLITE3EXE):	$(TOP)\src\shell.c $(SHELL_CORE_DEP) $(LIBRESOBJS) $(SHELL_CORE_SRC) $(SQLITE3H)
  1416   1429   	$(LTLINK) $(SHELL_COMPILE_OPTS) $(READLINE_FLAGS) $(TOP)\src\shell.c $(SHELL_CORE_SRC) \
  1417   1430   		/link $(SQLITE3EXEPDB) $(LDFLAGS) $(LTLINKOPTS) $(SHELL_LINK_OPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LIBREADLINE) $(LTLIBS) $(TLIBS)
  1418   1431   
  1419   1432   # <<mark>>
  1420   1433   sqldiff.exe:	$(TOP)\tool\sqldiff.c $(SQLITE3C) $(SQLITE3H)
................................................................................
  1780   1793   	.\lemon.exe $(REQ_FEATURE_FLAGS) $(OPT_FEATURE_FLAGS) $(EXT_FEATURE_FLAGS) $(OPTS) parse.y
  1781   1794   	move parse.h parse.h.temp
  1782   1795   	$(TCLSH_CMD) $(TOP)\tool\addopcodes.tcl parse.h.temp > parse.h
  1783   1796   
  1784   1797   $(SQLITE3H):	$(TOP)\src\sqlite.h.in $(TOP)\manifest.uuid $(TOP)\VERSION
  1785   1798   	$(TCLSH_CMD) $(TOP)\tool\mksqlite3h.tcl $(TOP:\=/) > $(SQLITE3H)
  1786   1799   
  1787         -sqlite3ext.h: .target_source
         1800  +sqlite3ext.h:	.target_source
  1788   1801   	copy tsrc\sqlite3ext.h .
  1789   1802   
  1790   1803   mkkeywordhash.exe:	$(TOP)\tool\mkkeywordhash.c
  1791   1804   	$(BCC) $(NO_WARN) -Fe$@ $(REQ_FEATURE_FLAGS) $(OPT_FEATURE_FLAGS) $(EXT_FEATURE_FLAGS) $(OPTS) \
  1792   1805   		$(TOP)\tool\mkkeywordhash.c /link $(LDFLAGS) $(NLTLINKOPTS) $(NLTLIBPATHS)
  1793   1806   
  1794   1807   keywordhash.h:	$(TOP)\tool\mkkeywordhash.c mkkeywordhash.exe
................................................................................
  1881   1894      $(TOP)\ext\fts5\fts5_vocab.c
  1882   1895   
  1883   1896   fts5parse.c:	$(TOP)\ext\fts5\fts5parse.y lemon.exe
  1884   1897   	copy $(TOP)\ext\fts5\fts5parse.y .
  1885   1898   	del /Q fts5parse.h 2>NUL
  1886   1899   	.\lemon.exe $(REQ_FEATURE_FLAGS) $(OPT_FEATURE_FLAGS) $(EXT_FEATURE_FLAGS) $(OPTS) fts5parse.y
  1887   1900   
  1888         -fts5parse.h: fts5parse.c
         1901  +fts5parse.h:	fts5parse.c
  1889   1902   
  1890         -fts5.c: $(FTS5_SRC)
         1903  +fts5.c:	$(FTS5_SRC)
  1891   1904   	$(TCLSH_CMD) $(TOP)\ext\fts5\tool\mkfts5c.tcl
  1892   1905   	copy $(TOP)\ext\fts5\fts5.h .
  1893   1906   
  1894   1907   fts5.lo:	fts5.c $(HDR) $(EXTHDR)
  1895   1908   	$(LTCOMPILE) $(CORE_COMPILE_OPTS) $(NO_WARN) -DSQLITE_CORE -c fts5.c
  1896   1909   
  1897   1910   fts5_ext.lo:	fts5.c $(HDR) $(EXTHDR)
................................................................................
  1909   1922   # fixture.  Otherwise link against libsqlite3.lib.  (This distinction is
  1910   1923   # necessary because the test fixture requires non-API symbols which are
  1911   1924   # hidden when the library is built via the amalgamation).
  1912   1925   #
  1913   1926   TESTFIXTURE_FLAGS = -DTCLSH=1 -DSQLITE_TEST=1 -DSQLITE_CRASH_TEST=1
  1914   1927   TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_SERVER=1 -DSQLITE_PRIVATE=""
  1915   1928   TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_CORE $(NO_WARN)
         1929  +TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_SERIES_CONSTRAINT_VERIFY=1
         1930  +TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_DEFAULT_PAGE_SIZE=1024
  1916   1931   
  1917   1932   TESTFIXTURE_SRC0 = $(TESTEXT) $(TESTSRC2)
  1918   1933   TESTFIXTURE_SRC1 = $(TESTEXT) $(SQLITE3C)
  1919   1934   !IF $(USE_AMALGAMATION)==0
  1920   1935   TESTFIXTURE_SRC = $(TESTSRC) $(TOP)\src\tclsqlite.c $(TESTFIXTURE_SRC0)
  1921   1936   !ELSE
  1922   1937   TESTFIXTURE_SRC = $(TESTSRC) $(TOP)\src\tclsqlite.c $(TESTFIXTURE_SRC1)
................................................................................
  1924   1939   
  1925   1940   testfixture.exe:	$(TESTFIXTURE_SRC) $(SQLITE3H) $(LIBRESOBJS) $(HDR)
  1926   1941   	$(LTLINK) -DSQLITE_NO_SYNC=1 $(TESTFIXTURE_FLAGS) \
  1927   1942   		-DBUILD_sqlite -I$(TCLINCDIR) \
  1928   1943   		$(TESTFIXTURE_SRC) \
  1929   1944   		/link $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LTLIBS) $(TLIBS)
  1930   1945   
  1931         -extensiontest: testfixture.exe testloadext.dll
         1946  +extensiontest:	testfixture.exe testloadext.dll
  1932   1947   	@set PATH=$(LIBTCLPATH);$(PATH)
  1933   1948   	.\testfixture.exe $(TOP)\test\loadext.test $(TESTOPTS)
  1934   1949   
  1935   1950   fulltest:	$(TESTPROGS) fuzztest
  1936   1951   	@set PATH=$(LIBTCLPATH);$(PATH)
  1937   1952   	.\testfixture.exe $(TOP)\test\all.test $(TESTOPTS)
  1938   1953   
................................................................................
  1967   1982   	@set PATH=$(LIBTCLPATH);$(PATH)
  1968   1983   	.\testfixture.exe $(TOP)\test\veryquick.test $(TESTOPTS)
  1969   1984   
  1970   1985   smoketest:	$(TESTPROGS)
  1971   1986   	@set PATH=$(LIBTCLPATH);$(PATH)
  1972   1987   	.\testfixture.exe $(TOP)\test\main.test $(TESTOPTS)
  1973   1988   
  1974         -sqlite3_analyzer.c: $(SQLITE3C) $(SQLITE3H) $(TOP)\src\tclsqlite.c $(TOP)\tool\spaceanal.tcl
         1989  +sqlite3_analyzer.c:	$(SQLITE3C) $(SQLITE3H) $(TOP)\src\tclsqlite.c $(TOP)\tool\spaceanal.tcl
  1975   1990   	echo #define TCLSH 2 > $@
  1976   1991   	echo #define SQLITE_ENABLE_DBSTAT_VTAB 1 >> $@
  1977   1992   	copy $@ + $(SQLITE3C) + $(TOP)\src\tclsqlite.c $@
  1978   1993   	echo static const char *tclsh_main_loop(void){ >> $@
  1979   1994   	echo static const char *zMainloop = >> $@
  1980   1995   	$(TCLSH_CMD) $(TOP)\tool\tostr.tcl $(TOP)\tool\spaceanal.tcl >> $@
  1981   1996   	echo ; return zMainloop; } >> $@
................................................................................
  1983   1998   sqlite3_analyzer.exe:	sqlite3_analyzer.c $(LIBRESOBJS)
  1984   1999   	$(LTLINK) $(NO_WARN) -DBUILD_sqlite -I$(TCLINCDIR) sqlite3_analyzer.c \
  1985   2000   		/link $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LTLIBS) $(TLIBS)
  1986   2001   
  1987   2002   testloadext.lo:	$(TOP)\src\test_loadext.c
  1988   2003   	$(LTCOMPILE) $(NO_WARN) -c $(TOP)\src\test_loadext.c
  1989   2004   
  1990         -testloadext.dll: testloadext.lo
         2005  +testloadext.dll:	testloadext.lo
  1991   2006   	$(LD) $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) /DLL /OUT:$@ testloadext.lo
  1992   2007   
  1993   2008   showdb.exe:	$(TOP)\tool\showdb.c $(SQLITE3C) $(SQLITE3H)
  1994   2009   	$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \
  1995   2010   		$(TOP)\tool\showdb.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
  1996   2011   
  1997   2012   showstat4.exe:	$(TOP)\tool\showstat4.c $(SQLITE3C) $(SQLITE3H)
................................................................................
  2021   2036   	$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \
  2022   2037   		$(TOP)\test\wordcount.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
  2023   2038   
  2024   2039   speedtest1.exe:	$(TOP)\test\speedtest1.c $(SQLITE3C) $(SQLITE3H)
  2025   2040   	$(LTLINK) $(NO_WARN) -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \
  2026   2041   		$(TOP)\test\speedtest1.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
  2027   2042   
  2028         -rbu.exe: $(TOP)\ext\rbu\rbu.c $(TOP)\ext\rbu\sqlite3rbu.c $(SQLITE3C) $(SQLITE3H)
         2043  +rbu.exe:	$(TOP)\ext\rbu\rbu.c $(TOP)\ext\rbu\sqlite3rbu.c $(SQLITE3C) $(SQLITE3H)
  2029   2044   	$(LTLINK) $(NO_WARN) -DSQLITE_ENABLE_RBU -Fe$@ \
  2030   2045   		$(TOP)\ext\rbu\rbu.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
         2046  +
         2047  +moreclean:	clean
         2048  +	del /Q $(SQLITE3C) $(SQLITE3H) 2>NUL
  2031   2049   # <</mark>>
  2032   2050   
  2033   2051   clean:
  2034   2052   	del /Q *.exp *.lo *.ilk *.lib *.obj *.ncb *.pdb *.sdf *.suo 2>NUL
  2035   2053   	del /Q *.bsc *.def *.cod *.da *.bb *.bbg *.vc gmon.out 2>NUL
  2036         -	del /Q $(SQLITE3EXE) $(SQLITE3DLL) 2>NUL
         2054  +	del /Q $(SQLITE3EXE) $(SQLITE3DLL) Replace.exe 2>NUL
  2037   2055   # <<mark>>
  2038         -	del /Q $(SQLITE3C) $(SQLITE3H) opcodes.c opcodes.h 2>NUL
         2056  +	del /Q sqlite3.c sqlite3.h 2>NUL
         2057  +	del /Q opcodes.c opcodes.h 2>NUL
  2039   2058   	del /Q lemon.* lempar.c parse.* 2>NUL
  2040   2059   	del /Q mkkeywordhash.* keywordhash.h 2>NUL
  2041   2060   	del /Q notasharedlib.* 2>NUL
  2042   2061   	-rmdir /Q/S .deps 2>NUL
  2043   2062   	-rmdir /Q/S .libs 2>NUL
  2044   2063   	-rmdir /Q/S quota2a 2>NUL
  2045   2064   	-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/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.

   351    351   **     lower('I', 'en_us') -> 'i'
   352    352   **     lower('I', 'tr_tr') -> 'ı' (small dotless i)
   353    353   **
   354    354   ** http://www.icu-project.org/userguide/posix.html#case_mappings
   355    355   */
   356    356   static void icuCaseFunc16(sqlite3_context *p, int nArg, sqlite3_value **apArg){
   357    357     const UChar *zInput;
   358         -  UChar *zOutput;
          358  +  UChar *zOutput = 0;
   359    359     int nInput;
   360         -  int nOutput;
   361         -
   362         -  UErrorCode status = U_ZERO_ERROR;
          360  +  int nOut;
          361  +  int cnt;
          362  +  UErrorCode status;
   363    363     const char *zLocale = 0;
   364    364   
   365    365     assert(nArg==1 || nArg==2);
   366    366     if( nArg==2 ){
   367    367       zLocale = (const char *)sqlite3_value_text(apArg[1]);
   368    368     }
   369    369   
   370    370     zInput = sqlite3_value_text16(apArg[0]);
   371    371     if( !zInput ){
   372    372       return;
   373    373     }
   374         -  nInput = sqlite3_value_bytes16(apArg[0]);
   375         -
   376         -  nOutput = nInput * 2 + 2;
   377         -  zOutput = sqlite3_malloc(nOutput);
   378         -  if( !zOutput ){
          374  +  nOut = nInput = sqlite3_value_bytes16(apArg[0]);
          375  +  if( nOut==0 ){
          376  +    sqlite3_result_text16(p, "", 0, SQLITE_STATIC);
   379    377       return;
   380    378     }
   381    379   
   382         -  if( sqlite3_user_data(p) ){
   383         -    u_strToUpper(zOutput, nOutput/2, zInput, nInput/2, zLocale, &status);
   384         -  }else{
   385         -    u_strToLower(zOutput, nOutput/2, zInput, nInput/2, zLocale, &status);
   386         -  }
   387         -
   388         -  if( !U_SUCCESS(status) ){
   389         -    icuFunctionError(p, "u_strToLower()/u_strToUpper", status);
   390         -    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  +    }
   391    400     }
   392         -
   393         -  sqlite3_result_text16(p, zOutput, -1, xFree);
          401  +  sqlite3_result_text16(p, zOutput, nOut, xFree);
   394    402   }
   395    403   
   396    404   /*
   397    405   ** Collation sequence destructor function. The pCtx argument points to
   398    406   ** a UCollator structure previously allocated using ucol_open().
   399    407   */
   400    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.

   283    283     $(TOP)/src/test6.c \
   284    284     $(TOP)/src/test7.c \
   285    285     $(TOP)/src/test8.c \
   286    286     $(TOP)/src/test9.c \
   287    287     $(TOP)/src/test_autoext.c \
   288    288     $(TOP)/src/test_async.c \
   289    289     $(TOP)/src/test_backup.c \
          290  +  $(TOP)/src/test_bestindex.c \
   290    291     $(TOP)/src/test_blob.c \
   291    292     $(TOP)/src/test_btree.c \
   292    293     $(TOP)/src/test_config.c \
   293    294     $(TOP)/src/test_demovfs.c \
   294    295     $(TOP)/src/test_devsym.c \
   295    296     $(TOP)/src/test_fs.c \
   296    297     $(TOP)/src/test_func.c \
................................................................................
   708    709   
   709    710   sqlite3_analyzer$(EXE): sqlite3_analyzer.c
   710    711   	$(TCCX) $(TCL_FLAGS) sqlite3_analyzer.c -o $@ $(LIBTCL) $(THREADLIB) 
   711    712   
   712    713   # Rules to build the 'testfixture' application.
   713    714   #
   714    715   TESTFIXTURE_FLAGS  = -DSQLITE_TEST=1 -DSQLITE_CRASH_TEST=1
   715         -TESTFIXTURE_FLAGS += -DSQLITE_SERVER=1 -DSQLITE_PRIVATE="" -DSQLITE_CORE 
          716  +TESTFIXTURE_FLAGS += -DSQLITE_SERVER=1 -DSQLITE_PRIVATE="" -DSQLITE_CORE
          717  +TESTFIXTURE_FLAGS += -DSQLITE_SERIES_CONSTRAINT_VERIFY=1
          718  +TESTFIXTURE_FLAGS += -DSQLITE_DEFAULT_PAGE_SIZE=1024
   716    719   
   717    720   testfixture$(EXE): $(TESTSRC2) libsqlite3.a $(TESTSRC) $(TOP)/src/tclsqlite.c
   718    721   	$(TCCX) $(TCL_FLAGS) -DTCLSH=1 $(TESTFIXTURE_FLAGS)                  \
   719    722   		$(TESTSRC) $(TESTSRC2) $(TOP)/src/tclsqlite.c                \
   720    723   		-o testfixture$(EXE) $(LIBTCL) libsqlite3.a $(THREADLIB)
   721    724   
   722    725   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/insert.c.

  1995   1995       if( sqlite3_stricmp(pDestCol->zColl, pSrcCol->zColl)!=0 ){
  1996   1996         return 0;    /* Collating sequence must be the same on all columns */
  1997   1997       }
  1998   1998       if( pDestCol->notNull && !pSrcCol->notNull ){
  1999   1999         return 0;    /* tab2 must be NOT NULL if tab1 is */
  2000   2000       }
  2001   2001       /* Default values for second and subsequent columns need to match. */
  2002         -    if( i>0
  2003         -     && ((pDestCol->zDflt==0)!=(pSrcCol->zDflt==0) 
  2004         -         || (pDestCol->zDflt && strcmp(pDestCol->zDflt, pSrcCol->zDflt)!=0))
  2005         -    ){
  2006         -      return 0;    /* Default values must be the same for all columns */
         2002  +    if( i>0 ){
         2003  +      assert( pDestCol->pDflt==0 || pDestCol->pDflt->op==TK_SPAN );
         2004  +      assert( pSrcCol->pDflt==0 || pSrcCol->pDflt->op==TK_SPAN );
         2005  +      if( (pDestCol->pDflt==0)!=(pSrcCol->pDflt==0) 
         2006  +       || (pDestCol->pDflt && strcmp(pDestCol->pDflt->u.zToken,
         2007  +                                       pSrcCol->pDflt->u.zToken)!=0)
         2008  +      ){
         2009  +        return 0;    /* Default values must be the same for all columns */
         2010  +      }
  2007   2011       }
  2008   2012     }
  2009   2013     for(pDestIdx=pDest->pIndex; pDestIdx; pDestIdx=pDestIdx->pNext){
  2010   2014       if( IsUniqueIndex(pDestIdx) ){
  2011   2015         destHasUniqueIdx = 1;
  2012   2016       }
  2013   2017       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.

  3450   3450     **     1. The specified column name was rowid", "oid" or "_rowid_" 
  3451   3451     **        and there is no explicitly declared IPK column. 
  3452   3452     **
  3453   3453     **     2. The table is not a view and the column name identified an 
  3454   3454     **        explicitly declared column. Copy meta information from *pCol.
  3455   3455     */ 
  3456   3456     if( pCol ){
  3457         -    zDataType = pCol->zType;
         3457  +    zDataType = sqlite3StrNext(pCol->zName);
         3458  +    if( zDataType[0]==0 ) zDataType = 0;
  3458   3459       zCollSeq = pCol->zColl;
  3459   3460       notnull = pCol->notNull!=0;
  3460   3461       primarykey  = (pCol->colFlags & COLFLAG_PRIMKEY)!=0;
  3461   3462       autoinc = pTab->iPKey==iCol && (pTab->tabFlags & TF_Autoincrement)!=0;
  3462   3463     }else{
  3463   3464       zDataType = "INTEGER";
  3464   3465       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);
................................................................................
  2733   2735     ** If a master journal file name is specified, but the file is not
  2734   2736     ** present on disk, then the journal is not hot and does not need to be
  2735   2737     ** played back.
  2736   2738     **
  2737   2739     ** TODO: Technically the following is an error because it assumes that
  2738   2740     ** buffer Pager.pTmpSpace is (mxPathname+1) bytes or larger. i.e. that
  2739   2741     ** (pPager->pageSize >= pPager->pVfs->mxPathname+1). Using os_unix.c,
  2740         -  **  mxPathname is 512, which is the same as the minimum allowable value
         2742  +  ** mxPathname is 512, which is the same as the minimum allowable value
  2741   2743     ** for pageSize.
  2742   2744     */
  2743   2745     zMaster = pPager->pTmpSpace;
  2744   2746     rc = readMasterJournal(pPager->jfd, zMaster, pPager->pVfs->mxPathname+1);
  2745   2747     if( rc==SQLITE_OK && zMaster[0] ){
  2746   2748       rc = sqlite3OsAccess(pVfs, zMaster, SQLITE_ACCESS_EXISTS, &res);
  2747   2749     }
................................................................................
  4361   4363   ** SQLITE_OK is returned if everything goes according to plan. An 
  4362   4364   ** SQLITE_IOERR_XXX error code is returned if a call to sqlite3OsOpen() 
  4363   4365   ** fails.
  4364   4366   */
  4365   4367   static int openSubJournal(Pager *pPager){
  4366   4368     int rc = SQLITE_OK;
  4367   4369     if( !isOpen(pPager->sjfd) ){
         4370  +    const int flags =  SQLITE_OPEN_SUBJOURNAL | SQLITE_OPEN_READWRITE 
         4371  +      | SQLITE_OPEN_CREATE | SQLITE_OPEN_EXCLUSIVE 
         4372  +      | SQLITE_OPEN_DELETEONCLOSE;
         4373  +    int nBuf = 64*1024;
  4368   4374       if( pPager->journalMode==PAGER_JOURNALMODE_MEMORY || pPager->subjInMemory ){
  4369         -      sqlite3MemJournalOpen(pPager->sjfd);
  4370         -    }else{
  4371         -      rc = pagerOpentemp(pPager, pPager->sjfd, SQLITE_OPEN_SUBJOURNAL);
         4375  +      nBuf = -1;
  4372   4376       }
         4377  +    rc = sqlite3JournalOpen(pPager->pVfs, 0, pPager->sjfd, flags, nBuf);
  4373   4378     }
  4374   4379     return rc;
  4375   4380   }
  4376   4381   
  4377   4382   /*
  4378   4383   ** Append a record of the current state of page pPg to the sub-journal. 
  4379   4384   **
................................................................................
  4586   4591     int useJournal = (flags & PAGER_OMIT_JOURNAL)==0; /* False to omit journal */
  4587   4592     int pcacheSize = sqlite3PcacheSize();       /* Bytes to allocate for PCache */
  4588   4593     u32 szPageDflt = SQLITE_DEFAULT_PAGE_SIZE;  /* Default page size */
  4589   4594     const char *zUri = 0;    /* URI args to copy */
  4590   4595     int nUri = 0;            /* Number of bytes of URI args at *zUri */
  4591   4596   
  4592   4597     /* Figure out how much space is required for each journal file-handle
  4593         -  ** (there are two of them, the main journal and the sub-journal). This
  4594         -  ** is the maximum space required for an in-memory journal file handle 
  4595         -  ** and a regular journal file-handle. Note that a "regular journal-handle"
  4596         -  ** may be a wrapper capable of caching the first portion of the journal
  4597         -  ** file in memory to implement the atomic-write optimization (see 
  4598         -  ** source file journal.c).
  4599         -  */
  4600         -  if( sqlite3JournalSize(pVfs)>sqlite3MemJournalSize() ){
  4601         -    journalFileSize = ROUND8(sqlite3JournalSize(pVfs));
  4602         -  }else{
  4603         -    journalFileSize = ROUND8(sqlite3MemJournalSize());
  4604         -  }
         4598  +  ** (there are two of them, the main journal and the sub-journal).  */
         4599  +  journalFileSize = ROUND8(sqlite3JournalSize(pVfs));
  4605   4600   
  4606   4601     /* Set the output variable to NULL in case an error occurs. */
  4607   4602     *ppPager = 0;
  4608   4603   
  4609   4604   #ifndef SQLITE_OMIT_MEMORYDB
  4610   4605     if( flags & PAGER_MEMORY ){
  4611   4606       memDb = 1;
................................................................................
  6689   6684       pPager->nSavepoint = nNew;
  6690   6685   
  6691   6686       /* If this is a release of the outermost savepoint, truncate 
  6692   6687       ** the sub-journal to zero bytes in size. */
  6693   6688       if( op==SAVEPOINT_RELEASE ){
  6694   6689         if( nNew==0 && isOpen(pPager->sjfd) ){
  6695   6690           /* Only truncate if it is an in-memory sub-journal. */
  6696         -        if( sqlite3IsMemJournal(pPager->sjfd) ){
         6691  +        if( sqlite3JournalIsInMemory(pPager->sjfd) ){
  6697   6692             rc = sqlite3OsTruncate(pPager->sjfd, 0);
  6698   6693             assert( rc==SQLITE_OK );
  6699   6694           }
  6700   6695           pPager->nSubRec = 0;
  6701   6696         }
  6702   6697       }
  6703   6698       /* 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.

  1078   1078         Column *pCol;
  1079   1079         Index *pPk = sqlite3PrimaryKeyIndex(pTab);
  1080   1080         pParse->nMem = 6;
  1081   1081         sqlite3CodeVerifySchema(pParse, iDb);
  1082   1082         setAllColumnNames(v, 6, azCol); assert( 6==ArraySize(azCol) );
  1083   1083         sqlite3ViewGetColumnNames(pParse, pTab);
  1084   1084         for(i=0, pCol=pTab->aCol; i<pTab->nCol; i++, pCol++){
         1085  +        const char *zName;
  1085   1086           if( IsHiddenColumn(pCol) ){
  1086   1087             nHidden++;
  1087   1088             continue;
  1088   1089           }
  1089   1090           if( (pCol->colFlags & COLFLAG_PRIMKEY)==0 ){
  1090   1091             k = 0;
  1091   1092           }else if( pPk==0 ){
  1092   1093             k = 1;
  1093   1094           }else{
  1094   1095             for(k=1; k<=pTab->nCol && pPk->aiColumn[k-1]!=i; k++){}
  1095   1096           }
         1097  +        assert( pCol->pDflt==0 || pCol->pDflt->op==TK_SPAN );
         1098  +        zName = pCol->zName;
  1096   1099           sqlite3VdbeMultiLoad(v, 1, "issisi",
  1097   1100                  i-nHidden,
  1098         -               pCol->zName,
  1099         -               pCol->zType ? pCol->zType : "",
         1101  +               zName,
         1102  +               sqlite3StrNext(zName),
  1100   1103                  pCol->notNull ? 1 : 0,
  1101         -               pCol->zDflt,
         1104  +               pCol->pDflt ? pCol->pDflt->u.zToken : 0,
  1102   1105                  k);
  1103   1106           sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 6);
  1104   1107         }
  1105   1108       }
  1106   1109     }
  1107   1110     break;
  1108   1111   

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       }

Changes to src/shell.c.

  1279   1279     int nErrMsg = 1+strlen30(sqlite3_errmsg(db));
  1280   1280     char *zErrMsg = sqlite3_malloc64(nErrMsg);
  1281   1281     if( zErrMsg ){
  1282   1282       memcpy(zErrMsg, sqlite3_errmsg(db), nErrMsg);
  1283   1283     }
  1284   1284     return zErrMsg;
  1285   1285   }
         1286  +
         1287  +#ifdef __linux__
         1288  +/*
         1289  +** Attempt to display I/O stats on Linux using /proc/PID/io
         1290  +*/
         1291  +static void displayLinuxIoStats(FILE *out){
         1292  +  FILE *in;
         1293  +  char z[200];
         1294  +  sqlite3_snprintf(sizeof(z), z, "/proc/%d/io", getpid());
         1295  +  in = fopen(z, "rb");
         1296  +  if( in==0 ) return;
         1297  +  while( fgets(z, sizeof(z), in)!=0 ){
         1298  +    static const struct {
         1299  +      const char *zPattern;
         1300  +      const char *zDesc;
         1301  +    } aTrans[] = {
         1302  +      { "rchar: ",                  "Bytes received by read():" },
         1303  +      { "wchar: ",                  "Bytes sent to write():"    },
         1304  +      { "syscr: ",                  "Read() system calls:"      },
         1305  +      { "syscw: ",                  "Write() system calls:"     },
         1306  +      { "read_bytes: ",             "Bytes read from storage:"  },
         1307  +      { "write_bytes: ",            "Bytes written to storage:" },
         1308  +      { "cancelled_write_bytes: ",  "Cancelled write bytes:"    },
         1309  +    };
         1310  +    int i;
         1311  +    for(i=0; i<ArraySize(aTrans); i++){
         1312  +      int n = (int)strlen(aTrans[i].zPattern);
         1313  +      if( strncmp(aTrans[i].zPattern, z, n)==0 ){
         1314  +        raw_printf(out, "%-36s %s", aTrans[i].zDesc, &z[n]);
         1315  +        break;
         1316  +      }
         1317  +    }
         1318  +  }
         1319  +  fclose(in);
         1320  +}   
         1321  +#endif
         1322  +
  1286   1323   
  1287   1324   /*
  1288   1325   ** Display memory stats.
  1289   1326   */
  1290   1327   static int display_stats(
  1291   1328     sqlite3 *db,                /* Database to query */
  1292   1329     ShellState *pArg,           /* Pointer to ShellState */
................................................................................
  1401   1438       iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_SORT, bReset);
  1402   1439       raw_printf(pArg->out, "Sort Operations:                     %d\n", iCur);
  1403   1440       iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_AUTOINDEX,bReset);
  1404   1441       raw_printf(pArg->out, "Autoindex Inserts:                   %d\n", iCur);
  1405   1442       iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_VM_STEP, bReset);
  1406   1443       raw_printf(pArg->out, "Virtual Machine Steps:               %d\n", iCur);
  1407   1444     }
         1445  +
         1446  +#ifdef __linux__
         1447  +  displayLinuxIoStats(pArg->out);
         1448  +#endif
  1408   1449   
  1409   1450     /* Do not remove this machine readable comment: extra-stats-output-here */
  1410   1451   
  1411   1452     return 0;
  1412   1453   }
  1413   1454   
  1414   1455   /*
................................................................................
  1953   1994     ".schema ?TABLE?        Show the CREATE statements\n"
  1954   1995     "                         If TABLE specified, only show tables matching\n"
  1955   1996     "                         LIKE pattern TABLE.\n"
  1956   1997     ".separator COL ?ROW?   Change the column separator and optionally the row\n"
  1957   1998     "                         separator for both the output mode and .import\n"
  1958   1999     ".shell CMD ARGS...     Run CMD ARGS... in a system shell\n"
  1959   2000     ".show                  Show the current values for various settings\n"
  1960         -  ".stats on|off          Turn stats on or off\n"
         2001  +  ".stats ?on|off?        Show stats or turn stats on or off\n"
  1961   2002     ".system CMD ARGS...    Run CMD ARGS... in a system shell\n"
  1962   2003     ".tables ?TABLE?        List names of tables\n"
  1963   2004     "                         If TABLE specified, only list tables matching\n"
  1964   2005     "                         LIKE pattern TABLE.\n"
  1965   2006     ".timeout MS            Try opening locked tables for MS milliseconds\n"
  1966   2007     ".timer on|off          Turn SQL timer on or off\n"
  1967   2008     ".trace FILE|off        Output each SQL statement as it is run\n"
................................................................................
  3831   3872       }
  3832   3873       raw_printf(p->out, "\n");
  3833   3874     }else
  3834   3875   
  3835   3876     if( c=='s' && strncmp(azArg[0], "stats", n)==0 ){
  3836   3877       if( nArg==2 ){
  3837   3878         p->statsOn = booleanValue(azArg[1]);
         3879  +    }else if( nArg==1 ){
         3880  +      display_stats(p->db, p, 0);
  3838   3881       }else{
  3839         -      raw_printf(stderr, "Usage: .stats on|off\n");
         3882  +      raw_printf(stderr, "Usage: .stats ?on|off?\n");
  3840   3883         rc = 1;
  3841   3884       }
  3842   3885     }else
  3843   3886   
  3844   3887     if( c=='t' && n>1 && strncmp(azArg[0], "tables", n)==0 ){
  3845   3888       sqlite3_stmt *pStmt;
  3846   3889       char **azResult;

Changes to src/sqlite.h.in.

  7965   7965   ** ^The [sqlite3_snapshot_open()] interface returns SQLITE_OK on success
  7966   7966   ** or an appropriate [error code] if it fails.
  7967   7967   **
  7968   7968   ** ^In order to succeed, a call to [sqlite3_snapshot_open(D,S,P)] must be
  7969   7969   ** the first operation, apart from other sqlite3_snapshot_open() calls,
  7970   7970   ** following the [BEGIN] that starts a new read transaction.
  7971   7971   ** ^A [snapshot] will fail to open if it has been overwritten by a 
  7972         -** [checkpoint].  
         7972  +** [checkpoint].
         7973  +** ^A [snapshot] will fail to open if the database connection D has not
         7974  +** previously completed at least one read operation against the database 
         7975  +** file.  (Hint: Run "[PRAGMA application_id]" against a newly opened
         7976  +** database connection in order to make it ready to use snapshots.)
  7973   7977   **
  7974   7978   ** The [sqlite3_snapshot_open()] interface is only available when the
  7975   7979   ** SQLITE_ENABLE_SNAPSHOT compile-time option is used.
  7976   7980   */
  7977   7981   SQLITE_EXPERIMENTAL int sqlite3_snapshot_open(
  7978   7982     sqlite3 *db,
  7979   7983     const char *zSchema,

Changes to src/sqliteInt.h.

  1549   1549   };
  1550   1550   
  1551   1551   /*
  1552   1552   ** information about each column of an SQL table is held in an instance
  1553   1553   ** of this structure.
  1554   1554   */
  1555   1555   struct Column {
  1556         -  char *zName;     /* Name of this column */
         1556  +  char *zName;     /* Name of this column, \000, then the type */
  1557   1557     Expr *pDflt;     /* Default value of this column */
  1558         -  char *zDflt;     /* Original text of the default value */
  1559         -  char *zType;     /* Data type for this column */
  1560   1558     char *zColl;     /* Collating sequence.  If NULL, use the default */
  1561   1559     u8 notNull;      /* An OE_ code for handling a NOT NULL constraint */
  1562   1560     char affinity;   /* One of the SQLITE_AFF_... values */
  1563   1561     u8 szEst;        /* Estimated size of value in this column. sizeof(INT)==1 */
  1564   1562     u8 colFlags;     /* Boolean properties.  See COLFLAG_ defines below */
  1565   1563   };
  1566   1564   
................................................................................
  3265   3263   #endif
  3266   3264   
  3267   3265   /*
  3268   3266   ** Internal function prototypes
  3269   3267   */
  3270   3268   int sqlite3StrICmp(const char*,const char*);
  3271   3269   int sqlite3Strlen30(const char*);
         3270  +const char *sqlite3StrNext(const char*);
  3272   3271   #define sqlite3StrNICmp sqlite3_strnicmp
  3273   3272   
  3274   3273   int sqlite3MallocInit(void);
  3275   3274   void sqlite3MallocEnd(void);
  3276   3275   void *sqlite3Malloc(u64);
  3277   3276   void *sqlite3MallocZero(u64);
  3278   3277   void *sqlite3DbMallocZero(sqlite3*, u64);
................................................................................
  3420   3419   i16 sqlite3ColumnOfIndex(Index*, i16);
  3421   3420   void sqlite3StartTable(Parse*,Token*,Token*,int,int,int,int);
  3422   3421   #if SQLITE_ENABLE_HIDDEN_COLUMNS
  3423   3422     void sqlite3ColumnPropertiesFromName(Table*, Column*);
  3424   3423   #else
  3425   3424   # define sqlite3ColumnPropertiesFromName(T,C) /* no-op */
  3426   3425   #endif
  3427         -void sqlite3AddColumn(Parse*,Token*);
         3426  +void sqlite3AddColumn(Parse*,Token*,Token*);
  3428   3427   void sqlite3AddNotNull(Parse*, int);
  3429   3428   void sqlite3AddPrimaryKey(Parse*, ExprList*, int, int, int);
  3430   3429   void sqlite3AddCheckConstraint(Parse*, Expr*);
  3431         -void sqlite3AddColumnType(Parse*,Token*);
  3432   3430   void sqlite3AddDefaultValue(Parse*,ExprSpan*);
  3433   3431   void sqlite3AddCollateType(Parse*, Token*);
  3434   3432   void sqlite3EndTable(Parse*,Token*,Token*,u8,Select*);
  3435   3433   int sqlite3ParseUri(const char*,const char*,unsigned int*,
  3436   3434                       sqlite3_vfs**,char**,char **);
  3437   3435   Btree *sqlite3DbNameToBtree(sqlite3*,const char*);
  3438   3436   int sqlite3CodeOnce(Parse *);
................................................................................
  4006   4004   ** Allowed flags for the 3rd parameter to sqlite3FindInIndex().
  4007   4005   */
  4008   4006   #define IN_INDEX_NOOP_OK     0x0001  /* OK to return IN_INDEX_NOOP */
  4009   4007   #define IN_INDEX_MEMBERSHIP  0x0002  /* IN operator used for membership test */
  4010   4008   #define IN_INDEX_LOOP        0x0004  /* IN operator used as a loop */
  4011   4009   int sqlite3FindInIndex(Parse *, Expr *, u32, int*);
  4012   4010   
         4011  +int sqlite3JournalOpen(sqlite3_vfs *, const char *, sqlite3_file *, int, int);
         4012  +int sqlite3JournalSize(sqlite3_vfs *);
  4013   4013   #ifdef SQLITE_ENABLE_ATOMIC_WRITE
  4014         -  int sqlite3JournalOpen(sqlite3_vfs *, const char *, sqlite3_file *, int, int);
  4015         -  int sqlite3JournalSize(sqlite3_vfs *);
  4016   4014     int sqlite3JournalCreate(sqlite3_file *);
  4017         -  int sqlite3JournalExists(sqlite3_file *p);
  4018         -#else
  4019         -  #define sqlite3JournalSize(pVfs) ((pVfs)->szOsFile)
  4020         -  #define sqlite3JournalExists(p) 1
  4021   4015   #endif
  4022   4016   
         4017  +int sqlite3JournalIsInMemory(sqlite3_file *p);
  4023   4018   void sqlite3MemJournalOpen(sqlite3_file *);
  4024         -int sqlite3MemJournalSize(void);
  4025         -int sqlite3IsMemJournal(sqlite3_file *);
  4026   4019   
  4027   4020   void sqlite3ExprSetHeightAndFlags(Parse *pParse, Expr *p);
  4028   4021   #if SQLITE_MAX_EXPR_DEPTH>0
  4029   4022     int sqlite3SelectExprHeight(Select *);
  4030   4023     int sqlite3ExprCheckHeight(Parse*, int);
  4031   4024   #else
  4032   4025     #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.

  3770   3770       extern int Sqlitetestrtree_Init(Tcl_Interp*);
  3771   3771       extern int Sqlitequota_Init(Tcl_Interp*);
  3772   3772       extern int Sqlitemultiplex_Init(Tcl_Interp*);
  3773   3773       extern int SqliteSuperlock_Init(Tcl_Interp*);
  3774   3774       extern int SqlitetestSyscall_Init(Tcl_Interp*);
  3775   3775       extern int Fts5tcl_Init(Tcl_Interp *);
  3776   3776       extern int SqliteRbu_Init(Tcl_Interp*);
         3777  +    extern int Sqlitetesttcl_Init(Tcl_Interp*);
  3777   3778   #if defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4)
  3778   3779       extern int Sqlitetestfts3_Init(Tcl_Interp *interp);
  3779   3780   #endif
  3780   3781   
  3781   3782   #ifdef SQLITE_ENABLE_ZIPVFS
  3782   3783       extern int Zipvfs_Init(Tcl_Interp*);
  3783   3784       Zipvfs_Init(interp);
................................................................................
  3814   3815       Sqlitetestrtree_Init(interp);
  3815   3816       Sqlitequota_Init(interp);
  3816   3817       Sqlitemultiplex_Init(interp);
  3817   3818       SqliteSuperlock_Init(interp);
  3818   3819       SqlitetestSyscall_Init(interp);
  3819   3820       Fts5tcl_Init(interp);
  3820   3821       SqliteRbu_Init(interp);
         3822  +    Sqlitetesttcl_Init(interp);
  3821   3823   
  3822   3824   #if defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4)
  3823   3825       Sqlitetestfts3_Init(interp);
  3824   3826   #endif
  3825   3827   
  3826   3828       Tcl_CreateObjCommand(
  3827   3829           interp, "load_testfixture_extensions", init_all_cmd, 0, 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/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;

Changes to src/vdbemem.c.

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

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.

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

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/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   
    93     96   if {$::tcl_platform(platform)!="unix"} {
    94     97     set alltests [test_set $alltests -exclude crash.test crash2.test]
    95     98   }
    96     99   set alltests [test_set $alltests -exclude {
................................................................................
   153    156   lappend ::testsuitelist xxx
   154    157   
   155    158   test_suite "veryquick" -prefix "" -description {
   156    159     "Very" quick test suite. Runs in minutes on a workstation.
   157    160     This test suite is the same as the "quick" tests, except that some files
   158    161     that test malloc and IO errors are omitted.
   159    162   } -files [
   160         -  test_set $allquicktests -exclude *malloc* *ioerr* *fault* *bigfile* *_err*
          163  +  test_set $allquicktests -exclude *malloc* *ioerr* *fault* *bigfile* *_err* \
          164  +      *fts5corrupt* *fts5big* *fts5aj*
   161    165   ]
   162    166   
   163    167   test_suite "extraquick" -prefix "" -description {
   164    168     "Extra" quick test suite. Runs in a few minutes on a workstation.
   165    169     This test suite is the same as the "veryquick" tests, except that
   166    170     slower tests are omitted.
   167    171   } -files [
................................................................................
   608    612       memdb.test minmax.test misc1.test misc2.test misc3.test notnull.test
   609    613       null.test progress.test quote.test rowid.test select1.test select2.test
   610    614       select3.test select4.test select5.test select6.test sort.test 
   611    615       subselect.test tableapi.test table.test temptable.test
   612    616       trace.test trigger1.test trigger2.test trigger3.test
   613    617       trigger4.test types2.test types.test unique.test update.test
   614    618       vacuum.test view.test where.test
          619  +    bestindex1.test
   615    620   }
   616    621   
   617    622   # Run some tests in exclusive locking mode.
   618    623   #
   619    624   test_suite "exclusive" -description {
   620    625     Run tests in exclusive locking mode.
   621    626   } -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.

    55     55   } {2}
    56     56   do_test stmt-1.4 {
    57     57     execsql {
    58     58       INSERT INTO t1 SELECT a+1, b+1 FROM t1;
    59     59     }
    60     60     set sqlite_open_file_count
    61     61     expr $sqlite_open_file_count-$extrafds
    62         -} {3}
           62  +  # 2016-03-04: statement-journal open deferred
           63  +} {2}
    63     64   do_test stmt-1.5 {
    64     65     execsql COMMIT
    65     66     set sqlite_open_file_count
    66     67     expr $sqlite_open_file_count-$extrafds
    67     68   } {1}
    68     69   do_test stmt-1.6.1 {
    69     70     execsql {
................................................................................
    73     74     set sqlite_open_file_count
    74     75     expr $sqlite_open_file_count-$extrafds
    75     76   } {2}
    76     77   do_test stmt-1.6.2 {
    77     78     execsql { INSERT INTO t1 SELECT a+4, b+4 FROM t1 }
    78     79     set sqlite_open_file_count
    79     80     expr $sqlite_open_file_count-$extrafds
    80         -} {3}
           81  +  # 2016-03-04: statement-journal open deferred
           82  +} {2}
    81     83   do_test stmt-1.7 {
    82     84     execsql COMMIT
    83     85     set sqlite_open_file_count
    84     86     expr $sqlite_open_file_count-$extrafds
    85     87   } {1}
    86     88   
    87     89   
................................................................................
    97     99   
    98    100   filecount stmt-2.1 { INSERT INTO t1 VALUES(9, 9)  } 2 $extrafds
    99    101   filecount stmt-2.2 { REPLACE INTO t1 VALUES(9, 9) } 2 $extrafds
   100    102   filecount stmt-2.3 { INSERT INTO t1 SELECT 9, 9   } 2 $extrafds
   101    103   filecount stmt-2.4 { 
   102    104       INSERT INTO t1 SELECT 9, 9;
   103    105       INSERT INTO t1 SELECT 10, 10;
   104         -} 3 $extrafds
          106  +} 2 $extrafds
   105    107   
   106    108   do_test stmt-2.5 {
   107    109     execsql { CREATE INDEX i1 ON t1(b) }
   108    110   } {}
   109    111   filecount stmt-2.6 { 
   110    112     REPLACE INTO t1 VALUES(5, 5);
   111    113     REPLACE INTO t1 VALUES(5, 5); 
   112         -} 3 $extrafds
          114  +} 2 $extrafds
   113    115   
   114    116   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.

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

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