/ Check-in [2ac72114]
Login

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

Overview
Comment:Merge latest trunk changes into this branch.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | reuse-schema
Files: files | file ages | folders
SHA3-256: 2ac72114a1f5344b42472b941c60f460c28c981a22ea40909b30f7bf4eb4b11b
User & Date: dan 2018-10-08 18:58:51
Wiki:reuse-schema
Context
2018-10-08
20:37
Merge fixes from trunk. check-in: 9c8255a1 user: drh tags: reuse-schema
18:58
Merge latest trunk changes into this branch. check-in: 2ac72114 user: dan tags: reuse-schema
12:58
Add the geopoly_reverse() function to the GeoPoly extension. check-in: 690dd18a user: drh tags: trunk
2017-08-09
20:35
Add experimental sqlite3_open_v2() flag SQLITE_OPEN_REUSE_SCHEMA. For sharing identical in-memory schema objects between connections. check-in: a6256980 user: dan tags: reuse-schema
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Added .fossil-settings/empty-dirs.

            1  +compat

Added .fossil-settings/ignore-glob.

            1  +compat/*

Changes to Makefile.in.

    84     84   OPT_FEATURE_FLAGS = @OPT_FEATURE_FLAGS@
    85     85   
    86     86   TCC += $(OPT_FEATURE_FLAGS)
    87     87   
    88     88   # Add in any optional parameters specified on the make commane line
    89     89   # ie.  make "OPTS=-DSQLITE_ENABLE_FOO=1 -DSQLITE_OMIT_FOO=1".
    90     90   TCC += $(OPTS)
           91  +
           92  +# Add in compile-time options for some libraries used by extensions
           93  +TCC += @HAVE_ZLIB@
    91     94   
    92     95   # Version numbers and release number for the SQLite being compiled.
    93     96   #
    94     97   VERSION = @VERSION@
    95     98   VERSION_NUMBER = @VERSION_NUMBER@
    96     99   RELEASE = @RELEASE@
    97    100   
................................................................................
   162    165   
   163    166   USE_AMALGAMATION = @USE_AMALGAMATION@
   164    167   
   165    168   # Object files for the SQLite library (non-amalgamation).
   166    169   #
   167    170   LIBOBJS0 = alter.lo analyze.lo attach.lo auth.lo \
   168    171            backup.lo bitvec.lo btmutex.lo btree.lo build.lo \
   169         -         callback.lo complete.lo ctime.lo date.lo dbstat.lo delete.lo \
          172  +         callback.lo complete.lo ctime.lo \
          173  +         date.lo dbpage.lo dbstat.lo delete.lo \
   170    174            expr.lo fault.lo fkey.lo \
   171    175            fts3.lo fts3_aux.lo fts3_expr.lo fts3_hash.lo fts3_icu.lo \
   172    176            fts3_porter.lo fts3_snippet.lo fts3_tokenizer.lo fts3_tokenizer1.lo \
   173    177            fts3_tokenize_vtab.lo \
   174    178            fts3_unicode.lo fts3_unicode2.lo fts3_write.lo \
   175    179   	 fts5.lo \
   176    180            func.lo global.lo hash.lo \
   177    181            icu.lo insert.lo json1.lo legacy.lo loadext.lo \
   178    182            main.lo malloc.lo mem0.lo mem1.lo mem2.lo mem3.lo mem5.lo \
   179         -         memjournal.lo \
          183  +         memdb.lo memjournal.lo \
   180    184            mutex.lo mutex_noop.lo mutex_unix.lo mutex_w32.lo \
   181    185            notify.lo opcodes.lo os.lo os_unix.lo os_win.lo \
   182    186            pager.lo parse.lo pcache.lo pcache1.lo pragma.lo prepare.lo printf.lo \
   183    187            random.lo resolve.lo rowset.lo rtree.lo \
   184    188            sqlite3session.lo select.lo sqlite3rbu.lo status.lo stmt.lo \
   185    189            table.lo threads.lo tokenize.lo treeview.lo trigger.lo \
   186         -         update.lo util.lo vacuum.lo \
          190  +         update.lo upsert.lo util.lo vacuum.lo \
   187    191            vdbe.lo vdbeapi.lo vdbeaux.lo vdbeblob.lo vdbemem.lo vdbesort.lo \
   188    192            vdbetrace.lo wal.lo walker.lo where.lo wherecode.lo whereexpr.lo \
   189         -         utf.lo vtab.lo
          193  +         window.lo utf.lo vtab.lo
   190    194   
   191    195   # Object files for the amalgamation.
   192    196   #
   193    197   LIBOBJS1 = sqlite3.lo
   194    198   
   195    199   # Determine the real value of LIBOBJ based on the 'configure' script
   196    200   #
................................................................................
   211    215     $(TOP)/src/btree.h \
   212    216     $(TOP)/src/btreeInt.h \
   213    217     $(TOP)/src/build.c \
   214    218     $(TOP)/src/callback.c \
   215    219     $(TOP)/src/complete.c \
   216    220     $(TOP)/src/ctime.c \
   217    221     $(TOP)/src/date.c \
          222  +  $(TOP)/src/dbpage.c \
   218    223     $(TOP)/src/dbstat.c \
   219    224     $(TOP)/src/delete.c \
   220    225     $(TOP)/src/expr.c \
   221    226     $(TOP)/src/fault.c \
   222    227     $(TOP)/src/fkey.c \
   223    228     $(TOP)/src/func.c \
   224    229     $(TOP)/src/global.c \
................................................................................
   231    236     $(TOP)/src/main.c \
   232    237     $(TOP)/src/malloc.c \
   233    238     $(TOP)/src/mem0.c \
   234    239     $(TOP)/src/mem1.c \
   235    240     $(TOP)/src/mem2.c \
   236    241     $(TOP)/src/mem3.c \
   237    242     $(TOP)/src/mem5.c \
          243  +  $(TOP)/src/memdb.c \
   238    244     $(TOP)/src/memjournal.c \
   239    245     $(TOP)/src/msvc.h \
   240    246     $(TOP)/src/mutex.c \
   241    247     $(TOP)/src/mutex.h \
   242    248     $(TOP)/src/mutex_noop.c \
   243    249     $(TOP)/src/mutex_unix.c \
   244    250     $(TOP)/src/mutex_w32.c \
................................................................................
   261    267     $(TOP)/src/prepare.c \
   262    268     $(TOP)/src/printf.c \
   263    269     $(TOP)/src/random.c \
   264    270     $(TOP)/src/resolve.c \
   265    271     $(TOP)/src/rowset.c \
   266    272     $(TOP)/src/select.c \
   267    273     $(TOP)/src/status.c \
   268         -  $(TOP)/src/shell.c \
          274  +  $(TOP)/src/shell.c.in \
   269    275     $(TOP)/src/sqlite.h.in \
   270    276     $(TOP)/src/sqlite3ext.h \
   271    277     $(TOP)/src/sqliteInt.h \
   272    278     $(TOP)/src/sqliteLimit.h \
   273    279     $(TOP)/src/table.c \
   274    280     $(TOP)/src/tclsqlite.c \
   275    281     $(TOP)/src/threads.c \
   276    282     $(TOP)/src/tokenize.c \
   277    283     $(TOP)/src/treeview.c \
   278    284     $(TOP)/src/trigger.c \
   279    285     $(TOP)/src/utf.c \
   280    286     $(TOP)/src/update.c \
          287  +  $(TOP)/src/upsert.c \
   281    288     $(TOP)/src/util.c \
   282    289     $(TOP)/src/vacuum.c \
   283    290     $(TOP)/src/vdbe.c \
   284    291     $(TOP)/src/vdbe.h \
   285    292     $(TOP)/src/vdbeapi.c \
   286    293     $(TOP)/src/vdbeaux.c \
   287    294     $(TOP)/src/vdbeblob.c \
................................................................................
   293    300     $(TOP)/src/vxworks.h \
   294    301     $(TOP)/src/wal.c \
   295    302     $(TOP)/src/wal.h \
   296    303     $(TOP)/src/walker.c \
   297    304     $(TOP)/src/where.c \
   298    305     $(TOP)/src/wherecode.c \
   299    306     $(TOP)/src/whereexpr.c \
   300         -  $(TOP)/src/whereInt.h
          307  +  $(TOP)/src/whereInt.h \
          308  +  $(TOP)/src/window.c
   301    309   
   302    310   # Source code for extensions
   303    311   #
   304    312   SRC += \
   305    313     $(TOP)/ext/fts1/fts1.c \
   306    314     $(TOP)/ext/fts1/fts1.h \
   307    315     $(TOP)/ext/fts1/fts1_hash.c \
................................................................................
   338    346     $(TOP)/ext/fts3/fts3_unicode2.c \
   339    347     $(TOP)/ext/fts3/fts3_write.c
   340    348   SRC += \
   341    349     $(TOP)/ext/icu/sqliteicu.h \
   342    350     $(TOP)/ext/icu/icu.c
   343    351   SRC += \
   344    352     $(TOP)/ext/rtree/rtree.h \
   345         -  $(TOP)/ext/rtree/rtree.c
          353  +  $(TOP)/ext/rtree/rtree.c \
          354  +  $(TOP)/ext/rtree/geopoly.c
   346    355   SRC += \
   347    356     $(TOP)/ext/session/sqlite3session.c \
   348    357     $(TOP)/ext/session/sqlite3session.h
   349    358   SRC += \
   350    359     $(TOP)/ext/rbu/sqlite3rbu.h \
   351    360     $(TOP)/ext/rbu/sqlite3rbu.c
   352    361   SRC += \
................................................................................
   358    367   SRC += \
   359    368     keywordhash.h \
   360    369     opcodes.c \
   361    370     opcodes.h \
   362    371     parse.c \
   363    372     parse.h \
   364    373     config.h \
          374  +  shell.c \
   365    375     sqlite3.h
   366    376   
   367    377   # Source code to the test files.
   368    378   #
   369    379   TESTSRC = \
   370    380     $(TOP)/src/test1.c \
   371    381     $(TOP)/src/test2.c \
................................................................................
   389    399     $(TOP)/src/test_fs.c \
   390    400     $(TOP)/src/test_func.c \
   391    401     $(TOP)/src/test_hexio.c \
   392    402     $(TOP)/src/test_init.c \
   393    403     $(TOP)/src/test_intarray.c \
   394    404     $(TOP)/src/test_journal.c \
   395    405     $(TOP)/src/test_malloc.c \
          406  +  $(TOP)/src/test_md5.c \
   396    407     $(TOP)/src/test_multiplex.c \
   397    408     $(TOP)/src/test_mutex.c \
   398    409     $(TOP)/src/test_onefile.c \
   399    410     $(TOP)/src/test_osinst.c \
   400    411     $(TOP)/src/test_pcache.c \
   401    412     $(TOP)/src/test_quota.c \
   402    413     $(TOP)/src/test_rtree.c \
   403    414     $(TOP)/src/test_schema.c \
   404    415     $(TOP)/src/test_server.c \
   405    416     $(TOP)/src/test_superlock.c \
   406    417     $(TOP)/src/test_syscall.c \
          418  +  $(TOP)/src/test_tclsh.c \
   407    419     $(TOP)/src/test_tclvar.c \
   408    420     $(TOP)/src/test_thread.c \
   409    421     $(TOP)/src/test_vfs.c \
   410    422     $(TOP)/src/test_windirent.c \
          423  +  $(TOP)/src/test_window.c \
   411    424     $(TOP)/src/test_wsd.c       \
   412    425     $(TOP)/ext/fts3/fts3_term.c \
   413    426     $(TOP)/ext/fts3/fts3_test.c  \
   414    427     $(TOP)/ext/session/test_session.c \
   415    428     $(TOP)/ext/rbu/test_rbu.c 
   416    429   
   417    430   # Statically linked extensions
   418    431   #
   419    432   TESTSRC += \
          433  +  $(TOP)/ext/expert/sqlite3expert.c \
          434  +  $(TOP)/ext/expert/test_expert.c \
   420    435     $(TOP)/ext/misc/amatch.c \
   421    436     $(TOP)/ext/misc/carray.c \
   422    437     $(TOP)/ext/misc/closure.c \
   423    438     $(TOP)/ext/misc/csv.c \
   424    439     $(TOP)/ext/misc/eval.c \
          440  +  $(TOP)/ext/misc/explain.c \
   425    441     $(TOP)/ext/misc/fileio.c \
   426    442     $(TOP)/ext/misc/fuzzer.c \
   427    443     $(TOP)/ext/fts5/fts5_tcl.c \
   428    444     $(TOP)/ext/fts5/fts5_test_mi.c \
   429    445     $(TOP)/ext/fts5/fts5_test_tok.c \
   430    446     $(TOP)/ext/misc/ieee754.c \
          447  +  $(TOP)/ext/misc/mmapwarm.c \
   431    448     $(TOP)/ext/misc/nextchar.c \
          449  +  $(TOP)/ext/misc/normalize.c \
   432    450     $(TOP)/ext/misc/percentile.c \
   433    451     $(TOP)/ext/misc/regexp.c \
   434    452     $(TOP)/ext/misc/remember.c \
   435    453     $(TOP)/ext/misc/series.c \
   436    454     $(TOP)/ext/misc/spellfix.c \
   437    455     $(TOP)/ext/misc/totype.c \
   438    456     $(TOP)/ext/misc/unionvtab.c \
   439         -  $(TOP)/ext/misc/wholenumber.c
          457  +  $(TOP)/ext/misc/wholenumber.c \
          458  +  $(TOP)/ext/misc/zipfile.c
   440    459   
   441    460   # Source code to the library files needed by the test fixture
   442    461   #
   443    462   TESTSRC2 = \
   444    463     $(TOP)/src/attach.c \
   445    464     $(TOP)/src/backup.c \
   446    465     $(TOP)/src/bitvec.c \
   447    466     $(TOP)/src/btree.c \
   448    467     $(TOP)/src/build.c \
   449    468     $(TOP)/src/ctime.c \
   450    469     $(TOP)/src/date.c \
          470  +  $(TOP)/src/dbpage.c \
   451    471     $(TOP)/src/dbstat.c \
   452    472     $(TOP)/src/expr.c \
   453    473     $(TOP)/src/func.c \
   454    474     $(TOP)/src/insert.c \
   455    475     $(TOP)/src/wal.c \
   456    476     $(TOP)/src/main.c \
   457    477     $(TOP)/src/mem5.c \
................................................................................
   473    493     $(TOP)/src/vdbeaux.c \
   474    494     $(TOP)/src/vdbe.c \
   475    495     $(TOP)/src/vdbemem.c \
   476    496     $(TOP)/src/vdbetrace.c \
   477    497     $(TOP)/src/where.c \
   478    498     $(TOP)/src/wherecode.c \
   479    499     $(TOP)/src/whereexpr.c \
          500  +  $(TOP)/src/window.c \
   480    501     parse.c \
   481    502     $(TOP)/ext/fts3/fts3.c \
   482    503     $(TOP)/ext/fts3/fts3_aux.c \
   483    504     $(TOP)/ext/fts3/fts3_expr.c \
   484    505     $(TOP)/ext/fts3/fts3_term.c \
   485    506     $(TOP)/ext/fts3/fts3_tokenizer.c \
   486    507     $(TOP)/ext/fts3/fts3_write.c \
................................................................................
   529    550     $(TOP)/ext/fts2/fts2_tokenizer.h
   530    551   EXTHDR += \
   531    552     $(TOP)/ext/fts3/fts3.h \
   532    553     $(TOP)/ext/fts3/fts3Int.h \
   533    554     $(TOP)/ext/fts3/fts3_hash.h \
   534    555     $(TOP)/ext/fts3/fts3_tokenizer.h
   535    556   EXTHDR += \
   536         -  $(TOP)/ext/rtree/rtree.h
          557  +  $(TOP)/ext/rtree/rtree.h \
          558  +  $(TOP)/ext/rtree/geopoly.c
   537    559   EXTHDR += \
   538    560     $(TOP)/ext/icu/sqliteicu.h
   539    561   EXTHDR += \
   540    562     $(TOP)/ext/rtree/sqlite3rtree.h
   541    563   
   542    564   # executables needed for testing
   543    565   #
   544    566   TESTPROGS = \
   545    567     testfixture$(TEXE) \
   546    568     sqlite3$(TEXE) \
   547    569     sqlite3_analyzer$(TEXE) \
   548    570     sqldiff$(TEXE) \
   549         -  dbhash$(TEXE)
          571  +  dbhash$(TEXE) \
          572  +  sqltclsh$(TEXE)
   550    573   
   551    574   # Databases containing fuzzer test cases
   552    575   #
   553    576   FUZZDATA = \
   554    577     $(TOP)/test/fuzzdata1.db \
   555    578     $(TOP)/test/fuzzdata2.db \
   556    579     $(TOP)/test/fuzzdata3.db \
   557    580     $(TOP)/test/fuzzdata4.db \
   558         -  $(TOP)/test/fuzzdata5.db
          581  +  $(TOP)/test/fuzzdata5.db \
          582  +  $(TOP)/test/fuzzdata6.db
   559    583   
   560    584   # Standard options to testfixture
   561    585   #
   562    586   TESTOPTS = --verbose=file --output=test-out.txt
   563    587   
   564    588   # Extra compiler options for various shell tools
   565    589   #
   566    590   SHELL_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS4
   567         -# SHELL_OPT += -DSQLITE_ENABLE_FTS5
          591  +#SHELL_OPT += -DSQLITE_ENABLE_FTS5
          592  +SHELL_OPT += -DSQLITE_ENABLE_RTREE
   568    593   SHELL_OPT += -DSQLITE_ENABLE_EXPLAIN_COMMENTS
   569    594   SHELL_OPT += -DSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
   570    595   SHELL_OPT += -DSQLITE_ENABLE_STMTVTAB
          596  +SHELL_OPT += -DSQLITE_ENABLE_DBPAGE_VTAB
          597  +SHELL_OPT += -DSQLITE_ENABLE_DBSTAT_VTAB
          598  +SHELL_OPT += -DSQLITE_ENABLE_OFFSET_SQL_FUNC
          599  +SHELL_OPT += -DSQLITE_INTROSPECTION_PRAGMAS
   571    600   FUZZERSHELL_OPT = -DSQLITE_ENABLE_JSON1
   572    601   FUZZCHECK_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5 -DSQLITE_OSS_FUZZ
   573    602   FUZZCHECK_OPT += -DSQLITE_MAX_MEMORY=50000000
          603  +FUZZCHECK_OPT += -DSQLITE_PRINTF_PRECISION_LIMIT=1000
   574    604   FUZZCHECK_SRC = $(TOP)/test/fuzzcheck.c $(TOP)/test/ossfuzz.c
   575    605   DBFUZZ_OPT = 
   576    606   
   577    607   # This is the default Makefile target.  The objects listed here
   578    608   # are what get build when you type just "make" with no arguments.
   579    609   #
   580    610   all:	sqlite3.h libsqlite3.la sqlite3$(TEXE) $(HAVE_TCL:1=libtclsqlite3.la)
................................................................................
   592    622   libtclsqlite3.la:	tclsqlite.lo libsqlite3.la
   593    623   	$(LTLINK) -no-undefined -o $@ tclsqlite.lo \
   594    624   		libsqlite3.la @TCL_STUB_LIB_SPEC@ $(TLIBS) \
   595    625   		-rpath "$(TCLLIBDIR)" \
   596    626   		-version-info "8:6:8" \
   597    627   		-avoid-version
   598    628   
   599         -sqlite3$(TEXE):	$(TOP)/src/shell.c sqlite3.c
          629  +sqlite3$(TEXE):	shell.c sqlite3.c
   600    630   	$(LTLINK) $(READLINE_FLAGS) $(SHELL_OPT) -o $@ \
   601         -		$(TOP)/src/shell.c sqlite3.c \
          631  +		shell.c sqlite3.c \
   602    632   		$(LIBREADLINE) $(TLIBS) -rpath "$(libdir)"
   603    633   
   604    634   sqldiff$(TEXE):	$(TOP)/tool/sqldiff.c sqlite3.lo sqlite3.h
   605    635   	$(LTLINK) -o $@ $(TOP)/tool/sqldiff.c sqlite3.lo $(TLIBS)
   606    636   
   607    637   dbhash$(TEXE):	$(TOP)/tool/dbhash.c sqlite3.lo sqlite3.h
   608    638   	$(LTLINK) -o $@ $(TOP)/tool/dbhash.c sqlite3.lo $(TLIBS)
................................................................................
   623    653   
   624    654   fuzzcheck$(TEXE):	$(FUZZCHECK_SRC) sqlite3.c sqlite3.h
   625    655   	$(LTLINK) -o $@ $(FUZZCHECK_OPT) $(FUZZCHECK_SRC) sqlite3.c $(TLIBS)
   626    656   
   627    657   ossshell$(TEXE):	$(TOP)/test/ossfuzz.c $(TOP)/test/ossshell.c sqlite3.c sqlite3.h
   628    658   	$(LTLINK) -o $@ $(FUZZCHECK_OPT) $(TOP)/test/ossshell.c \
   629    659                $(TOP)/test/ossfuzz.c sqlite3.c $(TLIBS)
          660  +
          661  +sessionfuzz$(TEXE):	$(TOP)/test/sessionfuzz.c sqlite3.c sqlite3.h
          662  +	$(CC) $(CFLAGS) -I. -o $@ $(TOP)/test/sessionfuzz.c $(TLIBS)
   630    663   
   631    664   dbfuzz$(TEXE):	$(TOP)/test/dbfuzz.c sqlite3.c sqlite3.h
   632    665   	$(LTLINK) -o $@ $(DBFUZZ_OPT) $(TOP)/test/dbfuzz.c sqlite3.c $(TLIBS)
   633    666   
   634    667   mptester$(TEXE):	sqlite3.lo $(TOP)/mptest/mptest.c
   635    668   	$(LTLINK) -o $@ -I. $(TOP)/mptest/mptest.c sqlite3.lo \
   636    669   		$(TLIBS) -rpath "$(libdir)"
................................................................................
   663    696   	$(TCLSH_CMD) $(TOP)/tool/vdbe-compress.tcl $(OPTS) <tsrc/vdbe.c >vdbe.new
   664    697   	mv vdbe.new tsrc/vdbe.c
   665    698   	cp fts5.c fts5.h tsrc
   666    699   	touch .target_source
   667    700   
   668    701   sqlite3.c:	.target_source $(TOP)/tool/mksqlite3c.tcl
   669    702   	$(TCLSH_CMD) $(TOP)/tool/mksqlite3c.tcl
   670         -	cp tsrc/shell.c tsrc/sqlite3ext.h .
          703  +	cp tsrc/sqlite3ext.h .
   671    704   	cp $(TOP)/ext/session/sqlite3session.h .
   672    705   
   673    706   sqlite3ext.h:	.target_source
   674    707   	cp tsrc/sqlite3ext.h .
   675    708   
   676    709   tclsqlite3.c:	sqlite3.c
   677    710   	echo '#ifndef USE_SYSTEM_SQLITE' >tclsqlite3.c
................................................................................
   688    721   	$(LTCOMPILE) $(TEMP_STORE) -c sqlite3.c
   689    722   
   690    723   # Rules to build the LEMON compiler generator
   691    724   #
   692    725   lemon$(BEXE):	$(TOP)/tool/lemon.c $(TOP)/tool/lempar.c
   693    726   	$(BCC) -o $@ $(TOP)/tool/lemon.c
   694    727   	cp $(TOP)/tool/lempar.c .
          728  +
          729  +# Rules to build the program that generates the source-id
          730  +#
          731  +mksourceid$(BEXE):	$(TOP)/tool/mksourceid.c
          732  +	$(BCC) -o $@ $(TOP)/tool/mksourceid.c
   695    733   
   696    734   # Rules to build individual *.o files from generated *.c files. This
   697    735   # applies to:
   698    736   #
   699    737   #     parse.o
   700    738   #     opcodes.o
   701    739   #
................................................................................
   742    780   
   743    781   ctime.lo:	$(TOP)/src/ctime.c $(HDR)
   744    782   	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/ctime.c
   745    783   
   746    784   date.lo:	$(TOP)/src/date.c $(HDR)
   747    785   	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/date.c
   748    786   
          787  +dbpage.lo:	$(TOP)/src/dbpage.c $(HDR)
          788  +	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/dbpage.c
          789  +
   749    790   dbstat.lo:	$(TOP)/src/dbstat.c $(HDR)
   750    791   	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/dbstat.c
   751    792   
   752    793   delete.lo:	$(TOP)/src/delete.c $(HDR)
   753    794   	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/delete.c
   754    795   
   755    796   expr.lo:	$(TOP)/src/expr.c $(HDR)
................................................................................
   796    837   
   797    838   mem3.lo:	$(TOP)/src/mem3.c $(HDR)
   798    839   	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mem3.c
   799    840   
   800    841   mem5.lo:	$(TOP)/src/mem5.c $(HDR)
   801    842   	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mem5.c
   802    843   
          844  +memdb.lo:	$(TOP)/src/memdb.c $(HDR)
          845  +	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/memdb.c
          846  +
   803    847   memjournal.lo:	$(TOP)/src/memjournal.c $(HDR)
   804    848   	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/memjournal.c
   805    849   
   806    850   mutex.lo:	$(TOP)/src/mutex.c $(HDR)
   807    851   	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/mutex.c
   808    852   
   809    853   mutex_noop.lo:	$(TOP)/src/mutex_noop.c $(HDR)
................................................................................
   874    918   
   875    919   trigger.lo:	$(TOP)/src/trigger.c $(HDR)
   876    920   	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/trigger.c
   877    921   
   878    922   update.lo:	$(TOP)/src/update.c $(HDR)
   879    923   	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/update.c
   880    924   
          925  +upsert.lo:	$(TOP)/src/upsert.c $(HDR)
          926  +	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/upsert.c
          927  +
   881    928   utf.lo:	$(TOP)/src/utf.c $(HDR)
   882    929   	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/utf.c
   883    930   
   884    931   util.lo:	$(TOP)/src/util.c $(HDR)
   885    932   	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/util.c
   886    933   
   887    934   vacuum.lo:	$(TOP)/src/vacuum.c $(HDR)
................................................................................
   922    969   
   923    970   wherecode.lo:	$(TOP)/src/wherecode.c $(HDR)
   924    971   	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/wherecode.c
   925    972   
   926    973   whereexpr.lo:	$(TOP)/src/whereexpr.c $(HDR)
   927    974   	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/whereexpr.c
   928    975   
          976  +window.lo:	$(TOP)/src/window.c $(HDR)
          977  +	$(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/window.c
          978  +
   929    979   tclsqlite.lo:	$(TOP)/src/tclsqlite.c $(HDR)
   930    980   	$(LTCOMPILE) -DUSE_TCL_STUBS=1 -c $(TOP)/src/tclsqlite.c
   931    981   
   932    982   tclsqlite-shell.lo:	$(TOP)/src/tclsqlite.c $(HDR)
   933         -	$(LTCOMPILE) -DTCLSH=1 -o $@ -c $(TOP)/src/tclsqlite.c
          983  +	$(LTCOMPILE) -DTCLSH -o $@ -c $(TOP)/src/tclsqlite.c
   934    984   
   935    985   tclsqlite-stubs.lo:	$(TOP)/src/tclsqlite.c $(HDR)
   936    986   	$(LTCOMPILE) -DUSE_TCL_STUBS=1 -o $@ -c $(TOP)/src/tclsqlite.c
   937    987   
   938    988   tclsqlite3$(TEXE):	tclsqlite-shell.lo libsqlite3.la
   939    989   	$(LTLINK) -o $@ tclsqlite-shell.lo \
   940    990   		 libsqlite3.la $(LIBTCL)
................................................................................
   954   1004   parse.c:	$(TOP)/src/parse.y lemon$(BEXE) $(TOP)/tool/addopcodes.tcl
   955   1005   	cp $(TOP)/src/parse.y .
   956   1006   	rm -f parse.h
   957   1007   	./lemon$(BEXE) $(OPT_FEATURE_FLAGS) $(OPTS) parse.y
   958   1008   	mv parse.h parse.h.temp
   959   1009   	$(TCLSH_CMD) $(TOP)/tool/addopcodes.tcl parse.h.temp >parse.h
   960   1010   
   961         -sqlite3.h:	$(TOP)/src/sqlite.h.in $(TOP)/manifest.uuid $(TOP)/VERSION
         1011  +sqlite3.h:	$(TOP)/src/sqlite.h.in $(TOP)/manifest mksourceid$(BEXE) $(TOP)/VERSION
   962   1012   	$(TCLSH_CMD) $(TOP)/tool/mksqlite3h.tcl $(TOP) >sqlite3.h
   963   1013   
   964   1014   keywordhash.h:	$(TOP)/tool/mkkeywordhash.c
   965   1015   	$(BCC) -o mkkeywordhash$(BEXE) $(OPT_FEATURE_FLAGS) $(OPTS) $(TOP)/tool/mkkeywordhash.c
   966   1016   	./mkkeywordhash$(BEXE) >keywordhash.h
         1017  +
         1018  +# Source files that go into making shell.c
         1019  +SHELL_SRC = \
         1020  +	$(TOP)/src/shell.c.in \
         1021  +        $(TOP)/ext/misc/appendvfs.c \
         1022  +	$(TOP)/ext/misc/shathree.c \
         1023  +	$(TOP)/ext/misc/fileio.c \
         1024  +	$(TOP)/ext/misc/completion.c \
         1025  +	$(TOP)/ext/misc/sqlar.c \
         1026  +	$(TOP)/ext/expert/sqlite3expert.c \
         1027  +	$(TOP)/ext/expert/sqlite3expert.h \
         1028  +	$(TOP)/ext/misc/zipfile.c \
         1029  +        $(TOP)/src/test_windirent.c
         1030  +
         1031  +shell.c:	$(SHELL_SRC) $(TOP)/tool/mkshellc.tcl
         1032  +	$(TCLSH_CMD) $(TOP)/tool/mkshellc.tcl >shell.c
         1033  +
   967   1034   
   968   1035   
   969   1036   
   970   1037   # Rules to build the extension objects.
   971   1038   #
   972   1039   icu.lo:	$(TOP)/ext/icu/icu.c $(HDR) $(EXTHDR)
   973   1040   	$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/icu/icu.c
................................................................................
  1081   1148   # Rules to build the 'testfixture' application.
  1082   1149   #
  1083   1150   # If using the amalgamation, use sqlite3.c directly to build the test
  1084   1151   # fixture.  Otherwise link against libsqlite3.la.  (This distinction is
  1085   1152   # necessary because the test fixture requires non-API symbols which are
  1086   1153   # hidden when the library is built via the amalgamation).
  1087   1154   #
  1088         -TESTFIXTURE_FLAGS  = -DTCLSH=1 -DSQLITE_TEST=1 -DSQLITE_CRASH_TEST=1
         1155  +TESTFIXTURE_FLAGS  = -DSQLITE_TEST=1 -DSQLITE_CRASH_TEST=1
         1156  +TESTFIXTURE_FLAGS += -DTCLSH_INIT_PROC=sqlite3TestInit
  1089   1157   TESTFIXTURE_FLAGS += -DSQLITE_SERVER=1 -DSQLITE_PRIVATE="" -DSQLITE_CORE 
  1090   1158   TESTFIXTURE_FLAGS += -DBUILD_sqlite
  1091   1159   TESTFIXTURE_FLAGS += -DSQLITE_SERIES_CONSTRAINT_VERIFY=1
  1092   1160   TESTFIXTURE_FLAGS += -DSQLITE_DEFAULT_PAGE_SIZE=1024
  1093   1161   TESTFIXTURE_FLAGS += -DSQLITE_ENABLE_STMTVTAB
         1162  +TESTFIXTURE_FLAGS += -DSQLITE_ENABLE_DBPAGE_VTAB
  1094   1163   
  1095   1164   TESTFIXTURE_SRC0 = $(TESTSRC2) libsqlite3.la
  1096   1165   TESTFIXTURE_SRC1 = sqlite3.c
  1097   1166   TESTFIXTURE_SRC = $(TESTSRC) $(TOP)/src/tclsqlite.c
  1098   1167   TESTFIXTURE_SRC += $(TESTFIXTURE_SRC$(USE_AMALGAMATION))
  1099   1168   
  1100   1169   testfixture$(TEXE):	$(TESTFIXTURE_SRC)
................................................................................
  1110   1179   	./testfixture$(TEXE) $(TOP)/test/all.test -soak=1 $(TESTOPTS)
  1111   1180   
  1112   1181   # Do extra testing but not everything.
  1113   1182   fulltestonly:	$(TESTPROGS) fuzztest
  1114   1183   	./testfixture$(TEXE) $(TOP)/test/full.test
  1115   1184   
  1116   1185   # Fuzz testing
  1117         -fuzztest:	fuzzcheck$(TEXE) $(FUZZDATA)
         1186  +fuzztest:	fuzzcheck$(TEXE) $(FUZZDATA) sessionfuzz$(TEXE) $(TOP)/test/sessionfuzz-data1.db
  1118   1187   	./fuzzcheck$(TEXE) $(FUZZDATA)
         1188  +	./sessionfuzz$(TEXE) run $(TOP)/test/sessionfuzz-data1.db
  1119   1189   
  1120         -fastfuzztest:	fuzzcheck$(TEXE) $(FUZZDATA)
         1190  +fastfuzztest:	fuzzcheck$(TEXE) $(FUZZDATA) sessionfuzz$(TEXE) $(TOP)/test/sessionfuzz-data1.db
  1121   1191   	./fuzzcheck$(TEXE) --limit-mem 100M $(FUZZDATA)
         1192  +	./sessionfuzz$(TEXE) run $(TOP)/test/sessionfuzz-data1.db
  1122   1193   
  1123         -valgrindfuzz:	fuzzcheck$(TEXT) $(FUZZDATA)
         1194  +valgrindfuzz:	fuzzcheck$(TEXT) $(FUZZDATA) sessionfuzz$(TEXE) $(TOP)/test/sessionfuzz-data1.db
  1124   1195   	valgrind ./fuzzcheck$(TEXE) --cell-size-check --limit-mem 10M --timeout 600 $(FUZZDATA)
         1196  +	valgrind ./sessionfuzz$(TEXE) run $(TOP)/test/sessionfuzz-data1.db
  1125   1197   
  1126   1198   # The veryquick.test TCL tests.
  1127   1199   #
  1128   1200   tcltest:	./testfixture$(TEXE)
  1129   1201   	./testfixture$(TEXE) $(TOP)/test/veryquick.test $(TESTOPTS)
  1130   1202   
  1131   1203   # Minimal testing that runs in less than 3 minutes
................................................................................
  1147   1219   # A very fast test that checks basic sanity.  The name comes from
  1148   1220   # the 60s-era electronics testing:  "Turn it on and see if smoke
  1149   1221   # comes out."
  1150   1222   #
  1151   1223   smoketest:	$(TESTPROGS) fuzzcheck$(TEXE)
  1152   1224   	./testfixture$(TEXE) $(TOP)/test/main.test $(TESTOPTS)
  1153   1225   
  1154         -sqlite3_analyzer.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/spaceanal.tcl
  1155         -	echo "#define TCLSH 2" > $@
  1156         -	echo "#define SQLITE_ENABLE_DBSTAT_VTAB 1" >> $@
  1157         -	cat sqlite3.c $(TOP)/src/tclsqlite.c >> $@
  1158         -	echo "static const char *tclsh_main_loop(void){" >> $@
  1159         -	echo "static const char *zMainloop = " >> $@
  1160         -	$(TCLSH_CMD) $(TOP)/tool/tostr.tcl $(TOP)/tool/spaceanal.tcl >> $@
  1161         -	echo "; return zMainloop; }" >> $@
         1226  +sqlite3_analyzer.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/spaceanal.tcl $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqlite3_analyzer.c.in
         1227  +	$(TCLSH_CMD) $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqlite3_analyzer.c.in >sqlite3_analyzer.c
  1162   1228   
  1163   1229   sqlite3_analyzer$(TEXE): sqlite3_analyzer.c
  1164   1230   	$(LTLINK) sqlite3_analyzer.c -o $@ $(LIBTCL) $(TLIBS)
         1231  +
         1232  +sqltclsh.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/sqltclsh.tcl $(TOP)/ext/misc/appendvfs.c $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqltclsh.c.in	
         1233  +	$(TCLSH_CMD) $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqltclsh.c.in >sqltclsh.c
         1234  +
         1235  +sqltclsh$(TEXE): sqltclsh.c
         1236  +	$(LTLINK) sqltclsh.c -o $@ $(LIBTCL) $(TLIBS)
         1237  +
         1238  +sqlite3_expert$(TEXE): $(TOP)/ext/expert/sqlite3expert.h $(TOP)/ext/expert/sqlite3expert.c $(TOP)/ext/expert/expert.c sqlite3.c
         1239  +	$(LTLINK)	$(TOP)/ext/expert/sqlite3expert.h $(TOP)/ext/expert/sqlite3expert.c $(TOP)/ext/expert/expert.c sqlite3.c -o sqlite3_expert $(TLIBS)
         1240  +
         1241  +CHECKER_DEPS =\
         1242  +  $(TOP)/tool/mkccode.tcl \
         1243  +  sqlite3.c \
         1244  +  $(TOP)/src/tclsqlite.c \
         1245  +  $(TOP)/ext/repair/sqlite3_checker.tcl \
         1246  +  $(TOP)/ext/repair/checkindex.c \
         1247  +  $(TOP)/ext/repair/checkfreelist.c \
         1248  +  $(TOP)/ext/misc/btreeinfo.c \
         1249  +  $(TOP)/ext/repair/sqlite3_checker.c.in
         1250  +
         1251  +sqlite3_checker.c:	$(CHECKER_DEPS)
         1252  +	$(TCLSH_CMD) $(TOP)/tool/mkccode.tcl $(TOP)/ext/repair/sqlite3_checker.c.in >$@
         1253  +
         1254  +sqlite3_checker$(TEXE):	sqlite3_checker.c
         1255  +	$(LTLINK) sqlite3_checker.c -o $@ $(LIBTCL) $(TLIBS)
  1165   1256   
  1166   1257   dbdump$(TEXE): $(TOP)/ext/misc/dbdump.c sqlite3.lo
  1167   1258   	$(LTLINK) -DDBDUMP_STANDALONE -o $@ \
  1168   1259              $(TOP)/ext/misc/dbdump.c sqlite3.lo $(TLIBS)
  1169   1260   
  1170   1261   showdb$(TEXE):	$(TOP)/tool/showdb.c sqlite3.lo
  1171   1262   	$(LTLINK) -o $@ $(TOP)/tool/showdb.c sqlite3.lo $(TLIBS)
................................................................................
  1175   1266   
  1176   1267   showjournal$(TEXE):	$(TOP)/tool/showjournal.c sqlite3.lo
  1177   1268   	$(LTLINK) -o $@ $(TOP)/tool/showjournal.c sqlite3.lo $(TLIBS)
  1178   1269   
  1179   1270   showwal$(TEXE):	$(TOP)/tool/showwal.c sqlite3.lo
  1180   1271   	$(LTLINK) -o $@ $(TOP)/tool/showwal.c sqlite3.lo $(TLIBS)
  1181   1272   
         1273  +showshm$(TEXE):	$(TOP)/tool/showshm.c
         1274  +	$(LTLINK) -o $@ $(TOP)/tool/showshm.c
         1275  +
  1182   1276   changeset$(TEXE):	$(TOP)/ext/session/changeset.c sqlite3.lo
  1183   1277   	$(LTLINK) -o $@ $(TOP)/ext/session/changeset.c sqlite3.lo $(TLIBS)
  1184   1278   
  1185   1279   rollback-test$(TEXE):	$(TOP)/tool/rollback-test.c sqlite3.lo
  1186   1280   	$(LTLINK) -o $@ $(TOP)/tool/rollback-test.c sqlite3.lo $(TLIBS)
  1187   1281   
         1282  +atrc$(TEXX): $(TOP)/test/atrc.c sqlite3.lo
         1283  +	$(LTLINK) -o $@ $(TOP)/test/atrc.c sqlite3.lo $(TLIBS)
         1284  +
  1188   1285   LogEst$(TEXE):	$(TOP)/tool/logest.c sqlite3.h
  1189   1286   	$(LTLINK) -I. -o $@ $(TOP)/tool/logest.c
  1190   1287   
  1191   1288   wordcount$(TEXE):	$(TOP)/test/wordcount.c sqlite3.lo
  1192   1289   	$(LTLINK) -o $@ $(TOP)/test/wordcount.c sqlite3.lo $(TLIBS)
  1193   1290   
  1194   1291   speedtest1$(TEXE):	$(TOP)/test/speedtest1.c sqlite3.c

Changes to Makefile.msc.

    88     88   # be used for debugging with Visual Studio.
    89     89   #
    90     90   !IFNDEF SPLIT_AMALGAMATION
    91     91   SPLIT_AMALGAMATION = 0
    92     92   !ENDIF
    93     93   
    94     94   # <<mark>>
           95  +# Set this non-0 to have this makefile assume the Tcl shell executable
           96  +# (tclsh*.exe) is available in the PATH.  By default, this is disabled
           97  +# for compatibility with older build environments.  This setting only
           98  +# applies if TCLSH_CMD is not set manually.
           99  +#
          100  +!IFNDEF USE_TCLSH_IN_PATH
          101  +USE_TCLSH_IN_PATH = 0
          102  +!ENDIF
          103  +
          104  +# Set this non-0 to use zlib, possibly compiling it from source code.
          105  +#
          106  +!IFNDEF USE_ZLIB
          107  +USE_ZLIB = 0
          108  +!ENDIF
          109  +
          110  +# Set this non-0 to build zlib from source code.  This is enabled by
          111  +# default and in that case it will be assumed that the ZLIBDIR macro
          112  +# points to the top-level source code directory for zlib.
          113  +#
          114  +!IFNDEF BUILD_ZLIB
          115  +BUILD_ZLIB = 1
          116  +!ENDIF
          117  +
    95    118   # Set this non-0 to use the International Components for Unicode (ICU).
    96    119   #
    97    120   !IFNDEF USE_ICU
    98    121   USE_ICU = 0
    99    122   !ENDIF
   100    123   # <</mark>>
   101    124   
................................................................................
   312    335   # These are the "standard" SQLite compilation options used when compiling for
   313    336   # the Windows platform.
   314    337   #
   315    338   !IFNDEF OPT_FEATURE_FLAGS
   316    339   !IF $(MINIMAL_AMALGAMATION)==0
   317    340   OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_FTS3=1
   318    341   OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_RTREE=1
          342  +OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_GEOPOLY=1
          343  +OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_JSON1=1
          344  +OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_STMTVTAB=1
          345  +OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_DBPAGE_VTAB=1
          346  +OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_DBSTAT_VTAB=1
          347  +OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_INTROSPECTION_PRAGMAS=1
   319    348   !ENDIF
   320    349   OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_COLUMN_METADATA=1
   321    350   !ENDIF
   322    351   
   323    352   # Should the session extension be enabled?  If so, add compilation options
   324    353   # to enable it.
   325    354   #
................................................................................
   593    622   
   594    623   # This is the source code that the shell executable should be compiled
   595    624   # with.
   596    625   #
   597    626   !IFNDEF SHELL_CORE_SRC
   598    627   !IF $(DYNAMIC_SHELL)!=0 || $(FOR_WIN10)!=0
   599    628   SHELL_CORE_SRC =
          629  +# <<mark>>
          630  +!ELSEIF $(USE_AMALGAMATION)==0
          631  +SHELL_CORE_SRC =
          632  +# <</mark>>
   600    633   !ELSE
   601    634   SHELL_CORE_SRC = $(SQLITE3C)
   602    635   !ENDIF
   603    636   !ENDIF
   604    637   
   605    638   # This is the core library that the shell executable should depend on.
   606    639   #
   607    640   !IFNDEF SHELL_CORE_DEP
   608    641   !IF $(DYNAMIC_SHELL)!=0 || $(FOR_WIN10)!=0
   609    642   SHELL_CORE_DEP = $(SQLITE3DLL)
          643  +# <<mark>>
          644  +!ELSEIF $(USE_AMALGAMATION)==0
          645  +SHELL_CORE_DEP = libsqlite3.lib
          646  +# <</mark>>
   610    647   !ELSE
   611    648   SHELL_CORE_DEP =
   612    649   !ENDIF
   613    650   !ENDIF
   614    651   
          652  +# <<mark>>
          653  +# If zlib support is enabled, add the dependencies for it.
          654  +#
          655  +!IF $(USE_ZLIB)!=0 && $(BUILD_ZLIB)!=0
          656  +SHELL_CORE_DEP = zlib $(SHELL_CORE_DEP)
          657  +TESTFIXTURE_DEP = zlib $(TESTFIXTURE_DEP)
          658  +!ENDIF
          659  +# <</mark>>
          660  +
   615    661   # This is the core library that the shell executable should link with.
   616    662   #
   617    663   !IFNDEF SHELL_CORE_LIB
   618    664   !IF $(DYNAMIC_SHELL)!=0 || $(FOR_WIN10)!=0
   619    665   SHELL_CORE_LIB = $(SQLITE3LIB)
          666  +# <<mark>>
          667  +!ELSEIF $(USE_AMALGAMATION)==0
          668  +SHELL_CORE_LIB = libsqlite3.lib
          669  +# <</mark>>
   620    670   !ELSE
   621    671   SHELL_CORE_LIB =
   622    672   !ENDIF
   623    673   !ENDIF
   624    674   
   625    675   # These are additional linker options used for the shell executable.
   626    676   #
................................................................................
   798    848   # <<mark>>
   799    849   # The locations of the Tcl header and library files.  Also, the library that
   800    850   # non-stubs enabled programs using Tcl must link against.  These variables
   801    851   # (TCLINCDIR, TCLLIBDIR, and LIBTCL) may be overridden via the environment
   802    852   # prior to running nmake in order to match the actual installed location and
   803    853   # version on this machine.
   804    854   #
          855  +!IFNDEF TCLDIR
          856  +TCLDIR = $(TOP)\compat\tcl
          857  +!ENDIF
          858  +
   805    859   !IFNDEF TCLINCDIR
   806         -TCLINCDIR = c:\tcl\include
          860  +TCLINCDIR = $(TCLDIR)\include
   807    861   !ENDIF
   808    862   
   809    863   !IFNDEF TCLLIBDIR
   810         -TCLLIBDIR = c:\tcl\lib
          864  +TCLLIBDIR = $(TCLDIR)\lib
   811    865   !ENDIF
   812    866   
   813    867   !IFNDEF LIBTCL
   814    868   LIBTCL = tcl86.lib
   815    869   !ENDIF
   816    870   
   817    871   !IFNDEF LIBTCLSTUB
   818    872   LIBTCLSTUB = tclstub86.lib
   819    873   !ENDIF
   820    874   
   821    875   !IFNDEF LIBTCLPATH
   822         -LIBTCLPATH = c:\tcl\bin
          876  +LIBTCLPATH = $(TCLDIR)\bin
          877  +!ENDIF
          878  +
          879  +# The locations of the zlib header and library files.  These variables
          880  +# (ZLIBINCDIR, ZLIBLIBDIR, and ZLIBLIB) may be overridden via the environment
          881  +# prior to running nmake in order to match the actual installed (or source
          882  +# code) location on this machine.
          883  +#
          884  +!IFNDEF ZLIBDIR
          885  +ZLIBDIR = $(TOP)\compat\zlib
          886  +!ENDIF
          887  +
          888  +!IFNDEF ZLIBINCDIR
          889  +ZLIBINCDIR = $(ZLIBDIR)
          890  +!ENDIF
          891  +
          892  +!IFNDEF ZLIBLIBDIR
          893  +ZLIBLIBDIR = $(ZLIBDIR)
          894  +!ENDIF
          895  +
          896  +!IFNDEF ZLIBLIB
          897  +!IF $(DYNAMIC_SHELL)!=0
          898  +ZLIBLIB = zdll.lib
          899  +!ELSE
          900  +ZLIBLIB = zlib.lib
          901  +!ENDIF
   823    902   !ENDIF
   824    903   
   825    904   # The locations of the ICU header and library files.  These variables
   826    905   # (ICUINCDIR, ICULIBDIR, and LIBICU) may be overridden via the environment
   827    906   # prior to running nmake in order to match the actual installed location on
   828    907   # this machine.
   829    908   #
          909  +!IFNDEF ICUDIR
          910  +ICUDIR = $(TOP)\compat\icu
          911  +!ENDIF
          912  +
   830    913   !IFNDEF ICUINCDIR
   831         -ICUINCDIR = c:\icu\include
          914  +ICUINCDIR = $(ICUDIR)\include
   832    915   !ENDIF
   833    916   
   834    917   !IFNDEF ICULIBDIR
   835         -ICULIBDIR = c:\icu\lib
          918  +ICULIBDIR = $(ICUDIR)\lib
   836    919   !ENDIF
   837    920   
   838    921   !IFNDEF LIBICU
   839    922   LIBICU = icuuc.lib icuin.lib
   840    923   !ENDIF
   841    924   
   842    925   # This is the command to use for tclsh - normally just "tclsh", but we may
   843    926   # know the specific version we want to use.  This variable (TCLSH_CMD) may be
   844    927   # overridden via the environment prior to running nmake in order to select a
   845    928   # specific Tcl shell to use.
   846    929   #
   847    930   !IFNDEF TCLSH_CMD
          931  +!IF $(USE_TCLSH_IN_PATH)!=0 || !EXIST("$(TCLDIR)\bin\tclsh.exe")
   848    932   TCLSH_CMD = tclsh
          933  +!ELSE
          934  +TCLSH_CMD = $(TCLDIR)\bin\tclsh.exe
          935  +!ENDIF
   849    936   !ENDIF
   850    937   # <</mark>>
   851    938   
   852    939   # Compiler options needed for programs that use the readline() library.
   853    940   #
   854    941   !IFNDEF READLINE_FLAGS
   855    942   READLINE_FLAGS = -DHAVE_READLINE=0
................................................................................
   947   1034   #
   948   1035   !IF $(DEBUG)>1 || $(SYMBOLS)!=0
   949   1036   TCC = $(TCC) -Zi
   950   1037   BCC = $(BCC) -Zi
   951   1038   !ENDIF
   952   1039   
   953   1040   # <<mark>>
         1041  +# If zlib support is enabled, add the compiler options for it.
         1042  +#
         1043  +!IF $(USE_ZLIB)!=0
         1044  +TCC = $(TCC) -DSQLITE_HAVE_ZLIB=1
         1045  +RCC = $(RCC) -DSQLITE_HAVE_ZLIB=1
         1046  +TCC = $(TCC) -I$(ZLIBINCDIR)
         1047  +RCC = $(RCC) -I$(ZLIBINCDIR)
         1048  +!ENDIF
         1049  +
   954   1050   # If ICU support is enabled, add the compiler options for it.
   955   1051   #
   956   1052   !IF $(USE_ICU)!=0
   957   1053   TCC = $(TCC) -DSQLITE_ENABLE_ICU=1
   958   1054   RCC = $(RCC) -DSQLITE_ENABLE_ICU=1
   959   1055   TCC = $(TCC) -I$(TOP)\ext\icu
   960   1056   RCC = $(RCC) -I$(TOP)\ext\icu
................................................................................
   970   1066   LTRCOMPILE = $(RCC) -r
   971   1067   LTLIB = lib.exe
   972   1068   LTLINK = $(TCC) -Fe$@
   973   1069   
   974   1070   # If requested, link to the RPCRT4 library.
   975   1071   #
   976   1072   !IF $(USE_RPCRT4_LIB)!=0
   977         -LTLINK = $(LTLINK) rpcrt4.lib
         1073  +LTLIBS = $(LTLIBS) rpcrt4.lib
   978   1074   !ENDIF
   979   1075   
   980   1076   # If a platform was set, force the linker to target that.
   981   1077   # Note that the vcvars*.bat family of batch files typically
   982   1078   # set this for you.  Otherwise, the linker will attempt
   983   1079   # to deduce the binary type based on the object files.
   984   1080   !IFDEF PLATFORM
................................................................................
  1067   1163   LDFLAGS = $(LDOPTS)
  1068   1164   !ENDIF
  1069   1165   
  1070   1166   # <<mark>>
  1071   1167   # Start with the Tcl related linker options.
  1072   1168   #
  1073   1169   !IF $(NO_TCL)==0
  1074         -LTLIBPATHS = /LIBPATH:$(TCLLIBDIR)
  1075         -LTLIBS = $(LIBTCL)
         1170  +TCLLIBPATHS = $(TCLLIBPATHS) /LIBPATH:$(TCLLIBDIR)
         1171  +TCLLIBS = $(TCLLIBS) $(LIBTCL)
         1172  +!ENDIF
         1173  +
         1174  +# If zlib support is enabled, add the linker options for it.
         1175  +#
         1176  +!IF $(USE_ZLIB)!=0
         1177  +LTLIBPATHS = $(LTLIBPATHS) /LIBPATH:$(ZLIBLIBDIR)
         1178  +LTLIBS = $(LTLIBS) $(ZLIBLIB)
  1076   1179   !ENDIF
  1077   1180   
  1078   1181   # If ICU support is enabled, add the linker options for it.
  1079   1182   #
  1080   1183   !IF $(USE_ICU)!=0
  1081   1184   LTLIBPATHS = $(LTLIBPATHS) /LIBPATH:$(ICULIBDIR)
  1082   1185   LTLIBS = $(LTLIBS) $(LIBICU)
................................................................................
  1087   1190   ###############################################################################
  1088   1191   
  1089   1192   # <<mark>>
  1090   1193   # Object files for the SQLite library (non-amalgamation).
  1091   1194   #
  1092   1195   LIBOBJS0 = vdbe.lo parse.lo alter.lo analyze.lo attach.lo auth.lo \
  1093   1196            backup.lo bitvec.lo btmutex.lo btree.lo build.lo \
  1094         -         callback.lo complete.lo ctime.lo date.lo dbstat.lo delete.lo \
         1197  +         callback.lo complete.lo ctime.lo \
         1198  +         date.lo dbpage.lo dbstat.lo delete.lo \
  1095   1199            expr.lo fault.lo fkey.lo \
  1096   1200            fts3.lo fts3_aux.lo fts3_expr.lo fts3_hash.lo fts3_icu.lo \
  1097   1201            fts3_porter.lo fts3_snippet.lo fts3_tokenizer.lo fts3_tokenizer1.lo \
  1098   1202            fts3_tokenize_vtab.lo fts3_unicode.lo fts3_unicode2.lo fts3_write.lo \
  1099   1203            fts5.lo \
  1100   1204            func.lo global.lo hash.lo \
  1101         -         icu.lo insert.lo legacy.lo loadext.lo \
         1205  +         icu.lo insert.lo json1.lo legacy.lo loadext.lo \
  1102   1206            main.lo malloc.lo mem0.lo mem1.lo mem2.lo mem3.lo mem5.lo \
  1103         -         memjournal.lo \
         1207  +         memdb.lo memjournal.lo \
  1104   1208            mutex.lo mutex_noop.lo mutex_unix.lo mutex_w32.lo \
  1105   1209            notify.lo opcodes.lo os.lo os_unix.lo os_win.lo \
  1106   1210            pager.lo pcache.lo pcache1.lo pragma.lo prepare.lo printf.lo \
  1107   1211            random.lo resolve.lo rowset.lo rtree.lo \
  1108         -         sqlite3session.lo select.lo sqlite3rbu.lo status.lo \
         1212  +         sqlite3session.lo select.lo sqlite3rbu.lo status.lo stmt.lo \
  1109   1213            table.lo threads.lo tokenize.lo treeview.lo trigger.lo \
  1110         -         update.lo util.lo vacuum.lo \
         1214  +         update.lo upsert.lo util.lo vacuum.lo \
  1111   1215            vdbeapi.lo vdbeaux.lo vdbeblob.lo vdbemem.lo vdbesort.lo \
  1112   1216            vdbetrace.lo wal.lo walker.lo where.lo wherecode.lo whereexpr.lo \
  1113         -         utf.lo vtab.lo
         1217  +         window.lo utf.lo vtab.lo
  1114   1218   # <</mark>>
  1115   1219   
  1116   1220   # Object files for the amalgamation.
  1117   1221   #
  1118   1222   LIBOBJS1 = sqlite3.lo
  1119   1223   
  1120   1224   # Determine the real value of LIBOBJ based on the 'configure' script
................................................................................
  1150   1254     $(TOP)\src\btmutex.c \
  1151   1255     $(TOP)\src\btree.c \
  1152   1256     $(TOP)\src\build.c \
  1153   1257     $(TOP)\src\callback.c \
  1154   1258     $(TOP)\src\complete.c \
  1155   1259     $(TOP)\src\ctime.c \
  1156   1260     $(TOP)\src\date.c \
         1261  +  $(TOP)\src\dbpage.c \
  1157   1262     $(TOP)\src\dbstat.c \
  1158   1263     $(TOP)\src\delete.c \
  1159   1264     $(TOP)\src\expr.c \
  1160   1265     $(TOP)\src\fault.c \
  1161   1266     $(TOP)\src\fkey.c \
  1162   1267     $(TOP)\src\func.c \
  1163   1268     $(TOP)\src\global.c \
................................................................................
  1168   1273     $(TOP)\src\main.c \
  1169   1274     $(TOP)\src\malloc.c \
  1170   1275     $(TOP)\src\mem0.c \
  1171   1276     $(TOP)\src\mem1.c \
  1172   1277     $(TOP)\src\mem2.c \
  1173   1278     $(TOP)\src\mem3.c \
  1174   1279     $(TOP)\src\mem5.c \
         1280  +  $(TOP)\src\memdb.c \
  1175   1281     $(TOP)\src\memjournal.c \
  1176   1282     $(TOP)\src\mutex.c \
  1177   1283     $(TOP)\src\mutex_noop.c \
  1178   1284     $(TOP)\src\mutex_unix.c \
  1179   1285     $(TOP)\src\mutex_w32.c \
  1180   1286     $(TOP)\src\notify.c \
  1181   1287     $(TOP)\src\os.c \
................................................................................
  1200   1306     $(TOP)\src\threads.c \
  1201   1307     $(TOP)\src\tclsqlite.c \
  1202   1308     $(TOP)\src\tokenize.c \
  1203   1309     $(TOP)\src\treeview.c \
  1204   1310     $(TOP)\src\trigger.c \
  1205   1311     $(TOP)\src\utf.c \
  1206   1312     $(TOP)\src\update.c \
         1313  +  $(TOP)\src\upsert.c \
  1207   1314     $(TOP)\src\util.c \
  1208   1315     $(TOP)\src\vacuum.c \
  1209   1316     $(TOP)\src\vdbe.c \
  1210   1317     $(TOP)\src\vdbeapi.c \
  1211   1318     $(TOP)\src\vdbeaux.c \
  1212   1319     $(TOP)\src\vdbeblob.c \
  1213   1320     $(TOP)\src\vdbemem.c \
................................................................................
  1214   1321     $(TOP)\src\vdbesort.c \
  1215   1322     $(TOP)\src\vdbetrace.c \
  1216   1323     $(TOP)\src\vtab.c \
  1217   1324     $(TOP)\src\wal.c \
  1218   1325     $(TOP)\src\walker.c \
  1219   1326     $(TOP)\src\where.c \
  1220   1327     $(TOP)\src\wherecode.c \
  1221         -  $(TOP)\src\whereexpr.c
  1222         -
  1223         -# Shell source code files.
  1224         -#
  1225         -SRC02 = \
  1226         -  $(TOP)\src\shell.c
         1328  +  $(TOP)\src\whereexpr.c \
         1329  +  $(TOP)\src\window.c
  1227   1330   
  1228   1331   # Core miscellaneous files.
  1229   1332   #
  1230   1333   SRC03 = \
  1231   1334     $(TOP)\src\parse.y
  1232   1335   
  1233   1336   # Core header files, part 1.
................................................................................
  1312   1415   SRC09 = \
  1313   1416     $(TOP)\ext\fts3\fts3.h \
  1314   1417     $(TOP)\ext\fts3\fts3Int.h \
  1315   1418     $(TOP)\ext\fts3\fts3_hash.h \
  1316   1419     $(TOP)\ext\fts3\fts3_tokenizer.h \
  1317   1420     $(TOP)\ext\icu\sqliteicu.h \
  1318   1421     $(TOP)\ext\rtree\rtree.h \
         1422  +  $(TOP)\ext\rtree\geopoly.c \
  1319   1423     $(TOP)\ext\rbu\sqlite3rbu.h \
  1320   1424     $(TOP)\ext\session\sqlite3session.h
  1321   1425   
  1322   1426   # Generated source code files
  1323   1427   #
  1324   1428   SRC10 = \
  1325   1429     opcodes.c \
................................................................................
  1327   1431   
  1328   1432   # Generated header files
  1329   1433   #
  1330   1434   SRC11 = \
  1331   1435     keywordhash.h \
  1332   1436     opcodes.h \
  1333   1437     parse.h \
         1438  +  shell.c \
  1334   1439     $(SQLITE3H)
  1335   1440   
  1336   1441   # Generated Tcl header files
  1337   1442   #
  1338   1443   !IF $(USE_STDCALL)!=0 || $(FOR_WIN10)!=0
  1339   1444   SRC12 = \
  1340   1445     $(SQLITETCLH) \
................................................................................
  1341   1446     $(SQLITETCLDECLSH)
  1342   1447   !ELSE
  1343   1448   SRC12 =
  1344   1449   !ENDIF
  1345   1450   
  1346   1451   # All source code files.
  1347   1452   #
  1348         -SRC = $(SRC00) $(SRC01) $(SRC02) $(SRC03) $(SRC04) $(SRC05) $(SRC06) $(SRC07) $(SRC08) $(SRC09) $(SRC10) $(SRC11)
         1453  +SRC = $(SRC00) $(SRC01) $(SRC03) $(SRC04) $(SRC05) $(SRC06) $(SRC07) $(SRC08) $(SRC09) $(SRC10) $(SRC11)
  1349   1454   
  1350   1455   # Source code to the test files.
  1351   1456   #
  1352   1457   TESTSRC = \
  1353   1458     $(TOP)\src\test1.c \
  1354   1459     $(TOP)\src\test2.c \
  1355   1460     $(TOP)\src\test3.c \
................................................................................
  1372   1477     $(TOP)\src\test_fs.c \
  1373   1478     $(TOP)\src\test_func.c \
  1374   1479     $(TOP)\src\test_hexio.c \
  1375   1480     $(TOP)\src\test_init.c \
  1376   1481     $(TOP)\src\test_intarray.c \
  1377   1482     $(TOP)\src\test_journal.c \
  1378   1483     $(TOP)\src\test_malloc.c \
         1484  +  $(TOP)\src\test_md5.c \
  1379   1485     $(TOP)\src\test_multiplex.c \
  1380   1486     $(TOP)\src\test_mutex.c \
  1381   1487     $(TOP)\src\test_onefile.c \
  1382   1488     $(TOP)\src\test_osinst.c \
  1383   1489     $(TOP)\src\test_pcache.c \
  1384   1490     $(TOP)\src\test_quota.c \
  1385   1491     $(TOP)\src\test_rtree.c \
  1386   1492     $(TOP)\src\test_schema.c \
  1387   1493     $(TOP)\src\test_server.c \
  1388   1494     $(TOP)\src\test_superlock.c \
  1389   1495     $(TOP)\src\test_syscall.c \
         1496  +  $(TOP)\src\test_tclsh.c \
  1390   1497     $(TOP)\src\test_tclvar.c \
  1391   1498     $(TOP)\src\test_thread.c \
  1392   1499     $(TOP)\src\test_vfs.c \
  1393   1500     $(TOP)\src\test_windirent.c \
         1501  +  $(TOP)\src\test_window.c \
  1394   1502     $(TOP)\src\test_wsd.c \
  1395   1503     $(TOP)\ext\fts3\fts3_term.c \
  1396   1504     $(TOP)\ext\fts3\fts3_test.c \
  1397   1505     $(TOP)\ext\rbu\test_rbu.c \
  1398   1506     $(TOP)\ext\session\test_session.c
  1399   1507   
  1400   1508   # Statically linked extensions.
  1401   1509   #
  1402   1510   TESTEXT = \
         1511  +  $(TOP)\ext\expert\sqlite3expert.c \
         1512  +  $(TOP)\ext\expert\test_expert.c \
  1403   1513     $(TOP)\ext\misc\amatch.c \
  1404   1514     $(TOP)\ext\misc\carray.c \
  1405   1515     $(TOP)\ext\misc\closure.c \
  1406   1516     $(TOP)\ext\misc\csv.c \
  1407   1517     $(TOP)\ext\misc\eval.c \
         1518  +  $(TOP)\ext\misc\explain.c \
  1408   1519     $(TOP)\ext\misc\fileio.c \
  1409   1520     $(TOP)\ext\misc\fuzzer.c \
  1410   1521     $(TOP)\ext\fts5\fts5_tcl.c \
  1411   1522     $(TOP)\ext\fts5\fts5_test_mi.c \
  1412   1523     $(TOP)\ext\fts5\fts5_test_tok.c \
  1413   1524     $(TOP)\ext\misc\ieee754.c \
         1525  +  $(TOP)\ext\misc\mmapwarm.c \
  1414   1526     $(TOP)\ext\misc\nextchar.c \
         1527  +  $(TOP)\ext\misc\normalize.c \
  1415   1528     $(TOP)\ext\misc\percentile.c \
  1416   1529     $(TOP)\ext\misc\regexp.c \
  1417   1530     $(TOP)\ext\misc\remember.c \
  1418   1531     $(TOP)\ext\misc\series.c \
  1419   1532     $(TOP)\ext\misc\spellfix.c \
  1420   1533     $(TOP)\ext\misc\totype.c \
  1421   1534     $(TOP)\ext\misc\unionvtab.c \
  1422   1535     $(TOP)\ext\misc\wholenumber.c
         1536  +
         1537  +# If use of zlib is enabled, add the "zipfile.c" source file.
         1538  +#
         1539  +!IF $(USE_ZLIB)!=0
         1540  +TESTEXT = $(TESTEXT) $(TOP)\ext\misc\zipfile.c
         1541  +!ENDIF
  1423   1542   
  1424   1543   # Source code to the library files needed by the test fixture
  1425   1544   # (non-amalgamation)
  1426   1545   #
  1427   1546   TESTSRC2 = \
  1428   1547     $(SRC00) \
  1429   1548     $(SRC01) \
................................................................................
  1472   1591     $(TOP)\ext\fts2\fts2_tokenizer.h
  1473   1592   EXTHDR = $(EXTHDR) \
  1474   1593     $(TOP)\ext\fts3\fts3.h \
  1475   1594     $(TOP)\ext\fts3\fts3Int.h \
  1476   1595     $(TOP)\ext\fts3\fts3_hash.h \
  1477   1596     $(TOP)\ext\fts3\fts3_tokenizer.h
  1478   1597   EXTHDR = $(EXTHDR) \
  1479         -  $(TOP)\ext\rtree\rtree.h
         1598  +  $(TOP)\ext\rtree\rtree.h \
         1599  +  $(TOP)\ext\rtree\geopoly.c
  1480   1600   EXTHDR = $(EXTHDR) \
  1481   1601     $(TOP)\ext\icu\sqliteicu.h
  1482   1602   EXTHDR = $(EXTHDR) \
  1483   1603     $(TOP)\ext\rtree\sqlite3rtree.h
  1484   1604   EXTHDR = $(EXTHDR) \
  1485   1605     $(TOP)\ext\session\sqlite3session.h
  1486   1606   
  1487   1607   # executables needed for testing
  1488   1608   #
  1489   1609   TESTPROGS = \
  1490   1610     testfixture.exe \
  1491   1611     $(SQLITE3EXE) \
  1492   1612     sqlite3_analyzer.exe \
         1613  +  sqlite3_checker.exe \
  1493   1614     sqldiff.exe \
  1494         -  dbhash.exe
         1615  +  dbhash.exe \
         1616  +  sqltclsh.exe
  1495   1617   
  1496   1618   # Databases containing fuzzer test cases
  1497   1619   #
  1498   1620   FUZZDATA = \
  1499   1621     $(TOP)\test\fuzzdata1.db \
  1500   1622     $(TOP)\test\fuzzdata2.db \
  1501   1623     $(TOP)\test\fuzzdata3.db \
  1502   1624     $(TOP)\test\fuzzdata4.db \
  1503         -  $(TOP)\test\fuzzdata5.db
         1625  +  $(TOP)\test\fuzzdata5.db \
         1626  +  $(TOP)\test\fuzzdata6.db
  1504   1627   # <</mark>>
  1505   1628   
  1506   1629   # Additional compiler options for the shell.  These are only effective
  1507   1630   # when the shell is not being dynamically linked.
  1508   1631   #
  1509   1632   !IF $(DYNAMIC_SHELL)==0 && $(FOR_WIN10)==0
  1510         -SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_SHELL_JSON1 -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_STMTVTAB
         1633  +SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_FTS4=1
         1634  +SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_EXPLAIN_COMMENTS=1
         1635  +SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_OFFSET_SQL_FUNC=1
  1511   1636   !ENDIF
  1512   1637   
  1513   1638   # <<mark>>
  1514   1639   # Extra compiler options for various test tools.
  1515   1640   #
  1516         -MPTESTER_COMPILE_OPTS = -DSQLITE_SHELL_JSON1 -DSQLITE_ENABLE_FTS5
         1641  +MPTESTER_COMPILE_OPTS = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS5
  1517   1642   FUZZERSHELL_COMPILE_OPTS = -DSQLITE_ENABLE_JSON1
  1518         -FUZZCHECK_COMPILE_OPTS = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5 -DSQLITE_OSS_FUZZ -DSQLITE_MAX_MEMORY=50000000
         1643  +FUZZCHECK_COMPILE_OPTS = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5 -DSQLITE_OSS_FUZZ -DSQLITE_MAX_MEMORY=50000000 -DSQLITE_PRINTF_PRECISION_LIMIT=1000
  1519   1644   FUZZCHECK_SRC = $(TOP)\test\fuzzcheck.c $(TOP)\test\ossfuzz.c
  1520   1645   OSSSHELL_SRC = $(TOP)\test\ossshell.c $(TOP)\test\ossfuzz.c
  1521   1646   DBFUZZ_COMPILE_OPTS = -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION
  1522   1647   KV_COMPILE_OPTS = -DSQLITE_THREADSAFE=0 -DSQLITE_DIRECT_OVERFLOW_READ
  1523         -DBSELFTEST_COMPILE_OPTS = -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_ENABLE_RTREE -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS5
  1524   1648   ST_COMPILE_OPTS = -DSQLITE_THREADSAFE=0
  1525   1649   
  1526   1650   # Standard options to testfixture.
  1527   1651   #
  1528   1652   TESTOPTS = --verbose=file --output=test-out.txt
  1529   1653   
  1530   1654   # Extra targets for the "all" target that require Tcl.
................................................................................
  1535   1659   ALL_TCL_TARGETS =
  1536   1660   !ENDIF
  1537   1661   # <</mark>>
  1538   1662   
  1539   1663   # This is the default Makefile target.  The objects listed here
  1540   1664   # are what get build when you type just "make" with no arguments.
  1541   1665   #
  1542         -all:	dll libsqlite3.lib shell $(ALL_TCL_TARGETS)
         1666  +core:	dll libsqlite3.lib shell
         1667  +
         1668  +# Targets that require the Tcl library.
         1669  +#
         1670  +tcl:	$(ALL_TCL_TARGETS)
         1671  +
         1672  +# This Makefile target builds all of the standard binaries.
         1673  +#
         1674  +all:	core tcl
  1543   1675   
  1544   1676   # Dynamic link library section.
  1545   1677   #
  1546   1678   dll:	$(SQLITE3DLL)
  1547   1679   
  1548   1680   # Shell executable.
  1549   1681   #
................................................................................
  1560   1692   $(SQLITE3DLL):	$(LIBOBJ) $(LIBRESOBJS) $(CORE_LINK_DEP)
  1561   1693   	$(LD) $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) /DLL $(CORE_LINK_OPTS) /OUT:$@ $(LIBOBJ) $(LIBRESOBJS) $(LTLIBS) $(TLIBS)
  1562   1694   
  1563   1695   # <<block2>>
  1564   1696   sqlite3.def:	libsqlite3.lib
  1565   1697   	echo EXPORTS > sqlite3.def
  1566   1698   	dumpbin /all libsqlite3.lib \
  1567         -		| $(TCLSH_CMD) $(TOP)\tool\replace.tcl include "^\s+1 _?(sqlite3(?:session|changeset|changegroup)?_[^@]*)(?:@\d+)?$$" \1 \
         1699  +		| $(TCLSH_CMD) $(TOP)\tool\replace.tcl include "^\s+1 _?(sqlite3(?:session|changeset|changegroup|rebaser)?_[^@]*)(?:@\d+)?$$" \1 \
  1568   1700   		| sort >> sqlite3.def
  1569   1701   # <</block2>>
  1570   1702   
  1571         -$(SQLITE3EXE):	$(TOP)\src\shell.c $(SHELL_CORE_DEP) $(LIBRESOBJS) $(SHELL_CORE_SRC) $(SQLITE3H)
  1572         -	$(LTLINK) $(SHELL_COMPILE_OPTS) $(READLINE_FLAGS) $(TOP)\src\shell.c $(SHELL_CORE_SRC) \
         1703  +$(SQLITE3EXE):	shell.c $(SHELL_CORE_DEP) $(LIBRESOBJS) $(SHELL_CORE_SRC) $(SQLITE3H)
         1704  +	$(LTLINK) $(SHELL_COMPILE_OPTS) $(READLINE_FLAGS) shell.c $(SHELL_CORE_SRC) \
  1573   1705   		/link $(SQLITE3EXEPDB) $(LDFLAGS) $(LTLINKOPTS) $(SHELL_LINK_OPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LIBREADLINE) $(LTLIBS) $(TLIBS)
  1574   1706   
  1575   1707   # <<mark>>
  1576   1708   sqldiff.exe:	$(TOP)\tool\sqldiff.c $(SQLITE3C) $(SQLITE3H)
  1577   1709   	$(LTLINK) $(NO_WARN) $(TOP)\tool\sqldiff.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
  1578   1710   
  1579   1711   dbhash.exe:	$(TOP)\tool\dbhash.c $(SQLITE3C) $(SQLITE3H)
  1580   1712   	$(LTLINK) $(NO_WARN) $(TOP)\tool\dbhash.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
  1581   1713   
  1582   1714   scrub.exe:	$(TOP)\ext\misc\scrub.c $(SQLITE3C) $(SQLITE3H)
  1583         -	$(LTLINK) $(NO_WARN) $(TOP)\ext\misc\scrub.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
         1715  +	$(LTLINK) $(NO_WARN) -DSCRUB_STANDALONE=1 $(TOP)\ext\misc\scrub.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
  1584   1716   
  1585   1717   srcck1.exe:	$(TOP)\tool\srcck1.c
  1586   1718   	$(BCC) $(NO_WARN) -Fe$@ $(TOP)\tool\srcck1.c
  1587   1719   
  1588         -sourcetest:	srcck1.exe sqlite3.c
  1589         -	srcck1.exe sqlite3.c
         1720  +sourcetest:	srcck1.exe $(SQLITE3C)
         1721  +	srcck1.exe $(SQLITE3C)
  1590   1722   
  1591   1723   fuzzershell.exe:	$(TOP)\tool\fuzzershell.c $(SQLITE3C) $(SQLITE3H)
  1592   1724   	$(LTLINK) $(NO_WARN) $(FUZZERSHELL_COMPILE_OPTS) $(TOP)\tool\fuzzershell.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
  1593   1725   
  1594   1726   dbfuzz.exe:	$(TOP)\test\dbfuzz.c $(SQLITE3C) $(SQLITE3H)
  1595   1727   	$(LTLINK) $(NO_WARN) $(DBFUZZ_COMPILE_OPTS) $(TOP)\test\dbfuzz.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
  1596   1728   
  1597   1729   fuzzcheck.exe:	$(FUZZCHECK_SRC) $(SQLITE3C) $(SQLITE3H)
  1598   1730   	$(LTLINK) $(NO_WARN) $(FUZZCHECK_COMPILE_OPTS) $(FUZZCHECK_SRC) $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
  1599   1731   
  1600   1732   ossshell.exe:	$(OSSSHELL_SRC) $(SQLITE3C) $(SQLITE3H)
  1601   1733   	$(LTLINK) $(NO_WARN) $(FUZZCHECK_COMPILE_OPTS) $(OSSSHELL_SRC) $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
  1602   1734   
         1735  +sessionfuzz.exe:	zlib $(TOP)\test\sessionfuzz.c $(SQLITE3C) $(SQLITE3H)
         1736  +	$(LTLINK) $(NO_WARN) -I$(ZLIBINCDIR) $(TOP)\test\sessionfuzz.c /link $(LDFLAGS) $(LTLINKOPTS) /LIBPATH:$(ZLIBLIBDIR) $(ZLIBLIB)
         1737  +
  1603   1738   mptester.exe:	$(TOP)\mptest\mptest.c $(SQLITE3C) $(SQLITE3H)
  1604   1739   	$(LTLINK) $(NO_WARN) $(MPTESTER_COMPILE_OPTS) $(TOP)\mptest\mptest.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
  1605   1740   
  1606   1741   MPTEST1 = mptester mptest.db $(TOP)\mptest\crash01.test --repeat 20
  1607   1742   MPTEST2 = mptester mptest.db $(TOP)\mptest\multiwrite01.test --repeat 20
  1608   1743   
  1609   1744   mptest:	mptester.exe
................................................................................
  1624   1759   # all that automatic generation.
  1625   1760   #
  1626   1761   .target_source:	$(SRC) $(TOP)\tool\vdbe-compress.tcl fts5.c $(SQLITE_TCL_DEP)
  1627   1762   	-rmdir /Q/S tsrc 2>NUL
  1628   1763   	-mkdir tsrc
  1629   1764   	for %i in ($(SRC00)) do copy /Y %i tsrc
  1630   1765   	for %i in ($(SRC01)) do copy /Y %i tsrc
  1631         -	for %i in ($(SRC02)) do copy /Y %i tsrc
  1632   1766   	for %i in ($(SRC03)) do copy /Y %i tsrc
  1633   1767   	for %i in ($(SRC04)) do copy /Y %i tsrc
  1634   1768   	for %i in ($(SRC05)) do copy /Y %i tsrc
  1635   1769   	for %i in ($(SRC06)) do copy /Y %i tsrc
  1636   1770   	for %i in ($(SRC07)) do copy /Y %i tsrc
  1637   1771   	for %i in ($(SRC08)) do copy /Y %i tsrc
  1638   1772   	for %i in ($(SRC09)) do copy /Y %i tsrc
................................................................................
  1644   1778   	del /Q tsrc\sqlite.h.in tsrc\parse.y 2>NUL
  1645   1779   	$(TCLSH_CMD) $(TOP)\tool\vdbe-compress.tcl $(OPTS) < tsrc\vdbe.c > vdbe.new
  1646   1780   	move vdbe.new tsrc\vdbe.c
  1647   1781   	echo > .target_source
  1648   1782   
  1649   1783   sqlite3.c:	.target_source sqlite3ext.h $(MKSQLITE3C_TOOL)
  1650   1784   	$(TCLSH_CMD) $(MKSQLITE3C_TOOL) $(MKSQLITE3C_ARGS)
  1651         -	copy tsrc\shell.c .
  1652   1785   	copy $(TOP)\ext\session\sqlite3session.h .
  1653   1786   
  1654   1787   sqlite3-all.c:	sqlite3.c $(TOP)\tool\split-sqlite3c.tcl
  1655   1788   	$(TCLSH_CMD) $(TOP)\tool\split-sqlite3c.tcl
  1656   1789   # <</mark>>
  1657   1790   
  1658   1791   # Rule to build the amalgamation
................................................................................
  1666   1799   lempar.c:	$(TOP)\tool\lempar.c
  1667   1800   	copy $(TOP)\tool\lempar.c .
  1668   1801   
  1669   1802   lemon.exe:	$(TOP)\tool\lemon.c lempar.c
  1670   1803   	$(BCC) $(NO_WARN) -Daccess=_access \
  1671   1804   		-Fe$@ $(TOP)\tool\lemon.c /link $(LDFLAGS) $(NLTLINKOPTS) $(NLTLIBPATHS)
  1672   1805   
         1806  +# <<mark>>
         1807  +# Rules to build the source-id generator tool
         1808  +#
         1809  +mksourceid.exe:	$(TOP)\tool\mksourceid.c
         1810  +	$(BCC) $(NO_WARN) -Fe$@ $(TOP)\tool\mksourceid.c /link $(LDFLAGS) $(NLTLINKOPTS) $(NLTLIBPATHS)
         1811  +
  1673   1812   # Rules to build individual *.lo files from generated *.c files. This
  1674   1813   # applies to:
  1675   1814   #
  1676   1815   #     parse.lo
  1677   1816   #     opcodes.lo
  1678   1817   #
  1679   1818   parse.lo:	parse.c $(HDR)
................................................................................
  1736   1875   
  1737   1876   ctime.lo:	$(TOP)\src\ctime.c $(HDR)
  1738   1877   	$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\ctime.c
  1739   1878   
  1740   1879   date.lo:	$(TOP)\src\date.c $(HDR)
  1741   1880   	$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\date.c
  1742   1881   
  1743         -dbstat.lo:	$(TOP)\src\date.c $(HDR)
         1882  +dbpage.lo:	$(TOP)\src\dbpage.c $(HDR)
         1883  +	$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\dbpage.c
         1884  +
         1885  +dbstat.lo:	$(TOP)\src\dbstat.c $(HDR)
  1744   1886   	$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\dbstat.c
  1745   1887   
  1746   1888   delete.lo:	$(TOP)\src\delete.c $(HDR)
  1747   1889   	$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\delete.c
  1748   1890   
  1749   1891   expr.lo:	$(TOP)\src\expr.c $(HDR)
  1750   1892   	$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\expr.c
................................................................................
  1790   1932   
  1791   1933   mem3.lo:	$(TOP)\src\mem3.c $(HDR)
  1792   1934   	$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\mem3.c
  1793   1935   
  1794   1936   mem5.lo:	$(TOP)\src\mem5.c $(HDR)
  1795   1937   	$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\mem5.c
  1796   1938   
         1939  +memdb.lo:	$(TOP)\src\memdb.c $(HDR)
         1940  +	$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\memdb.c
         1941  +
  1797   1942   memjournal.lo:	$(TOP)\src\memjournal.c $(HDR)
  1798   1943   	$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\memjournal.c
  1799   1944   
  1800   1945   mutex.lo:	$(TOP)\src\mutex.c $(HDR)
  1801   1946   	$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\mutex.c
  1802   1947   
  1803   1948   mutex_noop.lo:	$(TOP)\src\mutex_noop.c $(HDR)
................................................................................
  1868   2013   
  1869   2014   trigger.lo:	$(TOP)\src\trigger.c $(HDR)
  1870   2015   	$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\trigger.c
  1871   2016   
  1872   2017   update.lo:	$(TOP)\src\update.c $(HDR)
  1873   2018   	$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\update.c
  1874   2019   
         2020  +upsert.lo:	$(TOP)\src\upsert.c $(HDR)
         2021  +	$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\upsert.c
         2022  +
  1875   2023   utf.lo:	$(TOP)\src\utf.c $(HDR)
  1876   2024   	$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\utf.c
  1877   2025   
  1878   2026   util.lo:	$(TOP)\src\util.c $(HDR)
  1879   2027   	$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\util.c
  1880   2028   
  1881   2029   vacuum.lo:	$(TOP)\src\vacuum.c $(HDR)
................................................................................
  1916   2064   
  1917   2065   wherecode.lo:	$(TOP)\src\wherecode.c $(HDR)
  1918   2066   	$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\wherecode.c
  1919   2067   
  1920   2068   whereexpr.lo:	$(TOP)\src\whereexpr.c $(HDR)
  1921   2069   	$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\whereexpr.c
  1922   2070   
         2071  +window.lo:	$(TOP)\src\window.c $(HDR)
         2072  +	$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(TOP)\src\window.c
         2073  +
  1923   2074   tclsqlite.lo:	$(TOP)\src\tclsqlite.c $(HDR) $(SQLITE_TCL_DEP)
  1924   2075   	$(LTCOMPILE) $(NO_WARN) -DUSE_TCL_STUBS=1 -DBUILD_sqlite -I$(TCLINCDIR) -c $(TOP)\src\tclsqlite.c
  1925   2076   
  1926   2077   tclsqlite-shell.lo:	$(TOP)\src\tclsqlite.c $(HDR) $(SQLITE_TCL_DEP)
  1927         -	$(LTCOMPILE) $(NO_WARN) -DTCLSH=1 -DBUILD_sqlite -I$(TCLINCDIR) -c $(TOP)\src\tclsqlite.c
         2078  +	$(LTCOMPILE) $(NO_WARN) -DTCLSH -DBUILD_sqlite -I$(TCLINCDIR) -c $(TOP)\src\tclsqlite.c
  1928   2079   
  1929   2080   tclsqlite3.exe:	tclsqlite-shell.lo $(SQLITE3C) $(SQLITE3H) $(LIBRESOBJS)
  1930         -	$(LTLINK) $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) /OUT:$@ tclsqlite-shell.lo $(LIBRESOBJS) $(LTLIBS) $(TLIBS)
         2081  +	$(LTLINK) $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS) $(TCLLIBPATHS) $(LTLIBPATHS) /OUT:$@ tclsqlite-shell.lo $(LIBRESOBJS) $(TCLLIBS) $(LTLIBS) $(TLIBS)
  1931   2082   
  1932   2083   # Rules to build opcodes.c and opcodes.h
  1933   2084   #
  1934   2085   opcodes.c:	opcodes.h $(TOP)\tool\mkopcodec.tcl
  1935   2086   	$(TCLSH_CMD) $(TOP)\tool\mkopcodec.tcl opcodes.h > opcodes.c
  1936   2087   
  1937   2088   opcodes.h:	parse.h $(TOP)\src\vdbe.c $(TOP)\tool\mkopcodeh.tcl
................................................................................
  1944   2095   parse.c:	$(TOP)\src\parse.y lemon.exe $(TOP)\tool\addopcodes.tcl
  1945   2096   	del /Q parse.y parse.h parse.h.temp 2>NUL
  1946   2097   	copy $(TOP)\src\parse.y .
  1947   2098   	.\lemon.exe $(REQ_FEATURE_FLAGS) $(OPT_FEATURE_FLAGS) $(EXT_FEATURE_FLAGS) $(OPTS) parse.y
  1948   2099   	move parse.h parse.h.temp
  1949   2100   	$(TCLSH_CMD) $(TOP)\tool\addopcodes.tcl parse.h.temp > parse.h
  1950   2101   
  1951         -$(SQLITE3H):	$(TOP)\src\sqlite.h.in $(TOP)\manifest.uuid $(TOP)\VERSION
         2102  +$(SQLITE3H):	$(TOP)\src\sqlite.h.in $(TOP)\manifest mksourceid.exe $(TOP)\VERSION
  1952   2103   	$(TCLSH_CMD) $(TOP)\tool\mksqlite3h.tcl $(TOP:\=/) > $(SQLITE3H) $(MKSQLITE3H_ARGS)
  1953   2104   
  1954   2105   sqlite3ext.h:	.target_source
  1955   2106   !IF $(USE_STDCALL)!=0 || $(FOR_WIN10)!=0
  1956   2107   	type tsrc\sqlite3ext.h | $(TCLSH_CMD) $(TOP)\tool\replace.tcl regsub "\(\*\)" "(SQLITE_CALLBACK *)" \
  1957   2108   		| $(TCLSH_CMD) $(TOP)\tool\replace.tcl regsub "\(\*" "(SQLITE_APICALL *" > sqlite3ext.h
  1958   2109   	copy /Y sqlite3ext.h tsrc\sqlite3ext.h
................................................................................
  1963   2114   mkkeywordhash.exe:	$(TOP)\tool\mkkeywordhash.c
  1964   2115   	$(BCC) $(NO_WARN) -Fe$@ $(REQ_FEATURE_FLAGS) $(OPT_FEATURE_FLAGS) $(EXT_FEATURE_FLAGS) $(OPTS) \
  1965   2116   		$(TOP)\tool\mkkeywordhash.c /link $(LDFLAGS) $(NLTLINKOPTS) $(NLTLIBPATHS)
  1966   2117   
  1967   2118   keywordhash.h:	$(TOP)\tool\mkkeywordhash.c mkkeywordhash.exe
  1968   2119   	.\mkkeywordhash.exe > keywordhash.h
  1969   2120   
         2121  +# Source files that go into making shell.c
         2122  +SHELL_SRC = \
         2123  +	$(TOP)\src\shell.c.in \
         2124  +	$(TOP)\ext\misc\appendvfs.c \
         2125  +	$(TOP)\ext\misc\shathree.c \
         2126  +	$(TOP)\ext\misc\fileio.c \
         2127  +	$(TOP)\ext\misc\completion.c \
         2128  +	$(TOP)\ext\expert\sqlite3expert.c \
         2129  +	$(TOP)\ext\expert\sqlite3expert.h \
         2130  +	$(TOP)\src\test_windirent.c
  1970   2131   
         2132  +# If use of zlib is enabled, add the "zipfile.c" source file.
         2133  +#
         2134  +!IF $(USE_ZLIB)!=0
         2135  +SHELL_SRC = $(SHELL_SRC) $(TOP)\ext\misc\sqlar.c
         2136  +SHELL_SRC = $(SHELL_SRC) $(TOP)\ext\misc\zipfile.c
         2137  +!ENDIF
         2138  +
         2139  +shell.c:	$(SHELL_SRC) $(TOP)\tool\mkshellc.tcl
         2140  +	$(TCLSH_CMD) $(TOP)\tool\mkshellc.tcl > shell.c
         2141  +
         2142  +zlib:
         2143  +	pushd $(ZLIBDIR) && $(MAKE) /f win32\Makefile.msc clean $(ZLIBLIB) && popd
  1971   2144   
  1972   2145   # Rules to build the extension objects.
  1973   2146   #
  1974   2147   icu.lo:	$(TOP)\ext\icu\icu.c $(HDR) $(EXTHDR)
  1975   2148   	$(LTCOMPILE) $(CORE_COMPILE_OPTS) $(NO_WARN) -DSQLITE_CORE -c $(TOP)\ext\icu\icu.c
  1976   2149   
  1977   2150   fts2.lo:	$(TOP)\ext\fts2\fts2.c $(HDR) $(EXTHDR)
................................................................................
  2027   2200   
  2028   2201   fts3_unicode2.lo:	$(TOP)\ext\fts3\fts3_unicode2.c $(HDR) $(EXTHDR)
  2029   2202   	$(LTCOMPILE) $(CORE_COMPILE_OPTS) $(NO_WARN) -DSQLITE_CORE -c $(TOP)\ext\fts3\fts3_unicode2.c
  2030   2203   
  2031   2204   fts3_write.lo:	$(TOP)\ext\fts3\fts3_write.c $(HDR) $(EXTHDR)
  2032   2205   	$(LTCOMPILE) $(CORE_COMPILE_OPTS) $(NO_WARN) -DSQLITE_CORE -c $(TOP)\ext\fts3\fts3_write.c
  2033   2206   
         2207  +json1.lo:	$(TOP)\ext\misc\json1.c $(HDR) $(EXTHDR)
         2208  +	$(LTCOMPILE) $(CORE_COMPILE_OPTS) $(NO_WARN) -DSQLITE_CORE -c $(TOP)\ext\misc\json1.c
         2209  +
         2210  +stmt.lo:	$(TOP)\ext\misc\stmt.c $(HDR) $(EXTHDR)
         2211  +	$(LTCOMPILE) $(CORE_COMPILE_OPTS) $(NO_WARN) -DSQLITE_CORE -c $(TOP)\ext\misc\stmt.c
         2212  +
  2034   2213   rtree.lo:	$(TOP)\ext\rtree\rtree.c $(HDR) $(EXTHDR)
  2035   2214   	$(LTCOMPILE) $(CORE_COMPILE_OPTS) $(NO_WARN) -DSQLITE_CORE -c $(TOP)\ext\rtree\rtree.c
  2036   2215   
  2037   2216   sqlite3session.lo:	$(TOP)\ext\session\sqlite3session.c $(HDR) $(EXTHDR)
  2038   2217   	$(LTCOMPILE) $(CORE_COMPILE_OPTS) $(NO_WARN) -DSQLITE_CORE -c $(TOP)\ext\session\sqlite3session.c
  2039   2218   
  2040   2219   # FTS5 things
................................................................................
  2052   2231      fts5parse.c fts5parse.h \
  2053   2232      $(TOP)\ext\fts5\fts5_storage.c \
  2054   2233      $(TOP)\ext\fts5\fts5_tokenize.c \
  2055   2234      $(TOP)\ext\fts5\fts5_unicode2.c \
  2056   2235      $(TOP)\ext\fts5\fts5_varint.c \
  2057   2236      $(TOP)\ext\fts5\fts5_vocab.c
  2058   2237   
         2238  +LSM1_SRC = \
         2239  +   $(TOP)\ext\lsm1\lsm.h \
         2240  +   $(TOP)\ext\lsm1\lsmInt.h \
         2241  +   $(TOP)\ext\lsm1\lsm_ckpt.c \
         2242  +   $(TOP)\ext\lsm1\lsm_file.c \
         2243  +   $(TOP)\ext\lsm1\lsm_log.c \
         2244  +   $(TOP)\ext\lsm1\lsm_main.c \
         2245  +   $(TOP)\ext\lsm1\lsm_mem.c \
         2246  +   $(TOP)\ext\lsm1\lsm_mutex.c \
         2247  +   $(TOP)\ext\lsm1\lsm_shared.c \
         2248  +   $(TOP)\ext\lsm1\lsm_sorted.c \
         2249  +   $(TOP)\ext\lsm1\lsm_str.c \
         2250  +   $(TOP)\ext\lsm1\lsm_tree.c \
         2251  +   $(TOP)\ext\lsm1\lsm_unix.c \
         2252  +   $(TOP)\ext\lsm1\lsm_varint.c \
         2253  +   $(TOP)\ext\lsm1\lsm_vtab.c \
         2254  +   $(TOP)\ext\lsm1\lsm_win32.c
         2255  +
  2059   2256   fts5parse.c:	$(TOP)\ext\fts5\fts5parse.y lemon.exe
  2060   2257   	copy $(TOP)\ext\fts5\fts5parse.y .
  2061   2258   	del /Q fts5parse.h 2>NUL
  2062   2259   	.\lemon.exe $(REQ_FEATURE_FLAGS) $(OPT_FEATURE_FLAGS) $(EXT_FEATURE_FLAGS) $(OPTS) fts5parse.y
  2063   2260   
  2064   2261   fts5parse.h:	fts5parse.c
  2065   2262   
  2066   2263   fts5.c:	$(FTS5_SRC)
  2067   2264   	$(TCLSH_CMD) $(TOP)\ext\fts5\tool\mkfts5c.tcl
  2068   2265   	copy $(TOP)\ext\fts5\fts5.h .
  2069   2266   
         2267  +lsm1.c:	$(LSM1_SRC)
         2268  +	$(TCLSH_CMD) $(TOP)\ext\lsm1\tool\mklsm1c.tcl
         2269  +	copy $(TOP)\ext\lsm1\lsm.h .
         2270  +
  2070   2271   fts5.lo:	fts5.c $(HDR) $(EXTHDR)
  2071   2272   	$(LTCOMPILE) $(CORE_COMPILE_OPTS) $(NO_WARN) -DSQLITE_CORE -c fts5.c
  2072   2273   
  2073   2274   fts5_ext.lo:	fts5.c $(HDR) $(EXTHDR)
  2074   2275   	$(LTCOMPILE) $(NO_WARN) -c fts5.c
  2075   2276   
  2076   2277   fts5.dll:	fts5_ext.lo
................................................................................
  2082   2283   # Rules to build the 'testfixture' application.
  2083   2284   #
  2084   2285   # If using the amalgamation, use sqlite3.c directly to build the test
  2085   2286   # fixture.  Otherwise link against libsqlite3.lib.  (This distinction is
  2086   2287   # necessary because the test fixture requires non-API symbols which are
  2087   2288   # hidden when the library is built via the amalgamation).
  2088   2289   #
  2089         -TESTFIXTURE_FLAGS = -DTCLSH=1 -DSQLITE_TEST=1 -DSQLITE_CRASH_TEST=1
         2290  +TESTFIXTURE_FLAGS = -DTCLSH_INIT_PROC=sqlite3TestInit -DSQLITE_TEST=1 -DSQLITE_CRASH_TEST=1
  2090   2291   TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_SERVER=1 -DSQLITE_PRIVATE=""
  2091   2292   TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_CORE $(NO_WARN)
  2092   2293   TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_SERIES_CONSTRAINT_VERIFY=1
  2093   2294   TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_DEFAULT_PAGE_SIZE=1024
  2094         -TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_ENABLE_STMTVTAB
         2295  +TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_ENABLE_STMTVTAB=1
         2296  +TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_ENABLE_DBPAGE_VTAB=1
         2297  +TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_ENABLE_JSON1=1
  2095   2298   TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) $(TEST_CCONV_OPTS)
  2096   2299   
  2097   2300   TESTFIXTURE_SRC0 = $(TESTEXT) $(TESTSRC2)
  2098   2301   TESTFIXTURE_SRC1 = $(TESTEXT) $(SQLITE3C)
  2099   2302   !IF $(USE_AMALGAMATION)==0
  2100   2303   TESTFIXTURE_SRC = $(TESTSRC) $(TOP)\src\tclsqlite.c $(TESTFIXTURE_SRC0)
  2101   2304   !ELSE
................................................................................
  2118   2321   	type "$(TCLINCDIR)\tcl.h" | $(TCLSH_CMD) $(TOP)\tool\replace.tcl exact tclDecls.h sqlite_tclDecls.h \
  2119   2322   		| $(TCLSH_CMD) $(TOP)\tool\replace.tcl regsub "typedef (.*?)\(Tcl_" "typedef \1 (SQLITE_TCLAPI Tcl_" \
  2120   2323   		| $(TCLSH_CMD) $(TOP)\tool\replace.tcl exact "void (*freeProc)" "void (SQLITE_TCLAPI *freeProc)" \
  2121   2324   		| $(TCLSH_CMD) $(TOP)\tool\replace.tcl exact "Tcl_HashEntry *(*findProc)" "Tcl_HashEntry *(SQLITE_TCLAPI *findProc)" \
  2122   2325   		| $(TCLSH_CMD) $(TOP)\tool\replace.tcl exact "Tcl_HashEntry *(*createProc)" "Tcl_HashEntry *(SQLITE_TCLAPI *createProc)" >> $(SQLITETCLH)
  2123   2326   !ENDIF
  2124   2327   
  2125         -testfixture.exe:	$(TESTFIXTURE_SRC) $(SQLITE3H) $(LIBRESOBJS) $(HDR) $(SQLITE_TCL_DEP)
         2328  +testfixture.exe:	$(TESTFIXTURE_SRC) $(TESTFIXTURE_DEP) $(SQLITE3H) $(LIBRESOBJS) $(HDR) $(SQLITE_TCL_DEP)
  2126   2329   	$(LTLINK) -DSQLITE_NO_SYNC=1 $(TESTFIXTURE_FLAGS) \
  2127   2330   		-DBUILD_sqlite -I$(TCLINCDIR) \
  2128   2331   		$(TESTFIXTURE_SRC) \
  2129         -		/link $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LTLIBS) $(TLIBS)
         2332  +		/link $(LDFLAGS) $(LTLINKOPTS) $(TCLLIBPATHS) $(LTLIBPATHS) $(LIBRESOBJS) $(TCLLIBS) $(LTLIBS) $(TLIBS)
  2130   2333   
  2131   2334   extensiontest:	testfixture.exe testloadext.dll
  2132   2335   	@set PATH=$(LIBTCLPATH);$(PATH)
  2133   2336   	.\testfixture.exe $(TOP)\test\loadext.test $(TESTOPTS)
  2134   2337   
  2135   2338   fulltest:	$(TESTPROGS) fuzztest
  2136   2339   	@set PATH=$(LIBTCLPATH);$(PATH)
................................................................................
  2167   2370   	@set PATH=$(LIBTCLPATH);$(PATH)
  2168   2371   	.\testfixture.exe $(TOP)\test\veryquick.test $(TESTOPTS)
  2169   2372   
  2170   2373   smoketest:	$(TESTPROGS)
  2171   2374   	@set PATH=$(LIBTCLPATH);$(PATH)
  2172   2375   	.\testfixture.exe $(TOP)\test\main.test $(TESTOPTS)
  2173   2376   
  2174         -sqlite3_analyzer.c:	$(SQLITE3C) $(SQLITE3H) $(TOP)\src\tclsqlite.c $(TOP)\tool\spaceanal.tcl $(SQLITE_TCL_DEP)
  2175         -	echo #define TCLSH 2 > $@
  2176         -	echo #define SQLITE_ENABLE_DBSTAT_VTAB 1 >> $@
  2177         -	copy $@ + $(SQLITE3C) + $(TOP)\src\tclsqlite.c $@
  2178         -	echo static const char *tclsh_main_loop(void){ >> $@
  2179         -	echo static const char *zMainloop = >> $@
  2180         -	$(TCLSH_CMD) $(TOP)\tool\tostr.tcl $(TOP)\tool\spaceanal.tcl >> $@
  2181         -	echo ; return zMainloop; } >> $@
         2377  +sqlite3_analyzer.c:	$(SQLITE3C) $(SQLITE3H) $(TOP)\src\tclsqlite.c $(TOP)\tool\spaceanal.tcl $(TOP)\tool\mkccode.tcl $(TOP)\tool\sqlite3_analyzer.c.in $(SQLITE_TCL_DEP)
         2378  +	$(TCLSH_CMD) $(TOP)\tool\mkccode.tcl $(TOP)\tool\sqlite3_analyzer.c.in > $@
  2182   2379   
  2183   2380   sqlite3_analyzer.exe:	sqlite3_analyzer.c $(LIBRESOBJS)
  2184   2381   	$(LTLINK) $(NO_WARN) -DBUILD_sqlite -I$(TCLINCDIR) sqlite3_analyzer.c \
  2185         -		/link $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LTLIBS) $(TLIBS)
         2382  +		/link $(LDFLAGS) $(LTLINKOPTS) $(TCLLIBPATHS) $(LTLIBPATHS) $(LIBRESOBJS) $(TCLLIBS) $(LTLIBS) $(TLIBS)
  2186   2383   
  2187         -dbdump.exe:	$(TOP)\ext\misc\dbdump.c $(SQLITE3C) $(SQLITE3H)
         2384  +sqltclsh.c: sqlite3.c $(TOP)\src\tclsqlite.c $(TOP)\tool\sqltclsh.tcl $(TOP)\ext\misc\appendvfs.c $(TOP)\tool\mkccode.tcl $(TOP)\tool\sqltclsh.c.in
         2385  +	$(TCLSH_CMD) $(TOP)\tool\mkccode.tcl $(TOP)\tool\sqltclsh.c.in >sqltclsh.c
         2386  +
         2387  +sqltclsh.exe: sqltclsh.c  $(SHELL_CORE_DEP) $(LIBRESOBJS)
         2388  +	$(LTLINK) $(NO_WARN) -DBUILD_sqlite -I$(TCLINCDIR) sqltclsh.c \
         2389  +		/link $(LDFLAGS) $(LTLINKOPTS) $(TCLLIBPATHS) $(LTLIBPATHS) $(LIBRESOBJS) $(TCLLIBS) $(LTLIBS) $(TLIBS)
         2390  +
         2391  +sqlite3_expert.exe: $(SQLITE3C) $(TOP)\ext\expert\sqlite3expert.h $(TOP)\ext\expert\sqlite3expert.c $(TOP)\ext\expert\expert.c
         2392  +	$(LTLINK) $(NO_WARN)	$(TOP)\ext\expert\sqlite3expert.c $(TOP)\ext\expert\expert.c $(SQLITE3C) $(TLIBS)
         2393  +
         2394  +CHECKER_DEPS =\
         2395  +  $(TOP)/tool/mkccode.tcl \
         2396  +  sqlite3.c \
         2397  +  $(TOP)/src/tclsqlite.c \
         2398  +  $(TOP)/ext/repair/sqlite3_checker.tcl \
         2399  +  $(TOP)/ext/repair/checkindex.c \
         2400  +  $(TOP)/ext/repair/checkfreelist.c \
         2401  +  $(TOP)/ext/misc/btreeinfo.c \
         2402  +  $(TOP)/ext/repair/sqlite3_checker.c.in
         2403  +
         2404  +sqlite3_checker.c:	$(CHECKER_DEPS)
         2405  +	$(TCLSH_CMD) $(TOP)\tool\mkccode.tcl $(TOP)\ext\repair\sqlite3_checker.c.in > $@
         2406  +
         2407  +sqlite3_checker.exe:	sqlite3_checker.c $(LIBRESOBJS)
         2408  +	$(LTLINK) $(NO_WARN) -DBUILD_sqlite -I$(TCLINCDIR) sqlite3_checker.c \
         2409  +		/link $(LDFLAGS) $(LTLINKOPTS) $(TCLLIBPATHS) $(LTLIBPATHS) $(LIBRESOBJS) $(TCLLIBS) $(LTLIBS) $(TLIBS)
         2410  +
         2411  +dbdump.exe:	$(TOP)\ext\misc\dbdump.c $(SQLITE3C) $(SQLITE3H) $(LIBRESOBJS)
  2188   2412   	$(LTLINK) $(NO_WARN) -DDBDUMP_STANDALONE $(TOP)\ext\misc\dbdump.c $(SQLITE3C) \
  2189   2413   		/link $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LTLIBS)
  2190   2414   
  2191         -testloadext.lo:	$(TOP)\src\test_loadext.c
         2415  +testloadext.lo:	$(TOP)\src\test_loadext.c $(SQLITE3H)
  2192   2416   	$(LTCOMPILE) $(NO_WARN) -c $(TOP)\src\test_loadext.c
  2193   2417   
  2194   2418   testloadext.dll:	testloadext.lo
  2195   2419   	$(LD) $(LDFLAGS) $(LTLINKOPTS) $(LTLIBPATHS) /DLL /OUT:$@ testloadext.lo
  2196   2420   
  2197   2421   showdb.exe:	$(TOP)\tool\showdb.c $(SQLITE3C) $(SQLITE3H)
  2198   2422   	$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \
................................................................................
  2206   2430   	$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \
  2207   2431   		$(TOP)\tool\showjournal.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
  2208   2432   
  2209   2433   showwal.exe:	$(TOP)\tool\showwal.c $(SQLITE3C) $(SQLITE3H)
  2210   2434   	$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \
  2211   2435   		$(TOP)\tool\showwal.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
  2212   2436   
         2437  +showshm.exe:	$(TOP)\tool\showshm.c
         2438  +	$(LTLINK) $(NO_WARN)	$(TOP)\tool\showshm.c /link $(LDFLAGS) $(LTLINKOPTS)
         2439  +
  2213   2440   changeset.exe:	$(TOP)\ext\session\changeset.c $(SQLITE3C) $(SQLITE3H)
  2214   2441   	$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \
  2215   2442   		-DSQLITE_ENABLE_SESSION=1 -DSQLITE_ENABLE_PREUPDATE_HOOK=1 \
  2216   2443   		$(TOP)\ext\session\changeset.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
  2217   2444   
  2218   2445   fts3view.exe:	$(TOP)\ext\fts3\tool\fts3view.c $(SQLITE3C) $(SQLITE3H)
  2219   2446   	$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \
  2220   2447   		$(TOP)\ext\fts3\tool\fts3view.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
  2221   2448   
  2222   2449   rollback-test.exe:	$(TOP)\tool\rollback-test.c $(SQLITE3C) $(SQLITE3H)
  2223   2450   	$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \
  2224   2451   		$(TOP)\tool\rollback-test.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
  2225   2452   
         2453  +atrc.exe:	$(TOP)\test\atrc.c $(SQLITE3C) $(SQLITE3H)
         2454  +	$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \
         2455  +		$(TOP)\test\atrc.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
         2456  +
  2226   2457   LogEst.exe:	$(TOP)\tool\logest.c $(SQLITE3H)
  2227   2458   	$(LTLINK) $(NO_WARN) $(TOP)\tool\LogEst.c /link $(LDFLAGS) $(LTLINKOPTS)
  2228   2459   
  2229   2460   wordcount.exe:	$(TOP)\test\wordcount.c $(SQLITE3C) $(SQLITE3H)
  2230   2461   	$(LTLINK) $(NO_WARN) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \
  2231   2462   		$(TOP)\test\wordcount.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
  2232   2463   
................................................................................
  2234   2465   	$(LTLINK) $(NO_WARN) $(ST_COMPILE_OPTS) -DSQLITE_OMIT_LOAD_EXTENSION \
  2235   2466   		$(TOP)\test\speedtest1.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
  2236   2467   
  2237   2468   kvtest.exe:	$(TOP)\test\kvtest.c $(SQLITE3C) $(SQLITE3H)
  2238   2469   	$(LTLINK) $(NO_WARN) $(KV_COMPILE_OPTS) \
  2239   2470   		$(TOP)\test\kvtest.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
  2240   2471   
  2241         -dbselftest.exe:	$(TOP)\test\dbselftest.c $(SQLITE3C) $(SQLITE3H)
  2242         -	$(LTLINK) $(NO_WARN) $(DBSELFTEST_COMPILE_OPTS) $(TOP)\test\dbselftest.c $(SQLITE3C)
  2243         -
  2244   2472   rbu.exe:	$(TOP)\ext\rbu\rbu.c $(TOP)\ext\rbu\sqlite3rbu.c $(SQLITE3C) $(SQLITE3H)
  2245   2473   	$(LTLINK) $(NO_WARN) -DSQLITE_ENABLE_RBU \
  2246   2474   		$(TOP)\ext\rbu\rbu.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS)
  2247   2475   
  2248   2476   LSMDIR=$(TOP)\ext\lsm1
  2249   2477   !INCLUDE $(LSMDIR)\Makefile.msc
  2250   2478   
................................................................................
  2253   2481   # <</mark>>
  2254   2482   
  2255   2483   clean:
  2256   2484   	del /Q *.exp *.lo *.ilk *.lib *.obj *.ncb *.pdb *.sdf *.suo 2>NUL
  2257   2485   	del /Q *.bsc *.def *.cod *.da *.bb *.bbg *.vc gmon.out 2>NUL
  2258   2486   	del /Q $(SQLITE3EXE) $(SQLITE3DLL) Replace.exe 2>NUL
  2259   2487   # <<mark>>
  2260         -	del /Q sqlite3.c sqlite3.h 2>NUL
  2261   2488   	del /Q opcodes.c opcodes.h 2>NUL
  2262   2489   	del /Q lemon.* lempar.c parse.* 2>NUL
  2263         -	del /Q mkkeywordhash.* keywordhash.h 2>NUL
         2490  +	del /Q mksourceid.* mkkeywordhash.* keywordhash.h 2>NUL
  2264   2491   	del /Q notasharedlib.* 2>NUL
  2265   2492   	-rmdir /Q/S .deps 2>NUL
  2266   2493   	-rmdir /Q/S .libs 2>NUL
  2267   2494   	-rmdir /Q/S tsrc 2>NUL
  2268   2495   	del /Q .target_source 2>NUL
  2269   2496   	del /Q tclsqlite3.exe $(SQLITETCLH) $(SQLITETCLDECLSH) 2>NUL
  2270   2497   	del /Q lsm.dll lsmtest.exe 2>NUL
  2271   2498   	del /Q testloadext.dll 2>NUL
  2272   2499   	del /Q testfixture.exe test.db 2>NUL
  2273   2500   	del /Q LogEst.exe fts3view.exe rollback-test.exe showdb.exe dbdump.exe 2>NUL
  2274   2501   	del /Q changeset.exe 2>NUL
  2275   2502   	del /Q showjournal.exe showstat4.exe showwal.exe speedtest1.exe 2>NUL
  2276   2503   	del /Q mptester.exe wordcount.exe rbu.exe srcck1.exe 2>NUL
  2277         -	del /Q sqlite3.c sqlite3-*.c 2>NUL
         2504  +	del /Q sqlite3.c sqlite3-*.c sqlite3.h 2>NUL
  2278   2505   	del /Q sqlite3rc.h 2>NUL
  2279   2506   	del /Q shell.c sqlite3ext.h sqlite3session.h 2>NUL
  2280   2507   	del /Q sqlite3_analyzer.exe sqlite3_analyzer.c 2>NUL
  2281   2508   	del /Q sqlite-*-output.vsix 2>NUL
  2282   2509   	del /Q fuzzershell.exe fuzzcheck.exe sqldiff.exe dbhash.exe 2>NUL
         2510  +	del /Q sqltclsh.* 2>NUL
         2511  +	del /Q dbfuzz.exe sessionfuzz.exe 2>NUL
         2512  +	del /Q kvtest.exe ossshell.exe scrub.exe 2>NUL
         2513  +	del /Q showshm.exe sqlite3_checker.* sqlite3_expert.exe 2>NUL
  2283   2514   	del /Q fts5.* fts5parse.* 2>NUL
         2515  +	del /Q lsm.h lsm1.c 2>NUL
  2284   2516   # <</mark>>

Changes to README.md.

     1      1   <h1 align="center">SQLite Source Repository</h1>
     2      2   
     3         -This repository contains the complete source code for the SQLite database
     4         -engine.  Some test scripts are also include.  However, many other test scripts
            3  +This repository contains the complete source code for the 
            4  +[SQLite database engine](https://sqlite.org/).  Some test scripts 
            5  +are also included.  However, many other test scripts
     5      6   and most of the documentation are managed separately.
     6      7   
     7         -If you are reading this on a Git mirror someplace, you are doing it wrong.
     8         -The [official repository](https://www.sqlite.org/src/) is better.  Go there
     9         -now.
            8  +SQLite [does not use Git](https://sqlite.org/whynotgit.html).
            9  +If you are reading this on GitHub, then you are looking at an
           10  +unofficial mirror. See <https://sqlite.org/src> for the official
           11  +repository.
    10     12   
    11     13   ## Obtaining The Code
    12     14   
    13     15   SQLite sources are managed using the
    14     16   [Fossil](https://www.fossil-scm.org/), a distributed version control system
    15     17   that was specifically designed to support SQLite development.
    16     18   If you do not want to use Fossil, you can download tarballs or ZIP
    17         -archives as follows:
           19  +archives or [SQLite archives](https://sqlite.org/cli.html#sqlar) as follows:
    18     20   
    19         -  *  Lastest trunk check-in:
    20         -     <https://www.sqlite.org/src/tarball/sqlite.tar.gz> or
    21         -     <https://www.sqlite.org/src/zip/sqlite.zip>.
           21  +  *  Lastest trunk check-in as
           22  +     [Tarball](https://www.sqlite.org/src/tarball/sqlite.tar.gz),
           23  +     [ZIP-archive](https://www.sqlite.org/src/zip/sqlite.zip), or
           24  +     [SQLite-archive](https://www.sqlite.org/src/sqlar/sqlite.sqlar).
    22     25   
    23         -  *  Latest release:
    24         -     <https://www.sqlite.org/src/tarball/sqlite.tar.gz?r=release> or
    25         -     <https://www.sqlite.org/src/zip/sqlite.zip?r=release>.
           26  +  *  Latest release as
           27  +     [Tarball](https://www.sqlite.org/src/tarball/sqlite.tar.gz?r=release),
           28  +     [ZIP-archive](https://www.sqlite.org/src/zip/sqlite.zip?r=release), or
           29  +     [SQLite-archive](https://www.sqlite.org/src/sqlar/sqlite.sqlar?r=release).
    26     30   
    27     31     *  For other check-ins, substitute an appropriate branch name or
    28     32        tag or hash prefix for "release" in the URLs of the previous
    29     33        bullet.  Or browse the [timeline](https://www.sqlite.org/src/timeline)
    30     34        to locate the check-in desired, click on its information page link,
    31     35        then click on the "Tarball" or "ZIP Archive" links on the information
    32     36        page.
................................................................................
   100    104   to the "sqlite3.dll" command line above.  When debugging into the SQLite
   101    105   code, adding the "DEBUG=1" argument to one of the above command lines is
   102    106   recommended.
   103    107   
   104    108   SQLite does not require [Tcl](http://www.tcl.tk/) to run, but a Tcl installation
   105    109   is required by the makefiles (including those for MSVC).  SQLite contains
   106    110   a lot of generated code and Tcl is used to do much of that code generation.
   107         -The makefiles also require AWK.
   108    111   
   109    112   ## Source Code Tour
   110    113   
   111    114   Most of the core source files are in the **src/** subdirectory.  The
   112    115   **src/** folder also contains files used to build the "testfixture" test
   113    116   harness. The names of the source files used by "testfixture" all begin
   114    117   with "test".
   115    118   The **src/** also contains the "shell.c" file
   116    119   which is the main program for the "sqlite3.exe"
   117    120   [command-line shell](https://sqlite.org/cli.html) and
   118    121   the "tclsqlite.c" file which implements the
   119         -[TCL bindings](https://sqlite.org/tclsqlite.html) for SQLite.
          122  +[Tcl bindings](https://sqlite.org/tclsqlite.html) for SQLite.
   120    123   (Historical note:  SQLite began as a Tcl
   121    124   extension and only later escaped to the wild as an independent library.)
   122    125   
   123    126   Test scripts and programs are found in the **test/** subdirectory.
   124    127   Addtional test code is found in other source repositories.
   125    128   See [How SQLite Is Tested](http://www.sqlite.org/testing.html) for
   126    129   additional information.
................................................................................
   159    162   the src/parse.y file.  The conversion of "parse.y" into "parse.c" is done
   160    163   by the [lemon](./doc/lemon.html) LALR(1) parser generator.  The source code
   161    164   for lemon is at tool/lemon.c.  Lemon uses the tool/lempar.c file as a
   162    165   template for generating its parser.
   163    166   
   164    167   Lemon also generates the **parse.h** header file, at the same time it
   165    168   generates parse.c. But the parse.h header file is
   166         -modified further (to add additional symbols) using the ./addopcodes.awk
   167         -AWK script.
          169  +modified further (to add additional symbols) using the ./addopcodes.tcl
          170  +Tcl script.
   168    171   
   169    172   The **opcodes.h** header file contains macros that define the numbers
   170    173   corresponding to opcodes in the "VDBE" virtual machine.  The opcodes.h
   171    174   file is generated by the scanning the src/vdbe.c source file.  The
   172         -AWK script at ./mkopcodeh.awk does this scan and generates opcodes.h.
   173         -A second AWK script, ./mkopcodec.awk, then scans opcodes.h to generate
          175  +Tcl script at ./mkopcodeh.tcl does this scan and generates opcodes.h.
          176  +A second Tcl script, ./mkopcodec.tcl, then scans opcodes.h to generate
   174    177   the **opcodes.c** source file, which contains a reverse mapping from
   175    178   opcode-number to opcode-name that is used for EXPLAIN output.
   176    179   
   177    180   The **keywordhash.h** header file contains the definition of a hash table
   178    181   that maps SQL language keywords (ex: "CREATE", "SELECT", "INDEX", etc.) into
   179    182   the numeric codes used by the parse.c parser.  The keywordhash.h file is
   180    183   generated by a C-language program at tool mkkeywordhash.c.
................................................................................
   203    206   tool/mksqlite3c.tcl script is run to copy them all together in just the
   204    207   right order while resolving internal "#include" references.
   205    208   
   206    209   The amalgamation source file is more than 200K lines long.  Some symbolic
   207    210   debuggers (most notably MSVC) are unable to deal with files longer than 64K
   208    211   lines.  To work around this, a separate Tcl script, tool/split-sqlite3c.tcl,
   209    212   can be run on the amalgamation to break it up into a single small C file
   210         -called **sqlite3-all.c** that does #include on about five other files
   211         -named **sqlite3-1.c**, **sqlite3-2.c**, ..., **sqlite3-5.c**.  In this way,
          213  +called **sqlite3-all.c** that does #include on about seven other files
          214  +named **sqlite3-1.c**, **sqlite3-2.c**, ..., **sqlite3-7.c**.  In this way,
   212    215   all of the source code is contained within a single translation unit so
   213    216   that the compiler can do extra cross-procedure optimization, but no
   214    217   individual source file exceeds 32K lines in length.
   215    218   
   216    219   ## How It All Fits Together
   217    220   
   218    221   SQLite is modular in design.
................................................................................
   233    236   Key files:
   234    237   
   235    238     *  **sqlite.h.in** - This file defines the public interface to the SQLite
   236    239        library.  Readers will need to be familiar with this interface before
   237    240        trying to understand how the library works internally.
   238    241   
   239    242     *  **sqliteInt.h** - this header file defines many of the data objects
   240         -     used internally by SQLite.
          243  +     used internally by SQLite.  In addition to "sqliteInt.h", some
          244  +     subsystems have their own header files.
   241    245   
   242    246     *  **parse.y** - This file describes the LALR(1) grammar that SQLite uses
   243    247        to parse SQL statements, and the actions that are taken at each step
   244    248        in the parsing process.
   245    249   
   246    250     *  **vdbe.c** - This file implements the virtual machine that runs
   247    251        prepared statements.  There are various helper files whose names
   248    252        begin with "vdbe".  The VDBE has access to the vdbeInt.h header file
   249    253        which defines internal data objects.  The rest of SQLite interacts
   250    254        with the VDBE through an interface defined by vdbe.h.
   251    255   
   252         -  *  **where.c** - This file analyzes the WHERE clause and generates
          256  +  *  **where.c** - This file (together with its helper files named
          257  +     by "where*.c") analyzes the WHERE clause and generates
   253    258        virtual machine code to run queries efficiently.  This file is
   254    259        sometimes called the "query optimizer".  It has its own private
   255    260        header file, whereInt.h, that defines data objects used internally.
   256    261   
   257    262     *  **btree.c** - This file contains the implementation of the B-Tree
   258         -     storage engine used by SQLite.
          263  +     storage engine used by SQLite.  The interface to the rest of the system
          264  +     is defined by "btree.h".  The "btreeInt.h" header defines objects
          265  +     used internally by btree.c and not published to the rest of the system.
   259    266   
   260    267     *  **pager.c** - This file contains the "pager" implementation, the
   261         -     module that implements transactions.
          268  +     module that implements transactions.  The "pager.h" header file
          269  +     defines the interface between pager.c and the rest of the system.
   262    270   
   263    271     *  **os_unix.c** and **os_win.c** - These two files implement the interface
   264    272        between SQLite and the underlying operating system using the run-time
   265    273        pluggable VFS interface.
   266    274   
   267         -  *  **shell.c** - This file is not part of the core SQLite library.  This
          275  +  *  **shell.c.in** - This file is not part of the core SQLite library.  This
   268    276        is the file that, when linked against sqlite3.a, generates the
   269         -     "sqlite3.exe" command-line shell.
          277  +     "sqlite3.exe" command-line shell.  The "shell.c.in" file is transformed
          278  +     into "shell.c" as part of the build process.
   270    279   
   271    280     *  **tclsqlite.c** - This file implements the Tcl bindings for SQLite.  It
   272    281        is not part of the core SQLite library.  But as most of the tests in this
   273    282        repository are written in Tcl, the Tcl language bindings are important.
          283  +
          284  +  *  **test*.c** - Files in the src/ folder that begin with "test" go into
          285  +     building the "testfixture.exe" program.  The testfixture.exe program is
          286  +     an enhanced Tcl shell.  The testfixture.exe program runs scripts in the
          287  +     test/ folder to validate the core SQLite code.  The testfixture program
          288  +     (and some other test programs too) is build and run when you type
          289  +     "make test".
          290  +
          291  +  *  **ext/misc/json1.c** - This file implements the various JSON functions
          292  +     that are build into SQLite.
   274    293   
   275    294   There are many other source files.  Each has a succinct header comment that
   276    295   describes its purpose and role within the larger system.
   277    296   
   278    297   
   279    298   ## Contacts
   280    299   
   281    300   The main SQLite webpage is [http://www.sqlite.org/](http://www.sqlite.org/)
   282    301   with geographically distributed backups at
   283    302   [http://www2.sqlite.org/](http://www2.sqlite.org) and
   284    303   [http://www3.sqlite.org/](http://www3.sqlite.org).

Changes to VERSION.

     1         -3.21.0
            1  +3.26.0

Changes to autoconf/Makefile.am.

     1      1   
     2         -AM_CFLAGS = @THREADSAFE_FLAGS@ @DYNAMIC_EXTENSION_FLAGS@ @FTS5_FLAGS@ @JSON1_FLAGS@ @SESSION_FLAGS@ -DSQLITE_ENABLE_FTS3 -DSQLITE_ENABLE_RTREE
     3         -
            2  +AM_CFLAGS = @BUILD_CFLAGS@ 
     4      3   lib_LTLIBRARIES = libsqlite3.la
     5      4   libsqlite3_la_SOURCES = sqlite3.c
     6      5   libsqlite3_la_LDFLAGS = -no-undefined -version-info 8:6:8
     7      6   
     8      7   bin_PROGRAMS = sqlite3
     9      8   sqlite3_SOURCES = shell.c sqlite3.h
    10      9   EXTRA_sqlite3_SOURCES = sqlite3.c
    11     10   sqlite3_LDADD = @EXTRA_SHELL_OBJ@ @READLINE_LIBS@
    12     11   sqlite3_DEPENDENCIES = @EXTRA_SHELL_OBJ@
    13         -sqlite3_CFLAGS = $(AM_CFLAGS) -DSQLITE_ENABLE_EXPLAIN_COMMENTS
           12  +sqlite3_CFLAGS = $(AM_CFLAGS) -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_DBPAGE_VTAB -DSQLITE_ENABLE_STMTVTAB -DSQLITE_ENABLE_DBSTAT_VTAB $(SHELL_CFLAGS)
    14     13   
    15     14   include_HEADERS = sqlite3.h sqlite3ext.h
    16     15   
    17         -EXTRA_DIST = sqlite3.1 tea Makefile.msc sqlite3.rc README.txt Replace.cs
           16  +EXTRA_DIST = sqlite3.1 tea Makefile.msc sqlite3.rc README.txt Replace.cs Makefile.fallback
    18     17   pkgconfigdir = ${libdir}/pkgconfig
    19     18   pkgconfig_DATA = sqlite3.pc
    20     19   
    21     20   man_MANS = sqlite3.1

Added autoconf/Makefile.fallback.

            1  +#!/usr/bin/make
            2  +#
            3  +# If the configure script does not work, then this Makefile is available
            4  +# as a backup.  Manually configure the variables below.
            5  +#
            6  +# Note:  This makefile works out-of-the-box on MacOS 10.2 (Jaguar)
            7  +#
            8  +CC = gcc
            9  +CFLAGS = -O0 -I.
           10  +LIBS = -lz
           11  +COPTS += -D_BSD_SOURCE
           12  +COPTS += -DSQLITE_ENABLE_LOCKING_STYLE=0
           13  +COPTS += -DSQLITE_THREADSAFE=0
           14  +COPTS += -DSQLITE_OMIT_LOAD_EXTENSION
           15  +COPTS += -DSQLITE_WITHOUT_ZONEMALLOC
           16  +COPTS += -DSQLITE_ENABLE_RTREE
           17  +
           18  +sqlite3:	shell.c sqlite3.c
           19  +	$(CC) $(CFLAGS) $(COPTS) -o sqlite3 shell.c sqlite3.c $(LIBS)

Changes to autoconf/Makefile.msc.

   273    273   # These are the "standard" SQLite compilation options used when compiling for
   274    274   # the Windows platform.
   275    275   #
   276    276   !IFNDEF OPT_FEATURE_FLAGS
   277    277   !IF $(MINIMAL_AMALGAMATION)==0
   278    278   OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_FTS3=1
   279    279   OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_RTREE=1
          280  +OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_GEOPOLY=1
          281  +OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_JSON1=1
          282  +OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_STMTVTAB=1
          283  +OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_DBPAGE_VTAB=1
          284  +OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_DBSTAT_VTAB=1
          285  +OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_INTROSPECTION_PRAGMAS=1
   280    286   !ENDIF
   281    287   OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_COLUMN_METADATA=1
   282    288   !ENDIF
   283    289   
   284    290   # Should the session extension be enabled?  If so, add compilation options
   285    291   # to enable it.
   286    292   #
................................................................................
   556    562   !IFNDEF SHELL_CORE_DEP
   557    563   !IF $(DYNAMIC_SHELL)!=0 || $(FOR_WIN10)!=0
   558    564   SHELL_CORE_DEP = $(SQLITE3DLL)
   559    565   !ELSE
   560    566   SHELL_CORE_DEP =
   561    567   !ENDIF
   562    568   !ENDIF
          569  +
   563    570   
   564    571   # This is the core library that the shell executable should link with.
   565    572   #
   566    573   !IFNDEF SHELL_CORE_LIB
   567    574   !IF $(DYNAMIC_SHELL)!=0 || $(FOR_WIN10)!=0
   568    575   SHELL_CORE_LIB = $(SQLITE3LIB)
   569    576   !ELSE
................................................................................
   804    811   LTRCOMPILE = $(RCC) -r
   805    812   LTLIB = lib.exe
   806    813   LTLINK = $(TCC) -Fe$@
   807    814   
   808    815   # If requested, link to the RPCRT4 library.
   809    816   #
   810    817   !IF $(USE_RPCRT4_LIB)!=0
   811         -LTLINK = $(LTLINK) rpcrt4.lib
          818  +LTLIBS = $(LTLIBS) rpcrt4.lib
   812    819   !ENDIF
   813    820   
   814    821   # If a platform was set, force the linker to target that.
   815    822   # Note that the vcvars*.bat family of batch files typically
   816    823   # set this for you.  Otherwise, the linker will attempt
   817    824   # to deduce the binary type based on the object files.
   818    825   !IFDEF PLATFORM
................................................................................
   923    930   !ENDIF
   924    931   
   925    932   
   926    933   # Additional compiler options for the shell.  These are only effective
   927    934   # when the shell is not being dynamically linked.
   928    935   #
   929    936   !IF $(DYNAMIC_SHELL)==0 && $(FOR_WIN10)==0
   930         -SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_SHELL_JSON1 -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_STMTVTAB
          937  +SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_FTS4=1
          938  +SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_EXPLAIN_COMMENTS=1
          939  +SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_OFFSET_SQL_FUNC=1
   931    940   !ENDIF
   932    941   
   933    942   
   934    943   # This is the default Makefile target.  The objects listed here
   935    944   # are what get build when you type just "make" with no arguments.
   936    945   #
   937         -all:	dll shell
          946  +core:	dll shell
          947  +
          948  +# Targets that require the Tcl library.
          949  +#
          950  +tcl:	$(ALL_TCL_TARGETS)
          951  +
          952  +# This Makefile target builds all of the standard binaries.
          953  +#
          954  +all:	core tcl
   938    955   
   939    956   # Dynamic link library section.
   940    957   #
   941    958   dll:	$(SQLITE3DLL)
   942    959   
   943    960   # Shell executable.
   944    961   #
................................................................................
   950    967   
   951    968   Replace.exe:
   952    969   	$(CSC) /target:exe $(TOP)\Replace.cs
   953    970   
   954    971   sqlite3.def:	Replace.exe $(LIBOBJ)
   955    972   	echo EXPORTS > sqlite3.def
   956    973   	dumpbin /all $(LIBOBJ) \
   957         -		| .\Replace.exe "^\s+/EXPORT:_?(sqlite3(?:session|changeset|changegroup)?_[^@,]*)(?:@\d+|,DATA)?$$" $$1 true \
          974  +		| .\Replace.exe "^\s+/EXPORT:_?(sqlite3(?:session|changeset|changegroup|rebaser)?_[^@,]*)(?:@\d+|,DATA)?$$" $$1 true \
   958    975   		| sort >> sqlite3.def
   959    976   
   960         -$(SQLITE3EXE):	$(TOP)\shell.c $(SHELL_CORE_DEP) $(LIBRESOBJS) $(SHELL_CORE_SRC) $(SQLITE3H)
   961         -	$(LTLINK) $(SHELL_COMPILE_OPTS) $(READLINE_FLAGS) $(TOP)\shell.c $(SHELL_CORE_SRC) \
          977  +$(SQLITE3EXE):	shell.c $(SHELL_CORE_DEP) $(LIBRESOBJS) $(SHELL_CORE_SRC) $(SQLITE3H)
          978  +	$(LTLINK) $(SHELL_COMPILE_OPTS) $(READLINE_FLAGS) shell.c $(SHELL_CORE_SRC) \
   962    979   		/link $(SQLITE3EXEPDB) $(LDFLAGS) $(LTLINKOPTS) $(SHELL_LINK_OPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LIBREADLINE) $(LTLIBS) $(TLIBS)
   963    980   
   964    981   
   965    982   # Rule to build the amalgamation
   966    983   #
   967    984   sqlite3.lo:	$(SQLITE3C)
   968    985   	$(LTCOMPILE) $(CORE_COMPILE_OPTS) -c $(SQLITE3C)
................................................................................
   969    986   
   970    987   
   971    988   # Rule to build the Win32 resources object file.
   972    989   #
   973    990   !IF $(USE_RC)!=0
   974    991   _HASHCHAR=^#
   975    992   !IF ![echo !IFNDEF VERSION > rcver.vc] && \
   976         -    ![for /F "delims=" %V in ('type "$(SQLITE3H)" ^| find "$(_HASHCHAR)define SQLITE_VERSION "') do (echo VERSION = ^^%V >> rcver.vc)] && \
          993  +    ![for /F "delims=" %V in ('type "$(SQLITE3H)" ^| "%SystemRoot%\System32\find.exe" "$(_HASHCHAR)define SQLITE_VERSION "') do (echo VERSION = ^^%V >> rcver.vc)] && \
   977    994       ![echo !ENDIF >> rcver.vc]
   978    995   !INCLUDE rcver.vc
   979    996   !ENDIF
   980    997   
   981    998   RESOURCE_VERSION = $(VERSION:^#=)
   982    999   RESOURCE_VERSION = $(RESOURCE_VERSION:define=)
   983   1000   RESOURCE_VERSION = $(RESOURCE_VERSION:SQLITE_VERSION=)

Changes to autoconf/configure.ac.

     8      8   #   --enable-static-shell
     9      9   #   --enable-dynamic-extensions
    10     10   #
    11     11   
    12     12   AC_PREREQ(2.61)
    13     13   AC_INIT(sqlite, --SQLITE-VERSION--, http://www.sqlite.org)
    14     14   AC_CONFIG_SRCDIR([sqlite3.c])
           15  +AC_CONFIG_AUX_DIR([.])
    15     16   
    16     17   # Use automake.
    17     18   AM_INIT_AUTOMAKE([foreign])
    18     19   
    19     20   AC_SYS_LARGEFILE
    20     21   
    21     22   # Check for required programs.
................................................................................
    24     25   AC_PROG_MKDIR_P
    25     26   
    26     27   # Check for library functions that SQLite can optionally use.
    27     28   AC_CHECK_FUNCS([fdatasync usleep fullfsync localtime_r gmtime_r])
    28     29   AC_FUNC_STRERROR_R
    29     30   
    30     31   AC_CONFIG_FILES([Makefile sqlite3.pc])
           32  +BUILD_CFLAGS=
    31     33   AC_SUBST(BUILD_CFLAGS)
    32     34   
    33     35   #-------------------------------------------------------------------------
    34     36   # Two options to enable readline compatible libraries: 
    35     37   #
    36     38   #   --enable-editline
    37     39   #   --enable-readline
................................................................................
    81     83   
    82     84   #-----------------------------------------------------------------------
    83     85   #   --enable-threadsafe
    84     86   #
    85     87   AC_ARG_ENABLE(threadsafe, [AS_HELP_STRING(
    86     88     [--enable-threadsafe], [build a thread-safe library [default=yes]])], 
    87     89     [], [enable_threadsafe=yes])
    88         -THREADSAFE_FLAGS=-DSQLITE_THREADSAFE=0
    89     90   if test x"$enable_threadsafe" != "xno"; then
    90         -  THREADSAFE_FLAGS="-D_REENTRANT=1 -DSQLITE_THREADSAFE=1"
           91  +  BUILD_CFLAGS="$BUILD_CFLAGS -D_REENTRANT=1 -DSQLITE_THREADSAFE=1"
    91     92     AC_SEARCH_LIBS(pthread_create, pthread)
    92     93     AC_SEARCH_LIBS(pthread_mutexattr_init, pthread)
    93     94   fi
    94         -AC_SUBST(THREADSAFE_FLAGS)
    95     95   #-----------------------------------------------------------------------
    96     96   
    97     97   #-----------------------------------------------------------------------
    98     98   #   --enable-dynamic-extensions
    99     99   #
   100    100   AC_ARG_ENABLE(dynamic-extensions, [AS_HELP_STRING(
   101    101     [--enable-dynamic-extensions], [support loadable extensions [default=yes]])], 
   102    102     [], [enable_dynamic_extensions=yes])
   103    103   if test x"$enable_dynamic_extensions" != "xno"; then
   104    104     AC_SEARCH_LIBS(dlopen, dl)
   105    105   else
   106         -  DYNAMIC_EXTENSION_FLAGS=-DSQLITE_OMIT_LOAD_EXTENSION=1
          106  +  BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_OMIT_LOAD_EXTENSION=1"
   107    107   fi
   108    108   AC_MSG_CHECKING([for whether to support dynamic extensions])
   109    109   AC_MSG_RESULT($enable_dynamic_extensions)
   110         -AC_SUBST(DYNAMIC_EXTENSION_FLAGS)
          110  +#-----------------------------------------------------------------------
          111  +
          112  +#-----------------------------------------------------------------------
          113  +#   --enable-fts4
          114  +#
          115  +AC_ARG_ENABLE(fts4, [AS_HELP_STRING(
          116  +  [--enable-fts4], [include fts4 support [default=yes]])], 
          117  +  [], [enable_fts4=yes])
          118  +if test x"$enable_fts4" = "xyes"; then
          119  +  BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_ENABLE_FTS4"
          120  +fi
          121  +#-----------------------------------------------------------------------
          122  +
          123  +#-----------------------------------------------------------------------
          124  +#   --enable-fts3
          125  +#
          126  +AC_ARG_ENABLE(fts3, [AS_HELP_STRING(
          127  +  [--enable-fts3], [include fts3 support [default=no]])], 
          128  +  [], [])
          129  +if test x"$enable_fts3" = "xyes" -a x"$enable_fts4" = "xno"; then
          130  +  BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_ENABLE_FTS3"
          131  +fi
   111    132   #-----------------------------------------------------------------------
   112    133   
   113    134   #-----------------------------------------------------------------------
   114    135   #   --enable-fts5
   115    136   #
   116    137   AC_ARG_ENABLE(fts5, [AS_HELP_STRING(
   117         -  [--enable-fts5], [include fts5 support [default=no]])], 
   118         -  [], [enable_fts5=no])
          138  +  [--enable-fts5], [include fts5 support [default=yes]])], 
          139  +  [], [enable_fts5=yes])
   119    140   if test x"$enable_fts5" = "xyes"; then
   120    141     AC_SEARCH_LIBS(log, m)
   121         -  FTS5_FLAGS=-DSQLITE_ENABLE_FTS5
          142  +  BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_ENABLE_FTS5"
   122    143   fi
   123         -AC_SUBST(FTS5_FLAGS)
   124    144   #-----------------------------------------------------------------------
   125    145   
   126    146   #-----------------------------------------------------------------------
   127    147   #   --enable-json1
   128    148   #
   129    149   AC_ARG_ENABLE(json1, [AS_HELP_STRING(
   130         -  [--enable-json1], [include json1 support [default=no]])], 
   131         -  [], [enable_json1=no])
          150  +  [--enable-json1], [include json1 support [default=yes]])], 
          151  +  [],[enable_json1=yes])
   132    152   if test x"$enable_json1" = "xyes"; then
   133         -  JSON1_FLAGS=-DSQLITE_ENABLE_JSON1
          153  +  BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_ENABLE_JSON1"
   134    154   fi
   135         -AC_SUBST(JSON1_FLAGS)
          155  +#-----------------------------------------------------------------------
          156  +
          157  +#-----------------------------------------------------------------------
          158  +#   --enable-rtree
          159  +#
          160  +AC_ARG_ENABLE(rtree, [AS_HELP_STRING(
          161  +  [--enable-rtree], [include rtree support [default=yes]])], 
          162  +  [], [enable_rtree=yes])
          163  +if test x"$enable_rtree" = "xyes"; then
          164  +  BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_ENABLE_RTREE"
          165  +fi
   136    166   #-----------------------------------------------------------------------
   137    167   
   138    168   #-----------------------------------------------------------------------
   139    169   #   --enable-session
   140    170   #
   141    171   AC_ARG_ENABLE(session, [AS_HELP_STRING(
   142    172     [--enable-session], [enable the session extension [default=no]])], 
   143         -  [], [enable_session=no])
          173  +  [], [])
   144    174   if test x"$enable_session" = "xyes"; then
   145         -  SESSION_FLAGS="-DSQLITE_ENABLE_SESSION -DSQLITE_ENABLE_PREUPDATE_HOOK"
          175  +  BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_ENABLE_SESSION -DSQLITE_ENABLE_PREUPDATE_HOOK"
   146    176   fi
   147         -AC_SUBST(SESSION_FLAGS)
          177  +#-----------------------------------------------------------------------
          178  +
          179  +#-----------------------------------------------------------------------
          180  +#   --enable-debug
          181  +#
          182  +AC_ARG_ENABLE(debug, [AS_HELP_STRING(
          183  +  [--enable-debug], [build with debugging features enabled [default=no]])], 
          184  +  [], [])
          185  +if test x"$enable_debug" = "xyes"; then
          186  +  BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_DEBUG -DSQLITE_ENABLE_SELECTTRACE -DSQLITE_ENABLE_WHERETRACE"
          187  +  CFLAGS="-g -O0"
          188  +fi
   148    189   #-----------------------------------------------------------------------
   149    190   
   150    191   #-----------------------------------------------------------------------
   151    192   #   --enable-static-shell
   152    193   #
   153    194   AC_ARG_ENABLE(static-shell, [AS_HELP_STRING(
   154    195     [--enable-static-shell], 
................................................................................
   159    200   else
   160    201     EXTRA_SHELL_OBJ=libsqlite3.la
   161    202   fi
   162    203   AC_SUBST(EXTRA_SHELL_OBJ)
   163    204   #-----------------------------------------------------------------------
   164    205   
   165    206   AC_CHECK_FUNCS(posix_fallocate)
          207  +AC_CHECK_HEADERS(zlib.h,[
          208  +  AC_SEARCH_LIBS(deflate,z,[BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_HAVE_ZLIB"])
          209  +])
          210  +
          211  +AC_SEARCH_LIBS(system,,,[SHELL_CFLAGS="-DSQLITE_NOHAVE_SYSTEM"])
          212  +AC_SUBST(SHELL_CFLAGS)
   166    213   
   167    214   #-----------------------------------------------------------------------
   168    215   # UPDATE: Maybe it's better if users just set CFLAGS before invoking
   169    216   # configure. This option doesn't really add much...
   170    217   #
   171    218   #   --enable-tempstore
   172    219   #

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.21.0.
            3  +# Generated by GNU Autoconf 2.69 for sqlite 3.26.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.21.0'
   730         -PACKAGE_STRING='sqlite 3.21.0'
          729  +PACKAGE_VERSION='3.26.0'
          730  +PACKAGE_STRING='sqlite 3.26.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
................................................................................
   768    768   #endif"
   769    769   
   770    770   ac_subst_vars='LTLIBOBJS
   771    771   LIBOBJS
   772    772   BUILD_CFLAGS
   773    773   USE_GCOV
   774    774   OPT_FEATURE_FLAGS
          775  +HAVE_ZLIB
   775    776   USE_AMALGAMATION
   776    777   TARGET_DEBUG
   777    778   TARGET_HAVE_EDITLINE
   778    779   TARGET_HAVE_READLINE
   779    780   TARGET_READLINE_INC
   780    781   TARGET_READLINE_LIBS
   781    782   HAVE_TCL
................................................................................
   905    906   enable_load_extension
   906    907   enable_memsys5
   907    908   enable_memsys3
   908    909   enable_fts3
   909    910   enable_fts4
   910    911   enable_fts5
   911    912   enable_json1
          913  +enable_update_limit
          914  +enable_geopoly
   912    915   enable_rtree
   913    916   enable_session
   914    917   enable_gcov
   915    918   '
   916    919         ac_precious_vars='build_alias
   917    920   host_alias
   918    921   target_alias
................................................................................
  1459   1462   #
  1460   1463   # Report the --help message.
  1461   1464   #
  1462   1465   if test "$ac_init_help" = "long"; then
  1463   1466     # Omit some internal or obsolete options to make the list less imposing.
  1464   1467     # This message is too long to be a string in the A/UX 3.1 sh.
  1465   1468     cat <<_ACEOF
  1466         -\`configure' configures sqlite 3.21.0 to adapt to many kinds of systems.
         1469  +\`configure' configures sqlite 3.26.0 to adapt to many kinds of systems.
  1467   1470   
  1468   1471   Usage: $0 [OPTION]... [VAR=VALUE]...
  1469   1472   
  1470   1473   To assign environment variables (e.g., CC, CFLAGS...), specify them as
  1471   1474   VAR=VALUE.  See below for descriptions of some of the useful variables.
  1472   1475   
  1473   1476   Defaults for the options are specified in brackets.
................................................................................
  1524   1527     --build=BUILD     configure for building on BUILD [guessed]
  1525   1528     --host=HOST       cross-compile to build programs to run on HOST [BUILD]
  1526   1529   _ACEOF
  1527   1530   fi
  1528   1531   
  1529   1532   if test -n "$ac_init_help"; then
  1530   1533     case $ac_init_help in
  1531         -     short | recursive ) echo "Configuration of sqlite 3.21.0:";;
         1534  +     short | recursive ) echo "Configuration of sqlite 3.26.0:";;
  1532   1535      esac
  1533   1536     cat <<\_ACEOF
  1534   1537   
  1535   1538   Optional Features:
  1536   1539     --disable-option-checking  ignore unrecognized --enable/--with options
  1537   1540     --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
  1538   1541     --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
................................................................................
  1556   1559                             Disable loading of external extensions
  1557   1560     --enable-memsys5        Enable MEMSYS5
  1558   1561     --enable-memsys3        Enable MEMSYS3
  1559   1562     --enable-fts3           Enable the FTS3 extension
  1560   1563     --enable-fts4           Enable the FTS4 extension
  1561   1564     --enable-fts5           Enable the FTS5 extension
  1562   1565     --enable-json1          Enable the JSON1 extension
         1566  +  --enable-update-limit   Enable the UPDATE/DELETE LIMIT clause
         1567  +  --enable-geopoly        Enable the GEOPOLY extension
  1563   1568     --enable-rtree          Enable the RTREE extension
  1564   1569     --enable-session        Enable the SESSION extension
  1565   1570     --enable-gcov           Enable coverage testing using gcov
  1566   1571   
  1567   1572   Optional Packages:
  1568   1573     --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
  1569   1574     --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
................................................................................
  1648   1653       cd "$ac_pwd" || { ac_status=$?; break; }
  1649   1654     done
  1650   1655   fi
  1651   1656   
  1652   1657   test -n "$ac_init_help" && exit $ac_status
  1653   1658   if $ac_init_version; then
  1654   1659     cat <<\_ACEOF
  1655         -sqlite configure 3.21.0
         1660  +sqlite configure 3.26.0
  1656   1661   generated by GNU Autoconf 2.69
  1657   1662   
  1658   1663   Copyright (C) 2012 Free Software Foundation, Inc.
  1659   1664   This configure script is free software; the Free Software Foundation
  1660   1665   gives unlimited permission to copy, distribute and modify it.
  1661   1666   _ACEOF
  1662   1667     exit
................................................................................
  2067   2072     eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
  2068   2073   
  2069   2074   } # ac_fn_c_check_header_mongrel
  2070   2075   cat >config.log <<_ACEOF
  2071   2076   This file contains any messages produced by compilers while
  2072   2077   running configure, to aid debugging if configure makes a mistake.
  2073   2078   
  2074         -It was created by sqlite $as_me 3.21.0, which was
         2079  +It was created by sqlite $as_me 3.26.0, which was
  2075   2080   generated by GNU Autoconf 2.69.  Invocation command line was
  2076   2081   
  2077   2082     $ $0 $@
  2078   2083   
  2079   2084   _ACEOF
  2080   2085   exec 5>>config.log
  2081   2086   {
................................................................................
  3925   3930   { $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5
  3926   3931   $as_echo_n "checking the name lister ($NM) interface... " >&6; }
  3927   3932   if ${lt_cv_nm_interface+:} false; then :
  3928   3933     $as_echo_n "(cached) " >&6
  3929   3934   else
  3930   3935     lt_cv_nm_interface="BSD nm"
  3931   3936     echo "int some_variable = 0;" > conftest.$ac_ext
  3932         -  (eval echo "\"\$as_me:3932: $ac_compile\"" >&5)
         3937  +  (eval echo "\"\$as_me:3937: $ac_compile\"" >&5)
  3933   3938     (eval "$ac_compile" 2>conftest.err)
  3934   3939     cat conftest.err >&5
  3935         -  (eval echo "\"\$as_me:3935: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
         3940  +  (eval echo "\"\$as_me:3940: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
  3936   3941     (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
  3937   3942     cat conftest.err >&5
  3938         -  (eval echo "\"\$as_me:3938: output\"" >&5)
         3943  +  (eval echo "\"\$as_me:3943: output\"" >&5)
  3939   3944     cat conftest.out >&5
  3940   3945     if $GREP 'External.*some_variable' conftest.out > /dev/null; then
  3941   3946       lt_cv_nm_interface="MS dumpbin"
  3942   3947     fi
  3943   3948     rm -f conftest*
  3944   3949   fi
  3945   3950   { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5
................................................................................
  5137   5142   	;;
  5138   5143       esac
  5139   5144     fi
  5140   5145     rm -rf conftest*
  5141   5146     ;;
  5142   5147   *-*-irix6*)
  5143   5148     # Find out which ABI we are using.
  5144         -  echo '#line 5144 "configure"' > conftest.$ac_ext
         5149  +  echo '#line 5149 "configure"' > conftest.$ac_ext
  5145   5150     if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
  5146   5151     (eval $ac_compile) 2>&5
  5147   5152     ac_status=$?
  5148   5153     $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
  5149   5154     test $ac_status = 0; }; then
  5150   5155       if test "$lt_cv_prog_gnu_ld" = yes; then
  5151   5156         case `/usr/bin/file conftest.$ac_objext` in
................................................................................
  6662   6667      # Note that $ac_compile itself does not contain backslashes and begins
  6663   6668      # with a dollar sign (not a hyphen), so the echo should work correctly.
  6664   6669      # The option is referenced via a variable to avoid confusing sed.
  6665   6670      lt_compile=`echo "$ac_compile" | $SED \
  6666   6671      -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
  6667   6672      -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
  6668   6673      -e 's:$: $lt_compiler_flag:'`
  6669         -   (eval echo "\"\$as_me:6669: $lt_compile\"" >&5)
         6674  +   (eval echo "\"\$as_me:6674: $lt_compile\"" >&5)
  6670   6675      (eval "$lt_compile" 2>conftest.err)
  6671   6676      ac_status=$?
  6672   6677      cat conftest.err >&5
  6673         -   echo "$as_me:6673: \$? = $ac_status" >&5
         6678  +   echo "$as_me:6678: \$? = $ac_status" >&5
  6674   6679      if (exit $ac_status) && test -s "$ac_outfile"; then
  6675   6680        # The compiler can only warn and ignore the option if not recognized
  6676   6681        # So say no if there are warnings other than the usual output.
  6677   6682        $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp
  6678   6683        $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
  6679   6684        if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
  6680   6685          lt_cv_prog_compiler_rtti_exceptions=yes
................................................................................
  7001   7006      # Note that $ac_compile itself does not contain backslashes and begins
  7002   7007      # with a dollar sign (not a hyphen), so the echo should work correctly.
  7003   7008      # The option is referenced via a variable to avoid confusing sed.
  7004   7009      lt_compile=`echo "$ac_compile" | $SED \
  7005   7010      -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
  7006   7011      -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
  7007   7012      -e 's:$: $lt_compiler_flag:'`
  7008         -   (eval echo "\"\$as_me:7008: $lt_compile\"" >&5)
         7013  +   (eval echo "\"\$as_me:7013: $lt_compile\"" >&5)
  7009   7014      (eval "$lt_compile" 2>conftest.err)
  7010   7015      ac_status=$?
  7011   7016      cat conftest.err >&5
  7012         -   echo "$as_me:7012: \$? = $ac_status" >&5
         7017  +   echo "$as_me:7017: \$? = $ac_status" >&5
  7013   7018      if (exit $ac_status) && test -s "$ac_outfile"; then
  7014   7019        # The compiler can only warn and ignore the option if not recognized
  7015   7020        # So say no if there are warnings other than the usual output.
  7016   7021        $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp
  7017   7022        $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
  7018   7023        if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
  7019   7024          lt_cv_prog_compiler_pic_works=yes
................................................................................
  7106   7111      # (2) before a word containing "conftest.", or (3) at the end.
  7107   7112      # Note that $ac_compile itself does not contain backslashes and begins
  7108   7113      # with a dollar sign (not a hyphen), so the echo should work correctly.
  7109   7114      lt_compile=`echo "$ac_compile" | $SED \
  7110   7115      -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
  7111   7116      -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
  7112   7117      -e 's:$: $lt_compiler_flag:'`
  7113         -   (eval echo "\"\$as_me:7113: $lt_compile\"" >&5)
         7118  +   (eval echo "\"\$as_me:7118: $lt_compile\"" >&5)
  7114   7119      (eval "$lt_compile" 2>out/conftest.err)
  7115   7120      ac_status=$?
  7116   7121      cat out/conftest.err >&5
  7117         -   echo "$as_me:7117: \$? = $ac_status" >&5
         7122  +   echo "$as_me:7122: \$? = $ac_status" >&5
  7118   7123      if (exit $ac_status) && test -s out/conftest2.$ac_objext
  7119   7124      then
  7120   7125        # The compiler can only warn and ignore the option if not recognized
  7121   7126        # So say no if there are warnings
  7122   7127        $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp
  7123   7128        $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
  7124   7129        if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
................................................................................
  7161   7166      # (2) before a word containing "conftest.", or (3) at the end.
  7162   7167      # Note that $ac_compile itself does not contain backslashes and begins
  7163   7168      # with a dollar sign (not a hyphen), so the echo should work correctly.
  7164   7169      lt_compile=`echo "$ac_compile" | $SED \
  7165   7170      -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
  7166   7171      -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
  7167   7172      -e 's:$: $lt_compiler_flag:'`
  7168         -   (eval echo "\"\$as_me:7168: $lt_compile\"" >&5)
         7173  +   (eval echo "\"\$as_me:7173: $lt_compile\"" >&5)
  7169   7174      (eval "$lt_compile" 2>out/conftest.err)
  7170   7175      ac_status=$?
  7171   7176      cat out/conftest.err >&5
  7172         -   echo "$as_me:7172: \$? = $ac_status" >&5
         7177  +   echo "$as_me:7177: \$? = $ac_status" >&5
  7173   7178      if (exit $ac_status) && test -s out/conftest2.$ac_objext
  7174   7179      then
  7175   7180        # The compiler can only warn and ignore the option if not recognized
  7176   7181        # So say no if there are warnings
  7177   7182        $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp
  7178   7183        $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
  7179   7184        if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
................................................................................
  9541   9546   else
  9542   9547     	  if test "$cross_compiling" = yes; then :
  9543   9548     lt_cv_dlopen_self=cross
  9544   9549   else
  9545   9550     lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
  9546   9551     lt_status=$lt_dlunknown
  9547   9552     cat > conftest.$ac_ext <<_LT_EOF
  9548         -#line 9548 "configure"
         9553  +#line 9553 "configure"
  9549   9554   #include "confdefs.h"
  9550   9555   
  9551   9556   #if HAVE_DLFCN_H
  9552   9557   #include <dlfcn.h>
  9553   9558   #endif
  9554   9559   
  9555   9560   #include <stdio.h>
................................................................................
  9637   9642   else
  9638   9643     	  if test "$cross_compiling" = yes; then :
  9639   9644     lt_cv_dlopen_self_static=cross
  9640   9645   else
  9641   9646     lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
  9642   9647     lt_status=$lt_dlunknown
  9643   9648     cat > conftest.$ac_ext <<_LT_EOF
  9644         -#line 9644 "configure"
         9649  +#line 9649 "configure"
  9645   9650   #include "confdefs.h"
  9646   9651   
  9647   9652   #if HAVE_DLFCN_H
  9648   9653   #include <dlfcn.h>
  9649   9654   #endif
  9650   9655   
  9651   9656   #include <stdio.h>
................................................................................
 10298  10303   USE_AMALGAMATION=1
 10299  10304   
 10300  10305   #########
 10301  10306   # See whether we can run specific tclsh versions known to work well;
 10302  10307   # if not, then we fall back to plain tclsh.
 10303  10308   # TODO: try other versions before falling back?
 10304  10309   #
 10305         -for ac_prog in tclsh8.6 tclsh8.5 tclsh
        10310  +for ac_prog in tclsh8.7 tclsh8.6 tclsh8.5 tclsh
 10306  10311   do
 10307  10312     # Extract the first word of "$ac_prog", so it can be a program name with args.
 10308  10313   set dummy $ac_prog; ac_word=$2
 10309  10314   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 10310  10315   $as_echo_n "checking for $ac_word... " >&6; }
 10311  10316   if ${ac_cv_prog_TCLSH_CMD+:} false; then :
 10312  10317     $as_echo_n "(cached) " >&6
................................................................................
 10448  10453   
 10449  10454   ##########
 10450  10455   # Do we want to support multithreaded use of sqlite
 10451  10456   #
 10452  10457   # Check whether --enable-threadsafe was given.
 10453  10458   if test "${enable_threadsafe+set}" = set; then :
 10454  10459     enableval=$enable_threadsafe;
 10455         -else
 10456         -  enable_threadsafe=yes
 10457  10460   fi
 10458  10461   
 10459  10462   { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to support threadsafe operation" >&5
 10460  10463   $as_echo_n "checking whether to support threadsafe operation... " >&6; }
 10461  10464   if test "$enable_threadsafe" = "no"; then
 10462  10465     SQLITE_THREADSAFE=0
 10463  10466     { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
................................................................................
 11242  11245   fi
 11243  11246   
 11244  11247   
 11245  11248   #########
 11246  11249   # check for debug enabled
 11247  11250   # Check whether --enable-debug was given.
 11248  11251   if test "${enable_debug+set}" = set; then :
 11249         -  enableval=$enable_debug; use_debug=$enableval
 11250         -else
 11251         -  use_debug=no
        11252  +  enableval=$enable_debug;
 11252  11253   fi
 11253  11254   
 11254         -if test "${use_debug}" = "yes" ; then
        11255  +if test "${enable_debug}" = "yes" ; then
 11255  11256     TARGET_DEBUG="-DSQLITE_DEBUG=1 -DSQLITE_ENABLE_SELECTTRACE -DSQLITE_ENABLE_WHERETRACE -O0"
 11256  11257   else
 11257  11258     TARGET_DEBUG="-DNDEBUG"
 11258  11259   fi
 11259  11260   
 11260  11261   
 11261  11262   #########
 11262  11263   # See whether we should use the amalgamation to build
 11263  11264   # Check whether --enable-amalgamation was given.
 11264  11265   if test "${enable_amalgamation+set}" = set; then :
 11265         -  enableval=$enable_amalgamation; use_amalgamation=$enableval
 11266         -else
 11267         -  use_amalgamation=yes
        11266  +  enableval=$enable_amalgamation;
 11268  11267   fi
 11269  11268   
 11270         -if test "${use_amalgamation}" != "yes" ; then
        11269  +if test "${enable_amalgamation}" == "no" ; then
 11271  11270     USE_AMALGAMATION=0
 11272  11271   fi
        11272  +
        11273  +
        11274  +#########
        11275  +# Look for zlib.  Only needed by extensions and by the sqlite3.exe shell
        11276  +for ac_header in zlib.h
        11277  +do :
        11278  +  ac_fn_c_check_header_mongrel "$LINENO" "zlib.h" "ac_cv_header_zlib_h" "$ac_includes_default"
        11279  +if test "x$ac_cv_header_zlib_h" = xyes; then :
        11280  +  cat >>confdefs.h <<_ACEOF
        11281  +#define HAVE_ZLIB_H 1
        11282  +_ACEOF
        11283  +
        11284  +fi
        11285  +
        11286  +done
        11287  +
        11288  +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing deflate" >&5
        11289  +$as_echo_n "checking for library containing deflate... " >&6; }
        11290  +if ${ac_cv_search_deflate+:} false; then :
        11291  +  $as_echo_n "(cached) " >&6
        11292  +else
        11293  +  ac_func_search_save_LIBS=$LIBS
        11294  +cat confdefs.h - <<_ACEOF >conftest.$ac_ext
        11295  +/* end confdefs.h.  */
        11296  +
        11297  +/* Override any GCC internal prototype to avoid an error.
        11298  +   Use char because int might match the return type of a GCC
        11299  +   builtin and then its argument prototype would still apply.  */
        11300  +#ifdef __cplusplus
        11301  +extern "C"
        11302  +#endif
        11303  +char deflate ();
        11304  +int
        11305  +main ()
        11306  +{
        11307  +return deflate ();
        11308  +  ;
        11309  +  return 0;
        11310  +}
        11311  +_ACEOF
        11312  +for ac_lib in '' z; do
        11313  +  if test -z "$ac_lib"; then
        11314  +    ac_res="none required"
        11315  +  else
        11316  +    ac_res=-l$ac_lib
        11317  +    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
        11318  +  fi
        11319  +  if ac_fn_c_try_link "$LINENO"; then :
        11320  +  ac_cv_search_deflate=$ac_res
        11321  +fi
        11322  +rm -f core conftest.err conftest.$ac_objext \
        11323  +    conftest$ac_exeext
        11324  +  if ${ac_cv_search_deflate+:} false; then :
        11325  +  break
        11326  +fi
        11327  +done
        11328  +if ${ac_cv_search_deflate+:} false; then :
        11329  +
        11330  +else
        11331  +  ac_cv_search_deflate=no
        11332  +fi
        11333  +rm conftest.$ac_ext
        11334  +LIBS=$ac_func_search_save_LIBS
        11335  +fi
        11336  +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_deflate" >&5
        11337  +$as_echo "$ac_cv_search_deflate" >&6; }
        11338  +ac_res=$ac_cv_search_deflate
        11339  +if test "$ac_res" != no; then :
        11340  +  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
        11341  +  HAVE_ZLIB="-DSQLITE_HAVE_ZLIB=1"
        11342  +else
        11343  +  HAVE_ZLIB=""
        11344  +fi
        11345  +
 11273  11346   
 11274  11347   
 11275  11348   #########
 11276  11349   # See whether we should allow loadable extensions
 11277  11350   # Check whether --enable-load-extension was given.
 11278  11351   if test "${enable_load_extension+set}" = set; then :
 11279         -  enableval=$enable_load_extension; use_loadextension=$enableval
        11352  +  enableval=$enable_load_extension;
 11280  11353   else
 11281         -  use_loadextension=yes
        11354  +  enable_load_extension=yes
 11282  11355   fi
 11283  11356   
 11284         -if test "${use_loadextension}" = "yes" ; then
        11357  +if test "${enable_load_extension}" = "yes" ; then
 11285  11358     OPT_FEATURE_FLAGS=""
 11286  11359     { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing dlopen" >&5
 11287  11360   $as_echo_n "checking for library containing dlopen... " >&6; }
 11288  11361   if ${ac_cv_search_dlopen+:} false; then :
 11289  11362     $as_echo_n "(cached) " >&6
 11290  11363   else
 11291  11364     ac_func_search_save_LIBS=$LIBS
................................................................................
 11344  11417   fi
 11345  11418   
 11346  11419   ##########
 11347  11420   # Do we want to support memsys3 and/or memsys5
 11348  11421   #
 11349  11422   # Check whether --enable-memsys5 was given.
 11350  11423   if test "${enable_memsys5+set}" = set; then :
 11351         -  enableval=$enable_memsys5; enable_memsys5=yes
 11352         -else
 11353         -  enable_memsys5=no
        11424  +  enableval=$enable_memsys5;
 11354  11425   fi
 11355  11426   
 11356  11427   { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to support MEMSYS5" >&5
 11357  11428   $as_echo_n "checking whether to support MEMSYS5... " >&6; }
 11358  11429   if test "${enable_memsys5}" = "yes"; then
 11359  11430     OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_MEMSYS5"
 11360  11431     { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
................................................................................
 11361  11432   $as_echo "yes" >&6; }
 11362  11433   else
 11363  11434     { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
 11364  11435   $as_echo "no" >&6; }
 11365  11436   fi
 11366  11437   # Check whether --enable-memsys3 was given.
 11367  11438   if test "${enable_memsys3+set}" = set; then :
 11368         -  enableval=$enable_memsys3; enable_memsys3=yes
 11369         -else
 11370         -  enable_memsys3=no
        11439  +  enableval=$enable_memsys3;
 11371  11440   fi
 11372  11441   
 11373  11442   { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to support MEMSYS3" >&5
 11374  11443   $as_echo_n "checking whether to support MEMSYS3... " >&6; }
 11375  11444   if test "${enable_memsys3}" = "yes" -a "${enable_memsys5}" = "no"; then
 11376  11445     OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_MEMSYS3"
 11377  11446     { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
................................................................................
 11381  11450   $as_echo "no" >&6; }
 11382  11451   fi
 11383  11452   
 11384  11453   #########
 11385  11454   # See whether we should enable Full Text Search extensions
 11386  11455   # Check whether --enable-fts3 was given.
 11387  11456   if test "${enable_fts3+set}" = set; then :
 11388         -  enableval=$enable_fts3; enable_fts3=yes
 11389         -else
 11390         -  enable_fts3=no
        11457  +  enableval=$enable_fts3;
 11391  11458   fi
 11392  11459   
 11393  11460   if test "${enable_fts3}" = "yes" ; then
 11394  11461     OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_FTS3"
 11395  11462   fi
 11396  11463   # Check whether --enable-fts4 was given.
 11397  11464   if test "${enable_fts4+set}" = set; then :
 11398         -  enableval=$enable_fts4; enable_fts4=yes
 11399         -else
 11400         -  enable_fts4=no
        11465  +  enableval=$enable_fts4;
 11401  11466   fi
 11402  11467   
 11403  11468   if test "${enable_fts4}" = "yes" ; then
 11404  11469     OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_FTS4"
 11405  11470     { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing log" >&5
 11406  11471   $as_echo_n "checking for library containing log... " >&6; }
 11407  11472   if ${ac_cv_search_log+:} false; then :
................................................................................
 11457  11522     test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
 11458  11523   
 11459  11524   fi
 11460  11525   
 11461  11526   fi
 11462  11527   # Check whether --enable-fts5 was given.
 11463  11528   if test "${enable_fts5+set}" = set; then :
 11464         -  enableval=$enable_fts5; enable_fts5=yes
 11465         -else
 11466         -  enable_fts5=no
        11529  +  enableval=$enable_fts5;
 11467  11530   fi
 11468  11531   
 11469  11532   if test "${enable_fts5}" = "yes" ; then
 11470  11533     OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_FTS5"
 11471  11534     { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing log" >&5
 11472  11535   $as_echo_n "checking for library containing log... " >&6; }
 11473  11536   if ${ac_cv_search_log+:} false; then :
................................................................................
 11526  11589   
 11527  11590   fi
 11528  11591   
 11529  11592   #########
 11530  11593   # See whether we should enable JSON1
 11531  11594   # Check whether --enable-json1 was given.
 11532  11595   if test "${enable_json1+set}" = set; then :
 11533         -  enableval=$enable_json1; enable_json1=yes
 11534         -else
 11535         -  enable_json1=no
        11596  +  enableval=$enable_json1;
 11536  11597   fi
 11537  11598   
 11538  11599   if test "${enable_json1}" = "yes" ; then
 11539  11600     OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_JSON1"
 11540  11601   fi
        11602  +
        11603  +#########
        11604  +# See whether we should enable the LIMIT clause on UPDATE and DELETE
        11605  +# statements.
        11606  +# Check whether --enable-update-limit was given.
        11607  +if test "${enable_update_limit+set}" = set; then :
        11608  +  enableval=$enable_update_limit;
        11609  +fi
        11610  +
        11611  +if test "${enable_udlimit}" = "yes" ; then
        11612  +  OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_UPDATE_DELETE_LIMIT"
        11613  +fi
        11614  +
        11615  +#########
        11616  +# See whether we should enable GEOPOLY
        11617  +# Check whether --enable-geopoly was given.
        11618  +if test "${enable_geopoly+set}" = set; then :
        11619  +  enableval=$enable_geopoly; enable_geopoly=yes
        11620  +else
        11621  +  enable_geopoly=no
        11622  +fi
        11623  +
        11624  +if test "${enable_geopoly}" = "yes" ; then
        11625  +  OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_GEOPOLY"
        11626  +  enable_rtree=yes
        11627  +fi
 11541  11628   
 11542  11629   #########
 11543  11630   # See whether we should enable RTREE
 11544  11631   # Check whether --enable-rtree was given.
 11545  11632   if test "${enable_rtree+set}" = set; then :
 11546         -  enableval=$enable_rtree; enable_rtree=yes
 11547         -else
 11548         -  enable_rtree=no
        11633  +  enableval=$enable_rtree;
 11549  11634   fi
 11550  11635   
 11551  11636   if test "${enable_rtree}" = "yes" ; then
 11552  11637     OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_RTREE"
 11553  11638   fi
 11554  11639   
 11555  11640   #########
 11556  11641   # See whether we should enable the SESSION extension
 11557  11642   # Check whether --enable-session was given.
 11558  11643   if test "${enable_session+set}" = set; then :
 11559         -  enableval=$enable_session; enable_session=yes
 11560         -else
 11561         -  enable_session=no
        11644  +  enableval=$enable_session;
 11562  11645   fi
 11563  11646   
 11564  11647   if test "${enable_session}" = "yes" ; then
 11565  11648     OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_SESSION"
 11566  11649     OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_PREUPDATE_HOOK"
 11567  11650   fi
 11568  11651   
................................................................................
 11617  11700   BUILD_CFLAGS=$ac_temp_BUILD_CFLAGS
 11618  11701   
 11619  11702   
 11620  11703   #########
 11621  11704   # See whether we should use GCOV
 11622  11705   # Check whether --enable-gcov was given.
 11623  11706   if test "${enable_gcov+set}" = set; then :
 11624         -  enableval=$enable_gcov; use_gcov=$enableval
 11625         -else
 11626         -  use_gcov=no
        11707  +  enableval=$enable_gcov;
 11627  11708   fi
 11628  11709   
 11629  11710   if test "${use_gcov}" = "yes" ; then
 11630  11711     USE_GCOV=1
 11631  11712   else
 11632  11713     USE_GCOV=0
 11633  11714   fi
................................................................................
 12147  12228   test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1
 12148  12229   
 12149  12230   cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 12150  12231   # Save the log message, to keep $0 and so on meaningful, and to
 12151  12232   # report actual input values of CONFIG_FILES etc. instead of their
 12152  12233   # values after options handling.
 12153  12234   ac_log="
 12154         -This file was extended by sqlite $as_me 3.21.0, which was
        12235  +This file was extended by sqlite $as_me 3.26.0, which was
 12155  12236   generated by GNU Autoconf 2.69.  Invocation command line was
 12156  12237   
 12157  12238     CONFIG_FILES    = $CONFIG_FILES
 12158  12239     CONFIG_HEADERS  = $CONFIG_HEADERS
 12159  12240     CONFIG_LINKS    = $CONFIG_LINKS
 12160  12241     CONFIG_COMMANDS = $CONFIG_COMMANDS
 12161  12242     $ $0 $@
................................................................................
 12213  12294   
 12214  12295   Report bugs to the package provider."
 12215  12296   
 12216  12297   _ACEOF
 12217  12298   cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 12218  12299   ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 12219  12300   ac_cs_version="\\
 12220         -sqlite config.status 3.21.0
        12301  +sqlite config.status 3.26.0
 12221  12302   configured by $0, generated by GNU Autoconf 2.69,
 12222  12303     with options \\"\$ac_cs_config\\"
 12223  12304   
 12224  12305   Copyright (C) 2012 Free Software Foundation, Inc.
 12225  12306   This config.status script is free software; the Free Software Foundation
 12226  12307   gives unlimited permission to copy, distribute and modify it."
 12227  12308   

Changes to configure.ac.

   116    116   USE_AMALGAMATION=1
   117    117   
   118    118   #########
   119    119   # See whether we can run specific tclsh versions known to work well;
   120    120   # if not, then we fall back to plain tclsh.
   121    121   # TODO: try other versions before falling back?
   122    122   # 
   123         -AC_CHECK_PROGS(TCLSH_CMD, [tclsh8.6 tclsh8.5 tclsh], none)
          123  +AC_CHECK_PROGS(TCLSH_CMD, [tclsh8.7 tclsh8.6 tclsh8.5 tclsh], none)
   124    124   if test "$TCLSH_CMD" = "none"; then
   125    125     # If we can't find a local tclsh, then building the amalgamation will fail.
   126    126     # We act as though --disable-amalgamation has been used.
   127    127     echo "Warning: can't find tclsh - defaulting to non-amalgamation build."
   128    128     USE_AMALGAMATION=0
   129    129     TCLSH_CMD="tclsh"
   130    130   fi
................................................................................
   178    178   fi
   179    179   AC_SUBST(BUILD_CC)
   180    180   
   181    181   ##########
   182    182   # Do we want to support multithreaded use of sqlite
   183    183   #
   184    184   AC_ARG_ENABLE(threadsafe, 
   185         -AC_HELP_STRING([--disable-threadsafe],[Disable mutexing]),,enable_threadsafe=yes)
          185  +AC_HELP_STRING([--disable-threadsafe],[Disable mutexing]))
   186    186   AC_MSG_CHECKING([whether to support threadsafe operation])
   187    187   if test "$enable_threadsafe" = "no"; then
   188    188     SQLITE_THREADSAFE=0
   189    189     AC_MSG_RESULT([no])
   190    190   else
   191    191     SQLITE_THREADSAFE=1
   192    192     AC_MSG_RESULT([yes])
................................................................................
   553    553   # Figure out what C libraries are required to compile programs
   554    554   # that use "fdatasync()" function.
   555    555   #
   556    556   AC_SEARCH_LIBS(fdatasync, [rt])
   557    557   
   558    558   #########
   559    559   # check for debug enabled
   560         -AC_ARG_ENABLE(debug, AC_HELP_STRING([--enable-debug],[enable debugging & verbose explain]),
   561         -      [use_debug=$enableval],[use_debug=no])
   562         -if test "${use_debug}" = "yes" ; then
          560  +AC_ARG_ENABLE(debug, AC_HELP_STRING([--enable-debug],[enable debugging & verbose explain]))
          561  +if test "${enable_debug}" = "yes" ; then
   563    562     TARGET_DEBUG="-DSQLITE_DEBUG=1 -DSQLITE_ENABLE_SELECTTRACE -DSQLITE_ENABLE_WHERETRACE -O0"
   564    563   else
   565    564     TARGET_DEBUG="-DNDEBUG"
   566    565   fi
   567    566   AC_SUBST(TARGET_DEBUG)
   568    567   
   569    568   #########
   570    569   # See whether we should use the amalgamation to build
   571    570   AC_ARG_ENABLE(amalgamation, AC_HELP_STRING([--disable-amalgamation],
   572         -      [Disable the amalgamation and instead build all files separately]),
   573         -      [use_amalgamation=$enableval],[use_amalgamation=yes])
   574         -if test "${use_amalgamation}" != "yes" ; then
          571  +      [Disable the amalgamation and instead build all files separately]))
          572  +if test "${enable_amalgamation}" == "no" ; then
   575    573     USE_AMALGAMATION=0
   576    574   fi
   577    575   AC_SUBST(USE_AMALGAMATION)
   578    576   
          577  +#########
          578  +# Look for zlib.  Only needed by extensions and by the sqlite3.exe shell
          579  +AC_CHECK_HEADERS(zlib.h)
          580  +AC_SEARCH_LIBS(deflate, z, [HAVE_ZLIB="-DSQLITE_HAVE_ZLIB=1"], [HAVE_ZLIB=""])
          581  +AC_SUBST(HAVE_ZLIB)
          582  +
   579    583   #########
   580    584   # See whether we should allow loadable extensions
   581    585   AC_ARG_ENABLE(load-extension, AC_HELP_STRING([--disable-load-extension],
   582         -      [Disable loading of external extensions]),
   583         -      [use_loadextension=$enableval],[use_loadextension=yes])
   584         -if test "${use_loadextension}" = "yes" ; then
          586  +      [Disable loading of external extensions]),,[enable_load_extension=yes])
          587  +if test "${enable_load_extension}" = "yes" ; then
   585    588     OPT_FEATURE_FLAGS=""
   586    589     AC_SEARCH_LIBS(dlopen, dl)
   587    590   else
   588    591     OPT_FEATURE_FLAGS="-DSQLITE_OMIT_LOAD_EXTENSION=1"
   589    592   fi
   590    593   
   591    594   ##########
   592    595   # Do we want to support memsys3 and/or memsys5
   593    596   #
   594    597   AC_ARG_ENABLE(memsys5, 
   595         -  AC_HELP_STRING([--enable-memsys5],[Enable MEMSYS5]),
   596         -  [enable_memsys5=yes],[enable_memsys5=no])
          598  +  AC_HELP_STRING([--enable-memsys5],[Enable MEMSYS5]))
   597    599   AC_MSG_CHECKING([whether to support MEMSYS5])
   598    600   if test "${enable_memsys5}" = "yes"; then
   599    601     OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_MEMSYS5"
   600    602     AC_MSG_RESULT([yes])
   601    603   else
   602    604     AC_MSG_RESULT([no])
   603    605   fi
   604    606   AC_ARG_ENABLE(memsys3, 
   605         -  AC_HELP_STRING([--enable-memsys3],[Enable MEMSYS3]),
   606         -  [enable_memsys3=yes],[enable_memsys3=no])
          607  +  AC_HELP_STRING([--enable-memsys3],[Enable MEMSYS3]))
   607    608   AC_MSG_CHECKING([whether to support MEMSYS3])
   608    609   if test "${enable_memsys3}" = "yes" -a "${enable_memsys5}" = "no"; then
   609    610     OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_MEMSYS3"
   610    611     AC_MSG_RESULT([yes])
   611    612   else
   612    613     AC_MSG_RESULT([no])
   613    614   fi
   614    615   
   615    616   #########
   616    617   # See whether we should enable Full Text Search extensions
   617    618   AC_ARG_ENABLE(fts3, AC_HELP_STRING([--enable-fts3],
   618         -      [Enable the FTS3 extension]),
   619         -      [enable_fts3=yes],[enable_fts3=no])
          619  +      [Enable the FTS3 extension]))
   620    620   if test "${enable_fts3}" = "yes" ; then
   621    621     OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_FTS3"
   622    622   fi
   623    623   AC_ARG_ENABLE(fts4, AC_HELP_STRING([--enable-fts4],
   624         -      [Enable the FTS4 extension]),
   625         -      [enable_fts4=yes],[enable_fts4=no])
          624  +      [Enable the FTS4 extension]))
   626    625   if test "${enable_fts4}" = "yes" ; then
   627    626     OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_FTS4"
   628    627     AC_SEARCH_LIBS([log],[m])
   629    628   fi
   630    629   AC_ARG_ENABLE(fts5, AC_HELP_STRING([--enable-fts5],
   631         -      [Enable the FTS5 extension]),
   632         -      [enable_fts5=yes],[enable_fts5=no])
          630  +      [Enable the FTS5 extension]))
   633    631   if test "${enable_fts5}" = "yes" ; then
   634    632     OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_FTS5"
   635    633     AC_SEARCH_LIBS([log],[m])
   636    634   fi
   637    635   
   638    636   #########
   639    637   # See whether we should enable JSON1
   640         -AC_ARG_ENABLE(json1, AC_HELP_STRING([--enable-json1],
   641         -      [Enable the JSON1 extension]),
   642         -      [enable_json1=yes],[enable_json1=no])
          638  +AC_ARG_ENABLE(json1, AC_HELP_STRING([--enable-json1],[Enable the JSON1 extension]))
   643    639   if test "${enable_json1}" = "yes" ; then
   644    640     OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_JSON1"
   645    641   fi
          642  +
          643  +#########
          644  +# See whether we should enable the LIMIT clause on UPDATE and DELETE
          645  +# statements.
          646  +AC_ARG_ENABLE(update-limit, AC_HELP_STRING([--enable-update-limit],
          647  +      [Enable the UPDATE/DELETE LIMIT clause]))
          648  +if test "${enable_udlimit}" = "yes" ; then
          649  +  OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_UPDATE_DELETE_LIMIT"
          650  +fi
          651  +
          652  +#########
          653  +# See whether we should enable GEOPOLY
          654  +AC_ARG_ENABLE(geopoly, AC_HELP_STRING([--enable-geopoly],
          655  +      [Enable the GEOPOLY extension]),
          656  +      [enable_geopoly=yes],[enable_geopoly=no])
          657  +if test "${enable_geopoly}" = "yes" ; then
          658  +  OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_GEOPOLY"
          659  +  enable_rtree=yes
          660  +fi
   646    661   
   647    662   #########
   648    663   # See whether we should enable RTREE
   649    664   AC_ARG_ENABLE(rtree, AC_HELP_STRING([--enable-rtree],
   650         -      [Enable the RTREE extension]),
   651         -      [enable_rtree=yes],[enable_rtree=no])
          665  +      [Enable the RTREE extension]))
   652    666   if test "${enable_rtree}" = "yes" ; then
   653    667     OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_RTREE"
   654    668   fi
   655    669   
   656    670   #########
   657    671   # See whether we should enable the SESSION extension
   658    672   AC_ARG_ENABLE(session, AC_HELP_STRING([--enable-session],
   659         -      [Enable the SESSION extension]),
   660         -      [enable_session=yes],[enable_session=no])
          673  +      [Enable the SESSION extension]))
   661    674   if test "${enable_session}" = "yes" ; then
   662    675     OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_SESSION"
   663    676     OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_PREUPDATE_HOOK"
   664    677   fi
   665    678   
   666    679   #########
   667    680   # attempt to duplicate any OMITS and ENABLES into the ${OPT_FEATURE_FLAGS} parameter
................................................................................
   713    726   done
   714    727   BUILD_CFLAGS=$ac_temp_BUILD_CFLAGS
   715    728   
   716    729   
   717    730   #########
   718    731   # See whether we should use GCOV
   719    732   AC_ARG_ENABLE(gcov, AC_HELP_STRING([--enable-gcov],
   720         -      [Enable coverage testing using gcov]),
   721         -      [use_gcov=$enableval],[use_gcov=no])
          733  +      [Enable coverage testing using gcov]))
   722    734   if test "${use_gcov}" = "yes" ; then
   723    735     USE_GCOV=1
   724    736   else
   725    737     USE_GCOV=0
   726    738   fi
   727    739   AC_SUBST(USE_GCOV)
   728    740   

Added doc/F2FS.txt.

            1  +
            2  +SQLite's OS layer contains the following definitions used in F2FS related
            3  +calls:
            4  +
            5  +#define F2FS_IOCTL_MAGIC        0xf5
            6  +#define F2FS_IOC_START_ATOMIC_WRITE     _IO(F2FS_IOCTL_MAGIC, 1)
            7  +#define F2FS_IOC_COMMIT_ATOMIC_WRITE    _IO(F2FS_IOCTL_MAGIC, 2)
            8  +#define F2FS_IOC_START_VOLATILE_WRITE   _IO(F2FS_IOCTL_MAGIC, 3)
            9  +#define F2FS_IOC_ABORT_VOLATILE_WRITE   _IO(F2FS_IOCTL_MAGIC, 5)
           10  +#define F2FS_IOC_GET_FEATURES           _IOR(F2FS_IOCTL_MAGIC, 12, u32)
           11  +#define F2FS_FEATURE_ATOMIC_WRITE       0x0004
           12  +
           13  +After opening a database file on Linux (including Android), SQLite determines
           14  +whether or not a file supports F2FS atomic commits as follows:
           15  +
           16  +  u32 flags = 0;
           17  +  rc = ioctl(fd, F2FS_IOC_GET_FEATURES, &flags);
           18  +  if( rc==0 && (flags & F2FS_FEATURE_ATOMIC_WRITE) ){
           19  +    /* File supports F2FS atomic commits */
           20  +  }else{
           21  +    /* File does NOT support F2FS atomic commits */
           22  +  }
           23  +
           24  +where "fd" is the file-descriptor open on the database file.
           25  +
           26  +Usually, when writing to a database file that supports atomic commits, SQLite
           27  +accumulates the entire transaction in heap memory, deferring all writes to the
           28  +db file until the transaction is committed.
           29  +
           30  +When it is time to commit a transaction on a file that supports atomic
           31  +commits, SQLite does:
           32  +
           33  +  /* Take an F_WRLCK lock on the database file. This prevents any other
           34  +  ** SQLite clients from reading or writing the file until the lock
           35  +  ** is released.  */
           36  +  rc = fcntl(fd, F_SETLK, ...);
           37  +  if( rc!=0 ) goto failed;
           38  +
           39  +  rc = ioctl(fd, F2FS_IOC_START_ATOMIC_WRITE);
           40  +  if( rc!=0 ) goto fallback_to_legacy_journal_commit;
           41  +
           42  +  foreach (dirty page){
           43  +    rc = write(fd, ...dirty page...);
           44  +    if( rc!=0 ){
           45  +      ioctl(fd, F2FS_IOC_ABORT_VOLATILE_WRITE);
           46  +      goto fallback_to_legacy_journal_commit;
           47  +    }
           48  +  }
           49  +
           50  +  rc = ioctl(fd, F2FS_IOC_COMMIT_ATOMIC_WRITE);
           51  +  if( rc!=0 ){
           52  +    ioctl(fd, F2FS_IOC_ABORT_VOLATILE_WRITE);
           53  +    goto fallback_to_legacy_journal_commit;
           54  +  }
           55  +
           56  +  /* If we get there, the transaction has been successfully 
           57  +  ** committed to persistent storage. The following call
           58  +  ** relinquishes the F_WRLCK lock.  */
           59  +  fcntl(fd, F_SETLK, ...);
           60  +
           61  +Assumptions:
           62  +
           63  +1. After either of the F2FS_IOC_ABORT_VOLATILE_WRITE calls return,
           64  +   the database file is in the state that it was in before
           65  +   F2FS_IOC_START_ATOMIC_WRITE was invoked. Even if the ioctl()
           66  +   fails - we're ignoring the return code.
           67  +
           68  +   This is true regardless of the type of error that occurred in
           69  +   ioctl() or write().
           70  +
           71  +2. If the system fails before the F2FS_IOC_COMMIT_ATOMIC_WRITE is
           72  +   completed, then following a reboot the database file is in the
           73  +   state that it was in before F2FS_IOC_START_ATOMIC_WRITE was invoked.
           74  +   Or, if the write was commited right before the system failed, in a 
           75  +   state indicating that all write() calls were successfully committed
           76  +   to persistent storage before the failure occurred.
           77  +
           78  +3. If the process crashes before the F2FS_IOC_COMMIT_ATOMIC_WRITE is
           79  +   completed then the file is automatically restored to the state that
           80  +   it was in before F2FS_IOC_START_ATOMIC_WRITE was called. This occurs
           81  +   before the posix advisory lock is automatically dropped - there is
           82  +   no chance that another client will be able to read the file in a
           83  +   half-committed state before the rollback operation occurs.
           84  +
           85  +
           86  +
           87  +

Changes to doc/lemon.html.

     1      1   <html>
     2      2   <head>
     3      3   <title>The Lemon Parser Generator</title>
     4      4   </head>
     5         -<body bgcolor=white>
     6         -<h1 align=center>The Lemon Parser Generator</h1>
            5  +<body bgcolor='white'>
            6  +<h1 align='center'>The Lemon Parser Generator</h1>
     7      7   
     8      8   <p>Lemon is an LALR(1) parser generator for C.
     9      9   It does the same job as "bison" and "yacc".
    10         -But lemon is not a bison or yacc clone.  Lemon
           10  +But Lemon is not a bison or yacc clone.  Lemon
    11     11   uses a different grammar syntax which is designed to
    12     12   reduce the number of coding errors.  Lemon also uses a
    13     13   parsing engine that is faster than yacc and
    14     14   bison and which is both reentrant and threadsafe.
    15     15   (Update: Since the previous sentence was written, bison
    16     16   has also been updated so that it too can generate a
    17     17   reentrant and threadsafe parser.)
    18     18   Lemon also implements features that can be used
    19         -to eliminate resource leaks, making is suitable for use
           19  +to eliminate resource leaks, making it suitable for use
    20     20   in long-running programs such as graphical user interfaces
    21     21   or embedded controllers.</p>
    22     22   
    23     23   <p>This document is an introduction to the Lemon
    24     24   parser generator.</p>
    25     25   
    26     26   <h2>Security Note</h2>
................................................................................
    54     54   <li>A parser template file.
    55     55   </ul>
    56     56   Typically, only the grammar specification is supplied by the programmer.
    57     57   Lemon comes with a default parser template which works fine for most
    58     58   applications.  But the user is free to substitute a different parser
    59     59   template if desired.</p>
    60     60   
    61         -<p>Depending on command-line options, Lemon will generate between
    62         -one and three files of outputs.
           61  +<p>Depending on command-line options, Lemon will generate up to
           62  +three output files.
    63     63   <ul>
    64     64   <li>C code to implement the parser.
    65     65   <li>A header file defining an integer ID for each terminal symbol.
    66     66   <li>An information file that describes the states of the generated parser
    67     67       automaton.
    68     68   </ul>
    69     69   By default, all three of these output files are generated.
................................................................................
    86     86   
    87     87   <h3>Command Line Options</h3>
    88     88   
    89     89   <p>The behavior of Lemon can be modified using command-line options.
    90     90   You can obtain a list of the available command-line options together
    91     91   with a brief explanation of what each does by typing
    92     92   <pre>
    93         -   lemon -?
           93  +   lemon "-?"
    94     94   </pre>
    95     95   As of this writing, the following command-line options are supported:
    96     96   <ul>
    97     97   <li><b>-b</b>
    98     98   Show only the basis for each parser state in the report file.
    99     99   <li><b>-c</b>
   100         -Do not compress the generated action tables.
          100  +Do not compress the generated action tables.  The parser will be a
          101  +little larger and slower, but it will detect syntax errors sooner.
          102  +<li><b>-d</b><i>directory</i>
          103  +Write all output files into <i>directory</i>.  Normally, output files
          104  +are written into the directory that contains the input grammar file.
   101    105   <li><b>-D<i>name</i></b>
   102         -Define C preprocessor macro <i>name</i>.  This macro is useable by
   103         -"%ifdef" lines in the grammar file.
          106  +Define C preprocessor macro <i>name</i>.  This macro is usable by
          107  +"<tt><a href='#pifdef'>%ifdef</a></tt>" and
          108  +"<tt><a href='#pifdef'>%ifndef</a></tt>" lines
          109  +in the grammar file.
   104    110   <li><b>-g</b>
   105    111   Do not generate a parser.  Instead write the input grammar to standard
   106    112   output with all comments, actions, and other extraneous text removed.
   107    113   <li><b>-l</b>
   108    114   Omit "#line" directives in the generated parser C code.
   109    115   <li><b>-m</b>
   110    116   Cause the output C source code to be compatible with the "makeheaders"
   111         -program. 
          117  +program.
   112    118   <li><b>-p</b>
   113         -Display all conflicts that are resolved by 
          119  +Display all conflicts that are resolved by
   114    120   <a href='#precrules'>precedence rules</a>.
   115    121   <li><b>-q</b>
   116    122   Suppress generation of the report file.
   117    123   <li><b>-r</b>
   118    124   Do not sort or renumber the parser states as part of optimization.
   119    125   <li><b>-s</b>
   120    126   Show parser statistics before existing.
................................................................................
   161    167   be parsed.  This is accomplished by calling the following function
   162    168   once for each token:
   163    169   <pre>
   164    170      Parse(pParser, hTokenID, sTokenData, pArg);
   165    171   </pre>
   166    172   The first argument to the Parse() routine is the pointer returned by
   167    173   ParseAlloc().
   168         -The second argument is a small positive integer that tells the parse the
          174  +The second argument is a small positive integer that tells the parser the
   169    175   type of the next token in the data stream.
   170    176   There is one token type for each terminal symbol in the grammar.
   171    177   The gram.h file generated by Lemon contains #define statements that
   172    178   map symbolic terminal symbol names into appropriate integer values.
   173    179   A value of 0 for the second argument is a special flag to the
   174    180   parser to indicate that the end of input has been reached.
   175    181   The third argument is the value of the given token.  By default,
   176         -the type of the third argument is integer, but the grammar will
          182  +the type of the third argument is "void*", but the grammar will
   177    183   usually redefine this type to be some kind of structure.
   178    184   Typically the second argument will be a broad category of tokens
   179    185   such as "identifier" or "number" and the third argument will
   180    186   be the name of the identifier or the value of the number.</p>
   181    187   
   182    188   <p>The Parse() function may have either three or four arguments,
   183    189   depending on the grammar.  If the grammar specification file requests
   184         -it (via the <a href='#extraarg'><tt>extra_argument</tt> directive</a>),
          190  +it (via the <tt><a href='#extraarg'>%extra_argument</a></tt> directive),
   185    191   the Parse() function will have a fourth parameter that can be
   186    192   of any type chosen by the programmer.  The parser doesn't do anything
   187    193   with this argument except to pass it through to action routines.
   188    194   This is a convenient mechanism for passing state information down
   189    195   to the action routines without having to use global variables.</p>
   190    196   
   191    197   <p>A typical use of a Lemon parser might look something like the
   192    198   following:
   193    199   <pre>
   194         -   01 ParseTree *ParseFile(const char *zFilename){
   195         -   02    Tokenizer *pTokenizer;
   196         -   03    void *pParser;
   197         -   04    Token sToken;
   198         -   05    int hTokenId;
   199         -   06    ParserState sState;
   200         -   07
   201         -   08    pTokenizer = TokenizerCreate(zFilename);
   202         -   09    pParser = ParseAlloc( malloc );
   203         -   10    InitParserState(&sState);
   204         -   11    while( GetNextToken(pTokenizer, &hTokenId, &sToken) ){
   205         -   12       Parse(pParser, hTokenId, sToken, &sState);
          200  +    1 ParseTree *ParseFile(const char *zFilename){
          201  +    2    Tokenizer *pTokenizer;
          202  +    3    void *pParser;
          203  +    4    Token sToken;
          204  +    5    int hTokenId;
          205  +    6    ParserState sState;
          206  +    7
          207  +    8    pTokenizer = TokenizerCreate(zFilename);
          208  +    9    pParser = ParseAlloc( malloc );
          209  +   10    InitParserState(&amp;sState);
          210  +   11    while( GetNextToken(pTokenizer, &amp;hTokenId, &amp;sToken) ){
          211  +   12       Parse(pParser, hTokenId, sToken, &amp;sState);
   206    212      13    }
   207         -   14    Parse(pParser, 0, sToken, &sState);
          213  +   14    Parse(pParser, 0, sToken, &amp;sState);
   208    214      15    ParseFree(pParser, free );
   209    215      16    TokenizerFree(pTokenizer);
   210    216      17    return sState.treeRoot;
   211    217      18 }
   212    218   </pre>
   213    219   This example shows a user-written routine that parses a file of
   214    220   text and returns a pointer to the parse tree.
   215    221   (All error-handling code is omitted from this example to keep it
   216    222   simple.)
   217    223   We assume the existence of some kind of tokenizer which is created
   218    224   using TokenizerCreate() on line 8 and deleted by TokenizerFree()
   219    225   on line 16.  The GetNextToken() function on line 11 retrieves the
   220         -next token from the input file and puts its type in the 
          226  +next token from the input file and puts its type in the
   221    227   integer variable hTokenId.  The sToken variable is assumed to be
   222    228   some kind of structure that contains details about each token,
   223         -such as its complete text, what line it occurs on, etc. </p>
          229  +such as its complete text, what line it occurs on, etc.</p>
   224    230   
   225    231   <p>This example also assumes the existence of structure of type
   226    232   ParserState that holds state information about a particular parse.
   227    233   An instance of such a structure is created on line 6 and initialized
   228    234   on line 10.  A pointer to this structure is passed into the Parse()
   229    235   routine as the optional 4th argument.
   230    236   The action routine specified by the grammar for the parser can use
................................................................................
   233    239   the ParserState structure is left pointing to the root of the parse
   234    240   tree.</p>
   235    241   
   236    242   <p>The core of this example as it relates to Lemon is as follows:
   237    243   <pre>
   238    244      ParseFile(){
   239    245         pParser = ParseAlloc( malloc );
   240         -      while( GetNextToken(pTokenizer,&hTokenId, &sToken) ){
          246  +      while( GetNextToken(pTokenizer,&amp;hTokenId, &amp;sToken) ){
   241    247            Parse(pParser, hTokenId, sToken);
   242    248         }
   243    249         Parse(pParser, 0, sToken);
   244    250         ParseFree(pParser, free );
   245    251      }
   246    252   </pre>
   247    253   Basically, what a program has to do to use a Lemon-generated parser
................................................................................
   293    299   
   294    300   <p>The main purpose of the grammar specification file for Lemon is
   295    301   to define the grammar for the parser.  But the input file also
   296    302   specifies additional information Lemon requires to do its job.
   297    303   Most of the work in using Lemon is in writing an appropriate
   298    304   grammar file.</p>
   299    305   
   300         -<p>The grammar file for lemon is, for the most part, free format.
          306  +<p>The grammar file for Lemon is, for the most part, free format.
   301    307   It does not have sections or divisions like yacc or bison.  Any
   302    308   declaration can occur at any point in the file.
   303    309   Lemon ignores whitespace (except where it is needed to separate
   304         -tokens) and it honors the same commenting conventions as C and C++.</p>
          310  +tokens), and it honors the same commenting conventions as C and C++.</p>
   305    311   
   306    312   <h3>Terminals and Nonterminals</h3>
   307    313   
   308    314   <p>A terminal symbol (token) is any string of alphanumeric
   309    315   and/or underscore characters
   310         -that begins with an upper case letter.
          316  +that begins with an uppercase letter.
   311    317   A terminal can contain lowercase letters after the first character,
   312         -but the usual convention is to make terminals all upper case.
          318  +but the usual convention is to make terminals all uppercase.
   313    319   A nonterminal, on the other hand, is any string of alphanumeric
   314         -and underscore characters than begins with a lower case letter.
   315         -Again, the usual convention is to make nonterminals use all lower
   316         -case letters.</p>
          320  +and underscore characters than begins with a lowercase letter.
          321  +Again, the usual convention is to make nonterminals use all lowercase
          322  +letters.</p>
   317    323   
   318         -<p>In Lemon, terminal and nonterminal symbols do not need to 
          324  +<p>In Lemon, terminal and nonterminal symbols do not need to
   319    325   be declared or identified in a separate section of the grammar file.
   320    326   Lemon is able to generate a list of all terminals and nonterminals
   321    327   by examining the grammar rules, and it can always distinguish a
   322    328   terminal from a nonterminal by checking the case of the first
   323    329   character of the name.</p>
   324    330   
   325    331   <p>Yacc and bison allow terminal symbols to have either alphanumeric
................................................................................
   335    341   Each grammar rule consists of a nonterminal symbol followed by
   336    342   the special symbol "::=" and then a list of terminals and/or nonterminals.
   337    343   The rule is terminated by a period.
   338    344   The list of terminals and nonterminals on the right-hand side of the
   339    345   rule can be empty.
   340    346   Rules can occur in any order, except that the left-hand side of the
   341    347   first rule is assumed to be the start symbol for the grammar (unless
   342         -specified otherwise using the <tt>%start</tt> directive described below.)
          348  +specified otherwise using the <tt><a href='#start_symbol'>%start_symbol</a></tt>
          349  +directive described below.)
   343    350   A typical sequence of grammar rules might look something like this:
   344    351   <pre>
   345    352     expr ::= expr PLUS expr.
   346    353     expr ::= expr TIMES expr.
   347    354     expr ::= LPAREN expr RPAREN.
   348    355     expr ::= VALUE.
   349    356   </pre>
................................................................................
   378    385   rule and say "$7" when you really mean "$8".</p>
   379    386   
   380    387   <p>Lemon avoids the need to count grammar symbols by assigning symbolic
   381    388   names to each symbol in a grammar rule and then using those symbolic
   382    389   names in the action.
   383    390   In yacc or bison, one would write this:
   384    391   <pre>
   385         -  expr -> expr PLUS expr  { $$ = $1 + $3; };
          392  +  expr -&gt; expr PLUS expr  { $$ = $1 + $3; };
   386    393   </pre>
   387    394   But in Lemon, the same rule becomes the following:
   388    395   <pre>
   389    396     expr(A) ::= expr(B) PLUS expr(C).  { A = B+C; }
   390    397   </pre>
   391    398   In the Lemon rule, any symbol in parentheses after a grammar rule
   392    399   symbol becomes a place holder for that symbol in the grammar rule.
................................................................................
   418    425   
   419    426   <p>Lemon resolves parsing ambiguities in exactly the same way as
   420    427   yacc and bison.  A shift-reduce conflict is resolved in favor
   421    428   of the shift, and a reduce-reduce conflict is resolved by reducing
   422    429   whichever rule comes first in the grammar file.</p>
   423    430   
   424    431   <p>Just like in
   425         -yacc and bison, Lemon allows a measure of control 
   426         -over the resolution of paring conflicts using precedence rules.
          432  +yacc and bison, Lemon allows a measure of control
          433  +over the resolution of parsing conflicts using precedence rules.
   427    434   A precedence value can be assigned to any terminal symbol
   428         -using the 
   429         -<a href='#pleft'>%left</a>,
   430         -<a href='#pright'>%right</a> or
   431         -<a href='#pnonassoc'>%nonassoc</a> directives.  Terminal symbols
   432         -mentioned in earlier directives have a lower precedence that
          435  +using the
          436  +<tt><a href='#pleft'>%left</a></tt>,
          437  +<tt><a href='#pright'>%right</a></tt> or
          438  +<tt><a href='#pnonassoc'>%nonassoc</a></tt> directives.  Terminal symbols
          439  +mentioned in earlier directives have a lower precedence than
   433    440   terminal symbols mentioned in later directives.  For example:</p>
   434    441   
   435    442   <p><pre>
   436    443      %left AND.
   437    444      %left OR.
   438    445      %nonassoc EQ NE GT GE LT LE.
   439    446      %left PLUS MINUS.
................................................................................
   501    508   <ul>
   502    509   <li> If either the token to be shifted or the rule to be reduced
   503    510        lacks precedence information, then resolve in favor of the
   504    511        shift, but report a parsing conflict.
   505    512   <li> If the precedence of the token to be shifted is greater than
   506    513        the precedence of the rule to reduce, then resolve in favor
   507    514        of the shift.  No parsing conflict is reported.
   508         -<li> If the precedence of the token it be shifted is less than the
          515  +<li> If the precedence of the token to be shifted is less than the
   509    516        precedence of the rule to reduce, then resolve in favor of the
   510    517        reduce action.  No parsing conflict is reported.
   511    518   <li> If the precedences are the same and the shift token is
   512    519        right-associative, then resolve in favor of the shift.
   513    520        No parsing conflict is reported.
   514         -<li> If the precedences are the same the shift token is
          521  +<li> If the precedences are the same and the shift token is
   515    522        left-associative, then resolve in favor of the reduce.
   516    523        No parsing conflict is reported.
   517         -<li> Otherwise, resolve the conflict by doing the shift and
   518         -     report the parsing conflict.
          524  +<li> Otherwise, resolve the conflict by doing the shift, and
          525  +     report a parsing conflict.
   519    526   </ul>
   520    527   Reduce-reduce conflicts are resolved this way:
   521    528   <ul>
   522         -<li> If either reduce rule 
          529  +<li> If either reduce rule
   523    530        lacks precedence information, then resolve in favor of the
   524         -     rule that appears first in the grammar and report a parsing
          531  +     rule that appears first in the grammar, and report a parsing
   525    532        conflict.
   526         -<li> If both rules have precedence and the precedence is different
          533  +<li> If both rules have precedence and the precedence is different,
   527    534        then resolve the dispute in favor of the rule with the highest
   528         -     precedence and do not report a conflict.
          535  +     precedence, and do not report a conflict.
   529    536   <li> Otherwise, resolve the conflict by reducing by the rule that
   530         -     appears first in the grammar and report a parsing conflict.
          537  +     appears first in the grammar, and report a parsing conflict.
   531    538   </ul>
   532    539   
   533    540   <h3>Special Directives</h3>
   534    541   
   535    542   <p>The input grammar to Lemon consists of grammar rules and special
   536    543   directives.  We've described all the grammar rules, so now we'll
   537    544   talk about the special directives.</p>
   538    545   
   539         -<p>Directives in lemon can occur in any order.  You can put them before
   540         -the grammar rules, or after the grammar rules, or in the mist of the
          546  +<p>Directives in Lemon can occur in any order.  You can put them before
          547  +the grammar rules, or after the grammar rules, or in the midst of the
   541    548   grammar rules.  It doesn't matter.  The relative order of
   542    549   directives used to assign precedence to terminals is important, but
   543    550   other than that, the order of directives in Lemon is arbitrary.</p>
   544    551   
   545    552   <p>Lemon supports the following special directives:
   546    553   <ul>
   547         -<li><tt>%code</tt>
   548         -<li><tt>%default_destructor</tt>
   549         -<li><tt>%default_type</tt>
   550         -<li><tt>%destructor</tt>
   551         -<li><tt>%endif</tt>
   552         -<li><tt>%extra_argument</tt>
   553         -<li><tt>%fallback</tt>
   554         -<li><tt>%ifdef</tt>
   555         -<li><tt>%ifndef</tt>
   556         -<li><tt>%include</tt>
   557         -<li><tt>%left</tt>
   558         -<li><tt>%name</tt>
   559         -<li><tt>%nonassoc</tt>
   560         -<li><tt>%parse_accept</tt>
   561         -<li><tt>%parse_failure </tt>
   562         -<li><tt>%right</tt>
   563         -<li><tt>%stack_overflow</tt>
   564         -<li><tt>%stack_size</tt>
   565         -<li><tt>%start_symbol</tt>
   566         -<li><tt>%syntax_error</tt>
   567         -<li><tt>%token_class</tt>
   568         -<li><tt>%token_destructor</tt>
   569         -<li><tt>%token_prefix</tt>
   570         -<li><tt>%token_type</tt>
   571         -<li><tt>%type</tt>
   572         -<li><tt>%wildcard</tt>
          554  +<li><tt><a href='#pcode'>%code</a></tt>
          555  +<li><tt><a href='#default_destructor'>%default_destructor</a></tt>
          556  +<li><tt><a href='#default_type'>%default_type</a></tt>
          557  +<li><tt><a href='#destructor'>%destructor</a></tt>
          558  +<li><tt><a href='#pifdef'>%endif</a></tt>
          559  +<li><tt><a href='#extraarg'>%extra_argument</a></tt>
          560  +<li><tt><a href='#pfallback'>%fallback</a></tt>
          561  +<li><tt><a href='#pifdef'>%ifdef</a></tt>
          562  +<li><tt><a href='#pifdef'>%ifndef</a></tt>
          563  +<li><tt><a href='#pinclude'>%include</a></tt>
          564  +<li><tt><a href='#pleft'>%left</a></tt>
          565  +<li><tt><a href='#pname'>%name</a></tt>
          566  +<li><tt><a href='#pnonassoc'>%nonassoc</a></tt>
          567  +<li><tt><a href='#parse_accept'>%parse_accept</a></tt>
          568  +<li><tt><a href='#parse_failure'>%parse_failure</a></tt>
          569  +<li><tt><a href='#pright'>%right</a></tt>
          570  +<li><tt><a href='#stack_overflow'>%stack_overflow</a></tt>
          571  +<li><tt><a href='#stack_size'>%stack_size</a></tt>
          572  +<li><tt><a href='#start_symbol'>%start_symbol</a></tt>
          573  +<li><tt><a href='#syntax_error'>%syntax_error</a></tt>
          574  +<li><tt><a href='#token_class'>%token_class</a></tt>
          575  +<li><tt><a href='#token_destructor'>%token_destructor</a></tt>
          576  +<li><tt><a href='#token_prefix'>%token_prefix</a></tt>
          577  +<li><tt><a href='#token_type'>%token_type</a></tt>
          578  +<li><tt><a href='#ptype'>%type</a></tt>
          579  +<li><tt><a href='#pwildcard'>%wildcard</a></tt>
   573    580   </ul>
   574    581   Each of these directives will be described separately in the
   575    582   following sections:</p>
   576    583   
   577    584   <a name='pcode'></a>
   578    585   <h4>The <tt>%code</tt> directive</h4>
   579    586   
   580         -<p>The %code directive is used to specify addition C code that
          587  +<p>The <tt>%code</tt> directive is used to specify additional C code that
   581    588   is added to the end of the main output file.  This is similar to
   582         -the <a href='#pinclude'>%include</a> directive except that %include
   583         -is inserted at the beginning of the main output file.</p>
          589  +the <tt><a href='#pinclude'>%include</a></tt> directive except that
          590  +<tt>%include</tt> is inserted at the beginning of the main output file.</p>
   584    591   
   585         -<p>%code is typically used to include some action routines or perhaps
   586         -a tokenizer or even the "main()" function 
          592  +<p><tt>%code</tt> is typically used to include some action routines or perhaps
          593  +a tokenizer or even the "main()" function
   587    594   as part of the output file.</p>
   588    595   
   589    596   <a name='default_destructor'></a>
   590    597   <h4>The <tt>%default_destructor</tt> directive</h4>
   591    598   
   592         -<p>The %default_destructor directive specifies a destructor to 
          599  +<p>The <tt>%default_destructor</tt> directive specifies a destructor to
   593    600   use for non-terminals that do not have their own destructor
   594         -specified by a separate %destructor directive.  See the documentation
   595         -on the <a name='#destructor'>%destructor</a> directive below for
          601  +specified by a separate <tt>%destructor</tt> directive.  See the documentation
          602  +on the <tt><a name='#destructor'>%destructor</a></tt> directive below for
   596    603   additional information.</p>
   597    604   
   598         -<p>In some grammers, many different non-terminal symbols have the
   599         -same datatype and hence the same destructor.  This directive is
   600         -a convenience way to specify the same destructor for all those
          605  +<p>In some grammars, many different non-terminal symbols have the
          606  +same data type and hence the same destructor.  This directive is
          607  +a convenient way to specify the same destructor for all those
   601    608   non-terminals using a single statement.</p>
   602    609   
   603    610   <a name='default_type'></a>
   604    611   <h4>The <tt>%default_type</tt> directive</h4>
   605    612   
   606         -<p>The %default_type directive specifies the datatype of non-terminal
   607         -symbols that do no have their own datatype defined using a separate
   608         -<a href='#ptype'>%type</a> directive.  
   609         -</p>
          613  +<p>The <tt>%default_type</tt> directive specifies the data type of non-terminal
          614  +symbols that do not have their own data type defined using a separate
          615  +<tt><a href='#ptype'>%type</a></tt> directive.</p>
   610    616   
   611    617   <a name='destructor'></a>
   612    618   <h4>The <tt>%destructor</tt> directive</h4>
   613    619   
   614         -<p>The %destructor directive is used to specify a destructor for
          620  +<p>The <tt>%destructor</tt> directive is used to specify a destructor for
   615    621   a non-terminal symbol.
   616         -(See also the <a href='#token_destructor'>%token_destructor</a>
          622  +(See also the <tt><a href='#token_destructor'>%token_destructor</a></tt>
   617    623   directive which is used to specify a destructor for terminal symbols.)</p>
   618    624   
   619    625   <p>A non-terminal's destructor is called to dispose of the
   620    626   non-terminal's value whenever the non-terminal is popped from
   621    627   the stack.  This includes all of the following circumstances:
   622    628   <ul>
   623    629   <li> When a rule reduces and the value of a non-terminal on
................................................................................
   631    637   
   632    638   <p>Consider an example:
   633    639   <pre>
   634    640      %type nt {void*}
   635    641      %destructor nt { free($$); }
   636    642      nt(A) ::= ID NUM.   { A = malloc( 100 ); }
   637    643   </pre>
   638         -This example is a bit contrived but it serves to illustrate how
          644  +This example is a bit contrived, but it serves to illustrate how
   639    645   destructors work.  The example shows a non-terminal named
   640    646   "nt" that holds values of type "void*".  When the rule for
   641    647   an "nt" reduces, it sets the value of the non-terminal to
   642    648   space obtained from malloc().  Later, when the nt non-terminal
   643    649   is popped from the stack, the destructor will fire and call
   644    650   free() on this malloced space, thus avoiding a memory leak.
   645    651   (Note that the symbol "$$" in the destructor code is replaced
................................................................................
   647    653   
   648    654   <p>It is important to note that the value of a non-terminal is passed
   649    655   to the destructor whenever the non-terminal is removed from the
   650    656   stack, unless the non-terminal is used in a C-code action.  If
   651    657   the non-terminal is used by C-code, then it is assumed that the
   652    658   C-code will take care of destroying it.
   653    659   More commonly, the value is used to build some
   654         -larger structure and we don't want to destroy it, which is why
          660  +larger structure, and we don't want to destroy it, which is why
   655    661   the destructor is not called in this circumstance.</p>
   656    662   
   657    663   <p>Destructors help avoid memory leaks by automatically freeing
   658    664   allocated objects when they go out of scope.
   659    665   To do the same using yacc or bison is much more difficult.</p>
   660    666   
   661         -<a name="extraarg"></a>
          667  +<a name='extraarg'></a>
   662    668   <h4>The <tt>%extra_argument</tt> directive</h4>
   663    669   
   664         -The %extra_argument directive instructs Lemon to add a 4th parameter
          670  +The <tt>%extra_argument</tt> directive instructs Lemon to add a 4th parameter
   665    671   to the parameter list of the Parse() function it generates.  Lemon
   666    672   doesn't do anything itself with this extra argument, but it does
   667    673   make the argument available to C-code action routines, destructors,
   668    674   and so forth.  For example, if the grammar file contains:</p>
   669    675   
   670    676   <p><pre>
   671    677       %extra_argument { MyStruct *pAbc }
................................................................................
   672    678   </pre></p>
   673    679   
   674    680   <p>Then the Parse() function generated will have an 4th parameter
   675    681   of type "MyStruct*" and all action routines will have access to
   676    682   a variable named "pAbc" that is the value of the 4th parameter
   677    683   in the most recent call to Parse().</p>
   678    684   
          685  +<p>The <tt>%extra_context</tt> directive works the same except that it
          686  +is passed in on the ParseAlloc() or ParseInit() routines instead of
          687  +on Parse().
          688  +
          689  +<a name='extractx'></a>
          690  +<h4>The <tt>%extra_context</tt> directive</h4>
          691  +
          692  +The <tt>%extra_context</tt> directive instructs Lemon to add a 2th parameter
          693  +to the parameter list of the ParseAlloc() and ParseInif() functions.  Lemon
          694  +doesn't do anything itself with these extra argument, but it does
          695  +store the value make it available to C-code action routines, destructors,
          696  +and so forth.  For example, if the grammar file contains:</p>
          697  +
          698  +<p><pre>
          699  +    %extra_context { MyStruct *pAbc }
          700  +</pre></p>
          701  +
          702  +<p>Then the ParseAlloc() and ParseInit() functions will have an 2th parameter
          703  +of type "MyStruct*" and all action routines will have access to
          704  +a variable named "pAbc" that is the value of that 2th parameter.</p>
          705  +
          706  +<p>The <tt>%extra_argument</tt> directive works the same except that it
          707  +is passed in on the Parse() routine instead of on ParseAlloc()/ParseInit().
          708  +
   679    709   <a name='pfallback'></a>
   680    710   <h4>The <tt>%fallback</tt> directive</h4>
   681    711   
   682         -<p>The %fallback directive specifies an alternative meaning for one
          712  +<p>The <tt>%fallback</tt> directive specifies an alternative meaning for one
   683    713   or more tokens.  The alternative meaning is tried if the original token
   684         -would have generated a syntax error.
          714  +would have generated a syntax error.</p>
   685    715   
   686         -<p>The %fallback directive was added to support robust parsing of SQL
   687         -syntax in <a href="https://www.sqlite.org/">SQLite</a>.
          716  +<p>The <tt>%fallback</tt> directive was added to support robust parsing of SQL
          717  +syntax in <a href='https://www.sqlite.org/'>SQLite</a>.
   688    718   The SQL language contains a large assortment of keywords, each of which
   689    719   appears as a different token to the language parser.  SQL contains so
   690         -many keywords, that it can be difficult for programmers to keep up with
          720  +many keywords that it can be difficult for programmers to keep up with
   691    721   them all.  Programmers will, therefore, sometimes mistakenly use an
   692         -obscure language keyword for an identifier.  The %fallback directive
          722  +obscure language keyword for an identifier.  The <tt>%fallback</tt> directive
   693    723   provides a mechanism to tell the parser:  "If you are unable to parse
   694         -this keyword, try treating it as an identifier instead."
          724  +this keyword, try treating it as an identifier instead."</p>
   695    725   
   696         -<p>The syntax of %fallback is as follows:
          726  +<p>The syntax of <tt>%fallback</tt> is as follows:
   697    727   
   698    728   <blockquote>
   699         -<tt>%fallback</tt>  <i>ID</i> <i>TOKEN...</i> <b>.</b>
   700         -</blockquote>
          729  +<tt>%fallback</tt> <i>ID</i> <i>TOKEN...</i> <b>.</b>
          730  +</blockquote></p>
   701    731   
   702         -<p>In words, the %fallback directive is followed by a list of token names
   703         -terminated by a period.  The first token name is the fallback token - the
          732  +<p>In words, the <tt>%fallback</tt> directive is followed by a list of token
          733  +names terminated by a period.
          734  +The first token name is the fallback token &mdash; the
   704    735   token to which all the other tokens fall back to.  The second and subsequent
   705    736   arguments are tokens which fall back to the token identified by the first
   706         -argument.
          737  +argument.</p>
   707    738   
   708    739   <a name='pifdef'></a>
   709         -<h4>The <tt>%ifdef</tt>, <tt>%ifndef</tt>, and <tt>%endif</tt> directives.</h4>
          740  +<h4>The <tt>%ifdef</tt>, <tt>%ifndef</tt>, and <tt>%endif</tt> directives</h4>
   710    741   
   711         -<p>The %ifdef, %ifndef, and %endif directives are similar to
   712         -#ifdef, #ifndef, and #endif in the C-preprocessor, just not as general.
          742  +<p>The <tt>%ifdef</tt>, <tt>%ifndef</tt>, and <tt>%endif</tt> directives
          743  +are similar to #ifdef, #ifndef, and #endif in the C-preprocessor,
          744  +just not as general.
   713    745   Each of these directives must begin at the left margin.  No whitespace
   714         -is allowed between the "%" and the directive name.
          746  +is allowed between the "%" and the directive name.</p>
   715    747   
   716         -<p>Grammar text in between "%ifdef MACRO" and the next nested "%endif" is
          748  +<p>Grammar text in between "<tt>%ifdef MACRO</tt>" and the next nested
          749  +"<tt>%endif</tt>" is
   717    750   ignored unless the "-DMACRO" command-line option is used.  Grammar text
   718         -betwen "%ifndef MACRO" and the next nested "%endif" is included except when
   719         -the "-DMACRO" command-line option is used.
          751  +betwen "<tt>%ifndef MACRO</tt>" and the next nested "<tt>%endif</tt>" is
          752  +included except when the "-DMACRO" command-line option is used.</p>
   720    753   
   721         -<p>Note that the argument to %ifdef and %ifndef must be a single 
   722         -preprocessor symbol name, not a general expression.  There is no "%else"
   723         -directive.
          754  +<p>Note that the argument to <tt>%ifdef</tt> and <tt>%ifndef</tt> must
          755  +be a single preprocessor symbol name, not a general expression.
          756  +There is no "<tt>%else</tt>" directive.</p>
   724    757   
   725    758   
   726    759   <a name='pinclude'></a>
   727    760   <h4>The <tt>%include</tt> directive</h4>
   728    761   
   729         -<p>The %include directive specifies C code that is included at the
   730         -top of the generated parser.  You can include any text you want --
          762  +<p>The <tt>%include</tt> directive specifies C code that is included at the
          763  +top of the generated parser.  You can include any text you want &mdash;
   731    764   the Lemon parser generator copies it blindly.  If you have multiple
   732         -%include directives in your grammar file, their values are concatenated
   733         -so that all %include code ultimately appears near the top of the
   734         -generated parser, in the same order as it appeared in the grammer.</p>
          765  +<tt>%include</tt> directives in your grammar file, their values are concatenated
          766  +so that all <tt>%include</tt> code ultimately appears near the top of the
          767  +generated parser, in the same order as it appeared in the grammar.</p>
   735    768   
   736         -<p>The %include directive is very handy for getting some extra #include
          769  +<p>The <tt>%include</tt> directive is very handy for getting some extra #include
   737    770   preprocessor statements at the beginning of the generated parser.
   738    771   For example:</p>
   739    772   
   740    773   <p><pre>
   741    774      %include {#include &lt;unistd.h&gt;}
   742    775   </pre></p>
   743    776   
   744    777   <p>This might be needed, for example, if some of the C actions in the
   745         -grammar call functions that are prototyed in unistd.h.</p>
          778  +grammar call functions that are prototyped in unistd.h.</p>
   746    779   
   747    780   <a name='pleft'></a>
   748    781   <h4>The <tt>%left</tt> directive</h4>
   749    782   
   750         -The %left directive is used (along with the <a href='#pright'>%right</a> and
   751         -<a href='#pnonassoc'>%nonassoc</a> directives) to declare precedences of 
   752         -terminal symbols.  Every terminal symbol whose name appears after
   753         -a %left directive but before the next period (".") is
          783  +The <tt>%left</tt> directive is used (along with the
          784  +<tt><a href='#pright'>%right</a></tt> and
          785  +<tt><a href='#pnonassoc'>%nonassoc</a></tt> directives) to declare
          786  +precedences of terminal symbols.
          787  +Every terminal symbol whose name appears after
          788  +a <tt>%left</tt> directive but before the next period (".") is
   754    789   given the same left-associative precedence value.  Subsequent
   755         -%left directives have higher precedence.  For example:</p>
          790  +<tt>%left</tt> directives have higher precedence.  For example:</p>
   756    791   
   757    792   <p><pre>
   758    793      %left AND.
   759    794      %left OR.
   760    795      %nonassoc EQ NE GT GE LT LE.
   761    796      %left PLUS MINUS.
   762    797      %left TIMES DIVIDE MOD.
   763    798      %right EXP NOT.
   764    799   </pre></p>
   765    800   
   766         -<p>Note the period that terminates each %left, %right or %nonassoc
          801  +<p>Note the period that terminates each <tt>%left</tt>,
          802  +<tt>%right</tt> or <tt>%nonassoc</tt>
   767    803   directive.</p>
   768    804   
   769    805   <p>LALR(1) grammars can get into a situation where they require
   770    806   a large amount of stack space if you make heavy use or right-associative
   771         -operators.  For this reason, it is recommended that you use %left
   772         -rather than %right whenever possible.</p>
          807  +operators.  For this reason, it is recommended that you use <tt>%left</tt>
          808  +rather than <tt>%right</tt> whenever possible.</p>
   773    809   
   774    810   <a name='pname'></a>
   775    811   <h4>The <tt>%name</tt> directive</h4>
   776    812   
   777    813   <p>By default, the functions generated by Lemon all begin with the
   778    814   five-character string "Parse".  You can change this string to something
   779         -different using the %name directive.  For instance:</p>
          815  +different using the <tt>%name</tt> directive.  For instance:</p>
   780    816   
   781    817   <p><pre>
   782    818      %name Abcde
   783    819   </pre></p>
   784    820   
   785    821   <p>Putting this directive in the grammar file will cause Lemon to generate
   786    822   functions named
   787    823   <ul>
   788    824   <li> AbcdeAlloc(),
   789    825   <li> AbcdeFree(),
   790    826   <li> AbcdeTrace(), and
   791    827   <li> Abcde().
   792    828   </ul>
   793         -The %name directive allows you to generator two or more different
   794         -parsers and link them all into the same executable.
   795         -</p>
          829  +The <tt>%name</tt> directive allows you to generate two or more different
          830  +parsers and link them all into the same executable.</p>
   796    831   
   797    832   <a name='pnonassoc'></a>
   798    833   <h4>The <tt>%nonassoc</tt> directive</h4>
   799    834   
   800    835   <p>This directive is used to assign non-associative precedence to
   801         -one or more terminal symbols.  See the section on 
          836  +one or more terminal symbols.  See the section on
   802    837   <a href='#precrules'>precedence rules</a>
   803         -or on the <a href='#pleft'>%left</a> directive for additional information.</p>
          838  +or on the <tt><a href='#pleft'>%left</a></tt> directive
          839  +for additional information.</p>
   804    840   
   805    841   <a name='parse_accept'></a>
   806    842   <h4>The <tt>%parse_accept</tt> directive</h4>
   807    843   
   808         -<p>The %parse_accept directive specifies a block of C code that is
          844  +<p>The <tt>%parse_accept</tt> directive specifies a block of C code that is
   809    845   executed whenever the parser accepts its input string.  To "accept"
   810    846   an input string means that the parser was able to process all tokens
   811    847   without error.</p>
   812    848   
   813    849   <p>For example:</p>
   814    850   
   815    851   <p><pre>
................................................................................
   817    853         printf("parsing complete!\n");
   818    854      }
   819    855   </pre></p>
   820    856   
   821    857   <a name='parse_failure'></a>
   822    858   <h4>The <tt>%parse_failure</tt> directive</h4>
   823    859   
   824         -<p>The %parse_failure directive specifies a block of C code that
          860  +<p>The <tt>%parse_failure</tt> directive specifies a block of C code that
   825    861   is executed whenever the parser fails complete.  This code is not
   826    862   executed until the parser has tried and failed to resolve an input
   827    863   error using is usual error recovery strategy.  The routine is
   828    864   only invoked when parsing is unable to continue.</p>
   829    865   
   830    866   <p><pre>
   831    867      %parse_failure {
................................................................................
   833    869      }
   834    870   </pre></p>
   835    871   
   836    872   <a name='pright'></a>
   837    873   <h4>The <tt>%right</tt> directive</h4>
   838    874   
   839    875   <p>This directive is used to assign right-associative precedence to
   840         -one or more terminal symbols.  See the section on 
          876  +one or more terminal symbols.  See the section on
   841    877   <a href='#precrules'>precedence rules</a>
   842    878   or on the <a href='#pleft'>%left</a> directive for additional information.</p>
   843    879   
   844    880   <a name='stack_overflow'></a>
   845    881   <h4>The <tt>%stack_overflow</tt> directive</h4>
   846    882   
   847         -<p>The %stack_overflow directive specifies a block of C code that
          883  +<p>The <tt>%stack_overflow</tt> directive specifies a block of C code that
   848    884   is executed if the parser's internal stack ever overflows.  Typically
   849    885   this just prints an error message.  After a stack overflow, the parser
   850    886   will be unable to continue and must be reset.</p>
   851    887   
   852    888   <p><pre>
   853    889      %stack_overflow {
   854    890        fprintf(stderr,"Giving up.  Parser stack overflow\n");
   855    891      }
   856    892   </pre></p>
   857    893   
   858    894   <p>You can help prevent parser stack overflows by avoiding the use
   859    895   of right recursion and right-precedence operators in your grammar.
   860         -Use left recursion and and left-precedence operators instead, to
          896  +Use left recursion and and left-precedence operators instead to
   861    897   encourage rules to reduce sooner and keep the stack size down.
   862    898   For example, do rules like this:
   863    899   <pre>
   864    900      list ::= list element.      // left-recursion.  Good!
   865    901      list ::= .
   866    902   </pre>
   867    903   Not like this:
   868    904   <pre>
   869    905      list ::= element list.      // right-recursion.  Bad!
   870    906      list ::= .
   871         -</pre>
          907  +</pre></p>
   872    908   
   873    909   <a name='stack_size'></a>
   874    910   <h4>The <tt>%stack_size</tt> directive</h4>
   875    911   
   876    912   <p>If stack overflow is a problem and you can't resolve the trouble
   877    913   by using left-recursion, then you might want to increase the size
   878    914   of the parser's stack using this directive.  Put an positive integer
   879         -after the %stack_size directive and Lemon will generate a parse
          915  +after the <tt>%stack_size</tt> directive and Lemon will generate a parse
   880    916   with a stack of the requested size.  The default value is 100.</p>
   881    917   
   882    918   <p><pre>
   883    919      %stack_size 2000
   884    920   </pre></p>
   885    921   
   886    922   <a name='start_symbol'></a>
   887    923   <h4>The <tt>%start_symbol</tt> directive</h4>
   888    924   
   889         -<p>By default, the start-symbol for the grammar that Lemon generates
          925  +<p>By default, the start symbol for the grammar that Lemon generates
   890    926   is the first non-terminal that appears in the grammar file.  But you
   891         -can choose a different start-symbol using the %start_symbol directive.</p>
          927  +can choose a different start symbol using the
          928  +<tt>%start_symbol</tt> directive.</p>
   892    929   
   893    930   <p><pre>
   894    931      %start_symbol  prog
   895    932   </pre></p>
   896    933   
          934  +<a name='syntax_error'></a>
          935  +<h4>The <tt>%syntax_error</tt> directive</h4>
          936  +
          937  +<p>See <a href='#error_processing'>Error Processing</a>.</p>
          938  +
          939  +<a name='token_class'></a>
          940  +<h4>The <tt>%token_class</tt> directive</h4>
          941  +
          942  +<p>Undocumented.  Appears to be related to the MULTITERMINAL concept.
          943  +<a href='http://sqlite.org/src/fdiff?v1=796930d5fc2036c7&v2=624b24c5dc048e09&sbs=0'>Implementation</a>.</p>
          944  +
   897    945   <a name='token_destructor'></a>
   898    946   <h4>The <tt>%token_destructor</tt> directive</h4>
   899    947   
   900         -<p>The %destructor directive assigns a destructor to a non-terminal
   901         -symbol.  (See the description of the %destructor directive above.)
   902         -This directive does the same thing for all terminal symbols.</p>
          948  +<p>The <tt>%destructor</tt> directive assigns a destructor to a non-terminal
          949  +symbol.  (See the description of the
          950  +<tt><a href='%destructor'>%destructor</a></tt> directive above.)
          951  +The <tt>%token_destructor</tt> directive does the same thing
          952  +for all terminal symbols.</p>
   903    953   
   904    954   <p>Unlike non-terminal symbols which may each have a different data type
   905    955   for their values, terminals all use the same data type (defined by
   906         -the %token_type directive) and so they use a common destructor.  Other
   907         -than that, the token destructor works just like the non-terminal
          956  +the <tt><a href='#token_type'>%token_type</a></tt> directive)
          957  +and so they use a common destructor.
          958  +Other than that, the token destructor works just like the non-terminal
   908    959   destructors.</p>
   909    960   
   910    961   <a name='token_prefix'></a>
   911    962   <h4>The <tt>%token_prefix</tt> directive</h4>
   912    963   
   913    964   <p>Lemon generates #defines that assign small integer constants
   914    965   to each terminal symbol in the grammar.  If desired, Lemon will
   915    966   add a prefix specified by this directive
   916         -to each of the #defines it generates.
   917         -So if the default output of Lemon looked like this:
          967  +to each of the #defines it generates.</p>
          968  +
          969  +<p>So if the default output of Lemon looked like this:
   918    970   <pre>
   919    971       #define AND              1
   920    972       #define MINUS            2
   921    973       #define OR               3
   922    974       #define PLUS             4
   923    975   </pre>
   924    976   You can insert a statement into the grammar like this:
................................................................................
   927    979   </pre>
   928    980   to cause Lemon to produce these symbols instead:
   929    981   <pre>
   930    982       #define TOKEN_AND        1
   931    983       #define TOKEN_MINUS      2
   932    984       #define TOKEN_OR         3
   933    985       #define TOKEN_PLUS       4
   934         -</pre>
          986  +</pre></p>
   935    987   
   936    988   <a name='token_type'></a><a name='ptype'></a>
   937    989   <h4>The <tt>%token_type</tt> and <tt>%type</tt> directives</h4>
   938    990   
   939    991   <p>These directives are used to specify the data types for values
   940    992   on the parser's stack associated with terminal and non-terminal
   941    993   symbols.  The values of all terminal symbols must be of the same
................................................................................
   948   1000      %token_type    {Token*}
   949   1001   </pre></p>
   950   1002   
   951   1003   <p>If the data type of terminals is not specified, the default value
   952   1004   is "void*".</p>
   953   1005   
   954   1006   <p>Non-terminal symbols can each have their own data types.  Typically
   955         -the data type  of a non-terminal is a pointer to the root of a parse-tree
         1007  +the data type of a non-terminal is a pointer to the root of a parse tree
   956   1008   structure that contains all information about that non-terminal.
   957   1009   For example:</p>
   958   1010   
   959   1011   <p><pre>
   960   1012      %type   expr  {Expr*}
   961   1013   </pre></p>
   962   1014   
................................................................................
   969   1021   non-terminal whose data type requires 1K of storage, then your 100
   970   1022   entry parser stack will require 100K of heap space.  If you are willing
   971   1023   and able to pay that price, fine.  You just need to know.</p>
   972   1024   
   973   1025   <a name='pwildcard'></a>
   974   1026   <h4>The <tt>%wildcard</tt> directive</h4>
   975   1027   
   976         -<p>The %wildcard directive is followed by a single token name and a
   977         -period.  This directive specifies that the identified token should 
   978         -match any input token.
         1028  +<p>The <tt>%wildcard</tt> directive is followed by a single token name and a
         1029  +period.  This directive specifies that the identified token should
         1030  +match any input token.</p>
   979   1031   
   980   1032   <p>When the generated parser has the choice of matching an input against
   981   1033   the wildcard token and some other token, the other token is always used.
   982         -The wildcard token is only matched if there are no other alternatives.
         1034  +The wildcard token is only matched if there are no alternatives.</p>
   983   1035   
         1036  +<a name='error_processing'></a>
   984   1037   <h3>Error Processing</h3>
   985   1038   
   986   1039   <p>After extensive experimentation over several years, it has been
   987   1040   discovered that the error recovery strategy used by yacc is about
   988   1041   as good as it gets.  And so that is what Lemon uses.</p>
   989   1042   
   990   1043   <p>When a Lemon-generated parser encounters a syntax error, it
   991         -first invokes the code specified by the %syntax_error directive, if
         1044  +first invokes the code specified by the <tt>%syntax_error</tt> directive, if
   992   1045   any.  It then enters its error recovery strategy.  The error recovery
   993   1046   strategy is to begin popping the parsers stack until it enters a
   994   1047   state where it is permitted to shift a special non-terminal symbol
   995   1048   named "error".  It then shifts this non-terminal and continues
   996         -parsing.  But the %syntax_error routine will not be called again
         1049  +parsing.  The <tt>%syntax_error</tt> routine will not be called again
   997   1050   until at least three new tokens have been successfully shifted.</p>
   998   1051   
   999   1052   <p>If the parser pops its stack until the stack is empty, and it still
  1000         -is unable to shift the error symbol, then the %parse_failed routine
         1053  +is unable to shift the error symbol, then the
         1054  +<tt><a href='#parse_failure'>%parse_failure</a></tt> routine
  1001   1055   is invoked and the parser resets itself to its start state, ready
  1002   1056   to begin parsing a new file.  This is what will happen at the very
  1003         -first syntax error, of course, if there are no instances of the 
         1057  +first syntax error, of course, if there are no instances of the
  1004   1058   "error" non-terminal in your grammar.</p>
  1005   1059   
  1006   1060   </body>
  1007   1061   </html>

Added ext/expert/README.md.

            1  +## SQLite Expert Extension
            2  +
            3  +This folder contains code for a simple system to propose useful indexes
            4  +given a database and a set of SQL queries. It works as follows:
            5  +
            6  +  1. The user database schema is copied to a temporary database.
            7  +
            8  +  1. All SQL queries are prepared against the temporary database.
            9  +     Information regarding the WHERE and ORDER BY clauses, and other query
           10  +     features that affect index selection are recorded.
           11  +
           12  +  1. The information gathered in step 2 is used to create candidate 
           13  +     indexes - indexes that the planner might have made use of in the previous
           14  +     step, had they been available.
           15  +
           16  +  1. A subset of the data in the user database is used to generate statistics
           17  +     for all existing indexes and the candidate indexes generated in step 3
           18  +     above.
           19  +
           20  +  1. The SQL queries are prepared a second time. If the planner uses any
           21  +     of the indexes created in step 3, they are recommended to the user.
           22  +
           23  +# C API
           24  +
           25  +The SQLite expert C API is defined in sqlite3expert.h. Most uses will proceed
           26  +as follows:
           27  +
           28  +  1. An sqlite3expert object is created by calling **sqlite3\_expert\_new()**.
           29  +     A database handle opened by the user is passed as an argument.
           30  +
           31  +  1. The sqlite3expert object is configured with one or more SQL statements
           32  +     by making one or more calls to **sqlite3\_expert\_sql()**. Each call may
           33  +     specify a single SQL statement, or multiple statements separated by
           34  +     semi-colons.
           35  +  
           36  +  1. Optionally, the **sqlite3\_expert\_config()** API may be used to 
           37  +     configure the size of the data subset used to generate index statistics.
           38  +     Using a smaller subset of the data can speed up the analysis.
           39  +
           40  +  1. **sqlite3\_expert\_analyze()** is called to run the analysis.
           41  +
           42  +  1. One or more calls are made to **sqlite3\_expert\_report()** to extract
           43  +     components of the results of the analysis.
           44  +
           45  +  1. **sqlite3\_expert\_destroy()** is called to free all resources.
           46  +
           47  +Refer to comments in sqlite3expert.h for further details.
           48  +
           49  +# sqlite3_expert application
           50  +
           51  +The file "expert.c" contains the code for a command line application that
           52  +uses the API described above. It can be compiled with (for example):
           53  +
           54  +<pre>
           55  +  gcc -O2 sqlite3.c expert.c sqlite3expert.c -o sqlite3_expert
           56  +</pre>
           57  +
           58  +Assuming the database is named "test.db", it can then be run to analyze a
           59  +single query:
           60  +
           61  +<pre>
           62  +  ./sqlite3_expert -sql &lt;sql-query&gt; test.db
           63  +</pre>
           64  +
           65  +Or an entire text file worth of queries with:
           66  +
           67  +<pre>
           68  +  ./sqlite3_expert -file &lt;text-file&gt; test.db
           69  +</pre>
           70  +
           71  +By default, sqlite3\_expert generates index statistics using all the data in
           72  +the user database. For a large database, this may be prohibitively time
           73  +consuming. The "-sample" option may be used to configure sqlite3\_expert to
           74  +generate statistics based on an integer percentage of the user database as
           75  +follows:
           76  +
           77  +<pre>
           78  +  # Generate statistics based on 25% of the user database rows:
           79  +  ./sqlite3_expert -sample 25 -sql &lt;sql-query&gt; test.db
           80  +
           81  +  # Do not generate any statistics at all:
           82  +  ./sqlite3_expert -sample 0 -sql &lt;sql-query&gt; test.db
           83  +</pre>

Added ext/expert/expert.c.

            1  +/*
            2  +** 2017 April 07
            3  +**
            4  +** The author disclaims copyright to this source code.  In place of
            5  +** a legal notice, here is a blessing:
            6  +**
            7  +**    May you do good and not evil.
            8  +**    May you find forgiveness for yourself and forgive others.
            9  +**    May you share freely, never taking more than you give.
           10  +**
           11  +*************************************************************************
           12  +*/
           13  +
           14  +
           15  +#include <sqlite3.h>
           16  +#include <stdio.h>
           17  +#include <stdlib.h>
           18  +#include <string.h>
           19  +#include "sqlite3expert.h"
           20  +
           21  +
           22  +static void option_requires_argument(const char *zOpt){
           23  +  fprintf(stderr, "Option requires an argument: %s\n", zOpt);
           24  +  exit(-3);
           25  +}
           26  +
           27  +static int option_integer_arg(const char *zVal){
           28  +  return atoi(zVal);
           29  +}
           30  +
           31  +static void usage(char **argv){
           32  +  fprintf(stderr, "\n");
           33  +  fprintf(stderr, "Usage %s ?OPTIONS? DATABASE\n", argv[0]);
           34  +  fprintf(stderr, "\n");
           35  +  fprintf(stderr, "Options are:\n");
           36  +  fprintf(stderr, "  -sql SQL   (analyze SQL statements passed as argument)\n");
           37  +  fprintf(stderr, "  -file FILE (read SQL statements from file FILE)\n");
           38  +  fprintf(stderr, "  -verbose LEVEL (integer verbosity level. default 1)\n");
           39  +  fprintf(stderr, "  -sample PERCENT (percent of db to sample. default 100)\n");
           40  +  exit(-1);
           41  +}
           42  +
           43  +static int readSqlFromFile(sqlite3expert *p, const char *zFile, char **pzErr){
           44  +  FILE *in = fopen(zFile, "rb");
           45  +  long nIn;
           46  +  size_t nRead;
           47  +  char *pBuf;
           48  +  int rc;
           49  +  if( in==0 ){
           50  +    *pzErr = sqlite3_mprintf("failed to open file %s\n", zFile);
           51  +    return SQLITE_ERROR;
           52  +  }
           53  +  fseek(in, 0, SEEK_END);
           54  +  nIn = ftell(in);
           55  +  rewind(in);
           56  +  pBuf = sqlite3_malloc64( nIn+1 );
           57  +  nRead = fread(pBuf, nIn, 1, in);
           58  +  fclose(in);
           59  +  if( nRead!=1 ){
           60  +    sqlite3_free(pBuf);
           61  +    *pzErr = sqlite3_mprintf("failed to read file %s\n", zFile);
           62  +    return SQLITE_ERROR;
           63  +  }
           64  +  pBuf[nIn] = 0;
           65  +  rc = sqlite3_expert_sql(p, pBuf, pzErr);
           66  +  sqlite3_free(pBuf);
           67  +  return rc;
           68  +}
           69  +
           70  +int main(int argc, char **argv){
           71  +  const char *zDb;
           72  +  int rc = 0;
           73  +  char *zErr = 0;
           74  +  int i;
           75  +  int iVerbose = 1;               /* -verbose option */
           76  +
           77  +  sqlite3 *db = 0;
           78  +  sqlite3expert *p = 0;
           79  +
           80  +  if( argc<2 ) usage(argv);
           81  +  zDb = argv[argc-1];
           82  +  if( zDb[0]=='-' ) usage(argv);
           83  +  rc = sqlite3_open(zDb, &db);
           84  +  if( rc!=SQLITE_OK ){
           85  +    fprintf(stderr, "Cannot open db file: %s - %s\n", zDb, sqlite3_errmsg(db));
           86  +    exit(-2);
           87  +  }
           88  +
           89  +  p = sqlite3_expert_new(db, &zErr);
           90  +  if( p==0 ){
           91  +    fprintf(stderr, "Cannot run analysis: %s\n", zErr);
           92  +    rc = 1;
           93  +  }else{
           94  +    for(i=1; i<(argc-1); i++){
           95  +      char *zArg = argv[i];
           96  +      int nArg;
           97  +      if( zArg[0]=='-' && zArg[1]=='-' && zArg[2]!=0 ) zArg++;
           98  +      nArg = (int)strlen(zArg);
           99  +      if( nArg>=2 && 0==sqlite3_strnicmp(zArg, "-file", nArg) ){
          100  +        if( ++i==(argc-1) ) option_requires_argument("-file");
          101  +        rc = readSqlFromFile(p, argv[i], &zErr);
          102  +      }
          103  +
          104  +      else if( nArg>=3 && 0==sqlite3_strnicmp(zArg, "-sql", nArg) ){
          105  +        if( ++i==(argc-1) ) option_requires_argument("-sql");
          106  +        rc = sqlite3_expert_sql(p, argv[i], &zErr);
          107  +      }
          108  +
          109  +      else if( nArg>=3 && 0==sqlite3_strnicmp(zArg, "-sample", nArg) ){
          110  +        int iSample;
          111  +        if( ++i==(argc-1) ) option_requires_argument("-sample");
          112  +        iSample = option_integer_arg(argv[i]);
          113  +        sqlite3_expert_config(p, EXPERT_CONFIG_SAMPLE, iSample);
          114  +      }
          115  +
          116  +      else if( nArg>=2 && 0==sqlite3_strnicmp(zArg, "-verbose", nArg) ){
          117  +        if( ++i==(argc-1) ) option_requires_argument("-verbose");
          118  +        iVerbose = option_integer_arg(argv[i]);
          119  +      }
          120  +
          121  +      else{
          122  +        usage(argv);
          123  +      }
          124  +    }
          125  +  }
          126  +
          127  +  if( rc==SQLITE_OK ){
          128  +    rc = sqlite3_expert_analyze(p, &zErr);
          129  +  }
          130  +
          131  +  if( rc==SQLITE_OK ){
          132  +    int nQuery = sqlite3_expert_count(p);
          133  +    if( iVerbose>0 ){
          134  +      const char *zCand = sqlite3_expert_report(p,0,EXPERT_REPORT_CANDIDATES);
          135  +      fprintf(stdout, "-- Candidates -------------------------------\n");
          136  +      fprintf(stdout, "%s\n", zCand);
          137  +    }
          138  +    for(i=0; i<nQuery; i++){
          139  +      const char *zSql = sqlite3_expert_report(p, i, EXPERT_REPORT_SQL);
          140  +      const char *zIdx = sqlite3_expert_report(p, i, EXPERT_REPORT_INDEXES);
          141  +      const char *zEQP = sqlite3_expert_report(p, i, EXPERT_REPORT_PLAN);
          142  +      if( zIdx==0 ) zIdx = "(no new indexes)\n";
          143  +      if( iVerbose>0 ){
          144  +        fprintf(stdout, "-- Query %d ----------------------------------\n",i+1);
          145  +        fprintf(stdout, "%s\n\n", zSql);
          146  +      }
          147  +      fprintf(stdout, "%s\n%s\n", zIdx, zEQP);
          148  +    }
          149  +  }else{
          150  +    fprintf(stderr, "Error: %s\n", zErr ? zErr : "?");
          151  +  }
          152  +
          153  +  sqlite3_expert_destroy(p);
          154  +  sqlite3_free(zErr);
          155  +  return rc;
          156  +}

Added ext/expert/expert1.test.

            1  +# 2009 Nov 11
            2  +#
            3  +# The author disclaims copyright to this source code.  In place of
            4  +# a legal notice, here is a blessing:
            5  +#
            6  +#    May you do good and not evil.
            7  +#    May you find forgiveness for yourself and forgive others.
            8  +#    May you share freely, never taking more than you give.
            9  +#
           10  +#***********************************************************************
           11  +#
           12  +# The focus of this file is testing the CLI shell tool. Specifically,
           13  +# the ".recommend" command.
           14  +#
           15  +#
           16  +
           17  +# Test plan:
           18  +#
           19  +#
           20  +if {![info exists testdir]} {
           21  +  set testdir [file join [file dirname [info script]] .. .. test]
           22  +}
           23  +source $testdir/tester.tcl
           24  +set testprefix expert1
           25  +
           26  +if {[info commands sqlite3_expert_new]==""} {
           27  +  finish_test
           28  +  return
           29  +}
           30  +
           31  +set CLI [test_binary_name sqlite3]
           32  +set CMD [test_binary_name sqlite3_expert]
           33  +
           34  +proc squish {txt} {
           35  +  regsub -all {[[:space:]]+} $txt { }
           36  +}
           37  +
           38  +proc do_setup_rec_test {tn setup sql res} {
           39  +  reset_db
           40  +  db eval $setup
           41  +  uplevel [list do_rec_test $tn $sql $res]
           42  +}
           43  +
           44  +foreach {tn setup} {
           45  +  1 {
           46  +    if {![file executable $CMD]} { continue }
           47  +
           48  +    proc do_rec_test {tn sql res} {
           49  +      set res [squish [string trim $res]]
           50  +      set tst [subst -nocommands { 
           51  +        squish [string trim [exec $::CMD -verbose 0 -sql {$sql;} test.db]]
           52  +      }]
           53  +      uplevel [list do_test $tn $tst $res]
           54  +    }
           55  +  }
           56  +  2 {
           57  +    if {[info commands sqlite3_expert_new]==""} { continue }
           58  +
           59  +    proc do_rec_test {tn sql res} {
           60  +      set expert [sqlite3_expert_new db]
           61  +      $expert sql $sql
           62  +      $expert analyze
           63  +
           64  +      set result [list]
           65  +      for {set i 0} {$i < [$expert count]} {incr i} {
           66  +        set idx [string trim [$expert report $i indexes]]
           67  +        if {$idx==""} {set idx "(no new indexes)"}
           68  +        lappend result $idx
           69  +        lappend result [string trim [$expert report $i plan]]
           70  +      }
           71  +
           72  +      $expert destroy
           73  +
           74  +      set tst [subst -nocommands {set {} [squish [join {$result}]]}]
           75  +      uplevel [list do_test $tn $tst [string trim [squish $res]]]
           76  +    }
           77  +  }
           78  +  3 {
           79  +    if {![file executable $CLI]} { continue }
           80  +
           81  +    proc do_rec_test {tn sql res} {
           82  +      set res [squish [string trim $res]]
           83  +      set tst [subst -nocommands { 
           84  +        squish [string trim [exec $::CLI test.db ".expert" {$sql;}]]
           85  +      }]
           86  +      uplevel [list do_test $tn $tst $res]
           87  +    }
           88  +  }
           89  +} {
           90  +
           91  +  eval $setup
           92  +
           93  +
           94  +do_setup_rec_test $tn.1 { CREATE TABLE t1(a, b, c) } {
           95  +  SELECT * FROM t1
           96  +} {
           97  +  (no new indexes)
           98  +  SCAN TABLE t1
           99  +}
          100  +
          101  +do_setup_rec_test $tn.2 {
          102  +  CREATE TABLE t1(a, b, c);
          103  +} {
          104  +  SELECT * FROM t1 WHERE b>?;
          105  +} {
          106  +  CREATE INDEX t1_idx_00000062 ON t1(b);
          107  +  SEARCH TABLE t1 USING INDEX t1_idx_00000062 (b>?)
          108  +}
          109  +
          110  +do_setup_rec_test $tn.3 {
          111  +  CREATE TABLE t1(a, b, c);
          112  +} {
          113  +  SELECT * FROM t1 WHERE b COLLATE nocase BETWEEN ? AND ?
          114  +} {
          115  +  CREATE INDEX t1_idx_3e094c27 ON t1(b COLLATE NOCASE);
          116  +  SEARCH TABLE t1 USING INDEX t1_idx_3e094c27 (b>? AND b<?)
          117  +}
          118  +
          119  +do_setup_rec_test $tn.4 {
          120  +  CREATE TABLE t1(a, b, c);
          121  +} {
          122  +  SELECT a FROM t1 ORDER BY b;
          123  +} {
          124  +  CREATE INDEX t1_idx_00000062 ON t1(b);
          125  +  SCAN TABLE t1 USING INDEX t1_idx_00000062
          126  +}
          127  +
          128  +do_setup_rec_test $tn.5 {
          129  +  CREATE TABLE t1(a, b, c);
          130  +} {
          131  +  SELECT a FROM t1 WHERE a=? ORDER BY b;
          132  +} {
          133  +  CREATE INDEX t1_idx_000123a7 ON t1(a, b);
          134  +  SEARCH TABLE t1 USING COVERING INDEX t1_idx_000123a7 (a=?)
          135  +}
          136  +
          137  +do_setup_rec_test $tn.6 {
          138  +  CREATE TABLE t1(a, b, c);
          139  +} {
          140  +  SELECT min(a) FROM t1
          141  +} {
          142  +  CREATE INDEX t1_idx_00000061 ON t1(a);
          143  +  SEARCH TABLE t1 USING COVERING INDEX t1_idx_00000061
          144  +}
          145  +
          146  +do_setup_rec_test $tn.7 {
          147  +  CREATE TABLE t1(a, b, c);
          148  +} {
          149  +  SELECT * FROM t1 ORDER BY a, b, c;
          150  +} {
          151  +  CREATE INDEX t1_idx_033e95fe ON t1(a, b, c);
          152  +  SCAN TABLE t1 USING COVERING INDEX t1_idx_033e95fe
          153  +}
          154  +
          155  +#do_setup_rec_test $tn.1.8 {
          156  +#  CREATE TABLE t1(a, b, c);
          157  +#} {
          158  +#  SELECT * FROM t1 ORDER BY a ASC, b COLLATE nocase DESC, c ASC;
          159  +#} {
          160  +#  CREATE INDEX t1_idx_5be6e222 ON t1(a, b COLLATE NOCASE DESC, c);
          161  +#  0|0|0|SCAN TABLE t1 USING COVERING INDEX t1_idx_5be6e222
          162  +#}
          163  +
          164  +do_setup_rec_test $tn.8.1 {
          165  +  CREATE TABLE t1(a COLLATE NOCase, b, c);
          166  +} {
          167  +  SELECT * FROM t1 WHERE a=?
          168  +} {
          169  +  CREATE INDEX t1_idx_00000061 ON t1(a);
          170  +  SEARCH TABLE t1 USING INDEX t1_idx_00000061 (a=?)
          171  +}
          172  +do_setup_rec_test $tn.8.2 {
          173  +  CREATE TABLE t1(a, b COLLATE nocase, c);
          174  +} {
          175  +  SELECT * FROM t1 ORDER BY a ASC, b DESC, c ASC;
          176  +} {
          177  +  CREATE INDEX t1_idx_5cb97285 ON t1(a, b DESC, c);
          178  +  SCAN TABLE t1 USING COVERING INDEX t1_idx_5cb97285
          179  +}
          180  +
          181  +
          182  +# Tables with names that require quotes.
          183  +#
          184  +do_setup_rec_test $tn.9.1 {
          185  +  CREATE TABLE "t t"(a, b, c);
          186  +} {
          187  +  SELECT * FROM "t t" WHERE a=?
          188  +} {
          189  +  CREATE INDEX 't t_idx_00000061' ON 't t'(a);
          190  +  SEARCH TABLE t t USING INDEX t t_idx_00000061 (a=?) 
          191  +}
          192  +
          193  +do_setup_rec_test $tn.9.2 {
          194  +  CREATE TABLE "t t"(a, b, c);
          195  +} {
          196  +  SELECT * FROM "t t" WHERE b BETWEEN ? AND ?
          197  +} {
          198  +  CREATE INDEX 't t_idx_00000062' ON 't t'(b);
          199  +  SEARCH TABLE t t USING INDEX t t_idx_00000062 (b>? AND b<?)
          200  +}
          201  +
          202  +# Columns with names that require quotes.
          203  +#
          204  +do_setup_rec_test $tn.10.1 {
          205  +  CREATE TABLE t3(a, "b b", c);
          206  +} {
          207  +  SELECT * FROM t3 WHERE "b b" = ?
          208  +} {
          209  +  CREATE INDEX t3_idx_00050c52 ON t3('b b');
          210  +  SEARCH TABLE t3 USING INDEX t3_idx_00050c52 (b b=?)
          211  +}
          212  +
          213  +do_setup_rec_test $tn.10.2 {
          214  +  CREATE TABLE t3(a, "b b", c);
          215  +} {
          216  +  SELECT * FROM t3 ORDER BY "b b"
          217  +} {
          218  +  CREATE INDEX t3_idx_00050c52 ON t3('b b');
          219  +  SCAN TABLE t3 USING INDEX t3_idx_00050c52
          220  +}
          221  +
          222  +# Transitive constraints
          223  +#
          224  +do_setup_rec_test $tn.11.1 {
          225  +  CREATE TABLE t5(a, b);
          226  +  CREATE TABLE t6(c, d);
          227  +} {
          228  +  SELECT * FROM t5, t6 WHERE a=? AND b=c AND c=?
          229  +} {
          230  +  CREATE INDEX t5_idx_000123a7 ON t5(a, b);
          231  +  CREATE INDEX t6_idx_00000063 ON t6(c);
          232  +  SEARCH TABLE t6 USING INDEX t6_idx_00000063 (c=?) 
          233  +  SEARCH TABLE t5 USING COVERING INDEX t5_idx_000123a7 (a=? AND b=?)
          234  +}
          235  +
          236  +# OR terms.
          237  +#
          238  +do_setup_rec_test $tn.12.1 {
          239  +  CREATE TABLE t7(a, b);
          240  +} {
          241  +  SELECT * FROM t7 WHERE a=? OR b=?
          242  +} {
          243  +  CREATE INDEX t7_idx_00000062 ON t7(b);
          244  +  CREATE INDEX t7_idx_00000061 ON t7(a);
          245  +  MULTI-INDEX OR
          246  +    SEARCH TABLE t7 USING INDEX t7_idx_00000061 (a=?) 
          247  +    SEARCH TABLE t7 USING INDEX t7_idx_00000062 (b=?)
          248  +}
          249  +
          250  +# rowid terms.
          251  +#
          252  +do_setup_rec_test $tn.13.1 {
          253  +  CREATE TABLE t8(a, b);
          254  +} {
          255  +  SELECT * FROM t8 WHERE rowid=?
          256  +} {
          257  +  (no new indexes)
          258  +  SEARCH TABLE t8 USING INTEGER PRIMARY KEY (rowid=?)
          259  +}
          260  +do_setup_rec_test $tn.13.2 {
          261  +  CREATE TABLE t8(a, b);
          262  +} {
          263  +  SELECT * FROM t8 ORDER BY rowid
          264  +} {
          265  +  (no new indexes)
          266  +  SCAN TABLE t8
          267  +}
          268  +do_setup_rec_test $tn.13.3 {
          269  +  CREATE TABLE t8(a, b);
          270  +} {
          271  +  SELECT * FROM t8 WHERE a=? ORDER BY rowid
          272  +} {
          273  +  CREATE INDEX t8_idx_00000061 ON t8(a); 
          274  +  SEARCH TABLE t8 USING INDEX t8_idx_00000061 (a=?)
          275  +}
          276  +
          277  +# Triggers
          278  +#
          279  +do_setup_rec_test $tn.14 {
          280  +  CREATE TABLE t9(a, b, c);
          281  +  CREATE TABLE t10(a, b, c);
          282  +  CREATE TRIGGER t9t AFTER INSERT ON t9 BEGIN
          283  +    UPDATE t10 SET a=new.a WHERE b = new.b;
          284  +  END;
          285  +} {
          286  +  INSERT INTO t9 VALUES(?, ?, ?);
          287  +} {
          288  +  CREATE INDEX t10_idx_00000062 ON t10(b); 
          289  +  SEARCH TABLE t10 USING INDEX t10_idx_00000062 (b=?)
          290  +}
          291  +
          292  +do_setup_rec_test $tn.15 {
          293  +  CREATE TABLE t1(a, b);
          294  +  CREATE TABLE t2(c, d);
          295  +
          296  +  WITH s(i) AS ( VALUES(1) UNION ALL SELECT i+1 FROM s WHERE i<100)
          297  +  INSERT INTO t1 SELECT (i-1)/50, (i-1)/20 FROM s;
          298  +
          299  +  WITH s(i) AS ( VALUES(1) UNION ALL SELECT i+1 FROM s WHERE i<100)
          300  +  INSERT INTO t2 SELECT (i-1)/20, (i-1)/5 FROM s;
          301  +} {
          302  +  SELECT * FROM t2, t1 WHERE b=? AND d=? AND t2.rowid=t1.rowid
          303  +} {
          304  +  CREATE INDEX t2_idx_00000064 ON t2(d);
          305  +  SEARCH TABLE t2 USING INDEX t2_idx_00000064 (d=?) 
          306  +  SEARCH TABLE t1 USING INTEGER PRIMARY KEY (rowid=?)
          307  +}
          308  +
          309  +do_setup_rec_test $tn.16 {
          310  +  CREATE TABLE t1(a, b);
          311  +} {
          312  +  SELECT * FROM t1 WHERE b IS NOT NULL;
          313  +} {
          314  +  (no new indexes)
          315  +  SCAN TABLE t1
          316  +}
          317  +
          318  +}
          319  +
          320  +proc do_candidates_test {tn sql res} {
          321  +  set res [squish [string trim $res]]
          322  +
          323  +  set expert [sqlite3_expert_new db]
          324  +  $expert sql $sql
          325  +  $expert analyze
          326  +
          327  +  set candidates [squish [string trim [$expert report 0 candidates]]]
          328  +  $expert destroy
          329  +
          330  +  uplevel [list do_test $tn [list set {} $candidates] $res]
          331  +}
          332  +
          333  +
          334  +reset_db
          335  +do_execsql_test 4.0 {
          336  +  CREATE TABLE t1(a, b);
          337  +  CREATE TABLE t2(c, d);
          338  +
          339  +  WITH s(i) AS ( VALUES(1) UNION ALL SELECT i+1 FROM s WHERE i<100)
          340  +  INSERT INTO t1 SELECT (i-1)/50, (i-1)/20 FROM s;
          341  +
          342  +  WITH s(i) AS ( VALUES(1) UNION ALL SELECT i+1 FROM s WHERE i<100)
          343  +  INSERT INTO t2 SELECT (i-1)/20, (i-1)/5 FROM s;
          344  +}
          345  +do_candidates_test 4.1 {
          346  +  SELECT * FROM t1,t2 WHERE (b=? OR a=?) AND (c=? OR d=?)
          347  +} {
          348  +  CREATE INDEX t1_idx_00000062 ON t1(b); -- stat1: 100 20 
          349  +  CREATE INDEX t1_idx_00000061 ON t1(a); -- stat1: 100 50 
          350  +  CREATE INDEX t2_idx_00000063 ON t2(c); -- stat1: 100 20 
          351  +  CREATE INDEX t2_idx_00000064 ON t2(d); -- stat1: 100 5
          352  +}
          353  +
          354  +do_candidates_test 4.2 {
          355  +  SELECT * FROM t1,t2 WHERE a=? AND b=? AND c=? AND d=?
          356  +} {
          357  +  CREATE INDEX t1_idx_000123a7 ON t1(a, b); -- stat1: 100 50 17
          358  +  CREATE INDEX t2_idx_0001295b ON t2(c, d); -- stat1: 100 20 5
          359  +}
          360  +
          361  +do_execsql_test 4.3 {
          362  +  CREATE INDEX t1_idx_00000061 ON t1(a); -- stat1: 100 50 
          363  +  CREATE INDEX t1_idx_00000062 ON t1(b); -- stat1: 100 20 
          364  +  CREATE INDEX t1_idx_000123a7 ON t1(a, b); -- stat1: 100 50 16
          365  +
          366  +  CREATE INDEX t2_idx_00000063 ON t2(c); -- stat1: 100 20 
          367  +  CREATE INDEX t2_idx_00000064 ON t2(d); -- stat1: 100 5
          368  +  CREATE INDEX t2_idx_0001295b ON t2(c, d); -- stat1: 100 20 5
          369  +
          370  +  ANALYZE;
          371  +  SELECT * FROM sqlite_stat1 ORDER BY 1, 2;
          372  +} {
          373  +  t1 t1_idx_00000061 {100 50} 
          374  +  t1 t1_idx_00000062 {100 20}
          375  +  t1 t1_idx_000123a7 {100 50 17}
          376  +  t2 t2_idx_00000063 {100 20} 
          377  +  t2 t2_idx_00000064 {100 5} 
          378  +  t2 t2_idx_0001295b {100 20 5}
          379  +}
          380  +
          381  +
          382  +finish_test

Added ext/expert/sqlite3expert.c.

            1  +/*
            2  +** 2017 April 09
            3  +**
            4  +** The author disclaims copyright to this source code.  In place of
            5  +** a legal notice, here is a blessing:
            6  +**
            7  +**    May you do good and not evil.
            8  +**    May you find forgiveness for yourself and forgive others.
            9  +**    May you share freely, never taking more than you give.
           10  +**
           11  +*************************************************************************
           12  +*/
           13  +#include "sqlite3expert.h"
           14  +#include <assert.h>
           15  +#include <string.h>
           16  +#include <stdio.h>
           17  +
           18  +#ifndef SQLITE_OMIT_VIRTUALTABLE 
           19  +
           20  +typedef sqlite3_int64 i64;
           21  +typedef sqlite3_uint64 u64;
           22  +
           23  +typedef struct IdxColumn IdxColumn;
           24  +typedef struct IdxConstraint IdxConstraint;
           25  +typedef struct IdxScan IdxScan;
           26  +typedef struct IdxStatement IdxStatement;
           27  +typedef struct IdxTable IdxTable;
           28  +typedef struct IdxWrite IdxWrite;
           29  +
           30  +#define STRLEN  (int)strlen
           31  +
           32  +/*
           33  +** A temp table name that we assume no user database will actually use.
           34  +** If this assumption proves incorrect triggers on the table with the
           35  +** conflicting name will be ignored.
           36  +*/
           37  +#define UNIQUE_TABLE_NAME "t592690916721053953805701627921227776"
           38  +
           39  +/*
           40  +** A single constraint. Equivalent to either "col = ?" or "col < ?" (or
           41  +** any other type of single-ended range constraint on a column).
           42  +**
           43  +** pLink:
           44  +**   Used to temporarily link IdxConstraint objects into lists while
           45  +**   creating candidate indexes.
           46  +*/
           47  +struct IdxConstraint {
           48  +  char *zColl;                    /* Collation sequence */
           49  +  int bRange;                     /* True for range, false for eq */
           50  +  int iCol;                       /* Constrained table column */
           51  +  int bFlag;                      /* Used by idxFindCompatible() */
           52  +  int bDesc;                      /* True if ORDER BY <expr> DESC */
           53  +  IdxConstraint *pNext;           /* Next constraint in pEq or pRange list */
           54  +  IdxConstraint *pLink;           /* See above */
           55  +};
           56  +
           57  +/*
           58  +** A single scan of a single table.
           59  +*/
           60  +struct IdxScan {
           61  +  IdxTable *pTab;                 /* Associated table object */
           62  +  int iDb;                        /* Database containing table zTable */
           63  +  i64 covering;                   /* Mask of columns required for cov. index */
           64  +  IdxConstraint *pOrder;          /* ORDER BY columns */
           65  +  IdxConstraint *pEq;             /* List of == constraints */
           66  +  IdxConstraint *pRange;          /* List of < constraints */
           67  +  IdxScan *pNextScan;             /* Next IdxScan object for same analysis */
           68  +};
           69  +
           70  +/*
           71  +** Information regarding a single database table. Extracted from 
           72  +** "PRAGMA table_info" by function idxGetTableInfo().
           73  +*/
           74  +struct IdxColumn {
           75  +  char *zName;
           76  +  char *zColl;
           77  +  int iPk;
           78  +};
           79  +struct IdxTable {
           80  +  int nCol;
           81  +  char *zName;                    /* Table name */
           82  +  IdxColumn *aCol;
           83  +  IdxTable *pNext;                /* Next table in linked list of all tables */
           84  +};
           85  +
           86  +/*
           87  +** An object of the following type is created for each unique table/write-op
           88  +** seen. The objects are stored in a singly-linked list beginning at
           89  +** sqlite3expert.pWrite.
           90  +*/
           91  +struct IdxWrite {
           92  +  IdxTable *pTab;
           93  +  int eOp;                        /* SQLITE_UPDATE, DELETE or INSERT */
           94  +  IdxWrite *pNext;
           95  +};
           96  +
           97  +/*
           98  +** Each statement being analyzed is represented by an instance of this
           99  +** structure.
          100  +*/
          101  +struct IdxStatement {
          102  +  int iId;                        /* Statement number */
          103  +  char *zSql;                     /* SQL statement */
          104  +  char *zIdx;                     /* Indexes */
          105  +  char *zEQP;                     /* Plan */
          106  +  IdxStatement *pNext;
          107  +};
          108  +
          109  +
          110  +/*
          111  +** A hash table for storing strings. With space for a payload string
          112  +** with each entry. Methods are:
          113  +**
          114  +**   idxHashInit()
          115  +**   idxHashClear()
          116  +**   idxHashAdd()
          117  +**   idxHashSearch()
          118  +*/
          119  +#define IDX_HASH_SIZE 1023
          120  +typedef struct IdxHashEntry IdxHashEntry;
          121  +typedef struct IdxHash IdxHash;
          122  +struct IdxHashEntry {
          123  +  char *zKey;                     /* nul-terminated key */
          124  +  char *zVal;                     /* nul-terminated value string */
          125  +  char *zVal2;                    /* nul-terminated value string 2 */
          126  +  IdxHashEntry *pHashNext;        /* Next entry in same hash bucket */
          127  +  IdxHashEntry *pNext;            /* Next entry in hash */
          128  +};
          129  +struct IdxHash {
          130  +  IdxHashEntry *pFirst;
          131  +  IdxHashEntry *aHash[IDX_HASH_SIZE];
          132  +};
          133  +
          134  +/*
          135  +** sqlite3expert object.
          136  +*/
          137  +struct sqlite3expert {
          138  +  int iSample;                    /* Percentage of tables to sample for stat1 */
          139  +  sqlite3 *db;                    /* User database */
          140  +  sqlite3 *dbm;                   /* In-memory db for this analysis */
          141  +  sqlite3 *dbv;                   /* Vtab schema for this analysis */
          142  +  IdxTable *pTable;               /* List of all IdxTable objects */
          143  +  IdxScan *pScan;                 /* List of scan objects */
          144  +  IdxWrite *pWrite;               /* List of write objects */
          145  +  IdxStatement *pStatement;       /* List of IdxStatement objects */
          146  +  int bRun;                       /* True once analysis has run */
          147  +  char **pzErrmsg;
          148  +  int rc;                         /* Error code from whereinfo hook */
          149  +  IdxHash hIdx;                   /* Hash containing all candidate indexes */
          150  +  char *zCandidates;              /* For EXPERT_REPORT_CANDIDATES */
          151  +};
          152  +
          153  +
          154  +/*
          155  +** Allocate and return nByte bytes of zeroed memory using sqlite3_malloc(). 
          156  +** If the allocation fails, set *pRc to SQLITE_NOMEM and return NULL.
          157  +*/
          158  +static void *idxMalloc(int *pRc, int nByte){
          159  +  void *pRet;
          160  +  assert( *pRc==SQLITE_OK );
          161  +  assert( nByte>0 );
          162  +  pRet = sqlite3_malloc(nByte);
          163  +  if( pRet ){
          164  +    memset(pRet, 0, nByte);
          165  +  }else{
          166  +    *pRc = SQLITE_NOMEM;
          167  +  }
          168  +  return pRet;
          169  +}
          170  +
          171  +/*
          172  +** Initialize an IdxHash hash table.
          173  +*/
          174  +static void idxHashInit(IdxHash *pHash){
          175  +  memset(pHash, 0, sizeof(IdxHash));
          176  +}
          177  +
          178  +/*
          179  +** Reset an IdxHash hash table.
          180  +*/
          181  +static void idxHashClear(IdxHash *pHash){
          182  +  int i;
          183  +  for(i=0; i<IDX_HASH_SIZE; i++){
          184  +    IdxHashEntry *pEntry;
          185  +    IdxHashEntry *pNext;
          186  +    for(pEntry=pHash->aHash[i]; pEntry; pEntry=pNext){
          187  +      pNext = pEntry->pHashNext;
          188  +      sqlite3_free(pEntry->zVal2);
          189  +      sqlite3_free(pEntry);
          190  +    }
          191  +  }
          192  +  memset(pHash, 0, sizeof(IdxHash));
          193  +}
          194  +
          195  +/*
          196  +** Return the index of the hash bucket that the string specified by the
          197  +** arguments to this function belongs.
          198  +*/
          199  +static int idxHashString(const char *z, int n){
          200  +  unsigned int ret = 0;
          201  +  int i;
          202  +  for(i=0; i<n; i++){
          203  +    ret += (ret<<3) + (unsigned char)(z[i]);
          204  +  }
          205  +  return (int)(ret % IDX_HASH_SIZE);
          206  +}
          207  +
          208  +/*
          209  +** If zKey is already present in the hash table, return non-zero and do
          210  +** nothing. Otherwise, add an entry with key zKey and payload string zVal to
          211  +** the hash table passed as the second argument. 
          212  +*/
          213  +static int idxHashAdd(
          214  +  int *pRc, 
          215  +  IdxHash *pHash, 
          216  +  const char *zKey,
          217  +  const char *zVal
          218  +){
          219  +  int nKey = STRLEN(zKey);
          220  +  int iHash = idxHashString(zKey, nKey);
          221  +  int nVal = (zVal ? STRLEN(zVal) : 0);
          222  +  IdxHashEntry *pEntry;
          223  +  assert( iHash>=0 );
          224  +  for(pEntry=pHash->aHash[iHash]; pEntry; pEntry=pEntry->pHashNext){
          225  +    if( STRLEN(pEntry->zKey)==nKey && 0==memcmp(pEntry->zKey, zKey, nKey) ){
          226  +      return 1;
          227  +    }
          228  +  }
          229  +  pEntry = idxMalloc(pRc, sizeof(IdxHashEntry) + nKey+1 + nVal+1);
          230  +  if( pEntry ){
          231  +    pEntry->zKey = (char*)&pEntry[1];
          232  +    memcpy(pEntry->zKey, zKey, nKey);
          233  +    if( zVal ){
          234  +      pEntry->zVal = &pEntry->zKey[nKey+1];
          235  +      memcpy(pEntry->zVal, zVal, nVal);
          236  +    }
          237  +    pEntry->pHashNext = pHash->aHash[iHash];
          238  +    pHash->aHash[iHash] = pEntry;
          239  +
          240  +    pEntry->pNext = pHash->pFirst;
          241  +    pHash->pFirst = pEntry;
          242  +  }
          243  +  return 0;
          244  +}
          245  +
          246  +/*
          247  +** If zKey/nKey is present in the hash table, return a pointer to the 
          248  +** hash-entry object.
          249  +*/
          250  +static IdxHashEntry *idxHashFind(IdxHash *pHash, const char *zKey, int nKey){
          251  +  int iHash;
          252  +  IdxHashEntry *pEntry;
          253  +  if( nKey<0 ) nKey = STRLEN(zKey);
          254  +  iHash = idxHashString(zKey, nKey);
          255  +  assert( iHash>=0 );
          256  +  for(pEntry=pHash->aHash[iHash]; pEntry; pEntry=pEntry->pHashNext){
          257  +    if( STRLEN(pEntry->zKey)==nKey && 0==memcmp(pEntry->zKey, zKey, nKey) ){
          258  +      return pEntry;
          259  +    }
          260  +  }
          261  +  return 0;
          262  +}
          263  +
          264  +/*
          265  +** If the hash table contains an entry with a key equal to the string
          266  +** passed as the final two arguments to this function, return a pointer
          267  +** to the payload string. Otherwise, if zKey/nKey is not present in the
          268  +** hash table, return NULL.
          269  +*/
          270  +static const char *idxHashSearch(IdxHash *pHash, const char *zKey, int nKey){
          271  +  IdxHashEntry *pEntry = idxHashFind(pHash, zKey, nKey);
          272  +  if( pEntry ) return pEntry->zVal;
          273  +  return 0;
          274  +}
          275  +
          276  +/*
          277  +** Allocate and return a new IdxConstraint object. Set the IdxConstraint.zColl
          278  +** variable to point to a copy of nul-terminated string zColl.
          279  +*/
          280  +static IdxConstraint *idxNewConstraint(int *pRc, const char *zColl){
          281  +  IdxConstraint *pNew;
          282  +  int nColl = STRLEN(zColl);
          283  +
          284  +  assert( *pRc==SQLITE_OK );
          285  +  pNew = (IdxConstraint*)idxMalloc(pRc, sizeof(IdxConstraint) * nColl + 1);
          286  +  if( pNew ){
          287  +    pNew->zColl = (char*)&pNew[1];
          288  +    memcpy(pNew->zColl, zColl, nColl+1);
          289  +  }
          290  +  return pNew;
          291  +}
          292  +
          293  +/*
          294  +** An error associated with database handle db has just occurred. Pass
          295  +** the error message to callback function xOut.
          296  +*/
          297  +static void idxDatabaseError(
          298  +  sqlite3 *db,                    /* Database handle */
          299  +  char **pzErrmsg                 /* Write error here */
          300  +){
          301  +  *pzErrmsg = sqlite3_mprintf("%s", sqlite3_errmsg(db));
          302  +}
          303  +
          304  +/*
          305  +** Prepare an SQL statement.
          306  +*/
          307  +static int idxPrepareStmt(
          308  +  sqlite3 *db,                    /* Database handle to compile against */
          309  +  sqlite3_stmt **ppStmt,          /* OUT: Compiled SQL statement */
          310  +  char **pzErrmsg,                /* OUT: sqlite3_malloc()ed error message */
          311  +  const char *zSql                /* SQL statement to compile */
          312  +){
          313  +  int rc = sqlite3_prepare_v2(db, zSql, -1, ppStmt, 0);
          314  +  if( rc!=SQLITE_OK ){
          315  +    *ppStmt = 0;
          316  +    idxDatabaseError(db, pzErrmsg);
          317  +  }
          318  +  return rc;
          319  +}
          320  +
          321  +/*
          322  +** Prepare an SQL statement using the results of a printf() formatting.
          323  +*/
          324  +static int idxPrintfPrepareStmt(
          325  +  sqlite3 *db,                    /* Database handle to compile against */
          326  +  sqlite3_stmt **ppStmt,          /* OUT: Compiled SQL statement */
          327  +  char **pzErrmsg,                /* OUT: sqlite3_malloc()ed error message */
          328  +  const char *zFmt,               /* printf() format of SQL statement */
          329  +  ...                             /* Trailing printf() arguments */
          330  +){
          331  +  va_list ap;
          332  +  int rc;
          333  +  char *zSql;
          334  +  va_start(ap, zFmt);
          335  +  zSql = sqlite3_vmprintf(zFmt, ap);
          336  +  if( zSql==0 ){
          337  +    rc = SQLITE_NOMEM;
          338  +  }else{
          339  +    rc = idxPrepareStmt(db, ppStmt, pzErrmsg, zSql);
          340  +    sqlite3_free(zSql);
          341  +  }
          342  +  va_end(ap);
          343  +  return rc;
          344  +}
          345  +
          346  +
          347  +/*************************************************************************
          348  +** Beginning of virtual table implementation.
          349  +*/
          350  +typedef struct ExpertVtab ExpertVtab;
          351  +struct ExpertVtab {
          352  +  sqlite3_vtab base;
          353  +  IdxTable *pTab;
          354  +  sqlite3expert *pExpert;
          355  +};
          356  +
          357  +typedef struct ExpertCsr ExpertCsr;
          358  +struct ExpertCsr {
          359  +  sqlite3_vtab_cursor base;
          360  +  sqlite3_stmt *pData;
          361  +};
          362  +
          363  +static char *expertDequote(const char *zIn){
          364  +  int n = STRLEN(zIn);
          365  +  char *zRet = sqlite3_malloc(n);
          366  +
          367  +  assert( zIn[0]=='\'' );
          368  +  assert( zIn[n-1]=='\'' );
          369  +
          370  +  if( zRet ){
          371  +    int iOut = 0;
          372  +    int iIn = 0;
          373  +    for(iIn=1; iIn<(n-1); iIn++){
          374  +      if( zIn[iIn]=='\'' ){
          375  +        assert( zIn[iIn+1]=='\'' );
          376  +        iIn++;
          377  +      }
          378  +      zRet[iOut++] = zIn[iIn];
          379  +    }
          380  +    zRet[iOut] = '\0';
          381  +  }
          382  +
          383  +  return zRet;
          384  +}
          385  +
          386  +/* 
          387  +** This function is the implementation of both the xConnect and xCreate
          388  +** methods of the r-tree virtual table.
          389  +**
          390  +**   argv[0]   -> module name
          391  +**   argv[1]   -> database name
          392  +**   argv[2]   -> table name
          393  +**   argv[...] -> column names...
          394  +*/
          395  +static int expertConnect(
          396  +  sqlite3 *db,
          397  +  void *pAux,
          398  +  int argc, const char *const*argv,
          399  +  sqlite3_vtab **ppVtab,
          400  +  char **pzErr
          401  +){
          402  +  sqlite3expert *pExpert = (sqlite3expert*)pAux;
          403  +  ExpertVtab *p = 0;
          404  +  int rc;
          405  +
          406  +  if( argc!=4 ){
          407  +    *pzErr = sqlite3_mprintf("internal error!");
          408  +    rc = SQLITE_ERROR;
          409  +  }else{
          410  +    char *zCreateTable = expertDequote(argv[3]);
          411  +    if( zCreateTable ){
          412  +      rc = sqlite3_declare_vtab(db, zCreateTable);
          413  +      if( rc==SQLITE_OK ){
          414  +        p = idxMalloc(&rc, sizeof(ExpertVtab));
          415  +      }
          416  +      if( rc==SQLITE_OK ){
          417  +        p->pExpert = pExpert;
          418  +        p->pTab = pExpert->pTable;
          419  +        assert( sqlite3_stricmp(p->pTab->zName, argv[2])==0 );
          420  +      }
          421  +      sqlite3_free(zCreateTable);
          422  +    }else{
          423  +      rc = SQLITE_NOMEM;
          424  +    }
          425  +  }
          426  +
          427  +  *ppVtab = (sqlite3_vtab*)p;
          428  +  return rc;
          429  +}
          430  +
          431  +static int expertDisconnect(sqlite3_vtab *pVtab){
          432  +  ExpertVtab *p = (ExpertVtab*)pVtab;
          433  +  sqlite3_free(p);
          434  +  return SQLITE_OK;
          435  +}
          436  +
          437  +static int expertBestIndex(sqlite3_vtab *pVtab, sqlite3_index_info *pIdxInfo){
          438  +  ExpertVtab *p = (ExpertVtab*)pVtab;
          439  +  int rc = SQLITE_OK;
          440  +  int n = 0;
          441  +  IdxScan *pScan;
          442  +  const int opmask = 
          443  +    SQLITE_INDEX_CONSTRAINT_EQ | SQLITE_INDEX_CONSTRAINT_GT |
          444  +    SQLITE_INDEX_CONSTRAINT_LT | SQLITE_INDEX_CONSTRAINT_GE |
          445  +    SQLITE_INDEX_CONSTRAINT_LE;
          446  +
          447  +  pScan = idxMalloc(&rc, sizeof(IdxScan));
          448  +  if( pScan ){
          449  +    int i;
          450  +
          451  +    /* Link the new scan object into the list */
          452  +    pScan->pTab = p->pTab;
          453  +    pScan->pNextScan = p->pExpert->pScan;
          454  +    p->pExpert->pScan = pScan;
          455  +
          456  +    /* Add the constraints to the IdxScan object */
          457  +    for(i=0; i<pIdxInfo->nConstraint; i++){
          458  +      struct sqlite3_index_constraint *pCons = &pIdxInfo->aConstraint[i];
          459  +      if( pCons->usable 
          460  +       && pCons->iColumn>=0 
          461  +       && p->pTab->aCol[pCons->iColumn].iPk==0
          462  +       && (pCons->op & opmask) 
          463  +      ){
          464  +        IdxConstraint *pNew;
          465  +        const char *zColl = sqlite3_vtab_collation(pIdxInfo, i);
          466  +        pNew = idxNewConstraint(&rc, zColl);
          467  +        if( pNew ){
          468  +          pNew->iCol = pCons->iColumn;
          469  +          if( pCons->op==SQLITE_INDEX_CONSTRAINT_EQ ){
          470  +            pNew->pNext = pScan->pEq;
          471  +            pScan->pEq = pNew;
          472  +          }else{
          473  +            pNew->bRange = 1;
          474  +            pNew->pNext = pScan->pRange;
          475  +            pScan->pRange = pNew;
          476  +          }
          477  +        }
          478  +        n++;
          479  +        pIdxInfo->aConstraintUsage[i].argvIndex = n;
          480  +      }
          481  +    }
          482  +
          483  +    /* Add the ORDER BY to the IdxScan object */
          484  +    for(i=pIdxInfo->nOrderBy-1; i>=0; i--){
          485  +      int iCol = pIdxInfo->aOrderBy[i].iColumn;
          486  +      if( iCol>=0 ){
          487  +        IdxConstraint *pNew = idxNewConstraint(&rc, p->pTab->aCol[iCol].zColl);
          488  +        if( pNew ){
          489  +          pNew->iCol = iCol;
          490  +          pNew->bDesc = pIdxInfo->aOrderBy[i].desc;
          491  +          pNew->pNext = pScan->pOrder;
          492  +          pNew->pLink = pScan->pOrder;
          493  +          pScan->pOrder = pNew;
          494  +          n++;
          495  +        }
          496  +      }
          497  +    }
          498  +  }
          499  +
          500  +  pIdxInfo->estimatedCost = 1000000.0 / (n+1);
          501  +  return rc;
          502  +}
          503  +
          504  +static int expertUpdate(
          505  +  sqlite3_vtab *pVtab, 
          506  +  int nData, 
          507  +  sqlite3_value **azData, 
          508  +  sqlite_int64 *pRowid
          509  +){
          510  +  (void)pVtab;
          511  +  (void)nData;
          512  +  (void)azData;
          513  +  (void)pRowid;
          514  +  return SQLITE_OK;
          515  +}
          516  +
          517  +/* 
          518  +** Virtual table module xOpen method.
          519  +*/
          520  +static int expertOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
          521  +  int rc = SQLITE_OK;
          522  +  ExpertCsr *pCsr;
          523  +  (void)pVTab;
          524  +  pCsr = idxMalloc(&rc, sizeof(ExpertCsr));
          525  +  *ppCursor = (sqlite3_vtab_cursor*)pCsr;
          526  +  return rc;
          527  +}
          528  +
          529  +/* 
          530  +** Virtual table module xClose method.
          531  +*/
          532  +static int expertClose(sqlite3_vtab_cursor *cur){
          533  +  ExpertCsr *pCsr = (ExpertCsr*)cur;
          534  +  sqlite3_finalize(pCsr->pData);
          535  +  sqlite3_free(pCsr);
          536  +  return SQLITE_OK;
          537  +}
          538  +
          539  +/*
          540  +** Virtual table module xEof method.
          541  +**
          542  +** Return non-zero if the cursor does not currently point to a valid 
          543  +** record (i.e if the scan has finished), or zero otherwise.
          544  +*/
          545  +static int expertEof(sqlite3_vtab_cursor *cur){
          546  +  ExpertCsr *pCsr = (ExpertCsr*)cur;
          547  +  return pCsr->pData==0;
          548  +}
          549  +
          550  +/* 
          551  +** Virtual table module xNext method.
          552  +*/
          553  +static int expertNext(sqlite3_vtab_cursor *cur){
          554  +  ExpertCsr *pCsr = (ExpertCsr*)cur;
          555  +  int rc = SQLITE_OK;
          556  +
          557  +  assert( pCsr->pData );
          558  +  rc = sqlite3_step(pCsr->pData);
          559  +  if( rc!=SQLITE_ROW ){
          560  +    rc = sqlite3_finalize(pCsr->pData);
          561  +    pCsr->pData = 0;
          562  +  }else{
          563  +    rc = SQLITE_OK;
          564  +  }
          565  +
          566  +  return rc;
          567  +}
          568  +
          569  +/* 
          570  +** Virtual table module xRowid method.
          571  +*/
          572  +static int expertRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
          573  +  (void)cur;
          574  +  *pRowid = 0;
          575  +  return SQLITE_OK;
          576  +}
          577  +
          578  +/* 
          579  +** Virtual table module xColumn method.
          580  +*/
          581  +static int expertColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){
          582  +  ExpertCsr *pCsr = (ExpertCsr*)cur;
          583  +  sqlite3_value *pVal;
          584  +  pVal = sqlite3_column_value(pCsr->pData, i);
          585  +  if( pVal ){
          586  +    sqlite3_result_value(ctx, pVal);
          587  +  }
          588  +  return SQLITE_OK;
          589  +}
          590  +
          591  +/* 
          592  +** Virtual table module xFilter method.
          593  +*/
          594  +static int expertFilter(
          595  +  sqlite3_vtab_cursor *cur, 
          596  +  int idxNum, const char *idxStr,
          597  +  int argc, sqlite3_value **argv
          598  +){
          599  +  ExpertCsr *pCsr = (ExpertCsr*)cur;
          600  +  ExpertVtab *pVtab = (ExpertVtab*)(cur->pVtab);
          601  +  sqlite3expert *pExpert = pVtab->pExpert;
          602  +  int rc;
          603  +
          604  +  (void)idxNum;
          605  +  (void)idxStr;
          606  +  (void)argc;
          607  +  (void)argv;
          608  +  rc = sqlite3_finalize(pCsr->pData);
          609  +  pCsr->pData = 0;
          610  +  if( rc==SQLITE_OK ){
          611  +    rc = idxPrintfPrepareStmt(pExpert->db, &pCsr->pData, &pVtab->base.zErrMsg,
          612  +        "SELECT * FROM main.%Q WHERE sample()", pVtab->pTab->zName
          613  +    );
          614  +  }
          615  +
          616  +  if( rc==SQLITE_OK ){
          617  +    rc = expertNext(cur);
          618  +  }
          619  +  return rc;
          620  +}
          621  +
          622  +static int idxRegisterVtab(sqlite3expert *p){
          623  +  static sqlite3_module expertModule = {
          624  +    2,                            /* iVersion */
          625  +    expertConnect,                /* xCreate - create a table */
          626  +    expertConnect,                /* xConnect - connect to an existing table */
          627  +    expertBestIndex,              /* xBestIndex - Determine search strategy */
          628  +    expertDisconnect,             /* xDisconnect - Disconnect from a table */
          629  +    expertDisconnect,             /* xDestroy - Drop a table */
          630  +    expertOpen,                   /* xOpen - open a cursor */
          631  +    expertClose,                  /* xClose - close a cursor */
          632  +    expertFilter,                 /* xFilter - configure scan constraints */
          633  +    expertNext,                   /* xNext - advance a cursor */
          634  +    expertEof,                    /* xEof */
          635  +    expertColumn,                 /* xColumn - read data */
          636  +    expertRowid,                  /* xRowid - read data */
          637  +    expertUpdate,                 /* xUpdate - write data */
          638  +    0,                            /* xBegin - begin transaction */
          639  +    0,                            /* xSync - sync transaction */
          640  +    0,                            /* xCommit - commit transaction */
          641  +    0,                            /* xRollback - rollback transaction */
          642  +    0,                            /* xFindFunction - function overloading */
          643  +    0,                            /* xRename - rename the table */
          644  +    0,                            /* xSavepoint */
          645  +    0,                            /* xRelease */
          646  +    0,                            /* xRollbackTo */
          647  +  };
          648  +
          649  +  return sqlite3_create_module(p->dbv, "expert", &expertModule, (void*)p);
          650  +}
          651  +/*
          652  +** End of virtual table implementation.
          653  +*************************************************************************/
          654  +/*
          655  +** Finalize SQL statement pStmt. If (*pRc) is SQLITE_OK when this function
          656  +** is called, set it to the return value of sqlite3_finalize() before
          657  +** returning. Otherwise, discard the sqlite3_finalize() return value.
          658  +*/
          659  +static void idxFinalize(int *pRc, sqlite3_stmt *pStmt){
          660  +  int rc = sqlite3_finalize(pStmt);
          661  +  if( *pRc==SQLITE_OK ) *pRc = rc;
          662  +}
          663  +
          664  +/*
          665  +** Attempt to allocate an IdxTable structure corresponding to table zTab
          666  +** in the main database of connection db. If successful, set (*ppOut) to
          667  +** point to the new object and return SQLITE_OK. Otherwise, return an
          668  +** SQLite error code and set (*ppOut) to NULL. In this case *pzErrmsg may be
          669  +** set to point to an error string.
          670  +**
          671  +** It is the responsibility of the caller to eventually free either the
          672  +** IdxTable object or error message using sqlite3_free().
          673  +*/
          674  +static int idxGetTableInfo(
          675  +  sqlite3 *db,                    /* Database connection to read details from */
          676  +  const char *zTab,               /* Table name */
          677  +  IdxTable **ppOut,               /* OUT: New object (if successful) */
          678  +  char **pzErrmsg                 /* OUT: Error message (if not) */
          679  +){
          680  +  sqlite3_stmt *p1 = 0;
          681  +  int nCol = 0;
          682  +  int nTab = STRLEN(zTab);
          683  +  int nByte = sizeof(IdxTable) + nTab + 1;
          684  +  IdxTable *pNew = 0;
          685  +  int rc, rc2;
          686  +  char *pCsr = 0;
          687  +
          688  +  rc = idxPrintfPrepareStmt(db, &p1, pzErrmsg, "PRAGMA table_info=%Q", zTab);
          689  +  while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(p1) ){
          690  +    const char *zCol = (const char*)sqlite3_column_text(p1, 1);
          691  +    nByte += 1 + STRLEN(zCol);
          692  +    rc = sqlite3_table_column_metadata(
          693  +        db, "main", zTab, zCol, 0, &zCol, 0, 0, 0
          694  +    );
          695  +    nByte += 1 + STRLEN(zCol);
          696  +    nCol++;
          697  +  }
          698  +  rc2 = sqlite3_reset(p1);
          699  +  if( rc==SQLITE_OK ) rc = rc2;
          700  +
          701  +  nByte += sizeof(IdxColumn) * nCol;
          702  +  if( rc==SQLITE_OK ){
          703  +    pNew = idxMalloc(&rc, nByte);
          704  +  }
          705  +  if( rc==SQLITE_OK ){
          706  +    pNew->aCol = (IdxColumn*)&pNew[1];
          707  +    pNew->nCol = nCol;
          708  +    pCsr = (char*)&pNew->aCol[nCol];
          709  +  }
          710  +
          711  +  nCol = 0;
          712  +  while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(p1) ){
          713  +    const char *zCol = (const char*)sqlite3_column_text(p1, 1);
          714  +    int nCopy = STRLEN(zCol) + 1;
          715  +    pNew->aCol[nCol].zName = pCsr;
          716  +    pNew->aCol[nCol].iPk = sqlite3_column_int(p1, 5);
          717  +    memcpy(pCsr, zCol, nCopy);
          718  +    pCsr += nCopy;
          719  +
          720  +    rc = sqlite3_table_column_metadata(
          721  +        db, "main", zTab, zCol, 0, &zCol, 0, 0, 0
          722  +    );
          723  +    if( rc==SQLITE_OK ){
          724  +      nCopy = STRLEN(zCol) + 1;
          725  +      pNew->aCol[nCol].zColl = pCsr;
          726  +      memcpy(pCsr, zCol, nCopy);
          727  +      pCsr += nCopy;
          728  +    }
          729  +
          730  +    nCol++;
          731  +  }
          732  +  idxFinalize(&rc, p1);
          733  +
          734  +  if( rc!=SQLITE_OK ){
          735  +    sqlite3_free(pNew);
          736  +    pNew = 0;
          737  +  }else{
          738  +    pNew->zName = pCsr;
          739  +    memcpy(pNew->zName, zTab, nTab+1);
          740  +  }
          741  +
          742  +  *ppOut = pNew;
          743  +  return rc;
          744  +}
          745  +
          746  +/*
          747  +** This function is a no-op if *pRc is set to anything other than 
          748  +** SQLITE_OK when it is called.
          749  +**
          750  +** If *pRc is initially set to SQLITE_OK, then the text specified by
          751  +** the printf() style arguments is appended to zIn and the result returned
          752  +** in a buffer allocated by sqlite3_malloc(). sqlite3_free() is called on
          753  +** zIn before returning.
          754  +*/
          755  +static char *idxAppendText(int *pRc, char *zIn, const char *zFmt, ...){
          756  +  va_list ap;
          757  +  char *zAppend = 0;
          758  +  char *zRet = 0;
          759  +  int nIn = zIn ? STRLEN(zIn) : 0;
          760  +  int nAppend = 0;
          761  +  va_start(ap, zFmt);
          762  +  if( *pRc==SQLITE_OK ){
          763  +    zAppend = sqlite3_vmprintf(zFmt, ap);
          764  +    if( zAppend ){
          765  +      nAppend = STRLEN(zAppend);
          766  +      zRet = (char*)sqlite3_malloc(nIn + nAppend + 1);
          767  +    }
          768  +    if( zAppend && zRet ){
          769  +      if( nIn ) memcpy(zRet, zIn, nIn);
          770  +      memcpy(&zRet[nIn], zAppend, nAppend+1);
          771  +    }else{
          772  +      sqlite3_free(zRet);
          773  +      zRet = 0;
          774  +      *pRc = SQLITE_NOMEM;
          775  +    }
          776  +    sqlite3_free(zAppend);
          777  +    sqlite3_free(zIn);
          778  +  }
          779  +  va_end(ap);
          780  +  return zRet;
          781  +}
          782  +
          783  +/*
          784  +** Return true if zId must be quoted in order to use it as an SQL
          785  +** identifier, or false otherwise.
          786  +*/
          787  +static int idxIdentifierRequiresQuotes(const char *zId){
          788  +  int i;
          789  +  for(i=0; zId[i]; i++){
          790  +    if( !(zId[i]=='_')
          791  +     && !(zId[i]>='0' && zId[i]<='9')
          792  +     && !(zId[i]>='a' && zId[i]<='z')
          793  +     && !(zId[i]>='A' && zId[i]<='Z')
          794  +    ){
          795  +      return 1;
          796  +    }
          797  +  }
          798  +  return 0;
          799  +}
          800  +
          801  +/*
          802  +** This function appends an index column definition suitable for constraint
          803  +** pCons to the string passed as zIn and returns the result.
          804  +*/
          805  +static char *idxAppendColDefn(
          806  +  int *pRc,                       /* IN/OUT: Error code */
          807  +  char *zIn,                      /* Column defn accumulated so far */
          808  +  IdxTable *pTab,                 /* Table index will be created on */
          809  +  IdxConstraint *pCons
          810  +){
          811  +  char *zRet = zIn;
          812  +  IdxColumn *p = &pTab->aCol[pCons->iCol];
          813  +  if( zRet ) zRet = idxAppendText(pRc, zRet, ", ");
          814  +
          815  +  if( idxIdentifierRequiresQuotes(p->zName) ){
          816  +    zRet = idxAppendText(pRc, zRet, "%Q", p->zName);
          817  +  }else{
          818  +    zRet = idxAppendText(pRc, zRet, "%s", p->zName);
          819  +  }
          820  +
          821  +  if( sqlite3_stricmp(p->zColl, pCons->zColl) ){
          822  +    if( idxIdentifierRequiresQuotes(pCons->zColl) ){
          823  +      zRet = idxAppendText(pRc, zRet, " COLLATE %Q", pCons->zColl);
          824  +    }else{
          825  +      zRet = idxAppendText(pRc, zRet, " COLLATE %s", pCons->zColl);
          826  +    }
          827  +  }
          828  +
          829  +  if( pCons->bDesc ){
          830  +    zRet = idxAppendText(pRc, zRet, " DESC");
          831  +  }
          832  +  return zRet;
          833  +}
          834  +
          835  +/*
          836  +** Search database dbm for an index compatible with the one idxCreateFromCons()
          837  +** would create from arguments pScan, pEq and pTail. If no error occurs and 
          838  +** such an index is found, return non-zero. Or, if no such index is found,
          839  +** return zero.
          840  +**
          841  +** If an error occurs, set *pRc to an SQLite error code and return zero.
          842  +*/
          843  +static int idxFindCompatible(
          844  +  int *pRc,                       /* OUT: Error code */
          845  +  sqlite3* dbm,                   /* Database to search */
          846  +  IdxScan *pScan,                 /* Scan for table to search for index on */
          847  +  IdxConstraint *pEq,             /* List of == constraints */
          848  +  IdxConstraint *pTail            /* List of range constraints */
          849  +){
          850  +  const char *zTbl = pScan->pTab->zName;
          851  +  sqlite3_stmt *pIdxList = 0;
          852  +  IdxConstraint *pIter;
          853  +  int nEq = 0;                    /* Number of elements in pEq */
          854  +  int rc;
          855  +
          856  +  /* Count the elements in list pEq */
          857  +  for(pIter=pEq; pIter; pIter=pIter->pLink) nEq++;
          858  +
          859  +  rc = idxPrintfPrepareStmt(dbm, &pIdxList, 0, "PRAGMA index_list=%Q", zTbl);
          860  +  while( rc==SQLITE_OK && sqlite3_step(pIdxList)==SQLITE_ROW ){
          861  +    int bMatch = 1;
          862  +    IdxConstraint *pT = pTail;
          863  +    sqlite3_stmt *pInfo = 0;
          864  +    const char *zIdx = (const char*)sqlite3_column_text(pIdxList, 1);
          865  +
          866  +    /* Zero the IdxConstraint.bFlag values in the pEq list */
          867  +    for(pIter=pEq; pIter; pIter=pIter->pLink) pIter->bFlag = 0;
          868  +
          869  +    rc = idxPrintfPrepareStmt(dbm, &pInfo, 0, "PRAGMA index_xInfo=%Q", zIdx);
          870  +    while( rc==SQLITE_OK && sqlite3_step(pInfo)==SQLITE_ROW ){
          871  +      int iIdx = sqlite3_column_int(pInfo, 0);
          872  +      int iCol = sqlite3_column_int(pInfo, 1);
          873  +      const char *zColl = (const char*)sqlite3_column_text(pInfo, 4);
          874  +
          875  +      if( iIdx<nEq ){
          876  +        for(pIter=pEq; pIter; pIter=pIter->pLink){
          877  +          if( pIter->bFlag ) continue;
          878  +          if( pIter->iCol!=iCol ) continue;
          879  +          if( sqlite3_stricmp(pIter->zColl, zColl) ) continue;
          880  +          pIter->bFlag = 1;
          881  +          break;
          882  +        }
          883  +        if( pIter==0 ){
          884  +          bMatch = 0;
          885  +          break;
          886  +        }
          887  +      }else{
          888  +        if( pT ){
          889  +          if( pT->iCol!=iCol || sqlite3_stricmp(pT->zColl, zColl) ){
          890  +            bMatch = 0;
          891  +            break;
          892  +          }
          893  +          pT = pT->pLink;
          894  +        }
          895  +      }
          896  +    }
          897  +    idxFinalize(&rc, pInfo);
          898  +
          899  +    if( rc==SQLITE_OK && bMatch ){
          900  +      sqlite3_finalize(pIdxList);
          901  +      return 1;
          902  +    }
          903  +  }
          904  +  idxFinalize(&rc, pIdxList);
          905  +
          906  +  *pRc = rc;
          907  +  return 0;
          908  +}
          909  +
          910  +static int idxCreateFromCons(
          911  +  sqlite3expert *p,
          912  +  IdxScan *pScan,
          913  +  IdxConstraint *pEq, 
          914  +  IdxConstraint *pTail
          915  +){
          916  +  sqlite3 *dbm = p->dbm;
          917  +  int rc = SQLITE_OK;
          918  +  if( (pEq || pTail) && 0==idxFindCompatible(&rc, dbm, pScan, pEq, pTail) ){
          919  +    IdxTable *pTab = pScan->pTab;
          920  +    char *zCols = 0;
          921  +    char *zIdx = 0;
          922  +    IdxConstraint *pCons;
          923  +    unsigned int h = 0;
          924  +    const char *zFmt;
          925  +
          926  +    for(pCons=pEq; pCons; pCons=pCons->pLink){
          927  +      zCols = idxAppendColDefn(&rc, zCols, pTab, pCons);
          928  +    }
          929  +    for(pCons=pTail; pCons; pCons=pCons->pLink){
          930  +      zCols = idxAppendColDefn(&rc, zCols, pTab, pCons);
          931  +    }
          932  +
          933  +    if( rc==SQLITE_OK ){
          934  +      /* Hash the list of columns to come up with a name for the index */
          935  +      const char *zTable = pScan->pTab->zName;
          936  +      char *zName;                /* Index name */
          937  +      int i;
          938  +      for(i=0; zCols[i]; i++){
          939  +        h += ((h<<3) + zCols[i]);
          940  +      }
          941  +      zName = sqlite3_mprintf("%s_idx_%08x", zTable, h);
          942  +      if( zName==0 ){ 
          943  +        rc = SQLITE_NOMEM;
          944  +      }else{
          945  +        if( idxIdentifierRequiresQuotes(zTable) ){
          946  +          zFmt = "CREATE INDEX '%q' ON %Q(%s)";
          947  +        }else{
          948  +          zFmt = "CREATE INDEX %s ON %s(%s)";
          949  +        }
          950  +        zIdx = sqlite3_mprintf(zFmt, zName, zTable, zCols);
          951  +        if( !zIdx ){
          952  +          rc = SQLITE_NOMEM;
          953  +        }else{
          954  +          rc = sqlite3_exec(dbm, zIdx, 0, 0, p->pzErrmsg);
          955  +          idxHashAdd(&rc, &p->hIdx, zName, zIdx);
          956  +        }
          957  +        sqlite3_free(zName);
          958  +        sqlite3_free(zIdx);
          959  +      }
          960  +    }
          961  +
          962  +    sqlite3_free(zCols);
          963  +  }
          964  +  return rc;
          965  +}
          966  +
          967  +/*
          968  +** Return true if list pList (linked by IdxConstraint.pLink) contains
          969  +** a constraint compatible with *p. Otherwise return false.
          970  +*/
          971  +static int idxFindConstraint(IdxConstraint *pList, IdxConstraint *p){
          972  +  IdxConstraint *pCmp;
          973  +  for(pCmp=pList; pCmp; pCmp=pCmp->pLink){
          974  +    if( p->iCol==pCmp->iCol ) return 1;
          975  +  }
          976  +  return 0;
          977  +}
          978  +
          979  +static int idxCreateFromWhere(
          980  +  sqlite3expert *p, 
          981  +  IdxScan *pScan,                 /* Create indexes for this scan */
          982  +  IdxConstraint *pTail            /* range/ORDER BY constraints for inclusion */
          983  +){
          984  +  IdxConstraint *p1 = 0;
          985  +  IdxConstraint *pCon;
          986  +  int rc;
          987  +
          988  +  /* Gather up all the == constraints. */
          989  +  for(pCon=pScan->pEq; pCon; pCon=pCon->pNext){
          990  +    if( !idxFindConstraint(p1, pCon) && !idxFindConstraint(pTail, pCon) ){
          991  +      pCon->pLink = p1;
          992  +      p1 = pCon;
          993  +    }
          994  +  }
          995  +
          996  +  /* Create an index using the == constraints collected above. And the
          997  +  ** range constraint/ORDER BY terms passed in by the caller, if any. */
          998  +  rc = idxCreateFromCons(p, pScan, p1, pTail);
          999  +
         1000  +  /* If no range/ORDER BY passed by the caller, create a version of the
         1001  +  ** index for each range constraint.  */
         1002  +  if( pTail==0 ){
         1003  +    for(pCon=pScan->pRange; rc==SQLITE_OK && pCon; pCon=pCon->pNext){
         1004  +      assert( pCon->pLink==0 );
         1005  +      if( !idxFindConstraint(p1, pCon) && !idxFindConstraint(pTail, pCon) ){
         1006  +        rc = idxCreateFromCons(p, pScan, p1, pCon);
         1007  +      }
         1008  +    }
         1009  +  }
         1010  +
         1011  +  return rc;
         1012  +}
         1013  +
         1014  +/*
         1015  +** Create candidate indexes in database [dbm] based on the data in 
         1016  +** linked-list pScan.
         1017  +*/
         1018  +static int idxCreateCandidates(sqlite3expert *p){
         1019  +  int rc = SQLITE_OK;
         1020  +  IdxScan *pIter;
         1021  +
         1022  +  for(pIter=p->pScan; pIter && rc==SQLITE_OK; pIter=pIter->pNextScan){
         1023  +    rc = idxCreateFromWhere(p, pIter, 0);
         1024  +    if( rc==SQLITE_OK && pIter->pOrder ){
         1025  +      rc = idxCreateFromWhere(p, pIter, pIter->pOrder);
         1026  +    }
         1027  +  }
         1028  +
         1029  +  return rc;
         1030  +}
         1031  +
         1032  +/*
         1033  +** Free all elements of the linked list starting at pConstraint.
         1034  +*/
         1035  +static void idxConstraintFree(IdxConstraint *pConstraint){
         1036  +  IdxConstraint *pNext;
         1037  +  IdxConstraint *p;
         1038  +
         1039  +  for(p=pConstraint; p; p=pNext){
         1040  +    pNext = p->pNext;
         1041  +    sqlite3_free(p);
         1042  +  }
         1043  +}
         1044  +
         1045  +/*
         1046  +** Free all elements of the linked list starting from pScan up until pLast
         1047  +** (pLast is not freed).
         1048  +*/
         1049  +static void idxScanFree(IdxScan *pScan, IdxScan *pLast){
         1050  +  IdxScan *p;
         1051  +  IdxScan *pNext;
         1052  +  for(p=pScan; p!=pLast; p=pNext){
         1053  +    pNext = p->pNextScan;
         1054  +    idxConstraintFree(p->pOrder);
         1055  +    idxConstraintFree(p->pEq);
         1056  +    idxConstraintFree(p->pRange);
         1057  +    sqlite3_free(p);
         1058  +  }
         1059  +}
         1060  +
         1061  +/*
         1062  +** Free all elements of the linked list starting from pStatement up 
         1063  +** until pLast (pLast is not freed).
         1064  +*/
         1065  +static void idxStatementFree(IdxStatement *pStatement, IdxStatement *pLast){
         1066  +  IdxStatement *p;
         1067  +  IdxStatement *pNext;
         1068  +  for(p=pStatement; p!=pLast; p=pNext){
         1069  +    pNext = p->pNext;
         1070  +    sqlite3_free(p->zEQP);
         1071  +    sqlite3_free(p->zIdx);
         1072  +    sqlite3_free(p);
         1073  +  }
         1074  +}
         1075  +
         1076  +/*
         1077  +** Free the linked list of IdxTable objects starting at pTab.
         1078  +*/
         1079  +static void idxTableFree(IdxTable *pTab){
         1080  +  IdxTable *pIter;
         1081  +  IdxTable *pNext;
         1082  +  for(pIter=pTab; pIter; pIter=pNext){
         1083  +    pNext = pIter->pNext;
         1084  +    sqlite3_free(pIter);
         1085  +  }
         1086  +}
         1087  +
         1088  +/*
         1089  +** Free the linked list of IdxWrite objects starting at pTab.
         1090  +*/
         1091  +static void idxWriteFree(IdxWrite *pTab){
         1092  +  IdxWrite *pIter;
         1093  +  IdxWrite *pNext;
         1094  +  for(pIter=pTab; pIter; pIter=pNext){
         1095  +    pNext = pIter->pNext;
         1096  +    sqlite3_free(pIter);
         1097  +  }
         1098  +}
         1099  +
         1100  +
         1101  +
         1102  +/*
         1103  +** This function is called after candidate indexes have been created. It
         1104  +** runs all the queries to see which indexes they prefer, and populates
         1105  +** IdxStatement.zIdx and IdxStatement.zEQP with the results.
         1106  +*/
         1107  +int idxFindIndexes(
         1108  +  sqlite3expert *p,
         1109  +  char **pzErr                         /* OUT: Error message (sqlite3_malloc) */
         1110  +){
         1111  +  IdxStatement *pStmt;
         1112  +  sqlite3 *dbm = p->dbm;
         1113  +  int rc = SQLITE_OK;
         1114  +
         1115  +  IdxHash hIdx;
         1116  +  idxHashInit(&hIdx);
         1117  +
         1118  +  for(pStmt=p->pStatement; rc==SQLITE_OK && pStmt; pStmt=pStmt->pNext){
         1119  +    IdxHashEntry *pEntry;
         1120  +    sqlite3_stmt *pExplain = 0;
         1121  +    idxHashClear(&hIdx);
         1122  +    rc = idxPrintfPrepareStmt(dbm, &pExplain, pzErr,
         1123  +        "EXPLAIN QUERY PLAN %s", pStmt->zSql
         1124  +    );
         1125  +    while( rc==SQLITE_OK && sqlite3_step(pExplain)==SQLITE_ROW ){
         1126  +      /* int iId = sqlite3_column_int(pExplain, 0); */
         1127  +      /* int iParent = sqlite3_column_int(pExplain, 1); */
         1128  +      /* int iNotUsed = sqlite3_column_int(pExplain, 2); */
         1129  +      const char *zDetail = (const char*)sqlite3_column_text(pExplain, 3);
         1130  +      int nDetail = STRLEN(zDetail);
         1131  +      int i;
         1132  +
         1133  +      for(i=0; i<nDetail; i++){
         1134  +        const char *zIdx = 0;
         1135  +        if( memcmp(&zDetail[i], " USING INDEX ", 13)==0 ){
         1136  +          zIdx = &zDetail[i+13];
         1137  +        }else if( memcmp(&zDetail[i], " USING COVERING INDEX ", 22)==0 ){
         1138  +          zIdx = &zDetail[i+22];
         1139  +        }
         1140  +        if( zIdx ){
         1141  +          const char *zSql;
         1142  +          int nIdx = 0;
         1143  +          while( zIdx[nIdx]!='\0' && (zIdx[nIdx]!=' ' || zIdx[nIdx+1]!='(') ){
         1144  +            nIdx++;
         1145  +          }
         1146  +          zSql = idxHashSearch(&p->hIdx, zIdx, nIdx);
         1147  +          if( zSql ){
         1148  +            idxHashAdd(&rc, &hIdx, zSql, 0);
         1149  +            if( rc ) goto find_indexes_out;
         1150  +          }
         1151  +          break;
         1152  +        }
         1153  +      }
         1154  +
         1155  +      if( zDetail[0]!='-' ){
         1156  +        pStmt->zEQP = idxAppendText(&rc, pStmt->zEQP, "%s\n", zDetail);
         1157  +      }
         1158  +    }
         1159  +
         1160  +    for(pEntry=hIdx.pFirst; pEntry; pEntry=pEntry->pNext){
         1161  +      pStmt->zIdx = idxAppendText(&rc, pStmt->zIdx, "%s;\n", pEntry->zKey);
         1162  +    }
         1163  +
         1164  +    idxFinalize(&rc, pExplain);
         1165  +  }
         1166  +
         1167  + find_indexes_out:
         1168  +  idxHashClear(&hIdx);
         1169  +  return rc;
         1170  +}
         1171  +
         1172  +static int idxAuthCallback(
         1173  +  void *pCtx,
         1174  +  int eOp,
         1175  +  const char *z3,
         1176  +  const char *z4,
         1177  +  const char *zDb,
         1178  +  const char *zTrigger
         1179  +){
         1180  +  int rc = SQLITE_OK;
         1181  +  (void)z4;
         1182  +  (void)zTrigger;
         1183  +  if( eOp==SQLITE_INSERT || eOp==SQLITE_UPDATE || eOp==SQLITE_DELETE ){
         1184  +    if( sqlite3_stricmp(zDb, "main")==0 ){
         1185  +      sqlite3expert *p = (sqlite3expert*)pCtx;
         1186  +      IdxTable *pTab;
         1187  +      for(pTab=p->pTable; pTab; pTab=pTab->pNext){
         1188  +        if( 0==sqlite3_stricmp(z3, pTab->zName) ) break;
         1189  +      }
         1190  +      if( pTab ){
         1191  +        IdxWrite *pWrite;
         1192  +        for(pWrite=p->pWrite; pWrite; pWrite=pWrite->pNext){
         1193  +          if( pWrite->pTab==pTab && pWrite->eOp==eOp ) break;
         1194  +        }
         1195  +        if( pWrite==0 ){
         1196  +          pWrite = idxMalloc(&rc, sizeof(IdxWrite));
         1197  +          if( rc==SQLITE_OK ){
         1198  +            pWrite->pTab = pTab;
         1199  +            pWrite->eOp = eOp;
         1200  +            pWrite->pNext = p->pWrite;
         1201  +            p->pWrite = pWrite;
         1202  +          }
         1203  +        }
         1204  +      }
         1205  +    }
         1206  +  }
         1207  +  return rc;
         1208  +}
         1209  +
         1210  +static int idxProcessOneTrigger(
         1211  +  sqlite3expert *p, 
         1212  +  IdxWrite *pWrite, 
         1213  +  char **pzErr
         1214  +){
         1215  +  static const char *zInt = UNIQUE_TABLE_NAME;
         1216  +  static const char *zDrop = "DROP TABLE " UNIQUE_TABLE_NAME;
         1217  +  IdxTable *pTab = pWrite->pTab;
         1218  +  const char *zTab = pTab->zName;
         1219  +  const char *zSql = 
         1220  +    "SELECT 'CREATE TEMP' || substr(sql, 7) FROM sqlite_master "
         1221  +    "WHERE tbl_name = %Q AND type IN ('table', 'trigger') "
         1222  +    "ORDER BY type;";
         1223  +  sqlite3_stmt *pSelect = 0;
         1224  +  int rc = SQLITE_OK;
         1225  +  char *zWrite = 0;
         1226  +
         1227  +  /* Create the table and its triggers in the temp schema */
         1228  +  rc = idxPrintfPrepareStmt(p->db, &pSelect, pzErr, zSql, zTab, zTab);
         1229  +  while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSelect) ){
         1230  +    const char *zCreate = (const char*)sqlite3_column_text(pSelect, 0);
         1231  +    rc = sqlite3_exec(p->dbv, zCreate, 0, 0, pzErr);
         1232  +  }
         1233  +  idxFinalize(&rc, pSelect);
         1234  +
         1235  +  /* Rename the table in the temp schema to zInt */
         1236  +  if( rc==SQLITE_OK ){
         1237  +    char *z = sqlite3_mprintf("ALTER TABLE temp.%Q RENAME TO %Q", zTab, zInt);
         1238  +    if( z==0 ){
         1239  +      rc = SQLITE_NOMEM;
         1240  +    }else{
         1241  +      rc = sqlite3_exec(p->dbv, z, 0, 0, pzErr);
         1242  +      sqlite3_free(z);
         1243  +    }
         1244  +  }
         1245  +
         1246  +  switch( pWrite->eOp ){
         1247  +    case SQLITE_INSERT: {
         1248  +      int i;
         1249  +      zWrite = idxAppendText(&rc, zWrite, "INSERT INTO %Q VALUES(", zInt);
         1250  +      for(i=0; i<pTab->nCol; i++){
         1251  +        zWrite = idxAppendText(&rc, zWrite, "%s?", i==0 ? "" : ", ");
         1252  +      }
         1253  +      zWrite = idxAppendText(&rc, zWrite, ")");
         1254  +      break;
         1255  +    }
         1256  +    case SQLITE_UPDATE: {
         1257  +      int i;
         1258  +      zWrite = idxAppendText(&rc, zWrite, "UPDATE %Q SET ", zInt);
         1259  +      for(i=0; i<pTab->nCol; i++){
         1260  +        zWrite = idxAppendText(&rc, zWrite, "%s%Q=?", i==0 ? "" : ", ", 
         1261  +            pTab->aCol[i].zName
         1262  +        );
         1263  +      }
         1264  +      break;
         1265  +    }
         1266  +    default: {
         1267  +      assert( pWrite->eOp==SQLITE_DELETE );
         1268  +      if( rc==SQLITE_OK ){
         1269  +        zWrite = sqlite3_mprintf("DELETE FROM %Q", zInt);
         1270  +        if( zWrite==0 ) rc = SQLITE_NOMEM;
         1271  +      }
         1272  +    }
         1273  +  }
         1274  +
         1275  +  if( rc==SQLITE_OK ){
         1276  +    sqlite3_stmt *pX = 0;
         1277  +    rc = sqlite3_prepare_v2(p->dbv, zWrite, -1, &pX, 0);
         1278  +    idxFinalize(&rc, pX);
         1279  +    if( rc!=SQLITE_OK ){
         1280  +      idxDatabaseError(p->dbv, pzErr);
         1281  +    }
         1282  +  }
         1283  +  sqlite3_free(zWrite);
         1284  +
         1285  +  if( rc==SQLITE_OK ){
         1286  +    rc = sqlite3_exec(p->dbv, zDrop, 0, 0, pzErr);
         1287  +  }
         1288  +
         1289  +  return rc;
         1290  +}
         1291  +
         1292  +static int idxProcessTriggers(sqlite3expert *p, char **pzErr){
         1293  +  int rc = SQLITE_OK;
         1294  +  IdxWrite *pEnd = 0;
         1295  +  IdxWrite *pFirst = p->pWrite;
         1296  +
         1297  +  while( rc==SQLITE_OK && pFirst!=pEnd ){
         1298  +    IdxWrite *pIter;
         1299  +    for(pIter=pFirst; rc==SQLITE_OK && pIter!=pEnd; pIter=pIter->pNext){
         1300  +      rc = idxProcessOneTrigger(p, pIter, pzErr);
         1301  +    }
         1302  +    pEnd = pFirst;
         1303  +    pFirst = p->pWrite;
         1304  +  }
         1305  +
         1306  +  return rc;
         1307  +}
         1308  +
         1309  +
         1310  +static int idxCreateVtabSchema(sqlite3expert *p, char **pzErrmsg){
         1311  +  int rc = idxRegisterVtab(p);
         1312  +  sqlite3_stmt *pSchema = 0;
         1313  +
         1314  +  /* For each table in the main db schema:
         1315  +  **
         1316  +  **   1) Add an entry to the p->pTable list, and
         1317  +  **   2) Create the equivalent virtual table in dbv.
         1318  +  */
         1319  +  rc = idxPrepareStmt(p->db, &pSchema, pzErrmsg,
         1320  +      "SELECT type, name, sql, 1 FROM sqlite_master "
         1321  +      "WHERE type IN ('table','view') AND name NOT LIKE 'sqlite_%%' "
         1322  +      " UNION ALL "
         1323  +      "SELECT type, name, sql, 2 FROM sqlite_master "
         1324  +      "WHERE type = 'trigger'"
         1325  +      "  AND tbl_name IN(SELECT name FROM sqlite_master WHERE type = 'view') "
         1326  +      "ORDER BY 4, 1"
         1327  +  );
         1328  +  while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSchema) ){
         1329  +    const char *zType = (const char*)sqlite3_column_text(pSchema, 0);
         1330  +    const char *zName = (const char*)sqlite3_column_text(pSchema, 1);
         1331  +    const char *zSql = (const char*)sqlite3_column_text(pSchema, 2);
         1332  +
         1333  +    if( zType[0]=='v' || zType[1]=='r' ){
         1334  +      rc = sqlite3_exec(p->dbv, zSql, 0, 0, pzErrmsg);
         1335  +    }else{
         1336  +      IdxTable *pTab;
         1337  +      rc = idxGetTableInfo(p->db, zName, &pTab, pzErrmsg);
         1338  +      if( rc==SQLITE_OK ){
         1339  +        int i;
         1340  +        char *zInner = 0;
         1341  +        char *zOuter = 0;
         1342  +        pTab->pNext = p->pTable;
         1343  +        p->pTable = pTab;
         1344  +
         1345  +        /* The statement the vtab will pass to sqlite3_declare_vtab() */
         1346  +        zInner = idxAppendText(&rc, 0, "CREATE TABLE x(");
         1347  +        for(i=0; i<pTab->nCol; i++){
         1348  +          zInner = idxAppendText(&rc, zInner, "%s%Q COLLATE %s", 
         1349  +              (i==0 ? "" : ", "), pTab->aCol[i].zName, pTab->aCol[i].zColl
         1350  +          );
         1351  +        }
         1352  +        zInner = idxAppendText(&rc, zInner, ")");
         1353  +
         1354  +        /* The CVT statement to create the vtab */
         1355  +        zOuter = idxAppendText(&rc, 0, 
         1356  +            "CREATE VIRTUAL TABLE %Q USING expert(%Q)", zName, zInner
         1357  +        );
         1358  +        if( rc==SQLITE_OK ){
         1359  +          rc = sqlite3_exec(p->dbv, zOuter, 0, 0, pzErrmsg);
         1360  +        }
         1361  +        sqlite3_free(zInner);
         1362  +        sqlite3_free(zOuter);
         1363  +      }
         1364  +    }
         1365  +  }
         1366  +  idxFinalize(&rc, pSchema);
         1367  +  return rc;
         1368  +}
         1369  +
         1370  +struct IdxSampleCtx {
         1371  +  int iTarget;
         1372  +  double target;                  /* Target nRet/nRow value */
         1373  +  double nRow;                    /* Number of rows seen */
         1374  +  double nRet;                    /* Number of rows returned */
         1375  +};
         1376  +
         1377  +static void idxSampleFunc(
         1378  +  sqlite3_context *pCtx,
         1379  +  int argc,
         1380  +  sqlite3_value **argv
         1381  +){
         1382  +  struct IdxSampleCtx *p = (struct IdxSampleCtx*)sqlite3_user_data(pCtx);
         1383  +  int bRet;
         1384  +
         1385  +  (void)argv;
         1386  +  assert( argc==0 );
         1387  +  if( p->nRow==0.0 ){
         1388  +    bRet = 1;
         1389  +  }else{
         1390  +    bRet = (p->nRet / p->nRow) <= p->target;
         1391  +    if( bRet==0 ){
         1392  +      unsigned short rnd;
         1393  +      sqlite3_randomness(2, (void*)&rnd);
         1394  +      bRet = ((int)rnd % 100) <= p->iTarget;
         1395  +    }
         1396  +  }
         1397  +
         1398  +  sqlite3_result_int(pCtx, bRet);
         1399  +  p->nRow += 1.0;
         1400  +  p->nRet += (double)bRet;
         1401  +}
         1402  +
         1403  +struct IdxRemCtx {
         1404  +  int nSlot;
         1405  +  struct IdxRemSlot {
         1406  +    int eType;                    /* SQLITE_NULL, INTEGER, REAL, TEXT, BLOB */
         1407  +    i64 iVal;                     /* SQLITE_INTEGER value */
         1408  +    double rVal;                  /* SQLITE_FLOAT value */
         1409  +    int nByte;                    /* Bytes of space allocated at z */
         1410  +    int n;                        /* Size of buffer z */
         1411  +    char *z;                      /* SQLITE_TEXT/BLOB value */
         1412  +  } aSlot[1];
         1413  +};
         1414  +
         1415  +/*
         1416  +** Implementation of scalar function rem().
         1417  +*/
         1418  +static void idxRemFunc(
         1419  +  sqlite3_context *pCtx,
         1420  +  int argc,
         1421  +  sqlite3_value **argv
         1422  +){
         1423  +  struct IdxRemCtx *p = (struct IdxRemCtx*)sqlite3_user_data(pCtx);
         1424  +  struct IdxRemSlot *pSlot;
         1425  +  int iSlot;
         1426  +  assert( argc==2 );
         1427  +
         1428  +  iSlot = sqlite3_value_int(argv[0]);
         1429  +  assert( iSlot<=p->nSlot );
         1430  +  pSlot = &p->aSlot[iSlot];
         1431  +
         1432  +  switch( pSlot->eType ){
         1433  +    case SQLITE_NULL:
         1434  +      /* no-op */
         1435  +      break;
         1436  +
         1437  +    case SQLITE_INTEGER:
         1438  +      sqlite3_result_int64(pCtx, pSlot->iVal);
         1439  +      break;
         1440  +
         1441  +    case SQLITE_FLOAT:
         1442  +      sqlite3_result_double(pCtx, pSlot->rVal);
         1443  +      break;
         1444  +
         1445  +    case SQLITE_BLOB:
         1446  +      sqlite3_result_blob(pCtx, pSlot->z, pSlot->n, SQLITE_TRANSIENT);
         1447  +      break;
         1448  +
         1449  +    case SQLITE_TEXT:
         1450  +      sqlite3_result_text(pCtx, pSlot->z, pSlot->n, SQLITE_TRANSIENT);
         1451  +      break;
         1452  +  }
         1453  +
         1454  +  pSlot->eType = sqlite3_value_type(argv[1]);
         1455  +  switch( pSlot->eType ){
         1456  +    case SQLITE_NULL:
         1457  +      /* no-op */
         1458  +      break;
         1459  +
         1460  +    case SQLITE_INTEGER:
         1461  +      pSlot->iVal = sqlite3_value_int64(argv[1]);
         1462  +      break;
         1463  +
         1464  +    case SQLITE_FLOAT:
         1465  +      pSlot->rVal = sqlite3_value_double(argv[1]);
         1466  +      break;
         1467  +
         1468  +    case SQLITE_BLOB:
         1469  +    case SQLITE_TEXT: {
         1470  +      int nByte = sqlite3_value_bytes(argv[1]);
         1471  +      if( nByte>pSlot->nByte ){
         1472  +        char *zNew = (char*)sqlite3_realloc(pSlot->z, nByte*2);
         1473  +        if( zNew==0 ){
         1474  +          sqlite3_result_error_nomem(pCtx);
         1475  +          return;
         1476  +        }
         1477  +        pSlot->nByte = nByte*2;
         1478  +        pSlot->z = zNew;
         1479  +      }
         1480  +      pSlot->n = nByte;
         1481  +      if( pSlot->eType==SQLITE_BLOB ){
         1482  +        memcpy(pSlot->z, sqlite3_value_blob(argv[1]), nByte);
         1483  +      }else{
         1484  +        memcpy(pSlot->z, sqlite3_value_text(argv[1]), nByte);
         1485  +      }
         1486  +      break;
         1487  +    }
         1488  +  }
         1489  +}
         1490  +
         1491  +static int idxLargestIndex(sqlite3 *db, int *pnMax, char **pzErr){
         1492  +  int rc = SQLITE_OK;
         1493  +  const char *zMax = 
         1494  +    "SELECT max(i.seqno) FROM "
         1495  +    "  sqlite_master AS s, "
         1496  +    "  pragma_index_list(s.name) AS l, "
         1497  +    "  pragma_index_info(l.name) AS i "
         1498  +    "WHERE s.type = 'table'";
         1499  +  sqlite3_stmt *pMax = 0;
         1500  +
         1501  +  *pnMax = 0;
         1502  +  rc = idxPrepareStmt(db, &pMax, pzErr, zMax);
         1503  +  if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pMax) ){
         1504  +    *pnMax = sqlite3_column_int(pMax, 0) + 1;
         1505  +  }
         1506  +  idxFinalize(&rc, pMax);
         1507  +
         1508  +  return rc;
         1509  +}
         1510  +
         1511  +static int idxPopulateOneStat1(
         1512  +  sqlite3expert *p,
         1513  +  sqlite3_stmt *pIndexXInfo,
         1514  +  sqlite3_stmt *pWriteStat,
         1515  +  const char *zTab,
         1516  +  const char *zIdx,
         1517  +  char **pzErr
         1518  +){
         1519  +  char *zCols = 0;
         1520  +  char *zOrder = 0;
         1521  +  char *zQuery = 0;
         1522  +  int nCol = 0;
         1523  +  int i;
         1524  +  sqlite3_stmt *pQuery = 0;
         1525  +  int *aStat = 0;
         1526  +  int rc = SQLITE_OK;
         1527  +
         1528  +  assert( p->iSample>0 );
         1529  +
         1530  +  /* Formulate the query text */
         1531  +  sqlite3_bind_text(pIndexXInfo, 1, zIdx, -1, SQLITE_STATIC);
         1532  +  while( SQLITE_OK==rc && SQLITE_ROW==sqlite3_step(pIndexXInfo) ){
         1533  +    const char *zComma = zCols==0 ? "" : ", ";
         1534  +    const char *zName = (const char*)sqlite3_column_text(pIndexXInfo, 0);
         1535  +    const char *zColl = (const char*)sqlite3_column_text(pIndexXInfo, 1);
         1536  +    zCols = idxAppendText(&rc, zCols, 
         1537  +        "%sx.%Q IS rem(%d, x.%Q) COLLATE %s", zComma, zName, nCol, zName, zColl
         1538  +    );
         1539  +    zOrder = idxAppendText(&rc, zOrder, "%s%d", zComma, ++nCol);
         1540  +  }
         1541  +  sqlite3_reset(pIndexXInfo);
         1542  +  if( rc==SQLITE_OK ){
         1543  +    if( p->iSample==100 ){
         1544  +      zQuery = sqlite3_mprintf(
         1545  +          "SELECT %s FROM %Q x ORDER BY %s", zCols, zTab, zOrder
         1546  +      );
         1547  +    }else{
         1548  +      zQuery = sqlite3_mprintf(
         1549  +          "SELECT %s FROM temp."UNIQUE_TABLE_NAME" x ORDER BY %s", zCols, zOrder
         1550  +      );
         1551  +    }
         1552  +  }
         1553  +  sqlite3_free(zCols);
         1554  +  sqlite3_free(zOrder);
         1555  +
         1556  +  /* Formulate the query text */
         1557  +  if( rc==SQLITE_OK ){
         1558  +    sqlite3 *dbrem = (p->iSample==100 ? p->db : p->dbv);
         1559  +    rc = idxPrepareStmt(dbrem, &pQuery, pzErr, zQuery);
         1560  +  }
         1561  +  sqlite3_free(zQuery);
         1562  +
         1563  +  if( rc==SQLITE_OK ){
         1564  +    aStat = (int*)idxMalloc(&rc, sizeof(int)*(nCol+1));
         1565  +  }
         1566  +  if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pQuery) ){
         1567  +    IdxHashEntry *pEntry;
         1568  +    char *zStat = 0;
         1569  +    for(i=0; i<=nCol; i++) aStat[i] = 1;
         1570  +    while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pQuery) ){
         1571  +      aStat[0]++;
         1572  +      for(i=0; i<nCol; i++){
         1573  +        if( sqlite3_column_int(pQuery, i)==0 ) break;
         1574  +      }
         1575  +      for(/*no-op*/; i<nCol; i++){
         1576  +        aStat[i+1]++;
         1577  +      }
         1578  +    }
         1579  +
         1580  +    if( rc==SQLITE_OK ){
         1581  +      int s0 = aStat[0];
         1582  +      zStat = sqlite3_mprintf("%d", s0);
         1583  +      if( zStat==0 ) rc = SQLITE_NOMEM;
         1584  +      for(i=1; rc==SQLITE_OK && i<=nCol; i++){
         1585  +        zStat = idxAppendText(&rc, zStat, " %d", (s0+aStat[i]/2) / aStat[i]);
         1586  +      }
         1587  +    }
         1588  +
         1589  +    if( rc==SQLITE_OK ){
         1590  +      sqlite3_bind_text(pWriteStat, 1, zTab, -1, SQLITE_STATIC);
         1591  +      sqlite3_bind_text(pWriteStat, 2, zIdx, -1, SQLITE_STATIC);
         1592  +      sqlite3_bind_text(pWriteStat, 3, zStat, -1, SQLITE_STATIC);
         1593  +      sqlite3_step(pWriteStat);
         1594  +      rc = sqlite3_reset(pWriteStat);
         1595  +    }
         1596  +
         1597  +    pEntry = idxHashFind(&p->hIdx, zIdx, STRLEN(zIdx));
         1598  +    if( pEntry ){
         1599  +      assert( pEntry->zVal2==0 );
         1600  +      pEntry->zVal2 = zStat;
         1601  +    }else{
         1602  +      sqlite3_free(zStat);
         1603  +    }
         1604  +  }
         1605  +  sqlite3_free(aStat);
         1606  +  idxFinalize(&rc, pQuery);
         1607  +
         1608  +  return rc;
         1609  +}
         1610  +
         1611  +static int idxBuildSampleTable(sqlite3expert *p, const char *zTab){
         1612  +  int rc;
         1613  +  char *zSql;
         1614  +
         1615  +  rc = sqlite3_exec(p->dbv,"DROP TABLE IF EXISTS temp."UNIQUE_TABLE_NAME,0,0,0);
         1616  +  if( rc!=SQLITE_OK ) return rc;
         1617  +
         1618  +  zSql = sqlite3_mprintf(
         1619  +      "CREATE TABLE temp." UNIQUE_TABLE_NAME " AS SELECT * FROM %Q", zTab
         1620  +  );
         1621  +  if( zSql==0 ) return SQLITE_NOMEM;
         1622  +  rc = sqlite3_exec(p->dbv, zSql, 0, 0, 0);
         1623  +  sqlite3_free(zSql);
         1624  +
         1625  +  return rc;
         1626  +}
         1627  +
         1628  +/*
         1629  +** This function is called as part of sqlite3_expert_analyze(). Candidate
         1630  +** indexes have already been created in database sqlite3expert.dbm, this
         1631  +** function populates sqlite_stat1 table in the same database.
         1632  +**
         1633  +** The stat1 data is generated by querying the 
         1634  +*/
         1635  +static int idxPopulateStat1(sqlite3expert *p, char **pzErr){
         1636  +  int rc = SQLITE_OK;
         1637  +  int nMax =0;
         1638  +  struct IdxRemCtx *pCtx = 0;
         1639  +  struct IdxSampleCtx samplectx; 
         1640  +  int i;
         1641  +  i64 iPrev = -100000;
         1642  +  sqlite3_stmt *pAllIndex = 0;
         1643  +  sqlite3_stmt *pIndexXInfo = 0;
         1644  +  sqlite3_stmt *pWrite = 0;
         1645  +
         1646  +  const char *zAllIndex =
         1647  +    "SELECT s.rowid, s.name, l.name FROM "
         1648  +    "  sqlite_master AS s, "
         1649  +    "  pragma_index_list(s.name) AS l "
         1650  +    "WHERE s.type = 'table'";
         1651  +  const char *zIndexXInfo = 
         1652  +    "SELECT name, coll FROM pragma_index_xinfo(?) WHERE key";
         1653  +  const char *zWrite = "INSERT INTO sqlite_stat1 VALUES(?, ?, ?)";
         1654  +
         1655  +  /* If iSample==0, no sqlite_stat1 data is required. */
         1656  +  if( p->iSample==0 ) return SQLITE_OK;
         1657  +
         1658  +  rc = idxLargestIndex(p->dbm, &nMax, pzErr);
         1659  +  if( nMax<=0 || rc!=SQLITE_OK ) return rc;
         1660  +
         1661  +  rc = sqlite3_exec(p->dbm, "ANALYZE; PRAGMA writable_schema=1", 0, 0, 0);
         1662  +
         1663  +  if( rc==SQLITE_OK ){
         1664  +    int nByte = sizeof(struct IdxRemCtx) + (sizeof(struct IdxRemSlot) * nMax);
         1665  +    pCtx = (struct IdxRemCtx*)idxMalloc(&rc, nByte);
         1666  +  }
         1667  +
         1668  +  if( rc==SQLITE_OK ){
         1669  +    sqlite3 *dbrem = (p->iSample==100 ? p->db : p->dbv);
         1670  +    rc = sqlite3_create_function(
         1671  +        dbrem, "rem", 2, SQLITE_UTF8, (void*)pCtx, idxRemFunc, 0, 0
         1672  +    );
         1673  +  }
         1674  +  if( rc==SQLITE_OK ){
         1675  +    rc = sqlite3_create_function(
         1676  +        p->db, "sample", 0, SQLITE_UTF8, (void*)&samplectx, idxSampleFunc, 0, 0
         1677  +    );
         1678  +  }
         1679  +
         1680  +  if( rc==SQLITE_OK ){
         1681  +    pCtx->nSlot = nMax+1;
         1682  +    rc = idxPrepareStmt(p->dbm, &pAllIndex, pzErr, zAllIndex);
         1683  +  }
         1684  +  if( rc==SQLITE_OK ){
         1685  +    rc = idxPrepareStmt(p->dbm, &pIndexXInfo, pzErr, zIndexXInfo);
         1686  +  }
         1687  +  if( rc==SQLITE_OK ){
         1688  +    rc = idxPrepareStmt(p->dbm, &pWrite, pzErr, zWrite);
         1689  +  }
         1690  +
         1691  +  while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pAllIndex) ){
         1692  +    i64 iRowid = sqlite3_column_int64(pAllIndex, 0);
         1693  +    const char *zTab = (const char*)sqlite3_column_text(pAllIndex, 1);
         1694  +    const char *zIdx = (const char*)sqlite3_column_text(pAllIndex, 2);
         1695  +    if( p->iSample<100 && iPrev!=iRowid ){
         1696  +      samplectx.target = (double)p->iSample / 100.0;
         1697  +      samplectx.iTarget = p->iSample;
         1698  +      samplectx.nRow = 0.0;
         1699  +      samplectx.nRet = 0.0;
         1700  +      rc = idxBuildSampleTable(p, zTab);
         1701  +      if( rc!=SQLITE_OK ) break;
         1702  +    }
         1703  +    rc = idxPopulateOneStat1(p, pIndexXInfo, pWrite, zTab, zIdx, pzErr);
         1704  +    iPrev = iRowid;
         1705  +  }
         1706  +  if( rc==SQLITE_OK && p->iSample<100 ){
         1707  +    rc = sqlite3_exec(p->dbv, 
         1708  +        "DROP TABLE IF EXISTS temp." UNIQUE_TABLE_NAME, 0,0,0
         1709  +    );
         1710  +  }
         1711  +
         1712  +  idxFinalize(&rc, pAllIndex);
         1713  +  idxFinalize(&rc, pIndexXInfo);
         1714  +  idxFinalize(&rc, pWrite);
         1715  +
         1716  +  for(i=0; i<pCtx->nSlot; i++){
         1717  +    sqlite3_free(pCtx->aSlot[i].z);
         1718  +  }
         1719  +  sqlite3_free(pCtx);
         1720  +
         1721  +  if( rc==SQLITE_OK ){
         1722  +    rc = sqlite3_exec(p->dbm, "ANALYZE sqlite_master", 0, 0, 0);
         1723  +  }
         1724  +
         1725  +  sqlite3_exec(p->db, "DROP TABLE IF EXISTS temp."UNIQUE_TABLE_NAME,0,0,0);
         1726  +  return rc;
         1727  +}
         1728  +
         1729  +/*
         1730  +** Allocate a new sqlite3expert object.
         1731  +*/
         1732  +sqlite3expert *sqlite3_expert_new(sqlite3 *db, char **pzErrmsg){
         1733  +  int rc = SQLITE_OK;
         1734  +  sqlite3expert *pNew;
         1735  +
         1736  +  pNew = (sqlite3expert*)idxMalloc(&rc, sizeof(sqlite3expert));
         1737  +
         1738  +  /* Open two in-memory databases to work with. The "vtab database" (dbv)
         1739  +  ** will contain a virtual table corresponding to each real table in
         1740  +  ** the user database schema, and a copy of each view. It is used to
         1741  +  ** collect information regarding the WHERE, ORDER BY and other clauses
         1742  +  ** of the user's query.
         1743  +  */
         1744  +  if( rc==SQLITE_OK ){
         1745  +    pNew->db = db;
         1746  +    pNew->iSample = 100;
         1747  +    rc = sqlite3_open(":memory:", &pNew->dbv);
         1748  +  }
         1749  +  if( rc==SQLITE_OK ){
         1750  +    rc = sqlite3_open(":memory:", &pNew->dbm);
         1751  +    if( rc==SQLITE_OK ){
         1752  +      sqlite3_db_config(pNew->dbm, SQLITE_DBCONFIG_TRIGGER_EQP, 1, (int*)0);
         1753  +    }
         1754  +  }
         1755  +  
         1756  +
         1757  +  /* Copy the entire schema of database [db] into [dbm]. */
         1758  +  if( rc==SQLITE_OK ){
         1759  +    sqlite3_stmt *pSql;
         1760  +    rc = idxPrintfPrepareStmt(pNew->db, &pSql, pzErrmsg, 
         1761  +        "SELECT sql FROM sqlite_master WHERE name NOT LIKE 'sqlite_%%'"
         1762  +        " AND sql NOT LIKE 'CREATE VIRTUAL %%'"
         1763  +    );
         1764  +    while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pSql) ){
         1765  +      const char *zSql = (const char*)sqlite3_column_text(pSql, 0);
         1766  +      rc = sqlite3_exec(pNew->dbm, zSql, 0, 0, pzErrmsg);
         1767  +    }
         1768  +    idxFinalize(&rc, pSql);
         1769  +  }
         1770  +
         1771  +  /* Create the vtab schema */
         1772  +  if( rc==SQLITE_OK ){
         1773  +    rc = idxCreateVtabSchema(pNew, pzErrmsg);
         1774  +  }
         1775  +
         1776  +  /* Register the auth callback with dbv */
         1777  +  if( rc==SQLITE_OK ){
         1778  +    sqlite3_set_authorizer(pNew->dbv, idxAuthCallback, (void*)pNew);
         1779  +  }
         1780  +
         1781  +  /* If an error has occurred, free the new object and reutrn NULL. Otherwise,
         1782  +  ** return the new sqlite3expert handle.  */
         1783  +  if( rc!=SQLITE_OK ){
         1784  +    sqlite3_expert_destroy(pNew);
         1785  +    pNew = 0;
         1786  +  }
         1787  +  return pNew;
         1788  +}
         1789  +
         1790  +/*
         1791  +** Configure an sqlite3expert object.
         1792  +*/
         1793  +int sqlite3_expert_config(sqlite3expert *p, int op, ...){
         1794  +  int rc = SQLITE_OK;
         1795  +  va_list ap;
         1796  +  va_start(ap, op);
         1797  +  switch( op ){
         1798  +    case EXPERT_CONFIG_SAMPLE: {
         1799  +      int iVal = va_arg(ap, int);
         1800  +      if( iVal<0 ) iVal = 0;
         1801  +      if( iVal>100 ) iVal = 100;
         1802  +      p->iSample = iVal;
         1803  +      break;
         1804  +    }
         1805  +    default:
         1806  +      rc = SQLITE_NOTFOUND;
         1807  +      break;
         1808  +  }
         1809  +
         1810  +  va_end(ap);
         1811  +  return rc;
         1812  +}
         1813  +
         1814  +/*
         1815  +** Add an SQL statement to the analysis.
         1816  +*/
         1817  +int sqlite3_expert_sql(
         1818  +  sqlite3expert *p,               /* From sqlite3_expert_new() */
         1819  +  const char *zSql,               /* SQL statement to add */
         1820  +  char **pzErr                    /* OUT: Error message (if any) */
         1821  +){
         1822  +  IdxScan *pScanOrig = p->pScan;
         1823  +  IdxStatement *pStmtOrig = p->pStatement;
         1824  +  int rc = SQLITE_OK;
         1825  +  const char *zStmt = zSql;
         1826  +
         1827  +  if( p->bRun ) return SQLITE_MISUSE;
         1828  +
         1829  +  while( rc==SQLITE_OK && zStmt && zStmt[0] ){
         1830  +    sqlite3_stmt *pStmt = 0;
         1831  +    rc = sqlite3_prepare_v2(p->dbv, zStmt, -1, &pStmt, &zStmt);
         1832  +    if( rc==SQLITE_OK ){
         1833  +      if( pStmt ){
         1834  +        IdxStatement *pNew;
         1835  +        const char *z = sqlite3_sql(pStmt);
         1836  +        int n = STRLEN(z);
         1837  +        pNew = (IdxStatement*)idxMalloc(&rc, sizeof(IdxStatement) + n+1);
         1838  +        if( rc==SQLITE_OK ){
         1839  +          pNew->zSql = (char*)&pNew[1];
         1840  +          memcpy(pNew->zSql, z, n+1);
         1841  +          pNew->pNext = p->pStatement;
         1842  +          if( p->pStatement ) pNew->iId = p->pStatement->iId+1;
         1843  +          p->pStatement = pNew;
         1844  +        }
         1845  +        sqlite3_finalize(pStmt);
         1846  +      }
         1847  +    }else{
         1848  +      idxDatabaseError(p->dbv, pzErr);
         1849  +    }
         1850  +  }
         1851  +
         1852  +  if( rc!=SQLITE_OK ){
         1853  +    idxScanFree(p->pScan, pScanOrig);
         1854  +    idxStatementFree(p->pStatement, pStmtOrig);
         1855  +    p->pScan = pScanOrig;
         1856  +    p->pStatement = pStmtOrig;
         1857  +  }
         1858  +
         1859  +  return rc;
         1860  +}
         1861  +
         1862  +int sqlite3_expert_analyze(sqlite3expert *p, char **pzErr){
         1863  +  int rc;
         1864  +  IdxHashEntry *pEntry;
         1865  +
         1866  +  /* Do trigger processing to collect any extra IdxScan structures */
         1867  +  rc = idxProcessTriggers(p, pzErr);
         1868  +
         1869  +  /* Create candidate indexes within the in-memory database file */
         1870  +  if( rc==SQLITE_OK ){
         1871  +    rc = idxCreateCandidates(p);
         1872  +  }
         1873  +
         1874  +  /* Generate the stat1 data */
         1875  +  if( rc==SQLITE_OK ){
         1876  +    rc = idxPopulateStat1(p, pzErr);
         1877  +  }
         1878  +
         1879  +  /* Formulate the EXPERT_REPORT_CANDIDATES text */
         1880  +  for(pEntry=p->hIdx.pFirst; pEntry; pEntry=pEntry->pNext){
         1881  +    p->zCandidates = idxAppendText(&rc, p->zCandidates, 
         1882  +        "%s;%s%s\n", pEntry->zVal, 
         1883  +        pEntry->zVal2 ? " -- stat1: " : "", pEntry->zVal2
         1884  +    );
         1885  +  }
         1886  +
         1887  +  /* Figure out which of the candidate indexes are preferred by the query
         1888  +  ** planner and report the results to the user.  */
         1889  +  if( rc==SQLITE_OK ){
         1890  +    rc = idxFindIndexes(p, pzErr);
         1891  +  }
         1892  +
         1893  +  if( rc==SQLITE_OK ){
         1894  +    p->bRun = 1;
         1895  +  }
         1896  +  return rc;
         1897  +}
         1898  +
         1899  +/*
         1900  +** Return the total number of statements that have been added to this
         1901  +** sqlite3expert using sqlite3_expert_sql().
         1902  +*/
         1903  +int sqlite3_expert_count(sqlite3expert *p){
         1904  +  int nRet = 0;
         1905  +  if( p->pStatement ) nRet = p->pStatement->iId+1;
         1906  +  return nRet;
         1907  +}
         1908  +
         1909  +/*
         1910  +** Return a component of the report.
         1911  +*/
         1912  +const char *sqlite3_expert_report(sqlite3expert *p, int iStmt, int eReport){
         1913  +  const char *zRet = 0;
         1914  +  IdxStatement *pStmt;
         1915  +
         1916  +  if( p->bRun==0 ) return 0;
         1917  +  for(pStmt=p->pStatement; pStmt && pStmt->iId!=iStmt; pStmt=pStmt->pNext);
         1918  +  switch( eReport ){
         1919  +    case EXPERT_REPORT_SQL:
         1920  +      if( pStmt ) zRet = pStmt->zSql;
         1921  +      break;
         1922  +    case EXPERT_REPORT_INDEXES:
         1923  +      if( pStmt ) zRet = pStmt->zIdx;
         1924  +      break;
         1925  +    case EXPERT_REPORT_PLAN:
         1926  +      if( pStmt ) zRet = pStmt->zEQP;
         1927  +      break;
         1928  +    case EXPERT_REPORT_CANDIDATES:
         1929  +      zRet = p->zCandidates;
         1930  +      break;
         1931  +  }
         1932  +  return zRet;
         1933  +}
         1934  +
         1935  +/*
         1936  +** Free an sqlite3expert object.
         1937  +*/
         1938  +void sqlite3_expert_destroy(sqlite3expert *p){
         1939  +  if( p ){
         1940  +    sqlite3_close(p->dbm);
         1941  +    sqlite3_close(p->dbv);
         1942  +    idxScanFree(p->pScan, 0);
         1943  +    idxStatementFree(p->pStatement, 0);
         1944  +    idxTableFree(p->pTable);
         1945  +    idxWriteFree(p->pWrite);
         1946  +    idxHashClear(&p->hIdx);
         1947  +    sqlite3_free(p->zCandidates);
         1948  +    sqlite3_free(p);
         1949  +  }
         1950  +}
         1951  +
         1952  +#endif /* ifndef SQLITE_OMIT_VIRTUAL_TABLE */

Added ext/expert/sqlite3expert.h.

            1  +/*
            2  +** 2017 April 07
            3  +**
            4  +** The author disclaims copyright to this source code.  In place of
            5  +** a legal notice, here is a blessing:
            6  +**
            7  +**    May you do good and not evil.
            8  +**    May you find forgiveness for yourself and forgive others.
            9  +**    May you share freely, never taking more than you give.
           10  +**
           11  +*************************************************************************
           12  +*/
           13  +
           14  +
           15  +#include "sqlite3.h"
           16  +
           17  +typedef struct sqlite3expert sqlite3expert;
           18  +
           19  +/*
           20  +** Create a new sqlite3expert object.
           21  +**
           22  +** If successful, a pointer to the new object is returned and (*pzErr) set
           23  +** to NULL. Or, if an error occurs, NULL is returned and (*pzErr) set to
           24  +** an English-language error message. In this case it is the responsibility
           25  +** of the caller to eventually free the error message buffer using
           26  +** sqlite3_free().
           27  +*/
           28  +sqlite3expert *sqlite3_expert_new(sqlite3 *db, char **pzErr);
           29  +
           30  +/*
           31  +** Configure an sqlite3expert object.
           32  +**
           33  +** EXPERT_CONFIG_SAMPLE:
           34  +**   By default, sqlite3_expert_analyze() generates sqlite_stat1 data for
           35  +**   each candidate index. This involves scanning and sorting the entire
           36  +**   contents of each user database table once for each candidate index
           37  +**   associated with the table. For large databases, this can be 
           38  +**   prohibitively slow. This option allows the sqlite3expert object to
           39  +**   be configured so that sqlite_stat1 data is instead generated based on a
           40  +**   subset of each table, or so that no sqlite_stat1 data is used at all.
           41  +**
           42  +**   A single integer argument is passed to this option. If the value is less
           43  +**   than or equal to zero, then no sqlite_stat1 data is generated or used by
           44  +**   the analysis - indexes are recommended based on the database schema only.
           45  +**   Or, if the value is 100 or greater, complete sqlite_stat1 data is
           46  +**   generated for each candidate index (this is the default). Finally, if the
           47  +**   value falls between 0 and 100, then it represents the percentage of user
           48  +**   table rows that should be considered when generating sqlite_stat1 data.
           49  +**
           50  +**   Examples:
           51  +**
           52  +**     // Do not generate any sqlite_stat1 data
           53  +**     sqlite3_expert_config(pExpert, EXPERT_CONFIG_SAMPLE, 0);
           54  +**
           55  +**     // Generate sqlite_stat1 data based on 10% of the rows in each table.
           56  +**     sqlite3_expert_config(pExpert, EXPERT_CONFIG_SAMPLE, 10);
           57  +*/
           58  +int sqlite3_expert_config(sqlite3expert *p, int op, ...);
           59  +
           60  +#define EXPERT_CONFIG_SAMPLE 1    /* int */
           61  +
           62  +/*
           63  +** Specify zero or more SQL statements to be included in the analysis.
           64  +**
           65  +** Buffer zSql must contain zero or more complete SQL statements. This
           66  +** function parses all statements contained in the buffer and adds them
           67  +** to the internal list of statements to analyze. If successful, SQLITE_OK
           68  +** is returned and (*pzErr) set to NULL. Or, if an error occurs - for example
           69  +** due to a error in the SQL - an SQLite error code is returned and (*pzErr)
           70  +** may be set to point to an English language error message. In this case
           71  +** the caller is responsible for eventually freeing the error message buffer
           72  +** using sqlite3_free().
           73  +**
           74  +** If an error does occur while processing one of the statements in the
           75  +** buffer passed as the second argument, none of the statements in the
           76  +** buffer are added to the analysis.
           77  +**
           78  +** This function must be called before sqlite3_expert_analyze(). If a call
           79  +** to this function is made on an sqlite3expert object that has already
           80  +** been passed to sqlite3_expert_analyze() SQLITE_MISUSE is returned
           81  +** immediately and no statements are added to the analysis.
           82  +*/
           83  +int sqlite3_expert_sql(
           84  +  sqlite3expert *p,               /* From a successful sqlite3_expert_new() */
           85  +  const char *zSql,               /* SQL statement(s) to add */
           86  +  char **pzErr                    /* OUT: Error message (if any) */
           87  +);
           88  +
           89  +
           90  +/*
           91  +** This function is called after the sqlite3expert object has been configured
           92  +** with all SQL statements using sqlite3_expert_sql() to actually perform
           93  +** the analysis. Once this function has been called, it is not possible to
           94  +** add further SQL statements to the analysis.
           95  +**
           96  +** If successful, SQLITE_OK is returned and (*pzErr) is set to NULL. Or, if
           97  +** an error occurs, an SQLite error code is returned and (*pzErr) set to 
           98  +** point to a buffer containing an English language error message. In this
           99  +** case it is the responsibility of the caller to eventually free the buffer
          100  +** using sqlite3_free().
          101  +**
          102  +** If an error does occur within this function, the sqlite3expert object
          103  +** is no longer useful for any purpose. At that point it is no longer
          104  +** possible to add further SQL statements to the object or to re-attempt
          105  +** the analysis. The sqlite3expert object must still be freed using a call
          106  +** sqlite3_expert_destroy().
          107  +*/
          108  +int sqlite3_expert_analyze(sqlite3expert *p, char **pzErr);
          109  +
          110  +/*
          111  +** Return the total number of statements loaded using sqlite3_expert_sql().
          112  +** The total number of SQL statements may be different from the total number
          113  +** to calls to sqlite3_expert_sql().
          114  +*/
          115  +int sqlite3_expert_count(sqlite3expert*);
          116  +
          117  +/*
          118  +** Return a component of the report.
          119  +**
          120  +** This function is called after sqlite3_expert_analyze() to extract the
          121  +** results of the analysis. Each call to this function returns either a
          122  +** NULL pointer or a pointer to a buffer containing a nul-terminated string.
          123  +** The value passed as the third argument must be one of the EXPERT_REPORT_*
          124  +** #define constants defined below.
          125  +**
          126  +** For some EXPERT_REPORT_* parameters, the buffer returned contains 
          127  +** information relating to a specific SQL statement. In these cases that
          128  +** SQL statement is identified by the value passed as the second argument.
          129  +** SQL statements are numbered from 0 in the order in which they are parsed.
          130  +** If an out-of-range value (less than zero or equal to or greater than the
          131  +** value returned by sqlite3_expert_count()) is passed as the second argument
          132  +** along with such an EXPERT_REPORT_* parameter, NULL is always returned.
          133  +**
          134  +** EXPERT_REPORT_SQL:
          135  +**   Return the text of SQL statement iStmt.
          136  +**
          137  +** EXPERT_REPORT_INDEXES:
          138  +**   Return a buffer containing the CREATE INDEX statements for all recommended
          139  +**   indexes for statement iStmt. If there are no new recommeded indexes, NULL 
          140  +**   is returned.
          141  +**
          142  +** EXPERT_REPORT_PLAN:
          143  +**   Return a buffer containing the EXPLAIN QUERY PLAN output for SQL query
          144  +**   iStmt after the proposed indexes have been added to the database schema.
          145  +**
          146  +** EXPERT_REPORT_CANDIDATES:
          147  +**   Return a pointer to a buffer containing the CREATE INDEX statements 
          148  +**   for all indexes that were tested (for all SQL statements). The iStmt
          149  +**   parameter is ignored for EXPERT_REPORT_CANDIDATES calls.
          150  +*/
          151  +const char *sqlite3_expert_report(sqlite3expert*, int iStmt, int eReport);
          152  +
          153  +/*
          154  +** Values for the third argument passed to sqlite3_expert_report().
          155  +*/
          156  +#define EXPERT_REPORT_SQL        1
          157  +#define EXPERT_REPORT_INDEXES    2
          158  +#define EXPERT_REPORT_PLAN       3
          159  +#define EXPERT_REPORT_CANDIDATES 4
          160  +
          161  +/*
          162  +** Free an (sqlite3expert*) handle and all associated resources. There 
          163  +** should be one call to this function for each successful call to 
          164  +** sqlite3-expert_new().
          165  +*/
          166  +void sqlite3_expert_destroy(sqlite3expert*);
          167  +
          168  +

Added ext/expert/test_expert.c.

            1  +/*
            2  +** 2017 April 07
            3  +**
            4  +** The author disclaims copyright to this source code.  In place of
            5  +** a legal notice, here is a blessing:
            6  +**
            7  +**    May you do good and not evil.
            8  +**    May you find forgiveness for yourself and forgive others.
            9  +**    May you share freely, never taking more than you give.
           10  +**
           11  +*************************************************************************
           12  +*/
           13  +
           14  +#if defined(SQLITE_TEST)
           15  +
           16  +#include "sqlite3expert.h"
           17  +#include <assert.h>
           18  +#include <string.h>
           19  +
           20  +#if defined(INCLUDE_SQLITE_TCL_H)
           21  +#  include "sqlite_tcl.h"
           22  +#else
           23  +#  include "tcl.h"
           24  +#  ifndef SQLITE_TCLAPI
           25  +#    define SQLITE_TCLAPI
           26  +#  endif
           27  +#endif
           28  +
           29  +#ifndef SQLITE_OMIT_VIRTUALTABLE
           30  +
           31  +/*
           32  +** Extract an sqlite3* db handle from the object passed as the second
           33  +** argument. If successful, set *pDb to point to the db handle and return
           34  +** TCL_OK. Otherwise, return TCL_ERROR.
           35  +*/
           36  +static int dbHandleFromObj(Tcl_Interp *interp, Tcl_Obj *pObj, sqlite3 **pDb){
           37  +  Tcl_CmdInfo info;
           38  +  if( 0==Tcl_GetCommandInfo(interp, Tcl_GetString(pObj), &info) ){
           39  +    Tcl_AppendResult(interp, "no such handle: ", Tcl_GetString(pObj), 0);
           40  +    return TCL_ERROR;
           41  +  }
           42  +
           43  +  *pDb = *(sqlite3 **)info.objClientData;
           44  +  return TCL_OK;
           45  +}
           46  +
           47  +
           48  +/*
           49  +** Tclcmd:  $expert sql SQL
           50  +**          $expert analyze
           51  +**          $expert count
           52  +**          $expert report STMT EREPORT
           53  +**          $expert destroy
           54  +*/
           55  +static int SQLITE_TCLAPI testExpertCmd(
           56  +  void *clientData,
           57  +  Tcl_Interp *interp,
           58  +  int objc,
           59  +  Tcl_Obj *CONST objv[]
           60  +){
           61  +  sqlite3expert *pExpert = (sqlite3expert*)clientData;
           62  +  struct Subcmd {
           63  +    const char *zSub;
           64  +    int nArg;
           65  +    const char *zMsg;
           66  +  } aSub[] = {
           67  +    { "sql",       1, "TABLE",        }, /* 0 */
           68  +    { "analyze",   0, "",             }, /* 1 */
           69  +    { "count",     0, "",             }, /* 2 */
           70  +    { "report",    2, "STMT EREPORT", }, /* 3 */
           71  +    { "destroy",   0, "",             }, /* 4 */
           72  +    { 0 }
           73  +  };
           74  +  int iSub;
           75  +  int rc = TCL_OK;
           76  +  char *zErr = 0;
           77  +
           78  +  if( objc<2 ){
           79  +    Tcl_WrongNumArgs(interp, 1, objv, "SUBCOMMAND ...");
           80  +    return TCL_ERROR;
           81  +  }
           82  +  rc = Tcl_GetIndexFromObjStruct(interp, 
           83  +      objv[1], aSub, sizeof(aSub[0]), "sub-command", 0, &iSub
           84  +  );
           85  +  if( rc!=TCL_OK ) return rc;
           86  +  if( objc!=2+aSub[iSub].nArg ){
           87  +    Tcl_WrongNumArgs(interp, 2, objv, aSub[iSub].zMsg);
           88  +    return TCL_ERROR;
           89  +  }
           90  +
           91  +  switch( iSub ){
           92  +    case 0: {      /* sql */
           93  +      char *zArg = Tcl_GetString(objv[2]);
           94  +      rc = sqlite3_expert_sql(pExpert, zArg, &zErr);
           95  +      break;
           96  +    }
           97  +
           98  +    case 1: {      /* analyze */
           99  +      rc = sqlite3_expert_analyze(pExpert, &zErr);
          100  +      break;
          101  +    }
          102  +
          103  +    case 2: {      /* count */
          104  +      int n = sqlite3_expert_count(pExpert);
          105  +      Tcl_SetObjResult(interp, Tcl_NewIntObj(n));
          106  +      break;
          107  +    }
          108  +
          109  +    case 3: {      /* report */
          110  +      const char *aEnum[] = {
          111  +        "sql", "indexes", "plan", "candidates", 0
          112  +      };
          113  +      int iEnum;
          114  +      int iStmt;
          115  +      const char *zReport;
          116  +
          117  +      if( Tcl_GetIntFromObj(interp, objv[2], &iStmt) 
          118  +       || Tcl_GetIndexFromObj(interp, objv[3], aEnum, "report", 0, &iEnum)
          119  +      ){
          120  +        return TCL_ERROR;
          121  +      }
          122  +
          123  +      assert( EXPERT_REPORT_SQL==1 );
          124  +      assert( EXPERT_REPORT_INDEXES==2 );
          125  +      assert( EXPERT_REPORT_PLAN==3 );
          126  +      assert( EXPERT_REPORT_CANDIDATES==4 );
          127  +      zReport = sqlite3_expert_report(pExpert, iStmt, 1+iEnum);
          128  +      Tcl_SetObjResult(interp, Tcl_NewStringObj(zReport, -1));
          129  +      break;
          130  +    }
          131  +
          132  +    default:       /* destroy */
          133  +      assert( iSub==4 );     
          134  +      Tcl_DeleteCommand(interp, Tcl_GetString(objv[0]));
          135  +      break;
          136  +  }
          137  +
          138  +  if( rc!=TCL_OK ){
          139  +    if( zErr ){
          140  +      Tcl_SetObjResult(interp, Tcl_NewStringObj(zErr, -1));
          141  +    }else{
          142  +      extern const char *sqlite3ErrName(int);
          143  +      Tcl_SetObjResult(interp, Tcl_NewStringObj(sqlite3ErrName(rc), -1));
          144  +    }
          145  +  }
          146  +  sqlite3_free(zErr);
          147  +  return rc;
          148  +}
          149  +
          150  +static void SQLITE_TCLAPI testExpertDel(void *clientData){
          151  +  sqlite3expert *pExpert = (sqlite3expert*)clientData;
          152  +  sqlite3_expert_destroy(pExpert);
          153  +}
          154  +
          155  +/*
          156  +** sqlite3_expert_new DB
          157  +*/
          158  +static int SQLITE_TCLAPI test_sqlite3_expert_new(
          159  +  void * clientData,
          160  +  Tcl_Interp *interp,
          161  +  int objc,
          162  +  Tcl_Obj *CONST objv[]
          163  +){
          164  +  static int iCmd = 0;
          165  +  sqlite3 *db;
          166  +  char *zCmd = 0;
          167  +  char *zErr = 0;
          168  +  sqlite3expert *pExpert;
          169  +  int rc = TCL_OK;
          170  +
          171  +  if( objc!=2 ){
          172  +    Tcl_WrongNumArgs(interp, 1, objv, "DB");
          173  +    return TCL_ERROR;
          174  +  }
          175  +  if( dbHandleFromObj(interp, objv[1], &db) ){
          176  +    return TCL_ERROR;
          177  +  }
          178  +
          179  +  zCmd = sqlite3_mprintf("sqlite3expert%d", ++iCmd);
          180  +  if( zCmd==0 ){
          181  +    Tcl_AppendResult(interp, "out of memory", (char*)0);
          182  +    return TCL_ERROR;
          183  +  }
          184  +
          185  +  pExpert = sqlite3_expert_new(db, &zErr);
          186  +  if( pExpert==0 ){
          187  +    Tcl_AppendResult(interp, zErr, (char*)0);
          188  +    rc = TCL_ERROR;
          189  +  }else{
          190  +    void *p = (void*)pExpert;
          191  +    Tcl_CreateObjCommand(interp, zCmd, testExpertCmd, p, testExpertDel);
          192  +    Tcl_SetObjResult(interp, Tcl_NewStringObj(zCmd, -1));
          193  +  }
          194  +
          195  +  sqlite3_free(zCmd);
          196  +  sqlite3_free(zErr);
          197  +  return rc;
          198  +}
          199  +
          200  +#endif  /* ifndef SQLITE_OMIT_VIRTUALTABLE */
          201  +
          202  +int TestExpert_Init(Tcl_Interp *interp){
          203  +#ifndef SQLITE_OMIT_VIRTUALTABLE
          204  +  struct Cmd {
          205  +    const char *zCmd;
          206  +    Tcl_ObjCmdProc *xProc;
          207  +  } aCmd[] = {
          208  +    { "sqlite3_expert_new", test_sqlite3_expert_new },
          209  +  };
          210  +  int i;
          211  +
          212  +  for(i=0; i<sizeof(aCmd)/sizeof(struct Cmd); i++){
          213  +    struct Cmd *p = &aCmd[i];
          214  +    Tcl_CreateObjCommand(interp, p->zCmd, p->xProc, 0, 0);
          215  +  }
          216  +#endif
          217  +  return TCL_OK;
          218  +}
          219  +
          220  +#endif

Changes to ext/fts3/fts3.c.

  3804   3804   **
  3805   3805   ** Flush the contents of the pending-terms table to disk.
  3806   3806   */
  3807   3807   static int fts3SavepointMethod(sqlite3_vtab *pVtab, int iSavepoint){
  3808   3808     int rc = SQLITE_OK;
  3809   3809     UNUSED_PARAMETER(iSavepoint);
  3810   3810     assert( ((Fts3Table *)pVtab)->inTransaction );
  3811         -  assert( ((Fts3Table *)pVtab)->mxSavepoint < iSavepoint );
         3811  +  assert( ((Fts3Table *)pVtab)->mxSavepoint <= iSavepoint );
  3812   3812     TESTONLY( ((Fts3Table *)pVtab)->mxSavepoint = iSavepoint );
  3813   3813     if( ((Fts3Table *)pVtab)->bIgnoreSavepoint==0 ){
  3814   3814       rc = fts3SyncMethod(pVtab);
  3815   3815     }
  3816   3816     return rc;
  3817   3817   }
  3818   3818   
................................................................................
  3959   3959       ){
  3960   3960         rc = SQLITE_NOMEM;
  3961   3961       }
  3962   3962     }
  3963   3963   
  3964   3964   #ifdef SQLITE_TEST
  3965   3965     if( rc==SQLITE_OK ){
  3966         -    rc = sqlite3Fts3ExprInitTestInterface(db);
         3966  +    rc = sqlite3Fts3ExprInitTestInterface(db, pHash);
  3967   3967     }
  3968   3968   #endif
  3969   3969   
  3970   3970     /* Create the virtual table wrapper around the hash-table and overload 
  3971   3971     ** the four scalar functions. If this is successful, register the
  3972   3972     ** module with sqlite.
  3973   3973     */

Changes to ext/fts3/fts3Int.h.

   580    580   
   581    581   /* fts3_expr.c */
   582    582   int sqlite3Fts3ExprParse(sqlite3_tokenizer *, int,
   583    583     char **, int, int, int, const char *, int, Fts3Expr **, char **
   584    584   );
   585    585   void sqlite3Fts3ExprFree(Fts3Expr *);
   586    586   #ifdef SQLITE_TEST
   587         -int sqlite3Fts3ExprInitTestInterface(sqlite3 *db);
          587  +int sqlite3Fts3ExprInitTestInterface(sqlite3 *db, Fts3Hash*);
   588    588   int sqlite3Fts3InitTerm(sqlite3 *db);
   589    589   #endif
   590    590   
   591    591   int sqlite3Fts3OpenTokenizer(sqlite3_tokenizer *, int, const char *, int,
   592    592     sqlite3_tokenizer_cursor **
   593    593   );
   594    594   

Changes to ext/fts3/fts3_expr.c.

  1104   1104   ** Everything after this point is just test code.
  1105   1105   */
  1106   1106   
  1107   1107   #ifdef SQLITE_TEST
  1108   1108   
  1109   1109   #include <stdio.h>
  1110   1110   
  1111         -/*
  1112         -** Function to query the hash-table of tokenizers (see README.tokenizers).
  1113         -*/
  1114         -static int queryTestTokenizer(
  1115         -  sqlite3 *db, 
  1116         -  const char *zName,  
  1117         -  const sqlite3_tokenizer_module **pp
  1118         -){
  1119         -  int rc;
  1120         -  sqlite3_stmt *pStmt;
  1121         -  const char zSql[] = "SELECT fts3_tokenizer(?)";
  1122         -
  1123         -  *pp = 0;
  1124         -  rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
  1125         -  if( rc!=SQLITE_OK ){
  1126         -    return rc;
  1127         -  }
  1128         -
  1129         -  sqlite3_bind_text(pStmt, 1, zName, -1, SQLITE_STATIC);
  1130         -  if( SQLITE_ROW==sqlite3_step(pStmt) ){
  1131         -    if( sqlite3_column_type(pStmt, 0)==SQLITE_BLOB ){
  1132         -      memcpy((void *)pp, sqlite3_column_blob(pStmt, 0), sizeof(*pp));
  1133         -    }
  1134         -  }
  1135         -
  1136         -  return sqlite3_finalize(pStmt);
  1137         -}
  1138         -
  1139   1111   /*
  1140   1112   ** Return a pointer to a buffer containing a text representation of the
  1141   1113   ** expression passed as the first argument. The buffer is obtained from
  1142   1114   ** sqlite3_malloc(). It is the responsibility of the caller to use 
  1143   1115   ** sqlite3_free() to release the memory. If an OOM condition is encountered,
  1144   1116   ** NULL is returned.
  1145   1117   **
................................................................................
  1199   1171   ** to parse the query expression (see README.tokenizers). The second argument
  1200   1172   ** is the query expression to parse. Each subsequent argument is the name
  1201   1173   ** of a column of the fts3 table that the query expression may refer to.
  1202   1174   ** For example:
  1203   1175   **
  1204   1176   **   SELECT fts3_exprtest('simple', 'Bill col2:Bloggs', 'col1', 'col2');
  1205   1177   */
  1206         -static void fts3ExprTest(
         1178  +static void fts3ExprTestCommon(
         1179  +  int bRebalance,
  1207   1180     sqlite3_context *context,
  1208   1181     int argc,
  1209   1182     sqlite3_value **argv
  1210   1183   ){
  1211         -  sqlite3_tokenizer_module const *pModule = 0;
  1212   1184     sqlite3_tokenizer *pTokenizer = 0;
  1213   1185     int rc;
  1214   1186     char **azCol = 0;
  1215   1187     const char *zExpr;
  1216   1188     int nExpr;
  1217   1189     int nCol;
  1218   1190     int ii;
  1219   1191     Fts3Expr *pExpr;
  1220   1192     char *zBuf = 0;
  1221         -  sqlite3 *db = sqlite3_context_db_handle(context);
         1193  +  Fts3Hash *pHash = (Fts3Hash*)sqlite3_user_data(context);
         1194  +  const char *zTokenizer = 0;
         1195  +  char *zErr = 0;
  1222   1196   
  1223   1197     if( argc<3 ){
  1224   1198       sqlite3_result_error(context, 
  1225   1199           "Usage: fts3_exprtest(tokenizer, expr, col1, ...", -1
  1226   1200       );
  1227   1201       return;
  1228   1202     }
  1229   1203   
  1230         -  rc = queryTestTokenizer(db,
  1231         -                          (const char *)sqlite3_value_text(argv[0]), &pModule);
  1232         -  if( rc==SQLITE_NOMEM ){
  1233         -    sqlite3_result_error_nomem(context);
  1234         -    goto exprtest_out;
  1235         -  }else if( !pModule ){
  1236         -    sqlite3_result_error(context, "No such tokenizer module", -1);
  1237         -    goto exprtest_out;
         1204  +  zTokenizer = (const char*)sqlite3_value_text(argv[0]);
         1205  +  rc = sqlite3Fts3InitTokenizer(pHash, zTokenizer, &pTokenizer, &zErr);
         1206  +  if( rc!=SQLITE_OK ){
         1207  +    if( rc==SQLITE_NOMEM ){
         1208  +      sqlite3_result_error_nomem(context);
         1209  +    }else{
         1210  +      sqlite3_result_error(context, zErr, -1);
         1211  +    }
         1212  +    sqlite3_free(zErr);
         1213  +    return;
  1238   1214     }
  1239   1215   
  1240         -  rc = pModule->xCreate(0, 0, &pTokenizer);
  1241         -  assert( rc==SQLITE_NOMEM || rc==SQLITE_OK );
  1242         -  if( rc==SQLITE_NOMEM ){
  1243         -    sqlite3_result_error_nomem(context);
  1244         -    goto exprtest_out;
  1245         -  }
  1246         -  pTokenizer->pModule = pModule;
  1247         -
  1248   1216     zExpr = (const char *)sqlite3_value_text(argv[1]);
  1249   1217     nExpr = sqlite3_value_bytes(argv[1]);
  1250   1218     nCol = argc-2;
  1251   1219     azCol = (char **)sqlite3_malloc(nCol*sizeof(char *));
  1252   1220     if( !azCol ){
  1253   1221       sqlite3_result_error_nomem(context);
  1254   1222       goto exprtest_out;
  1255   1223     }
  1256   1224     for(ii=0; ii<nCol; ii++){
  1257   1225       azCol[ii] = (char *)sqlite3_value_text(argv[ii+2]);
  1258   1226     }
  1259   1227   
  1260         -  if( sqlite3_user_data(context) ){
         1228  +  if( bRebalance ){
  1261   1229       char *zDummy = 0;
  1262   1230       rc = sqlite3Fts3ExprParse(
  1263   1231           pTokenizer, 0, azCol, 0, nCol, nCol, zExpr, nExpr, &pExpr, &zDummy
  1264   1232       );
  1265   1233       assert( rc==SQLITE_OK || pExpr==0 );
  1266   1234       sqlite3_free(zDummy);
  1267   1235     }else{
................................................................................
  1279   1247       sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT);
  1280   1248       sqlite3_free(zBuf);
  1281   1249     }
  1282   1250   
  1283   1251     sqlite3Fts3ExprFree(pExpr);
  1284   1252   
  1285   1253   exprtest_out:
  1286         -  if( pModule && pTokenizer ){
  1287         -    rc = pModule->xDestroy(pTokenizer);
         1254  +  if( pTokenizer ){
         1255  +    rc = pTokenizer->pModule->xDestroy(pTokenizer);
  1288   1256     }
  1289   1257     sqlite3_free(azCol);
  1290   1258   }
         1259  +
         1260  +static void fts3ExprTest(
         1261  +  sqlite3_context *context,
         1262  +  int argc,
         1263  +  sqlite3_value **argv
         1264  +){
         1265  +  fts3ExprTestCommon(0, context, argc, argv);
         1266  +}
         1267  +static void fts3ExprTestRebalance(
         1268  +  sqlite3_context *context,
         1269  +  int argc,
         1270  +  sqlite3_value **argv
         1271  +){
         1272  +  fts3ExprTestCommon(1, context, argc, argv);
         1273  +}
  1291   1274   
  1292   1275   /*
  1293   1276   ** Register the query expression parser test function fts3_exprtest() 
  1294   1277   ** with database connection db. 
  1295   1278   */
  1296         -int sqlite3Fts3ExprInitTestInterface(sqlite3* db){
         1279  +int sqlite3Fts3ExprInitTestInterface(sqlite3 *db, Fts3Hash *pHash){
  1297   1280     int rc = sqlite3_create_function(
  1298         -      db, "fts3_exprtest", -1, SQLITE_UTF8, 0, fts3ExprTest, 0, 0
         1281  +      db, "fts3_exprtest", -1, SQLITE_UTF8, (void*)pHash, fts3ExprTest, 0, 0
  1299   1282     );
  1300   1283     if( rc==SQLITE_OK ){
  1301   1284       rc = sqlite3_create_function(db, "fts3_exprtest_rebalance", 
  1302         -        -1, SQLITE_UTF8, (void *)1, fts3ExprTest, 0, 0
         1285  +        -1, SQLITE_UTF8, (void*)pHash, fts3ExprTestRebalance, 0, 0
  1303   1286       );
  1304   1287     }
  1305   1288     return rc;
  1306   1289   }
  1307   1290   
  1308   1291   #endif
  1309   1292   #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */

Changes to ext/fts3/fts3_write.c.

  1904   1904     sqlite3_stmt *pStmt;
  1905   1905     int rc = fts3SqlStmt(p, SQL_INSERT_SEGMENTS, &pStmt, 0);
  1906   1906     if( rc==SQLITE_OK ){
  1907   1907       sqlite3_bind_int64(pStmt, 1, iBlock);
  1908   1908       sqlite3_bind_blob(pStmt, 2, z, n, SQLITE_STATIC);
  1909   1909       sqlite3_step(pStmt);
  1910   1910       rc = sqlite3_reset(pStmt);
         1911  +    sqlite3_bind_null(pStmt, 2);
  1911   1912     }
  1912   1913     return rc;
  1913   1914   }
  1914   1915   
  1915   1916   /*
  1916   1917   ** Find the largest relative level number in the table. If successful, set
  1917   1918   ** *pnMax to this value and return SQLITE_OK. Otherwise, if an error occurs,
................................................................................
  1960   1961         char *zEnd = sqlite3_mprintf("%lld %lld", iEndBlock, nLeafData);
  1961   1962         if( !zEnd ) return SQLITE_NOMEM;
  1962   1963         sqlite3_bind_text(pStmt, 5, zEnd, -1, sqlite3_free);
  1963   1964       }
  1964   1965       sqlite3_bind_blob(pStmt, 6, zRoot, nRoot, SQLITE_STATIC);
  1965   1966       sqlite3_step(pStmt);
  1966   1967       rc = sqlite3_reset(pStmt);
         1968  +    sqlite3_bind_null(pStmt, 6);
  1967   1969     }
  1968   1970     return rc;
  1969   1971   }
  1970   1972   
  1971   1973   /*
  1972   1974   ** Return the size of the common prefix (if any) shared by zPrev and
  1973   1975   ** zNext, in bytes. For example, 
................................................................................
  3439   3441       *pRC = rc;
  3440   3442       return;
  3441   3443     }
  3442   3444     sqlite3_bind_int(pStmt, 1, FTS_STAT_DOCTOTAL);
  3443   3445     sqlite3_bind_blob(pStmt, 2, pBlob, nBlob, SQLITE_STATIC);
  3444   3446     sqlite3_step(pStmt);
  3445   3447     *pRC = sqlite3_reset(pStmt);
         3448  +  sqlite3_bind_null(pStmt, 2);
  3446   3449     sqlite3_free(a);
  3447   3450   }
  3448   3451   
  3449   3452   /*
  3450   3453   ** Merge the entire database so that there is one segment for each 
  3451   3454   ** iIndex/iLangid combination.
  3452   3455   */
................................................................................
  4627   4630       if( rc==SQLITE_OK ){
  4628   4631         sqlite3_bind_int64(pChomp, 1, iNewStart);
  4629   4632         sqlite3_bind_blob(pChomp, 2, root.a, root.n, SQLITE_STATIC);
  4630   4633         sqlite3_bind_int64(pChomp, 3, iAbsLevel);
  4631   4634         sqlite3_bind_int(pChomp, 4, iIdx);
  4632   4635         sqlite3_step(pChomp);
  4633   4636         rc = sqlite3_reset(pChomp);
         4637  +      sqlite3_bind_null(pChomp, 2);
  4634   4638       }
  4635   4639     }
  4636   4640   
  4637   4641     sqlite3_free(root.a);
  4638   4642     sqlite3_free(block.a);
  4639   4643     return rc;
  4640   4644   }
................................................................................
  4706   4710   
  4707   4711     rc = fts3SqlStmt(p, SQL_REPLACE_STAT, &pReplace, 0);
  4708   4712     if( rc==SQLITE_OK ){
  4709   4713       sqlite3_bind_int(pReplace, 1, FTS_STAT_INCRMERGEHINT);
  4710   4714       sqlite3_bind_blob(pReplace, 2, pHint->a, pHint->n, SQLITE_STATIC);
  4711   4715       sqlite3_step(pReplace);
  4712   4716       rc = sqlite3_reset(pReplace);
         4717  +    sqlite3_bind_null(pReplace, 2);
  4713   4718     }
  4714   4719   
  4715   4720     return rc;
  4716   4721   }
  4717   4722   
  4718   4723   /*
  4719   4724   ** Load an incr-merge hint from the database. The incr-merge hint, if one 
................................................................................
  5520   5525     sqlite3_vtab *pVtab,            /* FTS3 vtab object */
  5521   5526     int nArg,                       /* Size of argument array */
  5522   5527     sqlite3_value **apVal,          /* Array of arguments */
  5523   5528     sqlite_int64 *pRowid            /* OUT: The affected (or effected) rowid */
  5524   5529   ){
  5525   5530     Fts3Table *p = (Fts3Table *)pVtab;
  5526   5531     int rc = SQLITE_OK;             /* Return Code */
  5527         -  int isRemove = 0;               /* True for an UPDATE or DELETE */
  5528   5532     u32 *aSzIns = 0;                /* Sizes of inserted documents */
  5529   5533     u32 *aSzDel = 0;                /* Sizes of deleted documents */
  5530   5534     int nChng = 0;                  /* Net change in number of documents */
  5531   5535     int bInsertDone = 0;
  5532   5536   
  5533   5537     /* At this point it must be known if the %_stat table exists or not.
  5534   5538     ** So bHasStat may not be 2.  */
................................................................................
  5618   5622       goto update_out;
  5619   5623     }
  5620   5624   
  5621   5625     /* If this is a DELETE or UPDATE operation, remove the old record. */
  5622   5626     if( sqlite3_value_type(apVal[0])!=SQLITE_NULL ){
  5623   5627       assert( sqlite3_value_type(apVal[0])==SQLITE_INTEGER );
  5624   5628       rc = fts3DeleteByRowid(p, apVal[0], &nChng, aSzDel);
  5625         -    isRemove = 1;
  5626   5629     }
  5627   5630     
  5628   5631     /* If this is an INSERT or UPDATE operation, insert the new record. */
  5629   5632     if( nArg>1 && rc==SQLITE_OK ){
  5630   5633       int iLangid = sqlite3_value_int(apVal[2 + p->nColumn + 2]);
  5631   5634       if( bInsertDone==0 ){
  5632   5635         rc = fts3InsertData(p, apVal, pRowid);
  5633   5636         if( rc==SQLITE_CONSTRAINT && p->zContentTbl==0 ){
  5634   5637           rc = FTS_CORRUPT_VTAB;
  5635   5638         }
  5636   5639       }
  5637         -    if( rc==SQLITE_OK && (!isRemove || *pRowid!=p->iPrevDocid ) ){
         5640  +    if( rc==SQLITE_OK ){
  5638   5641         rc = fts3PendingTermsDocid(p, 0, iLangid, *pRowid);
  5639   5642       }
  5640   5643       if( rc==SQLITE_OK ){
  5641   5644         assert( p->iPrevDocid==*pRowid );
  5642   5645         rc = fts3InsertTerms(p, iLangid, apVal, aSzIns);
  5643   5646       }
  5644   5647       if( p->bHasDocsize ){

Changes to ext/fts3/unicode/mkunicode.tcl.

   524    524       tl_print_if_entry $entry
   525    525     }
   526    526   
   527    527     puts ""
   528    528     puts "  return ret;"
   529    529     puts "\}"
   530    530   }
          531  +
          532  +proc code {txt} {
          533  +  set txt [string trimright $txt]
          534  +  set txt [string trimleft $txt "\n"]
          535  +  set n [expr {[string length $txt] - [string length [string trim $txt]]}]
          536  +  set ret ""
          537  +  foreach L [split $txt "\n"] {
          538  +    append ret "[string range $L $n end]\n"
          539  +  }
          540  +  return [uplevel "subst -nocommands {$ret}"]
          541  +}
          542  +
          543  +proc intarray {lInt} {
          544  +  set ret ""
          545  +  set n [llength $lInt]
          546  +  for {set i 0} {$i < $n} {incr i 10} {
          547  +    append ret "\n    "
          548  +    foreach int [lrange $lInt $i [expr $i+9]] {
          549  +      append ret [format "%-7s" "$int, "]
          550  +    }
          551  +  }
          552  +  append ret "\n  "
          553  +  set ret
          554  +}
          555  +
          556  +proc categories_switch {Cvar first lSecond} {
          557  +  upvar $Cvar C
          558  +  set ret ""
          559  +  append ret "case '$first':\n"
          560  +  append ret "          switch( zCat\[1\] ){\n"
          561  +  foreach s $lSecond {
          562  +    append ret "            case '$s': aArray\[$C($first$s)\] = 1; break;\n"
          563  +  }
          564  +  append ret "            case '*': \n"
          565  +  foreach s $lSecond {
          566  +    append ret "              aArray\[$C($first$s)\] = 1;\n"
          567  +  }
          568  +  append ret "              break;\n"
          569  +  append ret "            default: return 1;"
          570  +  append ret "          }\n"
          571  +  append ret "          break;\n"
          572  +}
          573  +
          574  +# Argument is a list. Each element of which is itself a list of two elements:
          575  +#
          576  +#   * the codepoint
          577  +#   * the category
          578  +#
          579  +# List elements are sorted in order of codepoint.
          580  +#
          581  +proc print_categories {lMap} {
          582  +  set categories {
          583  +    Cc Cf Cn Cs
          584  +    Ll Lm Lo Lt Lu
          585  +    Mc Me Mn
          586  +    Nd Nl No
          587  +    Pc Pd Pe Pf Pi Po Ps
          588  +    Sc Sk Sm So
          589  +    Zl Zp Zs
          590  +
          591  +    LC Co
          592  +  }
          593  +
          594  +  for {set i 0} {$i < [llength $categories]} {incr i} {
          595  +    set C([lindex $categories $i]) [expr 1+$i]
          596  +  }
          597  +
          598  +  set caseC [categories_switch C C {c f n s o}]
          599  +  set caseL [categories_switch C L {l m o t u C}]
          600  +  set caseM [categories_switch C M {c e n}]
          601  +  set caseN [categories_switch C N {d l o}]
          602  +  set caseP [categories_switch C P {c d e f i o s}]
          603  +  set caseS [categories_switch C S {c k m o}]
          604  +  set caseZ [categories_switch C Z {l p s}]
          605  +
          606  +  set nCat [expr [llength [array names C]] + 1]
          607  +  puts [code {
          608  +    int sqlite3Fts5UnicodeNCat(void) { 
          609  +      return $nCat;
          610  +    }
          611  +
          612  +    int sqlite3Fts5UnicodeCatParse(const char *zCat, u8 *aArray){ 
          613  +      aArray[0] = 1;
          614  +      switch( zCat[0] ){
          615  +        $caseC
          616  +        $caseL
          617  +        $caseM
          618  +        $caseN
          619  +        $caseP
          620  +        $caseS
          621  +        $caseZ
          622  +      }
          623  +      return 0;
          624  +    }
          625  +  }]
          626  +
          627  +  set nRepeat 0
          628  +  set first   [lindex $lMap 0 0]
          629  +  set class   [lindex $lMap 0 1]
          630  +  set prev -1
          631  +
          632  +  set CASE(0) "Lu"
          633  +  set CASE(1) "Ll"
          634  +
          635  +  foreach m $lMap {
          636  +    foreach {codepoint cl} $m {}
          637  +    set codepoint [expr "0x$codepoint"]
          638  +    if {$codepoint>=(1<<20)} continue
          639  +
          640  +    set bNew 0
          641  +    if {$codepoint!=($prev+1)} {
          642  +      set bNew 1
          643  +    } elseif {
          644  +      $cl==$class || ($class=="LC" && $cl==$CASE([expr $nRepeat & 0x01]))
          645  +    } {
          646  +      incr nRepeat
          647  +    } elseif {$class=="Lu" && $nRepeat==1 && $cl=="Ll"} {
          648  +      set class LC
          649  +      incr nRepeat
          650  +    } else {
          651  +      set bNew 1
          652  +    }
          653  +    if {$bNew} {
          654  +      lappend lEntries [list $first $class $nRepeat]
          655  +      set nRepeat 1
          656  +      set first $codepoint
          657  +      set class $cl
          658  +    }
          659  +    set prev $codepoint
          660  +  }
          661  +  if {$nRepeat>0} {
          662  +    lappend lEntries [list $first $class $nRepeat]
          663  +  }
          664  +
          665  +  set aBlock [list 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
          666  +  set aMap [list]
          667  +  foreach e $lEntries {
          668  +    foreach {cp class nRepeat} $e {}
          669  +    set block [expr ($cp>>16)]
          670  +    if {$block>0 && [lindex $aBlock $block]==0} {
          671  +      for {set i 1} {$i<=$block} {incr i} {
          672  +        if {[lindex $aBlock $i]==0} {
          673  +          lset aBlock $i [llength $aMap]
          674  +        }
          675  +      }
          676  +    }
          677  +    lappend aMap [expr {$cp & 0xFFFF}]
          678  +    lappend aData [expr {($nRepeat << 5) + $C($class)}]
          679  +  }
          680  +  for {set i 1} {$i<[llength $aBlock]} {incr i} {
          681  +    if {[lindex $aBlock $i]==0} {
          682  +      lset aBlock $i [llength $aMap]
          683  +    }
          684  +  }
          685  +
          686  +  set aBlockArray [intarray $aBlock]
          687  +  set aMapArray [intarray $aMap]
          688  +  set aDataArray [intarray $aData]
          689  +  puts [code {
          690  +    static u16 aFts5UnicodeBlock[] = {$aBlockArray};
          691  +    static u16 aFts5UnicodeMap[] = {$aMapArray};
          692  +    static u16 aFts5UnicodeData[] = {$aDataArray};
          693  +
          694  +    int sqlite3Fts5UnicodeCategory(int iCode) { 
          695  +      int iRes = -1;
          696  +      int iHi;
          697  +      int iLo;
          698  +      int ret;
          699  +      u16 iKey;
          700  +
          701  +      if( iCode>=(1<<20) ){
          702  +        return 0;
          703  +      }
          704  +      iLo = aFts5UnicodeBlock[(iCode>>16)];
          705  +      iHi = aFts5UnicodeBlock[1+(iCode>>16)];
          706  +      iKey = (iCode & 0xFFFF);
          707  +      while( iHi>iLo ){
          708  +        int iTest = (iHi + iLo) / 2;
          709  +        assert( iTest>=iLo && iTest<iHi );
          710  +        if( iKey>=aFts5UnicodeMap[iTest] ){
          711  +          iRes = iTest;
          712  +          iLo = iTest+1;
          713  +        }else{
          714  +          iHi = iTest;
          715  +        }
          716  +      }
          717  +
          718  +      if( iRes<0 ) return 0;
          719  +      if( iKey>=(aFts5UnicodeMap[iRes]+(aFts5UnicodeData[iRes]>>5)) ) return 0;
          720  +      ret = aFts5UnicodeData[iRes] & 0x1F;
          721  +      if( ret!=$C(LC) ) return ret;
          722  +      return ((iKey - aFts5UnicodeMap[iRes]) & 0x01) ? $C(Ll) : $C(Lu);
          723  +    }
          724  +
          725  +    void sqlite3Fts5UnicodeAscii(u8 *aArray, u8 *aAscii){
          726  +      int i = 0;
          727  +      int iTbl = 0;
          728  +      while( i<128 ){
          729  +        int bToken = aArray[ aFts5UnicodeData[iTbl] & 0x1F ];
          730  +        int n = (aFts5UnicodeData[iTbl] >> 5) + i;
          731  +        for(; i<128 && i<n; i++){
          732  +          aAscii[i] = bToken;
          733  +        }
          734  +        iTbl++;
          735  +      }
          736  +    }
          737  +  }]
          738  +}
          739  +
          740  +proc print_test_categories {lMap} {
          741  +
          742  +  set lCP [list]
          743  +  foreach e $lMap {
          744  +    foreach {cp cat} $e {}
          745  +    if {[expr 0x$cp] < (1<<20)} {
          746  +      lappend lCP "{0x$cp, \"$cat\"}, "
          747  +    }
          748  +  }
          749  +
          750  +  set aCP "\n"
          751  +  for {set i 0} {$i < [llength $lCP]} {incr i 4} {
          752  +    append aCP "    [join [lrange $lCP $i $i+3]]\n"
          753  +  }
          754  +
          755  +
          756  +  puts [code {
          757  +    static int categories_test (int *piCode){
          758  +      struct Codepoint {
          759  +        int iCode;
          760  +        const char *zCat;
          761  +      } aCP[] = {$aCP};
          762  +      int i;
          763  +      int iCP = 0;
          764  +
          765  +      for(i=0; i<1000000; i++){
          766  +        u8 aArray[40];
          767  +        int cat = 0;
          768  +        int c = 0;
          769  +        memset(aArray, 0, sizeof(aArray));
          770  +        if( aCP[iCP].iCode==i ){
          771  +          sqlite3Fts5UnicodeCatParse(aCP[iCP].zCat, aArray);
          772  +          iCP++;
          773  +        }else{
          774  +          aArray[0] = 1;
          775  +        }
          776  +
          777  +        c = sqlite3Fts5UnicodeCategory(i);
          778  +        if( aArray[c]==0 ){
          779  +          *piCode = i;
          780  +          return 1;
          781  +        }
          782  +      }
          783  +
          784  +      return 0;
          785  +    }
          786  +  }]
          787  +}
   531    788   
   532    789   proc print_fold_test {zFunc mappings} {
   533    790     global tl_lookup_table
   534    791   
   535    792     foreach m $mappings {
   536    793       set c [lindex $m 1]
   537    794       if {$c == ""} {
................................................................................
   601    858   }
   602    859   
   603    860   proc print_test_main {} {
   604    861     puts ""
   605    862     puts "#include <stdio.h>"
   606    863     puts ""
   607    864     puts "int main(int argc, char **argv)\{"
   608         -  puts "  int r1, r2;"
          865  +  puts "  int r1, r2, r3;"
   609    866     puts "  int code;"
          867  +  puts "  r3 = 0;"
   610    868     puts "  r1 = isalnum_test(&code);"
   611    869     puts "  if( r1 ) printf(\"isalnum(): Problem with code %d\\n\",code);"
   612    870     puts "  else printf(\"isalnum(): test passed\\n\");"
   613    871     puts "  r2 = fold_test(&code);"
   614    872     puts "  if( r2 ) printf(\"fold(): Problem with code %d\\n\",code);"
   615    873     puts "  else printf(\"fold(): test passed\\n\");"
   616         -  puts "  return (r1 || r2);"
          874  +  if {$::generate_fts5_code} {
          875  +    puts "  r3 = categories_test(&code);"
          876  +    puts "  if( r3 ) printf(\"categories(): Problem with code %d\\n\",code);"
          877  +    puts "  else printf(\"categories(): test passed\\n\");"
          878  +  }
          879  +  puts "  return (r1 || r2 || r3);"
   617    880     puts "\}"
   618    881   }
   619    882   
   620    883   # Proces the command line arguments. Exit early if they are not to
   621    884   # our liking.
   622    885   #
   623    886   proc usage {} {
................................................................................
   646    909       default {
   647    910         usage
   648    911       }
   649    912     }
   650    913   }
   651    914   
   652    915   print_fileheader
          916  +
          917  +if {$::generate_test_code} {
          918  +  puts "typedef unsigned short int u16;"
          919  +  puts "typedef unsigned char u8;"
          920  +  puts "#include <string.h>"
          921  +}
   653    922   
   654    923   # Print the isalnum() function to stdout.
   655    924   #
   656    925   set lRange [an_load_separator_ranges]
   657         -print_isalnum ${function_prefix}UnicodeIsalnum $lRange
          926  +if {$generate_fts5_code==0} {
          927  +  print_isalnum ${function_prefix}UnicodeIsalnum $lRange
          928  +}
   658    929   
   659    930   # Leave a gap between the two generated C functions.
   660    931   #
   661    932   puts ""
   662    933   puts ""
   663    934   
   664    935   # Load the fold data. This is used by the [rd_XXX] commands
................................................................................
   672    943   print_isdiacritic ${function_prefix}UnicodeIsdiacritic $mappings
   673    944   puts ""
   674    945   puts ""
   675    946   
   676    947   # Print the fold() function to stdout.
   677    948   #
   678    949   print_fold ${function_prefix}UnicodeFold
          950  +
          951  +if {$generate_fts5_code} {
          952  +  puts ""
          953  +  puts ""
          954  +  print_categories [cc_load_unicodedata_text ${unicodedata.txt}]
          955  +}
   679    956   
   680    957   # Print the test routines and main() function to stdout, if -test 
   681    958   # was specified.
   682    959   #
   683    960   if {$::generate_test_code} {
   684         -  print_test_isalnum ${function_prefix}UnicodeIsalnum $lRange
          961  +  if {$generate_fts5_code==0} {
          962  +    print_test_isalnum ${function_prefix}UnicodeIsalnum $lRange
          963  +  }
   685    964     print_fold_test ${function_prefix}UnicodeFold $mappings
          965  +  print_test_categories [cc_load_unicodedata_text ${unicodedata.txt}]
   686    966     print_test_main 
   687    967   }
   688    968   
   689    969   if {$generate_fts5_code} {
   690    970     # no-op
   691    971   } else {
   692    972     puts "#endif /* defined(SQLITE_ENABLE_FTS3) || defined(SQLITE_ENABLE_FTS4) */"
   693    973     puts "#endif /* !defined(SQLITE_DISABLE_FTS3_UNICODE) */"
   694    974   }

Changes to ext/fts3/unicode/parseunicode.tcl.

   138    138       foreach elem $c { lappend c2 [expr "0x[string trim $elem]"] }
   139    139       set b [string trim $b]
   140    140       set d [string trim $d]
   141    141   
   142    142       if {$b=="C" || $b=="S"} { set tl_lookup_table($a2) $c2 }
   143    143     }
   144    144   }
          145  +
          146  +proc cc_load_unicodedata_text {zName} {
          147  +  set fd [open $zName]
          148  +  set lField {
          149  +    code
          150  +    character_name
          151  +    general_category
          152  +    canonical_combining_classes
          153  +    bidirectional_category
          154  +    character_decomposition_mapping
          155  +    decimal_digit_value
          156  +    digit_value
          157  +    numeric_value
          158  +    mirrored
          159  +    unicode_1_name
          160  +    iso10646_comment_field
          161  +    uppercase_mapping
          162  +    lowercase_mapping
          163  +    titlecase_mapping
          164  +  }
          165  +  set lRet [list]
          166  +
          167  +  while { ![eof $fd] } {
          168  +    set line [gets $fd]
          169  +    if {$line == ""} continue
          170  +
          171  +    set fields [split $line ";"]
          172  +    if {[llength $fields] != [llength $lField]} { error "parse error: $line" }
          173  +    foreach $lField $fields {}
          174  +
          175  +    lappend lRet [list $code $general_category]
          176  +  }
          177  +
          178  +  close $fd
          179  +  set lRet
          180  +}
   145    181   
   146    182   

Changes to ext/fts5/fts5.h.

   440    440   **            document such as "I won first place" is tokenized, entries are
   441    441   **            added to the FTS index for "i", "won", "first", "1st" and
   442    442   **            "place".
   443    443   **
   444    444   **            This way, even if the tokenizer does not provide synonyms
   445    445   **            when tokenizing query text (it should not - to do would be
   446    446   **            inefficient), it doesn't matter if the user queries for 
   447         -**            'first + place' or '1st + place', as there are entires in the
          447  +**            'first + place' or '1st + place', as there are entries in the
   448    448   **            FTS index corresponding to both forms of the first token.
   449    449   **   </ol>
   450    450   **
   451    451   **   Whether it is parsing document or query text, any call to xToken that
   452    452   **   specifies a <i>tflags</i> argument with the FTS5_TOKEN_COLOCATED bit
   453    453   **   is considered to supply a synonym for the previous token. For example,
   454    454   **   when parsing the document "I won first place", a tokenizer that supports
................................................................................
   468    468   **   There is no limit to the number of synonyms that may be provided for a
   469    469   **   single token.
   470    470   **
   471    471   **   In many cases, method (1) above is the best approach. It does not add 
   472    472   **   extra data to the FTS index or require FTS5 to query for multiple terms,
   473    473   **   so it is efficient in terms of disk space and query speed. However, it
   474    474   **   does not support prefix queries very well. If, as suggested above, the
   475         -**   token "first" is subsituted for "1st" by the tokenizer, then the query:
          475  +**   token "first" is substituted for "1st" by the tokenizer, then the query:
   476    476   **
   477    477   **   <codeblock>
   478    478   **     ... MATCH '1s*'</codeblock>
   479    479   **
   480    480   **   will not match documents that contain the token "1st" (as the tokenizer
   481    481   **   will probably not map "1s" to any prefix of "first").
   482    482   **

Changes to ext/fts5/fts5Int.h.

   718    718   Fts5ExprPhrase *sqlite3Fts5ParseTerm(
   719    719     Fts5Parse *pParse, 
   720    720     Fts5ExprPhrase *pPhrase, 
   721    721     Fts5Token *pToken,
   722    722     int bPrefix
   723    723   );
   724    724   
          725  +void sqlite3Fts5ParseSetCaret(Fts5ExprPhrase*);
          726  +
   725    727   Fts5ExprNearset *sqlite3Fts5ParseNearset(
   726    728     Fts5Parse*, 
   727    729     Fts5ExprNearset*,
   728    730     Fts5ExprPhrase* 
   729    731   );
   730    732   
   731    733   Fts5Colset *sqlite3Fts5ParseColset(
................................................................................
   778    780   ** End of interface to code in fts5_vocab.c.
   779    781   **************************************************************************/
   780    782   
   781    783   
   782    784   /**************************************************************************
   783    785   ** Interface to automatically generated code in fts5_unicode2.c. 
   784    786   */
   785         -int sqlite3Fts5UnicodeIsalnum(int c);
   786    787   int sqlite3Fts5UnicodeIsdiacritic(int c);
   787    788   int sqlite3Fts5UnicodeFold(int c, int bRemoveDiacritic);
          789  +
          790  +int sqlite3Fts5UnicodeCatParse(const char*, u8*);
          791  +int sqlite3Fts5UnicodeCategory(int iCode);
          792  +void sqlite3Fts5UnicodeAscii(u8*, u8*);
   788    793   /*
   789    794   ** End of interface to code in fts5_unicode2.c.
   790    795   **************************************************************************/
   791    796   
   792    797   #endif

Changes to ext/fts5/fts5_aux.c.

   353    353       if( (iAdj+nToken)>nDocsize ) iAdj = nDocsize - nToken;
   354    354       if( iAdj<0 ) iAdj = 0;
   355    355       *piPos = iAdj;
   356    356     }
   357    357   
   358    358     return rc;
   359    359   }
          360  +
          361  +/*
          362  +** Return the value in pVal interpreted as utf-8 text. Except, if pVal 
          363  +** contains a NULL value, return a pointer to a static string zero
          364  +** bytes in length instead of a NULL pointer.
          365  +*/
          366  +static const char *fts5ValueToText(sqlite3_value *pVal){
          367  +  const char *zRet = (const char*)sqlite3_value_text(pVal);
          368  +  return zRet ? zRet : "";
          369  +}
   360    370   
   361    371   /*
   362    372   ** Implementation of snippet() function.
   363    373   */
   364    374   static void fts5SnippetFunction(
   365    375     const Fts5ExtensionApi *pApi,   /* API offered by current FTS version */
   366    376     Fts5Context *pFts,              /* First arg to pass to pApi functions */
................................................................................
   389    399       sqlite3_result_error(pCtx, zErr, -1);
   390    400       return;
   391    401     }
   392    402   
   393    403     nCol = pApi->xColumnCount(pFts);
   394    404     memset(&ctx, 0, sizeof(HighlightContext));
   395    405     iCol = sqlite3_value_int(apVal[0]);
   396         -  ctx.zOpen = (const char*)sqlite3_value_text(apVal[1]);
   397         -  ctx.zClose = (const char*)sqlite3_value_text(apVal[2]);
   398         -  zEllips = (const char*)sqlite3_value_text(apVal[3]);
          406  +  ctx.zOpen = fts5ValueToText(apVal[1]);
          407  +  ctx.zClose = fts5ValueToText(apVal[2]);
          408  +  zEllips = fts5ValueToText(apVal[3]);
   399    409     nToken = sqlite3_value_int(apVal[4]);
   400    410   
   401    411     iBestCol = (iCol>=0 ? iCol : 0);
   402    412     nPhrase = pApi->xPhraseCount(pFts);
   403    413     aSeen = sqlite3_malloc(nPhrase);
   404    414     if( aSeen==0 ){
   405    415       rc = SQLITE_NOMEM;

Changes to ext/fts5/fts5_expr.c.

    32     32   void *sqlite3Fts5ParserAlloc(void *(*mallocProc)(u64));
    33     33   void sqlite3Fts5ParserFree(void*, void (*freeProc)(void*));
    34     34   void sqlite3Fts5Parser(void*, int, Fts5Token, Fts5Parse*);
    35     35   #ifndef NDEBUG
    36     36   #include <stdio.h>
    37     37   void sqlite3Fts5ParserTrace(FILE*, char*);
    38     38   #endif
           39  +int sqlite3Fts5ParserFallback(int);
    39     40   
    40     41   
    41     42   struct Fts5Expr {
    42     43     Fts5Index *pIndex;
    43     44     Fts5Config *pConfig;
    44     45     Fts5ExprNode *pRoot;
    45     46     int bDesc;                      /* Iterate in descending rowid order */
................................................................................
    83     84   #define fts5ExprNodeNext(a,b,c,d) (b)->xNext((a), (b), (c), (d))
    84     85   
    85     86   /*
    86     87   ** An instance of the following structure represents a single search term
    87     88   ** or term prefix.
    88     89   */
    89     90   struct Fts5ExprTerm {
    90         -  int bPrefix;                    /* True for a prefix term */
           91  +  u8 bPrefix;                     /* True for a prefix term */
           92  +  u8 bFirst;                      /* True if token must be first in column */
    91     93     char *zTerm;                    /* nul-terminated term */
    92     94     Fts5IndexIter *pIter;           /* Iterator for this term */
    93     95     Fts5ExprTerm *pSynonym;         /* Pointer to first in list of synonyms */
    94     96   };
    95     97   
    96     98   /*
    97     99   ** A phrase. One or more terms that must appear in a contiguous sequence
................................................................................
   164    166       case '{':  tok = FTS5_LCP;   break;
   165    167       case '}':  tok = FTS5_RCP;   break;
   166    168       case ':':  tok = FTS5_COLON; break;
   167    169       case ',':  tok = FTS5_COMMA; break;
   168    170       case '+':  tok = FTS5_PLUS;  break;
   169    171       case '*':  tok = FTS5_STAR;  break;
   170    172       case '-':  tok = FTS5_MINUS; break;
          173  +    case '^':  tok = FTS5_CARET; break;
   171    174       case '\0': tok = FTS5_EOF;   break;
   172    175   
   173    176       case '"': {
   174    177         const char *z2;
   175    178         tok = FTS5_STRING;
   176    179   
   177    180         for(z2=&z[1]; 1; z2++){
................................................................................
   423    426     int *pbMatch                    /* OUT: Set to true if really a match */
   424    427   ){
   425    428     Fts5PoslistWriter writer = {0};
   426    429     Fts5PoslistReader aStatic[4];
   427    430     Fts5PoslistReader *aIter = aStatic;
   428    431     int i;
   429    432     int rc = SQLITE_OK;
          433  +  int bFirst = pPhrase->aTerm[0].bFirst;
   430    434     
   431    435     fts5BufferZero(&pPhrase->poslist);
   432    436   
   433    437     /* If the aStatic[] array is not large enough, allocate a large array
   434    438     ** using sqlite3_malloc(). This approach could be improved upon. */
   435    439     if( pPhrase->nTerm>ArraySize(aStatic) ){
   436    440       int nByte = sizeof(Fts5PoslistReader) * pPhrase->nTerm;
................................................................................
   477    481             }
   478    482             if( pPos->iPos>iAdj ) iPos = pPos->iPos-i;
   479    483           }
   480    484         }
   481    485       }while( bMatch==0 );
   482    486   
   483    487       /* Append position iPos to the output */
   484         -    rc = sqlite3Fts5PoslistWriterAppend(&pPhrase->poslist, &writer, iPos);
   485         -    if( rc!=SQLITE_OK ) goto ismatch_out;
          488  +    if( bFirst==0 || FTS5_POS2OFFSET(iPos)==0 ){
          489  +      rc = sqlite3Fts5PoslistWriterAppend(&pPhrase->poslist, &writer, iPos);
          490  +      if( rc!=SQLITE_OK ) goto ismatch_out;
          491  +    }
   486    492   
   487    493       for(i=0; i<pPhrase->nTerm; i++){
   488    494         if( sqlite3Fts5PoslistReaderNext(&aIter[i]) ) goto ismatch_out;
   489    495       }
   490    496     }
   491    497   
   492    498    ismatch_out:
................................................................................
   732    738       int i;
   733    739   
   734    740       /* Check that each phrase in the nearset matches the current row.
   735    741       ** Populate the pPhrase->poslist buffers at the same time. If any
   736    742       ** phrase is not a match, break out of the loop early.  */
   737    743       for(i=0; rc==SQLITE_OK && i<pNear->nPhrase; i++){
   738    744         Fts5ExprPhrase *pPhrase = pNear->apPhrase[i];
   739         -      if( pPhrase->nTerm>1 || pPhrase->aTerm[0].pSynonym || pNear->pColset ){
          745  +      if( pPhrase->nTerm>1 || pPhrase->aTerm[0].pSynonym 
          746  +       || pNear->pColset || pPhrase->aTerm[0].bFirst
          747  +      ){
   740    748           int bMatch = 0;
   741    749           rc = fts5ExprPhraseIsMatch(pNode, pPhrase, &bMatch);
   742    750           if( bMatch==0 ) break;
   743    751         }else{
   744    752           Fts5IndexIter *pIter = pPhrase->aTerm[0].pIter;
   745    753           fts5BufferSet(&rc, &pPhrase->poslist, pIter->nData, pIter->pData);
   746    754         }
................................................................................
   913    921     int bMatch;                     /* True if all terms are at the same rowid */
   914    922     const int bDesc = pExpr->bDesc;
   915    923   
   916    924     /* Check that this node should not be FTS5_TERM */
   917    925     assert( pNear->nPhrase>1 
   918    926          || pNear->apPhrase[0]->nTerm>1 
   919    927          || pNear->apPhrase[0]->aTerm[0].pSynonym
          928  +       || pNear->apPhrase[0]->aTerm[0].bFirst
   920    929     );
   921    930   
   922    931     /* Initialize iLast, the "lastest" rowid any iterator points to. If the
   923    932     ** iterator skips through rowids in the default ascending order, this means
   924    933     ** the maximum rowid. Or, if the iterator is "ORDER BY rowid DESC", then it
   925    934     ** means the minimum rowid.  */
   926    935     if( pLeft->aTerm[0].pSynonym ){
................................................................................
  1436   1445           sqlite3_free(pSyn);
  1437   1446         }
  1438   1447       }
  1439   1448       if( pPhrase->poslist.nSpace>0 ) fts5BufferFree(&pPhrase->poslist);
  1440   1449       sqlite3_free(pPhrase);
  1441   1450     }
  1442   1451   }
         1452  +
         1453  +/*
         1454  +** Set the "bFirst" flag on the first token of the phrase passed as the
         1455  +** only argument.
         1456  +*/
         1457  +void sqlite3Fts5ParseSetCaret(Fts5ExprPhrase *pPhrase){
         1458  +  if( pPhrase && pPhrase->nTerm ){
         1459  +    pPhrase->aTerm[0].bFirst = 1;
         1460  +  }
         1461  +}
  1443   1462   
  1444   1463   /*
  1445   1464   ** If argument pNear is NULL, then a new Fts5ExprNearset object is allocated
  1446   1465   ** and populated with pPhrase. Or, if pNear is not NULL, phrase pPhrase is
  1447   1466   ** appended to it and the results returned.
  1448   1467   **
  1449   1468   ** If an OOM error occurs, both the pNear and pPhrase objects are freed and
................................................................................
  1654   1673       }
  1655   1674   
  1656   1675       if( sCtx.pPhrase==0 ){
  1657   1676         /* This happens when parsing a token or quoted phrase that contains
  1658   1677         ** no token characters at all. (e.g ... MATCH '""'). */
  1659   1678         sCtx.pPhrase = sqlite3Fts5MallocZero(&pParse->rc, sizeof(Fts5ExprPhrase));
  1660   1679       }else if( sCtx.pPhrase->nTerm ){
  1661         -      sCtx.pPhrase->aTerm[sCtx.pPhrase->nTerm-1].bPrefix = bPrefix;
         1680  +      sCtx.pPhrase->aTerm[sCtx.pPhrase->nTerm-1].bPrefix = (u8)bPrefix;
  1662   1681       }
  1663   1682       pParse->apPhrase[pParse->nPhrase-1] = sCtx.pPhrase;
  1664   1683     }
  1665   1684   
  1666   1685     return sCtx.pPhrase;
  1667   1686   }
  1668   1687   
................................................................................
  1715   1734           const char *zTerm = p->zTerm;
  1716   1735           rc = fts5ParseTokenize((void*)&sCtx, tflags, zTerm, (int)strlen(zTerm),
  1717   1736               0, 0);
  1718   1737           tflags = FTS5_TOKEN_COLOCATED;
  1719   1738         }
  1720   1739         if( rc==SQLITE_OK ){
  1721   1740           sCtx.pPhrase->aTerm[i].bPrefix = pOrig->aTerm[i].bPrefix;
         1741  +        sCtx.pPhrase->aTerm[i].bFirst = pOrig->aTerm[i].bFirst;
  1722   1742         }
  1723   1743       }
  1724   1744     }else{
  1725   1745       /* This happens when parsing a token or quoted phrase that contains
  1726   1746       ** no token characters at all. (e.g ... MATCH '""'). */
  1727   1747       sCtx.pPhrase = sqlite3Fts5MallocZero(&rc, sizeof(Fts5ExprPhrase));
  1728   1748     }
................................................................................
  1733   1753       pNew->pConfig = pExpr->pConfig;
  1734   1754       pNew->nPhrase = 1;
  1735   1755       pNew->apExprPhrase[0] = sCtx.pPhrase;
  1736   1756       pNew->pRoot->pNear->apPhrase[0] = sCtx.pPhrase;
  1737   1757       pNew->pRoot->pNear->nPhrase = 1;
  1738   1758       sCtx.pPhrase->pNode = pNew->pRoot;
  1739   1759   
  1740         -    if( pOrig->nTerm==1 && pOrig->aTerm[0].pSynonym==0 ){
         1760  +    if( pOrig->nTerm==1 
         1761  +     && pOrig->aTerm[0].pSynonym==0 
         1762  +     && pOrig->aTerm[0].bFirst==0 
         1763  +    ){
  1741   1764         pNew->pRoot->eType = FTS5_TERM;
  1742   1765         pNew->pRoot->xNext = fts5ExprNodeNext_TERM;
  1743   1766       }else{
  1744   1767         pNew->pRoot->eType = FTS5_STRING;
  1745   1768         pNew->pRoot->xNext = fts5ExprNodeNext_STRING;
  1746   1769       }
  1747   1770     }else{
................................................................................
  2007   2030   
  2008   2031   static void fts5ExprAssignXNext(Fts5ExprNode *pNode){
  2009   2032     switch( pNode->eType ){
  2010   2033       case FTS5_STRING: {
  2011   2034         Fts5ExprNearset *pNear = pNode->pNear;
  2012   2035         if( pNear->nPhrase==1 && pNear->apPhrase[0]->nTerm==1 
  2013   2036          && pNear->apPhrase[0]->aTerm[0].pSynonym==0
         2037  +       && pNear->apPhrase[0]->aTerm[0].bFirst==0
  2014   2038         ){
  2015   2039           pNode->eType = FTS5_TERM;
  2016   2040           pNode->xNext = fts5ExprNodeNext_TERM;
  2017   2041         }else{
  2018   2042           pNode->xNext = fts5ExprNodeNext_STRING;
  2019   2043         }
  2020   2044         break;
................................................................................
  2093   2117             pNear->apPhrase[iPhrase]->pNode = pRet;
  2094   2118             if( pNear->apPhrase[iPhrase]->nTerm==0 ){
  2095   2119               pRet->xNext = 0;
  2096   2120               pRet->eType = FTS5_EOF;
  2097   2121             }
  2098   2122           }
  2099   2123   
  2100         -        if( pParse->pConfig->eDetail!=FTS5_DETAIL_FULL 
  2101         -         && (pNear->nPhrase!=1 || pNear->apPhrase[0]->nTerm>1)
  2102         -        ){
  2103         -          assert( pParse->rc==SQLITE_OK );
  2104         -          pParse->rc = SQLITE_ERROR;
  2105         -          assert( pParse->zErr==0 );
  2106         -          pParse->zErr = sqlite3_mprintf(
  2107         -              "fts5: %s queries are not supported (detail!=full)", 
  2108         -              pNear->nPhrase==1 ? "phrase": "NEAR"
  2109         -          );
  2110         -          sqlite3_free(pRet);
  2111         -          pRet = 0;
         2124  +        if( pParse->pConfig->eDetail!=FTS5_DETAIL_FULL ){
         2125  +          Fts5ExprPhrase *pPhrase = pNear->apPhrase[0];
         2126  +          if( pNear->nPhrase!=1 
         2127  +           || pPhrase->nTerm>1
         2128  +           || (pPhrase->nTerm>0 && pPhrase->aTerm[0].bFirst)
         2129  +          ){
         2130  +            assert( pParse->rc==SQLITE_OK );
         2131  +            pParse->rc = SQLITE_ERROR;
         2132  +            assert( pParse->zErr==0 );
         2133  +            pParse->zErr = sqlite3_mprintf(
         2134  +                "fts5: %s queries are not supported (detail!=full)", 
         2135  +                pNear->nPhrase==1 ? "phrase": "NEAR"
         2136  +                );
         2137  +            sqlite3_free(pRet);
         2138  +            pRet = 0;
         2139  +          }
  2112   2140           }
  2113         -
  2114   2141         }else{
  2115   2142           fts5ExprAddChildren(pRet, pLeft);
  2116   2143           fts5ExprAddChildren(pRet, pRight);
  2117   2144         }
  2118   2145       }
  2119   2146     }
  2120   2147   
................................................................................
  2510   2537   */
  2511   2538   static void fts5ExprIsAlnum(
  2512   2539     sqlite3_context *pCtx,          /* Function call context */
  2513   2540     int nArg,                       /* Number of args */
  2514   2541     sqlite3_value **apVal           /* Function arguments */
  2515   2542   ){
  2516   2543     int iCode;
         2544  +  u8 aArr[32];
  2517   2545     if( nArg!=1 ){
  2518   2546       sqlite3_result_error(pCtx, 
  2519   2547           "wrong number of arguments to function fts5_isalnum", -1
  2520   2548       );
  2521   2549       return;
  2522   2550     }
         2551  +  memset(aArr, 0, sizeof(aArr));
         2552  +  sqlite3Fts5UnicodeCatParse("L*", aArr);
         2553  +  sqlite3Fts5UnicodeCatParse("N*", aArr);
         2554  +  sqlite3Fts5UnicodeCatParse("Co", aArr);
  2523   2555     iCode = sqlite3_value_int(apVal[0]);
  2524         -  sqlite3_result_int(pCtx, sqlite3Fts5UnicodeIsalnum(iCode));
         2556  +  sqlite3_result_int(pCtx, aArr[sqlite3Fts5UnicodeCategory(iCode)]);
  2525   2557   }
  2526   2558   
  2527   2559   static void fts5ExprFold(
  2528   2560     sqlite3_context *pCtx,          /* Function call context */
  2529   2561     int nArg,                       /* Number of args */
  2530   2562     sqlite3_value **apVal           /* Function arguments */
  2531   2563   ){
................................................................................
  2561   2593     void *pCtx = (void*)pGlobal;
  2562   2594   
  2563   2595     for(i=0; rc==SQLITE_OK && i<ArraySize(aFunc); i++){
  2564   2596       struct Fts5ExprFunc *p = &aFunc[i];
  2565   2597       rc = sqlite3_create_function(db, p->z, -1, SQLITE_UTF8, pCtx, p->x, 0, 0);
  2566   2598     }
  2567   2599   
  2568         -  /* Avoid a warning indicating that sqlite3Fts5ParserTrace() is unused */
         2600  +  /* Avoid warnings indicating that sqlite3Fts5ParserTrace() and
         2601  +  ** sqlite3Fts5ParserFallback() are unused */
  2569   2602   #ifndef NDEBUG
  2570   2603     (void)sqlite3Fts5ParserTrace;
  2571   2604   #endif
         2605  +  (void)sqlite3Fts5ParserFallback;
  2572   2606   
  2573   2607     return rc;
  2574   2608   }
  2575   2609   
  2576   2610   /*
  2577   2611   ** Return the number of phrases in expression pExpr.
  2578   2612   */

Changes to ext/fts5/fts5_index.c.

   754    754       if( p->rc ) return;
   755    755     }
   756    756   
   757    757     sqlite3_bind_int64(p->pWriter, 1, iRowid);
   758    758     sqlite3_bind_blob(p->pWriter, 2, pData, nData, SQLITE_STATIC);
   759    759     sqlite3_step(p->pWriter);
   760    760     p->rc = sqlite3_reset(p->pWriter);
          761  +  sqlite3_bind_null(p->pWriter, 2);
   761    762   }
   762    763   
   763    764   /*
   764    765   ** Execute the following SQL:
   765    766   **
   766    767   **     DELETE FROM %_data WHERE id BETWEEN $iFirst AND $iLast
   767    768   */
................................................................................
  2382   2383     sqlite3_bind_blob(pIdxSelect, 2, pTerm, nTerm, SQLITE_STATIC);
  2383   2384     if( SQLITE_ROW==sqlite3_step(pIdxSelect) ){
  2384   2385       i64 val = sqlite3_column_int(pIdxSelect, 0);
  2385   2386       iPg = (int)(val>>1);
  2386   2387       bDlidx = (val & 0x0001);
  2387   2388     }
  2388   2389     p->rc = sqlite3_reset(pIdxSelect);
         2390  +  sqlite3_bind_null(pIdxSelect, 2);
  2389   2391   
  2390   2392     if( iPg<pSeg->pgnoFirst ){
  2391   2393       iPg = pSeg->pgnoFirst;
  2392   2394       bDlidx = 0;
  2393   2395     }
  2394   2396   
  2395   2397     pIter->iLeafPgno = iPg - 1;
................................................................................
  3594   3596           sqlite3_stmt *pIdxSelect = fts5IdxSelectStmt(p);
  3595   3597           if( p->rc==SQLITE_OK ){
  3596   3598             u8 aBlob[2] = {0xff, 0xff};
  3597   3599             sqlite3_bind_int(pIdxSelect, 1, iSegid);
  3598   3600             sqlite3_bind_blob(pIdxSelect, 2, aBlob, 2, SQLITE_STATIC);
  3599   3601             assert( sqlite3_step(pIdxSelect)!=SQLITE_ROW );
  3600   3602             p->rc = sqlite3_reset(pIdxSelect);
         3603  +          sqlite3_bind_null(pIdxSelect, 2);
  3601   3604           }
  3602   3605         }
  3603   3606   #endif
  3604   3607       }
  3605   3608     }
  3606   3609   
  3607   3610     return iSegid;
................................................................................
  3720   3723       const char *z = (pWriter->btterm.n>0?(const char*)pWriter->btterm.p:"");
  3721   3724       /* The following was already done in fts5WriteInit(): */
  3722   3725       /* sqlite3_bind_int(p->pIdxWriter, 1, pWriter->iSegid); */
  3723   3726       sqlite3_bind_blob(p->pIdxWriter, 2, z, pWriter->btterm.n, SQLITE_STATIC);
  3724   3727       sqlite3_bind_int64(p->pIdxWriter, 3, bFlag + ((i64)pWriter->iBtPage<<1));
  3725   3728       sqlite3_step(p->pIdxWriter);
  3726   3729       p->rc = sqlite3_reset(p->pIdxWriter);
         3730  +    sqlite3_bind_null(p->pIdxWriter, 2);
  3727   3731     }
  3728   3732     pWriter->iBtPage = 0;
  3729   3733   }
  3730   3734   
  3731   3735   /*
  3732   3736   ** This is called once for each leaf page except the first that contains
  3733   3737   ** at least one term. Argument (nTerm/pTerm) is the split-key - a term that
................................................................................
  4905   4909     if( p2->n ){
  4906   4910       i64 iLastRowid = 0;
  4907   4911       Fts5DoclistIter i1;
  4908   4912       Fts5DoclistIter i2;
  4909   4913       Fts5Buffer out = {0, 0, 0};
  4910   4914       Fts5Buffer tmp = {0, 0, 0};
  4911   4915   
  4912         -    if( sqlite3Fts5BufferSize(&p->rc, &out, p1->n + p2->n) ) return;
         4916  +    /* The maximum size of the output is equal to the sum of the two 
         4917  +    ** input sizes + 1 varint (9 bytes). The extra varint is because if the
         4918  +    ** first rowid in one input is a large negative number, and the first in
         4919  +    ** the other a non-negative number, the delta for the non-negative
         4920  +    ** number will be larger on disk than the literal integer value
         4921  +    ** was.  */
         4922  +    if( sqlite3Fts5BufferSize(&p->rc, &out, p1->n + p2->n + 9) ) return;
  4913   4923       fts5DoclistIterInit(p1, &i1);
  4914   4924       fts5DoclistIterInit(p2, &i2);
  4915   4925   
  4916   4926       while( 1 ){
  4917   4927         if( i1.iRowid<i2.iRowid ){
  4918   4928           /* Copy entry from i1 */
  4919   4929           fts5MergeAppendDocid(&out, iLastRowid, i1.iRowid);
................................................................................
  4999   5009         fts5MergeAppendDocid(&out, iLastRowid, i1.iRowid);
  5000   5010         fts5BufferSafeAppendBlob(&out, i1.aPoslist, i1.aEof - i1.aPoslist);
  5001   5011       }
  5002   5012       else if( i2.aPoslist ){
  5003   5013         fts5MergeAppendDocid(&out, iLastRowid, i2.iRowid);
  5004   5014         fts5BufferSafeAppendBlob(&out, i2.aPoslist, i2.aEof - i2.aPoslist);
  5005   5015       }
         5016  +    assert( out.n<=(p1->n+p2->n+9) );
  5006   5017   
  5007   5018       fts5BufferSet(&p->rc, p1, out.n, out.p);
  5008   5019       fts5BufferFree(&tmp);
  5009   5020       fts5BufferFree(&out);
  5010   5021     }
  5011   5022   }
  5012   5023   
................................................................................
  5246   5257     int nChar
  5247   5258   ){
  5248   5259     int n = 0;
  5249   5260     int i;
  5250   5261     for(i=0; i<nChar; i++){
  5251   5262       if( n>=nByte ) return 0;      /* Input contains fewer than nChar chars */
  5252   5263       if( (unsigned char)p[n++]>=0xc0 ){
  5253         -      while( (p[n] & 0xc0)==0x80 ) n++;
         5264  +      while( (p[n] & 0xc0)==0x80 ){
         5265  +        n++;
         5266  +        if( n>=nByte ) break;
         5267  +      }
  5254   5268       }
  5255   5269     }
  5256   5270     return n;
  5257   5271   }
  5258   5272   
  5259   5273   /*
  5260   5274   ** pIn is a UTF-8 encoded string, nIn bytes in size. Return the number of

Changes to ext/fts5/fts5_main.c.

   276    276         assert( p->ts.eState==1 || p->ts.eState==2 || p->ts.eState==0 );
   277    277         p->ts.eState = 0;
   278    278         break;
   279    279   
   280    280       case FTS5_SAVEPOINT:
   281    281         assert( p->ts.eState==1 );
   282    282         assert( iSavepoint>=0 );
   283         -      assert( iSavepoint>p->ts.iSavepoint );
          283  +      assert( iSavepoint>=p->ts.iSavepoint );
   284    284         p->ts.iSavepoint = iSavepoint;
   285    285         break;
   286    286         
   287    287       case FTS5_RELEASE:
   288    288         assert( p->ts.eState==1 );
   289    289         assert( iSavepoint>=0 );
   290    290         assert( iSavepoint<=p->ts.iSavepoint );
................................................................................
   530    530                                       FTS5_BI_ROWID_GE, 0, 0, -1},
   531    531     };
   532    532   
   533    533     int aColMap[3];
   534    534     aColMap[0] = -1;
   535    535     aColMap[1] = nCol;
   536    536     aColMap[2] = nCol+1;
          537  +
          538  +  assert( SQLITE_INDEX_CONSTRAINT_EQ<SQLITE_INDEX_CONSTRAINT_MATCH );
          539  +  assert( SQLITE_INDEX_CONSTRAINT_GT<SQLITE_INDEX_CONSTRAINT_MATCH );
          540  +  assert( SQLITE_INDEX_CONSTRAINT_LE<SQLITE_INDEX_CONSTRAINT_MATCH );
          541  +  assert( SQLITE_INDEX_CONSTRAINT_GE<SQLITE_INDEX_CONSTRAINT_MATCH );
          542  +  assert( SQLITE_INDEX_CONSTRAINT_LE<SQLITE_INDEX_CONSTRAINT_MATCH );
   537    543   
   538    544     /* Set idxFlags flags for all WHERE clause terms that will be used. */
   539    545     for(i=0; i<pInfo->nConstraint; i++){
   540    546       struct sqlite3_index_constraint *p = &pInfo->aConstraint[i];
   541    547       int iCol = p->iColumn;
   542    548   
   543    549       if( (p->op==SQLITE_INDEX_CONSTRAINT_MATCH && iCol>=0 && iCol<=nCol)
................................................................................
   549    555           aConstraint[0].iConsIndex = i;
   550    556         }else{
   551    557           /* As there exists an unusable MATCH constraint this is an 
   552    558           ** unusable plan. Set a prohibitively high cost. */
   553    559           pInfo->estimatedCost = 1e50;
   554    560           return SQLITE_OK;
   555    561         }
   556         -    }else{
          562  +    }else if( p->op<=SQLITE_INDEX_CONSTRAINT_MATCH ){
   557    563         int j;
   558    564         for(j=1; j<ArraySize(aConstraint); j++){
   559    565           struct Constraint *pC = &aConstraint[j];
   560         -        if( iCol==aColMap[pC->iCol] && p->op & pC->op && p->usable ){
          566  +        if( iCol==aColMap[pC->iCol] && (p->op & pC->op) && p->usable ){
   561    567             pC->iConsIndex = i;
   562    568             idxFlags |= pC->fts5op;
   563    569           }
   564    570         }
   565    571       }
   566    572     }
   567    573   
................................................................................
  1195   1201       ** return results to the user for this query. The current cursor 
  1196   1202       ** (pCursor) is used to execute the query issued by function 
  1197   1203       ** fts5CursorFirstSorted() above.  */
  1198   1204       assert( pRowidEq==0 && pRowidLe==0 && pRowidGe==0 && pRank==0 );
  1199   1205       assert( nVal==0 && pMatch==0 && bOrderByRank==0 && bDesc==0 );
  1200   1206       assert( pCsr->iLastRowid==LARGEST_INT64 );
  1201   1207       assert( pCsr->iFirstRowid==SMALLEST_INT64 );
         1208  +    if( pTab->pSortCsr->bDesc ){
         1209  +      pCsr->iLastRowid = pTab->pSortCsr->iFirstRowid;
         1210  +      pCsr->iFirstRowid = pTab->pSortCsr->iLastRowid;
         1211  +    }else{
         1212  +      pCsr->iLastRowid = pTab->pSortCsr->iLastRowid;
         1213  +      pCsr->iFirstRowid = pTab->pSortCsr->iFirstRowid;
         1214  +    }
  1202   1215       pCsr->ePlan = FTS5_PLAN_SOURCE;
  1203   1216       pCsr->pExpr = pTab->pSortCsr->pExpr;
  1204   1217       rc = fts5CursorFirst(pTab, pCsr, bDesc);
  1205   1218     }else if( pMatch ){
  1206   1219       const char *zExpr = (const char*)sqlite3_value_text(apVal[0]);
  1207   1220       if( zExpr==0 ) zExpr = "";
  1208   1221   

Changes to ext/fts5/fts5_storage.c.

   454    454       sqlite3_stmt *pReplace = 0;
   455    455       rc = fts5StorageGetStmt(p, FTS5_STMT_REPLACE_DOCSIZE, &pReplace, 0);
   456    456       if( rc==SQLITE_OK ){
   457    457         sqlite3_bind_int64(pReplace, 1, iRowid);
   458    458         sqlite3_bind_blob(pReplace, 2, pBuf->p, pBuf->n, SQLITE_STATIC);
   459    459         sqlite3_step(pReplace);
   460    460         rc = sqlite3_reset(pReplace);
          461  +      sqlite3_bind_null(pReplace, 2);
   461    462       }
   462    463     }
   463    464     return rc;
   464    465   }
   465    466   
   466    467   /*
   467    468   ** Load the contents of the "averages" record from disk into the 
................................................................................
  1114   1115       if( pVal ){
  1115   1116         sqlite3_bind_value(pReplace, 2, pVal);
  1116   1117       }else{
  1117   1118         sqlite3_bind_int(pReplace, 2, iVal);
  1118   1119       }
  1119   1120       sqlite3_step(pReplace);
  1120   1121       rc = sqlite3_reset(pReplace);
         1122  +    sqlite3_bind_null(pReplace, 1);
  1121   1123     }
  1122   1124     if( rc==SQLITE_OK && pVal ){
  1123   1125       int iNew = p->pConfig->iCookie + 1;
  1124   1126       rc = sqlite3Fts5IndexSetCookie(p->pIndex, iNew);
  1125   1127       if( rc==SQLITE_OK ){
  1126   1128         p->pConfig->iCookie = iNew;
  1127   1129       }
  1128   1130     }
  1129   1131     return rc;
  1130   1132   }

Changes to ext/fts5/fts5_tcl.c.

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

Changes to ext/fts5/fts5_tokenize.c.

   233    233   struct Unicode61Tokenizer {
   234    234     unsigned char aTokenChar[128];  /* ASCII range token characters */
   235    235     char *aFold;                    /* Buffer to fold text into */
   236    236     int nFold;                      /* Size of aFold[] in bytes */
   237    237     int bRemoveDiacritic;           /* True if remove_diacritics=1 is set */
   238    238     int nException;
   239    239     int *aiException;
          240  +
          241  +  unsigned char aCategory[32];    /* True for token char categories */
   240    242   };
   241    243   
   242    244   static int fts5UnicodeAddExceptions(
   243    245     Unicode61Tokenizer *p,          /* Tokenizer object */
   244    246     const char *z,                  /* Characters to treat as exceptions */
   245    247     int bTokenChars                 /* 1 for 'tokenchars', 0 for 'separators' */
   246    248   ){
................................................................................
   257    259         while( zCsr<zTerm ){
   258    260           int iCode;
   259    261           int bToken;
   260    262           READ_UTF8(zCsr, zTerm, iCode);
   261    263           if( iCode<128 ){
   262    264             p->aTokenChar[iCode] = (unsigned char)bTokenChars;
   263    265           }else{
   264         -          bToken = sqlite3Fts5UnicodeIsalnum(iCode);
          266  +          bToken = p->aCategory[sqlite3Fts5UnicodeCategory(iCode)];
   265    267             assert( (bToken==0 || bToken==1) ); 
   266    268             assert( (bTokenChars==0 || bTokenChars==1) );
   267    269             if( bToken!=bTokenChars && sqlite3Fts5UnicodeIsdiacritic(iCode)==0 ){
   268    270               int i;
   269    271               for(i=0; i<nNew; i++){
   270    272                 if( aNew[i]>iCode ) break;
   271    273               }
................................................................................
   317    319       Unicode61Tokenizer *p = (Unicode61Tokenizer*)pTok;
   318    320       sqlite3_free(p->aiException);
   319    321       sqlite3_free(p->aFold);
   320    322       sqlite3_free(p);
   321    323     }
   322    324     return;
   323    325   }
          326  +
          327  +static int unicodeSetCategories(Unicode61Tokenizer *p, const char *zCat){
          328  +  const char *z = zCat;
          329  +
          330  +  while( *z ){
          331  +    while( *z==' ' || *z=='\t' ) z++;
          332  +    if( *z && sqlite3Fts5UnicodeCatParse(z, p->aCategory) ){
          333  +      return SQLITE_ERROR;
          334  +    }
          335  +    while( *z!=' ' && *z!='\t' && *z!='\0' ) z++;
          336  +  }
          337  +
          338  +  sqlite3Fts5UnicodeAscii(p->aCategory, p->aTokenChar);
          339  +  return SQLITE_OK;
          340  +}
   324    341   
   325    342   /*
   326    343   ** Create a "unicode61" tokenizer.
   327    344   */
   328    345   static int fts5UnicodeCreate(
   329    346     void *pUnused, 
   330    347     const char **azArg, int nArg,
................................................................................
   336    353     UNUSED_PARAM(pUnused);
   337    354   
   338    355     if( nArg%2 ){
   339    356       rc = SQLITE_ERROR;
   340    357     }else{
   341    358       p = (Unicode61Tokenizer*)sqlite3_malloc(sizeof(Unicode61Tokenizer));
   342    359       if( p ){
          360  +      const char *zCat = "L* N* Co";
   343    361         int i;
   344    362         memset(p, 0, sizeof(Unicode61Tokenizer));
   345         -      memcpy(p->aTokenChar, aAsciiTokenChar, sizeof(aAsciiTokenChar));
          363  +
   346    364         p->bRemoveDiacritic = 1;
   347    365         p->nFold = 64;
   348    366         p->aFold = sqlite3_malloc(p->nFold * sizeof(char));
   349    367         if( p->aFold==0 ){
   350    368           rc = SQLITE_NOMEM;
   351    369         }
          370  +
          371  +      /* Search for a "categories" argument */
          372  +      for(i=0; rc==SQLITE_OK && i<nArg; i+=2){
          373  +        if( 0==sqlite3_stricmp(azArg[i], "categories") ){
          374  +          zCat = azArg[i+1];
          375  +        }
          376  +      }
          377  +
          378  +      if( rc==SQLITE_OK ){
          379  +        rc = unicodeSetCategories(p, zCat);
          380  +      }
          381  +
   352    382         for(i=0; rc==SQLITE_OK && i<nArg; i+=2){
   353    383           const char *zArg = azArg[i+1];
   354    384           if( 0==sqlite3_stricmp(azArg[i], "remove_diacritics") ){
   355    385             if( (zArg[0]!='0' && zArg[0]!='1') || zArg[1] ){
   356    386               rc = SQLITE_ERROR;
   357    387             }
   358    388             p->bRemoveDiacritic = (zArg[0]=='1');
   359    389           }else
   360    390           if( 0==sqlite3_stricmp(azArg[i], "tokenchars") ){
   361    391             rc = fts5UnicodeAddExceptions(p, zArg, 1);
   362    392           }else
   363    393           if( 0==sqlite3_stricmp(azArg[i], "separators") ){
   364    394             rc = fts5UnicodeAddExceptions(p, zArg, 0);
          395  +        }else
          396  +        if( 0==sqlite3_stricmp(azArg[i], "categories") ){
          397  +          /* no-op */
   365    398           }else{
   366    399             rc = SQLITE_ERROR;
   367    400           }
   368    401         }
          402  +
   369    403       }else{
   370    404         rc = SQLITE_NOMEM;
   371    405       }
   372    406       if( rc!=SQLITE_OK ){
   373    407         fts5UnicodeDelete((Fts5Tokenizer*)p);
   374    408         p = 0;
   375    409       }
................................................................................
   380    414   
   381    415   /*
   382    416   ** Return true if, for the purposes of tokenizing with the tokenizer
   383    417   ** passed as the first argument, codepoint iCode is considered a token 
   384    418   ** character (not a separator).
   385    419   */
   386    420   static int fts5UnicodeIsAlnum(Unicode61Tokenizer *p, int iCode){
   387         -  assert( (sqlite3Fts5UnicodeIsalnum(iCode) & 0xFFFFFFFE)==0 );
   388         -  return sqlite3Fts5UnicodeIsalnum(iCode) ^ fts5UnicodeIsException(p, iCode);
          421  +  return (
          422  +    p->aCategory[sqlite3Fts5UnicodeCategory(iCode)]
          423  +    ^ fts5UnicodeIsException(p, iCode)
          424  +  );
   389    425   }
   390    426   
   391    427   static int fts5UnicodeTokenize(
   392    428     Fts5Tokenizer *pTokenizer,
   393    429     void *pCtx,
   394    430     int iUnused,
   395    431     const char *pText, int nText,

Changes to ext/fts5/fts5_unicode2.c.

    14     14   /*
    15     15   ** DO NOT EDIT THIS MACHINE GENERATED FILE.
    16     16   */
    17     17   
    18     18   
    19     19   #include <assert.h>
    20     20   
    21         -/*
    22         -** Return true if the argument corresponds to a unicode codepoint
    23         -** classified as either a letter or a number. Otherwise false.
    24         -**
    25         -** The results are undefined if the value passed to this function
    26         -** is less than zero.
    27         -*/
    28         -int sqlite3Fts5UnicodeIsalnum(int c){
    29         -  /* Each unsigned integer in the following array corresponds to a contiguous
    30         -  ** range of unicode codepoints that are not either letters or numbers (i.e.
    31         -  ** codepoints for which this function should return 0).
    32         -  **
    33         -  ** The most significant 22 bits in each 32-bit value contain the first 
    34         -  ** codepoint in the range. The least significant 10 bits are used to store
    35         -  ** the size of the range (always at least 1). In other words, the value 
    36         -  ** ((C<<22) + N) represents a range of N codepoints starting with codepoint 
    37         -  ** C. It is not possible to represent a range larger than 1023 codepoints 
    38         -  ** using this format.
    39         -  */
    40         -  static const unsigned int aEntry[] = {
    41         -    0x00000030, 0x0000E807, 0x00016C06, 0x0001EC2F, 0x0002AC07,
    42         -    0x0002D001, 0x0002D803, 0x0002EC01, 0x0002FC01, 0x00035C01,
    43         -    0x0003DC01, 0x000B0804, 0x000B480E, 0x000B9407, 0x000BB401,
    44         -    0x000BBC81, 0x000DD401, 0x000DF801, 0x000E1002, 0x000E1C01,
    45         -    0x000FD801, 0x00120808, 0x00156806, 0x00162402, 0x00163C01,
    46         -    0x00164437, 0x0017CC02, 0x00180005, 0x00181816, 0x00187802,
    47         -    0x00192C15, 0x0019A804, 0x0019C001, 0x001B5001, 0x001B580F,
    48         -    0x001B9C07, 0x001BF402, 0x001C000E, 0x001C3C01, 0x001C4401,
    49         -    0x001CC01B, 0x001E980B, 0x001FAC09, 0x001FD804, 0x00205804,
    50         -    0x00206C09, 0x00209403, 0x0020A405, 0x0020C00F, 0x00216403,
    51         -    0x00217801, 0x0023901B, 0x00240004, 0x0024E803, 0x0024F812,
    52         -    0x00254407, 0x00258804, 0x0025C001, 0x00260403, 0x0026F001,
    53         -    0x0026F807, 0x00271C02, 0x00272C03, 0x00275C01, 0x00278802,
    54         -    0x0027C802, 0x0027E802, 0x00280403, 0x0028F001, 0x0028F805,
    55         -    0x00291C02, 0x00292C03, 0x00294401, 0x0029C002, 0x0029D401,
    56         -    0x002A0403, 0x002AF001, 0x002AF808, 0x002B1C03, 0x002B2C03,
    57         -    0x002B8802, 0x002BC002, 0x002C0403, 0x002CF001, 0x002CF807,
    58         -    0x002D1C02, 0x002D2C03, 0x002D5802, 0x002D8802, 0x002DC001,
    59         -    0x002E0801, 0x002EF805, 0x002F1803, 0x002F2804, 0x002F5C01,
    60         -    0x002FCC08, 0x00300403, 0x0030F807, 0x00311803, 0x00312804,
    61         -    0x00315402, 0x00318802, 0x0031FC01, 0x00320802, 0x0032F001,
    62         -    0x0032F807, 0x00331803, 0x00332804, 0x00335402, 0x00338802,
    63         -    0x00340802, 0x0034F807, 0x00351803, 0x00352804, 0x00355C01,
    64         -    0x00358802, 0x0035E401, 0x00360802, 0x00372801, 0x00373C06,
    65         -    0x00375801, 0x00376008, 0x0037C803, 0x0038C401, 0x0038D007,
    66         -    0x0038FC01, 0x00391C09, 0x00396802, 0x003AC401, 0x003AD006,
    67         -    0x003AEC02, 0x003B2006, 0x003C041F, 0x003CD00C, 0x003DC417,
    68         -    0x003E340B, 0x003E6424, 0x003EF80F, 0x003F380D, 0x0040AC14,
    69         -    0x00412806, 0x00415804, 0x00417803, 0x00418803, 0x00419C07,
    70         -    0x0041C404, 0x0042080C, 0x00423C01, 0x00426806, 0x0043EC01,
    71         -    0x004D740C, 0x004E400A, 0x00500001, 0x0059B402, 0x005A0001,
    72         -    0x005A6C02, 0x005BAC03, 0x005C4803, 0x005CC805, 0x005D4802,
    73         -    0x005DC802, 0x005ED023, 0x005F6004, 0x005F7401, 0x0060000F,
    74         -    0x0062A401, 0x0064800C, 0x0064C00C, 0x00650001, 0x00651002,
    75         -    0x0066C011, 0x00672002, 0x00677822, 0x00685C05, 0x00687802,
    76         -    0x0069540A, 0x0069801D, 0x0069FC01, 0x006A8007, 0x006AA006,
    77         -    0x006C0005, 0x006CD011, 0x006D6823, 0x006E0003, 0x006E840D,
    78         -    0x006F980E, 0x006FF004, 0x00709014, 0x0070EC05, 0x0071F802,
    79         -    0x00730008, 0x00734019, 0x0073B401, 0x0073C803, 0x00770027,
    80         -    0x0077F004, 0x007EF401, 0x007EFC03, 0x007F3403, 0x007F7403,
    81         -    0x007FB403, 0x007FF402, 0x00800065, 0x0081A806, 0x0081E805,
    82         -    0x00822805, 0x0082801A, 0x00834021, 0x00840002, 0x00840C04,
    83         -    0x00842002, 0x00845001, 0x00845803, 0x00847806, 0x00849401,
    84         -    0x00849C01, 0x0084A401, 0x0084B801, 0x0084E802, 0x00850005,
    85         -    0x00852804, 0x00853C01, 0x00864264, 0x00900027, 0x0091000B,
    86         -    0x0092704E, 0x00940200, 0x009C0475, 0x009E53B9, 0x00AD400A,
    87         -    0x00B39406, 0x00B3BC03, 0x00B3E404, 0x00B3F802, 0x00B5C001,
    88         -    0x00B5FC01, 0x00B7804F, 0x00B8C00C, 0x00BA001A, 0x00BA6C59,
    89         -    0x00BC00D6, 0x00BFC00C, 0x00C00005, 0x00C02019, 0x00C0A807,
    90         -    0x00C0D802, 0x00C0F403, 0x00C26404, 0x00C28001, 0x00C3EC01,
    91         -    0x00C64002, 0x00C6580A, 0x00C70024, 0x00C8001F, 0x00C8A81E,
    92         -    0x00C94001, 0x00C98020, 0x00CA2827, 0x00CB003F, 0x00CC0100,
    93         -    0x01370040, 0x02924037, 0x0293F802, 0x02983403, 0x0299BC10,
    94         -    0x029A7C01, 0x029BC008, 0x029C0017, 0x029C8002, 0x029E2402,
    95         -    0x02A00801, 0x02A01801, 0x02A02C01, 0x02A08C09, 0x02A0D804,
    96         -    0x02A1D004, 0x02A20002, 0x02A2D011, 0x02A33802, 0x02A38012,
    97         -    0x02A3E003, 0x02A4980A, 0x02A51C0D, 0x02A57C01, 0x02A60004,
    98         -    0x02A6CC1B, 0x02A77802, 0x02A8A40E, 0x02A90C01, 0x02A93002,
    99         -    0x02A97004, 0x02A9DC03, 0x02A9EC01, 0x02AAC001, 0x02AAC803,
   100         -    0x02AADC02, 0x02AAF802, 0x02AB0401, 0x02AB7802, 0x02ABAC07,
   101         -    0x02ABD402, 0x02AF8C0B, 0x03600001, 0x036DFC02, 0x036FFC02,
   102         -    0x037FFC01, 0x03EC7801, 0x03ECA401, 0x03EEC810, 0x03F4F802,
   103         -    0x03F7F002, 0x03F8001A, 0x03F88007, 0x03F8C023, 0x03F95013,
   104         -    0x03F9A004, 0x03FBFC01, 0x03FC040F, 0x03FC6807, 0x03FCEC06,
   105         -    0x03FD6C0B, 0x03FF8007, 0x03FFA007, 0x03FFE405, 0x04040003,
   106         -    0x0404DC09, 0x0405E411, 0x0406400C, 0x0407402E, 0x040E7C01,
   107         -    0x040F4001, 0x04215C01, 0x04247C01, 0x0424FC01, 0x04280403,
   108         -    0x04281402, 0x04283004, 0x0428E003, 0x0428FC01, 0x04294009,
   109         -    0x0429FC01, 0x042CE407, 0x04400003, 0x0440E016, 0x04420003,
   110         -    0x0442C012, 0x04440003, 0x04449C0E, 0x04450004, 0x04460003,
   111         -    0x0446CC0E, 0x04471404, 0x045AAC0D, 0x0491C004, 0x05BD442E,
   112         -    0x05BE3C04, 0x074000F6, 0x07440027, 0x0744A4B5, 0x07480046,
   113         -    0x074C0057, 0x075B0401, 0x075B6C01, 0x075BEC01, 0x075C5401,
   114         -    0x075CD401, 0x075D3C01, 0x075DBC01, 0x075E2401, 0x075EA401,
   115         -    0x075F0C01, 0x07BBC002, 0x07C0002C, 0x07C0C064, 0x07C2800F,
   116         -    0x07C2C40E, 0x07C3040F, 0x07C3440F, 0x07C4401F, 0x07C4C03C,
   117         -    0x07C5C02B, 0x07C7981D, 0x07C8402B, 0x07C90009, 0x07C94002,
   118         -    0x07CC0021, 0x07CCC006, 0x07CCDC46, 0x07CE0014, 0x07CE8025,
   119         -    0x07CF1805, 0x07CF8011, 0x07D0003F, 0x07D10001, 0x07D108B6,
   120         -    0x07D3E404, 0x07D4003E, 0x07D50004, 0x07D54018, 0x07D7EC46,
   121         -    0x07D9140B, 0x07DA0046, 0x07DC0074, 0x38000401, 0x38008060,
   122         -    0x380400F0,
   123         -  };
   124         -  static const unsigned int aAscii[4] = {
   125         -    0xFFFFFFFF, 0xFC00FFFF, 0xF8000001, 0xF8000001,
   126         -  };
   127         -
   128         -  if( (unsigned int)c<128 ){
   129         -    return ( (aAscii[c >> 5] & (1 << (c & 0x001F)))==0 );
   130         -  }else if( (unsigned int)c<(1<<22) ){
   131         -    unsigned int key = (((unsigned int)c)<<10) | 0x000003FF;
   132         -    int iRes = 0;
   133         -    int iHi = sizeof(aEntry)/sizeof(aEntry[0]) - 1;
   134         -    int iLo = 0;
   135         -    while( iHi>=iLo ){
   136         -      int iTest = (iHi + iLo) / 2;
   137         -      if( key >= aEntry[iTest] ){
   138         -        iRes = iTest;
   139         -        iLo = iTest+1;
   140         -      }else{
   141         -        iHi = iTest-1;
   142         -      }
   143         -    }
   144         -    assert( aEntry[0]<key );
   145         -    assert( key>=aEntry[iRes] );
   146         -    return (((unsigned int)c) >= ((aEntry[iRes]>>10) + (aEntry[iRes]&0x3FF)));
   147         -  }
   148         -  return 1;
   149         -}
   150     21   
   151     22   
   152     23   /*
   153     24   ** If the argument is a codepoint corresponding to a lowercase letter
   154     25   ** in the ASCII range with a diacritic added, return the codepoint
   155     26   ** of the ASCII letter only. For example, if passed 235 - "LATIN
   156     27   ** SMALL LETTER E WITH DIAERESIS" - return 65 ("LATIN SMALL LETTER
................................................................................
   354    225     
   355    226     else if( c>=66560 && c<66600 ){
   356    227       ret = c + 40;
   357    228     }
   358    229   
   359    230     return ret;
   360    231   }
          232  +
          233  +
          234  +#if 0
          235  +int sqlite3Fts5UnicodeNCat(void) { 
          236  +  return 32;
          237  +}
          238  +#endif
          239  +
          240  +int sqlite3Fts5UnicodeCatParse(const char *zCat, u8 *aArray){ 
          241  +  aArray[0] = 1;
          242  +  switch( zCat[0] ){
          243  +    case 'C':
          244  +          switch( zCat[1] ){
          245  +            case 'c': aArray[1] = 1; break;
          246  +            case 'f': aArray[2] = 1; break;
          247  +            case 'n': aArray[3] = 1; break;
          248  +            case 's': aArray[4] = 1; break;
          249  +            case 'o': aArray[31] = 1; break;
          250  +            case '*': 
          251  +              aArray[1] = 1;
          252  +              aArray[2] = 1;
          253  +              aArray[3] = 1;
          254  +              aArray[4] = 1;
          255  +              aArray[31] = 1;
          256  +              break;
          257  +            default: return 1;          }
          258  +          break;
          259  +
          260  +    case 'L':
          261  +          switch( zCat[1] ){
          262  +            case 'l': aArray[5] = 1; break;
          263  +            case 'm': aArray[6] = 1; break;
          264  +            case 'o': aArray[7] = 1; break;
          265  +            case 't': aArray[8] = 1; break;
          266  +            case 'u': aArray[9] = 1; break;
          267  +            case 'C': aArray[30] = 1; break;
          268  +            case '*': 
          269  +              aArray[5] = 1;
          270  +              aArray[6] = 1;
          271  +              aArray[7] = 1;
          272  +              aArray[8] = 1;
          273  +              aArray[9] = 1;
          274  +              aArray[30] = 1;
          275  +              break;
          276  +            default: return 1;          }
          277  +          break;
          278  +
          279  +    case 'M':
          280  +          switch( zCat[1] ){
          281  +            case 'c': aArray[10] = 1; break;
          282  +            case 'e': aArray[11] = 1; break;
          283  +            case 'n': aArray[12] = 1; break;
          284  +            case '*': 
          285  +              aArray[10] = 1;
          286  +              aArray[11] = 1;
          287  +              aArray[12] = 1;
          288  +              break;
          289  +            default: return 1;          }
          290  +          break;
          291  +
          292  +    case 'N':
          293  +          switch( zCat[1] ){
          294  +            case 'd': aArray[13] = 1; break;
          295  +            case 'l': aArray[14] = 1; break;
          296  +            case 'o': aArray[15] = 1; break;
          297  +            case '*': 
          298  +              aArray[13] = 1;
          299  +              aArray[14] = 1;
          300  +              aArray[15] = 1;
          301  +              break;
          302  +            default: return 1;          }
          303  +          break;
          304  +
          305  +    case 'P':
          306  +          switch( zCat[1] ){
          307  +            case 'c': aArray[16] = 1; break;
          308  +            case 'd': aArray[17] = 1; break;
          309  +            case 'e': aArray[18] = 1; break;
          310  +            case 'f': aArray[19] = 1; break;
          311  +            case 'i': aArray[20] = 1; break;
          312  +            case 'o': aArray[21] = 1; break;
          313  +            case 's': aArray[22] = 1; break;
          314  +            case '*': 
          315  +              aArray[16] = 1;
          316  +              aArray[17] = 1;
          317  +              aArray[18] = 1;
          318  +              aArray[19] = 1;
          319  +              aArray[20] = 1;
          320  +              aArray[21] = 1;
          321  +              aArray[22] = 1;
          322  +              break;
          323  +            default: return 1;          }
          324  +          break;
          325  +
          326  +    case 'S':
          327  +          switch( zCat[1] ){
          328  +            case 'c': aArray[23] = 1; break;
          329  +            case 'k': aArray[24] = 1; break;
          330  +            case 'm': aArray[25] = 1; break;
          331  +            case 'o': aArray[26] = 1; break;
          332  +            case '*': 
          333  +              aArray[23] = 1;
          334  +              aArray[24] = 1;
          335  +              aArray[25] = 1;
          336  +              aArray[26] = 1;
          337  +              break;
          338  +            default: return 1;          }
          339  +          break;
          340  +
          341  +    case 'Z':
          342  +          switch( zCat[1] ){
          343  +            case 'l': aArray[27] = 1; break;
          344  +            case 'p': aArray[28] = 1; break;
          345  +            case 's': aArray[29] = 1; break;
          346  +            case '*': 
          347  +              aArray[27] = 1;
          348  +              aArray[28] = 1;
          349  +              aArray[29] = 1;
          350  +              break;
          351  +            default: return 1;          }
          352  +          break;
          353  +
          354  +  }
          355  +  return 0;
          356  +}
          357  +
          358  +static u16 aFts5UnicodeBlock[] = {
          359  +    0,     1471,  1753,  1760,  1760,  1760,  1760,  1760,  1760,  1760,  
          360  +    1760,  1760,  1760,  1760,  1760,  1763,  1765,  
          361  +  };
          362  +static u16 aFts5UnicodeMap[] = {
          363  +    0,     32,    33,    36,    37,    40,    41,    42,    43,    44,    
          364  +    45,    46,    48,    58,    60,    63,    65,    91,    92,    93,    
          365  +    94,    95,    96,    97,    123,   124,   125,   126,   127,   160,   
          366  +    161,   162,   166,   167,   168,   169,   170,   171,   172,   173,   
          367  +    174,   175,   176,   177,   178,   180,   181,   182,   184,   185,   
          368  +    186,   187,   188,   191,   192,   215,   216,   223,   247,   248,   
          369  +    256,   312,   313,   329,   330,   377,   383,   385,   387,   388,   
          370  +    391,   394,   396,   398,   402,   403,   405,   406,   409,   412,   
          371  +    414,   415,   417,   418,   423,   427,   428,   431,   434,   436,   
          372  +    437,   440,   442,   443,   444,   446,   448,   452,   453,   454,   
          373  +    455,   456,   457,   458,   459,   460,   461,   477,   478,   496,   
          374  +    497,   498,   499,   500,   503,   505,   506,   564,   570,   572,   
          375  +    573,   575,   577,   580,   583,   584,   592,   660,   661,   688,   
          376  +    706,   710,   722,   736,   741,   748,   749,   750,   751,   768,   
          377  +    880,   884,   885,   886,   890,   891,   894,   900,   902,   903,   
          378  +    904,   908,   910,   912,   913,   931,   940,   975,   977,   978,   
          379  +    981,   984,   1008,  1012,  1014,  1015,  1018,  1020,  1021,  1072,  
          380  +    1120,  1154,  1155,  1160,  1162,  1217,  1231,  1232,  1329,  1369,  
          381  +    1370,  1377,  1417,  1418,  1423,  1425,  1470,  1471,  1472,  1473,  
          382  +    1475,  1476,  1478,  1479,  1488,  1520,  1523,  1536,  1542,  1545,  
          383  +    1547,  1548,  1550,  1552,  1563,  1566,  1568,  1600,  1601,  1611,  
          384  +    1632,  1642,  1646,  1648,  1649,  1748,  1749,  1750,  1757,  1758,  
          385  +    1759,  1765,  1767,  1769,  1770,  1774,  1776,  1786,  1789,  1791,  
          386  +    1792,  1807,  1808,  1809,  1810,  1840,  1869,  1958,  1969,  1984,  
          387  +    1994,  2027,  2036,  2038,  2039,  2042,  2048,  2070,  2074,  2075,  
          388  +    2084,  2085,  2088,  2089,  2096,  2112,  2137,  2142,  2208,  2210,  
          389  +    2276,  2304,  2307,  2308,  2362,  2363,  2364,  2365,  2366,  2369,  
          390  +    2377,  2381,  2382,  2384,  2385,  2392,  2402,  2404,  2406,  2416,  
          391  +    2417,  2418,  2425,  2433,  2434,  2437,  2447,  2451,  2474,  2482,  
          392  +    2486,  2492,  2493,  2494,  2497,  2503,  2507,  2509,  2510,  2519,  
          393  +    2524,  2527,  2530,  2534,  2544,  2546,  2548,  2554,  2555,  2561,  
          394  +    2563,  2565,  2575,  2579,  2602,  2610,  2613,  2616,  2620,  2622,  
          395  +    2625,  2631,  2635,  2641,  2649,  2654,  2662,  2672,  2674,  2677,  
          396  +    2689,  2691,  2693,  2703,  2707,  2730,  2738,  2741,  2748,  2749,  
          397  +    2750,  2753,  2759,  2761,  2763,  2765,  2768,  2784,  2786,  2790,  
          398  +    2800,  2801,  2817,  2818,  2821,  2831,  2835,  2858,  2866,  2869,  
          399  +    2876,  2877,  2878,  2879,  2880,  2881,  2887,  2891,  2893,  2902,  
          400  +    2903,  2908,  2911,  2914,  2918,  2928,  2929,  2930,  2946,  2947,  
          401  +    2949,  2958,  2962,  2969,  2972,  2974,  2979,  2984,  2990,  3006,  
          402  +    3008,  3009,  3014,  3018,  3021,  3024,  3031,  3046,  3056,  3059,  
          403  +    3065,  3066,  3073,  3077,  3086,  3090,  3114,  3125,  3133,  3134,  
          404  +    3137,  3142,  3146,  3157,  3160,  3168,  3170,  3174,  3192,  3199,  
          405  +    3202,  3205,  3214,  3218,  3242,  3253,  3260,  3261,  3262,  3263,  
          406  +    3264,  3270,  3271,  3274,  3276,  3285,  3294,  3296,  3298,  3302,  
          407  +    3313,  3330,  3333,  3342,  3346,  3389,  3390,  3393,  3398,  3402,  
          408  +    3405,  3406,  3415,  3424,  3426,  3430,  3440,  3449,  3450,  3458,  
          409  +    3461,  3482,  3507,  3517,  3520,  3530,  3535,  3538,  3542,  3544,  
          410  +    3570,  3572,  3585,  3633,  3634,  3636,  3647,  3648,  3654,  3655,  
          411  +    3663,  3664,  3674,  3713,  3716,  3719,  3722,  3725,  3732,  3737,  
          412  +    3745,  3749,  3751,  3754,  3757,  3761,  3762,  3764,  3771,  3773,  
          413  +    3776,  3782,  3784,  3792,  3804,  3840,  3841,  3844,  3859,  3860,  
          414  +    3861,  3864,  3866,  3872,  3882,  3892,  3893,  3894,  3895,  3896,  
          415  +    3897,  3898,  3899,  3900,  3901,  3902,  3904,  3913,  3953,  3967,  
          416  +    3968,  3973,  3974,  3976,  3981,  3993,  4030,  4038,  4039,  4046,  
          417  +    4048,  4053,  4057,  4096,  4139,  4141,  4145,  4146,  4152,  4153,  
          418  +    4155,  4157,  4159,  4160,  4170,  4176,  4182,  4184,  4186,  4190,  
          419  +    4193,  4194,  4197,  4199,  4206,  4209,  4213,  4226,  4227,  4229,  
          420  +    4231,  4237,  4238,  4239,  4240,  4250,  4253,  4254,  4256,  4295,  
          421  +    4301,  4304,  4347,  4348,  4349,  4682,  4688,  4696,  4698,  4704,  
          422  +    4746,  4752,  4786,  4792,  4800,  4802,  4808,  4824,  4882,  4888,  
          423  +    4957,  4960,  4969,  4992,  5008,  5024,  5120,  5121,  5741,  5743,  
          424  +    5760,  5761,  5787,  5788,  5792,  5867,  5870,  5888,  5902,  5906,  
          425  +    5920,  5938,  5941,  5952,  5970,  5984,  5998,  6002,  6016,  6068,  
          426  +    6070,  6071,  6078,  6086,  6087,  6089,  6100,  6103,  6104,  6107,  
          427  +    6108,  6109,  6112,  6128,  6144,  6150,  6151,  6155,  6158,  6160,  
          428  +    6176,  6211,  6212,  6272,  6313,  6314,  6320,  6400,  6432,  6435,  
          429  +    6439,  6441,  6448,  6450,  6451,  6457,  6464,  6468,  6470,  6480,  
          430  +    6512,  6528,  6576,  6593,  6600,  6608,  6618,  6622,  6656,  6679,  
          431  +    6681,  6686,  6688,  6741,  6742,  6743,  6744,  6752,  6753,  6754,  
          432  +    6755,  6757,  6765,  6771,  6783,  6784,  6800,  6816,  6823,  6824,  
          433  +    6912,  6916,  6917,  6964,  6965,  6966,  6971,  6972,  6973,  6978,  
          434  +    6979,  6981,  6992,  7002,  7009,  7019,  7028,  7040,  7042,  7043,  
          435  +    7073,  7074,  7078,  7080,  7082,  7083,  7084,  7086,  7088,  7098,  
          436  +    7142,  7143,  7144,  7146,  7149,  7150,  7151,  7154,  7164,  7168,  
          437  +    7204,  7212,  7220,  7222,  7227,  7232,  7245,  7248,  7258,  7288,  
          438  +    7294,  7360,  7376,  7379,  7380,  7393,  7394,  7401,  7405,  7406,  
          439  +    7410,  7412,  7413,  7424,  7468,  7531,  7544,  7545,  7579,  7616,  
          440  +    7676,  7680,  7830,  7838,  7936,  7944,  7952,  7960,  7968,  7976,  
          441  +    7984,  7992,  8000,  8008,  8016,  8025,  8027,  8029,  8031,  8033,  
          442  +    8040,  8048,  8064,  8072,  8080,  8088,  8096,  8104,  8112,  8118,  
          443  +    8120,  8124,  8125,  8126,  8127,  8130,  8134,  8136,  8140,  8141,  
          444  +    8144,  8150,  8152,  8157,  8160,  8168,  8173,  8178,  8182,  8184,  
          445  +    8188,  8189,  8192,  8203,  8208,  8214,  8216,  8217,  8218,  8219,  
          446  +    8221,  8222,  8223,  8224,  8232,  8233,  8234,  8239,  8240,  8249,  
          447  +    8250,  8251,  8255,  8257,  8260,  8261,  8262,  8263,  8274,  8275,  
          448  +    8276,  8277,  8287,  8288,  8298,  8304,  8305,  8308,  8314,  8317,  
          449  +    8318,  8319,  8320,  8330,  8333,  8334,  8336,  8352,  8400,  8413,  
          450  +    8417,  8418,  8421,  8448,  8450,  8451,  8455,  8456,  8458,  8459,  
          451  +    8462,  8464,  8467,  8468,  8469,  8470,  8472,  8473,  8478,  8484,  
          452  +    8485,  8486,  8487,  8488,  8489,  8490,  8494,  8495,  8496,  8500,  
          453  +    8501,  8505,  8506,  8508,  8510,  8512,  8517,  8519,  8522,  8523,  
          454  +    8524,  8526,  8527,  8528,  8544,  8579,  8581,  8585,  8592,  8597,  
          455  +    8602,  8604,  8608,  8609,  8611,  8612,  8614,  8615,  8622,  8623,  
          456  +    8654,  8656,  8658,  8659,  8660,  8661,  8692,  8960,  8968,  8972,  
          457  +    8992,  8994,  9001,  9002,  9003,  9084,  9085,  9115,  9140,  9180,  
          458  +    9186,  9216,  9280,  9312,  9372,  9450,  9472,  9655,  9656,  9665,  
          459  +    9666,  9720,  9728,  9839,  9840,  9985,  10088, 10089, 10090, 10091, 
          460  +    10092, 10093, 10094, 10095, 10096, 10097, 10098, 10099, 10100, 10101, 
          461  +    10102, 10132, 10176, 10181, 10182, 10183, 10214, 10215, 10216, 10217, 
          462  +    10218, 10219, 10220, 10221, 10222, 10223, 10224, 10240, 10496, 10627, 
          463  +    10628, 10629, 10630, 10631, 10632, 10633, 10634, 10635, 10636, 10637, 
          464  +    10638, 10639, 10640, 10641, 10642, 10643, 10644, 10645, 10646, 10647, 
          465  +    10648, 10649, 10712, 10713, 10714, 10715, 10716, 10748, 10749, 10750, 
          466  +    11008, 11056, 11077, 11079, 11088, 11264, 11312, 11360, 11363, 11365, 
          467  +    11367, 11374, 11377, 11378, 11380, 11381, 11383, 11388, 11390, 11393, 
          468  +    11394, 11492, 11493, 11499, 11503, 11506, 11513, 11517, 11518, 11520, 
          469  +    11559, 11565, 11568, 11631, 11632, 11647, 11648, 11680, 11688, 11696, 
          470  +    11704, 11712, 11720, 11728, 11736, 11744, 11776, 11778, 11779, 11780, 
          471  +    11781, 11782, 11785, 11786, 11787, 11788, 11789, 11790, 11799, 11800, 
          472  +    11802, 11803, 11804, 11805, 11806, 11808, 11809, 11810, 11811, 11812, 
          473  +    11813, 11814, 11815, 11816, 11817, 11818, 11823, 11824, 11834, 11904, 
          474  +    11931, 12032, 12272, 12288, 12289, 12292, 12293, 12294, 12295, 12296, 
          475  +    12297, 12298, 12299, 12300, 12301, 12302, 12303, 12304, 12305, 12306, 
          476  +    12308, 12309, 12310, 12311, 12312, 12313, 12314, 12315, 12316, 12317, 
          477  +    12318, 12320, 12321, 12330, 12334, 12336, 12337, 12342, 12344, 12347, 
          478  +    12348, 12349, 12350, 12353, 12441, 12443, 12445, 12447, 12448, 12449, 
          479  +    12539, 12540, 12543, 12549, 12593, 12688, 12690, 12694, 12704, 12736, 
          480  +    12784, 12800, 12832, 12842, 12872, 12880, 12881, 12896, 12928, 12938, 
          481  +    12977, 12992, 13056, 13312, 19893, 19904, 19968, 40908, 40960, 40981, 
          482  +    40982, 42128, 42192, 42232, 42238, 42240, 42508, 42509, 42512, 42528, 
          483  +    42538, 42560, 42606, 42607, 42608, 42611, 42612, 42622, 42623, 42624, 
          484  +    42655, 42656, 42726, 42736, 42738, 42752, 42775, 42784, 42786, 42800, 
          485  +    42802, 42864, 42865, 42873, 42878, 42888, 42889, 42891, 42896, 42912, 
          486  +    43000, 43002, 43003, 43010, 43011, 43014, 43015, 43019, 43020, 43043, 
          487  +    43045, 43047, 43048, 43056, 43062, 43064, 43065, 43072, 43124, 43136, 
          488  +    43138, 43188, 43204, 43214, 43216, 43232, 43250, 43256, 43259, 43264, 
          489  +    43274, 43302, 43310, 43312, 43335, 43346, 43359, 43360, 43392, 43395, 
          490  +    43396, 43443, 43444, 43446, 43450, 43452, 43453, 43457, 43471, 43472, 
          491  +    43486, 43520, 43561, 43567, 43569, 43571, 43573, 43584, 43587, 43588, 
          492  +    43596, 43597, 43600, 43612, 43616, 43632, 43633, 43639, 43642, 43643, 
          493  +    43648, 43696, 43697, 43698, 43701, 43703, 43705, 43710, 43712, 43713, 
          494  +    43714, 43739, 43741, 43742, 43744, 43755, 43756, 43758, 43760, 43762, 
          495  +    43763, 43765, 43766, 43777, 43785, 43793, 43808, 43816, 43968, 44003, 
          496  +    44005, 44006, 44008, 44009, 44011, 44012, 44013, 44016, 44032, 55203, 
          497  +    55216, 55243, 55296, 56191, 56319, 57343, 57344, 63743, 63744, 64112, 
          498  +    64256, 64275, 64285, 64286, 64287, 64297, 64298, 64312, 64318, 64320, 
          499  +    64323, 64326, 64434, 64467, 64830, 64831, 64848, 64914, 65008, 65020, 
          500  +    65021, 65024, 65040, 65047, 65048, 65049, 65056, 65072, 65073, 65075, 
          501  +    65077, 65078, 65079, 65080, 65081, 65082, 65083, 65084, 65085, 65086, 
          502  +    65087, 65088, 65089, 65090, 65091, 65092, 65093, 65095, 65096, 65097, 
          503  +    65101, 65104, 65108, 65112, 65113, 65114, 65115, 65116, 65117, 65118, 
          504  +    65119, 65122, 65123, 65124, 65128, 65129, 65130, 65136, 65142, 65279, 
          505  +    65281, 65284, 65285, 65288, 65289, 65290, 65291, 65292, 65293, 65294, 
          506  +    65296, 65306, 65308, 65311, 65313, 65339, 65340, 65341, 65342, 65343, 
          507  +    65344, 65345, 65371, 65372, 65373, 65374, 65375, 65376, 65377, 65378, 
          508  +    65379, 65380, 65382, 65392, 65393, 65438, 65440, 65474, 65482, 65490, 
          509  +    65498, 65504, 65506, 65507, 65508, 65509, 65512, 65513, 65517, 65529, 
          510  +    65532, 0,     13,    40,    60,    63,    80,    128,   256,   263,   
          511  +    311,   320,   373,   377,   394,   400,   464,   509,   640,   672,   
          512  +    768,   800,   816,   833,   834,   842,   896,   927,   928,   968,   
          513  +    976,   977,   1024,  1064,  1104,  1184,  2048,  2056,  2058,  2103,  
          514  +    2108,  2111,  2135,  2136,  2304,  2326,  2335,  2336,  2367,  2432,  
          515  +    2494,  2560,  2561,  2565,  2572,  2576,  2581,  2585,  2616,  2623,  
          516  +    2624,  2640,  2656,  2685,  2687,  2816,  2873,  2880,  2904,  2912,  
          517  +    2936,  3072,  3680,  4096,  4097,  4098,  4099,  4152,  4167,  4178,  
          518  +    4198,  4224,  4226,  4227,  4272,  4275,  4279,  4281,  4283,  4285,  
          519  +    4286,  4304,  4336,  4352,  4355,  4391,  4396,  4397,  4406,  4416,  
          520  +    4480,  4482,  4483,  4531,  4534,  4543,  4545,  4549,  4560,  5760,  
          521  +    5803,  5804,  5805,  5806,  5808,  5814,  5815,  5824,  8192,  9216,  
          522  +    9328,  12288, 26624, 28416, 28496, 28497, 28559, 28563, 45056, 53248, 
          523  +    53504, 53545, 53605, 53607, 53610, 53613, 53619, 53627, 53635, 53637, 
          524  +    53644, 53674, 53678, 53760, 53826, 53829, 54016, 54112, 54272, 54298, 
          525  +    54324, 54350, 54358, 54376, 54402, 54428, 54430, 54434, 54437, 54441, 
          526  +    54446, 54454, 54459, 54461, 54469, 54480, 54506, 54532, 54535, 54541, 
          527  +    54550, 54558, 54584, 54587, 54592, 54598, 54602, 54610, 54636, 54662, 
          528  +    54688, 54714, 54740, 54766, 54792, 54818, 54844, 54870, 54896, 54922, 
          529  +    54952, 54977, 54978, 55003, 55004, 55010, 55035, 55036, 55061, 55062, 
          530  +    55068, 55093, 55094, 55119, 55120, 55126, 55151, 55152, 55177, 55178, 
          531  +    55184, 55209, 55210, 55235, 55236, 55242, 55246, 60928, 60933, 60961, 
          532  +    60964, 60967, 60969, 60980, 60985, 60987, 60994, 60999, 61001, 61003, 
          533  +    61005, 61009, 61012, 61015, 61017, 61019, 61021, 61023, 61025, 61028, 
          534  +    61031, 61036, 61044, 61049, 61054, 61056, 61067, 61089, 61093, 61099, 
          535  +    61168, 61440, 61488, 61600, 61617, 61633, 61649, 61696, 61712, 61744, 
          536  +    61808, 61926, 61968, 62016, 62032, 62208, 62256, 62263, 62336, 62368, 
          537  +    62406, 62432, 62464, 62528, 62530, 62713, 62720, 62784, 62800, 62971, 
          538  +    63045, 63104, 63232, 0,     42710, 42752, 46900, 46912, 47133, 63488, 
          539  +    1,     32,    256,   0,     65533, 
          540  +  };
          541  +static u16 aFts5UnicodeData[] = {
          542  +    1025,  61,    117,   55,    117,   54,    50,    53,    57,    53,    
          543  +    49,    85,    333,   85,    121,   85,    841,   54,    53,    50,    
          544  +    56,    48,    56,    837,   54,    57,    50,    57,    1057,  61,    
          545  +    53,    151,   58,    53,    56,    58,    39,    52,    57,    34,    
          546  +    58,    56,    58,    57,    79,    56,    37,    85,    56,    47,    
          547  +    39,    51,    111,   53,    745,   57,    233,   773,   57,    261,   
          548  +    1822,  37,    542,   37,    1534,  222,   69,    73,    37,    126,   
          549  +    126,   73,    69,    137,   37,    73,    37,    105,   101,   73,    
          550  +    37,    73,    37,    190,   158,   37,    126,   126,   73,    37,    
          551  +    126,   94,    37,    39,    94,    69,    135,   41,    40,    37,    
          552  +    41,    40,    37,    41,    40,    37,    542,   37,    606,   37,    
          553  +    41,    40,    37,    126,   73,    37,    1886,  197,   73,    37,    
          554  +    73,    69,    126,   105,   37,    286,   2181,  39,    869,   582,   
          555  +    152,   390,   472,   166,   248,   38,    56,    38,    568,   3596,  
          556  +    158,   38,    56,    94,    38,    101,   53,    88,    41,    53,    
          557  +    105,   41,    73,    37,    553,   297,   1125,  94,    37,    105,   
          558  +    101,   798,   133,   94,    57,    126,   94,    37,    1641,  1541,  
          559  +    1118,  58,    172,   75,    1790,  478,   37,    2846,  1225,  38,    
          560  +    213,   1253,  53,    49,    55,    1452,  49,    44,    53,    76,    
          561  +    53,    76,    53,    44,    871,   103,   85,    162,   121,   85,    
          562  +    55,    85,    90,    364,   53,    85,    1031,  38,    327,   684,   
          563  +    333,   149,   71,    44,    3175,  53,    39,    236,   34,    58,    
          564  +    204,   70,    76,    58,    140,   71,    333,   103,   90,    39,    
          565  +    469,   34,    39,    44,    967,   876,   2855,  364,   39,    333,   
          566  +    1063,  300,   70,    58,    117,   38,    711,   140,   38,    300,   
          567  +    38,    108,   38,    172,   501,   807,   108,   53,    39,    359,   
          568  +    876,   108,   42,    1735,  44,    42,    44,    39,    106,   268,   
          569  +    138,   44,    74,    39,    236,   327,   76,    85,    333,   53,    
          570  +    38,    199,   231,   44,    74,    263,   71,    711,   231,   39,    
          571  +    135,   44,    39,    106,   140,   74,    74,    44,    39,    42,    
          572  +    71,    103,   76,    333,   71,    87,    207,   58,    55,    76,    
          573  +    42,    199,   71,    711,   231,   71,    71,    71,    44,    106,   
          574  +    76,    76,    108,   44,    135,   39,    333,   76,    103,   44,    
          575  +    76,    42,    295,   103,   711,   231,   71,    167,   44,    39,    
          576  +    106,   172,   76,    42,    74,    44,    39,    71,    76,    333,   
          577  +    53,    55,    44,    74,    263,   71,    711,   231,   71,    167,   
          578  +    44,    39,    42,    44,    42,    140,   74,    74,    44,    44,    
          579  +    42,    71,    103,   76,    333,   58,    39,    207,   44,    39,    
          580  +    199,   103,   135,   71,    39,    71,    71,    103,   391,   74,    
          581  +    44,    74,    106,   106,   44,    39,    42,    333,   111,   218,   
          582  +    55,    58,    106,   263,   103,   743,   327,   167,   39,    108,   
          583  +    138,   108,   140,   76,    71,    71,    76,    333,   239,   58,    
          584  +    74,    263,   103,   743,   327,   167,   44,    39,    42,    44,    
          585  +    170,   44,    74,    74,    76,    74,    39,    71,    76,    333,   
          586  +    71,    74,    263,   103,   1319,  39,    106,   140,   106,   106,   
          587  +    44,    39,    42,    71,    76,    333,   207,   58,    199,   74,    
          588  +    583,   775,   295,   39,    231,   44,    106,   108,   44,    266,   
          589  +    74,    53,    1543,  44,    71,    236,   55,    199,   38,    268,   
          590  +    53,    333,   85,    71,    39,    71,    39,    39,    135,   231,   
          591  +    103,   39,    39,    71,    135,   44,    71,    204,   76,    39,    
          592  +    167,   38,    204,   333,   135,   39,    122,   501,   58,    53,    
          593  +    122,   76,    218,   333,   335,   58,    44,    58,    44,    58,    
          594  +    44,    54,    50,    54,    50,    74,    263,   1159,  460,   42,    
          595  +    172,   53,    76,    167,   364,   1164,  282,   44,    218,   90,    
          596  +    181,   154,   85,    1383,  74,    140,   42,    204,   42,    76,    
          597  +    74,    76,    39,    333,   213,   199,   74,    76,    135,   108,   
          598  +    39,    106,   71,    234,   103,   140,   423,   44,    74,    76,    
          599  +    202,   44,    39,    42,    333,   106,   44,    90,    1225,  41,    
          600  +    41,    1383,  53,    38,    10631, 135,   231,   39,    135,   1319,  
          601  +    135,   1063,  135,   231,   39,    135,   487,   1831,  135,   2151,  
          602  +    108,   309,   655,   519,   346,   2727,  49,    19847, 85,    551,   
          603  +    61,    839,   54,    50,    2407,  117,   110,   423,   135,   108,   
          604  +    583,   108,   85,    583,   76,    423,   103,   76,    1671,  76,    
          605  +    42,    236,   266,   44,    74,    364,   117,   38,    117,   55,    
          606  +    39,    44,    333,   335,   213,   49,    149,   108,   61,    333,   
          607  +    1127,  38,    1671,  1319,  44,    39,    2247,  935,   108,   138,   
          608  +    76,    106,   74,    44,    202,   108,   58,    85,    333,   967,   
          609  +    167,   1415,  554,   231,   74,    333,   47,    1114,  743,   76,    
          610  +    106,   85,    1703,  42,    44,    42,    236,   44,    42,    44,    
          611  +    74,    268,   202,   332,   44,    333,   333,   245,   38,    213,   
          612  +    140,   42,    1511,  44,    42,    172,   42,    44,    170,   44,    
          613  +    74,    231,   333,   245,   346,   300,   314,   76,    42,    967,   
          614  +    42,    140,   74,    76,    42,    44,    74,    71,    333,   1415,  
          615  +    44,    42,    76,    106,   44,    42,    108,   74,    149,   1159,  
          616  +    266,   268,   74,    76,    181,   333,   103,   333,   967,   198,   
          617  +    85,    277,   108,   53,    428,   42,    236,   135,   44,    135,   
          618  +    74,    44,    71,    1413,  2022,  421,   38,    1093,  1190,  1260,  
          619  +    140,   4830,  261,   3166,  261,   265,   197,   201,   261,   265,   
          620  +    261,   265,   197,   201,   261,   41,    41,    41,    94,    229,   
          621  +    265,   453,   261,   264,   261,   264,   261,   264,   165,   69,    
          622  +    137,   40,    56,    37,    120,   101,   69,    137,   40,    120,   
          623  +    133,   69,    137,   120,   261,   169,   120,   101,   69,    137,   
          624  +    40,    88,    381,   162,   209,   85,    52,    51,    54,    84,    
          625  +    51,    54,    52,    277,   59,    60,    162,   61,    309,   52,    
          626  +    51,    149,   80,    117,   57,    54,    50,    373,   57,    53,    
          627  +    48,    341,   61,    162,   194,   47,    38,    207,   121,   54,    
          628  +    50,    38,    335,   121,   54,    50,    422,   855,   428,   139,   
          629  +    44,    107,   396,   90,    41,    154,   41,    90,    37,    105,   
          630  +    69,    105,   37,    58,    41,    90,    57,    169,   218,   41,    
          631  +    58,    41,    58,    41,    58,    137,   58,    37,    137,   37,    
          632  +    135,   37,    90,    69,    73,    185,   94,    101,   58,    57,    
          633  +    90,    37,    58,    527,   1134,  94,    142,   47,    185,   186,   
          634  +    89,    154,   57,    90,    57,    90,    57,    250,   57,    1018,  
          635  +    89,    90,    57,    58,    57,    1018,  8601,  282,   153,   666,   
          636  +    89,    250,   54,    50,    2618,  57,    986,   825,   1306,  217,   
          637  +    602,   1274,  378,   1935,  2522,  719,   5882,  57,    314,   57,    
          638  +    1754,  281,   3578,  57,    4634,  3322,  54,    50,    54,    50,    
          639  +    54,    50,    54,    50,    54,    50,    54,    50,    54,    50,    
          640  +    975,   1434,  185,   54,    50,    1017,  54,    50,    54,    50,    
          641  +    54,    50,    54,    50,    54,    50,    537,   8218,  4217,  54,    
          642  +    50,    54,    50,    54,    50,    54,    50,    54,    50,    54,    
          643  +    50,    54,    50,    54,    50,    54,    50,    54,    50,    54,    
          644  +    50,    2041,  54,    50,    54,    50,    1049,  54,    50,    8281,  
          645  +    1562,  697,   90,    217,   346,   1513,  1509,  126,   73,    69,    
          646  +    254,   105,   37,    94,    37,    94,    165,   70,    105,   37,    
          647  +    3166,  37,    218,   158,   108,   94,    149,   47,    85,    1221,  
          648  +    37,    37,    1799,  38,    53,    44,    743,   231,   231,   231,   
          649  +    231,   231,   231,   231,   231,   1036,  85,    52,    51,    52,    
          650  +    51,    117,   52,    51,    53,    52,    51,    309,   49,    85,    
          651  +    49,    53,    52,    51,    85,    52,    51,    54,    50,    54,    
          652  +    50,    54,    50,    54,    50,    181,   38,    341,   81,    858,   
          653  +    2874,  6874,  410,   61,    117,   58,    38,    39,    46,    54,    
          654  +    50,    54,    50,    54,    50,    54,    50,    54,    50,    90,    
          655  +    54,    50,    54,    50,    54,    50,    54,    50,    49,    54,    
          656  +    82,    58,    302,   140,   74,    49,    166,   90,    110,   38,    
          657  +    39,    53,    90,    2759,  76,    88,    70,    39,    49,    2887,  
          658  +    53,    102,   39,    1319,  3015,  90,    143,   346,   871,   1178,  
          659  +    519,   1018,  335,   986,   271,   58,    495,   1050,  335,   1274,  
          660  +    495,   2042,  8218,  39,    39,    2074,  39,    39,    679,   38,    
          661  +    36583, 1786,  1287,  198,   85,    8583,  38,    117,   519,   333,   
          662  +    71,    1502,  39,    44,    107,   53,    332,   53,    38,    798,   
          663  +    44,    2247,  334,   76,    213,   760,   294,   88,    478,   69,    
          664  +    2014,  38,    261,   190,   350,   38,    88,    158,   158,   382,   
          665  +    70,    37,    231,   44,    103,   44,    135,   44,    743,   74,    
          666  +    76,    42,    154,   207,   90,    55,    58,    1671,  149,   74,    
          667  +    1607,  522,   44,    85,    333,   588,   199,   117,   39,    333,   
          668  +    903,   268,   85,    743,   364,   74,    53,    935,   108,   42,    
          669  +    1511,  44,    74,    140,   74,    44,    138,   437,   38,    333,   
          670  +    85,    1319,  204,   74,    76,    74,    76,    103,   44,    263,   
          671  +    44,    42,    333,   149,   519,   38,    199,   122,   39,    42,    
          672  +    1543,  44,    39,    108,   71,    76,    167,   76,    39,    44,    
          673  +    39,    71,    38,    85,    359,   42,    76,    74,    85,    39,    
          674  +    70,    42,    44,    199,   199,   199,   231,   231,   1127,  74,    
          675  +    44,    74,    44,    74,    53,    42,    44,    333,   39,    39,    
          676  +    743,   1575,  36,    68,    68,    36,    63,    63,    11719, 3399,  
          677  +    229,   165,   39,    44,    327,   57,    423,   167,   39,    71,    
          678  +    71,    3463,  536,   11623, 54,    50,    2055,  1735,  391,   55,    
          679  +    58,    524,   245,   54,    50,    53,    236,   53,    81,    80,    
          680  +    54,    50,    54,    50,    54,    50,    54,    50,    54,    50,    
          681  +    54,    50,    54,    50,    54,    50,    85,    54,    50,    149,   
          682  +    112,   117,   149,   49,    54,    50,    54,    50,    54,    50,    
          683  +    117,   57,    49,    121,   53,    55,    85,    167,   4327,  34,    
          684  +    117,   55,    117,   54,    50,    53,    57,    53,    49,    85,    
          685  +    333,   85,    121,   85,    841,   54,    53,    50,    56,    48,    
          686  +    56,    837,   54,    57,    50,    57,    54,    50,    53,    54,    
          687  +    50,    85,    327,   38,    1447,  70,    999,   199,   199,   199,   
          688  +    103,   87,    57,    56,    58,    87,    58,    153,   90,    98,    
          689  +    90,    391,   839,   615,   71,    487,   455,   3943,  117,   1455,  
          690  +    314,   1710,  143,   570,   47,    410,   1466,  44,    935,   1575,  
          691  +    999,   143,   551,   46,    263,   46,    967,   53,    1159,  263,   
          692  +    53,    174,   1289,  1285,  2503,  333,   199,   39,    1415,  71,    
          693  +    39,    743,   53,    271,   711,   207,   53,    839,   53,    1799,  
          694  +    71,    39,    108,   76,    140,   135,   103,   871,   108,   44,    
          695  +    271,   309,   935,   79,    53,    1735,  245,   711,   271,   615,   
          696  +    271,   2343,  1007,  42,    44,    42,    1703,  492,   245,   655,   
          697  +    333,   76,    42,    1447,  106,   140,   74,    76,    85,    34,    
          698  +    149,   807,   333,   108,   1159,  172,   42,    268,   333,   149,   
          699  +    76,    42,    1543,  106,   300,   74,    135,   149,   333,   1383,  
          700  +    44,    42,    44,    74,    204,   42,    44,    333,   28135, 3182,  
          701  +    149,   34279, 18215, 2215,  39,    1482,  140,   422,   71,    7898,  
          702  +    1274,  1946,  74,    108,   122,   202,   258,   268,   90,    236,   
          703  +    986,   140,   1562,  2138,  108,   58,    2810,  591,   841,   837,   
          704  +    841,   229,   581,   841,   837,   41,    73,    41,    73,    137,   
          705  +    265,   133,   37,    229,   357,   841,   837,   73,    137,   265,   
          706  +    233,   837,   73,    137,   169,   41,    233,   837,   841,   837,   
          707  +    841,   837,   841,   837,   841,   837,   841,   837,   841,   901,   
          708  +    809,   57,    805,   57,    197,   809,   57,    805,   57,    197,   
          709  +    809,   57,    805,   57,    197,   809,   57,    805,   57,    197,   
          710  +    809,   57,    805,   57,    197,   94,    1613,  135,   871,   71,    
          711  +    39,    39,    327,   135,   39,    39,    39,    39,    39,    39,    
          712  +    103,   71,    39,    39,    39,    39,    39,    39,    71,    39,    
          713  +    135,   231,   135,   135,   39,    327,   551,   103,   167,   551,   
          714  +    89,    1434,  3226,  506,   474,   506,   506,   367,   1018,  1946,  
          715  +    1402,  954,   1402,  314,   90,    1082,  218,   2266,  666,   1210,  
          716  +    186,   570,   2042,  58,    5850,  154,   2010,  154,   794,   2266,  
          717  +    378,   2266,  3738,  39,    39,    39,    39,    39,    39,    17351, 
          718  +    34,    3074,  7692,  63,    63,    
          719  +  };
          720  +
          721  +int sqlite3Fts5UnicodeCategory(int iCode) { 
          722  +  int iRes = -1;
          723  +  int iHi;
          724  +  int iLo;
          725  +  int ret;
          726  +  u16 iKey;
          727  +
          728  +  if( iCode>=(1<<20) ){
          729  +    return 0;
          730  +  }
          731  +  iLo = aFts5UnicodeBlock[(iCode>>16)];
          732  +  iHi = aFts5UnicodeBlock[1+(iCode>>16)];
          733  +  iKey = (iCode & 0xFFFF);
          734  +  while( iHi>iLo ){
          735  +    int iTest = (iHi + iLo) / 2;
          736  +    assert( iTest>=iLo && iTest<iHi );
          737  +    if( iKey>=aFts5UnicodeMap[iTest] ){
          738  +      iRes = iTest;
          739  +      iLo = iTest+1;
          740  +    }else{
          741  +      iHi = iTest;
          742  +    }
          743  +  }
          744  +
          745  +  if( iRes<0 ) return 0;
          746  +  if( iKey>=(aFts5UnicodeMap[iRes]+(aFts5UnicodeData[iRes]>>5)) ) return 0;
          747  +  ret = aFts5UnicodeData[iRes] & 0x1F;
          748  +  if( ret!=30 ) return ret;
          749  +  return ((iKey - aFts5UnicodeMap[iRes]) & 0x01) ? 5 : 9;
          750  +}
          751  +
          752  +void sqlite3Fts5UnicodeAscii(u8 *aArray, u8 *aAscii){
          753  +  int i = 0;
          754  +  int iTbl = 0;
          755  +  while( i<128 ){
          756  +    int bToken = aArray[ aFts5UnicodeData[iTbl] & 0x1F ];
          757  +    int n = (aFts5UnicodeData[iTbl] >> 5) + i;
          758  +    for(; i<128 && i<n; i++){
          759  +      aAscii[i] = (u8)bToken;
          760  +    }
          761  +    iTbl++;
          762  +  }
          763  +}
          764  +

Changes to ext/fts5/fts5_vocab.c.

    25     25   ** row:
    26     26   **     CREATE TABLE vocab(term, doc, cnt, PRIMARY KEY(term));
    27     27   **
    28     28   **   One row for each term in the database. The value of $doc is set to
    29     29   **   the number of fts5 rows that contain at least one instance of term
    30     30   **   $term. Field $cnt is set to the total number of instances of term 
    31     31   **   $term in the database.
           32  +**
           33  +** instance:
           34  +**     CREATE TABLE vocab(term, doc, col, offset, PRIMARY KEY(<all-fields>));
           35  +**
           36  +**   One row for each term instance in the database. 
    32     37   */
    33     38   
    34     39   
    35     40   #include "fts5Int.h"
    36     41   
    37     42   
    38     43   typedef struct Fts5VocabTable Fts5VocabTable;
................................................................................
    40     45   
    41     46   struct Fts5VocabTable {
    42     47     sqlite3_vtab base;
    43     48     char *zFts5Tbl;                 /* Name of fts5 table */
    44     49     char *zFts5Db;                  /* Db containing fts5 table */
    45     50     sqlite3 *db;                    /* Database handle */
    46     51     Fts5Global *pGlobal;            /* FTS5 global object for this database */
    47         -  int eType;                      /* FTS5_VOCAB_COL or ROW */
           52  +  int eType;                      /* FTS5_VOCAB_COL, ROW or INSTANCE */
    48     53   };
    49     54   
    50     55   struct Fts5VocabCursor {
    51     56     sqlite3_vtab_cursor base;
    52     57     sqlite3_stmt *pStmt;            /* Statement holding lock on pIndex */
    53     58     Fts5Index *pIndex;              /* Associated FTS5 index */
    54     59   
................................................................................
    60     65   
    61     66     /* These are used by 'col' tables only */
    62     67     Fts5Config *pConfig;            /* Fts5 table configuration */
    63     68     int iCol;
    64     69     i64 *aCnt;
    65     70     i64 *aDoc;
    66     71   
    67         -  /* Output values used by 'row' and 'col' tables */
           72  +  /* Output values used by all tables. */
    68     73     i64 rowid;                      /* This table's current rowid value */
    69     74     Fts5Buffer term;                /* Current value of 'term' column */
           75  +
           76  +  /* Output values Used by 'instance' tables only */
           77  +  i64 iInstPos;
           78  +  int iInstOff;
    70     79   };
    71     80   
    72         -#define FTS5_VOCAB_COL    0
    73         -#define FTS5_VOCAB_ROW    1
           81  +#define FTS5_VOCAB_COL      0
           82  +#define FTS5_VOCAB_ROW      1
           83  +#define FTS5_VOCAB_INSTANCE 2
    74     84   
    75     85   #define FTS5_VOCAB_COL_SCHEMA  "term, col, doc, cnt"
    76     86   #define FTS5_VOCAB_ROW_SCHEMA  "term, doc, cnt"
           87  +#define FTS5_VOCAB_INST_SCHEMA "term, doc, col, offset"
    77     88   
    78     89   /*
    79     90   ** Bits for the mask used as the idxNum value by xBestIndex/xFilter.
    80     91   */
    81     92   #define FTS5_VOCAB_TERM_EQ 0x01
    82     93   #define FTS5_VOCAB_TERM_GE 0x02
    83     94   #define FTS5_VOCAB_TERM_LE 0x04
................................................................................
    96    107       sqlite3Fts5Dequote(zCopy);
    97    108       if( sqlite3_stricmp(zCopy, "col")==0 ){
    98    109         *peType = FTS5_VOCAB_COL;
    99    110       }else
   100    111   
   101    112       if( sqlite3_stricmp(zCopy, "row")==0 ){
   102    113         *peType = FTS5_VOCAB_ROW;
          114  +    }else
          115  +    if( sqlite3_stricmp(zCopy, "instance")==0 ){
          116  +      *peType = FTS5_VOCAB_INSTANCE;
   103    117       }else
   104    118       {
   105    119         *pzErr = sqlite3_mprintf("fts5vocab: unknown table type: %Q", zCopy);
   106    120         rc = SQLITE_ERROR;
   107    121       }
   108    122       sqlite3_free(zCopy);
   109    123     }
................................................................................
   157    171     int argc,                       /* Number of elements in argv array */
   158    172     const char * const *argv,       /* xCreate/xConnect argument array */
   159    173     sqlite3_vtab **ppVTab,          /* Write the resulting vtab structure here */
   160    174     char **pzErr                    /* Write any error message here */
   161    175   ){
   162    176     const char *azSchema[] = { 
   163    177       "CREATE TABlE vocab(" FTS5_VOCAB_COL_SCHEMA  ")", 
   164         -    "CREATE TABlE vocab(" FTS5_VOCAB_ROW_SCHEMA  ")"
          178  +    "CREATE TABlE vocab(" FTS5_VOCAB_ROW_SCHEMA  ")",
          179  +    "CREATE TABlE vocab(" FTS5_VOCAB_INST_SCHEMA ")"
   165    180     };
   166    181   
   167    182     Fts5VocabTable *pRet = 0;
   168    183     int rc = SQLITE_OK;             /* Return code */
   169    184     int bDb;
   170    185   
   171    186     bDb = (argc==6 && strlen(argv[1])==4 && memcmp("temp", argv[1], 4)==0);
................................................................................
   231    246     char **pzErr                    /* OUT: sqlite3_malloc'd error message */
   232    247   ){
   233    248     return fts5VocabInitVtab(db, pAux, argc, argv, ppVtab, pzErr);
   234    249   }
   235    250   
   236    251   /* 
   237    252   ** Implementation of the xBestIndex method.
          253  +**
          254  +** Only constraints of the form:
          255  +**
          256  +**     term <= ?
          257  +**     term == ?
          258  +**     term >= ?
          259  +**
          260  +** are interpreted. Less-than and less-than-or-equal are treated 
          261  +** identically, as are greater-than and greater-than-or-equal.
   238    262   */
   239    263   static int fts5VocabBestIndexMethod(
   240    264     sqlite3_vtab *pUnused,
   241    265     sqlite3_index_info *pInfo
   242    266   ){
   243    267     int i;
   244    268     int iTermEq = -1;
................................................................................
   374    398     fts5VocabResetCursor(pCsr);
   375    399     sqlite3Fts5BufferFree(&pCsr->term);
   376    400     sqlite3_finalize(pCsr->pStmt);
   377    401     sqlite3_free(pCsr);
   378    402     return SQLITE_OK;
   379    403   }
   380    404   
          405  +static int fts5VocabInstanceNewTerm(Fts5VocabCursor *pCsr){
          406  +  int rc = SQLITE_OK;
          407  +  
          408  +  if( sqlite3Fts5IterEof(pCsr->pIter) ){
          409  +    pCsr->bEof = 1;
          410  +  }else{
          411  +    const char *zTerm;
          412  +    int nTerm;
          413  +    zTerm = sqlite3Fts5IterTerm(pCsr->pIter, &nTerm);
          414  +    if( pCsr->nLeTerm>=0 ){
          415  +      int nCmp = MIN(nTerm, pCsr->nLeTerm);
          416  +      int bCmp = memcmp(pCsr->zLeTerm, zTerm, nCmp);
          417  +      if( bCmp<0 || (bCmp==0 && pCsr->nLeTerm<nTerm) ){
          418  +        pCsr->bEof = 1;
          419  +      }
          420  +    }
          421  +
          422  +    sqlite3Fts5BufferSet(&rc, &pCsr->term, nTerm, (const u8*)zTerm);
          423  +  }
          424  +  return rc;
          425  +}
          426  +
          427  +static int fts5VocabInstanceNext(Fts5VocabCursor *pCsr){
          428  +  int eDetail = pCsr->pConfig->eDetail;
          429  +  int rc = SQLITE_OK;
          430  +  Fts5IndexIter *pIter = pCsr->pIter;
          431  +  i64 *pp = &pCsr->iInstPos;
          432  +  int *po = &pCsr->iInstOff;
          433  +  
          434  +  while( eDetail==FTS5_DETAIL_NONE
          435  +      || sqlite3Fts5PoslistNext64(pIter->pData, pIter->nData, po, pp) 
          436  +  ){
          437  +    pCsr->iInstPos = 0;
          438  +    pCsr->iInstOff = 0;
          439  +
          440  +    rc = sqlite3Fts5IterNextScan(pCsr->pIter);
          441  +    if( rc==SQLITE_OK ){
          442  +      rc = fts5VocabInstanceNewTerm(pCsr);
          443  +      if( eDetail==FTS5_DETAIL_NONE ) break;
          444  +    }
          445  +    if( rc ){
          446  +      pCsr->bEof = 1;
          447  +      break;
          448  +    }
          449  +  }
          450  +
          451  +  return rc;
          452  +}
   381    453   
   382    454   /*
   383    455   ** Advance the cursor to the next row in the table.
   384    456   */
   385    457   static int fts5VocabNextMethod(sqlite3_vtab_cursor *pCursor){
   386    458     Fts5VocabCursor *pCsr = (Fts5VocabCursor*)pCursor;
   387    459     Fts5VocabTable *pTab = (Fts5VocabTable*)pCursor->pVtab;
   388    460     int rc = SQLITE_OK;
   389    461     int nCol = pCsr->pConfig->nCol;
   390    462   
   391    463     pCsr->rowid++;
          464  +
          465  +  if( pTab->eType==FTS5_VOCAB_INSTANCE ){
          466  +    return fts5VocabInstanceNext(pCsr);
          467  +  }
   392    468   
   393    469     if( pTab->eType==FTS5_VOCAB_COL ){
   394    470       for(pCsr->iCol++; pCsr->iCol<nCol; pCsr->iCol++){
   395    471         if( pCsr->aDoc[pCsr->iCol] ) break;
   396    472       }
   397    473     }
   398    474   
   399         -  if( pTab->eType==FTS5_VOCAB_ROW || pCsr->iCol>=nCol ){
          475  +  if( pTab->eType!=FTS5_VOCAB_COL || pCsr->iCol>=nCol ){
   400    476       if( sqlite3Fts5IterEof(pCsr->pIter) ){
   401    477         pCsr->bEof = 1;
   402    478       }else{
   403    479         const char *zTerm;
   404    480         int nTerm;
   405    481   
   406    482         zTerm = sqlite3Fts5IterTerm(pCsr->pIter, &nTerm);
................................................................................
   416    492         sqlite3Fts5BufferSet(&rc, &pCsr->term, nTerm, (const u8*)zTerm);
   417    493         memset(pCsr->aCnt, 0, nCol * sizeof(i64));
   418    494         memset(pCsr->aDoc, 0, nCol * sizeof(i64));
   419    495         pCsr->iCol = 0;
   420    496   
   421    497         assert( pTab->eType==FTS5_VOCAB_COL || pTab->eType==FTS5_VOCAB_ROW );
   422    498         while( rc==SQLITE_OK ){
          499  +        int eDetail = pCsr->pConfig->eDetail;
   423    500           const u8 *pPos; int nPos;   /* Position list */
   424    501           i64 iPos = 0;               /* 64-bit position read from poslist */
   425    502           int iOff = 0;               /* Current offset within position list */
   426    503   
   427    504           pPos = pCsr->pIter->pData;
   428    505           nPos = pCsr->pIter->nData;
   429         -        switch( pCsr->pConfig->eDetail ){
   430         -          case FTS5_DETAIL_FULL:
   431         -            pPos = pCsr->pIter->pData;
   432         -            nPos = pCsr->pIter->nData;
   433         -            if( pTab->eType==FTS5_VOCAB_ROW ){
          506  +
          507  +        switch( pTab->eType ){
          508  +          case FTS5_VOCAB_ROW:
          509  +            if( eDetail==FTS5_DETAIL_FULL ){
   434    510                 while( 0==sqlite3Fts5PoslistNext64(pPos, nPos, &iOff, &iPos) ){
   435    511                   pCsr->aCnt[0]++;
   436    512                 }
   437         -              pCsr->aDoc[0]++;
   438         -            }else{
          513  +            }
          514  +            pCsr->aDoc[0]++;
          515  +            break;
          516  +
          517  +          case FTS5_VOCAB_COL:
          518  +            if( eDetail==FTS5_DETAIL_FULL ){
   439    519                 int iCol = -1;
   440    520                 while( 0==sqlite3Fts5PoslistNext64(pPos, nPos, &iOff, &iPos) ){
   441    521                   int ii = FTS5_POS2COLUMN(iPos);
   442    522                   pCsr->aCnt[ii]++;
   443    523                   if( iCol!=ii ){
   444    524                     if( ii>=nCol ){
   445    525                       rc = FTS5_CORRUPT;
   446    526                       break;
   447    527                     }
   448    528                     pCsr->aDoc[ii]++;
   449    529                     iCol = ii;
   450    530                   }
   451    531                 }
   452         -            }
   453         -            break;
   454         -
   455         -          case FTS5_DETAIL_COLUMNS:
   456         -            if( pTab->eType==FTS5_VOCAB_ROW ){
   457         -              pCsr->aDoc[0]++;
   458         -            }else{
          532  +            }else if( eDetail==FTS5_DETAIL_COLUMNS ){
   459    533                 while( 0==sqlite3Fts5PoslistNext64(pPos, nPos, &iOff,&iPos) ){
   460    534                   assert_nc( iPos>=0 && iPos<nCol );
   461    535                   if( iPos>=nCol ){
   462    536                     rc = FTS5_CORRUPT;
   463    537                     break;
   464    538                   }
   465    539                   pCsr->aDoc[iPos]++;
   466    540                 }
          541  +            }else{
          542  +              assert( eDetail==FTS5_DETAIL_NONE );
          543  +              pCsr->aDoc[0]++;
   467    544               }
   468    545               break;
   469    546   
   470         -          default: 
   471         -            assert( pCsr->pConfig->eDetail==FTS5_DETAIL_NONE );
   472         -            pCsr->aDoc[0]++;
          547  +          default:
          548  +            assert( pTab->eType==FTS5_VOCAB_INSTANCE );
   473    549               break;
   474    550           }
   475    551   
   476    552           if( rc==SQLITE_OK ){
   477    553             rc = sqlite3Fts5IterNextScan(pCsr->pIter);
   478    554           }
          555  +        if( pTab->eType==FTS5_VOCAB_INSTANCE ) break;
   479    556   
   480    557           if( rc==SQLITE_OK ){
   481    558             zTerm = sqlite3Fts5IterTerm(pCsr->pIter, &nTerm);
   482    559             if( nTerm!=pCsr->term.n || memcmp(zTerm, pCsr->term.p, nTerm) ){
   483    560               break;
   484    561             }
   485    562             if( sqlite3Fts5IterEof(pCsr->pIter) ) break;
................................................................................
   501    578   static int fts5VocabFilterMethod(
   502    579     sqlite3_vtab_cursor *pCursor,   /* The cursor used for this query */
   503    580     int idxNum,                     /* Strategy index */
   504    581     const char *zUnused,            /* Unused */
   505    582     int nUnused,                    /* Number of elements in apVal */
   506    583     sqlite3_value **apVal           /* Arguments for the indexing scheme */
   507    584   ){
          585  +  Fts5VocabTable *pTab = (Fts5VocabTable*)pCursor->pVtab;
   508    586     Fts5VocabCursor *pCsr = (Fts5VocabCursor*)pCursor;
          587  +  int eType = pTab->eType;
   509    588     int rc = SQLITE_OK;
   510    589   
   511    590     int iVal = 0;
   512    591     int f = FTS5INDEX_QUERY_SCAN;
   513    592     const char *zTerm = 0;
   514    593     int nTerm = 0;
   515    594   
................................................................................
   541    620           rc = SQLITE_NOMEM;
   542    621         }else{
   543    622           memcpy(pCsr->zLeTerm, zCopy, pCsr->nLeTerm+1);
   544    623         }
   545    624       }
   546    625     }
   547    626   
   548         -
   549    627     if( rc==SQLITE_OK ){
   550    628       rc = sqlite3Fts5IndexQuery(pCsr->pIndex, zTerm, nTerm, f, 0, &pCsr->pIter);
   551    629     }
   552         -  if( rc==SQLITE_OK ){
          630  +  if( rc==SQLITE_OK && eType==FTS5_VOCAB_INSTANCE ){
          631  +    rc = fts5VocabInstanceNewTerm(pCsr);
          632  +  }
          633  +  if( rc==SQLITE_OK 
          634  +   && !pCsr->bEof 
          635  +   && (eType!=FTS5_VOCAB_INSTANCE || pCsr->pConfig->eDetail!=FTS5_DETAIL_NONE)
          636  +  ){
   553    637       rc = fts5VocabNextMethod(pCursor);
   554    638     }
   555    639   
   556    640     return rc;
   557    641   }
   558    642   
   559    643   /* 
................................................................................
   587    671           sqlite3_result_text(pCtx, z, -1, SQLITE_STATIC);
   588    672         }
   589    673       }else if( iCol==2 ){
   590    674         iVal = pCsr->aDoc[pCsr->iCol];
   591    675       }else{
   592    676         iVal = pCsr->aCnt[pCsr->iCol];
   593    677       }
   594         -  }else{
          678  +  }else if( eType==FTS5_VOCAB_ROW ){
   595    679       assert( iCol==1 || iCol==2 );
   596    680       if( iCol==1 ){
   597    681         iVal = pCsr->aDoc[0];
   598    682       }else{
   599    683         iVal = pCsr->aCnt[0];
          684  +    }
          685  +  }else{
          686  +    assert( eType==FTS5_VOCAB_INSTANCE );
          687  +    switch( iCol ){
          688  +      case 1:
          689  +        sqlite3_result_int64(pCtx, pCsr->pIter->iRowid);
          690  +        break;
          691  +      case 2: {
          692  +        int ii = -1;
          693  +        if( eDetail==FTS5_DETAIL_FULL ){
          694  +          ii = FTS5_POS2COLUMN(pCsr->iInstPos);
          695  +        }else if( eDetail==FTS5_DETAIL_COLUMNS ){
          696  +          ii = (int)pCsr->iInstPos;
          697  +        }
          698  +        if( ii>=0 && ii<pCsr->pConfig->nCol ){
          699  +          const char *z = pCsr->pConfig->azCol[ii];
          700  +          sqlite3_result_text(pCtx, z, -1, SQLITE_STATIC);
          701  +        }
          702  +        break;
          703  +      }
          704  +      default: {
          705  +        assert( iCol==3 );
          706  +        if( eDetail==FTS5_DETAIL_FULL ){
          707  +          int ii = FTS5_POS2OFFSET(pCsr->iInstPos);
          708  +          sqlite3_result_int(pCtx, ii);
          709  +        }
          710  +        break;
          711  +      }
   600    712       }
   601    713     }
   602    714   
   603    715     if( iVal>0 ) sqlite3_result_int64(pCtx, iVal);
   604    716     return SQLITE_OK;
   605    717   }
   606    718   

Changes to ext/fts5/fts5parse.y.

   144    144   
   145    145   
   146    146   %type nearset     {Fts5ExprNearset*}
   147    147   %type nearphrases {Fts5ExprNearset*}
   148    148   %destructor nearset { sqlite3Fts5ParseNearsetFree($$); }
   149    149   %destructor nearphrases { sqlite3Fts5ParseNearsetFree($$); }
   150    150   
   151         -nearset(A) ::= phrase(X). { A = sqlite3Fts5ParseNearset(pParse, 0, X); }
          151  +nearset(A) ::= phrase(Y). { A = sqlite3Fts5ParseNearset(pParse, 0, Y); }
          152  +nearset(A) ::= CARET phrase(Y). { 
          153  +  sqlite3Fts5ParseSetCaret(Y);
          154  +  A = sqlite3Fts5ParseNearset(pParse, 0, Y); 
          155  +}
   152    156   nearset(A) ::= STRING(X) LP nearphrases(Y) neardist_opt(Z) RP. {
   153    157     sqlite3Fts5ParseNear(pParse, &X);
   154    158     sqlite3Fts5ParseSetDistance(pParse, Y, &Z);
   155    159     A = Y;
   156    160   }
   157    161   
   158    162   nearphrases(A) ::= phrase(X). { 
................................................................................
   185    189     A = sqlite3Fts5ParseTerm(pParse, 0, &Y, Z);
   186    190   }
   187    191   
   188    192   /*
   189    193   ** Optional "*" character.
   190    194   */
   191    195   %type star_opt {int}
   192         -
   193    196   star_opt(A) ::= STAR. { A = 1; }
   194    197   star_opt(A) ::= . { A = 0; }

Changes to ext/fts5/test/fts5aa.test.

   587    587     COMMIT;
   588    588   }
   589    589   
   590    590   do_execsql_test 22.1 {
   591    591     SELECT rowid FROM t9('a*')
   592    592   } {1}
   593    593   
          594  +#-------------------------------------------------------------------------
          595  +do_execsql_test 23.0 {
          596  +  CREATE VIRTUAL TABLE t10 USING fts5(x, detail=%DETAIL%);
          597  +  CREATE TABLE t11(x);
          598  +}
          599  +do_execsql_test 23.1 {
          600  +  SELECT * FROM t11, t10 WHERE t11.x = t10.x AND t10.rowid IS NULL;
          601  +}
          602  +do_execsql_test 23.2 {
          603  +  SELECT * FROM t11, t10 WHERE t10.rowid IS NULL;
          604  +}
          605  +
   594    606   }
   595    607   
   596         -
          608  +expand_all_sql db
   597    609   finish_test

Changes to ext/fts5/test/fts5af.test.

   170    170       'x a a a a a a a a a a',
   171    171       'a a a a a a a a a a a a a a a a a a a x'
   172    172     );
   173    173   }
   174    174   do_execsql_test 5.1 {
   175    175     SELECT snippet(p1, 0, '[', ']', '...', 6) FROM p1('x');
   176    176   } {{[x] a a a a a...}}
          177  +
          178  +do_execsql_test 5.2 {
          179  +  SELECT snippet(p1, 0, '[', ']', NULL, 6) FROM p1('x');
          180  +} {{[x] a a a a a}}
          181  +do_execsql_test 5.3 {
          182  +  SELECT snippet(p1, 0, NULL, ']', '...', 6) FROM p1('x');
          183  +} {{x] a a a a a...}}
          184  +do_execsql_test 5.4 {
          185  +  SELECT snippet(p1, 0, '[', NULL, '...', 6) FROM p1('x');
          186  +} {{[x a a a a a...}}
   177    187   
   178    188   } ;# foreach_detail_mode 
   179    189   
   180    190   finish_test

Added ext/fts5/test/fts5cat.test.

            1  +# 2016 Jan 15
            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  +ifcapable !fts5 { finish_test ; return }
           15  +set ::testprefix fts5cat
           16  +
           17  +
           18  +do_execsql_test 1.0 {
           19  +  CREATE VIRTUAL TABLE t1 USING fts5(x, tokenize="unicode61 categories 'L*'");
           20  +  INSERT INTO t1 VALUES ('Unlike1option2values3and4column5names');
           21  +}
           22  +
           23  +do_execsql_test 1.1 {
           24  +  SELECT rowid FROM t1('option');
           25  +} {1}
           26  +
           27  +do_execsql_test 1.2 {
           28  +  CREATE VIRTUAL TABLE t2 USING fts5(x);
           29  +  CREATE VIRTUAL TABLE t2t USING fts5vocab(t2, row);
           30  +
           31  +  CREATE VIRTUAL TABLE t3 USING fts5(
           32  +    x, tokenize="unicode61 categories 'L* N* Co Mn'"
           33  +  );
           34  +  CREATE VIRTUAL TABLE t3t USING fts5vocab(t3, row);
           35  +
           36  +  CREATE VIRTUAL TABLE t4 USING fts5(
           37  +    x, tokenize="unicode61 categories 'L* N* Co M*'"
           38  +  );
           39  +  CREATE VIRTUAL TABLE t4t USING fts5vocab(t4, row);
           40  +
           41  +  INSERT INTO t2 VALUES ('สนามกีฬา');
           42  +  INSERT INTO t3 VALUES ('สนามกีฬา');
           43  +  INSERT INTO t4 VALUES ('สนามกีฬา');
           44  +}
           45  +
           46  +do_execsql_test 1.3 {
           47  +  SELECT * FROM t2t
           48  +} {สนามก 1 1 ฬา 1 1}
           49  +
           50  +do_execsql_test 1.4 {
           51  +  SELECT * FROM t3t
           52  +} {สนามกีฬา 1 1}
           53  +
           54  +do_execsql_test 1.5 {
           55  +  SELECT * FROM t4t
           56  +} {สนามกีฬา 1 1}
           57  +
           58  +
           59  +finish_test

Added ext/fts5/test/fts5connect.test.

            1  +# 2017 August 17
            2  +#
            3  +# The author disclaims copyright to this source code.  In place of
            4  +# a legal notice, here is a blessing:
            5  +#
            6  +#    May you do good and not evil.
            7  +#    May you find forgiveness for yourself and forgive others.
            8  +#    May you share freely, never taking more than you give.
            9  +#
           10  +#*************************************************************************
           11  +#
           12  +
           13  +
           14  +
           15  +source [file join [file dirname [info script]] fts5_common.tcl]
           16  +set testprefix fts5connect
           17  +
           18  +ifcapable !fts5 {
           19  +  finish_test
           20  +  return
           21  +}
           22  +
           23  +#-------------------------------------------------------------------------
           24  +# The tests in this file test the outcome of a schema-reset happening 
           25  +# within the xConnect() method of an FTS5 table. At one point this
           26  +# was causing a problem in SQLite. Each test proceeds as follows:
           27  +#
           28  +#   1. Connection [db] opens the db and reads from some unrelated, non-FTS5
           29  +#      table causing SQLite to load the db schema into memory.
           30  +#
           31  +#   2. Connection [db2] opens the db and modifies the db schema.
           32  +#
           33  +#   3. Connection [db] reads or writes an existing fts5 table. That the
           34  +#      schema has been modified is detected inside the fts5 xConnect() 
           35  +#      callback that is invoked by sqlite3_prepare(). 
           36  +#
           37  +#   4. Verify that the statement in 3 has worked. SQLite should detect
           38  +#      that the schema has changed and successfully prepare the 
           39  +#      statement against the new schema.
           40  +#
           41  +# Test plan:
           42  +#
           43  +#   1.*: Trigger the xConnect()/schema-reset using statements executed
           44  +#        directly against an FTS5 table.
           45  +#
           46  +#   2.*: Using various statements executed by various BEFORE triggers.
           47  +#
           48  +#   3.*: Using various statements executed by various AFTER triggers.
           49  +#
           50  +#   4.*: Using various statements executed by various INSTEAD OF triggers.
           51  +#
           52  +
           53  +
           54  +
           55  +do_execsql_test 1.0 {
           56  +  CREATE VIRTUAL TABLE ft1 USING fts5(a, b);
           57  +  CREATE TABLE abc(x INTEGER PRIMARY KEY);
           58  +  CREATE TABLE t1(i INTEGER PRIMARY KEY, a, b);
           59  +
           60  +  INSERT INTO ft1 VALUES('one', 'two');
           61  +  INSERT INTO ft1 VALUES('three', 'four');
           62  +}
           63  +
           64  +foreach {tn sql res} {
           65  +  1 "SELECT * FROM ft1" {one two three four}
           66  +  2 "REPLACE INTO ft1(rowid, a, b) VALUES(1, 'five', 'six')" {}
           67  +  3 "SELECT * FROM ft1" {five six three four}
           68  +  4 "INSERT INTO ft1 VALUES('seven', 'eight')" {}
           69  +  5 "SELECT * FROM ft1" {five six three four seven eight}
           70  +  6 "DELETE FROM ft1 WHERE rowid=2" {}
           71  +  7 "UPDATE ft1 SET b='nine' WHERE rowid=1" {}
           72  +  8 "SELECT * FROM ft1" {five nine seven eight}
           73  +} {
           74  +
           75  +  catch { db close }
           76  +  catch { db2 close }
           77  +  sqlite3 db  test.db
           78  +  sqlite3 db2 test.db
           79  +
           80  +  do_test 1.$tn.1 {
           81  +    db eval { INSERT INTO abc DEFAULT VALUES }
           82  +    db2 eval { CREATE TABLE newtable(x,y); DROP TABLE newtable }
           83  +  } {}
           84  +
           85  +  do_execsql_test 1.$tn.2 $sql $res
           86  +
           87  +  do_execsql_test 1.$tn.3 {
           88  +    INSERT INTO ft1(ft1) VALUES('integrity-check');
           89  +  }
           90  +}
           91  +
           92  +do_execsql_test 2.0 {
           93  +  CREATE VIRTUAL TABLE ft2 USING fts5(a, b);
           94  +  CREATE TABLE t2(a, b);
           95  +  CREATE TABLE log(txt);
           96  +
           97  +  CREATE TRIGGER t2_ai AFTER INSERT ON t2 BEGIN
           98  +    INSERT INTO ft2(rowid, a, b) VALUES(new.rowid, new.a, new.b);
           99  +    INSERT INTO log VALUES('insert');
          100  +  END;
          101  +
          102  +  CREATE TRIGGER t2_ad AFTER DELETE ON t2 BEGIN
          103  +    DELETE FROM ft2 WHERE rowid = old.rowid;
          104  +    INSERT INTO log VALUES('delete');
          105  +  END;
          106  +
          107  +  CREATE TRIGGER t2_au AFTER UPDATE ON t2 BEGIN
          108  +    UPDATE ft2 SET a=new.a, b=new.b WHERE rowid=new.rowid;
          109  +    INSERT INTO log VALUES('update');
          110  +  END;
          111  +
          112  +  INSERT INTO t2 VALUES('one', 'two');
          113  +  INSERT INTO t2 VALUES('three', 'four');
          114  +}
          115  +
          116  +foreach {tn sql res} {
          117  +  1 "SELECT * FROM t2" {one two three four}
          118  +  2 "REPLACE INTO t2(rowid, a, b) VALUES(1, 'five', 'six')" {}
          119  +  3 "SELECT * FROM ft2" {five six three four}
          120  +  4 "INSERT INTO t2 VALUES('seven', 'eight')" {}
          121  +  5 "SELECT * FROM ft2" {five six three four seven eight}
          122  +  6 "DELETE FROM t2 WHERE rowid=2" {}
          123  +  7 "UPDATE t2 SET b='nine' WHERE rowid=1" {}
          124  +  8 "SELECT * FROM ft2" {five nine seven eight}
          125  +} {
          126  +
          127  +  catch { db close }
          128  +  catch { db2 close }
          129  +  sqlite3 db  test.db
          130  +  sqlite3 db2 test.db
          131  +
          132  +  do_test 2.$tn.1 {
          133  +    db eval { INSERT INTO abc DEFAULT VALUES }
          134  +    db2 eval { CREATE TABLE newtable(x,y); DROP TABLE newtable }
          135  +  } {}
          136  +
          137  +  do_execsql_test 2.$tn.2 $sql $res
          138  +
          139  +  do_execsql_test 2.$tn.3 {
          140  +    INSERT INTO ft2(ft2) VALUES('integrity-check');
          141  +  }
          142  +}
          143  +
          144  +do_execsql_test 3.0 {
          145  +  CREATE VIRTUAL TABLE ft3 USING fts5(a, b);
          146  +  CREATE TABLE t3(a, b);
          147  +
          148  +  CREATE TRIGGER t3_ai BEFORE INSERT ON t3 BEGIN
          149  +    INSERT INTO ft3(rowid, a, b) VALUES(new.rowid, new.a, new.b);
          150  +    INSERT INTO log VALUES('insert');
          151  +  END;
          152  +
          153  +  CREATE TRIGGER t3_ad BEFORE DELETE ON t3 BEGIN
          154  +    DELETE FROM ft3 WHERE rowid = old.rowid;
          155  +    INSERT INTO log VALUES('delete');
          156  +  END;
          157  +
          158  +  CREATE TRIGGER t3_au BEFORE UPDATE ON t3 BEGIN
          159  +    UPDATE ft3 SET a=new.a, b=new.b WHERE rowid=new.rowid;
          160  +    INSERT INTO log VALUES('update');
          161  +  END;
          162  +
          163  +  INSERT INTO t3(rowid, a, b) VALUES(1, 'one', 'two');
          164  +  INSERT INTO t3(rowid, a, b) VALUES(2, 'three', 'four');
          165  +}
          166  +
          167  +foreach {tn sql res} {
          168  +  1 "SELECT * FROM t3" {one two three four}
          169  +  2 "REPLACE INTO t3(rowid, a, b) VALUES(1, 'five', 'six')" {}
          170  +  3 "SELECT * FROM ft3" {five six three four}
          171  +  4 "INSERT INTO t3(rowid, a, b) VALUES(3, 'seven', 'eight')" {}
          172  +  5 "SELECT * FROM ft3" {five six three four seven eight}
          173  +  6 "DELETE FROM t3 WHERE rowid=2" {}
          174  +  7 "UPDATE t3 SET b='nine' WHERE rowid=1" {}
          175  +  8 "SELECT * FROM ft3" {five nine seven eight}
          176  +} {
          177  +
          178  +  catch { db close }
          179  +  catch { db2 close }
          180  +  sqlite3 db  test.db
          181  +  sqlite3 db2 test.db
          182  +
          183  +  do_test 3.$tn.1 {
          184  +    db eval { INSERT INTO abc DEFAULT VALUES }
          185  +    db2 eval { CREATE TABLE newtable(x,y); DROP TABLE newtable }
          186  +  } {}
          187  +
          188  +  do_execsql_test 3.$tn.2 $sql $res
          189  +
          190  +  do_execsql_test 3.$tn.3 {
          191  +    INSERT INTO ft3(ft3) VALUES('integrity-check');
          192  +  }
          193  +}
          194  +
          195  +do_execsql_test 4.0 {
          196  +  CREATE VIRTUAL TABLE ft4 USING fts5(a, b);
          197  +  CREATE VIEW v4 AS SELECT rowid, * FROM ft4;
          198  +
          199  +  CREATE TRIGGER t4_ai INSTEAD OF INSERT ON v4 BEGIN
          200  +    INSERT INTO ft4(rowid, a, b) VALUES(new.rowid, new.a, new.b);
          201  +    INSERT INTO log VALUES('insert');
          202  +  END;
          203  +
          204  +  CREATE TRIGGER t4_ad INSTEAD OF DELETE ON v4 BEGIN
          205  +    DELETE FROM ft4 WHERE rowid = old.rowid;
          206  +    INSERT INTO log VALUES('delete');
          207  +  END;
          208  +
          209  +  CREATE TRIGGER t4_au INSTEAD OF UPDATE ON v4 BEGIN
          210  +    UPDATE ft4 SET a=new.a, b=new.b WHERE rowid=new.rowid;
          211  +    INSERT INTO log VALUES('update');
          212  +  END;
          213  +
          214  +  INSERT INTO ft4(rowid, a, b) VALUES(1, 'one', 'two');
          215  +  INSERT INTO ft4(rowid, a, b) VALUES(2, 'three', 'four');
          216  +}
          217  +
          218  +foreach {tn sql res} {
          219  +  1 "SELECT * FROM ft4" {one two three four}
          220  +  2 "REPLACE INTO v4(rowid, a, b) VALUES(1, 'five', 'six')" {}
          221  +  3 "SELECT * FROM ft4" {five six three four}
          222  +  4 "INSERT INTO v4(rowid, a, b) VALUES(3, 'seven', 'eight')" {}
          223  +  5 "SELECT * FROM ft4" {five six three four seven eight}
          224  +  6 "DELETE FROM v4 WHERE rowid=2" {}
          225  +  7 "UPDATE v4 SET b='nine' WHERE rowid=1" {}
          226  +  8 "SELECT * FROM ft4" {five nine seven eight}
          227  +} {
          228  +
          229  +  catch { db close }
          230  +  catch { db2 close }
          231  +  sqlite3 db  test.db
          232  +  sqlite3 db2 test.db
          233  +
          234  +  do_test 4.$tn.1 {
          235  +    db eval { INSERT INTO abc DEFAULT VALUES }
          236  +    db2 eval { CREATE TABLE newtable(x,y); DROP TABLE newtable }
          237  +  } {}
          238  +
          239  +  do_execsql_test 4.$tn.2 $sql $res
          240  +
          241  +  do_execsql_test 4.$tn.3 {
          242  +    INSERT INTO ft3(ft3) VALUES('integrity-check');
          243  +  }
          244  +}
          245  +
          246  +finish_test
          247  +

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

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

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

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

Changes to ext/fts5/test/fts5faultB.test.

   125    125   }
   126    126   
   127    127   do_faultsim_test 4.2 -faults oom* -body {
   128    128     execsql { SELECT rowid FROM t1('{a b c} : (a AND d)') }
   129    129   } -test {
   130    130     faultsim_test_result {0 {2 3}}
   131    131   }
          132  +
          133  +#-------------------------------------------------------------------------
          134  +# Test OOM injection while parsing a CARET expression
          135  +#
          136  +reset_db
          137  +do_execsql_test 5.0 {
          138  +  CREATE VIRTUAL TABLE t1 USING fts5(a);
          139  +  INSERT INTO t1 VALUES('a b c d');  -- 1
          140  +  INSERT INTO t1 VALUES('d a b c');  -- 2
          141  +  INSERT INTO t1 VALUES('c d a b');  -- 3
          142  +  INSERT INTO t1 VALUES('b c d a');  -- 4
          143  +}
          144  +do_faultsim_test 5.1 -faults oom* -body {
          145  +  execsql { SELECT rowid FROM t1('^a OR ^b') }
          146  +} -test {
          147  +  faultsim_test_result {0 {1 4}}
          148  +}
   132    149   
   133    150   
   134    151   finish_test

Added ext/fts5/test/fts5first.test.

            1  +# 2017 November 25
            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  +source [file join [file dirname [info script]] fts5_common.tcl]
           13  +set testprefix fts5first
           14  +
           15  +ifcapable !fts5 {
           16  +  finish_test
           17  +  return
           18  +}
           19  +
           20  +
           21  +do_execsql_test 1.0 {
           22  +  CREATE VIRTUAL TABLE x1 USING fts5(a, b);
           23  +}
           24  +
           25  +foreach {tn expr ok} {
           26  +  1 {^abc}           1
           27  +  2 {^abc + def}     1
           28  +  3 {^ "abc def"}    1
           29  +  4 {^"abc def"}     1
           30  +  5 {abc ^def}       1
           31  +  6 {abc + ^def}     0
           32  +  7 {abc ^+ def}     0
           33  +  8 {"^abc"}         1
           34  +  9 {NEAR(^abc def)} 0
           35  +} {
           36  +  set res(0) {/1 {fts5: syntax error near .*}/}
           37  +  set res(1) {0 {}}
           38  +
           39  +  do_catchsql_test 1.$tn { SELECT * FROM x1($expr) } $res($ok)
           40  +}
           41  +
           42  +#-------------------------------------------------------------------------
           43  +# 
           44  +do_execsql_test 2.0 {
           45  +  INSERT INTO x1 VALUES('a b c', 'b c a');
           46  +}
           47  +
           48  +foreach {tn expr match} {
           49  +  1 {^a} 1
           50  +  2 {^b} 1
           51  +  3 {^c} 0
           52  +  4 {^a + b} 1
           53  +  5 {^b + c} 1
           54  +  6 {^c + a} 0
           55  +  7 {^"c a"} 0
           56  +  8 {a:^a} 1
           57  +  9 {a:^b} 0
           58  +  10 {a:^"a b"} 1
           59  +} {
           60  +  do_execsql_test 2.$tn { SELECT EXISTS (SELECT rowid FROM x1($expr)) } $match
           61  +}
           62  +
           63  +#-------------------------------------------------------------------------
           64  +# 
           65  +do_execsql_test 3.0 {
           66  +  DELETE FROM x1;
           67  +  INSERT INTO x1 VALUES('b a', 'c a');
           68  +  INSERT INTO x1 VALUES('a a', 'c c');
           69  +  INSERT INTO x1 VALUES('a b', 'a a');
           70  +}
           71  +fts5_aux_test_functions db
           72  +
           73  +foreach {tn expr expect} {
           74  +  1 {^a} {{2 1}}
           75  +  2 {^c AND ^b} {{0 2} {1 0}}
           76  +} {
           77  +  do_execsql_test 3.$tn {
           78  +    SELECT fts5_test_queryphrase(x1) FROM x1($expr) LIMIT 1
           79  +  } [list $expect]
           80  +}
           81  +
           82  +#-------------------------------------------------------------------------
           83  +# 
           84  +do_execsql_test 3.1 {
           85  +  CREATE VIRTUAL TABLE x2 USING fts5(a, b, c, detail=column);
           86  +}
           87  +
           88  +do_catchsql_test 3.2 {
           89  +  SELECT * FROM x2('a + b');
           90  +} {1 {fts5: phrase queries are not supported (detail!=full)}}
           91  +
           92  +do_catchsql_test 3.3 {
           93  +  SELECT * FROM x2('^a');
           94  +} {1 {fts5: phrase queries are not supported (detail!=full)}}
           95  +finish_test
           96  +

Changes to ext/fts5/test/fts5plan.test.

    25     25     CREATE TABLE t1(x, y);
    26     26     CREATE VIRTUAL TABLE f1 USING fts5(ff);
    27     27   }
    28     28   
    29     29   do_eqp_test 1.1 {
    30     30     SELECT * FROM t1, f1 WHERE f1 MATCH t1.x
    31     31   } {
    32         -  0 0 0 {SCAN TABLE t1} 
    33         -  0 1 1 {SCAN TABLE f1 VIRTUAL TABLE INDEX 65537:}
           32  +  QUERY PLAN
           33  +  |--SCAN TABLE t1
           34  +  `--SCAN TABLE f1 VIRTUAL TABLE INDEX 65537:
    34     35   }
    35     36   
    36     37   do_eqp_test 1.2 {
    37     38     SELECT * FROM t1, f1 WHERE f1 > t1.x
    38     39   } {
    39         -  0 0 1 {SCAN TABLE f1 VIRTUAL TABLE INDEX 0:}
    40         -  0 1 0 {SCAN TABLE t1} 
           40  +  QUERY PLAN
           41  +  |--SCAN TABLE f1 VIRTUAL TABLE INDEX 0:
           42  +  `--SCAN TABLE t1
    41     43   }
    42     44   
    43     45   do_eqp_test 1.3 {
    44     46     SELECT * FROM f1 WHERE f1 MATCH ? ORDER BY ff
    45     47   } {
    46         -  0 0 0 {SCAN TABLE f1 VIRTUAL TABLE INDEX 65537:}
    47         -  0 0 0 {USE TEMP B-TREE FOR ORDER BY}
           48  +  QUERY PLAN
           49  +  |--SCAN TABLE f1 VIRTUAL TABLE INDEX 65537:
           50  +  `--USE TEMP B-TREE FOR ORDER BY
    48     51   }
    49     52   
    50     53   do_eqp_test 1.4 {
    51     54     SELECT * FROM f1 ORDER BY rank