/ Check-in [5c3a2a6e]
Login

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

Overview
Comment:Merge in the 3.9.0 changes from trunk.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | begin-concurrent
Files: files | file ages | folders
SHA1:5c3a2a6ed64f4d0e10238720bc2e4ae3af3eded3
User & Date: drh 2015-10-15 07:44:58
Wiki:begin-concurrent
Context
2015-10-16
20:55
Merge the 3.9.1 updates from trunk. check-in: bf866e6c user: drh tags: begin-concurrent
2015-10-15
07:44
Merge in the 3.9.0 changes from trunk. check-in: 5c3a2a6e user: drh tags: begin-concurrent
2015-10-14
20:03
Update makefiles to remove all uses of "awk" - to make building SQLite easier on Windows systems. The only requirements now are tclsh, a C compiler, and common file utilities. check-in: 4bd0d43d user: drh tags: trunk
2015-09-24
15:17
Merge all recent trunk enhancements and fixes into the begin-concurrent branch. check-in: c63c1e15 user: drh tags: begin-concurrent
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Deleted Makefile.arm-wince-mingw32ce-gcc.

     1         -#!/usr/make
     2         -#
     3         -# Makefile for SQLITE
     4         -#
     5         -# This is a template makefile for SQLite.  Most people prefer to
     6         -# use the autoconf generated "configure" script to generate the
     7         -# makefile automatically.  But that does not work for everybody
     8         -# and in every situation.  If you are having problems with the
     9         -# "configure" script, you might want to try this makefile as an
    10         -# alternative.  Create a copy of this file, edit the parameters
    11         -# below and type "make".
    12         -#
    13         -
    14         -#### The directory where to find the mingw32ce tools
    15         -MINGW32CE = /opt/mingw32ce/bin
    16         -
    17         -#### The target prefix of the mingw32ce tools
    18         -TARGET = arm-wince-mingw32ce
    19         -
    20         -#### The toplevel directory of the source tree.  This is the directory
    21         -#    that contains this "Makefile.in" and the "configure.in" script.
    22         -#
    23         -TOP = ../sqlite
    24         -
    25         -#### C Compiler and options for use in building executables that
    26         -#    will run on the platform that is doing the build.
    27         -#
    28         -BCC = gcc -g -O2
    29         -#BCC = /opt/ancic/bin/c89 -0
    30         -
    31         -#### If the target operating system supports the "usleep()" system
    32         -#    call, then define the HAVE_USLEEP macro for all C modules.
    33         -#
    34         -USLEEP = 
    35         -#USLEEP = -DHAVE_USLEEP=1
    36         -
    37         -#### If you want the SQLite library to be safe for use within a 
    38         -#    multi-threaded program, then define the following macro
    39         -#    appropriately:
    40         -#
    41         -THREADSAFE = -DTHREADSAFE=1
    42         -#THREADSAFE = -DTHREADSAFE=0
    43         -
    44         -#### Specify any extra linker options needed to make the library
    45         -#    thread safe
    46         -#
    47         -#THREADLIB = -lpthread
    48         -THREADLIB = 
    49         -
    50         -#### Specify any extra libraries needed to access required functions.
    51         -#
    52         -#TLIBS = -lrt    # fdatasync on Solaris 8
    53         -TLIBS = 
    54         -
    55         -#### Leave SQLITE_DEBUG undefined for maximum speed.  Use SQLITE_DEBUG=1
    56         -#    to check for memory leaks.  Use SQLITE_DEBUG=2 to print a log of all
    57         -#    malloc()s and free()s in order to track down memory leaks.
    58         -#    
    59         -#    SQLite uses some expensive assert() statements in the inner loop.
    60         -#    You can make the library go almost twice as fast if you compile
    61         -#    with -DNDEBUG=1
    62         -#
    63         -#OPTS = -DSQLITE_DEBUG=2
    64         -#OPTS = -DSQLITE_DEBUG=1
    65         -#OPTS = 
    66         -OPTS = -DNDEBUG=1 -DSQLITE_OS_WIN=1 -D_WIN32_WCE=1
    67         -#OPTS += -DHAVE_FDATASYNC=1
    68         -
    69         -#### The suffix to add to executable files.  ".exe" for windows.
    70         -#    Nothing for unix.
    71         -#
    72         -EXE = .exe
    73         -#EXE =
    74         -
    75         -#### C Compile and options for use in building executables that 
    76         -#    will run on the target platform.  This is usually the same
    77         -#    as BCC, unless you are cross-compiling.
    78         -#
    79         -#TCC = gcc -O6
    80         -#TCC = gcc -g -O0 -Wall
    81         -#TCC = gcc -g -O0 -Wall -fprofile-arcs -ftest-coverage
    82         -#TCC = /opt/mingw/bin/i386-mingw32-gcc -O6
    83         -TCC = $(MINGW32CE)/$(TARGET)-gcc -O2
    84         -#TCC = /opt/ansic/bin/c89 -O +z -Wl,-a,archive
    85         -
    86         -#### Tools used to build a static library.
    87         -#
    88         -#AR = ar cr
    89         -#AR = /opt/mingw/bin/i386-mingw32-ar cr
    90         -AR = $(MINGW32CE)/$(TARGET)-ar cr
    91         -#RANLIB = ranlib
    92         -#RANLIB = /opt/mingw/bin/i386-mingw32-ranlib
    93         -RANLIB = $(MINGW32CE)/$(TARGET)-ranlib
    94         -
    95         -#MKSHLIB = gcc -shared
    96         -#SO = so
    97         -#SHPREFIX = lib
    98         -MKSHLIB = $(MINGW32CE)/$(TARGET)-gcc -shared
    99         -SO = dll
   100         -SHPREFIX =
   101         -
   102         -#### Extra compiler options needed for programs that use the TCL library.
   103         -#
   104         -#TCL_FLAGS =
   105         -#TCL_FLAGS = -DSTATIC_BUILD=1
   106         -TCL_FLAGS = -I/home/drh/tcltk/8.5linux
   107         -#TCL_FLAGS = -I/home/drh/tcltk/8.5win -DSTATIC_BUILD=1
   108         -#TCL_FLAGS = -I/home/drh/tcltk/8.3hpux
   109         -
   110         -#### Linker options needed to link against the TCL library.
   111         -#
   112         -#LIBTCL = -ltcl -lm -ldl
   113         -LIBTCL = /home/drh/tcltk/8.5linux/libtcl8.5g.a -lm -ldl
   114         -#LIBTCL = /home/drh/tcltk/8.5win/libtcl85s.a -lmsvcrt
   115         -#LIBTCL = /home/drh/tcltk/8.3hpux/libtcl8.3.a -ldld -lm -lc
   116         -
   117         -#### Additional objects for SQLite library when TCL support is enabled.
   118         -TCLOBJ =
   119         -#TCLOBJ = tclsqlite.o
   120         -
   121         -#### Compiler options needed for programs that use the readline() library.
   122         -#
   123         -READLINE_FLAGS =
   124         -#READLINE_FLAGS = -DHAVE_READLINE=1 -I/usr/include/readline
   125         -
   126         -#### Linker options needed by programs using readline() must link against.
   127         -#
   128         -LIBREADLINE =
   129         -#LIBREADLINE = -static -lreadline -ltermcap
   130         -
   131         -#### Which "awk" program provides nawk compatibilty
   132         -#
   133         -# NAWK = nawk
   134         -NAWK = awk
   135         -
   136         -# You should not have to change anything below this line
   137         -###############################################################################
   138         -include $(TOP)/main.mk

Changes to Makefile.in.

    61     61   
    62     62   # Should the database engine be compiled threadsafe
    63     63   #
    64     64   TCC += -DSQLITE_THREADSAFE=@SQLITE_THREADSAFE@
    65     65   
    66     66   # Any target libraries which libsqlite must be linked against
    67     67   # 
    68         -TLIBS = @LIBS@
           68  +TLIBS = @LIBS@ $(LIBS)
    69     69   
    70     70   # Flags controlling use of the in memory btree implementation
    71     71   #
    72     72   # SQLITE_TEMP_STORE is 0 to force temporary tables to be in a file, 1 to
    73     73   # default to file, 2 to default to memory, and 3 to force temporary
    74     74   # tables to always be in memory.
    75     75   #
................................................................................
   151    151   ALLOWRELEASE = @ALLOWRELEASE@
   152    152   
   153    153   # libtool compile/link/install
   154    154   LTCOMPILE = $(LIBTOOL) --mode=compile --tag=CC $(TCC) $(LTCOMPILE_EXTRAS)
   155    155   LTLINK = $(LIBTOOL) --mode=link $(TCC) $(LTCOMPILE_EXTRAS) @LDFLAGS@ $(LTLINK_EXTRAS)
   156    156   LTINSTALL = $(LIBTOOL) --mode=install $(INSTALL)
   157    157   
   158         -# nawk compatible awk.
   159         -NAWK = @AWK@
   160         -
   161    158   # You should not have to change anything below this line
   162    159   ###############################################################################
   163    160   
   164    161   USE_AMALGAMATION = @USE_AMALGAMATION@
   165    162   
   166    163   # Object files for the SQLite library (non-amalgamation).
   167    164   #
................................................................................
   171    168            expr.lo fault.lo fkey.lo \
   172    169            fts3.lo fts3_aux.lo fts3_expr.lo fts3_hash.lo fts3_icu.lo \
   173    170            fts3_porter.lo fts3_snippet.lo fts3_tokenizer.lo fts3_tokenizer1.lo \
   174    171            fts3_tokenize_vtab.lo \
   175    172            fts3_unicode.lo fts3_unicode2.lo fts3_write.lo \
   176    173   	 fts5.lo \
   177    174            func.lo global.lo hash.lo \
   178         -         icu.lo insert.lo journal.lo legacy.lo loadext.lo \
          175  +         icu.lo insert.lo journal.lo json1.lo legacy.lo loadext.lo \
   179    176            main.lo malloc.lo mem0.lo mem1.lo mem2.lo mem3.lo mem5.lo \
   180    177            memjournal.lo \
   181    178            mutex.lo mutex_noop.lo mutex_unix.lo mutex_w32.lo \
   182    179            notify.lo opcodes.lo os.lo os_unix.lo os_win.lo \
   183    180            pager.lo parse.lo pcache.lo pcache1.lo pragma.lo prepare.lo printf.lo \
   184    181            random.lo resolve.lo rowset.lo rtree.lo select.lo status.lo \
   185    182            table.lo threads.lo tokenize.lo treeview.lo trigger.lo \
................................................................................
   268    265     $(TOP)/src/status.c \
   269    266     $(TOP)/src/shell.c \
   270    267     $(TOP)/src/sqlite.h.in \
   271    268     $(TOP)/src/sqlite3ext.h \
   272    269     $(TOP)/src/sqliteInt.h \
   273    270     $(TOP)/src/sqliteLimit.h \
   274    271     $(TOP)/src/table.c \
   275         -  $(TOP)/src/threads.c \
   276    272     $(TOP)/src/tclsqlite.c \
          273  +  $(TOP)/src/threads.c \
   277    274     $(TOP)/src/tokenize.c \
   278    275     $(TOP)/src/treeview.c \
   279    276     $(TOP)/src/trigger.c \
   280    277     $(TOP)/src/utf.c \
   281    278     $(TOP)/src/update.c \
   282    279     $(TOP)/src/util.c \
   283    280     $(TOP)/src/vacuum.c \
................................................................................
   343    340     $(TOP)/ext/icu/icu.c
   344    341   SRC += \
   345    342     $(TOP)/ext/rtree/rtree.h \
   346    343     $(TOP)/ext/rtree/rtree.c
   347    344   SRC += \
   348    345     $(TOP)/ext/rbu/sqlite3rbu.h \
   349    346     $(TOP)/ext/rbu/sqlite3rbu.c
          347  +SRC += \
          348  +  $(TOP)/ext/misc/json1.c
          349  +
   350    350   
   351    351   
   352    352   # Generated source code files
   353    353   #
   354    354   SRC += \
   355    355     keywordhash.h \
   356    356     opcodes.c \
................................................................................
   413    413     $(TOP)/ext/misc/closure.c \
   414    414     $(TOP)/ext/misc/eval.c \
   415    415     $(TOP)/ext/misc/fileio.c \
   416    416     $(TOP)/ext/misc/fuzzer.c \
   417    417     $(TOP)/ext/fts5/fts5_tcl.c \
   418    418     $(TOP)/ext/fts5/fts5_test_mi.c \
   419    419     $(TOP)/ext/misc/ieee754.c \
   420         -  $(TOP)/ext/misc/json1.c \
   421    420     $(TOP)/ext/misc/nextchar.c \
   422    421     $(TOP)/ext/misc/percentile.c \
   423    422     $(TOP)/ext/misc/regexp.c \
   424    423     $(TOP)/ext/misc/series.c \
   425    424     $(TOP)/ext/misc/spellfix.c \
   426    425     $(TOP)/ext/misc/totype.c \
   427    426     $(TOP)/ext/misc/wholenumber.c
................................................................................
   537    536   #
   538    537   FUZZDATA = \
   539    538     $(TOP)/test/fuzzdata1.db \
   540    539     $(TOP)/test/fuzzdata2.db \
   541    540     $(TOP)/test/fuzzdata3.db \
   542    541     $(TOP)/test/fuzzdata4.db
   543    542   
   544         -# Extra arguments for including json1 in the build of tools
   545         -#
   546         -JSON1_DEP = $(TOP)/ext/misc/json1.c sqlite3ext.h
   547         -JSON1_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_CORE
   548         -JSON1_SRC = $(TOP)/ext/misc/json1.c
   549         -
   550    543   # Standard options to testfixture
   551    544   #
   552    545   TESTOPTS = --verbose=file --output=test-out.txt
          546  +
          547  +# Extra compiler options for various shell tools
          548  +#
          549  +SHELL_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS5
          550  +FUZZERSHELL_OPT = -DSQLITE_ENABLE_JSON1
          551  +FUZZCHECK_OPT = -DSQLITE_ENABLE_JSON1
   553    552   
   554    553   # This is the default Makefile target.  The objects listed here
   555    554   # are what get build when you type just "make" with no arguments.
   556    555   #
   557    556   all:	sqlite3.h libsqlite3.la sqlite3$(TEXE) $(HAVE_TCL:1=libtclsqlite3.la)
   558    557   
   559    558   Makefile: $(TOP)/Makefile.in
................................................................................
   569    568   libtclsqlite3.la:	tclsqlite.lo libsqlite3.la
   570    569   	$(LTLINK) -no-undefined -o $@ tclsqlite.lo \
   571    570   		libsqlite3.la @TCL_STUB_LIB_SPEC@ $(TLIBS) \
   572    571   		-rpath "$(TCLLIBDIR)" \
   573    572   		-version-info "8:6:8" \
   574    573   		-avoid-version
   575    574   
   576         -sqlite3$(TEXE):	$(TOP)/src/shell.c libsqlite3.la sqlite3.h $(JSON1_DEP)
   577         -	$(LTLINK) $(READLINE_FLAGS) $(JSON1_OPT) -o $@ \
   578         -		$(TOP)/src/shell.c $(JSON1_SRC) libsqlite3.la \
          575  +sqlite3$(TEXE):	$(TOP)/src/shell.c libsqlite3.la sqlite3.h
          576  +	$(LTLINK) $(READLINE_FLAGS) $(SHELL_OPT) -o $@ \
          577  +		$(TOP)/src/shell.c libsqlite3.la \
   579    578   		$(LIBREADLINE) $(TLIBS) -rpath "$(libdir)"
   580    579   
   581    580   sqldiff$(TEXE):	$(TOP)/tool/sqldiff.c sqlite3.c sqlite3.h
   582    581   	$(LTLINK) -o $@ $(TOP)/tool/sqldiff.c sqlite3.c $(TLIBS)
   583    582   
   584         -fuzzershell$(TEXE):	$(TOP)/tool/fuzzershell.c sqlite3.c sqlite3.h $(JSON1_DEP)
   585         -	$(LTLINK) -o $@ $(JSON1_OPT) \
   586         -	  $(TOP)/tool/fuzzershell.c $(JSON1_SRC) sqlite3.c $(TLIBS)
          583  +fuzzershell$(TEXE):	$(TOP)/tool/fuzzershell.c sqlite3.c sqlite3.h
          584  +	$(LTLINK) -o $@ $(FUZZERSHELL_OPT) \
          585  +	  $(TOP)/tool/fuzzershell.c sqlite3.c $(TLIBS)
   587    586   
   588         -fuzzcheck$(TEXE):	$(TOP)/test/fuzzcheck.c sqlite3.c sqlite3.h $(JSON1_DEP)
   589         -	$(LTLINK) -o $@ $(JSON1_OPT) $(TOP)/test/fuzzcheck.c $(JSON1_SRC) sqlite3.c $(TLIBS)
          587  +fuzzcheck$(TEXE):	$(TOP)/test/fuzzcheck.c sqlite3.c sqlite3.h
          588  +	$(LTLINK) -o $@ $(FUZZCHECK_OPT) $(TOP)/test/fuzzcheck.c sqlite3.c $(TLIBS)
   590    589   
   591    590   mptester$(TEXE):	sqlite3.c $(TOP)/mptest/mptest.c
   592    591   	$(LTLINK) -o $@ -I. $(TOP)/mptest/mptest.c sqlite3.c \
   593    592   		$(TLIBS) -rpath "$(libdir)"
   594    593   
   595    594   MPTEST1=./mptester$(TEXE) mptest.db $(TOP)/mptest/crash01.test --repeat 20
   596    595   MPTEST2=./mptester$(TEXE) mptest.db $(TOP)/mptest/multiwrite01.test --repeat 20
................................................................................
   608    607   
   609    608   # This target creates a directory named "tsrc" and fills it with
   610    609   # copies of all of the C source code and header files needed to
   611    610   # build on the target system.  Some of the C source code and header
   612    611   # files are automatically generated.  This target takes care of
   613    612   # all that automatic generation.
   614    613   #
   615         -.target_source:	$(SRC) $(TOP)/tool/vdbe-compress.tcl
          614  +.target_source:	$(SRC) $(TOP)/tool/vdbe-compress.tcl fts5.c
   616    615   	rm -rf tsrc
   617    616   	mkdir tsrc
   618    617   	cp -f $(SRC) tsrc
   619    618   	rm tsrc/sqlite.h.in tsrc/parse.y
   620    619   	$(TCLSH_CMD) $(TOP)/tool/vdbe-compress.tcl $(OPTS) <tsrc/vdbe.c >vdbe.new
   621    620   	mv vdbe.new tsrc/vdbe.c
          621  +	cp fts5.c fts5.h tsrc
   622    622   	touch .target_source
   623    623   
   624    624   sqlite3.c:	.target_source $(TOP)/tool/mksqlite3c.tcl
   625    625   	$(TCLSH_CMD) $(TOP)/tool/mksqlite3c.tcl
   626    626   	cp tsrc/shell.c tsrc/sqlite3ext.h .
          627  +
          628  +sqlite3ext.h:	.target_source
          629  +	cp tsrc/sqlite3ext.h .
   627    630   
   628    631   tclsqlite3.c:	sqlite3.c
   629    632   	echo '#ifndef USE_SYSTEM_SQLITE' >tclsqlite3.c
   630    633   	cat sqlite3.c >>tclsqlite3.c
   631    634   	echo '#endif /* USE_SYSTEM_SQLITE */' >>tclsqlite3.c
   632    635   	cat $(TOP)/src/tclsqlite.c >>tclsqlite3.c
   633    636   
................................................................................
   892    895   
   893    896   tclsqlite3$(TEXE):	tclsqlite-shell.lo libsqlite3.la
   894    897   	$(LTLINK) -o $@ tclsqlite-shell.lo \
   895    898   		 libsqlite3.la $(LIBTCL)
   896    899   
   897    900   # Rules to build opcodes.c and opcodes.h
   898    901   #
   899         -opcodes.c:	opcodes.h $(TOP)/mkopcodec.awk
   900         -	$(NAWK) -f $(TOP)/mkopcodec.awk opcodes.h >opcodes.c
          902  +opcodes.c:	opcodes.h $(TOP)/tool/mkopcodec.tcl
          903  +	$(TCLSH_CMD) $(TOP)/tool/mkopcodec.tcl opcodes.h >opcodes.c
   901    904   
   902         -opcodes.h:	parse.h $(TOP)/src/vdbe.c $(TOP)/mkopcodeh.awk
   903         -	cat parse.h $(TOP)/src/vdbe.c | $(NAWK) -f $(TOP)/mkopcodeh.awk >opcodes.h
          905  +opcodes.h:	parse.h $(TOP)/src/vdbe.c $(TOP)/tool/mkopcodeh.tcl
          906  +	cat parse.h $(TOP)/src/vdbe.c | $(TCLSH_CMD) $(TOP)/tool/mkopcodeh.tcl >opcodes.h
   904    907   
   905    908   # Rules to build parse.c and parse.h - the outputs of lemon.
   906    909   #
   907    910   parse.h:	parse.c
   908    911   
   909         -parse.c:	$(TOP)/src/parse.y lemon$(BEXE) $(TOP)/addopcodes.awk
          912  +parse.c:	$(TOP)/src/parse.y lemon$(BEXE) $(TOP)/tool/addopcodes.tcl
   910    913   	cp $(TOP)/src/parse.y .
   911    914   	rm -f parse.h
   912    915   	./lemon$(BEXE) $(OPT_FEATURE_FLAGS) $(OPTS) parse.y
   913    916   	mv parse.h parse.h.temp
   914         -	$(NAWK) -f $(TOP)/addopcodes.awk parse.h.temp >parse.h
          917  +	$(TCLSH_CMD) $(TOP)/tool/addopcodes.tcl parse.h.temp >parse.h
   915    918   
   916    919   sqlite3.h:	$(TOP)/src/sqlite.h.in $(TOP)/manifest.uuid $(TOP)/VERSION
   917    920   	$(TCLSH_CMD) $(TOP)/tool/mksqlite3h.tcl $(TOP) >sqlite3.h
   918    921   
   919    922   keywordhash.h:	$(TOP)/tool/mkkeywordhash.c
   920    923   	$(BCC) -o mkkeywordhash$(BEXE) $(OPT_FEATURE_FLAGS) $(OPTS) $(TOP)/tool/mkkeywordhash.c
   921    924   	./mkkeywordhash$(BEXE) >keywordhash.h
................................................................................
   983    986   
   984    987   fts3_write.lo:	$(TOP)/ext/fts3/fts3_write.c $(HDR) $(EXTHDR)
   985    988   	$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_write.c
   986    989   
   987    990   rtree.lo:	$(TOP)/ext/rtree/rtree.c $(HDR) $(EXTHDR)
   988    991   	$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/rtree/rtree.c
   989    992   
          993  +json1.lo:	$(TOP)/ext/misc/json1.c
          994  +	$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/misc/json1.c
          995  +
   990    996   # FTS5 things
   991    997   #
   992    998   FTS5_SRC = \
   993    999      $(TOP)/ext/fts5/fts5.h \
   994   1000      $(TOP)/ext/fts5/fts5Int.h \
   995   1001      $(TOP)/ext/fts5/fts5_aux.c \
   996   1002      $(TOP)/ext/fts5/fts5_buffer.c \
................................................................................
  1089   1095   
  1090   1096   sqlite3_analyzer.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/spaceanal.tcl
  1091   1097   	echo "#define TCLSH 2" > $@
  1092   1098   	echo "#define SQLITE_ENABLE_DBSTAT_VTAB 1" >> $@
  1093   1099   	cat sqlite3.c $(TOP)/src/tclsqlite.c >> $@
  1094   1100   	echo "static const char *tclsh_main_loop(void){" >> $@
  1095   1101   	echo "static const char *zMainloop = " >> $@
  1096         -	$(NAWK) -f $(TOP)/tool/tostr.awk $(TOP)/tool/spaceanal.tcl >> $@
         1102  +	$(TCLSH_CMD) $(TOP)/tool/tostr.tcl $(TOP)/tool/spaceanal.tcl >> $@
  1097   1103   	echo "; return zMainloop; }" >> $@
  1098   1104   
  1099   1105   sqlite3_analyzer$(TEXE): sqlite3_analyzer.c
  1100   1106   	$(LTLINK) sqlite3_analyzer.c -o $@ $(LIBTCL) $(TLIBS)
  1101   1107   
  1102   1108   showdb$(TEXE):	$(TOP)/tool/showdb.c sqlite3.lo
  1103   1109   	$(LTLINK) -o $@ $(TOP)/tool/showdb.c sqlite3.lo $(TLIBS)

Changes to Makefile.linux-gcc.

   114    114   #READLINE_FLAGS = -DHAVE_READLINE=1 -I/usr/include/readline
   115    115   
   116    116   #### Linker options needed by programs using readline() must link against.
   117    117   #
   118    118   LIBREADLINE =
   119    119   #LIBREADLINE = -static -lreadline -ltermcap
   120    120   
   121         -#### Which "awk" program provides nawk compatibilty
   122         -#
   123         -# NAWK = nawk
   124         -NAWK = awk
   125         -
   126    121   # You should not have to change anything below this line
   127    122   ###############################################################################
   128    123   include $(TOP)/main.mk

Changes to Makefile.msc.

   386    386   !ENDIF
   387    387   !ENDIF
   388    388   
   389    389   # These are additional compiler options used for the shell executable.
   390    390   #
   391    391   !IFNDEF SHELL_COMPILE_OPTS
   392    392   !IF $(DYNAMIC_SHELL)!=0
   393         -SHELL_COMPILE_OPTS = -DSQLITE_ENABLE_JSON1 $(SHELL_CCONV_OPTS) -DSQLITE_API=__declspec(dllimport)
          393  +SHELL_COMPILE_OPTS = -DSQLITE_SHELL_JSON1 $(SHELL_CCONV_OPTS) -DSQLITE_API=__declspec(dllimport)
   394    394   !ELSE
   395         -SHELL_COMPILE_OPTS = -DSQLITE_ENABLE_JSON1 $(SHELL_CCONV_OPTS)
          395  +SHELL_COMPILE_OPTS = -DSQLITE_SHELL_JSON1 $(SHELL_CCONV_OPTS)
   396    396   !ENDIF
   397    397   !ENDIF
   398    398   
   399    399   # This is the core library that the shell executable should depend on.
   400    400   #
   401    401   !IFNDEF SHELL_CORE_DEP
   402    402   !IF $(DYNAMIC_SHELL)!=0
................................................................................
   564    564   !IFNDEF TCLLIBDIR
   565    565   TCLLIBDIR = c:\tcl\lib
   566    566   !ENDIF
   567    567   
   568    568   !IFNDEF LIBTCL
   569    569   LIBTCL = tcl85.lib
   570    570   !ENDIF
          571  +
          572  +!IFNDEF LIBTCLSTUB
          573  +LIBTCLSTUB = tclstub85.lib
          574  +!ENDIF
   571    575   
   572    576   # The locations of the ICU header and library files.  These variables
   573    577   # (ICUINCDIR, ICULIBDIR, and LIBICU) may be overridden via the environment
   574    578   # prior to running nmake in order to match the actual installed location on
   575    579   # this machine.
   576    580   #
   577    581   !IFNDEF ICUINCDIR
................................................................................
   805    809   # If ICU support is enabled, add the linker options for it.
   806    810   #
   807    811   !IF $(USE_ICU)!=0
   808    812   LTLIBPATHS = $(LTLIBPATHS) /LIBPATH:$(ICULIBDIR)
   809    813   LTLIBS = $(LTLIBS) $(LIBICU)
   810    814   !ENDIF
   811    815   
   812         -# nawk compatible awk.
   813         -#
   814         -!IFNDEF NAWK
   815         -NAWK = gawk.exe
   816         -!ENDIF
   817         -
   818    816   # You should not have to change anything below this line
   819    817   ###############################################################################
   820    818   
   821    819   # Object files for the SQLite library (non-amalgamation).
   822    820   #
   823    821   LIBOBJS0 = vdbe.lo parse.lo alter.lo analyze.lo attach.lo auth.lo \
   824    822            backup.lo bitvec.lo btmutex.lo btree.lo build.lo \
................................................................................
  1004   1002     $(TOP)\ext\fts3\fts3_unicode2.c \
  1005   1003     $(TOP)\ext\fts3\fts3_write.c \
  1006   1004     $(TOP)\ext\icu\sqliteicu.h \
  1007   1005     $(TOP)\ext\icu\icu.c \
  1008   1006     $(TOP)\ext\rtree\rtree.h \
  1009   1007     $(TOP)\ext\rtree\rtree.c \
  1010   1008     $(TOP)\ext\rbu\sqlite3rbu.h \
  1011         -  $(TOP)\ext\rbu\sqlite3rbu.c
         1009  +  $(TOP)\ext\rbu\sqlite3rbu.c \
         1010  +  $(TOP)\ext\misc\json1.c
  1012   1011   
  1013   1012   
  1014   1013   # Generated source code files
  1015   1014   #
  1016   1015   SRC5 = \
  1017   1016     keywordhash.h \
  1018   1017     opcodes.c \
................................................................................
  1206   1205   #
  1207   1206   FUZZDATA = \
  1208   1207     $(TOP)\test\fuzzdata1.db \
  1209   1208     $(TOP)\test\fuzzdata2.db \
  1210   1209     $(TOP)\test\fuzzdata3.db \
  1211   1210     $(TOP)\test\fuzzdata4.db
  1212   1211   
  1213         -# Extra arguments for including json1 in the build of tools
         1212  +# Extra compiler options for various shell tools
  1214   1213   #
  1215         -JSON1_DEP = sqlite3ext.h $(TOP)\ext\misc\json1.c
  1216         -JSON1_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_CORE
  1217         -JSON1_SRC = $(TOP)\ext\misc\json1.c
         1214  +SHELL_COMPILE_OPTS = -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS5
         1215  +FUZZERSHELL_COMPILE_OPTS = -DSQLITE_ENABLE_JSON1
         1216  +FUZZCHECK_COMPILE_OPTS = -DSQLITE_ENABLE_JSON1
  1218   1217   
  1219   1218   # Standard options to testfixture
  1220   1219   #
  1221   1220   TESTOPTS = --verbose=file --output=test-out.txt
  1222   1221   
  1223   1222   # This is the default Makefile target.  The objects listed here
  1224   1223   # are what get build when you type just "make" with no arguments.
................................................................................
  1225   1224   #
  1226   1225   all:	dll libsqlite3.lib sqlite3.exe libtclsqlite3.lib
  1227   1226   
  1228   1227   libsqlite3.lib:	$(LIBOBJ)
  1229   1228   	$(LTLIB) $(LTLIBOPTS) /OUT:$@ $(LIBOBJ) $(TLIBS)
  1230   1229   
  1231   1230   libtclsqlite3.lib:	tclsqlite.lo libsqlite3.lib
  1232         -	$(LTLIB) $(LTLIBOPTS) $(LTLIBPATHS) /OUT:$@ tclsqlite.lo libsqlite3.lib $(LIBTCL:tcl=tclstub) $(TLIBS)
         1231  +	$(LTLIB) $(LTLIBOPTS) $(LTLIBPATHS) /OUT:$@ tclsqlite.lo libsqlite3.lib $(LIBTCLSTUB) $(TLIBS)
  1233   1232   
  1234         -sqlite3.exe:	$(TOP)\src\shell.c $(JSON1_DEP) $(SHELL_CORE_DEP) $(LIBRESOBJS) sqlite3.h
  1235         -	$(LTLINK) $(SHELL_COMPILE_OPTS) $(JSON1_OPT) $(READLINE_FLAGS) $(TOP)\src\shell.c $(JSON1_SRC) \
  1236         -		/link /pdb:sqlite3sh.pdb $(LTLINKOPTS) $(SHELL_LINK_OPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LIBREADLINE) $(LTLIBS) $(TLIBS)
         1233  +sqlite3.exe:	$(TOP)\src\shell.c $(SHELL_CORE_DEP) $(LIBRESOBJS) sqlite3.h
         1234  +	$(LTLINK) $(SHELL_COMPILE_OPTS) $(SHELL_COMPILE_OPTS) $(READLINE_FLAGS) $(TOP)\src\shell.c \
         1235  +		/link /pdb:sqlite3sh.pdb $(LDFLAGS) $(LTLINKOPTS) $(SHELL_LINK_OPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LIBREADLINE) $(LTLIBS) $(TLIBS)
  1237   1236   
  1238   1237   sqldiff.exe:	$(TOP)\tool\sqldiff.c sqlite3.c sqlite3.h
  1239         -	$(LTLINK) $(NO_WARN) $(TOP)\tool\sqldiff.c sqlite3.c
         1238  +	$(LTLINK) $(NO_WARN) $(TOP)\tool\sqldiff.c sqlite3.c /link $(LDFLAGS) $(LTLINKOPTS)
  1240   1239   
  1241         -fuzzershell.exe:	$(TOP)\tool\fuzzershell.c sqlite3.c sqlite3.h $(JSON1_DEP)
  1242         -	$(LTLINK) $(NO_WARN) $(JSON1_OPT) \
  1243         -	  $(TOP)\tool\fuzzershell.c $(JSON1_SRC) sqlite3.c
         1240  +fuzzershell.exe:	$(TOP)\tool\fuzzershell.c sqlite3.c sqlite3.h
         1241  +	$(LTLINK) $(NO_WARN) $(FUZZERSHELL_COMPILE_OPTS) \
         1242  +	  $(TOP)\tool\fuzzershell.c sqlite3.c /link $(LDFLAGS) $(LTLINKOPTS)
  1244   1243   
  1245         -fuzzcheck.exe:	$(TOP)\test\fuzzcheck.c sqlite3.c sqlite3.h $(JSON1_DEP)
  1246         -	$(LTLINK) $(NO_WARN) $(JSON1_OPT) $(TOP)\test\fuzzcheck.c $(JSON1_SRC) sqlite3.c
         1244  +fuzzcheck.exe:	$(TOP)\test\fuzzcheck.c sqlite3.c sqlite3.h
         1245  +	$(LTLINK) $(NO_WARN) $(FUZZCHECK_COMPILE_OPTS) $(TOP)\test\fuzzcheck.c sqlite3.c /link $(LDFLAGS) $(LTLINKOPTS)
  1247   1246   
  1248   1247   mptester.exe:	$(TOP)\mptest\mptest.c $(SHELL_CORE_DEP) $(LIBRESOBJS) sqlite3.h
  1249   1248   	$(LTLINK) $(NO_WARN) $(SHELL_COMPILE_OPTS) $(TOP)\mptest\mptest.c \
  1250         -		/link $(LTLINKOPTS) $(LTLIBPATHS) $(SHELL_LINK_OPTS) $(LIBRESOBJS) $(LIBREADLINE) $(LTLIBS) $(TLIBS)
         1249  +		/link $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) $(SHELL_LINK_OPTS) $(LIBRESOBJS) $(LIBREADLINE) $(LTLIBS) $(TLIBS)
  1251   1250   
  1252   1251   MPTEST1 = mptester mptest.db $(TOP)\mptest\crash01.test --repeat 20
  1253   1252   MPTEST2 = mptester mptest.db $(TOP)\mptest\multiwrite01.test --repeat 20
  1254   1253   
  1255   1254   mptest:	mptester.exe
  1256   1255   	del /Q mptest.db 2>NUL
  1257   1256   	$(MPTEST1) --journalmode DELETE
................................................................................
  1265   1264   
  1266   1265   # This target creates a directory named "tsrc" and fills it with
  1267   1266   # copies of all of the C source code and header files needed to
  1268   1267   # build on the target system.  Some of the C source code and header
  1269   1268   # files are automatically generated.  This target takes care of
  1270   1269   # all that automatic generation.
  1271   1270   #
  1272         -.target_source:	$(SRC) $(TOP)\tool\vdbe-compress.tcl
         1271  +.target_source:	$(SRC) $(TOP)\tool\vdbe-compress.tcl fts5.c
  1273   1272   	-rmdir /Q/S tsrc 2>NUL
  1274   1273   	-mkdir tsrc
  1275   1274   	for %i in ($(SRC1)) do copy /Y %i tsrc
  1276   1275   	for %i in ($(SRC2)) do copy /Y %i tsrc
  1277   1276   	for %i in ($(SRC3)) do copy /Y %i tsrc
  1278   1277   	for %i in ($(SRC4)) do copy /Y %i tsrc
  1279   1278   	for %i in ($(SRC5)) do copy /Y %i tsrc
         1279  +	copy /Y fts5.c tsrc
         1280  +	copy /Y fts5.h tsrc
  1280   1281   	del /Q tsrc\sqlite.h.in tsrc\parse.y 2>NUL
  1281   1282   	$(TCLSH_CMD) $(TOP)\tool\vdbe-compress.tcl $(OPTS) < tsrc\vdbe.c > vdbe.new
  1282   1283   	move vdbe.new tsrc\vdbe.c
  1283   1284   	echo > .target_source
  1284   1285   
  1285   1286   sqlite3.c:	.target_source sqlite3ext.h $(TOP)\tool\mksqlite3c.tcl
  1286   1287   	$(TCLSH_CMD) $(TOP)\tool\mksqlite3c.tcl $(MKSQLITE3C_ARGS)
................................................................................
  1327   1328   # Rule to build the Win32 resources object file.
  1328   1329   #
  1329   1330   !IF $(USE_RC)!=0
  1330   1331   $(LIBRESOBJS):	$(TOP)\src\sqlite3.rc $(HDR)
  1331   1332   	echo #ifndef SQLITE_RESOURCE_VERSION > sqlite3rc.h
  1332   1333   	for /F %%V in ('type "$(TOP)\VERSION"') do ( \
  1333   1334   		echo #define SQLITE_RESOURCE_VERSION %%V \
  1334         -			| $(NAWK) "/.*/ { gsub(/[.]/,\",\");print }" >> sqlite3rc.h \
         1335  +			| $(TCLSH_CMD) $(TOP)\tool\replace.tcl exact . ^, >> sqlite3rc.h \
  1335   1336   	)
  1336   1337   	echo #endif >> sqlite3rc.h
  1337   1338   	$(LTRCOMPILE) -fo $(LIBRESOBJS) $(TOP)\src\sqlite3.rc
  1338   1339   !ENDIF
  1339   1340   
  1340   1341   # Rules to build individual *.lo files from files in the src directory.
  1341   1342   #
................................................................................
  1564   1565   tclsqlite.lo:	$(TOP)\src\tclsqlite.c $(HDR)
  1565   1566   	$(LTCOMPILE) $(NO_WARN) -DUSE_TCL_STUBS=1 -DBUILD_sqlite -I$(TCLINCDIR) -c $(TOP)\src\tclsqlite.c
  1566   1567   
  1567   1568   tclsqlite-shell.lo:	$(TOP)\src\tclsqlite.c $(HDR)
  1568   1569   	$(LTCOMPILE) $(NO_WARN) -DTCLSH=1 -DBUILD_sqlite -I$(TCLINCDIR) -c $(TOP)\src\tclsqlite.c
  1569   1570   
  1570   1571   tclsqlite3.exe:	tclsqlite-shell.lo $(SQLITE3C) $(LIBRESOBJS)
  1571         -	$(LTLINK) $(SQLITE3C) /link $(LTLINKOPTS) $(LTLIBPATHS) /OUT:$@ tclsqlite-shell.lo $(LIBRESOBJS) $(LTLIBS) $(TLIBS)
         1572  +	$(LTLINK) $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) /OUT:$@ tclsqlite-shell.lo $(LIBRESOBJS) $(LTLIBS) $(TLIBS)
  1572   1573   
  1573   1574   # Rules to build opcodes.c and opcodes.h
  1574   1575   #
  1575         -opcodes.c:	opcodes.h $(TOP)\mkopcodec.awk
  1576         -	$(NAWK) -f $(TOP)\mkopcodec.awk opcodes.h > opcodes.c
         1576  +opcodes.c:	opcodes.h $(TOP)\tool\mkopcodec.tcl
         1577  +	$(TCLSH_CMD) $(TOP)\tool\mkopcodec.tcl opcodes.h > opcodes.c
  1577   1578   
  1578         -opcodes.h:	parse.h $(TOP)\src\vdbe.c $(TOP)\mkopcodeh.awk
  1579         -	type parse.h $(TOP)\src\vdbe.c | $(NAWK) -f $(TOP)\mkopcodeh.awk > opcodes.h
         1579  +opcodes.h:	parse.h $(TOP)\src\vdbe.c $(TOP)\tool\mkopcodeh.tcl
         1580  +	type parse.h $(TOP)\src\vdbe.c | $(TCLSH_CMD) $(TOP)\tool\mkopcodeh.tcl > opcodes.h
  1580   1581   
  1581   1582   # Rules to build parse.c and parse.h - the outputs of lemon.
  1582   1583   #
  1583   1584   parse.h:	parse.c
  1584   1585   
  1585         -parse.c:	$(TOP)\src\parse.y lemon.exe $(TOP)\addopcodes.awk
         1586  +parse.c:	$(TOP)\src\parse.y lemon.exe $(TOP)\tool\addopcodes.tcl
  1586   1587   	del /Q parse.y parse.h parse.h.temp 2>NUL
  1587   1588   	copy $(TOP)\src\parse.y .
  1588   1589   	.\lemon.exe $(REQ_FEATURE_FLAGS) $(OPT_FEATURE_FLAGS) $(OPTS) parse.y
  1589   1590   	move parse.h parse.h.temp
  1590         -	$(NAWK) -f $(TOP)\addopcodes.awk parse.h.temp > parse.h
         1591  +	$(TCLSH_CMD) $(TOP)\tool\addopcodes.tcl parse.h.temp > parse.h
  1591   1592   
  1592   1593   sqlite3.h:	$(TOP)\src\sqlite.h.in $(TOP)\manifest.uuid $(TOP)\VERSION
  1593   1594   	$(TCLSH_CMD) $(TOP)\tool\mksqlite3h.tcl $(TOP:\=/) > sqlite3.h
  1594   1595   
  1595   1596   sqlite3ext.h: .target_source
  1596   1597   	copy tsrc\sqlite3ext.h .
  1597   1598   
................................................................................
  1727   1728   TESTFIXTURE_SRC = $(TESTSRC) $(TOP)\src\tclsqlite.c $(TESTFIXTURE_SRC1)
  1728   1729   !ENDIF
  1729   1730   
  1730   1731   testfixture.exe:	$(TESTFIXTURE_SRC) $(LIBRESOBJS) $(HDR)
  1731   1732   	$(LTLINK) -DSQLITE_NO_SYNC=1 $(TESTFIXTURE_FLAGS) \
  1732   1733   		-DBUILD_sqlite -I$(TCLINCDIR) \
  1733   1734   		$(TESTFIXTURE_SRC) \
  1734         -		/link $(LTLINKOPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LTLIBS) $(TLIBS)
         1735  +		/link $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LTLIBS) $(TLIBS)
  1735   1736   
  1736   1737   extensiontest: testfixture.exe testloadext.dll
  1737   1738   	.\testfixture.exe $(TOP)\test\loadext.test $(TESTOPTS)
  1738   1739   
  1739   1740   fulltest:	$(TESTPROGS) fuzztest
  1740   1741   	.\testfixture.exe $(TOP)\test\all.test $(TESTOPTS)
  1741   1742   
................................................................................
  1770   1771   
  1771   1772   sqlite3_analyzer.c: $(SQLITE3C) $(TOP)\src\tclsqlite.c $(TOP)\tool\spaceanal.tcl
  1772   1773   	echo #define TCLSH 2 > $@
  1773   1774   	echo #define SQLITE_ENABLE_DBSTAT_VTAB 1 >> $@
  1774   1775   	copy $@ + $(SQLITE3C) + $(TOP)\src\tclsqlite.c $@
  1775   1776   	echo static const char *tclsh_main_loop(void){ >> $@
  1776   1777   	echo static const char *zMainloop = >> $@
  1777         -	$(NAWK) -f $(TOP)\tool\tostr.awk $(TOP)\tool\spaceanal.tcl >> $@
         1778  +	$(TCLSH_CMD) $(TOP)\tool\tostr.tcl $(TOP)\tool\spaceanal.tcl >> $@
  1778   1779   	echo ; return zMainloop; } >> $@
  1779   1780   
  1780   1781   sqlite3_analyzer.exe:	sqlite3_analyzer.c $(LIBRESOBJS)
  1781   1782   	$(LTLINK) $(NO_WARN) -DBUILD_sqlite -I$(TCLINCDIR) sqlite3_analyzer.c \
  1782         -		/link $(LTLINKOPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LTLIBS) $(TLIBS)
         1783  +		/link $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LTLIBS) $(TLIBS)
  1783   1784   
  1784   1785   testloadext.lo:	$(TOP)\src\test_loadext.c
  1785   1786   	$(LTCOMPILE) $(NO_WARN) -c $(TOP)\src\test_loadext.c
  1786   1787   
  1787   1788   testloadext.dll: testloadext.lo
  1788   1789   	$(LD) $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) /DLL /OUT:$@ testloadext.lo
  1789   1790   
  1790   1791   showdb.exe:	$(TOP)\tool\showdb.c $(SQLITE3C)
  1791   1792   	$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \
  1792         -		$(TOP)\tool\showdb.c $(SQLITE3C)
         1793  +		$(TOP)\tool\showdb.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
  1793   1794   
  1794   1795   showstat4.exe:	$(TOP)\tool\showstat4.c $(SQLITE3C)
  1795   1796   	$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \
  1796         -		$(TOP)\tool\showstat4.c $(SQLITE3C)
         1797  +		$(TOP)\tool\showstat4.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
  1797   1798   
  1798   1799   showjournal.exe:	$(TOP)\tool\showjournal.c $(SQLITE3C)
  1799   1800   	$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \
  1800         -		$(TOP)\tool\showjournal.c $(SQLITE3C)
         1801  +		$(TOP)\tool\showjournal.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
  1801   1802   
  1802   1803   showwal.exe:	$(TOP)\tool\showwal.c $(SQLITE3C)
  1803   1804   	$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \
  1804         -		$(TOP)\tool\showwal.c $(SQLITE3C)
         1805  +		$(TOP)\tool\showwal.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
  1805   1806   
  1806   1807   fts3view.exe:	$(TOP)\ext\fts3\tool\fts3view.c $(SQLITE3C)
  1807   1808   	$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \
  1808         -		$(TOP)\ext\fts3\tool\fts3view.c $(SQLITE3C)
         1809  +		$(TOP)\ext\fts3\tool\fts3view.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
  1809   1810   
  1810   1811   rollback-test.exe:	$(TOP)\tool\rollback-test.c $(SQLITE3C)
  1811   1812   	$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \
  1812         -		$(TOP)\tool\rollback-test.c $(SQLITE3C)
         1813  +		$(TOP)\tool\rollback-test.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
  1813   1814   
  1814   1815   LogEst.exe:	$(TOP)\tool\logest.c sqlite3.h
  1815         -	$(LTLINK) $(NO_WARN) -Fe$@ $(TOP)\tool\LogEst.c
         1816  +	$(LTLINK) $(NO_WARN) -Fe$@ $(TOP)\tool\LogEst.c /link $(LDFLAGS) $(LTLINKOPTS)
  1816   1817   
  1817   1818   wordcount.exe:	$(TOP)\test\wordcount.c $(SQLITE3C)
  1818   1819   	$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \
  1819         -		$(TOP)\test\wordcount.c $(SQLITE3C)
         1820  +		$(TOP)\test\wordcount.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
  1820   1821   
  1821   1822   speedtest1.exe:	$(TOP)\test\speedtest1.c $(SQLITE3C)
  1822   1823   	$(LTLINK) $(NO_WARN) -DSQLITE_OMIT_LOAD_EXTENSION -Fe$@ \
  1823         -		$(TOP)\test\speedtest1.c $(SQLITE3C)
         1824  +		$(TOP)\test\speedtest1.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
  1824   1825   
  1825   1826   clean:
  1826   1827   	del /Q *.exp *.lo *.ilk *.lib *.obj *.ncb *.pdb *.sdf *.suo 2>NUL
  1827   1828   	del /Q *.bsc *.cod *.da *.bb *.bbg gmon.out 2>NUL
  1828   1829   	del /Q sqlite3.h opcodes.c opcodes.h 2>NUL
  1829   1830   	del /Q lemon.* lempar.c parse.* 2>NUL
  1830   1831   	del /Q mkkeywordhash.* keywordhash.h 2>NUL
................................................................................
  1854   1855   # Dynamic link library section.
  1855   1856   #
  1856   1857   dll: sqlite3.dll
  1857   1858   
  1858   1859   sqlite3.def: libsqlite3.lib
  1859   1860   	echo EXPORTS > sqlite3.def
  1860   1861   	dumpbin /all libsqlite3.lib \
  1861         -		| $(NAWK) "/ 1 _?sqlite3_/ { sub(/^.* _?/,\"\");print }" \
         1862  +		| $(TCLSH_CMD) $(TOP)\tool\replace.tcl include "^\s+1 _?(sqlite3_.*)$$" \1 \
  1862   1863   		| sort >> sqlite3.def
  1863   1864   
  1864   1865   sqlite3.dll: $(LIBOBJ) $(LIBRESOBJS) $(CORE_LINK_DEP)
  1865   1866   	$(LD) $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) /DLL $(CORE_LINK_OPTS) /OUT:$@ $(LIBOBJ) $(LIBRESOBJS) $(LTLIBS) $(TLIBS)

Deleted Makefile.vxworks.

     1         -#!/usr/make
     2         -#
     3         -# Makefile for SQLITE on VxWorks
     4         -
     5         -ifeq ($(FORCPU),)
     6         -  FORCPU = SH32gnule
     7         -endif
     8         -
     9         -TOOL_FAMILY = gnu
    10         -
    11         -include $(WIND_USR)/tool/gnu/make.$(FORCPU)
    12         -
    13         -#### The toplevel directory of the source tree.  This is the directory
    14         -#    that contains this "Makefile.in" and the "configure.in" script.
    15         -#
    16         -TOP = .
    17         -
    18         -#### C Compiler and options for use in building executables that
    19         -#    will run on the platform that is doing the build.
    20         -#
    21         -BCC = gcc -g -O2
    22         -#BCC = /opt/ancic/bin/c89 -0
    23         -
    24         -#### If the target operating system supports the "usleep()" system
    25         -#    call, then define the HAVE_USLEEP macro for all C modules.
    26         -#
    27         -USLEEP = 
    28         -#USLEEP = -DHAVE_USLEEP=1
    29         -
    30         -#### If you want the SQLite library to be safe for use within a 
    31         -#    multi-threaded program, then define the following macro
    32         -#    appropriately:
    33         -#
    34         -THREADSAFE = -DSQLITE_THREADSAFE=1
    35         -#THREADSAFE = -DSQLITE_THREADSAFE=0
    36         -
    37         -#### Specify any extra linker options needed to make the library
    38         -#    thread safe
    39         -#
    40         -#THREADLIB = -lpthread
    41         -THREADLIB = 
    42         -
    43         -#### Specify any extra libraries needed to access required functions.
    44         -#
    45         -ifeq ($(CPU),SH32) 
    46         -  # for SH4 shared library
    47         -  TLIBS_SHARED += -L$(WIND_USR)/lib/sh/SH32/commonle/PIC
    48         -else 
    49         -  # for all other CPUs shared library
    50         -  TLIBS_SHARED += $(LD_LINK_PATH_ATEND) $(LD_PARTIAL_LAST_FLAGS)
    51         -endif
    52         -# for static library
    53         -TLIBS += $(LD_LINK_PATH_ATEND) $(LD_PARTIAL_LAST_FLAGS)
    54         -
    55         -#### Leave SQLITE_DEBUG undefined for maximum speed.  Use SQLITE_DEBUG=1
    56         -#    to check for memory leaks.  Use SQLITE_DEBUG=2 to print a log of all
    57         -#    malloc()s and free()s in order to track down memory leaks.
    58         -#    
    59         -#    SQLite uses some expensive assert() statements in the inner loop.
    60         -#    You can make the library go almost twice as fast if you compile
    61         -#    with -DNDEBUG=1
    62         -#
    63         -#OPTS = -DSQLITE_DEBUG=2
    64         -#OPTS = -DSQLITE_DEBUG=1
    65         -#OPTS = 
    66         -OPTS = -DNDEBUG=1 -DSQLITE_OS_UNIX=1 $(THREADSAFE)
    67         -OPTS += -DSQLITE_OMIT_LOAD_EXTENSION=1
    68         -OPTS += -DSQLITE_ENABLE_LOCKING_STYLE=1
    69         -OPTS += -DSQLITE_THREAD_OVERRIDE_LOCK=0
    70         -OPTS += -DSQLITE_ENABLE_COLUMN_METADATA=1
    71         -OPTS += -DHAVE_FDATASYNC=1
    72         -
    73         -#### The suffix to add to executable files.  ".exe" for windows.
    74         -#    Nothing for unix.
    75         -#
    76         -EXE = .vxe
    77         -#EXE =
    78         -
    79         -#### C Compile and options for use in building executables that 
    80         -#    will run on the target platform.  This is usually the same
    81         -#    as BCC, unless you are cross-compiling.
    82         -#
    83         -#TCC = gcc -O6
    84         -#TCC = gcc -g -O0 -Wall
    85         -#TCC = gcc -g -O0 -Wall -fprofile-arcs -ftest-coverage
    86         -#TCC = /opt/mingw/bin/i386-mingw32-gcc -O6
    87         -TCC = $(CC) $(DEFINE_CC) -O2 -g -mrtp $(CC_ARCH_SPEC) -D_REENTRANT=1 -D_VX_CPU=_VX_$(CPU) -D_VX_TOOL_FAMILY=$(TOOL_FAMILY) -D_VX_TOOL=$(TOOL)
    88         -TCC += -I$(WIND_USR)/h -I$(WIND_USR)/h/wrn/coreip
    89         -#TCC = /opt/ansic/bin/c89 -O +z -Wl,-a,archive
    90         -
    91         -#TCC_SHARED = $(TCC) -fPIC
    92         -TCC_SHARED = $(TCC)
    93         -
    94         -#### Tools used to build a static library.
    95         -#
    96         -#ARX = ar cr
    97         -#ARX = /opt/mingw/bin/i386-mingw32-ar cr
    98         -AR += cr
    99         -#RANLIB = ranlib
   100         -#RANLIB = /opt/mingw/bin/i386-mingw32-ranlib
   101         -
   102         -#MKSHLIB = gcc -shared
   103         -#SO = so
   104         -#SHPREFIX = lib
   105         -MKSHLIB = $(CC) $(DEFINE_CC) -mrtp -shared $(CC_ARCH_SPEC) -D_VX_CPU=_VX_$(CPU) -D_VX_TOOL_FAMILY=$(TOOL_FAMILY) -D_VX_TOOL=$(TOOL)
   106         -SO = so
   107         -SHPREFIX = lib
   108         -
   109         -#### Extra compiler options needed for programs that use the TCL library.
   110         -#
   111         -#TCL_FLAGS =
   112         -#TCL_FLAGS = -DSTATIC_BUILD=1
   113         -TCL_FLAGS = -I/home/drh/tcltk/8.5linux
   114         -#TCL_FLAGS = -I/home/drh/tcltk/8.5win -DSTATIC_BUILD=1
   115         -#TCL_FLAGS = -I/home/drh/tcltk/8.3hpux
   116         -
   117         -#### Linker options needed to link against the TCL library.
   118         -#
   119         -#LIBTCL = -ltcl -lm -ldl
   120         -LIBTCL = /home/drh/tcltk/8.5linux/libtcl8.5g.a -lm -ldl
   121         -#LIBTCL = /home/drh/tcltk/8.5win/libtcl85s.a -lmsvcrt
   122         -#LIBTCL = /home/drh/tcltk/8.3hpux/libtcl8.3.a -ldld -lm -lc
   123         -
   124         -#### Additional objects for SQLite library when TCL support is enabled.
   125         -TCLOBJ =
   126         -#TCLOBJ = tclsqlite.o
   127         -
   128         -#### Compiler options needed for programs that use the readline() library.
   129         -#
   130         -READLINE_FLAGS =
   131         -#READLINE_FLAGS = -DHAVE_READLINE=1 -I/usr/include/readline
   132         -
   133         -#### Linker options needed by programs using readline() must link against.
   134         -#
   135         -LIBREADLINE =
   136         -#LIBREADLINE = -static -lreadline -ltermcap
   137         -
   138         -#### Which "awk" program provides nawk compatibilty
   139         -#
   140         -# NAWK = nawk
   141         -NAWK = awk
   142         -
   143         -
   144         -#### Pasted and adapted main.mk file
   145         -###############################################################################
   146         -# The following macros should be defined before this script is
   147         -# invoked:
   148         -#
   149         -# TOP              The toplevel directory of the source tree.  This is the
   150         -#                  directory that contains this "Makefile.in" and the
   151         -#                  "configure.in" script.
   152         -#
   153         -# BCC              C Compiler and options for use in building executables that
   154         -#                  will run on the platform that is doing the build.
   155         -#
   156         -# THREADLIB        Specify any extra linker options needed to make the library
   157         -#                  thread safe
   158         -#
   159         -# OPTS             Extra compiler command-line options.
   160         -#
   161         -# EXE              The suffix to add to executable files.  ".exe" for windows
   162         -#                  and "" for Unix.
   163         -#
   164         -# TCC              C Compiler and options for use in building executables that 
   165         -#                  will run on the target platform.  This is usually the same
   166         -#                  as BCC, unless you are cross-compiling.
   167         -#
   168         -# AR               Tools used to build a static library.
   169         -# RANLIB
   170         -#
   171         -# TCL_FLAGS        Extra compiler options needed for programs that use the
   172         -#                  TCL library.
   173         -#
   174         -# LIBTCL           Linker options needed to link against the TCL library.
   175         -#
   176         -# READLINE_FLAGS   Compiler options needed for programs that use the
   177         -#                  readline() library.
   178         -#
   179         -# LIBREADLINE      Linker options needed by programs using readline() must
   180         -#                  link against.
   181         -#
   182         -# NAWK             Nawk compatible awk program.  Older (obsolete?) solaris
   183         -#                  systems need this to avoid using the original AT&T AWK.
   184         -#
   185         -# Once the macros above are defined, the rest of this make script will
   186         -# build the SQLite library and testing tools.
   187         -################################################################################
   188         -
   189         -# This is how we compile
   190         -#
   191         -TCCX = $(TCC) $(OPTS) -I. -I$(TOP)/src -I$(TOP)
   192         -TCCX_SHARED = $(TCC_SHARED) $(OPTS) -I. -I$(TOP)/src -I$(TOP) \
   193         -	-I$(TOP)/ext/rtree -I$(TOP)/ext/icu -I$(TOP)/ext/fts3 \
   194         -	-I$(TOP)/ext/async
   195         -
   196         -# Object files for the SQLite library.
   197         -#
   198         -LIBOBJ+= alter.o analyze.o attach.o auth.o \
   199         -         backup.o bitvec.o btmutex.o btree.o build.o \
   200         -         callback.o complete.o date.o delete.o expr.o fault.o \
   201         -         fts3.o fts3_expr.o fts3_hash.o fts3_icu.o fts3_porter.o \
   202         -         fts3_tokenizer.o fts3_tokenizer1.o \
   203         -         func.o global.o hash.o \
   204         -         icu.o insert.o journal.o legacy.o loadext.o \
   205         -         main.o malloc.o mem0.o mem1.o mem2.o mem3.o mem5.o \
   206         -         memjournal.o \
   207         -         mutex.o mutex_noop.o mutex_unix.o mutex_w32.o \
   208         -         notify.o opcodes.o os.o os_unix.o os_win.o \
   209         -         pager.o parse.o pcache.o pcache1.o pragma.o prepare.o printf.o \
   210         -         random.o resolve.o rowset.o rtree.o select.o status.o \
   211         -         table.o tokenize.o trigger.o \
   212         -         update.o util.o vacuum.o \
   213         -         vdbe.o vdbeapi.o vdbeaux.o vdbeblob.o vdbemem.o \
   214         -         walker.o where.o utf.o vtab.o
   215         -
   216         -
   217         -
   218         -# All of the source code files.
   219         -#
   220         -SRC = \
   221         -  $(TOP)/src/alter.c \
   222         -  $(TOP)/src/analyze.c \
   223         -  $(TOP)/src/attach.c \
   224         -  $(TOP)/src/auth.c \
   225         -  $(TOP)/src/backup.c \
   226         -  $(TOP)/src/bitvec.c \
   227         -  $(TOP)/src/btmutex.c \
   228         -  $(TOP)/src/btree.c \
   229         -  $(TOP)/src/btree.h \
   230         -  $(TOP)/src/btreeInt.h \
   231         -  $(TOP)/src/build.c \
   232         -  $(TOP)/src/callback.c \
   233         -  $(TOP)/src/complete.c \
   234         -  $(TOP)/src/ctime.c \
   235         -  $(TOP)/src/date.c \
   236         -  $(TOP)/src/delete.c \
   237         -  $(TOP)/src/expr.c \
   238         -  $(TOP)/src/fault.c \
   239         -  $(TOP)/src/func.c \
   240         -  $(TOP)/src/global.c \
   241         -  $(TOP)/src/hash.c \
   242         -  $(TOP)/src/hash.h \
   243         -  $(TOP)/src/hwtime.h \
   244         -  $(TOP)/src/insert.c \
   245         -  $(TOP)/src/journal.c \
   246         -  $(TOP)/src/legacy.c \
   247         -  $(TOP)/src/loadext.c \
   248         -  $(TOP)/src/main.c \
   249         -  $(TOP)/src/malloc.c \
   250         -  $(TOP)/src/mem0.c \
   251         -  $(TOP)/src/mem1.c \
   252         -  $(TOP)/src/mem2.c \
   253         -  $(TOP)/src/mem3.c \
   254         -  $(TOP)/src/mem5.c \
   255         -  $(TOP)/src/memjournal.c \
   256         -  $(TOP)/src/msvc.h \
   257         -  $(TOP)/src/mutex.c \
   258         -  $(TOP)/src/mutex.h \
   259         -  $(TOP)/src/mutex_noop.c \
   260         -  $(TOP)/src/mutex_unix.c \
   261         -  $(TOP)/src/mutex_w32.c \
   262         -  $(TOP)/src/notify.c \
   263         -  $(TOP)/src/os.c \
   264         -  $(TOP)/src/os.h \
   265         -  $(TOP)/src/os_common.h \
   266         -  $(TOP)/src/os_setup.h \
   267         -  $(TOP)/src/os_unix.c \
   268         -  $(TOP)/src/os_win.c \
   269         -  $(TOP)/src/os_win.h \
   270         -  $(TOP)/src/pager.c \
   271         -  $(TOP)/src/pager.h \
   272         -  $(TOP)/src/parse.y \
   273         -  $(TOP)/src/pcache.c \
   274         -  $(TOP)/src/pcache.h \
   275         -  $(TOP)/src/pcache1.c \
   276         -  $(TOP)/src/pragma.c \
   277         -  $(TOP)/src/prepare.c \
   278         -  $(TOP)/src/printf.c \
   279         -  $(TOP)/src/random.c \
   280         -  $(TOP)/src/resolve.c \
   281         -  $(TOP)/src/rowset.c \
   282         -  $(TOP)/src/select.c \
   283         -  $(TOP)/src/status.c \
   284         -  $(TOP)/src/shell.c \
   285         -  $(TOP)/src/sqlite.h.in \
   286         -  $(TOP)/src/sqlite3ext.h \
   287         -  $(TOP)/src/sqliteInt.h \
   288         -  $(TOP)/src/sqliteLimit.h \
   289         -  $(TOP)/src/table.c \
   290         -  $(TOP)/src/tclsqlite.c \
   291         -  $(TOP)/src/tokenize.c \
   292         -  $(TOP)/src/trigger.c \
   293         -  $(TOP)/src/utf.c \
   294         -  $(TOP)/src/update.c \
   295         -  $(TOP)/src/util.c \
   296         -  $(TOP)/src/vacuum.c \
   297         -  $(TOP)/src/vdbe.c \
   298         -  $(TOP)/src/vdbe.h \
   299         -  $(TOP)/src/vdbeapi.c \
   300         -  $(TOP)/src/vdbeaux.c \
   301         -  $(TOP)/src/vdbeblob.c \
   302         -  $(TOP)/src/vdbemem.c \
   303         -  $(TOP)/src/vdbeInt.h \
   304         -  $(TOP)/src/vtab.c \
   305         -  $(TOP)/src/walker.c \
   306         -  $(TOP)/src/where.c
   307         -
   308         -# Source code for extensions
   309         -#
   310         -SRC += \
   311         -  $(TOP)/ext/fts1/fts1.c \
   312         -  $(TOP)/ext/fts1/fts1.h \
   313         -  $(TOP)/ext/fts1/fts1_hash.c \
   314         -  $(TOP)/ext/fts1/fts1_hash.h \
   315         -  $(TOP)/ext/fts1/fts1_porter.c \
   316         -  $(TOP)/ext/fts1/fts1_tokenizer.h \
   317         -  $(TOP)/ext/fts1/fts1_tokenizer1.c
   318         -SRC += \
   319         -  $(TOP)/ext/fts2/fts2.c \
   320         -  $(TOP)/ext/fts2/fts2.h \
   321         -  $(TOP)/ext/fts2/fts2_hash.c \
   322         -  $(TOP)/ext/fts2/fts2_hash.h \
   323         -  $(TOP)/ext/fts2/fts2_icu.c \
   324         -  $(TOP)/ext/fts2/fts2_porter.c \
   325         -  $(TOP)/ext/fts2/fts2_tokenizer.h \
   326         -  $(TOP)/ext/fts2/fts2_tokenizer.c \
   327         -  $(TOP)/ext/fts2/fts2_tokenizer1.c
   328         -SRC += \
   329         -  $(TOP)/ext/fts3/fts3.c \
   330         -  $(TOP)/ext/fts3/fts3.h \
   331         -  $(TOP)/ext/fts3/fts3_expr.c \
   332         -  $(TOP)/ext/fts3/fts3_expr.h \
   333         -  $(TOP)/ext/fts3/fts3_hash.c \
   334         -  $(TOP)/ext/fts3/fts3_hash.h \
   335         -  $(TOP)/ext/fts3/fts3_icu.c \
   336         -  $(TOP)/ext/fts3/fts3_porter.c \
   337         -  $(TOP)/ext/fts3/fts3_tokenizer.h \
   338         -  $(TOP)/ext/fts3/fts3_tokenizer.c \
   339         -  $(TOP)/ext/fts3/fts3_tokenizer1.c
   340         -SRC += \
   341         -  $(TOP)/ext/icu/sqliteicu.h \
   342         -  $(TOP)/ext/icu/icu.c 
   343         -SRC += \
   344         -  $(TOP)/ext/rtree/rtree.h \
   345         -  $(TOP)/ext/rtree/rtree.c
   346         -
   347         -
   348         -# Generated source code files
   349         -#
   350         -SRC += \
   351         -  keywordhash.h \
   352         -  opcodes.c \
   353         -  opcodes.h \
   354         -  parse.c \
   355         -  parse.h \
   356         -  sqlite3.h
   357         -
   358         -
   359         -# Source code to the test files.
   360         -#
   361         -TESTSRC = \
   362         -  $(TOP)/src/test1.c \
   363         -  $(TOP)/src/test2.c \
   364         -  $(TOP)/src/test3.c \
   365         -  $(TOP)/src/test4.c \
   366         -  $(TOP)/src/test5.c \
   367         -  $(TOP)/src/test6.c \
   368         -  $(TOP)/src/test7.c \
   369         -  $(TOP)/src/test8.c \
   370         -  $(TOP)/src/test9.c \
   371         -  $(TOP)/src/test_autoext.c \
   372         -  $(TOP)/src/test_async.c \
   373         -  $(TOP)/src/test_backup.c \
   374         -  $(TOP)/src/test_btree.c \
   375         -  $(TOP)/src/test_config.c \
   376         -  $(TOP)/src/test_devsym.c \
   377         -  $(TOP)/src/test_func.c \
   378         -  $(TOP)/src/test_hexio.c \
   379         -  $(TOP)/src/test_journal.c \
   380         -  $(TOP)/src/test_malloc.c \
   381         -  $(TOP)/src/test_md5.c \
   382         -  $(TOP)/src/test_mutex.c \
   383         -  $(TOP)/src/test_onefile.c \
   384         -  $(TOP)/src/test_osinst.c \
   385         -  $(TOP)/src/test_pcache.c \
   386         -  $(TOP)/src/test_schema.c \
   387         -  $(TOP)/src/test_server.c \
   388         -  $(TOP)/src/test_tclvar.c \
   389         -  $(TOP)/src/test_thread.c \
   390         -  $(TOP)/src/test_vfs.c \
   391         -  $(TOP)/src/test_wsd.c \
   392         -
   393         -#TESTSRC += $(TOP)/ext/fts2/fts2_tokenizer.c
   394         -#TESTSRC += $(TOP)/ext/fts3/fts3_tokenizer.c
   395         -
   396         -TESTSRC2 = \
   397         -  $(TOP)/src/attach.c $(TOP)/src/backup.c $(TOP)/src/btree.c                   \
   398         -  $(TOP)/src/build.c $(TOP)/src/ctime.c $(TOP)/src/date.c                      \
   399         -  $(TOP)/src/expr.c $(TOP)/src/func.c $(TOP)/src/insert.c $(TOP)/src/os.c      \
   400         -  $(TOP)/src/os_unix.c $(TOP)/src/os_win.c                 \
   401         -  $(TOP)/src/pager.c $(TOP)/src/pragma.c $(TOP)/src/prepare.c                  \
   402         -  $(TOP)/src/printf.c $(TOP)/src/random.c $(TOP)/src/pcache.c                  \
   403         -  $(TOP)/src/pcache1.c $(TOP)/src/select.c $(TOP)/src/tokenize.c               \
   404         -  $(TOP)/src/utf.c $(TOP)/src/util.c $(TOP)/src/vdbeapi.c $(TOP)/src/vdbeaux.c \
   405         -  $(TOP)/src/vdbe.c $(TOP)/src/vdbemem.c $(TOP)/src/where.c parse.c            \
   406         -  $(TOP)/ext/fts3/fts3.c $(TOP)/ext/fts3/fts3_expr.c                           \
   407         -  $(TOP)/ext/fts3/fts3_tokenizer.c                                             \
   408         -  $(TOP)/ext/async/sqlite3async.c
   409         -
   410         -# Header files used by all library source files.
   411         -#
   412         -HDR = \
   413         -   $(TOP)/src/btree.h \
   414         -   $(TOP)/src/btreeInt.h \
   415         -   $(TOP)/src/hash.h \
   416         -   $(TOP)/src/hwtime.h \
   417         -   keywordhash.h \
   418         -   $(TOP)/src/msvc.h \
   419         -   $(TOP)/src/mutex.h \
   420         -   opcodes.h \
   421         -   $(TOP)/src/os.h \
   422         -   $(TOP)/src/os_common.h \
   423         -   $(TOP)/src/os_setup.h \
   424         -   $(TOP)/src/os_win.h \
   425         -   $(TOP)/src/pager.h \
   426         -   $(TOP)/src/pcache.h \
   427         -   parse.h  \
   428         -   sqlite3.h  \
   429         -   $(TOP)/src/sqlite3ext.h \
   430         -   $(TOP)/src/sqliteInt.h  \
   431         -   $(TOP)/src/sqliteLimit.h \
   432         -   $(TOP)/src/vdbe.h \
   433         -   $(TOP)/src/vdbeInt.h
   434         -
   435         -# Header files used by extensions
   436         -#
   437         -EXTHDR += \
   438         -  $(TOP)/ext/fts1/fts1.h \
   439         -  $(TOP)/ext/fts1/fts1_hash.h \
   440         -  $(TOP)/ext/fts1/fts1_tokenizer.h
   441         -EXTHDR += \
   442         -  $(TOP)/ext/fts2/fts2.h \
   443         -  $(TOP)/ext/fts2/fts2_hash.h \
   444         -  $(TOP)/ext/fts2/fts2_tokenizer.h
   445         -EXTHDR += \
   446         -  $(TOP)/ext/fts3/fts3.h \
   447         -  $(TOP)/ext/fts3/fts3_expr.h \
   448         -  $(TOP)/ext/fts3/fts3_hash.h \
   449         -  $(TOP)/ext/fts3/fts3_tokenizer.h
   450         -EXTHDR += \
   451         -  $(TOP)/ext/rtree/rtree.h
   452         -EXTHDR += \
   453         -  $(TOP)/ext/icu/sqliteicu.h
   454         -
   455         -# This is the default Makefile target.  The objects listed here
   456         -# are what get build when you type just "make" with no arguments.
   457         -#
   458         -all:	sqlite3.h libsqlite3.a sqlite3$(EXE)
   459         -
   460         -libsqlite3.a:	$(LIBOBJ)
   461         -	$(AR) libsqlite3.a $(LIBOBJ)
   462         -	$(RANLIB) libsqlite3.a
   463         -
   464         -$(SHPREFIX)sqlite3.$(SO):	$(LIBOBJ)
   465         -	$(MKSHLIB) -o $(SHPREFIX)sqlite3.$(SO) $(LIBOBJ) $(TLIBS_SHARED)
   466         -
   467         -sqlite3$(EXE):	$(TOP)/src/shell.c libsqlite3.a sqlite3.h
   468         -	$(TCCX) $(READLINE_FLAGS) -o sqlite3$(EXE)      \
   469         -		$(TOP)/src/shell.c                      \
   470         -		$(LIBREADLINE) $(TLIBS) $(THREADLIB) -L. -lsqlite3
   471         -
   472         -# This target creates a directory named "tsrc" and fills it with
   473         -# copies of all of the C source code and header files needed to
   474         -# build on the target system.  Some of the C source code and header
   475         -# files are automatically generated.  This target takes care of
   476         -# all that automatic generation.
   477         -#
   478         -target_source:	$(SRC)
   479         -	rm -rf tsrc
   480         -	mkdir tsrc
   481         -	cp -f $(SRC) tsrc
   482         -	rm tsrc/sqlite.h.in tsrc/parse.y
   483         -	touch target_source
   484         -
   485         -sqlite3.c:	target_source $(TOP)/tool/mksqlite3c.tcl
   486         -	tclsh $(TOP)/tool/mksqlite3c.tcl
   487         -	cp sqlite3.c tclsqlite3.c
   488         -	cat $(TOP)/src/tclsqlite.c >>tclsqlite3.c
   489         -
   490         -fts2amal.c:	target_source $(TOP)/ext/fts2/mkfts2amal.tcl
   491         -	tclsh $(TOP)/ext/fts2/mkfts2amal.tcl
   492         -
   493         -fts3amal.c:	target_source $(TOP)/ext/fts3/mkfts3amal.tcl
   494         -	tclsh $(TOP)/ext/fts3/mkfts3amal.tcl
   495         -
   496         -# Rules to build the LEMON compiler generator
   497         -#
   498         -lemon:	$(TOP)/tool/lemon.c $(TOP)/src/lempar.c
   499         -	$(BCC) -o lemon $(TOP)/tool/lemon.c
   500         -	cp $(TOP)/src/lempar.c .
   501         -
   502         -# Rules to build individual *.o files from generated *.c files. This
   503         -# applies to:
   504         -#
   505         -#     parse.o
   506         -#     opcodes.o
   507         -#
   508         -%.o: %.c $(HDR)
   509         -	$(TCCX_SHARED) -c $<
   510         -
   511         -# Rules to build individual *.o files from files in the src directory.
   512         -#
   513         -%.o: $(TOP)/src/%.c $(HDR)
   514         -	$(TCCX_SHARED) -c $<
   515         -
   516         -tclsqlite.o:	$(TOP)/src/tclsqlite.c $(HDR)
   517         -	$(TCCX_SHARED) $(TCL_FLAGS) -c $(TOP)/src/tclsqlite.c
   518         -
   519         -
   520         -
   521         -# Rules to build opcodes.c and opcodes.h
   522         -#
   523         -opcodes.c:	opcodes.h $(TOP)/mkopcodec.awk
   524         -	$(NAWK) -f $(TOP)/mkopcodec.awk opcodes.h >opcodes.c
   525         -
   526         -opcodes.h:	parse.h $(TOP)/src/vdbe.c $(TOP)/mkopcodeh.awk
   527         -	cat parse.h $(TOP)/src/vdbe.c | \
   528         -		$(NAWK) -f $(TOP)/mkopcodeh.awk >opcodes.h
   529         -
   530         -# Rules to build parse.c and parse.h - the outputs of lemon.
   531         -#
   532         -parse.h:	parse.c
   533         -
   534         -parse.c:	$(TOP)/src/parse.y lemon $(TOP)/addopcodes.awk
   535         -	cp $(TOP)/src/parse.y .
   536         -	rm -f parse.h
   537         -	./lemon $(OPTS) parse.y
   538         -	mv parse.h parse.h.temp
   539         -	awk -f $(TOP)/addopcodes.awk parse.h.temp >parse.h
   540         -
   541         -sqlite3.h:	$(TOP)/src/sqlite.h.in 
   542         -	sed -e s/--VERS--/`cat ${TOP}/VERSION`/ \
   543         -	    -e s/--VERSION-NUMBER--/`cat ${TOP}/VERSION | sed 's/[^0-9]/ /g' | $(NAWK) '{printf "%d%03d%03d",$$1,$$2,$$3}'`/ \
   544         -                 $(TOP)/src/sqlite.h.in >sqlite3.h
   545         -
   546         -keywordhash.h:	$(TOP)/tool/mkkeywordhash.c
   547         -	$(BCC) -o mkkeywordhash $(OPTS) $(TOP)/tool/mkkeywordhash.c
   548         -	./mkkeywordhash >keywordhash.h
   549         -
   550         -
   551         -
   552         -# Rules to build the extension objects.
   553         -#
   554         -icu.o:	$(TOP)/ext/icu/icu.c $(HDR) $(EXTHDR)
   555         -	$(TCCX_SHARED) -DSQLITE_CORE -c $(TOP)/ext/icu/icu.c
   556         -
   557         -fts2.o:	$(TOP)/ext/fts2/fts2.c $(HDR) $(EXTHDR)
   558         -	$(TCCX_SHARED) -DSQLITE_CORE -c $(TOP)/ext/fts2/fts2.c
   559         -
   560         -fts2_hash.o:	$(TOP)/ext/fts2/fts2_hash.c $(HDR) $(EXTHDR)
   561         -	$(TCCX_SHARED) -DSQLITE_CORE -c $(TOP)/ext/fts2/fts2_hash.c
   562         -
   563         -fts2_icu.o:	$(TOP)/ext/fts2/fts2_icu.c $(HDR) $(EXTHDR)
   564         -	$(TCCX_SHARED) -DSQLITE_CORE -c $(TOP)/ext/fts2/fts2_icu.c
   565         -
   566         -fts2_porter.o:	$(TOP)/ext/fts2/fts2_porter.c $(HDR) $(EXTHDR)
   567         -	$(TCCX_SHARED) -DSQLITE_CORE -c $(TOP)/ext/fts2/fts2_porter.c
   568         -
   569         -fts2_tokenizer.o:	$(TOP)/ext/fts2/fts2_tokenizer.c $(HDR) $(EXTHDR)
   570         -	$(TCCX_SHARED) -DSQLITE_CORE -c $(TOP)/ext/fts2/fts2_tokenizer.c
   571         -
   572         -fts2_tokenizer1.o:	$(TOP)/ext/fts2/fts2_tokenizer1.c $(HDR) $(EXTHDR)
   573         -	$(TCCX_SHARED) -DSQLITE_CORE -c $(TOP)/ext/fts2/fts2_tokenizer1.c
   574         -
   575         -fts3.o:	$(TOP)/ext/fts3/fts3.c $(HDR) $(EXTHDR)
   576         -	$(TCCX_SHARED) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3.c
   577         -
   578         -fts3_expr.o:	$(TOP)/ext/fts3/fts3_expr.c $(HDR) $(EXTHDR)
   579         -	$(TCCX_SHARED) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_expr.c
   580         -
   581         -fts3_hash.o:	$(TOP)/ext/fts3/fts3_hash.c $(HDR) $(EXTHDR)
   582         -	$(TCCX_SHARED) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_hash.c
   583         -
   584         -fts3_icu.o:	$(TOP)/ext/fts3/fts3_icu.c $(HDR) $(EXTHDR)
   585         -	$(TCCX_SHARED) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_icu.c
   586         -
   587         -fts3_porter.o:	$(TOP)/ext/fts3/fts3_porter.c $(HDR) $(EXTHDR)
   588         -	$(TCCX_SHARED) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_porter.c
   589         -
   590         -fts3_tokenizer.o:	$(TOP)/ext/fts3/fts3_tokenizer.c $(HDR) $(EXTHDR)
   591         -	$(TCCX_SHARED) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_tokenizer.c
   592         -
   593         -fts3_tokenizer1.o:	$(TOP)/ext/fts3/fts3_tokenizer1.c $(HDR) $(EXTHDR)
   594         -	$(TCCX_SHARED) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_tokenizer1.c
   595         -
   596         -rtree.o:	$(TOP)/ext/rtree/rtree.c $(HDR) $(EXTHDR)
   597         -	$(TCCX_SHARED) -DSQLITE_CORE -c $(TOP)/ext/rtree/rtree.c
   598         -
   599         -
   600         -# Rules for building test programs and for running tests
   601         -#
   602         -tclsqlite3:	$(TOP)/src/tclsqlite.c libsqlite3.a
   603         -	$(TCCX_SHARED) $(TCL_FLAGS) -DTCLSH=1 -o tclsqlite3 \
   604         -		$(TOP)/src/tclsqlite.c libsqlite3.a $(LIBTCL) $(THREADLIB)
   605         -
   606         -
   607         -# Rules to build the 'testfixture' application.
   608         -#
   609         -TESTFIXTURE_FLAGS  = -DTCLSH=1 -DSQLITE_TEST=1 -DSQLITE_CRASH_TEST=1
   610         -TESTFIXTURE_FLAGS += -DSQLITE_SERVER=1 -DSQLITE_PRIVATE="" -DSQLITE_CORE 
   611         -
   612         -testfixture$(EXE): $(TESTSRC2) libsqlite3.a $(TESTSRC) $(TOP)/src/tclsqlite.c
   613         -	$(TCCX) $(TCL_FLAGS) $(TESTFIXTURE_FLAGS)                            \
   614         -		$(TESTSRC) $(TESTSRC2) $(TOP)/src/tclsqlite.c                \
   615         -		-o testfixture$(EXE) $(LIBTCL) $(THREADLIB) libsqlite3.a
   616         -
   617         -amalgamation-testfixture$(EXE): sqlite3.c $(TESTSRC) $(TOP)/src/tclsqlite.c
   618         -	$(TCCX) $(TCL_FLAGS) $(TESTFIXTURE_FLAGS)                            \
   619         -		$(TESTSRC) $(TOP)/src/tclsqlite.c sqlite3.c                  \
   620         -		-o testfixture$(EXE) $(LIBTCL) $(THREADLIB)
   621         -
   622         -fts3-testfixture$(EXE): sqlite3.c fts3amal.c $(TESTSRC) $(TOP)/src/tclsqlite.c
   623         -	$(TCCX) $(TCL_FLAGS) $(TESTFIXTURE_FLAGS)                            \
   624         -	-DSQLITE_ENABLE_FTS3=1                                               \
   625         -		$(TESTSRC) $(TOP)/src/tclsqlite.c sqlite3.c fts3amal.c       \
   626         -		-o testfixture$(EXE) $(LIBTCL) $(THREADLIB)
   627         -
   628         -fulltest:	testfixture$(EXE) sqlite3$(EXE)
   629         -	./testfixture$(EXE) $(TOP)/test/all.test
   630         -
   631         -soaktest:	testfixture$(EXE) sqlite3$(EXE)
   632         -	./testfixture$(EXE) $(TOP)/test/all.test -soak=1
   633         -
   634         -fulltestonly:	testfixture$(EXE) sqlite3$(EXE)
   635         -	./testfixture$(EXE) $(TOP)/test/full.test
   636         -
   637         -test:	testfixture$(EXE) sqlite3$(EXE)
   638         -	./testfixture$(EXE) $(TOP)/test/veryquick.test
   639         -
   640         -sqlite3_analyzer$(EXE):	$(TOP)/src/tclsqlite.c sqlite3.c $(TESTSRC) \
   641         -			$(TOP)/tool/spaceanal.tcl
   642         -	sed \
   643         -	  -e '/^#/d' \
   644         -	  -e 's,\\,\\\\,g' \
   645         -	  -e 's,",\\",g' \
   646         -	  -e 's,^,",' \
   647         -	  -e 's,$$,\\n",' \
   648         -	  $(TOP)/tool/spaceanal.tcl >spaceanal_tcl.h
   649         -	$(TCCX) $(TCL_FLAGS)                  $(TESTFIXTURE_FLAGS)                                 \
   650         -		-DTCLSH=2 -DSQLITE_TEST=1 -DSQLITE_DEBUG=1 -DSQLITE_PRIVATE="" \
   651         -		$(TESTSRC) $(TOP)/src/tclsqlite.c sqlite3.c                    \
   652         -		-o sqlite3_analyzer$(EXE)                                      \
   653         -		$(LIBTCL) $(THREADLIB)
   654         -
   655         -TEST_EXTENSION = $(SHPREFIX)testloadext.$(SO)
   656         -$(TEST_EXTENSION): $(TOP)/src/test_loadext.c
   657         -	$(MKSHLIB) $(TOP)/src/test_loadext.c -o $(TEST_EXTENSION)
   658         -
   659         -extensiontest: testfixture$(EXE) $(TEST_EXTENSION)
   660         -	./testfixture$(EXE) $(TOP)/test/loadext.test
   661         -
   662         -clean:	
   663         -	rm -f *.o sqlite3$(EXE) libsqlite3.a sqlite3.h opcodes.*
   664         -	rm -f lemon lempar.c parse.* sqlite*.tar.gz mkkeywordhash keywordhash.h
   665         -	rm -f $(PUBLISH)
   666         -	rm -f *.da *.bb *.bbg gmon.out
   667         -	rm -rf quota2a quota2b quota2c
   668         -	rm -rf tsrc target_source
   669         -	rm -f testloadext.dll libtestloadext.so
   670         -	rm -f sqlite3.c fts?amal.c tclsqlite3.c
   671         -	rm -f sqlite3rc.h
   672         -	rm -f shell.c sqlite3ext.h
   673         -	rm -f $(SHPREFIX)sqlite3.$(SO)

Changes to VERSION.

     1         -3.8.12
            1  +3.9.0

Deleted addopcodes.awk.

     1         -#!/usr/bin/awk
     2         -#
     3         -# This script appends additional token codes to the end of the
     4         -# parse.h file that lemon generates.  These extra token codes are
     5         -# not used by the parser.  But they are used by the tokenizer and/or
     6         -# the code generator.
     7         -#
     8         -#
     9         -BEGIN {
    10         -  max = 0
    11         -}
    12         -/^#define TK_/ {
    13         -  print $0
    14         -  if( max<$3 ) max = $3
    15         -}
    16         -END {
    17         -  printf "#define TK_%-29s %4d\n", "TO_TEXT",         ++max
    18         -  printf "#define TK_%-29s %4d\n", "TO_BLOB",         ++max
    19         -  printf "#define TK_%-29s %4d\n", "TO_NUMERIC",      ++max
    20         -  printf "#define TK_%-29s %4d\n", "TO_INT",          ++max
    21         -  printf "#define TK_%-29s %4d\n", "TO_REAL",         ++max
    22         -  printf "#define TK_%-29s %4d\n", "ISNOT",           ++max
    23         -  printf "#define TK_%-29s %4d\n", "END_OF_FILE",     ++max
    24         -  printf "#define TK_%-29s %4d\n", "ILLEGAL",         ++max
    25         -  printf "#define TK_%-29s %4d\n", "SPACE",           ++max
    26         -  printf "#define TK_%-29s %4d\n", "UNCLOSED_STRING", ++max
    27         -  printf "#define TK_%-29s %4d\n", "FUNCTION",        ++max
    28         -  printf "#define TK_%-29s %4d\n", "COLUMN",          ++max
    29         -  printf "#define TK_%-29s %4d\n", "AGG_FUNCTION",    ++max
    30         -  printf "#define TK_%-29s %4d\n", "AGG_COLUMN",      ++max
    31         -  printf "#define TK_%-29s %4d\n", "UMINUS",          ++max
    32         -  printf "#define TK_%-29s %4d\n", "UPLUS",           ++max
    33         -  printf "#define TK_%-29s %4d\n", "REGISTER",        ++max
    34         -  printf "#define TK_%-29s %4d\n", "EXCLUSIVE",       ++max
    35         -  printf "#define TK_%-29s %4d\n", "CONCURRENT",      ++max
    36         -}

Changes to autoconf/Makefile.am.

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

Changes to autoconf/configure.ac.

    73     73   else
    74     74     DYNAMIC_EXTENSION_FLAGS=-DSQLITE_OMIT_LOAD_EXTENSION=1
    75     75   fi
    76     76   AC_MSG_CHECKING([for whether to support dynamic extensions])
    77     77   AC_MSG_RESULT($enable_dynamic_extensions)
    78     78   AC_SUBST(DYNAMIC_EXTENSION_FLAGS)
    79     79   #-----------------------------------------------------------------------
           80  +
           81  +#-----------------------------------------------------------------------
           82  +#   --enable-fts5
           83  +#
           84  +AC_ARG_ENABLE(fts5, [AS_HELP_STRING(
           85  +  [--enable-fts5], [include fts5 support [default=no]])], 
           86  +  [], [enable_fts5=no])
           87  +if test x"$enable_fts5" == "xyes"; then
           88  +  AC_SEARCH_LIBS(log, m)
           89  +  FTS5_FLAGS=-DSQLITE_ENABLE_FTS5
           90  +fi
           91  +AC_SUBST(FTS5_FLAGS)
           92  +#-----------------------------------------------------------------------
           93  +
           94  +#-----------------------------------------------------------------------
           95  +#   --enable-json1
           96  +#
           97  +AC_ARG_ENABLE(json1, [AS_HELP_STRING(
           98  +  [--enable-json1], [include json1 support [default=no]])], 
           99  +  [], [enable_json1=no])
          100  +if test x"$enable_json1" == "xyes"; then
          101  +  JSON1_FLAGS=-DSQLITE_ENABLE_JSON1
          102  +fi
          103  +AC_SUBST(JSON1_FLAGS)
          104  +#-----------------------------------------------------------------------
    80    105   
    81    106   AC_CHECK_FUNCS(posix_fallocate)
    82    107   
    83    108   #-----------------------------------------------------------------------
    84    109   # UPDATE: Maybe it's better if users just set CFLAGS before invoking
    85    110   # configure. This option doesn't really add much...
    86    111   #

Changes to configure.

     1      1   #! /bin/sh
     2      2   # Guess values for system-dependent variables and create Makefiles.
     3         -# Generated by GNU Autoconf 2.69 for sqlite 3.8.12.
            3  +# Generated by GNU Autoconf 2.69 for sqlite 3.9.0.
     4      4   #
     5      5   #
     6      6   # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
     7      7   #
     8      8   #
     9      9   # This configure script is free software; the Free Software Foundation
    10     10   # gives unlimited permission to copy, distribute and modify it.
................................................................................
   722    722   subdirs=
   723    723   MFLAGS=
   724    724   MAKEFLAGS=
   725    725   
   726    726   # Identity of this package.
   727    727   PACKAGE_NAME='sqlite'
   728    728   PACKAGE_TARNAME='sqlite'
   729         -PACKAGE_VERSION='3.8.12'
   730         -PACKAGE_STRING='sqlite 3.8.12'
          729  +PACKAGE_VERSION='3.9.0'
          730  +PACKAGE_STRING='sqlite 3.9.0'
   731    731   PACKAGE_BUGREPORT=''
   732    732   PACKAGE_URL=''
   733    733   
   734    734   # Factoring default headers for most tests.
   735    735   ac_includes_default="\
   736    736   #include <stdio.h>
   737    737   #ifdef HAVE_SYS_TYPES_H
................................................................................
   799    799   BUILD_CC
   800    800   VERSION_NUMBER
   801    801   RELEASE
   802    802   VERSION
   803    803   program_prefix
   804    804   TCLLIBDIR
   805    805   TCLSH_CMD
   806         -AWK
   807    806   INSTALL_DATA
   808    807   INSTALL_SCRIPT
   809    808   INSTALL_PROGRAM
   810    809   CPP
   811    810   OTOOL64
   812    811   OTOOL
   813    812   LIPO
................................................................................
   898    897   with_tcl
   899    898   enable_readline
   900    899   with_readline_lib
   901    900   with_readline_inc
   902    901   enable_debug
   903    902   enable_amalgamation
   904    903   enable_load_extension
          904  +enable_fts3
          905  +enable_fts4
          906  +enable_fts5
          907  +enable_json1
          908  +enable_rtree
   905    909   enable_gcov
   906    910   '
   907    911         ac_precious_vars='build_alias
   908    912   host_alias
   909    913   target_alias
   910    914   CC
   911    915   CFLAGS
................................................................................
  1450   1454   #
  1451   1455   # Report the --help message.
  1452   1456   #
  1453   1457   if test "$ac_init_help" = "long"; then
  1454   1458     # Omit some internal or obsolete options to make the list less imposing.
  1455   1459     # This message is too long to be a string in the A/UX 3.1 sh.
  1456   1460     cat <<_ACEOF
  1457         -\`configure' configures sqlite 3.8.12 to adapt to many kinds of systems.
         1461  +\`configure' configures sqlite 3.9.0 to adapt to many kinds of systems.
  1458   1462   
  1459   1463   Usage: $0 [OPTION]... [VAR=VALUE]...
  1460   1464   
  1461   1465   To assign environment variables (e.g., CC, CFLAGS...), specify them as
  1462   1466   VAR=VALUE.  See below for descriptions of some of the useful variables.
  1463   1467   
  1464   1468   Defaults for the options are specified in brackets.
................................................................................
  1515   1519     --build=BUILD     configure for building on BUILD [guessed]
  1516   1520     --host=HOST       cross-compile to build programs to run on HOST [BUILD]
  1517   1521   _ACEOF
  1518   1522   fi
  1519   1523   
  1520   1524   if test -n "$ac_init_help"; then
  1521   1525     case $ac_init_help in
  1522         -     short | recursive ) echo "Configuration of sqlite 3.8.12:";;
         1526  +     short | recursive ) echo "Configuration of sqlite 3.9.0:";;
  1523   1527      esac
  1524   1528     cat <<\_ACEOF
  1525   1529   
  1526   1530   Optional Features:
  1527   1531     --disable-option-checking  ignore unrecognized --enable/--with options
  1528   1532     --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
  1529   1533     --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
................................................................................
  1540   1544     --disable-tcl           do not build TCL extension
  1541   1545     --disable-readline      disable readline support [default=detect]
  1542   1546     --enable-debug          enable debugging & verbose explain
  1543   1547     --disable-amalgamation  Disable the amalgamation and instead build all files
  1544   1548                             separately
  1545   1549     --disable-load-extension
  1546   1550                             Disable loading of external extensions
         1551  +  --enable-fts3           Enable the FTS3 extension
         1552  +  --enable-fts4           Enable the FTS4 extension
         1553  +  --enable-fts5           Enable the FTS5 extension
         1554  +  --enable-json1          Enable the JSON1 extension
         1555  +  --enable-rtree          Enable the RTREE extension
  1547   1556     --enable-gcov           Enable coverage testing using gcov
  1548   1557   
  1549   1558   Optional Packages:
  1550   1559     --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
  1551   1560     --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
  1552   1561     --with-pic              try to use only PIC/non-PIC objects [default=use
  1553   1562                             both]
................................................................................
  1630   1639       cd "$ac_pwd" || { ac_status=$?; break; }
  1631   1640     done
  1632   1641   fi
  1633   1642   
  1634   1643   test -n "$ac_init_help" && exit $ac_status
  1635   1644   if $ac_init_version; then
  1636   1645     cat <<\_ACEOF
  1637         -sqlite configure 3.8.12
         1646  +sqlite configure 3.9.0
  1638   1647   generated by GNU Autoconf 2.69
  1639   1648   
  1640   1649   Copyright (C) 2012 Free Software Foundation, Inc.
  1641   1650   This configure script is free software; the Free Software Foundation
  1642   1651   gives unlimited permission to copy, distribute and modify it.
  1643   1652   _ACEOF
  1644   1653     exit
................................................................................
  2049   2058     eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
  2050   2059   
  2051   2060   } # ac_fn_c_check_header_mongrel
  2052   2061   cat >config.log <<_ACEOF
  2053   2062   This file contains any messages produced by compilers while
  2054   2063   running configure, to aid debugging if configure makes a mistake.
  2055   2064   
  2056         -It was created by sqlite $as_me 3.8.12, which was
         2065  +It was created by sqlite $as_me 3.9.0, which was
  2057   2066   generated by GNU Autoconf 2.69.  Invocation command line was
  2058   2067   
  2059   2068     $ $0 $@
  2060   2069   
  2061   2070   _ACEOF
  2062   2071   exec 5>>config.log
  2063   2072   {
................................................................................
  3907   3916   { $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5
  3908   3917   $as_echo_n "checking the name lister ($NM) interface... " >&6; }
  3909   3918   if ${lt_cv_nm_interface+:} false; then :
  3910   3919     $as_echo_n "(cached) " >&6
  3911   3920   else
  3912   3921     lt_cv_nm_interface="BSD nm"
  3913   3922     echo "int some_variable = 0;" > conftest.$ac_ext
  3914         -  (eval echo "\"\$as_me:3914: $ac_compile\"" >&5)
         3923  +  (eval echo "\"\$as_me:3923: $ac_compile\"" >&5)
  3915   3924     (eval "$ac_compile" 2>conftest.err)
  3916   3925     cat conftest.err >&5
  3917         -  (eval echo "\"\$as_me:3917: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
         3926  +  (eval echo "\"\$as_me:3926: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
  3918   3927     (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
  3919   3928     cat conftest.err >&5
  3920         -  (eval echo "\"\$as_me:3920: output\"" >&5)
         3929  +  (eval echo "\"\$as_me:3929: output\"" >&5)
  3921   3930     cat conftest.out >&5
  3922   3931     if $GREP 'External.*some_variable' conftest.out > /dev/null; then
  3923   3932       lt_cv_nm_interface="MS dumpbin"
  3924   3933     fi
  3925   3934     rm -f conftest*
  3926   3935   fi
  3927   3936   { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5
................................................................................
  5119   5128   	;;
  5120   5129       esac
  5121   5130     fi
  5122   5131     rm -rf conftest*
  5123   5132     ;;
  5124   5133   *-*-irix6*)
  5125   5134     # Find out which ABI we are using.
  5126         -  echo '#line 5126 "configure"' > conftest.$ac_ext
         5135  +  echo '#line 5135 "configure"' > conftest.$ac_ext
  5127   5136     if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
  5128   5137     (eval $ac_compile) 2>&5
  5129   5138     ac_status=$?
  5130   5139     $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
  5131   5140     test $ac_status = 0; }; then
  5132   5141       if test "$lt_cv_prog_gnu_ld" = yes; then
  5133   5142         case `/usr/bin/file conftest.$ac_objext` in
................................................................................
  6644   6653      # Note that $ac_compile itself does not contain backslashes and begins
  6645   6654      # with a dollar sign (not a hyphen), so the echo should work correctly.
  6646   6655      # The option is referenced via a variable to avoid confusing sed.
  6647   6656      lt_compile=`echo "$ac_compile" | $SED \
  6648   6657      -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
  6649   6658      -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
  6650   6659      -e 's:$: $lt_compiler_flag:'`
  6651         -   (eval echo "\"\$as_me:6651: $lt_compile\"" >&5)
         6660  +   (eval echo "\"\$as_me:6660: $lt_compile\"" >&5)
  6652   6661      (eval "$lt_compile" 2>conftest.err)
  6653   6662      ac_status=$?
  6654   6663      cat conftest.err >&5
  6655         -   echo "$as_me:6655: \$? = $ac_status" >&5
         6664  +   echo "$as_me:6664: \$? = $ac_status" >&5
  6656   6665      if (exit $ac_status) && test -s "$ac_outfile"; then
  6657   6666        # The compiler can only warn and ignore the option if not recognized
  6658   6667        # So say no if there are warnings other than the usual output.
  6659   6668        $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp
  6660   6669        $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
  6661   6670        if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
  6662   6671          lt_cv_prog_compiler_rtti_exceptions=yes
................................................................................
  6983   6992      # Note that $ac_compile itself does not contain backslashes and begins
  6984   6993      # with a dollar sign (not a hyphen), so the echo should work correctly.
  6985   6994      # The option is referenced via a variable to avoid confusing sed.
  6986   6995      lt_compile=`echo "$ac_compile" | $SED \
  6987   6996      -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
  6988   6997      -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
  6989   6998      -e 's:$: $lt_compiler_flag:'`
  6990         -   (eval echo "\"\$as_me:6990: $lt_compile\"" >&5)
         6999  +   (eval echo "\"\$as_me:6999: $lt_compile\"" >&5)
  6991   7000      (eval "$lt_compile" 2>conftest.err)
  6992   7001      ac_status=$?
  6993   7002      cat conftest.err >&5
  6994         -   echo "$as_me:6994: \$? = $ac_status" >&5
         7003  +   echo "$as_me:7003: \$? = $ac_status" >&5
  6995   7004      if (exit $ac_status) && test -s "$ac_outfile"; then
  6996   7005        # The compiler can only warn and ignore the option if not recognized
  6997   7006        # So say no if there are warnings other than the usual output.
  6998   7007        $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp
  6999   7008        $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
  7000   7009        if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
  7001   7010          lt_cv_prog_compiler_pic_works=yes
................................................................................
  7088   7097      # (2) before a word containing "conftest.", or (3) at the end.
  7089   7098      # Note that $ac_compile itself does not contain backslashes and begins
  7090   7099      # with a dollar sign (not a hyphen), so the echo should work correctly.
  7091   7100      lt_compile=`echo "$ac_compile" | $SED \
  7092   7101      -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
  7093   7102      -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
  7094   7103      -e 's:$: $lt_compiler_flag:'`
  7095         -   (eval echo "\"\$as_me:7095: $lt_compile\"" >&5)
         7104  +   (eval echo "\"\$as_me:7104: $lt_compile\"" >&5)
  7096   7105      (eval "$lt_compile" 2>out/conftest.err)
  7097   7106      ac_status=$?
  7098   7107      cat out/conftest.err >&5
  7099         -   echo "$as_me:7099: \$? = $ac_status" >&5
         7108  +   echo "$as_me:7108: \$? = $ac_status" >&5
  7100   7109      if (exit $ac_status) && test -s out/conftest2.$ac_objext
  7101   7110      then
  7102   7111        # The compiler can only warn and ignore the option if not recognized
  7103   7112        # So say no if there are warnings
  7104   7113        $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp
  7105   7114        $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
  7106   7115        if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
................................................................................
  7143   7152      # (2) before a word containing "conftest.", or (3) at the end.
  7144   7153      # Note that $ac_compile itself does not contain backslashes and begins
  7145   7154      # with a dollar sign (not a hyphen), so the echo should work correctly.
  7146   7155      lt_compile=`echo "$ac_compile" | $SED \
  7147   7156      -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
  7148   7157      -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
  7149   7158      -e 's:$: $lt_compiler_flag:'`
  7150         -   (eval echo "\"\$as_me:7150: $lt_compile\"" >&5)
         7159  +   (eval echo "\"\$as_me:7159: $lt_compile\"" >&5)
  7151   7160      (eval "$lt_compile" 2>out/conftest.err)
  7152   7161      ac_status=$?
  7153   7162      cat out/conftest.err >&5
  7154         -   echo "$as_me:7154: \$? = $ac_status" >&5
         7163  +   echo "$as_me:7163: \$? = $ac_status" >&5
  7155   7164      if (exit $ac_status) && test -s out/conftest2.$ac_objext
  7156   7165      then
  7157   7166        # The compiler can only warn and ignore the option if not recognized
  7158   7167        # So say no if there are warnings
  7159   7168        $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp
  7160   7169        $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
  7161   7170        if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
................................................................................
  9523   9532   else
  9524   9533     	  if test "$cross_compiling" = yes; then :
  9525   9534     lt_cv_dlopen_self=cross
  9526   9535   else
  9527   9536     lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
  9528   9537     lt_status=$lt_dlunknown
  9529   9538     cat > conftest.$ac_ext <<_LT_EOF
  9530         -#line 9530 "configure"
         9539  +#line 9539 "configure"
  9531   9540   #include "confdefs.h"
  9532   9541   
  9533   9542   #if HAVE_DLFCN_H
  9534   9543   #include <dlfcn.h>
  9535   9544   #endif
  9536   9545   
  9537   9546   #include <stdio.h>
................................................................................
  9619   9628   else
  9620   9629     	  if test "$cross_compiling" = yes; then :
  9621   9630     lt_cv_dlopen_self_static=cross
  9622   9631   else
  9623   9632     lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
  9624   9633     lt_status=$lt_dlunknown
  9625   9634     cat > conftest.$ac_ext <<_LT_EOF
  9626         -#line 9626 "configure"
         9635  +#line 9635 "configure"
  9627   9636   #include "confdefs.h"
  9628   9637   
  9629   9638   #if HAVE_DLFCN_H
  9630   9639   #include <dlfcn.h>
  9631   9640   #endif
  9632   9641   
  9633   9642   #include <stdio.h>
................................................................................
  9939   9948   # It thinks the first close brace ends the variable substitution.
  9940   9949   test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
  9941   9950   
  9942   9951   test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
  9943   9952   
  9944   9953   test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
  9945   9954   
  9946         -for ac_prog in gawk mawk nawk awk
  9947         -do
  9948         -  # Extract the first word of "$ac_prog", so it can be a program name with args.
  9949         -set dummy $ac_prog; ac_word=$2
  9950         -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
  9951         -$as_echo_n "checking for $ac_word... " >&6; }
  9952         -if ${ac_cv_prog_AWK+:} false; then :
  9953         -  $as_echo_n "(cached) " >&6
  9954         -else
  9955         -  if test -n "$AWK"; then
  9956         -  ac_cv_prog_AWK="$AWK" # Let the user override the test.
  9957         -else
  9958         -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
  9959         -for as_dir in $PATH
  9960         -do
  9961         -  IFS=$as_save_IFS
  9962         -  test -z "$as_dir" && as_dir=.
  9963         -    for ac_exec_ext in '' $ac_executable_extensions; do
  9964         -  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
  9965         -    ac_cv_prog_AWK="$ac_prog"
  9966         -    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
  9967         -    break 2
  9968         -  fi
  9969         -done
  9970         -  done
  9971         -IFS=$as_save_IFS
  9972         -
  9973         -fi
  9974         -fi
  9975         -AWK=$ac_cv_prog_AWK
  9976         -if test -n "$AWK"; then
  9977         -  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5
  9978         -$as_echo "$AWK" >&6; }
  9979         -else
  9980         -  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
  9981         -$as_echo "no" >&6; }
  9982         -fi
  9983         -
  9984         -
  9985         -  test -n "$AWK" && break
  9986         -done
  9987         -
  9988   9955   
  9989   9956   #########
  9990   9957   # Enable large file support (if special flags are necessary)
  9991   9958   #
  9992   9959   # Check whether --enable-largefile was given.
  9993   9960   if test "${enable_largefile+set}" = set; then :
  9994   9961     enableval=$enable_largefile;
................................................................................
 11218  11185     test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
 11219  11186   
 11220  11187   fi
 11221  11188   
 11222  11189   else
 11223  11190     OPT_FEATURE_FLAGS="-DSQLITE_OMIT_LOAD_EXTENSION=1"
 11224  11191   fi
        11192  +
        11193  +#########
        11194  +# See whether we should enable Full Text Search extensions
        11195  +# Check whether --enable-fts3 was given.
        11196  +if test "${enable_fts3+set}" = set; then :
        11197  +  enableval=$enable_fts3; enable_fts3=yes
        11198  +else
        11199  +  enable_fts3=no
        11200  +fi
        11201  +
        11202  +if test "${enable_fts3}" = "yes" ; then
        11203  +  OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_FTS3"
        11204  +fi
        11205  +# Check whether --enable-fts4 was given.
        11206  +if test "${enable_fts4+set}" = set; then :
        11207  +  enableval=$enable_fts4; enable_fts4=yes
        11208  +else
        11209  +  enable_fts4=no
        11210  +fi
        11211  +
        11212  +if test "${enable_fts4}" = "yes" ; then
        11213  +  OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_FTS4"
        11214  +  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing log" >&5
        11215  +$as_echo_n "checking for library containing log... " >&6; }
        11216  +if ${ac_cv_search_log+:} false; then :
        11217  +  $as_echo_n "(cached) " >&6
        11218  +else
        11219  +  ac_func_search_save_LIBS=$LIBS
        11220  +cat confdefs.h - <<_ACEOF >conftest.$ac_ext
        11221  +/* end confdefs.h.  */
        11222  +
        11223  +/* Override any GCC internal prototype to avoid an error.
        11224  +   Use char because int might match the return type of a GCC
        11225  +   builtin and then its argument prototype would still apply.  */
        11226  +#ifdef __cplusplus
        11227  +extern "C"
        11228  +#endif
        11229  +char log ();
        11230  +int
        11231  +main ()
        11232  +{
        11233  +return log ();
        11234  +  ;
        11235  +  return 0;
        11236  +}
        11237  +_ACEOF
        11238  +for ac_lib in '' m; do
        11239  +  if test -z "$ac_lib"; then
        11240  +    ac_res="none required"
        11241  +  else
        11242  +    ac_res=-l$ac_lib
        11243  +    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
        11244  +  fi
        11245  +  if ac_fn_c_try_link "$LINENO"; then :
        11246  +  ac_cv_search_log=$ac_res
        11247  +fi
        11248  +rm -f core conftest.err conftest.$ac_objext \
        11249  +    conftest$ac_exeext
        11250  +  if ${ac_cv_search_log+:} false; then :
        11251  +  break
        11252  +fi
        11253  +done
        11254  +if ${ac_cv_search_log+:} false; then :
        11255  +
        11256  +else
        11257  +  ac_cv_search_log=no
        11258  +fi
        11259  +rm conftest.$ac_ext
        11260  +LIBS=$ac_func_search_save_LIBS
        11261  +fi
        11262  +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_log" >&5
        11263  +$as_echo "$ac_cv_search_log" >&6; }
        11264  +ac_res=$ac_cv_search_log
        11265  +if test "$ac_res" != no; then :
        11266  +  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
        11267  +
        11268  +fi
        11269  +
        11270  +fi
        11271  +# Check whether --enable-fts5 was given.
        11272  +if test "${enable_fts5+set}" = set; then :
        11273  +  enableval=$enable_fts5; enable_fts5=yes
        11274  +else
        11275  +  enable_fts5=no
        11276  +fi
        11277  +
        11278  +if test "${enable_fts5}" = "yes" ; then
        11279  +  OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_FTS5"
        11280  +  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing log" >&5
        11281  +$as_echo_n "checking for library containing log... " >&6; }
        11282  +if ${ac_cv_search_log+:} false; then :
        11283  +  $as_echo_n "(cached) " >&6
        11284  +else
        11285  +  ac_func_search_save_LIBS=$LIBS
        11286  +cat confdefs.h - <<_ACEOF >conftest.$ac_ext
        11287  +/* end confdefs.h.  */
        11288  +
        11289  +/* Override any GCC internal prototype to avoid an error.
        11290  +   Use char because int might match the return type of a GCC
        11291  +   builtin and then its argument prototype would still apply.  */
        11292  +#ifdef __cplusplus
        11293  +extern "C"
        11294  +#endif
        11295  +char log ();
        11296  +int
        11297  +main ()
        11298  +{
        11299  +return log ();
        11300  +  ;
        11301  +  return 0;
        11302  +}
        11303  +_ACEOF
        11304  +for ac_lib in '' m; do
        11305  +  if test -z "$ac_lib"; then
        11306  +    ac_res="none required"
        11307  +  else
        11308  +    ac_res=-l$ac_lib
        11309  +    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
        11310  +  fi
        11311  +  if ac_fn_c_try_link "$LINENO"; then :
        11312  +  ac_cv_search_log=$ac_res
        11313  +fi
        11314  +rm -f core conftest.err conftest.$ac_objext \
        11315  +    conftest$ac_exeext
        11316  +  if ${ac_cv_search_log+:} false; then :
        11317  +  break
        11318  +fi
        11319  +done
        11320  +if ${ac_cv_search_log+:} false; then :
        11321  +
        11322  +else
        11323  +  ac_cv_search_log=no
        11324  +fi
        11325  +rm conftest.$ac_ext
        11326  +LIBS=$ac_func_search_save_LIBS
        11327  +fi
        11328  +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_log" >&5
        11329  +$as_echo "$ac_cv_search_log" >&6; }
        11330  +ac_res=$ac_cv_search_log
        11331  +if test "$ac_res" != no; then :
        11332  +  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
        11333  +
        11334  +fi
        11335  +
        11336  +fi
        11337  +
        11338  +#########
        11339  +# See whether we should enable JSON1
        11340  +# Check whether --enable-json1 was given.
        11341  +if test "${enable_json1+set}" = set; then :
        11342  +  enableval=$enable_json1; enable_json1=yes
        11343  +else
        11344  +  enable_json1=no
        11345  +fi
        11346  +
        11347  +if test "${enable_json1}" = "yes" ; then
        11348  +  OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_JSON1"
        11349  +fi
        11350  +
        11351  +#########
        11352  +# See whether we should enable RTREE
        11353  +# Check whether --enable-rtree was given.
        11354  +if test "${enable_rtree+set}" = set; then :
        11355  +  enableval=$enable_rtree; enable_rtree=yes
        11356  +else
        11357  +  enable_rtree=no
        11358  +fi
        11359  +
        11360  +if test "${enable_rtree}" = "yes" ; then
        11361  +  OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_RTREE"
        11362  +fi
 11225  11363   
 11226  11364   #########
 11227  11365   # attempt to duplicate any OMITS and ENABLES into the $(OPT_FEATURE_FLAGS) parameter
 11228  11366   for option in $CFLAGS $CPPFLAGS
 11229  11367   do
 11230  11368     case $option in
 11231  11369       -DSQLITE_OMIT*) OPT_FEATURE_FLAGS="$OPT_FEATURE_FLAGS $option";;
................................................................................
 11804  11942   test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1
 11805  11943   
 11806  11944   cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 11807  11945   # Save the log message, to keep $0 and so on meaningful, and to
 11808  11946   # report actual input values of CONFIG_FILES etc. instead of their
 11809  11947   # values after options handling.
 11810  11948   ac_log="
 11811         -This file was extended by sqlite $as_me 3.8.12, which was
        11949  +This file was extended by sqlite $as_me 3.9.0, which was
 11812  11950   generated by GNU Autoconf 2.69.  Invocation command line was
 11813  11951   
 11814  11952     CONFIG_FILES    = $CONFIG_FILES
 11815  11953     CONFIG_HEADERS  = $CONFIG_HEADERS
 11816  11954     CONFIG_LINKS    = $CONFIG_LINKS
 11817  11955     CONFIG_COMMANDS = $CONFIG_COMMANDS
 11818  11956     $ $0 $@
................................................................................
 11870  12008   
 11871  12009   Report bugs to the package provider."
 11872  12010   
 11873  12011   _ACEOF
 11874  12012   cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 11875  12013   ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 11876  12014   ac_cs_version="\\
 11877         -sqlite config.status 3.8.12
        12015  +sqlite config.status 3.9.0
 11878  12016   configured by $0, generated by GNU Autoconf 2.69,
 11879  12017     with options \\"\$ac_cs_config\\"
 11880  12018   
 11881  12019   Copyright (C) 2012 Free Software Foundation, Inc.
 11882  12020   This config.status script is free software; the Free Software Foundation
 11883  12021   gives unlimited permission to copy, distribute and modify it."
 11884  12022   
 11885  12023   ac_pwd='$ac_pwd'
 11886  12024   srcdir='$srcdir'
 11887  12025   INSTALL='$INSTALL'
 11888         -AWK='$AWK'
 11889  12026   test -n "\$AWK" || AWK=awk
 11890  12027   _ACEOF
 11891  12028   
 11892  12029   cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 11893  12030   # The default lists apply if the user does not specify any file.
 11894  12031   ac_need_defaults=:
 11895  12032   while test $# != 0

Changes to configure.ac.

    86     86   fi
    87     87   
    88     88   #########
    89     89   # Programs needed
    90     90   #
    91     91   AC_PROG_LIBTOOL
    92     92   AC_PROG_INSTALL
    93         -AC_PROG_AWK
    94     93   
    95     94   #########
    96     95   # Enable large file support (if special flags are necessary)
    97     96   #
    98     97   AC_SYS_LARGEFILE
    99     98   
   100     99   #########
................................................................................
   555    554         [use_loadextension=$enableval],[use_loadextension=yes])
   556    555   if test "${use_loadextension}" = "yes" ; then
   557    556     OPT_FEATURE_FLAGS=""
   558    557     AC_SEARCH_LIBS(dlopen, dl)
   559    558   else
   560    559     OPT_FEATURE_FLAGS="-DSQLITE_OMIT_LOAD_EXTENSION=1"
   561    560   fi
          561  +
          562  +#########
          563  +# See whether we should enable Full Text Search extensions
          564  +AC_ARG_ENABLE(fts3, AC_HELP_STRING([--enable-fts3],
          565  +      [Enable the FTS3 extension]),
          566  +      [enable_fts3=yes],[enable_fts3=no])
          567  +if test "${enable_fts3}" = "yes" ; then
          568  +  OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_FTS3"
          569  +fi
          570  +AC_ARG_ENABLE(fts4, AC_HELP_STRING([--enable-fts4],
          571  +      [Enable the FTS4 extension]),
          572  +      [enable_fts4=yes],[enable_fts4=no])
          573  +if test "${enable_fts4}" = "yes" ; then
          574  +  OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_FTS4"
          575  +  AC_SEARCH_LIBS([log],[m])
          576  +fi
          577  +AC_ARG_ENABLE(fts5, AC_HELP_STRING([--enable-fts5],
          578  +      [Enable the FTS5 extension]),
          579  +      [enable_fts5=yes],[enable_fts5=no])
          580  +if test "${enable_fts5}" = "yes" ; then
          581  +  OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_FTS5"
          582  +  AC_SEARCH_LIBS([log],[m])
          583  +fi
          584  +
          585  +#########
          586  +# See whether we should enable JSON1
          587  +AC_ARG_ENABLE(json1, AC_HELP_STRING([--enable-json1],
          588  +      [Enable the JSON1 extension]),
          589  +      [enable_json1=yes],[enable_json1=no])
          590  +if test "${enable_json1}" = "yes" ; then
          591  +  OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_JSON1"
          592  +fi
          593  +
          594  +#########
          595  +# See whether we should enable RTREE
          596  +AC_ARG_ENABLE(rtree, AC_HELP_STRING([--enable-rtree],
          597  +      [Enable the RTREE extension]),
          598  +      [enable_rtree=yes],[enable_rtree=no])
          599  +if test "${enable_rtree}" = "yes" ; then
          600  +  OPT_FEATURE_FLAGS+=" -DSQLITE_ENABLE_RTREE"
          601  +fi
   562    602   
   563    603   #########
   564    604   # attempt to duplicate any OMITS and ENABLES into the $(OPT_FEATURE_FLAGS) parameter
   565    605   for option in $CFLAGS $CPPFLAGS
   566    606   do
   567    607     case $option in
   568    608       -DSQLITE_OMIT*) OPT_FEATURE_FLAGS="$OPT_FEATURE_FLAGS $option";;

Changes to ext/fts3/fts3.c.

  1512   1512   static void fts3SetEstimatedRows(sqlite3_index_info *pIdxInfo, i64 nRow){
  1513   1513   #if SQLITE_VERSION_NUMBER>=3008002
  1514   1514     if( sqlite3_libversion_number()>=3008002 ){
  1515   1515       pIdxInfo->estimatedRows = nRow;
  1516   1516     }
  1517   1517   #endif
  1518   1518   }
         1519  +
         1520  +/*
         1521  +** Set the SQLITE_INDEX_SCAN_UNIQUE flag in pIdxInfo->flags. Unless this
         1522  +** extension is currently being used by a version of SQLite too old to
         1523  +** support index-info flags. In that case this function is a no-op.
         1524  +*/
         1525  +static void fts3SetUniqueFlag(sqlite3_index_info *pIdxInfo){
         1526  +#if SQLITE_VERSION_NUMBER>=3008012
         1527  +  if( sqlite3_libversion_number()>=3008012 ){
         1528  +    pIdxInfo->idxFlags |= SQLITE_INDEX_SCAN_UNIQUE;
         1529  +  }
         1530  +#endif
         1531  +}
  1519   1532   
  1520   1533   /* 
  1521   1534   ** Implementation of the xBestIndex method for FTS3 tables. There
  1522   1535   ** are three possible strategies, in order of preference:
  1523   1536   **
  1524   1537   **   1. Direct lookup by rowid or docid. 
  1525   1538   **   2. Full-text search using a MATCH operator on a non-docid column.
................................................................................
  1602   1615           case SQLITE_INDEX_CONSTRAINT_LE:
  1603   1616           case SQLITE_INDEX_CONSTRAINT_LT:
  1604   1617             iDocidLe = i;
  1605   1618             break;
  1606   1619         }
  1607   1620       }
  1608   1621     }
         1622  +
         1623  +  /* If using a docid=? or rowid=? strategy, set the UNIQUE flag. */
         1624  +  if( pInfo->idxNum==FTS3_DOCID_SEARCH ) fts3SetUniqueFlag(pInfo);
  1609   1625   
  1610   1626     iIdx = 1;
  1611   1627     if( iCons>=0 ){
  1612   1628       pInfo->aConstraintUsage[iCons].argvIndex = iIdx++;
  1613   1629       pInfo->aConstraintUsage[iCons].omit = 1;
  1614   1630     } 
  1615   1631     if( iLangidCons>=0 ){

Changes to ext/fts3/fts3Int.h.

   260    260       int nPrefix;                  /* Prefix length (0 for main terms index) */
   261    261       Fts3Hash hPending;            /* Pending terms table for this index */
   262    262     } *aIndex;
   263    263     int nMaxPendingData;            /* Max pending data before flush to disk */
   264    264     int nPendingData;               /* Current bytes of pending data */
   265    265     sqlite_int64 iPrevDocid;        /* Docid of most recently inserted document */
   266    266     int iPrevLangid;                /* Langid of recently inserted document */
          267  +  int bPrevDelete;                /* True if last operation was a delete */
   267    268   
   268    269   #if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST)
   269    270     /* State variables used for validating that the transaction control
   270    271     ** methods of the virtual table are called at appropriate times.  These
   271    272     ** values do not contribute to FTS functionality; they are used for
   272    273     ** verifying the operation of the SQLite core.
   273    274     */

Changes to ext/fts3/fts3_expr.c.

   789    789     Fts3Expr *pFree = 0;            /* List of free nodes. Linked by pParent. */
   790    790     int eType = pRoot->eType;       /* Type of node in this tree */
   791    791   
   792    792     if( nMaxDepth==0 ){
   793    793       rc = SQLITE_ERROR;
   794    794     }
   795    795   
   796         -  if( rc==SQLITE_OK && (eType==FTSQUERY_AND || eType==FTSQUERY_OR) ){
   797         -    Fts3Expr **apLeaf;
   798         -    apLeaf = (Fts3Expr **)sqlite3_malloc(sizeof(Fts3Expr *) * nMaxDepth);
   799         -    if( 0==apLeaf ){
   800         -      rc = SQLITE_NOMEM;
   801         -    }else{
   802         -      memset(apLeaf, 0, sizeof(Fts3Expr *) * nMaxDepth);
   803         -    }
   804         -
   805         -    if( rc==SQLITE_OK ){
   806         -      int i;
   807         -      Fts3Expr *p;
   808         -
   809         -      /* Set $p to point to the left-most leaf in the tree of eType nodes. */
   810         -      for(p=pRoot; p->eType==eType; p=p->pLeft){
   811         -        assert( p->pParent==0 || p->pParent->pLeft==p );
   812         -        assert( p->pLeft && p->pRight );
   813         -      }
   814         -
   815         -      /* This loop runs once for each leaf in the tree of eType nodes. */
   816         -      while( 1 ){
   817         -        int iLvl;
   818         -        Fts3Expr *pParent = p->pParent;     /* Current parent of p */
   819         -
   820         -        assert( pParent==0 || pParent->pLeft==p );
   821         -        p->pParent = 0;
   822         -        if( pParent ){
   823         -          pParent->pLeft = 0;
   824         -        }else{
   825         -          pRoot = 0;
   826         -        }
   827         -        rc = fts3ExprBalance(&p, nMaxDepth-1);
   828         -        if( rc!=SQLITE_OK ) break;
   829         -
   830         -        for(iLvl=0; p && iLvl<nMaxDepth; iLvl++){
   831         -          if( apLeaf[iLvl]==0 ){
   832         -            apLeaf[iLvl] = p;
   833         -            p = 0;
   834         -          }else{
   835         -            assert( pFree );
   836         -            pFree->pLeft = apLeaf[iLvl];
   837         -            pFree->pRight = p;
   838         -            pFree->pLeft->pParent = pFree;
   839         -            pFree->pRight->pParent = pFree;
   840         -
   841         -            p = pFree;
   842         -            pFree = pFree->pParent;
   843         -            p->pParent = 0;
   844         -            apLeaf[iLvl] = 0;
   845         -          }
   846         -        }
   847         -        if( p ){
   848         -          sqlite3Fts3ExprFree(p);
   849         -          rc = SQLITE_TOOBIG;
   850         -          break;
   851         -        }
   852         -
   853         -        /* If that was the last leaf node, break out of the loop */
   854         -        if( pParent==0 ) break;
   855         -
   856         -        /* Set $p to point to the next leaf in the tree of eType nodes */
   857         -        for(p=pParent->pRight; p->eType==eType; p=p->pLeft);
   858         -
   859         -        /* Remove pParent from the original tree. */
   860         -        assert( pParent->pParent==0 || pParent->pParent->pLeft==pParent );
   861         -        pParent->pRight->pParent = pParent->pParent;
   862         -        if( pParent->pParent ){
   863         -          pParent->pParent->pLeft = pParent->pRight;
   864         -        }else{
   865         -          assert( pParent==pRoot );
   866         -          pRoot = pParent->pRight;
   867         -        }
   868         -
   869         -        /* Link pParent into the free node list. It will be used as an
   870         -        ** internal node of the new tree.  */
   871         -        pParent->pParent = pFree;
   872         -        pFree = pParent;
          796  +  if( rc==SQLITE_OK ){
          797  +    if( (eType==FTSQUERY_AND || eType==FTSQUERY_OR) ){
          798  +      Fts3Expr **apLeaf;
          799  +      apLeaf = (Fts3Expr **)sqlite3_malloc(sizeof(Fts3Expr *) * nMaxDepth);
          800  +      if( 0==apLeaf ){
          801  +        rc = SQLITE_NOMEM;
          802  +      }else{
          803  +        memset(apLeaf, 0, sizeof(Fts3Expr *) * nMaxDepth);
   873    804         }
   874    805   
   875    806         if( rc==SQLITE_OK ){
   876         -        p = 0;
   877         -        for(i=0; i<nMaxDepth; i++){
   878         -          if( apLeaf[i] ){
   879         -            if( p==0 ){
   880         -              p = apLeaf[i];
   881         -              p->pParent = 0;
          807  +        int i;
          808  +        Fts3Expr *p;
          809  +
          810  +        /* Set $p to point to the left-most leaf in the tree of eType nodes. */
          811  +        for(p=pRoot; p->eType==eType; p=p->pLeft){
          812  +          assert( p->pParent==0 || p->pParent->pLeft==p );
          813  +          assert( p->pLeft && p->pRight );
          814  +        }
          815  +
          816  +        /* This loop runs once for each leaf in the tree of eType nodes. */
          817  +        while( 1 ){
          818  +          int iLvl;
          819  +          Fts3Expr *pParent = p->pParent;     /* Current parent of p */
          820  +
          821  +          assert( pParent==0 || pParent->pLeft==p );
          822  +          p->pParent = 0;
          823  +          if( pParent ){
          824  +            pParent->pLeft = 0;
          825  +          }else{
          826  +            pRoot = 0;
          827  +          }
          828  +          rc = fts3ExprBalance(&p, nMaxDepth-1);
          829  +          if( rc!=SQLITE_OK ) break;
          830  +
          831  +          for(iLvl=0; p && iLvl<nMaxDepth; iLvl++){
          832  +            if( apLeaf[iLvl]==0 ){
          833  +              apLeaf[iLvl] = p;
          834  +              p = 0;
   882    835               }else{
   883         -              assert( pFree!=0 );
          836  +              assert( pFree );
          837  +              pFree->pLeft = apLeaf[iLvl];
   884    838                 pFree->pRight = p;
   885         -              pFree->pLeft = apLeaf[i];
   886    839                 pFree->pLeft->pParent = pFree;
   887    840                 pFree->pRight->pParent = pFree;
   888    841   
   889    842                 p = pFree;
   890    843                 pFree = pFree->pParent;
   891    844                 p->pParent = 0;
          845  +              apLeaf[iLvl] = 0;
          846  +            }
          847  +          }
          848  +          if( p ){
          849  +            sqlite3Fts3ExprFree(p);
          850  +            rc = SQLITE_TOOBIG;
          851  +            break;
          852  +          }
          853  +
          854  +          /* If that was the last leaf node, break out of the loop */
          855  +          if( pParent==0 ) break;
          856  +
          857  +          /* Set $p to point to the next leaf in the tree of eType nodes */
          858  +          for(p=pParent->pRight; p->eType==eType; p=p->pLeft);
          859  +
          860  +          /* Remove pParent from the original tree. */
          861  +          assert( pParent->pParent==0 || pParent->pParent->pLeft==pParent );
          862  +          pParent->pRight->pParent = pParent->pParent;
          863  +          if( pParent->pParent ){
          864  +            pParent->pParent->pLeft = pParent->pRight;
          865  +          }else{
          866  +            assert( pParent==pRoot );
          867  +            pRoot = pParent->pRight;
          868  +          }
          869  +
          870  +          /* Link pParent into the free node list. It will be used as an
          871  +          ** internal node of the new tree.  */
          872  +          pParent->pParent = pFree;
          873  +          pFree = pParent;
          874  +        }
          875  +
          876  +        if( rc==SQLITE_OK ){
          877  +          p = 0;
          878  +          for(i=0; i<nMaxDepth; i++){
          879  +            if( apLeaf[i] ){
          880  +              if( p==0 ){
          881  +                p = apLeaf[i];
          882  +                p->pParent = 0;
          883  +              }else{
          884  +                assert( pFree!=0 );
          885  +                pFree->pRight = p;
          886  +                pFree->pLeft = apLeaf[i];
          887  +                pFree->pLeft->pParent = pFree;
          888  +                pFree->pRight->pParent = pFree;
          889  +
          890  +                p = pFree;
          891  +                pFree = pFree->pParent;
          892  +                p->pParent = 0;
          893  +              }
   892    894               }
   893    895             }
   894         -        }
   895         -        pRoot = p;
   896         -      }else{
   897         -        /* An error occurred. Delete the contents of the apLeaf[] array 
   898         -        ** and pFree list. Everything else is cleaned up by the call to
   899         -        ** sqlite3Fts3ExprFree(pRoot) below.  */
   900         -        Fts3Expr *pDel;
   901         -        for(i=0; i<nMaxDepth; i++){
   902         -          sqlite3Fts3ExprFree(apLeaf[i]);
          896  +          pRoot = p;
          897  +        }else{
          898  +          /* An error occurred. Delete the contents of the apLeaf[] array 
          899  +          ** and pFree list. Everything else is cleaned up by the call to
          900  +          ** sqlite3Fts3ExprFree(pRoot) below.  */
          901  +          Fts3Expr *pDel;
          902  +          for(i=0; i<nMaxDepth; i++){
          903  +            sqlite3Fts3ExprFree(apLeaf[i]);
          904  +          }
          905  +          while( (pDel=pFree)!=0 ){
          906  +            pFree = pDel->pParent;
          907  +            sqlite3_free(pDel);
          908  +          }
   903    909           }
   904         -        while( (pDel=pFree)!=0 ){
   905         -          pFree = pDel->pParent;
   906         -          sqlite3_free(pDel);
   907         -        }
          910  +
          911  +        assert( pFree==0 );
          912  +        sqlite3_free( apLeaf );
          913  +      }
          914  +    }else if( eType==FTSQUERY_NOT ){
          915  +      Fts3Expr *pLeft = pRoot->pLeft;
          916  +      Fts3Expr *pRight = pRoot->pRight;
          917  +
          918  +      pRoot->pLeft = 0;
          919  +      pRoot->pRight = 0;
          920  +      pLeft->pParent = 0;
          921  +      pRight->pParent = 0;
          922  +
          923  +      rc = fts3ExprBalance(&pLeft, nMaxDepth-1);
          924  +      if( rc==SQLITE_OK ){
          925  +        rc = fts3ExprBalance(&pRight, nMaxDepth-1);
   908    926         }
   909    927   
   910         -      assert( pFree==0 );
   911         -      sqlite3_free( apLeaf );
          928  +      if( rc!=SQLITE_OK ){
          929  +        sqlite3Fts3ExprFree(pRight);
          930  +        sqlite3Fts3ExprFree(pLeft);
          931  +      }else{
          932  +        assert( pLeft && pRight );
          933  +        pRoot->pLeft = pLeft;
          934  +        pLeft->pParent = pRoot;
          935  +        pRoot->pRight = pRight;
          936  +        pRight->pParent = pRoot;
          937  +      }
   912    938       }
   913    939     }
   914         -
          940  +  
   915    941     if( rc!=SQLITE_OK ){
   916    942       sqlite3Fts3ExprFree(pRoot);
   917    943       pRoot = 0;
   918    944     }
   919    945     *pp = pRoot;
   920    946     return rc;
   921    947   }

Changes to ext/fts3/fts3_write.c.

   856    856   /* 
   857    857   ** Calling this function indicates that subsequent calls to 
   858    858   ** fts3PendingTermsAdd() are to add term/position-list pairs for the
   859    859   ** contents of the document with docid iDocid.
   860    860   */
   861    861   static int fts3PendingTermsDocid(
   862    862     Fts3Table *p,                   /* Full-text table handle */
          863  +  int bDelete,                    /* True if this op is a delete */
   863    864     int iLangid,                    /* Language id of row being written */
   864    865     sqlite_int64 iDocid             /* Docid of row being written */
   865    866   ){
   866    867     assert( iLangid>=0 );
          868  +  assert( bDelete==1 || bDelete==0 );
   867    869   
   868    870     /* TODO(shess) Explore whether partially flushing the buffer on
   869    871     ** forced-flush would provide better performance.  I suspect that if
   870    872     ** we ordered the doclists by size and flushed the largest until the
   871    873     ** buffer was half empty, that would let the less frequent terms
   872    874     ** generate longer doclists.
   873    875     */
   874         -  if( iDocid<=p->iPrevDocid 
          876  +  if( iDocid<p->iPrevDocid 
          877  +   || (iDocid==p->iPrevDocid && p->bPrevDelete==0)
   875    878      || p->iPrevLangid!=iLangid
   876    879      || p->nPendingData>p->nMaxPendingData 
   877    880     ){
   878    881       int rc = sqlite3Fts3PendingTermsFlush(p);
   879    882       if( rc!=SQLITE_OK ) return rc;
   880    883     }
   881    884     p->iPrevDocid = iDocid;
   882    885     p->iPrevLangid = iLangid;
          886  +  p->bPrevDelete = bDelete;
   883    887     return SQLITE_OK;
   884    888   }
   885    889   
   886    890   /*
   887    891   ** Discard the contents of the pending-terms hash tables. 
   888    892   */
   889    893   void sqlite3Fts3PendingTermsClear(Fts3Table *p){
................................................................................
  1065   1069     assert( *pbFound==0 );
  1066   1070     if( *pRC ) return;
  1067   1071     rc = fts3SqlStmt(p, SQL_SELECT_CONTENT_BY_ROWID, &pSelect, &pRowid);
  1068   1072     if( rc==SQLITE_OK ){
  1069   1073       if( SQLITE_ROW==sqlite3_step(pSelect) ){
  1070   1074         int i;
  1071   1075         int iLangid = langidFromSelect(p, pSelect);
  1072         -      rc = fts3PendingTermsDocid(p, iLangid, sqlite3_column_int64(pSelect, 0));
         1076  +      i64 iDocid = sqlite3_column_int64(pSelect, 0);
         1077  +      rc = fts3PendingTermsDocid(p, 1, iLangid, iDocid);
  1073   1078         for(i=1; rc==SQLITE_OK && i<=p->nColumn; i++){
  1074   1079           int iCol = i-1;
  1075   1080           if( p->abNotindexed[iCol]==0 ){
  1076   1081             const char *zText = (const char *)sqlite3_column_text(pSelect, i);
  1077   1082             rc = fts3PendingTermsAdd(p, iLangid, zText, -1, &aSz[iCol]);
  1078   1083             aSz[p->nColumn] += sqlite3_column_bytes(pSelect, i);
  1079   1084           }
................................................................................
  1313   1318       pNext = &pReader->aDoclist[pReader->nDoclist];
  1314   1319     }
  1315   1320   
  1316   1321     if( !pNext || pNext>=&pReader->aNode[pReader->nNode] ){
  1317   1322   
  1318   1323       if( fts3SegReaderIsPending(pReader) ){
  1319   1324         Fts3HashElem *pElem = *(pReader->ppNextElem);
  1320         -      if( pElem==0 ){
  1321         -        pReader->aNode = 0;
  1322         -      }else{
         1325  +      sqlite3_free(pReader->aNode);
         1326  +      pReader->aNode = 0;
         1327  +      if( pElem ){
         1328  +        char *aCopy;
  1323   1329           PendingList *pList = (PendingList *)fts3HashData(pElem);
         1330  +        int nCopy = pList->nData+1;
  1324   1331           pReader->zTerm = (char *)fts3HashKey(pElem);
  1325   1332           pReader->nTerm = fts3HashKeysize(pElem);
  1326         -        pReader->nNode = pReader->nDoclist = pList->nData + 1;
  1327         -        pReader->aNode = pReader->aDoclist = pList->aData;
         1333  +        aCopy = (char*)sqlite3_malloc(nCopy);
         1334  +        if( !aCopy ) return SQLITE_NOMEM;
         1335  +        memcpy(aCopy, pList->aData, nCopy);
         1336  +        pReader->nNode = pReader->nDoclist = nCopy;
         1337  +        pReader->aNode = pReader->aDoclist = aCopy;
  1328   1338           pReader->ppNextElem++;
  1329   1339           assert( pReader->aNode );
  1330   1340         }
  1331   1341         return SQLITE_OK;
  1332   1342       }
  1333   1343   
  1334   1344       fts3SegReaderSetEof(pReader);
................................................................................
  1560   1570   }
  1561   1571   
  1562   1572   /*
  1563   1573   ** Free all allocations associated with the iterator passed as the 
  1564   1574   ** second argument.
  1565   1575   */
  1566   1576   void sqlite3Fts3SegReaderFree(Fts3SegReader *pReader){
  1567         -  if( pReader && !fts3SegReaderIsPending(pReader) ){
  1568         -    sqlite3_free(pReader->zTerm);
         1577  +  if( pReader ){
         1578  +    if( !fts3SegReaderIsPending(pReader) ){
         1579  +      sqlite3_free(pReader->zTerm);
         1580  +    }
  1569   1581       if( !fts3SegReaderIsRootOnly(pReader) ){
  1570   1582         sqlite3_free(pReader->aNode);
  1571         -      sqlite3_blob_close(pReader->pBlob);
  1572   1583       }
         1584  +    sqlite3_blob_close(pReader->pBlob);
  1573   1585     }
  1574   1586     sqlite3_free(pReader);
  1575   1587   }
  1576   1588   
  1577   1589   /*
  1578   1590   ** Allocate a new SegReader object.
  1579   1591   */
................................................................................
  3508   3520           aSzDel = &aSzIns[p->nColumn+1];
  3509   3521         }
  3510   3522       }
  3511   3523   
  3512   3524       while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){
  3513   3525         int iCol;
  3514   3526         int iLangid = langidFromSelect(p, pStmt);
  3515         -      rc = fts3PendingTermsDocid(p, iLangid, sqlite3_column_int64(pStmt, 0));
         3527  +      rc = fts3PendingTermsDocid(p, 0, iLangid, sqlite3_column_int64(pStmt, 0));
  3516   3528         memset(aSz, 0, sizeof(aSz[0]) * (p->nColumn+1));
  3517   3529         for(iCol=0; rc==SQLITE_OK && iCol<p->nColumn; iCol++){
  3518   3530           if( p->abNotindexed[iCol]==0 ){
  3519   3531             const char *z = (const char *) sqlite3_column_text(pStmt, iCol+1);
  3520   3532             rc = fts3PendingTermsAdd(p, iLangid, z, iCol, &aSz[iCol]);
  3521   3533             aSz[p->nColumn] += sqlite3_column_bytes(pStmt, iCol+1);
  3522   3534           }
................................................................................
  5613   5625       if( bInsertDone==0 ){
  5614   5626         rc = fts3InsertData(p, apVal, pRowid);
  5615   5627         if( rc==SQLITE_CONSTRAINT && p->zContentTbl==0 ){
  5616   5628           rc = FTS_CORRUPT_VTAB;
  5617   5629         }
  5618   5630       }
  5619   5631       if( rc==SQLITE_OK && (!isRemove || *pRowid!=p->iPrevDocid ) ){
  5620         -      rc = fts3PendingTermsDocid(p, iLangid, *pRowid);
         5632  +      rc = fts3PendingTermsDocid(p, 0, iLangid, *pRowid);
  5621   5633       }
  5622   5634       if( rc==SQLITE_OK ){
  5623   5635         assert( p->iPrevDocid==*pRowid );
  5624   5636         rc = fts3InsertTerms(p, iLangid, apVal, aSzIns);
  5625   5637       }
  5626   5638       if( p->bHasDocsize ){
  5627   5639         fts3InsertDocsize(&rc, p, aSzIns);

Changes to ext/fts5/fts5.h.

    18     18   */
    19     19   
    20     20   
    21     21   #ifndef _FTS5_H
    22     22   #define _FTS5_H
    23     23   
    24     24   #include "sqlite3.h"
           25  +
           26  +#ifdef __cplusplus
           27  +extern "C" {
           28  +#endif
    25     29   
    26     30   /*************************************************************************
    27     31   ** CUSTOM AUXILIARY FUNCTIONS
    28     32   **
    29     33   ** Virtual table implementations may overload SQL functions by implementing
    30     34   ** the sqlite3_module.xFindFunction() method.
    31     35   */
................................................................................
   503    507       void (*xDestroy)(void*)
   504    508     );
   505    509   };
   506    510   
   507    511   /*
   508    512   ** END OF REGISTRATION API
   509    513   *************************************************************************/
          514  +
          515  +#ifdef __cplusplus
          516  +}  /* end of the 'extern "C"' block */
          517  +#endif
   510    518   
   511    519   #endif /* _FTS5_H */
   512    520   

Changes to ext/fts5/fts5Int.h.

    77     77   extern int sqlite3_fts5_may_be_corrupt;
    78     78   # define assert_nc(x) assert(sqlite3_fts5_may_be_corrupt || (x))
    79     79   #else
    80     80   # define assert_nc(x) assert(x)
    81     81   #endif
    82     82   
    83     83   typedef struct Fts5Global Fts5Global;
           84  +typedef struct Fts5Colset Fts5Colset;
           85  +
           86  +/* If a NEAR() clump or phrase may only match a specific set of columns, 
           87  +** then an object of the following type is used to record the set of columns.
           88  +** Each entry in the aiCol[] array is a column that may be matched.
           89  +**
           90  +** This object is used by fts5_expr.c and fts5_index.c.
           91  +*/
           92  +struct Fts5Colset {
           93  +  int nCol;
           94  +  int aiCol[1];
           95  +};
           96  +
           97  +
    84     98   
    85     99   /**************************************************************************
    86    100   ** Interface to code in fts5_config.c. fts5_config.c contains contains code
    87    101   ** to parse the arguments passed to the CREATE VIRTUAL TABLE statement.
    88    102   */
    89    103   
    90    104   typedef struct Fts5Config Fts5Config;
................................................................................
   236    250   
   237    251   #define FTS5_POS2COLUMN(iPos) (int)(iPos >> 32)
   238    252   #define FTS5_POS2OFFSET(iPos) (int)(iPos & 0xFFFFFFFF)
   239    253   
   240    254   typedef struct Fts5PoslistReader Fts5PoslistReader;
   241    255   struct Fts5PoslistReader {
   242    256     /* Variables used only by sqlite3Fts5PoslistIterXXX() functions. */
   243         -  int iCol;                       /* If (iCol>=0), this column only */
   244    257     const u8 *a;                    /* Position list to iterate through */
   245    258     int n;                          /* Size of buffer at a[] in bytes */
   246    259     int i;                          /* Current offset in a[] */
   247    260   
   248    261     u8 bFlag;                       /* For client use (any custom purpose) */
   249    262   
   250    263     /* Output variables */
   251    264     u8 bEof;                        /* Set to true at EOF */
   252    265     i64 iPos;                       /* (iCol<<32) + iPos */
   253    266   };
   254    267   int sqlite3Fts5PoslistReaderInit(
   255         -  int iCol,                       /* If (iCol>=0), this column only */
   256    268     const u8 *a, int n,             /* Poslist buffer to iterate through */
   257    269     Fts5PoslistReader *pIter        /* Iterator object to initialize */
   258    270   );
   259    271   int sqlite3Fts5PoslistReaderNext(Fts5PoslistReader*);
   260    272   
   261    273   typedef struct Fts5PoslistWriter Fts5PoslistWriter;
   262    274   struct Fts5PoslistWriter {
................................................................................
   301    313   ** Create/destroy an Fts5Index object.
   302    314   */
   303    315   int sqlite3Fts5IndexOpen(Fts5Config *pConfig, int bCreate, Fts5Index**, char**);
   304    316   int sqlite3Fts5IndexClose(Fts5Index *p);
   305    317   
   306    318   /*
   307    319   ** for(
   308         -**   pIter = sqlite3Fts5IndexQuery(p, "token", 5, 0);
          320  +**   sqlite3Fts5IndexQuery(p, "token", 5, 0, 0, &pIter);
   309    321   **   0==sqlite3Fts5IterEof(pIter);
   310    322   **   sqlite3Fts5IterNext(pIter)
   311    323   ** ){
   312    324   **   i64 iRowid = sqlite3Fts5IterRowid(pIter);
   313    325   ** }
   314    326   */
   315    327   
................................................................................
   317    329   ** Open a new iterator to iterate though all rowids that match the 
   318    330   ** specified token or token prefix.
   319    331   */
   320    332   int sqlite3Fts5IndexQuery(
   321    333     Fts5Index *p,                   /* FTS index to query */
   322    334     const char *pToken, int nToken, /* Token (or prefix) to query for */
   323    335     int flags,                      /* Mask of FTS5INDEX_QUERY_X flags */
   324         -  Fts5IndexIter **ppIter
          336  +  Fts5Colset *pColset,            /* Match these columns only */
          337  +  Fts5IndexIter **ppIter          /* OUT: New iterator object */
   325    338   );
   326    339   
   327    340   /*
   328    341   ** The various operations on open token or token prefix iterators opened
   329    342   ** using sqlite3Fts5IndexQuery().
   330    343   */
   331    344   int sqlite3Fts5IterEof(Fts5IndexIter*);
   332    345   int sqlite3Fts5IterNext(Fts5IndexIter*);
   333    346   int sqlite3Fts5IterNextFrom(Fts5IndexIter*, i64 iMatch);
   334    347   i64 sqlite3Fts5IterRowid(Fts5IndexIter*);
   335         -int sqlite3Fts5IterPoslist(Fts5IndexIter*, const u8 **pp, int *pn, i64 *pi);
          348  +int sqlite3Fts5IterPoslist(Fts5IndexIter*,Fts5Colset*, const u8**, int*, i64*);
   336    349   int sqlite3Fts5IterPoslistBuffer(Fts5IndexIter *pIter, Fts5Buffer *pBuf);
   337    350   
   338    351   /*
   339    352   ** Close an iterator opened by sqlite3Fts5IndexQuery().
   340    353   */
   341    354   void sqlite3Fts5IterClose(Fts5IndexIter*);
   342    355   
................................................................................
   366    379   
   367    380   /*
   368    381   ** Indicate that subsequent calls to sqlite3Fts5IndexWrite() pertain to
   369    382   ** document iDocid.
   370    383   */
   371    384   int sqlite3Fts5IndexBeginWrite(
   372    385     Fts5Index *p,                   /* Index to write to */
          386  +  int bDelete,                    /* True if current operation is a delete */
   373    387     i64 iDocid                      /* Docid to add or remove data from */
   374    388   );
   375    389   
   376    390   /*
   377    391   ** Flush any data stored in the in-memory hash tables to the database.
   378    392   ** If the bCommit flag is true, also close any open blob handles.
   379    393   */
................................................................................
   429    443   int sqlite3Fts5GetVarint32(const unsigned char *p, u32 *v);
   430    444   int sqlite3Fts5GetVarintLen(u32 iVal);
   431    445   u8 sqlite3Fts5GetVarint(const unsigned char*, u64*);
   432    446   int sqlite3Fts5PutVarint(unsigned char *p, u64 v);
   433    447   
   434    448   #define fts5GetVarint32(a,b) sqlite3Fts5GetVarint32(a,(u32*)&b)
   435    449   #define fts5GetVarint    sqlite3Fts5GetVarint
          450  +
          451  +#define fts5FastGetVarint32(a, iOff, nVal) {      \
          452  +  nVal = (a)[iOff++];                             \
          453  +  if( nVal & 0x80 ){                              \
          454  +    iOff--;                                       \
          455  +    iOff += fts5GetVarint32(&(a)[iOff], nVal);    \
          456  +  }                                               \
          457  +}
          458  +
   436    459   
   437    460   /*
   438    461   ** End of interface to code in fts5_varint.c.
   439    462   **************************************************************************/
   440    463   
   441    464   
   442    465   /**************************************************************************
................................................................................
   522    545   int sqlite3Fts5StorageClose(Fts5Storage *p);
   523    546   int sqlite3Fts5StorageRename(Fts5Storage*, const char *zName);
   524    547   
   525    548   int sqlite3Fts5DropAll(Fts5Config*);
   526    549   int sqlite3Fts5CreateTable(Fts5Config*, const char*, const char*, int, char **);
   527    550   
   528    551   int sqlite3Fts5StorageDelete(Fts5Storage *p, i64);
   529         -int sqlite3Fts5StorageInsert(Fts5Storage *p, sqlite3_value **apVal, int, i64*);
          552  +int sqlite3Fts5StorageContentInsert(Fts5Storage *p, sqlite3_value**, i64*);
          553  +int sqlite3Fts5StorageIndexInsert(Fts5Storage *p, sqlite3_value**, i64);
   530    554   
   531    555   int sqlite3Fts5StorageIntegrity(Fts5Storage *p);
   532    556   
   533    557   int sqlite3Fts5StorageStmt(Fts5Storage *p, int eStmt, sqlite3_stmt**, char**);
   534    558   void sqlite3Fts5StorageStmtRelease(Fts5Storage *p, int eStmt, sqlite3_stmt*);
   535    559   
   536    560   int sqlite3Fts5StorageDocsize(Fts5Storage *p, i64 iRowid, int *aCol);
................................................................................
   561    585   */
   562    586   typedef struct Fts5Expr Fts5Expr;
   563    587   typedef struct Fts5ExprNode Fts5ExprNode;
   564    588   typedef struct Fts5Parse Fts5Parse;
   565    589   typedef struct Fts5Token Fts5Token;
   566    590   typedef struct Fts5ExprPhrase Fts5ExprPhrase;
   567    591   typedef struct Fts5ExprNearset Fts5ExprNearset;
   568         -typedef struct Fts5ExprColset Fts5ExprColset;
   569    592   
   570    593   struct Fts5Token {
   571    594     const char *p;                  /* Token text (not NULL terminated) */
   572    595     int n;                          /* Size of buffer p in bytes */
   573    596   };
   574    597   
   575    598   /* Parse a MATCH expression. */
................................................................................
   629    652   
   630    653   Fts5ExprNearset *sqlite3Fts5ParseNearset(
   631    654     Fts5Parse*, 
   632    655     Fts5ExprNearset*,
   633    656     Fts5ExprPhrase* 
   634    657   );
   635    658   
   636         -Fts5ExprColset *sqlite3Fts5ParseColset(
          659  +Fts5Colset *sqlite3Fts5ParseColset(
   637    660     Fts5Parse*, 
   638         -  Fts5ExprColset*, 
          661  +  Fts5Colset*, 
   639    662     Fts5Token *
   640    663   );
   641    664   
   642    665   void sqlite3Fts5ParsePhraseFree(Fts5ExprPhrase*);
   643    666   void sqlite3Fts5ParseNearsetFree(Fts5ExprNearset*);
   644    667   void sqlite3Fts5ParseNodeFree(Fts5ExprNode*);
   645    668   
   646    669   void sqlite3Fts5ParseSetDistance(Fts5Parse*, Fts5ExprNearset*, Fts5Token*);
   647         -void sqlite3Fts5ParseSetColset(Fts5Parse*, Fts5ExprNearset*, Fts5ExprColset*);
          670  +void sqlite3Fts5ParseSetColset(Fts5Parse*, Fts5ExprNearset*, Fts5Colset*);
   648    671   void sqlite3Fts5ParseFinished(Fts5Parse *pParse, Fts5ExprNode *p);
   649    672   void sqlite3Fts5ParseNear(Fts5Parse *pParse, Fts5Token*);
   650    673   
   651    674   /*
   652    675   ** End of interface to code in fts5_expr.c.
   653    676   **************************************************************************/
   654    677   

Changes to ext/fts5/fts5_aux.c.

     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   ******************************************************************************
    12     12   */
    13     13   
    14     14   
    15     15   #include "fts5Int.h"
    16         -#include <math.h>
           16  +#include <math.h>                 /* amalgamator: keep */
    17     17   
    18     18   /*
    19     19   ** Object used to iterate through all "coalesced phrase instances" in 
    20     20   ** a single column of the current row. If the phrase instances in the
    21     21   ** column being considered do not overlap, this object simply iterates
    22     22   ** through them. Or, if they do overlap (share one or more tokens in
    23     23   ** common), each set of overlapping instances is treated as a single

Changes to ext/fts5/fts5_buffer.c.

   181    181     if( i>=n ){
   182    182       /* EOF */
   183    183       *piOff = -1;
   184    184       return 1;  
   185    185     }else{
   186    186       i64 iOff = *piOff;
   187    187       int iVal;
   188         -    i += fts5GetVarint32(&a[i], iVal);
          188  +    fts5FastGetVarint32(a, i, iVal);
   189    189       if( iVal==1 ){
   190         -      i += fts5GetVarint32(&a[i], iVal);
          190  +      fts5FastGetVarint32(a, i, iVal);
   191    191         iOff = ((i64)iVal) << 32;
   192         -      i += fts5GetVarint32(&a[i], iVal);
          192  +      fts5FastGetVarint32(a, i, iVal);
   193    193       }
   194    194       *piOff = iOff + (iVal-2);
   195    195       *pi = i;
   196    196       return 0;
   197    197     }
   198    198   }
   199    199   
   200    200   
   201    201   /*
   202    202   ** Advance the iterator object passed as the only argument. Return true
   203    203   ** if the iterator reaches EOF, or false otherwise.
   204    204   */
   205    205   int sqlite3Fts5PoslistReaderNext(Fts5PoslistReader *pIter){
   206         -  if( sqlite3Fts5PoslistNext64(pIter->a, pIter->n, &pIter->i, &pIter->iPos) 
   207         -   || (pIter->iCol>=0 && (pIter->iPos >> 32) > pIter->iCol)
   208         -  ){
          206  +  if( sqlite3Fts5PoslistNext64(pIter->a, pIter->n, &pIter->i, &pIter->iPos) ){
   209    207       pIter->bEof = 1;
   210    208     }
   211    209     return pIter->bEof;
   212    210   }
   213    211   
   214    212   int sqlite3Fts5PoslistReaderInit(
   215         -  int iCol,                       /* If (iCol>=0), this column only */
   216    213     const u8 *a, int n,             /* Poslist buffer to iterate through */
   217    214     Fts5PoslistReader *pIter        /* Iterator object to initialize */
   218    215   ){
   219    216     memset(pIter, 0, sizeof(*pIter));
   220    217     pIter->a = a;
   221    218     pIter->n = n;
   222         -  pIter->iCol = iCol;
   223         -  do {
   224         -    sqlite3Fts5PoslistReaderNext(pIter);
   225         -  }while( pIter->bEof==0 && (pIter->iPos >> 32)<iCol );
          219  +  sqlite3Fts5PoslistReaderNext(pIter);
   226    220     return pIter->bEof;
   227    221   }
   228    222   
   229    223   int sqlite3Fts5PoslistWriterAppend(
   230    224     Fts5Buffer *pBuf, 
   231    225     Fts5PoslistWriter *pWriter,
   232    226     i64 iPos
   233    227   ){
   234    228     static const i64 colmask = ((i64)(0x7FFFFFFF)) << 32;
   235    229     int rc = SQLITE_OK;
   236         -  if( (iPos & colmask) != (pWriter->iPrev & colmask) ){
   237         -    fts5BufferAppendVarint(&rc, pBuf, 1);
   238         -    fts5BufferAppendVarint(&rc, pBuf, (iPos >> 32));
   239         -    pWriter->iPrev = (iPos & colmask);
          230  +  if( 0==sqlite3Fts5BufferGrow(&rc, pBuf, 5+5+5) ){
          231  +    if( (iPos & colmask) != (pWriter->iPrev & colmask) ){
          232  +      pBuf->p[pBuf->n++] = 1;
          233  +      pBuf->n += sqlite3Fts5PutVarint(&pBuf->p[pBuf->n], (iPos>>32));
          234  +      pWriter->iPrev = (iPos & colmask);
          235  +    }
          236  +    pBuf->n += sqlite3Fts5PutVarint(&pBuf->p[pBuf->n], (iPos-pWriter->iPrev)+2);
          237  +    pWriter->iPrev = iPos;
   240    238     }
   241         -  fts5BufferAppendVarint(&rc, pBuf, (iPos - pWriter->iPrev) + 2);
   242         -  pWriter->iPrev = iPos;
   243    239     return rc;
   244    240   }
   245    241   
   246    242   void *sqlite3Fts5MallocZero(int *pRc, int nByte){
   247    243     void *pRet = 0;
   248    244     if( *pRc==SQLITE_OK ){
   249    245       pRet = sqlite3_malloc(nByte);
................................................................................
   286    282   ** Return true if character 't' may be part of an FTS5 bareword, or false
   287    283   ** otherwise. Characters that may be part of barewords:
   288    284   **
   289    285   **   * All non-ASCII characters,
   290    286   **   * The 52 upper and lower case ASCII characters, and
   291    287   **   * The 10 integer ASCII characters.
   292    288   **   * The underscore character "_" (0x5F).
          289  +**   * The unicode "subsitute" character (0x1A).
   293    290   */
   294    291   int sqlite3Fts5IsBareword(char t){
   295    292     u8 aBareword[128] = {
   296    293       0, 0, 0, 0, 0, 0, 0, 0,    0, 0, 0, 0, 0, 0, 0, 0,   /* 0x00 .. 0x0F */
   297         -    0, 0, 0, 0, 0, 0, 0, 0,    0, 0, 0, 0, 0, 0, 0, 0,   /* 0x10 .. 0x1F */
          294  +    0, 0, 0, 0, 0, 0, 0, 0,    0, 0, 1, 0, 0, 0, 0, 0,   /* 0x10 .. 0x1F */
   298    295       0, 0, 0, 0, 0, 0, 0, 0,    0, 0, 0, 0, 0, 0, 0, 0,   /* 0x20 .. 0x2F */
   299    296       1, 1, 1, 1, 1, 1, 1, 1,    1, 1, 0, 0, 0, 0, 0, 0,   /* 0x30 .. 0x3F */
   300    297       0, 1, 1, 1, 1, 1, 1, 1,    1, 1, 1, 1, 1, 1, 1, 1,   /* 0x40 .. 0x4F */
   301    298       1, 1, 1, 1, 1, 1, 1, 1,    1, 1, 1, 0, 0, 0, 0, 1,   /* 0x50 .. 0x5F */
   302    299       0, 1, 1, 1, 1, 1, 1, 1,    1, 1, 1, 1, 1, 1, 1, 1,   /* 0x60 .. 0x6F */
   303    300       1, 1, 1, 1, 1, 1, 1, 1,    1, 1, 1, 0, 0, 0, 0, 0    /* 0x70 .. 0x7F */
   304    301     };
   305    302   
   306    303     return (t & 0x80) || aBareword[(int)t];
   307    304   }
   308    305   
   309    306   

Changes to ext/fts5/fts5_expr.c.

    28     28   
    29     29   /*
    30     30   ** Functions generated by lemon from fts5parse.y.
    31     31   */
    32     32   void *sqlite3Fts5ParserAlloc(void *(*mallocProc)(u64));
    33     33   void sqlite3Fts5ParserFree(void*, void (*freeProc)(void*));
    34     34   void sqlite3Fts5Parser(void*, int, Fts5Token, Fts5Parse*);
           35  +#ifndef NDEBUG
           36  +#include <stdio.h>
           37  +void sqlite3Fts5ParserTrace(FILE*, char*);
           38  +#endif
           39  +
    35     40   
    36     41   struct Fts5Expr {
    37     42     Fts5Index *pIndex;
    38     43     Fts5ExprNode *pRoot;
    39     44     int bDesc;                      /* Iterate in descending rowid order */
    40     45     int nPhrase;                    /* Number of phrases in expression */
    41     46     Fts5ExprPhrase **apExprPhrase;  /* Pointers to phrase objects */
................................................................................
    85     90   struct Fts5ExprPhrase {
    86     91     Fts5ExprNode *pNode;            /* FTS5_STRING node this phrase is part of */
    87     92     Fts5Buffer poslist;             /* Current position list */
    88     93     int nTerm;                      /* Number of entries in aTerm[] */
    89     94     Fts5ExprTerm aTerm[1];          /* Terms that make up this phrase */
    90     95   };
    91     96   
    92         -/*
    93         -** If a NEAR() clump may only match a specific set of columns, then
    94         -** Fts5ExprNearset.pColset points to an object of the following type.
    95         -** Each entry in the aiCol[] array
    96         -*/
    97         -struct Fts5ExprColset {
    98         -  int nCol;
    99         -  int aiCol[1];
   100         -};
   101         -
   102     97   /*
   103     98   ** One or more phrases that must appear within a certain token distance of
   104     99   ** each other within each matching document.
   105    100   */
   106    101   struct Fts5ExprNearset {
   107    102     int nNear;                      /* NEAR parameter */
   108         -  Fts5ExprColset *pColset;        /* Columns to search (NULL -> all columns) */
          103  +  Fts5Colset *pColset;            /* Columns to search (NULL -> all columns) */
   109    104     int nPhrase;                    /* Number of entries in aPhrase[] array */
   110    105     Fts5ExprPhrase *apPhrase[1];    /* Array of phrase pointers */
   111    106   };
   112    107   
   113    108   
   114    109   /*
   115    110   ** Parse context.
................................................................................
   272    267     if( p ){
   273    268       sqlite3Fts5ParseNodeFree(p->pRoot);
   274    269       sqlite3_free(p->apExprPhrase);
   275    270       sqlite3_free(p);
   276    271     }
   277    272   }
   278    273   
   279         -static int fts5ExprColsetTest(Fts5ExprColset *pColset, int iCol){
   280         -  int i;
   281         -  for(i=0; i<pColset->nCol; i++){
   282         -    if( pColset->aiCol[i]==iCol ) return 1;
   283         -  }
   284         -  return 0;
   285         -}
   286         -
   287    274   /*
   288    275   ** Argument pTerm must be a synonym iterator. Return the current rowid
   289    276   ** that it points to.
   290    277   */
   291    278   static i64 fts5ExprSynonymRowid(Fts5ExprTerm *pTerm, int bDesc, int *pbEof){
   292    279     i64 iRet = 0;
   293    280     int bRetValid = 0;
................................................................................
   310    297   }
   311    298   
   312    299   /*
   313    300   ** Argument pTerm must be a synonym iterator.
   314    301   */
   315    302   static int fts5ExprSynonymPoslist(
   316    303     Fts5ExprTerm *pTerm, 
          304  +  Fts5Colset *pColset,
   317    305     i64 iRowid,
   318    306     int *pbDel,                     /* OUT: Caller should sqlite3_free(*pa) */
   319    307     u8 **pa, int *pn
   320    308   ){
   321    309     Fts5PoslistReader aStatic[4];
   322    310     Fts5PoslistReader *aIter = aStatic;
   323    311     int nIter = 0;
................................................................................
   328    316     assert( pTerm->pSynonym );
   329    317     for(p=pTerm; p; p=p->pSynonym){
   330    318       Fts5IndexIter *pIter = p->pIter;
   331    319       if( sqlite3Fts5IterEof(pIter)==0 && sqlite3Fts5IterRowid(pIter)==iRowid ){
   332    320         const u8 *a;
   333    321         int n;
   334    322         i64 dummy;
   335         -      rc = sqlite3Fts5IterPoslist(pIter, &a, &n, &dummy);
          323  +      rc = sqlite3Fts5IterPoslist(pIter, pColset, &a, &n, &dummy);
   336    324         if( rc!=SQLITE_OK ) goto synonym_poslist_out;
   337    325         if( nIter==nAlloc ){
   338    326           int nByte = sizeof(Fts5PoslistReader) * nAlloc * 2;
   339    327           Fts5PoslistReader *aNew = (Fts5PoslistReader*)sqlite3_malloc(nByte);
   340    328           if( aNew==0 ){
   341    329             rc = SQLITE_NOMEM;
   342    330             goto synonym_poslist_out;
   343    331           }
   344    332           memcpy(aNew, aIter, sizeof(Fts5PoslistReader) * nIter);
   345    333           nAlloc = nAlloc*2;
   346    334           if( aIter!=aStatic ) sqlite3_free(aIter);
   347    335           aIter = aNew;
   348    336         }
   349         -      sqlite3Fts5PoslistReaderInit(-1, a, n, &aIter[nIter]);
          337  +      sqlite3Fts5PoslistReaderInit(a, n, &aIter[nIter]);
   350    338         assert( aIter[nIter].bEof==0 );
   351    339         nIter++;
   352    340       }
   353    341     }
   354    342   
   355    343     assert( *pbDel==0 );
   356    344     if( nIter==1 ){
................................................................................
   401    389   **
   402    390   ** SQLITE_OK is returned if an error occurs, or an SQLite error code 
   403    391   ** otherwise. It is not considered an error code if the current rowid is 
   404    392   ** not a match.
   405    393   */
   406    394   static int fts5ExprPhraseIsMatch(
   407    395     Fts5ExprNode *pNode,            /* Node pPhrase belongs to */
   408         -  Fts5ExprColset *pColset,        /* Restrict matches to these columns */
          396  +  Fts5Colset *pColset,            /* Restrict matches to these columns */
   409    397     Fts5ExprPhrase *pPhrase,        /* Phrase object to initialize */
   410    398     int *pbMatch                    /* OUT: Set to true if really a match */
   411    399   ){
   412    400     Fts5PoslistWriter writer = {0};
   413    401     Fts5PoslistReader aStatic[4];
   414    402     Fts5PoslistReader *aIter = aStatic;
   415    403     int i;
   416    404     int rc = SQLITE_OK;
   417         -  int iCol = -1;
   418    405     
   419         -  if( pColset && pColset->nCol==1 ){
   420         -    iCol = pColset->aiCol[0];
   421         -    pColset = 0;
   422         -  }
   423         -
   424    406     fts5BufferZero(&pPhrase->poslist);
   425    407   
   426    408     /* If the aStatic[] array is not large enough, allocate a large array
   427    409     ** using sqlite3_malloc(). This approach could be improved upon. */
   428    410     if( pPhrase->nTerm>(sizeof(aStatic) / sizeof(aStatic[0])) ){
   429    411       int nByte = sizeof(Fts5PoslistReader) * pPhrase->nTerm;
   430    412       aIter = (Fts5PoslistReader*)sqlite3_malloc(nByte);
................................................................................
   436    418     for(i=0; i<pPhrase->nTerm; i++){
   437    419       Fts5ExprTerm *pTerm = &pPhrase->aTerm[i];
   438    420       i64 dummy;
   439    421       int n = 0;
   440    422       int bFlag = 0;
   441    423       const u8 *a = 0;
   442    424       if( pTerm->pSynonym ){
   443         -      rc = fts5ExprSynonymPoslist(pTerm, pNode->iRowid, &bFlag, (u8**)&a, &n);
          425  +      rc = fts5ExprSynonymPoslist(
          426  +          pTerm, pColset, pNode->iRowid, &bFlag, (u8**)&a, &n
          427  +      );
   444    428       }else{
   445         -      rc = sqlite3Fts5IterPoslist(pTerm->pIter, &a, &n, &dummy);
          429  +      rc = sqlite3Fts5IterPoslist(pTerm->pIter, pColset, &a, &n, &dummy);
   446    430       }
   447    431       if( rc!=SQLITE_OK ) goto ismatch_out;
   448         -    sqlite3Fts5PoslistReaderInit(iCol, a, n, &aIter[i]);
          432  +    sqlite3Fts5PoslistReaderInit(a, n, &aIter[i]);
   449    433       aIter[i].bFlag = bFlag;
   450    434       if( aIter[i].bEof ) goto ismatch_out;
   451    435     }
   452    436   
   453    437     while( 1 ){
   454    438       int bMatch;
   455    439       i64 iPos = aIter[0].iPos;
................................................................................
   464    448               if( sqlite3Fts5PoslistReaderNext(pPos) ) goto ismatch_out;
   465    449             }
   466    450             if( pPos->iPos>iAdj ) iPos = pPos->iPos-i;
   467    451           }
   468    452         }
   469    453       }while( bMatch==0 );
   470    454   
   471         -    if( pColset==0 || fts5ExprColsetTest(pColset, FTS5_POS2COLUMN(iPos)) ){
   472         -      /* Append position iPos to the output */
   473         -      rc = sqlite3Fts5PoslistWriterAppend(&pPhrase->poslist, &writer, iPos);
   474         -      if( rc!=SQLITE_OK ) goto ismatch_out;
   475         -    }
          455  +    /* Append position iPos to the output */
          456  +    rc = sqlite3Fts5PoslistWriterAppend(&pPhrase->poslist, &writer, iPos);
          457  +    if( rc!=SQLITE_OK ) goto ismatch_out;
   476    458   
   477    459       for(i=0; i<pPhrase->nTerm; i++){
   478    460         if( sqlite3Fts5PoslistReaderNext(&aIter[i]) ) goto ismatch_out;
   479    461       }
   480    462     }
   481    463   
   482    464    ismatch_out:
................................................................................
   763    745       bEof = 1;
   764    746     }else{
   765    747       *piLast = fts5ExprSynonymRowid(pTerm, bDesc, &bEof);
   766    748     }
   767    749     return bEof;
   768    750   }
   769    751   
   770         -/*
   771         -** IN/OUT parameter (*pa) points to a position list n bytes in size. If
   772         -** the position list contains entries for column iCol, then (*pa) is set
   773         -** to point to the sub-position-list for that column and the number of
   774         -** bytes in it returned. Or, if the argument position list does not
   775         -** contain any entries for column iCol, return 0.
   776         -*/
   777         -static int fts5ExprExtractCol(
   778         -  const u8 **pa,                  /* IN/OUT: Pointer to poslist */
   779         -  int n,                          /* IN: Size of poslist in bytes */
   780         -  int iCol                        /* Column to extract from poslist */
   781         -){
   782         -  int iCurrent = 0;
   783         -  const u8 *p = *pa;
   784         -  const u8 *pEnd = &p[n];         /* One byte past end of position list */
   785         -  u8 prev = 0;
   786         -
   787         -  while( iCol!=iCurrent ){
   788         -    /* Advance pointer p until it points to pEnd or an 0x01 byte that is
   789         -    ** not part of a varint */
   790         -    while( (prev & 0x80) || *p!=0x01 ){
   791         -      prev = *p++;
   792         -      if( p==pEnd ) return 0;
   793         -    }
   794         -    *pa = p++;
   795         -    p += fts5GetVarint32(p, iCurrent);
   796         -  }
   797         -
   798         -  /* Advance pointer p until it points to pEnd or an 0x01 byte that is
   799         -  ** not part of a varint */
   800         -  assert( (prev & 0x80)==0 );
   801         -  while( p<pEnd && ((prev & 0x80) || *p!=0x01) ){
   802         -    prev = *p++;
   803         -  }
   804         -  return p - (*pa);
   805         -}
   806         -
   807         -static int fts5ExprExtractColset (
   808         -  Fts5ExprColset *pColset,        /* Colset to filter on */
   809         -  const u8 *pPos, int nPos,       /* Position list */
   810         -  Fts5Buffer *pBuf                /* Output buffer */
   811         -){
   812         -  int rc = SQLITE_OK;
   813         -  int i;
   814         -
   815         -  fts5BufferZero(pBuf);
   816         -  for(i=0; i<pColset->nCol; i++){
   817         -    const u8 *pSub = pPos;
   818         -    int nSub = fts5ExprExtractCol(&pSub, nPos, pColset->aiCol[i]);
   819         -    if( nSub ){
   820         -      fts5BufferAppendBlob(&rc, pBuf, nSub, pSub);
   821         -    }
   822         -  }
   823         -  return rc;
   824         -}
   825    752   
   826    753   static int fts5ExprNearTest(
   827    754     int *pRc,
   828    755     Fts5Expr *pExpr,                /* Expression that pNear is a part of */
   829    756     Fts5ExprNode *pNode             /* The "NEAR" node (FTS5_STRING) */
   830    757   ){
   831    758     Fts5ExprNearset *pNear = pNode->pNear;
................................................................................
   864    791     ** of a single term only, grab pointers into the poslist managed by the
   865    792     ** fts5_index.c iterator object. This is much faster than synthesizing 
   866    793     ** a new poslist the way we have to for more complicated phrase or NEAR
   867    794     ** expressions.  */
   868    795     Fts5ExprNearset *pNear = pNode->pNear;
   869    796     Fts5ExprPhrase *pPhrase = pNear->apPhrase[0];
   870    797     Fts5IndexIter *pIter = pPhrase->aTerm[0].pIter;
   871         -  Fts5ExprColset *pColset = pNear->pColset;
   872         -  const u8 *pPos;
   873         -  int nPos;
          798  +  Fts5Colset *pColset = pNear->pColset;
   874    799     int rc;
   875    800   
   876    801     assert( pNode->eType==FTS5_TERM );
   877    802     assert( pNear->nPhrase==1 && pPhrase->nTerm==1 );
   878    803     assert( pPhrase->aTerm[0].pSynonym==0 );
   879    804   
   880         -  rc = sqlite3Fts5IterPoslist(pIter, &pPos, &nPos, &pNode->iRowid);
   881         -
   882         -  /* If the term may match any column, then this must be a match. 
   883         -  ** Return immediately in this case. Otherwise, try to find the
   884         -  ** part of the poslist that corresponds to the required column.
   885         -  ** If it can be found, return. If it cannot, the next iteration
   886         -  ** of the loop will test the next rowid in the database for this
   887         -  ** term.  */
   888         -  if( pColset==0 ){
   889         -    assert( pPhrase->poslist.nSpace==0 );
   890         -    pPhrase->poslist.p = (u8*)pPos;
   891         -    pPhrase->poslist.n = nPos;
   892         -  }else if( pColset->nCol==1 ){
   893         -    assert( pPhrase->poslist.nSpace==0 );
   894         -    pPhrase->poslist.n = fts5ExprExtractCol(&pPos, nPos, pColset->aiCol[0]);
   895         -    pPhrase->poslist.p = (u8*)pPos;
   896         -  }else if( rc==SQLITE_OK ){
   897         -    rc = fts5ExprExtractColset(pColset, pPos, nPos, &pPhrase->poslist);
   898         -  }
   899         -
          805  +  rc = sqlite3Fts5IterPoslist(pIter, pColset, 
          806  +      (const u8**)&pPhrase->poslist.p, &pPhrase->poslist.n, &pNode->iRowid
          807  +  );
   900    808     pNode->bNomatch = (pPhrase->poslist.n==0);
   901    809     return rc;
   902    810   }
   903    811   
   904    812   /*
   905    813   ** All individual term iterators in pNear are guaranteed to be valid when
   906    814   ** this function is called. This function checks if all term iterators
................................................................................
   998    906             sqlite3Fts5IterClose(p->pIter);
   999    907             p->pIter = 0;
  1000    908           }
  1001    909           rc = sqlite3Fts5IndexQuery(
  1002    910               pExpr->pIndex, p->zTerm, strlen(p->zTerm),
  1003    911               (pTerm->bPrefix ? FTS5INDEX_QUERY_PREFIX : 0) |
  1004    912               (pExpr->bDesc ? FTS5INDEX_QUERY_DESC : 0),
          913  +            pNear->pColset,
  1005    914               &p->pIter
  1006    915           );
  1007    916           assert( rc==SQLITE_OK || p->pIter==0 );
  1008    917           if( p->pIter && 0==sqlite3Fts5IterEof(p->pIter) ){
  1009    918             bEof = 0;
  1010    919           }
  1011    920         }
................................................................................
  1750   1659       nNear = FTS5_DEFAULT_NEARDIST;
  1751   1660     }
  1752   1661     pNear->nNear = nNear;
  1753   1662   }
  1754   1663   
  1755   1664   /*
  1756   1665   ** The second argument passed to this function may be NULL, or it may be
  1757         -** an existing Fts5ExprColset object. This function returns a pointer to
         1666  +** an existing Fts5Colset object. This function returns a pointer to
  1758   1667   ** a new colset object containing the contents of (p) with new value column
  1759   1668   ** number iCol appended. 
  1760   1669   **
  1761   1670   ** If an OOM error occurs, store an error code in pParse and return NULL.
  1762   1671   ** The old colset object (if any) is not freed in this case.
  1763   1672   */
  1764         -static Fts5ExprColset *fts5ParseColset(
         1673  +static Fts5Colset *fts5ParseColset(
  1765   1674     Fts5Parse *pParse,              /* Store SQLITE_NOMEM here if required */
  1766         -  Fts5ExprColset *p,              /* Existing colset object */
         1675  +  Fts5Colset *p,                  /* Existing colset object */
  1767   1676     int iCol                        /* New column to add to colset object */
  1768   1677   ){
  1769   1678     int nCol = p ? p->nCol : 0;     /* Num. columns already in colset object */
  1770         -  Fts5ExprColset *pNew;           /* New colset object to return */
         1679  +  Fts5Colset *pNew;               /* New colset object to return */
  1771   1680   
  1772   1681     assert( pParse->rc==SQLITE_OK );
  1773   1682     assert( iCol>=0 && iCol<pParse->pConfig->nCol );
  1774   1683   
  1775         -  pNew = sqlite3_realloc(p, sizeof(Fts5ExprColset) + sizeof(int)*nCol);
         1684  +  pNew = sqlite3_realloc(p, sizeof(Fts5Colset) + sizeof(int)*nCol);
  1776   1685     if( pNew==0 ){
  1777   1686       pParse->rc = SQLITE_NOMEM;
  1778   1687     }else{
  1779   1688       int *aiCol = pNew->aiCol;
  1780   1689       int i, j;
  1781   1690       for(i=0; i<nCol; i++){
  1782   1691         if( aiCol[i]==iCol ) return pNew;
................................................................................
  1793   1702       for(i=1; i<pNew->nCol; i++) assert( pNew->aiCol[i]>pNew->aiCol[i-1] );
  1794   1703   #endif
  1795   1704     }
  1796   1705   
  1797   1706     return pNew;
  1798   1707   }
  1799   1708   
  1800         -Fts5ExprColset *sqlite3Fts5ParseColset(
         1709  +Fts5Colset *sqlite3Fts5ParseColset(
  1801   1710     Fts5Parse *pParse,              /* Store SQLITE_NOMEM here if required */
  1802         -  Fts5ExprColset *pColset,        /* Existing colset object */
         1711  +  Fts5Colset *pColset,            /* Existing colset object */
  1803   1712     Fts5Token *p
  1804   1713   ){
  1805         -  Fts5ExprColset *pRet = 0;
         1714  +  Fts5Colset *pRet = 0;
  1806   1715     int iCol;
  1807   1716     char *z;                        /* Dequoted copy of token p */
  1808   1717   
  1809   1718     z = sqlite3Fts5Strndup(&pParse->rc, p->p, p->n);
  1810   1719     if( pParse->rc==SQLITE_OK ){
  1811   1720       Fts5Config *pConfig = pParse->pConfig;
  1812   1721       sqlite3Fts5Dequote(z);
................................................................................
  1828   1737   
  1829   1738     return pRet;
  1830   1739   }
  1831   1740   
  1832   1741   void sqlite3Fts5ParseSetColset(
  1833   1742     Fts5Parse *pParse, 
  1834   1743     Fts5ExprNearset *pNear, 
  1835         -  Fts5ExprColset *pColset 
         1744  +  Fts5Colset *pColset 
  1836   1745   ){
  1837   1746     if( pNear ){
  1838   1747       pNear->pColset = pColset;
  1839   1748     }else{
  1840   1749       sqlite3_free(pColset);
  1841   1750     }
  1842   1751   }
................................................................................
  2280   2189     int rc = SQLITE_OK;
  2281   2190     void *pCtx = (void*)pGlobal;
  2282   2191   
  2283   2192     for(i=0; rc==SQLITE_OK && i<(sizeof(aFunc) / sizeof(aFunc[0])); i++){
  2284   2193       struct Fts5ExprFunc *p = &aFunc[i];
  2285   2194       rc = sqlite3_create_function(db, p->z, -1, SQLITE_UTF8, pCtx, p->x, 0, 0);
  2286   2195     }
         2196  +
         2197  +  /* Avoid a warning indicating that sqlite3Fts5ParserTrace() is unused */
         2198  +#ifndef NDEBUG
         2199  +  (void)sqlite3Fts5ParserTrace;
         2200  +#endif
  2287   2201   
  2288   2202     return rc;
  2289   2203   }
  2290   2204   
  2291   2205   /*
  2292   2206   ** Return the number of phrases in expression pExpr.
  2293   2207   */
................................................................................
  2316   2230       nRet = pPhrase->poslist.n;
  2317   2231     }else{
  2318   2232       *pa = 0;
  2319   2233       nRet = 0;
  2320   2234     }
  2321   2235     return nRet;
  2322   2236   }
  2323         -

Changes to ext/fts5/fts5_index.c.

   287    287     ** Variables related to the accumulation of tokens and doclists within the
   288    288     ** in-memory hash tables before they are flushed to disk.
   289    289     */
   290    290     Fts5Hash *pHash;                /* Hash table for in-memory data */
   291    291     int nMaxPendingData;            /* Max pending data before flush to disk */
   292    292     int nPendingData;               /* Current bytes of pending data */
   293    293     i64 iWriteRowid;                /* Rowid for current doc being written */
   294         -  Fts5Buffer scratch;
          294  +  int bDelete;                    /* Current write is a delete */
   295    295   
   296    296     /* Error state. */
   297    297     int rc;                         /* Current error code */
   298    298   
   299    299     /* State used by the fts5DataXXX() functions. */
   300    300     sqlite3_blob *pReader;          /* RO incr-blob open on %_data table */
   301    301     sqlite3_stmt *pWriter;          /* "INSERT ... %_data VALUES(?,?)" */
................................................................................
   303    303     sqlite3_stmt *pIdxWriter;       /* "INSERT ... %_idx VALUES(?,?,?,?)" */
   304    304     sqlite3_stmt *pIdxDeleter;      /* "DELETE FROM %_idx WHERE segid=? */
   305    305     sqlite3_stmt *pIdxSelect;
   306    306     int nRead;                      /* Total number of blocks read */
   307    307   };
   308    308   
   309    309   struct Fts5DoclistIter {
   310         -  u8 *a;
   311         -  int n;
   312         -  int i;
          310  +  u8 *aEof;                       /* Pointer to 1 byte past end of doclist */
   313    311   
   314    312     /* Output variables. aPoslist==0 at EOF */
   315    313     i64 iRowid;
   316    314     u8 *aPoslist;
   317    315     int nPoslist;
          316  +  int nSize;
   318    317   };
   319    318   
   320    319   /*
   321    320   ** The contents of the "structure" record for each index are represented
   322    321   ** using an Fts5Structure record in memory. Which uses instances of the 
   323    322   ** other Fts5StructureXXX types as components.
   324    323   */
................................................................................
   508    507   struct Fts5IndexIter {
   509    508     Fts5Index *pIndex;              /* Index that owns this iterator */
   510    509     Fts5Structure *pStruct;         /* Database structure for this iterator */
   511    510     Fts5Buffer poslist;             /* Buffer containing current poslist */
   512    511   
   513    512     int nSeg;                       /* Size of aSeg[] array */
   514    513     int bRev;                       /* True to iterate in reverse order */
   515         -  int bSkipEmpty;                 /* True to skip deleted entries */
   516         -  int bEof;                       /* True at EOF */
          514  +  u8 bSkipEmpty;                  /* True to skip deleted entries */
          515  +  u8 bEof;                        /* True at EOF */
          516  +  u8 bFiltered;                   /* True if column-filter already applied */
   517    517   
   518    518     i64 iSwitchRowid;               /* Firstest rowid of other than aFirst[1] */
   519    519     Fts5CResult *aFirst;            /* Current merge state (see above) */
   520    520     Fts5SegIter aSeg[1];            /* Array of segment iterators */
   521    521   };
   522    522   
   523    523   
................................................................................
  1454   1454   ** Argument p points to a buffer containing a varint to be interpreted as a
  1455   1455   ** position list size field. Read the varint and return the number of bytes
  1456   1456   ** read. Before returning, set *pnSz to the number of bytes in the position
  1457   1457   ** list, and *pbDel to true if the delete flag is set, or false otherwise.
  1458   1458   */
  1459   1459   static int fts5GetPoslistSize(const u8 *p, int *pnSz, int *pbDel){
  1460   1460     int nSz;
  1461         -  int n = fts5GetVarint32(p, nSz);
         1461  +  int n = 0;
         1462  +  fts5FastGetVarint32(p, n, nSz);
  1462   1463     assert_nc( nSz>=0 );
  1463   1464     *pnSz = nSz/2;
  1464   1465     *pbDel = nSz & 0x0001;
  1465   1466     return n;
  1466   1467   }
  1467   1468   
  1468   1469   /*
................................................................................
  1475   1476   **
  1476   1477   ** Leave Fts5SegIter.iLeafOffset pointing to the first byte of the 
  1477   1478   ** position list content (if any).
  1478   1479   */
  1479   1480   static void fts5SegIterLoadNPos(Fts5Index *p, Fts5SegIter *pIter){
  1480   1481     if( p->rc==SQLITE_OK ){
  1481   1482       int iOff = pIter->iLeafOffset;  /* Offset to read at */
         1483  +    int nSz;
  1482   1484       ASSERT_SZLEAF_OK(pIter->pLeaf);
  1483         -    if( iOff>=pIter->pLeaf->szLeaf ){
  1484         -      p->rc = FTS5_CORRUPT;
  1485         -    }else{
  1486         -      const u8 *a = &pIter->pLeaf->p[iOff];
  1487         -      pIter->iLeafOffset += fts5GetPoslistSize(a, &pIter->nPos, &pIter->bDel);
  1488         -    }
         1485  +    fts5FastGetVarint32(pIter->pLeaf->p, iOff, nSz);
         1486  +    pIter->bDel = (nSz & 0x0001);
         1487  +    pIter->nPos = nSz>>1;
         1488  +    pIter->iLeafOffset = iOff;
  1489   1489     }
  1490   1490   }
  1491   1491   
  1492   1492   static void fts5SegIterLoadRowid(Fts5Index *p, Fts5SegIter *pIter){
  1493   1493     u8 *a = pIter->pLeaf->p;        /* Buffer to read data from */
  1494   1494     int iOff = pIter->iLeafOffset;
  1495   1495   
................................................................................
  1776   1776           }else{
  1777   1777             pIter->pLeaf->p = (u8*)pList;
  1778   1778             pIter->pLeaf->nn = nList;
  1779   1779             pIter->pLeaf->szLeaf = nList;
  1780   1780             pIter->iEndofDoclist = nList+1;
  1781   1781             sqlite3Fts5BufferSet(&p->rc, &pIter->term, strlen(zTerm), (u8*)zTerm);
  1782   1782             pIter->iLeafOffset = fts5GetVarint(pList, (u64*)&pIter->iRowid);
         1783  +          if( pbNewTerm ) *pbNewTerm = 1;
  1783   1784           }
  1784   1785         }else{
  1785   1786           iOff = 0;
  1786   1787           /* Next entry is not on the current page */
  1787   1788           while( iOff==0 ){
  1788   1789             fts5SegIterNextPage(p, pIter);
  1789   1790             pLeaf = pIter->pLeaf;
................................................................................
  1936   1937     ){
  1937   1938       return;
  1938   1939     }
  1939   1940   
  1940   1941     pIter->pDlidx = fts5DlidxIterInit(p, bRev, iSeg, pIter->iTermLeafPgno);
  1941   1942   }
  1942   1943   
  1943         -#define fts5IndexGetVarint32(a, iOff, nVal) {     \
  1944         -  nVal = (a)[iOff++];                             \
  1945         -  if( nVal & 0x80 ){                              \
  1946         -    iOff--;                                       \
  1947         -    iOff += fts5GetVarint32(&(a)[iOff], nVal);    \
  1948         -  }                                               \
  1949         -}
  1950         -
  1951   1944   #define fts5IndexSkipVarint(a, iOff) {            \
  1952   1945     int iEnd = iOff+9;                              \
  1953   1946     while( (a[iOff++] & 0x80) && iOff<iEnd );       \
  1954   1947   }
  1955   1948   
  1956   1949   /*
  1957   1950   ** The iterator object passed as the second argument currently contains
................................................................................
  1990   1983     iPgidx = szLeaf;
  1991   1984     iPgidx += fts5GetVarint32(&a[iPgidx], iTermOff);
  1992   1985     iOff = iTermOff;
  1993   1986   
  1994   1987     while( 1 ){
  1995   1988   
  1996   1989       /* Figure out how many new bytes are in this term */
  1997         -    fts5IndexGetVarint32(a, iOff, nNew);
         1990  +    fts5FastGetVarint32(a, iOff, nNew);
  1998   1991       if( nKeep<nMatch ){
  1999   1992         goto search_failed;
  2000   1993       }
  2001   1994   
  2002   1995       assert( nKeep>=nMatch );
  2003   1996       if( nKeep==nMatch ){
  2004   1997         int nCmp;
................................................................................
  2026   2019       }
  2027   2020   
  2028   2021       iPgidx += fts5GetVarint32(&a[iPgidx], nKeep);
  2029   2022       iTermOff += nKeep;
  2030   2023       iOff = iTermOff;
  2031   2024   
  2032   2025       /* Read the nKeep field of the next term. */
  2033         -    fts5IndexGetVarint32(a, iOff, nKeep);
         2026  +    fts5FastGetVarint32(a, iOff, nKeep);
  2034   2027     }
  2035   2028   
  2036   2029    search_failed:
  2037   2030     if( bGe==0 ){
  2038   2031       fts5DataRelease(pIter->pLeaf);
  2039   2032       pIter->pLeaf = 0;
  2040   2033       return;
................................................................................
  2729   2722     Fts5IndexIter **ppOut           /* New object */
  2730   2723   ){
  2731   2724     Fts5IndexIter *pNew;
  2732   2725     pNew = fts5MultiIterAlloc(p, 2);
  2733   2726     if( pNew ){
  2734   2727       Fts5SegIter *pIter = &pNew->aSeg[1];
  2735   2728   
         2729  +    pNew->bFiltered = 1;
  2736   2730       pIter->flags = FTS5_SEGITER_ONETERM;
  2737   2731       if( pData->szLeaf>0 ){
  2738   2732         pIter->pLeaf = pData;
  2739   2733         pIter->iLeafOffset = fts5GetVarint(pData->p, (u64*)&pIter->iRowid);
  2740   2734         pIter->iEndofDoclist = pData->nn;
  2741   2735         pNew->aFirst[1].iFirst = 1;
  2742   2736         if( bDesc ){
................................................................................
  3701   3695         if( (ret + i) > nMax ) break;
  3702   3696         ret += i;
  3703   3697       }
  3704   3698     }
  3705   3699     return ret;
  3706   3700   }
  3707   3701   
  3708         -#define fts5BufferSafeAppendBlob(pBuf, pBlob, nBlob) { \
  3709         -  assert( pBuf->nSpace>=(pBuf->n+nBlob) );             \
  3710         -  memcpy(&pBuf->p[pBuf->n], pBlob, nBlob);             \
  3711         -  pBuf->n += nBlob;                                    \
         3702  +#define fts5BufferSafeAppendBlob(pBuf, pBlob, nBlob) {     \
         3703  +  assert( (pBuf)->nSpace>=((pBuf)->n+nBlob) );             \
         3704  +  memcpy(&(pBuf)->p[(pBuf)->n], pBlob, nBlob);             \
         3705  +  (pBuf)->n += nBlob;                                      \
         3706  +}
         3707  +
         3708  +#define fts5BufferSafeAppendVarint(pBuf, iVal) {                \
         3709  +  (pBuf)->n += sqlite3Fts5PutVarint(&(pBuf)->p[(pBuf)->n], (iVal));  \
         3710  +  assert( (pBuf)->nSpace>=(pBuf)->n );                          \
  3712   3711   }
  3713   3712   
  3714   3713   /*
  3715   3714   ** Flush the contents of in-memory hash table iHash to a new level-0 
  3716   3715   ** segment on disk. Also update the corresponding structure record.
  3717   3716   **
  3718   3717   ** If an error occurs, set the Fts5Index.rc error code. If an error has 
................................................................................
  3934   3933     fts5StructureRelease(pStruct);
  3935   3934   
  3936   3935     return fts5IndexReturn(p);
  3937   3936   }
  3938   3937   
  3939   3938   static void fts5PoslistCallback(
  3940   3939     Fts5Index *p, 
  3941         -  void *pCtx, 
         3940  +  void *pContext, 
         3941  +  const u8 *pChunk, int nChunk
         3942  +){
         3943  +  assert_nc( nChunk>=0 );
         3944  +  if( nChunk>0 ){
         3945  +    fts5BufferSafeAppendBlob((Fts5Buffer*)pContext, pChunk, nChunk);
         3946  +  }
         3947  +}
         3948  +
         3949  +typedef struct PoslistCallbackCtx PoslistCallbackCtx;
         3950  +struct PoslistCallbackCtx {
         3951  +  Fts5Buffer *pBuf;               /* Append to this buffer */
         3952  +  Fts5Colset *pColset;            /* Restrict matches to this column */
         3953  +  int eState;                     /* See above */
         3954  +};
         3955  +
         3956  +/*
         3957  +** TODO: Make this more efficient!
         3958  +*/
         3959  +static int fts5IndexColsetTest(Fts5Colset *pColset, int iCol){
         3960  +  int i;
         3961  +  for(i=0; i<pColset->nCol; i++){
         3962  +    if( pColset->aiCol[i]==iCol ) return 1;
         3963  +  }
         3964  +  return 0;
         3965  +}
         3966  +
         3967  +static void fts5PoslistFilterCallback(
         3968  +  Fts5Index *p, 
         3969  +  void *pContext, 
  3942   3970     const u8 *pChunk, int nChunk
  3943   3971   ){
         3972  +  PoslistCallbackCtx *pCtx = (PoslistCallbackCtx*)pContext;
  3944   3973     assert_nc( nChunk>=0 );
  3945   3974     if( nChunk>0 ){
  3946         -    fts5BufferAppendBlob(&p->rc, (Fts5Buffer*)pCtx, nChunk, pChunk);
         3975  +    /* Search through to find the first varint with value 1. This is the
         3976  +    ** start of the next columns hits. */
         3977  +    int i = 0;
         3978  +    int iStart = 0;
         3979  +
         3980  +    if( pCtx->eState==2 ){
         3981  +      int iCol;
         3982  +      fts5FastGetVarint32(pChunk, i, iCol);
         3983  +      if( fts5IndexColsetTest(pCtx->pColset, iCol) ){
         3984  +        pCtx->eState = 1;
         3985  +        fts5BufferSafeAppendVarint(pCtx->pBuf, 1);
         3986  +      }else{
         3987  +        pCtx->eState = 0;
         3988  +      }
         3989  +    }
         3990  +
         3991  +    do {
         3992  +      while( i<nChunk && pChunk[i]!=0x01 ){
         3993  +        while( pChunk[i] & 0x80 ) i++;
         3994  +        i++;
         3995  +      }
         3996  +      if( pCtx->eState ){
         3997  +        fts5BufferSafeAppendBlob(pCtx->pBuf, &pChunk[iStart], i-iStart);
         3998  +      }
         3999  +      if( i<nChunk ){
         4000  +        int iCol;
         4001  +        iStart = i;
         4002  +        i++;
         4003  +        if( i>=nChunk ){
         4004  +          pCtx->eState = 2;
         4005  +        }else{
         4006  +          fts5FastGetVarint32(pChunk, i, iCol);
         4007  +          pCtx->eState = fts5IndexColsetTest(pCtx->pColset, iCol);
         4008  +          if( pCtx->eState ){
         4009  +            fts5BufferSafeAppendBlob(pCtx->pBuf, &pChunk[iStart], i-iStart);
         4010  +            iStart = i;
         4011  +          }
         4012  +        }
         4013  +      }
         4014  +    }while( i<nChunk );
  3947   4015     }
  3948   4016   }
  3949   4017   
  3950   4018   /*
  3951   4019   ** Iterator pIter currently points to a valid entry (not EOF). This
  3952   4020   ** function appends the position list data for the current entry to
  3953   4021   ** buffer pBuf. It does not make a copy of the position-list size
  3954   4022   ** field.
  3955   4023   */
  3956   4024   static void fts5SegiterPoslist(
  3957   4025     Fts5Index *p,
  3958   4026     Fts5SegIter *pSeg,
         4027  +  Fts5Colset *pColset,
  3959   4028     Fts5Buffer *pBuf
  3960   4029   ){
  3961         -  fts5ChunkIterate(p, pSeg, (void*)pBuf, fts5PoslistCallback);
         4030  +  if( 0==fts5BufferGrow(&p->rc, pBuf, pSeg->nPos) ){
         4031  +    if( pColset==0 ){
         4032  +      fts5ChunkIterate(p, pSeg, (void*)pBuf, fts5PoslistCallback);
         4033  +    }else{
         4034  +      PoslistCallbackCtx sCtx;
         4035  +      sCtx.pBuf = pBuf;
         4036  +      sCtx.pColset = pColset;
         4037  +      sCtx.eState = pColset ? fts5IndexColsetTest(pColset, 0) : 1;
         4038  +      assert( sCtx.eState==0 || sCtx.eState==1 );
         4039  +      fts5ChunkIterate(p, pSeg, (void*)&sCtx, fts5PoslistFilterCallback);
         4040  +    }
         4041  +  }
  3962   4042   }
         4043  +
         4044  +/*
         4045  +** IN/OUT parameter (*pa) points to a position list n bytes in size. If
         4046  +** the position list contains entries for column iCol, then (*pa) is set
         4047  +** to point to the sub-position-list for that column and the number of
         4048  +** bytes in it returned. Or, if the argument position list does not
         4049  +** contain any entries for column iCol, return 0.
         4050  +*/
         4051  +static int fts5IndexExtractCol(
         4052  +  const u8 **pa,                  /* IN/OUT: Pointer to poslist */
         4053  +  int n,                          /* IN: Size of poslist in bytes */
         4054  +  int iCol                        /* Column to extract from poslist */
         4055  +){
         4056  +  int iCurrent = 0;               /* Anything before the first 0x01 is col 0 */
         4057  +  const u8 *p = *pa;
         4058  +  const u8 *pEnd = &p[n];         /* One byte past end of position list */
         4059  +  u8 prev = 0;
         4060  +
         4061  +  while( iCol!=iCurrent ){
         4062  +    /* Advance pointer p until it points to pEnd or an 0x01 byte that is
         4063  +    ** not part of a varint */
         4064  +    while( (prev & 0x80) || *p!=0x01 ){
         4065  +      prev = *p++;
         4066  +      if( p==pEnd ) return 0;
         4067  +    }
         4068  +    *pa = p++;
         4069  +    p += fts5GetVarint32(p, iCurrent);
         4070  +  }
         4071  +
         4072  +  /* Advance pointer p until it points to pEnd or an 0x01 byte that is
         4073  +  ** not part of a varint */
         4074  +  assert( (prev & 0x80)==0 );
         4075  +  while( p<pEnd && ((prev & 0x80) || *p!=0x01) ){
         4076  +    prev = *p++;
         4077  +  }
         4078  +  return p - (*pa);
         4079  +}
         4080  +
  3963   4081   
  3964   4082   /*
  3965   4083   ** Iterator pMulti currently points to a valid entry (not EOF). This
  3966         -** function appends a copy of the position-list of the entry pMulti 
  3967         -** currently points to to buffer pBuf.
         4084  +** function appends the following to buffer pBuf:
  3968   4085   **
  3969         -** If an error occurs, an error code is left in p->rc. It is assumed
  3970         -** no error has already occurred when this function is called.
         4086  +**   * The varint iDelta, and
         4087  +**   * the position list that currently points to, including the size field.
         4088  +**
         4089  +** If argument pColset is NULL, then the position list is filtered according
         4090  +** to pColset before being appended to the buffer. If this means there are
         4091  +** no entries in the position list, nothing is appended to the buffer (not
         4092  +** even iDelta).
         4093  +**
         4094  +** If an error occurs, an error code is left in p->rc. 
  3971   4095   */
  3972         -static void fts5MultiIterPoslist(
         4096  +static int fts5AppendPoslist(
  3973   4097     Fts5Index *p,
         4098  +  i64 iDelta,
  3974   4099     Fts5IndexIter *pMulti,
  3975         -  int bSz,                        /* Append a size field before the data */
         4100  +  Fts5Colset *pColset,
  3976   4101     Fts5Buffer *pBuf
  3977   4102   ){
  3978   4103     if( p->rc==SQLITE_OK ){
  3979   4104       Fts5SegIter *pSeg = &pMulti->aSeg[ pMulti->aFirst[1].iFirst ];
  3980   4105       assert( fts5MultiIterEof(p, pMulti)==0 );
         4106  +    assert( pSeg->nPos>0 );
         4107  +    if( 0==fts5BufferGrow(&p->rc, pBuf, pSeg->nPos+9+9) ){
         4108  +      int iSv1;
         4109  +      int iSv2;
         4110  +      int iData;
  3981   4111   
  3982         -    if( bSz ){
         4112  +      /* Append iDelta */
         4113  +      iSv1 = pBuf->n;
         4114  +      fts5BufferSafeAppendVarint(pBuf, iDelta);
         4115  +
  3983   4116         /* WRITEPOSLISTSIZE */
  3984         -      fts5BufferAppendVarint(&p->rc, pBuf, pSeg->nPos*2);
         4117  +      iSv2 = pBuf->n;
         4118  +      fts5BufferSafeAppendVarint(pBuf, pSeg->nPos*2);
         4119  +      iData = pBuf->n;
         4120  +
         4121  +      if( pSeg->iLeafOffset+pSeg->nPos<=pSeg->pLeaf->szLeaf 
         4122  +       && (pColset==0 || pColset->nCol==1)
         4123  +      ){
         4124  +        const u8 *pPos = &pSeg->pLeaf->p[pSeg->iLeafOffset];
         4125  +        int nPos;
         4126  +        if( pColset ){
         4127  +          nPos = fts5IndexExtractCol(&pPos, pSeg->nPos, pColset->aiCol[0]);
         4128  +        }else{
         4129  +          nPos = pSeg->nPos;
         4130  +        }
         4131  +        fts5BufferSafeAppendBlob(pBuf, pPos, nPos);
         4132  +      }else{
         4133  +        fts5SegiterPoslist(p, pSeg, pColset, pBuf);
         4134  +      }
         4135  +
         4136  +      if( pColset ){
         4137  +        int nActual = pBuf->n - iData;
         4138  +        if( nActual!=pSeg->nPos ){
         4139  +          if( nActual==0 ){
         4140  +            pBuf->n = iSv1;
         4141  +            return 1;
         4142  +          }else{
         4143  +            int nReq = sqlite3Fts5GetVarintLen((u32)(nActual*2));
         4144  +            while( iSv2<(iData-nReq) ){ pBuf->p[iSv2++] = 0x80; }
         4145  +            sqlite3Fts5PutVarint(&pBuf->p[iSv2], nActual*2);
         4146  +          }
         4147  +        }
         4148  +      }
  3985   4149       }
  3986         -    fts5SegiterPoslist(p, pSeg, pBuf);
  3987   4150     }
         4151  +
         4152  +  return 0;
  3988   4153   }
  3989   4154   
  3990   4155   static void fts5DoclistIterNext(Fts5DoclistIter *pIter){
  3991         -  if( pIter->i<pIter->n ){
  3992         -    int bDummy;
  3993         -    if( pIter->i ){
  3994         -      i64 iDelta;
  3995         -      pIter->i += fts5GetVarint(&pIter->a[pIter->i], (u64*)&iDelta);
  3996         -      pIter->iRowid += iDelta;
         4156  +  u8 *p = pIter->aPoslist + pIter->nSize + pIter->nPoslist;
         4157  +
         4158  +  assert( pIter->aPoslist );
         4159  +  if( p>=pIter->aEof ){
         4160  +    pIter->aPoslist = 0;
         4161  +  }else{
         4162  +    i64 iDelta;
         4163  +
         4164  +    p += fts5GetVarint(p, (u64*)&iDelta);
         4165  +    pIter->iRowid += iDelta;
         4166  +
         4167  +    /* Read position list size */
         4168  +    if( p[0] & 0x80 ){
         4169  +      int nPos;
         4170  +      pIter->nSize = fts5GetVarint32(p, nPos);
         4171  +      pIter->nPoslist = (nPos>>1);
  3997   4172       }else{
  3998         -      pIter->i += fts5GetVarint(&pIter->a[pIter->i], (u64*)&pIter->iRowid);
         4173  +      pIter->nPoslist = ((int)(p[0])) >> 1;
         4174  +      pIter->nSize = 1;
  3999   4175       }
  4000         -    pIter->i += fts5GetPoslistSize(
  4001         -        &pIter->a[pIter->i], &pIter->nPoslist, &bDummy
  4002         -    );
  4003         -    pIter->aPoslist = &pIter->a[pIter->i];
  4004         -    pIter->i += pIter->nPoslist;
  4005         -  }else{
  4006         -    pIter->aPoslist = 0;
         4176  +
         4177  +    pIter->aPoslist = p;
  4007   4178     }
  4008   4179   }
  4009   4180   
  4010   4181   static void fts5DoclistIterInit(
  4011   4182     Fts5Buffer *pBuf, 
  4012   4183     Fts5DoclistIter *pIter
  4013   4184   ){
  4014   4185     memset(pIter, 0, sizeof(*pIter));
  4015         -  pIter->a = pBuf->p;
  4016         -  pIter->n = pBuf->n;
         4186  +  pIter->aPoslist = pBuf->p;
         4187  +  pIter->aEof = &pBuf->p[pBuf->n];
  4017   4188     fts5DoclistIterNext(pIter);
  4018   4189   }
  4019   4190   
         4191  +#if 0
  4020   4192   /*
  4021   4193   ** Append a doclist to buffer pBuf.
         4194  +**
         4195  +** This function assumes that space within the buffer has already been
         4196  +** allocated.
  4022   4197   */
  4023   4198   static void fts5MergeAppendDocid(
  4024         -  int *pRc,                       /* IN/OUT: Error code */
  4025   4199     Fts5Buffer *pBuf,               /* Buffer to write to */
  4026   4200     i64 *piLastRowid,               /* IN/OUT: Previous rowid written (if any) */
  4027   4201     i64 iRowid                      /* Rowid to append */
  4028   4202   ){
  4029         -  if( pBuf->n==0 ){
  4030         -    fts5BufferAppendVarint(pRc, pBuf, iRowid);
  4031         -  }else{
  4032         -    fts5BufferAppendVarint(pRc, pBuf, iRowid - *piLastRowid);
  4033         -  }
         4203  +  assert( pBuf->n!=0 || (*piLastRowid)==0 );
         4204  +  fts5BufferSafeAppendVarint(pBuf, iRowid - *piLastRowid);
  4034   4205     *piLastRowid = iRowid;
  4035   4206   }
         4207  +#endif
         4208  +
         4209  +#define fts5MergeAppendDocid(pBuf, iLastRowid, iRowid) {       \
         4210  +  assert( (pBuf)->n!=0 || (iLastRowid)==0 );                   \
         4211  +  fts5BufferSafeAppendVarint((pBuf), (iRowid) - (iLastRowid)); \
         4212  +  (iLastRowid) = (iRowid);                                     \
         4213  +}
  4036   4214   
  4037   4215   /*
  4038   4216   ** Buffers p1 and p2 contain doclists. This function merges the content
  4039   4217   ** of the two doclists together and sets buffer p1 to the result before
  4040   4218   ** returning.
  4041   4219   **
  4042   4220   ** If an error occurs, an error code is left in p->rc. If an error has
................................................................................
  4052   4230       Fts5DoclistIter i1;
  4053   4231       Fts5DoclistIter i2;
  4054   4232       Fts5Buffer out;
  4055   4233       Fts5Buffer tmp;
  4056   4234       memset(&out, 0, sizeof(out));
  4057   4235       memset(&tmp, 0, sizeof(tmp));
  4058   4236   
         4237  +    sqlite3Fts5BufferGrow(&p->rc, &out, p1->n + p2->n);
  4059   4238       fts5DoclistIterInit(p1, &i1);
  4060   4239       fts5DoclistIterInit(p2, &i2);
  4061   4240       while( p->rc==SQLITE_OK && (i1.aPoslist!=0 || i2.aPoslist!=0) ){
  4062   4241         if( i2.aPoslist==0 || (i1.aPoslist && i1.iRowid<i2.iRowid) ){
  4063   4242           /* Copy entry from i1 */
  4064         -        fts5MergeAppendDocid(&p->rc, &out, &iLastRowid, i1.iRowid);
  4065         -        /* WRITEPOSLISTSIZE */
  4066         -        fts5BufferAppendVarint(&p->rc, &out, i1.nPoslist * 2);
  4067         -        fts5BufferAppendBlob(&p->rc, &out, i1.nPoslist, i1.aPoslist);
         4243  +        fts5MergeAppendDocid(&out, iLastRowid, i1.iRowid);
         4244  +        fts5BufferSafeAppendBlob(&out, i1.aPoslist, i1.nPoslist+i1.nSize);
  4068   4245           fts5DoclistIterNext(&i1);
  4069   4246         }
  4070   4247         else if( i1.aPoslist==0 || i2.iRowid!=i1.iRowid ){
  4071   4248           /* Copy entry from i2 */
  4072         -        fts5MergeAppendDocid(&p->rc, &out, &iLastRowid, i2.iRowid);
  4073         -        /* WRITEPOSLISTSIZE */
  4074         -        fts5BufferAppendVarint(&p->rc, &out, i2.nPoslist * 2);
  4075         -        fts5BufferAppendBlob(&p->rc, &out, i2.nPoslist, i2.aPoslist);
         4249  +        fts5MergeAppendDocid(&out, iLastRowid, i2.iRowid);
         4250  +        fts5BufferSafeAppendBlob(&out, i2.aPoslist, i2.nPoslist+i2.nSize);
  4076   4251           fts5DoclistIterNext(&i2);
  4077   4252         }
  4078   4253         else{
  4079         -        Fts5PoslistReader r1;
  4080         -        Fts5PoslistReader r2;
         4254  +        i64 iPos1 = 0;
         4255  +        i64 iPos2 = 0;
         4256  +        int iOff1 = 0;
         4257  +        int iOff2 = 0;
         4258  +        u8 *a1 = &i1.aPoslist[i1.nSize];
         4259  +        u8 *a2 = &i2.aPoslist[i2.nSize];
         4260  +
  4081   4261           Fts5PoslistWriter writer;
  4082         -
  4083   4262           memset(&writer, 0, sizeof(writer));
  4084   4263   
  4085   4264           /* Merge the two position lists. */ 
  4086         -        fts5MergeAppendDocid(&p->rc, &out, &iLastRowid, i2.iRowid);
         4265  +        fts5MergeAppendDocid(&out, iLastRowid, i2.iRowid);
  4087   4266           fts5BufferZero(&tmp);
  4088         -        sqlite3Fts5PoslistReaderInit(-1, i1.aPoslist, i1.nPoslist, &r1);
  4089         -        sqlite3Fts5PoslistReaderInit(-1, i2.aPoslist, i2.nPoslist, &r2);
  4090         -        while( p->rc==SQLITE_OK && (r1.bEof==0 || r2.bEof==0) ){
         4267  +
         4268  +        sqlite3Fts5PoslistNext64(a1, i1.nPoslist, &iOff1, &iPos1);
         4269  +        sqlite3Fts5PoslistNext64(a2, i2.nPoslist, &iOff2, &iPos2);
         4270  +
         4271  +        while( p->rc==SQLITE_OK && (iPos1>=0 || iPos2>=0) ){
  4091   4272             i64 iNew;
  4092         -          if( r2.bEof || (r1.bEof==0 && r1.iPos<r2.iPos) ){
  4093         -            iNew = r1.iPos;
  4094         -            sqlite3Fts5PoslistReaderNext(&r1);
         4273  +          if( iPos2<0 || (iPos1>=0 && iPos1<iPos2) ){
         4274  +            iNew = iPos1;
         4275  +            sqlite3Fts5PoslistNext64(a1, i1.nPoslist, &iOff1, &iPos1);
  4095   4276             }else{
  4096         -            iNew = r2.iPos;
  4097         -            sqlite3Fts5PoslistReaderNext(&r2);
  4098         -            if( r1.iPos==r2.iPos ) sqlite3Fts5PoslistReaderNext(&r1);
         4277  +            iNew = iPos2;
         4278  +            sqlite3Fts5PoslistNext64(a2, i2.nPoslist, &iOff2, &iPos2);
         4279  +            if( iPos1==iPos2 ){
         4280  +              sqlite3Fts5PoslistNext64(a1, i1.nPoslist, &iOff1,&iPos1);
         4281  +            }
  4099   4282             }
  4100   4283             p->rc = sqlite3Fts5PoslistWriterAppend(&tmp, &writer, iNew);
  4101   4284           }
  4102   4285   
  4103   4286           /* WRITEPOSLISTSIZE */
  4104         -        fts5BufferAppendVarint(&p->rc, &out, tmp.n * 2);
  4105         -        fts5BufferAppendBlob(&p->rc, &out, tmp.n, tmp.p);
         4287  +        fts5BufferSafeAppendVarint(&out, tmp.n * 2);
         4288  +        fts5BufferSafeAppendBlob(&out, tmp.p, tmp.n);
  4106   4289           fts5DoclistIterNext(&i1);
  4107   4290           fts5DoclistIterNext(&i2);
  4108   4291         }
  4109   4292       }
  4110   4293   
  4111   4294       fts5BufferSet(&p->rc, p1, out.n, out.p);
  4112   4295       fts5BufferFree(&tmp);
................................................................................
  4121   4304   }
  4122   4305   
  4123   4306   static void fts5SetupPrefixIter(
  4124   4307     Fts5Index *p,                   /* Index to read from */
  4125   4308     int bDesc,                      /* True for "ORDER BY rowid DESC" */
  4126   4309     const u8 *pToken,               /* Buffer containing prefix to match */
  4127   4310     int nToken,                     /* Size of buffer pToken in bytes */
  4128         -  Fts5IndexIter **ppIter       /* OUT: New iterator */
         4311  +  Fts5Colset *pColset,            /* Restrict matches to these columns */
         4312  +  Fts5IndexIter **ppIter          /* OUT: New iterator */
  4129   4313   ){
  4130   4314     Fts5Structure *pStruct;
  4131   4315     Fts5Buffer *aBuf;
  4132   4316     const int nBuf = 32;
  4133   4317   
  4134   4318     aBuf = (Fts5Buffer*)fts5IdxMalloc(p, sizeof(Fts5Buffer)*nBuf);
  4135   4319     pStruct = fts5StructureRead(p);
................................................................................
  4160   4344               fts5BufferSwap(&doclist, &aBuf[i]);
  4161   4345               fts5BufferZero(&doclist);
  4162   4346             }else{
  4163   4347               fts5MergePrefixLists(p, &doclist, &aBuf[i]);
  4164   4348               fts5BufferZero(&aBuf[i]);
  4165   4349             }
  4166   4350           }
         4351  +        iLastRowid = 0;
  4167   4352         }
  4168   4353   
  4169         -      fts5MergeAppendDocid(&p->rc, &doclist, &iLastRowid, iRowid);
  4170         -      fts5MultiIterPoslist(p, p1, 1, &doclist);
         4354  +      if( !fts5AppendPoslist(p, iRowid-iLastRowid, p1, pColset, &doclist) ){
         4355  +        iLastRowid = iRowid;
         4356  +      }
  4171   4357       }
  4172   4358   
  4173   4359       for(i=0; i<nBuf; i++){
  4174         -      fts5MergePrefixLists(p, &doclist, &aBuf[i]);
         4360  +      if( p->rc==SQLITE_OK ){
         4361  +        fts5MergePrefixLists(p, &doclist, &aBuf[i]);
         4362  +      }
  4175   4363         fts5BufferFree(&aBuf[i]);
  4176   4364       }
  4177   4365       fts5MultiIterFree(p, p1);
  4178   4366   
  4179   4367       pData = fts5IdxMalloc(p, sizeof(Fts5Data) + doclist.n);
  4180   4368       if( pData ){
  4181   4369         pData->p = (u8*)&pData[1];
................................................................................
  4191   4379   }
  4192   4380   
  4193   4381   
  4194   4382   /*
  4195   4383   ** Indicate that all subsequent calls to sqlite3Fts5IndexWrite() pertain
  4196   4384   ** to the document with rowid iRowid.
  4197   4385   */
  4198         -int sqlite3Fts5IndexBeginWrite(Fts5Index *p, i64 iRowid){
         4386  +int sqlite3Fts5IndexBeginWrite(Fts5Index *p, int bDelete, i64 iRowid){
  4199   4387     assert( p->rc==SQLITE_OK );
  4200   4388   
  4201   4389     /* Allocate the hash table if it has not already been allocated */
  4202   4390     if( p->pHash==0 ){
  4203   4391       p->rc = sqlite3Fts5HashNew(&p->pHash, &p->nPendingData);
  4204   4392     }
  4205   4393   
  4206   4394     /* Flush the hash table to disk if required */
  4207         -  if( iRowid<=p->iWriteRowid || (p->nPendingData > p->nMaxPendingData) ){
         4395  +  if( iRowid<p->iWriteRowid 
         4396  +   || (iRowid==p->iWriteRowid && p->bDelete==0)
         4397  +   || (p->nPendingData > p->nMaxPendingData) 
         4398  +  ){
  4208   4399       fts5IndexFlush(p);
  4209   4400     }
         4401  +
  4210   4402     p->iWriteRowid = iRowid;
         4403  +  p->bDelete = bDelete;
  4211   4404     return fts5IndexReturn(p);
  4212   4405   }
  4213   4406   
  4214   4407   /*
  4215   4408   ** Commit data to disk.
  4216   4409   */
  4217   4410   int sqlite3Fts5IndexSync(Fts5Index *p, int bCommit){
................................................................................
  4302   4495       assert( p->pReader==0 );
  4303   4496       sqlite3_finalize(p->pWriter);
  4304   4497       sqlite3_finalize(p->pDeleter);
  4305   4498       sqlite3_finalize(p->pIdxWriter);
  4306   4499       sqlite3_finalize(p->pIdxDeleter);
  4307   4500       sqlite3_finalize(p->pIdxSelect);
  4308   4501       sqlite3Fts5HashFree(p->pHash);
  4309         -    sqlite3Fts5BufferFree(&p->scratch);
  4310   4502       sqlite3_free(p->zDataTbl);
  4311   4503       sqlite3_free(p);
  4312   4504     }
  4313   4505     return rc;
  4314   4506   }
  4315   4507   
  4316   4508   /*
................................................................................
  4363   4555     const char *pToken, int nToken  /* Token to add or remove to or from index */
  4364   4556   ){
  4365   4557     int i;                          /* Used to iterate through indexes */
  4366   4558     int rc = SQLITE_OK;             /* Return code */
  4367   4559     Fts5Config *pConfig = p->pConfig;
  4368   4560   
  4369   4561     assert( p->rc==SQLITE_OK );
         4562  +  assert( (iCol<0)==p->bDelete );
  4370   4563   
  4371   4564     /* Add the entry to the main terms index. */
  4372   4565     rc = sqlite3Fts5HashWrite(
  4373   4566         p->pHash, p->iWriteRowid, iCol, iPos, FTS5_MAIN_PREFIX, pToken, nToken
  4374   4567     );
  4375   4568   
  4376   4569     for(i=0; i<pConfig->nPrefix && rc==SQLITE_OK; i++){
................................................................................
  4389   4582   ** Open a new iterator to iterate though all rowid that match the 
  4390   4583   ** specified token or token prefix.
  4391   4584   */
  4392   4585   int sqlite3Fts5IndexQuery(
  4393   4586     Fts5Index *p,                   /* FTS index to query */
  4394   4587     const char *pToken, int nToken, /* Token (or prefix) to query for */
  4395   4588     int flags,                      /* Mask of FTS5INDEX_QUERY_X flags */
         4589  +  Fts5Colset *pColset,            /* Match these columns only */
  4396   4590     Fts5IndexIter **ppIter          /* OUT: New iterator object */
  4397   4591   ){
  4398   4592     Fts5Config *pConfig = p->pConfig;
  4399   4593     Fts5IndexIter *pRet = 0;
  4400   4594     int iIdx = 0;
  4401   4595     Fts5Buffer buf = {0, 0, 0};
  4402   4596   
................................................................................
  4432   4626         if( pStruct ){
  4433   4627           fts5MultiIterNew(p, pStruct, 1, flags, buf.p, nToken+1, -1, 0, &pRet);
  4434   4628           fts5StructureRelease(pStruct);
  4435   4629         }
  4436   4630       }else{
  4437   4631         int bDesc = (flags & FTS5INDEX_QUERY_DESC)!=0;
  4438   4632         buf.p[0] = FTS5_MAIN_PREFIX;
  4439         -      fts5SetupPrefixIter(p, bDesc, buf.p, nToken+1, &pRet);
         4633  +      fts5SetupPrefixIter(p, bDesc, buf.p, nToken+1, pColset, &pRet);
  4440   4634       }
  4441   4635   
  4442   4636       if( p->rc ){
  4443   4637         sqlite3Fts5IterClose(pRet);
  4444   4638         pRet = 0;
  4445   4639         fts5CloseReader(p);
  4446   4640       }
................................................................................
  4511   4705   const char *sqlite3Fts5IterTerm(Fts5IndexIter *pIter, int *pn){
  4512   4706     int n;
  4513   4707     const char *z = (const char*)fts5MultiIterTerm(pIter, &n);
  4514   4708     *pn = n-1;
  4515   4709     return &z[1];
  4516   4710   }
  4517   4711   
         4712  +
         4713  +static int fts5IndexExtractColset (
         4714  +  Fts5Colset *pColset,            /* Colset to filter on */
         4715  +  const u8 *pPos, int nPos,       /* Position list */
         4716  +  Fts5Buffer *pBuf                /* Output buffer */
         4717  +){
         4718  +  int rc = SQLITE_OK;
         4719  +  int i;
         4720  +
         4721  +  fts5BufferZero(pBuf);
         4722  +  for(i=0; i<pColset->nCol; i++){
         4723  +    const u8 *pSub = pPos;
         4724  +    int nSub = fts5IndexExtractCol(&pSub, nPos, pColset->aiCol[i]);
         4725  +    if( nSub ){
         4726  +      fts5BufferAppendBlob(&rc, pBuf, nSub, pSub);
         4727  +    }
         4728  +  }
         4729  +  return rc;
         4730  +}
         4731  +
  4518   4732   
  4519   4733   /*
  4520   4734   ** Return a pointer to a buffer containing a copy of the position list for
  4521   4735   ** the current entry. Output variable *pn is set to the size of the buffer 
  4522   4736   ** in bytes before returning.
  4523   4737   **
  4524   4738   ** The returned position list does not include the "number of bytes" varint
  4525   4739   ** field that starts the position list on disk.
  4526   4740   */
  4527   4741   int sqlite3Fts5IterPoslist(
  4528   4742     Fts5IndexIter *pIter, 
         4743  +  Fts5Colset *pColset,            /* Column filter (or NULL) */
  4529   4744     const u8 **pp,                  /* OUT: Pointer to position-list data */
  4530   4745     int *pn,                        /* OUT: Size of position-list in bytes */
  4531   4746     i64 *piRowid                    /* OUT: Current rowid */
  4532   4747   ){
  4533   4748     Fts5SegIter *pSeg = &pIter->aSeg[ pIter->aFirst[1].iFirst ];
  4534   4749     assert( pIter->pIndex->rc==SQLITE_OK );
  4535   4750     *piRowid = pSeg->iRowid;
  4536         -  *pn = pSeg->nPos;
  4537         -  if( pSeg->iLeafOffset+pSeg->nPos <= pSeg->pLeaf->szLeaf ){
  4538         -    *pp = &pSeg->pLeaf->p[pSeg->iLeafOffset];
         4751  +  if( pSeg->iLeafOffset+pSeg->nPos<=pSeg->pLeaf->szLeaf ){
         4752  +    u8 *pPos = &pSeg->pLeaf->p[pSeg->iLeafOffset];
         4753  +    if( pColset==0 || pIter->bFiltered ){
         4754  +      *pn = pSeg->nPos;
         4755  +      *pp = pPos;
         4756  +    }else if( pColset->nCol==1 ){
         4757  +      *pp = pPos;
         4758  +      *pn = fts5IndexExtractCol(pp, pSeg->nPos, pColset->aiCol[0]);
         4759  +    }else{
         4760  +      fts5BufferZero(&pIter->poslist);
         4761  +      fts5IndexExtractColset(pColset, pPos, pSeg->nPos, &pIter->poslist);
         4762  +      *pp = pIter->poslist.p;
         4763  +      *pn = pIter->poslist.n;
         4764  +    }
  4539   4765     }else{
  4540   4766       fts5BufferZero(&pIter->poslist);
  4541         -    fts5SegiterPoslist(pIter->pIndex, pSeg, &pIter->poslist);
         4767  +    fts5SegiterPoslist(pIter->pIndex, pSeg, pColset, &pIter->poslist);
  4542   4768       *pp = pIter->poslist.p;
         4769  +    *pn = pIter->poslist.n;
  4543   4770     }
  4544   4771     return fts5IndexReturn(pIter->pIndex);
  4545   4772   }
  4546   4773   
  4547   4774   /*
  4548   4775   ** This function is similar to sqlite3Fts5IterPoslist(), except that it
  4549   4776   ** copies the position list into the buffer supplied as the second 
  4550   4777   ** argument.
  4551   4778   */
  4552   4779   int sqlite3Fts5IterPoslistBuffer(Fts5IndexIter *pIter, Fts5Buffer *pBuf){
  4553   4780     Fts5Index *p = pIter->pIndex;
  4554         -
         4781  +  Fts5SegIter *pSeg = &pIter->aSeg[ pIter->aFirst[1].iFirst ];
  4555   4782     assert( p->rc==SQLITE_OK );
  4556   4783     fts5BufferZero(pBuf);
  4557         -  fts5MultiIterPoslist(p, pIter, 0, pBuf);
         4784  +  fts5SegiterPoslist(p, pSeg, 0, pBuf);
  4558   4785     return fts5IndexReturn(p);
  4559   4786   }
  4560   4787   
  4561   4788   /*
  4562   4789   ** Close an iterator opened by an earlier call to sqlite3Fts5IndexQuery().
  4563   4790   */
  4564   4791   void sqlite3Fts5IterClose(Fts5IndexIter *pIter){
................................................................................
  4725   4952     const char *z,                  /* Index key to query for */
  4726   4953     int n,                          /* Size of index key in bytes */
  4727   4954     int flags,                      /* Flags for Fts5IndexQuery */
  4728   4955     u64 *pCksum                     /* IN/OUT: Checksum value */
  4729   4956   ){
  4730   4957     u64 cksum = *pCksum;
  4731   4958     Fts5IndexIter *pIdxIter = 0;
  4732         -  int rc = sqlite3Fts5IndexQuery(p, z, n, flags, &pIdxIter);
         4959  +  int rc = sqlite3Fts5IndexQuery(p, z, n, flags, 0, &pIdxIter);
  4733   4960   
  4734   4961     while( rc==SQLITE_OK && 0==sqlite3Fts5IterEof(pIdxIter) ){
  4735   4962       i64 dummy;
  4736   4963       const u8 *pPos;
  4737   4964       int nPos;
  4738   4965       i64 rowid = sqlite3Fts5IterRowid(pIdxIter);
  4739         -    rc = sqlite3Fts5IterPoslist(pIdxIter, &pPos, &nPos, &dummy);
         4966  +    rc = sqlite3Fts5IterPoslist(pIdxIter, 0, &pPos, &nPos, &dummy);
  4740   4967       if( rc==SQLITE_OK ){
  4741   4968         Fts5PoslistReader sReader;
  4742         -      for(sqlite3Fts5PoslistReaderInit(-1, pPos, nPos, &sReader);
         4969  +      for(sqlite3Fts5PoslistReaderInit(pPos, nPos, &sReader);
  4743   4970             sReader.bEof==0;
  4744   4971             sqlite3Fts5PoslistReaderNext(&sReader)
  4745   4972         ){
  4746   4973           int iCol = FTS5_POS2COLUMN(sReader.iPos);
  4747   4974           int iOff = FTS5_POS2OFFSET(sReader.iPos);
  4748   4975           cksum ^= fts5IndexEntryCksum(rowid, iCol, iOff, iIdx, z, n);
  4749   4976         }
................................................................................
  5099   5326       i64 iRowid = fts5MultiIterRowid(pIter);
  5100   5327       char *z = (char*)fts5MultiIterTerm(pIter, &n);
  5101   5328   
  5102   5329       /* If this is a new term, query for it. Update cksum3 with the results. */
  5103   5330       fts5TestTerm(p, &term, z, n, cksum2, &cksum3);
  5104   5331   
  5105   5332       poslist.n = 0;
  5106         -    fts5MultiIterPoslist(p, pIter, 0, &poslist);
         5333  +    fts5SegiterPoslist(p, &pIter->aSeg[pIter->aFirst[1].iFirst] , 0, &poslist);
  5107   5334       while( 0==sqlite3Fts5PoslistNext64(poslist.p, poslist.n, &iOff, &iPos) ){
  5108   5335         int iCol = FTS5_POS2COLUMN(iPos);
  5109   5336         int iTokOff = FTS5_POS2OFFSET(iPos);
  5110   5337         cksum2 ^= fts5IndexEntryCksum(iRowid, iCol, iTokOff, -1, z, n);
  5111   5338       }
  5112   5339     }
  5113   5340     fts5TestTerm(p, &term, 0, 0, cksum2, &cksum3);
................................................................................
  5238   5465       *pRc = rc;
  5239   5466       return;
  5240   5467     }
  5241   5468   
  5242   5469     fts5DebugStructure(pRc, pBuf, p);
  5243   5470     fts5StructureRelease(p);
  5244   5471   }
         5472  +
         5473  +/*
         5474  +** This is part of the fts5_decode() debugging aid.
         5475  +**
         5476  +** Arguments pBlob/nBlob contain an "averages" record. This function 
         5477  +** appends a human-readable representation of record to the buffer passed 
         5478  +** as the second argument. 
         5479  +*/
         5480  +static void fts5DecodeAverages(
         5481  +  int *pRc,                       /* IN/OUT: error code */
         5482  +  Fts5Buffer *pBuf,
         5483  +  const u8 *pBlob, int nBlob
         5484  +){
         5485  +  int i = 0;
         5486  +  const char *zSpace = "";
         5487  +
         5488  +  while( i<nBlob ){
         5489  +    u64 iVal;
         5490  +    i += sqlite3Fts5GetVarint(&pBlob[i], &iVal);
         5491  +    sqlite3Fts5BufferAppendPrintf(pRc, pBuf, "%s%d", zSpace, (int)iVal);
         5492  +    zSpace = " ";
         5493  +  }
         5494  +}
  5245   5495   
  5246   5496   /*
  5247   5497   ** Buffer (a/n) is assumed to contain a list of serialized varints. Read
  5248   5498   ** each varint and append its string representation to buffer pBuf. Return
  5249   5499   ** after either the input buffer is exhausted or a 0 value is read.
  5250   5500   **
  5251   5501   ** The return value is the number of bytes read from the input buffer.
................................................................................
  5340   5590       for(fts5DlidxLvlNext(&lvl); lvl.bEof==0; fts5DlidxLvlNext(&lvl)){
  5341   5591         sqlite3Fts5BufferAppendPrintf(&rc, &s, 
  5342   5592             " %d(%lld)", lvl.iLeafPgno, lvl.iRowid
  5343   5593         );
  5344   5594       }
  5345   5595     }else if( iSegid==0 ){
  5346   5596       if( iRowid==FTS5_AVERAGES_ROWID ){
  5347         -      /* todo */
         5597  +      fts5DecodeAverages(&rc, &s, a, n);
  5348   5598       }else{
  5349   5599         fts5DecodeStructure(&rc, &s, a, n);
  5350   5600       }
  5351   5601     }else{
  5352   5602       Fts5Buffer term;              /* Current term read from page */
  5353   5603       int szLeaf;                   /* Offset of pgidx in a[] */
  5354   5604       int iPgidxOff;
................................................................................
  5357   5607       int iRowidOff = 0;
  5358   5608       int iOff;
  5359   5609       int nDoclist;
  5360   5610   
  5361   5611       memset(&term, 0, sizeof(Fts5Buffer));
  5362   5612   
  5363   5613       if( n<4 ){
  5364         -      sqlite3Fts5BufferSet(&rc, &s, 8, (const u8*)"corrupt");
         5614  +      sqlite3Fts5BufferSet(&rc, &s, 7, (const u8*)"corrupt");
  5365   5615         goto decode_out;
  5366   5616       }else{
  5367   5617         iRowidOff = fts5GetU16(&a[0]);
  5368   5618         iPgidxOff = szLeaf = fts5GetU16(&a[2]);
  5369   5619         if( iPgidxOff<n ){
  5370   5620           fts5GetVarint32(&a[iPgidxOff], iTermOff);
  5371   5621         }

Changes to ext/fts5/fts5_main.c.

   435    435   */
   436    436   #define FTS5_PLAN_MATCH          1       /* (<tbl> MATCH ?) */
   437    437   #define FTS5_PLAN_SOURCE         2       /* A source cursor for SORTED_MATCH */
   438    438   #define FTS5_PLAN_SPECIAL        3       /* An internal query */
   439    439   #define FTS5_PLAN_SORTED_MATCH   4       /* (<tbl> MATCH ? ORDER BY rank) */
   440    440   #define FTS5_PLAN_SCAN           5       /* No usable constraint */
   441    441   #define FTS5_PLAN_ROWID          6       /* (rowid = ?) */
          442  +
          443  +/*
          444  +** Set the SQLITE_INDEX_SCAN_UNIQUE flag in pIdxInfo->flags. Unless this
          445  +** extension is currently being used by a version of SQLite too old to
          446  +** support index-info flags. In that case this function is a no-op.
          447  +*/
          448  +static void fts5SetUniqueFlag(sqlite3_index_info *pIdxInfo){
          449  +#if SQLITE_VERSION_NUMBER>=3008012
          450  +  if( sqlite3_libversion_number()>=3008012 ){
          451  +    pIdxInfo->idxFlags |= SQLITE_INDEX_SCAN_UNIQUE;
          452  +  }
          453  +#endif
          454  +}
   442    455   
   443    456   /*
   444    457   ** Implementation of the xBestIndex method for FTS5 tables. Within the 
   445    458   ** WHERE constraint, it searches for the following:
   446    459   **
   447    460   **   1. A MATCH constraint against the special column.
   448    461   **   2. A MATCH constraint against the "rank" column.
................................................................................
   488    501     struct Constraint {
   489    502       int op;                       /* Mask against sqlite3_index_constraint.op */
   490    503       int fts5op;                   /* FTS5 mask for idxFlags */
   491    504       int iCol;                     /* 0==rowid, 1==tbl, 2==rank */
   492    505       int omit;                     /* True to omit this if found */
   493    506       int iConsIndex;               /* Index in pInfo->aConstraint[] */
   494    507     } aConstraint[] = {
   495         -    {SQLITE_INDEX_CONSTRAINT_MATCH, FTS5_BI_MATCH,    1, 1, -1},
   496         -    {SQLITE_INDEX_CONSTRAINT_MATCH, FTS5_BI_RANK,     2, 1, -1},
          508  +    {SQLITE_INDEX_CONSTRAINT_MATCH|SQLITE_INDEX_CONSTRAINT_EQ, 
          509  +                                    FTS5_BI_MATCH,    1, 1, -1},
          510  +    {SQLITE_INDEX_CONSTRAINT_MATCH|SQLITE_INDEX_CONSTRAINT_EQ, 
          511  +                                    FTS5_BI_RANK,     2, 1, -1},
   497    512       {SQLITE_INDEX_CONSTRAINT_EQ,    FTS5_BI_ROWID_EQ, 0, 0, -1},
   498    513       {SQLITE_INDEX_CONSTRAINT_LT|SQLITE_INDEX_CONSTRAINT_LE, 
   499    514                                       FTS5_BI_ROWID_LE, 0, 0, -1},
   500    515       {SQLITE_INDEX_CONSTRAINT_GT|SQLITE_INDEX_CONSTRAINT_GE, 
   501    516                                       FTS5_BI_ROWID_GE, 0, 0, -1},
   502    517     };
   503    518   
................................................................................
   542    557       }
   543    558     }
   544    559   
   545    560     /* Calculate the estimated cost based on the flags set in idxFlags. */
   546    561     bHasMatch = BitFlagTest(idxFlags, FTS5_BI_MATCH);
   547    562     if( BitFlagTest(idxFlags, FTS5_BI_ROWID_EQ) ){
   548    563       pInfo->estimatedCost = bHasMatch ? 100.0 : 10.0;
          564  +    if( bHasMatch==0 ) fts5SetUniqueFlag(pInfo);
   549    565     }else if( BitFlagAllTest(idxFlags, FTS5_BI_ROWID_LE|FTS5_BI_ROWID_GE) ){
   550    566       pInfo->estimatedCost = bHasMatch ? 500.0 : 250000.0;
   551    567     }else if( BitFlagTest(idxFlags, FTS5_BI_ROWID_LE|FTS5_BI_ROWID_GE) ){
   552    568       pInfo->estimatedCost = bHasMatch ? 750.0 : 750000.0;
   553    569     }else{
   554    570       pInfo->estimatedCost = bHasMatch ? 1000.0 : 1000000.0;
   555    571     }
................................................................................
  1280   1296   **
  1281   1297   ** The commands implemented by this function are documented in the "Special
  1282   1298   ** INSERT Directives" section of the documentation. It should be updated if
  1283   1299   ** more commands are added to this function.
  1284   1300   */
  1285   1301   static int fts5SpecialInsert(
  1286   1302     Fts5Table *pTab,                /* Fts5 table object */
  1287         -  sqlite3_value *pCmd,            /* Value inserted into special column */
         1303  +  const char *zCmd,               /* Text inserted into table-name column */
  1288   1304     sqlite3_value *pVal             /* Value inserted into rank column */
  1289   1305   ){
  1290   1306     Fts5Config *pConfig = pTab->pConfig;
  1291         -  const char *z = (const char*)sqlite3_value_text(pCmd);
  1292   1307     int rc = SQLITE_OK;
  1293   1308     int bError = 0;
  1294   1309   
  1295         -  if( 0==sqlite3_stricmp("delete-all", z) ){
         1310  +  if( 0==sqlite3_stricmp("delete-all", zCmd) ){
  1296   1311       if( pConfig->eContent==FTS5_CONTENT_NORMAL ){
  1297   1312         fts5SetVtabError(pTab, 
  1298   1313             "'delete-all' may only be used with a "
  1299   1314             "contentless or external content fts5 table"
  1300   1315         );
  1301   1316         rc = SQLITE_ERROR;
  1302   1317       }else{
  1303   1318         rc = sqlite3Fts5StorageDeleteAll(pTab->pStorage);
  1304   1319       }
  1305         -  }else if( 0==sqlite3_stricmp("rebuild", z) ){
         1320  +  }else if( 0==sqlite3_stricmp("rebuild", zCmd) ){
  1306   1321       if( pConfig->eContent==FTS5_CONTENT_NONE ){
  1307   1322         fts5SetVtabError(pTab, 
  1308   1323             "'rebuild' may not be used with a contentless fts5 table"
  1309   1324         );
  1310   1325         rc = SQLITE_ERROR;
  1311   1326       }else{
  1312   1327         rc = sqlite3Fts5StorageRebuild(pTab->pStorage);
  1313   1328       }
  1314         -  }else if( 0==sqlite3_stricmp("optimize", z) ){
         1329  +  }else if( 0==sqlite3_stricmp("optimize", zCmd) ){
  1315   1330       rc = sqlite3Fts5StorageOptimize(pTab->pStorage);
  1316         -  }else if( 0==sqlite3_stricmp("merge", z) ){
         1331  +  }else if( 0==sqlite3_stricmp("merge", zCmd) ){
  1317   1332       int nMerge = sqlite3_value_int(pVal);
  1318   1333       rc = sqlite3Fts5StorageMerge(pTab->pStorage, nMerge);
  1319         -  }else if( 0==sqlite3_stricmp("integrity-check", z) ){
         1334  +  }else if( 0==sqlite3_stricmp("integrity-check", zCmd) ){
  1320   1335       rc = sqlite3Fts5StorageIntegrity(pTab->pStorage);
  1321   1336   #ifdef SQLITE_DEBUG
  1322         -  }else if( 0==sqlite3_stricmp("prefix-index", z) ){
         1337  +  }else if( 0==sqlite3_stricmp("prefix-index", zCmd) ){
  1323   1338       pConfig->bPrefixIndex = sqlite3_value_int(pVal);
  1324   1339   #endif
  1325   1340     }else{
  1326   1341       rc = sqlite3Fts5IndexLoadConfig(pTab->pIndex);
  1327   1342       if( rc==SQLITE_OK ){
  1328         -      rc = sqlite3Fts5ConfigSetValue(pTab->pConfig, z, pVal, &bError);
         1343  +      rc = sqlite3Fts5ConfigSetValue(pTab->pConfig, zCmd, pVal, &bError);
  1329   1344       }
  1330   1345       if( rc==SQLITE_OK ){
  1331   1346         if( bError ){
  1332   1347           rc = SQLITE_ERROR;
  1333   1348         }else{
  1334         -        rc = sqlite3Fts5StorageConfigValue(pTab->pStorage, z, pVal, 0);
         1349  +        rc = sqlite3Fts5StorageConfigValue(pTab->pStorage, zCmd, pVal, 0);
  1335   1350         }
  1336   1351       }
  1337   1352     }
  1338   1353     return rc;
  1339   1354   }
  1340   1355   
  1341   1356   static int fts5SpecialDelete(
................................................................................
  1347   1362     int eType1 = sqlite3_value_type(apVal[1]);
  1348   1363     if( eType1==SQLITE_INTEGER ){
  1349   1364       sqlite3_int64 iDel = sqlite3_value_int64(apVal[1]);
  1350   1365       rc = sqlite3Fts5StorageSpecialDelete(pTab->pStorage, iDel, &apVal[2]);
  1351   1366     }
  1352   1367     return rc;
  1353   1368   }
         1369  +
         1370  +static void fts5StorageInsert(
         1371  +  int *pRc, 
         1372  +  Fts5Table *pTab, 
         1373  +  sqlite3_value **apVal, 
         1374  +  i64 *piRowid
         1375  +){
         1376  +  int rc = *pRc;
         1377  +  if( rc==SQLITE_OK ){
         1378  +    rc = sqlite3Fts5StorageContentInsert(pTab->pStorage, apVal, piRowid);
         1379  +  }
         1380  +  if( rc==SQLITE_OK ){
         1381  +    rc = sqlite3Fts5StorageIndexInsert(pTab->pStorage, apVal, *piRowid);
         1382  +  }
         1383  +  *pRc = rc;
         1384  +}
  1354   1385   
  1355   1386   /* 
  1356   1387   ** This function is the implementation of the xUpdate callback used by 
  1357   1388   ** FTS3 virtual tables. It is invoked by SQLite each time a row is to be
  1358   1389   ** inserted, updated or deleted.
         1390  +**
         1391  +** A delete specifies a single argument - the rowid of the row to remove.
         1392  +** 
         1393  +** Update and insert operations pass:
         1394  +**
         1395  +**   1. The "old" rowid, or NULL.
         1396  +**   2. The "new" rowid.
         1397  +**   3. Values for each of the nCol matchable columns.
         1398  +**   4. Values for the two hidden columns (<tablename> and "rank").
  1359   1399   */
  1360   1400   static int fts5UpdateMethod(
  1361   1401     sqlite3_vtab *pVtab,            /* Virtual table handle */
  1362   1402     int nArg,                       /* Size of argument array */
  1363   1403     sqlite3_value **apVal,          /* Array of arguments */
  1364   1404     sqlite_int64 *pRowid            /* OUT: The affected (or effected) rowid */
  1365   1405   ){
  1366   1406     Fts5Table *pTab = (Fts5Table*)pVtab;
  1367   1407     Fts5Config *pConfig = pTab->pConfig;
  1368   1408     int eType0;                     /* value_type() of apVal[0] */
  1369         -  int eConflict;                  /* ON CONFLICT for this DML */
  1370   1409     int rc = SQLITE_OK;             /* Return code */
  1371   1410   
  1372   1411     /* A transaction must be open when this is called. */
  1373   1412     assert( pTab->ts.eState==1 );
  1374   1413   
         1414  +  assert( pVtab->zErrMsg==0 );
         1415  +  assert( nArg==1 || nArg==(2+pConfig->nCol+2) );
         1416  +  assert( nArg==1 
         1417  +      || sqlite3_value_type(apVal[1])==SQLITE_INTEGER 
         1418  +      || sqlite3_value_type(apVal[1])==SQLITE_NULL 
         1419  +  );
  1375   1420     assert( pTab->pConfig->pzErrmsg==0 );
  1376   1421     pTab->pConfig->pzErrmsg = &pTab->base.zErrMsg;
  1377   1422   
  1378         -  /* A delete specifies a single argument - the rowid of the row to remove.
  1379         -  ** Update and insert operations pass:
  1380         -  **
  1381         -  **   1. The "old" rowid, or NULL.
  1382         -  **   2. The "new" rowid.
  1383         -  **   3. Values for each of the nCol matchable columns.
  1384         -  **   4. Values for the two hidden columns (<tablename> and "rank").
  1385         -  */
         1423  +  /* Put any active cursors into REQUIRE_SEEK state. */
         1424  +  fts5TripCursors(pTab);
  1386   1425   
  1387   1426     eType0 = sqlite3_value_type(apVal[0]);
  1388         -  eConflict = sqlite3_vtab_on_conflict(pConfig->db);
         1427  +  if( eType0==SQLITE_NULL 
         1428  +   && sqlite3_value_type(apVal[2+pConfig->nCol])!=SQLITE_NULL 
         1429  +  ){
         1430  +    /* A "special" INSERT op. These are handled separately. */
         1431  +    const char *z = (const char*)sqlite3_value_text(apVal[2+pConfig->nCol]);
         1432  +    if( pConfig->eContent!=FTS5_CONTENT_NORMAL 
         1433  +      && 0==sqlite3_stricmp("delete", z) 
         1434  +    ){
         1435  +      rc = fts5SpecialDelete(pTab, apVal, pRowid);
         1436  +    }else{
         1437  +      rc = fts5SpecialInsert(pTab, z, apVal[2 + pConfig->nCol + 1]);
         1438  +    }
         1439  +  }else{
         1440  +    /* A regular INSERT, UPDATE or DELETE statement. The trick here is that
         1441  +    ** any conflict on the rowid value must be detected before any 
         1442  +    ** modifications are made to the database file. There are 4 cases:
         1443  +    **
         1444  +    **   1) DELETE
         1445  +    **   2) UPDATE (rowid not modified)
         1446  +    **   3) UPDATE (rowid modified)
         1447  +    **   4) INSERT
         1448  +    **
         1449  +    ** Cases 3 and 4 may violate the rowid constraint.
         1450  +    */
         1451  +    int eConflict = sqlite3_vtab_on_conflict(pConfig->db);
  1389   1452   
  1390         -  assert( eType0==SQLITE_INTEGER || eType0==SQLITE_NULL );
  1391         -  assert( pVtab->zErrMsg==0 );
  1392         -  assert( (nArg==1 && eType0==SQLITE_INTEGER) || nArg==(2+pConfig->nCol+2) );
         1453  +    assert( eType0==SQLITE_INTEGER || eType0==SQLITE_NULL );
         1454  +    assert( nArg!=1 || eType0==SQLITE_INTEGER );
  1393   1455   
  1394         -  fts5TripCursors(pTab);
  1395         -  if( eType0==SQLITE_INTEGER ){
  1396         -    if( fts5IsContentless(pTab) ){
         1456  +    /* Filter out attempts to run UPDATE or DELETE on contentless tables.
         1457  +    ** This is not suported.  */
         1458  +    if( eType0==SQLITE_INTEGER && fts5IsContentless(pTab) ){
  1397   1459         pTab->base.zErrMsg = sqlite3_mprintf(
  1398   1460             "cannot %s contentless fts5 table: %s", 
  1399   1461             (nArg>1 ? "UPDATE" : "DELETE from"), pConfig->zName
  1400   1462         );
  1401   1463         rc = SQLITE_ERROR;
  1402         -    }else{
         1464  +    }
         1465  +
         1466  +    /* Case 1: DELETE */
         1467  +    else if( nArg==1 ){
  1403   1468         i64 iDel = sqlite3_value_int64(apVal[0]);  /* Rowid to delete */
  1404   1469         rc = sqlite3Fts5StorageDelete(pTab->pStorage, iDel);
  1405   1470       }
  1406         -  }else{
  1407         -    sqlite3_value *pCmd = apVal[2 + pConfig->nCol];
  1408         -    assert( nArg>1 );
  1409         -    if( SQLITE_NULL!=sqlite3_value_type(pCmd) ){
  1410         -      const char *z = (const char*)sqlite3_value_text(pCmd);
  1411         -      if( pConfig->eContent!=FTS5_CONTENT_NORMAL 
  1412         -       && 0==sqlite3_stricmp("delete", z) 
         1471  +
         1472  +    /* Case 2: INSERT */
         1473  +    else if( eType0!=SQLITE_INTEGER ){     
         1474  +      /* If this is a REPLACE, first remove the current entry (if any) */
         1475  +      if( eConflict==SQLITE_REPLACE 
         1476  +       && sqlite3_value_type(apVal[1])==SQLITE_INTEGER 
  1413   1477         ){
  1414         -        rc = fts5SpecialDelete(pTab, apVal, pRowid);
         1478  +        i64 iNew = sqlite3_value_int64(apVal[1]);  /* Rowid to delete */
         1479  +        rc = sqlite3Fts5StorageDelete(pTab->pStorage, iNew);
         1480  +      }
         1481  +      fts5StorageInsert(&rc, pTab, apVal, pRowid);
         1482  +    }
         1483  +
         1484  +    /* Case 2: UPDATE */
         1485  +    else{
         1486  +      i64 iOld = sqlite3_value_int64(apVal[0]);  /* Old rowid */
         1487  +      i64 iNew = sqlite3_value_int64(apVal[1]);  /* New rowid */
         1488  +      if( iOld!=iNew ){
         1489  +        if( eConflict==SQLITE_REPLACE ){
         1490  +          rc = sqlite3Fts5StorageDelete(pTab->pStorage, iOld);
         1491  +          if( rc==SQLITE_OK ){
         1492  +            rc = sqlite3Fts5StorageDelete(pTab->pStorage, iNew);
         1493  +          }
         1494  +          fts5StorageInsert(&rc, pTab, apVal, pRowid);
         1495  +        }else{
         1496  +          rc = sqlite3Fts5StorageContentInsert(pTab->pStorage, apVal, pRowid);
         1497  +          if( rc==SQLITE_OK ){
         1498  +            rc = sqlite3Fts5StorageDelete(pTab->pStorage, iOld);
         1499  +          }
         1500  +          if( rc==SQLITE_OK ){
         1501  +            rc = sqlite3Fts5StorageIndexInsert(pTab->pStorage, apVal, *pRowid);
         1502  +          }
         1503  +        }
  1415   1504         }else{
  1416         -        rc = fts5SpecialInsert(pTab, pCmd, apVal[2 + pConfig->nCol + 1]);
         1505  +        rc = sqlite3Fts5StorageDelete(pTab->pStorage, iOld);
         1506  +        fts5StorageInsert(&rc, pTab, apVal, pRowid);
  1417   1507         }
  1418         -      goto update_method_out;
  1419   1508       }
  1420   1509     }
  1421   1510   
  1422         -
  1423         -  if( rc==SQLITE_OK && nArg>1 ){
  1424         -    rc = sqlite3Fts5StorageInsert(pTab->pStorage, apVal, eConflict, pRowid);
  1425         -  }
  1426         -
  1427         - update_method_out:
  1428   1511     pTab->pConfig->pzErrmsg = 0;
  1429   1512     return rc;
  1430   1513   }
  1431   1514   
  1432   1515   /*
  1433   1516   ** Implementation of xSync() method. 
  1434   1517   */
................................................................................
  1556   1639       int nInst = 0;                /* Number instances seen so far */
  1557   1640       int i;
  1558   1641   
  1559   1642       /* Initialize all iterators */
  1560   1643       for(i=0; i<nIter; i++){
  1561   1644         const u8 *a;
  1562   1645         int n = fts5CsrPoslist(pCsr, i, &a);
  1563         -      sqlite3Fts5PoslistReaderInit(-1, a, n, &aIter[i]);
         1646  +      sqlite3Fts5PoslistReaderInit(a, n, &aIter[i]);
  1564   1647       }
  1565   1648   
  1566   1649       while( 1 ){
  1567   1650         int *aInst;
  1568   1651         int iBest = -1;
  1569   1652         for(i=0; i<nIter; i++){
  1570   1653           if( (aIter[i].bEof==0) 
................................................................................
  2128   2211     fts5_extension_function xFunc,  /* Aux. function implementation */
  2129   2212     void(*xDestroy)(void*)          /* Destructor for pUserData */
  2130   2213   ){
  2131   2214     Fts5Global *pGlobal = (Fts5Global*)pApi;
  2132   2215     int rc = sqlite3_overload_function(pGlobal->db, zName, -1);
  2133   2216     if( rc==SQLITE_OK ){
  2134   2217       Fts5Auxiliary *pAux;
         2218  +    int nName;                      /* Size of zName in bytes, including \0 */
  2135   2219       int nByte;                      /* Bytes of space to allocate */
  2136   2220   
  2137         -    nByte = sizeof(Fts5Auxiliary) + strlen(zName) + 1;
         2221  +    nName = (int)strlen(zName) + 1;
         2222  +    nByte = sizeof(Fts5Auxiliary) + nName;
  2138   2223       pAux = (Fts5Auxiliary*)sqlite3_malloc(nByte);
  2139   2224       if( pAux ){
  2140   2225         memset(pAux, 0, nByte);
  2141   2226         pAux->zFunc = (char*)&pAux[1];
  2142         -      strcpy(pAux->zFunc, zName);
         2227  +      memcpy(pAux->zFunc, zName, nName);
  2143   2228         pAux->pGlobal = pGlobal;
  2144   2229         pAux->pUserData = pUserData;
  2145   2230         pAux->xFunc = xFunc;
  2146   2231         pAux->xDestroy = xDestroy;
  2147   2232         pAux->pNext = pGlobal->pAux;
  2148   2233         pGlobal->pAux = pAux;
  2149   2234       }else{
................................................................................
  2163   2248     const char *zName,              /* Name of new function */
  2164   2249     void *pUserData,                /* User data for aux. function */
  2165   2250     fts5_tokenizer *pTokenizer,     /* Tokenizer implementation */
  2166   2251     void(*xDestroy)(void*)          /* Destructor for pUserData */
  2167   2252   ){
  2168   2253     Fts5Global *pGlobal = (Fts5Global*)pApi;
  2169   2254     Fts5TokenizerModule *pNew;
         2255  +  int nName;                      /* Size of zName and its \0 terminator */
  2170   2256     int nByte;                      /* Bytes of space to allocate */
  2171   2257     int rc = SQLITE_OK;
  2172   2258   
  2173         -  nByte = sizeof(Fts5TokenizerModule) + strlen(zName) + 1;
         2259  +  nName = (int)strlen(zName) + 1;
         2260  +  nByte = sizeof(Fts5TokenizerModule) + nName;
  2174   2261     pNew = (Fts5TokenizerModule*)sqlite3_malloc(nByte);
  2175   2262     if( pNew ){
  2176   2263       memset(pNew, 0, nByte);
  2177   2264       pNew->zName = (char*)&pNew[1];
  2178         -    strcpy(pNew->zName, zName);
         2265  +    memcpy(pNew->zName, zName, nName);
  2179   2266       pNew->pUserData = pUserData;
  2180   2267       pNew->x = *pTokenizer;
  2181   2268       pNew->xDestroy = xDestroy;
  2182   2269       pNew->pNext = pGlobal->pTok;
  2183   2270       pGlobal->pTok = pNew;
  2184   2271       if( pNew->pNext==0 ){
  2185   2272         pGlobal->pDfltTok = pNew;
................................................................................
  2306   2393     int nArg,                       /* Number of args */
  2307   2394     sqlite3_value **apVal           /* Function arguments */
  2308   2395   ){
  2309   2396     assert( nArg==0 );
  2310   2397     sqlite3_result_text(pCtx, "--FTS5-SOURCE-ID--", -1, SQLITE_TRANSIENT);
  2311   2398   }
  2312   2399   
  2313         -#ifdef _WIN32
  2314         -__declspec(dllexport)
  2315         -#endif
  2316         -int sqlite3_fts5_init(
  2317         -  sqlite3 *db,
  2318         -  char **pzErrMsg,
  2319         -  const sqlite3_api_routines *pApi
  2320         -){
         2400  +static int fts5Init(sqlite3 *db){
  2321   2401     static const sqlite3_module fts5Mod = {
  2322   2402       /* iVersion      */ 2,
  2323   2403       /* xCreate       */ fts5CreateMethod,
  2324   2404       /* xConnect      */ fts5ConnectMethod,
  2325   2405       /* xBestIndex    */ fts5BestIndexMethod,
  2326   2406       /* xDisconnect   */ fts5DisconnectMethod,
  2327   2407       /* xDestroy      */ fts5DestroyMethod,
................................................................................
  2343   2423       /* xRelease      */ fts5ReleaseMethod,
  2344   2424       /* xRollbackTo   */ fts5RollbackToMethod,
  2345   2425     };
  2346   2426   
  2347   2427     int rc;
  2348   2428     Fts5Global *pGlobal = 0;
  2349   2429   
  2350         -  SQLITE_EXTENSION_INIT2(pApi);
  2351         -
  2352   2430     pGlobal = (Fts5Global*)sqlite3_malloc(sizeof(Fts5Global));
  2353   2431     if( pGlobal==0 ){
  2354   2432       rc = SQLITE_NOMEM;
  2355   2433     }else{
  2356   2434       void *p = (void*)pGlobal;
  2357   2435       memset(pGlobal, 0, sizeof(Fts5Global));
  2358   2436       pGlobal->db = db;
................................................................................
  2376   2454             db, "fts5_source_id", 0, SQLITE_UTF8, p, fts5SourceIdFunc, 0, 0
  2377   2455         );
  2378   2456       }
  2379   2457     }
  2380   2458     return rc;
  2381   2459   }
  2382   2460   
         2461  +/*
         2462  +** The following functions are used to register the module with SQLite. If
         2463  +** this module is being built as part of the SQLite core (SQLITE_CORE is
         2464  +** defined), then sqlite3_open() will call sqlite3Fts5Init() directly.
         2465  +**
         2466  +** Or, if this module is being built as a loadable extension, 
         2467  +** sqlite3Fts5Init() is omitted and the two standard entry points
         2468  +** sqlite3_fts_init() and sqlite3_fts5_init() defined instead.
         2469  +*/
         2470  +#ifndef SQLITE_CORE
  2383   2471   #ifdef _WIN32
  2384   2472   __declspec(dllexport)
  2385   2473   #endif
  2386   2474   int sqlite3_fts_init(
  2387   2475     sqlite3 *db,
  2388   2476     char **pzErrMsg,
  2389   2477     const sqlite3_api_routines *pApi
  2390   2478   ){
  2391         -  return sqlite3_fts5_init(db, pzErrMsg, pApi);
         2479  +  SQLITE_EXTENSION_INIT2(pApi);
         2480  +  (void)pzErrMsg;  /* Unused parameter */
         2481  +  return fts5Init(db);
  2392   2482   }
  2393   2483   
  2394         -
         2484  +#ifdef _WIN32
         2485  +__declspec(dllexport)
         2486  +#endif
         2487  +int sqlite3_fts5_init(
         2488  +  sqlite3 *db,
         2489  +  char **pzErrMsg,
         2490  +  const sqlite3_api_routines *pApi
         2491  +){
         2492  +  SQLITE_EXTENSION_INIT2(pApi);
         2493  +  (void)pzErrMsg;  /* Unused parameter */
         2494  +  return fts5Init(db);
         2495  +}
         2496  +#else
         2497  +int sqlite3Fts5Init(sqlite3 *db){
         2498  +  return fts5Init(db);
         2499  +}
         2500  +#endif

Changes to ext/fts5/fts5_storage.c.

   388    388       int rc2;
   389    389       sqlite3_bind_int64(pSeek, 1, iDel);
   390    390       if( sqlite3_step(pSeek)==SQLITE_ROW ){
   391    391         int iCol;
   392    392         Fts5InsertCtx ctx;
   393    393         ctx.pStorage = p;
   394    394         ctx.iCol = -1;
   395         -      rc = sqlite3Fts5IndexBeginWrite(p->pIndex, iDel);
          395  +      rc = sqlite3Fts5IndexBeginWrite(p->pIndex, 1, iDel);
   396    396         for(iCol=1; rc==SQLITE_OK && iCol<=pConfig->nCol; iCol++){
   397    397           if( pConfig->abUnindexed[iCol-1] ) continue;
   398    398           ctx.szCol = 0;
   399    399           rc = sqlite3Fts5Tokenize(pConfig, 
   400    400               FTS5_TOKENIZE_DOCUMENT,
   401    401               (const char*)sqlite3_column_text(pSeek, iCol),
   402    402               sqlite3_column_bytes(pSeek, iCol),
................................................................................
   545    545     /* Delete the index records */
   546    546     if( rc==SQLITE_OK ){
   547    547       int iCol;
   548    548       Fts5InsertCtx ctx;
   549    549       ctx.pStorage = p;
   550    550       ctx.iCol = -1;
   551    551   
   552         -    rc = sqlite3Fts5IndexBeginWrite(p->pIndex, iDel);
          552  +    rc = sqlite3Fts5IndexBeginWrite(p->pIndex, 1, iDel);
   553    553       for(iCol=0; rc==SQLITE_OK && iCol<pConfig->nCol; iCol++){
   554    554         if( pConfig->abUnindexed[iCol] ) continue;
   555    555         ctx.szCol = 0;
   556    556         rc = sqlite3Fts5Tokenize(pConfig, 
   557    557           FTS5_TOKENIZE_DOCUMENT,
   558    558           (const char*)sqlite3_value_text(apVal[iCol]),
   559    559           sqlite3_value_bytes(apVal[iCol]),
................................................................................
   635    635       rc = fts5StorageGetStmt(p, FTS5_STMT_SCAN, &pScan, 0);
   636    636     }
   637    637   
   638    638     while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pScan) ){
   639    639       i64 iRowid = sqlite3_column_int64(pScan, 0);
   640    640   
   641    641       sqlite3Fts5BufferZero(&buf);
   642         -    rc = sqlite3Fts5IndexBeginWrite(p->pIndex, iRowid);
          642  +    rc = sqlite3Fts5IndexBeginWrite(p->pIndex, 0, iRowid);
   643    643       for(ctx.iCol=0; rc==SQLITE_OK && ctx.iCol<pConfig->nCol; ctx.iCol++){
   644    644         ctx.szCol = 0;
   645    645         if( pConfig->abUnindexed[ctx.iCol]==0 ){
   646    646           rc = sqlite3Fts5Tokenize(pConfig, 
   647    647               FTS5_TOKENIZE_DOCUMENT,
   648    648               (const char*)sqlite3_column_text(pScan, ctx.iCol+1),
   649    649               sqlite3_column_bytes(pScan, ctx.iCol+1),
................................................................................
   701    701         *piRowid = sqlite3_last_insert_rowid(p->pConfig->db);
   702    702       }
   703    703     }
   704    704     return rc;
   705    705   }
   706    706   
   707    707   /*
   708         -** Insert a new row into the FTS table.
          708  +** Insert a new row into the FTS content table.
          709  +*/
          710  +int sqlite3Fts5StorageContentInsert(
          711  +  Fts5Storage *p, 
          712  +  sqlite3_value **apVal, 
          713  +  i64 *piRowid
          714  +){
          715  +  Fts5Config *pConfig = p->pConfig;
          716  +  int rc = SQLITE_OK;
          717  +
          718  +  /* Insert the new row into the %_content table. */
          719  +  if( pConfig->eContent!=FTS5_CONTENT_NORMAL ){
          720  +    if( sqlite3_value_type(apVal[1])==SQLITE_INTEGER ){
          721  +      *piRowid = sqlite3_value_int64(apVal[1]);
          722  +    }else{
          723  +      rc = fts5StorageNewRowid(p, piRowid);
          724  +    }
          725  +  }else{
          726  +    sqlite3_stmt *pInsert = 0;    /* Statement to write %_content table */
          727  +    int i;                        /* Counter variable */
          728  +#if 0
          729  +    if( eConflict==SQLITE_REPLACE ){
          730  +      eStmt = FTS5_STMT_REPLACE_CONTENT;
          731  +      rc = fts5StorageDeleteFromIndex(p, sqlite3_value_int64(apVal[1]));
          732  +    }else{
          733  +      eStmt = FTS5_STMT_INSERT_CONTENT;
          734  +    }
          735  +#endif
          736  +    if( rc==SQLITE_OK ){
          737  +      rc = fts5StorageGetStmt(p, FTS5_STMT_INSERT_CONTENT, &pInsert, 0);
          738  +    }
          739  +    for(i=1; rc==SQLITE_OK && i<=pConfig->nCol+1; i++){
          740  +      rc = sqlite3_bind_value(pInsert, i, apVal[i]);
          741  +    }
          742  +    if( rc==SQLITE_OK ){
          743  +      sqlite3_step(pInsert);
          744  +      rc = sqlite3_reset(pInsert);
          745  +    }
          746  +    *piRowid = sqlite3_last_insert_rowid(pConfig->db);
          747  +  }
          748  +
          749  +  return rc;
          750  +}
          751  +
          752  +/*
          753  +** Insert new entries into the FTS index and %_docsize table.
   709    754   */
   710         -int sqlite3Fts5StorageInsert(
   711         -  Fts5Storage *p,                 /* Storage module to write to */
   712         -  sqlite3_value **apVal,          /* Array of values passed to xUpdate() */
   713         -  int eConflict,                  /* on conflict clause */
   714         -  i64 *piRowid                    /* OUT: rowid of new record */
          755  +int sqlite3Fts5StorageIndexInsert(
          756  +  Fts5Storage *p, 
          757  +  sqlite3_value **apVal, 
          758  +  i64 iRowid
   715    759   ){
   716    760     Fts5Config *pConfig = p->pConfig;
   717    761     int rc = SQLITE_OK;             /* Return code */
   718         -  sqlite3_stmt *pInsert = 0;      /* Statement used to write %_content table */
   719         -  int eStmt = 0;                  /* Type of statement used on %_content */
   720         -  int i;                          /* Counter variable */
   721    762     Fts5InsertCtx ctx;              /* Tokenization callback context object */
   722    763     Fts5Buffer buf;                 /* Buffer used to build up %_docsize blob */
   723    764   
   724    765     memset(&buf, 0, sizeof(Fts5Buffer));
          766  +  ctx.pStorage = p;
   725    767     rc = fts5StorageLoadTotals(p, 1);
   726    768   
   727         -  /* Insert the new row into the %_content table. */
   728    769     if( rc==SQLITE_OK ){
   729         -    if( pConfig->eContent!=FTS5_CONTENT_NORMAL ){
   730         -      if( sqlite3_value_type(apVal[1])==SQLITE_INTEGER ){
   731         -        *piRowid = sqlite3_value_int64(apVal[1]);
   732         -      }else{
   733         -        rc = fts5StorageNewRowid(p, piRowid);
   734         -      }
   735         -    }else{
   736         -      if( eConflict==SQLITE_REPLACE ){
   737         -        eStmt = FTS5_STMT_REPLACE_CONTENT;
   738         -        rc = fts5StorageDeleteFromIndex(p, sqlite3_value_int64(apVal[1]));
   739         -      }else{
   740         -        eStmt = FTS5_STMT_INSERT_CONTENT;
   741         -      }
   742         -      if( rc==SQLITE_OK ){
   743         -        rc = fts5StorageGetStmt(p, eStmt, &pInsert, 0);
   744         -      }
   745         -      for(i=1; rc==SQLITE_OK && i<=pConfig->nCol+1; i++){
   746         -        rc = sqlite3_bind_value(pInsert, i, apVal[i]);
   747         -      }
   748         -      if( rc==SQLITE_OK ){
   749         -        sqlite3_step(pInsert);
   750         -        rc = sqlite3_reset(pInsert);
   751         -      }
   752         -      *piRowid = sqlite3_last_insert_rowid(pConfig->db);
   753         -    }
   754         -  }
   755         -
   756         -  /* Add new entries to the FTS index */
   757         -  if( rc==SQLITE_OK ){
   758         -    rc = sqlite3Fts5IndexBeginWrite(p->pIndex, *piRowid);
   759         -    ctx.pStorage = p;
          770  +    rc = sqlite3Fts5IndexBeginWrite(p->pIndex, 0, iRowid);
   760    771     }
   761    772     for(ctx.iCol=0; rc==SQLITE_OK && ctx.iCol<pConfig->nCol; ctx.iCol++){
   762    773       ctx.szCol = 0;
   763    774       if( pConfig->abUnindexed[ctx.iCol]==0 ){
   764    775         rc = sqlite3Fts5Tokenize(pConfig, 
   765    776             FTS5_TOKENIZE_DOCUMENT,
   766    777             (const char*)sqlite3_value_text(apVal[ctx.iCol+2]),
................................................................................
   772    783       sqlite3Fts5BufferAppendVarint(&rc, &buf, ctx.szCol);
   773    784       p->aTotalSize[ctx.iCol] += (i64)ctx.szCol;
   774    785     }
   775    786     p->nTotalRow++;
   776    787   
   777    788     /* Write the %_docsize record */
   778    789     if( rc==SQLITE_OK ){
   779         -    rc = fts5StorageInsertDocsize(p, *piRowid, &buf);
          790  +    rc = fts5StorageInsertDocsize(p, iRowid, &buf);
   780    791     }
   781    792     sqlite3_free(buf.p);
   782    793   
   783    794     /* Write the averages record */
   784    795     if( rc==SQLITE_OK ){
   785    796       rc = fts5StorageSaveTotals(p);
   786    797     }

Changes to ext/fts5/fts5_tcl.c.

   972    972   
   973    973   static int f5tTokenHash(
   974    974     void * clientData,
   975    975     Tcl_Interp *interp,
   976    976     int objc,
   977    977     Tcl_Obj *CONST objv[]
   978    978   ){
   979         -  int bOld = sqlite3_fts5_may_be_corrupt;
   980    979     char *z;
   981    980     int n;
   982    981     unsigned int iVal;
   983    982     int nSlot;
   984    983   
   985    984     if( objc!=3 ){
   986    985       Tcl_WrongNumArgs(interp, 1, objv, "NSLOT TOKEN");

Changes to ext/fts5/fts5_vocab.c.

   345    345         assert( pTab->eType==FTS5_VOCAB_COL || pTab->eType==FTS5_VOCAB_ROW );
   346    346         while( rc==SQLITE_OK ){
   347    347           i64 dummy;
   348    348           const u8 *pPos; int nPos;   /* Position list */
   349    349           i64 iPos = 0;               /* 64-bit position read from poslist */
   350    350           int iOff = 0;               /* Current offset within position list */
   351    351   
   352         -        rc = sqlite3Fts5IterPoslist(pCsr->pIter, &pPos, &nPos, &dummy);
          352  +        rc = sqlite3Fts5IterPoslist(pCsr->pIter, 0, &pPos, &nPos, &dummy);
   353    353           if( rc==SQLITE_OK ){
   354    354             if( pTab->eType==FTS5_VOCAB_ROW ){
   355    355               while( 0==sqlite3Fts5PoslistNext64(pPos, nPos, &iOff, &iPos) ){
   356    356                 pCsr->aVal[1]++;
   357    357               }
   358    358               pCsr->aVal[0]++;
   359    359             }else{
................................................................................
   398    398     sqlite3_value **apVal           /* Arguments for the indexing scheme */
   399    399   ){
   400    400     Fts5VocabCursor *pCsr = (Fts5VocabCursor*)pCursor;
   401    401     int rc;
   402    402     const int flags = FTS5INDEX_QUERY_SCAN;
   403    403   
   404    404     fts5VocabResetCursor(pCsr);
   405         -  rc = sqlite3Fts5IndexQuery(pCsr->pIndex, 0, 0, flags, &pCsr->pIter);
          405  +  rc = sqlite3Fts5IndexQuery(pCsr->pIndex, 0, 0, flags, 0, &pCsr->pIter);
   406    406     if( rc==SQLITE_OK ){
   407    407       rc = fts5VocabNextMethod(pCursor);
   408    408     }
   409    409   
   410    410     return rc;
   411    411   }
   412    412   

Changes to ext/fts5/fts5parse.y.

    63     63   %left OR.
    64     64   %left AND.
    65     65   %left NOT.
    66     66   %left TERM.
    67     67   %left COLON.
    68     68   
    69     69   input ::= expr(X). { sqlite3Fts5ParseFinished(pParse, X); }
           70  +%destructor input { (void)pParse; }
    70     71   
    71     72   %type cnearset    {Fts5ExprNode*}
    72     73   %type expr        {Fts5ExprNode*}
    73     74   %type exprlist    {Fts5ExprNode*}
    74     75   %destructor cnearset { sqlite3Fts5ParseNodeFree($$); }
    75     76   %destructor expr     { sqlite3Fts5ParseNodeFree($$); }
    76     77   %destructor exprlist { sqlite3Fts5ParseNodeFree($$); }
................................................................................
    97     98     A = sqlite3Fts5ParseNode(pParse, FTS5_STRING, 0, 0, X); 
    98     99   }
    99    100   cnearset(A) ::= colset(X) COLON nearset(Y). { 
   100    101     sqlite3Fts5ParseSetColset(pParse, Y, X);
   101    102     A = sqlite3Fts5ParseNode(pParse, FTS5_STRING, 0, 0, Y); 
   102    103   }
   103    104   
   104         -%type colset {Fts5ExprColset*}
          105  +%type colset {Fts5Colset*}
   105    106   %destructor colset { sqlite3_free($$); }
   106         -%type colsetlist {Fts5ExprColset*}
          107  +%type colsetlist {Fts5Colset*}
   107    108   %destructor colsetlist { sqlite3_free($$); }
   108    109   
   109    110   colset(A) ::= LCP colsetlist(X) RCP. { A = X; }
   110    111   colset(A) ::= STRING(X). {
   111    112     A = sqlite3Fts5ParseColset(pParse, 0, &X);
   112    113   }
   113    114   

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

    13     13   if {![info exists testdir]} {
    14     14     set testdir [file join [file dirname [info script]] .. .. .. test]
    15     15   }
    16     16   source $testdir/tester.tcl
    17     17   
    18     18   catch { 
    19     19     sqlite3_fts5_may_be_corrupt 0 
    20         -  append G(perm:dbconfig) "; load_static_extension \$::dbhandle fts5"
    21     20     reset_db
    22     21   }
    23     22   
    24     23   proc fts5_test_poslist {cmd} {
    25     24     set res [list]
    26     25     for {set i 0} {$i < [$cmd xInstCount]} {incr i} {
    27     26       lappend res [string map {{ } .} [$cmd xInst $i]]

Changes to ext/fts5/test/fts5al.test.

   247    247     INSERT INTO t3 VALUES('a one');
   248    248     INSERT INTO t3 VALUES('a two');
   249    249     INSERT INTO t3 VALUES('a three');
   250    250     INSERT INTO t3 VALUES('a four');
   251    251     INSERT INTO t3 VALUES('a five');
   252    252     INSERT INTO t3(t3, rank) VALUES('rank', 'bm25()');
   253    253   }
   254         -breakpoint
   255    254   
   256    255   do_execsql_test 4.3.2 {
   257    256     SELECT * FROM t3
   258    257     WHERE t3 MATCH 'a' AND rank MATCH 'rowidmod(4)' 
   259    258     ORDER BY rank ASC
   260    259   } {
   261    260     {a four} {a one} {a five} {a two} {a three}
   262    261   }
          262  +
   263    263   do_execsql_test 4.3.3 {
   264    264     SELECT *, rank FROM t3
   265    265     WHERE t3 MATCH 'a' AND rank MATCH 'rowidmod(3)' 
   266    266     ORDER BY rank ASC
   267    267   } {
   268    268     {a three} 0 {a one} 1 {a four} 1 {a two} 2 {a five} 2 
   269    269   }
          270  +
          271  +do_execsql_test 4.3.4 {
          272  +  SELECT * FROM t3('a', 'rowidmod(4)') ORDER BY rank ASC;
          273  +} {
          274  +  {a four} {a one} {a five} {a two} {a three}
          275  +}
          276  +
          277  +do_execsql_test 4.3.5 {
          278  +  SELECT *, rank FROM t3('a', 'rowidmod(3)') ORDER BY rank ASC
          279  +} {
          280  +  {a three} 0 {a one} 1 {a four} 1 {a two} 2 {a five} 2 
          281  +}
   270    282   
   271    283   do_catchsql_test 4.4.3 {
   272    284     SELECT *, rank FROM t3 WHERE t3 MATCH 'a' AND rank MATCH 'xyz(3)' 
   273    285   } {1 {no such function: xyz}}
   274    286   do_catchsql_test 4.4.4 {
   275    287     SELECT *, rank FROM t3 WHERE t3 MATCH 'a' AND rank MATCH NULL
   276    288   } {1 {parse error in rank function: }}
   277    289   
   278    290   
   279    291   
   280    292   finish_test
   281    293   

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

   280    280   
   281    281   #-------------------------------------------------------------------------
   282    282   catch { db close }
   283    283   breakpoint
   284    284   do_faultsim_test 6 -faults oom* -prep {
   285    285     sqlite_orig db test.db
   286    286     sqlite3_db_config_lookaside db 0 0 0
   287         -} -body {
   288         -  load_static_extension db fts5
   289    287   } -test {
   290    288     faultsim_test_result {0 {}} {1 {initialization of fts5 failed: }}
   291    289     if {$testrc==0} {
   292    290       db eval { CREATE VIRTUAL TABLE temp.t1 USING fts5(x) }
   293    291     }
   294    292     db close
   295    293   }
   296    294   finish_test
   297    295   

Added ext/fts5/test/fts5onepass.test.

            1  +# 2015 Sep 27
            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 fts5onepass
           15  +
           16  +# If SQLITE_ENABLE_FTS3 is defined, omit this file.
           17  +ifcapable !fts5 {
           18  +  finish_test
           19  +  return
           20  +}
           21  +
           22  +do_execsql_test 1.0 {
           23  +  CREATE VIRTUAL TABLE ft USING fts5(content);
           24  +  INSERT INTO ft(rowid, content) VALUES(1, '1 2 3');
           25  +  INSERT INTO ft(rowid, content) VALUES(2, '4 5 6');
           26  +  INSERT INTO ft(rowid, content) VALUES(3, '7 8 9');
           27  +}
           28  +
           29  +#-------------------------------------------------------------------------
           30  +# Check that UPDATE and DELETE statements that feature "WHERE rowid=?" or 
           31  +# or "WHERE rowid=?" clauses do not use statement journals. But that other
           32  +# DELETE and UPDATE statements do.
           33  +#
           34  +# Note: "MATCH ? AND rowid=?" does use a statement journal.
           35  +#
           36  +foreach {tn sql uses} {
           37  +  1.1 { DELETE FROM ft } 1
           38  +  1.2 { DELETE FROM ft WHERE rowid=? } 0
           39  +  1.3 { DELETE FROM ft WHERE rowid=? } 0
           40  +  1.4 { DELETE FROM ft WHERE ft MATCH '1' } 1
           41  +  1.5 { DELETE FROM ft WHERE ft MATCH '1' AND rowid=? } 1
           42  +  1.6 { DELETE FROM ft WHERE ft MATCH '1' AND rowid=? } 1
           43  +
           44  +  2.1 { UPDATE ft SET content='a b c' } 1
           45  +  2.2 { UPDATE ft SET content='a b c' WHERE rowid=? } 0
           46  +  2.3 { UPDATE ft SET content='a b c' WHERE rowid=? } 0
           47  +  2.4 { UPDATE ft SET content='a b c' WHERE ft MATCH '1' } 1
           48  +  2.5 { UPDATE ft SET content='a b c' WHERE ft MATCH '1' AND rowid=? } 1
           49  +  2.6 { UPDATE ft SET content='a b c' WHERE ft MATCH '1' AND rowid=? } 1
           50  +} {
           51  +  do_test 1.$tn { sql_uses_stmt db $sql } $uses
           52  +}
           53  +
           54  +#-------------------------------------------------------------------------
           55  +# Check that putting a "DELETE/UPDATE ... WHERE rowid=?" statement in a
           56  +# trigger program does not prevent the VM from using a statement 
           57  +# transaction. Even if the calling statement cannot hit a constraint.
           58  +#
           59  +do_execsql_test 2.0 {
           60  +  CREATE TABLE t1(x);
           61  +
           62  +  CREATE TRIGGER t1_ai AFTER INSERT ON t1 BEGIN
           63  +    DELETE FROM ft WHERE rowid=new.x;
           64  +  END;
           65  +
           66  +  CREATE TRIGGER t1_ad AFTER DELETE ON t1 BEGIN
           67  +    UPDATE ft SET content = 'a b c' WHERE rowid=old.x;
           68  +  END;
           69  +
           70  +  CREATE TRIGGER t1_bu BEFORE UPDATE ON t1 BEGIN
           71  +    DELETE FROM ft WHERE rowid=old.x;
           72  +  END;
           73  +}
           74  +
           75  +foreach {tn sql uses} {
           76  +  1 { INSERT INTO t1 VALUES(1)      } 1
           77  +  2 { DELETE FROM t1 WHERE x=4      } 1
           78  +  3 { UPDATE t1 SET x=10 WHERE x=11 } 1
           79  +} {
           80  +  do_test 2.$tn { sql_uses_stmt db $sql } $uses
           81  +}
           82  +
           83  +#-------------------------------------------------------------------------
           84  +# Test that an "UPDATE ... WHERE rowid=?" works and does not corrupt the
           85  +# index when it strikes a constraint. Both inside and outside a 
           86  +# transaction.
           87  +#
           88  +foreach {tn tcl1 tcl2}  {
           89  +  1 {} {}
           90  +
           91  +  2 {
           92  +    execsql BEGIN
           93  +  } {
           94  +    if {[sqlite3_get_autocommit db]==1} { error "transaction rolled back!" }
           95  +    execsql COMMIT
           96  +  }
           97  +} {
           98  +
           99  +  do_execsql_test 3.$tn.0 {
          100  +    DROP TABLE IF EXISTS ft2;
          101  +    CREATE VIRTUAL TABLE ft2 USING fts5(content);
          102  +    INSERT INTO ft2(rowid, content) VALUES(1, 'a b c');
          103  +    INSERT INTO ft2(rowid, content) VALUES(2, 'a b d');
          104  +    INSERT INTO ft2(rowid, content) VALUES(3, 'a b e');
          105  +  }
          106  +
          107  +  eval $tcl1
          108  +  foreach {tn2 sql content} {
          109  +    1 { UPDATE ft2 SET rowid=2 WHERE rowid=1 }
          110  +      { 1 {a b c} 2 {a b d} 3 {a b e} }
          111  +
          112  +    2 { 
          113  +      INSERT INTO ft2(rowid, content) VALUES(4, 'a b f');
          114  +      UPDATE ft2 SET rowid=5 WHERE rowid=4;
          115  +      UPDATE ft2 SET rowid=3 WHERE rowid=5;
          116  +    } { 1 {a b c} 2 {a b d} 3 {a b e} 5 {a b f} }
          117  +
          118  +    3 {
          119  +      UPDATE ft2 SET rowid=3 WHERE rowid=4;           -- matches 0 rows
          120  +      UPDATE ft2 SET rowid=2 WHERE rowid=3;
          121  +    } { 1 {a b c} 2 {a b d} 3 {a b e} 5 {a b f} }
          122  +
          123  +    4 {
          124  +      INSERT INTO ft2(rowid, content) VALUES(4, 'a b g');
          125  +      UPDATE ft2 SET rowid=-1 WHERE rowid=4;
          126  +      UPDATE ft2 SET rowid=3 WHERE rowid=-1;
          127  +    } {-1 {a b g} 1 {a b c} 2 {a b d} 3 {a b e} 5 {a b f} }
          128  +
          129  +    5 {
          130  +      DELETE FROM ft2 WHERE rowid=451;
          131  +      DELETE FROM ft2 WHERE rowid=-1;
          132  +      UPDATE ft2 SET rowid = 2 WHERE rowid = 1;
          133  +    } {1 {a b c} 2 {a b d} 3 {a b e} 5 {a b f} }
          134  +  } {
          135  +    do_catchsql_test 3.$tn.$tn2.a $sql {1 {constraint failed}}
          136  +    do_execsql_test  3.$tn.$tn2.b { SELECT rowid, content FROM ft2 } $content
          137  +
          138  +    do_execsql_test  3.$tn.$tn2.c { 
          139  +      INSERT INTO ft2(ft2) VALUES('integrity-check');
          140  +    }
          141  +  }
          142  +  eval $tcl2
          143  +}
          144  +
          145  +#-------------------------------------------------------------------------
          146  +# Check that DELETE and UPDATE operations can be done without flushing
          147  +# the in-memory hash table to disk.
          148  +#
          149  +reset_db
          150  +do_execsql_test 4.1.1 {
          151  +  CREATE VIRTUAL TABLE ttt USING fts5(x);
          152  +  BEGIN;
          153  +    INSERT INTO ttt(rowid, x) VALUES(1, 'a b c');
          154  +    INSERT INTO ttt(rowid, x) VALUES(2, 'a b c');
          155  +    INSERT INTO ttt(rowid, x) VALUES(3, 'a b c');
          156  +  COMMIT
          157  +}
          158  +do_test 4.1.2 { fts5_level_segs ttt } {1}
          159  +
          160  +do_execsql_test 4.2.1 {
          161  +  BEGIN;
          162  +    DELETE FROM ttt WHERE rowid=1;
          163  +    DELETE FROM ttt WHERE rowid=3;
          164  +    INSERT INTO ttt(rowid, x) VALUES(4, 'd e f');
          165  +    INSERT INTO ttt(rowid, x) VALUES(5, 'd e f');
          166  +  COMMIT;
          167  +} {}
          168  +do_test 4.2.2 { fts5_level_segs ttt } {2}
          169  +
          170  +
          171  +do_execsql_test 4.3.1 {
          172  +  BEGIN;
          173  +    UPDATE ttt SET x = 'd e f' WHERE rowid = 2;
          174  +    UPDATE ttt SET x = 'A B C' WHERE rowid = 4;
          175  +    INSERT INTO ttt(rowid, x) VALUES(6, 'd e f');
          176  +  COMMIT;
          177  +} {}
          178  +do_test 4.2.2 { fts5_level_segs ttt } {3}
          179  +
          180  +finish_test
          181  +

Added ext/fts5/test/fts5phrase.test.

            1  +# 2014 Jan 08
            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  +# Tests focused on phrase queries.
           13  +#
           14  +
           15  +source [file join [file dirname [info script]] fts5_common.tcl]
           16  +set testprefix fts5phrase
           17  +
           18  +# If SQLITE_ENABLE_FTS5 is defined, omit this file.
           19  +ifcapable !fts5 {
           20  +  finish_test
           21  +  return
           22  +}
           23  +
           24  +do_execsql_test 1.0 {
           25  +  CREATE VIRTUAL TABLE t3 USING fts5(a, b, c);
           26  +  INSERT INTO t3 VALUES('d e a', 'd i j j f', 'i j i e b f h'); -- 1
           27  +  INSERT INTO t3 VALUES('g a e', 'f g i g a', 'h d g i g h c'); -- 2
           28  +  INSERT INTO t3 VALUES('e a d', 'e i h a f', 'c e h i f b i'); -- 3
           29  +  INSERT INTO t3 VALUES('a g c', 'd j d j c', 'c d f j i g j'); -- 4
           30  +  INSERT INTO t3 VALUES('b c b', 'j g c d f', 'j c j d g f b'); -- 5
           31  +  INSERT INTO t3 VALUES('j a d', 'e b i h h', 'c c f g d i d'); -- 6
           32  +  INSERT INTO t3 VALUES('a d f', 'h g i i i', 'e a g c i f b'); -- 7
           33  +  INSERT INTO t3 VALUES('g f d', 'f c g b j', 'b b h h h j j'); -- 8
           34  +  INSERT INTO t3 VALUES('f h g', 'c j f g j', 'd h d f e b h'); -- 9
           35  +  INSERT INTO t3 VALUES('f h d', 'c i a d b', 'g b j b a d e'); -- 10
           36  +  INSERT INTO t3 VALUES('j h h', 'j i h a g', 'd e i e a g j'); -- 11
           37  +  INSERT INTO t3 VALUES('a b e', 'h g a g c', 'h c a a d e g'); -- 12
           38  +  INSERT INTO t3 VALUES('a j g', 'i h i f i', 'a g h j g i b'); -- 13
           39  +  INSERT INTO t3 VALUES('j h e', 'f e d i e', 'i d c f e d c'); -- 14
           40  +  INSERT INTO t3 VALUES('d j d', 'd b i a c', 'g d h i d b e'); -- 15
           41  +  INSERT INTO t3 VALUES('h j e', 'e b b c f', 'j a f g h d j'); -- 16
           42  +  INSERT INTO t3 VALUES('c b j', 'c a b a i', 'h f i d a d c'); -- 17
           43  +  INSERT INTO t3 VALUES('e e d', 'i d f c c', 'g i d a f e a'); -- 18
           44  +  INSERT INTO t3 VALUES('e i g', 'e a b i h', 'i f d d a d f'); -- 19
           45  +  INSERT INTO t3 VALUES('h g f', 'b h h j d', 'i f d e g j a'); -- 20
           46  +  INSERT INTO t3 VALUES('e h f', 'j c b c f', 'j a j g h a c'); -- 21
           47  +  INSERT INTO t3 VALUES('d c h', 'b g i c e', 'i i c d e h i'); -- 22
           48  +  INSERT INTO t3 VALUES('a h i', 'a g d f f', 'e f i i b b h'); -- 23
           49  +  INSERT INTO t3 VALUES('d d g', 'c c b c g', 'g c h e b c e'); -- 24
           50  +  INSERT INTO t3 VALUES('a b b', 'b f a d i', 'd a h a b c i'); -- 25
           51  +  INSERT INTO t3 VALUES('a f d', 'a j e a h', 'j i h j a i f'); -- 26
           52  +  INSERT INTO t3 VALUES('d j d', 'h a d i a', 'h h f j h g a'); -- 27
           53  +  INSERT INTO t3 VALUES('g a e', 'd g f a g', 'i d b c g g j'); -- 28
           54  +  INSERT INTO t3 VALUES('j e h', 'g h j h g', 'd a e j a a h'); -- 29
           55  +  INSERT INTO t3 VALUES('e j e', 'g e j g c', 'f c e b e e a'); -- 30
           56  +  INSERT INTO t3 VALUES('h f f', 'i j g e c', 'j j f c a i j'); -- 31
           57  +  INSERT INTO t3 VALUES('a g c', 'c g d b i', 'g h c b a a f'); -- 32
           58  +  INSERT INTO t3 VALUES('c h i', 'j d h e e', 'a h i d c c j'); -- 33
           59  +  INSERT INTO t3 VALUES('d a c', 'e d d b j', 'c e b b h i h'); -- 34
           60  +  INSERT INTO t3 VALUES('d f h', 'c a f c c', 'j b b c c j f'); -- 35
           61  +  INSERT INTO t3 VALUES('b g h', 'g c c c f', 'c g c f h e e'); -- 36
           62  +  INSERT INTO t3 VALUES('f e a', 'b h f j h', 'j g h f d g f'); -- 37
           63  +  INSERT INTO t3 VALUES('h f a', 'a e i j g', 'f d a f d f c'); -- 38
           64  +  INSERT INTO t3 VALUES('f i c', 'f i i i i', 'e c f d h j f'); -- 39
           65  +  INSERT INTO t3 VALUES('h h d', 'd i e d i', 'd f e i a h a'); -- 40
           66  +  INSERT INTO t3 VALUES('f g c', 'd a f c h', 'b b g j c e g'); -- 41
           67  +  INSERT INTO t3 VALUES('h i h', 'h d j d e', 'e d b b i e g'); -- 42
           68  +  INSERT INTO t3 VALUES('b h i', 'j e i d a', 'j j h e e c a'); -- 43
           69  +  INSERT INTO t3 VALUES('g i g', 'f c c f d', 'a c i c a d a'); -- 44
           70  +  INSERT INTO t3 VALUES('c c f', 'a b j d b', 'c a e g f e c'); -- 45
           71  +  INSERT INTO t3 VALUES('d h j', 'g c b j d', 'e a h f h j g'); -- 46
           72  +  INSERT INTO t3 VALUES('a a d', 'j e j a i', 'i d c f f f b'); -- 47
           73  +  INSERT INTO t3 VALUES('b g j', 'e c i h f', 'd d h b g a d'); -- 48
           74  +  INSERT INTO t3 VALUES('c i a', 'a c c c c', 'e h i e h i e'); -- 49
           75  +  INSERT INTO t3 VALUES('f f c', 'f f b i i', 'f f a j e c i'); -- 50
           76  +}
           77  +
           78  +proc pmatch {col expr} {
           79  +  return [expr {[string first $expr $col]>=0}]
           80  +}
           81  +db func pmatch pmatch
           82  +
           83  +foreach {tn cols tokens} {
           84  +  1 a         "c c"
           85  +  2 b         "c c"
           86  +  3 c         "c c"
           87  +  4 {a b c}   "c c"
           88  +  5 {a b c}   "b h"
           89  +  6 {a b}     "b h"
           90  +  7 {a c}     "b h"
           91  +  8 {c a}     "b h"
           92  +  9 {c}       "i e"
           93  +  10 {b}      "i e"
           94  +  11 {a}      "i e"
           95  +} {
           96  +  set fts   "{$cols}:[join $tokens +]"
           97  +  set where [list]
           98  +  foreach c $cols { lappend where "pmatch($c, '$tokens')" }
           99  +  set where [join $where " OR "]
          100  +
          101  +  set res [db eval "SELECT rowid FROM t3 WHERE $where"]
          102  +  do_execsql_test "1.$tn.$fts->([llength $res] rows)" { 
          103  +    SELECT rowid FROM t3($fts) 
          104  +  } $res
          105  +}
          106  +
          107  +do_execsql_test 2.0 {
          108  +  SELECT rowid,
          109  +    highlight(t3, 0, '*', '*'),
          110  +    highlight(t3, 1, '*', '*'),
          111  +    highlight(t3, 2, '*', '*')
          112  +  FROM t3('a:f+f')
          113  +} {
          114  +  31 {h *f f*} {i j g e c} {j j f c a i j} 
          115  +  50 {*f f* c} {f f b i i} {f f a j e c i}
          116  +}
          117  +
          118  +finish_test
          119  +

Changes to ext/fts5/test/fts5prefix.test.

    58     58   foreach {tn q res} {
    59     59     1 "SELECT rowid FROM t1 WHERE t1 MATCH '\xCA\xCB*'" 1
    60     60     2 "SELECT rowid FROM t1 WHERE t1 MATCH '\u1234\u5678*'" 2
    61     61   } {
    62     62     do_execsql_test 2.3.$tn $q $res
    63     63   }
    64     64   
           65  +#-------------------------------------------------------------------------
           66  +# Check that prefix queries with:
           67  +#
           68  +#   * a column filter, and
           69  +#   * no prefix index.
           70  +#
           71  +# work Ok.
           72  +#
           73  +do_execsql_test 3.0 {
           74  +  CREATE VIRTUAL TABLE t3 USING fts5(a, b, c);
           75  +  INSERT INTO t3(t3, rank) VALUES('pgsz', 32);
           76  +  BEGIN;
           77  +    INSERT INTO t3 VALUES('acb ccc bba', 'cca bba bca', 'bbc ccc bca'); -- 1
           78  +    INSERT INTO t3 VALUES('cbb cac cab', 'abb aac bba', 'aab ccc cac'); -- 2
           79  +    INSERT INTO t3 VALUES('aac bcb aac', 'acb bcb caa', 'aca bab bca'); -- 3
           80  +    INSERT INTO t3 VALUES('aab ccb ccc', 'aca cba cca', 'aca aac cbb'); -- 4
           81  +    INSERT INTO t3 VALUES('bac aab bab', 'ccb bac cba', 'acb aba abb'); -- 5
           82  +    INSERT INTO t3 VALUES('bab abc ccb', 'acb cba abb', 'cbb aaa cab'); -- 6
           83  +    INSERT INTO t3 VALUES('cbb bbc baa', 'aab aca baa', 'bcc cca aca'); -- 7
           84  +    INSERT INTO t3 VALUES('abc bba abb', 'cac abc cba', 'acc aac cac'); -- 8
           85  +    INSERT INTO t3 VALUES('bbc bbc cab', 'bcb ccb cba', 'bcc cac acb'); -- 9
           86  +  COMMIT;
           87  +}
           88  +
           89  +foreach {tn match res} {
           90  +  1 "a : c*" {1 2 4 6 7 9}
           91  +  2 "b : c*" {1 3 4 5 6 8 9}
           92  +  3 "c : c*" {1 2 4 6 7 8 9}
           93  +  4 "a : b*" {1 3 5 6 7 8 9}
           94  +  5 "b : b*" {1 2 3 5 7 9}
           95  +  6 "c : b*" {1 3 7 9}
           96  +  7 "a : a*" {1 3 4 5 6 8}
           97  +  8 "b : a*" {2 3 4 6 7 8}
           98  +  9 "c : a*" {2 3 4 5 6 7 8 9}
           99  +} {
          100  +  do_execsql_test 3.1.$tn {
          101  +    SELECT rowid FROM t3($match)
          102  +  } $res
          103  +}
          104  +
          105  +do_test 3.2 {
          106  +  expr srand(0)
          107  +  execsql { DELETE FROM t3 }
          108  +  for {set i 0} {$i < 1000} {incr i} {
          109  +    set a [fts5_rnddoc 3]
          110  +    set b [fts5_rnddoc 8]
          111  +    set c [fts5_rnddoc 20]
          112  +    execsql { INSERT INTO t3 VALUES($a, $b, $c) }
          113  +  }
          114  +  execsql { INSERT INTO t3(t3) VALUES('integrity-check') }
          115  +} {}
          116  +
          117  +proc gmatch {col pattern} {
          118  +  expr {[lsearch -glob $col $pattern]>=0}
          119  +}
          120  +db func gmatch gmatch
          121  +
          122  +proc ghl {col pattern} {
          123  +  foreach t $col {
          124  +    if {[string match $pattern $t]} {
          125  +      lappend res "*$t*"
          126  +    } else {
          127  +      lappend res $t
          128  +    }
          129  +  }
          130  +  set res
          131  +}
          132  +db func ghl ghl
          133  +
          134  +set COLS(a) 0
          135  +set COLS(b) 1
          136  +set COLS(c) 2
          137  +
          138  +for {set x 0} {$x<2} {incr x} {
          139  +  foreach {tn pattern} {
          140  +    1  {xa*}
          141  +    2  {xb*}
          142  +    3  {xc*}
          143  +    4  {xd*}
          144  +    5  {xe*}
          145  +    6  {xf*}
          146  +    7  {xg*}
          147  +    8  {xh*}
          148  +    9  {xi*}
          149  +    10 {xj*}
          150  +  } {
          151  +    foreach col {a b c} {
          152  +
          153  +      # Check that the list of returned rowids is correct.
          154  +      #
          155  +      set res [db eval "SELECT rowid FROM t3 WHERE gmatch($col, '$pattern')"]
          156  +      set query "$col : $pattern"
          157  +      do_execsql_test 3.3.$x.$tn.$col.rowid {
          158  +        SELECT rowid FROM t3($query);
          159  +      } $res
          160  +
          161  +      # Check that the highlight() function works.
          162  +      #
          163  +      set res [db eval \
          164  +        "SELECT ghl($col, '$pattern') FROM t3 WHERE gmatch($col, '$pattern')"
          165  +      ]
          166  +      set idx $COLS($col)
          167  +      do_execsql_test 3.3.$x.$tn.$col.highlight {
          168  +        SELECT highlight(t3, $idx, '*', '*') FROM t3($query);
          169  +      } $res
          170  +    }
          171  +
          172  +    foreach colset {{a b} {b c} {c a} {a c} {b a}} {
          173  +      # Check that the list of returned rowids is correct.
          174  +      #
          175  +      foreach {col1 col2} $colset {}
          176  +      set expr "gmatch($col1, '$pattern') OR gmatch($col2, '$pattern')"
          177  +      set res [db eval "SELECT rowid FROM t3 WHERE $expr"]
          178  +      set query "{$colset} : $pattern"
          179  +      do_execsql_test 3.3.$x.$tn.{$colset}.rowid {
          180  +        SELECT rowid FROM t3($query);
          181  +      } $res
          182  +
          183  +      set resq    "SELECT ghl($col1, '$pattern'), ghl($col2, '$pattern')"
          184  +      append resq " FROM t3 WHERE $expr"
          185  +      set res [db eval $resq]
          186  +      set idx1 $COLS($col1)
          187  +      set idx2 $COLS($col2)
          188  +      do_execsql_test 3.3.$x.$tn.{$colset}.highlight {
          189  +        SELECT highlight(t3, $idx1, '*', '*'), highlight(t3, $idx2, '*', '*')
          190  +          FROM t3($query)
          191  +      } $res
          192  +    }
          193  +  }
          194  +  execsql { INSERT INTO t3(t3) VALUES('optimize') }
          195  +  execsql { INSERT INTO t3(t3) VALUES('integrity-check') }
          196  +}
          197  +
    65    198   
    66    199   finish_test
          200  +
    67    201   

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 {
    23     22   #-------------------------------------------------------------------------
    24     23   #
    25     24   set doc "x x [string repeat {y } 50]z z"
    26     25   do_execsql_test 1.0 {
    27     26     CREATE VIRTUAL TABLE t1 USING fts5(x);
    28     27     INSERT INTO t1(t1, rank) VALUES('pgsz', 32);
    29     28     BEGIN;
................................................................................
   133    132     COMMIT;
   134    133   } {}
   135    134   
   136    135   do_execsql_test 5.4 {
   137    136     SELECT rowid FROM tt WHERE tt MATCH 'a*';
   138    137   } {1 2}
   139    138   
   140         -}
   141         -
   142    139   do_execsql_test 5.5 {
   143    140     DELETE FROM tt;
   144    141     BEGIN;
   145    142       INSERT INTO tt VALUES('aa');
   146    143       INSERT INTO tt VALUES('ab');
   147    144       INSERT INTO tt VALUES('aa');
   148    145       INSERT INTO tt VALUES('ab');
................................................................................
   180    177   do_catchsql_test 6.2 { 
   181    178     SELECT * FROM xyz WHERE xyz MATCH '' 
   182    179   } {1 {fts5: syntax error near ""}}
   183    180   do_catchsql_test 6.3 { 
   184    181     SELECT * FROM xyz WHERE xyz MATCH NULL 
   185    182   } {1 {fts5: syntax error near ""}}
   186    183   
          184  +#-------------------------------------------------------------------------
          185  +
          186  +do_execsql_test 7.1 {
          187  +  CREATE VIRTUAL TABLE ft2 USING fts5(content);
          188  +  INSERT INTO ft2(rowid, content) VALUES(1, 'a b c');
          189  +  INSERT INTO ft2(rowid, content) VALUES(2, 'a b d');
          190  +} 
          191  +
          192  +do_catchsql_test 7.2 {
          193  +  BEGIN;
          194  +    UPDATE ft2 SET rowid=2 WHERE rowid=1;
          195  +} {1 {constraint failed}} 
          196  +
          197  +do_execsql_test 7.3 {
          198  +  COMMIT;
          199  +  INSERT INTO ft2(ft2) VALUES('integrity-check');
          200  +} {}
          201  +
          202  +do_execsql_test 7.4 {
          203  +  SELECT * FROM ft2;
          204  +} {{a b c} {a b d}}
          205  +
          206  +#-------------------------------------------------------------------------
          207  +#
          208  +reset_db
          209  +do_execsql_test 8.1 {
          210  +  CREATE VIRTUAL TABLE ft2 USING fts5(content);
          211  +  INSERT INTO ft2(rowid, content) VALUES(1, 'a b');
          212  +}
          213  +
          214  +do_execsql_test 8.2 {
          215  +  BEGIN;
          216  +    INSERT INTO ft2(rowid, content) VALUES(4, 'a x');
          217  +}
          218  +
          219  +do_execsql_test 8.3 {
          220  +  INSERT INTO ft2(ft2) VALUES('integrity-check');
          221  +}
          222  +
          223  +#-------------------------------------------------------------------------
          224  +# Check that the "table function" syntax works.
          225  +#
          226  +reset_db
          227  +do_execsql_test 9.1 {
          228  +  CREATE VIRTUAL TABLE ft2 USING fts5(content);
          229  +  INSERT INTO ft2(rowid, content) VALUES(1, 'a b');
          230  +  INSERT INTO ft2(rowid, content) VALUES(2, 'a b c d');
          231  +  INSERT INTO ft2(rowid, content) VALUES(3, 'c d e f');
          232  +}
          233  +
          234  +do_execsql_test 9.2 {
          235  +  SELECT rowid FROM ft2('a');
          236  +} {1 2}
          237  +
          238  +do_execsql_test 9.3 {
          239  +  SELECT rowid FROM ft2('b AND c');
          240  +} {2}
          241  +
          242  +#-------------------------------------------------------------------------
          243  +#
          244  +do_execsql_test 10.0 {
          245  +  CREATE VIRTUAL TABLE t3 USING fts5(a, b, c);
          246  +  INSERT INTO t3 VALUES('bac aab bab', 'c bac c', 'acb aba abb'); -- 1
          247  +  INSERT INTO t3 VALUES('bab abc c', 'acb c abb', 'c aaa c');     -- 2
          248  +}
          249  +
          250  +do_execsql_test 10.1 {
          251  +  SELECT rowid FROM t3('c: c*');
          252  +} {2}
          253  +
          254  +do_execsql_test 10.2 {
          255  +  SELECT rowid FROM t3('b: acb');
          256  +} {2}
          257  +
          258  +#-------------------------------------------------------------------------
          259  +# Test that character 0x1A is allowed in fts5 barewords.
          260  +#
          261  +do_test 11.0 {
          262  +  execsql "CREATE VIRTUAL TABLE t4 USING fts5(x, tokenize=\"ascii tokenchars '\x1A'\")"
          263  +  execsql "
          264  +    INSERT INTO t4 VALUES('a b c \x1A');
          265  +    INSERT INTO t4 VALUES('a b c d\x1A');
          266  +    INSERT INTO t4 VALUES('a b c \x1Ad');
          267  +    INSERT INTO t4 VALUES('a b c d');
          268  +  "
          269  +} {}
          270  +
          271  +do_test 11.1 {
          272  +  execsql "SELECT rowid FROM t4('\x1A')"
          273  +} {1}
          274  +do_test 11.2 {
          275  +  execsql "SELECT rowid FROM t4('\x1A*')"
          276  +} {1 3}
          277  +do_test 11.3 {
          278  +  execsql "SELECT rowid FROM t4('d\x1A')"
          279  +} {2}
          280  +
          281  +do_test 11.4 {
          282  +  catchsql "SELECT rowid FROM t4('d\x1B')"
          283  +} {/fts5: syntax error/}
          284  +do_test 11.5 {
          285  +  catchsql "SELECT rowid FROM t4('d\x19')"
          286  +} {/fts5: syntax error/}
          287  +
          288  +#-------------------------------------------------------------------------
          289  +#
          290  +do_test 12.1 {
          291  +  execsql {
          292  +    CREATE VIRTUAL TABLE xx USING fts5(x,y);
          293  +    BEGIN;
          294  +      INSERT INTO xx VALUES('1 2 3', 'a b c');
          295  +  }
          296  +} {}
          297  +
          298  +do_execsql_test 12.2 {
          299  +  SELECT rowid FROM xx('x:a');
          300  +  COMMIT;
          301  +} {}
   187    302   
   188    303   finish_test
   189    304   

Added 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
           26  +}
           27  +
           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]
           43  +  }
           44  +
           45  +  switch -- $opt {
           46  +    -colsize {
           47  +      set O(aColSize) $val
           48  +    }
           49  +
           50  +    -fts4 {
           51  +      set O(fts) fts4
           52  +    }
           53  +
           54  +    -fts5 {
           55  +      set O(fts) fts5
           56  +    }
           57  +  }
           58  +}
           59  +
           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  +foreach {k v} [lrange $argv 0 end-2] {
           65  +  switch -- $k {
           66  +    -colsize {
           67  +      set O(aColSize) $v
           68  +    }
           69  +
           70  +    -colsize {
           71  +      set O(aColSize) $v
           72  +    }
           73  +  }
           74  +
           75  +}
           76  +
           77  +sqlite3 db $O(db)
           78  +load_static_extension db fts5
           79  +
           80  +
           81  +# Create the FTS table in the db. Return a list of the table columns.
           82  +#
           83  +proc create_table {} {
           84  +  global O
           85  +  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]
           86  +
           87  +  set nCol [llength $O(aColsize)]
           88  +  set cols [lrange $cols 0 [expr $nCol-1]]
           89  +
           90  +  set sql    "CREATE VIRTUAL TABLE IF NOT EXISTS $O(tblname) USING $O(fts) ("
           91  +  append sql [join $cols ,]
           92  +  append sql ");"
           93  +
           94  +  db eval $sql
           95  +  return $cols
           96  +}
           97  +
           98  +# Return a list of tokens from the named file.
           99  +#
          100  +proc readfile {file} {
          101  +  set fd [open $file]
          102  +  set data [read $fd]
          103  +  close $fd
          104  +  split $data
          105  +}
          106  +
          107  +
          108  +# Load all the data into a big list of tokens.
          109  +#
          110  +set tokens [list]
          111  +foreach f $O(files) {
          112  +  set tokens [concat $tokens [readfile $f]]
          113  +}
          114  +
          115  +set N [llength $tokens]
          116  +set i 0
          117  +set cols [create_table]
          118  +set sql "INSERT INTO $O(tblname) VALUES(\$[lindex $cols 0]"
          119  +foreach c [lrange $cols 1 end] {
          120  +  append sql ", \$$c"
          121  +}
          122  +append sql ")"
          123  +
          124  +db eval BEGIN
          125  +  while {$i < $N} {
          126  +    foreach c $cols s $O(aColsize) {
          127  +      set $c [lrange $tokens $i [expr $i+$s-1]]
          128  +      incr i $s
          129  +    }
          130  +    db eval $sql
          131  +  }
          132  +db eval COMMIT
          133  +
          134  +
          135  +

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

     3      3   exec tclsh "$0" "$@"
     4      4   
     5      5   set srcdir [file dirname [file dirname [info script]]]
     6      6   set G(src) [string map [list %dir% $srcdir] {
     7      7     %dir%/fts5.h
     8      8     %dir%/fts5Int.h
     9      9     fts5parse.h
           10  +  fts5parse.c
    10     11     %dir%/fts5_aux.c
    11     12     %dir%/fts5_buffer.c
    12     13     %dir%/fts5_config.c
    13     14     %dir%/fts5_expr.c
    14     15     %dir%/fts5_hash.c
    15     16     %dir%/fts5_index.c
    16     17     %dir%/fts5_main.c
    17     18     %dir%/fts5_storage.c
    18     19     %dir%/fts5_tokenize.c
    19     20     %dir%/fts5_unicode2.c
    20     21     %dir%/fts5_varint.c
    21     22     %dir%/fts5_vocab.c
    22         -  fts5parse.c
    23     23   }]
    24     24   
    25     25   set G(hdr) {
    26     26   
    27         -#if !defined(SQLITE_TEST) || defined(SQLITE_ENABLE_FTS5) 
           27  +#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS5) 
    28     28   
    29     29   #if !defined(NDEBUG) && !defined(SQLITE_DEBUG) 
    30     30   # define NDEBUG 1
    31     31   #endif
    32     32   #if defined(NDEBUG) && defined(SQLITE_DEBUG)
    33     33   # undef NDEBUG
    34     34   #endif
    35     35   
    36     36   }
    37     37   
    38     38   set G(footer) {
    39     39       
    40         -#endif /* !defined(SQLITE_TEST) || defined(SQLITE_ENABLE_FTS5) */
           40  +#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS5) */
    41     41   }
    42     42   
    43     43   #-------------------------------------------------------------------------
    44     44   # Read and return the entire contents of text file $zFile from disk.
    45     45   #
    46     46   proc readfile {zFile} {
    47     47     set fd [open $zFile]
................................................................................
    83     83     set sub_map [list --FTS5-SOURCE-ID-- [fts5_source_id $::srcdir]]
    84     84     if {$zTail=="fts5parse.c"} {
    85     85       lappend sub_map yy fts5yy YY fts5YY TOKEN FTS5TOKEN
    86     86     }
    87     87   
    88     88     foreach line [split $data "\n"] {
    89     89       if {[regexp {^#include.*fts5} $line]} continue
    90         -    if {[regexp {^(const )?[a-zA-Z][a-zA-Z0-9]* [*]?sqlite3Fts5} $line]} {
           90  +    if { ![regexp { sqlite3Fts5Init\(} $line] 
           91  +       && [regexp {^(const )?[a-zA-Z][a-zA-Z0-9]* [*]?sqlite3Fts5} $line]
           92  +    } {
    91     93         set line "static $line"
    92     94       }
    93     95       set line [string map $sub_map $line]
    94     96       puts $G(fd) $line
    95     97     }
    96     98   }
    97     99   
................................................................................
   103    105     }
   104    106   }
   105    107   
   106    108   
   107    109   fts5c_init fts5.c
   108    110   foreach f $G(src) { fts5c_printfile $f }
   109    111   fts5c_close
   110         -
   111         -
   112         -
   113         -

Changes to ext/misc/json1.c.

    17     17   **
    18     18   ** For the time being, all JSON is stored as pure text.  (We might add
    19     19   ** a JSONB type in the future which stores a binary encoding of JSON in
    20     20   ** a BLOB, but there is no support for JSONB in the current implementation.
    21     21   ** This implementation parses JSON text at 250 MB/s, so it is hard to see
    22     22   ** how JSONB might improve on that.)
    23     23   */
           24  +#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_JSON1)
    24     25   #if !defined(_SQLITEINT_H_)
    25     26   #include "sqlite3ext.h"
    26     27   #endif
    27     28   SQLITE_EXTENSION_INIT1
    28     29   #include <assert.h>
    29     30   #include <string.h>
    30         -#include <ctype.h>
           31  +#include <ctype.h>  /* amalgamator: keep */
    31     32   #include <stdlib.h>
    32     33   #include <stdarg.h>
    33     34   
    34     35   #define UNUSED_PARAM(X)  (void)(X)
           36  +
           37  +#ifndef LARGEST_INT64
           38  +# define LARGEST_INT64  (0xffffffff|(((sqlite3_int64)0x7fffffff)<<32))
           39  +# define SMALLEST_INT64 (((sqlite3_int64)-1) - LARGEST_INT64)
           40  +#endif
    35     41   
    36     42   /*
    37     43   ** Versions of isspace(), isalnum() and isdigit() to which it is safe
    38     44   ** to pass signed char values.
    39     45   */
    40     46   #define safe_isdigit(x) isdigit((unsigned char)(x))
    41     47   #define safe_isalnum(x) isalnum((unsigned char)(x))
................................................................................
    61     67     0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
    62     68     0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
    63     69     0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
    64     70     0, 0, 0, 0, 0, 0, 0, 0,     0, 0, 0, 0, 0, 0, 0, 0,
    65     71   };
    66     72   #define safe_isspace(x) (jsonIsSpace[(unsigned char)x])
    67     73   
    68         -/* Unsigned integer types */
    69         -typedef sqlite3_uint64 u64;
    70         -typedef unsigned int u32;
    71         -typedef unsigned char u8;
           74  +#ifndef SQLITE_AMALGAMATION
           75  +  /* Unsigned integer types.  These are already defined in the sqliteInt.h,
           76  +  ** but the definitions need to be repeated for separate compilation. */
           77  +  typedef sqlite3_uint64 u64;
           78  +  typedef unsigned int u32;
           79  +  typedef unsigned char u8;
           80  +#endif
    72     81   
    73     82   /* Objects */
    74     83   typedef struct JsonString JsonString;
    75     84   typedef struct JsonNode JsonNode;
    76     85   typedef struct JsonParse JsonParse;
    77     86   
    78     87   /* An instance of this object represents a JSON string
................................................................................
   473    482         sqlite3_result_int(pCtx, 1);
   474    483         break;
   475    484       }
   476    485       case JSON_FALSE: {
   477    486         sqlite3_result_int(pCtx, 0);
   478    487         break;
   479    488       }
   480         -    case JSON_REAL: {
   481         -      double r = strtod(pNode->u.zJContent, 0);
   482         -      sqlite3_result_double(pCtx, r);
   483         -      break;
   484         -    }
   485    489       case JSON_INT: {
   486    490         sqlite3_int64 i = 0;
   487    491         const char *z = pNode->u.zJContent;
   488    492         if( z[0]=='-' ){ z++; }
   489         -      while( z[0]>='0' && z[0]<='9' ){ i = i*10 + *(z++) - '0'; }
          493  +      while( z[0]>='0' && z[0]<='9' ){
          494  +        unsigned v = *(z++) - '0';
          495  +        if( i>=LARGEST_INT64/10 ){
          496  +          if( i>LARGEST_INT64/10 ) goto int_as_real;
          497  +          if( z[0]>='0' && z[0]<='9' ) goto int_as_real;
          498  +          if( v==9 ) goto int_as_real;
          499  +          if( v==8 ){
          500  +            if( pNode->u.zJContent[0]=='-' ){
          501  +              sqlite3_result_int64(pCtx, SMALLEST_INT64);
          502  +              goto int_done;
          503  +            }else{
          504  +              goto int_as_real;
          505  +            }
          506  +          }
          507  +        }
          508  +        i = i*10 + v;
          509  +      }
   490    510         if( pNode->u.zJContent[0]=='-' ){ i = -i; }
   491    511         sqlite3_result_int64(pCtx, i);
          512  +      int_done:
          513  +      break;
          514  +      int_as_real: /* fall through to real */;
          515  +    }
          516  +    case JSON_REAL: {
          517  +      double r = strtod(pNode->u.zJContent, 0);
          518  +      sqlite3_result_double(pCtx, r);
   492    519         break;
   493    520       }
   494    521       case JSON_STRING: {
   495    522   #if 0 /* Never happens because JNODE_RAW is only set by json_set(),
   496    523         ** json_insert() and json_replace() and those routines do not
   497    524         ** call jsonReturn() */
   498    525         if( pNode->jnFlags & JNODE_RAW ){
................................................................................
   854    881     return SQLITE_OK;
   855    882   }
   856    883   
   857    884   /*
   858    885   ** Compare the OBJECT label at pNode against zKey,nKey.  Return true on
   859    886   ** a match.
   860    887   */
   861         -static int jsonLabelCompare(JsonNode *pNode, const char *zKey, int nKey){
          888  +static int jsonLabelCompare(JsonNode *pNode, const char *zKey, u32 nKey){
   862    889     if( pNode->jnFlags & JNODE_RAW ){
   863    890       if( pNode->n!=nKey ) return 0;
   864    891       return strncmp(pNode->u.zJContent, zKey, nKey)==0;
   865    892     }else{
   866    893       if( pNode->n!=nKey+2 ) return 0;
   867    894       return strncmp(pNode->u.zJContent+1, zKey, nKey)==0;
   868    895     }
................................................................................
  1933   1960     0,                         /* xSavepoint */
  1934   1961     0,                         /* xRelease */
  1935   1962     0                          /* xRollbackTo */
  1936   1963   };
  1937   1964   #endif /* SQLITE_OMIT_VIRTUALTABLE */
  1938   1965   
  1939   1966   /****************************************************************************
  1940         -** The following routine is the only publically visible identifier in this
  1941         -** file.  Call the following routine in order to register the various SQL
         1967  +** The following routines are the only publically visible identifiers in this
         1968  +** file.  Call the following routines in order to register the various SQL
  1942   1969   ** functions and the virtual table implemented by this file.
  1943   1970   ****************************************************************************/
  1944   1971   
  1945         -#ifdef _WIN32
  1946         -__declspec(dllexport)
  1947         -#endif
  1948         -int sqlite3_json_init(
  1949         -  sqlite3 *db, 
  1950         -  char **pzErrMsg, 
  1951         -  const sqlite3_api_routines *pApi
  1952         -){
         1972  +int sqlite3Json1Init(sqlite3 *db){
  1953   1973     int rc = SQLITE_OK;
  1954   1974     unsigned int i;
  1955   1975     static const struct {
  1956   1976        const char *zName;
  1957   1977        int nArg;
  1958   1978        int flag;
  1959   1979        void (*xFunc)(sqlite3_context*,int,sqlite3_value**);
................................................................................
  1983   2003        const char *zName;
  1984   2004        sqlite3_module *pModule;
  1985   2005     } aMod[] = {
  1986   2006       { "json_each",            &jsonEachModule               },
  1987   2007       { "json_tree",            &jsonTreeModule               },
  1988   2008     };
  1989   2009   #endif
  1990         -  SQLITE_EXTENSION_INIT2(pApi);
  1991         -  (void)pzErrMsg;  /* Unused parameter */
  1992   2010     for(i=0; i<sizeof(aFunc)/sizeof(aFunc[0]) && rc==SQLITE_OK; i++){
  1993   2011       rc = sqlite3_create_function(db, aFunc[i].zName, aFunc[i].nArg,
  1994   2012                                    SQLITE_UTF8 | SQLITE_DETERMINISTIC, 
  1995   2013                                    (void*)&aFunc[i].flag,
  1996   2014                                    aFunc[i].xFunc, 0, 0);
  1997   2015     }
  1998   2016   #ifndef SQLITE_OMIT_VIRTUALTABLE
  1999   2017     for(i=0; i<sizeof(aMod)/sizeof(aMod[0]) && rc==SQLITE_OK; i++){
  2000   2018       rc = sqlite3_create_module(db, aMod[i].zName, aMod[i].pModule, 0);
  2001   2019     }
  2002   2020   #endif
  2003   2021     return rc;
  2004   2022   }
         2023  +
         2024  +
         2025  +#ifndef SQLITE_CORE
         2026  +#ifdef _WIN32
         2027  +__declspec(dllexport)
         2028  +#endif
         2029  +int sqlite3_json_init(
         2030  +  sqlite3 *db, 
         2031  +  char **pzErrMsg, 
         2032  +  const sqlite3_api_routines *pApi
         2033  +){
         2034  +  SQLITE_EXTENSION_INIT2(pApi);
         2035  +  (void)pzErrMsg;  /* Unused parameter */
         2036  +  return sqlite3Json1Init(db);
         2037  +}
         2038  +#endif
         2039  +#endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_JSON1) */

Changes to ext/rbu/sqlite3rbu.c.

    84     84   #include <string.h>
    85     85   #include <stdio.h>
    86     86   
    87     87   #include "sqlite3.h"
    88     88   
    89     89   #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_RBU)
    90     90   #include "sqlite3rbu.h"
           91  +
           92  +#if defined(_WIN32_WCE)
           93  +#include "windows.h"
           94  +#endif
    91     95   
    92     96   /* Maximum number of prepared UPDATE statements held by this module */
    93     97   #define SQLITE_RBU_UPDATE_CACHESIZE 16
    94     98   
    95     99   /*
    96    100   ** Swap two objects of type TYPE.
    97    101   */
................................................................................
  2378   2382     assert( p->rc==SQLITE_OK );
  2379   2383     p->rc = pReal->pMethods->xLock(pReal, SQLITE_LOCK_SHARED);
  2380   2384     if( p->rc==SQLITE_OK ){
  2381   2385       p->rc = pReal->pMethods->xLock(pReal, SQLITE_LOCK_EXCLUSIVE);
  2382   2386     }
  2383   2387   }
  2384   2388   
         2389  +#if defined(_WIN32_WCE)
         2390  +static LPWSTR rbuWinUtf8ToUnicode(const char *zFilename){
         2391  +  int nChar;
         2392  +  LPWSTR zWideFilename;
         2393  +
         2394  +  nChar = MultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0);
         2395  +  if( nChar==0 ){
         2396  +    return 0;
         2397  +  }
         2398  +  zWideFilename = sqlite3_malloc( nChar*sizeof(zWideFilename[0]) );
         2399  +  if( zWideFilename==0 ){
         2400  +    return 0;
         2401  +  }
         2402  +  memset(zWideFilename, 0, nChar*sizeof(zWideFilename[0]));
         2403  +  nChar = MultiByteToWideChar(CP_UTF8, 0, zFilename, -1, zWideFilename,
         2404  +                                nChar);
         2405  +  if( nChar==0 ){
         2406  +    sqlite3_free(zWideFilename);
         2407  +    zWideFilename = 0;
         2408  +  }
         2409  +  return zWideFilename;
         2410  +}
         2411  +#endif
         2412  +
  2385   2413   /*
  2386   2414   ** The RBU handle is currently in RBU_STAGE_OAL state, with a SHARED lock
  2387   2415   ** on the database file. This proc moves the *-oal file to the *-wal path,
  2388   2416   ** then reopens the database file (this time in vanilla, non-oal, WAL mode).
  2389   2417   ** If an error occurs, leave an error code and error message in the rbu 
  2390   2418   ** handle.
  2391   2419   */
................................................................................
  2412   2440         rbuFileSuffix3(zBase, zWal);
  2413   2441         rbuFileSuffix3(zBase, zOal);
  2414   2442   
  2415   2443         /* Re-open the databases. */
  2416   2444         rbuObjIterFinalize(&p->objiter);
  2417   2445         sqlite3_close(p->dbMain);
  2418   2446         sqlite3_close(p->dbRbu);
         2447  +      p->dbMain = 0;
         2448  +      p->dbRbu = 0;
         2449  +
         2450  +#if defined(_WIN32_WCE)
         2451  +      {
         2452  +        LPWSTR zWideOal;
         2453  +        LPWSTR zWideWal;
         2454  +
         2455  +        zWideOal = rbuWinUtf8ToUnicode(zOal);
         2456  +        if( zWideOal ){
         2457  +          zWideWal = rbuWinUtf8ToUnicode(zWal);
         2458  +          if( zWideWal ){
         2459  +            if( MoveFileW(zWideOal, zWideWal) ){
         2460  +              p->rc = SQLITE_OK;
         2461  +            }else{
         2462  +              p->rc = SQLITE_IOERR;
         2463  +            }
         2464  +            sqlite3_free(zWideWal);
         2465  +          }else{
         2466  +            p->rc = SQLITE_IOERR_NOMEM;
         2467  +          }
         2468  +          sqlite3_free(zWideOal);
         2469  +        }else{
         2470  +          p->rc = SQLITE_IOERR_NOMEM;
         2471  +        }
         2472  +      }
         2473  +#else
  2419   2474         p->rc = rename(zOal, zWal) ? SQLITE_IOERR : SQLITE_OK;
         2475  +#endif
         2476  +
  2420   2477         if( p->rc==SQLITE_OK ){
  2421         -        p->dbMain = 0;
  2422         -        p->dbRbu = 0;
  2423   2478           rbuOpenDatabase(p);
  2424   2479           rbuSetupCheckpoint(p, 0);
  2425   2480         }
  2426   2481       }
  2427   2482     }
  2428   2483   
  2429   2484     sqlite3_free(zWal);

Changes to ext/rbu/sqlite3rbu.h.

   264    264   ** the suspended RBU update is also an error (SQLITE_BUSY).
   265    265   */
   266    266   
   267    267   #ifndef _SQLITE3RBU_H
   268    268   #define _SQLITE3RBU_H
   269    269   
   270    270   #include "sqlite3.h"              /* Required for error code definitions */
          271  +
          272  +#ifdef __cplusplus
          273  +extern "C" {
          274  +#endif
   271    275   
   272    276   typedef struct sqlite3rbu sqlite3rbu;
   273    277   
   274    278   /*
   275    279   ** Open an RBU handle.
   276    280   **
   277    281   ** Argument zTarget is the path to the target database. Argument zRbu is
................................................................................
   442    446   ** sqlite3rbu_create_vfs().
   443    447   **
   444    448   ** VFS objects are not reference counted. If a VFS object is destroyed
   445    449   ** before all database handles that use it have been closed, the results
   446    450   ** are undefined.
   447    451   */
   448    452   void sqlite3rbu_destroy_vfs(const char *zName);
          453  +
          454  +#ifdef __cplusplus
          455  +}  /* end of the 'extern "C"' block */
          456  +#endif
   449    457   
   450    458   #endif /* _SQLITE3RBU_H */

Changes to ext/rtree/rtree1.test.

    30     30   #   rtree-5.*: Test DELETE
    31     31   #   rtree-6.*: Test UPDATE
    32     32   #   rtree-7.*: Test renaming an r-tree table.
    33     33   #   rtree-8.*: Test constrained scans of r-tree data.
    34     34   #
    35     35   #   rtree-12.*: Test that on-conflict clauses are supported.
    36     36   #   rtree-13.*: Test that bug [d2889096e7bdeac6d] has been fixed.
           37  +#   rtree-14.*: Test if a non-integer is inserted into the PK column of an
           38  +#               r-tree table, it is converted to an integer before being
           39  +#               inserted. Also that if a non-numeric is inserted into one
           40  +#               of the min/max dimension columns, it is converted to the
           41  +#               required type before being inserted.
    37     42   #
    38     43   
    39     44   ifcapable !rtree {
    40     45     finish_test
    41     46     return
    42     47   }
    43     48   
................................................................................
   530    535     WITH r(x) AS (
   531    536       SELECT 1 UNION ALL
   532    537       SELECT 2 UNION ALL
   533    538       SELECT 3
   534    539     )
   535    540     SELECT * FROM r CROSS JOIN t9 WHERE id=x;
   536    541   } {1 1 0.0 0.0 2 2 0.0 0.0}
          542  +
          543  +#-------------------------------------------------------------------------
          544  +# Test if a non-integer is inserted into the PK column of an r-tree
          545  +# table, it is converted to an integer before being inserted. Also
          546  +# that if a non-numeric is inserted into one of the min/max dimension
          547  +# columns, it is converted to the required type before being inserted.
          548  +#
          549  +do_execsql_test 14.1 {
          550  +  CREATE VIRTUAL TABLE t10 USING rtree(ii, x1, x2);
          551  +}
          552  +
          553  +do_execsql_test 14.2 {
          554  +  INSERT INTO t10 VALUES(NULL,   1, 2);
          555  +  INSERT INTO t10 VALUES(NULL,   2, 3);
          556  +  INSERT INTO t10 VALUES('4xxx', 3, 4);
          557  +  INSERT INTO t10 VALUES(5.0,    4, 5);
          558  +  INSERT INTO t10 VALUES(6.4,    5, 6);
          559  +}
          560  +do_execsql_test 14.3 {
          561  +  SELECT * FROM t10;
          562  +} {
          563  +  1 1.0 2.0   2 2.0 3.0   4 3.0 4.0   5 4.0 5.0   6 5.0 6.0
          564  +}
          565  +
          566  +do_execsql_test 14.4 {
          567  +  DELETE FROM t10;
          568  +  INSERT INTO t10 VALUES(1, 'one', 'two');
          569  +  INSERT INTO t10 VALUES(2, '52xyz', '81...');
          570  +}
          571  +do_execsql_test 14.5 {
          572  +  SELECT * FROM t10;
          573  +} {
          574  +  1 0.0 0.0
          575  +  2 52.0 81.0
          576  +}
          577  +
          578  +do_execsql_test 14.4 {
          579  +  DROP TABLE t10;
          580  +  CREATE VIRTUAL TABLE t10 USING rtree_i32(ii, x1, x2);
          581  +  INSERT INTO t10 VALUES(1, 'one', 'two');
          582  +  INSERT INTO t10 VALUES(2, '52xyz', '81...');
          583  +  INSERT INTO t10 VALUES(3, 42.3, 49.9);
          584  +}
          585  +do_execsql_test 14.5 {
          586  +  SELECT * FROM t10;
          587  +} {
          588  +  1 0 0
          589  +  2 52 81
          590  +  3 42 49
          591  +}
   537    592   
   538    593   finish_test

Changes to main.mk.

     7      7   #                  "configure.in" script.
     8      8   #
     9      9   # BCC              C Compiler and options for use in building executables that
    10     10   #                  will run on the platform that is doing the build.
    11     11   #
    12     12   # THREADLIB        Specify any extra linker options needed to make the library
    13     13   #                  thread safe
           14  +#
           15  +# LIBS             Extra libraries options
    14     16   #
    15     17   # OPTS             Extra compiler command-line options.
    16     18   #
    17     19   # EXE              The suffix to add to executable files.  ".exe" for windows
    18     20   #                  and "" for Unix.
    19     21   #
    20     22   # TCC              C Compiler and options for use in building executables that 
................................................................................
    31     33   #
    32     34   # READLINE_FLAGS   Compiler options needed for programs that use the
    33     35   #                  readline() library.
    34     36   #
    35     37   # LIBREADLINE      Linker options needed by programs using readline() must
    36     38   #                  link against.
    37     39   #
    38         -# NAWK             Nawk compatible awk program.  Older (obsolete?) solaris
    39         -#                  systems need this to avoid using the original AT&T AWK.
    40         -#
    41     40   # Once the macros above are defined, the rest of this make script will
    42     41   # build the SQLite library and testing tools.
    43     42   ################################################################################
    44     43   
    45     44   # This is how we compile
    46     45   #
    47     46   TCCX =  $(TCC) $(OPTS) -I. -I$(TOP)/src -I$(TOP) 
    48     47   TCCX += -I$(TOP)/ext/rtree -I$(TOP)/ext/icu -I$(TOP)/ext/fts3
    49     48   TCCX += -I$(TOP)/ext/async -I$(TOP)/ext/userauth
    50     49   TCCX += -I$(TOP)/ext/fts5
           50  +THREADLIB += $(LIBS)
    51     51   
    52     52   # Object files for the SQLite library.
    53     53   #
    54     54   LIBOBJ+= vdbe.o parse.o \
    55     55            alter.o analyze.o attach.o auth.o \
    56     56            backup.o bitvec.o btmutex.o btree.o build.o \
    57         -         callback.o complete.o ctime.o date.o dbstat.o delete.o expr.o fault.o fkey.o \
           57  +         callback.o complete.o ctime.o date.o dbstat.o delete.o expr.o \
           58  +	 fault.o fkey.o \
    58     59            fts3.o fts3_aux.o fts3_expr.o fts3_hash.o fts3_icu.o fts3_porter.o \
    59     60            fts3_snippet.o fts3_tokenizer.o fts3_tokenizer1.o \
    60     61            fts3_tokenize_vtab.o \
    61     62   	 fts3_unicode.o fts3_unicode2.o \
    62         -         fts3_write.o func.o global.o hash.o \
    63         -         icu.o insert.o journal.o legacy.o loadext.o \
           63  +         fts3_write.o fts5.o func.o global.o hash.o \
           64  +         icu.o insert.o journal.o json1.o legacy.o loadext.o \
    64     65            main.o malloc.o mem0.o mem1.o mem2.o mem3.o mem5.o \
    65     66            memjournal.o \
    66     67            mutex.o mutex_noop.o mutex_unix.o mutex_w32.o \
    67     68            notify.o opcodes.o os.o os_unix.o os_win.o \
    68     69            pager.o pcache.o pcache1.o pragma.o prepare.o printf.o \
    69     70            random.o resolve.o rowset.o rtree.o select.o sqlite3rbu.o status.o \
    70     71            table.o threads.o tokenize.o treeview.o trigger.o \
................................................................................
   221    222   SRC += \
   222    223     $(TOP)/ext/rtree/sqlite3rtree.h \
   223    224     $(TOP)/ext/rtree/rtree.h \
   224    225     $(TOP)/ext/rtree/rtree.c
   225    226   SRC += \
   226    227     $(TOP)/ext/userauth/userauth.c \
   227    228     $(TOP)/ext/userauth/sqlite3userauth.h 
   228         -
   229    229   SRC += \
   230    230     $(TOP)/ext/rbu/sqlite3rbu.c \
   231    231     $(TOP)/ext/rbu/sqlite3rbu.h
          232  +SRC += \
          233  +  $(TOP)/ext/misc/json1.c
   232    234   
   233    235   
   234    236   # FTS5 things
   235    237   #
   236    238   FTS5_HDR = \
   237    239      $(TOP)/ext/fts5/fts5.h \
   238    240      $(TOP)/ext/fts5/fts5Int.h \
................................................................................
   317    319   TESTSRC += \
   318    320     $(TOP)/ext/misc/amatch.c \
   319    321     $(TOP)/ext/misc/closure.c \
   320    322     $(TOP)/ext/misc/eval.c \
   321    323     $(TOP)/ext/misc/fileio.c \
   322    324     $(TOP)/ext/misc/fuzzer.c \
   323    325     $(TOP)/ext/misc/ieee754.c \
   324         -  $(TOP)/ext/misc/json1.c \
   325    326     $(TOP)/ext/misc/nextchar.c \
   326    327     $(TOP)/ext/misc/percentile.c \
   327    328     $(TOP)/ext/misc/regexp.c \
   328    329     $(TOP)/ext/misc/series.c \
   329    330     $(TOP)/ext/misc/spellfix.c \
   330    331     $(TOP)/ext/misc/totype.c \
   331    332     $(TOP)/ext/misc/wholenumber.c \
   332    333     $(TOP)/ext/misc/vfslog.c \
   333    334     $(TOP)/ext/fts5/fts5_tcl.c \
   334         -  $(TOP)/ext/fts5/fts5_test_mi.c \
   335         -  fts5.c
          335  +  $(TOP)/ext/fts5/fts5_test_mi.c
   336    336   
   337    337   
   338    338   #TESTSRC += $(TOP)/ext/fts2/fts2_tokenizer.c
   339    339   #TESTSRC += $(TOP)/ext/fts3/fts3_tokenizer.c
   340    340   
   341    341   TESTSRC2 = \
   342    342     $(TOP)/src/attach.c \
................................................................................
   375    375     $(TOP)/src/whereexpr.c \
   376    376     parse.c \
   377    377     $(TOP)/ext/fts3/fts3.c \
   378    378     $(TOP)/ext/fts3/fts3_aux.c \
   379    379     $(TOP)/ext/fts3/fts3_expr.c \
   380    380     $(TOP)/ext/fts3/fts3_tokenizer.c \
   381    381     $(TOP)/ext/fts3/fts3_write.c \
   382         -  $(TOP)/ext/async/sqlite3async.c 
          382  +  $(TOP)/ext/async/sqlite3async.c
   383    383   
   384    384   # Header files used by all library source files.
   385    385   #
   386    386   HDR = \
   387    387      $(TOP)/src/btree.h \
   388    388      $(TOP)/src/btreeInt.h \
   389    389      $(TOP)/src/hash.h \
................................................................................
   447    447   #
   448    448   FUZZDATA = \
   449    449     $(TOP)/test/fuzzdata1.db \
   450    450     $(TOP)/test/fuzzdata2.db \
   451    451     $(TOP)/test/fuzzdata3.db \
   452    452     $(TOP)/test/fuzzdata4.db
   453    453   
   454         -# Extra arguments for including json1 in the build of tools
   455         -#
   456         -JSON1_DEP = $(TOP)/ext/misc/json1.c sqlite3ext.h
   457         -JSON1_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_CORE
   458         -JSON1_SRC = $(TOP)/ext/misc/json1.c
   459         -
   460    454   # Standard options to testfixture
   461    455   #
   462    456   TESTOPTS = --verbose=file --output=test-out.txt
          457  +
          458  +# Extra compiler options for various shell tools
          459  +#
          460  +SHELL_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS5
          461  +FUZZERSHELL_OPT = -DSQLITE_ENABLE_JSON1
          462  +FUZZCHECK_OPT = -DSQLITE_ENABLE_JSON1
   463    463   
   464    464   # This is the default Makefile target.  The objects listed here
   465    465   # are what get build when you type just "make" with no arguments.
   466    466   #
   467    467   all:	sqlite3.h libsqlite3.a sqlite3$(EXE)
   468    468   
   469    469   libsqlite3.a:	$(LIBOBJ)
   470    470   	$(AR) libsqlite3.a $(LIBOBJ)
   471    471   	$(RANLIB) libsqlite3.a
   472    472   
   473         -sqlite3$(EXE):	$(TOP)/src/shell.c libsqlite3.a sqlite3.h $(JSON1_DEP)
   474         -	$(TCCX) $(READLINE_FLAGS) $(JSON1_OPT) -o sqlite3$(EXE)  \
   475         -		$(TOP)/src/shell.c $(JSON1_SRC) \
   476         -		libsqlite3.a $(LIBREADLINE) $(TLIBS) $(THREADLIB)
          473  +sqlite3$(EXE):	$(TOP)/src/shell.c libsqlite3.a sqlite3.h
          474  +	$(TCCX) $(READLINE_FLAGS) -o sqlite3$(EXE) $(SHELL_OPT) \
          475  +		$(TOP)/src/shell.c libsqlite3.a $(LIBREADLINE) $(TLIBS) $(THREADLIB)
   477    476   
   478    477   sqldiff$(EXE):	$(TOP)/tool/sqldiff.c sqlite3.c sqlite3.h
   479    478   	$(TCCX) -o sqldiff$(EXE) -DSQLITE_THREADSAFE=0 \
   480    479   		$(TOP)/tool/sqldiff.c sqlite3.c $(TLIBS) $(THREADLIB)
   481    480   
   482         -fuzzershell$(EXE):	$(TOP)/tool/fuzzershell.c sqlite3.c sqlite3.h $(JSON1_DEP)
          481  +fuzzershell$(EXE):	$(TOP)/tool/fuzzershell.c sqlite3.c sqlite3.h
   483    482   	$(TCCX) -o fuzzershell$(EXE) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \
   484         -	  $(JSON1_OPT)	$(TOP)/tool/fuzzershell.c $(JSON1_SRC) sqlite3.c \
          483  +	  $(FUZZERSHELL_OPT) $(TOP)/tool/fuzzershell.c sqlite3.c \
   485    484   	  $(TLIBS) $(THREADLIB)
   486    485   
   487         -fuzzcheck$(EXE):	$(TOP)/test/fuzzcheck.c sqlite3.c sqlite3.h $(JSON1_DEP)
          486  +fuzzcheck$(EXE):	$(TOP)/test/fuzzcheck.c sqlite3.c sqlite3.h
   488    487   	$(TCCX) -o fuzzcheck$(EXE) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \
   489         -		-DSQLITE_ENABLE_MEMSYS5 $(JSON1_OPT) \
   490         -		$(TOP)/test/fuzzcheck.c $(JSON1_SRC) sqlite3.c $(TLIBS) $(THREADLIB)
          488  +		-DSQLITE_ENABLE_MEMSYS5 $(FUZZCHECK_OPT) \
          489  +		$(TOP)/test/fuzzcheck.c sqlite3.c $(TLIBS) $(THREADLIB)
   491    490   
   492    491   mptester$(EXE):	sqlite3.c $(TOP)/mptest/mptest.c
   493    492   	$(TCCX) -o $@ -I. $(TOP)/mptest/mptest.c sqlite3.c \
   494    493   		$(TLIBS) $(THREADLIB)
   495    494   
   496    495   MPTEST1=./mptester$(EXE) mptest.db $(TOP)/mptest/crash01.test --repeat 20
   497    496   MPTEST2=./mptester$(EXE) mptest.db $(TOP)/mptest/multiwrite01.test --repeat 20
................................................................................
   511    510   
   512    511   # This target creates a directory named "tsrc" and fills it with
   513    512   # copies of all of the C source code and header files needed to
   514    513   # build on the target system.  Some of the C source code and header
   515    514   # files are automatically generated.  This target takes care of
   516    515   # all that automatic generation.
   517    516   #
   518         -target_source:	$(SRC) $(TOP)/tool/vdbe-compress.tcl
          517  +target_source:	$(SRC) $(TOP)/tool/vdbe-compress.tcl fts5.c
   519    518   	rm -rf tsrc
   520    519   	mkdir tsrc
   521    520   	cp -f $(SRC) tsrc
   522    521   	rm tsrc/sqlite.h.in tsrc/parse.y
   523    522   	tclsh $(TOP)/tool/vdbe-compress.tcl $(OPTS) <tsrc/vdbe.c >vdbe.new
   524    523   	mv vdbe.new tsrc/vdbe.c
          524  +	cp fts5.c fts5.h tsrc
   525    525   	touch target_source
   526    526   
   527    527   sqlite3.c:	target_source $(TOP)/tool/mksqlite3c.tcl
   528    528   	tclsh $(TOP)/tool/mksqlite3c.tcl
   529    529   	cp tsrc/shell.c tsrc/sqlite3ext.h .
   530    530   	echo '#ifndef USE_SYSTEM_SQLITE' >tclsqlite3.c
   531    531   	cat sqlite3.c >>tclsqlite3.c
   532    532   	echo '#endif /* USE_SYSTEM_SQLITE */' >>tclsqlite3.c
   533    533   	cat $(TOP)/src/tclsqlite.c >>tclsqlite3.c
          534  +
          535  +sqlite3ext.h:	target_source
          536  +	cp tsrc/sqlite3ext.h .
   534    537   
   535    538   sqlite3.c-debug:	target_source $(TOP)/tool/mksqlite3c.tcl
   536    539   	tclsh $(TOP)/tool/mksqlite3c.tcl --linemacros
   537    540   	echo '#ifndef USE_SYSTEM_SQLITE' >tclsqlite3.c
   538    541   	cat sqlite3.c >>tclsqlite3.c
   539    542   	echo '#endif /* USE_SYSTEM_SQLITE */' >>tclsqlite3.c
   540    543   	echo '#line 1 "tclsqlite.c"' >>tclsqlite3.c
................................................................................
   572    575   tclsqlite.o:	$(TOP)/src/tclsqlite.c $(HDR)
   573    576   	$(TCCX) $(TCL_FLAGS) -c $(TOP)/src/tclsqlite.c
   574    577   
   575    578   
   576    579   
   577    580   # Rules to build opcodes.c and opcodes.h
   578    581   #
   579         -opcodes.c:	opcodes.h $(TOP)/mkopcodec.awk
   580         -	$(NAWK) -f $(TOP)/mkopcodec.awk opcodes.h >opcodes.c
          582  +opcodes.c:	opcodes.h $(TOP)/tool/mkopcodec.tcl
          583  +	tclsh $(TOP)/tool/mkopcodec.tcl opcodes.h >opcodes.c
   581    584   
   582         -opcodes.h:	parse.h $(TOP)/src/vdbe.c $(TOP)/mkopcodeh.awk
          585  +opcodes.h:	parse.h $(TOP)/src/vdbe.c $(TOP)/tool/mkopcodeh.tcl
   583    586   	cat parse.h $(TOP)/src/vdbe.c | \
   584         -		$(NAWK) -f $(TOP)/mkopcodeh.awk >opcodes.h
          587  +		tclsh $(TOP)/tool/mkopcodeh.tcl >opcodes.h
   585    588   
   586    589   # Rules to build parse.c and parse.h - the outputs of lemon.
   587    590   #
   588    591   parse.h:	parse.c
   589    592   
   590         -parse.c:	$(TOP)/src/parse.y lemon $(TOP)/addopcodes.awk
          593  +parse.c:	$(TOP)/src/parse.y lemon $(TOP)/tool/addopcodes.tcl
   591    594   	cp $(TOP)/src/parse.y .
   592    595   	rm -f parse.h
   593    596   	./lemon -s $(OPTS) parse.y
   594    597   	mv parse.h parse.h.temp
   595         -	$(NAWK) -f $(TOP)/addopcodes.awk parse.h.temp >parse.h
          598  +	tclsh $(TOP)/tool/addopcodes.tcl parse.h.temp >parse.h
   596    599   
   597    600   sqlite3.h:	$(TOP)/src/sqlite.h.in $(TOP)/manifest.uuid $(TOP)/VERSION $(TOP)/ext/rtree/sqlite3rtree.h
   598    601   	tclsh $(TOP)/tool/mksqlite3h.tcl $(TOP) >sqlite3.h
   599    602   
   600    603   keywordhash.h:	$(TOP)/tool/mkkeywordhash.c
   601    604   	$(BCC) -o mkkeywordhash $(OPTS) $(TOP)/tool/mkkeywordhash.c
   602    605   	./mkkeywordhash >keywordhash.h
................................................................................
   661    664   
   662    665   fts3_unicode2.o:	$(TOP)/ext/fts3/fts3_unicode2.c $(HDR) $(EXTHDR)
   663    666   	$(TCCX) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_unicode2.c
   664    667   
   665    668   fts3_write.o:	$(TOP)/ext/fts3/fts3_write.c $(HDR) $(EXTHDR)
   666    669   	$(TCCX) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_write.c
   667    670   
          671  +fts5.o:	fts5.c
          672  +	$(TCCX) -DSQLITE_CORE -c fts5.c
          673  +
          674  +json1.o:	$(TOP)/ext/misc/json1.c
          675  +	$(TCCX) -DSQLITE_CORE -c $(TOP)/ext/misc/json1.c
          676  +
   668    677   rtree.o:	$(TOP)/ext/rtree/rtree.c $(HDR) $(EXTHDR)
   669    678   	$(TCCX) -DSQLITE_CORE -c $(TOP)/ext/rtree/rtree.c
          679  +
          680  +
   670    681   
   671    682   fts5parse.c:	$(TOP)/ext/fts5/fts5parse.y lemon 
   672    683   	cp $(TOP)/ext/fts5/fts5parse.y .
   673    684   	rm -f fts5parse.h
   674    685   	./lemon $(OPTS) fts5parse.y
   675    686   
   676    687   fts5parse.h: fts5parse.c
................................................................................
   694    705   
   695    706   sqlite3_analyzer.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/spaceanal.tcl
   696    707   	echo "#define TCLSH 2" > $@
   697    708   	echo "#define SQLITE_ENABLE_DBSTAT_VTAB 1" >> $@
   698    709   	cat sqlite3.c $(TOP)/src/tclsqlite.c >> $@
   699    710   	echo "static const char *tclsh_main_loop(void){" >> $@
   700    711   	echo "static const char *zMainloop = " >> $@
   701         -	$(NAWK) -f $(TOP)/tool/tostr.awk $(TOP)/tool/spaceanal.tcl >> $@
          712  +	tclsh $(TOP)/tool/tostr.tcl $(TOP)/tool/spaceanal.tcl >> $@
   702    713   	echo "; return zMainloop; }" >> $@
   703    714   
   704    715   sqlite3_analyzer$(EXE): sqlite3_analyzer.c
   705    716   	$(TCCX) $(TCL_FLAGS) sqlite3_analyzer.c -o $@ $(LIBTCL) $(THREADLIB) 
   706    717   
   707    718   # Rules to build the 'testfixture' application.
   708    719   #
................................................................................
   710    721   TESTFIXTURE_FLAGS += -DSQLITE_SERVER=1 -DSQLITE_PRIVATE="" -DSQLITE_CORE 
   711    722   
   712    723   testfixture$(EXE): $(TESTSRC2) libsqlite3.a $(TESTSRC) $(TOP)/src/tclsqlite.c
   713    724   	$(TCCX) $(TCL_FLAGS) -DTCLSH=1 $(TESTFIXTURE_FLAGS)                  \
   714    725   		$(TESTSRC) $(TESTSRC2) $(TOP)/src/tclsqlite.c                \
   715    726   		-o testfixture$(EXE) $(LIBTCL) libsqlite3.a $(THREADLIB)
   716    727   
   717         -amalgamation-testfixture$(EXE): sqlite3.c fts5.c $(TESTSRC) $(TOP)/src/tclsqlite.c
          728  +amalgamation-testfixture$(EXE): sqlite3.c $(TESTSRC) $(TOP)/src/tclsqlite.c
   718    729   	$(TCCX) $(TCL_FLAGS) -DTCLSH=1 $(TESTFIXTURE_FLAGS)                  \
   719         -		$(TESTSRC) $(TOP)/src/tclsqlite.c sqlite3.c fts5.c           \
          730  +		$(TESTSRC) $(TOP)/src/tclsqlite.c sqlite3.c                  \
   720    731   		-o testfixture$(EXE) $(LIBTCL) $(THREADLIB)
   721    732   
   722    733   fts3-testfixture$(EXE): sqlite3.c fts3amal.c $(TESTSRC) $(TOP)/src/tclsqlite.c
   723    734   	$(TCCX) $(TCL_FLAGS) -DTCLSH=1 $(TESTFIXTURE_FLAGS)                  \
   724    735   	-DSQLITE_ENABLE_FTS3=1                                               \
   725    736   		$(TESTSRC) $(TOP)/src/tclsqlite.c sqlite3.c fts3amal.c       \
   726    737   		-o testfixture$(EXE) $(LIBTCL) $(THREADLIB)

Deleted mkopcodec.awk.

     1         -#!/usr/bin/awk -f
     2         -#
     3         -# This AWK script scans the opcodes.h file (which is itself generated by
     4         -# another awk script) and uses the information gleaned to create the
     5         -# opcodes.c source file.
     6         -#
     7         -# Opcodes.c contains strings which are the symbolic names for the various
     8         -# opcodes used by the VDBE.  These strings are used when disassembling a
     9         -# VDBE program during tracing or as a result of the EXPLAIN keyword.
    10         -#
    11         -BEGIN {
    12         -  print "/* Automatically generated.  Do not edit */"
    13         -  print "/* See the mkopcodec.awk script for details. */"
    14         -  printf "#if !defined(SQLITE_OMIT_EXPLAIN)"
    15         -  printf    " || defined(VDBE_PROFILE)"
    16         -  print     " || defined(SQLITE_DEBUG)"
    17         -  print "#if defined(SQLITE_ENABLE_EXPLAIN_COMMENTS) || defined(SQLITE_DEBUG)"
    18         -  print "# define OpHelp(X) \"\\0\" X"
    19         -  print "#else"
    20         -  print "# define OpHelp(X)"
    21         -  print "#endif"
    22         -  print "const char *sqlite3OpcodeName(int i){"
    23         -  print " static const char *const azName[] = { \"?\","
    24         -  mx = 0
    25         -}
    26         -/^.define OP_/ {
    27         -  sub("OP_","",$2)
    28         -  i = $3+0
    29         -  label[i] = $2
    30         -  if( mx<i ) mx = i
    31         -  for(j=5; j<NF; j++) if( $j=="synopsis:" ) break
    32         -  if( j<NF ){
    33         -    j++
    34         -    x = $j
    35         -    for(j=j+1; j<NF; j++) x = x " " $j
    36         -    synopsis[i] = x
    37         -  }else{
    38         -    synopsis[i] = ""
    39         -  }
    40         -}
    41         -END {
    42         -  for(i=1; i<=mx; i++){
    43         -    printf "     /* %3d */ %-18s OpHelp(\"%s\"),\n", i, \
    44         -        "\"" label[i] "\"", synopsis[i]
    45         -  }
    46         -  print "  };"
    47         -  print "  return azName[i];"
    48         -  print "}"
    49         -  print "#endif"
    50         -}

Deleted mkopcodeh.awk.

     1         -#!/usr/bin/awk -f
     2         -#
     3         -# Generate the file opcodes.h.
     4         -#
     5         -# This AWK script scans a concatenation of the parse.h output file from the
     6         -# parser and the vdbe.c source file in order to generate the opcodes numbers
     7         -# for all opcodes.  
     8         -#
     9         -# The lines of the vdbe.c that we are interested in are of the form:
    10         -#
    11         -#       case OP_aaaa:      /* same as TK_bbbbb */
    12         -#
    13         -# The TK_ comment is optional.  If it is present, then the value assigned to
    14         -# the OP_ is the same as the TK_ value.  If missing, the OP_ value is assigned
    15         -# a small integer that is different from every other OP_ value.
    16         -#
    17         -# We go to the trouble of making some OP_ values the same as TK_ values
    18         -# as an optimization.  During parsing, things like expression operators
    19         -# are coded with TK_ values such as TK_ADD, TK_DIVIDE, and so forth.  Later
    20         -# during code generation, we need to generate corresponding opcodes like
    21         -# OP_Add and OP_Divide.  By making TK_ADD==OP_Add and TK_DIVIDE==OP_Divide,
    22         -# code to translate from one to the other is avoided.  This makes the
    23         -# code generator run (infinitesimally) faster and more importantly it makes
    24         -# the library footprint smaller.
    25         -#
    26         -# This script also scans for lines of the form:
    27         -#
    28         -#       case OP_aaaa:       /* jump, in1, in2, in3, out2-prerelease, out3 */
    29         -#
    30         -# When such comments are found on an opcode, it means that certain
    31         -# properties apply to that opcode.  Set corresponding flags using the
    32         -# OPFLG_INITIALIZER macro.
    33         -#
    34         -
    35         -
    36         -# Remember the TK_ values from the parse.h file
    37         -/^#define TK_/ {
    38         -  tk[$2] = 0+$3    # tk[x] holds the numeric value for TK symbol X
    39         -}
    40         -
    41         -# Find "/* Opcode: " lines in the vdbe.c file.  Each one introduces
    42         -# a new opcode.  Remember which parameters are used.
    43         -/^.. Opcode: / {
    44         -  currentOp = "OP_" $3
    45         -  m = 0
    46         -  for(i=4; i<=NF; i++){
    47         -    x = $i
    48         -    if( x=="P1" ) m += 1
    49         -    if( x=="P2" ) m += 2
    50         -    if( x=="P3" ) m += 4
    51         -    if( x=="P4" ) m += 8
    52         -    if( x=="P5" ) m += 16
    53         -  }
    54         -  paramused[currentOp] = m
    55         -}
    56         -
    57         -# Find "** Synopsis: " lines that follow Opcode:
    58         -/^.. Synopsis: / {
    59         -  if( currentOp ){
    60         -    x = $3
    61         -    for(i=4; i<=NF; i++){
    62         -      x = x " " $i
    63         -    }
    64         -    synopsis[currentOp] = x
    65         -  }
    66         -}
    67         -
    68         -# Scan for "case OP_aaaa:" lines in the vdbe.c file
    69         -/^case OP_/ {
    70         -  name = $2
    71         -  sub(/:/,"",name)
    72         -  sub("\r","",name)
    73         -  op[name] = -1       # op[x] holds the numeric value for OP symbol x
    74         -  jump[name] = 0
    75         -  in1[name] = 0
    76         -  in2[name] = 0
    77         -  in3[name] = 0
    78         -  out2[name] = 0
    79         -  out3[name] = 0
    80         -  for(i=3; i<NF; i++){
    81         -    if($i=="same" && $(i+1)=="as"){
    82         -      sym = $(i+2)
    83         -      sub(/,/,"",sym)
    84         -      val = tk[sym]
    85         -      op[name] = val
    86         -      used[val] = 1
    87         -      sameas[val] = sym
    88         -      def[val] = name
    89         -    }
    90         -    x = $i
    91         -    sub(",","",x)
    92         -    if(x=="jump"){
    93         -      jump[name] = 1
    94         -    }else if(x=="in1"){
    95         -      in1[name] = 1
    96         -    }else if(x=="in2"){
    97         -      in2[name] = 1
    98         -    }else if(x=="in3"){
    99         -      in3[name] = 1
   100         -    }else if(x=="out2"){
   101         -      out2[name] = 1
   102         -    }else if(x=="out3"){
   103         -      out3[name] = 1
   104         -    }
   105         -  }
   106         -  order[n_op++] = name;
   107         -}
   108         -
   109         -# Assign numbers to all opcodes and output the result.
   110         -END {
   111         -  cnt = 0
   112         -  max = 0
   113         -  print "/* Automatically generated.  Do not edit */"
   114         -  print "/* See the mkopcodeh.awk script for details */"
   115         -  op["OP_Noop"] = -1;
   116         -  order[n_op++] = "OP_Noop";
   117         -  op["OP_Explain"] = -1;
   118         -  order[n_op++] = "OP_Explain";
   119         -
   120         -  # Assign small values to opcodes that are processed by resolveP2Values()
   121         -  # to make code generation for the switch() statement smaller and faster.
   122         -  for(i=0; i<n_op; i++){
   123         -    name = order[i];
   124         -    if( op[name]>=0 ) continue;
   125         -    if( name=="OP_Transaction"   \
   126         -     || name=="OP_AutoCommit"    \
   127         -     || name=="OP_Savepoint"     \
   128         -     || name=="OP_Checkpoint"    \
   129         -     || name=="OP_Vacuum"        \
   130         -     || name=="OP_JournalMode"   \
   131         -     || name=="OP_VUpdate"       \
   132         -     || name=="OP_VFilter"       \
   133         -     || name=="OP_Next"          \
   134         -     || name=="OP_NextIfOpen"    \
   135         -     || name=="OP_SorterNext"    \
   136         -     || name=="OP_Prev"          \
   137         -     || name=="OP_PrevIfOpen"    \
   138         -    ){
   139         -      cnt++
   140         -      while( used[cnt] ) cnt++
   141         -      op[name] = cnt
   142         -      used[cnt] = 1
   143         -      def[cnt] = name
   144         -    }
   145         -  }
   146         -
   147         -  # Generate the numeric values for opcodes
   148         -  for(i=0; i<n_op; i++){
   149         -    name = order[i];
   150         -    if( op[name]<0 ){
   151         -      cnt++
   152         -      while( used[cnt] ) cnt++
   153         -      op[name] = cnt
   154         -      used[cnt] = 1
   155         -      def[cnt] = name
   156         -    }
   157         -  }
   158         -  max = cnt
   159         -  for(i=1; i<=max; i++){
   160         -    if( !used[i] ){
   161         -      def[i] = "OP_NotUsed_" i 
   162         -    }
   163         -    printf "#define %-16s %3d", def[i], i
   164         -    com = ""
   165         -    if( sameas[i] ){
   166         -      com = "same as " sameas[i]
   167         -    }
   168         -    x = synopsis[def[i]]
   169         -    if( x ){
   170         -      if( com=="" ){
   171         -        com = "synopsis: " x
   172         -      } else {
   173         -        com = com ", synopsis: " x
   174         -      }
   175         -    }
   176         -    if( com!="" ){
   177         -      printf " /* %-42s */", com
   178         -    }
   179         -    printf "\n"
   180         -  }
   181         -
   182         -  # Generate the bitvectors:
   183         -  #
   184         -  #  bit 0:     jump
   185         -  #  bit 1:     pushes a result onto stack
   186         -  #  bit 2:     output to p1.  release p1 before opcode runs
   187         -  #
   188         -  for(i=0; i<=max; i++){
   189         -    name = def[i]
   190         -    a0 = a1 = a2 = a3 = a4 = a5 = a6 = a7 = 0
   191         -    if( jump[name] ) a0 = 1;
   192         -    if( in1[name] ) a2 = 2;
   193         -    if( in2[name] ) a3 = 4;
   194         -    if( in3[name] ) a4 = 8;
   195         -    if( out2[name] ) a5 = 16;
   196         -    if( out3[name] ) a6 = 32;
   197         -    bv[i] = a0+a1+a2+a3+a4+a5+a6;
   198         -  }
   199         -  print "\n"
   200         -  print "/* Properties such as \"out2\" or \"jump\" that are specified in"
   201         -  print "** comments following the \"case\" for each opcode in the vdbe.c"
   202         -  print "** are encoded into bitvectors as follows:"
   203         -  print "*/"
   204         -  print "#define OPFLG_JUMP            0x0001  /* jump:  P2 holds jmp target */"
   205         -  print "#define OPFLG_IN1             0x0002  /* in1:   P1 is an input */"
   206         -  print "#define OPFLG_IN2             0x0004  /* in2:   P2 is an input */"
   207         -  print "#define OPFLG_IN3             0x0008  /* in3:   P3 is an input */"
   208         -  print "#define OPFLG_OUT2            0x0010  /* out2:  P2 is an output */"
   209         -  print "#define OPFLG_OUT3            0x0020  /* out3:  P3 is an output */"
   210         -  print "#define OPFLG_INITIALIZER {\\"
   211         -  for(i=0; i<=max; i++){
   212         -    if( i%8==0 ) printf("/* %3d */",i)
   213         -    printf " 0x%02x,", bv[i]
   214         -    if( i%8==7 ) printf("\\\n");
   215         -  }
   216         -  print "}"
   217         -  if( 0 ){
   218         -    print "\n/* Bitmask to indicate which fields (P1..P5) of each opcode are"
   219         -    print "** actually used.\n*/"
   220         -    print "#define OP_PARAM_USED_INITIALIZER {\\"
   221         -    for(i=0; i<=max; i++){
   222         -      if( i%8==0 ) printf("/* %3d */",i)
   223         -      printf " 0x%02x,", paramused[def[i]]
   224         -      if( i%8==7 ) printf("\\\n");
   225         -    }
   226         -    print "}"
   227         -  }
   228         -}

Changes to src/alter.c.

   598    598     v = sqlite3GetVdbe(pParse);
   599    599     /* The VDBE should have been allocated before this routine is called.
   600    600     ** If that allocation failed, we would have quit before reaching this
   601    601     ** point */
   602    602     if( ALWAYS(v) ){
   603    603       int r1 = sqlite3GetTempReg(pParse);
   604    604       int r2 = sqlite3GetTempReg(pParse);
   605         -    int j1;
          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         -    j1 = sqlite3VdbeAddOp3(v, OP_Ge, r2, 0, r1);
          609  +    addr1 = sqlite3VdbeAddOp3(v, OP_Ge, r2, 0, r1);
   610    610       sqlite3VdbeChangeP5(v, SQLITE_NOTNULL); VdbeCoverage(v);
   611    611       sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_FILE_FORMAT, r2);
   612         -    sqlite3VdbeJumpHere(v, j1);
          612  +    sqlite3VdbeJumpHere(v, addr1);
   613    613       sqlite3ReleaseTempReg(pParse, r1);
   614    614       sqlite3ReleaseTempReg(pParse, r2);
   615    615     }
   616    616   }
   617    617   
   618    618   /*
   619    619   ** This function is called after an "ALTER TABLE ... ADD" statement

Changes to src/btree.c.

   853    853   
   854    854     rc = saveCursorKey(pCur);
   855    855     if( rc==SQLITE_OK ){
   856    856       btreeReleaseAllCursorPages(pCur);
   857    857       pCur->eState = CURSOR_REQUIRESEEK;
   858    858     }
   859    859   
   860         -  invalidateOverflowCache(pCur);
          860  +  pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl|BTCF_AtLast);
   861    861     return rc;
   862    862   }
   863    863   
   864    864   /* Forward reference */
   865    865   static int SQLITE_NOINLINE saveCursorsOnList(BtCursor*,Pgno,BtCursor*);
   866    866   
   867    867   /*
................................................................................
  6899   6899       u8 *pSlot;
  6900   6900       sz = cachedCellSize(pCArray, i);
  6901   6901       if( (aData[1]==0 && aData[2]==0) || (pSlot = pageFindSlot(pPg,sz,&rc))==0 ){
  6902   6902         pData -= sz;
  6903   6903         if( pData<pBegin ) return 1;
  6904   6904         pSlot = pData;
  6905   6905       }
  6906         -    memcpy(pSlot, pCArray->apCell[i], sz);
         6906  +    /* pSlot and pCArray->apCell[i] will never overlap on a well-formed
         6907  +    ** database.  But they might for a corrupt database.  Hence use memmove()
         6908  +    ** since memcpy() sends SIGABORT with overlapping buffers on OpenBSD */
         6909  +    assert( (pSlot+sz)<=pCArray->apCell[i]
         6910  +         || pSlot>=(pCArray->apCell[i]+sz)
         6911  +         || CORRUPT_DB );
         6912  +    memmove(pSlot, pCArray->apCell[i], sz);
  6907   6913       put2byte(pCellptr, (pSlot - aData));
  6908   6914       pCellptr += 2;
  6909   6915     }
  6910   6916     *ppData = pData;
  6911   6917     return 0;
  6912   6918   }
  6913   6919   
................................................................................
  8024   8030       ** for which the pointer is stored within the content being copied.
  8025   8031       **
  8026   8032       ** It is critical that the child page be defragmented before being
  8027   8033       ** copied into the parent, because if the parent is page 1 then it will
  8028   8034       ** by smaller than the child due to the database header, and so all the
  8029   8035       ** free space needs to be up front.
  8030   8036       */
  8031         -    assert( nNew==1 );
         8037  +    assert( nNew==1 || CORRUPT_DB );
  8032   8038       rc = defragmentPage(apNew[0]);
  8033   8039       testcase( rc!=SQLITE_OK );
  8034   8040       assert( apNew[0]->nFree == 
  8035   8041           (get2byte(&apNew[0]->aData[5])-apNew[0]->cellOffset-apNew[0]->nCell*2)
  8036   8042         || rc!=SQLITE_OK
  8037   8043       );
  8038   8044       copyNodeContent(apNew[0], pParent, &rc);

Changes to src/build.c.

   188    188             OP_Transaction,                    /* Opcode */
   189    189             iDb,                               /* P1 */
   190    190             DbMaskTest(pParse->writeMask,iDb), /* P2 */
   191    191             pParse->cookieValue[iDb],          /* P3 */
   192    192             db->aDb[iDb].pSchema->iGeneration  /* P4 */
   193    193           );
   194    194           if( db->init.busy==0 ) sqlite3VdbeChangeP5(v, 1);
          195  +        VdbeComment((v,
          196  +              "usesStmtJournal=%d", pParse->mayAbort && pParse->isMultiWrite));
   195    197         }
   196    198   #ifndef SQLITE_OMIT_VIRTUALTABLE
   197    199         for(i=0; i<pParse->nVtabLock; i++){
   198    200           char *vtab = (char *)sqlite3GetVTable(db, pParse->apVtabLock[i]);
   199    201           sqlite3VdbeAddOp4(v, OP_VBegin, 0, 0, 0, vtab, P4_VTAB);
   200    202         }
   201    203         pParse->nVtabLock = 0;
................................................................................
   979    981     ** and allocate the record number for the table entry now.  Before any
   980    982     ** PRIMARY KEY or UNIQUE keywords are parsed.  Those keywords will cause
   981    983     ** indices to be created and the table record must come before the 
   982    984     ** indices.  Hence, the record number for the table must be allocated
   983    985     ** now.
   984    986     */
   985    987     if( !db->init.busy && (v = sqlite3GetVdbe(pParse))!=0 ){
   986         -    int j1;
          988  +    int addr1;
   987    989       int fileFormat;
   988    990       int reg1, reg2, reg3;
   989    991       /* nullRow[] is an OP_Record encoding of a row containing 5 NULLs */
   990    992       static const char nullRow[] = { 6, 0, 0, 0, 0, 0 };
   991    993       sqlite3BeginWriteOperation(pParse, 1, iDb);
   992    994   
   993    995   #ifndef SQLITE_OMIT_VIRTUALTABLE
................................................................................
  1000   1002       ** set them now.
  1001   1003       */
  1002   1004       reg1 = pParse->regRowid = ++pParse->nMem;
  1003   1005       reg2 = pParse->regRoot = ++pParse->nMem;
  1004   1006       reg3 = ++pParse->nMem;
  1005   1007       sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, reg3, BTREE_FILE_FORMAT);
  1006   1008       sqlite3VdbeUsesBtree(v, iDb);
  1007         -    j1 = sqlite3VdbeAddOp1(v, OP_If, reg3); VdbeCoverage(v);
         1009  +    addr1 = sqlite3VdbeAddOp1(v, OP_If, reg3); VdbeCoverage(v);
  1008   1010       fileFormat = (db->flags & SQLITE_LegacyFileFmt)!=0 ?
  1009   1011                     1 : SQLITE_MAX_FILE_FORMAT;
  1010   1012       sqlite3VdbeAddOp2(v, OP_Integer, fileFormat, reg3);
  1011   1013       sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_FILE_FORMAT, reg3);
  1012   1014       sqlite3VdbeAddOp2(v, OP_Integer, ENC(db), reg3);
  1013   1015       sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_TEXT_ENCODING, reg3);
  1014         -    sqlite3VdbeJumpHere(v, j1);
         1016  +    sqlite3VdbeJumpHere(v, addr1);
  1015   1017   
  1016   1018       /* This just creates a place-holder record in the sqlite_master table.
  1017   1019       ** The record created does not contain anything yet.  It will be replaced
  1018   1020       ** by the real entry in code generated at sqlite3EndTable().
  1019   1021       **
  1020   1022       ** The rowid for the new entry is left in register pParse->regRowid.
  1021   1023       ** The root page number of the new table is left in reg pParse->regRoot.
................................................................................
  2078   2080     DbFixer sFix;
  2079   2081     Token *pName = 0;
  2080   2082     int iDb;
  2081   2083     sqlite3 *db = pParse->db;
  2082   2084   
  2083   2085     if( pParse->nVar>0 ){
  2084   2086       sqlite3ErrorMsg(pParse, "parameters are not allowed in views");
  2085         -    sqlite3SelectDelete(db, pSelect);
  2086         -    return;
         2087  +    goto create_view_fail;
  2087   2088     }
  2088   2089     sqlite3StartTable(pParse, pName1, pName2, isTemp, 1, 0, noErr);
  2089   2090     p = pParse->pNewTable;
  2090   2091     if( p==0 || pParse->nErr ) goto create_view_fail;
  2091   2092     sqlite3TwoPartName(pParse, pName1, pName2, &pName);
  2092   2093     iDb = sqlite3SchemaToIndex(db, p->pSchema);
  2093   2094     sqlite3FixInit(&sFix, pParse, iDb, "view", pName);
................................................................................
  3131   3132     }else{
  3132   3133       sortOrderMask = 0;    /* Ignore DESC */
  3133   3134     }
  3134   3135   
  3135   3136     /* Analyze the list of expressions that form the terms of the index and
  3136   3137     ** report any errors.  In the common case where the expression is exactly
  3137   3138     ** a table column, store that column in aiColumn[].  For general expressions,
  3138         -  ** populate pIndex->aColExpr and store -2 in aiColumn[].
         3139  +  ** populate pIndex->aColExpr and store XN_EXPR (-2) in aiColumn[].
  3139   3140     **
  3140   3141     ** TODO: Issue a warning if two or more columns of the index are identical.
  3141   3142     ** TODO: Issue a warning if the table primary key is used as part of the
  3142   3143     ** index key.
  3143   3144     */
  3144   3145     for(i=0, pListItem=pList->a; i<pList->nExpr; i++, pListItem++){
  3145   3146       Expr *pCExpr;                  /* The i-th index expression */
................................................................................
  3160   3161           ExprList *pCopy = sqlite3ExprListDup(db, pList, 0);
  3161   3162           pIndex->aColExpr = pCopy;
  3162   3163           if( !db->mallocFailed ){
  3163   3164             assert( pCopy!=0 );
  3164   3165             pListItem = &pCopy->a[i];
  3165   3166           }
  3166   3167         }
  3167         -      j = -2;
  3168         -      pIndex->aiColumn[i] = -2;
         3168  +      j = XN_EXPR;
         3169  +      pIndex->aiColumn[i] = XN_EXPR;
  3169   3170         pIndex->uniqNotNull = 0;
  3170   3171       }else{
  3171   3172         j = pCExpr->iColumn;
  3172   3173         assert( j<=0x7fff );
  3173   3174         if( j<0 ){
  3174   3175           j = pTab->iPKey;
  3175   3176         }else if( pTab->aCol[j].notNull==0 ){
................................................................................
  3214   3215           pIndex->azColl[i] = pPk->azColl[j];
  3215   3216           pIndex->aSortOrder[i] = pPk->aSortOrder[j];
  3216   3217           i++;
  3217   3218         }
  3218   3219       }
  3219   3220       assert( i==pIndex->nColumn );
  3220   3221     }else{
  3221         -    pIndex->aiColumn[i] = -1;
         3222  +    pIndex->aiColumn[i] = XN_ROWID;
  3222   3223       pIndex->azColl[i] = "BINARY";
  3223   3224     }
  3224   3225     sqlite3DefaultRowEst(pIndex);
  3225   3226     if( pParse->pNewTable==0 ) estimateIndexWidth(pIndex);
  3226   3227   
  3227   3228     if( pTab==pParse->pNewTable ){
  3228   3229       /* This routine has been called to create an automatic index as a

Changes to src/ctime.c.

    91     91     "ENABLE_FTS3",
    92     92   #endif
    93     93   #if SQLITE_ENABLE_FTS3_PARENTHESIS
    94     94     "ENABLE_FTS3_PARENTHESIS",
    95     95   #endif
    96     96   #if SQLITE_ENABLE_FTS4
    97     97     "ENABLE_FTS4",
           98  +#endif
           99  +#if SQLITE_ENABLE_FTS5
          100  +  "ENABLE_FTS5",
    98    101   #endif
    99    102   #if SQLITE_ENABLE_ICU
   100    103     "ENABLE_ICU",
   101    104   #endif
   102    105   #if SQLITE_ENABLE_IOTRACE
   103    106     "ENABLE_IOTRACE",
          107  +#endif
          108  +#if SQLITE_ENABLE_JSON1
          109  +  "ENABLE_JSON1",
   104    110   #endif
   105    111   #if SQLITE_ENABLE_LOAD_EXTENSION
   106    112     "ENABLE_LOAD_EXTENSION",
   107    113   #endif
   108    114   #if SQLITE_ENABLE_LOCKING_STYLE
   109    115     "ENABLE_LOCKING_STYLE=" CTIMEOPT_VAL(SQLITE_ENABLE_LOCKING_STYLE),
   110    116   #endif

Changes to src/delete.c.

   407    407       **  ONEPASS_OFF:    Two-pass approach - use a FIFO for rowids/PK values.
   408    408       **  ONEPASS_SINGLE: One-pass approach - at most one row deleted.
   409    409       **  ONEPASS_MULTI:  One-pass approach - any number of rows may be deleted.
   410    410       */
   411    411       pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0, wcf, iTabCur+1);
   412    412       if( pWInfo==0 ) goto delete_from_cleanup;
   413    413       eOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass);
   414         -    assert( IsVirtual(pTab)==0 || eOnePass==ONEPASS_OFF );
          414  +    assert( IsVirtual(pTab)==0 || eOnePass!=ONEPASS_MULTI );
   415    415       assert( IsVirtual(pTab) || bComplex || eOnePass!=ONEPASS_OFF );
   416    416     
   417    417       /* Keep track of the number of rows to be deleted */
   418    418       if( db->flags & SQLITE_CountRows ){
   419    419         sqlite3VdbeAddOp2(v, OP_AddImm, memCnt, 1);
   420    420       }
   421    421     
   422    422       /* Extract the rowid or primary key for the current row */
   423    423       if( pPk ){
   424    424         for(i=0; i<nPk; i++){
   425         -        assert( pPk->aiColumn[i]>=(-1) );
          425  +        assert( pPk->aiColumn[i]>=0 );
   426    426           sqlite3ExprCodeGetColumnOfTable(v, pTab, iTabCur,
   427    427                                           pPk->aiColumn[i], iPk+i);
   428    428         }
   429    429         iKey = iPk;
   430    430       }else{
   431    431         iKey = pParse->nMem + 1;
   432    432         iKey = sqlite3ExprCodeGetColumn(pParse, pTab, -1, iTabCur, iKey, 0);
................................................................................
   490    490       }
   491    491     
   492    492       /* Set up a loop over the rowids/primary-keys that were found in the
   493    493       ** where-clause loop above.
   494    494       */
   495    495       if( eOnePass!=ONEPASS_OFF ){
   496    496         assert( nKey==nPk );  /* OP_Found will use an unpacked key */
   497         -      if( aToOpen[iDataCur-iTabCur] ){
          497  +      if( !IsVirtual(pTab) && aToOpen[iDataCur-iTabCur] ){
   498    498           assert( pPk!=0 || pTab->pSelect!=0 );
   499    499           sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, addrBypass, iKey, nKey);
   500    500           VdbeCoverage(v);
   501    501         }
   502    502       }else if( pPk ){
   503    503         addrLoop = sqlite3VdbeAddOp1(v, OP_Rewind, iEphCur); VdbeCoverage(v);
   504    504         sqlite3VdbeAddOp2(v, OP_RowKey, iEphCur, iKey);
................................................................................
   512    512       /* Delete the row */
   513    513   #ifndef SQLITE_OMIT_VIRTUALTABLE
   514    514       if( IsVirtual(pTab) ){
   515    515         const char *pVTab = (const char *)sqlite3GetVTable(db, pTab);
   516    516         sqlite3VtabMakeWritable(pParse, pTab);
   517    517         sqlite3VdbeAddOp4(v, OP_VUpdate, 0, 1, iKey, pVTab, P4_VTAB);
   518    518         sqlite3VdbeChangeP5(v, OE_Abort);
          519  +      assert( eOnePass==ONEPASS_OFF || eOnePass==ONEPASS_SINGLE );
   519    520         sqlite3MayAbort(pParse);
          521  +      if( eOnePass==ONEPASS_SINGLE && sqlite3IsToplevel(pParse) ){
          522  +        pParse->isMultiWrite = 0;
          523  +      }
   520    524       }else
   521    525   #endif
   522    526       {
   523    527         int count = (pParse->nested==0);    /* True to count changes */
   524    528         int iIdxNoSeek = -1;
   525    529         if( bComplex==0 && aiCurOnePass[1]!=iDataCur ){
   526    530           iIdxNoSeek = aiCurOnePass[1];
................................................................................
   850    854     }
   851    855     nCol = (prefixOnly && pIdx->uniqNotNull) ? pIdx->nKeyCol : pIdx->nColumn;
   852    856     regBase = sqlite3GetTempRange(pParse, nCol);
   853    857     if( pPrior && (regBase!=regPrior || pPrior->pPartIdxWhere) ) pPrior = 0;
   854    858     for(j=0; j<nCol; j++){
   855    859       if( pPrior
   856    860        && pPrior->aiColumn[j]==pIdx->aiColumn[j]
   857         -     && pPrior->aiColumn[j]>=(-1)
          861  +     && pPrior->aiColumn[j]!=XN_EXPR
   858    862       ){
   859    863         /* This column was already computed by the previous index */
   860    864         continue;
   861    865       }
   862    866       sqlite3ExprCodeLoadIndexColumn(pParse, pIdx, iDataCur, j, regBase+j);
   863    867       /* If the column affinity is REAL but the number is an integer, then it
   864    868       ** might be stored in the table as an integer (using a compact

Changes to src/expr.c.

  1591   1591   /*
  1592   1592   ** Generate code that checks the left-most column of index table iCur to see if
  1593   1593   ** it contains any NULL entries.  Cause the register at regHasNull to be set
  1594   1594   ** to a non-NULL value if iCur contains no NULLs.  Cause register regHasNull
  1595   1595   ** to be set to NULL if iCur contains one or more NULL values.
  1596   1596   */
  1597   1597   static void sqlite3SetHasNullFlag(Vdbe *v, int iCur, int regHasNull){
  1598         -  int j1;
         1598  +  int addr1;
  1599   1599     sqlite3VdbeAddOp2(v, OP_Integer, 0, regHasNull);
  1600         -  j1 = sqlite3VdbeAddOp1(v, OP_Rewind, iCur); VdbeCoverage(v);
         1600  +  addr1 = sqlite3VdbeAddOp1(v, OP_Rewind, iCur); VdbeCoverage(v);
  1601   1601     sqlite3VdbeAddOp3(v, OP_Column, iCur, 0, regHasNull);
  1602   1602     sqlite3VdbeChangeP5(v, OPFLAG_TYPEOFARG);
  1603   1603     VdbeComment((v, "first_entry_in(%d)", iCur));
  1604         -  sqlite3VdbeJumpHere(v, j1);
         1604  +  sqlite3VdbeJumpHere(v, addr1);
  1605   1605   }
  1606   1606   
  1607   1607   
  1608   1608   #ifndef SQLITE_OMIT_SUBQUERY
  1609   1609   /*
  1610   1610   ** The argument is an IN operator with a list (not a subquery) on the 
  1611   1611   ** right-hand side.  Return TRUE if that list is constant.
................................................................................
  2197   2197           sqlite3VdbeAddOp4Int(v, OP_NotFound, pExpr->iTable, destIfFalse, r1, 1);
  2198   2198           VdbeCoverage(v);
  2199   2199         }else{
  2200   2200           /* In this branch, the RHS of the IN might contain a NULL and
  2201   2201           ** the presence of a NULL on the RHS makes a difference in the
  2202   2202           ** outcome.
  2203   2203           */
  2204         -        int j1;
         2204  +        int addr1;
  2205   2205     
  2206   2206           /* First check to see if the LHS is contained in the RHS.  If so,
  2207   2207           ** then the answer is TRUE the presence of NULLs in the RHS does
  2208   2208           ** not matter.  If the LHS is not contained in the RHS, then the
  2209   2209           ** answer is NULL if the RHS contains NULLs and the answer is
  2210   2210           ** FALSE if the RHS is NULL-free.
  2211   2211           */
  2212         -        j1 = sqlite3VdbeAddOp4Int(v, OP_Found, pExpr->iTable, 0, r1, 1);
         2212  +        addr1 = sqlite3VdbeAddOp4Int(v, OP_Found, pExpr->iTable, 0, r1, 1);
  2213   2213           VdbeCoverage(v);
  2214   2214           sqlite3VdbeAddOp2(v, OP_IsNull, rRhsHasNull, destIfNull);
  2215   2215           VdbeCoverage(v);
  2216   2216           sqlite3VdbeGoto(v, destIfFalse);
  2217         -        sqlite3VdbeJumpHere(v, j1);
         2217  +        sqlite3VdbeJumpHere(v, addr1);
  2218   2218         }
  2219   2219       }
  2220   2220     }
  2221   2221     sqlite3ReleaseTempReg(pParse, r1);
  2222   2222     sqlite3ExprCachePop(pParse);
  2223   2223     VdbeComment((v, "end IN expr"));
  2224   2224   }
................................................................................
  2439   2439     Parse *pParse,  /* The parsing context */
  2440   2440     Index *pIdx,    /* The index whose column is to be loaded */
  2441   2441     int iTabCur,    /* Cursor pointing to a table row */
  2442   2442     int iIdxCol,    /* The column of the index to be loaded */
  2443   2443     int regOut      /* Store the index column value in this register */
  2444   2444   ){
  2445   2445     i16 iTabCol = pIdx->aiColumn[iIdxCol];
  2446         -  if( iTabCol>=(-1) ){
         2446  +  if( iTabCol==XN_EXPR ){
         2447  +    assert( pIdx->aColExpr );
         2448  +    assert( pIdx->aColExpr->nExpr>iIdxCol );
         2449  +    pParse->iSelfTab = iTabCur;
         2450  +    sqlite3ExprCode(pParse, pIdx->aColExpr->a[iIdxCol].pExpr, regOut);
         2451  +  }else{
  2447   2452       sqlite3ExprCodeGetColumnOfTable(pParse->pVdbe, pIdx->pTable, iTabCur,
  2448   2453                                       iTabCol, regOut);
  2449         -    return;
  2450   2454     }
  2451         -  assert( pIdx->aColExpr );
  2452         -  assert( pIdx->aColExpr->nExpr>iIdxCol );
  2453         -  pParse->iSelfTab = iTabCur;
  2454         -  sqlite3ExprCode(pParse, pIdx->aColExpr->a[iIdxCol].pExpr, regOut);
  2455   2455   }
  2456   2456   
  2457   2457   /*
  2458   2458   ** Generate code to extract the value of the iCol-th column of a table.
  2459   2459   */
  2460   2460   void sqlite3ExprCodeGetColumnOfTable(
  2461   2461     Vdbe *v,        /* The VDBE under construction */

Changes to src/fkey.c.

   248    248           ** the default collation sequences for each column. */
   249    249           int i, j;
   250    250           for(i=0; i<nCol; i++){
   251    251             i16 iCol = pIdx->aiColumn[i];     /* Index of column in parent tbl */
   252    252             char *zDfltColl;                  /* Def. collation for column */
   253    253             char *zIdxCol;                    /* Name of indexed column */
   254    254   
          255  +          if( iCol<0 ) break; /* No foreign keys against expression indexes */
          256  +
   255    257             /* If the index uses a collation sequence that is different from
   256    258             ** the default collation sequence for the column, this index is
   257    259             ** unusable. Bail out early in this case.  */
   258    260             zDfltColl = pParent->aCol[iCol].zColl;
   259    261             if( !zDfltColl ){
   260    262               zDfltColl = "BINARY";
   261    263             }
................................................................................
   400    402         ** none of the child key values are).
   401    403         */
   402    404         if( pTab==pFKey->pFrom && nIncr==1 ){
   403    405           int iJump = sqlite3VdbeCurrentAddr(v) + nCol + 1;
   404    406           for(i=0; i<nCol; i++){
   405    407             int iChild = aiCol[i]+1+regData;
   406    408             int iParent = pIdx->aiColumn[i]+1+regData;
          409  +          assert( pIdx->aiColumn[i]>=0 );
   407    410             assert( aiCol[i]!=pTab->iPKey );
   408    411             if( pIdx->aiColumn[i]==pTab->iPKey ){
   409    412               /* The parent key is a composite key that includes the IPK column */
   410    413               iParent = regData;
   411    414             }
   412    415             sqlite3VdbeAddOp3(v, OP_Ne, iChild, iJump, iParent); VdbeCoverage(v);
   413    416             sqlite3VdbeChangeP5(v, SQLITE_JUMPIFNULL);
................................................................................
   608    611         pNe = sqlite3PExpr(pParse, TK_NE, pLeft, pRight, 0);
   609    612       }else{
   610    613         Expr *pEq, *pAll = 0;
   611    614         Index *pPk = sqlite3PrimaryKeyIndex(pTab);
   612    615         assert( pIdx!=0 );
   613    616         for(i=0; i<pPk->nKeyCol; i++){
   614    617           i16 iCol = pIdx->aiColumn[i];
          618  +        assert( iCol>=0 );
   615    619           pLeft = exprTableRegister(pParse, pTab, regData, iCol);
   616    620           pRight = exprTableColumn(db, pTab, pSrc->a[0].iCursor, iCol);
   617    621           pEq = sqlite3PExpr(pParse, TK_EQ, pLeft, pRight, 0);
   618    622           pAll = sqlite3ExprAnd(db, pAll, pEq);
   619    623         }
   620    624         pNe = sqlite3PExpr(pParse, TK_NOT, pAll, 0, 0);
   621    625       }
................................................................................
   927    931         iCol = pFKey->aCol[0].iFrom;
   928    932         aiCol = &iCol;
   929    933       }
   930    934       for(i=0; i<pFKey->nCol; i++){
   931    935         if( aiCol[i]==pTab->iPKey ){
   932    936           aiCol[i] = -1;
   933    937         }
          938  +      assert( pIdx==0 || pIdx->aiColumn[i]>=0 );
   934    939   #ifndef SQLITE_OMIT_AUTHORIZATION
   935    940         /* Request permission to read the parent key columns. If the 
   936    941         ** authorization callback returns SQLITE_IGNORE, behave as if any
   937    942         ** values read from the parent table are NULL. */
   938    943         if( db->xAuth ){
   939    944           int rcauth;
   940    945           char *zCol = pTo->aCol[pIdx ? pIdx->aiColumn[i] : pTo->iPKey].zName;
................................................................................
  1058   1063       for(p=pTab->pFKey; p; p=p->pNextFrom){
  1059   1064         for(i=0; i<p->nCol; i++) mask |= COLUMN_MASK(p->aCol[i].iFrom);
  1060   1065       }
  1061   1066       for(p=sqlite3FkReferences(pTab); p; p=p->pNextTo){
  1062   1067         Index *pIdx = 0;
  1063   1068         sqlite3FkLocateIndex(pParse, pTab, p, &pIdx, 0);
  1064   1069         if( pIdx ){
  1065         -        for(i=0; i<pIdx->nKeyCol; i++) mask |= COLUMN_MASK(pIdx->aiColumn[i]);
         1070  +        for(i=0; i<pIdx->nKeyCol; i++){
         1071  +          assert( pIdx->aiColumn[i]>=0 );
         1072  +          mask |= COLUMN_MASK(pIdx->aiColumn[i]);
         1073  +        }
  1066   1074         }
  1067   1075       }
  1068   1076     }
  1069   1077     return mask;
  1070   1078   }
  1071   1079   
  1072   1080   
................................................................................
  1181   1189         Token tToCol;               /* Name of column in parent table */
  1182   1190         int iFromCol;               /* Idx of column in child table */
  1183   1191         Expr *pEq;                  /* tFromCol = OLD.tToCol */
  1184   1192   
  1185   1193         iFromCol = aiCol ? aiCol[i] : pFKey->aCol[0].iFrom;
  1186   1194         assert( iFromCol>=0 );
  1187   1195         assert( pIdx!=0 || (pTab->iPKey>=0 && pTab->iPKey<pTab->nCol) );
         1196  +      assert( pIdx==0 || pIdx->aiColumn[i]>=0 );
  1188   1197         tToCol.z = pTab->aCol[pIdx ? pIdx->aiColumn[i] : pTab->iPKey].zName;
  1189   1198         tFromCol.z = pFKey->pFrom->aCol[iFromCol].zName;
  1190   1199   
  1191   1200         tToCol.n = sqlite3Strlen30(tToCol.z);
  1192   1201         tFromCol.n = sqlite3Strlen30(tFromCol.z);
  1193   1202   
  1194   1203         /* Create the expression "OLD.zToCol = zFromCol". It is important

Changes to src/insert.c.

    86     86         db->mallocFailed = 1;
    87     87         return 0;
    88     88       }
    89     89       for(n=0; n<pIdx->nColumn; n++){
    90     90         i16 x = pIdx->aiColumn[n];
    91     91         if( x>=0 ){
    92     92           pIdx->zColAff[n] = pTab->aCol[x].affinity;
    93         -      }else if( x==(-1) ){
           93  +      }else if( x==XN_ROWID ){
    94     94           pIdx->zColAff[n] = SQLITE_AFF_INTEGER;
    95     95         }else{
    96     96           char aff;
    97         -        assert( x==(-2) );
           97  +        assert( x==XN_EXPR );
    98     98           assert( pIdx->aColExpr!=0 );
    99     99           aff = sqlite3ExprAffinity(pIdx->aColExpr->a[n].pExpr);
   100    100           if( aff==0 ) aff = SQLITE_AFF_BLOB;
   101    101           pIdx->zColAff[n] = aff;
   102    102         }
   103    103       }
   104    104       pIdx->zColAff[n] = 0;
................................................................................
   256    256     int memId;                 /* Register holding max rowid */
   257    257     int addr;                  /* A VDBE address */
   258    258     Vdbe *v = pParse->pVdbe;   /* VDBE under construction */
   259    259   
   260    260     /* This routine is never called during trigger-generation.  It is
   261    261     ** only called from the top-level */
   262    262     assert( pParse->pTriggerTab==0 );
   263         -  assert( pParse==sqlite3ParseToplevel(pParse) );
          263  +  assert( sqlite3IsToplevel(pParse) );
   264    264   
   265    265     assert( v );   /* We failed long ago if this is not so */
   266    266     for(p = pParse->pAinc; p; p = p->pNext){
   267    267       pDb = &db->aDb[p->iDb];
   268    268       memId = p->regCtr;
   269    269       assert( sqlite3SchemaMutexHeld(db, 0, pDb->pSchema) );
   270    270       sqlite3OpenTable(pParse, 0, p->iDb, pDb->pSchema->pSeqTab, OP_OpenRead);
................................................................................
   309    309     AutoincInfo *p;
   310    310     Vdbe *v = pParse->pVdbe;
   311    311     sqlite3 *db = pParse->db;
   312    312   
   313    313     assert( v );
   314    314     for(p = pParse->pAinc; p; p = p->pNext){
   315    315       Db *pDb = &db->aDb[p->iDb];
   316         -    int j1;
          316  +    int addr1;
   317    317       int iRec;
   318    318       int memId = p->regCtr;
   319    319   
   320    320       iRec = sqlite3GetTempReg(pParse);
   321    321       assert( sqlite3SchemaMutexHeld(db, 0, pDb->pSchema) );
   322    322       sqlite3OpenTable(pParse, 0, p->iDb, pDb->pSchema->pSeqTab, OP_OpenWrite);
   323         -    j1 = sqlite3VdbeAddOp1(v, OP_NotNull, memId+1); VdbeCoverage(v);
          323  +    addr1 = sqlite3VdbeAddOp1(v, OP_NotNull, memId+1); VdbeCoverage(v);
   324    324       sqlite3VdbeAddOp2(v, OP_NewRowid, 0, memId+1);
   325         -    sqlite3VdbeJumpHere(v, j1);
          325  +    sqlite3VdbeJumpHere(v, addr1);
   326    326       sqlite3VdbeAddOp3(v, OP_MakeRecord, memId-1, 2, iRec);
   327    327       sqlite3VdbeAddOp3(v, OP_Insert, 0, iRec, memId+1);
   328    328       sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
   329    329       sqlite3VdbeAddOp0(v, OP_Close);
   330    330       sqlite3ReleaseTempReg(pParse, iRec);
   331    331     }
   332    332   }
................................................................................
   810    810       ** translated into a unique ID for the row.  But on a BEFORE trigger,
   811    811       ** we do not know what the unique ID will be (because the insert has
   812    812       ** not happened yet) so we substitute a rowid of -1
   813    813       */
   814    814       if( ipkColumn<0 ){
   815    815         sqlite3VdbeAddOp2(v, OP_Integer, -1, regCols);
   816    816       }else{
   817         -      int j1;
          817  +      int addr1;
   818    818         assert( !withoutRowid );
   819    819         if( useTempTable ){
   820    820           sqlite3VdbeAddOp3(v, OP_Column, srcTab, ipkColumn, regCols);
   821    821         }else{
   822    822           assert( pSelect==0 );  /* Otherwise useTempTable is true */
   823    823           sqlite3ExprCode(pParse, pList->a[ipkColumn].pExpr, regCols);
   824    824         }
   825         -      j1 = sqlite3VdbeAddOp1(v, OP_NotNull, regCols); VdbeCoverage(v);
          825  +      addr1 = sqlite3VdbeAddOp1(v, OP_NotNull, regCols); VdbeCoverage(v);
   826    826         sqlite3VdbeAddOp2(v, OP_Integer, -1, regCols);
   827         -      sqlite3VdbeJumpHere(v, j1);
          827  +      sqlite3VdbeJumpHere(v, addr1);
   828    828         sqlite3VdbeAddOp1(v, OP_MustBeInt, regCols); VdbeCoverage(v);
   829    829       }
   830    830   
   831    831       /* Cannot have triggers on a virtual table. If it were possible,
   832    832       ** this block would have to account for hidden column.
   833    833       */
   834    834       assert( !IsVirtual(pTab) );
................................................................................
   894    894             pOp->p3 = regAutoinc;
   895    895           }
   896    896         }
   897    897         /* If the PRIMARY KEY expression is NULL, then use OP_NewRowid
   898    898         ** to generate a unique primary key value.
   899    899         */
   900    900         if( !appendFlag ){
   901         -        int j1;
          901  +        int addr1;
   902    902           if( !IsVirtual(pTab) ){
   903         -          j1 = sqlite3VdbeAddOp1(v, OP_NotNull, regRowid); VdbeCoverage(v);
          903  +          addr1 = sqlite3VdbeAddOp1(v, OP_NotNull, regRowid); VdbeCoverage(v);
   904    904             sqlite3VdbeAddOp3(v, OP_NewRowid, iDataCur, regRowid, regAutoinc);
   905         -          sqlite3VdbeJumpHere(v, j1);
          905  +          sqlite3VdbeJumpHere(v, addr1);
   906    906           }else{
   907         -          j1 = sqlite3VdbeCurrentAddr(v);
   908         -          sqlite3VdbeAddOp2(v, OP_IsNull, regRowid, j1+2); VdbeCoverage(v);
          907  +          addr1 = sqlite3VdbeCurrentAddr(v);
          908  +          sqlite3VdbeAddOp2(v, OP_IsNull, regRowid, addr1+2); VdbeCoverage(v);
   909    909           }
   910    910           sqlite3VdbeAddOp1(v, OP_MustBeInt, regRowid); VdbeCoverage(v);
   911    911         }
   912    912       }else if( IsVirtual(pTab) || withoutRowid ){
   913    913         sqlite3VdbeAddOp2(v, OP_Null, 0, regRowid);
   914    914       }else{
   915    915         sqlite3VdbeAddOp3(v, OP_NewRowid, iDataCur, regRowid, regAutoinc);
................................................................................
  1155   1155     Index *pIdx;         /* Pointer to one of the indices */
  1156   1156     Index *pPk = 0;      /* The PRIMARY KEY index */
  1157   1157     sqlite3 *db;         /* Database connection */
  1158   1158     int i;               /* loop counter */
  1159   1159     int ix;              /* Index loop counter */
  1160   1160     int nCol;            /* Number of columns */
  1161   1161     int onError;         /* Conflict resolution strategy */
  1162         -  int j1;              /* Address of jump instruction */
         1162  +  int addr1;           /* Address of jump instruction */
  1163   1163     int seenReplace = 0; /* True if REPLACE is used to resolve INT PK conflict */
  1164   1164     int nPkField;        /* Number of fields in PRIMARY KEY. 1 for ROWID tables */
  1165   1165     int ipkTop = 0;      /* Top of the rowid change constraint check */
  1166   1166     int ipkBottom = 0;   /* Bottom of the rowid change constraint check */
  1167   1167     u8 isUpdate;         /* True if this is an UPDATE operation */
  1168   1168     u8 bAffinityDone = 0;  /* True if the OP_Affinity operation has been run */
  1169   1169     int regRowid = -1;   /* Register holding ROWID value */
................................................................................
  1226   1226         case OE_Ignore: {
  1227   1227           sqlite3VdbeAddOp2(v, OP_IsNull, regNewData+1+i, ignoreDest);
  1228   1228           VdbeCoverage(v);
  1229   1229           break;
  1230   1230         }
  1231   1231         default: {
  1232   1232           assert( onError==OE_Replace );
  1233         -        j1 = sqlite3VdbeAddOp1(v, OP_NotNull, regNewData+1+i); VdbeCoverage(v);
         1233  +        addr1 = sqlite3VdbeAddOp1(v, OP_NotNull, regNewData+1+i);
         1234  +           VdbeCoverage(v);
  1234   1235           sqlite3ExprCode(pParse, pTab->aCol[i].pDflt, regNewData+1+i);
  1235         -        sqlite3VdbeJumpHere(v, j1);
         1236  +        sqlite3VdbeJumpHere(v, addr1);
  1236   1237           break;
  1237   1238         }
  1238   1239       }
  1239   1240     }
  1240   1241   
  1241   1242     /* Test all CHECK constraints
  1242   1243     */
................................................................................
  1404   1405       /* Create a record for this index entry as it should appear after
  1405   1406       ** the insert or update.  Store that record in the aRegIdx[ix] register
  1406   1407       */
  1407   1408       regIdx = sqlite3GetTempRange(pParse, pIdx->nColumn);
  1408   1409       for(i=0; i<pIdx->nColumn; i++){
  1409   1410         int iField = pIdx->aiColumn[i];
  1410   1411         int x;
  1411         -      if( iField==(-2) ){
         1412  +      if( iField==XN_EXPR ){
  1412   1413           pParse->ckBase = regNewData+1;
  1413   1414           sqlite3ExprCode(pParse, pIdx->aColExpr->a[i].pExpr, regIdx+i);
  1414   1415           pParse->ckBase = 0;
  1415   1416           VdbeComment((v, "%s column %d", pIdx->zName, i));
  1416   1417         }else{
  1417         -        if( iField==(-1) || iField==pTab->iPKey ){
         1418  +        if( iField==XN_ROWID || iField==pTab->iPKey ){
  1418   1419             if( regRowid==regIdx+i ) continue; /* ROWID already in regIdx+i */
  1419   1420             x = regNewData;
  1420   1421             regRowid =  pIdx->pPartIdxWhere ? -1 : regIdx+i;
  1421   1422           }else{
  1422   1423             x = iField + regNewData + 1;
  1423   1424           }
  1424   1425           sqlite3VdbeAddOp2(v, OP_SCopy, x, regIdx+i);
................................................................................
  1469   1470           }
  1470   1471         }else{
  1471   1472           int x;
  1472   1473           /* Extract the PRIMARY KEY from the end of the index entry and
  1473   1474           ** store it in registers regR..regR+nPk-1 */
  1474   1475           if( pIdx!=pPk ){
  1475   1476             for(i=0; i<pPk->nKeyCol; i++){
         1477  +            assert( pPk->aiColumn[i]>=0 );
  1476   1478               x = sqlite3ColumnOfIndex(pIdx, pPk->aiColumn[i]);
  1477   1479               sqlite3VdbeAddOp3(v, OP_Column, iThisCur, x, regR+i);
  1478   1480               VdbeComment((v, "%s.%s", pTab->zName,
  1479   1481                            pTab->aCol[pPk->aiColumn[i]].zName));
  1480   1482             }
  1481   1483           }
  1482   1484           if( isUpdate ){
................................................................................
  1490   1492             int addrJump = sqlite3VdbeCurrentAddr(v)+pPk->nKeyCol;
  1491   1493             int op = OP_Ne;
  1492   1494             int regCmp = (IsPrimaryKeyIndex(pIdx) ? regIdx : regR);
  1493   1495     
  1494   1496             for(i=0; i<pPk->nKeyCol; i++){
  1495   1497               char *p4 = (char*)sqlite3LocateCollSeq(pParse, pPk->azColl[i]);
  1496   1498               x = pPk->aiColumn[i];
         1499  +            assert( x>=0 );
  1497   1500               if( i==(pPk->nKeyCol-1) ){
  1498   1501                 addrJump = addrUniqueOk;
  1499   1502                 op = OP_Eq;
  1500   1503               }
  1501   1504               sqlite3VdbeAddOp4(v, op, 
  1502   1505                   regOldData+1+x, addrJump, regCmp+i, p4, P4_COLLSEQ
  1503   1506               );
................................................................................
  1741   1744     if( pDest->onError!=pSrc->onError ){
  1742   1745       return 0;   /* Different conflict resolution strategies */
  1743   1746     }
  1744   1747     for(i=0; i<pSrc->nKeyCol; i++){
  1745   1748       if( pSrc->aiColumn[i]!=pDest->aiColumn[i] ){
  1746   1749         return 0;   /* Different columns indexed */
  1747   1750       }
  1748         -    if( pSrc->aiColumn[i]==(-2) ){
         1751  +    if( pSrc->aiColumn[i]==XN_EXPR ){
  1749   1752         assert( pSrc->aColExpr!=0 && pDest->aColExpr!=0 );
  1750   1753         if( sqlite3ExprCompare(pSrc->aColExpr->a[i].pExpr,
  1751   1754                                pDest->aColExpr->a[i].pExpr, -1)!=0 ){
  1752   1755           return 0;   /* Different expressions in the index */
  1753   1756         }
  1754   1757       }
  1755   1758       if( pSrc->aSortOrder[i]!=pDest->aSortOrder[i] ){

Changes to src/loadext.c.

   404    404     sqlite3_result_text64,
   405    405     sqlite3_strglob,
   406    406     /* Version 3.8.11 and later */
   407    407     (sqlite3_value*(*)(const sqlite3_value*))sqlite3_value_dup,
   408    408     sqlite3_value_free,
   409    409     sqlite3_result_zeroblob64,
   410    410     sqlite3_bind_zeroblob64,
   411         -  /* Version 3.8.12 and later */
          411  +  /* Version 3.9.0 and later */
   412    412     sqlite3_value_subtype,
   413    413     sqlite3_result_subtype
   414    414   };
   415    415   
   416    416   /*
   417    417   ** Attempt to load an SQLite extension library contained in the file
   418    418   ** zFile.  The entry point is zProc.  zProc may be 0 in which case a
................................................................................
   611    611   /*
   612    612   ** The auto-extension code added regardless of whether or not extension
   613    613   ** loading is supported.  We need a dummy sqlite3Apis pointer for that
   614    614   ** code if regular extension loading is not available.  This is that
   615    615   ** dummy pointer.
   616    616   */
   617    617   #ifdef SQLITE_OMIT_LOAD_EXTENSION
   618         -static const sqlite3_api_routines sqlite3Apis = { 0 };
          618  +static const sqlite3_api_routines sqlite3Apis;
   619    619   #endif
   620    620   
   621    621   
   622    622   /*
   623    623   ** The following object holds the list of automatically loaded
   624    624   ** extensions.
   625    625   **

Changes to src/main.c.

    21     21   #endif
    22     22   #ifdef SQLITE_ENABLE_RTREE
    23     23   # include "rtree.h"
    24     24   #endif
    25     25   #ifdef SQLITE_ENABLE_ICU
    26     26   # include "sqliteicu.h"
    27     27   #endif
           28  +#ifdef SQLITE_ENABLE_JSON1
           29  +int sqlite3Json1Init(sqlite3*);
           30  +#endif
           31  +#ifdef SQLITE_ENABLE_FTS5
           32  +int sqlite3Fts5Init(sqlite3*);
           33  +#endif
    28     34   
    29     35   #ifndef SQLITE_AMALGAMATION
    30     36   /* IMPLEMENTATION-OF: R-46656-45156 The sqlite3_version[] string constant
    31     37   ** contains the text of SQLITE_VERSION macro. 
    32     38   */
    33     39   const char sqlite3_version[] = SQLITE_VERSION;
    34     40   #endif
................................................................................
  2868   2874   #ifdef SQLITE_ENABLE_FTS2
  2869   2875     if( !db->mallocFailed && rc==SQLITE_OK ){
  2870   2876       extern int sqlite3Fts2Init(sqlite3*);
  2871   2877       rc = sqlite3Fts2Init(db);
  2872   2878     }
  2873   2879   #endif
  2874   2880   
  2875         -#ifdef SQLITE_ENABLE_FTS3
         2881  +#ifdef SQLITE_ENABLE_FTS3 /* automatically defined by SQLITE_ENABLE_FTS4 */
  2876   2882     if( !db->mallocFailed && rc==SQLITE_OK ){
  2877   2883       rc = sqlite3Fts3Init(db);
  2878   2884     }
  2879   2885   #endif
         2886  +
         2887  +#ifdef SQLITE_ENABLE_FTS5
         2888  +  if( !db->mallocFailed && rc==SQLITE_OK ){
         2889  +    rc = sqlite3Fts5Init(db);
         2890  +  }
         2891  +#endif
  2880   2892   
  2881   2893   #ifdef SQLITE_ENABLE_ICU
  2882   2894     if( !db->mallocFailed && rc==SQLITE_OK ){
  2883   2895       rc = sqlite3IcuInit(db);
  2884   2896     }
  2885   2897   #endif
  2886   2898   
................................................................................
  2891   2903   #endif
  2892   2904   
  2893   2905   #ifdef SQLITE_ENABLE_DBSTAT_VTAB
  2894   2906     if( !db->mallocFailed && rc==SQLITE_OK){
  2895   2907       rc = sqlite3DbstatRegister(db);
  2896   2908     }
  2897   2909   #endif
         2910  +
         2911  +#ifdef SQLITE_ENABLE_JSON1
         2912  +  if( !db->mallocFailed && rc==SQLITE_OK){
         2913  +    rc = sqlite3Json1Init(db);
         2914  +  }
         2915  +#endif
  2898   2916   
  2899   2917     /* -DSQLITE_DEFAULT_LOCKING_MODE=1 makes EXCLUSIVE the default locking
  2900   2918     ** mode.  -DSQLITE_DEFAULT_LOCKING_MODE=0 make NORMAL the default locking
  2901   2919     ** mode.  Doing nothing at all also makes NORMAL the default.
  2902   2920     */
  2903   2921   #ifdef SQLITE_DEFAULT_LOCKING_MODE
  2904   2922     db->dfltLockMode = SQLITE_DEFAULT_LOCKING_MODE;

Changes to src/mutex_unix.c.

    77     77   }
    78     78   static int pthreadMutexNotheld(sqlite3_mutex *p){
    79     79     return p->nRef==0 || pthread_equal(p->owner, pthread_self())==0;
    80     80   }
    81     81   #endif
    82     82   
    83     83   /*
    84         -** Try to provide a memory barrier operation, needed for initialization only.
           84  +** Try to provide a memory barrier operation, needed for initialization
           85  +** and also for the implementation of xShmBarrier in the VFS in cases
           86  +** where SQLite is compiled without mutexes.
    85     87   */
    86     88   void sqlite3MemoryBarrier(void){
    87     89   #if defined(SQLITE_MEMORY_BARRIER)
    88     90     SQLITE_MEMORY_BARRIER;
    89     91   #elif defined(__GNUC__) && GCC_VERSION>=4001000
    90     92     __sync_synchronize();
    91     93   #endif

Changes to src/mutex_w32.c.

    74     74   static int winMutexNotheld(sqlite3_mutex *p){
    75     75     DWORD tid = GetCurrentThreadId();
    76     76     return winMutexNotheld2(p, tid);
    77     77   }
    78     78   #endif
    79     79   
    80     80   /*
    81         -** Try to provide a memory barrier operation, needed for initialization only.
           81  +** Try to provide a memory barrier operation, needed for initialization
           82  +** and also for the xShmBarrier method of the VFS in cases when SQLite is
           83  +** compiled without mutexes (SQLITE_THREADSAFE=0).
    82     84   */
    83     85   void sqlite3MemoryBarrier(void){
    84     86   #if defined(SQLITE_MEMORY_BARRIER)
    85     87     SQLITE_MEMORY_BARRIER;
    86     88   #elif defined(__GNUC__)
    87     89     __sync_synchronize();
    88         -#else
           90  +#elif !defined(SQLITE_DISABLE_INTRINSIC) && \
           91  +      defined(_MSC_VER) && _MSC_VER>=1300
           92  +  _ReadWriteBarrier();
           93  +#elif defined(MemoryBarrier)
    89     94     MemoryBarrier();
    90     95   #endif
    91     96   }
    92     97   
    93     98   /*
    94     99   ** Initialize and deinitialize the mutex subsystem.
    95    100   */

Changes to src/pragma.c.

  1357   1357   
  1358   1358       /* Code that appears at the end of the integrity check.  If no error
  1359   1359       ** messages have been generated, output OK.  Otherwise output the
  1360   1360       ** error message
  1361   1361       */
  1362   1362       static const int iLn = VDBE_OFFSET_LINENO(2);
  1363   1363       static const VdbeOpList endCode[] = {
  1364         -      { OP_IfNeg,       1, 0,        0},    /* 0 */
  1365         -      { OP_String8,     0, 3,        0},    /* 1 */
         1364  +      { OP_AddImm,      1, 0,        0},    /* 0 */
         1365  +      { OP_If,          1, 0,        0},    /* 1 */
         1366  +      { OP_String8,     0, 3,        0},    /* 2 */
  1366   1367         { OP_ResultRow,   3, 1,        0},
  1367   1368       };
  1368   1369   
  1369   1370       int isQuick = (sqlite3Tolower(zLeft[0])=='q');
  1370   1371   
  1371   1372       /* If the PRAGMA command was of the form "PRAGMA <db>.integrity_check",
  1372   1373       ** then iDb is set to the index of the database identified by <db>.
................................................................................
  1520   1521             ** or (2) the next entry has a different key */
  1521   1522             if( IsUniqueIndex(pIdx) ){
  1522   1523               int uniqOk = sqlite3VdbeMakeLabel(v);
  1523   1524               int jmp6;
  1524   1525               int kk;
  1525   1526               for(kk=0; kk<pIdx->nKeyCol; kk++){
  1526   1527                 int iCol = pIdx->aiColumn[kk];
  1527         -              assert( iCol>=0 && iCol<pTab->nCol );
  1528         -              if( pTab->aCol[iCol].notNull ) continue;
         1528  +              assert( iCol!=XN_ROWID && iCol<pTab->nCol );
         1529  +              if( iCol>=0 && pTab->aCol[iCol].notNull ) continue;
  1529   1530                 sqlite3VdbeAddOp2(v, OP_IsNull, r1+kk, uniqOk);
  1530   1531                 VdbeCoverage(v);
  1531   1532               }
  1532   1533               jmp6 = sqlite3VdbeAddOp1(v, OP_Next, iIdxCur+j); VdbeCoverage(v);
  1533   1534               sqlite3VdbeGoto(v, uniqOk);
  1534   1535               sqlite3VdbeJumpHere(v, jmp6);
  1535   1536               sqlite3VdbeAddOp4Int(v, OP_IdxGT, iIdxCur+j, uniqOk, r1,
................................................................................
  1559   1560             sqlite3VdbeAddOp3(v, OP_Concat, 3, 2, 7);
  1560   1561             sqlite3VdbeAddOp2(v, OP_ResultRow, 7, 1);
  1561   1562           }
  1562   1563   #endif /* SQLITE_OMIT_BTREECOUNT */
  1563   1564         } 
  1564   1565       }
  1565   1566       addr = sqlite3VdbeAddOpList(v, ArraySize(endCode), endCode, iLn);
  1566         -    sqlite3VdbeChangeP3(v, addr, -mxErr);
  1567         -    sqlite3VdbeJumpHere(v, addr);
  1568         -    sqlite3VdbeChangeP4(v, addr+1, "ok", P4_STATIC);
         1567  +    sqlite3VdbeChangeP2(v, addr, -mxErr);
         1568  +    sqlite3VdbeJumpHere(v, addr+1);
         1569  +    sqlite3VdbeChangeP4(v, addr+2, "ok", P4_STATIC);
  1569   1570     }
  1570   1571     break;
  1571   1572   #endif /* SQLITE_OMIT_INTEGRITY_CHECK */
  1572   1573   
  1573   1574   #ifndef SQLITE_OMIT_UTF16
  1574   1575     /*
  1575   1576     **   PRAGMA encoding

Changes to src/select.c.

   575    575       int addr;
   576    576       int iLimit;
   577    577       if( pSelect->iOffset ){
   578    578         iLimit = pSelect->iOffset+1;
   579    579       }else{
   580    580         iLimit = pSelect->iLimit;
   581    581       }
   582         -    addr = sqlite3VdbeAddOp3(v, OP_IfNotZero, iLimit, 0, -1); VdbeCoverage(v);
          582  +    addr = sqlite3VdbeAddOp3(v, OP_IfNotZero, iLimit, 0, 1); VdbeCoverage(v);
   583    583       sqlite3VdbeAddOp1(v, OP_Last, pSort->iECursor);
   584    584       sqlite3VdbeAddOp1(v, OP_Delete, pSort->iECursor);
   585    585       sqlite3VdbeJumpHere(v, addr);
   586    586     }
   587    587   }
   588    588   
   589    589   /*
................................................................................
   591    591   */
   592    592   static void codeOffset(
   593    593     Vdbe *v,          /* Generate code into this VM */
   594    594     int iOffset,      /* Register holding the offset counter */
   595    595     int iContinue     /* Jump here to skip the current record */
   596    596   ){
   597    597     if( iOffset>0 ){
   598         -    int addr;
   599         -    addr = sqlite3VdbeAddOp3(v, OP_IfNeg, iOffset, 0, -1); VdbeCoverage(v);
   600         -    sqlite3VdbeGoto(v, iContinue);
   601         -    VdbeComment((v, "skip OFFSET records"));
   602         -    sqlite3VdbeJumpHere(v, addr);
          598  +    sqlite3VdbeAddOp3(v, OP_IfPos, iOffset, iContinue, 1); VdbeCoverage(v);
          599  +    VdbeComment((v, "OFFSET"));
   603    600     }
   604    601   }
   605    602   
   606    603   /*
   607    604   ** Add code that will check to make sure the N registers starting at iMem
   608    605   ** form a distinct entry.  iTab is a sorting index that holds previously
   609    606   ** seen combinations of the N values.  A new entry is made in iTab
................................................................................
  1811   1808   ** the reuse of the same limit and offset registers across multiple
  1812   1809   ** SELECT statements.
  1813   1810   */
  1814   1811   static void computeLimitRegisters(Parse *pParse, Select *p, int iBreak){
  1815   1812     Vdbe *v = 0;
  1816   1813     int iLimit = 0;
  1817   1814     int iOffset;
  1818         -  int addr1, n;
         1815  +  int n;
  1819   1816     if( p->iLimit ) return;
  1820   1817   
  1821   1818     /* 
  1822   1819     ** "LIMIT -1" always shows all rows.  There is some
  1823   1820     ** controversy about what the correct behavior should be.
  1824   1821     ** The current implementation interprets "LIMIT 0" to mean
  1825   1822     ** no rows.
................................................................................
  1846   1843       }
  1847   1844       if( p->pOffset ){
  1848   1845         p->iOffset = iOffset = ++pParse->nMem;
  1849   1846         pParse->nMem++;   /* Allocate an extra register for limit+offset */
  1850   1847         sqlite3ExprCode(pParse, p->pOffset, iOffset);
  1851   1848         sqlite3VdbeAddOp1(v, OP_MustBeInt, iOffset); VdbeCoverage(v);
  1852   1849         VdbeComment((v, "OFFSET counter"));
  1853         -      addr1 = sqlite3VdbeAddOp1(v, OP_IfPos, iOffset); VdbeCoverage(v);
  1854         -      sqlite3VdbeAddOp2(v, OP_Integer, 0, iOffset);
  1855         -      sqlite3VdbeJumpHere(v, addr1);
         1850  +      sqlite3VdbeAddOp3(v, OP_SetIfNotPos, iOffset, iOffset, 0);
  1856   1851         sqlite3VdbeAddOp3(v, OP_Add, iLimit, iOffset, iOffset+1);
  1857   1852         VdbeComment((v, "LIMIT+OFFSET"));
  1858         -      addr1 = sqlite3VdbeAddOp1(v, OP_IfPos, iLimit); VdbeCoverage(v);
  1859         -      sqlite3VdbeAddOp2(v, OP_Integer, -1, iOffset+1);
  1860         -      sqlite3VdbeJumpHere(v, addr1);
         1853  +      sqlite3VdbeAddOp3(v, OP_SetIfNotPos, iLimit, iOffset+1, -1);
  1861   1854       }
  1862   1855     }
  1863   1856   }
  1864   1857   
  1865   1858   #ifndef SQLITE_OMIT_COMPOUND_SELECT
  1866   1859   /*
  1867   1860   ** Return the appropriate collating sequence for the iCol-th column of
................................................................................
  2269   2262         }
  2270   2263         p->pPrior = 0;
  2271   2264         p->iLimit = pPrior->iLimit;
  2272   2265         p->iOffset = pPrior->iOffset;
  2273   2266         if( p->iLimit ){
  2274   2267           addr = sqlite3VdbeAddOp1(v, OP_IfNot, p->iLimit); VdbeCoverage(v);
  2275   2268           VdbeComment((v, "Jump ahead if LIMIT reached"));
         2269  +        if( p->iOffset ){
         2270  +          sqlite3VdbeAddOp3(v, OP_SetIfNotPos, p->iOffset, p->iOffset, 0);
         2271  +          sqlite3VdbeAddOp3(v, OP_Add, p->iLimit, p->iOffset, p->iOffset+1);
         2272  +          sqlite3VdbeAddOp3(v, OP_SetIfNotPos, p->iLimit, p->iOffset+1, -1);
         2273  +        }
  2276   2274         }
  2277   2275         explainSetInteger(iSub2, pParse->iNextSelectId);
  2278   2276         rc = sqlite3Select(pParse, p, &dest);
  2279   2277         testcase( rc!=SQLITE_OK );
  2280   2278         pDelete = p->pPrior;
  2281   2279         p->pPrior = pPrior;
  2282   2280         p->nSelectRow += pPrior->nSelectRow;
................................................................................
  2576   2574   
  2577   2575     addr = sqlite3VdbeCurrentAddr(v);
  2578   2576     iContinue = sqlite3VdbeMakeLabel(v);
  2579   2577   
  2580   2578     /* Suppress duplicates for UNION, EXCEPT, and INTERSECT 
  2581   2579     */
  2582   2580     if( regPrev ){
  2583         -    int j1, j2;
  2584         -    j1 = sqlite3VdbeAddOp1(v, OP_IfNot, regPrev); VdbeCoverage(v);
  2585         -    j2 = sqlite3VdbeAddOp4(v, OP_Compare, pIn->iSdst, regPrev+1, pIn->nSdst,
         2581  +    int addr1, addr2;
         2582  +    addr1 = sqlite3VdbeAddOp1(v, OP_IfNot, regPrev); VdbeCoverage(v);
         2583  +    addr2 = sqlite3VdbeAddOp4(v, OP_Compare, pIn->iSdst, regPrev+1, pIn->nSdst,
  2586   2584                                 (char*)sqlite3KeyInfoRef(pKeyInfo), P4_KEYINFO);
  2587         -    sqlite3VdbeAddOp3(v, OP_Jump, j2+2, iContinue, j2+2); VdbeCoverage(v);
  2588         -    sqlite3VdbeJumpHere(v, j1);
         2585  +    sqlite3VdbeAddOp3(v, OP_Jump, addr2+2, iContinue, addr2+2); VdbeCoverage(v);
         2586  +    sqlite3VdbeJumpHere(v, addr1);
  2589   2587       sqlite3VdbeAddOp3(v, OP_Copy, pIn->iSdst, regPrev+1, pIn->nSdst-1);
  2590   2588       sqlite3VdbeAddOp2(v, OP_Integer, 1, regPrev);
  2591   2589     }
  2592   2590     if( pParse->db->mallocFailed ) return 0;
  2593   2591   
  2594   2592     /* Suppress the first OFFSET entries if there is an OFFSET clause
  2595   2593     */
................................................................................
  2798   2796     int regLimitA;        /* Limit register for select-A */
  2799   2797     int regLimitB;        /* Limit register for select-A */
  2800   2798     int regPrev;          /* A range of registers to hold previous output */
  2801   2799     int savedLimit;       /* Saved value of p->iLimit */
  2802   2800     int savedOffset;      /* Saved value of p->iOffset */
  2803   2801     int labelCmpr;        /* Label for the start of the merge algorithm */
  2804   2802     int labelEnd;         /* Label for the end of the overall SELECT stmt */
  2805         -  int j1;               /* Jump instructions that get retargetted */
         2803  +  int addr1;            /* Jump instructions that get retargetted */
  2806   2804     int op;               /* One of TK_ALL, TK_UNION, TK_EXCEPT, TK_INTERSECT */
  2807   2805     KeyInfo *pKeyDup = 0; /* Comparison information for duplicate removal */
  2808   2806     KeyInfo *pKeyMerge;   /* Comparison information for merging rows */
  2809   2807     sqlite3 *db;          /* Database connection */
  2810   2808     ExprList *pOrderBy;   /* The ORDER BY clause */
  2811   2809     int nOrderBy;         /* Number of terms in the ORDER BY clause */
  2812   2810     int *aPermute;        /* Mapping from ORDER BY terms to result set columns */
................................................................................
  2934   2932     sqlite3SelectDestInit(&destA, SRT_Coroutine, regAddrA);
  2935   2933     sqlite3SelectDestInit(&destB, SRT_Coroutine, regAddrB);
  2936   2934   
  2937   2935     /* Generate a coroutine to evaluate the SELECT statement to the
  2938   2936     ** left of the compound operator - the "A" select.
  2939   2937     */
  2940   2938     addrSelectA = sqlite3VdbeCurrentAddr(v) + 1;
  2941         -  j1 = sqlite3VdbeAddOp3(v, OP_InitCoroutine, regAddrA, 0, addrSelectA);
         2939  +  addr1 = sqlite3VdbeAddOp3(v, OP_InitCoroutine, regAddrA, 0, addrSelectA);
  2942   2940     VdbeComment((v, "left SELECT"));
  2943   2941     pPrior->iLimit = regLimitA;
  2944   2942     explainSetInteger(iSub1, pParse->iNextSelectId);
  2945   2943     sqlite3Select(pParse, pPrior, &destA);
  2946   2944     sqlite3VdbeAddOp1(v, OP_EndCoroutine, regAddrA);
  2947         -  sqlite3VdbeJumpHere(v, j1);
         2945  +  sqlite3VdbeJumpHere(v, addr1);
  2948   2946   
  2949   2947     /* Generate a coroutine to evaluate the SELECT statement on 
  2950   2948     ** the right - the "B" select
  2951   2949     */
  2952   2950     addrSelectB = sqlite3VdbeCurrentAddr(v) + 1;
  2953         -  j1 = sqlite3VdbeAddOp3(v, OP_InitCoroutine, regAddrB, 0, addrSelectB);
         2951  +  addr1 = sqlite3VdbeAddOp3(v, OP_InitCoroutine, regAddrB, 0, addrSelectB);
  2954   2952     VdbeComment((v, "right SELECT"));
  2955   2953     savedLimit = p->iLimit;
  2956   2954     savedOffset = p->iOffset;
  2957   2955     p->iLimit = regLimitB;
  2958   2956     p->iOffset = 0;  
  2959   2957     explainSetInteger(iSub2, pParse->iNextSelectId);
  2960   2958     sqlite3Select(pParse, p, &destB);
................................................................................
  3037   3035       sqlite3VdbeAddOp2(v, OP_Gosub, regOutB, addrOutB);
  3038   3036     }
  3039   3037     sqlite3VdbeAddOp2(v, OP_Yield, regAddrB, addrEofB); VdbeCoverage(v);
  3040   3038     sqlite3VdbeGoto(v, labelCmpr);
  3041   3039   
  3042   3040     /* This code runs once to initialize everything.
  3043   3041     */
  3044         -  sqlite3VdbeJumpHere(v, j1);
         3042  +  sqlite3VdbeJumpHere(v, addr1);
  3045   3043     sqlite3VdbeAddOp2(v, OP_Yield, regAddrA, addrEofA_noB); VdbeCoverage(v);
  3046   3044     sqlite3VdbeAddOp2(v, OP_Yield, regAddrB, addrEofB); VdbeCoverage(v);
  3047   3045   
  3048   3046     /* Implement the main merge loop
  3049   3047     */
  3050   3048     sqlite3VdbeResolveLabel(v, labelCmpr);
  3051   3049     sqlite3VdbeAddOp4(v, OP_Permutation, 0, 0, 0, (char*)aPermute, P4_INTARRAY);
................................................................................
  3080   3078     return pParse->nErr!=0;
  3081   3079   }
  3082   3080   #endif
  3083   3081   
  3084   3082   #if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
  3085   3083   /* Forward Declarations */
  3086   3084   static void substExprList(sqlite3*, ExprList*, int, ExprList*);
  3087         -static void substSelect(sqlite3*, Select *, int, ExprList *);
         3085  +static void substSelect(sqlite3*, Select *, int, ExprList*, int);
  3088   3086   
  3089   3087   /*
  3090   3088   ** Scan through the expression pExpr.  Replace every reference to
  3091   3089   ** a column in table number iTable with a copy of the iColumn-th
  3092   3090   ** entry in pEList.  (But leave references to the ROWID column 
  3093   3091   ** unchanged.)
  3094   3092   **
................................................................................
  3117   3115         sqlite3ExprDelete(db, pExpr);
  3118   3116         pExpr = pNew;
  3119   3117       }
  3120   3118     }else{
  3121   3119       pExpr->pLeft = substExpr(db, pExpr->pLeft, iTable, pEList);
  3122   3120       pExpr->pRight = substExpr(db, pExpr->pRight, iTable, pEList);
  3123   3121       if( ExprHasProperty(pExpr, EP_xIsSelect) ){
  3124         -      substSelect(db, pExpr->x.pSelect, iTable, pEList);
         3122  +      substSelect(db, pExpr->x.pSelect, iTable, pEList, 1);
  3125   3123       }else{
  3126   3124         substExprList(db, pExpr->x.pList, iTable, pEList);
  3127   3125       }
  3128   3126     }
  3129   3127     return pExpr;
  3130   3128   }
  3131   3129   static void substExprList(
................................................................................
  3140   3138       pList->a[i].pExpr = substExpr(db, pList->a[i].pExpr, iTable, pEList);
  3141   3139     }
  3142   3140   }
  3143   3141   static void substSelect(
  3144   3142     sqlite3 *db,         /* Report malloc errors here */
  3145   3143     Select *p,           /* SELECT statement in which to make substitutions */
  3146   3144     int iTable,          /* Table to be replaced */
  3147         -  ExprList *pEList     /* Substitute values */
         3145  +  ExprList *pEList,    /* Substitute values */
         3146  +  int doPrior          /* Do substitutes on p->pPrior too */
  3148   3147   ){
  3149   3148     SrcList *pSrc;
  3150   3149     struct SrcList_item *pItem;
  3151   3150     int i;
  3152   3151     if( !p ) return;
  3153         -  substExprList(db, p->pEList, iTable, pEList);
  3154         -  substExprList(db, p->pGroupBy, iTable, pEList);
  3155         -  substExprList(db, p->pOrderBy, iTable, pEList);
  3156         -  p->pHaving = substExpr(db, p->pHaving, iTable, pEList);
  3157         -  p->pWhere = substExpr(db, p->pWhere, iTable, pEList);
  3158         -  substSelect(db, p->pPrior, iTable, pEList);
  3159         -  pSrc = p->pSrc;
  3160         -  assert( pSrc );  /* Even for (SELECT 1) we have: pSrc!=0 but pSrc->nSrc==0 */
  3161         -  if( ALWAYS(pSrc) ){
         3152  +  do{
         3153  +    substExprList(db, p->pEList, iTable, pEList);
         3154  +    substExprList(db, p->pGroupBy, iTable, pEList);
         3155  +    substExprList(db, p->pOrderBy, iTable, pEList);
         3156  +    p->pHaving = substExpr(db, p->pHaving, iTable, pEList);
         3157  +    p->pWhere = substExpr(db, p->pWhere, iTable, pEList);
         3158  +    pSrc = p->pSrc;
         3159  +    assert( pSrc!=0 );
  3162   3160       for(i=pSrc->nSrc, pItem=pSrc->a; i>0; i--, pItem++){
  3163         -      substSelect(db, pItem->pSelect, iTable, pEList);
         3161  +      substSelect(db, pItem->pSelect, iTable, pEList, 1);
         3162  +      if( pItem->fg.isTabFunc ){
         3163  +        substExprList(db, pItem->u1.pFuncArg, iTable, pEList);
         3164  +      }
  3164   3165       }
  3165         -  }
         3166  +  }while( doPrior && (p = p->pPrior)!=0 );
  3166   3167   }
  3167   3168   #endif /* !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) */
  3168   3169   
  3169   3170   #if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
  3170   3171   /*
  3171   3172   ** This routine attempts to flatten subqueries as a performance optimization.
  3172   3173   ** This routine returns 1 if it makes changes and 0 if no flattening occurs.
................................................................................
  3310   3311     Parse *pParse,       /* Parsing context */
  3311   3312     Select *p,           /* The parent or outer SELECT statement */
  3312   3313     int iFrom,           /* Index in p->pSrc->a[] of the inner subquery */
  3313   3314     int isAgg,           /* True if outer SELECT uses aggregate functions */
  3314   3315     int subqueryIsAgg    /* True if the subquery uses aggregate functions */
  3315   3316   ){
  3316   3317     const char *zSavedAuthContext = pParse->zAuthContext;
  3317         -  Select *pParent;
         3318  +  Select *pParent;    /* Current UNION ALL term of the other query */
  3318   3319     Select *pSub;       /* The inner query or "subquery" */
  3319   3320     Select *pSub1;      /* Pointer to the rightmost select in sub-query */
  3320   3321     SrcList *pSrc;      /* The FROM clause of the outer query */
  3321   3322     SrcList *pSubSrc;   /* The FROM clause of the subquery */
  3322   3323     ExprList *pList;    /* The result set of the outer query */
  3323   3324     int iParent;        /* VDBE cursor number of the pSub result set temp table */
  3324   3325     int i;              /* Loop counter */
................................................................................
  3605   3606       **
  3606   3607       ** Example:
  3607   3608       **
  3608   3609       **    SELECT * FROM tabA, (SELECT * FROM sub1, sub2), tabB;
  3609   3610       **
  3610   3611       ** The outer query has 3 slots in its FROM clause.  One slot of the
  3611   3612       ** outer query (the middle slot) is used by the subquery.  The next
  3612         -    ** block of code will expand the out query to 4 slots.  The middle
  3613         -    ** slot is expanded to two slots in order to make space for the
  3614         -    ** two elements in the FROM clause of the subquery.
         3613  +    ** block of code will expand the outer query FROM clause to 4 slots.
         3614  +    ** The middle slot is expanded to two slots in order to make space
         3615  +    ** for the two elements in the FROM clause of the subquery.
  3615   3616       */
  3616   3617       if( nSubSrc>1 ){
  3617   3618         pParent->pSrc = pSrc = sqlite3SrcListEnlarge(db, pSrc, nSubSrc-1,iFrom+1);
  3618   3619         if( db->mallocFailed ){
  3619   3620           break;
  3620   3621         }
  3621   3622       }
................................................................................
  3646   3647       for(i=0; i<pList->nExpr; i++){
  3647   3648         if( pList->a[i].zName==0 ){
  3648   3649           char *zName = sqlite3DbStrDup(db, pList->a[i].zSpan);
  3649   3650           sqlite3Dequote(zName);
  3650   3651           pList->a[i].zName = zName;
  3651   3652         }
  3652   3653       }
  3653         -    substExprList(db, pParent->pEList, iParent, pSub->pEList);
  3654         -    if( isAgg ){
  3655         -      substExprList(db, pParent->pGroupBy, iParent, pSub->pEList);
  3656         -      pParent->pHaving = substExpr(db, pParent->pHaving, iParent, pSub->pEList);
  3657         -    }
  3658   3654       if( pSub->pOrderBy ){
  3659   3655         /* At this point, any non-zero iOrderByCol values indicate that the
  3660   3656         ** ORDER BY column expression is identical to the iOrderByCol'th
  3661   3657         ** expression returned by SELECT statement pSub. Since these values
  3662   3658         ** do not necessarily correspond to columns in SELECT statement pParent,
  3663   3659         ** zero them before transfering the ORDER BY clause.
  3664   3660         **
................................................................................
  3670   3666         for(i=0; i<pOrderBy->nExpr; i++){
  3671   3667           pOrderBy->a[i].u.x.iOrderByCol = 0;
  3672   3668         }
  3673   3669         assert( pParent->pOrderBy==0 );
  3674   3670         assert( pSub->pPrior==0 );
  3675   3671         pParent->pOrderBy = pOrderBy;
  3676   3672         pSub->pOrderBy = 0;
  3677         -    }else if( pParent->pOrderBy ){
  3678         -      substExprList(db, pParent->pOrderBy, iParent, pSub->pEList);
  3679   3673       }
  3680         -    if( pSub->pWhere ){
  3681         -      pWhere = sqlite3ExprDup(db, pSub->pWhere, 0);
  3682         -    }else{
  3683         -      pWhere = 0;
  3684         -    }
         3674  +    pWhere = sqlite3ExprDup(db, pSub->pWhere, 0);
  3685   3675       if( subqueryIsAgg ){
  3686   3676         assert( pParent->pHaving==0 );
  3687   3677         pParent->pHaving = pParent->pWhere;
  3688   3678         pParent->pWhere = pWhere;
  3689         -      pParent->pHaving = substExpr(db, pParent->pHaving, iParent, pSub->pEList);
  3690   3679         pParent->pHaving = sqlite3ExprAnd(db, pParent->pHaving, 
  3691   3680                                     sqlite3ExprDup(db, pSub->pHaving, 0));
  3692   3681         assert( pParent->pGroupBy==0 );
  3693   3682         pParent->pGroupBy = sqlite3ExprListDup(db, pSub->pGroupBy, 0);
  3694   3683       }else{
  3695         -      pParent->pWhere = substExpr(db, pParent->pWhere, iParent, pSub->pEList);
  3696   3684         pParent->pWhere = sqlite3ExprAnd(db, pParent->pWhere, pWhere);
  3697   3685       }
         3686  +    substSelect(db, pParent, iParent, pSub->pEList, 0);
  3698   3687     
  3699   3688       /* The flattened query is distinct if either the inner or the
  3700   3689       ** outer query is distinct. 
  3701   3690       */
  3702   3691       pParent->selFlags |= pSub->selFlags & SF_Distinct;
  3703   3692     
  3704   3693       /*
................................................................................
  4217   4206   
  4218   4207     /* Look up every table named in the FROM clause of the select.  If
  4219   4208     ** an entry of the FROM clause is a subquery instead of a table or view,
  4220   4209     ** then create a transient table structure to describe the subquery.
  4221   4210     */
  4222   4211     for(i=0, pFrom=pTabList->a; i<pTabList->nSrc; i++, pFrom++){
  4223   4212       Table *pTab;
  4224         -    assert( pFrom->fg.isRecursive==0 || pFrom->pTab );
         4213  +    assert( pFrom->fg.isRecursive==0 || pFrom->pTab!=0 );
  4225   4214       if( pFrom->fg.isRecursive ) continue;
  4226         -    if( pFrom->pTab!=0 ){
  4227         -      /* This statement has already been prepared.  There is no need
  4228         -      ** to go further. */
  4229         -      assert( i==0 );
  4230         -#ifndef SQLITE_OMIT_CTE
  4231         -      selectPopWith(pWalker, p);
  4232         -#endif
  4233         -      return WRC_Prune;
  4234         -    }
         4215  +    assert( pFrom->pTab==0 );
  4235   4216   #ifndef SQLITE_OMIT_CTE
  4236   4217       if( withExpand(pWalker, pFrom) ) return WRC_Abort;
  4237   4218       if( pFrom->pTab ) {} else
  4238   4219   #endif
  4239   4220       if( pFrom->zName==0 ){
  4240   4221   #ifndef SQLITE_OMIT_SUBQUERY
  4241   4222         Select *pSel = pFrom->pSelect;
................................................................................
  4263   4244              pTab->zName);
  4264   4245           pFrom->pTab = 0;
  4265   4246           return WRC_Abort;
  4266   4247         }
  4267   4248         pTab->nRef++;
  4268   4249   #if !defined(SQLITE_OMIT_VIEW) || !defined (SQLITE_OMIT_VIRTUALTABLE)
  4269   4250         if( pTab->pSelect || IsVirtual(pTab) ){
         4251  +        i16 nCol;
  4270   4252           if( sqlite3ViewGetColumnNames(pParse, pTab) ) return WRC_Abort;
  4271   4253           assert( pFrom->pSelect==0 );
  4272   4254           if( pFrom->fg.isTabFunc && !IsVirtual(pTab) ){
  4273   4255             sqlite3ErrorMsg(pParse, "'%s' is not a function", pTab->zName);
  4274   4256             return WRC_Abort;
  4275   4257           }
  4276   4258           pFrom->pSelect = sqlite3SelectDup(db, pTab->pSelect, 0);
  4277   4259           sqlite3SelectSetName(pFrom->pSelect, pTab->zName);
         4260  +        nCol = pTab->nCol;
         4261  +        pTab->nCol = -1;
  4278   4262           sqlite3WalkSelect(pWalker, pFrom->pSelect);
         4263  +        pTab->nCol = nCol;
  4279   4264         }
  4280   4265   #endif
  4281   4266       }
  4282   4267   
  4283   4268       /* Locate the index named by the INDEXED BY clause, if any. */
  4284   4269       if( sqlite3IndexedByLookup(pParse, pFrom) ){
  4285   4270         return WRC_Abort;
................................................................................
  4519   4504   static void selectAddSubqueryTypeInfo(Walker *pWalker, Select *p){
  4520   4505     Parse *pParse;
  4521   4506     int i;
  4522   4507     SrcList *pTabList;
  4523   4508     struct SrcList_item *pFrom;
  4524   4509   
  4525   4510     assert( p->selFlags & SF_Resolved );
  4526         -  if( (p->selFlags & SF_HasTypeInfo)==0 ){
  4527         -    p->selFlags |= SF_HasTypeInfo;
  4528         -    pParse = pWalker->pParse;
  4529         -    pTabList = p->pSrc;
  4530         -    for(i=0, pFrom=pTabList->a; i<pTabList->nSrc; i++, pFrom++){
  4531         -      Table *pTab = pFrom->pTab;
  4532         -      if( ALWAYS(pTab!=0) && (pTab->tabFlags & TF_Ephemeral)!=0 ){
  4533         -        /* A sub-query in the FROM clause of a SELECT */
  4534         -        Select *pSel = pFrom->pSelect;
  4535         -        if( pSel ){
  4536         -          while( pSel->pPrior ) pSel = pSel->pPrior;
  4537         -          selectAddColumnTypeAndCollation(pParse, pTab, pSel);
  4538         -        }
         4511  +  assert( (p->selFlags & SF_HasTypeInfo)==0 );
         4512  +  p->selFlags |= SF_HasTypeInfo;
         4513  +  pParse = pWalker->pParse;
         4514  +  pTabList = p->pSrc;
         4515  +  for(i=0, pFrom=pTabList->a; i<pTabList->nSrc; i++, pFrom++){
         4516  +    Table *pTab = pFrom->pTab;
         4517  +    assert( pTab!=0 );
         4518  +    if( (pTab->tabFlags & TF_Ephemeral)!=0 ){
         4519  +      /* A sub-query in the FROM clause of a SELECT */
         4520  +      Select *pSel = pFrom->pSelect;
         4521  +      if( pSel ){
         4522  +        while( pSel->pPrior ) pSel = pSel->pPrior;
         4523  +        selectAddColumnTypeAndCollation(pParse, pTab, pSel);
  4539   4524         }
  4540   4525       }
  4541   4526     }
  4542   4527   }
  4543   4528   #endif
  4544   4529   
  4545   4530   
................................................................................
  4857   4842     /* Try to flatten subqueries in the FROM clause up into the main query
  4858   4843     */
  4859   4844   #if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
  4860   4845     for(i=0; !p->pPrior && i<pTabList->nSrc; i++){
  4861   4846       struct SrcList_item *pItem = &pTabList->a[i];
  4862   4847       Select *pSub = pItem->pSelect;
  4863   4848       int isAggSub;
         4849  +    Table *pTab = pItem->pTab;
  4864   4850       if( pSub==0 ) continue;
         4851  +
         4852  +    /* Catch mismatch in the declared columns of a view and the number of
         4853  +    ** columns in the SELECT on the RHS */
         4854  +    if( pTab->nCol!=pSub->pEList->nExpr ){
         4855  +      sqlite3ErrorMsg(pParse, "expected %d columns for '%s' but got %d",
         4856  +                      pTab->nCol, pTab->zName, pSub->pEList->nExpr);
         4857  +      goto select_end;
         4858  +    }
         4859  +
  4865   4860       isAggSub = (pSub->selFlags & SF_Aggregate)!=0;
  4866   4861       if( flattenSubquery(pParse, p, i, isAgg, isAggSub) ){
  4867   4862         /* This subquery can be absorbed into its parent. */
  4868   4863         if( isAggSub ){
  4869   4864           isAgg = 1;
  4870   4865           p->selFlags |= SF_Aggregate;
  4871   4866         }
................................................................................
  5209   5204       if( db->mallocFailed ) goto select_end;
  5210   5205   
  5211   5206       /* Processing for aggregates with GROUP BY is very different and
  5212   5207       ** much more complex than aggregates without a GROUP BY.
  5213   5208       */
  5214   5209       if( pGroupBy ){
  5215   5210         KeyInfo *pKeyInfo;  /* Keying information for the group by clause */
  5216         -      int j1;             /* A-vs-B comparision jump */
         5211  +      int addr1;          /* A-vs-B comparision jump */
  5217   5212         int addrOutputRow;  /* Start of subroutine that outputs a result row */
  5218   5213         int regOutputRow;   /* Return address register for output subroutine */
  5219   5214         int addrSetAbort;   /* Set the abort flag and return */
  5220   5215         int addrTopOfLoop;  /* Top of the input loop */
  5221   5216         int addrSortingIdx; /* The OP_OpenEphemeral for the sorting index */
  5222   5217         int addrReset;      /* Subroutine for resetting the accumulator */
  5223   5218         int regReset;       /* Return address register for reset subroutine */
................................................................................
  5357   5352           }else{
  5358   5353             sAggInfo.directMode = 1;
  5359   5354             sqlite3ExprCode(pParse, pGroupBy->a[j].pExpr, iBMem+j);
  5360   5355           }
  5361   5356         }
  5362   5357         sqlite3VdbeAddOp4(v, OP_Compare, iAMem, iBMem, pGroupBy->nExpr,
  5363   5358                             (char*)sqlite3KeyInfoRef(pKeyInfo), P4_KEYINFO);
  5364         -      j1 = sqlite3VdbeCurrentAddr(v);
  5365         -      sqlite3VdbeAddOp3(v, OP_Jump, j1+1, 0, j1+1); VdbeCoverage(v);
         5359  +      addr1 = sqlite3VdbeCurrentAddr(v);
         5360  +      sqlite3VdbeAddOp3(v, OP_Jump, addr1+1, 0, addr1+1); VdbeCoverage(v);
  5366   5361   
  5367   5362         /* Generate code that runs whenever the GROUP BY changes.
  5368   5363         ** Changes in the GROUP BY are detected by the previous code
  5369   5364         ** block.  If there were no changes, this block is skipped.
  5370   5365         **
  5371   5366         ** This code copies current group by terms in b0,b1,b2,...
  5372   5367         ** over to a0,a1,a2.  It then calls the output subroutine
................................................................................
  5380   5375         VdbeComment((v, "check abort flag"));
  5381   5376         sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset);
  5382   5377         VdbeComment((v, "reset accumulator"));
  5383   5378   
  5384   5379         /* Update the aggregate accumulators based on the content of
  5385   5380         ** the current row
  5386   5381         */
  5387         -      sqlite3VdbeJumpHere(v, j1);
         5382  +      sqlite3VdbeJumpHere(v, addr1);
  5388   5383         updateAccumulator(pParse, &sAggInfo);
  5389   5384         sqlite3VdbeAddOp2(v, OP_Integer, 1, iUseFlag);
  5390   5385         VdbeComment((v, "indicate data in accumulator"));
  5391   5386   
  5392   5387         /* End of the loop
  5393   5388         */
  5394   5389         if( groupBySort ){

Changes to src/shell.c.

  2608   2608       sqlite3_free(zSql);
  2609   2609       fprintf(p->out, "%-20s %d\n", aQuery[i].zName, val);
  2610   2610     }
  2611   2611     sqlite3_free(zSchemaTab);
  2612   2612     return 0;
  2613   2613   }
  2614   2614   
         2615  +/*
         2616  +** Print the current sqlite3_errmsg() value to stderr and return 1.
         2617  +*/
         2618  +static int shellDatabaseError(sqlite3 *db){
         2619  +  const char *zErr = sqlite3_errmsg(db);
         2620  +  fprintf(stderr, "Error: %s\n", zErr);
         2621  +  return 1;
         2622  +}
         2623  +
         2624  +/*
         2625  +** Print an out-of-memory message to stderr and return 1.
         2626  +*/
         2627  +static int shellNomemError(void){
         2628  +  fprintf(stderr, "Error: out of memory\n");
         2629  +  return 1;
         2630  +}
  2615   2631   
  2616   2632   /*
  2617   2633   ** If an input line begins with "." then invoke this routine to
  2618   2634   ** process that line.
  2619   2635   **
  2620   2636   ** Return 1 on error, 2 to exit, and 0 otherwise.
  2621   2637   */
................................................................................
  3709   3725       sqlite3_stmt *pStmt;
  3710   3726       char **azResult;
  3711   3727       int nRow, nAlloc;
  3712   3728       char *zSql = 0;
  3713   3729       int ii;
  3714   3730       open_db(p, 0);
  3715   3731       rc = sqlite3_prepare_v2(p->db, "PRAGMA database_list", -1, &pStmt, 0);
  3716         -    if( rc ) return rc;
         3732  +    if( rc ) return shellDatabaseError(p->db);
         3733  +
         3734  +    /* Create an SQL statement to query for the list of tables in the
         3735  +    ** main and all attached databases where the table name matches the
         3736  +    ** LIKE pattern bound to variable "?1". */
  3717   3737       zSql = sqlite3_mprintf(
  3718   3738           "SELECT name FROM sqlite_master"
  3719   3739           " WHERE type IN ('table','view')"
  3720   3740           "   AND name NOT LIKE 'sqlite_%%'"
  3721   3741           "   AND name LIKE ?1");
  3722         -    while( sqlite3_step(pStmt)==SQLITE_ROW ){
         3742  +    while( zSql && sqlite3_step(pStmt)==SQLITE_ROW ){
  3723   3743         const char *zDbName = (const char*)sqlite3_column_text(pStmt, 1);
  3724   3744         if( zDbName==0 || strcmp(zDbName,"main")==0 ) continue;
  3725   3745         if( strcmp(zDbName,"temp")==0 ){
  3726   3746           zSql = sqlite3_mprintf(
  3727   3747                    "%z UNION ALL "
  3728   3748                    "SELECT 'temp.' || name FROM sqlite_temp_master"
  3729   3749                    " WHERE type IN ('table','view')"
................................................................................
  3734   3754                    "%z UNION ALL "
  3735   3755                    "SELECT '%q.' || name FROM \"%w\".sqlite_master"
  3736   3756                    " WHERE type IN ('table','view')"
  3737   3757                    "   AND name NOT LIKE 'sqlite_%%'"
  3738   3758                    "   AND name LIKE ?1", zSql, zDbName, zDbName);
  3739   3759         }
  3740   3760       }
  3741         -    sqlite3_finalize(pStmt);
  3742         -    zSql = sqlite3_mprintf("%z ORDER BY 1", zSql);
  3743         -    rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
         3761  +    rc = sqlite3_finalize(pStmt);
         3762  +    if( zSql && rc==SQLITE_OK ){
         3763  +      zSql = sqlite3_mprintf("%z ORDER BY 1", zSql);
         3764  +      if( zSql ) rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
         3765  +    }
  3744   3766       sqlite3_free(zSql);
  3745         -    if( rc ) return rc;
         3767  +    if( !zSql ) return shellNomemError();
         3768  +    if( rc ) return shellDatabaseError(p->db);
         3769  +
         3770  +    /* Run the SQL statement prepared by the above block. Store the results
         3771  +    ** as an array of nul-terminated strings in azResult[].  */
  3746   3772       nRow = nAlloc = 0;
  3747   3773       azResult = 0;
  3748   3774       if( nArg>1 ){
  3749   3775         sqlite3_bind_text(pStmt, 1, azArg[1], -1, SQLITE_TRANSIENT);
  3750   3776       }else{
  3751   3777         sqlite3_bind_text(pStmt, 1, "%", -1, SQLITE_STATIC);
  3752   3778       }
  3753   3779       while( sqlite3_step(pStmt)==SQLITE_ROW ){
  3754   3780         if( nRow>=nAlloc ){
  3755   3781           char **azNew;
  3756   3782           int n2 = nAlloc*2 + 10;
  3757   3783           azNew = sqlite3_realloc64(azResult, sizeof(azResult[0])*n2);
  3758   3784           if( azNew==0 ){
  3759         -          fprintf(stderr, "Error: out of memory\n");
         3785  +          rc = shellNomemError();
  3760   3786             break;
  3761   3787           }
  3762   3788           nAlloc = n2;
  3763   3789           azResult = azNew;
  3764   3790         }
  3765   3791         azResult[nRow] = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 0));
  3766         -      if( azResult[nRow] ) nRow++;
         3792  +      if( 0==azResult[nRow] ){
         3793  +        rc = shellNomemError();
         3794  +        break;
         3795  +      }
         3796  +      nRow++;
  3767   3797       }
  3768         -    sqlite3_finalize(pStmt);        
  3769         -    if( nRow>0 ){
         3798  +    if( sqlite3_finalize(pStmt)!=SQLITE_OK ){
         3799  +      rc = shellDatabaseError(p->db);
         3800  +    }
         3801  +
         3802  +    /* Pretty-print the contents of array azResult[] to the output */
         3803  +    if( rc==0 && nRow>0 ){
  3770   3804         int len, maxlen = 0;
  3771   3805         int i, j;
  3772   3806         int nPrintCol, nPrintRow;
  3773   3807         for(i=0; i<nRow; i++){
  3774   3808           len = strlen30(azResult[i]);
  3775   3809           if( len>maxlen ) maxlen = len;
  3776   3810         }
................................................................................
  3781   3815           for(j=i; j<nRow; j+=nPrintRow){
  3782   3816             char *zSp = j<nPrintRow ? "" : "  ";
  3783   3817             fprintf(p->out, "%s%-*s", zSp, maxlen, azResult[j] ? azResult[j]:"");
  3784   3818           }
  3785   3819           fprintf(p->out, "\n");
  3786   3820         }
  3787   3821       }
         3822  +
  3788   3823       for(ii=0; ii<nRow; ii++) sqlite3_free(azResult[ii]);
  3789   3824       sqlite3_free(azResult);
  3790   3825     }else
  3791   3826   
  3792   3827     if( c=='t' && n>=8 && strncmp(azArg[0], "testctrl", n)==0 && nArg>=2 ){
  3793   3828       static const struct {
  3794   3829          const char *zCtrlName;   /* Name of a test-control option */
................................................................................
  4615   4650   #else
  4616   4651       fprintf(stderr,"%s: Error: no database filename specified\n", Argv0);
  4617   4652       return 1;
  4618   4653   #endif
  4619   4654     }
  4620   4655     data.out = stdout;
  4621   4656   
  4622         -#ifdef SQLITE_ENABLE_JSON1
  4623         -  {
  4624         -    extern int sqlite3_json_init(sqlite3*);
  4625         -    sqlite3_auto_extension((void(*)(void))sqlite3_json_init);
  4626         -  }
  4627         -#endif
  4628         -
  4629   4657     /* Go ahead and open the database file if it already exists.  If the
  4630   4658     ** file does not exist, delay opening it.  This prevents empty database
  4631   4659     ** files from being created if a user mistypes the database name argument
  4632   4660     ** to the sqlite command-line tool.
  4633   4661     */
  4634   4662     if( access(data.zDbFilename, 0)==0 ){
  4635   4663       open_db(&data, 0);

Changes to src/sqlite.h.in.

  4356   4356   const void *sqlite3_value_text16(sqlite3_value*);
  4357   4357   const void *sqlite3_value_text16le(sqlite3_value*);
  4358   4358   const void *sqlite3_value_text16be(sqlite3_value*);
  4359   4359   int sqlite3_value_type(sqlite3_value*);
  4360   4360   int sqlite3_value_numeric_type(sqlite3_value*);
  4361   4361   
  4362   4362   /*
  4363         -** CAPI3REF: Obtaining SQL Values
         4363  +** CAPI3REF: Finding The Subtype Of SQL Values
  4364   4364   ** METHOD: sqlite3_value
  4365   4365   **
  4366   4366   ** The sqlite3_value_subtype(V) function returns the subtype for
  4367   4367   ** an [application-defined SQL function] argument V.  The subtype
  4368   4368   ** information can be used to pass a limited amount of context from
  4369   4369   ** one SQL function to another.  Use the [sqlite3_result_subtype()]
  4370   4370   ** routine to set the subtype for the return value of an SQL function.
................................................................................
  5629   5629   ** strategy. A cost of N indicates that the cost of the strategy is similar
  5630   5630   ** to a linear scan of an SQLite table with N rows. A cost of log(N) 
  5631   5631   ** indicates that the expense of the operation is similar to that of a
  5632   5632   ** binary search on a unique indexed field of an SQLite table with N rows.
  5633   5633   **
  5634   5634   ** ^The estimatedRows value is an estimate of the number of rows that
  5635   5635   ** will be returned by the strategy.
         5636  +**
         5637  +** The xBestIndex method may optionally populate the idxFlags field with a 
         5638  +** mask of SQLITE_INDEX_SCAN_* flags. Currently there is only one such flag -
         5639  +** SQLITE_INDEX_SCAN_UNIQUE. If the xBestIndex method sets this flag, SQLite
         5640  +** assumes that the strategy may visit at most one row. 
         5641  +**
         5642  +** Additionally, if xBestIndex sets the SQLITE_INDEX_SCAN_UNIQUE flag, then
         5643  +** SQLite also assumes that if a call to the xUpdate() method is made as
         5644  +** part of the same statement to delete or update a virtual table row and the
         5645  +** implementation returns SQLITE_CONSTRAINT, then there is no need to rollback
         5646  +** any database changes. In other words, if the xUpdate() returns
         5647  +** SQLITE_CONSTRAINT, the database contents must be exactly as they were
         5648  +** before xUpdate was called. By contrast, if SQLITE_INDEX_SCAN_UNIQUE is not
         5649  +** set and xUpdate returns SQLITE_CONSTRAINT, any database changes made by
         5650  +** the xUpdate method are automatically rolled back by SQLite.
  5636   5651   **
  5637   5652   ** IMPORTANT: The estimatedRows field was added to the sqlite3_index_info
  5638   5653   ** structure for SQLite version 3.8.2. If a virtual table extension is
  5639   5654   ** used with an SQLite version earlier than 3.8.2, the results of attempting 
  5640   5655   ** to read or write the estimatedRows field are undefined (but are likely 
  5641   5656   ** to included crashing the application). The estimatedRows field should
  5642   5657   ** therefore only be used if [sqlite3_libversion_number()] returns a
  5643         -** value greater than or equal to 3008002.
         5658  +** value greater than or equal to 3008002. Similarly, the idxFlags field
         5659  +** was added for version 3.9.0. It may therefore only be used if
         5660  +** sqlite3_libversion_number() returns a value greater than or equal to
         5661  +** 3009000.
  5644   5662   */
  5645   5663   struct sqlite3_index_info {
  5646   5664     /* Inputs */
  5647   5665     int nConstraint;           /* Number of entries in aConstraint */
  5648   5666     struct sqlite3_index_constraint {
  5649   5667        int iColumn;              /* Column on left-hand side of constraint */
  5650   5668        unsigned char op;         /* Constraint operator */
................................................................................
  5664   5682     int idxNum;                /* Number used to identify the index */
  5665   5683     char *idxStr;              /* String, possibly obtained from sqlite3_malloc */
  5666   5684     int needToFreeIdxStr;      /* Free idxStr using sqlite3_free() if true */
  5667   5685     int orderByConsumed;       /* True if output is already ordered */
  5668   5686     double estimatedCost;           /* Estimated cost of using this index */
  5669   5687     /* Fields below are only available in SQLite 3.8.2 and later */
  5670   5688     sqlite3_int64 estimatedRows;    /* Estimated number of rows returned */
         5689  +  /* Fields below are only available in SQLite 3.9.0 and later */
         5690  +  int idxFlags;              /* Mask of SQLITE_INDEX_SCAN_* flags */
  5671   5691   };
  5672   5692   
         5693  +/*
         5694  +** CAPI3REF: Virtual Table Scan Flags
         5695  +*/
         5696  +#define SQLITE_INDEX_SCAN_UNIQUE      1     /* Scan visits at most 1 row */
         5697  +
  5673   5698   /*
  5674   5699   ** CAPI3REF: Virtual Table Constraint Operator Codes
  5675   5700   **
  5676   5701   ** These macros defined the allowed values for the
  5677   5702   ** [sqlite3_index_info].aConstraint[].op field.  Each value represents
  5678   5703   ** an operator that is part of a constraint term in the wHERE clause of
  5679   5704   ** a query that uses a [virtual table].

Changes to src/sqlite3ext.h.

   268    268                            void(*)(void*), unsigned char);
   269    269     int (*strglob)(const char*,const char*);
   270    270     /* Version 3.8.11 and later */
   271    271     sqlite3_value *(*value_dup)(const sqlite3_value*);
   272    272     void (*value_free)(sqlite3_value*);
   273    273     int (*result_zeroblob64)(sqlite3_context*,sqlite3_uint64);
   274    274     int (*bind_zeroblob64)(sqlite3_stmt*, int, sqlite3_uint64);
   275         -  /* Version 3.8.12 and later */
          275  +  /* Version 3.9.0 and later */
   276    276     unsigned int (*value_subtype)(sqlite3_value*);
   277    277     void (*result_subtype)(sqlite3_context*,unsigned int);
   278    278   };
   279    279   
   280    280   /*
   281    281   ** The following macros redefine the API routines so that they are
   282    282   ** redirected through the global sqlite3_api structure.
................................................................................
   507    507   #define sqlite3_result_text64          sqlite3_api->result_text64
   508    508   #define sqlite3_strglob                sqlite3_api->strglob
   509    509   /* Version 3.8.11 and later */
   510    510   #define sqlite3_value_dup              sqlite3_api->value_dup
   511    511   #define sqlite3_value_free             sqlite3_api->value_free
   512    512   #define sqlite3_result_zeroblob64      sqlite3_api->result_zeroblob64
   513    513   #define sqlite3_bind_zeroblob64        sqlite3_api->bind_zeroblob64
   514         -/* Version 3.8.12 and later */
          514  +/* Version 3.9.0 and later */
   515    515   #define sqlite3_value_subtype          sqlite3_api->value_subtype
   516    516   #define sqlite3_result_subtype         sqlite3_api->result_subtype
   517    517   #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
   518    518   
   519    519   #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
   520    520     /* This case when the file really is being compiled as a loadable 
   521    521     ** extension */

Changes to src/sqliteInt.h.

   192    192   */
   193    193   #if !defined(SQLITE_DISABLE_INTRINSIC)
   194    194   #  if defined(_MSC_VER) && _MSC_VER>=1300
   195    195   #    if !defined(_WIN32_WCE)
   196    196   #      include <intrin.h>
   197    197   #      pragma intrinsic(_byteswap_ushort)
   198    198   #      pragma intrinsic(_byteswap_ulong)
          199  +#      pragma intrinsic(_ReadWriteBarrier)
   199    200   #    else
   200    201   #      include <cmnintrin.h>
   201    202   #    endif
   202    203   #  endif
   203    204   #endif
   204    205   
   205    206   /*
................................................................................
  1914   1915   
  1915   1916   /* Return true if index X is a PRIMARY KEY index */
  1916   1917   #define IsPrimaryKeyIndex(X)  ((X)->idxType==SQLITE_IDXTYPE_PRIMARYKEY)
  1917   1918   
  1918   1919   /* Return true if index X is a UNIQUE index */
  1919   1920   #define IsUniqueIndex(X)      ((X)->onError!=OE_None)
  1920   1921   
         1922  +/* The Index.aiColumn[] values are normally positive integer.  But
         1923  +** there are some negative values that have special meaning:
         1924  +*/
         1925  +#define XN_ROWID     (-1)     /* Indexed column is the rowid */
         1926  +#define XN_EXPR      (-2)     /* Indexed column is an expression */
         1927  +
  1921   1928   /*
  1922   1929   ** Each sample stored in the sqlite_stat3 table is represented in memory 
  1923   1930   ** using a structure of this type.  See documentation at the top of the
  1924   1931   ** analyze.c source file for additional information.
  1925   1932   */
  1926   1933   struct IndexSample {
  1927   1934     void *p;          /* Pointer to sampled record */
................................................................................
  3501   3508                                           Select*,u8);
  3502   3509     TriggerStep *sqlite3TriggerUpdateStep(sqlite3*,Token*,ExprList*, Expr*, u8);
  3503   3510     TriggerStep *sqlite3TriggerDeleteStep(sqlite3*,Token*, Expr*);
  3504   3511     void sqlite3DeleteTrigger(sqlite3*, Trigger*);
  3505   3512     void sqlite3UnlinkAndDeleteTrigger(sqlite3*,int,const char*);
  3506   3513     u32 sqlite3TriggerColmask(Parse*,Trigger*,ExprList*,int,int,Table*,int);
  3507   3514   # define sqlite3ParseToplevel(p) ((p)->pToplevel ? (p)->pToplevel : (p))
         3515  +# define sqlite3IsToplevel(p) ((p)->pToplevel==0)
  3508   3516   #else
  3509   3517   # define sqlite3TriggersExist(B,C,D,E,F) 0
  3510   3518   # define sqlite3DeleteTrigger(A,B)
  3511   3519   # define sqlite3DropTriggerPtr(A,B)
  3512   3520   # define sqlite3UnlinkAndDeleteTrigger(A,B,C)
  3513   3521   # define sqlite3CodeRowTrigger(A,B,C,D,E,F,G,H,I)
  3514   3522   # define sqlite3CodeRowTriggerDirect(A,B,C,D,E,F)
  3515   3523   # define sqlite3TriggerList(X, Y) 0
  3516   3524   # define sqlite3ParseToplevel(p) p
         3525  +# define sqlite3IsToplevel(p) 1
  3517   3526   # define sqlite3TriggerColmask(A,B,C,D,E,F,G) 0
  3518   3527   #endif
  3519   3528   
  3520   3529   int sqlite3JoinType(Parse*, Token*, Token*, Token*);
  3521   3530   void sqlite3CreateForeignKey(Parse*, ExprList*, Token*, ExprList*, int);
  3522   3531   void sqlite3DeferForeignKey(Parse*, int);
  3523   3532   #ifndef SQLITE_OMIT_AUTHORIZATION

Changes to src/test1.c.

  6373   6373   ){
  6374   6374     extern int sqlite3_amatch_init(sqlite3*,char**,const sqlite3_api_routines*);
  6375   6375     extern int sqlite3_closure_init(sqlite3*,char**,const sqlite3_api_routines*);
  6376   6376     extern int sqlite3_eval_init(sqlite3*,char**,const sqlite3_api_routines*);
  6377   6377     extern int sqlite3_fileio_init(sqlite3*,char**,const sqlite3_api_routines*);
  6378   6378     extern int sqlite3_fuzzer_init(sqlite3*,char**,const sqlite3_api_routines*);
  6379   6379     extern int sqlite3_ieee_init(sqlite3*,char**,const sqlite3_api_routines*);
  6380         -  extern int sqlite3_json_init(sqlite3*,char**,const sqlite3_api_routines*);
  6381   6380     extern int sqlite3_nextchar_init(sqlite3*,char**,const sqlite3_api_routines*);
  6382   6381     extern int sqlite3_percentile_init(sqlite3*,char**,const sqlite3_api_routines*);
  6383   6382     extern int sqlite3_regexp_init(sqlite3*,char**,const sqlite3_api_routines*);
  6384   6383     extern int sqlite3_series_init(sqlite3*,char**,const sqlite3_api_routines*);
  6385   6384     extern int sqlite3_spellfix_init(sqlite3*,char**,const sqlite3_api_routines*);
  6386   6385     extern int sqlite3_totype_init(sqlite3*,char**,const sqlite3_api_routines*);
  6387   6386     extern int sqlite3_wholenumber_init(sqlite3*,char**,const sqlite3_api_routines*);
  6388         -  extern int sqlite3_fts5_init(sqlite3*,char**,const sqlite3_api_routines*);
  6389   6387     static const struct {
  6390   6388       const char *zExtName;
  6391   6389       int (*pInit)(sqlite3*,char**,const sqlite3_api_routines*);
  6392   6390     } aExtension[] = {
  6393   6391       { "amatch",                sqlite3_amatch_init               },
  6394   6392       { "closure",               sqlite3_closure_init              },
  6395   6393       { "eval",                  sqlite3_eval_init                 },
  6396         -#ifdef SQLITE_ENABLE_FTS5
  6397         -    { "fts5",                  sqlite3_fts5_init                 },
  6398         -#endif
  6399   6394       { "fileio",                sqlite3_fileio_init               },
  6400   6395       { "fuzzer",                sqlite3_fuzzer_init               },
  6401   6396       { "ieee754",               sqlite3_ieee_init                 },
  6402         -    { "json",                  sqlite3_json_init                 },
  6403   6397       { "nextchar",              sqlite3_nextchar_init             },
  6404   6398       { "percentile",            sqlite3_percentile_init           },
  6405   6399       { "regexp",                sqlite3_regexp_init               },
  6406   6400       { "series",                sqlite3_series_init               },
  6407   6401       { "spellfix",              sqlite3_spellfix_init             },
  6408   6402       { "totype",                sqlite3_totype_init               },
  6409   6403       { "wholenumber",           sqlite3_wholenumber_init          },
................................................................................
  6422   6416       for(i=0; i<ArraySize(aExtension); i++){
  6423   6417         if( strcmp(zName, aExtension[i].zExtName)==0 ) break;
  6424   6418       }
  6425   6419       if( i>=ArraySize(aExtension) ){
  6426   6420         Tcl_AppendResult(interp, "no such extension: ", zName, (char*)0);
  6427   6421         return TCL_ERROR;
  6428   6422       }
  6429         -    rc = aExtension[i].pInit(db, &zErrMsg, 0);
         6423  +    if( aExtension[i].pInit ){
         6424  +      rc = aExtension[i].pInit(db, &zErrMsg, 0);
         6425  +    }else{
         6426  +      rc = SQLITE_OK;
         6427  +    }
  6430   6428       if( rc!=SQLITE_OK || zErrMsg ){
  6431   6429         Tcl_AppendResult(interp, "initialization of ", zName, " failed: ", zErrMsg,
  6432   6430                          (char*)0);
  6433   6431         sqlite3_free(zErrMsg);
  6434   6432         return TCL_ERROR;
  6435   6433       }
  6436   6434     }

Changes to src/test_config.c.

   162    162   #endif
   163    163   
   164    164   #ifdef SQLITE_ENABLE_ATOMIC_WRITE
   165    165     Tcl_SetVar2(interp, "sqlite_options", "atomicwrite", "1", TCL_GLOBAL_ONLY);
   166    166   #else
   167    167     Tcl_SetVar2(interp, "sqlite_options", "atomicwrite", "0", TCL_GLOBAL_ONLY);
   168    168   #endif
          169  +
          170  +#ifdef SQLITE_ENABLE_JSON1
          171  +  Tcl_SetVar2(interp, "sqlite_options", "json1", "1", TCL_GLOBAL_ONLY);
          172  +#else
          173  +  Tcl_SetVar2(interp, "sqlite_options", "json1", "0", TCL_GLOBAL_ONLY);
          174  +#endif
   169    175   
   170    176   #ifdef SQLITE_OMIT_ATTACH
   171    177     Tcl_SetVar2(interp, "sqlite_options", "attach", "0", TCL_GLOBAL_ONLY);
   172    178   #else
   173    179     Tcl_SetVar2(interp, "sqlite_options", "attach", "1", TCL_GLOBAL_ONLY);
   174    180   #endif
   175    181   

Changes to src/threads.c.

    63     63   
    64     64     *ppThread = 0;
    65     65     p = sqlite3Malloc(sizeof(*p));
    66     66     if( p==0 ) return SQLITE_NOMEM;
    67     67     memset(p, 0, sizeof(*p));
    68     68     p->xTask = xTask;
    69     69     p->pIn = pIn;
           70  +  /* If the SQLITE_TESTCTRL_FAULT_INSTALL callback is registered to a 
           71  +  ** function that returns SQLITE_ERROR when passed the argument 200, that
           72  +  ** forces worker threads to run sequentially and deterministically 
           73  +  ** for testing purposes. */
    70     74     if( sqlite3FaultSim(200) ){
    71     75       rc = 1;
    72     76     }else{    
    73     77       rc = pthread_create(&p->tid, 0, xTask, pIn);
    74     78     }
    75     79     if( rc ){
    76     80       p->done = 1;
................................................................................
   147    151     SQLiteThread *p;
   148    152   
   149    153     assert( ppThread!=0 );
   150    154     assert( xTask!=0 );
   151    155     *ppThread = 0;
   152    156     p = sqlite3Malloc(sizeof(*p));
   153    157     if( p==0 ) return SQLITE_NOMEM;
   154         -  if( sqlite3GlobalConfig.bCoreMutex==0 ){
          158  +  /* If the SQLITE_TESTCTRL_FAULT_INSTALL callback is registered to a 
          159  +  ** function that returns SQLITE_ERROR when passed the argument 200, that
          160  +  ** forces worker threads to run sequentially and deterministically 
          161  +  ** (via the sqlite3FaultSim() term of the conditional) for testing
          162  +  ** purposes. */
          163  +  if( sqlite3GlobalConfig.bCoreMutex==0 || sqlite3FaultSim(200) ){
   155    164       memset(p, 0, sizeof(*p));
   156    165     }else{
   157    166       p->xTask = xTask;
   158    167       p->pIn = pIn;
   159    168       p->tid = (void*)_beginthreadex(0, 0, sqlite3ThreadProc, p, 0, &p->id);
   160    169       if( p->tid==0 ){
   161    170         memset(p, 0, sizeof(*p));
................................................................................
   175    184   int sqlite3ThreadJoin(SQLiteThread *p, void **ppOut){
   176    185     DWORD rc;
   177    186     BOOL bRc;
   178    187   
   179    188     assert( ppOut!=0 );
   180    189     if( NEVER(p==0) ) return SQLITE_NOMEM;
   181    190     if( p->xTask==0 ){
   182         -    assert( p->id==GetCurrentThreadId() );
          191  +    /* assert( p->id==GetCurrentThreadId() ); */
   183    192       rc = WAIT_OBJECT_0;
   184    193       assert( p->tid==0 );
   185    194     }else{
   186    195       assert( p->id!=0 && p->id!=GetCurrentThreadId() );
   187    196       rc = sqlite3Win32Wait((HANDLE)p->tid);
   188    197       assert( rc!=WAIT_IO_COMPLETION );
   189    198       bRc = CloseHandle((HANDLE)p->tid);

Changes to src/update.c.

   130    130     int newmask;           /* Mask of NEW.* columns accessed by BEFORE triggers */
   131    131     int iEph = 0;          /* Ephemeral table holding all primary key values */
   132    132     int nKey = 0;          /* Number of elements in regKey for WITHOUT ROWID */
   133    133     int aiCurOnePass[2];   /* The write cursors opened by WHERE_ONEPASS */
   134    134   
   135    135     /* Register Allocations */
   136    136     int regRowCount = 0;   /* A count of rows changed */
   137         -  int regOldRowid;       /* The old rowid */
   138         -  int regNewRowid;       /* The new rowid */
   139         -  int regNew;            /* Content of the NEW.* table in triggers */
          137  +  int regOldRowid = 0;   /* The old rowid */
          138  +  int regNewRowid = 0;   /* The new rowid */
          139  +  int regNew = 0;        /* Content of the NEW.* table in triggers */
   140    140     int regOld = 0;        /* Content of OLD.* table in triggers */
   141    141     int regRowSet = 0;     /* Rowset of rows to be updated */
   142    142     int regKey = 0;        /* composite PRIMARY KEY value */
   143    143   
   144    144     memset(&sContext, 0, sizeof(sContext));
   145    145     db = pParse->db;
   146    146     if( pParse->nErr || db->mallocFailed ){
................................................................................
   296    296   
   297    297     /* Begin generating code. */
   298    298     v = sqlite3GetVdbe(pParse);
   299    299     if( v==0 ) goto update_cleanup;
   300    300     if( pParse->nested==0 ) sqlite3VdbeCountChanges(v);
   301    301     sqlite3BeginWriteOperation(pParse, 1, iDb);
   302    302   
   303         -#ifndef SQLITE_OMIT_VIRTUALTABLE
   304         -  /* Virtual tables must be handled separately */
   305         -  if( IsVirtual(pTab) ){
   306         -    updateVirtualTable(pParse, pTabList, pTab, pChanges, pRowidExpr, aXRef,
   307         -                       pWhere, onError);
   308         -    pWhere = 0;
   309         -    pTabList = 0;
   310         -    goto update_cleanup;
   311         -  }
   312         -#endif
   313         -
   314    303     /* Allocate required registers. */
   315         -  regRowSet = ++pParse->nMem;
   316         -  regOldRowid = regNewRowid = ++pParse->nMem;
   317         -  if( chngPk || pTrigger || hasFK ){
   318         -    regOld = pParse->nMem + 1;
          304  +  if( !IsVirtual(pTab) ){
          305  +    regRowSet = ++pParse->nMem;
          306  +    regOldRowid = regNewRowid = ++pParse->nMem;
          307  +    if( chngPk || pTrigger || hasFK ){
          308  +      regOld = pParse->nMem + 1;
          309  +      pParse->nMem += pTab->nCol;
          310  +    }
          311  +    if( chngKey || pTrigger || hasFK ){
          312  +      regNewRowid = ++pParse->nMem;
          313  +    }
          314  +    regNew = pParse->nMem + 1;
   319    315       pParse->nMem += pTab->nCol;
   320    316     }
   321         -  if( chngKey || pTrigger || hasFK ){
   322         -    regNewRowid = ++pParse->nMem;
   323         -  }
   324         -  regNew = pParse->nMem + 1;
   325         -  pParse->nMem += pTab->nCol;
   326    317   
   327    318     /* Start the view context. */
   328    319     if( isView ){
   329    320       sqlite3AuthContextPush(pParse, &sContext, pTab->zName);
   330    321     }
   331    322   
   332    323     /* If we are trying to update a view, realize that view into
................................................................................
   340    331   
   341    332     /* Resolve the column names in all the expressions in the
   342    333     ** WHERE clause.
   343    334     */
   344    335     if( sqlite3ResolveExprNames(&sNC, pWhere) ){
   345    336       goto update_cleanup;
   346    337     }
          338  +
          339  +#ifndef SQLITE_OMIT_VIRTUALTABLE
          340  +  /* Virtual tables must be handled separately */
          341  +  if( IsVirtual(pTab) ){
          342  +    updateVirtualTable(pParse, pTabList, pTab, pChanges, pRowidExpr, aXRef,
          343  +                       pWhere, onError);
          344  +    goto update_cleanup;
          345  +  }
          346  +#endif
   347    347   
   348    348     /* Begin the database scan
   349    349     */
   350    350     if( HasRowid(pTab) ){
   351    351       sqlite3VdbeAddOp3(v, OP_Null, 0, regRowSet, regOldRowid);
   352    352       pWInfo = sqlite3WhereBegin(
   353    353           pParse, pTabList, pWhere, 0, 0, WHERE_ONEPASS_DESIRED, iIdxCur
................................................................................
   380    380       addrOpen = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, iEph, nPk);
   381    381       sqlite3VdbeSetP4KeyInfo(pParse, pPk);
   382    382       pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, 0, 0, 
   383    383                                  WHERE_ONEPASS_DESIRED, iIdxCur);
   384    384       if( pWInfo==0 ) goto update_cleanup;
   385    385       okOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass);
   386    386       for(i=0; i<nPk; i++){
   387         -      assert( pPk->aiColumn[i]>=(-1) );
          387  +      assert( pPk->aiColumn[i]>=0 );
   388    388         sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, pPk->aiColumn[i],
   389    389                                         iPk+i);
   390    390       }
   391    391       if( okOnePass ){
   392    392         sqlite3VdbeChangeToNoop(v, addrOpen);
   393    393         nKey = nPk;
   394    394         regKey = iPk;
................................................................................
   503    503     ** the database after the BEFORE triggers are fired anyway (as the trigger 
   504    504     ** may have modified them). So not loading those that are not going to
   505    505     ** be used eliminates some redundant opcodes.
   506    506     */
   507    507     newmask = sqlite3TriggerColmask(
   508    508         pParse, pTrigger, pChanges, 1, TRIGGER_BEFORE, pTab, onError
   509    509     );
   510         -  /*sqlite3VdbeAddOp3(v, OP_Null, 0, regNew, regNew+pTab->nCol-1);*/
   511    510     for(i=0; i<pTab->nCol; i++){
   512    511       if( i==pTab->iPKey ){
   513    512         sqlite3VdbeAddOp2(v, OP_Null, 0, regNew+i);
   514    513       }else{
   515    514         j = aXRef[i];
   516    515         if( j>=0 ){
   517    516           sqlite3ExprCode(pParse, pChanges->a[j].pExpr, regNew+i);
................................................................................
   561    560         if( aXRef[i]<0 && i!=pTab->iPKey ){
   562    561           sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, i, regNew+i);
   563    562         }
   564    563       }
   565    564     }
   566    565   
   567    566     if( !isView ){
   568         -    int j1 = 0;           /* Address of jump instruction */
          567  +    int addr1 = 0;        /* Address of jump instruction */
   569    568       int bReplace = 0;     /* True if REPLACE conflict resolution might happen */
   570    569   
   571    570       /* Do constraint checks. */
   572    571       assert( regOldRowid>0 );
   573    572       sqlite3GenerateConstraintChecks(pParse, pTab, aRegIdx, iDataCur, iIdxCur,
   574    573           regNewRowid, regOldRowid, chngKey, onError, labelContinue, &bReplace);
   575    574   
................................................................................
   577    576       if( hasFK ){
   578    577         sqlite3FkCheck(pParse, pTab, regOldRowid, 0, aXRef, chngKey);
   579    578       }
   580    579   
   581    580       /* Delete the index entries associated with the current record.  */
   582    581       if( bReplace || chngKey ){
   583    582         if( pPk ){
   584         -        j1 = sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, 0, regKey, nKey);
          583  +        addr1 = sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, 0, regKey, nKey);
   585    584         }else{
   586         -        j1 = sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, 0, regOldRowid);
          585  +        addr1 = sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, 0, regOldRowid);
   587    586         }
   588    587         VdbeCoverageNeverTaken(v);
   589    588       }
   590    589       sqlite3GenerateRowIndexDelete(pParse, pTab, iDataCur, iIdxCur, aRegIdx, -1);
   591    590     
   592    591       /* If changing the record number, delete the old record.  */
   593    592       if( hasFK || chngKey || pPk!=0 ){
   594    593         sqlite3VdbeAddOp2(v, OP_Delete, iDataCur, 0);
   595    594       }
   596    595       if( bReplace || chngKey ){
   597         -      sqlite3VdbeJumpHere(v, j1);
          596  +      sqlite3VdbeJumpHere(v, addr1);
   598    597       }
   599    598   
   600    599       if( hasFK ){
   601    600         sqlite3FkCheck(pParse, pTab, 0, regNewRowid, aXRef, chngKey);
   602    601       }
   603    602     
   604    603       /* Insert the new index entries and the new record. */
................................................................................
   681    680    #undef pTrigger
   682    681   #endif
   683    682   
   684    683   #ifndef SQLITE_OMIT_VIRTUALTABLE
   685    684   /*
   686    685   ** Generate code for an UPDATE of a virtual table.
   687    686   **
   688         -** The strategy is that we create an ephemeral table that contains
          687  +** There are two possible strategies - the default and the special 
          688  +** "onepass" strategy. Onepass is only used if the virtual table 
          689  +** implementation indicates that pWhere may match at most one row.
          690  +**
          691  +** The default strategy is to create an ephemeral table that contains
   689    692   ** for each row to be changed:
   690    693   **
   691    694   **   (A)  The original rowid of that row.
   692         -**   (B)  The revised rowid for the row. (note1)
          695  +**   (B)  The revised rowid for the row.
   693    696   **   (C)  The content of every column in the row.
   694    697   **
   695         -** Then we loop over this ephemeral table and for each row in
   696         -** the ephemeral table call VUpdate.
          698  +** Then loop through the contents of this ephemeral table executing a
          699  +** VUpdate for each row. When finished, drop the ephemeral table.
   697    700   **
   698         -** When finished, drop the ephemeral table.
   699         -**
   700         -** (note1) Actually, if we know in advance that (A) is always the same
   701         -** as (B) we only store (A), then duplicate (A) when pulling
   702         -** it out of the ephemeral table before calling VUpdate.
          701  +** The "onepass" strategy does not use an ephemeral table. Instead, it
          702  +** stores the same values (A, B and C above) in a register array and
          703  +** makes a single invocation of VUpdate.
   703    704   */
   704    705   static void updateVirtualTable(
   705    706     Parse *pParse,       /* The parsing context */
   706    707     SrcList *pSrc,       /* The virtual table to be modified */
   707    708     Table *pTab,         /* The virtual table */
   708    709     ExprList *pChanges,  /* The columns to change in the UPDATE statement */
   709    710     Expr *pRowid,        /* Expression used to recompute the rowid */
   710    711     int *aXRef,          /* Mapping from columns of pTab to entries in pChanges */
   711    712     Expr *pWhere,        /* WHERE clause of the UPDATE statement */
   712    713     int onError          /* ON CONFLICT strategy */
   713    714   ){
   714    715     Vdbe *v = pParse->pVdbe;  /* Virtual machine under construction */
   715         -  ExprList *pEList = 0;     /* The result set of the SELECT statement */
   716         -  Select *pSelect = 0;      /* The SELECT statement */
   717         -  Expr *pExpr;              /* Temporary expression */
   718    716     int ephemTab;             /* Table holding the result of the SELECT */
   719    717     int i;                    /* Loop counter */
   720         -  int addr;                 /* Address of top of loop */
   721         -  int iReg;                 /* First register in set passed to OP_VUpdate */
   722    718     sqlite3 *db = pParse->db; /* Database connection */
   723    719     const char *pVTab = (const char*)sqlite3GetVTable(db, pTab);
   724         -  SelectDest dest;
          720  +  WhereInfo *pWInfo;
          721  +  int nArg = 2 + pTab->nCol;      /* Number of arguments to VUpdate */
          722  +  int regArg;                     /* First register in VUpdate arg array */
          723  +  int regRec;                     /* Register in which to assemble record */
          724  +  int regRowid;                   /* Register for ephem table rowid */
          725  +  int iCsr = pSrc->a[0].iCursor;  /* Cursor used for virtual table scan */
          726  +  int aDummy[2];                  /* Unused arg for sqlite3WhereOkOnePass() */
          727  +  int bOnePass;                   /* True to use onepass strategy */
          728  +  int addr;                       /* Address of OP_OpenEphemeral */
   725    729   
   726         -  /* Construct the SELECT statement that will find the new values for
   727         -  ** all updated rows. 
   728         -  */
   729         -  pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(db, TK_ID, "_rowid_"));
   730         -  if( pRowid ){
   731         -    pEList = sqlite3ExprListAppend(pParse, pEList,
   732         -                                   sqlite3ExprDup(db, pRowid, 0));
   733         -  }
   734         -  assert( pTab->iPKey<0 );
   735         -  for(i=0; i<pTab->nCol; i++){
   736         -    if( aXRef[i]>=0 ){
   737         -      pExpr = sqlite3ExprDup(db, pChanges->a[aXRef[i]].pExpr, 0);
   738         -    }else{
   739         -      pExpr = sqlite3Expr(db, TK_ID, pTab->aCol[i].zName);
   740         -    }
   741         -    pEList = sqlite3ExprListAppend(pParse, pEList, pExpr);
   742         -  }
   743         -  pSelect = sqlite3SelectNew(pParse, pEList, pSrc, pWhere, 0, 0, 0, 0, 0, 0);
   744         -  
   745         -  /* Create the ephemeral table into which the update results will
   746         -  ** be stored.
   747         -  */
          730  +  /* Allocate nArg registers to martial the arguments to VUpdate. Then
          731  +  ** create and open the ephemeral table in which the records created from
          732  +  ** these arguments will be temporarily stored. */
   748    733     assert( v );
   749    734     ephemTab = pParse->nTab++;
          735  +  addr= sqlite3VdbeAddOp2(v, OP_OpenEphemeral, ephemTab, nArg);
          736  +  regArg = pParse->nMem + 1;
          737  +  pParse->nMem += nArg;
          738  +  regRec = ++pParse->nMem;
          739  +  regRowid = ++pParse->nMem;
   750    740   
   751         -  /* fill the ephemeral table 
   752         -  */
   753         -  sqlite3SelectDestInit(&dest, SRT_EphemTab, ephemTab);
   754         -  sqlite3Select(pParse, pSelect, &dest);
          741  +  /* Start scanning the virtual table */
          742  +  pWInfo = sqlite3WhereBegin(pParse, pSrc, pWhere, 0,0,WHERE_ONEPASS_DESIRED,0);
          743  +  if( pWInfo==0 ) return;
   755    744   
   756         -  /* Generate code to scan the ephemeral table and call VUpdate. */
   757         -  iReg = ++pParse->nMem;
   758         -  pParse->nMem += pTab->nCol+1;
   759         -  addr = sqlite3VdbeAddOp2(v, OP_Rewind, ephemTab, 0); VdbeCoverage(v);
   760         -  sqlite3VdbeAddOp3(v, OP_Column,  ephemTab, 0, iReg);
   761         -  sqlite3VdbeAddOp3(v, OP_Column, ephemTab, (pRowid?1:0), iReg+1);
          745  +  /* Populate the argument registers. */
          746  +  sqlite3VdbeAddOp2(v, OP_Rowid, iCsr, regArg);
          747  +  if( pRowid ){
          748  +    sqlite3ExprCode(pParse, pRowid, regArg+1);
          749  +  }else{
          750  +    sqlite3VdbeAddOp2(v, OP_Rowid, iCsr, regArg+1);
          751  +  }
   762    752     for(i=0; i<pTab->nCol; i++){
   763         -    sqlite3VdbeAddOp3(v, OP_Column, ephemTab, i+1+(pRowid!=0), iReg+2+i);
          753  +    if( aXRef[i]>=0 ){
          754  +      sqlite3ExprCode(pParse, pChanges->a[aXRef[i]].pExpr, regArg+2+i);
          755  +    }else{
          756  +      sqlite3VdbeAddOp3(v, OP_VColumn, iCsr, i, regArg+2+i);
          757  +    }
          758  +  }
          759  +
          760  +  bOnePass = sqlite3WhereOkOnePass(pWInfo, aDummy);
          761  +
          762  +  if( bOnePass ){
          763  +    /* If using the onepass strategy, no-op out the OP_OpenEphemeral coded
          764  +    ** above. Also, if this is a top-level parse (not a trigger), clear the
          765  +    ** multi-write flag so that the VM does not open a statement journal */
          766  +    sqlite3VdbeChangeToNoop(v, addr);
          767  +    if( sqlite3IsToplevel(pParse) ){
          768  +      pParse->isMultiWrite = 0;
          769  +    }
          770  +  }else{
          771  +    /* Create a record from the argument register contents and insert it into
          772  +    ** the ephemeral table. */
          773  +    sqlite3VdbeAddOp3(v, OP_MakeRecord, regArg, nArg, regRec);
          774  +    sqlite3VdbeAddOp2(v, OP_NewRowid, ephemTab, regRowid);
          775  +    sqlite3VdbeAddOp3(v, OP_Insert, ephemTab, regRec, regRowid);
          776  +  }
          777  +
          778  +
          779  +  if( bOnePass==0 ){
          780  +    /* End the virtual table scan */
          781  +    sqlite3WhereEnd(pWInfo);
          782  +
          783  +    /* Begin scannning through the ephemeral table. */
          784  +    addr = sqlite3VdbeAddOp1(v, OP_Rewind, ephemTab); VdbeCoverage(v);
          785  +
          786  +    /* Extract arguments from the current row of the ephemeral table and 
          787  +    ** invoke the VUpdate method.  */
          788  +    for(i=0; i<nArg; i++){
          789  +      sqlite3VdbeAddOp3(v, OP_Column, ephemTab, i, regArg+i);
          790  +    }
   764    791     }
   765    792     sqlite3VtabMakeWritable(pParse, pTab);
   766         -  sqlite3VdbeAddOp4(v, OP_VUpdate, 0, pTab->nCol+2, iReg, pVTab, P4_VTAB);
          793  +  sqlite3VdbeAddOp4(v, OP_VUpdate, 0, nArg, regArg, pVTab, P4_VTAB);
   767    794     sqlite3VdbeChangeP5(v, onError==OE_Default ? OE_Abort : onError);
   768    795     sqlite3MayAbort(pParse);
   769         -  sqlite3VdbeAddOp2(v, OP_Next, ephemTab, addr+1); VdbeCoverage(v);
   770         -  sqlite3VdbeJumpHere(v, addr);
   771         -  sqlite3VdbeAddOp2(v, OP_Close, ephemTab, 0);
   772    796   
   773         -  /* Cleanup */
   774         -  sqlite3SelectDelete(db, pSelect);  
          797  +  /* End of the ephemeral table scan. Or, if using the onepass strategy,
          798  +  ** jump to here if the scan visited zero rows. */
          799  +  if( bOnePass==0 ){
          800  +    sqlite3VdbeAddOp2(v, OP_Next, ephemTab, addr+1); VdbeCoverage(v);
          801  +    sqlite3VdbeJumpHere(v, addr);
          802  +    sqlite3VdbeAddOp2(v, OP_Close, ephemTab, 0);
          803  +  }else{
          804  +    sqlite3WhereEnd(pWInfo);
          805  +  }
   775    806   }
   776    807   #endif /* SQLITE_OMIT_VIRTUALTABLE */

Changes to src/vdbe.c.

  5699   5699     if( pIn1->u.i<pIn2->u.i){
  5700   5700       pIn1->u.i = pIn2->u.i;
  5701   5701     }
  5702   5702     break;
  5703   5703   }
  5704   5704   #endif /* SQLITE_OMIT_AUTOINCREMENT */
  5705   5705   
  5706         -/* Opcode: IfPos P1 P2 * * *
  5707         -** Synopsis: if r[P1]>0 goto P2
         5706  +/* Opcode: IfPos P1 P2 P3 * *
         5707  +** Synopsis: if r[P1]>0 then r[P1]-=P3, goto P2
  5708   5708   **
  5709   5709   ** Register P1 must contain an integer.
  5710         -** If the value of register P1 is 1 or greater, jump to P2 and
  5711         -** add the literal value P3 to register P1.
         5710  +** If the value of register P1 is 1 or greater, subtract P3 from the
         5711  +** value in P1 and jump to P2.
  5712   5712   **
  5713   5713   ** If the initial value of register P1 is less than 1, then the
  5714   5714   ** value is unchanged and control passes through to the next instruction.
  5715   5715   */
  5716   5716   case OP_IfPos: {        /* jump, in1 */
  5717   5717     pIn1 = &aMem[pOp->p1];
  5718   5718     assert( pIn1->flags&MEM_Int );
  5719   5719     VdbeBranchTaken( pIn1->u.i>0, 2);
  5720         -  if( pIn1->u.i>0 ) goto jump_to_p2;
         5720  +  if( pIn1->u.i>0 ){
         5721  +    pIn1->u.i -= pOp->p3;
         5722  +    goto jump_to_p2;
         5723  +  }
  5721   5724     break;
  5722   5725   }
  5723   5726   
  5724         -/* Opcode: IfNeg P1 P2 P3 * *
  5725         -** Synopsis: r[P1]+=P3, if r[P1]<0 goto P2
         5727  +/* Opcode: SetIfNotPos P1 P2 P3 * *
         5728  +** Synopsis: if r[P1]<=0 then r[P2]=P3
  5726   5729   **
  5727         -** Register P1 must contain an integer.  Add literal P3 to the value in
  5728         -** register P1 then if the value of register P1 is less than zero, jump to P2. 
         5730  +** Register P1 must contain an integer.
         5731  +** If the value of register P1 is not positive (if it is less than 1) then
         5732  +** set the value of register P2 to be the integer P3.
  5729   5733   */
  5730         -case OP_IfNeg: {        /* jump, in1 */
         5734  +case OP_SetIfNotPos: {        /* in1, in2 */
  5731   5735     pIn1 = &aMem[pOp->p1];
  5732   5736     assert( pIn1->flags&MEM_Int );
  5733         -  pIn1->u.i += pOp->p3;
  5734         -  VdbeBranchTaken(pIn1->u.i<0, 2);
  5735         -  if( pIn1->u.i<0 ) goto jump_to_p2;
         5737  +  if( pIn1->u.i<=0 ){
         5738  +    pOut = out2Prerelease(p, pOp);
         5739  +    pOut->u.i = pOp->p3;
         5740  +  }
  5736   5741     break;
  5737   5742   }
  5738   5743   
  5739   5744   /* Opcode: IfNotZero P1 P2 P3 * *
  5740         -** Synopsis: if r[P1]!=0 then r[P1]+=P3, goto P2
         5745  +** Synopsis: if r[P1]!=0 then r[P1]-=P3, goto P2
  5741   5746   **
  5742   5747   ** Register P1 must contain an integer.  If the content of register P1 is
  5743         -** initially nonzero, then add P3 to P1 and jump to P2.  If register P1 is
  5744         -** initially zero, leave it unchanged and fall through.
         5748  +** initially nonzero, then subtract P3 from the value in register P1 and
         5749  +** jump to P2.  If register P1 is initially zero, leave it unchanged
         5750  +** and fall through.
  5745   5751   */
  5746   5752   case OP_IfNotZero: {        /* jump, in1 */
  5747   5753     pIn1 = &aMem[pOp->p1];
  5748   5754     assert( pIn1->flags&MEM_Int );
  5749   5755     VdbeBranchTaken(pIn1->u.i<0, 2);
  5750   5756     if( pIn1->u.i ){
  5751         -     pIn1->u.i += pOp->p3;
         5757  +     pIn1->u.i -= pOp->p3;
  5752   5758        goto jump_to_p2;
  5753   5759     }
  5754   5760     break;
  5755   5761   }
  5756   5762   
  5757   5763   /* Opcode: DecrJumpZero P1 P2 * * *
  5758   5764   ** Synopsis: if (--r[P1])==0 goto P2

Changes to src/vdbeblob.c.

   244    244           }
   245    245         }
   246    246   #endif
   247    247         for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
   248    248           int j;
   249    249           for(j=0; j<pIdx->nKeyCol; j++){
   250    250             /* FIXME: Be smarter about indexes that use expressions */
   251         -          if( pIdx->aiColumn[j]==iCol || pIdx->aiColumn[j]==(-2) ){
          251  +          if( pIdx->aiColumn[j]==iCol || pIdx->aiColumn[j]==XN_EXPR ){
   252    252               zFault = "indexed";
   253    253             }
   254    254           }
   255    255         }
   256    256         if( zFault ){
   257    257           sqlite3DbFree(db, zErr);
   258    258           zErr = sqlite3MPrintf(db, "cannot open %s column for writing", zFault);

Changes to src/vtab.c.

   933    933   
   934    934       /* Invoke the xBegin method. If successful, add the vtab to the 
   935    935       ** sqlite3.aVTrans[] array. */
   936    936       rc = growVTrans(db);
   937    937       if( rc==SQLITE_OK ){
   938    938         rc = pModule->xBegin(pVTab->pVtab);
   939    939         if( rc==SQLITE_OK ){
          940  +        int iSvpt = db->nStatement + db->nSavepoint;
   940    941           addToVTrans(db, pVTab);
          942  +        if( iSvpt ) rc = sqlite3VtabSavepoint(db, SAVEPOINT_BEGIN, iSvpt-1);
   941    943         }
   942    944       }
   943    945     }
   944    946     return rc;
   945    947   }
   946    948   
   947    949   /*
................................................................................
  1139   1141   
  1140   1142   /*
  1141   1143   ** Erase the eponymous virtual table instance associated with
  1142   1144   ** virtual table module pMod, if it exists.
  1143   1145   */
  1144   1146   void sqlite3VtabEponymousTableClear(sqlite3 *db, Module *pMod){
  1145   1147     Table *pTab = pMod->pEpoTab;
  1146         -  if( (pTab = pMod->pEpoTab)!=0 ){
         1148  +  if( pTab!=0 ){
  1147   1149       sqlite3DeleteColumnNames(db, pTab);
  1148   1150       sqlite3VtabClear(db, pTab);
  1149   1151       sqlite3DbFree(db, pTab);
  1150   1152       pMod->pEpoTab = 0;
  1151   1153     }
  1152   1154   }
  1153   1155   

Changes to src/where.c.

    83     83   ** Any cursors returned will have been opened for writing.
    84     84   **
    85     85   ** aiCur[0] and aiCur[1] both get -1 if the where-clause logic is
    86     86   ** unable to use the ONEPASS optimization.
    87     87   */
    88     88   int sqlite3WhereOkOnePass(WhereInfo *pWInfo, int *aiCur){
    89     89     memcpy(aiCur, pWInfo->aiCurOnePass, sizeof(int)*2);
           90  +#ifdef WHERETRACE_ENABLED
           91  +  if( sqlite3WhereTrace && pWInfo->eOnePass!=ONEPASS_OFF ){
           92  +    sqlite3DebugPrintf("%s cursors: %d %d\n",
           93  +         pWInfo->eOnePass==ONEPASS_SINGLE ? "ONEPASS_SINGLE" : "ONEPASS_MULTI",
           94  +         aiCur[0], aiCur[1]);
           95  +  }
           96  +#endif
    90     97     return pWInfo->eOnePass;
    91     98   }
    92     99   
    93    100   /*
    94    101   ** Move the content of pSrc into pDest
    95    102   */
    96    103   static void whereOrMove(WhereOrSet *pDest, WhereOrSet *pSrc){
................................................................................
   178    185     WhereClause *pWC;    /* Shorthand for pScan->pWC */
   179    186     WhereTerm *pTerm;    /* The term being tested */
   180    187     int k = pScan->k;    /* Where to start scanning */
   181    188   
   182    189     while( pScan->iEquiv<=pScan->nEquiv ){
   183    190       iCur = pScan->aiCur[pScan->iEquiv-1];
   184    191       iColumn = pScan->aiColumn[pScan->iEquiv-1];
   185         -    if( iColumn==(-2) && pScan->pIdxExpr==0 ) return 0;
          192  +    if( iColumn==XN_EXPR && pScan->pIdxExpr==0 ) return 0;
   186    193       while( (pWC = pScan->pWC)!=0 ){
   187    194         for(pTerm=pWC->a+k; k<pWC->nTerm; k++, pTerm++){
   188    195           if( pTerm->leftCursor==iCur
   189    196            && pTerm->u.leftColumn==iColumn
   190         -         && (iColumn!=(-2)
   191         -               || sqlite3ExprCompare(pTerm->pExpr->pLeft,pScan->pIdxExpr,iCur)==0)
          197  +         && (iColumn!=XN_EXPR
          198  +             || sqlite3ExprCompare(pTerm->pExpr->pLeft,pScan->pIdxExpr,iCur)==0)
   192    199            && (pScan->iEquiv<=1 || !ExprHasProperty(pTerm->pExpr, EP_FromJoin))
   193    200           ){
   194    201             if( (pTerm->eOperator & WO_EQUIV)!=0
   195    202              && pScan->nEquiv<ArraySize(pScan->aiCur)
   196    203              && (pX = sqlite3ExprSkipCollate(pTerm->pExpr->pRight))->op==TK_COLUMN
   197    204             ){
   198    205               int j;
................................................................................
   277    284     /* memset(pScan, 0, sizeof(*pScan)); */
   278    285     pScan->pOrigWC = pWC;
   279    286     pScan->pWC = pWC;
   280    287     pScan->pIdxExpr = 0;
   281    288     if( pIdx ){
   282    289       j = iColumn;
   283    290       iColumn = pIdx->aiColumn[j];
   284         -    if( iColumn==(-2) ) pScan->pIdxExpr = pIdx->aColExpr->a[j].pExpr;
          291  +    if( iColumn==XN_EXPR ) pScan->pIdxExpr = pIdx->aColExpr->a[j].pExpr;
   285    292     }
   286    293     if( pIdx && iColumn>=0 ){
   287    294       pScan->idxaff = pIdx->pTable->aCol[iColumn].affinity;
   288    295       pScan->zCollName = pIdx->azColl[j];
   289    296     }else{
   290    297       pScan->idxaff = 0;
   291    298       pScan->zCollName = 0;
................................................................................
   716    723       for(i=BMS-1; i<pTable->nCol; i++){
   717    724         pIdx->aiColumn[n] = i;
   718    725         pIdx->azColl[n] = "BINARY";
   719    726         n++;
   720    727       }
   721    728     }
   722    729     assert( n==nKeyCol );
   723         -  pIdx->aiColumn[n] = -1;
          730  +  pIdx->aiColumn[n] = XN_ROWID;
   724    731     pIdx->azColl[n] = "BINARY";
   725    732   
   726    733     /* Create the automatic index */
   727    734     assert( pLevel->iIdxCur>=0 );
   728    735     pLevel->iIdxCur = pParse->nTab++;
   729    736     sqlite3VdbeAddOp2(v, OP_OpenAutoindex, pLevel->iIdxCur, nKeyCol+1);
   730    737     sqlite3VdbeSetP4KeyInfo(pParse, pIdx);
................................................................................
  1155   1162   
  1156   1163   
  1157   1164   #ifdef SQLITE_ENABLE_STAT3_OR_STAT4
  1158   1165   /*
  1159   1166   ** Return the affinity for a single column of an index.
  1160   1167   */
  1161   1168   static char sqlite3IndexColumnAffinity(sqlite3 *db, Index *pIdx, int iCol){
         1169  +  assert( iCol>=0 && iCol<pIdx->nColumn );
  1162   1170     if( !pIdx->zColAff ){
  1163   1171       if( sqlite3IndexAffinityStr(db, pIdx)==0 ) return SQLITE_AFF_BLOB;
  1164   1172     }
  1165   1173     return pIdx->zColAff[iCol];
  1166   1174   }
  1167   1175   #endif
  1168   1176   
................................................................................
  1212   1220   ){
  1213   1221     Index *p = pLoop->u.btree.pIndex;
  1214   1222     int nEq = pLoop->u.btree.nEq;
  1215   1223     sqlite3 *db = pParse->db;
  1216   1224     int nLower = -1;
  1217   1225     int nUpper = p->nSample+1;
  1218   1226     int rc = SQLITE_OK;
  1219         -  int iCol = p->aiColumn[nEq];
  1220         -  u8 aff = sqlite3IndexColumnAffinity(db, p, iCol);
         1227  +  u8 aff = sqlite3IndexColumnAffinity(db, p, nEq);
  1221   1228     CollSeq *pColl;
  1222   1229     
  1223   1230     sqlite3_value *p1 = 0;          /* Value extracted from pLower */
  1224   1231     sqlite3_value *p2 = 0;          /* Value extracted from pUpper */
  1225   1232     sqlite3_value *pVal = 0;        /* Value extracted from record */
  1226   1233   
  1227   1234     pColl = sqlite3LocateCollSeq(pParse, p->azColl[nEq]);
................................................................................
  2231   2238         assert( nIn>0 );  /* RHS always has 2 or more terms...  The parser
  2232   2239                           ** changes "x IN (?)" into "x=?". */
  2233   2240   
  2234   2241       }else if( eOp & (WO_EQ|WO_IS) ){
  2235   2242         int iCol = pProbe->aiColumn[saved_nEq];
  2236   2243         pNew->wsFlags |= WHERE_COLUMN_EQ;
  2237   2244         assert( saved_nEq==pNew->u.btree.nEq );
  2238         -      if( iCol==(-1) || (iCol>0 && nInMul==0 && saved_nEq==pProbe->nKeyCol-1) ){
         2245  +      if( iCol==XN_ROWID 
         2246  +       || (iCol>0 && nInMul==0 && saved_nEq==pProbe->nKeyCol-1)
         2247  +      ){
  2239   2248           if( iCol>=0 && pProbe->uniqNotNull==0 ){
  2240   2249             pNew->wsFlags |= WHERE_UNQ_WANTED;
  2241   2250           }else{
  2242   2251             pNew->wsFlags |= WHERE_ONEROW;
  2243   2252           }
  2244   2253         }
  2245   2254       }else if( eOp & WO_ISNULL ){
................................................................................
  2417   2426   */
  2418   2427   static int indexMightHelpWithOrderBy(
  2419   2428     WhereLoopBuilder *pBuilder,
  2420   2429     Index *pIndex,
  2421   2430     int iCursor
  2422   2431   ){
  2423   2432     ExprList *pOB;
         2433  +  ExprList *aColExpr;
  2424   2434     int ii, jj;
  2425   2435   
  2426   2436     if( pIndex->bUnordered ) return 0;
  2427   2437     if( (pOB = pBuilder->pWInfo->pOrderBy)==0 ) return 0;
  2428   2438     for(ii=0; ii<pOB->nExpr; ii++){
  2429   2439       Expr *pExpr = sqlite3ExprSkipCollate(pOB->a[ii].pExpr);
  2430         -    if( pExpr->op!=TK_COLUMN ) return 0;
  2431         -    if( pExpr->iTable==iCursor ){
         2440  +    if( pExpr->op==TK_COLUMN && pExpr->iTable==iCursor ){
  2432   2441         if( pExpr->iColumn<0 ) return 1;
  2433   2442         for(jj=0; jj<pIndex->nKeyCol; jj++){
  2434   2443           if( pExpr->iColumn==pIndex->aiColumn[jj] ) return 1;
         2444  +      }
         2445  +    }else if( (aColExpr = pIndex->aColExpr)!=0 ){
         2446  +      for(jj=0; jj<pIndex->nKeyCol; jj++){
         2447  +        if( pIndex->aiColumn[jj]!=XN_EXPR ) continue;
         2448  +        if( sqlite3ExprCompare(pExpr,aColExpr->a[jj].pExpr,iCursor)==0 ){
         2449  +          return 1;
         2450  +        }
  2435   2451         }
  2436   2452       }
  2437   2453     }
  2438   2454     return 0;
  2439   2455   }
  2440   2456   
  2441   2457   /*
................................................................................
  2576   2592   #ifndef SQLITE_OMIT_AUTOMATIC_INDEX
  2577   2593     /* Automatic indexes */
  2578   2594     if( !pBuilder->pOrSet      /* Not part of an OR optimization */
  2579   2595      && (pWInfo->wctrlFlags & WHERE_NO_AUTOINDEX)==0
  2580   2596      && (pWInfo->pParse->db->flags & SQLITE_AutoIndex)!=0
  2581   2597      && pSrc->pIBIndex==0      /* Has no INDEXED BY clause */
  2582   2598      && !pSrc->fg.notIndexed   /* Has no NOT INDEXED clause */
  2583         -   && HasRowid(pTab)         /* Is not a WITHOUT ROWID table. (FIXME: Why not?) */
         2599  +   && HasRowid(pTab)         /* Not WITHOUT ROWID table. (FIXME: Why not?) */
  2584   2600      && !pSrc->fg.isCorrelated /* Not a correlated subquery */
  2585   2601      && !pSrc->fg.isRecursive  /* Not a recursive common table expression. */
  2586   2602     ){
  2587   2603       /* Generate auto-index WhereLoops */
  2588   2604       WhereTerm *pTerm;
  2589   2605       WhereTerm *pWCEnd = pWC->a + pWC->nTerm;
  2590   2606       for(pTerm=pWC->a; rc==SQLITE_OK && pTerm<pWCEnd; pTerm++){
................................................................................
  2821   2837       if( pIdxInfo->needToFreeIdxStr ) sqlite3_free(pIdxInfo->idxStr);
  2822   2838       pIdxInfo->idxStr = 0;
  2823   2839       pIdxInfo->idxNum = 0;
  2824   2840       pIdxInfo->needToFreeIdxStr = 0;
  2825   2841       pIdxInfo->orderByConsumed = 0;
  2826   2842       pIdxInfo->estimatedCost = SQLITE_BIG_DBL / (double)2;
  2827   2843       pIdxInfo->estimatedRows = 25;
         2844  +    pIdxInfo->idxFlags = 0;
  2828   2845       rc = vtabBestIndex(pParse, pTab, pIdxInfo);
  2829   2846       if( rc ) goto whereLoopAddVtab_exit;
  2830   2847       pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint;
  2831   2848       pNew->prereq = mExtra;
  2832   2849       mxTerm = -1;
  2833   2850       assert( pNew->nLSlot>=nConstraint );
  2834   2851       for(i=0; i<nConstraint; i++) pNew->aLTerm[i] = 0;
................................................................................
  2866   2883             }
  2867   2884             /* A virtual table that is constrained by an IN clause may not
  2868   2885             ** consume the ORDER BY clause because (1) the order of IN terms
  2869   2886             ** is not necessarily related to the order of output terms and
  2870   2887             ** (2) Multiple outputs from a single IN value will not merge
  2871   2888             ** together.  */
  2872   2889             pIdxInfo->orderByConsumed = 0;
         2890  +          pIdxInfo->idxFlags &= ~SQLITE_INDEX_SCAN_UNIQUE;
  2873   2891           }
  2874   2892         }
  2875   2893       }
  2876   2894       if( i>=nConstraint ){
  2877   2895         pNew->nLTerm = mxTerm+1;
  2878   2896         assert( pNew->nLTerm<=pNew->nLSlot );
  2879   2897         pNew->u.vtab.idxNum = pIdxInfo->idxNum;
................................................................................
  2881   2899         pIdxInfo->needToFreeIdxStr = 0;
  2882   2900         pNew->u.vtab.idxStr = pIdxInfo->idxStr;
  2883   2901         pNew->u.vtab.isOrdered = (i8)(pIdxInfo->orderByConsumed ?
  2884   2902                                         pIdxInfo->nOrderBy : 0);
  2885   2903         pNew->rSetup = 0;
  2886   2904         pNew->rRun = sqlite3LogEstFromDouble(pIdxInfo->estimatedCost);
  2887   2905         pNew->nOut = sqlite3LogEst(pIdxInfo->estimatedRows);
         2906  +
         2907  +      /* Set the WHERE_ONEROW flag if the xBestIndex() method indicated
         2908  +      ** that the scan will visit at most one row. Clear it otherwise. */
         2909  +      if( pIdxInfo->idxFlags & SQLITE_INDEX_SCAN_UNIQUE ){
         2910  +        pNew->wsFlags |= WHERE_ONEROW;
         2911  +      }else{
         2912  +        pNew->wsFlags &= ~WHERE_ONEROW;
         2913  +      }
  2888   2914         whereLoopInsert(pBuilder, pNew);
  2889   2915         if( pNew->u.vtab.needFree ){
  2890   2916           sqlite3_free(pNew->u.vtab.idxStr);
  2891   2917           pNew->u.vtab.needFree = 0;
  2892   2918         }
  2893   2919       }
  2894   2920     }  
................................................................................
  3202   3228           nColumn = 1;
  3203   3229         }else if( (pIndex = pLoop->u.btree.pIndex)==0 || pIndex->bUnordered ){
  3204   3230           return 0;
  3205   3231         }else{
  3206   3232           nKeyCol = pIndex->nKeyCol;
  3207   3233           nColumn = pIndex->nColumn;
  3208   3234           assert( nColumn==nKeyCol+1 || !HasRowid(pIndex->pTable) );
  3209         -        assert( pIndex->aiColumn[nColumn-1]==(-1) || !HasRowid(pIndex->pTable));
         3235  +        assert( pIndex->aiColumn[nColumn-1]==XN_ROWID
         3236  +                          || !HasRowid(pIndex->pTable));
  3210   3237           isOrderDistinct = IsUniqueIndex(pIndex);
  3211   3238         }
  3212   3239   
  3213   3240         /* Loop through all columns of the index and deal with the ones
  3214   3241         ** that are not constrained by == or IN.
  3215   3242         */
  3216   3243         rev = revSet = 0;
................................................................................
  3234   3261           ** (revIdx) for the j-th column of the index.
  3235   3262           */
  3236   3263           if( pIndex ){
  3237   3264             iColumn = pIndex->aiColumn[j];
  3238   3265             revIdx = pIndex->aSortOrder[j];
  3239   3266             if( iColumn==pIndex->pTable->iPKey ) iColumn = -1;
  3240   3267           }else{
  3241         -          iColumn = -1;
         3268  +          iColumn = XN_ROWID;
  3242   3269             revIdx = 0;
  3243   3270           }
  3244   3271   
  3245   3272           /* An unconstrained column that might be NULL means that this
  3246   3273           ** WhereLoop is not well-ordered
  3247   3274           */
  3248   3275           if( isOrderDistinct
................................................................................
  3260   3287           isMatch = 0;
  3261   3288           for(i=0; bOnce && i<nOrderBy; i++){
  3262   3289             if( MASKBIT(i) & obSat ) continue;
  3263   3290             pOBExpr = sqlite3ExprSkipCollate(pOrderBy->a[i].pExpr);
  3264   3291             testcase( wctrlFlags & WHERE_GROUPBY );
  3265   3292             testcase( wctrlFlags & WHERE_DISTINCTBY );
  3266   3293             if( (wctrlFlags & (WHERE_GROUPBY|WHERE_DISTINCTBY))==0 ) bOnce = 0;
  3267         -          if( pOBExpr->op!=TK_COLUMN ) continue;
  3268         -          if( pOBExpr->iTable!=iCur ) continue;
  3269         -          if( pOBExpr->iColumn!=iColumn ) continue;
         3294  +          if( iColumn>=(-1) ){
         3295  +            if( pOBExpr->op!=TK_COLUMN ) continue;
         3296  +            if( pOBExpr->iTable!=iCur ) continue;
         3297  +            if( pOBExpr->iColumn!=iColumn ) continue;
         3298  +          }else{
         3299  +            if( sqlite3ExprCompare(pOBExpr,pIndex->aColExpr->a[j].pExpr,iCur) ){
         3300  +              continue;
         3301  +            }
         3302  +          }
  3270   3303             if( iColumn>=0 ){
  3271   3304               pColl = sqlite3ExprCollSeq(pWInfo->pParse, pOrderBy->a[i].pExpr);
  3272   3305               if( !pColl ) pColl = db->pDfltColl;
  3273   3306               if( sqlite3StrICmp(pColl->zName, pIndex->azColl[j])!=0 ) continue;
  3274   3307             }
  3275   3308             isMatch = 1;
  3276   3309             break;
................................................................................
  4093   4126         /* Try to ORDER BY the result set to make distinct processing easier */
  4094   4127         pWInfo->wctrlFlags |= WHERE_DISTINCTBY;
  4095   4128         pWInfo->pOrderBy = pResultSet;
  4096   4129       }
  4097   4130     }
  4098   4131   
  4099   4132     /* Construct the WhereLoop objects */
  4100         -  WHERETRACE(0xffff,("*** Optimizer Start ***\n"));
         4133  +  WHERETRACE(0xffff,("*** Optimizer Start *** (wctrlFlags: 0x%x)\n",
         4134  +             wctrlFlags));
  4101   4135   #if defined(WHERETRACE_ENABLED)
  4102   4136     if( sqlite3WhereTrace & 0x100 ){ /* Display all terms of the WHERE clause */
  4103   4137       int i;
  4104   4138       for(i=0; i<sWLB.pWC->nTerm; i++){
  4105   4139         whereTermPrint(&sWLB.pWC->a[i], i);
  4106   4140       }
  4107   4141     }
................................................................................
  4512   4546       ** reference the index.
  4513   4547       */
  4514   4548       if( pLoop->wsFlags & (WHERE_INDEXED|WHERE_IDX_ONLY) ){
  4515   4549         pIdx = pLoop->u.btree.pIndex;
  4516   4550       }else if( pLoop->wsFlags & WHERE_MULTI_OR ){
  4517   4551         pIdx = pLevel->u.pCovidx;
  4518   4552       }
  4519         -    if( pIdx && !db->mallocFailed ){
         4553  +    if( pIdx
         4554  +     && (pWInfo->eOnePass==ONEPASS_OFF || !HasRowid(pIdx->pTable))
         4555  +     && !db->mallocFailed
         4556  +    ){
  4520   4557         last = sqlite3VdbeCurrentAddr(v);
  4521   4558         k = pLevel->addrBody;
  4522   4559         pOp = sqlite3VdbeGetOp(v, k);
  4523   4560         for(; k<last; k++, pOp++){
  4524   4561           if( pOp->p1!=pLevel->iTabCur ) continue;
  4525   4562           if( pOp->opcode==OP_Column ){
  4526   4563             int x = pOp->p2;
  4527   4564             assert( pIdx->pTable==pTab );
  4528   4565             if( !HasRowid(pTab) ){
  4529   4566               Index *pPk = sqlite3PrimaryKeyIndex(pTab);
  4530   4567               x = pPk->aiColumn[x];
         4568  +            assert( x>=0 );
  4531   4569             }
  4532   4570             x = sqlite3ColumnOfIndex(pIdx, x);
  4533   4571             if( x>=0 ){
  4534   4572               pOp->p2 = x;
  4535   4573               pOp->p1 = pLevel->iIdxCur;
  4536   4574             }
  4537   4575             assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 || x>=0 );

Changes to src/wherecode.c.

    42     42   }
    43     43   
    44     44   /*
    45     45   ** Return the name of the i-th column of the pIdx index.
    46     46   */
    47     47   static const char *explainIndexColumnName(Index *pIdx, int i){
    48     48     i = pIdx->aiColumn[i];
    49         -  if( i==(-2) ) return "<expr>";
    50         -  if( i==(-1) ) return "rowid";
           49  +  if( i==XN_EXPR ) return "<expr>";
           50  +  if( i==XN_ROWID ) return "rowid";
    51     51     return pIdx->pTable->aCol[i].zName;
    52     52   }
    53     53   
    54     54   /*
    55     55   ** Argument pLevel describes a strategy for scanning table pTab. This 
    56     56   ** function appends text to pStr that describes the subset of table
    57     57   ** rows scanned by the strategy in the form of an SQL expression.
................................................................................
   510    510       pLevel->addrSkip = sqlite3VdbeAddOp4Int(v, (bRev?OP_SeekLT:OP_SeekGT),
   511    511                               iIdxCur, 0, regBase, nSkip);
   512    512       VdbeCoverageIf(v, bRev==0);
   513    513       VdbeCoverageIf(v, bRev!=0);
   514    514       sqlite3VdbeJumpHere(v, j);
   515    515       for(j=0; j<nSkip; j++){
   516    516         sqlite3VdbeAddOp3(v, OP_Column, iIdxCur, j, regBase+j);
   517         -      testcase( pIdx->aiColumn[j]==(-2) );
          517  +      testcase( pIdx->aiColumn[j]==XN_EXPR );
   518    518         VdbeComment((v, "%s", explainIndexColumnName(pIdx, j)));
   519    519       }
   520    520     }    
   521    521   
   522    522     /* Evaluate the equality constraints
   523    523     */
   524    524     assert( zAff==0 || (int)strlen(zAff)>=nEq );
................................................................................
   696    696       VdbeCoverage(v);
   697    697       pLoop->u.vtab.needFree = 0;
   698    698       for(j=0; j<nConstraint && j<16; j++){
   699    699         if( (pLoop->u.vtab.omitMask>>j)&1 ){
   700    700           disableTerm(pLevel, pLoop->aLTerm[j]);
   701    701         }
   702    702       }
   703         -    pLevel->op = OP_VNext;
   704    703       pLevel->p1 = iCur;
          704  +    pLevel->op = pWInfo->eOnePass ? OP_Noop : OP_VNext;
   705    705       pLevel->p2 = sqlite3VdbeCurrentAddr(v);
   706    706       sqlite3ReleaseTempRange(pParse, iReg, nConstraint+2);
   707    707       sqlite3ExprCachePop(pParse);
   708    708     }else
   709    709   #endif /* SQLITE_OMIT_VIRTUALTABLE */
   710    710   
   711    711     if( (pLoop->wsFlags & WHERE_IPK)!=0
................................................................................
  1262   1262                   | WHERE_ONETABLE_ONLY
  1263   1263                   | WHERE_NO_AUTOINDEX;
  1264   1264       for(ii=0; ii<pOrWc->nTerm; ii++){
  1265   1265         WhereTerm *pOrTerm = &pOrWc->a[ii];
  1266   1266         if( pOrTerm->leftCursor==iCur || (pOrTerm->eOperator & WO_AND)!=0 ){
  1267   1267           WhereInfo *pSubWInfo;           /* Info for single OR-term scan */
  1268   1268           Expr *pOrExpr = pOrTerm->pExpr; /* Current OR clause term */
  1269         -        int j1 = 0;                     /* Address of jump operation */
         1269  +        int jmp1 = 0;                   /* Address of jump operation */
  1270   1270           if( pAndExpr && !ExprHasProperty(pOrExpr, EP_FromJoin) ){
  1271   1271             pAndExpr->pLeft = pOrExpr;
  1272   1272             pOrExpr = pAndExpr;
  1273   1273           }
  1274   1274           /* Loop through table entries that match term pOrTerm. */
  1275   1275           WHERETRACE(0xffff, ("Subplan for OR-clause:\n"));
  1276   1276           pSubWInfo = sqlite3WhereBegin(pParse, pOrTab, pOrExpr, 0, 0,
................................................................................
  1289   1289             ** row will be skipped in subsequent sub-WHERE clauses.
  1290   1290             */
  1291   1291             if( (pWInfo->wctrlFlags & WHERE_DUPLICATES_OK)==0 ){
  1292   1292               int r;
  1293   1293               int iSet = ((ii==pOrWc->nTerm-1)?-1:ii);
  1294   1294               if( HasRowid(pTab) ){
  1295   1295                 r = sqlite3ExprCodeGetColumn(pParse, pTab, -1, iCur, regRowid, 0);
  1296         -              j1 = sqlite3VdbeAddOp4Int(v, OP_RowSetTest, regRowset, 0, r,iSet);
         1296  +              jmp1 = sqlite3VdbeAddOp4Int(v, OP_RowSetTest, regRowset, 0,
         1297  +                                           r,iSet);
  1297   1298                 VdbeCoverage(v);
  1298   1299               }else{
  1299   1300                 Index *pPk = sqlite3PrimaryKeyIndex(pTab);
  1300   1301                 int nPk = pPk->nKeyCol;
  1301   1302                 int iPk;
  1302   1303   
  1303   1304                 /* Read the PK into an array of temp registers. */
................................................................................
  1319   1320                 **
  1320   1321                 ** Use some of the same optimizations as OP_RowSetTest: If iSet
  1321   1322                 ** is zero, assume that the key cannot already be present in
  1322   1323                 ** the temp table. And if iSet is -1, assume that there is no 
  1323   1324                 ** need to insert the key into the temp table, as it will never 
  1324   1325                 ** be tested for.  */ 
  1325   1326                 if( iSet ){
  1326         -                j1 = sqlite3VdbeAddOp4Int(v, OP_Found, regRowset, 0, r, nPk);
         1327  +                jmp1 = sqlite3VdbeAddOp4Int(v, OP_Found, regRowset, 0, r, nPk);
  1327   1328                   VdbeCoverage(v);
  1328   1329                 }
  1329   1330                 if( iSet>=0 ){
  1330   1331                   sqlite3VdbeAddOp3(v, OP_MakeRecord, r, nPk, regRowid);
  1331   1332                   sqlite3VdbeAddOp3(v, OP_IdxInsert, regRowset, regRowid, 0);
  1332   1333                   if( iSet ) sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
  1333   1334                 }
................................................................................
  1338   1339             }
  1339   1340   
  1340   1341             /* Invoke the main loop body as a subroutine */
  1341   1342             sqlite3VdbeAddOp2(v, OP_Gosub, regReturn, iLoopBody);
  1342   1343   
  1343   1344             /* Jump here (skipping the main loop body subroutine) if the
  1344   1345             ** current sub-WHERE row is a duplicate from prior sub-WHEREs. */
  1345         -          if( j1 ) sqlite3VdbeJumpHere(v, j1);
         1346  +          if( jmp1 ) sqlite3VdbeJumpHere(v, jmp1);
  1346   1347   
  1347   1348             /* The pSubWInfo->untestedTerms flag means that this OR term
  1348   1349             ** contained one or more AND term from a notReady table.  The
  1349   1350             ** terms from the notReady table could not be tested and will
  1350   1351             ** need to be tested later.
  1351   1352             */
  1352   1353             if( pSubWInfo->untestedTerms ) untestedTerms = 1;

Changes to src/whereexpr.c.

   946    946             eExtraOp = WO_EQUIV;
   947    947           }
   948    948         }else{
   949    949           pDup = pExpr;
   950    950           pNew = pTerm;
   951    951         }
   952    952         exprCommute(pParse, pDup);
   953         -      pLeft = sqlite3ExprSkipCollate(pDup->pLeft);
   954    953         pNew->leftCursor = iCur;
   955    954         pNew->u.leftColumn = iColumn;
   956    955         testcase( (prereqLeft | extraRight) != prereqLeft );
   957    956         pNew->prereqRight = prereqLeft | extraRight;
   958    957         pNew->prereqAll = prereqAll;
   959    958         pNew->eOperator = (operatorMask(pDup->op) + eExtraOp) & opMask;
   960    959       }

Changes to test/delete4.test.

    93     93   do_execsql_test 3.3 {
    94     94     SELECT i FROM t1 ORDER BY i;
    95     95   } {1 3 5 7}
    96     96   
    97     97   do_execsql_test 3.4 { 
    98     98     PRAGMA integrity_check; 
    99     99   } {ok}
          100  +
          101  +# Between 2015-09-14 and 2015-09-28, the following test cases would result
          102  +# in corruption (wrong # of entries in index) due to a bug in the ONEPASS
          103  +# optimization.
          104  +#
          105  +do_execsql_test 4.1 {
          106  +  DROP TABLE IF EXISTS t4;
          107  +  CREATE TABLE t4(col0, col1);
          108  +  INSERT INTO "t4" VALUES(14, 'abcde');
          109  +  CREATE INDEX idx_t4_0 ON t4 (col1, col0);
          110  +  CREATE INDEX idx_t4_3 ON t4 (col0);
          111  +  DELETE FROM t4 WHERE col0=69 OR col0>7;
          112  +  PRAGMA integrity_check;
          113  +} {ok}
          114  +do_execsql_test 4.2 {
          115  +  DROP TABLE IF EXISTS t4;
          116  +  CREATE TABLE t4(col0, col1);
          117  +  INSERT INTO "t4" VALUES(14, 'abcde');
          118  +  CREATE INDEX idx_t4_3 ON t4 (col0);
          119  +  CREATE INDEX idx_t4_0 ON t4 (col1, col0);
          120  +  DELETE FROM t4 WHERE col0=69 OR col0>7;
          121  +  PRAGMA integrity_check;
          122  +} {ok}
          123  +do_execsql_test 4.11 {
          124  +  DROP TABLE IF EXISTS t4;
          125  +  CREATE TABLE t4(col0, col1, pk PRIMARY KEY) WITHOUT ROWID;
          126  +  INSERT INTO t4 VALUES(14, 'abcde','xyzzy');
          127  +  CREATE INDEX idx_t4_0 ON t4 (col1, col0);
          128  +  CREATE INDEX idx_t4_3 ON t4 (col0);
          129  +  DELETE FROM t4 WHERE col0=69 OR col0>7;
          130  +  PRAGMA integrity_check;
          131  +} {ok}
          132  +do_execsql_test 4.12 {
          133  +  DROP TABLE IF EXISTS t4;
          134  +  CREATE TABLE t4(col0, col1, pk PRIMARY KEY) WITHOUT ROWID;
          135  +  INSERT INTO t4 VALUES(14, 'abcde','xyzzy');
          136  +  CREATE INDEX idx_t4_3 ON t4 (col0);
          137  +  CREATE INDEX idx_t4_0 ON t4 (col1, col0);
          138  +  DELETE FROM t4 WHERE col0=69 OR col0>7;
          139  +  PRAGMA integrity_check;
          140  +} {ok}
          141  +
          142  +
   100    143   
   101    144   
   102    145   finish_test

Changes to test/fkey1.test.

   146    146     SELECT 1, """5" FROM """4";
   147    147     DELETE FROM """1";
   148    148     SELECT 2, """5" FROM """4";
   149    149   } {1 abc}
   150    150   do_execsql_test fkey1-4.2 {
   151    151     PRAGMA table_info="""1";
   152    152   } {0 {"2} TEXT 0 {} 1 1 {"3} TEXT 0 {} 0}
          153  +
          154  +#-------------------------------------------------------------------------
          155  +#
          156  +do_execsql_test fkey1-5.1 {
          157  +  CREATE TABLE t11(
          158  +    x INTEGER PRIMARY KEY, 
          159  +    parent REFERENCES t11 ON DELETE CASCADE
          160  +  );
          161  +  INSERT INTO t11 VALUES (1, NULL), (2, 1), (3, 2);
          162  +} {}
          163  +
          164  +# The REPLACE part of this statement deletes the row (2, 1). Then the 
          165  +# DELETE CASCADE caused by deleting that row removes the (3, 2) row. Which
          166  +# would have been the parent of the new row being inserted. Causing an
          167  +# FK violation.
          168  +#
          169  +do_catchsql_test fkey1-5.2 {
          170  +  INSERT OR REPLACE INTO t11 VALUES (2, 3);
          171  +} {1 {FOREIGN KEY constraint failed}}
          172  +
          173  +# A similar test to the above.
          174  +do_execsql_test fkey1-5.3 {
          175  +  CREATE TABLE Foo (
          176  +    Id INTEGER PRIMARY KEY, 
          177  +    ParentId INTEGER REFERENCES Foo(Id) ON DELETE CASCADE, C1
          178  +  );
          179  +  INSERT OR REPLACE INTO Foo(Id, ParentId, C1) VALUES (1, null, 'A');
          180  +  INSERT OR REPLACE INTO Foo(Id, ParentId, C1) VALUES (2, 1, 'A-2-1');
          181  +  INSERT OR REPLACE INTO Foo(Id, ParentId, C1) VALUES (3, 2, 'A-3-2');
          182  +  INSERT OR REPLACE INTO Foo(Id, ParentId, C1) VALUES (4, 3, 'A-4-3');
          183  +}
          184  +do_catchsql_test fkey1-5.4 {
          185  +  INSERT OR REPLACE INTO Foo(Id, ParentId, C1) VALUES (2, 3, 'A-2-3');
          186  +} {1 {FOREIGN KEY constraint failed}}
   153    187   
   154    188   finish_test

Changes to test/fts3conf.test.

    82     82   
    83     83     6    "INSERT OR ROLLBACK $T2"   1 1 {{a b c d} {e f g h}}
    84     84     7    "INSERT OR ABORT    $T2"   1 1 {{a b c d} {e f g h} {i j k l}}
    85     85     8    "INSERT OR FAIL     $T2"   1 1 {{a b c d} {e f g h} {i j k l} z}
    86     86     9    "INSERT OR IGNORE   $T2"   1 0 {{a b c d} {e f g h} {i j k l} z}
    87     87     10   "INSERT OR REPLACE  $T2"   1 0 {{a b c d} y {i j k l} z}
    88     88   
    89         -  11   "UPDATE OR ROLLBACK $T3"   1 1 {{a b c d} {e f g h}}
    90         -  12   "UPDATE OR ABORT    $T3"   1 1 {{a b c d} {e f g h} {i j k l}}
    91         -  13   "UPDATE OR FAIL     $T3"   1 1 {{a b c d} {e f g h} {i j k l}}
    92         -  14   "UPDATE OR IGNORE   $T3"   1 0 {{a b c d} {e f g h} {i j k l}}
    93         -  15   "UPDATE OR REPLACE  $T3"   1 0 {{a b c d} {i j k l}}
           89  +  11   "UPDATE OR ROLLBACK $T3"   0 1 {{a b c d} {e f g h}}
           90  +  12   "UPDATE OR ABORT    $T3"   0 1 {{a b c d} {e f g h} {i j k l}}
           91  +  13   "UPDATE OR FAIL     $T3"   0 1 {{a b c d} {e f g h} {i j k l}}
           92  +  14   "UPDATE OR IGNORE   $T3"   0 0 {{a b c d} {e f g h} {i j k l}}
           93  +  15   "UPDATE OR REPLACE  $T3"   0 0 {{a b c d} {i j k l}}
    94     94   
    95     95     16   "UPDATE OR ROLLBACK $T4"   1 1 {{a b c d} {e f g h}}
    96     96     17   "UPDATE OR ABORT    $T4"   1 1 {{a b c d} {e f g h} {i j k l}}
    97     97     18   "UPDATE OR FAIL     $T4"   1 1 {{e f g h} {i j k l} {a b c d}}
    98     98     19   "UPDATE OR IGNORE   $T4"   1 0 {{e f g h} {i j k l} {a b c d}}
    99     99     20   "UPDATE OR REPLACE  $T4"   1 0 {{e f g h} {a b c d}}
   100    100   }] {
................................................................................
   173    173     SELECT docid FROM t3;
   174    174   } {3 4 5}
   175    175   
   176    176   do_execsql_test 3.8 {
   177    177     UPDATE OR REPLACE t3 SET docid = 5, content='three four' WHERE docid = 4;
   178    178     SELECT quote(matchinfo(t3, 'na')) FROM t3 WHERE t3 MATCH 'one'
   179    179   } {X'0200000002000000'}
          180  +
          181  +#-------------------------------------------------------------------------
          182  +# Test that the xSavepoint is invoked correctly if the first write 
          183  +# operation within a transaction is to a virtual table. 
          184  +# 
          185  +do_catchsql_test 4.1.1 {
          186  +  CREATE VIRTUAL TABLE t0 USING fts4;
          187  +  BEGIN;
          188  +    INSERT INTO t0(rowid, content) SELECT
          189  +      1, 'abc' UNION ALL SELECT
          190  +      2, 'def' UNION ALL SELECT
          191  +      1, 'ghi';
          192  +} {1 {constraint failed}}
          193  +do_execsql_test 4.1.2 {
          194  +  COMMIT;
          195  +}
          196  +do_execsql_test 4.1.3 {
          197  +  SELECT * FROM t0 WHERE t0 MATCH 'abc';
          198  +  INSERT INTO t0(t0) VALUES('integrity-check');
          199  +} {}
          200  +
          201  +do_execsql_test 4.2.1 {
          202  +  CREATE VIRTUAL TABLE t01 USING fts4;
          203  +  BEGIN;
          204  +    SAVEPOINT abc;
          205  +      INSERT INTO t01 VALUES('a b c');
          206  +    ROLLBACK TO abc;
          207  +  COMMIT;
          208  +}
          209  +do_execsql_test 4.2.2 {
          210  +  SELECT * FROM t01 WHERE t01 MATCH 'b';
          211  +  INSERT INTO t01(t01) VALUES('integrity-check');
          212  +} {}
   180    213   
   181    214   finish_test
          215  +

Changes to test/fts3expr3.test.

   117    117   proc balanced_andor_tree {nEntry} {
   118    118     set tree [balanced_exprtree_structure $nEntry]
   119    119     set node "{[balanced_and_tree $nEntry]}"
   120    120     regsub -all AND $node OR node
   121    121     regsub -all xxx $tree $node tree
   122    122     return $tree
   123    123   }
          124  +
          125  +if 1 {
   124    126   
   125    127   # Test that queries like "1 AND 2 AND 3 AND 4..." are transformed to 
   126    128   # balanced trees by FTS.
   127    129   #
   128    130   for {set i 1} {$i < 100} {incr i} {
   129    131     do_test 1.$i {
   130    132       test_fts3expr2 [random_and_query $i]
................................................................................
   197    199   set query [random_andor_query 12]
   198    200   set result [balanced_andor_tree 12]
   199    201   do_faultsim_test fts3expr3-fault-1 -faults oom-* -body {
   200    202     test_fts3expr2 $::query
   201    203   } -test {
   202    204     faultsim_test_result [list 0 $::result]
   203    205   }
          206  +
          207  +}
          208  +
          209  +#-------------------------------------------------------------------
          210  +
          211  +foreach {tn expr res} {
          212  +  1 {1 OR 2 OR 3 OR 4}           {OR {OR {P 1} {P 2}} {OR {P 3} {P 4}}} 
          213  +  2 {1 OR (2 AND 3 AND 4 AND 5)} 
          214  +    {OR {P 1} {AND {AND {P 2} {P 3}} {AND {P 4} {P 5}}}}
          215  +  3 {(2 AND 3 AND 4 AND 5) OR 1} 
          216  +    {OR {AND {AND {P 2} {P 3}} {AND {P 4} {P 5}}} {P 1}}
          217  +
          218  +  4 {1 AND (2 OR 3 OR 4 OR 5)} 
          219  +    {AND {P 1} {OR {OR {P 2} {P 3}} {OR {P 4} {P 5}}}}
          220  +  5 {(2 OR 3 OR 4 OR 5) AND 1} 
          221  +    {AND {OR {OR {P 2} {P 3}} {OR {P 4} {P 5}}} {P 1}}
          222  +
          223  +  6 {(2 OR 3 OR 4 OR 5) NOT 1} 
          224  +    {NOT {OR {OR {P 2} {P 3}} {OR {P 4} {P 5}}} {P 1}}
          225  +
          226  +  7 {1 NOT (2 OR 3 OR 4 OR 5)} 
          227  +    {NOT {P 1} {OR {OR {P 2} {P 3}} {OR {P 4} {P 5}}}}
          228  +
          229  +  8 {(1 OR 2 OR 3 OR 4) NOT (5 AND 6 AND 7 AND 8)}
          230  +    {NOT {OR {OR {P 1} {P 2}} {OR {P 3} {P 4}}} {AND {AND {P 5} {P 6}} {AND {P 7} {P 8}}}}
          231  +} {
          232  +  do_test 5.1.$tn {
          233  +    test_fts3expr2 $expr
          234  +  } $res
          235  +}
   204    236   
   205    237   set sqlite_fts3_enable_parentheses 0
   206    238   finish_test

Added test/fts4onepass.test.

            1  +# 2015 Sep 27
            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  +set testdir [file dirname $argv0]
           14  +source $testdir/tester.tcl
           15  +source $testdir/fts3_common.tcl
           16  +set ::testprefix fts4onepass
           17  +
           18  +# If SQLITE_ENABLE_FTS3 is defined, omit this file.
           19  +ifcapable !fts3 {
           20  +  finish_test
           21  +  return
           22  +}
           23  +
           24  +do_execsql_test 1.0 {
           25  +  CREATE VIRTUAL TABLE ft USING fts3;
           26  +  INSERT INTO ft(rowid, content) VALUES(1, '1 2 3');
           27  +  INSERT INTO ft(rowid, content) VALUES(2, '4 5 6');
           28  +  INSERT INTO ft(rowid, content) VALUES(3, '7 8 9');
           29  +}
           30  +
           31  +#-------------------------------------------------------------------------
           32  +# Check that UPDATE and DELETE statements that feature "WHERE rowid=?" or 
           33  +# or "WHERE docid=?" clauses do not use statement journals. But that other
           34  +# DELETE and UPDATE statements do.
           35  +#
           36  +# Note: "MATCH ? AND docid=?" does use a statement journal.
           37  +#
           38  +foreach {tn sql uses} {
           39  +  1.1 { DELETE FROM ft } 1
           40  +  1.2 { DELETE FROM ft WHERE docid=? } 0
           41  +  1.3 { DELETE FROM ft WHERE rowid=? } 0
           42  +  1.4 { DELETE FROM ft WHERE ft MATCH '1' } 1
           43  +  1.5 { DELETE FROM ft WHERE ft MATCH '1' AND docid=? } 1
           44  +  1.6 { DELETE FROM ft WHERE ft MATCH '1' AND rowid=? } 1
           45  +
           46  +  2.1 { UPDATE ft SET content='a b c' } 1
           47  +  2.2 { UPDATE ft SET content='a b c' WHERE docid=? } 0
           48  +  2.3 { UPDATE ft SET content='a b c' WHERE rowid=? } 0
           49  +  2.4 { UPDATE ft SET content='a b c' WHERE ft MATCH '1' } 1
           50  +  2.5 { UPDATE ft SET content='a b c' WHERE ft MATCH '1' AND docid=? } 1
           51  +  2.6 { UPDATE ft SET content='a b c' WHERE ft MATCH '1' AND rowid=? } 1
           52  +} {
           53  +  do_test 1.$tn { sql_uses_stmt db $sql } $uses
           54  +}
           55  +
           56  +#-------------------------------------------------------------------------
           57  +# Check that putting a "DELETE/UPDATE ... WHERE rowid=?" statement in a
           58  +# trigger program does not prevent the VM from using a statement 
           59  +# transaction. Even if the calling statement cannot hit a constraint.
           60  +#
           61  +do_execsql_test 2.0 {
           62  +  CREATE TABLE t1(x);
           63  +
           64  +  CREATE TRIGGER t1_ai AFTER INSERT ON t1 BEGIN
           65  +    DELETE FROM ft WHERE rowid=new.x;
           66  +  END;
           67  +
           68  +  CREATE TRIGGER t1_ad AFTER DELETE ON t1 BEGIN
           69  +    UPDATE ft SET content = 'a b c' WHERE rowid=old.x;
           70  +  END;
           71  +
           72  +  CREATE TRIGGER t1_bu BEFORE UPDATE ON t1 BEGIN
           73  +    DELETE FROM ft WHERE rowid=old.x;
           74  +  END;
           75  +}
           76  +
           77  +foreach {tn sql uses} {
           78  +  1 { INSERT INTO t1 VALUES(1)      } 1
           79  +  2 { DELETE FROM t1 WHERE x=4      } 1
           80  +  3 { UPDATE t1 SET x=10 WHERE x=11 } 1
           81  +} {
           82  +  do_test 2.$tn { sql_uses_stmt db $sql } $uses
           83  +}
           84  +
           85  +#-------------------------------------------------------------------------
           86  +# Test that an "UPDATE ... WHERE rowid=?" works and does not corrupt the
           87  +# index when it strikes a constraint. Both inside and outside a 
           88  +# transaction.
           89  +#
           90  +foreach {tn tcl1 tcl2}  {
           91  +  1 {} {}
           92  +
           93  +  2 {
           94  +    execsql BEGIN
           95  +  } {
           96  +    if {[sqlite3_get_autocommit db]==1} { error "transaction rolled back!" }
           97  +    execsql COMMIT
           98  +  }
           99  +} {
          100  +
          101  +  do_execsql_test 3.$tn.0 {
          102  +    DROP TABLE IF EXISTS ft2;
          103  +    CREATE VIRTUAL TABLE ft2 USING fts4;
          104  +    INSERT INTO ft2(rowid, content) VALUES(1, 'a b c');
          105  +    INSERT INTO ft2(rowid, content) VALUES(2, 'a b d');
          106  +    INSERT INTO ft2(rowid, content) VALUES(3, 'a b e');
          107  +  }
          108  +
          109  +  eval $tcl1
          110  +  foreach {tn2 sql content} {
          111  +    1 { UPDATE ft2 SET docid=2 WHERE docid=1 }
          112  +      { 1 {a b c} 2 {a b d} 3 {a b e} }
          113  +
          114  +    2 { 
          115  +      INSERT INTO ft2(rowid, content) VALUES(4, 'a b f');
          116  +      UPDATE ft2 SET docid=5 WHERE docid=4;
          117  +      UPDATE ft2 SET docid=3 WHERE docid=5;
          118  +    } { 1 {a b c} 2 {a b d} 3 {a b e} 5 {a b f} }
          119  +
          120  +    3 {
          121  +      UPDATE ft2 SET docid=3 WHERE docid=4;           -- matches 0 rows
          122  +      UPDATE ft2 SET docid=2 WHERE docid=3;
          123  +    } { 1 {a b c} 2 {a b d} 3 {a b e} 5 {a b f} }
          124  +
          125  +    4 {
          126  +      INSERT INTO ft2(rowid, content) VALUES(4, 'a b g');
          127  +      UPDATE ft2 SET docid=-1 WHERE docid=4;
          128  +      UPDATE ft2 SET docid=3 WHERE docid=-1;
          129  +    } {-1 {a b g} 1 {a b c} 2 {a b d} 3 {a b e} 5 {a b f} }
          130  +
          131  +    5 {
          132  +      DELETE FROM ft2 WHERE rowid=451;
          133  +      DELETE FROM ft2 WHERE rowid=-1;
          134  +      UPDATE ft2 SET docid = 2 WHERE docid = 1;
          135  +    } {1 {a b c} 2 {a b d} 3 {a b e} 5 {a b f} }
          136  +  } {
          137  +    do_catchsql_test 3.$tn.$tn2.a $sql {1 {constraint failed}}
          138  +    do_execsql_test  3.$tn.$tn2.b { SELECT rowid, content FROM ft2 } $content
          139  +    do_execsql_test  3.$tn.$tn2.c { 
          140  +      INSERT INTO ft2(ft2) VALUES('integrity-check');
          141  +    }
          142  +  }
          143  +  eval $tcl2
          144  +}
          145  +
          146  +finish_test
          147  +

Changes to test/fuzzcheck.c.

  1047   1047         g.pFirstDb->seq = 0;
  1048   1048         g.nDb = 1;
  1049   1049         sqlFuzz = 1;
  1050   1050       }
  1051   1051     
  1052   1052       /* Print the description, if there is one */
  1053   1053       if( !quietFlag ){
  1054         -      int i;
  1055   1054         zDbName = azSrcDb[iSrcDb];
  1056   1055         i = strlen(zDbName) - 1;
  1057   1056         while( i>0 && zDbName[i-1]!='/' && zDbName[i-1]!='\\' ){ i--; }
  1058   1057         zDbName += i;
  1059   1058         sqlite3_prepare_v2(db, "SELECT msg FROM readme", -1, &pStmt, 0);
  1060   1059         if( pStmt && sqlite3_step(pStmt)==SQLITE_ROW ){
  1061   1060           printf("%s: %s\n", zDbName, sqlite3_column_text(pStmt,0));
................................................................................
  1123   1122           openFlags = SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE;
  1124   1123           if( nativeFlag && pDb->sz==0 ){
  1125   1124             openFlags |= SQLITE_OPEN_MEMORY;
  1126   1125             zVfs = 0;
  1127   1126           }
  1128   1127           rc = sqlite3_open_v2("main.db", &db, openFlags, zVfs);
  1129   1128           if( rc ) fatalError("cannot open inmem database");
  1130         -#ifdef SQLITE_ENABLE_JSON1
  1131         -        {
  1132         -          extern int sqlite3_json_init(sqlite3*);
  1133         -          sqlite3_json_init(db);
  1134         -        }
  1135         -#endif
  1136   1129           if( cellSzCkFlag ) runSql(db, "PRAGMA cell_size_check=ON", runFlags);
  1137   1130           setAlarm(iTimeout);
  1138   1131   #ifndef SQLITE_OMIT_PROGRESS_CALLBACK
  1139   1132           if( sqlFuzz || vdbeLimitFlag ){
  1140   1133             sqlite3_progress_handler(db, 100000, progressHandler, &vdbeLimitFlag);
  1141   1134           }
  1142   1135   #endif

Changes to test/fuzzdata3.db.

cannot compute difference between binary files

Changes to test/indexexpr1.test.

    84     84   } {1 1 1}
    85     85   do_execsql_test indexexpr1-160eqp {
    86     86     EXPLAIN QUERY PLAN
    87     87     SELECT rowid, b, c FROM t1
    88     88      WHERE substr(a,27,3)=='ord' AND d>=29;
    89     89   } {/USING INDEX t1a2/}
    90     90   
           91  +# ORDER BY using an indexed expression
           92  +#
           93  +do_execsql_test indexexpr1-170 {
           94  +  CREATE INDEX t1alen ON t1(length(a));
           95  +  SELECT length(a) FROM t1 ORDER BY length(a);
           96  +} {20 25 27 29 38 52}
           97  +do_execsql_test indexexpr1-170eqp {
           98  +  EXPLAIN QUERY PLAN
           99  +  SELECT length(a) FROM t1 ORDER BY length(a);
          100  +} {/SCAN TABLE t1 USING INDEX t1alen/}
          101  +do_execsql_test indexexpr1-171 {
          102  +  SELECT length(a) FROM t1 ORDER BY length(a) DESC;
          103  +} {52 38 29 27 25 20}
          104  +do_execsql_test indexexpr1-171eqp {
          105  +  EXPLAIN QUERY PLAN
          106  +  SELECT length(a) FROM t1 ORDER BY length(a) DESC;
          107  +} {/SCAN TABLE t1 USING INDEX t1alen/}
    91    108   
    92    109   do_execsql_test indexexpr1-200 {
    93    110     DROP TABLE t1;
    94    111     CREATE TABLE t1(id ANY PRIMARY KEY, a,b,c) WITHOUT ROWID;
    95    112     INSERT INTO t1(id,a,b,c)
    96    113     VALUES(1,'In_the_beginning_was_the_Word',1,1),
    97    114           (2,'and_the_Word_was_with_God',1,2),
................................................................................
   189    206   do_execsql_test indexexpr1-400 {
   190    207     CREATE TABLE t3(a,b,c);
   191    208     WITH RECURSIVE c(x) AS (VALUES(1) UNION SELECT x+1 FROM c WHERE x<30)
   192    209     INSERT INTO t3(a,b,c)
   193    210       SELECT x, printf('ab%04xyz',x), random() FROM c;
   194    211     CREATE UNIQUE INDEX t3abc ON t3(CAST(a AS text), b, substr(c,1,3));
   195    212     SELECT a FROM t3 WHERE CAST(a AS text)<='10' ORDER BY +a;
   196         -} {1 10}
          213  +  PRAGMA integrity_check;
          214  +} {1 10 ok}
   197    215   do_catchsql_test indexexpr1-410 {
   198    216     INSERT INTO t3 SELECT * FROM t3 WHERE rowid=10;
   199    217   } {1 {UNIQUE constraint failed: index 't3abc'}}
   200    218   
   201    219   do_execsql_test indexexpr1-500 {
   202    220     CREATE TABLE t5(a);
   203    221     CREATE TABLE cnt(x);
................................................................................
   250    268     CREATE INDEX t72yz ON t72(y+z);
   251    269     INSERT INTO t71(a,b,c) VALUES(1,11,2),(2,7,15),(3,5,4);
   252    270     INSERT INTO t72(x,y,z) VALUES(1,10,3),(2,8,14),(3,9,9);
   253    271     SELECT a, x, '|' FROM t71, t72
   254    272      WHERE b+c=y+z
   255    273     ORDER BY +a, +x;
   256    274   } {1 1 | 2 2 |}
          275  +
          276  +# Collating sequences on indexes of expressions
          277  +#
          278  +do_execsql_test indexexpr1-800 {
          279  +  DROP TABLE IF EXISTS t8;
          280  +  CREATE TABLE t8(a INTEGER PRIMARY KEY, b TEXT);
          281  +  CREATE UNIQUE INDEX t8bx ON t8(substr(b,2,4) COLLATE nocase);
          282  +  INSERT INTO t8(a,b) VALUES(1,'Alice'),(2,'Bartholemew'),(3,'Cynthia');
          283  +  SELECT * FROM t8 WHERE substr(b,2,4)='ARTH' COLLATE nocase;
          284  +} {2 Bartholemew}
          285  +do_catchsql_test indexexpr1-810 {
          286  +  INSERT INTO t8(a,b) VALUES(4,'BARTHMERE');
          287  +} {1 {UNIQUE constraint failed: index 't8bx'}}
          288  +do_catchsql_test indexexpr1-820 {
          289  +  DROP INDEX t8bx;
          290  +  CREATE UNIQUE INDEX t8bx ON t8(substr(b,2,4) COLLATE rtrim);
          291  +  INSERT INTO t8(a,b) VALUES(4,'BARTHMERE');
          292  +} {0 {}}
          293  +
          294  +# Check that PRAGMA integrity_check works correctly on a
          295  +# UNIQUE index that includes rowid and expression terms.
          296  +#
          297  +do_execsql_test indexexpr1-900 {
          298  +  CREATE TABLE t9(a,b,c,d);
          299  +  CREATE UNIQUE INDEX t9x1 ON t9(c,abs(d),b);
          300  +  INSERT INTO t9(rowid,a,b,c,d) VALUES(1,2,3,4,5);
          301  +  INSERT INTO t9(rowid,a,b,c,d) VALUES(2,NULL,NULL,NULL,NULL);
          302  +  INSERT INTO t9(rowid,a,b,c,d) VALUES(3,NULL,NULL,NULL,NULL);
          303  +  INSERT INTO t9(rowid,a,b,c,d) VALUES(4,5,6,7,8);
          304  +  PRAGMA integrity_check;
          305  +} {ok}
          306  +do_catchsql_test indexexpr1-910 {
          307  +  INSERT INTO t9(a,b,c,d) VALUES(5,6,7,-8);
          308  +} {1 {UNIQUE constraint failed: index 't9x1'}}
          309  +
   257    310   
   258    311   finish_test

Changes to test/json101.test.

    11     11   # This file implements tests for JSON SQL functions extension to the
    12     12   # SQLite library.
    13     13   #
    14     14   
    15     15   set testdir [file dirname $argv0]
    16     16   source $testdir/tester.tcl
    17     17   
    18         -load_static_extension db json
           18  +ifcapable !json1 {
           19  +  finish_test
           20  +  return
           21  +}
           22  +
    19     23   do_execsql_test json101-1.1.00 {
    20     24     SELECT json_array(1,2.5,null,'hello');
    21     25   } {[1,2.5,null,"hello"]}
    22     26   do_execsql_test json101-1.1.01 {
    23     27     SELECT json_array(1,'{"abc":2.5,"def":null,"ghi":hello}',99);
    24     28     -- the second term goes in as a string:
    25     29   } {[1,"{\\"abc\\":2.5,\\"def\\":null,\\"ghi\\":hello}",99]}

Changes to test/json102.test.

    14     14   # This file contains tests automatically generated from the json1
    15     15   # documentation.
    16     16   #
    17     17   
    18     18   set testdir [file dirname $argv0]
    19     19   source $testdir/tester.tcl
    20     20   
    21         -load_static_extension db json
           21  +ifcapable !json1 {
           22  +  finish_test
           23  +  return
           24  +}
           25  +
    22     26   do_execsql_test json102-100 {
    23     27     SELECT json_object('ex','[52,3.14159]');
    24     28   } {{{"ex":"[52,3.14159]"}}}
    25     29   do_execsql_test json102-110 {
    26     30     SELECT json_object('ex',json('[52,3.14159]'));
    27     31   } {{{"ex":[52,3.14159]}}}
    28     32   do_execsql_test json102-120 {

Added test/offset1.test.

            1  +# 2015-10-06
            2  +#
            3  +# The author disclaims copyright to this source code.  In place of
            4  +# a legal notice, here is a blessing:
            5  +#
            6  +#    May you do good and not evil.
            7  +#    May you find forgiveness for yourself and forgive others.
            8  +#    May you share freely, never taking more than you give.
            9  +#
           10  +#***********************************************************************
           11  +# 
           12  +# This file implements test cases for the [b65cb2c8d91f6685841d7d1e13b6]
           13  +# bug:  Correct handling of LIMIT and OFFSET on a UNION ALL query where
           14  +# the right-hand SELECT contains an ORDER BY in a subquery.
           15  +#
           16  +
           17  +set testdir [file dirname $argv0]
           18  +source $testdir/tester.tcl
           19  +
           20  +ifcapable !compound {
           21  +  finish_test
           22  +  return
           23  +}
           24  +
           25  +do_execsql_test offset1-1.1 {
           26  +  CREATE TABLE t1(a,b);
           27  +  INSERT INTO t1 VALUES(1,'a'),(2,'b'),(3,'c'),(4,'d'),(5,'e');
           28  +  CREATE TABLE t2(x,y);
           29  +  INSERT INTO t2 VALUES(8,'y'),(9,'z'),(6,'w'),(7,'x');
           30  +  SELECT count(*) FROM t1, t2;
           31  +} {20}
           32  +
           33  +do_execsql_test offset1-1.2.0 {
           34  +  SELECT a, b FROM t1
           35  +  UNION ALL
           36  +  SELECT * FROM (SELECT x, y FROM t2 ORDER BY y)
           37  +  LIMIT 3 OFFSET 0;
           38  +} {1 a 2 b 3 c}
           39  +do_execsql_test offset1-1.2.1 {
           40  +  SELECT a, b FROM t1
           41  +  UNION ALL
           42  +  SELECT * FROM (SELECT x, y FROM t2 ORDER BY y)
           43  +  LIMIT 3 OFFSET 1;
           44  +} {2 b 3 c 4 d}
           45  +do_execsql_test offset1-1.2.2 {
           46  +  SELECT a, b FROM t1
           47  +  UNION ALL
           48  +  SELECT * FROM (SELECT x, y FROM t2 ORDER BY y)
           49  +  LIMIT 3 OFFSET 2;
           50  +} {3 c 4 d 5 e}
           51  +do_execsql_test offset1-1.2.3 {
           52  +  SELECT a, b FROM t1
           53  +  UNION ALL
           54  +  SELECT * FROM (SELECT x, y FROM t2 ORDER BY y)
           55  +  LIMIT 3 OFFSET 3;
           56  +} {4 d 5 e 6 w}
           57  +do_execsql_test offset1-1.2.4 {
           58  +  SELECT a, b FROM t1
           59  +  UNION ALL
           60  +  SELECT * FROM (SELECT x, y FROM t2 ORDER BY y)
           61  +  LIMIT 3 OFFSET 4;
           62  +} {5 e 6 w 7 x}
           63  +do_execsql_test offset1-1.2.5 {
           64  +  SELECT a, b FROM t1
           65  +  UNION ALL
           66  +  SELECT * FROM (SELECT x, y FROM t2 ORDER BY y)
           67  +  LIMIT 3 OFFSET 5;
           68  +} {6 w 7 x 8 y}
           69  +do_execsql_test offset1-1.2.6 {
           70  +  SELECT a, b FROM t1
           71  +  UNION ALL
           72  +  SELECT * FROM (SELECT x, y FROM t2 ORDER BY y)
           73  +  LIMIT 3 OFFSET 6;
           74  +} {7 x 8 y 9 z}
           75  +do_execsql_test offset1-1.2.7 {
           76  +  SELECT a, b FROM t1
           77  +  UNION ALL
           78  +  SELECT * FROM (SELECT x, y FROM t2 ORDER BY y)
           79  +  LIMIT 3 OFFSET 7;
           80  +} {8 y 9 z}
           81  +do_execsql_test offset1-1.2.8 {
           82  +  SELECT a, b FROM t1
           83  +  UNION ALL
           84  +  SELECT * FROM (SELECT x, y FROM t2 ORDER BY y)
           85  +  LIMIT 3 OFFSET 8;
           86  +} {9 z}
           87  +do_execsql_test offset1-1.2.9 {
           88  +  SELECT a, b FROM t1
           89  +  UNION ALL
           90  +  SELECT * FROM (SELECT x, y FROM t2 ORDER BY y)
           91  +  LIMIT 3 OFFSET 9;
           92  +} {}
           93  +
           94  +do_execsql_test offset1-1.3.0 {
           95  +  SELECT * FROM t1 LIMIT 0;
           96  +} {}
           97  +
           98  +do_execsql_test offset1-1.4.0 {
           99  +  SELECT a, b FROM t1
          100  +  UNION ALL
          101  +  SELECT * FROM (SELECT x, y FROM t2 ORDER BY y)
          102  +  LIMIT 0 OFFSET 1;
          103  +} {}
          104  +do_execsql_test offset1-1.4.1 {
          105  +  SELECT a, b FROM t1
          106  +  UNION ALL
          107  +  SELECT * FROM (SELECT x, y FROM t2 ORDER BY y)
          108  +  LIMIT 1 OFFSET 1;
          109  +} {2 b}
          110  +do_execsql_test offset1-1.4.2 {
          111  +  SELECT a, b FROM t1
          112  +  UNION ALL
          113  +  SELECT * FROM (SELECT x, y FROM t2 ORDER BY y)
          114  +  LIMIT 2 OFFSET 1;
          115  +} {2 b 3 c}
          116  +do_execsql_test offset1-1.4.3 {
          117  +  SELECT a, b FROM t1
          118  +  UNION ALL
          119  +  SELECT * FROM (SELECT x, y FROM t2 ORDER BY y)
          120  +  LIMIT 3 OFFSET 1;
          121  +} {2 b 3 c 4 d}
          122  +do_execsql_test offset1-1.4.4 {
          123  +  SELECT a, b FROM t1
          124  +  UNION ALL
          125  +  SELECT * FROM (SELECT x, y FROM t2 ORDER BY y)
          126  +  LIMIT 4 OFFSET 1;
          127  +} {2 b 3 c 4 d 5 e}
          128  +do_execsql_test offset1-1.4.5 {
          129  +  SELECT a, b FROM t1
          130  +  UNION ALL
          131  +  SELECT * FROM (SELECT x, y FROM t2 ORDER BY y)
          132  +  LIMIT 5 OFFSET 1;
          133  +} {2 b 3 c 4 d 5 e 6 w}
          134  +do_execsql_test offset1-1.4.6 {
          135  +  SELECT a, b FROM t1
          136  +  UNION ALL
          137  +  SELECT * FROM (SELECT x, y FROM t2 ORDER BY y)
          138  +  LIMIT 6 OFFSET 1;
          139  +} {2 b 3 c 4 d 5 e 6 w 7 x}
          140  +do_execsql_test offset1-1.4.7 {
          141  +  SELECT a, b FROM t1
          142  +  UNION ALL
          143  +  SELECT * FROM (SELECT x, y FROM t2 ORDER BY y)
          144  +  LIMIT 7 OFFSET 1;
          145  +} {2 b 3 c 4 d 5 e 6 w 7 x 8 y}
          146  +do_execsql_test offset1-1.4.8 {
          147  +  SELECT a, b FROM t1
          148  +  UNION ALL
          149  +  SELECT * FROM (SELECT x, y FROM t2 ORDER BY y)
          150  +  LIMIT 8 OFFSET 1;
          151  +} {2 b 3 c 4 d 5 e 6 w 7 x 8 y 9 z}
          152  +do_execsql_test offset1-1.4.9 {
          153  +  SELECT a, b FROM t1
          154  +  UNION ALL
          155  +  SELECT * FROM (SELECT x, y FROM t2 ORDER BY y)
          156  +  LIMIT 9 OFFSET 1;
          157  +} {2 b 3 c 4 d 5 e 6 w 7 x 8 y 9 z}
          158  +
          159  +
          160  +
          161  +finish_test

Changes to test/releasetest.tcl.

    74     74       -DSQLITE_SOUNDEX=1
    75     75     }
    76     76     "Update-Delete-Limit" {
    77     77       -O2
    78     78       -DSQLITE_DEFAULT_FILE_FORMAT=4
    79     79       -DSQLITE_ENABLE_UPDATE_DELETE_LIMIT=1
    80     80       -DSQLITE_ENABLE_STMT_SCANSTATUS
           81  +    --enable-json1
    81     82     }
    82     83     "Check-Symbols" {
    83     84       -DSQLITE_MEMDEBUG=1
    84     85       -DSQLITE_ENABLE_FTS3_PARENTHESIS=1
    85     86       -DSQLITE_ENABLE_FTS3=1
    86     87       -DSQLITE_ENABLE_RTREE=1
    87     88       -DSQLITE_ENABLE_MEMSYS5=1
................................................................................
    91     92       -DSQLITE_SECURE_DELETE=1
    92     93       -DSQLITE_SOUNDEX=1
    93     94       -DSQLITE_ENABLE_ATOMIC_WRITE=1
    94     95       -DSQLITE_ENABLE_MEMORY_MANAGEMENT=1
    95     96       -DSQLITE_ENABLE_OVERSIZE_CELL_CHECK=1
    96     97       -DSQLITE_ENABLE_STAT4
    97     98       -DSQLITE_ENABLE_STMT_SCANSTATUS
           99  +    --enable-json1 --enable-fts5
    98    100     }
    99    101     "Debug-One" {
   100    102       --disable-shared
   101    103       -O2
   102    104       -DSQLITE_DEBUG=1
   103    105       -DSQLITE_MEMDEBUG=1
   104    106       -DSQLITE_MUTEX_NOOP=1
................................................................................
   131    133       -DSQLITE_ENABLE_IOTRACE=1
   132    134       -DSQLITE_ENABLE_MEMORY_MANAGEMENT=1
   133    135       -DSQLITE_MAX_PAGE_SIZE=4096
   134    136       -DSQLITE_OMIT_LOAD_EXTENSION=1
   135    137       -DSQLITE_OMIT_PROGRESS_CALLBACK=1
   136    138       -DSQLITE_OMIT_VIRTUALTABLE=1
   137    139       -DSQLITE_TEMP_STORE=3
          140  +    --enable-json1
   138    141     }
   139    142     "Device-Two" {
   140    143       -DSQLITE_4_BYTE_ALIGNED_MALLOC=1
   141    144       -DSQLITE_DEFAULT_AUTOVACUUM=1
   142    145       -DSQLITE_DEFAULT_CACHE_SIZE=1000
   143    146       -DSQLITE_DEFAULT_LOCKING_MODE=0
   144    147       -DSQLITE_DEFAULT_PAGE_SIZE=1024
................................................................................
   148    151       -DSQLITE_ENABLE_MEMORY_MANAGEMENT=1
   149    152       -DSQLITE_ENABLE_RTREE=1
   150    153       -DSQLITE_MAX_COMPOUND_SELECT=50
   151    154       -DSQLITE_MAX_PAGE_SIZE=32768
   152    155       -DSQLITE_OMIT_TRACE=1
   153    156       -DSQLITE_TEMP_STORE=3
   154    157       -DSQLITE_THREADSAFE=2
          158  +    --enable-json1 --enable-fts5
   155    159     }
   156    160     "Locking-Style" {
   157    161       -O2
   158    162       -DSQLITE_ENABLE_LOCKING_STYLE=1
   159    163     }
   160    164     "OS-X" {
   161    165       -O1   # Avoid a compiler bug in gcc 4.2.1 build 5658
   162    166       -DSQLITE_OMIT_LOAD_EXTENSION=1
   163    167       -DSQLITE_DEFAULT_MEMSTATUS=0
   164    168       -DSQLITE_THREADSAFE=2
   165    169       -DSQLITE_OS_UNIX=1
          170  +    -DSQLITE_ENABLE_JSON1=1
   166    171       -DSQLITE_ENABLE_LOCKING_STYLE=1
   167    172       -DUSE_PREAD=1
   168    173       -DSQLITE_ENABLE_RTREE=1
   169    174       -DSQLITE_ENABLE_FTS3=1
   170    175       -DSQLITE_ENABLE_FTS3_PARENTHESIS=1
   171    176       -DSQLITE_DEFAULT_CACHE_SIZE=1000
   172    177       -DSQLITE_MAX_LENGTH=2147483645
   173    178       -DSQLITE_MAX_VARIABLE_NUMBER=500000
   174    179       -DSQLITE_DEBUG=1
   175    180       -DSQLITE_PREFER_PROXY_LOCKING=1
   176    181       -DSQLITE_ENABLE_API_ARMOR=1
          182  +    --enable-json1 --enable-fts5
   177    183     }
   178    184     "Extra-Robustness" {
   179    185       -DSQLITE_ENABLE_OVERSIZE_CELL_CHECK=1
   180    186       -DSQLITE_MAX_ATTACHED=62
   181    187     }
   182    188     "Devkit" {
   183    189       -DSQLITE_DEFAULT_FILE_FORMAT=4
   184    190       -DSQLITE_MAX_ATTACHED=30
   185    191       -DSQLITE_ENABLE_COLUMN_METADATA
   186    192       -DSQLITE_ENABLE_FTS4
   187    193       -DSQLITE_ENABLE_FTS4_PARENTHESIS
   188    194       -DSQLITE_DISABLE_FTS4_DEFERRED
   189    195       -DSQLITE_ENABLE_RTREE
          196  +    --enable-json1 --enable-fts5
   190    197     }
   191    198     "No-lookaside" {
   192    199       -DSQLITE_TEST_REALLOC_STRESS=1
   193    200       -DSQLITE_OMIT_LOOKASIDE=1
   194    201       -DHAVE_USLEEP=1
   195    202     }
   196    203     "Valgrind" {
   197    204       -DSQLITE_ENABLE_STAT4
   198    205       -DSQLITE_ENABLE_FTS4
   199    206       -DSQLITE_ENABLE_RTREE
          207  +    --enable-json1
   200    208     }
   201    209   
   202    210     # The next group of configurations are used only by the
   203    211     # Failure-Detection platform.  They are all the same, but we need
   204    212     # different names for them all so that they results appear in separate
   205    213     # subdirectories.
   206    214     #

Changes to test/spellfix2.test.

    72     72     WHERE word MATCH 'amstedam*' AND distance <= 100 AND top=20;
    73     73   } {
    74     74     32 20
    75     75   }
    76     76   
    77     77   do_execsql_test 1.6 {
    78     78     SELECT word, distance, matchlen FROM demo 
    79         -  WHERE word MATCH 'amstedam*' AND distance <= 100;
           79  +  WHERE word MATCH 'amstedam*' AND distance <= 100
           80  +  ORDER BY distance, word;
    80     81   } {
    81         -  amsterdam         100 9        amsterdamh        100 9
    82         -  amsterdamm        100 9        amsterdamn        100 9
    83         -  amsterdama        100 9        amsterdame        100 9
    84         -  amsterdami        100 9        amsterdamo        100 9
    85         -  amsterdamu        100 9        amsterdamy        100 9
    86         -  amsterdammetje    100 9        amsterdamania     100 9
    87         -  amsterdamb        100 9        amsterdamf        100 9
    88         -  amsterdamp        100 9        amsterdamv        100 9
    89         -  amsterdamw        100 9        amsterdamweg      100 9
    90         -  amsterdamc        100 9        amsterdamg        100 9
    91         -  amsterdamj        100 9        amsterdamk        100 9
    92         -  amsterdamq        100 9        amsterdams        100 9
    93         -  amsterdamx        100 9        amsterdamz        100 9
    94         -  amsterdamsestraat 100 9        amsterdamd        100 9
    95         -  amsterdamt        100 9        amsterdaml        100 9
    96         -  amsterdamlaan     100 9        amsterdamr        100 9
           82  +  amsterdam         100 9        amsterdama        100 9
           83  +  amsterdamania     100 9        amsterdamb        100 9
           84  +  amsterdamc        100 9        amsterdamd        100 9
           85  +  amsterdame        100 9        amsterdamf        100 9
           86  +  amsterdamg        100 9        amsterdamh        100 9
           87  +  amsterdami        100 9        amsterdamj        100 9
           88  +  amsterdamk        100 9        amsterdaml        100 9
           89  +  amsterdamlaan     100 9        amsterdamm        100 9
           90  +  amsterdammetje    100 9        amsterdamn        100 9
           91  +  amsterdamo        100 9        amsterdamp        100 9
           92  +  amsterdamq        100 9        amsterdamr        100 9
           93  +  amsterdams        100 9        amsterdamsestraat 100 9
           94  +  amsterdamt        100 9        amsterdamu        100 9
           95  +  amsterdamv        100 9        amsterdamw        100 9
           96  +  amsterdamweg      100 9        amsterdamx        100 9
           97  +  amsterdamy        100 9        amsterdamz        100 9
    97     98   }
    98     99   
    99    100   do_execsql_test 1.7 {
   100    101     SELECT word, distance, matchlen FROM demo 
   101         -  WHERE word MATCH 'amstedam*' AND distance <= 100 AND top=20;
          102  +  WHERE word MATCH 'amstedam*' AND distance <= 100 AND top=20
          103  +  ORDER BY distance, word;
   102    104   } {
   103         -  amsterdam         100 9        amsterdamh        100 9
   104         -  amsterdamm        100 9        amsterdamn        100 9
   105         -  amsterdama        100 9        amsterdame        100 9
   106         -  amsterdami        100 9        amsterdamo        100 9
   107         -  amsterdamu        100 9        amsterdamy        100 9
   108         -  amsterdammetje    100 9        amsterdamania     100 9
   109         -