/ Check-in [1cd536ec]
Login

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

Overview
Comment:Merge all recent enhancements.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | begin-concurrent-pnu-wal2
Files: files | file ages | folders
SHA3-256: 1cd536ecc8f21898475d4641fd67da15a8007af78d59a1f418143b348aceeaad
User & Date: drh 2019-04-15 15:28:58
Wiki:begin-concurrent-pnu-wal2
Context
2019-05-14
22:07
Merge the latest trunk and wal2 enhancements. check-in: 3deaa6e2 user: drh tags: begin-concurrent-pnu-wal2
2019-04-15
15:28
Merge all recent enhancements. check-in: 1cd536ec user: drh tags: begin-concurrent-pnu-wal2
15:17
Merge the latest trunk enhancements. check-in: 8950f119 user: drh tags: wal2
2019-03-26
12:29
Bring this branch up to date with all the latest enhancements. check-in: 2e964aaf user: drh tags: begin-concurrent-pnu-wal2
Changes
Hide Diffs Side-by-Side Diffs Show Whitespace Changes Patch

Changes to Makefile.in.

   418    418     $(TOP)/src/test_schema.c \
   419    419     $(TOP)/src/test_server.c \
   420    420     $(TOP)/src/test_superlock.c \
   421    421     $(TOP)/src/test_syscall.c \
   422    422     $(TOP)/src/test_tclsh.c \
   423    423     $(TOP)/src/test_tclvar.c \
   424    424     $(TOP)/src/test_thread.c \
          425  +  $(TOP)/src/test_vdbecov.c \
   425    426     $(TOP)/src/test_vfs.c \
   426    427     $(TOP)/src/test_windirent.c \
   427    428     $(TOP)/src/test_window.c \
   428    429     $(TOP)/src/test_wsd.c       \
   429    430     $(TOP)/ext/fts3/fts3_term.c \
   430    431     $(TOP)/ext/fts3/fts3_test.c  \
   431    432     $(TOP)/ext/session/test_session.c \
................................................................................
  1047   1048   opcodes.h:	parse.h $(TOP)/src/vdbe.c $(TOP)/tool/mkopcodeh.tcl
  1048   1049   	cat parse.h $(TOP)/src/vdbe.c | $(TCLSH_CMD) $(TOP)/tool/mkopcodeh.tcl >opcodes.h
  1049   1050   
  1050   1051   # Rules to build parse.c and parse.h - the outputs of lemon.
  1051   1052   #
  1052   1053   parse.h:	parse.c
  1053   1054   
  1054         -parse.c:	$(TOP)/src/parse.y lemon$(BEXE) $(TOP)/tool/addopcodes.tcl
         1055  +parse.c:	$(TOP)/src/parse.y lemon$(BEXE)
  1055   1056   	cp $(TOP)/src/parse.y .
  1056         -	rm -f parse.h
  1057   1057   	./lemon$(BEXE) $(OPT_FEATURE_FLAGS) $(OPTS) parse.y
  1058         -	mv parse.h parse.h.temp
  1059         -	$(TCLSH_CMD) $(TOP)/tool/addopcodes.tcl parse.h.temp >parse.h
  1060   1058   
  1061   1059   sqlite3.h:	$(TOP)/src/sqlite.h.in $(TOP)/manifest mksourceid$(BEXE) $(TOP)/VERSION
  1062   1060   	$(TCLSH_CMD) $(TOP)/tool/mksqlite3h.tcl $(TOP) >sqlite3.h
  1063   1061   
  1064   1062   keywordhash.h:	$(TOP)/tool/mkkeywordhash.c
  1065   1063   	$(BCC) -o mkkeywordhash$(BEXE) $(OPT_FEATURE_FLAGS) $(OPTS) $(TOP)/tool/mkkeywordhash.c
  1066   1064   	./mkkeywordhash$(BEXE) >keywordhash.h
................................................................................
  1371   1369   	$(LTLINK) $(TOP)/tool/loadfts.c libsqlite3.la -o $@ $(TLIBS)
  1372   1370   
  1373   1371   # This target will fail if the SQLite amalgamation contains any exported
  1374   1372   # symbols that do not begin with "sqlite3_". It is run as part of the
  1375   1373   # releasetest.tcl script.
  1376   1374   #
  1377   1375   VALIDIDS=' sqlite3(changeset|changegroup|session)?_'
  1378         -checksymbols: sqlite3.lo
  1379         -	nm -g --defined-only sqlite3.lo | egrep -v $(VALIDIDS); test $$? -ne 0
         1376  +checksymbols: sqlite3.o
         1377  +	nm -g --defined-only sqlite3.o
         1378  +	nm -g --defined-only sqlite3.o | egrep -v $(VALIDIDS); test $$? -ne 0
  1380   1379   	echo '0 errors out of 1 tests'
  1381   1380   
  1382   1381   # Build the amalgamation-autoconf package.  The amalamgation-tarball target builds
  1383   1382   # a tarball named for the version number.  Ex:  sqlite-autoconf-3110000.tar.gz.
  1384   1383   # The snapshot-tarball target builds a tarball named by the SHA1 hash
  1385   1384   #
  1386   1385   amalgamation-tarball: sqlite3.c

Changes to Makefile.msc.

   315    315   !IFNDEF SQLITETCLH
   316    316   SQLITETCLH = sqlite_tcl.h
   317    317   !ENDIF
   318    318   
   319    319   !IFNDEF SQLITETCLDECLSH
   320    320   SQLITETCLDECLSH = sqlite_tclDecls.h
   321    321   !ENDIF
          322  +
          323  +# This is the name to use for the dynamic link library (DLL) containing the
          324  +# Tcl bindings for SQLite.
          325  +#
          326  +!IFNDEF SQLITE3TCLDLL
          327  +SQLITE3TCLDLL = tclsqlite3.dll
          328  +!ENDIF
   322    329   
   323    330   # These are the additional targets that the targets that integrate with the
   324    331   # Tcl library should depend on when compiling, etc.
   325    332   #
   326    333   !IFNDEF SQLITE_TCL_DEP
   327    334   !IF $(USE_STDCALL)!=0 || $(FOR_WIN10)!=0
   328    335   SQLITE_TCL_DEP = $(SQLITETCLDECLSH) $(SQLITETCLH)
................................................................................
   491    498   
   492    499   UCRTLIBPATH = $(UCRTLIBPATH:\\=\)
   493    500   
   494    501   # C compiler and options for use in building executables that
   495    502   # will run on the platform that is doing the build.
   496    503   #
   497    504   !IF $(USE_FULLWARN)!=0
   498         -BCC = $(NCC) -nologo -W4 $(CCOPTS) $(BCCOPTS)
          505  +BCC = $(NCC) -nologo -W4 -Fd$*.pdb $(CCOPTS) $(BCCOPTS)
   499    506   !ELSE
   500         -BCC = $(NCC) -nologo -W3 $(CCOPTS) $(BCCOPTS)
          507  +BCC = $(NCC) -nologo -W3 -Fd$*.pdb $(CCOPTS) $(BCCOPTS)
   501    508   !ENDIF
   502    509   
   503    510   # Check if assembly code listings should be generated for the source
   504    511   # code files to be compiled.
   505    512   #
   506    513   !IF $(USE_LISTINGS)!=0
   507    514   BCC = $(BCC) -FAcs
................................................................................
   849    856   # <<mark>>
   850    857   # The locations of the Tcl header and library files.  Also, the library that
   851    858   # non-stubs enabled programs using Tcl must link against.  These variables
   852    859   # (TCLINCDIR, TCLLIBDIR, and LIBTCL) may be overridden via the environment
   853    860   # prior to running nmake in order to match the actual installed location and
   854    861   # version on this machine.
   855    862   #
          863  +!IFNDEF TCLVERSION
          864  +TCLVERSION = 86
          865  +!ENDIF
          866  +
          867  +!IFNDEF TCLSUFFIX
          868  +TCLSUFFIX =
          869  +!ENDIF
          870  +
   856    871   !IFNDEF TCLDIR
   857    872   TCLDIR = $(TOP)\compat\tcl
   858    873   !ENDIF
   859    874   
   860    875   !IFNDEF TCLINCDIR
   861    876   TCLINCDIR = $(TCLDIR)\include
   862    877   !ENDIF
   863    878   
   864    879   !IFNDEF TCLLIBDIR
   865    880   TCLLIBDIR = $(TCLDIR)\lib
   866    881   !ENDIF
   867    882   
   868    883   !IFNDEF LIBTCL
   869         -LIBTCL = tcl86.lib
          884  +LIBTCL = tcl$(TCLVERSION)$(TCLSUFFIX).lib
   870    885   !ENDIF
   871    886   
   872    887   !IFNDEF LIBTCLSTUB
   873         -LIBTCLSTUB = tclstub86.lib
          888  +LIBTCLSTUB = tclstub$(TCLVERSION)$(TCLSUFFIX).lib
   874    889   !ENDIF
   875    890   
   876    891   !IFNDEF LIBTCLPATH
   877    892   LIBTCLPATH = $(TCLDIR)\bin
   878    893   !ENDIF
   879    894   
   880    895   # The locations of the zlib header and library files.  These variables
................................................................................
  1059   1074   RCC = $(RCC) -I$(ICUINCDIR)
  1060   1075   !ENDIF
  1061   1076   # <</mark>>
  1062   1077   
  1063   1078   # Command line prefixes for compiling code, compiling resources,
  1064   1079   # linking, etc.
  1065   1080   #
  1066         -LTCOMPILE = $(TCC) -Fo$@
         1081  +LTCOMPILE = $(TCC) -Fo$@ -Fd$*.pdb
  1067   1082   LTRCOMPILE = $(RCC) -r
  1068   1083   LTLIB = lib.exe
  1069   1084   LTLINK = $(TCC) -Fe$@
  1070   1085   
  1071   1086   # If requested, link to the RPCRT4 library.
  1072   1087   #
  1073   1088   !IF $(USE_RPCRT4_LIB)!=0
................................................................................
  1077   1092   # If a platform was set, force the linker to target that.
  1078   1093   # Note that the vcvars*.bat family of batch files typically
  1079   1094   # set this for you.  Otherwise, the linker will attempt
  1080   1095   # to deduce the binary type based on the object files.
  1081   1096   !IFDEF PLATFORM
  1082   1097   LTLINKOPTS = /NOLOGO /MACHINE:$(PLATFORM)
  1083   1098   LTLIBOPTS = /NOLOGO /MACHINE:$(PLATFORM)
         1099  +!ELSEIF "$(VISUALSTUDIOVERSION)"=="12.0" || \
         1100  +        "$(VISUALSTUDIOVERSION)"=="14.0" || \
         1101  +        "$(VISUALSTUDIOVERSION)"=="15.0"
         1102  +LTLINKOPTS = /NOLOGO /MACHINE:x86
         1103  +LTLIBOPTS = /NOLOGO /MACHINE:x86
  1084   1104   !ELSE
  1085   1105   LTLINKOPTS = /NOLOGO
  1086   1106   LTLIBOPTS = /NOLOGO
  1087   1107   !ENDIF
  1088   1108   
  1089   1109   # When compiling for use in the WinRT environment, the following
  1090   1110   # linker option must be used to mark the executable as runnable
................................................................................
  1493   1513     $(TOP)\src\test_schema.c \
  1494   1514     $(TOP)\src\test_server.c \
  1495   1515     $(TOP)\src\test_superlock.c \
  1496   1516     $(TOP)\src\test_syscall.c \
  1497   1517     $(TOP)\src\test_tclsh.c \
  1498   1518     $(TOP)\src\test_tclvar.c \
  1499   1519     $(TOP)\src\test_thread.c \
         1520  +  $(TOP)\src\test_vdbecov.c \
  1500   1521     $(TOP)\src\test_vfs.c \
  1501   1522     $(TOP)\src\test_windirent.c \
  1502   1523     $(TOP)\src\test_window.c \
  1503   1524     $(TOP)\src\test_wsd.c \
  1504   1525     $(TOP)\ext\fts3\fts3_term.c \
  1505   1526     $(TOP)\ext\fts3\fts3_test.c \
  1506   1527     $(TOP)\ext\rbu\test_rbu.c \
................................................................................
  1662   1683   # Standard options to testfixture.
  1663   1684   #
  1664   1685   TESTOPTS = --verbose=file --output=test-out.txt
  1665   1686   
  1666   1687   # Extra targets for the "all" target that require Tcl.
  1667   1688   #
  1668   1689   !IF $(NO_TCL)==0
  1669         -ALL_TCL_TARGETS = libtclsqlite3.lib
         1690  +ALL_TCL_TARGETS = $(SQLITE3TCLDLL)
  1670   1691   !ELSE
  1671   1692   ALL_TCL_TARGETS =
  1672   1693   !ENDIF
  1673   1694   # <</mark>>
  1674   1695   
  1675   1696   # This is the default Makefile target.  The objects listed here
  1676   1697   # are what get build when you type just "make" with no arguments.
................................................................................
  1694   1715   shell:	$(SQLITE3EXE)
  1695   1716   
  1696   1717   # <<mark>>
  1697   1718   libsqlite3.lib:	$(LIBOBJ)
  1698   1719   	$(LTLIB) $(LTLIBOPTS) /OUT:$@ $(LIBOBJ) $(TLIBS)
  1699   1720   
  1700   1721   libtclsqlite3.lib:	tclsqlite.lo libsqlite3.lib
  1701         -	$(LTLIB) $(LTLIBOPTS) $(LTLIBPATHS) /OUT:$@ tclsqlite.lo libsqlite3.lib $(LIBTCLSTUB) $(TLIBS)
         1722  +	$(LTLIB) $(LTLIBOPTS) $(TCLLIBPATHS) $(LTLIBPATHS) /OUT:$@ tclsqlite.lo libsqlite3.lib $(LIBTCLSTUB) $(TLIBS)
         1723  +
         1724  +tclsqlite3.def:	tclsqlite.lo
         1725  +	echo EXPORTS > tclsqlite3.def
         1726  +	dumpbin /all tclsqlite.lo \
         1727  +		| $(TCLSH_CMD) $(TOP)\tool\replace.tcl include "^\s+/EXPORT:_?((?:Sqlite3|Tclsqlite3)_[^@]*)(?:@\d+)?$$" \1 \
         1728  +		| sort >> tclsqlite3.def
         1729  +
         1730  +pkgIndex.tcl:	$(TOP)\VERSION
         1731  +	for /F %%V in ('type "$(TOP)\VERSION"') do ( \
         1732  +		echo package ifneeded sqlite3 @version@ [list load [file join $$dir $(SQLITE3TCLDLL)] sqlite3] \
         1733  +			| $(TCLSH_CMD) $(TOP)\tool\replace.tcl exact @version@ %%V > pkgIndex.tcl \
         1734  +	)
         1735  +
         1736  +$(SQLITE3TCLDLL):	libtclsqlite3.lib $(LIBRESOBJS) tclsqlite3.def pkgIndex.tcl
         1737  +	$(LD) $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) /DLL /DEF:tclsqlite3.def /OUT:$@ libtclsqlite3.lib $(LIBRESOBJS) $(LTLIBS) $(TLIBS)
  1702   1738   # <</mark>>
  1703   1739   
  1704   1740   $(SQLITE3DLL):	$(LIBOBJ) $(LIBRESOBJS) $(CORE_LINK_DEP)
  1705   1741   	$(LD) $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) /DLL $(CORE_LINK_OPTS) /OUT:$@ $(LIBOBJ) $(LIBRESOBJS) $(LTLIBS) $(TLIBS)
  1706   1742   
  1707   1743   # <<block2>>
  1708   1744   sqlite3.def:	libsqlite3.lib
................................................................................
  1834   1870   	$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c opcodes.c
  1835   1871   # <</mark>>
  1836   1872   
  1837   1873   # Rule to build the Win32 resources object file.
  1838   1874   #
  1839   1875   !IF $(USE_RC)!=0
  1840   1876   # <<block1>>
  1841         -$(LIBRESOBJS):	$(TOP)\src\sqlite3.rc $(SQLITE3H)
         1877  +$(LIBRESOBJS):	$(TOP)\src\sqlite3.rc $(SQLITE3H) $(TOP)\VERSION
  1842   1878   	echo #ifndef SQLITE_RESOURCE_VERSION > sqlite3rc.h
  1843   1879   	for /F %%V in ('type "$(TOP)\VERSION"') do ( \
  1844   1880   		echo #define SQLITE_RESOURCE_VERSION %%V \
  1845   1881   			| $(TCLSH_CMD) $(TOP)\tool\replace.tcl exact . ^, >> sqlite3rc.h \
  1846   1882   	)
  1847   1883   	echo #endif >> sqlite3rc.h
  1848   1884   	$(LTRCOMPILE) -fo $(LIBRESOBJS) $(TOP)\src\sqlite3.rc
................................................................................
  2100   2136   opcodes.h:	parse.h $(TOP)\src\vdbe.c $(TOP)\tool\mkopcodeh.tcl
  2101   2137   	type parse.h $(TOP)\src\vdbe.c | $(TCLSH_CMD) $(TOP)\tool\mkopcodeh.tcl > opcodes.h
  2102   2138   
  2103   2139   # Rules to build parse.c and parse.h - the outputs of lemon.
  2104   2140   #
  2105   2141   parse.h:	parse.c
  2106   2142   
  2107         -parse.c:	$(TOP)\src\parse.y lemon.exe $(TOP)\tool\addopcodes.tcl
         2143  +parse.c:	$(TOP)\src\parse.y lemon.exe
  2108   2144   	del /Q parse.y parse.h parse.h.temp 2>NUL
  2109   2145   	copy $(TOP)\src\parse.y .
  2110   2146   	.\lemon.exe $(REQ_FEATURE_FLAGS) $(OPT_FEATURE_FLAGS) $(EXT_FEATURE_FLAGS) $(OPTS) parse.y
  2111         -	move parse.h parse.h.temp
  2112         -	$(TCLSH_CMD) $(TOP)\tool\addopcodes.tcl parse.h.temp > parse.h
  2113   2147   
  2114   2148   $(SQLITE3H):	$(TOP)\src\sqlite.h.in $(TOP)\manifest mksourceid.exe $(TOP)\VERSION
  2115   2149   	$(TCLSH_CMD) $(TOP)\tool\mksqlite3h.tcl $(TOP:\=/) > $(SQLITE3H) $(MKSQLITE3H_ARGS)
  2116   2150   
  2117   2151   sqlite3ext.h:	.target_source
  2118   2152   !IF $(USE_STDCALL)!=0 || $(FOR_WIN10)!=0
  2119   2153   	type tsrc\sqlite3ext.h | $(TCLSH_CMD) $(TOP)\tool\replace.tcl regsub "\(\*\)" "(SQLITE_CALLBACK *)" \
................................................................................
  2511   2545   # <</mark>>
  2512   2546   
  2513   2547   clean:
  2514   2548   	del /Q *.exp *.lo *.ilk *.lib *.obj *.ncb *.pdb *.sdf *.suo 2>NUL
  2515   2549   	del /Q *.bsc *.def *.cod *.da *.bb *.bbg *.vc gmon.out 2>NUL
  2516   2550   	del /Q $(SQLITE3EXE) $(SQLITE3DLL) Replace.exe 2>NUL
  2517   2551   # <<mark>>
         2552  +	del /Q $(SQLITE3TCLDLL) pkgIndex.tcl 2>NUL
  2518   2553   	del /Q opcodes.c opcodes.h 2>NUL
  2519   2554   	del /Q lemon.* lempar.c parse.* 2>NUL
  2520   2555   	del /Q mksourceid.* mkkeywordhash.* keywordhash.h 2>NUL
  2521   2556   	del /Q notasharedlib.* 2>NUL
  2522   2557   	-rmdir /Q/S .deps 2>NUL
  2523   2558   	-rmdir /Q/S .libs 2>NUL
  2524   2559   	-rmdir /Q/S tsrc 2>NUL
  2525   2560   	del /Q .target_source 2>NUL
  2526   2561   	del /Q tclsqlite3.exe $(SQLITETCLH) $(SQLITETCLDECLSH) 2>NUL
  2527   2562   	del /Q lsm.dll lsmtest.exe 2>NUL
         2563  +	del /Q atrc.exe changesetfuzz.exe dbtotxt.exe index_usage.exe 2>NUL
  2528   2564   	del /Q testloadext.dll 2>NUL
  2529   2565   	del /Q testfixture.exe test.db 2>NUL
  2530   2566   	del /Q LogEst.exe fts3view.exe rollback-test.exe showdb.exe dbdump.exe 2>NUL
  2531   2567   	del /Q changeset.exe 2>NUL
  2532   2568   	del /Q showjournal.exe showstat4.exe showwal.exe speedtest1.exe 2>NUL
  2533   2569   	del /Q mptester.exe wordcount.exe rbu.exe srcck1.exe 2>NUL
  2534   2570   	del /Q sqlite3.c sqlite3-*.c sqlite3.h 2>NUL

Changes to README.md.

    37     37   
    38     38     *  Latest release as
    39     39        [Tarball](https://www.sqlite.org/src/tarball/sqlite.tar.gz?r=release),
    40     40        [ZIP-archive](https://www.sqlite.org/src/zip/sqlite.zip?r=release), or
    41     41        [SQLite-archive](https://www.sqlite.org/src/sqlar/sqlite.sqlar?r=release).
    42     42   
    43     43     *  For other check-ins, substitute an appropriate branch name or
    44         -     tag or hash prefix for "release" in the URLs of the previous
           44  +     tag or hash prefix in place of "release" in the URLs of the previous
    45     45        bullet.  Or browse the [timeline](https://www.sqlite.org/src/timeline)
    46     46        to locate the check-in desired, click on its information page link,
    47     47        then click on the "Tarball" or "ZIP Archive" links on the information
    48     48        page.
    49     49   
    50     50   If you do want to use Fossil to check out the source tree, 
    51     51   first install Fossil version 2.0 or later.
................................................................................
   171    171   used to generate that documentation are in a separate source repository.
   172    172   
   173    173   The SQL language parser is **parse.c** which is generate from a grammar in
   174    174   the src/parse.y file.  The conversion of "parse.y" into "parse.c" is done
   175    175   by the [lemon](./doc/lemon.html) LALR(1) parser generator.  The source code
   176    176   for lemon is at tool/lemon.c.  Lemon uses the tool/lempar.c file as a
   177    177   template for generating its parser.
   178         -
   179    178   Lemon also generates the **parse.h** header file, at the same time it
   180         -generates parse.c. But the parse.h header file is
   181         -modified further (to add additional symbols) using the ./addopcodes.tcl
   182         -Tcl script.
          179  +generates parse.c.
   183    180   
   184    181   The **opcodes.h** header file contains macros that define the numbers
   185    182   corresponding to opcodes in the "VDBE" virtual machine.  The opcodes.h
   186    183   file is generated by the scanning the src/vdbe.c source file.  The
   187    184   Tcl script at ./mkopcodeh.tcl does this scan and generates opcodes.h.
   188    185   A second Tcl script, ./mkopcodec.tcl, then scans opcodes.h to generate
   189    186   the **opcodes.c** source file, which contains a reverse mapping from
................................................................................
   309    306   <a name="vauth"></a>
   310    307   ## Verifying Code Authenticity
   311    308   
   312    309   If you obtained an SQLite source tree from a secondary source, such as a
   313    310   GitHub mirror, and you want to verify that it has not been altered, there
   314    311   are a couple of ways to do that.
   315    312   
   316         -If you have an official release version of SQLite, and you are using the
          313  +If you have a release version of SQLite, and you are using the
   317    314   `sqlite3.c` amalgamation, then SHA3-256 hashes for the amalgamation are
   318    315   available in the [change log](https://www.sqlite.org/changes.html) on
   319    316   the official website.  After building the `sqlite3.c` file, you can check
   320         -that is authentic by comparing the hash.  This does not ensure that the
          317  +that it is authentic by comparing the hash.  This does not ensure that the
   321    318   test scripts are unaltered, but it does validate the deliverable part of
   322         -the code and only involves computing and comparing a single hash.
          319  +the code and the verification process only involves computing and
          320  +comparing a single hash.
   323    321   
   324    322   For versions other than an official release, or if you are building the
   325    323   `sqlite3.c` amalgamation using non-standard build options, the verification
   326    324   process is a little more involved.  The `manifest` file at the root directory
   327         -of the source tree ([example](https://sqlite.org/src/artifact/bd49a8271d650fa8))
          325  +of the source tree
   328    326   contains either a SHA3-256 hash (for newer files) or a SHA1 hash (for 
   329    327   older files) for every source file in the repository.  You can write a script
   330    328   to extracts hashes from `manifest` and verifies the hashes against the 
   331    329   corresponding files in the source tree.  The SHA3-256 hash of the `manifest`
   332    330   file itself is the official name of the version of the source tree that you
   333    331   have.  The `manifest.uuid` file should contain the SHA3-256 hash of the
   334    332   `manifest` file.  If all of the above hash comparisons are correct, then
   335    333   you can be confident that your source tree is authentic and unadulterated.
   336    334   
          335  +The format of the `manifest` file should be mostly self-explanatory, but
          336  +if you want details, they are available
          337  +[here](https://fossil-scm.org/fossil/doc/trunk/www/fileformat.wiki#manifest).
          338  +
   337    339   ## Contacts
   338    340   
   339         -The main SQLite webpage is [http://www.sqlite.org/](http://www.sqlite.org/)
          341  +The main SQLite website is [http://www.sqlite.org/](http://www.sqlite.org/)
   340    342   with geographically distributed backups at
   341    343   [http://www2.sqlite.org/](http://www2.sqlite.org) and
   342    344   [http://www3.sqlite.org/](http://www3.sqlite.org).

Changes to autoconf/Makefile.msc.

   429    429   
   430    430   UCRTLIBPATH = $(UCRTLIBPATH:\\=\)
   431    431   
   432    432   # C compiler and options for use in building executables that
   433    433   # will run on the platform that is doing the build.
   434    434   #
   435    435   !IF $(USE_FULLWARN)!=0
   436         -BCC = $(NCC) -nologo -W4 $(CCOPTS) $(BCCOPTS)
          436  +BCC = $(NCC) -nologo -W4 -Fd$*.pdb $(CCOPTS) $(BCCOPTS)
   437    437   !ELSE
   438         -BCC = $(NCC) -nologo -W3 $(CCOPTS) $(BCCOPTS)
          438  +BCC = $(NCC) -nologo -W3 -Fd$*.pdb $(CCOPTS) $(BCCOPTS)
   439    439   !ENDIF
   440    440   
   441    441   # Check if assembly code listings should be generated for the source
   442    442   # code files to be compiled.
   443    443   #
   444    444   !IF $(USE_LISTINGS)!=0
   445    445   BCC = $(BCC) -FAcs
................................................................................
   804    804   BCC = $(BCC) -Zi
   805    805   !ENDIF
   806    806   
   807    807   
   808    808   # Command line prefixes for compiling code, compiling resources,
   809    809   # linking, etc.
   810    810   #
   811         -LTCOMPILE = $(TCC) -Fo$@
          811  +LTCOMPILE = $(TCC) -Fo$@ -Fd$*.pdb
   812    812   LTRCOMPILE = $(RCC) -r
   813    813   LTLIB = lib.exe
   814    814   LTLINK = $(TCC) -Fe$@
   815    815   
   816    816   # If requested, link to the RPCRT4 library.
   817    817   #
   818    818   !IF $(USE_RPCRT4_LIB)!=0
................................................................................
   822    822   # If a platform was set, force the linker to target that.
   823    823   # Note that the vcvars*.bat family of batch files typically
   824    824   # set this for you.  Otherwise, the linker will attempt
   825    825   # to deduce the binary type based on the object files.
   826    826   !IFDEF PLATFORM
   827    827   LTLINKOPTS = /NOLOGO /MACHINE:$(PLATFORM)
   828    828   LTLIBOPTS = /NOLOGO /MACHINE:$(PLATFORM)
          829  +!ELSEIF "$(VISUALSTUDIOVERSION)"=="12.0" || \
          830  +        "$(VISUALSTUDIOVERSION)"=="14.0" || \
          831  +        "$(VISUALSTUDIOVERSION)"=="15.0"
          832  +LTLINKOPTS = /NOLOGO /MACHINE:x86
          833  +LTLIBOPTS = /NOLOGO /MACHINE:x86
   829    834   !ELSE
   830    835   LTLINKOPTS = /NOLOGO
   831    836   LTLIBOPTS = /NOLOGO
   832    837   !ENDIF
   833    838   
   834    839   # When compiling for use in the WinRT environment, the following
   835    840   # linker option must be used to mark the executable as runnable

Changes to ext/fts3/fts3_snippet.c.

   124    124   /*************************************************************************
   125    125   ** Start of MatchinfoBuffer code.
   126    126   */
   127    127   
   128    128   /*
   129    129   ** Allocate a two-slot MatchinfoBuffer object.
   130    130   */
   131         -static MatchinfoBuffer *fts3MIBufferNew(int nElem, const char *zMatchinfo){
          131  +static MatchinfoBuffer *fts3MIBufferNew(size_t nElem, const char *zMatchinfo){
   132    132     MatchinfoBuffer *pRet;
   133         -  int nByte = sizeof(u32) * (2*nElem + 1) + sizeof(MatchinfoBuffer);
   134         -  int nStr = (int)strlen(zMatchinfo);
          133  +  sqlite3_int64 nByte = sizeof(u32) * (2*(sqlite3_int64)nElem + 1)
          134  +                           + sizeof(MatchinfoBuffer);
          135  +  sqlite3_int64 nStr = strlen(zMatchinfo);
   135    136   
   136         -  pRet = sqlite3_malloc(nByte + nStr+1);
          137  +  pRet = sqlite3_malloc64(nByte + nStr+1);
   137    138     if( pRet ){
   138    139       memset(pRet, 0, nByte);
   139    140       pRet->aMatchinfo[0] = (u8*)(&pRet->aMatchinfo[1]) - (u8*)pRet;
   140         -    pRet->aMatchinfo[1+nElem] = pRet->aMatchinfo[0] + sizeof(u32)*(nElem+1);
   141         -    pRet->nElem = nElem;
          141  +    pRet->aMatchinfo[1+nElem] = pRet->aMatchinfo[0]
          142  +                                      + sizeof(u32)*((int)nElem+1);
          143  +    pRet->nElem = (int)nElem;
   142    144       pRet->zMatchinfo = ((char*)pRet) + nByte;
   143    145       memcpy(pRet->zMatchinfo, zMatchinfo, nStr+1);
   144    146       pRet->aRef[0] = 1;
   145    147     }
   146    148   
   147    149     return pRet;
   148    150   }
................................................................................
   995    997     ){
   996    998       return SQLITE_OK;
   997    999     }
   998   1000     sqlite3Fts3ErrMsg(pzErr, "unrecognized matchinfo request: %c", cArg);
   999   1001     return SQLITE_ERROR;
  1000   1002   }
  1001   1003   
  1002         -static int fts3MatchinfoSize(MatchInfo *pInfo, char cArg){
  1003         -  int nVal;                       /* Number of integers output by cArg */
         1004  +static size_t fts3MatchinfoSize(MatchInfo *pInfo, char cArg){
         1005  +  size_t nVal;                      /* Number of integers output by cArg */
  1004   1006   
  1005   1007     switch( cArg ){
  1006   1008       case FTS3_MATCHINFO_NDOC:
  1007   1009       case FTS3_MATCHINFO_NPHRASE: 
  1008   1010       case FTS3_MATCHINFO_NCOL: 
  1009   1011         nVal = 1;
  1010   1012         break;
................................................................................
  1280   1282           if( rc==SQLITE_OK ){
  1281   1283             rc = fts3MatchinfoLcs(pCsr, pInfo);
  1282   1284           }
  1283   1285           break;
  1284   1286   
  1285   1287         case FTS3_MATCHINFO_LHITS_BM:
  1286   1288         case FTS3_MATCHINFO_LHITS: {
  1287         -        int nZero = fts3MatchinfoSize(pInfo, zArg[i]) * sizeof(u32);
         1289  +        size_t nZero = fts3MatchinfoSize(pInfo, zArg[i]) * sizeof(u32);
  1288   1290           memset(pInfo->aMatchinfo, 0, nZero);
  1289   1291           rc = fts3ExprLHitGather(pCsr->pExpr, pInfo);
  1290   1292           break;
  1291   1293         }
  1292   1294   
  1293   1295         default: {
  1294   1296           Fts3Expr *pExpr;
................................................................................
  1349   1351   
  1350   1352     /* If Fts3Cursor.pMIBuffer is NULL, then this is the first time the
  1351   1353     ** matchinfo function has been called for this query. In this case 
  1352   1354     ** allocate the array used to accumulate the matchinfo data and
  1353   1355     ** initialize those elements that are constant for every row.
  1354   1356     */
  1355   1357     if( pCsr->pMIBuffer==0 ){
  1356         -    int nMatchinfo = 0;           /* Number of u32 elements in match-info */
         1358  +    size_t nMatchinfo = 0;        /* Number of u32 elements in match-info */
  1357   1359       int i;                        /* Used to iterate through zArg */
  1358   1360   
  1359   1361       /* Determine the number of phrases in the query */
  1360   1362       pCsr->nPhrase = fts3ExprPhraseCount(pCsr->pExpr);
  1361   1363       sInfo.nPhrase = pCsr->nPhrase;
  1362   1364   
  1363   1365       /* Determine the number of integers in the buffer returned by this call. */

Changes to ext/fts3/fts3_test.c.

   444    444     while( p<pEnd && testIsTokenChar(*p)==0 ) p++;
   445    445   
   446    446     if( p==pEnd ){
   447    447       rc = SQLITE_DONE;
   448    448     }else{
   449    449       /* Advance to the end of the token */
   450    450       const char *pToken = p;
   451         -    int nToken;
          451  +    sqlite3_int64 nToken;
   452    452       while( p<pEnd && testIsTokenChar(*p) ) p++;
   453         -    nToken = (int)(p-pToken);
          453  +    nToken = (sqlite3_int64)(p-pToken);
   454    454   
   455    455       /* Copy the token into the buffer */
   456    456       if( nToken>pCsr->nBuffer ){
   457    457         sqlite3_free(pCsr->aBuffer);
   458         -      pCsr->aBuffer = sqlite3_malloc(nToken);
          458  +      pCsr->aBuffer = sqlite3_malloc64(nToken);
   459    459       }
   460    460       if( pCsr->aBuffer==0 ){
   461    461         rc = SQLITE_NOMEM;
   462    462       }else{
   463    463         int i;
   464    464   
   465    465         if( pCsr->iLangid & 0x00000001 ){
................................................................................
   467    467         }else{
   468    468           for(i=0; i<nToken; i++) pCsr->aBuffer[i] = (char)testTolower(pToken[i]);
   469    469         }
   470    470         pCsr->iToken++;
   471    471         pCsr->iInput = (int)(p - pCsr->aInput);
   472    472   
   473    473         *ppToken = pCsr->aBuffer;
   474         -      *pnBytes = nToken;
          474  +      *pnBytes = (int)nToken;
   475    475         *piStartOffset = (int)(pToken - pCsr->aInput);
   476    476         *piEndOffset = (int)(p - pCsr->aInput);
   477    477         *piPosition = pCsr->iToken;
   478    478       }
   479    479     }
   480    480   
   481    481     return rc;

Changes to ext/fts3/fts3_tokenize_vtab.c.

   342    342     UNUSED_PARAMETER(idxStr);
   343    343     UNUSED_PARAMETER(nVal);
   344    344   
   345    345     fts3tokResetCursor(pCsr);
   346    346     if( idxNum==1 ){
   347    347       const char *zByte = (const char *)sqlite3_value_text(apVal[0]);
   348    348       int nByte = sqlite3_value_bytes(apVal[0]);
   349         -    pCsr->zInput = sqlite3_malloc(nByte+1);
          349  +    pCsr->zInput = sqlite3_malloc64(nByte+1);
   350    350       if( pCsr->zInput==0 ){
   351    351         rc = SQLITE_NOMEM;
   352    352       }else{
   353    353         memcpy(pCsr->zInput, zByte, nByte);
   354    354         pCsr->zInput[nByte] = 0;
   355    355         rc = pTab->pMod->xOpen(pTab->pTok, pCsr->zInput, nByte, &pCsr->pCsr);
   356    356         if( rc==SQLITE_OK ){

Changes to ext/fts3/fts3_tokenizer.c.

    75     75   
    76     76     pHash = (Fts3Hash *)sqlite3_user_data(context);
    77     77   
    78     78     zName = sqlite3_value_text(argv[0]);
    79     79     nName = sqlite3_value_bytes(argv[0])+1;
    80     80   
    81     81     if( argc==2 ){
    82         -    if( fts3TokenizerEnabled(context) ){
           82  +    if( fts3TokenizerEnabled(context) || sqlite3_value_frombind(argv[1]) ){
    83     83         void *pOld;
    84     84         int n = sqlite3_value_bytes(argv[1]);
    85     85         if( zName==0 || n!=sizeof(pPtr) ){
    86     86           sqlite3_result_error(context, "argument type mismatch", -1);
    87     87           return;
    88     88         }
    89     89         pPtr = *(void **)sqlite3_value_blob(argv[1]);
................................................................................
   102    102       if( !pPtr ){
   103    103         char *zErr = sqlite3_mprintf("unknown tokenizer: %s", zName);
   104    104         sqlite3_result_error(context, zErr, -1);
   105    105         sqlite3_free(zErr);
   106    106         return;
   107    107       }
   108    108     }
   109         -  if( fts3TokenizerEnabled(context) ){
          109  +  if( fts3TokenizerEnabled(context) || sqlite3_value_frombind(argv[0]) ){
   110    110       sqlite3_result_blob(context, (void *)&pPtr, sizeof(pPtr), SQLITE_TRANSIENT);
   111    111     }
   112    112   }
   113    113   
   114    114   int sqlite3Fts3IsIdChar(char c){
   115    115     static const char isFtsIdChar[] = {
   116    116         0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  /* 0x */
................................................................................
   192    192       sqlite3Fts3ErrMsg(pzErr, "unknown tokenizer: %s", z);
   193    193       rc = SQLITE_ERROR;
   194    194     }else{
   195    195       char const **aArg = 0;
   196    196       int iArg = 0;
   197    197       z = &z[n+1];
   198    198       while( z<zEnd && (NULL!=(z = (char *)sqlite3Fts3NextToken(z, &n))) ){
   199         -      int nNew = sizeof(char *)*(iArg+1);
   200         -      char const **aNew = (const char **)sqlite3_realloc((void *)aArg, nNew);
          199  +      sqlite3_int64 nNew = sizeof(char *)*(iArg+1);
          200  +      char const **aNew = (const char **)sqlite3_realloc64((void *)aArg, nNew);
   201    201         if( !aNew ){
   202    202           sqlite3_free(zCopy);
   203    203           sqlite3_free((void *)aArg);
   204    204           return SQLITE_NOMEM;
   205    205         }
   206    206         aArg = aNew;
   207    207         aArg[iArg++] = z;

Changes to ext/fts3/fts3_write.c.

  1748   1748       if( pE ){
  1749   1749         aElem = &pE;
  1750   1750         nElem = 1;
  1751   1751       }
  1752   1752     }
  1753   1753   
  1754   1754     if( nElem>0 ){
  1755         -    int nByte = sizeof(Fts3SegReader) + (nElem+1)*sizeof(Fts3HashElem *);
  1756         -    pReader = (Fts3SegReader *)sqlite3_malloc(nByte);
         1755  +    sqlite3_int64 nByte;
         1756  +    nByte = sizeof(Fts3SegReader) + (nElem+1)*sizeof(Fts3HashElem *);
         1757  +    pReader = (Fts3SegReader *)sqlite3_malloc64(nByte);
  1757   1758       if( !pReader ){
  1758   1759         rc = SQLITE_NOMEM;
  1759   1760       }else{
  1760   1761         memset(pReader, 0, nByte);
  1761   1762         pReader->iIdx = 0x7FFFFFFF;
  1762   1763         pReader->ppNextElem = (Fts3HashElem **)&pReader[1];
  1763   1764         memcpy(pReader->ppNextElem, aElem, nElem*sizeof(Fts3HashElem *));
................................................................................
  3363   3364   ){
  3364   3365     char *pBlob;             /* The BLOB encoding of the document size */
  3365   3366     int nBlob;               /* Number of bytes in the BLOB */
  3366   3367     sqlite3_stmt *pStmt;     /* Statement used to insert the encoding */
  3367   3368     int rc;                  /* Result code from subfunctions */
  3368   3369   
  3369   3370     if( *pRC ) return;
  3370         -  pBlob = sqlite3_malloc( 10*p->nColumn );
         3371  +  pBlob = sqlite3_malloc64( 10*(sqlite3_int64)p->nColumn );
  3371   3372     if( pBlob==0 ){
  3372   3373       *pRC = SQLITE_NOMEM;
  3373   3374       return;
  3374   3375     }
  3375   3376     fts3EncodeIntArray(p->nColumn, aSz, pBlob, &nBlob);
  3376   3377     rc = fts3SqlStmt(p, SQL_REPLACE_DOCSIZE, &pStmt, 0);
  3377   3378     if( rc ){
................................................................................
  3413   3414     sqlite3_stmt *pStmt;     /* Statement for reading and writing */
  3414   3415     int i;                   /* Loop counter */
  3415   3416     int rc;                  /* Result code from subfunctions */
  3416   3417   
  3417   3418     const int nStat = p->nColumn+2;
  3418   3419   
  3419   3420     if( *pRC ) return;
  3420         -  a = sqlite3_malloc( (sizeof(u32)+10)*nStat );
         3421  +  a = sqlite3_malloc64( (sizeof(u32)+10)*(sqlite3_int64)nStat );
  3421   3422     if( a==0 ){
  3422   3423       *pRC = SQLITE_NOMEM;
  3423   3424       return;
  3424   3425     }
  3425   3426     pBlob = (char*)&a[nStat];
  3426   3427     rc = fts3SqlStmt(p, SQL_SELECT_STAT, &pStmt, 0);
  3427   3428     if( rc ){
................................................................................
  3534   3535         rc = SQLITE_NOMEM;
  3535   3536       }else{
  3536   3537         rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
  3537   3538         sqlite3_free(zSql);
  3538   3539       }
  3539   3540   
  3540   3541       if( rc==SQLITE_OK ){
  3541         -      int nByte = sizeof(u32) * (p->nColumn+1)*3;
  3542         -      aSz = (u32 *)sqlite3_malloc(nByte);
         3542  +      sqlite3_int64 nByte = sizeof(u32) * ((sqlite3_int64)p->nColumn+1)*3;
         3543  +      aSz = (u32 *)sqlite3_malloc64(nByte);
  3543   3544         if( aSz==0 ){
  3544   3545           rc = SQLITE_NOMEM;
  3545   3546         }else{
  3546   3547           memset(aSz, 0, nByte);
  3547   3548           aSzIns = &aSz[p->nColumn+1];
  3548   3549           aSzDel = &aSzIns[p->nColumn+1];
  3549   3550         }
................................................................................
  3601   3602     Fts3Table *p,                   /* FTS3 table handle */
  3602   3603     sqlite3_int64 iAbsLevel,        /* Absolute level to open */
  3603   3604     int nSeg,                       /* Number of segments to merge */
  3604   3605     Fts3MultiSegReader *pCsr        /* Cursor object to populate */
  3605   3606   ){
  3606   3607     int rc;                         /* Return Code */
  3607   3608     sqlite3_stmt *pStmt = 0;        /* Statement used to read %_segdir entry */  
  3608         -  int nByte;                      /* Bytes allocated at pCsr->apSegment[] */
         3609  +  sqlite3_int64 nByte;            /* Bytes allocated at pCsr->apSegment[] */
  3609   3610   
  3610   3611     /* Allocate space for the Fts3MultiSegReader.aCsr[] array */
  3611   3612     memset(pCsr, 0, sizeof(*pCsr));
  3612   3613     nByte = sizeof(Fts3SegReader *) * nSeg;
  3613         -  pCsr->apSegment = (Fts3SegReader **)sqlite3_malloc(nByte);
         3614  +  pCsr->apSegment = (Fts3SegReader **)sqlite3_malloc64(nByte);
  3614   3615   
  3615   3616     if( pCsr->apSegment==0 ){
  3616   3617       rc = SQLITE_NOMEM;
  3617   3618     }else{
  3618   3619       memset(pCsr->apSegment, 0, nByte);
  3619   3620       rc = fts3SqlStmt(p, SQL_SELECT_LEVEL, &pStmt, 0);
  3620   3621     }
................................................................................
  5586   5587   
  5587   5588     if( nArg>1 && sqlite3_value_int(apVal[2 + p->nColumn + 2])<0 ){
  5588   5589       rc = SQLITE_CONSTRAINT;
  5589   5590       goto update_out;
  5590   5591     }
  5591   5592   
  5592   5593     /* Allocate space to hold the change in document sizes */
  5593         -  aSzDel = sqlite3_malloc( sizeof(aSzDel[0])*(p->nColumn+1)*2 );
         5594  +  aSzDel = sqlite3_malloc64(sizeof(aSzDel[0])*((sqlite3_int64)p->nColumn+1)*2);
  5594   5595     if( aSzDel==0 ){
  5595   5596       rc = SQLITE_NOMEM;
  5596   5597       goto update_out;
  5597   5598     }
  5598   5599     aSzIns = &aSzDel[p->nColumn+1];
  5599   5600     memset(aSzDel, 0, sizeof(aSzDel[0])*(p->nColumn+1)*2);
  5600   5601   

Changes to ext/fts5/fts5_index.c.

  2639   2639     if( p1->pLeaf==0 ){           /* If p1 is at EOF */
  2640   2640       iRes = i2;
  2641   2641     }else if( p2->pLeaf==0 ){     /* If p2 is at EOF */
  2642   2642       iRes = i1;
  2643   2643     }else{
  2644   2644       int res = fts5BufferCompare(&p1->term, &p2->term);
  2645   2645       if( res==0 ){
  2646         -      assert( i2>i1 );
  2647         -      assert( i2!=0 );
         2646  +      assert_nc( i2>i1 );
         2647  +      assert_nc( i2!=0 );
  2648   2648         pRes->bTermEq = 1;
  2649   2649         if( p1->iRowid==p2->iRowid ){
  2650   2650           p1->bDel = p2->bDel;
  2651   2651           return i2;
  2652   2652         }
  2653   2653         res = ((p1->iRowid > p2->iRowid)==pIter->bRev) ? -1 : +1;
  2654   2654       }
................................................................................
  3687   3687     if( p->rc==SQLITE_OK && nLvl>=pWriter->nDlidx ){
  3688   3688       Fts5DlidxWriter *aDlidx = (Fts5DlidxWriter*)sqlite3_realloc64(
  3689   3689           pWriter->aDlidx, sizeof(Fts5DlidxWriter) * nLvl
  3690   3690       );
  3691   3691       if( aDlidx==0 ){
  3692   3692         p->rc = SQLITE_NOMEM;
  3693   3693       }else{
  3694         -      int nByte = sizeof(Fts5DlidxWriter) * (nLvl - pWriter->nDlidx);
         3694  +      size_t nByte = sizeof(Fts5DlidxWriter) * (nLvl - pWriter->nDlidx);
  3695   3695         memset(&aDlidx[pWriter->nDlidx], 0, nByte);
  3696   3696         pWriter->aDlidx = aDlidx;
  3697   3697         pWriter->nDlidx = nLvl;
  3698   3698       }
  3699   3699     }
  3700   3700     return p->rc;
  3701   3701   }

Changes to ext/fts5/fts5_main.c.

  2464   2464     fts5_extension_function xFunc,  /* Aux. function implementation */
  2465   2465     void(*xDestroy)(void*)          /* Destructor for pUserData */
  2466   2466   ){
  2467   2467     Fts5Global *pGlobal = (Fts5Global*)pApi;
  2468   2468     int rc = sqlite3_overload_function(pGlobal->db, zName, -1);
  2469   2469     if( rc==SQLITE_OK ){
  2470   2470       Fts5Auxiliary *pAux;
  2471         -    int nName;                      /* Size of zName in bytes, including \0 */
  2472         -    int nByte;                      /* Bytes of space to allocate */
         2471  +    sqlite3_int64 nName;            /* Size of zName in bytes, including \0 */
         2472  +    sqlite3_int64 nByte;            /* Bytes of space to allocate */
  2473   2473   
  2474         -    nName = (int)strlen(zName) + 1;
         2474  +    nName = strlen(zName) + 1;
  2475   2475       nByte = sizeof(Fts5Auxiliary) + nName;
  2476         -    pAux = (Fts5Auxiliary*)sqlite3_malloc(nByte);
         2476  +    pAux = (Fts5Auxiliary*)sqlite3_malloc64(nByte);
  2477   2477       if( pAux ){
  2478         -      memset(pAux, 0, nByte);
         2478  +      memset(pAux, 0, (size_t)nByte);
  2479   2479         pAux->zFunc = (char*)&pAux[1];
  2480   2480         memcpy(pAux->zFunc, zName, nName);
  2481   2481         pAux->pGlobal = pGlobal;
  2482   2482         pAux->pUserData = pUserData;
  2483   2483         pAux->xFunc = xFunc;
  2484   2484         pAux->xDestroy = xDestroy;
  2485   2485         pAux->pNext = pGlobal->pAux;
................................................................................
  2501   2501     const char *zName,              /* Name of new function */
  2502   2502     void *pUserData,                /* User data for aux. function */
  2503   2503     fts5_tokenizer *pTokenizer,     /* Tokenizer implementation */
  2504   2504     void(*xDestroy)(void*)          /* Destructor for pUserData */
  2505   2505   ){
  2506   2506     Fts5Global *pGlobal = (Fts5Global*)pApi;
  2507   2507     Fts5TokenizerModule *pNew;
  2508         -  int nName;                      /* Size of zName and its \0 terminator */
  2509         -  int nByte;                      /* Bytes of space to allocate */
         2508  +  sqlite3_int64 nName;            /* Size of zName and its \0 terminator */
         2509  +  sqlite3_int64 nByte;            /* Bytes of space to allocate */
  2510   2510     int rc = SQLITE_OK;
  2511   2511   
  2512         -  nName = (int)strlen(zName) + 1;
         2512  +  nName = strlen(zName) + 1;
  2513   2513     nByte = sizeof(Fts5TokenizerModule) + nName;
  2514         -  pNew = (Fts5TokenizerModule*)sqlite3_malloc(nByte);
         2514  +  pNew = (Fts5TokenizerModule*)sqlite3_malloc64(nByte);
  2515   2515     if( pNew ){
  2516         -    memset(pNew, 0, nByte);
         2516  +    memset(pNew, 0, (size_t)nByte);
  2517   2517       pNew->zName = (char*)&pNew[1];
  2518   2518       memcpy(pNew->zName, zName, nName);
  2519   2519       pNew->pUserData = pUserData;
  2520   2520       pNew->x = *pTokenizer;
  2521   2521       pNew->xDestroy = xDestroy;
  2522   2522       pNew->pNext = pGlobal->pTok;
  2523   2523       pGlobal->pTok = pNew;

Changes to ext/fts5/fts5_tokenize.c.

   365    365       if( p ){
   366    366         const char *zCat = "L* N* Co";
   367    367         int i;
   368    368         memset(p, 0, sizeof(Unicode61Tokenizer));
   369    369   
   370    370         p->eRemoveDiacritic = FTS5_REMOVE_DIACRITICS_SIMPLE;
   371    371         p->nFold = 64;
   372         -      p->aFold = sqlite3_malloc(p->nFold * sizeof(char));
          372  +      p->aFold = sqlite3_malloc64(p->nFold * sizeof(char));
   373    373         if( p->aFold==0 ){
   374    374           rc = SQLITE_NOMEM;
   375    375         }
   376    376   
   377    377         /* Search for a "categories" argument */
   378    378         for(i=0; rc==SQLITE_OK && i<nArg; i+=2){
   379    379           if( 0==sqlite3_stricmp(azArg[i], "categories") ){

Changes to ext/fts5/test/fts5corrupt3.test.

  7990   7990   |   4080: 67 73 7a 18 0b 03 1b 01 76 65 72 73 69 6f 6e 04   gsz.....version.
  7991   7991   | page 6 offset 20480
  7992   7992   |      0: 0d 00 00 00 03 0f f2 00 0f fc 0f f7 0f f2 00 00   ................
  7993   7993   |   4080: 00 00 03 03 02 01 03 03 02 02 01 02 02 01 02 09   ................
  7994   7994   | end crash-2acc487d09f033.db
  7995   7995   }]} {}
  7996   7996   
  7997         -do_catchsql_test 56.1 {
         7997  +do_test 56.1 {
         7998  +  set res [catchsql {
  7998   7999     INSERT INTO t1(b) VALUES(randomblob(250));
  7999   8000     INSERT INTO t1(b) VALUES(randomblob(250));
         8001  +  }]
         8002  +
         8003  +  # For some permutations - those that use the page-cache - this test
         8004  +  # may return SQLITE_CONSTRAINT instead of SQLITE_CORRUPT. This is because
         8005  +  # the corrupt db in the test over-reads the page buffer slightly, with
         8006  +  # different results depending on whether or not the page-cache is in use.
         8007  +  if {$res=="1 {constraint failed}"} {
         8008  +    set res "1 {database disk image is malformed}"
         8009  +  }
         8010  +  set res
         8011  +} {1 {database disk image is malformed}}
         8012  +
         8013  +#-------------------------------------------------------------------------
         8014  +reset_db
         8015  +do_test 57.0 {
         8016  +  sqlite3 db {}
         8017  +  db deserialize [decode_hexdb {
         8018  +| size 28672 pagesize 4096 filename x.db
         8019  +| page 1 offset 0
         8020  +|      0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00   SQLite format 3.
         8021  +|     16: 10 00 01 01 00 40 20 20 00 00 00 01 00 00 00 07   .....@  ........
         8022  +|     32: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00   ................
         8023  +|     80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01   ................
         8024  +|     96: 00 2e 34 20 0d 00 00 00 07 0d d2 00 0f c4 0f 6d   ..4 ...........m
         8025  +|    112: 0f 02 0e ab 0e 4e 0d f6 0d d2 00 00 00 00 00 00   .....N..........
         8026  +|   3536: 00 00 22 07 06 17 11 11 01 31 74 61 62 6c 65 74   .........1tablet
         8027  +|   3552: 32 74 32 07 43 52 45 41 54 45 20 54 41 42 4c 45   2t2.CREATE TABLE
         8028  +|   3568: 20 74 32 28 78 29 56 06 06 17 1f 1f 01 7d 74 61    t2(x)V.......ta
         8029  +|   3584: 61 6b 65 74 31 5f 63 6f 6e 66 69 67 74 31 5f 63   aket1_configt1_c
         8030  +|   3600: 6f 7e 66 69 67 06 43 52 45 41 54 45 20 54 41 42   o~fig.CREATE TAB
         8031  +|   3616: 4c 45 20 27 74 31 5f 63 6f 6e 66 69 67 27 28 6b   LE 't1_config'(k
         8032  +|   3632: 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 76 29    PRIMARY KEY, v)
         8033  +|   3648: 20 57 49 54 48 4f 55 54 20 52 4f 57 49 44 5b 05    WITHOUT ROWID[.
         8034  +|   3664: 07 17 21 21 01 81 01 74 61 62 6c 65 74 31 5f 64   ..!!...tablet1_d
         8035  +|   3680: 6f 63 73 69 7a 65 74 31 5f 64 6f 63 73 69 7a 65   ocsizet1_docsize
         8036  +|   3696: 05 43 52 45 41 54 45 20 54 41 42 4c 45 20 27 74   .CREATE TABLE 't
         8037  +|   3712: 31 5f 64 6f 63 73 69 7a 65 27 28 69 64 20 49 4e   1_docsize'(id IN
         8038  +|   3728: 54 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45   TEGER PRIMARY KE
         8039  +|   3744: 59 2c 20 73 7a 20 42 4c 4f 42 29 55 04 06 17 21   Y, sz BLOB)U...!
         8040  +|   3760: 21 01 77 74 61 62 6c 65 74 31 5f 63 6f 6e 74 1d   !.wtablet1_cont.
         8041  +|   3776: 6e 74 74 31 5f 63 6f 6e 74 65 6e 74 04 43 52 45   ntt1_content.CRE
         8042  +|   3792: 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 63 6f   ATE TABLE 't1_co
         8043  +|   3808: 6e 74 65 6e 74 27 28 69 64 20 49 4e 54 45 47 45   ntent'(id INTEGE
         8044  +|   3824: 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 63   R PRIMARY KEY, c
         8045  +|   3840: 30 29 69 03 07 17 19 19 01 81 2d 74 61 62 6c 65   0)i.......-table
         8046  +|   3856: 74 31 5f 69 64 78 74 31 5f 59 64 78 03 43 52 45   t1_idxt1_Ydx.CRE
         8047  +|   3872: 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 69 64   ATE TABLE 't1_id
         8048  +|   3888: 78 27 28 73 65 67 69 64 2c 20 74 65 72 6d 2c 20   x'(segid, term, 
         8049  +|   3904: 70 67 6e 6f 2c 20 50 52 49 4d 41 52 59 20 4b 45   pgno, PRIMARY KE
         8050  +|   3920: 59 28 73 65 67 69 64 2c 20 74 65 72 6d 29 29 20   Y(segid, term)) 
         8051  +|   3936: 57 49 54 48 4f 55 54 20 52 4f 57 49 44 55 02 07   WITHOUT ROWIDU..
         8052  +|   3952: 17 1b 1b 01 81 01 74 61 62 6c 65 74 31 5f 64 61   ......tablet1_da
         8053  +|   3968: 74 61 74 31 5f 64 61 64 61 02 43 52 45 41 54 45   tat1_dada.CREATE
         8054  +|   3984: 20 54 41 42 4c 45 20 27 74 31 5f 64 61 74 61 27    TABLE 't1_data'
         8055  +|   4000: 28 69 64 20 49 4e 54 45 47 45 52 20 50 52 49 4d   (id INTEGER PRIM
         8056  +|   4016: 41 52 59 20 4b 45 59 2c 20 62 6c 6f 63 6b 20 42   ARY KEY, block B
         8057  +|   4032: 4c 4f 42 29 3a 01 06 17 11 11 08 63 74 61 62 6c   LOB):......ctabl
         8058  +|   4048: 65 74 31 74 31 43 52 45 41 54 45 20 56 49 52 54   et1t1CREATE VIRT
         8059  +|   4064: 55 41 4c 20 54 41 42 4c 45 20 74 31 20 55 53 49   UAL TABLE t1 USI
         8060  +|   4080: 4e 47 20 66 74 73 35 28 63 6f 6e 74 65 6e 74 29   NG fts5(content)
         8061  +| page 2 offset 4096
         8062  +|      0: 0d 0e b4 00 06 0e 35 00 0f e8 0e 35 0f bd 0f 4e   ......5....5...N
         8063  +|     16: 0e cb 0e 4f 00 00 00 00 00 00 00 00 00 00 00 00   ...O............
         8064  +|   3632: 00 00 00 00 00 18 0a 03 00 36 00 00 00 00 01 04   .........6......
         8065  +|   3648: 04 00 04 01 01 01 02 01 01 03 01 01 04 01 01 5e   ...............^
         8066  +|   3664: 90 80 80 80 80 01 04 00 81 40 00 00 00 51 06 30   .........@...Q.0
         8067  +|   3680: 61 62 61 63 6b 01 01 04 04 6e 64 6f 6e 01 01 02   aback....ndon...
         8068  +|   3696: 04 63 69 76 65 01 01 02 04 6c 70 68 61 01 01 02   .cive....lpha...
         8069  +|   3712: 03 74 6f 6d 01 01 01 06 62 61 63 6b 75 70 01 01   .tom....backup..
         8070  +|   3728: 02 05 6f 6f 6d 65 72 01 01 01 06 63 68 61 6e 6e   ..oomer....chann
         8071  +|   3744: 65 01 01 01 04 74 65 73 74 01 01 04 09 08 08 08   e....test.......
         8072  +|   3760: 07 0a 09 0a 0f 3a 00 17 30 00 00 00 00 01 03 03   .....:..0.......
         8073  +|   3776: 00 03 01 01 01 02 01 01 03 01 01 68 8c 80 80 80   ...........h....
         8074  +|   3792: 80 01 04 00 81 54 00 00 00 5b 06 30 61 62 61 63   .....T...[.0abac
         8075  +|   3808: 6b 02 02 07 04 04 6e 64 6f 6e 02 02 05 02 04 63   k.....ndon.....c
         8076  +|   3824: 69 76 65 02 02 0b 02 04 6c 70 68 61 02 04 02 0a   ive.....lpha....
         8077  +|   3840: 02 03 74 6f 6d 02 02 09 01 06 62 61 63 6b 75 70   ..tom.....backup
         8078  +|   3856: 02 02 04 02 05 6f 6f 6d 65 72 02 02 08 01 06 63   .....oomer.....c
         8079  +|   3872: 68 61 6e 6e 65 02 02 03 01 04 74 65 73 74 02 02   hanne.....test..
         8080  +|   3888: 06 04 0a 09 09 0a 08 0b 0a 0b 0f ef 00 14 2a 00   ..............*.
         8081  +|   3904: 00 00 00 01 02 02 00 02 01 01 01 02 01 01 68 88   ..............h.
         8082  +|   3920: 80 80 80 80 01 04 00 81 54 00 00 00 5b 06 30 61   ........T...[.0a
         8083  +|   3936: 62 61 63 6b 01 02 07 04 04 6e 64 6f 6e 01 02 05   back.....ndon...
         8084  +|   3952: 02 04 63 69 76 65 01 02 0b 02 04 6c 70 68 61 01   ..cive.....lpha.
         8085  +|   3968: 04 02 0a 02 03 74 6f 6d 01 02 09 01 06 62 61 63   .....tom.....bac
         8086  +|   3984: 6b 75 70 01 02 04 02 05 6f 6f 6d 65 72 01 02 08   kup.....oomer...
         8087  +|   4000: 01 06 63 68 61 6e 6e 65 01 02 03 01 04 74 65 73   ..channe.....tes
         8088  +|   4016: 74 01 02 06 04 0a 09 09 0a 08 0b 0a 0b 24 84 80   t............$..
         8089  +|   4032: 80 80 80 01 03 00 4e 00 00 00 1e 06 30 61 62 61   ......N.....0aba
         8090  +|   4048: 63 6b 01 02 02 05 42 66 74 02 02 02 04 04 6e 64   ck....Bft.....nd
         8091  +|   4064: 6f 6e 03 02 02 04 0a 07 05 01 03 00 10 04 0d 00   on..............
         8092  +|   4080: 00 00 11 24 00 00 00 00 01 01 01 00 01 01 01 01   ...$............
         8093  +| page 3 offset 8192
         8094  +|      0: 0a 00 00 00 04 0f e5 00 00 00 0f f3 0f ec 0f e5   ................
         8095  +|   4064: 00 00 00 00 00 06 04 01 0c 01 04 02 06 04 01 0c   ................
         8096  +|   4080: 01 03 02 06 04 01 0c 01 02 02 05 04 09 0d 01 02   ................
         8097  +| page 4 offset 12288
         8098  +|      0: 0d 0e bc 00 04 0e 78 00 00 00 00 00 00 00 0e 78   ......x........x
         8099  +|     16: 0e 78 00 00 00 00 00 00 00 00 00 00 00 00 00 00   .x..............
         8100  +|   3696: 00 00 00 00 00 00 00 00 42 02 04 00 81 09 61 6c   ........B.....al
         8101  +|   3712: 70 68 61 20 63 68 61 6e 6e 65 20 62 61 63 6b 75   pha channe backu
         8102  +|   3728: 70 20 61 62 61 6e 64 6f 6e 20 74 65 73 74 20 61   p abandon test a
         8103  +|   3744: 62 61 63 6b 20 62 6f 6f 6d 65 72 20 61 74 6f 6d   back boomer atom
         8104  +|   3760: 20 61 6c 70 68 61 20 61 63 69 76 65 00 00 00 44    alpha acive...D
         8105  +|   3776: 81 09 61 6c 70 68 61 20 63 68 61 6e 6e 65 20 62   ..alpha channe b
         8106  +|   3792: 61 63 6b 75 70 20 61 62 61 6e 64 6f 6e 20 74 65   ackup abandon te
         8107  +|   3808: 73 74 20 61 62 61 63 6b 20 62 6f 6f 6d 65 72 20   st aback boomer 
         8108  +|   3824: 61 74 6f 6d 20 61 6c 70 68 61 20 61 63 69 76 65   atom alpha acive
         8109  +|   4064: 0a 03 03 00 1b 61 4e 61 6e 64 6f 6e 08 02 03 00   .....aNandon....
         8110  +|   4080: 17 61 62 61 66 74 08 01 03 00 17 61 62 71 63 6b   .abaft.....abqck
         8111  +| page 5 offset 16384
         8112  +|      0: 0d 0f e8 00 04 0f e2 00 00 00 00 00 00 00 0f e2   ................
         8113  +|     16: 0f e2 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
         8114  +|   4064: 00 00 04 02 03 00 0e 0a 00 00 00 06 0e 0a 04 03   ................
         8115  +|   4080: 03 00 0e 01 04 02 03 00 0e 01 04 01 03 10 0e 01   ................
         8116  +| page 6 offset 20480
         8117  +|      0: 0a 00 00 00 01 0f f4 00 0f f4 00 00 00 00 00 00   ................
         8118  +|   4080: 00 00 00 00 0b 03 1b 01 76 65 72 73 69 6f 6e 04   ........version.
         8119  +| page 7 offset 24576
         8120  +|      0: 0d 00 00 00 03 0f d6 00 0f f4 00 00 00 00 00 00   ................
         8121  +|   4048: 00 00 00 00 00 00 09 03 02 1b 72 65 62 75 69 6c   ..........rebuil
         8122  +|   4064: 64 11 02 02 2b 69 6e 74 65 67 72 69 74 79 2d 63   d...+integrity-c
         8123  +|   4080: 68 65 63 6b 0a 01 02 1d 6f 70 74 69 6d 69 7a 65   heck....optimize
         8124  +| end x.db
         8125  +}]} {}
         8126  +
         8127  +do_catchsql_test 57.1 {
         8128  +  INSERT INTO t1(t1) VALUES('optimize')
  8000   8129   } {1 {database disk image is malformed}}
         8130  +
  8001   8131   
  8002   8132   sqlite3_fts5_may_be_corrupt 0
  8003   8133   finish_test
  8004   8134   

Added ext/misc/blobio.c.

            1  +/*
            2  +** 2019-03-30
            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  +** An SQL function that uses the incremental BLOB I/O mechanism of SQLite
           14  +** to read or write part of a blob.  This is intended for debugging use
           15  +** in the CLI.
           16  +**
           17  +**      readblob(SCHEMA,TABLE,COLUMN,ROWID,OFFSET,N)
           18  +**
           19  +** Returns N bytes of the blob starting at OFFSET.
           20  +**
           21  +**      writeblob(SCHEMA,TABLE,COLUMN,ROWID,OFFSET,NEWDATA)
           22  +**
           23  +** NEWDATA must be a blob.  The content of NEWDATA overwrites the
           24  +** existing BLOB data at SCHEMA.TABLE.COLUMN for row ROWID beginning
           25  +** at OFFSET bytes into the blob.
           26  +*/
           27  +#include "sqlite3ext.h"
           28  +SQLITE_EXTENSION_INIT1
           29  +#include <assert.h>
           30  +#include <string.h>
           31  +
           32  +static void readblobFunc(
           33  +  sqlite3_context *context,
           34  +  int argc,
           35  +  sqlite3_value **argv
           36  +){
           37  +  sqlite3_blob *pBlob = 0;
           38  +  const char *zSchema;
           39  +  const char *zTable;
           40  +  const char *zColumn;
           41  +  sqlite3_int64 iRowid;
           42  +  int iOfst;
           43  +  unsigned char *aData;
           44  +  int nData;
           45  +  sqlite3 *db;
           46  +  int rc;
           47  +
           48  +  zSchema = (const char*)sqlite3_value_text(argv[0]);
           49  +  zTable = (const char*)sqlite3_value_text(argv[1]);
           50  +  if( zTable==0 ){
           51  +    sqlite3_result_error(context, "bad table name", -1);
           52  +    return;
           53  +  }
           54  +  zColumn = (const char*)sqlite3_value_text(argv[2]);
           55  +  if( zTable==0 ){
           56  +    sqlite3_result_error(context, "bad column name", -1);
           57  +    return;
           58  +  }
           59  +  iRowid = sqlite3_value_int64(argv[3]);
           60  +  iOfst = sqlite3_value_int(argv[4]);
           61  +  nData = sqlite3_value_int(argv[5]);
           62  +  if( nData<=0 ) return;
           63  +  aData = sqlite3_malloc64( nData+1 );
           64  +  if( aData==0 ){
           65  +    sqlite3_result_error_nomem(context);
           66  +    return;
           67  +  }
           68  +  db = sqlite3_context_db_handle(context);
           69  +  rc = sqlite3_blob_open(db, zSchema, zTable, zColumn, iRowid, 0, &pBlob);
           70  +  if( rc ){
           71  +    sqlite3_free(aData);
           72  +    sqlite3_result_error(context, "cannot open BLOB pointer", -1);
           73  +    return;
           74  +  }
           75  +  rc = sqlite3_blob_read(pBlob, aData, nData, iOfst);
           76  +  sqlite3_blob_close(pBlob);
           77  +  if( rc ){
           78  +    sqlite3_free(aData);
           79  +    sqlite3_result_error(context, "BLOB write failed", -1);
           80  +  }else{
           81  +    sqlite3_result_blob(context, aData, nData, sqlite3_free);
           82  +  }
           83  +}    
           84  +
           85  +static void writeblobFunc(
           86  +  sqlite3_context *context,
           87  +  int argc,
           88  +  sqlite3_value **argv
           89  +){
           90  +  sqlite3_blob *pBlob = 0;
           91  +  const char *zSchema;
           92  +  const char *zTable;
           93  +  const char *zColumn;
           94  +  sqlite3_int64 iRowid;
           95  +  int iOfst;
           96  +  unsigned char *aData;
           97  +  int nData;
           98  +  sqlite3 *db;
           99  +  int rc;
          100  +
          101  +  zSchema = (const char*)sqlite3_value_text(argv[0]);
          102  +  zTable = (const char*)sqlite3_value_text(argv[1]);
          103  +  if( zTable==0 ){
          104  +    sqlite3_result_error(context, "bad table name", -1);
          105  +    return;
          106  +  }
          107  +  zColumn = (const char*)sqlite3_value_text(argv[2]);
          108  +  if( zTable==0 ){
          109  +    sqlite3_result_error(context, "bad column name", -1);
          110  +    return;
          111  +  }
          112  +  iRowid = sqlite3_value_int64(argv[3]);
          113  +  iOfst = sqlite3_value_int(argv[4]);
          114  +  if( sqlite3_value_type(argv[5])!=SQLITE_BLOB ){
          115  +    sqlite3_result_error(context, "6th argument must be a BLOB", -1);
          116  +    return;
          117  +  }
          118  +  nData = sqlite3_value_bytes(argv[5]);
          119  +  aData = (unsigned char *)sqlite3_value_blob(argv[5]);
          120  +  db = sqlite3_context_db_handle(context);
          121  +  rc = sqlite3_blob_open(db, zSchema, zTable, zColumn, iRowid, 1, &pBlob);
          122  +  if( rc ){
          123  +    sqlite3_result_error(context, "cannot open BLOB pointer", -1);
          124  +    return;
          125  +  }
          126  +  rc = sqlite3_blob_write(pBlob, aData, nData, iOfst);
          127  +  sqlite3_blob_close(pBlob);
          128  +  if( rc ){
          129  +    sqlite3_result_error(context, "BLOB write failed", -1);
          130  +  }
          131  +}    
          132  +
          133  +
          134  +#ifdef _WIN32
          135  +__declspec(dllexport)
          136  +#endif
          137  +int sqlite3_blobio_init(
          138  +  sqlite3 *db, 
          139  +  char **pzErrMsg, 
          140  +  const sqlite3_api_routines *pApi
          141  +){
          142  +  int rc = SQLITE_OK;
          143  +  SQLITE_EXTENSION_INIT2(pApi);
          144  +  (void)pzErrMsg;  /* Unused parameter */
          145  +  rc = sqlite3_create_function(db, "readblob", 6, SQLITE_UTF8, 0,
          146  +                               readblobFunc, 0, 0);
          147  +  if( rc==SQLITE_OK ){
          148  +    rc = sqlite3_create_function(db, "writeblob", 6, SQLITE_UTF8, 0,
          149  +                               writeblobFunc, 0, 0);
          150  +  }
          151  +  return rc;
          152  +}

Changes to ext/misc/fileio.c.

   154    154     }
   155    155     pBuf = sqlite3_malloc64( nIn ? nIn : 1 );
   156    156     if( pBuf==0 ){
   157    157       sqlite3_result_error_nomem(ctx);
   158    158       fclose(in);
   159    159       return;
   160    160     }
   161         -  if( nIn==fread(pBuf, 1, (size_t)nIn, in) ){
          161  +  if( nIn==(sqlite3_int64)fread(pBuf, 1, (size_t)nIn, in) ){
   162    162       sqlite3_result_blob64(ctx, pBuf, nIn, sqlite3_free);
   163    163     }else{
   164    164       sqlite3_result_error_code(ctx, SQLITE_IOERR);
   165    165       sqlite3_free(pBuf);
   166    166     }
   167    167     fclose(in);
   168    168   }

Added ext/rbu/rbupartial.test.

            1  +# 2019 April 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  +
           13  +source [file join [file dirname [info script]] rbu_common.tcl]
           14  +set ::testprefix rbupartial
           15  +
           16  +db close
           17  +sqlite3_shutdown
           18  +sqlite3_config_uri 1
           19  +
           20  +foreach {tn without_rowid a b c d} {
           21  +  1 ""              a b c d
           22  +  2 "WITHOUT ROWID" aaa bbb ccc ddd
           23  +  3 "WITHOUT ROWID" "\"hello\"" {"one'two"}  {[c]} ddd
           24  +  4 "WITHOUT ROWID" {`a b`} {"one'two"}  {[c c c]} ddd
           25  +  5 "" a b c {"d""d"}
           26  +  6 "" {'one''two'} b {"c""c"} {"d""d"}
           27  +} {
           28  +  eval [string map [list \
           29  +    %WITHOUT_ROWID% $without_rowid %A% $a %B% $b %C% $c %D% $d
           30  +  ] {
           31  +  reset_db
           32  +  do_execsql_test $tn.1.0 {
           33  +    CREATE TABLE t1(%A% PRIMARY KEY, %B%, %C%, %D%) %WITHOUT_ROWID% ;
           34  +    CREATE INDEX i1b  ON t1(%B%);
           35  +    CREATE INDEX i1b2 ON t1(%B%) WHERE %C%<5;
           36  +    CREATE INDEX i1b3 ON t1(%B%) WHERE %C%>=5;
           37  +
           38  +    CREATE INDEX i1c  ON t1(%C%);
           39  +    CREATE INDEX i1c2 ON t1(%C%) WHERE %C% IS NULL;
           40  +    CREATE INDEX i1c3 ON t1(%C%) WHERE %C% IS NOT NULL;
           41  +
           42  +    CREATE INDEX i1c4 ON t1(%C%) WHERE %D% < 'd';
           43  +  }
           44  +
           45  +  do_execsql_test $tn.1.1 {
           46  +    INSERT INTO t1 VALUES(0, NULL, NULL, 'a');
           47  +    INSERT INTO t1 VALUES(1, 2, 3, 'b');
           48  +    INSERT INTO t1 VALUES(4, 5, 6, 'c');
           49  +    INSERT INTO t1 VALUES(7, 8, 9, 'd');
           50  +  }
           51  +
           52  +  forcedelete rbu.db
           53  +  do_test $tn.1.2 {
           54  +    sqlite3 rbu rbu.db
           55  +    rbu eval {
           56  +      CREATE TABLE data_t1(%A%, %B%, %C%, %D%, rbu_control);
           57  +
           58  +      INSERT INTO data_t1 VALUES(10, 11, 12, 'e', 0);
           59  +      INSERT INTO data_t1 VALUES(13, 14, NULL, 'f', 0);
           60  +
           61  +      INSERT INTO data_t1 VALUES(0, NULL, NULL, NULL, 1);
           62  +      INSERT INTO data_t1 VALUES(4, NULL, NULL, NULL, 1);
           63  +
           64  +      INSERT INTO data_t1 VALUES(7, NULL, 4, NULL, '..x.');
           65  +      INSERT INTO data_t1 VALUES(1, 10, NULL, NULL, '.xx.');
           66  +    }
           67  +    rbu close
           68  +  } {}
           69  +
           70  +  do_test $tn.1.3 {
           71  +    run_rbu test.db rbu.db
           72  +    execsql { PRAGMA integrity_check }
           73  +  } {ok}
           74  +
           75  +  do_execsql_test $tn.1.4 {
           76  +    SELECT * FROM t1 ORDER BY %A%;
           77  +  } {
           78  +    1 10 {} b   7 8 4 d   10 11 12 e   13 14 {} f
           79  +  }
           80  +
           81  +  set step 0
           82  +  do_rbu_vacuum_test $tn.1.5 0
           83  +  }]
           84  +}
           85  +
           86  +finish_test

Changes to ext/rbu/sqlite3rbu.c.

   237    237   **
   238    238   ** abIndexed:
   239    239   **   If the table has no indexes on it, abIndexed is set to NULL. Otherwise,
   240    240   **   it points to an array of flags nTblCol elements in size. The flag is
   241    241   **   set for each column that is either a part of the PK or a part of an
   242    242   **   index. Or clear otherwise.
   243    243   **   
          244  +**   If there are one or more partial indexes on the table, all fields of
          245  +**   this array set set to 1. This is because in that case, the module has
          246  +**   no way to tell which fields will be required to add and remove entries
          247  +**   from the partial indexes.
          248  +**   
   244    249   */
   245    250   struct RbuObjIter {
   246    251     sqlite3_stmt *pTblIter;         /* Iterate through tables */
   247    252     sqlite3_stmt *pIdxIter;         /* Index iterator */
   248    253     int nTblCol;                    /* Size of azTblCol[] array */
   249    254     char **azTblCol;                /* Array of unquoted target column names */
   250    255     char **azTblType;               /* Array of target column types */
................................................................................
  1031   1036   **
  1032   1037   ** If an error (i.e. an OOM condition) occurs, return NULL and leave an 
  1033   1038   ** error code in the rbu handle passed as the first argument. Or, if an 
  1034   1039   ** error has already occurred when this function is called, return NULL 
  1035   1040   ** immediately without attempting the allocation or modifying the stored
  1036   1041   ** error code.
  1037   1042   */
  1038         -static void *rbuMalloc(sqlite3rbu *p, int nByte){
         1043  +static void *rbuMalloc(sqlite3rbu *p, sqlite3_int64 nByte){
  1039   1044     void *pRet = 0;
  1040   1045     if( p->rc==SQLITE_OK ){
  1041   1046       assert( nByte>0 );
  1042   1047       pRet = sqlite3_malloc64(nByte);
  1043   1048       if( pRet==0 ){
  1044   1049         p->rc = SQLITE_NOMEM;
  1045   1050       }else{
................................................................................
  1052   1057   
  1053   1058   /*
  1054   1059   ** Allocate and zero the pIter->azTblCol[] and abTblPk[] arrays so that
  1055   1060   ** there is room for at least nCol elements. If an OOM occurs, store an
  1056   1061   ** error code in the RBU handle passed as the first argument.
  1057   1062   */
  1058   1063   static void rbuAllocateIterArrays(sqlite3rbu *p, RbuObjIter *pIter, int nCol){
  1059         -  int nByte = (2*sizeof(char*) + sizeof(int) + 3*sizeof(u8)) * nCol;
         1064  +  sqlite3_int64 nByte = (2*sizeof(char*) + sizeof(int) + 3*sizeof(u8)) * nCol;
  1060   1065     char **azNew;
  1061   1066   
  1062   1067     azNew = (char**)rbuMalloc(p, nByte);
  1063   1068     if( azNew ){
  1064   1069       pIter->azTblCol = azNew;
  1065   1070       pIter->azTblType = &azNew[nCol];
  1066   1071       pIter->aiSrcOrder = (int*)&pIter->azTblType[nCol];
................................................................................
  1246   1251           sqlite3_mprintf("PRAGMA main.index_list = %Q", pIter->zTbl)
  1247   1252       );
  1248   1253     }
  1249   1254   
  1250   1255     pIter->nIndex = 0;
  1251   1256     while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pList) ){
  1252   1257       const char *zIdx = (const char*)sqlite3_column_text(pList, 1);
         1258  +    int bPartial = sqlite3_column_int(pList, 4);
  1253   1259       sqlite3_stmt *pXInfo = 0;
  1254   1260       if( zIdx==0 ) break;
         1261  +    if( bPartial ){
         1262  +      memset(pIter->abIndexed, 0x01, sizeof(u8)*pIter->nTblCol);
         1263  +    }
  1255   1264       p->rc = prepareFreeAndCollectError(p->dbMain, &pXInfo, &p->zErrmsg,
  1256   1265           sqlite3_mprintf("PRAGMA main.index_xinfo = %Q", zIdx)
  1257   1266       );
  1258   1267       while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pXInfo) ){
  1259   1268         int iCid = sqlite3_column_int(pXInfo, 1);
  1260   1269         if( iCid>=0 ) pIter->abIndexed[iCid] = 1;
  1261   1270       }
................................................................................
  1692   1701   ** string, an error code is left in the rbu handle passed as the first
  1693   1702   ** argument and NULL is returned. Or, if an error has already occurred
  1694   1703   ** when this function is called, NULL is returned immediately, without
  1695   1704   ** attempting the allocation or modifying the stored error code.
  1696   1705   */
  1697   1706   static char *rbuObjIterGetBindlist(sqlite3rbu *p, int nBind){
  1698   1707     char *zRet = 0;
  1699         -  int nByte = nBind*2 + 1;
         1708  +  sqlite3_int64 nByte = 2*(sqlite3_int64)nBind + 1;
  1700   1709   
  1701   1710     zRet = (char*)rbuMalloc(p, nByte);
  1702   1711     if( zRet ){
  1703   1712       int i;
  1704   1713       for(i=0; i<nBind; i++){
  1705   1714         zRet[i*2] = '?';
  1706   1715         zRet[i*2+1] = (i+1==nBind) ? '\0' : ',';
................................................................................
  1953   1962       rc = sqlite3_reset(p->objiter.pTmpInsert);
  1954   1963     }
  1955   1964   
  1956   1965     if( rc!=SQLITE_OK ){
  1957   1966       sqlite3_result_error_code(pCtx, rc);
  1958   1967     }
  1959   1968   }
         1969  +
         1970  +static char *rbuObjIterGetIndexWhere(sqlite3rbu *p, RbuObjIter *pIter){
         1971  +  sqlite3_stmt *pStmt = 0;
         1972  +  int rc = p->rc;
         1973  +  char *zRet = 0;
         1974  +
         1975  +  if( rc==SQLITE_OK ){
         1976  +    rc = prepareAndCollectError(p->dbMain, &pStmt, &p->zErrmsg,
         1977  +        "SELECT trim(sql) FROM sqlite_master WHERE type='index' AND name=?"
         1978  +    );
         1979  +  }
         1980  +  if( rc==SQLITE_OK ){
         1981  +    int rc2;
         1982  +    rc = sqlite3_bind_text(pStmt, 1, pIter->zIdx, -1, SQLITE_STATIC);
         1983  +    if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
         1984  +      const char *zSql = (const char*)sqlite3_column_text(pStmt, 0);
         1985  +      if( zSql ){
         1986  +        int nParen = 0;           /* Number of open parenthesis */
         1987  +        int i;
         1988  +        for(i=0; zSql[i]; i++){
         1989  +          char c = zSql[i];
         1990  +          if( c=='(' ){
         1991  +            nParen++;
         1992  +          }
         1993  +          else if( c==')' ){
         1994  +            nParen--;
         1995  +            if( nParen==0 ){
         1996  +              i++;
         1997  +              break;
         1998  +            }
         1999  +          }else if( c=='"' || c=='\'' || c=='`' ){
         2000  +            for(i++; 1; i++){
         2001  +              if( zSql[i]==c ){
         2002  +                if( zSql[i+1]!=c ) break;
         2003  +                i++;
         2004  +              }
         2005  +            }
         2006  +          }else if( c=='[' ){
         2007  +            for(i++; 1; i++){
         2008  +              if( zSql[i]==']' ) break;
         2009  +            }
         2010  +          }
         2011  +        }
         2012  +        if( zSql[i] ){
         2013  +          zRet = rbuStrndup(&zSql[i], &rc);
         2014  +        }
         2015  +      }
         2016  +    }
         2017  +
         2018  +    rc2 = sqlite3_finalize(pStmt);
         2019  +    if( rc==SQLITE_OK ) rc = rc2;
         2020  +  }
         2021  +
         2022  +  p->rc = rc;
         2023  +  return zRet;
         2024  +}
  1960   2025   
  1961   2026   /*
  1962   2027   ** Ensure that the SQLite statement handles required to update the 
  1963   2028   ** target database object currently indicated by the iterator passed 
  1964   2029   ** as the second argument are available.
  1965   2030   */
  1966   2031   static int rbuObjIterPrepareAll(
................................................................................
  1983   2048   
  1984   2049       if( zIdx ){
  1985   2050         const char *zTbl = pIter->zTbl;
  1986   2051         char *zImposterCols = 0;    /* Columns for imposter table */
  1987   2052         char *zImposterPK = 0;      /* Primary key declaration for imposter */
  1988   2053         char *zWhere = 0;           /* WHERE clause on PK columns */
  1989   2054         char *zBind = 0;
         2055  +      char *zPart = 0;
  1990   2056         int nBind = 0;
  1991   2057   
  1992   2058         assert( pIter->eType!=RBU_PK_VTAB );
  1993   2059         zCollist = rbuObjIterGetIndexCols(
  1994   2060             p, pIter, &zImposterCols, &zImposterPK, &zWhere, &nBind
  1995   2061         );
  1996   2062         zBind = rbuObjIterGetBindlist(p, nBind);
         2063  +      zPart = rbuObjIterGetIndexWhere(p, pIter);
  1997   2064   
  1998   2065         /* Create the imposter table used to write to this index. */
  1999   2066         sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 0, 1);
  2000   2067         sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->dbMain, "main", 1,tnum);
  2001   2068         rbuMPrintfExec(p, p->dbMain,
  2002   2069             "CREATE TABLE \"rbu_imp_%w\"( %s, PRIMARY KEY( %s ) ) WITHOUT ROWID",
  2003   2070             zTbl, zImposterCols, zImposterPK
................................................................................
  2022   2089         }
  2023   2090   
  2024   2091         /* Create the SELECT statement to read keys in sorted order */
  2025   2092         if( p->rc==SQLITE_OK ){
  2026   2093           char *zSql;
  2027   2094           if( rbuIsVacuum(p) ){
  2028   2095             zSql = sqlite3_mprintf(
  2029         -              "SELECT %s, 0 AS rbu_control FROM '%q' ORDER BY %s%s",
         2096  +              "SELECT %s, 0 AS rbu_control FROM '%q' %s ORDER BY %s%s",
  2030   2097                 zCollist, 
  2031   2098                 pIter->zDataTbl,
  2032         -              zCollist, zLimit
         2099  +              zPart, zCollist, zLimit
  2033   2100             );
  2034   2101           }else
  2035   2102   
  2036   2103           if( pIter->eType==RBU_PK_EXTERNAL || pIter->eType==RBU_PK_NONE ){
  2037   2104             zSql = sqlite3_mprintf(
  2038         -              "SELECT %s, rbu_control FROM %s.'rbu_tmp_%q' ORDER BY %s%s",
         2105  +              "SELECT %s, rbu_control FROM %s.'rbu_tmp_%q' %s ORDER BY %s%s",
  2039   2106                 zCollist, p->zStateDb, pIter->zDataTbl,
  2040         -              zCollist, zLimit
         2107  +              zPart, zCollist, zLimit
  2041   2108             );
  2042   2109           }else{
  2043   2110             zSql = sqlite3_mprintf(
  2044         -              "SELECT %s, rbu_control FROM %s.'rbu_tmp_%q' "
         2111  +              "SELECT %s, rbu_control FROM %s.'rbu_tmp_%q' %s "
  2045   2112                 "UNION ALL "
  2046   2113                 "SELECT %s, rbu_control FROM '%q' "
  2047         -              "WHERE typeof(rbu_control)='integer' AND rbu_control!=1 "
         2114  +              "%s %s typeof(rbu_control)='integer' AND rbu_control!=1 "
  2048   2115                 "ORDER BY %s%s",
  2049         -              zCollist, p->zStateDb, pIter->zDataTbl, 
         2116  +              zCollist, p->zStateDb, pIter->zDataTbl, zPart,
  2050   2117                 zCollist, pIter->zDataTbl, 
         2118  +              zPart,
         2119  +              (zPart ? "AND" : "WHERE"),
  2051   2120                 zCollist, zLimit
  2052   2121             );
  2053   2122           }
  2054   2123           p->rc = prepareFreeAndCollectError(p->dbRbu, &pIter->pSelect, pz, zSql);
  2055   2124         }
  2056   2125   
  2057   2126         sqlite3_free(zImposterCols);
  2058   2127         sqlite3_free(zImposterPK);
  2059   2128         sqlite3_free(zWhere);
  2060   2129         sqlite3_free(zBind);
         2130  +      sqlite3_free(zPart);
  2061   2131       }else{
  2062   2132         int bRbuRowid = (pIter->eType==RBU_PK_VTAB)
  2063   2133                       ||(pIter->eType==RBU_PK_NONE)
  2064   2134                       ||(pIter->eType==RBU_PK_EXTERNAL && rbuIsVacuum(p));
  2065   2135         const char *zTbl = pIter->zTbl;       /* Table this step applies to */
  2066   2136         const char *zWrite;                   /* Imposter table name */
  2067   2137   
................................................................................
  4487   4557   
  4488   4558     /* If not in RBU_STAGE_OAL, allow this call to pass through. Or, if this
  4489   4559     ** rbu is in the RBU_STAGE_OAL state, use heap memory for *-shm space 
  4490   4560     ** instead of a file on disk.  */
  4491   4561     assert( p->openFlags & (SQLITE_OPEN_MAIN_DB|SQLITE_OPEN_TEMP_DB) );
  4492   4562     if( eStage==RBU_STAGE_OAL || eStage==RBU_STAGE_MOVE ){
  4493   4563       if( iRegion<=p->nShm ){
  4494         -      int nByte = (iRegion+1) * sizeof(char*);
         4564  +      sqlite3_int64 nByte = (iRegion+1) * sizeof(char*);
  4495   4565         char **apNew = (char**)sqlite3_realloc64(p->apShm, nByte);
  4496   4566         if( apNew==0 ){
  4497   4567           rc = SQLITE_NOMEM;
  4498   4568         }else{
  4499   4569           memset(&apNew[p->nShm], 0, sizeof(char*) * (1 + iRegion - p->nShm));
  4500   4570           p->apShm = apNew;
  4501   4571           p->nShm = iRegion+1;

Changes to ext/rtree/geopoly.c.

   265    265        && s.a[0]==s.a[s.nVertex*2-2]
   266    266        && s.a[1]==s.a[s.nVertex*2-1]
   267    267        && (s.z++, geopolySkipSpace(&s)==0)
   268    268       ){
   269    269         GeoPoly *pOut;
   270    270         int x = 1;
   271    271         s.nVertex--;  /* Remove the redundant vertex at the end */
   272         -      pOut = sqlite3_malloc64( GEOPOLY_SZ(s.nVertex) );
          272  +      pOut = sqlite3_malloc64( GEOPOLY_SZ((sqlite3_int64)s.nVertex) );
   273    273         x = 1;
   274    274         if( pOut==0 ) goto parse_json_err;
   275    275         pOut->nVertex = s.nVertex;
   276    276         memcpy(pOut->a, s.a, s.nVertex*2*sizeof(GeoCoord));
   277    277         pOut->hdr[0] = *(unsigned char*)&x;
   278    278         pOut->hdr[1] = (s.nVertex>>16)&0xff;
   279    279         pOut->hdr[2] = (s.nVertex>>8)&0xff;
................................................................................
   651    651         r = GeoY(p,ii);
   652    652         if( r<mnY ) mnY = (float)r;
   653    653         else if( r>mxY ) mxY = (float)r;
   654    654       }
   655    655       if( pRc ) *pRc = SQLITE_OK;
   656    656       if( aCoord==0 ){
   657    657         geopolyBboxFill:
   658         -      pOut = sqlite3_realloc(p, GEOPOLY_SZ(4));
          658  +      pOut = sqlite3_realloc64(p, GEOPOLY_SZ(4));
   659    659         if( pOut==0 ){
   660    660           sqlite3_free(p);
   661    661           if( context ) sqlite3_result_error_nomem(context);
   662    662           if( pRc ) *pRc = SQLITE_NOMEM;
   663    663           return 0;
   664    664         }
   665    665         pOut->nVertex = 4;
................................................................................
  1047   1047     return p;
  1048   1048   }
  1049   1049   
  1050   1050   /*
  1051   1051   ** Determine the overlap between two polygons
  1052   1052   */
  1053   1053   static int geopolyOverlap(GeoPoly *p1, GeoPoly *p2){
  1054         -  int nVertex = p1->nVertex + p2->nVertex + 2;
         1054  +  sqlite3_int64 nVertex = p1->nVertex + p2->nVertex + 2;
  1055   1055     GeoOverlap *p;
  1056         -  int nByte;
         1056  +  sqlite3_int64 nByte;
  1057   1057     GeoEvent *pThisEvent;
  1058   1058     double rX;
  1059   1059     int rc = 0;
  1060   1060     int needSort = 0;
  1061   1061     GeoSegment *pActive = 0;
  1062   1062     GeoSegment *pSeg;
  1063   1063     unsigned char aOverlap[4];
  1064   1064   
  1065   1065     nByte = sizeof(GeoEvent)*nVertex*2 
  1066   1066              + sizeof(GeoSegment)*nVertex 
  1067   1067              + sizeof(GeoOverlap);
  1068         -  p = sqlite3_malloc( nByte );
         1068  +  p = sqlite3_malloc64( nByte );
  1069   1069     if( p==0 ) return -1;
  1070   1070     p->aEvent = (GeoEvent*)&p[1];
  1071   1071     p->aSegment = (GeoSegment*)&p->aEvent[nVertex*2];
  1072   1072     p->nEvent = p->nSegment = 0;
  1073   1073     geopolyAddSegments(p, p1, 1);
  1074   1074     geopolyAddSegments(p, p2, 2);
  1075   1075     pThisEvent = geopolySortEventsByX(p->aEvent, p->nEvent);
................................................................................
  1220   1220     int argc, const char *const*argv,   /* Parameters to CREATE TABLE statement */
  1221   1221     sqlite3_vtab **ppVtab,              /* OUT: New virtual table */
  1222   1222     char **pzErr,                       /* OUT: Error message, if any */
  1223   1223     int isCreate                        /* True for xCreate, false for xConnect */
  1224   1224   ){
  1225   1225     int rc = SQLITE_OK;
  1226   1226     Rtree *pRtree;
  1227         -  int nDb;              /* Length of string argv[1] */
  1228         -  int nName;            /* Length of string argv[2] */
         1227  +  sqlite3_int64 nDb;              /* Length of string argv[1] */
         1228  +  sqlite3_int64 nName;            /* Length of string argv[2] */
  1229   1229     sqlite3_str *pSql;
  1230   1230     char *zSql;
  1231   1231     int ii;
  1232   1232   
  1233   1233     sqlite3_vtab_config(db, SQLITE_VTAB_CONSTRAINT_SUPPORT, 1);
  1234   1234   
  1235   1235     /* Allocate the sqlite3_vtab structure */
  1236         -  nDb = (int)strlen(argv[1]);
  1237         -  nName = (int)strlen(argv[2]);
  1238         -  pRtree = (Rtree *)sqlite3_malloc(sizeof(Rtree)+nDb+nName+2);
         1236  +  nDb = strlen(argv[1]);
         1237  +  nName = strlen(argv[2]);
         1238  +  pRtree = (Rtree *)sqlite3_malloc64(sizeof(Rtree)+nDb+nName+2);
  1239   1239     if( !pRtree ){
  1240   1240       return SQLITE_NOMEM;
  1241   1241     }
  1242   1242     memset(pRtree, 0, sizeof(Rtree)+nDb+nName+2);
  1243   1243     pRtree->nBusy = 1;
  1244   1244     pRtree->base.pModule = &rtreeModule;
  1245   1245     pRtree->zDb = (char *)&pRtree[1];

Changes to ext/session/changesetfuzz.c.

   150    150     }
   151    151     fseek(f, 0, SEEK_END);
   152    152     sz = ftell(f);
   153    153     rewind(f);
   154    154     pBuf = sqlite3_malloc64( sz ? sz : 1 );
   155    155     if( pBuf==0 ){
   156    156       fprintf(stderr, "cannot allocate %d to hold content of \"%s\"\n",
   157         -            sz, zFilename);
          157  +            (int)sz, zFilename);
   158    158       exit(1);
   159    159     }
   160    160     if( sz>0 ){
   161         -    if( fread(pBuf, sz, 1, f)!=1 ){
   162         -      fprintf(stderr, "cannot read all %d bytes of \"%s\"\n", sz, zFilename);
          161  +    if( fread(pBuf, (size_t)sz, 1, f)!=1 ){
          162  +      fprintf(stderr, "cannot read all %d bytes of \"%s\"\n",
          163  +              (int)sz, zFilename);
   163    164         exit(1);
   164    165       }
   165    166       fclose(f);
   166    167     }
   167         -  *pSz = sz;
          168  +  *pSz = (int)sz;
   168    169     *ppBuf = pBuf;
   169    170   }
   170    171   
   171    172   /* 
   172    173   ** Write the contents of buffer pBuf, size nBuf bytes, into file zFilename
   173    174   ** on disk. zFilename, if it already exists, is clobbered.
   174    175   */
................................................................................
   339    340   
   340    341   /*
   341    342   ** Allocate and return nByte bytes of zeroed memory.
   342    343   */
   343    344   static void *fuzzMalloc(sqlite3_int64 nByte){
   344    345     void *pRet = sqlite3_malloc64(nByte);
   345    346     if( pRet ){
   346         -    memset(pRet, 0, nByte);
          347  +    memset(pRet, 0, (size_t)nByte);
   347    348     }
   348    349     return pRet;
   349    350   }
   350    351   
   351    352   /*
   352    353   ** Free the buffer indicated by the first argument. This function is used
   353    354   ** to free buffers allocated by fuzzMalloc().
................................................................................
   380    381   ** Write value nVal into the buffer indicated by argument p as an SQLite
   381    382   ** varint. nVal is guaranteed to be between 0 and (2^21-1), inclusive.
   382    383   ** Return the number of bytes written to buffer p.
   383    384   */
   384    385   static int fuzzPutVarint(u8 *p, int nVal){
   385    386     assert( nVal>0 && nVal<2097152 );
   386    387     if( nVal<128 ){
   387         -    p[0] = nVal;
          388  +    p[0] = (u8)nVal;
   388    389       return 1;
   389    390     }
   390    391     if( nVal<16384 ){
   391    392       p[0] = ((nVal >> 7) & 0x7F) | 0x80;
   392    393       p[1] = (nVal & 0x7F);
   393    394       return 2;
   394    395     }
................................................................................
   455    456         rc = fuzzCorrupt();
   456    457       }else{
   457    458         p++;
   458    459         p += fuzzGetVarint(p, &pGrp->nCol);
   459    460         pGrp->aPK = p;
   460    461         p += pGrp->nCol;
   461    462         pGrp->zTab = (const char*)p;
   462         -      p = &p[strlen(p)+1];
          463  +      p = &p[strlen((const char*)p)+1];
   463    464   
   464    465         if( p>=pEnd ){
   465    466           rc = fuzzCorrupt();
   466    467         }
   467    468       }
   468    469       *ppHdr = p;
   469    470     }
................................................................................
   691    692             p += 8;
   692    693             break;
   693    694           }
   694    695   
   695    696           case 0x03:                    /* text */
   696    697           case 0x04: {                  /* blob */
   697    698             int nTxt;
   698         -          int sz;
   699         -          int i;
   700    699             p += fuzzGetVarint(p, &nTxt);
   701    700             printf("%s%s", zPre, eType==0x03 ? "'" : "X'");
   702    701             for(i=0; i<nTxt; i++){
   703    702               if( eType==0x03 ){
   704    703                 printf("%c", p[i]);
   705    704               }else{
   706    705                 char aHex[16] = {'0', '1', '2', '3', '4', '5', '6', '7',
................................................................................
   855    854             fuzzPutU64(&pChange->aSub[1], iVal1);
   856    855             break;
   857    856           }
   858    857   
   859    858           case 0x03:                    /* text */
   860    859           case 0x04: {                  /* blob */
   861    860             int nByte = fuzzRandomInt(48);
   862         -          pChange->aSub[1] = nByte;
          861  +          pChange->aSub[1] = (u8)nByte;
   863    862             fuzzRandomBlob(nByte, &pChange->aSub[2]);
   864    863             if( pChange->aSub[0]==0x03 ){
   865    864               int i;
   866    865               for(i=0; i<nByte; i++){
   867    866                 pChange->aSub[2+i] &= 0x7F;
   868    867               }
   869    868             }
................................................................................
  1000    999         }
  1001   1000   
  1002   1001         if( p==pFuzz->pSub1 ){
  1003   1002           pCopy = pFuzz->pSub2;
  1004   1003         }else if( p==pFuzz->pSub2 ){
  1005   1004           pCopy = pFuzz->pSub1;
  1006   1005         }else if( i==iUndef ){
  1007         -        pCopy = "\0";
         1006  +        pCopy = (u8*)"\0";
  1008   1007         }
  1009   1008   
  1010   1009         if( pCopy[0]==0x00 && eNew!=eType && eType==SQLITE_UPDATE && iRec==0 ){
  1011   1010           while( pCopy[0]==0x00 ){
  1012   1011             pCopy = pParse->apVal[fuzzRandomInt(pParse->nVal)];
  1013   1012           }
  1014   1013         }else if( p[0]==0x00 && pCopy[0]!=0x00 ){
................................................................................
  1063   1062       }
  1064   1063       if( eNew!=eType && eNew==SQLITE_UPDATE && !bPS ){
  1065   1064         int i;
  1066   1065         u8 *pCsr = (*ppOut) + 2;
  1067   1066         for(i=0; i<pGrp->nCol; i++){
  1068   1067           int sz;
  1069   1068           u8 *pCopy = pCsr;
  1070         -        if( pGrp->aPK[i] ) pCopy = "\0";
         1069  +        if( pGrp->aPK[i] ) pCopy = (u8*)"\0";
  1071   1070           fuzzChangeSize(pCopy, &sz);
  1072   1071           memcpy(pOut, pCopy, sz);
  1073   1072           pOut += sz;
  1074   1073           fuzzChangeSize(pCsr, &sz);
  1075   1074           pCsr += sz;
  1076   1075         }
  1077   1076       }

Changes to ext/session/sqlite3session.c.

   905    905   ** Growing the hash table in this case is a performance optimization only,
   906    906   ** it is not required for correct operation.
   907    907   */
   908    908   static int sessionGrowHash(int bPatchset, SessionTable *pTab){
   909    909     if( pTab->nChange==0 || pTab->nEntry>=(pTab->nChange/2) ){
   910    910       int i;
   911    911       SessionChange **apNew;
   912         -    int nNew = (pTab->nChange ? pTab->nChange : 128) * 2;
          912  +    sqlite3_int64 nNew = 2*(sqlite3_int64)(pTab->nChange ? pTab->nChange : 128);
   913    913   
   914    914       apNew = (SessionChange **)sqlite3_malloc64(sizeof(SessionChange *) * nNew);
   915    915       if( apNew==0 ){
   916    916         if( pTab->nChange==0 ){
   917    917           return SQLITE_ERROR;
   918    918         }
   919    919         return SQLITE_OK;
................................................................................
  1832   1832   /*
  1833   1833   ** Ensure that there is room in the buffer to append nByte bytes of data.
  1834   1834   ** If not, use sqlite3_realloc() to grow the buffer so that there is.
  1835   1835   **
  1836   1836   ** If successful, return zero. Otherwise, if an OOM condition is encountered,
  1837   1837   ** set *pRc to SQLITE_NOMEM and return non-zero.
  1838   1838   */
  1839         -static int sessionBufferGrow(SessionBuffer *p, int nByte, int *pRc){
         1839  +static int sessionBufferGrow(SessionBuffer *p, size_t nByte, int *pRc){
  1840   1840     if( *pRc==SQLITE_OK && p->nAlloc-p->nBuf<nByte ){
  1841   1841       u8 *aNew;
  1842   1842       i64 nNew = p->nAlloc ? p->nAlloc : 128;
  1843   1843       do {
  1844   1844         nNew = nNew*2;
  1845   1845       }while( (nNew-p->nBuf)<nByte );
  1846   1846   
................................................................................
  2964   2964         sessionBufferGrow(&p->tblhdr, nByte, &rc);
  2965   2965       }else{
  2966   2966         rc = SQLITE_CORRUPT_BKPT;
  2967   2967       }
  2968   2968     }
  2969   2969   
  2970   2970     if( rc==SQLITE_OK ){
  2971         -    int iPK = sizeof(sqlite3_value*)*p->nCol*2;
         2971  +    size_t iPK = sizeof(sqlite3_value*)*p->nCol*2;
  2972   2972       memset(p->tblhdr.aBuf, 0, iPK);
  2973   2973       memcpy(&p->tblhdr.aBuf[iPK], &p->in.aData[p->in.iNext], nCopy);
  2974   2974       p->in.iNext += nCopy;
  2975   2975     }
  2976   2976   
  2977   2977     p->apValue = (sqlite3_value**)p->tblhdr.aBuf;
  2978   2978     p->abPK = (u8*)&p->apValue[p->nCol*2];
................................................................................
  3879   3879       if( rc!=SQLITE_ROW ) rc = sqlite3_reset(pSelect);
  3880   3880     }
  3881   3881   
  3882   3882     return rc;
  3883   3883   }
  3884   3884   
  3885   3885   /*
  3886         -** This function is called from within sqlite3changset_apply_v2() when
         3886  +** This function is called from within sqlite3changeset_apply_v2() when
  3887   3887   ** a conflict is encountered and resolved using conflict resolution
  3888   3888   ** mode eType (either SQLITE_CHANGESET_OMIT or SQLITE_CHANGESET_REPLACE)..
  3889   3889   ** It adds a conflict resolution record to the buffer in 
  3890   3890   ** SessionApplyCtx.rebase, which will eventually be returned to the caller
  3891   3891   ** of apply_v2() as the "rebase" buffer.
  3892   3892   **
  3893   3893   ** Return SQLITE_OK if successful, or an SQLite error code otherwise.
................................................................................
  4268   4268     while( pApply->constraints.nBuf ){
  4269   4269       sqlite3_changeset_iter *pIter2 = 0;
  4270   4270       SessionBuffer cons = pApply->constraints;
  4271   4271       memset(&pApply->constraints, 0, sizeof(SessionBuffer));
  4272   4272   
  4273   4273       rc = sessionChangesetStart(&pIter2, 0, 0, cons.nBuf, cons.aBuf, 0);
  4274   4274       if( rc==SQLITE_OK ){
  4275         -      int nByte = 2*pApply->nCol*sizeof(sqlite3_value*);
         4275  +      size_t nByte = 2*pApply->nCol*sizeof(sqlite3_value*);
  4276   4276         int rc2;
  4277   4277         pIter2->bPatchset = bPatchset;
  4278   4278         pIter2->zTab = (char*)zTab;
  4279   4279         pIter2->nCol = pApply->nCol;
  4280   4280         pIter2->abPK = pApply->abPK;
  4281   4281         sessionBufferGrow(&pIter2->tblhdr, nByte, &rc);
  4282   4282         pIter2->apValue = (sqlite3_value**)pIter2->tblhdr.aBuf;

Changes to ext/session/sqlite3session.h.

  1437   1437   ** CAPI3REF: Rebase a changeset
  1438   1438   ** EXPERIMENTAL
  1439   1439   **
  1440   1440   ** Argument pIn must point to a buffer containing a changeset nIn bytes
  1441   1441   ** in size. This function allocates and populates a buffer with a copy
  1442   1442   ** of the changeset rebased rebased according to the configuration of the
  1443   1443   ** rebaser object passed as the first argument. If successful, (*ppOut)
  1444         -** is set to point to the new buffer containing the rebased changset and 
         1444  +** is set to point to the new buffer containing the rebased changeset and 
  1445   1445   ** (*pnOut) to its size in bytes and SQLITE_OK returned. It is the
  1446   1446   ** responsibility of the caller to eventually free the new buffer using
  1447   1447   ** sqlite3_free(). Otherwise, if an error occurs, (*ppOut) and (*pnOut)
  1448   1448   ** are set to zero and an SQLite error code returned.
  1449   1449   */
  1450   1450   int sqlite3rebaser_rebase(
  1451   1451     sqlite3_rebaser*,

Changes to main.mk.

   344    344     $(TOP)/src/test_server.c \
   345    345     $(TOP)/src/test_sqllog.c \
   346    346     $(TOP)/src/test_superlock.c \
   347    347     $(TOP)/src/test_syscall.c \
   348    348     $(TOP)/src/test_tclsh.c \
   349    349     $(TOP)/src/test_tclvar.c \
   350    350     $(TOP)/src/test_thread.c \
          351  +  $(TOP)/src/test_vdbecov.c \
   351    352     $(TOP)/src/test_vfs.c \
   352    353     $(TOP)/src/test_windirent.c \
   353    354     $(TOP)/src/test_window.c \
   354    355     $(TOP)/src/test_wsd.c
   355    356   
   356    357   # Extensions to be statically loaded.
   357    358   #
................................................................................
   374    375     $(TOP)/ext/misc/regexp.c \
   375    376     $(TOP)/ext/misc/remember.c \
   376    377     $(TOP)/ext/misc/series.c \
   377    378     $(TOP)/ext/misc/spellfix.c \
   378    379     $(TOP)/ext/misc/totype.c \
   379    380     $(TOP)/ext/misc/unionvtab.c \
   380    381     $(TOP)/ext/misc/wholenumber.c \
   381         -  $(TOP)/ext/misc/vfslog.c \
   382    382     $(TOP)/ext/misc/zipfile.c \
   383    383     $(TOP)/ext/fts5/fts5_tcl.c \
   384    384     $(TOP)/ext/fts5/fts5_test_mi.c \
   385    385     $(TOP)/ext/fts5/fts5_test_tok.c
   386    386   
   387    387   
   388    388   #TESTSRC += $(TOP)/ext/fts2/fts2_tokenizer.c
................................................................................
   713    713   	cat parse.h $(TOP)/src/vdbe.c | \
   714    714   		tclsh $(TOP)/tool/mkopcodeh.tcl >opcodes.h
   715    715   
   716    716   # Rules to build parse.c and parse.h - the outputs of lemon.
   717    717   #
   718    718   parse.h:	parse.c
   719    719   
   720         -parse.c:	$(TOP)/src/parse.y lemon $(TOP)/tool/addopcodes.tcl
          720  +parse.c:	$(TOP)/src/parse.y lemon
   721    721   	cp $(TOP)/src/parse.y .
   722         -	rm -f parse.h
   723    722   	./lemon -s $(OPTS) parse.y
   724         -	mv parse.h parse.h.temp
   725         -	tclsh $(TOP)/tool/addopcodes.tcl parse.h.temp >parse.h
   726    723   
   727    724   sqlite3.h:	$(TOP)/src/sqlite.h.in $(TOP)/manifest mksourceid $(TOP)/VERSION $(TOP)/ext/rtree/sqlite3rtree.h
   728    725   	tclsh $(TOP)/tool/mksqlite3h.tcl $(TOP) >sqlite3.h
   729    726   
   730    727   keywordhash.h:	$(TOP)/tool/mkkeywordhash.c
   731    728   	$(BCC) -o mkkeywordhash $(OPTS) $(TOP)/tool/mkkeywordhash.c
   732    729   	./mkkeywordhash >keywordhash.h

Changes to src/btree.c.

  1062   1062   ** when saveCursorPosition() was called. Note that this call deletes the 
  1063   1063   ** saved position info stored by saveCursorPosition(), so there can be
  1064   1064   ** at most one effective restoreCursorPosition() call after each 
  1065   1065   ** saveCursorPosition().
  1066   1066   */
  1067   1067   static int btreeRestoreCursorPosition(BtCursor *pCur){
  1068   1068     int rc;
  1069         -  int skipNext;
         1069  +  int skipNext = 0;
  1070   1070     assert( cursorOwnsBtShared(pCur) );
  1071   1071     assert( pCur->eState>=CURSOR_REQUIRESEEK );
  1072   1072     if( pCur->eState==CURSOR_FAULT ){
  1073   1073       return pCur->skipNext;
  1074   1074     }
  1075   1075     pCur->eState = CURSOR_INVALID;
         1076  +  if( sqlite3FaultSim(410) ){
         1077  +    rc = SQLITE_IOERR;
         1078  +  }else{
  1076   1079     rc = btreeMoveto(pCur, pCur->pKey, pCur->nKey, 0, &skipNext);
         1080  +  }
  1077   1081     if( rc==SQLITE_OK ){
  1078   1082       sqlite3_free(pCur->pKey);
  1079   1083       pCur->pKey = 0;
  1080   1084       assert( pCur->eState==CURSOR_VALID || pCur->eState==CURSOR_INVALID );
  1081   1085       if( skipNext ) pCur->skipNext = skipNext;
  1082   1086       if( pCur->skipNext && pCur->eState==CURSOR_VALID ){
  1083   1087         pCur->eState = CURSOR_SKIPNEXT;
................................................................................
  1668   1672     /* This block handles pages with two or fewer free blocks and nMaxFrag
  1669   1673     ** or fewer fragmented bytes. In this case it is faster to move the
  1670   1674     ** two (or one) blocks of cells using memmove() and add the required
  1671   1675     ** offsets to each pointer in the cell-pointer array than it is to 
  1672   1676     ** reconstruct the entire page.  */
  1673   1677     if( (int)data[hdr+7]<=nMaxFrag ){
  1674   1678       int iFree = get2byte(&data[hdr+1]);
  1675         -
  1676         -    /* If the initial freeblock offset were out of bounds, that would have
  1677         -    ** been detected by btreeComputeFreeSpace() when it was computing the
  1678         -    ** number of free bytes on the page. */
  1679         -    assert( iFree<=usableSize-4 );
         1679  +    if( iFree>usableSize-4 ) return SQLITE_CORRUPT_PAGE(pPage);
  1680   1680       if( iFree ){
  1681   1681         int iFree2 = get2byte(&data[iFree]);
  1682   1682         if( iFree2>usableSize-4 ) return SQLITE_CORRUPT_PAGE(pPage);
  1683   1683         if( 0==iFree2 || (data[iFree2]==0 && data[iFree2+1]==0) ){
  1684   1684           u8 *pEnd = &data[cellOffset + nCell*2];
  1685   1685           u8 *pAddr;
  1686   1686           int sz2 = 0;
................................................................................
  5727   5727       assert( pCur->pgnoRoot==0 || pCur->pPage->nCell==0 );
  5728   5728       *pRes = 1;
  5729   5729       rc = SQLITE_OK;
  5730   5730     }
  5731   5731     return rc;
  5732   5732   }
  5733   5733   
  5734         -/*
  5735         -** This function is a no-op if cursor pCur does not point to a valid row.
  5736         -** Otherwise, if pCur is valid, configure it so that the next call to
  5737         -** sqlite3BtreeNext() is a no-op.
  5738         -*/
  5739         -#ifndef SQLITE_OMIT_WINDOWFUNC
  5740         -void sqlite3BtreeSkipNext(BtCursor *pCur){
  5741         -  /* We believe that the cursor must always be in the valid state when
  5742         -  ** this routine is called, but the proof is difficult, so we add an
  5743         -  ** ALWaYS() test just in case we are wrong. */
  5744         -  if( ALWAYS(pCur->eState==CURSOR_VALID) ){
  5745         -    pCur->eState = CURSOR_SKIPNEXT;
  5746         -    pCur->skipNext = 1;
  5747         -  }
  5748         -}
  5749         -#endif /* SQLITE_OMIT_WINDOWFUNC */
  5750         -
  5751   5734   /* Move the cursor to the last entry in the table.  Return SQLITE_OK
  5752   5735   ** on success.  Set *pRes to 0 if the cursor actually points to something
  5753   5736   ** or set *pRes to 1 if the table is empty.
  5754   5737   */
  5755   5738   int sqlite3BtreeLast(BtCursor *pCur, int *pRes){
  5756   5739     int rc;
  5757   5740    
................................................................................
  6651   6634   */
  6652   6635   static int freePage2(BtShared *pBt, MemPage *pMemPage, Pgno iPage){
  6653   6636     MemPage *pTrunk = 0;                /* Free-list trunk page */
  6654   6637     Pgno iTrunk = 0;                    /* Page number of free-list trunk page */ 
  6655   6638     MemPage *pPage1 = pBt->pPage1;      /* Local reference to page 1 */
  6656   6639     MemPage *pPage;                     /* Page being freed. May be NULL. */
  6657   6640     int rc;                             /* Return Code */
  6658         -  int nFree;                          /* Initial number of pages on free-list */
         6641  +  u32 nFree;                          /* Initial number of pages on free-list */
  6659   6642   
  6660   6643     assert( sqlite3_mutex_held(pBt->mutex) );
  6661   6644     assert( CORRUPT_DB || iPage>1 );
  6662   6645     assert( !pMemPage || pMemPage->pgno==iPage );
  6663   6646   
  6664   6647     if( iPage<2 || iPage>pBt->nPage ){
  6665   6648       return SQLITE_CORRUPT_BKPT;
................................................................................
  9298   9281   
  9299   9282     assert( cursorOwnsBtShared(pCur) );
  9300   9283     assert( pBt->inTransaction==TRANS_WRITE );
  9301   9284     assert( (pBt->btsFlags & BTS_READ_ONLY)==0 );
  9302   9285     assert( pCur->curFlags & BTCF_WriteFlag );
  9303   9286     assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) );
  9304   9287     assert( !hasReadConflicts(p, pCur->pgnoRoot) );
  9305         -  assert( pCur->ix<pCur->pPage->nCell );
  9306         -  assert( pCur->eState==CURSOR_VALID );
  9307   9288     assert( (flags & ~(BTREE_SAVEPOSITION | BTREE_AUXDELETE))==0 );
         9289  +  if( pCur->eState==CURSOR_REQUIRESEEK ){
         9290  +    rc = btreeRestoreCursorPosition(pCur);
         9291  +    if( rc ) return rc;
         9292  +  }
         9293  +  assert( pCur->eState==CURSOR_VALID );
  9308   9294   
  9309   9295     iCellDepth = pCur->iPage;
  9310   9296     iCellIdx = pCur->ix;
  9311   9297     pPage = pCur->pPage;
  9312   9298     pCell = findCell(pPage, iCellIdx);
  9313   9299     if( pPage->nFree<0 && btreeComputeFreeSpace(pPage) ) return SQLITE_CORRUPT;
  9314   9300   

Changes to src/btree.h.

   297    297     int nData;              /* Size of pData.  0 if none. */
   298    298     int nZero;              /* Extra zero data appended after pData,nData */
   299    299   };
   300    300   
   301    301   int sqlite3BtreeInsert(BtCursor*, const BtreePayload *pPayload,
   302    302                          int flags, int seekResult);
   303    303   int sqlite3BtreeFirst(BtCursor*, int *pRes);
   304         -#ifndef SQLITE_OMIT_WINDOWFUNC
   305         -void sqlite3BtreeSkipNext(BtCursor*);
   306         -#endif
   307    304   int sqlite3BtreeLast(BtCursor*, int *pRes);
   308    305   int sqlite3BtreeNext(BtCursor*, int flags);
   309    306   int sqlite3BtreeEof(BtCursor*);
   310    307   int sqlite3BtreePrevious(BtCursor*, int flags);
   311    308   i64 sqlite3BtreeIntegerKey(BtCursor*);
   312    309   #ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC
   313    310   i64 sqlite3BtreeOffset(BtCursor*);

Changes to src/build.c.

   262    262     zSql = sqlite3VMPrintf(db, zFormat, ap);
   263    263     va_end(ap);
   264    264     if( zSql==0 ){
   265    265       /* This can result either from an OOM or because the formatted string
   266    266       ** exceeds SQLITE_LIMIT_LENGTH.  In the latter case, we need to set
   267    267       ** an error */
   268    268       if( !db->mallocFailed ) pParse->rc = SQLITE_TOOBIG;
          269  +    pParse->nErr++;
   269    270       return;
   270    271     }
   271    272     pParse->nested++;
   272    273     memcpy(saveBuf, PARSE_TAIL(pParse), PARSE_TAIL_SZ);
   273    274     memset(PARSE_TAIL(pParse), 0, PARSE_TAIL_SZ);
   274    275     sqlite3RunParser(pParse, zSql, &zErrMsg);
   275    276     sqlite3DbFree(db, zErrMsg);
................................................................................
  3262   3263       pList = sqlite3ExprListAppend(pParse, 0,
  3263   3264                 sqlite3ExprAlloc(db, TK_ID, &prevCol, 0));
  3264   3265       if( pList==0 ) goto exit_create_index;
  3265   3266       assert( pList->nExpr==1 );
  3266   3267       sqlite3ExprListSetSortOrder(pList, sortOrder);
  3267   3268     }else{
  3268   3269       sqlite3ExprListCheckLength(pParse, pList, "index");
         3270  +    if( pParse->nErr ) goto exit_create_index;
  3269   3271     }
  3270   3272   
  3271   3273     /* Figure out how many bytes of space are required to store explicitly
  3272   3274     ** specified collation sequence names.
  3273   3275     */
  3274   3276     for(i=0; i<pList->nExpr; i++){
  3275   3277       Expr *pExpr = pList->a[i].pExpr;
................................................................................
  3280   3282     }
  3281   3283   
  3282   3284     /* 
  3283   3285     ** Allocate the index structure. 
  3284   3286     */
  3285   3287     nName = sqlite3Strlen30(zName);
  3286   3288     nExtraCol = pPk ? pPk->nKeyCol : 1;
         3289  +  assert( pList->nExpr + nExtraCol <= 32767 /* Fits in i16 */ );
  3287   3290     pIndex = sqlite3AllocateIndexObject(db, pList->nExpr + nExtraCol,
  3288   3291                                         nName + nExtra + 1, &zExtra);
  3289   3292     if( db->mallocFailed ){
  3290   3293       goto exit_create_index;
  3291   3294     }
  3292   3295     assert( EIGHT_BYTE_ALIGNMENT(pIndex->aiRowLogEst) );
  3293   3296     assert( EIGHT_BYTE_ALIGNMENT(pIndex->azColl) );
................................................................................
  3763   3766     sqlite3 *db,      /* Connection to notify of malloc failures */
  3764   3767     void *pArray,     /* Array of objects.  Might be reallocated */
  3765   3768     int szEntry,      /* Size of each object in the array */
  3766   3769     int *pnEntry,     /* Number of objects currently in use */
  3767   3770     int *pIdx         /* Write the index of a new slot here */
  3768   3771   ){
  3769   3772     char *z;
  3770         -  int n = *pnEntry;
         3773  +  sqlite3_int64 n = *pIdx = *pnEntry;
  3771   3774     if( (n & (n-1))==0 ){
  3772         -    int sz = (n==0) ? 1 : 2*n;
         3775  +    sqlite3_int64 sz = (n==0) ? 1 : 2*n;
  3773   3776       void *pNew = sqlite3DbRealloc(db, pArray, sz*szEntry);
  3774   3777       if( pNew==0 ){
  3775   3778         *pIdx = -1;
  3776   3779         return pArray;
  3777   3780       }
  3778   3781       pArray = pNew;
  3779   3782     }
  3780   3783     z = (char*)pArray;
  3781   3784     memset(&z[n * szEntry], 0, szEntry);
  3782         -  *pIdx = n;
  3783   3785     ++*pnEntry;
  3784   3786     return pArray;
  3785   3787   }
  3786   3788   
  3787   3789   /*
  3788   3790   ** Append a new element to the given IdList.  Create a new IdList if
  3789   3791   ** need be.
................................................................................
  3886   3888     assert( nExtra>=1 );
  3887   3889     assert( pSrc!=0 );
  3888   3890     assert( iStart<=pSrc->nSrc );
  3889   3891   
  3890   3892     /* Allocate additional space if needed */
  3891   3893     if( (u32)pSrc->nSrc+nExtra>pSrc->nAlloc ){
  3892   3894       SrcList *pNew;
  3893         -    int nAlloc = pSrc->nSrc*2+nExtra;
         3895  +    sqlite3_int64 nAlloc = 2*(sqlite3_int64)pSrc->nSrc+nExtra;
  3894   3896       sqlite3 *db = pParse->db;
  3895   3897   
  3896   3898       if( pSrc->nSrc+nExtra>=SQLITE_MAX_SRCLIST ){
  3897   3899         sqlite3ErrorMsg(pParse, "too many FROM clause terms, max: %d",
  3898   3900                         SQLITE_MAX_SRCLIST);
  3899   3901         return 0;
  3900   3902       }
................................................................................
  4393   4395     Index *pIdx       /* The index that triggers the constraint */
  4394   4396   ){
  4395   4397     char *zErr;
  4396   4398     int j;
  4397   4399     StrAccum errMsg;
  4398   4400     Table *pTab = pIdx->pTable;
  4399   4401   
  4400         -  sqlite3StrAccumInit(&errMsg, pParse->db, 0, 0, 200);
         4402  +  sqlite3StrAccumInit(&errMsg, pParse->db, 0, 0, 
         4403  +                      pParse->db->aLimit[SQLITE_LIMIT_LENGTH]);
  4401   4404     if( pIdx->aColExpr ){
  4402   4405       sqlite3_str_appendf(&errMsg, "index '%q'", pIdx->zName);
  4403   4406     }else{
  4404   4407       for(j=0; j<pIdx->nKeyCol; j++){
  4405   4408         char *zCol;
  4406   4409         assert( pIdx->aiColumn[j]>=0 );
  4407   4410         zCol = pTab->aCol[pIdx->aiColumn[j]].zName;
................................................................................
  4642   4645         if( sqlite3StrICmp(zName, pWith->a[i].zName)==0 ){
  4643   4646           sqlite3ErrorMsg(pParse, "duplicate WITH table name: %s", zName);
  4644   4647         }
  4645   4648       }
  4646   4649     }
  4647   4650   
  4648   4651     if( pWith ){
  4649         -    int nByte = sizeof(*pWith) + (sizeof(pWith->a[1]) * pWith->nCte);
         4652  +    sqlite3_int64 nByte = sizeof(*pWith) + (sizeof(pWith->a[1]) * pWith->nCte);
  4650   4653       pNew = sqlite3DbRealloc(db, pWith, nByte);
  4651   4654     }else{
  4652   4655       pNew = sqlite3DbMallocZero(db, sizeof(*pWith));
  4653   4656     }
  4654   4657     assert( (pNew!=0 && zName!=0) || db->mallocFailed );
  4655   4658   
  4656   4659     if( db->mallocFailed ){

Changes to src/expr.c.

   853    853     if( op==TK_AND && pParse->nErr==0 && !IN_RENAME_OBJECT ){
   854    854       /* Take advantage of short-circuit false optimization for AND */
   855    855       p = sqlite3ExprAnd(pParse->db, pLeft, pRight);
   856    856     }else{
   857    857       p = sqlite3DbMallocRawNN(pParse->db, sizeof(Expr));
   858    858       if( p ){
   859    859         memset(p, 0, sizeof(Expr));
   860         -      p->op = op & TKFLG_MASK;
          860  +      p->op = op & 0xff;
   861    861         p->iAgg = -1;
   862    862       }
   863    863       sqlite3ExprAttachSubtrees(pParse->db, p, pLeft, pRight);
   864    864     }
   865    865     if( p ) {
   866    866       sqlite3ExprCheckHeight(pParse, p->nHeight);
   867    867     }
................................................................................
  1318   1318   ** argument. If an OOM condition is encountered, NULL is returned
  1319   1319   ** and the db->mallocFailed flag set.
  1320   1320   */
  1321   1321   #ifndef SQLITE_OMIT_CTE
  1322   1322   static With *withDup(sqlite3 *db, With *p){
  1323   1323     With *pRet = 0;
  1324   1324     if( p ){
  1325         -    int nByte = sizeof(*p) + sizeof(p->a[0]) * (p->nCte-1);
         1325  +    sqlite3_int64 nByte = sizeof(*p) + sizeof(p->a[0]) * (p->nCte-1);
  1326   1326       pRet = sqlite3DbMallocZero(db, nByte);
  1327   1327       if( pRet ){
  1328   1328         int i;
  1329   1329         pRet->nCte = p->nCte;
  1330   1330         for(i=0; i<p->nCte; i++){
  1331   1331           pRet->a[i].pSelect = sqlite3SelectDup(db, p->a[i].pSelect, 0);
  1332   1332           pRet->a[i].pCols = sqlite3ExprListDup(db, p->a[i].pCols, 0);
................................................................................
  1583   1583       if( pList==0 ){
  1584   1584         goto no_mem;
  1585   1585       }
  1586   1586       pList->nExpr = 0;
  1587   1587     }else if( (pList->nExpr & (pList->nExpr-1))==0 ){
  1588   1588       ExprList *pNew;
  1589   1589       pNew = sqlite3DbRealloc(db, pList, 
  1590         -             sizeof(*pList)+(2*pList->nExpr - 1)*sizeof(pList->a[0]));
         1590  +         sizeof(*pList)+(2*(sqlite3_int64)pList->nExpr-1)*sizeof(pList->a[0]));
  1591   1591       if( pNew==0 ){
  1592   1592         goto no_mem;
  1593   1593       }
  1594   1594       pList = pNew;
  1595   1595     }
  1596   1596     pItem = &pList->a[pList->nExpr++];
  1597   1597     assert( offsetof(struct ExprList_item,zName)==sizeof(pItem->pExpr) );
................................................................................
  5028   5028   ** an ordinary JOIN.  The p argument is the WHERE clause.  If the WHERE
  5029   5029   ** clause requires that some column of the right table of the LEFT JOIN
  5030   5030   ** be non-NULL, then the LEFT JOIN can be safely converted into an
  5031   5031   ** ordinary join.
  5032   5032   */
  5033   5033   int sqlite3ExprImpliesNonNullRow(Expr *p, int iTab){
  5034   5034     Walker w;
         5035  +  p = sqlite3ExprSkipCollate(p);
         5036  +  while( p ){
         5037  +    if( p->op==TK_NOTNULL ){
         5038  +      p = p->pLeft;
         5039  +    }else if( p->op==TK_AND ){
         5040  +      if( sqlite3ExprImpliesNonNullRow(p->pLeft, iTab) ) return 1;
         5041  +      p = p->pRight;
         5042  +    }else{
         5043  +      break;
         5044  +    }
         5045  +  }
  5035   5046     w.xExprCallback = impliesNotNullRow;
  5036   5047     w.xSelectCallback = 0;
  5037   5048     w.xSelectCallback2 = 0;
  5038   5049     w.eCode = 0;
  5039   5050     w.u.iCur = iTab;
  5040   5051     sqlite3WalkExpr(&w, p);
  5041   5052     return w.eCode;

Changes to src/hash.c.

   146    146   */
   147    147   static HashElem *findElementWithHash(
   148    148     const Hash *pH,     /* The pH to be searched */
   149    149     const char *pKey,   /* The key we are searching for */
   150    150     unsigned int *pHash /* Write the hash value here */
   151    151   ){
   152    152     HashElem *elem;                /* Used to loop thru the element list */
   153         -  int count;                     /* Number of elements left to test */
          153  +  unsigned int count;            /* Number of elements left to test */
   154    154     unsigned int h;                /* The computed hash */
   155    155     static HashElem nullElement = { 0, 0, 0, 0 };
   156    156   
   157    157     if( pH->ht ){   /*OPTIMIZATION-IF-TRUE*/
   158    158       struct _ht *pEntry;
   159    159       h = strHash(pKey) % pH->htsize;
   160    160       pEntry = &pH->ht[h];
................................................................................
   194    194       elem->next->prev = elem->prev;
   195    195     }
   196    196     if( pH->ht ){
   197    197       pEntry = &pH->ht[h];
   198    198       if( pEntry->chain==elem ){
   199    199         pEntry->chain = elem->next;
   200    200       }
          201  +    assert( pEntry->count>0 );
   201    202       pEntry->count--;
   202         -    assert( pEntry->count>=0 );
   203    203     }
   204    204     sqlite3_free( elem );
   205    205     pH->count--;
   206    206     if( pH->count==0 ){
   207    207       assert( pH->first==0 );
   208    208       assert( pH->count==0 );
   209    209       sqlite3HashClear(pH);

Changes to src/hash.h.

    41     41   ** the hash table.
    42     42   */
    43     43   struct Hash {
    44     44     unsigned int htsize;      /* Number of buckets in the hash table */
    45     45     unsigned int count;       /* Number of entries in this table */
    46     46     HashElem *first;          /* The first element of the array */
    47     47     struct _ht {              /* the hash table */
    48         -    int count;                 /* Number of entries with this hash */
           48  +    unsigned int count;        /* Number of entries with this hash */
    49     49       HashElem *chain;           /* Pointer to first entry with this hash */
    50     50     } *ht;
    51     51   };
    52     52   
    53     53   /* Each element in the hash table is an instance of the following 
    54     54   ** structure.  All elements are stored on a single doubly-linked list.
    55     55   **

Changes to src/insert.c.

  2271   2271       }
  2272   2272       for(pSrcIdx=pSrc->pIndex; pSrcIdx; pSrcIdx=pSrcIdx->pNext){
  2273   2273         if( xferCompatibleIndex(pDestIdx, pSrcIdx) ) break;
  2274   2274       }
  2275   2275       if( pSrcIdx==0 ){
  2276   2276         return 0;    /* pDestIdx has no corresponding index in pSrc */
  2277   2277       }
         2278  +    if( pSrcIdx->tnum==pDestIdx->tnum && pSrc->pSchema==pDest->pSchema
         2279  +         && sqlite3FaultSim(411)==SQLITE_OK ){
         2280  +      /* The sqlite3FaultSim() call allows this corruption test to be
         2281  +      ** bypassed during testing, in order to exercise other corruption tests
         2282  +      ** further downstream. */
         2283  +      return 0;   /* Corrupt schema - two indexes on the same btree */
         2284  +    }
  2278   2285     }
  2279   2286   #ifndef SQLITE_OMIT_CHECK
  2280   2287     if( pDest->pCheck && sqlite3ExprListCompare(pSrc->pCheck,pDest->pCheck,-1) ){
  2281   2288       return 0;   /* Tables have different CHECK constraints.  Ticket #2252 */
  2282   2289     }
  2283   2290   #endif
  2284   2291   #ifndef SQLITE_OMIT_FOREIGN_KEY
................................................................................
  2348   2355         addr1 = sqlite3VdbeAddOp2(v, OP_Rowid, iSrc, regRowid);
  2349   2356         sqlite3VdbeVerifyAbortable(v, onError);
  2350   2357         addr2 = sqlite3VdbeAddOp3(v, OP_NotExists, iDest, 0, regRowid);
  2351   2358         VdbeCoverage(v);
  2352   2359         sqlite3RowidConstraint(pParse, onError, pDest);
  2353   2360         sqlite3VdbeJumpHere(v, addr2);
  2354   2361         autoIncStep(pParse, regAutoinc, regRowid);
  2355         -    }else if( pDest->pIndex==0 && !(db->mDbFlags & DBFLAG_Vacuum) ){
         2362  +    }else if( pDest->pIndex==0 && !(db->mDbFlags & DBFLAG_VacuumInto) ){
  2356   2363         addr1 = sqlite3VdbeAddOp2(v, OP_NewRowid, iDest, regRowid);
  2357   2364       }else{
  2358   2365         addr1 = sqlite3VdbeAddOp2(v, OP_Rowid, iSrc, regRowid);
  2359   2366         assert( (pDest->tabFlags & TF_Autoincrement)==0 );
  2360   2367       }
  2361   2368       sqlite3VdbeAddOp3(v, OP_RowData, iSrc, regData, 1);
  2362   2369       if( db->mDbFlags & DBFLAG_Vacuum ){

Changes to src/loadext.c.

   451    451     sqlite3_str_errcode,
   452    452     sqlite3_str_length,
   453    453     sqlite3_str_value,
   454    454     /* Version 3.25.0 and later */
   455    455     sqlite3_create_window_function,
   456    456     /* Version 3.26.0 and later */
   457    457   #ifdef SQLITE_ENABLE_NORMALIZE
   458         -  sqlite3_normalized_sql
          458  +  sqlite3_normalized_sql,
   459    459   #else
   460         -  0
          460  +  0,
   461    461   #endif
          462  +  /* Version 3.28.0 and later */
          463  +  sqlite3_stmt_isexplain,
          464  +  sqlite3_value_frombind
   462    465   };
   463    466   
   464    467   /*
   465    468   ** Attempt to load an SQLite extension library contained in the file
   466    469   ** zFile.  The entry point is zProc.  zProc may be 0 in which case a
   467    470   ** default entry point name (sqlite3_extension_init) is used.  Use
   468    471   ** of the default name is recommended.

Changes to src/main.c.

   701    701     if( sz<=(int)sizeof(LookasideSlot*) ) sz = 0;
   702    702     if( cnt<0 ) cnt = 0;
   703    703     if( sz==0 || cnt==0 ){
   704    704       sz = 0;
   705    705       pStart = 0;
   706    706     }else if( pBuf==0 ){
   707    707       sqlite3BeginBenignMalloc();
   708         -    pStart = sqlite3Malloc( sz*cnt );  /* IMP: R-61949-35727 */
          708  +    pStart = sqlite3Malloc( sz*(sqlite3_int64)cnt );  /* IMP: R-61949-35727 */
   709    709       sqlite3EndBenignMalloc();
   710    710       if( pStart ) cnt = sqlite3MallocSize(pStart)/sz;
   711    711     }else{
   712    712       pStart = pBuf;
   713    713     }
   714    714     db->lookaside.pStart = pStart;
   715    715     db->lookaside.pInit = 0;

Changes to src/parse.y.

   205    205   columnlist ::= columnname carglist.
   206    206   columnname(A) ::= nm(A) typetoken(Y). {sqlite3AddColumn(pParse,&A,&Y);}
   207    207   
   208    208   // Declare some tokens early in order to influence their values, to 
   209    209   // improve performance and reduce the executable size.  The goal here is
   210    210   // to get the "jump" operations in ISNULL through ESCAPE to have numeric
   211    211   // values that are early enough so that all jump operations are clustered
   212         -// at the beginning, but also so that the comparison tokens NE through GE
   213         -// are as large as possible so that they are near to FUNCTION, which is a
   214         -// token synthesized by addopcodes.tcl.
          212  +// at the beginning.
   215    213   //
   216    214   %token ABORT ACTION AFTER ANALYZE ASC ATTACH BEFORE BEGIN BY CASCADE CAST.
   217    215   %token CONFLICT DATABASE DEFERRED DESC DETACH EACH END EXCLUSIVE EXPLAIN FAIL.
   218    216   %token OR AND NOT IS MATCH LIKE_KW BETWEEN IN ISNULL NOTNULL NE EQ.
   219    217   %token GT LE LT GE ESCAPE.
   220    218   
   221    219   // The following directive causes tokens ABORT, AFTER, ASC, etc. to
................................................................................
   230    228     QUERY KEY OF OFFSET PRAGMA RAISE RECURSIVE RELEASE REPLACE RESTRICT ROW ROWS
   231    229     ROLLBACK SAVEPOINT TEMP TRIGGER VACUUM VIEW VIRTUAL WITH WITHOUT
   232    230   %ifdef SQLITE_OMIT_COMPOUND_SELECT
   233    231     EXCEPT INTERSECT UNION
   234    232   %endif SQLITE_OMIT_COMPOUND_SELECT
   235    233   %ifndef SQLITE_OMIT_WINDOWFUNC
   236    234     CURRENT FOLLOWING PARTITION PRECEDING RANGE UNBOUNDED
          235  +  EXCLUDE GROUPS OTHERS TIES
   237    236   %endif SQLITE_OMIT_WINDOWFUNC
   238    237     REINDEX RENAME CTIME_KW IF
   239    238     .
   240    239   %wildcard ANY.
   241    240   
   242    241   // Define operator precedence early so that this is the first occurrence
   243    242   // of the operator tokens in the grammer.  Keeping the operators together
................................................................................
  1644   1643   //
  1645   1644   %ifndef SQLITE_OMIT_WINDOWFUNC
  1646   1645   %type windowdefn_list {Window*}
  1647   1646   %destructor windowdefn_list {sqlite3WindowListDelete(pParse->db, $$);}
  1648   1647   windowdefn_list(A) ::= windowdefn(Z). { A = Z; }
  1649   1648   windowdefn_list(A) ::= windowdefn_list(Y) COMMA windowdefn(Z). {
  1650   1649     assert( Z!=0 );
         1650  +  sqlite3WindowChain(pParse, Z, Y);
  1651   1651     Z->pNextWin = Y;
  1652   1652     A = Z;
  1653   1653   }
  1654   1654   
  1655   1655   %type windowdefn {Window*}
  1656   1656   %destructor windowdefn {sqlite3WindowDelete(pParse->db, $$);}
  1657         -windowdefn(A) ::= nm(X) AS window(Y). {
         1657  +windowdefn(A) ::= nm(X) AS LP window(Y) RP. {
  1658   1658     if( ALWAYS(Y) ){
  1659   1659       Y->zName = sqlite3DbStrNDup(pParse->db, X.z, X.n);
  1660   1660     }
  1661   1661     A = Y;
  1662   1662   }
  1663   1663   
  1664   1664   %type window {Window*}
................................................................................
  1678   1678   %type frame_bound {struct FrameBound}
  1679   1679   %destructor frame_bound {sqlite3ExprDelete(pParse->db, $$.pExpr);}
  1680   1680   %type frame_bound_s {struct FrameBound}
  1681   1681   %destructor frame_bound_s {sqlite3ExprDelete(pParse->db, $$.pExpr);}
  1682   1682   %type frame_bound_e {struct FrameBound}
  1683   1683   %destructor frame_bound_e {sqlite3ExprDelete(pParse->db, $$.pExpr);}
  1684   1684   
  1685         -window(A) ::= LP part_opt(X) orderby_opt(Y) frame_opt(Z) RP. {
         1685  +window(A) ::= PARTITION BY nexprlist(X) orderby_opt(Y) frame_opt(Z). {
         1686  +  A = sqlite3WindowAssemble(pParse, Z, X, Y, 0);
         1687  +}
         1688  +window(A) ::= nm(W) PARTITION BY nexprlist(X) orderby_opt(Y) frame_opt(Z). {
         1689  +  A = sqlite3WindowAssemble(pParse, Z, X, Y, &W);
         1690  +}
         1691  +window(A) ::= ORDER BY sortlist(Y) frame_opt(Z). {
         1692  +  A = sqlite3WindowAssemble(pParse, Z, 0, Y, 0);
         1693  +}
         1694  +window(A) ::= nm(W) ORDER BY sortlist(Y) frame_opt(Z). {
         1695  +  A = sqlite3WindowAssemble(pParse, Z, 0, Y, &W);
         1696  +}
         1697  +window(A) ::= frame_opt(Z). {
  1686   1698     A = Z;
  1687         -  if( ALWAYS(A) ){
  1688         -    A->pPartition = X;
  1689         -    A->pOrderBy = Y;
  1690   1699     }
         1700  +window(A) ::= nm(W) frame_opt(Z). {
         1701  +  A = sqlite3WindowAssemble(pParse, Z, 0, 0, &W);
  1691   1702   }
  1692   1703   
  1693         -part_opt(A) ::= PARTITION BY nexprlist(X). { A = X; }
  1694         -part_opt(A) ::= .                          { A = 0; }
  1695         -
  1696   1704   frame_opt(A) ::= .                             { 
  1697         -  A = sqlite3WindowAlloc(pParse, TK_RANGE, TK_UNBOUNDED, 0, TK_CURRENT, 0);
         1705  +  A = sqlite3WindowAlloc(pParse, 0, TK_UNBOUNDED, 0, TK_CURRENT, 0, 0);
  1698   1706   }
  1699         -frame_opt(A) ::= range_or_rows(X) frame_bound_s(Y). { 
  1700         -  A = sqlite3WindowAlloc(pParse, X, Y.eType, Y.pExpr, TK_CURRENT, 0);
         1707  +frame_opt(A) ::= range_or_rows(X) frame_bound_s(Y) frame_exclude_opt(Z). { 
         1708  +  A = sqlite3WindowAlloc(pParse, X, Y.eType, Y.pExpr, TK_CURRENT, 0, Z);
  1701   1709   }
  1702         -frame_opt(A) ::= range_or_rows(X) BETWEEN frame_bound_s(Y) AND frame_bound_e(Z). { 
  1703         -  A = sqlite3WindowAlloc(pParse, X, Y.eType, Y.pExpr, Z.eType, Z.pExpr);
         1710  +frame_opt(A) ::= range_or_rows(X) BETWEEN frame_bound_s(Y) AND
         1711  +                          frame_bound_e(Z) frame_exclude_opt(W). { 
         1712  +  A = sqlite3WindowAlloc(pParse, X, Y.eType, Y.pExpr, Z.eType, Z.pExpr, W);
  1704   1713   }
  1705   1714   
  1706         -range_or_rows(A) ::= RANGE.   { A = TK_RANGE; }
  1707         -range_or_rows(A) ::= ROWS.    { A = TK_ROWS;  }
  1708         -
         1715  +range_or_rows(A) ::= RANGE|ROWS|GROUPS(X).   {A = @X; /*A-overwrites-X*/}
  1709   1716   
  1710   1717   frame_bound_s(A) ::= frame_bound(X). { A = X; }
  1711         -frame_bound_s(A) ::= UNBOUNDED PRECEDING. {A.eType = TK_UNBOUNDED; A.pExpr = 0;}
         1718  +frame_bound_s(A) ::= UNBOUNDED(X) PRECEDING. {A.eType = @X; A.pExpr = 0;}
  1712   1719   frame_bound_e(A) ::= frame_bound(X). { A = X; }
  1713         -frame_bound_e(A) ::= UNBOUNDED FOLLOWING. {A.eType = TK_UNBOUNDED; A.pExpr = 0;}
         1720  +frame_bound_e(A) ::= UNBOUNDED(X) FOLLOWING. {A.eType = @X; A.pExpr = 0;}
         1721  +
         1722  +frame_bound(A) ::= expr(X) PRECEDING|FOLLOWING(Y).
         1723  +                                             {A.eType = @Y; A.pExpr = X;}
         1724  +frame_bound(A) ::= CURRENT(X) ROW.           {A.eType = @X; A.pExpr = 0;}
         1725  +
         1726  +%type frame_exclude_opt {u8}
         1727  +frame_exclude_opt(A) ::= . {A = 0;}
         1728  +frame_exclude_opt(A) ::= EXCLUDE frame_exclude(X). {A = X;}
  1714   1729   
  1715         -frame_bound(A) ::= expr(X) PRECEDING.   { A.eType = TK_PRECEDING; A.pExpr = X; }
  1716         -frame_bound(A) ::= CURRENT ROW.         { A.eType = TK_CURRENT  ; A.pExpr = 0; }
  1717         -frame_bound(A) ::= expr(X) FOLLOWING.   { A.eType = TK_FOLLOWING; A.pExpr = X; }
         1730  +%type frame_exclude {u8}
         1731  +frame_exclude(A) ::= NO(X) OTHERS.   {A = @X; /*A-overwrites-X*/}
         1732  +frame_exclude(A) ::= CURRENT(X) ROW. {A = @X; /*A-overwrites-X*/}
         1733  +frame_exclude(A) ::= GROUP|TIES(X).  {A = @X; /*A-overwrites-X*/}
         1734  +
  1718   1735   
  1719   1736   %type window_clause {Window*}
  1720   1737   %destructor window_clause {sqlite3WindowListDelete(pParse->db, $$);}
  1721   1738   window_clause(A) ::= WINDOW windowdefn_list(B). { A = B; }
  1722   1739   
  1723   1740   %type over_clause {Window*}
  1724   1741   %destructor over_clause {sqlite3WindowDelete(pParse->db, $$);}
  1725         -over_clause(A) ::= filter_opt(W) OVER window(Z). {
         1742  +over_clause(A) ::= filter_opt(W) OVER LP window(Z) RP. {
  1726   1743     A = Z;
  1727   1744     assert( A!=0 );
  1728   1745     A->pFilter = W;
  1729   1746   }
  1730   1747   over_clause(A) ::= filter_opt(W) OVER nm(Z). {
  1731   1748     A = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window));
  1732   1749     if( A ){
................................................................................
  1736   1753       sqlite3ExprDelete(pParse->db, W);
  1737   1754     }
  1738   1755   }
  1739   1756   
  1740   1757   filter_opt(A) ::= .                            { A = 0; }
  1741   1758   filter_opt(A) ::= FILTER LP WHERE expr(X) RP.  { A = X; }
  1742   1759   %endif /* SQLITE_OMIT_WINDOWFUNC */
         1760  +
         1761  +/*
         1762  +** The code generator needs some extra TK_ token values for tokens that
         1763  +** are synthesized and do not actually appear in the grammar:
         1764  +*/
         1765  +%token
         1766  +  TRUEFALSE       /* True or false keyword */
         1767  +  ISNOT           /* Combination of IS and NOT */
         1768  +  FUNCTION        /* A function invocation */
         1769  +  COLUMN          /* Reference to a table column */
         1770  +  AGG_FUNCTION    /* An aggregate function */
         1771  +  AGG_COLUMN      /* An aggregated column */
         1772  +  UMINUS          /* Unary minus */
         1773  +  UPLUS           /* Unary plus */
         1774  +  TRUTH           /* IS TRUE or IS FALSE or IS NOT TRUE or IS NOT FALSE */
         1775  +  REGISTER        /* Reference to a VDBE register */
         1776  +  CONCURRENT      /* BEGIN CONCURRENT */
         1777  +  VECTOR          /* Vector */
         1778  +  SELECT_COLUMN   /* Choose a single column from a multi-column SELECT */
         1779  +  IF_NULL_ROW     /* the if-null-row operator */
         1780  +  ASTERISK        /* The "*" in count(*) and similar */
         1781  +  SPAN            /* The span operator */
         1782  +.
         1783  +/* There must be no more than 255 tokens defined above.  If this grammar
         1784  +** is extended with new rules and tokens, they must either be so few in
         1785  +** number that TK_SPAN is no more than 255, or else the new tokens must
         1786  +** appear after this line.
         1787  +*/
         1788  +%include {
         1789  +#if TK_SPAN>255
         1790  +# error too many tokens in the grammar
         1791  +#endif
         1792  +}
         1793  +
         1794  +/*
         1795  +** The TK_SPACE and TK_ILLEGAL tokens must be the last two tokens.  The
         1796  +** parser depends on this.  Those tokens are not used in any grammar rule.
         1797  +** They are only used by the tokenizer.  Declare them last so that they
         1798  +** are guaranteed to be the last two tokens
         1799  +*/
         1800  +%token SPACE ILLEGAL.

Changes to src/pcache1.c.

   485    485   
   486    486   /*
   487    487   ** Malloc function used by SQLite to obtain space from the buffer configured
   488    488   ** using sqlite3_config(SQLITE_CONFIG_PAGECACHE) option. If no such buffer
   489    489   ** exists, this function falls back to sqlite3Malloc().
   490    490   */
   491    491   void *sqlite3PageMalloc(int sz){
   492         -  /* During rebalance operations on a corrupt database file, it is sometimes
   493         -  ** (rarely) possible to overread the temporary page buffer by a few bytes.
   494         -  ** Enlarge the allocation slightly so that this does not cause problems. */
          492  +  assert( sz<=65536+8 ); /* These allocations are never very large */
   495    493     return pcache1Alloc(sz);
   496    494   }
   497    495   
   498    496   /*
   499    497   ** Free an allocated buffer obtained from sqlite3PageMalloc().
   500    498   */
   501    499   void sqlite3PageFree(void *p){

Changes to src/printf.c.

   133    133   /*
   134    134   ** Set the StrAccum object to an error mode.
   135    135   */
   136    136   static void setStrAccumError(StrAccum *p, u8 eError){
   137    137     assert( eError==SQLITE_NOMEM || eError==SQLITE_TOOBIG );
   138    138     p->accError = eError;
   139    139     if( p->mxAlloc ) sqlite3_str_reset(p);
          140  +  if( eError==SQLITE_TOOBIG ) sqlite3ErrorToParser(p->db, eError);
   140    141   }
   141    142   
   142    143   /*
   143    144   ** Extra argument values from a PrintfArguments object
   144    145   */
   145    146   static sqlite3_int64 getIntArg(PrintfArguments *p){
   146    147     if( p->nArg<=p->nUsed ) return 0;

Changes to src/resolve.c.

   430    430             assert( pExpr->pLeft==0 && pExpr->pRight==0 );
   431    431             assert( pExpr->x.pList==0 );
   432    432             assert( pExpr->x.pSelect==0 );
   433    433             pOrig = pEList->a[j].pExpr;
   434    434             if( (pNC->ncFlags&NC_AllowAgg)==0 && ExprHasProperty(pOrig, EP_Agg) ){
   435    435               sqlite3ErrorMsg(pParse, "misuse of aliased aggregate %s", zAs);
   436    436               return WRC_Abort;
          437  +          }
          438  +          if( (pNC->ncFlags&NC_AllowWin)==0 && ExprHasProperty(pOrig, EP_Win) ){
          439  +            sqlite3ErrorMsg(pParse, "misuse of aliased window function %s",zAs);
          440  +            return WRC_Abort;
   437    441             }
   438    442             if( sqlite3ExprVectorSize(pOrig)!=1 ){
   439    443               sqlite3ErrorMsg(pParse, "row value misused");
   440    444               return WRC_Abort;
   441    445             }
   442    446             resolveAlias(pParse, pEList, j, pExpr, "", nSubquery);
   443    447             cnt = 1;
................................................................................
   721    725         int no_such_func = 0;       /* True if no such function exists */
   722    726         int wrong_num_args = 0;     /* True if wrong number of arguments */
   723    727         int is_agg = 0;             /* True if is an aggregate function */
   724    728         int nId;                    /* Number of characters in function name */
   725    729         const char *zId;            /* The function name. */
   726    730         FuncDef *pDef;              /* Information about the function */
   727    731         u8 enc = ENC(pParse->db);   /* The database encoding */
          732  +      int savedAllowFlags = (pNC->ncFlags & (NC_AllowAgg | NC_AllowWin));
   728    733   
   729    734         assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
   730    735         zId = pExpr->u.zToken;
   731    736         nId = sqlite3Strlen30(zId);
   732    737         pDef = sqlite3FindFunction(pParse->db, zId, n, enc, 0);
   733    738         if( pDef==0 ){
   734    739           pDef = sqlite3FindFunction(pParse->db, zId, -2, enc, 0);
................................................................................
   842    847             pNC->nErr++;
   843    848           }else if( wrong_num_args ){
   844    849             sqlite3ErrorMsg(pParse,"wrong number of arguments to function %.*s()",
   845    850                  nId, zId);
   846    851             pNC->nErr++;
   847    852           }
   848    853           if( is_agg ){
          854  +          /* Window functions may not be arguments of aggregate functions.
          855  +          ** Or arguments of other window functions. But aggregate functions
          856  +          ** may be arguments for window functions.  */
   849    857   #ifndef SQLITE_OMIT_WINDOWFUNC
   850         -          pNC->ncFlags &= ~(pExpr->y.pWin ? NC_AllowWin : NC_AllowAgg);
          858  +          pNC->ncFlags &= ~(NC_AllowWin | (!pExpr->y.pWin ? NC_AllowAgg : 0));
   851    859   #else
   852    860             pNC->ncFlags &= ~NC_AllowAgg;
   853    861   #endif
   854    862           }
   855    863         }
   856    864         sqlite3WalkExprList(pWalker, pList);
   857    865         if( is_agg ){
................................................................................
   864    872             sqlite3WalkExpr(pWalker, pExpr->y.pWin->pFilter);
   865    873             if( 0==pSel->pWin 
   866    874              || 0==sqlite3WindowCompare(pParse, pSel->pWin, pExpr->y.pWin) 
   867    875             ){
   868    876               pExpr->y.pWin->pNextWin = pSel->pWin;
   869    877               pSel->pWin = pExpr->y.pWin;
   870    878             }
   871         -          pNC->ncFlags |= NC_AllowWin;
          879  +          pNC->ncFlags |= NC_HasWin;
   872    880           }else
   873    881   #endif /* SQLITE_OMIT_WINDOWFUNC */
   874    882           {
   875    883             NameContext *pNC2 = pNC;
   876    884             pExpr->op = TK_AGG_FUNCTION;
   877    885             pExpr->op2 = 0;
   878    886             while( pNC2 && !sqlite3FunctionUsesThisSrc(pExpr, pNC2->pSrcList) ){
................................................................................
   882    890             assert( pDef!=0 );
   883    891             if( pNC2 ){
   884    892               assert( SQLITE_FUNC_MINMAX==NC_MinMaxAgg );
   885    893               testcase( (pDef->funcFlags & SQLITE_FUNC_MINMAX)!=0 );
   886    894               pNC2->ncFlags |= NC_HasAgg | (pDef->funcFlags & SQLITE_FUNC_MINMAX);
   887    895   
   888    896             }
   889         -          pNC->ncFlags |= NC_AllowAgg;
   890    897           }
          898  +        pNC->ncFlags |= savedAllowFlags;
   891    899         }
   892    900         /* FIX ME:  Compute pExpr->affinity based on the expected return
   893    901         ** type of the function 
   894    902         */
   895    903         return WRC_Prune;
   896    904       }
   897    905   #ifndef SQLITE_OMIT_SUBQUERY
................................................................................
  1420   1428         p->pOrderBy = 0;
  1421   1429       }
  1422   1430     
  1423   1431       /* Recursively resolve names in all subqueries
  1424   1432       */
  1425   1433       for(i=0; i<p->pSrc->nSrc; i++){
  1426   1434         struct SrcList_item *pItem = &p->pSrc->a[i];
  1427         -      if( pItem->pSelect ){
         1435  +      if( pItem->pSelect && (pItem->pSelect->selFlags & SF_Resolved)==0 ){
  1428   1436           NameContext *pNC;         /* Used to iterate name contexts */
  1429   1437           int nRef = 0;             /* Refcount for pOuterNC and outer contexts */
  1430   1438           const char *zSavedContext = pParse->zAuthContext;
  1431   1439   
  1432   1440           /* Count the total number of references to pOuterNC and all of its
  1433   1441           ** parent contexts. After resolving references to expressions in
  1434   1442           ** pItem->pSelect, check if this value has changed. If so, then
................................................................................
  1644   1652     NameContext *pNC,       /* Namespace to resolve expressions in. */
  1645   1653     Expr *pExpr             /* The expression to be analyzed. */
  1646   1654   ){
  1647   1655     u16 savedHasAgg;
  1648   1656     Walker w;
  1649   1657   
  1650   1658     if( pExpr==0 ) return SQLITE_OK;
  1651         -  savedHasAgg = pNC->ncFlags & (NC_HasAgg|NC_MinMaxAgg);
  1652         -  pNC->ncFlags &= ~(NC_HasAgg|NC_MinMaxAgg);
         1659  +  savedHasAgg = pNC->ncFlags & (NC_HasAgg|NC_MinMaxAgg|NC_HasWin);
         1660  +  pNC->ncFlags &= ~(NC_HasAgg|NC_MinMaxAgg|NC_HasWin);
  1653   1661     w.pParse = pNC->pParse;
  1654   1662     w.xExprCallback = resolveExprStep;
  1655   1663     w.xSelectCallback = resolveSelectStep;
  1656   1664     w.xSelectCallback2 = 0;
  1657   1665     w.u.pNC = pNC;
  1658   1666   #if SQLITE_MAX_EXPR_DEPTH>0
  1659   1667     w.pParse->nHeight += pExpr->nHeight;
................................................................................
  1661   1669       return SQLITE_ERROR;
  1662   1670     }
  1663   1671   #endif
  1664   1672     sqlite3WalkExpr(&w, pExpr);
  1665   1673   #if SQLITE_MAX_EXPR_DEPTH>0
  1666   1674     w.pParse->nHeight -= pExpr->nHeight;
  1667   1675   #endif
  1668         -  if( pNC->ncFlags & NC_HasAgg ){
  1669         -    ExprSetProperty(pExpr, EP_Agg);
  1670         -  }
         1676  +  assert( EP_Agg==NC_HasAgg );
         1677  +  assert( EP_Win==NC_HasWin );
         1678  +  testcase( pNC->ncFlags & NC_HasAgg );
         1679  +  testcase( pNC->ncFlags & NC_HasWin );
         1680  +  ExprSetProperty(pExpr, pNC->ncFlags & (NC_HasAgg|NC_HasWin) );
  1671   1681     pNC->ncFlags |= savedHasAgg;
  1672   1682     return pNC->nErr>0 || w.pParse->nErr>0;
  1673   1683   }
  1674   1684   
  1675   1685   /*
  1676   1686   ** Resolve all names for all expression in an expression list.  This is
  1677   1687   ** just like sqlite3ResolveExprNames() except that it works for an expression

Changes to src/sqlite.h.in.

   185    185   **
   186    186   ** See also: SQL functions [sqlite_compileoption_used()] and
   187    187   ** [sqlite_compileoption_get()] and the [compile_options pragma].
   188    188   */
   189    189   #ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
   190    190   int sqlite3_compileoption_used(const char *zOptName);
   191    191   const char *sqlite3_compileoption_get(int N);
          192  +#else
          193  +# define sqlite3_compileoption_used(X) 0
          194  +# define sqlite3_compileoption_get(X)  ((void*)0)
   192    195   #endif
   193    196   
   194    197   /*
   195    198   ** CAPI3REF: Test To See If The Library Is Threadsafe
   196    199   **
   197    200   ** ^The sqlite3_threadsafe() function returns zero if and only if
   198    201   ** SQLite was compiled with mutexing code omitted due to the
................................................................................
  4972   4975   ** <tr><td><b>sqlite3_value_type</b><td>&rarr;<td>Default
  4973   4976   ** datatype of the value
  4974   4977   ** <tr><td><b>sqlite3_value_numeric_type&nbsp;&nbsp;</b>
  4975   4978   ** <td>&rarr;&nbsp;&nbsp;<td>Best numeric datatype of the value
  4976   4979   ** <tr><td><b>sqlite3_value_nochange&nbsp;&nbsp;</b>
  4977   4980   ** <td>&rarr;&nbsp;&nbsp;<td>True if the column is unchanged in an UPDATE
  4978   4981   ** against a virtual table.
         4982  +** <tr><td><b>sqlite3_value_frombind&nbsp;&nbsp;</b>
         4983  +** <td>&rarr;&nbsp;&nbsp;<td>True if value originated from a [bound parameter]
  4979   4984   ** </table></blockquote>
  4980   4985   **
  4981   4986   ** <b>Details:</b>
  4982   4987   **
  4983   4988   ** These routines extract type, size, and content information from
  4984   4989   ** [protected sqlite3_value] objects.  Protected sqlite3_value objects
  4985   4990   ** are used to pass parameter information into implementation of
................................................................................
  5032   5037   ** the value for that column returned without setting a result (probably
  5033   5038   ** because it queried [sqlite3_vtab_nochange()] and found that the column
  5034   5039   ** was unchanging).  ^Within an [xUpdate] method, any value for which
  5035   5040   ** sqlite3_value_nochange(X) is true will in all other respects appear
  5036   5041   ** to be a NULL value.  If sqlite3_value_nochange(X) is invoked anywhere other
  5037   5042   ** than within an [xUpdate] method call for an UPDATE statement, then
  5038   5043   ** the return value is arbitrary and meaningless.
         5044  +**
         5045  +** ^The sqlite3_value_frombind(X) interface returns non-zero if the
         5046  +** value X originated from one of the [sqlite3_bind_int|sqlite3_bind()]
         5047  +** interfaces.  ^If X comes from an SQL literal value, or a table column,
         5048  +** and expression, then sqlite3_value_frombind(X) returns zero.
  5039   5049   **
  5040   5050   ** Please pay particular attention to the fact that the pointer returned
  5041   5051   ** from [sqlite3_value_blob()], [sqlite3_value_text()], or
  5042   5052   ** [sqlite3_value_text16()] can be invalidated by a subsequent call to
  5043   5053   ** [sqlite3_value_bytes()], [sqlite3_value_bytes16()], [sqlite3_value_text()],
  5044   5054   ** or [sqlite3_value_text16()].
  5045   5055   **
................................................................................
  5078   5088   const void *sqlite3_value_text16le(sqlite3_value*);
  5079   5089   const void *sqlite3_value_text16be(sqlite3_value*);
  5080   5090   int sqlite3_value_bytes(sqlite3_value*);
  5081   5091   int sqlite3_value_bytes16(sqlite3_value*);
  5082   5092   int sqlite3_value_type(sqlite3_value*);
  5083   5093   int sqlite3_value_numeric_type(sqlite3_value*);
  5084   5094   int sqlite3_value_nochange(sqlite3_value*);
         5095  +int sqlite3_value_frombind(sqlite3_value*);
  5085   5096   
  5086   5097   /*
  5087   5098   ** CAPI3REF: Finding The Subtype Of SQL Values
  5088   5099   ** METHOD: sqlite3_value
  5089   5100   **
  5090   5101   ** The sqlite3_value_subtype(V) function returns the subtype for
  5091   5102   ** an [application-defined SQL function] argument V.  The subtype

Changes to src/sqlite3ext.h.

   315    315                               void (*xStep)(sqlite3_context*,int,sqlite3_value**),
   316    316                               void (*xFinal)(sqlite3_context*),
   317    317                               void (*xValue)(sqlite3_context*),
   318    318                               void (*xInv)(sqlite3_context*,int,sqlite3_value**),
   319    319                               void(*xDestroy)(void*));
   320    320     /* Version 3.26.0 and later */
   321    321     const char *(*normalized_sql)(sqlite3_stmt*);
          322  +  /* Version 3.28.0 and later */
          323  +  int (*stmt_isexplain)(sqlite3_stmt*);
          324  +  int (*value_frombind)(sqlite3_value*);
   322    325   };
   323    326   
   324    327   /*
   325    328   ** This is the function signature used for all extension entry points.  It
   326    329   ** is also defined in the file "loadext.c".
   327    330   */
   328    331   typedef int (*sqlite3_loadext_entry)(
................................................................................
   604    607   #define sqlite3_str_errcode            sqlite3_api->str_errcode
   605    608   #define sqlite3_str_length             sqlite3_api->str_length
   606    609   #define sqlite3_str_value              sqlite3_api->str_value
   607    610   /* Version 3.25.0 and later */
   608    611   #define sqlite3_create_window_function sqlite3_api->create_window_function
   609    612   /* Version 3.26.0 and later */
   610    613   #define sqlite3_normalized_sql         sqlite3_api->normalized_sql
          614  +/* Version 3.28.0 and later */
          615  +#define sqlite3_stmt_isexplain         sqlite3_api->isexplain
          616  +#define sqlite3_value_frombind         sqlite3_api->frombind
   611    617   #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
   612    618   
   613    619   #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
   614    620     /* This case when the file really is being compiled as a loadable 
   615    621     ** extension */
   616    622   # define SQLITE_EXTENSION_INIT1     const sqlite3_api_routines *sqlite3_api=0;
   617    623   # define SQLITE_EXTENSION_INIT2(v)  sqlite3_api=v;

Changes to src/sqliteInt.h.

  1573   1573   
  1574   1574   /*
  1575   1575   ** Allowed values for sqlite3.mDbFlags
  1576   1576   */
  1577   1577   #define DBFLAG_SchemaChange   0x0001  /* Uncommitted Hash table changes */
  1578   1578   #define DBFLAG_PreferBuiltin  0x0002  /* Preference to built-in funcs */
  1579   1579   #define DBFLAG_Vacuum         0x0004  /* Currently in a VACUUM */
  1580         -#define DBFLAG_SchemaKnownOk  0x0008  /* Schema is known to be valid */
         1580  +#define DBFLAG_VacuumInto     0x0008  /* Currently running VACUUM INTO */
         1581  +#define DBFLAG_SchemaKnownOk  0x0010  /* Schema is known to be valid */
  1581   1582   
  1582   1583   /*
  1583   1584   ** Bits of the sqlite3.dbOptFlags field that are used by the
  1584   1585   ** sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS,...) interface to
  1585   1586   ** selectively disable various optimizations.
  1586   1587   */
  1587   1588   #define SQLITE_QueryFlattener 0x0001   /* Query flattening */
  1588         -                          /*  0x0002   available for reuse */
         1589  +#define SQLITE_WindowFunc     0x0002   /* Use xInverse for window functions */
  1589   1590   #define SQLITE_GroupByOrder   0x0004   /* GROUPBY cover of ORDERBY */
  1590   1591   #define SQLITE_FactorOutConst 0x0008   /* Constant factoring */
  1591   1592   #define SQLITE_DistinctOpt    0x0010   /* DISTINCT using indexes */
  1592   1593   #define SQLITE_CoverIdxScan   0x0020   /* Covering index scans */
  1593   1594   #define SQLITE_OrderByIdxJoin 0x0040   /* ORDER BY of joins via index */
  1594   1595   #define SQLITE_Transitive     0x0080   /* Transitive constraints */
  1595   1596   #define SQLITE_OmitNoopJoin   0x0100   /* Omit unused tables in joins */
................................................................................
  1699   1700   #define SQLITE_FUNC_CONSTANT 0x0800 /* Constant inputs give a constant output */
  1700   1701   #define SQLITE_FUNC_MINMAX   0x1000 /* True for min() and max() aggregates */
  1701   1702   #define SQLITE_FUNC_SLOCHNG  0x2000 /* "Slow Change". Value constant during a
  1702   1703                                       ** single query - might change over time */
  1703   1704   #define SQLITE_FUNC_AFFINITY 0x4000 /* Built-in affinity() function */
  1704   1705   #define SQLITE_FUNC_OFFSET   0x8000 /* Built-in sqlite_offset() function */
  1705   1706   #define SQLITE_FUNC_WINDOW   0x00010000 /* Built-in window-only function */
  1706         -#define SQLITE_FUNC_WINDOW_SIZE 0x20000 /* Requires partition size as arg. */
  1707   1707   #define SQLITE_FUNC_INTERNAL 0x00040000 /* For use by NestedParse() only */
  1708   1708   
  1709   1709   /*
  1710   1710   ** The following three macros, FUNCTION(), LIKEFUNC() and AGGREGATE() are
  1711   1711   ** used to create the initializers for the FuncDef structures.
  1712   1712   **
  1713   1713   **   FUNCTION(zName, nArg, iArg, bNC, xFunc)
................................................................................
  2505   2505         int regReturn;         /* Register used to hold return address */
  2506   2506       } sub;
  2507   2507     } y;
  2508   2508   };
  2509   2509   
  2510   2510   /*
  2511   2511   ** The following are the meanings of bits in the Expr.flags field.
         2512  +** Value restrictions:
         2513  +**
         2514  +**          EP_Agg == NC_HasAgg == SF_HasAgg
         2515  +**          EP_Win == NC_HasWin
  2512   2516   */
  2513   2517   #define EP_FromJoin  0x000001 /* Originates in ON/USING clause of outer join */
  2514         -#define EP_Agg       0x000002 /* Contains one or more aggregate functions */
         2518  +#define EP_Distinct  0x000002 /* Aggregate function with DISTINCT keyword */
  2515   2519   #define EP_HasFunc   0x000004 /* Contains one or more functions of any kind */
  2516   2520   #define EP_FixedCol  0x000008 /* TK_Column with a known fixed value */
  2517         -#define EP_Distinct  0x000010 /* Aggregate function with DISTINCT keyword */
         2521  +#define EP_Agg       0x000010 /* Contains one or more aggregate functions */
  2518   2522   #define EP_VarSelect 0x000020 /* pSelect is correlated, not constant */
  2519   2523   #define EP_DblQuoted 0x000040 /* token.z was originally in "..." */
  2520   2524   #define EP_InfixFunc 0x000080 /* True for an infix function: LIKE, GLOB, etc */
  2521   2525   #define EP_Collate   0x000100 /* Tree contains a TK_COLLATE operator */
  2522   2526   #define EP_Generic   0x000200 /* Ignore COLLATE or affinity on this tree */
  2523   2527   #define EP_IntValue  0x000400 /* Integer value contained in u.iValue */
  2524   2528   #define EP_xIsSelect 0x000800 /* x.pSelect is valid (otherwise x.pList is) */
  2525   2529   #define EP_Skip      0x001000 /* COLLATE, AS, or UNLIKELY */
  2526   2530   #define EP_Reduced   0x002000 /* Expr struct EXPR_REDUCEDSIZE bytes only */
  2527   2531   #define EP_TokenOnly 0x004000 /* Expr struct EXPR_TOKENONLYSIZE bytes only */
  2528         -#define EP_Static    0x008000 /* Held in memory not obtained from malloc() */
         2532  +#define EP_Win       0x008000 /* Contains window functions */
  2529   2533   #define EP_MemToken  0x010000 /* Need to sqlite3DbFree() Expr.zToken */
  2530   2534   #define EP_NoReduce  0x020000 /* Cannot EXPRDUP_REDUCE this Expr */
  2531   2535   #define EP_Unlikely  0x040000 /* unlikely() or likelihood() function */
  2532   2536   #define EP_ConstFunc 0x080000 /* A SQLITE_FUNC_CONSTANT or _SLOCHNG function */
  2533   2537   #define EP_CanBeNull 0x100000 /* Can be null despite NOT NULL constraint */
  2534   2538   #define EP_Subquery  0x200000 /* Tree contains a TK_SELECT operator */
  2535   2539   #define EP_Alias     0x400000 /* Is an alias for a result set column */
  2536   2540   #define EP_Leaf      0x800000 /* Expr.pLeft, .pRight, .u.pSelect all NULL */
  2537   2541   #define EP_WinFunc  0x1000000 /* TK_FUNCTION with Expr.y.pWin set */
  2538   2542   #define EP_Subrtn   0x2000000 /* Uses Expr.y.sub. TK_IN, _SELECT, or _EXISTS */
  2539   2543   #define EP_Quoted   0x4000000 /* TK_ID was originally quoted */
         2544  +#define EP_Static   0x8000000 /* Held in memory not obtained from malloc() */
  2540   2545   
  2541   2546   /*
  2542   2547   ** The EP_Propagate mask is a set of properties that automatically propagate
  2543   2548   ** upwards into parent nodes.
  2544   2549   */
  2545   2550   #define EP_Propagate (EP_Collate|EP_Subquery|EP_HasFunc)
  2546   2551   
................................................................................
  2772   2777     Select *pWinSelect;  /* SELECT statement for any window functions */
  2773   2778   };
  2774   2779   
  2775   2780   /*
  2776   2781   ** Allowed values for the NameContext, ncFlags field.
  2777   2782   **
  2778   2783   ** Value constraints (all checked via assert()):
  2779         -**    NC_HasAgg    == SF_HasAgg
         2784  +**    NC_HasAgg    == SF_HasAgg    == EP_Agg
  2780   2785   **    NC_MinMaxAgg == SF_MinMaxAgg == SQLITE_FUNC_MINMAX
         2786  +**    NC_HasWin    == EP_Win
  2781   2787   **
  2782   2788   */
  2783   2789   #define NC_AllowAgg  0x0001  /* Aggregate functions are allowed here */
  2784   2790   #define NC_PartIdx   0x0002  /* True if resolving a partial index WHERE */
  2785   2791   #define NC_IsCheck   0x0004  /* True if resolving names in a CHECK constraint */
  2786   2792   #define NC_InAggFunc 0x0008  /* True if analyzing arguments to an agg func */
  2787   2793   #define NC_HasAgg    0x0010  /* One or more aggregate functions seen */
................................................................................
  2789   2795   #define NC_VarSelect 0x0040  /* A correlated subquery has been seen */
  2790   2796   #define NC_UEList    0x0080  /* True if uNC.pEList is used */
  2791   2797   #define NC_UAggInfo  0x0100  /* True if uNC.pAggInfo is used */
  2792   2798   #define NC_UUpsert   0x0200  /* True if uNC.pUpsert is used */
  2793   2799   #define NC_MinMaxAgg 0x1000  /* min/max aggregates seen.  See note above */
  2794   2800   #define NC_Complex   0x2000  /* True if a function or subquery seen */
  2795   2801   #define NC_AllowWin  0x4000  /* Window functions are allowed here */
         2802  +#define NC_HasWin    0x8000  /* One or more window functions seen */
  2796   2803   
  2797   2804   /*
  2798   2805   ** An instance of the following object describes a single ON CONFLICT
  2799   2806   ** clause in an upsert.
  2800   2807   **
  2801   2808   ** The pUpsertTarget field is only set if the ON CONFLICT clause includes
  2802   2809   ** conflict-target clause.  (In "ON CONFLICT(a,b)" the "(a,b)" is the
................................................................................
  3544   3551   struct TreeView {
  3545   3552     int iLevel;             /* Which level of the tree we are on */
  3546   3553     u8  bLine[100];         /* Draw vertical in column i if bLine[i] is true */
  3547   3554   };
  3548   3555   #endif /* SQLITE_DEBUG */
  3549   3556   
  3550   3557   /*
  3551         -** This object is used in varioius ways, all related to window functions
         3558  +** This object is used in various ways, all related to window functions
  3552   3559   **
  3553   3560   **   (1) A single instance of this structure is attached to the
  3554   3561   **       the Expr.pWin field for each window function in an expression tree.
  3555   3562   **       This object holds the information contained in the OVER clause,
  3556   3563   **       plus additional fields used during code generation.
  3557   3564   **
  3558   3565   **   (2) All window functions in a single SELECT form a linked-list
................................................................................
  3559   3566   **       attached to Select.pWin.  The Window.pFunc and Window.pExpr
  3560   3567   **       fields point back to the expression that is the window function.
  3561   3568   **
  3562   3569   **   (3) The terms of the WINDOW clause of a SELECT are instances of this
  3563   3570   **       object on a linked list attached to Select.pWinDefn.
  3564   3571   **
  3565   3572   ** The uses (1) and (2) are really the same Window object that just happens
  3566         -** to be accessible in two different ways.  Use (3) is are separate objects.
         3573  +** to be accessible in two different ways.  Use case (3) are separate objects.
  3567   3574   */
  3568   3575   struct Window {
  3569   3576     char *zName;            /* Name of window (may be NULL) */
         3577  +  char *zBase;            /* Name of base window for chaining (may be NULL) */
  3570   3578     ExprList *pPartition;   /* PARTITION BY clause */
  3571   3579     ExprList *pOrderBy;     /* ORDER BY clause */
  3572         -  u8 eType;               /* TK_RANGE or TK_ROWS */
         3580  +  u8 eFrmType;            /* TK_RANGE, TK_GROUPS, TK_ROWS, or 0 */
  3573   3581     u8 eStart;              /* UNBOUNDED, CURRENT, PRECEDING or FOLLOWING */
  3574   3582     u8 eEnd;                /* UNBOUNDED, CURRENT, PRECEDING or FOLLOWING */
         3583  +  u8 bImplicitFrame;      /* True if frame was implicitly specified */
         3584  +  u8 eExclude;            /* TK_NO, TK_CURRENT, TK_TIES, TK_GROUP, or 0 */
  3575   3585     Expr *pStart;           /* Expression for "<expr> PRECEDING" */
  3576   3586     Expr *pEnd;             /* Expression for "<expr> FOLLOWING" */
  3577   3587     Window *pNextWin;       /* Next window function belonging to this SELECT */
  3578   3588     Expr *pFilter;          /* The FILTER expression */
  3579   3589     FuncDef *pFunc;         /* The function */
  3580   3590     int iEphCsr;            /* Partition buffer or Peer buffer */
  3581   3591     int regAccum;
  3582   3592     int regResult;
  3583   3593     int csrApp;             /* Function cursor (used by min/max) */
  3584   3594     int regApp;             /* Function register (also used by min/max) */
  3585         -  int regPart;            /* First in a set of registers holding PARTITION BY
  3586         -                          ** and ORDER BY values for the window */
         3595  +  int regPart;            /* Array of registers for PARTITION BY values */
  3587   3596     Expr *pOwner;           /* Expression object this window is attached to */
  3588   3597     int nBufferCol;         /* Number of columns in buffer table */
  3589   3598     int iArgCol;            /* Offset of first argument for this function */
         3599  +  int regOne;             /* Register containing constant value 1 */
         3600  +  int regStartRowid;
         3601  +  int regEndRowid;
  3590   3602   };
  3591   3603   
  3592   3604   #ifndef SQLITE_OMIT_WINDOWFUNC
  3593   3605   void sqlite3WindowDelete(sqlite3*, Window*);
  3594   3606   void sqlite3WindowListDelete(sqlite3 *db, Window *p);
  3595         -Window *sqlite3WindowAlloc(Parse*, int, int, Expr*, int , Expr*);
         3607  +Window *sqlite3WindowAlloc(Parse*, int, int, Expr*, int , Expr*, u8);
  3596   3608   void sqlite3WindowAttach(Parse*, Expr*, Window*);
  3597   3609   int sqlite3WindowCompare(Parse*, Window*, Window*);
  3598   3610   void sqlite3WindowCodeInit(Parse*, Window*);
  3599   3611   void sqlite3WindowCodeStep(Parse*, Select*, WhereInfo*, int, int);
  3600   3612   int sqlite3WindowRewrite(Parse*, Select*);
  3601   3613   int sqlite3ExpandSubquery(Parse*, struct SrcList_item*);
  3602   3614   void sqlite3WindowUpdate(Parse*, Window*, Window*, FuncDef*);
  3603   3615   Window *sqlite3WindowDup(sqlite3 *db, Expr *pOwner, Window *p);
  3604   3616   Window *sqlite3WindowListDup(sqlite3 *db, Window *p);
  3605   3617   void sqlite3WindowFunctions(void);
         3618  +void sqlite3WindowChain(Parse*, Window*, Window*);
         3619  +Window *sqlite3WindowAssemble(Parse*, Window*, ExprList*, ExprList*, Token*);
  3606   3620   #else
  3607   3621   # define sqlite3WindowDelete(a,b)
  3608   3622   # define sqlite3WindowFunctions()
  3609   3623   # define sqlite3WindowAttach(a,b,c)
  3610   3624   #endif
  3611   3625   
  3612   3626   /*
................................................................................
  3828   3842     void sqlite3TreeViewWinFunc(TreeView*, const Window*, u8);
  3829   3843   #endif
  3830   3844   #endif
  3831   3845   
  3832   3846   
  3833   3847   void sqlite3SetString(char **, sqlite3*, const char*);
  3834   3848   void sqlite3ErrorMsg(Parse*, const char*, ...);
         3849  +int sqlite3ErrorToParser(sqlite3*,int);
  3835   3850   void sqlite3Dequote(char*);
  3836   3851   void sqlite3DequoteExpr(Expr*);
  3837   3852   void sqlite3TokenInit(Token*,char*);
  3838   3853   int sqlite3KeywordCode(const unsigned char*, int);
  3839   3854   int sqlite3RunParser(Parse*, const char*, char **);
  3840   3855   void sqlite3FinishCoding(Parse*);
  3841   3856   int sqlite3GetTempReg(Parse*);

Changes to src/test4.c.

    60     60   #define N_THREAD 26
    61     61   static Thread threadset[N_THREAD];
    62     62   
    63     63   
    64     64   /*
    65     65   ** The main loop for a thread.  Threads use busy waiting. 
    66     66   */
    67         -static void *thread_main(void *pArg){
           67  +static void *test_thread_main(void *pArg){
    68     68     Thread *p = (Thread*)pArg;
    69     69     if( p->db ){
    70     70       sqlite3_close(p->db);
    71     71     }
    72     72     sqlite3_open(p->zFilename, &p->db);
    73     73     if( SQLITE_OK!=sqlite3_errcode(p->db) ){
    74     74       p->zErr = strdup(sqlite3_errmsg(p->db));
................................................................................
   147    147       return TCL_ERROR;
   148    148     }
   149    149     threadset[i].busy = 1;
   150    150     sqlite3_free(threadset[i].zFilename);
   151    151     threadset[i].zFilename = sqlite3_mprintf("%s", argv[2]);
   152    152     threadset[i].opnum = 1;
   153    153     threadset[i].completed = 0;
   154         -  rc = pthread_create(&x, 0, thread_main, &threadset[i]);
          154  +  rc = pthread_create(&x, 0, test_thread_main, &threadset[i]);
   155    155     if( rc ){
   156    156       Tcl_AppendResult(interp, "failed to create the thread", 0);
   157    157       sqlite3_free(threadset[i].zFilename);
   158    158       threadset[i].busy = 0;
   159    159       return TCL_ERROR;
   160    160     }
   161    161     pthread_detach(x);
   162    162     return TCL_OK;
   163    163   }
   164    164   
   165    165   /*
   166    166   ** Wait for a thread to reach its idle state.
   167    167   */
   168         -static void thread_wait(Thread *p){
          168  +static void test_thread_wait(Thread *p){
   169    169     while( p->opnum>p->completed ) sched_yield();
   170    170   }
   171    171   
   172    172   /*
   173    173   ** Usage:  thread_wait ID
   174    174   **
   175    175   ** Wait on thread ID to reach its idle state.
................................................................................
   189    189     }
   190    190     i = parse_thread_id(interp, argv[1]);
   191    191     if( i<0 ) return TCL_ERROR;
   192    192     if( !threadset[i].busy ){
   193    193       Tcl_AppendResult(interp, "no such thread", 0);
   194    194       return TCL_ERROR;
   195    195     }
   196         -  thread_wait(&threadset[i]);
          196  +  test_thread_wait(&threadset[i]);
   197    197     return TCL_OK;
   198    198   }
   199    199   
   200    200   /*
   201    201   ** Stop a thread.
   202    202   */
   203         -static void stop_thread(Thread *p){
   204         -  thread_wait(p);
          203  +static void test_stop_thread(Thread *p){
          204  +  test_thread_wait(p);
   205    205     p->xOp = 0;
   206    206     p->opnum++;
   207         -  thread_wait(p);
          207  +  test_thread_wait(p);
   208    208     sqlite3_free(p->zArg);
   209    209     p->zArg = 0;
   210    210     sqlite3_free(p->zFilename);
   211    211     p->zFilename = 0;
   212    212     p->busy = 0;
   213    213   }
   214    214   
................................................................................
   229    229     if( argc!=2 ){
   230    230       Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
   231    231          " ID", 0);
   232    232       return TCL_ERROR;
   233    233     }
   234    234     if( argv[1][0]=='*' && argv[1][1]==0 ){
   235    235       for(i=0; i<N_THREAD; i++){
   236         -      if( threadset[i].busy ) stop_thread(&threadset[i]);
          236  +      if( threadset[i].busy ) test_stop_thread(&threadset[i]);
   237    237       }
   238    238     }else{
   239    239       i = parse_thread_id(interp, argv[1]);
   240    240       if( i<0 ) return TCL_ERROR;
   241    241       if( !threadset[i].busy ){
   242    242         Tcl_AppendResult(interp, "no such thread", 0);
   243    243         return TCL_ERROR;
   244    244       }
   245         -    stop_thread(&threadset[i]);
          245  +    test_stop_thread(&threadset[i]);
   246    246     }
   247    247     return TCL_OK;
   248    248   }
   249    249   
   250    250   /*
   251    251   ** Usage: thread_argc  ID
   252    252   **
................................................................................
   269    269     }
   270    270     i = parse_thread_id(interp, argv[1]);
   271    271     if( i<0 ) return TCL_ERROR;
   272    272     if( !threadset[i].busy ){
   273    273       Tcl_AppendResult(interp, "no such thread", 0);
   274    274       return TCL_ERROR;
   275    275     }
   276         -  thread_wait(&threadset[i]);
          276  +  test_thread_wait(&threadset[i]);
   277    277     sqlite3_snprintf(sizeof(zBuf), zBuf, "%d", threadset[i].argc);
   278    278     Tcl_AppendResult(interp, zBuf, 0);
   279    279     return TCL_OK;
   280    280   }
   281    281   
   282    282   /*
   283    283   ** Usage: thread_argv  ID   N
................................................................................
   302    302     i = parse_thread_id(interp, argv[1]);
   303    303     if( i<0 ) return TCL_ERROR;
   304    304     if( !threadset[i].busy ){
   305    305       Tcl_AppendResult(interp, "no such thread", 0);
   306    306       return TCL_ERROR;
   307    307     }
   308    308     if( Tcl_GetInt(interp, argv[2], &n) ) return TCL_ERROR;
   309         -  thread_wait(&threadset[i]);
          309  +  test_thread_wait(&threadset[i]);
   310    310     if( n<0 || n>=threadset[i].argc ){
   311    311       Tcl_AppendResult(interp, "column number out of range", 0);
   312    312       return TCL_ERROR;
   313    313     }
   314    314     Tcl_AppendResult(interp, threadset[i].argv[n], 0);
   315    315     return TCL_OK;
   316    316   }
................................................................................
   338    338     i = parse_thread_id(interp, argv[1]);
   339    339     if( i<0 ) return TCL_ERROR;
   340    340     if( !threadset[i].busy ){
   341    341       Tcl_AppendResult(interp, "no such thread", 0);
   342    342       return TCL_ERROR;
   343    343     }
   344    344     if( Tcl_GetInt(interp, argv[2], &n) ) return TCL_ERROR;
   345         -  thread_wait(&threadset[i]);
          345  +  test_thread_wait(&threadset[i]);
   346    346     if( n<0 || n>=threadset[i].argc ){
   347    347       Tcl_AppendResult(interp, "column number out of range", 0);
   348    348       return TCL_ERROR;
   349    349     }
   350    350     Tcl_AppendResult(interp, threadset[i].colv[n], 0);
   351    351     return TCL_OK;
   352    352   }
................................................................................
   373    373     }
   374    374     i = parse_thread_id(interp, argv[1]);
   375    375     if( i<0 ) return TCL_ERROR;
   376    376     if( !threadset[i].busy ){
   377    377       Tcl_AppendResult(interp, "no such thread", 0);
   378    378       return TCL_ERROR;
   379    379     }
   380         -  thread_wait(&threadset[i]);
          380  +  test_thread_wait(&threadset[i]);
   381    381     zName = sqlite3ErrName(threadset[i].rc);
   382    382     Tcl_AppendResult(interp, zName, 0);
   383    383     return TCL_OK;
   384    384   }
   385    385   
   386    386   /*
   387    387   ** Usage: thread_error  ID
................................................................................
   404    404     }
   405    405     i = parse_thread_id(interp, argv[1]);
   406    406     if( i<0 ) return TCL_ERROR;
   407    407     if( !threadset[i].busy ){
   408    408       Tcl_AppendResult(interp, "no such thread", 0);
   409    409       return TCL_ERROR;
   410    410     }
   411         -  thread_wait(&threadset[i]);
          411  +  test_thread_wait(&threadset[i]);
   412    412     Tcl_AppendResult(interp, threadset[i].zErr, 0);
   413    413     return TCL_OK;
   414    414   }
   415    415   
   416    416   /*
   417    417   ** This procedure runs in the thread to compile an SQL statement.
   418    418   */
................................................................................
   448    448     }
   449    449     i = parse_thread_id(interp, argv[1]);
   450    450     if( i<0 ) return TCL_ERROR;
   451    451     if( !threadset[i].busy ){
   452    452       Tcl_AppendResult(interp, "no such thread", 0);
   453    453       return TCL_ERROR;
   454    454     }
   455         -  thread_wait(&threadset[i]);
          455  +  test_thread_wait(&threadset[i]);
   456    456     threadset[i].xOp = do_compile;
   457    457     sqlite3_free(threadset[i].zArg);
   458    458     threadset[i].zArg = sqlite3_mprintf("%s", argv[2]);
   459    459     threadset[i].opnum++;
   460    460     return TCL_OK;
   461    461   }
   462    462   
................................................................................
   501    501     }
   502    502     i = parse_thread_id(interp, argv[1]);
   503    503     if( i<0 ) return TCL_ERROR;
   504    504     if( !threadset[i].busy ){
   505    505       Tcl_AppendResult(interp, "no such thread", 0);
   506    506       return TCL_ERROR;
   507    507     }
   508         -  thread_wait(&threadset[i]);
          508  +  test_thread_wait(&threadset[i]);
   509    509     threadset[i].xOp = do_step;
   510    510     threadset[i].opnum++;
   511    511     return TCL_OK;
   512    512   }
   513    513   
   514    514   /*
   515    515   ** This procedure runs in the thread to finalize a virtual machine.
................................................................................
   543    543     }
   544    544     i = parse_thread_id(interp, argv[1]);
   545    545     if( i<0 ) return TCL_ERROR;
   546    546     if( !threadset[i].busy ){
   547    547       Tcl_AppendResult(interp, "no such thread", 0);
   548    548       return TCL_ERROR;
   549    549     }
   550         -  thread_wait(&threadset[i]);
          550  +  test_thread_wait(&threadset[i]);
   551    551     threadset[i].xOp = do_finalize;
   552    552     sqlite3_free(threadset[i].zArg);
   553    553     threadset[i].zArg = 0;
   554    554     threadset[i].opnum++;
   555    555     return TCL_OK;
   556    556   }
   557    557   
................................................................................
   575    575     }
   576    576     i = parse_thread_id(interp, argv[1]);
   577    577     if( i<0 ) return TCL_ERROR;
   578    578     if( !threadset[i].busy ){
   579    579       Tcl_AppendResult(interp, "no such thread", 0);
   580    580       return TCL_ERROR;
   581    581     }
   582         -  thread_wait(&threadset[i]);
          582  +  test_thread_wait(&threadset[i]);
   583    583     j = parse_thread_id(interp, argv[2]);
   584    584     if( j<0 ) return TCL_ERROR;
   585    585     if( !threadset[j].busy ){
   586    586       Tcl_AppendResult(interp, "no such thread", 0);
   587    587       return TCL_ERROR;
   588    588     }
   589         -  thread_wait(&threadset[j]);
          589  +  test_thread_wait(&threadset[j]);
   590    590     temp = threadset[i].db;
   591    591     threadset[i].db = threadset[j].db;
   592    592     threadset[j].db = temp;
   593    593     return TCL_OK;
   594    594   }
   595    595   
   596    596   /*
................................................................................
   616    616     }
   617    617     i = parse_thread_id(interp, argv[1]);
   618    618     if( i<0 ) return TCL_ERROR;
   619    619     if( !threadset[i].busy ){
   620    620       Tcl_AppendResult(interp, "no such thread", 0);
   621    621       return TCL_ERROR;
   622    622     }
   623         -  thread_wait(&threadset[i]);
          623  +  test_thread_wait(&threadset[i]);
   624    624     sqlite3TestMakePointerStr(interp, zBuf, threadset[i].db);
   625    625     threadset[i].db = 0;
   626    626     Tcl_AppendResult(interp, zBuf, (char*)0);
   627    627     return TCL_OK;
   628    628   }
   629    629   
   630    630   /*
................................................................................
   647    647     }
   648    648     i = parse_thread_id(interp, argv[1]);
   649    649     if( i<0 ) return TCL_ERROR;
   650    650     if( !threadset[i].busy ){
   651    651       Tcl_AppendResult(interp, "no such thread", 0);
   652    652       return TCL_ERROR;
   653    653     }
   654         -  thread_wait(&threadset[i]);
          654  +  test_thread_wait(&threadset[i]);
   655    655     assert( !threadset[i].db );
   656    656     threadset[i].db = (sqlite3*)sqlite3TestTextToPtr(argv[2]);
   657    657     return TCL_OK;
   658    658   }
   659    659   
   660    660   /*
   661    661   ** Usage: thread_stmt_get ID
................................................................................
   679    679     }
   680    680     i = parse_thread_id(interp, argv[1]);
   681    681     if( i<0 ) return TCL_ERROR;
   682    682     if( !threadset[i].busy ){
   683    683       Tcl_AppendResult(interp, "no such thread", 0);
   684    684       return TCL_ERROR;
   685    685     }
   686         -  thread_wait(&threadset[i]);
          686  +  test_thread_wait(&threadset[i]);
   687    687     sqlite3TestMakePointerStr(interp, zBuf, threadset[i].pStmt);
   688    688     threadset[i].pStmt = 0;
   689    689     Tcl_AppendResult(interp, zBuf, (char*)0);
   690    690     return TCL_OK;
   691    691   }
   692    692   
   693    693   /*

Changes to src/test_fs.c.

   736    736   
   737    737       int n;
   738    738       fd = open(zFile, O_RDONLY);
   739    739       if( fd<0 ) return SQLITE_IOERR;
   740    740       fstat(fd, &sbuf);
   741    741   
   742    742       if( sbuf.st_size>=pCur->nAlloc ){
   743         -      int nNew = sbuf.st_size*2;
          743  +      sqlite3_int64 nNew = sbuf.st_size*2;
   744    744         char *zNew;
   745    745         if( nNew<1024 ) nNew = 1024;
   746    746   
   747    747         zNew = sqlite3Realloc(pCur->zBuf, nNew);
   748    748         if( zNew==0 ){
   749    749           close(fd);
   750    750           return SQLITE_NOMEM;

Changes to src/test_func.c.

   625    625   static void test_getsubtype(
   626    626     sqlite3_context *context,
   627    627     int argc,
   628    628     sqlite3_value **argv
   629    629   ){
   630    630     sqlite3_result_int(context, (int)sqlite3_value_subtype(argv[0]));
   631    631   }
          632  +
          633  +/*         test_frombind(A,B,C,...)
          634  +**
          635  +** Return an integer bitmask that has a bit set for every argument
          636  +** (up to the first 63 arguments) that originates from a bind a parameter.
          637  +*/
          638  +static void test_frombind(
          639  +  sqlite3_context *context,
          640  +  int argc,
          641  +  sqlite3_value **argv
          642  +){
          643  +  sqlite3_uint64 m = 0;
          644  +  int i;
          645  +  for(i=0; i<argc && i<63; i++){
          646  +    if( sqlite3_value_frombind(argv[i]) ) m |= ((sqlite3_uint64)1)<<i;
          647  +  }
          648  +  sqlite3_result_int64(context, (sqlite3_int64)m);
          649  +}
   632    650   
   633    651   /*         test_setsubtype(V, T)
   634    652   **
   635    653   ** Return the value V with its subtype changed to T
   636    654   */
   637    655   static void test_setsubtype(
   638    656     sqlite3_context *context,
................................................................................
   671    689       { "test_counter",          1, SQLITE_UTF8, counterFunc},
   672    690       { "real2hex",              1, SQLITE_UTF8, real2hex},
   673    691       { "test_decode",           1, SQLITE_UTF8, test_decode},
   674    692       { "test_extract",          2, SQLITE_UTF8, test_extract},
   675    693       { "test_zeroblob",  1, SQLITE_UTF8|SQLITE_DETERMINISTIC, test_zeroblob},
   676    694       { "test_getsubtype",       1, SQLITE_UTF8, test_getsubtype},
   677    695       { "test_setsubtype",       2, SQLITE_UTF8, test_setsubtype},
          696  +    { "test_frombind",        -1, SQLITE_UTF8, test_frombind},
   678    697     };
   679    698     int i;
   680    699   
   681    700     for(i=0; i<sizeof(aFuncs)/sizeof(aFuncs[0]); i++){
   682    701       sqlite3_create_function(db, aFuncs[i].zName, aFuncs[i].nArg,
   683    702           aFuncs[i].eTextRep, 0, aFuncs[i].xFunc, 0, 0);
   684    703     }

Changes to src/test_tclsh.c.

   103    103     extern int Sqlitetestfts3_Init(Tcl_Interp *interp);
   104    104   #endif
   105    105   #ifdef SQLITE_ENABLE_ZIPVFS
   106    106     extern int Zipvfs_Init(Tcl_Interp*);
   107    107   #endif
   108    108     extern int TestExpert_Init(Tcl_Interp*);
   109    109     extern int Sqlitetest_window_Init(Tcl_Interp *);
          110  +  extern int Sqlitetestvdbecov_Init(Tcl_Interp *);
   110    111   
   111    112     Tcl_CmdInfo cmdInfo;
   112    113   
   113    114     /* Since the primary use case for this binary is testing of SQLite,
   114    115     ** be sure to generate core files if we crash */
   115    116   #if defined(unix)
   116    117     { struct rlimit x;
................................................................................
   170    171   
   171    172   
   172    173   #if defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4)
   173    174     Sqlitetestfts3_Init(interp);
   174    175   #endif
   175    176     TestExpert_Init(interp);
   176    177     Sqlitetest_window_Init(interp);
          178  +  Sqlitetestvdbecov_Init(interp);
   177    179   
   178    180     Tcl_CreateObjCommand(
   179    181         interp, "load_testfixture_extensions", load_testfixture_extensions,0,0
   180    182     );
   181    183     return 0;
   182    184   }
   183    185   

Added src/test_vdbecov.c.

            1  +/*
            2  +** 2019 April 02
            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  +*/
           14  +#if SQLITE_TEST          /* This file is used for testing only */
           15  +
           16  +#include "sqlite3.h"
           17  +#include "sqliteInt.h"
           18  +#if defined(INCLUDE_SQLITE_TCL_H)
           19  +#  include "sqlite_tcl.h"
           20  +#else
           21  +#  include "tcl.h"
           22  +#endif
           23  +
           24  +#ifdef SQLITE_VDBE_COVERAGE
           25  +
           26  +static u8 aBranchArray[200000];
           27  +
           28  +static void test_vdbe_branch(
           29  +  void *pCtx, 
           30  +  unsigned int iSrc, 
           31  +  unsigned char iBranch, 
           32  +  unsigned char iType
           33  +){
           34  +  if( iSrc<sizeof(aBranchArray) ){
           35  +    aBranchArray[iSrc] |= iBranch;
           36  +  }
           37  +}
           38  +
           39  +static void appendToList(
           40  +  Tcl_Obj *pList, 
           41  +  int iLine, 
           42  +  int iPath, 
           43  +  const char *zNever
           44  +){
           45  +  Tcl_Obj *pNew = Tcl_NewObj();
           46  +  Tcl_IncrRefCount(pNew);
           47  +  Tcl_ListObjAppendElement(0, pNew, Tcl_NewIntObj(iLine));
           48  +  Tcl_ListObjAppendElement(0, pNew, Tcl_NewIntObj(iPath));
           49  +  Tcl_ListObjAppendElement(0, pNew, Tcl_NewStringObj(zNever, -1));
           50  +  Tcl_ListObjAppendElement(0, pList, pNew);
           51  +  Tcl_DecrRefCount(pNew);
           52  +}
           53  +
           54  +
           55  +static int SQLITE_TCLAPI test_vdbe_coverage(
           56  +  ClientData cd,
           57  +  Tcl_Interp *interp,
           58  +  int objc,
           59  +  Tcl_Obj *CONST objv[]
           60  +){
           61  +  const char *aSub[] = { "start", "report", "stop", 0 };
           62  +  int iSub = -1;
           63  +  if( objc!=2 ){
           64  +    Tcl_WrongNumArgs(interp, 1, objv, "sub-command");
           65  +    return TCL_ERROR;
           66  +  }
           67  +
           68  +  if( Tcl_GetIndexFromObj(interp, objv[1], aSub, "sub-command", 0, &iSub) ){
           69  +    return TCL_ERROR;
           70  +  }
           71  +
           72  +  Tcl_ResetResult(interp);
           73  +  assert( iSub==0 || iSub==1 || iSub==2 );
           74  +  switch( iSub ){
           75  +    case 0:       /* start */
           76  +      memset(aBranchArray, 0, sizeof(aBranchArray));
           77  +      sqlite3_test_control(SQLITE_TESTCTRL_VDBE_COVERAGE, test_vdbe_branch, 0);
           78  +      break;
           79  +    case 1: {     /* report */
           80  +      int i;
           81  +      Tcl_Obj *pRes = Tcl_NewObj();
           82  +      Tcl_IncrRefCount(pRes);
           83  +      for(i=0; i<sizeof(aBranchArray); i++){
           84  +        u8 b = aBranchArray[i];
           85  +        int bFlag = ((b >> 4)==4);
           86  +        if( b ){
           87  +          if( (b & 0x01)==0 ){
           88  +            appendToList(pRes, i, 0, bFlag ? "less than" : "falls through");
           89  +          }
           90  +          if( (b & 0x02)==0 ){
           91  +            appendToList(pRes, i, 1, bFlag ? "equal" : "taken");
           92  +          }
           93  +          if( (b & 0x04)==0 ){
           94  +            appendToList(pRes, i, 2, bFlag ? "greater-than" : "NULL");
           95  +          }
           96  +        }
           97  +      }
           98  +      Tcl_SetObjResult(interp, pRes);
           99  +      Tcl_DecrRefCount(pRes);
          100  +      break;
          101  +    };
          102  +      
          103  +    default:      /* stop */         
          104  +      sqlite3_test_control(SQLITE_TESTCTRL_VDBE_COVERAGE, 0, 0);
          105  +      break;
          106  +  }
          107  +
          108  +  return TCL_OK;
          109  +}
          110  +
          111  +#endif  /* SQLITE_VDBE_COVERAGE */
          112  +
          113  +int Sqlitetestvdbecov_Init(Tcl_Interp *interp){
          114  +#ifdef SQLITE_VDBE_COVERAGE
          115  +  Tcl_CreateObjCommand(interp, "vdbe_coverage", test_vdbe_coverage, 0, 0);
          116  +#endif
          117  +  return TCL_OK;
          118  +}
          119  +
          120  +#endif

Changes to src/test_vfs.c.

   231    231       { SQLITE_OK,       "SQLITE_OK"     },
   232    232       { SQLITE_ERROR,    "SQLITE_ERROR"  },
   233    233       { SQLITE_IOERR,    "SQLITE_IOERR"  },
   234    234       { SQLITE_LOCKED,   "SQLITE_LOCKED" },
   235    235       { SQLITE_BUSY,     "SQLITE_BUSY"   },
   236    236       { SQLITE_READONLY, "SQLITE_READONLY"   },
   237    237       { SQLITE_READONLY_CANTINIT, "SQLITE_READONLY_CANTINIT"   },
          238  +    { -1,              "SQLITE_OMIT"   },
   238    239     };
   239    240   
   240    241     const char *z;
   241    242     int i;
   242    243   
   243    244     z = Tcl_GetStringResult(p->interp);
   244    245     for(i=0; i<ArraySize(aCode); i++){
................................................................................
   378    379   
   379    380     if( p->pScript && p->mask&TESTVFS_WRITE_MASK ){
   380    381       tvfsExecTcl(p, "xWrite", 
   381    382           Tcl_NewStringObj(pFd->zFilename, -1), pFd->pShmId, 
   382    383           Tcl_NewWideIntObj(iOfst), Tcl_NewIntObj(iAmt)
   383    384       );
   384    385       tvfsResultCode(p, &rc);
          386  +    if( rc<0 ) return SQLITE_OK;
   385    387     }
   386    388   
   387    389     if( rc==SQLITE_OK && tvfsInjectFullerr(p) ){
   388    390       rc = SQLITE_FULL;
   389    391     }
   390    392     if( rc==SQLITE_OK && p->mask&TESTVFS_WRITE_MASK && tvfsInjectIoerr(p) ){
   391    393       rc = SQLITE_IOERR;

Changes to src/treeview.c.

   305    305   #endif /* SQLITE_OMIT_WINDOWFUNC */
   306    306   
   307    307   #ifndef SQLITE_OMIT_WINDOWFUNC
   308    308   /*
   309    309   ** Generate a human-readable explanation for a Window object
   310    310   */
   311    311   void sqlite3TreeViewWindow(TreeView *pView, const Window *pWin, u8 more){
          312  +  int nElement = 0;
          313  +  if( pWin->pFilter ){
          314  +    sqlite3TreeViewItem(pView, "FILTER", 1);
          315  +    sqlite3TreeViewExpr(pView, pWin->pFilter, 0);
          316  +    sqlite3TreeViewPop(pView);
          317  +  }
   312    318     pView = sqlite3TreeViewPush(pView, more);
   313    319     if( pWin->zName ){
   314         -    sqlite3TreeViewLine(pView, "OVER %s", pWin->zName);
          320  +    sqlite3TreeViewLine(pView, "OVER %s (%p)", pWin->zName, pWin);
   315    321     }else{
   316         -    sqlite3TreeViewLine(pView, "OVER");
          322  +    sqlite3TreeViewLine(pView, "OVER (%p)", pWin);
          323  +  }
          324  +  if( pWin->zBase )    nElement++;
          325  +  if( pWin->pOrderBy ) nElement++;
          326  +  if( pWin->eFrmType ) nElement++;
          327  +  if( pWin->eExclude ) nElement++;
          328  +  if( pWin->zBase ){
          329  +    sqlite3TreeViewPush(pView, (--nElement)>0);
          330  +    sqlite3TreeViewLine(pView, "window: %s", pWin->zBase);
          331  +    sqlite3TreeViewPop(pView);
   317    332     }
   318    333     if( pWin->pPartition ){
   319         -    sqlite3TreeViewExprList(pView, pWin->pPartition, 1, "PARTITION-BY");
          334  +    sqlite3TreeViewExprList(pView, pWin->pPartition, nElement>0,"PARTITION-BY");
   320    335     }
   321    336     if( pWin->pOrderBy ){
   322         -    sqlite3TreeViewExprList(pView, pWin->pOrderBy, 1, "ORDER-BY");
          337  +    sqlite3TreeViewExprList(pView, pWin->pOrderBy, (--nElement)>0, "ORDER-BY");
   323    338     }
   324         -  if( pWin->eType ){
   325         -    sqlite3TreeViewItem(pView, pWin->eType==TK_RANGE ? "RANGE" : "ROWS", 0);
          339  +  if( pWin->eFrmType ){
          340  +    char zBuf[30];
          341  +    const char *zFrmType = "ROWS";
          342  +    if( pWin->eFrmType==TK_RANGE ) zFrmType = "RANGE";
          343  +    if( pWin->eFrmType==TK_GROUPS ) zFrmType = "GROUPS";
          344  +    sqlite3_snprintf(sizeof(zBuf),zBuf,"%s%s",zFrmType,
          345  +        pWin->bImplicitFrame ? " (implied)" : "");
          346  +    sqlite3TreeViewItem(pView, zBuf, (--nElement)>0);
   326    347       sqlite3TreeViewBound(pView, pWin->eStart, pWin->pStart, 1);
   327    348       sqlite3TreeViewBound(pView, pWin->eEnd, pWin->pEnd, 0);
   328    349       sqlite3TreeViewPop(pView);
   329    350     }
          351  +  if( pWin->eExclude ){
          352  +    char zBuf[30];
          353  +    const char *zExclude;
          354  +    switch( pWin->eExclude ){
          355  +      case TK_NO:      zExclude = "NO OTHERS";   break;
          356  +      case TK_CURRENT: zExclude = "CURRENT ROW"; break;
          357  +      case TK_GROUP:   zExclude = "GROUP";       break;
          358  +      case TK_TIES:    zExclude = "TIES";        break;
          359  +      default:
          360  +        sqlite3_snprintf(sizeof(zBuf),zBuf,"invalid(%d)", pWin->eExclude);
          361  +        zExclude = zBuf;
          362  +        break;
          363  +    }
          364  +    sqlite3TreeViewPush(pView, 0);
          365  +    sqlite3TreeViewLine(pView, "EXCLUDE %s", zExclude);
          366  +    sqlite3TreeViewPop(pView);
          367  +  }
   330    368     sqlite3TreeViewPop(pView);
   331    369   }
   332    370   #endif /* SQLITE_OMIT_WINDOWFUNC */
   333    371   
   334    372   #ifndef SQLITE_OMIT_WINDOWFUNC
   335    373   /*
   336    374   ** Generate a human-readable explanation for a Window Function object

Changes to src/utf.c.

   196    196   #ifndef SQLITE_OMIT_UTF16
   197    197   /*
   198    198   ** This routine transforms the internal text encoding used by pMem to
   199    199   ** desiredEnc. It is an error if the string is already of the desired
   200    200   ** encoding, or if *pMem does not contain a string value.
   201    201   */
   202    202   SQLITE_NOINLINE int sqlite3VdbeMemTranslate(Mem *pMem, u8 desiredEnc){
   203         -  int len;                    /* Maximum length of output string in bytes */
          203  +  sqlite3_int64 len;          /* Maximum length of output string in bytes */
   204    204     unsigned char *zOut;                  /* Output buffer */
   205    205     unsigned char *zIn;                   /* Input iterator */
   206    206     unsigned char *zTerm;                 /* End of input */
   207    207     unsigned char *z;                     /* Output iterator */
   208    208     unsigned int c;
   209    209   
   210    210     assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
................................................................................
   249    249     if( desiredEnc==SQLITE_UTF8 ){
   250    250       /* When converting from UTF-16, the maximum growth results from
   251    251       ** translating a 2-byte character to a 4-byte UTF-8 character.
   252    252       ** A single byte is required for the output string
   253    253       ** nul-terminator.
   254    254       */
   255    255       pMem->n &= ~1;
   256         -    len = pMem->n * 2 + 1;
          256  +    len = 2 * (sqlite3_int64)pMem->n + 1;
   257    257     }else{
   258    258       /* When converting from UTF-8 to UTF-16 the maximum growth is caused
   259    259       ** when a 1-byte UTF-8 character is translated into a 2-byte UTF-16
   260    260       ** character. Two bytes are required in the output buffer for the
   261    261       ** nul-terminator.
   262    262       */
   263         -    len = pMem->n * 2 + 2;
          263  +    len = 2 * (sqlite3_int64)pMem->n + 2;
   264    264     }
   265    265   
   266    266     /* Set zIn to point at the start of the input buffer and zTerm to point 1
   267    267     ** byte past the end.
   268    268     **
   269    269     ** Variable zOut is set to point at the output buffer, space obtained
   270    270     ** from sqlite3_malloc().

Changes to src/util.c.

    28     28   void sqlite3Coverage(int x){
    29     29     static unsigned dummy = 0;
    30     30     dummy += (unsigned)x;
    31     31   }
    32     32   #endif
    33     33   
    34     34   /*
    35         -** Give a callback to the test harness that can be used to simulate faults
    36         -** in places where it is difficult or expensive to do so purely by means
    37         -** of inputs.
           35  +** Calls to sqlite3FaultSim() are used to simulate a failure during testing,
           36  +** or to bypass normal error detection during testing in order to let 
           37  +** execute proceed futher downstream.
    38     38   **
    39         -** The intent of the integer argument is to let the fault simulator know
    40         -** which of multiple sqlite3FaultSim() calls has been hit.
           39  +** In deployment, sqlite3FaultSim() *always* return SQLITE_OK (0).  The
           40  +** sqlite3FaultSim() function only returns non-zero during testing.
    41     41   **
    42         -** Return whatever integer value the test callback returns, or return
    43         -** SQLITE_OK if no test callback is installed.
           42  +** During testing, if the test harness has set a fault-sim callback using
           43  +** a call to sqlite3_test_control(SQLITE_TESTCTRL_FAULT_INSTALL), then
           44  +** each call to sqlite3FaultSim() is relayed to that application-supplied
           45  +** callback and the integer return value form the application-supplied
           46  +** callback is returned by sqlite3FaultSim().
           47  +**
           48  +** The integer argument to sqlite3FaultSim() is a code to identify which
           49  +** sqlite3FaultSim() instance is being invoked. Each call to sqlite3FaultSim()
           50  +** should have a unique code.  To prevent legacy testing applications from
           51  +** breaking, the codes should not be changed or reused.
    44     52   */
    45     53   #ifndef SQLITE_UNTESTABLE
    46     54   int sqlite3FaultSim(int iTest){
    47     55     int (*xCallback)(int) = sqlite3GlobalConfig.xTestCallback;
    48     56     return xCallback ? xCallback(iTest) : SQLITE_OK;
    49     57   }
    50     58   #endif
................................................................................
   220    228     }else{
   221    229       pParse->nErr++;
   222    230       sqlite3DbFree(db, pParse->zErrMsg);
   223    231       pParse->zErrMsg = zMsg;
   224    232       pParse->rc = SQLITE_ERROR;
   225    233     }
   226    234   }
          235  +
          236  +/*
          237  +** If database connection db is currently parsing SQL, then transfer
          238  +** error code errCode to that parser if the parser has not already
          239  +** encountered some other kind of error.
          240  +*/
          241  +int sqlite3ErrorToParser(sqlite3 *db, int errCode){
          242  +  Parse *pParse;
          243  +  if( db==0 || (pParse = db->pParse)==0 ) return errCode;
          244  +  pParse->rc = errCode;
          245  +  pParse->nErr++;
          246  +  return errCode;
          247  +}
   227    248   
   228    249   /*
   229    250   ** Convert an SQL-style quoted string into a normal string by removing
   230    251   ** the quote characters.  The conversion is done in-place.  If the
   231    252   ** input does not begin with a quote character, then this routine
   232    253   ** is a no-op.
   233    254   **
................................................................................
  1572   1593     char *z;               /* Pointer to where zName will be stored */
  1573   1594     int i;                 /* Index in pIn[] where zName is stored */
  1574   1595   
  1575   1596     nInt = nName/4 + 3;
  1576   1597     assert( pIn==0 || pIn[0]>=3 );  /* Verify ok to add new elements */
  1577   1598     if( pIn==0 || pIn[1]+nInt > pIn[0] ){
  1578   1599       /* Enlarge the allocation */
  1579         -    int nAlloc = (pIn ? pIn[0]*2 : 10) + nInt;
         1600  +    sqlite3_int64 nAlloc = (pIn ? 2*(sqlite3_int64)pIn[0] : 10) + nInt;
  1580   1601       VList *pOut = sqlite3DbRealloc(db, pIn, nAlloc*sizeof(int));
  1581   1602       if( pOut==0 ) return pIn;
  1582   1603       if( pIn==0 ) pOut[1] = 2;
  1583   1604       pIn = pOut;
  1584   1605       pIn[0] = nAlloc;
  1585   1606     }
  1586   1607     i = pIn[1];

Changes to src/vacuum.c.

   135    135     sqlite3ExprDelete(pParse->db, pInto);
   136    136     return;
   137    137   }
   138    138   
   139    139   /*
   140    140   ** This routine implements the OP_Vacuum opcode of the VDBE.
   141    141   */
   142         -int sqlite3RunVacuum(
          142  +SQLITE_NOINLINE int sqlite3RunVacuum(
   143    143     char **pzErrMsg,        /* Write error message here */
   144    144     sqlite3 *db,            /* Database connection */
   145    145     int iDb,                /* Which attached DB to vacuum */
   146    146     sqlite3_value *pOut     /* Write results here, if not NULL. VACUUM INTO */
   147    147   ){
   148    148     int rc = SQLITE_OK;     /* Return code from service routines */
   149    149     Btree *pMain;           /* The database being vacuumed */
................................................................................
   159    159     int nRes;               /* Bytes of reserved space at the end of each page */
   160    160     int nDb;                /* Number of attached databases */
   161    161     const char *zDbMain;    /* Schema name of database to vacuum */
   162    162     const char *zOut;       /* Name of output file */
   163    163   
   164    164     if( !db->autoCommit ){
   165    165       sqlite3SetString(pzErrMsg, db, "cannot VACUUM from within a transaction");
   166         -    return SQLITE_ERROR;
          166  +    return SQLITE_ERROR; /* IMP: R-12218-18073 */
   167    167     }
   168    168     if( db->nVdbeActive>1 ){
   169    169       sqlite3SetString(pzErrMsg, db,"cannot VACUUM - SQL statements in progress");
   170         -    return SQLITE_ERROR;
          170  +    return SQLITE_ERROR; /* IMP: R-15610-35227 */
   171    171     }
   172    172     saved_openFlags = db->openFlags;
   173    173     if( pOut ){
   174    174       if( sqlite3_value_type(pOut)!=SQLITE_TEXT ){
   175    175         sqlite3SetString(pzErrMsg, db, "non-text filename");
   176    176         return SQLITE_ERROR;
   177    177       }
................................................................................
   226    226       sqlite3_file *id = sqlite3PagerFile(sqlite3BtreePager(pTemp));
   227    227       i64 sz = 0;
   228    228       if( id->pMethods!=0 && (sqlite3OsFileSize(id, &sz)!=SQLITE_OK || sz>0) ){
   229    229         rc = SQLITE_ERROR;
   230    230         sqlite3SetString(pzErrMsg, db, "output file already exists");
   231    231         goto end_of_vacuum;
   232    232       }
          233  +    db->mDbFlags |= DBFLAG_VacuumInto;
   233    234     }
   234    235     nRes = sqlite3BtreeGetOptimalReserve(pMain);
   235    236   
   236    237     /* A VACUUM cannot change the pagesize of an encrypted database. */
   237    238   #ifdef SQLITE_HAS_CODEC
   238    239     if( db->nextPagesize ){
   239    240       extern void sqlite3CodecGetKey(sqlite3*, int, void**, int*);

Changes to src/vdbe.c.

   118    118   #endif
   119    119   
   120    120   /*
   121    121   ** Invoke the VDBE coverage callback, if that callback is defined.  This
   122    122   ** feature is used for test suite validation only and does not appear an
   123    123   ** production builds.
   124    124   **
   125         -** M is an integer between 2 and 4.  2 indicates a ordinary two-way
   126         -** branch (I=0 means fall through and I=1 means taken).  3 indicates
   127         -** a 3-way branch where the third way is when one of the operands is
   128         -** NULL.  4 indicates the OP_Jump instruction which has three destinations
   129         -** depending on whether the first operand is less than, equal to, or greater
   130         -** than the second. 
          125  +** M is the type of branch.  I is the direction taken for this instance of
          126  +** the branch.
          127  +**
          128  +**   M: 2 - two-way branch (I=0: fall-thru   1: jump                )
          129  +**      3 - two-way + NULL (I=0: fall-thru   1: jump      2: NULL   )
          130  +**      4 - OP_Jump        (I=0: jump p1     1: jump p2   2: jump p3)
          131  +**
          132  +** In other words, if M is 2, then I is either 0 (for fall-through) or
          133  +** 1 (for when the branch is taken).  If M is 3, the I is 0 for an
          134  +** ordinary fall-through, I is 1 if the branch was taken, and I is 2 
          135  +** if the result of comparison is NULL.  For M=3, I=2 the jump may or
          136  +** may not be taken, depending on the SQLITE_JUMPIFNULL flags in p5.
          137  +** When M is 4, that means that an OP_Jump is being run.  I is 0, 1, or 2
          138  +** depending on if the operands are less than, equal, or greater than.
   131    139   **
   132    140   ** iSrcLine is the source code line (from the __LINE__ macro) that
   133    141   ** generated the VDBE instruction combined with flag bits.  The source
   134    142   ** code line number is in the lower 24 bits of iSrcLine and the upper
   135    143   ** 8 bytes are flags.  The lower three bits of the flags indicate
   136    144   ** values for I that should never occur.  For example, if the branch is
   137    145   ** always taken, the flags should be 0x05 since the fall-through and
   138    146   ** alternate branch are never taken.  If a branch is never taken then
   139    147   ** flags should be 0x06 since only the fall-through approach is allowed.
   140    148   **
   141         -** Bit 0x04 of the flags indicates an OP_Jump opcode that is only
          149  +** Bit 0x08 of the flags indicates an OP_Jump opcode that is only
   142    150   ** interested in equal or not-equal.  In other words, I==0 and I==2
   143         -** should be treated the same.
          151  +** should be treated as equivalent
   144    152   **
   145    153   ** Since only a line number is retained, not the filename, this macro
   146    154   ** only works for amalgamation builds.  But that is ok, since these macros
   147    155   ** should be no-ops except for special builds used to measure test coverage.
   148    156   */
   149    157   #if !defined(SQLITE_VDBE_COVERAGE)
   150    158   # define VdbeBranchTaken(I,M)
................................................................................
   160    168       /* The upper 8 bits of iSrcLine are flags.  The lower three bits of
   161    169       ** the flags indicate directions that the branch can never go.  If
   162    170       ** a branch really does go in one of those directions, assert right
   163    171       ** away. */
   164    172       mNever = iSrcLine >> 24;
   165    173       assert( (I & mNever)==0 );
   166    174       if( sqlite3GlobalConfig.xVdbeBranch==0 ) return;  /*NO_TEST*/
          175  +    /* Invoke the branch coverage callback with three arguments:
          176  +    **    iSrcLine - the line number of the VdbeCoverage() macro, with
          177  +    **               flags removed.
          178  +    **    I        - Mask of bits 0x07 indicating which cases are are
          179  +    **               fulfilled by this instance of the jump.  0x01 means
          180  +    **               fall-thru, 0x02 means taken, 0x04 means NULL.  Any
          181  +    **               impossible cases (ex: if the comparison is never NULL)
          182  +    **               are filled in automatically so that the coverage
          183  +    **               measurement logic does not flag those impossible cases
          184  +    **               as missed coverage.
          185  +    **    M        - Type of jump.  Same as M argument above
          186  +    */
   167    187       I |= mNever;
   168    188       if( M==2 ) I |= 0x04;
   169    189       if( M==4 ){
   170    190         I |= 0x08;
   171    191         if( (mNever&0x08)!=0 && (I&0x05)!=0) I |= 0x05; /*NO_TEST*/
   172    192       }
   173    193       sqlite3GlobalConfig.xVdbeBranch(sqlite3GlobalConfig.pVdbeBranchArg,
................................................................................
  1232   1252     assert( pOp->p1>0 && pOp->p1<=p->nVar );
  1233   1253     assert( pOp->p4.z==0 || pOp->p4.z==sqlite3VListNumToName(p->pVList,pOp->p1) );
  1234   1254     pVar = &p->aVar[pOp->p1 - 1];
  1235   1255     if( sqlite3VdbeMemTooBig(pVar) ){
  1236   1256       goto too_big;
  1237   1257     }
  1238   1258     pOut = &aMem[pOp->p2];
  1239         -  sqlite3VdbeMemShallowCopy(pOut, pVar, MEM_Static);
         1259  +  if( VdbeMemDynamic(pOut) ) sqlite3VdbeMemSetNull(pOut);
         1260  +  memcpy(pOut, pVar, MEMCELLSIZE);
         1261  +  pOut->flags &= ~(MEM_Dyn|MEM_Ephem);
         1262  +  pOut->flags |= MEM_Static|MEM_FromBind;
  1240   1263     UPDATE_MAX_BLOBSIZE(pOut);
  1241   1264     break;
  1242   1265   }
  1243   1266   
  1244   1267   /* Opcode: Move P1 P2 P3 * *
  1245   1268   ** Synopsis: r[P2@P3]=r[P1@P3]
  1246   1269   **
................................................................................
  1730   1753   ** without data loss, then jump immediately to P2, or if P2==0
  1731   1754   ** raise an SQLITE_MISMATCH exception.
  1732   1755   */
  1733   1756   case OP_MustBeInt: {            /* jump, in1 */
  1734   1757     pIn1 = &aMem[pOp->p1];
  1735   1758     if( (pIn1->flags & MEM_Int)==0 ){
  1736   1759       applyAffinity(pIn1, SQLITE_AFF_NUMERIC, encoding);
  1737         -    VdbeBranchTaken((pIn1->flags&MEM_Int)==0, 2);
  1738   1760       if( (pIn1->flags & MEM_Int)==0 ){
         1761  +      VdbeBranchTaken(1, 2);
  1739   1762         if( pOp->p2==0 ){
  1740   1763           rc = SQLITE_MISMATCH;
  1741   1764           goto abort_due_to_error;
  1742   1765         }else{
  1743   1766           goto jump_to_p2;
  1744   1767         }
  1745   1768       }
  1746   1769     }
         1770  +  VdbeBranchTaken(0, 2);
  1747   1771     MemSetTypeFlag(pIn1, MEM_Int);
  1748   1772     break;
  1749   1773   }
  1750   1774   
  1751   1775   #ifndef SQLITE_OMIT_FLOATING_POINT
  1752   1776   /* Opcode: RealAffinity P1 * * * *
  1753   1777   **
................................................................................
  1914   1938     if( (flags1 | flags3)&MEM_Null ){
  1915   1939       /* One or both operands are NULL */
  1916   1940       if( pOp->p5 & SQLITE_NULLEQ ){
  1917   1941         /* If SQLITE_NULLEQ is set (which will only happen if the operator is
  1918   1942         ** OP_Eq or OP_Ne) then take the jump or not depending on whether
  1919   1943         ** or not both operands are null.
  1920   1944         */
  1921         -      assert( pOp->opcode==OP_Eq || pOp->opcode==OP_Ne );
  1922   1945         assert( (flags1 & MEM_Cleared)==0 );
  1923   1946         assert( (pOp->p5 & SQLITE_JUMPIFNULL)==0 || CORRUPT_DB );
  1924   1947         testcase( (pOp->p5 & SQLITE_JUMPIFNULL)!=0 );
  1925   1948         if( (flags1&flags3&MEM_Null)!=0
  1926   1949          && (flags3&MEM_Cleared)==0
  1927   1950         ){
  1928   1951           res = 0;  /* Operands are equal */
  1929   1952         }else{
  1930         -        res = 1;  /* Operands are not equal */
         1953  +        res = ((flags3 & MEM_Null) ? -1 : +1);  /* Operands are not equal */
  1931   1954         }
  1932   1955       }else{
  1933   1956         /* SQLITE_NULLEQ is clear and at least one operand is NULL,
  1934   1957         ** then the result is always NULL.
  1935   1958         ** The jump is taken if the SQLITE_JUMPIFNULL bit is set.
  1936   1959         */
  1937   1960         if( pOp->p5 & SQLITE_STOREP2 ){
................................................................................
  2041   2064         if( (pOp->opcode==OP_Eq)==res2 ) break;
  2042   2065       }
  2043   2066       memAboutToChange(p, pOut);
  2044   2067       MemSetTypeFlag(pOut, MEM_Int);
  2045   2068       pOut->u.i = res2;
  2046   2069       REGISTER_TRACE(pOp->p2, pOut);
  2047   2070     }else{
  2048         -    VdbeBranchTaken(res!=0, (pOp->p5 & SQLITE_NULLEQ)?2:3);
         2071  +    VdbeBranchTaken(res2!=0, (pOp->p5 & SQLITE_NULLEQ)?2:3);
  2049   2072       if( res2 ){
  2050   2073         goto jump_to_p2;
  2051   2074       }
  2052   2075     }
  2053   2076     break;
  2054   2077   }
  2055   2078   
................................................................................
  3633   3656     pCx = allocateCursor(p, pOp->p1, pOrig->nField, -1, CURTYPE_BTREE);
  3634   3657     if( pCx==0 ) goto no_mem;
  3635   3658     pCx->nullRow = 1;
  3636   3659     pCx->isEphemeral = 1;
  3637   3660     pCx->pKeyInfo = pOrig->pKeyInfo;
  3638   3661     pCx->isTable = pOrig->isTable;
  3639   3662     pCx->pgnoRoot = pOrig->pgnoRoot;
         3663  +  pCx->isOrdered = pOrig->isOrdered;
  3640   3664     rc = sqlite3BtreeCursor(pOrig->pBtx, pCx->pgnoRoot, BTREE_WRCSR,
  3641   3665                             pCx->pKeyInfo, pCx->uc.pCursor);
  3642   3666     /* The sqlite3BtreeCursor() routine can only fail for the first cursor
  3643   3667     ** opened for a database.  Since there is already an open cursor when this
  3644   3668     ** opcode is run, the sqlite3BtreeCursor() cannot fail */
  3645   3669     assert( rc==SQLITE_OK );
  3646   3670     break;
................................................................................
  5141   5165   #ifdef SQLITE_TEST
  5142   5166     sqlite3_sort_count++;
  5143   5167     sqlite3_search_count--;
  5144   5168   #endif
  5145   5169     p->aCounter[SQLITE_STMTSTATUS_SORT]++;
  5146   5170     /* Fall through into OP_Rewind */
  5147   5171   }
  5148         -/* Opcode: Rewind P1 P2 * * P5
         5172  +/* Opcode: Rewind P1 P2 * * *
  5149   5173   **
  5150   5174   ** The next use of the Rowid or Column or Next instruction for P1 
  5151   5175   ** will refer to the first entry in the database table or index.
  5152   5176   ** If the table or index is empty, jump immediately to P2.
  5153   5177   ** If the table or index is not empty, fall through to the following 
  5154   5178   ** instruction.
  5155   5179   **
  5156         -** If P5 is non-zero and the table is not empty, then the "skip-next"
  5157         -** flag is set on the cursor so that the next OP_Next instruction 
  5158         -** executed on it is a no-op.
  5159         -**
  5160   5180   ** This opcode leaves the cursor configured to move in forward order,
  5161   5181   ** from the beginning toward the end.  In other words, the cursor is
  5162   5182   ** configured to use Next, not Prev.
  5163   5183   */
  5164   5184   case OP_Rewind: {        /* jump */
  5165   5185     VdbeCursor *pC;
  5166   5186     BtCursor *pCrsr;
  5167   5187     int res;
  5168   5188   
  5169   5189     assert( pOp->p1>=0 && pOp->p1<p->nCursor );
         5190  +  assert( pOp->p5==0 );
  5170   5191     pC = p->apCsr[pOp->p1];
  5171   5192     assert( pC!=0 );
  5172   5193     assert( isSorter(pC)==(pOp->opcode==OP_SorterSort) );
  5173   5194     res = 1;
  5174   5195   #ifdef SQLITE_DEBUG
  5175   5196     pC->seekOp = OP_Rewind;
  5176   5197   #endif
................................................................................
  5177   5198     if( isSorter(pC) ){
  5178   5199       rc = sqlite3VdbeSorterRewind(pC, &res);
  5179   5200     }else{
  5180   5201       assert( pC->eCurType==CURTYPE_BTREE );
  5181   5202       pCrsr = pC->uc.pCursor;
  5182   5203       assert( pCrsr );
  5183   5204       rc = sqlite3BtreeFirst(pCrsr, &res);
  5184         -#ifndef SQLITE_OMIT_WINDOWFUNC
  5185         -    if( pOp->p5 ) sqlite3BtreeSkipNext(pCrsr);
  5186         -#endif
  5187   5205       pC->deferredMoveto = 0;
  5188   5206       pC->cacheStatus = CACHE_STALE;
  5189   5207     }
  5190   5208     if( rc ) goto abort_due_to_error;
  5191   5209     pC->nullRow = (u8)res;
  5192   5210     assert( pOp->p2>0 && pOp->p2<p->nOp );
  5193   5211     VdbeBranchTaken(res!=0,2);
................................................................................
  6561   6579     Mem *pMem;
  6562   6580     assert( pOp->p1>0 && pOp->p1<=(p->nMem+1 - p->nCursor) );
  6563   6581     assert( pOp->p3==0 || pOp->opcode==OP_AggValue );
  6564   6582     pMem = &aMem[pOp->p1];
  6565   6583     assert( (pMem->flags & ~(MEM_Null|MEM_Agg))==0 );
  6566   6584   #ifndef SQLITE_OMIT_WINDOWFUNC
  6567   6585     if( pOp->p3 ){
         6586  +    memAboutToChange(p, &aMem[pOp->p3]);
  6568   6587       rc = sqlite3VdbeMemAggValue(pMem, &aMem[pOp->p3], pOp->p4.pFunc);
  6569   6588       pMem = &aMem[pOp->p3];
  6570   6589     }else
  6571   6590   #endif
  6572   6591     {
  6573   6592       rc = sqlite3VdbeMemFinalize(pMem, pOp->p4.pFunc);
  6574   6593     }

Changes to src/vdbeInt.h.

   242    242   */
   243    243   #define MEM_Null      0x0001   /* Value is NULL (or a pointer) */
   244    244   #define MEM_Str       0x0002   /* Value is a string */
   245    245   #define MEM_Int       0x0004   /* Value is an integer */
   246    246   #define MEM_Real      0x0008   /* Value is a real number */
   247    247   #define MEM_Blob      0x0010   /* Value is a BLOB */
   248    248   #define MEM_AffMask   0x001f   /* Mask of affinity bits */
   249         -/* Available          0x0020   */
          249  +#define MEM_FromBind  0x0020   /* Value originates from sqlite3_bind() */
   250    250   /* Available          0x0040   */
   251    251   #define MEM_Undefined 0x0080   /* Value is undefined */
   252    252   #define MEM_Cleared   0x0100   /* NULL set by OP_Null, not from data */
   253         -#define MEM_TypeMask  0xc1ff   /* Mask of type bits */
          253  +#define MEM_TypeMask  0xc1df   /* Mask of type bits */
   254    254   
   255    255   
   256    256   /* Whenever Mem contains a valid string or blob representation, one of
   257    257   ** the following flags must be set to determine the memory management
   258    258   ** policy for Mem.z.  The MEM_Term flag tells us whether or not the
   259    259   ** string is \000 or \u0000 terminated
   260    260   */
................................................................................
   278    278   
   279    279   /*
   280    280   ** Clear any existing type flags from a Mem and replace them with f
   281    281   */
   282    282   #define MemSetTypeFlag(p, f) \
   283    283      ((p)->flags = ((p)->flags&~(MEM_TypeMask|MEM_Zero))|f)
   284    284   
          285  +/*
          286  +** True if Mem X is a NULL-nochng type.
          287  +*/
          288  +#define MemNullNochng(X) \
          289  +  ((X)->flags==(MEM_Null|MEM_Zero) && (X)->n==0 && (X)->u.nZero==0)
          290  +
   285    291   /*
   286    292   ** Return true if a memory cell is not marked as invalid.  This macro
   287    293   ** is for use inside assert() statements only.
   288    294   */
   289    295   #ifdef SQLITE_DEBUG
   290    296   #define memIsValid(M)  ((M)->flags & MEM_Undefined)==0
   291    297   #endif

Changes to src/vdbeapi.c.

   270    270     return aType[pVal->flags&MEM_AffMask];
   271    271   }
   272    272   
   273    273   /* Return true if a parameter to xUpdate represents an unchanged column */
   274    274   int sqlite3_value_nochange(sqlite3_value *pVal){
   275    275     return (pVal->flags&(MEM_Null|MEM_Zero))==(MEM_Null|MEM_Zero);
   276    276   }
          277  +
          278  +/* Return true if a parameter value originated from an sqlite3_bind() */
          279  +int sqlite3_value_frombind(sqlite3_value *pVal){
          280  +  return (pVal->flags&MEM_FromBind)!=0;
          281  +}
   277    282   
   278    283   /* Make a copy of an sqlite3_value object
   279    284   */
   280    285   sqlite3_value *sqlite3_value_dup(const sqlite3_value *pOrig){
   281    286     sqlite3_value *pNew;
   282    287     if( pOrig==0 ) return 0;
   283    288     pNew = sqlite3_malloc( sizeof(*pNew) );

Changes to src/vdbeaux.c.

   151    151     ** more frequent reallocs and hence provide more opportunities for 
   152    152     ** simulated OOM faults.  SQLITE_TEST_REALLOC_STRESS is generally used
   153    153     ** during testing only.  With SQLITE_TEST_REALLOC_STRESS grow the op array
   154    154     ** by the minimum* amount required until the size reaches 512.  Normal
   155    155     ** operation (without SQLITE_TEST_REALLOC_STRESS) is to double the current
   156    156     ** size of the op array or add 1KB of space, whichever is smaller. */
   157    157   #ifdef SQLITE_TEST_REALLOC_STRESS
   158         -  int nNew = (v->nOpAlloc>=512 ? v->nOpAlloc*2 : v->nOpAlloc+nOp);
          158  +  sqlite3_int64 nNew = (v->nOpAlloc>=512 ? 2*(sqlite3_int64)v->nOpAlloc
          159  +                        : (sqlite3_int64)v->nOpAlloc+nOp);
   159    160   #else
   160         -  int nNew = (v->nOpAlloc ? v->nOpAlloc*2 : (int)(1024/sizeof(Op)));
          161  +  sqlite3_int64 nNew = (v->nOpAlloc ? 2*(sqlite3_int64)v->nOpAlloc
          162  +                        : (sqlite3_int64)(1024/sizeof(Op)));
   161    163     UNUSED_PARAMETER(nOp);
   162    164   #endif
   163    165   
   164    166     /* Ensure that the size of a VDBE does not grow too large */
   165    167     if( nNew > p->db->aLimit[SQLITE_LIMIT_VDBE_OP] ){
   166    168       sqlite3OomFault(p->db);
   167    169       return SQLITE_NOMEM;
................................................................................
   941    943     Vdbe *p,                        /* VM to add scanstatus() to */
   942    944     int addrExplain,                /* Address of OP_Explain (or 0) */
   943    945     int addrLoop,                   /* Address of loop counter */ 
   944    946     int addrVisit,                  /* Address of rows visited counter */
   945    947     LogEst nEst,                    /* Estimated number of output rows */
   946    948     const char *zName               /* Name of table or index being scanned */
   947    949   ){
   948         -  int nByte = (p->nScan+1) * sizeof(ScanStatus);
          950  +  sqlite3_int64 nByte = (p->nScan+1) * sizeof(ScanStatus);
   949    951     ScanStatus *aNew;
   950    952     aNew = (ScanStatus*)sqlite3DbRealloc(p->db, p->aScan, nByte);
   951    953     if( aNew ){
   952    954       ScanStatus *pNew = &aNew[p->nScan++];
   953    955       pNew->addrExplain = addrExplain;
   954    956       pNew->addrLoop = addrLoop;
   955    957       pNew->addrVisit = addrVisit;
................................................................................
  2063   2065   
  2064   2066   /* An instance of this object describes bulk memory available for use
  2065   2067   ** by subcomponents of a prepared statement.  Space is allocated out
  2066   2068   ** of a ReusableSpace object by the allocSpace() routine below.
  2067   2069   */
  2068   2070   struct ReusableSpace {
  2069   2071     u8 *pSpace;          /* Available memory */
  2070         -  int nFree;           /* Bytes of available memory */
  2071         -  int nNeeded;         /* Total bytes that could not be allocated */
         2072  +  sqlite3_int64 nFree;   /* Bytes of available memory */
         2073  +  sqlite3_int64 nNeeded; /* Total bytes that could not be allocated */
  2072   2074   };
  2073   2075   
  2074   2076   /* Try to allocate nByte bytes of 8-byte aligned bulk memory for pBuf
  2075   2077   ** from the ReusableSpace object.  Return a pointer to the allocated
  2076   2078   ** memory on success.  If insufficient memory is available in the
  2077   2079   ** ReusableSpace object, increase the ReusableSpace.nNeeded
  2078   2080   ** value by the amount needed and return NULL.
................................................................................
  2084   2086   ** This allocator is employed to repurpose unused slots at the end of the
  2085   2087   ** opcode array of prepared state for other memory needs of the prepared
  2086   2088   ** statement.
  2087   2089   */
  2088   2090   static void *allocSpace(
  2089   2091     struct ReusableSpace *p,  /* Bulk memory available for allocation */
  2090   2092     void *pBuf,               /* Pointer to a prior allocation */
  2091         -  int nByte                 /* Bytes of memory needed */
         2093  +  sqlite3_int64 nByte       /* Bytes of memory needed */
  2092   2094   ){
  2093   2095     assert( EIGHT_BYTE_ALIGNMENT(p->pSpace) );
  2094   2096     if( pBuf==0 ){
  2095   2097       nByte = ROUND8(nByte);
  2096   2098       if( nByte <= p->nFree ){
  2097   2099         p->nFree -= nByte;
  2098   2100         pBuf = &p->pSpace[p->nFree];

Changes to src/vdbemem.c.

    53     53         /* This is a pointer type.  There may be a flag to indicate what to
    54     54         ** do with the pointer. */
    55     55         assert( ((p->flags&MEM_Dyn)!=0 ? 1 : 0) +
    56     56                 ((p->flags&MEM_Ephem)!=0 ? 1 : 0) +
    57     57                 ((p->flags&MEM_Static)!=0 ? 1 : 0) <= 1 );
    58     58   
    59     59         /* No other bits set */
    60         -      assert( (p->flags & ~(MEM_Null|MEM_Term|MEM_Subtype
           60  +      assert( (p->flags & ~(MEM_Null|MEM_Term|MEM_Subtype|MEM_FromBind
    61     61                              |MEM_Dyn|MEM_Ephem|MEM_Static))==0 );
    62     62       }else{
    63     63         /* A pure NULL might have other flags, such as MEM_Static, MEM_Dyn,
    64     64         ** MEM_Ephem, MEM_Cleared, or MEM_Subtype */
    65     65       }
    66     66     }else{
    67     67       /* The MEM_Cleared bit is only allowed on NULLs */
................................................................................
   294    294   ** If the given Mem* has a zero-filled tail, turn it into an ordinary
   295    295   ** blob stored in dynamically allocated space.
   296    296   */
   297    297   #ifndef SQLITE_OMIT_INCRBLOB
   298    298   int sqlite3VdbeMemExpandBlob(Mem *pMem){
   299    299     int nByte;
   300    300     assert( pMem->flags & MEM_Zero );
   301         -  assert( pMem->flags&MEM_Blob );
          301  +  assert( (pMem->flags&MEM_Blob)!=0 || MemNullNochng(pMem) );
          302  +  testcase( sqlite3_value_nochange(pMem) );
   302    303     assert( !sqlite3VdbeMemIsRowSet(pMem) );
   303    304     assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
   304    305   
   305    306     /* Set nByte to the number of bytes required to store the expanded blob. */
   306    307     nByte = pMem->n + pMem->u.nZero;
   307    308     if( nByte<=0 ){
          309  +    if( (pMem->flags & MEM_Blob)==0 ) return SQLITE_OK;
   308    310       nByte = 1;
   309    311     }
   310    312     if( sqlite3VdbeMemGrow(pMem, nByte, 1) ){
   311    313       return SQLITE_NOMEM_BKPT;
   312    314     }
   313    315   
   314    316     memset(&pMem->z[pMem->n], 0, pMem->u.nZero);
................................................................................
  1057   1059     */
  1058   1060     if( xDel==SQLITE_TRANSIENT ){
  1059   1061       u32 nAlloc = nByte;
  1060   1062       if( flags&MEM_Term ){
  1061   1063         nAlloc += (enc==SQLITE_UTF8?1:2);
  1062   1064       }
  1063   1065       if( nByte>iLimit ){
  1064         -      return SQLITE_TOOBIG;
         1066  +      return sqlite3ErrorToParser(pMem->db, SQLITE_TOOBIG);
  1065   1067       }
  1066   1068       testcase( nAlloc==0 );
  1067   1069       testcase( nAlloc==31 );
  1068   1070       testcase( nAlloc==32 );
  1069   1071       if( sqlite3VdbeMemClearAndResize(pMem, (int)MAX(nAlloc,32)) ){
  1070   1072         return SQLITE_NOMEM_BKPT;
  1071   1073       }

Changes to src/vdbesort.c.

   533    533       ** In this case, allocate space at p->aAlloc[] to copy the requested
   534    534       ** range into. Then return a copy of pointer p->aAlloc to the caller.  */
   535    535       int nRem;                     /* Bytes remaining to copy */
   536    536   
   537    537       /* Extend the p->aAlloc[] allocation if required. */
   538    538       if( p->nAlloc<nByte ){
   539    539         u8 *aNew;
   540         -      int nNew = MAX(128, p->nAlloc*2);
          540  +      sqlite3_int64 nNew = MAX(128, 2*(sqlite3_int64)p->nAlloc);
   541    541         while( nByte>nNew ) nNew = nNew*2;
   542    542         aNew = sqlite3Realloc(p->aAlloc, nNew);
   543    543         if( !aNew ) return SQLITE_NOMEM_BKPT;
   544    544         p->nAlloc = nNew;
   545    545         p->aAlloc = aNew;
   546    546       }
   547    547   
................................................................................
  1825   1825   
  1826   1826     if( pSorter->list.aMemory ){
  1827   1827       int nMin = pSorter->iMemory + nReq;
  1828   1828   
  1829   1829       if( nMin>pSorter->nMemory ){
  1830   1830         u8 *aNew;
  1831   1831         int iListOff = (u8*)pSorter->list.pList - pSorter->list.aMemory;
  1832         -      int nNew = pSorter->nMemory * 2;
         1832  +      sqlite3_int64 nNew = 2 * (sqlite3_int64)pSorter->nMemory;
  1833   1833         while( nNew < nMin ) nNew = nNew*2;
  1834   1834         if( nNew > pSorter->mxPmaSize ) nNew = pSorter->mxPmaSize;
  1835   1835         if( nNew < nMin ) nNew = nMin;
  1836   1836   
  1837   1837         aNew = sqlite3Realloc(pSorter->list.aMemory, nNew);
  1838   1838         if( !aNew ) return SQLITE_NOMEM_BKPT;
  1839   1839         pSorter->list.pList = (SorterRecord*)&aNew[iListOff];

Changes to src/vtab.c.

   298    298   
   299    299   /*
   300    300   ** Add a new module argument to pTable->azModuleArg[].
   301    301   ** The string is not copied - the pointer is stored.  The
   302    302   ** string will be freed automatically when the table is
   303    303   ** deleted.
   304    304   */
   305         -static void addModuleArgument(sqlite3 *db, Table *pTable, char *zArg){
   306         -  int nBytes = sizeof(char *)*(2+pTable->nModuleArg);
          305  +static void addModuleArgument(Parse *pParse, Table *pTable, char *zArg){
          306  +  sqlite3_int64 nBytes = sizeof(char *)*(2+pTable->nModuleArg);
   307    307     char **azModuleArg;
          308  +  sqlite3 *db = pParse->db;
          309  +  if( pTable->nModuleArg+3>=db->aLimit[SQLITE_LIMIT_COLUMN] ){
          310  +    sqlite3ErrorMsg(pParse, "too many columns on %s", pTable->zName);
          311  +  }
   308    312     azModuleArg = sqlite3DbRealloc(db, pTable->azModuleArg, nBytes);
   309    313     if( azModuleArg==0 ){
   310    314       sqlite3DbFree(db, zArg);
   311    315     }else{
   312    316       int i = pTable->nModuleArg++;
   313    317       azModuleArg[i] = zArg;
   314    318       azModuleArg[i+1] = 0;
................................................................................
   335    339     pTable = pParse->pNewTable;
   336    340     if( pTable==0 ) return;
   337    341     assert( 0==pTable->pIndex );
   338    342   
   339    343     db = pParse->db;
   340    344   
   341    345     assert( pTable->nModuleArg==0 );
   342         -  addModuleArgument(db, pTable, sqlite3NameFromToken(db, pModuleName));
   343         -  addModuleArgument(db, pTable, 0);
   344         -  addModuleArgument(db, pTable, sqlite3DbStrDup(db, pTable->zName));
          346  +  addModuleArgument(pParse, pTable, sqlite3NameFromToken(db, pModuleName));
          347  +  addModuleArgument(pParse, pTable, 0);
          348  +  addModuleArgument(pParse, pTable, sqlite3DbStrDup(db, pTable->zName));
   345    349     assert( (pParse->sNameToken.z==pName2->z && pName2->z!=0)
   346    350          || (pParse->sNameToken.z==pName1->z && pName2->z==0)
   347    351     );
   348    352     pParse->sNameToken.n = (int)(
   349    353         &pModuleName->z[pModuleName->n] - pParse->sNameToken.z
   350    354     );
   351    355   
................................................................................
   370    374   ** virtual table currently under construction in pParse->pTable.
   371    375   */
   372    376   static void addArgumentToVtab(Parse *pParse){
   373    377     if( pParse->sArg.z && pParse->pNewTable ){
   374    378       const char *z = (const char*)pParse->sArg.z;
   375    379       int n = pParse->sArg.n;
   376    380       sqlite3 *db = pParse->db;
   377         -    addModuleArgument(db, pParse->pNewTable, sqlite3DbStrNDup(db, z, n));
          381  +    addModuleArgument(pParse, pParse->pNewTable, sqlite3DbStrNDup(db, z, n));
   378    382     }
   379    383   }
   380    384   
   381    385   /*
   382    386   ** The parser calls this routine after the CREATE VIRTUAL TABLE statement
   383    387   ** has been completely parsed.
   384    388   */
................................................................................
   659    663   */
   660    664   static int growVTrans(sqlite3 *db){
   661    665     const int ARRAY_INCR = 5;
   662    666   
   663    667     /* Grow the sqlite3.aVTrans array if required */
   664    668     if( (db->nVTrans%ARRAY_INCR)==0 ){
   665    669       VTable **aVTrans;
   666         -    int nBytes = sizeof(sqlite3_vtab *) * (db->nVTrans + ARRAY_INCR);
          670  +    sqlite3_int64 nBytes = sizeof(sqlite3_vtab*)*
          671  +                                 ((sqlite3_int64)db->nVTrans + ARRAY_INCR);
   667    672       aVTrans = sqlite3DbRealloc(db, (void *)db->aVTrans, nBytes);
   668    673       if( !aVTrans ){
   669    674         return SQLITE_NOMEM_BKPT;
   670    675       }
   671    676       memset(&aVTrans[db->nVTrans], 0, sizeof(sqlite3_vtab *)*ARRAY_INCR);
   672    677       db->aVTrans = aVTrans;
   673    678     }
................................................................................
  1155   1160       return 0;
  1156   1161     }
  1157   1162     pMod->pEpoTab = pTab;
  1158   1163     pTab->nTabRef = 1;
  1159   1164     pTab->pSchema = db->aDb[0].pSchema;
  1160   1165     assert( pTab->nModuleArg==0 );
  1161   1166     pTab->iPKey = -1;
  1162         -  addModuleArgument(db, pTab, sqlite3DbStrDup(db, pTab->zName));
  1163         -  addModuleArgument(db, pTab, 0);
  1164         -  addModuleArgument(db, pTab, sqlite3DbStrDup(db, pTab->zName));
         1167  +  addModuleArgument(pParse, pTab, sqlite3DbStrDup(db, pTab->zName));
         1168  +  addModuleArgument(pParse, pTab, 0);
         1169  +  addModuleArgument(pParse, pTab, sqlite3DbStrDup(db, pTab->zName));
  1165   1170     rc = vtabCallConstructor(db, pTab, pMod, pModule->xConnect, &zErr);
  1166   1171     if( rc ){
  1167   1172       sqlite3ErrorMsg(pParse, "%s", zErr);
  1168   1173       sqlite3DbFree(db, zErr);
  1169   1174       sqlite3VtabEponymousTableClear(db, pMod);
  1170   1175       return 0;
  1171   1176     }

Changes to src/wal.c.

   835    835     int iPage,               /* The page we seek */
   836    836     volatile u32 **ppPage    /* Write the page pointer here */
   837    837   ){
   838    838     int rc = SQLITE_OK;
   839    839   
   840    840     /* Enlarge the pWal->apWiData[] array if required */
   841    841     if( pWal->nWiData<=iPage ){
   842         -    int nByte = sizeof(u32*)*(iPage+1);
          842  +    sqlite3_int64 nByte = sizeof(u32*)*(iPage+1);
   843    843       volatile u32 **apNew;
   844    844       apNew = (volatile u32 **)sqlite3_realloc64((void *)pWal->apWiData, nByte);
   845    845       if( !apNew ){
   846    846         *ppPage = 0;
   847    847         return SQLITE_NOMEM_BKPT;
   848    848       }
   849    849       memset((void*)&apNew[pWal->nWiData], 0,
................................................................................
   939    939       s2 = aIn[1];
   940    940     }else{
   941    941       s1 = s2 = 0;
   942    942     }
   943    943   
   944    944     assert( nByte>=8 );
   945    945     assert( (nByte&0x00000007)==0 );
          946  +  assert( nByte<=65536 );
   946    947   
   947    948     if( nativeCksum ){
   948    949       do {
   949    950         s1 += *aData++ + s2;
   950    951         s2 += *aData++ + s1;
   951    952       }while( aData<aEnd );
   952    953     }else{
................................................................................
  1298   1299   ** actually needed.
  1299   1300   */
  1300   1301   static void walCleanupHash(Wal *pWal){
  1301   1302     WalHashLoc sLoc;                /* Hash table location */
  1302   1303     int iLimit = 0;                 /* Zero values greater than this */
  1303   1304     int nByte;                      /* Number of bytes to zero in aPgno[] */
  1304   1305     int i;                          /* Used to iterate through aHash[] */
         1306  +  int rc;                         /* Return code form walHashGet() */
  1305   1307     int iWal = walidxGetFile(&pWal->hdr);
  1306   1308     u32 mxFrame = walidxGetMxFrame(&pWal->hdr, iWal);
  1307   1309   
  1308   1310     u32 iExternal;
  1309   1311     if( isWalMode2(pWal) ){
  1310   1312       iExternal = walExternalEncode(iWal, mxFrame);
  1311   1313     }else{
................................................................................
  1317   1319     testcase( mxFrame==HASHTABLE_NPAGE_ONE-1 );
  1318   1320     testcase( mxFrame==HASHTABLE_NPAGE_ONE );
  1319   1321     testcase( mxFrame==HASHTABLE_NPAGE_ONE+1 );
  1320   1322   
  1321   1323     if( mxFrame==0 ) return;
  1322   1324   
  1323   1325     /* Obtain pointers to the hash-table and page-number array containing 
  1324         -  ** the entry that corresponds to frame pWal->hdr.mxFrame.  */
         1326  +  ** the entry that corresponds to frame pWal->hdr.mxFrame. It is guaranteed
         1327  +  ** that the page said hash-table and array reside on is already mapped.(1)
         1328  +  */
  1325   1329     assert( pWal->nWiData>walFramePage(iExternal) );
  1326   1330     assert( pWal->apWiData[walFramePage(iExternal)] );
  1327         -  walHashGet(pWal, walFramePage(iExternal), &sLoc);
         1331  +  rc = walHashGet(pWal, walFramePage(iExternal), &sLoc);
         1332  +  if( NEVER(rc) ) return; /* Defense-in-depth, in case (1) above is wrong */
  1328   1333   
  1329   1334     /* Zero all hash-table entries that correspond to frame numbers greater
  1330   1335     ** than pWal->hdr.mxFrame.
  1331   1336     */
  1332   1337     iLimit = iExternal - sLoc.iZero;
  1333   1338     assert( iLimit>0 );
  1334   1339     for(i=0; i<HASHTABLE_NSLOT; i++){
................................................................................
  2088   2093     int iWal, 
  2089   2094     u32 nBackfill, 
  2090   2095     WalIterator **pp
  2091   2096   ){
  2092   2097     WalIterator *p;                 /* Return value */
  2093   2098     int nSegment;                   /* Number of segments to merge */
  2094   2099     u32 iLast;                      /* Last frame in log */
  2095         -  int nByte;                      /* Number of bytes to allocate */
         2100  +  sqlite3_int64 nByte;            /* Number of bytes to allocate */
  2096   2101     int i;                          /* Iterator variable */
  2097   2102     int iLastSeg;                   /* Last hash table to iterate though */
  2098   2103     ht_slot *aTmp;                  /* Temp space used by merge-sort */
  2099   2104     int rc = SQLITE_OK;             /* Return Code */
  2100   2105     int iMode = isWalMode2(pWal) ? 2 : 1;
  2101   2106   
  2102   2107     assert( isWalMode2(pWal) || iWal==0 );

Changes to src/where.c.

  3331   3331   
  3332   3332     /* First call xBestIndex() with all constraints usable. */
  3333   3333     WHERETRACE(0x800, ("BEGIN %s.addVirtual()\n", pSrc->pTab->zName));
  3334   3334     WHERETRACE(0x40, ("  VirtualOne: all usable\n"));
  3335   3335     rc = whereLoopAddVirtualOne(pBuilder, mPrereq, ALLBITS, 0, p, mNoOmit, &bIn);
  3336   3336   
  3337   3337     /* If the call to xBestIndex() with all terms enabled produced a plan
  3338         -  ** that does not require any source tables (IOW: a plan with mBest==0),
  3339         -  ** then there is no point in making any further calls to xBestIndex() 
  3340         -  ** since they will all return the same result (if the xBestIndex()
  3341         -  ** implementation is sane). */
  3342         -  if( rc==SQLITE_OK && (mBest = (pNew->prereq & ~mPrereq))!=0 ){
         3338  +  ** that does not require any source tables (IOW: a plan with mBest==0)
         3339  +  ** and does not use an IN(...) operator, then there is no point in making 
         3340  +  ** any further calls to xBestIndex() since they will all return the same
         3341  +  ** result (if the xBestIndex() implementation is sane). */
         3342  +  if( rc==SQLITE_OK && ((mBest = (pNew->prereq & ~mPrereq))!=0 || bIn) ){
  3343   3343       int seenZero = 0;             /* True if a plan with no prereqs seen */
  3344   3344       int seenZeroNoIN = 0;         /* Plan with no prereqs and no IN(...) seen */
  3345   3345       Bitmask mPrev = 0;
  3346   3346       Bitmask mBestNoIn = 0;
  3347   3347   
  3348   3348       /* If the plan produced by the earlier call uses an IN(...) term, call
  3349   3349       ** xBestIndex again, this time with IN(...) terms disabled. */

Changes to src/wherecode.c.

  1963   1963           if( (pWC->a[iTerm].wtFlags & (TERM_VIRTUAL|TERM_CODED))!=0 ) continue;
  1964   1964           if( (pWC->a[iTerm].eOperator & WO_ALL)==0 ) continue;
  1965   1965           testcase( pWC->a[iTerm].wtFlags & TERM_ORINFO );
  1966   1966           pExpr = sqlite3ExprDup(db, pExpr, 0);
  1967   1967           pAndExpr = sqlite3ExprAnd(db, pAndExpr, pExpr);
  1968   1968         }
  1969   1969         if( pAndExpr ){
  1970         -        pAndExpr = sqlite3PExpr(pParse, TK_AND|TKFLG_DONTFOLD, 0, pAndExpr);
         1970  +        /* The extra 0x10000 bit on the opcode is masked off and does not
         1971  +        ** become part of the new Expr.op.  However, it does make the
         1972  +        ** op==TK_AND comparison inside of sqlite3PExpr() false, and this
         1973  +        ** prevents sqlite3PExpr() from implementing AND short-circuit 
         1974  +        ** optimization, which we do not want here. */
         1975  +        pAndExpr = sqlite3PExpr(pParse, TK_AND|0x10000, 0, pAndExpr);
  1971   1976         }
  1972   1977       }
  1973   1978   
  1974   1979       /* Run a separate WHERE clause for each term of the OR clause.  After
  1975   1980       ** eliminating duplicates from other WHERE clauses, the action for each
  1976   1981       ** sub-WHERE clause is to to invoke the main loop body as a subroutine.
  1977   1982       */
................................................................................
  2193   2198           ** that compares BLOBs. */
  2194   2199   #ifdef SQLITE_LIKE_DOESNT_MATCH_BLOBS
  2195   2200           continue;
  2196   2201   #else
  2197   2202           u32 x = pLevel->iLikeRepCntr;
  2198   2203           if( x>0 ){
  2199   2204             skipLikeAddr = sqlite3VdbeAddOp1(v, (x&1)?OP_IfNot:OP_If,(int)(x>>1));
         2205  +          VdbeCoverageIf(v, (x&1)==1);
         2206  +          VdbeCoverageIf(v, (x&1)==0);
  2200   2207           }
  2201         -        VdbeCoverage(v);
  2202   2208   #endif
  2203   2209         }
  2204   2210   #ifdef WHERETRACE_ENABLED /* 0xffff */
  2205   2211         if( sqlite3WhereTrace ){
  2206   2212           VdbeNoopComment((v, "WhereTerm[%d] (%p) priority=%d",
  2207   2213                            pWC->nTerm-j, pTerm, iLoop));
  2208   2214         }

Changes to src/window.c.

   194    194         p->nValue++;
   195    195         p->nStep = 0;
   196    196       }
   197    197       sqlite3_result_int64(pCtx, p->nValue);
   198    198     }
   199    199   }
   200    200   
          201  +/*
          202  +** Implementation of built-in window function nth_value(). This
          203  +** implementation is used in "slow mode" only - when the EXCLUDE clause
          204  +** is not set to the default value "NO OTHERS".
          205  +*/
          206  +struct NthValueCtx {
          207  +  i64 nStep;
          208  +  sqlite3_value *pValue;
          209  +};
          210  +static void nth_valueStepFunc(
          211  +  sqlite3_context *pCtx, 
          212  +  int nArg,
          213  +  sqlite3_value **apArg
          214  +){
          215  +  struct NthValueCtx *p;
          216  +  p = (struct NthValueCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p));
          217  +  if( p ){
          218  +    i64 iVal;
          219  +    switch( sqlite3_value_numeric_type(apArg[1]) ){
          220  +      case SQLITE_INTEGER:
          221  +        iVal = sqlite3_value_int64(apArg[1]);
          222  +        break;
          223  +      case SQLITE_FLOAT: {
          224  +        double fVal = sqlite3_value_double(apArg[1]);
          225  +        if( ((i64)fVal)!=fVal ) goto error_out;
          226  +        iVal = (i64)fVal;
          227  +        break;
          228  +      }
          229  +      default:
          230  +        goto error_out;
          231  +    }
          232  +    if( iVal<=0 ) goto error_out;
          233  +
          234  +    p->nStep++;
          235  +    if( iVal==p->nStep ){
          236  +      p->pValue = sqlite3_value_dup(apArg[0]);
          237  +      if( !p->pValue ){
          238  +        sqlite3_result_error_nomem(pCtx);
          239  +      }
          240  +    }
          241  +  }
          242  +  UNUSED_PARAMETER(nArg);
          243  +  UNUSED_PARAMETER(apArg);
          244  +  return;
          245  +
          246  + error_out:
          247  +  sqlite3_result_error(
          248  +      pCtx, "second argument to nth_value must be a positive integer", -1
          249  +  );
          250  +}
          251  +static void nth_valueFinalizeFunc(sqlite3_context *pCtx){
          252  +  struct NthValueCtx *p;
          253  +  p = (struct NthValueCtx*)sqlite3_aggregate_context(pCtx, 0);
          254  +  if( p && p->pValue ){
          255  +    sqlite3_result_value(pCtx, p->pValue);
          256  +    sqlite3_value_free(p->pValue);
          257  +    p->pValue = 0;
          258  +  }
          259  +}
          260  +#define nth_valueInvFunc noopStepFunc
          261  +#define nth_valueValueFunc noopValueFunc
          262  +
          263  +static void first_valueStepFunc(
          264  +  sqlite3_context *pCtx, 
          265  +  int nArg,
          266  +  sqlite3_value **apArg
          267  +){
          268  +  struct NthValueCtx *p;
          269  +  p = (struct NthValueCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p));
          270  +  if( p && p->pValue==0 ){
          271  +    p->pValue = sqlite3_value_dup(apArg[0]);
          272  +    if( !p->pValue ){
          273  +      sqlite3_result_error_nomem(pCtx);
          274  +    }
          275  +  }
          276  +  UNUSED_PARAMETER(nArg);
          277  +  UNUSED_PARAMETER(apArg);
          278  +}
          279  +static void first_valueFinalizeFunc(sqlite3_context *pCtx){
          280  +  struct NthValueCtx *p;
          281  +  p = (struct NthValueCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p));
          282  +  if( p && p->pValue ){
          283  +    sqlite3_result_value(pCtx, p->pValue);
          284  +    sqlite3_value_free(p->pValue);
          285  +    p->pValue = 0;
          286  +  }
          287  +}
          288  +#define first_valueInvFunc noopStepFunc
          289  +#define first_valueValueFunc noopValueFunc
          290  +
   201    291   /*
   202    292   ** Implementation of built-in window function rank(). Assumes that
   203    293   ** the window frame has been set to:
   204    294   **
   205    295   **   RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW 
   206    296   */
   207    297   static void rankStepFunc(
................................................................................
   229    319     }
   230    320   }
   231    321   
   232    322   /*
   233    323   ** Implementation of built-in window function percent_rank(). Assumes that
   234    324   ** the window frame has been set to:
   235    325   **
   236         -**   RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW 
          326  +**   GROUPS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
   237    327   */
   238    328   static void percent_rankStepFunc(
   239    329     sqlite3_context *pCtx, 
   240    330     int nArg,
   241    331     sqlite3_value **apArg
   242    332   ){
   243    333     struct CallCount *p;
   244         -  UNUSED_PARAMETER(nArg); assert( nArg==1 );
   245         -
          334  +  UNUSED_PARAMETER(nArg); assert( nArg==0 );
          335  +  UNUSED_PARAMETER(apArg);
   246    336     p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
   247    337     if( p ){
   248         -    if( p->nTotal==0 ){
   249         -      p->nTotal = sqlite3_value_int64(apArg[0]);
   250         -    }
   251         -    p->nStep++;
   252         -    if( p->nValue==0 ){
   253         -      p->nValue = p->nStep;
          338  +    p->nTotal++;
   254    339       }
   255    340     }
          341  +static void percent_rankInvFunc(
          342  +  sqlite3_context *pCtx, 
          343  +  int nArg,
          344  +  sqlite3_value **apArg
          345  +){
          346  +  struct CallCount *p;
          347  +  UNUSED_PARAMETER(nArg); assert( nArg==0 );
          348  +  UNUSED_PARAMETER(apArg);
          349  +  p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
          350  +  p->nStep++;
   256    351   }
   257    352   static void percent_rankValueFunc(sqlite3_context *pCtx){
   258    353     struct CallCount *p;
   259    354     p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
   260    355     if( p ){
          356  +    p->nValue = p->nStep;
   261    357       if( p->nTotal>1 ){
   262         -      double r = (double)(p->nValue-1) / (double)(p->nTotal-1);
          358  +      double r = (double)p->nValue / (double)(p->nTotal-1);
   263    359         sqlite3_result_double(pCtx, r);
   264    360       }else{
   265    361         sqlite3_result_double(pCtx, 0.0);
   266    362       }
   267         -    p->nValue = 0;
   268    363     }
   269    364   }
          365  +#define percent_rankFinalizeFunc percent_rankValueFunc
   270    366   
   271    367   /*
   272    368   ** Implementation of built-in window function cume_dist(). Assumes that
   273    369   ** the window frame has been set to:
   274    370   **
   275         -**   RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW 
          371  +**   GROUPS BETWEEN 1 FOLLOWING AND UNBOUNDED FOLLOWING
   276    372   */
   277    373   static void cume_distStepFunc(
   278    374     sqlite3_context *pCtx, 
   279    375     int nArg,
   280    376     sqlite3_value **apArg
   281    377   ){
   282    378     struct CallCount *p;
   283         -  assert( nArg==1 ); UNUSED_PARAMETER(nArg);
   284         -
          379  +  UNUSED_PARAMETER(nArg); assert( nArg==0 );
          380  +  UNUSED_PARAMETER(apArg);
   285    381     p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
   286    382     if( p ){
   287         -    if( p->nTotal==0 ){
   288         -      p->nTotal = sqlite3_value_int64(apArg[0]);
          383  +    p->nTotal++;
   289    384       }
          385  +}
          386  +static void cume_distInvFunc(
          387  +  sqlite3_context *pCtx, 
          388  +  int nArg,
          389  +  sqlite3_value **apArg
          390  +){
          391  +  struct CallCount *p;
          392  +  UNUSED_PARAMETER(nArg); assert( nArg==0 );
          393  +  UNUSED_PARAMETER(apArg);
          394  +  p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
   290    395       p->nStep++;
   291    396     }
   292         -}
   293    397   static void cume_distValueFunc(sqlite3_context *pCtx){
   294    398     struct CallCount *p;
   295         -  p = (struct CallCount*)sqlite3_aggregate_context(pCtx, sizeof(*p));
   296         -  if( p && p->nTotal ){
          399  +  p = (struct CallCount*)sqlite3_aggregate_context(pCtx, 0);
          400  +  if( p ){
   297    401       double r = (double)(p->nStep) / (double)(p->nTotal);
   298    402       sqlite3_result_double(pCtx, r);
   299    403     }
   300    404   }
          405  +#define cume_distFinalizeFunc cume_distValueFunc
   301    406   
   302    407   /*
   303    408   ** Context object for ntile() window function.
   304    409   */
   305    410   struct NtileCtx {
   306    411     i64 nTotal;                     /* Total rows in partition */
   307    412     i64 nParam;                     /* Parameter passed to ntile(N) */
................................................................................
   308    413     i64 iRow;                       /* Current row */
   309    414   };
   310    415   
   311    416   /*
   312    417   ** Implementation of ntile(). This assumes that the window frame has
   313    418   ** been coerced to:
   314    419   **
   315         -**   ROWS UNBOUNDED PRECEDING AND CURRENT ROW
          420  +**   ROWS CURRENT ROW AND UNBOUNDED FOLLOWING
   316    421   */
   317    422   static void ntileStepFunc(
   318    423     sqlite3_context *pCtx, 
   319    424     int nArg,
   320    425     sqlite3_value **apArg
   321    426   ){
   322    427     struct NtileCtx *p;
   323         -  assert( nArg==2 ); UNUSED_PARAMETER(nArg);
          428  +  assert( nArg==1 ); UNUSED_PARAMETER(nArg);
   324    429     p = (struct NtileCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p));
   325    430     if( p ){
   326    431       if( p->nTotal==0 ){
   327    432         p->nParam = sqlite3_value_int64(apArg[0]);
   328         -      p->nTotal = sqlite3_value_int64(apArg[1]);
   329    433         if( p->nParam<=0 ){
   330    434           sqlite3_result_error(
   331    435               pCtx, "argument of ntile must be a positive integer", -1
   332    436           );
   333    437         }
   334    438       }
          439  +    p->nTotal++;
          440  +  }
          441  +}
          442  +static void ntileInvFunc(
          443  +  sqlite3_context *pCtx, 
          444  +  int nArg,
          445  +  sqlite3_value **apArg
          446  +){
          447  +  struct NtileCtx *p;
          448  +  assert( nArg==1 ); UNUSED_PARAMETER(nArg);
          449  +  UNUSED_PARAMETER(apArg);
          450  +  p = (struct NtileCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p));
   335    451       p->iRow++;
   336    452     }
   337         -}
   338    453   static void ntileValueFunc(sqlite3_context *pCtx){
   339    454     struct NtileCtx *p;
   340    455     p = (struct NtileCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p));
   341    456     if( p && p->nParam>0 ){
   342    457       int nSize = (p->nTotal / p->nParam);
   343    458       if( nSize==0 ){
   344         -      sqlite3_result_int64(pCtx, p->iRow);
          459  +      sqlite3_result_int64(pCtx, p->iRow+1);
   345    460       }else{
   346    461         i64 nLarge = p->nTotal - p->nParam*nSize;
   347    462         i64 iSmall = nLarge*(nSize+1);
   348         -      i64 iRow = p->iRow-1;
          463  +      i64 iRow = p->iRow;
   349    464   
   350    465         assert( (nLarge*(nSize+1) + (p->nParam-nLarge)*nSize)==p->nTotal );
   351    466   
   352    467         if( iRow<iSmall ){
   353    468           sqlite3_result_int64(pCtx, 1 + iRow/(nSize+1));
   354    469         }else{
   355    470           sqlite3_result_int64(pCtx, 1 + nLarge + (iRow-iSmall)/nSize);
   356    471         }
   357    472       }
   358    473     }
   359    474   }
          475  +#define ntileFinalizeFunc ntileValueFunc
   360    476   
   361    477   /*
   362    478   ** Context object for last_value() window function.
   363    479   */
   364    480   struct LastValueCtx {
   365    481     sqlite3_value *pVal;
   366    482     int nVal;
................................................................................
   402    518         sqlite3_value_free(p->pVal);
   403    519         p->pVal = 0;
   404    520       }
   405    521     }
   406    522   }
   407    523   static void last_valueValueFunc(sqlite3_context *pCtx){
   408    524     struct LastValueCtx *p;
   409         -  p = (struct LastValueCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p));
          525  +  p = (struct LastValueCtx*)sqlite3_aggregate_context(pCtx, 0);
   410    526     if( p && p->pVal ){
   411    527       sqlite3_result_value(pCtx, p->pVal);
   412    528     }
   413    529   }
   414    530   static void last_valueFinalizeFunc(sqlite3_context *pCtx){
   415    531     struct LastValueCtx *p;
   416    532     p = (struct LastValueCtx*)sqlite3_aggregate_context(pCtx, sizeof(*p));
................................................................................
   492    608   ** Register those built-in window functions that are not also aggregates.
   493    609   */
   494    610   void sqlite3WindowFunctions(void){
   495    611     static FuncDef aWindowFuncs[] = {
   496    612       WINDOWFUNCX(row_number, 0, 0),
   497    613       WINDOWFUNCX(dense_rank, 0, 0),
   498    614       WINDOWFUNCX(rank, 0, 0),
   499         -    WINDOWFUNCX(percent_rank, 0, SQLITE_FUNC_WINDOW_SIZE),
   500         -    WINDOWFUNCX(cume_dist, 0, SQLITE_FUNC_WINDOW_SIZE),
   501         -    WINDOWFUNCX(ntile, 1, SQLITE_FUNC_WINDOW_SIZE),
          615  +    WINDOWFUNCALL(percent_rank, 0, 0),
          616  +    WINDOWFUNCALL(cume_dist, 0, 0),
          617  +    WINDOWFUNCALL(ntile, 1, 0),
   502    618       WINDOWFUNCALL(last_value, 1, 0),
   503         -    WINDOWFUNCNOOP(nth_value, 2, 0),
   504         -    WINDOWFUNCNOOP(first_value, 1, 0),
          619  +    WINDOWFUNCALL(nth_value, 2, 0),
          620  +    WINDOWFUNCALL(first_value, 1, 0),
   505    621       WINDOWFUNCNOOP(lead, 1, 0),
   506    622       WINDOWFUNCNOOP(lead, 2, 0),
   507    623       WINDOWFUNCNOOP(lead, 3, 0),
   508    624       WINDOWFUNCNOOP(lag, 1, 0),
   509    625       WINDOWFUNCNOOP(lag, 2, 0),
   510    626       WINDOWFUNCNOOP(lag, 3, 0),
   511    627     };
   512    628     sqlite3InsertBuiltinFuncs(aWindowFuncs, ArraySize(aWindowFuncs));
   513    629   }
          630  +
          631  +static Window *windowFind(Parse *pParse, Window *pList, const char *zName){
          632  +  Window *p;
          633  +  for(p=pList; p; p=p->pNextWin){
          634  +    if( sqlite3StrICmp(p->zName, zName)==0 ) break;
          635  +  }
          636  +  if( p==0 ){
          637  +    sqlite3ErrorMsg(pParse, "no such window: %s", zName);
          638  +  }
          639  +  return p;
          640  +}
   514    641   
   515    642   /*
   516    643   ** This function is called immediately after resolving the function name
   517    644   ** for a window function within a SELECT statement. Argument pList is a
   518    645   ** linked list of WINDOW definitions for the current SELECT statement.
   519    646   ** Argument pFunc is the function definition just resolved and pWin
   520    647   ** is the Window object representing the associated OVER clause. This
................................................................................
   531    658   */
   532    659   void sqlite3WindowUpdate(
   533    660     Parse *pParse, 
   534    661     Window *pList,                  /* List of named windows for this SELECT */
   535    662     Window *pWin,                   /* Window frame to update */
   536    663     FuncDef *pFunc                  /* Window function definition */
   537    664   ){
   538         -  if( pWin->zName && pWin->eType==0 ){
   539         -    Window *p;
   540         -    for(p=pList; p; p=p->pNextWin){
   541         -      if( sqlite3StrICmp(p->zName, pWin->zName)==0 ) break;
   542         -    }
   543         -    if( p==0 ){
   544         -      sqlite3ErrorMsg(pParse, "no such window: %s", pWin->zName);
   545         -      return;
   546         -    }
          665  +  if( pWin->zName && pWin->eFrmType==0 ){
          666  +    Window *p = windowFind(pParse, pList, pWin->zName);
          667  +    if( p==0 ) return;
   547    668       pWin->pPartition = sqlite3ExprListDup(pParse->db, p->pPartition, 0);
   548    669       pWin->pOrderBy = sqlite3ExprListDup(pParse->db, p->pOrderBy, 0);
   549    670       pWin->pStart = sqlite3ExprDup(pParse->db, p->pStart, 0);
   550    671       pWin->pEnd = sqlite3ExprDup(pParse->db, p->pEnd, 0);
   551    672       pWin->eStart = p->eStart;
   552    673       pWin->eEnd = p->eEnd;
   553         -    pWin->eType = p->eType;
          674  +    pWin->eFrmType = p->eFrmType;
          675  +    pWin->eExclude = p->eExclude;
          676  +  }else{
          677  +    sqlite3WindowChain(pParse, pWin, pList);
   554    678     }
          679  +  if( (pWin->eFrmType==TK_RANGE)
          680  +   && (pWin->pStart || pWin->pEnd) 
          681  +   && (pWin->pOrderBy==0 || pWin->pOrderBy->nExpr!=1)
          682  +  ){
          683  +    sqlite3ErrorMsg(pParse, 
          684  +      "RANGE with offset PRECEDING/FOLLOWING requires one ORDER BY expression"
          685  +    );
          686  +  }else
   555    687     if( pFunc->funcFlags & SQLITE_FUNC_WINDOW ){
   556    688       sqlite3 *db = pParse->db;
   557    689       if( pWin->pFilter ){
   558    690         sqlite3ErrorMsg(pParse, 
   559    691             "FILTER clause may only be used with aggregate window functions"
   560    692         );
   561         -    }else
   562         -    if( pFunc->zName==row_numberName || pFunc->zName==ntileName ){
   563         -      sqlite3ExprDelete(db, pWin->pStart);
   564         -      sqlite3ExprDelete(db, pWin->pEnd);
   565         -      pWin->pStart = pWin->pEnd = 0;
   566         -      pWin->eType = TK_ROWS;
   567         -      pWin->eStart = TK_UNBOUNDED;
   568         -      pWin->eEnd = TK_CURRENT;
   569         -    }else
   570         -
   571         -    if( pFunc->zName==dense_rankName || pFunc->zName==rankName
   572         -     || pFunc->zName==percent_rankName || pFunc->zName==cume_distName
   573         -    ){
          693  +    }else{
          694  +      struct WindowUpdate {
          695  +        const char *zFunc;
          696  +        int eFrmType;
          697  +        int eStart;
          698  +        int eEnd;
          699  +      } aUp[] = {
          700  +        { row_numberName,   TK_ROWS,   TK_UNBOUNDED, TK_CURRENT }, 
          701  +        { dense_rankName,   TK_RANGE,  TK_UNBOUNDED, TK_CURRENT }, 
          702  +        { rankName,         TK_RANGE,  TK_UNBOUNDED, TK_CURRENT }, 
          703  +        { percent_rankName, TK_GROUPS, TK_CURRENT,   TK_UNBOUNDED }, 
          704  +        { cume_distName,    TK_GROUPS, TK_FOLLOWING, TK_UNBOUNDED }, 
          705  +        { ntileName,        TK_ROWS,   TK_CURRENT,   TK_UNBOUNDED }, 
          706  +        { leadName,         TK_ROWS,   TK_UNBOUNDED, TK_UNBOUNDED }, 
          707  +        { lagName,          TK_ROWS,   TK_UNBOUNDED, TK_CURRENT }, 
          708  +      };
          709  +      int i;
          710  +      for(i=0; i<ArraySize(aUp); i++){
          711  +        if( pFunc->zName==aUp[i].zFunc ){
   574    712         sqlite3ExprDelete(db, pWin->pStart);
   575    713         sqlite3ExprDelete(db, pWin->pEnd);
   576         -      pWin->pStart = pWin->pEnd = 0;
   577         -      pWin->eType = TK_RANGE;
   578         -      pWin->eStart = TK_UNBOUNDED;
   579         -      pWin->eEnd = TK_CURRENT;
          714  +          pWin->pEnd = pWin->pStart = 0;
          715  +          pWin->eFrmType = aUp[i].eFrmType;
          716  +          pWin->eStart = aUp[i].eStart;
          717  +          pWin->eEnd = aUp[i].eEnd;
          718  +          pWin->eExclude = 0;
          719  +          if( pWin->eStart==TK_FOLLOWING ){
          720  +            pWin->pStart = sqlite3Expr(db, TK_INTEGER, "1");
          721  +          }
          722  +          break;
          723  +        }
          724  +      }
   580    725       }
   581    726     }
   582    727     pWin->pFunc = pFunc;
   583    728   }
   584    729   
   585    730   /*
   586    731   ** Context object passed through sqlite3WalkExprList() to
................................................................................
   777    922         }
   778    923       }
   779    924   
   780    925       /* Assign a cursor number for the ephemeral table used to buffer rows.
   781    926       ** The OpenEphemeral instruction is coded later, after it is known how
   782    927       ** many columns the table will have.  */
   783    928       pMWin->iEphCsr = pParse->nTab++;
          929  +    pParse->nTab += 3;
   784    930   
   785    931       selectWindowRewriteEList(pParse, pMWin, pSrc, p->pEList, &pSublist);
   786    932       selectWindowRewriteEList(pParse, pMWin, pSrc, p->pOrderBy, &pSublist);
   787    933       pMWin->nBufferCol = (pSublist ? pSublist->nExpr : 0);
   788    934   
   789    935       /* Append the PARTITION BY and ORDER BY expressions to the to the 
   790    936       ** sub-select expression list. They are required to figure out where 
................................................................................
   832    978         }else{
   833    979           pSub->selFlags |= SF_Expanded;
   834    980           p->selFlags &= ~SF_Aggregate;
   835    981           sqlite3SelectPrep(pParse, pSub, 0);
   836    982         }
   837    983   
   838    984         sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pMWin->iEphCsr, pSublist->nExpr);
          985  +      sqlite3VdbeAddOp2(v, OP_OpenDup, pMWin->iEphCsr+1, pMWin->iEphCsr);
          986  +      sqlite3VdbeAddOp2(v, OP_OpenDup, pMWin->iEphCsr+2, pMWin->iEphCsr);
          987  +      sqlite3VdbeAddOp2(v, OP_OpenDup, pMWin->iEphCsr+3, pMWin->iEphCsr);
   839    988       }else{
   840    989         sqlite3SelectDelete(db, pSub);
   841    990       }
   842    991       if( db->mallocFailed ) rc = SQLITE_NOMEM;
   843    992     }
   844    993   
   845    994     return rc;
................................................................................
   852   1001     if( p ){
   853   1002       sqlite3ExprDelete(db, p->pFilter);
   854   1003       sqlite3ExprListDelete(db, p->pPartition);
   855   1004       sqlite3ExprListDelete(db, p->pOrderBy);
   856   1005       sqlite3ExprDelete(db, p->pEnd);
   857   1006       sqlite3ExprDelete(db, p->pStart);
   858   1007       sqlite3DbFree(db, p->zName);
         1008  +    sqlite3DbFree(db, p->zBase);
   859   1009       sqlite3DbFree(db, p);
   860   1010     }
   861   1011   }
   862   1012   
   863   1013   /*
   864   1014   ** Free the linked list of Window objects starting at the second argument.
   865   1015   */
................................................................................
   888   1038   }
   889   1039   
   890   1040   /*
   891   1041   ** Allocate and return a new Window object describing a Window Definition.
   892   1042   */
   893   1043   Window *sqlite3WindowAlloc(
   894   1044     Parse *pParse,    /* Parsing context */
   895         -  int eType,        /* Frame type. TK_RANGE or TK_ROWS */
         1045  +  int eType,        /* Frame type. TK_RANGE, TK_ROWS, TK_GROUPS, or 0 */
   896   1046     int eStart,       /* Start type: CURRENT, PRECEDING, FOLLOWING, UNBOUNDED */
   897   1047     Expr *pStart,     /* Start window size if TK_PRECEDING or FOLLOWING */
   898   1048     int eEnd,         /* End type: CURRENT, FOLLOWING, TK_UNBOUNDED, PRECEDING */
   899         -  Expr *pEnd        /* End window size if TK_FOLLOWING or PRECEDING */
         1049  +  Expr *pEnd,       /* End window size if TK_FOLLOWING or PRECEDING */
         1050  +  u8 eExclude       /* EXCLUDE clause */
   900   1051   ){
   901   1052     Window *pWin = 0;
         1053  +  int bImplicitFrame = 0;
   902   1054   
   903   1055     /* Parser assures the following: */
   904         -  assert( eType==TK_RANGE || eType==TK_ROWS );
         1056  +  assert( eType==0 || eType==TK_RANGE || eType==TK_ROWS || eType==TK_GROUPS );
   905   1057     assert( eStart==TK_CURRENT || eStart==TK_PRECEDING
   906   1058              || eStart==TK_UNBOUNDED || eStart==TK_FOLLOWING );
   907   1059     assert( eEnd==TK_CURRENT || eEnd==TK_FOLLOWING
   908   1060              || eEnd==TK_UNBOUNDED || eEnd==TK_PRECEDING );
   909   1061     assert( (eStart==TK_PRECEDING || eStart==TK_FOLLOWING)==(pStart!=0) );
   910   1062     assert( (eEnd==TK_FOLLOWING || eEnd==TK_PRECEDING)==(pEnd!=0) );
   911   1063   
   912         -
   913         -  /* If a frame is declared "RANGE" (not "ROWS"), then it may not use
   914         -  ** either "<expr> PRECEDING" or "<expr> FOLLOWING".
   915         -  */
   916         -  if( eType==TK_RANGE && (pStart!=0 || pEnd!=0) ){
   917         -    sqlite3ErrorMsg(pParse, "RANGE must use only UNBOUNDED or CURRENT ROW");
   918         -    goto windowAllocErr;
         1064  +  if( eType==0 ){
         1065  +    bImplicitFrame = 1;
         1066  +    eType = TK_RANGE;
   919   1067     }
   920   1068   
   921   1069     /* Additionally, the
   922   1070     ** starting boundary type may not occur earlier in the following list than
   923   1071     ** the ending boundary type:
   924   1072     **
   925   1073     **   UNBOUNDED PRECEDING
................................................................................
   931   1079     ** The parser ensures that "UNBOUNDED PRECEDING" cannot be used as an ending
   932   1080     ** boundary, and than "UNBOUNDED FOLLOWING" cannot be used as a starting
   933   1081     ** frame boundary.
   934   1082     */
   935   1083     if( (eStart==TK_CURRENT && eEnd==TK_PRECEDING)
   936   1084      || (eStart==TK_FOLLOWING && (eEnd==TK_PRECEDING || eEnd==TK_CURRENT))
   937   1085     ){
   938         -    sqlite3ErrorMsg(pParse, "unsupported frame delimiter for ROWS");
         1086  +    sqlite3ErrorMsg(pParse, "unsupported frame specification");
   939   1087       goto windowAllocErr;
   940   1088     }
   941   1089   
   942   1090     pWin = (Window*)sqlite3DbMallocZero(pParse->db, sizeof(Window));
   943   1091     if( pWin==0 ) goto windowAllocErr;
   944         -  pWin->eType = eType;
         1092  +  pWin->eFrmType = eType;
   945   1093     pWin->eStart = eStart;
   946   1094     pWin->eEnd = eEnd;
         1095  +  if( eExclude==0 && OptimizationDisabled(pParse->db, SQLITE_WindowFunc) ){
         1096  +    eExclude = TK_NO;
         1097  +  }
         1098  +  pWin->eExclude = eExclude;
         1099  +  pWin->bImplicitFrame = bImplicitFrame;
   947   1100     pWin->pEnd = sqlite3WindowOffsetExpr(pParse, pEnd);
   948   1101     pWin->pStart = sqlite3WindowOffsetExpr(pParse, pStart);
   949   1102     return pWin;
   950   1103   
   951   1104   windowAllocErr:
   952   1105     sqlite3ExprDelete(pParse->db, pEnd);
   953   1106     sqlite3ExprDelete(pParse->db, pStart);
   954   1107     return 0;
   955   1108   }
         1109  +
         1110  +/*
         1111  +** Attach PARTITION and ORDER BY clauses pPartition and pOrderBy to window
         1112  +** pWin. Also, if parameter pBase is not NULL, set pWin->zBase to the
         1113  +** equivalent nul-terminated string.
         1114  +*/
         1115  +Window *sqlite3WindowAssemble(
         1116  +  Parse *pParse, 
         1117  +  Window *pWin, 
         1118  +  ExprList *pPartition, 
         1119  +  ExprList *pOrderBy, 
         1120  +  Token *pBase
         1121  +){
         1122  +  if( pWin ){
         1123  +    pWin->pPartition = pPartition;
         1124  +    pWin->pOrderBy = pOrderBy;
         1125  +    if( pBase ){
         1126  +      pWin->zBase = sqlite3DbStrNDup(pParse->db, pBase->z, pBase->n);
         1127  +    }
         1128  +  }else{
         1129  +    sqlite3ExprListDelete(pParse->db, pPartition);
         1130  +    sqlite3ExprListDelete(pParse->db, pOrderBy);
         1131  +  }
         1132  +  return pWin;
         1133  +}
         1134  +
         1135  +/*
         1136  +** Window *pWin has just been created from a WINDOW clause. Tokne pBase
         1137  +** is the base window. Earlier windows from the same WINDOW clause are
         1138  +** stored in the linked list starting at pWin->pNextWin. This function
         1139  +** either updates *pWin according to the base specification, or else
         1140  +** leaves an error in pParse.
         1141  +*/
         1142  +void sqlite3WindowChain(Parse *pParse, Window *pWin, Window *pList){
         1143  +  if( pWin->zBase ){
         1144  +    sqlite3 *db = pParse->db;
         1145  +    Window *pExist = windowFind(pParse, pList, pWin->zBase);
         1146  +    if( pExist ){
         1147  +      const char *zErr = 0;
         1148  +      /* Check for errors */
         1149  +      if( pWin->pPartition ){
         1150  +        zErr = "PARTITION clause";
         1151  +      }else if( pExist->pOrderBy && pWin->pOrderBy ){
         1152  +        zErr = "ORDER BY clause";
         1153  +      }else if( pExist->bImplicitFrame==0 ){
         1154  +        zErr = "frame specification";
         1155  +      }
         1156  +      if( zErr ){
         1157  +        sqlite3ErrorMsg(pParse, 
         1158  +            "cannot override %s of window: %s", zErr, pWin->zBase
         1159  +        );
         1160  +      }else{
         1161  +        pWin->pPartition = sqlite3ExprListDup(db, pExist->pPartition, 0);
         1162  +        if( pExist->pOrderBy ){
         1163  +          assert( pWin->pOrderBy==0 );
         1164  +          pWin->pOrderBy = sqlite3ExprListDup(db, pExist->pOrderBy, 0);
         1165  +        }
         1166  +        sqlite3DbFree(db, pWin->zBase);
         1167  +        pWin->zBase = 0;
         1168  +      }
         1169  +    }
         1170  +  }
         1171  +}
   956   1172   
   957   1173   /*
   958   1174   ** Attach window object pWin to expression p.
   959   1175   */
   960   1176   void sqlite3WindowAttach(Parse *pParse, Expr *p, Window *pWin){
   961   1177     if( p ){
   962   1178       assert( p->op==TK_FUNCTION );
................................................................................
   978   1194   }
   979   1195   
   980   1196   /*
   981   1197   ** Return 0 if the two window objects are identical, or non-zero otherwise.
   982   1198   ** Identical window objects can be processed in a single scan.
   983   1199   */
   984   1200   int sqlite3WindowCompare(Parse *pParse, Window *p1, Window *p2){
   985         -  if( p1->eType!=p2->eType ) return 1;
         1201  +  if( p1->eFrmType!=p2->eFrmType ) return 1;
   986   1202     if( p1->eStart!=p2->eStart ) return 1;
   987   1203     if( p1->eEnd!=p2->eEnd ) return 1;
         1204  +  if( p1->eExclude!=p2->eExclude ) return 1;
   988   1205     if( sqlite3ExprCompare(pParse, p1->pStart, p2->pStart, -1) ) return 1;
   989   1206     if( sqlite3ExprCompare(pParse, p1->pEnd, p2->pEnd, -1) ) return 1;
   990   1207     if( sqlite3ExprListCompare(p1->pPartition, p2->pPartition, -1) ) return 1;
   991   1208     if( sqlite3ExprListCompare(p1->pOrderBy, p2->pOrderBy, -1) ) return 1;
   992   1209     return 0;
   993   1210   }
   994   1211   
................................................................................
   997   1214   ** This is called by code in select.c before it calls sqlite3WhereBegin()
   998   1215   ** to begin iterating through the sub-query results. It is used to allocate
   999   1216   ** and initialize registers and cursors used by sqlite3WindowCodeStep().
  1000   1217   */
  1001   1218   void sqlite3WindowCodeInit(Parse *pParse, Window *pMWin){
  1002   1219     Window *pWin;
  1003   1220     Vdbe *v = sqlite3GetVdbe(pParse);
  1004         -  int nPart = (pMWin->pPartition ? pMWin->pPartition->nExpr : 0);
  1005         -  nPart += (pMWin->pOrderBy ? pMWin->pOrderBy->nExpr : 0);
  1006         -  if( nPart ){
         1221  +
         1222  +  /* Allocate registers to use for PARTITION BY values, if any. Initialize
         1223  +  ** said registers to NULL.  */
         1224  +  if( pMWin->pPartition ){
         1225  +    int nExpr = pMWin->pPartition->nExpr;
  1007   1226       pMWin->regPart = pParse->nMem+1;
  1008         -    pParse->nMem += nPart;
  1009         -    sqlite3VdbeAddOp3(v, OP_Null, 0, pMWin->regPart, pMWin->regPart+nPart-1);
         1227  +    pParse->nMem += nExpr;
         1228  +    sqlite3VdbeAddOp3(v, OP_Null, 0, pMWin->regPart, pMWin->regPart+nExpr-1);
         1229  +  }
         1230  +
         1231  +  pMWin->regOne = ++pParse->nMem;
         1232  +  sqlite3VdbeAddOp2(v, OP_Integer, 1, pMWin->regOne);
         1233  +
         1234  +  if( pMWin->eExclude ){
         1235  +    pMWin->regStartRowid = ++pParse->nMem;
         1236  +    pMWin->regEndRowid = ++pParse->nMem;
         1237  +    pMWin->csrApp = pParse->nTab++;
         1238  +    sqlite3VdbeAddOp2(v, OP_Integer, 1, pMWin->regStartRowid);
         1239  +    sqlite3VdbeAddOp2(v, OP_Integer, 0, pMWin->regEndRowid);
         1240  +    sqlite3VdbeAddOp2(v, OP_OpenDup, pMWin->csrApp, pMWin->iEphCsr);
         1241  +    return;
  1010   1242     }
  1011   1243   
  1012   1244     for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
  1013   1245       FuncDef *p = pWin->pFunc;
  1014   1246       if( (p->funcFlags & SQLITE_FUNC_MINMAX) && pWin->eStart!=TK_UNBOUNDED ){
  1015   1247         /* The inline versions of min() and max() require a single ephemeral
  1016   1248         ** table and 3 registers. The registers are used as follows:
................................................................................
  1031   1263         sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pWin->csrApp, 2);
  1032   1264         sqlite3VdbeAppendP4(v, pKeyInfo, P4_KEYINFO);
  1033   1265         sqlite3VdbeAddOp2(v, OP_Integer, 0, pWin->regApp+1);
  1034   1266       }
  1035   1267       else if( p->zName==nth_valueName || p->zName==first_valueName ){
  1036   1268         /* Allocate two registers at pWin->regApp. These will be used to
  1037   1269         ** store the start and end index of the current frame.  */
  1038         -      assert( pMWin->iEphCsr );
  1039   1270         pWin->regApp = pParse->nMem+1;
  1040   1271         pWin->csrApp = pParse->nTab++;
  1041   1272         pParse->nMem += 2;
  1042   1273         sqlite3VdbeAddOp2(v, OP_OpenDup, pWin->csrApp, pMWin->iEphCsr);
  1043   1274       }
  1044   1275       else if( p->zName==leadName || p->zName==lagName ){
  1045         -      assert( pMWin->iEphCsr );
  1046   1276         pWin->csrApp = pParse->nTab++;
  1047   1277         sqlite3VdbeAddOp2(v, OP_OpenDup, pWin->csrApp, pMWin->iEphCsr);
  1048   1278       }
  1049   1279     }
  1050   1280   }
         1281  +
         1282  +#define WINDOW_STARTING_INT  0
         1283  +#define WINDOW_ENDING_INT    1
         1284  +#define WINDOW_NTH_VALUE_INT 2
         1285  +#define WINDOW_STARTING_NUM  3
         1286  +#define WINDOW_ENDING_NUM    4
  1051   1287   
  1052   1288   /*
  1053   1289   ** A "PRECEDING <expr>" (eCond==0) or "FOLLOWING <expr>" (eCond==1) or the
  1054   1290   ** value of the second argument to nth_value() (eCond==2) has just been
  1055   1291   ** evaluated and the result left in register reg. This function generates VM
  1056   1292   ** code to check that the value is a non-negative integer and throws an
  1057   1293   ** exception if it is not.
  1058   1294   */
  1059         -static void windowCheckIntValue(Parse *pParse, int reg, int eCond){
         1295  +static void windowCheckValue(Parse *pParse, int reg, int eCond){
  1060   1296     static const char *azErr[] = {
  1061   1297       "frame starting offset must be a non-negative integer",
  1062   1298       "frame ending offset must be a non-negative integer",
  1063         -    "second argument to nth_value must be a positive integer"
         1299  +    "second argument to nth_value must be a positive integer",
         1300  +    "frame starting offset must be a non-negative number",
         1301  +    "frame ending offset must be a non-negative number",
  1064   1302     };
  1065         -  static int aOp[] = { OP_Ge, OP_Ge, OP_Gt };
         1303  +  static int aOp[] = { OP_Ge, OP_Ge, OP_Gt, OP_Ge, OP_Ge };
  1066   1304     Vdbe *v = sqlite3GetVdbe(pParse);
  1067   1305     int regZero = sqlite3GetTempReg(pParse);
  1068         -  assert( eCond==0 || eCond==1 || eCond==2 );
         1306  +  assert( eCond>=0 && eCond<ArraySize(azErr) );
  1069   1307     sqlite3VdbeAddOp2(v, OP_Integer, 0, regZero);
         1308  +  if( eCond>=WINDOW_STARTING_NUM ){
         1309  +    int regString = sqlite3GetTempReg(pParse);
         1310  +    sqlite3VdbeAddOp4(v, OP_String8, 0, regString, 0, "", P4_STATIC);
         1311  +    sqlite3VdbeAddOp3(v, OP_Ge, regString, sqlite3VdbeCurrentAddr(v)+2, reg);
         1312  +    sqlite3VdbeChangeP5(v, SQLITE_AFF_NUMERIC|SQLITE_JUMPIFNULL);
         1313  +    VdbeCoverage(v);
         1314  +    assert( eCond==3 || eCond==4 );
         1315  +    VdbeCoverageIf(v, eCond==3);
         1316  +    VdbeCoverageIf(v, eCond==4);
         1317  +  }else{
  1070   1318     sqlite3VdbeAddOp2(v, OP_MustBeInt, reg, sqlite3VdbeCurrentAddr(v)+2);
         1319  +    VdbeCoverage(v);
         1320  +    assert( eCond==0 || eCond==1 || eCond==2 );
  1071   1321     VdbeCoverageIf(v, eCond==0);
  1072   1322     VdbeCoverageIf(v, eCond==1);
  1073   1323     VdbeCoverageIf(v, eCond==2);
         1324  +  }
  1074   1325     sqlite3VdbeAddOp3(v, aOp[eCond], regZero, sqlite3VdbeCurrentAddr(v)+2, reg);
  1075         -  VdbeCoverageNeverNullIf(v, eCond==0);
  1076         -  VdbeCoverageNeverNullIf(v, eCond==1);
         1326  +  VdbeCoverageNeverNullIf(v, eCond==0); /* NULL case captured by */
         1327  +  VdbeCoverageNeverNullIf(v, eCond==1); /*   the OP_MustBeInt */
  1077   1328     VdbeCoverageNeverNullIf(v, eCond==2);
         1329  +  VdbeCoverageNeverNullIf(v, eCond==3); /* NULL case caught by */
         1330  +  VdbeCoverageNeverNullIf(v, eCond==4); /*   the OP_Ge */
  1078   1331     sqlite3MayAbort(pParse);
  1079   1332     sqlite3VdbeAddOp2(v, OP_Halt, SQLITE_ERROR, OE_Abort);
  1080   1333     sqlite3VdbeAppendP4(v, (void*)azErr[eCond], P4_STATIC);
  1081   1334     sqlite3ReleaseTempReg(pParse, regZero);
  1082   1335   }
  1083   1336   
  1084   1337   /*
................................................................................
  1110   1363   ** number of rows in the current partition.
  1111   1364   */
  1112   1365   static void windowAggStep(
  1113   1366     Parse *pParse, 
  1114   1367     Window *pMWin,                  /* Linked list of window functions */
  1115   1368     int csr,                        /* Read arguments from this cursor */
  1116   1369     int bInverse,                   /* True to invoke xInverse instead of xStep */
  1117         -  int reg,                        /* Array of registers */
  1118         -  int regPartSize                 /* Register containing size of partition */
         1370  +  int reg                         /* Array of registers */
  1119   1371   ){
  1120   1372     Vdbe *v = sqlite3GetVdbe(pParse);
  1121   1373     Window *pWin;
  1122   1374     for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
  1123         -    int flags = pWin->pFunc->funcFlags;
         1375  +    FuncDef *pFunc = pWin->pFunc;
  1124   1376       int regArg;
  1125   1377       int nArg = windowArgCount(pWin);
  1126         -
  1127         -    if( csr>=0 ){
  1128   1378         int i;
         1379  +
  1129   1380         for(i=0; i<nArg; i++){
         1381  +      if( i!=1 || pFunc->zName!=nth_valueName ){
  1130   1382           sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol+i, reg+i);
         1383  +      }else{
         1384  +        sqlite3VdbeAddOp3(v, OP_Column, pMWin->iEphCsr, pWin->iArgCol+i, reg+i);
         1385  +      }
  1131   1386         }
  1132   1387         regArg = reg;
  1133         -      if( flags & SQLITE_FUNC_WINDOW_SIZE ){
  1134         -        if( nArg==0 ){
  1135         -          regArg = regPartSize;
  1136         -        }else{
  1137         -          sqlite3VdbeAddOp2(v, OP_SCopy, regPartSize, reg+nArg);
  1138         -        }
  1139         -        nArg++;
  1140         -      }
  1141         -    }else{
  1142         -      assert( !(flags & SQLITE_FUNC_WINDOW_SIZE) );
  1143         -      regArg = reg + pWin->iArgCol;
  1144         -    }
  1145   1388   
  1146         -    if( (pWin->pFunc->funcFlags & SQLITE_FUNC_MINMAX) 
  1147         -      && pWin->eStart!=TK_UNBOUNDED 
         1389  +    if( pMWin->regStartRowid==0
         1390  +     && (pFunc->funcFlags & SQLITE_FUNC_MINMAX) 
         1391  +     && (pWin->eStart!=TK_UNBOUNDED)
  1148   1392       ){
  1149   1393         int addrIsNull = sqlite3VdbeAddOp1(v, OP_IsNull, regArg);
  1150   1394         VdbeCoverage(v);
  1151   1395         if( bInverse==0 ){
  1152   1396           sqlite3VdbeAddOp2(v, OP_AddImm, pWin->regApp+1, 1);
  1153   1397           sqlite3VdbeAddOp2(v, OP_SCopy, regArg, pWin->regApp);
  1154   1398           sqlite3VdbeAddOp3(v, OP_MakeRecord, pWin->regApp, 2, pWin->regApp+2);
................................................................................
  1157   1401           sqlite3VdbeAddOp4Int(v, OP_SeekGE, pWin->csrApp, 0, regArg, 1);
  1158   1402           VdbeCoverageNeverTaken(v);
  1159   1403           sqlite3VdbeAddOp1(v, OP_Delete, pWin->csrApp);
  1160   1404           sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-2);
  1161   1405         }
  1162   1406         sqlite3VdbeJumpHere(v, addrIsNull);
  1163   1407       }else if( pWin->regApp ){
  1164         -      assert( pWin->pFunc->zName==nth_valueName
  1165         -           || pWin->pFunc->zName==first_valueName
         1408  +      assert( pFunc->zName==nth_valueName
         1409  +           || pFunc->zName==first_valueName
  1166   1410         );
  1167   1411         assert( bInverse==0 || bInverse==1 );
  1168   1412         sqlite3VdbeAddOp2(v, OP_AddImm, pWin->regApp+1-bInverse, 1);
  1169         -    }else if( pWin->pFunc->zName==leadName
  1170         -           || pWin->pFunc->zName==lagName
  1171         -    ){
  1172         -      /* no-op */
  1173         -    }else{
         1413  +    }else if( pFunc->xSFunc!=noopStepFunc ){
  1174   1414         int addrIf = 0;
  1175   1415         if( pWin->pFilter ){
  1176   1416           int regTmp;
  1177   1417           assert( nArg==0 || nArg==pWin->pOwner->x.pList->nExpr );
  1178   1418           assert( nArg || pWin->pOwner->x.pList==0 );
  1179         -        if( csr>0 ){
  1180   1419             regTmp = sqlite3GetTempReg(pParse);
  1181   1420             sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol+nArg,regTmp);
  1182         -        }else{
  1183         -          regTmp = regArg + nArg;
  1184         -        }
  1185   1421           addrIf = sqlite3VdbeAddOp3(v, OP_IfNot, regTmp, 0, 1);
  1186   1422           VdbeCoverage(v);
  1187         -        if( csr>0 ){
  1188   1423             sqlite3ReleaseTempReg(pParse, regTmp);
  1189   1424           }
  1190         -      }
  1191         -      if( pWin->pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL ){
         1425  +      if( pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL ){
  1192   1426           CollSeq *pColl;
  1193   1427           assert( nArg>0 );
  1194   1428           pColl = sqlite3ExprNNCollSeq(pParse, pWin->pOwner->x.pList->a[0].pExpr);
  1195   1429           sqlite3VdbeAddOp4(v, OP_CollSeq, 0,0,0, (const char*)pColl, P4_COLLSEQ);
  1196   1430         }
  1197   1431         sqlite3VdbeAddOp3(v, bInverse? OP_AggInverse : OP_AggStep, 
  1198   1432                           bInverse, regArg, pWin->regAccum);
  1199         -      sqlite3VdbeAppendP4(v, pWin->pFunc, P4_FUNCDEF);
         1433  +      sqlite3VdbeAppendP4(v, pFunc, P4_FUNCDEF);
  1200   1434         sqlite3VdbeChangeP5(v, (u8)nArg);
  1201   1435         if( addrIf ) sqlite3VdbeJumpHere(v, addrIf);
  1202   1436       }
  1203   1437     }
  1204   1438   }
  1205   1439   
         1440  +typedef struct WindowCodeArg WindowCodeArg;
         1441  +typedef struct WindowCsrAndReg WindowCsrAndReg;
         1442  +struct WindowCsrAndReg {
         1443  +  int csr;
         1444  +  int reg;
         1445  +};
         1446  +
         1447  +struct WindowCodeArg {
         1448  +  Parse *pParse;
         1449  +  Window *pMWin;
         1450  +  Vdbe *pVdbe;
         1451  +  int regGosub;
         1452  +  int addrGosub;
         1453  +  int regArg;
         1454  +  int eDelete;
         1455  +
         1456  +  WindowCsrAndReg start;
         1457  +  WindowCsrAndReg current;
         1458  +  WindowCsrAndReg end;
         1459  +};
         1460  +
  1206   1461   /*
  1207         -** Generate VM code to invoke either xValue() (bFinal==0) or xFinalize()
  1208         -** (bFinal==1) for each window function in the linked list starting at
         1462  +** Values that may be passed as the second argument to windowCodeOp().
         1463  +*/
         1464  +#define WINDOW_RETURN_ROW 1
         1465  +#define WINDOW_AGGINVERSE 2
         1466  +#define WINDOW_AGGSTEP    3
         1467  +
         1468  +/*
         1469  +** Generate VM code to read the window frames peer values from cursor csr into
         1470  +** an array of registers starting at reg.
         1471  +*/
         1472  +static void windowReadPeerValues(
         1473  +  WindowCodeArg *p,
         1474  +  int csr,
         1475  +  int reg
         1476  +){
         1477  +  Window *pMWin = p->pMWin;
         1478  +  ExprList *pOrderBy = pMWin->pOrderBy;
         1479  +  if( pOrderBy ){
         1480  +    Vdbe *v = sqlite3GetVdbe(p->pParse);
         1481  +    ExprList *pPart = pMWin->pPartition;
         1482  +    int iColOff = pMWin->nBufferCol + (pPart ? pPart->nExpr : 0);
         1483  +    int i;
         1484  +    for(i=0; i<pOrderBy->nExpr; i++){
         1485  +      sqlite3VdbeAddOp3(v, OP_Column, csr, iColOff+i, reg+i);
         1486  +    }
         1487  +  }
         1488  +}
         1489  +
         1490  +/*
         1491  +** Generate VM code to invoke either xValue() (bFin==0) or xFinalize()
         1492  +** (bFin==1) for each window function in the linked list starting at
  1209   1493   ** pMWin. Or, for built-in window-functions that do not use the standard
  1210   1494   ** API, generate the equivalent VM code.
  1211   1495   */
  1212         -static void windowAggFinal(Parse *pParse, Window *pMWin, int bFinal){
         1496  +static void windowAggFinal(WindowCodeArg *p, int bFin){
         1497  +  Parse *pParse = p->pParse;
         1498  +  Window *pMWin = p->pMWin;
  1213   1499     Vdbe *v = sqlite3GetVdbe(pParse);
  1214   1500     Window *pWin;
  1215   1501   
  1216   1502     for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
  1217         -    if( (pWin->pFunc->funcFlags & SQLITE_FUNC_MINMAX) 
  1218         -     && pWin->eStart!=TK_UNBOUNDED 
         1503  +    if( pMWin->regStartRowid==0
         1504  +     && (pWin->pFunc->funcFlags & SQLITE_FUNC_MINMAX) 
         1505  +     && (pWin->eStart!=TK_UNBOUNDED)
  1219   1506       ){
  1220   1507         sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regResult);
  1221   1508         sqlite3VdbeAddOp1(v, OP_Last, pWin->csrApp);
  1222   1509         VdbeCoverage(v);
  1223   1510         sqlite3VdbeAddOp3(v, OP_Column, pWin->csrApp, 0, pWin->regResult);
  1224   1511         sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-2);
  1225         -      if( bFinal ){
  1226         -        sqlite3VdbeAddOp1(v, OP_ResetSorter, pWin->csrApp);
  1227         -      }
  1228   1512       }else if( pWin->regApp ){
         1513  +      assert( pMWin->regStartRowid==0 );
  1229   1514       }else{
  1230         -      if( bFinal ){
  1231         -        sqlite3VdbeAddOp2(v, OP_AggFinal, pWin->regAccum, windowArgCount(pWin));
         1515  +      int nArg = windowArgCount(pWin);
         1516  +      if( bFin ){
         1517  +        sqlite3VdbeAddOp2(v, OP_AggFinal, pWin->regAccum, nArg);
  1232   1518           sqlite3VdbeAppendP4(v, pWin->pFunc, P4_FUNCDEF);
  1233   1519           sqlite3VdbeAddOp2(v, OP_Copy, pWin->regAccum, pWin->regResult);
  1234   1520           sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regAccum);
  1235   1521         }else{
  1236         -        sqlite3VdbeAddOp3(v, OP_AggValue, pWin->regAccum, windowArgCount(pWin),
  1237         -                             pWin->regResult);
         1522  +        sqlite3VdbeAddOp3(v, OP_AggValue,pWin->regAccum,nArg,pWin->regResult);
  1238   1523           sqlite3VdbeAppendP4(v, pWin->pFunc, P4_FUNCDEF);
  1239   1524         }
  1240   1525       }
  1241   1526     }
  1242   1527   }
  1243   1528   
  1244   1529   /*
  1245         -** This function generates VM code to invoke the sub-routine at address
  1246         -** lblFlushPart once for each partition with the entire partition cached in
  1247         -** the Window.iEphCsr temp table.
         1530  +** Generate code to calculate the current values of all window functions in the
         1531  +** p->pMWin list by doing a full scan of the current window frame. Store the
         1532  +** results in the Window.regResult registers, ready to return the upper
         1533  +** layer.
  1248   1534   */
  1249         -static void windowPartitionCache(
  1250         -  Parse *pParse,
  1251         -  Select *p,                      /* The rewritten SELECT statement */
  1252         -  WhereInfo *pWInfo,              /* WhereInfo to call WhereEnd() on */
  1253         -  int regFlushPart,               /* Register to use with Gosub lblFlushPart */
  1254         -  int lblFlushPart,               /* Subroutine to Gosub to */
  1255         -  int *pRegSize                   /* OUT: Register containing partition size */
  1256         -){
  1257         -  Window *pMWin = p->pWin;
  1258         -  Vdbe *v = sqlite3GetVdbe(pParse);
  1259         -  int iSubCsr = p->pSrc->a[0].iCursor;
  1260         -  int nSub = p->pSrc->a[0].pTab->nCol;
  1261         -  int k;
  1262         -
  1263         -  int reg = pParse->nMem+1;
  1264         -  int regRecord = reg+nSub;
  1265         -  int regRowid = regRecord+1;
  1266         -
  1267         -  *pRegSize = regRowid;
  1268         -  pParse->nMem += nSub + 2;
  1269         -
  1270         -  /* Load the column values for the row returned by the sub-select
  1271         -  ** into an array of registers starting at reg. */
  1272         -  for(k=0; k<nSub; k++){
  1273         -    sqlite3VdbeAddOp3(v, OP_Column, iSubCsr, k, reg+k);
  1274         -  }
  1275         -  sqlite3VdbeAddOp3(v, OP_MakeRecord, reg, nSub, regRecord);
  1276         -
  1277         -  /* Check if this is the start of a new partition. If so, call the
  1278         -  ** flush_partition sub-routine.  */
  1279         -  if( pMWin->pPartition ){
         1535  +static void windowFullScan(WindowCodeArg *p){
         1536  +  Window *pWin;
         1537  +  Parse *pParse = p->pParse;
         1538  +  Window *pMWin = p->pMWin;
         1539  +  Vdbe *v = p->pVdbe;
         1540  +
         1541  +  int regCRowid = 0;              /* Current rowid value */
         1542  +  int regCPeer = 0;               /* Current peer values */
         1543  +  int regRowid = 0;               /* AggStep rowid value */
         1544  +  int regPeer = 0;                /* AggStep peer values */
         1545  +
         1546  +  int nPeer;
         1547  +  int lblNext;
         1548  +  int lblBrk;
         1549  +  int addrNext;
         1550  +  int csr = pMWin->csrApp;
         1551  +
         1552  +  nPeer = (pMWin->pOrderBy ? pMWin->pOrderBy->nExpr : 0);
         1553  +
         1554  +  lblNext = sqlite3VdbeMakeLabel(pParse);
         1555  +  lblBrk = sqlite3VdbeMakeLabel(pParse);
         1556  +
         1557  +  regCRowid = sqlite3GetTempReg(pParse);
         1558  +  regRowid = sqlite3GetTempReg(pParse);
         1559  +  if( nPeer ){
         1560  +    regCPeer = sqlite3GetTempRange(pParse, nPeer);
         1561  +    regPeer = sqlite3GetTempRange(pParse, nPeer);
         1562  +  }
         1563  +
         1564  +  sqlite3VdbeAddOp2(v, OP_Rowid, pMWin->iEphCsr, regCRowid);
         1565  +  windowReadPeerValues(p, pMWin->iEphCsr, regCPeer);
         1566  +
         1567  +  for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
         1568  +    sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regAccum);
         1569  +  }
         1570  +
         1571  +  sqlite3VdbeAddOp3(v, OP_SeekGE, csr, lblBrk, pMWin->regStartRowid);
         1572  +  VdbeCoverage(v);
         1573  +  addrNext = sqlite3VdbeCurrentAddr(v);
         1574  +  sqlite3VdbeAddOp2(v, OP_Rowid, csr, regRowid);
         1575  +  sqlite3VdbeAddOp3(v, OP_Gt, pMWin->regEndRowid, lblBrk, regRowid);
         1576  +  VdbeCoverageNeverNull(v);
         1577  +
         1578  +  if( pMWin->eExclude==TK_CURRENT ){
         1579  +    sqlite3VdbeAddOp3(v, OP_Eq, regCRowid, lblNext, regRowid);
         1580  +    VdbeCoverageNeverNull(v);
         1581  +  }else if( pMWin->eExclude!=TK_NO ){
  1280   1582       int addr;
  1281         -    ExprList *pPart = pMWin->pPartition;
  1282         -    int nPart = pPart->nExpr;
  1283         -    int regNewPart = reg + pMWin->nBufferCol;
  1284         -    KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pPart, 0, 0);
         1583  +    int addrEq = 0;
         1584  +    KeyInfo *pKeyInfo = 0;
  1285   1585   
  1286         -    addr = sqlite3VdbeAddOp3(v, OP_Compare, regNewPart, pMWin->regPart,nPart);
         1586  +    if( pMWin->pOrderBy ){
         1587  +      pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pMWin->pOrderBy, 0, 0);
         1588  +    }
         1589  +    if( pMWin->eExclude==TK_TIES ){
         1590  +      addrEq = sqlite3VdbeAddOp3(v, OP_Eq, regCRowid, 0, regRowid);
         1591  +      VdbeCoverageNeverNull(v);
         1592  +    }
         1593  +    if( pKeyInfo ){
         1594  +      windowReadPeerValues(p, csr, regPeer);
         1595  +      sqlite3VdbeAddOp3(v, OP_Compare, regPeer, regCPeer, nPeer);
  1287   1596       sqlite3VdbeAppendP4(v, (void*)pKeyInfo, P4_KEYINFO);
  1288         -    sqlite3VdbeAddOp3(v, OP_Jump, addr+2, addr+4, addr+2);
         1597  +      addr = sqlite3VdbeCurrentAddr(v)+1;
         1598  +      sqlite3VdbeAddOp3(v, OP_Jump, addr, lblNext, addr);
  1289   1599       VdbeCoverageEqNe(v);
  1290         -    sqlite3VdbeAddOp3(v, OP_Copy, regNewPart, pMWin->regPart, nPart-1);
  1291         -    sqlite3VdbeAddOp2(v, OP_Gosub, regFlushPart, lblFlushPart);
  1292         -    VdbeComment((v, "call flush_partition"));
         1600  +    }else{
         1601  +      sqlite3VdbeAddOp2(v, OP_Goto, 0, lblNext);
         1602  +    }
         1603  +    if( addrEq ) sqlite3VdbeJumpHere(v, addrEq);
  1293   1604     }
  1294   1605   
  1295         -  /* Buffer the current row in the ephemeral table. */
  1296         -  sqlite3VdbeAddOp2(v, OP_NewRowid, pMWin->iEphCsr, regRowid);
  1297         -  sqlite3VdbeAddOp3(v, OP_Insert, pMWin->iEphCsr, regRecord, regRowid);
         1606  +  windowAggStep(pParse, pMWin, csr, 0, p->regArg);
  1298   1607   
  1299         -  /* End of the input loop */
  1300         -  sqlite3WhereEnd(pWInfo);
         1608  +  sqlite3VdbeResolveLabel(v, lblNext);
         1609  +  sqlite3VdbeAddOp2(v, OP_Next, csr, addrNext);
         1610  +  VdbeCoverage(v);
         1611  +  sqlite3VdbeJumpHere(v, addrNext-1);
         1612  +  sqlite3VdbeJumpHere(v, addrNext+1);
         1613  +  sqlite3ReleaseTempReg(pParse, regRowid);
         1614  +  sqlite3ReleaseTempReg(pParse, regCRowid);
         1615  +  if( nPeer ){
         1616  +    sqlite3ReleaseTempRange(pParse, regPeer, nPeer);
         1617  +    sqlite3ReleaseTempRange(pParse, regCPeer, nPeer);
         1618  +  }
  1301   1619   
  1302         -  /* Invoke "flush_partition" to deal with the final (or only) partition */
  1303         -  sqlite3VdbeAddOp2(v, OP_Gosub, regFlushPart, lblFlushPart);
  1304         -  VdbeComment((v, "call flush_partition"));
         1620  +  windowAggFinal(p, 1);
  1305   1621   }
  1306   1622   
  1307   1623   /*
  1308   1624   ** Invoke the sub-routine at regGosub (generated by code in select.c) to
  1309   1625   ** return the current row of Window.iEphCsr. If all window functions are
  1310   1626   ** aggregate window functions that use the standard API, a single
  1311   1627   ** OP_Gosub instruction is all that this routine generates. Extra VM code
................................................................................
  1313   1629   ** functions:
  1314   1630   **
  1315   1631   **   nth_value()
  1316   1632   **   first_value()
  1317   1633   **   lag()
  1318   1634   **   lead()
  1319   1635   */
  1320         -static void windowReturnOneRow(
  1321         -  Parse *pParse,
  1322         -  Window *pMWin,
  1323         -  int regGosub,
  1324         -  int addrGosub
  1325         -){
  1326         -  Vdbe *v = sqlite3GetVdbe(pParse);
         1636  +static void windowReturnOneRow(WindowCodeArg *p){
         1637  +  Window *pMWin = p->pMWin;
         1638  +  Vdbe *v = p->pVdbe;
         1639  +
         1640  +  if( pMWin->regStartRowid ){
         1641  +    windowFullScan(p);
         1642  +  }else{
         1643  +    Parse *pParse = p->pParse;
  1327   1644     Window *pWin;
         1645  +
  1328   1646     for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
  1329   1647       FuncDef *pFunc = pWin->pFunc;
  1330   1648       if( pFunc->zName==nth_valueName
  1331   1649        || pFunc->zName==first_valueName
  1332   1650       ){
  1333   1651         int csr = pWin->csrApp;
  1334   1652         int lbl = sqlite3VdbeMakeLabel(pParse);
  1335   1653         int tmpReg = sqlite3GetTempReg(pParse);
  1336   1654         sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regResult);
  1337   1655   
  1338   1656         if( pFunc->zName==nth_valueName ){
  1339   1657           sqlite3VdbeAddOp3(v, OP_Column, pMWin->iEphCsr, pWin->iArgCol+1,tmpReg);
  1340         -        windowCheckIntValue(pParse, tmpReg, 2);
         1658  +          windowCheckValue(pParse, tmpReg, 2);
  1341   1659         }else{
  1342   1660           sqlite3VdbeAddOp2(v, OP_Integer, 1, tmpReg);
  1343   1661         }
  1344   1662         sqlite3VdbeAddOp3(v, OP_Add, tmpReg, pWin->regApp, tmpReg);
  1345   1663         sqlite3VdbeAddOp3(v, OP_Gt, pWin->regApp+1, lbl, tmpReg);
  1346   1664         VdbeCoverageNeverNull(v);
  1347   1665         sqlite3VdbeAddOp3(v, OP_SeekRowid, csr, 0, tmpReg);
................................................................................
  1348   1666         VdbeCoverageNeverTaken(v);
  1349   1667         sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol, pWin->regResult);
  1350   1668         sqlite3VdbeResolveLabel(v, lbl);
  1351   1669         sqlite3ReleaseTempReg(pParse, tmpReg);
  1352   1670       }
  1353   1671       else if( pFunc->zName==leadName || pFunc->zName==lagName ){
  1354   1672         int nArg = pWin->pOwner->x.pList->nExpr;
  1355         -      int iEph = pMWin->iEphCsr;
  1356   1673         int csr = pWin->csrApp;
  1357   1674         int lbl = sqlite3VdbeMakeLabel(pParse);
  1358   1675         int tmpReg = sqlite3GetTempReg(pParse);
         1676  +        int iEph = pMWin->iEphCsr;
  1359   1677   
  1360   1678         if( nArg<3 ){
  1361   1679           sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regResult);
  1362   1680         }else{
  1363   1681           sqlite3VdbeAddOp3(v, OP_Column, iEph, pWin->iArgCol+2, pWin->regResult);
  1364   1682         }
  1365   1683         sqlite3VdbeAddOp2(v, OP_Rowid, iEph, tmpReg);
................................................................................
  1377   1695         sqlite3VdbeAddOp3(v, OP_SeekRowid, csr, lbl, tmpReg);
  1378   1696         VdbeCoverage(v);
  1379   1697         sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol, pWin->regResult);
  1380   1698         sqlite3VdbeResolveLabel(v, lbl);
  1381   1699         sqlite3ReleaseTempReg(pParse, tmpReg);
  1382   1700       }
  1383   1701     }
  1384         -  sqlite3VdbeAddOp2(v, OP_Gosub, regGosub, addrGosub);
  1385   1702   }
  1386         -
  1387         -/*
  1388         -** Invoke the code generated by windowReturnOneRow() and, optionally, the
  1389         -** xInverse() function for each window function, for one or more rows
  1390         -** from the Window.iEphCsr temp table. This routine generates VM code
  1391         -** similar to:
  1392         -**
  1393         -**   while( regCtr>0 ){
  1394         -**     regCtr--;
  1395         -**     windowReturnOneRow()
  1396         -**     if( bInverse ){
  1397         -**       AggInverse
  1398         -**     }
  1399         -**     Next (Window.iEphCsr)
  1400         -**   }
  1401         -*/
  1402         -static void windowReturnRows(
  1403         -  Parse *pParse,
  1404         -  Window *pMWin,                  /* List of window functions */
  1405         -  int regCtr,                     /* Register containing number of rows */
  1406         -  int regGosub,                   /* Register for Gosub addrGosub */
  1407         -  int addrGosub,                  /* Address of sub-routine for ReturnOneRow */
  1408         -  int regInvArg,                  /* Array of registers for xInverse args */
  1409         -  int regInvSize                  /* Register containing size of partition */
  1410         -){
  1411         -  int addr;
  1412         -  Vdbe *v = sqlite3GetVdbe(pParse);
  1413         -  windowAggFinal(pParse, pMWin, 0);
  1414         -  addr = sqlite3VdbeAddOp3(v, OP_IfPos, regCtr, sqlite3VdbeCurrentAddr(v)+2 ,1);
  1415         -  VdbeCoverage(v);
  1416         -  sqlite3VdbeAddOp2(v, OP_Goto, 0, 0);
  1417         -  windowReturnOneRow(pParse, pMWin, regGosub, addrGosub);
  1418         -  if( regInvArg ){
  1419         -    windowAggStep(pParse, pMWin, pMWin->iEphCsr, 1, regInvArg, regInvSize);
  1420         -  }
  1421         -  sqlite3VdbeAddOp2(v, OP_Next, pMWin->iEphCsr, addr);
  1422         -  VdbeCoverage(v);
  1423         -  sqlite3VdbeJumpHere(v, addr+1);   /* The OP_Goto */
         1703  +  sqlite3VdbeAddOp2(v, OP_Gosub, p->regGosub, p->addrGosub);
  1424   1704   }
  1425   1705   
  1426   1706   /*
  1427   1707   ** Generate code to set the accumulator register for each window function
  1428   1708   ** in the linked list passed as the second argument to NULL. And perform
  1429   1709   ** any equivalent initialization required by any built-in window functions
  1430   1710   ** in the list.
................................................................................
  1434   1714     int regArg;
  1435   1715     int nArg = 0;
  1436   1716     Window *pWin;
  1437   1717     for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
  1438   1718       FuncDef *pFunc = pWin->pFunc;
  1439   1719       sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regAccum);
  1440   1720       nArg = MAX(nArg, windowArgCount(pWin));
  1441         -    if( pFunc->zName==nth_valueName
  1442         -     || pFunc->zName==first_valueName
  1443         -    ){
         1721  +    if( pMWin->regStartRowid==0 ){
         1722  +      if( pFunc->zName==nth_valueName || pFunc->zName==first_valueName ){
  1444   1723         sqlite3VdbeAddOp2(v, OP_Integer, 0, pWin->regApp);
  1445   1724         sqlite3VdbeAddOp2(v, OP_Integer, 0, pWin->regApp+1);
  1446   1725       }
  1447   1726   
  1448   1727       if( (pFunc->funcFlags & SQLITE_FUNC_MINMAX) && pWin->csrApp ){
  1449   1728         assert( pWin->eStart!=TK_UNBOUNDED );
  1450   1729         sqlite3VdbeAddOp1(v, OP_ResetSorter, pWin->csrApp);
  1451   1730         sqlite3VdbeAddOp2(v, OP_Integer, 0, pWin->regApp+1);
  1452   1731       }
  1453   1732     }
         1733  +  }
  1454   1734     regArg = pParse->nMem+1;
  1455   1735     pParse->nMem += nArg;
  1456   1736     return regArg;
  1457   1737   }
  1458   1738   
         1739  +/* 
         1740  +** Return true if the current frame should be cached in the ephemeral table,
         1741  +** even if there are no xInverse() calls required.
         1742  +*/
         1743  +static int windowCacheFrame(Window *pMWin){
         1744  +  Window *pWin;
         1745  +  if( pMWin->regStartRowid ) return 1;
         1746  +  for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
         1747  +    FuncDef *pFunc = pWin->pFunc;
         1748  +    if( (pFunc->zName==nth_valueName)
         1749  +     || (pFunc->zName==first_valueName)
         1750  +     || (pFunc->zName==leadName)
         1751  +     || (pFunc->zName==lagName)
         1752  +    ){
         1753  +      return 1;
         1754  +    }
         1755  +  }
         1756  +  return 0;
         1757  +}
         1758  +
         1759  +/*
         1760  +** regOld and regNew are each the first register in an array of size
         1761  +** pOrderBy->nExpr. This function generates code to compare the two
         1762  +** arrays of registers using the collation sequences and other comparison
         1763  +** parameters specified by pOrderBy. 
         1764  +**
         1765  +** If the two arrays are not equal, the contents of regNew is copied to 
         1766  +** regOld and control falls through. Otherwise, if the contents of the arrays
         1767  +** are equal, an OP_Goto is executed. The address of the OP_Goto is returned.
         1768  +*/
         1769  +static void windowIfNewPeer(
         1770  +  Parse *pParse,
         1771  +  ExprList *pOrderBy,
         1772  +  int regNew,                     /* First in array of new values */
         1773  +  int regOld,                     /* First in array of old values */
         1774  +  int addr                        /* Jump here */
         1775  +){
         1776  +  Vdbe *v = sqlite3GetVdbe(pParse);
         1777  +  if( pOrderBy ){
         1778  +    int nVal = pOrderBy->nExpr;
         1779  +    KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pOrderBy, 0, 0);
         1780  +    sqlite3VdbeAddOp3(v, OP_Compare, regOld, regNew, nVal);
         1781  +    sqlite3VdbeAppendP4(v, (void*)pKeyInfo, P4_KEYINFO);
         1782  +    sqlite3VdbeAddOp3(v, OP_Jump, 
         1783  +      sqlite3VdbeCurrentAddr(v)+1, addr, sqlite3VdbeCurrentAddr(v)+1
         1784  +    );
         1785  +    VdbeCoverageEqNe(v);
         1786  +    sqlite3VdbeAddOp3(v, OP_Copy, regNew, regOld, nVal-1);
         1787  +  }else{
         1788  +    sqlite3VdbeAddOp2(v, OP_Goto, 0, addr);
         1789  +  }
         1790  +}
  1459   1791   
  1460   1792   /*
  1461         -** This function does the work of sqlite3WindowCodeStep() for all "ROWS"
  1462         -** window frame types except for "BETWEEN UNBOUNDED PRECEDING AND CURRENT
  1463         -** ROW". Pseudo-code for each follows.
  1464         -**
  1465         -** ROWS BETWEEN <expr1> PRECEDING AND <expr2> FOLLOWING
  1466         -**
  1467         -**     ...
  1468         -**       if( new partition ){
  1469         -**         Gosub flush_partition
  1470         -**       }
  1471         -**       Insert (record in eph-table)
  1472         -**     sqlite3WhereEnd()
  1473         -**     Gosub flush_partition
  1474         -**  
  1475         -**   flush_partition:
  1476         -**     Once {
  1477         -**       OpenDup (iEphCsr -> csrStart)
  1478         -**       OpenDup (iEphCsr -> csrEnd)
  1479         -**     }
  1480         -**     regStart = <expr1>                // PRECEDING expression
  1481         -**     regEnd = <expr2>                  // FOLLOWING expression
  1482         -**     if( regStart<0 || regEnd<0 ){ error! }
  1483         -**     Rewind (csr,csrStart,csrEnd)      // if EOF goto flush_partition_done
  1484         -**       Next(csrEnd)                    // if EOF skip Aggstep
  1485         -**       Aggstep (csrEnd)
  1486         -**       if( (regEnd--)<=0 ){
  1487         -**         AggFinal (xValue)
  1488         -**         Gosub addrGosub
  1489         -**         Next(csr)                // if EOF goto flush_partition_done
  1490         -**         if( (regStart--)<=0 ){
  1491         -**           AggInverse (csrStart)
  1492         -**           Next(csrStart)
  1493         -**         }
  1494         -**       }
  1495         -**   flush_partition_done:
  1496         -**     ResetSorter (csr)
  1497         -**     Return
  1498         -**
  1499         -** ROWS BETWEEN <expr> PRECEDING    AND CURRENT ROW
  1500         -** ROWS BETWEEN CURRENT ROW         AND <expr> FOLLOWING
  1501         -** ROWS BETWEEN UNBOUNDED PRECEDING AND <expr> FOLLOWING
  1502         -**
  1503         -**   These are similar to the above. For "CURRENT ROW", intialize the
  1504         -**   register to 0. For "UNBOUNDED PRECEDING" to infinity.
  1505         -**
  1506         -** ROWS BETWEEN <expr> PRECEDING    AND UNBOUNDED FOLLOWING
  1507         -** ROWS BETWEEN CURRENT ROW         AND UNBOUNDED FOLLOWING
  1508         -**
  1509         -**     Rewind (csr,csrStart,csrEnd)    // if EOF goto flush_partition_done
  1510         -**     while( 1 ){
  1511         -**       Next(csrEnd)                  // Exit while(1) at EOF
  1512         -**       Aggstep (csrEnd)
  1513         -**     }
  1514         -**     while( 1 ){
  1515         -**       AggFinal (xValue)
  1516         -**       Gosub addrGosub
  1517         -**       Next(csr)                     // if EOF goto flush_partition_done
  1518         -**       if( (regStart--)<=0 ){
  1519         -**         AggInverse (csrStart)
  1520         -**         Next(csrStart)
  1521         -**       }
  1522         -**     }
  1523         -**
  1524         -**   For the "CURRENT ROW AND UNBOUNDED FOLLOWING" case, the final if() 
  1525         -**   condition is always true (as if regStart were initialized to 0).
  1526         -**
  1527         -** RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
  1528         -** 
  1529         -**   This is the only RANGE case handled by this routine. It modifies the
  1530         -**   second while( 1 ) loop in "ROWS BETWEEN CURRENT ... UNBOUNDED..." to
  1531         -**   be:
  1532         -**
  1533         -**     while( 1 ){
  1534         -**       AggFinal (xValue)
  1535         -**       while( 1 ){
  1536         -**         regPeer++
  1537         -**         Gosub addrGosub
  1538         -**         Next(csr)                     // if EOF goto flush_partition_done
  1539         -**         if( new peer ) break;
  1540         -**       }
  1541         -**       while( (regPeer--)>0 ){
  1542         -**         AggInverse (csrStart)
  1543         -**         Next(csrStart)
  1544         -**       }
  1545         -**     }
  1546         -**
  1547         -** ROWS BETWEEN <expr> FOLLOWING    AND <expr> FOLLOWING
  1548         -**
  1549         -**   regEnd = regEnd - regStart
  1550         -**   Rewind (csr,csrStart,csrEnd)   // if EOF goto flush_partition_done
  1551         -**     Aggstep (csrEnd)
  1552         -**     Next(csrEnd)                 // if EOF fall-through
  1553         -**     if( (regEnd--)<=0 ){
  1554         -**       if( (regStart--)<=0 ){
  1555         -**         AggFinal (xValue)
  1556         -**         Gosub addrGosub
  1557         -**         Next(csr)              // if EOF goto flush_partition_done
  1558         -**       }
  1559         -**       AggInverse (csrStart)
  1560         -**       Next (csrStart)
  1561         -**     }
  1562         -**
  1563         -** ROWS BETWEEN <expr> PRECEDING    AND <expr> PRECEDING
  1564         -**
  1565         -**   Replace the bit after "Rewind" in the above with:
  1566         -**
  1567         -**     if( (regEnd--)<=0 ){
  1568         -**       AggStep (csrEnd)
  1569         -**       Next (csrEnd)
  1570         -**     }
  1571         -**     AggFinal (xValue)
  1572         -**     Gosub addrGosub
  1573         -**     Next(csr)                  // if EOF goto flush_partition_done
  1574         -**     if( (regStart--)<=0 ){
  1575         -**       AggInverse (csr2)
  1576         -**       Next (csr2)
  1577         -**     }
  1578         -**
         1793  +** This function is called as part of generating VM programs for RANGE
         1794  +** offset PRECEDING/FOLLOWING frame boundaries. Assuming "ASC" order for
         1795  +** the ORDER BY term in the window, it generates code equivalent to:
         1796  +**
         1797  +**   if( csr1.peerVal + regVal >= csr2.peerVal ) goto lbl;
         1798  +**
         1799  +** A special type of arithmetic is used such that if csr.peerVal is not
         1800  +** a numeric type (real or integer), then the result of the addition is
         1801  +** a copy of csr1.peerVal.
  1579   1802   */
  1580         -static void windowCodeRowExprStep(
  1581         -  Parse *pParse, 
  1582         -  Select *p,
  1583         -  WhereInfo *pWInfo,
  1584         -  int regGosub, 
  1585         -  int addrGosub
         1803  +static void windowCodeRangeTest(
         1804  +  WindowCodeArg *p, 
         1805  +  int op,                          /* OP_Ge or OP_Gt */
         1806  +  int csr1, 
         1807  +  int regVal, 
         1808  +  int csr2,
         1809  +  int lbl
  1586   1810   ){
  1587         -  Window *pMWin = p->pWin;
         1811  +  Parse *pParse = p->pParse;
  1588   1812     Vdbe *v = sqlite3GetVdbe(pParse);
  1589         -  int regFlushPart;               /* Register for "Gosub flush_partition" */
  1590         -  int lblFlushPart;               /* Label for "Gosub flush_partition" */
  1591         -  int lblFlushDone;               /* Label for "Gosub flush_partition_done" */
  1592         -
  1593         -  int regArg;
  1594         -  int addr;
  1595         -  int csrStart = pParse->nTab++;
  1596         -  int csrEnd = pParse->nTab++;
  1597         -  int regStart;                    /* Value of <expr> PRECEDING */
  1598         -  int regEnd;                      /* Value of <expr> FOLLOWING */
  1599         -  int addrGoto;
  1600         -  int addrTop;
  1601         -  int addrIfPos1 = 0;
  1602         -  int addrIfPos2 = 0;
  1603         -  int regSize = 0;
  1604         -
  1605         -  assert( pMWin->eStart==TK_PRECEDING 
  1606         -       || pMWin->eStart==TK_CURRENT 
  1607         -       || pMWin->eStart==TK_FOLLOWING 
  1608         -       || pMWin->eStart==TK_UNBOUNDED 
  1609         -  );
  1610         -  assert( pMWin->eEnd==TK_FOLLOWING 
  1611         -       || pMWin->eEnd==TK_CURRENT 
  1612         -       || pMWin->eEnd==TK_UNBOUNDED 
  1613         -       || pMWin->eEnd==TK_PRECEDING 
  1614         -  );
  1615         -
  1616         -  /* Allocate register and label for the "flush_partition" sub-routine. */
  1617         -  regFlushPart = ++pParse->nMem;
  1618         -  lblFlushPart = sqlite3VdbeMakeLabel(pParse);
  1619         -  lblFlushDone = sqlite3VdbeMakeLabel(pParse);
  1620         -
  1621         -  regStart = ++pParse->nMem;
  1622         -  regEnd = ++pParse->nMem;
  1623         -
  1624         -  windowPartitionCache(pParse, p, pWInfo, regFlushPart, lblFlushPart, &regSize);
  1625         -
  1626         -  addrGoto = sqlite3VdbeAddOp0(v, OP_Goto);
  1627         -
  1628         -  /* Start of "flush_partition" */
  1629         -  sqlite3VdbeResolveLabel(v, lblFlushPart);
  1630         -  sqlite3VdbeAddOp2(v, OP_Once, 0, sqlite3VdbeCurrentAddr(v)+3);
         1813  +  int reg1 = sqlite3GetTempReg(pParse);
         1814  +  int reg2 = sqlite3GetTempReg(pParse);
         1815  +  int arith = OP_Add;
         1816  +  int addrGe;
         1817  +
         1818  +  int regString = ++pParse->nMem;
         1819  +
         1820  +  assert( op==OP_Ge || op==OP_Gt || op==OP_Le );
         1821  +  assert( p->pMWin->pOrderBy && p->pMWin->pOrderBy->nExpr==1 );
         1822  +  if( p->pMWin->pOrderBy->a[0].sortOrder ){
         1823  +    switch( op ){
         1824  +      case OP_Ge: op = OP_Le; break;
         1825  +      case OP_Gt: op = OP_Lt; break;
         1826  +      default: assert( op==OP_Le ); op = OP_Ge; break;
         1827  +    }
         1828  +    arith = OP_Subtract;
         1829  +  }
         1830  +
         1831  +  windowReadPeerValues(p, csr1, reg1);
         1832  +  windowReadPeerValues(p, csr2, reg2);
         1833  +
         1834  +  /* Check if the peer value for csr1 value is a text or blob by comparing
         1835  +  ** it to the smallest possible string - ''. If it is, jump over the
         1836  +  ** OP_Add or OP_Subtract operation and proceed directly to the comparison. */
         1837  +  sqlite3VdbeAddOp4(v, OP_String8, 0, regString, 0, "", P4_STATIC);
         1838  +  addrGe = sqlite3VdbeAddOp3(v, OP_Ge, regString, 0, reg1);
  1631   1839     VdbeCoverage(v);
  1632         -  VdbeComment((v, "Flush_partition subroutine"));
  1633         -  sqlite3VdbeAddOp2(v, OP_OpenDup, csrStart, pMWin->iEphCsr);
  1634         -  sqlite3VdbeAddOp2(v, OP_OpenDup, csrEnd, pMWin->iEphCsr);
  1635         -
  1636         -  /* If either regStart or regEnd are not non-negative integers, throw 
  1637         -  ** an exception.  */
  1638         -  if( pMWin->pStart ){
  1639         -    sqlite3ExprCode(pParse, pMWin->pStart, regStart);
  1640         -    windowCheckIntValue(pParse, regStart, 0);
  1641         -  }
  1642         -  if( pMWin->pEnd ){
  1643         -    sqlite3ExprCode(pParse, pMWin->pEnd, regEnd);
  1644         -    windowCheckIntValue(pParse, regEnd, 1);
  1645         -  }
  1646         -
  1647         -  /* If this is "ROWS <expr1> FOLLOWING AND ROWS <expr2> FOLLOWING", do:
  1648         -  **
  1649         -  **   if( regEnd<regStart ){
  1650         -  **     // The frame always consists of 0 rows
  1651         -  **     regStart = regSize;
  1652         -  **   }
  1653         -  **   regEnd = regEnd - regStart;
  1654         -  */
  1655         -  if( pMWin->pEnd && pMWin->eStart==TK_FOLLOWING ){
  1656         -    assert( pMWin->pStart!=0 );
  1657         -    assert( pMWin->eEnd==TK_FOLLOWING );
  1658         -    sqlite3VdbeAddOp3(v, OP_Ge, regStart, sqlite3VdbeCurrentAddr(v)+2, regEnd);
  1659         -    VdbeCoverageNeverNull(v);
  1660         -    sqlite3VdbeAddOp2(v, OP_Copy, regSize, regStart);
  1661         -    sqlite3VdbeAddOp3(v, OP_Subtract, regStart, regEnd, regEnd);
  1662         -  }
  1663         -
  1664         -  if( pMWin->pStart && pMWin->eEnd==TK_PRECEDING ){
  1665         -    assert( pMWin->pEnd!=0 );
  1666         -    assert( pMWin->eStart==TK_PRECEDING );
  1667         -    sqlite3VdbeAddOp3(v, OP_Le, regStart, sqlite3VdbeCurrentAddr(v)+3, regEnd);
  1668         -    VdbeCoverageNeverNull(v);
  1669         -    sqlite3VdbeAddOp2(v, OP_Copy, regSize, regStart);
  1670         -    sqlite3VdbeAddOp2(v, OP_Copy, regSize, regEnd);
  1671         -  }
  1672         -
  1673         -  /* Initialize the accumulator register for each window function to NULL */
  1674         -  regArg = windowInitAccum(pParse, pMWin);
  1675         -
  1676         -  sqlite3VdbeAddOp2(v, OP_Rewind, pMWin->iEphCsr, lblFlushDone);
  1677         -  VdbeCoverage(v);
  1678         -  sqlite3VdbeAddOp2(v, OP_Rewind, csrStart, lblFlushDone);
  1679         -  VdbeCoverageNeverTaken(v);
  1680         -  sqlite3VdbeChangeP5(v, 1);
  1681         -  sqlite3VdbeAddOp2(v, OP_Rewind, csrEnd, lblFlushDone);
  1682         -  VdbeCoverageNeverTaken(v);
  1683         -  sqlite3VdbeChangeP5(v, 1);
  1684         -
  1685         -  /* Invoke AggStep function for each window function using the row that
  1686         -  ** csrEnd currently points to. Or, if csrEnd is already at EOF,
  1687         -  ** do nothing.  */
  1688         -  addrTop = sqlite3VdbeCurrentAddr(v);
  1689         -  if( pMWin->eEnd==TK_PRECEDING ){
  1690         -    addrIfPos1 = sqlite3VdbeAddOp3(v, OP_IfPos, regEnd, 0 , 1);
  1691         -    VdbeCoverage(v);
  1692         -  }
  1693         -  sqlite3VdbeAddOp2(v, OP_Next, csrEnd, sqlite3VdbeCurrentAddr(v)+2);
  1694         -  VdbeCoverage(v);
  1695         -  addr = sqlite3VdbeAddOp0(v, OP_Goto);
  1696         -  windowAggStep(pParse, pMWin, csrEnd, 0, regArg, regSize);
  1697         -  if( pMWin->eEnd==TK_UNBOUNDED ){
  1698         -    sqlite3VdbeAddOp2(v, OP_Goto, 0, addrTop);
  1699         -    sqlite3VdbeJumpHere(v, addr);
  1700         -    addrTop = sqlite3VdbeCurrentAddr(v);
  1701         -  }else{
  1702         -    sqlite3VdbeJumpHere(v, addr);
  1703         -    if( pMWin->eEnd==TK_PRECEDING ){
  1704         -      sqlite3VdbeJumpHere(v, addrIfPos1);
  1705         -    }
  1706         -  }
  1707         -
  1708         -  if( pMWin->eEnd==TK_FOLLOWING ){
  1709         -    addrIfPos1 = sqlite3VdbeAddOp3(v, OP_IfPos, regEnd, 0 , 1);
  1710         -    VdbeCoverage(v);
  1711         -  }
  1712         -  if( pMWin->eStart==TK_FOLLOWING ){
  1713         -    addrIfPos2 = sqlite3VdbeAddOp3(v, OP_IfPos, regStart, 0 , 1);
  1714         -    VdbeCoverage(v);
  1715         -  }
  1716         -  windowAggFinal(pParse, pMWin, 0);
  1717         -  windowReturnOneRow(pParse, pMWin, regGosub, addrGosub);
  1718         -  sqlite3VdbeAddOp2(v, OP_Next, pMWin->iEphCsr, sqlite3VdbeCurrentAddr(v)+2);
  1719         -  VdbeCoverage(v);
  1720         -  sqlite3VdbeAddOp2(v, OP_Goto, 0, lblFlushDone);
  1721         -  if( pMWin->eStart==TK_FOLLOWING ){
  1722         -    sqlite3VdbeJumpHere(v, addrIfPos2);
  1723         -  }
  1724         -
  1725         -  if( pMWin->eStart==TK_CURRENT 
  1726         -   || pMWin->eStart==TK_PRECEDING 
  1727         -   || pMWin->eStart==TK_FOLLOWING 
  1728         -  ){
  1729         -    int lblSkipInverse = sqlite3VdbeMakeLabel(pParse);;
  1730         -    if( pMWin->eStart==TK_PRECEDING ){
  1731         -      sqlite3VdbeAddOp3(v, OP_IfPos, regStart, lblSkipInverse, 1);
  1732         -      VdbeCoverage(v);
  1733         -    }
  1734         -    if( pMWin->eStart==TK_FOLLOWING ){
  1735         -      sqlite3VdbeAddOp2(v, OP_Next, csrStart, sqlite3VdbeCurrentAddr(v)+2);
  1736         -      VdbeCoverage(v);
  1737         -      sqlite3VdbeAddOp2(v, OP_Goto, 0, lblSkipInverse);
  1738         -    }else{
  1739         -      sqlite3VdbeAddOp2(v, OP_Next, csrStart, sqlite3VdbeCurrentAddr(v)+1);
  1740         -      VdbeCoverageAlwaysTaken(v);
  1741         -    }
  1742         -    windowAggStep(pParse, pMWin, csrStart, 1, regArg, regSize);
  1743         -    sqlite3VdbeResolveLabel(v, lblSkipInverse);
  1744         -  }
  1745         -  if( pMWin->eEnd==TK_FOLLOWING ){
  1746         -    sqlite3VdbeJumpHere(v, addrIfPos1);
  1747         -  }
  1748         -  sqlite3VdbeAddOp2(v, OP_Goto, 0, addrTop);
  1749         -
  1750         -  /* flush_partition_done: */
  1751         -  sqlite3VdbeResolveLabel(v, lblFlushDone);
  1752         -  sqlite3VdbeAddOp1(v, OP_ResetSorter, pMWin->iEphCsr);
  1753         -  sqlite3VdbeAddOp1(v, OP_Return, regFlushPart);
  1754         -  VdbeComment((v, "end flush_partition subroutine"));
  1755         -
  1756         -  /* Jump to here to skip over flush_partition */
  1757         -  sqlite3VdbeJumpHere(v, addrGoto);
         1840  +  sqlite3VdbeAddOp3(v, arith, regVal, reg1, reg1);
         1841  +  sqlite3VdbeJumpHere(v, addrGe);
         1842  +  sqlite3VdbeAddOp3(v, op, reg2, lbl, reg1); VdbeCoverage(v);
         1843  +  sqlite3VdbeChangeP5(v, SQLITE_NULLEQ);
         1844  +  assert( op==OP_Ge || op==OP_Gt || op==OP_Lt || op==OP_Le );
         1845  +  testcase(op==OP_Ge); VdbeCoverageIf(v, op==OP_Ge);
         1846  +  testcase(op==OP_Lt); VdbeCoverageIf(v, op==OP_Lt);
         1847  +  testcase(op==OP_Le); VdbeCoverageIf(v, op==OP_Le);
         1848  +  testcase(op==OP_Gt); VdbeCoverageIf(v, op==OP_Gt);
         1849  +
         1850  +  sqlite3ReleaseTempReg(pParse, reg1);
         1851  +  sqlite3ReleaseTempReg(pParse, reg2);
  1758   1852   }
  1759   1853   
  1760   1854   /*
  1761         -** This function does the work of sqlite3WindowCodeStep() for cases that
  1762         -** would normally be handled by windowCodeDefaultStep() when there are
  1763         -** one or more built-in window-functions that require the entire partition
  1764         -** to be cached in a temp table before any rows can be returned. Additionally.
  1765         -** "RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING" is always handled by
  1766         -** this function.
  1767         -**
  1768         -** Pseudo-code corresponding to the VM code generated by this function
  1769         -** for each type of window follows.
  1770         -**
  1771         -** RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
  1772         -**
  1773         -**   flush_partition:
  1774         -**     Once {
  1775         -**       OpenDup (iEphCsr -> csrLead)
  1776         -**     }
  1777         -**     Integer ctr 0
  1778         -**     foreach row (csrLead){
  1779         -**       if( new peer ){
  1780         -**         AggFinal (xValue)
  1781         -**         for(i=0; i<ctr; i++){
  1782         -**           Gosub addrGosub
  1783         -**           Next iEphCsr
  1784         -**         }
  1785         -**         Integer ctr 0
  1786         -**       }
  1787         -**       AggStep (csrLead)
  1788         -**       Incr ctr
  1789         -**     }
  1790         -**
  1791         -**     AggFinal (xFinalize)
  1792         -**     for(i=0; i<ctr; i++){
  1793         -**       Gosub addrGosub
  1794         -**       Next iEphCsr
  1795         -**     }
  1796         -**
  1797         -**     ResetSorter (csr)
  1798         -**     Return
  1799         -**
  1800         -** ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
  1801         -**
  1802         -**   As above, except that the "if( new peer )" branch is always taken.
  1803         -**
  1804         -** RANGE BETWEEN CURRENT ROW AND CURRENT ROW 
  1805         -**
  1806         -**   As above, except that each of the for() loops becomes:
  1807         -**
  1808         -**         for(i=0; i<ctr; i++){
  1809         -**           Gosub addrGosub
  1810         -**           AggInverse (iEphCsr)
  1811         -**           Next iEphCsr
  1812         -**         }
  1813         -**
  1814         -** RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
  1815         -**
  1816         -**   flush_partition:
  1817         -**     Once {
  1818         -**       OpenDup (iEphCsr -> csrLead)
  1819         -**     }
  1820         -**     foreach row (csrLead) {
  1821         -**       AggStep (csrLead)
  1822         -**     }
  1823         -**     foreach row (iEphCsr) {
  1824         -**       Gosub addrGosub
  1825         -**     }
  1826         -** 
  1827         -** RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
  1828         -**
  1829         -**   flush_partition:
  1830         -**     Once {
  1831         -**       OpenDup (iEphCsr -> csrLead)
  1832         -**     }
  1833         -**     foreach row (csrLead){
  1834         -**       AggStep (csrLead)
  1835         -**     }
  1836         -**     Rewind (csrLead)
  1837         -**     Integer ctr 0
  1838         -**     foreach row (csrLead){
  1839         -**       if( new peer ){
  1840         -**         AggFinal (xValue)
  1841         -**         for(i=0; i<ctr; i++){
  1842         -**           Gosub addrGosub
  1843         -**           AggInverse (iEphCsr)
  1844         -**           Next iEphCsr
  1845         -**         }
  1846         -**         Integer ctr 0
  1847         -**       }
  1848         -**       Incr ctr
  1849         -**     }
  1850         -**
  1851         -**     AggFinal (xFinalize)
  1852         -**     for(i=0; i<ctr; i++){
  1853         -**       Gosub addrGosub
  1854         -**       Next iEphCsr
  1855         -**     }
  1856         -**
  1857         -**     ResetSorter (csr)
  1858         -**     Return
         1855  +** Helper function for sqlite3WindowCodeStep(). Each call to this function
         1856  +** generates VM code for a single RETURN_ROW, AGGSTEP or AGGINVERSE 
         1857  +** operation. Refer to the header comment for sqlite3WindowCodeStep() for
         1858  +** details.
  1859   1859   */
  1860         -static void windowCodeCacheStep(
  1861         -  Parse *pParse, 
  1862         -  Select *p,
  1863         -  WhereInfo *pWInfo,
  1864         -  int regGosub, 
  1865         -  int addrGosub
         1860  +static int windowCodeOp(
         1861  + WindowCodeArg *p,                /* Context object */
         1862  + int op,                          /* WINDOW_RETURN_ROW, AGGSTEP or AGGINVERSE */
         1863  + int regCountdown,                /* Register for OP_IfPos countdown */
         1864  + int jumpOnEof                    /* Jump here if stepped cursor reaches EOF */
  1866   1865   ){
  1867         -  Window *pMWin = p->pWin;
  1868         -  Vdbe *v = sqlite3GetVdbe(pParse);
  1869         -  int k;
  1870         -  int addr;
  1871         -  ExprList *pPart = pMWin->pPartition;
  1872         -  ExprList *pOrderBy = pMWin->pOrderBy;
  1873         -  int nPeer = pOrderBy ? pOrderBy->nExpr : 0;
  1874         -  int regNewPeer;
  1875         -
  1876         -  int addrGoto;                   /* Address of Goto used to jump flush_par.. */
  1877         -  int addrNext;                   /* Jump here for next iteration of loop */
  1878         -  int regFlushPart;
  1879         -  int lblFlushPart;
  1880         -  int csrLead;
  1881         -  int regCtr;
  1882         -  int regArg;                     /* Register array to martial function args */
  1883         -  int regSize;
  1884         -  int lblEmpty;
  1885         -  int bReverse = pMWin->pOrderBy && pMWin->eStart==TK_CURRENT 
  1886         -          && pMWin->eEnd==TK_UNBOUNDED;
  1887         -
  1888         -  assert( (pMWin->eStart==TK_UNBOUNDED && pMWin->eEnd==TK_CURRENT) 
  1889         -       || (pMWin->eStart==TK_UNBOUNDED && pMWin->eEnd==TK_UNBOUNDED) 
  1890         -       || (pMWin->eStart==TK_CURRENT && pMWin->eEnd==TK_CURRENT) 
  1891         -       || (pMWin->eStart==TK_CURRENT && pMWin->eEnd==TK_UNBOUNDED) 
         1866  +  int csr, reg;
         1867  +  Parse *pParse = p->pParse;
         1868  +  Window *pMWin = p->pMWin;
         1869  +  int ret = 0;
         1870  +  Vdbe *v = p->pVdbe;
         1871  +  int addrIf = 0; 
         1872  +  int addrContinue = 0;
         1873  +  int addrGoto = 0;
         1874  +  int bPeer = (pMWin->eFrmType!=TK_ROWS);
         1875  +
         1876  +  int lblDone = sqlite3VdbeMakeLabel(pParse);
         1877  +  int addrNextRange = 0;
         1878  +
         1879  +  /* Special case - WINDOW_AGGINVERSE is always a no-op if the frame
         1880  +  ** starts with UNBOUNDED PRECEDING. */
         1881  +  if( op==WINDOW_AGGINVERSE && pMWin->eStart==TK_UNBOUNDED ){
         1882  +    assert( regCountdown==0 && jumpOnEof==0 );
         1883  +    return 0;
         1884  +  }
         1885  +
         1886  +  if( regCountdown>0 ){
         1887  +    if( pMWin->eFrmType==TK_RANGE ){
         1888  +      addrNextRange = sqlite3VdbeCurrentAddr(v);
         1889  +      assert( op==WINDOW_AGGINVERSE || op==WINDOW_AGGSTEP );
         1890  +      if( op==WINDOW_AGGINVERSE ){
         1891  +        if( pMWin->eStart==TK_FOLLOWING ){
         1892  +          windowCodeRangeTest(
         1893  +              p, OP_Le, p->current.csr, regCountdown, p->start.csr, lblDone
         1894  +          );
         1895  +        }else{
         1896  +          windowCodeRangeTest(
         1897  +              p, OP_Ge, p->start.csr, regCountdown, p->current.csr, lblDone
         1898  +          );
         1899  +        }
         1900  +      }else{
         1901  +        windowCodeRangeTest(
         1902  +            p, OP_Gt, p->end.csr, regCountdown, p->current.csr, lblDone
  1892   1903     );
  1893         -
  1894         -  lblEmpty = sqlite3VdbeMakeLabel(pParse);
  1895         -  regNewPeer = pParse->nMem+1;
  1896         -  pParse->nMem += nPeer;
  1897         -
  1898         -  /* Allocate register and label for the "flush_partition" sub-routine. */
  1899         -  regFlushPart = ++pParse->nMem;
  1900         -  lblFlushPart = sqlite3VdbeMakeLabel(pParse);
  1901         -
  1902         -  csrLead = pParse->nTab++;
  1903         -  regCtr = ++pParse->nMem;
  1904         -
  1905         -  windowPartitionCache(pParse, p, pWInfo, regFlushPart, lblFlushPart, &regSize);
  1906         -  addrGoto = sqlite3VdbeAddOp0(v, OP_Goto);
  1907         -
  1908         -  /* Start of "flush_partition" */
  1909         -  sqlite3VdbeResolveLabel(v, lblFlushPart);
  1910         -  sqlite3VdbeAddOp2(v, OP_Once, 0, sqlite3VdbeCurrentAddr(v)+2);
         1904  +      }
         1905  +    }else{
         1906  +      addrIf = sqlite3VdbeAddOp3(v, OP_IfPos, regCountdown, 0, 1);
         1907  +      VdbeCoverage(v);
         1908  +    }
         1909  +  }
         1910  +
         1911  +  if( op==WINDOW_RETURN_ROW && pMWin->regStartRowid==0 ){
         1912  +    windowAggFinal(p, 0);
         1913  +  }
         1914  +  addrContinue = sqlite3VdbeCurrentAddr(v);
         1915  +  switch( op ){
         1916  +    case WINDOW_RETURN_ROW:
         1917  +      csr = p->current.csr;
         1918  +      reg = p->current.reg;
         1919  +      windowReturnOneRow(p);
         1920  +      break;
         1921  +
         1922  +    case WINDOW_AGGINVERSE:
         1923  +      csr = p->start.csr;
         1924  +      reg = p->start.reg;
         1925  +      if( pMWin->regStartRowid ){
         1926  +        assert( pMWin->regEndRowid );
         1927  +        sqlite3VdbeAddOp2(v, OP_AddImm, pMWin->regStartRowid, 1);
         1928  +      }else{
         1929  +        windowAggStep(pParse, pMWin, csr, 1, p->regArg);
         1930  +      }
         1931  +      break;
         1932  +
         1933  +    default:
         1934  +      assert( op==WINDOW_AGGSTEP );
         1935  +      csr = p->end.csr;
         1936  +      reg = p->end.reg;
         1937  +      if( pMWin->regStartRowid ){
         1938  +        assert( pMWin->regEndRowid );
         1939  +        sqlite3VdbeAddOp2(v, OP_AddImm, pMWin->regEndRowid, 1);
         1940  +      }else{
         1941  +        windowAggStep(pParse, pMWin, csr, 0, p->regArg);
         1942  +      }
         1943  +      break;
         1944  +  }
         1945  +
         1946  +  if( op==p->eDelete ){
         1947  +    sqlite3VdbeAddOp1(v, OP_Delete, csr);
         1948  +    sqlite3VdbeChangeP5(v, OPFLAG_SAVEPOSITION);
         1949  +  }
         1950  +
         1951  +  if( jumpOnEof ){
         1952  +    sqlite3VdbeAddOp2(v, OP_Next, csr, sqlite3VdbeCurrentAddr(v)+2);
         1953  +    VdbeCoverage(v);
         1954  +    ret = sqlite3VdbeAddOp0(v, OP_Goto);
         1955  +  }else{
         1956  +    sqlite3VdbeAddOp2(v, OP_Next, csr, sqlite3VdbeCurrentAddr(v)+1+bPeer);
  1911   1957     VdbeCoverage(v);
  1912         -  sqlite3VdbeAddOp2(v, OP_OpenDup, csrLead, pMWin->iEphCsr);
  1913         -
  1914         -  /* Initialize the accumulator register for each window function to NULL */
  1915         -  regArg = windowInitAccum(pParse, pMWin);
  1916         -
  1917         -  sqlite3VdbeAddOp2(v, OP_Integer, 0, regCtr);
  1918         -  sqlite3VdbeAddOp2(v, OP_Rewind, csrLead, lblEmpty);
  1919         -  VdbeCoverage(v);
  1920         -  sqlite3VdbeAddOp2(v, OP_Rewind, pMWin->iEphCsr, lblEmpty);
  1921         -  VdbeCoverageNeverTaken(v);
  1922         -
  1923         -  if( bReverse ){
  1924         -    int addr2 = sqlite3VdbeCurrentAddr(v);
  1925         -    windowAggStep(pParse, pMWin, csrLead, 0, regArg, regSize);
  1926         -    sqlite3VdbeAddOp2(v, OP_Next, csrLead, addr2);
  1927         -    VdbeCoverage(v);
  1928         -    sqlite3VdbeAddOp2(v, OP_Rewind, csrLead, lblEmpty);
  1929         -    VdbeCoverageNeverTaken(v);
  1930         -  }
  1931         -  addrNext = sqlite3VdbeCurrentAddr(v);
  1932         -
  1933         -  if( pOrderBy && (pMWin->eEnd==TK_CURRENT || pMWin->eStart==TK_CURRENT) ){
  1934         -    int bCurrent = (pMWin->eStart==TK_CURRENT);
  1935         -    int addrJump = 0;             /* Address of OP_Jump below */
  1936         -    if( pMWin->eType==TK_RANGE ){
  1937         -      int iOff = pMWin->nBufferCol + (pPart ? pPart->nExpr : 0);
  1938         -      int regPeer = pMWin->regPart + (pPart ? pPart->nExpr : 0);
  1939         -      KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pOrderBy, 0, 0);
  1940         -      for(k=0; k<nPeer; k++){
  1941         -        sqlite3VdbeAddOp3(v, OP_Column, csrLead, iOff+k, regNewPeer+k);
  1942         -      }
  1943         -      addr = sqlite3VdbeAddOp3(v, OP_Compare, regNewPeer, regPeer, nPeer);
  1944         -      sqlite3VdbeAppendP4(v, (void*)pKeyInfo, P4_KEYINFO);
  1945         -      addrJump = sqlite3VdbeAddOp3(v, OP_Jump, addr+2, 0, addr+2);
  1946         -      VdbeCoverage(v);
  1947         -      sqlite3VdbeAddOp3(v, OP_Copy, regNewPeer, regPeer, nPeer-1);
  1948         -    }
  1949         -
  1950         -    windowReturnRows(pParse, pMWin, regCtr, regGosub, addrGosub, 
  1951         -        (bCurrent ? regArg : 0), (bCurrent ? regSize : 0)
  1952         -    );
  1953         -    if( addrJump ) sqlite3VdbeJumpHere(v, addrJump);
  1954         -  }
  1955         -
  1956         -  if( bReverse==0 ){
  1957         -    windowAggStep(pParse, pMWin, csrLead, 0, regArg, regSize);
  1958         -  }
  1959         -  sqlite3VdbeAddOp2(v, OP_AddImm, regCtr, 1);
  1960         -  sqlite3VdbeAddOp2(v, OP_Next, csrLead, addrNext);
  1961         -  VdbeCoverage(v);
  1962         -
  1963         -  windowReturnRows(pParse, pMWin, regCtr, regGosub, addrGosub, 0, 0);
  1964         -
  1965         -  sqlite3VdbeResolveLabel(v, lblEmpty);
  1966         -  sqlite3VdbeAddOp1(v, OP_ResetSorter, pMWin->iEphCsr);
  1967         -  sqlite3VdbeAddOp1(v, OP_Return, regFlushPart);
  1968         -
  1969         -  /* Jump to here to skip over flush_partition */
  1970         -  sqlite3VdbeJumpHere(v, addrGoto);
  1971         -}
  1972         -
  1973         -
  1974         -/*
  1975         -** RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
  1976         -**
  1977         -**   ...
  1978         -**     if( new partition ){
  1979         -**       AggFinal (xFinalize)
  1980         -**       Gosub addrGosub
  1981         -**       ResetSorter eph-table
  1982         -**     }
  1983         -**     else if( new peer ){
  1984         -**       AggFinal (xValue)
  1985         -**       Gosub addrGosub
  1986         -**       ResetSorter eph-table
  1987         -**     }
  1988         -**     AggStep
  1989         -**     Insert (record into eph-table)
  1990         -**   sqlite3WhereEnd()
  1991         -**   AggFinal (xFinalize)
  1992         -**   Gosub addrGosub
  1993         -**
  1994         -** RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
  1995         -**
  1996         -**   As above, except take no action for a "new peer". Invoke
  1997         -**   the sub-routine once only for each partition.
  1998         -**
  1999         -** RANGE BETWEEN CURRENT ROW AND CURRENT ROW
  2000         -**
  2001         -**   As above, except that the "new peer" condition is handled in the
  2002         -**   same way as "new partition" (so there is no "else if" block).
  2003         -**
  2004         -** ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
  2005         -** 
  2006         -**   As above, except assume every row is a "new peer".
  2007         -*/
  2008         -static void windowCodeDefaultStep(
  2009         -  Parse *pParse, 
  2010         -  Select *p,
  2011         -  WhereInfo *pWInfo,
  2012         -  int regGosub, 
  2013         -  int addrGosub
  2014         -){
  2015         -  Window *pMWin = p->pWin;
  2016         -  Vdbe *v = sqlite3GetVdbe(pParse);
  2017         -  int k;
  2018         -  int iSubCsr = p->pSrc->a[0].iCursor;
  2019         -  int nSub = p->pSrc->a[0].pTab->nCol;
  2020         -  int reg = pParse->nMem+1;
  2021         -  int regRecord = reg+nSub;
  2022         -  int regRowid = regRecord+1;
  2023         -  int addr;
  2024         -  ExprList *pPart = pMWin->pPartition;
  2025         -  ExprList *pOrderBy = pMWin->pOrderBy;
  2026         -
  2027         -  assert( pMWin->eType==TK_RANGE 
  2028         -      || (pMWin->eStart==TK_UNBOUNDED && pMWin->eEnd==TK_CURRENT)
  2029         -  );
  2030         -
  2031         -  assert( (pMWin->eStart==TK_UNBOUNDED && pMWin->eEnd==TK_CURRENT)
  2032         -       || (pMWin->eStart==TK_UNBOUNDED && pMWin->eEnd==TK_UNBOUNDED)
  2033         -       || (pMWin->eStart==TK_CURRENT && pMWin->eEnd==TK_CURRENT)
  2034         -       || (pMWin->eStart==TK_CURRENT && pMWin->eEnd==TK_UNBOUNDED && !pOrderBy)
  2035         -  );
  2036         -
  2037         -  if( pMWin->eEnd==TK_UNBOUNDED ){
  2038         -    pOrderBy = 0;
  2039         -  }
  2040         -
  2041         -  pParse->nMem += nSub + 2;
  2042         -
  2043         -  /* Load the individual column values of the row returned by
  2044         -  ** the sub-select into an array of registers. */
  2045         -  for(k=0; k<nSub; k++){
  2046         -    sqlite3VdbeAddOp3(v, OP_Column, iSubCsr, k, reg+k);
  2047         -  }
  2048         -
  2049         -  /* Check if this is the start of a new partition or peer group. */
  2050         -  if( pPart || pOrderBy ){
  2051         -    int nPart = (pPart ? pPart->nExpr : 0);
  2052         -    int addrGoto = 0;
  2053         -    int addrJump = 0;
  2054         -    int nPeer = (pOrderBy ? pOrderBy->nExpr : 0);
  2055         -
  2056         -    if( pPart ){
  2057         -      int regNewPart = reg + pMWin->nBufferCol;
  2058         -      KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pPart, 0, 0);
  2059         -      addr = sqlite3VdbeAddOp3(v, OP_Compare, regNewPart, pMWin->regPart,nPart);
  2060         -      sqlite3VdbeAppendP4(v, (void*)pKeyInfo, P4_KEYINFO);
  2061         -      addrJump = sqlite3VdbeAddOp3(v, OP_Jump, addr+2, 0, addr+2);
  2062         -      VdbeCoverageEqNe(v);
  2063         -      windowAggFinal(pParse, pMWin, 1);
  2064         -      if( pOrderBy ){
         1958  +    if( bPeer ){
  2065   1959           addrGoto = sqlite3VdbeAddOp0(v, OP_Goto);
  2066   1960         }
  2067   1961       }
  2068   1962   
  2069         -    if( pOrderBy ){
  2070         -      int regNewPeer = reg + pMWin->nBufferCol + nPart;
  2071         -      int regPeer = pMWin->regPart + nPart;
         1963  +  if( bPeer ){
         1964  +    int nReg = (pMWin->pOrderBy ? pMWin->pOrderBy->nExpr : 0);
         1965  +    int regTmp = (nReg ? sqlite3GetTempRange(pParse, nReg) : 0);
         1966  +    windowReadPeerValues(p, csr, regTmp);
         1967  +    windowIfNewPeer(pParse, pMWin->pOrderBy, regTmp, reg, addrContinue);
         1968  +    sqlite3ReleaseTempRange(pParse, regTmp, nReg);
         1969  +  }
  2072   1970   
  2073         -      if( addrJump ) sqlite3VdbeJumpHere(v, addrJump);
  2074         -      if( pMWin->eType==TK_RANGE ){
  2075         -        KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pOrderBy, 0, 0);
  2076         -        addr = sqlite3VdbeAddOp3(v, OP_Compare, regNewPeer, regPeer, nPeer);
  2077         -        sqlite3VdbeAppendP4(v, (void*)pKeyInfo, P4_KEYINFO);
  2078         -        addrJump = sqlite3VdbeAddOp3(v, OP_Jump, addr+2, 0, addr+2);
  2079         -        VdbeCoverage(v);
  2080         -      }else{
  2081         -        addrJump = 0;
         1971  +  if( addrNextRange ){
         1972  +    sqlite3VdbeAddOp2(v, OP_Goto, 0, addrNextRange);
  2082   1973         }
  2083         -      windowAggFinal(pParse, pMWin, pMWin->eStart==TK_CURRENT);
         1974  +  sqlite3VdbeResolveLabel(v, lblDone);
  2084   1975         if( addrGoto ) sqlite3VdbeJumpHere(v, addrGoto);
         1976  +  if( addrIf ) sqlite3VdbeJumpHere(v, addrIf);
         1977  +  return ret;
  2085   1978       }
  2086   1979   
  2087         -    sqlite3VdbeAddOp2(v, OP_Rewind, pMWin->iEphCsr,sqlite3VdbeCurrentAddr(v)+3);
  2088         -    VdbeCoverage(v);
  2089         -    sqlite3VdbeAddOp2(v, OP_Gosub, regGosub, addrGosub);
  2090         -    sqlite3VdbeAddOp2(v, OP_Next, pMWin->iEphCsr, sqlite3VdbeCurrentAddr(v)-1);
  2091         -    VdbeCoverage(v);
  2092         -
  2093         -    sqlite3VdbeAddOp1(v, OP_ResetSorter, pMWin->iEphCsr);
  2094         -    sqlite3VdbeAddOp3(
  2095         -        v, OP_Copy, reg+pMWin->nBufferCol, pMWin->regPart, nPart+nPeer-1
  2096         -    );
  2097         -
  2098         -    if( addrJump ) sqlite3VdbeJumpHere(v, addrJump);
  2099         -  }
  2100         -
  2101         -  /* Invoke step function for window functions */
  2102         -  windowAggStep(pParse, pMWin, -1, 0, reg, 0);
  2103         -
  2104         -  /* Buffer the current row in the ephemeral table. */
  2105         -  if( pMWin->nBufferCol>0 ){
  2106         -    sqlite3VdbeAddOp3(v, OP_MakeRecord, reg, pMWin->nBufferCol, regRecord);
  2107         -  }else{
  2108         -    sqlite3VdbeAddOp2(v, OP_Blob, 0, regRecord);
  2109         -    sqlite3VdbeAppendP4(v, (void*)"", 0);
  2110         -  }
  2111         -  sqlite3VdbeAddOp2(v, OP_NewRowid, pMWin->iEphCsr, regRowid);
  2112         -  sqlite3VdbeAddOp3(v, OP_Insert, pMWin->iEphCsr, regRecord, regRowid);
  2113         -
  2114         -  /* End the database scan loop. */
  2115         -  sqlite3WhereEnd(pWInfo);
  2116         -
  2117         -  windowAggFinal(pParse, pMWin, 1);
  2118         -  sqlite3VdbeAddOp2(v, OP_Rewind, pMWin->iEphCsr,sqlite3VdbeCurrentAddr(v)+3);
  2119         -  VdbeCoverage(v);
  2120         -  sqlite3VdbeAddOp2(v, OP_Gosub, regGosub, addrGosub);
  2121         -  sqlite3VdbeAddOp2(v, OP_Next, pMWin->iEphCsr, sqlite3VdbeCurrentAddr(v)-1);
  2122         -  VdbeCoverage(v);
  2123         -}
  2124   1980   
  2125   1981   /*
  2126   1982   ** Allocate and return a duplicate of the Window object indicated by the
  2127   1983   ** third argument. Set the Window.pOwner field of the new object to
  2128   1984   ** pOwner.
  2129   1985   */
  2130   1986   Window *sqlite3WindowDup(sqlite3 *db, Expr *pOwner, Window *p){
................................................................................
  2133   1989       pNew = sqlite3DbMallocZero(db, sizeof(Window));
  2134   1990       if( pNew ){
  2135   1991         pNew->zName = sqlite3DbStrDup(db, p->zName);
  2136   1992         pNew->pFilter = sqlite3ExprDup(db, p->pFilter, 0);
  2137   1993         pNew->pFunc = p->pFunc;
  2138   1994         pNew->pPartition = sqlite3ExprListDup(db, p->pPartition, 0);
  2139   1995         pNew->pOrderBy = sqlite3ExprListDup(db, p->pOrderBy, 0);
  2140         -      pNew->eType = p->eType;
         1996  +      pNew->eFrmType = p->eFrmType;
  2141   1997         pNew->eEnd = p->eEnd;
  2142   1998         pNew->eStart = p->eStart;
         1999  +      pNew->eExclude = p->eExclude;
  2143   2000         pNew->pStart = sqlite3ExprDup(db, p->pStart, 0);
  2144   2001         pNew->pEnd = sqlite3ExprDup(db, p->pEnd, 0);
  2145   2002         pNew->pOwner = pOwner;
  2146   2003       }
  2147   2004     }
  2148   2005     return pNew;
  2149   2006   }
................................................................................
  2161   2018       *pp = sqlite3WindowDup(db, 0, pWin);
  2162   2019       if( *pp==0 ) break;
  2163   2020       pp = &((*pp)->pNextWin);
  2164   2021     }
  2165   2022   
  2166   2023     return pRet;
  2167   2024   }
         2025  +
         2026  +/*
         2027  +** Return true if it can be determined at compile time that expression 
         2028  +** pExpr evaluates to a value that, when cast to an integer, is greater 
         2029  +** than zero. False otherwise.
         2030  +**
         2031  +** If an OOM error occurs, this function sets the Parse.db.mallocFailed 
         2032  +** flag and returns zero.
         2033  +*/
         2034  +static int windowExprGtZero(Parse *pParse, Expr *pExpr){
         2035  +  int ret = 0;
         2036  +  sqlite3 *db = pParse->db;
         2037  +  sqlite3_value *pVal = 0;
         2038  +  sqlite3ValueFromExpr(db, pExpr, db->enc, SQLITE_AFF_NUMERIC, &pVal);
         2039  +  if( pVal && sqlite3_value_int(pVal)>0 ){
         2040  +    ret = 1;
         2041  +  }
         2042  +  sqlite3ValueFree(pVal);
         2043  +  return ret;
         2044  +}
  2168   2045   
  2169   2046   /*
  2170   2047   ** sqlite3WhereBegin() has already been called for the SELECT statement 
  2171   2048   ** passed as the second argument when this function is invoked. It generates
  2172         -** code to populate the Window.regResult register for each window function and
  2173         -** invoke the sub-routine at instruction addrGosub once for each row.
  2174         -** This function calls sqlite3WhereEnd() before returning. 
         2049  +** code to populate the Window.regResult register for each window function 
         2050  +** and invoke the sub-routine at instruction addrGosub once for each row.
         2051  +** sqlite3WhereEnd() is always called before returning. 
         2052  +**
         2053  +** This function handles several different types of window frames, which
         2054  +** require slightly different processing. The following pseudo code is
         2055  +** used to implement window frames of the form:
         2056  +**
         2057  +**   ROWS BETWEEN <expr1> PRECEDING AND <expr2> FOLLOWING
         2058  +**
         2059  +** Other window frame types use variants of the following:
         2060  +**
         2061  +**     ... loop started by sqlite3WhereBegin() ...
         2062  +**       if( new partition ){
         2063  +**         Gosub flush
         2064  +**       }
         2065  +**       Insert new row into eph table.
         2066  +**       
         2067  +**       if( first row of partition ){
         2068  +**         // Rewind three cursors, all open on the eph table.
         2069  +**         Rewind(csrEnd);
         2070  +**         Rewind(csrStart);
         2071  +**         Rewind(csrCurrent);
         2072  +**       
         2073  +**         regEnd = <expr2>          // FOLLOWING expression
         2074  +**         regStart = <expr1>        // PRECEDING expression
         2075  +**       }else{
         2076  +**         // First time this branch is taken, the eph table contains two 
         2077  +**         // rows. The first row in the partition, which all three cursors
         2078  +**         // currently point to, and the following row.
         2079  +**         AGGSTEP
         2080  +**         if( (regEnd--)<=0 ){
         2081  +**           RETURN_ROW
         2082  +**           if( (regStart--)<=0 ){
         2083  +**             AGGINVERSE
         2084  +**           }
         2085  +**         }
         2086  +**       }
         2087  +**     }
         2088  +**     flush:
         2089  +**       AGGSTEP
         2090  +**       while( 1 ){
         2091  +**         RETURN ROW
         2092  +**         if( csrCurrent is EOF ) break;
         2093  +**         if( (regStart--)<=0 ){
         2094  +**           AggInverse(csrStart)
         2095  +**           Next(csrStart)
         2096  +**         }
         2097  +**       }
         2098  +**
         2099  +** The pseudo-code above uses the following shorthand:
         2100  +**
         2101  +**   AGGSTEP:    invoke the aggregate xStep() function for each window function
         2102  +**               with arguments read from the current row of cursor csrEnd, then
         2103  +**               step cursor csrEnd forward one row (i.e. sqlite3BtreeNext()).
         2104  +**
         2105  +**   RETURN_ROW: return a row to the caller based on the contents of the 
         2106  +**               current row of csrCurrent and the current state of all 
         2107  +**               aggregates. Then step cursor csrCurrent forward one row.
         2108  +**
         2109  +**   AGGINVERSE: invoke the aggregate xInverse() function for each window 
         2110  +**               functions with arguments read from the current row of cursor
         2111  +**               csrStart. Then step csrStart forward one row.
         2112  +**
         2113  +** There are two other ROWS window frames that are handled significantly
         2114  +** differently from the above - "BETWEEN <expr> PRECEDING AND <expr> PRECEDING"
         2115  +** and "BETWEEN <expr> FOLLOWING AND <expr> FOLLOWING". These are special 
         2116  +** cases because they change the order in which the three cursors (csrStart,
         2117  +** csrCurrent and csrEnd) iterate through the ephemeral table. Cases that
         2118  +** use UNBOUNDED or CURRENT ROW are much simpler variations on one of these
         2119  +** three.
         2120  +**
         2121  +**   ROWS BETWEEN <expr1> PRECEDING AND <expr2> PRECEDING
         2122  +**
         2123  +**     ... loop started by sqlite3WhereBegin() ...
         2124  +**       if( new partition ){
         2125  +**         Gosub flush
         2126  +**       }
         2127  +**       Insert new row into eph table.
         2128  +**       if( first row of partition ){
         2129  +**         Rewind(csrEnd) ; Rewind(csrStart) ; Rewind(csrCurrent)
         2130  +**         regEnd = <expr2>
         2131  +**         regStart = <expr1>
         2132  +**       }else{
         2133  +**         if( (regEnd--)<=0 ){
         2134  +**           AGGSTEP
         2135  +**         }
         2136  +**         RETURN_ROW
         2137  +**         if( (regStart--)<=0 ){
         2138  +**           AGGINVERSE
         2139  +**         }
         2140  +**       }
         2141  +**     }
         2142  +**     flush:
         2143  +**       if( (regEnd--)<=0 ){
         2144  +**         AGGSTEP
         2145  +**       }
         2146  +**       RETURN_ROW
         2147  +**
         2148  +**
         2149  +**   ROWS BETWEEN <expr1> FOLLOWING AND <expr2> FOLLOWING
         2150  +**
         2151  +**     ... loop started by sqlite3WhereBegin() ...
         2152  +**     if( new partition ){
         2153  +**       Gosub flush
         2154  +**     }
         2155  +**     Insert new row into eph table.
         2156  +**     if( first row of partition ){
         2157  +**       Rewind(csrEnd) ; Rewind(csrStart) ; Rewind(csrCurrent)
         2158  +**       regEnd = <expr2>
         2159  +**       regStart = regEnd - <expr1>
         2160  +**     }else{
         2161  +**       AGGSTEP
         2162  +**       if( (regEnd--)<=0 ){
         2163  +**         RETURN_ROW
         2164  +**       }
         2165  +**       if( (regStart--)<=0 ){
         2166  +**         AGGINVERSE
         2167  +**       }
         2168  +**     }
         2169  +**   }
         2170  +**   flush:
         2171  +**     AGGSTEP
         2172  +**     while( 1 ){
         2173  +**       if( (regEnd--)<=0 ){
         2174  +**         RETURN_ROW
         2175  +**         if( eof ) break;
         2176  +**       }
         2177  +**       if( (regStart--)<=0 ){
         2178  +**         AGGINVERSE
         2179  +**         if( eof ) break
         2180  +**       }
         2181  +**     }
         2182  +**     while( !eof csrCurrent ){
         2183  +**       RETURN_ROW
         2184  +**     }
         2185  +**
         2186  +** For the most part, the patterns above are adapted to support UNBOUNDED by
         2187  +** assuming that it is equivalent to "infinity PRECEDING/FOLLOWING" and
         2188  +** CURRENT ROW by assuming that it is equivilent to "0 PRECEDING/FOLLOWING".
         2189  +** This is optimized of course - branches that will never be taken and
         2190  +** conditions that are always true are omitted from the VM code. The only
         2191  +** exceptional case is:
         2192  +**
         2193  +**   ROWS BETWEEN <expr1> FOLLOWING AND UNBOUNDED FOLLOWING
         2194  +**
         2195  +**     ... loop started by sqlite3WhereBegin() ...
         2196  +**     if( new partition ){
         2197  +**       Gosub flush
         2198  +**     }
         2199  +**     Insert new row into eph table.
         2200  +**     if( first row of partition ){
         2201  +**       Rewind(csrEnd) ; Rewind(csrStart) ; Rewind(csrCurrent)
         2202  +**       regStart = <expr1>
         2203  +**     }else{
         2204  +**       AGGSTEP
         2205  +**     }
         2206  +**   }
         2207  +**   flush:
         2208  +**     AGGSTEP
         2209  +**     while( 1 ){
         2210  +**       if( (regStart--)<=0 ){
         2211  +**         AGGINVERSE
         2212  +**         if( eof ) break
         2213  +**       }
         2214  +**       RETURN_ROW
         2215  +**     }
         2216  +**     while( !eof csrCurrent ){
         2217  +**       RETURN_ROW
         2218  +**     }
         2219  +**
         2220  +** Also requiring special handling are the cases:
         2221  +**
         2222  +**   ROWS BETWEEN <expr1> PRECEDING AND <expr2> PRECEDING
         2223  +**   ROWS BETWEEN <expr1> FOLLOWING AND <expr2> FOLLOWING
         2224  +**
         2225  +** when (expr1 < expr2). This is detected at runtime, not by this function.
         2226  +** To handle this case, the pseudo-code programs depicted above are modified
         2227  +** slightly to be:
         2228  +**
         2229  +**     ... loop started by sqlite3WhereBegin() ...
         2230  +**     if( new partition ){
         2231  +**       Gosub flush
         2232  +**     }
         2233  +**     Insert new row into eph table.
         2234  +**     if( first row of partition ){
         2235  +**       Rewind(csrEnd) ; Rewind(csrStart) ; Rewind(csrCurrent)
         2236  +**       regEnd = <expr2>
         2237  +**       regStart = <expr1>
         2238  +**       if( regEnd < regStart ){
         2239  +**         RETURN_ROW
         2240  +**         delete eph table contents
         2241  +**         continue
         2242  +**       }
         2243  +**     ...
         2244  +**
         2245  +** The new "continue" statement in the above jumps to the next iteration
         2246  +** of the outer loop - the one started by sqlite3WhereBegin().
         2247  +**
         2248  +** The various GROUPS cases are implemented using the same patterns as
         2249  +** ROWS. The VM code is modified slightly so that:
         2250  +**
         2251  +**   1. The else branch in the main loop is only taken if the row just
         2252  +**      added to the ephemeral table is the start of a new group. In
         2253  +**      other words, it becomes:
         2254  +**
         2255  +**         ... loop started by sqlite3WhereBegin() ...
         2256  +**         if( new partition ){
         2257  +**           Gosub flush
         2258  +**         }
         2259  +**         Insert new row into eph table.
         2260  +**         if( first row of partition ){
         2261  +**           Rewind(csrEnd) ; Rewind(csrStart) ; Rewind(csrCurrent)
         2262  +**           regEnd = <expr2>
         2263  +**           regStart = <expr1>
         2264  +**         }else if( new group ){
         2265  +**           ... 
         2266  +**         }
         2267  +**       }
         2268  +**
         2269  +**   2. Instead of processing a single row, each RETURN_ROW, AGGSTEP or 
         2270  +**      AGGINVERSE step processes the current row of the relevant cursor and
         2271  +**      all subsequent rows belonging to the same group.
         2272  +**
         2273  +** RANGE window frames are a little different again. As for GROUPS, the 
         2274  +** main loop runs once per group only. And RETURN_ROW, AGGSTEP and AGGINVERSE
         2275  +** deal in groups instead of rows. As for ROWS and GROUPS, there are three
         2276  +** basic cases:
         2277  +**
         2278  +**   RANGE BETWEEN <expr1> PRECEDING AND <expr2> FOLLOWING
         2279  +**
         2280  +**     ... loop started by sqlite3WhereBegin() ...
         2281  +**       if( new partition ){
         2282  +**         Gosub flush
         2283  +**       }
         2284  +**       Insert new row into eph table.
         2285  +**       if( first row of partition ){
         2286  +**         Rewind(csrEnd) ; Rewind(csrStart) ; Rewind(csrCurrent)
         2287  +**         regEnd = <expr2>
         2288  +**         regStart = <expr1>
         2289  +**       }else{
         2290  +**         AGGSTEP
         2291  +**         while( (csrCurrent.key + regEnd) < csrEnd.key ){
         2292  +**           RETURN_ROW
         2293  +**           while( csrStart.key + regStart) < csrCurrent.key ){
         2294  +**             AGGINVERSE
         2295  +**           }
         2296  +**         }
         2297  +**       }
         2298  +**     }
         2299  +**     flush:
         2300  +**       AGGSTEP
         2301  +**       while( 1 ){
         2302  +**         RETURN ROW
         2303  +**         if( csrCurrent is EOF ) break;
         2304  +**           while( csrStart.key + regStart) < csrCurrent.key ){
         2305  +**             AGGINVERSE
         2306  +**           }
         2307  +**         }
         2308  +**       }
         2309  +**
         2310  +** In the above notation, "csr.key" means the current value of the ORDER BY 
         2311  +** expression (there is only ever 1 for a RANGE that uses an <expr> FOLLOWING
         2312  +** or <expr PRECEDING) read from cursor csr.
         2313  +**
         2314  +**   RANGE BETWEEN <expr1> PRECEDING AND <expr2> PRECEDING
         2315  +**
         2316  +**     ... loop started by sqlite3WhereBegin() ...
         2317  +**       if( new partition ){
         2318  +**         Gosub flush
         2319  +**       }
         2320  +**       Insert new row into eph table.
         2321  +**       if( first row of partition ){
         2322  +**         Rewind(csrEnd) ; Rewind(csrStart) ; Rewind(csrCurrent)
         2323  +**         regEnd = <expr2>
         2324  +**         regStart = <expr1>
         2325  +**       }else{
         2326  +**         if( (csrEnd.key + regEnd) <= csrCurrent.key ){
         2327  +**           AGGSTEP
         2328  +**         }
         2329  +**         while( (csrStart.key + regStart) < csrCurrent.key ){
         2330  +**           AGGINVERSE
         2331  +**         }
         2332  +**         RETURN_ROW
         2333  +**       }
         2334  +**     }
         2335  +**     flush:
         2336  +**       while( (csrEnd.key + regEnd) <= csrCurrent.key ){
         2337  +**         AGGSTEP
         2338  +**       }
         2339  +**       while( (csrStart.key + regStart) < csrCurrent.key ){
         2340  +**         AGGINVERSE
         2341  +**       }
         2342  +**       RETURN_ROW
         2343  +**
         2344  +**   RANGE BETWEEN <expr1> FOLLOWING AND <expr2> FOLLOWING
         2345  +**
         2346  +**     ... loop started by sqlite3WhereBegin() ...
         2347  +**       if( new partition ){
         2348  +**         Gosub flush
         2349  +**       }
         2350  +**       Insert new row into eph table.
         2351  +**       if( first row of partition ){
         2352  +**         Rewind(csrEnd) ; Rewind(csrStart) ; Rewind(csrCurrent)
         2353  +**         regEnd = <expr2>
         2354  +**         regStart = <expr1>
         2355  +**       }else{
         2356  +**         AGGSTEP
         2357  +**         while( (csrCurrent.key + regEnd) < csrEnd.key ){
         2358  +**           while( (csrCurrent.key + regStart) > csrStart.key ){
         2359  +**             AGGINVERSE
         2360  +**           }
         2361  +**           RETURN_ROW
         2362  +**         }
         2363  +**       }
         2364  +**     }
         2365  +**     flush:
         2366  +**       AGGSTEP
         2367  +**       while( 1 ){
         2368  +**         while( (csrCurrent.key + regStart) > csrStart.key ){
         2369  +**           AGGINVERSE
         2370  +**           if( eof ) break "while( 1 )" loop.
         2371  +**         }
         2372  +**         RETURN_ROW
         2373  +**       }
         2374  +**       while( !eof csrCurrent ){
         2375  +**         RETURN_ROW
         2376  +**       }
         2377  +**
         2378  +** The text above leaves out many details. Refer to the code and comments
         2379  +** below for a more complete picture.
  2175   2380   */
  2176   2381   void sqlite3WindowCodeStep(
  2177   2382     Parse *pParse,                  /* Parse context */
  2178   2383     Select *p,                      /* Rewritten SELECT statement */
  2179   2384     WhereInfo *pWInfo,              /* Context returned by sqlite3WhereBegin() */
  2180   2385     int regGosub,                   /* Register for OP_Gosub */
  2181   2386     int addrGosub                   /* OP_Gosub here to return each row */
  2182   2387   ){
  2183   2388     Window *pMWin = p->pWin;
  2184         -
  2185         -  /* There are three different functions that may be used to do the work
  2186         -  ** of this one, depending on the window frame and the specific built-in
  2187         -  ** window functions used (if any).
  2188         -  **
  2189         -  ** windowCodeRowExprStep() handles all "ROWS" window frames, except for:
  2190         -  **
  2191         -  **   ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
  2192         -  **
  2193         -  ** The exception is because windowCodeRowExprStep() implements all window
  2194         -  ** frame types by caching the entire partition in a temp table, and
  2195         -  ** "ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW" is easy enough to
  2196         -  ** implement without such a cache.
  2197         -  **
  2198         -  ** windowCodeCacheStep() is used for:
  2199         -  **
  2200         -  **   RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
  2201         -  **
  2202         -  ** It is also used for anything not handled by windowCodeRowExprStep() 
  2203         -  ** that invokes a built-in window function that requires the entire 
  2204         -  ** partition to be cached in a temp table before any rows are returned
  2205         -  ** (e.g. nth_value() or percent_rank()).
  2206         -  **
  2207         -  ** Finally, assuming there is no built-in window function that requires
  2208         -  ** the partition to be cached, windowCodeDefaultStep() is used for:
  2209         -  **
  2210         -  **   RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW 
  2211         -  **   RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
  2212         -  **   RANGE BETWEEN CURRENT ROW AND CURRENT ROW 
  2213         -  **   ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
  2214         -  **
  2215         -  ** windowCodeDefaultStep() is the only one of the three functions that
  2216         -  ** does not cache each partition in a temp table before beginning to
  2217         -  ** return rows.
  2218         -  */
  2219         -  if( pMWin->eType==TK_ROWS 
  2220         -   && (pMWin->eStart!=TK_UNBOUNDED||pMWin->eEnd!=TK_CURRENT||!pMWin->pOrderBy)
         2389  +  ExprList *pOrderBy = pMWin->pOrderBy;
         2390  +  Vdbe *v = sqlite3GetVdbe(pParse);
         2391  +  int csrWrite;                   /* Cursor used to write to eph. table */
         2392  +  int csrInput = p->pSrc->a[0].iCursor;     /* Cursor of sub-select */
         2393  +  int nInput = p->pSrc->a[0].pTab->nCol;    /* Number of cols returned by sub */
         2394  +  int iInput;                               /* To iterate through sub cols */
         2395  +  int addrNe;                     /* Address of OP_Ne */
         2396  +  int addrGosubFlush = 0;         /* Address of OP_Gosub to flush: */
         2397  +  int addrInteger = 0;            /* Address of OP_Integer */
         2398  +  int addrEmpty;                  /* Address of OP_Rewind in flush: */
         2399  +  int regStart = 0;               /* Value of <expr> PRECEDING */
         2400  +  int regEnd = 0;                 /* Value of <expr> FOLLOWING */
         2401  +  int regNew;                     /* Array of registers holding new input row */
         2402  +  int regRecord;                  /* regNew array in record form */
         2403  +  int regRowid;                   /* Rowid for regRecord in eph table */
         2404  +  int regNewPeer = 0;             /* Peer values for new row (part of regNew) */
         2405  +  int regPeer = 0;                /* Peer values for current row */
         2406  +  int regFlushPart = 0;           /* Register for "Gosub flush_partition" */
         2407  +  WindowCodeArg s;                /* Context object for sub-routines */
         2408  +  int lblWhereEnd;                /* Label just before sqlite3WhereEnd() code */
         2409  +
         2410  +  assert( pMWin->eStart==TK_PRECEDING || pMWin->eStart==TK_CURRENT 
         2411  +       || pMWin->eStart==TK_FOLLOWING || pMWin->eStart==TK_UNBOUNDED 
         2412  +  );
         2413  +  assert( pMWin->eEnd==TK_FOLLOWING || pMWin->eEnd==TK_CURRENT 
         2414  +       || pMWin->eEnd==TK_UNBOUNDED || pMWin->eEnd==TK_PRECEDING 
         2415  +  );
         2416  +  assert( pMWin->eExclude==0 || pMWin->eExclude==TK_CURRENT
         2417  +       || pMWin->eExclude==TK_GROUP || pMWin->eExclude==TK_TIES
         2418  +       || pMWin->eExclude==TK_NO
         2419  +  );
         2420  +
         2421  +  lblWhereEnd = sqlite3VdbeMakeLabel(pParse);
         2422  +
         2423  +  /* Fill in the context object */
         2424  +  memset(&s, 0, sizeof(WindowCodeArg));
         2425  +  s.pParse = pParse;
         2426  +  s.pMWin = pMWin;
         2427  +  s.pVdbe = v;
         2428  +  s.regGosub = regGosub;
         2429  +  s.addrGosub = addrGosub;
         2430  +  s.current.csr = pMWin->iEphCsr;
         2431  +  csrWrite = s.current.csr+1;
         2432  +  s.start.csr = s.current.csr+2;
         2433  +  s.end.csr = s.current.csr+3;
         2434  +
         2435  +  /* Figure out when rows may be deleted from the ephemeral table. There
         2436  +  ** are four options - they may never be deleted (eDelete==0), they may 
         2437  +  ** be deleted as soon as they are no longer part of the window frame
         2438  +  ** (eDelete==WINDOW_AGGINVERSE), they may be deleted as after the row 
         2439  +  ** has been returned to the caller (WINDOW_RETURN_ROW), or they may
         2440  +  ** be deleted after they enter the frame (WINDOW_AGGSTEP). */
         2441  +  switch( pMWin->eStart ){
         2442  +    case TK_FOLLOWING:
         2443  +      if( pMWin->eFrmType!=TK_RANGE
         2444  +       && windowExprGtZero(pParse, pMWin->pStart)
         2445  +      ){
         2446  +        s.eDelete = WINDOW_RETURN_ROW;
         2447  +      }
         2448  +      break;
         2449  +    case TK_UNBOUNDED:
         2450  +      if( windowCacheFrame(pMWin)==0 ){
         2451  +        if( pMWin->eEnd==TK_PRECEDING ){
         2452  +          if( pMWin->eFrmType!=TK_RANGE
         2453  +           && windowExprGtZero(pParse, pMWin->pEnd)
  2221   2454     ){
  2222         -    VdbeModuleComment((pParse->pVdbe, "Begin RowExprStep()"));
  2223         -    windowCodeRowExprStep(pParse, p, pWInfo, regGosub, addrGosub);
         2455  +            s.eDelete = WINDOW_AGGSTEP;
         2456  +          }
  2224   2457     }else{
  2225         -    Window *pWin;
  2226         -    int bCache = 0;               /* True to use CacheStep() */
  2227         -
  2228         -    if( pMWin->eStart==TK_CURRENT && pMWin->eEnd==TK_UNBOUNDED ){
  2229         -      bCache = 1;
  2230         -    }else{
  2231         -      for(pWin=pMWin; pWin; pWin=pWin->pNextWin){
  2232         -        FuncDef *pFunc = pWin->pFunc;
  2233         -        if( (pFunc->funcFlags & SQLITE_FUNC_WINDOW_SIZE)
  2234         -         || (pFunc->zName==nth_valueName)
  2235         -         || (pFunc->zName==first_valueName)
  2236         -         || (pFunc->zName==leadName)
  2237         -         || (pFunc->zName==lagName)
  2238         -        ){
  2239         -          bCache = 1;
         2458  +          s.eDelete = WINDOW_RETURN_ROW;
         2459  +        }
         2460  +      }
         2461  +      break;
         2462  +    default:
         2463  +      s.eDelete = WINDOW_AGGINVERSE;
  2240   2464             break;
  2241   2465           }
         2466  +
         2467  +  /* Allocate registers for the array of values from the sub-query, the
         2468  +  ** samve values in record form, and the rowid used to insert said record
         2469  +  ** into the ephemeral table.  */
         2470  +  regNew = pParse->nMem+1;
         2471  +  pParse->nMem += nInput;
         2472  +  regRecord = ++pParse->nMem;
         2473  +  regRowid = ++pParse->nMem;
         2474  +
         2475  +  /* If the window frame contains an "<expr> PRECEDING" or "<expr> FOLLOWING"
         2476  +  ** clause, allocate registers to store the results of evaluating each
         2477  +  ** <expr>.  */
         2478  +  if( pMWin->eStart==TK_PRECEDING || pMWin->eStart==TK_FOLLOWING ){
         2479  +    regStart = ++pParse->nMem;
         2480  +  }
         2481  +  if( pMWin->eEnd==TK_PRECEDING || pMWin->eEnd==TK_FOLLOWING ){
         2482  +    regEnd = ++pParse->nMem;
         2483  +  }
         2484  +
         2485  +  /* If this is not a "ROWS BETWEEN ..." frame, then allocate arrays of
         2486  +  ** registers to store copies of the ORDER BY expressions (peer values) 
         2487  +  ** for the main loop, and for each cursor (start, current and end). */
         2488  +  if( pMWin->eFrmType!=TK_ROWS ){
         2489  +    int nPeer = (pOrderBy ? pOrderBy->nExpr : 0);
         2490  +    regNewPeer = regNew + pMWin->nBufferCol;
         2491  +    if( pMWin->pPartition ) regNewPeer += pMWin->pPartition->nExpr;
         2492  +    regPeer = pParse->nMem+1;       pParse->nMem += nPeer;
         2493  +    s.start.reg = pParse->nMem+1;   pParse->nMem += nPeer;
         2494  +    s.current.reg = pParse->nMem+1; pParse->nMem += nPeer;
         2495  +    s.end.reg = pParse->nMem+1;     pParse->nMem += nPeer;
         2496  +  }
         2497  +
         2498  +  /* Load the column values for the row returned by the sub-select
         2499  +  ** into an array of registers starting at regNew. Assemble them into
         2500  +  ** a record in register regRecord. */
         2501  +  for(iInput=0; iInput<nInput; iInput++){
         2502  +    sqlite3VdbeAddOp3(v, OP_Column, csrInput, iInput, regNew+iInput);
         2503  +  }
         2504  +  sqlite3VdbeAddOp3(v, OP_MakeRecord, regNew, nInput, regRecord);
         2505  +
         2506  +  /* An input row has just been read into an array of registers starting
         2507  +  ** at regNew. If the window has a PARTITION clause, this block generates 
         2508  +  ** VM code to check if the input row is the start of a new partition.
         2509  +  ** If so, it does an OP_Gosub to an address to be filled in later. The
         2510  +  ** address of the OP_Gosub is stored in local variable addrGosubFlush. */
         2511  +  if( pMWin->pPartition ){
         2512  +    int addr;
         2513  +    ExprList *pPart = pMWin->pPartition;
         2514  +    int nPart = pPart->nExpr;
         2515  +    int regNewPart = regNew + pMWin->nBufferCol;
         2516  +    KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pPart, 0, 0);
         2517  +
         2518  +    regFlushPart = ++pParse->nMem;
         2519  +    addr = sqlite3VdbeAddOp3(v, OP_Compare, regNewPart, pMWin->regPart, nPart);
         2520  +    sqlite3VdbeAppendP4(v, (void*)pKeyInfo, P4_KEYINFO);
         2521  +    sqlite3VdbeAddOp3(v, OP_Jump, addr+2, addr+4, addr+2);
         2522  +    VdbeCoverageEqNe(v);
         2523  +    addrGosubFlush = sqlite3VdbeAddOp1(v, OP_Gosub, regFlushPart);
         2524  +    VdbeComment((v, "call flush_partition"));
         2525  +    sqlite3VdbeAddOp3(v, OP_Copy, regNewPart, pMWin->regPart, nPart-1);
         2526  +  }
         2527  +
         2528  +  /* Insert the new row into the ephemeral table */
         2529  +  sqlite3VdbeAddOp2(v, OP_NewRowid, csrWrite, regRowid);
         2530  +  sqlite3VdbeAddOp3(v, OP_Insert, csrWrite, regRecord, regRowid);
         2531  +  addrNe = sqlite3VdbeAddOp3(v, OP_Ne, pMWin->regOne, 0, regRowid);
         2532  +  VdbeCoverageNeverNull(v);
         2533  +
         2534  +  /* This block is run for the first row of each partition */
         2535  +  s.regArg = windowInitAccum(pParse, pMWin);
         2536  +
         2537  +  if( regStart ){
         2538  +    sqlite3ExprCode(pParse, pMWin->pStart, regStart);
         2539  +    windowCheckValue(pParse, regStart, 0 + (pMWin->eFrmType==TK_RANGE ? 3 : 0));
         2540  +  }
         2541  +  if( regEnd ){
         2542  +    sqlite3ExprCode(pParse, pMWin->pEnd, regEnd);
         2543  +    windowCheckValue(pParse, regEnd, 1 + (pMWin->eFrmType==TK_RANGE ? 3 : 0));
         2544  +  }
         2545  +
         2546  +  if( pMWin->eStart==pMWin->eEnd && regStart ){
         2547  +    int op = ((pMWin->eStart==TK_FOLLOWING) ? OP_Ge : OP_Le);
         2548  +    int addrGe = sqlite3VdbeAddOp3(v, op, regStart, 0, regEnd);
         2549  +    VdbeCoverageNeverNullIf(v, op==OP_Ge); /* NeverNull because bound <expr> */
         2550  +    VdbeCoverageNeverNullIf(v, op==OP_Le); /*   values previously checked */
         2551  +    windowAggFinal(&s, 0);
         2552  +    sqlite3VdbeAddOp2(v, OP_Rewind, s.current.csr, 1);
         2553  +    VdbeCoverageNeverTaken(v);
         2554  +    windowReturnOneRow(&s);
         2555  +    sqlite3VdbeAddOp1(v, OP_ResetSorter, s.current.csr);
         2556  +    sqlite3VdbeAddOp2(v, OP_Goto, 0, lblWhereEnd);
         2557  +    sqlite3VdbeJumpHere(v, addrGe);
         2558  +  }
         2559  +  if( pMWin->eStart==TK_FOLLOWING && pMWin->eFrmType!=TK_RANGE && regEnd ){
         2560  +    assert( pMWin->eEnd==TK_FOLLOWING );
         2561  +    sqlite3VdbeAddOp3(v, OP_Subtract, regStart, regEnd, regStart);
         2562  +  }
         2563  +
         2564  +  if( pMWin->eStart!=TK_UNBOUNDED ){
         2565  +    sqlite3VdbeAddOp2(v, OP_Rewind, s.start.csr, 1);
         2566  +    VdbeCoverageNeverTaken(v);
         2567  +  }
         2568  +  sqlite3VdbeAddOp2(v, OP_Rewind, s.current.csr, 1);
         2569  +  VdbeCoverageNeverTaken(v);
         2570  +  sqlite3VdbeAddOp2(v, OP_Rewind, s.end.csr, 1);
         2571  +  VdbeCoverageNeverTaken(v);
         2572  +  if( regPeer && pOrderBy ){
         2573  +    sqlite3VdbeAddOp3(v, OP_Copy, regNewPeer, regPeer, pOrderBy->nExpr-1);
         2574  +    sqlite3VdbeAddOp3(v, OP_Copy, regPeer, s.start.reg, pOrderBy->nExpr-1);
         2575  +    sqlite3VdbeAddOp3(v, OP_Copy, regPeer, s.current.reg, pOrderBy->nExpr-1);
         2576  +    sqlite3VdbeAddOp3(v, OP_Copy, regPeer, s.end.reg, pOrderBy->nExpr-1);
         2577  +  }
         2578  +
         2579  +  sqlite3VdbeAddOp2(v, OP_Goto, 0, lblWhereEnd);
         2580  +
         2581  +  sqlite3VdbeJumpHere(v, addrNe);
         2582  +
         2583  +  /* Beginning of the block executed for the second and subsequent rows. */
         2584  +  if( regPeer ){
         2585  +    windowIfNewPeer(pParse, pOrderBy, regNewPeer, regPeer, lblWhereEnd);
         2586  +  }
         2587  +  if( pMWin->eStart==TK_FOLLOWING ){
         2588  +    windowCodeOp(&s, WINDOW_AGGSTEP, 0, 0);
         2589  +    if( pMWin->eEnd!=TK_UNBOUNDED ){
         2590  +      if( pMWin->eFrmType==TK_RANGE ){
         2591  +        int lbl = sqlite3VdbeMakeLabel(pParse);
         2592  +        int addrNext = sqlite3VdbeCurrentAddr(v);
         2593  +        windowCodeRangeTest(&s, OP_Ge, s.current.csr, regEnd, s.end.csr, lbl);
         2594  +        windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 0);
         2595  +        windowCodeOp(&s, WINDOW_RETURN_ROW, 0, 0);
         2596  +        sqlite3VdbeAddOp2(v, OP_Goto, 0, addrNext);
         2597  +        sqlite3VdbeResolveLabel(v, lbl);
         2598  +      }else{
         2599  +        windowCodeOp(&s, WINDOW_RETURN_ROW, regEnd, 0);
         2600  +        windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 0);
         2601  +      }
         2602  +    }
         2603  +  }else
         2604  +  if( pMWin->eEnd==TK_PRECEDING ){
         2605  +    int bRPS = (pMWin->eStart==TK_PRECEDING && pMWin->eFrmType==TK_RANGE);
         2606  +    windowCodeOp(&s, WINDOW_AGGSTEP, regEnd, 0);
         2607  +    if( bRPS ) windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 0);
         2608  +    windowCodeOp(&s, WINDOW_RETURN_ROW, 0, 0);
         2609  +    if( !bRPS ) windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 0);
         2610  +  }else{
         2611  +    int addr = 0;
         2612  +    windowCodeOp(&s, WINDOW_AGGSTEP, 0, 0);
         2613  +    if( pMWin->eEnd!=TK_UNBOUNDED ){
         2614  +      if( pMWin->eFrmType==TK_RANGE ){
         2615  +        int lbl = 0;
         2616  +        addr = sqlite3VdbeCurrentAddr(v);
         2617  +        if( regEnd ){
         2618  +          lbl = sqlite3VdbeMakeLabel(pParse);
         2619  +          windowCodeRangeTest(&s, OP_Ge, s.current.csr, regEnd, s.end.csr, lbl);
         2620  +        }
         2621  +        windowCodeOp(&s, WINDOW_RETURN_ROW, 0, 0);
         2622  +        windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 0);
         2623  +        if( regEnd ){
         2624  +          sqlite3VdbeAddOp2(v, OP_Goto, 0, addr);
         2625  +          sqlite3VdbeResolveLabel(v, lbl);
         2626  +        }
         2627  +      }else{
         2628  +        if( regEnd ){
         2629  +          addr = sqlite3VdbeAddOp3(v, OP_IfPos, regEnd, 0, 1);
         2630  +          VdbeCoverage(v);
         2631  +        }
         2632  +        windowCodeOp(&s, WINDOW_RETURN_ROW, 0, 0);
         2633  +        windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 0);
         2634  +        if( regEnd ) sqlite3VdbeJumpHere(v, addr);
         2635  +      }
         2636  +    }
  2242   2637         }
         2638  +
         2639  +  /* End of the main input loop */
         2640  +  sqlite3VdbeResolveLabel(v, lblWhereEnd);
         2641  +  sqlite3WhereEnd(pWInfo);
         2642  +
         2643  +  /* Fall through */
         2644  +  if( pMWin->pPartition ){
         2645  +    addrInteger = sqlite3VdbeAddOp2(v, OP_Integer, 0, regFlushPart);
         2646  +    sqlite3VdbeJumpHere(v, addrGosubFlush);
  2243   2647       }
  2244   2648   
  2245         -    /* Otherwise, call windowCodeDefaultStep().  */
  2246         -    if( bCache ){
  2247         -      VdbeModuleComment((pParse->pVdbe, "Begin CacheStep()"));
  2248         -      windowCodeCacheStep(pParse, p, pWInfo, regGosub, addrGosub);
         2649  +  addrEmpty = sqlite3VdbeAddOp1(v, OP_Rewind, csrWrite);
         2650  +  VdbeCoverage(v);
         2651  +  if( pMWin->eEnd==TK_PRECEDING ){
         2652  +    int bRPS = (pMWin->eStart==TK_PRECEDING && pMWin->eFrmType==TK_RANGE);
         2653  +    windowCodeOp(&s, WINDOW_AGGSTEP, regEnd, 0);
         2654  +    if( bRPS ) windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 0);
         2655  +    windowCodeOp(&s, WINDOW_RETURN_ROW, 0, 0);
         2656  +  }else if( pMWin->eStart==TK_FOLLOWING ){
         2657  +    int addrStart;
         2658  +    int addrBreak1;
         2659  +    int addrBreak2;
         2660  +    int addrBreak3;
         2661  +    windowCodeOp(&s, WINDOW_AGGSTEP, 0, 0);
         2662  +    if( pMWin->eFrmType==TK_RANGE ){
         2663  +      addrStart = sqlite3VdbeCurrentAddr(v);
         2664  +      addrBreak2 = windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 1);
         2665  +      addrBreak1 = windowCodeOp(&s, WINDOW_RETURN_ROW, 0, 1);
         2666  +    }else
         2667  +    if( pMWin->eEnd==TK_UNBOUNDED ){
         2668  +      addrStart = sqlite3VdbeCurrentAddr(v);
         2669  +      addrBreak1 = windowCodeOp(&s, WINDOW_RETURN_ROW, regStart, 1);
         2670  +      addrBreak2 = windowCodeOp(&s, WINDOW_AGGINVERSE, 0, 1);
         2671  +    }else{
         2672  +      assert( pMWin->eEnd==TK_FOLLOWING );
         2673  +      addrStart = sqlite3VdbeCurrentAddr(v);
         2674  +      addrBreak1 = windowCodeOp(&s, WINDOW_RETURN_ROW, regEnd, 1);
         2675  +      addrBreak2 = windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 1);
         2676  +    }
         2677  +    sqlite3VdbeAddOp2(v, OP_Goto, 0, addrStart);
         2678  +    sqlite3VdbeJumpHere(v, addrBreak2);
         2679  +    addrStart = sqlite3VdbeCurrentAddr(v);
         2680  +    addrBreak3 = windowCodeOp(&s, WINDOW_RETURN_ROW, 0, 1);
         2681  +    sqlite3VdbeAddOp2(v, OP_Goto, 0, addrStart);
         2682  +    sqlite3VdbeJumpHere(v, addrBreak1);
         2683  +    sqlite3VdbeJumpHere(v, addrBreak3);
  2249   2684       }else{
  2250         -      VdbeModuleComment((pParse->pVdbe, "Begin DefaultStep()"));
  2251         -      windowCodeDefaultStep(pParse, p, pWInfo, regGosub, addrGosub);
         2685  +    int addrBreak;
         2686  +    int addrStart;
         2687  +    windowCodeOp(&s, WINDOW_AGGSTEP, 0, 0);
         2688  +    addrStart = sqlite3VdbeCurrentAddr(v);
         2689  +    addrBreak = windowCodeOp(&s, WINDOW_RETURN_ROW, 0, 1);
         2690  +    windowCodeOp(&s, WINDOW_AGGINVERSE, regStart, 0);
         2691  +    sqlite3VdbeAddOp2(v, OP_Goto, 0, addrStart);
         2692  +    sqlite3VdbeJumpHere(v, addrBreak);
         2693  +  }
         2694  +  sqlite3VdbeJumpHere(v, addrEmpty);
         2695  +
         2696  +  sqlite3VdbeAddOp1(v, OP_ResetSorter, s.current.csr);
         2697  +  if( pMWin->pPartition ){
         2698  +    if( pMWin->regStartRowid ){
         2699  +      sqlite3VdbeAddOp2(v, OP_Integer, 1, pMWin->regStartRowid);
         2700  +      sqlite3VdbeAddOp2(v, OP_Integer, 0, pMWin->regEndRowid);
  2252   2701       }
         2702  +    sqlite3VdbeChangeP1(v, addrInteger, sqlite3VdbeCurrentAddr(v));
         2703  +    sqlite3VdbeAddOp1(v, OP_Return, regFlushPart);
  2253   2704     }
  2254   2705   }
  2255   2706   
  2256   2707   #endif /* SQLITE_OMIT_WINDOWFUNC */

Changes to test/altertab3.test.

    95     95     BEGIN;
    96     96       ALTER TABLE t3 RENAME TO t4;
    97     97   } {1 {error in trigger tr1: no such table: main.t2}}
    98     98   do_execsql_test 4.1.2 {
    99     99     COMMIT;
   100    100   }
   101    101   do_execsql_test 4.1.3 {
   102         -  SELECT * FROM sqlite_master WHERE type='table' AND name!='t1';
   103         -} {table t3 t3 3 {CREATE TABLE t3(e, f)}}
          102  +  SELECT type, name, tbl_name, sql 
          103  +  FROM sqlite_master WHERE type='table' AND name!='t1';
          104  +} {table t3 t3 {CREATE TABLE t3(e, f)}}
   104    105   
   105    106   
   106    107   do_catchsql_test 4.2.1 {
   107    108     BEGIN;
   108    109       ALTER TABLE t3 RENAME e TO eee;
   109    110   } {1 {error in trigger tr1: no such table: main.t2}}
   110    111   do_execsql_test 4.2.2 {
   111    112     COMMIT;
   112    113   }
   113    114   do_execsql_test 4.2.3 {
   114         -  SELECT * FROM sqlite_master WHERE type='table' AND name!='t1';
   115         -} {table t3 t3 3 {CREATE TABLE t3(e, f)}}
          115  +  SELECT type, name, tbl_name, sql 
          116  +  FROM sqlite_master WHERE type='table' AND name!='t1';
          117  +} {table t3 t3 {CREATE TABLE t3(e, f)}}
   116    118   
   117    119   #-------------------------------------------------------------------------
   118    120   reset_db
   119    121   do_execsql_test 5.0 {
   120    122     CREATE TABLE t1 (
   121    123         c1 integer, c2, PRIMARY KEY(c1 collate rtrim),
   122    124         UNIQUE(c2)

Changes to test/autoinc.test.

    12     12   # focus of this script is testing the AUTOINCREMENT features.
    13     13   #
    14     14   # $Id: autoinc.test,v 1.14 2009/06/23 20:28:54 drh Exp $
    15     15   #
    16     16   
    17     17   set testdir [file dirname $argv0]
    18     18   source $testdir/tester.tcl
           19  +set testprefix autoinc
    19     20   
    20     21   # If the library is not compiled with autoincrement support then
    21     22   # skip all tests in this file.
    22     23   #
    23     24   ifcapable {!autoinc} {
    24     25     finish_test
    25     26     return
................................................................................
   851    852     set res [catch {db eval {
   852    853       INSERT INTO t1(b) VALUES('two'),('three'),('four');
   853    854       INSERT INTO t1(b) VALUES('five');
   854    855       PRAGMA integrity_check;
   855    856     }} msg]
   856    857     lappend res $msg
   857    858   } {0 ok}
          859  +
          860  +#--------------------------------------------------------------------------
          861  +reset_db
          862  +do_execsql_test 13.0 {
          863  +  CREATE TABLE t1(i INTEGER PRIMARY KEY AUTOINCREMENT, j);
          864  +  CREATE TABLE t2(i INTEGER PRIMARY KEY AUTOINCREMENT, j);
          865  +  CREATE TABLE t3(i INTEGER PRIMARY KEY AUTOINCREMENT, j);
          866  +
          867  +  INSERT INTO t1 VALUES(NULL, 1);
          868  +  INSERT INTO t2 VALUES(NULL, 2);
          869  +  INSERT INTO t3 VALUES(NULL, 3);
          870  +
          871  +  SELECT name FROM sqlite_sequence;
          872  +} {t1 t2 t3}
          873  +
          874  +do_execsql_test 13.1 {
          875  +  UPDATE sqlite_sequence SET name=NULL WHERE name='t2';
          876  +  INSERT INTO t3 VALUES(NULL, 4);
          877  +  DELETE FROM t3;
          878  +  INSERT INTO t3 VALUES(NULL, 5);
          879  +  SELECT * FROM t3;
          880  +} {3 5}
          881  +
   858    882   
   859    883   finish_test

Changes to test/badutf2.test.

    94     94       do_test badutf2-3.1.$i {
    95     95         set sql "SELECT hex('$hstr') AS x;"
    96     96         set res [ sqlite3_exec db $sql ]
    97     97         lindex [ lindex $res 1] 1
    98     98       } $uval
    99     99     }
   100    100   
          101  +  # Tcl 8.7 and later do automatic bad-utf8 correction for
          102  +  # characters 0x80 thru 0x9f so test case 5 does not work here.
          103  +  if {$i==5 && $tcl_version>=8.7} {
          104  +     # no-op
          105  +  } else {
   101    106     do_test badutf2-4.1.$i {
   102    107       sqlite3_reset $S
   103    108       sqlite3_bind_text $S 1 $xstr $len
   104    109       sqlite3_step $S
   105    110       utf8_to_ustr2 [ sqlite3_column_text $S 0 ]
   106    111     } $ustr
          112  +  }
   107    113   
   108    114     ifcapable debug {
   109    115       do_test badutf2-5.1.$i {
   110    116         utf8_to_utf8 $uval
   111    117       } $u2u
   112    118     }
   113    119   

Changes to test/bestindex1.test.

   261    261     WHERE a.FlagA=0 AND a.ColumnA IN ('ValueA', 'ValueB') 
   262    262   } {
   263    263     1 0 ValueA 1 0 ValueA
   264    264     2 0 ValueA 2 0 ValueA
   265    265     3 0 ValueB 3 0 ValueB
   266    266     4 0 ValueB 4 0 ValueB
   267    267   }
          268  +
          269  +#-------------------------------------------------------------------------
          270  +# If there is an IN(..) condition in the WHERE clause of a query on a
          271  +# virtual table, the xBestIndex method is first invoked with the IN(...)
          272  +# represented by a "usable" SQLITE_INDEX_CONSTRAINT_EQ constraint. If
          273  +# the virtual table elects to use the IN(...) constraint, then the 
          274  +# xBestIndex method is invoked again, this time with the IN(...) marked
          275  +# as "not usable". Depending on the relative costs of the two plans as
          276  +# defined by the virtual table implementation, and the cardinality of the
          277  +# IN(...) operator, SQLite chooses the most efficient plan. 
          278  +#
          279  +# At one point the second invocation of xBestIndex() was only being made
          280  +# for join queries. The following tests check that this problem has been
          281  +# fixed.
          282  +#
          283  +proc vtab_command {method args} {
          284  +  switch -- $method {
          285  +    xConnect {
          286  +      return "CREATE TABLE t1(a, b, c, d)"
          287  +    }
          288  +
          289  +    xBestIndex {
          290  +      set clist [lindex $args 0]
          291  +      lappend ::bestindex_calls $clist
          292  +      set ret "cost 1000000 idxnum 555"
          293  +      for {set i 0} {$i < [llength $clist]} {incr i} {
          294  +        array set C [lindex $clist $i]
          295  +        if {$C(usable)} { lappend ret use $i }
          296  +      }
          297  +      return $ret
          298  +    }
          299  +  }
          300  +  return {}
          301  +}
          302  +
          303  +do_execsql_test 4.0 {
          304  +  CREATE VIRTUAL TABLE x1 USING tcl(vtab_command);
          305  +} {}
          306  +
          307  +do_test 4.1 {
          308  +  set ::bestindex_calls [list]
          309  +  execsql {
          310  +    SELECT * FROM x1 WHERE a=? AND b BETWEEN ? AND ? AND c IN (1, 2, 3, 4);
          311  +  }
          312  +  set ::bestindex_calls
          313  +} [list \
          314  +    [list {op eq column 0 usable 1} \
          315  +          {op eq column 2 usable 1} \
          316  +          {op ge column 1 usable 1} \
          317  +          {op le column 1 usable 1} \
          318  +    ] \
          319  +    [list {op eq column 0 usable 1} \
          320  +          {op eq column 2 usable 0} \
          321  +          {op ge column 1 usable 1} \
          322  +          {op le column 1 usable 1}
          323  +    ]
          324  +]
   268    325   
   269    326   
   270    327   finish_test

Changes to test/corruptC.test.

    93     93     forcecopy test.bu test.db
    94     94   
    95     95     # insert corrupt byte(s)
    96     96     hexio_write test.db 2053 [format %02x 0x04]
    97     97   
    98     98     sqlite3 db test.db
    99     99     catchsql {PRAGMA integrity_check}
   100         -} {1 {database disk image is malformed}}
          100  +} {0 {{*** in database main ***
          101  +Page 3: free space corruption}}}
   101    102   
   102    103   # test that a corrupt content offset size is handled (seed 5649)
   103    104   #
   104    105   # Update 2016-12-27:  As of check-in [0b86fbca66] "In sqlite3BtreeInsert() when
   105    106   # replacing a re-existing row, try to overwrite the cell directly rather than
   106    107   # deallocate and reallocate the cell" on 2016-12-09, this test case no longer
   107    108   # detects the offset size problem during the UPDATE.  We have to run a subsequent

Changes to test/createtab.test.

     8      8   #    May you share freely, never taking more than you give.
     9      9   #
    10     10   #***********************************************************************
    11     11   # This file implements regression tests for SQLite library.  The
    12     12   # focus of this file is testing that it is OK to create new tables
    13     13   # and indices while creating existing tables and indices.
    14     14   #
    15         -# $Id: createtab.test,v 1.3 2007/09/12 17:01:45 danielk1977 Exp $
    16     15   
    17     16   set testdir [file dirname $argv0]
    18     17   source $testdir/tester.tcl
    19     18   
    20     19   ifcapable autovacuum {
    21     20     set upperBound 2
    22     21   } else {
................................................................................
   138    137       execsql {
   139    138         SELECT name FROM sqlite_master WHERE type='table' ORDER BY 1
   140    139       }
   141    140     } {t1 t2 t3 t4}
   142    141     integrity_check createtab-$av.40
   143    142   
   144    143   }
          144  +
          145  +# 2019-03-31 Ensure that a proper error is returned for an index
          146  +# with too many columns.
          147  +#
          148  +do_test createtab-3.1 {
          149  +  db eval {DROP TABLE IF EXISTS t1;}
          150  +  set sql "CREATE TABLE t1(x,UNIQUE(x[string repeat ,x 100000]))"
          151  +  catchsql $sql
          152  +} {1 {too many columns in index}}
   145    153     
   146    154   finish_test

Changes to test/dbfuzz001.test.

   185    185   
   186    186   # The DELETE query below deletes the very last cell from page 8.
   187    187   # Prior to a certain fix to sqlite3BtreeDelete() and because of the
   188    188   # corruption to the freeblock list on page 8, this would fail to
   189    189   # cause a rebalance operation, which would leave the btree in a weird
   190    190   # state that would lead to segfaults and or assertion faults.
   191    191   #
   192         -set res {0 {}}
   193         -ifcapable oversize_cell_check { set res {1 {database disk image is malformed}} }
   194         -do_catchsql_test dbfuzz001-110 {
          192  +do_execsql_test dbfuzz001-110 {
   195    193     DELETE FROM t3 WHERE x IS NOT NULL AND +rowid=6;
   196         -} $res
          194  +} {}
   197    195   
   198    196   # This is a dbfuzz2-generate test case that can cause a page with
   199    197   # pPage->nCell==0 to enter the balancer.
   200    198   #
   201    199   do_test dbfuzz001-200 {
   202    200     db deserialize [decode_hexdb {
   203    201       | size 3076 pagesize 512 filename c03.db

Changes to test/delete4.test.

   178    178   do_execsql_test 6.1 {
   179    179     DROP TABLE IF EXISTS t2;
   180    180     CREATE TABLE t2(x INT);
   181    181     INSERT INTO t2(x) VALUES(1),(2),(3),(4),(5);
   182    182     DELETE FROM t2 WHERE EXISTS(SELECT 1 FROM t2 AS v WHERE v.x=t2.x+1);
   183    183     SELECT x FROM t2;
   184    184   } {5}
          185  +
          186  +#-------------------------------------------------------------------------
          187  +# Test the effect of failing to find a table row based on an index key
          188  +# within a DELETE. Either because the db is corrupt, or a trigger on another
          189  +# row already deleted the entry, or because a BEFORE trigger on the current
          190  +# row has already deleted it.
          191  +#
          192  +do_execsql_test 7.1.0 {
          193  +  CREATE TABLE t3(id INT PRIMARY KEY, a, b) WITHOUT ROWID;
          194  +  CREATE INDEX t3a ON t3(a);
          195  +  CREATE INDEX t3b ON t3(b);
          196  +
          197  +  INSERT INTO t3 VALUES(1, 1, 1);
          198  +  INSERT INTO t3 VALUES(2, 2, 2);
          199  +  INSERT INTO t3 VALUES(3, 3, 3);
          200  +  INSERT INTO t3 VALUES(4, 4, 1);
          201  +}
          202  +do_execsql_test 7.1.1 {
          203  +  DELETE FROM t3 WHERE a=4 OR b=1;
          204  +}
          205  +do_execsql_test 7.1.2 {
          206  +  SELECT * FROM t3;
          207  +} { 2 2 2   3 3 3 }
          208  +
          209  +do_execsql_test 7.2.0 {
          210  +  CREATE TABLE t4(a PRIMARY KEY, b) WITHOUT ROWID;
          211  +  CREATE INDEX t4i ON t4(b);
          212  +  INSERT INTO t4 VALUES(1, 'hello');
          213  +  INSERT INTO t4 VALUES(2, 'world');
          214  +
          215  +  CREATE TABLE t5(a PRIMARY KEY, b) WITHOUT ROWID;
          216  +  CREATE INDEX t5i ON t5(b);
          217  +  INSERT INTO t5 VALUES(1, 'hello');
          218  +  INSERT INTO t5 VALUES(3, 'world');
          219  +
          220  +  PRAGMA writable_schema = 1;
          221  +  UPDATE sqlite_master SET rootpage = (
          222  +    SELECT rootpage FROM sqlite_master WHERE name = 't5'
          223  +  ) WHERE name = 't4';
          224  +}
          225  +
          226  +db close
          227  +sqlite3 db test.db
          228  +do_execsql_test 7.2.1 {
          229  +  DELETE FROM t4 WHERE b='world'
          230  +}
          231  +reset_db
          232  +
          233  +do_execsql_test 7.3.0 {
          234  +  CREATE TABLE t3(id INT PRIMARY KEY, a, b) WITHOUT ROWID;
          235  +  INSERT INTO t3 VALUES(1, 2, 3);
          236  +  INSERT INTO t3 VALUES(4, 5, 6);
          237  +  INSERT INTO t3 VALUES(7, 8, 9);
          238  +  CREATE TRIGGER t3t BEFORE DELETE ON t3 BEGIN
          239  +    DELETE FROM t3 WHERE id=old.id+3;
          240  +  END;
          241  +}
          242  +
          243  +do_execsql_test 7.3.1 {
          244  +  DELETE FROM t3 WHERE a IN(2, 5, 8);
          245  +  SELECT * FROM t3;
          246  +} {}
          247  +
          248  +do_execsql_test 7.3.2 {
          249  +  DROP TRIGGER t3t;
          250  +  INSERT INTO t3 VALUES(1, 2, 3);
          251  +  INSERT INTO t3 VALUES(4, 5, 6);
          252  +  INSERT INTO t3 VALUES(7, 8, 9);
          253  +  CREATE TRIGGER t3t BEFORE DELETE ON t3 BEGIN
          254  +    DELETE FROM t3 WHERE id=old.id;
          255  +  END;
          256  +}
          257  +
          258  +do_execsql_test 7.3.3 {
          259  +  DELETE FROM t3 WHERE a IN(2, 5, 8);
          260  +  SELECT * FROM t3;
          261  +} {}
   185    262   
   186    263   
   187    264   finish_test

Changes to test/e_vacuum.test.

   228    228     INSERT INTO t4(x) VALUES('z');
   229    229     DELETE FROM t4 WHERE x = 'y';
   230    230     SELECT rowid, x FROM t4;
   231    231   } {1 x 3 z}
   232    232   do_execsql_test e_vacuum-3.1.2 {
   233    233     VACUUM;
   234    234     SELECT rowid, x FROM t4;
   235         -} {1 x 3 z}
   236         -# Was: {1 x 2 z}
          235  +} {1 x 2 z}
   237    236   
          237  +# Rowids are preserved if an INTEGER PRIMARY KEY is used
   238    238   do_execsql_test e_vacuum-3.1.3 {
   239    239     CREATE TABLE t5(x, y INTEGER PRIMARY KEY);
   240    240     INSERT INTO t5(x) VALUES('x');
   241    241     INSERT INTO t5(x) VALUES('y');
   242    242     INSERT INTO t5(x) VALUES('z');
   243    243     DELETE FROM t5 WHERE x = 'y';
   244    244     SELECT rowid, x FROM t5;
   245    245   } {1 x 3 z}
   246    246   do_execsql_test e_vacuum-3.1.4 {
   247    247     VACUUM;
   248    248     SELECT rowid, x FROM t5;
   249    249   } {1 x 3 z}
   250    250   
   251         -# EVIDENCE-OF: R-49563-33883 A VACUUM will fail if there is an open
   252         -# transaction, or if there are one or more active SQL statements when it
   253         -# is run.
          251  +# Rowid is preserved for VACUUM INTO
          252  +do_execsql_test e_vacuum-3.1.5 {
          253  +  DROP TABLE t5;
          254  +  CREATE TABLE t5(x);
          255  +  INSERT INTO t5(x) VALUES('x');
          256  +  INSERT INTO t5(x) VALUES('y');
          257  +  INSERT INTO t5(x) VALUES('z');
          258  +  DELETE FROM t5 WHERE x = 'y';
          259  +  SELECT rowid, x FROM t5;
          260  +} {1 x 3 z}
          261  +forcedelete test2.db
          262  +do_execsql_test e_vacuum-3.1.6 {
          263  +  VACUUM INTO 'test2.db';
          264  +  ATTACH 'test2.db' AS aux1;
          265  +  SELECT rowid, x FROM aux1.t5;
          266  +  DETACH aux1;
          267  +} {1 x 3 z}
          268  +
          269  +# Rowids are not renumbered if the table being vacuumed
          270  +# has indexes.
          271  +do_execsql_test e_vacuum-3.1.7 {
          272  +  DROP TABLE t5;
          273  +  CREATE TABLE t5(x,y,z);
          274  +  INSERT INTO t5(x) VALUES('x');
          275  +  INSERT INTO t5(x) VALUES('y');
          276  +  INSERT INTO t5(x) VALUES('z');
          277  +  UPDATE t5 SET y=x, z=random();
          278  +  DELETE FROM t5 WHERE x = 'y';
          279  +  CREATE INDEX t5x ON t5(x);
          280  +  CREATE UNIQUE INDEX t5y ON t5(y);
          281  +  CREATE INDEX t5zxy ON t5(z,x,y);
          282  +  SELECT rowid, x FROM t5;
          283  +} {1 x 3 z}
          284  +do_execsql_test e_vacuum-3.1.8 {
          285  +  VACUUM;
          286  +  SELECT rowid, x FROM t5;
          287  +} {1 x 3 z}
          288  +
          289  +# EVIDENCE-OF: R-12218-18073 A VACUUM will fail if there is an open
          290  +# transaction on the database connection that is attempting to run the
          291  +# VACUUM.
   254    292   #
   255    293   do_execsql_test  e_vacuum-3.2.1.1 { BEGIN } {}
   256    294   do_catchsql_test e_vacuum-3.2.1.2 { 
   257    295     VACUUM 
   258    296   } {1 {cannot VACUUM from within a transaction}}
   259    297   do_execsql_test  e_vacuum-3.2.1.3 { COMMIT } {}
   260    298   do_execsql_test  e_vacuum-3.2.1.4 { VACUUM } {}

Changes to test/fts3atoken.test.

    82     82       INSERT INTO t1(content) VALUES('There was movement at the station');
    83     83       INSERT INTO t1(content) VALUES('For the word has passed around');
    84     84       INSERT INTO t1(content) VALUES('That the colt from ol regret had got');
    85     85       SELECT content FROM t1 WHERE content MATCH 'movement'
    86     86     }
    87     87   } {{There was movement at the station}}
    88     88   
           89  +unset -nocomplain simple blah2name simplename
           90  +set simplename "simple"
           91  +set blah2name "blah2"
           92  +set simple [db one {SELECT fts3_tokenizer('simple')}]
    89     93   sqlite3_db_config db SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER 0
    90     94   do_catchsql_test 1.6 {
    91     95     SELECT fts3_tokenizer('blah', fts3_tokenizer('simple')) IS NULL;
    92     96   } {1 {fts3tokenize disabled}}
           97  +do_test fts3atoken-1.7 {
           98  +  execsql {
           99  +    SELECT fts3_tokenizer('blah2', $simple) IS NULL;
          100  +  }
          101  +} {1}
    93    102   
          103  +# With ENABLE_FTS3_TOKENIZER off, the fts3_tokenzer(1) function
          104  +# returns NULL unless the first parameter is a bound parameter.
          105  +# If the first parameter is a bound parameter, then fts3_tokenizer(1)
          106  +# returns the actual pointer value as a BLOB.
          107  +#
          108  +do_test fts3atoken-1.8 {
          109  +  execsql {
          110  +    SELECT fts3_tokenizer($blah2name) == fts3_tokenizer($simplename),
          111  +           typeof(fts3_tokenizer($blah2name)),
          112  +           typeof(fts3_tokenizer('blah2')),
          113  +           typeof(fts3_tokenizer($simplename)),
          114  +           typeof(fts3_tokenizer('simple'));
          115  +  }
          116  +} {1 blob null blob null}
          117  +
          118  +# With ENABLE_FTS3_TOKENIZER on, fts3_tokenizer() always returns
          119  +# the BLOB pointer, regardless the parameter
          120  +#
          121  +sqlite3_db_config db SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER 1
          122  +do_test fts3atoken-1.9 {
          123  +  execsql {
          124  +    SELECT fts3_tokenizer('blah2') == fts3_tokenizer('simple'),
          125  +           typeof(fts3_tokenizer($blah2name)),
          126  +           typeof(fts3_tokenizer('blah2')),
          127  +           typeof(fts3_tokenizer($simplename)),
          128  +           typeof(fts3_tokenizer('simple'));
          129  +  }
          130  +} {1 blob blob blob blob}
    94    131   
    95    132   #--------------------------------------------------------------------------
    96    133   # Test cases fts3atoken-2.* test error cases in the scalar function based
    97    134   # API for getting and setting tokenizers.
    98    135   #
    99    136   do_test fts3atoken-2.1 {
   100    137     catchsql {

Changes to test/fts3varint.test.

   106    106       576460752303423487 576460752303423488 576460752303423489 }
   107    107   do_fts3_varint_test 2.60 { 
   108    108       1152921504606846975 1152921504606846976 1152921504606846977 }
   109    109   do_fts3_varint_test 2.61 { 
   110    110       2305843009213693951 2305843009213693952 2305843009213693953 }
   111    111   do_fts3_varint_test 2.62 { 
   112    112       4611686018427387903 4611686018427387904 4611686018427387905 }
          113  +
          114  +if {![catch {fts3_test_varint 18446744073709551615}]} {
   113    115   do_fts3_varint_test 2.63 { 
   114    116       9223372036854775807 9223372036854775808 9223372036854775809 }
   115    117   
   116    118   do_fts3_varint_test 3.0 { 18446744073709551615 -18446744073709551615 }
          119  +}
   117    120   
   118    121   finish_test

Changes to test/func.test.

  1387   1387   }
  1388   1388   
  1389   1389   # Test char().
  1390   1390   #
  1391   1391   do_execsql_test func-31.1 { 
  1392   1392     SELECT char(), length(char()), typeof(char()) 
  1393   1393   } {{} 0 text}
         1394  +
         1395  +# sqlite3_value_frombind()
         1396  +#
         1397  +do_execsql_test func-32.100 {
         1398  +  SELECT test_frombind(1,2,3,4);
         1399  +} {0}
         1400  +do_execsql_test func-32.110 {
         1401  +  SELECT test_frombind(1,2,?,4);
         1402  +} {4}
         1403  +do_execsql_test func-32.120 {
         1404  +  SELECT test_frombind(1,(?),4,?+7);
         1405  +} {2}
         1406  +do_execsql_test func-32.130 {
         1407  +  DROP TABLE IF EXISTS t1;
         1408  +  CREATE TABLE t1(a,b,c,e,f);
         1409  +  INSERT INTO t1 VALUES(1,2.5,'xyz',x'e0c1b2a3',null);
         1410  +  SELECT test_frombind(a,b,c,e,f,$xyz) FROM t1;
         1411  +} {32}
         1412  +do_execsql_test func-32.140 {
         1413  +  SELECT test_frombind(a,b,c,e,f,$xyz+f) FROM t1;
         1414  +} {0}
         1415  +do_execsql_test func-32.150 {
         1416  +  SELECT test_frombind(x.a,y.b,x.c,:123,y.e,x.f,$xyz+y.f) FROM t1 x, t1 y;
         1417  +} {8}
         1418  +
         1419  +
         1420  +
         1421  +
  1394   1422   finish_test

Changes to test/fuzzdata8.db.

cannot compute difference between binary files

Changes to test/in.test.

   709    709                              WHERE name='Bob'
   710    710                            ) AS 't'
   711    711                      WHERE x=1
   712    712                    )
   713    713                AND t6.id IN (1,id)
   714    714            );
   715    715   } {1 Alice}
          716  +
          717  +#-------------------------------------------------------------------------
          718  +reset_db
          719  +do_execsql_test in-16.0 {
          720  +  CREATE TABLE x1(a, b);
          721  +  INSERT INTO x1(a) VALUES(1), (2), (3), (4), (5), (6);
          722  +  CREATE INDEX x1i ON x1(a, b);
          723  +}
          724  +
          725  +do_execsql_test in-16.1 {
          726  +  SELECT * FROM x1 
          727  +  WHERE a IN (SELECT a FROM x1 WHERE (a%2)==0) 
          728  +  ORDER BY a DESC, b;
          729  +} {6 {} 4 {} 2 {}}
          730  +
          731  +do_execsql_test in-16.2 {
          732  +  SELECT * FROM x1 
          733  +  WHERE a IN (SELECT a FROM x1 WHERE (a%7)==0) 
          734  +  ORDER BY a DESC, b;
          735  +} {}
          736  +
   716    737   
   717    738   
   718    739   finish_test

Changes to test/insert4.test.

   594    594   do_test 10.3 {
   595    595     execsql { PRAGMA integrity_check }
   596    596     set sqlite3_xferopt_count 0
   597    597     execsql { INSERT INTO x     SELECT * FROM t8 }
   598    598     set sqlite3_xferopt_count
   599    599   } {1}
   600    600   
          601  +#-------------------------------------------------------------------------
          602  +# xfer transfer between tables where the source has an empty partial index.
          603  +#
          604  +do_execsql_test 11.0 {
          605  +  CREATE TABLE t9(a, b, c);
          606  +  CREATE INDEX t9a ON t9(a);
          607  +  CREATE INDEX t9b ON t9(b) WHERE c=0;
          608  +
          609  +  INSERT INTO t9 VALUES(1, 1, 1);
          610  +  INSERT INTO t9 VALUES(2, 2, 2);
          611  +  INSERT INTO t9 VALUES(3, 3, 3);
          612  +
          613  +  CREATE TABLE t10(a, b, c);
          614  +  CREATE INDEX t10a ON t10(a);
          615  +  CREATE INDEX t10b ON t10(b) WHERE c=0;
          616  +
          617  +  INSERT INTO t10 SELECT * FROM t9;
          618  +  SELECT * FROM t10;
          619  +  PRAGMA integrity_check;
          620  +} {1 1 1  2 2 2  3 3 3  ok}
   601    621   
   602    622   finish_test

Changes to test/journal3.test.

    34     34      1 00644
    35     35      2 00666
    36     36      3 00600
    37     37      4 00755
    38     38     } {
    39     39       db close
    40     40       #set effective [format %.5o [expr $permissions & ~$umask]]
           41  +    if {$tcl_version>=8.7} {
           42  +       regsub {^00} $permissions {0o} permissions
           43  +    }
    41     44       set effective $permissions
    42     45       do_test journal3-1.2.$tn.1 {
    43     46         catch { forcedelete test.db-journal }
    44     47         file attributes test.db -permissions $permissions
    45     48         file attributes test.db -permissions
    46     49       } $permissions
    47     50       do_test journal3-1.2.$tn.2 { file exists test.db-journal } {0}

Changes to test/memdb1.test.

   182    182   } {1 {unknown option: a}}
   183    183   do_test 620 {
   184    184     set rc [catch {db serialize a b} msg]
   185    185     lappend rc $msg
   186    186   } {1 {wrong # args: should be "db serialize ?DATABASE?"}}
   187    187   
   188    188   #-------------------------------------------------------------------------
          189  +ifcapable vtab {
   189    190   reset_db
   190    191   do_execsql_test 700 {
   191    192     CREATE TABLE t1(a, b);
   192    193     PRAGMA schema_version = 0;
   193    194   }
   194    195   do_test 710 {
   195    196     set ser [db serialize main]
................................................................................
   196    197     db close
   197    198     sqlite3 db
   198    199     db deserialize main $ser
   199    200     catchsql {
   200    201       CREATE VIRTUAL TABLE t1 USING rtree(id, a, b, c, d);
   201    202     }
   202    203   } {1 {table t1 already exists}}
          204  +}
   203    205   
   204    206   finish_test

Changes to test/permutations.test.

  1064   1064   } -files [
  1065   1065     test_set [glob -nocomplain $::testdir/../ext/rbu/*.test] -exclude rbu.test
  1066   1066   ]
  1067   1067   
  1068   1068   test_suite "no_optimization" -description {
  1069   1069     Run test scripts with optimizations disabled using the
  1070   1070     sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS) interface.
  1071         -} -files {
  1072         -  where.test where2.test where3.test where4.test where5.test
  1073         -  where6.test where7.test where8.test where9.test
  1074         -  whereA.test whereB.test wherelimit.test
  1075         -  select1.test select2.test select3.test select4.test select5.test
         1071  +} -files [
         1072  +  test_set \
         1073  +    [glob -nocomplain $::testdir/window*.test]                       \
         1074  +    where.test where2.test where3.test where4.test where5.test       \
         1075  +    where6.test where7.test where8.test where9.test                  \
         1076  +    whereA.test whereB.test wherelimit.test                          \
         1077  +    select1.test select2.test select3.test select4.test select5.test \
  1076   1078     select7.test select8.test selectA.test selectC.test
  1077         -} -dbconfig {
         1079  +] -dbconfig {
  1078   1080     optimization_control $::dbhandle all 0
  1079   1081   }
  1080   1082   
  1081   1083   test_suite "prepare" -description {
  1082   1084     Run tests with the db connection using sqlite3_prepare() instead of _v2().
  1083   1085   } -dbconfig {
  1084   1086     $::dbhandle version -use-legacy-prepare 1

Changes to test/pg_common.tcl.

    36     36     }
    37     37     if {$frag != ""} {
    38     38       lappend lSql $frag
    39     39     }
    40     40     #puts $lSql
    41     41   
    42     42     set ret ""
           43  +  set nChar 0
    43     44     foreach stmt $lSql {
    44     45       set res [pg_exec $::db $stmt]
    45     46       set err [pg_result $res -error]
    46     47       if {$err!=""} { error $err }
           48  +
    47     49       for {set i 0} {$i < [pg_result $res -numTuples]} {incr i} {
    48         -      if {$i==0} {
    49         -        set ret [pg_result $res -getTuple 0]
           50  +      set t [pg_result $res -getTuple $i]
           51  +      set nNew [string length $t]
           52  +      if {$nChar>0 && ($nChar+$nNew+3)>75} {
           53  +        append ret "\n  "
           54  +        set nChar 0
    50     55         } else {
    51         -        append ret "   [pg_result $res -getTuple $i]"
           56  +        if {$nChar>0} {
           57  +          append ret "   "
           58  +          incr nChar 3
    52     59         }
    53         -      # lappend ret {*}[pg_result $res -getTuple $i]
           60  +      }
           61  +      incr nChar $nNew
           62  +      append ret $t
    54     63       }
    55     64       pg_result $res -clear
    56     65     }
    57     66   
    58     67     set ret
    59     68   }
    60     69   
    61     70   proc execsql_test {tn sql} {
    62     71     set res [execsql $sql]
    63     72     set sql [string map {string_agg group_concat} $sql]
           73  +  set sql [string map [list {NULLS FIRST} {}] $sql]
           74  +  set sql [string map [list {NULLS LAST} {}] $sql]
    64     75     puts $::fd "do_execsql_test $tn {"
    65     76     puts $::fd "  [string trim $sql]"
    66     77     puts $::fd "} {$res}"
    67     78     puts $::fd ""
    68     79   }
           80  +
           81  +proc errorsql_test {tn sql} {
           82  +  set rc [catch {execsql $sql} msg]
           83  +  if {$rc==0} {
           84  +    error "errorsql_test SQL did not cause an error!"
           85  +  }
           86  +  set msg [lindex [split [string trim $msg] "\n"] 0]
           87  +  puts $::fd "# PG says $msg"
           88  +  set sql [string map {string_agg group_concat} $sql]
           89  +  puts $::fd "do_test $tn { catch { execsql {"
           90  +  puts $::fd "  [string trim $sql]"
           91  +  puts $::fd "} } } 1"
           92  +  puts $::fd ""
           93  +}
    69     94   
    70     95   # Same as [execsql_test], except coerce all results to floating point values
    71     96   # with two decimal points.
    72     97   #
    73     98   proc execsql_float_test {tn sql} {
    74     99     set F "%.4f"
    75    100     set T 0.0001
................................................................................
    84    109   puts $::fd [subst -nocommands {
    85    110   do_test $tn {
    86    111     set myres {}
    87    112     foreach r [db eval {$sql}] {
    88    113       lappend myres [format $F [set r]]
    89    114     }
    90    115     set res2 {$res2}
          116  +  set i 0
    91    117     foreach r [set myres] r2 [set res2] {
    92    118       if {[set r]<([set r2]-$T) || [set r]>([set r2]+$T)} {
    93    119         error "list element [set i] does not match: got=[set r] expected=[set r2]"
    94    120       }
          121  +    incr i
    95    122     }
    96    123     set {} {}
    97    124   } {}
    98    125   }]
    99    126   }
   100    127   
   101    128   proc start_test {name date} {

Changes to test/pragma.test.

   247    247   } {0}
   248    248   do_test pragma-1.14.4 {
   249    249     execsql {
   250    250       PRAGMA synchronous=10;
   251    251       PRAGMA synchronous;
   252    252     }
   253    253   } {2}
          254  +
          255  +do_execsql_test 1.15.1 {
          256  +  PRAGMA default_cache_size = 0;
          257  +}
          258  +do_execsql_test 1.15.2 {
          259  +  PRAGMA default_cache_size;
          260  +} $DFLT_CACHE_SZ
          261  +do_execsql_test 1.15.3 {
          262  +  PRAGMA default_cache_size = -500;
          263  +}
          264  +do_execsql_test 1.15.4 {
          265  +  PRAGMA default_cache_size;
          266  +} 500
          267  +do_execsql_test 1.15.3 {
          268  +  PRAGMA default_cache_size = 500;
          269  +}
          270  +do_execsql_test 1.15.4 {
          271  +  PRAGMA default_cache_size;
          272  +} 500
          273  +db close
          274  +hexio_write test.db 48 FFFFFF00
          275  +sqlite3 db test.db
          276  +do_execsql_test 1.15.4 {
          277  +  PRAGMA default_cache_size;
          278  +} 256
   254    279   } ;# ifcapable pager_pragmas
   255    280   
   256    281   # Test turning "flag" pragmas on and off.
   257    282   #
   258    283   ifcapable debug {
   259    284     # Pragma "vdbe_listing" is only available if compiled with SQLITE_DEBUG
   260    285     #

Changes to test/pragma4.test.

   170    170   }
   171    171   do_test 4.3.4 { 
   172    172     sqlite3 db3 test.db
   173    173     sqlite3 db2 test.db2
   174    174     execsql { DROP INDEX i1 } db3
   175    175     execsql { DROP INDEX i2 } db2
   176    176   } {}
          177  +if {[permutation]=="prepare"} { catchsql { SELECT * FROM sqlite_master } }
   177    178   ifcapable vtab {
   178    179     do_execsql_test 4.3.5 { SELECT * FROM pragma_index_info('i1') } 
   179    180     do_execsql_test 4.3.6 { SELECT * FROM pragma_index_info('i2') } 
   180    181   }
   181    182   
   182    183   execsql {SELECT * FROM main.sqlite_master, aux.sqlite_master}
   183    184   do_execsql_test 4.4.0 {
................................................................................
   188    189     do_execsql_test 4.4.1 { SELECT * FROM pragma_index_list('t1') } {0 i1 0 c 0}
   189    190     do_execsql_test 4.4.2 { SELECT * FROM pragma_index_list('t2') } {0 i2 0 c 0}
   190    191   }
   191    192   do_test 4.4.3 { 
   192    193     execsql { DROP INDEX i1 } db3
   193    194     execsql { DROP INDEX i2 } db2
   194    195   } {}
          196  +if {[permutation]=="prepare"} { 
          197  +  catchsql { SELECT * FROM sqlite_master, aux.sqlite_master }
          198  +}
   195    199   ifcapable vtab {
   196    200     do_execsql_test 4.4.5 { SELECT * FROM pragma_index_list('t1') } {}
   197    201     do_execsql_test 4.4.6 { SELECT * FROM pragma_index_list('t2') } {}
   198    202   }
   199    203   execsql {SELECT * FROM main.sqlite_master, aux.sqlite_master}
   200    204   
   201    205   do_execsql_test 4.5.0 {
................................................................................
   212    216       0 0 t2 r d {NO ACTION} {NO ACTION} NONE
   213    217     }
   214    218   }
   215    219   do_test 4.5.3 { 
   216    220     execsql { DROP TABLE c1 } db3
   217    221     execsql { DROP TABLE c2 } db2
   218    222   } {}
          223  +if {[permutation]=="prepare"} { 
          224  +  catchsql { SELECT * FROM sqlite_master, aux.sqlite_master }
          225  +}
   219    226   ifcapable vtab {
   220    227     do_execsql_test 4.5.4 { SELECT * FROM pragma_foreign_key_list('c1') }
   221    228     do_execsql_test 4.5.5 { SELECT * FROM pragma_foreign_key_list('c2') } 
   222    229   }
   223    230   execsql {SELECT * FROM main.sqlite_master, aux.sqlite_master}
   224    231   
   225    232   do_execsql_test 4.6.0 {

Added test/releasetest_data.tcl.

            1  +
            2  +# This file contains Configuration data used by "wapptest.tcl" and
            3  +# "releasetest.tcl".
            4  +#
            5  +
            6  +# Omit comments (text between # and \n) in a long multi-line string.
            7  +#
            8  +proc strip_comments {in} {
            9  +  regsub -all {#[^\n]*\n} $in {} out
           10  +  return $out
           11  +}
           12  +
           13  +array set ::Configs [strip_comments {
           14  +  "Default" {
           15  +    -O2
           16  +    --disable-amalgamation --disable-shared
           17  +    --enable-session
           18  +    -DSQLITE_ENABLE_DESERIALIZE
           19  +  }
           20  +  "Sanitize" {
           21  +    CC=clang -fsanitize=undefined
           22  +    -DSQLITE_ENABLE_STAT4
           23  +    --enable-session
           24  +  }
           25  +  "Stdcall" {
           26  +    -DUSE_STDCALL=1
           27  +    -O2
           28  +  }
           29  +  "Have-Not" {
           30  +    # The "Have-Not" configuration sets all possible -UHAVE_feature options
           31  +    # in order to verify that the code works even on platforms that lack
           32  +    # these support services.
           33  +    -DHAVE_FDATASYNC=0
           34  +    -DHAVE_GMTIME_R=0
           35  +    -DHAVE_ISNAN=0
           36  +    -DHAVE_LOCALTIME_R=0
           37  +    -DHAVE_LOCALTIME_S=0
           38  +    -DHAVE_MALLOC_USABLE_SIZE=0
           39  +    -DHAVE_STRCHRNUL=0
           40  +    -DHAVE_USLEEP=0
           41  +    -DHAVE_UTIME=0
           42  +  }
           43  +  "Unlock-Notify" {
           44  +    -O2
           45  +    -DSQLITE_ENABLE_UNLOCK_NOTIFY
           46  +    -DSQLITE_THREADSAFE
           47  +    -DSQLITE_TCL_DEFAULT_FULLMUTEX=1
           48  +  }
           49  +  "User-Auth" {
           50  +    -O2
           51  +    -DSQLITE_USER_AUTHENTICATION=1
           52  +  }
           53  +  "Secure-Delete" {
           54  +    -O2
           55  +    -DSQLITE_SECURE_DELETE=1
           56  +    -DSQLITE_SOUNDEX=1
           57  +  }
           58  +  "Update-Delete-Limit" {
           59  +    -O2
           60  +    -DSQLITE_DEFAULT_FILE_FORMAT=4
           61  +    -DSQLITE_ENABLE_UPDATE_DELETE_LIMIT=1
           62  +    -DSQLITE_ENABLE_STMT_SCANSTATUS
           63  +    -DSQLITE_LIKE_DOESNT_MATCH_BLOBS
           64  +    -DSQLITE_ENABLE_CURSOR_HINTS
           65  +    --enable-json1
           66  +  }
           67  +  "Check-Symbols" {
           68  +    -DSQLITE_MEMDEBUG=1
           69  +    -DSQLITE_ENABLE_FTS3_PARENTHESIS=1
           70  +    -DSQLITE_ENABLE_FTS3=1
           71  +    -DSQLITE_ENABLE_RTREE=1
           72  +    -DSQLITE_ENABLE_MEMSYS5=1
           73  +    -DSQLITE_ENABLE_MEMSYS3=1
           74  +    -DSQLITE_ENABLE_COLUMN_METADATA=1
           75  +    -DSQLITE_ENABLE_UPDATE_DELETE_LIMIT=1
           76  +    -DSQLITE_SECURE_DELETE=1
           77  +    -DSQLITE_SOUNDEX=1
           78  +    -DSQLITE_ENABLE_ATOMIC_WRITE=1
           79  +    -DSQLITE_ENABLE_MEMORY_MANAGEMENT=1
           80  +    -DSQLITE_ENABLE_OVERSIZE_CELL_CHECK=1
           81  +    -DSQLITE_ENABLE_STAT4
           82  +    -DSQLITE_ENABLE_STMT_SCANSTATUS
           83  +    --enable-json1 --enable-fts5 --enable-session
           84  +  }
           85  +  "Debug-One" {
           86  +    --disable-shared
           87  +    -O2 -funsigned-char
           88  +    -DSQLITE_DEBUG=1
           89  +    -DSQLITE_MEMDEBUG=1
           90  +    -DSQLITE_MUTEX_NOOP=1
           91  +    -DSQLITE_TCL_DEFAULT_FULLMUTEX=1
           92  +    -DSQLITE_ENABLE_FTS3=1
           93  +    -DSQLITE_ENABLE_RTREE=1
           94  +    -DSQLITE_ENABLE_MEMSYS5=1
           95  +    -DSQLITE_ENABLE_COLUMN_METADATA=1
           96  +    -DSQLITE_ENABLE_STAT4
           97  +    -DSQLITE_ENABLE_HIDDEN_COLUMNS
           98  +    -DSQLITE_MAX_ATTACHED=125
           99  +    -DSQLITE_MUTATION_TEST
          100  +    --enable-fts5 --enable-json1
          101  +  }
          102  +  "Fast-One" {
          103  +    -O6
          104  +    -DSQLITE_ENABLE_FTS4=1
          105  +    -DSQLITE_ENABLE_RTREE=1
          106  +    -DSQLITE_ENABLE_STAT4
          107  +    -DSQLITE_ENABLE_RBU
          108  +    -DSQLITE_MAX_ATTACHED=125
          109  +    -DLONGDOUBLE_TYPE=double
          110  +    --enable-session
          111  +  }
          112  +  "Device-One" {
          113  +    -O2
          114  +    -DSQLITE_DEBUG=1
          115  +    -DSQLITE_DEFAULT_AUTOVACUUM=1
          116  +    -DSQLITE_DEFAULT_CACHE_SIZE=64
          117  +    -DSQLITE_DEFAULT_PAGE_SIZE=1024
          118  +    -DSQLITE_DEFAULT_TEMP_CACHE_SIZE=32
          119  +    -DSQLITE_DISABLE_LFS=1
          120  +    -DSQLITE_ENABLE_ATOMIC_WRITE=1
          121  +    -DSQLITE_ENABLE_IOTRACE=1
          122  +    -DSQLITE_ENABLE_MEMORY_MANAGEMENT=1
          123  +    -DSQLITE_MAX_PAGE_SIZE=4096
          124  +    -DSQLITE_OMIT_LOAD_EXTENSION=1
          125  +    -DSQLITE_OMIT_PROGRESS_CALLBACK=1
          126  +    -DSQLITE_OMIT_VIRTUALTABLE=1
          127  +    -DSQLITE_ENABLE_HIDDEN_COLUMNS
          128  +    -DSQLITE_TEMP_STORE=3
          129  +    --enable-json1
          130  +  }
          131  +  "Device-Two" {
          132  +    -DSQLITE_4_BYTE_ALIGNED_MALLOC=1
          133  +    -DSQLITE_DEFAULT_AUTOVACUUM=1
          134  +    -DSQLITE_DEFAULT_CACHE_SIZE=1000
          135  +    -DSQLITE_DEFAULT_LOCKING_MODE=0
          136  +    -DSQLITE_DEFAULT_PAGE_SIZE=1024
          137  +    -DSQLITE_DEFAULT_TEMP_CACHE_SIZE=1000
          138  +    -DSQLITE_DISABLE_LFS=1
          139  +    -DSQLITE_ENABLE_FTS3=1
          140  +    -DSQLITE_ENABLE_MEMORY_MANAGEMENT=1
          141  +    -DSQLITE_ENABLE_RTREE=1
          142  +    -DSQLITE_MAX_COMPOUND_SELECT=50
          143  +    -DSQLITE_MAX_PAGE_SIZE=32768
          144  +    -DSQLITE_OMIT_TRACE=1
          145  +    -DSQLITE_TEMP_STORE=3
          146  +    -DSQLITE_THREADSAFE=2
          147  +    -DSQLITE_ENABLE_DESERIALIZE=1
          148  +    --enable-json1 --enable-fts5 --enable-session
          149  +  }
          150  +  "Locking-Style" {
          151  +    -O2
          152  +    -DSQLITE_ENABLE_LOCKING_STYLE=1
          153  +  }
          154  +  "Apple" {
          155  +    -Os
          156  +    -DHAVE_GMTIME_R=1
          157  +    -DHAVE_ISNAN=1
          158  +    -DHAVE_LOCALTIME_R=1
          159  +    -DHAVE_PREAD=1
          160  +    -DHAVE_PWRITE=1
          161  +    -DHAVE_USLEEP=1
          162  +    -DHAVE_USLEEP=1
          163  +    -DHAVE_UTIME=1
          164  +    -DSQLITE_DEFAULT_CACHE_SIZE=1000
          165  +    -DSQLITE_DEFAULT_CKPTFULLFSYNC=1
          166  +    -DSQLITE_DEFAULT_MEMSTATUS=1
          167  +    -DSQLITE_DEFAULT_PAGE_SIZE=1024
          168  +    -DSQLITE_DISABLE_PAGECACHE_OVERFLOW_STATS=1
          169  +    -DSQLITE_ENABLE_API_ARMOR=1
          170  +    -DSQLITE_ENABLE_AUTO_PROFILE=1
          171  +    -DSQLITE_ENABLE_FLOCKTIMEOUT=1
          172  +    -DSQLITE_ENABLE_FTS3=1
          173  +    -DSQLITE_ENABLE_FTS3_PARENTHESIS=1
          174  +    -DSQLITE_ENABLE_FTS3_TOKENIZER=1
          175  +    if:os=="Darwin" -DSQLITE_ENABLE_LOCKING_STYLE=1
          176  +    -DSQLITE_ENABLE_PERSIST_WAL=1
          177  +    -DSQLITE_ENABLE_PURGEABLE_PCACHE=1
          178  +    -DSQLITE_ENABLE_RTREE=1
          179  +    -DSQLITE_ENABLE_SNAPSHOT=1
          180  +    # -DSQLITE_ENABLE_SQLLOG=1
          181  +    -DSQLITE_ENABLE_UPDATE_DELETE_LIMIT=1
          182  +    -DSQLITE_MAX_LENGTH=2147483645
          183  +    -DSQLITE_MAX_VARIABLE_NUMBER=500000
          184  +    # -DSQLITE_MEMDEBUG=1
          185  +    -DSQLITE_NO_SYNC=1
          186  +    -DSQLITE_OMIT_AUTORESET=1
          187  +    -DSQLITE_OMIT_LOAD_EXTENSION=1
          188  +    -DSQLITE_PREFER_PROXY_LOCKING=1
          189  +    -DSQLITE_SERIES_CONSTRAINT_VERIFY=1
          190  +    -DSQLITE_THREADSAFE=2
          191  +    -DSQLITE_USE_URI=1
          192  +    -DSQLITE_WRITE_WALFRAME_PREBUFFERED=1
          193  +    -DUSE_GUARDED_FD=1
          194  +    -DUSE_PREAD=1
          195  +    --enable-json1 --enable-fts5
          196  +  }
          197  +  "Extra-Robustness" {
          198  +    -DSQLITE_ENABLE_OVERSIZE_CELL_CHECK=1
          199  +    -DSQLITE_MAX_ATTACHED=62
          200  +  }
          201  +  "Devkit" {
          202  +    -DSQLITE_DEFAULT_FILE_FORMAT=4
          203  +    -DSQLITE_MAX_ATTACHED=30
          204  +    -DSQLITE_ENABLE_COLUMN_METADATA
          205  +    -DSQLITE_ENABLE_FTS4
          206  +    -DSQLITE_ENABLE_FTS5
          207  +    -DSQLITE_ENABLE_FTS4_PARENTHESIS
          208  +    -DSQLITE_DISABLE_FTS4_DEFERRED
          209  +    -DSQLITE_ENABLE_RTREE
          210  +    --enable-json1 --enable-fts5
          211  +  }
          212  +  "No-lookaside" {
          213  +    -DSQLITE_TEST_REALLOC_STRESS=1
          214  +    -DSQLITE_OMIT_LOOKASIDE=1
          215  +    -DHAVE_USLEEP=1
          216  +  }
          217  +  "Valgrind" {
          218  +    -DSQLITE_ENABLE_STAT4
          219  +    -DSQLITE_ENABLE_FTS4
          220  +    -DSQLITE_ENABLE_RTREE
          221  +    -DSQLITE_ENABLE_HIDDEN_COLUMNS
          222  +    --enable-json1
          223  +  }
          224  +
          225  +  # The next group of configurations are used only by the
          226  +  # Failure-Detection platform.  They are all the same, but we need
          227  +  # different names for them all so that they results appear in separate
          228  +  # subdirectories.
          229  +  #
          230  +  Fail0 {-O0}
          231  +  Fail2 {-O0}
          232  +  Fail3 {-O0}
          233  +  Fail4 {-O0}
          234  +  FuzzFail1 {-O0}
          235  +  FuzzFail2 {-O0}
          236  +}]
          237  +
          238  +array set ::Platforms [strip_comments {
          239  +  Linux-x86_64 {
          240  +    "Check-Symbols"           checksymbols
          241  +    "Fast-One"                "fuzztest test"
          242  +    "Debug-One"               "mptest test"
          243  +    "Have-Not"                test
          244  +    "Secure-Delete"           test
          245  +    "Unlock-Notify"           "QUICKTEST_INCLUDE=notify2.test test"
          246  +    "User-Auth"               tcltest
          247  +    "Update-Delete-Limit"     test
          248  +    "Extra-Robustness"        test
          249  +    "Device-Two"              test
          250  +    "No-lookaside"            test
          251  +    "Devkit"                  test
          252  +    "Apple"                   test
          253  +    "Sanitize"                {QUICKTEST_OMIT=func4.test,nan.test test}
          254  +    "Device-One"              fulltest
          255  +    "Default"                 "threadtest fulltest"
          256  +    "Valgrind"                valgrindtest
          257  +  }
          258  +  Linux-i686 {
          259  +    "Devkit"                  test
          260  +    "Have-Not"                test
          261  +    "Unlock-Notify"           "QUICKTEST_INCLUDE=notify2.test test"
          262  +    "Device-One"              test
          263  +    "Device-Two"              test
          264  +    "Default"                 "threadtest fulltest"
          265  +  }
          266  +  Darwin-i386 {
          267  +    "Locking-Style"           "mptest test"
          268  +    "Have-Not"                test
          269  +    "Apple"                   "threadtest fulltest"
          270  +  }
          271  +  Darwin-x86_64 {
          272  +    "Locking-Style"           "mptest test"
          273  +    "Have-Not"                test
          274  +    "Apple"                   "threadtest fulltest"
          275  +  }
          276  +  "Windows NT-intel" {
          277  +    "Stdcall"                 test
          278  +    "Have-Not"                test
          279  +    "Default"                 "mptest fulltestonly"
          280  +  }
          281  +  "Windows NT-amd64" {
          282  +    "Stdcall"                 test
          283  +    "Have-Not"                test
          284  +    "Default"                 "mptest fulltestonly"
          285  +  }
          286  +
          287  +  # The Failure-Detection platform runs various tests that deliberately
          288  +  # fail.  This is used as a test of this script to verify that this script
          289  +  # correctly identifies failures.
          290  +  #
          291  +  Failure-Detection {
          292  +    Fail0     "TEST_FAILURE=0 test"
          293  +    Sanitize  "TEST_FAILURE=1 test"
          294  +    Fail2     "TEST_FAILURE=2 valgrindtest"
          295  +    Fail3     "TEST_FAILURE=3 valgrindtest"
          296  +    Fail4     "TEST_FAILURE=4 test"
          297  +    FuzzFail1 "TEST_FAILURE=5 test"
          298  +    FuzzFail2 "TEST_FAILURE=5 valgrindtest"
          299  +  }
          300  +}]
          301  +
          302  +proc make_test_suite {msvc withtcl name testtarget config} {
          303  +
          304  +  # Tcl variable $opts is used to build up the value used to set the
          305  +  # OPTS Makefile variable. Variable $cflags holds the value for
          306  +  # CFLAGS. The makefile will pass OPTS to both gcc and lemon, but
          307  +  # CFLAGS is only passed to gcc.
          308  +  #
          309  +  set makeOpts ""
          310  +  set cflags [expr {$msvc ? "-Zi" : "-g"}]
          311  +  set opts ""
          312  +  set title ${name}($testtarget)
          313  +  set configOpts $withtcl
          314  +  set skip 0
          315  +
          316  +  regsub -all {#[^\n]*\n} $config \n config
          317  +  foreach arg $config {
          318  +    if {$skip} {
          319  +      set skip 0
          320  +      continue
          321  +    }
          322  +    if {[regexp {^-[UD]} $arg]} {
          323  +      lappend opts $arg
          324  +    } elseif {[regexp {^[A-Z]+=} $arg]} {
          325  +      lappend testtarget $arg
          326  +    } elseif {[regexp {^if:([a-z]+)(.*)} $arg all key tail]} {
          327  +      # Arguments of the form 'if:os=="Linux"' will cause the subsequent
          328  +      # argument to be skipped if the $tcl_platform(os) is not "Linux", for
          329  +      # example...
          330  +      set skip [expr !(\$::tcl_platform($key)$tail)]
          331  +    } elseif {[regexp {^--(enable|disable)-} $arg]} {
          332  +      if {$msvc} {
          333  +        if {$arg eq "--disable-amalgamation"} {
          334  +          lappend makeOpts USE_AMALGAMATION=0
          335  +          continue
          336  +        }
          337  +        if {$arg eq "--disable-shared"} {
          338  +          lappend makeOpts USE_CRT_DLL=0 DYNAMIC_SHELL=0
          339  +          continue
          340  +        }
          341  +        if {$arg eq "--enable-fts5"} {
          342  +          lappend opts -DSQLITE_ENABLE_FTS5
          343  +          continue
          344  +        }
          345  +        if {$arg eq "--enable-json1"} {
          346  +          lappend opts -DSQLITE_ENABLE_JSON1
          347  +          continue
          348  +        }
          349  +        if {$arg eq "--enable-shared"} {
          350  +          lappend makeOpts USE_CRT_DLL=1 DYNAMIC_SHELL=1
          351  +          continue
          352  +        }
          353  +      }
          354  +      lappend configOpts $arg
          355  +    } else {
          356  +      if {$msvc} {
          357  +        if {$arg eq "-g"} {
          358  +          lappend cflags -Zi
          359  +          continue
          360  +        }
          361  +        if {[regexp -- {^-O(\d+)$} $arg all level]} then {
          362  +          lappend makeOpts OPTIMIZATIONS=$level
          363  +          continue
          364  +        }
          365  +      }
          366  +      lappend cflags $arg
          367  +    }
          368  +  }
          369  +
          370  +  # Disable sync to make testing faster.
          371  +  #
          372  +  lappend opts -DSQLITE_NO_SYNC=1
          373  +
          374  +  # Some configurations already set HAVE_USLEEP; in that case, skip it.
          375  +  #
          376  +  if {[lsearch -regexp $opts {^-DHAVE_USLEEP(?:=|$)}]==-1} {
          377  +    lappend opts -DHAVE_USLEEP=1
          378  +  }
          379  +
          380  +  # Add the define for this platform.
          381  +  #
          382  +  if {$::tcl_platform(platform)=="windows"} {
          383  +    lappend opts -DSQLITE_OS_WIN=1
          384  +  } else {
          385  +    lappend opts -DSQLITE_OS_UNIX=1
          386  +  }
          387  +
          388  +  # Set the sub-directory to use.
          389  +  #
          390  +  set dir [string tolower [string map {- _ " " _ "(" _ ")" _} $name]]
          391  +
          392  +  # Join option lists into strings, using space as delimiter.
          393  +  #
          394  +  set makeOpts [join $makeOpts " "]
          395  +  set cflags   [join $cflags " "]
          396  +  set opts     [join $opts " "]
          397  +
          398  +  return [list $title $dir $configOpts $testtarget $makeOpts $cflags $opts]
          399  +}
          400  +
          401  +# Configuration verification: Check that each entry in the list of configs
          402  +# specified for each platforms exists.
          403  +#
          404  +foreach {key value} [array get ::Platforms] {
          405  +  foreach {v t} $value {
          406  +    if {0==[info exists ::Configs($v)]} {
          407  +      puts stderr "No such configuration: \"$v\""
          408  +      exit -1
          409  +    }
          410  +  }
          411  +}
          412  +

Changes to test/shell1.test.

  1018   1018       #       command channels opened for it as textual ones), the carriage
  1019   1019       #       return character (and on Windows, the end-of-file character)
  1020   1020       #       cannot be used here.
  1021   1021       #
  1022   1022       if {$i==0x0D || ($tcl_platform(platform)=="windows" && $i==0x1A)} {
  1023   1023         continue
  1024   1024       }
         1025  +    # Tcl 8.7 maps 0x80 through 0x9f into valid UTF8.  So skip those tests.
         1026  +    if {$i>=0x80 && $i<=0x9f} continue
  1025   1027       if {$i>=0xE0 && $tcl_platform(os)=="OpenBSD"}  continue
  1026   1028       if {$i>=0xE0 && $i<=0xEF && $tcl_platform(os)=="Linux"}  continue
  1027   1029       set hex [format %02X $i]
  1028   1030       set char [subst \\x$hex]; set oldChar $char
  1029   1031       set escapes [list]
  1030   1032       if {$tcl_platform(platform)=="windows"} {
  1031   1033         #

Changes to test/skipscan1.test.

   340    340   
   341    341   optimization_control db skip-scan 0
   342    342   do_execsql_test skipscan1-9.3 {
   343    343     EXPLAIN QUERY PLAN
   344    344     SELECT  * FROM t9a WHERE b IN (SELECT x FROM t9b WHERE y!=5);
   345    345   } {/{SCAN TABLE t9a}/}
   346    346   optimization_control db skip-scan 1
          347  +
          348  +do_execsql_test skipscan1-2.1 {
          349  +  CREATE TABLE t6(a TEXT, b INT, c INT, d INT);
          350  +  CREATE INDEX t6abc ON t6(a,b,c);
          351  +  INSERT INTO t6 VALUES('abc',123,4,5);
          352  +
          353  +  ANALYZE;
          354  +  DELETE FROM sqlite_stat1;
          355  +  INSERT INTO sqlite_stat1 VALUES('t6','t6abc','10000 5000 2000 10');
          356  +  ANALYZE sqlite_master;
          357  +  DELETE FROM t6;
          358  +} {}
          359  +
          360  +do_execsql_test skipscan1-2.2eqp {
          361  +  EXPLAIN QUERY PLAN
          362  +  SELECT a,b,c,d,'|' FROM t6 WHERE d<>99 AND b=345 ORDER BY a;
          363  +} {/* USING INDEX t6abc (ANY(a) AND b=?)*/}
          364  +do_execsql_test skipscan1-2.2 {
          365  +  SELECT a,b,c,d,'|' FROM t6 WHERE d<>99 AND b=345 ORDER BY a;
          366  +} {}
          367  +
          368  +do_execsql_test skipscan1-2.3eqp {
          369  +  EXPLAIN QUERY PLAN
          370  +  SELECT a,b,c,d,'|' FROM t6 WHERE d<>99 AND b=345 ORDER BY a DESC;
          371  +} {/* USING INDEX t6abc (ANY(a) AND b=?)*/}
          372  +do_execsql_test skipscan1-2.3 {
          373  +  SELECT a,b,c,d,'|' FROM t6 WHERE d<>99 AND b=345 ORDER BY a DESC;
          374  +} {}
   347    375   
   348    376   finish_test

Changes to test/skipscan2.test.

   196    196       execsql { INSERT INTO t3 VALUES($i%2, $i, 'xyz') }
   197    197     }
   198    198     execsql { ANALYZE }
   199    199   } {}
   200    200   do_eqp_test skipscan2-3.3eqp {
   201    201     SELECT * FROM t3 WHERE b=42;
   202    202   } {SEARCH TABLE t3 USING PRIMARY KEY (ANY(a) AND b=?)}
          203  +
   203    204   
   204    205   
   205    206   finish_test

Changes to test/sqllimits1.test.

   885    885     ))))
   886    886   } "1 {too many columns in result set}"
   887    887   
   888    888   
   889    889   foreach {key value} [array get saved] {
   890    890     catch {set $key $value}
   891    891   }
          892  +
          893  +#-------------------------------------------------------------------------
          894  +# At one point the following caused an assert() to fail.
          895  +#
          896  +sqlite3_limit db SQLITE_LIMIT_LENGTH 10000
          897  +set nm [string repeat x 10000]
          898  +do_catchsql_test sqllimits1-17.1 "
          899  +  CREATE TABLE $nm (x PRIMARY KEY)
          900  +" {1 {string or blob too big}}
          901  +
   892    902   finish_test

Changes to test/tester.tcl.

   572    572       set ::G(output_fd) [open $cmdlinearg(output) w]
   573    573       fconfigure $::G(output_fd) -buffering line
   574    574     }
   575    575   
   576    576     if {$cmdlinearg(verbose)==""} {
   577    577       set cmdlinearg(verbose) 1
   578    578     }
          579  +
          580  +  if {[info commands vdbe_coverage]!=""} {
          581  +    vdbe_coverage start
          582  +  }
   579    583   }
   580    584   
   581    585   # Update the soft-heap-limit each time this script is run. In that
   582    586   # way if an individual test file changes the soft-heap-limit, it
   583    587   # will be reset at the start of the next test file.
   584    588   #
   585    589   sqlite3_soft_heap_limit $cmdlinearg(soft-heap-limit)
................................................................................
  1292   1296       sqlite3_memdebug_log stop
  1293   1297       sqlite3_memdebug_log clear
  1294   1298       if {[sqlite3_memory_used]>0} {
  1295   1299         output2 "Writing leaks.tcl..."
  1296   1300         sqlite3_memdebug_log sync
  1297   1301         memdebug_log_sql leaks.tcl
  1298   1302       }
         1303  +  }
         1304  +  if {[info commands vdbe_coverage]!=""} {
         1305  +    vdbe_coverage_report
  1299   1306     }
  1300   1307     foreach f [glob -nocomplain test.db-*-journal] {
  1301   1308       forcedelete $f
  1302   1309     }
  1303   1310     foreach f [glob -nocomplain test.db-mj*] {
  1304   1311       forcedelete $f
  1305   1312     }
  1306   1313     exit [expr {$nErr>0}]
  1307   1314   }
         1315  +
         1316  +proc vdbe_coverage_report {} {
         1317  +  puts "Writing vdbe coverage report to vdbe_coverage.txt"
         1318  +  set lSrc [list]
         1319  +  set iLine 0
         1320  +  if {[file exists ../sqlite3.c]} {
         1321  +    set fd [open ../sqlite3.c]
         1322  +    set iLine
         1323  +    while { ![eof $fd] } {
         1324  +      set line [gets $fd]
         1325  +      incr iLine
         1326  +      if {[regexp {^/\** Begin file (.*\.c) \**/} $line -> file]} {
         1327  +        lappend lSrc [list $iLine $file]
         1328  +      }
         1329  +    }
         1330  +    close $fd
         1331  +  }
         1332  +  set fd [open vdbe_coverage.txt w]
         1333  +  foreach miss [vdbe_coverage report] {
         1334  +    foreach {line branch never} $miss {}
         1335  +    set nextfile ""
         1336  +    while {[llength $lSrc]>0 && [lindex $lSrc 0 0] < $line} {
         1337  +      set nextfile [lindex $lSrc 0 1]
         1338  +      set lSrc [lrange $lSrc 1 end]
         1339  +    }
         1340  +    if {$nextfile != ""} {
         1341  +      puts $fd ""
         1342  +      puts $fd "### $nextfile ###"
         1343  +    }
         1344  +    puts $fd "Vdbe branch $line: never $never (path $branch)"
         1345  +  }
         1346  +  close $fd
         1347  +}
  1308   1348   
  1309   1349   # Display memory statistics for analysis and debugging purposes.
  1310   1350   #
  1311   1351   proc show_memstats {} {
  1312   1352     set x [sqlite3_status SQLITE_STATUS_MEMORY_USED 0]
  1313   1353     set y [sqlite3_status SQLITE_STATUS_MALLOC_SIZE 0]
  1314   1354     set val [format {now %10d  max %10d  max-size %10d} \

Changes to test/triggerC.test.

  1052   1052   } {1 {1st ORDER BY term does not match any column in the result set}}
  1053   1053   
  1054   1054   do_catchsql_test 16.2 {
  1055   1055     SELECT count(*) FROM sqlite_master 
  1056   1056     GROUP BY raise(IGNORE) 
  1057   1057     HAVING raise(ABORT, 'msg');
  1058   1058   } {1 {RAISE() may only be used within a trigger-program}}
         1059  +
         1060  +#-------------------------------------------------------------------------
         1061  +# Datatype mismatch on IPK when there are BEFORE triggers.
         1062  +#
         1063  +do_execsql_test 17.0 {
         1064  +  CREATE TABLE xyz(x INTEGER PRIMARY KEY, y, z);
         1065  +  CREATE TRIGGER xyz_tr BEFORE INSERT ON xyz BEGIN
         1066  +    SELECT new.x;
         1067  +  END;
         1068  +}
         1069  +do_catchsql_test 17.1 {
         1070  +  INSERT INTO xyz VALUES('hello', 2, 3);
         1071  +} {1 {datatype mismatch}}
         1072  +
  1059   1073   
  1060   1074   finish_test
  1061   1075   

Changes to test/wal2.test.

  1044   1044      2 00666
  1045   1045      3 00600
  1046   1046      4 00755
  1047   1047     } {
  1048   1048       set effective [format %.5o [expr $permissions & ~$umask]]
  1049   1049       do_test wal2-12.2.$tn.1 {
  1050   1050         file attributes test.db -permissions $permissions
  1051         -      file attributes test.db -permissions
         1051  +      string map {o 0} [file attributes test.db -permissions]
  1052   1052       } $permissions
  1053   1053       do_test wal2-12.2.$tn.2 {
  1054   1054         list [file exists test.db-wal] [file exists test.db-shm]
  1055   1055       } {0 0}
  1056   1056       do_test wal2-12.2.$tn.3 {
  1057   1057         sqlite3 db test.db
  1058   1058         execsql { INSERT INTO tx DEFAULT VALUES }
  1059   1059         list [file exists test.db-wal] [file exists test.db-shm]
  1060   1060       } {1 1}
  1061   1061       do_test wal2-12.2.$tn.4 {
  1062         -      list [file attr test.db-wal -perm] [file attr test.db-shm -perm]
         1062  +      set x [list [file attr test.db-wal -perm] [file attr test.db-shm -perm]]
         1063  +      string map {o 0} $x
  1063   1064       } [list $effective $effective]
  1064   1065       do_test wal2-12.2.$tn.5 {
  1065   1066         db close
  1066   1067         list [file exists test.db-wal] [file exists test.db-shm]
  1067   1068       } {0 0}
  1068   1069     }
  1069   1070   }
................................................................................
  1113   1114         file attr test.db     -perm $db_perm
  1114   1115         file attr test.db-wal -perm $wal_perm
  1115   1116         file attr test.db-shm -perm $shm_perm
  1116   1117   
  1117   1118         set     L [file attr test.db -perm]
  1118   1119         lappend L [file attr test.db-wal -perm]
  1119   1120         lappend L [file attr test.db-shm -perm]
         1121  +      string map {o 0} $L
  1120   1122       } [list $db_perm $wal_perm $shm_perm]
  1121   1123   
  1122   1124       # If $can_open is true, then it should be possible to open a database
  1123   1125       # handle. Otherwise, if $can_open is 0, attempting to open the db
  1124   1126       # handle throws an "unable to open database file" exception.
  1125   1127       #
  1126   1128       set r(1) {0 ok}

Added test/wapp.tcl.

            1  +# Copyright (c) 2017 D. Richard Hipp
            2  +# 
            3  +# This program is free software; you can redistribute it and/or
            4  +# modify it under the terms of the Simplified BSD License (also
            5  +# known as the "2-Clause License" or "FreeBSD License".)
            6  +#
            7  +# This program is distributed in the hope that it will be useful,
            8  +# but without any warranty; without even the implied warranty of
            9  +# merchantability or fitness for a particular purpose.
           10  +#
           11  +#---------------------------------------------------------------------------
           12  +#
           13  +# Design rules:
           14  +#
           15  +#   (1)  All identifiers in the global namespace begin with "wapp"
           16  +#
           17  +#   (2)  Indentifiers intended for internal use only begin with "wappInt"
           18  +#
           19  +package require Tcl 8.6
           20  +
           21  +# Add text to the end of the HTTP reply.  No interpretation or transformation
           22  +# of the text is performs.  The argument should be enclosed within {...}
           23  +#
           24  +proc wapp {txt} {
           25  +  global wapp
           26  +  dict append wapp .reply $txt
           27  +}
           28  +
           29  +# Add text to the page under construction.  Do no escaping on the text.
           30  +#
           31  +# Though "unsafe" in general, there are uses for this kind of thing.
           32  +# For example, if you want to return the complete, unmodified content of
           33  +# a file:
           34  +#
           35  +#         set fd [open content.html rb]
           36  +#         wapp-unsafe [read $fd]
           37  +#         close $fd
           38  +#
           39  +# You could do the same thing using ordinary "wapp" instead of "wapp-unsafe".
           40  +# The difference is that wapp-safety-check will complain about the misuse
           41  +# of "wapp", but it assumes that the person who write "wapp-unsafe" understands
           42  +# the risks.
           43  +#
           44  +# Though occasionally necessary, the use of this interface should be minimized.
           45  +#
           46  +proc wapp-unsafe {txt} {
           47  +  global wapp
           48  +  dict append wapp .reply $txt
           49  +}
           50  +
           51  +# Add text to the end of the reply under construction.  The following
           52  +# substitutions are made:
           53  +#
           54  +#     %html(...)          Escape text for inclusion in HTML
           55  +#     %url(...)           Escape text for use as a URL
           56  +#     %qp(...)            Escape text for use as a URI query parameter
           57  +#     %string(...)        Escape text for use within a JSON string
           58  +#     %unsafe(...)        No transformations of the text
           59  +#
           60  +# The substitutions above terminate at the first ")" character.  If the
           61  +# text of the TCL string in ... contains ")" characters itself, use instead:
           62  +#
           63  +#     %html%(...)%
           64  +#     %url%(...)%
           65  +#     %qp%(...)%
           66  +#     %string%(...)%
           67  +#     %unsafe%(...)%
           68  +#
           69  +# In other words, use "%(...)%" instead of "(...)" to include the TCL string
           70  +# to substitute.
           71  +#
           72  +# The %unsafe substitution should be avoided whenever possible, obviously.
           73  +# In addition to the substitutions above, the text also does backslash
           74  +# escapes.
           75  +#
           76  +# The wapp-trim proc works the same as wapp-subst except that it also removes
           77  +# whitespace from the left margin, so that the generated HTML/CSS/Javascript
           78  +# does not appear to be indented when delivered to the client web browser.
           79  +#
           80  +if {$tcl_version>=8.7} {
           81  +  proc wapp-subst {txt} {
           82  +    global wapp
           83  +    regsub -all -command \
           84  +       {%(html|url|qp|string|unsafe){1,1}?(|%)\((.+)\)\2} $txt wappInt-enc txt
           85  +    dict append wapp .reply [subst -novariables -nocommand $txt]
           86  +  }
           87  +  proc wapp-trim {txt} {
           88  +    global wapp
           89  +    regsub -all {\n\s+} [string trim $txt] \n txt
           90  +    regsub -all -command \
           91  +       {%(html|url|qp|string|unsafe){1,1}?(|%)\((.+)\)\2} $txt wappInt-enc txt
           92  +    dict append wapp .reply [subst -novariables -nocommand $txt]
           93  +  }
           94  +  proc wappInt-enc {all mode nu1 txt} {
           95  +    return [uplevel 2 "wappInt-enc-$mode \"$txt\""]
           96  +  }
           97  +} else {
           98  +  proc wapp-subst {txt} {
           99  +    global wapp
          100  +    regsub -all {%(html|url|qp|string|unsafe){1,1}?(|%)\((.+)\)\2} $txt \
          101  +           {[wappInt-enc-\1 "\3"]} txt
          102  +    dict append wapp .reply [uplevel 1 [list subst -novariables $txt]]
          103  +  }
          104  +  proc wapp-trim {txt} {
          105  +    global wapp
          106  +    regsub -all {\n\s+} [string trim $txt] \n txt
          107  +    regsub -all {%(html|url|qp|string|unsafe){1,1}?(|%)\((.+)\)\2} $txt \
          108  +           {[wappInt-enc-\1 "\3"]} txt
          109  +    dict append wapp .reply [uplevel 1 [list subst -novariables $txt]]
          110  +  }
          111  +}
          112  +
          113  +# There must be a wappInt-enc-NAME routine for each possible substitution
          114  +# in wapp-subst.  Thus there are routines for "html", "url", "qp", and "unsafe".
          115  +#
          116  +#    wappInt-enc-html           Escape text so that it is safe to use in the
          117  +#                               body of an HTML document.
          118  +#
          119  +#    wappInt-enc-url            Escape text so that it is safe to pass as an
          120  +#                               argument to href= and src= attributes in HTML.
          121  +#
          122  +#    wappInt-enc-qp             Escape text so that it is safe to use as the
          123  +#                               value of a query parameter in a URL or in
          124  +#                               post data or in a cookie.
          125  +#
          126  +#    wappInt-enc-string         Escape ", ', \, and < for using inside of a
          127  +#                               javascript string literal.  The < character
          128  +#                               is escaped to prevent "</script>" from causing
          129  +#                               problems in embedded javascript.
          130  +#
          131  +#    wappInt-enc-unsafe         Perform no encoding at all.  Unsafe.
          132  +#
          133  +proc wappInt-enc-html {txt} {
          134  +  return [string map {& &amp; < &lt; > &gt; \" &quot; \\ &#92;} $txt]
          135  +}
          136  +proc wappInt-enc-unsafe {txt} {
          137  +  return $txt
          138  +}
          139  +proc wappInt-enc-url {s} {
          140  +  if {[regsub -all {[^-{}@~?=#_.:/a-zA-Z0-9]} $s {[wappInt-%HHchar {&}]} s]} {
          141  +    set s [subst -novar -noback $s]
          142  +  }
          143  +  if {[regsub -all {[{}]} $s {[wappInt-%HHchar \\&]} s]} {
          144  +    set s [subst -novar -noback $s]
          145  +  }
          146  +  return $s
          147  +}
          148  +proc wappInt-enc-qp {s} {
          149  +  if {[regsub -all {[^-{}_.a-zA-Z0-9]} $s {[wappInt-%HHchar {&}]} s]} {
          150  +    set s [subst -novar -noback $s]
          151  +  }
          152  +  if {[regsub -all {[{}]} $s {[wappInt-%HHchar \\&]} s]} {
          153  +    set s [subst -novar -noback $s]
          154  +  }
          155  +  return $s
          156  +}
          157  +proc wappInt-enc-string {s} {
          158  +  return [string map {\\ \\\\ \" \\\" ' \\' < \\u003c} $s]
          159  +}
          160  +
          161  +# This is a helper routine for wappInt-enc-url and wappInt-enc-qp.  It returns
          162  +# an appropriate %HH encoding for the single character c.  If c is a unicode
          163  +# character, then this routine might return multiple bytes:  %HH%HH%HH
          164  +#
          165  +proc wappInt-%HHchar {c} {
          166  +  if {$c==" "} {return +}
          167  +  return [regsub -all .. [binary encode hex [encoding convertto utf-8 $c]] {%&}]
          168  +}
          169  +
          170  +
          171  +# Undo the www-url-encoded format.
          172  +#
          173  +# HT: This code stolen from ncgi.tcl
          174  +#
          175  +proc wappInt-decode-url {str} {
          176  +  set str [string map [list + { } "\\" "\\\\" \[ \\\[ \] \\\]] $str]
          177  +  regsub -all -- \
          178  +      {%([Ee][A-Fa-f0-9])%([89ABab][A-Fa-f0-9])%([89ABab][A-Fa-f0-9])} \
          179  +      $str {[encoding convertfrom utf-8 [binary decode hex \1\2\3]]} str
          180  +  regsub -all -- \
          181  +      {%([CDcd][A-Fa-f0-9])%([89ABab][A-Fa-f0-9])}                     \
          182  +      $str {[encoding convertfrom utf-8 [binary decode hex \1\2]]} str
          183  +  regsub -all -- {%([0-7][A-Fa-f0-9])} $str {\\u00\1} str
          184  +  return [subst -novar $str]
          185  +}
          186  +
          187  +# Reset the document back to an empty string.
          188  +#
          189  +proc wapp-reset {} {
          190  +  global wapp
          191  +  dict set wapp .reply {}
          192  +}
          193  +
          194  +# Change the mime-type of the result document.
          195  +#
          196  +proc wapp-mimetype {x} {
          197  +  global wapp
          198  +  dict set wapp .mimetype $x
          199  +}
          200  +
          201  +# Change the reply code.
          202  +#
          203  +proc wapp-reply-code {x} {
          204  +  global wapp
          205  +  dict set wapp .reply-code $x
          206  +}
          207  +
          208  +# Set a cookie
          209  +#
          210  +proc wapp-set-cookie {name value} {
          211  +  global wapp
          212  +  dict lappend wapp .new-cookies $name $value
          213  +}
          214  +
          215  +# Unset a cookie
          216  +#
          217  +proc wapp-clear-cookie {name} {
          218  +  wapp-set-cookie $name {}
          219  +}
          220  +
          221  +# Add extra entries to the reply header
          222  +#
          223  +proc wapp-reply-extra {name value} {
          224  +  global wapp
          225  +  dict lappend wapp .reply-extra $name $value
          226  +}
          227  +
          228  +# Specifies how the web-page under construction should be cached.
          229  +# The argument should be one of:
          230  +#
          231  +#    no-cache
          232  +#    max-age=N             (for some integer number of seconds, N)
          233  +#    private,max-age=N
          234  +#
          235  +proc wapp-cache-control {x} {
          236  +  wapp-reply-extra Cache-Control $x
          237  +}
          238  +
          239  +# Redirect to a different web page
          240  +#
          241  +proc wapp-redirect {uri} {
          242  +  wapp-reply-code {307 Redirect}
          243  +  wapp-reply-extra Location $uri
          244  +}
          245  +
          246  +# Return the value of a wapp parameter
          247  +#
          248  +proc wapp-param {name {dflt {}}} {
          249  +  global wapp
          250  +  if {![dict exists $wapp $name]} {return $dflt}
          251  +  return [dict get $wapp $name]
          252  +}
          253  +
          254  +# Return true if a and only if the wapp parameter $name exists
          255  +#
          256  +proc wapp-param-exists {name} {
          257  +  global wapp
          258  +  return [dict exists $wapp $name]
          259  +}
          260  +
          261  +# Set the value of a wapp parameter
          262  +#
          263  +proc wapp-set-param {name value} {
          264  +  global wapp
          265  +  dict set wapp $name $value
          266  +}
          267  +
          268  +# Return all parameter names that match the GLOB pattern, or all
          269  +# names if the GLOB pattern is omitted.
          270  +#
          271  +proc wapp-param-list {{glob {*}}} {
          272  +  global wapp
          273  +  return [dict keys $wapp $glob]
          274  +}
          275  +
          276  +# By default, Wapp does not decode query parameters and POST parameters
          277  +# for cross-origin requests.  This is a security restriction, designed to
          278  +# help prevent cross-site request forgery (CSRF) attacks.
          279  +#
          280  +# As a consequence of this restriction, URLs for sites generated by Wapp
          281  +# that contain query parameters will not work as URLs found in other
          282  +# websites.  You cannot create a link from a second website into a Wapp
          283  +# website if the link contains query planner, by default.
          284  +#
          285  +# Of course, it is sometimes desirable to allow query parameters on external
          286  +# links.  For URLs for which this is safe, the application should invoke
          287  +# wapp-allow-xorigin-params.  This procedure tells Wapp that it is safe to
          288  +# go ahead and decode the query parameters even for cross-site requests.
          289  +#
          290  +# In other words, for Wapp security is the default setting.  Individual pages
          291  +# need to actively disable the cross-site request security if those pages
          292  +# are safe for cross-site access.
          293  +#
          294  +proc wapp-allow-xorigin-params {} {
          295  +  global wapp
          296  +  if {![dict exists $wapp .qp] && ![dict get $wapp SAME_ORIGIN]} {
          297  +    wappInt-decode-query-params
          298  +  }
          299  +}
          300  +
          301  +# Set the content-security-policy.
          302  +#
          303  +# The default content-security-policy is very strict:  "default-src 'self'"
          304  +# The default policy prohibits the use of in-line javascript or CSS.
          305  +#
          306  +# Provide an alternative CSP as the argument.  Or use "off" to disable
          307  +# the CSP completely.
          308  +#
          309  +proc wapp-content-security-policy {val} {
          310  +  global wapp
          311  +  if {$val=="off"} {
          312  +    dict unset wapp .csp
          313  +  } else {
          314  +    dict set wapp .csp $val
          315  +  }
          316  +}
          317  +
          318  +# Examine the bodys of all procedures in this program looking for
          319  +# unsafe calls to various Wapp interfaces.  Return a text string
          320  +# containing warnings. Return an empty string if all is ok.
          321  +#
          322  +# This routine is advisory only.  It misses some constructs that are
          323  +# dangerous and flags others that are safe.
          324  +#
          325  +proc wapp-safety-check {} {
          326  +  set res {}
          327  +  foreach p [info procs] {
          328  +    set ln 0
          329  +    foreach x [split [info body $p] \n] {
          330  +      incr ln
          331  +      if {[regexp {^[ \t]*wapp[ \t]+([^\n]+)} $x all tail]
          332  +       && [string index $tail 0]!="\173"
          333  +       && [regexp {[[$]} $tail]
          334  +      } {
          335  +        append res "$p:$ln: unsafe \"wapp\" call: \"[string trim $x]\"\n"
          336  +      }
          337  +      if {[regexp {^[ \t]*wapp-(subst|trim)[ \t]+[^\173]} $x all cx]} {
          338  +        append res "$p:$ln: unsafe \"wapp-$cx\" call: \"[string trim $x]\"\n"
          339  +      }
          340  +    }
          341  +  }
          342  +  return $res
          343  +}
          344  +
          345  +# Return a string that descripts the current environment.  Applications
          346  +# might find this useful for debugging.
          347  +#
          348  +proc wapp-debug-env {} {
          349  +  global wapp
          350  +  set out {}
          351  +  foreach var [lsort [dict keys $wapp]] {
          352  +    if {[string index $var 0]=="."} continue
          353  +    append out "$var = [list [dict get $wapp $var]]\n"
          354  +  }
          355  +  append out "\[pwd\] = [list [pwd]]\n"
          356  +  return $out
          357  +}
          358  +
          359  +# Tracing function for each HTTP request.  This is overridden by wapp-start
          360  +# if tracing is enabled.
          361  +#
          362  +proc wappInt-trace {} {}
          363  +
          364  +# Start up a listening socket.  Arrange to invoke wappInt-new-connection
          365  +# for each inbound HTTP connection.
          366  +#
          367  +#    port            Listen on this TCP port.  0 means to select a port
          368  +#                    that is not currently in use
          369  +#
          370  +#    wappmode        One of "scgi", "remote-scgi", "server", or "local".
          371  +#
          372  +#    fromip          If not {}, then reject all requests from IP addresses
          373  +#                    other than $fromip
          374  +#
          375  +proc wappInt-start-listener {port wappmode fromip} {
          376  +  if {[string match *scgi $wappmode]} {
          377  +    set type SCGI
          378  +    set server [list wappInt-new-connection \
          379  +                wappInt-scgi-readable $wappmode $fromip]
          380  +  } else {
          381  +    set type HTTP
          382  +    set server [list wappInt-new-connection \
          383  +                wappInt-http-readable $wappmode $fromip]
          384  +  }
          385  +  if {$wappmode=="local" || $wappmode=="scgi"} {
          386  +    set x [socket -server $server -myaddr 127.0.0.1 $port]
          387  +  } else {
          388  +    set x [socket -server $server $port]
          389  +  }
          390  +  set coninfo [chan configure $x -sockname]
          391  +  set port [lindex $coninfo 2]
          392  +  if {$wappmode=="local"} {
          393  +    wappInt-start-browser http://127.0.0.1:$port/
          394  +  } elseif {$fromip!=""} {
          395  +    puts "Listening for $type requests on TCP port $port from IP $fromip"
          396  +  } else {
          397  +    puts "Listening for $type requests on TCP port $port"
          398  +  }
          399  +}
          400  +
          401  +# Start a web-browser and point it at $URL
          402  +#
          403  +proc wappInt-start-browser {url} {
          404  +  global tcl_platform
          405  +  if {$tcl_platform(platform)=="windows"} {
          406  +    exec cmd /c start $url &
          407  +  } elseif {$tcl_platform(os)=="Darwin"} {
          408  +    exec open $url &
          409  +  } elseif {[catch {exec xdg-open $url}]} {
          410  +    exec firefox $url &
          411  +  }
          412  +}
          413  +
          414  +# This routine is a "socket -server" callback.  The $chan, $ip, and $port
          415  +# arguments are added by the socket command.
          416  +#
          417  +# Arrange to invoke $callback when content is available on the new socket.
          418  +# The $callback will process inbound HTTP or SCGI content.  Reject the
          419  +# request if $fromip is not an empty string and does not match $ip.
          420  +#
          421  +proc wappInt-new-connection {callback wappmode fromip chan ip port} {
          422  +  upvar #0 wappInt-$chan W
          423  +  if {$fromip!="" && ![string match $fromip $ip]} {
          424  +    close $chan
          425  +    return
          426  +  }
          427  +  set W [dict create REMOTE_ADDR $ip REMOTE_PORT $port WAPP_MODE $wappmode \
          428  +         .header {}]
          429  +  fconfigure $chan -blocking 0 -translation binary
          430  +  fileevent $chan readable [list $callback $chan]
          431  +}
          432  +
          433  +# Close an input channel
          434  +#
          435  +proc wappInt-close-channel {chan} {
          436  +  if {$chan=="stdout"} {
          437  +    # This happens after completing a CGI request
          438  +    exit 0
          439  +  } else {
          440  +    unset ::wappInt-$chan
          441  +    close $chan
          442  +  }
          443  +}
          444  +
          445  +# Process new text received on an inbound HTTP request
          446  +#
          447  +proc wappInt-http-readable {chan} {
          448  +  if {[catch [list wappInt-http-readable-unsafe $chan] msg]} {
          449  +    puts stderr "$msg\n$::errorInfo"
          450  +    wappInt-close-channel $chan
          451  +  }
          452  +}
          453  +proc wappInt-http-readable-unsafe {chan} {
          454  +  upvar #0 wappInt-$chan W wapp wapp
          455  +  if {![dict exists $W .toread]} {
          456  +    # If the .toread key is not set, that means we are still reading
          457  +    # the header
          458  +    set line [string trimright [gets $chan]]
          459  +    set n [string length $line]
          460  +    if {$n>0} {
          461  +      if {[dict get $W .header]=="" || [regexp {^\s+} $line]} {
          462  +        dict append W .header $line
          463  +      } else {
          464  +        dict append W .header \n$line
          465  +      }
          466  +      if {[string length [dict get $W .header]]>100000} {
          467  +        error "HTTP request header too big - possible DOS attack"
          468  +      }
          469  +    } elseif {$n==0} {
          470  +      # We have reached the blank line that terminates the header.
          471  +      global argv0
          472  +      set a0 [file normalize $argv0]
          473  +      dict set W SCRIPT_FILENAME $a0
          474  +      dict set W DOCUMENT_ROOT [file dir $a0]
          475  +      if {[wappInt-parse-header $chan]} {
          476  +        catch {close $chan}
          477  +        return
          478  +      }
          479  +      set len 0
          480  +      if {[dict exists $W CONTENT_LENGTH]} {
          481  +        set len [dict get $W CONTENT_LENGTH]
          482  +      }
          483  +      if {$len>0} {
          484  +        # Still need to read the query content
          485  +        dict set W .toread $len
          486  +      } else {
          487  +        # There is no query content, so handle the request immediately
          488  +        set wapp $W
          489  +        wappInt-handle-request $chan 0
          490  +      }
          491  +    }
          492  +  } else {
          493  +    # If .toread is set, that means we are reading the query content.
          494  +    # Continue reading until .toread reaches zero.
          495  +    set got [read $chan [dict get $W .toread]]
          496  +    dict append W CONTENT $got
          497  +    dict set W .toread [expr {[dict get $W .toread]-[string length $got]}]
          498  +    if {[dict get $W .toread]<=0} {
          499  +      # Handle the request as soon as all the query content is received
          500  +      set wapp $W
          501  +      wappInt-handle-request $chan 0
          502  +    }
          503  +  }
          504  +}
          505  +
          506  +# Decode the HTTP request header.
          507  +#
          508  +# This routine is always running inside of a [catch], so if
          509  +# any problems arise, simply raise an error.
          510  +#
          511  +proc wappInt-parse-header {chan} {
          512  +  upvar #0 wappInt-$chan W
          513  +  set hdr [split [dict get $W .header] \n]
          514  +  if {$hdr==""} {return 1}
          515  +  set req [lindex $hdr 0]
          516  +  dict set W REQUEST_METHOD [set method [lindex $req 0]]
          517  +  if {[lsearch {GET HEAD POST} $method]<0} {
          518  +    error "unsupported request method: \"[dict get $W REQUEST_METHOD]\""
          519  +  }
          520  +  set uri [lindex $req 1]
          521  +  set split_uri [split $uri ?]
          522  +  set uri0 [lindex $split_uri 0]
          523  +  if {![regexp {^/[-.a-z0-9_/]*$} $uri0]} {
          524  +    error "invalid request uri: \"$uri0\""
          525  +  }
          526  +  dict set W REQUEST_URI $uri0
          527  +  dict set W PATH_INFO $uri0
          528  +  set uri1 [lindex $split_uri 1]
          529  +  dict set W QUERY_STRING $uri1
          530  +  set n [llength $hdr]
          531  +  for {set i 1} {$i<$n} {incr i} {
          532  +    set x [lindex $hdr $i]
          533  +    if {![regexp {^(.+): +(.*)$} $x all name value]} {
          534  +      error "invalid header line: \"$x\""
          535  +    }
          536  +    set name [string toupper $name]
          537  +    switch -- $name {
          538  +      REFERER {set name HTTP_REFERER}
          539  +      USER-AGENT {set name HTTP_USER_AGENT}
          540  +      CONTENT-LENGTH {set name CONTENT_LENGTH}
          541  +      CONTENT-TYPE {set name CONTENT_TYPE}
          542  +      HOST {set name HTTP_HOST}
          543  +      COOKIE {set name HTTP_COOKIE}
          544  +      ACCEPT-ENCODING {set name HTTP_ACCEPT_ENCODING}
          545  +      default {set name .hdr:$name}
          546  +    }
          547  +    dict set W $name $value
          548  +  }
          549  +  return 0
          550  +}
          551  +
          552  +# Decode the QUERY_STRING parameters from a GET request or the
          553  +# application/x-www-form-urlencoded CONTENT from a POST request.
          554  +#
          555  +# This routine sets the ".qp" element of the ::wapp dict as a signal
          556  +# that query parameters have already been decoded.
          557  +#
          558  +proc wappInt-decode-query-params {} {
          559  +  global wapp
          560  +  dict set wapp .qp 1
          561  +  if {[dict exists $wapp QUERY_STRING]} {
          562  +    foreach qterm [split [dict get $wapp QUERY_STRING] &] {
          563  +      set qsplit [split $qterm =]
          564  +      set nm [lindex $qsplit 0]
          565  +      if {[regexp {^[a-z][a-z0-9]*$} $nm]} {
          566  +        dict set wapp $nm [wappInt-decode-url [lindex $qsplit 1]]
          567  +      }
          568  +    }
          569  +  }
          570  +  if {[dict exists $wapp CONTENT_TYPE] && [dict exists $wapp CONTENT]} {
          571  +    set ctype [dict get $wapp CONTENT_TYPE]
          572  +    if {$ctype=="application/x-www-form-urlencoded"} {
          573  +      foreach qterm [split [string trim [dict get $wapp CONTENT]] &] {
          574  +        set qsplit [split $qterm =]
          575  +        set nm [lindex $qsplit 0]
          576  +        if {[regexp {^[a-z][-a-z0-9_]*$} $nm]} {
          577  +          dict set wapp $nm [wappInt-decode-url [lindex $qsplit 1]]
          578  +        }
          579  +      }
          580  +    } elseif {[string match multipart/form-data* $ctype]} {
          581  +      regexp {^(.*?)\r\n(.*)$} [dict get $wapp CONTENT] all divider body
          582  +      set ndiv [string length $divider]
          583  +      while {[string length $body]} {
          584  +        set idx [string first $divider $body]
          585  +        set unit [string range $body 0 [expr {$idx-3}]]
          586  +        set body [string range $body [expr {$idx+$ndiv+2}] end]
          587  +        if {[regexp {^Content-Disposition: form-data; (.*?)\r\n\r\n(.*)$} \
          588  +             $unit unit hdr content]} {
          589  +          if {[regexp {name="(.*)"; filename="(.*)"\r\nContent-Type: (.*?)$}\
          590  +                $hdr hr name filename mimetype]} {
          591  +            dict set wapp $name.filename \
          592  +              [string map [list \\\" \" \\\\ \\] $filename]
          593  +            dict set wapp $name.mimetype $mimetype
          594  +            dict set wapp $name.content $content
          595  +          } elseif {[regexp {name="(.*)"} $hdr hr name]} {
          596  +            dict set wapp $name $content
          597  +          }
          598  +        }
          599  +      }
          600  +    }
          601  +  }
          602  +}
          603  +
          604  +# Invoke application-supplied methods to generate a reply to
          605  +# a single HTTP request.
          606  +#
          607  +# This routine always runs within [catch], so handle exceptions by
          608  +# invoking [error].
          609  +#
          610  +proc wappInt-handle-request {chan useCgi} {
          611  +  global wapp
          612  +  dict set wapp .reply {}
          613  +  dict set wapp .mimetype {text/html; charset=utf-8}
          614  +  dict set wapp .reply-code {200 Ok}
          615  +  dict set wapp .csp {default-src 'self'}
          616  +
          617  +  # Set up additional CGI environment values
          618  +  #
          619  +  if {![dict exists $wapp HTTP_HOST]} {
          620  +    dict set wapp BASE_URL {}
          621  +  } elseif {[dict exists $wapp HTTPS]} {
          622  +    dict set wapp BASE_URL https://[dict get $wapp HTTP_HOST]
          623  +  } else {
          624  +    dict set wapp BASE_URL http://[dict get $wapp HTTP_HOST]
          625  +  }
          626  +  if {![dict exists $wapp REQUEST_URI]} {
          627  +    dict set wapp REQUEST_URI /
          628  +  } elseif {[regsub {\?.*} [dict get $wapp REQUEST_URI] {} newR]} {
          629  +    # Some servers (ex: nginx) append the query parameters to REQUEST_URI.
          630  +    # These need to be stripped off
          631  +    dict set wapp REQUEST_URI $newR
          632  +  }
          633  +  if {[dict exists $wapp SCRIPT_NAME]} {
          634  +    dict append wapp BASE_URL [dict get $wapp SCRIPT_NAME]
          635  +  } else {
          636  +    dict set wapp SCRIPT_NAME {}
          637  +  }
          638  +  if {![dict exists $wapp PATH_INFO]} {
          639  +    # If PATH_INFO is missing (ex: nginx) then construct it
          640  +    set URI [dict get $wapp REQUEST_URI]
          641  +    set skip [string length [dict get $wapp SCRIPT_NAME]]
          642  +    dict set wapp PATH_INFO [string range $URI $skip end]
          643  +  }
          644  +  if {[regexp {^/([^/]+)(.*)$} [dict get $wapp PATH_INFO] all head tail]} {
          645  +    dict set wapp PATH_HEAD $head
          646  +    dict set wapp PATH_TAIL [string trimleft $tail /]
          647  +  } else {
          648  +    dict set wapp PATH_INFO {}
          649  +    dict set wapp PATH_HEAD {}
          650  +    dict set wapp PATH_TAIL {}
          651  +  }
          652  +  dict set wapp SELF_URL [dict get $wapp BASE_URL]/[dict get $wapp PATH_HEAD]
          653  +
          654  +  # Parse query parameters from the query string, the cookies, and
          655  +  # POST data
          656  +  #
          657  +  if {[dict exists $wapp HTTP_COOKIE]} {
          658  +    foreach qterm [split [dict get $wapp HTTP_COOKIE] {;}] {
          659  +      set qsplit [split [string trim $qterm] =]
          660  +      set nm [lindex $qsplit 0]
          661  +      if {[regexp {^[a-z][-a-z0-9_]*$} $nm]} {
          662  +        dict set wapp $nm [wappInt-decode-url [lindex $qsplit 1]]
          663  +      }
          664  +    }
          665  +  }
          666  +  set same_origin 0
          667  +  if {[dict exists $wapp HTTP_REFERER]} {
          668  +    set referer [dict get $wapp HTTP_REFERER]
          669  +    set base [dict get $wapp BASE_URL]
          670  +    if {$referer==$base || [string match $base/* $referer]} {
          671  +      set same_origin 1
          672  +    }
          673  +  }
          674  +  dict set wapp SAME_ORIGIN $same_origin
          675  +  if {$same_origin} {
          676  +    wappInt-decode-query-params
          677  +  }
          678  +
          679  +  # Invoke the application-defined handler procedure for this page
          680  +  # request.  If an error occurs while running that procedure, generate
          681  +  # an HTTP reply that contains the error message.
          682  +  #
          683  +  wapp-before-dispatch-hook
          684  +  wappInt-trace
          685  +  set mname [dict get $wapp PATH_HEAD]
          686  +  if {[catch {
          687  +    if {$mname!="" && [llength [info proc wapp-page-$mname]]>0} {
          688  +      wapp-page-$mname
          689  +    } else {
          690  +      wapp-default
          691  +    }
          692  +  } msg]} {
          693  +    if {[wapp-param WAPP_MODE]=="local" || [wapp-param WAPP_MODE]=="server"} {
          694  +      puts "ERROR: $::errorInfo"
          695  +    }
          696  +    wapp-reset
          697  +    wapp-reply-code "500 Internal Server Error"
          698  +    wapp-mimetype text/html
          699  +    wapp-trim {
          700  +      <h1>Wapp Application Error</h1>
          701  +      <pre>%html($::errorInfo)</pre>
          702  +    }
          703  +    dict unset wapp .new-cookies
          704  +  }
          705  +
          706  +  # Transmit the HTTP reply
          707  +  #
          708  +  if {$chan=="stdout"} {
          709  +    puts $chan "Status: [dict get $wapp .reply-code]\r"
          710  +  } else {
          711  +    puts $chan "HTTP/1.1 [dict get $wapp .reply-code]\r"
          712  +    puts $chan "Server: wapp\r"
          713  +    puts $chan "Connection: close\r"
          714  +  }
          715  +  if {[dict exists $wapp .reply-extra]} {
          716  +    foreach {name value} [dict get $wapp .reply-extra] {
          717  +      puts $chan "$name: $value\r"
          718  +    }
          719  +  }
          720  +  if {[dict exists $wapp .csp]} {
          721  +    puts $chan "Content-Security-Policy: [dict get $wapp .csp]\r"
          722  +  }
          723  +  set mimetype [dict get $wapp .mimetype]
          724  +  puts $chan "Content-Type: $mimetype\r"
          725  +  if {[dict exists $wapp .new-cookies]} {
          726  +    foreach {nm val} [dict get $wapp .new-cookies] {
          727  +      if {[regexp {^[a-z][-a-z0-9_]*$} $nm]} {
          728  +        if {$val==""} {
          729  +          puts $chan "Set-Cookie: $nm=; HttpOnly; Path=/; Max-Age=1\r"
          730  +        } else {
          731  +          set val [wappInt-enc-url $val]
          732  +          puts $chan "Set-Cookie: $nm=$val; HttpOnly; Path=/\r"
          733  +        }
          734  +      }
          735  +    }
          736  +  }
          737  +  if {[string match text/* $mimetype]} {
          738  +    set reply [encoding convertto utf-8 [dict get $wapp .reply]]
          739  +    if {[regexp {\ygzip\y} [wapp-param HTTP_ACCEPT_ENCODING]]} {
          740  +      catch {
          741  +        set x [zlib gzip $reply]
          742  +        set reply $x
          743  +        puts $chan "Content-Encoding: gzip\r"
          744  +      }
          745  +    }
          746  +  } else {
          747  +    set reply [dict get $wapp .reply]
          748  +  }
          749  +  puts $chan "Content-Length: [string length $reply]\r"
          750  +  puts $chan \r
          751  +  puts -nonewline $chan $reply
          752  +  flush $chan
          753  +  wappInt-close-channel $chan
          754  +}
          755  +
          756  +# This routine runs just prior to request-handler dispatch.  The
          757  +# default implementation is a no-op, but applications can override
          758  +# to do additional transformations or checks.
          759  +#
          760  +proc wapp-before-dispatch-hook {} {return}
          761  +
          762  +# Process a single CGI request
          763  +#
          764  +proc wappInt-handle-cgi-request {} {
          765  +  global wapp env
          766  +  foreach key {
          767  +    CONTENT_LENGTH
          768  +    CONTENT_TYPE
          769  +    DOCUMENT_ROOT
          770  +    HTTP_ACCEPT_ENCODING
          771  +    HTTP_COOKIE
          772  +    HTTP_HOST
          773  +    HTTP_REFERER
          774  +    HTTP_USER_AGENT
          775  +    HTTPS
          776  +    PATH_INFO
          777  +    QUERY_STRING
          778  +    REMOTE_ADDR
          779  +    REQUEST_METHOD
          780  +    REQUEST_URI
          781  +    REMOTE_USER
          782  +    SCRIPT_FILENAME
          783  +    SCRIPT_NAME
          784  +    SERVER_NAME
          785  +    SERVER_PORT
          786  +    SERVER_PROTOCOL
          787  +  } {
          788  +    if {[info exists env($key)]} {
          789  +      dict set wapp $key $env($key)
          790  +    }
          791  +  }
          792  +  set len 0
          793  +  if {[dict exists $wapp CONTENT_LENGTH]} {
          794  +    set len [dict get $wapp CONTENT_LENGTH]
          795  +  }
          796  +  if {$len>0} {
          797  +    fconfigure stdin -translation binary
          798  +    dict set wapp CONTENT [read stdin $len]
          799  +  }
          800  +  dict set wapp WAPP_MODE cgi
          801  +  fconfigure stdout -translation binary
          802  +  wappInt-handle-request stdout 1
          803  +}
          804  +
          805  +# Process new text received on an inbound SCGI request
          806  +#
          807  +proc wappInt-scgi-readable {chan} {
          808  +  if {[catch [list wappInt-scgi-readable-unsafe $chan] msg]} {
          809  +    puts stderr "$msg\n$::errorInfo"
          810  +    wappInt-close-channel $chan
          811  +  }
          812  +}
          813  +proc wappInt-scgi-readable-unsafe {chan} {
          814  +  upvar #0 wappInt-$chan W wapp wapp
          815  +  if {![dict exists $W .toread]} {
          816  +    # If the .toread key is not set, that means we are still reading
          817  +    # the header.
          818  +    #
          819  +    # An SGI header is short.  This implementation assumes the entire
          820  +    # header is available all at once.
          821  +    #
          822  +    dict set W .remove_addr [dict get $W REMOTE_ADDR]
          823  +    set req [read $chan 15]
          824  +    set n [string length $req]
          825  +    scan $req %d:%s len hdr
          826  +    incr len [string length "$len:,"]
          827  +    append hdr [read $chan [expr {$len-15}]]
          828  +    foreach {nm val} [split $hdr \000] {
          829  +      if {$nm==","} break
          830  +      dict set W $nm $val
          831  +    }
          832  +    set len 0
          833  +    if {[dict exists $W CONTENT_LENGTH]} {
          834  +      set len [dict get $W CONTENT_LENGTH]
          835  +    }
          836  +    if {$len>0} {
          837  +      # Still need to read the query content
          838  +      dict set W .toread $len
          839  +    } else {
          840  +      # There is no query content, so handle the request immediately
          841  +      dict set W SERVER_ADDR [dict get $W .remove_addr]
          842  +      set wapp $W
          843  +      wappInt-handle-request $chan 0
          844  +    }
          845  +  } else {
          846  +    # If .toread is set, that means we are reading the query content.
          847  +    # Continue reading until .toread reaches zero.
          848  +    set got [read $chan [dict get $W .toread]]
          849  +    dict append W CONTENT $got
          850  +    dict set W .toread [expr {[dict get $W .toread]-[string length $got]}]
          851  +    if {[dict get $W .toread]<=0} {
          852  +      # Handle the request as soon as all the query content is received
          853  +      dict set W SERVER_ADDR [dict get $W .remove_addr]
          854  +      set wapp $W
          855  +      wappInt-handle-request $chan 0
          856  +    }
          857  +  }
          858  +}
          859  +
          860  +# Start up the wapp framework.  Parameters are a list passed as the
          861  +# single argument.
          862  +#
          863  +#    -server $PORT         Listen for HTTP requests on this TCP port $PORT
          864  +#
          865  +#    -local $PORT          Listen for HTTP requests on 127.0.0.1:$PORT
          866  +#
          867  +#    -scgi $PORT           Listen for SCGI requests on 127.0.0.1:$PORT
          868  +#
          869  +#    -remote-scgi $PORT    Listen for SCGI requests on TCP port $PORT
          870  +#
          871  +#    -cgi                  Handle a single CGI request
          872  +#
          873  +# With no arguments, the behavior is called "auto".  In "auto" mode,
          874  +# if the GATEWAY_INTERFACE environment variable indicates CGI, then run
          875  +# as CGI.  Otherwise, start an HTTP server bound to the loopback address
          876  +# only, on an arbitrary TCP port, and automatically launch a web browser
          877  +# on that TCP port.
          878  +#
          879  +# Additional options:
          880  +#
          881  +#    -fromip GLOB         Reject any incoming request where the remote
          882  +#                         IP address does not match the GLOB pattern.  This
          883  +#                         value defaults to '127.0.0.1' for -local and -scgi.
          884  +#
          885  +#    -nowait              Do not wait in the event loop.  Return immediately
          886  +#                         after all event handlers are established.
          887  +#
          888  +#    -trace               "puts" each request URL as it is handled, for
          889  +#                         debugging
          890  +#
          891  +#    -lint                Run wapp-safety-check on the application instead
          892  +#                         of running the application itself
          893  +#
          894  +#    -Dvar=value          Set TCL global variable "var" to "value"
          895  +#
          896  +#
          897  +proc wapp-start {arglist} {
          898  +  global env
          899  +  set mode auto
          900  +  set port 0
          901  +  set nowait 0
          902  +  set fromip {}
          903  +  set n [llength $arglist]
          904  +  for {set i 0} {$i<$n} {incr i} {
          905  +    set term [lindex $arglist $i]
          906  +    if {[string match --* $term]} {set term [string range $term 1 end]}
          907  +    switch -glob -- $term {
          908  +      -server {
          909  +        incr i;
          910  +        set mode "server"
          911  +        set port [lindex $arglist $i]
          912  +      }
          913  +      -local {
          914  +        incr i;
          915  +        set mode "local"
          916  +        set fromip 127.0.0.1
          917  +        set port [lindex $arglist $i]
          918  +      }
          919  +      -scgi {
          920  +        incr i;
          921  +        set mode "scgi"
          922  +        set fromip 127.0.0.1
          923  +        set port [lindex $arglist $i]
          924  +      }
          925  +      -remote-scgi {
          926  +        incr i;
          927  +        set mode "remote-scgi"
          928  +        set port [lindex $arglist $i]
          929  +      }
          930  +      -cgi {
          931  +        set mode "cgi"
          932  +      }
          933  +      -fromip {
          934  +        incr i
          935  +        set fromip [lindex $arglist $i]
          936  +      }
          937  +      -nowait {
          938  +        set nowait 1
          939  +      }
          940  +      -trace {
          941  +        proc wappInt-trace {} {
          942  +          set q [wapp-param QUERY_STRING]
          943  +          set uri [wapp-param BASE_URL][wapp-param PATH_INFO]
          944  +          if {$q!=""} {append uri ?$q}
          945  +          puts $uri
          946  +        }
          947  +      }
          948  +      -lint {
          949  +        set res [wapp-safety-check]
          950  +        if {$res!=""} {
          951  +          puts "Potential problems in this code:"
          952  +          puts $res
          953  +          exit 1
          954  +        } else {
          955  +          exit
          956  +        }
          957  +      }
          958  +      -D*=* {
          959  +        if {[regexp {^.D([^=]+)=(.*)$} $term all var val]} {
          960  +          set ::$var $val
          961  +        }
          962  +      }
          963  +      default {
          964  +        error "unknown option: $term"
          965  +      }
          966  +    }
          967  +  }
          968  +  if {$mode=="auto"} {
          969  +    if {[info exists env(GATEWAY_INTERFACE)]
          970  +        && [string match CGI/1.* $env(GATEWAY_INTERFACE)]} {
          971  +      set mode cgi
          972  +    } else {
          973  +      set mode local
          974  +    }
          975  +  }
          976  +  if {$mode=="cgi"} {
          977  +    wappInt-handle-cgi-request
          978  +  } else {
          979  +    wappInt-start-listener $port $mode $fromip
          980  +    if {!$nowait} {
          981  +      vwait ::forever
          982  +    }
          983  +  }
          984  +}
          985  +
          986  +# Call this version 1.0
          987  +package provide wapp 1.0

Added test/wapptest.tcl.

            1  +#!/bin/sh
            2  +# \
            3  +exec wapptclsh "$0" ${1+"$@"}
            4  +
            5  +# package required wapp
            6  +source [file join [file dirname [info script]] wapp.tcl]
            7  +
            8  +# Read the data from the releasetest_data.tcl script.
            9  +#
           10  +source [file join [file dirname [info script]] releasetest_data.tcl]
           11  +
           12  +# Variables set by the "control" form:
           13  +#
           14  +#   G(platform) - User selected platform.
           15  +#   G(test)     - Set to "Normal", "Veryquick", "Smoketest" or "Build-Only".
           16  +#   G(keep)     - Boolean. True to delete no files after each test.
           17  +#   G(msvc)     - Boolean. True to use MSVC as the compiler.
           18  +#   G(tcl)      - Use Tcl from this directory for builds.
           19  +#   G(jobs)     - How many sub-processes to run simultaneously.
           20  +#
           21  +set G(platform) $::tcl_platform(os)-$::tcl_platform(machine)
           22  +set G(test)     Normal
           23  +set G(keep)     0
           24  +set G(msvc)     0
           25  +set G(tcl)      [::tcl::pkgconfig get libdir,install]
           26  +set G(jobs)     3
           27  +set G(debug)    0
           28  +
           29  +proc wapptest_init {} {
           30  +  global G
           31  +
           32  +  set lSave [list platform test keep msvc tcl jobs debug] 
           33  +  foreach k $lSave { set A($k) $G($k) }
           34  +  array unset G
           35  +  foreach k $lSave { set G($k) $A($k) }
           36  +
           37  +  # The root of the SQLite source tree.
           38  +  set G(srcdir)   [file dirname [file dirname [info script]]]
           39  +
           40  +  # releasetest.tcl script
           41  +  set G(releaseTest) [file join [file dirname [info script]] releasetest.tcl]
           42  +
           43  +  set G(sqlite_version) "unknown"
           44  +
           45  +  # Either "config", "running" or "stopped":
           46  +  set G(state) "config"
           47  +
           48  +  set G(hostname) "(unknown host)"
           49  +  catch { set G(hostname) [exec hostname] } 
           50  +  set G(host) $G(hostname)
           51  +  append G(host) " $::tcl_platform(os) $::tcl_platform(osVersion)"
           52  +  append G(host) " $::tcl_platform(machine) $::tcl_platform(byteOrder)"
           53  +}
           54  +
           55  +# Check to see if there are uncommitted changes in the SQLite source
           56  +# directory. Return true if there are, or false otherwise.
           57  +#
           58  +proc check_uncommitted {} {
           59  +  global G
           60  +  set ret 0
           61  +  set pwd [pwd]
           62  +  cd $G(srcdir)
           63  +  if {[catch {exec fossil changes} res]==0 && [string trim $res]!=""} {
           64  +    set ret 1
           65  +  }
           66  +  cd $pwd
           67  +  return $ret
           68  +}
           69  +
           70  +proc generate_fossil_info {} {
           71  +  global G
           72  +  set pwd [pwd]
           73  +  cd $G(srcdir)
           74  +  if {[catch {exec fossil info}    r1]} return
           75  +  if {[catch {exec fossil changes} r2]} return
           76  +  cd $pwd
           77  +
           78  +  foreach line [split $r1 "\n"] {
           79  +    if {[regexp {^checkout: *(.*)$} $line -> co]} {
           80  +      wapp-trim { <br> %html($co) }
           81  +    }
           82  +  }
           83  +
           84  +  if {[string trim $r2]!=""} {
           85  +    wapp-trim { 
           86  +      <br><span class=warning> 
           87  +      WARNING: Uncommitted changes in checkout
           88  +      </span>
           89  +    }
           90  +  }
           91  +}
           92  +
           93  +# If the application is in "config" state, set the contents of the 
           94  +# ::G(test_array) global to reflect the tests that will be run. If the
           95  +# app is in some other state ("running" or "stopped"), this command
           96  +# is a no-op.
           97  +#
           98  +proc set_test_array {} {
           99  +  global G
          100  +  if { $G(state)=="config" } {
          101  +    set G(test_array) [list]
          102  +    foreach {config target} $::Platforms($G(platform)) {
          103  +
          104  +      # If using MSVC, do not run sanitize or valgrind tests. Or the
          105  +      # checksymbols test.
          106  +      if {$G(msvc) && (
          107  +          "Sanitize" == $config 
          108  +       || "checksymbols" in $target
          109  +       || "valgrindtest" in $target
          110  +      )} {
          111  +        continue
          112  +      }
          113  +
          114  +      # If the test mode is not "Normal", override the target.
          115  +      #
          116  +      if {$target!="checksymbols" && $G(platform)!="Failure-Detection"} {
          117  +        switch -- $G(test) {
          118  +          Veryquick { set target quicktest }
          119  +          Smoketest { set target smoketest }
          120  +          Build-Only {
          121  +            set target testfixture
          122  +            if {$::tcl_platform(platform)=="windows"} {
          123  +              set target testfixture.exe
          124  +            }
          125  +          }
          126  +        }
          127  +      }
          128  +
          129  +      lappend G(test_array) [dict create config $config target $target]
          130  +
          131  +      set exclude [list checksymbols valgrindtest fuzzoomtest]
          132  +      if {$G(debug) && !($target in $exclude)} {
          133  +        set debug_idx [lsearch -glob $::Configs($config) -DSQLITE_DEBUG*]
          134  +        set xtarget $target
          135  +        regsub -all {fulltest[a-z]*} $xtarget test xtarget
          136  +        if {$debug_idx<0} {
          137  +          lappend G(test_array) [
          138  +            dict create config $config-(Debug) target $xtarget
          139  +          ]
          140  +        } else {
          141  +          lappend G(test_array) [
          142  +            dict create config $config-(NDebug) target $xtarget
          143  +          ]
          144  +        }
          145  +      }
          146  +    }
          147  +  }
          148  +}
          149  +
          150  +proc count_tests_and_errors {name logfile} {
          151  +  global G
          152  +
          153  +  set fd [open $logfile rb]
          154  +  set seen 0
          155  +  while {![eof $fd]} {
          156  +    set line [gets $fd]
          157  +    if {[regexp {(\d+) errors out of (\d+) tests} $line all nerr ntest]} {
          158  +      incr G(test.$name.nError) $nerr
          159  +      incr G(test.$name.nTest) $ntest
          160  +      set seen 1
          161  +      if {$nerr>0} {
          162  +        set G(test.$name.errmsg) $line
          163  +      }
          164  +    }
          165  +    if {[regexp {runtime error: +(.*)} $line all msg]} {
          166  +      # skip over "value is outside range" errors
          167  +      if {[regexp {value .* is outside the range of representable} $line]} {
          168  +         # noop
          169  +      } else {
          170  +        incr G(test.$name.nError)
          171  +        if {$G(test.$name.errmsg)==""} {
          172  +          set G(test.$name.errmsg) $msg
          173  +        }
          174  +      }
          175  +    }
          176  +    if {[regexp {fatal error +(.*)} $line all msg]} {
          177  +      incr G(test.$name.nError)
          178  +      if {$G(test.$name.errmsg)==""} {
          179  +        set G(test.$name.errmsg) $msg
          180  +      }
          181  +    }
          182  +    if {[regexp {ERROR SUMMARY: (\d+) errors.*} $line all cnt] && $cnt>0} {
          183  +      incr G(test.$name.nError)
          184  +      if {$G(test.$name.errmsg)==""} {
          185  +        set G(test.$name.errmsg) $all
          186  +      }
          187  +    }
          188  +    if {[regexp {^VERSION: 3\.\d+.\d+} $line]} {
          189  +      set v [string range $line 9 end]
          190  +      if {$G(sqlite_version) eq "unknown"} {
          191  +        set G(sqlite_version) $v
          192  +      } elseif {$G(sqlite_version) ne $v} {
          193  +        set G(test.$name.errmsg) "version conflict: {$G(sqlite_version)} vs. {$v}"
          194  +      }
          195  +    }
          196  +  }
          197  +  close $fd
          198  +  if {$G(test) == "Build-Only"} {
          199  +    incr G(test.$name.nTest)
          200  +    if {$G(test.$name.nError)>0} {
          201  +      set errmsg "Build failed"
          202  +    }
          203  +  } elseif {!$seen} {
          204  +    set G(test.$name.errmsg) "Test did not complete"
          205  +    if {[file readable core]} {
          206  +      append G(test.$name.errmsg) " - core file exists"
          207  +    }
          208  +  }
          209  +}
          210  +
          211  +proc slave_test_done {name rc} {
          212  +  global G
          213  +  set G(test.$name.done) [clock seconds]
          214  +  set G(test.$name.nError) 0
          215  +  set G(test.$name.nTest) 0
          216  +  set G(test.$name.errmsg) ""
          217  +  if {$rc} {
          218  +    incr G(test.$name.nError)
          219  +  }
          220  +  if {[file exists $G(test.$name.log)]} {
          221  +    count_tests_and_errors $name $G(test.$name.log)
          222  +  }
          223  +}
          224  +
          225  +proc slave_fileevent {name} {
          226  +  global G
          227  +  set fd $G(test.$name.channel)
          228  +
          229  +  if {[eof $fd]} {
          230  +    fconfigure $fd -blocking 1
          231  +    set rc [catch { close $fd }]
          232  +    unset G(test.$name.channel)
          233  +    slave_test_done $name $rc
          234  +  } else {
          235  +    set line [gets $fd]
          236  +    if {[string trim $line] != ""} { puts "Trace   : $name - \"$line\"" }
          237  +  }
          238  +
          239  +  do_some_stuff
          240  +}
          241  +
          242  +proc do_some_stuff {} {
          243  +  global G
          244  +
          245  +  # Count the number of running jobs. A running job has an entry named
          246  +  # "channel" in its dictionary.
          247  +  set nRunning 0
          248  +  set bFinished 1
          249  +  foreach j $G(test_array) {
          250  +    set name [dict get $j config]
          251  +    if { [info exists G(test.$name.channel)]} { incr nRunning   }
          252  +    if {![info exists G(test.$name.done)]}    { set bFinished 0 }
          253  +  }
          254  +
          255  +  if {$bFinished} {
          256  +    set nError 0
          257  +    set nTest 0
          258  +    set nConfig 0
          259  +    foreach j $G(test_array) {
          260  +      set name [dict get $j config]
          261  +      incr nError $G(test.$name.nError)
          262  +      incr nTest $G(test.$name.nTest)
          263  +      incr nConfig 
          264  +    }
          265  +    set G(result) "$nError errors from $nTest tests in $nConfig configurations."
          266  +    catch {
          267  +      append G(result) " SQLite version $G(sqlite_version)"
          268  +    }
          269  +    set G(state) "stopped"
          270  +  } else {
          271  +    set nLaunch [expr $G(jobs) - $nRunning]
          272  +    foreach j $G(test_array) {
          273  +      if {$nLaunch<=0} break
          274  +      set name [dict get $j config]
          275  +      if { ![info exists G(test.$name.channel)]
          276  +        && ![info exists G(test.$name.done)]
          277  +      } {
          278  +        set target [dict get $j target]
          279  +        set G(test.$name.start) [clock seconds]
          280  +        set fd [open "|[info nameofexecutable] $G(releaseTest) --slave" r+]
          281  +        set G(test.$name.channel) $fd
          282  +        fconfigure $fd -blocking 0
          283  +        fileevent $fd readable [list slave_fileevent $name]
          284  +
          285  +        puts $fd [list 0 $G(msvc) 0 $G(keep)]
          286  +
          287  +        set wtcl ""
          288  +        if {$G(tcl)!=""} { set wtcl "--with-tcl=$G(tcl)" }
          289  +
          290  +        # If this configuration is named <name>-(Debug) or <name>-(NDebug),
          291  +        # then add or remove the SQLITE_DEBUG option from the base
          292  +        # configuration before running the test.
          293  +        if {[regexp -- {(.*)-(\(.*\))} $name -> head tail]} {
          294  +          set opts $::Configs($head)
          295  +          if {$tail=="(Debug)"} {
          296  +            append opts " -DSQLITE_DEBUG=1 -DSQLITE_EXTRA_IFNULLROW=1"
          297  +          } else {
          298  +            regsub { *-DSQLITE_MEMDEBUG[^ ]* *} $opts { } opts
          299  +            regsub { *-DSQLITE_DEBUG[^ ]* *} $opts { } opts
          300  +          }
          301  +        } else {
          302  +          set opts $::Configs($name)
          303  +        }
          304  +
          305  +        set L [make_test_suite $G(msvc) $wtcl $name $target $opts]
          306  +        puts $fd $L
          307  +        flush $fd
          308  +        set G(test.$name.log) [file join [lindex $L 1] test.log]
          309  +        incr nLaunch -1
          310  +      }
          311  +    }
          312  +  }
          313  +}
          314  +
          315  +proc generate_select_widget {label id lOpt opt} {
          316  +  wapp-trim {
          317  +    <label> %string($label) </label>
          318  +    <select id=%string($id) name=%string($id)>
          319  +  }
          320  +  foreach o $lOpt {
          321  +    set selected ""
          322  +    if {$o==$opt} { set selected " selected=1" }
          323  +    wapp-subst "<option $selected>$o</option>"
          324  +  }
          325  +  wapp-trim { </select> }
          326  +}
          327  +
          328  +proc generate_main_page {{extra {}}} {
          329  +  global G
          330  +  set_test_array
          331  +
          332  +  set hostname $G(hostname)
          333  +  wapp-trim {
          334  +    <html>
          335  +    <head>
          336  +      <title> %html($hostname): wapptest.tcl </title>
          337  +      <link rel="stylesheet" type="text/css" href="style.css"/>
          338  +    </head>
          339  +    <body>
          340  +  }
          341  +
          342  +  set host $G(host)
          343  +  wapp-trim {
          344  +    <div class="border">%string($host)
          345  +  }
          346  +  generate_fossil_info
          347  +  wapp-trim {
          348  +    </div>
          349  +    <div class="border" id=controls> 
          350  +    <form action="control" method="post" name="control">
          351  +  }
          352  +
          353  +  # Build the "platform" select widget. 
          354  +  set lOpt [array names ::Platforms]
          355  +  generate_select_widget Platform control_platform $lOpt $G(platform)
          356  +
          357  +  # Build the "test" select widget. 
          358  +  set lOpt [list Normal Veryquick Smoketest Build-Only] 
          359  +  generate_select_widget Test control_test $lOpt $G(test)
          360  +
          361  +  # Build the "jobs" select widget. Options are 1 to 8.
          362  +  generate_select_widget Jobs control_jobs {1 2 3 4 5 6 7 8} $G(jobs)
          363  +
          364  +  switch $G(state) {
          365  +    config {
          366  +      set txt "Run Tests!"
          367  +      set id control_run
          368  +    }
          369  +    running {
          370  +      set txt "STOP Tests!"
          371  +      set id control_stop
          372  +    }
          373  +    stopped {
          374  +      set txt "Reset!"
          375  +      set id control_reset
          376  +    }
          377  +  }
          378  +  wapp-trim {
          379  +    <div class=right>
          380  +    <input id=%string($id) name=%string($id) type=submit value="%string($txt)">
          381  +    </input>
          382  +    </div>
          383  +  }
          384  +
          385  +  wapp-trim {
          386  +  <br><br>
          387  +        <label> Tcl: </label>
          388  +        <input id="control_tcl" name="control_tcl"></input>
          389  +        <label> Keep files: </label>
          390  +        <input id="control_keep" name="control_keep" type=checkbox value=1>
          391  +        </input>
          392  +        <label> Use MSVC: </label>
          393  +        <input id="control_msvc" name="control_msvc" type=checkbox value=1>
          394  +        <label> Debug tests: </label>
          395  +        <input id="control_debug" name="control_debug" type=checkbox value=1>
          396  +        </input>
          397  +  }
          398  +  wapp-trim {
          399  +     </form>
          400  +  }
          401  +  wapp-trim {
          402  +     </div>
          403  +     <div id=tests>
          404  +  }
          405  +  wapp-page-tests
          406  +
          407  +  set script "script/$G(state).js"
          408  +  wapp-trim {
          409  +    </div>
          410  +      <script src=%string($script)></script>
          411  +    </body>
          412  +    </html>
          413  +  }
          414  +}
          415  +
          416  +proc wapp-default {} {
          417  +  generate_main_page
          418  +}
          419  +
          420  +proc wapp-page-tests {} {
          421  +  global G
          422  +  wapp-trim { <table class="border" width=100%> }
          423  +  foreach t $G(test_array) {
          424  +    set config [dict get $t config]
          425  +    set target [dict get $t target]
          426  +
          427  +    set class "testwait"
          428  +    set seconds ""
          429  +
          430  +    if {[info exists G(test.$config.log)]} {
          431  +      if {[info exists G(test.$config.channel)]} {
          432  +        set class "testrunning"
          433  +        set seconds [expr [clock seconds] - $G(test.$config.start)]
          434  +      } elseif {[info exists G(test.$config.done)]} {
          435  +        if {$G(test.$config.nError)>0} {
          436  +          set class "testfail" 
          437  +        } else {
          438  +          set class "testdone"
          439  +        }
          440  +        set seconds [expr $G(test.$config.done) - $G(test.$config.start)]
          441  +      }
          442  +
          443  +      set min [format %.2d [expr ($seconds / 60) % 60]]
          444  +      set  hr [format %.2d [expr $seconds / 3600]]
          445  +      set sec [format %.2d [expr $seconds % 60]]
          446  +      set seconds "$hr:$min:$sec"
          447  +    }
          448  +
          449  +    wapp-trim {
          450  +      <tr class=%string($class)>
          451  +      <td class="nowrap"> %html($config) 
          452  +      <td class="padleft nowrap"> %html($target)
          453  +      <td class="padleft nowrap"> %html($seconds)
          454  +      <td class="padleft nowrap">
          455  +    }
          456  +    if {[info exists G(test.$config.log)]} {
          457  +      set log $G(test.$config.log)
          458  +      set uri "log/$log"
          459  +      wapp-trim {
          460  +        <a href=%url($uri)> %html($log) </a>
          461  +      }
          462  +    }
          463  +    if {[info exists G(test.$config.errmsg)] && $G(test.$config.errmsg)!=""} {
          464  +      set errmsg $G(test.$config.errmsg)
          465  +      wapp-trim {
          466  +        <tr class=testfail>
          467  +        <td> <td class="padleft" colspan=3> %html($errmsg)
          468  +      }
          469  +    }
          470  +  }
          471  +
          472  +  wapp-trim { </table> }
          473  +
          474  +  if {[info exists G(result)]} {
          475  +    set res $G(result)
          476  +    wapp-trim {
          477  +      <div class=border id=result> %string($res) </div>
          478  +    }
          479  +  }
          480  +}
          481  +
          482  +# URI: /control
          483  +#
          484  +# Whenever the form at the top of the application page is submitted, it
          485  +# is submitted here.
          486  +#
          487  +proc wapp-page-control {} {
          488  +  global G
          489  +  if {$::G(state)=="config"} {
          490  +    set lControls [list platform test tcl jobs keep msvc debug]
          491  +    set G(msvc) 0
          492  +    set G(keep) 0
          493  +    set G(debug) 0
          494  +  } else {
          495  +    set lControls [list jobs]
          496  +  }
          497  +  foreach v $lControls {
          498  +    if {[wapp-param-exists control_$v]} {
          499  +      set G($v) [wapp-param control_$v]
          500  +    }
          501  +  }
          502  +
          503  +  if {[wapp-param-exists control_run]} {
          504  +    # This is a "run test" command.
          505  +    set_test_array
          506  +    set ::G(state) "running"
          507  +  }
          508  +
          509  +  if {[wapp-param-exists control_stop]} {
          510  +    # A "STOP tests" command.
          511  +    set G(state) "stopped"
          512  +    set G(result) "Test halted by user"
          513  +    foreach j $G(test_array) {
          514  +      set name [dict get $j config]
          515  +      if { [info exists G(test.$name.channel)] } {
          516  +        close $G(test.$name.channel)
          517  +        unset G(test.$name.channel)
          518  +        slave_test_done $name 1
          519  +      }
          520  +    }
          521  +  }
          522  +
          523  +  if {[wapp-param-exists control_reset]} {
          524  +    # A "reset app" command.
          525  +    set G(state) "config"
          526  +    wapptest_init
          527  +  }
          528  +
          529  +  if {$::G(state) == "running"} {
          530  +    do_some_stuff
          531  +  }
          532  +  wapp-redirect /
          533  +}
          534  +
          535  +# URI: /style.css
          536  +#
          537  +# Return the stylesheet for the application main page.
          538  +#
          539  +proc wapp-page-style.css {} {
          540  +  wapp-subst {
          541  +
          542  +    /* The boxes with black borders use this class */
          543  +    .border {
          544  +      border: 3px groove #444444;
          545  +      padding: 1em;
          546  +      margin-top: 1em;
          547  +      margin-bottom: 1em;
          548  +    }
          549  +
          550  +    /* Float to the right (used for the Run/Stop/Reset button) */
          551  +    .right { float: right; }
          552  +
          553  +    /* Style for the large red warning at the top of the page */
          554  +    .warning {
          555  +      color: red;
          556  +      font-weight: bold;
          557  +    }
          558  +
          559  +    /* Styles used by cells in the test table */
          560  +    .padleft { padding-left: 5ex; }
          561  +    .nowrap  { white-space: nowrap; }
          562  +
          563  +    /* Styles for individual tests, depending on the outcome */
          564  +    .testwait    {              }
          565  +    .testrunning { color: blue  }
          566  +    .testdone    { color: green }
          567  +    .testfail    { color: red   }
          568  +  }
          569  +}
          570  +
          571  +# URI: /script/${state}.js
          572  +#
          573  +# The last part of this URI is always "config.js", "running.js" or 
          574  +# "stopped.js", depending on the state of the application. It returns
          575  +# the javascript part of the front-end for the requested state to the
          576  +# browser.
          577  +#
          578  +proc wapp-page-script {} {
          579  +  regexp {[^/]*$} [wapp-param REQUEST_URI] script
          580  +
          581  +  set tcl $::G(tcl)
          582  +