/ Check-in [6ef3de81]
Login

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

Overview
Comment:Merge changes from trunk.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | memdb
Files: files | file ages | folders
SHA3-256:6ef3de810d54563c227045b16197b8011ce285ea867261946f93b2de55344f29
User & Date: drh 2018-01-24 15:02:53
Context
2018-03-01
13:44
Merge the latest enhancements from trunk. check-in: c8083de1 user: drh tags: memdb
2018-01-24
15:02
Merge changes from trunk. check-in: 6ef3de81 user: drh tags: memdb
14:40
Interchange the numeric codes for CURSOR_VALID and CURSOR_INVALID to obtain a small size decrease and performance increase. check-in: e0f192ea user: drh tags: trunk
2018-01-03
23:54
Fix compiler warnings on Windows. check-in: 512b8e40 user: drh tags: memdb
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Added .fossil-settings/empty-dirs.

            1  +compat

Added .fossil-settings/ignore-glob.

            1  +compat/*

Changes to Makefile.in.

   444    444     $(TOP)/ext/misc/percentile.c \
   445    445     $(TOP)/ext/misc/regexp.c \
   446    446     $(TOP)/ext/misc/remember.c \
   447    447     $(TOP)/ext/misc/series.c \
   448    448     $(TOP)/ext/misc/spellfix.c \
   449    449     $(TOP)/ext/misc/totype.c \
   450    450     $(TOP)/ext/misc/unionvtab.c \
   451         -  $(TOP)/ext/misc/wholenumber.c
          451  +  $(TOP)/ext/misc/wholenumber.c \
          452  +  $(TOP)/ext/misc/zipfile.c
   452    453   
   453    454   # Source code to the library files needed by the test fixture
   454    455   #
   455    456   TESTSRC2 = \
   456    457     $(TOP)/src/attach.c \
   457    458     $(TOP)/src/backup.c \
   458    459     $(TOP)/src/bitvec.c \
................................................................................
   555    556   # executables needed for testing
   556    557   #
   557    558   TESTPROGS = \
   558    559     testfixture$(TEXE) \
   559    560     sqlite3$(TEXE) \
   560    561     sqlite3_analyzer$(TEXE) \
   561    562     sqldiff$(TEXE) \
   562         -  dbhash$(TEXE)
          563  +  dbhash$(TEXE) \
          564  +  sqltclsh$(TEXE)
   563    565   
   564    566   # Databases containing fuzzer test cases
   565    567   #
   566    568   FUZZDATA = \
   567    569     $(TOP)/test/fuzzdata1.db \
   568    570     $(TOP)/test/fuzzdata2.db \
   569    571     $(TOP)/test/fuzzdata3.db \
................................................................................
   573    575   # Standard options to testfixture
   574    576   #
   575    577   TESTOPTS = --verbose=file --output=test-out.txt
   576    578   
   577    579   # Extra compiler options for various shell tools
   578    580   #
   579    581   SHELL_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS4
   580         -# SHELL_OPT += -DSQLITE_ENABLE_FTS5
          582  +#SHELL_OPT += -DSQLITE_ENABLE_FTS5
          583  +SHELL_OPT += -DSQLITE_ENABLE_RTREE
   581    584   SHELL_OPT += -DSQLITE_ENABLE_EXPLAIN_COMMENTS
   582    585   SHELL_OPT += -DSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
   583    586   SHELL_OPT += -DSQLITE_ENABLE_STMTVTAB
   584    587   SHELL_OPT += -DSQLITE_ENABLE_DBPAGE_VTAB
   585    588   SHELL_OPT += -DSQLITE_ENABLE_DBSTAT_VTAB
   586    589   SHELL_OPT += -DSQLITE_ENABLE_OFFSET_SQL_FUNC
   587    590   SHELL_OPT += -DSQLITE_INTROSPECTION_PRAGMAS
................................................................................
   992    995   keywordhash.h:	$(TOP)/tool/mkkeywordhash.c
   993    996   	$(BCC) -o mkkeywordhash$(BEXE) $(OPT_FEATURE_FLAGS) $(OPTS) $(TOP)/tool/mkkeywordhash.c
   994    997   	./mkkeywordhash$(BEXE) >keywordhash.h
   995    998   
   996    999   # Source files that go into making shell.c
   997   1000   SHELL_SRC = \
   998   1001   	$(TOP)/src/shell.c.in \
         1002  +        $(TOP)/ext/misc/appendvfs.c \
   999   1003   	$(TOP)/ext/misc/shathree.c \
  1000   1004   	$(TOP)/ext/misc/fileio.c \
  1001         -	$(TOP)/ext/misc/completion.c
         1005  +	$(TOP)/ext/misc/completion.c \
         1006  +	$(TOP)/ext/misc/sqlar.c \
         1007  +	$(TOP)/ext/expert/sqlite3expert.c \
         1008  +	$(TOP)/ext/expert/sqlite3expert.h \
         1009  +	$(TOP)/ext/misc/zipfile.c \
         1010  +        $(TOP)/src/test_windirent.c
  1002   1011   
  1003   1012   shell.c:	$(SHELL_SRC) $(TOP)/tool/mkshellc.tcl
  1004   1013   	$(TCLSH_CMD) $(TOP)/tool/mkshellc.tcl >shell.c
  1005   1014   
  1006   1015   
  1007   1016   
  1008   1017   
................................................................................
  1193   1202   	./testfixture$(TEXE) $(TOP)/test/main.test $(TESTOPTS)
  1194   1203   
  1195   1204   sqlite3_analyzer.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/spaceanal.tcl $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqlite3_analyzer.c.in
  1196   1205   	$(TCLSH_CMD) $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqlite3_analyzer.c.in >sqlite3_analyzer.c
  1197   1206   
  1198   1207   sqlite3_analyzer$(TEXE): sqlite3_analyzer.c
  1199   1208   	$(LTLINK) sqlite3_analyzer.c -o $@ $(LIBTCL) $(TLIBS)
         1209  +
         1210  +sqltclsh.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/sqltclsh.tcl $(TOP)/ext/misc/appendvfs.c $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqltclsh.c.in	
         1211  +	$(TCLSH_CMD) $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqltclsh.c.in >sqltclsh.c
         1212  +
         1213  +sqltclsh$(TEXE): sqltclsh.c
         1214  +	$(LTLINK) sqltclsh.c -o $@ $(LIBTCL) $(TLIBS)
  1200   1215   
  1201   1216   sqlite3_expert$(TEXE): $(TOP)/ext/expert/sqlite3expert.h $(TOP)/ext/expert/sqlite3expert.c $(TOP)/ext/expert/expert.c sqlite3.c
  1202   1217   	$(LTLINK)	$(TOP)/ext/expert/sqlite3expert.h $(TOP)/ext/expert/sqlite3expert.c $(TOP)/ext/expert/expert.c sqlite3.c -o sqlite3_expert $(TLIBS)
  1203   1218   
  1204   1219   CHECKER_DEPS =\
  1205   1220     $(TOP)/tool/mkccode.tcl \
  1206   1221     sqlite3.c \

Changes to Makefile.msc.

    88     88   # be used for debugging with Visual Studio.
    89     89   #
    90     90   !IFNDEF SPLIT_AMALGAMATION
    91     91   SPLIT_AMALGAMATION = 0
    92     92   !ENDIF
    93     93   
    94     94   # <<mark>>
           95  +# Set this non-0 to have this makefile assume the Tcl shell executable
           96  +# (tclsh*.exe) is available in the PATH.  By default, this is disabled
           97  +# for compatibility with older build environments.  This setting only
           98  +# applies if TCLSH_CMD is not set manually.
           99  +#
          100  +!IFNDEF USE_TCLSH_IN_PATH
          101  +USE_TCLSH_IN_PATH = 0
          102  +!ENDIF
          103  +
          104  +# Set this non-0 to use zlib, possibly compiling it from source code.
          105  +#
          106  +!IFNDEF USE_ZLIB
          107  +USE_ZLIB = 0
          108  +!ENDIF
          109  +
          110  +# Set this non-0 to build zlib from source code.  This is enabled by
          111  +# default and in that case it will be assumed that the ZLIBDIR macro
          112  +# points to the top-level source code directory for zlib.
          113  +#
          114  +!IFNDEF BUILD_ZLIB
          115  +BUILD_ZLIB = 1
          116  +!ENDIF
          117  +
    95    118   # Set this non-0 to use the International Components for Unicode (ICU).
    96    119   #
    97    120   !IFNDEF USE_ICU
    98    121   USE_ICU = 0
    99    122   !ENDIF
   100    123   # <</mark>>
   101    124   
................................................................................
   608    631   !IF $(DYNAMIC_SHELL)!=0 || $(FOR_WIN10)!=0
   609    632   SHELL_CORE_DEP = $(SQLITE3DLL)
   610    633   !ELSE
   611    634   SHELL_CORE_DEP =
   612    635   !ENDIF
   613    636   !ENDIF
   614    637   
          638  +# <<mark>>
          639  +# If zlib support is enabled, add the dependencies for it.
          640  +#
          641  +!IF $(USE_ZLIB)!=0 && $(BUILD_ZLIB)!=0
          642  +SHELL_CORE_DEP = zlib $(SHELL_CORE_DEP)
          643  +TESTFIXTURE_DEP = zlib $(TESTFIXTURE_DEP)
          644  +!ENDIF
          645  +# <</mark>>
          646  +
   615    647   # This is the core library that the shell executable should link with.
   616    648   #
   617    649   !IFNDEF SHELL_CORE_LIB
   618    650   !IF $(DYNAMIC_SHELL)!=0 || $(FOR_WIN10)!=0
   619    651   SHELL_CORE_LIB = $(SQLITE3LIB)
   620    652   !ELSE
   621    653   SHELL_CORE_LIB =
................................................................................
   798    830   # <<mark>>
   799    831   # The locations of the Tcl header and library files.  Also, the library that
   800    832   # non-stubs enabled programs using Tcl must link against.  These variables
   801    833   # (TCLINCDIR, TCLLIBDIR, and LIBTCL) may be overridden via the environment
   802    834   # prior to running nmake in order to match the actual installed location and
   803    835   # version on this machine.
   804    836   #
          837  +!IFNDEF TCLDIR
          838  +TCLDIR = $(TOP)\compat\tcl
          839  +!ENDIF
          840  +
   805    841   !IFNDEF TCLINCDIR
   806         -TCLINCDIR = c:\tcl\include
          842  +TCLINCDIR = $(TCLDIR)\include
   807    843   !ENDIF
   808    844   
   809    845   !IFNDEF TCLLIBDIR
   810         -TCLLIBDIR = c:\tcl\lib
          846  +TCLLIBDIR = $(TCLDIR)\lib
   811    847   !ENDIF
   812    848   
   813    849   !IFNDEF LIBTCL
   814    850   LIBTCL = tcl86.lib
   815    851   !ENDIF
   816    852   
   817    853   !IFNDEF LIBTCLSTUB
   818    854   LIBTCLSTUB = tclstub86.lib
   819    855   !ENDIF
   820    856   
   821    857   !IFNDEF LIBTCLPATH
   822         -LIBTCLPATH = c:\tcl\bin
          858  +LIBTCLPATH = $(TCLDIR)\bin
          859  +!ENDIF
          860  +
          861  +# The locations of the zlib header and library files.  These variables
          862  +# (ZLIBINCDIR, ZLIBLIBDIR, and ZLIBLIB) may be overridden via the environment
          863  +# prior to running nmake in order to match the actual installed (or source
          864  +# code) location on this machine.
          865  +#
          866  +!IFNDEF ZLIBDIR
          867  +ZLIBDIR = $(TOP)\compat\zlib
          868  +!ENDIF
          869  +
          870  +!IFNDEF ZLIBINCDIR
          871  +ZLIBINCDIR = $(ZLIBDIR)
          872  +!ENDIF
          873  +
          874  +!IFNDEF ZLIBLIBDIR
          875  +ZLIBLIBDIR = $(ZLIBDIR)
          876  +!ENDIF
          877  +
          878  +!IFNDEF ZLIBLIB
          879  +!IF $(DYNAMIC_SHELL)!=0
          880  +ZLIBLIB = zdll.lib
          881  +!ELSE
          882  +ZLIBLIB = zlib.lib
          883  +!ENDIF
   823    884   !ENDIF
   824    885   
   825    886   # The locations of the ICU header and library files.  These variables
   826    887   # (ICUINCDIR, ICULIBDIR, and LIBICU) may be overridden via the environment
   827    888   # prior to running nmake in order to match the actual installed location on
   828    889   # this machine.
   829    890   #
          891  +!IFNDEF ICUDIR
          892  +ICUDIR = $(TOP)\compat\icu
          893  +!ENDIF
          894  +
   830    895   !IFNDEF ICUINCDIR
   831         -ICUINCDIR = c:\icu\include
          896  +ICUINCDIR = $(ICUDIR)\include
   832    897   !ENDIF
   833    898   
   834    899   !IFNDEF ICULIBDIR
   835         -ICULIBDIR = c:\icu\lib
          900  +ICULIBDIR = $(ICUDIR)\lib
   836    901   !ENDIF
   837    902   
   838    903   !IFNDEF LIBICU
   839    904   LIBICU = icuuc.lib icuin.lib
   840    905   !ENDIF
   841    906   
   842    907   # This is the command to use for tclsh - normally just "tclsh", but we may
   843    908   # know the specific version we want to use.  This variable (TCLSH_CMD) may be
   844    909   # overridden via the environment prior to running nmake in order to select a
   845    910   # specific Tcl shell to use.
   846    911   #
   847    912   !IFNDEF TCLSH_CMD
          913  +!IF $(USE_TCLSH_IN_PATH)!=0 || !EXIST("$(TCLDIR)\bin\tclsh.exe")
   848    914   TCLSH_CMD = tclsh
          915  +!ELSE
          916  +TCLSH_CMD = $(TCLDIR)\bin\tclsh.exe
          917  +!ENDIF
   849    918   !ENDIF
   850    919   # <</mark>>
   851    920   
   852    921   # Compiler options needed for programs that use the readline() library.
   853    922   #
   854    923   !IFNDEF READLINE_FLAGS
   855    924   READLINE_FLAGS = -DHAVE_READLINE=0
................................................................................
   947   1016   #
   948   1017   !IF $(DEBUG)>1 || $(SYMBOLS)!=0
   949   1018   TCC = $(TCC) -Zi
   950   1019   BCC = $(BCC) -Zi
   951   1020   !ENDIF
   952   1021   
   953   1022   # <<mark>>
         1023  +# If zlib support is enabled, add the compiler options for it.
         1024  +#
         1025  +!IF $(USE_ZLIB)!=0
         1026  +TCC = $(TCC) -DSQLITE_HAVE_ZLIB=1
         1027  +RCC = $(RCC) -DSQLITE_HAVE_ZLIB=1
         1028  +TCC = $(TCC) -I$(ZLIBINCDIR)
         1029  +RCC = $(RCC) -I$(ZLIBINCDIR)
         1030  +!ENDIF
         1031  +
   954   1032   # If ICU support is enabled, add the compiler options for it.
   955   1033   #
   956   1034   !IF $(USE_ICU)!=0
   957   1035   TCC = $(TCC) -DSQLITE_ENABLE_ICU=1
   958   1036   RCC = $(RCC) -DSQLITE_ENABLE_ICU=1
   959   1037   TCC = $(TCC) -I$(TOP)\ext\icu
   960   1038   RCC = $(RCC) -I$(TOP)\ext\icu
................................................................................
  1067   1145   LDFLAGS = $(LDOPTS)
  1068   1146   !ENDIF
  1069   1147   
  1070   1148   # <<mark>>
  1071   1149   # Start with the Tcl related linker options.
  1072   1150   #
  1073   1151   !IF $(NO_TCL)==0
  1074         -LTLIBPATHS = /LIBPATH:$(TCLLIBDIR)
  1075         -LTLIBS = $(LTLIBS) $(LIBTCL)
         1152  +TCLLIBPATHS = $(TCLLIBPATHS) /LIBPATH:$(TCLLIBDIR)
         1153  +TCLLIBS = $(TCLLIBS) $(LIBTCL)
         1154  +!ENDIF
         1155  +
         1156  +# If zlib support is enabled, add the linker options for it.
         1157  +#
         1158  +!IF $(USE_ZLIB)!=0
         1159  +LTLIBPATHS = $(LTLIBPATHS) /LIBPATH:$(ZLIBLIBDIR)
         1160  +LTLIBS = $(LTLIBS) $(ZLIBLIB)
  1076   1161   !ENDIF
  1077   1162   
  1078   1163   # If ICU support is enabled, add the linker options for it.
  1079   1164   #
  1080   1165   !IF $(USE_ICU)!=0
  1081   1166   LTLIBPATHS = $(LTLIBPATHS) /LIBPATH:$(ICULIBDIR)
  1082   1167   LTLIBS = $(LTLIBS) $(LIBICU)
................................................................................
  1420   1505     $(TOP)\ext\misc\regexp.c \
  1421   1506     $(TOP)\ext\misc\remember.c \
  1422   1507     $(TOP)\ext\misc\series.c \
  1423   1508     $(TOP)\ext\misc\spellfix.c \
  1424   1509     $(TOP)\ext\misc\totype.c \
  1425   1510     $(TOP)\ext\misc\unionvtab.c \
  1426   1511     $(TOP)\ext\misc\wholenumber.c
         1512  +
         1513  +# If use of zlib is enabled, add the "zipfile.c" source file.
         1514  +#
         1515  +!IF $(USE_ZLIB)!=0
         1516  +TESTEXT = $(TESTEXT) $(TOP)\ext\misc\zipfile.c
         1517  +!ENDIF
  1427   1518   
  1428   1519   # Source code to the library files needed by the test fixture
  1429   1520   # (non-amalgamation)
  1430   1521   #
  1431   1522   TESTSRC2 = \
  1432   1523     $(SRC00) \
  1433   1524     $(SRC01) \
................................................................................
  1492   1583   #
  1493   1584   TESTPROGS = \
  1494   1585     testfixture.exe \
  1495   1586     $(SQLITE3EXE) \
  1496   1587     sqlite3_analyzer.exe \
  1497   1588     sqlite3_checker.exe \
  1498   1589     sqldiff.exe \
  1499         -  dbhash.exe
         1590  +  dbhash.exe \
         1591  +  sqltclsh.exe
  1500   1592   
  1501   1593   # Databases containing fuzzer test cases
  1502   1594   #
  1503   1595   FUZZDATA = \
  1504   1596     $(TOP)\test\fuzzdata1.db \
  1505   1597     $(TOP)\test\fuzzdata2.db \
  1506   1598     $(TOP)\test\fuzzdata3.db \
................................................................................
  1511   1603   # Additional compiler options for the shell.  These are only effective
  1512   1604   # when the shell is not being dynamically linked.
  1513   1605   #
  1514   1606   !IF $(DYNAMIC_SHELL)==0 && $(FOR_WIN10)==0
  1515   1607   SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_STMTVTAB
  1516   1608   SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_DBPAGE_VTAB -DSQLITE_ENABLE_DBSTAT_VTAB
  1517   1609   SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_OFFSET_SQL_FUNC -DSQLITE_INTROSPECTION_PRAGMAS
         1610  +SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_RTREE
  1518   1611   !ENDIF
  1519   1612   
  1520   1613   # <<mark>>
  1521   1614   # Extra compiler options for various test tools.
  1522   1615   #
  1523   1616   MPTESTER_COMPILE_OPTS = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS5
  1524   1617   FUZZERSHELL_COMPILE_OPTS = -DSQLITE_ENABLE_JSON1
................................................................................
  1542   1635   ALL_TCL_TARGETS =
  1543   1636   !ENDIF
  1544   1637   # <</mark>>
  1545   1638   
  1546   1639   # This is the default Makefile target.  The objects listed here
  1547   1640   # are what get build when you type just "make" with no arguments.
  1548   1641   #
  1549         -all:	dll libsqlite3.lib shell $(ALL_TCL_TARGETS)
         1642  +core:	dll libsqlite3.lib shell
         1643  +
         1644  +# Targets that require the Tcl library.
         1645  +#
         1646  +tcl:	$(ALL_TCL_TARGETS)
         1647  +
         1648  +# This Makefile target builds all of the standard binaries.
         1649  +#
         1650  +all:	core tcl
  1550   1651   
  1551   1652   # Dynamic link library section.
  1552   1653   #
  1553   1654   dll:	$(SQLITE3DLL)
  1554   1655   
  1555   1656   # Shell executable.
  1556   1657   #
................................................................................
  1940   2041   tclsqlite.lo:	$(TOP)\src\tclsqlite.c $(HDR) $(SQLITE_TCL_DEP)
  1941   2042   	$(LTCOMPILE) $(NO_WARN) -DUSE_TCL_STUBS=1 -DBUILD_sqlite -I$(TCLINCDIR) -c $(TOP)\src\tclsqlite.c
  1942   2043   
  1943   2044   tclsqlite-shell.lo:	$(TOP)\src\tclsqlite.c $(HDR) $(SQLITE_TCL_DEP)
  1944   2045   	$(LTCOMPILE) $(NO_WARN) -DTCLSH -DBUILD_sqlite -I$(TCLINCDIR) -c $(TOP)\src\tclsqlite.c
  1945   2046   
  1946   2047   tclsqlite3.exe:	tclsqlite-shell.lo $(SQLITE3C) $(SQLITE3H) $(LIBRESOBJS)
  1947         -	$(LTLINK) $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) /OUT:$@ tclsqlite-shell.lo $(LIBRESOBJS) $(LTLIBS) $(TLIBS)
         2048  +	$(LTLINK) $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS) $(TCLLIBPATHS) $(LTLIBPATHS) /OUT:$@ tclsqlite-shell.lo $(LIBRESOBJS) $(TCLLIBS) $(LTLIBS) $(TLIBS)
  1948   2049   
  1949   2050   # Rules to build opcodes.c and opcodes.h
  1950   2051   #
  1951   2052   opcodes.c:	opcodes.h $(TOP)\tool\mkopcodec.tcl
  1952   2053   	$(TCLSH_CMD) $(TOP)\tool\mkopcodec.tcl opcodes.h > opcodes.c
  1953   2054   
  1954   2055   opcodes.h:	parse.h $(TOP)\src\vdbe.c $(TOP)\tool\mkopcodeh.tcl
................................................................................
  1983   2084   
  1984   2085   keywordhash.h:	$(TOP)\tool\mkkeywordhash.c mkkeywordhash.exe
  1985   2086   	.\mkkeywordhash.exe > keywordhash.h
  1986   2087   
  1987   2088   # Source files that go into making shell.c
  1988   2089   SHELL_SRC = \
  1989   2090   	$(TOP)\src\shell.c.in \
         2091  +        $(TOP)\ext\misc\appendvfs.c \
  1990   2092   	$(TOP)\ext\misc\shathree.c \
  1991   2093   	$(TOP)\ext\misc\fileio.c \
  1992         -	$(TOP)\ext\misc\completion.c
         2094  +	$(TOP)\ext\misc\completion.c \
         2095  +	$(TOP)\ext\expert\sqlite3expert.c \
         2096  +	$(TOP)\ext\expert\sqlite3expert.h \
         2097  +	$(TOP)\src\test_windirent.c
         2098  +
         2099  +# If use of zlib is enabled, add the "zipfile.c" source file.
         2100  +#
         2101  +!IF $(USE_ZLIB)!=0
         2102  +SHELL_SRC = $(SHELL_SRC) $(TOP)\ext\misc\sqlar.c
         2103  +SHELL_SRC = $(SHELL_SRC) $(TOP)\ext\misc\zipfile.c
         2104  +!ENDIF
  1993   2105   
  1994   2106   shell.c:	$(SHELL_SRC) $(TOP)\tool\mkshellc.tcl
  1995   2107   	$(TCLSH_CMD) $(TOP)\tool\mkshellc.tcl > shell.c
  1996   2108   
         2109  +zlib:
         2110  +	pushd $(ZLIBDIR) && $(MAKE) /f win32\Makefile.msc clean $(ZLIBLIB) && popd
  1997   2111   
  1998   2112   # Rules to build the extension objects.
  1999   2113   #
  2000   2114   icu.lo:	$(TOP)\ext\icu\icu.c $(HDR) $(EXTHDR)
  2001   2115   	$(LTCOMPILE) $(CORE_COMPILE_OPTS) $(NO_WARN) -DSQLITE_CORE -c $(TOP)\ext\icu\icu.c
  2002   2116   
  2003   2117   fts2.lo:	$(TOP)\ext\fts2\fts2.c $(HDR) $(EXTHDR)
................................................................................
  2167   2281   	type "$(TCLINCDIR)\tcl.h" | $(TCLSH_CMD) $(TOP)\tool\replace.tcl exact tclDecls.h sqlite_tclDecls.h \
  2168   2282   		| $(TCLSH_CMD) $(TOP)\tool\replace.tcl regsub "typedef (.*?)\(Tcl_" "typedef \1 (SQLITE_TCLAPI Tcl_" \
  2169   2283   		| $(TCLSH_CMD) $(TOP)\tool\replace.tcl exact "void (*freeProc)" "void (SQLITE_TCLAPI *freeProc)" \
  2170   2284   		| $(TCLSH_CMD) $(TOP)\tool\replace.tcl exact "Tcl_HashEntry *(*findProc)" "Tcl_HashEntry *(SQLITE_TCLAPI *findProc)" \
  2171   2285   		| $(TCLSH_CMD) $(TOP)\tool\replace.tcl exact "Tcl_HashEntry *(*createProc)" "Tcl_HashEntry *(SQLITE_TCLAPI *createProc)" >> $(SQLITETCLH)
  2172   2286   !ENDIF
  2173   2287   
  2174         -testfixture.exe:	$(TESTFIXTURE_SRC) $(SQLITE3H) $(LIBRESOBJS) $(HDR) $(SQLITE_TCL_DEP)
         2288  +testfixture.exe:	$(TESTFIXTURE_SRC) $(TESTFIXTURE_DEP) $(SQLITE3H) $(LIBRESOBJS) $(HDR) $(SQLITE_TCL_DEP)
  2175   2289   	$(LTLINK) -DSQLITE_NO_SYNC=1 $(TESTFIXTURE_FLAGS) \
  2176   2290   		-DBUILD_sqlite -I$(TCLINCDIR) \
  2177   2291   		$(TESTFIXTURE_SRC) \
  2178         -		/link $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LTLIBS) $(TLIBS)
         2292  +		/link $(LDFLAGS) $(LTLINKOPTS) $(TCLLIBPATHS) $(LTLIBPATHS) $(LIBRESOBJS) $(TCLLIBS) $(LTLIBS) $(TLIBS)
  2179   2293   
  2180   2294   extensiontest:	testfixture.exe testloadext.dll
  2181   2295   	@set PATH=$(LIBTCLPATH);$(PATH)
  2182   2296   	.\testfixture.exe $(TOP)\test\loadext.test $(TESTOPTS)
  2183   2297   
  2184   2298   fulltest:	$(TESTPROGS) fuzztest
  2185   2299   	@set PATH=$(LIBTCLPATH);$(PATH)
................................................................................
  2221   2335   	.\testfixture.exe $(TOP)\test\main.test $(TESTOPTS)
  2222   2336   
  2223   2337   sqlite3_analyzer.c:	$(SQLITE3C) $(SQLITE3H) $(TOP)\src\tclsqlite.c $(TOP)\tool\spaceanal.tcl $(TOP)\tool\mkccode.tcl $(TOP)\tool\sqlite3_analyzer.c.in $(SQLITE_TCL_DEP)
  2224   2338   	$(TCLSH_CMD) $(TOP)\tool\mkccode.tcl $(TOP)\tool\sqlite3_analyzer.c.in > $@
  2225   2339   
  2226   2340   sqlite3_analyzer.exe:	sqlite3_analyzer.c $(LIBRESOBJS)
  2227   2341   	$(LTLINK) $(NO_WARN) -DBUILD_sqlite -I$(TCLINCDIR) sqlite3_analyzer.c \
  2228         -		/link $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LTLIBS) $(TLIBS)
         2342  +		/link $(LDFLAGS) $(LTLINKOPTS) $(TCLLIBPATHS) $(LTLIBPATHS) $(LIBRESOBJS) $(TCLLIBS) $(LTLIBS) $(TLIBS)
         2343  +
         2344  +sqltclsh.c: sqlite3.c $(TOP)\src\tclsqlite.c $(TOP)\tool\sqltclsh.tcl $(TOP)\ext\misc\appendvfs.c $(TOP)\tool\mkccode.tcl $(TOP)\tool\sqltclsh.c.in
         2345  +	$(TCLSH_CMD) $(TOP)\tool\mkccode.tcl $(TOP)\tool\sqltclsh.c.in >sqltclsh.c
         2346  +
         2347  +sqltclsh.exe: sqltclsh.c  $(SHELL_CORE_DEP) $(LIBRESOBJS)
         2348  +	$(LTLINK) $(NO_WARN) -DBUILD_sqlite -I$(TCLINCDIR) sqltclsh.c \
         2349  +		/link $(LDFLAGS) $(LTLINKOPTS) $(TCLLIBPATHS) $(LTLIBPATHS) $(LIBRESOBJS) $(TCLLIBS) $(LTLIBS) $(TLIBS)
  2229   2350   
  2230   2351   sqlite3_expert.exe: $(SQLITE3C) $(TOP)\ext\expert\sqlite3expert.h $(TOP)\ext\expert\sqlite3expert.c $(TOP)\ext\expert\expert.c
  2231   2352   	$(LTLINK) $(NO_WARN)	$(TOP)\ext\expert\sqlite3expert.c $(TOP)\ext\expert\expert.c $(SQLITE3C) $(TLIBS)
  2232   2353   
  2233   2354   CHECKER_DEPS =\
  2234   2355     $(TOP)/tool/mkccode.tcl \
  2235   2356     sqlite3.c \
................................................................................
  2241   2362     $(TOP)/ext/repair/sqlite3_checker.c.in
  2242   2363   
  2243   2364   sqlite3_checker.c:	$(CHECKER_DEPS)
  2244   2365   	$(TCLSH_CMD) $(TOP)\tool\mkccode.tcl $(TOP)\ext\repair\sqlite3_checker.c.in > $@
  2245   2366   
  2246   2367   sqlite3_checker.exe:	sqlite3_checker.c $(LIBRESOBJS)
  2247   2368   	$(LTLINK) $(NO_WARN) -DBUILD_sqlite -I$(TCLINCDIR) sqlite3_checker.c \
  2248         -		/link $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LTLIBS) $(TLIBS)
         2369  +		/link $(LDFLAGS) $(LTLINKOPTS) $(TCLLIBPATHS) $(LTLIBPATHS) $(LIBRESOBJS) $(TCLLIBS) $(LTLIBS) $(TLIBS)
  2249   2370   
  2250   2371   dbdump.exe:	$(TOP)\ext\misc\dbdump.c $(SQLITE3C) $(SQLITE3H)
  2251   2372   	$(LTLINK) $(NO_WARN) -DDBDUMP_STANDALONE $(TOP)\ext\misc\dbdump.c $(SQLITE3C) \
  2252   2373   		/link $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LTLIBS)
  2253   2374   
  2254   2375   testloadext.lo:	$(TOP)\src\test_loadext.c
  2255   2376   	$(LTCOMPILE) $(NO_WARN) -c $(TOP)\src\test_loadext.c
................................................................................
  2342   2463   	del /Q mptester.exe wordcount.exe rbu.exe srcck1.exe 2>NUL
  2343   2464   	del /Q sqlite3.c sqlite3-*.c 2>NUL
  2344   2465   	del /Q sqlite3rc.h 2>NUL
  2345   2466   	del /Q shell.c sqlite3ext.h sqlite3session.h 2>NUL
  2346   2467   	del /Q sqlite3_analyzer.exe sqlite3_analyzer.c 2>NUL
  2347   2468   	del /Q sqlite-*-output.vsix 2>NUL
  2348   2469   	del /Q fuzzershell.exe fuzzcheck.exe sqldiff.exe dbhash.exe 2>NUL
         2470  +	del /Q sqltclsh.exe 2>NUL
  2349   2471   	del /Q fts5.* fts5parse.* 2>NUL
  2350   2472   	del /Q lsm.h lsm1.c 2>NUL
  2351   2473   # <</mark>>

Changes to README.md.

     1      1   <h1 align="center">SQLite Source Repository</h1>
     2      2   
     3      3   This repository contains the complete source code for the SQLite database
     4         -engine.  Some test scripts are also include.  However, many other test scripts
            4  +engine.  Some test scripts are also included.  However, many other test scripts
     5      5   and most of the documentation are managed separately.
     6      6   
     7      7   If you are reading this on a Git mirror someplace, you are doing it wrong.
     8      8   The [official repository](https://www.sqlite.org/src/) is better.  Go there
     9      9   now.
    10     10   
    11     11   ## Obtaining The Code
................................................................................
   100    100   to the "sqlite3.dll" command line above.  When debugging into the SQLite
   101    101   code, adding the "DEBUG=1" argument to one of the above command lines is
   102    102   recommended.
   103    103   
   104    104   SQLite does not require [Tcl](http://www.tcl.tk/) to run, but a Tcl installation
   105    105   is required by the makefiles (including those for MSVC).  SQLite contains
   106    106   a lot of generated code and Tcl is used to do much of that code generation.
   107         -The makefiles also require AWK.
   108    107   
   109    108   ## Source Code Tour
   110    109   
   111    110   Most of the core source files are in the **src/** subdirectory.  The
   112    111   **src/** folder also contains files used to build the "testfixture" test
   113    112   harness. The names of the source files used by "testfixture" all begin
   114    113   with "test".
   115    114   The **src/** also contains the "shell.c" file
   116    115   which is the main program for the "sqlite3.exe"
   117    116   [command-line shell](https://sqlite.org/cli.html) and
   118    117   the "tclsqlite.c" file which implements the
   119         -[TCL bindings](https://sqlite.org/tclsqlite.html) for SQLite.
          118  +[Tcl bindings](https://sqlite.org/tclsqlite.html) for SQLite.
   120    119   (Historical note:  SQLite began as a Tcl
   121    120   extension and only later escaped to the wild as an independent library.)
   122    121   
   123    122   Test scripts and programs are found in the **test/** subdirectory.
   124    123   Addtional test code is found in other source repositories.
   125    124   See [How SQLite Is Tested](http://www.sqlite.org/testing.html) for
   126    125   additional information.
................................................................................
   159    158   the src/parse.y file.  The conversion of "parse.y" into "parse.c" is done
   160    159   by the [lemon](./doc/lemon.html) LALR(1) parser generator.  The source code
   161    160   for lemon is at tool/lemon.c.  Lemon uses the tool/lempar.c file as a
   162    161   template for generating its parser.
   163    162   
   164    163   Lemon also generates the **parse.h** header file, at the same time it
   165    164   generates parse.c. But the parse.h header file is
   166         -modified further (to add additional symbols) using the ./addopcodes.awk
   167         -AWK script.
          165  +modified further (to add additional symbols) using the ./addopcodes.tcl
          166  +Tcl script.
   168    167   
   169    168   The **opcodes.h** header file contains macros that define the numbers
   170    169   corresponding to opcodes in the "VDBE" virtual machine.  The opcodes.h
   171    170   file is generated by the scanning the src/vdbe.c source file.  The
   172         -AWK script at ./mkopcodeh.awk does this scan and generates opcodes.h.
   173         -A second AWK script, ./mkopcodec.awk, then scans opcodes.h to generate
          171  +Tcl script at ./mkopcodeh.tcl does this scan and generates opcodes.h.
          172  +A second Tcl script, ./mkopcodec.tcl, then scans opcodes.h to generate
   174    173   the **opcodes.c** source file, which contains a reverse mapping from
   175    174   opcode-number to opcode-name that is used for EXPLAIN output.
   176    175   
   177    176   The **keywordhash.h** header file contains the definition of a hash table
   178    177   that maps SQL language keywords (ex: "CREATE", "SELECT", "INDEX", etc.) into
   179    178   the numeric codes used by the parse.c parser.  The keywordhash.h file is
   180    179   generated by a C-language program at tool mkkeywordhash.c.
................................................................................
   276    275   
   277    276     *  **tclsqlite.c** - This file implements the Tcl bindings for SQLite.  It
   278    277        is not part of the core SQLite library.  But as most of the tests in this
   279    278        repository are written in Tcl, the Tcl language bindings are important.
   280    279   
   281    280     *  **test*.c** - Files in the src/ folder that begin with "test" go into
   282    281        building the "testfixture.exe" program.  The testfixture.exe program is
   283         -     an enhanced TCL shell.  The testfixture.exe program runs scripts in the
          282  +     an enhanced Tcl shell.  The testfixture.exe program runs scripts in the
   284    283        test/ folder to validate the core SQLite code.  The testfixture program
   285    284        (and some other test programs too) is build and run when you type
   286    285        "make test".
   287    286   
   288    287     *  **ext/misc/json1.c** - This file implements the various JSON functions
   289    288        that are build into SQLite.
   290    289   

Changes to VERSION.

     1         -3.22.0
            1  +3.23.0

Changes to autoconf/Makefile.am.

     1      1   
     2         -AM_CFLAGS = @THREADSAFE_FLAGS@ @DYNAMIC_EXTENSION_FLAGS@ @FTS5_FLAGS@ @JSON1_FLAGS@ @SESSION_FLAGS@ -DSQLITE_ENABLE_FTS3 -DSQLITE_ENABLE_RTREE
            2  +AM_CFLAGS = @THREADSAFE_FLAGS@ @DYNAMIC_EXTENSION_FLAGS@ @FTS5_FLAGS@ @JSON1_FLAGS@ @ZLIB_FLAGS@ @SESSION_FLAGS@ -DSQLITE_ENABLE_FTS3 -DSQLITE_ENABLE_RTREE
     3      3   
     4      4   lib_LTLIBRARIES = libsqlite3.la
     5      5   libsqlite3_la_SOURCES = sqlite3.c
     6      6   libsqlite3_la_LDFLAGS = -no-undefined -version-info 8:6:8
     7      7   
     8      8   bin_PROGRAMS = sqlite3
     9      9   sqlite3_SOURCES = shell.c sqlite3.h

Changes to autoconf/Makefile.msc.

   556    556   !IFNDEF SHELL_CORE_DEP
   557    557   !IF $(DYNAMIC_SHELL)!=0 || $(FOR_WIN10)!=0
   558    558   SHELL_CORE_DEP = $(SQLITE3DLL)
   559    559   !ELSE
   560    560   SHELL_CORE_DEP =
   561    561   !ENDIF
   562    562   !ENDIF
          563  +
   563    564   
   564    565   # This is the core library that the shell executable should link with.
   565    566   #
   566    567   !IFNDEF SHELL_CORE_LIB
   567    568   !IF $(DYNAMIC_SHELL)!=0 || $(FOR_WIN10)!=0
   568    569   SHELL_CORE_LIB = $(SQLITE3LIB)
   569    570   !ELSE
................................................................................
   925    926   
   926    927   # Additional compiler options for the shell.  These are only effective
   927    928   # when the shell is not being dynamically linked.
   928    929   #
   929    930   !IF $(DYNAMIC_SHELL)==0 && $(FOR_WIN10)==0
   930    931   SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_STMTVTAB
   931    932   SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_DBPAGE_VTAB -DSQLITE_ENABLE_DBSTAT_VTAB
          933  +SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_OFFSET_SQL_FUNC -DSQLITE_INTROSPECTION_PRAGMAS
   932    934   !ENDIF
   933    935   
   934    936   
   935    937   # This is the default Makefile target.  The objects listed here
   936    938   # are what get build when you type just "make" with no arguments.
   937    939   #
   938         -all:	dll shell
          940  +core:	dll shell
          941  +
          942  +# Targets that require the Tcl library.
          943  +#
          944  +tcl:	$(ALL_TCL_TARGETS)
          945  +
          946  +# This Makefile target builds all of the standard binaries.
          947  +#
          948  +all:	core tcl
   939    949   
   940    950   # Dynamic link library section.
   941    951   #
   942    952   dll:	$(SQLITE3DLL)
   943    953   
   944    954   # Shell executable.
   945    955   #

Changes to autoconf/configure.ac.

   160    160   else
   161    161     EXTRA_SHELL_OBJ=libsqlite3.la
   162    162   fi
   163    163   AC_SUBST(EXTRA_SHELL_OBJ)
   164    164   #-----------------------------------------------------------------------
   165    165   
   166    166   AC_CHECK_FUNCS(posix_fallocate)
          167  +AC_CHECK_HEADERS(zlib.h,[
          168  +  AC_SEARCH_LIBS(deflate,z,[ZLIB_FLAGS="-DSQLITE_HAVE_ZLIB"])
          169  +])
          170  +AC_SUBST(ZLIB_FLAGS)
   167    171   
   168    172   #-----------------------------------------------------------------------
   169    173   # UPDATE: Maybe it's better if users just set CFLAGS before invoking
   170    174   # configure. This option doesn't really add much...
   171    175   #
   172    176   #   --enable-tempstore
   173    177   #

Changes to configure.

     1      1   #! /bin/sh
     2      2   # Guess values for system-dependent variables and create Makefiles.
     3         -# Generated by GNU Autoconf 2.69 for sqlite 3.22.0.
            3  +# Generated by GNU Autoconf 2.69 for sqlite 3.23.0.
     4      4   #
     5      5   #
     6      6   # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
     7      7   #
     8      8   #
     9      9   # This configure script is free software; the Free Software Foundation
    10     10   # gives unlimited permission to copy, distribute and modify it.
................................................................................
   722    722   subdirs=
   723    723   MFLAGS=
   724    724   MAKEFLAGS=
   725    725   
   726    726   # Identity of this package.
   727    727   PACKAGE_NAME='sqlite'
   728    728   PACKAGE_TARNAME='sqlite'
   729         -PACKAGE_VERSION='3.22.0'
   730         -PACKAGE_STRING='sqlite 3.22.0'
          729  +PACKAGE_VERSION='3.23.0'
          730  +PACKAGE_STRING='sqlite 3.23.0'
   731    731   PACKAGE_BUGREPORT=''
   732    732   PACKAGE_URL=''
   733    733   
   734    734   # Factoring default headers for most tests.
   735    735   ac_includes_default="\
   736    736   #include <stdio.h>
   737    737   #ifdef HAVE_SYS_TYPES_H
................................................................................
  1461   1461   #
  1462   1462   # Report the --help message.
  1463   1463   #
  1464   1464   if test "$ac_init_help" = "long"; then
  1465   1465     # Omit some internal or obsolete options to make the list less imposing.
  1466   1466     # This message is too long to be a string in the A/UX 3.1 sh.
  1467   1467     cat <<_ACEOF
  1468         -\`configure' configures sqlite 3.22.0 to adapt to many kinds of systems.
         1468  +\`configure' configures sqlite 3.23.0 to adapt to many kinds of systems.
  1469   1469   
  1470   1470   Usage: $0 [OPTION]... [VAR=VALUE]...
  1471   1471   
  1472   1472   To assign environment variables (e.g., CC, CFLAGS...), specify them as
  1473   1473   VAR=VALUE.  See below for descriptions of some of the useful variables.
  1474   1474   
  1475   1475   Defaults for the options are specified in brackets.
................................................................................
  1526   1526     --build=BUILD     configure for building on BUILD [guessed]
  1527   1527     --host=HOST       cross-compile to build programs to run on HOST [BUILD]
  1528   1528   _ACEOF
  1529   1529   fi
  1530   1530   
  1531   1531   if test -n "$ac_init_help"; then
  1532   1532     case $ac_init_help in
  1533         -     short | recursive ) echo "Configuration of sqlite 3.22.0:";;
         1533  +     short | recursive ) echo "Configuration of sqlite 3.23.0:";;
  1534   1534      esac
  1535   1535     cat <<\_ACEOF
  1536   1536   
  1537   1537   Optional Features:
  1538   1538     --disable-option-checking  ignore unrecognized --enable/--with options
  1539   1539     --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
  1540   1540     --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
................................................................................
  1651   1651       cd "$ac_pwd" || { ac_status=$?; break; }
  1652   1652     done
  1653   1653   fi
  1654   1654   
  1655   1655   test -n "$ac_init_help" && exit $ac_status
  1656   1656   if $ac_init_version; then
  1657   1657     cat <<\_ACEOF
  1658         -sqlite configure 3.22.0
         1658  +sqlite configure 3.23.0
  1659   1659   generated by GNU Autoconf 2.69
  1660   1660   
  1661   1661   Copyright (C) 2012 Free Software Foundation, Inc.
  1662   1662   This configure script is free software; the Free Software Foundation
  1663   1663   gives unlimited permission to copy, distribute and modify it.
  1664   1664   _ACEOF
  1665   1665     exit
................................................................................
  2070   2070     eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
  2071   2071   
  2072   2072   } # ac_fn_c_check_header_mongrel
  2073   2073   cat >config.log <<_ACEOF
  2074   2074   This file contains any messages produced by compilers while
  2075   2075   running configure, to aid debugging if configure makes a mistake.
  2076   2076   
  2077         -It was created by sqlite $as_me 3.22.0, which was
         2077  +It was created by sqlite $as_me 3.23.0, which was
  2078   2078   generated by GNU Autoconf 2.69.  Invocation command line was
  2079   2079   
  2080   2080     $ $0 $@
  2081   2081   
  2082   2082   _ACEOF
  2083   2083   exec 5>>config.log
  2084   2084   {
................................................................................
 12238  12238   test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1
 12239  12239   
 12240  12240   cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 12241  12241   # Save the log message, to keep $0 and so on meaningful, and to
 12242  12242   # report actual input values of CONFIG_FILES etc. instead of their
 12243  12243   # values after options handling.
 12244  12244   ac_log="
 12245         -This file was extended by sqlite $as_me 3.22.0, which was
        12245  +This file was extended by sqlite $as_me 3.23.0, which was
 12246  12246   generated by GNU Autoconf 2.69.  Invocation command line was
 12247  12247   
 12248  12248     CONFIG_FILES    = $CONFIG_FILES
 12249  12249     CONFIG_HEADERS  = $CONFIG_HEADERS
 12250  12250     CONFIG_LINKS    = $CONFIG_LINKS
 12251  12251     CONFIG_COMMANDS = $CONFIG_COMMANDS
 12252  12252     $ $0 $@
................................................................................
 12304  12304   
 12305  12305   Report bugs to the package provider."
 12306  12306   
 12307  12307   _ACEOF
 12308  12308   cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 12309  12309   ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 12310  12310   ac_cs_version="\\
 12311         -sqlite config.status 3.22.0
        12311  +sqlite config.status 3.23.0
 12312  12312   configured by $0, generated by GNU Autoconf 2.69,
 12313  12313     with options \\"\$ac_cs_config\\"
 12314  12314   
 12315  12315   Copyright (C) 2012 Free Software Foundation, Inc.
 12316  12316   This config.status script is free software; the Free Software Foundation
 12317  12317   gives unlimited permission to copy, distribute and modify it."
 12318  12318   

Changes to ext/expert/expert1.test.

    18     18   #
    19     19   #
    20     20   if {![info exists testdir]} {
    21     21     set testdir [file join [file dirname [info script]] .. .. test]
    22     22   }
    23     23   source $testdir/tester.tcl
    24     24   set testprefix expert1
           25  +
           26  +if {[info commands sqlite3_expert_new]==""} {
           27  +  finish_test
           28  +  return
           29  +}
    25     30   
    26     31   set CLI [test_binary_name sqlite3]
    27     32   set CMD [test_binary_name sqlite3_expert]
    28     33   
    29     34   proc squish {txt} {
    30     35     regsub -all {[[:space:]]+} $txt { }
    31     36   }

Changes to ext/expert/sqlite3expert.c.

    11     11   *************************************************************************
    12     12   */
    13     13   #include "sqlite3expert.h"
    14     14   #include <assert.h>
    15     15   #include <string.h>
    16     16   #include <stdio.h>
    17     17   
           18  +#ifndef SQLITE_OMIT_VIRTUALTABLE 
           19  +
    18     20   typedef sqlite3_int64 i64;
    19     21   typedef sqlite3_uint64 u64;
    20     22   
    21     23   typedef struct IdxColumn IdxColumn;
    22     24   typedef struct IdxConstraint IdxConstraint;
    23     25   typedef struct IdxScan IdxScan;
    24     26   typedef struct IdxStatement IdxStatement;
................................................................................
   491    493             pScan->pOrder = pNew;
   492    494             n++;
   493    495           }
   494    496         }
   495    497       }
   496    498     }
   497    499   
   498         -  pIdxInfo->estimatedCost = 1000000.0 / n;
          500  +  pIdxInfo->estimatedCost = 1000000.0 / (n+1);
   499    501     return rc;
   500    502   }
   501    503   
   502    504   static int expertUpdate(
   503    505     sqlite3_vtab *pVtab, 
   504    506     int nData, 
   505    507     sqlite3_value **azData, 
   506    508     sqlite_int64 *pRowid
   507    509   ){
          510  +  (void)pVtab;
          511  +  (void)nData;
          512  +  (void)azData;
          513  +  (void)pRowid;
   508    514     return SQLITE_OK;
   509    515   }
   510    516   
   511    517   /* 
   512    518   ** Virtual table module xOpen method.
   513    519   */
   514    520   static int expertOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
   515    521     int rc = SQLITE_OK;
   516    522     ExpertCsr *pCsr;
          523  +  (void)pVTab;
   517    524     pCsr = idxMalloc(&rc, sizeof(ExpertCsr));
   518    525     *ppCursor = (sqlite3_vtab_cursor*)pCsr;
   519    526     return rc;
   520    527   }
   521    528   
   522    529   /* 
   523    530   ** Virtual table module xClose method.
................................................................................
   559    566     return rc;
   560    567   }
   561    568   
   562    569   /* 
   563    570   ** Virtual table module xRowid method.
   564    571   */
   565    572   static int expertRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
          573  +  (void)cur;
   566    574     *pRowid = 0;
   567    575     return SQLITE_OK;
   568    576   }
   569    577   
   570    578   /* 
   571    579   ** Virtual table module xColumn method.
   572    580   */
................................................................................
   589    597     int argc, sqlite3_value **argv
   590    598   ){
   591    599     ExpertCsr *pCsr = (ExpertCsr*)cur;
   592    600     ExpertVtab *pVtab = (ExpertVtab*)(cur->pVtab);
   593    601     sqlite3expert *pExpert = pVtab->pExpert;
   594    602     int rc;
   595    603   
          604  +  (void)idxNum;
          605  +  (void)idxStr;
          606  +  (void)argc;
          607  +  (void)argv;
   596    608     rc = sqlite3_finalize(pCsr->pData);
   597    609     pCsr->pData = 0;
   598    610     if( rc==SQLITE_OK ){
   599    611       rc = idxPrintfPrepareStmt(pExpert->db, &pCsr->pData, &pVtab->base.zErrMsg,
   600    612           "SELECT * FROM main.%Q WHERE sample()", pVtab->pTab->zName
   601    613       );
   602    614     }
................................................................................
   750    762     if( *pRc==SQLITE_OK ){
   751    763       zAppend = sqlite3_vmprintf(zFmt, ap);
   752    764       if( zAppend ){
   753    765         nAppend = STRLEN(zAppend);
   754    766         zRet = (char*)sqlite3_malloc(nIn + nAppend + 1);
   755    767       }
   756    768       if( zAppend && zRet ){
   757         -      memcpy(zRet, zIn, nIn);
          769  +      if( nIn ) memcpy(zRet, zIn, nIn);
   758    770         memcpy(&zRet[nIn], zAppend, nAppend+1);
   759    771       }else{
   760    772         sqlite3_free(zRet);
   761    773         zRet = 0;
   762    774         *pRc = SQLITE_NOMEM;
   763    775       }
   764    776       sqlite3_free(zAppend);
................................................................................
   904    916     sqlite3 *dbm = p->dbm;
   905    917     int rc = SQLITE_OK;
   906    918     if( (pEq || pTail) && 0==idxFindCompatible(&rc, dbm, pScan, pEq, pTail) ){
   907    919       IdxTable *pTab = pScan->pTab;
   908    920       char *zCols = 0;
   909    921       char *zIdx = 0;
   910    922       IdxConstraint *pCons;
   911         -    int h = 0;
          923  +    unsigned int h = 0;
   912    924       const char *zFmt;
   913    925   
   914    926       for(pCons=pEq; pCons; pCons=pCons->pLink){
   915    927         zCols = idxAppendColDefn(&rc, zCols, pTab, pCons);
   916    928       }
   917    929       for(pCons=pTail; pCons; pCons=pCons->pLink){
   918    930         zCols = idxAppendColDefn(&rc, zCols, pTab, pCons);
................................................................................
   999   1011     return rc;
  1000   1012   }
  1001   1013   
  1002   1014   /*
  1003   1015   ** Create candidate indexes in database [dbm] based on the data in 
  1004   1016   ** linked-list pScan.
  1005   1017   */
  1006         -static int idxCreateCandidates(sqlite3expert *p, char **pzErr){
         1018  +static int idxCreateCandidates(sqlite3expert *p){
  1007   1019     int rc = SQLITE_OK;
  1008   1020     IdxScan *pIter;
  1009   1021   
  1010   1022     for(pIter=p->pScan; pIter && rc==SQLITE_OK; pIter=pIter->pNextScan){
  1011   1023       rc = idxCreateFromWhere(p, pIter, 0);
  1012   1024       if( rc==SQLITE_OK && pIter->pOrder ){
  1013   1025         rc = idxCreateFromWhere(p, pIter, pIter->pOrder);
................................................................................
  1162   1174     int eOp,
  1163   1175     const char *z3,
  1164   1176     const char *z4,
  1165   1177     const char *zDb,
  1166   1178     const char *zTrigger
  1167   1179   ){
  1168   1180     int rc = SQLITE_OK;
         1181  +  (void)z4;
         1182  +  (void)zTrigger;
  1169   1183     if( eOp==SQLITE_INSERT || eOp==SQLITE_UPDATE || eOp==SQLITE_DELETE ){
  1170   1184       if( sqlite3_stricmp(zDb, "main")==0 ){
  1171   1185         sqlite3expert *p = (sqlite3expert*)pCtx;
  1172   1186         IdxTable *pTab;
  1173   1187         for(pTab=p->pTable; pTab; pTab=pTab->pNext){
  1174   1188           if( 0==sqlite3_stricmp(z3, pTab->zName) ) break;
  1175   1189         }
................................................................................
  1364   1378     sqlite3_context *pCtx,
  1365   1379     int argc,
  1366   1380     sqlite3_value **argv
  1367   1381   ){
  1368   1382     struct IdxSampleCtx *p = (struct IdxSampleCtx*)sqlite3_user_data(pCtx);
  1369   1383     int bRet;
  1370   1384   
         1385  +  (void)argv;
  1371   1386     assert( argc==0 );
  1372   1387     if( p->nRow==0.0 ){
  1373   1388       bRet = 1;
  1374   1389     }else{
  1375   1390       bRet = (p->nRet / p->nRow) <= p->target;
  1376   1391       if( bRet==0 ){
  1377   1392         unsigned short rnd;
................................................................................
  1519   1534       const char *zName = (const char*)sqlite3_column_text(pIndexXInfo, 0);
  1520   1535       const char *zColl = (const char*)sqlite3_column_text(pIndexXInfo, 1);
  1521   1536       zCols = idxAppendText(&rc, zCols, 
  1522   1537           "%sx.%Q IS rem(%d, x.%Q) COLLATE %s", zComma, zName, nCol, zName, zColl
  1523   1538       );
  1524   1539       zOrder = idxAppendText(&rc, zOrder, "%s%d", zComma, ++nCol);
  1525   1540     }
         1541  +  sqlite3_reset(pIndexXInfo);
  1526   1542     if( rc==SQLITE_OK ){
  1527   1543       if( p->iSample==100 ){
  1528   1544         zQuery = sqlite3_mprintf(
  1529   1545             "SELECT %s FROM %Q x ORDER BY %s", zCols, zTab, zOrder
  1530   1546         );
  1531   1547       }else{
  1532   1548         zQuery = sqlite3_mprintf(
................................................................................
  1848   1864     IdxHashEntry *pEntry;
  1849   1865   
  1850   1866     /* Do trigger processing to collect any extra IdxScan structures */
  1851   1867     rc = idxProcessTriggers(p, pzErr);
  1852   1868   
  1853   1869     /* Create candidate indexes within the in-memory database file */
  1854   1870     if( rc==SQLITE_OK ){
  1855         -    rc = idxCreateCandidates(p, pzErr);
         1871  +    rc = idxCreateCandidates(p);
  1856   1872     }
  1857   1873   
  1858   1874     /* Generate the stat1 data */
  1859   1875     if( rc==SQLITE_OK ){
  1860   1876       rc = idxPopulateStat1(p, pzErr);
  1861   1877     }
  1862   1878   
................................................................................
  1928   1944       idxTableFree(p->pTable);
  1929   1945       idxWriteFree(p->pWrite);
  1930   1946       idxHashClear(&p->hIdx);
  1931   1947       sqlite3_free(p->zCandidates);
  1932   1948       sqlite3_free(p);
  1933   1949     }
  1934   1950   }
         1951  +
         1952  +#endif /* ifndef SQLITE_OMIT_VIRTUAL_TABLE */

Changes to ext/expert/test_expert.c.

    22     22   #else
    23     23   #  include "tcl.h"
    24     24   #  ifndef SQLITE_TCLAPI
    25     25   #    define SQLITE_TCLAPI
    26     26   #  endif
    27     27   #endif
    28     28   
           29  +#ifndef SQLITE_OMIT_VIRTUALTABLE
           30  +
    29     31   /*
    30     32   ** Extract an sqlite3* db handle from the object passed as the second
    31     33   ** argument. If successful, set *pDb to point to the db handle and return
    32     34   ** TCL_OK. Otherwise, return TCL_ERROR.
    33     35   */
    34     36   static int dbHandleFromObj(Tcl_Interp *interp, Tcl_Obj *pObj, sqlite3 **pDb){
    35     37     Tcl_CmdInfo info;
................................................................................
   191    193     }
   192    194   
   193    195     sqlite3_free(zCmd);
   194    196     sqlite3_free(zErr);
   195    197     return rc;
   196    198   }
   197    199   
          200  +#endif  /* ifndef SQLITE_OMIT_VIRTUALTABLE */
          201  +
   198    202   int TestExpert_Init(Tcl_Interp *interp){
          203  +#ifndef SQLITE_OMIT_VIRTUALTABLE
   199    204     struct Cmd {
   200    205       const char *zCmd;
   201    206       Tcl_ObjCmdProc *xProc;
   202    207     } aCmd[] = {
   203    208       { "sqlite3_expert_new", test_sqlite3_expert_new },
   204    209     };
   205    210     int i;
   206    211   
   207    212     for(i=0; i<sizeof(aCmd)/sizeof(struct Cmd); i++){
   208    213       struct Cmd *p = &aCmd[i];
   209    214       Tcl_CreateObjCommand(interp, p->zCmd, p->xProc, 0, 0);
   210    215     }
   211         -
          216  +#endif
   212    217     return TCL_OK;
   213    218   }
   214    219   
   215    220   #endif

Changes to ext/fts5/fts5_tcl.c.

   429    429         rc = p->pApi->xSetAuxdata(p->pFts, (void*)((char*)0 + iVal), 0);
   430    430         break;
   431    431       }
   432    432       CASE(15, "xGetAuxdataInt") {
   433    433         int iVal;
   434    434         int bClear;
   435    435         if( Tcl_GetBooleanFromObj(interp, objv[2], &bClear) ) return TCL_ERROR;
   436         -      iVal = ((char*)p->pApi->xGetAuxdata(p->pFts, bClear) - (char*)0);
          436  +      iVal = (int)((char*)p->pApi->xGetAuxdata(p->pFts, bClear) - (char*)0);
   437    437         Tcl_SetObjResult(interp, Tcl_NewIntObj(iVal));
   438    438         break;
   439    439       }
   440    440   
   441    441       CASE(16, "xPhraseForeach") {
   442    442         int iPhrase;
   443    443         int iCol;
................................................................................
   478    478         Fts5PhraseIter iter;
   479    479   
   480    480         if( Tcl_GetIntFromObj(interp, objv[2], &iPhrase) ) return TCL_ERROR;
   481    481         zColvar = Tcl_GetString(objv[3]);
   482    482   
   483    483         rc = p->pApi->xPhraseFirstColumn(p->pFts, iPhrase, &iter, &iCol);
   484    484         if( rc!=SQLITE_OK ){
   485         -        Tcl_AppendResult(interp, sqlite3ErrName(rc), 0);
          485  +        Tcl_SetResult(interp, (char*)sqlite3ErrName(rc), TCL_VOLATILE);
   486    486           return TCL_ERROR;
   487    487         }
   488    488         for( ; iCol>=0; p->pApi->xPhraseNextColumn(p->pFts, &iter, &iCol)){
   489    489           Tcl_SetVar2Ex(interp, zColvar, 0, Tcl_NewIntObj(iCol), 0);
   490    490           rc = Tcl_EvalObjEx(interp, pScript, 0);
   491    491           if( rc==TCL_CONTINUE ) rc = TCL_OK;
   492    492           if( rc!=TCL_OK ){
................................................................................
   920    920           "sqlite3_fts5_token may only be used by tokenizer callback", 0
   921    921       );
   922    922       return TCL_ERROR;
   923    923     }
   924    924   
   925    925     rc = p->xToken(p->pCtx, tflags, zToken, nToken, iStart, iEnd);
   926    926     Tcl_SetResult(interp, (char*)sqlite3ErrName(rc), TCL_VOLATILE);
   927         -  return TCL_OK;
          927  +  return rc==SQLITE_OK ? TCL_OK : TCL_ERROR;
   928    928   
   929    929    usage:
   930    930     Tcl_WrongNumArgs(interp, 1, objv, "?-colocated? TEXT START END");
   931    931     return TCL_ERROR;
   932    932   }
   933    933   
   934    934   static void f5tDelTokenizer(void *pCtx){

Changes to ext/fts5/test/fts5fault6.test.

   249    249     sqlite3_fts5_register_matchinfo db
   250    250     db func mit mit
   251    251   } -body {
   252    252     db eval { 
   253    253       SELECT rowid, mit(matchinfo(t1, 'x')) FROM t1 WHERE t1 MATCH 'a AND c'
   254    254     }
   255    255   } -test {
   256         -  faultsim_test_result [list 0 $::res]
          256  +  faultsim_test_result [list 0 $::res] {1 {SQL logic error}}
   257    257   }
   258    258   
   259    259   do_faultsim_test 5.3 -faults oom* -prep {
   260    260     faultsim_restore_and_reopen
   261    261     sqlite3_fts5_create_tokenizer db tcl tcl_create
   262    262   } -body {
   263    263     db eval { 
   264    264       SELECT count(*) FROM t1 WHERE t1 MATCH 'd AND e AND f'
   265    265     }
   266    266   } -test {
   267         -  faultsim_test_result {0 29}
          267  +  faultsim_test_result {0 29} {1 {SQL logic error}}
   268    268   }
   269    269   
   270    270   do_faultsim_test 5.4 -faults oom* -prep {
   271    271     faultsim_restore_and_reopen
   272    272     sqlite3_fts5_create_tokenizer db tcl tcl_create
   273    273   } -body {
   274    274     db eval { 
   275    275       SELECT count(*) FROM t1 WHERE t1 MATCH 'x + e'
   276    276     }
   277    277   } -test {
   278         -  faultsim_test_result {0 1}
          278  +  faultsim_test_result {0 1} {1 {SQL logic error}}
   279    279   }
   280    280   
   281    281   #-------------------------------------------------------------------------
   282    282   catch { db close }
   283    283   do_faultsim_test 6 -faults oom* -prep {
   284    284     sqlite_orig db test.db
   285    285     sqlite3_db_config_lookaside db 0 0 0

Changes to ext/fts5/test/fts5fault9.test.

    20     20   ifcapable !fts5 {
    21     21     finish_test
    22     22     return
    23     23   }
    24     24   
    25     25   foreach_detail_mode $testprefix {
    26     26   
           27  +if {"%DETAIL%" != "none"} continue
           28  +
    27     29   fts5_aux_test_functions db
    28     30   
    29     31   do_execsql_test 1.0 {
    30     32     CREATE VIRTUAL TABLE t1 USING fts5(a, b, detail=%DETAIL%);
    31     33     INSERT INTO t1(t1, rank) VALUES('pgsz', 32);
    32     34     WITH seq(s) AS ( SELECT 1 UNION ALL SELECT s+1 FROM seq WHERE s<50)
    33     35     INSERT INTO t1 SELECT 'x x x y y y', 'a b c d e f' FROM seq;
................................................................................
    94     96     INSERT INTO t4 VALUES('c1 c2 c3', 'c4 c5 c6', 'c7 c8 c9');
    95     97   }
    96     98   
    97     99   do_faultsim_test 4.1 -faults oom-t* -body {
    98    100     execsql { SELECT rowid, fts5_test_collist(t4) FROM t4('2') }
    99    101   } -test {
   100    102     faultsim_test_result \
   101         -      {0 {1 {0.0 0.1 0.2} 2 {0.0 0.1 0.2} 3 {0.0 0.1 0.2}}} {1 SQLITE_NOMEM}
          103  +      {0 {1 {0.0 0.1 0.2} 2 {0.0 0.1 0.2} 3 {0.0 0.1 0.2}}} \
          104  +      {1 SQLITE_NOMEM} {1 SQLITE_ERROR} {1 {SQL logic error}}
   102    105   }
   103    106   
   104    107   do_faultsim_test 4.2 -faults oom-t* -body {
   105    108     execsql { SELECT rowid, fts5_test_collist(t4) FROM t4('a5 OR b5 OR c5') }
   106    109   } -test {
   107    110     faultsim_test_result \
   108         -      {0 {4 {0.0 0.1 0.2} 5 {1.0 1.1 1.2} 6 {2.0 2.1 2.2}}} {1 SQLITE_NOMEM}
          111  +      {0 {4 {0.0 0.1 0.2} 5 {1.0 1.1 1.2} 6 {2.0 2.1 2.2}}} \
          112  +      {1 SQLITE_NOMEM} {1 SQLITE_ERROR} {1 {SQL logic error}}
   109    113   }
   110    114   
   111    115   
   112    116   #-------------------------------------------------------------------------
   113    117   # An OOM within an "ORDER BY rank" query.
   114    118   #
   115    119   db func rnddoc fts5_rnddoc 

Changes to ext/lsm1/lsm-test/lsmtest.h.

   117    117   ** Functions in wrapper3.c. This file contains the tdb wrapper for lsm.
   118    118   ** The wrapper for lsm is a bit more involved than the others, as it 
   119    119   ** includes code for a couple of different lsm configurations, and for
   120    120   ** various types of fault injection and robustness testing.
   121    121   */
   122    122   int test_lsm_open(const char*, const char *zFile, int bClear, TestDb **ppDb);
   123    123   int test_lsm_lomem_open(const char*, const char*, int bClear, TestDb **ppDb);
          124  +int test_lsm_lomem2_open(const char*, const char*, int bClear, TestDb **ppDb);
   124    125   int test_lsm_zip_open(const char*, const char*, int bClear, TestDb **ppDb);
   125    126   int test_lsm_small_open(const char*, const char*, int bClear, TestDb **ppDb);
   126    127   int test_lsm_mt2(const char*, const char *zFile, int bClear, TestDb **ppDb);
   127    128   int test_lsm_mt3(const char*, const char *zFile, int bClear, TestDb **ppDb);
   128    129   
   129    130   int tdb_lsm_configure(lsm_db *, const char *);
   130    131   

Changes to ext/lsm1/lsm-test/lsmtest_tdb.c.

   717    717     const char *zName;
   718    718     const char *zDefaultDb;
   719    719     int (*xOpen)(const char *, const char *zFilename, int bClear, TestDb **ppDb);
   720    720   } aLib[] = {
   721    721     { "sqlite3",      "testdb.sqlite",    sql_open },
   722    722     { "lsm_small",    "testdb.lsm_small", test_lsm_small_open },
   723    723     { "lsm_lomem",    "testdb.lsm_lomem", test_lsm_lomem_open },
          724  +  { "lsm_lomem2",   "testdb.lsm_lomem2", test_lsm_lomem2_open },
   724    725   #ifdef HAVE_ZLIB
   725    726     { "lsm_zip",      "testdb.lsm_zip",   test_lsm_zip_open },
   726    727   #endif
   727    728     { "lsm",          "testdb.lsm",       test_lsm_open },
   728    729   #ifdef LSM_MUTEX_PTHREADS
   729    730     { "lsm_mt2",      "testdb.lsm_mt2",   test_lsm_mt2 },
   730    731     { "lsm_mt3",      "testdb.lsm_mt3",   test_lsm_mt3 },

Changes to ext/lsm1/lsm-test/lsmtest_tdb3.c.

  1028   1028     const char *zCfg = 
  1029   1029       "page_size=256 block_size=64 autoflush=16 "
  1030   1030       "autocheckpoint=32"
  1031   1031       "mmap=0 "
  1032   1032     ;
  1033   1033     return testLsmOpen(zCfg, zFilename, bClear, ppDb);
  1034   1034   }
         1035  +
         1036  +int test_lsm_lomem2_open(
         1037  +  const char *zSpec, 
         1038  +  const char *zFilename, 
         1039  +  int bClear, 
         1040  +  TestDb **ppDb
         1041  +){
         1042  +    /* "max_freelist=4 autocheckpoint=32" */
         1043  +  const char *zCfg = 
         1044  +    "page_size=512 block_size=64 autoflush=0 mmap=0 "
         1045  +  ;
         1046  +  return testLsmOpen(zCfg, zFilename, bClear, ppDb);
         1047  +}
  1035   1048   
  1036   1049   int test_lsm_zip_open(
  1037   1050     const char *zSpec, 
  1038   1051     const char *zFilename, 
  1039   1052     int bClear, 
  1040   1053     TestDb **ppDb
  1041   1054   ){

Changes to ext/lsm1/lsm_main.c.

   679    679       int pgsz = lsmFsPageSize(pDb->pFS);
   680    680       int nQuant = LSM_AUTOWORK_QUANT * pgsz;
   681    681       int nBefore;
   682    682       int nAfter;
   683    683       int nDiff;
   684    684   
   685    685       if( nQuant>pDb->nTreeLimit ){
   686         -      nQuant = pDb->nTreeLimit;
          686  +      nQuant = LSM_MAX(pDb->nTreeLimit, pgsz);
   687    687       }
   688    688   
   689    689       nBefore = lsmTreeSize(pDb);
   690    690       if( bDeleteRange ){
   691    691         rc = lsmTreeDelete(pDb, (void *)pKey, nKey, (void *)pVal, nVal);
   692    692       }else{
   693    693         rc = lsmTreeInsert(pDb, (void *)pKey, nKey, (void *)pVal, nVal);

Changes to ext/lsm1/lsm_sorted.c.

  5248   5248       nRem -= nPg;
  5249   5249       if( nPg ) bDirty = 1;
  5250   5250     }
  5251   5251   
  5252   5252     /* If the in-memory part of the free-list is too large, write a new 
  5253   5253     ** top-level containing just the in-memory free-list entries to disk. */
  5254   5254     if( rc==LSM_OK && pDb->pWorker->freelist.nEntry > pDb->nMaxFreelist ){
  5255         -    int nPg = 0;
  5256   5255       while( rc==LSM_OK && lsmDatabaseFull(pDb) ){
         5256  +      int nPg = 0;
  5257   5257         rc = sortedWork(pDb, 16, nMerge, 1, &nPg);
  5258   5258         nRem -= nPg;
  5259   5259       }
  5260   5260       if( rc==LSM_OK ){
  5261   5261         rc = sortedNewFreelistOnly(pDb);
  5262   5262       }
  5263         -    nRem -= nPg;
  5264         -    if( nPg ) bDirty = 1;
         5263  +    bDirty = 1;
  5265   5264     }
  5266   5265   
  5267   5266     if( rc==LSM_OK ){
  5268   5267       *pnWrite = (nMax - nRem);
  5269   5268       *pbCkpt = (bCkpt && nRem<=0);
  5270   5269       if( nMerge==1 && pDb->nAutockpt>0 && *pnWrite>0
  5271   5270        && pWorker->pLevel 

Changes to ext/misc/README.md.

    10     10   as follows:
    11     11   
    12     12     *  **carray.c** &mdash;  This module implements the
    13     13        [carray](https://www.sqlite.org/carray.html) table-valued function.
    14     14        It is a good example of how to go about implementing a custom
    15     15        [table-valued function](https://www.sqlite.org/vtab.html#tabfunc2).
    16     16   
           17  +  *  **csv.c** &mdash;  A [virtual table](https://sqlite.org/vtab.html)
           18  +     for reading 
           19  +     [Comma-Separated-Value (CSV) files](https://en.wikipedia.org/wiki/Comma-separated_values).
           20  +
    17     21     *  **dbdump.c** &mdash;  This is not actually a loadable extension, but
    18     22        rather a library that implements an approximate equivalent to the
    19     23        ".dump" command of the
    20     24        [command-line shell](https://www.sqlite.org/cli.html).
           25  +
           26  +  *  **json1.c** &mdash;  Various SQL functions and table-valued functions
           27  +     for processing JSON.  This extension is already built into the
           28  +     [SQLite amalgamation](https://sqlite.org/amalgamation.html).  See
           29  +     <https://sqlite.org/json1.html> for additional information.
    21     30   
    22     31     *  **memvfs.c** &mdash;  This file implements a custom
    23     32        [VFS](https://www.sqlite.org/vfs.html) that stores an entire database
    24     33        file in a single block of RAM.  It serves as a good example of how
    25     34        to implement a simple custom VFS.
    26     35   
    27     36     *  **rot13.c** &mdash;  This file implements the very simple rot13()
................................................................................
    34     43   
    35     44     *  **shathree.c** &mdash;  An implementation of the sha3() and
    36     45        sha3_query() SQL functions.  The file is named "shathree.c" instead
    37     46        of "sha3.c" because the default entry point names in SQLite are based
    38     47        on the source filename with digits removed, so if we used the name
    39     48        "sha3.c" then the entry point would conflict with the prior "sha1.c"
    40     49        extension.
           50  +
           51  +  *  **unionvtab.c** &mdash; Implementation of the unionvtab and
           52  +     [swarmvtab](https://sqlite.org/swarmvtab.html) virtual tables.
           53  +     These virtual tables allow a single
           54  +     large table to be spread out across multiple database files.  In the
           55  +     case of swarmvtab, the individual database files can be attached on
           56  +     demand.
           57  +
           58  +  *  **zipfile.c** &mdash;  A [virtual table](https://sqlite.org/vtab.html)
           59  +     that can read and write a 
           60  +     [ZIP archive](https://en.wikipedia.org/wiki/Zip_%28file_format%29).

Added ext/misc/appendvfs.c.

            1  +/*
            2  +** 2017-10-20
            3  +**
            4  +** The author disclaims copyright to this source code.  In place of
            5  +** a legal notice, here is a blessing:
            6  +**
            7  +**    May you do good and not evil.
            8  +**    May you find forgiveness for yourself and forgive others.
            9  +**    May you share freely, never taking more than you give.
           10  +**
           11  +******************************************************************************
           12  +**
           13  +** This file implements a VFS shim that allows an SQLite database to be
           14  +** appended onto the end of some other file, such as an executable.
           15  +**
           16  +** A special record must appear at the end of the file that identifies the
           17  +** file as an appended database and provides an offset to page 1.  For
           18  +** best performance page 1 should be located at a disk page boundary, though
           19  +** that is not required.
           20  +**
           21  +** When opening a database using this VFS, the connection might treat
           22  +** the file as an ordinary SQLite database, or it might treat is as a
           23  +** database appended onto some other file.  Here are the rules:
           24  +**
           25  +**  (1)  When opening a new empty file, that file is treated as an ordinary
           26  +**       database.
           27  +**
           28  +**  (2)  When opening a file that begins with the standard SQLite prefix
           29  +**       string "SQLite format 3", that file is treated as an ordinary
           30  +**       database.
           31  +**
           32  +**  (3)  When opening a file that ends with the appendvfs trailer string
           33  +**       "Start-Of-SQLite3-NNNNNNNN" that file is treated as an appended
           34  +**       database.
           35  +**
           36  +**  (4)  If none of the above apply and the SQLITE_OPEN_CREATE flag is
           37  +**       set, then a new database is appended to the already existing file.
           38  +**
           39  +**  (5)  Otherwise, SQLITE_CANTOPEN is returned.
           40  +**
           41  +** To avoid unnecessary complications with the PENDING_BYTE, the size of
           42  +** the file containing the database is limited to 1GB.  This VFS will refuse
           43  +** to read or write past the 1GB mark.  This restriction might be lifted in
           44  +** future versions.  For now, if you need a large database, then keep the
           45  +** database in a separate file.
           46  +**
           47  +** If the file being opened is not an appended database, then this shim is
           48  +** a pass-through into the default underlying VFS.
           49  +**/
           50  +#include "sqlite3ext.h"
           51  +SQLITE_EXTENSION_INIT1
           52  +#include <string.h>
           53  +#include <assert.h>
           54  +
           55  +/* The append mark at the end of the database is:
           56  +**
           57  +**     Start-Of-SQLite3-NNNNNNNN
           58  +**     123456789 123456789 12345
           59  +**
           60  +** The NNNNNNNN represents a 64-bit big-endian unsigned integer which is
           61  +** the offset to page 1.
           62  +*/
           63  +#define APND_MARK_PREFIX     "Start-Of-SQLite3-"
           64  +#define APND_MARK_PREFIX_SZ  17
           65  +#define APND_MARK_SIZE       25
           66  +
           67  +/*
           68  +** Maximum size of the combined prefix + database + append-mark.  This
           69  +** must be less than 0x40000000 to avoid locking issues on Windows.
           70  +*/
           71  +#define APND_MAX_SIZE  (65536*15259)
           72  +
           73  +/*
           74  +** Forward declaration of objects used by this utility
           75  +*/
           76  +typedef struct sqlite3_vfs ApndVfs;
           77  +typedef struct ApndFile ApndFile;
           78  +
           79  +/* Access to a lower-level VFS that (might) implement dynamic loading,
           80  +** access to randomness, etc.
           81  +*/
           82  +#define ORIGVFS(p)  ((sqlite3_vfs*)((p)->pAppData))
           83  +#define ORIGFILE(p) ((sqlite3_file*)(((ApndFile*)(p))+1))
           84  +
           85  +/* An open file */
           86  +struct ApndFile {
           87  +  sqlite3_file base;              /* IO methods */
           88  +  sqlite3_int64 iPgOne;           /* File offset to page 1 */
           89  +  sqlite3_int64 iMark;            /* Start of the append-mark */
           90  +};
           91  +
           92  +/*
           93  +** Methods for ApndFile
           94  +*/
           95  +static int apndClose(sqlite3_file*);
           96  +static int apndRead(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst);
           97  +static int apndWrite(sqlite3_file*,const void*,int iAmt, sqlite3_int64 iOfst);
           98  +static int apndTruncate(sqlite3_file*, sqlite3_int64 size);
           99  +static int apndSync(sqlite3_file*, int flags);
          100  +static int apndFileSize(sqlite3_file*, sqlite3_int64 *pSize);
          101  +static int apndLock(sqlite3_file*, int);
          102  +static int apndUnlock(sqlite3_file*, int);
          103  +static int apndCheckReservedLock(sqlite3_file*, int *pResOut);
          104  +static int apndFileControl(sqlite3_file*, int op, void *pArg);
          105  +static int apndSectorSize(sqlite3_file*);
          106  +static int apndDeviceCharacteristics(sqlite3_file*);
          107  +static int apndShmMap(sqlite3_file*, int iPg, int pgsz, int, void volatile**);
          108  +static int apndShmLock(sqlite3_file*, int offset, int n, int flags);
          109  +static void apndShmBarrier(sqlite3_file*);
          110  +static int apndShmUnmap(sqlite3_file*, int deleteFlag);
          111  +static int apndFetch(sqlite3_file*, sqlite3_int64 iOfst, int iAmt, void **pp);
          112  +static int apndUnfetch(sqlite3_file*, sqlite3_int64 iOfst, void *p);
          113  +
          114  +/*
          115  +** Methods for ApndVfs
          116  +*/
          117  +static int apndOpen(sqlite3_vfs*, const char *, sqlite3_file*, int , int *);
          118  +static int apndDelete(sqlite3_vfs*, const char *zName, int syncDir);
          119  +static int apndAccess(sqlite3_vfs*, const char *zName, int flags, int *);
          120  +static int apndFullPathname(sqlite3_vfs*, const char *zName, int, char *zOut);
          121  +static void *apndDlOpen(sqlite3_vfs*, const char *zFilename);
          122  +static void apndDlError(sqlite3_vfs*, int nByte, char *zErrMsg);
          123  +static void (*apndDlSym(sqlite3_vfs *pVfs, void *p, const char*zSym))(void);
          124  +static void apndDlClose(sqlite3_vfs*, void*);
          125  +static int apndRandomness(sqlite3_vfs*, int nByte, char *zOut);
          126  +static int apndSleep(sqlite3_vfs*, int microseconds);
          127  +static int apndCurrentTime(sqlite3_vfs*, double*);
          128  +static int apndGetLastError(sqlite3_vfs*, int, char *);
          129  +static int apndCurrentTimeInt64(sqlite3_vfs*, sqlite3_int64*);
          130  +static int apndSetSystemCall(sqlite3_vfs*, const char*,sqlite3_syscall_ptr);
          131  +static sqlite3_syscall_ptr apndGetSystemCall(sqlite3_vfs*, const char *z);
          132  +static const char *apndNextSystemCall(sqlite3_vfs*, const char *zName);
          133  +
          134  +static sqlite3_vfs apnd_vfs = {
          135  +  3,                            /* iVersion (set when registered) */
          136  +  0,                            /* szOsFile (set when registered) */
          137  +  1024,                         /* mxPathname */
          138  +  0,                            /* pNext */
          139  +  "apndvfs",                    /* zName */
          140  +  0,                            /* pAppData (set when registered) */ 
          141  +  apndOpen,                     /* xOpen */
          142  +  apndDelete,                   /* xDelete */
          143  +  apndAccess,                   /* xAccess */
          144  +  apndFullPathname,             /* xFullPathname */
          145  +  apndDlOpen,                   /* xDlOpen */
          146  +  apndDlError,                  /* xDlError */
          147  +  apndDlSym,                    /* xDlSym */
          148  +  apndDlClose,                  /* xDlClose */
          149  +  apndRandomness,               /* xRandomness */
          150  +  apndSleep,                    /* xSleep */
          151  +  apndCurrentTime,              /* xCurrentTime */
          152  +  apndGetLastError,             /* xGetLastError */
          153  +  apndCurrentTimeInt64,         /* xCurrentTimeInt64 */
          154  +  apndSetSystemCall,            /* xSetSystemCall */
          155  +  apndGetSystemCall,            /* xGetSystemCall */
          156  +  apndNextSystemCall            /* xNextSystemCall */
          157  +};
          158  +
          159  +static const sqlite3_io_methods apnd_io_methods = {
          160  +  3,                              /* iVersion */
          161  +  apndClose,                      /* xClose */
          162  +  apndRead,                       /* xRead */
          163  +  apndWrite,                      /* xWrite */
          164  +  apndTruncate,                   /* xTruncate */
          165  +  apndSync,                       /* xSync */
          166  +  apndFileSize,                   /* xFileSize */
          167  +  apndLock,                       /* xLock */
          168  +  apndUnlock,                     /* xUnlock */
          169  +  apndCheckReservedLock,          /* xCheckReservedLock */
          170  +  apndFileControl,                /* xFileControl */
          171  +  apndSectorSize,                 /* xSectorSize */
          172  +  apndDeviceCharacteristics,      /* xDeviceCharacteristics */
          173  +  apndShmMap,                     /* xShmMap */
          174  +  apndShmLock,                    /* xShmLock */
          175  +  apndShmBarrier,                 /* xShmBarrier */
          176  +  apndShmUnmap,                   /* xShmUnmap */
          177  +  apndFetch,                      /* xFetch */
          178  +  apndUnfetch                     /* xUnfetch */
          179  +};
          180  +
          181  +
          182  +
          183  +/*
          184  +** Close an apnd-file.
          185  +*/
          186  +static int apndClose(sqlite3_file *pFile){
          187  +  pFile = ORIGFILE(pFile);
          188  +  return pFile->pMethods->xClose(pFile);
          189  +}
          190  +
          191  +/*
          192  +** Read data from an apnd-file.
          193  +*/
          194  +static int apndRead(
          195  +  sqlite3_file *pFile, 
          196  +  void *zBuf, 
          197  +  int iAmt, 
          198  +  sqlite_int64 iOfst
          199  +){
          200  +  ApndFile *p = (ApndFile *)pFile;
          201  +  pFile = ORIGFILE(pFile);
          202  +  return pFile->pMethods->xRead(pFile, zBuf, iAmt, iOfst+p->iPgOne);
          203  +}
          204  +
          205  +/*
          206  +** Add the append-mark onto the end of the file.
          207  +*/
          208  +static int apndWriteMark(ApndFile *p, sqlite3_file *pFile){
          209  +  int i;
          210  +  unsigned char a[APND_MARK_SIZE];
          211  +  memcpy(a, APND_MARK_PREFIX, APND_MARK_PREFIX_SZ);
          212  +  for(i=0; i<8; i++){
          213  +    a[APND_MARK_PREFIX_SZ+i] = (p->iPgOne >> (56 - i*8)) & 0xff;
          214  +  }
          215  +  return pFile->pMethods->xWrite(pFile, a, APND_MARK_SIZE, p->iMark);
          216  +}
          217  +
          218  +/*
          219  +** Write data to an apnd-file.
          220  +*/
          221  +static int apndWrite(
          222  +  sqlite3_file *pFile,
          223  +  const void *zBuf,
          224  +  int iAmt,
          225  +  sqlite_int64 iOfst
          226  +){
          227  +  int rc;
          228  +  ApndFile *p = (ApndFile *)pFile;
          229  +  pFile = ORIGFILE(pFile);
          230  +  if( iOfst+iAmt>=APND_MAX_SIZE ) return SQLITE_FULL;
          231  +  rc = pFile->pMethods->xWrite(pFile, zBuf, iAmt, iOfst+p->iPgOne);
          232  +  if( rc==SQLITE_OK &&  iOfst + iAmt + p->iPgOne > p->iMark ){
          233  +    sqlite3_int64 sz = 0;
          234  +    rc = pFile->pMethods->xFileSize(pFile, &sz);
          235  +    if( rc==SQLITE_OK ){
          236  +      p->iMark = sz - APND_MARK_SIZE;
          237  +      if( iOfst + iAmt + p->iPgOne > p->iMark ){
          238  +        p->iMark = p->iPgOne + iOfst + iAmt;
          239  +        rc = apndWriteMark(p, pFile);
          240  +      }
          241  +    }
          242  +  }
          243  +  return rc;
          244  +}
          245  +
          246  +/*
          247  +** Truncate an apnd-file.
          248  +*/
          249  +static int apndTruncate(sqlite3_file *pFile, sqlite_int64 size){
          250  +  int rc;
          251  +  ApndFile *p = (ApndFile *)pFile;
          252  +  pFile = ORIGFILE(pFile);
          253  +  rc = pFile->pMethods->xTruncate(pFile, size+p->iPgOne+APND_MARK_SIZE);
          254  +  if( rc==SQLITE_OK ){
          255  +    p->iMark = p->iPgOne+size;
          256  +    rc = apndWriteMark(p, pFile);
          257  +  }
          258  +  return rc;
          259  +}
          260  +
          261  +/*
          262  +** Sync an apnd-file.
          263  +*/
          264  +static int apndSync(sqlite3_file *pFile, int flags){
          265  +  pFile = ORIGFILE(pFile);
          266  +  return pFile->pMethods->xSync(pFile, flags);
          267  +}
          268  +
          269  +/*
          270  +** Return the current file-size of an apnd-file.
          271  +*/
          272  +static int apndFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){
          273  +  ApndFile *p = (ApndFile *)pFile;
          274  +  int rc;
          275  +  pFile = ORIGFILE(p);
          276  +  rc = pFile->pMethods->xFileSize(pFile, pSize);
          277  +  if( rc==SQLITE_OK && p->iPgOne ){
          278  +    *pSize -= p->iPgOne + APND_MARK_SIZE;
          279  +  }
          280  +  return rc;
          281  +}
          282  +
          283  +/*
          284  +** Lock an apnd-file.
          285  +*/
          286  +static int apndLock(sqlite3_file *pFile, int eLock){
          287  +  pFile = ORIGFILE(pFile);
          288  +  return pFile->pMethods->xLock(pFile, eLock);
          289  +}
          290  +
          291  +/*
          292  +** Unlock an apnd-file.
          293  +*/
          294  +static int apndUnlock(sqlite3_file *pFile, int eLock){
          295  +  pFile = ORIGFILE(pFile);
          296  +  return pFile->pMethods->xUnlock(pFile, eLock);
          297  +}
          298  +
          299  +/*
          300  +** Check if another file-handle holds a RESERVED lock on an apnd-file.
          301  +*/
          302  +static int apndCheckReservedLock(sqlite3_file *pFile, int *pResOut){
          303  +  pFile = ORIGFILE(pFile);
          304  +  return pFile->pMethods->xCheckReservedLock(pFile, pResOut);
          305  +}
          306  +
          307  +/*
          308  +** File control method. For custom operations on an apnd-file.
          309  +*/
          310  +static int apndFileControl(sqlite3_file *pFile, int op, void *pArg){
          311  +  ApndFile *p = (ApndFile *)pFile;
          312  +  int rc;
          313  +  pFile = ORIGFILE(pFile);
          314  +  rc = pFile->pMethods->xFileControl(pFile, op, pArg);
          315  +  if( rc==SQLITE_OK && op==SQLITE_FCNTL_VFSNAME ){
          316  +    *(char**)pArg = sqlite3_mprintf("apnd(%lld)/%z", p->iPgOne, *(char**)pArg);
          317  +  }
          318  +  return rc;
          319  +}
          320  +
          321  +/*
          322  +** Return the sector-size in bytes for an apnd-file.
          323  +*/
          324  +static int apndSectorSize(sqlite3_file *pFile){
          325  +  pFile = ORIGFILE(pFile);
          326  +  return pFile->pMethods->xSectorSize(pFile);
          327  +}
          328  +
          329  +/*
          330  +** Return the device characteristic flags supported by an apnd-file.
          331  +*/
          332  +static int apndDeviceCharacteristics(sqlite3_file *pFile){
          333  +  pFile = ORIGFILE(pFile);
          334  +  return pFile->pMethods->xDeviceCharacteristics(pFile);
          335  +}
          336  +
          337  +/* Create a shared memory file mapping */
          338  +static int apndShmMap(
          339  +  sqlite3_file *pFile,
          340  +  int iPg,
          341  +  int pgsz,
          342  +  int bExtend,
          343  +  void volatile **pp
          344  +){
          345  +  pFile = ORIGFILE(pFile);
          346  +  return pFile->pMethods->xShmMap(pFile,iPg,pgsz,bExtend,pp);
          347  +}
          348  +
          349  +/* Perform locking on a shared-memory segment */
          350  +static int apndShmLock(sqlite3_file *pFile, int offset, int n, int flags){
          351  +  pFile = ORIGFILE(pFile);
          352  +  return pFile->pMethods->xShmLock(pFile,offset,n,flags);
          353  +}
          354  +
          355  +/* Memory barrier operation on shared memory */
          356  +static void apndShmBarrier(sqlite3_file *pFile){
          357  +  pFile = ORIGFILE(pFile);
          358  +  pFile->pMethods->xShmBarrier(pFile);
          359  +}
          360  +
          361  +/* Unmap a shared memory segment */
          362  +static int apndShmUnmap(sqlite3_file *pFile, int deleteFlag){
          363  +  pFile = ORIGFILE(pFile);
          364  +  return pFile->pMethods->xShmUnmap(pFile,deleteFlag);
          365  +}
          366  +
          367  +/* Fetch a page of a memory-mapped file */
          368  +static int apndFetch(
          369  +  sqlite3_file *pFile,
          370  +  sqlite3_int64 iOfst,
          371  +  int iAmt,
          372  +  void **pp
          373  +){
          374  +  ApndFile *p = (ApndFile *)pFile;
          375  +  pFile = ORIGFILE(pFile);
          376  +  return pFile->pMethods->xFetch(pFile, iOfst+p->iPgOne, iAmt, pp);
          377  +}
          378  +
          379  +/* Release a memory-mapped page */
          380  +static int apndUnfetch(sqlite3_file *pFile, sqlite3_int64 iOfst, void *pPage){
          381  +  ApndFile *p = (ApndFile *)pFile;
          382  +  pFile = ORIGFILE(pFile);
          383  +  return pFile->pMethods->xUnfetch(pFile, iOfst+p->iPgOne, pPage);
          384  +}
          385  +
          386  +/*
          387  +** Check to see if the file is an ordinary SQLite database file.
          388  +*/
          389  +static int apndIsOrdinaryDatabaseFile(sqlite3_int64 sz, sqlite3_file *pFile){
          390  +  int rc;
          391  +  char zHdr[16];
          392  +  static const char aSqliteHdr[] = "SQLite format 3";
          393  +  if( sz<512 ) return 0;
          394  +  rc = pFile->pMethods->xRead(pFile, zHdr, sizeof(zHdr), 0);
          395  +  if( rc ) return 0;
          396  +  return memcmp(zHdr, aSqliteHdr, sizeof(zHdr))==0;
          397  +}
          398  +
          399  +/*
          400  +** Try to read the append-mark off the end of a file.  Return the
          401  +** start of the appended database if the append-mark is present.  If
          402  +** there is no append-mark, return -1;
          403  +*/
          404  +static sqlite3_int64 apndReadMark(sqlite3_int64 sz, sqlite3_file *pFile){
          405  +  int rc, i;
          406  +  sqlite3_int64 iMark;
          407  +  unsigned char a[APND_MARK_SIZE];
          408  +
          409  +  if( sz<=APND_MARK_SIZE ) return -1;
          410  +  rc = pFile->pMethods->xRead(pFile, a, APND_MARK_SIZE, sz-APND_MARK_SIZE);
          411  +  if( rc ) return -1;
          412  +  if( memcmp(a, APND_MARK_PREFIX, APND_MARK_PREFIX_SZ)!=0 ) return -1;
          413  +  iMark = ((sqlite3_int64)(a[APND_MARK_PREFIX_SZ]&0x7f))<<56;
          414  +  for(i=1; i<8; i++){    
          415  +    iMark += (sqlite3_int64)a[APND_MARK_PREFIX_SZ+i]<<(56-8*i);
          416  +  }
          417  +  return iMark;
          418  +}
          419  +
          420  +/*
          421  +** Open an apnd file handle.
          422  +*/
          423  +static int apndOpen(
          424  +  sqlite3_vfs *pVfs,
          425  +  const char *zName,
          426  +  sqlite3_file *pFile,
          427  +  int flags,
          428  +  int *pOutFlags
          429  +){
          430  +  ApndFile *p;
          431  +  sqlite3_file *pSubFile;
          432  +  sqlite3_vfs *pSubVfs;
          433  +  int rc;
          434  +  sqlite3_int64 sz;
          435  +  pSubVfs = ORIGVFS(pVfs);
          436  +  if( (flags & SQLITE_OPEN_MAIN_DB)==0 ){
          437  +    return pSubVfs->xOpen(pSubVfs, zName, pFile, flags, pOutFlags);
          438  +  }
          439  +  p = (ApndFile*)pFile;
          440  +  memset(p, 0, sizeof(*p));
          441  +  pSubFile = ORIGFILE(pFile);
          442  +  p->base.pMethods = &apnd_io_methods;
          443  +  rc = pSubVfs->xOpen(pSubVfs, zName, pSubFile, flags, pOutFlags);
          444  +  if( rc ) goto apnd_open_done;
          445  +  rc = pSubFile->pMethods->xFileSize(pSubFile, &sz);
          446  +  if( rc ){
          447  +    pSubFile->pMethods->xClose(pSubFile);
          448  +    goto apnd_open_done;
          449  +  }
          450  +  if( apndIsOrdinaryDatabaseFile(sz, pSubFile) ){
          451  +    memmove(pFile, pSubFile, pSubVfs->szOsFile);
          452  +    return SQLITE_OK;
          453  +  }
          454  +  p->iMark = 0;
          455  +  p->iPgOne = apndReadMark(sz, pFile);
          456  +  if( p->iPgOne>0 ){
          457  +    return SQLITE_OK;
          458  +  }
          459  +  if( (flags & SQLITE_OPEN_CREATE)==0 ){
          460  +    pSubFile->pMethods->xClose(pSubFile);
          461  +    rc = SQLITE_CANTOPEN;
          462  +  }
          463  +  p->iPgOne = (sz+0xfff) & ~(sqlite3_int64)0xfff;
          464  +apnd_open_done:
          465  +  if( rc ) pFile->pMethods = 0;
          466  +  return rc;
          467  +}
          468  +
          469  +/*
          470  +** All other VFS methods are pass-thrus.
          471  +*/
          472  +static int apndDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
          473  +  return ORIGVFS(pVfs)->xDelete(ORIGVFS(pVfs), zPath, dirSync);
          474  +}
          475  +static int apndAccess(
          476  +  sqlite3_vfs *pVfs, 
          477  +  const char *zPath, 
          478  +  int flags, 
          479  +  int *pResOut
          480  +){
          481  +  return ORIGVFS(pVfs)->xAccess(ORIGVFS(pVfs), zPath, flags, pResOut);
          482  +}
          483  +static int apndFullPathname(
          484  +  sqlite3_vfs *pVfs, 
          485  +  const char *zPath, 
          486  +  int nOut, 
          487  +  char *zOut
          488  +){
          489  +  return ORIGVFS(pVfs)->xFullPathname(ORIGVFS(pVfs),zPath,nOut,zOut);
          490  +}
          491  +static void *apndDlOpen(sqlite3_vfs *pVfs, const char *zPath){
          492  +  return ORIGVFS(pVfs)->xDlOpen(ORIGVFS(pVfs), zPath);
          493  +}
          494  +static void apndDlError(sqlite3_vfs *pVfs, int nByte, char *zErrMsg){
          495  +  ORIGVFS(pVfs)->xDlError(ORIGVFS(pVfs), nByte, zErrMsg);
          496  +}
          497  +static void (*apndDlSym(sqlite3_vfs *pVfs, void *p, const char *zSym))(void){
          498  +  return ORIGVFS(pVfs)->xDlSym(ORIGVFS(pVfs), p, zSym);
          499  +}
          500  +static void apndDlClose(sqlite3_vfs *pVfs, void *pHandle){
          501  +  ORIGVFS(pVfs)->xDlClose(ORIGVFS(pVfs), pHandle);
          502  +}
          503  +static int apndRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
          504  +  return ORIGVFS(pVfs)->xRandomness(ORIGVFS(pVfs), nByte, zBufOut);
          505  +}
          506  +static int apndSleep(sqlite3_vfs *pVfs, int nMicro){
          507  +  return ORIGVFS(pVfs)->xSleep(ORIGVFS(pVfs), nMicro);
          508  +}
          509  +static int apndCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){
          510  +  return ORIGVFS(pVfs)->xCurrentTime(ORIGVFS(pVfs), pTimeOut);
          511  +}
          512  +static int apndGetLastError(sqlite3_vfs *pVfs, int a, char *b){
          513  +  return ORIGVFS(pVfs)->xGetLastError(ORIGVFS(pVfs), a, b);
          514  +}
          515  +static int apndCurrentTimeInt64(sqlite3_vfs *pVfs, sqlite3_int64 *p){
          516  +  return ORIGVFS(pVfs)->xCurrentTimeInt64(ORIGVFS(pVfs), p);
          517  +}
          518  +static int apndSetSystemCall(
          519  +  sqlite3_vfs *pVfs,
          520  +  const char *zName,
          521  +  sqlite3_syscall_ptr pCall
          522  +){
          523  +  return ORIGVFS(pVfs)->xSetSystemCall(ORIGVFS(pVfs),zName,pCall);
          524  +}
          525  +static sqlite3_syscall_ptr apndGetSystemCall(
          526  +  sqlite3_vfs *pVfs,
          527  +  const char *zName
          528  +){
          529  +  return ORIGVFS(pVfs)->xGetSystemCall(ORIGVFS(pVfs),zName);
          530  +}
          531  +static const char *apndNextSystemCall(sqlite3_vfs *pVfs, const char *zName){
          532  +  return ORIGVFS(pVfs)->xNextSystemCall(ORIGVFS(pVfs), zName);
          533  +}
          534  +
          535  +  
          536  +#ifdef _WIN32
          537  +__declspec(dllexport)
          538  +#endif
          539  +/* 
          540  +** This routine is called when the extension is loaded.
          541  +** Register the new VFS.
          542  +*/
          543  +int sqlite3_appendvfs_init(
          544  +  sqlite3 *db, 
          545  +  char **pzErrMsg, 
          546  +  const sqlite3_api_routines *pApi
          547  +){
          548  +  int rc = SQLITE_OK;
          549  +  sqlite3_vfs *pOrig;
          550  +  SQLITE_EXTENSION_INIT2(pApi);
          551  +  (void)pzErrMsg;
          552  +  (void)db;
          553  +  pOrig = sqlite3_vfs_find(0);
          554  +  apnd_vfs.iVersion = pOrig->iVersion;
          555  +  apnd_vfs.pAppData = pOrig;
          556  +  apnd_vfs.szOsFile = pOrig->szOsFile + sizeof(ApndFile);
          557  +  rc = sqlite3_vfs_register(&apnd_vfs, 0);
          558  +#ifdef APPENDVFS_TEST
          559  +  if( rc==SQLITE_OK ){
          560  +    rc = sqlite3_auto_extension((void(*)(void))apndvfsRegister);
          561  +  }
          562  +#endif
          563  +  if( rc==SQLITE_OK ) rc = SQLITE_OK_LOAD_PERMANENTLY;
          564  +  return rc;
          565  +}

Changes to ext/misc/btreeinfo.c.

   335    335   ){
   336    336     BinfoCursor *pCsr = (BinfoCursor *)pCursor;
   337    337     if( i>=BINFO_COLUMN_HASROWID && i<=BINFO_COLUMN_SZPAGE && pCsr->hasRowid<0 ){
   338    338       int pgno = sqlite3_column_int(pCsr->pStmt, BINFO_COLUMN_ROOTPAGE+1);
   339    339       sqlite3 *db = sqlite3_context_db_handle(ctx);
   340    340       int rc = binfoCompute(db, pgno, pCsr);
   341    341       if( rc ){
   342         -      return rc;
          342  +      pCursor->pVtab->zErrMsg = sqlite3_mprintf("%s", sqlite3_errmsg(db));
          343  +      return SQLITE_ERROR;
   343    344       }
   344    345     }
   345    346     switch( i ){
   346    347       case BINFO_COLUMN_NAME:
   347    348       case BINFO_COLUMN_TYPE:
   348    349       case BINFO_COLUMN_TBL_NAME:
   349    350       case BINFO_COLUMN_ROOTPAGE:

Changes to ext/misc/compress.c.

    23     23   **
    24     24   ** The output is a BLOB that begins with a variable-length integer that
    25     25   ** is the input size in bytes (the size of X before compression).  The
    26     26   ** variable-length integer is implemented as 1 to 5 bytes.  There are
    27     27   ** seven bits per integer stored in the lower seven bits of each byte.
    28     28   ** More significant bits occur first.  The most significant bit (0x80)
    29     29   ** is a flag to indicate the end of the integer.
           30  +**
           31  +** This function, SQLAR, and ZIP all use the same "deflate" compression
           32  +** algorithm, but each is subtly different:
           33  +**
           34  +**   *  ZIP uses raw deflate.
           35  +**
           36  +**   *  SQLAR uses the "zlib format" which is raw deflate with a two-byte
           37  +**      algorithm-identification header and a four-byte checksum at the end.
           38  +**
           39  +**   *  This utility uses the "zlib format" like SQLAR, but adds the variable-
           40  +**      length integer uncompressed size value at the beginning.
           41  +**
           42  +** This function might be extended in the future to support compression
           43  +** formats other than deflate, by providing a different algorithm-id
           44  +** mark following the variable-length integer size parameter.
    30     45   */
    31     46   static void compressFunc(
    32     47     sqlite3_context *context,
    33     48     int argc,
    34     49     sqlite3_value **argv
    35     50   ){
    36     51     const unsigned char *pIn;

Changes to ext/misc/fileio.c.

     7      7   **    May you do good and not evil.
     8      8   **    May you find forgiveness for yourself and forgive others.
     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   ******************************************************************************
    12     12   **
    13     13   ** This SQLite extension implements SQL functions readfile() and
    14         -** writefile().
           14  +** writefile(), and eponymous virtual type "fsdir".
           15  +**
           16  +** WRITEFILE(FILE, DATA [, MODE [, MTIME]]):
           17  +**
           18  +**   If neither of the optional arguments is present, then this UDF
           19  +**   function writes blob DATA to file FILE. If successful, the number
           20  +**   of bytes written is returned. If an error occurs, NULL is returned.
           21  +**
           22  +**   If the first option argument - MODE - is present, then it must
           23  +**   be passed an integer value that corresponds to a POSIX mode
           24  +**   value (file type + permissions, as returned in the stat.st_mode
           25  +**   field by the stat() system call). Three types of files may
           26  +**   be written/created:
           27  +**
           28  +**     regular files:  (mode & 0170000)==0100000
           29  +**     symbolic links: (mode & 0170000)==0120000
           30  +**     directories:    (mode & 0170000)==0040000
           31  +**
           32  +**   For a directory, the DATA is ignored. For a symbolic link, it is
           33  +**   interpreted as text and used as the target of the link. For a
           34  +**   regular file, it is interpreted as a blob and written into the
           35  +**   named file. Regardless of the type of file, its permissions are
           36  +**   set to (mode & 0777) before returning.
           37  +**
           38  +**   If the optional MTIME argument is present, then it is interpreted
           39  +**   as an integer - the number of seconds since the unix epoch. The
           40  +**   modification-time of the target file is set to this value before
           41  +**   returning.
           42  +**
           43  +**   If three or more arguments are passed to this function and an
           44  +**   error is encountered, an exception is raised.
           45  +**
           46  +** READFILE(FILE):
           47  +**
           48  +**   Read and return the contents of file FILE (type blob) from disk.
           49  +**
           50  +** FSDIR:
           51  +**
           52  +**   Used as follows:
           53  +**
           54  +**     SELECT * FROM fsdir($path [, $dir]);
           55  +**
           56  +**   Parameter $path is an absolute or relative pathname. If the file that it
           57  +**   refers to does not exist, it is an error. If the path refers to a regular
           58  +**   file or symbolic link, it returns a single row. Or, if the path refers
           59  +**   to a directory, it returns one row for the directory, and one row for each
           60  +**   file within the hierarchy rooted at $path.
           61  +**
           62  +**   Each row has the following columns:
           63  +**
           64  +**     name:  Path to file or directory (text value).
           65  +**     mode:  Value of stat.st_mode for directory entry (an integer).
           66  +**     mtime: Value of stat.st_mtime for directory entry (an integer).
           67  +**     data:  For a regular file, a blob containing the file data. For a
           68  +**            symlink, a text value containing the text of the link. For a
           69  +**            directory, NULL.
           70  +**
           71  +**   If a non-NULL value is specified for the optional $dir parameter and
           72  +**   $path is a relative path, then $path is interpreted relative to $dir. 
           73  +**   And the paths returned in the "name" column of the table are also 
           74  +**   relative to directory $dir.
    15     75   */
    16     76   #include "sqlite3ext.h"
    17     77   SQLITE_EXTENSION_INIT1
    18     78   #include <stdio.h>
           79  +#include <string.h>
           80  +#include <assert.h>
           81  +
           82  +#include <sys/types.h>
           83  +#include <sys/stat.h>
           84  +#include <fcntl.h>
           85  +#if !defined(_WIN32) && !defined(WIN32)
           86  +#  include <unistd.h>
           87  +#  include <dirent.h>
           88  +#  include <utime.h>
           89  +#  include <sys/time.h>
           90  +#else
           91  +#  include "windows.h"
           92  +#  include <io.h>
           93  +#  include <direct.h>
           94  +#  include "test_windirent.h"
           95  +#  define dirent DIRENT
           96  +#  ifndef stat
           97  +#    define stat _stat
           98  +#  endif
           99  +#  define mkdir(path,mode) _mkdir(path)
          100  +#  define lstat(path,buf) stat(path,buf)
          101  +#endif
          102  +#include <time.h>
          103  +#include <errno.h>
          104  +
          105  +
          106  +#define FSDIR_SCHEMA "(name,mode,mtime,data,path HIDDEN,dir HIDDEN)"
          107  +
          108  +/*
          109  +** Set the result stored by context ctx to a blob containing the 
          110  +** contents of file zName.
          111  +*/
          112  +static void readFileContents(sqlite3_context *ctx, const char *zName){
          113  +  FILE *in;
          114  +  long nIn;
          115  +  void *pBuf;
          116  +
          117  +  in = fopen(zName, "rb");
          118  +  if( in==0 ) return;
          119  +  fseek(in, 0, SEEK_END);
          120  +  nIn = ftell(in);
          121  +  rewind(in);
          122  +  pBuf = sqlite3_malloc( nIn );
          123  +  if( pBuf && 1==fread(pBuf, nIn, 1, in) ){
          124  +    sqlite3_result_blob(ctx, pBuf, nIn, sqlite3_free);
          125  +  }else{
          126  +    sqlite3_free(pBuf);
          127  +  }
          128  +  fclose(in);
          129  +}
    19    130   
    20    131   /*
    21    132   ** Implementation of the "readfile(X)" SQL function.  The entire content
    22    133   ** of the file named X is read and returned as a BLOB.  NULL is returned
    23    134   ** if the file does not exist or is unreadable.
    24    135   */
    25    136   static void readfileFunc(
    26    137     sqlite3_context *context,
    27    138     int argc,
    28    139     sqlite3_value **argv
    29    140   ){
    30    141     const char *zName;
    31         -  FILE *in;
    32         -  long nIn;
    33         -  void *pBuf;
    34         -
    35    142     (void)(argc);  /* Unused parameter */
    36    143     zName = (const char*)sqlite3_value_text(argv[0]);
    37    144     if( zName==0 ) return;
    38         -  in = fopen(zName, "rb");
    39         -  if( in==0 ) return;
    40         -  fseek(in, 0, SEEK_END);
    41         -  nIn = ftell(in);
    42         -  rewind(in);
    43         -  pBuf = sqlite3_malloc( nIn );
    44         -  if( pBuf && 1==fread(pBuf, nIn, 1, in) ){
    45         -    sqlite3_result_blob(context, pBuf, nIn, sqlite3_free);
          145  +  readFileContents(context, zName);
          146  +}
          147  +
          148  +/*
          149  +** Set the error message contained in context ctx to the results of
          150  +** vprintf(zFmt, ...).
          151  +*/
          152  +static void ctxErrorMsg(sqlite3_context *ctx, const char *zFmt, ...){
          153  +  char *zMsg = 0;
          154  +  va_list ap;
          155  +  va_start(ap, zFmt);
          156  +  zMsg = sqlite3_vmprintf(zFmt, ap);
          157  +  sqlite3_result_error(ctx, zMsg, -1);
          158  +  sqlite3_free(zMsg);
          159  +  va_end(ap);
          160  +}
          161  +
          162  +/*
          163  +** Argument zFile is the name of a file that will be created and/or written
          164  +** by SQL function writefile(). This function ensures that the directory
          165  +** zFile will be written to exists, creating it if required. The permissions
          166  +** for any path components created by this function are set to (mode&0777).
          167  +**
          168  +** If an OOM condition is encountered, SQLITE_NOMEM is returned. Otherwise,
          169  +** SQLITE_OK is returned if the directory is successfully created, or
          170  +** SQLITE_ERROR otherwise.
          171  +*/
          172  +static int makeDirectory(
          173  +  const char *zFile,
          174  +  mode_t mode
          175  +){
          176  +  char *zCopy = sqlite3_mprintf("%s", zFile);
          177  +  int rc = SQLITE_OK;
          178  +
          179  +  if( zCopy==0 ){
          180  +    rc = SQLITE_NOMEM;
    46    181     }else{
    47         -    sqlite3_free(pBuf);
    48         -  }
    49         -  fclose(in);
    50         -}
    51         -
    52         -/*
    53         -** Implementation of the "writefile(X,Y)" SQL function.  The argument Y
    54         -** is written into file X.  The number of bytes written is returned.  Or
    55         -** NULL is returned if something goes wrong, such as being unable to open
    56         -** file X for writing.
          182  +    int nCopy = (int)strlen(zCopy);
          183  +    int i = 1;
          184  +
          185  +    while( rc==SQLITE_OK ){
          186  +      struct stat sStat;
          187  +      int rc2;
          188  +
          189  +      for(; zCopy[i]!='/' && i<nCopy; i++);
          190  +      if( i==nCopy ) break;
          191  +      zCopy[i] = '\0';
          192  +
          193  +      rc2 = stat(zCopy, &sStat);
          194  +      if( rc2!=0 ){
          195  +        if( mkdir(zCopy, mode & 0777) ) rc = SQLITE_ERROR;
          196  +      }else{
          197  +        if( !S_ISDIR(sStat.st_mode) ) rc = SQLITE_ERROR;
          198  +      }
          199  +      zCopy[i] = '/';
          200  +      i++;
          201  +    }
          202  +
          203  +    sqlite3_free(zCopy);
          204  +  }
          205  +
          206  +  return rc;
          207  +}
          208  +
          209  +/*
          210  +** This function does the work for the writefile() UDF. Refer to 
          211  +** header comments at the top of this file for details.
          212  +*/
          213  +static int writeFile(
          214  +  sqlite3_context *pCtx,          /* Context to return bytes written in */
          215  +  const char *zFile,              /* File to write */
          216  +  sqlite3_value *pData,           /* Data to write */
          217  +  mode_t mode,                    /* MODE parameter passed to writefile() */
          218  +  sqlite3_int64 mtime             /* MTIME parameter (or -1 to not set time) */
          219  +){
          220  +#if !defined(_WIN32) && !defined(WIN32)
          221  +  if( S_ISLNK(mode) ){
          222  +    const char *zTo = (const char*)sqlite3_value_text(pData);
          223  +    if( symlink(zTo, zFile)<0 ) return 1;
          224  +  }else
          225  +#endif
          226  +  {
          227  +    if( S_ISDIR(mode) ){
          228  +      if( mkdir(zFile, mode) ){
          229  +        /* The mkdir() call to create the directory failed. This might not
          230  +        ** be an error though - if there is already a directory at the same
          231  +        ** path and either the permissions already match or can be changed
          232  +        ** to do so using chmod(), it is not an error.  */
          233  +        struct stat sStat;
          234  +        if( errno!=EEXIST
          235  +         || 0!=stat(zFile, &sStat)
          236  +         || !S_ISDIR(sStat.st_mode)
          237  +         || ((sStat.st_mode&0777)!=(mode&0777) && 0!=chmod(zFile, mode&0777))
          238  +        ){
          239  +          return 1;
          240  +        }
          241  +      }
          242  +    }else{
          243  +      sqlite3_int64 nWrite = 0;
          244  +      const char *z;
          245  +      int rc = 0;
          246  +      FILE *out = fopen(zFile, "wb");
          247  +      if( out==0 ) return 1;
          248  +      z = (const char*)sqlite3_value_blob(pData);
          249  +      if( z ){
          250  +        sqlite3_int64 n = fwrite(z, 1, sqlite3_value_bytes(pData), out);
          251  +        nWrite = sqlite3_value_bytes(pData);
          252  +        if( nWrite!=n ){
          253  +          rc = 1;
          254  +        }
          255  +      }
          256  +      fclose(out);
          257  +      if( rc==0 && mode && chmod(zFile, mode & 0777) ){
          258  +        rc = 1;
          259  +      }
          260  +      if( rc ) return 2;
          261  +      sqlite3_result_int64(pCtx, nWrite);
          262  +    }
          263  +  }
          264  +
          265  +  if( mtime>=0 ){
          266  +#if defined(_WIN32)
          267  +    /* Windows */
          268  +    FILETIME lastAccess;
          269  +    FILETIME lastWrite;
          270  +    SYSTEMTIME currentTime;
          271  +    LONGLONG intervals;
          272  +    HANDLE hFile;
          273  +    LPWSTR zUnicodeName;
          274  +    extern LPWSTR sqlite3_win32_utf8_to_unicode(const char*);
          275  +
          276  +    GetSystemTime(&currentTime);
          277  +    SystemTimeToFileTime(&currentTime, &lastAccess);
          278  +    intervals = Int32x32To64(mtime, 10000000) + 116444736000000000;
          279  +    lastWrite.dwLowDateTime = (DWORD)intervals;
          280  +    lastWrite.dwHighDateTime = intervals >> 32;
          281  +    zUnicodeName = sqlite3_win32_utf8_to_unicode(zFile);
          282  +    hFile = CreateFileW(
          283  +      zUnicodeName, FILE_WRITE_ATTRIBUTES, 0, NULL, OPEN_EXISTING,
          284  +      FILE_FLAG_BACKUP_SEMANTICS, NULL
          285  +    );
          286  +    sqlite3_free(zUnicodeName);
          287  +    if( hFile!=INVALID_HANDLE_VALUE ){
          288  +      BOOL bResult = SetFileTime(hFile, NULL, &lastAccess, &lastWrite);
          289  +      CloseHandle(hFile);
          290  +      return !bResult;
          291  +    }else{
          292  +      return 1;
          293  +    }
          294  +#elif defined(AT_FDCWD) && 0 /* utimensat() is not univerally available */
          295  +    /* Recent unix */
          296  +    struct timespec times[2];
          297  +    times[0].tv_nsec = times[1].tv_nsec = 0;
          298  +    times[0].tv_sec = time(0);
          299  +    times[1].tv_sec = mtime;
          300  +    if( utimensat(AT_FDCWD, zFile, times, AT_SYMLINK_NOFOLLOW) ){
          301  +      return 1;
          302  +    }
          303  +#else
          304  +    /* Legacy unix */
          305  +    struct timeval times[2];
          306  +    times[0].tv_usec = times[1].tv_usec = 0;
          307  +    times[0].tv_sec = time(0);
          308  +    times[1].tv_sec = mtime;
          309  +    if( utimes(zFile, times) ){
          310  +      return 1;
          311  +    }
          312  +#endif
          313  +  }
          314  +
          315  +  return 0;
          316  +}
          317  +
          318  +/*
          319  +** Implementation of the "writefile(W,X[,Y[,Z]]])" SQL function.  
          320  +** Refer to header comments at the top of this file for details.
    57    321   */
    58    322   static void writefileFunc(
    59    323     sqlite3_context *context,
    60    324     int argc,
    61    325     sqlite3_value **argv
    62    326   ){
    63         -  FILE *out;
    64         -  const char *z;
    65         -  sqlite3_int64 rc;
    66    327     const char *zFile;
          328  +  mode_t mode = 0;
          329  +  int res;
          330  +  sqlite3_int64 mtime = -1;
    67    331   
    68         -  (void)(argc);  /* Unused parameter */
          332  +  if( argc<2 || argc>4 ){
          333  +    sqlite3_result_error(context, 
          334  +        "wrong number of arguments to function writefile()", -1
          335  +    );
          336  +    return;
          337  +  }
          338  +
    69    339     zFile = (const char*)sqlite3_value_text(argv[0]);
    70    340     if( zFile==0 ) return;
    71         -  out = fopen(zFile, "wb");
    72         -  if( out==0 ) return;
    73         -  z = (const char*)sqlite3_value_blob(argv[1]);
    74         -  if( z==0 ){
    75         -    rc = 0;
          341  +  if( argc>=3 ){
          342  +    mode = (mode_t)sqlite3_value_int(argv[2]);
          343  +  }
          344  +  if( argc==4 ){
          345  +    mtime = sqlite3_value_int64(argv[3]);
          346  +  }
          347  +
          348  +  res = writeFile(context, zFile, argv[1], mode, mtime);
          349  +  if( res==1 && errno==ENOENT ){
          350  +    if( makeDirectory(zFile, mode)==SQLITE_OK ){
          351  +      res = writeFile(context, zFile, argv[1], mode, mtime);
          352  +    }
          353  +  }
          354  +
          355  +  if( argc>2 && res!=0 ){
          356  +    if( S_ISLNK(mode) ){
          357  +      ctxErrorMsg(context, "failed to create symlink: %s", zFile);
          358  +    }else if( S_ISDIR(mode) ){
          359  +      ctxErrorMsg(context, "failed to create directory: %s", zFile);
          360  +    }else{
          361  +      ctxErrorMsg(context, "failed to write file: %s", zFile);
          362  +    }
          363  +  }
          364  +}
          365  +
          366  +/*
          367  +** SQL function:   lsmode(MODE)
          368  +**
          369  +** Given a numberic st_mode from stat(), convert it into a human-readable
          370  +** text string in the style of "ls -l".
          371  +*/
          372  +static void lsModeFunc(
          373  +  sqlite3_context *context,
          374  +  int argc,
          375  +  sqlite3_value **argv
          376  +){
          377  +  int i;
          378  +  int iMode = sqlite3_value_int(argv[0]);
          379  +  char z[16];
          380  +  (void)argc;
          381  +  if( S_ISLNK(iMode) ){
          382  +    z[0] = 'l';
          383  +  }else if( S_ISREG(iMode) ){
          384  +    z[0] = '-';
          385  +  }else if( S_ISDIR(iMode) ){
          386  +    z[0] = 'd';
          387  +  }else{
          388  +    z[0] = '?';
          389  +  }
          390  +  for(i=0; i<3; i++){
          391  +    int m = (iMode >> ((2-i)*3));
          392  +    char *a = &z[1 + i*3];
          393  +    a[0] = (m & 0x4) ? 'r' : '-';
          394  +    a[1] = (m & 0x2) ? 'w' : '-';
          395  +    a[2] = (m & 0x1) ? 'x' : '-';
          396  +  }
          397  +  z[10] = '\0';
          398  +  sqlite3_result_text(context, z, -1, SQLITE_TRANSIENT);
          399  +}
          400  +
          401  +#ifndef SQLITE_OMIT_VIRTUALTABLE
          402  +
          403  +/* 
          404  +** Cursor type for recursively iterating through a directory structure.
          405  +*/
          406  +typedef struct fsdir_cursor fsdir_cursor;
          407  +typedef struct FsdirLevel FsdirLevel;
          408  +
          409  +struct FsdirLevel {
          410  +  DIR *pDir;                 /* From opendir() */
          411  +  char *zDir;                /* Name of directory (nul-terminated) */
          412  +};
          413  +
          414  +struct fsdir_cursor {
          415  +  sqlite3_vtab_cursor base;  /* Base class - must be first */
          416  +
          417  +  int nLvl;                  /* Number of entries in aLvl[] array */
          418  +  int iLvl;                  /* Index of current entry */
          419  +  FsdirLevel *aLvl;          /* Hierarchy of directories being traversed */
          420  +
          421  +  const char *zBase;
          422  +  int nBase;
          423  +
          424  +  struct stat sStat;         /* Current lstat() results */
          425  +  char *zPath;               /* Path to current entry */
          426  +  sqlite3_int64 iRowid;      /* Current rowid */
          427  +};
          428  +
          429  +typedef struct fsdir_tab fsdir_tab;
          430  +struct fsdir_tab {
          431  +  sqlite3_vtab base;         /* Base class - must be first */
          432  +};
          433  +
          434  +/*
          435  +** Construct a new fsdir virtual table object.
          436  +*/
          437  +static int fsdirConnect(
          438  +  sqlite3 *db,
          439  +  void *pAux,
          440  +  int argc, const char *const*argv,
          441  +  sqlite3_vtab **ppVtab,
          442  +  char **pzErr
          443  +){
          444  +  fsdir_tab *pNew = 0;
          445  +  int rc;
          446  +  (void)pAux;
          447  +  (void)argc;
          448  +  (void)argv;
          449  +  (void)pzErr;
          450  +  rc = sqlite3_declare_vtab(db, "CREATE TABLE x" FSDIR_SCHEMA);
          451  +  if( rc==SQLITE_OK ){
          452  +    pNew = (fsdir_tab*)sqlite3_malloc( sizeof(*pNew) );
          453  +    if( pNew==0 ) return SQLITE_NOMEM;
          454  +    memset(pNew, 0, sizeof(*pNew));
          455  +  }
          456  +  *ppVtab = (sqlite3_vtab*)pNew;
          457  +  return rc;
          458  +}
          459  +
          460  +/*
          461  +** This method is the destructor for fsdir vtab objects.
          462  +*/
          463  +static int fsdirDisconnect(sqlite3_vtab *pVtab){
          464  +  sqlite3_free(pVtab);
          465  +  return SQLITE_OK;
          466  +}
          467  +
          468  +/*
          469  +** Constructor for a new fsdir_cursor object.
          470  +*/
          471  +static int fsdirOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
          472  +  fsdir_cursor *pCur;
          473  +  (void)p;
          474  +  pCur = sqlite3_malloc( sizeof(*pCur) );
          475  +  if( pCur==0 ) return SQLITE_NOMEM;
          476  +  memset(pCur, 0, sizeof(*pCur));
          477  +  pCur->iLvl = -1;
          478  +  *ppCursor = &pCur->base;
          479  +  return SQLITE_OK;
          480  +}
          481  +
          482  +/*
          483  +** Reset a cursor back to the state it was in when first returned
          484  +** by fsdirOpen().
          485  +*/
          486  +static void fsdirResetCursor(fsdir_cursor *pCur){
          487  +  int i;
          488  +  for(i=0; i<=pCur->iLvl; i++){
          489  +    FsdirLevel *pLvl = &pCur->aLvl[i];
          490  +    if( pLvl->pDir ) closedir(pLvl->pDir);
          491  +    sqlite3_free(pLvl->zDir);
          492  +  }
          493  +  sqlite3_free(pCur->zPath);
          494  +  pCur->aLvl = 0;
          495  +  pCur->zPath = 0;
          496  +  pCur->zBase = 0;
          497  +  pCur->nBase = 0;
          498  +  pCur->iLvl = -1;
          499  +  pCur->iRowid = 1;
          500  +}
          501  +
          502  +/*
          503  +** Destructor for an fsdir_cursor.
          504  +*/
          505  +static int fsdirClose(sqlite3_vtab_cursor *cur){
          506  +  fsdir_cursor *pCur = (fsdir_cursor*)cur;
          507  +
          508  +  fsdirResetCursor(pCur);
          509  +  sqlite3_free(pCur->aLvl);
          510  +  sqlite3_free(pCur);
          511  +  return SQLITE_OK;
          512  +}
          513  +
          514  +/*
          515  +** Set the error message for the virtual table associated with cursor
          516  +** pCur to the results of vprintf(zFmt, ...).
          517  +*/
          518  +static void fsdirSetErrmsg(fsdir_cursor *pCur, const char *zFmt, ...){
          519  +  va_list ap;
          520  +  va_start(ap, zFmt);
          521  +  pCur->base.pVtab->zErrMsg = sqlite3_vmprintf(zFmt, ap);
          522  +  va_end(ap);
          523  +}
          524  +
          525  +
          526  +/*
          527  +** Advance an fsdir_cursor to its next row of output.
          528  +*/
          529  +static int fsdirNext(sqlite3_vtab_cursor *cur){
          530  +  fsdir_cursor *pCur = (fsdir_cursor*)cur;
          531  +  mode_t m = pCur->sStat.st_mode;
          532  +
          533  +  pCur->iRowid++;
          534  +  if( S_ISDIR(m) ){
          535  +    /* Descend into this directory */
          536  +    int iNew = pCur->iLvl + 1;
          537  +    FsdirLevel *pLvl;
          538  +    if( iNew>=pCur->nLvl ){
          539  +      int nNew = iNew+1;
          540  +      int nByte = nNew*sizeof(FsdirLevel);
          541  +      FsdirLevel *aNew = (FsdirLevel*)sqlite3_realloc(pCur->aLvl, nByte);
          542  +      if( aNew==0 ) return SQLITE_NOMEM;
          543  +      memset(&aNew[pCur->nLvl], 0, sizeof(FsdirLevel)*(nNew-pCur->nLvl));
          544  +      pCur->aLvl = aNew;
          545  +      pCur->nLvl = nNew;
          546  +    }
          547  +    pCur->iLvl = iNew;
          548  +    pLvl = &pCur->aLvl[iNew];
          549  +    
          550  +    pLvl->zDir = pCur->zPath;
          551  +    pCur->zPath = 0;
          552  +    pLvl->pDir = opendir(pLvl->zDir);
          553  +    if( pLvl->pDir==0 ){
          554  +      fsdirSetErrmsg(pCur, "cannot read directory: %s", pCur->zPath);
          555  +      return SQLITE_ERROR;
          556  +    }
          557  +  }
          558  +
          559  +  while( pCur->iLvl>=0 ){
          560  +    FsdirLevel *pLvl = &pCur->aLvl[pCur->iLvl];
          561  +    struct dirent *pEntry = readdir(pLvl->pDir);
          562  +    if( pEntry ){
          563  +      if( pEntry->d_name[0]=='.' ){
          564  +       if( pEntry->d_name[1]=='.' && pEntry->d_name[2]=='\0' ) continue;
          565  +       if( pEntry->d_name[1]=='\0' ) continue;
          566  +      }
          567  +      sqlite3_free(pCur->zPath);
          568  +      pCur->zPath = sqlite3_mprintf("%s/%s", pLvl->zDir, pEntry->d_name);
          569  +      if( pCur->zPath==0 ) return SQLITE_NOMEM;
          570  +      if( lstat(pCur->zPath, &pCur->sStat) ){
          571  +        fsdirSetErrmsg(pCur, "cannot stat file: %s", pCur->zPath);
          572  +        return SQLITE_ERROR;
          573  +      }
          574  +      return SQLITE_OK;
          575  +    }
          576  +    closedir(pLvl->pDir);
          577  +    sqlite3_free(pLvl->zDir);
          578  +    pLvl->pDir = 0;
          579  +    pLvl->zDir = 0;
          580  +    pCur->iLvl--;
          581  +  }
          582  +
          583  +  /* EOF */
          584  +  sqlite3_free(pCur->zPath);
          585  +  pCur->zPath = 0;
          586  +  return SQLITE_OK;
          587  +}
          588  +
          589  +/*
          590  +** Return values of columns for the row at which the series_cursor
          591  +** is currently pointing.
          592  +*/
          593  +static int fsdirColumn(
          594  +  sqlite3_vtab_cursor *cur,   /* The cursor */
          595  +  sqlite3_context *ctx,       /* First argument to sqlite3_result_...() */
          596  +  int i                       /* Which column to return */
          597  +){
          598  +  fsdir_cursor *pCur = (fsdir_cursor*)cur;
          599  +  switch( i ){
          600  +    case 0: { /* name */
          601  +      sqlite3_result_text(ctx, &pCur->zPath[pCur->nBase], -1, SQLITE_TRANSIENT);
          602  +      break;
          603  +    }
          604  +
          605  +    case 1: /* mode */
          606  +      sqlite3_result_int64(ctx, pCur->sStat.st_mode);
          607  +      break;
          608  +
          609  +    case 2: /* mtime */
          610  +      sqlite3_result_int64(ctx, pCur->sStat.st_mtime);
          611  +      break;
          612  +
          613  +    case 3: { /* data */
          614  +      mode_t m = pCur->sStat.st_mode;
          615  +      if( S_ISDIR(m) ){
          616  +        sqlite3_result_null(ctx);
          617  +#if !defined(_WIN32) && !defined(WIN32)
          618  +      }else if( S_ISLNK(m) ){
          619  +        char aStatic[64];
          620  +        char *aBuf = aStatic;
          621  +        int nBuf = 64;
          622  +        int n;
          623  +
          624  +        while( 1 ){
          625  +          n = readlink(pCur->zPath, aBuf, nBuf);
          626  +          if( n<nBuf ) break;
          627  +          if( aBuf!=aStatic ) sqlite3_free(aBuf);
          628  +          nBuf = nBuf*2;
          629  +          aBuf = sqlite3_malloc(nBuf);
          630  +          if( aBuf==0 ){
          631  +            sqlite3_result_error_nomem(ctx);
          632  +            return SQLITE_NOMEM;
          633  +          }
          634  +        }
          635  +
          636  +        sqlite3_result_text(ctx, aBuf, n, SQLITE_TRANSIENT);
          637  +        if( aBuf!=aStatic ) sqlite3_free(aBuf);
          638  +#endif
          639  +      }else{
          640  +        readFileContents(ctx, pCur->zPath);
          641  +      }
          642  +    }
          643  +  }
          644  +  return SQLITE_OK;
          645  +}
          646  +
          647  +/*
          648  +** Return the rowid for the current row. In this implementation, the
          649  +** first row returned is assigned rowid value 1, and each subsequent
          650  +** row a value 1 more than that of the previous.
          651  +*/
          652  +static int fsdirRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
          653  +  fsdir_cursor *pCur = (fsdir_cursor*)cur;
          654  +  *pRowid = pCur->iRowid;
          655  +  return SQLITE_OK;
          656  +}
          657  +
          658  +/*
          659  +** Return TRUE if the cursor has been moved off of the last
          660  +** row of output.
          661  +*/
          662  +static int fsdirEof(sqlite3_vtab_cursor *cur){
          663  +  fsdir_cursor *pCur = (fsdir_cursor*)cur;
          664  +  return (pCur->zPath==0);
          665  +}
          666  +
          667  +/*
          668  +** xFilter callback.
          669  +*/
          670  +static int fsdirFilter(
          671  +  sqlite3_vtab_cursor *cur, 
          672  +  int idxNum, const char *idxStr,
          673  +  int argc, sqlite3_value **argv
          674  +){
          675  +  const char *zDir = 0;
          676  +  fsdir_cursor *pCur = (fsdir_cursor*)cur;
          677  +  (void)idxStr;
          678  +  fsdirResetCursor(pCur);
          679  +
          680  +  if( idxNum==0 ){
          681  +    fsdirSetErrmsg(pCur, "table function fsdir requires an argument");
          682  +    return SQLITE_ERROR;
          683  +  }
          684  +
          685  +  assert( argc==idxNum && (argc==1 || argc==2) );
          686  +  zDir = (const char*)sqlite3_value_text(argv[0]);
          687  +  if( zDir==0 ){
          688  +    fsdirSetErrmsg(pCur, "table function fsdir requires a non-NULL argument");
          689  +    return SQLITE_ERROR;
          690  +  }
          691  +  if( argc==2 ){
          692  +    pCur->zBase = (const char*)sqlite3_value_text(argv[1]);
          693  +  }
          694  +  if( pCur->zBase ){
          695  +    pCur->nBase = (int)strlen(pCur->zBase)+1;
          696  +    pCur->zPath = sqlite3_mprintf("%s/%s", pCur->zBase, zDir);
          697  +  }else{
          698  +    pCur->zPath = sqlite3_mprintf("%s", zDir);
          699  +  }
          700  +
          701  +  if( pCur->zPath==0 ){
          702  +    return SQLITE_NOMEM;
          703  +  }
          704  +  if( lstat(pCur->zPath, &pCur->sStat) ){
          705  +    fsdirSetErrmsg(pCur, "cannot stat file: %s", pCur->zPath);
          706  +    return SQLITE_ERROR;
          707  +  }
          708  +
          709  +  return SQLITE_OK;
          710  +}
          711  +
          712  +/*
          713  +** SQLite will invoke this method one or more times while planning a query
          714  +** that uses the generate_series virtual table.  This routine needs to create
          715  +** a query plan for each invocation and compute an estimated cost for that
          716  +** plan.
          717  +**
          718  +** In this implementation idxNum is used to represent the
          719  +** query plan.  idxStr is unused.
          720  +**
          721  +** The query plan is represented by bits in idxNum:
          722  +**
          723  +**  (1)  start = $value  -- constraint exists
          724  +**  (2)  stop = $value   -- constraint exists
          725  +**  (4)  step = $value   -- constraint exists
          726  +**  (8)  output in descending order
          727  +*/
          728  +static int fsdirBestIndex(
          729  +  sqlite3_vtab *tab,
          730  +  sqlite3_index_info *pIdxInfo
          731  +){
          732  +  int i;                 /* Loop over constraints */
          733  +  int idx4 = -1;
          734  +  int idx5 = -1;
          735  +  const struct sqlite3_index_constraint *pConstraint;
          736  +
          737  +  (void)tab;
          738  +  pConstraint = pIdxInfo->aConstraint;
          739  +  for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){
          740  +    if( pConstraint->usable==0 ) continue;
          741  +    if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
          742  +    if( pConstraint->iColumn==4 ) idx4 = i;
          743  +    if( pConstraint->iColumn==5 ) idx5 = i;
          744  +  }
          745  +
          746  +  if( idx4<0 ){
          747  +    pIdxInfo->idxNum = 0;
          748  +    pIdxInfo->estimatedCost = (double)(((sqlite3_int64)1) << 50);
    76    749     }else{
    77         -    rc = fwrite(z, 1, sqlite3_value_bytes(argv[1]), out);
          750  +    pIdxInfo->aConstraintUsage[idx4].omit = 1;
          751  +    pIdxInfo->aConstraintUsage[idx4].argvIndex = 1;
          752  +    if( idx5>=0 ){
          753  +      pIdxInfo->aConstraintUsage[idx5].omit = 1;
          754  +      pIdxInfo->aConstraintUsage[idx5].argvIndex = 2;
          755  +      pIdxInfo->idxNum = 2;
          756  +      pIdxInfo->estimatedCost = 10.0;
          757  +    }else{
          758  +      pIdxInfo->idxNum = 1;
          759  +      pIdxInfo->estimatedCost = 100.0;
          760  +    }
    78    761     }
    79         -  fclose(out);
    80         -  sqlite3_result_int64(context, rc);
          762  +
          763  +  return SQLITE_OK;
    81    764   }
    82    765   
          766  +/*
          767  +** Register the "fsdir" virtual table.
          768  +*/
          769  +static int fsdirRegister(sqlite3 *db){
          770  +  static sqlite3_module fsdirModule = {
          771  +    0,                         /* iVersion */
          772  +    0,                         /* xCreate */
          773  +    fsdirConnect,              /* xConnect */
          774  +    fsdirBestIndex,            /* xBestIndex */
          775  +    fsdirDisconnect,           /* xDisconnect */
          776  +    0,                         /* xDestroy */
          777  +    fsdirOpen,                 /* xOpen - open a cursor */
          778  +    fsdirClose,                /* xClose - close a cursor */
          779  +    fsdirFilter,               /* xFilter - configure scan constraints */
          780  +    fsdirNext,                 /* xNext - advance a cursor */
          781  +    fsdirEof,                  /* xEof - check for end of scan */
          782  +    fsdirColumn,               /* xColumn - read data */
          783  +    fsdirRowid,                /* xRowid - read data */
          784  +    0,                         /* xUpdate */
          785  +    0,                         /* xBegin */
          786  +    0,                         /* xSync */
          787  +    0,                         /* xCommit */
          788  +    0,                         /* xRollback */
          789  +    0,                         /* xFindMethod */
          790  +    0,                         /* xRename */
          791  +    0,                         /* xSavepoint */
          792  +    0,                         /* xRelease */
          793  +    0                          /* xRollbackTo */
          794  +  };
          795  +
................................................................................
          796  +  int rc = sqlite3_create_module(db, "fsdir", &fsdirModule, 0);
          797  +  return rc;
          798  +}
          799  +#else         /* SQLITE_OMIT_VIRTUALTABLE */
          800  +# define fsdirRegister(x) SQLITE_OK
          801  +#endif
    83    802   
    84    803   #ifdef _WIN32
    85    804   __declspec(dllexport)
    86    805   #endif
    87    806   int sqlite3_fileio_init(
    88    807     sqlite3 *db, 
    89    808     char **pzErrMsg, 
................................................................................
    91    810   ){
    92    811     int rc = SQLITE_OK;
    93    812     SQLITE_EXTENSION_INIT2(pApi);
    94    813     (void)pzErrMsg;  /* Unused parameter */
    95    814     rc = sqlite3_create_function(db, "readfile", 1, SQLITE_UTF8, 0,
    96    815                                  readfileFunc, 0, 0);
    97    816     if( rc==SQLITE_OK ){
    98         -    rc = sqlite3_create_function(db, "writefile", 2, SQLITE_UTF8, 0,
          817  +    rc = sqlite3_create_function(db, "writefile", -1, SQLITE_UTF8, 0,
    99    818                                    writefileFunc, 0, 0);
   100    819     }
          820  +  if( rc==SQLITE_OK ){
          821  +    rc = sqlite3_create_function(db, "lsmode", 1, SQLITE_UTF8, 0,
          822  +                                 lsModeFunc, 0, 0);
          823  +  }
          824  +  if( rc==SQLITE_OK ){
          825  +    rc = fsdirRegister(db);
          826  +  }
   101    827     return rc;
   102    828   }

Added ext/misc/sqlar.c.

            1  +/*
            2  +** 2017-12-17
            3  +**
            4  +** The author disclaims copyright to this source code.  In place of
            5  +** a legal notice, here is a blessing:
            6  +**
            7  +**    May you do good and not evil.
            8  +**    May you find forgiveness for yourself and forgive others.
            9  +**    May you share freely, never taking more than you give.
           10  +**
           11  +******************************************************************************
           12  +**
           13  +** Utility functions sqlar_compress() and sqlar_uncompress(). Useful
           14  +** for working with sqlar archives and used by the shell tool's built-in
           15  +** sqlar support.
           16  +*/
           17  +#include "sqlite3ext.h"
           18  +SQLITE_EXTENSION_INIT1
           19  +#include <zlib.h>
           20  +
           21  +/*
           22  +** Implementation of the "sqlar_compress(X)" SQL function.
           23  +**
           24  +** If the type of X is SQLITE_BLOB, and compressing that blob using
           25  +** zlib utility function compress() yields a smaller blob, return the
           26  +** compressed blob. Otherwise, return a copy of X.
           27  +**
           28  +** SQLar uses the "zlib format" for compressed content.  The zlib format
           29  +** contains a two-byte identification header and a four-byte checksum at
           30  +** the end.  This is different from ZIP which uses the raw deflate format.
           31  +**
           32  +** Future enhancements to SQLar might add support for new compression formats.
           33  +** If so, those new formats will be identified by alternative headers in the
           34  +** compressed data.
           35  +*/
           36  +static void sqlarCompressFunc(
           37  +  sqlite3_context *context,
           38  +  int argc,
           39  +  sqlite3_value **argv
           40  +){
           41  +  assert( argc==1 );
           42  +  if( sqlite3_value_type(argv[0])==SQLITE_BLOB ){
           43  +    const Bytef *pData = sqlite3_value_blob(argv[0]);
           44  +    uLong nData = sqlite3_value_bytes(argv[0]);
           45  +    uLongf nOut = compressBound(nData);
           46  +    Bytef *pOut;
           47  +
           48  +    pOut = (Bytef*)sqlite3_malloc(nOut);
           49  +    if( pOut==0 ){
           50  +      sqlite3_result_error_nomem(context);
           51  +      return;
           52  +    }else{
           53  +      if( Z_OK!=compress(pOut, &nOut, pData, nData) ){
           54  +        sqlite3_result_error(context, "error in compress()", -1);
           55  +      }else if( nOut<nData ){
           56  +        sqlite3_result_blob(context, pOut, nOut, SQLITE_TRANSIENT);
           57  +      }else{
           58  +        sqlite3_result_value(context, argv[0]);
           59  +      }
           60  +      sqlite3_free(pOut);
           61  +    }
           62  +  }else{
           63  +    sqlite3_result_value(context, argv[0]);
           64  +  }
           65  +}
           66  +
           67  +/*
           68  +** Implementation of the "sqlar_uncompress(X,SZ)" SQL function
           69  +**
           70  +** Parameter SZ is interpreted as an integer. If it is less than or
           71  +** equal to zero, then this function returns a copy of X. Or, if
           72  +** SZ is equal to the size of X when interpreted as a blob, also
           73  +** return a copy of X. Otherwise, decompress blob X using zlib
           74  +** utility function uncompress() and return the results (another
           75  +** blob).
           76  +*/
           77  +static void sqlarUncompressFunc(
           78  +  sqlite3_context *context,
           79  +  int argc,
           80  +  sqlite3_value **argv
           81  +){
           82  +  uLong nData;
           83  +  uLongf sz;
           84  +
           85  +  assert( argc==2 );
           86  +  sz = sqlite3_value_int(argv[1]);
           87  +
           88  +  if( sz<=0 || sz==(nData = sqlite3_value_bytes(argv[0])) ){
           89  +    sqlite3_result_value(context, argv[0]);
           90  +  }else{
           91  +    const Bytef *pData= sqlite3_value_blob(argv[0]);
           92  +    Bytef *pOut = sqlite3_malloc(sz);
           93  +    if( Z_OK!=uncompress(pOut, &sz, pData, nData) ){
           94  +      sqlite3_result_error(context, "error in uncompress()", -1);
           95  +    }else{
           96  +      sqlite3_result_blob(context, pOut, sz, SQLITE_TRANSIENT);
           97  +    }
           98  +    sqlite3_free(pOut);
           99  +  }
          100  +}
          101  +
          102  +
          103  +#ifdef _WIN32
          104  +__declspec(dllexport)
          105  +#endif
          106  +int sqlite3_sqlar_init(
          107  +  sqlite3 *db, 
          108  +  char **pzErrMsg, 
          109  +  const sqlite3_api_routines *pApi
          110  +){
          111  +  int rc = SQLITE_OK;
          112  +  SQLITE_EXTENSION_INIT2(pApi);
          113  +  (void)pzErrMsg;  /* Unused parameter */
          114  +  rc = sqlite3_create_function(db, "sqlar_compress", 1, SQLITE_UTF8, 0,
          115  +                               sqlarCompressFunc, 0, 0);
          116  +  if( rc==SQLITE_OK ){
          117  +    rc = sqlite3_create_function(db, "sqlar_uncompress", 2, SQLITE_UTF8, 0,
          118  +                                 sqlarUncompressFunc, 0, 0);
          119  +  }
          120  +  return rc;
          121  +}

Changes to ext/misc/unionvtab.c.

   480    480   */
   481    481   static int unionDisconnect(sqlite3_vtab *pVtab){
   482    482     if( pVtab ){
   483    483       UnionTab *pTab = (UnionTab*)pVtab;
   484    484       int i;
   485    485       for(i=0; i<pTab->nSrc; i++){
   486    486         UnionSrc *pSrc = &pTab->aSrc[i];
   487         -      if( pSrc->db ){
          487  +      int bHaveSrcDb = (pSrc->db!=0);
          488  +      sqlite3_close(pSrc->db);
          489  +      if( bHaveSrcDb ){
   488    490           unionInvokeOpenClose(pTab, pSrc, 1, 0);
   489    491         }
   490    492         sqlite3_free(pSrc->zDb);
   491    493         sqlite3_free(pSrc->zTab);
   492    494         sqlite3_free(pSrc->zFile);
   493    495         sqlite3_free(pSrc->zContext);
   494         -      sqlite3_close(pSrc->db);
   495    496       }
   496    497       sqlite3_finalize(pTab->pNotFound);
   497    498       sqlite3_finalize(pTab->pOpenClose);
   498    499       sqlite3_free(pTab->zSourceStr);
   499    500       sqlite3_free(pTab->aSrc);
   500    501       sqlite3_free(pTab);
   501    502     }

Added ext/misc/zipfile.c.

            1  +/*
            2  +** 2017-12-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  +**
           13  +** This file implements a virtual table for reading and writing ZIP archive
           14  +** files.
           15  +**
           16  +** Usage example:
           17  +**
           18  +**     SELECT name, sz, datetime(mtime,'unixepoch') FROM zipfile($filename);
           19  +**
           20  +** Current limitations:
           21  +**
           22  +**    *  No support for encryption
           23  +**    *  No support for ZIP archives spanning multiple files
           24  +**    *  No support for zip64 extensions
           25  +**    *  Only the "inflate/deflate" (zlib) compression method is supported
           26  +*/
           27  +#include "sqlite3ext.h"
           28  +SQLITE_EXTENSION_INIT1
           29  +#include <stdio.h>
           30  +#include <string.h>
           31  +#include <assert.h>
           32  +
           33  +#include <sys/types.h>
           34  +#include <sys/stat.h>
           35  +#include <fcntl.h>
           36  +#if !defined(_WIN32) && !defined(WIN32)
           37  +#  include <unistd.h>
           38  +#  include <dirent.h>
           39  +#  include <utime.h>
           40  +#else
           41  +#  include <io.h>
           42  +#endif
           43  +#include <time.h>
           44  +#include <errno.h>
           45  +
           46  +#include <zlib.h>
           47  +
           48  +#ifndef SQLITE_OMIT_VIRTUALTABLE
           49  +
           50  +#ifndef SQLITE_AMALGAMATION
           51  +typedef sqlite3_int64 i64;
           52  +typedef unsigned char u8;
           53  +typedef unsigned short u16;
           54  +typedef unsigned long u32;
           55  +#define MIN(a,b) ((a)<(b) ? (a) : (b))
           56  +#endif
           57  +
           58  +static const char ZIPFILE_SCHEMA[] = 
           59  +  "CREATE TABLE y("
           60  +    "name PRIMARY KEY,"  /* 0: Name of file in zip archive */
           61  +    "mode,"              /* 1: POSIX mode for file */
           62  +    "mtime,"             /* 2: Last modification time (secs since 1970)*/
           63  +    "sz,"                /* 3: Size of object */
           64  +    "rawdata,"           /* 4: Raw data */
           65  +    "data,"              /* 5: Uncompressed data */
           66  +    "method,"            /* 6: Compression method (integer) */
           67  +    "z HIDDEN"           /* 7: Name of zip file */
           68  +  ") WITHOUT ROWID;";
           69  +
           70  +#define ZIPFILE_F_COLUMN_IDX 7    /* Index of column "file" in the above */
           71  +#define ZIPFILE_BUFFER_SIZE (64*1024)
           72  +
           73  +
           74  +/*
           75  +** Magic numbers used to read and write zip files.
           76  +**
           77  +** ZIPFILE_NEWENTRY_MADEBY:
           78  +**   Use this value for the "version-made-by" field in new zip file
           79  +**   entries. The upper byte indicates "unix", and the lower byte 
           80  +**   indicates that the zip file matches pkzip specification 3.0. 
           81  +**   This is what info-zip seems to do.
           82  +**
           83  +** ZIPFILE_NEWENTRY_REQUIRED:
           84  +**   Value for "version-required-to-extract" field of new entries.
           85  +**   Version 2.0 is required to support folders and deflate compression.
           86  +**
           87  +** ZIPFILE_NEWENTRY_FLAGS:
           88  +**   Value for "general-purpose-bit-flags" field of new entries. Bit
           89  +**   11 means "utf-8 filename and comment".
           90  +**
           91  +** ZIPFILE_SIGNATURE_CDS:
           92  +**   First 4 bytes of a valid CDS record.
           93  +**
           94  +** ZIPFILE_SIGNATURE_LFH:
           95  +**   First 4 bytes of a valid LFH record.
           96  +*/
           97  +#define ZIPFILE_EXTRA_TIMESTAMP   0x5455
           98  +#define ZIPFILE_NEWENTRY_MADEBY   ((3<<8) + 30)
           99  +#define ZIPFILE_NEWENTRY_REQUIRED 20
          100  +#define ZIPFILE_NEWENTRY_FLAGS    0x800
          101  +#define ZIPFILE_SIGNATURE_CDS     0x02014b50
          102  +#define ZIPFILE_SIGNATURE_LFH     0x04034b50
          103  +#define ZIPFILE_SIGNATURE_EOCD    0x06054b50
          104  +#define ZIPFILE_LFH_FIXED_SZ      30
          105  +
          106  +/*
          107  +** Set the error message contained in context ctx to the results of
          108  +** vprintf(zFmt, ...).
          109  +*/
          110  +static void zipfileCtxErrorMsg(sqlite3_context *ctx, const char *zFmt, ...){
          111  +  char *zMsg = 0;
          112  +  va_list ap;
          113  +  va_start(ap, zFmt);
          114  +  zMsg = sqlite3_vmprintf(zFmt, ap);
          115  +  sqlite3_result_error(ctx, zMsg, -1);
          116  +  sqlite3_free(zMsg);
          117  +  va_end(ap);
          118  +}
          119  +
          120  +
          121  +/*
          122  +*** 4.3.16  End of central directory record:
          123  +***
          124  +***   end of central dir signature    4 bytes  (0x06054b50)
          125  +***   number of this disk             2 bytes
          126  +***   number of the disk with the
          127  +***   start of the central directory  2 bytes
          128  +***   total number of entries in the
          129  +***   central directory on this disk  2 bytes
          130  +***   total number of entries in
          131  +***   the central directory           2 bytes
          132  +***   size of the central directory   4 bytes
          133  +***   offset of start of central
          134  +***   directory with respect to
          135  +***   the starting disk number        4 bytes
          136  +***   .ZIP file comment length        2 bytes
          137  +***   .ZIP file comment       (variable size)
          138  +*/
          139  +typedef struct ZipfileEOCD ZipfileEOCD;
          140  +struct ZipfileEOCD {
          141  +  u16 iDisk;
          142  +  u16 iFirstDisk;
          143  +  u16 nEntry;
          144  +  u16 nEntryTotal;
          145  +  u32 nSize;
          146  +  u32 iOffset;
          147  +};
          148  +
          149  +/*
          150  +*** 4.3.12  Central directory structure:
          151  +***
          152  +*** ...
          153  +***
          154  +***   central file header signature   4 bytes  (0x02014b50)
          155  +***   version made by                 2 bytes
          156  +***   version needed to extract       2 bytes
          157  +***   general purpose bit flag        2 bytes
          158  +***   compression method              2 bytes
          159  +***   last mod file time              2 bytes
          160  +***   last mod file date              2 bytes
          161  +***   crc-32                          4 bytes
          162  +***   compressed size                 4 bytes
          163  +***   uncompressed size               4 bytes
          164  +***   file name length                2 bytes
          165  +***   extra field length              2 bytes
          166  +***   file comment length             2 bytes
          167  +***   disk number start               2 bytes
          168  +***   internal file attributes        2 bytes
          169  +***   external file attributes        4 bytes
          170  +***   relative offset of local header 4 bytes
          171  +*/
          172  +typedef struct ZipfileCDS ZipfileCDS;
          173  +struct ZipfileCDS {
          174  +  u16 iVersionMadeBy;
          175  +  u16 iVersionExtract;
          176  +  u16 flags;
          177  +  u16 iCompression;
          178  +  u16 mTime;
          179  +  u16 mDate;
          180  +  u32 crc32;
          181  +  u32 szCompressed;
          182  +  u32 szUncompressed;
          183  +  u16 nFile;
          184  +  u16 nExtra;
          185  +  u16 nComment;
          186  +  u16 iDiskStart;
          187  +  u16 iInternalAttr;
          188  +  u32 iExternalAttr;
          189  +  u32 iOffset;
          190  +  char *zFile;                    /* Filename (sqlite3_malloc()) */
          191  +};
          192  +
          193  +/*
          194  +*** 4.3.7  Local file header:
          195  +***
          196  +***   local file header signature     4 bytes  (0x04034b50)
          197  +***   version needed to extract       2 bytes
          198  +***   general purpose bit flag        2 bytes
          199  +***   compression method              2 bytes
          200  +***   last mod file time              2 bytes
          201  +***   last mod file date              2 bytes
          202  +***   crc-32                          4 bytes
          203  +***   compressed size                 4 bytes
          204  +***   uncompressed size               4 bytes
          205  +***   file name length                2 bytes
          206  +***   extra field length              2 bytes
          207  +***   
          208  +*/
          209  +typedef struct ZipfileLFH ZipfileLFH;
          210  +struct ZipfileLFH {
          211  +  u16 iVersionExtract;
          212  +  u16 flags;
          213  +  u16 iCompression;
          214  +  u16 mTime;
          215  +  u16 mDate;
          216  +  u32 crc32;
          217  +  u32 szCompressed;
          218  +  u32 szUncompressed;
          219  +  u16 nFile;
          220  +  u16 nExtra;
          221  +};
          222  +
          223  +typedef struct ZipfileEntry ZipfileEntry;
          224  +struct ZipfileEntry {
          225  +  char *zPath;               /* Path of zipfile entry */
          226  +  u8 *aCdsEntry;             /* Buffer containing entire CDS entry */
          227  +  int nCdsEntry;             /* Size of buffer aCdsEntry[] in bytes */
          228  +  int bDeleted;              /* True if entry has been deleted */
          229  +  ZipfileEntry *pNext;       /* Next element in in-memory CDS */
          230  +};
          231  +
          232  +/* 
          233  +** Cursor type for recursively iterating through a directory structure.
          234  +*/
          235  +typedef struct ZipfileCsr ZipfileCsr;
          236  +struct ZipfileCsr {
          237  +  sqlite3_vtab_cursor base;  /* Base class - must be first */
          238  +  i64 iId;                   /* Cursor ID */
          239  +  int bEof;                  /* True when at EOF */
          240  +
          241  +  /* Used outside of write transactions */
          242  +  FILE *pFile;               /* Zip file */
          243  +  i64 iNextOff;              /* Offset of next record in central directory */
          244  +  ZipfileEOCD eocd;          /* Parse of central directory record */
          245  +
          246  +  /* Used inside write transactions */
          247  +  ZipfileEntry *pCurrent;
          248  +
          249  +  ZipfileCDS cds;            /* Central Directory Structure */
          250  +  ZipfileLFH lfh;            /* Local File Header for current entry */
          251  +  i64 iDataOff;              /* Offset in zipfile to data */
          252  +  u32 mTime;                 /* Extended mtime value */
          253  +  int flags;                 /* Flags byte (see below for bits) */
          254  +  ZipfileCsr *pCsrNext;      /* Next cursor on same virtual table */
          255  +};
          256  +
          257  +/*
          258  +** Values for ZipfileCsr.flags.
          259  +*/
          260  +#define ZIPFILE_MTIME_VALID 0x0001
          261  +
          262  +typedef struct ZipfileTab ZipfileTab;
          263  +struct ZipfileTab {
          264  +  sqlite3_vtab base;         /* Base class - must be first */
          265  +  char *zFile;               /* Zip file this table accesses (may be NULL) */
          266  +  u8 *aBuffer;               /* Temporary buffer used for various tasks */
          267  +
          268  +  ZipfileCsr *pCsrList;      /* List of cursors */
          269  +  i64 iNextCsrid;
          270  +
          271  +  /* The following are used by write transactions only */
          272  +  ZipfileEntry *pFirstEntry; /* Linked list of all files (if pWriteFd!=0) */
          273  +  ZipfileEntry *pLastEntry;  /* Last element in pFirstEntry list */
          274  +  FILE *pWriteFd;            /* File handle open on zip archive */
          275  +  i64 szCurrent;             /* Current size of zip archive */
          276  +  i64 szOrig;                /* Size of archive at start of transaction */
          277  +};
          278  +
          279  +static void zipfileDequote(char *zIn){
          280  +  char q = zIn[0];
          281  +  if( q=='"' || q=='\'' || q=='`' || q=='[' ){
          282  +    char c;
          283  +    int iIn = 1;
          284  +    int iOut = 0;
          285  +    if( q=='[' ) q = ']';
          286  +    while( (c = zIn[iIn++]) ){
          287  +      if( c==q ){
          288  +        if( zIn[iIn++]!=q ) break;
          289  +      }
          290  +      zIn[iOut++] = c;
          291  +    }
          292  +    zIn[iOut] = '\0';
          293  +  }
          294  +}
          295  +
          296  +/*
          297  +** Construct a new ZipfileTab virtual table object.
          298  +** 
          299  +**   argv[0]   -> module name  ("zipfile")
          300  +**   argv[1]   -> database name
          301  +**   argv[2]   -> table name
          302  +**   argv[...] -> "column name" and other module argument fields.
          303  +*/
          304  +static int zipfileConnect(
          305  +  sqlite3 *db,
          306  +  void *pAux,
          307  +  int argc, const char *const*argv,
          308  +  sqlite3_vtab **ppVtab,
          309  +  char **pzErr
          310  +){
          311  +  int nByte = sizeof(ZipfileTab) + ZIPFILE_BUFFER_SIZE;
          312  +  int nFile = 0;
          313  +  const char *zFile = 0;
          314  +  ZipfileTab *pNew = 0;
          315  +  int rc;
          316  +
          317  +  if( argc>3 ){
          318  +    zFile = argv[3];
          319  +    nFile = (int)strlen(zFile)+1;
          320  +  }
          321  +
          322  +  rc = sqlite3_declare_vtab(db, ZIPFILE_SCHEMA);
          323  +  if( rc==SQLITE_OK ){
          324  +    pNew = (ZipfileTab*)sqlite3_malloc(nByte+nFile);
          325  +    if( pNew==0 ) return SQLITE_NOMEM;
          326  +    memset(pNew, 0, nByte+nFile);
          327  +    pNew->aBuffer = (u8*)&pNew[1];
          328  +    if( zFile ){
          329  +      pNew->zFile = (char*)&pNew->aBuffer[ZIPFILE_BUFFER_SIZE];
          330  +      memcpy(pNew->zFile, zFile, nFile);
          331  +      zipfileDequote(pNew->zFile);
          332  +    }
          333  +  }
          334  +  *ppVtab = (sqlite3_vtab*)pNew;
          335  +  return rc;
          336  +}
          337  +
          338  +/*
          339  +** This method is the destructor for zipfile vtab objects.
          340  +*/
          341  +static int zipfileDisconnect(sqlite3_vtab *pVtab){
          342  +  sqlite3_free(pVtab);
          343  +  return SQLITE_OK;
          344  +}
          345  +
          346  +/*
          347  +** Constructor for a new ZipfileCsr object.
          348  +*/
          349  +static int zipfileOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCsr){
          350  +  ZipfileTab *pTab = (ZipfileTab*)p;
          351  +  ZipfileCsr *pCsr;
          352  +  pCsr = sqlite3_malloc(sizeof(*pCsr));
          353  +  *ppCsr = (sqlite3_vtab_cursor*)pCsr;
          354  +  if( pCsr==0 ){
          355  +    return SQLITE_NOMEM;
          356  +  }
          357  +  memset(pCsr, 0, sizeof(*pCsr));
          358  +  pCsr->iId = ++pTab->iNextCsrid;
          359  +  pCsr->pCsrNext = pTab->pCsrList;
          360  +  pTab->pCsrList = pCsr;
          361  +  return SQLITE_OK;
          362  +}
          363  +
          364  +/*
          365  +** Reset a cursor back to the state it was in when first returned
          366  +** by zipfileOpen().
          367  +*/
          368  +static void zipfileResetCursor(ZipfileCsr *pCsr){
          369  +  sqlite3_free(pCsr->cds.zFile);
          370  +  pCsr->cds.zFile = 0;
          371  +  pCsr->bEof = 0;
          372  +  if( pCsr->pFile ){
          373  +    fclose(pCsr->pFile);
          374  +    pCsr->pFile = 0;
          375  +  }
          376  +}
          377  +
          378  +/*
          379  +** Destructor for an ZipfileCsr.
          380  +*/
          381  +static int zipfileClose(sqlite3_vtab_cursor *cur){
          382  +  ZipfileCsr *pCsr = (ZipfileCsr*)cur;
          383  +  ZipfileTab *pTab = (ZipfileTab*)(pCsr->base.pVtab);
          384  +  ZipfileCsr **pp;
          385  +  zipfileResetCursor(pCsr);
          386  +
          387  +  /* Remove this cursor from the ZipfileTab.pCsrList list. */
          388  +  for(pp=&pTab->pCsrList; *pp; pp=&((*pp)->pCsrNext)){
          389  +    if( *pp==pCsr ){ 
          390  +      *pp = pCsr->pCsrNext;
          391  +      break;
          392  +    }
          393  +  }
          394  +
          395  +  sqlite3_free(pCsr);
          396  +  return SQLITE_OK;
          397  +}
          398  +
          399  +/*
          400  +** Set the error message for the virtual table associated with cursor
          401  +** pCsr to the results of vprintf(zFmt, ...).
          402  +*/
          403  +static void zipfileSetErrmsg(ZipfileCsr *pCsr, const char *zFmt, ...){
          404  +  va_list ap;
          405  +  va_start(ap, zFmt);
          406  +  pCsr->base.pVtab->zErrMsg = sqlite3_vmprintf(zFmt, ap);
          407  +  va_end(ap);
          408  +}
          409  +
          410  +static int zipfileReadData(
          411  +  FILE *pFile,                    /* Read from this file */
          412  +  u8 *aRead,                      /* Read into this buffer */
          413  +  int nRead,                      /* Number of bytes to read */
          414  +  i64 iOff,                       /* Offset to read from */
          415  +  char **pzErrmsg                 /* OUT: Error message (from sqlite3_malloc) */
          416  +){
          417  +  size_t n;
          418  +  fseek(pFile, (long)iOff, SEEK_SET);
          419  +  n = fread(aRead, 1, nRead, pFile);
          420  +  if( (int)n!=nRead ){
          421  +    *pzErrmsg = sqlite3_mprintf("error in fread()");
          422  +    return SQLITE_ERROR;
          423  +  }
          424  +  return SQLITE_OK;
          425  +}
          426  +
          427  +static int zipfileAppendData(
          428  +  ZipfileTab *pTab,
          429  +  const u8 *aWrite,
          430  +  int nWrite
          431  +){
          432  +  size_t n;
          433  +  fseek(pTab->pWriteFd, (long)pTab->szCurrent, SEEK_SET);
          434  +  n = fwrite(aWrite, 1, nWrite, pTab->pWriteFd);
          435  +  if( (int)n!=nWrite ){
          436  +    pTab->base.zErrMsg = sqlite3_mprintf("error in fwrite()");
          437  +    return SQLITE_ERROR;
          438  +  }
          439  +  pTab->szCurrent += nWrite;
          440  +  return SQLITE_OK;
          441  +}
          442  +
          443  +static u16 zipfileGetU16(const u8 *aBuf){
          444  +  return (aBuf[1] << 8) + aBuf[0];
          445  +}
          446  +static u32 zipfileGetU32(const u8 *aBuf){
          447  +  return ((u32)(aBuf[3]) << 24)
          448  +       + ((u32)(aBuf[2]) << 16)
          449  +       + ((u32)(aBuf[1]) <<  8)
          450  +       + ((u32)(aBuf[0]) <<  0);
          451  +}
          452  +
          453  +static void zipfilePutU16(u8 *aBuf, u16 val){
          454  +  aBuf[0] = val & 0xFF;
          455  +  aBuf[1] = (val>>8) & 0xFF;
          456  +}
          457  +static void zipfilePutU32(u8 *aBuf, u32 val){
          458  +  aBuf[0] = val & 0xFF;
          459  +  aBuf[1] = (val>>8) & 0xFF;
          460  +  aBuf[2] = (val>>16) & 0xFF;
          461  +  aBuf[3] = (val>>24) & 0xFF;
          462  +}
          463  +
          464  +#define zipfileRead32(aBuf) ( aBuf+=4, zipfileGetU32(aBuf-4) )
          465  +#define zipfileRead16(aBuf) ( aBuf+=2, zipfileGetU16(aBuf-2) )
          466  +
          467  +#define zipfileWrite32(aBuf,val) { zipfilePutU32(aBuf,val); aBuf+=4; }
          468  +#define zipfileWrite16(aBuf,val) { zipfilePutU16(aBuf,val); aBuf+=2; }
          469  +
          470  +static u8* zipfileCsrBuffer(ZipfileCsr *pCsr){
          471  +  return ((ZipfileTab*)(pCsr->base.pVtab))->aBuffer;
          472  +}
          473  +
          474  +/*
          475  +** Magic numbers used to read CDS records.
          476  +*/
          477  +#define ZIPFILE_CDS_FIXED_SZ         46
          478  +#define ZIPFILE_CDS_NFILE_OFF        28
          479  +
          480  +/*
          481  +** Decode the CDS record in buffer aBuf into (*pCDS). Return SQLITE_ERROR
          482  +** if the record is not well-formed, or SQLITE_OK otherwise.
          483  +*/
          484  +static int zipfileReadCDS(u8 *aBuf, ZipfileCDS *pCDS){
          485  +  u8 *aRead = aBuf;
          486  +  u32 sig = zipfileRead32(aRead);
          487  +  int rc = SQLITE_OK;
          488  +  if( sig!=ZIPFILE_SIGNATURE_CDS ){
          489  +    rc = SQLITE_ERROR;
          490  +  }else{
          491  +    pCDS->iVersionMadeBy = zipfileRead16(aRead);
          492  +    pCDS->iVersionExtract = zipfileRead16(aRead);
          493  +    pCDS->flags = zipfileRead16(aRead);
          494  +    pCDS->iCompression = zipfileRead16(aRead);
          495  +    pCDS->mTime = zipfileRead16(aRead);
          496  +    pCDS->mDate = zipfileRead16(aRead);
          497  +    pCDS->crc32 = zipfileRead32(aRead);
          498  +    pCDS->szCompressed = zipfileRead32(aRead);
          499  +    pCDS->szUncompressed = zipfileRead32(aRead);
          500  +    assert( aRead==&aBuf[ZIPFILE_CDS_NFILE_OFF] );
          501  +    pCDS->nFile = zipfileRead16(aRead);
          502  +    pCDS->nExtra = zipfileRead16(aRead);
          503  +    pCDS->nComment = zipfileRead16(aRead);
          504  +    pCDS->iDiskStart = zipfileRead16(aRead);
          505  +    pCDS->iInternalAttr = zipfileRead16(aRead);
          506  +    pCDS->iExternalAttr = zipfileRead32(aRead);
          507  +    pCDS->iOffset = zipfileRead32(aRead);
          508  +    assert( aRead==&aBuf[ZIPFILE_CDS_FIXED_SZ] );
          509  +  }
          510  +
          511  +  return rc;
          512  +}
          513  +
          514  +/*
          515  +** Read the CDS record for the current entry from disk into pCsr->cds.
          516  +*/
          517  +static int zipfileCsrReadCDS(ZipfileCsr *pCsr){
          518  +  char **pzErr = &pCsr->base.pVtab->zErrMsg;
          519  +  u8 *aRead;
          520  +  int rc = SQLITE_OK;
          521  +
          522  +  sqlite3_free(pCsr->cds.zFile);
          523  +  pCsr->cds.zFile = 0;
          524  +
          525  +  if( pCsr->pCurrent==0 ){
          526  +    aRead = zipfileCsrBuffer(pCsr);
          527  +    rc = zipfileReadData(
          528  +        pCsr->pFile, aRead, ZIPFILE_CDS_FIXED_SZ, pCsr->iNextOff, pzErr
          529  +    );
          530  +  }else{
          531  +    aRead = pCsr->pCurrent->aCdsEntry;
          532  +  }
          533  +
          534  +  if( rc==SQLITE_OK ){
          535  +    rc = zipfileReadCDS(aRead, &pCsr->cds);
          536  +    if( rc!=SQLITE_OK ){
          537  +      assert( pCsr->pCurrent==0 );
          538  +      zipfileSetErrmsg(pCsr,"failed to read CDS at offset %lld",pCsr->iNextOff);
          539  +    }else{
          540  +      int nRead;
          541  +      if( pCsr->pCurrent==0 ){
          542  +        nRead = pCsr->cds.nFile + pCsr->cds.nExtra;
          543  +        aRead = zipfileCsrBuffer(pCsr);
          544  +        pCsr->iNextOff += ZIPFILE_CDS_FIXED_SZ;
          545  +        rc = zipfileReadData(pCsr->pFile, aRead, nRead, pCsr->iNextOff, pzErr);
          546  +      }else{
          547  +        aRead = &aRead[ZIPFILE_CDS_FIXED_SZ];
          548  +      }
          549  +
          550  +      if( rc==SQLITE_OK ){
          551  +        pCsr->cds.zFile = sqlite3_mprintf("%.*s", (int)pCsr->cds.nFile, aRead);
          552  +        pCsr->iNextOff += pCsr->cds.nFile;
          553  +        pCsr->iNextOff += pCsr->cds.nExtra;
          554  +        pCsr->iNextOff += pCsr->cds.nComment;
          555  +      }
          556  +
          557  +      /* Scan the cds.nExtra bytes of "extra" fields for any that can
          558  +      ** be interpreted. The general format of an extra field is:
          559  +      **
          560  +      **   Header ID    2 bytes
          561  +      **   Data Size    2 bytes
          562  +      **   Data         N bytes
          563  +      **
          564  +      */
          565  +      if( rc==SQLITE_OK ){
          566  +        u8 *p = &aRead[pCsr->cds.nFile];
          567  +        u8 *pEnd = &p[pCsr->cds.nExtra];
          568  +
          569  +        while( p<pEnd ){
          570  +          u16 id = zipfileRead16(p);
          571  +          u16 nByte = zipfileRead16(p);
          572  +
          573  +          switch( id ){
          574  +            case ZIPFILE_EXTRA_TIMESTAMP: {
          575  +              u8 b = p[0];
          576  +              if( b & 0x01 ){     /* 0x01 -> modtime is present */
          577  +                pCsr->mTime = zipfileGetU32(&p[1]);
          578  +                pCsr->flags |= ZIPFILE_MTIME_VALID;
          579  +              }
          580  +              break;
          581  +            }
          582  +          }
          583  +
          584  +          p += nByte;
          585  +        }
          586  +      }
          587  +    }
          588  +  }
          589  +
          590  +  return rc;
          591  +}
          592  +
          593  +static FILE *zipfileGetFd(ZipfileCsr *pCsr){
          594  +  if( pCsr->pFile ) return pCsr->pFile;
          595  +  return ((ZipfileTab*)(pCsr->base.pVtab))->pWriteFd;
          596  +}
          597  +
          598  +static int zipfileReadLFH(
          599  +  FILE *pFd, 
          600  +  i64 iOffset,
          601  +  u8 *aTmp, 
          602  +  ZipfileLFH *pLFH, 
          603  +  char **pzErr
          604  +){
          605  +  u8 *aRead = aTmp;
          606  +  static const int szFix = ZIPFILE_LFH_FIXED_SZ;
          607  +  int rc;
          608  +
          609  +  rc = zipfileReadData(pFd, aRead, szFix, iOffset, pzErr);
          610  +  if( rc==SQLITE_OK ){
          611  +    u32 sig = zipfileRead32(aRead);
          612  +    if( sig!=ZIPFILE_SIGNATURE_LFH ){
          613  +      *pzErr = sqlite3_mprintf("failed to read LFH at offset %d", (int)iOffset);
          614  +      rc = SQLITE_ERROR;
          615  +    }else{
          616  +      pLFH->iVersionExtract = zipfileRead16(aRead);
          617  +      pLFH->flags = zipfileRead16(aRead);
          618  +      pLFH->iCompression = zipfileRead16(aRead);
          619  +      pLFH->mTime = zipfileRead16(aRead);
          620  +      pLFH->mDate = zipfileRead16(aRead);
          621  +      pLFH->crc32 = zipfileRead32(aRead);
          622  +      pLFH->szCompressed = zipfileRead32(aRead);
          623  +      pLFH->szUncompressed = zipfileRead32(aRead);
          624  +      pLFH->nFile = zipfileRead16(aRead);
          625  +      pLFH->nExtra = zipfileRead16(aRead);
          626  +      assert( aRead==&aTmp[szFix] );
          627  +    }
          628  +  }
          629  +  return rc;
          630  +}
          631  +
          632  +static int zipfileCsrReadLFH(ZipfileCsr *pCsr){
          633  +  FILE *pFile = zipfileGetFd(pCsr);
          634  +  char **pzErr = &pCsr->base.pVtab->zErrMsg;
          635  +  u8 *aRead = zipfileCsrBuffer(pCsr);
          636  +  int rc = zipfileReadLFH(pFile, pCsr->cds.iOffset, aRead, &pCsr->lfh, pzErr);
          637  +  pCsr->iDataOff =  pCsr->cds.iOffset + ZIPFILE_LFH_FIXED_SZ;
          638  +  pCsr->iDataOff += pCsr->lfh.nFile+pCsr->lfh.nExtra;
          639  +  return rc;
          640  +}
          641  +
          642  +
          643  +/*
          644  +** Advance an ZipfileCsr to its next row of output.
          645  +*/
          646  +static int zipfileNext(sqlite3_vtab_cursor *cur){
          647  +  ZipfileCsr *pCsr = (ZipfileCsr*)cur;
          648  +  int rc = SQLITE_OK;
          649  +  pCsr->flags = 0;
          650  +
          651  +  if( pCsr->pCurrent==0 ){
          652  +    i64 iEof = pCsr->eocd.iOffset + pCsr->eocd.nSize;
          653  +    if( pCsr->iNextOff>=iEof ){
          654  +      pCsr->bEof = 1;
          655  +    }
          656  +  }else{
          657  +    assert( pCsr->pFile==0 );
          658  +    do {
          659  +      pCsr->pCurrent = pCsr->pCurrent->pNext;
          660  +    }while( pCsr->pCurrent && pCsr->pCurrent->bDeleted );
          661  +    if( pCsr->pCurrent==0 ){
          662  +      pCsr->bEof = 1;
          663  +    }
          664  +  }
          665  +
          666  +  if( pCsr->bEof==0 ){
          667  +    rc = zipfileCsrReadCDS(pCsr);
          668  +    if( rc==SQLITE_OK ){
          669  +      rc = zipfileCsrReadLFH(pCsr);
          670  +    }
          671  +  }
          672  +
          673  +  return rc;
          674  +}
          675  +
          676  +/*
          677  +** "Standard" MS-DOS time format:
          678  +**
          679  +**   File modification time:
          680  +**     Bits 00-04: seconds divided by 2
          681  +**     Bits 05-10: minute
          682  +**     Bits 11-15: hour
          683  +**   File modification date:
          684  +**     Bits 00-04: day
          685  +**     Bits 05-08: month (1-12)
          686  +**     Bits 09-15: years from 1980 
          687  +*/
          688  +static time_t zipfileMtime(ZipfileCsr *pCsr){
          689  +  struct tm t;
          690  +  memset(&t, 0, sizeof(t));
          691  +  t.tm_sec = (pCsr->cds.mTime & 0x1F)*2;
          692  +  t.tm_min = (pCsr->cds.mTime >> 5) & 0x2F;
          693  +  t.tm_hour = (pCsr->cds.mTime >> 11) & 0x1F;
          694  +
          695  +  t.tm_mday = (pCsr->cds.mDate & 0x1F);
          696  +  t.tm_mon = ((pCsr->cds.mDate >> 5) & 0x0F) - 1;
          697  +  t.tm_year = 80 + ((pCsr->cds.mDate >> 9) & 0x7F);
          698  +
          699  +  return mktime(&t);
          700  +}
          701  +
          702  +static void zipfileMtimeToDos(ZipfileCDS *pCds, u32 mTime){
          703  +  time_t t = (time_t)mTime;
          704  +  struct tm res;
          705  +
          706  +#if !defined(_WIN32) && !defined(WIN32)
          707  +  localtime_r(&t, &res);
          708  +#else
          709  +  memcpy(&res, localtime(&t), sizeof(struct tm));
          710  +#endif
          711  +
          712  +  pCds->mTime = (u16)(
          713  +    (res.tm_sec / 2) + 
          714  +    (res.tm_min << 5) +
          715  +    (res.tm_hour << 11));
          716  +
          717  +  pCds->mDate = (u16)(
          718  +    (res.tm_mday-1) +
          719  +    ((res.tm_mon+1) << 5) +
          720  +    ((res.tm_year-80) << 9));
          721  +}
          722  +
          723  +static void zipfileInflate(
          724  +  sqlite3_context *pCtx,          /* Store error here, if any */
          725  +  const u8 *aIn,                  /* Compressed data */
          726  +  int nIn,                        /* Size of buffer aIn[] in bytes */
          727  +  int nOut                        /* Expected output size */
          728  +){
          729  +  u8 *aRes = sqlite3_malloc(nOut);
          730  +  if( aRes==0 ){
          731  +    sqlite3_result_error_nomem(pCtx);
          732  +  }else{
          733  +    int err;
          734  +    z_stream str;
          735  +    memset(&str, 0, sizeof(str));
          736  +
          737  +    str.next_in = (Byte*)aIn;
          738  +    str.avail_in = nIn;
          739  +    str.next_out = (Byte*)aRes;
          740  +    str.avail_out = nOut;
          741  +
          742  +    err = inflateInit2(&str, -15);
          743  +    if( err!=Z_OK ){
          744  +      zipfileCtxErrorMsg(pCtx, "inflateInit2() failed (%d)", err);
          745  +    }else{
          746  +      err = inflate(&str, Z_NO_FLUSH);
          747  +      if( err!=Z_STREAM_END ){
          748  +        zipfileCtxErrorMsg(pCtx, "inflate() failed (%d)", err);
          749  +      }else{
          750  +        sqlite3_result_blob(pCtx, aRes, nOut, SQLITE_TRANSIENT);
          751  +      }
          752  +    }
          753  +    sqlite3_free(aRes);
          754  +    inflateEnd(&str);
          755  +  }
          756  +}
          757  +
          758  +static int zipfileDeflate(
          759  +  ZipfileTab *pTab,               /* Set error message here */
          760  +  const u8 *aIn, int nIn,         /* Input */
          761  +  u8 **ppOut, int *pnOut          /* Output */
          762  +){
          763  +  int nAlloc = (int)compressBound(nIn);
          764  +  u8 *aOut;
          765  +  int rc = SQLITE_OK;
          766  +
          767  +  aOut = (u8*)sqlite3_malloc(nAlloc);
          768  +  if( aOut==0 ){
          769  +    rc = SQLITE_NOMEM;
          770  +  }else{
          771  +    int res;
          772  +    z_stream str;
          773  +    memset(&str, 0, sizeof(str));
          774  +    str.next_in = (Bytef*)aIn;
          775  +    str.avail_in = nIn;
          776  +    str.next_out = aOut;
          777  +    str.avail_out = nAlloc;
          778  +
          779  +    deflateInit2(&str, 9, Z_DEFLATED, -15, 8, Z_DEFAULT_STRATEGY);
          780  +    res = deflate(&str, Z_FINISH);
          781  +
          782  +    if( res==Z_STREAM_END ){
          783  +      *ppOut = aOut;
          784  +      *pnOut = (int)str.total_out;
          785  +    }else{
          786  +      sqlite3_free(aOut);
          787  +      pTab->base.zErrMsg = sqlite3_mprintf("zipfile: deflate() error");
          788  +      rc = SQLITE_ERROR;
          789  +    }
          790  +    deflateEnd(&str);
          791  +  }
          792  +
          793  +  return rc;
          794  +}
          795  +
          796  +
          797  +/*
          798  +** Return values of columns for the row at which the series_cursor
          799  +** is currently pointing.
          800  +*/
          801  +static int zipfileColumn(
          802  +  sqlite3_vtab_cursor *cur,   /* The cursor */
          803  +  sqlite3_context *ctx,       /* First argument to sqlite3_result_...() */
          804  +  int i                       /* Which column to return */
          805  +){
          806  +  ZipfileCsr *pCsr = (ZipfileCsr*)cur;
          807  +  int rc = SQLITE_OK;
          808  +  switch( i ){
          809  +    case 0:   /* name */
          810  +      sqlite3_result_text(ctx, pCsr->cds.zFile, -1, SQLITE_TRANSIENT);
          811  +      break;
          812  +    case 1:   /* mode */
          813  +      /* TODO: Whether or not the following is correct surely depends on
          814  +      ** the platform on which the archive was created.  */
          815  +      sqlite3_result_int(ctx, pCsr->cds.iExternalAttr >> 16);
          816  +      break;
          817  +    case 2: { /* mtime */
          818  +      if( pCsr->flags & ZIPFILE_MTIME_VALID ){
          819  +        sqlite3_result_int64(ctx, pCsr->mTime);
          820  +      }else{
          821  +        sqlite3_result_int64(ctx, zipfileMtime(pCsr));
          822  +      }
          823  +      break;
          824  +    }
          825  +    case 3: { /* sz */
          826  +      if( sqlite3_vtab_nochange(ctx)==0 ){
          827  +        sqlite3_result_int64(ctx, pCsr->cds.szUncompressed);
          828  +      }
          829  +      break;
          830  +    }
          831  +    case 4:   /* rawdata */
          832  +      if( sqlite3_vtab_nochange(ctx) ) break;
          833  +    case 5: { /* data */
          834  +      if( i==4 || pCsr->cds.iCompression==0 || pCsr->cds.iCompression==8 ){
          835  +        int sz = pCsr->cds.szCompressed;
          836  +        int szFinal = pCsr->cds.szUncompressed;
          837  +        if( szFinal>0 ){
          838  +          u8 *aBuf = sqlite3_malloc(sz);
          839  +          if( aBuf==0 ){
          840  +            rc = SQLITE_NOMEM;
          841  +          }else{
          842  +            FILE *pFile = zipfileGetFd(pCsr);
          843  +            rc = zipfileReadData(pFile, aBuf, sz, pCsr->iDataOff,
          844  +                &pCsr->base.pVtab->zErrMsg
          845  +            );
          846  +          }
          847  +          if( rc==SQLITE_OK ){
          848  +            if( i==5 && pCsr->cds.iCompression ){
          849  +              zipfileInflate(ctx, aBuf, sz, szFinal);
          850  +            }else{
          851  +              sqlite3_result_blob(ctx, aBuf, sz, SQLITE_TRANSIENT);
          852  +            }
          853  +            sqlite3_free(aBuf);
          854  +          }
          855  +        }else{
          856  +          /* Figure out if this is a directory or a zero-sized file. Consider
          857  +          ** it to be a directory either if the mode suggests so, or if
          858  +          ** the final character in the name is '/'.  */
          859  +          u32 mode = pCsr->cds.iExternalAttr >> 16;
          860  +          if( !(mode & S_IFDIR) && pCsr->cds.zFile[pCsr->cds.nFile-1]!='/' ){
          861  +            sqlite3_result_blob(ctx, "", 0, SQLITE_STATIC);
          862  +          }
          863  +        }
          864  +      }
          865  +      break;
          866  +    }
          867  +    case 6:   /* method */
          868  +      sqlite3_result_int(ctx, pCsr->cds.iCompression);
          869  +      break;
          870  +    case 7:   /* z */
          871  +      sqlite3_result_int64(ctx, pCsr->iId);
          872  +      break;
          873  +  }
          874  +
          875  +  return rc;
          876  +}
          877  +
          878  +/*
          879  +** Return the rowid for the current row.
          880  +*/
          881  +static int zipfileRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
          882  +  assert( 0 );
          883  +  return SQLITE_OK;
          884  +}
          885  +
          886  +/*
          887  +** Return TRUE if the cursor has been moved off of the last
          888  +** row of output.
          889  +*/
          890  +static int zipfileEof(sqlite3_vtab_cursor *cur){
          891  +  ZipfileCsr *pCsr = (ZipfileCsr*)cur;
          892  +  return pCsr->bEof;
          893  +}
          894  +
          895  +/*
          896  +*/
          897  +static int zipfileReadEOCD(
          898  +  ZipfileTab *pTab,               /* Return errors here */
          899  +  FILE *pFile,                    /* Read from this file */
          900  +  ZipfileEOCD *pEOCD              /* Object to populate */
          901  +){
          902  +  u8 *aRead = pTab->aBuffer;      /* Temporary buffer */
          903  +  i64 szFile;                     /* Total size of file in bytes */
          904  +  int nRead;                      /* Bytes to read from file */
          905  +  i64 iOff;                       /* Offset to read from */
          906  +  int rc;
          907  +
          908  +  fseek(pFile, 0, SEEK_END);
          909  +  szFile = (i64)ftell(pFile);
          910  +  if( szFile==0 ){
          911  +    memset(pEOCD, 0, sizeof(ZipfileEOCD));
          912  +    return SQLITE_OK;
          913  +  }
          914  +  nRead = (int)(MIN(szFile, ZIPFILE_BUFFER_SIZE));
          915  +  iOff = szFile - nRead;
          916  +
          917  +  rc = zipfileReadData(pFile, aRead, nRead, iOff, &pTab->base.zErrMsg);
          918  +  if( rc==SQLITE_OK ){
          919  +    int i;
          920  +
          921  +    /* Scan backwards looking for the signature bytes */
          922  +    for(i=nRead-20; i>=0; i--){
          923  +      if( aRead[i]==0x50 && aRead[i+1]==0x4b 
          924  +       && aRead[i+2]==0x05 && aRead[i+3]==0x06 
          925  +      ){
          926  +        break;
          927  +      }
          928  +    }
          929  +    if( i<0 ){
          930  +      pTab->base.zErrMsg = sqlite3_mprintf(
          931  +          "cannot find end of central directory record"
          932  +      );
          933  +      return SQLITE_ERROR;
          934  +    }
          935  +
          936  +    aRead += i+4;
          937  +    pEOCD->iDisk = zipfileRead16(aRead);
          938  +    pEOCD->iFirstDisk = zipfileRead16(aRead);
          939  +    pEOCD->nEntry = zipfileRead16(aRead);
          940  +    pEOCD->nEntryTotal = zipfileRead16(aRead);
          941  +    pEOCD->nSize = zipfileRead32(aRead);
          942  +    pEOCD->iOffset = zipfileRead32(aRead);
          943  +
          944  +#if 0
          945  +    printf("iDisk=%d  iFirstDisk=%d  nEntry=%d  "
          946  +           "nEntryTotal=%d  nSize=%d  iOffset=%d", 
          947  +           (int)pEOCD->iDisk, (int)pEOCD->iFirstDisk, (int)pEOCD->nEntry,
          948  +           (int)pEOCD->nEntryTotal, (int)pEOCD->nSize, (int)pEOCD->iOffset
          949  +    );
          950  +#endif
          951  +  }
          952  +
          953  +  return SQLITE_OK;
          954  +}
          955  +
          956  +/*
          957  +** xFilter callback.
          958  +*/
          959  +static int zipfileFilter(
          960  +  sqlite3_vtab_cursor *cur, 
          961  +  int idxNum, const char *idxStr,
          962  +  int argc, sqlite3_value **argv
          963  +){
          964  +  ZipfileTab *pTab = (ZipfileTab*)cur->pVtab;
          965  +  ZipfileCsr *pCsr = (ZipfileCsr*)cur;
          966  +  const char *zFile;              /* Zip file to scan */
          967  +  int rc = SQLITE_OK;             /* Return Code */
          968  +
          969  +  zipfileResetCursor(pCsr);
          970  +
          971  +  if( pTab->zFile ){
          972  +    zFile = pTab->zFile;
          973  +  }else if( idxNum==0 ){
          974  +    /* Error. This is an eponymous virtual table and the user has not 
          975  +    ** supplied a file name. */
          976  +    zipfileSetErrmsg(pCsr, "table function zipfile() requires an argument");
          977  +    return SQLITE_ERROR;
          978  +  }else{
          979  +    zFile = (const char*)sqlite3_value_text(argv[0]);
          980  +  }
          981  +
          982  +  if( pTab->pWriteFd==0 ){
          983  +    pCsr->pFile = fopen(zFile, "rb");
          984  +    if( pCsr->pFile==0 ){
          985  +      zipfileSetErrmsg(pCsr, "cannot open file: %s", zFile);
          986  +      rc = SQLITE_ERROR;
          987  +    }else{
          988  +      rc = zipfileReadEOCD(pTab, pCsr->pFile, &pCsr->eocd);
          989  +      if( rc==SQLITE_OK ){
          990  +        if( pCsr->eocd.nEntry==0 ){
          991  +          pCsr->bEof = 1;
          992  +        }else{
          993  +          pCsr->iNextOff = pCsr->eocd.iOffset;
          994  +          rc = zipfileNext(cur);
          995  +        }
          996  +      }
          997  +    }
          998  +  }else{
          999  +    ZipfileEntry e;
         1000  +    memset(&e, 0, sizeof(e));
         1001  +    e.pNext = pTab->pFirstEntry;
         1002  +    pCsr->pCurrent = &e;
         1003  +    rc = zipfileNext(cur);
         1004  +    assert( pCsr->pCurrent!=&e );
         1005  +  }
         1006  +
         1007  +  return rc;
         1008  +}
         1009  +
         1010  +/*
         1011  +** xBestIndex callback.
         1012  +*/
         1013  +static int zipfileBestIndex(
         1014  +  sqlite3_vtab *tab,
         1015  +  sqlite3_index_info *pIdxInfo
         1016  +){
         1017  +  int i;
         1018  +
         1019  +  for(i=0; i<pIdxInfo->nConstraint; i++){
         1020  +    const struct sqlite3_index_constraint *pCons = &pIdxInfo->aConstraint[i];
         1021  +    if( pCons->usable==0 ) continue;
         1022  +    if( pCons->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
         1023  +    if( pCons->iColumn!=ZIPFILE_F_COLUMN_IDX ) continue;
         1024  +    break;
         1025  +  }
         1026  +
         1027  +  if( i<pIdxInfo->nConstraint ){
         1028  +    pIdxInfo->aConstraintUsage[i].argvIndex = 1;
         1029  +    pIdxInfo->aConstraintUsage[i].omit = 1;
         1030  +    pIdxInfo->estimatedCost = 1000.0;
         1031  +    pIdxInfo->idxNum = 1;
         1032  +  }else{
         1033  +    pIdxInfo->estimatedCost = (double)(((sqlite3_int64)1) << 50);
         1034  +    pIdxInfo->idxNum = 0;
         1035  +  }
         1036  +
         1037  +  return SQLITE_OK;
         1038  +}
         1039  +
         1040  +/*
         1041  +** Add object pNew to the end of the linked list that begins at
         1042  +** ZipfileTab.pFirstEntry and ends with pLastEntry.
         1043  +*/
         1044  +static void zipfileAddEntry(
         1045  +  ZipfileTab *pTab, 
         1046  +  ZipfileEntry *pBefore, 
         1047  +  ZipfileEntry *pNew
         1048  +){
         1049  +  assert( (pTab->pFirstEntry==0)==(pTab->pLastEntry==0) );
         1050  +  assert( pNew->pNext==0 );
         1051  +  if( pBefore==0 ){
         1052  +    if( pTab->pFirstEntry==0 ){
         1053  +      pTab->pFirstEntry = pTab->pLastEntry = pNew;
         1054  +    }else{
         1055  +      assert( pTab->pLastEntry->pNext==0 );
         1056  +      pTab->pLastEntry->pNext = pNew;
         1057  +      pTab->pLastEntry = pNew;
         1058  +    }
         1059  +  }else{
         1060  +    ZipfileEntry **pp;
         1061  +    for(pp=&pTab->pFirstEntry; *pp!=pBefore; pp=&((*pp)->pNext));
         1062  +    pNew->pNext = pBefore;
         1063  +    *pp = pNew;
         1064  +  }
         1065  +}
         1066  +
         1067  +static int zipfileLoadDirectory(ZipfileTab *pTab){
         1068  +  ZipfileEOCD eocd;
         1069  +  int rc;
         1070  +
         1071  +  rc = zipfileReadEOCD(pTab, pTab->pWriteFd, &eocd);
         1072  +  if( rc==SQLITE_OK && eocd.nEntry>0 ){
         1073  +    int i;
         1074  +    int iOff = 0;
         1075  +    u8 *aBuf = sqlite3_malloc(eocd.nSize);
         1076  +    if( aBuf==0 ){
         1077  +      rc = SQLITE_NOMEM;
         1078  +    }else{
         1079  +      rc = zipfileReadData(
         1080  +          pTab->pWriteFd, aBuf, eocd.nSize, eocd.iOffset, &pTab->base.zErrMsg
         1081  +      );
         1082  +    }
         1083  +
         1084  +    for(i=0; rc==SQLITE_OK && i<eocd.nEntry; i++){
         1085  +      u16 nFile;
         1086  +      u16 nExtra;
         1087  +      u16 nComment;
         1088  +      ZipfileEntry *pNew;
         1089  +      u8 *aRec = &aBuf[iOff];
         1090  +
         1091  +      nFile = zipfileGetU16(&aRec[ZIPFILE_CDS_NFILE_OFF]);
         1092  +      nExtra = zipfileGetU16(&aRec[ZIPFILE_CDS_NFILE_OFF+2]);
         1093  +      nComment = zipfileGetU16(&aRec[ZIPFILE_CDS_NFILE_OFF+4]);
         1094  +
         1095  +      pNew = sqlite3_malloc(
         1096  +          sizeof(ZipfileEntry) 
         1097  +        + nFile+1 
         1098  +        + ZIPFILE_CDS_FIXED_SZ+nFile+nExtra+nComment
         1099  +      );
         1100  +      if( pNew==0 ){
         1101  +        rc = SQLITE_NOMEM;
         1102  +      }else{
         1103  +        memset(pNew, 0, sizeof(ZipfileEntry));
         1104  +        pNew->zPath = (char*)&pNew[1];
         1105  +        memcpy(pNew->zPath, &aRec[ZIPFILE_CDS_FIXED_SZ], nFile);
         1106  +        pNew->zPath[nFile] = '\0';
         1107  +        pNew->aCdsEntry = (u8*)&pNew->zPath[nFile+1];
         1108  +        pNew->nCdsEntry = ZIPFILE_CDS_FIXED_SZ+nFile+nExtra+nComment;
         1109  +        memcpy(pNew->aCdsEntry, aRec, pNew->nCdsEntry);
         1110  +        zipfileAddEntry(pTab, 0, pNew);
         1111  +      }
         1112  +
         1113  +      iOff += ZIPFILE_CDS_FIXED_SZ+nFile+nExtra+nComment;
         1114  +    }
         1115  +
         1116  +    sqlite3_free(aBuf);
         1117  +  }
         1118  +
         1119  +  return rc;
         1120  +}
         1121  +
         1122  +static ZipfileEntry *zipfileNewEntry(
         1123  +  ZipfileCDS *pCds,               /* Values for fixed size part of CDS */
         1124  +  const char *zPath,              /* Path for new entry */
         1125  +  int nPath,                      /* strlen(zPath) */
         1126  +  u32 mTime                       /* Modification time (or 0) */
         1127  +){
         1128  +  u8 *aWrite;
         1129  +  ZipfileEntry *pNew;
         1130  +  pCds->nFile = (u16)nPath;
         1131  +  pCds->nExtra = mTime ? 9 : 0;
         1132  +  pNew = (ZipfileEntry*)sqlite3_malloc(
         1133  +    sizeof(ZipfileEntry) + 
         1134  +    nPath+1 + 
         1135  +    ZIPFILE_CDS_FIXED_SZ + nPath + pCds->nExtra
         1136  +  );
         1137  +
         1138  +  if( pNew ){
         1139  +    memset(pNew, 0, sizeof(ZipfileEntry));
         1140  +    pNew->zPath = (char*)&pNew[1];
         1141  +    pNew->aCdsEntry = (u8*)&pNew->zPath[nPath+1];
         1142  +    pNew->nCdsEntry = ZIPFILE_CDS_FIXED_SZ + nPath + pCds->nExtra;
         1143  +    memcpy(pNew->zPath, zPath, nPath+1);
         1144  +
         1145  +    aWrite = pNew->aCdsEntry;
         1146  +    zipfileWrite32(aWrite, ZIPFILE_SIGNATURE_CDS);
         1147  +    zipfileWrite16(aWrite, pCds->iVersionMadeBy);
         1148  +    zipfileWrite16(aWrite, pCds->iVersionExtract);
         1149  +    zipfileWrite16(aWrite, pCds->flags);
         1150  +    zipfileWrite16(aWrite, pCds->iCompression);
         1151  +    zipfileWrite16(aWrite, pCds->mTime);
         1152  +    zipfileWrite16(aWrite, pCds->mDate);
         1153  +    zipfileWrite32(aWrite, pCds->crc32);
         1154  +    zipfileWrite32(aWrite, pCds->szCompressed);
         1155  +    zipfileWrite32(aWrite, pCds->szUncompressed);
         1156  +    zipfileWrite16(aWrite, pCds->nFile);
         1157  +    zipfileWrite16(aWrite, pCds->nExtra);
         1158  +    zipfileWrite16(aWrite, pCds->nComment);      assert( pCds->nComment==0 );
         1159  +    zipfileWrite16(aWrite, pCds->iDiskStart);
         1160  +    zipfileWrite16(aWrite, pCds->iInternalAttr);
         1161  +    zipfileWrite32(aWrite, pCds->iExternalAttr);
         1162  +    zipfileWrite32(aWrite, pCds->iOffset);
         1163  +    assert( aWrite==&pNew->aCdsEntry[ZIPFILE_CDS_FIXED_SZ] );
         1164  +    memcpy(aWrite, zPath, nPath);
         1165  +    if( pCds->nExtra ){
         1166  +      aWrite += nPath;
         1167  +      zipfileWrite16(aWrite, ZIPFILE_EXTRA_TIMESTAMP);
         1168  +      zipfileWrite16(aWrite, 5);
         1169  +      *aWrite++ = 0x01;
         1170  +      zipfileWrite32(aWrite, mTime);
         1171  +    }
         1172  +  }
         1173  +
         1174  +  return pNew;
         1175  +}
         1176  +
         1177  +static int zipfileAppendEntry(
         1178  +  ZipfileTab *pTab,
         1179  +  ZipfileCDS *pCds,
         1180  +  const char *zPath,              /* Path for new entry */
         1181  +  int nPath,                      /* strlen(zPath) */
         1182  +  const u8 *pData,
         1183  +  int nData,
         1184  +  u32 mTime
         1185  +){
         1186  +  u8 *aBuf = pTab->aBuffer;
         1187  +  int rc;
         1188  +
         1189  +  zipfileWrite32(aBuf, ZIPFILE_SIGNATURE_LFH);
         1190  +  zipfileWrite16(aBuf, pCds->iVersionExtract);
         1191  +  zipfileWrite16(aBuf, pCds->flags);
         1192  +  zipfileWrite16(aBuf, pCds->iCompression);
         1193  +  zipfileWrite16(aBuf, pCds->mTime);
         1194  +  zipfileWrite16(aBuf, pCds->mDate);
         1195  +  zipfileWrite32(aBuf, pCds->crc32);
         1196  +  zipfileWrite32(aBuf, pCds->szCompressed);
         1197  +  zipfileWrite32(aBuf, pCds->szUncompressed);
         1198  +  zipfileWrite16(aBuf, (u16)nPath);
         1199  +  zipfileWrite16(aBuf, pCds->nExtra);
         1200  +  assert( aBuf==&pTab->aBuffer[ZIPFILE_LFH_FIXED_SZ] );
         1201  +  rc = zipfileAppendData(pTab, pTab->aBuffer, (int)(aBuf - pTab->aBuffer));
         1202  +  if( rc==SQLITE_OK ){
         1203  +    rc = zipfileAppendData(pTab, (const u8*)zPath, nPath);
         1204  +  }
         1205  +
         1206  +  if( rc==SQLITE_OK && pCds->nExtra ){
         1207  +    aBuf = pTab->aBuffer;
         1208  +    zipfileWrite16(aBuf, ZIPFILE_EXTRA_TIMESTAMP);
         1209  +    zipfileWrite16(aBuf, 5);
         1210  +    *aBuf++ = 0x01;
         1211  +    zipfileWrite32(aBuf, mTime);
         1212  +    rc = zipfileAppendData(pTab, pTab->aBuffer, 9);
         1213  +  }
         1214  +
         1215  +  if( rc==SQLITE_OK ){
         1216  +    rc = zipfileAppendData(pTab, pData, nData);
         1217  +  }
         1218  +
         1219  +  return rc;
         1220  +}
         1221  +
         1222  +static int zipfileGetMode(
         1223  +  ZipfileTab *pTab, 
         1224  +  sqlite3_value *pVal, 
         1225  +  u32 defaultMode,                /* Value to use if pVal IS NULL */
         1226  +  u32 *pMode
         1227  +){
         1228  +  const char *z = (const char*)sqlite3_value_text(pVal);
         1229  +  u32 mode = 0;
         1230  +  if( z==0 ){
         1231  +    mode = defaultMode;
         1232  +  }else if( z[0]>='0' && z[0]<='9' ){
         1233  +    mode = (unsigned int)sqlite3_value_int(pVal);
         1234  +  }else{
         1235  +    const char zTemplate[11] = "-rwxrwxrwx";
         1236  +    int i;
         1237  +    if( strlen(z)!=10 ) goto parse_error;
         1238  +    switch( z[0] ){
         1239  +      case '-': mode |= S_IFREG; break;
         1240  +      case 'd': mode |= S_IFDIR; break;
         1241  +#if !defined(_WIN32) && !defined(WIN32)
         1242  +      case 'l': mode |= S_IFLNK; break;
         1243  +#endif
         1244  +      default: goto parse_error;
         1245  +    }
         1246  +    for(i=1; i<10; i++){
         1247  +      if( z[i]==zTemplate[i] ) mode |= 1 << (9-i);
         1248  +      else if( z[i]!='-' ) goto parse_error;
         1249  +    }
         1250  +  }
         1251  +  *pMode = mode;
         1252  +  return SQLITE_OK;
         1253  +
         1254  + parse_error:
         1255  +  pTab->base.zErrMsg = sqlite3_mprintf("zipfile: parse error in mode: %s", z);
         1256  +  return SQLITE_ERROR;
         1257  +}
         1258  +
         1259  +/*
         1260  +** Both (const char*) arguments point to nul-terminated strings. Argument
         1261  +** nB is the value of strlen(zB). This function returns 0 if the strings are
         1262  +** identical, ignoring any trailing '/' character in either path.  */
         1263  +static int zipfileComparePath(const char *zA, const char *zB, int nB){
         1264  +  int nA = (int)strlen(zA);
         1265  +  if( zA[nA-1]=='/' ) nA--;
         1266  +  if( zB[nB-1]=='/' ) nB--;
         1267  +  if( nA==nB && memcmp(zA, zB, nA)==0 ) return 0;
         1268  +  return 1;
         1269  +}
         1270  +
         1271  +/*
         1272  +** xUpdate method.
         1273  +*/
         1274  +static int zipfileUpdate(
         1275  +  sqlite3_vtab *pVtab, 
         1276  +  int nVal, 
         1277  +  sqlite3_value **apVal, 
         1278  +  sqlite_int64 *pRowid
         1279  +){
         1280  +  ZipfileTab *pTab = (ZipfileTab*)pVtab;
         1281  +  int rc = SQLITE_OK;             /* Return Code */
         1282  +  ZipfileEntry *pNew = 0;         /* New in-memory CDS entry */
         1283  +
         1284  +  u32 mode = 0;                   /* Mode for new entry */
         1285  +  i64 mTime = 0;                  /* Modification time for new entry */
         1286  +  i64 sz = 0;                     /* Uncompressed size */
         1287  +  const char *zPath = 0;          /* Path for new entry */
         1288  +  int nPath = 0;                  /* strlen(zPath) */
         1289  +  const u8 *pData = 0;            /* Pointer to buffer containing content */
         1290  +  int nData = 0;                  /* Size of pData buffer in bytes */
         1291  +  int iMethod = 0;                /* Compression method for new entry */
         1292  +  u8 *pFree = 0;                  /* Free this */
         1293  +  char *zFree = 0;                /* Also free this */
         1294  +  ZipfileCDS cds;                 /* New Central Directory Structure entry */
         1295  +  ZipfileEntry *pOld = 0;
         1296  +  int bIsDir = 0;
         1297  +  u32 iCrc32 = 0;
         1298  +
         1299  +  assert( pTab->zFile );
         1300  +  assert( pTab->pWriteFd );
         1301  +
         1302  +  if( sqlite3_value_type(apVal[0])!=SQLITE_NULL ){
         1303  +    const char *zDelete = (const char*)sqlite3_value_text(apVal[0]);
         1304  +    int nDelete = (int)strlen(zDelete);
         1305  +    for(pOld=pTab->pFirstEntry; 1; pOld=pOld->pNext){
         1306  +      if( pOld->bDeleted ) continue;
         1307  +      if( zipfileComparePath(pOld->zPath, zDelete, nDelete)==0 ){
         1308  +        pOld->bDeleted = 1;
         1309  +        break;
         1310  +      }
         1311  +      assert( pOld->pNext );
         1312  +    }
         1313  +    if( nVal==1 ) return SQLITE_OK;
         1314  +  }
         1315  +
         1316  +  /* Check that "sz" and "rawdata" are both NULL: */
         1317  +  if( sqlite3_value_type(apVal[5])!=SQLITE_NULL
         1318  +   || sqlite3_value_type(apVal[6])!=SQLITE_NULL
         1319  +  ){
         1320  +    rc = SQLITE_CONSTRAINT;
         1321  +  }
         1322  +
         1323  +  if( rc==SQLITE_OK ){
         1324  +    if( sqlite3_value_type(apVal[7])==SQLITE_NULL ){
         1325  +      /* data=NULL. A directory */
         1326  +      bIsDir = 1;
         1327  +    }else{
         1328  +      /* Value specified for "data", and possibly "method". This must be
         1329  +      ** a regular file or a symlink. */
         1330  +      const u8 *aIn = sqlite3_value_blob(apVal[7]);
         1331  +      int nIn = sqlite3_value_bytes(apVal[7]);
         1332  +      int bAuto = sqlite3_value_type(apVal[8])==SQLITE_NULL;
         1333  +
         1334  +      iMethod = sqlite3_value_int(apVal[8]);
         1335  +      sz = nIn;
         1336  +      pData = aIn;
         1337  +      nData = nIn;
         1338  +      if( iMethod!=0 && iMethod!=8 ){
         1339  +        rc = SQLITE_CONSTRAINT;
         1340  +      }else{
         1341  +        if( bAuto || iMethod ){
         1342  +          int nCmp;
         1343  +          rc = zipfileDeflate(pTab, aIn, nIn, &pFree, &nCmp);
         1344  +          if( rc==SQLITE_OK ){
         1345  +            if( iMethod || nCmp<nIn ){
         1346  +              iMethod = 8;
         1347  +              pData = pFree;
         1348  +              nData = nCmp;
         1349  +            }
         1350  +          }
         1351  +        }
         1352  +        iCrc32 = crc32(0, aIn, nIn);
         1353  +      }
         1354  +    }
         1355  +  }
         1356  +
         1357  +  if( rc==SQLITE_OK ){
         1358  +    rc = zipfileGetMode(pTab, apVal[3], 
         1359  +        (bIsDir ? (S_IFDIR + 0755) : (S_IFREG + 0644)), &mode
         1360  +    );
         1361  +    if( rc==SQLITE_OK && (bIsDir == ((mode & S_IFDIR)==0)) ){
         1362  +      /* The "mode" attribute is a directory, but data has been specified.
         1363  +      ** Or vice-versa - no data but "mode" is a file or symlink.  */
         1364  +      rc = SQLITE_CONSTRAINT;
         1365  +    }
         1366  +  }
         1367  +
         1368  +  if( rc==SQLITE_OK ){
         1369  +    zPath = (const char*)sqlite3_value_text(apVal[2]);
         1370  +    nPath = (int)strlen(zPath);
         1371  +    if( sqlite3_value_type(apVal[4])==SQLITE_NULL ){
         1372  +      mTime = (sqlite3_int64)time(0);
         1373  +    }else{
         1374  +      mTime = sqlite3_value_int64(apVal[4]);
         1375  +    }
         1376  +  }
         1377  +
         1378  +  if( rc==SQLITE_OK && bIsDir ){
         1379  +    /* For a directory, check that the last character in the path is a
         1380  +    ** '/'. This appears to be required for compatibility with info-zip
         1381  +    ** (the unzip command on unix). It does not create directories
         1382  +    ** otherwise.  */
         1383  +    if( zPath[nPath-1]!='/' ){
         1384  +      zFree = sqlite3_mprintf("%s/", zPath);
         1385  +      if( zFree==0 ){ rc = SQLITE_NOMEM; }
         1386  +      zPath = (const char*)zFree;
         1387  +      nPath++;
         1388  +    }
         1389  +  }
         1390  +
         1391  +  /* Check that we're not inserting a duplicate entry */
         1392  +  if( rc==SQLITE_OK ){
         1393  +    ZipfileEntry *p;
         1394  +    for(p=pTab->pFirstEntry; p; p=p->pNext){
         1395  +      if( p->bDeleted ) continue;
         1396  +      if( zipfileComparePath(p->zPath, zPath, nPath)==0 ){
         1397  +        rc = SQLITE_CONSTRAINT;
         1398  +        break;
         1399  +      }
         1400  +    }
         1401  +  }
         1402  +
         1403  +  if( rc==SQLITE_OK ){
         1404  +    /* Create the new CDS record. */
         1405  +    memset(&cds, 0, sizeof(cds));
         1406  +    cds.iVersionMadeBy = ZIPFILE_NEWENTRY_MADEBY;
         1407  +    cds.iVersionExtract = ZIPFILE_NEWENTRY_REQUIRED;
         1408  +    cds.flags = ZIPFILE_NEWENTRY_FLAGS;
         1409  +    cds.iCompression = (u16)iMethod;
         1410  +    zipfileMtimeToDos(&cds, (u32)mTime);
         1411  +    cds.crc32 = iCrc32;
         1412  +    cds.szCompressed = nData;
         1413  +    cds.szUncompressed = (u32)sz;
         1414  +    cds.iExternalAttr = (mode<<16);
         1415  +    cds.iOffset = (u32)pTab->szCurrent;
         1416  +    pNew = zipfileNewEntry(&cds, zPath, nPath, (u32)mTime);
         1417  +    if( pNew==0 ){
         1418  +      rc = SQLITE_NOMEM;
         1419  +    }else{
         1420  +      zipfileAddEntry(pTab, pOld, pNew);
         1421  +    }
         1422  +  }
         1423  +
         1424  +  /* Append the new header+file to the archive */
         1425  +  if( rc==SQLITE_OK ){
         1426  +    rc = zipfileAppendEntry(pTab, &cds, zPath, nPath, pData, nData, (u32)mTime);
         1427  +  }
         1428  +
         1429  +  if( rc!=SQLITE_OK && pOld ){
         1430  +    pOld->bDeleted = 0;
         1431  +  }
         1432  +  sqlite3_free(pFree);
         1433  +  sqlite3_free(zFree);
         1434  +  return rc;
         1435  +}
         1436  +
         1437  +static int zipfileAppendEOCD(ZipfileTab *pTab, ZipfileEOCD *p){
         1438  +  u8 *aBuf = pTab->aBuffer;
         1439  +
         1440  +  zipfileWrite32(aBuf, ZIPFILE_SIGNATURE_EOCD);
         1441  +  zipfileWrite16(aBuf, p->iDisk);
         1442  +  zipfileWrite16(aBuf, p->iFirstDisk);
         1443  +  zipfileWrite16(aBuf, p->nEntry);
         1444  +  zipfileWrite16(aBuf, p->nEntryTotal);
         1445  +  zipfileWrite32(aBuf, p->nSize);
         1446  +  zipfileWrite32(aBuf, p->iOffset);
         1447  +  zipfileWrite16(aBuf, 0);        /* Size of trailing comment in bytes*/
         1448  +
         1449  +  assert( (aBuf-pTab->aBuffer)==22 );
         1450  +  return zipfileAppendData(pTab, pTab->aBuffer, (int)(aBuf - pTab->aBuffer));
         1451  +}
         1452  +
         1453  +static void zipfileCleanupTransaction(ZipfileTab *pTab){
         1454  +  ZipfileEntry *pEntry;
         1455  +  ZipfileEntry *pNext;
         1456  +
         1457  +  for(pEntry=pTab->pFirstEntry; pEntry; pEntry=pNext){
         1458  +    pNext = pEntry->pNext;
         1459  +    sqlite3_free(pEntry);
         1460  +  }
         1461  +  pTab->pFirstEntry = 0;
         1462  +  pTab->pLastEntry = 0;
         1463  +  fclose(pTab->pWriteFd);
         1464  +  pTab->pWriteFd = 0;
         1465  +  pTab->szCurrent = 0;
         1466  +  pTab->szOrig = 0;
         1467  +}
         1468  +
         1469  +static int zipfileBegin(sqlite3_vtab *pVtab){
         1470  +  ZipfileTab *pTab = (ZipfileTab*)pVtab;
         1471  +  int rc = SQLITE_OK;
         1472  +
         1473  +  assert( pTab->pWriteFd==0 );
         1474  +
         1475  +  /* This table is only writable if a default archive path was specified 
         1476  +  ** as part of the CREATE VIRTUAL TABLE statement. */
         1477  +  if( pTab->zFile==0 ){
         1478  +    pTab->base.zErrMsg = sqlite3_mprintf(
         1479  +        "zipfile: writing requires a default archive"
         1480  +    );
         1481  +    return SQLITE_ERROR;
         1482  +  }
         1483  +
         1484  +  /* Open a write fd on the file. Also load the entire central directory
         1485  +  ** structure into memory. During the transaction any new file data is 
         1486  +  ** appended to the archive file, but the central directory is accumulated
         1487  +  ** in main-memory until the transaction is committed.  */
         1488  +  pTab->pWriteFd = fopen(pTab->zFile, "ab+");
         1489  +  if( pTab->pWriteFd==0 ){
         1490  +    pTab->base.zErrMsg = sqlite3_mprintf(
         1491  +        "zipfile: failed to open file %s for writing", pTab->zFile
         1492  +    );
         1493  +    rc = SQLITE_ERROR;
         1494  +  }else{
         1495  +    fseek(pTab->pWriteFd, 0, SEEK_END);
         1496  +    pTab->szCurrent = pTab->szOrig = (i64)ftell(pTab->pWriteFd);
         1497  +    rc = zipfileLoadDirectory(pTab);
         1498  +  }
         1499  +
         1500  +  if( rc!=SQLITE_OK ){
         1501  +    zipfileCleanupTransaction(pTab);
         1502  +  }
         1503  +
         1504  +  return rc;
         1505  +}
         1506  +
         1507  +static int zipfileCommit(sqlite3_vtab *pVtab){
         1508  +  ZipfileTab *pTab = (ZipfileTab*)pVtab;
         1509  +  int rc = SQLITE_OK;
         1510  +  if( pTab->pWriteFd ){
         1511  +    i64 iOffset = pTab->szCurrent;
         1512  +    ZipfileEntry *p;
         1513  +    ZipfileEOCD eocd;
         1514  +    int nEntry = 0;
         1515  +
         1516  +    /* Write out all undeleted entries */
         1517  +    for(p=pTab->pFirstEntry; rc==SQLITE_OK && p; p=p->pNext){
         1518  +      if( p->bDeleted ) continue;
         1519  +      rc = zipfileAppendData(pTab, p->aCdsEntry, p->nCdsEntry);
         1520  +      nEntry++;
         1521  +    }
         1522  +
         1523  +    /* Write out the EOCD record */
         1524  +    eocd.iDisk = 0;
         1525  +    eocd.iFirstDisk = 0;
         1526  +    eocd.nEntry = (u16)nEntry;
         1527  +    eocd.nEntryTotal = (u16)nEntry;
         1528  +    eocd.nSize = (u32)(pTab->szCurrent - iOffset);
         1529  +    eocd.iOffset = (u32)iOffset;
         1530  +    rc = zipfileAppendEOCD(pTab, &eocd);
         1531  +
         1532  +    zipfileCleanupTransaction(pTab);
         1533  +  }
         1534  +  return rc;
         1535  +}
         1536  +
         1537  +static int zipfileRollback(sqlite3_vtab *pVtab){
         1538  +  return zipfileCommit(pVtab);
         1539  +}
         1540  +
         1541  +static ZipfileCsr *zipfileFindCursor(ZipfileTab *pTab, i64 iId){
         1542  +  ZipfileCsr *pCsr;
         1543  +  for(pCsr=pTab->pCsrList; pCsr; pCsr=pCsr->pCsrNext){
         1544  +    if( iId==pCsr->iId ) break;
         1545  +  }
         1546  +  return pCsr;
         1547  +}
         1548  +
         1549  +static void zipfileFunctionCds(
         1550  +  sqlite3_context *context,
         1551  +  int argc,
         1552  +  sqlite3_value **argv
         1553  +){
         1554  +  ZipfileCsr *pCsr;
         1555  +  ZipfileTab *pTab = (ZipfileTab*)sqlite3_user_data(context);
         1556  +  assert( argc>0 );
         1557  +
         1558  +  pCsr = zipfileFindCursor(pTab, sqlite3_value_int64(argv[0]));
         1559  +  if( pCsr ){
         1560  +    ZipfileCDS *p = &pCsr->cds;
         1561  +    char *zRes = sqlite3_mprintf("{"
         1562  +        "\"version-made-by\" : %u, "
         1563  +        "\"version-to-extract\" : %u, "
         1564  +        "\"flags\" : %u, "
         1565  +        "\"compression\" : %u, "
         1566  +        "\"time\" : %u, "
         1567  +        "\"date\" : %u, "
         1568  +        "\"crc32\" : %u, "
         1569  +        "\"compressed-size\" : %u, "
         1570  +        "\"uncompressed-size\" : %u, "
         1571  +        "\"file-name-length\" : %u, "
         1572  +        "\"extra-field-length\" : %u, "
         1573  +        "\"file-comment-length\" : %u, "
         1574  +        "\"disk-number-start\" : %u, "
         1575  +        "\"internal-attr\" : %u, "
         1576  +        "\"external-attr\" : %u, "
         1577  +        "\"offset\" : %u }",
         1578  +        (u32)p->iVersionMadeBy, (u32)p->iVersionExtract,
         1579  +        (u32)p->flags, (u32)p->iCompression,
         1580  +        (u32)p->mTime, (u32)p->mDate,
         1581  +        (u32)p->crc32, (u32)p->szCompressed,
         1582  +        (u32)p->szUncompressed, (u32)p->nFile,
         1583  +        (u32)p->nExtra, (u32)p->nComment,
         1584  +        (u32)p->iDiskStart, (u32)p->iInternalAttr,
         1585  +        (u32)p->iExternalAttr, (u32)p->iOffset
         1586  +    );
         1587  +
         1588  +    if( zRes==0 ){
         1589  +      sqlite3_result_error_nomem(context);
         1590  +    }else{
         1591  +      sqlite3_result_text(context, zRes, -1, SQLITE_TRANSIENT);
         1592  +      sqlite3_free(zRes);
         1593  +    }
         1594  +  }
         1595  +}
         1596  +
         1597  +
         1598  +/*
         1599  +** xFindFunction method.
         1600  +*/
         1601  +static int zipfileFindFunction(
         1602  +  sqlite3_vtab *pVtab,            /* Virtual table handle */
         1603  +  int nArg,                       /* Number of SQL function arguments */
         1604  +  const char *zName,              /* Name of SQL function */
         1605  +  void (**pxFunc)(sqlite3_context*,int,sqlite3_value**), /* OUT: Result */
         1606  +  void **ppArg                    /* OUT: User data for *pxFunc */
         1607  +){
         1608  +  if( nArg>0 ){
         1609  +    if( sqlite3_stricmp("zipfile_cds", zName)==0 ){
         1610  +      *pxFunc = zipfileFunctionCds;
         1611  +      *ppArg = (void*)pVtab;
         1612  +      return 1;
         1613  +    }
         1614  +  }
         1615  +
         1616  +  return 0;
         1617  +}
         1618  +
         1619  +/*
         1620  +** Register the "zipfile" virtual table.
         1621  +*/
         1622  +static int zipfileRegister(sqlite3 *db){
         1623  +  static sqlite3_module zipfileModule = {
         1624  +    1,                         /* iVersion */
         1625  +    zipfileConnect,            /* xCreate */
         1626  +    zipfileConnect,            /* xConnect */
         1627  +    zipfileBestIndex,          /* xBestIndex */
         1628  +    zipfileDisconnect,         /* xDisconnect */
         1629  +    zipfileDisconnect,         /* xDestroy */
         1630  +    zipfileOpen,               /* xOpen - open a cursor */
         1631  +    zipfileClose,              /* xClose - close a cursor */
         1632  +    zipfileFilter,             /* xFilter - configure scan constraints */
         1633  +    zipfileNext,               /* xNext - advance a cursor */
         1634  +    zipfileEof,                /* xEof - check for end of scan */
         1635  +    zipfileColumn,             /* xColumn - read data */
         1636  +    zipfileRowid,              /* xRowid - read data */
         1637  +    zipfileUpdate,             /* xUpdate */
         1638  +    zipfileBegin,              /* xBegin */
         1639  +    0,                         /* xSync */
         1640  +    zipfileCommit,             /* xCommit */
         1641  +    zipfileRollback,           /* xRollback */
         1642  +    zipfileFindFunction,       /* xFindMethod */
         1643  +    0,                         /* xRename */
         1644  +  };
         1645  +
         1646  +  int rc = sqlite3_create_module(db, "zipfile"  , &zipfileModule, 0);
         1647  +  if( rc==SQLITE_OK ){
         1648  +    rc = sqlite3_overload_function(db, "zipfile_cds", -1);
         1649  +  }
         1650  +  return rc;
         1651  +}
         1652  +#else         /* SQLITE_OMIT_VIRTUALTABLE */
         1653  +# define zipfileRegister(x) SQLITE_OK
         1654  +#endif
         1655  +
         1656  +#ifdef _WIN32
         1657  +__declspec(dllexport)
         1658  +#endif
         1659  +int sqlite3_zipfile_init(
         1660  +  sqlite3 *db, 
         1661  +  char **pzErrMsg, 
         1662  +  const sqlite3_api_routines *pApi
         1663  +){
         1664  +  SQLITE_EXTENSION_INIT2(pApi);
         1665  +  (void)pzErrMsg;  /* Unused parameter */
         1666  +  return zipfileRegister(db);
         1667  +}

Added ext/rbu/rbumulti.test.

            1  +# 2018 January 11
            2  +#
            3  +# The author disclaims copyright to this source code.  In place of
            4  +# a legal notice, here is a blessing:
            5  +#
            6  +#    May you do good and not evil.
            7  +#    May you find forgiveness for yourself and forgive others.
            8  +#    May you share freely, never taking more than you give.
            9  +#
           10  +#***********************************************************************
           11  +#
           12  +# This file contains tests of multiple RBU operations running
           13  +# concurrently within the same process. 
           14  +#
           15  +
           16  +source [file join [file dirname [info script]] rbu_common.tcl]
           17  +set ::testprefix rbumulti
           18  +
           19  +db close
           20  +sqlite3_shutdown
           21  +sqlite3_config_uri 1
           22  +
           23  +autoinstall_test_functions
           24  +
           25  +proc build_db {db} {
           26  +  $db eval {
           27  +    CREATE TABLE t1(a PRIMARY KEY, b, c);
           28  +    CREATE INDEX i1 ON t1(b);
           29  +    CREATE INDEX i2 ON t1(c);
           30  +
           31  +    WITH s(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<500 )
           32  +    INSERT INTO t1 
           33  +    SELECT randomblob(10), randomblob(100), randomblob(100) FROM s;
           34  +  }
           35  +}
           36  +
           37  +proc build_rbu {db} {
           38  +  $db eval {
           39  +    CREATE TABLE data_t1(a, b, c, rbu_control);
           40  +    WITH s(i) AS ( SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<100 )
           41  +    INSERT INTO data_t1 
           42  +    SELECT randomblob(10), randomblob(100), randomblob(100), 0 FROM s;
           43  +  }
           44  +}
           45  +
           46  +proc step_rbu2 {bOpenClose openr1 openr2} {
           47  +
           48  +  forcedelete teststate.db1
           49  +  forcedelete teststate.db2
           50  +
           51  +  if {$bOpenClose!=0 && $bOpenClose!=1} { error $bOpenClose }
           52  +  if {$bOpenClose==0} {
           53  +    eval $openr1 
           54  +    eval $openr2 
           55  +  }
           56  +
           57  +  set b1 0
           58  +  set b2 0
           59  +
           60  +  while {$b1==0 || $b2==0} {
           61  +    if {$bOpenClose==1} {
           62  +      if {$b1==0} { eval $openr1 teststate.db1 }
           63  +      if {$b2==0} { eval $openr2 teststate.db2 }
           64  +    }
           65  +    if {$b1==0} {
           66  +      set rc1 [r1 step]
           67  +      if {$rc1 != "SQLITE_OK"} { set b1 1 }
           68  +    }
           69  +    if {$b2==0} {
           70  +      set rc2 [r2 step]
           71  +      if {$rc2 != "SQLITE_OK"} { set b2 1 }
           72  +    }
           73  +    if {$bOpenClose==1} {
           74  +      if {$b1==0} { r1 close }
           75  +      if {$b2==0} { r2 close }
           76  +    }
           77  +  }
           78  +
           79  +  set rc1 [r1 close]
           80  +  set rc2 [r2 close]
           81  +
           82  +  list $rc1 $rc2
           83  +}
           84  +
           85  +
           86  +for {set i 0} {$i<=3} {incr i} {
           87  +
           88  +  if {$i & 0x01} {
           89  +    sqlite3rbu_create_vfs -default myrbu ""
           90  +  }
           91  +  set bOpenClose [expr $i>>1]
           92  +
           93  +  forcedelete test.db
           94  +  forcedelete test.db2
           95  +  forcedelete rbu.db
           96  +  forcedelete rbu.db2
           97  +  
           98  +  do_test 1.$i.0 {
           99  +    sqlite3 db test.db
          100  +    sqlite3 db2 test.db2
          101  +    build_db db
          102  +    build_db db2
          103  +  
          104  +    sqlite3 rbu1 rbu.db
          105  +    sqlite3 rbu2 rbu.db2
          106  +  
          107  +    build_rbu rbu1
          108  +    build_rbu rbu2
          109  +  
          110  +    rbu1 close
          111  +    rbu2 close
          112  +  } {}
          113  +
          114  +  set m1 [db eval {SELECT md5sum(a, b, c) FROM t1}]
          115  +  set m2 [db2 eval {SELECT md5sum(a, b, c) FROM t1}]
          116  +  
          117  +  do_test 1.$i.1 {
          118  +    step_rbu2 $bOpenClose {
          119  +      sqlite3rbu r1 test.db rbu.db
          120  +    } {
          121  +      sqlite3rbu r2 test.db2 rbu.db2
          122  +    }
          123  +  } {SQLITE_DONE SQLITE_DONE}
          124  +  
          125  +  do_execsql_test -db db  1.$i.2.1 { PRAGMA integrity_check } ok
          126  +  do_execsql_test -db db2 1.$i.2.2 { PRAGMA integrity_check } ok
          127  +
          128  +  do_execsql_test -db db  1.$i.3.1 { SELECT md5sum(a, b, c)==$m1 FROM t1 } 0
          129  +  do_execsql_test -db db2 1.$i.3.2 { SELECT md5sum(a, b, c)==$m2 FROM t1 } 0
          130  +  
          131  +  catch { db close }
          132  +  catch { db2 close }
          133  +  #-----------------------------------------------------------------------
          134  +  forcedelete test.db2
          135  +  forcedelete test.db
          136  +  forcedelete rbu.db2
          137  +  
          138  +  do_test 1.$i.4 {
          139  +    sqlite3 db test.db
          140  +    sqlite3 db2 test.db2
          141  +    build_db db
          142  +    build_db db2
          143  +    sqlite3 rbu2 rbu.db2
          144  +    build_rbu rbu2
          145  +    rbu2 close
          146  +  } {}
          147  +
          148  +  set m1 [db eval {SELECT md5sum(a, b, c) FROM t1}]
          149  +  set m2 [db2 eval {SELECT md5sum(a, b, c) FROM t1}]
          150  +
          151  +  do_test 1.$i.5 {
          152  +    step_rbu2 $bOpenClose {
          153  +      sqlite3rbu_vacuum r1 test.db
          154  +    } {
          155  +      sqlite3rbu r2 test.db2 rbu.db2
          156  +    }
          157  +  } {SQLITE_DONE SQLITE_DONE}
          158  +
          159  +  do_execsql_test -db db  1.$i.6.1 { SELECT md5sum(a, b, c)==$m1 FROM t1 } 1
          160  +  do_execsql_test -db db2 1.$i.6.2 { SELECT md5sum(a, b, c)==$m2 FROM t1 } 0
          161  +
          162  +  do_execsql_test -db db  1.$i.7.1 { PRAGMA integrity_check } ok
          163  +  do_execsql_test -db db2 1.$i.7.2 { PRAGMA integrity_check } ok
          164  +
          165  +  catch { db close }
          166  +  catch { db2 close }
          167  +  if {$i & 0x01} {
          168  +    sqlite3rbu_destroy_vfs myrbu
          169  +  }
          170  +
          171  +}
          172  +
          173  +
          174  +finish_test
          175  +

Changes to ext/rtree/rtree.c.

    48     48   **   3. The remainder of the node contains the node entries. Each entry
    49     49   **      consists of a single 8-byte integer followed by an even number
    50     50   **      of 4-byte coordinates. For leaf nodes the integer is the rowid
    51     51   **      of a record. For internal nodes it is the node number of a
    52     52   **      child page.
    53     53   */
    54     54   
    55         -#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_RTREE)
           55  +#if !defined(SQLITE_CORE) \
           56  +  || (defined(SQLITE_ENABLE_RTREE) && !defined(SQLITE_OMIT_VIRTUALTABLE))
    56     57   
    57     58   #ifndef SQLITE_CORE
    58     59     #include "sqlite3ext.h"
    59     60     SQLITE_EXTENSION_INIT1
    60     61   #else
    61     62     #include "sqlite3.h"
    62     63   #endif

Changes to ext/rtree/rtree.h.

    10     10   **
    11     11   ******************************************************************************
    12     12   **
    13     13   ** This header file is used by programs that want to link against the
    14     14   ** RTREE library.  All it does is declare the sqlite3RtreeInit() interface.
    15     15   */
    16     16   #include "sqlite3.h"
           17  +
           18  +#ifdef SQLITE_OMIT_VIRTUALTABLE
           19  +# undef SQLITE_ENABLE_RTREE
           20  +#endif
    17     21   
    18     22   #ifdef __cplusplus
    19     23   extern "C" {
    20     24   #endif  /* __cplusplus */
    21     25   
    22     26   int sqlite3RtreeInit(sqlite3 *db);
    23     27   
    24     28   #ifdef __cplusplus
    25     29   }  /* extern "C" */
    26     30   #endif  /* __cplusplus */

Changes to ext/session/sessionD.test.

   217    217   do_test 4.2.2 {
   218    218     sqlite3session S db main
   219    219     S attach t2
   220    220     list [catch { S diff ixua t2 } msg] $msg
   221    221   } {1 {SQLITE_SCHEMA - table schemas do not match}}
   222    222   S delete
   223    223   
          224  +do_test 4.3.1 {
          225  +  sqlite3session S db main
          226  +  S attach t4
          227  +  execsql { CREATE TABLE t4(i PRIMARY KEY, b) }
          228  +  list [catch { S diff ixua t4 } msg] $msg
          229  +} {1 {SQLITE_SCHEMA - table schemas do not match}}
          230  +S delete
          231  +do_catchsql_test 4.3.2 {
          232  +  SELECT * FROM ixua.t4;
          233  +} {1 {no such table: ixua.t4}}
          234  +
          235  +do_test 4.4.1 {
          236  +  sqlite3session S db main
          237  +  S attach sqlite_stat1
          238  +  execsql { ANALYZE }
          239  +  execsql { DROP TABLE ixua.sqlite_stat1 }
          240  +  list [catch { S diff ixua sqlite_stat1 } msg] $msg
          241  +} {1 {SQLITE_SCHEMA - table schemas do not match}}
          242  +S delete
          243  +do_catchsql_test 4.4.2 {
          244  +  SELECT * FROM ixua.sqlite_stat1;
          245  +} {1 {no such table: ixua.sqlite_stat1}}
          246  +
          247  +do_test 4.5.1 {
          248  +  sqlite3session S db main
          249  +  S attach t8
          250  +  list [catch { S diff ixua t8 } msg] $msg
          251  +} {0 {}}
          252  +S delete
          253  +do_catchsql_test 4.5.2 {
          254  +  SELECT * FROM ixua.i8;
          255  +} {1 {no such table: ixua.i8}}
          256  +
   224    257   finish_test
   225    258   

Changes to ext/session/sessionG.test.

   168    168   
   169    169       UPDATE t2 SET b=3 WHERE a=3;
   170    170       UPDATE t2 SET b=2 WHERE a=2;
   171    171       UPDATE t2 SET b=1 WHERE a=1;
   172    172     }
   173    173     compare_db db db2
   174    174   } {}
          175  +
          176  +#-------------------------------------------------------------------------
          177  +reset_db 
          178  +catch { db2 close }
          179  +forcedelete test.db2
          180  +sqlite3 db2 test.db2
          181  +
          182  +do_execsql_test 5.0.1 {
          183  +  CREATE TABLE t1(a PRIMARY KEY, b, c);
          184  +  CREATE TABLE t2(a, b, c PRIMARY KEY);
          185  +  CREATE TABLE t3(a, b PRIMARY KEY, c);
          186  +}
          187  +do_execsql_test -db db2 5.0.2 {
          188  +  CREATE TABLE t1(a PRIMARY KEY, b, c);
          189  +  CREATE TABLE t2(a, b, c);
          190  +  CREATE TABLE t3(a, b PRIMARY KEY, c);
          191  +}
          192  +
          193  +do_test 5.1 {
          194  +  do_then_apply_sql {
          195  +    INSERT INTO t1 VALUES(1, 2, 3);
          196  +    INSERT INTO t2 VALUES(4, 5, 6);
          197  +    INSERT INTO t3 VALUES(7, 8, 9);
          198  +  }
          199  +
          200  +  db2 eval {
          201  +    SELECT * FROM t1;
          202  +    SELECT * FROM t2;
          203  +    SELECT * FROM t3;
          204  +  }
          205  +} {1 2 3 7 8 9}
          206  +
          207  +
          208  +
   175    209   
   176    210   finish_test
   177    211   

Added ext/session/sessionH.test.

            1  +# 2018 January 18
            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  +if {![info exists testdir]} {
           14  +  set testdir [file join [file dirname [info script]] .. .. test]
           15  +} 
           16  +source [file join [file dirname [info script]] session_common.tcl]
           17  +source $testdir/tester.tcl
           18  +ifcapable !session {finish_test; return}
           19  +set testprefix sessionH
           20  +
           21  +forcedelete test.db2
           22  +sqlite3 db2 test.db2
           23  +
           24  +do_test 1.0 {
           25  +  do_common_sql {
           26  +    CREATE TABLE t1(a, b, c, PRIMARY KEY(a, b));
           27  +  }
           28  +  do_then_apply_sql {
           29  +    WITH s(i) AS (
           30  +      VALUES(1) UNION ALL SELECT i+1 FROM s WHERe i<10000
           31  +    )
           32  +    INSERT INTO t1 SELECT 'abcde', randomblob(16), i FROM s;
           33  +  }
           34  +  compare_db db db2
           35  +} {}
           36  +
           37  +
           38  +finish_test
           39  +

Changes to ext/session/sessionat.test.

   237    237     do_test $tn.6.3 {
   238    238       sqlite3changeset_apply db $cinv xConflict
   239    239       execsql { SELECT * FROM t7 }
   240    240     } {1 1 ccc 2 2 ccc 3 3 ccc}
   241    241   }]
   242    242   }
   243    243   
          244  +catch { db close }
          245  +catch { db2 close }
          246  +sqlite3_shutdown
          247  +test_sqlite3_log
   244    248   
   245    249   finish_test

Added ext/session/sessionstat1.test.

            1  +# 2018 January 12
            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  +if {![info exists testdir]} {
           14  +  set testdir [file join [file dirname [info script]] .. .. test]
           15  +} 
           16  +source [file join [file dirname [info script]] session_common.tcl]
           17  +source $testdir/tester.tcl
           18  +ifcapable !session {finish_test; return}
           19  +
           20  +set testprefix sessionstat1
           21  +
           22  +do_execsql_test 1.0 {
           23  +  CREATE TABLE t1(a PRIMARY KEY, b, c);
           24  +  CREATE INDEX t1b ON t1(b);
           25  +  CREATE INDEX t1c ON t1(c);
           26  +
           27  +  WITH s(i) AS (
           28  +    SELECT 0 UNION ALL SELECT i+1 FROM s WHERE (i+1)<32
           29  +  )
           30  +  INSERT INTO t1 SELECT i, i%8, i%2 FROM s;
           31  +}
           32  +
           33  +do_iterator_test 1.1 {} {
           34  +  ANALYZE
           35  +} {
           36  +  {INSERT sqlite_stat1 0 XX. {} {t t1 t sqlite_autoindex_t1_1 t {32 1}}}
           37  +  {INSERT sqlite_stat1 0 XX. {} {t t1 t t1b t {32 4}}} 
           38  +  {INSERT sqlite_stat1 0 XX. {} {t t1 t t1c t {32 16}}}
           39  +}
           40  +
           41  +do_execsql_test 1.2 {
           42  +  WITH s(i) AS (
           43  +    SELECT 32 UNION ALL SELECT i+1 FROM s WHERE (i+1)<64
           44  +  )
           45  +  INSERT INTO t1 SELECT i, i%8, i%2 FROM s;
           46  +}
           47  +
           48  +do_iterator_test 1.3 {} {
           49  +  ANALYZE
           50  +} {
           51  +  {UPDATE sqlite_stat1 0 XX. {t t1 t sqlite_autoindex_t1_1 t {32 1}} {{} {} {} {} t {64 1}}} 
           52  +  {UPDATE sqlite_stat1 0 XX. {t t1 t t1b t {32 4}} {{} {} {} {} t {64 8}}} 
           53  +  {UPDATE sqlite_stat1 0 XX. {t t1 t t1c t {32 16}} {{} {} {} {} t {64 32}}}
           54  +}
           55  +
           56  +do_iterator_test 1.5 {} {
           57  +  DROP INDEX t1b;
           58  +} {
           59  +  {DELETE sqlite_stat1 0 XX. {t t1 t t1b t {64 8}} {}}
           60  +}
           61  +
           62  +do_iterator_test 1.6 {} {
           63  +  DROP TABLE t1;
           64  +} {
           65  +  {DELETE sqlite_stat1 0 XX. {t t1 t sqlite_autoindex_t1_1 t {64 1}} {}}
           66  +  {DELETE sqlite_stat1 0 XX. {t t1 t t1c t {64 32}} {}}
           67  +}
           68  +
           69  +#-------------------------------------------------------------------------
           70  +#
           71  +catch { db2 close }
           72  +forcedelete test.db2
           73  +sqlite3 db2 test.db2
           74  +
           75  +do_test 2.0 {
           76  +  do_common_sql {
           77  +    CREATE TABLE t1(a PRIMARY KEY, b, c);
           78  +    CREATE INDEX t1b ON t1(b);
           79  +    CREATE INDEX t1c ON t1(c);
           80  +    ANALYZE;
           81  +  }
           82  +} {}
           83  +
           84  +do_test 2.1 {
           85  +  do_then_apply_sql {
           86  +    WITH s(i) AS (
           87  +        SELECT 0 UNION ALL SELECT i+1 FROM s WHERE (i+1)<32
           88  +    )
           89  +    INSERT INTO t1 SELECT i, i%8, i%2 FROM s;
           90  +    ANALYZE;
           91  +  }
           92  +} {}
           93  +
           94  +do_execsql_test -db db2 2.2 {
           95  +  SELECT * FROM sqlite_stat1
           96  +} {
           97  +  t1 sqlite_autoindex_t1_1 {32 1} 
           98  +  t1 t1b {32 4} 
           99  +  t1 t1c {32 16}
          100  +}
          101  +
          102  +do_test 2.3 {
          103  +  do_then_apply_sql { DROP INDEX t1c }
          104  +} {}
          105  +
          106  +do_execsql_test -db db2 2.4 {
          107  +  SELECT * FROM sqlite_stat1
          108  +} {
          109  +  t1 sqlite_autoindex_t1_1 {32 1} 
          110  +  t1 t1b {32 4} 
          111  +}
          112  +
          113  +do_test 2.3 {
          114  +  do_then_apply_sql { DROP TABLE t1 }
          115  +} {}
          116  +
          117  +do_execsql_test -db db2 2.4 {
          118  +  SELECT * FROM sqlite_stat1
          119  +} {
          120  +}
          121  +
          122  +do_execsql_test -db db2 2.5 { SELECT count(*) FROM t1 } 32
          123  +
          124  +#-------------------------------------------------------------------------
          125  +db2 close
          126  +forcedelete test.db2
          127  +reset_db
          128  +sqlite3 db2 test.db2
          129  +
          130  +do_test 3.0 {
          131  +  do_common_sql {
          132  +    CREATE TABLE t1(a, b, c);
          133  +    ANALYZE;
          134  +    DELETE FROM sqlite_stat1;
          135  +  }
          136  +  execsql {
          137  +    INSERT INTO t1 VALUES(1, 1, 1);
          138  +    INSERT INTO t1 VALUES(2, 2, 2);
          139  +    INSERT INTO t1 VALUES(3, 3, 3);
          140  +    INSERT INTO t1 VALUES(4, 4, 4);
          141  +  }
          142  +} {} 
          143  +
          144  +do_iterator_test 3.1 {} {
          145  +  ANALYZE
          146  +} {
          147  +  {INSERT sqlite_stat1 0 XX. {} {t t1 b {} t 4}}
          148  +}
          149  +db null null
          150  +db2 null null
          151  +do_execsql_test 3.2 {
          152  +  SELECT * FROM sqlite_stat1;
          153  +} {t1 null 4}
          154  +do_test 3.3 {
          155  +  execsql { DELETE FROM sqlite_stat1 }
          156  +  do_then_apply_sql { ANALYZE }
          157  +  execsql { SELECT * FROM sqlite_stat1 } db2
          158  +} {t1 null 4}
          159  +do_test 3.4 {
          160  +  execsql { INSERT INTO t1 VALUES(5,5,5) }
          161  +  do_then_apply_sql { ANALYZE }
          162  +  execsql { SELECT * FROM sqlite_stat1 } db2
          163  +} {t1 null 5}
          164  +do_test 3.5 {
          165  +  do_then_apply_sql { DROP TABLE t1 }
          166  +  execsql { SELECT * FROM sqlite_stat1 } db2
          167  +} {}
          168  +
          169  +do_test 3.6.1 {
          170  +  execsql { 
          171  +    CREATE TABLE t1(a, b, c);
          172  +    CREATE TABLE t2(x, y, z);
          173  +    INSERT INTO t1 VALUES(1,1,1), (2,2,2), (3,3,3), (4,4,4), (5,5,5);
          174  +    INSERT INTO t2 SELECT * FROM t1;
          175  +    DELETE FROM sqlite_stat1;
          176  +  }
          177  +  sqlite3session S db main
          178  +  S attach sqlite_stat1
          179  +  execsql { ANALYZE }
          180  +} {}
          181  +do_changeset_test 3.6.2 S {
          182  +  {INSERT sqlite_stat1 0 XX. {} {t t2 b {} t 5}}
          183  +  {INSERT sqlite_stat1 0 XX. {} {t t1 b {} t 5}}
          184  +}
          185  +do_changeset_invert_test 3.6.3 S {
          186  +  {DELETE sqlite_stat1 0 XX. {t t2 b {} t 5} {}}
          187  +  {DELETE sqlite_stat1 0 XX. {t t1 b {} t 5} {}}
          188  +}
          189  +do_test 3.6.4 { S delete } {}
          190  +
          191  +proc sql_changeset_concat {args} {
          192  +  foreach sql $args {
          193  +    sqlite3session S db main
          194  +    S attach sqlite_stat1
          195  +    execsql $sql
          196  +    set change [S changeset]
          197  +    S delete
          198  +
          199  +    if {[info vars ret]!=""} {
          200  +      set ret [sqlite3changeset_concat $ret $change]
          201  +    } else {
          202  +      set ret $change
          203  +    }
          204  +  }
          205  +
          206  +  changeset_to_list $ret
          207  +}
          208  +
          209  +proc do_scc_test {tn args} {
          210  +  uplevel [list \
          211  +    do_test $tn [concat sql_changeset_concat [lrange $args 0 end-1]] \
          212  +    [list {*}[ lindex $args end ]]
          213  +  ]
          214  +}
          215  +
          216  +do_execsql_test 3.7.0 {
          217  +  DELETE FROM sqlite_stat1;
          218  +}
          219  +do_scc_test 3.7.1 {
          220  +  ANALYZE;
          221  +} {
          222  +  INSERT INTO t2 VALUES(6,6,6);
          223  +  ANALYZE;
          224  +} {
          225  +  {INSERT sqlite_stat1 0 XX. {} {t t1 b {} t 5}}
          226  +  {INSERT sqlite_stat1 0 XX. {} {t t2 b {} t 6}}
          227  +}
          228  +
          229  +#-------------------------------------------------------------------------
          230  +catch { db2 close }
          231  +reset_db
          232  +forcedelete test.db2
          233  +sqlite3 db2 test.db2
          234  +
          235  +do_test 4.1.0 {
          236  +  do_common_sql {
          237  +    CREATE TABLE t1(a, b);
          238  +    CREATE INDEX i1 ON t1(a);
          239  +    CREATE INDEX i2 ON t1(b);
          240  +    INSERT INTO t1 VALUES(1,1), (2,2);
          241  +    ANALYZE;
          242  +  }
          243  +  execsql { DELETE FROM sqlite_stat1 }
          244  +} {}
          245  +
          246  +do_test 4.1.1 {
          247  +  execsql { INSERT INTO t1 VALUES(3,3); }
          248  +  set C [changeset_from_sql {ANALYZE}]
          249  +  set ::c [list]
          250  +  proc xConflict {args} {
          251  +    lappend ::c $args
          252  +    return "OMIT"
          253  +  }
          254  +  sqlite3changeset_apply db2 $C xConflict
          255  +  set ::c
          256  +} [list {*}{
          257  +  {INSERT sqlite_stat1 CONFLICT {t t1 t i1 t {3 1}} {t t1 t i1 t {2 1}}}
          258  +  {INSERT sqlite_stat1 CONFLICT {t t1 t i2 t {3 1}} {t t1 t i2 t {2 1}}}
          259  +}]
          260  +
          261  +do_execsql_test -db db2 4.1.2 {
          262  +  SELECT * FROM sqlite_stat1 ORDER BY 1,2;
          263  +} {t1 i1 {2 1} t1 i2 {2 1}}
          264  +
          265  +do_test 4.1.3 {
          266  +  proc xConflict {args} {
          267  +    return "REPLACE"
          268  +  }
          269  +  sqlite3changeset_apply db2 $C xConflict
          270  +  execsql { SELECT * FROM sqlite_stat1 ORDER BY 1,2 } db2
          271  +} {t1 i1 {3 1} t1 i2 {3 1}}
          272  +
          273  +do_test 4.2.0 {
          274  +  do_common_sql { 
          275  +    DROP TABLE t1;
          276  +    CREATE TABLE t3(x,y);
          277  +    INSERT INTO t3 VALUES('a','a');
          278  +    INSERT INTO t3 VALUES('b','b');
          279  +    ANALYZE;
          280  +  }
          281  +  execsql { DELETE FROM sqlite_stat1 }
          282  +} {}
          283  +do_test 4.2.1 {
          284  +  execsql { INSERT INTO t3 VALUES('c','c'); }
          285  +  set C [changeset_from_sql {ANALYZE}]
          286  +  set ::c [list]
          287  +  proc xConflict {args} {
          288  +    lappend ::c $args
          289  +    return "OMIT"
          290  +  }
          291  +  sqlite3changeset_apply db2 $C xConflict
          292  +  set ::c
          293  +} [list {*}{
          294  +  {INSERT sqlite_stat1 CONFLICT {t t3 b {} t 3} {t t3 b {} t 2}}
          295  +}]
          296  +
          297  +db2 null null
          298  +do_execsql_test -db db2 4.2.2 {
          299  +  SELECT * FROM sqlite_stat1 ORDER BY 1,2;
          300  +} {t3 null 2}
          301  +
          302  +do_test 4.2.3 {
          303  +  proc xConflict {args} {
          304  +    return "REPLACE"
          305  +  }
          306  +  sqlite3changeset_apply db2 $C xConflict
          307  +  execsql { SELECT * FROM sqlite_stat1 ORDER BY 1,2 } db2
          308  +} {t3 null 3}
          309  +
          310  +finish_test
          311  +

Changes to ext/session/sqlite3session.c.

    42     42     char *zDb;                      /* Name of database session is attached to */
    43     43     int bEnable;                    /* True if currently recording */
    44     44     int bIndirect;                  /* True if all changes are indirect */
    45     45     int bAutoAttach;                /* True to auto-attach tables */
    46     46     int rc;                         /* Non-zero if an error has occurred */
    47     47     void *pFilterCtx;               /* First argument to pass to xTableFilter */
    48     48     int (*xTableFilter)(void *pCtx, const char *zTab);
           49  +  sqlite3_value *pZeroBlob;       /* Value containing X'' */
    49     50     sqlite3_session *pNext;         /* Next session object on same db. */
    50     51     SessionTable *pTable;           /* List of attached tables */
    51     52     SessionHook hook;               /* APIs to grab new and old data with */
    52     53   };
    53     54   
    54     55   /*
    55     56   ** Instances of this structure are used to build strings or binary records.
................................................................................
   109    110   ** a subset of the initial values that the modified row contained at the
   110    111   ** start of the session. Or no initial values if the row was inserted.
   111    112   */
   112    113   struct SessionTable {
   113    114     SessionTable *pNext;
   114    115     char *zName;                    /* Local name of table */
   115    116     int nCol;                       /* Number of columns in table zName */
          117  +  int bStat1;                     /* True if this is sqlite_stat1 */
   116    118     const char **azCol;             /* Column names */
   117    119     u8 *abPK;                       /* Array of primary key flags */
   118    120     int nEntry;                     /* Total number of entries in hash table */
   119    121     int nChange;                    /* Size of apChange[] array */
   120    122     SessionChange **apChange;       /* Hash table buckets */
   121    123   };
   122    124   
................................................................................
   492    494             z = (const u8 *)sqlite3_value_blob(pVal);
   493    495           }
   494    496           n = sqlite3_value_bytes(pVal);
   495    497           if( !z && (eType!=SQLITE_BLOB || n>0) ) return SQLITE_NOMEM;
   496    498           h = sessionHashAppendBlob(h, n, z);
   497    499         }else{
   498    500           assert( eType==SQLITE_NULL );
          501  +        assert( pTab->bStat1==0 || i!=1 );
   499    502           *pbNullPK = 1;
   500    503         }
   501    504       }
   502    505     }
   503    506   
   504    507     *piHash = (h % pTab->nChange);
   505    508     return SQLITE_OK;
................................................................................
   834    837           if( eType==SQLITE_TEXT ){
   835    838             z = sqlite3_value_text(pVal);
   836    839           }else{
   837    840             z = sqlite3_value_blob(pVal);
   838    841           }
   839    842           if( memcmp(a, z, n) ) return 0;
   840    843           a += n;
   841         -        break;
   842    844         }
   843    845       }
   844    846     }
   845    847   
   846    848     return 1;
   847    849   }
   848    850   
................................................................................
   890    892     }
   891    893   
   892    894     return SQLITE_OK;
   893    895   }
   894    896   
   895    897   /*
   896    898   ** This function queries the database for the names of the columns of table
   897         -** zThis, in schema zDb. It is expected that the table has nCol columns. If
   898         -** not, SQLITE_SCHEMA is returned and none of the output variables are
   899         -** populated.
          899  +** zThis, in schema zDb.
   900    900   **
   901    901   ** Otherwise, if they are not NULL, variable *pnCol is set to the number
   902    902   ** of columns in the database table and variable *pzTab is set to point to a
   903    903   ** nul-terminated copy of the table name. *pazCol (if not NULL) is set to
   904    904   ** point to an array of pointers to column names. And *pabPK (again, if not
   905    905   ** NULL) is set to point to an array of booleans - true if the corresponding
   906    906   ** column is part of the primary key.
................................................................................
   913    913   **
   914    914   **     *pnCol  = 4
   915    915   **     *pzTab  = "tbl1"
   916    916   **     *pazCol = {"w", "x", "y", "z"}
   917    917   **     *pabPK  = {1, 0, 0, 1}
   918    918   **
   919    919   ** All returned buffers are part of the same single allocation, which must
   920         -** be freed using sqlite3_free() by the caller. If pazCol was not NULL, then
   921         -** pointer *pazCol should be freed to release all memory. Otherwise, pointer
   922         -** *pabPK. It is illegal for both pazCol and pabPK to be NULL.
          920  +** be freed using sqlite3_free() by the caller
   923    921   */
   924    922   static int sessionTableInfo(
   925    923     sqlite3 *db,                    /* Database connection */
   926    924     const char *zDb,                /* Name of attached database (e.g. "main") */
   927    925     const char *zThis,              /* Table name */
   928    926     int *pnCol,                     /* OUT: number of columns */
   929    927     const char **pzTab,             /* OUT: Copy of zThis */
................................................................................
   940    938     u8 *pAlloc = 0;
   941    939     char **azCol = 0;
   942    940     u8 *abPK = 0;
   943    941   
   944    942     assert( pazCol && pabPK );
   945    943   
   946    944     nThis = sqlite3Strlen30(zThis);
   947         -  zPragma = sqlite3_mprintf("PRAGMA '%q'.table_info('%q')", zDb, zThis);
          945  +  if( nThis==12 && 0==sqlite3_stricmp("sqlite_stat1", zThis) ){
          946  +    rc = sqlite3_table_column_metadata(db, zDb, zThis, 0, 0, 0, 0, 0, 0);
          947  +    if( rc==SQLITE_OK ){
          948  +      /* For sqlite_stat1, pretend that (tbl,idx) is the PRIMARY KEY. */
          949  +      zPragma = sqlite3_mprintf(
          950  +          "SELECT 0, 'tbl',  '', 0, '', 1     UNION ALL "
          951  +          "SELECT 1, 'idx',  '', 0, '', 2     UNION ALL "
          952  +          "SELECT 2, 'stat', '', 0, '', 0"
          953  +      );
          954  +    }else if( rc==SQLITE_ERROR ){
          955  +      zPragma = sqlite3_mprintf("");
          956  +    }else{
          957  +      return rc;
          958  +    }
          959  +  }else{
          960  +    zPragma = sqlite3_mprintf("PRAGMA '%q'.table_info('%q')", zDb, zThis);
          961  +  }
   948    962     if( !zPragma ) return SQLITE_NOMEM;
   949    963   
   950    964     rc = sqlite3_prepare_v2(db, zPragma, -1, &pStmt, 0);
   951    965     sqlite3_free(zPragma);
   952    966     if( rc!=SQLITE_OK ) return rc;
   953    967   
   954    968     nByte = nThis + 1;
................................................................................
  1032   1046         int i;
  1033   1047         for(i=0; i<pTab->nCol; i++){
  1034   1048           if( abPK[i] ){
  1035   1049             pTab->abPK = abPK;
  1036   1050             break;
  1037   1051           }
  1038   1052         }
         1053  +      if( 0==sqlite3_stricmp("sqlite_stat1", pTab->zName) ){
         1054  +        pTab->bStat1 = 1;
         1055  +      }
  1039   1056       }
  1040   1057     }
  1041   1058     return (pSession->rc || pTab->abPK==0);
  1042   1059   }
         1060  +
         1061  +/*
         1062  +** Versions of the four methods in object SessionHook for use with the
         1063  +** sqlite_stat1 table. The purpose of this is to substitute a zero-length
         1064  +** blob each time a NULL value is read from the "idx" column of the
         1065  +** sqlite_stat1 table.
         1066  +*/
         1067  +typedef struct SessionStat1Ctx SessionStat1Ctx;
         1068  +struct SessionStat1Ctx {
         1069  +  SessionHook hook;
         1070  +  sqlite3_session *pSession;
         1071  +};
         1072  +static int sessionStat1Old(void *pCtx, int iCol, sqlite3_value **ppVal){
         1073  +  SessionStat1Ctx *p = (SessionStat1Ctx*)pCtx;
         1074  +  sqlite3_value *pVal = 0;
         1075  +  int rc = p->hook.xOld(p->hook.pCtx, iCol, &pVal);
         1076  +  if( rc==SQLITE_OK && iCol==1 && sqlite3_value_type(pVal)==SQLITE_NULL ){
         1077  +    pVal = p->pSession->pZeroBlob;
         1078  +  }
         1079  +  *ppVal = pVal;
         1080  +  return rc;
         1081  +}
         1082  +static int sessionStat1New(void *pCtx, int iCol, sqlite3_value **ppVal){
         1083  +  SessionStat1Ctx *p = (SessionStat1Ctx*)pCtx;
         1084  +  sqlite3_value *pVal = 0;
         1085  +  int rc = p->hook.xNew(p->hook.pCtx, iCol, &pVal);
         1086  +  if( rc==SQLITE_OK && iCol==1 && sqlite3_value_type(pVal)==SQLITE_NULL ){
         1087  +    pVal = p->pSession->pZeroBlob;
         1088  +  }
         1089  +  *ppVal = pVal;
         1090  +  return rc;
         1091  +}
         1092  +static int sessionStat1Count(void *pCtx){
         1093  +  SessionStat1Ctx *p = (SessionStat1Ctx*)pCtx;
         1094  +  return p->hook.xCount(p->hook.pCtx);
         1095  +}
         1096  +static int sessionStat1Depth(void *pCtx){
         1097  +  SessionStat1Ctx *p = (SessionStat1Ctx*)pCtx;
         1098  +  return p->hook.xDepth(p->hook.pCtx);
         1099  +}
         1100  +
  1043   1101   
  1044   1102   /*
  1045   1103   ** This function is only called from with a pre-update-hook reporting a 
  1046   1104   ** change on table pTab (attached to session pSession). The type of change
  1047   1105   ** (UPDATE, INSERT, DELETE) is specified by the first argument.
  1048   1106   **
  1049   1107   ** Unless one is already present or an error occurs, an entry is added
................................................................................
  1053   1111     int op,                         /* One of SQLITE_UPDATE, INSERT, DELETE */
  1054   1112     sqlite3_session *pSession,      /* Session object pTab is attached to */
  1055   1113     SessionTable *pTab              /* Table that change applies to */
  1056   1114   ){
  1057   1115     int iHash; 
  1058   1116     int bNull = 0; 
  1059   1117     int rc = SQLITE_OK;
         1118  +  SessionStat1Ctx stat1 = {0};
  1060   1119   
  1061   1120     if( pSession->rc ) return;
  1062   1121   
  1063   1122     /* Load table details if required */
  1064   1123     if( sessionInitTable(pSession, pTab) ) return;
  1065   1124   
  1066   1125     /* Check the number of columns in this xPreUpdate call matches the 
................................................................................
  1071   1130     }
  1072   1131   
  1073   1132     /* Grow the hash table if required */
  1074   1133     if( sessionGrowHash(0, pTab) ){
  1075   1134       pSession->rc = SQLITE_NOMEM;
  1076   1135       return;
  1077   1136     }
         1137  +
         1138  +  if( pTab->bStat1 ){
         1139  +    stat1.hook = pSession->hook;
         1140  +    stat1.pSession = pSession;
         1141  +    pSession->hook.pCtx = (void*)&stat1;
         1142  +    pSession->hook.xNew = sessionStat1New;
         1143  +    pSession->hook.xOld = sessionStat1Old;
         1144  +    pSession->hook.xCount = sessionStat1Count;
         1145  +    pSession->hook.xDepth = sessionStat1Depth;
         1146  +    if( pSession->pZeroBlob==0 ){
         1147  +      sqlite3_value *p = sqlite3ValueNew(0);
         1148  +      if( p==0 ){
         1149  +        rc = SQLITE_NOMEM;
         1150  +        goto error_out;
         1151  +      }
         1152  +      sqlite3ValueSetStr(p, 0, "", 0, SQLITE_STATIC);
         1153  +      pSession->pZeroBlob = p;
         1154  +    }
         1155  +  }
  1078   1156   
  1079   1157     /* Calculate the hash-key for this change. If the primary key of the row
  1080   1158     ** includes a NULL value, exit early. Such changes are ignored by the
  1081   1159     ** session module. */
  1082   1160     rc = sessionPreupdateHash(pSession, pTab, op==SQLITE_INSERT, &iHash, &bNull);
  1083   1161     if( rc!=SQLITE_OK ) goto error_out;
  1084   1162   
................................................................................
  1161   1239           pC->bIndirect = 0;
  1162   1240         }
  1163   1241       }
  1164   1242     }
  1165   1243   
  1166   1244     /* If an error has occurred, mark the session object as failed. */
  1167   1245    error_out:
         1246  +  if( pTab->bStat1 ){
         1247  +    pSession->hook = stat1.hook;
         1248  +  }
  1168   1249     if( rc!=SQLITE_OK ){
  1169   1250       pSession->rc = rc;
  1170   1251     }
  1171   1252   }
  1172   1253   
  1173   1254   static int sessionFindTable(
  1174   1255     sqlite3_session *pSession, 
................................................................................
  1497   1578             int i;
  1498   1579             for(i=0; i<nCol; i++){
  1499   1580               if( pTo->abPK[i]!=abPK[i] ) bMismatch = 1;
  1500   1581               if( sqlite3_stricmp(azCol[i], pTo->azCol[i]) ) bMismatch = 1;
  1501   1582               if( abPK[i] ) bHasPk = 1;
  1502   1583             }
  1503   1584           }
  1504         -
  1505   1585         }
  1506   1586         sqlite3_free((char*)azCol);
  1507   1587         if( bMismatch ){
  1508   1588           *pzErrMsg = sqlite3_mprintf("table schemas do not match");
  1509   1589           rc = SQLITE_SCHEMA;
  1510   1590         }
  1511   1591         if( bHasPk==0 ){
................................................................................
  1623   1703       if( (*pp)==pSession ){
  1624   1704         *pp = (*pp)->pNext;
  1625   1705         if( pHead ) sqlite3_preupdate_hook(db, xPreUpdate, (void*)pHead);
  1626   1706         break;
  1627   1707       }
  1628   1708     }
  1629   1709     sqlite3_mutex_leave(sqlite3_db_mutex(db));
         1710  +  sqlite3ValueFree(pSession->pZeroBlob);
  1630   1711   
  1631   1712     /* Delete all attached table objects. And the contents of their 
  1632   1713     ** associated hash-tables. */
  1633   1714     sessionDeleteTable(pSession->pTable);
  1634   1715   
  1635   1716     /* Free the session object itself. */
  1636   1717     sqlite3_free(pSession);
................................................................................
  2090   2171     const char *zTab,               /* Table name */
  2091   2172     int nCol,                       /* Number of columns in table */
  2092   2173     const char **azCol,             /* Names of table columns */
  2093   2174     u8 *abPK,                       /* PRIMARY KEY  array */
  2094   2175     sqlite3_stmt **ppStmt           /* OUT: Prepared SELECT statement */
  2095   2176   ){
  2096   2177     int rc = SQLITE_OK;
  2097         -  int i;
  2098         -  const char *zSep = "";
  2099         -  SessionBuffer buf = {0, 0, 0};
  2100         -
  2101         -  sessionAppendStr(&buf, "SELECT * FROM ", &rc);
  2102         -  sessionAppendIdent(&buf, zDb, &rc);
  2103         -  sessionAppendStr(&buf, ".", &rc);
  2104         -  sessionAppendIdent(&buf, zTab, &rc);
  2105         -  sessionAppendStr(&buf, " WHERE ", &rc);
  2106         -  for(i=0; i<nCol; i++){
  2107         -    if( abPK[i] ){
  2108         -      sessionAppendStr(&buf, zSep, &rc);
  2109         -      sessionAppendIdent(&buf, azCol[i], &rc);
  2110         -      sessionAppendStr(&buf, " = ?", &rc);
  2111         -      sessionAppendInteger(&buf, i+1, &rc);
  2112         -      zSep = " AND ";
  2113         -    }
  2114         -  }
  2115         -  if( rc==SQLITE_OK ){
  2116         -    rc = sqlite3_prepare_v2(db, (char *)buf.aBuf, buf.nBuf, ppStmt, 0);
  2117         -  }
  2118         -  sqlite3_free(buf.aBuf);
         2178  +  char *zSql = 0;
         2179  +  int nSql = -1;
         2180  +
         2181  +  if( 0==sqlite3_stricmp("sqlite_stat1", zTab) ){
         2182  +    zSql = sqlite3_mprintf(
         2183  +        "SELECT tbl, ?2, stat FROM %Q.sqlite_stat1 WHERE tbl IS ?1 AND "
         2184  +        "idx IS (CASE WHEN ?2=X'' THEN NULL ELSE ?2 END)", zDb
         2185  +    );
         2186  +  }else{
         2187  +    int i;
         2188  +    const char *zSep = "";
         2189  +    SessionBuffer buf = {0, 0, 0};
         2190  +
         2191  +    sessionAppendStr(&buf, "SELECT * FROM ", &rc);
         2192  +    sessionAppendIdent(&buf, zDb, &rc);
         2193  +    sessionAppendStr(&buf, ".", &rc);
         2194  +    sessionAppendIdent(&buf, zTab, &rc);
         2195  +    sessionAppendStr(&buf, " WHERE ", &rc);
         2196  +    for(i=0; i<nCol; i++){
         2197  +      if( abPK[i] ){
         2198  +        sessionAppendStr(&buf, zSep, &rc);
         2199  +        sessionAppendIdent(&buf, azCol[i], &rc);
         2200  +        sessionAppendStr(&buf, " IS ?", &rc);
         2201  +        sessionAppendInteger(&buf, i+1, &rc);
         2202  +        zSep = " AND ";
         2203  +      }
         2204  +    }
         2205  +    zSql = (char*)buf.aBuf;
         2206  +    nSql = buf.nBuf;
         2207  +  }
         2208  +
         2209  +  if( rc==SQLITE_OK ){
         2210  +    rc = sqlite3_prepare_v2(db, zSql, nSql, ppStmt, 0);
         2211  +  }
         2212  +  sqlite3_free(zSql);
  2119   2213     return rc;
  2120   2214   }
  2121   2215   
  2122   2216   /*
  2123   2217   ** Bind the PRIMARY KEY values from the change passed in argument pChange
  2124   2218   ** to the SELECT statement passed as the first argument. The SELECT statement
  2125   2219   ** is as prepared by function sessionSelectStmt().
................................................................................
  3280   3374     sqlite3_stmt *pDelete;          /* DELETE statement */
  3281   3375     sqlite3_stmt *pUpdate;          /* UPDATE statement */
  3282   3376     sqlite3_stmt *pInsert;          /* INSERT statement */
  3283   3377     sqlite3_stmt *pSelect;          /* SELECT statement */
  3284   3378     int nCol;                       /* Size of azCol[] and abPK[] arrays */
  3285   3379     const char **azCol;             /* Array of column names */
  3286   3380     u8 *abPK;                       /* Boolean array - true if column is in PK */
  3287         -
         3381  +  int bStat1;                     /* True if table is sqlite_stat1 */
  3288   3382     int bDeferConstraints;          /* True to defer constraints */
  3289   3383     SessionBuffer constraints;      /* Deferred constraints are stored here */
  3290   3384   };
  3291   3385   
  3292   3386   /*
  3293   3387   ** Formulate a statement to DELETE a row from database db. Assuming a table
  3294   3388   ** structure like this:
................................................................................
  3449   3543     if( rc==SQLITE_OK ){
  3450   3544       rc = sqlite3_prepare_v2(db, (char *)buf.aBuf, buf.nBuf, &p->pUpdate, 0);
  3451   3545     }
  3452   3546     sqlite3_free(buf.aBuf);
  3453   3547   
  3454   3548     return rc;
  3455   3549   }
         3550  +
  3456   3551   
  3457   3552   /*
  3458   3553   ** Formulate and prepare an SQL statement to query table zTab by primary
  3459   3554   ** key. Assuming the following table structure:
  3460   3555   **
  3461   3556   **     CREATE TABLE x(a, b, c, d, PRIMARY KEY(a, c));
  3462   3557   **
................................................................................
  3510   3605   
  3511   3606     if( rc==SQLITE_OK ){
  3512   3607       rc = sqlite3_prepare_v2(db, (char *)buf.aBuf, buf.nBuf, &p->pInsert, 0);
  3513   3608     }
  3514   3609     sqlite3_free(buf.aBuf);
  3515   3610     return rc;
  3516   3611   }
         3612  +
         3613  +static int sessionPrepare(sqlite3 *db, sqlite3_stmt **pp, const char *zSql){
         3614  +  return sqlite3_prepare_v2(db, zSql, -1, pp, 0);
         3615  +}
         3616  +
         3617  +/*
         3618  +** Prepare statements for applying changes to the sqlite_stat1 table.
         3619  +** These are similar to those created by sessionSelectRow(),
         3620  +** sessionInsertRow(), sessionUpdateRow() and sessionDeleteRow() for 
         3621  +** other tables.
         3622  +*/
         3623  +static int sessionStat1Sql(sqlite3 *db, SessionApplyCtx *p){
         3624  +  int rc = sessionSelectRow(db, "sqlite_stat1", p);
         3625  +  if( rc==SQLITE_OK ){
         3626  +    rc = sessionPrepare(db, &p->pInsert,
         3627  +        "INSERT INTO main.sqlite_stat1 VALUES(?1, "
         3628  +        "CASE WHEN length(?2)=0 AND typeof(?2)='blob' THEN NULL ELSE ?2 END, "
         3629  +        "?3)"
         3630  +    );
         3631  +  }
         3632  +  if( rc==SQLITE_OK ){
         3633  +    rc = sessionPrepare(db, &p->pUpdate,
         3634  +        "UPDATE main.sqlite_stat1 SET "
         3635  +        "tbl = CASE WHEN ?2 THEN ?3 ELSE tbl END, "
         3636  +        "idx = CASE WHEN ?5 THEN ?6 ELSE idx END, "
         3637  +        "stat = CASE WHEN ?8 THEN ?9 ELSE stat END  "
         3638  +        "WHERE tbl=?1 AND idx IS "
         3639  +        "CASE WHEN length(?4)=0 AND typeof(?4)='blob' THEN NULL ELSE ?4 END "
         3640  +        "AND (?10 OR ?8=0 OR stat IS ?7)"
         3641  +    );
         3642  +  }
         3643  +  if( rc==SQLITE_OK ){
         3644  +    rc = sessionPrepare(db, &p->pDelete,
         3645  +        "DELETE FROM main.sqlite_stat1 WHERE tbl=?1 AND idx IS "
         3646  +        "CASE WHEN length(?2)=0 AND typeof(?2)='blob' THEN NULL ELSE ?2 END "
         3647  +        "AND (?4 OR stat IS ?3)"
         3648  +    );
         3649  +  }
         3650  +  assert( rc==SQLITE_OK );
         3651  +  return rc;
         3652  +}
  3517   3653   
  3518   3654   /*
  3519   3655   ** A wrapper around sqlite3_bind_value() that detects an extra problem. 
  3520   3656   ** See comments in the body of this function for details.
  3521   3657   */
  3522   3658   static int sessionBindValue(
  3523   3659     sqlite3_stmt *pStmt,            /* Statement to bind value to */
................................................................................
  3841   3977         rc = sessionConflictHandler(
  3842   3978             SQLITE_CHANGESET_CONFLICT, p, pIter, xConflict, pCtx, 0
  3843   3979         );
  3844   3980       }
  3845   3981   
  3846   3982     }else{
  3847   3983       assert( op==SQLITE_INSERT );
  3848         -    rc = sessionBindRow(pIter, sqlite3changeset_new, nCol, 0, p->pInsert);
  3849         -    if( rc!=SQLITE_OK ) return rc;
         3984  +    if( p->bStat1 ){
         3985  +      /* Check if there is a conflicting row. For sqlite_stat1, this needs
         3986  +      ** to be done using a SELECT, as there is no PRIMARY KEY in the 
         3987  +      ** database schema to throw an exception if a duplicate is inserted.  */
         3988  +      rc = sessionSeekToRow(p->db, pIter, p->abPK, p->pSelect);
         3989  +      if( rc==SQLITE_ROW ){
         3990  +        rc = SQLITE_CONSTRAINT;
         3991  +        sqlite3_reset(p->pSelect);
         3992  +      }
         3993  +    }
  3850   3994   
  3851         -    sqlite3_step(p->pInsert);
  3852         -    rc = sqlite3_reset(p->pInsert);
         3995  +    if( rc==SQLITE_OK ){
         3996  +      rc = sessionBindRow(pIter, sqlite3changeset_new, nCol, 0, p->pInsert);
         3997  +      if( rc!=SQLITE_OK ) return rc;
         3998  +
         3999  +      sqlite3_step(p->pInsert);
         4000  +      rc = sqlite3_reset(p->pInsert);
         4001  +    }
         4002  +
  3853   4003       if( (rc&0xff)==SQLITE_CONSTRAINT ){
  3854   4004         rc = sessionConflictHandler(
  3855   4005             SQLITE_CHANGESET_CONFLICT, p, pIter, xConflict, pCtx, pbReplace
  3856   4006         );
  3857   4007       }
  3858   4008     }
  3859   4009   
................................................................................
  4078   4228             schemaMismatch = 1;
  4079   4229             sqlite3_log(SQLITE_SCHEMA, "sqlite3changeset_apply(): "
  4080   4230                 "primary key mismatch for table %s", zTab
  4081   4231             );
  4082   4232           }
  4083   4233           else{
  4084   4234             sApply.nCol = nCol;
  4085         -          if((rc = sessionSelectRow(db, zTab, &sApply))
  4086         -          || (rc = sessionUpdateRow(db, zTab, &sApply))
  4087         -          || (rc = sessionDeleteRow(db, zTab, &sApply))
  4088         -          || (rc = sessionInsertRow(db, zTab, &sApply))
  4089         -          ){
  4090         -            break;
         4235  +          if( 0==sqlite3_stricmp(zTab, "sqlite_stat1") ){
         4236  +            if( (rc = sessionStat1Sql(db, &sApply) ) ){
         4237  +              break;
         4238  +            }
         4239  +            sApply.bStat1 = 1;
         4240  +          }else{
         4241  +            if((rc = sessionSelectRow(db, zTab, &sApply))
         4242  +                || (rc = sessionUpdateRow(db, zTab, &sApply))
         4243  +                || (rc = sessionDeleteRow(db, zTab, &sApply))
         4244  +                || (rc = sessionInsertRow(db, zTab, &sApply))
         4245  +              ){
         4246  +              break;
         4247  +            }
         4248  +            sApply.bStat1 = 0;
  4091   4249             }
  4092   4250           }
  4093   4251           nTab = sqlite3Strlen30(zTab);
  4094   4252         }
  4095   4253       }
  4096   4254   
  4097   4255       /* If there is a schema mismatch on the current table, proceed to the

Changes to ext/session/sqlite3session.h.

   143    143   ** no changes will be recorded in either of these scenarios.
   144    144   **
   145    145   ** Changes are not recorded for individual rows that have NULL values stored
   146    146   ** in one or more of their PRIMARY KEY columns.
   147    147   **
   148    148   ** SQLITE_OK is returned if the call completes without error. Or, if an error 
   149    149   ** occurs, an SQLite error code (e.g. SQLITE_NOMEM) is returned.
          150  +**
          151  +** <h3>Special sqlite_stat1 Handling</h3>
          152  +**
          153  +** As of SQLite version 3.22.0, the "sqlite_stat1" table is an exception to 
          154  +** some of the rules above. In SQLite, the schema of sqlite_stat1 is:
          155  +**  <pre>
          156  +**  &nbsp;     CREATE TABLE sqlite_stat1(tbl,idx,stat)  
          157  +**  </pre>
          158  +**
          159  +** Even though sqlite_stat1 does not have a PRIMARY KEY, changes are 
          160  +** recorded for it as if the PRIMARY KEY is (tbl,idx). Additionally, changes 
          161  +** are recorded for rows for which (idx IS NULL) is true. However, for such
          162  +** rows a zero-length blob (SQL value X'') is stored in the changeset or
          163  +** patchset instead of a NULL value. This allows such changesets to be
          164  +** manipulated by legacy implementations of sqlite3changeset_invert(),
          165  +** concat() and similar.
          166  +**
          167  +** The sqlite3changeset_apply() function automatically converts the 
          168  +** zero-length blob back to a NULL value when updating the sqlite_stat1
          169  +** table. However, if the application calls sqlite3changeset_new(),
          170  +** sqlite3changeset_old() or sqlite3changeset_conflict on a changeset 
          171  +** iterator directly (including on a changeset iterator passed to a
          172  +** conflict-handler callback) then the X'' value is returned. The application
          173  +** must translate X'' to NULL itself if required.
          174  +**
          175  +** Legacy (older than 3.22.0) versions of the sessions module cannot capture
          176  +** changes made to the sqlite_stat1 table. Legacy versions of the
          177  +** sqlite3changeset_apply() function silently ignore any modifications to the
          178  +** sqlite_stat1 table that are part of a changeset or patchset.
   150    179   */
   151    180   int sqlite3session_attach(
   152    181     sqlite3_session *pSession,      /* Session object */
   153    182     const char *zTab                /* Table name */
   154    183   );
   155    184   
   156    185   /*

Changes to main.mk.

   367    367     $(TOP)/ext/misc/remember.c \
   368    368     $(TOP)/ext/misc/series.c \
   369    369     $(TOP)/ext/misc/spellfix.c \
   370    370     $(TOP)/ext/misc/totype.c \
   371    371     $(TOP)/ext/misc/unionvtab.c \
   372    372     $(TOP)/ext/misc/wholenumber.c \
   373    373     $(TOP)/ext/misc/vfslog.c \
          374  +  $(TOP)/ext/misc/zipfile.c \
   374    375     $(TOP)/ext/fts5/fts5_tcl.c \
   375    376     $(TOP)/ext/fts5/fts5_test_mi.c \
   376         -  $(TOP)/ext/fts5/fts5_test_tok.c 
          377  +  $(TOP)/ext/fts5/fts5_test_tok.c
   377    378   
   378    379   
   379    380   #TESTSRC += $(TOP)/ext/fts2/fts2_tokenizer.c
   380    381   #TESTSRC += $(TOP)/ext/fts3/fts3_tokenizer.c
   381    382   
   382    383   TESTSRC2 = \
   383    384     $(TOP)/src/attach.c \
................................................................................
   418    419     parse.c \
   419    420     $(TOP)/ext/fts3/fts3.c \
   420    421     $(TOP)/ext/fts3/fts3_aux.c \
   421    422     $(TOP)/ext/fts3/fts3_expr.c \
   422    423     $(TOP)/ext/fts3/fts3_tokenizer.c \
   423    424     $(TOP)/ext/fts3/fts3_write.c \
   424    425     $(TOP)/ext/async/sqlite3async.c \
          426  +  $(TOP)/ext/misc/stmt.c \
   425    427     $(TOP)/ext/session/sqlite3session.c \
   426    428     $(TOP)/ext/session/test_session.c 
   427    429   
   428    430   # Header files used by all library source files.
   429    431   #
   430    432   HDR = \
   431    433      $(TOP)/src/btree.h \
................................................................................
   483    485   #
   484    486   TESTPROGS = \
   485    487     testfixture$(EXE) \
   486    488     sqlite3$(EXE) \
   487    489     sqlite3_analyzer$(EXE) \
   488    490     sqlite3_checker$(EXE) \
   489    491     sqldiff$(EXE) \
   490         -  dbhash$(EXE)
          492  +  dbhash$(EXE) \
          493  +  sqltclsh$(EXE)
   491    494   
   492    495   # Databases containing fuzzer test cases
   493    496   #
   494    497   FUZZDATA = \
   495    498     $(TOP)/test/fuzzdata1.db \
   496    499     $(TOP)/test/fuzzdata2.db \
   497    500     $(TOP)/test/fuzzdata3.db \
................................................................................
   501    504   # Standard options to testfixture
   502    505   #
   503    506   TESTOPTS = --verbose=file --output=test-out.txt
   504    507   
   505    508   # Extra compiler options for various shell tools
   506    509   #
   507    510   SHELL_OPT += -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS5
          511  +SHELL_OPT += -DSQLITE_ENABLE_RTREE
   508    512   SHELL_OPT += -DSQLITE_ENABLE_EXPLAIN_COMMENTS
   509    513   SHELL_OPT += -DSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
   510    514   SHELL_OPT += -DSQLITE_ENABLE_STMTVTAB
   511    515   SHELL_OPT += -DSQLITE_ENABLE_DBPAGE_VTAB
   512    516   SHELL_OPT += -DSQLITE_ENABLE_DBSTAT_VTAB
   513    517   SHELL_OPT += -DSQLITE_ENABLE_OFFSET_SQL_FUNC
   514    518   SHELL_OPT += -DSQLITE_INTROSPECTION_PRAGMAS
................................................................................
   689    693   keywordhash.h:	$(TOP)/tool/mkkeywordhash.c
   690    694   	$(BCC) -o mkkeywordhash $(OPTS) $(TOP)/tool/mkkeywordhash.c
   691    695   	./mkkeywordhash >keywordhash.h
   692    696   
   693    697   # Source files that go into making shell.c
   694    698   SHELL_SRC = \
   695    699   	$(TOP)/src/shell.c.in \
          700  +        $(TOP)/ext/misc/appendvfs.c \
   696    701   	$(TOP)/ext/misc/shathree.c \
   697    702   	$(TOP)/ext/misc/fileio.c \
   698    703   	$(TOP)/ext/misc/completion.c \
          704  +	$(TOP)/ext/misc/sqlar.c \
   699    705   	$(TOP)/ext/expert/sqlite3expert.c \
   700         -	$(TOP)/ext/expert/sqlite3expert.h
          706  +	$(TOP)/ext/expert/sqlite3expert.h \
          707  +	$(TOP)/ext/misc/zipfile.c \
          708  +        $(TOP)/src/test_windirent.c
   701    709   
   702    710   shell.c:	$(SHELL_SRC) $(TOP)/tool/mkshellc.tcl
   703    711   	tclsh $(TOP)/tool/mkshellc.tcl >shell.c
   704    712   
   705    713   
   706    714   
   707    715   # Rules to build the extension objects.
................................................................................
   811    819   		$(TOP)/src/tclsqlite.c libsqlite3.a $(LIBTCL) $(THREADLIB)
   812    820   
   813    821   sqlite3_analyzer.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/spaceanal.tcl $(TOP)/tool/sqlite3_analyzer.c.in $(TOP)/tool/mkccode.tcl
   814    822   	tclsh $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqlite3_analyzer.c.in >sqlite3_analyzer.c
   815    823   
   816    824   sqlite3_analyzer$(EXE): sqlite3_analyzer.c
   817    825   	$(TCCX) $(TCL_FLAGS) sqlite3_analyzer.c -o $@ $(LIBTCL) $(THREADLIB) 
          826  +
          827  +sqltclsh.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/sqltclsh.tcl $(TOP)/ext/misc/appendvfs.c $(TOP)/tool/mkccode.tcl
          828  +	tclsh $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqltclsh.c.in >sqltclsh.c
          829  +
          830  +sqltclsh$(EXE): sqltclsh.c
          831  +	$(TCCX) $(TCL_FLAGS) sqltclsh.c -o $@ $(LIBTCL) $(THREADLIB) 
   818    832   
   819    833   sqlite3_expert$(EXE): $(TOP)/ext/expert/sqlite3expert.h $(TOP)/ext/expert/sqlite3expert.c $(TOP)/ext/expert/expert.c sqlite3.c
   820    834   	$(TCCX) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION $(TOP)/ext/expert/sqlite3expert.c $(TOP)/ext/expert/expert.c sqlite3.c -o sqlite3_expert$(EXE) $(THREADLIB)
   821    835   
   822    836   CHECKER_DEPS =\
   823    837     $(TOP)/tool/mkccode.tcl \
   824    838     sqlite3.c \

Changes to src/analyze.c.

   230    230         aCreateTbl[i] = 0;
   231    231         sqlite3TableLock(pParse, iDb, aRoot[i], 1, zTab);
   232    232         if( zWhere ){
   233    233           sqlite3NestedParse(pParse,
   234    234              "DELETE FROM %Q.%s WHERE %s=%Q",
   235    235              pDb->zDbSName, zTab, zWhereType, zWhere
   236    236           );
          237  +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
          238  +      }else if( db->xPreUpdateCallback ){
          239  +        sqlite3NestedParse(pParse, "DELETE FROM %Q.%s", pDb->zDbSName, zTab);
          240  +#endif
   237    241         }else{
   238    242           /* The sqlite_stat[134] table already exists.  Delete all rows. */
   239    243           sqlite3VdbeAddOp2(v, OP_Clear, aRoot[i], iDb);
   240    244         }
   241    245       }
   242    246     }
   243    247   
................................................................................
   994    998     int regRowid = iMem++;       /* Rowid argument passed to stat_push() */
   995    999   #endif
   996   1000     int regTemp = iMem++;        /* Temporary use register */
   997   1001     int regTabname = iMem++;     /* Register containing table name */
   998   1002     int regIdxname = iMem++;     /* Register containing index name */
   999   1003     int regStat1 = iMem++;       /* Value for the stat column of sqlite_stat1 */
  1000   1004     int regPrev = iMem;          /* MUST BE LAST (see below) */
         1005  +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
         1006  +  Table *pStat1 = 0; 
         1007  +#endif
  1001   1008   
  1002   1009     pParse->nMem = MAX(pParse->nMem, iMem);
  1003   1010     v = sqlite3GetVdbe(pParse);
  1004   1011     if( v==0 || NEVER(pTab==0) ){
  1005   1012       return;
  1006   1013     }
  1007   1014     if( pTab->tnum==0 ){
................................................................................
  1018   1025     assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
  1019   1026   #ifndef SQLITE_OMIT_AUTHORIZATION
  1020   1027     if( sqlite3AuthCheck(pParse, SQLITE_ANALYZE, pTab->zName, 0,
  1021   1028         db->aDb[iDb].zDbSName ) ){
  1022   1029       return;
  1023   1030     }
  1024   1031   #endif
         1032  +
         1033  +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
         1034  +  if( db->xPreUpdateCallback ){
         1035  +    pStat1 = (Table*)sqlite3DbMallocZero(db, sizeof(Table) + 13);
         1036  +    if( pStat1==0 ) return;
         1037  +    pStat1->zName = (char*)&pStat1[1];
         1038  +    memcpy(pStat1->zName, "sqlite_stat1", 13);
         1039  +    pStat1->nCol = 3;
         1040  +    pStat1->iPKey = -1;
         1041  +    sqlite3VdbeAddOp4(pParse->pVdbe, OP_Noop, 0, 0, 0,(char*)pStat1,P4_DYNBLOB);
         1042  +  }
         1043  +#endif
  1025   1044   
  1026   1045     /* Establish a read-lock on the table at the shared-cache level. 
  1027   1046     ** Open a read-only cursor on the table. Also allocate a cursor number
  1028   1047     ** to use for scanning indexes (iIdxCur). No index cursor is opened at
  1029   1048     ** this time though.  */
  1030   1049     sqlite3TableLock(pParse, iDb, pTab->tnum, 0, pTab->zName);
  1031   1050     iTabCur = iTab++;
................................................................................
  1220   1239   
  1221   1240       /* Add the entry to the stat1 table. */
  1222   1241       callStatGet(v, regStat4, STAT_GET_STAT1, regStat1);
  1223   1242       assert( "BBB"[0]==SQLITE_AFF_TEXT );
  1224   1243       sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regTemp, "BBB", 0);
  1225   1244       sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid);
  1226   1245       sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regTemp, regNewRowid);
         1246  +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
         1247  +    sqlite3VdbeChangeP4(v, -1, (char*)pStat1, P4_TABLE);
         1248  +#endif
  1227   1249       sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
  1228   1250   
  1229   1251       /* Add the entries to the stat3 or stat4 table. */
  1230   1252   #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
  1231   1253       {
  1232   1254         int regEq = regStat1;
  1233   1255         int regLt = regStat1+1;
................................................................................
  1283   1305       jZeroRows = sqlite3VdbeAddOp1(v, OP_IfNot, regStat1); VdbeCoverage(v);
  1284   1306       sqlite3VdbeAddOp2(v, OP_Null, 0, regIdxname);
  1285   1307       assert( "BBB"[0]==SQLITE_AFF_TEXT );
  1286   1308       sqlite3VdbeAddOp4(v, OP_MakeRecord, regTabname, 3, regTemp, "BBB", 0);
  1287   1309       sqlite3VdbeAddOp2(v, OP_NewRowid, iStatCur, regNewRowid);
  1288   1310       sqlite3VdbeAddOp3(v, OP_Insert, iStatCur, regTemp, regNewRowid);
  1289   1311       sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
         1312  +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK
         1313  +    sqlite3VdbeChangeP4(v, -1, (char*)pStat1, P4_TABLE);
         1314  +#endif
  1290   1315       sqlite3VdbeJumpHere(v, jZeroRows);
  1291   1316     }
  1292   1317   }
  1293   1318   
  1294   1319   
  1295   1320   /*
  1296   1321   ** Generate code that will cause the most recent index analysis to

Changes to src/btree.c.

   119    119   ** If SQLITE_DEBUG is not defined, then this macro is equivalent to
   120    120   ** SQLITE_CORRUPT_BKPT. Or, if SQLITE_DEBUG is set, then the log message
   121    121   ** normally produced as a side-effect of SQLITE_CORRUPT_BKPT is augmented
   122    122   ** with the page number and filename associated with the (MemPage*).
   123    123   */
   124    124   #ifdef SQLITE_DEBUG
   125    125   int corruptPageError(int lineno, MemPage *p){
   126         -  char *zMsg = sqlite3_mprintf("database corruption page %d of %s",
          126  +  char *zMsg;
          127  +  sqlite3BeginBenignMalloc();
          128  +  zMsg = sqlite3_mprintf("database corruption page %d of %s",
   127    129         (int)p->pgno, sqlite3PagerFilename(p->pBt->pPager, 0)
   128    130     );
          131  +  sqlite3EndBenignMalloc();
   129    132     if( zMsg ){
   130    133       sqlite3ReportError(SQLITE_CORRUPT, lineno, zMsg);
   131    134     }
   132    135     sqlite3_free(zMsg);
   133    136     return SQLITE_CORRUPT_BKPT;
   134    137   }
   135    138   # define SQLITE_CORRUPT_PAGE(pMemPage) corruptPageError(__LINE__, pMemPage)
................................................................................
  6182   6185   static void freePage(MemPage *pPage, int *pRC){
  6183   6186     if( (*pRC)==SQLITE_OK ){
  6184   6187       *pRC = freePage2(pPage->pBt, pPage, pPage->pgno);
  6185   6188     }
  6186   6189   }
  6187   6190   
  6188   6191   /*
  6189         -** Free any overflow pages associated with the given Cell.  Write the
  6190         -** local Cell size (the number of bytes on the original page, omitting
  6191         -** overflow) into *pnSize.
         6192  +** Free any overflow pages associated with the given Cell.  Store
         6193  +** size information about the cell in pInfo.
  6192   6194   */
  6193   6195   static int clearCell(
  6194   6196     MemPage *pPage,          /* The page that contains the Cell */
  6195   6197     unsigned char *pCell,    /* First byte of the Cell */
  6196   6198     CellInfo *pInfo          /* Size information about the cell */
  6197   6199   ){
  6198   6200     BtShared *pBt;
................................................................................
  7388   7390       */
  7389   7391       if( pOld->aData[0]!=apOld[0]->aData[0] ){
  7390   7392         rc = SQLITE_CORRUPT_BKPT;
  7391   7393         goto balance_cleanup;
  7392   7394       }
  7393   7395   
  7394   7396       /* Load b.apCell[] with pointers to all cells in pOld.  If pOld
  7395         -    ** constains overflow cells, include them in the b.apCell[] array
         7397  +    ** contains overflow cells, include them in the b.apCell[] array
  7396   7398       ** in the correct spot.
  7397   7399       **
  7398   7400       ** Note that when there are multiple overflow cells, it is always the
  7399   7401       ** case that they are sequential and adjacent.  This invariant arises
  7400   7402       ** because multiple overflows can only occurs when inserting divider
  7401   7403       ** cells into a parent on a prior balance, and divider cells are always
  7402   7404       ** adjacent and are inserted in order.  There is an assert() tagged

Changes to src/btreeInt.h.

   562    562   ** CURSOR_FAULT:
   563    563   **   An unrecoverable error (an I/O error or a malloc failure) has occurred
   564    564   **   on a different connection that shares the BtShared cache with this
   565    565   **   cursor.  The error has left the cache in an inconsistent state.
   566    566   **   Do nothing else with this cursor.  Any attempt to use the cursor
   567    567   **   should return the error code stored in BtCursor.skipNext
   568    568   */
   569         -#define CURSOR_INVALID           0
   570         -#define CURSOR_VALID             1
          569  +#define CURSOR_VALID             0
          570  +#define CURSOR_INVALID           1
   571    571   #define CURSOR_SKIPNEXT          2
   572    572   #define CURSOR_REQUIRESEEK       3
   573    573   #define CURSOR_FAULT             4
   574    574   
   575    575   /* 
   576    576   ** The database page the PENDING_BYTE occupies. This page is never used.
   577    577   */

Changes to src/build.c.

  2120   2120     p->pCheck = sqlite3ExprListDup(db, pCNames, EXPRDUP_REDUCE);
  2121   2121     if( db->mallocFailed ) goto create_view_fail;
  2122   2122   
  2123   2123     /* Locate the end of the CREATE VIEW statement.  Make sEnd point to
  2124   2124     ** the end.
  2125   2125     */
  2126   2126     sEnd = pParse->sLastToken;
  2127         -  assert( sEnd.z[0]!=0 );
         2127  +  assert( sEnd.z[0]!=0 || sEnd.n==0 );
  2128   2128     if( sEnd.z[0]!=';' ){
  2129   2129       sEnd.z += sEnd.n;
  2130   2130     }
  2131   2131     sEnd.n = 0;
  2132   2132     n = (int)(sEnd.z - pBegin->z);
  2133   2133     assert( n>0 );
  2134   2134     z = pBegin->z;

Changes to src/delete.c.

   756    756     ** the update-hook is not invoked for rows removed by REPLACE, but the 
   757    757     ** pre-update-hook is.
   758    758     */ 
   759    759     if( pTab->pSelect==0 ){
   760    760       u8 p5 = 0;
   761    761       sqlite3GenerateRowIndexDelete(pParse, pTab, iDataCur, iIdxCur,0,iIdxNoSeek);
   762    762       sqlite3VdbeAddOp2(v, OP_Delete, iDataCur, (count?OPFLAG_NCHANGE:0));
   763         -    if( pParse->nested==0 ){
          763  +    if( pParse->nested==0 || 0==sqlite3_stricmp(pTab->zName, "sqlite_stat1") ){
   764    764         sqlite3VdbeAppendP4(v, (char*)pTab, P4_TABLE);
   765    765       }
   766    766       if( eMode!=ONEPASS_OFF ){
   767    767         sqlite3VdbeChangeP5(v, OPFLAG_AUXDELETE);
   768    768       }
   769    769       if( iIdxNoSeek>=0 && iIdxNoSeek!=iDataCur ){
   770    770         sqlite3VdbeAddOp1(v, OP_Delete, iIdxNoSeek);

Changes to src/expr.c.

   654    654     if( p ){
   655    655       int i;
   656    656       for(i=0; i<p->nExpr; i++){
   657    657         heightOfExpr(p->a[i].pExpr, pnHeight);
   658    658       }
   659    659     }
   660    660   }
   661         -static void heightOfSelect(Select *p, int *pnHeight){
   662         -  if( p ){
          661  +static void heightOfSelect(Select *pSelect, int *pnHeight){
          662  +  Select *p;
          663  +  for(p=pSelect; p; p=p->pPrior){
   663    664       heightOfExpr(p->pWhere, pnHeight);
   664    665       heightOfExpr(p->pHaving, pnHeight);
   665    666       heightOfExpr(p->pLimit, pnHeight);
   666    667       heightOfExprList(p->pEList, pnHeight);
   667    668       heightOfExprList(p->pGroupBy, pnHeight);
   668    669       heightOfExprList(p->pOrderBy, pnHeight);
   669         -    heightOfSelect(p->pPrior, pnHeight);
   670    670     }
   671    671   }
   672    672   
   673    673   /*
   674    674   ** Set the Expr.nHeight variable in the structure passed as an 
   675    675   ** argument. An expression with no children, Expr.pList or 
   676    676   ** Expr.pSelect member has a height of 1. Any other expression
................................................................................
  2760   2760         if( pSel->pLimit ){
  2761   2761           sqlite3ExprDelete(pParse->db, pSel->pLimit->pLeft);
  2762   2762           pSel->pLimit->pLeft = pLimit;
  2763   2763         }else{
  2764   2764           pSel->pLimit = sqlite3PExpr(pParse, TK_LIMIT, pLimit, 0);
  2765   2765         }
  2766   2766         pSel->iLimit = 0;
  2767         -      pSel->selFlags &= ~SF_MultiValue;
  2768   2767         if( sqlite3Select(pParse, pSel, &dest) ){
  2769   2768           return 0;
  2770   2769         }
  2771   2770         rReg = dest.iSDParm;
  2772   2771         ExprSetVVAProperty(pExpr, EP_NoReduce);
  2773   2772         break;
  2774   2773       }

Changes to src/func.c.

    31     31   }
    32     32   
    33     33   /*
    34     34   ** Indicate that the accumulator load should be skipped on this
    35     35   ** iteration of the aggregate loop.
    36     36   */
    37     37   static void sqlite3SkipAccumulatorLoad(sqlite3_context *context){
           38  +  assert( context->isError<=0 );
           39  +  context->isError = -1;
    38     40     context->skipFlag = 1;
    39     41   }
    40     42   
    41     43   /*
    42     44   ** Implementation of the non-aggregate min() and max() functions
    43     45   */
    44     46   static void minmaxFunc(
................................................................................
    97     99   ** Implementation of the length() function
    98    100   */
    99    101   static void lengthFunc(
   100    102     sqlite3_context *context,
   101    103     int argc,
   102    104     sqlite3_value **argv
   103    105   ){
   104         -  int len;
   105         -
   106    106     assert( argc==1 );
   107    107     UNUSED_PARAMETER(argc);
   108    108     switch( sqlite3_value_type(argv[0]) ){
   109    109       case SQLITE_BLOB:
   110    110       case SQLITE_INTEGER:
   111    111       case SQLITE_FLOAT: {
   112    112         sqlite3_result_int(context, sqlite3_value_bytes(argv[0]));
   113    113         break;
   114    114       }
   115    115       case SQLITE_TEXT: {
   116    116         const unsigned char *z = sqlite3_value_text(argv[0]);
          117  +      const unsigned char *z0;
          118  +      unsigned char c;
   117    119         if( z==0 ) return;
   118         -      len = 0;
   119         -      while( *z ){
   120         -        len++;
   121         -        SQLITE_SKIP_UTF8(z);
          120  +      z0 = z;
          121  +      while( (c = *z)!=0 ){
          122  +        z++;
          123  +        if( c>=0xc0 ){
          124  +          while( (*z & 0xc0)==0x80 ){ z++; z0++; }
          125  +        }
   122    126         }
   123         -      sqlite3_result_int(context, len);
          127  +      sqlite3_result_int(context, (int)(z-z0));
   124    128         break;
   125    129       }
   126    130       default: {
   127    131         sqlite3_result_null(context);
   128    132         break;
   129    133       }
   130    134     }
................................................................................
  1796   1800       FUNCTION2(unlikely,          1, 0, 0, noopFunc,  SQLITE_FUNC_UNLIKELY),
  1797   1801       FUNCTION2(likelihood,        2, 0, 0, noopFunc,  SQLITE_FUNC_UNLIKELY),
  1798   1802       FUNCTION2(likely,            1, 0, 0, noopFunc,  SQLITE_FUNC_UNLIKELY),
  1799   1803   #ifdef SQLITE_DEBUG
  1800   1804       FUNCTION2(affinity,          1, 0, 0, noopFunc,  SQLITE_FUNC_AFFINITY),
  1801   1805   #endif
  1802   1806   #ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
  1803         -    FUNCTION2(sqlite_unsupported_offset,
  1804         -                                 1, 0, 0, noopFunc,  SQLITE_FUNC_OFFSET|
         1807  +    FUNCTION2(sqlite_offset,     1, 0, 0, noopFunc,  SQLITE_FUNC_OFFSET|
  1805   1808                                                        SQLITE_FUNC_TYPEOF),
  1806   1809   #endif
  1807   1810       FUNCTION(ltrim,              1, 1, 0, trimFunc         ),
  1808   1811       FUNCTION(ltrim,              2, 1, 0, trimFunc         ),
  1809   1812       FUNCTION(rtrim,              1, 2, 0, trimFunc         ),
  1810   1813       FUNCTION(rtrim,              2, 2, 0, trimFunc         ),
  1811   1814       FUNCTION(trim,               1, 3, 0, trimFunc         ),

Changes to src/loadext.c.

   426    426     /* Version 3.18.0 and later */
   427    427     sqlite3_set_last_insert_rowid,
   428    428     /* Version 3.20.0 and later */
   429    429     sqlite3_prepare_v3,
   430    430     sqlite3_prepare16_v3,
   431    431     sqlite3_bind_pointer,
   432    432     sqlite3_result_pointer,
   433         -  sqlite3_value_pointer
          433  +  sqlite3_value_pointer,
          434  +  /* Version 3.22.0 and later */
          435  +  sqlite3_vtab_nochange,
          436  +  sqlite3_value_nochange,
          437  +  sqlite3_vtab_collation
   434    438   };
   435    439   
   436    440   /*
   437    441   ** Attempt to load an SQLite extension library contained in the file
   438    442   ** zFile.  The entry point is zProc.  zProc may be 0 in which case a
   439    443   ** default entry point name (sqlite3_extension_init) is used.  Use
   440    444   ** of the default name is recommended.

Changes to src/main.c.

  1319   1319         case SQLITE_LOCKED_SHAREDCACHE: zName = "SQLITE_LOCKED_SHAREDCACHE";break;
  1320   1320         case SQLITE_NOMEM:              zName = "SQLITE_NOMEM";             break;
  1321   1321         case SQLITE_READONLY:           zName = "SQLITE_READONLY";          break;
  1322   1322         case SQLITE_READONLY_RECOVERY:  zName = "SQLITE_READONLY_RECOVERY"; break;
  1323   1323         case SQLITE_READONLY_CANTINIT:  zName = "SQLITE_READONLY_CANTINIT"; break;
  1324   1324         case SQLITE_READONLY_ROLLBACK:  zName = "SQLITE_READONLY_ROLLBACK"; break;
  1325   1325         case SQLITE_READONLY_DBMOVED:   zName = "SQLITE_READONLY_DBMOVED";  break;
         1326  +      case SQLITE_READONLY_DIRECTORY: zName = "SQLITE_READONLY_DIRECTORY";break;
  1326   1327         case SQLITE_INTERRUPT:          zName = "SQLITE_INTERRUPT";         break;
  1327   1328         case SQLITE_IOERR:              zName = "SQLITE_IOERR";             break;
  1328   1329         case SQLITE_IOERR_READ:         zName = "SQLITE_IOERR_READ";        break;
  1329   1330         case SQLITE_IOERR_SHORT_READ:   zName = "SQLITE_IOERR_SHORT_READ";  break;
  1330   1331         case SQLITE_IOERR_WRITE:        zName = "SQLITE_IOERR_WRITE";       break;
  1331   1332         case SQLITE_IOERR_FSYNC:        zName = "SQLITE_IOERR_FSYNC";       break;
  1332   1333         case SQLITE_IOERR_DIR_FSYNC:    zName = "SQLITE_IOERR_DIR_FSYNC";   break;

Changes to src/malloc.c.

   632    632   ** SQL statement.  Make a copy of this phrase in space obtained form
   633    633   ** sqlite3DbMalloc().  Omit leading and trailing whitespace.
   634    634   */
   635    635   char *sqlite3DbSpanDup(sqlite3 *db, const char *zStart, const char *zEnd){
   636    636     int n;
   637    637     while( sqlite3Isspace(zStart[0]) ) zStart++;
   638    638     n = (int)(zEnd - zStart);
   639         -  while( n>0 && sqlite3Isspace(zStart[n-1]) ) n--;
          639  +  while( ALWAYS(n>0) && sqlite3Isspace(zStart[n-1]) ) n--;
   640    640     return sqlite3DbStrNDup(db, zStart, n);
   641    641   }
   642    642   
   643    643   /*
   644    644   ** Free any prior content in *pz and replace it with a copy of zNew.
   645    645   */
   646    646   void sqlite3SetString(char **pz, sqlite3 *db, const char *zNew){

Changes to src/os_unix.c.

  3946   3946     if( pFile->sectorSize == 0 ){
  3947   3947       struct statvfs fsInfo;
  3948   3948          
  3949   3949       /* Set defaults for non-supported filesystems */
  3950   3950       pFile->sectorSize = SQLITE_DEFAULT_SECTOR_SIZE;
  3951   3951       pFile->deviceCharacteristics = 0;
  3952   3952       if( fstatvfs(pFile->h, &fsInfo) == -1 ) {
  3953         -      return pFile->sectorSize;
         3953  +      return;
  3954   3954       }
  3955   3955   
  3956   3956       if( !strcmp(fsInfo.f_basetype, "tmp") ) {
  3957   3957         pFile->sectorSize = fsInfo.f_bsize;
  3958   3958         pFile->deviceCharacteristics =
  3959   3959           SQLITE_IOCAP_ATOMIC4K |       /* All ram filesystem writes are atomic */
  3960   3960           SQLITE_IOCAP_SAFE_APPEND |    /* growing the file does not occur until
................................................................................
  5900   5900         assert( !p->pPreallocatedUnused );
  5901   5901         assert( eType==SQLITE_OPEN_WAL || eType==SQLITE_OPEN_MAIN_JOURNAL );
  5902   5902         return rc;
  5903   5903       }
  5904   5904       fd = robust_open(zName, openFlags, openMode);
  5905   5905       OSTRACE(("OPENX   %-3d %s 0%o\n", fd, zName, openFlags));
  5906   5906       assert( !isExclusive || (openFlags & O_CREAT)!=0 );
  5907         -    if( fd<0 && errno!=EISDIR && isReadWrite ){
  5908         -      /* Failed to open the file for read/write access. Try read-only. */
  5909         -      flags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE);
  5910         -      openFlags &= ~(O_RDWR|O_CREAT);
  5911         -      flags |= SQLITE_OPEN_READONLY;
  5912         -      openFlags |= O_RDONLY;
  5913         -      isReadonly = 1;
  5914         -      fd = robust_open(zName, openFlags, openMode);
         5907  +    if( fd<0 ){
         5908  +      if( isNewJrnl && errno==EACCES && osAccess(zName, F_OK) ){
         5909  +        /* If unable to create a journal because the directory is not
         5910  +        ** writable, change the error code to indicate that. */
         5911  +        rc = SQLITE_READONLY_DIRECTORY;
         5912  +      }else if( errno!=EISDIR && isReadWrite ){
         5913  +        /* Failed to open the file for read/write access. Try read-only. */
         5914  +        flags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE);
         5915  +        openFlags &= ~(O_RDWR|O_CREAT);
         5916  +        flags |= SQLITE_OPEN_READONLY;
         5917  +        openFlags |= O_RDONLY;
         5918  +        isReadonly = 1;
         5919  +        fd = robust_open(zName, openFlags, openMode);
         5920  +      }
  5915   5921       }
  5916   5922       if( fd<0 ){
  5917         -      rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zName);
  5918         -      /* If unable to create a journal, change the error code to
  5919         -      ** indicate that the directory permissions are wrong. */
  5920         -      if( isNewJrnl && osAccess(zName, F_OK) ) rc = SQLITE_READONLY_DIRECTORY;
         5923  +      int rc2 = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zName);
         5924  +      if( rc==SQLITE_OK ) rc = rc2;
  5921   5925         goto open_finished;
  5922   5926       }
  5923   5927   
  5924   5928       /* If this process is running as root and if creating a new rollback
  5925   5929       ** journal or WAL file, set the ownership of the journal or WAL to be
  5926   5930       ** the same as the original database.
  5927   5931       */

Changes to src/os_win.c.

  3861   3861   ** file are currently open, in this process or in other processes, then
  3862   3862   ** the file must be truncated to zero length or have its header cleared.
  3863   3863   */
  3864   3864   static int winOpenSharedMemory(winFile *pDbFd){
  3865   3865     struct winShm *p;                  /* The connection to be opened */
  3866   3866     winShmNode *pShmNode = 0;          /* The underlying mmapped file */
  3867   3867     int rc = SQLITE_OK;                /* Result code */
  3868         -  int rc2 = SQLITE_ERROR;            /* winOpen result code */
  3869   3868     winShmNode *pNew;                  /* Newly allocated winShmNode */
  3870   3869     int nName;                         /* Size of zName in bytes */
  3871   3870   
  3872   3871     assert( pDbFd->pShm==0 );    /* Not previously opened */
  3873   3872   
  3874   3873     /* Allocate space for the new sqlite3_shm object.  Also speculatively
  3875   3874     ** allocate space for a new winShmNode and filename.
................................................................................
  3895   3894       ** use FILE_ID_BOTH_DIR_INFO Structure.
  3896   3895       */
  3897   3896       if( sqlite3StrICmp(pShmNode->zFilename, pNew->zFilename)==0 ) break;
  3898   3897     }
  3899   3898     if( pShmNode ){
  3900   3899       sqlite3_free(pNew);
  3901   3900     }else{
         3901  +    int inFlags = SQLITE_OPEN_WAL;
         3902  +    int outFlags = 0;
         3903  +
  3902   3904       pShmNode = pNew;
  3903   3905       pNew = 0;
  3904   3906       ((winFile*)(&pShmNode->hFile))->h = INVALID_HANDLE_VALUE;
  3905   3907       pShmNode->pNext = winShmNodeList;
  3906   3908       winShmNodeList = pShmNode;
  3907   3909   
  3908   3910       if( sqlite3GlobalConfig.bCoreMutex ){
................................................................................
  3910   3912         if( pShmNode->mutex==0 ){
  3911   3913           rc = SQLITE_IOERR_NOMEM_BKPT;
  3912   3914           goto shm_open_err;
  3913   3915         }
  3914   3916       }
  3915   3917   
  3916   3918       if( 0==sqlite3_uri_boolean(pDbFd->zPath, "readonly_shm", 0) ){
  3917         -      rc2 = winOpen(pDbFd->pVfs,
  3918         -                    pShmNode->zFilename,
  3919         -                    (sqlite3_file*)&pShmNode->hFile,
  3920         -                    SQLITE_OPEN_WAL|SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE,
  3921         -                    0);
         3919  +      inFlags |= SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
         3920  +    }else{
         3921  +      inFlags |= SQLITE_OPEN_READONLY;
  3922   3922       }
  3923         -    if( rc2!=SQLITE_OK ){
  3924         -      rc2 = winOpen(pDbFd->pVfs,
  3925         -                    pShmNode->zFilename,
  3926         -                    (sqlite3_file*)&pShmNode->hFile,
  3927         -                    SQLITE_OPEN_WAL|SQLITE_OPEN_READONLY,
  3928         -                    0);
  3929         -      if( rc2!=SQLITE_OK ){
  3930         -        rc = winLogError(rc2, osGetLastError(), "winOpenShm",
  3931         -                         pShmNode->zFilename);
  3932         -        goto shm_open_err;
  3933         -      }
  3934         -      pShmNode->isReadonly = 1;
         3923  +    rc = winOpen(pDbFd->pVfs, pShmNode->zFilename,
         3924  +                 (sqlite3_file*)&pShmNode->hFile,
         3925  +                 inFlags, &outFlags);
         3926  +    if( rc!=SQLITE_OK ){
         3927  +      rc = winLogError(rc, osGetLastError(), "winOpenShm",
         3928  +                       pShmNode->zFilename);
         3929  +      goto shm_open_err;
  3935   3930       }
         3931  +    if( outFlags==SQLITE_OPEN_READONLY ) pShmNode->isReadonly = 1;
  3936   3932   
  3937   3933       rc = winLockSharedMemory(pShmNode);
  3938   3934       if( rc!=SQLITE_OK && rc!=SQLITE_READONLY_CANTINIT ) goto shm_open_err;
  3939   3935     }
  3940   3936   
  3941   3937     /* Make the new connection a child of the winShmNode */
  3942   3938     p->pShmNode = pShmNode;
................................................................................
  5114   5110         h = osCreateFile2((LPCWSTR)zConverted,
  5115   5111                           dwDesiredAccess,
  5116   5112                           dwShareMode,
  5117   5113                           dwCreationDisposition,
  5118   5114                           &extendedParameters);
  5119   5115         if( h!=INVALID_HANDLE_VALUE ) break;
  5120   5116         if( isReadWrite ){
  5121         -        int isRO = 0;
  5122         -        int rc2 = winAccess(pVfs, zName, SQLITE_ACCESS_READ, &isRO);
         5117  +        int rc2, isRO = 0;
         5118  +        sqlite3BeginBenignMalloc();
         5119  +        rc2 = winAccess(pVfs, zName, SQLITE_ACCESS_READ, &isRO);
         5120  +        sqlite3EndBenignMalloc();
  5123   5121           if( rc2==SQLITE_OK && isRO ) break;
  5124   5122         }
  5125   5123       }while( winRetryIoerr(&cnt, &lastErrno) );
  5126   5124   #else
  5127   5125       do{
  5128   5126         h = osCreateFileW((LPCWSTR)zConverted,
  5129   5127                           dwDesiredAccess,
  5130   5128                           dwShareMode, NULL,
  5131   5129                           dwCreationDisposition,
  5132   5130                           dwFlagsAndAttributes,
  5133   5131                           NULL);
  5134   5132         if( h!=INVALID_HANDLE_VALUE ) break;
  5135   5133         if( isReadWrite ){
  5136         -        int isRO = 0;
  5137         -        int rc2 = winAccess(pVfs, zName, SQLITE_ACCESS_READ, &isRO);
         5134  +        int rc2, isRO = 0;
         5135  +        sqlite3BeginBenignMalloc();
         5136  +        rc2 = winAccess(pVfs, zName, SQLITE_ACCESS_READ, &isRO);
         5137  +        sqlite3EndBenignMalloc();
  5138   5138           if( rc2==SQLITE_OK && isRO ) break;
  5139   5139         }
  5140   5140       }while( winRetryIoerr(&cnt, &lastErrno) );
  5141   5141   #endif
  5142   5142     }
  5143   5143   #ifdef SQLITE_WIN32_HAS_ANSI
  5144   5144     else{
................................................................................
  5147   5147                           dwDesiredAccess,
  5148   5148                           dwShareMode, NULL,
  5149   5149                           dwCreationDisposition,
  5150   5150                           dwFlagsAndAttributes,
  5151   5151                           NULL);
  5152   5152         if( h!=INVALID_HANDLE_VALUE ) break;
  5153   5153         if( isReadWrite ){
  5154         -        int isRO = 0;
  5155         -        int rc2 = winAccess(pVfs, zName, SQLITE_ACCESS_READ, &isRO);
         5154  +        int rc2, isRO = 0;
         5155  +        sqlite3BeginBenignMalloc();
         5156  +        rc2 = winAccess(pVfs, zName, SQLITE_ACCESS_READ, &isRO);
         5157  +        sqlite3EndBenignMalloc();
  5156   5158           if( rc2==SQLITE_OK && isRO ) break;
  5157   5159         }
  5158   5160       }while( winRetryIoerr(&cnt, &lastErrno) );
  5159   5161     }
  5160   5162   #endif
  5161   5163     winLogIoerr(cnt, __LINE__);
  5162   5164   

Changes to src/pager.c.

  1209   1209     assert( isOpen(pPager->fd) );
  1210   1210     dc = sqlite3OsDeviceCharacteristics(pPager->fd);
  1211   1211   #else
  1212   1212     UNUSED_PARAMETER(pPager);
  1213   1213   #endif
  1214   1214   
  1215   1215   #ifdef SQLITE_ENABLE_BATCH_ATOMIC_WRITE
  1216         -  if( dc&SQLITE_IOCAP_BATCH_ATOMIC ){
         1216  +  if( pPager->dbSize>0 && (dc&SQLITE_IOCAP_BATCH_ATOMIC) ){
  1217   1217       return -1;
  1218   1218     }
  1219   1219   #endif
  1220   1220   
  1221   1221   #ifdef SQLITE_ENABLE_ATOMIC_WRITE
  1222   1222     {
  1223   1223       int nSector = pPager->sectorSize;
................................................................................
  6497   6497           rc = sqlite3OsFileControl(fd, SQLITE_FCNTL_BEGIN_ATOMIC_WRITE, 0);
  6498   6498           if( rc!=SQLITE_OK ) goto commit_phase_one_exit;
  6499   6499         }
  6500   6500         rc = pager_write_pagelist(pPager,sqlite3PcacheDirtyList(pPager->pPCache));
  6501   6501         if( bBatch ){
  6502   6502           if( rc==SQLITE_OK ){
  6503   6503             rc = sqlite3OsFileControl(fd, SQLITE_FCNTL_COMMIT_ATOMIC_WRITE, 0);
  6504         -        }else{
  6505         -          sqlite3OsFileControl(fd, SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE, 0);
         6504  +        }
         6505  +        if( rc!=SQLITE_OK ){
         6506  +          sqlite3OsFileControlHint(fd, SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE, 0);
  6506   6507           }
  6507   6508         }
  6508   6509   
  6509   6510         if( rc!=SQLITE_OK ){
  6510   6511           assert( rc!=SQLITE_IOERR_BLOCKED );
  6511   6512           goto commit_phase_one_exit;
  6512   6513         }

Changes to src/parse.y.

    27     27   // The generated parser function takes a 4th argument as follows:
    28     28   %extra_argument {Parse *pParse}
    29     29   
    30     30   // This code runs whenever there is a syntax error
    31     31   //
    32     32   %syntax_error {
    33     33     UNUSED_PARAMETER(yymajor);  /* Silence some compiler warnings */
    34         -  assert( TOKEN.z[0] );  /* The tokenizer always gives us a token */
    35         -  sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &TOKEN);
           34  +  if( TOKEN.z[0] ){
           35  +    sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &TOKEN);
           36  +  }else{
           37  +    sqlite3ErrorMsg(pParse, "incomplete input");
           38  +  }
    36     39   }
    37     40   %stack_overflow {
    38     41     sqlite3ErrorMsg(pParse, "parser stack overflow");
    39     42   }
    40     43   
    41     44   // The name of the generated procedure that implements the parser
    42     45   // is as follows:

Changes to src/select.c.

  2180   2180   /*
  2181   2181   ** Handle the special case of a compound-select that originates from a
  2182   2182   ** VALUES clause.  By handling this as a special case, we avoid deep
  2183   2183   ** recursion, and thus do not need to enforce the SQLITE_LIMIT_COMPOUND_SELECT
  2184   2184   ** on a VALUES clause.
  2185   2185   **
  2186   2186   ** Because the Select object originates from a VALUES clause:
  2187         -**   (1) It has no LIMIT or OFFSET
         2187  +**   (1) There is no LIMIT or OFFSET or else there is a LIMIT of exactly 1
  2188   2188   **   (2) All terms are UNION ALL
  2189   2189   **   (3) There is no ORDER BY clause
         2190  +**
         2191  +** The "LIMIT of exactly 1" case of condition (1) comes about when a VALUES
         2192  +** clause occurs within scalar expression (ex: "SELECT (VALUES(1),(2),(3))").
         2193  +** The sqlite3CodeSubselect will have added the LIMIT 1 clause in tht case.
         2194  +** Since the limit is exactly 1, we only need to evalutes the left-most VALUES.
  2190   2195   */
  2191   2196   static int multiSelectValues(
  2192   2197     Parse *pParse,        /* Parsing context */
  2193   2198     Select *p,            /* The right-most of SELECTs to be coded */
  2194   2199     SelectDest *pDest     /* What to do with query results */
  2195   2200   ){
  2196   2201     Select *pPrior;
         2202  +  Select *pRightmost = p;
  2197   2203     int nRow = 1;
  2198   2204     int rc = 0;
  2199   2205     assert( p->selFlags & SF_MultiValue );
  2200   2206     do{
  2201   2207       assert( p->selFlags & SF_Values );
  2202   2208       assert( p->op==TK_ALL || (p->op==TK_SELECT && p->pPrior==0) );
  2203         -    assert( p->pLimit==0 );
  2204   2209       assert( p->pNext==0 || p->pEList->nExpr==p->pNext->pEList->nExpr );
  2205   2210       if( p->pPrior==0 ) break;
  2206   2211       assert( p->pPrior->pNext==p );
  2207   2212       p = p->pPrior;
  2208   2213       nRow++;
  2209   2214     }while(1);
  2210   2215     while( p ){
  2211   2216       pPrior = p->pPrior;
  2212   2217       p->pPrior = 0;
  2213   2218       rc = sqlite3Select(pParse, p, pDest);
  2214   2219       p->pPrior = pPrior;
  2215         -    if( rc ) break;
         2220  +    if( rc || pRightmost->pLimit ) break;
  2216   2221       p->nSelectRow = nRow;
  2217   2222       p = p->pNext;
  2218   2223     }
  2219   2224     return rc;
  2220   2225   }
  2221   2226   
  2222   2227   /*

Changes to src/shell.c.in.

    57     57   #endif
    58     58   
    59     59   #include <stdlib.h>
    60     60   #include <string.h>
    61     61   #include <stdio.h>
    62     62   #include <assert.h>
    63     63   #include "sqlite3.h"
           64  +typedef sqlite3_int64 i64;
           65  +typedef sqlite3_uint64 u64;
           66  +typedef unsigned char u8;
    64     67   #if SQLITE_USER_AUTHENTICATION
    65     68   # include "sqlite3userauth.h"
    66     69   #endif
    67     70   #include <ctype.h>
    68     71   #include <stdarg.h>
    69     72   
    70     73   #if !defined(_WIN32) && !defined(WIN32)
    71     74   # include <signal.h>
    72     75   # if !defined(__RTP__) && !defined(_WRS_KERNEL)
    73     76   #  include <pwd.h>
    74     77   # endif
           78  +#endif
           79  +#if (!defined(_WIN32) && !defined(WIN32)) || defined(__MINGW32__)
    75     80   # include <unistd.h>
    76         -# include <sys/types.h>
           81  +# include <dirent.h>
           82  +# if defined(__MINGW32__)
           83  +#  define DIRENT dirent
           84  +#  ifndef S_ISLNK
           85  +#   define S_ISLNK(mode) (0)
           86  +#  endif
           87  +# endif
    77     88   #endif
           89  +#include <sys/types.h>
           90  +#include <sys/stat.h>
    78     91   
    79     92   #if HAVE_READLINE
    80     93   # include <readline/readline.h>
    81     94   # include <readline/history.h>
    82     95   #endif
    83     96   
    84     97   #if HAVE_EDITLINE
................................................................................
   335    348   #endif
   336    349   
   337    350   /*
   338    351   ** Used to prevent warnings about unused parameters
   339    352   */
   340    353   #define UNUSED_PARAMETER(x) (void)(x)
   341    354   
          355  +/*
          356  +** Number of elements in an array
          357  +*/
          358  +#define ArraySize(X)  (int)(sizeof(X)/sizeof(X[0]))
          359  +
   342    360   /*
   343    361   ** If the following flag is set, then command execution stops
   344    362   ** at an error if we are not interactive.
   345    363   */
   346    364   static int bail_on_error = 0;
   347    365   
   348    366   /*
................................................................................
   607    625       free(zPrior);
   608    626       zResult = shell_readline(zPrompt);
   609    627       if( zResult && *zResult ) shell_add_history(zResult);
   610    628   #endif
   611    629     }
   612    630     return zResult;
   613    631   }
          632  +
          633  +
          634  +/*
          635  +** Return the value of a hexadecimal digit.  Return -1 if the input
          636  +** is not a hex digit.
          637  +*/
          638  +static int hexDigitValue(char c){
          639  +  if( c>='0' && c<='9' ) return c - '0';
          640  +  if( c>='a' && c<='f' ) return c - 'a' + 10;
          641  +  if( c>='A' && c<='F' ) return c - 'A' + 10;
          642  +  return -1;
          643  +}
          644  +
          645  +/*
          646  +** Interpret zArg as an integer value, possibly with suffixes.
          647  +*/
          648  +static sqlite3_int64 integerValue(const char *zArg){
          649  +  sqlite3_int64 v = 0;
          650  +  static const struct { char *zSuffix; int iMult; } aMult[] = {
          651  +    { "KiB", 1024 },
          652  +    { "MiB", 1024*1024 },
          653  +    { "GiB", 1024*1024*1024 },
          654  +    { "KB",  1000 },
          655  +    { "MB",  1000000 },
          656  +    { "GB",  1000000000 },
          657  +    { "K",   1000 },
          658  +    { "M",   1000000 },
          659  +    { "G",   1000000000 },
          660  +  };
          661  +  int i;
          662  +  int isNeg = 0;
          663  +  if( zArg[0]=='-' ){
          664  +    isNeg = 1;
          665  +    zArg++;
          666  +  }else if( zArg[0]=='+' ){
          667  +    zArg++;
          668  +  }
          669  +  if( zArg[0]=='0' && zArg[1]=='x' ){
          670  +    int x;
          671  +    zArg += 2;
          672  +    while( (x = hexDigitValue(zArg[0]))>=0 ){
          673  +      v = (v<<4) + x;
          674  +      zArg++;
          675  +    }
          676  +  }else{
          677  +    while( IsDigit(zArg[0]) ){
          678  +      v = v*10 + zArg[0] - '0';
          679  +      zArg++;
          680  +    }
          681  +  }
          682  +  for(i=0; i<ArraySize(aMult); i++){
          683  +    if( sqlite3_stricmp(aMult[i].zSuffix, zArg)==0 ){
          684  +      v *= aMult[i].iMult;
          685  +      break;
          686  +    }
          687  +  }
          688  +  return isNeg? -v : v;
          689  +}
          690  +
   614    691   /*
   615    692   ** A variable length string to which one can append text.
   616    693   */
   617    694   typedef struct ShellText ShellText;
   618    695   struct ShellText {
   619    696     char *z;
   620    697     int n;
................................................................................
   784    861   static void shellModuleSchema(
   785    862     sqlite3_context *pCtx,
   786    863     int nVal,
   787    864     sqlite3_value **apVal
   788    865   ){
   789    866     const char *zName = (const char*)sqlite3_value_text(apVal[0]);
   790    867     char *zFake = shellFakeSchema(sqlite3_context_db_handle(pCtx), 0, zName);
          868  +  UNUSED_PARAMETER(nVal);
   791    869     if( zFake ){
   792         -    sqlite3_result_text(pCtx, sqlite3_mprintf("/* %z */", zFake),
          870  +    sqlite3_result_text(pCtx, sqlite3_mprintf("/* %s */", zFake),
   793    871                           -1, sqlite3_free);
          872  +    free(zFake);
   794    873     }
   795    874   }
   796    875   
   797    876   /*
   798    877   ** SQL function:  shell_add_schema(S,X)
   799    878   **
   800    879   ** Add the schema name X to the CREATE statement in S and return the result.
................................................................................
   827    906        "VIRTUAL TABLE"
   828    907     };
   829    908     int i = 0;
   830    909     const char *zIn = (const char*)sqlite3_value_text(apVal[0]);
   831    910     const char *zSchema = (const char*)sqlite3_value_text(apVal[1]);
   832    911     const char *zName = (const char*)sqlite3_value_text(apVal[2]);
   833    912     sqlite3 *db = sqlite3_context_db_handle(pCtx);
          913  +  UNUSED_PARAMETER(nVal);
   834    914     if( zIn!=0 && strncmp(zIn, "CREATE ", 7)==0 ){
   835    915       for(i=0; i<(int)(sizeof(aPrefix)/sizeof(aPrefix[0])); i++){
   836    916         int n = strlen30(aPrefix[i]);
   837    917         if( strncmp(zIn+7, aPrefix[i], n)==0 && zIn[n+7]==' ' ){
   838    918           char *z = 0;
   839    919           char *zFake = 0;
   840    920           if( zSchema ){
................................................................................
   846    926             }
   847    927           }
   848    928           if( zName
   849    929            && aPrefix[i][0]=='V'
   850    930            && (zFake = shellFakeSchema(db, zSchema, zName))!=0
   851    931           ){
   852    932             if( z==0 ){
   853         -            z = sqlite3_mprintf("%s\n/* %z */", zIn, zFake);
          933  +            z = sqlite3_mprintf("%s\n/* %s */", zIn, zFake);
   854    934             }else{
   855         -            z = sqlite3_mprintf("%z\n/* %z */", z, zFake);
          935  +            z = sqlite3_mprintf("%z\n/* %s */", z, zFake);
   856    936             }
          937  +          free(zFake);
   857    938           }
   858    939           if( z ){
   859    940             sqlite3_result_text(pCtx, z, -1, sqlite3_free);
   860    941             return;
   861    942           }
   862    943         }
   863    944       }
................................................................................
   870    951   ** below by the ../tool/mkshellc.tcl script.  Before processing that included
   871    952   ** code, we need to override some macros to make the included program code
   872    953   ** work here in the middle of this regular program.
   873    954   */
   874    955   #define SQLITE_EXTENSION_INIT1
   875    956   #define SQLITE_EXTENSION_INIT2(X) (void)(X)
   876    957   
          958  +#if defined(_WIN32) && defined(_MSC_VER)
          959  +INCLUDE test_windirent.h
          960  +INCLUDE test_windirent.c
          961  +#define dirent DIRENT
          962  +#endif
   877    963   INCLUDE ../ext/misc/shathree.c
   878    964   INCLUDE ../ext/misc/fileio.c
   879    965   INCLUDE ../ext/misc/completion.c
          966  +INCLUDE ../ext/misc/appendvfs.c
          967  +#ifdef SQLITE_HAVE_ZLIB
          968  +INCLUDE ../ext/misc/zipfile.c
          969  +INCLUDE ../ext/misc/sqlar.c
          970  +#endif
   880    971   INCLUDE ../ext/expert/sqlite3expert.h
   881    972   INCLUDE ../ext/expert/sqlite3expert.c
   882    973   
   883    974   #if defined(SQLITE_ENABLE_SESSION)
   884    975   /*
   885    976   ** State information for a single open session
   886    977   */
................................................................................
   914   1005   /*
   915   1006   ** State information about the database connection is contained in an
   916   1007   ** instance of the following structure.
   917   1008   */
   918   1009   typedef struct ShellState ShellState;
   919   1010   struct ShellState {
   920   1011     sqlite3 *db;           /* The database */
   921         -  int autoExplain;       /* Automatically turn on .explain mode */
   922         -  int autoEQP;           /* Run EXPLAIN QUERY PLAN prior to seach SQL stmt */
   923         -  int statsOn;           /* True to display memory stats before each finalize */
   924         -  int scanstatsOn;       /* True to display scan stats before each finalize */
         1012  +  u8 autoExplain;        /* Automatically turn on .explain mode */
         1013  +  u8 autoEQP;            /* Run EXPLAIN QUERY PLAN prior to seach SQL stmt */
         1014  +  u8 statsOn;            /* True to display memory stats before each finalize */
         1015  +  u8 scanstatsOn;        /* True to display scan stats before each finalize */
         1016  +  u8 openMode;           /* SHELL_OPEN_NORMAL, _APPENDVFS, or _ZIPFILE */
         1017  +  u8 doXdgOpen;          /* Invoke start/open/xdg-open in output_reset() */
   925   1018     int outCount;          /* Revert to stdout when reaching zero */
   926   1019     int cnt;               /* Number of records displayed so far */
   927   1020     FILE *out;             /* Write results here */
   928   1021     FILE *traceOut;        /* Output for sqlite3_trace() */
   929   1022     int nErr;              /* Number of errors seen */
   930   1023     int mode;              /* An output mode setting */
         1024  +  int modePrior;         /* Saved mode */
   931   1025     int cMode;             /* temporary output mode for the current query */
   932   1026     int normalMode;        /* Output mode before ".explain on" */
   933   1027     int writableSchema;    /* True if PRAGMA writable_schema=ON */
   934   1028     int showHeader;        /* True to show column names in List or Column mode */
   935   1029     int nCheck;            /* Number of ".check" commands run */
   936   1030     unsigned shellFlgs;    /* Various flags */
   937   1031     char *zDestTable;      /* Name of destination table when MODE_Insert */
         1032  +  char *zTempFile;       /* Temporary file that might need deleting */
   938   1033     char zTestcase[30];    /* Name of current test case */
   939   1034     char colSeparator[20]; /* Column separator character for several modes */
   940   1035     char rowSeparator[20]; /* Row separator character for MODE_Ascii */
         1036  +  char colSepPrior[20];  /* Saved column separator */
         1037  +  char rowSepPrior[20];  /* Saved row separator */
   941   1038     int colWidth[100];     /* Requested width of each column when in column mode*/
   942   1039     int actualWidth[100];  /* Actual width of each column */
   943   1040     char nullValue[20];    /* The text to print when a NULL comes back from
   944   1041                            ** the database */
   945   1042     char outfile[FILENAME_MAX]; /* Filename for *out */
   946   1043     const char *zDbFilename;    /* name of the database file */
   947   1044     char *zFreeOnClose;         /* Filename to free when closing */
................................................................................
   953   1050     int iIndent;           /* Index of current op in aiIndent[] */
   954   1051   #if defined(SQLITE_ENABLE_SESSION)
   955   1052     int nSession;             /* Number of active sessions */
   956   1053     OpenSession aSession[4];  /* Array of sessions.  [0] is in focus. */
   957   1054   #endif
   958   1055     ExpertInfo expert;        /* Valid if previous command was ".expert OPT..." */
   959   1056   };
         1057  +
   960   1058   
   961   1059   /* Allowed values for ShellState.autoEQP
   962   1060   */
   963   1061   #define AUTOEQP_off      0
   964   1062   #define AUTOEQP_on       1
   965   1063   #define AUTOEQP_trigger  2
   966   1064   #define AUTOEQP_full     3
   967   1065   
         1066  +/* Allowed values for ShellState.openMode
         1067  +*/
         1068  +#define SHELL_OPEN_UNSPEC     0      /* No open-mode specified */
         1069  +#define SHELL_OPEN_NORMAL     1      /* Normal database file */
         1070  +#define SHELL_OPEN_APPENDVFS  2      /* Use appendvfs */
         1071  +#define SHELL_OPEN_ZIPFILE    3      /* Use the zipfile virtual table */
         1072  +
   968   1073   /*
   969   1074   ** These are the allowed shellFlgs values
   970   1075   */
   971   1076   #define SHFLG_Pagecache      0x00000001 /* The --pagecache option is used */
   972   1077   #define SHFLG_Lookaside      0x00000002 /* Lookaside memory is used */
   973   1078   #define SHFLG_Backslash      0x00000004 /* The --backslash option is used */
   974   1079   #define SHFLG_PreserveRowid  0x00000008 /* .dump preserves rowid values */
................................................................................
  1023   1128   #define SEP_Tab       "\t"
  1024   1129   #define SEP_Space     " "
  1025   1130   #define SEP_Comma     ","
  1026   1131   #define SEP_CrLf      "\r\n"
  1027   1132   #define SEP_Unit      "\x1F"
  1028   1133   #define SEP_Record    "\x1E"
  1029   1134   
  1030         -/*
  1031         -** Number of elements in an array
  1032         -*/
  1033         -#define ArraySize(X)  (int)(sizeof(X)/sizeof(X[0]))
  1034         -
  1035   1135   /*
  1036   1136   ** A callback for the sqlite3_log() interface.
  1037   1137   */
  1038   1138   static void shellLog(void *pArg, int iErrCode, const char *zMsg){
  1039   1139     ShellState *p = (ShellState*)pArg;
  1040   1140     if( p->pLog==0 ) return;
  1041   1141     utf8_printf(p->pLog, "(%d) %s\n", iErrCode, zMsg);
  1042   1142     fflush(p->pLog);
  1043   1143   }
         1144  +
         1145  +/*
         1146  +** SQL function:  shell_putsnl(X)
         1147  +**
         1148  +** Write the text X to the screen (or whatever output is being directed)
         1149  +** adding a newline at the end, and then return X.
         1150  +*/
         1151  +static void shellPutsFunc(
         1152  +  sqlite3_context *pCtx,
         1153  +  int nVal,
         1154  +  sqlite3_value **apVal
         1155  +){
         1156  +  ShellState *p = (ShellState*)sqlite3_user_data(pCtx);
         1157  +  (void)nVal;
         1158  +  utf8_printf(p->out, "%s\n", sqlite3_value_text(apVal[0]));
         1159  +  sqlite3_result_value(pCtx, apVal[0]);
         1160  +}
         1161  +
         1162  +/*
         1163  +** SQL function:   edit(VALUE)
         1164  +**                 edit(VALUE,EDITOR)
         1165  +**
         1166  +** These steps:
         1167  +**
         1168  +**     (1) Write VALUE into a temporary file.
         1169  +**     (2) Run program EDITOR on that temporary file.
         1170  +**     (3) Read the temporary file back and return its content as the result.
         1171  +**     (4) Delete the temporary file
         1172  +**
         1173  +** If the EDITOR argument is omitted, use the value in the VISUAL
         1174  +** environment variable.  If still there is no EDITOR, through an error.
         1175  +**
         1176  +** Also throw an error if the EDITOR program returns a non-zero exit code.
         1177  +*/
         1178  +static void editFunc(
         1179  +  sqlite3_context *context,
         1180  +  int argc,
         1181  +  sqlite3_value **argv
         1182  +){
         1183  +  const char *zEditor;
         1184  +  char *zTempFile = 0;
         1185  +  sqlite3 *db;
         1186  +  char *zCmd = 0;
         1187  +  int bBin;
         1188  +  int rc;
         1189  +  FILE *f = 0;
         1190  +  sqlite3_int64 sz;
         1191  +  sqlite3_int64 x;
         1192  +  unsigned char *p = 0;
         1193  +
         1194  +  if( argc==2 ){
         1195  +    zEditor = (const char*)sqlite3_value_text(argv[1]);
         1196  +  }else{
         1197  +    zEditor = getenv("VISUAL");
         1198  +  }
         1199  +  if( zEditor==0 ){
         1200  +    sqlite3_result_error(context, "no editor for edit()", -1);
         1201  +    return;
         1202  +  }
         1203  +  if( sqlite3_value_type(argv[0])==SQLITE_NULL ){
         1204  +    sqlite3_result_error(context, "NULL input to edit()", -1);
         1205  +    return;
         1206  +  }
         1207  +  db = sqlite3_context_db_handle(context);
         1208  +  zTempFile = 0;
         1209  +  sqlite3_file_control(db, 0, SQLITE_FCNTL_TEMPFILENAME, &zTempFile);
         1210  +  if( zTempFile==0 ){
         1211  +    sqlite3_uint64 r = 0;
         1212  +    sqlite3_randomness(sizeof(r), &r);
         1213  +    zTempFile = sqlite3_mprintf("temp%llx", r);
         1214  +    if( zTempFile==0 ){
         1215  +      sqlite3_result_error_nomem(context);
         1216  +      return;
         1217  +    }
         1218  +  }
         1219  +  bBin = sqlite3_value_type(argv[0])==SQLITE_BLOB;
         1220  +  f = fopen(zTempFile, bBin ? "wb" : "w");
         1221  +  if( f==0 ){
         1222  +    sqlite3_result_error(context, "edit() cannot open temp file", -1);
         1223  +    goto edit_func_end;
         1224  +  }
         1225  +  sz = sqlite3_value_bytes(argv[0]);
         1226  +  if( bBin ){
         1227  +    x = fwrite(sqlite3_value_blob(argv[0]), 1, sz, f);
         1228  +  }else{
         1229  +    x = fwrite(sqlite3_value_text(argv[0]), 1, sz, f);
         1230  +  }
         1231  +  fclose(f);
         1232  +  f = 0;
         1233  +  if( x!=sz ){
         1234  +    sqlite3_result_error(context, "edit() could not write the whole file", -1);
         1235  +    goto edit_func_end;
         1236  +  }
         1237  +  zCmd = sqlite3_mprintf("%s \"%s\"", zEditor, zTempFile);
         1238  +  if( zCmd==0 ){
         1239  +    sqlite3_result_error_nomem(context);
         1240  +    goto edit_func_end;
         1241  +  }
         1242  +  rc = system(zCmd);
         1243  +  sqlite3_free(zCmd);
         1244  +  if( rc ){
         1245  +    sqlite3_result_error(context, "EDITOR returned non-zero", -1);
         1246  +    goto edit_func_end;
         1247  +  }
         1248  +  f = fopen(zTempFile, bBin ? "rb" : "r");
         1249  +  if( f==0 ){
         1250  +    sqlite3_result_error(context,
         1251  +      "edit() cannot reopen temp file after edit", -1);
         1252  +    goto edit_func_end;
         1253  +  }
         1254  +  fseek(f, 0, SEEK_END);
         1255  +  sz = ftell(f);
         1256  +  rewind(f);
         1257  +  p = sqlite3_malloc64( sz+(bBin==0) );
         1258  +  if( p==0 ){
         1259  +    sqlite3_result_error_nomem(context);
         1260  +    goto edit_func_end;
         1261  +  }
         1262  +  if( bBin ){
         1263  +    x = fread(p, 1, sz, f);
         1264  +  }else{
         1265  +    x = fread(p, 1, sz, f);
         1266  +    p[sz] = 0;
         1267  +  }
         1268  +  fclose(f);
         1269  +  f = 0;
         1270  +  if( x!=sz ){
         1271  +    sqlite3_result_error(context, "could not read back the whole file", -1);
         1272  +    goto edit_func_end;
         1273  +  }
         1274  +  if( bBin ){
         1275  +    sqlite3_result_blob64(context, p, sz, sqlite3_free);
         1276  +  }else{
         1277  +    sqlite3_result_text64(context, (const char*)p, sz,
         1278  +                          sqlite3_free, SQLITE_UTF8);
         1279  +  }
         1280  +  p = 0;
         1281  +
         1282  +edit_func_end:
         1283  +  if( f ) fclose(f);
         1284  +  unlink(zTempFile);
         1285  +  sqlite3_free(zTempFile);
         1286  +  sqlite3_free(p);
         1287  +}
         1288  +
         1289  +/*
         1290  +** Save or restore the current output mode
         1291  +*/
         1292  +static void outputModePush(ShellState *p){
         1293  +  p->modePrior = p->mode;
         1294  +  memcpy(p->colSepPrior, p->colSeparator, sizeof(p->colSeparator));
         1295  +  memcpy(p->rowSepPrior, p->rowSeparator, sizeof(p->rowSeparator));
         1296  +}
         1297  +static void outputModePop(ShellState *p){
         1298  +  p->mode = p->modePrior;
         1299  +  memcpy(p->colSeparator, p->colSepPrior, sizeof(p->colSeparator));
         1300  +  memcpy(p->rowSeparator, p->rowSepPrior, sizeof(p->rowSeparator));
         1301  +}
  1044   1302   
  1045   1303   /*
  1046   1304   ** Output the given string as a hex-encoded blob (eg. X'1234' )
  1047   1305   */
  1048   1306   static void output_hex_blob(FILE *out, const void *pBlob, int nBlob){
  1049   1307     int i;
  1050   1308     char *zBlob = (char *)pBlob;
................................................................................
  1387   1645   static void printSchemaLineN(FILE *out, char *z, int n, const char *zTail){
  1388   1646     char c = z[n];
  1389   1647     z[n] = 0;
  1390   1648     printSchemaLine(out, z, zTail);
  1391   1649     z[n] = c;
  1392   1650   }
  1393   1651   
         1652  +/*
         1653  +** Return true if string z[] has nothing but whitespace and comments to the
         1654  +** end of the first line.
         1655  +*/
         1656  +static int wsToEol(const char *z){
         1657  +  int i;
         1658  +  for(i=0; z[i]; i++){
         1659  +    if( z[i]=='\n' ) return 1;
         1660  +    if( IsSpace(z[i]) ) continue;
         1661  +    if( z[i]=='-' && z[i+1]=='-' ) return 1;
         1662  +    return 0;
         1663  +  }
         1664  +  return 1;
         1665  +}
         1666  +    
         1667  +
  1394   1668   /*
  1395   1669   ** This is the callback routine that the shell
  1396   1670   ** invokes for each row of a query result.
  1397   1671   */
  1398   1672   static int shell_callback(
  1399   1673     void *pArg,
  1400   1674     int nArg,        /* Number of result columns */
................................................................................
  1526   1800             j--;
  1527   1801           }
  1528   1802           z[j++] = c;
  1529   1803         }
  1530   1804         while( j>0 && IsSpace(z[j-1]) ){ j--; }
  1531   1805         z[j] = 0;
  1532   1806         if( strlen30(z)>=79 ){
  1533         -        for(i=j=0; (c = z[i])!=0; i++){
         1807  +        for(i=j=0; (c = z[i])!=0; i++){  /* Copy changes from z[i] back to z[j] */
  1534   1808             if( c==cEnd ){
  1535   1809               cEnd = 0;
  1536   1810             }else if( c=='"' || c=='\'' || c=='`' ){
  1537   1811               cEnd = c;
  1538   1812             }else if( c=='[' ){
  1539   1813               cEnd = ']';
         1814  +          }else if( c=='-' && z[i+1]=='-' ){
         1815  +            cEnd = '\n';
  1540   1816             }else if( c=='(' ){
  1541   1817               nParen++;
  1542   1818             }else if( c==')' ){
  1543   1819               nParen--;
  1544   1820               if( nLine>0 && nParen==0 && j>0 ){
  1545   1821                 printSchemaLineN(p->out, z, j, "\n");
  1546   1822                 j = 0;
  1547   1823               }
  1548   1824             }
  1549   1825             z[j++] = c;
  1550         -          if( nParen==1 && (c=='(' || c==',' || c=='\n') ){
         1826  +          if( nParen==1 && cEnd==0
         1827  +           && (c=='(' || c=='\n' || (c==',' && !wsToEol(z+i+1)))
         1828  +          ){
  1551   1829               if( c=='\n' ) j--;
  1552   1830               printSchemaLineN(p->out, z, j, "\n  ");
  1553   1831               j = 0;
  1554   1832               nLine++;
  1555   1833               while( IsSpace(z[i+1]) ){ i++; }
  1556   1834             }
  1557   1835           }
................................................................................
  1941   2219         { "syscw: ",                  "Write() system calls:"     },
  1942   2220         { "read_bytes: ",             "Bytes read from storage:"  },
  1943   2221         { "write_bytes: ",            "Bytes written to storage:" },
  1944   2222         { "cancelled_write_bytes: ",  "Cancelled write bytes:"    },
  1945   2223       };
  1946   2224       int i;
  1947   2225       for(i=0; i<ArraySize(aTrans); i++){
  1948         -      int n = (int)strlen(aTrans[i].zPattern);
         2226  +      int n = strlen30(aTrans[i].zPattern);
  1949   2227         if( strncmp(aTrans[i].zPattern, z, n)==0 ){
  1950   2228           utf8_printf(out, "%-36s %s", aTrans[i].zDesc, &z[n]);
  1951   2229           break;
  1952   2230         }
  1953   2231       }
  1954   2232     }
  1955   2233     fclose(in);
................................................................................
  2342   2620         do{
  2343   2621           rc = sqlite3_step(pStmt);
  2344   2622         } while( rc == SQLITE_ROW );
  2345   2623       }
  2346   2624     }
  2347   2625   }
  2348   2626   
         2627  +#ifndef SQLITE_OMIT_VIRTUALTABLE
  2349   2628   /*
  2350   2629   ** This function is called to process SQL if the previous shell command
  2351   2630   ** was ".expert". It passes the SQL in the second argument directly to
  2352   2631   ** the sqlite3expert object.
  2353   2632   **
  2354   2633   ** If successful, SQLITE_OK is returned. Otherwise, an SQLite error
  2355   2634   ** code. In this case, (*pzErr) may be set to point to a buffer containing
................................................................................
  2414   2693       }
  2415   2694     }
  2416   2695     sqlite3_expert_destroy(p);
  2417   2696     pState->expert.pExpert = 0;
  2418   2697     return rc;
  2419   2698   }
  2420   2699   
         2700  +/*
         2701  +** Implementation of ".expert" dot command.
         2702  +*/
         2703  +static int expertDotCommand(
         2704  +  ShellState *pState,             /* Current shell tool state */
         2705  +  char **azArg,                   /* Array of arguments passed to dot command */
         2706  +  int nArg                        /* Number of entries in azArg[] */
         2707  +){
         2708  +  int rc = SQLITE_OK;
         2709  +  char *zErr = 0;
         2710  +  int i;
         2711  +  int iSample = 0;
         2712  +
         2713  +  assert( pState->expert.pExpert==0 );
         2714  +  memset(&pState->expert, 0, sizeof(ExpertInfo));
         2715  +
         2716  +  for(i=1; rc==SQLITE_OK && i<nArg; i++){
         2717  +    char *z = azArg[i];
         2718  +    int n;
         2719  +    if( z[0]=='-' && z[1]=='-' ) z++;
         2720  +    n = strlen30(z);
         2721  +    if( n>=2 && 0==strncmp(z, "-verbose", n) ){
         2722  +      pState->expert.bVerbose = 1;
         2723  +    }
         2724  +    else if( n>=2 && 0==strncmp(z, "-sample", n) ){
         2725  +      if( i==(nArg-1) ){
         2726  +        raw_printf(stderr, "option requires an argument: %s\n", z);
         2727  +        rc = SQLITE_ERROR;
         2728  +      }else{
         2729  +        iSample = (int)integerValue(azArg[++i]);
         2730  +        if( iSample<0 || iSample>100 ){
         2731  +          raw_printf(stderr, "value out of range: %s\n", azArg[i]);
         2732  +          rc = SQLITE_ERROR;
         2733  +        }
         2734  +      }
         2735  +    }
         2736  +    else{
         2737  +      raw_printf(stderr, "unknown option: %s\n", z);
         2738  +      rc = SQLITE_ERROR;
         2739  +    }
         2740  +  }
         2741  +
         2742  +  if( rc==SQLITE_OK ){
         2743  +    pState->expert.pExpert = sqlite3_expert_new(pState->db, &zErr);
         2744  +    if( pState->expert.pExpert==0 ){
         2745  +      raw_printf(stderr, "sqlite3_expert_new: %s\n", zErr);
         2746  +      rc = SQLITE_ERROR;
         2747  +    }else{
         2748  +      sqlite3_expert_config(
         2749  +          pState->expert.pExpert, EXPERT_CONFIG_SAMPLE, iSample
         2750  +      );
         2751  +    }
         2752  +  }
         2753  +
         2754  +  return rc;
         2755  +}
         2756  +#endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */
  2421   2757   
  2422   2758   /*
  2423   2759   ** Execute a statement or set of statements.  Print
  2424   2760   ** any result rows/columns depending on the current mode
  2425   2761   ** set via the supplied callback.
  2426   2762   **
  2427   2763   ** This is very similar to SQLite's built-in sqlite3_exec()
................................................................................
  2441   2777     int rc2;
  2442   2778     const char *zLeftover;          /* Tail of unprocessed SQL */
  2443   2779   
  2444   2780     if( pzErrMsg ){
  2445   2781       *pzErrMsg = NULL;
  2446   2782     }
  2447   2783   
         2784  +#ifndef SQLITE_OMIT_VIRTUALTABLE
  2448   2785     if( pArg->expert.pExpert ){
  2449   2786       rc = expertHandleSQL(pArg, zSql, pzErrMsg);
  2450   2787       return expertFinish(pArg, (rc!=SQLITE_OK), pzErrMsg);
  2451   2788     }
         2789  +#endif
  2452   2790   
  2453   2791     while( zSql[0] && (SQLITE_OK == rc) ){
  2454   2792       static const char *zStmtSql;
  2455   2793       rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, &zLeftover);
  2456   2794       if( SQLITE_OK != rc ){
  2457   2795         if( pzErrMsg ){
  2458   2796           *pzErrMsg = save_err_msg(db);
................................................................................
  2851   3189     return rc;
  2852   3190   }
  2853   3191   
  2854   3192   /*
  2855   3193   ** Text of a help message
  2856   3194   */
  2857   3195   static char zHelp[] =
         3196  +#if defined(SQLITE_HAVE_ZLIB) && !defined(SQLITE_OMIT_VIRTUALTABLE)
         3197  +  ".archive ...           Manage SQL archives: \".archive --help\" for details\n"
         3198  +#endif
  2858   3199   #ifndef SQLITE_OMIT_AUTHORIZATION
  2859   3200     ".auth ON|OFF           Show authorizer callbacks\n"
  2860   3201   #endif
  2861   3202     ".backup ?DB? FILE      Backup DB (default \"main\") to FILE\n"
  2862   3203     ".bail on|off           Stop after hitting an error.  Default OFF\n"
  2863   3204     ".binary on|off         Turn binary output on or off.  Default OFF\n"
  2864   3205     ".cd DIRECTORY          Change the working directory to DIRECTORY\n"
................................................................................
  2868   3209     ".databases             List names and files of attached databases\n"
  2869   3210     ".dbinfo ?DB?           Show status information about the database\n"
  2870   3211     ".dump ?TABLE? ...      Dump the database in an SQL text format\n"
  2871   3212     "                         If TABLE specified, only dump tables matching\n"
  2872   3213     "                         LIKE pattern TABLE.\n"
  2873   3214     ".echo on|off           Turn command echo on or off\n"
  2874   3215     ".eqp on|off|full       Enable or disable automatic EXPLAIN QUERY PLAN\n"
         3216  +  ".excel                 Display the output of next command in a spreadsheet\n"
  2875   3217     ".exit                  Exit this program\n"
  2876   3218     ".expert                EXPERIMENTAL. Suggest indexes for specified queries\n"
  2877   3219   /* Because explain mode comes on automatically now, the ".explain" mode
  2878   3220   ** is removed from the help screen.  It is still supported for legacy, however */
  2879   3221   /*".explain ?on|off|auto? Turn EXPLAIN output mode on or off or to automatic\n"*/
  2880   3222     ".fullschema ?--indent? Show schema and the content of sqlite_stat tables\n"
  2881   3223     ".headers on|off        Turn display of headers on or off\n"
................................................................................
  2905   3247     "                         insert   SQL insert statements for TABLE\n"
  2906   3248     "                         line     One value per line\n"
  2907   3249     "                         list     Values delimited by \"|\"\n"
  2908   3250     "                         quote    Escape answers as for SQL\n"
  2909   3251     "                         tabs     Tab-separated values\n"
  2910   3252     "                         tcl      TCL list elements\n"
  2911   3253     ".nullvalue STRING      Use STRING in place of NULL values\n"
  2912         -  ".once FILENAME         Output for the next SQL command only to FILENAME\n"
         3254  +  ".once (-e|-x|FILE)     Output for the next SQL command only to FILE\n"
         3255  +  "                         or invoke system text editor (-e) or spreadsheet (-x)\n"
         3256  +  "                         on the output.\n"
  2913   3257     ".open ?OPTIONS? ?FILE? Close existing database and reopen FILE\n"
  2914   3258     "                         The --new option starts with an empty file\n"
  2915         -  ".output ?FILENAME?     Send output to FILENAME or stdout\n"
         3259  +  ".output ?FILE?         Send output to FILE or stdout\n"
  2916   3260     ".print STRING...       Print literal STRING\n"
  2917   3261     ".prompt MAIN CONTINUE  Replace the standard prompts\n"
  2918   3262     ".quit                  Exit this program\n"
  2919   3263     ".read FILENAME         Execute SQL in FILENAME\n"
  2920   3264     ".restore ?DB? FILE     Restore content of DB (default \"main\") from FILE\n"
  2921   3265     ".save FILE             Write in-memory database into FILE\n"
  2922   3266     ".scanstats on|off      Turn sqlite3_stmt_scanstatus() metrics on or off\n"
................................................................................
  3053   3397     int i;
  3054   3398     for(i=0; i<pSession->nFilter; i++){
  3055   3399       if( sqlite3_strglob(pSession->azFilter[i], zTab)==0 ) return 0;
  3056   3400     }
  3057   3401     return 1;
  3058   3402   }
  3059   3403   #endif
         3404  +
         3405  +/*
         3406  +** Try to deduce the type of file for zName based on its content.  Return
         3407  +** one of the SHELL_OPEN_* constants.
         3408  +*/
         3409  +static int deduceDatabaseType(const char *zName){
         3410  +  FILE *f = fopen(zName, "rb");
         3411  +  size_t n;
         3412  +  int rc = SHELL_OPEN_UNSPEC;
         3413  +  char zBuf[100];
         3414  +  if( f==0 ) return SHELL_OPEN_NORMAL;
         3415  +  fseek(f, -25, SEEK_END);
         3416  +  n = fread(zBuf, 25, 1, f);
         3417  +  if( n==1 && memcmp(zBuf, "Start-Of-SQLite3-", 17)==0 ){
         3418  +    rc = SHELL_OPEN_APPENDVFS;
         3419  +  }else{
         3420  +    fseek(f, -22, SEEK_END);
         3421  +    n = fread(zBuf, 22, 1, f);
         3422  +    if( n==1 && zBuf[0]==0x50 && zBuf[1]==0x4b && zBuf[2]==0x05
         3423  +       && zBuf[3]==0x06 ){
         3424  +      rc = SHELL_OPEN_ZIPFILE;
         3425  +    }
         3426  +  }
         3427  +  fclose(f);
         3428  +  return rc;  
         3429  +}
  3060   3430   
  3061   3431   /*
  3062   3432   ** Make sure the database is open.  If it is not, then open it.  If
  3063   3433   ** the database fails to open, print an error message and exit.
  3064   3434   */
  3065   3435   static void open_db(ShellState *p, int keepAlive){
  3066   3436     if( p->db==0 ){
  3067   3437       sqlite3_initialize();
  3068         -    sqlite3_open(p->zDbFilename, &p->db);
         3438  +    if( p->openMode==SHELL_OPEN_UNSPEC && access(p->zDbFilename,0)==0 ){
         3439  +      p->openMode = (u8)deduceDatabaseType(p->zDbFilename);
         3440  +    }
         3441  +    switch( p->openMode ){
         3442  +      case SHELL_OPEN_APPENDVFS: {
         3443  +        sqlite3_open_v2(p->zDbFilename, &p->db, 
         3444  +           SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE, "apndvfs");
         3445  +        break;
         3446  +      }
         3447  +      case SHELL_OPEN_ZIPFILE: {
         3448  +        sqlite3_open(":memory:", &p->db);
         3449  +        break;
         3450  +      }
         3451  +      case SHELL_OPEN_UNSPEC:
         3452  +      case SHELL_OPEN_NORMAL: {
         3453  +        sqlite3_open(p->zDbFilename, &p->db);
         3454  +        break;
         3455  +      }
         3456  +    }
  3069   3457       globalDb = p->db;
  3070   3458       if( p->db==0 || SQLITE_OK!=sqlite3_errcode(p->db) ){
  3071   3459         utf8_printf(stderr,"Error: unable to open database \"%s\": %s\n",
  3072   3460             p->zDbFilename, sqlite3_errmsg(p->db));
  3073   3461         if( keepAlive ) return;
  3074   3462         exit(1);
  3075   3463       }
  3076   3464   #ifndef SQLITE_OMIT_LOAD_EXTENSION
  3077   3465       sqlite3_enable_load_extension(p->db, 1);
  3078   3466   #endif
  3079   3467       sqlite3_fileio_init(p->db, 0, 0);
  3080   3468       sqlite3_shathree_init(p->db, 0, 0);
  3081   3469       sqlite3_completion_init(p->db, 0, 0);
         3470  +#ifdef SQLITE_HAVE_ZLIB
         3471  +    sqlite3_zipfile_init(p->db, 0, 0);
         3472  +    sqlite3_sqlar_init(p->db, 0, 0);
         3473  +#endif
  3082   3474       sqlite3_create_function(p->db, "shell_add_schema", 3, SQLITE_UTF8, 0,
  3083   3475                               shellAddSchemaName, 0, 0);
  3084   3476       sqlite3_create_function(p->db, "shell_module_schema", 1, SQLITE_UTF8, 0,
  3085   3477                               shellModuleSchema, 0, 0);
         3478  +    sqlite3_create_function(p->db, "shell_putsnl", 1, SQLITE_UTF8, p,
         3479  +                            shellPutsFunc, 0, 0);
         3480  +    sqlite3_create_function(p->db, "edit", 1, SQLITE_UTF8, 0,
         3481  +                            editFunc, 0, 0);
         3482  +    sqlite3_create_function(p->db, "edit", 2, SQLITE_UTF8, 0,
         3483  +                            editFunc, 0, 0);
         3484  +    if( p->openMode==SHELL_OPEN_ZIPFILE ){
         3485  +      char *zSql = sqlite3_mprintf(
         3486  +         "CREATE VIRTUAL TABLE zip USING zipfile(%Q);", p->zDbFilename);
         3487  +      sqlite3_exec(p->db, zSql, 0, 0, 0);
         3488  +      sqlite3_free(zSql);
         3489  +    }
  3086   3490     }
  3087   3491   }
  3088   3492   
  3089   3493   #if HAVE_READLINE || HAVE_EDITLINE
  3090   3494   /*
  3091   3495   ** Readline completion callbacks
  3092   3496   */
................................................................................
  3116   3520   }
  3117   3521   
  3118   3522   #elif HAVE_LINENOISE
  3119   3523   /*
  3120   3524   ** Linenoise completion callback
  3121   3525   */
  3122   3526   static void linenoise_completion(const char *zLine, linenoiseCompletions *lc){
  3123         -  int nLine = (int)strlen(zLine);
         3527  +  int nLine = strlen30(zLine);
  3124   3528     int i, iStart;
  3125   3529     sqlite3_stmt *pStmt = 0;
  3126   3530     char *zSql;
  3127   3531     char zBuf[1000];
  3128   3532   
  3129   3533     if( nLine>sizeof(zBuf)-30 ) return;
  3130   3534     if( zLine[0]=='.' ) return;
................................................................................
  3206   3610         }
  3207   3611       }
  3208   3612       z[j] = c;
  3209   3613     }
  3210   3614     if( j<i ) z[j] = 0;
  3211   3615   }
  3212   3616   
  3213         -/*
  3214         -** Return the value of a hexadecimal digit.  Return -1 if the input
  3215         -** is not a hex digit.
  3216         -*/
  3217         -static int hexDigitValue(char c){
  3218         -  if( c>='0' && c<='9' ) return c - '0';
  3219         -  if( c>='a' && c<='f' ) return c - 'a' + 10;
  3220         -  if( c>='A' && c<='F' ) return c - 'A' + 10;
  3221         -  return -1;
  3222         -}
  3223         -
  3224         -/*
  3225         -** Interpret zArg as an integer value, possibly with suffixes.
  3226         -*/
  3227         -static sqlite3_int64 integerValue(const char *zArg){
  3228         -  sqlite3_int64 v = 0;
  3229         -  static const struct { char *zSuffix; int iMult; } aMult[] = {
  3230         -    { "KiB", 1024 },
  3231         -    { "MiB", 1024*1024 },
  3232         -    { "GiB", 1024*1024*1024 },
  3233         -    { "KB",  1000 },
  3234         -    { "MB",  1000000 },
  3235         -    { "GB",  1000000000 },
  3236         -    { "K",   1000 },
  3237         -    { "M",   1000000 },
  3238         -    { "G",   1000000000 },
  3239         -  };
  3240         -  int i;
  3241         -  int isNeg = 0;
  3242         -  if( zArg[0]=='-' ){
  3243         -    isNeg = 1;
  3244         -    zArg++;
  3245         -  }else if( zArg[0]=='+' ){
  3246         -    zArg++;
  3247         -  }
  3248         -  if( zArg[0]=='0' && zArg[1]=='x' ){
  3249         -    int x;
  3250         -    zArg += 2;
  3251         -    while( (x = hexDigitValue(zArg[0]))>=0 ){
  3252         -      v = (v<<4) + x;
  3253         -      zArg++;
  3254         -    }
  3255         -  }else{
  3256         -    while( IsDigit(zArg[0]) ){
  3257         -      v = v*10 + zArg[0] - '0';
  3258         -      zArg++;
  3259         -    }
  3260         -  }
  3261         -  for(i=0; i<ArraySize(aMult); i++){
  3262         -    if( sqlite3_stricmp(aMult[i].zSuffix, zArg)==0 ){
  3263         -      v *= aMult[i].iMult;
  3264         -      break;
  3265         -    }
  3266         -  }
  3267         -  return isNeg? -v : v;
  3268         -}
  3269         -
  3270   3617   /*
  3271   3618   ** Interpret zArg as either an integer or a boolean value.  Return 1 or 0
  3272   3619   ** for TRUE and FALSE.  Return the integer value if appropriate.
  3273   3620   */
  3274   3621   static int booleanValue(const char *zArg){
  3275   3622     int i;
  3276   3623     if( zArg[0]=='0' && zArg[1]=='x' ){
................................................................................
  3309   3656   }
  3310   3657   
  3311   3658   /*
  3312   3659   ** Try to open an output file.   The names "stdout" and "stderr" are
  3313   3660   ** recognized and do the right thing.  NULL is returned if the output
  3314   3661   ** filename is "off".
  3315   3662   */
  3316         -static FILE *output_file_open(const char *zFile){
         3663  +static FILE *output_file_open(const char *zFile, int bTextMode){
  3317   3664     FILE *f;
  3318   3665     if( strcmp(zFile,"stdout")==0 ){
  3319   3666       f = stdout;
  3320   3667     }else if( strcmp(zFile, "stderr")==0 ){
  3321   3668       f = stderr;
  3322   3669     }else if( strcmp(zFile, "off")==0 ){
  3323   3670       f = 0;
  3324   3671     }else{
  3325         -    f = fopen(zFile, "wb");
         3672  +    f = fopen(zFile, bTextMode ? "w" : "wb");
  3326   3673       if( f==0 ){
  3327   3674         utf8_printf(stderr, "Error: cannot open \"%s\"\n", zFile);
  3328   3675       }
  3329   3676     }
  3330   3677     return f;
  3331   3678   }
  3332   3679   
................................................................................
  3342   3689     void *pX
  3343   3690   ){
  3344   3691     FILE *f = (FILE*)pArg;
  3345   3692     UNUSED_PARAMETER(mType);
  3346   3693     UNUSED_PARAMETER(pP);
  3347   3694     if( f ){
  3348   3695       const char *z = (const char*)pX;
  3349         -    int i = (int)strlen(z);
         3696  +    int i = strlen30(z);
  3350   3697       while( i>0 && z[i-1]==';' ){ i--; }
  3351   3698       utf8_printf(f, "%.*s;\n", i, z);
  3352   3699     }
  3353   3700     return 0;
  3354   3701   }
  3355   3702   #endif
  3356   3703   #endif
................................................................................
  3531   3878   ){
  3532   3879     sqlite3_stmt *pQuery = 0;
  3533   3880     sqlite3_stmt *pInsert = 0;
  3534   3881     char *zQuery = 0;
  3535   3882     char *zInsert = 0;
  3536   3883     int rc;
  3537   3884     int i, j, n;
  3538         -  int nTable = (int)strlen(zTable);
         3885  +  int nTable = strlen30(zTable);
  3539   3886     int k = 0;
  3540   3887     int cnt = 0;
  3541   3888     const int spinRate = 10000;
  3542   3889   
  3543   3890     zQuery = sqlite3_mprintf("SELECT * FROM \"%w\"", zTable);
  3544   3891     rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
  3545   3892     if( rc ){
................................................................................
  3552   3899     zInsert = sqlite3_malloc64(200 + nTable + n*3);
  3553   3900     if( zInsert==0 ){
  3554   3901       raw_printf(stderr, "out of memory\n");
  3555   3902       goto end_data_xfer;
  3556   3903     }
  3557   3904     sqlite3_snprintf(200+nTable,zInsert,
  3558   3905                      "INSERT OR IGNORE INTO \"%s\" VALUES(?", zTable);
  3559         -  i = (int)strlen(zInsert);
         3906  +  i = strlen30(zInsert);
  3560   3907     for(j=1; j<n; j++){
  3561   3908       memcpy(zInsert+i, ",?", 2);
  3562   3909       i += 2;
  3563   3910     }
  3564   3911     memcpy(zInsert+i, ");", 3);
  3565   3912     rc = sqlite3_prepare_v2(newDb, zInsert, -1, &pInsert, 0);
  3566   3913     if( rc ){
................................................................................
  3731   4078       sqlite3_exec(newDb, "COMMIT;", 0, 0, 0);
  3732   4079       sqlite3_exec(p->db, "PRAGMA writable_schema=OFF;", 0, 0, 0);
  3733   4080     }
  3734   4081     sqlite3_close(newDb);
  3735   4082   }
  3736   4083   
  3737   4084   /*
  3738         -** Change the output file back to stdout
         4085  +** Change the output file back to stdout.
         4086  +**
         4087  +** If the p->doXdgOpen flag is set, that means the output was being
         4088  +** redirected to a temporary file named by p->zTempFile.  In that case,
         4089  +** launch start/open/xdg-open on that temporary file.
  3739   4090   */
  3740   4091   static void output_reset(ShellState *p){
  3741   4092     if( p->outfile[0]=='|' ){
  3742   4093   #ifndef SQLITE_OMIT_POPEN
  3743   4094       pclose(p->out);
  3744   4095   #endif
  3745   4096     }else{
  3746   4097       output_file_close(p->out);
         4098  +    if( p->doXdgOpen ){
         4099  +      const char *zXdgOpenCmd =
         4100  +#if defined(_WIN32)
         4101  +      "start";
         4102  +#elif defined(__APPLE__)
         4103  +      "open";
         4104  +#else
         4105  +      "xdg-open";
         4106  +#endif
         4107  +      char *zCmd;
         4108  +      zCmd = sqlite3_mprintf("%s %s", zXdgOpenCmd, p->zTempFile);
         4109  +      if( system(zCmd) ){
         4110  +        utf8_printf(stderr, "Failed: [%s]\n", zCmd);
         4111  +      }
         4112  +      sqlite3_free(zCmd);
         4113  +      outputModePop(p);
         4114  +      p->doXdgOpen = 0;
         4115  +    }
  3747   4116     }
  3748   4117     p->outfile[0] = 0;
  3749   4118     p->out = stdout;
  3750   4119   }
  3751   4120   
  3752   4121   /*
  3753   4122   ** Run an SQL command and return the single integer result.
................................................................................
  3998   4367     sqlite3_free(z);
  3999   4368   #else
  4000   4369     rc = unlink(zFilename);
  4001   4370   #endif
  4002   4371     return rc;
  4003   4372   }
  4004   4373   
         4374  +/*
         4375  +** Try to delete the temporary file (if there is one) and free the
         4376  +** memory used to hold the name of the temp file.
         4377  +*/
         4378  +static void clearTempFile(ShellState *p){
         4379  +  if( p->zTempFile==0 ) return;
         4380  +  if( p->doXdgOpen ) return;
         4381  +  if( shellDeleteFile(p->zTempFile) ) return;
         4382  +  sqlite3_free(p->zTempFile);
         4383  +  p->zTempFile = 0;
         4384  +}
         4385  +
         4386  +/*
         4387  +** Create a new temp file name with the given suffix.
         4388  +*/
         4389  +static void newTempFile(ShellState *p, const char *zSuffix){
         4390  +  clearTempFile(p);
         4391  +  sqlite3_free(p->zTempFile);
         4392  +  p->zTempFile = 0;
         4393  +  if( p->db ){
         4394  +    sqlite3_file_control(p->db, 0, SQLITE_FCNTL_TEMPFILENAME, &p->zTempFile);
         4395  +  }
         4396  +  if( p->zTempFile==0 ){
         4397  +    sqlite3_uint64 r;
         4398  +    sqlite3_randomness(sizeof(r), &r);
         4399  +    p->zTempFile = sqlite3_mprintf("temp%llx.%s", r, zSuffix);
         4400  +  }else{
         4401  +    p->zTempFile = sqlite3_mprintf("%z.%s", p->zTempFile, zSuffix);
         4402  +  }
         4403  +  if( p->zTempFile==0 ){
         4404  +    raw_printf(stderr, "out of memory\n");
         4405  +    exit(1);
         4406  +  }
         4407  +}
         4408  +
  4005   4409   
  4006   4410   /*
  4007   4411   ** The implementation of SQL scalar function fkey_collate_clause(), used
  4008   4412   ** by the ".lint fkey-indexes" command. This scalar function is always
  4009   4413   ** called with four arguments - the parent table name, the parent column name,
  4010   4414   ** the child table name and the child column name.
  4011   4415   **
................................................................................
  4134   4538       "LEFT JOIN pragma_table_info AS p ON (pk-1=seq AND p.arg=f.[table]) "
  4135   4539       "GROUP BY s.name, f.id "
  4136   4540       "ORDER BY (CASE WHEN ? THEN f.[table] ELSE s.name END)"
  4137   4541     ;
  4138   4542     const char *zGlobIPK = "SEARCH TABLE * USING INTEGER PRIMARY KEY (rowid=?)";
  4139   4543   
  4140   4544     for(i=2; i<nArg; i++){
  4141         -    int n = (int)strlen(azArg[i]);
         4545  +    int n = strlen30(azArg[i]);
  4142   4546       if( n>1 && sqlite3_strnicmp("-verbose", azArg[i], n)==0 ){
  4143   4547         bVerbose = 1;
  4144   4548       }
  4145   4549       else if( n>1 && sqlite3_strnicmp("-groupbyparent", azArg[i], n)==0 ){
  4146   4550         bGroupByParent = 1;
  4147   4551         zIndent = "    ";
  4148   4552       }
................................................................................
  4237   4641   */
  4238   4642   static int lintDotCommand(
  4239   4643     ShellState *pState,             /* Current shell tool state */
  4240   4644     char **azArg,                   /* Array of arguments passed to dot command */
  4241   4645     int nArg                        /* Number of entries in azArg[] */
  4242   4646   ){
  4243   4647     int n;
  4244         -  n = (nArg>=2 ? (int)strlen(azArg[1]) : 0);
         4648  +  n = (nArg>=2 ? strlen30(azArg[1]) : 0);
  4245   4649     if( n<1 || sqlite3_strnicmp(azArg[1], "fkey-indexes", n) ) goto usage;
  4246   4650     return lintFkeyIndexes(pState, azArg, nArg);
  4247   4651   
  4248   4652    usage:
  4249   4653     raw_printf(stderr, "Usage %s sub-command ?switches...?\n", azArg[0]);
  4250   4654     raw_printf(stderr, "Where sub-commands are:\n");
  4251   4655     raw_printf(stderr, "    fkey-indexes\n");
  4252   4656     return SQLITE_ERROR;
  4253   4657   }
  4254   4658   
  4255         -/*
  4256         -** Implementation of ".expert" dot command.
  4257         -*/
  4258         -static int expertDotCommand(
         4659  +#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB)
         4660  +/*********************************************************************************
         4661  +** The ".archive" or ".ar" command.
         4662  +*/
         4663  +static void shellPrepare(
         4664  +  sqlite3 *db, 
         4665  +  int *pRc, 
         4666  +  const char *zSql, 
         4667  +  sqlite3_stmt **ppStmt
         4668  +){
         4669  +  *ppStmt = 0;
         4670  +  if( *pRc==SQLITE_OK ){
         4671  +    int rc = sqlite3_prepare_v2(db, zSql, -1, ppStmt, 0);
         4672  +    if( rc!=SQLITE_OK ){
         4673  +      raw_printf(stderr, "sql error: %s (%d)\n", 
         4674  +          sqlite3_errmsg(db), sqlite3_errcode(db)
         4675  +      );
         4676  +      *pRc = rc;
         4677  +    }
         4678  +  }
         4679  +}
         4680  +
         4681  +static void shellPreparePrintf(
         4682  +  sqlite3 *db, 
         4683  +  int *pRc, 
         4684  +  sqlite3_stmt **ppStmt,
         4685  +  const char *zFmt, 
         4686  +  ...
         4687  +){
         4688  +  *ppStmt = 0;
         4689  +  if( *pRc==SQLITE_OK ){
         4690  +    va_list ap;
         4691  +    char *z;
         4692  +    va_start(ap, zFmt);
         4693  +    z = sqlite3_vmprintf(zFmt, ap);
         4694  +    if( z==0 ){
         4695  +      *pRc = SQLITE_NOMEM;
         4696  +    }else{
         4697  +      shellPrepare(db, pRc, z, ppStmt);
         4698  +      sqlite3_free(z);
         4699  +    }
         4700  +  }
         4701  +}
         4702  +
         4703  +static void shellFinalize(
         4704  +  int *pRc, 
         4705  +  sqlite3_stmt *pStmt
         4706  +){
         4707  +  if( pStmt ){
         4708  +    sqlite3 *db = sqlite3_db_handle(pStmt);
         4709  +    int rc = sqlite3_finalize(pStmt);
         4710  +    if( *pRc==SQLITE_OK ){
         4711  +      if( rc!=SQLITE_OK ){
         4712  +        raw_printf(stderr, "SQL error: %s\n", sqlite3_errmsg(db));
         4713  +      }
         4714  +      *pRc = rc;
         4715  +    }
         4716  +  }
         4717  +}
         4718  +
         4719  +static void shellReset(
         4720  +  int *pRc, 
         4721  +  sqlite3_stmt *pStmt
         4722  +){
         4723  +  int rc = sqlite3_reset(pStmt);
         4724  +  if( *pRc==SQLITE_OK ){
         4725  +    if( rc!=SQLITE_OK ){
         4726  +      sqlite3 *db = sqlite3_db_handle(pStmt);
         4727  +      raw_printf(stderr, "SQL error: %s\n", sqlite3_errmsg(db));
         4728  +    }
         4729  +    *pRc = rc;
         4730  +  }
         4731  +}
         4732  +/*
         4733  +** Structure representing a single ".ar" command.
         4734  +*/
         4735  +typedef struct ArCommand ArCommand;
         4736  +struct ArCommand {
         4737  +  u8 eCmd;                        /* An AR_CMD_* value */
         4738  +  u8 bVerbose;                    /* True if --verbose */
         4739  +  u8 bZip;                        /* True if the archive is a ZIP */
         4740  +  u8 bDryRun;                     /* True if --dry-run */
         4741  +  u8 bAppend;                     /* True if --append */
         4742  +  int nArg;                       /* Number of command arguments */
         4743  +  char *zSrcTable;                /* "sqlar", "zipfile($file)" or "zip" */
         4744  +  const char *zFile;              /* --file argument, or NULL */
         4745  +  const char *zDir;               /* --directory argument, or NULL */
         4746  +  char **azArg;                   /* Array of command arguments */
         4747  +  ShellState *p;                  /* Shell state */
         4748  +  sqlite3 *db;                    /* Database containing the archive */
         4749  +};
         4750  +
         4751  +/*
         4752  +** Print a usage message for the .ar command to stderr and return SQLITE_ERROR.
         4753  +*/
         4754  +static int arUsage(FILE *f){
         4755  +  raw_printf(f,
         4756  +"\n"
         4757  +"Usage: .ar [OPTION...] [FILE...]\n"
         4758  +"The .ar command manages sqlar archives.\n"
         4759  +"\n"
         4760  +"Examples:\n"
         4761  +"  .ar -cf archive.sar foo bar    # Create archive.sar from files foo and bar\n"
         4762  +"  .ar -tf archive.sar            # List members of archive.sar\n"
         4763  +"  .ar -xvf archive.sar           # Verbosely extract files from archive.sar\n"
         4764  +"\n"
         4765  +"Each command line must feature exactly one command option:\n"
         4766  +"  -c, --create               Create a new archive\n"
         4767  +"  -u, --update               Update or add files to an existing archive\n"
         4768  +"  -t, --list                 List contents of archive\n"
         4769  +"  -x, --extract              Extract files from archive\n"
         4770  +"\n"
         4771  +"And zero or more optional options:\n"
         4772  +"  -v, --verbose              Print each filename as it is processed\n"
         4773  +"  -f FILE, --file FILE       Operate on archive FILE (default is current db)\n"
         4774  +"  -a FILE, --append FILE     Operate on FILE opened using the apndvfs VFS\n"
         4775  +"  -C DIR, --directory DIR    Change to directory DIR to read/extract files\n"
         4776  +"  -n, --dryrun               Show the SQL that would have occurred\n"
         4777  +"\n"
         4778  +"See also: http://sqlite.org/cli.html#sqlar_archive_support\n"
         4779  +"\n"
         4780  +);
         4781  +  return SQLITE_ERROR;
         4782  +}
         4783  +
         4784  +/*
         4785  +** Print an error message for the .ar command to stderr and return 
         4786  +** SQLITE_ERROR.
         4787  +*/
         4788  +static int arErrorMsg(const char *zFmt, ...){
         4789  +  va_list ap;
         4790  +  char *z;
         4791  +  va_start(ap, zFmt);
         4792  +  z = sqlite3_vmprintf(zFmt, ap);
         4793  +  va_end(ap);
         4794  +  raw_printf(stderr, "Error: %s (try \".ar --help\")\n", z);
         4795  +  sqlite3_free(z);
         4796  +  return SQLITE_ERROR;
         4797  +}
         4798  +
         4799  +/*
         4800  +** Values for ArCommand.eCmd.
         4801  +*/
         4802  +#define AR_CMD_CREATE       1
         4803  +#define AR_CMD_EXTRACT      2
         4804  +#define AR_CMD_LIST         3
         4805  +#define AR_CMD_UPDATE       4
         4806  +#define AR_CMD_HELP         5
         4807  +
         4808  +/*
         4809  +** Other (non-command) switches.
         4810  +*/
         4811  +#define AR_SWITCH_VERBOSE     6
         4812  +#define AR_SWITCH_FILE        7
         4813  +#define AR_SWITCH_DIRECTORY   8
         4814  +#define AR_SWITCH_APPEND      9
         4815  +#define AR_SWITCH_DRYRUN     10
         4816  +
         4817  +static int arProcessSwitch(ArCommand *pAr, int eSwitch, const char *zArg){
         4818  +  switch( eSwitch ){
         4819  +    case AR_CMD_CREATE:
         4820  +    case AR_CMD_EXTRACT:
         4821  +    case AR_CMD_LIST:
         4822  +    case AR_CMD_UPDATE:
         4823  +    case AR_CMD_HELP:
         4824  +      if( pAr->eCmd ){
         4825  +        return arErrorMsg("multiple command options");
         4826  +      }
         4827  +      pAr->eCmd = eSwitch;
         4828  +      break;
         4829  +
         4830  +    case AR_SWITCH_DRYRUN:
         4831  +      pAr->bDryRun = 1;
         4832  +      break;
         4833  +    case AR_SWITCH_VERBOSE:
         4834  +      pAr->bVerbose = 1;
         4835  +      break;
         4836  +    case AR_SWITCH_APPEND:
         4837  +      pAr->bAppend = 1;
         4838  +      /* Fall thru into --file */
         4839  +    case AR_SWITCH_FILE:
         4840  +      pAr->zFile = zArg;
         4841  +      break;
         4842  +    case AR_SWITCH_DIRECTORY:
         4843  +      pAr->zDir = zArg;
         4844  +      break;
         4845  +  }
         4846  +
         4847  +  return SQLITE_OK;
         4848  +}
         4849  +
         4850  +/*
         4851  +** Parse the command line for an ".ar" command. The results are written into
         4852  +** structure (*pAr). SQLITE_OK is returned if the command line is parsed
         4853  +** successfully, otherwise an error message is written to stderr and 
         4854  +** SQLITE_ERROR returned.
         4855  +*/
         4856  +static int arParseCommand(
         4857  +  char **azArg,                   /* Array of arguments passed to dot command */
         4858  +  int nArg,                       /* Number of entries in azArg[] */
         4859  +  ArCommand *pAr                  /* Populate this object */
         4860  +){
         4861  +  struct ArSwitch {
         4862  +    const char *zLong;
         4863  +    char cShort;
         4864  +    u8 eSwitch;
         4865  +    u8 bArg;
         4866  +  } aSwitch[] = {
         4867  +    { "create",    'c', AR_CMD_CREATE,       0 },
         4868  +    { "extract",   'x', AR_CMD_EXTRACT,      0 },
         4869  +    { "list",      't', AR_CMD_LIST,         0 },
         4870  +    { "update",    'u', AR_CMD_UPDATE,       0 },
         4871  +    { "help",      'h', AR_CMD_HELP,         0 },
         4872  +    { "verbose",   'v', AR_SWITCH_VERBOSE,   0 },
         4873  +    { "file",      'f', AR_SWITCH_FILE,      1 },
         4874  +    { "append",    'a', AR_SWITCH_APPEND,    1 },
         4875  +    { "directory", 'C', AR_SWITCH_DIRECTORY, 1 },
         4876  +    { "dryrun",    'n', AR_SWITCH_DRYRUN,    0 },
         4877  +  };
         4878  +  int nSwitch = sizeof(aSwitch) / sizeof(struct ArSwitch);
         4879  +  struct ArSwitch *pEnd = &aSwitch[nSwitch];
         4880  +
         4881  +  if( nArg<=1 ){
         4882  +    return arUsage(stderr);
         4883  +  }else{
         4884  +    char *z = azArg[1];
         4885  +    memset(pAr, 0, sizeof(ArCommand));
         4886  +
         4887  +    if( z[0]!='-' ){
         4888  +      /* Traditional style [tar] invocation */
         4889  +      int i;
         4890  +      int iArg = 2;
         4891  +      for(i=0; z[i]; i++){
         4892  +        const char *zArg = 0;
         4893  +        struct ArSwitch *pOpt;
         4894  +        for(pOpt=&aSwitch[0]; pOpt<pEnd; pOpt++){
         4895  +          if( z[i]==pOpt->cShort ) break;
         4896  +        }
         4897  +        if( pOpt==pEnd ){
         4898  +          return arErrorMsg("unrecognized option: %c", z[i]);
         4899  +        }
         4900  +        if( pOpt->bArg ){
         4901  +          if( iArg>=nArg ){
         4902  +            return arErrorMsg("option requires an argument: %c",z[i]);
         4903  +          }
         4904  +          zArg = azArg[iArg++];
         4905  +        }
         4906  +        if( arProcessSwitch(pAr, pOpt->eSwitch, zArg) ) return SQLITE_ERROR;
         4907  +      }
         4908  +      pAr->nArg = nArg-iArg;
         4909  +      if( pAr->nArg>0 ){
         4910  +        pAr->azArg = &azArg[iArg];
         4911  +      }
         4912  +    }else{
         4913  +      /* Non-traditional invocation */
         4914  +      int iArg;
         4915  +      for(iArg=1; iArg<nArg; iArg++){
         4916  +        int n;
         4917  +        z = azArg[iArg];
         4918  +        if( z[0]!='-' ){
         4919  +          /* All remaining command line words are command arguments. */
         4920  +          pAr->azArg = &azArg[iArg];
         4921  +          pAr->nArg = nArg-iArg;
         4922  +          break;
         4923  +        }
         4924  +        n = strlen30(z);
         4925  +
         4926  +        if( z[1]!='-' ){
         4927  +          int i;
         4928  +          /* One or more short options */
         4929  +          for(i=1; i<n; i++){
         4930  +            const char *zArg = 0;
         4931  +            struct ArSwitch *pOpt;
         4932  +            for(pOpt=&aSwitch[0]; pOpt<pEnd; pOpt++){
         4933  +              if( z[i]==pOpt->cShort ) break;
         4934  +            }
         4935  +            if( pOpt==pEnd ){
         4936  +              return arErrorMsg("unrecognized option: %c\n", z[i]);
         4937  +            }
         4938  +            if( pOpt->bArg ){
         4939  +              if( i<(n-1) ){
         4940  +                zArg = &z[i+1];
         4941  +                i = n;
         4942  +              }else{
         4943  +                if( iArg>=(nArg-1) ){
         4944  +                  return arErrorMsg("option requires an argument: %c\n",z[i]);
         4945  +                }
         4946  +                zArg = azArg[++iArg];
         4947  +              }
         4948  +            }
         4949  +            if( arProcessSwitch(pAr, pOpt->eSwitch, zArg) ) return SQLITE_ERROR;
         4950  +          }
         4951  +        }else if( z[2]=='\0' ){
         4952  +          /* A -- option, indicating that all remaining command line words
         4953  +          ** are command arguments.  */
         4954  +          pAr->azArg = &azArg[iArg+1];
         4955  +          pAr->nArg = nArg-iArg-1;
         4956  +          break;
         4957  +        }else{
         4958  +          /* A long option */
         4959  +          const char *zArg = 0;             /* Argument for option, if any */
         4960  +          struct ArSwitch *pMatch = 0;      /* Matching option */
         4961  +          struct ArSwitch *pOpt;            /* Iterator */
         4962  +          for(pOpt=&aSwitch[0]; pOpt<pEnd; pOpt++){
         4963  +            const char *zLong = pOpt->zLong;
         4964  +            if( (n-2)<=strlen30(zLong) && 0==memcmp(&z[2], zLong, n-2) ){
         4965  +              if( pMatch ){
         4966  +                return arErrorMsg("ambiguous option: %s",z);
         4967  +              }else{
         4968  +                pMatch = pOpt;
         4969  +              }
         4970  +            }
         4971  +          }
         4972  +
         4973  +          if( pMatch==0 ){
         4974  +            return arErrorMsg("unrecognized option: %s", z);
         4975  +          }
         4976  +          if( pMatch->bArg ){
         4977  +            if( iArg>=(nArg-1) ){
         4978  +              return arErrorMsg("option requires an argument: %s", z);
         4979  +            }
         4980  +            zArg = azArg[++iArg];
         4981  +          }
         4982  +          if( arProcessSwitch(pAr, pMatch->eSwitch, zArg) ) return SQLITE_ERROR;
         4983  +        }
         4984  +      }
         4985  +    }
         4986  +  }
         4987  +
         4988  +  return SQLITE_OK;
         4989  +}
         4990  +
         4991  +/*
         4992  +** This function assumes that all arguments within the ArCommand.azArg[]
         4993  +** array refer to archive members, as for the --extract or --list commands. 
         4994  +** It checks that each of them are present. If any specified file is not
         4995  +** present in the archive, an error is printed to stderr and an error
         4996  +** code returned. Otherwise, if all specified arguments are present in
         4997  +** the archive, SQLITE_OK is returned.
         4998  +**
         4999  +** This function strips any trailing '/' characters from each argument.
         5000  +** This is consistent with the way the [tar] command seems to work on
         5001  +** Linux.
         5002  +*/
         5003  +static int arCheckEntries(ArCommand *pAr){
         5004  +  int rc = SQLITE_OK;
         5005  +  if( pAr->nArg ){
         5006  +    int i, j;
         5007  +    sqlite3_stmt *pTest = 0;
         5008  +
         5009  +    shellPreparePrintf(pAr->db, &rc, &pTest,
         5010  +        "SELECT name FROM %s WHERE name=$name", 
         5011  +        pAr->zSrcTable
         5012  +    );
         5013  +    j = sqlite3_bind_parameter_index(pTest, "$name");
         5014  +    for(i=0; i<pAr->nArg && rc==SQLITE_OK; i++){
         5015  +      char *z = pAr->azArg[i];
         5016  +      int n = strlen30(z);
         5017  +      int bOk = 0;
         5018  +      while( n>0 && z[n-1]=='/' ) n--;
         5019  +      z[n] = '\0';
         5020  +      sqlite3_bind_text(pTest, j, z, -1, SQLITE_STATIC);
         5021  +      if( SQLITE_ROW==sqlite3_step(pTest) ){
         5022  +        bOk = 1;
         5023  +      }
         5024  +      shellReset(&rc, pTest);
         5025  +      if( rc==SQLITE_OK && bOk==0 ){
         5026  +        utf8_printf(stderr, "not found in archive: %s\n", z);
         5027  +        rc = SQLITE_ERROR;
         5028  +      }
         5029  +    }
         5030  +    shellFinalize(&rc, pTest);
         5031  +  }
         5032  +  return rc;
         5033  +}
         5034  +
         5035  +/*
         5036  +** Format a WHERE clause that can be used against the "sqlar" table to
         5037  +** identify all archive members that match the command arguments held
         5038  +** in (*pAr). Leave this WHERE clause in (*pzWhere) before returning.
         5039  +** The caller is responsible for eventually calling sqlite3_free() on
         5040  +** any non-NULL (*pzWhere) value.
         5041  +*/
         5042  +static void arWhereClause(
         5043  +  int *pRc, 
         5044  +  ArCommand *pAr, 
         5045  +  char **pzWhere                  /* OUT: New WHERE clause */
         5046  +){
         5047  +  char *zWhere = 0;
         5048  +  if( *pRc==SQLITE_OK ){
         5049  +    if( pAr->nArg==0 ){
         5050  +      zWhere = sqlite3_mprintf("1");
         5051  +    }else{
         5052  +      int i;
         5053  +      const char *zSep = "";
         5054  +      for(i=0; i<pAr->nArg; i++){
         5055  +        const char *z = pAr->azArg[i];
         5056  +        zWhere = sqlite3_mprintf(
         5057  +          "%z%s name = '%q' OR substr(name,1,%d) = '%q/'", 
         5058  +          zWhere, zSep, z, strlen30(z)+1, z
         5059  +        );
         5060  +        if( zWhere==0 ){
         5061  +          *pRc = SQLITE_NOMEM;
         5062  +          break;
         5063  +        }
         5064  +        zSep = " OR ";
         5065  +      }
         5066  +    }
         5067  +  }
         5068  +  *pzWhere = zWhere;
         5069  +}
         5070  +
         5071  +/*
         5072  +** Implementation of .ar "lisT" command. 
         5073  +*/
         5074  +static int arListCommand(ArCommand *pAr){
         5075  +  const char *zSql = "SELECT %s FROM %s WHERE %s"; 
         5076  +  const char *azCols[] = {
         5077  +    "name",
         5078  +    "lsmode(mode), sz, datetime(mtime, 'unixepoch'), name"
         5079  +  };
         5080  +
         5081  +  char *zWhere = 0;
         5082  +  sqlite3_stmt *pSql = 0;
         5083  +  int rc;
         5084  +
         5085  +  rc = arCheckEntries(pAr);
         5086  +  arWhereClause(&rc, pAr, &zWhere);
         5087  +
         5088  +  shellPreparePrintf(pAr->db, &rc, &pSql, zSql, azCols[pAr->bVerbose],
         5089  +                     pAr->zSrcTable, zWhere);
         5090  +  if( pAr->bDryRun ){
         5091  +    utf8_printf(pAr->p->out, "%s\n", sqlite3_sql(pSql));
         5092  +  }else{
         5093  +    while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSql) ){
         5094  +      if( pAr->bVerbose ){
         5095  +        utf8_printf(pAr->p->out, "%s % 10d  %s  %s\n",
         5096  +            sqlite3_column_text(pSql, 0),
         5097  +            sqlite3_column_int(pSql, 1), 
         5098  +            sqlite3_column_text(pSql, 2),
         5099  +            sqlite3_column_text(pSql, 3)
         5100  +        );
         5101  +      }else{
         5102  +        utf8_printf(pAr->p->out, "%s\n", sqlite3_column_text(pSql, 0));
         5103  +      }
         5104  +    }
         5105  +  }
         5106  +  shellFinalize(&rc, pSql);
         5107  +  return rc;
         5108  +}
         5109  +
         5110  +
         5111  +/*
         5112  +** Implementation of .ar "eXtract" command. 
         5113  +*/
         5114  +static int arExtractCommand(ArCommand *pAr){
         5115  +  const char *zSql1 = 
         5116  +    "SELECT "
         5117  +    " ($dir || name),"
         5118  +    " writefile(($dir || name), %s, mode, mtime) "
         5119  +    "FROM %s WHERE (%s) AND (data IS NULL OR $dirOnly = 0)";
         5120  +
         5121  +  const char *azExtraArg[] = { 
         5122  +    "sqlar_uncompress(data, sz)",
         5123  +    "data"
         5124  +  };
         5125  +
         5126  +  sqlite3_stmt *pSql = 0;
         5127  +  int rc = SQLITE_OK;
         5128  +  char *zDir = 0;
         5129  +  char *zWhere = 0;
         5130  +  int i, j;
         5131  +
         5132  +  /* If arguments are specified, check that they actually exist within
         5133  +  ** the archive before proceeding. And formulate a WHERE clause to
         5134  +  ** match them.  */
         5135  +  rc = arCheckEntries(pAr);
         5136  +  arWhereClause(&rc, pAr, &zWhere);
         5137  +
         5138  +  if( rc==SQLITE_OK ){
         5139  +    if( pAr->zDir ){
         5140  +      zDir = sqlite3_mprintf("%s/", pAr->zDir);
         5141  +    }else{
         5142  +      zDir = sqlite3_mprintf("");
         5143  +    }
         5144  +    if( zDir==0 ) rc = SQLITE_NOMEM;
         5145  +  }
         5146  +
         5147  +  shellPreparePrintf(pAr->db, &rc, &pSql, zSql1, 
         5148  +      azExtraArg[pAr->bZip], pAr->zSrcTable, zWhere
         5149  +  );
         5150  +
         5151  +  if( rc==SQLITE_OK ){
         5152  +    j = sqlite3_bind_parameter_index(pSql, "$dir");
         5153  +    sqlite3_bind_text(pSql, j, zDir, -1, SQLITE_STATIC);
         5154  +
         5155  +    /* Run the SELECT statement twice. The first time, writefile() is called
         5156  +    ** for all archive members that should be extracted. The second time,
         5157  +    ** only for the directories. This is because the timestamps for
         5158  +    ** extracted directories must be reset after they are populated (as
         5159  +    ** populating them changes the timestamp).  */
         5160  +    for(i=0; i<2; i++){
         5161  +      j = sqlite3_bind_parameter_index(pSql, "$dirOnly");
         5162  +      sqlite3_bind_int(pSql, j, i);
         5163  +      if( pAr->bDryRun ){
         5164  +        utf8_printf(pAr->p->out, "%s\n", sqlite3_sql(pSql));
         5165  +      }else{
         5166  +        while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSql) ){
         5167  +          if( i==0 && pAr->bVerbose ){
         5168  +            utf8_printf(pAr->p->out, "%s\n", sqlite3_column_text(pSql, 0));
         5169  +          }
         5170  +        }
         5171  +      }
         5172  +      shellReset(&rc, pSql);
         5173  +    }
         5174  +    shellFinalize(&rc, pSql);
         5175  +  }
         5176  +
         5177  +  sqlite3_free(zDir);
         5178  +  sqlite3_free(zWhere);
         5179  +  return rc;
         5180  +}
         5181  +
         5182  +/*
         5183  +** Run the SQL statement in zSql.  Or if doing a --dryrun, merely print it out.
         5184  +*/
         5185  +static int arExecSql(ArCommand *pAr, const char *zSql){
         5186  +  int rc;
         5187  +  if( pAr->bDryRun ){
         5188  +    utf8_printf(pAr->p->out, "%s\n", zSql);
         5189  +    rc = SQLITE_OK;
         5190  +  }else{
         5191  +    char *zErr = 0;
         5192  +    rc = sqlite3_exec(pAr->db, zSql, 0, 0, &zErr);
         5193  +    if( zErr ){
         5194  +      utf8_printf(stdout, "ERROR: %s\n", zErr);
         5195  +      sqlite3_free(zErr);
         5196  +    }
         5197  +  }
         5198  +  return rc;
         5199  +}
         5200  +
         5201  +
         5202  +/*
         5203  +** Implementation of .ar "create" and "update" commands.
         5204  +**
         5205  +** Create the "sqlar" table in the database if it does not already exist.
         5206  +** Then add each file in the azFile[] array to the archive. Directories
         5207  +** are added recursively. If argument bVerbose is non-zero, a message is
         5208  +** printed on stdout for each file archived.
         5209  +**
         5210  +** The create command is the same as update, except that it drops
         5211  +** any existing "sqlar" table before beginning.
         5212  +*/
         5213  +static int arCreateOrUpdateCommand(
         5214  +  ArCommand *pAr,                 /* Command arguments and options */
         5215  +  int bUpdate                     /* true for a --create.  false for --update */
         5216  +){
         5217  +  const char *zCreate = 
         5218  +      "CREATE TABLE IF NOT EXISTS sqlar(\n"
         5219  +      "  name TEXT PRIMARY KEY,  -- name of the file\n"
         5220  +      "  mode INT,               -- access permissions\n"
         5221  +      "  mtime INT,              -- last modification time\n"
         5222  +      "  sz INT,                 -- original file size\n"
         5223  +      "  data BLOB               -- compressed content\n"
         5224  +      ")";
         5225  +  const char *zDrop = "DROP TABLE IF EXISTS sqlar";
         5226  +  const char *zInsertFmt = 
         5227  +     "REPLACE INTO sqlar(name,mode,mtime,sz,data)\n"
         5228  +     "  SELECT\n"
         5229  +     "    %s,\n"
         5230  +     "    mode,\n"
         5231  +     "    mtime,\n"
         5232  +     "    CASE substr(lsmode(mode),1,1)\n"
         5233  +     "      WHEN '-' THEN length(data)\n"
         5234  +     "      WHEN 'd' THEN 0\n"
         5235  +     "      ELSE -1 END,\n"
         5236  +     "    CASE WHEN lsmode(mode) LIKE 'd%%' THEN NULL else data END\n"
         5237  +     "  FROM fsdir(%Q,%Q)\n"
         5238  +     "  WHERE lsmode(mode) NOT LIKE '?%%';";
         5239  +  int i;                          /* For iterating through azFile[] */
         5240  +  int rc;                         /* Return code */
         5241  +
         5242  +  rc = arExecSql(pAr, "SAVEPOINT ar;");
         5243  +  if( rc!=SQLITE_OK ) return rc;
         5244  +  if( bUpdate==0 ){
         5245  +    rc = arExecSql(pAr, zDrop);
         5246  +    if( rc!=SQLITE_OK ) return rc;
         5247  +  }
         5248  +  rc = arExecSql(pAr, zCreate);
         5249  +  for(i=0; i<pAr->nArg && rc==SQLITE_OK; i++){
         5250  +    char *zSql = sqlite3_mprintf(zInsertFmt,
         5251  +        pAr->bVerbose ? "shell_putsnl(name)" : "name",
         5252  +        pAr->azArg[i], pAr->zDir);
         5253  +    rc = arExecSql(pAr, zSql);
         5254  +    sqlite3_free(zSql);
         5255  +  }
         5256  +  if( rc!=SQLITE_OK ){
         5257  +    arExecSql(pAr, "ROLLBACK TO ar; RELEASE ar;");
         5258  +  }else{
         5259  +    rc = arExecSql(pAr, "RELEASE ar;");
         5260  +  }
         5261  +  return rc;
         5262  +}
         5263  +
         5264  +/*
         5265  +** Implementation of ".ar" dot command.
         5266  +*/
         5267  +static int arDotCommand(
  4259   5268     ShellState *pState,             /* Current shell tool state */
  4260   5269     char **azArg,                   /* Array of arguments passed to dot command */
  4261   5270     int nArg                        /* Number of entries in azArg[] */
  4262   5271   ){
  4263         -  int rc = SQLITE_OK;
  4264         -  char *zErr = 0;
  4265         -  int i;
  4266         -  int iSample = 0;
  4267         -
  4268         -  assert( pState->expert.pExpert==0 );
  4269         -  memset(&pState->expert, 0, sizeof(ExpertInfo));
  4270         -
  4271         -  for(i=1; rc==SQLITE_OK && i<nArg; i++){
  4272         -    char *z = azArg[i];
  4273         -    int n;
  4274         -    if( z[0]=='-' && z[1]=='-' ) z++;
  4275         -    n = strlen30(z);
  4276         -    if( n>=2 && 0==strncmp(z, "-verbose", n) ){
  4277         -      pState->expert.bVerbose = 1;
  4278         -    }
  4279         -    else if( n>=2 && 0==strncmp(z, "-sample", n) ){
  4280         -      if( i==(nArg-1) ){
  4281         -        raw_printf(stderr, "option requires an argument: %s\n", z);
  4282         -        rc = SQLITE_ERROR;
  4283         -      }else{
  4284         -        iSample = (int)integerValue(azArg[++i]);
  4285         -        if( iSample<0 || iSample>100 ){
  4286         -          raw_printf(stderr, "value out of range: %s\n", azArg[i]);
  4287         -          rc = SQLITE_ERROR;
  4288         -        }
  4289         -      }
  4290         -    }
  4291         -    else{
  4292         -      raw_printf(stderr, "unknown option: %s\n", z);
  4293         -      rc = SQLITE_ERROR;
  4294         -    }
  4295         -  }
  4296         -
         5272  +  ArCommand cmd;
         5273  +  int rc;
         5274  +  memset(&cmd, 0, sizeof(cmd));
         5275  +  rc = arParseCommand(azArg, nArg, &cmd);
  4297   5276     if( rc==SQLITE_OK ){
  4298         -    pState->expert.pExpert = sqlite3_expert_new(pState->db, &zErr);
  4299         -    if( pState->expert.pExpert==0 ){
  4300         -      raw_printf(stderr, "sqlite3_expert_new: %s\n", zErr);
  4301         -      rc = SQLITE_ERROR;
  4302         -    }else{
  4303         -      sqlite3_expert_config(
  4304         -          pState->expert.pExpert, EXPERT_CONFIG_SAMPLE, iSample
  4305         -      );
  4306         -    }
  4307         -  }
         5277  +    int eDbType = SHELL_OPEN_UNSPEC;
         5278  +    cmd.p = pState;
         5279  +    cmd.db = pState->db;
         5280  +    if( cmd.zFile ){
         5281  +      eDbType = deduceDatabaseType(cmd.zFile);
         5282  +    }else{
         5283  +      eDbType = pState->openMode;
         5284  +    }
         5285  +    if( eDbType==SHELL_OPEN_ZIPFILE ){
         5286  +      if( cmd.zFile==0 ){
         5287  +        cmd.zSrcTable = sqlite3_mprintf("zip");
         5288  +      }else{
         5289  +        cmd.zSrcTable = sqlite3_mprintf("zipfile(%Q)", cmd.zFile);
         5290  +      }
         5291  +      if( cmd.eCmd==AR_CMD_CREATE || cmd.eCmd==AR_CMD_UPDATE ){
         5292  +        utf8_printf(stderr, "zip archives are read-only\n");
         5293  +        rc = SQLITE_ERROR;
         5294  +        goto end_ar_command;
         5295  +      }
         5296  +      cmd.bZip = 1;
         5297  +    }else if( cmd.zFile ){
         5298  +      int flags;
         5299  +      if( cmd.bAppend ) eDbType = SHELL_OPEN_APPENDVFS;
         5300  +      if( cmd.eCmd==AR_CMD_CREATE || cmd.eCmd==AR_CMD_UPDATE ){
         5301  +        flags = SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE;
         5302  +      }else{
         5303  +        flags = SQLITE_OPEN_READONLY;
         5304  +      }
         5305  +      cmd.db = 0;
         5306  +      if( cmd.bDryRun ){
         5307  +        utf8_printf(pState->out, "-- open database '%s'%s\n", cmd.zFile,
         5308  +             eDbType==SHELL_OPEN_APPENDVFS ? " using 'apndvfs'" : "");
         5309  +      }
         5310  +      rc = sqlite3_open_v2(cmd.zFile, &cmd.db, flags, 
         5311  +             eDbType==SHELL_OPEN_APPENDVFS ? "apndvfs" : 0);
         5312  +      if( rc!=SQLITE_OK ){
         5313  +        utf8_printf(stderr, "cannot open file: %s (%s)\n", 
         5314  +            cmd.zFile, sqlite3_errmsg(cmd.db)
         5315  +        );
         5316  +        goto end_ar_command;
         5317  +      }
         5318  +      sqlite3_fileio_init(cmd.db, 0, 0);
         5319  +#ifdef SQLITE_HAVE_ZLIB
         5320  +      sqlite3_sqlar_init(cmd.db, 0, 0);
         5321  +#endif
         5322  +      sqlite3_create_function(cmd.db, "shell_putsnl", 1, SQLITE_UTF8, cmd.p,
         5323  +                              shellPutsFunc, 0, 0);
         5324  +
         5325  +    }
         5326  +    if( cmd.zSrcTable==0 ){
         5327  +      if( cmd.eCmd!=AR_CMD_CREATE
         5328  +       && sqlite3_table_column_metadata(cmd.db,0,"sqlar","name",0,0,0,0,0)
         5329  +      ){
         5330  +        utf8_printf(stderr, "database does not contain an 'sqlar' table\n");
         5331  +        rc = SQLITE_ERROR;
         5332  +        goto end_ar_command;
         5333  +      }
         5334  +      cmd.zSrcTable = sqlite3_mprintf("sqlar");
         5335  +    }
         5336  +
         5337  +    switch( cmd.eCmd ){
         5338  +      case AR_CMD_CREATE:
         5339  +        rc = arCreateOrUpdateCommand(&cmd, 0);
         5340  +        break;
         5341  +
         5342  +      case AR_CMD_EXTRACT:
         5343  +        rc = arExtractCommand(&cmd);
         5344  +        break;
         5345  +
         5346  +      case AR_CMD_LIST:
         5347  +        rc = arListCommand(&cmd);
         5348  +        break;
         5349  +
         5350  +      case AR_CMD_HELP:
         5351  +        arUsage(pState->out);
         5352  +        break;
         5353  +
         5354  +      default:
         5355  +        assert( cmd.eCmd==AR_CMD_UPDATE );
         5356  +        rc = arCreateOrUpdateCommand(&cmd, 1);
         5357  +        break;
         5358  +    }
         5359  +  }
         5360  +end_ar_command:
         5361  +  if( cmd.db!=pState->db ){
         5362  +    sqlite3_close(cmd.db);
         5363  +  }
         5364  +  sqlite3_free(cmd.zSrcTable);
  4308   5365   
  4309   5366     return rc;
  4310   5367   }
  4311         -
         5368  +/* End of the ".archive" or ".ar" command logic
         5369  +**********************************************************************************/
         5370  +#endif /* !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB) */
  4312   5371   
  4313   5372   
  4314   5373   /*
  4315   5374   ** If an input line begins with "." then invoke this routine to
  4316   5375   ** process that line.
  4317   5376   **
  4318   5377   ** Return 1 on error, 2 to exit, and 0 otherwise.
................................................................................
  4320   5379   static int do_meta_command(char *zLine, ShellState *p){
  4321   5380     int h = 1;
  4322   5381     int nArg = 0;
  4323   5382     int n, c;
  4324   5383     int rc = 0;
  4325   5384     char *azArg[50];
  4326   5385   
         5386  +#ifndef SQLITE_OMIT_VIRTUALTABLE
  4327   5387     if( p->expert.pExpert ){
  4328   5388       expertFinish(p, 1, 0);
  4329   5389     }
         5390  +#endif
  4330   5391   
  4331   5392     /* Parse the input line into tokens.
  4332   5393     */
  4333   5394     while( zLine[h] && nArg<ArraySize(azArg) ){
  4334   5395       while( IsSpace(zLine[h]) ){ h++; }
  4335   5396       if( zLine[h]==0 ) break;
  4336   5397       if( zLine[h]=='\'' || zLine[h]=='"' ){
................................................................................
  4353   5414     }
  4354   5415   
  4355   5416     /* Process the input line.
  4356   5417     */
  4357   5418     if( nArg==0 ) return 0; /* no tokens, no error */
  4358   5419     n = strlen30(azArg[0]);
  4359   5420     c = azArg[0][0];
         5421  +  clearTempFile(p);
  4360   5422   
  4361   5423   #ifndef SQLITE_OMIT_AUTHORIZATION
  4362   5424     if( c=='a' && strncmp(azArg[0], "auth", n)==0 ){
  4363   5425       if( nArg!=2 ){
  4364   5426         raw_printf(stderr, "Usage: .auth ON|OFF\n");
  4365   5427         rc = 1;
  4366   5428         goto meta_command_exit;
................................................................................
  4369   5431       if( booleanValue(azArg[1]) ){
  4370   5432         sqlite3_set_authorizer(p->db, shellAuth, p);
  4371   5433       }else{
  4372   5434         sqlite3_set_authorizer(p->db, 0, 0);
  4373   5435       }
  4374   5436     }else
  4375   5437   #endif
         5438  +
         5439  +#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB)
         5440  +  if( c=='a' && strncmp(azArg[0], "archive", n)==0 ){
         5441  +    open_db(p, 0);
         5442  +    rc = arDotCommand(p, azArg, nArg);
         5443  +  }else
         5444  +#endif
  4376   5445   
  4377   5446     if( (c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0)
  4378   5447      || (c=='s' && n>=3 && strncmp(azArg[0], "save", n)==0)
  4379   5448     ){
  4380   5449       const char *zDestFile = 0;
  4381   5450       const char *zDb = 0;
  4382   5451       sqlite3 *pDest;
................................................................................
  4643   5712     if( c=='e' && strncmp(azArg[0], "eqp", n)==0 ){
  4644   5713       if( nArg==2 ){
  4645   5714         if( strcmp(azArg[1],"full")==0 ){
  4646   5715           p->autoEQP = AUTOEQP_full;
  4647   5716         }else if( strcmp(azArg[1],"trigger")==0 ){
  4648   5717           p->autoEQP = AUTOEQP_trigger;
  4649   5718         }else{
  4650         -        p->autoEQP = booleanValue(azArg[1]);
         5719  +        p->autoEQP = (u8)booleanValue(azArg[1]);
  4651   5720         }
  4652   5721       }else{
  4653   5722         raw_printf(stderr, "Usage: .eqp off|on|trigger|full\n");
  4654   5723         rc = 1;
  4655   5724       }
  4656   5725     }else
  4657   5726   
................................................................................
  4680   5749         p->autoExplain = 0;
  4681   5750       }else if( val==99 ){
  4682   5751         if( p->mode==MODE_Explain ) p->mode = p->normalMode;
  4683   5752         p->autoExplain = 1;
  4684   5753       }
  4685   5754     }else
  4686   5755   
         5756  +#ifndef SQLITE_OMIT_VIRTUALTABLE
  4687   5757     if( c=='e' && strncmp(azArg[0], "expert", n)==0 ){
  4688   5758       open_db(p, 0);
  4689   5759       expertDotCommand(p, azArg, nArg);
  4690   5760     }else
         5761  +#endif
  4691   5762   
  4692   5763     if( c=='f' && strncmp(azArg[0], "fullschema", n)==0 ){
  4693   5764       ShellState data;
  4694   5765       char *zErrMsg = 0;
  4695   5766       int doStats = 0;
  4696   5767       memcpy(&data, p, sizeof(data));
  4697   5768       data.showHeader = 0;
................................................................................
  5139   6210     if( c=='l' && strncmp(azArg[0], "log", n)==0 ){
  5140   6211       if( nArg!=2 ){
  5141   6212         raw_printf(stderr, "Usage: .log FILENAME\n");
  5142   6213         rc = 1;
  5143   6214       }else{
  5144   6215         const char *zFile = azArg[1];
  5145   6216         output_file_close(p->pLog);
  5146         -      p->pLog = output_file_open(zFile);
         6217  +      p->pLog = output_file_open(zFile, 0);
  5147   6218       }
  5148   6219     }else
  5149   6220   
  5150   6221     if( c=='m' && strncmp(azArg[0], "mode", n)==0 ){
  5151   6222       const char *zMode = nArg>=2 ? azArg[1] : "";
  5152         -    int n2 = (int)strlen(zMode);
         6223  +    int n2 = strlen30(zMode);
  5153   6224       int c2 = zMode[0];
  5154   6225       if( c2=='l' && n2>2 && strncmp(azArg[1],"lines",n2)==0 ){
  5155   6226         p->mode = MODE_Line;
  5156   6227         sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
  5157   6228       }else if( c2=='c' && strncmp(azArg[1],"columns",n2)==0 ){
  5158   6229         p->mode = MODE_Column;
  5159   6230         sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Row);
................................................................................
  5210   6281       /* Close the existing database */
  5211   6282       session_close_all(p);
  5212   6283       sqlite3_close(p->db);
  5213   6284       p->db = 0;
  5214   6285       p->zDbFilename = 0;
  5215   6286       sqlite3_free(p->zFreeOnClose);
  5216   6287       p->zFreeOnClose = 0;
         6288  +    p->openMode = SHELL_OPEN_UNSPEC;
  5217   6289       /* Check for command-line arguments */
  5218   6290       for(iName=1; iName<nArg && azArg[iName][0]=='-'; iName++){
  5219   6291         const char *z = azArg[iName];
  5220   6292         if( optionMatch(z,"new") ){
  5221   6293           newFlag = 1;
         6294  +#ifdef SQLITE_HAVE_ZIP
         6295  +      }else if( optionMatch(z, "zip") ){
         6296  +        p->openMode = SHELL_OPEN_ZIPFILE;
         6297  +#endif
         6298  +      }else if( optionMatch(z, "append") ){
         6299  +        p->openMode = SHELL_OPEN_APPENDVFS;
  5222   6300         }else if( z[0]=='-' ){
  5223   6301           utf8_printf(stderr, "unknown option: %s\n", z);
  5224   6302           rc = 1;
  5225   6303           goto meta_command_exit;
  5226   6304         }
  5227   6305       }
  5228   6306       /* If a filename is specified, try to open it first */
................................................................................
  5241   6319       if( p->db==0 ){
  5242   6320         /* As a fall-back open a TEMP database */
  5243   6321         p->zDbFilename = 0;
  5244   6322         open_db(p, 0);
  5245   6323       }
  5246   6324     }else
  5247   6325   
  5248         -  if( c=='o'
  5249         -   && (strncmp(azArg[0], "output", n)==0 || strncmp(azArg[0], "once", n)==0)
         6326  +  if( (c=='o'
         6327  +        && (strncmp(azArg[0], "output", n)==0||strncmp(azArg[0], "once", n)==0))
         6328  +   || (c=='e' && n==5 && strcmp(azArg[0],"excel")==0)
  5250   6329     ){
  5251   6330       const char *zFile = nArg>=2 ? azArg[1] : "stdout";
         6331  +    int bTxtMode = 0;
         6332  +    if( azArg[0][0]=='e' ){
         6333  +      /* Transform the ".excel" command into ".once -x" */
         6334  +      nArg = 2;
         6335  +      azArg[0] = "once";
         6336  +      zFile = azArg[1] = "-x";
         6337  +      n = 4;
         6338  +    }
  5252   6339       if( nArg>2 ){
  5253         -      utf8_printf(stderr, "Usage: .%s FILE\n", azArg[0]);
         6340  +      utf8_printf(stderr, "Usage: .%s [-e|-x|FILE]\n", azArg[0]);
  5254   6341         rc = 1;
  5255   6342         goto meta_command_exit;
  5256   6343       }
  5257   6344       if( n>1 && strncmp(azArg[0], "once", n)==0 ){
  5258   6345         if( nArg<2 ){
  5259         -        raw_printf(stderr, "Usage: .once FILE\n");
         6346  +        raw_printf(stderr, "Usage: .once (-e|-x|FILE)\n");
  5260   6347           rc = 1;
  5261   6348           goto meta_command_exit;
  5262   6349         }
  5263   6350         p->outCount = 2;
  5264   6351       }else{
  5265   6352         p->outCount = 0;
  5266   6353       }
  5267   6354       output_reset(p);
         6355  +    if( zFile[0]=='-' && zFile[1]=='-' ) zFile++;
         6356  +    if( strcmp(zFile, "-e")==0 || strcmp(zFile, "-x")==0 ){
         6357  +      p->doXdgOpen = 1;
         6358  +      outputModePush(p);
         6359  +      if( zFile[1]=='x' ){
         6360  +        newTempFile(p, "csv");
         6361  +        p->mode = MODE_Csv;
         6362  +        sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Comma);
         6363  +        sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_CrLf);
         6364  +      }else{
         6365  +        newTempFile(p, "txt");
         6366  +        bTxtMode = 1;
         6367  +      }
         6368  +      zFile = p->zTempFile;
         6369  +    }
  5268   6370       if( zFile[0]=='|' ){
  5269   6371   #ifdef SQLITE_OMIT_POPEN
  5270   6372         raw_printf(stderr, "Error: pipes are not supported in this OS\n");
  5271   6373         rc = 1;
  5272   6374         p->out = stdout;
  5273   6375   #else
  5274   6376         p->out = popen(zFile + 1, "w");
................................................................................
  5277   6379           p->out = stdout;
  5278   6380           rc = 1;
  5279   6381         }else{
  5280   6382           sqlite3_snprintf(sizeof(p->outfile), p->outfile, "%s", zFile);
  5281   6383         }
  5282   6384   #endif
  5283   6385       }else{
  5284         -      p->out = output_file_open(zFile);
         6386  +      p->out = output_file_open(zFile, bTxtMode);
  5285   6387         if( p->out==0 ){
  5286   6388           if( strcmp(zFile,"off")!=0 ){
  5287   6389             utf8_printf(stderr,"Error: cannot write to \"%s\"\n", zFile);
  5288   6390           }
  5289   6391           p->out = stdout;
  5290   6392           rc = 1;
  5291   6393         } else {
................................................................................
  5383   6485       }
  5384   6486       sqlite3_close(pSrc);
  5385   6487     }else
  5386   6488   
  5387   6489   
  5388   6490     if( c=='s' && strncmp(azArg[0], "scanstats", n)==0 ){
  5389   6491       if( nArg==2 ){
  5390         -      p->scanstatsOn = booleanValue(azArg[1]);
         6492  +      p->scanstatsOn = (u8)booleanValue(azArg[1]);
  5391   6493   #ifndef SQLITE_ENABLE_STMT_SCANSTATUS
  5392   6494         raw_printf(stderr, "Warning: .scanstats not available in this build.\n");
  5393   6495   #endif
  5394   6496       }else{
  5395   6497         raw_printf(stderr, "Usage: .scanstats on|off\n");
  5396   6498         rc = 1;
  5397   6499       }
................................................................................
  6034   7136       raw_printf(p->out, "\n");
  6035   7137       utf8_printf(p->out, "%12.12s: %s\n", "filename",
  6036   7138                   p->zDbFilename ? p->zDbFilename : "");
  6037   7139     }else
  6038   7140   
  6039   7141     if( c=='s' && strncmp(azArg[0], "stats", n)==0 ){
  6040   7142       if( nArg==2 ){
  6041         -      p->statsOn = booleanValue(azArg[1]);
         7143  +      p->statsOn = (u8)booleanValue(azArg[1]);
  6042   7144       }else if( nArg==1 ){
  6043   7145         display_stats(p->db, p, 0);
  6044   7146       }else{
  6045   7147         raw_printf(stderr, "Usage: .stats ?on|off?\n");
  6046   7148         rc = 1;
  6047   7149       }
  6048   7150     }else
................................................................................
  6154   7256       for(ii=0; ii<nRow; ii++) sqlite3_free(azResult[ii]);
  6155   7257       sqlite3_free(azResult);
  6156   7258     }else
  6157   7259   
  6158   7260     /* Begin redirecting output to the file "testcase-out.txt" */
  6159   7261     if( c=='t' && strcmp(azArg[0],"testcase")==0 ){
  6160   7262       output_reset(p);
  6161         -    p->out = output_file_open("testcase-out.txt");
         7263  +    p->out = output_file_open("testcase-out.txt", 0);
  6162   7264       if( p->out==0 ){
  6163   7265         raw_printf(stderr, "Error: cannot open 'testcase-out.txt'\n");
  6164   7266       }
  6165   7267       if( nArg>=2 ){
  6166   7268         sqlite3_snprintf(sizeof(p->zTestcase), p->zTestcase, "%s", azArg[1]);
  6167   7269       }else{
  6168   7270         sqlite3_snprintf(sizeof(p->zTestcase), p->zTestcase, "?");
................................................................................
  6360   7462       open_db(p, 0);
  6361   7463       if( nArg!=2 ){
  6362   7464         raw_printf(stderr, "Usage: .trace FILE|off\n");
  6363   7465         rc = 1;
  6364   7466         goto meta_command_exit;
  6365   7467       }
  6366   7468       output_file_close(p->traceOut);
  6367         -    p->traceOut = output_file_open(azArg[1]);
         7469  +    p->traceOut = output_file_open(azArg[1], 0);
  6368   7470   #if !defined(SQLITE_OMIT_TRACE) && !defined(SQLITE_OMIT_FLOATING_POINT)
  6369   7471       if( p->traceOut==0 ){
  6370   7472         sqlite3_trace_v2(p->db, 0, 0, 0);
  6371   7473       }else{
  6372   7474         sqlite3_trace_v2(p->db, SQLITE_TRACE_STMT, sql_trace_callback,p->traceOut);
  6373   7475       }
  6374   7476   #endif
................................................................................
  6384   7486       open_db(p, 0);
  6385   7487       if( strcmp(azArg[1],"login")==0 ){
  6386   7488         if( nArg!=4 ){
  6387   7489           raw_printf(stderr, "Usage: .user login USER PASSWORD\n");
  6388   7490           rc = 1;
  6389   7491           goto meta_command_exit;
  6390   7492         }
  6391         -      rc = sqlite3_user_authenticate(p->db, azArg[2], azArg[3],
  6392         -                                    (int)strlen(azArg[3]));
         7493  +      rc = sqlite3_user_authenticate(p->db, azArg[2], azArg[3], strlen30(azArg[3]));
  6393   7494         if( rc ){
  6394   7495           utf8_printf(stderr, "Authentication failed for user %s\n", azArg[2]);
  6395   7496           rc = 1;
  6396   7497         }
  6397   7498       }else if( strcmp(azArg[1],"add")==0 ){
  6398   7499         if( nArg!=5 ){
  6399   7500           raw_printf(stderr, "Usage: .user add USER PASSWORD ISADMIN\n");
  6400   7501           rc = 1;
  6401   7502           goto meta_command_exit;
  6402   7503         }
  6403         -      rc = sqlite3_user_add(p->db, azArg[2],
  6404         -                            azArg[3], (int)strlen(azArg[3]),
         7504  +      rc = sqlite3_user_add(p->db, azArg[2], azArg[3], strlen30(azArg[3]),
  6405   7505                               booleanValue(azArg[4]));
  6406   7506         if( rc ){
  6407   7507           raw_printf(stderr, "User-Add failed: %d\n", rc);
  6408   7508           rc = 1;
  6409   7509         }
  6410   7510       }else if( strcmp(azArg[1],"edit")==0 ){
  6411   7511         if( nArg!=5 ){
  6412   7512           raw_printf(stderr, "Usage: .user edit USER PASSWORD ISADMIN\n");
  6413   7513           rc = 1;
  6414   7514           goto meta_command_exit;
  6415   7515         }
  6416         -      rc = sqlite3_user_change(p->db, azArg[2],
  6417         -                              azArg[3], (int)strlen(azArg[3]),
         7516  +      rc = sqlite3_user_change(p->db, azArg[2], azArg[3], strlen30(azArg[3]),
  6418   7517                                 booleanValue(azArg[4]));
  6419   7518         if( rc ){
  6420   7519           raw_printf(stderr, "User-Edit failed: %d\n", rc);
  6421   7520           rc = 1;
  6422   7521         }
  6423   7522       }else if( strcmp(azArg[1],"delete")==0 ){
  6424   7523         if( nArg!=3 ){
................................................................................
  6438   7537       }
  6439   7538     }else
  6440   7539   #endif /* SQLITE_USER_AUTHENTICATION */
  6441   7540   
  6442   7541     if( c=='v' && strncmp(azArg[0], "version", n)==0 ){
  6443   7542       utf8_printf(p->out, "SQLite %s %s\n" /*extra-version-info*/,
  6444   7543           sqlite3_libversion(), sqlite3_sourceid());
         7544  +#if SQLITE_HAVE_ZLIB
         7545  +    utf8_printf(p->out, "zlib version %s\n", zlibVersion());
         7546  +#endif
         7547  +#define CTIMEOPT_VAL_(opt) #opt
         7548  +#define CTIMEOPT_VAL(opt) CTIMEOPT_VAL_(opt)
         7549  +#if defined(__clang__) && defined(__clang_major__)
         7550  +    utf8_printf(p->out, "clang-" CTIMEOPT_VAL(__clang_major__) "."
         7551  +                    CTIMEOPT_VAL(__clang_minor__) "."
         7552  +                    CTIMEOPT_VAL(__clang_patchlevel__) "\n");
         7553  +#elif defined(_MSC_VER)
         7554  +    utf8_printf(p->out, "msvc-" CTIMEOPT_VAL(_MSC_VER) "\n");
         7555  +#elif defined(__GNUC__) && defined(__VERSION__)
         7556  +    utf8_printf(p->out, "gcc-" __VERSION__ "\n");
         7557  +#endif
  6445   7558     }else
  6446   7559   
  6447   7560     if( c=='v' && strncmp(azArg[0], "vfsinfo", n)==0 ){
  6448   7561       const char *zDbName = nArg==2 ? azArg[1] : "main";
  6449   7562       sqlite3_vfs *pVfs = 0;
  6450   7563       if( p->db ){
  6451   7564         sqlite3_file_control(p->db, zDbName, SQLITE_FCNTL_VFS_POINTER, &pVfs);
................................................................................
  6563   7676     if( ToLower(zLine[0])=='g' && ToLower(zLine[1])=='o'
  6564   7677            && _all_whitespace(&zLine[2]) ){
  6565   7678       return 1;  /* SQL Server */
  6566   7679     }
  6567   7680     return 0;
  6568   7681   }
  6569   7682   
         7683  +/*
         7684  +** We need a default sqlite3_complete() implementation to use in case
         7685  +** the shell is compiled with SQLITE_OMIT_COMPLETE.  The default assumes
         7686  +** any arbitrary text is a complete SQL statement.  This is not very
         7687  +** user-friendly, but it does seem to work.
         7688  +*/
         7689  +#ifdef SQLITE_OMIT_COMPLETE
         7690  +int sqlite3_complete(const char *zSql){ return 1; }
         7691  +#endif
         7692  +
  6570   7693   /*
  6571   7694   ** Return true if zSql is a complete SQL statement.  Return false if it
  6572   7695   ** ends in the middle of a string literal or C-style comment.
  6573   7696   */
  6574   7697   static int line_is_complete(char *zSql, int nSql){
  6575   7698     int rc;
  6576   7699     if( zSql==0 ) return 1;
................................................................................
  6693   7816       if( nSql && line_contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior)
  6694   7817                   && sqlite3_complete(zSql) ){
  6695   7818         errCnt += runOneSqlLine(p, zSql, in, startline);
  6696   7819         nSql = 0;
  6697   7820         if( p->outCount ){
  6698   7821           output_reset(p);
  6699   7822           p->outCount = 0;
         7823  +      }else{
         7824  +        clearTempFile(p);
  6700   7825         }
  6701   7826       }else if( nSql && _all_whitespace(zSql) ){
  6702   7827         if( ShellHasFlag(p, SHFLG_Echo) ) printf("%s\n", zSql);
  6703   7828         nSql = 0;
  6704   7829       }
  6705   7830     }
  6706   7831     if( nSql && !_all_whitespace(zSql) ){
................................................................................
  7086   8211         sqlite3_vfs *pVfs = sqlite3_vfs_find(cmdline_option_value(argc,argv,++i));
  7087   8212         if( pVfs ){
  7088   8213           sqlite3_vfs_register(pVfs, 1);
  7089   8214         }else{
  7090   8215           utf8_printf(stderr, "no such VFS: \"%s\"\n", argv[i]);
  7091   8216           exit(1);
  7092   8217         }
         8218  +#ifdef SQLITE_HAVE_ZIP
         8219  +    }else if( strcmp(z,"-zip")==0 ){
         8220  +      data.openMode = SHELL_OPEN_ZIPFILE;
         8221  +#endif
         8222  +    }else if( strcmp(z,"-append")==0 ){
         8223  +      data.openMode = SHELL_OPEN_APPENDVFS;
  7093   8224       }
  7094   8225     }
  7095   8226     if( data.zDbFilename==0 ){
  7096   8227   #ifndef SQLITE_OMIT_MEMORYDB
  7097   8228       data.zDbFilename = ":memory:";
  7098   8229       warnInmemoryDb = argc==1;
  7099   8230   #else
  7100   8231       utf8_printf(stderr,"%s: Error: no database filename specified\n", Argv0);
  7101   8232       return 1;
  7102   8233   #endif
  7103   8234     }
  7104   8235     data.out = stdout;
         8236  +  sqlite3_appendvfs_init(0,0,0);
  7105   8237   
  7106   8238     /* Go ahead and open the database file if it already exists.  If the
  7107   8239     ** file does not exist, delay opening it.  This prevents empty database
  7108   8240     ** files from being created if a user mistypes the database name argument
  7109   8241     ** to the sqlite command-line tool.
  7110   8242     */
  7111   8243     if( access(data.zDbFilename, 0)==0 ){
................................................................................
  7138   8270       }else if( strcmp(z,"-line")==0 ){
  7139   8271         data.mode = MODE_Line;
  7140   8272       }else if( strcmp(z,"-column")==0 ){
  7141   8273         data.mode = MODE_Column;
  7142   8274       }else if( strcmp(z,"-csv")==0 ){
  7143   8275         data.mode = MODE_Csv;
  7144   8276         memcpy(data.colSeparator,",",2);
         8277  +#ifdef SQLITE_HAVE_ZIP
         8278  +    }else if( strcmp(z,"-zip")==0 ){
         8279  +      data.openMode = SHELL_OPEN_ZIPFILE;
         8280  +#endif
         8281  +    }else if( strcmp(z,"-append")==0 ){
         8282  +      data.openMode = SHELL_OPEN_APPENDVFS;
  7145   8283       }else if( strcmp(z,"-ascii")==0 ){
  7146   8284         data.mode = MODE_Ascii;
  7147   8285         sqlite3_snprintf(sizeof(data.colSeparator), data.colSeparator,
  7148   8286                          SEP_Unit);
  7149   8287         sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator,
  7150   8288                          SEP_Record);
  7151   8289       }else if( strcmp(z,"-separator")==0 ){
................................................................................
  7302   8440     set_table_name(&data, 0);
  7303   8441     if( data.db ){
  7304   8442       session_close_all(&data);
  7305   8443       sqlite3_close(data.db);
  7306   8444     }
  7307   8445     sqlite3_free(data.zFreeOnClose);
  7308   8446     find_home_dir(1);
         8447  +  output_reset(&data);
         8448  +  data.doXdgOpen = 0;
         8449  +  clearTempFile(&data);
  7309   8450   #if !SQLITE_SHELL_IS_UTF8
  7310   8451     for(i=0; i<argc; i++) sqlite3_free(argv[i]);
  7311   8452     sqlite3_free(argv);
  7312   8453   #endif
  7313   8454     return rc;
  7314   8455   }

Changes to src/sqlite.h.in.

   506    506   #define SQLITE_LOCKED_SHAREDCACHE      (SQLITE_LOCKED |  (1<<8))
   507    507   #define SQLITE_BUSY_RECOVERY           (SQLITE_BUSY   |  (1<<8))
   508    508   #define SQLITE_BUSY_SNAPSHOT           (SQLITE_BUSY   |  (2<<8))
   509    509   #define SQLITE_CANTOPEN_NOTEMPDIR      (SQLITE_CANTOPEN | (1<<8))
   510    510   #define SQLITE_CANTOPEN_ISDIR          (SQLITE_CANTOPEN | (2<<8))
   511    511   #define SQLITE_CANTOPEN_FULLPATH       (SQLITE_CANTOPEN | (3<<8))
   512    512   #define SQLITE_CANTOPEN_CONVPATH       (SQLITE_CANTOPEN | (4<<8))
   513         -#define SQLITE_CANTOPEN_DIRTYWAL       (SQLITE_CANTOPEN | (5<<8))
   514    513   #define SQLITE_CORRUPT_VTAB            (SQLITE_CORRUPT | (1<<8))
   515    514   #define SQLITE_READONLY_RECOVERY       (SQLITE_READONLY | (1<<8))
   516    515   #define SQLITE_READONLY_CANTLOCK       (SQLITE_READONLY | (2<<8))
   517    516   #define SQLITE_READONLY_ROLLBACK       (SQLITE_READONLY | (3<<8))
   518    517   #define SQLITE_READONLY_DBMOVED        (SQLITE_READONLY | (4<<8))
   519    518   #define SQLITE_READONLY_CANTINIT       (SQLITE_READONLY | (5<<8))
   520    519   #define SQLITE_READONLY_DIRECTORY      (SQLITE_READONLY | (6<<8))
................................................................................
  2948   2947      void(*xProfile)(void*,const char*,sqlite3_uint64), void*);
  2949   2948   
  2950   2949   /*
  2951   2950   ** CAPI3REF: SQL Trace Event Codes
  2952   2951   ** KEYWORDS: SQLITE_TRACE
  2953   2952   **
  2954   2953   ** These constants identify classes of events that can be monitored
  2955         -** using the [sqlite3_trace_v2()] tracing logic.  The third argument
  2956         -** to [sqlite3_trace_v2()] is an OR-ed combination of one or more of
         2954  +** using the [sqlite3_trace_v2()] tracing logic.  The M argument
         2955  +** to [sqlite3_trace_v2(D,M,X,P)] is an OR-ed combination of one or more of
  2957   2956   ** the following constants.  ^The first argument to the trace callback
  2958   2957   ** is one of the following constants.
  2959   2958   **
  2960   2959   ** New tracing constants may be added in future releases.
  2961   2960   **
  2962   2961   ** ^A trace callback has four arguments: xCallback(T,C,P,X).
  2963   2962   ** ^The T argument is one of the integer type codes above.
................................................................................
  3656   3655   ** a schema change, on the first  [sqlite3_step()] call following any change
  3657   3656   ** to the [sqlite3_bind_text | bindings] of that [parameter]. 
  3658   3657   ** ^The specific value of WHERE-clause [parameter] might influence the 
  3659   3658   ** choice of query plan if the parameter is the left-hand side of a [LIKE]
  3660   3659   ** or [GLOB] operator or if the parameter is compared to an indexed column
  3661   3660   ** and the [SQLITE_ENABLE_STAT3] compile-time option is enabled.
  3662   3661   ** </li>
         3662  +** </ol>
  3663   3663   **
  3664   3664   ** <p>^sqlite3_prepare_v3() differs from sqlite3_prepare_v2() only in having
  3665   3665   ** the extra prepFlags parameter, which is a bit array consisting of zero or
  3666   3666   ** more of the [SQLITE_PREPARE_PERSISTENT|SQLITE_PREPARE_*] flags.  ^The
  3667   3667   ** sqlite3_prepare_v2() interface works exactly the same as
  3668   3668   ** sqlite3_prepare_v3() with a zero prepFlags parameter.
  3669         -** </ol>
  3670   3669   */
  3671   3670   int sqlite3_prepare(
  3672   3671     sqlite3 *db,            /* Database handle */
  3673   3672     const char *zSql,       /* SQL statement, UTF-8 encoded */
  3674   3673     int nByte,              /* Maximum length of zSql in bytes. */
  3675   3674     sqlite3_stmt **ppStmt,  /* OUT: Statement handle */
  3676   3675     const char **pzTail     /* OUT: Pointer to unused portion of zSql */
................................................................................
  4795   4794   ** <tr><td><b>sqlite3_value_bytes16&nbsp;&nbsp;</b>
  4796   4795   ** <td>&rarr;&nbsp;&nbsp;<td>Size of UTF-16
  4797   4796   ** TEXT in bytes
  4798   4797   ** <tr><td><b>sqlite3_value_type</b><td>&rarr;<td>Default
  4799   4798   ** datatype of the value
  4800   4799   ** <tr><td><b>sqlite3_value_numeric_type&nbsp;&nbsp;</b>
  4801   4800   ** <td>&rarr;&nbsp;&nbsp;<td>Best numeric datatype of the value
         4801  +** <tr><td><b>sqlite3_value_nochange&nbsp;&nbsp;</b>
         4802  +** <td>&rarr;&nbsp;&nbsp;<td>True if the column is unchanged in an UPDATE
         4803  +** against a virtual table.
  4802   4804   ** </table></blockquote>
  4803   4805   **
  4804   4806   ** <b>Details:</b>
  4805   4807   **
  4806   4808   ** These routines extract type, size, and content information from
  4807   4809   ** [protected sqlite3_value] objects.  Protected sqlite3_value objects
  4808   4810   ** are used to pass parameter information into implementation of
................................................................................
  4842   4844   ** ^(The sqlite3_value_numeric_type() interface attempts to apply
  4843   4845   ** numeric affinity to the value.  This means that an attempt is
  4844   4846   ** made to convert the value to an integer or floating point.  If
  4845   4847   ** such a conversion is possible without loss of information (in other
  4846   4848   ** words, if the value is a string that looks like a number)
  4847   4849   ** then the conversion is performed.  Otherwise no conversion occurs.
  4848   4850   ** The [SQLITE_INTEGER | datatype] after conversion is returned.)^
         4851  +**
         4852  +** ^Within the [xUpdate] method of a [virtual table], the
         4853  +** sqlite3_value_nochange(X) interface returns true if and only if
         4854  +** the column corresponding to X is unchanged by the UPDATE operation
         4855  +** that the xUpdate method call was invoked to implement and if
         4856  +** and the prior [xColumn] method call that was invoked to extracted
         4857  +** the value for that column returned without setting a result (probably
         4858  +** because it queried [sqlite3_vtab_nochange()] and found that the column
         4859  +** was unchanging).  ^Within an [xUpdate] method, any value for which
         4860  +** sqlite3_value_nochange(X) is true will in all other respects appear
         4861  +** to be a NULL value.  If sqlite3_value_nochange(X) is invoked anywhere other
         4862  +** than within an [xUpdate] method call for an UPDATE statement, then
         4863  +** the return value is arbitrary and meaningless.
  4849   4864   **
  4850   4865   ** Please pay particular attention to the fact that the pointer returned
  4851   4866   ** from [sqlite3_value_blob()], [sqlite3_value_text()], or
  4852   4867   ** [sqlite3_value_text16()] can be invalidated by a subsequent call to
  4853   4868   ** [sqlite3_value_bytes()], [sqlite3_value_bytes16()], [sqlite3_value_text()],
  4854   4869   ** or [sqlite3_value_text16()].
  4855   4870   **
................................................................................
  4865   4880   const void *sqlite3_value_text16(sqlite3_value*);
  4866   4881   const void *sqlite3_value_text16le(sqlite3_value*);
  4867   4882   const void *sqlite3_value_text16be(sqlite3_value*);
  4868   4883   int sqlite3_value_bytes(sqlite3_value*);
  4869   4884   int sqlite3_value_bytes16(sqlite3_value*);
  4870   4885   int sqlite3_value_type(sqlite3_value*);
  4871   4886   int sqlite3_value_numeric_type(sqlite3_value*);
         4887  +int sqlite3_value_nochange(sqlite3_value*);
  4872   4888   
  4873   4889   /*
  4874   4890   ** CAPI3REF: Finding The Subtype Of SQL Values
  4875   4891   ** METHOD: sqlite3_value
  4876   4892   **
  4877   4893   ** The sqlite3_value_subtype(V) function returns the subtype for
  4878   4894   ** an [application-defined SQL function] argument V.  The subtype
................................................................................
  8293   8309   ** value returned is one of [SQLITE_ROLLBACK], [SQLITE_IGNORE], [SQLITE_FAIL],
  8294   8310   ** [SQLITE_ABORT], or [SQLITE_REPLACE], according to the [ON CONFLICT] mode
  8295   8311   ** of the SQL statement that triggered the call to the [xUpdate] method of the
  8296   8312   ** [virtual table].
  8297   8313   */
  8298   8314   int sqlite3_vtab_on_conflict(sqlite3 *);
  8299   8315   
         8316  +/*
         8317  +** CAPI3REF: Determine If Virtual Table Column Access Is For UPDATE
         8318  +**
         8319  +** If the sqlite3_vtab_nochange(X) routine is called within the [xColumn]
         8320  +** method of a [virtual table], then it returns true if and only if the
         8321  +** column is being fetched as part of an UPDATE operation during which the
         8322  +** column value will not change.  Applications might use this to substitute
         8323  +** a lighter-weight value to return that the corresponding [xUpdate] method
         8324  +** understands as a "no-change" value.
         8325  +**
         8326  +** If the [xColumn] method calls sqlite3_vtab_nochange() and finds that
         8327  +** the column is not changed by the UPDATE statement, they the xColumn
         8328  +** method can optionally return without setting a result, without calling
         8329  +** any of the [sqlite3_result_int|sqlite3_result_xxxxx() interfaces].
         8330  +** In that case, [sqlite3_value_nochange(X)] will return true for the
         8331  +** same column in the [xUpdate] method.
         8332  +*/
         8333  +int sqlite3_vtab_nochange(sqlite3_context*);
         8334  +
  8300   8335   /*
  8301   8336   ** CAPI3REF: Determine The Collation For a Virtual Table Constraint
  8302   8337   **
  8303   8338   ** This function may only be called from within a call to the [xBestIndex]
  8304         -** method of a [virtual table implementation]. 
         8339  +** method of a [virtual table]. 
  8305   8340   **
  8306   8341   ** The first argument must be the sqlite3_index_info object that is the
  8307   8342   ** first parameter to the xBestIndex() method. The second argument must be
  8308   8343   ** an index into the aConstraint[] array belonging to the sqlite3_index_info
  8309   8344   ** structure passed to xBestIndex. This function returns a pointer to a buffer 
  8310   8345   ** containing the name of the collation sequence for the corresponding
  8311   8346   ** constraint.

Changes to src/sqlite3ext.h.

   288    288     int (*prepare_v3)(sqlite3*,const char*,int,unsigned int,
   289    289                       sqlite3_stmt**,const char**);
   290    290     int (*prepare16_v3)(sqlite3*,const void*,int,unsigned int,
   291    291                         sqlite3_stmt**,const void**);
   292    292     int (*bind_pointer)(sqlite3_stmt*,int,void*,const char*,void(*)(void*));
   293    293     void (*result_pointer)(sqlite3_context*,void*,const char*,void(*)(void*));
   294    294     void *(*value_pointer)(sqlite3_value*,const char*);
          295  +  int (*vtab_nochange)(sqlite3_context*);
          296  +  int (*value_nochange)(sqlite3_value*);
          297  +  const char *(*vtab_collation)(sqlite3_index_info*,int);
   295    298   };
   296    299   
   297    300   /*
   298    301   ** This is the function signature used for all extension entry points.  It
   299    302   ** is also defined in the file "loadext.c".
   300    303   */
   301    304   typedef int (*sqlite3_loadext_entry)(
................................................................................
   554    557   #define sqlite3_set_last_insert_rowid  sqlite3_api->set_last_insert_rowid
   555    558   /* Version 3.20.0 and later */
   556    559   #define sqlite3_prepare_v3             sqlite3_api->prepare_v3
   557    560   #define sqlite3_prepare16_v3           sqlite3_api->prepare16_v3
   558    561   #define sqlite3_bind_pointer           sqlite3_api->bind_pointer
   559    562   #define sqlite3_result_pointer         sqlite3_api->result_pointer
   560    563   #define sqlite3_value_pointer          sqlite3_api->value_pointer
          564  +/* Version 3.22.0 and later */
          565  +#define sqlite3_vtab_nochange          sqlite3_api->vtab_nochange
          566  +#define sqlite3_value_nochange         sqlite3_api->value_nochange
          567  +#define sqlite3_vtab_collation         sqlite3_api->vtab_collation
   561    568   #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
   562    569   
   563    570   #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
   564    571     /* This case when the file really is being compiled as a loadable 
   565    572     ** extension */
   566    573   # define SQLITE_EXTENSION_INIT1     const sqlite3_api_routines *sqlite3_api=0;
   567    574   # define SQLITE_EXTENSION_INIT2(v)  sqlite3_api=v;

Changes to src/sqliteInt.h.

  3114   3114   #define OPFLAG_BULKCSR       0x01    /* OP_Open** used to open bulk cursor */
  3115   3115   #define OPFLAG_SEEKEQ        0x02    /* OP_Open** cursor uses EQ seek only */
  3116   3116   #define OPFLAG_FORDELETE     0x08    /* OP_Open should use BTREE_FORDELETE */
  3117   3117   #define OPFLAG_P2ISREG       0x10    /* P2 to OP_Open** is a register number */
  3118   3118   #define OPFLAG_PERMUTE       0x01    /* OP_Compare: use the permutation */
  3119   3119   #define OPFLAG_SAVEPOSITION  0x02    /* OP_Delete/Insert: save cursor pos */
  3120   3120   #define OPFLAG_AUXDELETE     0x04    /* OP_Delete: index in a DELETE op */
         3121  +#define OPFLAG_NOCHNG_MAGIC  0x6d    /* OP_MakeRecord: serialtype 10 is ok */
  3121   3122   
  3122   3123   /*
  3123   3124    * Each trigger present in the database schema is stored as an instance of
  3124   3125    * struct Trigger.
  3125   3126    *
  3126   3127    * Pointers to instances of struct Trigger are stored in two ways.
  3127   3128    * 1. In the "trigHash" hash table (part of the sqlite3* that represents the

Changes to src/tclsqlite.c.

    60     60   
    61     61   /* Used to get the current process ID */
    62     62   #if !defined(_WIN32)
    63     63   # include <unistd.h>
    64     64   # define GETPID getpid
    65     65   #elif !defined(_WIN32_WCE)
    66     66   # ifndef SQLITE_AMALGAMATION
    67         -#  define WIN32_LEAN_AND_MEAN
           67  +#  ifndef WIN32_LEAN_AND_MEAN
           68  +#   define WIN32_LEAN_AND_MEAN
           69  +#  endif
    68     70   #  include <windows.h>
    69     71   # endif
    70     72   # define GETPID (int)GetCurrentProcessId
    71     73   #endif
    72     74   
    73     75   /*
    74     76    * Windows needs to know which symbols to export.  Unix does not.

Changes to src/test1.c.

  6956   6956     extern int sqlite3_regexp_init(sqlite3*,char**,const sqlite3_api_routines*);
  6957   6957     extern int sqlite3_remember_init(sqlite3*,char**,const sqlite3_api_routines*);
  6958   6958     extern int sqlite3_series_init(sqlite3*,char**,const sqlite3_api_routines*);
  6959   6959     extern int sqlite3_spellfix_init(sqlite3*,char**,const sqlite3_api_routines*);
  6960   6960     extern int sqlite3_totype_init(sqlite3*,char**,const sqlite3_api_routines*);
  6961   6961     extern int sqlite3_wholenumber_init(sqlite3*,char**,const sqlite3_api_routines*);
  6962   6962     extern int sqlite3_unionvtab_init(sqlite3*,char**,const sqlite3_api_routines*);
         6963  +#ifdef SQLITE_HAVE_ZLIB
         6964  +  extern int sqlite3_zipfile_init(sqlite3*,char**,const sqlite3_api_routines*);
         6965  +#endif
  6963   6966     static const struct {
  6964   6967       const char *zExtName;
  6965   6968       int (*pInit)(sqlite3*,char**,const sqlite3_api_routines*);
  6966   6969     } aExtension[] = {
  6967   6970       { "amatch",                sqlite3_amatch_init               },
  6968   6971       { "carray",                sqlite3_carray_init               },
  6969   6972       { "closure",               sqlite3_closure_init              },
................................................................................
  6977   6980       { "regexp",                sqlite3_regexp_init               },
  6978   6981       { "remember",              sqlite3_remember_init             },
  6979   6982       { "series",                sqlite3_series_init               },
  6980   6983       { "spellfix",              sqlite3_spellfix_init             },
  6981   6984       { "totype",                sqlite3_totype_init               },
  6982   6985       { "unionvtab",             sqlite3_unionvtab_init            },
  6983   6986       { "wholenumber",           sqlite3_wholenumber_init          },
         6987  +#ifdef SQLITE_HAVE_ZLIB
         6988  +    { "zipfile",               sqlite3_zipfile_init              },
         6989  +#endif
  6984   6990     };
  6985   6991     sqlite3 *db;
  6986   6992     const char *zName;
  6987   6993     int i, j, rc;
  6988   6994     char *zErrMsg = 0;
  6989   6995     if( objc<3 ){
  6990   6996       Tcl_WrongNumArgs(interp, 1, objv, "DB NAME ...");

Changes to src/test_windirent.c.

    10     10   **
    11     11   *************************************************************************
    12     12   ** This file contains code to implement most of the opendir() family of
    13     13   ** POSIX functions on Win32 using the MSVCRT.
    14     14   */
    15     15   
    16     16   #if defined(_WIN32) && defined(_MSC_VER)
    17         -
    18     17   #include "test_windirent.h"
    19     18   
    20     19   /*
    21     20   ** Implementation of the POSIX getenv() function using the Win32 API.
    22     21   ** This function is not thread-safe.
    23     22   */
    24     23   const char *windirent_getenv(

Changes to src/test_windirent.h.

     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   ** This file contains declarations for most of the opendir() family of
    13     13   ** POSIX functions on Win32 using the MSVCRT.
    14     14   */
    15     15   
    16         -#if defined(_WIN32) && defined(_MSC_VER)
           16  +#if defined(_WIN32) && defined(_MSC_VER) && !defined(SQLITE_WINDIRENT_H)
           17  +#define SQLITE_WINDIRENT_H
    17     18   
    18     19   /*
    19     20   ** We need several data types from the Windows SDK header.
    20     21   */
    21     22   
           23  +#ifndef WIN32_LEAN_AND_MEAN
    22     24   #define WIN32_LEAN_AND_MEAN
           25  +#endif
           26  +
    23     27   #include "windows.h"
    24     28   
    25     29   /*
    26     30   ** We need several support functions from the SQLite core.
    27     31   */
    28     32   
    29     33   #include "sqlite3.h"
................................................................................
    33     37   */
    34     38   
    35     39   #include <stdio.h>
    36     40   #include <stdlib.h>
    37     41   #include <errno.h>
    38     42   #include <io.h>
    39     43   #include <limits.h>
           44  +#include <sys/types.h>
           45  +#include <sys/stat.h>
           46  +
           47  +/*
           48  +** We may need several defines that should have been in "sys/stat.h".
           49  +*/
           50  +
           51  +#ifndef S_ISREG
           52  +#define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG)
           53  +#endif
           54  +
           55  +#ifndef S_ISDIR
           56  +#define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
           57  +#endif
           58  +
           59  +#ifndef S_ISLNK
           60  +#define S_ISLNK(mode) (0)
           61  +#endif
           62  +
           63  +/*
           64  +** We may need to provide the "mode_t" type.
           65  +*/
           66  +
           67  +#ifndef MODE_T_DEFINED
           68  +  #define MODE_T_DEFINED
           69  +  typedef unsigned short mode_t;
           70  +#endif
    40     71   
    41     72   /*
    42     73   ** We may need to provide the "ino_t" type.
    43     74   */
    44     75   
    45     76   #ifndef INO_T_DEFINED
    46     77     #define INO_T_DEFINED
................................................................................
    71    102   #  define BAD_INTPTR_T ((intptr_t)(-1))
    72    103   #endif
    73    104   
    74    105   /*
    75    106   ** We need to provide the necessary structures and related types.
    76    107   */
    77    108   
          109  +#ifndef DIRENT_DEFINED
          110  +#define DIRENT_DEFINED
    78    111   typedef struct DIRENT DIRENT;
    79         -typedef struct DIR DIR;
    80    112   typedef DIRENT *LPDIRENT;
    81         -typedef DIR *LPDIR;
    82         -
    83    113   struct DIRENT {
    84    114     ino_t d_ino;               /* Sequence number, do not use. */
    85    115     unsigned d_attributes;     /* Win32 file attributes. */
    86    116     char d_name[NAME_MAX + 1]; /* Name within the directory. */
    87    117   };
          118  +#endif
    88    119   
          120  +#ifndef DIR_DEFINED
          121  +#define DIR_DEFINED
          122  +typedef struct DIR DIR;
          123  +typedef DIR *LPDIR;
    89    124   struct DIR {
    90    125     intptr_t d_handle; /* Value returned by "_findfirst". */
    91    126     DIRENT d_first;    /* DIRENT constructed based on "_findfirst". */
    92    127     DIRENT d_next;     /* DIRENT constructed based on "_findnext". */
    93    128   };
          129  +#endif
    94    130   
    95    131   /*
    96    132   ** Provide a macro, for use by the implementation, to determine if a
    97    133   ** particular directory entry should be skipped over when searching for
    98    134   ** the next directory entry that should be returned by the readdir() or
    99    135   ** readdir_r() functions.
   100    136   */

Changes to src/tokenize.c.

   522    522         if( lastTokenParsed==TK_SEMI ){
   523    523           tokenType = 0;
   524    524         }else if( lastTokenParsed==0 ){
   525    525           break;
   526    526         }else{
   527    527           tokenType = TK_SEMI;
   528    528         }
   529         -      zSql -= n;
          529  +      n = 0;
   530    530       }
   531    531       if( tokenType>=TK_SPACE ){
   532    532         assert( tokenType==TK_SPACE || tokenType==TK_ILLEGAL );
   533    533         if( db->u1.isInterrupted ){
   534    534           pParse->rc = SQLITE_INTERRUPT;
   535    535           break;
   536    536         }

Changes to src/update.c.

   803    803     int regRec;                     /* Register in which to assemble record */
   804    804     int regRowid;                   /* Register for ephem table rowid */
   805    805     int iCsr = pSrc->a[0].iCursor;  /* Cursor used for virtual table scan */
   806    806     int aDummy[2];                  /* Unused arg for sqlite3WhereOkOnePass() */
   807    807     int bOnePass;                   /* True to use onepass strategy */
   808    808     int addr;                       /* Address of OP_OpenEphemeral */
   809    809   
   810         -  /* Allocate nArg registers to martial the arguments to VUpdate. Then
          810  +  /* Allocate nArg registers in which to gather the arguments for VUpdate. Then
   811    811     ** create and open the ephemeral table in which the records created from
   812    812     ** these arguments will be temporarily stored. */
   813    813     assert( v );
   814    814     ephemTab = pParse->nTab++;
   815    815     addr= sqlite3VdbeAddOp2(v, OP_OpenEphemeral, ephemTab, nArg);
   816    816     regArg = pParse->nMem + 1;
   817    817     pParse->nMem += nArg;
................................................................................
   824    824   
   825    825     /* Populate the argument registers. */
   826    826     for(i=0; i<pTab->nCol; i++){
   827    827       if( aXRef[i]>=0 ){
   828    828         sqlite3ExprCode(pParse, pChanges->a[aXRef[i]].pExpr, regArg+2+i);
   829    829       }else{
   830    830         sqlite3VdbeAddOp3(v, OP_VColumn, iCsr, i, regArg+2+i);
          831  +      sqlite3VdbeChangeP5(v, 1); /* Enable sqlite3_vtab_nochange() */
   831    832       }
   832    833     }
   833    834     if( HasRowid(pTab) ){
   834    835       sqlite3VdbeAddOp2(v, OP_Rowid, iCsr, regArg);
   835    836       if( pRowid ){
   836    837         sqlite3ExprCode(pParse, pRowid, regArg+1);
   837    838       }else{
................................................................................
   858    859       if( sqlite3IsToplevel(pParse) ){
   859    860         pParse->isMultiWrite = 0;
   860    861       }
   861    862     }else{
   862    863       /* Create a record from the argument register contents and insert it into
   863    864       ** the ephemeral table. */
   864    865       sqlite3VdbeAddOp3(v, OP_MakeRecord, regArg, nArg, regRec);
          866  +#ifdef SQLITE_DEBUG
          867  +    /* Signal an assert() within OP_MakeRecord that it is allowed to
          868  +    ** accept no-change records with serial_type 10 */
          869  +    sqlite3VdbeChangeP5(v, OPFLAG_NOCHNG_MAGIC);
          870  +#endif
   865    871       sqlite3VdbeAddOp2(v, OP_NewRowid, ephemTab, regRowid);
   866    872       sqlite3VdbeAddOp3(v, OP_Insert, ephemTab, regRec, regRowid);
   867    873     }
   868    874   
   869    875   
   870    876     if( bOnePass==0 ){
   871    877       /* End the virtual table scan */

Changes to src/util.c.

   323    323   /*
   324    324   ** Compute 10 to the E-th power.  Examples:  E==1 results in 10.
   325    325   ** E==2 results in 100.  E==50 results in 1.0e50.
   326    326   **
   327    327   ** This routine only works for values of E between 1 and 341.
   328    328   */
   329    329   static LONGDOUBLE_TYPE sqlite3Pow10(int E){
          330  +#if defined(_MSC_VER)
          331  +  static const LONGDOUBLE_TYPE x[] = {
          332  +    1.0e+001,
          333  +    1.0e+002,
          334  +    1.0e+004,
          335  +    1.0e+008,
          336  +    1.0e+016,
          337  +    1.0e+032,
          338  +    1.0e+064,
          339  +    1.0e+128,
          340  +    1.0e+256
          341  +  };
          342  +  LONGDOUBLE_TYPE r = 1.0;
          343  +  int i;
          344  +  assert( E>=0 && E<=307 );
          345  +  for(i=0; E!=0; i++, E >>=1){
          346  +    if( E & 1 ) r *= x[i];
          347  +  }
          348  +  return r;
          349  +#else
   330    350     LONGDOUBLE_TYPE x = 10.0;
   331    351     LONGDOUBLE_TYPE r = 1.0;
   332    352     while(1){
   333    353       if( E & 1 ) r *= x;
   334    354       E >>= 1;
   335    355       if( E==0 ) break;
   336    356       x *= x;
   337    357     }
   338    358     return r; 
          359  +#endif
   339    360   }
   340    361   
   341    362   /*
   342    363   ** The string z[] is an text representation of a real number.
   343    364   ** Convert this string to a double and write it into *pResult.
   344    365   **
   345    366   ** The string z[] is length bytes in length (bytes, not characters) and

Changes to src/vdbe.c.

   460    460   /*
   461    461   ** Print the value of a register for tracing purposes:
   462    462   */
   463    463   static void memTracePrint(Mem *p){
   464    464     if( p->flags & MEM_Undefined ){
   465    465       printf(" undefined");
   466    466     }else if( p->flags & MEM_Null ){
   467         -    printf(" NULL");
          467  +    printf(p->flags & MEM_Zero ? " NULL-nochng" : " NULL");
   468    468     }else if( (p->flags & (MEM_Int|MEM_Str))==(MEM_Int|MEM_Str) ){
   469    469       printf(" si:%lld", p->u.i);
   470    470     }else if( p->flags & MEM_Int ){
   471    471       printf(" i:%lld", p->u.i);
   472    472   #ifndef SQLITE_OMIT_FLOATING_POINT
   473    473     }else if( p->flags & MEM_Real ){
   474    474       printf(" r:%g", p->u.r);
................................................................................
  2788   2788   
  2789   2789     /* Loop through the elements that will make up the record to figure
  2790   2790     ** out how much space is required for the new record.
  2791   2791     */
  2792   2792     pRec = pLast;
  2793   2793     do{
  2794   2794       assert( memIsValid(pRec) );
  2795         -    pRec->uTemp = serial_type = sqlite3VdbeSerialType(pRec, file_format, &len);
         2795  +    serial_type = sqlite3VdbeSerialType(pRec, file_format, &len);
  2796   2796       if( pRec->flags & MEM_Zero ){
  2797         -      if( nData ){
         2797  +      if( serial_type==0 ){
         2798  +        /* Values with MEM_Null and MEM_Zero are created by xColumn virtual
         2799  +        ** table methods that never invoke sqlite3_result_xxxxx() while
         2800  +        ** computing an unchanging column value in an UPDATE statement.
         2801  +        ** Give such values a special internal-use-only serial-type of 10
         2802  +        ** so that they can be passed through to xUpdate and have
         2803  +        ** a true sqlite3_value_nochange(). */
         2804  +        assert( pOp->p5==OPFLAG_NOCHNG_MAGIC || CORRUPT_DB );
         2805  +        serial_type = 10;
         2806  +      }else if( nData ){
  2798   2807           if( sqlite3VdbeMemExpandBlob(pRec) ) goto no_mem;
  2799   2808         }else{
  2800   2809           nZero += pRec->u.nZero;
  2801   2810           len -= pRec->u.nZero;
  2802   2811         }
  2803   2812       }
  2804   2813       nData += len;
  2805   2814       testcase( serial_type==127 );
  2806   2815       testcase( serial_type==128 );
  2807   2816       nHdr += serial_type<=127 ? 1 : sqlite3VarintLen(serial_type);
         2817  +    pRec->uTemp = serial_type;
  2808   2818       if( pRec==pData0 ) break;
  2809   2819       pRec--;
  2810   2820     }while(1);
  2811   2821   
  2812   2822     /* EVIDENCE-OF: R-22564-11647 The header begins with a single varint
  2813   2823     ** which determines the total number of bytes in the header. The varint
  2814   2824     ** value is the size of the header in bytes including the size varint
................................................................................
  4411   4421   case OP_InsertInt: {
  4412   4422     Mem *pData;       /* MEM cell holding data for the record to be inserted */
  4413   4423     Mem *pKey;        /* MEM cell holding key  for the record */
  4414   4424     VdbeCursor *pC;   /* Cursor to table into which insert is written */
  4415   4425     int seekResult;   /* Result of prior seek or 0 if no USESEEKRESULT flag */
  4416   4426     const char *zDb;  /* database name - used by the update hook */
  4417   4427     Table *pTab;      /* Table structure - used by update and pre-update hooks */
  4418         -  int op;           /* Opcode for update hook: SQLITE_UPDATE or SQLITE_INSERT */
  4419   4428     BtreePayload x;   /* Payload to be inserted */
  4420   4429   
  4421         -  op = 0;
  4422   4430     pData = &aMem[pOp->p2];
  4423   4431     assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  4424   4432     assert( memIsValid(pData) );
  4425   4433     pC = p->apCsr[pOp->p1];
  4426   4434     assert( pC!=0 );
  4427   4435     assert( pC->eCurType==CURTYPE_BTREE );
  4428   4436     assert( pC->uc.pCursor!=0 );
................................................................................
  4442   4450     }
  4443   4451   
  4444   4452     if( pOp->p4type==P4_TABLE && HAS_UPDATE_HOOK(db) ){
  4445   4453       assert( pC->iDb>=0 );
  4446   4454       zDb = db->aDb[pC->iDb].zDbSName;
  4447   4455       pTab = pOp->p4.pTab;
  4448   4456       assert( (pOp->p5 & OPFLAG_ISNOOP) || HasRowid(pTab) );
  4449         -    op = ((pOp->p5 & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_INSERT);
  4450   4457     }else{
  4451         -    pTab = 0; /* Not needed.  Silence a compiler warning. */
         4458  +    pTab = 0;
  4452   4459       zDb = 0;  /* Not needed.  Silence a compiler warning. */
  4453   4460     }
  4454   4461   
  4455   4462   #ifdef SQLITE_ENABLE_PREUPDATE_HOOK
  4456   4463     /* Invoke the pre-update hook, if any */
  4457         -  if( db->xPreUpdateCallback 
  4458         -   && pOp->p4type==P4_TABLE
  4459         -   && !(pOp->p5 & OPFLAG_ISUPDATE)
  4460         -  ){
  4461         -    sqlite3VdbePreUpdateHook(p, pC, SQLITE_INSERT, zDb, pTab, x.nKey, pOp->p2);
         4464  +  if( pTab ){
         4465  +    if( db->xPreUpdateCallback && !(pOp->p5 & OPFLAG_ISUPDATE) ){
         4466  +      sqlite3VdbePreUpdateHook(p, pC, SQLITE_INSERT, zDb, pTab, x.nKey,pOp->p2);
         4467  +    }
         4468  +    if( db->xUpdateCallback==0 || pTab->aCol==0 ){
         4469  +      /* Prevent post-update hook from running in cases when it should not */
         4470  +      pTab = 0;
         4471  +    }
  4462   4472     }
  4463   4473     if( pOp->p5 & OPFLAG_ISNOOP ) break;
  4464   4474   #endif
  4465   4475   
  4466   4476     if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++;
  4467   4477     if( pOp->p5 & OPFLAG_LASTROWID ) db->lastRowid = x.nKey;
  4468   4478     assert( pData->flags & (MEM_Blob|MEM_Str) );
................................................................................
  4479   4489         (pOp->p5 & (OPFLAG_APPEND|OPFLAG_SAVEPOSITION)), seekResult
  4480   4490     );
  4481   4491     pC->deferredMoveto = 0;
  4482   4492     pC->cacheStatus = CACHE_STALE;
  4483   4493   
  4484   4494     /* Invoke the update-hook if required. */
  4485   4495     if( rc ) goto abort_due_to_error;
  4486         -  if( db->xUpdateCallback && op ){
  4487         -    db->xUpdateCallback(db->pUpdateArg, op, zDb, pTab->zName, x.nKey);
         4496  +  if( pTab ){
         4497  +    assert( db->xUpdateCallback!=0 );
         4498  +    assert( pTab->aCol!=0 );
         4499  +    db->xUpdateCallback(db->pUpdateArg,
         4500  +           (pOp->p5 & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_INSERT,
         4501  +           zDb, pTab->zName, x.nKey);
  4488   4502     }
  4489   4503     break;
  4490   4504   }
  4491   4505   
  4492   4506   /* Opcode: Delete P1 P2 P3 P4 P5
  4493   4507   **
  4494   4508   ** Delete the record at which the P1 cursor is currently pointing.
................................................................................
  6186   6200     sqlite3_context *pCtx;
  6187   6201   
  6188   6202     assert( pOp->p4type==P4_FUNCDEF );
  6189   6203     n = pOp->p5;
  6190   6204     assert( pOp->p3>0 && pOp->p3<=(p->nMem+1 - p->nCursor) );
  6191   6205     assert( n==0 || (pOp->p2>0 && pOp->p2+n<=(p->nMem+1 - p->nCursor)+1) );
  6192   6206     assert( pOp->p3<pOp->p2 || pOp->p3>=pOp->p2+n );
  6193         -  pCtx = sqlite3DbMallocRawNN(db, sizeof(*pCtx) + (n-1)*sizeof(sqlite3_value*));
         6207  +  pCtx = sqlite3DbMallocRawNN(db, n*sizeof(sqlite3_value*) +
         6208  +               (sizeof(pCtx[0]) + sizeof(Mem) - sizeof(sqlite3_value*)));
  6194   6209     if( pCtx==0 ) goto no_mem;
  6195   6210     pCtx->pMem = 0;
         6211  +  pCtx->pOut = (Mem*)&(pCtx->argv[n]);
         6212  +  sqlite3VdbeMemInit(pCtx->pOut, db, MEM_Null);
  6196   6213     pCtx->pFunc = pOp->p4.pFunc;
  6197   6214     pCtx->iOp = (int)(pOp - aOp);
  6198   6215     pCtx->pVdbe = p;
         6216  +  pCtx->skipFlag = 0;
         6217  +  pCtx->isError = 0;
  6199   6218     pCtx->argc = n;
  6200   6219     pOp->p4type = P4_FUNCCTX;
  6201   6220     pOp->p4.pCtx = pCtx;
  6202   6221     pOp->opcode = OP_AggStep;
  6203   6222     /* Fall through into OP_AggStep */
  6204   6223   }
  6205   6224   case OP_AggStep: {
  6206   6225     int i;
  6207   6226     sqlite3_context *pCtx;
  6208   6227     Mem *pMem;
  6209         -  Mem t;
  6210   6228   
  6211   6229     assert( pOp->p4type==P4_FUNCCTX );
  6212   6230     pCtx = pOp->p4.pCtx;
  6213   6231     pMem = &aMem[pOp->p3];
  6214   6232   
  6215   6233     /* If this function is inside of a trigger, the register array in aMem[]
  6216   6234     ** might change from one evaluation to the next.  The next block of code
................................................................................
  6225   6243     for(i=0; i<pCtx->argc; i++){
  6226   6244       assert( memIsValid(pCtx->argv[i]) );
  6227   6245       REGISTER_TRACE(pOp->p2+i, pCtx->argv[i]);
  6228   6246     }
  6229   6247   #endif
  6230   6248   
  6231   6249     pMem->n++;
  6232         -  sqlite3VdbeMemInit(&t, db, MEM_Null);
  6233         -  pCtx->pOut = &t;
  6234         -  pCtx->fErrorOrAux = 0;
  6235         -  pCtx->skipFlag = 0;
         6250  +  assert( pCtx->pOut->flags==MEM_Null );
         6251  +  assert( pCtx->isError==0 );
         6252  +  assert( pCtx->skipFlag==0 );
  6236   6253     (pCtx->pFunc->xSFunc)(pCtx,pCtx->argc,pCtx->argv); /* IMP: R-24505-23230 */
  6237         -  if( pCtx->fErrorOrAux ){
  6238         -    if( pCtx->isError ){
  6239         -      sqlite3VdbeError(p, "%s", sqlite3_value_text(&t));
         6254  +  if( pCtx->isError ){
         6255  +    if( pCtx->isError>0 ){
         6256  +      sqlite3VdbeError(p, "%s", sqlite3_value_text(pCtx->pOut));
  6240   6257         rc = pCtx->isError;
  6241   6258       }
  6242         -    sqlite3VdbeMemRelease(&t);
         6259  +    if( pCtx->skipFlag ){
         6260  +      assert( pOp[-1].opcode==OP_CollSeq );
         6261  +      i = pOp[-1].p1;
         6262  +      if( i ) sqlite3VdbeMemSetInt64(&aMem[i], 1);
         6263  +      pCtx->skipFlag = 0;
         6264  +    }
         6265  +    sqlite3VdbeMemRelease(pCtx->pOut);
         6266  +    pCtx->pOut->flags = MEM_Null;
         6267  +    pCtx->isError = 0;
  6243   6268       if( rc ) goto abort_due_to_error;
  6244         -  }else{
  6245         -    assert( t.flags==MEM_Null );
  6246   6269     }
  6247         -  if( pCtx->skipFlag ){
  6248         -    assert( pOp[-1].opcode==OP_CollSeq );
  6249         -    i = pOp[-1].p1;
  6250         -    if( i ) sqlite3VdbeMemSetInt64(&aMem[i], 1);
  6251         -  }
         6270  +  assert( pCtx->pOut->flags==MEM_Null );
         6271  +  assert( pCtx->skipFlag==0 );
  6252   6272     break;
  6253   6273   }
  6254   6274   
  6255   6275   /* Opcode: AggFinal P1 P2 * P4 *
  6256   6276   ** Synopsis: accum=r[P1] N=P2
  6257   6277   **
  6258   6278   ** Execute the finalizer function for an aggregate.  P1 is
................................................................................
  6689   6709     VdbeBranchTaken(res!=0,2);
  6690   6710     if( res ) goto jump_to_p2;
  6691   6711     break;
  6692   6712   }
  6693   6713   #endif /* SQLITE_OMIT_VIRTUALTABLE */
  6694   6714   
  6695   6715   #ifndef SQLITE_OMIT_VIRTUALTABLE
  6696         -/* Opcode: VColumn P1 P2 P3 * *
         6716  +/* Opcode: VColumn P1 P2 P3 * P5
  6697   6717   ** Synopsis: r[P3]=vcolumn(P2)
  6698   6718   **
  6699         -** Store the value of the P2-th column of
  6700         -** the row of the virtual-table that the 
  6701         -** P1 cursor is pointing to into register P3.
         6719  +** Store in register P3 the value of the P2-th column of
         6720  +** the current row of the virtual-table of cursor P1.
         6721  +**
         6722  +** If the VColumn opcode is being used to fetch the value of
         6723  +** an unchanging column during an UPDATE operation, then the P5
         6724  +** value is 1.  Otherwise, P5 is 0.  The P5 value is returned
         6725  +** by sqlite3_vtab_nochange() routine can can be used
         6726  +** by virtual table implementations to return special "no-change"
         6727  +** marks which can be more efficient, depending on the virtual table.
  6702   6728   */
  6703   6729   case OP_VColumn: {
  6704   6730     sqlite3_vtab *pVtab;
  6705   6731     const sqlite3_module *pModule;
  6706   6732     Mem *pDest;
  6707   6733     sqlite3_context sContext;
  6708   6734   
................................................................................
  6716   6742       break;
  6717   6743     }
  6718   6744     pVtab = pCur->uc.pVCur->pVtab;
  6719   6745     pModule = pVtab->pModule;
  6720   6746     assert( pModule->xColumn );
  6721   6747     memset(&sContext, 0, sizeof(sContext));
  6722   6748     sContext.pOut = pDest;
  6723         -  MemSetTypeFlag(pDest, MEM_Null);
         6749  +  if( pOp->p5 ){
         6750  +    sqlite3VdbeMemSetNull(pDest);
         6751  +    pDest->flags = MEM_Null|MEM_Zero;
         6752  +    pDest->u.nZero = 0;
         6753  +  }else{
         6754  +    MemSetTypeFlag(pDest, MEM_Null);
         6755  +  }
  6724   6756     rc = pModule->xColumn(pCur->uc.pVCur, &sContext, pOp->p2);
  6725   6757     sqlite3VtabImportErrmsg(p, pVtab);
  6726         -  if( sContext.isError ){
         6758  +  if( sContext.isError>0 ){
  6727   6759       rc = sContext.isError;
  6728   6760     }
  6729   6761     sqlite3VdbeChangeEncoding(pDest, encoding);
  6730   6762     REGISTER_TRACE(pOp->p3, pDest);
  6731   6763     UPDATE_MAX_BLOBSIZE(pDest);
  6732   6764   
  6733   6765     if( sqlite3VdbeMemTooBig(pDest) ){
................................................................................
  6984   7016     assert( pOp->p3<pOp->p2 || pOp->p3>=pOp->p2+n );
  6985   7017     pCtx = sqlite3DbMallocRawNN(db, sizeof(*pCtx) + (n-1)*sizeof(sqlite3_value*));
  6986   7018     if( pCtx==0 ) goto no_mem;
  6987   7019     pCtx->pOut = 0;
  6988   7020     pCtx->pFunc = pOp->p4.pFunc;
  6989   7021     pCtx->iOp = (int)(pOp - aOp);
  6990   7022     pCtx->pVdbe = p;
         7023  +  pCtx->isError = 0;
  6991   7024     pCtx->argc = n;
  6992   7025     pOp->p4type = P4_FUNCCTX;
  6993   7026     pOp->p4.pCtx = pCtx;
  6994   7027     assert( OP_PureFunc == OP_PureFunc0+2 );
  6995   7028     assert( OP_Function == OP_Function0+2 );
  6996   7029     pOp->opcode += 2;
  6997   7030     /* Fall through into OP_Function */
................................................................................
  7018   7051   #ifdef SQLITE_DEBUG
  7019   7052     for(i=0; i<pCtx->argc; i++){
  7020   7053       assert( memIsValid(pCtx->argv[i]) );
  7021   7054       REGISTER_TRACE(pOp->p2+i, pCtx->argv[i]);
  7022   7055     }
  7023   7056   #endif
  7024   7057     MemSetTypeFlag(pOut, MEM_Null);
  7025         -  pCtx->fErrorOrAux = 0;
         7058  +  assert( pCtx->isError==0 );
  7026   7059     (*pCtx->pFunc->xSFunc)(pCtx, pCtx->argc, pCtx->argv);/* IMP: R-24505-23230 */
  7027   7060   
  7028   7061     /* If the function returned an error, throw an exception */
  7029         -  if( pCtx->fErrorOrAux ){
  7030         -    if( pCtx->isError ){
         7062  +  if( pCtx->isError ){
         7063  +    if( pCtx->isError>0 ){
  7031   7064         sqlite3VdbeError(p, "%s", sqlite3_value_text(pOut));
  7032   7065         rc = pCtx->isError;
  7033   7066       }
  7034   7067       sqlite3VdbeDeleteAuxData(db, &p->pAuxData, pCtx->iOp, pOp->p1);
         7068  +    pCtx->isError = 0;
  7035   7069       if( rc ) goto abort_due_to_error;
  7036   7070     }
  7037   7071   
  7038   7072     /* Copy the result of the function into register P3 */
  7039   7073     if( pOut->flags & (MEM_Str|MEM_Blob) ){
  7040   7074       sqlite3VdbeChangeEncoding(pOut, encoding);
  7041   7075       if( sqlite3VdbeMemTooBig(pOut) ) goto too_big;
................................................................................
  7069   7103   ** first time they are evaluated for this run.
  7070   7104   **
  7071   7105   ** If P3 is not zero, then it is an address to jump to if an SQLITE_CORRUPT
  7072   7106   ** error is encountered.
  7073   7107   */
  7074   7108   case OP_Trace:
  7075   7109   case OP_Init: {          /* jump */
  7076         -  char *zTrace;
  7077   7110     int i;
         7111  +#ifndef SQLITE_OMIT_TRACE
         7112  +  char *zTrace;
         7113  +#endif
  7078   7114   
  7079   7115     /* If the P4 argument is not NULL, then it must be an SQL comment string.
  7080   7116     ** The "--" string is broken up to prevent false-positives with srcck1.c.
  7081   7117     **
  7082   7118     ** This assert() provides evidence for:
  7083   7119     ** EVIDENCE-OF: R-50676-09860 The callback can compute the same text that
  7084   7120     ** would have been returned by the legacy sqlite3_trace() interface by

Changes to src/vdbe.h.

   123    123   #define P4_EXPR       (-10) /* P4 is a pointer to an Expr tree */
   124    124   #define P4_MEM        (-11) /* P4 is a pointer to a Mem*    structure */
   125    125   #define P4_VTAB       (-12) /* P4 is a pointer to an sqlite3_vtab structure */
   126    126   #define P4_REAL       (-13) /* P4 is a 64-bit floating point value */
   127    127   #define P4_INT64      (-14) /* P4 is a 64-bit signed integer */
   128    128   #define P4_INTARRAY   (-15) /* P4 is a vector of 32-bit integers */
   129    129   #define P4_FUNCCTX    (-16) /* P4 is a pointer to an sqlite3_context object */
          130  +#define P4_DYNBLOB    (-17) /* Pointer to memory from sqliteMalloc() */
   130    131   
   131    132   /* Error message codes for OP_Halt */
   132    133   #define P5_ConstraintNotNull 1
   133    134   #define P5_ConstraintUnique  2
   134    135   #define P5_ConstraintCheck   3
   135    136   #define P5_ConstraintFK      4
   136    137   

Changes to src/vdbeInt.h.

   313    313     Mem *pOut;              /* The return value is stored here */
   314    314     FuncDef *pFunc;         /* Pointer to function information */
   315    315     Mem *pMem;              /* Memory cell used to store aggregate context */
   316    316     Vdbe *pVdbe;            /* The VM that owns this context */
   317    317     int iOp;                /* Instruction number of OP_Function */
   318    318     int isError;            /* Error code returned by the function. */
   319    319     u8 skipFlag;            /* Skip accumulator loading if true */
   320         -  u8 fErrorOrAux;         /* isError!=0 or pVdbe->pAuxData modified */
   321    320     u8 argc;                /* Number of arguments */
   322    321     sqlite3_value *argv[1]; /* Argument set */
   323    322   };
   324    323   
   325    324   /* A bitfield type for use inside of structures.  Always follow with :N where
   326    325   ** N is the number of bits.
   327    326   */

Changes to src/vdbeapi.c.

   263    263        SQLITE_INTEGER,  /* 0x1c */
   264    264        SQLITE_NULL,     /* 0x1d */
   265    265        SQLITE_INTEGER,  /* 0x1e */
   266    266        SQLITE_NULL,     /* 0x1f */
   267    267     };
   268    268     return aType[pVal->flags&MEM_AffMask];
   269    269   }
          270  +
          271  +/* Return true if a parameter to xUpdate represents an unchanged column */
          272  +int sqlite3_value_nochange(sqlite3_value *pVal){
          273  +  return (pVal->flags&(MEM_Null|MEM_Zero))==(MEM_Null|MEM_Zero);
          274  +}
   270    275   
   271    276   /* Make a copy of an sqlite3_value object
   272    277   */
   273    278   sqlite3_value *sqlite3_value_dup(const sqlite3_value *pOrig){
   274    279     sqlite3_value *pNew;
   275    280     if( pOrig==0 ) return 0;
   276    281     pNew = sqlite3_malloc( sizeof(*pNew) );
................................................................................
   363    368   void sqlite3_result_double(sqlite3_context *pCtx, double rVal){
   364    369     assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
   365    370     sqlite3VdbeMemSetDouble(pCtx->pOut, rVal);
   366    371   }
   367    372   void sqlite3_result_error(sqlite3_context *pCtx, const char *z, int n){
   368    373     assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
   369    374     pCtx->isError = SQLITE_ERROR;
   370         -  pCtx->fErrorOrAux = 1;
   371    375     sqlite3VdbeMemSetStr(pCtx->pOut, z, n, SQLITE_UTF8, SQLITE_TRANSIENT);
   372    376   }
   373    377   #ifndef SQLITE_OMIT_UTF16
   374    378   void sqlite3_result_error16(sqlite3_context *pCtx, const void *z, int n){
   375    379     assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
   376    380     pCtx->isError = SQLITE_ERROR;
   377         -  pCtx->fErrorOrAux = 1;
   378    381     sqlite3VdbeMemSetStr(pCtx->pOut, z, n, SQLITE_UTF16NATIVE, SQLITE_TRANSIENT);
   379    382   }
   380    383   #endif
   381    384   void sqlite3_result_int(sqlite3_context *pCtx, int iVal){
   382    385     assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
   383    386     sqlite3VdbeMemSetInt64(pCtx->pOut, (i64)iVal);
   384    387   }
................................................................................
   476    479     if( n>(u64)pOut->db->aLimit[SQLITE_LIMIT_LENGTH] ){
   477    480       return SQLITE_TOOBIG;
   478    481     }
   479    482     sqlite3VdbeMemSetZeroBlob(pCtx->pOut, (int)n);
   480    483     return SQLITE_OK;
   481    484   }
   482    485   void sqlite3_result_error_code(sqlite3_context *pCtx, int errCode){
   483         -  pCtx->isError = errCode;
   484         -  pCtx->fErrorOrAux = 1;
          486  +  pCtx->isError = errCode ? errCode : -1;
   485    487   #ifdef SQLITE_DEBUG
   486    488     if( pCtx->pVdbe ) pCtx->pVdbe->rcApp = errCode;
   487    489   #endif
   488    490     if( pCtx->pOut->flags & MEM_Null ){
   489    491       sqlite3VdbeMemSetStr(pCtx->pOut, sqlite3ErrStr(errCode), -1, 
   490    492                            SQLITE_UTF8, SQLITE_STATIC);
   491    493     }
   492    494   }
   493    495   
   494    496   /* Force an SQLITE_TOOBIG error. */
   495    497   void sqlite3_result_error_toobig(sqlite3_context *pCtx){
   496    498     assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
   497    499     pCtx->isError = SQLITE_TOOBIG;
   498         -  pCtx->fErrorOrAux = 1;
   499    500     sqlite3VdbeMemSetStr(pCtx->pOut, "string or blob too big", -1, 
   500    501                          SQLITE_UTF8, SQLITE_STATIC);
   501    502   }
   502    503   
   503    504   /* An SQLITE_NOMEM error. */
   504    505   void sqlite3_result_error_nomem(sqlite3_context *pCtx){
   505    506     assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
   506    507     sqlite3VdbeMemSetNull(pCtx->pOut);
   507    508     pCtx->isError = SQLITE_NOMEM_BKPT;
   508         -  pCtx->fErrorOrAux = 1;
   509    509     sqlite3OomFault(pCtx->pOut->db);
   510    510   }
   511    511   
   512    512   /*
   513    513   ** This function is called after a transaction has been committed. It 
   514    514   ** invokes callbacks registered with sqlite3_wal_hook() as required.
   515    515   */
................................................................................
   740    740   ** sqlite3_create_function16() routines that originally registered the
   741    741   ** application defined function.
   742    742   */
   743    743   sqlite3 *sqlite3_context_db_handle(sqlite3_context *p){
   744    744     assert( p && p->pOut );
   745    745     return p->pOut->db;
   746    746   }
          747  +
          748  +/*
          749  +** If this routine is invoked from within an xColumn method of a virtual
          750  +** table, then it returns true if and only if the the call is during an
          751  +** UPDATE operation and the value of the column will not be modified
          752  +** by the UPDATE.
          753  +**
          754  +** If this routine is called from any context other than within the
          755  +** xColumn method of a virtual table, then the return value is meaningless
          756  +** and arbitrary.
          757  +**
          758  +** Virtual table implements might use this routine to optimize their
          759  +** performance by substituting a NULL result, or some other light-weight
          760  +** value, as a signal to the xUpdate routine that the column is unchanged.
          761  +*/
          762  +int sqlite3_vtab_nochange(sqlite3_context *p){
          763  +  assert( p );
          764  +  return sqlite3_value_nochange(p->pOut);
          765  +}
   747    766   
   748    767   /*
   749    768   ** Return the current time for a statement.  If the current time
   750    769   ** is requested more than once within the same run of a single prepared
   751    770   ** statement, the exact same time is returned for each invocation regardless
   752    771   ** of the amount of time that elapses between invocations.  In other words,
   753    772   ** the time returned is always the time of the first call.
................................................................................
   889    908     if( pAuxData==0 ){
   890    909       pAuxData = sqlite3DbMallocZero(pVdbe->db, sizeof(AuxData));
   891    910       if( !pAuxData ) goto failed;
   892    911       pAuxData->iAuxOp = pCtx->iOp;
   893    912       pAuxData->iAuxArg = iArg;
   894    913       pAuxData->pNextAux = pVdbe->pAuxData;
   895    914       pVdbe->pAuxData = pAuxData;
   896         -    if( pCtx->fErrorOrAux==0 ){
   897         -      pCtx->isError = 0;
   898         -      pCtx->fErrorOrAux = 1;
   899         -    }
          915  +    if( pCtx->isError==0 ) pCtx->isError = -1;
   900    916     }else if( pAuxData->xDeleteAux ){
   901    917       pAuxData->xDeleteAux(pAuxData->pAux);
   902    918     }
   903    919   
   904    920     pAuxData->pAux = pAux;
   905    921     pAuxData->xDeleteAux = xDelete;
   906    922     return;

Changes to src/vdbeaux.c.

   862    862       case P4_FUNCCTX: {
   863    863         freeP4FuncCtx(db, (sqlite3_context*)p4);
   864    864         break;
   865    865       }
   866    866       case P4_REAL:
   867    867       case P4_INT64:
   868    868       case P4_DYNAMIC:
          869  +    case P4_DYNBLOB:
   869    870       case P4_INTARRAY: {
   870    871         sqlite3DbFree(db, p4);
   871    872         break;
   872    873       }
   873    874       case P4_KEYINFO: {
   874    875         if( db->pnBytesFreed==0 ) sqlite3KeyInfoUnref((KeyInfo*)p4);
   875    876         break;
................................................................................
  1403   1404         sqlite3StrAccumAppend(&x, "]", 1);
  1404   1405         break;
  1405   1406       }
  1406   1407       case P4_SUBPROGRAM: {
  1407   1408         sqlite3XPrintf(&x, "program");
  1408   1409         break;
  1409   1410       }
         1411  +    case P4_DYNBLOB:
  1410   1412       case P4_ADVANCE: {
  1411   1413         zTemp[0] = 0;
  1412   1414         break;
  1413   1415       }
  1414   1416       case P4_TABLE: {
  1415   1417         sqlite3XPrintf(&x, "%s", pOp->p4.pTab->zName);
  1416   1418         break;
................................................................................
  3448   3450   }
  3449   3451   u32 sqlite3VdbeSerialGet(
  3450   3452     const unsigned char *buf,     /* Buffer to deserialize from */
  3451   3453     u32 serial_type,              /* Serial type to deserialize */
  3452   3454     Mem *pMem                     /* Memory cell to write value into */
  3453   3455   ){
  3454   3456     switch( serial_type ){
  3455         -    case 10:   /* Reserved for future use */
         3457  +    case 10: { /* Internal use only: NULL with virtual table
         3458  +               ** UPDATE no-change flag set */
         3459  +      pMem->flags = MEM_Null|MEM_Zero;
         3460  +      pMem->n = 0;
         3461  +      pMem->u.nZero = 0;
         3462  +      break;
         3463  +    }
  3456   3464       case 11:   /* Reserved for future use */
  3457   3465       case 0: {  /* Null */
  3458   3466         /* EVIDENCE-OF: R-24078-09375 Value is a NULL. */
  3459   3467         pMem->flags = MEM_Null;
  3460   3468         break;
  3461   3469       }
  3462   3470       case 1: {

Changes to src/vdbemem.c.

    39     39   
    40     40     /* Cannot be both MEM_Int and MEM_Real at the same time */
    41     41     assert( (p->flags & (MEM_Int|MEM_Real))!=(MEM_Int|MEM_Real) );
    42     42   
    43     43     if( p->flags & MEM_Null ){
    44     44       /* Cannot be both MEM_Null and some other type */
    45     45       assert( (p->flags & (MEM_Int|MEM_Real|MEM_Str|MEM_Blob
    46         -                         |MEM_RowSet|MEM_Frame|MEM_Agg|MEM_Zero))==0 );
           46  +                         |MEM_RowSet|MEM_Frame|MEM_Agg))==0 );
    47     47   
    48     48       /* If MEM_Null is set, then either the value is a pure NULL (the usual
    49     49       ** case) or it is a pointer set using sqlite3_bind_pointer() or
    50     50       ** sqlite3_result_pointer().  If a pointer, then MEM_Term must also be
    51     51       ** set.
    52     52       */
    53     53       if( (p->flags & (MEM_Term|MEM_Subtype))==(MEM_Term|MEM_Subtype) ){
................................................................................
   577    577     assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
   578    578     assert( EIGHT_BYTE_ALIGNMENT(pMem) );
   579    579   
   580    580     pMem->u.r = sqlite3VdbeRealValue(pMem);
   581    581     MemSetTypeFlag(pMem, MEM_Real);
   582    582     return SQLITE_OK;
   583    583   }
          584  +
          585  +/* Compare a floating point value to an integer.  Return true if the two
          586  +** values are the same within the precision of the floating point value.
          587  +**
          588  +** For some versions of GCC on 32-bit machines, if you do the more obvious
          589  +** comparison of "r1==(double)i" you sometimes get an answer of false even
          590  +** though the r1 and (double)i values are bit-for-bit the same.
          591  +*/
          592  +static int sqlite3RealSameAsInt(double r1, sqlite3_int64 i){
          593  +  double r2 = (double)i;
          594  +  return memcmp(&r1, &r2, sizeof(r1))==0;
          595  +}
   584    596   
   585    597   /*
   586    598   ** Convert pMem so that it has types MEM_Real or MEM_Int or both.
   587    599   ** Invalidate any prior representations.
   588    600   **
   589    601   ** Every effort is made to force the conversion, even if the input
   590    602   ** is a string that does not look completely like a number.  Convert
................................................................................
   597    609       assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
   598    610       rc = sqlite3Atoi64(pMem->z, &pMem->u.i, pMem->n, pMem->enc);
   599    611       if( rc==0 ){
   600    612         MemSetTypeFlag(pMem, MEM_Int);
   601    613       }else{
   602    614         i64 i = pMem->u.i;
   603    615         sqlite3AtoF(pMem->z, &pMem->u.r, pMem->n, pMem->enc);
   604         -      if( rc==1 && pMem->u.r==(double)i ){
          616  +      if( rc==1 && sqlite3RealSameAsInt(pMem->u.r, i) ){
   605    617           pMem->u.i = i;
   606    618           MemSetTypeFlag(pMem, MEM_Int);
   607    619         }else{
   608    620           MemSetTypeFlag(pMem, MEM_Real);
   609    621         }
   610    622       }
   611    623     }

Changes to src/where.c.

  4797   4797       }
  4798   4798     }
  4799   4799     WHERETRACE(0xffff,("*** Optimizer Finished ***\n"));
  4800   4800     pWInfo->pParse->nQueryLoop += pWInfo->nRowOut;
  4801   4801   
  4802   4802     /* If the caller is an UPDATE or DELETE statement that is requesting
  4803   4803     ** to use a one-pass algorithm, determine if this is appropriate.
         4804  +  **
         4805  +  ** A one-pass approach can be used if the caller has requested one
         4806  +  ** and either (a) the scan visits at most one row or (b) each
         4807  +  ** of the following are true:
         4808  +  **
         4809  +  **   * the caller has indicated that a one-pass approach can be used
         4810  +  **     with multiple rows (by setting WHERE_ONEPASS_MULTIROW), and
         4811  +  **   * the table is not a virtual table, and
         4812  +  **   * either the scan does not use the OR optimization or the caller
         4813  +  **     is a DELETE operation (WHERE_DUPLICATES_OK is only specified
         4814  +  **     for DELETE).
         4815  +  **
         4816  +  ** The last qualification is because an UPDATE statement uses
         4817  +  ** WhereInfo.aiCurOnePass[1] to determine whether or not it really can
         4818  +  ** use a one-pass approach, and this is not set accurately for scans
         4819  +  ** that use the OR optimization.
  4804   4820     */
  4805   4821     assert( (wctrlFlags & WHERE_ONEPASS_DESIRED)==0 || pWInfo->nLevel==1 );
  4806   4822     if( (wctrlFlags & WHERE_ONEPASS_DESIRED)!=0 ){
  4807   4823       int wsFlags = pWInfo->a[0].pWLoop->wsFlags;
  4808   4824       int bOnerow = (wsFlags & WHERE_ONEROW)!=0;
  4809         -    if( bOnerow
  4810         -     || ((wctrlFlags & WHERE_ONEPASS_MULTIROW)!=0
  4811         -           && 0==(wsFlags & WHERE_VIRTUALTABLE))
  4812         -    ){
         4825  +    if( bOnerow || (
         4826  +        0!=(wctrlFlags & WHERE_ONEPASS_MULTIROW)
         4827  +     && 0==(wsFlags & WHERE_VIRTUALTABLE)
         4828  +     && (0==(wsFlags & WHERE_MULTI_OR) || (wctrlFlags & WHERE_DUPLICATES_OK))
         4829  +    )){
  4813   4830         pWInfo->eOnePass = bOnerow ? ONEPASS_SINGLE : ONEPASS_MULTI;
  4814   4831         if( HasRowid(pTabList->a[0].pTab) && (wsFlags & WHERE_IDX_ONLY) ){
  4815   4832           if( wctrlFlags & WHERE_ONEPASS_MULTIROW ){
  4816   4833             bFordelete = OPFLAG_FORDELETE;
  4817   4834           }
  4818   4835           pWInfo->a[0].pWLoop->wsFlags = (wsFlags & ~WHERE_IDX_ONLY);
  4819   4836         }

Changes to src/wherecode.c.

  2166   2166       pE = pTerm->pExpr;
  2167   2167       assert( !ExprHasProperty(pE, EP_FromJoin) );
  2168   2168       assert( (pTerm->prereqRight & pLevel->notReady)!=0 );
  2169   2169       pAlt = sqlite3WhereFindTerm(pWC, iCur, pTerm->u.leftColumn, notReady,
  2170   2170                       WO_EQ|WO_IN|WO_IS, 0);
  2171   2171       if( pAlt==0 ) continue;
  2172   2172       if( pAlt->wtFlags & (TERM_CODED) ) continue;
         2173  +    if( (pAlt->eOperator & WO_IN) 
         2174  +     && (pAlt->pExpr->flags & EP_xIsSelect)
         2175  +     && (pAlt->pExpr->x.pSelect->pEList->nExpr>1)
         2176  +    ){
         2177  +      continue;
         2178  +    }
  2173   2179       testcase( pAlt->eOperator & WO_EQ );
  2174   2180       testcase( pAlt->eOperator & WO_IS );
  2175   2181       testcase( pAlt->eOperator & WO_IN );
  2176   2182       VdbeModuleComment((v, "begin transitive constraint"));
  2177   2183       sEAlt = *pAlt->pExpr;
  2178   2184       sEAlt.pLeft = pE->pLeft;
  2179   2185       sqlite3ExprIfFalse(pParse, &sEAlt, addrCont, SQLITE_JUMPIFNULL);

Changes to test/capi2.test.

   159    159     lappend rc $msg $TAIL
   160    160   } {1 {(1) no such column: bogus} {}}
   161    161   do_test capi2-3.2 {
   162    162     set rc [catch {
   163    163         sqlite3_prepare $DB {select bogus from } -1 TAIL
   164    164     } msg]
   165    165     lappend rc $msg $TAIL
   166         -} {1 {(1) near " ": syntax error} {}}
          166  +} {1 {(1) incomplete input} {}}
   167    167   do_test capi2-3.3 {
   168    168     set rc [catch {
   169    169         sqlite3_prepare $DB {;;;;select bogus from sqlite_master} -1 TAIL
   170    170     } msg]
   171    171     lappend rc $msg $TAIL
   172    172   } {1 {(1) no such column: bogus} {}}
   173    173   do_test capi2-3.4 {

Changes to test/capi3.test.

   645    645   
   646    646   check_header $STMT capi3-5.31 {x y z} {VARINT {} {}}
   647    647   check_origin_header $STMT capi3-5.32 {main {} {}} {t1 {} {}} {a {} {}}
   648    648   do_test capi3-5.33 {
   649    649     sqlite3_finalize $STMT
   650    650   } SQLITE_OK
   651    651   
          652  +# 2018-01-09:  If a column is the last token if a string, the column name
          653  +# was not being set correctly, due to changes in check-in
          654  +# https://sqlite.org/src/info/0fdf97efe5df7455
          655  +#
          656  +# This problem was detected by the community during beta-testing.
          657  +#
          658  +do_test capi3-5.34 {
          659  +  set STMT [sqlite3_prepare $DB {SELECT :a, :b} -1 TAIL]
          660  +  sqlite3_column_count $STMT
          661  +} 2
          662  +check_header $STMT capi-5.35 {:a :b} {{} {}}
          663  +sqlite3_finalize $STMT
   652    664   
   653    665   set ::ENC [execsql {pragma encoding}]
   654    666   db close
   655    667   
   656    668   do_test capi3-6.0 {
   657    669     sqlite3 db test.db
   658    670     set DB [sqlite3_connection_pointer db]

Changes to test/colname.test.

   389    389     DROP TABLE IF EXISTS t2;
   390    390     CREATE TABLE t1(aaa INT);
   391    391     INSERT INTO t1(aaa) VALUES(123);
   392    392   }
   393    393   do_test colname-9.310 {
   394    394     execsql2 {SELECT BBb FROM (SELECT aaa AS Bbb FROM t1)}
   395    395   } {Bbb 123}
   396         -do_execsql_test colname-9.320 {
   397         -  CREATE TABLE t2 AS SELECT BBb FROM (SELECT aaa AS Bbb FROM t1);
   398         -  SELECT name FROM pragma_table_info('t2');
   399         -} {Bbb}
          396  +ifcapable vtab {
          397  +  do_execsql_test colname-9.320 {
          398  +    CREATE TABLE t2 AS SELECT BBb FROM (SELECT aaa AS Bbb FROM t1);
          399  +    SELECT name FROM pragma_table_info('t2');
          400  +  } {Bbb}
          401  +}
   400    402   
   401    403   # Issue detected by OSSFuzz on 2017-12-24 (Christmas Eve)
   402    404   # caused by check-in https://sqlite.org/src/info/6b2ff26c25
   403    405   #
   404    406   # Prior to being fixed, the following CREATE TABLE was dereferencing
   405    407   # a NULL pointer and segfaulting.
   406    408   #

Changes to test/crash8.test.

   138    138   # Also test that SQLite will not rollback a hot-journal file with a
   139    139   # suspect page-size. In this case "suspect" means:
   140    140   # 
   141    141   #    a) Not a power of 2, or
   142    142   #    b) Less than 512, or
   143    143   #    c) Greater than SQLITE_MAX_PAGE_SIZE
   144    144   #
          145  +if {[atomic_batch_write test.db]==0} {
   145    146   do_test crash8-3.1 {
   146    147     list [file exists test.db-joural] [file exists test.db]
   147    148   } {0 1}
   148    149   do_test crash8-3.2 {
   149    150     execsql {
   150    151       PRAGMA synchronous = off;
   151    152       BEGIN;
................................................................................
   224    225     puts -nonewline $fd $zJournal
   225    226     close $fd
   226    227     execsql { 
   227    228       SELECT count(*) FROM t1;
   228    229       PRAGMA integrity_check
   229    230     }
   230    231   } {6 ok}
          232  +}
   231    233   
   232    234   
   233    235   # If a connection running in persistent-journal mode is part of a 
   234    236   # multi-file transaction, it must ensure that the master-journal name
   235    237   # appended to the journal file contents during the commit is located
   236    238   # at the end of the physical journal file. If there was already a
   237    239   # large journal file allocated at the start of the transaction, this
................................................................................
   262    264         PRAGMA aux.journal_mode = persist;
   263    265         CREATE TABLE aux.ab(a, b);
   264    266         INSERT INTO aux.ab SELECT * FROM main.ab;
   265    267   
   266    268         UPDATE aux.ab SET b = randstr(1000,1000) WHERE a>=1;
   267    269         UPDATE ab SET b = randstr(1000,1000) WHERE a>=1;
   268    270       }
   269         -    list [file exists test.db-journal] [file exists test2.db-journal]
   270         -  } {1 1}
          271  +  } {persist persist}
          272  +  if {[atomic_batch_write test.db]==0} {
          273  +    do_test crash8.4.1.1 {
          274  +      list [file exists test.db-journal] [file exists test2.db-journal]
          275  +    } {1 1}
          276  +  }
   271    277   
   272    278     do_test crash8-4.2 {
   273    279       execsql {
   274    280         BEGIN;
   275    281           UPDATE aux.ab SET b = 'def' WHERE a = 0;
   276    282           UPDATE main.ab SET b = 'def' WHERE a = 0;
   277    283         COMMIT;

Changes to test/delete_db.test.

    12     12   # focus of this file is testing the code in test_delete.c (the
    13     13   # sqlite3_delete_database() API).
    14     14   #
    15     15   
    16     16   set testdir [file dirname $argv0]
    17     17   source $testdir/tester.tcl
    18     18   set testprefix delete_db
           19  +
           20  +if {[atomic_batch_write test.db]} {
           21  +  finish_test
           22  +  return
           23  +}
    19     24   
    20     25   proc delete_all {} {
    21     26     foreach f [glob -nocomplain test2*] { file delete $f }
    22     27     foreach f [glob -nocomplain test3*] { file delete $f }
    23     28   }
    24     29   
    25     30   proc copydb {} {

Changes to test/exclusive.test.

   248    248   # truncates instead of deletes the journal file when committing 
   249    249   # a transaction.
   250    250   #
   251    251   # These tests are not run on windows because the windows backend
   252    252   # opens the journal file for exclusive access, preventing its contents 
   253    253   # from being inspected externally.
   254    254   #
   255         -if {$tcl_platform(platform) != "windows"} {
          255  +if {$tcl_platform(platform) != "windows"
          256  + && [atomic_batch_write test.db]==0
          257  +} {
   256    258   
   257    259     # Return a list of two booleans (either 0 or 1). The first is true
   258    260     # if the named file exists. The second is true only if the file
   259    261     # exists and the first 28 bytes contain at least one non-zero byte.
   260    262     #
   261    263     proc filestate {fname} {
   262    264       set exists 0
................................................................................
   387    389     }
   388    390   } {normal}
   389    391   
   390    392   #----------------------------------------------------------------------
   391    393   # Tests exclusive-5.X - test that statement journals are truncated
   392    394   # instead of deleted when in exclusive access mode.
   393    395   #
          396  +if {[atomic_batch_write test.db]==0} {
   394    397   
   395    398   # Close and reopen the database so that the temp database is no
   396    399   # longer active.
   397    400   #
   398    401   db close
   399    402   sqlite3 db test.db
   400    403   
................................................................................
   503    506     sqlite3 db test.db
   504    507   } {}
   505    508   
   506    509   do_execsql_test exclusive-6.5 {
   507    510     PRAGMA locking_mode = EXCLUSIVE;
   508    511     SELECT * FROM sqlite_master;
   509    512   } {exclusive}
          513  +
          514  +} ;# atomic_batch_write==0
   510    515   
   511    516   finish_test

Changes to test/fallocate.test.

    57     57   # causes a database file to grow, the database grows to its previous size
    58     58   # on disk, not to the minimum size required to hold the database image.
    59     59   #
    60     60   do_test fallocate-1.7 {
    61     61     execsql { BEGIN; INSERT INTO t1 VALUES(1, 2); }
    62     62     if {[permutation] != "inmemory_journal"
    63     63      && [permutation] != "atomic-batch-write"
           64  +   && [atomic_batch_write test.db]==0
    64     65     } {
    65     66       hexio_get_int [hexio_read test.db-journal 16 4]
    66     67     } else {
    67     68       set {} 1024
    68     69     }
    69     70   } {1024}
    70     71   do_test fallocate-1.8 { execsql { COMMIT } } {}

Changes to test/fkey1.test.

   170    170   do_catchsql_test fkey1-5.2 {
   171    171     INSERT OR REPLACE INTO t11 VALUES (2, 3);
   172    172   } {1 {FOREIGN KEY constraint failed}}
   173    173   
   174    174   # Make sure sqlite3_trace() output works with triggers used to implement
   175    175   # FK constraints
   176    176   #
   177         -proc sqltrace {txt} {
   178         -  global traceoutput
   179         -  lappend traceoutput $txt
          177  +ifcapable trace {
          178  +  proc sqltrace {txt} {
          179  +    global traceoutput
          180  +    lappend traceoutput $txt
          181  +  }
          182  +  do_test fkey1-5.2.1 {
          183  +    unset -nocomplain traceoutput
          184  +    db trace sqltrace
          185  +    catch {db eval {INSERT OR REPLACE INTO t11 VALUES(2,3);}}
          186  +    set traceoutput
          187  +  } {{INSERT OR REPLACE INTO t11 VALUES(2,3);} {INSERT OR REPLACE INTO t11 VALUES(2,3);} {INSERT OR REPLACE INTO t11 VALUES(2,3);}}
   180    188   }
   181         -do_test fkey1-5.2.1 {
   182         -  unset -nocomplain traceoutput
   183         -  db trace sqltrace
   184         -  catch {db eval {INSERT OR REPLACE INTO t11 VALUES(2,3);}}
   185         -  set traceoutput
   186         -} {{INSERT OR REPLACE INTO t11 VALUES(2,3);} {INSERT OR REPLACE INTO t11 VALUES(2,3);} {INSERT OR REPLACE INTO t11 VALUES(2,3);}}
   187    189   
   188    190   # A similar test to the above.
   189    191   do_execsql_test fkey1-5.3 {
   190    192     CREATE TABLE Foo (
   191    193       Id INTEGER PRIMARY KEY, 
   192    194       ParentId INTEGER REFERENCES Foo(Id) ON DELETE CASCADE, C1
   193    195     );

Changes to test/fts3rank.test.

    10     10   #*************************************************************************
    11     11   # This file implements regression tests for SQLite library.  The
    12     12   # focus of this script is testing the FTS3 module.
    13     13   #
    14     14   
    15     15   set testdir [file dirname $argv0]
    16     16   source $testdir/tester.tcl
    17         -set testprefix fts3expr5
           17  +set testprefix fts3rank
    18     18   
    19     19   # If SQLITE_ENABLE_FTS3 is defined, omit this file.
    20     20   ifcapable !fts3 {
    21     21     finish_test
    22     22     return
    23     23   }
    24     24   
................................................................................
    52     52     SELECT * FROM t1 ORDER BY rank(matchinfo(t1), 1.0, 1.0) DESC, rowid
    53     53   } {1 {invalid matchinfo blob passed to function rank()}}
    54     54   
    55     55   do_catchsql_test 1.4 {
    56     56     SELECT * FROM t1 ORDER BY rank(x'0000000000000000') DESC, rowid
    57     57   } {0 {{one two} one {one two} three {one two} two}}
    58     58   
    59         -do_catchsql_test 1.5 {
    60         -  SELECT * FROM t1 ORDER BY rank(x'0100000001000000') DESC, rowid
    61         -} {1 {invalid matchinfo blob passed to function rank()}}
           59  +if {$tcl_platform(byteOrder)=="littleEndian"} {
           60  +  do_catchsql_test 1.5le {
           61  +    SELECT * FROM t1 ORDER BY rank(x'0100000001000000') DESC, rowid
           62  +  } {1 {invalid matchinfo blob passed to function rank()}}
           63  +} else {
           64  +  do_catchsql_test 1.5be {
           65  +    SELECT * FROM t1 ORDER BY rank(x'0000000100000001') DESC, rowid
           66  +  } {1 {invalid matchinfo blob passed to function rank()}}
           67  +}
    62     68   
    63     69   finish_test
    64         -

Changes to test/func6.test.

     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   #
    12         -# Test cases for the sqlite_unsupported_offset() function.
           12  +# Test cases for the sqlite_offset() function.
    13     13   #
    14     14   # Some of the tests in this file depend on the exact placement of content
    15     15   # within b-tree pages.  Such placement is at the implementations discretion,
    16     16   # and so it is possible for results to change from one release to the next.
    17     17   #
    18     18   set testdir [file dirname $argv0]
    19     19   source $testdir/tester.tcl
................................................................................
    30     30      INSERT INTO t1(a,b,c,d) SELECT printf('abc%03x',x), x, 1000-x, NULL FROM c;
    31     31     CREATE INDEX t1a ON t1(a);
    32     32     CREATE INDEX t1bc ON t1(b,c);
    33     33     CREATE TABLE t2(x TEXT PRIMARY KEY, y) WITHOUT ROWID;
    34     34     INSERT INTO t2(x,y) SELECT a, b FROM t1;
    35     35   }
    36     36   do_execsql_test func6-110 {
    37         -  SELECT a, sqlite_unsupported_offset(d)/4096 + 1,
    38         -            sqlite_unsupported_offset(d)%4096 FROM t1
           37  +  SELECT a, sqlite_offset(d)/4096 + 1,
           38  +            sqlite_offset(d)%4096 FROM t1
    39     39      ORDER BY rowid LIMIT 2;
    40     40   } {abc001 2 4084 abc002 2 4069}
    41     41   do_execsql_test func6-120 {
    42         -  SELECT a, typeof(sqlite_unsupported_offset(+a)) FROM t1
           42  +  SELECT a, typeof(sqlite_offset(+a)) FROM t1
    43     43      ORDER BY rowid LIMIT 2;
    44     44   } {abc001 null abc002 null}
    45     45   do_execsql_test func6-130 {
    46         -  SELECT a, sqlite_unsupported_offset(a)/4096+1, 
    47         -         sqlite_unsupported_offset(a)%4096
           46  +  SELECT a, sqlite_offset(a)/4096+1, 
           47  +         sqlite_offset(a)%4096
    48     48      FROM t1
    49     49      ORDER BY a LIMIT 2;
    50     50   } {abc001 3 4087 abc002 3 4076}
    51     51   do_execsql_test func6-140 {
    52         -  SELECT a, sqlite_unsupported_offset(d)/4096+1, 
    53         -         sqlite_unsupported_offset(d)%4096
           52  +  SELECT a, sqlite_offset(d)/4096+1, 
           53  +         sqlite_offset(d)%4096
    54     54      FROM t1
    55     55      ORDER BY a LIMIT 2;
    56     56   } {abc001 2 4084 abc002 2 4069}
    57     57   do_execsql_test func6-150 {
    58     58     SELECT a,
    59         -         sqlite_unsupported_offset(a)/4096+1, 
    60         -         sqlite_unsupported_offset(a)%4096,
    61         -         sqlite_unsupported_offset(d)/4096+1, 
    62         -         sqlite_unsupported_offset(d)%4096
           59  +         sqlite_offset(a)/4096+1, 
           60  +         sqlite_offset(a)%4096,
           61  +         sqlite_offset(d)/4096+1, 
           62  +         sqlite_offset(d)%4096
    63     63      FROM t1
    64     64      ORDER BY a LIMIT 2;
    65     65   } {abc001 3 4087 2 4084 abc002 3 4076 2 4069}
    66     66   do_execsql_test func6-160 {
    67     67     SELECT b,
    68         -         sqlite_unsupported_offset(b)/4096+1, 
    69         -         sqlite_unsupported_offset(b)%4096,
    70         -         sqlite_unsupported_offset(c)/4096+1, 
    71         -         sqlite_unsupported_offset(c)%4096,
    72         -         sqlite_unsupported_offset(d)/4096+1, 
    73         -         sqlite_unsupported_offset(d)%4096
           68  +         sqlite_offset(b)/4096+1, 
           69  +         sqlite_offset(b)%4096,
           70  +         sqlite_offset(c)/4096+1, 
           71  +         sqlite_offset(c)%4096,
           72  +         sqlite_offset(d)/4096+1, 
           73  +         sqlite_offset(d)%4096
    74     74      FROM t1
    75     75      ORDER BY b LIMIT 2;
    76     76   } {1 4 4090 4 4090 2 4084 2 4 4081 4 4081 2 4069}
    77     77   
    78     78   
    79     79   do_execsql_test func6-200 {
    80         -  SELECT y, sqlite_unsupported_offset(y)/4096+1,
    81         -         sqlite_unsupported_offset(y)%4096
           80  +  SELECT y, sqlite_offset(y)/4096+1,
           81  +         sqlite_offset(y)%4096
    82     82      FROM t2
    83     83      ORDER BY x LIMIT 2;
    84     84   } {1 5 4087 2 5 4076}
    85     85   
    86     86   finish_test

Changes to test/hook.test.

   901    901   } {
   902    902     INSERT main t3 1 1 0 {} 1
   903    903   }
   904    904   do_execsql_test 10.2 { SELECT * FROM t3 } {{} 1}
   905    905   do_preupdate_test 10.3 {
   906    906     DELETE FROM t3 WHERE b=1
   907    907   } {DELETE main t3 1 1 0 {} 1}
          908  +
          909  +#-------------------------------------------------------------------------
          910  +# Test that the "update" hook is not fired for operations on the 
          911  +# sqlite_stat1 table performed by ANALYZE, even if a pre-update hook is
          912  +# registered.
          913  +ifcapable analyze {
          914  +  reset_db
          915  +  do_execsql_test 11.1 {
          916  +    CREATE TABLE t1(a, b);
          917  +    CREATE INDEX idx1 ON t1(a);
          918  +    CREATE INDEX idx2 ON t1(b);
          919  +
          920  +    INSERT INTO t1 VALUES(1, 2);
          921  +    INSERT INTO t1 VALUES(3, 4);
          922  +    INSERT INTO t1 VALUES(5, 6);
          923  +    INSERT INTO t1 VALUES(7, 8);
          924  +  }
          925  +
          926  +  db preupdate hook preupdate_cb
          927  +  db update_hook update_cb
          928  +
          929  +  proc preupdate_cb {args} { lappend ::res "preupdate" $args }
          930  +  proc update_cb {args} { lappend ::res "update" $args }
          931  +
          932  +  set ::res [list]
          933  +  do_test 11.2 {
          934  +    execsql ANALYZE
          935  +    set ::res
          936  +  } [list {*}{
          937  +    preupdate {INSERT main sqlite_stat1 1 1}
          938  +    preupdate {INSERT main sqlite_stat1 2 2}
          939  +  }]
          940  +
          941  +  do_execsql_test 11.3 {
          942  +    INSERT INTO t1 VALUES(9, 10);
          943  +    INSERT INTO t1 VALUES(11, 12);
          944  +    INSERT INTO t1 VALUES(13, 14);
          945  +    INSERT INTO t1 VALUES(15, 16);
          946  +  }
          947  +
          948  +  set ::res [list]
          949  +  do_test 11.4 {
          950  +    execsql ANALYZE
          951  +    set ::res
          952  +  } [list {*}{
          953  +    preupdate {DELETE main sqlite_stat1 1 1}
          954  +    preupdate {DELETE main sqlite_stat1 2 2}
          955  +    preupdate {INSERT main sqlite_stat1 1 1}
          956  +    preupdate {INSERT main sqlite_stat1 2 2}
          957  +  }]
          958  +}
   908    959   
   909    960   
   910    961   finish_test

Changes to test/icu.test.

   134    134     } {1 {wrong number of arguments to function regexp()}}
   135    135     do_catchsql_test icu-5.3 { 
   136    136       SELECT regexp('a[abc]c.*', 'abc', 'c') 
   137    137     } {1 {wrong number of arguments to function regexp()}}
   138    138     do_catchsql_test icu-5.4 { 
   139    139       SELECT 'abc' REGEXP 'a[abc]c.*'
   140    140     } {0 1}
   141         -  do_catchsql_test icu-5.4 {SELECT 'abc' REGEXP }   {1 {near " ": syntax error}}
   142         -  do_catchsql_test icu-5.5 {SELECT 'abc' REGEXP, 1} {1 {near ",": syntax error}}
          141  +  do_catchsql_test icu-5.5 {SELECT 'abc' REGEXP }   {1 {incomplete input}}
          142  +  do_catchsql_test icu-5.6 {SELECT 'abc' REGEXP, 1} {1 {near ",": syntax error}}
   143    143    
   144    144     do_malloc_test icu-6.10 -sqlbody {
   145    145       SELECT upper(char(0xfb04,0xdf,0xfb04,0xe8,0xfb04));
   146    146     }
   147    147   }
   148    148   
   149    149   finish_test

Changes to test/indexexpr1.test.

   408    408   do_execsql_test indexexpr1-1500 {
   409    409     CREATE TABLE t1500(a INT PRIMARY KEY, b INT UNIQUE);
   410    410     CREATE INDEX t1500ab ON t1500(a*b);
   411    411     INSERT INTO t1500(a,b) VALUES(1,2);
   412    412     REPLACE INTO t1500(a,b) VALUES(1,3);  -- formerly caused assertion fault
   413    413     SELECT * FROM t1500;
   414    414   } {1 3}
          415  +
          416  +# 2018-01-03 OSSFuzz discovers another test case for the same problem
          417  +# above.
          418  +#
          419  +do_execsql_test indexexpr-1510 {
          420  +  DROP TABLE IF EXISTS t1;
          421  +  CREATE TABLE t1(a PRIMARY KEY,b UNIQUE);
          422  +  REPLACE INTO t1 VALUES(2, 1);
          423  +  REPLACE INTO t1 SELECT 6,1;
          424  +  CREATE INDEX t1aa ON t1(a-a);
          425  +  REPLACE INTO t1 SELECT a, randomblob(a) FROM t1
          426  +} {}
   415    427   
   416    428   finish_test

Changes to test/ioerr.test.

   168    168   
   169    169   # Test handling of IO errors that occur while rolling back hot journal
   170    170   # files.
   171    171   #
   172    172   # These tests can't be run on windows because the windows version of 
   173    173   # SQLite holds a mandatory exclusive lock on journal files it has open.
   174    174   #
   175         -if {$tcl_platform(platform)!="windows"} {
          175  +if {$tcl_platform(platform)!="windows" && ![atomic_batch_write test.db]} {
   176    176     do_ioerr_test ioerr-7 -tclprep {
   177    177       db close
   178    178       sqlite3 db2 test2.db
   179    179       db2 eval {
   180    180         PRAGMA synchronous = 0;
   181    181         CREATE TABLE t1(a, b);
   182    182         INSERT INTO t1 VALUES(1, 2);
................................................................................
   207    207     sqlite3 db test.db
   208    208   } -sqlbody {
   209    209     SELECT c FROM t1;
   210    210   }
   211    211   
   212    212   # For test coverage: Cause an IO error whilst reading the master-journal
   213    213   # name from a journal file.
   214         -if {$tcl_platform(platform)=="unix"} {
          214  +if {$tcl_platform(platform)=="unix" && [atomic_batch_write test.db]==0} {
   215    215     do_ioerr_test ioerr-9 -ckrefcount true -tclprep {
   216    216       execsql {
   217    217         CREATE TABLE t1(a,b,c);
   218    218         INSERT INTO t1 VALUES(randstr(200,200), randstr(1000,1000), 2);
   219    219         BEGIN;
   220    220         INSERT INTO t1 VALUES(randstr(200,200), randstr(1000,1000), 2);
   221    221       }

Changes to test/journal1.test.

    18     18   
    19     19   set testdir [file dirname $argv0]
    20     20   source $testdir/tester.tcl
    21     21   
    22     22   # These tests will not work on windows because windows uses
    23     23   # manditory file locking which breaks the copy_file command.
    24     24   #
    25         -if {$tcl_platform(platform)=="windows"} {
           25  +# Or with atomic_batch_write systems, as journal files are
           26  +# not created.
           27  +#
           28  +if {$tcl_platform(platform)=="windows"
           29  + || [atomic_batch_write test.db]
           30  +} {
    26     31     finish_test
    27     32     return
    28     33   }
    29     34   
    30     35   # Create a smaple database
    31     36   #
    32     37   do_test journal1-1.1 {

Changes to test/journal3.test.

    16     16   source $testdir/lock_common.tcl
    17     17   source $testdir/malloc_common.tcl
    18     18   
    19     19   #-------------------------------------------------------------------------
    20     20   # If a connection is required to create a journal file, it creates it with 
    21     21   # the same file-system permissions as the database file itself. Test this.
    22     22   #
    23         -if {$::tcl_platform(platform) == "unix"} {
           23  +if {$::tcl_platform(platform) == "unix"
           24  + && [atomic_batch_write test.db]==0
           25  +} {
    24     26   
    25     27     # Changed on 2012-02-13:  umask is deliberately ignored for -wal, -journal,
    26     28     # and -shm files.
    27     29     #set umask [exec /bin/sh -c umask]
    28     30     faultsim_delete_and_reopen
    29     31     do_test journal3-1.1 { execsql { CREATE TABLE tx(y, z) } } {}
    30     32   

Changes to test/jrnlmode.test.

   298    298     integrity_check jrnlmode-4.5
   299    299   }
   300    300   
   301    301   #------------------------------------------------------------------------
   302    302   # The following test caes, jrnlmode-5.*, test the journal_size_limit
   303    303   # pragma.
   304    304   ifcapable pragma {
          305  +if {[atomic_batch_write test.db]==0} {
   305    306     db close
   306    307     forcedelete test.db test2.db test3.db
   307    308     sqlite3 db test.db
   308    309   
   309    310     do_test jrnlmode-5.1 {
   310    311       execsql {pragma page_size=1024}
   311    312       execsql {pragma journal_mode=persist}
................................................................................
   450    451       expr {[file size test.db-journal] > 1024}
   451    452     } {1}
   452    453     do_test jrnlmode-5.22 {
   453    454       execsql COMMIT
   454    455       list [file exists test.db-journal] [file size test.db-journal]
   455    456     } {1 0}
   456    457   }
          458  +}
   457    459   
   458    460   ifcapable pragma {
          461  +if {[atomic_batch_write test.db]==0} {
   459    462     # These tests are not run as part of the "journaltest" permutation,
   460    463     # as the test_journal.c layer is incompatible with in-memory journaling.
   461    464     if {[permutation] ne "journaltest"} {
   462    465   
   463    466       do_test jrnlmode-6.1 {
   464    467         execsql {
   465    468           PRAGMA journal_mode = truncate;
................................................................................
   502    505         execsql {
   503    506           PRAGMA journal_mode = DELETE;
   504    507           BEGIN IMMEDIATE; INSERT INTO t4 VALUES(1,2); COMMIT;
   505    508         }
   506    509         file exists test.db-journal
   507    510       } {0}
   508    511     }
          512  +}
   509    513   }
   510    514   
   511    515   ifcapable pragma {
   512    516     catch { db close }
   513    517     do_test jrnlmode-7.1 {
   514    518       foreach f [glob -nocomplain test.db*] { forcedelete $f }
   515    519       sqlite3 db test.db

Changes to test/jrnlmode2.test.

    13     13   set testdir [file dirname $argv0]
    14     14   source $testdir/tester.tcl
    15     15   
    16     16   ifcapable {!pager_pragmas} {
    17     17     finish_test
    18     18     return
    19     19   }
           20  +
           21  +if {[atomic_batch_write test.db]} {
           22  +  finish_test
           23  +  return
           24  +}
    20     25   
    21     26   #-------------------------------------------------------------------------
    22     27   # The tests in this file check that the following two bugs (both now fixed)
    23     28   # do not reappear.
    24     29   #
    25     30   # jrnlmode2-1.*: Demonstrate bug #3745:
    26     31   #

Changes to test/lock4.test.

    12     12   # focus of this script is database locks.
    13     13   #
    14     14   # $Id: lock4.test,v 1.10 2009/05/06 00:52:41 drh Exp $
    15     15   
    16     16   
    17     17   set testdir [file dirname $argv0]
    18     18   source $testdir/tester.tcl
           19  +
           20  +if {[atomic_batch_write test.db]} {
           21  +  # This test uses two processes, one of which blocks until the other
           22  +  # creates a *-journal file. Which doesn't work if atomic writes are
           23  +