/ Check-in [e6a4a163]
Login

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

Overview
Comment:Merge recent enhancements from trunk.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | apple-osx
Files: files | file ages | folders
SHA1:e6a4a16312bf71ed5f277cdcd326003eb2580e72
User & Date: drh 2016-02-02 02:30:01
Context
2016-02-05
14:29
Merge OOM handling optimizations and PRAGMA synchronous=EXTRA as well as other enhancements from trunk. check-in: 201fcbee user: drh tags: apple-osx
2016-02-02
02:30
Merge recent enhancements from trunk. check-in: e6a4a163 user: drh tags: apple-osx
02:04
Enhance the comment on the sqlite3_index_constraint object to bring attention to the fact than iColumn field can be negative for a rowid. check-in: d8b7b199 user: drh tags: trunk
2016-01-20
11:40
Merge all recent enhancements from trunk. check-in: 3ed49691 user: drh tags: apple-osx
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to Makefile.in.

  1188   1188   
  1189   1189   # Standard install and cleanup targets
  1190   1190   #
  1191   1191   lib_install:	libsqlite3.la
  1192   1192   	$(INSTALL) -d $(DESTDIR)$(libdir)
  1193   1193   	$(LTINSTALL) libsqlite3.la $(DESTDIR)$(libdir)
  1194   1194   	
  1195         -install:	sqlite3$(BEXE) lib_install sqlite3.h sqlite3.pc ${HAVE_TCL:1=tcl_install}
         1195  +install:	sqlite3$(TEXE) lib_install sqlite3.h sqlite3.pc ${HAVE_TCL:1=tcl_install}
  1196   1196   	$(INSTALL) -d $(DESTDIR)$(bindir)
  1197         -	$(LTINSTALL) sqlite3$(BEXE) $(DESTDIR)$(bindir)
         1197  +	$(LTINSTALL) sqlite3$(TEXE) $(DESTDIR)$(bindir)
  1198   1198   	$(INSTALL) -d $(DESTDIR)$(includedir)
  1199   1199   	$(INSTALL) -m 0644 sqlite3.h $(DESTDIR)$(includedir)
  1200   1200   	$(INSTALL) -m 0644 $(TOP)/src/sqlite3ext.h $(DESTDIR)$(includedir)
  1201   1201   	$(INSTALL) -d $(DESTDIR)$(pkgconfigdir)
  1202   1202   	$(INSTALL) -m 0644 sqlite3.pc $(DESTDIR)$(pkgconfigdir)
  1203   1203   
  1204   1204   pkgIndex.tcl:
................................................................................
  1226   1226   	rm -f sqlite3.dll sqlite3.lib sqlite3.exp sqlite3.def
  1227   1227   	rm -f sqlite3.c
  1228   1228   	rm -f sqlite3rc.h
  1229   1229   	rm -f shell.c sqlite3ext.h
  1230   1230   	rm -f sqlite3_analyzer$(TEXE) sqlite3_analyzer.c
  1231   1231   	rm -f sqlite-*-output.vsix
  1232   1232   	rm -f mptester mptester.exe
         1233  +	rm -f rbu rbu.exe
  1233   1234   	rm -f fuzzershell fuzzershell.exe
  1234   1235   	rm -f fuzzcheck fuzzcheck.exe
  1235   1236   	rm -f sqldiff sqldiff.exe
  1236   1237   	rm -f fts5.* fts5parse.*
  1237   1238   
  1238   1239   distclean:	clean
  1239   1240   	rm -f config.h config.log config.status libtool Makefile sqlite3.pc

Changes to Makefile.msc.

     6      6   ###############################################################################
     7      7   
     8      8   # The toplevel directory of the source tree.  This is the directory
     9      9   # that contains this "Makefile.msc".
    10     10   #
    11     11   TOP = .
    12     12   
           13  +# <<mark>>
    13     14   # Set this non-0 to create and use the SQLite amalgamation file.
    14     15   #
    15     16   !IFNDEF USE_AMALGAMATION
    16     17   USE_AMALGAMATION = 1
    17     18   !ENDIF
           19  +# <</mark>>
    18     20   
    19     21   # Set this non-0 to enable full warnings (-W4, etc) when compiling.
    20     22   #
    21     23   !IFNDEF USE_FULLWARN
    22     24   USE_FULLWARN = 0
    23     25   !ENDIF
    24     26   
................................................................................
    64     66   # Set this non-0 to split the SQLite amalgamation file into chunks to
    65     67   # be used for debugging with Visual Studio.
    66     68   #
    67     69   !IFNDEF SPLIT_AMALGAMATION
    68     70   SPLIT_AMALGAMATION = 0
    69     71   !ENDIF
    70     72   
           73  +# <<mark>>
    71     74   # Set this non-0 to use the International Components for Unicode (ICU).
    72     75   #
    73     76   !IFNDEF USE_ICU
    74     77   USE_ICU = 0
    75     78   !ENDIF
           79  +# <</mark>>
    76     80   
    77     81   # Set this non-0 to dynamically link to the MSVC runtime library.
    78     82   #
    79     83   !IFNDEF USE_CRT_DLL
    80     84   USE_CRT_DLL = 0
    81     85   !ENDIF
    82     86   
................................................................................
   126    130   # This setting does not apply to any binaries that require Tcl to operate
   127    131   # properly (i.e. the text fixture, etc).
   128    132   #
   129    133   !IFNDEF FOR_UAP
   130    134   FOR_UAP = 0
   131    135   !ENDIF
   132    136   
          137  +# Set this non-0 to compile binaries suitable for the Windows 10 platform.
          138  +#
          139  +!IFNDEF FOR_WIN10
          140  +FOR_WIN10 = 0
          141  +!ENDIF
          142  +
          143  +# <<mark>>
   133    144   # Set this non-0 to skip attempting to look for and/or link with the Tcl
   134    145   # runtime library.
   135    146   #
   136    147   !IFNDEF NO_TCL
   137    148   NO_TCL = 0
   138    149   !ENDIF
          150  +# <</mark>>
   139    151   
   140    152   # Set this to non-0 to create and use PDBs.
   141    153   #
   142    154   !IFNDEF SYMBOLS
   143    155   SYMBOLS = 1
   144    156   !ENDIF
   145    157   
................................................................................
   181    193   # Enable use of available compiler optimizations?  Normally, this should be
   182    194   # non-zero.  Setting this to zero, thus disabling all compiler optimizations,
   183    195   # can be useful for testing.
   184    196   #
   185    197   !IFNDEF OPTIMIZATIONS
   186    198   OPTIMIZATIONS = 2
   187    199   !ENDIF
          200  +
          201  +# Set the source code file to be used by executables and libraries when
          202  +# they need the amalgamation.
          203  +#
          204  +!IFNDEF SQLITE3C
          205  +!IF $(SPLIT_AMALGAMATION)!=0
          206  +SQLITE3C = sqlite3-all.c
          207  +!ELSE
          208  +SQLITE3C = sqlite3.c
          209  +!ENDIF
          210  +!ENDIF
          211  +
          212  +# Set the include code file to be used by executables and libraries when
          213  +# they need SQLite.
          214  +#
          215  +!IFNDEF SQLITE3H
          216  +SQLITE3H = sqlite3.h
          217  +!ENDIF
          218  +
          219  +# This is the name to use for the SQLite dynamic link library (DLL).
          220  +#
          221  +!IFNDEF SQLITE3DLL
          222  +SQLITE3DLL = sqlite3.dll
          223  +!ENDIF
          224  +
          225  +# This is the name to use for the SQLite import library (LIB).
          226  +#
          227  +!IFNDEF SQLITE3LIB
          228  +SQLITE3LIB = sqlite3.lib
          229  +!ENDIF
          230  +
          231  +# This is the name to use for the SQLite shell executable (EXE).
          232  +#
          233  +!IFNDEF SQLITE3EXE
          234  +SQLITE3EXE = sqlite3.exe
          235  +!ENDIF
          236  +
          237  +# This is the argument used to set the program database (PDB) file for the
          238  +# SQLite shell executable (EXE).
          239  +#
          240  +!IFNDEF SQLITE3EXEPDB
          241  +SQLITE3EXEPDB = /pdb:sqlite3sh.pdb
          242  +!ENDIF
   188    243   
   189    244   # These are the "standard" SQLite compilation options used when compiling for
   190    245   # the Windows platform.
   191    246   #
   192    247   !IFNDEF OPT_FEATURE_FLAGS
   193    248   OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_FTS3=1
   194    249   OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_RTREE=1
   195    250   OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_COLUMN_METADATA=1
   196    251   !ENDIF
          252  +
          253  +# These are the "extended" SQLite compilation options used when compiling for
          254  +# the Windows 10 platform.
          255  +#
          256  +!IFNDEF EXT_FEATURE_FLAGS
          257  +!IF $(FOR_WIN10)!=0
          258  +EXT_FEATURE_FLAGS = $(EXT_FEATURE_FLAGS) -DSQLITE_ENABLE_FTS4=1
          259  +EXT_FEATURE_FLAGS = $(EXT_FEATURE_FLAGS) -DSQLITE_SYSTEM_MALLOC=1
          260  +EXT_FEATURE_FLAGS = $(EXT_FEATURE_FLAGS) -DSQLITE_OMIT_LOCALTIME=1
          261  +!ELSE
          262  +EXT_FEATURE_FLAGS =
          263  +!ENDIF
          264  +!ENDIF
   197    265   
   198    266   ###############################################################################
   199    267   ############################### END OF OPTIONS ################################
   200    268   ###############################################################################
   201    269   
   202    270   # This assumes that MSVC is always installed in 32-bit Program Files directory
   203    271   # and sets the variable for use in locating other 32-bit installs accordingly.
................................................................................
   323    391   #
   324    392   !IF $(USE_FULLWARN)!=0
   325    393   TCC = $(CC) -nologo -W4 -DINCLUDE_MSVC_H=1 $(CCOPTS) $(TCCOPTS)
   326    394   !ELSE
   327    395   TCC = $(CC) -nologo -W3 $(CCOPTS) $(TCCOPTS)
   328    396   !ENDIF
   329    397   
   330         -TCC = $(TCC) -DSQLITE_OS_WIN=1 -I. -I$(TOP) -I$(TOP)\src -fp:precise
          398  +TCC = $(TCC) -DSQLITE_OS_WIN=1 -I$(TOP) -I$(TOP)\src -fp:precise
   331    399   RCC = $(RC) -DSQLITE_OS_WIN=1 -I$(TOP) -I$(TOP)\src $(RCOPTS) $(RCCOPTS)
          400  +
          401  +# Adjust the names of the primary targets for use with Windows 10.
          402  +#
          403  +!IF $(FOR_WIN10)!=0
          404  +SQLITE3DLL = winsqlite3.dll
          405  +SQLITE3LIB = winsqlite3.lib
          406  +SQLITE3EXE = winsqlite3shell.exe
          407  +SQLITE3EXEPDB =
          408  +!ENDIF
   332    409   
   333    410   # Check if we want to use the "stdcall" calling convention when compiling.
   334    411   # This is not supported by the compilers for non-x86 platforms.  It should
   335    412   # also be noted here that building any target with these "stdcall" options
   336    413   # will most likely fail if the Tcl library is also required.  This is due
   337    414   # to how the Tcl library functions are declared and exported (i.e. without
   338    415   # an explicit calling convention, which results in "cdecl").
   339    416   #
   340         -!IF $(USE_STDCALL)!=0
          417  +!IF $(USE_STDCALL)!=0 || $(FOR_WIN10)!=0
   341    418   !IF "$(PLATFORM)"=="x86"
   342    419   CORE_CCONV_OPTS = -Gz -DSQLITE_CDECL=__cdecl -DSQLITE_STDCALL=__stdcall
   343    420   SHELL_CCONV_OPTS = -Gz -DSQLITE_CDECL=__cdecl -DSQLITE_STDCALL=__stdcall
   344    421   !ELSE
   345    422   !IFNDEF PLATFORM
   346    423   CORE_CCONV_OPTS = -Gz -DSQLITE_CDECL=__cdecl -DSQLITE_STDCALL=__stdcall
   347    424   SHELL_CCONV_OPTS = -Gz -DSQLITE_CDECL=__cdecl -DSQLITE_STDCALL=__stdcall
................................................................................
   354    431   CORE_CCONV_OPTS =
   355    432   SHELL_CCONV_OPTS =
   356    433   !ENDIF
   357    434   
   358    435   # These are additional compiler options used for the core library.
   359    436   #
   360    437   !IFNDEF CORE_COMPILE_OPTS
   361         -!IF $(DYNAMIC_SHELL)!=0
          438  +!IF $(DYNAMIC_SHELL)!=0 || $(FOR_WIN10)!=0
   362    439   CORE_COMPILE_OPTS = $(CORE_CCONV_OPTS) -DSQLITE_API=__declspec(dllexport)
   363    440   !ELSE
   364    441   CORE_COMPILE_OPTS = $(CORE_CCONV_OPTS)
   365    442   !ENDIF
   366    443   !ENDIF
   367    444   
   368    445   # These are the additional targets that the core library should depend on
   369    446   # when linking.
   370    447   #
   371    448   !IFNDEF CORE_LINK_DEP
   372         -!IF $(DYNAMIC_SHELL)!=0
          449  +!IF $(DYNAMIC_SHELL)!=0 || $(FOR_WIN10)!=0
   373    450   CORE_LINK_DEP =
   374    451   !ELSE
   375    452   CORE_LINK_DEP = sqlite3.def
   376    453   !ENDIF
   377    454   !ENDIF
   378    455   
   379    456   # These are additional linker options used for the core library.
   380    457   #
   381    458   !IFNDEF CORE_LINK_OPTS
   382         -!IF $(DYNAMIC_SHELL)!=0
          459  +!IF $(DYNAMIC_SHELL)!=0 || $(FOR_WIN10)!=0
   383    460   CORE_LINK_OPTS =
   384    461   !ELSE
   385    462   CORE_LINK_OPTS = /DEF:sqlite3.def
   386    463   !ENDIF
   387    464   !ENDIF
   388    465   
   389    466   # These are additional compiler options used for the shell executable.
   390    467   #
   391    468   !IFNDEF SHELL_COMPILE_OPTS
   392         -!IF $(DYNAMIC_SHELL)!=0
   393         -SHELL_COMPILE_OPTS = -DSQLITE_SHELL_JSON1 $(SHELL_CCONV_OPTS) -DSQLITE_API=__declspec(dllimport)
          469  +!IF $(DYNAMIC_SHELL)!=0 || $(FOR_WIN10)!=0
          470  +SHELL_COMPILE_OPTS = $(SHELL_CCONV_OPTS) -DSQLITE_API=__declspec(dllimport)
   394    471   !ELSE
   395         -SHELL_COMPILE_OPTS = -DSQLITE_SHELL_JSON1 $(SHELL_CCONV_OPTS)
          472  +SHELL_COMPILE_OPTS = $(SHELL_CCONV_OPTS)
          473  +!ENDIF
          474  +!ENDIF
          475  +
          476  +# This is the source code that the shell executable should be compiled
          477  +# with.
          478  +#
          479  +!IFNDEF SHELL_CORE_SRC
          480  +!IF $(DYNAMIC_SHELL)!=0 || $(FOR_WIN10)!=0
          481  +SHELL_CORE_SRC =
          482  +!ELSE
          483  +SHELL_CORE_SRC = $(SQLITE3C)
   396    484   !ENDIF
   397    485   !ENDIF
   398    486   
   399    487   # This is the core library that the shell executable should depend on.
   400    488   #
   401    489   !IFNDEF SHELL_CORE_DEP
   402         -!IF $(DYNAMIC_SHELL)!=0
   403         -SHELL_CORE_DEP = sqlite3.dll
          490  +!IF $(DYNAMIC_SHELL)!=0 || $(FOR_WIN10)!=0
          491  +SHELL_CORE_DEP = $(SQLITE3DLL)
   404    492   !ELSE
   405         -SHELL_CORE_DEP = libsqlite3.lib
          493  +SHELL_CORE_DEP =
   406    494   !ENDIF
   407    495   !ENDIF
   408    496   
   409    497   # This is the core library that the shell executable should link with.
   410    498   #
   411    499   !IFNDEF SHELL_CORE_LIB
   412         -!IF $(DYNAMIC_SHELL)!=0
   413         -SHELL_CORE_LIB = sqlite3.lib
          500  +!IF $(DYNAMIC_SHELL)!=0 || $(FOR_WIN10)!=0
          501  +SHELL_CORE_LIB = $(SQLITE3LIB)
   414    502   !ELSE
   415         -SHELL_CORE_LIB = libsqlite3.lib
          503  +SHELL_CORE_LIB =
   416    504   !ENDIF
   417    505   !ENDIF
   418    506   
   419    507   # These are additional linker options used for the shell executable.
   420    508   #
   421    509   !IFNDEF SHELL_LINK_OPTS
   422    510   SHELL_LINK_OPTS = $(SHELL_CORE_LIB)
................................................................................
   436    524   #
   437    525   !IF $(FOR_WINRT)!=0
   438    526   TCC = $(TCC) -DSQLITE_OS_WINRT=1
   439    527   RCC = $(RCC) -DSQLITE_OS_WINRT=1
   440    528   TCC = $(TCC) -DWINAPI_FAMILY=WINAPI_FAMILY_APP
   441    529   RCC = $(RCC) -DWINAPI_FAMILY=WINAPI_FAMILY_APP
   442    530   !ENDIF
          531  +
          532  +# C compiler options for the Windows 10 platform (needs MSVC 2015).
          533  +#
          534  +!IF $(FOR_WIN10)!=0
          535  +TCC = $(TCC) /guard:cf -D_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE
          536  +BCC = $(BCC) /guard:cf -D_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE
          537  +!ENDIF
   443    538   
   444    539   # Also, we need to dynamically link to the correct MSVC runtime
   445    540   # when compiling for WinRT (e.g. debug or release) OR if the
   446    541   # USE_CRT_DLL option is set to force dynamically linking to the
   447    542   # MSVC runtime library.
   448    543   #
   449         -!IF $(FOR_WINRT)!=0 || $(USE_CRT_DLL)!=0
          544  +!IF $(FOR_WINRT)!=0 || $(FOR_WIN10)!=0 || $(USE_CRT_DLL)!=0
   450    545   !IF $(DEBUG)>1
   451    546   TCC = $(TCC) -MDd
   452    547   BCC = $(BCC) -MDd
   453    548   !ELSE
   454    549   TCC = $(TCC) -MD
   455    550   BCC = $(BCC) -MD
   456    551   !ENDIF
................................................................................
   460    555   BCC = $(BCC) -MTd
   461    556   !ELSE
   462    557   TCC = $(TCC) -MT
   463    558   BCC = $(BCC) -MT
   464    559   !ENDIF
   465    560   !ENDIF
   466    561   
          562  +# <<mark>>
   467    563   # The mksqlite3c.tcl and mksqlite3h.tcl scripts will pull in
   468    564   # any extension header files by default.  For non-amalgamation
   469    565   # builds, we need to make sure the compiler can find these.
   470    566   #
   471    567   !IF $(USE_AMALGAMATION)==0
   472    568   TCC = $(TCC) -I$(TOP)\ext\fts3
   473    569   RCC = $(RCC) -I$(TOP)\ext\fts3
................................................................................
   483    579   !IFNDEF MKSQLITE3C_ARGS
   484    580   !IF $(DEBUG)>1
   485    581   MKSQLITE3C_ARGS = --linemacros
   486    582   !ELSE
   487    583   MKSQLITE3C_ARGS =
   488    584   !ENDIF
   489    585   !ENDIF
          586  +# <</mark>>
   490    587   
   491    588   # Define -DNDEBUG to compile without debugging (i.e., for production usage)
   492    589   # Omitting the define will cause extra debugging code to be inserted and
   493    590   # includes extra comments when "EXPLAIN stmt" is used.
   494    591   #
   495    592   !IF $(DEBUG)==0
   496    593   TCC = $(TCC) -DNDEBUG
   497    594   BCC = $(BCC) -DNDEBUG
   498    595   RCC = $(RCC) -DNDEBUG
   499    596   !ENDIF
   500    597   
   501         -!IF $(DEBUG)>0 || $(API_ARMOR)!=0
          598  +!IF $(DEBUG)>0 || $(API_ARMOR)!=0 || $(FOR_WIN10)!=0
   502    599   TCC = $(TCC) -DSQLITE_ENABLE_API_ARMOR=1
   503    600   RCC = $(RCC) -DSQLITE_ENABLE_API_ARMOR=1
   504    601   !ENDIF
   505    602   
   506    603   !IF $(DEBUG)>2
   507    604   TCC = $(TCC) -DSQLITE_DEBUG=1
   508    605   RCC = $(RCC) -DSQLITE_DEBUG=1
................................................................................
   547    644   #
   548    645   !IF $(DEBUG)>3
   549    646   TCC = $(TCC) -DSQLITE_WIN32_MALLOC_VALIDATE=1
   550    647   RCC = $(RCC) -DSQLITE_WIN32_MALLOC_VALIDATE=1
   551    648   !ENDIF
   552    649   !ENDIF
   553    650   
          651  +# <<mark>>
   554    652   # The locations of the Tcl header and library files.  Also, the library that
   555    653   # non-stubs enabled programs using Tcl must link against.  These variables
   556    654   # (TCLINCDIR, TCLLIBDIR, and LIBTCL) may be overridden via the environment
   557    655   # prior to running nmake in order to match the actual installed location and
   558    656   # version on this machine.
   559    657   #
   560    658   !IFNDEF TCLINCDIR
................................................................................
   598    696   # know the specific version we want to use.  This variable (TCLSH_CMD) may be
   599    697   # overridden via the environment prior to running nmake in order to select a
   600    698   # specific Tcl shell to use.
   601    699   #
   602    700   !IFNDEF TCLSH_CMD
   603    701   TCLSH_CMD = tclsh85
   604    702   !ENDIF
          703  +# <</mark>>
   605    704   
   606    705   # Compiler options needed for programs that use the readline() library.
   607    706   #
   608    707   !IFNDEF READLINE_FLAGS
   609    708   READLINE_FLAGS = -DHAVE_READLINE=0
   610    709   !ENDIF
   611    710   
................................................................................
   655    754   !IF $(USE_RPCRT4_LIB)!=0
   656    755   REQ_FEATURE_FLAGS = $(REQ_FEATURE_FLAGS) -DSQLITE_WIN32_USE_UUID=1
   657    756   !ENDIF
   658    757   
   659    758   # Add the required and optional SQLite compilation options into the command
   660    759   # lines used to invoke the MSVC code and resource compilers.
   661    760   #
   662         -TCC = $(TCC) $(REQ_FEATURE_FLAGS) $(OPT_FEATURE_FLAGS)
   663         -RCC = $(RCC) $(REQ_FEATURE_FLAGS) $(OPT_FEATURE_FLAGS)
          761  +TCC = $(TCC) $(REQ_FEATURE_FLAGS) $(OPT_FEATURE_FLAGS) $(EXT_FEATURE_FLAGS)
          762  +RCC = $(RCC) $(REQ_FEATURE_FLAGS) $(OPT_FEATURE_FLAGS) $(EXT_FEATURE_FLAGS)
   664    763   
   665    764   # Add in any optional parameters specified on the commane line, e.g.
   666    765   # nmake /f Makefile.msc all "OPTS=-DSQLITE_ENABLE_FOO=1 -DSQLITE_OMIT_FOO=1"
   667    766   #
   668    767   TCC = $(TCC) $(OPTS)
   669    768   RCC = $(RCC) $(OPTS)
   670    769   
................................................................................
   696    795   # If symbols are enabled (or compiling for debugging), enable PDBs.
   697    796   #
   698    797   !IF $(DEBUG)>1 || $(SYMBOLS)!=0
   699    798   TCC = $(TCC) -Zi
   700    799   BCC = $(BCC) -Zi
   701    800   !ENDIF
   702    801   
          802  +# <<mark>>
   703    803   # If ICU support is enabled, add the compiler options for it.
   704    804   #
   705    805   !IF $(USE_ICU)!=0
   706    806   TCC = $(TCC) -DSQLITE_ENABLE_ICU=1
   707    807   RCC = $(RCC) -DSQLITE_ENABLE_ICU=1
   708    808   TCC = $(TCC) -I$(TOP)\ext\icu
   709    809   RCC = $(RCC) -I$(TOP)\ext\icu
   710    810   TCC = $(TCC) -I$(ICUINCDIR)
   711    811   RCC = $(RCC) -I$(ICUINCDIR)
   712    812   !ENDIF
          813  +# <</mark>>
   713    814   
   714    815   # Command line prefixes for compiling code, compiling resources,
   715    816   # linking, etc.
   716    817   #
   717    818   LTCOMPILE = $(TCC) -Fo$@
   718    819   LTRCOMPILE = $(RCC) -r
   719    820   LTLIB = lib.exe
................................................................................
   785    886   LTLINKOPTS = $(LTLINKOPTS) /DYNAMICBASE
   786    887   LTLINKOPTS = $(LTLINKOPTS) WindowsPhoneCore.lib RuntimeObject.lib PhoneAppModelHost.lib
   787    888   LTLINKOPTS = $(LTLINKOPTS) /NODEFAULTLIB:kernel32.lib /NODEFAULTLIB:ole32.lib
   788    889   !ENDIF
   789    890   
   790    891   # When compiling for UAP, some extra linker options are also required.
   791    892   #
   792         -!IF $(FOR_UAP)!=0
          893  +!IF $(FOR_UAP)!=0 || $(FOR_WIN10)!=0
   793    894   LTLINKOPTS = $(LTLINKOPTS) /DYNAMICBASE /NODEFAULTLIB:kernel32.lib
   794    895   LTLINKOPTS = $(LTLINKOPTS) mincore.lib
   795    896   !IFDEF PSDKLIBPATH
   796    897   LTLINKOPTS = $(LTLINKOPTS) "/LIBPATH:$(PSDKLIBPATH)"
   797    898   !ENDIF
   798    899   !ENDIF
   799    900   
................................................................................
   801    902   #
   802    903   !IF $(DEBUG)>1 || $(SYMBOLS)!=0
   803    904   LDFLAGS = /DEBUG $(LDOPTS)
   804    905   !ELSE
   805    906   LDFLAGS = $(LDOPTS)
   806    907   !ENDIF
   807    908   
          909  +# <<mark>>
   808    910   # Start with the Tcl related linker options.
   809    911   #
   810    912   !IF $(NO_TCL)==0
   811    913   LTLIBPATHS = /LIBPATH:$(TCLLIBDIR)
   812    914   LTLIBS = $(LIBTCL)
   813    915   !ENDIF
   814    916   
   815    917   # If ICU support is enabled, add the linker options for it.
   816    918   #
   817    919   !IF $(USE_ICU)!=0
   818    920   LTLIBPATHS = $(LTLIBPATHS) /LIBPATH:$(ICULIBDIR)
   819    921   LTLIBS = $(LTLIBS) $(LIBICU)
   820    922   !ENDIF
          923  +# <</mark>>
   821    924   
   822    925   # You should not have to change anything below this line
   823    926   ###############################################################################
   824    927   
          928  +# <<mark>>
   825    929   # Object files for the SQLite library (non-amalgamation).
   826    930   #
   827    931   LIBOBJS0 = vdbe.lo parse.lo alter.lo analyze.lo attach.lo auth.lo \
   828    932            backup.lo bitvec.lo btmutex.lo btree.lo build.lo \
   829    933            callback.lo complete.lo ctime.lo date.lo dbstat.lo delete.lo \
   830    934            expr.lo fault.lo fkey.lo \
   831    935            fts3.lo fts3_aux.lo fts3_expr.lo fts3_hash.lo fts3_icu.lo \
................................................................................
   841    945            pager.lo pcache.lo pcache1.lo pragma.lo prepare.lo printf.lo \
   842    946            random.lo resolve.lo rowset.lo rtree.lo select.lo sqlite3rbu.lo status.lo \
   843    947            table.lo threads.lo tokenize.lo treeview.lo trigger.lo \
   844    948            update.lo util.lo vacuum.lo \
   845    949            vdbeapi.lo vdbeaux.lo vdbeblob.lo vdbemem.lo vdbesort.lo \
   846    950            vdbetrace.lo wal.lo walker.lo where.lo wherecode.lo whereexpr.lo \
   847    951            utf.lo vtab.lo
          952  +# <</mark>>
   848    953   
   849    954   # Object files for the amalgamation.
   850    955   #
   851    956   LIBOBJS1 = sqlite3.lo
   852    957   
   853    958   # Determine the real value of LIBOBJ based on the 'configure' script
   854    959   #
          960  +# <<mark>>
   855    961   !IF $(USE_AMALGAMATION)==0
   856    962   LIBOBJ = $(LIBOBJS0)
   857    963   !ELSE
          964  +# <</mark>>
   858    965   LIBOBJ = $(LIBOBJS1)
          966  +# <<mark>>
   859    967   !ENDIF
          968  +# <</mark>>
   860    969   
   861    970   # Determine if embedded resource compilation and usage are enabled.
   862    971   #
   863    972   !IF $(USE_RC)!=0
   864    973   LIBRESOBJS = sqlite3res.lo
   865    974   !ELSE
   866    975   LIBRESOBJS =
   867    976   !ENDIF
   868    977   
          978  +# <<mark>>
   869    979   # All of the source code files.
   870    980   #
   871    981   SRC1 = \
   872    982     $(TOP)\src\alter.c \
   873    983     $(TOP)\src\analyze.c \
   874    984     $(TOP)\src\attach.c \
   875    985     $(TOP)\src\auth.c \
................................................................................
  1020   1130   #
  1021   1131   SRC5 = \
  1022   1132     keywordhash.h \
  1023   1133     opcodes.c \
  1024   1134     opcodes.h \
  1025   1135     parse.c \
  1026   1136     parse.h \
  1027         -  sqlite3.h
         1137  +  $(SQLITE3H)
  1028   1138   
  1029   1139   # All source code files.
  1030   1140   #
  1031   1141   SRC = $(SRC1) $(SRC2) $(SRC3) $(SRC4) $(SRC5)
  1032   1142   
  1033   1143   # Source code to the test files.
  1034   1144   #
................................................................................
  1164   1274      $(TOP)\src\os_common.h \
  1165   1275      $(TOP)\src\os_setup.h \
  1166   1276      $(TOP)\src\os_win.h \
  1167   1277      $(TOP)\src\pager.h \
  1168   1278      $(TOP)\src\pcache.h \
  1169   1279      parse.h \
  1170   1280      $(TOP)\src\pragma.h \
  1171         -   sqlite3.h \
         1281  +   $(SQLITE3H) \
  1172   1282      $(TOP)\src\sqlite3ext.h \
  1173   1283      $(TOP)\src\sqliteInt.h \
  1174   1284      $(TOP)\src\sqliteLimit.h \
  1175   1285      $(TOP)\src\vdbe.h \
  1176   1286      $(TOP)\src\vdbeInt.h \
  1177   1287      $(TOP)\src\vxworks.h \
  1178   1288      $(TOP)\src\whereInt.h
................................................................................
  1199   1309   EXTHDR = $(EXTHDR) \
  1200   1310     $(TOP)\ext\rtree\sqlite3rtree.h
  1201   1311   
  1202   1312   # executables needed for testing
  1203   1313   #
  1204   1314   TESTPROGS = \
  1205   1315     testfixture.exe \
  1206         -  sqlite3.exe \
         1316  +  $(SQLITE3EXE) \
  1207   1317     sqlite3_analyzer.exe \
  1208   1318     sqldiff.exe
  1209   1319   
  1210   1320   # Databases containing fuzzer test cases
  1211   1321   #
  1212   1322   FUZZDATA = \
  1213   1323     $(TOP)\test\fuzzdata1.db \
  1214   1324     $(TOP)\test\fuzzdata2.db \
  1215   1325     $(TOP)\test\fuzzdata3.db \
  1216   1326     $(TOP)\test\fuzzdata4.db
         1327  +# <</mark>>
  1217   1328   
  1218         -# Extra compiler options for various shell tools
         1329  +# Additional compiler options for the shell.  These are only effective
         1330  +# when the shell is not being dynamically linked.
  1219   1331   #
  1220         -SHELL_COMPILE_OPTS = -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS5
         1332  +!IF $(DYNAMIC_SHELL)==0 && $(FOR_WIN10)==0
         1333  +SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_SHELL_JSON1 -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS5
         1334  +!ENDIF
         1335  +
         1336  +# <<mark>>
         1337  +# Extra compiler options for various test tools.
         1338  +#
         1339  +MPTESTER_COMPILE_OPTS = -DSQLITE_SHELL_JSON1 -DSQLITE_ENABLE_FTS5
  1221   1340   FUZZERSHELL_COMPILE_OPTS = -DSQLITE_ENABLE_JSON1
  1222   1341   FUZZCHECK_COMPILE_OPTS = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5
  1223   1342   
  1224         -# Standard options to testfixture
         1343  +# Standard options to testfixture.
  1225   1344   #
  1226   1345   TESTOPTS = --verbose=file --output=test-out.txt
         1346  +
         1347  +# Extra targets for the "all" target that require Tcl.
         1348  +#
         1349  +!IF $(NO_TCL)==0
         1350  +ALL_TCL_TARGETS = libtclsqlite3.lib
         1351  +!ELSE
         1352  +ALL_TCL_TARGETS =
         1353  +!ENDIF
         1354  +# <</mark>>
  1227   1355   
  1228   1356   # This is the default Makefile target.  The objects listed here
  1229   1357   # are what get build when you type just "make" with no arguments.
  1230   1358   #
  1231         -all:	dll libsqlite3.lib sqlite3.exe libtclsqlite3.lib
         1359  +all:	dll libsqlite3.lib shell $(ALL_TCL_TARGETS)
         1360  +
         1361  +# Dynamic link library section.
         1362  +#
         1363  +dll: $(SQLITE3DLL)
         1364  +
         1365  +# Shell executable.
         1366  +#
         1367  +shell: $(SQLITE3EXE)
  1232   1368   
  1233   1369   libsqlite3.lib:	$(LIBOBJ)
  1234   1370   	$(LTLIB) $(LTLIBOPTS) /OUT:$@ $(LIBOBJ) $(TLIBS)
  1235   1371   
         1372  +# <<mark>>
  1236   1373   libtclsqlite3.lib:	tclsqlite.lo libsqlite3.lib
  1237   1374   	$(LTLIB) $(LTLIBOPTS) $(LTLIBPATHS) /OUT:$@ tclsqlite.lo libsqlite3.lib $(LIBTCLSTUB) $(TLIBS)
  1238         -
  1239         -sqlite3.exe:	$(TOP)\src\shell.c $(SHELL_CORE_DEP) $(LIBRESOBJS) sqlite3.h
  1240         -	$(LTLINK) $(SHELL_COMPILE_OPTS) $(SHELL_COMPILE_OPTS) $(READLINE_FLAGS) $(TOP)\src\shell.c \
  1241         -		/link /pdb:sqlite3sh.pdb $(LDFLAGS) $(LTLINKOPTS) $(SHELL_LINK_OPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LIBREADLINE) $(LTLIBS) $(TLIBS)
  1242         -
  1243         -sqldiff.exe:	$(TOP)\tool\sqldiff.c sqlite3.c sqlite3.h
  1244         -	$(LTLINK) $(NO_WARN) $(TOP)\tool\sqldiff.c sqlite3.c /link $(LDFLAGS) $(LTLINKOPTS)
  1245         -
  1246         -fuzzershell.exe:	$(TOP)\tool\fuzzershell.c sqlite3.c sqlite3.h
  1247         -	$(LTLINK) $(NO_WARN) $(FUZZERSHELL_COMPILE_OPTS) \
  1248         -	  $(TOP)\tool\fuzzershell.c sqlite3.c /link $(LDFLAGS) $(LTLINKOPTS)
  1249         -
  1250         -fuzzcheck.exe:	$(TOP)\test\fuzzcheck.c sqlite3.c sqlite3.h
  1251         -	$(LTLINK) $(NO_WARN) $(FUZZCHECK_COMPILE_OPTS) $(TOP)\test\fuzzcheck.c sqlite3.c /link $(LDFLAGS) $(LTLINKOPTS)
  1252         -
  1253         -mptester.exe:	$(TOP)\mptest\mptest.c $(SHELL_CORE_DEP) $(LIBRESOBJS) sqlite3.h
  1254         -	$(LTLINK) $(NO_WARN) $(SHELL_COMPILE_OPTS) $(TOP)\mptest\mptest.c \
  1255         -		/link $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) $(SHELL_LINK_OPTS) $(LIBRESOBJS) $(LIBREADLINE) $(LTLIBS) $(TLIBS)
         1375  +# <</mark>>
         1376  +
         1377  +$(SQLITE3DLL): $(LIBOBJ) $(LIBRESOBJS) $(CORE_LINK_DEP)
         1378  +	$(LD) $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) /DLL $(CORE_LINK_OPTS) /OUT:$@ $(LIBOBJ) $(LIBRESOBJS) $(LTLIBS) $(TLIBS)
         1379  +
         1380  +# <<mark>>
         1381  +sqlite3.def: libsqlite3.lib
         1382  +	echo EXPORTS > sqlite3.def
         1383  +	dumpbin /all libsqlite3.lib \
         1384  +		| $(TCLSH_CMD) $(TOP)\tool\replace.tcl include "^\s+1 _?(sqlite3_.*)$$" \1 \
         1385  +		| sort >> sqlite3.def
         1386  +# <</mark>>
         1387  +
         1388  +$(SQLITE3EXE):	$(TOP)\src\shell.c $(SHELL_CORE_DEP) $(LIBRESOBJS) $(SHELL_CORE_SRC) $(SQLITE3H)
         1389  +	$(LTLINK) $(SHELL_COMPILE_OPTS) $(READLINE_FLAGS) $(TOP)\src\shell.c $(SHELL_CORE_SRC) \
         1390  +		/link $(SQLITE3EXEPDB) $(LDFLAGS) $(LTLINKOPTS) $(SHELL_LINK_OPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LIBREADLINE) $(LTLIBS) $(TLIBS)
         1391  +
         1392  +# <<mark>>
         1393  +sqldiff.exe:	$(TOP)\tool\sqldiff.c $(SQLITE3C) $(SQLITE3H)
         1394  +	$(LTLINK) $(NO_WARN) $(TOP)\tool\sqldiff.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
         1395  +
         1396  +fuzzershell.exe:	$(TOP)\tool\fuzzershell.c $(SQLITE3C) $(SQLITE3H)
         1397  +	$(LTLINK) $(NO_WARN) $(FUZZERSHELL_COMPILE_OPTS) $(TOP)\tool\fuzzershell.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
         1398  +
         1399  +fuzzcheck.exe:	$(TOP)\test\fuzzcheck.c $(SQLITE3C) $(SQLITE3H)
         1400  +	$(LTLINK) $(NO_WARN) $(FUZZCHECK_COMPILE_OPTS) $(TOP)\test\fuzzcheck.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
         1401  +
         1402  +mptester.exe:	$(TOP)\mptest\mptest.c $(SQLITE3C) $(SQLITE3H)
         1403  +	$(LTLINK) $(NO_WARN) $(MPTESTER_COMPILE_OPTS) $(TOP)\mptest\mptest.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
  1256   1404   
  1257   1405   MPTEST1 = mptester mptest.db $(TOP)\mptest\crash01.test --repeat 20
  1258   1406   MPTEST2 = mptester mptest.db $(TOP)\mptest\multiwrite01.test --repeat 20
  1259   1407   
  1260   1408   mptest:	mptester.exe
  1261   1409   	del /Q mptest.db 2>NUL
  1262   1410   	$(MPTEST1) --journalmode DELETE
................................................................................
  1291   1439   
  1292   1440   sqlite3.c:	.target_source sqlite3ext.h $(TOP)\tool\mksqlite3c.tcl
  1293   1441   	$(TCLSH_CMD) $(TOP)\tool\mksqlite3c.tcl $(MKSQLITE3C_ARGS)
  1294   1442   	copy tsrc\shell.c .
  1295   1443   
  1296   1444   sqlite3-all.c:	sqlite3.c $(TOP)\tool\split-sqlite3c.tcl
  1297   1445   	$(TCLSH_CMD) $(TOP)\tool\split-sqlite3c.tcl
  1298         -
  1299         -# Set the source code file to be used by executables and libraries when
  1300         -# they need the amalgamation.
  1301         -#
  1302         -!IF $(SPLIT_AMALGAMATION)!=0
  1303         -SQLITE3C = sqlite3-all.c
  1304         -!ELSE
  1305         -SQLITE3C = sqlite3.c
  1306         -!ENDIF
         1446  +# <</mark>>
  1307   1447   
  1308   1448   # Rule to build the amalgamation
  1309   1449   #
  1310   1450   sqlite3.lo:	$(SQLITE3C)
  1311   1451   	$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(SQLITE3C)
  1312   1452   
         1453  +# <<mark>>
  1313   1454   # Rules to build the LEMON compiler generator
  1314   1455   #
  1315   1456   lempar.c:	$(TOP)\tool\lempar.c
  1316   1457   	copy $(TOP)\tool\lempar.c .
  1317   1458   
  1318   1459   lemon.exe:	$(TOP)\tool\lemon.c lempar.c
  1319   1460   	$(BCC) $(NO_WARN) -Daccess=_access \
................................................................................
  1326   1467   #     opcodes.lo
  1327   1468   #
  1328   1469   parse.lo:	parse.c $(HDR)
  1329   1470   	$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c parse.c
  1330   1471   
  1331   1472   opcodes.lo:	opcodes.c
  1332   1473   	$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c opcodes.c
         1474  +# <</mark>>
  1333   1475   
  1334   1476   # Rule to build the Win32 resources object file.
  1335   1477   #
  1336   1478   !IF $(USE_RC)!=0
  1337         -$(LIBRESOBJS):	$(TOP)\src\sqlite3.rc $(HDR)
         1479  +# <<block1>>
         1480  +$(LIBRESOBJS):	$(TOP)\src\sqlite3.rc $(SQLITE3H)
  1338   1481   	echo #ifndef SQLITE_RESOURCE_VERSION > sqlite3rc.h
  1339   1482   	for /F %%V in ('type "$(TOP)\VERSION"') do ( \
  1340   1483   		echo #define SQLITE_RESOURCE_VERSION %%V \
  1341   1484   			| $(TCLSH_CMD) $(TOP)\tool\replace.tcl exact . ^, >> sqlite3rc.h \
  1342   1485   	)
  1343   1486   	echo #endif >> sqlite3rc.h
  1344   1487   	$(LTRCOMPILE) -fo $(LIBRESOBJS) $(TOP)\src\sqlite3.rc
         1488  +# <</block1>>
  1345   1489   !ENDIF
  1346   1490   
         1491  +# <<mark>>
  1347   1492   # Rules to build individual *.lo files from files in the src directory.
  1348   1493   #
  1349   1494   alter.lo:	$(TOP)\src\alter.c $(HDR)
  1350   1495   	$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\alter.c
  1351   1496   
  1352   1497   analyze.lo:	$(TOP)\src\analyze.c $(HDR)
  1353   1498   	$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\analyze.c
................................................................................
  1570   1715   
  1571   1716   tclsqlite.lo:	$(TOP)\src\tclsqlite.c $(HDR)
  1572   1717   	$(LTCOMPILE) $(NO_WARN) -DUSE_TCL_STUBS=1 -DBUILD_sqlite -I$(TCLINCDIR) -c $(TOP)\src\tclsqlite.c
  1573   1718   
  1574   1719   tclsqlite-shell.lo:	$(TOP)\src\tclsqlite.c $(HDR)
  1575   1720   	$(LTCOMPILE) $(NO_WARN) -DTCLSH=1 -DBUILD_sqlite -I$(TCLINCDIR) -c $(TOP)\src\tclsqlite.c
  1576   1721   
  1577         -tclsqlite3.exe:	tclsqlite-shell.lo $(SQLITE3C) $(LIBRESOBJS)
         1722  +tclsqlite3.exe:	tclsqlite-shell.lo $(SQLITE3C) $(SQLITE3H) $(LIBRESOBJS)
  1578   1723   	$(LTLINK) $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) /OUT:$@ tclsqlite-shell.lo $(LIBRESOBJS) $(LTLIBS) $(TLIBS)
  1579   1724   
  1580   1725   # Rules to build opcodes.c and opcodes.h
  1581   1726   #
  1582   1727   opcodes.c:	opcodes.h $(TOP)\tool\mkopcodec.tcl
  1583   1728   	$(TCLSH_CMD) $(TOP)\tool\mkopcodec.tcl opcodes.h > opcodes.c
  1584   1729   
................................................................................
  1588   1733   # Rules to build parse.c and parse.h - the outputs of lemon.
  1589   1734   #
  1590   1735   parse.h:	parse.c
  1591   1736   
  1592   1737   parse.c:	$(TOP)\src\parse.y lemon.exe $(TOP)\tool\addopcodes.tcl
  1593   1738   	del /Q parse.y parse.h parse.h.temp 2>NUL
  1594   1739   	copy $(TOP)\src\parse.y .
  1595         -	.\lemon.exe $(REQ_FEATURE_FLAGS) $(OPT_FEATURE_FLAGS) $(OPTS) parse.y
         1740  +	.\lemon.exe $(REQ_FEATURE_FLAGS) $(OPT_FEATURE_FLAGS) $(EXT_FEATURE_FLAGS) $(OPTS) parse.y
  1596   1741   	move parse.h parse.h.temp
  1597   1742   	$(TCLSH_CMD) $(TOP)\tool\addopcodes.tcl parse.h.temp > parse.h
  1598   1743   
  1599         -sqlite3.h:	$(TOP)\src\sqlite.h.in $(TOP)\manifest.uuid $(TOP)\VERSION
  1600         -	$(TCLSH_CMD) $(TOP)\tool\mksqlite3h.tcl $(TOP:\=/) > sqlite3.h
         1744  +$(SQLITE3H):	$(TOP)\src\sqlite.h.in $(TOP)\manifest.uuid $(TOP)\VERSION
         1745  +	$(TCLSH_CMD) $(TOP)\tool\mksqlite3h.tcl $(TOP:\=/) > $(SQLITE3H)
  1601   1746   
  1602   1747   sqlite3ext.h: .target_source
  1603   1748   	copy tsrc\sqlite3ext.h .
  1604   1749   
  1605   1750   mkkeywordhash.exe:	$(TOP)\tool\mkkeywordhash.c
  1606         -	$(BCC) $(NO_WARN) -Fe$@ $(REQ_FEATURE_FLAGS) $(OPT_FEATURE_FLAGS) $(OPTS) \
         1751  +	$(BCC) $(NO_WARN) -Fe$@ $(REQ_FEATURE_FLAGS) $(OPT_FEATURE_FLAGS) $(EXT_FEATURE_FLAGS) $(OPTS) \
  1607   1752   		$(TOP)\tool\mkkeywordhash.c /link $(LDFLAGS) $(NLTLINKOPTS) $(NLTLIBPATHS)
  1608   1753   
  1609   1754   keywordhash.h:	$(TOP)\tool\mkkeywordhash.c mkkeywordhash.exe
  1610   1755   	.\mkkeywordhash.exe > keywordhash.h
  1611   1756   
  1612   1757   
  1613   1758   
................................................................................
  1694   1839      $(TOP)\ext\fts5\fts5_unicode2.c \
  1695   1840      $(TOP)\ext\fts5\fts5_varint.c \
  1696   1841      $(TOP)\ext\fts5\fts5_vocab.c
  1697   1842   
  1698   1843   fts5parse.c:	$(TOP)\ext\fts5\fts5parse.y lemon.exe
  1699   1844   	copy $(TOP)\ext\fts5\fts5parse.y .
  1700   1845   	del /Q fts5parse.h 2>NUL
  1701         -	.\lemon.exe $(REQ_FEATURE_FLAGS) $(OPT_FEATURE_FLAGS) $(OPTS) fts5parse.y
         1846  +	.\lemon.exe $(REQ_FEATURE_FLAGS) $(OPT_FEATURE_FLAGS) $(EXT_FEATURE_FLAGS) $(OPTS) fts5parse.y
  1702   1847   
  1703   1848   fts5parse.h: fts5parse.c
  1704   1849   
  1705   1850   fts5.c: $(FTS5_SRC)
  1706   1851   	$(TCLSH_CMD) $(TOP)\ext\fts5\tool\mkfts5c.tcl
  1707   1852   	copy $(TOP)\ext\fts5\fts5.h .
  1708   1853   
................................................................................
  1733   1878   TESTFIXTURE_SRC1 = $(TESTEXT) $(SQLITE3C)
  1734   1879   !IF $(USE_AMALGAMATION)==0
  1735   1880   TESTFIXTURE_SRC = $(TESTSRC) $(TOP)\src\tclsqlite.c $(TESTFIXTURE_SRC0)
  1736   1881   !ELSE
  1737   1882   TESTFIXTURE_SRC = $(TESTSRC) $(TOP)\src\tclsqlite.c $(TESTFIXTURE_SRC1)
  1738   1883   !ENDIF
  1739   1884   
  1740         -testfixture.exe:	$(TESTFIXTURE_SRC) $(LIBRESOBJS) $(HDR)
         1885  +testfixture.exe:	$(TESTFIXTURE_SRC) $(SQLITE3H) $(LIBRESOBJS) $(HDR)
  1741   1886   	$(LTLINK) -DSQLITE_NO_SYNC=1 $(TESTFIXTURE_FLAGS) \
  1742   1887   		-DBUILD_sqlite -I$(TCLINCDIR) \
  1743   1888   		$(TESTFIXTURE_SRC) \
  1744   1889   		/link $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LTLIBS) $(TLIBS)
  1745   1890   
  1746   1891   extensiontest: testfixture.exe testloadext.dll
  1747   1892   	@set PATH=$(LIBTCLPATH);$(PATH)
................................................................................
  1755   1900   	@set PATH=$(LIBTCLPATH);$(PATH)
  1756   1901   	.\testfixture.exe $(TOP)\test\all.test -soak=1 $(TESTOPTS)
  1757   1902   
  1758   1903   fulltestonly:	$(TESTPROGS) fuzztest
  1759   1904   	@set PATH=$(LIBTCLPATH);$(PATH)
  1760   1905   	.\testfixture.exe $(TOP)\test\full.test
  1761   1906   
  1762         -queryplantest:	testfixture.exe sqlite3.exe
         1907  +queryplantest:	testfixture.exe shell
  1763   1908   	@set PATH=$(LIBTCLPATH);$(PATH)
  1764   1909   	.\testfixture.exe $(TOP)\test\permutations.test queryplanner $(TESTOPTS)
  1765   1910   
  1766   1911   fuzztest:	fuzzcheck.exe
  1767   1912   	.\fuzzcheck.exe $(FUZZDATA)
  1768   1913   
  1769   1914   fastfuzztest:	fuzzcheck.exe
................................................................................
  1782   1927   	@set PATH=$(LIBTCLPATH);$(PATH)
  1783   1928   	.\testfixture.exe $(TOP)\test\veryquick.test $(TESTOPTS)
  1784   1929   
  1785   1930   smoketest:	$(TESTPROGS)
  1786   1931   	@set PATH=$(LIBTCLPATH);$(PATH)
  1787   1932   	.\testfixture.exe $(TOP)\test\main.test $(TESTOPTS)
  1788   1933   
  1789         -sqlite3_analyzer.c: $(SQLITE3C) $(TOP)\src\tclsqlite.c $(TOP)\tool\spaceanal.tcl
         1934  +sqlite3_analyzer.c: $(SQLITE3C) $(SQLITE3H) $(TOP)\src\tclsqlite.c $(TOP)\tool\spaceanal.tcl
  1790   1935   	echo #define TCLSH 2 > $@
  1791   1936   	echo #define SQLITE_ENABLE_DBSTAT_VTAB 1 >> $@
  1792   1937   	copy $@ + $(SQLITE3C) + $(TOP)\src\tclsqlite.c $@
  1793   1938   	echo static const char *tclsh_main_loop(void){ >> $@
  1794   1939   	echo static const char *zMainloop = >> $@
  1795   1940   	$(TCLSH_CMD) $(TOP)\tool\tostr.tcl $(TOP)\tool\spaceanal.tcl >> $@
  1796   1941   	echo ; return zMainloop; } >> $@
................................................................................
  1801   1946   
  1802   1947   testloadext.lo:	$(TOP)\src\test_loadext.c
  1803   1948   	$(LTCOMPILE) $(NO_WARN) -c $(TOP)\src\test_loadext.c
  1804   1949   
  1805   1950   testloadext.dll: testloadext.lo
  1806   1951   	$(LD) $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) /DLL /OUT:$@ testloadext.lo
  1807   1952   
  1808         -showdb.exe:	$(TOP)\tool\showdb.c $(SQLITE3C)
         1953  +showdb.exe:	$(TOP)\tool\showdb.c $(SQLITE3C) $(SQLITE3H)
  1809   1954   	$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \
  1810   1955   		$(TOP)\tool\showdb.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
  1811   1956   
  1812         -showstat4.exe:	$(TOP)\tool\showstat4.c $(SQLITE3C)
         1957  +showstat4.exe:	$(TOP)\tool\showstat4.c $(SQLITE3C) $(SQLITE3H)
  1813   1958   	$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \
  1814   1959   		$(TOP)\tool\showstat4.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
  1815   1960   
  1816         -showjournal.exe:	$(TOP)\tool\showjournal.c $(SQLITE3C)
         1961  +showjournal.exe:	$(TOP)\tool\showjournal.c $(SQLITE3C) $(SQLITE3H)
  1817   1962   	$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \
  1818   1963   		$(TOP)\tool\showjournal.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
  1819   1964   
  1820         -showwal.exe:	$(TOP)\tool\showwal.c $(SQLITE3C)
         1965  +showwal.exe:	$(TOP)\tool\showwal.c $(SQLITE3C) $(SQLITE3H)
  1821   1966   	$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \
  1822   1967   		$(TOP)\tool\showwal.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
  1823   1968   
  1824         -fts3view.exe:	$(TOP)\ext\fts3\tool\fts3view.c $(SQLITE3C)
         1969  +fts3view.exe:	$(TOP)\ext\fts3\tool\fts3view.c $(SQLITE3C) $(SQLITE3H)
  1825   1970   	$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \
  1826   1971   		$(TOP)\ext\fts3\tool\fts3view.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
  1827   1972   
  1828         -rollback-test.exe:	$(TOP)\tool\rollback-test.c $(SQLITE3C)
         1973  +rollback-test.exe:	$(TOP)\tool\rollback-test.c $(SQLITE3C) $(SQLITE3H)
  1829   1974   	$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \
  1830   1975   		$(TOP)\tool\rollback-test.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
  1831   1976   
  1832         -LogEst.exe:	$(TOP)\tool\logest.c sqlite3.h
         1977  +LogEst.exe:	$(TOP)\tool\logest.c $(SQLITE3H)
  1833   1978   	$(LTLINK) $(NO_WARN) -Fe$@ $(TOP)\tool\LogEst.c /link $(LDFLAGS) $(LTLINKOPTS)
  1834   1979   
  1835         -wordcount.exe:	$(TOP)\test\wordcount.c $(SQLITE3C)
         1980  +wordcount.exe:	$(TOP)\test\wordcount.c $(SQLITE3C) $(SQLITE3H)
  1836   1981   	$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \
  1837   1982   		$(TOP)\test\wordcount.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
  1838   1983   
  1839         -speedtest1.exe:	$(TOP)\test\speedtest1.c $(SQLITE3C)
         1984  +speedtest1.exe:	$(TOP)\test\speedtest1.c $(SQLITE3C) $(SQLITE3H)
  1840   1985   	$(LTLINK) $(NO_WARN) -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \
  1841   1986   		$(TOP)\test\speedtest1.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
  1842   1987   
  1843         -rbu.exe: $(TOP)\ext\rbu\rbu.c $(TOP)\ext\rbu\sqlite3rbu.c $(SQLITE3C)
  1844         -	$(LTLINK) $(NO_WARN) -DSQLITE_ENABLE_RBU -Fe$@ $(TOP)\ext\rbu\rbu.c $(SQLITE3C) \
  1845         -		/link $(LDFLAGS) $(LTLINKOPTS)
         1988  +rbu.exe: $(TOP)\ext\rbu\rbu.c $(TOP)\ext\rbu\sqlite3rbu.c $(SQLITE3C) $(SQLITE3H)
         1989  +	$(LTLINK) $(NO_WARN) -DSQLITE_ENABLE_RBU -Fe$@ \
         1990  +		$(TOP)\ext\rbu\rbu.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
         1991  +# <</mark>>
  1846   1992   
  1847   1993   clean:
  1848   1994   	del /Q *.exp *.lo *.ilk *.lib *.obj *.ncb *.pdb *.sdf *.suo 2>NUL
  1849         -	del /Q *.bsc *.cod *.da *.bb *.bbg gmon.out 2>NUL
  1850         -	del /Q sqlite3.h opcodes.c opcodes.h 2>NUL
         1995  +	del /Q *.bsc *.cod *.da *.bb *.bbg *.vc gmon.out 2>NUL
         1996  +# <<mark>>
         1997  +	del /Q $(SQLITE3C) $(SQLITE3H) opcodes.c opcodes.h 2>NUL
  1851   1998   	del /Q lemon.* lempar.c parse.* 2>NUL
  1852   1999   	del /Q mkkeywordhash.* keywordhash.h 2>NUL
  1853   2000   	del /Q notasharedlib.* 2>NUL
  1854   2001   	-rmdir /Q/S .deps 2>NUL
  1855   2002   	-rmdir /Q/S .libs 2>NUL
  1856   2003   	-rmdir /Q/S quota2a 2>NUL
  1857   2004   	-rmdir /Q/S quota2b 2>NUL
................................................................................
  1859   2006   	-rmdir /Q/S tsrc 2>NUL
  1860   2007   	del /Q .target_source 2>NUL
  1861   2008   	del /Q tclsqlite3.exe 2>NUL
  1862   2009   	del /Q testloadext.dll 2>NUL
  1863   2010   	del /Q testfixture.exe test.db 2>NUL
  1864   2011   	del /Q LogEst.exe fts3view.exe rollback-test.exe showdb.exe 2>NUL
  1865   2012   	del /Q showjournal.exe showstat4.exe showwal.exe speedtest1.exe 2>NUL
  1866         -	del /Q mptester.exe wordcount.exe 2>NUL
  1867         -	del /Q sqlite3.exe sqlite3.dll sqlite3.def 2>NUL
         2013  +	del /Q mptester.exe wordcount.exe rbu.exe 2>NUL
         2014  +	del /Q $(SQLITE3EXE) $(SQLITE3DLL) sqlite3.def 2>NUL
  1868   2015   	del /Q sqlite3.c sqlite3-*.c 2>NUL
  1869   2016   	del /Q sqlite3rc.h 2>NUL
  1870   2017   	del /Q shell.c sqlite3ext.h 2>NUL
  1871   2018   	del /Q sqlite3_analyzer.exe sqlite3_analyzer.c 2>NUL
  1872   2019   	del /Q sqlite-*-output.vsix 2>NUL
  1873   2020   	del /Q fuzzershell.exe fuzzcheck.exe sqldiff.exe 2>NUL
  1874   2021   	del /Q fts5.* fts5parse.* 2>NUL
  1875         -
  1876         -# Dynamic link library section.
  1877         -#
  1878         -dll: sqlite3.dll
  1879         -
  1880         -sqlite3.def: libsqlite3.lib
  1881         -	echo EXPORTS > sqlite3.def
  1882         -	dumpbin /all libsqlite3.lib \
  1883         -		| $(TCLSH_CMD) $(TOP)\tool\replace.tcl include "^\s+1 _?(sqlite3_.*)$$" \1 \
  1884         -		| sort >> sqlite3.def
  1885         -
  1886         -sqlite3.dll: $(LIBOBJ) $(LIBRESOBJS) $(CORE_LINK_DEP)
  1887         -	$(LD) $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) /DLL $(CORE_LINK_OPTS) /OUT:$@ $(LIBOBJ) $(LIBRESOBJS) $(LTLIBS) $(TLIBS)
         2022  +# <</mark>>

Changes to autoconf/Makefile.am.

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

Added autoconf/Makefile.msc.

            1  +#### DO NOT EDIT ####
            2  +# This makefile is automatically generated from the Makefile.msc at
            3  +# the root of the canonical SQLite source tree (not the
            4  +# amalgamation tarball) using the tool/mkmsvcmin.tcl
            5  +# script.
            6  +#
            7  +
            8  +#
            9  +# nmake Makefile for SQLite
           10  +#
           11  +###############################################################################
           12  +############################## START OF OPTIONS ###############################
           13  +###############################################################################
           14  +
           15  +# The toplevel directory of the source tree.  This is the directory
           16  +# that contains this "Makefile.msc".
           17  +#
           18  +TOP = .
           19  +
           20  +
           21  +# Set this non-0 to enable full warnings (-W4, etc) when compiling.
           22  +#
           23  +!IFNDEF USE_FULLWARN
           24  +USE_FULLWARN = 0
           25  +!ENDIF
           26  +
           27  +# Set this non-0 to use "stdcall" calling convention for the core library
           28  +# and shell executable.
           29  +#
           30  +!IFNDEF USE_STDCALL
           31  +USE_STDCALL = 0
           32  +!ENDIF
           33  +
           34  +# Set this non-0 to have the shell executable link against the core dynamic
           35  +# link library.
           36  +#
           37  +!IFNDEF DYNAMIC_SHELL
           38  +DYNAMIC_SHELL = 0
           39  +!ENDIF
           40  +
           41  +# Set this non-0 to enable extra code that attempts to detect misuse of the
           42  +# SQLite API.
           43  +#
           44  +!IFNDEF API_ARMOR
           45  +API_ARMOR = 0
           46  +!ENDIF
           47  +
           48  +# If necessary, create a list of harmless compiler warnings to disable when
           49  +# compiling the various tools.  For the SQLite source code itself, warnings,
           50  +# if any, will be disabled from within it.
           51  +#
           52  +!IFNDEF NO_WARN
           53  +!IF $(USE_FULLWARN)!=0
           54  +NO_WARN = -wd4054 -wd4055 -wd4100 -wd4127 -wd4130 -wd4152 -wd4189 -wd4206
           55  +NO_WARN = $(NO_WARN) -wd4210 -wd4232 -wd4305 -wd4306 -wd4702 -wd4706
           56  +!ENDIF
           57  +!ENDIF
           58  +
           59  +# Set this non-0 to use the library paths and other options necessary for
           60  +# Windows Phone 8.1.
           61  +#
           62  +!IFNDEF USE_WP81_OPTS
           63  +USE_WP81_OPTS = 0
           64  +!ENDIF
           65  +
           66  +# Set this non-0 to split the SQLite amalgamation file into chunks to
           67  +# be used for debugging with Visual Studio.
           68  +#
           69  +!IFNDEF SPLIT_AMALGAMATION
           70  +SPLIT_AMALGAMATION = 0
           71  +!ENDIF
           72  +
           73  +
           74  +# Set this non-0 to dynamically link to the MSVC runtime library.
           75  +#
           76  +!IFNDEF USE_CRT_DLL
           77  +USE_CRT_DLL = 0
           78  +!ENDIF
           79  +
           80  +# Set this non-0 to link to the RPCRT4 library.
           81  +#
           82  +!IFNDEF USE_RPCRT4_LIB
           83  +USE_RPCRT4_LIB = 0
           84  +!ENDIF
           85  +
           86  +# Set this non-0 to generate assembly code listings for the source code
           87  +# files.
           88  +#
           89  +!IFNDEF USE_LISTINGS
           90  +USE_LISTINGS = 0
           91  +!ENDIF
           92  +
           93  +# Set this non-0 to attempt setting the native compiler automatically
           94  +# for cross-compiling the command line tools needed during the compilation
           95  +# process.
           96  +#
           97  +!IFNDEF XCOMPILE
           98  +XCOMPILE = 0
           99  +!ENDIF
          100  +
          101  +# Set this non-0 to use the native libraries paths for cross-compiling
          102  +# the command line tools needed during the compilation process.
          103  +#
          104  +!IFNDEF USE_NATIVE_LIBPATHS
          105  +USE_NATIVE_LIBPATHS = 0
          106  +!ENDIF
          107  +
          108  +# Set this 0 to skip the compiling and embedding of version resources.
          109  +#
          110  +!IFNDEF USE_RC
          111  +USE_RC = 1
          112  +!ENDIF
          113  +
          114  +# Set this non-0 to compile binaries suitable for the WinRT environment.
          115  +# This setting does not apply to any binaries that require Tcl to operate
          116  +# properly (i.e. the text fixture, etc).
          117  +#
          118  +!IFNDEF FOR_WINRT
          119  +FOR_WINRT = 0
          120  +!ENDIF
          121  +
          122  +# Set this non-0 to compile binaries suitable for the UAP environment.
          123  +# This setting does not apply to any binaries that require Tcl to operate
          124  +# properly (i.e. the text fixture, etc).
          125  +#
          126  +!IFNDEF FOR_UAP
          127  +FOR_UAP = 0
          128  +!ENDIF
          129  +
          130  +# Set this non-0 to compile binaries suitable for the Windows 10 platform.
          131  +#
          132  +!IFNDEF FOR_WIN10
          133  +FOR_WIN10 = 0
          134  +!ENDIF
          135  +
          136  +
          137  +# Set this to non-0 to create and use PDBs.
          138  +#
          139  +!IFNDEF SYMBOLS
          140  +SYMBOLS = 1
          141  +!ENDIF
          142  +
          143  +# Set this to non-0 to use the SQLite debugging heap subsystem.
          144  +#
          145  +!IFNDEF MEMDEBUG
          146  +MEMDEBUG = 0
          147  +!ENDIF
          148  +
          149  +# Set this to non-0 to use the Win32 native heap subsystem.
          150  +#
          151  +!IFNDEF WIN32HEAP
          152  +WIN32HEAP = 0
          153  +!ENDIF
          154  +
          155  +# Set this to non-0 to enable OSTRACE() macros, which can be useful when
          156  +# debugging.
          157  +#
          158  +!IFNDEF OSTRACE
          159  +OSTRACE = 0
          160  +!ENDIF
          161  +
          162  +# Set this to one of the following values to enable various debugging
          163  +# features.  Each level includes the debugging options from the previous
          164  +# levels.  Currently, the recognized values for DEBUG are:
          165  +#
          166  +# 0 == NDEBUG: Disables assert() and other runtime diagnostics.
          167  +# 1 == SQLITE_ENABLE_API_ARMOR: extra attempts to detect misuse of the API.
          168  +# 2 == Disables NDEBUG and all optimizations and then enables PDBs.
          169  +# 3 == SQLITE_DEBUG: Enables various diagnostics messages and code.
          170  +# 4 == SQLITE_WIN32_MALLOC_VALIDATE: Validate the Win32 native heap per call.
          171  +# 5 == SQLITE_DEBUG_OS_TRACE: Enables output from the OSTRACE() macros.
          172  +# 6 == SQLITE_ENABLE_IOTRACE: Enables output from the IOTRACE() macros.
          173  +#
          174  +!IFNDEF DEBUG
          175  +DEBUG = 0
          176  +!ENDIF
          177  +
          178  +# Enable use of available compiler optimizations?  Normally, this should be
          179  +# non-zero.  Setting this to zero, thus disabling all compiler optimizations,
          180  +# can be useful for testing.
          181  +#
          182  +!IFNDEF OPTIMIZATIONS
          183  +OPTIMIZATIONS = 2
          184  +!ENDIF
          185  +
          186  +# Set the source code file to be used by executables and libraries when
          187  +# they need the amalgamation.
          188  +#
          189  +!IFNDEF SQLITE3C
          190  +!IF $(SPLIT_AMALGAMATION)!=0
          191  +SQLITE3C = sqlite3-all.c
          192  +!ELSE
          193  +SQLITE3C = sqlite3.c
          194  +!ENDIF
          195  +!ENDIF
          196  +
          197  +# Set the include code file to be used by executables and libraries when
          198  +# they need SQLite.
          199  +#
          200  +!IFNDEF SQLITE3H
          201  +SQLITE3H = sqlite3.h
          202  +!ENDIF
          203  +
          204  +# This is the name to use for the SQLite dynamic link library (DLL).
          205  +#
          206  +!IFNDEF SQLITE3DLL
          207  +SQLITE3DLL = sqlite3.dll
          208  +!ENDIF
          209  +
          210  +# This is the name to use for the SQLite import library (LIB).
          211  +#
          212  +!IFNDEF SQLITE3LIB
          213  +SQLITE3LIB = sqlite3.lib
          214  +!ENDIF
          215  +
          216  +# This is the name to use for the SQLite shell executable (EXE).
          217  +#
          218  +!IFNDEF SQLITE3EXE
          219  +SQLITE3EXE = sqlite3.exe
          220  +!ENDIF
          221  +
          222  +# This is the argument used to set the program database (PDB) file for the
          223  +# SQLite shell executable (EXE).
          224  +#
          225  +!IFNDEF SQLITE3EXEPDB
          226  +SQLITE3EXEPDB = /pdb:sqlite3sh.pdb
          227  +!ENDIF
          228  +
          229  +# These are the "standard" SQLite compilation options used when compiling for
          230  +# the Windows platform.
          231  +#
          232  +!IFNDEF OPT_FEATURE_FLAGS
          233  +OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_FTS3=1
          234  +OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_RTREE=1
          235  +OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_COLUMN_METADATA=1
          236  +!ENDIF
          237  +
          238  +# These are the "extended" SQLite compilation options used when compiling for
          239  +# the Windows 10 platform.
          240  +#
          241  +!IFNDEF EXT_FEATURE_FLAGS
          242  +!IF $(FOR_WIN10)!=0
          243  +EXT_FEATURE_FLAGS = $(EXT_FEATURE_FLAGS) -DSQLITE_ENABLE_FTS4=1
          244  +EXT_FEATURE_FLAGS = $(EXT_FEATURE_FLAGS) -DSQLITE_SYSTEM_MALLOC=1
          245  +EXT_FEATURE_FLAGS = $(EXT_FEATURE_FLAGS) -DSQLITE_OMIT_LOCALTIME=1
          246  +!ELSE
          247  +EXT_FEATURE_FLAGS =
          248  +!ENDIF
          249  +!ENDIF
          250  +
          251  +###############################################################################
          252  +############################### END OF OPTIONS ################################
          253  +###############################################################################
          254  +
          255  +# This assumes that MSVC is always installed in 32-bit Program Files directory
          256  +# and sets the variable for use in locating other 32-bit installs accordingly.
          257  +#
          258  +PROGRAMFILES_X86 = $(VCINSTALLDIR)\..\..
          259  +PROGRAMFILES_X86 = $(PROGRAMFILES_X86:\\=\)
          260  +
          261  +# Check for the predefined command macro CC.  This should point to the compiler
          262  +# binary for the target platform.  If it is not defined, simply define it to
          263  +# the legacy default value 'cl.exe'.
          264  +#
          265  +!IFNDEF CC
          266  +CC = cl.exe
          267  +!ENDIF
          268  +
          269  +# Check for the command macro LD.  This should point to the linker binary for
          270  +# the target platform.  If it is not defined, simply define it to the legacy
          271  +# default value 'link.exe'.
          272  +#
          273  +!IFNDEF LD
          274  +LD = link.exe
          275  +!ENDIF
          276  +
          277  +# Check for the predefined command macro RC.  This should point to the resource
          278  +# compiler binary for the target platform.  If it is not defined, simply define
          279  +# it to the legacy default value 'rc.exe'.
          280  +#
          281  +!IFNDEF RC
          282  +RC = rc.exe
          283  +!ENDIF
          284  +
          285  +# Check for the MSVC runtime library path macro.  Othertise, this value will
          286  +# default to the 'lib' directory underneath the MSVC installation directory.
          287  +#
          288  +!IFNDEF CRTLIBPATH
          289  +CRTLIBPATH = $(VCINSTALLDIR)\lib
          290  +!ENDIF
          291  +
          292  +CRTLIBPATH = $(CRTLIBPATH:\\=\)
          293  +
          294  +# Check for the command macro NCC.  This should point to the compiler binary
          295  +# for the platform the compilation process is taking place on.  If it is not
          296  +# defined, simply define it to have the same value as the CC macro.  When
          297  +# cross-compiling, it is suggested that this macro be modified via the command
          298  +# line (since nmake itself does not provide a built-in method to guess it).
          299  +# For example, to use the x86 compiler when cross-compiling for x64, a command
          300  +# line similar to the following could be used (all on one line):
          301  +#
          302  +#     nmake /f Makefile.msc sqlite3.dll
          303  +#           XCOMPILE=1 USE_NATIVE_LIBPATHS=1
          304  +#
          305  +# Alternatively, the full path and file name to the compiler binary for the
          306  +# platform the compilation process is taking place may be specified (all on
          307  +# one line):
          308  +#
          309  +#     nmake /f Makefile.msc sqlite3.dll
          310  +#           "NCC=""%VCINSTALLDIR%\bin\cl.exe"""
          311  +#           USE_NATIVE_LIBPATHS=1
          312  +#
          313  +!IFDEF NCC
          314  +NCC = $(NCC:\\=\)
          315  +!ELSEIF $(XCOMPILE)!=0
          316  +NCC = "$(VCINSTALLDIR)\bin\$(CC)"
          317  +NCC = $(NCC:\\=\)
          318  +!ELSE
          319  +NCC = $(CC)
          320  +!ENDIF
          321  +
          322  +# Check for the MSVC native runtime library path macro.  Othertise,
          323  +# this value will default to the 'lib' directory underneath the MSVC
          324  +# installation directory.
          325  +#
          326  +!IFNDEF NCRTLIBPATH
          327  +NCRTLIBPATH = $(VCINSTALLDIR)\lib
          328  +!ENDIF
          329  +
          330  +NCRTLIBPATH = $(NCRTLIBPATH:\\=\)
          331  +
          332  +# Check for the Platform SDK library path macro.  Othertise, this
          333  +# value will default to the 'lib' directory underneath the Windows
          334  +# SDK installation directory (the environment variable used appears
          335  +# to be available when using Visual C++ 2008 or later via the
          336  +# command line).
          337  +#
          338  +!IFNDEF NSDKLIBPATH
          339  +NSDKLIBPATH = $(WINDOWSSDKDIR)\lib
          340  +!ENDIF
          341  +
          342  +NSDKLIBPATH = $(NSDKLIBPATH:\\=\)
          343  +
          344  +# C compiler and options for use in building executables that
          345  +# will run on the platform that is doing the build.
          346  +#
          347  +!IF $(USE_FULLWARN)!=0
          348  +BCC = $(NCC) -nologo -W4 $(CCOPTS) $(BCCOPTS)
          349  +!ELSE
          350  +BCC = $(NCC) -nologo -W3 $(CCOPTS) $(BCCOPTS)
          351  +!ENDIF
          352  +
          353  +# Check if assembly code listings should be generated for the source
          354  +# code files to be compiled.
          355  +#
          356  +!IF $(USE_LISTINGS)!=0
          357  +BCC = $(BCC) -FAcs
          358  +!ENDIF
          359  +
          360  +# Check if the native library paths should be used when compiling
          361  +# the command line tools used during the compilation process.  If
          362  +# so, set the necessary macro now.
          363  +#
          364  +!IF $(USE_NATIVE_LIBPATHS)!=0
          365  +NLTLIBPATHS = "/LIBPATH:$(NCRTLIBPATH)" "/LIBPATH:$(NSDKLIBPATH)"
          366  +
          367  +!IFDEF NUCRTLIBPATH
          368  +NUCRTLIBPATH = $(NUCRTLIBPATH:\\=\)
          369  +NLTLIBPATHS = $(NLTLIBPATHS) "/LIBPATH:$(NUCRTLIBPATH)"
          370  +!ENDIF
          371  +!ENDIF
          372  +
          373  +# C compiler and options for use in building executables that
          374  +# will run on the target platform.  (BCC and TCC are usually the
          375  +# same unless your are cross-compiling.)
          376  +#
          377  +!IF $(USE_FULLWARN)!=0
          378  +TCC = $(CC) -nologo -W4 -DINCLUDE_MSVC_H=1 $(CCOPTS) $(TCCOPTS)
          379  +!ELSE
          380  +TCC = $(CC) -nologo -W3 $(CCOPTS) $(TCCOPTS)
          381  +!ENDIF
          382  +
          383  +TCC = $(TCC) -DSQLITE_OS_WIN=1 -I$(TOP) -fp:precise
          384  +RCC = $(RC) -DSQLITE_OS_WIN=1 -I$(TOP) $(RCOPTS) $(RCCOPTS)
          385  +
          386  +# Adjust the names of the primary targets for use with Windows 10.
          387  +#
          388  +!IF $(FOR_WIN10)!=0
          389  +SQLITE3DLL = winsqlite3.dll
          390  +SQLITE3LIB = winsqlite3.lib
          391  +SQLITE3EXE = winsqlite3shell.exe
          392  +SQLITE3EXEPDB =
          393  +!ENDIF
          394  +
          395  +# Check if we want to use the "stdcall" calling convention when compiling.
          396  +# This is not supported by the compilers for non-x86 platforms.  It should
          397  +# also be noted here that building any target with these "stdcall" options
          398  +# will most likely fail if the Tcl library is also required.  This is due
          399  +# to how the Tcl library functions are declared and exported (i.e. without
          400  +# an explicit calling convention, which results in "cdecl").
          401  +#
          402  +!IF $(USE_STDCALL)!=0 || $(FOR_WIN10)!=0
          403  +!IF "$(PLATFORM)"=="x86"
          404  +CORE_CCONV_OPTS = -Gz -DSQLITE_CDECL=__cdecl -DSQLITE_STDCALL=__stdcall
          405  +SHELL_CCONV_OPTS = -Gz -DSQLITE_CDECL=__cdecl -DSQLITE_STDCALL=__stdcall
          406  +!ELSE
          407  +!IFNDEF PLATFORM
          408  +CORE_CCONV_OPTS = -Gz -DSQLITE_CDECL=__cdecl -DSQLITE_STDCALL=__stdcall
          409  +SHELL_CCONV_OPTS = -Gz -DSQLITE_CDECL=__cdecl -DSQLITE_STDCALL=__stdcall
          410  +!ELSE
          411  +CORE_CCONV_OPTS =
          412  +SHELL_CCONV_OPTS =
          413  +!ENDIF
          414  +!ENDIF
          415  +!ELSE
          416  +CORE_CCONV_OPTS =
          417  +SHELL_CCONV_OPTS =
          418  +!ENDIF
          419  +
          420  +# These are additional compiler options used for the core library.
          421  +#
          422  +!IFNDEF CORE_COMPILE_OPTS
          423  +!IF $(DYNAMIC_SHELL)!=0 || $(FOR_WIN10)!=0
          424  +CORE_COMPILE_OPTS = $(CORE_CCONV_OPTS) -DSQLITE_API=__declspec(dllexport)
          425  +!ELSE
          426  +CORE_COMPILE_OPTS = $(CORE_CCONV_OPTS)
          427  +!ENDIF
          428  +!ENDIF
          429  +
          430  +# These are the additional targets that the core library should depend on
          431  +# when linking.
          432  +#
          433  +!IFNDEF CORE_LINK_DEP
          434  +!IF $(DYNAMIC_SHELL)!=0 || $(FOR_WIN10)!=0
          435  +CORE_LINK_DEP =
          436  +!ELSE
          437  +CORE_LINK_DEP =
          438  +!ENDIF
          439  +!ENDIF
          440  +
          441  +# These are additional linker options used for the core library.
          442  +#
          443  +!IFNDEF CORE_LINK_OPTS
          444  +!IF $(DYNAMIC_SHELL)!=0 || $(FOR_WIN10)!=0
          445  +CORE_LINK_OPTS =
          446  +!ELSE
          447  +CORE_LINK_OPTS =
          448  +!ENDIF
          449  +!ENDIF
          450  +
          451  +# These are additional compiler options used for the shell executable.
          452  +#
          453  +!IFNDEF SHELL_COMPILE_OPTS
          454  +!IF $(DYNAMIC_SHELL)!=0 || $(FOR_WIN10)!=0
          455  +SHELL_COMPILE_OPTS = $(SHELL_CCONV_OPTS) -DSQLITE_API=__declspec(dllimport)
          456  +!ELSE
          457  +SHELL_COMPILE_OPTS = $(SHELL_CCONV_OPTS)
          458  +!ENDIF
          459  +!ENDIF
          460  +
          461  +# This is the source code that the shell executable should be compiled
          462  +# with.
          463  +#
          464  +!IFNDEF SHELL_CORE_SRC
          465  +!IF $(DYNAMIC_SHELL)!=0 || $(FOR_WIN10)!=0
          466  +SHELL_CORE_SRC =
          467  +!ELSE
          468  +SHELL_CORE_SRC = $(SQLITE3C)
          469  +!ENDIF
          470  +!ENDIF
          471  +
          472  +# This is the core library that the shell executable should depend on.
          473  +#
          474  +!IFNDEF SHELL_CORE_DEP
          475  +!IF $(DYNAMIC_SHELL)!=0 || $(FOR_WIN10)!=0
          476  +SHELL_CORE_DEP = $(SQLITE3DLL)
          477  +!ELSE
          478  +SHELL_CORE_DEP =
          479  +!ENDIF
          480  +!ENDIF
          481  +
          482  +# This is the core library that the shell executable should link with.
          483  +#
          484  +!IFNDEF SHELL_CORE_LIB
          485  +!IF $(DYNAMIC_SHELL)!=0 || $(FOR_WIN10)!=0
          486  +SHELL_CORE_LIB = $(SQLITE3LIB)
          487  +!ELSE
          488  +SHELL_CORE_LIB =
          489  +!ENDIF
          490  +!ENDIF
          491  +
          492  +# These are additional linker options used for the shell executable.
          493  +#
          494  +!IFNDEF SHELL_LINK_OPTS
          495  +SHELL_LINK_OPTS = $(SHELL_CORE_LIB)
          496  +!ENDIF
          497  +
          498  +# Check if assembly code listings should be generated for the source
          499  +# code files to be compiled.
          500  +#
          501  +!IF $(USE_LISTINGS)!=0
          502  +TCC = $(TCC) -FAcs
          503  +!ENDIF
          504  +
          505  +# When compiling the library for use in the WinRT environment,
          506  +# the following compile-time options must be used as well to
          507  +# disable use of Win32 APIs that are not available and to enable
          508  +# use of Win32 APIs that are specific to Windows 8 and/or WinRT.
          509  +#
          510  +!IF $(FOR_WINRT)!=0
          511  +TCC = $(TCC) -DSQLITE_OS_WINRT=1
          512  +RCC = $(RCC) -DSQLITE_OS_WINRT=1
          513  +TCC = $(TCC) -DWINAPI_FAMILY=WINAPI_FAMILY_APP
          514  +RCC = $(RCC) -DWINAPI_FAMILY=WINAPI_FAMILY_APP
          515  +!ENDIF
          516  +
          517  +# C compiler options for the Windows 10 platform (needs MSVC 2015).
          518  +#
          519  +!IF $(FOR_WIN10)!=0
          520  +TCC = $(TCC) /guard:cf -D_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE
          521  +BCC = $(BCC) /guard:cf -D_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE
          522  +!ENDIF
          523  +
          524  +# Also, we need to dynamically link to the correct MSVC runtime
          525  +# when compiling for WinRT (e.g. debug or release) OR if the
          526  +# USE_CRT_DLL option is set to force dynamically linking to the
          527  +# MSVC runtime library.
          528  +#
          529  +!IF $(FOR_WINRT)!=0 || $(FOR_WIN10)!=0 || $(USE_CRT_DLL)!=0
          530  +!IF $(DEBUG)>1
          531  +TCC = $(TCC) -MDd
          532  +BCC = $(BCC) -MDd
          533  +!ELSE
          534  +TCC = $(TCC) -MD
          535  +BCC = $(BCC) -MD
          536  +!ENDIF
          537  +!ELSE
          538  +!IF $(DEBUG)>1
          539  +TCC = $(TCC) -MTd
          540  +BCC = $(BCC) -MTd
          541  +!ELSE
          542  +TCC = $(TCC) -MT
          543  +BCC = $(BCC) -MT
          544  +!ENDIF
          545  +!ENDIF
          546  +
          547  +
          548  +# Define -DNDEBUG to compile without debugging (i.e., for production usage)
          549  +# Omitting the define will cause extra debugging code to be inserted and
          550  +# includes extra comments when "EXPLAIN stmt" is used.
          551  +#
          552  +!IF $(DEBUG)==0
          553  +TCC = $(TCC) -DNDEBUG
          554  +BCC = $(BCC) -DNDEBUG
          555  +RCC = $(RCC) -DNDEBUG
          556  +!ENDIF
          557  +
          558  +!IF $(DEBUG)>0 || $(API_ARMOR)!=0 || $(FOR_WIN10)!=0
          559  +TCC = $(TCC) -DSQLITE_ENABLE_API_ARMOR=1
          560  +RCC = $(RCC) -DSQLITE_ENABLE_API_ARMOR=1
          561  +!ENDIF
          562  +
          563  +!IF $(DEBUG)>2
          564  +TCC = $(TCC) -DSQLITE_DEBUG=1
          565  +RCC = $(RCC) -DSQLITE_DEBUG=1
          566  +!ENDIF
          567  +
          568  +!IF $(DEBUG)>4 || $(OSTRACE)!=0
          569  +TCC = $(TCC) -DSQLITE_FORCE_OS_TRACE=1 -DSQLITE_DEBUG_OS_TRACE=1
          570  +RCC = $(RCC) -DSQLITE_FORCE_OS_TRACE=1 -DSQLITE_DEBUG_OS_TRACE=1
          571  +!ENDIF
          572  +
          573  +!IF $(DEBUG)>5
          574  +TCC = $(TCC) -DSQLITE_ENABLE_IOTRACE=1
          575  +RCC = $(RCC) -DSQLITE_ENABLE_IOTRACE=1
          576  +!ENDIF
          577  +
          578  +# Prevent warnings about "insecure" MSVC runtime library functions
          579  +# being used.
          580  +#
          581  +TCC = $(TCC) -D_CRT_SECURE_NO_DEPRECATE -D_CRT_SECURE_NO_WARNINGS
          582  +BCC = $(BCC) -D_CRT_SECURE_NO_DEPRECATE -D_CRT_SECURE_NO_WARNINGS
          583  +RCC = $(RCC) -D_CRT_SECURE_NO_DEPRECATE -D_CRT_SECURE_NO_WARNINGS
          584  +
          585  +# Prevent warnings about "deprecated" POSIX functions being used.
          586  +#
          587  +TCC = $(TCC) -D_CRT_NONSTDC_NO_DEPRECATE -D_CRT_NONSTDC_NO_WARNINGS
          588  +BCC = $(BCC) -D_CRT_NONSTDC_NO_DEPRECATE -D_CRT_NONSTDC_NO_WARNINGS
          589  +RCC = $(RCC) -D_CRT_NONSTDC_NO_DEPRECATE -D_CRT_NONSTDC_NO_WARNINGS
          590  +
          591  +# Use the SQLite debugging heap subsystem?
          592  +#
          593  +!IF $(MEMDEBUG)!=0
          594  +TCC = $(TCC) -DSQLITE_MEMDEBUG=1
          595  +RCC = $(RCC) -DSQLITE_MEMDEBUG=1
          596  +
          597  +# Use native Win32 heap subsystem instead of malloc/free?
          598  +#
          599  +!ELSEIF $(WIN32HEAP)!=0
          600  +TCC = $(TCC) -DSQLITE_WIN32_MALLOC=1
          601  +RCC = $(RCC) -DSQLITE_WIN32_MALLOC=1
          602  +
          603  +# Validate the heap on every call into the native Win32 heap subsystem?
          604  +#
          605  +!IF $(DEBUG)>3
          606  +TCC = $(TCC) -DSQLITE_WIN32_MALLOC_VALIDATE=1
          607  +RCC = $(RCC) -DSQLITE_WIN32_MALLOC_VALIDATE=1
          608  +!ENDIF
          609  +!ENDIF
          610  +
          611  +
          612  +# Compiler options needed for programs that use the readline() library.
          613  +#
          614  +!IFNDEF READLINE_FLAGS
          615  +READLINE_FLAGS = -DHAVE_READLINE=0
          616  +!ENDIF
          617  +
          618  +# The library that programs using readline() must link against.
          619  +#
          620  +!IFNDEF LIBREADLINE
          621  +LIBREADLINE =
          622  +!ENDIF
          623  +
          624  +# Should the database engine be compiled threadsafe
          625  +#
          626  +TCC = $(TCC) -DSQLITE_THREADSAFE=1
          627  +RCC = $(RCC) -DSQLITE_THREADSAFE=1
          628  +
          629  +# Do threads override each others locks by default (1), or do we test (-1)
          630  +#
          631  +TCC = $(TCC) -DSQLITE_THREAD_OVERRIDE_LOCK=-1
          632  +RCC = $(RCC) -DSQLITE_THREAD_OVERRIDE_LOCK=-1
          633  +
          634  +# Any target libraries which libsqlite must be linked against
          635  +#
          636  +!IFNDEF TLIBS
          637  +TLIBS =
          638  +!ENDIF
          639  +
          640  +# Flags controlling use of the in memory btree implementation
          641  +#
          642  +# SQLITE_TEMP_STORE is 0 to force temporary tables to be in a file, 1 to
          643  +# default to file, 2 to default to memory, and 3 to force temporary
          644  +# tables to always be in memory.
          645  +#
          646  +TCC = $(TCC) -DSQLITE_TEMP_STORE=1
          647  +RCC = $(RCC) -DSQLITE_TEMP_STORE=1
          648  +
          649  +# Enable/disable loadable extensions, and other optional features
          650  +# based on configuration. (-DSQLITE_OMIT*, -DSQLITE_ENABLE*).
          651  +# The same set of OMIT and ENABLE flags should be passed to the
          652  +# LEMON parser generator and the mkkeywordhash tool as well.
          653  +
          654  +# These are the required SQLite compilation options used when compiling for
          655  +# the Windows platform.
          656  +#
          657  +REQ_FEATURE_FLAGS = $(REQ_FEATURE_FLAGS) -DSQLITE_MAX_TRIGGER_DEPTH=100
          658  +
          659  +# If we are linking to the RPCRT4 library, enable features that need it.
          660  +#
          661  +!IF $(USE_RPCRT4_LIB)!=0
          662  +REQ_FEATURE_FLAGS = $(REQ_FEATURE_FLAGS) -DSQLITE_WIN32_USE_UUID=1
          663  +!ENDIF
          664  +
          665  +# Add the required and optional SQLite compilation options into the command
          666  +# lines used to invoke the MSVC code and resource compilers.
          667  +#
          668  +TCC = $(TCC) $(REQ_FEATURE_FLAGS) $(OPT_FEATURE_FLAGS) $(EXT_FEATURE_FLAGS)
          669  +RCC = $(RCC) $(REQ_FEATURE_FLAGS) $(OPT_FEATURE_FLAGS) $(EXT_FEATURE_FLAGS)
          670  +
          671  +# Add in any optional parameters specified on the commane line, e.g.
          672  +# nmake /f Makefile.msc all "OPTS=-DSQLITE_ENABLE_FOO=1 -DSQLITE_OMIT_FOO=1"
          673  +#
          674  +TCC = $(TCC) $(OPTS)
          675  +RCC = $(RCC) $(OPTS)
          676  +
          677  +# If compiling for debugging, add some defines.
          678  +#
          679  +!IF $(DEBUG)>1
          680  +TCC = $(TCC) -D_DEBUG
          681  +BCC = $(BCC) -D_DEBUG
          682  +RCC = $(RCC) -D_DEBUG
          683  +!ENDIF
          684  +
          685  +# If optimizations are enabled or disabled (either implicitly or
          686  +# explicitly), add the necessary flags.
          687  +#
          688  +!IF $(DEBUG)>1 || $(OPTIMIZATIONS)==0
          689  +TCC = $(TCC) -Od
          690  +BCC = $(BCC) -Od
          691  +!ELSEIF $(OPTIMIZATIONS)>=3
          692  +TCC = $(TCC) -Ox
          693  +BCC = $(BCC) -Ox
          694  +!ELSEIF $(OPTIMIZATIONS)==2
          695  +TCC = $(TCC) -O2
          696  +BCC = $(BCC) -O2
          697  +!ELSEIF $(OPTIMIZATIONS)==1
          698  +TCC = $(TCC) -O1
          699  +BCC = $(BCC) -O1
          700  +!ENDIF
          701  +
          702  +# If symbols are enabled (or compiling for debugging), enable PDBs.
          703  +#
          704  +!IF $(DEBUG)>1 || $(SYMBOLS)!=0
          705  +TCC = $(TCC) -Zi
          706  +BCC = $(BCC) -Zi
          707  +!ENDIF
          708  +
          709  +
          710  +# Command line prefixes for compiling code, compiling resources,
          711  +# linking, etc.
          712  +#
          713  +LTCOMPILE = $(TCC) -Fo$@
          714  +LTRCOMPILE = $(RCC) -r
          715  +LTLIB = lib.exe
          716  +LTLINK = $(TCC) -Fe$@
          717  +
          718  +# If requested, link to the RPCRT4 library.
          719  +#
          720  +!IF $(USE_RPCRT4_LIB)!=0
          721  +LTLINK = $(LTLINK) rpcrt4.lib
          722  +!ENDIF
          723  +
          724  +# If a platform was set, force the linker to target that.
          725  +# Note that the vcvars*.bat family of batch files typically
          726  +# set this for you.  Otherwise, the linker will attempt
          727  +# to deduce the binary type based on the object files.
          728  +!IFDEF PLATFORM
          729  +LTLINKOPTS = /NOLOGO /MACHINE:$(PLATFORM)
          730  +LTLIBOPTS = /NOLOGO /MACHINE:$(PLATFORM)
          731  +!ELSE
          732  +LTLINKOPTS = /NOLOGO
          733  +LTLIBOPTS = /NOLOGO
          734  +!ENDIF
          735  +
          736  +# When compiling for use in the WinRT environment, the following
          737  +# linker option must be used to mark the executable as runnable
          738  +# only in the context of an application container.
          739  +#
          740  +!IF $(FOR_WINRT)!=0
          741  +LTLINKOPTS = $(LTLINKOPTS) /APPCONTAINER
          742  +!IF "$(VISUALSTUDIOVERSION)"=="12.0" || "$(VISUALSTUDIOVERSION)"=="14.0"
          743  +!IFNDEF STORELIBPATH
          744  +!IF "$(PLATFORM)"=="x86"
          745  +STORELIBPATH = $(CRTLIBPATH)\store
          746  +!ELSEIF "$(PLATFORM)"=="x64"
          747  +STORELIBPATH = $(CRTLIBPATH)\store\amd64
          748  +!ELSEIF "$(PLATFORM)"=="ARM"
          749  +STORELIBPATH = $(CRTLIBPATH)\store\arm
          750  +!ELSE
          751  +STORELIBPATH = $(CRTLIBPATH)\store
          752  +!ENDIF
          753  +!ENDIF
          754  +STORELIBPATH = $(STORELIBPATH:\\=\)
          755  +LTLINKOPTS = $(LTLINKOPTS) "/LIBPATH:$(STORELIBPATH)"
          756  +!ENDIF
          757  +!ENDIF
          758  +
          759  +# When compiling for Windows Phone 8.1, an extra library path is
          760  +# required.
          761  +#
          762  +!IF $(USE_WP81_OPTS)!=0
          763  +!IFNDEF WP81LIBPATH
          764  +!IF "$(PLATFORM)"=="x86"
          765  +WP81LIBPATH = $(PROGRAMFILES_X86)\Windows Phone Kits\8.1\lib\x86
          766  +!ELSEIF "$(PLATFORM)"=="ARM"
          767  +WP81LIBPATH = $(PROGRAMFILES_X86)\Windows Phone Kits\8.1\lib\ARM
          768  +!ELSE
          769  +WP81LIBPATH = $(PROGRAMFILES_X86)\Windows Phone Kits\8.1\lib\x86
          770  +!ENDIF
          771  +!ENDIF
          772  +!ENDIF
          773  +
          774  +# When compiling for Windows Phone 8.1, some extra linker options
          775  +# are also required.
          776  +#
          777  +!IF $(USE_WP81_OPTS)!=0
          778  +!IFDEF WP81LIBPATH
          779  +LTLINKOPTS = $(LTLINKOPTS) "/LIBPATH:$(WP81LIBPATH)"
          780  +!ENDIF
          781  +LTLINKOPTS = $(LTLINKOPTS) /DYNAMICBASE
          782  +LTLINKOPTS = $(LTLINKOPTS) WindowsPhoneCore.lib RuntimeObject.lib PhoneAppModelHost.lib
          783  +LTLINKOPTS = $(LTLINKOPTS) /NODEFAULTLIB:kernel32.lib /NODEFAULTLIB:ole32.lib
          784  +!ENDIF
          785  +
          786  +# When compiling for UAP, some extra linker options are also required.
          787  +#
          788  +!IF $(FOR_UAP)!=0 || $(FOR_WIN10)!=0
          789  +LTLINKOPTS = $(LTLINKOPTS) /DYNAMICBASE /NODEFAULTLIB:kernel32.lib
          790  +LTLINKOPTS = $(LTLINKOPTS) mincore.lib
          791  +!IFDEF PSDKLIBPATH
          792  +LTLINKOPTS = $(LTLINKOPTS) "/LIBPATH:$(PSDKLIBPATH)"
          793  +!ENDIF
          794  +!ENDIF
          795  +
          796  +# If either debugging or symbols are enabled, enable PDBs.
          797  +#
          798  +!IF $(DEBUG)>1 || $(SYMBOLS)!=0
          799  +LDFLAGS = /DEBUG $(LDOPTS)
          800  +!ELSE
          801  +LDFLAGS = $(LDOPTS)
          802  +!ENDIF
          803  +
          804  +
          805  +# You should not have to change anything below this line
          806  +###############################################################################
          807  +
          808  +
          809  +# Object files for the amalgamation.
          810  +#
          811  +LIBOBJS1 = sqlite3.lo
          812  +
          813  +# Determine the real value of LIBOBJ based on the 'configure' script
          814  +#
          815  +LIBOBJ = $(LIBOBJS1)
          816  +
          817  +# Determine if embedded resource compilation and usage are enabled.
          818  +#
          819  +!IF $(USE_RC)!=0
          820  +LIBRESOBJS = sqlite3res.lo
          821  +!ELSE
          822  +LIBRESOBJS =
          823  +!ENDIF
          824  +
          825  +
          826  +# Additional compiler options for the shell.  These are only effective
          827  +# when the shell is not being dynamically linked.
          828  +#
          829  +!IF $(DYNAMIC_SHELL)==0 && $(FOR_WIN10)==0
          830  +SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_SHELL_JSON1 -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS5
          831  +!ENDIF
          832  +
          833  +
          834  +# This is the default Makefile target.  The objects listed here
          835  +# are what get build when you type just "make" with no arguments.
          836  +#
          837  +all:	dll libsqlite3.lib shell
          838  +
          839  +# Dynamic link library section.
          840  +#
          841  +dll: $(SQLITE3DLL)
          842  +
          843  +# Shell executable.
          844  +#
          845  +shell: $(SQLITE3EXE)
          846  +
          847  +libsqlite3.lib:	$(LIBOBJ)
          848  +	$(LTLIB) $(LTLIBOPTS) /OUT:$@ $(LIBOBJ) $(TLIBS)
          849  +
          850  +
          851  +$(SQLITE3DLL): $(LIBOBJ) $(LIBRESOBJS) $(CORE_LINK_DEP)
          852  +	$(LD) $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) /DLL $(CORE_LINK_OPTS) /OUT:$@ $(LIBOBJ) $(LIBRESOBJS) $(LTLIBS) $(TLIBS)
          853  +
          854  +
          855  +$(SQLITE3EXE):	$(TOP)\shell.c $(SHELL_CORE_DEP) $(LIBRESOBJS) $(SHELL_CORE_SRC) $(SQLITE3H)
          856  +	$(LTLINK) $(SHELL_COMPILE_OPTS) $(READLINE_FLAGS) $(TOP)\shell.c $(SHELL_CORE_SRC) \
          857  +		/link $(SQLITE3EXEPDB) $(LDFLAGS) $(LTLINKOPTS) $(SHELL_LINK_OPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LIBREADLINE) $(LTLIBS) $(TLIBS)
          858  +
          859  +
          860  +# Rule to build the amalgamation
          861  +#
          862  +sqlite3.lo:	$(SQLITE3C)
          863  +	$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(SQLITE3C)
          864  +
          865  +
          866  +# Rule to build the Win32 resources object file.
          867  +#
          868  +!IF $(USE_RC)!=0
          869  +_HASHCHAR=^#
          870  +!IF ![echo !IFNDEF VERSION > rcver.vc] && \
          871  +    ![for /F "delims=" %V in ('type "$(SQLITE3H)" ^| find "$(_HASHCHAR)define SQLITE_VERSION "') do (echo VERSION = ^^%V >> rcver.vc)] && \
          872  +    ![echo !ENDIF >> rcver.vc]
          873  +!INCLUDE rcver.vc
          874  +!ENDIF
          875  +
          876  +RESOURCE_VERSION = $(VERSION:^#=)
          877  +RESOURCE_VERSION = $(RESOURCE_VERSION:define=)
          878  +RESOURCE_VERSION = $(RESOURCE_VERSION:SQLITE_VERSION=)
          879  +RESOURCE_VERSION = $(RESOURCE_VERSION:"=)
          880  +RESOURCE_VERSION = $(RESOURCE_VERSION:.=,)
          881  +
          882  +$(LIBRESOBJS):	$(TOP)\sqlite3.rc rcver.vc $(SQLITE3H)
          883  +	echo #ifndef SQLITE_RESOURCE_VERSION > sqlite3rc.h
          884  +	echo #define SQLITE_RESOURCE_VERSION $(RESOURCE_VERSION) >> sqlite3rc.h
          885  +	echo #endif >> sqlite3rc.h
          886  +	$(LTRCOMPILE) -fo $(LIBRESOBJS) -DRC_VERONLY $(TOP)\sqlite3.rc
          887  +!ENDIF
          888  +
          889  +
          890  +clean:
          891  +	del /Q *.exp *.lo *.ilk *.lib *.obj *.ncb *.pdb *.sdf *.suo 2>NUL
          892  +	del /Q *.bsc *.cod *.da *.bb *.bbg *.vc gmon.out 2>NUL

Name change from autoconf/README to autoconf/README.txt.

     1         -
     2      1   This package contains:
     3      2   
     4      3    * the SQLite library amalgamation (single file) source code distribution,
     5      4    * the shell.c file used to build the sqlite3 shell too, and
     6      5    * the sqlite3.h and sqlite3ext.h header files required to link programs
     7      6      and sqlite extensions against the installed libary.
     8         - * autoconf/automake installation infrastucture.
            7  + * autoconf/automake installation infrastucture for building on POSIX
            8  +   compliant systems.
            9  + * a Makefile.msc and sqlite3.rc for building with Microsoft Visual C++ on
           10  +   Windows.
           11  +
           12  +SUMMARY OF HOW TO BUILD
           13  +=======================
           14  +
           15  +  Unix:      ./configure; make
           16  +  Windows:   nmake /f Makefile.msc
           17  +
           18  +BUILDING ON POSIX
           19  +=================
     9     20   
    10     21   The generic installation instructions for autoconf/automake are found
    11     22   in the INSTALL file.
    12     23   
    13     24   The following SQLite specific boolean options are supported:
    14     25   
    15     26     --enable-readline           use readline in shell tool   [default=yes]
    16     27     --enable-threadsafe         build a thread-safe library  [default=yes]
    17     28     --enable-dynamic-extensions support loadable extensions  [default=yes]
    18     29   
    19         -The default value for the CFLAGS variable (options passed to the C 
           30  +The default value for the CFLAGS variable (options passed to the C
    20     31   compiler) includes debugging symbols in the build, resulting in larger
    21     32   binaries than are necessary. Override it on the configure command
    22     33   line like this:
    23     34   
    24     35     $ CFLAGS="-Os" ./configure
    25     36   
    26     37   to produce a smaller installation footprint.
    27     38   
    28     39   Other SQLite compilation parameters can also be set using CFLAGS. For
    29     40   example:
    30     41   
    31     42     $ CFLAGS="-Os -DSQLITE_OMIT_TRIGGERS" ./configure
    32     43   
           44  +
           45  +BUILDING WITH MICROSOFT VISUAL C++
           46  +==================================
           47  +
           48  +To compile for Windows using Microsoft Visual C++:
           49  +
           50  +  $ nmake /f Makefile.msc
           51  +
           52  +Using Microsoft Visual C++ 2005 (or later) is recommended.  Several Windows
           53  +platform variants may be built by adding additional macros to the NMAKE
           54  +command line.
           55  +
           56  +Building for WinRT 8.0
           57  +----------------------
           58  +
           59  +  FOR_WINRT=1
           60  +
           61  +Using Microsoft Visual C++ 2012 (or later) is required.  When using the
           62  +above, something like the following macro will need to be added to the
           63  +NMAKE command line as well:
           64  +
           65  +  "NSDKLIBPATH=%WindowsSdkDir%\..\8.0\lib\win8\um\x86"
           66  +
           67  +Building for WinRT 8.1
           68  +----------------------
           69  +
           70  +  FOR_WINRT=1
           71  +
           72  +Using Microsoft Visual C++ 2013 (or later) is required.  When using the
           73  +above, something like the following macro will need to be added to the
           74  +NMAKE command line as well:
           75  +
           76  +  "NSDKLIBPATH=%WindowsSdkDir%\..\8.1\lib\winv6.3\um\x86"
           77  +
           78  +Building for UAP 10.0
           79  +---------------------
           80  +
           81  +  FOR_WINRT=1 FOR_UAP=1
           82  +
           83  +Using Microsoft Visual C++ 2015 (or later) is required.  When using the
           84  +above, something like the following macros will need to be added to the
           85  +NMAKE command line as well:
           86  +
           87  +  "NSDKLIBPATH=%WindowsSdkDir%\..\10\lib\10.0.10586.0\um\x86"
           88  +  "PSDKLIBPATH=%WindowsSdkDir%\..\10\lib\10.0.10586.0\um\x86"
           89  +  "NUCRTLIBPATH=%UniversalCRTSdkDir%\..\10\lib\10.0.10586.0\ucrt\x86"
           90  +
           91  +Building for the Windows 10 SDK
           92  +-------------------------------
           93  +
           94  +  FOR_WIN10=1
           95  +
           96  +Using Microsoft Visual C++ 2015 (or later) is required.  When using the
           97  +above, no other macros should be needed on the NMAKE command line.
           98  +
           99  +Other preprocessor defines
          100  +--------------------------
          101  +
          102  +Additionally, preprocessor defines may be specified by using the OPTS macro
          103  +on the NMAKE command line.  However, not all possible preprocessor defines
          104  +may be specified in this manner as some require the amalgamation to be built
          105  +with them enabled (see http://www.sqlite.org/compile.html). For example, the
          106  +following will work:
          107  +
          108  +  "OPTS=-DSQLITE_ENABLE_STAT4=1 -DSQLITE_ENABLE_JSON1=1"
          109  +
          110  +However, the following will not compile unless the amalgamation was built
          111  +with it enabled:
          112  +
          113  +  "OPTS=-DSQLITE_ENABLE_UPDATE_DELETE_LIMIT=1"

Changes to autoconf/configure.ac.

    45     45   if test x"$enable_editline" != xno ; then
    46     46     sLIBS=$LIBS
    47     47     LIBS=""
    48     48     AC_SEARCH_LIBS([readline],[edit],[enable_readline=no],[enable_editline=no])
    49     49     READLINE_LIBS=$LIBS
    50     50     if test x"$LIBS" != "x"; then
    51     51        AC_DEFINE([HAVE_EDITLINE],1,Define to use BSD editline)
           52  +  else
           53  +    unset ac_cv_search_readline
    52     54     fi
    53     55     LIBS=$sLIBS
    54     56   fi
    55     57   if test x"$enable_readline" != xno ; then
    56     58     sLIBS=$LIBS
    57     59     LIBS=""
    58     60     AC_SEARCH_LIBS(tgetent, curses ncurses ncursesw, [], [])
................................................................................
    69     71   #
    70     72   AC_ARG_ENABLE(threadsafe, [AS_HELP_STRING(
    71     73     [--enable-threadsafe], [build a thread-safe library [default=yes]])], 
    72     74     [], [enable_threadsafe=yes])
    73     75   THREADSAFE_FLAGS=-DSQLITE_THREADSAFE=0
    74     76   if test x"$enable_threadsafe" != "xno"; then
    75     77     THREADSAFE_FLAGS="-D_REENTRANT=1 -DSQLITE_THREADSAFE=1"
           78  +  AC_SEARCH_LIBS(pthread_create, pthread)
    76     79     AC_SEARCH_LIBS(pthread_mutexattr_init, pthread)
    77     80   fi
    78     81   AC_SUBST(THREADSAFE_FLAGS)
    79     82   #-----------------------------------------------------------------------
    80     83   
    81     84   #-----------------------------------------------------------------------
    82     85   #   --enable-dynamic-extensions

Changes to configure.

 10460  10460     SQLITE_THREADSAFE=1
 10461  10461     { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
 10462  10462   $as_echo "yes" >&6; }
 10463  10463   fi
 10464  10464   
 10465  10465   
 10466  10466   if test "$SQLITE_THREADSAFE" = "1"; then
        10467  +  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing pthread_create" >&5
        10468  +$as_echo_n "checking for library containing pthread_create... " >&6; }
        10469  +if ${ac_cv_search_pthread_create+:} false; then :
        10470  +  $as_echo_n "(cached) " >&6
        10471  +else
        10472  +  ac_func_search_save_LIBS=$LIBS
        10473  +cat confdefs.h - <<_ACEOF >conftest.$ac_ext
        10474  +/* end confdefs.h.  */
        10475  +
        10476  +/* Override any GCC internal prototype to avoid an error.
        10477  +   Use char because int might match the return type of a GCC
        10478  +   builtin and then its argument prototype would still apply.  */
        10479  +#ifdef __cplusplus
        10480  +extern "C"
        10481  +#endif
        10482  +char pthread_create ();
        10483  +int
        10484  +main ()
        10485  +{
        10486  +return pthread_create ();
        10487  +  ;
        10488  +  return 0;
        10489  +}
        10490  +_ACEOF
        10491  +for ac_lib in '' pthread; do
        10492  +  if test -z "$ac_lib"; then
        10493  +    ac_res="none required"
        10494  +  else
        10495  +    ac_res=-l$ac_lib
        10496  +    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
        10497  +  fi
        10498  +  if ac_fn_c_try_link "$LINENO"; then :
        10499  +  ac_cv_search_pthread_create=$ac_res
        10500  +fi
        10501  +rm -f core conftest.err conftest.$ac_objext \
        10502  +    conftest$ac_exeext
        10503  +  if ${ac_cv_search_pthread_create+:} false; then :
        10504  +  break
        10505  +fi
        10506  +done
        10507  +if ${ac_cv_search_pthread_create+:} false; then :
        10508  +
        10509  +else
        10510  +  ac_cv_search_pthread_create=no
        10511  +fi
        10512  +rm conftest.$ac_ext
        10513  +LIBS=$ac_func_search_save_LIBS
        10514  +fi
        10515  +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_pthread_create" >&5
        10516  +$as_echo "$ac_cv_search_pthread_create" >&6; }
        10517  +ac_res=$ac_cv_search_pthread_create
        10518  +if test "$ac_res" != no; then :
        10519  +  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
        10520  +
        10521  +fi
        10522  +
 10467  10523     { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing pthread_mutexattr_init" >&5
 10468  10524   $as_echo_n "checking for library containing pthread_mutexattr_init... " >&6; }
 10469  10525   if ${ac_cv_search_pthread_mutexattr_init+:} false; then :
 10470  10526     $as_echo_n "(cached) " >&6
 10471  10527   else
 10472  10528     ac_func_search_save_LIBS=$LIBS
 10473  10529   cat confdefs.h - <<_ACEOF >conftest.$ac_ext

Changes to configure.ac.

   190    190   else
   191    191     SQLITE_THREADSAFE=1
   192    192     AC_MSG_RESULT([yes])
   193    193   fi
   194    194   AC_SUBST(SQLITE_THREADSAFE)
   195    195   
   196    196   if test "$SQLITE_THREADSAFE" = "1"; then
          197  +  AC_SEARCH_LIBS(pthread_create, pthread)
   197    198     AC_SEARCH_LIBS(pthread_mutexattr_init, pthread)
   198    199   fi
   199    200   
   200    201   ##########
   201    202   # Do we want to support release
   202    203   #
   203    204   AC_ARG_ENABLE(releasemode, 

Changes to ext/fts5/fts5Int.h.

    25     25   
    26     26   typedef unsigned char  u8;
    27     27   typedef unsigned int   u32;
    28     28   typedef unsigned short u16;
    29     29   typedef sqlite3_int64 i64;
    30     30   typedef sqlite3_uint64 u64;
    31     31   
    32         -#define ArraySize(x) (sizeof(x) / sizeof(x[0]))
           32  +#define ArraySize(x) ((int)(sizeof(x) / sizeof(x[0])))
    33     33   
    34     34   #define testcase(x)
    35     35   #define ALWAYS(x) 1
    36     36   #define NEVER(x) 0
    37     37   
    38     38   #define MIN(x,y) (((x) < (y)) ? (x) : (y))
    39     39   #define MAX(x,y) (((x) > (y)) ? (x) : (y))
................................................................................
   221    221   
   222    222   /*
   223    223   ** Buffer object for the incremental building of string data.
   224    224   */
   225    225   typedef struct Fts5Buffer Fts5Buffer;
   226    226   struct Fts5Buffer {
   227    227     u8 *p;
   228         -  u32 n;
   229         -  u32 nSpace;
          228  +  int n;
          229  +  int nSpace;
   230    230   };
   231    231   
   232    232   int sqlite3Fts5BufferSize(int*, Fts5Buffer*, u32);
   233    233   void sqlite3Fts5BufferAppendVarint(int*, Fts5Buffer*, i64);
   234    234   void sqlite3Fts5BufferAppendBlob(int*, Fts5Buffer*, u32, const u8*);
   235    235   void sqlite3Fts5BufferAppendString(int *, Fts5Buffer*, const char*);
   236    236   void sqlite3Fts5BufferFree(Fts5Buffer*);
................................................................................
   243    243   #define fts5BufferZero(x)             sqlite3Fts5BufferZero(x)
   244    244   #define fts5BufferAppendVarint(a,b,c) sqlite3Fts5BufferAppendVarint(a,b,c)
   245    245   #define fts5BufferFree(a)             sqlite3Fts5BufferFree(a)
   246    246   #define fts5BufferAppendBlob(a,b,c,d) sqlite3Fts5BufferAppendBlob(a,b,c,d)
   247    247   #define fts5BufferSet(a,b,c,d)        sqlite3Fts5BufferSet(a,b,c,d)
   248    248   
   249    249   #define fts5BufferGrow(pRc,pBuf,nn) ( \
   250         -  (pBuf)->n + (nn) <= (pBuf)->nSpace ? 0 : \
          250  +  (u32)((pBuf)->n) + (u32)(nn) <= (u32)((pBuf)->nSpace) ? 0 : \
   251    251       sqlite3Fts5BufferSize((pRc),(pBuf),(nn)+(pBuf)->n) \
   252    252   )
   253    253   
   254    254   /* Write and decode big-endian 32-bit integer values */
   255    255   void sqlite3Fts5Put32(u8*, int);
   256    256   int sqlite3Fts5Get32(const u8*);
   257    257   
................................................................................
   310    310   /**************************************************************************
   311    311   ** Interface to code in fts5_index.c. fts5_index.c contains contains code
   312    312   ** to access the data stored in the %_data table.
   313    313   */
   314    314   
   315    315   typedef struct Fts5Index Fts5Index;
   316    316   typedef struct Fts5IndexIter Fts5IndexIter;
          317  +
          318  +struct Fts5IndexIter {
          319  +  i64 iRowid;
          320  +  const u8 *pData;
          321  +  int nData;
          322  +};
   317    323   
   318    324   /*
   319    325   ** Values used as part of the flags argument passed to IndexQuery().
   320    326   */
   321    327   #define FTS5INDEX_QUERY_PREFIX     0x0001   /* Prefix query */
   322    328   #define FTS5INDEX_QUERY_DESC       0x0002   /* Docs in descending rowid order */
   323    329   #define FTS5INDEX_QUERY_TEST_NOIDX 0x0004   /* Do not use prefix index */
................................................................................
   378    384   ** The various operations on open token or token prefix iterators opened
   379    385   ** using sqlite3Fts5IndexQuery().
   380    386   */
   381    387   int sqlite3Fts5IterEof(Fts5IndexIter*);
   382    388   int sqlite3Fts5IterNext(Fts5IndexIter*);
   383    389   int sqlite3Fts5IterNextFrom(Fts5IndexIter*, i64 iMatch);
   384    390   i64 sqlite3Fts5IterRowid(Fts5IndexIter*);
   385         -int sqlite3Fts5IterPoslist(Fts5IndexIter*,Fts5Colset*, const u8**, int*, i64*);
   386         -int sqlite3Fts5IterPoslistBuffer(Fts5IndexIter *pIter, Fts5Buffer *pBuf);
   387    391   
   388    392   /*
   389    393   ** Close an iterator opened by sqlite3Fts5IndexQuery().
   390    394   */
   391    395   void sqlite3Fts5IterClose(Fts5IndexIter*);
   392    396   
   393    397   /*
................................................................................
   465    469   
   466    470   int sqlite3Fts5IndexReinit(Fts5Index *p);
   467    471   int sqlite3Fts5IndexOptimize(Fts5Index *p);
   468    472   int sqlite3Fts5IndexMerge(Fts5Index *p, int nMerge);
   469    473   
   470    474   int sqlite3Fts5IndexLoadConfig(Fts5Index *p);
   471    475   
   472         -int sqlite3Fts5IterCollist(Fts5IndexIter*, const u8 **, int*);
   473         -
   474    476   /*
   475    477   ** End of interface to code in fts5_index.c.
   476    478   **************************************************************************/
   477    479   
   478    480   /**************************************************************************
   479    481   ** Interface to code in fts5_varint.c. 
   480    482   */

Changes to ext/fts5/fts5_aux.c.

   540    540       { "snippet",   0, fts5SnippetFunction, 0 },
   541    541       { "highlight", 0, fts5HighlightFunction, 0 },
   542    542       { "bm25",      0, fts5Bm25Function,    0 },
   543    543     };
   544    544     int rc = SQLITE_OK;             /* Return code */
   545    545     int i;                          /* To iterate through builtin functions */
   546    546   
   547         -  for(i=0; rc==SQLITE_OK && i<(int)ArraySize(aBuiltin); i++){
          547  +  for(i=0; rc==SQLITE_OK && i<ArraySize(aBuiltin); i++){
   548    548       rc = pApi->xCreateFunction(pApi,
   549    549           aBuiltin[i].zFunc,
   550    550           aBuiltin[i].pUserData,
   551    551           aBuiltin[i].xFunc,
   552    552           aBuiltin[i].xDestroy
   553    553       );
   554    554     }
   555    555   
   556    556     return rc;
   557    557   }
   558    558   
   559    559   

Changes to ext/fts5/fts5_buffer.c.

   318    318     const char *pTerm, int nTerm, 
   319    319     int *pbPresent
   320    320   ){
   321    321     int rc = SQLITE_OK;
   322    322     *pbPresent = 0;
   323    323     if( p ){
   324    324       int i;
   325         -    int hash = 13;
          325  +    u32 hash = 13;
   326    326       Fts5TermsetEntry *pEntry;
   327    327   
   328    328       /* Calculate a hash value for this term. This is the same hash checksum
   329    329       ** used by the fts5_hash.c module. This is not important for correct
   330    330       ** operation of the module, but is necessary to ensure that some tests
   331    331       ** designed to produce hash table collisions really do work.  */
   332    332       for(i=nTerm-1; i>=0; i--){
................................................................................
   335    335       hash = (hash << 3) ^ hash ^ iIdx;
   336    336       hash = hash % ArraySize(p->apHash);
   337    337   
   338    338       for(pEntry=p->apHash[hash]; pEntry; pEntry=pEntry->pNext){
   339    339         if( pEntry->iIdx==iIdx 
   340    340             && pEntry->nTerm==nTerm 
   341    341             && memcmp(pEntry->pTerm, pTerm, nTerm)==0 
   342         -        ){
          342  +      ){
   343    343           *pbPresent = 1;
   344    344           break;
   345    345         }
   346    346       }
   347    347   
   348    348       if( pEntry==0 ){
   349    349         pEntry = sqlite3Fts5MallocZero(&rc, sizeof(Fts5TermsetEntry) + nTerm);
................................................................................
   359    359     }
   360    360   
   361    361     return rc;
   362    362   }
   363    363   
   364    364   void sqlite3Fts5TermsetFree(Fts5Termset *p){
   365    365     if( p ){
   366         -    int i;
          366  +    u32 i;
   367    367       for(i=0; i<ArraySize(p->apHash); i++){
   368    368         Fts5TermsetEntry *pEntry = p->apHash[i];
   369    369         while( pEntry ){
   370    370           Fts5TermsetEntry *pDel = pEntry;
   371    371           pEntry = pEntry->pNext;
   372    372           sqlite3_free(pDel);
   373    373         }

Changes to ext/fts5/fts5_expr.c.

    58     58   **       FTS5_TERM                (pNear valid)
    59     59   */
    60     60   struct Fts5ExprNode {
    61     61     int eType;                      /* Node type */
    62     62     int bEof;                       /* True at EOF */
    63     63     int bNomatch;                   /* True if entry is not a match */
    64     64   
           65  +  /* Next method for this node. */
           66  +  int (*xNext)(Fts5Expr*, Fts5ExprNode*, int, i64);
           67  +
    65     68     i64 iRowid;                     /* Current rowid */
    66     69     Fts5ExprNearset *pNear;         /* For FTS5_STRING - cluster of phrases */
    67     70   
    68     71     /* Child nodes. For a NOT node, this array always contains 2 entries. For 
    69     72     ** AND or OR nodes, it contains 2 or more entries.  */
    70     73     int nChild;                     /* Number of child nodes */
    71     74     Fts5ExprNode *apChild[1];       /* Array of child nodes */
    72     75   };
    73     76   
    74     77   #define Fts5NodeIsString(p) ((p)->eType==FTS5_TERM || (p)->eType==FTS5_STRING)
    75     78   
           79  +/*
           80  +** Invoke the xNext method of an Fts5ExprNode object. This macro should be
           81  +** used as if it has the same signature as the xNext() methods themselves.
           82  +*/
           83  +#define fts5ExprNodeNext(a,b,c,d) (b)->xNext((a), (b), (c), (d))
           84  +
    76     85   /*
    77     86   ** An instance of the following structure represents a single search term
    78     87   ** or term prefix.
    79     88   */
    80     89   struct Fts5ExprTerm {
    81     90     int bPrefix;                    /* True for a prefix term */
    82     91     char *zTerm;                    /* nul-terminated term */
................................................................................
   230    239     assert( sParse.rc!=SQLITE_OK || sParse.zErr==0 );
   231    240     if( sParse.rc==SQLITE_OK ){
   232    241       *ppNew = pNew = sqlite3_malloc(sizeof(Fts5Expr));
   233    242       if( pNew==0 ){
   234    243         sParse.rc = SQLITE_NOMEM;
   235    244         sqlite3Fts5ParseNodeFree(sParse.pExpr);
   236    245       }else{
   237         -      pNew->pRoot = sParse.pExpr;
          246  +      if( !sParse.pExpr ){
          247  +        const int nByte = sizeof(Fts5ExprNode);
          248  +        pNew->pRoot = (Fts5ExprNode*)sqlite3Fts5MallocZero(&sParse.rc, nByte);
          249  +        if( pNew->pRoot ){
          250  +          pNew->pRoot->bEof = 1;
          251  +        }
          252  +      }else{
          253  +        pNew->pRoot = sParse.pExpr;
          254  +      }
   238    255         pNew->pIndex = 0;
   239    256         pNew->pConfig = pConfig;
   240    257         pNew->apExprPhrase = sParse.apPhrase;
   241    258         pNew->nPhrase = sParse.nPhrase;
   242    259         sParse.apPhrase = 0;
   243    260       }
   244    261     }
................................................................................
   302    319   ** Argument pTerm must be a synonym iterator.
   303    320   */
   304    321   static int fts5ExprSynonymList(
   305    322     Fts5ExprTerm *pTerm, 
   306    323     int bCollist, 
   307    324     Fts5Colset *pColset,
   308    325     i64 iRowid,
   309         -  int *pbDel,                     /* OUT: Caller should sqlite3_free(*pa) */
          326  +  Fts5Buffer *pBuf,               /* Use this buffer for space if required */
   310    327     u8 **pa, int *pn
   311    328   ){
   312    329     Fts5PoslistReader aStatic[4];
   313    330     Fts5PoslistReader *aIter = aStatic;
   314    331     int nIter = 0;
   315    332     int nAlloc = 4;
   316    333     int rc = SQLITE_OK;
   317    334     Fts5ExprTerm *p;
   318    335   
   319    336     assert( pTerm->pSynonym );
   320    337     for(p=pTerm; p; p=p->pSynonym){
   321    338       Fts5IndexIter *pIter = p->pIter;
   322    339       if( sqlite3Fts5IterEof(pIter)==0 && sqlite3Fts5IterRowid(pIter)==iRowid ){
   323         -      const u8 *a;
   324         -      int n;
   325         -
   326         -      if( bCollist ){
   327         -        rc = sqlite3Fts5IterCollist(pIter, &a, &n);
   328         -      }else{
   329         -        i64 dummy;
   330         -        rc = sqlite3Fts5IterPoslist(pIter, pColset, &a, &n, &dummy);
   331         -      }
   332         -
   333         -      if( rc!=SQLITE_OK ) goto synonym_poslist_out;
   334         -      if( n==0 ) continue;
          340  +      if( pIter->nData==0 ) continue;
   335    341         if( nIter==nAlloc ){
   336    342           int nByte = sizeof(Fts5PoslistReader) * nAlloc * 2;
   337    343           Fts5PoslistReader *aNew = (Fts5PoslistReader*)sqlite3_malloc(nByte);
   338    344           if( aNew==0 ){
   339    345             rc = SQLITE_NOMEM;
   340    346             goto synonym_poslist_out;
   341    347           }
   342    348           memcpy(aNew, aIter, sizeof(Fts5PoslistReader) * nIter);
   343    349           nAlloc = nAlloc*2;
   344    350           if( aIter!=aStatic ) sqlite3_free(aIter);
   345    351           aIter = aNew;
   346    352         }
   347         -      sqlite3Fts5PoslistReaderInit(a, n, &aIter[nIter]);
          353  +      sqlite3Fts5PoslistReaderInit(pIter->pData, pIter->nData, &aIter[nIter]);
   348    354         assert( aIter[nIter].bEof==0 );
   349    355         nIter++;
   350    356       }
   351    357     }
   352    358   
   353         -  assert( *pbDel==0 );
   354    359     if( nIter==1 ){
   355    360       *pa = (u8*)aIter[0].a;
   356    361       *pn = aIter[0].n;
   357    362     }else{
   358    363       Fts5PoslistWriter writer = {0};
   359         -    Fts5Buffer buf = {0,0,0};
   360    364       i64 iPrev = -1;
          365  +    fts5BufferZero(pBuf);
   361    366       while( 1 ){
   362    367         int i;
   363    368         i64 iMin = FTS5_LARGEST_INT64;
   364    369         for(i=0; i<nIter; i++){
   365    370           if( aIter[i].bEof==0 ){
   366    371             if( aIter[i].iPos==iPrev ){
   367    372               if( sqlite3Fts5PoslistReaderNext(&aIter[i]) ) continue;
................................................................................
   368    373             }
   369    374             if( aIter[i].iPos<iMin ){
   370    375               iMin = aIter[i].iPos;
   371    376             }
   372    377           }
   373    378         }
   374    379         if( iMin==FTS5_LARGEST_INT64 || rc!=SQLITE_OK ) break;
   375         -      rc = sqlite3Fts5PoslistWriterAppend(&buf, &writer, iMin);
          380  +      rc = sqlite3Fts5PoslistWriterAppend(pBuf, &writer, iMin);
   376    381         iPrev = iMin;
   377    382       }
   378         -    if( rc ){
   379         -      sqlite3_free(buf.p);
   380         -    }else{
   381         -      *pa = buf.p;
   382         -      *pn = buf.n;
   383         -      *pbDel = 1;
          383  +    if( rc==SQLITE_OK ){
          384  +      *pa = pBuf->p;
          385  +      *pn = pBuf->n;
   384    386       }
   385    387     }
   386    388   
   387    389    synonym_poslist_out:
   388    390     if( aIter!=aStatic ) sqlite3_free(aIter);
   389    391     return rc;
   390    392   }
................................................................................
   413    415     int i;
   414    416     int rc = SQLITE_OK;
   415    417     
   416    418     fts5BufferZero(&pPhrase->poslist);
   417    419   
   418    420     /* If the aStatic[] array is not large enough, allocate a large array
   419    421     ** using sqlite3_malloc(). This approach could be improved upon. */
   420         -  if( pPhrase->nTerm>(int)ArraySize(aStatic) ){
          422  +  if( pPhrase->nTerm>ArraySize(aStatic) ){
   421    423       int nByte = sizeof(Fts5PoslistReader) * pPhrase->nTerm;
   422    424       aIter = (Fts5PoslistReader*)sqlite3_malloc(nByte);
   423    425       if( !aIter ) return SQLITE_NOMEM;
   424    426     }
   425    427     memset(aIter, 0, sizeof(Fts5PoslistReader) * pPhrase->nTerm);
   426    428   
   427    429     /* Initialize a term iterator for each term in the phrase */
   428    430     for(i=0; i<pPhrase->nTerm; i++){
   429    431       Fts5ExprTerm *pTerm = &pPhrase->aTerm[i];
   430         -    i64 dummy;
   431    432       int n = 0;
   432    433       int bFlag = 0;
   433         -    const u8 *a = 0;
          434  +    u8 *a = 0;
   434    435       if( pTerm->pSynonym ){
          436  +      Fts5Buffer buf = {0, 0, 0};
   435    437         rc = fts5ExprSynonymList(
   436         -          pTerm, 0, pColset, pNode->iRowid, &bFlag, (u8**)&a, &n
          438  +          pTerm, 0, pColset, pNode->iRowid, &buf, &a, &n
   437    439         );
          440  +      if( rc ){
          441  +        sqlite3_free(a);
          442  +        goto ismatch_out;
          443  +      }
          444  +      if( a==buf.p ) bFlag = 1;
   438    445       }else{
   439         -      rc = sqlite3Fts5IterPoslist(pTerm->pIter, pColset, &a, &n, &dummy);
          446  +      a = (u8*)pTerm->pIter->pData;
          447  +      n = pTerm->pIter->nData;
   440    448       }
   441         -    if( rc!=SQLITE_OK ) goto ismatch_out;
   442    449       sqlite3Fts5PoslistReaderInit(a, n, &aIter[i]);
   443    450       aIter[i].bFlag = (u8)bFlag;
   444    451       if( aIter[i].bEof ) goto ismatch_out;
   445    452     }
   446    453   
   447    454     while( 1 ){
   448    455       int bMatch;
................................................................................
   506    513     memset(p, 0, sizeof(Fts5LookaheadReader));
   507    514     p->a = a;
   508    515     p->n = n;
   509    516     fts5LookaheadReaderNext(p);
   510    517     return fts5LookaheadReaderNext(p);
   511    518   }
   512    519   
   513         -#if 0
   514         -static int fts5LookaheadReaderEof(Fts5LookaheadReader *p){
   515         -  return (p->iPos==FTS5_LOOKAHEAD_EOF);
   516         -}
   517         -#endif
   518         -
   519    520   typedef struct Fts5NearTrimmer Fts5NearTrimmer;
   520    521   struct Fts5NearTrimmer {
   521    522     Fts5LookaheadReader reader;     /* Input iterator */
   522    523     Fts5PoslistWriter writer;       /* Writer context */
   523    524     Fts5Buffer *pOut;               /* Output poslist */
   524    525   };
   525    526   
................................................................................
   549    550     int rc = *pRc;
   550    551     int bMatch;
   551    552   
   552    553     assert( pNear->nPhrase>1 );
   553    554   
   554    555     /* If the aStatic[] array is not large enough, allocate a large array
   555    556     ** using sqlite3_malloc(). This approach could be improved upon. */
   556         -  if( pNear->nPhrase>(int)ArraySize(aStatic) ){
          557  +  if( pNear->nPhrase>ArraySize(aStatic) ){
   557    558       int nByte = sizeof(Fts5NearTrimmer) * pNear->nPhrase;
   558    559       a = (Fts5NearTrimmer*)sqlite3Fts5MallocZero(&rc, nByte);
   559    560     }else{
   560    561       memset(aStatic, 0, sizeof(aStatic));
   561    562     }
   562    563     if( rc!=SQLITE_OK ){
   563    564       *pRc = rc;
................................................................................
   642    643     Fts5ExprNode *pNode,            /* FTS5_STRING or FTS5_TERM node */
   643    644     int bFromValid,
   644    645     i64 iFrom 
   645    646   ){
   646    647     Fts5ExprTerm *pTerm = &pNode->pNear->apPhrase[0]->aTerm[0];
   647    648     int rc = SQLITE_OK;
   648    649   
          650  +  pNode->bNomatch = 0;
   649    651     if( pTerm->pSynonym ){
   650    652       int bEof = 1;
   651    653       Fts5ExprTerm *p;
   652    654   
   653    655       /* Find the firstest rowid any synonym points to. */
   654    656       i64 iRowid = fts5ExprSynonymRowid(pTerm, pExpr->bDesc, 0);
   655    657   
................................................................................
   771    773     if( pExpr->pConfig->eDetail!=FTS5_DETAIL_FULL ){
   772    774       Fts5ExprTerm *pTerm;
   773    775       Fts5ExprPhrase *pPhrase = pNear->apPhrase[0];
   774    776       pPhrase->poslist.n = 0;
   775    777       for(pTerm=&pPhrase->aTerm[0]; pTerm; pTerm=pTerm->pSynonym){
   776    778         Fts5IndexIter *pIter = pTerm->pIter;
   777    779         if( sqlite3Fts5IterEof(pIter)==0 ){
   778         -        int n;
   779         -        i64 iRowid;
   780         -        rc = sqlite3Fts5IterPoslist(pIter, pNear->pColset, 0, &n, &iRowid);
   781         -        if( rc!=SQLITE_OK ){
   782         -          *pRc = rc;
   783         -          return 0;
   784         -        }else if( iRowid==pNode->iRowid && n>0 ){
          780  +        if( pIter->iRowid==pNode->iRowid && pIter->nData>0 ){
   785    781             pPhrase->poslist.n = 1;
   786    782           }
   787    783         }
   788    784       }
   789    785       return pPhrase->poslist.n;
   790    786     }else{
   791    787       int i;
................................................................................
   796    792       for(i=0; rc==SQLITE_OK && i<pNear->nPhrase; i++){
   797    793         Fts5ExprPhrase *pPhrase = pNear->apPhrase[i];
   798    794         if( pPhrase->nTerm>1 || pPhrase->aTerm[0].pSynonym || pNear->pColset ){
   799    795           int bMatch = 0;
   800    796           rc = fts5ExprPhraseIsMatch(pNode, pNear->pColset, pPhrase, &bMatch);
   801    797           if( bMatch==0 ) break;
   802    798         }else{
   803         -        rc = sqlite3Fts5IterPoslistBuffer(
   804         -            pPhrase->aTerm[0].pIter, &pPhrase->poslist
   805         -        );
          799  +        Fts5IndexIter *pIter = pPhrase->aTerm[0].pIter;
          800  +        fts5BufferSet(&rc, &pPhrase->poslist, pIter->nData, pIter->pData);
   806    801         }
   807    802       }
   808    803   
   809    804       *pRc = rc;
   810    805       if( i==pNear->nPhrase && (i==1 || fts5ExprNearIsMatch(pRc, pNear)) ){
   811    806         return 1;
   812    807       }
................................................................................
   819    814     Fts5ExprNode *pNode             /* The "NEAR" node (FTS5_TERM) */
   820    815   ){
   821    816     /* As this "NEAR" object is actually a single phrase that consists 
   822    817     ** of a single term only, grab pointers into the poslist managed by the
   823    818     ** fts5_index.c iterator object. This is much faster than synthesizing 
   824    819     ** a new poslist the way we have to for more complicated phrase or NEAR
   825    820     ** expressions.  */
   826         -  Fts5ExprNearset *pNear = pNode->pNear;
   827         -  Fts5ExprPhrase *pPhrase = pNear->apPhrase[0];
          821  +  Fts5ExprPhrase *pPhrase = pNode->pNear->apPhrase[0];
   828    822     Fts5IndexIter *pIter = pPhrase->aTerm[0].pIter;
   829         -  Fts5Colset *pColset = pNear->pColset;
   830         -  int rc;
   831    823   
   832    824     assert( pNode->eType==FTS5_TERM );
   833         -  assert( pNear->nPhrase==1 && pPhrase->nTerm==1 );
          825  +  assert( pNode->pNear->nPhrase==1 && pPhrase->nTerm==1 );
   834    826     assert( pPhrase->aTerm[0].pSynonym==0 );
   835    827   
   836         -  rc = sqlite3Fts5IterPoslist(pIter, pColset, 
   837         -      (const u8**)&pPhrase->poslist.p, (int*)&pPhrase->poslist.n, &pNode->iRowid
   838         -  );
          828  +  pPhrase->poslist.n = pIter->nData;
          829  +  if( pExpr->pConfig->eDetail==FTS5_DETAIL_FULL ){
          830  +    pPhrase->poslist.p = (u8*)pIter->pData;
          831  +  }
          832  +  pNode->iRowid = pIter->iRowid;
   839    833     pNode->bNomatch = (pPhrase->poslist.n==0);
   840         -  return rc;
          834  +  return SQLITE_OK;
   841    835   }
   842    836   
   843    837   /*
   844    838   ** All individual term iterators in pNear are guaranteed to be valid when
   845    839   ** this function is called. This function checks if all term iterators
   846    840   ** point to the same rowid, and if not, advances them until they do.
   847    841   ** If an EOF is reached before this happens, *pbEof is set to true before
................................................................................
   886    880         for(j=0; j<pPhrase->nTerm; j++){
   887    881           Fts5ExprTerm *pTerm = &pPhrase->aTerm[j];
   888    882           if( pTerm->pSynonym ){
   889    883             i64 iRowid = fts5ExprSynonymRowid(pTerm, bDesc, 0);
   890    884             if( iRowid==iLast ) continue;
   891    885             bMatch = 0;
   892    886             if( fts5ExprSynonymAdvanceto(pTerm, bDesc, &iLast, &rc) ){
          887  +            pNode->bNomatch = 0;
   893    888               pNode->bEof = 1;
   894    889               return rc;
   895    890             }
   896    891           }else{
   897    892             Fts5IndexIter *pIter = pPhrase->aTerm[j].pIter;
   898    893             i64 iRowid = sqlite3Fts5IterRowid(pIter);
   899    894             if( iRowid==iLast ) continue;
................................................................................
   903    898             }
   904    899           }
   905    900         }
   906    901       }
   907    902     }while( bMatch==0 );
   908    903   
   909    904     pNode->iRowid = iLast;
   910         -  pNode->bNomatch = (0==fts5ExprNearTest(&rc, pExpr, pNode));
          905  +  pNode->bNomatch = ((0==fts5ExprNearTest(&rc, pExpr, pNode)) && rc==SQLITE_OK);
          906  +  assert( pNode->bEof==0 || pNode->bNomatch==0 );
   911    907   
   912    908     return rc;
   913    909   }
   914    910   
   915    911   /*
   916    912   ** Initialize all term iterators in the pNear object. If any term is found
   917    913   ** to match no documents at all, return immediately without initializing any
................................................................................
   921    917     Fts5Expr *pExpr,
   922    918     Fts5ExprNode *pNode
   923    919   ){
   924    920     Fts5ExprNearset *pNear = pNode->pNear;
   925    921     int i, j;
   926    922     int rc = SQLITE_OK;
   927    923   
          924  +  assert( pNode->bNomatch==0 );
   928    925     for(i=0; rc==SQLITE_OK && i<pNear->nPhrase; i++){
   929    926       Fts5ExprPhrase *pPhrase = pNear->apPhrase[i];
   930    927       for(j=0; j<pPhrase->nTerm; j++){
   931    928         Fts5ExprTerm *pTerm = &pPhrase->aTerm[j];
   932    929         Fts5ExprTerm *p;
   933    930         int bEof = 1;
   934    931   
................................................................................
   988    985       return (iLhs < iRhs);
   989    986     }
   990    987   }
   991    988   
   992    989   static void fts5ExprSetEof(Fts5ExprNode *pNode){
   993    990     int i;
   994    991     pNode->bEof = 1;
          992  +  pNode->bNomatch = 0;
   995    993     for(i=0; i<pNode->nChild; i++){
   996    994       fts5ExprSetEof(pNode->apChild[i]);
   997    995     }
   998    996   }
   999    997   
  1000    998   static void fts5ExprNodeZeroPoslist(Fts5ExprNode *pNode){
  1001    999     if( pNode->eType==FTS5_STRING || pNode->eType==FTS5_TERM ){
................................................................................
  1010   1008       for(i=0; i<pNode->nChild; i++){
  1011   1009         fts5ExprNodeZeroPoslist(pNode->apChild[i]);
  1012   1010       }
  1013   1011     }
  1014   1012   }
  1015   1013   
  1016   1014   
  1017         -static int fts5ExprNodeNext(Fts5Expr*, Fts5ExprNode*, int, i64);
  1018         -
  1019   1015   /*
  1020   1016   ** Argument pNode is an FTS5_AND node.
  1021   1017   */
  1022   1018   static int fts5ExprAndNextRowid(
  1023   1019     Fts5Expr *pExpr,                /* Expression pPhrase belongs to */
  1024   1020     Fts5ExprNode *pAnd              /* FTS5_AND node to advance */
  1025   1021   ){
................................................................................
  1090   1086     Fts5ExprNode *p1, 
  1091   1087     Fts5ExprNode *p2
  1092   1088   ){
  1093   1089     if( p2->bEof ) return -1;
  1094   1090     if( p1->bEof ) return +1;
  1095   1091     return fts5RowidCmp(pExpr, p1->iRowid, p2->iRowid);
  1096   1092   }
         1093  +
         1094  +/*
         1095  +** xNext() method for a node of type FTS5_TERM.
         1096  +*/
         1097  +static int fts5ExprNodeNext_Term(
         1098  +  Fts5Expr *pExpr, 
         1099  +  Fts5ExprNode *pNode,
         1100  +  int bFromValid,
         1101  +  i64 iFrom
         1102  +){
         1103  +  int rc;
         1104  +  Fts5IndexIter *pIter = pNode->pNear->apPhrase[0]->aTerm[0].pIter;
         1105  +
         1106  +  assert( pNode->bEof==0 );
         1107  +  if( bFromValid ){
         1108  +    rc = sqlite3Fts5IterNextFrom(pIter, iFrom);
         1109  +  }else{
         1110  +    rc = sqlite3Fts5IterNext(pIter);
         1111  +  }
         1112  +  if( rc==SQLITE_OK && sqlite3Fts5IterEof(pIter)==0 ){
         1113  +    rc = fts5ExprTokenTest(pExpr, pNode);
         1114  +  }else{
         1115  +    pNode->bEof = 1;
         1116  +    pNode->bNomatch = 0;
         1117  +  }
         1118  +  return rc;
         1119  +}
  1097   1120   
  1098   1121   /*
  1099   1122   ** Advance node iterator pNode, part of expression pExpr. If argument
  1100   1123   ** bFromValid is zero, then pNode is advanced exactly once. Or, if argument
  1101   1124   ** bFromValid is non-zero, then pNode is advanced until it is at or past
  1102   1125   ** rowid value iFrom. Whether "past" means "less than" or "greater than"
  1103   1126   ** depends on whether this is an ASC or DESC iterator.
  1104   1127   */
  1105         -static int fts5ExprNodeNext(
         1128  +static int fts5ExprNodeNext_Fallback(
  1106   1129     Fts5Expr *pExpr, 
  1107   1130     Fts5ExprNode *pNode,
  1108   1131     int bFromValid,
  1109   1132     i64 iFrom
  1110   1133   ){
  1111   1134     int rc = SQLITE_OK;
  1112   1135   
................................................................................
  1125   1148             rc = sqlite3Fts5IterNext(pIter);
  1126   1149           }
  1127   1150           if( rc==SQLITE_OK && sqlite3Fts5IterEof(pIter)==0 ){
  1128   1151             assert( rc==SQLITE_OK );
  1129   1152             rc = fts5ExprTokenTest(pExpr, pNode);
  1130   1153           }else{
  1131   1154             pNode->bEof = 1;
         1155  +          pNode->bNomatch = 0;
  1132   1156           }
  1133   1157           return rc;
  1134   1158         };
  1135   1159   
  1136   1160         case FTS5_AND: {
  1137   1161           Fts5ExprNode *pLeft = pNode->apChild[0];
  1138   1162           rc = fts5ExprNodeNext(pExpr, pLeft, bFromValid, iFrom);
................................................................................
  1178   1202     */
  1179   1203     assert( bFromValid==0 
  1180   1204         || rc!=SQLITE_OK                                                  /* a */
  1181   1205         || pNode->bEof                                                    /* b */
  1182   1206         || pNode->iRowid==iFrom || pExpr->bDesc==(pNode->iRowid<iFrom)    /* c */
  1183   1207     );
  1184   1208   
         1209  +  assert( pNode->bNomatch==0 || rc==SQLITE_OK );
  1185   1210     return rc;
  1186   1211   }
  1187   1212   
  1188   1213   
  1189   1214   /*
  1190   1215   ** If pNode currently points to a match, this function returns SQLITE_OK
  1191   1216   ** without modifying it. Otherwise, pNode is advanced until it does point
................................................................................
  1244   1269               cmp = fts5NodeCompare(pExpr, p1, p2);
  1245   1270             }
  1246   1271             assert( rc!=SQLITE_OK || cmp<=0 );
  1247   1272             if( cmp || p2->bNomatch ) break;
  1248   1273             rc = fts5ExprNodeNext(pExpr, p1, 0, 0);
  1249   1274           }
  1250   1275           pNode->bEof = p1->bEof;
         1276  +        pNode->bNomatch = p1->bNomatch;
  1251   1277           pNode->iRowid = p1->iRowid;
  1252   1278           if( p1->bEof ){
  1253   1279             fts5ExprNodeZeroPoslist(p2);
  1254   1280           }
  1255   1281           break;
  1256   1282         }
  1257   1283       }
................................................................................
  1266   1292   **
  1267   1293   ** Return an SQLite error code if an error occurs, or SQLITE_OK otherwise.
  1268   1294   ** It is not an error if there are no matches.
  1269   1295   */
  1270   1296   static int fts5ExprNodeFirst(Fts5Expr *pExpr, Fts5ExprNode *pNode){
  1271   1297     int rc = SQLITE_OK;
  1272   1298     pNode->bEof = 0;
         1299  +  pNode->bNomatch = 0;
  1273   1300   
  1274   1301     if( Fts5NodeIsString(pNode) ){
  1275   1302       /* Initialize all term iterators in the NEAR object. */
  1276   1303       rc = fts5ExprNearInitAll(pExpr, pNode);
  1277   1304     }else{
  1278   1305       int i;
         1306  +    int nEof = 0;
  1279   1307       for(i=0; i<pNode->nChild && rc==SQLITE_OK; i++){
         1308  +      Fts5ExprNode *pChild = pNode->apChild[i];
  1280   1309         rc = fts5ExprNodeFirst(pExpr, pNode->apChild[i]);
         1310  +      assert( pChild->bEof==0 || pChild->bEof==1 );
         1311  +      nEof += pChild->bEof;
  1281   1312       }
  1282   1313       pNode->iRowid = pNode->apChild[0]->iRowid;
         1314  +
         1315  +    switch( pNode->eType ){
         1316  +      case FTS5_AND:
         1317  +        if( nEof>0 ) fts5ExprSetEof(pNode);
         1318  +        break;
         1319  +
         1320  +      case FTS5_OR:
         1321  +        if( pNode->nChild==nEof ) fts5ExprSetEof(pNode);
         1322  +        break;
         1323  +
         1324  +      default:
         1325  +        assert( pNode->eType==FTS5_NOT );
         1326  +        pNode->bEof = pNode->apChild[0]->bEof;
         1327  +        break;
         1328  +    }
  1283   1329     }
  1284   1330   
  1285   1331     if( rc==SQLITE_OK ){
  1286   1332       rc = fts5ExprNodeNextMatch(pExpr, pNode);
  1287   1333     }
  1288   1334     return rc;
  1289   1335   }
................................................................................
  1303   1349   **
  1304   1350   ** Return SQLITE_OK if successful, or an SQLite error code otherwise. It
  1305   1351   ** is not considered an error if the query does not match any documents.
  1306   1352   */
  1307   1353   int sqlite3Fts5ExprFirst(Fts5Expr *p, Fts5Index *pIdx, i64 iFirst, int bDesc){
  1308   1354     Fts5ExprNode *pRoot = p->pRoot;
  1309   1355     int rc = SQLITE_OK;
  1310         -  if( pRoot ){
         1356  +  if( pRoot->xNext ){
  1311   1357       p->pIndex = pIdx;
  1312   1358       p->bDesc = bDesc;
  1313   1359       rc = fts5ExprNodeFirst(p, pRoot);
  1314   1360   
  1315   1361       /* If not at EOF but the current rowid occurs earlier than iFirst in
  1316   1362       ** the iteration order, move to document iFirst or later. */
  1317   1363       if( pRoot->bEof==0 && fts5RowidCmp(p, pRoot->iRowid, iFirst)<0 ){
................................................................................
  1331   1377   **
  1332   1378   ** Return SQLITE_OK if successful, or an SQLite error code otherwise. It
  1333   1379   ** is not considered an error if the query does not match any documents.
  1334   1380   */
  1335   1381   int sqlite3Fts5ExprNext(Fts5Expr *p, i64 iLast){
  1336   1382     int rc;
  1337   1383     Fts5ExprNode *pRoot = p->pRoot;
         1384  +  assert( pRoot->bEof==0 && pRoot->bNomatch==0 );
  1338   1385     do {
  1339   1386       rc = fts5ExprNodeNext(p, pRoot, 0, 0);
  1340         -  }while( pRoot->bNomatch && pRoot->bEof==0 && rc==SQLITE_OK );
         1387  +    assert( pRoot->bNomatch==0 || (rc==SQLITE_OK && pRoot->bEof==0) );
         1388  +  }while( pRoot->bNomatch );
  1341   1389     if( fts5RowidCmp(p, pRoot->iRowid, iLast)>0 ){
  1342   1390       pRoot->bEof = 1;
  1343   1391     }
  1344   1392     return rc;
  1345   1393   }
  1346   1394   
  1347   1395   int sqlite3Fts5ExprEof(Fts5Expr *p){
  1348         -  return (p->pRoot==0 || p->pRoot->bEof);
         1396  +  return p->pRoot->bEof;
  1349   1397   }
  1350   1398   
  1351   1399   i64 sqlite3Fts5ExprRowid(Fts5Expr *p){
  1352   1400     return p->pRoot->iRowid;
  1353   1401   }
  1354   1402   
  1355   1403   static int fts5ParseStringFromToken(Fts5Token *pToken, char **pz){
................................................................................
  1366   1414       int i;
  1367   1415       for(i=0; i<pPhrase->nTerm; i++){
  1368   1416         Fts5ExprTerm *pSyn;
  1369   1417         Fts5ExprTerm *pNext;
  1370   1418         Fts5ExprTerm *pTerm = &pPhrase->aTerm[i];
  1371   1419         sqlite3_free(pTerm->zTerm);
  1372   1420         sqlite3Fts5IterClose(pTerm->pIter);
  1373         -
  1374   1421         for(pSyn=pTerm->pSynonym; pSyn; pSyn=pNext){
  1375   1422           pNext = pSyn->pSynonym;
  1376   1423           sqlite3Fts5IterClose(pSyn->pIter);
         1424  +        fts5BufferFree((Fts5Buffer*)&pSyn[1]);
  1377   1425           sqlite3_free(pSyn);
  1378   1426         }
  1379   1427       }
  1380   1428       if( pPhrase->poslist.nSpace>0 ) fts5BufferFree(&pPhrase->poslist);
  1381   1429       sqlite3_free(pPhrase);
  1382   1430     }
  1383   1431   }
................................................................................
  1457   1505   
  1458   1506     /* If an error has already occurred, this is a no-op */
  1459   1507     if( pCtx->rc!=SQLITE_OK ) return pCtx->rc;
  1460   1508   
  1461   1509     assert( pPhrase==0 || pPhrase->nTerm>0 );
  1462   1510     if( pPhrase && (tflags & FTS5_TOKEN_COLOCATED) ){
  1463   1511       Fts5ExprTerm *pSyn;
  1464         -    int nByte = sizeof(Fts5ExprTerm) + nToken+1;
         1512  +    int nByte = sizeof(Fts5ExprTerm) + sizeof(Fts5Buffer) + nToken+1;
  1465   1513       pSyn = (Fts5ExprTerm*)sqlite3_malloc(nByte);
  1466   1514       if( pSyn==0 ){
  1467   1515         rc = SQLITE_NOMEM;
  1468   1516       }else{
  1469   1517         memset(pSyn, 0, nByte);
  1470         -      pSyn->zTerm = (char*)&pSyn[1];
         1518  +      pSyn->zTerm = ((char*)pSyn) + sizeof(Fts5ExprTerm) + sizeof(Fts5Buffer);
  1471   1519         memcpy(pSyn->zTerm, pToken, nToken);
  1472   1520         pSyn->pSynonym = pPhrase->aTerm[pPhrase->nTerm-1].pSynonym;
  1473   1521         pPhrase->aTerm[pPhrase->nTerm-1].pSynonym = pSyn;
  1474   1522       }
  1475   1523     }else{
  1476   1524       Fts5ExprTerm *pTerm;
  1477   1525       if( pPhrase==0 || (pPhrase->nTerm % SZALLOC)==0 ){
................................................................................
  1638   1686       /* All the allocations succeeded. Put the expression object together. */
  1639   1687       pNew->pIndex = pExpr->pIndex;
  1640   1688       pNew->pConfig = pExpr->pConfig;
  1641   1689       pNew->nPhrase = 1;
  1642   1690       pNew->apExprPhrase[0] = sCtx.pPhrase;
  1643   1691       pNew->pRoot->pNear->apPhrase[0] = sCtx.pPhrase;
  1644   1692       pNew->pRoot->pNear->nPhrase = 1;
         1693  +    pNew->pRoot->xNext = fts5ExprNodeNext_Fallback;
  1645   1694       sCtx.pPhrase->pNode = pNew->pRoot;
  1646   1695   
  1647   1696       if( pOrig->nTerm==1 && pOrig->aTerm[0].pSynonym==0 ){
  1648   1697         pNew->pRoot->eType = FTS5_TERM;
  1649   1698       }else{
  1650   1699         pNew->pRoot->eType = FTS5_STRING;
  1651   1700       }
................................................................................
  1838   1887         if( pRight->eType==eType ) nChild += pRight->nChild-1;
  1839   1888       }
  1840   1889   
  1841   1890       nByte = sizeof(Fts5ExprNode) + sizeof(Fts5ExprNode*)*(nChild-1);
  1842   1891       pRet = (Fts5ExprNode*)sqlite3Fts5MallocZero(&pParse->rc, nByte);
  1843   1892   
  1844   1893       if( pRet ){
         1894  +      pRet->xNext = fts5ExprNodeNext_Fallback;
  1845   1895         pRet->eType = eType;
  1846   1896         pRet->pNear = pNear;
  1847   1897         if( eType==FTS5_STRING ){
  1848   1898           int iPhrase;
  1849   1899           for(iPhrase=0; iPhrase<pNear->nPhrase; iPhrase++){
  1850   1900             pNear->apPhrase[iPhrase]->pNode = pRet;
  1851   1901           }
  1852   1902           if( pNear->nPhrase==1 && pNear->apPhrase[0]->nTerm==1 ){
  1853   1903             if( pNear->apPhrase[0]->aTerm[0].pSynonym==0 ){
  1854   1904               pRet->eType = FTS5_TERM;
         1905  +            pRet->xNext = fts5ExprNodeNext_Term;
  1855   1906             }
  1856   1907           }else if( pParse->pConfig->eDetail!=FTS5_DETAIL_FULL ){
  1857   1908             assert( pParse->rc==SQLITE_OK );
  1858   1909             pParse->rc = SQLITE_ERROR;
  1859   1910             assert( pParse->zErr==0 );
  1860   1911             pParse->zErr = sqlite3_mprintf(
  1861   1912                 "fts5: %s queries are not supported (detail!=full)", 
................................................................................
  2142   2193   
  2143   2194     rc = sqlite3Fts5ConfigParse(pGlobal, db, nConfig, azConfig, &pConfig, &zErr);
  2144   2195     if( rc==SQLITE_OK ){
  2145   2196       rc = sqlite3Fts5ExprNew(pConfig, zExpr, &pExpr, &zErr);
  2146   2197     }
  2147   2198     if( rc==SQLITE_OK ){
  2148   2199       char *zText;
  2149         -    if( pExpr->pRoot==0 ){
         2200  +    if( pExpr->pRoot->xNext==0 ){
  2150   2201         zText = sqlite3_mprintf("");
  2151   2202       }else if( bTcl ){
  2152   2203         zText = fts5ExprPrintTcl(pConfig, zNearsetCmd, pExpr->pRoot);
  2153   2204       }else{
  2154   2205         zText = fts5ExprPrint(pConfig, pExpr->pRoot);
  2155   2206       }
  2156   2207       if( zText==0 ){
................................................................................
  2242   2293       { "fts5_isalnum",  fts5ExprIsAlnum },
  2243   2294       { "fts5_fold",     fts5ExprFold },
  2244   2295     };
  2245   2296     int i;
  2246   2297     int rc = SQLITE_OK;
  2247   2298     void *pCtx = (void*)pGlobal;
  2248   2299   
  2249         -  for(i=0; rc==SQLITE_OK && i<(int)ArraySize(aFunc); i++){
         2300  +  for(i=0; rc==SQLITE_OK && i<ArraySize(aFunc); i++){
  2250   2301       struct Fts5ExprFunc *p = &aFunc[i];
  2251   2302       rc = sqlite3_create_function(db, p->z, -1, SQLITE_UTF8, pCtx, p->x, 0, 0);
  2252   2303     }
  2253   2304   
  2254   2305     /* Avoid a warning indicating that sqlite3Fts5ParserTrace() is unused */
  2255   2306   #ifndef NDEBUG
  2256   2307     (void)sqlite3Fts5ParserTrace;
................................................................................
  2480   2531     int *pnCollist
  2481   2532   ){
  2482   2533     Fts5ExprPhrase *pPhrase = pExpr->apExprPhrase[iPhrase];
  2483   2534     Fts5ExprNode *pNode = pPhrase->pNode;
  2484   2535     int rc = SQLITE_OK;
  2485   2536   
  2486   2537     assert( iPhrase>=0 && iPhrase<pExpr->nPhrase );
         2538  +  assert( pExpr->pConfig->eDetail==FTS5_DETAIL_COLUMNS );
         2539  +
  2487   2540     if( pNode->bEof==0 
  2488   2541      && pNode->iRowid==pExpr->pRoot->iRowid 
  2489   2542      && pPhrase->poslist.n>0
  2490   2543     ){
  2491   2544       Fts5ExprTerm *pTerm = &pPhrase->aTerm[0];
  2492   2545       if( pTerm->pSynonym ){
  2493         -      int bDel = 0;
  2494         -      u8 *a;
         2546  +      Fts5Buffer *pBuf = (Fts5Buffer*)&pTerm->pSynonym[1];
  2495   2547         rc = fts5ExprSynonymList(
  2496         -          pTerm, 1, 0, pNode->iRowid, &bDel, &a, pnCollist
         2548  +          pTerm, 1, 0, pNode->iRowid, pBuf, (u8**)ppCollist, pnCollist
  2497   2549         );
  2498         -      if( bDel ){
  2499         -        sqlite3Fts5BufferSet(&rc, &pPhrase->poslist, *pnCollist, a);
  2500         -        *ppCollist = pPhrase->poslist.p;
  2501         -        sqlite3_free(a);
  2502         -      }else{
  2503         -        *ppCollist = a;
  2504         -      }
  2505   2550       }else{
  2506         -      sqlite3Fts5IterCollist(pPhrase->aTerm[0].pIter, ppCollist, pnCollist);
         2551  +      *ppCollist = pPhrase->aTerm[0].pIter->pData;
         2552  +      *pnCollist = pPhrase->aTerm[0].pIter->nData;
  2507   2553       }
  2508   2554     }else{
  2509   2555       *ppCollist = 0;
  2510   2556       *pnCollist = 0;
  2511   2557     }
  2512   2558   
  2513   2559     return rc;
  2514   2560   }
  2515   2561   

Changes to ext/fts5/fts5_index.c.

   257    257   #define FTS5_DATA_ZERO_PADDING 8
   258    258   #define FTS5_DATA_PADDING 20
   259    259   
   260    260   typedef struct Fts5Data Fts5Data;
   261    261   typedef struct Fts5DlidxIter Fts5DlidxIter;
   262    262   typedef struct Fts5DlidxLvl Fts5DlidxLvl;
   263    263   typedef struct Fts5DlidxWriter Fts5DlidxWriter;
          264  +typedef struct Fts5Iter Fts5Iter;
   264    265   typedef struct Fts5PageWriter Fts5PageWriter;
   265    266   typedef struct Fts5SegIter Fts5SegIter;
   266    267   typedef struct Fts5DoclistIter Fts5DoclistIter;
   267    268   typedef struct Fts5SegWriter Fts5SegWriter;
   268    269   typedef struct Fts5Structure Fts5Structure;
   269    270   typedef struct Fts5StructureLevel Fts5StructureLevel;
   270    271   typedef struct Fts5StructureSegment Fts5StructureSegment;
................................................................................
   499    500   ** aFirst[1] contains the index in aSeg[] of the iterator that points to
   500    501   ** the smallest key overall. aFirst[0] is unused. 
   501    502   **
   502    503   ** poslist:
   503    504   **   Used by sqlite3Fts5IterPoslist() when the poslist needs to be buffered.
   504    505   **   There is no way to tell if this is populated or not.
   505    506   */
   506         -struct Fts5IndexIter {
          507  +struct Fts5Iter {
          508  +  Fts5IndexIter base;             /* Base class containing output vars */
          509  +
   507    510     Fts5Index *pIndex;              /* Index that owns this iterator */
   508    511     Fts5Structure *pStruct;         /* Database structure for this iterator */
   509    512     Fts5Buffer poslist;             /* Buffer containing current poslist */
          513  +  Fts5Colset *pColset;            /* Restrict matches to these columns */
          514  +
          515  +  /* Invoked to set output variables. */
          516  +  void (*xSetOutputs)(Fts5Iter*, Fts5SegIter*);
   510    517   
   511    518     int nSeg;                       /* Size of aSeg[] array */
   512    519     int bRev;                       /* True to iterate in reverse order */
   513    520     u8 bSkipEmpty;                  /* True to skip deleted entries */
   514    521     u8 bEof;                        /* True at EOF */
   515    522     u8 bFiltered;                   /* True if column-filter already applied */
   516    523   
................................................................................
  1748   1755   }
  1749   1756   
  1750   1757   /*
  1751   1758   ** Return true if the iterator passed as the second argument currently
  1752   1759   ** points to a delete marker. A delete marker is an entry with a 0 byte
  1753   1760   ** position-list.
  1754   1761   */
  1755         -static int fts5MultiIterIsEmpty(Fts5Index *p, Fts5IndexIter *pIter){
         1762  +static int fts5MultiIterIsEmpty(Fts5Index *p, Fts5Iter *pIter){
  1756   1763     Fts5SegIter *pSeg = &pIter->aSeg[pIter->aFirst[1].iFirst];
  1757   1764     return (p->rc==SQLITE_OK && pSeg->pLeaf && pSeg->nPos==0);
  1758   1765   }
  1759   1766   
  1760   1767   /*
  1761   1768   ** Advance iterator pIter to the next entry.
  1762   1769   **
................................................................................
  2402   2409   /*
  2403   2410   ** This function is used as part of the big assert() procedure implemented by
  2404   2411   ** fts5AssertMultiIterSetup(). It ensures that the result currently stored
  2405   2412   ** in *pRes is the correct result of comparing the current positions of the
  2406   2413   ** two iterators.
  2407   2414   */
  2408   2415   static void fts5AssertComparisonResult(
  2409         -  Fts5IndexIter *pIter, 
         2416  +  Fts5Iter *pIter, 
  2410   2417     Fts5SegIter *p1,
  2411   2418     Fts5SegIter *p2,
  2412   2419     Fts5CResult *pRes
  2413   2420   ){
  2414   2421     int i1 = p1 - pIter->aSeg;
  2415   2422     int i2 = p2 - pIter->aSeg;
  2416   2423   
................................................................................
  2443   2450   
  2444   2451   /*
  2445   2452   ** This function is a no-op unless SQLITE_DEBUG is defined when this module
  2446   2453   ** is compiled. In that case, this function is essentially an assert() 
  2447   2454   ** statement used to verify that the contents of the pIter->aFirst[] array
  2448   2455   ** are correct.
  2449   2456   */
  2450         -static void fts5AssertMultiIterSetup(Fts5Index *p, Fts5IndexIter *pIter){
         2457  +static void fts5AssertMultiIterSetup(Fts5Index *p, Fts5Iter *pIter){
  2451   2458     if( p->rc==SQLITE_OK ){
  2452   2459       Fts5SegIter *pFirst = &pIter->aSeg[ pIter->aFirst[1].iFirst ];
  2453   2460       int i;
  2454   2461   
  2455   2462       assert( (pFirst->pLeaf==0)==pIter->bEof );
  2456   2463   
  2457   2464       /* Check that pIter->iSwitchRowid is set correctly. */
................................................................................
  2488   2495   ** Do the comparison necessary to populate pIter->aFirst[iOut].
  2489   2496   **
  2490   2497   ** If the returned value is non-zero, then it is the index of an entry
  2491   2498   ** in the pIter->aSeg[] array that is (a) not at EOF, and (b) pointing
  2492   2499   ** to a key that is a duplicate of another, higher priority, 
  2493   2500   ** segment-iterator in the pSeg->aSeg[] array.
  2494   2501   */
  2495         -static int fts5MultiIterDoCompare(Fts5IndexIter *pIter, int iOut){
         2502  +static int fts5MultiIterDoCompare(Fts5Iter *pIter, int iOut){
  2496   2503     int i1;                         /* Index of left-hand Fts5SegIter */
  2497   2504     int i2;                         /* Index of right-hand Fts5SegIter */
  2498   2505     int iRes;
  2499   2506     Fts5SegIter *p1;                /* Left-hand Fts5SegIter */
  2500   2507     Fts5SegIter *p2;                /* Right-hand Fts5SegIter */
  2501   2508     Fts5CResult *pRes = &pIter->aFirst[iOut];
  2502   2509   
................................................................................
  2634   2641     }while( p->rc==SQLITE_OK );
  2635   2642   }
  2636   2643   
  2637   2644   
  2638   2645   /*
  2639   2646   ** Free the iterator object passed as the second argument.
  2640   2647   */
  2641         -static void fts5MultiIterFree(Fts5Index *p, Fts5IndexIter *pIter){
         2648  +static void fts5MultiIterFree(Fts5Index *p, Fts5Iter *pIter){
  2642   2649     if( pIter ){
  2643   2650       int i;
  2644   2651       for(i=0; i<pIter->nSeg; i++){
  2645   2652         fts5SegIterClear(&pIter->aSeg[i]);
  2646   2653       }
  2647   2654       fts5StructureRelease(pIter->pStruct);
  2648   2655       fts5BufferFree(&pIter->poslist);
  2649   2656       sqlite3_free(pIter);
  2650   2657     }
  2651   2658   }
  2652   2659   
  2653   2660   static void fts5MultiIterAdvanced(
  2654   2661     Fts5Index *p,                   /* FTS5 backend to iterate within */
  2655         -  Fts5IndexIter *pIter,           /* Iterator to update aFirst[] array for */
         2662  +  Fts5Iter *pIter,                /* Iterator to update aFirst[] array for */
  2656   2663     int iChanged,                   /* Index of sub-iterator just advanced */
  2657   2664     int iMinset                     /* Minimum entry in aFirst[] to set */
  2658   2665   ){
  2659   2666     int i;
  2660   2667     for(i=(pIter->nSeg+iChanged)/2; i>=iMinset && p->rc==SQLITE_OK; i=i/2){
  2661   2668       int iEq;
  2662   2669       if( (iEq = fts5MultiIterDoCompare(pIter, i)) ){
................................................................................
  2676   2683   **
  2677   2684   ** If non-zero is returned, the caller should call fts5MultiIterAdvanced()
  2678   2685   ** on the iterator instead. That function does the same as this one, except
  2679   2686   ** that it deals with more complicated cases as well.
  2680   2687   */ 
  2681   2688   static int fts5MultiIterAdvanceRowid(
  2682   2689     Fts5Index *p,                   /* FTS5 backend to iterate within */
  2683         -  Fts5IndexIter *pIter,           /* Iterator to update aFirst[] array for */
  2684         -  int iChanged                    /* Index of sub-iterator just advanced */
         2690  +  Fts5Iter *pIter,                /* Iterator to update aFirst[] array for */
         2691  +  int iChanged,                   /* Index of sub-iterator just advanced */
         2692  +  Fts5SegIter **ppFirst
  2685   2693   ){
  2686   2694     Fts5SegIter *pNew = &pIter->aSeg[iChanged];
  2687   2695   
  2688   2696     if( pNew->iRowid==pIter->iSwitchRowid
  2689   2697      || (pNew->iRowid<pIter->iSwitchRowid)==pIter->bRev
  2690   2698     ){
  2691   2699       int i;
................................................................................
  2710   2718         pRes->iFirst = (u16)(pNew - pIter->aSeg);
  2711   2719         if( i==1 ) break;
  2712   2720   
  2713   2721         pOther = &pIter->aSeg[ pIter->aFirst[i ^ 0x0001].iFirst ];
  2714   2722       }
  2715   2723     }
  2716   2724   
         2725  +  *ppFirst = pNew;
  2717   2726     return 0;
  2718   2727   }
  2719   2728   
  2720   2729   /*
  2721   2730   ** Set the pIter->bEof variable based on the state of the sub-iterators.
  2722   2731   */
  2723         -static void fts5MultiIterSetEof(Fts5IndexIter *pIter){
         2732  +static void fts5MultiIterSetEof(Fts5Iter *pIter){
  2724   2733     Fts5SegIter *pSeg = &pIter->aSeg[ pIter->aFirst[1].iFirst ];
  2725   2734     pIter->bEof = pSeg->pLeaf==0;
  2726   2735     pIter->iSwitchRowid = pSeg->iRowid;
  2727   2736   }
  2728   2737   
  2729   2738   /*
  2730   2739   ** Move the iterator to the next entry. 
................................................................................
  2731   2740   **
  2732   2741   ** If an error occurs, an error code is left in Fts5Index.rc. It is not 
  2733   2742   ** considered an error if the iterator reaches EOF, or if it is already at 
  2734   2743   ** EOF when this function is called.
  2735   2744   */
  2736   2745   static void fts5MultiIterNext(
  2737   2746     Fts5Index *p, 
  2738         -  Fts5IndexIter *pIter,
         2747  +  Fts5Iter *pIter,
  2739   2748     int bFrom,                      /* True if argument iFrom is valid */
  2740   2749     i64 iFrom                       /* Advance at least as far as this */
  2741   2750   ){
  2742         -  if( p->rc==SQLITE_OK ){
  2743         -    int bUseFrom = bFrom;
  2744         -    do {
  2745         -      int iFirst = pIter->aFirst[1].iFirst;
  2746         -      int bNewTerm = 0;
  2747         -      Fts5SegIter *pSeg = &pIter->aSeg[iFirst];
  2748         -      assert( p->rc==SQLITE_OK );
  2749         -      if( bUseFrom && pSeg->pDlidx ){
  2750         -        fts5SegIterNextFrom(p, pSeg, iFrom);
  2751         -      }else{
  2752         -        pSeg->xNext(p, pSeg, &bNewTerm);
  2753         -      }
  2754         -
  2755         -      if( pSeg->pLeaf==0 || bNewTerm 
  2756         -       || fts5MultiIterAdvanceRowid(p, pIter, iFirst)
  2757         -      ){
  2758         -        fts5MultiIterAdvanced(p, pIter, iFirst, 1);
  2759         -        fts5MultiIterSetEof(pIter);
  2760         -      }
  2761         -      fts5AssertMultiIterSetup(p, pIter);
  2762         -
  2763         -      bUseFrom = 0;
  2764         -    }while( pIter->bSkipEmpty && fts5MultiIterIsEmpty(p, pIter) );
         2751  +  int bUseFrom = bFrom;
         2752  +  while( p->rc==SQLITE_OK ){
         2753  +    int iFirst = pIter->aFirst[1].iFirst;
         2754  +    int bNewTerm = 0;
         2755  +    Fts5SegIter *pSeg = &pIter->aSeg[iFirst];
         2756  +    assert( p->rc==SQLITE_OK );
         2757  +    if( bUseFrom && pSeg->pDlidx ){
         2758  +      fts5SegIterNextFrom(p, pSeg, iFrom);
         2759  +    }else{
         2760  +      pSeg->xNext(p, pSeg, &bNewTerm);
         2761  +    }
         2762  +
         2763  +    if( pSeg->pLeaf==0 || bNewTerm 
         2764  +     || fts5MultiIterAdvanceRowid(p, pIter, iFirst, &pSeg)
         2765  +    ){
         2766  +      fts5MultiIterAdvanced(p, pIter, iFirst, 1);
         2767  +      fts5MultiIterSetEof(pIter);
         2768  +      pSeg = &pIter->aSeg[pIter->aFirst[1].iFirst];
         2769  +      if( pSeg->pLeaf==0 ) return;
         2770  +    }
         2771  +
         2772  +    fts5AssertMultiIterSetup(p, pIter);
         2773  +    assert( pSeg==&pIter->aSeg[pIter->aFirst[1].iFirst] && pSeg->pLeaf );
         2774  +    if( pIter->bSkipEmpty==0 || pSeg->nPos ){
         2775  +      pIter->xSetOutputs(pIter, pSeg);
         2776  +      return;
         2777  +    }
         2778  +    bUseFrom = 0;
  2765   2779     }
  2766   2780   }
  2767   2781   
  2768   2782   static void fts5MultiIterNext2(
  2769   2783     Fts5Index *p, 
  2770         -  Fts5IndexIter *pIter,
         2784  +  Fts5Iter *pIter,
  2771   2785     int *pbNewTerm                  /* OUT: True if *might* be new term */
  2772   2786   ){
  2773   2787     assert( pIter->bSkipEmpty );
  2774   2788     if( p->rc==SQLITE_OK ){
  2775   2789       do {
  2776   2790         int iFirst = pIter->aFirst[1].iFirst;
  2777   2791         Fts5SegIter *pSeg = &pIter->aSeg[iFirst];
  2778   2792         int bNewTerm = 0;
  2779   2793   
  2780   2794         assert( p->rc==SQLITE_OK );
  2781   2795         pSeg->xNext(p, pSeg, &bNewTerm);
  2782   2796         if( pSeg->pLeaf==0 || bNewTerm 
  2783         -       || fts5MultiIterAdvanceRowid(p, pIter, iFirst)
         2797  +       || fts5MultiIterAdvanceRowid(p, pIter, iFirst, &pSeg)
  2784   2798         ){
  2785   2799           fts5MultiIterAdvanced(p, pIter, iFirst, 1);
  2786   2800           fts5MultiIterSetEof(pIter);
  2787   2801           *pbNewTerm = 1;
  2788   2802         }else{
  2789   2803           *pbNewTerm = 0;
  2790   2804         }
  2791   2805         fts5AssertMultiIterSetup(p, pIter);
  2792   2806   
  2793   2807       }while( fts5MultiIterIsEmpty(p, pIter) );
  2794   2808     }
  2795   2809   }
  2796   2810   
         2811  +static void fts5IterSetOutputs_Noop(Fts5Iter *pIter, Fts5SegIter *pSeg){
         2812  +}
  2797   2813   
  2798         -static Fts5IndexIter *fts5MultiIterAlloc(
         2814  +static Fts5Iter *fts5MultiIterAlloc(
  2799   2815     Fts5Index *p,                   /* FTS5 backend to iterate within */
  2800   2816     int nSeg
  2801   2817   ){
  2802         -  Fts5IndexIter *pNew;
         2818  +  Fts5Iter *pNew;
  2803   2819     int nSlot;                      /* Power of two >= nSeg */
  2804   2820   
  2805   2821     for(nSlot=2; nSlot<nSeg; nSlot=nSlot*2);
  2806   2822     pNew = fts5IdxMalloc(p, 
  2807         -      sizeof(Fts5IndexIter) +             /* pNew */
         2823  +      sizeof(Fts5Iter) +                  /* pNew */
  2808   2824         sizeof(Fts5SegIter) * (nSlot-1) +   /* pNew->aSeg[] */
  2809   2825         sizeof(Fts5CResult) * nSlot         /* pNew->aFirst[] */
  2810   2826     );
  2811   2827     if( pNew ){
  2812   2828       pNew->nSeg = nSlot;
  2813   2829       pNew->aFirst = (Fts5CResult*)&pNew->aSeg[nSlot];
  2814   2830       pNew->pIndex = p;
         2831  +    pNew->xSetOutputs = fts5IterSetOutputs_Noop;
  2815   2832     }
  2816   2833     return pNew;
  2817   2834   }
  2818   2835   
  2819   2836   /*
  2820         -** Allocate a new Fts5IndexIter object.
         2837  +** Allocate a new Fts5Iter object.
  2821   2838   **
  2822   2839   ** The new object will be used to iterate through data in structure pStruct.
  2823   2840   ** If iLevel is -ve, then all data in all segments is merged. Or, if iLevel
  2824   2841   ** is zero or greater, data from the first nSegment segments on level iLevel
  2825   2842   ** is merged.
  2826   2843   **
  2827   2844   ** The iterator initially points to the first term/rowid entry in the 
................................................................................
  2831   2848     Fts5Index *p,                   /* FTS5 backend to iterate within */
  2832   2849     Fts5Structure *pStruct,         /* Structure of specific index */
  2833   2850     int bSkipEmpty,                 /* True to ignore delete-keys */
  2834   2851     int flags,                      /* FTS5INDEX_QUERY_XXX flags */
  2835   2852     const u8 *pTerm, int nTerm,     /* Term to seek to (or NULL/0) */
  2836   2853     int iLevel,                     /* Level to iterate (-1 for all) */
  2837   2854     int nSegment,                   /* Number of segments to merge (iLevel>=0) */
  2838         -  Fts5IndexIter **ppOut           /* New object */
         2855  +  Fts5Iter **ppOut                /* New object */
  2839   2856   ){
  2840   2857     int nSeg = 0;                   /* Number of segment-iters in use */
  2841   2858     int iIter = 0;                  /* */
  2842   2859     int iSeg;                       /* Used to iterate through segments */
  2843   2860     Fts5Buffer buf = {0,0,0};       /* Buffer used by fts5SegIterSeekInit() */
  2844   2861     Fts5StructureLevel *pLvl;
  2845         -  Fts5IndexIter *pNew;
         2862  +  Fts5Iter *pNew;
  2846   2863   
  2847   2864     assert( (pTerm==0 && nTerm==0) || iLevel<0 );
  2848   2865   
  2849   2866     /* Allocate space for the new multi-seg-iterator. */
  2850   2867     if( p->rc==SQLITE_OK ){
  2851   2868       if( iLevel<0 ){
  2852   2869         assert( pStruct->nSegment==fts5StructureCountSegments(pStruct) );
................................................................................
  2913   2930       fts5MultiIterFree(p, pNew);
  2914   2931       *ppOut = 0;
  2915   2932     }
  2916   2933     fts5BufferFree(&buf);
  2917   2934   }
  2918   2935   
  2919   2936   /*
  2920         -** Create an Fts5IndexIter that iterates through the doclist provided
         2937  +** Create an Fts5Iter that iterates through the doclist provided
  2921   2938   ** as the second argument.
  2922   2939   */
  2923   2940   static void fts5MultiIterNew2(
  2924   2941     Fts5Index *p,                   /* FTS5 backend to iterate within */
  2925   2942     Fts5Data *pData,                /* Doclist to iterate through */
  2926   2943     int bDesc,                      /* True for descending rowid order */
  2927         -  Fts5IndexIter **ppOut           /* New object */
         2944  +  Fts5Iter **ppOut                /* New object */
  2928   2945   ){
  2929         -  Fts5IndexIter *pNew;
         2946  +  Fts5Iter *pNew;
  2930   2947     pNew = fts5MultiIterAlloc(p, 2);
  2931   2948     if( pNew ){
  2932   2949       Fts5SegIter *pIter = &pNew->aSeg[1];
  2933   2950   
  2934   2951       pNew->bFiltered = 1;
  2935   2952       pIter->flags = FTS5_SEGITER_ONETERM;
  2936   2953       if( pData->szLeaf>0 ){
................................................................................
  2957   2974     fts5DataRelease(pData);
  2958   2975   }
  2959   2976   
  2960   2977   /*
  2961   2978   ** Return true if the iterator is at EOF or if an error has occurred. 
  2962   2979   ** False otherwise.
  2963   2980   */
  2964         -static int fts5MultiIterEof(Fts5Index *p, Fts5IndexIter *pIter){
         2981  +static int fts5MultiIterEof(Fts5Index *p, Fts5Iter *pIter){
  2965   2982     assert( p->rc 
  2966   2983         || (pIter->aSeg[ pIter->aFirst[1].iFirst ].pLeaf==0)==pIter->bEof 
  2967   2984     );
  2968   2985     return (p->rc || pIter->bEof);
  2969   2986   }
  2970   2987   
  2971   2988   /*
  2972   2989   ** Return the rowid of the entry that the iterator currently points
  2973   2990   ** to. If the iterator points to EOF when this function is called the
  2974   2991   ** results are undefined.
  2975   2992   */
  2976         -static i64 fts5MultiIterRowid(Fts5IndexIter *pIter){
         2993  +static i64 fts5MultiIterRowid(Fts5Iter *pIter){
  2977   2994     assert( pIter->aSeg[ pIter->aFirst[1].iFirst ].pLeaf );
  2978   2995     return pIter->aSeg[ pIter->aFirst[1].iFirst ].iRowid;
  2979   2996   }
  2980   2997   
  2981   2998   /*
  2982   2999   ** Move the iterator to the next entry at or following iMatch.
  2983   3000   */
  2984   3001   static void fts5MultiIterNextFrom(
  2985   3002     Fts5Index *p, 
  2986         -  Fts5IndexIter *pIter, 
         3003  +  Fts5Iter *pIter, 
  2987   3004     i64 iMatch
  2988   3005   ){
  2989   3006     while( 1 ){
  2990   3007       i64 iRowid;
  2991   3008       fts5MultiIterNext(p, pIter, 1, iMatch);
  2992   3009       if( fts5MultiIterEof(p, pIter) ) break;
  2993   3010       iRowid = fts5MultiIterRowid(pIter);
................................................................................
  2996   3013     }
  2997   3014   }
  2998   3015   
  2999   3016   /*
  3000   3017   ** Return a pointer to a buffer containing the term associated with the 
  3001   3018   ** entry that the iterator currently points to.
  3002   3019   */
  3003         -static const u8 *fts5MultiIterTerm(Fts5IndexIter *pIter, int *pn){
         3020  +static const u8 *fts5MultiIterTerm(Fts5Iter *pIter, int *pn){
  3004   3021     Fts5SegIter *p = &pIter->aSeg[ pIter->aFirst[1].iFirst ];
  3005   3022     *pn = p->term.n;
  3006   3023     return p->term.p;
  3007   3024   }
  3008   3025   
  3009   3026   static void fts5ChunkIterate(
  3010   3027     Fts5Index *p,                   /* Index object */
................................................................................
  3578   3595   }
  3579   3596   
  3580   3597   /*
  3581   3598   ** Iterator pIter was used to iterate through the input segments of on an
  3582   3599   ** incremental merge operation. This function is called if the incremental
  3583   3600   ** merge step has finished but the input has not been completely exhausted.
  3584   3601   */
  3585         -static void fts5TrimSegments(Fts5Index *p, Fts5IndexIter *pIter){
         3602  +static void fts5TrimSegments(Fts5Index *p, Fts5Iter *pIter){
  3586   3603     int i;
  3587   3604     Fts5Buffer buf;
  3588   3605     memset(&buf, 0, sizeof(Fts5Buffer));
  3589   3606     for(i=0; i<pIter->nSeg; i++){
  3590   3607       Fts5SegIter *pSeg = &pIter->aSeg[i];
  3591   3608       if( pSeg->pSeg==0 ){
  3592   3609         /* no-op */
................................................................................
  3656   3673     Fts5Structure **ppStruct,       /* IN/OUT: Stucture of index */
  3657   3674     int iLvl,                       /* Level to read input from */
  3658   3675     int *pnRem                      /* Write up to this many output leaves */
  3659   3676   ){
  3660   3677     Fts5Structure *pStruct = *ppStruct;
  3661   3678     Fts5StructureLevel *pLvl = &pStruct->aLevel[iLvl];
  3662   3679     Fts5StructureLevel *pLvlOut;
  3663         -  Fts5IndexIter *pIter = 0;       /* Iterator to read input data */
         3680  +  Fts5Iter *pIter = 0;       /* Iterator to read input data */
  3664   3681     int nRem = pnRem ? *pnRem : 0;  /* Output leaf pages left to write */
  3665   3682     int nInput;                     /* Number of input segments */
  3666   3683     Fts5SegWriter writer;           /* Writer object */
  3667   3684     Fts5StructureSegment *pSeg;     /* Output segment */
  3668   3685     Fts5Buffer term;
  3669   3686     int bOldest;                    /* True if the output segment is the oldest */
  3670   3687     int eDetail = p->pConfig->eDetail;
................................................................................
  4312   4329     const u8 **pa,                  /* IN/OUT: Pointer to poslist */
  4313   4330     int n,                          /* IN: Size of poslist in bytes */
  4314   4331     int iCol                        /* Column to extract from poslist */
  4315   4332   ){
  4316   4333     int iCurrent = 0;               /* Anything before the first 0x01 is col 0 */
  4317   4334     const u8 *p = *pa;
  4318   4335     const u8 *pEnd = &p[n];         /* One byte past end of position list */
  4319         -  u8 prev = 0;
  4320   4336   
  4321   4337     while( iCol>iCurrent ){
  4322   4338       /* Advance pointer p until it points to pEnd or an 0x01 byte that is
  4323         -    ** not part of a varint */
  4324         -    while( (prev & 0x80) || *p!=0x01 ){
  4325         -      prev = *p++;
  4326         -      if( p==pEnd ) return 0;
         4339  +    ** not part of a varint. Note that it is not possible for a negative
         4340  +    ** or extremely large varint to occur within an uncorrupted position 
         4341  +    ** list. So the last byte of each varint may be assumed to have a clear
         4342  +    ** 0x80 bit.  */
         4343  +    while( *p!=0x01 ){
         4344  +      while( *p++ & 0x80 );
         4345  +      if( p>=pEnd ) return 0;
  4327   4346       }
  4328   4347       *pa = p++;
  4329         -    p += fts5GetVarint32(p, iCurrent);
         4348  +    iCurrent = *p++;
         4349  +    if( iCurrent & 0x80 ){
         4350  +      p--;
         4351  +      p += fts5GetVarint32(p, iCurrent);
         4352  +    }
  4330   4353     }
  4331   4354     if( iCol!=iCurrent ) return 0;
  4332   4355   
  4333   4356     /* Advance pointer p until it points to pEnd or an 0x01 byte that is
  4334   4357     ** not part of a varint */
  4335         -  assert( (prev & 0x80)==0 );
  4336         -  while( p<pEnd && ((prev & 0x80) || *p!=0x01) ){
  4337         -    prev = *p++;
         4358  +  while( p<pEnd && *p!=0x01 ){
         4359  +    while( *p++ & 0x80 );
  4338   4360     }
         4361  +
  4339   4362     return p - (*pa);
  4340   4363   }
  4341   4364   
  4342   4365   static int fts5AppendRowid(
  4343   4366     Fts5Index *p,
  4344   4367     i64 iDelta,
  4345         -  Fts5IndexIter *pMulti,
         4368  +  Fts5Iter *pMulti,
  4346   4369     Fts5Colset *pColset,
  4347   4370     Fts5Buffer *pBuf
  4348   4371   ){
  4349   4372     fts5BufferAppendVarint(&p->rc, pBuf, iDelta);
  4350   4373     return 0;
  4351   4374   }
  4352   4375   
................................................................................
  4363   4386   ** even iDelta).
  4364   4387   **
  4365   4388   ** If an error occurs, an error code is left in p->rc. 
  4366   4389   */
  4367   4390   static int fts5AppendPoslist(
  4368   4391     Fts5Index *p,
  4369   4392     i64 iDelta,
  4370         -  Fts5IndexIter *pMulti,
         4393  +  Fts5Iter *pMulti,
  4371   4394     Fts5Colset *pColset,
  4372   4395     Fts5Buffer *pBuf
  4373   4396   ){
  4374   4397     if( p->rc==SQLITE_OK ){
  4375   4398       Fts5SegIter *pSeg = &pMulti->aSeg[ pMulti->aFirst[1].iFirst ];
  4376   4399       assert( fts5MultiIterEof(p, pMulti)==0 );
  4377   4400       assert( pSeg->nPos>0 );
................................................................................
  4641   4664   
  4642   4665   static void fts5SetupPrefixIter(
  4643   4666     Fts5Index *p,                   /* Index to read from */
  4644   4667     int bDesc,                      /* True for "ORDER BY rowid DESC" */
  4645   4668     const u8 *pToken,               /* Buffer containing prefix to match */
  4646   4669     int nToken,                     /* Size of buffer pToken in bytes */
  4647   4670     Fts5Colset *pColset,            /* Restrict matches to these columns */
  4648         -  Fts5IndexIter **ppIter          /* OUT: New iterator */
         4671  +  Fts5Iter **ppIter          /* OUT: New iterator */
  4649   4672   ){
  4650   4673     Fts5Structure *pStruct;
  4651   4674     Fts5Buffer *aBuf;
  4652   4675     const int nBuf = 32;
  4653   4676   
  4654   4677     void (*xMerge)(Fts5Index*, Fts5Buffer*, Fts5Buffer*);
  4655         -  int (*xAppend)(Fts5Index*, i64, Fts5IndexIter*, Fts5Colset*, Fts5Buffer*);
         4678  +  int (*xAppend)(Fts5Index*, i64, Fts5Iter*, Fts5Colset*, Fts5Buffer*);
  4656   4679     if( p->pConfig->eDetail==FTS5_DETAIL_NONE ){
  4657   4680       xMerge = fts5MergeRowidLists;
  4658   4681       xAppend = fts5AppendRowid;
  4659   4682     }else{
  4660   4683       xMerge = fts5MergePrefixLists;
  4661   4684       xAppend = fts5AppendPoslist;
  4662   4685     }
................................................................................
  4664   4687     aBuf = (Fts5Buffer*)fts5IdxMalloc(p, sizeof(Fts5Buffer)*nBuf);
  4665   4688     pStruct = fts5StructureRead(p);
  4666   4689   
  4667   4690     if( aBuf && pStruct ){
  4668   4691       const int flags = FTS5INDEX_QUERY_SCAN;
  4669   4692       int i;
  4670   4693       i64 iLastRowid = 0;
  4671         -    Fts5IndexIter *p1 = 0;     /* Iterator used to gather data from index */
         4694  +    Fts5Iter *p1 = 0;     /* Iterator used to gather data from index */
  4672   4695       Fts5Data *pData;
  4673   4696       Fts5Buffer doclist;
  4674   4697       int bNewTerm = 1;
  4675   4698   
  4676   4699       memset(&doclist, 0, sizeof(doclist));
  4677   4700       for(fts5MultiIterNew(p, pStruct, 1, flags, pToken, nToken, -1, 0, &p1);
  4678   4701           fts5MultiIterEof(p, p1)==0;
................................................................................
  4928   4951         );
  4929   4952       }
  4930   4953     }
  4931   4954   
  4932   4955     return rc;
  4933   4956   }
  4934   4957   
         4958  +
         4959  +static int fts5IndexExtractColset (
         4960  +  Fts5Colset *pColset,            /* Colset to filter on */
         4961  +  const u8 *pPos, int nPos,       /* Position list */
         4962  +  Fts5Buffer *pBuf                /* Output buffer */
         4963  +){
         4964  +  int rc = SQLITE_OK;
         4965  +  int i;
         4966  +
         4967  +  fts5BufferZero(pBuf);
         4968  +  for(i=0; i<pColset->nCol; i++){
         4969  +    const u8 *pSub = pPos;
         4970  +    int nSub = fts5IndexExtractCol(&pSub, nPos, pColset->aiCol[i]);
         4971  +    if( nSub ){
         4972  +      fts5BufferAppendBlob(&rc, pBuf, nSub, pSub);
         4973  +    }
         4974  +  }
         4975  +  return rc;
         4976  +}
         4977  +
         4978  +/*
         4979  +** xSetOutputs callback used by detail=none tables.
         4980  +*/
         4981  +static void fts5IterSetOutputs_None(Fts5Iter *pIter, Fts5SegIter *pSeg){
         4982  +  assert( pIter->pIndex->pConfig->eDetail==FTS5_DETAIL_NONE );
         4983  +  pIter->base.iRowid = pSeg->iRowid;
         4984  +  pIter->base.nData = pSeg->nPos;
         4985  +}
         4986  +
         4987  +/*
         4988  +** xSetOutputs callback used by detail=full and detail=col tables when no
         4989  +** column filters are specified.
         4990  +*/
         4991  +static void fts5IterSetOutputs_Nocolset(Fts5Iter *pIter, Fts5SegIter *pSeg){
         4992  +  pIter->base.iRowid = pSeg->iRowid;
         4993  +  pIter->base.nData = pSeg->nPos;
         4994  +
         4995  +  assert( pIter->pIndex->pConfig->eDetail!=FTS5_DETAIL_NONE );
         4996  +  assert( pIter->pColset==0 || pIter->bFiltered );
         4997  +
         4998  +  if( pSeg->iLeafOffset+pSeg->nPos<=pSeg->pLeaf->szLeaf ){
         4999  +    /* All data is stored on the current page. Populate the output 
         5000  +    ** variables to point into the body of the page object. */
         5001  +    pIter->base.pData = &pSeg->pLeaf->p[pSeg->iLeafOffset];
         5002  +  }else{
         5003  +    /* The data is distributed over two or more pages. Copy it into the
         5004  +    ** Fts5Iter.poslist buffer and then set the output pointer to point
         5005  +    ** to this buffer.  */
         5006  +    fts5BufferZero(&pIter->poslist);
         5007  +    fts5SegiterPoslist(pIter->pIndex, pSeg, 0, &pIter->poslist);
         5008  +    pIter->base.pData = pIter->poslist.p;
         5009  +  }
         5010  +}
         5011  +
         5012  +/*
         5013  +** xSetOutputs callback used by detail=col when there is a column filter
         5014  +** and there are 100 or more columns. Also called as a fallback from
         5015  +** fts5IterSetOutputs_Col100 if the column-list spans more than one page.
         5016  +*/
         5017  +static void fts5IterSetOutputs_Col(Fts5Iter *pIter, Fts5SegIter *pSeg){
         5018  +  fts5BufferZero(&pIter->poslist);
         5019  +  fts5SegiterPoslist(pIter->pIndex, pSeg, pIter->pColset, &pIter->poslist);
         5020  +  pIter->base.iRowid = pSeg->iRowid;
         5021  +  pIter->base.pData = pIter->poslist.p;
         5022  +  pIter->base.nData = pIter->poslist.n;
         5023  +}
         5024  +
         5025  +/*
         5026  +** xSetOutputs callback used when: 
         5027  +**
         5028  +**   * detail=col,
         5029  +**   * there is a column filter, and
         5030  +**   * the table contains 100 or fewer columns. 
         5031  +**
         5032  +** The last point is to ensure all column numbers are stored as 
         5033  +** single-byte varints.
         5034  +*/
         5035  +static void fts5IterSetOutputs_Col100(Fts5Iter *pIter, Fts5SegIter *pSeg){
         5036  +
         5037  +  assert( pIter->pIndex->pConfig->eDetail==FTS5_DETAIL_COLUMNS );
         5038  +  assert( pIter->pColset );
         5039  +
         5040  +  if( pSeg->iLeafOffset+pSeg->nPos>pSeg->pLeaf->szLeaf ){
         5041  +    fts5IterSetOutputs_Col(pIter, pSeg);
         5042  +  }else{
         5043  +    u8 *a = (u8*)&pSeg->pLeaf->p[pSeg->iLeafOffset];
         5044  +    u8 *pEnd = (u8*)&a[pSeg->nPos]; 
         5045  +    int iPrev = 0;
         5046  +    int *aiCol = pIter->pColset->aiCol;
         5047  +    int *aiColEnd = &aiCol[pIter->pColset->nCol];
         5048  +
         5049  +    u8 *aOut = pIter->poslist.p;
         5050  +    int iPrevOut = 0;
         5051  +
         5052  +    pIter->base.iRowid = pSeg->iRowid;
         5053  +
         5054  +    while( a<pEnd ){
         5055  +      iPrev += (int)a++[0] - 2;
         5056  +      while( *aiCol<iPrev ){
         5057  +        aiCol++;
         5058  +        if( aiCol==aiColEnd ) goto setoutputs_col_out;
         5059  +      }
         5060  +      if( *aiCol==iPrev ){
         5061  +        *aOut++ = (iPrev - iPrevOut) + 2;
         5062  +        iPrevOut = iPrev;
         5063  +      }
         5064  +    }
         5065  +
         5066  +setoutputs_col_out:
         5067  +    pIter->base.pData = pIter->poslist.p;
         5068  +    pIter->base.nData = aOut - pIter->poslist.p;
         5069  +  }
         5070  +}
         5071  +
         5072  +/*
         5073  +** xSetOutputs callback used by detail=full when there is a column filter.
         5074  +*/
         5075  +static void fts5IterSetOutputs_Full(Fts5Iter *pIter, Fts5SegIter *pSeg){
         5076  +  Fts5Colset *pColset = pIter->pColset;
         5077  +  pIter->base.iRowid = pSeg->iRowid;
         5078  +
         5079  +  assert( pIter->pIndex->pConfig->eDetail==FTS5_DETAIL_FULL );
         5080  +  assert( pColset );
         5081  +
         5082  +  if( pSeg->iLeafOffset+pSeg->nPos<=pSeg->pLeaf->szLeaf ){
         5083  +    /* All data is stored on the current page. Populate the output 
         5084  +    ** variables to point into the body of the page object. */
         5085  +    const u8 *a = &pSeg->pLeaf->p[pSeg->iLeafOffset];
         5086  +    if( pColset->nCol==1 ){
         5087  +      pIter->base.nData = fts5IndexExtractCol(&a, pSeg->nPos,pColset->aiCol[0]);
         5088  +      pIter->base.pData = a;
         5089  +    }else{
         5090  +      fts5BufferZero(&pIter->poslist);
         5091  +      fts5IndexExtractColset(pColset, a, pSeg->nPos, &pIter->poslist);
         5092  +      pIter->base.pData = pIter->poslist.p;
         5093  +      pIter->base.nData = pIter->poslist.n;
         5094  +    }
         5095  +  }else{
         5096  +    /* The data is distributed over two or more pages. Copy it into the
         5097  +    ** Fts5Iter.poslist buffer and then set the output pointer to point
         5098  +    ** to this buffer.  */
         5099  +    fts5BufferZero(&pIter->poslist);
         5100  +    fts5SegiterPoslist(pIter->pIndex, pSeg, pColset, &pIter->poslist);
         5101  +    pIter->base.pData = pIter->poslist.p;
         5102  +    pIter->base.nData = pIter->poslist.n;
         5103  +  }
         5104  +}
         5105  +
         5106  +static void fts5IterSetOutputCb(int *pRc, Fts5Iter *pIter){
         5107  +  Fts5Config *pConfig = pIter->pIndex->pConfig;
         5108  +  if( pConfig->eDetail==FTS5_DETAIL_NONE ){
         5109  +    pIter->xSetOutputs = fts5IterSetOutputs_None;
         5110  +  }
         5111  +
         5112  +  else if( pIter->pColset==0 || pIter->bFiltered ){
         5113  +    pIter->xSetOutputs = fts5IterSetOutputs_Nocolset;
         5114  +  }
         5115  +
         5116  +  else if( pConfig->eDetail==FTS5_DETAIL_FULL ){
         5117  +    pIter->xSetOutputs = fts5IterSetOutputs_Full;
         5118  +  }
         5119  +
         5120  +  else{
         5121  +    assert( pConfig->eDetail==FTS5_DETAIL_COLUMNS );
         5122  +    if( pConfig->nCol<=100 ){
         5123  +      pIter->xSetOutputs = fts5IterSetOutputs_Col100;
         5124  +      sqlite3Fts5BufferSize(pRc, &pIter->poslist, pConfig->nCol);
         5125  +    }else{
         5126  +      pIter->xSetOutputs = fts5IterSetOutputs_Col;
         5127  +    }
         5128  +  }
         5129  +}
         5130  +
  4935   5131   /*
  4936   5132   ** Open a new iterator to iterate though all rowid that match the 
  4937   5133   ** specified token or token prefix.
  4938   5134   */
  4939   5135   int sqlite3Fts5IndexQuery(
  4940   5136     Fts5Index *p,                   /* FTS index to query */
  4941   5137     const char *pToken, int nToken, /* Token (or prefix) to query for */
  4942   5138     int flags,                      /* Mask of FTS5INDEX_QUERY_X flags */
  4943   5139     Fts5Colset *pColset,            /* Match these columns only */
  4944   5140     Fts5IndexIter **ppIter          /* OUT: New iterator object */
  4945   5141   ){
  4946   5142     Fts5Config *pConfig = p->pConfig;
  4947         -  Fts5IndexIter *pRet = 0;
  4948         -  int iIdx = 0;
         5143  +  Fts5Iter *pRet = 0;
  4949   5144     Fts5Buffer buf = {0, 0, 0};
  4950   5145   
  4951   5146     /* If the QUERY_SCAN flag is set, all other flags must be clear. */
  4952   5147     assert( (flags & FTS5INDEX_QUERY_SCAN)==0 || flags==FTS5INDEX_QUERY_SCAN );
  4953   5148   
  4954   5149     if( sqlite3Fts5BufferSize(&p->rc, &buf, nToken+1)==0 ){
         5150  +    int iIdx = 0;                 /* Index to search */
  4955   5151       memcpy(&buf.p[1], pToken, nToken);
  4956   5152   
  4957         -#ifdef SQLITE_DEBUG
  4958         -    /* If the QUERY_TEST_NOIDX flag was specified, then this must be a
         5153  +    /* Figure out which index to search and set iIdx accordingly. If this
         5154  +    ** is a prefix query for which there is no prefix index, set iIdx to
         5155  +    ** greater than pConfig->nPrefix to indicate that the query will be
         5156  +    ** satisfied by scanning multiple terms in the main index.
         5157  +    **
         5158  +    ** If the QUERY_TEST_NOIDX flag was specified, then this must be a
  4959   5159       ** prefix-query. Instead of using a prefix-index (if one exists), 
  4960   5160       ** evaluate the prefix query using the main FTS index. This is used
  4961   5161       ** for internal sanity checking by the integrity-check in debug 
  4962   5162       ** mode only.  */
         5163  +#ifdef SQLITE_DEBUG
  4963   5164       if( pConfig->bPrefixIndex==0 || (flags & FTS5INDEX_QUERY_TEST_NOIDX) ){
  4964   5165         assert( flags & FTS5INDEX_QUERY_PREFIX );
  4965   5166         iIdx = 1+pConfig->nPrefix;
  4966   5167       }else
  4967   5168   #endif
  4968   5169       if( flags & FTS5INDEX_QUERY_PREFIX ){
  4969   5170         int nChar = fts5IndexCharlen(pToken, nToken);
  4970   5171         for(iIdx=1; iIdx<=pConfig->nPrefix; iIdx++){
  4971   5172           if( pConfig->aPrefix[iIdx-1]==nChar ) break;
  4972   5173         }
  4973   5174       }
  4974   5175   
  4975   5176       if( iIdx<=pConfig->nPrefix ){
         5177  +      /* Straight index lookup */
  4976   5178         Fts5Structure *pStruct = fts5StructureRead(p);
  4977   5179         buf.p[0] = (u8)(FTS5_MAIN_PREFIX + iIdx);
  4978   5180         if( pStruct ){
  4979   5181           fts5MultiIterNew(p, pStruct, 1, flags, buf.p, nToken+1, -1, 0, &pRet);
  4980   5182           fts5StructureRelease(pStruct);
  4981   5183         }
  4982   5184       }else{
         5185  +      /* Scan multiple terms in the main index */
  4983   5186         int bDesc = (flags & FTS5INDEX_QUERY_DESC)!=0;
  4984   5187         buf.p[0] = FTS5_MAIN_PREFIX;
  4985   5188         fts5SetupPrefixIter(p, bDesc, buf.p, nToken+1, pColset, &pRet);
  4986   5189       }
  4987   5190   
         5191  +    if( p->rc==SQLITE_OK ){
         5192  +      Fts5SegIter *pSeg = &pRet->aSeg[pRet->aFirst[1].iFirst];
         5193  +      pRet->pColset = pColset;
         5194  +      fts5IterSetOutputCb(&p->rc, pRet);
         5195  +      if( p->rc==SQLITE_OK && pSeg->pLeaf ) pRet->xSetOutputs(pRet, pSeg);
         5196  +    }
  4988   5197       if( p->rc ){
  4989         -      sqlite3Fts5IterClose(pRet);
         5198  +      sqlite3Fts5IterClose(&pRet->base);
  4990   5199         pRet = 0;
  4991   5200         fts5CloseReader(p);
  4992   5201       }
  4993         -    *ppIter = pRet;
         5202  +
         5203  +    *ppIter = &pRet->base;
  4994   5204       sqlite3Fts5BufferFree(&buf);
  4995   5205     }
  4996   5206     return fts5IndexReturn(p);
  4997   5207   }
  4998   5208   
  4999   5209   /*
  5000   5210   ** Return true if the iterator passed as the only argument is at EOF.
  5001   5211   */
  5002   5212   int sqlite3Fts5IterEof(Fts5IndexIter *pIter){
  5003         -  assert( pIter->pIndex->rc==SQLITE_OK );
  5004         -  return pIter->bEof;
         5213  +  assert( ((Fts5Iter*)pIter)->pIndex->rc==SQLITE_OK );
         5214  +  return ((Fts5Iter*)pIter)->bEof;
  5005   5215   }
  5006   5216   
  5007   5217   /*
  5008   5218   ** Move to the next matching rowid. 
  5009   5219   */
  5010         -int sqlite3Fts5IterNext(Fts5IndexIter *pIter){
         5220  +int sqlite3Fts5IterNext(Fts5IndexIter *pIndexIter){
         5221  +  Fts5Iter *pIter = (Fts5Iter*)pIndexIter;
  5011   5222     assert( pIter->pIndex->rc==SQLITE_OK );
  5012   5223     fts5MultiIterNext(pIter->pIndex, pIter, 0, 0);
  5013   5224     return fts5IndexReturn(pIter->pIndex);
  5014   5225   }
  5015   5226   
  5016   5227   /*
  5017   5228   ** Move to the next matching term/rowid. Used by the fts5vocab module.
  5018   5229   */
  5019         -int sqlite3Fts5IterNextScan(Fts5IndexIter *pIter){
         5230  +int sqlite3Fts5IterNextScan(Fts5IndexIter *pIndexIter){
         5231  +  Fts5Iter *pIter = (Fts5Iter*)pIndexIter;
  5020   5232     Fts5Index *p = pIter->pIndex;
  5021   5233   
  5022   5234     assert( pIter->pIndex->rc==SQLITE_OK );
  5023   5235   
  5024   5236     fts5MultiIterNext(p, pIter, 0, 0);
  5025   5237     if( p->rc==SQLITE_OK ){
  5026   5238       Fts5SegIter *pSeg = &pIter->aSeg[ pIter->aFirst[1].iFirst ];
................................................................................
  5035   5247   }
  5036   5248   
  5037   5249   /*
  5038   5250   ** Move to the next matching rowid that occurs at or after iMatch. The
  5039   5251   ** definition of "at or after" depends on whether this iterator iterates
  5040   5252   ** in ascending or descending rowid order.
  5041   5253   */
  5042         -int sqlite3Fts5IterNextFrom(Fts5IndexIter *pIter, i64 iMatch){
         5254  +int sqlite3Fts5IterNextFrom(Fts5IndexIter *pIndexIter, i64 iMatch){
         5255  +  Fts5Iter *pIter = (Fts5Iter*)pIndexIter;
  5043   5256     fts5MultiIterNextFrom(pIter->pIndex, pIter, iMatch);
  5044   5257     return fts5IndexReturn(pIter->pIndex);
  5045   5258   }
  5046   5259   
  5047   5260   /*
  5048   5261   ** Return the current rowid.
  5049   5262   */
  5050         -i64 sqlite3Fts5IterRowid(Fts5IndexIter *pIter){
  5051         -  return fts5MultiIterRowid(pIter);
         5263  +i64 sqlite3Fts5IterRowid(Fts5IndexIter *pIndexIter){
         5264  +  return fts5MultiIterRowid((Fts5Iter*)pIndexIter);
  5052   5265   }
  5053   5266   
  5054   5267   /*
  5055   5268   ** Return the current term.
  5056   5269   */
  5057         -const char *sqlite3Fts5IterTerm(Fts5IndexIter *pIter, int *pn){
         5270  +const char *sqlite3Fts5IterTerm(Fts5IndexIter *pIndexIter, int *pn){
  5058   5271     int n;
  5059         -  const char *z = (const char*)fts5MultiIterTerm(pIter, &n);
         5272  +  const char *z = (const char*)fts5MultiIterTerm((Fts5Iter*)pIndexIter, &n);
  5060   5273     *pn = n-1;
  5061   5274     return &z[1];
  5062   5275   }
  5063   5276   
  5064         -
  5065         -static int fts5IndexExtractColset (
  5066         -  Fts5Colset *pColset,            /* Colset to filter on */
  5067         -  const u8 *pPos, int nPos,       /* Position list */
  5068         -  Fts5Buffer *pBuf                /* Output buffer */
  5069         -){
  5070         -  int rc = SQLITE_OK;
  5071         -  int i;
  5072         -
  5073         -  fts5BufferZero(pBuf);
  5074         -  for(i=0; i<pColset->nCol; i++){
  5075         -    const u8 *pSub = pPos;
  5076         -    int nSub = fts5IndexExtractCol(&pSub, nPos, pColset->aiCol[i]);
  5077         -    if( nSub ){
  5078         -      fts5BufferAppendBlob(&rc, pBuf, nSub, pSub);
  5079         -    }
  5080         -  }
  5081         -  return rc;
  5082         -}
  5083         -
  5084         -
  5085         -/*
  5086         -** Return a pointer to a buffer containing a copy of the position list for
  5087         -** the current entry. Output variable *pn is set to the size of the buffer 
  5088         -** in bytes before returning.
  5089         -**
  5090         -** The returned position list does not include the "number of bytes" varint
  5091         -** field that starts the position list on disk.
  5092         -*/
  5093         -int sqlite3Fts5IterPoslist(
  5094         -  Fts5IndexIter *pIter, 
  5095         -  Fts5Colset *pColset,            /* Column filter (or NULL) */
  5096         -  const u8 **pp,                  /* OUT: Pointer to position-list data */
  5097         -  int *pn,                        /* OUT: Size of position-list in bytes */
  5098         -  i64 *piRowid                    /* OUT: Current rowid */
  5099         -){
  5100         -  Fts5SegIter *pSeg = &pIter->aSeg[ pIter->aFirst[1].iFirst ];
  5101         -  int eDetail = pIter->pIndex->pConfig->eDetail;
  5102         -
  5103         -  assert( pIter->pIndex->rc==SQLITE_OK );
  5104         -  *piRowid = pSeg->iRowid;
  5105         -  if( eDetail==FTS5_DETAIL_NONE ){
  5106         -    *pn = pSeg->nPos;
  5107         -  }else
  5108         -  if( eDetail==FTS5_DETAIL_FULL 
  5109         -   && pSeg->iLeafOffset+pSeg->nPos<=pSeg->pLeaf->szLeaf 
  5110         -  ){
  5111         -    u8 *pPos = &pSeg->pLeaf->p[pSeg->iLeafOffset];
  5112         -    if( pColset==0 || pIter->bFiltered ){
  5113         -      *pn = pSeg->nPos;
  5114         -      *pp = pPos;
  5115         -    }else if( pColset->nCol==1 ){
  5116         -      *pp = pPos;
  5117         -      *pn = fts5IndexExtractCol(pp, pSeg->nPos, pColset->aiCol[0]);
  5118         -    }else{
  5119         -      fts5BufferZero(&pIter->poslist);
  5120         -      fts5IndexExtractColset(pColset, pPos, pSeg->nPos, &pIter->poslist);
  5121         -      *pp = pIter->poslist.p;
  5122         -      *pn = pIter->poslist.n;
  5123         -    }
  5124         -  }else{
  5125         -    fts5BufferZero(&pIter->poslist);
  5126         -    fts5SegiterPoslist(pIter->pIndex, pSeg, pColset, &pIter->poslist);
  5127         -    if( eDetail==FTS5_DETAIL_FULL ){
  5128         -      *pp = pIter->poslist.p;
  5129         -    }
  5130         -    *pn = pIter->poslist.n;
  5131         -  }
  5132         -  return fts5IndexReturn(pIter->pIndex);
  5133         -}
  5134         -
  5135         -int sqlite3Fts5IterCollist(
  5136         -  Fts5IndexIter *pIter, 
  5137         -  const u8 **pp,                  /* OUT: Pointer to position-list data */
  5138         -  int *pn                         /* OUT: Size of position-list in bytes */
  5139         -){
  5140         -  assert( pIter->pIndex->pConfig->eDetail==FTS5_DETAIL_COLUMNS );
  5141         -  *pp = pIter->poslist.p;
  5142         -  *pn = pIter->poslist.n;
  5143         -  return SQLITE_OK;
  5144         -}
  5145         -
  5146         -/*
  5147         -** This function is similar to sqlite3Fts5IterPoslist(), except that it
  5148         -** copies the position list into the buffer supplied as the second 
  5149         -** argument.
  5150         -*/
  5151         -int sqlite3Fts5IterPoslistBuffer(Fts5IndexIter *pIter, Fts5Buffer *pBuf){
  5152         -  Fts5Index *p = pIter->pIndex;
  5153         -  Fts5SegIter *pSeg = &pIter->aSeg[ pIter->aFirst[1].iFirst ];
  5154         -  assert( p->rc==SQLITE_OK );
  5155         -  fts5BufferZero(pBuf);
  5156         -  fts5SegiterPoslist(p, pSeg, 0, pBuf);
  5157         -  return fts5IndexReturn(p);
  5158         -}
  5159         -
  5160   5277   /*
  5161   5278   ** Close an iterator opened by an earlier call to sqlite3Fts5IndexQuery().
  5162   5279   */
  5163         -void sqlite3Fts5IterClose(Fts5IndexIter *pIter){
  5164         -  if( pIter ){
         5280  +void sqlite3Fts5IterClose(Fts5IndexIter *pIndexIter){
         5281  +  if( pIndexIter ){
         5282  +    Fts5Iter *pIter = (Fts5Iter*)pIndexIter;
  5165   5283       Fts5Index *pIndex = pIter->pIndex;
  5166   5284       fts5MultiIterFree(pIter->pIndex, pIter);
  5167   5285       fts5CloseReader(pIndex);
  5168   5286     }
  5169   5287   }
  5170   5288   
  5171   5289   /*
................................................................................
  5324   5442     const char *z,                  /* Index key to query for */
  5325   5443     int n,                          /* Size of index key in bytes */
  5326   5444     int flags,                      /* Flags for Fts5IndexQuery */
  5327   5445     u64 *pCksum                     /* IN/OUT: Checksum value */
  5328   5446   ){
  5329   5447     int eDetail = p->pConfig->eDetail;
  5330   5448     u64 cksum = *pCksum;
  5331         -  Fts5IndexIter *pIdxIter = 0;
  5332         -  Fts5Buffer buf = {0, 0, 0};
  5333         -  int rc = sqlite3Fts5IndexQuery(p, z, n, flags, 0, &pIdxIter);
         5449  +  Fts5IndexIter *pIter = 0;
         5450  +  int rc = sqlite3Fts5IndexQuery(p, z, n, flags, 0, &pIter);
  5334   5451   
  5335         -  while( rc==SQLITE_OK && 0==sqlite3Fts5IterEof(pIdxIter) ){
  5336         -    i64 rowid = sqlite3Fts5IterRowid(pIdxIter);
         5452  +  while( rc==SQLITE_OK && 0==sqlite3Fts5IterEof(pIter) ){
         5453  +    i64 rowid = sqlite3Fts5IterRowid(pIter);
  5337   5454   
  5338   5455       if( eDetail==FTS5_DETAIL_NONE ){
  5339   5456         cksum ^= sqlite3Fts5IndexEntryCksum(rowid, 0, 0, iIdx, z, n);
  5340   5457       }else{
  5341         -      rc = sqlite3Fts5IterPoslistBuffer(pIdxIter, &buf);
  5342         -      if( rc==SQLITE_OK ){
  5343         -        Fts5PoslistReader sReader;
  5344         -        for(sqlite3Fts5PoslistReaderInit(buf.p, buf.n, &sReader);
  5345         -            sReader.bEof==0;
  5346         -            sqlite3Fts5PoslistReaderNext(&sReader)
  5347         -        ){
  5348         -          int iCol = FTS5_POS2COLUMN(sReader.iPos);
  5349         -          int iOff = FTS5_POS2OFFSET(sReader.iPos);
  5350         -          cksum ^= sqlite3Fts5IndexEntryCksum(rowid, iCol, iOff, iIdx, z, n);
  5351         -        }
         5458  +      Fts5PoslistReader sReader;
         5459  +      for(sqlite3Fts5PoslistReaderInit(pIter->pData, pIter->nData, &sReader);
         5460  +          sReader.bEof==0;
         5461  +          sqlite3Fts5PoslistReaderNext(&sReader)
         5462  +      ){
         5463  +        int iCol = FTS5_POS2COLUMN(sReader.iPos);
         5464  +        int iOff = FTS5_POS2OFFSET(sReader.iPos);
         5465  +        cksum ^= sqlite3Fts5IndexEntryCksum(rowid, iCol, iOff, iIdx, z, n);
  5352   5466         }
  5353   5467       }
  5354   5468       if( rc==SQLITE_OK ){
  5355         -      rc = sqlite3Fts5IterNext(pIdxIter);
         5469  +      rc = sqlite3Fts5IterNext(pIter);
  5356   5470       }
  5357   5471     }
  5358         -  sqlite3Fts5IterClose(pIdxIter);
  5359         -  fts5BufferFree(&buf);
         5472  +  sqlite3Fts5IterClose(pIter);
  5360   5473   
  5361   5474     *pCksum = cksum;
  5362   5475     return rc;
  5363   5476   }
  5364   5477   
  5365   5478   
  5366   5479   /*
................................................................................
  5657   5770   ** error, or some other SQLite error code if another error (e.g. OOM)
  5658   5771   ** occurs.
  5659   5772   */
  5660   5773   int sqlite3Fts5IndexIntegrityCheck(Fts5Index *p, u64 cksum){
  5661   5774     int eDetail = p->pConfig->eDetail;
  5662   5775     u64 cksum2 = 0;                 /* Checksum based on contents of indexes */
  5663   5776     Fts5Buffer poslist = {0,0,0};   /* Buffer used to hold a poslist */
  5664         -  Fts5IndexIter *pIter;           /* Used to iterate through entire index */
         5777  +  Fts5Iter *pIter;                /* Used to iterate through entire index */
  5665   5778     Fts5Structure *pStruct;         /* Index structure */
  5666   5779   
  5667   5780   #ifdef SQLITE_DEBUG
  5668   5781     /* Used by extra internal tests only run if NDEBUG is not defined */
  5669   5782     u64 cksum3 = 0;                 /* Checksum based on contents of indexes */
  5670   5783     Fts5Buffer term = {0,0,0};      /* Buffer used to hold most recent term */
  5671   5784   #endif

Changes to ext/fts5/fts5_main.c.

   216    216   #define FTS5_BI_ORDER_RANK   0x0020
   217    217   #define FTS5_BI_ORDER_ROWID  0x0040
   218    218   #define FTS5_BI_ORDER_DESC   0x0080
   219    219   
   220    220   /*
   221    221   ** Values for Fts5Cursor.csrflags
   222    222   */
   223         -#define FTS5CSR_REQUIRE_CONTENT   0x01
   224         -#define FTS5CSR_REQUIRE_DOCSIZE   0x02
   225         -#define FTS5CSR_REQUIRE_INST      0x04
   226         -#define FTS5CSR_EOF               0x08
          223  +#define FTS5CSR_EOF               0x01
          224  +#define FTS5CSR_REQUIRE_CONTENT   0x02
          225  +#define FTS5CSR_REQUIRE_DOCSIZE   0x04
          226  +#define FTS5CSR_REQUIRE_INST      0x08
   227    227   #define FTS5CSR_FREE_ZRANK        0x10
   228    228   #define FTS5CSR_REQUIRE_RESEEK    0x20
   229    229   #define FTS5CSR_REQUIRE_POSLIST   0x40
   230    230   
   231    231   #define BitFlagAllTest(x,y) (((x) & (y))==(y))
   232    232   #define BitFlagTest(x,y)    (((x) & (y))!=0)
   233    233   
................................................................................
   534    534     aColMap[1] = pConfig->nCol;
   535    535     aColMap[2] = pConfig->nCol+1;
   536    536   
   537    537     /* Set idxFlags flags for all WHERE clause terms that will be used. */
   538    538     for(i=0; i<pInfo->nConstraint; i++){
   539    539       struct sqlite3_index_constraint *p = &pInfo->aConstraint[i];
   540    540       int j;
   541         -    for(j=0; j<(int)ArraySize(aConstraint); j++){
          541  +    for(j=0; j<ArraySize(aConstraint); j++){
   542    542         struct Constraint *pC = &aConstraint[j];
   543    543         if( p->iColumn==aColMap[pC->iCol] && p->op & pC->op ){
   544    544           if( p->usable ){
   545    545             pC->iConsIndex = i;
   546    546             idxFlags |= pC->fts5op;
   547    547           }else if( j==0 ){
   548    548             /* As there exists an unusable MATCH constraint this is an 
................................................................................
   581    581       pInfo->estimatedCost = bHasMatch ? 750.0 : 750000.0;
   582    582     }else{
   583    583       pInfo->estimatedCost = bHasMatch ? 1000.0 : 1000000.0;
   584    584     }
   585    585   
   586    586     /* Assign argvIndex values to each constraint in use. */
   587    587     iNext = 1;
   588         -  for(i=0; i<(int)ArraySize(aConstraint); i++){
          588  +  for(i=0; i<ArraySize(aConstraint); i++){
   589    589       struct Constraint *pC = &aConstraint[i];
   590    590       if( pC->iConsIndex>=0 ){
   591    591         pInfo->aConstraintUsage[pC->iConsIndex].argvIndex = iNext++;
   592    592         pInfo->aConstraintUsage[pC->iConsIndex].omit = (unsigned char)pC->omit;
   593    593       }
   594    594     }
   595    595   
................................................................................
   774    774     assert( *pbSkip==0 );
   775    775     if( CsrFlagTest(pCsr, FTS5CSR_REQUIRE_RESEEK) ){
   776    776       Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab);
   777    777       int bDesc = pCsr->bDesc;
   778    778       i64 iRowid = sqlite3Fts5ExprRowid(pCsr->pExpr);
   779    779   
   780    780       rc = sqlite3Fts5ExprFirst(pCsr->pExpr, pTab->pIndex, iRowid, bDesc);
   781         -    if( rc==SQLITE_OK && iRowid!=sqlite3Fts5ExprRowid(pCsr->pExpr) ){
          781  +    if( rc==SQLITE_OK &&  iRowid!=sqlite3Fts5ExprRowid(pCsr->pExpr) ){
   782    782         *pbSkip = 1;
   783    783       }
   784    784   
   785    785       CsrFlagClear(pCsr, FTS5CSR_REQUIRE_RESEEK);
   786    786       fts5CsrNewrow(pCsr);
   787    787       if( sqlite3Fts5ExprEof(pCsr->pExpr) ){
   788    788         CsrFlagSet(pCsr, FTS5CSR_EOF);
          789  +      *pbSkip = 1;
   789    790       }
   790    791     }
   791    792     return rc;
   792    793   }
   793    794   
   794    795   
   795    796   /*
................................................................................
   803    804   static int fts5NextMethod(sqlite3_vtab_cursor *pCursor){
   804    805     Fts5Cursor *pCsr = (Fts5Cursor*)pCursor;
   805    806     int rc = SQLITE_OK;
   806    807   
   807    808     assert( (pCsr->ePlan<3)==
   808    809             (pCsr->ePlan==FTS5_PLAN_MATCH || pCsr->ePlan==FTS5_PLAN_SOURCE) 
   809    810     );
          811  +  assert( !CsrFlagTest(pCsr, FTS5CSR_EOF) );
   810    812   
   811    813     if( pCsr->ePlan<3 ){
   812    814       int bSkip = 0;
   813    815       if( (rc = fts5CursorReseek(pCsr, &bSkip)) || bSkip ) return rc;
   814    816       rc = sqlite3Fts5ExprNext(pCsr->pExpr, pCsr->iLastRowid);
   815         -    if( sqlite3Fts5ExprEof(pCsr->pExpr) ){
   816         -      CsrFlagSet(pCsr, FTS5CSR_EOF);
   817         -    }
          817  +    CsrFlagSet(pCsr, sqlite3Fts5ExprEof(pCsr->pExpr));
   818    818       fts5CsrNewrow(pCsr);
   819    819     }else{
   820    820       switch( pCsr->ePlan ){
   821    821         case FTS5_PLAN_SPECIAL: {
   822    822           CsrFlagSet(pCsr, FTS5CSR_EOF);
   823    823           break;
   824    824         }

Changes to ext/fts5/fts5_storage.c.

   334    334   */
   335    335   int sqlite3Fts5StorageClose(Fts5Storage *p){
   336    336     int rc = SQLITE_OK;
   337    337     if( p ){
   338    338       int i;
   339    339   
   340    340       /* Finalize all SQL statements */
   341         -    for(i=0; i<(int)ArraySize(p->aStmt); i++){
          341  +    for(i=0; i<ArraySize(p->aStmt); i++){
   342    342         sqlite3_finalize(p->aStmt[i]);
   343    343       }
   344    344   
   345    345       sqlite3_free(p);
   346    346     }
   347    347     return rc;
   348    348   }

Changes to ext/fts5/fts5_tokenize.c.

  1216   1216       { "ascii",     {fts5AsciiCreate, fts5AsciiDelete, fts5AsciiTokenize }},
  1217   1217       { "porter",    {fts5PorterCreate, fts5PorterDelete, fts5PorterTokenize }},
  1218   1218     };
  1219   1219     
  1220   1220     int rc = SQLITE_OK;             /* Return code */
  1221   1221     int i;                          /* To iterate through builtin functions */
  1222   1222   
  1223         -  for(i=0; rc==SQLITE_OK && i<(int)ArraySize(aBuiltin); i++){
         1223  +  for(i=0; rc==SQLITE_OK && i<ArraySize(aBuiltin); i++){
  1224   1224       rc = pApi->xCreateTokenizer(pApi,
  1225   1225           aBuiltin[i].zName,
  1226   1226           (void*)pApi,
  1227   1227           &aBuiltin[i].x,
  1228   1228           0
  1229   1229       );
  1230   1230     }
  1231   1231   
  1232   1232     return rc;
  1233   1233   }
  1234   1234   
  1235   1235   

Changes to ext/fts5/fts5_vocab.c.

   180    180       const char *zType = bDb ? argv[5] : argv[4];
   181    181       int nDb = (int)strlen(zDb)+1; 
   182    182       int nTab = (int)strlen(zTab)+1;
   183    183       int eType = 0;
   184    184       
   185    185       rc = fts5VocabTableType(zType, pzErr, &eType);
   186    186       if( rc==SQLITE_OK ){
   187         -      assert( eType>=0 && eType<sizeof(azSchema)/sizeof(azSchema[0]) );
          187  +      assert( eType>=0 && eType<ArraySize(azSchema) );
   188    188         rc = sqlite3_declare_vtab(db, azSchema[eType]);
   189    189       }
   190    190   
   191    191       nByte = sizeof(Fts5VocabTable) + nDb + nTab;
   192    192       pRet = sqlite3Fts5MallocZero(&rc, nByte);
   193    193       if( pRet ){
   194    194         pRet->pGlobal = (Fts5Global*)pAux;
................................................................................
   403    403         sqlite3Fts5BufferSet(&rc, &pCsr->term, nTerm, (const u8*)zTerm);
   404    404         memset(pCsr->aCnt, 0, nCol * sizeof(i64));
   405    405         memset(pCsr->aDoc, 0, nCol * sizeof(i64));
   406    406         pCsr->iCol = 0;
   407    407   
   408    408         assert( pTab->eType==FTS5_VOCAB_COL || pTab->eType==FTS5_VOCAB_ROW );
   409    409         while( rc==SQLITE_OK ){
   410         -        i64 dummy;
   411    410           const u8 *pPos; int nPos;   /* Position list */
   412    411           i64 iPos = 0;               /* 64-bit position read from poslist */
   413    412           int iOff = 0;               /* Current offset within position list */
   414    413   
          414  +        pPos = pCsr->pIter->pData;
          415  +        nPos = pCsr->pIter->nData;
   415    416           switch( pCsr->pConfig->eDetail ){
   416    417             case FTS5_DETAIL_FULL:
   417         -            rc = sqlite3Fts5IterPoslist(pCsr->pIter, 0, &pPos, &nPos, &dummy);
   418         -            if( rc==SQLITE_OK ){
   419         -              if( pTab->eType==FTS5_VOCAB_ROW ){
   420         -                while( 0==sqlite3Fts5PoslistNext64(pPos, nPos, &iOff, &iPos) ){
   421         -                  pCsr->aCnt[0]++;
   422         -                }
   423         -                pCsr->aDoc[0]++;
   424         -              }else{
   425         -                int iCol = -1;
   426         -                while( 0==sqlite3Fts5PoslistNext64(pPos, nPos, &iOff, &iPos) ){
   427         -                  int ii = FTS5_POS2COLUMN(iPos);
   428         -                  pCsr->aCnt[ii]++;
   429         -                  if( iCol!=ii ){
   430         -                    if( ii>=nCol ){
   431         -                      rc = FTS5_CORRUPT;
   432         -                      break;
   433         -                    }
   434         -                    pCsr->aDoc[ii]++;
   435         -                    iCol = ii;
          418  +            pPos = pCsr->pIter->pData;
          419  +            nPos = pCsr->pIter->nData;
          420  +            if( pTab->eType==FTS5_VOCAB_ROW ){
          421  +              while( 0==sqlite3Fts5PoslistNext64(pPos, nPos, &iOff, &iPos) ){
          422  +                pCsr->aCnt[0]++;
          423  +              }
          424  +              pCsr->aDoc[0]++;
          425  +            }else{
          426  +              int iCol = -1;
          427  +              while( 0==sqlite3Fts5PoslistNext64(pPos, nPos, &iOff, &iPos) ){
          428  +                int ii = FTS5_POS2COLUMN(iPos);
          429  +                pCsr->aCnt[ii]++;
          430  +                if( iCol!=ii ){
          431  +                  if( ii>=nCol ){
          432  +                    rc = FTS5_CORRUPT;
          433  +                    break;
   436    434                     }
          435  +                  pCsr->aDoc[ii]++;
          436  +                  iCol = ii;
   437    437                   }
   438    438                 }
   439    439               }
   440    440               break;
   441    441   
   442    442             case FTS5_DETAIL_COLUMNS:
   443    443               if( pTab->eType==FTS5_VOCAB_ROW ){
   444    444                 pCsr->aDoc[0]++;
   445    445               }else{
   446         -              Fts5Buffer buf = {0, 0, 0};
   447         -              rc = sqlite3Fts5IterPoslistBuffer(pCsr->pIter, &buf);
   448         -              if( rc==SQLITE_OK ){
   449         -                while( 0==sqlite3Fts5PoslistNext64(buf.p, buf.n, &iOff,&iPos) ){
   450         -                  assert_nc( iPos>=0 && iPos<nCol );
   451         -                  if( iPos>=nCol ){
   452         -                    rc = FTS5_CORRUPT;
   453         -                    break;
   454         -                  }
   455         -                  pCsr->aDoc[iPos]++;
          446  +              while( 0==sqlite3Fts5PoslistNext64(pPos, nPos, &iOff,&iPos) ){
          447  +                assert_nc( iPos>=0 && iPos<nCol );
          448  +                if( iPos>=nCol ){
          449  +                  rc = FTS5_CORRUPT;
          450  +                  break;
   456    451                   }
          452  +                pCsr->aDoc[iPos]++;
   457    453                 }
   458         -              sqlite3Fts5BufferFree(&buf);
   459    454               }
   460    455               break;
   461    456   
   462    457             default: 
   463    458               assert( pCsr->pConfig->eDetail==FTS5_DETAIL_NONE );
   464    459               pCsr->aDoc[0]++;
   465    460               break;

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

    44     44   
    45     45     for {set i 0} {$i < [$cmd xPhraseCount]} {incr i} {
    46     46       $cmd xPhraseForeach $i c o {
    47     47         lappend res $i.$c.$o
    48     48       }
    49     49     }
    50     50   
    51         -  set res
           51  +  #set res
           52  +  sort_poslist $res
    52     53   }
    53     54   
    54     55   proc fts5_test_collist {cmd} {
    55     56     set res [list]
    56     57   
    57     58     for {set i 0} {$i < [$cmd xPhraseCount]} {incr i} {
    58     59       $cmd xPhraseColumnForeach $i c { lappend res $i.$c }

Changes to ext/fts5/test/fts5ac.test.

   154    154     do_execsql_test 1.$tn2.integrity {
   155    155       INSERT INTO xx(xx) VALUES('integrity-check');
   156    156     }
   157    157   
   158    158     #-------------------------------------------------------------------------
   159    159     #
   160    160     foreach {tn expr} {
   161         -    1.2 "a   OR b"
   162    161       1.1 "a   AND b"
          162  +    1.2 "a   OR b"
   163    163       1.3 "o"
   164    164       1.4 "b q"
   165    165       1.5 "e a e"
   166    166       1.6 "m d g q q b k b w f q q p p"
   167    167       1.7 "l o o l v v k"
   168    168       1.8 "a"
   169    169       1.9 "b"
................................................................................
   245    245       }
   246    246   
   247    247       set res [fts5_query_data $expr xx]
   248    248       do_execsql_test 1.$tn2.$tn.[llength $res].asc {
   249    249         SELECT rowid, fts5_test_poslist(xx), fts5_test_collist(xx) 
   250    250         FROM xx WHERE xx match $expr
   251    251       } $res
   252         -
   253    252   
   254    253       set res [fts5_query_data $expr xx DESC]
   255    254       do_execsql_test 1.$tn2.$tn.[llength $res].desc {
   256    255         SELECT rowid, fts5_test_poslist(xx), fts5_test_collist(xx) 
   257    256         FROM xx WHERE xx match $expr ORDER BY 1 DESC
   258    257       } $res
   259    258     }

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

    15     15   
    16     16   # If SQLITE_ENABLE_FTS5 is defined, omit this file.
    17     17   ifcapable !fts5 {
    18     18     finish_test
    19     19     return
    20     20   }
    21     21   
    22         - if 1 {
           22  +if 1 {
    23     23   
    24     24   #-------------------------------------------------------------------------
    25     25   #
    26     26   set doc "x x [string repeat {y } 50]z z"
    27     27   do_execsql_test 1.0 {
    28     28     CREATE VIRTUAL TABLE t1 USING fts5(x);
    29     29     INSERT INTO t1(t1, rank) VALUES('pgsz', 32);
................................................................................
   359    359     INSERT INTO x2 VALUES('ab');
   360    360   }
   361    361   
   362    362   do_execsql_test 15.1 {
   363    363     INSERT INTO x2(x2) VALUES('integrity-check');
   364    364   }
   365    365   
   366         -}
   367         -
   368    366   #-------------------------------------------------------------------------
   369    367   foreach_detail_mode $testprefix {
   370    368     reset_db
   371    369     fts5_aux_test_functions db
   372    370     do_execsql_test 16.0 {
   373    371       CREATE VIRTUAL TABLE x3 USING fts5(x, detail=%DETAIL%);
   374    372       INSERT INTO x3 VALUES('a b c d e f');
................................................................................
   377    375       SELECT fts5_test_poslist(x3) FROM x3('(a NOT b) OR c');
   378    376     } {2.0.2}
   379    377   
   380    378     do_execsql_test 16.1 {
   381    379       SELECT fts5_test_poslist(x3) FROM x3('a OR c');
   382    380     } {{0.0.0 1.0.2}}
   383    381   }
          382  +
          383  +}
          384  +
          385  +#-------------------------------------------------------------------------
          386  +reset_db
          387  +do_execsql_test 17.0 {
          388  +  CREATE VIRTUAL TABLE x3 USING fts5(x);
          389  +  INSERT INTO x3 VALUES('a b c');
          390  +}
          391  +
          392  +do_execsql_test 17.1 {
          393  +  SELECT rowid FROM x3('b AND d');
          394  +}
          395  +
          396  +#-------------------------------------------------------------------------
          397  +do_execsql_test 18.1 {
          398  +  CREATE VIRTUAL TABLE x4 USING fts5(x);
          399  +  SELECT rowid FROM x4('""');
          400  +}
   384    401   
   385    402   finish_test
   386    403   

Added ext/fts5/test/fts5simple3.test.

            1  +# 2015 September 05
            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]] fts5_common.tcl]
           14  +set testprefix fts5simple3
           15  +
           16  +# If SQLITE_ENABLE_FTS5 is defined, omit this file.
           17  +ifcapable !fts5 {
           18  +  finish_test
           19  +  return
           20  +}
           21  +
           22  +fts5_aux_test_functions db
           23  +
           24  +do_execsql_test 1.0 {
           25  +  CREATE VIRTUAL TABLE t1 USING fts5(a, b, c, detail=col);
           26  +  INSERT INTO t1 VALUES('a', 'b', 'c');
           27  +  INSERT INTO t1 VALUES('x', 'x', 'x');
           28  +}
           29  +
           30  +do_execsql_test 1.1 {
           31  +  SELECT rowid, fts5_test_collist(t1) FROM t1('a:a');
           32  +} {1 0.0}
           33  +
           34  +do_execsql_test 1.2 {
           35  +  SELECT rowid, fts5_test_collist(t1) FROM t1('b:x');
           36  +} {2 0.1}
           37  +
           38  +do_execsql_test 1.3 {
           39  +  SELECT rowid, fts5_test_collist(t1) FROM t1('b:a');
           40  +} {}
           41  +
           42  +
           43  +finish_test
           44  +

Changes to ext/fts5/test/fts5synonym2.test.

    23     23   
    24     24   foreach tok {query document} {
    25     25   foreach_detail_mode $testprefix {
    26     26   
    27     27   fts5_tclnum_register db
    28     28   fts5_aux_test_functions db
    29     29   
           30  +proc fts5_test_bothlist {cmd} {
           31  +
           32  +  for {set i 0} {$i < [$cmd xPhraseCount]} {incr i} {
           33  +    set bFirst 1
           34  +    $cmd xPhraseColumnForeach $i c { 
           35  +      lappend CL $i.$c 
           36  +      if {$bFirst} { $cmd xPhraseForeach $i c o { lappend PL $i.$c.$o } }
           37  +      set bFirst 0
           38  +    }
           39  +  }
           40  +
           41  +  list [sort_poslist $PL] $CL
           42  +}
           43  +sqlite3_fts5_create_function db fts5_test_bothlist fts5_test_bothlist
           44  +
    30     45   proc fts5_rowid {cmd} { expr [$cmd xColumnText -1] }
    31     46   sqlite3_fts5_create_function db fts5_rowid fts5_rowid
    32     47   
    33     48   do_execsql_test 1.$tok.0.1 "
    34     49     CREATE VIRTUAL TABLE ss USING fts5(a, b, 
    35     50          tokenize='tclnum $tok', detail=%DETAIL%);
    36     51     INSERT INTO ss(ss, rank) VALUES('rank', 'fts5_rowid()');
................................................................................
    85    100     INSERT INTO ss VALUES('eight vii eight six 3', 'i vii 1 six 9 vii');
    86    101     INSERT INTO ss VALUES('9 0 viii viii five', 'i 1 viii ix 3 4');
    87    102     INSERT INTO ss VALUES('three nine 5 nine viii four zero', 'ii i 1 5 2 viii');
    88    103     INSERT INTO ss VALUES('5 vii three 9 four', 'three five one 7 2 eight one');
    89    104   }
    90    105   
    91    106   foreach {tn expr} {
          107  +  2.1 "one OR two OR three OR four"
          108  +
    92    109     1.1 "one"   1.2 "two"   1.3 "three"   1.4 "four"
    93    110     1.5 "v"     1.6 "vi"    1.7 "vii"     1.8 "viii"
    94    111     1.9 "9"    1.10 "0"    1.11 "1"      1.12 "2"
    95    112   
    96    113     2.1 "one OR two OR three OR four"
    97    114     2.2 "(one AND two) OR (three AND four)"
    98    115     2.3 "(one AND two) OR (three AND four) NOT five"
................................................................................
   109    126     if {[fts5_expr_ok $expr ss]==0} {
   110    127       do_test 1.$tok.$tn.OMITTED { list } [list]
   111    128       continue
   112    129     }
   113    130   
   114    131     set res [fts5_query_data $expr ss ASC ::tclnum_syn]
   115    132     do_execsql_test 1.$tok.$tn.[llength $res].asc.1 {
   116         -    SELECT rowid, fts5_test_poslist(ss), fts5_test_collist(ss) FROM ss($expr)
          133  +    SELECT rowid, fts5_test_poslist2(ss), fts5_test_collist(ss) FROM ss($expr)
   117    134     } $res
   118    135   
   119    136     do_execsql_test 1.$tok.$tn.[llength $res].asc.2 {
   120    137       SELECT rowid, fts5_test_poslist(ss), fts5_test_collist(ss) FROM ss($expr)
          138  +  } $res
          139  +
          140  +  do_execsql_test 1.$tok.$tn.[llength $res].asc.2 {
          141  +    SELECT rowid, fts5_test_poslist2(ss), fts5_test_collist(ss) FROM ss($expr)
   121    142       ORDER BY rank ASC
   122    143     } $res
          144  +
          145  +  set res2 [list]
          146  +  foreach {a b c} $res { lappend res2 $a $c $b }
          147  +  do_execsql_test 1.$tok.$tn.[llength $res].asc.3 {
          148  +    SELECT rowid, fts5_test_collist(ss), fts5_test_poslist2(ss) FROM ss($expr)
          149  +  } $res2
          150  +
          151  +  set res3 [list]
          152  +  foreach {a b c} $res { lappend res3 $a [list $b $c] }
          153  +  do_execsql_test 1.$tok.$tn.[llength $res].asc.3 {
          154  +    SELECT rowid, fts5_test_bothlist(ss) FROM ss($expr)
          155  +  } $res3
          156  +
          157  +
   123    158   }
   124    159   
   125    160   }
   126    161   }
   127    162   
   128    163   finish_test
   129    164   

Changes to ext/fts5/tool/fts5speed.tcl.

     7      7     {100 "SELECT count(*) FROM t1 WHERE t1 MATCH 'loaned OR mobility OR popcore OR sunk'"}
     8      8     {100 "SELECT count(*) FROM t1 WHERE t1 MATCH 'enron AND myapps'"}
     9      9     {1   "SELECT count(*) FROM t1 WHERE t1 MATCH 'en* AND my*'"}
    10     10   
    11     11     {1   "SELECT count(*) FROM t1 WHERE t1 MATCH 'c:t*'"}
    12     12     {1   "SELECT count(*) FROM t1 WHERE t1 MATCH 'a:t* OR b:t* OR c:t* OR d:t* OR e:t* OR f:t* OR g:t*'"}
    13     13     {1   "SELECT count(*) FROM t1 WHERE t1 MATCH 'a:t*'"}
           14  +  {2   "SELECT count(*) FROM t1 WHERE t1 MATCH 'c:the'"}
    14     15   }
    15     16   
    16     17   proc usage {} {
    17     18     global Q
    18     19     puts stderr "Usage: $::argv0 DATABASE QUERY"
    19     20     puts stderr ""
    20     21     for {set i 1} {$i <= [llength $Q]} {incr i} {

Changes to ext/fts5/tool/fts5txt2db.tcl.

     1         -
     2         -
     3         -proc usage {} {
     4         -  puts stderr "$::argv0 ?OPTIONS? DATABASE FILE1..."
     5         -  puts stderr ""
     6         -  puts stderr "Options are"
     7         -  puts stderr "  -fts5"
     8         -  puts stderr "  -fts4"
     9         -  puts stderr "  -colsize <list of column sizes>"
    10         -  puts stderr {
    11         -This script is designed to create fts4/5 tables with more than one column.
    12         -The -colsize option should be set to a Tcl list of integer values, one for
    13         -each column in the table. Each value is the number of tokens that will be
    14         -inserted into the column value for each row. For example, setting the -colsize
    15         -option to "5 10" creates an FTS table with 2 columns, with roughly 5 and 10
    16         -tokens per row in each, respectively.
    17         -
    18         -Each "FILE" argument should be a text file. The contents of these text files is
    19         -split on whitespace characters to form a list of tokens. The first N1 tokens
    20         -are used for the first column of the first row, where N1 is the first element
    21         -of the -colsize list. The next N2 are used for the second column of the first
    22         -row, and so on. Rows are added to the table until the entire list of tokens
    23         -is exhausted.
    24         -}
    25         -  exit -1
            1  +##########################################################################
            2  +# 2016 Jan 27
            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  +proc process_cmdline {} { 
           12  +  cmdline::process ::A $::argv {
           13  +    {fts5                 "use fts5 (this is the default)"}
           14  +    {fts4                 "use fts4"}
           15  +    {colsize   "10 10 10" "list of column sizes"}
           16  +    {tblname   "t1"       "table name to create"}
           17  +    {detail    "full"     "Fts5 detail mode to use"}
           18  +    {repeat    1          "Load each file this many times"}
           19  +    {prefix    ""         "Fts prefix= option"}
           20  +    database
           21  +    file...
           22  +  } {
           23  +  This script is designed to create fts4/5 tables with more than one column.
           24  +  The -colsize option should be set to a Tcl list of integer values, one for
           25  +  each column in the table. Each value is the number of tokens that will be
           26  +  inserted into the column value for each row. For example, setting the -colsize
           27  +  option to "5 10" creates an FTS table with 2 columns, with roughly 5 and 10
           28  +  tokens per row in each, respectively.
           29  +  
           30  +  Each "FILE" argument should be a text file. The contents of these text files
           31  +  is split on whitespace characters to form a list of tokens. The first N1
           32  +  tokens are used for the first column of the first row, where N1 is the first
           33  +  element of the -colsize list. The next N2 are used for the second column of
           34  +  the first row, and so on. Rows are added to the table until the entire list
           35  +  of tokens is exhausted.
           36  +  }
    26     37   }
    27     38   
    28         -set O(aColSize)       [list 10 10 10]
    29         -set O(tblname)        t1
    30         -set O(fts)            fts5
    31         -
    32         -
    33         -set options_with_values {-colsize}
    34         -
    35         -for {set i 0} {$i < [llength $argv]} {incr i} {
    36         -  set opt [lindex $argv $i]
    37         -  if {[string range $opt 0 0]!="-"} break
    38         -
    39         -  if {[lsearch $options_with_values $opt]>=0} {
    40         -    incr i
    41         -    if {$i==[llength $argv]} usage
    42         -    set val [lindex $argv $i]
           39  +###########################################################################
           40  +###########################################################################
           41  +# Command line options processor. This is generic code that can be copied
           42  +# between scripts.
           43  +#
           44  +namespace eval cmdline {
           45  +  proc cmdline_error {O E {msg ""}} {
           46  +    if {$msg != ""} {
           47  +      puts stderr "Error: $msg"
           48  +      puts stderr ""
           49  +    }
           50  +  
           51  +    set L [list]
           52  +    foreach o $O {
           53  +      if {[llength $o]==1} {
           54  +        lappend L [string toupper $o]
           55  +      }
           56  +    }
           57  +  
           58  +    puts stderr "Usage: $::argv0 ?SWITCHES? $L"
           59  +    puts stderr ""
           60  +    puts stderr "Switches are:"
           61  +    foreach o $O {
           62  +      if {[llength $o]==3} {
           63  +        foreach {a b c} $o {}
           64  +        puts stderr [format "    -%-15s %s (default \"%s\")" "$a VAL" $c $b]
           65  +      } elseif {[llength $o]==2} {
           66  +        foreach {a b} $o {}
           67  +        puts stderr [format "    -%-15s %s" $a $b]
           68  +      }
           69  +    }
           70  +    puts stderr ""
           71  +    puts stderr $E
           72  +    exit -1
    43     73     }
    44         -
    45         -  switch -- $opt {
    46         -    -colsize {
    47         -      set O(aColSize) $val
           74  +  
           75  +  proc process {avar lArgs O E} {
           76  +    upvar $avar A
           77  +    set zTrailing ""       ;# True if ... is present in $O
           78  +    set lPosargs [list]
           79  +  
           80  +    # Populate A() with default values. Also, for each switch in the command
           81  +    # line spec, set an entry in the idx() array as follows:
           82  +    #
           83  +    #  {tblname t1 "table name to use"}  
           84  +    #      -> [set idx(-tblname) {tblname t1 "table name to use"}  
           85  +    #
           86  +    # For each position parameter, append its name to $lPosargs. If the ...
           87  +    # specifier is present, set $zTrailing to the name of the prefix.
           88  +    #
           89  +    foreach o $O {
           90  +      set nm [lindex $o 0]
           91  +      set nArg [llength $o]
           92  +      switch -- $nArg {
           93  +        1 {
           94  +          if {[string range $nm end-2 end]=="..."} {
           95  +            set zTrailing [string range $nm 0 end-3]
           96  +          } else {
           97  +            lappend lPosargs $nm
           98  +          }
           99  +        }
          100  +        2 {
          101  +          set A($nm) 0
          102  +          set idx(-$nm) $o
          103  +        }
          104  +        3 {
          105  +          set A($nm) [lindex $o 1]
          106  +          set idx(-$nm) $o
          107  +        }
          108  +        default {
          109  +          error "Error in command line specification"
          110  +        }
          111  +      }
          112  +    }
          113  +  
          114  +    # Set explicitly specified option values
          115  +    #
          116  +    set nArg [llength $lArgs]
          117  +    for {set i 0} {$i < $nArg} {incr i} {
          118  +      set opt [lindex $lArgs $i]
          119  +      if {[string range $opt 0 0]!="-" || $opt=="--"} break
          120  +      set c [array names idx "${opt}*"]
          121  +      if {[llength $c]==0} { cmdline_error $O $E "Unrecognized option: $opt"}
          122  +      if {[llength $c]>1}  { cmdline_error $O $E "Ambiguous option: $opt"}
          123  +  
          124  +      if {[llength $idx($c)]==3} {
          125  +        if {$i==[llength $lArgs]-1} {
          126  +          cmdline_error $O $E "Option requires argument: $c" 
          127  +        }
          128  +        incr i
          129  +        set A([lindex $idx($c) 0]) [lindex $lArgs $i]
          130  +      } else {
          131  +        set A([lindex $idx($c) 0]) 1
          132  +      }
          133  +    }
          134  +  
          135  +    # Deal with position arguments.
          136  +    #
          137  +    set nPosarg [llength $lPosargs]
          138  +    set nRem [expr $nArg - $i]
          139  +    if {$nRem < $nPosarg || ($zTrailing=="" && $nRem > $nPosarg)} {
          140  +      cmdline_error $O $E
    48    141       }
    49         -
    50         -    -fts4 {
    51         -      set O(fts) fts4
          142  +    for {set j 0} {$j < $nPosarg} {incr j} {
          143  +      set A([lindex $lPosargs $j]) [lindex $lArgs [expr $j+$i]]
    52    144       }
    53         -
    54         -    -fts5 {
    55         -      set O(fts) fts5
          145  +    if {$zTrailing!=""} {
          146  +      set A($zTrailing) [lrange $lArgs [expr $j+$i] end]
    56    147       }
    57    148     }
          149  +} ;# namespace eval cmdline
          150  +# End of command line options processor.
          151  +###########################################################################
          152  +###########################################################################
          153  +
          154  +process_cmdline
          155  +
          156  +# If -fts4 was specified, use fts4. Otherwise, fts5.
          157  +if {$A(fts4)} {
          158  +  set A(fts) fts4
          159  +} else {
          160  +  set A(fts) fts5
    58    161   }
    59    162   
    60         -if {$i > [llength $argv]-2} usage
    61         -set O(db) [lindex $argv $i]
    62         -set O(files) [lrange $argv [expr $i+1] end]
    63         -
    64         -sqlite3 db $O(db)
          163  +sqlite3 db $A(database)
    65    164   
    66    165   # Create the FTS table in the db. Return a list of the table columns.
    67    166   #
    68    167   proc create_table {} {
    69         -  global O
          168  +  global A
    70    169     set cols [list a b c d e f g h i j k l m n o p q r s t u v w x y z]
    71    170   
    72         -  set nCol [llength $O(aColSize)]
          171  +  set nCol [llength $A(colsize)]
    73    172     set cols [lrange $cols 0 [expr $nCol-1]]
    74    173   
    75         -  set sql    "CREATE VIRTUAL TABLE IF NOT EXISTS $O(tblname) USING $O(fts) ("
          174  +  set sql    "CREATE VIRTUAL TABLE IF NOT EXISTS $A(tblname) USING $A(fts) ("
    76    175     append sql [join $cols ,]
    77         -  append sql ");"
          176  +  if {$A(fts)=="fts5"} { append sql ",detail=$A(detail)" }
          177  +  append sql ", prefix='$A(prefix)');"
    78    178   
    79    179     db eval $sql
    80    180     return $cols
    81    181   }
    82    182   
    83    183   # Return a list of tokens from the named file.
    84    184   #
................................................................................
    85    185   proc readfile {file} {
    86    186     set fd [open $file]
    87    187     set data [read $fd]
    88    188     close $fd
    89    189     split $data
    90    190   }
    91    191   
          192  +proc repeat {L n} {
          193  +  set res [list]
          194  +  for {set i 0} {$i < $n} {incr i} {
          195  +    set res [concat $res $L]
          196  +  }
          197  +  set res
          198  +}
          199  +
    92    200   
    93    201   # Load all the data into a big list of tokens.
    94    202   #
    95    203   set tokens [list]
    96         -foreach f $O(files) {
    97         -  set tokens [concat $tokens [readfile $f]]
          204  +foreach f $A(file) {
          205  +  set tokens [concat $tokens [repeat [readfile $f] $A(repeat)]]
    98    206   }
    99    207   
   100    208   set N [llength $tokens]
   101    209   set i 0
   102    210   set cols [create_table]
   103         -set sql "INSERT INTO $O(tblname) VALUES(\$[lindex $cols 0]"
          211  +set sql "INSERT INTO $A(tblname) VALUES(\$R([lindex $cols 0])"
   104    212   foreach c [lrange $cols 1 end] {
   105         -  append sql ", \$A($c)"
          213  +  append sql ", \$R($c)"
   106    214   }
   107    215   append sql ")"
   108    216   
   109    217   db eval BEGIN
   110    218     while {$i < $N} {
   111         -    foreach c $cols s $O(aColSize) {
   112         -      set A($c) [lrange $tokens $i [expr $i+$s-1]]
          219  +    foreach c $cols s $A(colsize) {
          220  +      set R($c) [lrange $tokens $i [expr $i+$s-1]]
   113    221         incr i $s
   114    222       }
   115    223       db eval $sql
   116    224     }
   117    225   db eval COMMIT
   118    226   
   119    227   
   120    228   

Changes to ext/fts5/tool/loadfts5.tcl.

    45     45     puts stderr "  -delete      (delete the database file before starting)"
    46     46     puts stderr "  -limit N     (load no more than N documents)"
    47     47     puts stderr "  -automerge N (set the automerge parameter to N)"
    48     48     puts stderr "  -crisismerge N (set the crisismerge parameter to N)"
    49     49     puts stderr "  -prefix PREFIX (comma separated prefix= argument)"
    50     50     puts stderr "  -trans N     (commit after N inserts - 0 == never)"
    51     51     puts stderr "  -hashsize N  (set the fts5 hashsize parameter to N)"
           52  +  puts stderr "  -detail MODE (detail mode for fts5 tables)"
    52     53     exit 1
    53     54   }
    54     55   
    55     56   set O(vtab)       fts5
    56     57   set O(tok)        ""
    57     58   set O(limit)      0
    58     59   set O(delete)     0
    59     60   set O(automerge)  -1
    60     61   set O(crisismerge)  -1
    61     62   set O(prefix)     ""
    62     63   set O(trans)      0
    63     64   set O(hashsize)   -1
           65  +set O(detail)     full
    64     66   
    65     67   if {[llength $argv]<2} usage
    66     68   set nOpt [expr {[llength $argv]-2}]
    67     69   for {set i 0} {$i < $nOpt} {incr i} {
    68     70     set arg [lindex $argv $i]
    69     71     switch -- [lindex $argv $i] {
    70     72       -fts4 {
................................................................................
   108    110         set O(prefix) [lindex $argv $i]
   109    111       }
   110    112   
   111    113       -hashsize {
   112    114         if { [incr i]>=$nOpt } usage
   113    115         set O(hashsize) [lindex $argv $i]
   114    116       }
          117  +
          118  +    -detail {
          119  +      if { [incr i]>=$nOpt } usage
          120  +      set O(detail) [lindex $argv $i]
          121  +    }
   115    122   
   116    123       default {
   117    124         usage
   118    125       }
   119    126     }
   120    127   }
   121    128   
................................................................................
   125    132   catch { load_static_extension db fts5 }
   126    133   db func loadfile loadfile
   127    134   db eval "PRAGMA page_size=4096"
   128    135   
   129    136   db eval BEGIN
   130    137     set pref ""
   131    138     if {$O(prefix)!=""} { set pref ", prefix='$O(prefix)'" }
          139  +  if {$O(vtab)=="fts5"} {
          140  +    append pref ", detail=$O(detail)"
          141  +  }
   132    142     catch {
   133    143       db eval "CREATE VIRTUAL TABLE t1 USING $O(vtab) (path, content$O(tok)$pref)"
   134    144       db eval "INSERT INTO t1(t1, rank) VALUES('pgsz', 4050);"
   135    145     }
   136    146   
   137    147     if {$O(hashsize)>=0} {
   138    148       catch {

Changes to ext/misc/spellfix.c.

   361    361     char cAnext, cBnext;   /* Next character in zA and zB */
   362    362     int d;                 /* North-west cost value */
   363    363     int dc = 0;            /* North-west character value */
   364    364     int res;               /* Final result */
   365    365     int *m;                /* The cost matrix */
   366    366     char *cx;              /* Corresponding character values */
   367    367     int *toFree = 0;       /* Malloced space */
   368         -  int mStack[60+15];     /* Stack space to use if not too much is needed */
   369    368     int nMatch = 0;
          369  +  int mStack[60+15];     /* Stack space to use if not too much is needed */
   370    370   
   371    371     /* Early out if either input is NULL */
   372    372     if( zA==0 || zB==0 ) return -1;
   373    373   
   374    374     /* Skip any common prefix */
   375    375     while( zA[0] && zA[0]==zB[0] ){ dc = zA[0]; zA++; zB++; nMatch++; }
   376    376     if( pnMatch ) *pnMatch = nMatch;
................................................................................
   871    871     assert( iCost>=0 );
   872    872     if( iCost<10000 ){
   873    873       unsigned int b = m[j] + iCost;
   874    874       if( b<m[i] ) m[i] = b;
   875    875     }
   876    876   }
   877    877   
          878  +/*
          879  +** How much stack space (int bytes) to use for Wagner matrix in 
          880  +** editDist3Core().  If more space than this is required, the entire
          881  +** matrix is taken from the heap.  To reduce the load on the memory
          882  +** allocator, make this value as large as practical for the
          883  +** architecture in use.
          884  +*/
          885  +#ifndef SQLITE_SPELLFIX_STACKALLOC_SZ
          886  +# define SQLITE_SPELLFIX_STACKALLOC_SZ  (1024)
          887  +#endif
          888  +
   878    889   /* Compute the edit distance between two strings.
   879    890   **
   880    891   ** If an error occurs, return a negative number which is the error code.
   881    892   **
   882    893   ** If pnMatch is not NULL, then *pnMatch is set to the number of characters
   883    894   ** (not bytes) in z2 that matched the search pattern in *pFrom. If pFrom does
   884    895   ** not contain the pattern for a prefix-search, then this is always the number
................................................................................
   895    906   ){
   896    907     int k, n;
   897    908     int i1, b1;
   898    909     int i2, b2;
   899    910     EditDist3FromString f = *pFrom;
   900    911     EditDist3To *a2;
   901    912     unsigned int *m;
          913  +  unsigned int *pToFree;
   902    914     int szRow;
   903    915     EditDist3Cost *p;
   904    916     int res;
          917  +  sqlite3_uint64 nByte;
          918  +  unsigned int stackSpace[SQLITE_SPELLFIX_STACKALLOC_SZ/sizeof(unsigned int)];
   905    919   
   906    920     /* allocate the Wagner matrix and the aTo[] array for the TO string */
   907    921     n = (f.n+1)*(n2+1);
   908    922     n = (n+1)&~1;
   909         -  m = sqlite3_malloc( n*sizeof(m[0]) + sizeof(a2[0])*n2 );
   910         -  if( m==0 ) return -1;            /* Out of memory */
          923  +  nByte = n*sizeof(m[0]) + sizeof(a2[0])*n2;
          924  +  if( nByte<=sizeof(stackSpace) ){
          925  +    m = stackSpace;
          926  +    pToFree = 0;
          927  +  }else{
          928  +    m = pToFree = sqlite3_malloc( nByte );
          929  +    if( m==0 ) return -1;            /* Out of memory */
          930  +  }
   911    931     a2 = (EditDist3To*)&m[n];
   912    932     memset(a2, 0, sizeof(a2[0])*n2);
   913    933   
   914    934     /* Fill in the a1[] matrix for all characters of the TO string */
   915    935     for(i2=0; i2<n2; i2++){
   916    936       a2[i2].nByte = utf8Len((unsigned char)z2[i2], n2-i2);
   917    937       for(p=pLang->pCost; p; p=p->pNext){
................................................................................
  1025   1045         if( (z2[k] & 0xc0)==0x80 ) nExtra++;
  1026   1046       }
  1027   1047       *pnMatch = n - nExtra;
  1028   1048     }
  1029   1049   
  1030   1050   editDist3Abort:
  1031   1051     for(i2=0; i2<n2; i2++) sqlite3_free(a2[i2].apIns);
  1032         -  sqlite3_free(m);
         1052  +  sqlite3_free(pToFree);
  1033   1053     return res;
  1034   1054   }
  1035   1055   
  1036   1056   /*
  1037   1057   ** Get an appropriate EditDist3Lang object.
  1038   1058   */
  1039   1059   static const EditDist3Lang *editDist3FindLang(

Changes to main.mk.

   875    875   	rm -f rollback-test rollback-test.exe
   876    876   	rm -f showdb showdb.exe
   877    877   	rm -f showjournal showjournal.exe
   878    878   	rm -f showstat4 showstat4.exe
   879    879   	rm -f showwal showwal.exe
   880    880   	rm -f speedtest1 speedtest1.exe
   881    881   	rm -f wordcount wordcount.exe
          882  +	rm -f rbu rbu.exe
   882    883   	rm -f sqlite3.c sqlite3-*.c fts?amal.c tclsqlite3.c
   883    884   	rm -f sqlite3rc.h
   884    885   	rm -f shell.c sqlite3ext.h
   885    886   	rm -f sqlite3_analyzer sqlite3_analyzer.exe sqlite3_analyzer.c
   886    887   	rm -f sqlite-*-output.vsix
   887    888   	rm -f mptester mptester.exe
   888    889   	rm -f fuzzershell fuzzershell.exe
   889    890   	rm -f fuzzcheck fuzzcheck.exe
   890    891   	rm -f sqldiff sqldiff.exe
   891    892   	rm -f fts5.* fts5parse.*

Changes to src/alter.c.

   604    604       int r2 = sqlite3GetTempReg(pParse);
   605    605       int addr1;
   606    606       sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, r1, BTREE_FILE_FORMAT);
   607    607       sqlite3VdbeUsesBtree(v, iDb);
   608    608       sqlite3VdbeAddOp2(v, OP_Integer, minFormat, r2);
   609    609       addr1 = sqlite3VdbeAddOp3(v, OP_Ge, r2, 0, r1);
   610    610       sqlite3VdbeChangeP5(v, SQLITE_NOTNULL); VdbeCoverage(v);
   611         -    sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_FILE_FORMAT, r2);
          611  +    sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_FILE_FORMAT, minFormat);
   612    612       sqlite3VdbeJumpHere(v, addr1);
   613    613       sqlite3ReleaseTempReg(pParse, r1);
   614    614       sqlite3ReleaseTempReg(pParse, r2);
   615    615     }
   616    616   }
   617    617   
   618    618   /*

Changes to src/btree.c.

  4072   4072   /*
  4073   4073   ** Create a new cursor for the BTree whose root is on the page
  4074   4074   ** iTable. If a read-only cursor is requested, it is assumed that
  4075   4075   ** the caller already has at least a read-only transaction open
  4076   4076   ** on the database already. If a write-cursor is requested, then
  4077   4077   ** the caller is assumed to have an open write transaction.
  4078   4078   **
  4079         -** If wrFlag==0, then the cursor can only be used for reading.
  4080         -** If wrFlag==1, then the cursor can be used for reading or for
  4081         -** writing if other conditions for writing are also met.  These
  4082         -** are the conditions that must be met in order for writing to
  4083         -** be allowed:
         4079  +** If the BTREE_WRCSR bit of wrFlag is clear, then the cursor can only
         4080  +** be used for reading.  If the BTREE_WRCSR bit is set, then the cursor
         4081  +** can be used for reading or for writing if other conditions for writing
         4082  +** are also met.  These are the conditions that must be met in order
         4083  +** for writing to be allowed:
  4084   4084   **
  4085         -** 1:  The cursor must have been opened with wrFlag==1
         4085  +** 1:  The cursor must have been opened with wrFlag containing BTREE_WRCSR
  4086   4086   **
  4087   4087   ** 2:  Other database connections that share the same pager cache
  4088   4088   **     but which are not in the READ_UNCOMMITTED state may not have
  4089   4089   **     cursors open with wrFlag==0 on the same table.  Otherwise
  4090   4090   **     the changes made by this write cursor would be visible to
  4091   4091   **     the read cursors in the other database connection.
  4092   4092   **
  4093   4093   ** 3:  The database must be writable (not on read-only media)
  4094   4094   **
  4095   4095   ** 4:  There must be an active transaction.
         4096  +**
         4097  +** The BTREE_FORDELETE bit of wrFlag may optionally be set if BTREE_WRCSR
         4098  +** is set.  If FORDELETE is set, that is a hint to the implementation that
         4099  +** this cursor will only be used to seek to and delete entries of an index
         4100  +** as part of a larger DELETE statement.  The FORDELETE hint is not used by
         4101  +** this implementation.  But in a hypothetical alternative storage engine 
         4102  +** in which index entries are automatically deleted when corresponding table
         4103  +** rows are deleted, the FORDELETE flag is a hint that all SEEK and DELETE
         4104  +** operations on this cursor can be no-ops and all READ operations can 
         4105  +** return a null row (2-bytes: 0x01 0x00).
  4096   4106   **
  4097   4107   ** No checking is done to make sure that page iTable really is the
  4098   4108   ** root page of a b-tree.  If it is not, then the cursor acquired
  4099   4109   ** will not work correctly.
  4100   4110   **
  4101   4111   ** It is assumed that the sqlite3BtreeCursorZero() has been called
  4102   4112   ** on pCur to initialize the memory space prior to invoking this routine.
................................................................................
  8105   8115   end_insert:
  8106   8116     return rc;
  8107   8117   }
  8108   8118   
  8109   8119   /*
  8110   8120   ** Delete the entry that the cursor is pointing to. 
  8111   8121   **
  8112         -** If the second parameter is zero, then the cursor is left pointing at an
  8113         -** arbitrary location after the delete. If it is non-zero, then the cursor 
  8114         -** is left in a state such that the next call to BtreeNext() or BtreePrev()
  8115         -** moves it to the same row as it would if the call to BtreeDelete() had
  8116         -** been omitted.
         8122  +** If the BTREE_SAVEPOSITION bit of the flags parameter is zero, then
         8123  +** the cursor is left pointing at an arbitrary location after the delete.
         8124  +** But if that bit is set, then the cursor is left in a state such that
         8125  +** the next call to BtreeNext() or BtreePrev() moves it to the same row
         8126  +** as it would have been on if the call to BtreeDelete() had been omitted.
         8127  +**
         8128  +** The BTREE_AUXDELETE bit of flags indicates that is one of several deletes
         8129  +** associated with a single table entry and its indexes.  Only one of those
         8130  +** deletes is considered the "primary" delete.  The primary delete occurs
         8131  +** on a cursor that is not a BTREE_FORDELETE cursor.  All but one delete
         8132  +** operation on non-FORDELETE cursors is tagged with the AUXDELETE flag.
         8133  +** The BTREE_AUXDELETE bit is a hint that is not used by this implementation,
         8134  +** but which might be used by alternative storage engines.
  8117   8135   */
  8118         -int sqlite3BtreeDelete(BtCursor *pCur, int bPreserve){
         8136  +int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){
  8119   8137     Btree *p = pCur->pBtree;
  8120   8138     BtShared *pBt = p->pBt;              
  8121   8139     int rc;                              /* Return code */
  8122   8140     MemPage *pPage;                      /* Page to delete cell from */
  8123   8141     unsigned char *pCell;                /* Pointer to cell to delete */
  8124   8142     int iCellIdx;                        /* Index of cell to delete */
  8125   8143     int iCellDepth;                      /* Depth of node containing pCell */ 
  8126   8144     u16 szCell;                          /* Size of the cell being deleted */
  8127   8145     int bSkipnext = 0;                   /* Leaf cursor in SKIPNEXT state */
         8146  +  u8 bPreserve = flags & BTREE_SAVEPOSITION;  /* Keep cursor valid */
  8128   8147   
  8129   8148     assert( cursorOwnsBtShared(pCur) );
  8130   8149     assert( pBt->inTransaction==TRANS_WRITE );
  8131   8150     assert( (pBt->btsFlags & BTS_READ_ONLY)==0 );
  8132   8151     assert( pCur->curFlags & BTCF_WriteFlag );
  8133   8152     assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) );
  8134   8153     assert( !hasReadConflicts(p, pCur->pgnoRoot) );
  8135   8154     assert( pCur->aiIdx[pCur->iPage]<pCur->apPage[pCur->iPage]->nCell );
  8136   8155     assert( pCur->eState==CURSOR_VALID );
         8156  +  assert( (flags & ~(BTREE_SAVEPOSITION | BTREE_AUXDELETE))==0 );
  8137   8157   
  8138   8158     iCellDepth = pCur->iPage;
  8139   8159     iCellIdx = pCur->aiIdx[iCellDepth];
  8140   8160     pPage = pCur->apPage[iCellDepth];
  8141   8161     pCell = findCell(pPage, iCellIdx);
  8142   8162   
  8143   8163     /* If the page containing the entry to delete is not a leaf page, move
................................................................................
  8242   8262       }
  8243   8263       rc = balance(pCur);
  8244   8264     }
  8245   8265   
  8246   8266     if( rc==SQLITE_OK ){
  8247   8267       if( bSkipnext ){
  8248   8268         assert( bPreserve && (pCur->iPage==iCellDepth || CORRUPT_DB) );
  8249         -      assert( pPage==pCur->apPage[pCur->iPage] );
         8269  +      assert( pPage==pCur->apPage[pCur->iPage] || CORRUPT_DB );
  8250   8270         assert( (pPage->nCell>0 || CORRUPT_DB) && iCellIdx<=pPage->nCell );
  8251   8271         pCur->eState = CURSOR_SKIPNEXT;
  8252   8272         if( iCellIdx>=pPage->nCell ){
  8253   8273           pCur->skipNext = -1;
  8254   8274           pCur->aiIdx[iCellDepth] = pPage->nCell-1;
  8255   8275         }else{
  8256   8276           pCur->skipNext = 1;
................................................................................
  8828   8848     pCheck->mxErr--;
  8829   8849     pCheck->nErr++;
  8830   8850     va_start(ap, zFormat);
  8831   8851     if( pCheck->errMsg.nChar ){
  8832   8852       sqlite3StrAccumAppend(&pCheck->errMsg, "\n", 1);
  8833   8853     }
  8834   8854     if( pCheck->zPfx ){
  8835         -    sqlite3XPrintf(&pCheck->errMsg, 0, pCheck->zPfx, pCheck->v1, pCheck->v2);
         8855  +    sqlite3XPrintf(&pCheck->errMsg, pCheck->zPfx, pCheck->v1, pCheck->v2);
  8836   8856     }
  8837         -  sqlite3VXPrintf(&pCheck->errMsg, 1, zFormat, ap);
         8857  +  sqlite3VXPrintf(&pCheck->errMsg, zFormat, ap);
  8838   8858     va_end(ap);
  8839   8859     if( pCheck->errMsg.accError==STRACCUM_NOMEM ){
  8840   8860       pCheck->mallocFailed = 1;
  8841   8861     }
  8842   8862   }
  8843   8863   #endif /* SQLITE_OMIT_INTEGRITY_CHECK */
  8844   8864   
................................................................................
  9344   9364     sCheck.mallocFailed = 0;
  9345   9365     sCheck.zPfx = 0;
  9346   9366     sCheck.v1 = 0;
  9347   9367     sCheck.v2 = 0;
  9348   9368     sCheck.aPgRef = 0;
  9349   9369     sCheck.heap = 0;
  9350   9370     sqlite3StrAccumInit(&sCheck.errMsg, 0, zErr, sizeof(zErr), SQLITE_MAX_LENGTH);
         9371  +  sCheck.errMsg.printfFlags = SQLITE_PRINTF_INTERNAL;
  9351   9372     if( sCheck.nPage==0 ){
  9352   9373       goto integrity_ck_cleanup;
  9353   9374     }
  9354   9375   
  9355   9376     sCheck.aPgRef = sqlite3MallocZero((sCheck.nPage / 8)+ 1);
  9356   9377     if( !sCheck.aPgRef ){
  9357   9378       sCheck.mallocFailed = 1;

Changes to src/btree.h.

   195    195   #define BTREE_BULKLOAD 0x00000001  /* Used to full index in sorted order */
   196    196   #define BTREE_SEEK_EQ  0x00000002  /* EQ seeks only - no range seeks */
   197    197   
   198    198   /* 
   199    199   ** Flags passed as the third argument to sqlite3BtreeCursor().
   200    200   **
   201    201   ** For read-only cursors the wrFlag argument is always zero. For read-write
   202         -** cursors it may be set to either (BTREE_WRCSR|BTREE_FORDELETE) or
   203         -** (BTREE_WRCSR). If the BTREE_FORDELETE flag is set, then the cursor will
          202  +** cursors it may be set to either (BTREE_WRCSR|BTREE_FORDELETE) or just
          203  +** (BTREE_WRCSR). If the BTREE_FORDELETE bit is set, then the cursor will
   204    204   ** only be used by SQLite for the following:
   205    205   **
   206         -**   * to seek to and delete specific entries, and/or
          206  +**   * to seek to and then delete specific entries, and/or
   207    207   **
   208    208   **   * to read values that will be used to create keys that other
   209    209   **     BTREE_FORDELETE cursors will seek to and delete.
          210  +**
          211  +** The BTREE_FORDELETE flag is an optimization hint.  It is not used by
          212  +** by this, the native b-tree engine of SQLite, but it is available to
          213  +** alternative storage engines that might be substituted in place of this
          214  +** b-tree system.  For alternative storage engines in which a delete of
          215  +** the main table row automatically deletes corresponding index rows,
          216  +** the FORDELETE flag hint allows those alternative storage engines to
          217  +** skip a lot of work.  Namely:  FORDELETE cursors may treat all SEEK
          218  +** and DELETE operations as no-ops, and any READ operation against a
          219  +** FORDELETE cursor may return a null row: 0x01 0x00.
   210    220   */
   211    221   #define BTREE_WRCSR     0x00000004     /* read-write cursor */
   212    222   #define BTREE_FORDELETE 0x00000008     /* Cursor is for seek/delete only */
   213    223   
   214    224   int sqlite3BtreeCursor(
   215    225     Btree*,                              /* BTree containing table to open */
   216    226     int iTable,                          /* Index of root page */
................................................................................
   231    241     UnpackedRecord *pUnKey,
   232    242     i64 intKey,
   233    243     int bias,
   234    244     int *pRes
   235    245   );
   236    246   int sqlite3BtreeCursorHasMoved(BtCursor*);
   237    247   int sqlite3BtreeCursorRestore(BtCursor*, int*);
   238         -int sqlite3BtreeDelete(BtCursor*, int);
          248  +int sqlite3BtreeDelete(BtCursor*, u8 flags);
          249  +
          250  +/* Allowed flags for the 2nd argument to sqlite3BtreeDelete() */
          251  +#define BTREE_SAVEPOSITION 0x02  /* Leave cursor pointing at NEXT or PREV */
          252  +#define BTREE_AUXDELETE    0x04  /* not the primary delete operation */
          253  +
   239    254   int sqlite3BtreeInsert(BtCursor*, const void *pKey, i64 nKey,
   240    255                                     const void *pData, int nData,
   241    256                                     int nZero, int bias, int seekResult);
   242    257   int sqlite3BtreeFirst(BtCursor*, int *pRes);
   243    258   int sqlite3BtreeLast(BtCursor*, int *pRes);
   244    259   int sqlite3BtreeNext(BtCursor*, int *pRes);
   245    260   int sqlite3BtreeEof(BtCursor*);

Changes to src/build.c.

   979    979       reg2 = pParse->regRoot = ++pParse->nMem;
   980    980       reg3 = ++pParse->nMem;
   981    981       sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, reg3, BTREE_FILE_FORMAT);
   982    982       sqlite3VdbeUsesBtree(v, iDb);
   983    983       addr1 = sqlite3VdbeAddOp1(v, OP_If, reg3); VdbeCoverage(v);
   984    984       fileFormat = (db->flags & SQLITE_LegacyFileFmt)!=0 ?
   985    985                     1 : SQLITE_MAX_FILE_FORMAT;
   986         -    sqlite3VdbeAddOp2(v, OP_Integer, fileFormat, reg3);
   987         -    sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_FILE_FORMAT, reg3);
   988         -    sqlite3VdbeAddOp2(v, OP_Integer, ENC(db), reg3);
   989         -    sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_TEXT_ENCODING, reg3);
          986  +    sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_FILE_FORMAT, fileFormat);
          987  +    sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_TEXT_ENCODING, ENC(db));
   990    988       sqlite3VdbeJumpHere(v, addr1);
   991    989   
   992    990       /* This just creates a place-holder record in the sqlite_master table.
   993    991       ** The record created does not contain anything yet.  It will be replaced
   994    992       ** by the real entry in code generated at sqlite3EndTable().
   995    993       **
   996    994       ** The rowid for the new entry is left in register pParse->regRowid.
................................................................................
  1467   1465   ** This plan is not completely bullet-proof.  It is possible for
  1468   1466   ** the schema to change multiple times and for the cookie to be
  1469   1467   ** set back to prior value.  But schema changes are infrequent
  1470   1468   ** and the probability of hitting the same cookie value is only
  1471   1469   ** 1 chance in 2^32.  So we're safe enough.
  1472   1470   */
  1473   1471   void sqlite3ChangeCookie(Parse *pParse, int iDb){
  1474         -  int r1 = sqlite3GetTempReg(pParse);
  1475   1472     sqlite3 *db = pParse->db;
  1476   1473     Vdbe *v = pParse->pVdbe;
  1477   1474     assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
  1478         -  sqlite3VdbeAddOp2(v, OP_Integer, db->aDb[iDb].pSchema->schema_cookie+1, r1);
  1479         -  sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_SCHEMA_VERSION, r1);
  1480         -  sqlite3ReleaseTempReg(pParse, r1);
         1475  +  sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_SCHEMA_VERSION, 
         1476  +                    db->aDb[iDb].pSchema->schema_cookie+1);
  1481   1477   }
  1482   1478   
  1483   1479   /*
  1484   1480   ** Measure the number of characters needed to output the given
  1485   1481   ** identifier.  The number returned includes any quotes used
  1486   1482   ** but does not include the null terminator.
  1487   1483   **
................................................................................
  1704   1700   
  1705   1701     /* Locate the PRIMARY KEY index.  Or, if this table was originally
  1706   1702     ** an INTEGER PRIMARY KEY table, create a new PRIMARY KEY index. 
  1707   1703     */
  1708   1704     if( pTab->iPKey>=0 ){
  1709   1705       ExprList *pList;
  1710   1706       Token ipkToken;
  1711         -    ipkToken.z = pTab->aCol[pTab->iPKey].zName;
  1712         -    ipkToken.n = sqlite3Strlen30(ipkToken.z);
         1707  +    sqlite3TokenInit(&ipkToken, pTab->aCol[pTab->iPKey].zName);
  1713   1708       pList = sqlite3ExprListAppend(pParse, 0, 
  1714   1709                     sqlite3ExprAlloc(db, TK_ID, &ipkToken, 0));
  1715   1710       if( pList==0 ) return;
  1716   1711       pList->a[0].sortOrder = pParse->iPkSortOrder;
  1717   1712       assert( pParse->pNewTable==pTab );
  1718   1713       pPk = sqlite3CreateIndex(pParse, 0, 0, 0, pList, pTab->keyConf, 0, 0, 0, 0);
  1719   1714       if( pPk==0 ) return;
................................................................................
  3053   3048   
  3054   3049     /* If pList==0, it means this routine was called to make a primary
  3055   3050     ** key out of the last column added to the table under construction.
  3056   3051     ** So create a fake list to simulate this.
  3057   3052     */
  3058   3053     if( pList==0 ){
  3059   3054       Token prevCol;
  3060         -    prevCol.z = pTab->aCol[pTab->nCol-1].zName;
  3061         -    prevCol.n = sqlite3Strlen30(prevCol.z);
         3055  +    sqlite3TokenInit(&prevCol, pTab->aCol[pTab->nCol-1].zName);
  3062   3056       pList = sqlite3ExprListAppend(pParse, 0,
  3063   3057                 sqlite3ExprAlloc(db, TK_ID, &prevCol, 0));
  3064   3058       if( pList==0 ) goto exit_create_index;
  3065   3059       assert( pList->nExpr==1 );
  3066   3060       sqlite3ExprListSetSortOrder(pList, sortOrder);
  3067   3061     }else{
  3068   3062       sqlite3ExprListCheckLength(pParse, pList, "index");
................................................................................
  3890   3884         p->a[i].fg.jointype = p->a[i-1].fg.jointype;
  3891   3885       }
  3892   3886       p->a[0].fg.jointype = 0;
  3893   3887     }
  3894   3888   }
  3895   3889   
  3896   3890   /*
  3897         -** Begin a transaction
         3891  +** Generate VDBE code for a BEGIN statement.
  3898   3892   */
  3899   3893   void sqlite3BeginTransaction(Parse *pParse, int type){
  3900   3894     sqlite3 *db;
  3901   3895     Vdbe *v;
  3902   3896     int i;
  3903   3897   
  3904   3898     assert( pParse!=0 );
  3905   3899     db = pParse->db;
  3906   3900     assert( db!=0 );
  3907         -/*  if( db->aDb[0].pBt==0 ) return; */
  3908   3901     if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "BEGIN", 0, 0) ){
  3909   3902       return;
  3910   3903     }
  3911   3904     v = sqlite3GetVdbe(pParse);
  3912   3905     if( !v ) return;
  3913   3906     if( type!=TK_DEFERRED ){
  3914   3907       for(i=0; i<db->nDb; i++){
  3915   3908         sqlite3VdbeAddOp2(v, OP_Transaction, i, (type==TK_EXCLUSIVE)+1);
  3916   3909         sqlite3VdbeUsesBtree(v, i);
  3917   3910       }
  3918   3911     }
  3919         -  sqlite3VdbeAddOp2(v, OP_AutoCommit, 0, 0);
         3912  +  sqlite3VdbeAddOp0(v, OP_AutoCommit);
  3920   3913   }
  3921   3914   
  3922   3915   /*
  3923         -** Commit a transaction
         3916  +** Generate VDBE code for a COMMIT statement.
  3924   3917   */
  3925   3918   void sqlite3CommitTransaction(Parse *pParse){
  3926   3919     Vdbe *v;
  3927   3920   
  3928   3921     assert( pParse!=0 );
  3929   3922     assert( pParse->db!=0 );
  3930   3923     if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "COMMIT", 0, 0) ){
  3931   3924       return;
  3932   3925     }
  3933   3926     v = sqlite3GetVdbe(pParse);
  3934   3927     if( v ){
  3935         -    sqlite3VdbeAddOp2(v, OP_AutoCommit, 1, 0);
         3928  +    sqlite3VdbeAddOp1(v, OP_AutoCommit, 1);
  3936   3929     }
  3937   3930   }
  3938   3931   
  3939   3932   /*
  3940         -** Rollback a transaction
         3933  +** Generate VDBE code for a ROLLBACK statement.
  3941   3934   */
  3942   3935   void sqlite3RollbackTransaction(Parse *pParse){
  3943   3936     Vdbe *v;
  3944   3937   
  3945   3938     assert( pParse!=0 );
  3946   3939     assert( pParse->db!=0 );
  3947   3940     if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, "ROLLBACK", 0, 0) ){
................................................................................
  4130   4123     char *zErr;
  4131   4124     int j;
  4132   4125     StrAccum errMsg;
  4133   4126     Table *pTab = pIdx->pTable;
  4134   4127   
  4135   4128     sqlite3StrAccumInit(&errMsg, pParse->db, 0, 0, 200);
  4136   4129     if( pIdx->aColExpr ){
  4137         -    sqlite3XPrintf(&errMsg, 0, "index '%q'", pIdx->zName);
         4130  +    sqlite3XPrintf(&errMsg, "index '%q'", pIdx->zName);
  4138   4131     }else{
  4139   4132       for(j=0; j<pIdx->nKeyCol; j++){
  4140   4133         char *zCol;
  4141   4134         assert( pIdx->aiColumn[j]>=0 );
  4142   4135         zCol = pTab->aCol[pIdx->aiColumn[j]].zName;
  4143   4136         if( j ) sqlite3StrAccumAppend(&errMsg, ", ", 2);
  4144         -      sqlite3XPrintf(&errMsg, 0, "%s.%s", pTab->zName, zCol);
         4137  +      sqlite3XPrintf(&errMsg, "%s.%s", pTab->zName, zCol);
  4145   4138       }
  4146   4139     }
  4147   4140     zErr = sqlite3StrAccumFinish(&errMsg);
  4148   4141     sqlite3HaltConstraint(pParse, 
  4149   4142       IsPrimaryKeyIndex(pIdx) ? SQLITE_CONSTRAINT_PRIMARYKEY 
  4150   4143                               : SQLITE_CONSTRAINT_UNIQUE,
  4151   4144       onError, zErr, P4_DYNAMIC, P5_ConstraintUnique);

Changes to src/dbstat.c.

   145    145     char **pzErr
   146    146   ){
   147    147     StatTable *pTab = 0;
   148    148     int rc = SQLITE_OK;
   149    149     int iDb;
   150    150   
   151    151     if( argc>=4 ){
   152         -    iDb = sqlite3FindDbName(db, argv[3]);
          152  +    Token nm;
          153  +    sqlite3TokenInit(&nm, (char*)argv[3]);
          154  +    iDb = sqlite3FindDb(db, &nm);
   153    155       if( iDb<0 ){
   154    156         *pzErr = sqlite3_mprintf("no such database: %s", argv[3]);
   155    157         return SQLITE_ERROR;
   156    158       }
   157    159     }else{
   158    160       iDb = 0;
   159    161     }

Changes to src/delete.c.

   475    475       /* Unless this is a view, open cursors for the table we are 
   476    476       ** deleting from and all its indices. If this is a view, then the
   477    477       ** only effect this statement has is to fire the INSTEAD OF 
   478    478       ** triggers.
   479    479       */
   480    480       if( !isView ){
   481    481         int iAddrOnce = 0;
   482         -      u8 p5 = (eOnePass==ONEPASS_OFF ? 0 : OPFLAG_FORDELETE);
   483    482         if( eOnePass==ONEPASS_MULTI ){
   484    483           iAddrOnce = sqlite3CodeOnce(pParse); VdbeCoverage(v);
   485    484         }
   486    485         testcase( IsVirtual(pTab) );
   487         -      sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, p5, iTabCur, 
   488         -                                 aToOpen, &iDataCur, &iIdxCur);
          486  +      sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, OPFLAG_FORDELETE,
          487  +                                 iTabCur, aToOpen, &iDataCur, &iIdxCur);
   489    488         assert( pPk || IsVirtual(pTab) || iDataCur==iTabCur );
   490    489         assert( pPk || IsVirtual(pTab) || iIdxCur==iDataCur+1 );
   491    490         if( eOnePass==ONEPASS_MULTI ) sqlite3VdbeJumpHere(v, iAddrOnce);
   492    491       }
   493    492     
   494    493       /* Set up a loop over the rowids/primary-keys that were found in the
   495    494       ** where-clause loop above.
................................................................................
   714    713       sqlite3FkCheck(pParse, pTab, iOld, 0, 0, 0);
   715    714     }
   716    715   
   717    716     /* Delete the index and table entries. Skip this step if pTab is really
   718    717     ** a view (in which case the only effect of the DELETE statement is to
   719    718     ** fire the INSTEAD OF triggers).  */ 
   720    719     if( pTab->pSelect==0 ){
          720  +    u8 p5 = 0;
   721    721       sqlite3GenerateRowIndexDelete(pParse, pTab, iDataCur, iIdxCur,0,iIdxNoSeek);
   722    722       sqlite3VdbeAddOp2(v, OP_Delete, iDataCur, (count?OPFLAG_NCHANGE:0));
   723    723       if( count ){
   724    724         sqlite3VdbeChangeP4(v, -1, pTab->zName, P4_TRANSIENT);
   725    725       }
          726  +    if( eMode!=ONEPASS_OFF ){
          727  +      sqlite3VdbeChangeP5(v, OPFLAG_AUXDELETE);
          728  +    }
   726    729       if( iIdxNoSeek>=0 ){
   727    730         sqlite3VdbeAddOp1(v, OP_Delete, iIdxNoSeek);
   728    731       }
   729         -    sqlite3VdbeChangeP5(v, eMode==ONEPASS_MULTI);
          732  +    if( eMode==ONEPASS_MULTI ) p5 |= OPFLAG_SAVEPOSITION;
          733  +    sqlite3VdbeChangeP5(v, p5);
   730    734     }
   731    735   
   732    736     /* Do any ON CASCADE, SET NULL or SET DEFAULT operations required to
   733    737     ** handle rows (possibly in other tables) that refer via a foreign key
   734    738     ** to the row just deleted. */ 
   735    739     sqlite3FkActions(pParse, pTab, 0, iOld, 0, 0);
   736    740   

Changes to src/expr.c.

    81     81       }
    82     82     }
    83     83     return pExpr;
    84     84   }
    85     85   Expr *sqlite3ExprAddCollateString(Parse *pParse, Expr *pExpr, const char *zC){
    86     86     Token s;
    87     87     assert( zC!=0 );
    88         -  s.z = zC;
    89         -  s.n = sqlite3Strlen30(s.z);
           88  +  sqlite3TokenInit(&s, (char*)zC);
    90     89     return sqlite3ExprAddCollateToken(pParse, pExpr, &s, 0);
    91     90   }
    92     91   
    93     92   /*
    94     93   ** Skip over any TK_COLLATE operators and any unlikely()
    95     94   ** or likelihood() function at the root of an expression.
    96     95   */

Changes to src/fkey.c.

  1188   1188         int iFromCol;               /* Idx of column in child table */
  1189   1189         Expr *pEq;                  /* tFromCol = OLD.tToCol */
  1190   1190   
  1191   1191         iFromCol = aiCol ? aiCol[i] : pFKey->aCol[0].iFrom;
  1192   1192         assert( iFromCol>=0 );
  1193   1193         assert( pIdx!=0 || (pTab->iPKey>=0 && pTab->iPKey<pTab->nCol) );
  1194   1194         assert( pIdx==0 || pIdx->aiColumn[i]>=0 );
  1195         -      tToCol.z = pTab->aCol[pIdx ? pIdx->aiColumn[i] : pTab->iPKey].zName;
  1196         -      tFromCol.z = pFKey->pFrom->aCol[iFromCol].zName;
  1197         -
  1198         -      tToCol.n = sqlite3Strlen30(tToCol.z);
  1199         -      tFromCol.n = sqlite3Strlen30(tFromCol.z);
         1195  +      sqlite3TokenInit(&tToCol,
         1196  +                   pTab->aCol[pIdx ? pIdx->aiColumn[i] : pTab->iPKey].zName);
         1197  +      sqlite3TokenInit(&tFromCol, pFKey->pFrom->aCol[iFromCol].zName);
  1200   1198   
  1201   1199         /* Create the expression "OLD.zToCol = zFromCol". It is important
  1202   1200         ** that the "OLD.zToCol" term is on the LHS of the = operator, so
  1203   1201         ** that the affinity and collation sequence associated with the
  1204   1202         ** parent table are used for the comparison. */
  1205   1203         pEq = sqlite3PExpr(pParse, TK_EQ,
  1206   1204             sqlite3PExpr(pParse, TK_DOT, 

Changes to src/func.c.

   235    235     sqlite3 *db = sqlite3_context_db_handle(context);
   236    236   
   237    237     if( argc>=1 && (zFormat = (const char*)sqlite3_value_text(argv[0]))!=0 ){
   238    238       x.nArg = argc-1;
   239    239       x.nUsed = 0;
   240    240       x.apArg = argv+1;
   241    241       sqlite3StrAccumInit(&str, db, 0, 0, db->aLimit[SQLITE_LIMIT_LENGTH]);
   242         -    sqlite3XPrintf(&str, SQLITE_PRINTF_SQLFUNC, zFormat, &x);
          242  +    str.printfFlags = SQLITE_PRINTF_SQLFUNC;
          243  +    sqlite3XPrintf(&str, zFormat, &x);
   243    244       n = str.nChar;
   244    245       sqlite3_result_text(context, sqlite3StrAccumFinish(&str), n,
   245    246                           SQLITE_DYNAMIC);
   246    247     }
   247    248   }
   248    249   
   249    250   /*
................................................................................
   735    736             return 0;
   736    737           }
   737    738           continue;
   738    739         }
   739    740       }
   740    741       c2 = Utf8Read(zString);
   741    742       if( c==c2 ) continue;
   742         -    if( noCase && sqlite3Tolower(c)==sqlite3Tolower(c2) ){
          743  +    if( noCase && c<0x80 && c2<0x80 && sqlite3Tolower(c)==sqlite3Tolower(c2) ){
   743    744         continue;
   744    745       }
   745    746       if( c==matchOne && zPattern!=zEscaped && c2!=0 ) continue;
   746    747       return 0;
   747    748     }
   748    749     return *zString==0;
   749    750   }

Changes to src/insert.c.

  1643   1643   ** If pTab is a virtual table, then this routine is a no-op and the
  1644   1644   ** *piDataCur and *piIdxCur values are left uninitialized.
  1645   1645   */
  1646   1646   int sqlite3OpenTableAndIndices(
  1647   1647     Parse *pParse,   /* Parsing context */
  1648   1648     Table *pTab,     /* Table to be opened */
  1649   1649     int op,          /* OP_OpenRead or OP_OpenWrite */
  1650         -  u8 p5,           /* P5 value for OP_Open* instructions */
         1650  +  u8 p5,           /* P5 value for OP_Open* opcodes (except on WITHOUT ROWID) */
  1651   1651     int iBase,       /* Use this for the table cursor, if there is one */
  1652   1652     u8 *aToOpen,     /* If not NULL: boolean for each table and index */
  1653   1653     int *piDataCur,  /* Write the database source cursor number here */
  1654   1654     int *piIdxCur    /* Write the first index cursor number here */
  1655   1655   ){
  1656   1656     int i;
  1657   1657     int iDb;
................................................................................
  1678   1678     }else{
  1679   1679       sqlite3TableLock(pParse, iDb, pTab->tnum, op==OP_OpenWrite, pTab->zName);
  1680   1680     }
  1681   1681     if( piIdxCur ) *piIdxCur = iBase;
  1682   1682     for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){
  1683   1683       int iIdxCur = iBase++;
  1684   1684       assert( pIdx->pSchema==pTab->pSchema );
  1685         -    if( IsPrimaryKeyIndex(pIdx) && !HasRowid(pTab) && piDataCur ){
  1686         -      *piDataCur = iIdxCur;
  1687         -    }
  1688   1685       if( aToOpen==0 || aToOpen[i+1] ){
  1689   1686         sqlite3VdbeAddOp3(v, op, iIdxCur, pIdx->tnum, iDb);
  1690   1687         sqlite3VdbeSetP4KeyInfo(pParse, pIdx);
  1691         -      sqlite3VdbeChangeP5(v, p5);
  1692   1688         VdbeComment((v, "%s", pIdx->zName));
         1689  +    }
         1690  +    if( IsPrimaryKeyIndex(pIdx) && !HasRowid(pTab) ){
         1691  +      if( piDataCur ) *piDataCur = iIdxCur;
         1692  +    }else{
         1693  +      sqlite3VdbeChangeP5(v, p5);
  1693   1694       }
  1694   1695     }
  1695   1696     if( iBase>pParse->nTab ) pParse->nTab = iBase;
  1696   1697     return i;
  1697   1698   }
  1698   1699   
  1699   1700   

Changes to src/mem5.c.

   318    318   #endif
   319    319   
   320    320     mem5.aCtrl[iBlock] = CTRL_FREE | iLogsize;
   321    321     while( ALWAYS(iLogsize<LOGMAX) ){
   322    322       int iBuddy;
   323    323       if( (iBlock>>iLogsize) & 1 ){
   324    324         iBuddy = iBlock - size;
          325  +      assert( iBuddy>=0 );
   325    326       }else{
   326    327         iBuddy = iBlock + size;
          328  +      if( iBuddy>=mem5.nBlock ) break;
   327    329       }
   328         -    assert( iBuddy>=0 );
   329         -    if( (iBuddy+(1<<iLogsize))>mem5.nBlock ) break;
   330    330       if( mem5.aCtrl[iBuddy]!=(CTRL_FREE | iLogsize) ) break;
   331    331       memsys5Unlink(iBuddy, iLogsize);
   332    332       iLogsize++;
   333    333       if( iBuddy<iBlock ){
   334    334         mem5.aCtrl[iBuddy] = CTRL_FREE | iLogsize;
   335    335         mem5.aCtrl[iBlock] = 0;
   336    336         iBlock = iBuddy;

Changes to src/os_unix.c.

   146    146   #endif
   147    147   
   148    148   /*
   149    149   ** Maximum supported path-length.
   150    150   */
   151    151   #define MAX_PATHNAME 512
   152    152   
          153  +/*
          154  +** Maximum supported symbolic links
          155  +*/
          156  +#define SQLITE_MAX_SYMLINKS 100
          157  +
   153    158   /* Always cast the getpid() return type for compatibility with
   154    159   ** kernel modules in VxWorks. */
   155    160   #define osGetpid(X) (pid_t)getpid()
   156    161   
   157    162   /*
   158    163   ** Only set the lastErrno if the error code is a real error and not 
   159    164   ** a normal expected return code of SQLITE_BUSY or SQLITE_OK
................................................................................
   759    764   #if defined(HAVE_READLINK)
   760    765     { "readlink",     (sqlite3_syscall_ptr)readlink,        0 },
   761    766   #else
   762    767     { "readlink",     (sqlite3_syscall_ptr)0,               0 },
   763    768   #endif
   764    769   #define osReadlink ((ssize_t(*)(const char*,char*,size_t))aSyscall[26].pCurrent)
   765    770   
          771  +#if defined(HAVE_LSTAT)
          772  +  { "lstat",         (sqlite3_syscall_ptr)lstat,          0 },
          773  +#else
          774  +  { "lstat",         (sqlite3_syscall_ptr)0,              0 },
          775  +#endif
          776  +#define osLstat      ((int(*)(const char*,struct stat*))aSyscall[27].pCurrent)
   766    777   
   767    778   }; /* End of the overrideable system calls */
   768    779   
   769    780   
   770    781   /*
   771    782   ** On some systems, calls to fchown() will trigger a message in a security
   772    783   ** log if they come from non-root processes.  So avoid calling fchown() if
................................................................................
  7130   7141       *pResOut = (0==osStat(zPath, &buf) && buf.st_size>0);
  7131   7142     }else{
  7132   7143       *pResOut = osAccess(zPath, W_OK|R_OK)==0;
  7133   7144     }
  7134   7145     return SQLITE_OK;
  7135   7146   }
  7136   7147   
         7148  +/*
         7149  +**
         7150  +*/
         7151  +static int mkFullPathname(
         7152  +  const char *zPath,              /* Input path */
         7153  +  char *zOut,                     /* Output buffer */
         7154  +  int nOut                        /* Allocated size of buffer zOut */
         7155  +){
         7156  +  int nPath = sqlite3Strlen30(zPath);
         7157  +  int iOff = 0;
         7158  +  if( zPath[0]!='/' ){
         7159  +    if( osGetcwd(zOut, nOut-2)==0 ){
         7160  +      return unixLogError(SQLITE_CANTOPEN_BKPT, "getcwd", zPath);
         7161  +    }
         7162  +    iOff = sqlite3Strlen30(zOut);
         7163  +    zOut[iOff++] = '/';
         7164  +  }
         7165  +  if( (iOff+nPath+1)>nOut ){
         7166  +    /* SQLite assumes that xFullPathname() nul-terminates the output buffer
         7167  +    ** even if it returns an error.  */
         7168  +    zOut[iOff] = '\0';
         7169  +    return SQLITE_CANTOPEN_BKPT;
         7170  +  }
         7171  +  sqlite3_snprintf(nOut-iOff, &zOut[iOff], "%s", zPath);
         7172  +  return SQLITE_OK;
         7173  +}
  7137   7174   
  7138   7175   /*
  7139   7176   ** Turn a relative pathname into a full pathname. The relative path
  7140   7177   ** is stored as a nul-terminated string in the buffer pointed to by
  7141   7178   ** zPath. 
  7142   7179   **
  7143   7180   ** zOut points to a buffer of at least sqlite3_vfs.mxPathname bytes 
................................................................................
  7146   7183   */
  7147   7184   static int unixFullPathname(
  7148   7185     sqlite3_vfs *pVfs,            /* Pointer to vfs object */
  7149   7186     const char *zPath,            /* Possibly relative input path */
  7150   7187     int nOut,                     /* Size of output buffer in bytes */
  7151   7188     char *zOut                    /* Output buffer */
  7152   7189   ){
         7190  +#if !defined(HAVE_READLINK) || !defined(HAVE_LSTAT)
         7191  +  return mkFullPathname(zPath, zOut, nOut);
         7192  +#else
         7193  +  int rc = SQLITE_OK;
  7153   7194     int nByte;
         7195  +  int nLink = 1;                /* Number of symbolic links followed so far */
         7196  +  const char *zIn = zPath;      /* Input path for each iteration of loop */
         7197  +  char *zDel = 0;
         7198  +
         7199  +  assert( pVfs->mxPathname==MAX_PATHNAME );
         7200  +  UNUSED_PARAMETER(pVfs);
  7154   7201   
  7155   7202     /* It's odd to simulate an io-error here, but really this is just
  7156   7203     ** using the io-error infrastructure to test that SQLite handles this
  7157   7204     ** function failing. This function could fail if, for example, the
  7158   7205     ** current working directory has been unlinked.
  7159   7206     */
  7160   7207     SimulateIOError( return SQLITE_ERROR );
  7161   7208   
  7162         -  assert( pVfs->mxPathname==MAX_PATHNAME );
  7163         -  UNUSED_PARAMETER(pVfs);
  7164         -
  7165         -#if defined(HAVE_READLINK)
  7166         -  /* Attempt to resolve the path as if it were a symbolic link. If it is
  7167         -  ** a symbolic link, the resolved path is stored in buffer zOut[]. Or, if
  7168         -  ** the identified file is not a symbolic link or does not exist, then
  7169         -  ** zPath is copied directly into zOut. Either way, nByte is left set to
  7170         -  ** the size of the string copied into zOut[] in bytes.  */
  7171         -  nByte = osReadlink(zPath, zOut, nOut-1);
  7172         -  if( nByte<0 ){
  7173         -    if( errno!=EINVAL && errno!=ENOENT ){
  7174         -      return unixLogError(SQLITE_CANTOPEN_BKPT, "readlink", zPath);
  7175         -    }
  7176         -    sqlite3_snprintf(nOut, zOut, "%s", zPath);
  7177         -    nByte = sqlite3Strlen30(zOut);
  7178         -  }else{
  7179         -    zOut[nByte] = '\0';
  7180         -  }
  7181         -#endif
  7182         -
  7183         -  /* If buffer zOut[] now contains an absolute path there is nothing more
  7184         -  ** to do. If it contains a relative path, do the following:
  7185         -  **
  7186         -  **   * move the relative path string so that it is at the end of th
  7187         -  **     zOut[] buffer.
  7188         -  **   * Call getcwd() to read the path of the current working directory 
  7189         -  **     into the start of the zOut[] buffer.
  7190         -  **   * Append a '/' character to the cwd string and move the 
  7191         -  **     relative path back within the buffer so that it immediately 
  7192         -  **     follows the '/'.
  7193         -  **
  7194         -  ** This code is written so that if the combination of the CWD and relative
  7195         -  ** path are larger than the allocated size of zOut[] the CWD is silently
  7196         -  ** truncated to make it fit. This is Ok, as SQLite refuses to open any
  7197         -  ** file for which this function returns a full path larger than (nOut-8)
  7198         -  ** bytes in size.  */
  7199         -  testcase( nByte==nOut-5 );
  7200         -  testcase( nByte==nOut-4 );
  7201         -  if( zOut[0]!='/' && nByte<nOut-4 ){
  7202         -    int nCwd;
  7203         -    int nRem = nOut-nByte-1;
  7204         -    memmove(&zOut[nRem], zOut, nByte+1);
  7205         -    zOut[nRem-1] = '\0';
  7206         -    if( osGetcwd(zOut, nRem-1)==0 ){
  7207         -      return unixLogError(SQLITE_CANTOPEN_BKPT, "getcwd", zPath);
  7208         -    }
  7209         -    nCwd = sqlite3Strlen30(zOut);
  7210         -    assert( nCwd<=nRem-1 );
  7211         -    zOut[nCwd] = '/';
  7212         -    memmove(&zOut[nCwd+1], &zOut[nRem], nByte+1);
  7213         -  }
  7214         -
  7215         -  return SQLITE_OK;
         7209  +  do {
         7210  +
         7211  +    /* Call stat() on path zIn. Set bLink to true if the path is a symbolic
         7212  +    ** link, or false otherwise.  */
         7213  +    int bLink = 0;
         7214  +    struct stat buf;
         7215  +    if( osLstat(zIn, &buf)!=0 ){
         7216  +      if( errno!=ENOENT ){
         7217  +        rc = unixLogError(SQLITE_CANTOPEN_BKPT, "lstat", zIn);
         7218  +      }
         7219  +    }else{
         7220  +      bLink = S_ISLNK(buf.st_mode);
         7221  +    }
         7222  +
         7223  +    if( bLink ){
         7224  +      if( zDel==0 ){
         7225  +        zDel = sqlite3_malloc(nOut);
         7226  +        if( zDel==0 ) rc = SQLITE_NOMEM;
         7227  +      }else if( ++nLink>SQLITE_MAX_SYMLINKS ){
         7228  +        rc = SQLITE_CANTOPEN_BKPT;
         7229  +      }
         7230  +
         7231  +      if( rc==SQLITE_OK ){
         7232  +        nByte = osReadlink(zIn, zDel, nOut-1);
         7233  +        if( nByte<0 ){
         7234  +          rc = unixLogError(SQLITE_CANTOPEN_BKPT, "readlink", zIn);
         7235  +        }else{
         7236  +          if( zDel[0]!='/' ){
         7237  +            int n;
         7238  +            for(n = sqlite3Strlen30(zIn); n>0 && zIn[n-1]!='/'; n--);
         7239  +            if( nByte+n+1>nOut ){
         7240  +              rc = SQLITE_CANTOPEN_BKPT;
         7241  +            }else{
         7242  +              memmove(&zDel[n], zDel, nByte+1);
         7243  +              memcpy(zDel, zIn, n);
         7244  +              nByte += n;
         7245  +            }
         7246  +          }
         7247  +          zDel[nByte] = '\0';
         7248  +        }
         7249  +      }
         7250  +
         7251  +      zIn = zDel;
         7252  +    }
         7253  +
         7254  +    assert( rc!=SQLITE_OK || zIn!=zOut || zIn[0]=='/' );
         7255  +    if( rc==SQLITE_OK && zIn!=zOut ){
         7256  +      rc = mkFullPathname(zIn, zOut, nOut);
         7257  +    }
         7258  +    if( bLink==0 ) break;
         7259  +    zIn = zOut;
         7260  +  }while( rc==SQLITE_OK );
         7261  +
         7262  +  sqlite3_free(zDel);
         7263  +  return rc;
         7264  +#endif   /* HAVE_READLINK && HAVE_LSTAT */
  7216   7265   }
  7217   7266   
  7218   7267   
  7219   7268   #ifndef SQLITE_OMIT_LOAD_EXTENSION
  7220   7269   /*
  7221   7270   ** Interfaces for opening a shared library, finding entry points
  7222   7271   ** within the shared library, and closing the shared library.
................................................................................
  7390   7439       *piNow = 1000*(sqlite3_int64)sqlite3_current_time + unixEpoch;
  7391   7440     }
  7392   7441   #endif
  7393   7442     UNUSED_PARAMETER(NotUsed);
  7394   7443     return rc;
  7395   7444   }
  7396   7445   
  7397         -#if 0 /* Not used */
         7446  +#ifndef SQLITE_OMIT_DEPRECATED
  7398   7447   /*
  7399   7448   ** Find the current time (in Universal Coordinated Time).  Write the
  7400   7449   ** current time and date as a Julian Day number into *prNow and
  7401   7450   ** return 0.  Return 1 if the time and date cannot be found.
  7402   7451   */
  7403   7452   static int unixCurrentTime(sqlite3_vfs *NotUsed, double *prNow){
  7404   7453     sqlite3_int64 i = 0;
................................................................................
  7408   7457     *prNow = i/86400000.0;
  7409   7458     return rc;
  7410   7459   }
  7411   7460   #else
  7412   7461   # define unixCurrentTime 0
  7413   7462   #endif
  7414   7463   
  7415         -#if 0  /* Not used */
         7464  +#ifndef SQLITE_OMIT_DEPRECATED
  7416   7465   /*
  7417   7466   ** We added the xGetLastError() method with the intention of providing
  7418   7467   ** better low-level error messages when operating-system problems come up
  7419   7468   ** during SQLite operation.  But so far, none of that has been implemented
  7420   7469   ** in the core.  So this routine is never called.  For now, it is merely
  7421   7470   ** a place-holder.
  7422   7471   */
................................................................................
  8759   8808       UNIXVFS("unix-proxy",    proxyIoFinder ),
  8760   8809   #endif
  8761   8810     };
  8762   8811     unsigned int i;          /* Loop counter */
  8763   8812   
  8764   8813     /* Double-check that the aSyscall[] array has been constructed
  8765   8814     ** correctly.  See ticket [bb3a86e890c8e96ab] */
  8766         -  assert( ArraySize(aSyscall)==27 );
         8815  +  assert( ArraySize(aSyscall)==28 );
  8767   8816   
  8768   8817     /* Register all VFSes defined in the aVfs[] array */
  8769   8818     for(i=0; i<(sizeof(aVfs)/sizeof(sqlite3_vfs)); i++){
  8770   8819       sqlite3_vfs_register(&aVfs[i], i==0);
  8771   8820     }
  8772   8821     return SQLITE_OK; 
  8773   8822   }

Changes to src/os_win.c.

    72     72   #  define NTDDI_WIN8                        0x06020000
    73     73   #endif
    74     74   
    75     75   #ifndef NTDDI_WINBLUE
    76     76   #  define NTDDI_WINBLUE                     0x06030000
    77     77   #endif
    78     78   
           79  +#ifndef NTDDI_WINTHRESHOLD
           80  +#  define NTDDI_WINTHRESHOLD                0x06040000
           81  +#endif
           82  +
    79     83   /*
    80     84   ** Check to see if the GetVersionEx[AW] functions are deprecated on the
    81     85   ** target system.  GetVersionEx was first deprecated in Win8.1.
    82     86   */
    83     87   #ifndef SQLITE_WIN32_GETVERSIONEX
    84     88   #  if defined(NTDDI_VERSION) && NTDDI_VERSION >= NTDDI_WINBLUE
    85     89   #    define SQLITE_WIN32_GETVERSIONEX   0   /* GetVersionEx() is deprecated */
    86     90   #  else
    87     91   #    define SQLITE_WIN32_GETVERSIONEX   1   /* GetVersionEx() is current */
    88     92   #  endif
    89     93   #endif
    90     94   
           95  +/*
           96  +** Check to see if the CreateFileMappingA function is supported on the
           97  +** target system.  It is unavailable when using "mincore.lib" on Win10.
           98  +** When compiling for Windows 10, always assume "mincore.lib" is in use.
           99  +*/
          100  +#ifndef SQLITE_WIN32_CREATEFILEMAPPINGA
          101  +#  if defined(NTDDI_VERSION) && NTDDI_VERSION >= NTDDI_WINTHRESHOLD
          102  +#    define SQLITE_WIN32_CREATEFILEMAPPINGA   0
          103  +#  else
          104  +#    define SQLITE_WIN32_CREATEFILEMAPPINGA   1
          105  +#  endif
          106  +#endif
          107  +
    91    108   /*
    92    109   ** This constant should already be defined (in the "WinDef.h" SDK file).
    93    110   */
    94    111   #ifndef MAX_PATH
    95    112   #  define MAX_PATH                      (260)
    96    113   #endif
    97    114   
................................................................................
   490    507   #else
   491    508     { "CreateFileW",             (SYSCALL)0,                       0 },
   492    509   #endif
   493    510   
   494    511   #define osCreateFileW ((HANDLE(WINAPI*)(LPCWSTR,DWORD,DWORD, \
   495    512           LPSECURITY_ATTRIBUTES,DWORD,DWORD,HANDLE))aSyscall[5].pCurrent)
   496    513   
   497         -#if (!SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_ANSI) && \
   498         -        (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0))
          514  +#if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_ANSI) && \
          515  +        (!defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0) && \
          516  +        SQLITE_WIN32_CREATEFILEMAPPINGA
   499    517     { "CreateFileMappingA",      (SYSCALL)CreateFileMappingA,      0 },
   500    518   #else
   501    519     { "CreateFileMappingA",      (SYSCALL)0,                       0 },
   502    520   #endif
   503    521   
   504    522   #define osCreateFileMappingA ((HANDLE(WINAPI*)(HANDLE,LPSECURITY_ATTRIBUTES, \
   505    523           DWORD,DWORD,DWORD,LPCSTR))aSyscall[6].pCurrent)
................................................................................
   721    739     { "GetTickCount",            (SYSCALL)GetTickCount,            0 },
   722    740   #else
   723    741     { "GetTickCount",            (SYSCALL)0,                       0 },
   724    742   #endif
   725    743   
   726    744   #define osGetTickCount ((DWORD(WINAPI*)(VOID))aSyscall[33].pCurrent)
   727    745   
   728         -#if defined(SQLITE_WIN32_HAS_ANSI) && defined(SQLITE_WIN32_GETVERSIONEX) && \
   729         -        SQLITE_WIN32_GETVERSIONEX
          746  +#if defined(SQLITE_WIN32_HAS_ANSI) && SQLITE_WIN32_GETVERSIONEX
   730    747     { "GetVersionExA",           (SYSCALL)GetVersionExA,           0 },
   731    748   #else
   732    749     { "GetVersionExA",           (SYSCALL)0,                       0 },
   733    750   #endif
   734    751   
   735    752   #define osGetVersionExA ((BOOL(WINAPI*)( \
   736    753           LPOSVERSIONINFOA))aSyscall[34].pCurrent)
   737    754   
   738    755   #if !SQLITE_OS_WINRT && defined(SQLITE_WIN32_HAS_WIDE) && \
   739         -        defined(SQLITE_WIN32_GETVERSIONEX) && SQLITE_WIN32_GETVERSIONEX
          756  +        SQLITE_WIN32_GETVERSIONEX
   740    757     { "GetVersionExW",           (SYSCALL)GetVersionExW,           0 },
   741    758   #else
   742    759     { "GetVersionExW",           (SYSCALL)0,                       0 },
   743    760   #endif
   744    761   
   745    762   #define osGetVersionExW ((BOOL(WINAPI*)( \
   746    763           LPOSVERSIONINFOW))aSyscall[35].pCurrent)
................................................................................
  1343   1360   ** the LockFileEx() API.  But we can still statically link against that
  1344   1361   ** API as long as we don't call it when running Win95/98/ME.  A call to
  1345   1362   ** this routine is used to determine if the host is Win95/98/ME or
  1346   1363   ** WinNT/2K/XP so that we will know whether or not we can safely call
  1347   1364   ** the LockFileEx() API.
  1348   1365   */
  1349   1366   
  1350         -#if !defined(SQLITE_WIN32_GETVERSIONEX) || !SQLITE_WIN32_GETVERSIONEX
         1367  +#if !SQLITE_WIN32_GETVERSIONEX
  1351   1368   # define osIsNT()  (1)
  1352   1369   #elif SQLITE_OS_WINCE || SQLITE_OS_WINRT || !defined(SQLITE_WIN32_HAS_ANSI)
  1353   1370   # define osIsNT()  (1)
  1354   1371   #elif !defined(SQLITE_WIN32_HAS_WIDE)
  1355   1372   # define osIsNT()  (0)
  1356   1373   #else
  1357   1374   # define osIsNT()  ((sqlite3_os_type==2) || sqlite3_win32_is_nt())
................................................................................
  1364   1381   int sqlite3_win32_is_nt(void){
  1365   1382   #if SQLITE_OS_WINRT
  1366   1383     /*
  1367   1384     ** NOTE: The WinRT sub-platform is always assumed to be based on the NT
  1368   1385     **       kernel.
  1369   1386     */
  1370   1387     return 1;
  1371         -#elif defined(SQLITE_WIN32_GETVERSIONEX) && SQLITE_WIN32_GETVERSIONEX
         1388  +#elif SQLITE_WIN32_GETVERSIONEX
  1372   1389     if( osInterlockedCompareExchange(&sqlite3_os_type, 0, 0)==0 ){
  1373   1390   #if defined(SQLITE_WIN32_HAS_ANSI)
  1374   1391       OSVERSIONINFOA sInfo;
  1375   1392       sInfo.dwOSVersionInfoSize = sizeof(sInfo);
  1376   1393       osGetVersionExA(&sInfo);
  1377   1394       osInterlockedCompareExchange(&sqlite3_os_type,
  1378   1395           (sInfo.dwPlatformId == VER_PLATFORM_WIN32_NT) ? 2 : 1, 0);
................................................................................
  3957   3974         hMap = osCreateFileMappingFromApp(pShmNode->hFile.h,
  3958   3975             NULL, PAGE_READWRITE, nByte, NULL
  3959   3976         );
  3960   3977   #elif defined(SQLITE_WIN32_HAS_WIDE)
  3961   3978         hMap = osCreateFileMappingW(pShmNode->hFile.h,
  3962   3979             NULL, PAGE_READWRITE, 0, nByte, NULL
  3963   3980         );
  3964         -#elif defined(SQLITE_WIN32_HAS_ANSI)
         3981  +#elif defined(SQLITE_WIN32_HAS_ANSI) && SQLITE_WIN32_CREATEFILEMAPPINGA
  3965   3982         hMap = osCreateFileMappingA(pShmNode->hFile.h,
  3966   3983             NULL, PAGE_READWRITE, 0, nByte, NULL
  3967   3984         );
  3968   3985   #endif
  3969   3986         OSTRACE(("SHM-MAP-CREATE pid=%lu, region=%d, size=%d, rc=%s\n",
  3970   3987                  osGetCurrentProcessId(), pShmNode->nRegion, nByte,
  3971   3988                  hMap ? "ok" : "failed"));
................................................................................
  4113   4130   #endif
  4114   4131   #if SQLITE_OS_WINRT
  4115   4132       pFd->hMap = osCreateFileMappingFromApp(pFd->h, NULL, protect, nMap, NULL);
  4116   4133   #elif defined(SQLITE_WIN32_HAS_WIDE)
  4117   4134       pFd->hMap = osCreateFileMappingW(pFd->h, NULL, protect,
  4118   4135                                   (DWORD)((nMap>>32) & 0xffffffff),
  4119   4136                                   (DWORD)(nMap & 0xffffffff), NULL);
  4120         -#elif defined(SQLITE_WIN32_HAS_ANSI)
         4137  +#elif defined(SQLITE_WIN32_HAS_ANSI) && SQLITE_WIN32_CREATEFILEMAPPINGA
  4121   4138       pFd->hMap = osCreateFileMappingA(pFd->h, NULL, protect,
  4122   4139                                   (DWORD)((nMap>>32) & 0xffffffff),
  4123   4140                                   (DWORD)(nMap & 0xffffffff), NULL);
  4124   4141   #endif
  4125   4142       if( pFd->hMap==NULL ){
  4126   4143         pFd->lastErrno = osGetLastError();
  4127   4144         rc = winLogError(SQLITE_IOERR_MMAP, pFd->lastErrno,

Changes to src/pager.c.

   423    423   /*
   424    424   ** The maximum allowed sector size. 64KiB. If the xSectorsize() method 
   425    425   ** returns a value larger than this, then MAX_SECTOR_SIZE is used instead.
   426    426   ** This could conceivably cause corruption following a power failure on
   427    427   ** such a system. This is currently an undocumented limit.
   428    428   */
   429    429   #define MAX_SECTOR_SIZE 0x10000
          430  +
          431  +/*
          432  +** If the option SQLITE_EXTRA_DURABLE option is set at compile-time, then
          433  +** SQLite will do extra fsync() operations when synchronous==FULL to help
          434  +** ensure that transactions are durable across a power failure.  Most
          435  +** applications are happy as long as transactions are consistent across
          436  +** a power failure, and are perfectly willing to lose the last transaction
          437  +** in exchange for the extra performance of avoiding directory syncs.
          438  +** And so the default SQLITE_EXTRA_DURABLE setting is off.
          439  +*/
          440  +#ifndef SQLITE_EXTRA_DURABLE
          441  +# define SQLITE_EXTRA_DURABLE 0
          442  +#endif
          443  +
   430    444   
   431    445   /*
   432    446   ** An instance of the following structure is allocated for each active
   433    447   ** savepoint and statement transaction in the system. All such structures
   434    448   ** are stored in the Pager.aSavepoint[] array, which is allocated and
   435    449   ** resized using sqlite3Realloc().
   436    450   **
................................................................................
  1979   1993         int bDelete = (!pPager->tempFile && sqlite3JournalExists(pPager->jfd));
  1980   1994         assert( pPager->journalMode==PAGER_JOURNALMODE_DELETE 
  1981   1995              || pPager->journalMode==PAGER_JOURNALMODE_MEMORY 
  1982   1996              || pPager->journalMode==PAGER_JOURNALMODE_WAL 
  1983   1997         );
  1984   1998         sqlite3OsClose(pPager->jfd);
  1985   1999         if( bDelete ){
  1986         -        rc = sqlite3OsDelete(pPager->pVfs, pPager->zJournal, 0);
         2000  +        rc = sqlite3OsDelete(pPager->pVfs, pPager->zJournal, 
         2001  +                 pPager->fullSync && SQLITE_EXTRA_DURABLE);
  1987   2002         }
  1988   2003       }
  1989   2004     }
  1990   2005   
  1991   2006   #ifdef SQLITE_CHECK_PAGES
  1992   2007     sqlite3PcacheIterateDirty(pPager->pPCache, pager_set_pagehash);
  1993   2008     if( pPager->dbSize==0 && sqlite3PcacheRefCount(pPager->pPCache)>0 ){

Changes to src/parse.y.

  1006   1006   expr(A) ::= expr(X) NOT NULL(E). {spanUnaryPostfix(&A,pParse,TK_NOTNULL,&X,&E);}
  1007   1007   
  1008   1008   %include {
  1009   1009     /* A routine to convert a binary TK_IS or TK_ISNOT expression into a
  1010   1010     ** unary TK_ISNULL or TK_NOTNULL expression. */
  1011   1011     static void binaryToUnaryIfNull(Parse *pParse, Expr *pY, Expr *pA, int op){
  1012   1012       sqlite3 *db = pParse->db;
  1013         -    if( pY && pA && pY->op==TK_NULL ){
         1013  +    if( pA && pY && pY->op==TK_NULL ){
  1014   1014         pA->op = (u8)op;
  1015   1015         sqlite3ExprDelete(db, pA->pRight);
  1016   1016         pA->pRight = 0;
  1017   1017       }
  1018   1018     }
  1019   1019   }
  1020   1020   

Changes to src/pragma.c.

   440    440         if( ONLY_IF_REALLOC_STRESS(aOp==0) ) break;
   441    441         aOp[0].p1 = iDb;
   442    442         aOp[1].p1 = iDb;
   443    443         aOp[6].p1 = SQLITE_DEFAULT_CACHE_SIZE;
   444    444       }else{
   445    445         int size = sqlite3AbsInt32(sqlite3Atoi(zRight));
   446    446         sqlite3BeginWriteOperation(pParse, 0, iDb);
   447         -      sqlite3VdbeAddOp2(v, OP_Integer, size, 1);
   448         -      sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_DEFAULT_CACHE_SIZE, 1);
          447  +      sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_DEFAULT_CACHE_SIZE, size);
   449    448         assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
   450    449         pDb->pSchema->cache_size = size;
   451    450         sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size);
   452    451       }
   453    452       break;
   454    453     }
   455    454   #endif /* !SQLITE_OMIT_PAGER_PRAGMAS && !SQLITE_OMIT_DEPRECATED */
................................................................................
   693    692           */
   694    693           static const int iLn = VDBE_OFFSET_LINENO(2);
   695    694           static const VdbeOpList setMeta6[] = {
   696    695             { OP_Transaction,    0,         1,                 0},    /* 0 */
   697    696             { OP_ReadCookie,     0,         1,         BTREE_LARGEST_ROOT_PAGE},
   698    697             { OP_If,             1,         0,                 0},    /* 2 */
   699    698             { OP_Halt,           SQLITE_OK, OE_Abort,          0},    /* 3 */
   700         -          { OP_Integer,        0,         1,                 0},    /* 4 */
   701         -          { OP_SetCookie,      0,         BTREE_INCR_VACUUM, 1},    /* 5 */
          699  +          { OP_SetCookie,      0,         BTREE_INCR_VACUUM, 0},    /* 4 */
   702    700           };
   703    701           VdbeOp *aOp;
   704    702           int iAddr = sqlite3VdbeCurrentAddr(v);
   705    703           sqlite3VdbeVerifyNoMallocRequired(v, ArraySize(setMeta6));
   706    704           aOp = sqlite3VdbeAddOpList(v, ArraySize(setMeta6), setMeta6, iLn);
   707    705           if( ONLY_IF_REALLOC_STRESS(aOp==0) ) break;
   708    706           aOp[0].p1 = iDb;
   709    707           aOp[1].p1 = iDb;
   710    708           aOp[2].p2 = iAddr+4;
   711         -        aOp[4].p1 = eAuto - 1;
   712         -        aOp[5].p1 = iDb;
          709  +        aOp[4].p1 = iDb;
          710  +        aOp[4].p3 = eAuto - 1;
   713    711           sqlite3VdbeUsesBtree(v, iDb);
   714    712         }
   715    713       }
   716    714       break;
   717    715     }
   718    716   #endif
   719    717   
................................................................................
  1741   1739     case PragTyp_HEADER_VALUE: {
  1742   1740       int iCookie = pPragma->iArg;  /* Which cookie to read or write */
  1743   1741       sqlite3VdbeUsesBtree(v, iDb);
  1744   1742       if( zRight && (pPragma->mPragFlag & PragFlag_ReadOnly)==0 ){
  1745   1743         /* Write the specified cookie value */
  1746   1744         static const VdbeOpList setCookie[] = {
  1747   1745           { OP_Transaction,    0,  1,  0},    /* 0 */
  1748         -        { OP_Integer,        0,  1,  0},    /* 1 */
  1749         -        { OP_SetCookie,      0,  0,  1},    /* 2 */
         1746  +        { OP_SetCookie,      0,  0,  0},    /* 1 */
  1750   1747         };
  1751   1748         VdbeOp *aOp;
  1752   1749         sqlite3VdbeVerifyNoMallocRequired(v, ArraySize(setCookie));
  1753   1750         aOp = sqlite3VdbeAddOpList(v, ArraySize(setCookie), setCookie, 0);
  1754   1751         if( ONLY_IF_REALLOC_STRESS(aOp==0) ) break;
  1755   1752         aOp[0].p1 = iDb;
  1756         -      aOp[1].p1 = sqlite3Atoi(zRight);
  1757         -      aOp[2].p1 = iDb;
  1758         -      aOp[2].p2 = iCookie;
         1753  +      aOp[1].p1 = iDb;
         1754  +      aOp[1].p2 = iCookie;
         1755  +      aOp[1].p3 = sqlite3Atoi(zRight);
  1759   1756       }else{
  1760   1757         /* Read the specified cookie value */
  1761   1758         static const VdbeOpList readCookie[] = {
  1762   1759           { OP_Transaction,     0,  0,  0},    /* 0 */
  1763   1760           { OP_ReadCookie,      0,  1,  0},    /* 1 */
  1764   1761           { OP_ResultRow,       1,  1,  0}
  1765   1762         };

Changes to src/prepare.c.

   524    524     pParse = sqlite3StackAllocZero(db, sizeof(*pParse));
   525    525     if( pParse==0 ){
   526    526       rc = SQLITE_NOMEM;
   527    527       goto end_prepare;
   528    528     }
   529    529     pParse->pReprepare = pReprepare;
   530    530     assert( ppStmt && *ppStmt==0 );
   531         -  assert( !db->mallocFailed );
          531  +  /* assert( !db->mallocFailed ); // not true with SQLITE_USE_ALLOCA */
   532    532     assert( sqlite3_mutex_held(db->mutex) );
   533    533   
   534    534     /* Check to verify that it is possible to get a read lock on all
   535    535     ** database schemas.  The inability to get a read lock indicates that
   536    536     ** some other database connection is holding a write-lock, which in
   537    537     ** turn means that the other connection has made uncommitted changes
   538    538     ** to the schema.
................................................................................
   581    581         sqlite3ErrorWithMsg(db, SQLITE_TOOBIG, "statement too long");
   582    582         rc = sqlite3ApiExit(db, SQLITE_TOOBIG);
   583    583         goto end_prepare;
   584    584       }
   585    585       zSqlCopy = sqlite3DbStrNDup(db, zSql, nBytes);
   586    586       if( zSqlCopy ){
   587    587         sqlite3RunParser(pParse, zSqlCopy, &zErrMsg);
   588         -      sqlite3DbFree(db, zSqlCopy);
   589    588         pParse->zTail = &zSql[pParse->zTail-zSqlCopy];
          589  +      sqlite3DbFree(db, zSqlCopy);
   590    590       }else{
   591    591         pParse->zTail = &zSql[nBytes];
   592    592       }
   593    593     }else{
   594    594       sqlite3RunParser(pParse, zSql, &zErrMsg);
   595    595     }
   596    596     assert( 0==pParse->nQueryLoop );

Changes to src/printf.c.

   167    167   #define etBUFSIZE SQLITE_PRINT_BUF_SIZE  /* Size of the output buffer */
   168    168   
   169    169   /*
   170    170   ** Render a string given by "fmt" into the StrAccum object.
   171    171   */
   172    172   void sqlite3VXPrintf(
   173    173     StrAccum *pAccum,          /* Accumulate results here */
   174         -  u32 bFlags,                /* SQLITE_PRINTF_* flags */
   175    174     const char *fmt,           /* Format string */
   176    175     va_list ap                 /* arguments */
   177    176   ){
   178    177     int c;                     /* Next character in the format string */
   179    178     char *bufpt;               /* Pointer to the conversion buffer */
   180    179     int precision;             /* Precision of the current field */
   181    180     int length;                /* Length of the field */
................................................................................
   207    206     etByte flag_dp;            /* True if decimal point should be shown */
   208    207     etByte flag_rtz;           /* True if trailing zeros should be removed */
   209    208   #endif
   210    209     PrintfArguments *pArgList = 0; /* Arguments for SQLITE_PRINTF_SQLFUNC */
   211    210     char buf[etBUFSIZE];       /* Conversion buffer */
   212    211   
   213    212     bufpt = 0;
   214         -  if( bFlags ){
   215         -    if( (bArgList = (bFlags & SQLITE_PRINTF_SQLFUNC))!=0 ){
          213  +  if( pAccum->printfFlags ){
          214  +    if( (bArgList = (pAccum->printfFlags & SQLITE_PRINTF_SQLFUNC))!=0 ){
   216    215         pArgList = va_arg(ap, PrintfArguments*);
   217    216       }
   218         -    useIntern = bFlags & SQLITE_PRINTF_INTERNAL;
          217  +    useIntern = pAccum->printfFlags & SQLITE_PRINTF_INTERNAL;
   219    218     }else{
   220    219       bArgList = useIntern = 0;
   221    220     }
   222    221     for(; (c=(*fmt))!=0; ++fmt){
   223    222       if( c!='%' ){
   224    223         bufpt = (char *)fmt;
   225    224   #if HAVE_STRCHRNUL
................................................................................
   762    761       return 0;
   763    762     }
   764    763     if( p->mxAlloc==0 ){
   765    764       N = p->nAlloc - p->nChar - 1;
   766    765       setStrAccumError(p, STRACCUM_TOOBIG);
   767    766       return N;
   768    767     }else{
   769         -    char *zOld = p->bMalloced ? p->zText : 0;
          768  +    char *zOld = isMalloced(p) ? p->zText : 0;
   770    769       i64 szNew = p->nChar;
   771         -    assert( (p->zText==0 || p->zText==p->zBase)==(p->bMalloced==0) );
          770  +    assert( (p->zText==0 || p->zText==p->zBase)==!isMalloced(p) );
   772    771       szNew += N + 1;
   773    772       if( szNew+p->nChar<=p->mxAlloc ){
   774    773         /* Force exponential buffer size growth as long as it does not overflow,
   775    774         ** to avoid having to call this routine too often */
   776    775         szNew += p->nChar;
   777    776       }
   778    777       if( szNew > p->mxAlloc ){
................................................................................
   785    784       if( p->db ){
   786    785         zNew = sqlite3DbRealloc(p->db, zOld, p->nAlloc);
   787    786       }else{
   788    787         zNew = sqlite3_realloc64(zOld, p->nAlloc);
   789    788       }
   790    789       if( zNew ){
   791    790         assert( p->zText!=0 || p->nChar==0 );
   792         -      if( !p->bMalloced && p->nChar>0 ) memcpy(zNew, p->zText, p->nChar);
          791  +      if( !isMalloced(p) && p->nChar>0 ) memcpy(zNew, p->zText, p->nChar);
   793    792         p->zText = zNew;
   794    793         p->nAlloc = sqlite3DbMallocSize(p->db, zNew);
   795         -      p->bMalloced = 1;
          794  +      p->printfFlags |= SQLITE_PRINTF_MALLOCED;
   796    795       }else{
   797    796         sqlite3StrAccumReset(p);
   798    797         setStrAccumError(p, STRACCUM_NOMEM);
   799    798         return 0;
   800    799       }
   801    800     }
   802    801     return N;
................................................................................
   806    805   ** Append N copies of character c to the given string buffer.
   807    806   */
   808    807   void sqlite3AppendChar(StrAccum *p, int N, char c){
   809    808     testcase( p->nChar + (i64)N > 0x7fffffff );
   810    809     if( p->nChar+(i64)N >= p->nAlloc && (N = sqlite3StrAccumEnlarge(p, N))<=0 ){
   811    810       return;
   812    811     }
   813         -  assert( (p->zText==p->zBase)==(p->bMalloced==0) );
          812  +  assert( (p->zText==p->zBase)==!isMalloced(p) );
   814    813     while( (N--)>0 ) p->zText[p->nChar++] = c;
   815    814   }
   816    815   
   817    816   /*
   818    817   ** The StrAccum "p" is not large enough to accept N new bytes of z[].
   819    818   ** So enlarge if first, then do the append.
   820    819   **
................................................................................
   824    823   */
   825    824   static void SQLITE_NOINLINE enlargeAndAppend(StrAccum *p, const char *z, int N){
   826    825     N = sqlite3StrAccumEnlarge(p, N);
   827    826     if( N>0 ){
   828    827       memcpy(&p->zText[p->nChar], z, N);
   829    828       p->nChar += N;
   830    829     }
   831         -  assert( (p->zText==0 || p->zText==p->zBase)==(p->bMalloced==0) );
          830  +  assert( (p->zText==0 || p->zText==p->zBase)==!isMalloced(p) );
   832    831   }
   833    832   
   834    833   /*
   835    834   ** Append N bytes of text from z to the StrAccum object.  Increase the
   836    835   ** size of the memory allocation for StrAccum if necessary.
   837    836   */
   838    837   void sqlite3StrAccumAppend(StrAccum *p, const char *z, int N){
................................................................................
   860    859   /*
   861    860   ** Finish off a string by making sure it is zero-terminated.
   862    861   ** Return a pointer to the resulting string.  Return a NULL
   863    862   ** pointer if any kind of error was encountered.
   864    863   */
   865    864   char *sqlite3StrAccumFinish(StrAccum *p){
   866    865     if( p->zText ){
   867         -    assert( (p->zText==p->zBase)==(p->bMalloced==0) );
          866  +    assert( (p->zText==p->zBase)==!isMalloced(p) );
   868    867       p->zText[p->nChar] = 0;
   869         -    if( p->mxAlloc>0 && p->bMalloced==0 ){
          868  +    if( p->mxAlloc>0 && !isMalloced(p) ){
   870    869         p->zText = sqlite3DbMallocRaw(p->db, p->nChar+1 );
   871    870         if( p->zText ){
   872    871           memcpy(p->zText, p->zBase, p->nChar+1);
   873         -        p->bMalloced = 1;
          872  +        p->printfFlags |= SQLITE_PRINTF_MALLOCED;
   874    873         }else{
   875    874           setStrAccumError(p, STRACCUM_NOMEM);
   876    875         }
   877    876       }
   878    877     }
   879    878     return p->zText;
   880    879   }
   881    880   
   882    881   /*
   883    882   ** Reset an StrAccum string.  Reclaim all malloced memory.
   884    883   */
   885    884   void sqlite3StrAccumReset(StrAccum *p){
   886         -  assert( (p->zText==0 || p->zText==p->zBase)==(p->bMalloced==0) );
   887         -  if( p->bMalloced ){
          885  +  assert( (p->zText==0 || p->zText==p->zBase)==!isMalloced(p) );
          886  +  if( isMalloced(p) ){
   888    887       sqlite3DbFree(p->db, p->zText);
   889         -    p->bMalloced = 0;
          888  +    p->printfFlags &= ~SQLITE_PRINTF_MALLOCED;
   890    889     }
   891    890     p->zText = 0;
   892    891   }
   893    892   
   894    893   /*
   895    894   ** Initialize a string accumulator.
   896    895   **
................................................................................
   908    907   void sqlite3StrAccumInit(StrAccum *p, sqlite3 *db, char *zBase, int n, int mx){
   909    908     p->zText = p->zBase = zBase;
   910    909     p->db = db;
   911    910     p->nChar = 0;
   912    911     p->nAlloc = n;
   913    912     p->mxAlloc = mx;
   914    913     p->accError = 0;
   915         -  p->bMalloced = 0;
          914  +  p->printfFlags = 0;
   916    915   }
   917    916   
   918    917   /*
   919    918   ** Print into memory obtained from sqliteMalloc().  Use the internal
   920    919   ** %-conversion extensions.
   921    920   */
   922    921   char *sqlite3VMPrintf(sqlite3 *db, const char *zFormat, va_list ap){
   923    922     char *z;
   924    923     char zBase[SQLITE_PRINT_BUF_SIZE];
   925    924     StrAccum acc;
   926    925     assert( db!=0 );
   927    926     sqlite3StrAccumInit(&acc, db, zBase, sizeof(zBase),
   928    927                         db->aLimit[SQLITE_LIMIT_LENGTH]);
   929         -  sqlite3VXPrintf(&acc, SQLITE_PRINTF_INTERNAL, zFormat, ap);
          928  +  acc.printfFlags = SQLITE_PRINTF_INTERNAL;
          929  +  sqlite3VXPrintf(&acc, zFormat, ap);
   930    930     z = sqlite3StrAccumFinish(&acc);
   931    931     if( acc.accError==STRACCUM_NOMEM ){
   932    932       db->mallocFailed = 1;
   933    933     }
   934    934     return z;
   935    935   }
   936    936   
................................................................................
   962    962       return 0;
   963    963     }
   964    964   #endif
   965    965   #ifndef SQLITE_OMIT_AUTOINIT
   966    966     if( sqlite3_initialize() ) return 0;
   967    967   #endif
   968    968     sqlite3StrAccumInit(&acc, 0, zBase, sizeof(zBase), SQLITE_MAX_LENGTH);
   969         -  sqlite3VXPrintf(&acc, 0, zFormat, ap);
          969  +  sqlite3VXPrintf(&acc, zFormat, ap);
   970    970     z = sqlite3StrAccumFinish(&acc);
   971    971     return z;
   972    972   }
   973    973   
   974    974   /*
   975    975   ** Print into memory obtained from sqlite3_malloc()().  Omit the internal
   976    976   ** %-conversion extensions.
................................................................................
  1007   1007     if( zBuf==0 || zFormat==0 ) {
  1008   1008       (void)SQLITE_MISUSE_BKPT;
  1009   1009       if( zBuf ) zBuf[0] = 0;
  1010   1010       return zBuf;
  1011   1011     }
  1012   1012   #endif
  1013   1013     sqlite3StrAccumInit(&acc, 0, zBuf, n, 0);
  1014         -  sqlite3VXPrintf(&acc, 0, zFormat, ap);
         1014  +  sqlite3VXPrintf(&acc, zFormat, ap);
  1015   1015     return sqlite3StrAccumFinish(&acc);
  1016   1016   }
  1017   1017   char *sqlite3_snprintf(int n, char *zBuf, const char *zFormat, ...){
  1018   1018     char *z;
  1019   1019     va_list ap;
  1020   1020     va_start(ap,zFormat);
  1021   1021     z = sqlite3_vsnprintf(n, zBuf, zFormat, ap);
................................................................................
  1038   1038   ** memory mutex is held do not use these mechanisms.
  1039   1039   */
  1040   1040   static void renderLogMsg(int iErrCode, const char *zFormat, va_list ap){
  1041   1041     StrAccum acc;                          /* String accumulator */
  1042   1042     char zMsg[SQLITE_PRINT_BUF_SIZE*3];    /* Complete log message */
  1043   1043   
  1044   1044     sqlite3StrAccumInit(&acc, 0, zMsg, sizeof(zMsg), 0);
  1045         -  sqlite3VXPrintf(&acc, 0, zFormat, ap);
         1045  +  sqlite3VXPrintf(&acc, zFormat, ap);
  1046   1046     sqlite3GlobalConfig.xLog(sqlite3GlobalConfig.pLogArg, iErrCode,
  1047   1047                              sqlite3StrAccumFinish(&acc));
  1048   1048   }
  1049   1049   
  1050   1050   /*
  1051   1051   ** Format and write a message to the log if logging is enabled.
  1052   1052   */
................................................................................
  1067   1067   */
  1068   1068   void sqlite3DebugPrintf(const char *zFormat, ...){
  1069   1069     va_list ap;
  1070   1070     StrAccum acc;
  1071   1071     char zBuf[500];
  1072   1072     sqlite3StrAccumInit(&acc, 0, zBuf, sizeof(zBuf), 0);
  1073   1073     va_start(ap,zFormat);
  1074         -  sqlite3VXPrintf(&acc, 0, zFormat, ap);
         1074  +  sqlite3VXPrintf(&acc, zFormat, ap);
  1075   1075     va_end(ap);
  1076   1076     sqlite3StrAccumFinish(&acc);
  1077   1077     fprintf(stdout,"%s", zBuf);
  1078   1078     fflush(stdout);
  1079   1079   }
  1080   1080   #endif
  1081   1081   
  1082   1082   
  1083   1083   /*
  1084   1084   ** variable-argument wrapper around sqlite3VXPrintf().  The bFlags argument
  1085   1085   ** can contain the bit SQLITE_PRINTF_INTERNAL enable internal formats.
  1086   1086   */
  1087         -void sqlite3XPrintf(StrAccum *p, u32 bFlags, const char *zFormat, ...){
         1087  +void sqlite3XPrintf(StrAccum *p, const char *zFormat, ...){
  1088   1088     va_list ap;
  1089   1089     va_start(ap,zFormat);
  1090         -  sqlite3VXPrintf(p, bFlags, zFormat, ap);
         1090  +  sqlite3VXPrintf(p, zFormat, ap);
  1091   1091     va_end(ap);
  1092   1092   }

Changes to src/select.c.

  1856   1856       }
  1857   1857       if( p->pOffset ){
  1858   1858         p->iOffset = iOffset = ++pParse->nMem;
  1859   1859         pParse->nMem++;   /* Allocate an extra register for limit+offset */
  1860   1860         sqlite3ExprCode(pParse, p->pOffset, iOffset);
  1861   1861         sqlite3VdbeAddOp1(v, OP_MustBeInt, iOffset); VdbeCoverage(v);
  1862   1862         VdbeComment((v, "OFFSET counter"));
  1863         -      sqlite3VdbeAddOp3(v, OP_SetIfNotPos, iOffset, iOffset, 0);
  1864         -      sqlite3VdbeAddOp3(v, OP_Add, iLimit, iOffset, iOffset+1);
         1863  +      sqlite3VdbeAddOp3(v, OP_OffsetLimit, iLimit, iOffset+1, iOffset);
  1865   1864         VdbeComment((v, "LIMIT+OFFSET"));
  1866         -      sqlite3VdbeAddOp3(v, OP_SetIfNotPos, iLimit, iOffset+1, -1);
  1867   1865       }
  1868   1866     }
  1869   1867   }
  1870   1868   
  1871   1869   #ifndef SQLITE_OMIT_COMPOUND_SELECT
  1872   1870   /*
  1873   1871   ** Return the appropriate collating sequence for the iCol-th column of
................................................................................
  2276   2274         p->pPrior = 0;
  2277   2275         p->iLimit = pPrior->iLimit;
  2278   2276         p->iOffset = pPrior->iOffset;
  2279   2277         if( p->iLimit ){
  2280   2278           addr = sqlite3VdbeAddOp1(v, OP_IfNot, p->iLimit); VdbeCoverage(v);
  2281   2279           VdbeComment((v, "Jump ahead if LIMIT reached"));
  2282   2280           if( p->iOffset ){
  2283         -          sqlite3VdbeAddOp3(v, OP_SetIfNotPos, p->iOffset, p->iOffset, 0);
  2284         -          sqlite3VdbeAddOp3(v, OP_Add, p->iLimit, p->iOffset, p->iOffset+1);
  2285         -          sqlite3VdbeAddOp3(v, OP_SetIfNotPos, p->iLimit, p->iOffset+1, -1);
         2281  +          sqlite3VdbeAddOp3(v, OP_OffsetLimit,
         2282  +                            p->iLimit, p->iOffset+1, p->iOffset);
  2286   2283           }
  2287   2284         }
  2288   2285         explainSetInteger(iSub2, pParse->iNextSelectId);
  2289   2286         rc = sqlite3Select(pParse, p, &dest);
  2290   2287         testcase( rc!=SQLITE_OK );
  2291   2288         pDelete = p->pPrior;
  2292   2289         p->pPrior = pPrior;
................................................................................
  2869   2866     /* Compute the comparison permutation and keyinfo that is used with
  2870   2867     ** the permutation used to determine if the next
  2871   2868     ** row of results comes from selectA or selectB.  Also add explicit
  2872   2869     ** collations to the ORDER BY clause terms so that when the subqueries
  2873   2870     ** to the right and the left are evaluated, they use the correct
  2874   2871     ** collation.
  2875   2872     */
  2876         -  aPermute = sqlite3DbMallocRaw(db, sizeof(int)*nOrderBy);
         2873  +  aPermute = sqlite3DbMallocRaw(db, sizeof(int)*(nOrderBy + 1));
  2877   2874     if( aPermute ){
  2878   2875       struct ExprList_item *pItem;
  2879         -    for(i=0, pItem=pOrderBy->a; i<nOrderBy; i++, pItem++){
         2876  +    aPermute[0] = nOrderBy;
         2877  +    for(i=1, pItem=pOrderBy->a; i<=nOrderBy; i++, pItem++){
  2880   2878         assert( pItem->u.x.iOrderByCol>0 );
  2881   2879         assert( pItem->u.x.iOrderByCol<=p->pEList->nExpr );
  2882   2880         aPermute[i] = pItem->u.x.iOrderByCol - 1;
  2883   2881       }
  2884   2882       pKeyMerge = multiSelectOrderByKeyInfo(pParse, p, 1);
  2885   2883     }else{
  2886   2884       pKeyMerge = 0;
................................................................................
  4434   4432                   zColname = sqlite3MPrintf(db, "%s.%s", zTabName, zName);
  4435   4433                   zToFree = zColname;
  4436   4434                 }
  4437   4435               }else{
  4438   4436                 pExpr = pRight;
  4439   4437               }
  4440   4438               pNew = sqlite3ExprListAppend(pParse, pNew, pExpr);
  4441         -            sColname.z = zColname;
  4442         -            sColname.n = sqlite3Strlen30(zColname);
         4439  +            sqlite3TokenInit(&sColname, zColname);
  4443   4440               sqlite3ExprListSetName(pParse, pNew, &sColname, 0);
  4444   4441               if( pNew && (p->selFlags & SF_NestedFrom)!=0 ){
  4445   4442                 struct ExprList_item *pX = &pNew->a[pNew->nExpr-1];
  4446   4443                 if( pSub ){
  4447   4444                   pX->zSpan = sqlite3DbStrDup(db, pSub->pEList->a[j].zSpan);
  4448   4445                   testcase( pX->zSpan==0 );
  4449   4446                 }else{

Changes to src/sqlite.h.in.

  5694   5694   ** sqlite3_libversion_number() returns a value greater than or equal to
  5695   5695   ** 3009000.
  5696   5696   */
  5697   5697   struct sqlite3_index_info {
  5698   5698     /* Inputs */
  5699   5699     int nConstraint;           /* Number of entries in aConstraint */
  5700   5700     struct sqlite3_index_constraint {
  5701         -     int iColumn;              /* Column on left-hand side of constraint */
         5701  +     int iColumn;              /* Column constrained.  -1 for ROWID */
  5702   5702        unsigned char op;         /* Constraint operator */
  5703   5703        unsigned char usable;     /* True if this constraint is usable */
  5704   5704        int iTermOffset;          /* Used internally - xBestIndex should ignore */
  5705   5705     } *aConstraint;            /* Table of WHERE clause constraints */
  5706   5706     int nOrderBy;              /* Number of terms in the ORDER BY clause */
  5707   5707     struct sqlite3_index_orderby {
  5708   5708        int iColumn;              /* Column number */

Changes to src/sqlite3.rc.

    35     35   #pragma code_page(1252)
    36     36   #endif /* defined(_WIN32) */
    37     37   
    38     38   /*
    39     39    * Icon
    40     40    */
    41     41   
           42  +#if !defined(RC_VERONLY)
    42     43   #define IDI_SQLITE 101
    43     44   
    44     45   IDI_SQLITE ICON "..\\art\\sqlite370.ico"
           46  +#endif /* !defined(RC_VERONLY) */
    45     47   
    46     48   /*
    47     49    * Version
    48     50    */
    49     51   
    50     52   VS_VERSION_INFO VERSIONINFO
    51     53     FILEVERSION SQLITE_RESOURCE_VERSION

Changes to src/sqliteInt.h.

  2853   2853     const char *zAuthContext;   /* Put saved Parse.zAuthContext here */
  2854   2854     Parse *pParse;              /* The Parse structure */
  2855   2855   };
  2856   2856   
  2857   2857   /*
  2858   2858   ** Bitfield flags for P5 value in various opcodes.
  2859   2859   */
  2860         -#define OPFLAG_NCHANGE       0x01    /* Set to update db->nChange */
         2860  +#define OPFLAG_NCHANGE       0x01    /* OP_Insert: Set to update db->nChange */
         2861  +                                     /* Also used in P2 (not P5) of OP_Delete */
  2861   2862   #define OPFLAG_EPHEM         0x01    /* OP_Column: Ephemeral output is ok */
  2862   2863   #define OPFLAG_LASTROWID     0x02    /* Set to update db->lastRowid */
  2863   2864   #define OPFLAG_ISUPDATE      0x04    /* This OP_Insert is an sql UPDATE */
  2864   2865   #define OPFLAG_APPEND        0x08    /* This is likely to be an append */
  2865   2866   #define OPFLAG_USESEEKRESULT 0x10    /* Try to avoid a seek in BtreeInsert() */
  2866   2867   #define OPFLAG_LENGTHARG     0x40    /* OP_Column only used for length() */
  2867   2868   #define OPFLAG_TYPEOFARG     0x80    /* OP_Column only used for typeof() */
  2868   2869   #define OPFLAG_BULKCSR       0x01    /* OP_Open** used to open bulk cursor */
  2869   2870   #define OPFLAG_SEEKEQ        0x02    /* OP_Open** cursor uses EQ seek only */
  2870         -#define OPFLAG_FORDELETE     0x08    /* OP_Open is opening for-delete csr */
         2871  +#define OPFLAG_FORDELETE     0x08    /* OP_Open should use BTREE_FORDELETE */
  2871   2872   #define OPFLAG_P2ISREG       0x10    /* P2 to OP_Open** is a register number */
  2872   2873   #define OPFLAG_PERMUTE       0x01    /* OP_Compare: use the permutation */
         2874  +#define OPFLAG_SAVEPOSITION  0x02    /* OP_Delete: keep cursor position */
         2875  +#define OPFLAG_AUXDELETE     0x04    /* OP_Delete: index in a DELETE op */
  2873   2876   
  2874   2877   /*
  2875   2878    * Each trigger present in the database schema is stored as an instance of
  2876   2879    * struct Trigger. 
  2877   2880    *
  2878   2881    * Pointers to instances of struct Trigger are stored in two ways.
  2879   2882    * 1. In the "trigHash" hash table (part of the sqlite3* that represents the 
................................................................................
  2984   2987     sqlite3 *db;         /* Optional database for lookaside.  Can be NULL */
  2985   2988     char *zBase;         /* A base allocation.  Not from malloc. */
  2986   2989     char *zText;         /* The string collected so far */
  2987   2990     u32  nChar;          /* Length of the string so far */
  2988   2991     u32  nAlloc;         /* Amount of space allocated in zText */
  2989   2992     u32  mxAlloc;        /* Maximum allowed allocation.  0 for no malloc usage */
  2990   2993     u8   accError;       /* STRACCUM_NOMEM or STRACCUM_TOOBIG */
  2991         -  u8   bMalloced;      /* zText points to allocated space */
         2994  +  u8   printfFlags;    /* SQLITE_PRINTF flags below */
  2992   2995   };
  2993   2996   #define STRACCUM_NOMEM   1
  2994   2997   #define STRACCUM_TOOBIG  2
         2998  +#define SQLITE_PRINTF_INTERNAL 0x01  /* Internal-use-only converters allowed */
         2999  +#define SQLITE_PRINTF_SQLFUNC  0x02  /* SQL function arguments to VXPrintf */
         3000  +#define SQLITE_PRINTF_MALLOCED 0x04  /* True if xText is allocated space */
         3001  +
         3002  +#define isMalloced(X)  (((X)->printfFlags & SQLITE_PRINTF_MALLOCED)!=0)
         3003  +
  2995   3004   
  2996   3005   /*
  2997   3006   ** A pointer to this structure is used to communicate information
  2998   3007   ** from sqlite3Init and OP_ParseSchema into the sqlite3InitCallback.
  2999   3008   */
  3000   3009   typedef struct {
  3001   3010     sqlite3 *db;        /* The database being initialized */
................................................................................
  3304   3313   */
  3305   3314   struct PrintfArguments {
  3306   3315     int nArg;                /* Total number of arguments */
  3307   3316     int nUsed;               /* Number of arguments used so far */
  3308   3317     sqlite3_value **apArg;   /* The argument values */
  3309   3318   };
  3310   3319   
  3311         -#define SQLITE_PRINTF_INTERNAL 0x01
  3312         -#define SQLITE_PRINTF_SQLFUNC  0x02
  3313         -void sqlite3VXPrintf(StrAccum*, u32, const char*, va_list);
  3314         -void sqlite3XPrintf(StrAccum*, u32, const char*, ...);
         3320  +void sqlite3VXPrintf(StrAccum*, const char*, va_list);
         3321  +void sqlite3XPrintf(StrAccum*, const char*, ...);
  3315   3322   char *sqlite3MPrintf(sqlite3*,const char*, ...);
  3316   3323   char *sqlite3VMPrintf(sqlite3*,const char*, va_list);
  3317   3324   #if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE)
  3318   3325     void sqlite3DebugPrintf(const char*, ...);
  3319   3326   #endif
  3320   3327   #if defined(SQLITE_TEST)
  3321   3328     void *sqlite3TestTextToPtr(const char*);
................................................................................
  3328   3335     void sqlite3TreeViewWith(TreeView*, const With*, u8);
  3329   3336   #endif
  3330   3337   
  3331   3338   
  3332   3339   void sqlite3SetString(char **, sqlite3*, const char*);
  3333   3340   void sqlite3ErrorMsg(Parse*, const char*, ...);
  3334   3341   int sqlite3Dequote(char*);
         3342  +void sqlite3TokenInit(Token*,char*);
  3335   3343   int sqlite3KeywordCode(const unsigned char*, int);
  3336   3344   int sqlite3RunParser(Parse*, const char*, char **);
  3337   3345   void sqlite3FinishCoding(Parse*);
  3338   3346   int sqlite3GetTempReg(Parse*);
  3339   3347   void sqlite3ReleaseTempReg(Parse*,int);
  3340   3348   int sqlite3GetTempRange(Parse*,int);
  3341   3349   void sqlite3ReleaseTempRange(Parse*,int,int);

Changes to src/tclsqlite.c.

   149    149     SqlPreparedStmt *stmtList; /* List of prepared statements*/
   150    150     SqlPreparedStmt *stmtLast; /* Last statement in the list */
   151    151     int maxStmt;               /* The next maximum number of stmtList */
   152    152     int nStmt;                 /* Number of statements in stmtList */
   153    153     IncrblobChannel *pIncrblob;/* Linked list of open incrblob channels */
   154    154     int nStep, nSort, nIndex;  /* Statistics for most recent operation */
   155    155     int nTransaction;          /* Number of nested [transaction] methods */
          156  +  int openFlags;             /* Flags used to open.  (SQLITE_OPEN_URI) */
   156    157   #ifdef SQLITE_TEST
   157    158     int bLegacyPrepare;        /* True to use sqlite3_prepare() */
   158    159   #endif
   159    160   };
   160    161   
   161    162   struct IncrblobChannel {
   162    163     sqlite3_blob *pBlob;      /* sqlite3 blob handle */
................................................................................
  1746   1747       }else if( objc==4 ){
  1747   1748         zSrcDb = Tcl_GetString(objv[2]);
  1748   1749         zDestFile = Tcl_GetString(objv[3]);
  1749   1750       }else{
  1750   1751         Tcl_WrongNumArgs(interp, 2, objv, "?DATABASE? FILENAME");
  1751   1752         return TCL_ERROR;
  1752   1753       }
  1753         -    rc = sqlite3_open(zDestFile, &pDest);
         1754  +    rc = sqlite3_open_v2(zDestFile, &pDest,
         1755  +               SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE| pDb->openFlags, 0);
  1754   1756       if( rc!=SQLITE_OK ){
  1755   1757         Tcl_AppendResult(interp, "cannot open target database: ",
  1756   1758              sqlite3_errmsg(pDest), (char*)0);
  1757   1759         sqlite3_close(pDest);
  1758   1760         return TCL_ERROR;
  1759   1761       }
  1760   1762       pBackup = sqlite3_backup_init(pDest, "main", pDb->db, zSrcDb);
................................................................................
  2609   2611       }else if( objc==4 ){
  2610   2612         zDestDb = Tcl_GetString(objv[2]);
  2611   2613         zSrcFile = Tcl_GetString(objv[3]);
  2612   2614       }else{
  2613   2615         Tcl_WrongNumArgs(interp, 2, objv, "?DATABASE? FILENAME");
  2614   2616         return TCL_ERROR;
  2615   2617       }
  2616         -    rc = sqlite3_open_v2(zSrcFile, &pSrc, SQLITE_OPEN_READONLY, 0);
         2618  +    rc = sqlite3_open_v2(zSrcFile, &pSrc,
         2619  +                         SQLITE_OPEN_READONLY | pDb->openFlags, 0);
  2617   2620       if( rc!=SQLITE_OK ){
  2618   2621         Tcl_AppendResult(interp, "cannot open source database: ",
  2619   2622              sqlite3_errmsg(pSrc), (char*)0);
  2620   2623         sqlite3_close(pSrc);
  2621   2624         return TCL_ERROR;
  2622   2625       }
  2623   2626       pBackup = sqlite3_backup_init(pDb->db, zDestDb, pSrc, "main");
................................................................................
  3084   3087     if( p->db==0 ){
  3085   3088       Tcl_SetResult(interp, zErrMsg, TCL_VOLATILE);
  3086   3089       Tcl_Free((char*)p);
  3087   3090       sqlite3_free(zErrMsg);
  3088   3091       return TCL_ERROR;
  3089   3092     }
  3090   3093     p->maxStmt = NUM_PREPARED_STMTS;
         3094  +  p->openFlags = flags & SQLITE_OPEN_URI;
  3091   3095     p->interp = interp;
  3092   3096     zArg = Tcl_GetStringFromObj(objv[1], 0);
  3093   3097     if( DbUseNre() ){
  3094   3098       Tcl_NRCreateCommand(interp, zArg, DbObjCmdAdaptor, DbObjCmd,
  3095   3099                           (char*)p, DbDeleteCmd);
  3096   3100     }else{
  3097   3101       Tcl_CreateObjCommand(interp, zArg, DbObjCmd, (char*)p, DbDeleteCmd);

Changes to src/treeview.c.

    59     59     if( p ){
    60     60       for(i=0; i<p->iLevel && i<sizeof(p->bLine)-1; i++){
    61     61         sqlite3StrAccumAppend(&acc, p->bLine[i] ? "|   " : "    ", 4);
    62     62       }
    63     63       sqlite3StrAccumAppend(&acc, p->bLine[i] ? "|-- " : "'-- ", 4);
    64     64     }
    65     65     va_start(ap, zFormat);
    66         -  sqlite3VXPrintf(&acc, 0, zFormat, ap);
           66  +  sqlite3VXPrintf(&acc, zFormat, ap);
    67     67     va_end(ap);
    68     68     if( zBuf[acc.nChar-1]!='\n' ) sqlite3StrAccumAppend(&acc, "\n", 1);
    69     69     sqlite3StrAccumFinish(&acc);
    70     70     fprintf(stdout,"%s", zBuf);
    71     71     fflush(stdout);
    72     72   }
    73     73   
................................................................................
    94     94     if( pWith->nCte>0 ){
    95     95       pView = sqlite3TreeViewPush(pView, 1);
    96     96       for(i=0; i<pWith->nCte; i++){
    97     97         StrAccum x;
    98     98         char zLine[1000];
    99     99         const struct Cte *pCte = &pWith->a[i];
   100    100         sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0);
   101         -      sqlite3XPrintf(&x, 0, "%s", pCte->zName);
          101  +      sqlite3XPrintf(&x, "%s", pCte->zName);
   102    102         if( pCte->pCols && pCte->pCols->nExpr>0 ){
   103    103           char cSep = '(';
   104    104           int j;
   105    105           for(j=0; j<pCte->pCols->nExpr; j++){
   106         -          sqlite3XPrintf(&x, 0, "%c%s", cSep, pCte->pCols->a[j].zName);
          106  +          sqlite3XPrintf(&x, "%c%s", cSep, pCte->pCols->a[j].zName);
   107    107             cSep = ',';
   108    108           }
   109         -        sqlite3XPrintf(&x, 0, ")");
          109  +        sqlite3XPrintf(&x, ")");
   110    110         }
   111         -      sqlite3XPrintf(&x, 0, " AS");
          111  +      sqlite3XPrintf(&x, " AS");
   112    112         sqlite3StrAccumFinish(&x);
   113    113         sqlite3TreeViewItem(pView, zLine, i<pWith->nCte-1);
   114    114         sqlite3TreeViewSelect(pView, pCte->pSelect, 0);
   115    115         sqlite3TreeViewPop(pView);
   116    116       }
   117    117       sqlite3TreeViewPop(pView);
   118    118     }
................................................................................
   155    155         pView = sqlite3TreeViewPush(pView, (n--)>0);
   156    156         sqlite3TreeViewLine(pView, "FROM");
   157    157         for(i=0; i<p->pSrc->nSrc; i++){
   158    158           struct SrcList_item *pItem = &p->pSrc->a[i];
   159    159           StrAccum x;
   160    160           char zLine[100];
   161    161           sqlite3StrAccumInit(&x, 0, zLine, sizeof(zLine), 0);
   162         -        sqlite3XPrintf(&x, 0, "{%d,*}", pItem->iCursor);
          162  +        sqlite3XPrintf(&x, "{%d,*}", pItem->iCursor);
   163    163           if( pItem->zDatabase ){
   164         -          sqlite3XPrintf(&x, 0, " %s.%s", pItem->zDatabase, pItem->zName);
          164  +          sqlite3XPrintf(&x, " %s.%s", pItem->zDatabase, pItem->zName);
   165    165           }else if( pItem->zName ){
   166         -          sqlite3XPrintf(&x, 0, " %s", pItem->zName);
          166  +          sqlite3XPrintf(&x, " %s", pItem->zName);
   167    167           }
   168    168           if( pItem->pTab ){
   169         -          sqlite3XPrintf(&x, 0, " tabname=%Q", pItem->pTab->zName);
          169  +          sqlite3XPrintf(&x, " tabname=%Q", pItem->pTab->zName);
   170    170           }
   171    171           if( pItem->zAlias ){
   172         -          sqlite3XPrintf(&x, 0, " (AS %s)", pItem->zAlias);
          172  +          sqlite3XPrintf(&x, " (AS %s)", pItem->zAlias);
   173    173           }
   174    174           if( pItem->fg.jointype & JT_LEFT ){
   175         -          sqlite3XPrintf(&x, 0, " LEFT-JOIN");
          175  +          sqlite3XPrintf(&x, " LEFT-JOIN");
   176    176           }
   177    177           sqlite3StrAccumFinish(&x);
   178    178           sqlite3TreeViewItem(pView, zLine, i<p->pSrc->nSrc-1); 
   179    179           if( pItem->pSelect ){
   180    180             sqlite3TreeViewSelect(pView, pItem->pSelect, 0);
   181    181           }
   182    182           if( pItem->fg.isTabFunc ){

Changes to src/trigger.c.

   283    283     zName = pTrig->zName;
   284    284     iDb = sqlite3SchemaToIndex(pParse->db, pTrig->pSchema);
   285    285     pTrig->step_list = pStepList;
   286    286     while( pStepList ){
   287    287       pStepList->pTrig = pTrig;
   288    288       pStepList = pStepList->pNext;
   289    289     }
   290         -  nameToken.z = pTrig->zName;
   291         -  nameToken.n = sqlite3Strlen30(nameToken.z);
          290  +  sqlite3TokenInit(&nameToken, pTrig->zName);
   292    291     sqlite3FixInit(&sFix, pParse, iDb, "trigger", &nameToken);
   293    292     if( sqlite3FixTriggerStep(&sFix, pTrig->step_list) 
   294    293      || sqlite3FixExpr(&sFix, pTrig->pWhen) 
   295    294     ){
   296    295       goto triggerfinish_cleanup;
   297    296     }
   298    297   

Changes to src/utf.c.

   312    312       pMem->n = (int)(z - zOut);
   313    313     }
   314    314     *z = 0;
   315    315     assert( (pMem->n+(desiredEnc==SQLITE_UTF8?1:2))<=len );
   316    316   
   317    317     c = pMem->flags;
   318    318     sqlite3VdbeMemRelease(pMem);
   319         -  pMem->flags = MEM_Str|MEM_Term|(c&MEM_AffMask);
          319  +  pMem->flags = MEM_Str|MEM_Term|(c&(MEM_AffMask|MEM_Subtype));
   320    320     pMem->enc = desiredEnc;
   321    321     pMem->z = (char*)zOut;
   322    322     pMem->zMalloc = pMem->z;
   323    323     pMem->szMalloc = sqlite3DbMallocSize(pMem->db, pMem->z);
   324    324   
   325    325   translate_out:
   326    326   #if defined(TRANSLATE_TRACE) && defined(SQLITE_DEBUG)

Changes to src/util.c.

   229    229       }else{
   230    230         z[j++] = z[i];
   231    231       }
   232    232     }
   233    233     z[j] = 0;
   234    234     return j;
   235    235   }
          236  +
          237  +/*
          238  +** Generate a Token object from a string
          239  +*/
          240  +void sqlite3TokenInit(Token *p, char *z){
          241  +  p->z = z;
          242  +  p->n = sqlite3Strlen30(z);
          243  +}
   236    244   
   237    245   /* Convenient short-hand */
   238    246   #define UpperToLower sqlite3UpperToLower
   239    247   
   240    248   /*
   241    249   ** Some systems have stricmp().  Others have strcasecmp().  Because
   242    250   ** there is no consistency, we will define our own.

Changes to src/vdbe.c.

   467    467     }else if( p->flags & MEM_RowSet ){
   468    468       printf(" (rowset)");
   469    469     }else{
   470    470       char zBuf[200];
   471    471       sqlite3VdbeMemPrettyPrint(p, zBuf);
   472    472       printf(" %s", zBuf);
   473    473     }
          474  +  if( p->flags & MEM_Subtype ) printf(" subtype=0x%02x", p->eSubtype);
   474    475   }
   475    476   static void registerTrace(int iReg, Mem *p){
   476    477     printf("REG[%d] = ", iReg);
   477    478     memTracePrint(p);
   478    479     printf("\n");
   479    480   }
   480    481   #endif
................................................................................
   548    549     Vdbe *p                    /* The VDBE */
   549    550   ){
   550    551     Op *aOp = p->aOp;          /* Copy of p->aOp */
   551    552     Op *pOp = aOp;             /* Current operation */
   552    553   #if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
   553    554     Op *pOrigOp;               /* Value of pOp at the top of the loop */
   554    555   #endif
          556  +#ifdef SQLITE_DEBUG
          557  +  int nExtraDelete = 0;      /* Verifies FORDELETE and AUXDELETE flags */
          558  +#endif
   555    559     int rc = SQLITE_OK;        /* Value to return */
   556    560     sqlite3 *db = p->db;       /* The database */
   557    561     u8 resetSchemaOnFault = 0; /* Reset schema after an error if positive */
   558    562     u8 encoding = ENC(db);     /* The database encoding */
   559    563     int iCompare = 0;          /* Result of last OP_Compare operation */
   560    564     unsigned nVmStep = 0;      /* Number of virtual machine steps */
   561    565   #ifndef SQLITE_OMIT_PROGRESS_CALLBACK
................................................................................
  2064   2068   **
  2065   2069   ** Set the permutation used by the OP_Compare operator to be the array
  2066   2070   ** of integers in P4.
  2067   2071   **
  2068   2072   ** The permutation is only valid until the next OP_Compare that has
  2069   2073   ** the OPFLAG_PERMUTE bit set in P5. Typically the OP_Permutation should 
  2070   2074   ** occur immediately prior to the OP_Compare.
         2075  +**
         2076  +** The first integer in the P4 integer array is the length of the array
         2077  +** and does not become part of the permutation.
  2071   2078   */
  2072   2079   case OP_Permutation: {
  2073   2080     assert( pOp->p4type==P4_INTARRAY );
  2074   2081     assert( pOp->p4.ai );
  2075         -  aPermute = pOp->p4.ai;
         2082  +  aPermute = pOp->p4.ai + 1;
  2076   2083     break;
  2077   2084   }
  2078   2085   
  2079   2086   /* Opcode: Compare P1 P2 P3 P4 P5
  2080   2087   ** Synopsis: r[P1@P3] <-> r[P2@P3]
  2081   2088   **
  2082   2089   ** Compare two vectors of registers in reg(P1)..reg(P1+P3-1) (call this
................................................................................
  2373   2380     const u8 *zEndHdr; /* Pointer to first byte after the header */
  2374   2381     u32 offset;        /* Offset into the data */
  2375   2382     u64 offset64;      /* 64-bit offset */
  2376   2383     u32 avail;         /* Number of bytes of available data */
  2377   2384     u32 t;             /* A type code from the record header */
  2378   2385     Mem *pReg;         /* PseudoTable input register */
  2379   2386   
         2387  +  pC = p->apCsr[pOp->p1];
  2380   2388     p2 = pOp->p2;
         2389  +
         2390  +  /* If the cursor cache is stale, bring it up-to-date */
         2391  +  rc = sqlite3VdbeCursorMoveto(&pC, &p2);
         2392  +
  2381   2393     assert( pOp->p3>0 && pOp->p3<=(p->nMem-p->nCursor) );
  2382   2394     pDest = &aMem[pOp->p3];
  2383   2395     memAboutToChange(p, pDest);
  2384   2396     assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  2385         -  pC = p->apCsr[pOp->p1];
  2386   2397     assert( pC!=0 );
  2387   2398     assert( p2<pC->nField );
  2388   2399     aOffset = pC->aOffset;
  2389   2400     assert( pC->eCurType!=CURTYPE_VTAB );
  2390   2401     assert( pC->eCurType!=CURTYPE_PSEUDO || pC->nullRow );
  2391   2402     assert( pC->eCurType!=CURTYPE_SORTER );
  2392   2403     pCrsr = pC->uc.pCursor;
  2393   2404   
  2394         -  /* If the cursor cache is stale, bring it up-to-date */
  2395         -  rc = sqlite3VdbeCursorMoveto(pC);
  2396   2405     if( rc ) goto abort_due_to_error;
  2397   2406     if( pC->cacheStatus!=p->cacheCtr ){
  2398   2407       if( pC->nullRow ){
  2399   2408         if( pC->eCurType==CURTYPE_PSEUDO ){
  2400   2409           assert( pC->uc.pseudoTableReg>0 );
  2401   2410           pReg = &aMem[pC->uc.pseudoTableReg];
  2402   2411           assert( pReg->flags & MEM_Blob );
................................................................................
  2996   3005   ** there are active writing VMs or active VMs that use shared cache.
  2997   3006   **
  2998   3007   ** This instruction causes the VM to halt.
  2999   3008   */
  3000   3009   case OP_AutoCommit: {
  3001   3010     int desiredAutoCommit;
  3002   3011     int iRollback;
  3003         -  int turnOnAC;
  3004   3012   
  3005   3013     desiredAutoCommit = pOp->p1;
  3006   3014     iRollback = pOp->p2;
  3007         -  turnOnAC = desiredAutoCommit && !db->autoCommit;
  3008   3015     assert( desiredAutoCommit==1 || desiredAutoCommit==0 );
  3009   3016     assert( desiredAutoCommit==1 || iRollback==0 );
  3010   3017     assert( db->nVdbeActive>0 );  /* At least this one VM is active */
  3011   3018     assert( p->bIsReader );
  3012   3019   
  3013         -  if( turnOnAC && !iRollback && db->nVdbeWrite>0 ){
  3014         -    /* If this instruction implements a COMMIT and other VMs are writing
  3015         -    ** return an error indicating that the other VMs must complete first. 
  3016         -    */
  3017         -    sqlite3VdbeError(p, "cannot commit transaction - "
  3018         -                        "SQL statements in progress");
  3019         -    rc = SQLITE_BUSY;
  3020         -  }else if( desiredAutoCommit!=db->autoCommit ){
         3020  +  if( desiredAutoCommit!=db->autoCommit ){
  3021   3021       if( iRollback ){
  3022   3022         assert( desiredAutoCommit==1 );
  3023   3023         sqlite3RollbackAll(db, SQLITE_ABORT_ROLLBACK);
  3024   3024         db->autoCommit = 1;
         3025  +    }else if( desiredAutoCommit && db->nVdbeWrite>0 ){
         3026  +      /* If this instruction implements a COMMIT and other VMs are writing
         3027  +      ** return an error indicating that the other VMs must complete first. 
         3028  +      */
         3029  +      sqlite3VdbeError(p, "cannot commit transaction - "
         3030  +                          "SQL statements in progress");
         3031  +      rc = SQLITE_BUSY;
         3032  +      break;
  3025   3033       }else if( (rc = sqlite3VdbeCheckFk(p, 1))!=SQLITE_OK ){
  3026   3034         goto vdbe_return;
  3027   3035       }else{
  3028   3036         db->autoCommit = (u8)desiredAutoCommit;
  3029   3037       }
  3030   3038       if( sqlite3VdbeHalt(p)==SQLITE_BUSY ){
  3031   3039         p->pc = (int)(pOp - aOp);
................................................................................
  3202   3210     pOut = out2Prerelease(p, pOp);
  3203   3211     pOut->u.i = iMeta;
  3204   3212     break;
  3205   3213   }
  3206   3214   
  3207   3215   /* Opcode: SetCookie P1 P2 P3 * *
  3208   3216   **
  3209         -** Write the content of register P3 (interpreted as an integer)
  3210         -** into cookie number P2 of database P1.  P2==1 is the schema version.  
  3211         -** P2==2 is the database format. P2==3 is the recommended pager cache 
         3217  +** Write the integer value P3 into cookie number P2 of database P1.
         3218  +** P2==1 is the schema version.  P2==2 is the database format.
         3219  +** P2==3 is the recommended pager cache 
  3212   3220   ** size, and so forth.  P1==0 is the main database file and P1==1 is the 
  3213   3221   ** database file used to store temporary tables.
  3214   3222   **
  3215   3223   ** A transaction must be started before executing this opcode.
  3216   3224   */
  3217         -case OP_SetCookie: {       /* in3 */
         3225  +case OP_SetCookie: {
  3218   3226     Db *pDb;
  3219   3227     assert( pOp->p2<SQLITE_N_BTREE_META );
  3220   3228     assert( pOp->p1>=0 && pOp->p1<db->nDb );
  3221   3229     assert( DbMaskTest(p->btreeMask, pOp->p1) );
  3222   3230     assert( p->readOnly==0 );
  3223   3231     pDb = &db->aDb[pOp->p1];
  3224   3232     assert( pDb->pBt!=0 );
  3225   3233     assert( sqlite3SchemaMutexHeld(db, pOp->p1, 0) );
  3226         -  pIn3 = &aMem[pOp->p3];
  3227         -  sqlite3VdbeMemIntegerify(pIn3);
  3228   3234     /* See note about index shifting on OP_ReadCookie */
  3229         -  rc = sqlite3BtreeUpdateMeta(pDb->pBt, pOp->p2, (int)pIn3->u.i);
         3235  +  rc = sqlite3BtreeUpdateMeta(pDb->pBt, pOp->p2, pOp->p3);
  3230   3236     if( pOp->p2==BTREE_SCHEMA_VERSION ){
  3231   3237       /* When the schema cookie changes, record the new cookie internally */
  3232         -    pDb->pSchema->schema_cookie = (int)pIn3->u.i;
         3238  +    pDb->pSchema->schema_cookie = pOp->p3;
  3233   3239       db->flags |= SQLITE_InternChanges;
  3234   3240     }else if( pOp->p2==BTREE_FILE_FORMAT ){
  3235   3241       /* Record changes in the file format */
  3236         -    pDb->pSchema->file_format = (u8)pIn3->u.i;
         3242  +    pDb->pSchema->file_format = pOp->p3;
  3237   3243     }
  3238   3244     if( pOp->p1==1 ){
  3239   3245       /* Invalidate all prepared statements whenever the TEMP database
  3240   3246       ** schema is changed.  Ticket #1644 */
  3241   3247       sqlite3ExpirePreparedStatements(db);
  3242   3248       p->expired = 0;
  3243   3249     }
................................................................................
  3389   3395     assert( nField>=0 );
  3390   3396     testcase( nField==0 );  /* Table with INTEGER PRIMARY KEY and nothing else */
  3391   3397     pCur = allocateCursor(p, pOp->p1, nField, iDb, CURTYPE_BTREE);
  3392   3398     if( pCur==0 ) goto no_mem;
  3393   3399     pCur->nullRow = 1;
  3394   3400     pCur->isOrdered = 1;
  3395   3401     pCur->pgnoRoot = p2;
         3402  +#ifdef SQLITE_DEBUG
         3403  +  pCur->wrFlag = wrFlag;
         3404  +#endif
  3396   3405     rc = sqlite3BtreeCursor(pX, p2, wrFlag, pKeyInfo, pCur->uc.pCursor);
  3397   3406     pCur->pKeyInfo = pKeyInfo;
  3398   3407     /* Set the VdbeCursor.isTable variable. Previous versions of
  3399   3408     ** SQLite used to check if the root-page flags were sane at this point
  3400   3409     ** and report database corruption if they were not, but this check has
  3401   3410     ** since moved into the btree layer.  */  
  3402   3411     pCur->isTable = pOp->p4type!=P4_KEYINFO;
................................................................................
  3842   3851       goto jump_to_p2;
  3843   3852     }else if( eqOnly ){
  3844   3853       assert( pOp[1].opcode==OP_IdxLT || pOp[1].opcode==OP_IdxGT );
  3845   3854       pOp++; /* Skip the OP_IdxLt or OP_IdxGT that follows */
  3846   3855     }
  3847   3856     break;
  3848   3857   }
  3849         -
  3850         -/* Opcode: Seek P1 P2 * * *
  3851         -** Synopsis:  intkey=r[P2]
  3852         -**
  3853         -** P1 is an open table cursor and P2 is a rowid integer.  Arrange
  3854         -** for P1 to move so that it points to the rowid given by P2.
  3855         -**
  3856         -** This is actually a deferred seek.  Nothing actually happens until
  3857         -** the cursor is used to read a record.  That way, if no reads
  3858         -** occur, no unnecessary I/O happens.
  3859         -*/
  3860         -case OP_Seek: {    /* in2 */
  3861         -  VdbeCursor *pC;
  3862         -
  3863         -  assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  3864         -  pC = p->apCsr[pOp->p1];
  3865         -  assert( pC!=0 );
  3866         -  assert( pC->eCurType==CURTYPE_BTREE );
  3867         -  assert( pC->uc.pCursor!=0 );
  3868         -  assert( pC->isTable );
  3869         -  pC->nullRow = 0;
  3870         -  pIn2 = &aMem[pOp->p2];
  3871         -  pC->movetoTarget = sqlite3VdbeIntValue(pIn2);
  3872         -  pC->deferredMoveto = 1;
  3873         -  break;
  3874         -}
  3875   3858     
  3876   3859   
  3877   3860   /* Opcode: Found P1 P2 P3 P4 *
  3878   3861   ** Synopsis: key=r[P3@P4]
  3879   3862   **
  3880   3863   ** If P4==0 then register P3 holds a blob constructed by MakeRecord.  If
  3881   3864   ** P4>0 then register P3 is the first of P4 registers that form an unpacked
................................................................................
  4338   4321     break;
  4339   4322   }
  4340   4323   
  4341   4324   /* Opcode: Delete P1 P2 * P4 P5
  4342   4325   **
  4343   4326   ** Delete the record at which the P1 cursor is currently pointing.
  4344   4327   **
  4345         -** If the P5 parameter is non-zero, the cursor will be left pointing at 
  4346         -** either the next or the previous record in the table. If it is left 
  4347         -** pointing at the next record, then the next Next instruction will be a 
  4348         -** no-op. As a result, in this case it is OK to delete a record from within a
  4349         -** Next loop. If P5 is zero, then the cursor is left in an undefined state.
         4328  +** If the OPFLAG_SAVEPOSITION bit of the P5 parameter is set, then
         4329  +** the cursor will be left pointing at  either the next or the previous
         4330  +** record in the table. If it is left pointing at the next record, then
         4331  +** the next Next instruction will be a no-op. As a result, in this case
         4332  +** it is ok to delete a record from within a Next loop. If 
         4333  +** OPFLAG_SAVEPOSITION bit of P5 is clear, then the cursor will be
         4334  +** left in an undefined state.
  4350   4335   **
  4351         -** If the OPFLAG_NCHANGE flag of P2 is set, then the row change count is
  4352         -** incremented (otherwise not).
         4336  +** If the OPFLAG_AUXDELETE bit is set on P5, that indicates that this
         4337  +** delete one of several associated with deleting a table row and all its
         4338  +** associated index entries.  Exactly one of those deletes is the "primary"
         4339  +** delete.  The others are all on OPFLAG_FORDELETE cursors or else are
         4340  +** marked with the AUXDELETE flag.
         4341  +**
         4342  +** If the OPFLAG_NCHANGE flag of P2 (NB: P2 not P5) is set, then the row
         4343  +** change count is incremented (otherwise not).
  4353   4344   **
  4354   4345   ** P1 must not be pseudo-table.  It has to be a real table with
  4355   4346   ** multiple rows.
  4356   4347   **
  4357   4348   ** If P4 is not NULL, then it is the name of the table that P1 is
  4358   4349   ** pointing to.  The update hook will be invoked, if it exists.
  4359   4350   ** If P4 is not NULL then the P1 cursor must have been positioned
................................................................................
  4381   4372     ** is being deleted */
  4382   4373     if( pOp->p4.z && pC->isTable && pOp->p5==0 ){
  4383   4374       i64 iKey = 0;
  4384   4375       sqlite3BtreeKeySize(pC->uc.pCursor, &iKey);
  4385   4376       assert( pC->movetoTarget==iKey ); 
  4386   4377     }
  4387   4378   #endif
  4388         - 
         4379  +
         4380  +  /* Only flags that can be set are SAVEPOISTION and AUXDELETE */ 
         4381  +  assert( (pOp->p5 & ~(OPFLAG_SAVEPOSITION|OPFLAG_AUXDELETE))==0 );
         4382  +  assert( OPFLAG_SAVEPOSITION==BTREE_SAVEPOSITION );
         4383  +  assert( OPFLAG_AUXDELETE==BTREE_AUXDELETE );
         4384  +
         4385  +#ifdef SQLITE_DEBUG
         4386  +  if( p->pFrame==0 ){
         4387  +    if( pC->isEphemeral==0
         4388  +        && (pOp->p5 & OPFLAG_AUXDELETE)==0
         4389  +        && (pC->wrFlag & OPFLAG_FORDELETE)==0
         4390  +      ){
         4391  +      nExtraDelete++;
         4392  +    }
         4393  +    if( pOp->p2 & OPFLAG_NCHANGE ){
         4394  +      nExtraDelete--;
         4395  +    }
         4396  +  }
         4397  +#endif
         4398  +
  4389   4399     rc = sqlite3BtreeDelete(pC->uc.pCursor, pOp->p5);
  4390   4400     pC->cacheStatus = CACHE_STALE;
  4391   4401   
  4392   4402     /* Invoke the update-hook if required. */
  4393   4403     if( rc==SQLITE_OK && hasUpdateCallback ){
  4394   4404       db->xUpdateCallback(db->pUpdateArg, SQLITE_DELETE,
  4395   4405                           db->aDb[pC->iDb].zName, pOp->p4.z, pC->movetoTarget);
................................................................................
  4926   4936     pCrsr = pC->uc.pCursor;
  4927   4937     assert( pCrsr!=0 );
  4928   4938     assert( pOp->p5==0 );
  4929   4939     r.pKeyInfo = pC->pKeyInfo;
  4930   4940     r.nField = (u16)pOp->p3;
  4931   4941     r.default_rc = 0;
  4932   4942     r.aMem = &aMem[pOp->p2];
  4933         -#ifdef SQLITE_DEBUG
  4934         -  { int i; for(i=0; i<r.nField; i++) assert( memIsValid(&r.aMem[i]) ); }
  4935         -#endif
  4936   4943     rc = sqlite3BtreeMovetoUnpacked(pCrsr, &r, 0, 0, &res);
  4937   4944     if( rc==SQLITE_OK && res==0 ){
  4938         -    rc = sqlite3BtreeDelete(pCrsr, 0);
         4945  +    rc = sqlite3BtreeDelete(pCrsr, BTREE_AUXDELETE);
  4939   4946     }
  4940   4947     assert( pC->deferredMoveto==0 );
  4941   4948     pC->cacheStatus = CACHE_STALE;
  4942   4949     break;
  4943   4950   }
  4944   4951   
         4952  +/* Opcode: Seek P1 * P3 P4 *
         4953  +** Synopsis:  Move P3 to P1.rowid
         4954  +**
         4955  +** P1 is an open index cursor and P3 is a cursor on the corresponding
         4956  +** table.  This opcode does a deferred seek of the P3 table cursor
         4957  +** to the row that corresponds to the current row of P1.
         4958  +**
         4959  +** This is a deferred seek.  Nothing actually happens until
         4960  +** the cursor is used to read a record.  That way, if no reads
         4961  +** occur, no unnecessary I/O happens.
         4962  +**
         4963  +** P4 may be an array of integers (type P4_INTARRAY) containing
         4964  +** one entry for each column in the P3 table.  If array entry a[i]
         4965  +** is non-zero, then reading column (a[i]-1) from cursor P3 is 
         4966  +** equivalent to performing the deferred seek and then reading column i 
         4967  +** from P1.  This information is stored in P3 and used to redirect
         4968  +** reads against P3 over to P1, thus possibly avoiding the need to
         4969  +** seek and read cursor P3.
         4970  +*/
  4945   4971   /* Opcode: IdxRowid P1 P2 * * *
  4946   4972   ** Synopsis: r[P2]=rowid
  4947   4973   **
  4948   4974   ** Write into register P2 an integer which is the last entry in the record at
  4949   4975   ** the end of the index key pointed to by cursor P1.  This integer should be
  4950   4976   ** the rowid of the table entry to which this index entry points.
  4951   4977   **
  4952   4978   ** See also: Rowid, MakeRecord.
  4953   4979   */
         4980  +case OP_Seek:
  4954   4981   case OP_IdxRowid: {              /* out2 */
  4955         -  BtCursor *pCrsr;
  4956         -  VdbeCursor *pC;
  4957         -  i64 rowid;
         4982  +  VdbeCursor *pC;                /* The P1 index cursor */
         4983  +  VdbeCursor *pTabCur;           /* The P2 table cursor (OP_Seek only) */
         4984  +  i64 rowid;                     /* Rowid that P1 current points to */
  4958   4985   
  4959         -  pOut = out2Prerelease(p, pOp);
  4960   4986     assert( pOp->p1>=0 && pOp->p1<p->nCursor );
  4961   4987     pC = p->apCsr[pOp->p1];
  4962   4988     assert( pC!=0 );
  4963   4989     assert( pC->eCurType==CURTYPE_BTREE );
  4964         -  pCrsr = pC->uc.pCursor;
  4965         -  assert( pCrsr!=0 );
  4966         -  pOut->flags = MEM_Null;
         4990  +  assert( pC->uc.pCursor!=0 );
  4967   4991     assert( pC->isTable==0 );
  4968   4992     assert( pC->deferredMoveto==0 );
         4993  +  assert( !pC->nullRow || pOp->opcode==OP_IdxRowid );
         4994  +
         4995  +  /* The IdxRowid and Seek opcodes are combined because of the commonality
         4996  +  ** of sqlite3VdbeCursorRestore() and sqlite3VdbeIdxRowid(). */
         4997  +  rc = sqlite3VdbeCursorRestore(pC);
  4969   4998   
  4970   4999     /* sqlite3VbeCursorRestore() can only fail if the record has been deleted
  4971         -  ** out from under the cursor.  That will never happend for an IdxRowid
  4972         -  ** opcode, hence the NEVER() arround the check of the return value.
  4973         -  */
  4974         -  rc = sqlite3VdbeCursorRestore(pC);
         5000  +  ** out from under the cursor.  That will never happens for an IdxRowid
         5001  +  ** or Seek opcode */
  4975   5002     if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error;
  4976   5003   
  4977   5004     if( !pC->nullRow ){
  4978   5005       rowid = 0;  /* Not needed.  Only used to silence a warning. */
  4979         -    rc = sqlite3VdbeIdxRowid(db, pCrsr, &rowid);
         5006  +    rc = sqlite3VdbeIdxRowid(db, pC->uc.pCursor, &rowid);
  4980   5007       if( rc!=SQLITE_OK ){
  4981   5008         goto abort_due_to_error;
  4982   5009       }
  4983         -    pOut->u.i = rowid;
  4984         -    pOut->flags = MEM_Int;
         5010  +    if( pOp->opcode==OP_Seek ){
         5011  +      assert( pOp->p3>=0 && pOp->p3<p->nCursor );
         5012  +      pTabCur = p->apCsr[pOp->p3];
         5013  +      assert( pTabCur!=0 );
         5014  +      assert( pTabCur->eCurType==CURTYPE_BTREE );
         5015  +      assert( pTabCur->uc.pCursor!=0 );
         5016  +      assert( pTabCur->isTable );
         5017  +      pTabCur->nullRow = 0;
         5018  +      pTabCur->movetoTarget = rowid;
         5019  +      pTabCur->deferredMoveto = 1;
         5020  +      assert( pOp->p4type==P4_INTARRAY || pOp->p4.ai==0 );
         5021  +      pTabCur->aAltMap = pOp->p4.ai;
         5022  +      pTabCur->pAltCursor = pC;
         5023  +    }else{
         5024  +      pOut = out2Prerelease(p, pOp);
         5025  +      pOut->u.i = rowid;
         5026  +      pOut->flags = MEM_Int;
         5027  +    }
         5028  +  }else{
         5029  +    assert( pOp->opcode==OP_IdxRowid );
         5030  +    sqlite3VdbeMemSetNull(&aMem[pOp->p2]);
  4985   5031     }
  4986   5032     break;
  4987   5033   }
  4988   5034   
  4989   5035   /* Opcode: IdxGE P1 P2 P3 P4 P5
  4990   5036   ** Synopsis: key=r[P3@P4]
  4991   5037   **
................................................................................
  5754   5800     if( pIn1->u.i>0 ){
  5755   5801       pIn1->u.i -= pOp->p3;
  5756   5802       goto jump_to_p2;
  5757   5803     }
  5758   5804     break;
  5759   5805   }
  5760   5806   
  5761         -/* Opcode: SetIfNotPos P1 P2 P3 * *
  5762         -** Synopsis: if r[P1]<=0 then r[P2]=P3
         5807  +/* Opcode: OffsetLimit P1 P2 P3 * *
         5808  +** Synopsis: if r[P1]>0 then r[P2]=r[P1]+max(0,r[P3]) else r[P2]=(-1)
  5763   5809   **
  5764         -** Register P1 must contain an integer.
  5765         -** If the value of register P1 is not positive (if it is less than 1) then
  5766         -** set the value of register P2 to be the integer P3.
         5810  +** This opcode performs a commonly used computation associated with
         5811  +** LIMIT and OFFSET process.  r[P1] holds the limit counter.  r[P3]
         5812  +** holds the offset counter.  The opcode computes the combined value
         5813  +** of the LIMIT and OFFSET and stores that value in r[P2].  The r[P2]
         5814  +** value computed is the total number of rows that will need to be
         5815  +** visited in order to complete the query.
         5816  +**
         5817  +** If r[P3] is zero or negative, that means there is no OFFSET
         5818  +** and r[P2] is set to be the value of the LIMIT, r[P1].
         5819  +**
         5820  +** if r[P1] is zero or negative, that means there is no LIMIT
         5821  +** and r[P2] is set to -1. 
         5822  +**
         5823  +** Otherwise, r[P2] is set to the sum of r[P1] and r[P3].
  5767   5824   */
  5768         -case OP_SetIfNotPos: {        /* in1, in2 */
         5825  +case OP_OffsetLimit: {    /* in1, out2, in3 */
  5769   5826     pIn1 = &aMem[pOp->p1];
  5770         -  assert( pIn1->flags&MEM_Int );
  5771         -  if( pIn1->u.i<=0 ){
  5772         -    pOut = out2Prerelease(p, pOp);
  5773         -    pOut->u.i = pOp->p3;
  5774         -  }
         5827  +  pIn3 = &aMem[pOp->p3];
         5828  +  pOut = out2Prerelease(p, pOp);
         5829  +  assert( pIn1->flags & MEM_Int );
         5830  +  assert( pIn3->flags & MEM_Int );
         5831  +  pOut->u.i = pIn1->u.i<=0 ? -1 : pIn1->u.i+(pIn3->u.i>0?pIn3->u.i:0);
  5775   5832     break;
  5776   5833   }
  5777   5834   
  5778   5835   /* Opcode: IfNotZero P1 P2 P3 * *
  5779   5836   ** Synopsis: if r[P1]!=0 then r[P1]-=P3, goto P2
  5780   5837   **
  5781   5838   ** Register P1 must contain an integer.  If the content of register P1 is
................................................................................
  6739   6796     ** release the mutexes on btrees that were acquired at the
  6740   6797     ** top. */
  6741   6798   vdbe_return:
  6742   6799     db->lastRowid = lastRowid;
  6743   6800     testcase( nVmStep>0 );
  6744   6801     p->aCounter[SQLITE_STMTSTATUS_VM_STEP] += (int)nVmStep;
  6745   6802     sqlite3VdbeLeave(p);
         6803  +  assert( rc!=SQLITE_OK || nExtraDelete==0 
         6804  +       || sqlite3_strlike("DELETE%",p->zSql,0)!=0 
         6805  +  );
  6746   6806     return rc;
  6747   6807   
  6748   6808     /* Jump to here if a string or blob larger than SQLITE_MAX_LENGTH
  6749   6809     ** is encountered.
  6750   6810     */
  6751   6811   too_big:
  6752   6812     sqlite3VdbeError(p, "string or blob too big");

Changes to src/vdbeInt.h.

    70     70   **      * A b-tree cursor
    71     71   **          -  In the main database or in an ephemeral database
    72     72   **          -  On either an index or a table
    73     73   **      * A sorter
    74     74   **      * A virtual table
    75     75   **      * A one-row "pseudotable" stored in a single register
    76     76   */
           77  +typedef struct VdbeCursor VdbeCursor;
    77     78   struct VdbeCursor {
    78     79     u8 eCurType;          /* One of the CURTYPE_* values above */
    79     80     i8 iDb;               /* Index of cursor database in db->aDb[] (or -1) */
    80     81     u8 nullRow;           /* True if pointing to a row with no data */
    81     82     u8 deferredMoveto;    /* A call to sqlite3BtreeMoveto() is needed */
    82     83     u8 isTable;           /* True for rowid tables.  False for indexes */
    83     84   #ifdef SQLITE_DEBUG
    84     85     u8 seekOp;            /* Most recent seek operation on this cursor */
           86  +  u8 wrFlag;            /* The wrFlag argument to sqlite3BtreeCursor() */
    85     87   #endif
    86     88     Bool isEphemeral:1;   /* True for an ephemeral table */
    87     89     Bool useRandomRowid:1;/* Generate new record numbers semi-randomly */
    88     90     Bool isOrdered:1;     /* True if the underlying table is BTREE_UNORDERED */
    89     91     Pgno pgnoRoot;        /* Root page of the open btree cursor */
    90     92     i16 nField;           /* Number of fields in the header */
    91     93     u16 nHdrParsed;       /* Number of header fields parsed so far */
................................................................................
    96     98       VdbeSorter *pSorter;        /* CURTYPE_SORTER. Sorter object */
    97     99     } uc;
    98    100     Btree *pBt;           /* Separate file holding temporary table */
    99    101     KeyInfo *pKeyInfo;    /* Info about index keys needed by index cursors */
   100    102     int seekResult;       /* Result of previous sqlite3BtreeMoveto() */
   101    103     i64 seqCount;         /* Sequence counter */
   102    104     i64 movetoTarget;     /* Argument to the deferred sqlite3BtreeMoveto() */
          105  +  VdbeCursor *pAltCursor; /* Associated index cursor from which to read */
          106  +  int *aAltMap;           /* Mapping from table to index column numbers */
   103    107   #ifdef SQLITE_ENABLE_COLUMN_USED_MASK
   104    108     u64 maskUsed;         /* Mask of columns used by this cursor */
   105    109   #endif
   106    110   
   107    111     /* Cached information about the header for the data record that the
   108    112     ** cursor is currently pointing to.  Only valid if cacheStatus matches
   109    113     ** Vdbe.cacheCtr.  Vdbe.cacheCtr will never take on the value of
................................................................................
   120    124     const u8 *aRow;       /* Data for the current row, if all on one page */
   121    125     u32 *aOffset;         /* Pointer to aType[nField] */
   122    126     u32 aType[1];         /* Type values for all entries in the record */
   123    127     /* 2*nField extra array elements allocated for aType[], beyond the one
   124    128     ** static element declared in the structure.  nField total array slots for
   125    129     ** aType[] and nField+1 array slots for aOffset[] */
   126    130   };
   127         -typedef struct VdbeCursor VdbeCursor;
   128    131   
   129    132   /*
   130    133   ** When a sub-program is executed (OP_Program), a structure of this type
   131    134   ** is allocated to store the current value of the program counter, as
   132    135   ** well as the current memory cell array and various other frame specific
   133    136   ** values stored in the Vdbe struct. When the sub-program is finished, 
   134    137   ** these values are copied back to the Vdbe from the VdbeFrame structure,
................................................................................
   231    234   #define MEM_Real      0x0008   /* Value is a real number */
   232    235   #define MEM_Blob      0x0010   /* Value is a BLOB */
   233    236   #define MEM_AffMask   0x001f   /* Mask of affinity bits */
   234    237   #define MEM_RowSet    0x0020   /* Value is a RowSet object */
   235    238   #define MEM_Frame     0x0040   /* Value is a VdbeFrame object */
   236    239   #define MEM_Undefined 0x0080   /* Value is undefined */
   237    240   #define MEM_Cleared   0x0100   /* NULL set by OP_Null, not from data */
   238         -#define MEM_TypeMask  0x01ff   /* Mask of type bits */
          241  +#define MEM_TypeMask  0x81ff   /* Mask of type bits */
   239    242   
   240    243   
   241    244   /* Whenever Mem contains a valid string or blob representation, one of
   242    245   ** the following flags must be set to determine the memory management
   243    246   ** policy for Mem.z.  The MEM_Term flag tells us whether or not the
   244    247   ** string is \000 or \u0000 terminated
   245    248   */
   246    249   #define MEM_Term      0x0200   /* String rep is nul terminated */
   247    250   #define MEM_Dyn       0x0400   /* Need to call Mem.xDel() on Mem.z */
   248    251   #define MEM_Static    0x0800   /* Mem.z points to a static string */
   249    252   #define MEM_Ephem     0x1000   /* Mem.z points to an ephemeral string */
   250    253   #define MEM_Agg       0x2000   /* Mem.z points to an agg function context */
   251    254   #define MEM_Zero      0x4000   /* Mem.i contains count of 0s appended to blob */
          255  +#define MEM_Subtype   0x8000   /* Mem.eSubtype is valid */
   252    256   #ifdef SQLITE_OMIT_INCRBLOB
   253    257     #undef MEM_Zero
   254    258     #define MEM_Zero 0x0000
   255    259   #endif
          260  +
          261  +/* Return TRUE if Mem X contains dynamically allocated content - anything
          262  +** that needs to be deallocated to avoid a leak.
          263  +*/
          264  +#define VdbeMemDynamic(X)  \
          265  +  (((X)->flags&(MEM_Agg|MEM_Dyn|MEM_RowSet|MEM_Frame))!=0)
   256    266   
   257    267   /*
   258    268   ** Clear any existing type flags from a Mem and replace them with f
   259    269   */
   260    270   #define MemSetTypeFlag(p, f) \
   261    271      ((p)->flags = ((p)->flags&~(MEM_TypeMask|MEM_Zero))|f)
   262    272   
................................................................................
   419    429   
   420    430   /*
   421    431   ** Function prototypes
   422    432   */
   423    433   void sqlite3VdbeError(Vdbe*, const char *, ...);
   424    434   void sqlite3VdbeFreeCursor(Vdbe *, VdbeCursor*);
   425    435   void sqliteVdbePopStack(Vdbe*,int);
   426         -int sqlite3VdbeCursorMoveto(VdbeCursor*);
          436  +int sqlite3VdbeCursorMoveto(VdbeCursor**, int*);
   427    437   int sqlite3VdbeCursorRestore(VdbeCursor*);
   428    438   #if defined(SQLITE_DEBUG) || defined(VDBE_PROFILE)
   429    439   void sqlite3VdbePrintOp(FILE*, int, Op*);
   430    440   #endif
   431    441   u32 sqlite3VdbeSerialTypeLen(u32);
   432    442   u8 sqlite3VdbeOneByteSerialTypeLen(u8);
   433    443   u32 sqlite3VdbeSerialType(Mem*, int, u32*);
................................................................................
   465    475   double sqlite3VdbeRealValue(Mem*);
   466    476   void sqlite3VdbeIntegerAffinity(Mem*);
   467    477   int sqlite3VdbeMemRealify(Mem*);
   468    478   int sqlite3VdbeMemNumerify(Mem*);
   469    479   void sqlite3VdbeMemCast(Mem*,u8,u8);
   470    480   int sqlite3VdbeMemFromBtree(BtCursor*,u32,u32,int,Mem*);
   471    481   void sqlite3VdbeMemRelease(Mem *p);
   472         -#define VdbeMemDynamic(X)  \
   473         -  (((X)->flags&(MEM_Agg|MEM_Dyn|MEM_RowSet|MEM_Frame))!=0)
   474    482   int sqlite3VdbeMemFinalize(Mem*, FuncDef*);
   475    483   const char *sqlite3OpcodeName(int);
   476    484   int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve);
   477    485   int sqlite3VdbeMemClearAndResize(Mem *pMem, int n);
   478    486   int sqlite3VdbeCloseStatement(Vdbe *, int);
   479    487   void sqlite3VdbeFrameDelete(VdbeFrame*);
   480    488   int sqlite3VdbeFrameRestore(VdbeFrame *);

Changes to src/vdbeapi.c.

   200    200   int sqlite3_value_int(sqlite3_value *pVal){
   201    201     return (int)sqlite3VdbeIntValue((Mem*)pVal);
   202    202   }
   203    203   sqlite_int64 sqlite3_value_int64(sqlite3_value *pVal){
   204    204     return sqlite3VdbeIntValue((Mem*)pVal);
   205    205   }
   206    206   unsigned int sqlite3_value_subtype(sqlite3_value *pVal){
   207         -  return ((Mem*)pVal)->eSubtype;
          207  +  Mem *pMem = (Mem*)pVal;
          208  +  return ((pMem->flags & MEM_Subtype) ? pMem->eSubtype : 0);
   208    209   }
   209    210   const unsigned char *sqlite3_value_text(sqlite3_value *pVal){
   210    211     return (const unsigned char *)sqlite3ValueText(pVal, SQLITE_UTF8);
   211    212   }
   212    213   #ifndef SQLITE_OMIT_UTF16
   213    214   const void *sqlite3_value_text16(sqlite3_value* pVal){
   214    215     return sqlite3ValueText(pVal, SQLITE_UTF16NATIVE);
................................................................................
   381    382     sqlite3VdbeMemSetInt64(pCtx->pOut, iVal);
   382    383   }
   383    384   void sqlite3_result_null(sqlite3_context *pCtx){
   384    385     assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
   385    386     sqlite3VdbeMemSetNull(pCtx->pOut);
   386    387   }
   387    388   void sqlite3_result_subtype(sqlite3_context *pCtx, unsigned int eSubtype){
   388         -  assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) );
   389         -  pCtx->pOut->eSubtype = eSubtype & 0xff;
          389  +  Mem *pOut = pCtx->pOut;
          390  +  assert( sqlite3_mutex_held(pOut->db->mutex) );
          391  +  pOut->eSubtype = eSubtype & 0xff;
          392  +  pOut->flags |= MEM_Subtype;
   390    393   }
   391    394   void sqlite3_result_text(
   392    395     sqlite3_context *pCtx, 
   393    396     const char *z, 
   394    397     int n,
   395    398     void (*xDel)(void *)
   396    399   ){

Changes to src/vdbeaux.c.

   167    167   }
   168    168   int sqlite3VdbeAddOp3(Vdbe *p, int op, int p1, int p2, int p3){
   169    169     int i;
   170    170     VdbeOp *pOp;
   171    171   
   172    172     i = p->nOp;
   173    173     assert( p->magic==VDBE_MAGIC_INIT );
   174         -  assert( op>0 && op<0xff );
          174  +  assert( op>=0 && op<0xff );
   175    175     if( p->pParse->nOpAlloc<=i ){
   176    176       return growOp3(p, op, p1, p2, p3);
   177    177     }
   178    178     p->nOp++;
   179    179     pOp = &p->aOp[i];
   180    180     pOp->opcode = (u8)op;
   181    181     pOp->p5 = 0;
................................................................................
   530    530     Parse *pParse = p->pParse;
   531    531     int *aLabel = pParse->aLabel;
   532    532     p->readOnly = 1;
   533    533     p->bIsReader = 0;
   534    534     for(pOp=p->aOp, i=p->nOp-1; i>=0; i--, pOp++){
   535    535       u8 opcode = pOp->opcode;
   536    536   
   537         -    /* NOTE: Be sure to update mkopcodeh.awk when adding or removing
          537  +    /* NOTE: Be sure to update mkopcodeh.tcl when adding or removing
   538    538       ** cases from this switch! */
   539    539       switch( opcode ){
   540    540         case OP_Transaction: {
   541    541           if( pOp->p2!=0 ) p->readOnly = 0;
   542    542           /* fall thru */
   543    543         }
   544    544         case OP_AutoCommit:
................................................................................
  1113   1113   #endif /* SQLITE_DEBUG */
  1114   1114   
  1115   1115   #if VDBE_DISPLAY_P4 && defined(SQLITE_ENABLE_CURSOR_HINTS)
  1116   1116   /*
  1117   1117   ** Translate the P4.pExpr value for an OP_CursorHint opcode into text
  1118   1118   ** that can be displayed in the P4 column of EXPLAIN output.
  1119   1119   */
  1120         -static int displayP4Expr(int nTemp, char *zTemp, Expr *pExpr){
         1120  +static void displayP4Expr(StrAccum *p, Expr *pExpr){
  1121   1121     const char *zOp = 0;
  1122         -  int n;
  1123   1122     switch( pExpr->op ){
  1124   1123       case TK_STRING:
  1125         -      sqlite3_snprintf(nTemp, zTemp, "%Q", pExpr->u.zToken);
         1124  +      sqlite3XPrintf(p, "%Q", pExpr->u.zToken);
  1126   1125         break;
  1127   1126       case TK_INTEGER:
  1128         -      sqlite3_snprintf(nTemp, zTemp, "%d", pExpr->u.iValue);
         1127  +      sqlite3XPrintf(p, "%d", pExpr->u.iValue);
  1129   1128         break;
  1130   1129       case TK_NULL:
  1131         -      sqlite3_snprintf(nTemp, zTemp, "NULL");
         1130  +      sqlite3XPrintf(p, "NULL");
  1132   1131         break;
  1133   1132       case TK_REGISTER: {
  1134         -      sqlite3_snprintf(nTemp, zTemp, "r[%d]", pExpr->iTable);
         1133  +      sqlite3XPrintf(p, "r[%d]", pExpr->iTable);
  1135   1134         break;
  1136   1135       }
  1137   1136       case TK_COLUMN: {
  1138   1137         if( pExpr->iColumn<0 ){
  1139         -        sqlite3_snprintf(nTemp, zTemp, "rowid");
         1138  +        sqlite3XPrintf(p, "rowid");
  1140   1139         }else{
  1141         -        sqlite3_snprintf(nTemp, zTemp, "c%d", (int)pExpr->iColumn);
         1140  +        sqlite3XPrintf(p, "c%d", (int)pExpr->iColumn);
  1142   1141         }
  1143   1142         break;
  1144   1143       }
  1145   1144       case TK_LT:      zOp = "LT";      break;
  1146   1145       case TK_LE:      zOp = "LE";      break;
  1147   1146       case TK_GT:      zOp = "GT";      break;
  1148   1147       case TK_GE:      zOp = "GE";      break;
................................................................................
  1166   1165       case TK_UPLUS:   zOp = "PLUS";    break;
  1167   1166       case TK_BITNOT:  zOp = "BITNOT";  break;
  1168   1167       case TK_NOT:     zOp = "NOT";     break;
  1169   1168       case TK_ISNULL:  zOp = "ISNULL";  break;
  1170   1169       case TK_NOTNULL: zOp = "NOTNULL"; break;
  1171   1170   
  1172   1171       default:
  1173         -      sqlite3_snprintf(nTemp, zTemp, "%s", "expr");
         1172  +      sqlite3XPrintf(p, "%s", "expr");
  1174   1173         break;
  1175   1174     }
  1176   1175   
  1177   1176     if( zOp ){
  1178         -    sqlite3_snprintf(nTemp, zTemp, "%s(", zOp);
  1179         -    n = sqlite3Strlen30(zTemp);
  1180         -    n += displayP4Expr(nTemp-n, zTemp+n, pExpr->pLeft);
  1181         -    if( n<nTemp-1 && pExpr->pRight ){
  1182         -      zTemp[n++] = ',';
  1183         -      n += displayP4Expr(nTemp-n, zTemp+n, pExpr->pRight);
         1177  +    sqlite3XPrintf(p, "%s(", zOp);
         1178  +    displayP4Expr(p, pExpr->pLeft);
         1179  +    if( pExpr->pRight ){
         1180  +      sqlite3StrAccumAppend(p, ",", 1);
         1181  +      displayP4Expr(p, pExpr->pRight);
  1184   1182       }
  1185         -    sqlite3_snprintf(nTemp-n, zTemp+n, ")");
         1183  +    sqlite3StrAccumAppend(p, ")", 1);
  1186   1184     }
  1187         -  return sqlite3Strlen30(zTemp);
  1188   1185   }
  1189   1186   #endif /* VDBE_DISPLAY_P4 && defined(SQLITE_ENABLE_CURSOR_HINTS) */
  1190   1187   
  1191   1188   
  1192   1189   #if VDBE_DISPLAY_P4
  1193   1190   /*
  1194   1191   ** Compute a string that describes the P4 parameter for an opcode.
  1195   1192   ** Use zTemp for any required temporary buffer space.
  1196   1193   */
  1197   1194   static char *displayP4(Op *pOp, char *zTemp, int nTemp){
  1198   1195     char *zP4 = zTemp;
         1196  +  StrAccum x;
  1199   1197     assert( nTemp>=20 );
         1198  +  sqlite3StrAccumInit(&x, 0, zTemp, nTemp, 0);
  1200   1199     switch( pOp->p4type ){
  1201   1200       case P4_KEYINFO: {
  1202         -      int i, j;
         1201  +      int j;
  1203   1202         KeyInfo *pKeyInfo = pOp->p4.pKeyInfo;
  1204   1203         assert( pKeyInfo->aSortOrder!=0 );
  1205         -      sqlite3_snprintf(nTemp, zTemp, "k(%d", pKeyInfo->nField);
  1206         -      i = sqlite3Strlen30(zTemp);
         1204  +      sqlite3XPrintf(&x, "k(%d", pKeyInfo->nField);
  1207   1205         for(j=0; j<pKeyInfo->nField; j++){
  1208   1206           CollSeq *pColl = pKeyInfo->aColl[j];
  1209         -        const char *zColl = pColl ? pColl->zName : "nil";
  1210         -        int n = sqlite3Strlen30(zColl);
  1211         -        if( n==6 && memcmp(zColl,"BINARY",6)==0 ){
  1212         -          zColl = "B";
  1213         -          n = 1;
  1214         -        }
  1215         -        if( i+n>nTemp-7 ){
  1216         -          memcpy(&zTemp[i],",...",4);
  1217         -          i += 4;
  1218         -          break;
  1219         -        }
  1220         -        zTemp[i++] = ',';
  1221         -        if( pKeyInfo->aSortOrder[j] ){
  1222         -          zTemp[i++] = '-';
  1223         -        }
  1224         -        memcpy(&zTemp[i], zColl, n+1);
  1225         -        i += n;
         1207  +        const char *zColl = pColl ? pColl->zName : "";
         1208  +        if( strcmp(zColl, "BINARY")==0 ) zColl = "B";
         1209  +        sqlite3XPrintf(&x, ",%s%s", pKeyInfo->aSortOrder[j] ? "-" : "", zColl);
  1226   1210         }
  1227         -      zTemp[i++] = ')';
  1228         -      zTemp[i] = 0;
  1229         -      assert( i<nTemp );
         1211  +      sqlite3StrAccumAppend(&x, ")", 1);
  1230   1212         break;
  1231   1213       }
  1232   1214   #ifdef SQLITE_ENABLE_CURSOR_HINTS
  1233   1215       case P4_EXPR: {
  1234         -      displayP4Expr(nTemp, zTemp, pOp->p4.pExpr);
         1216  +      displayP4Expr(&x, pOp->p4.pExpr);
  1235   1217         break;
  1236   1218       }
  1237   1219   #endif
  1238   1220       case P4_COLLSEQ: {
  1239   1221         CollSeq *pColl = pOp->p4.pColl;
  1240         -      sqlite3_snprintf(nTemp, zTemp, "(%.20s)", pColl->zName);
         1222  +      sqlite3XPrintf(&x, "(%.20s)", pColl->zName);
  1241   1223         break;
  1242   1224       }
  1243   1225       case P4_FUNCDEF: {
  1244   1226         FuncDef *pDef = pOp->p4.pFunc;
  1245         -      sqlite3_snprintf(nTemp, zTemp, "%s(%d)", pDef->zName, pDef->nArg);
         1227  +      sqlite3XPrintf(&x, "%s(%d)", pDef->zName, pDef->nArg);
  1246   1228         break;
  1247   1229       }
  1248   1230   #ifdef SQLITE_DEBUG
  1249   1231       case P4_FUNCCTX: {
  1250   1232         FuncDef *pDef = pOp->p4.pCtx->pFunc;
  1251         -      sqlite3_snprintf(nTemp, zTemp, "%s(%d)", pDef->zName, pDef->nArg);
         1233  +      sqlite3XPrintf(&x, "%s(%d)", pDef->zName, pDef->nArg);
  1252   1234         break;
  1253   1235       }
  1254   1236   #endif
  1255   1237       case P4_INT64: {
  1256         -      sqlite3_snprintf(nTemp, zTemp, "%lld", *pOp->p4.pI64);
         1238  +      sqlite3XPrintf(&x, "%lld", *pOp->p4.pI64);
  1257   1239         break;
  1258   1240       }
  1259   1241       case P4_INT32: {
  1260         -      sqlite3_snprintf(nTemp, zTemp, "%d", pOp->p4.i);
         1242  +      sqlite3XPrintf(&x, "%d", pOp->p4.i);
  1261   1243         break;
  1262   1244       }
  1263   1245       case P4_REAL: {
  1264         -      sqlite3_snprintf(nTemp, zTemp, "%.16g", *pOp->p4.pReal);
         1246  +      sqlite3XPrintf(&x, "%.16g", *pOp->p4.pReal);
  1265   1247         break;
  1266   1248       }
  1267   1249       case P4_MEM: {
  1268   1250         Mem *pMem = pOp->p4.pMem;
  1269   1251         if( pMem->flags & MEM_Str ){
  1270   1252           zP4 = pMem->z;
  1271   1253         }else if( pMem->flags & MEM_Int ){
  1272         -        sqlite3_snprintf(nTemp, zTemp, "%lld", pMem->u.i);
         1254  +        sqlite3XPrintf(&x, "%lld", pMem->u.i);
  1273   1255         }else if( pMem->flags & MEM_Real ){
  1274         -        sqlite3_snprintf(nTemp, zTemp, "%.16g", pMem->u.r);
         1256  +        sqlite3XPrintf(&x, "%.16g", pMem->u.r);
  1275   1257         }else if( pMem->flags & MEM_Null ){
  1276         -        sqlite3_snprintf(nTemp, zTemp, "NULL");
         1258  +        zP4 = "NULL";
  1277   1259         }else{
  1278   1260           assert( pMem->flags & MEM_Blob );
  1279   1261           zP4 = "(blob)";
  1280   1262         }
  1281   1263         break;
  1282   1264       }
  1283   1265   #ifndef SQLITE_OMIT_VIRTUALTABLE
  1284   1266       case P4_VTAB: {
  1285   1267         sqlite3_vtab *pVtab = pOp->p4.pVtab->pVtab;
  1286         -      sqlite3_snprintf(nTemp, zTemp, "vtab:%p", pVtab);
         1268  +      sqlite3XPrintf(&x, "vtab:%p", pVtab);
  1287   1269         break;
  1288   1270       }
  1289   1271   #endif
  1290   1272       case P4_INTARRAY: {
  1291         -      sqlite3_snprintf(nTemp, zTemp, "intarray");
         1273  +      int i;
         1274  +      int *ai = pOp->p4.ai;
         1275  +      int n = ai[0];   /* The first element of an INTARRAY is always the
         1276  +                       ** count of the number of elements to follow */
         1277  +      for(i=1; i<n; i++){
         1278  +        sqlite3XPrintf(&x, ",%d", ai[i]);
         1279  +      }
         1280  +      zTemp[0] = '[';
         1281  +      sqlite3StrAccumAppend(&x, "]", 1);
  1292   1282         break;
  1293   1283       }
  1294   1284       case P4_SUBPROGRAM: {
  1295         -      sqlite3_snprintf(nTemp, zTemp, "program");
         1285  +      sqlite3XPrintf(&x, "program");
  1296   1286         break;
  1297   1287       }
  1298   1288       case P4_ADVANCE: {
  1299   1289         zTemp[0] = 0;
  1300   1290         break;
  1301   1291       }
  1302   1292       default: {
................................................................................
  1303   1293         zP4 = pOp->p4.z;
  1304   1294         if( zP4==0 ){
  1305   1295           zP4 = zTemp;
  1306   1296           zTemp[0] = 0;
  1307   1297         }
  1308   1298       }
  1309   1299     }
         1300  +  sqlite3StrAccumFinish(&x);
  1310   1301     assert( zP4!=0 );
  1311   1302     return zP4;
  1312   1303   }
  1313   1304   #endif /* VDBE_DISPLAY_P4 */
  1314   1305   
  1315   1306   /*
  1316   1307   ** Declare to the Vdbe that the BTree object at db->aDb[i] is used.
................................................................................
  1717   1708       }
  1718   1709       z[j] = 0;
  1719   1710       sqlite3IoTrace("SQL %s\n", z);
  1720   1711     }
  1721   1712   }
  1722   1713   #endif /* !SQLITE_OMIT_TRACE && SQLITE_ENABLE_IOTRACE */
  1723   1714   
  1724         -/*
  1725         -** Allocate space from a fixed size buffer and return a pointer to
  1726         -** that space.  If insufficient space is available, return NULL.
  1727         -**
  1728         -** The pBuf parameter is the initial value of a pointer which will
  1729         -** receive the new memory.  pBuf is normally NULL.  If pBuf is not
  1730         -** NULL, it means that memory space has already been allocated and that
  1731         -** this routine should not allocate any new memory.  When pBuf is not
  1732         -** NULL simply return pBuf.  Only allocate new memory space when pBuf
  1733         -** is NULL.
  1734         -**
  1735         -** nByte is the number of bytes of space needed.
  1736         -**
  1737         -** pFrom points to *pnFrom bytes of available space.  New space is allocated
  1738         -** from the end of the pFrom buffer and *pnFrom is decremented.
  1739         -**
  1740         -** *pnNeeded is a counter of the number of bytes of space that have failed
  1741         -** to allocate.  If there is insufficient space in pFrom to satisfy the
  1742         -** request, then increment *pnNeeded by the amount of the request.
         1715  +/* An instance of this object describes bulk memory available for use
         1716  +** by subcomponents of a prepared statement.  Space is allocated out
         1717  +** of a ReusableSpace object by the allocSpace() routine below.
         1718  +*/
         1719  +struct ReusableSpace {
         1720  +  u8 *pSpace;          /* Available memory */
         1721  +  int nFree;           /* Bytes of available memory */
         1722  +  int nNeeded;         /* Total bytes that could not be allocated */
         1723  +};
         1724  +
         1725  +/* Try to allocate nByte bytes of 8-byte aligned bulk memory for pBuf
         1726  +** from the ReusableSpace object.  Return a pointer to the allocated
         1727  +** memory on success.  If insufficient memory is available in the
         1728  +** ReusableSpace object, increase the ReusableSpace.nNeeded
         1729  +** value by the amount needed and return NULL.
         1730  +**
         1731  +** If pBuf is not initially NULL, that means that the memory has already
         1732  +** been allocated by a prior call to this routine, so just return a copy
         1733  +** of pBuf and leave ReusableSpace unchanged.
         1734  +**
         1735  +** This allocator is employed to repurpose unused slots at the end of the
         1736  +** opcode array of prepared state for other memory needs of the prepared
         1737  +** statement.
  1743   1738   */
  1744   1739   static void *allocSpace(
  1745         -  void *pBuf,          /* Where return pointer will be stored */
  1746         -  int nByte,           /* Number of bytes to allocate */
  1747         -  u8 *pFrom,           /* Memory available for allocation */
  1748         -  int *pnFrom,         /* IN/OUT: Space available at pFrom */
  1749         -  int *pnNeeded        /* If allocation cannot be made, increment *pnByte */
         1740  +  struct ReusableSpace *p,  /* Bulk memory available for allocation */
         1741  +  void *pBuf,               /* Pointer to a prior allocation */
         1742  +  int nByte                 /* Bytes of memory needed */
  1750   1743   ){
  1751         -  assert( EIGHT_BYTE_ALIGNMENT(pFrom) );
         1744  +  assert( EIGHT_BYTE_ALIGNMENT(p->pSpace) );
  1752   1745     if( pBuf==0 ){
  1753   1746       nByte = ROUND8(nByte);
  1754         -    if( nByte <= *pnFrom ){
  1755         -      *pnFrom -= nByte;
  1756         -      pBuf = &pFrom[*pnFrom];
         1747  +    if( nByte <= p->nFree ){
         1748  +      p->nFree -= nByte;
         1749  +      pBuf = &p->pSpace[p->nFree];
  1757   1750       }else{
  1758         -      *pnNeeded += nByte;
         1751  +      p->nNeeded += nByte;
  1759   1752       }
  1760   1753     }
  1761   1754     assert( EIGHT_BYTE_ALIGNMENT(pBuf) );
  1762   1755     return pBuf;
  1763   1756   }
  1764   1757   
  1765   1758   /*
................................................................................
  1784   1777     for(i=1; i<p->nMem; i++){
  1785   1778       assert( p->aMem[i].db==p->db );
  1786   1779     }
  1787   1780   #endif
  1788   1781     p->pc = -1;
  1789   1782     p->rc = SQLITE_OK;
  1790   1783     p->errorAction = OE_Abort;
  1791         -  p->magic = VDBE_MAGIC_RUN;
  1792   1784     p->nChange = 0;
  1793   1785     p->cacheCtr = 1;
  1794   1786     p->minWriteFileFormat = 255;
  1795   1787     p->iStatement = 0;
  1796   1788     p->nFkConstraint = 0;
  1797   1789   #ifdef VDBE_PROFILE
  1798   1790     for(i=0; i<p->nOp; i++){
................................................................................
  1827   1819     sqlite3 *db;                   /* The database connection */
  1828   1820     int nVar;                      /* Number of parameters */
  1829   1821     int nMem;                      /* Number of VM memory registers */
  1830   1822     int nCursor;                   /* Number of cursors required */
  1831   1823     int nArg;                      /* Number of arguments in subprograms */
  1832   1824     int nOnce;                     /* Number of OP_Once instructions */
  1833   1825     int n;                         /* Loop counter */
  1834         -  int nFree;                     /* Available free space */
  1835         -  u8 *zCsr;                      /* Memory available for allocation */
  1836         -  int nByte;                     /* How much extra memory is needed */
         1826  +  struct ReusableSpace x;        /* Reusable bulk memory */
  1837   1827   
  1838   1828     assert( p!=0 );
  1839   1829     assert( p->nOp>0 );
  1840   1830     assert( pParse!=0 );
  1841   1831     assert( p->magic==VDBE_MAGIC_INIT );
  1842   1832     assert( pParse==p->pParse );
  1843   1833     db = p->db;
................................................................................
  1847   1837     nCursor = pParse->nTab;
  1848   1838     nArg = pParse->nMaxArg;
  1849   1839     nOnce = pParse->nOnce;
  1850   1840     if( nOnce==0 ) nOnce = 1; /* Ensure at least one byte in p->aOnceFlag[] */
  1851   1841     
  1852   1842     /* For each cursor required, also allocate a memory cell. Memory
  1853   1843     ** cells (nMem+1-nCursor)..nMem, inclusive, will never be used by
  1854         -  ** the vdbe program. Instead they are used to allocate space for
         1844  +  ** the vdbe program. Instead they are used to allocate memory for
  1855   1845     ** VdbeCursor/BtCursor structures. The blob of memory associated with 
  1856   1846     ** cursor 0 is stored in memory cell nMem. Memory cell (nMem-1)
  1857   1847     ** stores the blob of memory associated with cursor 1, etc.
  1858   1848     **
  1859   1849     ** See also: allocateCursor().
  1860   1850     */
  1861   1851     nMem += nCursor;
  1862   1852   
  1863         -  /* zCsr will initially point to nFree bytes of unused space at the
  1864         -  ** end of the opcode array, p->aOp.  The computation of nFree is
  1865         -  ** conservative - it might be smaller than the true number of free
  1866         -  ** bytes, but never larger.  nFree must be a multiple of 8 - it is
  1867         -  ** rounded down if is not.
         1853  +  /* Figure out how much reusable memory is available at the end of the
         1854  +  ** opcode array.  This extra memory will be reallocated for other elements
         1855  +  ** of the prepared statement.
  1868   1856     */
  1869         -  n = ROUND8(sizeof(Op)*p->nOp);              /* Bytes of opcode space used */
  1870         -  zCsr = &((u8*)p->aOp)[n];                   /* Unused opcode space */
  1871         -  assert( EIGHT_BYTE_ALIGNMENT(zCsr) );
  1872         -  nFree = ROUNDDOWN8(pParse->szOpAlloc - n);  /* Bytes of unused space */
  1873         -  assert( nFree>=0 );
  1874         -  if( nFree>0 ){
  1875         -    memset(zCsr, 0, nFree);
  1876         -    assert( EIGHT_BYTE_ALIGNMENT(&zCsr[nFree]) );
         1857  +  n = ROUND8(sizeof(Op)*p->nOp);              /* Bytes of opcode memory used */
         1858  +  x.pSpace = &((u8*)p->aOp)[n];               /* Unused opcode memory */
         1859  +  assert( EIGHT_BYTE_ALIGNMENT(x.pSpace) );
         1860  +  x.nFree = ROUNDDOWN8(pParse->szOpAlloc - n);  /* Bytes of unused memory */
         1861  +  assert( x.nFree>=0 );
         1862  +  if( x.nFree>0 ){
         1863  +    memset(x.pSpace, 0, x.nFree);
         1864  +    assert( EIGHT_BYTE_ALIGNMENT(&x.pSpace[x.nFree]) );
  1877   1865     }
  1878   1866   
  1879   1867     resolveP2Values(p, &nArg);
  1880   1868     p->usesStmtJournal = (u8)(pParse->isMultiWrite && pParse->mayAbort);
  1881   1869     if( pParse->explain && nMem<10 ){
  1882   1870       nMem = 10;
  1883   1871     }
  1884   1872     p->expired = 0;
  1885   1873   
  1886         -  p->expired = 0;
  1887         -  
  1888         -  /* Memory for registers, parameters, cursor, etc, is allocated in two
  1889         -  ** passes.  On the first pass, we try to reuse unused space at the 
         1874  +  /* Memory for registers, parameters, cursor, etc, is allocated in one or two
         1875  +  ** passes.  On the first pass, we try to reuse unused memory at the 
  1890   1876     ** end of the opcode array.  If we are unable to satisfy all memory
  1891   1877     ** requirements by reusing the opcode array tail, then the second
  1892         -  ** pass will fill in the rest using a fresh allocation.  
         1878  +  ** pass will fill in the remainder using a fresh memory allocation.  
  1893   1879     **
  1894   1880     ** This two-pass approach that reuses as much memory as possible from
  1895         -  ** the leftover space at the end of the opcode array can significantly
         1881  +  ** the leftover memory at the end of the opcode array.  This can significantly
  1896   1882     ** reduce the amount of memory held by a prepared statement.
  1897   1883     */
  1898   1884     do {
  1899         -    nByte = 0;
  1900         -    p->aMem = allocSpace(p->aMem, nMem*sizeof(Mem), zCsr, &nFree, &nByte);
  1901         -    p->aVar = allocSpace(p->aVar, nVar*sizeof(Mem), zCsr, &nFree, &nByte);
  1902         -    p->apArg = allocSpace(p->apArg, nArg*sizeof(Mem*), zCsr, &nFree, &nByte);
  1903         -    p->apCsr = allocSpace(p->apCsr, nCursor*sizeof(VdbeCursor*),
  1904         -                          zCsr, &nFree, &nByte);
  1905         -    p->aOnceFlag = allocSpace(p->aOnceFlag, nOnce, zCsr, &nFree, &nByte);
         1885  +    x.nNeeded = 0;
         1886  +    p->aMem = allocSpace(&x, p->aMem, nMem*sizeof(Mem));
         1887  +    p->aVar = allocSpace(&x, p->aVar, nVar*sizeof(Mem));
         1888  +    p->apArg = allocSpace(&x, p->apArg, nArg*sizeof(Mem*));
         1889  +    p->apCsr = allocSpace(&x, p->apCsr, nCursor*sizeof(VdbeCursor*));
         1890  +    p->aOnceFlag = allocSpace(&x, p->aOnceFlag, nOnce);
  1906   1891   #ifdef SQLITE_ENABLE_STMT_SCANSTATUS
  1907         -    p->anExec = allocSpace(p->anExec, p->nOp*sizeof(i64), zCsr, &nFree, &nByte);
         1892  +    p->anExec = allocSpace(&x, p->anExec, p->nOp*sizeof(i64));
  1908   1893   #endif
  1909         -    if( nByte ){
  1910         -      p->pFree = sqlite3DbMallocZero(db, nByte);
  1911         -    }
  1912         -    zCsr = p->pFree;
  1913         -    nFree = nByte;
  1914         -  }while( nByte && !db->mallocFailed );
         1894  +    if( x.nNeeded==0 ) break;
         1895  +    x.pSpace = p->pFree = sqlite3DbMallocZero(db, x.nNeeded);
         1896  +    x.nFree = x.nNeeded;
         1897  +  }while( !db->mallocFailed );
  1915   1898   
  1916   1899     p->nCursor = nCursor;
  1917   1900     p->nOnceFlag = nOnce;
  1918   1901     if( p->aVar ){
  1919   1902       p->nVar = (ynVar)nVar;
  1920   1903       for(n=0; n<nVar; n++){
  1921   1904         p->aVar[n].flags = MEM_Null;
................................................................................
  3012   2995   ** MoveTo now.  If no move is pending, check to see if the row has been
  3013   2996   ** deleted out from under the cursor and if it has, mark the row as
  3014   2997   ** a NULL row.
  3015   2998   **
  3016   2999   ** If the cursor is already pointing to the correct row and that row has
  3017   3000   ** not been deleted out from under the cursor, then this routine is a no-op.
  3018   3001   */
  3019         -int sqlite3VdbeCursorMoveto(VdbeCursor *p){
         3002  +int sqlite3VdbeCursorMoveto(VdbeCursor **pp, int *piCol){
         3003  +  VdbeCursor *p = *pp;
  3020   3004     if( p->eCurType==CURTYPE_BTREE ){
  3021   3005       if( p->deferredMoveto ){
         3006  +      int iMap;
         3007  +      if( p->aAltMap && (iMap = p->aAltMap[1+*piCol])>0 ){
         3008  +        *pp = p->pAltCursor;
         3009  +        *piCol = iMap - 1;
         3010  +        return SQLITE_OK;
         3011  +      }
  3022   3012         return handleDeferredMoveto(p);
  3023   3013       }
  3024   3014       if( sqlite3BtreeCursorHasMoved(p->uc.pCursor) ){
  3025   3015         return handleMovedCursor(p);
  3026   3016       }
  3027   3017     }
  3028   3018     return SQLITE_OK;

Changes to src/vdbesort.c.

  1817   1817     }
  1818   1818   
  1819   1819     if( pSorter->list.aMemory ){
  1820   1820       int nMin = pSorter->iMemory + nReq;
  1821   1821   
  1822   1822       if( nMin>pSorter->nMemory ){
  1823   1823         u8 *aNew;
         1824  +      int iListOff = (u8*)pSorter->list.pList - pSorter->list.aMemory;
  1824   1825         int nNew = pSorter->nMemory * 2;
  1825   1826         while( nNew < nMin ) nNew = nNew*2;
  1826   1827         if( nNew > pSorter->mxPmaSize ) nNew = pSorter->mxPmaSize;
  1827   1828         if( nNew < nMin ) nNew = nMin;
  1828   1829   
  1829   1830         aNew = sqlite3Realloc(pSorter->list.aMemory, nNew);
  1830   1831         if( !aNew ) return SQLITE_NOMEM;
  1831         -      pSorter->list.pList = (SorterRecord*)(
  1832         -          aNew + ((u8*)pSorter->list.pList - pSorter->list.aMemory)
  1833         -      );
         1832  +      pSorter->list.pList = (SorterRecord*)&aNew[iListOff];
  1834   1833         pSorter->list.aMemory = aNew;
  1835   1834         pSorter->nMemory = nNew;
  1836   1835       }
  1837   1836   
  1838   1837       pNew = (SorterRecord*)&pSorter->list.aMemory[pSorter->iMemory];
  1839   1838       pSorter->iMemory += ROUND8(nReq);
  1840         -    pNew->u.iNext = (int)((u8*)(pSorter->list.pList) - pSorter->list.aMemory);
         1839  +    if( pSorter->list.pList ){
         1840  +      pNew->u.iNext = (int)((u8*)(pSorter->list.pList) - pSorter->list.aMemory);
         1841  +    }
  1841   1842     }else{
  1842   1843       pNew = (SorterRecord *)sqlite3Malloc(nReq);
  1843   1844       if( pNew==0 ){
  1844   1845         return SQLITE_NOMEM;
  1845   1846       }
  1846   1847       pNew->u.pNext = pSorter->list.pList;
  1847   1848     }

Changes to src/vdbetrace.c.

   124    124         zRawSql += nToken;
   125    125         nextIndex = idx + 1;
   126    126         assert( idx>0 && idx<=p->nVar );
   127    127         pVar = &p->aVar[idx-1];
   128    128         if( pVar->flags & MEM_Null ){
   129    129           sqlite3StrAccumAppend(&out, "NULL", 4);
   130    130         }else if( pVar->flags & MEM_Int ){
   131         -        sqlite3XPrintf(&out, 0, "%lld", pVar->u.i);
          131  +        sqlite3XPrintf(&out, "%lld", pVar->u.i);
   132    132         }else if( pVar->flags & MEM_Real ){
   133         -        sqlite3XPrintf(&out, 0, "%!.15g", pVar->u.r);
          133  +        sqlite3XPrintf(&out, "%!.15g", pVar->u.r);
   134    134         }else if( pVar->flags & MEM_Str ){
   135    135           int nOut;  /* Number of bytes of the string text to include in output */
   136    136   #ifndef SQLITE_OMIT_UTF16
   137    137           u8 enc = ENC(db);
   138    138           Mem utf8;
   139    139           if( enc!=SQLITE_UTF8 ){
   140    140             memset(&utf8, 0, sizeof(utf8));
................................................................................
   147    147           nOut = pVar->n;
   148    148   #ifdef SQLITE_TRACE_SIZE_LIMIT
   149    149           if( nOut>SQLITE_TRACE_SIZE_LIMIT ){
   150    150             nOut = SQLITE_TRACE_SIZE_LIMIT;
   151    151             while( nOut<pVar->n && (pVar->z[nOut]&0xc0)==0x80 ){ nOut++; }
   152    152           }
   153    153   #endif    
   154         -        sqlite3XPrintf(&out, 0, "'%.*q'", nOut, pVar->z);
          154  +        sqlite3XPrintf(&out, "'%.*q'", nOut, pVar->z);
   155    155   #ifdef SQLITE_TRACE_SIZE_LIMIT
   156    156           if( nOut<pVar->n ){
   157         -          sqlite3XPrintf(&out, 0, "/*+%d bytes*/", pVar->n-nOut);
          157  +          sqlite3XPrintf(&out, "/*+%d bytes*/", pVar->n-nOut);
   158    158           }
   159    159   #endif
   160    160   #ifndef SQLITE_OMIT_UTF16
   161    161           if( enc!=SQLITE_UTF8 ) sqlite3VdbeMemRelease(&utf8);
   162    162   #endif
   163    163         }else if( pVar->flags & MEM_Zero ){
   164         -        sqlite3XPrintf(&out, 0, "zeroblob(%d)", pVar->u.nZero);
          164  +        sqlite3XPrintf(&out, "zeroblob(%d)", pVar->u.nZero);
   165    165         }else{
   166    166           int nOut;  /* Number of bytes of the blob to include in output */
   167    167           assert( pVar->flags & MEM_Blob );
   168    168           sqlite3StrAccumAppend(&out, "x'", 2);
   169    169           nOut = pVar->n;
   170    170   #ifdef SQLITE_TRACE_SIZE_LIMIT
   171    171           if( nOut>SQLITE_TRACE_SIZE_LIMIT ) nOut = SQLITE_TRACE_SIZE_LIMIT;
   172    172   #endif
   173    173           for(i=0; i<nOut; i++){
   174         -          sqlite3XPrintf(&out, 0, "%02x", pVar->z[i]&0xff);
          174  +          sqlite3XPrintf(&out, "%02x", pVar->z[i]&0xff);
   175    175           }
   176    176           sqlite3StrAccumAppend(&out, "'", 1);
   177    177   #ifdef SQLITE_TRACE_SIZE_LIMIT
   178    178           if( nOut<pVar->n ){
   179         -          sqlite3XPrintf(&out, 0, "/*+%d bytes*/", pVar->n-nOut);
          179  +          sqlite3XPrintf(&out, "/*+%d bytes*/", pVar->n-nOut);
   180    180           }
   181    181   #endif
   182    182         }
   183    183       }
   184    184     }
   185    185     return sqlite3StrAccumFinish(&out);
   186    186   }
   187    187   
   188    188   #endif /* #ifndef SQLITE_OMIT_TRACE */

Changes to src/vxworks.h.

    24     24   #define SQLITE_ENABLE_LOCKING_STYLE 0
    25     25   #define HAVE_UTIME 1
    26     26   #else
    27     27   /* This is not VxWorks. */
    28     28   #define OS_VXWORKS 0
    29     29   #define HAVE_FCHOWN 1
    30     30   #define HAVE_READLINK 1
           31  +#define HAVE_LSTAT 1
    31     32   #endif /* defined(_WRS_KERNEL) */

Changes to src/where.c.

  4010   4010     WhereLoopBuilder sWLB;     /* The WhereLoop builder */
  4011   4011     WhereMaskSet *pMaskSet;    /* The expression mask set */
  4012   4012     WhereLevel *pLevel;        /* A single level in pWInfo->a[] */
  4013   4013     WhereLoop *pLoop;          /* Pointer to a single WhereLoop object */
  4014   4014     int ii;                    /* Loop counter */
  4015   4015     sqlite3 *db;               /* Database connection */
  4016   4016     int rc;                    /* Return code */
  4017         -  u8 bFordelete = 0;
         4017  +  u8 bFordelete = 0;         /* OPFLAG_FORDELETE or zero, as appropriate */
  4018   4018   
  4019   4019     assert( (wctrlFlags & WHERE_ONEPASS_MULTIROW)==0 || (
  4020   4020           (wctrlFlags & WHERE_ONEPASS_DESIRED)!=0 
  4021   4021        && (wctrlFlags & WHERE_OMIT_OPEN_CLOSE)==0 
  4022   4022     ));
  4023   4023   
  4024   4024     /* Variable initialization */
................................................................................
  4255   4255       }
  4256   4256     }
  4257   4257     WHERETRACE(0xffff,("*** Optimizer Finished ***\n"));
  4258   4258     pWInfo->pParse->nQueryLoop += pWInfo->nRowOut;
  4259   4259   
  4260   4260     /* If the caller is an UPDATE or DELETE statement that is requesting
  4261   4261     ** to use a one-pass algorithm, determine if this is appropriate.
  4262         -  ** The one-pass algorithm only works if the WHERE clause constrains
  4263         -  ** the statement to update or delete a single row.
  4264   4262     */
  4265   4263     assert( (wctrlFlags & WHERE_ONEPASS_DESIRED)==0 || pWInfo->nLevel==1 );
  4266   4264     if( (wctrlFlags & WHERE_ONEPASS_DESIRED)!=0 ){
  4267   4265       int wsFlags = pWInfo->a[0].pWLoop->wsFlags;
  4268   4266       int bOnerow = (wsFlags & WHERE_ONEROW)!=0;
  4269         -    if( bOnerow || ( (wctrlFlags & WHERE_ONEPASS_MULTIROW)
  4270         -       && 0==(wsFlags & WHERE_VIRTUALTABLE)
  4271         -    )){
         4267  +    if( bOnerow
         4268  +     || ((wctrlFlags & WHERE_ONEPASS_MULTIROW)!=0
         4269  +           && 0==(wsFlags & WHERE_VIRTUALTABLE))
         4270  +    ){
  4272   4271         pWInfo->eOnePass = bOnerow ? ONEPASS_SINGLE : ONEPASS_MULTI;
  4273   4272         if( HasRowid(pTabList->a[0].pTab) && (wsFlags & WHERE_IDX_ONLY) ){
  4274   4273           if( wctrlFlags & WHERE_ONEPASS_MULTIROW ){
  4275   4274             bFordelete = OPFLAG_FORDELETE;
  4276   4275           }
  4277   4276           pWInfo->a[0].pWLoop->wsFlags = (wsFlags & ~WHERE_IDX_ONLY);
  4278   4277         }

Changes to src/wherecode.c.

    72     72     int i, j;
    73     73   
    74     74     if( nEq==0 && (pLoop->wsFlags&(WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))==0 ) return;
    75     75     sqlite3StrAccumAppend(pStr, " (", 2);
    76     76     for(i=0; i<nEq; i++){
    77     77       const char *z = explainIndexColumnName(pIndex, i);
    78     78       if( i ) sqlite3StrAccumAppend(pStr, " AND ", 5);
    79         -    sqlite3XPrintf(pStr, 0, i>=nSkip ? "%s=?" : "ANY(%s)", z);
           79  +    sqlite3XPrintf(pStr, i>=nSkip ? "%s=?" : "ANY(%s)", z);
    80     80     }
    81     81   
    82     82     j = i;
    83     83     if( pLoop->wsFlags&WHERE_BTM_LIMIT ){
    84     84       const char *z = explainIndexColumnName(pIndex, i);
    85     85       explainAppendTerm(pStr, i++, z, ">");
    86     86     }
................................................................................
   131    131       isSearch = (flags&(WHERE_BTM_LIMIT|WHERE_TOP_LIMIT))!=0
   132    132               || ((flags&WHERE_VIRTUALTABLE)==0 && (pLoop->u.btree.nEq>0))
   133    133               || (wctrlFlags&(WHERE_ORDERBY_MIN|WHERE_ORDERBY_MAX));
   134    134   
   135    135       sqlite3StrAccumInit(&str, db, zBuf, sizeof(zBuf), SQLITE_MAX_LENGTH);
   136    136       sqlite3StrAccumAppendAll(&str, isSearch ? "SEARCH" : "SCAN");
   137    137       if( pItem->pSelect ){
   138         -      sqlite3XPrintf(&str, 0, " SUBQUERY %d", pItem->iSelectId);
          138  +      sqlite3XPrintf(&str, " SUBQUERY %d", pItem->iSelectId);
   139    139       }else{
   140         -      sqlite3XPrintf(&str, 0, " TABLE %s", pItem->zName);
          140  +      sqlite3XPrintf(&str, " TABLE %s", pItem->zName);
   141    141       }
   142    142   
   143    143       if( pItem->zAlias ){
   144         -      sqlite3XPrintf(&str, 0, " AS %s", pItem->zAlias);
          144  +      sqlite3XPrintf(&str, " AS %s", pItem->zAlias);
   145    145       }
   146    146       if( (flags & (WHERE_IPK|WHERE_VIRTUALTABLE))==0 ){
   147    147         const char *zFmt = 0;
   148    148         Index *pIdx;
   149    149   
   150    150         assert( pLoop->u.btree.pIndex!=0 );
   151    151         pIdx = pLoop->u.btree.pIndex;
................................................................................
   161    161         }else if( flags & WHERE_IDX_ONLY ){
   162    162           zFmt = "COVERING INDEX %s";
   163    163         }else{
   164    164           zFmt = "INDEX %s";
   165    165         }
   166    166         if( zFmt ){
   167    167           sqlite3StrAccumAppend(&str, " USING ", 7);
   168         -        sqlite3XPrintf(&str, 0, zFmt, pIdx->zName);
          168  +        sqlite3XPrintf(&str, zFmt, pIdx->zName);
   169    169           explainIndexRange(&str, pLoop);
   170    170         }
   171    171       }else if( (flags & WHERE_IPK)!=0 && (flags & WHERE_CONSTRAINT)!=0 ){
   172    172         const char *zRangeOp;
   173    173         if( flags&(WHERE_COLUMN_EQ|WHERE_COLUMN_IN) ){
   174    174           zRangeOp = "=";
   175    175         }else if( (flags&WHERE_BOTH_LIMIT)==WHERE_BOTH_LIMIT ){
................................................................................
   176    176           zRangeOp = ">? AND rowid<";
   177    177         }else if( flags&WHERE_BTM_LIMIT ){
   178    178           zRangeOp = ">";
   179    179         }else{
   180    180           assert( flags&WHERE_TOP_LIMIT);
   181    181           zRangeOp = "<";
   182    182         }
   183         -      sqlite3XPrintf(&str, 0, " USING INTEGER PRIMARY KEY (rowid%s?)",zRangeOp);
          183  +      sqlite3XPrintf(&str, " USING INTEGER PRIMARY KEY (rowid%s?)",zRangeOp);
   184    184       }
   185    185   #ifndef SQLITE_OMIT_VIRTUALTABLE
   186    186       else if( (flags & WHERE_VIRTUALTABLE)!=0 ){
   187         -      sqlite3XPrintf(&str, 0, " VIRTUAL TABLE INDEX %d:%s",
          187  +      sqlite3XPrintf(&str, " VIRTUAL TABLE INDEX %d:%s",
   188    188                     pLoop->u.vtab.idxNum, pLoop->u.vtab.idxStr);
   189    189       }
   190    190   #endif
   191    191   #ifdef SQLITE_EXPLAIN_ESTIMATED_ROWS
   192    192       if( pLoop->nOut>=10 ){
   193         -      sqlite3XPrintf(&str, 0, " (~%llu rows)", sqlite3LogEstToInt(pLoop->nOut));
          193  +      sqlite3XPrintf(&str, " (~%llu rows)", sqlite3LogEstToInt(pLoop->nOut));
   194    194       }else{
   195    195         sqlite3StrAccumAppend(&str, " (~1 row)", 9);
   196    196       }
   197    197   #endif
   198    198       zMsg = sqlite3StrAccumFinish(&str);
   199    199       ret = sqlite3VdbeAddOp4(v, OP_Explain, iId, iLevel, iFrom, zMsg,P4_DYNAMIC);
   200    200     }
................................................................................
   741    741                         (sHint.pIdx ? sHint.iIdxCur : sHint.iTabCur), 0, 0,
   742    742                         (const char*)pExpr, P4_EXPR);
   743    743     }
   744    744   }
   745    745   #else
   746    746   # define codeCursorHint(A,B,C)  /* No-op */
   747    747   #endif /* SQLITE_ENABLE_CURSOR_HINTS */
          748  +
          749  +/*
          750  +** Cursor iCur is open on an intkey b-tree (a table). Register iRowid contains
          751  +** a rowid value just read from cursor iIdxCur, open on index pIdx. This
          752  +** function generates code to do a deferred seek of cursor iCur to the 
          753  +** rowid stored in register iRowid.
          754  +**
          755  +** Normally, this is just:
          756  +**
          757  +**   OP_Seek $iCur $iRowid
          758  +**
          759  +** However, if the scan currently being coded is a branch of an OR-loop and
          760  +** the statement currently being coded is a SELECT, then P3 of the OP_Seek
          761  +** is set to iIdxCur and P4 is set to point to an array of integers
          762  +** containing one entry for each column of the table cursor iCur is open 
          763  +** on. For each table column, if the column is the i'th column of the 
          764  +** index, then the corresponding array entry is set to (i+1). If the column
          765  +** does not appear in the index at all, the array entry is set to 0.
          766  +*/
          767  +static void codeDeferredSeek(
          768  +  WhereInfo *pWInfo,              /* Where clause context */
          769  +  Index *pIdx,                    /* Index scan is using */
          770  +  int iCur,                       /* Cursor for IPK b-tree */
          771  +  int iIdxCur                     /* Index cursor */
          772  +){
          773  +  Parse *pParse = pWInfo->pParse; /* Parse context */
          774  +  Vdbe *v = pParse->pVdbe;        /* Vdbe to generate code within */
          775  +
          776  +  assert( iIdxCur>0 );
          777  +  assert( pIdx->aiColumn[pIdx->nColumn-1]==-1 );
          778  +  
          779  +  sqlite3VdbeAddOp3(v, OP_Seek, iIdxCur, 0, iCur);
          780  +  if( (pWInfo->wctrlFlags & WHERE_FORCE_TABLE)
          781  +   && DbMaskAllZero(sqlite3ParseToplevel(pParse)->writeMask)
          782  +  ){
          783  +    int i;
          784  +    Table *pTab = pIdx->pTable;
          785  +    int *ai = (int*)sqlite3DbMallocZero(pParse->db, sizeof(int)*(pTab->nCol+1));
          786  +    if( ai ){
          787  +      ai[0] = pTab->nCol;
          788  +      for(i=0; i<pIdx->nColumn-1; i++){
          789  +        assert( pIdx->aiColumn[i]<pTab->nCol );
          790  +        if( pIdx->aiColumn[i]>=0 ) ai[pIdx->aiColumn[i]+1] = i+1;
          791  +      }
          792  +      sqlite3VdbeChangeP4(v, -1, (char*)ai, P4_INTARRAY);
          793  +    }
          794  +  }
          795  +}
   748    796   
   749    797   /*
   750    798   ** Generate code for the start of the iLevel-th loop in the WHERE clause
   751    799   ** implementation described by pWInfo.
   752    800   */
   753    801   Bitmask sqlite3WhereCodeOneLoopStart(
   754    802     WhereInfo *pWInfo,   /* Complete information about the WHERE clause */
................................................................................
  1221   1269   
  1222   1270       /* Seek the table cursor, if required */
  1223   1271       disableTerm(pLevel, pRangeStart);
  1224   1272       disableTerm(pLevel, pRangeEnd);
  1225   1273       if( omitTable ){
  1226   1274         /* pIdx is a covering index.  No need to access the main table. */
  1227   1275       }else if( HasRowid(pIdx->pTable) ){
  1228         -      iRowidReg = ++pParse->nMem;
  1229         -      sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur, iRowidReg);
  1230         -      sqlite3ExprCacheStore(pParse, iCur, -1, iRowidReg);
  1231   1276         if( pWInfo->eOnePass!=ONEPASS_OFF ){
         1277  +        iRowidReg = ++pParse->nMem;
         1278  +        sqlite3VdbeAddOp2(v, OP_IdxRowid, iIdxCur, iRowidReg);
         1279  +        sqlite3ExprCacheStore(pParse, iCur, -1, iRowidReg);
  1232   1280           sqlite3VdbeAddOp3(v, OP_NotExists, iCur, 0, iRowidReg);
  1233   1281           VdbeCoverage(v);
  1234   1282         }else{
  1235         -        sqlite3VdbeAddOp2(v, OP_Seek, iCur, iRowidReg);  /* Deferred seek */
         1283  +        codeDeferredSeek(pWInfo, pIdx, iCur, iIdxCur);
  1236   1284         }
  1237   1285       }else if( iCur!=iIdxCur ){
  1238   1286         Index *pPk = sqlite3PrimaryKeyIndex(pIdx->pTable);
  1239   1287         iRowidReg = sqlite3GetTempRange(pParse, pPk->nKeyCol);
  1240   1288         for(j=0; j<pPk->nKeyCol; j++){
  1241   1289           k = sqlite3ColumnOfIndex(pIdx, pPk->aiColumn[j]);
  1242   1290           sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, k, iRowidReg+j);
................................................................................
  1397   1445       */
  1398   1446       if( pWC->nTerm>1 ){
  1399   1447         int iTerm;
  1400   1448         for(iTerm=0; iTerm<pWC->nTerm; iTerm++){
  1401   1449           Expr *pExpr = pWC->a[iTerm].pExpr;
  1402   1450           if( &pWC->a[iTerm] == pTerm ) continue;
  1403   1451           if( ExprHasProperty(pExpr, EP_FromJoin) ) continue;
  1404         -        if( (pWC->a[iTerm].wtFlags & TERM_VIRTUAL)!=0 ) continue;
         1452  +        testcase( pWC->a[iTerm].wtFlags & TERM_VIRTUAL );
         1453  +        testcase( pWC->a[iTerm].wtFlags & TERM_CODED );
         1454  +        if( (pWC->a[iTerm].wtFlags & (TERM_VIRTUAL|TERM_CODED))!=0 ) continue;
  1405   1455           if( (pWC->a[iTerm].eOperator & WO_ALL)==0 ) continue;
  1406   1456           testcase( pWC->a[iTerm].wtFlags & TERM_ORINFO );
  1407   1457           pExpr = sqlite3ExprDup(db, pExpr, 0);
  1408   1458           pAndExpr = sqlite3ExprAnd(db, pAndExpr, pExpr);
  1409   1459         }
  1410   1460         if( pAndExpr ){
  1411   1461           pAndExpr = sqlite3PExpr(pParse, TK_AND|TKFLG_DONTFOLD, 0, pAndExpr, 0);

Changes to test/fordelete.test.

    26     26   proc analyze_delete_program {sql} {
    27     27     # Build a map from root page to table/index name.
    28     28     db eval {
    29     29       SELECT name, rootpage FROM sqlite_master
    30     30     } {
    31     31       set T($rootpage) $name
    32     32     }
           33  +  
           34  +  # For each OpenWrite instruction generated for the proposed DELETE
           35  +  # statement, add the following array entries:
           36  +  #
           37  +  #   $M(<cursor number>) -> <object name>
           38  +  #   $O(<object name>)   -> "*" | ""
           39  +  #
           40  +  # The O() entry is set to "*" if the BTREE_FORDELETE flag is specified,
           41  +  # or "" otherwise.
           42  +  #
           43  +  db eval "EXPLAIN $sql" R {
           44  +    if {$R(opcode)=="OpenWrite"} {
           45  +      set root $R(p2)
           46  +      set csr $R(p1)
           47  +      if {[info exists T($root)]} { set M($csr) $T($root) }
    33     48   
    34         -  # Calculate the results.
    35         -  set res [list]
           49  +      set obj $T($root)
           50  +      set O($obj) ""
           51  +      if {"0x$R(p5)" & 0x08} { 
           52  +        set O($obj) *
           53  +      } else {
           54  +        set O($obj) ""
           55  +      }
           56  +    }
           57  +  }
           58  +
    36     59     db eval "EXPLAIN $sql" R {
    37         -    if {$R(opcode) == "OpenWrite"} {
    38         -      set obj $T($R(p2))
    39         -      if {"0x$R(p5)" & 0x08} { append obj *}
    40         -      lappend res $obj
           60  +    if {$R(opcode) == "Delete"} {
           61  +      set csr $R(p1)
           62  +      if {[info exists M($csr)]} {
           63  +        set idxdelete [expr {("0x$R(p5)" & 0x04) ? 1 : 0}]
           64  +        if {$idxdelete} {
           65  +          append O($M($csr)) "+"
           66  +        }
           67  +      }
    41     68       }
    42     69     }
           70  +
           71  +  set res [list]
           72  +  foreach {k v} [array get O] {
           73  +    lappend res "${k}${v}"
           74  +  }
    43     75   
    44     76     lsort $res
    45     77   }
    46     78   
    47     79   proc do_adp_test {tn sql res} {
    48     80     uplevel [list do_test $tn [list analyze_delete_program $sql] [list {*}$res]]
    49     81   }
    50     82   
    51     83   do_execsql_test 1.0 {
    52     84     CREATE TABLE t1(a PRIMARY KEY, b);
    53     85   }
    54     86   
    55     87   foreach {tn sql res} {
    56         -  1 { DELETE FROM t1 WHERE a=?}          { sqlite_autoindex_t1_1  t1* }
    57         -  2 { DELETE FROM t1 WHERE a=? AND b=? } { sqlite_autoindex_t1_1  t1 }
    58         -  3 { DELETE FROM t1 WHERE a>? }         { sqlite_autoindex_t1_1  t1* }
    59         -  4 { DELETE FROM t1 WHERE rowid=? }     { sqlite_autoindex_t1_1*  t1 }
           88  +  1 { DELETE FROM t1 WHERE a=?}          { sqlite_autoindex_t1_1  t1*+ }
           89  +  2 { DELETE FROM t1 WHERE a=? AND b=? } { sqlite_autoindex_t1_1  t1+  }
           90  +  3 { DELETE FROM t1 WHERE a>? }         { sqlite_autoindex_t1_1  t1*+ }
           91  +  4 { DELETE FROM t1 WHERE rowid=? }     { sqlite_autoindex_t1_1*  t1  }
    60     92   } {
    61     93     do_adp_test 1.$tn $sql $res
    62     94   }
    63     95   
    64     96   do_execsql_test 2.0 {
    65     97     CREATE TABLE t2(a, b, c);
    66     98     CREATE INDEX t2a ON t2(a);
    67     99     CREATE INDEX t2b ON t2(b);
    68    100     CREATE INDEX t2c ON t2(c);
    69    101   }
    70    102   foreach {tn sql res} {
    71         -  1 { DELETE FROM t2 WHERE a=?}          { t2* t2a t2b* t2c* }
    72         -  2 { DELETE FROM t2 WHERE a=? AND +b=?} { t2 t2a t2b* t2c* }
          103  +  1 { DELETE FROM t2 WHERE a=?}          { t2*+ t2a t2b* t2c* }
          104  +  2 { DELETE FROM t2 WHERE a=? AND +b=?} { t2+ t2a t2b* t2c* }
    73    105     3 { DELETE FROM t2 WHERE a=? OR b=?}   { t2 t2a* t2b* t2c* }
    74    106     4 { DELETE FROM t2 WHERE +a=? }        { t2 t2a* t2b* t2c* }
    75    107     5 { DELETE FROM t2 WHERE rowid=? }     { t2 t2a* t2b* t2c* }
    76    108   } {
    77    109     do_adp_test 2.$tn $sql $res
    78    110   }
    79    111   
................................................................................
   121    153     btree_close_cursor $csr
   122    154     db eval { COMMIT }
   123    155   
   124    156     db eval {
   125    157       SELECT * FROM x2;
   126    158     }
   127    159   } {6 {} {} {}}
          160  +
          161  +
          162  +#-------------------------------------------------------------------------
          163  +#
          164  +reset_db 
          165  +do_execsql_test 4.0 {
          166  +  CREATE TABLE log(x);
          167  +  CREATE TABLE p1(one PRIMARY KEY, two);
          168  +
          169  +  CREATE TRIGGER tr_bd BEFORE DELETE ON p1 BEGIN
          170  +    INSERT INTO log VALUES('delete');
          171  +  END;
          172  +  INSERT INTO p1 VALUES('a', 'A'), ('b', 'B'), ('c', 'C');
          173  +  DELETE FROM p1 WHERE one = 'a';
          174  +}
          175  +
          176  +reset_db
          177  +do_execsql_test 4.1 {
          178  +  BEGIN TRANSACTION;
          179  +  CREATE TABLE tbl(a PRIMARY KEY, b, c);
          180  +  CREATE TABLE log(a, b, c);
          181  +  INSERT INTO "tbl" VALUES(1,2,3);
          182  +  CREATE TRIGGER the_trigger BEFORE DELETE ON tbl BEGIN 
          183  +    INSERT INTO log VALUES(1, 2,3);
          184  +  END;
          185  +  COMMIT;
          186  +  DELETE FROM tbl WHERE a=1;
          187  +}
          188  +
          189  +reset_db
          190  +do_execsql_test 5.1 {
          191  +  PRAGMA foreign_keys = 1;
          192  +  CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
          193  +  CREATE TABLE t2(
          194  +      c INTEGER PRIMARY KEY,
          195  +      d INTEGER DEFAULT 1 REFERENCES t1 ON DELETE SET DEFAULT
          196  +  );
          197  +} {}
          198  +do_execsql_test 5.2 {
          199  +  INSERT INTO t1 VALUES(1, 'one');
          200  +  INSERT INTO t1 VALUES(2, 'two');
          201  +  INSERT INTO t2 VALUES(1, 2);
          202  +  SELECT * FROM t2;
          203  +} {1 2}
          204  +do_execsql_test 5.3 {
          205  +  DELETE FROM t1 WHERE a = 2;
          206  +} {}
          207  +
   128    208   
   129    209   finish_test
   130    210   

Changes to test/json103.test.

    56     56      WHERE rowid BETWEEN 31 AND 39 AND rowid%2==1;
    57     57   } {{{"n31":32.5,"n33":33,"n35":35,"n37":null,"n39":"orange"}}}
    58     58   do_execsql_test json103-220 {
    59     59     SELECT b, json_group_object(c,a) FROM t1
    60     60      WHERE rowid<7 GROUP BY b ORDER BY b;
    61     61   } {0 {{"n3":3,"n6":6}} 1 {{"n1":1,"n4":4}} 2 {{"n2":2,"n5":5}}}
    62     62   
    63         -
           63  +# ticket https://www.sqlite.org/src/info/f45ac567eaa9f93c 2016-01-30
           64  +# Invalid JSON generated by json_group_array() 
           65  +#
           66  +# The underlying problem is a failure to reset Mem.eSubtype
           67  +#
           68  +do_execsql_test json103-300 {
           69  +  DROP TABLE IF EXISTS t1;
           70  +  CREATE TABLE t1(x);
           71  +  INSERT INTO t1 VALUES(1),('abc');
           72  +  SELECT
           73  +     json_group_array(x),
           74  +     json_group_array(json_object('x',x))
           75  +    FROM t1;
           76  +} {{[1,"abc"]} {[{"x":1},{"x":"abc"}]}}
    64     77   
    65     78   finish_test

Changes to test/like.test.

   959    959     EXPLAIN QUERY PLAN
   960    960     SELECT id FROM t12nc WHERE x LIKE 'abc%' COLLATE binary ORDER BY +id;
   961    961   } {/SEARCH/}
   962    962   do_execsql_test like-12.16 {
   963    963     EXPLAIN QUERY PLAN
   964    964     SELECT id FROM t12b WHERE x LIKE 'abc%' COLLATE binary ORDER BY +id;
   965    965   } {/SCAN/}
          966  +
          967  +# Ticket [https://www.sqlite.org/src/tktview/80369eddd5c94d49f7fbbcf5]
          968  +# 2016-01-20
          969  +#
          970  +do_execsql_test like-13.1 {
          971  +  SELECT char(0x304d) LIKE char(0x306d);
          972  +} {0}
          973  +do_execsql_test like-13.2 {
          974  +  SELECT char(0x4d) LIKE char(0x306d);
          975  +} {0}
          976  +do_execsql_test like-13.3 {
          977  +  SELECT char(0x304d) LIKE char(0x6d);
          978  +} {0}
          979  +do_execsql_test like-13.4 {
          980  +  SELECT char(0x4d) LIKE char(0x6d);
          981  +} {1}
          982  +
   966    983   
   967    984   
   968    985   finish_test

Changes to test/oserror.test.

    91     91   do_test 1.4.1 {
    92     92     set ::log [list]
    93     93     list [catch { sqlite3 dbh /root/test.db } msg] $msg
    94     94   } {1 {unable to open database file}}
    95     95   
    96     96   do_re_test 1.4.2 { 
    97     97     lindex $::log 0
    98         -} {^os_unix.c:\d*: \(\d+\) (open|readlink)\(.*test.db\) - }
           98  +} {^os_unix.c:\d*: \(\d+\) (open|readlink|lstat)\(.*test.db\) - }
    99     99   
   100    100   #--------------------------------------------------------------------------
   101    101   # Tests oserror-1.* test failures in the unlink() system call.
   102    102   #
   103    103   ifcapable wal {
   104    104     do_test 2.1.1 {
   105    105       set ::log [list]

Changes to test/stat.test.

    10     10   #***********************************************************************
    11     11   # This file implements regression tests for SQLite library.  The
    12     12   # focus of this file is testing the SELECT statement.
    13     13   #
    14     14   
    15     15   set testdir [file dirname $argv0]
    16     16   source $testdir/tester.tcl
           17  +set testprefix stat
    17     18   
    18     19   ifcapable !vtab||!compound {
    19     20     finish_test
    20     21     return
    21     22   }
    22     23   
    23     24   
................................................................................
   179    180     t1 /000+000000 3 overflow 0 1020 0 0    \
   180    181     t1 /001+000000 4 overflow 0 1020 0 0    \
   181    182   ]
   182    183   
   183    184   do_catchsql_test stat-6.1 {
   184    185     CREATE VIRTUAL TABLE temp.s2 USING dbstat(mainx);
   185    186   } {1 {no such database: mainx}}
          187  +
          188  +#-------------------------------------------------------------------------
          189  +# Test that the argument passed to the dbstat constructor is dequoted
          190  +# before it is matched against the names of attached databases.
          191  +#
          192  +forcedelete test.db2
          193  +do_execsql_test 7.1 {
          194  +  ATTACH 'test.db2' AS '123';
          195  +  PRAGMA "123".auto_vacuum = OFF;
          196  +  CREATE TABLE "123".x1(a, b);
          197  +  INSERT INTO x1 VALUES(1, 2);
          198  +}
          199  +
          200  +do_execsql_test 7.1.1 {
          201  +  SELECT * FROM dbstat('123');
          202  +} {
          203  +  sqlite_master / 1 leaf 1 37 875 37 0 1024 
          204  +  x1 / 2 leaf 1 4 1008 4 1024 1024
          205  +}
          206  +do_execsql_test 7.1.2 {
          207  +  SELECT * FROM dbstat(123);
          208  +} {
          209  +  sqlite_master / 1 leaf 1 37 875 37 0 1024 
          210  +  x1 / 2 leaf 1 4 1008 4 1024 1024
          211  +}
          212  +do_execsql_test 7.1.3 {
          213  +  CREATE VIRTUAL TABLE x2 USING dbstat('123');
          214  +  SELECT * FROM x2;
          215  +} {
          216  +  sqlite_master / 1 leaf 1 37 875 37 0 1024 
          217  +  x1 / 2 leaf 1 4 1008 4 1024 1024
          218  +}
          219  +do_execsql_test 7.1.4 {
          220  +  CREATE VIRTUAL TABLE x3 USING dbstat(123);
          221  +  SELECT * FROM x3;
          222  +} {
          223  +  sqlite_master / 1 leaf 1 37 875 37 0 1024 
          224  +  x1 / 2 leaf 1 4 1008 4 1024 1024
          225  +}
          226  +
          227  +do_execsql_test 7.2 {
          228  +  DETACH 123;
          229  +  DROP TABLE x2;
          230  +  DROP TABLE x3;
          231  +  ATTACH 'test.db2' AS '123corp';
          232  +}
          233  +do_execsql_test 7.2.1 {
          234  +  SELECT * FROM dbstat('123corp');
          235  +} {
          236  +  sqlite_master / 1 leaf 1 37 875 37 0 1024 
          237  +  x1 / 2 leaf 1 4 1008 4 1024 1024
          238  +}
          239  +do_catchsql_test 7.2.2 {
          240  +  SELECT * FROM dbstat(123corp);
          241  +} {1 {unrecognized token: "123corp"}}
          242  +do_execsql_test 7.2.3 {
          243  +  CREATE VIRTUAL TABLE x2 USING dbstat('123corp');
          244  +  SELECT * FROM x2;
          245  +} {
          246  +  sqlite_master / 1 leaf 1 37 875 37 0 1024 
          247  +  x1 / 2 leaf 1 4 1008 4 1024 1024
          248  +}
          249  +do_catchsql_test 7.2.4 {
          250  +  CREATE VIRTUAL TABLE x3 USING dbstat(123corp);
          251  +  SELECT * FROM x3;
          252  +} {1 {unrecognized token: "123corp"}}
   186    253   
   187    254   finish_test

Changes to test/symlink.test.

    79     79   #-------------------------------------------------------------------------
    80     80   # Test that journal and wal files are created next to the real file,
    81     81   # not the symlink.
    82     82   #
    83     83   do_test 2.0 {
    84     84     catch { db close }
    85     85     catch { db2 close }
    86         -  forcedelete test.db test.db2
           86  +  forcedelete test.db test.db2 test.db3
    87     87     sqlite3 db test.db
    88     88     execsql { CREATE TABLE t1(x) }
    89     89     file link test.db2 test.db
    90         -  sqlite3 db2 test.db2
    91         -  file exists test.db-journal
    92         -} 0
           90  +  file link test.db3 test.db2
           91  +  set {} {}
           92  +} {}
    93     93   
    94         -do_test 2.1 {
    95         -  execsql {
    96         -    BEGIN;
    97         -      INSERT INTO t1 VALUES(1);
    98         -  } db2
    99         -  file exists test.db-journal
   100         -} 1
   101         -do_test 2.2 {
   102         -  file exists test.db2-journal
   103         -} 0
   104         -do_test 2.3 {
   105         -  execsql {
   106         -    COMMIT;
   107         -    PRAGMA journal_mode = wal;
   108         -    INSERT INTO t1 VALUES(2);
   109         -  } db2
   110         -  file exists test.db-wal
   111         -} 1
   112         -do_test 2.4 {
   113         -  file exists test.db2-wal
   114         -} 0
   115         -do_execsql_test 2.5 {
   116         -  SELECT * FROM t1;
   117         -} {1 2}
           94  +foreach {tn f} {1 test.db2 2 test.db3} {
           95  +  do_test 2.$tn.1 {
           96  +    sqlite3 db2 $f
           97  +    file exists test.db-journal
           98  +  } 0
           99  +  do_test 2.$tn.2 {
          100  +    execsql {
          101  +      BEGIN;
          102  +        INSERT INTO t1 VALUES(1);
          103  +    } db2
          104  +    file exists test.db-journal
          105  +  } 1
          106  +  do_test 2.$tn.3 {
          107  +    list [file exists test2.db-journal] [file exists test3.db-journal]
          108  +  } {0 0}
          109  +  do_test 2.$tn.4 {
          110  +    execsql {
          111  +      COMMIT;
          112  +      PRAGMA journal_mode = wal;
          113  +      INSERT INTO t1 VALUES(2);
          114  +    } db2
          115  +    file exists test.db-wal
          116  +  } 1
          117  +  do_test 2.$tn.5 {
          118  +    list [file exists test2.db-wal] [file exists test3.db-wal]
          119  +  } {0 0}
          120  +  do_execsql_test 2.$tn.6 {
          121  +    SELECT * FROM t1;
          122  +  } {1 2}
          123  +  db2 close
          124  +  do_execsql_test 2.$tn.7 {
          125  +    DELETE FROM t1;
          126  +    PRAGMA journal_mode = delete;
          127  +  } delete
          128  +}
   118    129   
   119    130   # Try to open a ridiculously long pathname.  Bug found by
   120    131   # Kostya Serebryany using libFuzzer on 2015-11-30.
   121    132   #
   122    133   do_test 3.1 {
   123    134     db close
   124    135     catch {sqlite3 db [string repeat [string repeat x 100]/ 6]} res
   125    136     set res
   126    137   } {unable to open database file}
   127    138   
          139  +#-------------------------------------------------------------------------
          140  +# Test that relative symlinks that are not located in the cwd work.
          141  +#
          142  +do_test 4.1 {
          143  +  forcedelete x y z
          144  +  file mkdir x
          145  +  file mkdir y
          146  +  file mkdir z
          147  +  sqlite3 db x/test.db
          148  +  file link y/test.db ../x/test.db
          149  +  file link z/test.db ../y/test.db
          150  +  execsql {
          151  +    PRAGMA journal_mode = wal;
          152  +    CREATE TABLE t1(x, y);
          153  +    INSERT INTO t1 VALUES('hello', 'world');
          154  +  }
          155  +} {wal}
          156  +
          157  +do_test 4.2.1 {
          158  +  db close
          159  +  sqlite3 db y/test.db
          160  +  db eval { SELECT * FROM t1 }
          161  +} {hello world}
          162  +do_test 4.2.2 {
          163  +  list [file exists x/test.db-wal] [file exists y/test.db-wal]
          164  +} {1 0}
          165  +
          166  +do_test 4.3.1 {
          167  +  db close
          168  +  sqlite3 db z/test.db
          169  +  db eval { SELECT * FROM t1 }
          170  +} {hello world}
          171  +do_test 4.3.2 {
          172  +  list [file exists x/test.db-wal] [file exists y/test.db-wal] \
          173  +       [file exists z/test.db-wal]
          174  +} {1 0 0}
          175  +
          176  +do_test 4.4.0 {
          177  +  forcedelete w
          178  +  file mkdir w
          179  +  file link w/test.db [file join [pwd] x/test.db] 
          180  +  set {} {}
          181  +} {}
          182  +do_test 4.4.1 {
          183  +  db close
          184  +  sqlite3 db w/test.db
          185  +  db eval { SELECT * FROM t1 }
          186  +} {hello world}
          187  +do_test 4.4.2 {
          188  +  list [file exists x/test.db-wal] [file exists w/test.db-wal]
          189  +} {1 0}
   128    190   
   129    191   finish_test

Changes to test/syscall.test.

    57     57   # Tests for the xNextSystemCall method.
    58     58   #
    59     59   foreach s {
    60     60       open close access getcwd stat fstat ftruncate
    61     61       fcntl read pread write pwrite fchmod fallocate
    62     62       pread64 pwrite64 unlink openDirectory mkdir rmdir 
    63     63       statvfs fchown geteuid umask mmap munmap mremap
    64         -    getpagesize readlink
           64  +    getpagesize readlink lstat
    65     65   } {
    66     66     if {[test_syscall exists $s]} {lappend syscall_list $s}
    67     67   }
    68     68   do_test 3.1 { lsort [test_syscall list] } [lsort $syscall_list]
    69     69   
    70     70   #-------------------------------------------------------------------------
    71     71   # This test verifies that if a call to open() fails and errno is set to

Changes to test/walcrash.test.

   234    234         INSERT INTO t1 SELECT randomblob(900) FROM t1 LIMIT 4;   /* 28 */
   235    235         INSERT INTO t1 SELECT randomblob(900) FROM t1 LIMIT 4;   /* 32 */
   236    236   
   237    237         PRAGMA wal_checkpoint;
   238    238         INSERT INTO t1 VALUES(randomblob(9000));
   239    239         INSERT INTO t1 VALUES(randomblob(9000));
   240    240         INSERT INTO t1 VALUES(randomblob(9000));
          241  +      INSERT INTO t1 VALUES(randomblob(9000));
   241    242       }
   242    243     } {1 {child process exited abnormally}}
   243    244   
   244    245     do_test walcrash-6.$i.2 {
   245    246       sqlite3 db test.db
   246         -    execsql { SELECT count(*)==34 OR count(*)==35 FROM t1 WHERE x != 1 }
          247  +    execsql { SELECT count(*) BETWEEN 34 AND 36 FROM t1 WHERE x != 1 }
   247    248     } {1}
   248    249     do_test walcrash-6.$i.3 { execsql { PRAGMA main.integrity_check } } {ok}
   249    250     do_test walcrash-6.$i.4 { execsql { PRAGMA main.journal_mode } } {wal}
   250    251   
   251    252     db close
   252    253   }
   253    254   

Changes to test/whereD.test.

   152    152     SELECT a, b FROM t3 WHERE 
   153    153           (a=2 AND b=(SELECT y FROM t4 WHERE x='b')) 
   154    154        OR (a=1 AND b=(SELECT y FROM t4 WHERE x='a')) 
   155    155   } {2 two 1 one search 8}
   156    156   
   157    157   do_searchcount_test 3.5.1 {
   158    158     SELECT a, b FROM t3 WHERE (a=1 AND b='one') OR rowid=4
   159         -} {1 one 2 two search 3}
          159  +} {1 one 2 two search 2}
   160    160   do_searchcount_test 3.5.2 {
   161    161     SELECT a, c FROM t3 WHERE (a=1 AND b='one') OR rowid=4
   162    162   } {1 i 2 ii search 3}
   163    163   
   164    164   # Ticket [d02e1406a58ea02d] (2012-10-04)
   165    165   # LEFT JOIN with an OR in the ON clause causes segfault 
   166    166   #
................................................................................
   267    267       c0=1 or  c1=1 or  c2=1 or  c3=1 or
   268    268       c4=1 or  c5=1 or  c6=1 or  c7=1 or
   269    269       c8=1 or  c9=1 or c10=1 or c11=1 or
   270    270       c12=1 or c13=1 or c14=1 or c15=1 or
   271    271       c16=1 or c17=1;
   272    272   } {1 {} {} {} {} {} {} {} {} {} {} {} {} {} {} 1 {} {}}
   273    273   
          274  +#-------------------------------------------------------------------------
          275  +do_execsql_test 6.1 {
          276  +  CREATE TABLE x1(a, b, c, d, e);
          277  +  CREATE INDEX x1a  ON x1(a);
          278  +  CREATE INDEX x1bc ON x1(b, c);
          279  +  CREATE INDEX x1cd ON x1(c, d);
          280  +
          281  +  INSERT INTO x1 VALUES(1, 2, 3, 4, 'A');
          282  +  INSERT INTO x1 VALUES(5, 6, 7, 8, 'B');
          283  +  INSERT INTO x1 VALUES(9, 10, 11, 12, 'C');
          284  +  INSERT INTO x1 VALUES(13, 14, 15, 16, 'D');
          285  +}
          286  +
          287  +do_searchcount_test 6.2.1 {
          288  +  SELECT e FROM x1 WHERE b=2 OR c=7;
          289  +} {A B search 6}
          290  +do_searchcount_test 6.2.2 {
          291  +  SELECT c FROM x1 WHERE b=2 OR c=7;
          292  +} {3 7 search 4}
          293  +
          294  +do_searchcount_test 6.3.1 {
          295  +  SELECT e FROM x1 WHERE a=1 OR b=10;
          296  +} {A C search 6}
          297  +do_searchcount_test 6.3.2 {
          298  +  SELECT c FROM x1 WHERE a=1 OR b=10;
          299  +} {3 11 search 5}
          300  +do_searchcount_test 6.3.3 {
          301  +  SELECT rowid FROM x1 WHERE a=1 OR b=10;
          302  +} {1 3 search 4}
          303  +
          304  +do_searchcount_test 6.4.1 {
          305  +  SELECT a FROM x1 WHERE b BETWEEN 1 AND 4 OR c BETWEEN 8 AND 12
          306  +} {1 9 search 6}
          307  +do_searchcount_test 6.4.2 {
          308  +  SELECT b, c FROM x1 WHERE b BETWEEN 1 AND 4 OR c BETWEEN 8 AND 12
          309  +} {2 3 10 11 search 5}
          310  +do_searchcount_test 6.4.3 {
          311  +  SELECT rowid, c FROM x1 WHERE b BETWEEN 1 AND 4 OR c BETWEEN 8 AND 12
          312  +} {1 3 3 11 search 4}
          313  +
          314  +do_searchcount_test 6.5.1 {
          315  +  SELECT a FROM x1 WHERE rowid = 2 OR c=11
          316  +} {5 9 search 3}
          317  +do_searchcount_test 6.5.2 {
          318  +  SELECT d FROM x1 WHERE rowid = 2 OR c=11
          319  +} {8 12 search 2}
          320  +do_searchcount_test 6.5.3 {
          321  +  SELECT d FROM x1 WHERE c=11 OR rowid = 2
          322  +} {12 8 search 2}
          323  +do_searchcount_test 6.5.4 {
          324  +  SELECT a FROM x1 WHERE c=11 OR rowid = 2 
          325  +} {9 5 search 3}
          326  +
          327  +do_searchcount_test 6.6.1 {
          328  +  SELECT rowid FROM x1 WHERE a=1 OR b=6 OR c=11
          329  +} {1 2 3 search 6}
          330  +do_searchcount_test 6.6.2 {
          331  +  SELECT c FROM x1 WHERE a=1 OR b=6 OR c=11
          332  +} {3 7 11 search 7}
          333  +do_searchcount_test 6.6.3 {
          334  +  SELECT c FROM x1 WHERE c=11 OR a=1 OR b=6 
          335  +} {11 3 7 search 7}
          336  +do_searchcount_test 6.6.4 {
          337  +  SELECT c FROM x1 WHERE b=6 OR c=11 OR a=1
          338  +} {7 11 3 search 7}
   274    339   
   275    340   finish_test

Changes to tool/build-all-msvc.bat.

   725    725     FOR /F "delims=" %%V IN ('%__ECHO_CMD%') DO (
   726    726       SET VALUE=%%V
   727    727     )
   728    728     ENDLOCAL && SET %2=%VALUE%
   729    729     GOTO :EOF
   730    730   
   731    731   :fn_UnsetVariable
   732         -  IF NOT "%1" == "" (
   733         -    SET %1=
          732  +  SET VALUE=%1
          733  +  IF DEFINED VALUE (
          734  +    SET %VALUE%=
          735  +    SET VALUE=
   734    736       CALL :fn_ResetErrorLevel
   735    737     )
   736    738     GOTO :EOF
   737    739   
   738    740   :fn_AppendVariable
   739    741     SET __ECHO_CMD=ECHO %%%1%%
   740    742     IF DEFINED %1 (

Changes to tool/mkautoconfamal.sh.

    30     30   zz=0
    31     31   set +e
    32     32     zz=`echo $VERSION|sed 's/3\.[^.]*\.[^.]*\.\([0-9]*\).*/\1/'|grep -v '\.'`
    33     33   set -e
    34     34   ARTIFACT=`printf "3%.2d%.2d%.2d" $xx $yy $zz`
    35     35   
    36     36   rm -rf $TMPSPACE
    37         -cp -R $TOP/autoconf $TMPSPACE
    38         -
    39         -cp sqlite3.c          $TMPSPACE
    40         -cp sqlite3.h          $TMPSPACE
    41         -cp sqlite3ext.h       $TMPSPACE
    42         -cp $TOP/sqlite3.1     $TMPSPACE
    43         -cp $TOP/sqlite3.pc.in $TMPSPACE
    44         -cp $TOP/src/shell.c   $TMPSPACE
           37  +cp -R $TOP/autoconf       $TMPSPACE
           38  +cp sqlite3.c              $TMPSPACE
           39  +cp sqlite3.h              $TMPSPACE
           40  +cp sqlite3ext.h           $TMPSPACE
           41  +cp $TOP/sqlite3.1         $TMPSPACE
           42  +cp $TOP/sqlite3.pc.in     $TMPSPACE
           43  +cp $TOP/src/shell.c       $TMPSPACE
           44  +cp $TOP/src/sqlite3.rc    $TMPSPACE
    45     45   
    46     46   cat $TMPSPACE/configure.ac |
    47     47   sed "s/--SQLITE-VERSION--/$VERSION/" > $TMPSPACE/tmp
    48     48   mv $TMPSPACE/tmp $TMPSPACE/configure.ac
    49     49   
    50     50   cd $TMPSPACE
    51     51   autoreconf -i

Added tool/mkmsvcmin.tcl.

            1  +#!/usr/bin/tcl
            2  +#
            3  +# This script reads the regular MSVC makefile (../Makefile.msc) and outputs
            4  +# a revised version of that Makefile that is "minimal" in the sense that
            5  +# it uses the sqlite3.c amalgamation as input and does not require tclsh.
            6  +# The resulting "../Makefile.min.msc" is suitable for use in the amalgamation
            7  +# tarballs.
            8  +#
            9  +if {$argc==0} {
           10  +  set basedir [file dir [file dir [file normalize $argv0]]]
           11  +  set fromFileName [file join $basedir Makefile.msc]
           12  +  set toFileName [file join $basedir autoconf Makefile.msc]
           13  +} else {
           14  +  set fromFileName [lindex $argv 0]
           15  +  if {![file exists $fromFileName]} {
           16  +    error "input file \"$fromFileName\" does not exist"
           17  +  }
           18  +  set toFileName [lindex $argv 1]
           19  +  if {[file exists $toFileName]} {
           20  +    error "output file \"$toFileName\" already exists"
           21  +  }
           22  +}
           23  +
           24  +proc readFile { fileName } {
           25  +  set file_id [open $fileName RDONLY]
           26  +  fconfigure $file_id -encoding binary -translation binary
           27  +  set result [read $file_id]
           28  +  close $file_id
           29  +  return $result
           30  +}
           31  +
           32  +proc writeFile { fileName data } {
           33  +  set file_id [open $fileName {WRONLY CREAT TRUNC}]
           34  +  fconfigure $file_id -encoding binary -translation binary
           35  +  puts -nonewline $file_id $data
           36  +  close $file_id
           37  +  return ""
           38  +}
           39  +
           40  +proc escapeSubSpec { data } {
           41  +  regsub -all -- {&} $data {\\\&} data
           42  +  regsub -all -- {\\(\d+)} $data {\\\\\1} data
           43  +  return $data
           44  +}
           45  +
           46  +proc substVars { data } {
           47  +  return [uplevel 1 [list subst -nocommands -nobackslashes $data]]
           48  +}
           49  +
           50  +#
           51  +# NOTE: This block is used to replace the section marked <<block1>> in
           52  +#       the Makefile, if it exists.
           53  +#
           54  +set blocks(1) [string trimleft [string map [list \\\\ \\] {
           55  +_HASHCHAR=^#
           56  +!IF ![echo !IFNDEF VERSION > rcver.vc] && \\
           57  +    ![for /F "delims=" %V in ('type "$(SQLITE3H)" ^| find "$(_HASHCHAR)define SQLITE_VERSION "') do (echo VERSION = ^^%V >> rcver.vc)] && \\
           58  +    ![echo !ENDIF >> rcver.vc]
           59  +!INCLUDE rcver.vc
           60  +!ENDIF
           61  +
           62  +RESOURCE_VERSION = $(VERSION:^#=)
           63  +RESOURCE_VERSION = $(RESOURCE_VERSION:define=)
           64  +RESOURCE_VERSION = $(RESOURCE_VERSION:SQLITE_VERSION=)
           65  +RESOURCE_VERSION = $(RESOURCE_VERSION:"=)
           66  +RESOURCE_VERSION = $(RESOURCE_VERSION:.=,)
           67  +
           68  +$(LIBRESOBJS):	$(TOP)\sqlite3.rc rcver.vc $(SQLITE3H)
           69  +	echo #ifndef SQLITE_RESOURCE_VERSION > sqlite3rc.h
           70  +	echo #define SQLITE_RESOURCE_VERSION $(RESOURCE_VERSION) >> sqlite3rc.h
           71  +	echo #endif >> sqlite3rc.h
           72  +	$(LTRCOMPILE) -fo $(LIBRESOBJS) -DRC_VERONLY $(TOP)\sqlite3.rc
           73  +}]]
           74  +
           75  +set data "#### DO NOT EDIT ####\n"
           76  +append data "# This makefile is automatically "
           77  +append data "generated from the [file tail $fromFileName] at\n"
           78  +append data "# the root of the canonical SQLite source tree (not the\n"
           79  +append data "# amalgamation tarball) using the tool/[file tail $argv0]\n"
           80  +append data "# script.\n#\n\n"
           81  +append data [readFile $fromFileName]
           82  +
           83  +regsub -all -- {# <<mark>>\n.*?# <</mark>>\n} \
           84  +    $data "" data
           85  +
           86  +foreach i [lsort -integer [array names blocks]] {
           87  +  regsub -all -- [substVars \
           88  +      {# <<block${i}>>\n.*?# <</block${i}>>\n}] \
           89  +      $data [escapeSubSpec $blocks($i)] data
           90  +}
           91  +
           92  +set data [string map [list " -I\$(TOP)\\src" ""] $data]
           93  +set data [string map [list " /DEF:sqlite3.def" ""] $data]
           94  +set data [string map [list " sqlite3.def" ""] $data]
           95  +set data [string map [list " \$(ALL_TCL_TARGETS)" ""] $data]
           96  +set data [string map [list "\$(TOP)\\src\\" "\$(TOP)\\"] $data]
           97  +
           98  +writeFile $toFileName $data

Changes to tool/mkopcodec.tcl.

    15     15   puts " || defined(SQLITE_DEBUG)"
    16     16   puts "#if defined(SQLITE_ENABLE_EXPLAIN_COMMENTS) || defined(SQLITE_DEBUG)"
    17     17   puts "# define OpHelp(X) \"\\0\" X"
    18     18   puts "#else"
    19     19   puts "# define OpHelp(X)"
    20     20   puts "#endif"
    21     21   puts "const char *sqlite3OpcodeName(int i)\173"
    22         -puts " static const char *const azName\[\] = \173 \"?\","
           22  +puts " static const char *const azName\[\] = \173"
    23     23   set mx 0
    24     24   
    25     25   set in [open [lindex $argv 0] rb]
    26     26   while {![eof $in]} {
    27     27     set line [gets $in]
    28     28     if {[regexp {^#define OP_} $line]} {
    29     29       set name [lindex $line 1]
................................................................................
    36     36       } else {
    37     37         set synopsis($i) {}
    38     38       }
    39     39     }
    40     40   }
    41     41   close $in
    42     42   
    43         -for {set i 1} {$i<=$mx} {incr i} {
           43  +for {set i 0} {$i<=$mx} {incr i} {
    44     44     puts [format "    /* %3d */ %-18s OpHelp(\"%s\")," \
    45     45            $i \"$label($i)\" $synopsis($i)]
    46     46   }
    47     47   puts "  \175;"
    48     48   puts "  return azName\[i\];"
    49     49   puts "\175"
    50     50   puts "#endif"

Changes to tool/mkopcodeh.tcl.

    77     77       set line [split $line]
    78     78       set name [string trim [lindex $line 1] :]
    79     79       set op($name) -1
    80     80       set jump($name) 0
    81     81       set in1($name) 0
    82     82       set in2($name) 0
    83     83       set in3($name) 0
    84         -    set out1($name) 0
    85     84       set out2($name) 0
           85  +    set out3($name) 0
    86     86       for {set i 3} {$i<[llength $line]-1} {incr i} {
    87     87          switch [string trim [lindex $line $i] ,] {
    88     88            same {
    89     89              incr i
    90     90              if {[lindex $line $i]=="as"} {
    91     91                incr i
    92     92                set sym [string trim [lindex $line $i] ,]
................................................................................
   108    108       set order($nOp) $name
   109    109       incr nOp
   110    110     }
   111    111   }
   112    112   
   113    113   # Assign numbers to all opcodes and output the result.
   114    114   #
   115         -set cnt 0
   116         -set max 0
   117    115   puts "/* Automatically generated.  Do not edit */"
   118    116   puts "/* See the tool/mkopcodeh.tcl script for details */"
   119         -set op(OP_Noop) -1
   120         -set order($nOp) OP_Noop
   121         -incr nOp
   122         -set op(OP_Explain) -1
   123         -set order($nOp) OP_Explain
   124         -incr nOp
          117  +foreach name {OP_Noop OP_Explain} {
          118  +  set jump($name) 0
          119  +  set in1($name) 0
          120  +  set in2($name) 0
          121  +  set in3($name) 0
          122  +  set out2($name) 0
          123  +  set out3($name) 0
          124  +  set op($name) -1
          125  +  set order($nOp) $name
          126  +  incr nOp
          127  +}
   125    128   
   126    129   # The following are the opcodes that are processed by resolveP2Values()
   127    130   #
   128    131   set rp2v_ops {
   129    132     OP_Transaction
   130    133     OP_AutoCommit
   131    134     OP_Savepoint
................................................................................
   140    143     OP_Prev
   141    144     OP_PrevIfOpen
   142    145   }
   143    146   
   144    147   # Assign small values to opcodes that are processed by resolveP2Values()
   145    148   # to make code generation for the switch() statement smaller and faster.
   146    149   #
   147         -set cnt 0
          150  +set cnt -1
   148    151   for {set i 0} {$i<$nOp} {incr i} {
   149    152     set name $order($i)
   150    153     if {[lsearch $rp2v_ops $name]>=0} {
   151    154       incr cnt
   152    155       while {[info exists used($cnt)]} {incr cnt}
   153    156       set op($name) $cnt
   154    157       set used($cnt) 1
................................................................................
   165    168       while {[info exists used($cnt)]} {incr cnt}
   166    169       set op($name) $cnt
   167    170       set used($cnt) 1
   168    171       set def($cnt) $name
   169    172     }
   170    173   }
   171    174   set max $cnt
   172         -for {set i 1} {$i<=$nOp} {incr i} {
          175  +for {set i 0} {$i<$nOp} {incr i} {
   173    176     if {![info exists used($i)]} {
   174    177       set def($i) "OP_NotUsed_$i"
   175    178     }
   176    179     set name $def($i)
   177    180     puts -nonewline [format {#define %-16s %3d} $name $i]
   178    181     set com {}
   179    182     if {[info exists sameas($i)]} {
................................................................................
   192    195     }
   193    196     puts ""
   194    197   }
   195    198   
   196    199   # Generate the bitvectors:
   197    200   #
   198    201   set bv(0) 0
   199         -for {set i 1} {$i<=$max} {incr i} {
          202  +for {set i 0} {$i<=$max} {incr i} {
   200    203     set name $def($i)
   201         -  if {[info exists jump($name)] && $jump($name)} {set a0 1}  {set a0 0}
   202         -  if {[info exists in1($name)] && $in1($name)}   {set a1 2}  {set a1 0}
   203         -  if {[info exists in2($name)] && $in2($name)}   {set a2 4}  {set a2 0}
   204         -  if {[info exists in3($name)] && $in3($name)}   {set a3 8}  {set a3 0}
   205         -  if {[info exists out2($name)] && $out2($name)} {set a4 16} {set a4 0}
   206         -  if {[info exists out3($name)] && $out3($name)} {set a5 32} {set a5 0}
   207         -  set bv($i) [expr {$a0+$a1+$a2+$a3+$a4+$a5}]
          204  +  set x 0
          205  +  if {$jump($name)}  {incr x 1}
          206  +  if {$in1($name)}   {incr x 2}
          207  +  if {$in2($name)}   {incr x 4}
          208  +  if {$in3($name)}   {incr x 8}
          209  +  if {$out2($name)}  {incr x 16}
          210  +  if {$out3($name)}  {incr x 32}
          211  +  set bv($i) $x
   208    212   }
   209    213   puts ""
   210    214   puts "/* Properties such as \"out2\" or \"jump\" that are specified in"
   211    215   puts "** comments following the \"case\" for each opcode in the vdbe.c"
   212    216   puts "** are encoded into bitvectors as follows:"
   213    217   puts "*/"
   214         -puts "#define OPFLG_JUMP            0x0001  /* jump:  P2 holds jmp target */"
   215         -puts "#define OPFLG_IN1             0x0002  /* in1:   P1 is an input */"
   216         -puts "#define OPFLG_IN2             0x0004  /* in2:   P2 is an input */"
   217         -puts "#define OPFLG_IN3             0x0008  /* in3:   P3 is an input */"
   218         -puts "#define OPFLG_OUT2            0x0010  /* out2:  P2 is an output */"
   219         -puts "#define OPFLG_OUT3            0x0020  /* out3:  P3 is an output */"
          218  +puts "#define OPFLG_JUMP        0x01  /* jump:  P2 holds jmp target */"
          219  +puts "#define OPFLG_IN1         0x02  /* in1:   P1 is an input */"
          220  +puts "#define OPFLG_IN2         0x04  /* in2:   P2 is an input */"
          221  +puts "#define OPFLG_IN3         0x08  /* in3:   P3 is an input */"
          222  +puts "#define OPFLG_OUT2        0x10  /* out2:  P2 is an output */"
          223  +puts "#define OPFLG_OUT3        0x20  /* out3:  P3 is an output */"
   220    224   puts "#define OPFLG_INITIALIZER \173\\"
   221    225   for {set i 0} {$i<=$max} {incr i} {
   222    226     if {$i%8==0} {
   223    227       puts -nonewline [format "/* %3d */" $i]
   224    228     }
   225    229     puts -nonewline [format " 0x%02x," $bv($i)]
   226    230     if {$i%8==7} {
   227    231       puts "\\"
   228    232     }
   229    233   }
   230    234   puts "\175"