/ Check-in [d198a6db]
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

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

Overview
Comment:Merge changes from the 3.11.0 release candidate.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | apple-osx
Files: files | file ages | folders
SHA1: d198a6db2e49d0205420f8ed08cfffd75ee93e1e
User & Date: drh 2016-02-13 17:35:48
Context
2016-02-15
17:40
Merge 3.11.0 changes. check-in: 5cecc509 user: drh tags: apple-osx
2016-02-13
17:35
Merge changes from the 3.11.0 release candidate. check-in: d198a6db user: drh tags: apple-osx
2016-02-12
18:48
Fix a potential buffer overread provoked by invalid utf-8 in fts5. check-in: a049fbbd user: dan tags: trunk
2016-02-09
15:50
Merge recent fixes and enhancements from trunk. check-in: f0734017 user: drh tags: apple-osx
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to Makefile.in.

   558    558   
   559    559   # Standard options to testfixture
   560    560   #
   561    561   TESTOPTS = --verbose=file --output=test-out.txt
   562    562   
   563    563   # Extra compiler options for various shell tools
   564    564   #
   565         -SHELL_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS5
          565  +SHELL_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS4
          566  +SHELL_OPT += -DSQLITE_ENABLE_EXPLAIN_COMMENTS
   566    567   FUZZERSHELL_OPT = -DSQLITE_ENABLE_JSON1
   567    568   FUZZCHECK_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5
   568    569   
   569    570   # This is the default Makefile target.  The objects listed here
   570    571   # are what get build when you type just "make" with no arguments.
   571    572   #
   572    573   all:	sqlite3.h libsqlite3.la sqlite3$(TEXE) $(HAVE_TCL:1=libtclsqlite3.la)
................................................................................
   583    584   
   584    585   libtclsqlite3.la:	tclsqlite.lo libsqlite3.la
   585    586   	$(LTLINK) -no-undefined -o $@ tclsqlite.lo \
   586    587   		libsqlite3.la @TCL_STUB_LIB_SPEC@ $(TLIBS) \
   587    588                   -rpath "$(TCLLIBDIR)/sqlite3" \
   588    589   		-version-info "8:6:8"
   589    590   
   590         -sqlite3$(TEXE):	$(TOP)/src/shell.c libsqlite3.la sqlite3.h
          591  +sqlite3$(TEXE):	$(TOP)/src/shell.c sqlite3.c
   591    592   	$(LTLINK) $(READLINE_FLAGS) $(SHELL_OPT) -o $@ \
   592         -		$(TOP)/src/shell.c libsqlite3.la \
          593  +		$(TOP)/src/shell.c sqlite3.c \
   593    594   		$(LIBREADLINE) $(TLIBS) -rpath "$(libdir)"
   594    595   
   595    596   sqldiff$(TEXE):	$(TOP)/tool/sqldiff.c sqlite3.c sqlite3.h
   596    597   	$(LTLINK) -o $@ $(TOP)/tool/sqldiff.c sqlite3.c $(TLIBS)
   597    598   
   598    599   srcck1$(BEXE):	$(TOP)/tool/srcck1.c
   599    600   	$(BCC) -o srcck1$(BEXE) $(TOP)/tool/srcck1.c
................................................................................
  1163   1164   # symbols that do not begin with "sqlite3_". It is run as part of the
  1164   1165   # releasetest.tcl script.
  1165   1166   #
  1166   1167   checksymbols: sqlite3.lo
  1167   1168   	nm -g --defined-only sqlite3.o | grep -v " sqlite3_" ; test $$? -ne 0
  1168   1169   	echo '0 errors out of 1 tests'
  1169   1170   
  1170         -# Build the amalgamation-autoconf package.
         1171  +# Build the amalgamation-autoconf package.  The amalamgation-tarball target builds
         1172  +# a tarball named for the version number.  Ex:  sqlite-autoconf-3110000.tar.gz.
         1173  +# The snapshot-tarball target builds a tarball named by the SHA1 hash
  1171   1174   #
  1172   1175   amalgamation-tarball: sqlite3.c
  1173         -	TOP=$(TOP) sh $(TOP)/tool/mkautoconfamal.sh
         1176  +	TOP=$(TOP) sh $(TOP)/tool/mkautoconfamal.sh --normal
         1177  +
         1178  +snapshot-tarball: sqlite3.c
         1179  +	TOP=$(TOP) sh $(TOP)/tool/mkautoconfamal.sh --snapshot
  1174   1180   
  1175   1181   # The next two rules are used to support the "threadtest" target. Building
  1176   1182   # threadtest runs a few thread-safety tests that are implemented in C. This
  1177   1183   # target is invoked by the releasetest.tcl script.
  1178   1184   # 
  1179   1185   THREADTEST3_SRC = $(TOP)/test/threadtest3.c    \
  1180   1186                     $(TOP)/test/tt3_checkpoint.c \

Changes to Makefile.msc.

   122    122   # This setting does not apply to any binaries that require Tcl to operate
   123    123   # properly (i.e. the text fixture, etc).
   124    124   #
   125    125   !IFNDEF FOR_WINRT
   126    126   FOR_WINRT = 0
   127    127   !ENDIF
   128    128   
   129         -# Set this non-0 to compile binaries suitable for the UAP environment.
          129  +# Set this non-0 to compile binaries suitable for the UWP environment.
   130    130   # This setting does not apply to any binaries that require Tcl to operate
   131    131   # properly (i.e. the text fixture, etc).
   132    132   #
   133         -!IFNDEF FOR_UAP
   134         -FOR_UAP = 0
          133  +!IFNDEF FOR_UWP
          134  +FOR_UWP = 0
   135    135   !ENDIF
   136    136   
   137    137   # Set this non-0 to compile binaries suitable for the Windows 10 platform.
   138    138   #
   139    139   !IFNDEF FOR_WIN10
   140    140   FOR_WIN10 = 0
   141    141   !ENDIF
................................................................................
   410    410   #
   411    411   !IF $(USE_FULLWARN)!=0
   412    412   TCC = $(CC) -nologo -W4 -DINCLUDE_MSVC_H=1 $(CCOPTS) $(TCCOPTS)
   413    413   !ELSE
   414    414   TCC = $(CC) -nologo -W3 $(CCOPTS) $(TCCOPTS)
   415    415   !ENDIF
   416    416   
   417         -TCC = $(TCC) -DSQLITE_OS_WIN=1 -I$(TOP) -I$(TOP)\src -fp:precise
   418         -RCC = $(RC) -DSQLITE_OS_WIN=1 -I$(TOP) -I$(TOP)\src $(RCOPTS) $(RCCOPTS)
          417  +TCC = $(TCC) -DSQLITE_OS_WIN=1 -I. -I$(TOP) -I$(TOP)\src -fp:precise
          418  +RCC = $(RC) -DSQLITE_OS_WIN=1 -I. -I$(TOP) -I$(TOP)\src $(RCOPTS) $(RCCOPTS)
   419    419   
   420    420   # Adjust the names of the primary targets for use with Windows 10.
   421    421   #
   422    422   !IF $(FOR_WIN10)!=0
   423    423   SQLITE3DLL = winsqlite3.dll
   424    424   SQLITE3LIB = winsqlite3.lib
   425    425   SQLITE3EXE = winsqlite3shell.exe
................................................................................
   547    547   TCC = $(TCC) -DWINAPI_FAMILY=WINAPI_FAMILY_APP
   548    548   RCC = $(RCC) -DWINAPI_FAMILY=WINAPI_FAMILY_APP
   549    549   !ENDIF
   550    550   
   551    551   # C compiler options for the Windows 10 platform (needs MSVC 2015).
   552    552   #
   553    553   !IF $(FOR_WIN10)!=0
   554         -TCC = $(TCC) /guard:cf -D_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE
   555         -BCC = $(BCC) /guard:cf -D_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE
          554  +TCC = $(TCC) /d2guard4 -D_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE
          555  +BCC = $(BCC) /d2guard4 -D_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE
   556    556   !ENDIF
   557    557   
   558    558   # Also, we need to dynamically link to the correct MSVC runtime
   559    559   # when compiling for WinRT (e.g. debug or release) OR if the
   560    560   # USE_CRT_DLL option is set to force dynamically linking to the
   561    561   # MSVC runtime library.
   562    562   #
................................................................................
   903    903   LTLINKOPTS = $(LTLINKOPTS) "/LIBPATH:$(WP81LIBPATH)"
   904    904   !ENDIF
   905    905   LTLINKOPTS = $(LTLINKOPTS) /DYNAMICBASE
   906    906   LTLINKOPTS = $(LTLINKOPTS) WindowsPhoneCore.lib RuntimeObject.lib PhoneAppModelHost.lib
   907    907   LTLINKOPTS = $(LTLINKOPTS) /NODEFAULTLIB:kernel32.lib /NODEFAULTLIB:ole32.lib
   908    908   !ENDIF
   909    909   
   910         -# When compiling for UAP or the Windows 10 platform, some extra linker
          910  +# When compiling for UWP or the Windows 10 platform, some extra linker
   911    911   # options are also required.
   912    912   #
   913         -!IF $(FOR_UAP)!=0 || $(FOR_WIN10)!=0
          913  +!IF $(FOR_UWP)!=0 || $(FOR_WIN10)!=0
   914    914   LTLINKOPTS = $(LTLINKOPTS) /DYNAMICBASE /NODEFAULTLIB:kernel32.lib
   915    915   LTLINKOPTS = $(LTLINKOPTS) mincore.lib
   916    916   !IFDEF PSDKLIBPATH
   917    917   LTLINKOPTS = $(LTLINKOPTS) "/LIBPATH:$(PSDKLIBPATH)"
   918    918   !ENDIF
   919    919   !ENDIF
   920    920   
   921    921   !IF $(FOR_WIN10)!=0
   922         -LTLINKOPTS = $(LTLINKOPTS) "/LIBPATH:$(UCRTLIBPATH)"
          922  +LTLINKOPTS = $(LTLINKOPTS) /guard:cf "/LIBPATH:$(UCRTLIBPATH)"
   923    923   !IF $(DEBUG)>1
   924    924   LTLINKOPTS = $(LTLINKOPTS) /NODEFAULTLIB:libucrtd.lib /DEFAULTLIB:ucrtd.lib
   925    925   !ELSE
   926    926   LTLINKOPTS = $(LTLINKOPTS) /NODEFAULTLIB:libucrt.lib /DEFAULTLIB:ucrt.lib
   927    927   !ENDIF
   928    928   !ENDIF
   929    929   
................................................................................
  1001   1001   !IF $(USE_RC)!=0
  1002   1002   LIBRESOBJS = sqlite3res.lo
  1003   1003   !ELSE
  1004   1004   LIBRESOBJS =
  1005   1005   !ENDIF
  1006   1006   
  1007   1007   # <<mark>>
  1008         -# All of the source code files.
         1008  +# Core source code files, part 1.
  1009   1009   #
  1010         -SRC1 = \
         1010  +SRC00 = \
  1011   1011     $(TOP)\src\alter.c \
  1012   1012     $(TOP)\src\analyze.c \
  1013   1013     $(TOP)\src\attach.c \
  1014   1014     $(TOP)\src\auth.c \
  1015   1015     $(TOP)\src\backup.c \
  1016   1016     $(TOP)\src\bitvec.c \
  1017   1017     $(TOP)\src\btmutex.c \
  1018   1018     $(TOP)\src\btree.c \
  1019         -  $(TOP)\src\btree.h \
  1020         -  $(TOP)\src\btreeInt.h \
  1021   1019     $(TOP)\src\build.c \
  1022   1020     $(TOP)\src\callback.c \
  1023   1021     $(TOP)\src\complete.c \
  1024   1022     $(TOP)\src\ctime.c \
  1025   1023     $(TOP)\src\date.c \
  1026   1024     $(TOP)\src\dbstat.c \
  1027   1025     $(TOP)\src\delete.c \
  1028   1026     $(TOP)\src\expr.c \
  1029   1027     $(TOP)\src\fault.c \
  1030   1028     $(TOP)\src\fkey.c \
  1031   1029     $(TOP)\src\func.c \
  1032   1030     $(TOP)\src\global.c \
  1033   1031     $(TOP)\src\hash.c \
  1034         -  $(TOP)\src\hash.h \
  1035         -  $(TOP)\src\hwtime.h \
  1036   1032     $(TOP)\src\insert.c \
  1037   1033     $(TOP)\src\journal.c \
  1038   1034     $(TOP)\src\legacy.c \
  1039   1035     $(TOP)\src\loadext.c \
  1040   1036     $(TOP)\src\main.c \
  1041   1037     $(TOP)\src\malloc.c \
  1042   1038     $(TOP)\src\mem0.c \
  1043   1039     $(TOP)\src\mem1.c \
  1044   1040     $(TOP)\src\mem2.c \
  1045   1041     $(TOP)\src\mem3.c \
  1046   1042     $(TOP)\src\mem5.c \
  1047   1043     $(TOP)\src\memjournal.c \
  1048         -  $(TOP)\src\msvc.h \
  1049   1044     $(TOP)\src\mutex.c \
  1050         -  $(TOP)\src\mutex.h \
  1051   1045     $(TOP)\src\mutex_noop.c \
  1052   1046     $(TOP)\src\mutex_unix.c \
  1053   1047     $(TOP)\src\mutex_w32.c \
  1054   1048     $(TOP)\src\notify.c \
  1055   1049     $(TOP)\src\os.c \
  1056         -  $(TOP)\src\os.h \
  1057         -  $(TOP)\src\os_common.h \
  1058         -  $(TOP)\src\os_setup.h \
  1059   1050     $(TOP)\src\os_unix.c \
  1060         -  $(TOP)\src\os_win.c \
  1061         -  $(TOP)\src\os_win.h
  1062         -SRC2 = \
         1051  +  $(TOP)\src\os_win.c
         1052  +
         1053  +# Core source code files, part 2.
         1054  +#
         1055  +SRC01 = \
  1063   1056     $(TOP)\src\pager.c \
  1064         -  $(TOP)\src\pager.h \
  1065         -  $(TOP)\src\parse.y \
  1066   1057     $(TOP)\src\pcache.c \
  1067         -  $(TOP)\src\pcache.h \
  1068   1058     $(TOP)\src\pcache1.c \
  1069   1059     $(TOP)\src\pragma.c \
  1070         -  $(TOP)\src\pragma.h \
  1071   1060     $(TOP)\src\prepare.c \
  1072   1061     $(TOP)\src\printf.c \
  1073   1062     $(TOP)\src\random.c \
  1074   1063     $(TOP)\src\resolve.c \
  1075   1064     $(TOP)\src\rowset.c \
  1076   1065     $(TOP)\src\select.c \
  1077   1066     $(TOP)\src\status.c \
  1078         -  $(TOP)\src\shell.c \
  1079         -  $(TOP)\src\sqlite.h.in \
  1080         -  $(TOP)\src\sqlite3ext.h \
  1081         -  $(TOP)\src\sqliteInt.h \
  1082         -  $(TOP)\src\sqliteLimit.h \
  1083   1067     $(TOP)\src\table.c \
  1084   1068     $(TOP)\src\threads.c \
  1085   1069     $(TOP)\src\tclsqlite.c \
  1086   1070     $(TOP)\src\tokenize.c \
  1087   1071     $(TOP)\src\treeview.c \
  1088   1072     $(TOP)\src\trigger.c \
  1089   1073     $(TOP)\src\utf.c \
  1090   1074     $(TOP)\src\update.c \
  1091   1075     $(TOP)\src\util.c \
  1092   1076     $(TOP)\src\vacuum.c \
  1093   1077     $(TOP)\src\vdbe.c \
  1094         -  $(TOP)\src\vdbe.h \
  1095   1078     $(TOP)\src\vdbeapi.c \
  1096   1079     $(TOP)\src\vdbeaux.c \
  1097   1080     $(TOP)\src\vdbeblob.c \
  1098   1081     $(TOP)\src\vdbemem.c \
  1099   1082     $(TOP)\src\vdbesort.c \
  1100   1083     $(TOP)\src\vdbetrace.c \
  1101         -  $(TOP)\src\vdbeInt.h \
  1102   1084     $(TOP)\src\vtab.c \
  1103         -  $(TOP)\src\vxworks.h \
  1104   1085     $(TOP)\src\wal.c \
  1105         -  $(TOP)\src\wal.h \
  1106   1086     $(TOP)\src\walker.c \
  1107   1087     $(TOP)\src\where.c \
  1108   1088     $(TOP)\src\wherecode.c \
  1109         -  $(TOP)\src\whereexpr.c \
         1089  +  $(TOP)\src\whereexpr.c
         1090  +
         1091  +# Shell source code files.
         1092  +#
         1093  +SRC02 = \
         1094  +  $(TOP)\src\shell.c
         1095  +
         1096  +# Core miscellaneous files.
         1097  +#
         1098  +SRC03 = \
         1099  +  $(TOP)\src\parse.y
         1100  +
         1101  +# Core header files, part 1.
         1102  +#
         1103  +SRC04 = \
         1104  +  $(TOP)\src\btree.h \
         1105  +  $(TOP)\src\btreeInt.h \
         1106  +  $(TOP)\src\hash.h \
         1107  +  $(TOP)\src\hwtime.h \
         1108  +  $(TOP)\src\msvc.h \
         1109  +  $(TOP)\src\mutex.h \
         1110  +  $(TOP)\src\os.h \
         1111  +  $(TOP)\src\os_common.h \
         1112  +  $(TOP)\src\os_setup.h \
         1113  +  $(TOP)\src\os_win.h
         1114  +
         1115  +# Core header files, part 2.
         1116  +#
         1117  +SRC05 = \
         1118  +  $(TOP)\src\pager.h \
         1119  +  $(TOP)\src\pcache.h \
         1120  +  $(TOP)\src\pragma.h \
         1121  +  $(TOP)\src\sqlite.h.in \
         1122  +  $(TOP)\src\sqlite3ext.h \
         1123  +  $(TOP)\src\sqliteInt.h \
         1124  +  $(TOP)\src\sqliteLimit.h \
         1125  +  $(TOP)\src\vdbe.h \
         1126  +  $(TOP)\src\vdbeInt.h \
         1127  +  $(TOP)\src\vxworks.h \
         1128  +  $(TOP)\src\wal.h \
  1110   1129     $(TOP)\src\whereInt.h
  1111   1130   
  1112         -# Source code for extensions
         1131  +# Extension source code files, part 1.
  1113   1132   #
  1114         -SRC3 = \
         1133  +SRC06 = \
  1115   1134     $(TOP)\ext\fts1\fts1.c \
  1116         -  $(TOP)\ext\fts1\fts1.h \
  1117   1135     $(TOP)\ext\fts1\fts1_hash.c \
  1118         -  $(TOP)\ext\fts1\fts1_hash.h \
  1119   1136     $(TOP)\ext\fts1\fts1_porter.c \
  1120         -  $(TOP)\ext\fts1\fts1_tokenizer.h \
  1121   1137     $(TOP)\ext\fts1\fts1_tokenizer1.c \
  1122   1138     $(TOP)\ext\fts2\fts2.c \
  1123         -  $(TOP)\ext\fts2\fts2.h \
  1124   1139     $(TOP)\ext\fts2\fts2_hash.c \
  1125         -  $(TOP)\ext\fts2\fts2_hash.h \
  1126   1140     $(TOP)\ext\fts2\fts2_icu.c \
  1127   1141     $(TOP)\ext\fts2\fts2_porter.c \
  1128         -  $(TOP)\ext\fts2\fts2_tokenizer.h \
  1129   1142     $(TOP)\ext\fts2\fts2_tokenizer.c \
  1130   1143     $(TOP)\ext\fts2\fts2_tokenizer1.c
  1131         -SRC4 = \
         1144  +
         1145  +# Extension source code files, part 2.
         1146  +#
         1147  +SRC07 = \
  1132   1148     $(TOP)\ext\fts3\fts3.c \
  1133         -  $(TOP)\ext\fts3\fts3.h \
  1134         -  $(TOP)\ext\fts3\fts3Int.h \
  1135   1149     $(TOP)\ext\fts3\fts3_aux.c \
  1136   1150     $(TOP)\ext\fts3\fts3_expr.c \
  1137   1151     $(TOP)\ext\fts3\fts3_hash.c \
  1138         -  $(TOP)\ext\fts3\fts3_hash.h \
  1139   1152     $(TOP)\ext\fts3\fts3_icu.c \
  1140   1153     $(TOP)\ext\fts3\fts3_porter.c \
  1141   1154     $(TOP)\ext\fts3\fts3_snippet.c \
  1142         -  $(TOP)\ext\fts3\fts3_tokenizer.h \
  1143   1155     $(TOP)\ext\fts3\fts3_tokenizer.c \
  1144   1156     $(TOP)\ext\fts3\fts3_tokenizer1.c \
  1145   1157     $(TOP)\ext\fts3\fts3_tokenize_vtab.c \
  1146   1158     $(TOP)\ext\fts3\fts3_unicode.c \
  1147   1159     $(TOP)\ext\fts3\fts3_unicode2.c \
  1148   1160     $(TOP)\ext\fts3\fts3_write.c \
  1149         -  $(TOP)\ext\icu\sqliteicu.h \
  1150   1161     $(TOP)\ext\icu\icu.c \
  1151         -  $(TOP)\ext\rtree\rtree.h \
  1152   1162     $(TOP)\ext\rtree\rtree.c \
  1153         -  $(TOP)\ext\rbu\sqlite3rbu.h \
  1154   1163     $(TOP)\ext\rbu\sqlite3rbu.c \
  1155   1164     $(TOP)\ext\misc\json1.c
  1156   1165   
         1166  +# Extension header files, part 1.
         1167  +#
         1168  +SRC08 = \
         1169  +  $(TOP)\ext\fts1\fts1.h \
         1170  +  $(TOP)\ext\fts1\fts1_hash.h \
         1171  +  $(TOP)\ext\fts1\fts1_tokenizer.h \
         1172  +  $(TOP)\ext\fts2\fts2.h \
         1173  +  $(TOP)\ext\fts2\fts2_hash.h \
         1174  +  $(TOP)\ext\fts2\fts2_tokenizer.h
         1175  +
         1176  +# Extension header files, part 2.
         1177  +#
         1178  +SRC09 = \
         1179  +  $(TOP)\ext\fts3\fts3.h \
         1180  +  $(TOP)\ext\fts3\fts3Int.h \
         1181  +  $(TOP)\ext\fts3\fts3_hash.h \
         1182  +  $(TOP)\ext\fts3\fts3_tokenizer.h \
         1183  +  $(TOP)\ext\icu\sqliteicu.h \
         1184  +  $(TOP)\ext\rtree\rtree.h \
         1185  +  $(TOP)\ext\rbu\sqlite3rbu.h
  1157   1186   
  1158   1187   # Generated source code files
  1159   1188   #
  1160         -SRC5 = \
  1161         -  keywordhash.h \
         1189  +SRC10 = \
  1162   1190     opcodes.c \
         1191  +  parse.c
         1192  +
         1193  +# Generated header files
         1194  +#
         1195  +SRC11 = \
         1196  +  keywordhash.h \
  1163   1197     opcodes.h \
  1164         -  parse.c \
  1165   1198     parse.h \
  1166   1199     $(SQLITE3H)
  1167   1200   
  1168   1201   # All source code files.
  1169   1202   #
  1170         -SRC = $(SRC1) $(SRC2) $(SRC3) $(SRC4) $(SRC5)
         1203  +SRC = $(SRC00) $(SRC01) $(SRC02) $(SRC03) $(SRC04) $(SRC05) $(SRC06) $(SRC07) $(SRC08) $(SRC09) $(SRC10) $(SRC11)
  1171   1204   
  1172   1205   # Source code to the test files.
  1173   1206   #
  1174   1207   TESTSRC = \
  1175   1208     $(TOP)\src\test1.c \
  1176   1209     $(TOP)\src\test2.c \
  1177   1210     $(TOP)\src\test3.c \
................................................................................
  1212   1245     $(TOP)\src\test_vfs.c \
  1213   1246     $(TOP)\src\test_windirent.c \
  1214   1247     $(TOP)\src\test_wsd.c \
  1215   1248     $(TOP)\ext\fts3\fts3_term.c \
  1216   1249     $(TOP)\ext\fts3\fts3_test.c \
  1217   1250     $(TOP)\ext\rbu\test_rbu.c
  1218   1251   
  1219         -# Statically linked extensions
         1252  +# Statically linked extensions.
  1220   1253   #
  1221   1254   TESTEXT = \
  1222   1255     $(TOP)\ext\misc\amatch.c \
  1223   1256     $(TOP)\ext\misc\closure.c \
  1224   1257     $(TOP)\ext\misc\eval.c \
  1225   1258     $(TOP)\ext\misc\fileio.c \
  1226   1259     $(TOP)\ext\misc\fuzzer.c \
................................................................................
  1232   1265     $(TOP)\ext\misc\percentile.c \
  1233   1266     $(TOP)\ext\misc\regexp.c \
  1234   1267     $(TOP)\ext\misc\series.c \
  1235   1268     $(TOP)\ext\misc\spellfix.c \
  1236   1269     $(TOP)\ext\misc\totype.c \
  1237   1270     $(TOP)\ext\misc\wholenumber.c
  1238   1271   
  1239         -
  1240   1272   # Source code to the library files needed by the test fixture
  1241   1273   #
  1242   1274   TESTSRC2 = \
  1243         -  $(TOP)\src\attach.c \
  1244         -  $(TOP)\src\backup.c \
  1245         -  $(TOP)\src\bitvec.c \
  1246         -  $(TOP)\src\btree.c \
  1247         -  $(TOP)\src\build.c \
  1248         -  $(TOP)\src\ctime.c \
  1249         -  $(TOP)\src\date.c \
  1250         -  $(TOP)\src\dbstat.c \
  1251         -  $(TOP)\src\expr.c \
  1252         -  $(TOP)\src\func.c \
  1253         -  $(TOP)\src\insert.c \
  1254         -  $(TOP)\src\wal.c \
  1255         -  $(TOP)\src\main.c \
  1256         -  $(TOP)\src\mem5.c \
  1257         -  $(TOP)\src\os.c \
  1258         -  $(TOP)\src\os_unix.c \
  1259         -  $(TOP)\src\os_win.c \
  1260         -  $(TOP)\src\pager.c \
  1261         -  $(TOP)\src\pragma.c \
  1262         -  $(TOP)\src\prepare.c \
  1263         -  $(TOP)\src\printf.c \
  1264         -  $(TOP)\src\random.c \
  1265         -  $(TOP)\src\pcache.c \
  1266         -  $(TOP)\src\pcache1.c \
  1267         -  $(TOP)\src\select.c \
  1268         -  $(TOP)\src\tokenize.c \
  1269         -  $(TOP)\src\utf.c \
  1270         -  $(TOP)\src\util.c \
  1271         -  $(TOP)\src\vdbeapi.c \
  1272         -  $(TOP)\src\vdbeaux.c \
  1273         -  $(TOP)\src\vdbe.c \
  1274         -  $(TOP)\src\vdbemem.c \
  1275         -  $(TOP)\src\vdbesort.c \
  1276         -  $(TOP)\src\vdbetrace.c \
  1277         -  $(TOP)\src\where.c \
  1278         -  $(TOP)\src\wherecode.c \
  1279         -  $(TOP)\src\whereexpr.c \
  1280         -  parse.c \
  1281         -  $(TOP)\ext\fts3\fts3.c \
  1282         -  $(TOP)\ext\fts3\fts3_aux.c \
  1283         -  $(TOP)\ext\fts3\fts3_expr.c \
  1284         -  $(TOP)\ext\fts3\fts3_tokenizer.c \
  1285         -  $(TOP)\ext\fts3\fts3_tokenize_vtab.c \
  1286         -  $(TOP)\ext\fts3\fts3_unicode.c \
  1287         -  $(TOP)\ext\fts3\fts3_unicode2.c \
  1288         -  $(TOP)\ext\fts3\fts3_write.c \
         1275  +  $(SRC00) \
         1276  +  $(SRC01) \
         1277  +  $(SRC06) \
         1278  +  $(SRC07) \
         1279  +  $(SRC10) \
  1289   1280     $(TOP)\ext\async\sqlite3async.c
  1290   1281   
  1291   1282   # Header files used by all library source files.
  1292   1283   #
  1293   1284   HDR = \
  1294   1285      $(TOP)\src\btree.h \
  1295   1286      $(TOP)\src\btreeInt.h \
................................................................................
  1355   1346     $(TOP)\test\fuzzdata4.db
  1356   1347   # <</mark>>
  1357   1348   
  1358   1349   # Additional compiler options for the shell.  These are only effective
  1359   1350   # when the shell is not being dynamically linked.
  1360   1351   #
  1361   1352   !IF $(DYNAMIC_SHELL)==0 && $(FOR_WIN10)==0
  1362         -SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_SHELL_JSON1 -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS5
         1353  +SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_SHELL_JSON1 -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS
  1363   1354   !ENDIF
  1364   1355   
  1365   1356   # <<mark>>
  1366   1357   # Extra compiler options for various test tools.
  1367   1358   #
  1368   1359   MPTESTER_COMPILE_OPTS = -DSQLITE_SHELL_JSON1 -DSQLITE_ENABLE_FTS5
  1369   1360   FUZZERSHELL_COMPILE_OPTS = -DSQLITE_ENABLE_JSON1
................................................................................
  1456   1447   # build on the target system.  Some of the C source code and header
  1457   1448   # files are automatically generated.  This target takes care of
  1458   1449   # all that automatic generation.
  1459   1450   #
  1460   1451   .target_source:	$(SRC) $(TOP)\tool\vdbe-compress.tcl fts5.c
  1461   1452   	-rmdir /Q/S tsrc 2>NUL
  1462   1453   	-mkdir tsrc
  1463         -	for %i in ($(SRC1)) do copy /Y %i tsrc
  1464         -	for %i in ($(SRC2)) do copy /Y %i tsrc
  1465         -	for %i in ($(SRC3)) do copy /Y %i tsrc
  1466         -	for %i in ($(SRC4)) do copy /Y %i tsrc
  1467         -	for %i in ($(SRC5)) do copy /Y %i tsrc
         1454  +	for %i in ($(SRC00)) do copy /Y %i tsrc
         1455  +	for %i in ($(SRC01)) do copy /Y %i tsrc
         1456  +	for %i in ($(SRC02)) do copy /Y %i tsrc
         1457  +	for %i in ($(SRC03)) do copy /Y %i tsrc
         1458  +	for %i in ($(SRC04)) do copy /Y %i tsrc
         1459  +	for %i in ($(SRC05)) do copy /Y %i tsrc
         1460  +	for %i in ($(SRC06)) do copy /Y %i tsrc
         1461  +	for %i in ($(SRC07)) do copy /Y %i tsrc
         1462  +	for %i in ($(SRC08)) do copy /Y %i tsrc
         1463  +	for %i in ($(SRC09)) do copy /Y %i tsrc
         1464  +	for %i in ($(SRC10)) do copy /Y %i tsrc
         1465  +	for %i in ($(SRC11)) do copy /Y %i tsrc
  1468   1466   	copy /Y fts5.c tsrc
  1469   1467   	copy /Y fts5.h tsrc
  1470   1468   	del /Q tsrc\sqlite.h.in tsrc\parse.y 2>NUL
  1471   1469   	$(TCLSH_CMD) $(TOP)\tool\vdbe-compress.tcl $(OPTS) < tsrc\vdbe.c > vdbe.new
  1472   1470   	move vdbe.new tsrc\vdbe.c
  1473   1471   	echo > .target_source
  1474   1472   
................................................................................
  1905   1903   # necessary because the test fixture requires non-API symbols which are
  1906   1904   # hidden when the library is built via the amalgamation).
  1907   1905   #
  1908   1906   TESTFIXTURE_FLAGS = -DTCLSH=1 -DSQLITE_TEST=1 -DSQLITE_CRASH_TEST=1
  1909   1907   TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_SERVER=1 -DSQLITE_PRIVATE=""
  1910   1908   TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_CORE $(NO_WARN)
  1911   1909   
  1912         -TESTFIXTURE_SRC0 = $(TESTEXT) $(TESTSRC2) $(SHELL_CORE_DEP)
         1910  +TESTFIXTURE_SRC0 = $(TESTEXT) $(TESTSRC2)
  1913   1911   TESTFIXTURE_SRC1 = $(TESTEXT) $(SQLITE3C)
  1914   1912   !IF $(USE_AMALGAMATION)==0
  1915   1913   TESTFIXTURE_SRC = $(TESTSRC) $(TOP)\src\tclsqlite.c $(TESTFIXTURE_SRC0)
  1916   1914   !ELSE
  1917   1915   TESTFIXTURE_SRC = $(TESTSRC) $(TOP)\src\tclsqlite.c $(TESTFIXTURE_SRC1)
  1918   1916   !ENDIF
  1919   1917   

Changes to autoconf/Makefile.am.

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

Changes to autoconf/Makefile.msc.

   115    115   # This setting does not apply to any binaries that require Tcl to operate
   116    116   # properly (i.e. the text fixture, etc).
   117    117   #
   118    118   !IFNDEF FOR_WINRT
   119    119   FOR_WINRT = 0
   120    120   !ENDIF
   121    121   
   122         -# Set this non-0 to compile binaries suitable for the UAP environment.
          122  +# Set this non-0 to compile binaries suitable for the UWP environment.
   123    123   # This setting does not apply to any binaries that require Tcl to operate
   124    124   # properly (i.e. the text fixture, etc).
   125    125   #
   126         -!IFNDEF FOR_UAP
   127         -FOR_UAP = 0
          126  +!IFNDEF FOR_UWP
          127  +FOR_UWP = 0
   128    128   !ENDIF
   129    129   
   130    130   # Set this non-0 to compile binaries suitable for the Windows 10 platform.
   131    131   #
   132    132   !IFNDEF FOR_WIN10
   133    133   FOR_WIN10 = 0
   134    134   !ENDIF
................................................................................
   395    395   #
   396    396   !IF $(USE_FULLWARN)!=0
   397    397   TCC = $(CC) -nologo -W4 -DINCLUDE_MSVC_H=1 $(CCOPTS) $(TCCOPTS)
   398    398   !ELSE
   399    399   TCC = $(CC) -nologo -W3 $(CCOPTS) $(TCCOPTS)
   400    400   !ENDIF
   401    401   
   402         -TCC = $(TCC) -DSQLITE_OS_WIN=1 -I$(TOP) -fp:precise
   403         -RCC = $(RC) -DSQLITE_OS_WIN=1 -I$(TOP) $(RCOPTS) $(RCCOPTS)
          402  +TCC = $(TCC) -DSQLITE_OS_WIN=1 -I. -I$(TOP) -fp:precise
          403  +RCC = $(RC) -DSQLITE_OS_WIN=1 -I. -I$(TOP) $(RCOPTS) $(RCCOPTS)
   404    404   
   405    405   # Adjust the names of the primary targets for use with Windows 10.
   406    406   #
   407    407   !IF $(FOR_WIN10)!=0
   408    408   SQLITE3DLL = winsqlite3.dll
   409    409   SQLITE3LIB = winsqlite3.lib
   410    410   SQLITE3EXE = winsqlite3shell.exe
................................................................................
   532    532   TCC = $(TCC) -DWINAPI_FAMILY=WINAPI_FAMILY_APP
   533    533   RCC = $(RCC) -DWINAPI_FAMILY=WINAPI_FAMILY_APP
   534    534   !ENDIF
   535    535   
   536    536   # C compiler options for the Windows 10 platform (needs MSVC 2015).
   537    537   #
   538    538   !IF $(FOR_WIN10)!=0
   539         -TCC = $(TCC) /guard:cf -D_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE
   540         -BCC = $(BCC) /guard:cf -D_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE
          539  +TCC = $(TCC) /d2guard4 -D_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE
          540  +BCC = $(BCC) /d2guard4 -D_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE
   541    541   !ENDIF
   542    542   
   543    543   # Also, we need to dynamically link to the correct MSVC runtime
   544    544   # when compiling for WinRT (e.g. debug or release) OR if the
   545    545   # USE_CRT_DLL option is set to force dynamically linking to the
   546    546   # MSVC runtime library.
   547    547   #
................................................................................
   798    798   LTLINKOPTS = $(LTLINKOPTS) "/LIBPATH:$(WP81LIBPATH)"
   799    799   !ENDIF
   800    800   LTLINKOPTS = $(LTLINKOPTS) /DYNAMICBASE
   801    801   LTLINKOPTS = $(LTLINKOPTS) WindowsPhoneCore.lib RuntimeObject.lib PhoneAppModelHost.lib
   802    802   LTLINKOPTS = $(LTLINKOPTS) /NODEFAULTLIB:kernel32.lib /NODEFAULTLIB:ole32.lib
   803    803   !ENDIF
   804    804   
   805         -# When compiling for UAP or the Windows 10 platform, some extra linker
          805  +# When compiling for UWP or the Windows 10 platform, some extra linker
   806    806   # options are also required.
   807    807   #
   808         -!IF $(FOR_UAP)!=0 || $(FOR_WIN10)!=0
          808  +!IF $(FOR_UWP)!=0 || $(FOR_WIN10)!=0
   809    809   LTLINKOPTS = $(LTLINKOPTS) /DYNAMICBASE /NODEFAULTLIB:kernel32.lib
   810    810   LTLINKOPTS = $(LTLINKOPTS) mincore.lib
   811    811   !IFDEF PSDKLIBPATH
   812    812   LTLINKOPTS = $(LTLINKOPTS) "/LIBPATH:$(PSDKLIBPATH)"
   813    813   !ENDIF
   814    814   !ENDIF
   815    815   
   816    816   !IF $(FOR_WIN10)!=0
   817         -LTLINKOPTS = $(LTLINKOPTS) "/LIBPATH:$(UCRTLIBPATH)"
          817  +LTLINKOPTS = $(LTLINKOPTS) /guard:cf "/LIBPATH:$(UCRTLIBPATH)"
   818    818   !IF $(DEBUG)>1
   819    819   LTLINKOPTS = $(LTLINKOPTS) /NODEFAULTLIB:libucrtd.lib /DEFAULTLIB:ucrtd.lib
   820    820   !ELSE
   821    821   LTLINKOPTS = $(LTLINKOPTS) /NODEFAULTLIB:libucrt.lib /DEFAULTLIB:ucrt.lib
   822    822   !ENDIF
   823    823   !ENDIF
   824    824   
................................................................................
   852    852   !ENDIF
   853    853   
   854    854   
   855    855   # Additional compiler options for the shell.  These are only effective
   856    856   # when the shell is not being dynamically linked.
   857    857   #
   858    858   !IF $(DYNAMIC_SHELL)==0 && $(FOR_WIN10)==0
   859         -SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_SHELL_JSON1 -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS5
          859  +SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_SHELL_JSON1 -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_EXPLAIN_COMMENTS
   860    860   !ENDIF
   861    861   
   862    862   
   863    863   # This is the default Makefile target.  The objects listed here
   864    864   # are what get build when you type just "make" with no arguments.
   865    865   #
   866    866   all:	dll libsqlite3.lib shell

Changes to autoconf/README.txt.

     1      1   This package contains:
     2      2   
     3         - * the SQLite library amalgamation (single file) source code distribution,
     4         - * the shell.c file used to build the sqlite3 shell too, and
     5         - * the sqlite3.h and sqlite3ext.h header files required to link programs
     6         -   and sqlite extensions against the installed libary.
            3  + * the SQLite library amalgamation source code file: sqlite3.c
            4  + * the sqlite3.h and sqlite3ext.h header files that define the C-language
            5  +   interface to the sqlite3.c library file
            6  + * the shell.c file used to build the sqlite3 command-line shell program
     7      7    * autoconf/automake installation infrastucture for building on POSIX
     8         -   compliant systems.
            8  +   compliant systems
     9      9    * a Makefile.msc and sqlite3.rc for building with Microsoft Visual C++ on
    10         -   Windows.
           10  +   Windows
    11     11   
    12     12   SUMMARY OF HOW TO BUILD
    13     13   =======================
    14     14   
    15     15     Unix:      ./configure; make
    16     16     Windows:   nmake /f Makefile.msc
    17     17   
................................................................................
    35     35     $ CFLAGS="-Os" ./configure
    36     36   
    37     37   to produce a smaller installation footprint.
    38     38   
    39     39   Other SQLite compilation parameters can also be set using CFLAGS. For
    40     40   example:
    41     41   
    42         -  $ CFLAGS="-Os -DSQLITE_OMIT_TRIGGERS" ./configure
           42  +  $ CFLAGS="-Os -DSQLITE_THREADSAFE=0" ./configure
    43     43   
    44     44   
    45     45   BUILDING WITH MICROSOFT VISUAL C++
    46     46   ==================================
    47     47   
    48     48   To compile for Windows using Microsoft Visual C++:
    49     49   
................................................................................
    71     71   
    72     72   Using Microsoft Visual C++ 2013 (or later) is required.  When using the
    73     73   above, something like the following macro will need to be added to the
    74     74   NMAKE command line as well:
    75     75   
    76     76     "NSDKLIBPATH=%WindowsSdkDir%\..\8.1\lib\winv6.3\um\x86"
    77     77   
    78         -Building for UAP 10.0
           78  +Building for UWP 10.0
    79     79   ---------------------
    80     80   
    81         -  FOR_WINRT=1 FOR_UAP=1
           81  +  FOR_WINRT=1 FOR_UWP=1
    82     82   
    83     83   Using Microsoft Visual C++ 2015 (or later) is required.  When using the
    84     84   above, something like the following macros will need to be added to the
    85     85   NMAKE command line as well:
    86     86   
    87     87     "NSDKLIBPATH=%WindowsSdkDir%\..\10\lib\10.0.10586.0\um\x86"
    88     88     "PSDKLIBPATH=%WindowsSdkDir%\..\10\lib\10.0.10586.0\um\x86"

Changes to ext/fts3/fts3Int.h.

    13     13   */
    14     14   #ifndef _FTSINT_H
    15     15   #define _FTSINT_H
    16     16   
    17     17   #if !defined(NDEBUG) && !defined(SQLITE_DEBUG) 
    18     18   # define NDEBUG 1
    19     19   #endif
           20  +
           21  +/* FTS3/FTS4 require virtual tables */
           22  +#ifdef SQLITE_OMIT_VIRTUALTABLE
           23  +# undef SQLITE_ENABLE_FTS3
           24  +# undef SQLITE_ENABLE_FTS4
           25  +#endif
    20     26   
    21     27   /*
    22     28   ** FTS4 is really an extension for FTS3.  It is enabled using the
    23     29   ** SQLITE_ENABLE_FTS3 macro.  But to avoid confusion we also all
    24     30   ** the SQLITE_ENABLE_FTS4 macro to serve as an alisse for SQLITE_ENABLE_FTS3.
    25     31   */
    26     32   #if defined(SQLITE_ENABLE_FTS4) && !defined(SQLITE_ENABLE_FTS3)

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

   222    222     puts "** The results are undefined if the value passed to this function"
   223    223     puts "** is less than zero."
   224    224     puts "*/"
   225    225     puts "int ${zFunc}\(int c)\{"
   226    226     an_print_range_array $lRange
   227    227     an_print_ascii_bitmap $lRange
   228    228     puts {
   229         -  if( c<128 ){
          229  +  if( (unsigned int)c<128 ){
   230    230       return ( (aAscii[c >> 5] & (1 << (c & 0x001F)))==0 );
   231         -  }else if( c<(1<<22) ){
          231  +  }else if( (unsigned int)c<(1<<22) ){
   232    232       unsigned int key = (((unsigned int)c)<<10) | 0x000003FF;
   233    233       int iRes = 0;
   234    234       int iHi = sizeof(aEntry)/sizeof(aEntry[0]) - 1;
   235    235       int iLo = 0;
   236    236       while( iHi>=iLo ){
   237    237         int iTest = (iHi + iLo) / 2;
   238    238         if( key >= aEntry[iTest] ){

Changes to ext/fts5/fts5Int.h.

    22     22   #include <assert.h>
    23     23   
    24     24   #ifndef SQLITE_AMALGAMATION
    25     25   
    26     26   typedef unsigned char  u8;
    27     27   typedef unsigned int   u32;
    28     28   typedef unsigned short u16;
           29  +typedef short i16;
    29     30   typedef sqlite3_int64 i64;
    30     31   typedef sqlite3_uint64 u64;
    31     32   
    32     33   #define ArraySize(x) ((int)(sizeof(x) / sizeof(x[0])))
    33     34   
    34     35   #define testcase(x)
    35     36   #define ALWAYS(x) 1
................................................................................
    75     76   */
    76     77   #ifdef SQLITE_DEBUG
    77     78   extern int sqlite3_fts5_may_be_corrupt;
    78     79   # define assert_nc(x) assert(sqlite3_fts5_may_be_corrupt || (x))
    79     80   #else
    80     81   # define assert_nc(x) assert(x)
    81     82   #endif
           83  +
           84  +/* Mark a function parameter as unused, to suppress nuisance compiler
           85  +** warnings. */
           86  +#ifndef UNUSED_PARAM
           87  +# define UNUSED_PARAM(X)  (void)(X)
           88  +#endif
           89  +
           90  +#ifndef UNUSED_PARAM2
           91  +# define UNUSED_PARAM2(X, Y)  (void)(X), (void)(Y)
           92  +#endif
    82     93   
    83     94   typedef struct Fts5Global Fts5Global;
    84     95   typedef struct Fts5Colset Fts5Colset;
    85     96   
    86     97   /* If a NEAR() clump or phrase may only match a specific set of columns, 
    87     98   ** then an object of the following type is used to record the set of columns.
    88     99   ** Each entry in the aiCol[] array is a column that may be matched.
................................................................................
   341    352   
   342    353   /*
   343    354   ** Create/destroy an Fts5Index object.
   344    355   */
   345    356   int sqlite3Fts5IndexOpen(Fts5Config *pConfig, int bCreate, Fts5Index**, char**);
   346    357   int sqlite3Fts5IndexClose(Fts5Index *p);
   347    358   
   348         -/*
   349         -** for(
   350         -**   sqlite3Fts5IndexQuery(p, "token", 5, 0, 0, &pIter);
   351         -**   0==sqlite3Fts5IterEof(pIter);
   352         -**   sqlite3Fts5IterNext(pIter)
   353         -** ){
   354         -**   i64 iRowid = sqlite3Fts5IterRowid(pIter);
   355         -** }
   356         -*/
   357         -
   358    359   /*
   359    360   ** Return a simple checksum value based on the arguments.
   360    361   */
   361    362   u64 sqlite3Fts5IndexEntryCksum(
   362    363     i64 iRowid, 
   363    364     int iCol, 
   364    365     int iPos, 
................................................................................
   392    393   
   393    394   /*
   394    395   ** The various operations on open token or token prefix iterators opened
   395    396   ** using sqlite3Fts5IndexQuery().
   396    397   */
   397    398   int sqlite3Fts5IterNext(Fts5IndexIter*);
   398    399   int sqlite3Fts5IterNextFrom(Fts5IndexIter*, i64 iMatch);
   399         -i64 sqlite3Fts5IterRowid(Fts5IndexIter*);
   400    400   
   401    401   /*
   402    402   ** Close an iterator opened by sqlite3Fts5IndexQuery().
   403    403   */
   404    404   void sqlite3Fts5IterClose(Fts5IndexIter*);
   405    405   
   406    406   /*
................................................................................
   677    677   Fts5PoslistPopulator *sqlite3Fts5ExprClearPoslists(Fts5Expr*, int);
   678    678   int sqlite3Fts5ExprPopulatePoslists(
   679    679       Fts5Config*, Fts5Expr*, Fts5PoslistPopulator*, int, const char*, int
   680    680   );
   681    681   void sqlite3Fts5ExprCheckPoslists(Fts5Expr*, i64);
   682    682   void sqlite3Fts5ExprClearEof(Fts5Expr*);
   683    683   
   684         -int sqlite3Fts5ExprClonePhrase(Fts5Config*, Fts5Expr*, int, Fts5Expr**);
          684  +int sqlite3Fts5ExprClonePhrase(Fts5Expr*, int, Fts5Expr**);
   685    685   
   686    686   int sqlite3Fts5ExprPhraseCollist(Fts5Expr *, int, const u8 **, int *);
   687    687   
   688    688   /*******************************************
   689    689   ** The fts5_expr.c API above this point is used by the other hand-written
   690    690   ** C code in this module. The interfaces below this point are called by
   691    691   ** the parser code in fts5parse.y.  */

Changes to ext/fts5/fts5_aux.c.

   153    153     int nToken,                     /* Size of token in bytes */
   154    154     int iStartOff,                  /* Start offset of token */
   155    155     int iEndOff                     /* End offset of token */
   156    156   ){
   157    157     HighlightContext *p = (HighlightContext*)pContext;
   158    158     int rc = SQLITE_OK;
   159    159     int iPos;
          160  +
          161  +  UNUSED_PARAM2(pToken, nToken);
   160    162   
   161    163     if( tflags & FTS5_TOKEN_COLOCATED ) return SQLITE_OK;
   162    164     iPos = p->iPos++;
   163    165   
   164    166     if( p->iRangeEnd>0 ){
   165    167       if( iPos<p->iRangeStart || iPos>p->iRangeEnd ) return SQLITE_OK;
   166    168       if( p->iRangeStart && iPos==p->iRangeStart ) p->iOff = iStartOff;
................................................................................
   387    389   */
   388    390   static int fts5CountCb(
   389    391     const Fts5ExtensionApi *pApi, 
   390    392     Fts5Context *pFts,
   391    393     void *pUserData                 /* Pointer to sqlite3_int64 variable */
   392    394   ){
   393    395     sqlite3_int64 *pn = (sqlite3_int64*)pUserData;
          396  +  UNUSED_PARAM2(pApi, pFts);
   394    397     (*pn)++;
   395    398     return SQLITE_OK;
   396    399   }
   397    400   
   398    401   /*
   399    402   ** Set *ppData to point to the Fts5Bm25Data object for the current query. 
   400    403   ** If the object has not already been allocated, allocate and populate it

Changes to ext/fts5/fts5_buffer.c.

   232    232   }
   233    233   
   234    234   int sqlite3Fts5PoslistWriterAppend(
   235    235     Fts5Buffer *pBuf, 
   236    236     Fts5PoslistWriter *pWriter,
   237    237     i64 iPos
   238    238   ){
   239         -  int rc;
          239  +  int rc = 0;   /* Initialized only to suppress erroneous warning from Clang */
   240    240     if( fts5BufferGrow(&rc, pBuf, 5+5+5) ) return rc;
   241    241     sqlite3Fts5PoslistSafeAppend(pBuf, &pWriter->iPrev, iPos);
   242    242     return SQLITE_OK;
   243    243   }
   244    244   
   245    245   void *sqlite3Fts5MallocZero(int *pRc, int nByte){
   246    246     void *pRet = 0;
................................................................................
   386    386           pEntry = pEntry->pNext;
   387    387           sqlite3_free(pDel);
   388    388         }
   389    389       }
   390    390       sqlite3_free(p);
   391    391     }
   392    392   }
   393         -
   394         -
   395         -

Changes to ext/fts5/fts5_config.c.

   202    202   typedef struct Fts5Enum Fts5Enum;
   203    203   
   204    204   static int fts5ConfigSetEnum(
   205    205     const Fts5Enum *aEnum, 
   206    206     const char *zEnum, 
   207    207     int *peVal
   208    208   ){
   209         -  int nEnum = strlen(zEnum);
          209  +  int nEnum = (int)strlen(zEnum);
   210    210     int i;
   211    211     int iVal = -1;
   212    212   
   213    213     for(i=0; aEnum[i].zName; i++){
   214    214       if( sqlite3_strnicmp(aEnum[i].zName, zEnum, nEnum)==0 ){
   215    215         if( iVal>=0 ) return SQLITE_ERROR;
   216    216         iVal = aEnum[i].eVal;
................................................................................
   939    939     }
   940    940   
   941    941     if( rc==SQLITE_OK ){
   942    942       pConfig->iCookie = iCookie;
   943    943     }
   944    944     return rc;
   945    945   }
   946         -

Changes to ext/fts5/fts5_expr.c.

   316    316   }
   317    317   
   318    318   /*
   319    319   ** Argument pTerm must be a synonym iterator.
   320    320   */
   321    321   static int fts5ExprSynonymList(
   322    322     Fts5ExprTerm *pTerm, 
   323         -  int bCollist, 
   324         -  Fts5Colset *pColset,
   325    323     i64 iRowid,
   326    324     Fts5Buffer *pBuf,               /* Use this buffer for space if required */
   327    325     u8 **pa, int *pn
   328    326   ){
   329    327     Fts5PoslistReader aStatic[4];
   330    328     Fts5PoslistReader *aIter = aStatic;
   331    329     int nIter = 0;
................................................................................
   401    399   **
   402    400   ** SQLITE_OK is returned if an error occurs, or an SQLite error code 
   403    401   ** otherwise. It is not considered an error code if the current rowid is 
   404    402   ** not a match.
   405    403   */
   406    404   static int fts5ExprPhraseIsMatch(
   407    405     Fts5ExprNode *pNode,            /* Node pPhrase belongs to */
   408         -  Fts5Colset *pColset,            /* Restrict matches to these columns */
   409    406     Fts5ExprPhrase *pPhrase,        /* Phrase object to initialize */
   410    407     int *pbMatch                    /* OUT: Set to true if really a match */
   411    408   ){
   412    409     Fts5PoslistWriter writer = {0};
   413    410     Fts5PoslistReader aStatic[4];
   414    411     Fts5PoslistReader *aIter = aStatic;
   415    412     int i;
................................................................................
   430    427     for(i=0; i<pPhrase->nTerm; i++){
   431    428       Fts5ExprTerm *pTerm = &pPhrase->aTerm[i];
   432    429       int n = 0;
   433    430       int bFlag = 0;
   434    431       u8 *a = 0;
   435    432       if( pTerm->pSynonym ){
   436    433         Fts5Buffer buf = {0, 0, 0};
   437         -      rc = fts5ExprSynonymList(
   438         -          pTerm, 0, pColset, pNode->iRowid, &buf, &a, &n
   439         -      );
          434  +      rc = fts5ExprSynonymList(pTerm, pNode->iRowid, &buf, &a, &n);
   440    435         if( rc ){
   441    436           sqlite3_free(a);
   442    437           goto ismatch_out;
   443    438         }
   444    439         if( a==buf.p ) bFlag = 1;
   445    440       }else{
   446    441         a = (u8*)pTerm->pIter->pData;
................................................................................
   723    718       /* Check that each phrase in the nearset matches the current row.
   724    719       ** Populate the pPhrase->poslist buffers at the same time. If any
   725    720       ** phrase is not a match, break out of the loop early.  */
   726    721       for(i=0; rc==SQLITE_OK && i<pNear->nPhrase; i++){
   727    722         Fts5ExprPhrase *pPhrase = pNear->apPhrase[i];
   728    723         if( pPhrase->nTerm>1 || pPhrase->aTerm[0].pSynonym || pNear->pColset ){
   729    724           int bMatch = 0;
   730         -        rc = fts5ExprPhraseIsMatch(pNode, pNear->pColset, pPhrase, &bMatch);
          725  +        rc = fts5ExprPhraseIsMatch(pNode, pPhrase, &bMatch);
   731    726           if( bMatch==0 ) break;
   732    727         }else{
   733    728           Fts5IndexIter *pIter = pPhrase->aTerm[0].pIter;
   734    729           fts5BufferSet(&rc, &pPhrase->poslist, pIter->nData, pIter->pData);
   735    730         }
   736    731       }
   737    732   
................................................................................
  1471   1466     int iUnused1,                   /* Start offset of token */
  1472   1467     int iUnused2                    /* End offset of token */
  1473   1468   ){
  1474   1469     int rc = SQLITE_OK;
  1475   1470     const int SZALLOC = 8;
  1476   1471     TokenCtx *pCtx = (TokenCtx*)pContext;
  1477   1472     Fts5ExprPhrase *pPhrase = pCtx->pPhrase;
         1473  +
         1474  +  UNUSED_PARAM2(iUnused1, iUnused2);
  1478   1475   
  1479   1476     /* If an error has already occurred, this is a no-op */
  1480   1477     if( pCtx->rc!=SQLITE_OK ) return pCtx->rc;
  1481   1478   
  1482   1479     assert( pPhrase==0 || pPhrase->nTerm>0 );
  1483   1480     if( pPhrase && (tflags & FTS5_TOKEN_COLOCATED) ){
  1484   1481       Fts5ExprTerm *pSyn;
................................................................................
  1607   1604   }
  1608   1605   
  1609   1606   /*
  1610   1607   ** Create a new FTS5 expression by cloning phrase iPhrase of the
  1611   1608   ** expression passed as the second argument.
  1612   1609   */
  1613   1610   int sqlite3Fts5ExprClonePhrase(
  1614         -  Fts5Config *pConfig,
  1615   1611     Fts5Expr *pExpr, 
  1616   1612     int iPhrase, 
  1617   1613     Fts5Expr **ppNew
  1618   1614   ){
  1619   1615     int rc = SQLITE_OK;             /* Return code */
  1620   1616     Fts5ExprPhrase *pOrig;          /* The phrase extracted from pExpr */
  1621   1617     int i;                          /* Used to iterate through phrase terms */
  1622         -
  1623   1618     Fts5Expr *pNew = 0;             /* Expression to return via *ppNew */
  1624         -
  1625   1619     TokenCtx sCtx = {0,0};          /* Context object for fts5ParseTokenize */
  1626   1620   
  1627         -
  1628   1621     pOrig = pExpr->apExprPhrase[iPhrase];
  1629         -
  1630   1622     pNew = (Fts5Expr*)sqlite3Fts5MallocZero(&rc, sizeof(Fts5Expr));
  1631   1623     if( rc==SQLITE_OK ){
  1632   1624       pNew->apExprPhrase = (Fts5ExprPhrase**)sqlite3Fts5MallocZero(&rc, 
  1633   1625           sizeof(Fts5ExprPhrase*));
  1634   1626     }
  1635   1627     if( rc==SQLITE_OK ){
  1636   1628       pNew->pRoot = (Fts5ExprNode*)sqlite3Fts5MallocZero(&rc, 
................................................................................
  2395   2387   }
  2396   2388   
  2397   2389   static int fts5ExprPopulatePoslistsCb(
  2398   2390     void *pCtx,                /* Copy of 2nd argument to xTokenize() */
  2399   2391     int tflags,                /* Mask of FTS5_TOKEN_* flags */
  2400   2392     const char *pToken,        /* Pointer to buffer containing token */
  2401   2393     int nToken,                /* Size of token in bytes */
  2402         -  int iStart,                /* Byte offset of token within input text */
  2403         -  int iEnd                   /* Byte offset of end of token within input text */
         2394  +  int iUnused1,              /* Byte offset of token within input text */
         2395  +  int iUnused2               /* Byte offset of end of token within input text */
  2404   2396   ){
  2405   2397     Fts5ExprCtx *p = (Fts5ExprCtx*)pCtx;
  2406   2398     Fts5Expr *pExpr = p->pExpr;
  2407   2399     int i;
         2400  +
         2401  +  UNUSED_PARAM2(iUnused1, iUnused2);
  2408   2402   
  2409   2403     if( (tflags & FTS5_TOKEN_COLOCATED)==0 ) p->iOff++;
  2410   2404     for(i=0; i<pExpr->nPhrase; i++){
  2411   2405       Fts5ExprTerm *pTerm;
  2412   2406       if( p->aPopulator[i].bOk==0 ) continue;
  2413   2407       for(pTerm=&pExpr->apExprPhrase[i]->aTerm[0]; pTerm; pTerm=pTerm->pSynonym){
  2414   2408         int nTerm = strlen(pTerm->zTerm);
................................................................................
  2546   2540      && pNode->iRowid==pExpr->pRoot->iRowid 
  2547   2541      && pPhrase->poslist.n>0
  2548   2542     ){
  2549   2543       Fts5ExprTerm *pTerm = &pPhrase->aTerm[0];
  2550   2544       if( pTerm->pSynonym ){
  2551   2545         Fts5Buffer *pBuf = (Fts5Buffer*)&pTerm->pSynonym[1];
  2552   2546         rc = fts5ExprSynonymList(
  2553         -          pTerm, 1, 0, pNode->iRowid, pBuf, (u8**)ppCollist, pnCollist
         2547  +          pTerm, pNode->iRowid, pBuf, (u8**)ppCollist, pnCollist
  2554   2548         );
  2555   2549       }else{
  2556   2550         *ppCollist = pPhrase->aTerm[0].pIter->pData;
  2557   2551         *pnCollist = pPhrase->aTerm[0].pIter->nData;
  2558   2552       }
  2559   2553     }else{
  2560   2554       *ppCollist = 0;
  2561   2555       *pnCollist = 0;
  2562   2556     }
  2563   2557   
  2564   2558     return rc;
  2565   2559   }
  2566   2560   

Changes to ext/fts5/fts5_hash.c.

    58     58   struct Fts5HashEntry {
    59     59     Fts5HashEntry *pHashNext;       /* Next hash entry with same hash-key */
    60     60     Fts5HashEntry *pScanNext;       /* Next entry in sorted order */
    61     61     
    62     62     int nAlloc;                     /* Total size of allocation */
    63     63     int iSzPoslist;                 /* Offset of space for 4-byte poslist size */
    64     64     int nData;                      /* Total bytes of data (incl. structure) */
           65  +  int nKey;                       /* Length of zKey[] in bytes */
    65     66     u8 bDel;                        /* Set delete-flag @ iSzPoslist */
    66     67     u8 bContent;                    /* Set content-flag (detail=none mode) */
    67         -
    68         -  int iCol;                       /* Column of last value written */
           68  +  i16 iCol;                       /* Column of last value written */
    69     69     int iPos;                       /* Position of last value written */
    70     70     i64 iRowid;                     /* Rowid of last value written */
    71     71     char zKey[8];                   /* Nul-terminated entry key */
    72     72   };
    73     73   
    74     74   /*
    75     75   ** Size of Fts5HashEntry without the zKey[] array.
................................................................................
   241    241     
   242    242     bNew = (pHash->eDetail==FTS5_DETAIL_FULL);
   243    243   
   244    244     /* Attempt to locate an existing hash entry */
   245    245     iHash = fts5HashKey2(pHash->nSlot, (u8)bByte, (const u8*)pToken, nToken);
   246    246     for(p=pHash->aSlot[iHash]; p; p=p->pHashNext){
   247    247       if( p->zKey[0]==bByte 
          248  +     && p->nKey==nToken
   248    249        && memcmp(&p->zKey[1], pToken, nToken)==0 
   249         -     && p->zKey[nToken+1]==0 
   250    250       ){
   251    251         break;
   252    252       }
   253    253     }
   254    254   
   255    255     /* If an existing hash entry cannot be found, create a new one. */
   256    256     if( p==0 ){
................................................................................
   269    269       p = (Fts5HashEntry*)sqlite3_malloc(nByte);
   270    270       if( !p ) return SQLITE_NOMEM;
   271    271       memset(p, 0, FTS5_HASHENTRYSIZE);
   272    272       p->nAlloc = nByte;
   273    273       p->zKey[0] = bByte;
   274    274       memcpy(&p->zKey[1], pToken, nToken);
   275    275       assert( iHash==fts5HashKey(pHash->nSlot, (u8*)p->zKey, nToken+1) );
          276  +    p->nKey = nToken;
   276    277       p->zKey[nToken+1] = '\0';
   277    278       p->nData = nToken+1 + 1 + FTS5_HASHENTRYSIZE;
   278    279       p->pHashNext = pHash->aSlot[iHash];
   279    280       pHash->aSlot[iHash] = p;
   280    281       pHash->nEntry++;
   281    282   
   282    283       /* Add the first rowid field to the hash-entry */

Changes to ext/fts5/fts5_index.c.

   603    603   */
   604    604   static int fts5BufferCompare(Fts5Buffer *pLeft, Fts5Buffer *pRight){
   605    605     int nCmp = MIN(pLeft->n, pRight->n);
   606    606     int res = memcmp(pLeft->p, pRight->p, nCmp);
   607    607     return (res==0 ? (pLeft->n - pRight->n) : res);
   608    608   }
   609    609   
   610         -#ifdef SQLITE_DEBUG
   611         -static int fts5BlobCompare(
   612         -  const u8 *pLeft, int nLeft, 
   613         -  const u8 *pRight, int nRight
   614         -){
   615         -  int nCmp = MIN(nLeft, nRight);
   616         -  int res = memcmp(pLeft, pRight, nCmp);
   617         -  return (res==0 ? (nLeft - nRight) : res);
   618         -}
   619         -#endif
   620         -
   621    610   static int fts5LeafFirstTermOff(Fts5Data *pLeaf){
   622    611     int ret;
   623    612     fts5GetVarint32(&pLeaf->p[pLeaf->szLeaf], ret);
   624    613     return ret;
   625    614   }
   626    615   
   627    616   /*
................................................................................
   875    864       i += sqlite3Fts5GetVarint(&pData[i], &pRet->nWriteCounter);
   876    865   
   877    866       for(iLvl=0; rc==SQLITE_OK && iLvl<nLevel; iLvl++){
   878    867         Fts5StructureLevel *pLvl = &pRet->aLevel[iLvl];
   879    868         int nTotal;
   880    869         int iSeg;
   881    870   
   882         -      i += fts5GetVarint32(&pData[i], pLvl->nMerge);
   883         -      i += fts5GetVarint32(&pData[i], nTotal);
   884         -      assert( nTotal>=pLvl->nMerge );
   885         -      pLvl->aSeg = (Fts5StructureSegment*)sqlite3Fts5MallocZero(&rc, 
   886         -          nTotal * sizeof(Fts5StructureSegment)
   887         -      );
          871  +      if( i>=nData ){
          872  +        rc = FTS5_CORRUPT;
          873  +      }else{
          874  +        i += fts5GetVarint32(&pData[i], pLvl->nMerge);
          875  +        i += fts5GetVarint32(&pData[i], nTotal);
          876  +        assert( nTotal>=pLvl->nMerge );
          877  +        pLvl->aSeg = (Fts5StructureSegment*)sqlite3Fts5MallocZero(&rc, 
          878  +            nTotal * sizeof(Fts5StructureSegment)
          879  +        );
          880  +      }
   888    881   
   889    882         if( rc==SQLITE_OK ){
   890    883           pLvl->nSeg = nTotal;
   891    884           for(iSeg=0; iSeg<nTotal; iSeg++){
          885  +          if( i>=nData ){
          886  +            rc = FTS5_CORRUPT;
          887  +            break;
          888  +          }
   892    889             i += fts5GetVarint32(&pData[i], pLvl->aSeg[iSeg].iSegid);
   893    890             i += fts5GetVarint32(&pData[i], pLvl->aSeg[iSeg].pgnoFirst);
   894    891             i += fts5GetVarint32(&pData[i], pLvl->aSeg[iSeg].pgnoLast);
   895    892           }
   896         -      }else{
   897         -        fts5StructureRelease(pRet);
   898         -        pRet = 0;
   899    893         }
          894  +    }
          895  +    if( rc!=SQLITE_OK ){
          896  +      fts5StructureRelease(pRet);
          897  +      pRet = 0;
   900    898       }
   901    899     }
   902    900   
   903    901     *ppOut = pRet;
   904    902     return rc;
   905    903   }
   906    904   
................................................................................
  1560   1558   */
  1561   1559   static void fts5SegIterLoadTerm(Fts5Index *p, Fts5SegIter *pIter, int nKeep){
  1562   1560     u8 *a = pIter->pLeaf->p;        /* Buffer to read data from */
  1563   1561     int iOff = pIter->iLeafOffset;  /* Offset to read at */
  1564   1562     int nNew;                       /* Bytes of new data */
  1565   1563   
  1566   1564     iOff += fts5GetVarint32(&a[iOff], nNew);
         1565  +  if( iOff+nNew>pIter->pLeaf->nn ){
         1566  +    p->rc = FTS5_CORRUPT;
         1567  +    return;
         1568  +  }
  1567   1569     pIter->term.n = nKeep;
  1568   1570     fts5BufferAppendBlob(&p->rc, &pIter->term, nNew, &a[iOff]);
  1569   1571     iOff += nNew;
  1570   1572     pIter->iTermLeafOffset = iOff;
  1571   1573     pIter->iTermLeafPgno = pIter->iLeafPgno;
  1572   1574     pIter->iLeafOffset = iOff;
  1573   1575   
................................................................................
  1766   1768   ** Advance iterator pIter to the next entry.
  1767   1769   **
  1768   1770   ** This version of fts5SegIterNext() is only used by reverse iterators.
  1769   1771   */
  1770   1772   static void fts5SegIterNext_Reverse(
  1771   1773     Fts5Index *p,                   /* FTS5 backend object */
  1772   1774     Fts5SegIter *pIter,             /* Iterator to advance */
  1773         -  int *pbNewTerm                  /* OUT: Set for new term */
         1775  +  int *pbUnused                   /* Unused */
  1774   1776   ){
  1775   1777     assert( pIter->flags & FTS5_SEGITER_REVERSE );
  1776   1778     assert( pIter->pNextLeaf==0 );
         1779  +  UNUSED_PARAM(pbUnused);
         1780  +
  1777   1781     if( pIter->iRowidOffset>0 ){
  1778   1782       u8 *a = pIter->pLeaf->p;
  1779   1783       int iOff;
  1780   1784       i64 iDelta;
  1781   1785   
  1782   1786       pIter->iRowidOffset--;
  1783   1787       pIter->iLeafOffset = pIter->aRowidOffset[pIter->iRowidOffset];
................................................................................
  2246   2250   ** pSeg. If there is no such term in the index, the iterator is set to EOF.
  2247   2251   **
  2248   2252   ** If an error occurs, Fts5Index.rc is set to an appropriate error code. If 
  2249   2253   ** an error has already occurred when this function is called, it is a no-op.
  2250   2254   */
  2251   2255   static void fts5SegIterSeekInit(
  2252   2256     Fts5Index *p,                   /* FTS5 backend */
  2253         -  Fts5Buffer *pBuf,               /* Buffer to use for loading pages */
  2254   2257     const u8 *pTerm, int nTerm,     /* Term to seek to */
  2255   2258     int flags,                      /* Mask of FTS5INDEX_XXX flags */
  2256   2259     Fts5StructureSegment *pSeg,     /* Description of segment */
  2257   2260     Fts5SegIter *pIter              /* Object to populate */
  2258   2261   ){
  2259   2262     int iPg = 1;
  2260   2263     int bGe = (flags & FTS5INDEX_QUERY_SCAN);
................................................................................
  2633   2636     }while( p->rc==SQLITE_OK );
  2634   2637   }
  2635   2638   
  2636   2639   
  2637   2640   /*
  2638   2641   ** Free the iterator object passed as the second argument.
  2639   2642   */
  2640         -static void fts5MultiIterFree(Fts5Index *p, Fts5Iter *pIter){
         2643  +static void fts5MultiIterFree(Fts5Iter *pIter){
  2641   2644     if( pIter ){
  2642   2645       int i;
  2643   2646       for(i=0; i<pIter->nSeg; i++){
  2644   2647         fts5SegIterClear(&pIter->aSeg[i]);
  2645   2648       }
  2646   2649       fts5StructureRelease(pIter->pStruct);
  2647   2650       fts5BufferFree(&pIter->poslist);
................................................................................
  2674   2677   ** If it does so successfully, 0 is returned. Otherwise 1.
  2675   2678   **
  2676   2679   ** If non-zero is returned, the caller should call fts5MultiIterAdvanced()
  2677   2680   ** on the iterator instead. That function does the same as this one, except
  2678   2681   ** that it deals with more complicated cases as well.
  2679   2682   */ 
  2680   2683   static int fts5MultiIterAdvanceRowid(
  2681         -  Fts5Index *p,                   /* FTS5 backend to iterate within */
  2682   2684     Fts5Iter *pIter,                /* Iterator to update aFirst[] array for */
  2683   2685     int iChanged,                   /* Index of sub-iterator just advanced */
  2684   2686     Fts5SegIter **ppFirst
  2685   2687   ){
  2686   2688     Fts5SegIter *pNew = &pIter->aSeg[iChanged];
  2687   2689   
  2688   2690     if( pNew->iRowid==pIter->iSwitchRowid
................................................................................
  2749   2751       if( bUseFrom && pSeg->pDlidx ){
  2750   2752         fts5SegIterNextFrom(p, pSeg, iFrom);
  2751   2753       }else{
  2752   2754         pSeg->xNext(p, pSeg, &bNewTerm);
  2753   2755       }
  2754   2756   
  2755   2757       if( pSeg->pLeaf==0 || bNewTerm 
  2756         -     || fts5MultiIterAdvanceRowid(p, pIter, iFirst, &pSeg)
         2758  +     || fts5MultiIterAdvanceRowid(pIter, iFirst, &pSeg)
  2757   2759       ){
  2758   2760         fts5MultiIterAdvanced(p, pIter, iFirst, 1);
  2759   2761         fts5MultiIterSetEof(pIter);
  2760   2762         pSeg = &pIter->aSeg[pIter->aFirst[1].iFirst];
  2761   2763         if( pSeg->pLeaf==0 ) return;
  2762   2764       }
  2763   2765   
................................................................................
  2782   2784         int iFirst = pIter->aFirst[1].iFirst;
  2783   2785         Fts5SegIter *pSeg = &pIter->aSeg[iFirst];
  2784   2786         int bNewTerm = 0;
  2785   2787   
  2786   2788         assert( p->rc==SQLITE_OK );
  2787   2789         pSeg->xNext(p, pSeg, &bNewTerm);
  2788   2790         if( pSeg->pLeaf==0 || bNewTerm 
  2789         -       || fts5MultiIterAdvanceRowid(p, pIter, iFirst, &pSeg)
         2791  +       || fts5MultiIterAdvanceRowid(pIter, iFirst, &pSeg)
  2790   2792         ){
  2791   2793           fts5MultiIterAdvanced(p, pIter, iFirst, 1);
  2792   2794           fts5MultiIterSetEof(pIter);
  2793   2795           *pbNewTerm = 1;
  2794   2796         }else{
  2795   2797           *pbNewTerm = 0;
  2796   2798         }
  2797   2799         fts5AssertMultiIterSetup(p, pIter);
  2798   2800   
  2799   2801       }while( fts5MultiIterIsEmpty(p, pIter) );
  2800   2802     }
  2801   2803   }
  2802   2804   
  2803         -static void fts5IterSetOutputs_Noop(Fts5Iter *pIter, Fts5SegIter *pSeg){
         2805  +static void fts5IterSetOutputs_Noop(Fts5Iter *pUnused1, Fts5SegIter *pUnused2){
         2806  +  UNUSED_PARAM2(pUnused1, pUnused2);
  2804   2807   }
  2805   2808   
  2806   2809   static Fts5Iter *fts5MultiIterAlloc(
  2807   2810     Fts5Index *p,                   /* FTS5 backend to iterate within */
  2808   2811     int nSeg
  2809   2812   ){
  2810   2813     Fts5Iter *pNew;
................................................................................
  2822   2825       pNew->pIndex = p;
  2823   2826       pNew->xSetOutputs = fts5IterSetOutputs_Noop;
  2824   2827     }
  2825   2828     return pNew;
  2826   2829   }
  2827   2830   
  2828   2831   static void fts5PoslistCallback(
  2829         -  Fts5Index *p, 
         2832  +  Fts5Index *pUnused, 
  2830   2833     void *pContext, 
  2831   2834     const u8 *pChunk, int nChunk
  2832   2835   ){
         2836  +  UNUSED_PARAM(pUnused);
  2833   2837     assert_nc( nChunk>=0 );
  2834   2838     if( nChunk>0 ){
  2835   2839       fts5BufferSafeAppendBlob((Fts5Buffer*)pContext, pChunk, nChunk);
  2836   2840     }
  2837   2841   }
  2838   2842   
  2839   2843   typedef struct PoslistCallbackCtx PoslistCallbackCtx;
................................................................................
  2859   2863     for(i=0; i<pColset->nCol; i++){
  2860   2864       if( pColset->aiCol[i]==iCol ) return 1;
  2861   2865     }
  2862   2866     return 0;
  2863   2867   }
  2864   2868   
  2865   2869   static void fts5PoslistOffsetsCallback(
  2866         -  Fts5Index *p, 
         2870  +  Fts5Index *pUnused, 
  2867   2871     void *pContext, 
  2868   2872     const u8 *pChunk, int nChunk
  2869   2873   ){
  2870   2874     PoslistOffsetsCtx *pCtx = (PoslistOffsetsCtx*)pContext;
         2875  +  UNUSED_PARAM(pUnused);
  2871   2876     assert_nc( nChunk>=0 );
  2872   2877     if( nChunk>0 ){
  2873   2878       int i = 0;
  2874   2879       while( i<nChunk ){
  2875   2880         int iVal;
  2876   2881         i += fts5GetVarint32(&pChunk[i], iVal);
  2877   2882         iVal += pCtx->iRead - 2;
................................................................................
  2881   2886           pCtx->iWrite = iVal;
  2882   2887         }
  2883   2888       }
  2884   2889     }
  2885   2890   }
  2886   2891   
  2887   2892   static void fts5PoslistFilterCallback(
  2888         -  Fts5Index *p, 
         2893  +  Fts5Index *pUnused,
  2889   2894     void *pContext, 
  2890   2895     const u8 *pChunk, int nChunk
  2891   2896   ){
  2892   2897     PoslistCallbackCtx *pCtx = (PoslistCallbackCtx*)pContext;
         2898  +  UNUSED_PARAM(pUnused);
  2893   2899     assert_nc( nChunk>=0 );
  2894   2900     if( nChunk>0 ){
  2895   2901       /* Search through to find the first varint with value 1. This is the
  2896   2902       ** start of the next columns hits. */
  2897   2903       int i = 0;
  2898   2904       int iStart = 0;
  2899   2905   
................................................................................
  3249   3255     int iLevel,                     /* Level to iterate (-1 for all) */
  3250   3256     int nSegment,                   /* Number of segments to merge (iLevel>=0) */
  3251   3257     Fts5Iter **ppOut                /* New object */
  3252   3258   ){
  3253   3259     int nSeg = 0;                   /* Number of segment-iters in use */
  3254   3260     int iIter = 0;                  /* */
  3255   3261     int iSeg;                       /* Used to iterate through segments */
  3256         -  Fts5Buffer buf = {0,0,0};       /* Buffer used by fts5SegIterSeekInit() */
  3257   3262     Fts5StructureLevel *pLvl;
  3258   3263     Fts5Iter *pNew;
  3259   3264   
  3260   3265     assert( (pTerm==0 && nTerm==0) || iLevel<0 );
  3261   3266   
  3262   3267     /* Allocate space for the new multi-seg-iterator. */
  3263   3268     if( p->rc==SQLITE_OK ){
................................................................................
  3292   3297         for(pLvl=&pStruct->aLevel[0]; pLvl<pEnd; pLvl++){
  3293   3298           for(iSeg=pLvl->nSeg-1; iSeg>=0; iSeg--){
  3294   3299             Fts5StructureSegment *pSeg = &pLvl->aSeg[iSeg];
  3295   3300             Fts5SegIter *pIter = &pNew->aSeg[iIter++];
  3296   3301             if( pTerm==0 ){
  3297   3302               fts5SegIterInit(p, pSeg, pIter);
  3298   3303             }else{
  3299         -            fts5SegIterSeekInit(p, &buf, pTerm, nTerm, flags, pSeg, pIter);
         3304  +            fts5SegIterSeekInit(p, pTerm, nTerm, flags, pSeg, pIter);
  3300   3305             }
  3301   3306           }
  3302   3307         }
  3303   3308       }else{
  3304   3309         pLvl = &pStruct->aLevel[iLevel];
  3305   3310         for(iSeg=nSeg-1; iSeg>=0; iSeg--){
  3306   3311           fts5SegIterInit(p, &pLvl->aSeg[iSeg], &pNew->aSeg[iIter++]);
................................................................................
  3329   3334         fts5MultiIterNext(p, pNew, 0, 0);
  3330   3335       }else if( pNew->base.bEof==0 ){
  3331   3336         Fts5SegIter *pSeg = &pNew->aSeg[pNew->aFirst[1].iFirst];
  3332   3337         pNew->xSetOutputs(pNew, pSeg);
  3333   3338       }
  3334   3339   
  3335   3340     }else{
  3336         -    fts5MultiIterFree(p, pNew);
         3341  +    fts5MultiIterFree(pNew);
  3337   3342       *ppOut = 0;
  3338   3343     }
  3339         -  fts5BufferFree(&buf);
  3340         -
  3341   3344   }
  3342   3345   
  3343   3346   /*
  3344   3347   ** Create an Fts5Iter that iterates through the doclist provided
  3345   3348   ** as the second argument.
  3346   3349   */
  3347   3350   static void fts5MultiIterNew2(
................................................................................
  3471   3474     if( p->pHash ){
  3472   3475       sqlite3Fts5HashClear(p->pHash);
  3473   3476       p->nPendingData = 0;
  3474   3477     }
  3475   3478   }
  3476   3479   
  3477   3480   /*
  3478         -** Return the size of the prefix, in bytes, that buffer (nNew/pNew) shares
  3479         -** with buffer (nOld/pOld).
         3481  +** Return the size of the prefix, in bytes, that buffer 
         3482  +** (pNew/<length-unknown>) shares with buffer (pOld/nOld).
         3483  +**
         3484  +** Buffer (pNew/<length-unknown>) is guaranteed to be greater 
         3485  +** than buffer (pOld/nOld).
  3480   3486   */
  3481         -static int fts5PrefixCompress(
  3482         -  int nOld, const u8 *pOld,
  3483         -  int nNew, const u8 *pNew
  3484         -){
         3487  +static int fts5PrefixCompress(int nOld, const u8 *pOld, const u8 *pNew){
  3485   3488     int i;
  3486         -  assert( fts5BlobCompare(pOld, nOld, pNew, nNew)<0 );
  3487   3489     for(i=0; i<nOld; i++){
  3488   3490       if( pOld[i]!=pNew[i] ) break;
  3489   3491     }
  3490   3492     return i;
  3491   3493   }
  3492   3494   
  3493   3495   static void fts5WriteDlidxClear(
................................................................................
  3789   3791         ** Usually, the previous term is available in pPage->term. The exception
  3790   3792         ** is if this is the first term written in an incremental-merge step.
  3791   3793         ** In this case the previous term is not available, so just write a
  3792   3794         ** copy of (pTerm/nTerm) into the parent node. This is slightly
  3793   3795         ** inefficient, but still correct.  */
  3794   3796         int n = nTerm;
  3795   3797         if( pPage->term.n ){
  3796         -        n = 1 + fts5PrefixCompress(pPage->term.n, pPage->term.p, nTerm, pTerm);
         3798  +        n = 1 + fts5PrefixCompress(pPage->term.n, pPage->term.p, pTerm);
  3797   3799         }
  3798   3800         fts5WriteBtreeTerm(p, pWriter, n, pTerm);
  3799   3801         pPage = &pWriter->writer;
  3800   3802       }
  3801   3803     }else{
  3802         -    nPrefix = fts5PrefixCompress(pPage->term.n, pPage->term.p, nTerm, pTerm);
         3804  +    nPrefix = fts5PrefixCompress(pPage->term.n, pPage->term.p, pTerm);
  3803   3805       fts5BufferAppendVarint(&p->rc, &pPage->buf, nPrefix);
  3804   3806     }
  3805   3807   
  3806   3808     /* Append the number of bytes of new data, then the term data itself
  3807   3809     ** to the page. */
  3808   3810     fts5BufferAppendVarint(&p->rc, &pPage->buf, nTerm - nPrefix);
  3809   3811     fts5BufferAppendBlob(&p->rc, &pPage->buf, nTerm - nPrefix, &pTerm[nPrefix]);
................................................................................
  4161   4163       }
  4162   4164     }else{
  4163   4165       assert( pSeg->pgnoLast>0 );
  4164   4166       fts5TrimSegments(p, pIter);
  4165   4167       pLvl->nMerge = nInput;
  4166   4168     }
  4167   4169   
  4168         -  fts5MultiIterFree(p, pIter);
         4170  +  fts5MultiIterFree(pIter);
  4169   4171     fts5BufferFree(&term);
  4170   4172     if( pnRem ) *pnRem -= writer.nLeafWritten;
  4171   4173   }
  4172   4174   
  4173   4175   /*
  4174   4176   ** Do up to nPg pages of automerge work on the index.
  4175   4177   */
................................................................................
  4537   4539   
  4538   4540     return fts5IndexReturn(p);
  4539   4541   }
  4540   4542   
  4541   4543   static void fts5AppendRowid(
  4542   4544     Fts5Index *p,
  4543   4545     i64 iDelta,
  4544         -  Fts5Iter *pMulti,
         4546  +  Fts5Iter *pUnused,
  4545   4547     Fts5Buffer *pBuf
  4546   4548   ){
         4549  +  UNUSED_PARAM(pUnused);
  4547   4550     fts5BufferAppendVarint(&p->rc, pBuf, iDelta);
  4548   4551   }
  4549   4552   
  4550   4553   static void fts5AppendPoslist(
  4551   4554     Fts5Index *p,
  4552   4555     i64 iDelta,
  4553   4556     Fts5Iter *pMulti,
................................................................................
  4882   4885   
  4883   4886       for(i=0; i<nBuf; i++){
  4884   4887         if( p->rc==SQLITE_OK ){
  4885   4888           xMerge(p, &doclist, &aBuf[i]);
  4886   4889         }
  4887   4890         fts5BufferFree(&aBuf[i]);
  4888   4891       }
  4889         -    fts5MultiIterFree(p, p1);
         4892  +    fts5MultiIterFree(p1);
  4890   4893   
  4891   4894       pData = fts5IdxMalloc(p, sizeof(Fts5Data) + doclist.n);
  4892   4895       if( pData ){
  4893   4896         pData->p = (u8*)&pData[1];
  4894   4897         pData->nn = pData->szLeaf = doclist.n;
  4895   4898         memcpy(pData->p, doclist.p, doclist.n);
  4896   4899         fts5MultiIterNew2(p, pData, bDesc, ppIter);
................................................................................
  5163   5166           fts5StructureRelease(pStruct);
  5164   5167         }
  5165   5168       }else{
  5166   5169         /* Scan multiple terms in the main index */
  5167   5170         int bDesc = (flags & FTS5INDEX_QUERY_DESC)!=0;
  5168   5171         buf.p[0] = FTS5_MAIN_PREFIX;
  5169   5172         fts5SetupPrefixIter(p, bDesc, buf.p, nToken+1, pColset, &pRet);
  5170         -      assert( pRet->pColset==0 );
         5173  +      assert( p->rc!=SQLITE_OK || pRet->pColset==0 );
  5171   5174         fts5IterSetOutputCb(&p->rc, pRet);
  5172   5175         if( p->rc==SQLITE_OK ){
  5173   5176           Fts5SegIter *pSeg = &pRet->aSeg[pRet->aFirst[1].iFirst];
  5174   5177           if( pSeg->pLeaf ) pRet->xSetOutputs(pRet, pSeg);
  5175   5178         }
  5176   5179       }
  5177   5180   
................................................................................
  5246   5249   /*
  5247   5250   ** Close an iterator opened by an earlier call to sqlite3Fts5IndexQuery().
  5248   5251   */
  5249   5252   void sqlite3Fts5IterClose(Fts5IndexIter *pIndexIter){
  5250   5253     if( pIndexIter ){
  5251   5254       Fts5Iter *pIter = (Fts5Iter*)pIndexIter;
  5252   5255       Fts5Index *pIndex = pIter->pIndex;
  5253         -    fts5MultiIterFree(pIter->pIndex, pIter);
         5256  +    fts5MultiIterFree(pIter);
  5254   5257       fts5CloseReader(pIndex);
  5255   5258     }
  5256   5259   }
  5257   5260   
  5258   5261   /*
  5259   5262   ** Read and decode the "averages" record from the database. 
  5260   5263   **
................................................................................
  5805   5808           int iTokOff = FTS5_POS2OFFSET(iPos);
  5806   5809           cksum2 ^= sqlite3Fts5IndexEntryCksum(iRowid, iCol, iTokOff, -1, z, n);
  5807   5810         }
  5808   5811       }
  5809   5812     }
  5810   5813     fts5TestTerm(p, &term, 0, 0, cksum2, &cksum3);
  5811   5814   
  5812         -  fts5MultiIterFree(p, pIter);
         5815  +  fts5MultiIterFree(pIter);
  5813   5816     if( p->rc==SQLITE_OK && cksum!=cksum2 ) p->rc = FTS5_CORRUPT;
  5814   5817   
  5815   5818     fts5StructureRelease(pStruct);
  5816   5819   #ifdef SQLITE_DEBUG
  5817   5820     fts5BufferFree(&term);
  5818   5821   #endif
  5819   5822     fts5BufferFree(&poslist);
................................................................................
  6042   6045     u8 *a = 0;
  6043   6046     Fts5Buffer s;                   /* Build up text to return here */
  6044   6047     int rc = SQLITE_OK;             /* Return code */
  6045   6048     int nSpace = 0;
  6046   6049     int eDetailNone = (sqlite3_user_data(pCtx)!=0);
  6047   6050   
  6048   6051     assert( nArg==2 );
         6052  +  UNUSED_PARAM(nArg);
  6049   6053     memset(&s, 0, sizeof(Fts5Buffer));
  6050   6054     iRowid = sqlite3_value_int64(apVal[0]);
  6051   6055   
  6052   6056     /* Make a copy of the second argument (a blob) in aBlob[]. The aBlob[]
  6053   6057     ** copy is followed by FTS5_DATA_ZERO_PADDING 0x00 bytes, which prevents
  6054   6058     ** buffer overreads even if the record is corrupt.  */
  6055   6059     n = sqlite3_value_bytes(apVal[1]);

Changes to ext/fts5/fts5_main.c.

  1092   1092   **   1. Full-text search using a MATCH operator.
  1093   1093   **   2. A by-rowid lookup.
  1094   1094   **   3. A full-table scan.
  1095   1095   */
  1096   1096   static int fts5FilterMethod(
  1097   1097     sqlite3_vtab_cursor *pCursor,   /* The cursor used for this query */
  1098   1098     int idxNum,                     /* Strategy index */
  1099         -  const char *idxStr,             /* Unused */
         1099  +  const char *zUnused,            /* Unused */
  1100   1100     int nVal,                       /* Number of elements in apVal */
  1101   1101     sqlite3_value **apVal           /* Arguments for the indexing scheme */
  1102   1102   ){
  1103   1103     Fts5Table *pTab = (Fts5Table*)(pCursor->pVtab);
  1104   1104     Fts5Config *pConfig = pTab->pConfig;
  1105   1105     Fts5Cursor *pCsr = (Fts5Cursor*)pCursor;
  1106   1106     int rc = SQLITE_OK;             /* Error code */
................................................................................
  1109   1109     int bOrderByRank;               /* True if ORDER BY rank */
  1110   1110     sqlite3_value *pMatch = 0;      /* <tbl> MATCH ? expression (or NULL) */
  1111   1111     sqlite3_value *pRank = 0;       /* rank MATCH ? expression (or NULL) */
  1112   1112     sqlite3_value *pRowidEq = 0;    /* rowid = ? expression (or NULL) */
  1113   1113     sqlite3_value *pRowidLe = 0;    /* rowid <= ? expression (or NULL) */
  1114   1114     sqlite3_value *pRowidGe = 0;    /* rowid >= ? expression (or NULL) */
  1115   1115     char **pzErrmsg = pConfig->pzErrmsg;
         1116  +
         1117  +  UNUSED_PARAM(zUnused);
         1118  +  UNUSED_PARAM(nVal);
  1116   1119   
  1117   1120     if( pCsr->ePlan ){
  1118   1121       fts5FreeCursorComponents(pCsr);
  1119   1122       memset(&pCsr->ePlan, 0, sizeof(Fts5Cursor) - ((u8*)&pCsr->ePlan-(u8*)pCsr));
  1120   1123     }
  1121   1124   
  1122   1125     assert( pCsr->pStmt==0 );
................................................................................
  1394   1397       }
  1395   1398     }
  1396   1399     return rc;
  1397   1400   }
  1398   1401   
  1399   1402   static int fts5SpecialDelete(
  1400   1403     Fts5Table *pTab, 
  1401         -  sqlite3_value **apVal, 
  1402         -  sqlite3_int64 *piRowid
         1404  +  sqlite3_value **apVal
  1403   1405   ){
  1404   1406     int rc = SQLITE_OK;
  1405   1407     int eType1 = sqlite3_value_type(apVal[1]);
  1406   1408     if( eType1==SQLITE_INTEGER ){
  1407   1409       sqlite3_int64 iDel = sqlite3_value_int64(apVal[1]);
  1408   1410       rc = sqlite3Fts5StorageDelete(pTab->pStorage, iDel, &apVal[2]);
  1409   1411     }
................................................................................
  1471   1473      && sqlite3_value_type(apVal[2+pConfig->nCol])!=SQLITE_NULL 
  1472   1474     ){
  1473   1475       /* A "special" INSERT op. These are handled separately. */
  1474   1476       const char *z = (const char*)sqlite3_value_text(apVal[2+pConfig->nCol]);
  1475   1477       if( pConfig->eContent!=FTS5_CONTENT_NORMAL 
  1476   1478         && 0==sqlite3_stricmp("delete", z) 
  1477   1479       ){
  1478         -      rc = fts5SpecialDelete(pTab, apVal, pRowid);
         1480  +      rc = fts5SpecialDelete(pTab, apVal);
  1479   1481       }else{
  1480   1482         rc = fts5SpecialInsert(pTab, z, apVal[2 + pConfig->nCol + 1]);
  1481   1483       }
  1482   1484     }else{
  1483   1485       /* A regular INSERT, UPDATE or DELETE statement. The trick here is that
  1484   1486       ** any conflict on the rowid value must be detected before any 
  1485   1487       ** modifications are made to the database file. There are 4 cases:
................................................................................
  1572   1574     return rc;
  1573   1575   }
  1574   1576   
  1575   1577   /*
  1576   1578   ** Implementation of xBegin() method. 
  1577   1579   */
  1578   1580   static int fts5BeginMethod(sqlite3_vtab *pVtab){
         1581  +  UNUSED_PARAM(pVtab);  /* Call below is a no-op for NDEBUG builds */
  1579   1582     fts5CheckTransactionState((Fts5Table*)pVtab, FTS5_BEGIN, 0);
  1580   1583     return SQLITE_OK;
  1581   1584   }
  1582   1585   
  1583   1586   /*
  1584   1587   ** Implementation of xCommit() method. This is a no-op. The contents of
  1585   1588   ** the pending-terms hash-table have already been flushed into the database
  1586   1589   ** by fts5SyncMethod().
  1587   1590   */
  1588   1591   static int fts5CommitMethod(sqlite3_vtab *pVtab){
         1592  +  UNUSED_PARAM(pVtab);  /* Call below is a no-op for NDEBUG builds */
  1589   1593     fts5CheckTransactionState((Fts5Table*)pVtab, FTS5_COMMIT, 0);
  1590   1594     return SQLITE_OK;
  1591   1595   }
  1592   1596   
  1593   1597   /*
  1594   1598   ** Implementation of xRollback(). Discard the contents of the pending-terms
  1595   1599   ** hash-table. Any changes made to the database are reverted by SQLite.
................................................................................
  1835   1839   static sqlite3_int64 fts5ApiRowid(Fts5Context *pCtx){
  1836   1840     return fts5CursorRowid((Fts5Cursor*)pCtx);
  1837   1841   }
  1838   1842   
  1839   1843   static int fts5ColumnSizeCb(
  1840   1844     void *pContext,                 /* Pointer to int */
  1841   1845     int tflags,
  1842         -  const char *pToken,             /* Buffer containing token */
  1843         -  int nToken,                     /* Size of token in bytes */
  1844         -  int iStart,                     /* Start offset of token */
  1845         -  int iEnd                        /* End offset of token */
         1846  +  const char *pUnused,            /* Buffer containing token */
         1847  +  int nUnused,                    /* Size of token in bytes */
         1848  +  int iUnused1,                   /* Start offset of token */
         1849  +  int iUnused2                    /* End offset of token */
  1846   1850   ){
  1847   1851     int *pCnt = (int*)pContext;
         1852  +  UNUSED_PARAM2(pUnused, nUnused);
         1853  +  UNUSED_PARAM2(iUnused1, iUnused2);
  1848   1854     if( (tflags & FTS5_TOKEN_COLOCATED)==0 ){
  1849   1855       (*pCnt)++;
  1850   1856     }
  1851   1857     return SQLITE_OK;
  1852   1858   }
  1853   1859   
  1854   1860   static int fts5ApiColumnSize(Fts5Context *pCtx, int iCol, int *pnToken){
................................................................................
  1956   1962       }
  1957   1963     }
  1958   1964   
  1959   1965     return pRet;
  1960   1966   }
  1961   1967   
  1962   1968   static void fts5ApiPhraseNext(
  1963         -  Fts5Context *pCtx, 
         1969  +  Fts5Context *pUnused, 
  1964   1970     Fts5PhraseIter *pIter, 
  1965   1971     int *piCol, int *piOff
  1966   1972   ){
         1973  +  UNUSED_PARAM(pUnused);
  1967   1974     if( pIter->a>=pIter->b ){
  1968   1975       *piCol = -1;
  1969   1976       *piOff = -1;
  1970   1977     }else{
  1971   1978       int iVal;
  1972   1979       pIter->a += fts5GetVarint32(pIter->a, iVal);
  1973   1980       if( iVal==1 ){
................................................................................
  2111   2118     Fts5Cursor *pCsr = (Fts5Cursor*)pCtx;
  2112   2119     Fts5Table *pTab = (Fts5Table*)(pCsr->base.pVtab);
  2113   2120     int rc;
  2114   2121     Fts5Cursor *pNew = 0;
  2115   2122   
  2116   2123     rc = fts5OpenMethod(pCsr->base.pVtab, (sqlite3_vtab_cursor**)&pNew);
  2117   2124     if( rc==SQLITE_OK ){
  2118         -    Fts5Config *pConf = pTab->pConfig;
  2119   2125       pNew->ePlan = FTS5_PLAN_MATCH;
  2120   2126       pNew->iFirstRowid = SMALLEST_INT64;
  2121   2127       pNew->iLastRowid = LARGEST_INT64;
  2122   2128       pNew->base.pVtab = (sqlite3_vtab*)pTab;
  2123         -    rc = sqlite3Fts5ExprClonePhrase(pConf, pCsr->pExpr, iPhrase, &pNew->pExpr);
         2129  +    rc = sqlite3Fts5ExprClonePhrase(pCsr->pExpr, iPhrase, &pNew->pExpr);
  2124   2130     }
  2125   2131   
  2126   2132     if( rc==SQLITE_OK ){
  2127   2133       for(rc = fts5CursorFirst(pTab, pNew, 0);
  2128   2134           rc==SQLITE_OK && CsrFlagTest(pNew, FTS5CSR_EOF)==0;
  2129   2135           rc = fts5NextMethod((sqlite3_vtab_cursor*)pNew)
  2130   2136       ){
................................................................................
  2329   2335   
  2330   2336   /*
  2331   2337   ** This routine implements the xFindFunction method for the FTS3
  2332   2338   ** virtual table.
  2333   2339   */
  2334   2340   static int fts5FindFunctionMethod(
  2335   2341     sqlite3_vtab *pVtab,            /* Virtual table handle */
  2336         -  int nArg,                       /* Number of SQL function arguments */
         2342  +  int nUnused,                    /* Number of SQL function arguments */
  2337   2343     const char *zName,              /* Name of SQL function */
  2338   2344     void (**pxFunc)(sqlite3_context*,int,sqlite3_value**), /* OUT: Result */
  2339   2345     void **ppArg                    /* OUT: User data for *pxFunc */
  2340   2346   ){
  2341   2347     Fts5Table *pTab = (Fts5Table*)pVtab;
  2342   2348     Fts5Auxiliary *pAux;
  2343   2349   
         2350  +  UNUSED_PARAM(nUnused);
  2344   2351     pAux = fts5FindAuxiliary(pTab, zName);
  2345   2352     if( pAux ){
  2346   2353       *pxFunc = fts5ApiCallback;
  2347   2354       *ppArg = (void*)pAux;
  2348   2355       return 1;
  2349   2356     }
  2350   2357   
................................................................................
  2366   2373   /*
  2367   2374   ** The xSavepoint() method.
  2368   2375   **
  2369   2376   ** Flush the contents of the pending-terms table to disk.
  2370   2377   */
  2371   2378   static int fts5SavepointMethod(sqlite3_vtab *pVtab, int iSavepoint){
  2372   2379     Fts5Table *pTab = (Fts5Table*)pVtab;
         2380  +  UNUSED_PARAM(iSavepoint);  /* Call below is a no-op for NDEBUG builds */
  2373   2381     fts5CheckTransactionState(pTab, FTS5_SAVEPOINT, iSavepoint);
  2374   2382     fts5TripCursors(pTab);
  2375   2383     return sqlite3Fts5StorageSync(pTab->pStorage, 0);
  2376   2384   }
  2377   2385   
  2378   2386   /*
  2379   2387   ** The xRelease() method.
  2380   2388   **
  2381   2389   ** This is a no-op.
  2382   2390   */
  2383   2391   static int fts5ReleaseMethod(sqlite3_vtab *pVtab, int iSavepoint){
  2384   2392     Fts5Table *pTab = (Fts5Table*)pVtab;
         2393  +  UNUSED_PARAM(iSavepoint);  /* Call below is a no-op for NDEBUG builds */
  2385   2394     fts5CheckTransactionState(pTab, FTS5_RELEASE, iSavepoint);
  2386   2395     fts5TripCursors(pTab);
  2387   2396     return sqlite3Fts5StorageSync(pTab->pStorage, 0);
  2388   2397   }
  2389   2398   
  2390   2399   /*
  2391   2400   ** The xRollbackTo() method.
  2392   2401   **
  2393   2402   ** Discard the contents of the pending terms table.
  2394   2403   */
  2395   2404   static int fts5RollbackToMethod(sqlite3_vtab *pVtab, int iSavepoint){
  2396   2405     Fts5Table *pTab = (Fts5Table*)pVtab;
         2406  +  UNUSED_PARAM(iSavepoint);  /* Call below is a no-op for NDEBUG builds */
  2397   2407     fts5CheckTransactionState(pTab, FTS5_ROLLBACKTO, iSavepoint);
  2398   2408     fts5TripCursors(pTab);
  2399   2409     return sqlite3Fts5StorageRollback(pTab->pStorage);
  2400   2410   }
  2401   2411   
  2402   2412   /*
  2403   2413   ** Register a new auxiliary function with global context pGlobal.
................................................................................
  2569   2579   
  2570   2580     sqlite3_free(pGlobal);
  2571   2581   }
  2572   2582   
  2573   2583   static void fts5Fts5Func(
  2574   2584     sqlite3_context *pCtx,          /* Function call context */
  2575   2585     int nArg,                       /* Number of args */
  2576         -  sqlite3_value **apVal           /* Function arguments */
         2586  +  sqlite3_value **apUnused        /* Function arguments */
  2577   2587   ){
  2578   2588     Fts5Global *pGlobal = (Fts5Global*)sqlite3_user_data(pCtx);
  2579   2589     char buf[8];
         2590  +  UNUSED_PARAM2(nArg, apUnused);
  2580   2591     assert( nArg==0 );
  2581   2592     assert( sizeof(buf)>=sizeof(pGlobal) );
  2582   2593     memcpy(buf, (void*)&pGlobal, sizeof(pGlobal));
  2583   2594     sqlite3_result_blob(pCtx, buf, sizeof(pGlobal), SQLITE_TRANSIENT);
  2584   2595   }
  2585   2596   
  2586   2597   /*
  2587   2598   ** Implementation of fts5_source_id() function.
  2588   2599   */
  2589   2600   static void fts5SourceIdFunc(
  2590   2601     sqlite3_context *pCtx,          /* Function call context */
  2591   2602     int nArg,                       /* Number of args */
  2592         -  sqlite3_value **apVal           /* Function arguments */
         2603  +  sqlite3_value **apUnused        /* Function arguments */
  2593   2604   ){
  2594   2605     assert( nArg==0 );
         2606  +  UNUSED_PARAM2(nArg, apUnused);
  2595   2607     sqlite3_result_text(pCtx, "--FTS5-SOURCE-ID--", -1, SQLITE_TRANSIENT);
  2596   2608   }
  2597   2609   
  2598   2610   static int fts5Init(sqlite3 *db){
  2599   2611     static const sqlite3_module fts5Mod = {
  2600   2612       /* iVersion      */ 2,
  2601   2613       /* xCreate       */ fts5CreateMethod,

Changes to ext/fts5/fts5_storage.c.

   358    358   ** Tokenization callback used when inserting tokens into the FTS index.
   359    359   */
   360    360   static int fts5StorageInsertCallback(
   361    361     void *pContext,                 /* Pointer to Fts5InsertCtx object */
   362    362     int tflags,
   363    363     const char *pToken,             /* Buffer containing token */
   364    364     int nToken,                     /* Size of token in bytes */
   365         -  int iStart,                     /* Start offset of token */
   366         -  int iEnd                        /* End offset of token */
          365  +  int iUnused1,                   /* Start offset of token */
          366  +  int iUnused2                    /* End offset of token */
   367    367   ){
   368    368     Fts5InsertCtx *pCtx = (Fts5InsertCtx*)pContext;
   369    369     Fts5Index *pIdx = pCtx->pStorage->pIndex;
          370  +  UNUSED_PARAM2(iUnused1, iUnused2);
   370    371     if( (tflags & FTS5_TOKEN_COLOCATED)==0 || pCtx->szCol==0 ){
   371    372       pCtx->szCol++;
   372    373     }
   373    374     return sqlite3Fts5IndexWrite(pIdx, pCtx->iCol, pCtx->szCol-1, pToken, nToken);
   374    375   }
   375    376   
   376    377   /*
................................................................................
   793    794   ** Tokenization callback used by integrity check.
   794    795   */
   795    796   static int fts5StorageIntegrityCallback(
   796    797     void *pContext,                 /* Pointer to Fts5IntegrityCtx object */
   797    798     int tflags,
   798    799     const char *pToken,             /* Buffer containing token */
   799    800     int nToken,                     /* Size of token in bytes */
   800         -  int iStart,                     /* Start offset of token */
   801         -  int iEnd                        /* End offset of token */
          801  +  int iUnused1,                   /* Start offset of token */
          802  +  int iUnused2                    /* End offset of token */
   802    803   ){
   803    804     Fts5IntegrityCtx *pCtx = (Fts5IntegrityCtx*)pContext;
   804    805     Fts5Termset *pTermset = pCtx->pTermset;
   805    806     int bPresent;
   806    807     int ii;
   807    808     int rc = SQLITE_OK;
   808    809     int iPos;
   809    810     int iCol;
          811  +
          812  +  UNUSED_PARAM2(iUnused1, iUnused2);
   810    813   
   811    814     if( (tflags & FTS5_TOKEN_COLOCATED)==0 || pCtx->szCol==0 ){
   812    815       pCtx->szCol++;
   813    816     }
   814    817   
   815    818     switch( pCtx->pConfig->eDetail ){
   816    819       case FTS5_DETAIL_FULL:

Changes to ext/fts5/fts5_tokenize.c.

    58     58     sqlite3_free(p);
    59     59   }
    60     60   
    61     61   /*
    62     62   ** Create an "ascii" tokenizer.
    63     63   */
    64     64   static int fts5AsciiCreate(
    65         -  void *pCtx, 
           65  +  void *pUnused, 
    66     66     const char **azArg, int nArg,
    67     67     Fts5Tokenizer **ppOut
    68     68   ){
    69     69     int rc = SQLITE_OK;
    70     70     AsciiTokenizer *p = 0;
           71  +  UNUSED_PARAM(pUnused);
    71     72     if( nArg%2 ){
    72     73       rc = SQLITE_ERROR;
    73     74     }else{
    74     75       p = sqlite3_malloc(sizeof(AsciiTokenizer));
    75     76       if( p==0 ){
    76     77         rc = SQLITE_NOMEM;
    77     78       }else{
................................................................................
   112    113   
   113    114   /*
   114    115   ** Tokenize some text using the ascii tokenizer.
   115    116   */
   116    117   static int fts5AsciiTokenize(
   117    118     Fts5Tokenizer *pTokenizer,
   118    119     void *pCtx,
   119         -  int flags,
          120  +  int iUnused,
   120    121     const char *pText, int nText,
   121    122     int (*xToken)(void*, int, const char*, int nToken, int iStart, int iEnd)
   122    123   ){
   123    124     AsciiTokenizer *p = (AsciiTokenizer*)pTokenizer;
   124    125     int rc = SQLITE_OK;
   125    126     int ie;
   126    127     int is = 0;
   127    128   
   128    129     char aFold[64];
   129    130     int nFold = sizeof(aFold);
   130    131     char *pFold = aFold;
   131    132     unsigned char *a = p->aTokenChar;
          133  +
          134  +  UNUSED_PARAM(iUnused);
   132    135   
   133    136     while( is<nText && rc==SQLITE_OK ){
   134    137       int nByte;
   135    138   
   136    139       /* Skip any leading divider characters. */
   137    140       while( is<nText && ((pText[is]&0x80)==0 && a[(int)pText[is]]==0) ){
   138    141         is++;
................................................................................
   319    322     return;
   320    323   }
   321    324   
   322    325   /*
   323    326   ** Create a "unicode61" tokenizer.
   324    327   */
   325    328   static int fts5UnicodeCreate(
   326         -  void *pCtx, 
          329  +  void *pUnused, 
   327    330     const char **azArg, int nArg,
   328    331     Fts5Tokenizer **ppOut
   329    332   ){
   330    333     int rc = SQLITE_OK;             /* Return code */
   331    334     Unicode61Tokenizer *p = 0;      /* New tokenizer object */ 
          335  +
          336  +  UNUSED_PARAM(pUnused);
   332    337   
   333    338     if( nArg%2 ){
   334    339       rc = SQLITE_ERROR;
   335    340     }else{
   336    341       p = (Unicode61Tokenizer*)sqlite3_malloc(sizeof(Unicode61Tokenizer));
   337    342       if( p ){
   338    343         int i;
................................................................................
   382    387     assert( (sqlite3Fts5UnicodeIsalnum(iCode) & 0xFFFFFFFE)==0 );
   383    388     return sqlite3Fts5UnicodeIsalnum(iCode) ^ fts5UnicodeIsException(p, iCode);
   384    389   }
   385    390   
   386    391   static int fts5UnicodeTokenize(
   387    392     Fts5Tokenizer *pTokenizer,
   388    393     void *pCtx,
   389         -  int flags,
          394  +  int iUnused,
   390    395     const char *pText, int nText,
   391    396     int (*xToken)(void*, int, const char*, int nToken, int iStart, int iEnd)
   392    397   ){
   393    398     Unicode61Tokenizer *p = (Unicode61Tokenizer*)pTokenizer;
   394    399     int rc = SQLITE_OK;
   395    400     unsigned char *a = p->aTokenChar;
   396    401   
................................................................................
   397    402     unsigned char *zTerm = (unsigned char*)&pText[nText];
   398    403     unsigned char *zCsr = (unsigned char *)pText;
   399    404   
   400    405     /* Output buffer */
   401    406     char *aFold = p->aFold;
   402    407     int nFold = p->nFold;
   403    408     const char *pEnd = &aFold[nFold-6];
          409  +
          410  +  UNUSED_PARAM(iUnused);
   404    411   
   405    412     /* Each iteration of this loop gobbles up a contiguous run of separators,
   406    413     ** then the next token.  */
   407    414     while( rc==SQLITE_OK ){
   408    415       int iCode;                    /* non-ASCII codepoint read from input */
   409    416       char *zOut = aFold;
   410    417       int is;

Changes to ext/fts5/fts5_unicode2.c.

   121    121       0x07D9140B, 0x07DA0046, 0x07DC0074, 0x38000401, 0x38008060,
   122    122       0x380400F0,
   123    123     };
   124    124     static const unsigned int aAscii[4] = {
   125    125       0xFFFFFFFF, 0xFC00FFFF, 0xF8000001, 0xF8000001,
   126    126     };
   127    127   
   128         -  if( c<128 ){
          128  +  if( (unsigned int)c<128 ){
   129    129       return ( (aAscii[c >> 5] & (1 << (c & 0x001F)))==0 );
   130         -  }else if( c<(1<<22) ){
          130  +  }else if( (unsigned int)c<(1<<22) ){
   131    131       unsigned int key = (((unsigned int)c)<<10) | 0x000003FF;
   132    132       int iRes = 0;
   133    133       int iHi = sizeof(aEntry)/sizeof(aEntry[0]) - 1;
   134    134       int iLo = 0;
   135    135       while( iHi>=iLo ){
   136    136         int iTest = (iHi + iLo) / 2;
   137    137         if( key >= aEntry[iTest] ){

Changes to ext/fts5/fts5_vocab.c.

   233    233     return fts5VocabInitVtab(db, pAux, argc, argv, ppVtab, pzErr);
   234    234   }
   235    235   
   236    236   /* 
   237    237   ** Implementation of the xBestIndex method.
   238    238   */
   239    239   static int fts5VocabBestIndexMethod(
   240         -  sqlite3_vtab *pVTab, 
          240  +  sqlite3_vtab *pUnused,
   241    241     sqlite3_index_info *pInfo
   242    242   ){
   243    243     int i;
   244    244     int iTermEq = -1;
   245    245     int iTermGe = -1;
   246    246     int iTermLe = -1;
   247    247     int idxNum = 0;
   248    248     int nArg = 0;
          249  +
          250  +  UNUSED_PARAM(pUnused);
   249    251   
   250    252     for(i=0; i<pInfo->nConstraint; i++){
   251    253       struct sqlite3_index_constraint *p = &pInfo->aConstraint[i];
   252    254       if( p->usable==0 ) continue;
   253    255       if( p->iColumn==0 ){          /* term column */
   254    256         if( p->op==SQLITE_INDEX_CONSTRAINT_EQ ) iTermEq = i;
   255    257         if( p->op==SQLITE_INDEX_CONSTRAINT_LE ) iTermLe = i;
................................................................................
   484    486   
   485    487   /*
   486    488   ** This is the xFilter implementation for the virtual table.
   487    489   */
   488    490   static int fts5VocabFilterMethod(
   489    491     sqlite3_vtab_cursor *pCursor,   /* The cursor used for this query */
   490    492     int idxNum,                     /* Strategy index */
   491         -  const char *idxStr,             /* Unused */
   492         -  int nVal,                       /* Number of elements in apVal */
          493  +  const char *zUnused,            /* Unused */
          494  +  int nUnused,                    /* Number of elements in apVal */
   493    495     sqlite3_value **apVal           /* Arguments for the indexing scheme */
   494    496   ){
   495    497     Fts5VocabCursor *pCsr = (Fts5VocabCursor*)pCursor;
   496    498     int rc = SQLITE_OK;
   497    499   
   498    500     int iVal = 0;
   499    501     int f = FTS5INDEX_QUERY_SCAN;
   500    502     const char *zTerm = 0;
   501    503     int nTerm = 0;
   502    504   
   503    505     sqlite3_value *pEq = 0;
   504    506     sqlite3_value *pGe = 0;
   505    507     sqlite3_value *pLe = 0;
          508  +
          509  +  UNUSED_PARAM2(zUnused, nUnused);
   506    510   
   507    511     fts5VocabResetCursor(pCsr);
   508    512     if( idxNum & FTS5_VOCAB_TERM_EQ ) pEq = apVal[iVal++];
   509    513     if( idxNum & FTS5_VOCAB_TERM_GE ) pGe = apVal[iVal++];
   510    514     if( idxNum & FTS5_VOCAB_TERM_LE ) pLe = apVal[iVal++];
   511    515   
   512    516     if( pEq ){

Changes to ext/fts5/fts5parse.y.

    24     24   
    25     25   // The generated parser function takes a 4th argument as follows:
    26     26   %extra_argument {Fts5Parse *pParse}
    27     27   
    28     28   // This code runs whenever there is a syntax error
    29     29   //
    30     30   %syntax_error {
           31  +  UNUSED_PARAM(yymajor); /* Silence a compiler warning */
    31     32     sqlite3Fts5ParseError(
    32     33       pParse, "fts5: syntax error near \"%.*s\"",TOKEN.n,TOKEN.p
    33     34     );
    34     35   }
    35     36   %stack_overflow {
    36         -  assert( 0 );
           37  +  UNUSED_PARAM(yypMinor); /* Silence a compiler warning */
           38  +  sqlite3Fts5ParseError(pParse, "fts5: parser stack overflow");
    37     39   }
    38     40   
    39     41   // The name of the generated procedure that implements the parser
    40     42   // is as follows:
    41     43   %name sqlite3Fts5Parser
    42     44   
    43     45   // The following text is included near the beginning of the C source

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

   330    330       WHERE id>100;
   331    331   }
   332    332   do_catchsql_test 6.3.5 {
   333    333     INSERT INTO t1(t1) VALUES('integrity-check');
   334    334   } {1 {database disk image is malformed}}
   335    335   
   336    336   
   337         -}
   338         -
   339    337   #------------------------------------------------------------------------
   340    338   #
   341         -reset_db
   342    339   reset_db
   343    340   proc rnddoc {n} {
   344    341     set map [list a b c d]
   345    342     set doc [list]
   346    343     for {set i 0} {$i < $n} {incr i} {
   347    344       lappend doc "x[lindex $map [expr int(rand()*4)]]"
   348    345     }
................................................................................
   367    364       db eval {DELETE FROM t5_data WHERE rowid = $i}
   368    365       set r [catchsql { INSERT INTO t5(t5) VALUES('integrity-check')} ]
   369    366       if {$r != "1 {database disk image is malformed}"} { error $r }
   370    367       db eval ROLLBACK  
   371    368     }
   372    369   } {}
   373    370   
          371  +}
          372  +
          373  +#------------------------------------------------------------------------
          374  +# Corruption within the structure record.
          375  +#
          376  +reset_db
          377  +do_execsql_test 8.1 {
          378  +  CREATE VIRTUAL TABLE t1 USING fts5(x, y);
          379  +  INSERT INTO t1 VALUES('one', 'two');
          380  +}
          381  +
          382  +do_test 9.1.1 {
          383  +  set    blob "12345678"    ;# cookie
          384  +  append blob "0105"        ;# 1 level, total of 5 segments
          385  +  append blob "06"          ;# write counter
          386  +  append blob "0002"        ;# first level has 0 segments merging, 2 other.
          387  +  append blob "450108"      ;# first segment
          388  +  execsql "REPLACE INTO t1_data VALUES(10, X'$blob')"
          389  +} {}
          390  +do_catchsql_test 9.1.2 {
          391  +  SELECT * FROM t1('one AND two');
          392  +} {1 {database disk image is malformed}}
          393  +
          394  +do_test 9.2.1 {
          395  +  set    blob "12345678"    ;# cookie
          396  +  append blob "0205"        ;# 2 levels, total of 5 segments
          397  +  append blob "06"          ;# write counter
          398  +  append blob "0001"        ;# first level has 0 segments merging, 1 other.
          399  +  append blob "450108"      ;# first segment
          400  +  execsql "REPLACE INTO t1_data VALUES(10, X'$blob')"
          401  +} {}
          402  +do_catchsql_test 9.2.2 {
          403  +  SELECT * FROM t1('one AND two');
          404  +} {1 {database disk image is malformed}}
          405  +
   374    406   sqlite3_fts5_may_be_corrupt 0
   375    407   finish_test
   376    408   

Changes to ext/fts5/test/fts5hash.test.

    62     62       lappend doc [lindex $vocab $j]
    63     63     }
    64     64     return $doc
    65     65   }
    66     66   
    67     67   foreach_detail_mode $testprefix {
    68     68   
    69         -set vocab [build_vocab1]
    70         -db func r random_doc 
    71         -
    72         -do_execsql_test 1.0 {
    73         -  CREATE VIRTUAL TABLE eee USING fts5(e, ee, detail=%DETAIL%);
    74         -  BEGIN;
    75         -    WITH ii(i) AS (SELECT 1 UNION ALL SELECT i+1 FROM ii WHERE i<100)
    76         -    INSERT INTO eee SELECT r($vocab, 5), r($vocab, 7) FROM ii;
           69  +  set vocab [build_vocab1]
           70  +  db func r random_doc 
           71  +  
           72  +  do_execsql_test 1.0 {
           73  +    CREATE VIRTUAL TABLE eee USING fts5(e, ee, detail=%DETAIL%);
           74  +    BEGIN;
           75  +      WITH ii(i) AS (SELECT 1 UNION ALL SELECT i+1 FROM ii WHERE i<100)
           76  +      INSERT INTO eee SELECT r($vocab, 5), r($vocab, 7) FROM ii;
           77  +      INSERT INTO eee(eee) VALUES('integrity-check');
           78  +    COMMIT;
    77     79       INSERT INTO eee(eee) VALUES('integrity-check');
    78         -  COMMIT;
    79         -  INSERT INTO eee(eee) VALUES('integrity-check');
    80         -}
    81         -
    82         -set hash [sqlite3_fts5_token_hash 1024 xyz]
    83         -set vocab [build_vocab1 -prefix xyz -hash $hash]
    84         -lappend vocab xyz
    85         -
    86         -do_execsql_test 1.1 {
    87         -  CREATE VIRTUAL TABLE vocab USING fts5vocab(eee, 'row'); 
    88         -  BEGIN;
    89         -}
    90         -do_test 1.2 {
    91         -  for {set i 1} {$i <= 100} {incr i} {
    92         -    execsql { INSERT INTO eee VALUES( r($vocab, 5), r($vocab, 7) ) }
           80  +  }
           81  +  
           82  +  set hash [sqlite3_fts5_token_hash 1024 xyz]
           83  +  set vocab [build_vocab1 -prefix xyz -hash $hash]
           84  +  lappend vocab xyz
           85  +  
           86  +  do_execsql_test 1.1 {
           87  +    CREATE VIRTUAL TABLE vocab USING fts5vocab(eee, 'row'); 
           88  +    BEGIN;
    93     89     }
    94         -} {}
           90  +  do_test 1.2 {
           91  +    for {set i 1} {$i <= 100} {incr i} {
           92  +      execsql { INSERT INTO eee VALUES( r($vocab, 5), r($vocab, 7) ) }
           93  +    }
           94  +  } {}
           95  +    
           96  +  do_test 1.3 {
           97  +    db eval { SELECT term, doc FROM vocab } {
           98  +      set nRow [db one {SELECT count(*) FROM eee WHERE eee MATCH $term}]
           99  +      if {$nRow != $doc} {
          100  +        error "term=$term fts5vocab=$doc cnt=$nRow"
          101  +      }
          102  +    }
          103  +    set {} {}
          104  +  } {}
    95    105     
    96         -do_test 1.3 {
    97         -  db eval { SELECT term, doc FROM vocab } {
    98         -    set nRow [db one {SELECT count(*) FROM eee WHERE eee MATCH $term}]
    99         -    if {$nRow != $doc} {
   100         -      error "term=$term fts5vocab=$doc cnt=$nRow"
   101         -    }
          106  +  do_execsql_test 1.4 {
          107  +    COMMIT;
          108  +    INSERT INTO eee(eee) VALUES('integrity-check');
   102    109     }
   103         -  set {} {}
   104         -} {}
          110  +
          111  +  #-----------------------------------------------------------------------
          112  +  # Add a small and very large token with the same hash value to an
          113  +  # empty table. At one point this would provoke an asan error.
          114  +  #
          115  +  do_test 2.0 {
          116  +    set big [string repeat 12345 40]
          117  +    set hash [sqlite3_fts5_token_hash 1024 $big]
          118  +    while {1} {
          119  +      set small [random_token]
          120  +      if {[sqlite3_fts5_token_hash 1024 $small]==$hash} break
          121  +    }
   105    122   
   106         -do_execsql_test 1.4 {
   107         -  COMMIT;
   108         -  INSERT INTO eee(eee) VALUES('integrity-check');
   109         -}
          123  +    execsql { CREATE VIRTUAL TABLE t2 USING fts5(x, detail=%DETAIL%) }
          124  +breakpoint
          125  +    execsql {
          126  +      INSERT INTO t2 VALUES($small || ' ' || $big);
          127  +    }
          128  +  } {}
   110    129   
   111    130   } ;# foreach_detail_mode
   112    131   
   113    132   finish_test
   114    133   

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

   394    394   }
   395    395   
   396    396   #-------------------------------------------------------------------------
   397    397   do_execsql_test 18.1 {
   398    398     CREATE VIRTUAL TABLE x4 USING fts5(x);
   399    399     SELECT rowid FROM x4('""');
   400    400   }
          401  +
          402  +#-------------------------------------------------------------------------
          403  +reset_db
          404  +do_execsql_test 19.1 {
          405  +  CREATE VIRTUAL TABLE x1 USING fts5(a,b,c);
          406  +}
          407  +
          408  +do_catchsql_test 19.2 {
          409  +  SELECT * FROM x1 WHERE x1 MATCH 'c0 AND (c1 AND (c2 AND (c3 AND (c4 AND (c5 AND (c6 AND (c7 AND (c8 AND (c9 AND (c10 AND (c11 AND (c12 AND (c13 AND (c14 AND (c15 AND (c16 AND (c17 AND (c18 AND (c19 AND (c20 AND (c21 AND (c22 AND (c23 AND (c24 AND (c25 AND (c26 AND (c27 AND (c28 AND (c29 AND (c30 AND (c31 AND (c32 AND (c33 AND (c34 AND (c35 AND (c36 AND (c37 AND (c38 AND (c39 AND (c40 AND (c41 AND (c42 AND (c43 AND (c44 AND (c45 AND (c46 AND (c47 AND (c48 AND (c49 AND (c50 AND (c51 AND (c52 AND (c53 AND (c54 AND (c55 AND (c56 AND (c57 AND (c58 AND (c59 AND (c60 AND (c61 AND (c62 AND (c63 AND (c64 AND (c65 AND (c66 AND (c67 AND (c68 AND (c69 AND (c70 AND (c71 AND (c72 AND (c73 AND (c74 AND (c75 AND (c76 AND (c77 AND (c78 AND (c79 AND (c80 AND (c81 AND (c82 AND (c83 AND (c84 AND (c85 AND (c86 AND (c87 AND (c88 AND (c89 AND (c90 AND (c91 AND (c92 AND (c93 AND (c94 AND (c95 AND (c96 AND (c97 AND (c98 AND (c99 AND (c100 AND (c101 AND (c102 AND (c103 AND (c104 AND (c105 AND (c106 AND (c107 AND (c108 AND (c109 AND (c110 AND (c111 AND (c112 AND (c113 AND (c114 AND (c115 AND (c116 AND (c117 AND (c118 AND (c119 AND (c120 AND (c121 AND (c122 AND (c123 AND (c124 AND (c125 AND (c126 AND (c127 AND (c128 AND (c129 AND (c130 AND (c131 AND (c132 AND (c133 AND (c134 AND (c135 AND (c136 AND (c137 AND (c138 AND (c139 AND (c140 AND (c141 AND (c142 AND (c143 AND (c144 AND (c145 AND (c146 AND (c147 AND (c148 AND (c149 AND (c150 AND (c151 AND (c152 AND (c153 AND (c154 AND (c155 AND (c156 AND (c157 AND (c158 AND (c159 AND (c160 AND (c161 AND (c162 AND (c163 AND (c164 AND (c165 AND (c166 AND (c167 AND (c168 AND (c169 AND (c170 AND (c171 AND (c172 AND (c173 AND (c174 AND (c175 AND (c176 AND (c177 AND (c178 AND (c179 AND (c180 AND (c181 AND (c182 AND (c183 AND (c184 AND (c185 AND (c186 AND (c187 AND (c188 AND (c189 AND (c190 AND (c191 AND (c192 AND (c193 AND (c194 AND (c195 AND (c196 AND (c197 AND (c198 AND (c199 AND c200)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))';
          410  +} {1 {fts5: parser stack overflow}}
   401    411   
   402    412   finish_test
   403    413   

Changes to ext/misc/json1.c.

    27     27   #endif
    28     28   SQLITE_EXTENSION_INIT1
    29     29   #include <assert.h>
    30     30   #include <string.h>
    31     31   #include <stdlib.h>
    32     32   #include <stdarg.h>
    33     33   
    34         -#define UNUSED_PARAM(X)  (void)(X)
           34  +/* Mark a function parameter as unused, to suppress nuisance compiler
           35  +** warnings. */
           36  +#ifndef UNUSED_PARAM
           37  +# define UNUSED_PARAM(X)  (void)(X)
           38  +#endif
    35     39   
    36     40   #ifndef LARGEST_INT64
    37     41   # define LARGEST_INT64  (0xffffffff|(((sqlite3_int64)0x7fffffff)<<32))
    38     42   # define SMALLEST_INT64 (((sqlite3_int64)-1) - LARGEST_INT64)
    39     43   #endif
    40     44   
    41     45   /*
................................................................................
  1548   1552   */
  1549   1553   static void jsonArrayStep(
  1550   1554     sqlite3_context *ctx,
  1551   1555     int argc,
  1552   1556     sqlite3_value **argv
  1553   1557   ){
  1554   1558     JsonString *pStr;
         1559  +  UNUSED_PARAM(argc);
  1555   1560     pStr = (JsonString*)sqlite3_aggregate_context(ctx, sizeof(*pStr));
  1556   1561     if( pStr ){
  1557   1562       if( pStr->zBuf==0 ){
  1558   1563         jsonInit(pStr, ctx);
  1559   1564         jsonAppendChar(pStr, '[');
  1560   1565       }else{
  1561   1566         jsonAppendChar(pStr, ',');
................................................................................
  1593   1598     sqlite3_context *ctx,
  1594   1599     int argc,
  1595   1600     sqlite3_value **argv
  1596   1601   ){
  1597   1602     JsonString *pStr;
  1598   1603     const char *z;
  1599   1604     u32 n;
         1605  +  UNUSED_PARAM(argc);
  1600   1606     pStr = (JsonString*)sqlite3_aggregate_context(ctx, sizeof(*pStr));
  1601   1607     if( pStr ){
  1602   1608       if( pStr->zBuf==0 ){
  1603   1609         jsonInit(pStr, ctx);
  1604   1610         jsonAppendChar(pStr, '{');
  1605   1611       }else{
  1606   1612         jsonAppendChar(pStr, ',');

Changes to main.mk.

   483    483   		-DSQLITE_ENABLE_MEMSYS5 $(FUZZCHECK_OPT) \
   484    484   		$(TOP)/test/fuzzcheck.c sqlite3.c $(TLIBS) $(THREADLIB)
   485    485   
   486    486   mptester$(EXE):	sqlite3.c $(TOP)/mptest/mptest.c
   487    487   	$(TCCX) -o $@ -I. $(TOP)/mptest/mptest.c sqlite3.c \
   488    488   		$(TLIBS) $(THREADLIB)
   489    489   
   490         -MPTEST1=./mptester$(EXE) mptest.db $(TOP)/mptest/crash01.test --repeat 20
   491         -MPTEST2=./mptester$(EXE) mptest.db $(TOP)/mptest/multiwrite01.test --repeat 20
          490  +MPTEST1=./mptester$(EXE) mptest1.db $(TOP)/mptest/crash01.test --repeat 20
          491  +MPTEST2=./mptester$(EXE) mptest2.db $(TOP)/mptest/multiwrite01.test --repeat 20
   492    492   mptest:	mptester$(EXE)
   493         -	rm -f mptest.db
   494    493   	$(MPTEST1) --journalmode DELETE
   495    494   	$(MPTEST2) --journalmode WAL
   496    495   	$(MPTEST1) --journalmode WAL
   497    496   	$(MPTEST2) --journalmode PERSIST
   498    497   	$(MPTEST1) --journalmode PERSIST
   499    498   	$(MPTEST2) --journalmode TRUNCATE
   500    499   	$(MPTEST1) --journalmode TRUNCATE
................................................................................
   846    845   # This target will fail if the SQLite amalgamation contains any exported
   847    846   # symbols that do not begin with "sqlite3_". It is run as part of the
   848    847   # releasetest.tcl script.
   849    848   #
   850    849   checksymbols: sqlite3.o
   851    850   	nm -g --defined-only sqlite3.o | grep -v " sqlite3_" ; test $$? -ne 0
   852    851   
   853         -# Build the amalgamation-autoconf package.
          852  +# Build the amalgamation-autoconf package.  The amalamgation-tarball target builds
          853  +# a tarball named for the version number.  Ex:  sqlite-autoconf-3110000.tar.gz.
          854  +# The snapshot-tarball target builds a tarball named by the SHA1 hash
   854    855   #
   855    856   amalgamation-tarball: sqlite3.c
   856         -	TOP=$(TOP) sh $(TOP)/tool/mkautoconfamal.sh
          857  +	TOP=$(TOP) sh $(TOP)/tool/mkautoconfamal.sh --normal
          858  +
          859  +snapshot-tarball: sqlite3.c
          860  +	TOP=$(TOP) sh $(TOP)/tool/mkautoconfamal.sh --snapshot
   857    861   
   858    862   
   859    863   # Standard install and cleanup targets
   860    864   #
   861    865   install:	sqlite3 libsqlite3.a sqlite3.h
   862    866   	mv sqlite3 /usr/bin
   863    867   	mv libsqlite3.a /usr/lib

Changes to mptest/mptest.c.

    37     37   #include <stdio.h>
    38     38   #if defined(_WIN32)
    39     39   # define WIN32_LEAN_AND_MEAN
    40     40   # include <windows.h>
    41     41   #else
    42     42   # include <unistd.h>
    43     43   #endif
           44  +#include <errno.h>
    44     45   #include <stdlib.h>
    45     46   #include <string.h>
    46     47   #include <assert.h>
    47     48   #include <ctype.h>
    48     49   
    49     50   #define ISSPACE(X) isspace((unsigned char)(X))
    50     51   #define ISDIGIT(X) isdigit((unsigned char)(X))
................................................................................
  1240   1241   static void usage(const char *argv0){
  1241   1242     int i;
  1242   1243     const char *zTail = argv0;
  1243   1244     for(i=0; argv0[i]; i++){
  1244   1245       if( isDirSep(argv0[i]) ) zTail = argv0+i+1;
  1245   1246     }
  1246   1247     fprintf(stderr,"Usage: %s DATABASE ?OPTIONS? ?SCRIPT?\n", zTail);
         1248  +  fprintf(stderr,
         1249  +    "Options:\n"
         1250  +    "   --errlog FILENAME           Write errors to FILENAME\n"
         1251  +    "   --journalmode MODE          Use MODE as the journal_mode\n"
         1252  +    "   --log FILENAME              Log messages to FILENAME\n"
         1253  +    "   --quiet                     Suppress unnecessary output\n"
         1254  +    "   --vfs NAME                  Use NAME as the VFS\n"
         1255  +    "   --repeat N                  Repeat the test N times\n"
         1256  +    "   --sqltrace                  Enable SQL tracing\n"
         1257  +    "   --sync                      Enable synchronous disk writes\n"
         1258  +    "   --timeout MILLISEC          Busy timeout is MILLISEC\n"
         1259  +    "   --trace BOOLEAN             Enable or disable tracing\n"
         1260  +  );
  1247   1261     exit(1);
  1248   1262   }
  1249   1263   
  1250   1264   /* Report on unrecognized arguments */
  1251   1265   static void unrecognizedArguments(
  1252   1266     const char *argv0,
  1253   1267     int nArg,
................................................................................
  1271   1285     char *zScript;
  1272   1286     int taskId;
  1273   1287     const char *zTrace;
  1274   1288     const char *zCOption;
  1275   1289     const char *zJMode;
  1276   1290     const char *zNRep;
  1277   1291     int nRep = 1, iRep;
         1292  +  int iTmout = 0;              /* Default: no timeout */
         1293  +  const char *zTmout;
  1278   1294   
  1279   1295     g.argv0 = argv[0];
  1280   1296     g.iTrace = 1;
  1281   1297     if( argc<2 ) usage(argv[0]);
  1282   1298     g.zDbFile = argv[1];
  1283   1299     if( strglob("*.test", g.zDbFile) ) usage(argv[0]);
  1284   1300     if( strcmp(sqlite3_sourceid(), SQLITE_SOURCE_ID)!=0 ){
................................................................................
  1297   1313     g.zVfs = findOption(argv+2, &n, "vfs", 1);
  1298   1314     zClient = findOption(argv+2, &n, "client", 1);
  1299   1315     g.zErrLog = findOption(argv+2, &n, "errlog", 1);
  1300   1316     g.zLog = findOption(argv+2, &n, "log", 1);
  1301   1317     zTrace = findOption(argv+2, &n, "trace", 1);
  1302   1318     if( zTrace ) g.iTrace = atoi(zTrace);
  1303   1319     if( findOption(argv+2, &n, "quiet", 0)!=0 ) g.iTrace = 0;
         1320  +  zTmout = findOption(argv+2, &n, "timeout", 1);
         1321  +  if( zTmout ) iTmout = atoi(zTmout);
  1304   1322     g.bSqlTrace = findOption(argv+2, &n, "sqltrace", 0)!=0;
  1305   1323     g.bSync = findOption(argv+2, &n, "sync", 0)!=0;
  1306   1324     if( g.zErrLog ){
  1307   1325       g.pErrLog = fopen(g.zErrLog, "a");
  1308   1326     }else{
  1309   1327       g.pErrLog = stderr;
  1310   1328     }
................................................................................
  1317   1335     sqlite3_config(SQLITE_CONFIG_LOG, sqlErrorCallback, 0);
  1318   1336     if( zClient ){
  1319   1337       iClient = atoi(zClient);
  1320   1338       if( iClient<1 ) fatalError("illegal client number: %d\n", iClient);
  1321   1339       sqlite3_snprintf(sizeof(g.zName), g.zName, "%05d.client%02d",
  1322   1340                        GETPID(), iClient);
  1323   1341     }else{
         1342  +    int nTry = 0;
  1324   1343       if( g.iTrace>0 ){
  1325   1344         printf("BEGIN: %s", argv[0]);
  1326   1345         for(i=1; i<argc; i++) printf(" %s", argv[i]);
  1327   1346         printf("\n");
  1328   1347         printf("With SQLite " SQLITE_VERSION " " SQLITE_SOURCE_ID "\n" );
  1329   1348         for(i=0; (zCOption = sqlite3_compileoption_get(i))!=0; i++){
  1330   1349           printf("-DSQLITE_%s\n", zCOption);
  1331   1350         }
  1332   1351         fflush(stdout);
  1333   1352       }
  1334   1353       iClient =  0;
  1335         -    unlink(g.zDbFile);
         1354  +    do{
         1355  +      if( (nTry%5)==4 ) printf("... %strying to unlink '%s'\n",
         1356  +                               nTry>5 ? "still " : "", g.zDbFile);
         1357  +      rc = unlink(g.zDbFile);
         1358  +      if( rc && errno==ENOENT ) rc = 0;
         1359  +    }while( rc!=0 && (++nTry)<60 && sqlite3_sleep(1000)>0 );
         1360  +    if( rc!=0 ){
         1361  +      fatalError("unable to unlink '%s' after %d attempts\n",
         1362  +                 g.zDbFile, nTry);
         1363  +    }
  1336   1364       openFlags |= SQLITE_OPEN_CREATE;
  1337   1365     }
  1338   1366     rc = sqlite3_open_v2(g.zDbFile, &g.db, openFlags, g.zVfs);
  1339   1367     if( rc ) fatalError("cannot open [%s]", g.zDbFile);
         1368  +  if( iTmout>0 ) sqlite3_busy_timeout(g.db, iTmout);
         1369  +  
  1340   1370     if( zJMode ){
  1341   1371   #if defined(_WIN32)
  1342   1372       if( sqlite3_stricmp(zJMode,"persist")==0
  1343   1373        || sqlite3_stricmp(zJMode,"truncate")==0
  1344   1374       ){
  1345   1375         printf("Changing journal mode to DELETE from %s", zJMode);
  1346   1376         zJMode = "DELETE";

Changes to src/alter.c.

   584    584   
   585    585   exit_rename_table:
   586    586     sqlite3SrcListDelete(db, pSrc);
   587    587     sqlite3DbFree(db, zName);
   588    588     db->flags = savedDbFlags;
   589    589   }
   590    590   
   591         -
   592         -/*
   593         -** Generate code to make sure the file format number is at least minFormat.
   594         -** The generated code will increase the file format number if necessary.
   595         -*/
   596         -void sqlite3MinimumFileFormat(Parse *pParse, int iDb, int minFormat){
   597         -  Vdbe *v;
   598         -  v = sqlite3GetVdbe(pParse);
   599         -  /* The VDBE should have been allocated before this routine is called.
   600         -  ** If that allocation failed, we would have quit before reaching this
   601         -  ** point */
   602         -  if( ALWAYS(v) ){
   603         -    int r1 = sqlite3GetTempReg(pParse);
   604         -    int r2 = sqlite3GetTempReg(pParse);
   605         -    int addr1;
   606         -    sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, r1, BTREE_FILE_FORMAT);
   607         -    sqlite3VdbeUsesBtree(v, iDb);
   608         -    sqlite3VdbeAddOp2(v, OP_Integer, minFormat, r2);
   609         -    addr1 = sqlite3VdbeAddOp3(v, OP_Ge, r2, 0, r1);
   610         -    sqlite3VdbeChangeP5(v, SQLITE_NOTNULL); VdbeCoverage(v);
   611         -    sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_FILE_FORMAT, minFormat);
   612         -    sqlite3VdbeJumpHere(v, addr1);
   613         -    sqlite3ReleaseTempReg(pParse, r1);
   614         -    sqlite3ReleaseTempReg(pParse, r2);
   615         -  }
   616         -}
   617         -
   618    591   /*
   619    592   ** This function is called after an "ALTER TABLE ... ADD" statement
   620    593   ** has been parsed. Argument pColDef contains the text of the new
   621    594   ** column definition.
   622    595   **
   623    596   ** The Table structure pParse->pNewTable was extended to include
   624    597   ** the new column during parsing.
................................................................................
   629    602     int iDb;                  /* Database number */
   630    603     const char *zDb;          /* Database name */
   631    604     const char *zTab;         /* Table name */
   632    605     char *zCol;               /* Null-terminated column definition */
   633    606     Column *pCol;             /* The new column */
   634    607     Expr *pDflt;              /* Default value for the new column */
   635    608     sqlite3 *db;              /* The database connection; */
          609  +  Vdbe *v = pParse->pVdbe;  /* The prepared statement under construction */
   636    610   
   637    611     db = pParse->db;
   638    612     if( pParse->nErr || db->mallocFailed ) return;
          613  +  assert( v!=0 );
   639    614     pNew = pParse->pNewTable;
   640    615     assert( pNew );
   641    616   
   642    617     assert( sqlite3BtreeHoldsAllMutexes(db) );
   643    618     iDb = sqlite3SchemaToIndex(db, pNew->pSchema);
   644    619     zDb = db->aDb[iDb].zName;
   645    620     zTab = &pNew->zName[16];  /* Skip the "sqlite_altertab_" prefix on the name */
................................................................................
   721    696         zDb, SCHEMA_TABLE(iDb), pNew->addColOffset, zCol, pNew->addColOffset+1,
   722    697         zTab
   723    698       );
   724    699       sqlite3DbFree(db, zCol);
   725    700       db->flags = savedDbFlags;
   726    701     }
   727    702   
   728         -  /* If the default value of the new column is NULL, then set the file
          703  +  /* If the default value of the new column is NULL, then the file
   729    704     ** format to 2. If the default value of the new column is not NULL,
   730         -  ** the file format becomes 3.
          705  +  ** the file format be 3.  Back when this feature was first added
          706  +  ** in 2006, we went to the trouble to upgrade the file format to the
          707  +  ** minimum support values.  But 10-years on, we can assume that all
          708  +  ** extent versions of SQLite support file-format 4, so we always and
          709  +  ** unconditionally upgrade to 4.
   731    710     */
   732         -  sqlite3MinimumFileFormat(pParse, iDb, pDflt ? 3 : 2);
          711  +  sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_FILE_FORMAT, 
          712  +                    SQLITE_MAX_FILE_FORMAT);
   733    713   
   734    714     /* Reload the schema of the modified table. */
   735    715     reloadTableSchema(pParse, pTab, pTab->zName);
   736    716   }
   737    717   
   738    718   /*
   739    719   ** This function is called by the parser after the table-name in

Changes to src/insert.c.

   991    991         sqlite3VdbeChangeP5(v, onError==OE_Default ? OE_Abort : onError);
   992    992         sqlite3MayAbort(pParse);
   993    993       }else
   994    994   #endif
   995    995       {
   996    996         int isReplace;    /* Set to true if constraints may cause a replace */
   997    997         sqlite3GenerateConstraintChecks(pParse, pTab, aRegIdx, iDataCur, iIdxCur,
   998         -          regIns, 0, ipkColumn>=0, onError, endOfLoop, &isReplace
          998  +          regIns, 0, ipkColumn>=0, onError, endOfLoop, &isReplace, 0
   999    999         );
  1000   1000         sqlite3FkCheck(pParse, pTab, 0, regIns, 0, 0);
  1001   1001         sqlite3CompleteInsertion(pParse, pTab, iDataCur, iIdxCur,
  1002   1002                                  regIns, aRegIdx, 0, appendFlag, isReplace==0);
  1003   1003       }
  1004   1004     }
  1005   1005   
................................................................................
  1072   1072   #endif
  1073   1073   #ifdef pTrigger
  1074   1074    #undef pTrigger
  1075   1075   #endif
  1076   1076   #ifdef tmask
  1077   1077    #undef tmask
  1078   1078   #endif
         1079  +
         1080  +/*
         1081  +** Meanings of bits in of pWalker->eCode for checkConstraintUnchanged()
         1082  +*/
         1083  +#define CKCNSTRNT_COLUMN   0x01    /* CHECK constraint uses a changing column */
         1084  +#define CKCNSTRNT_ROWID    0x02    /* CHECK constraint references the ROWID */
         1085  +
         1086  +/* This is the Walker callback from checkConstraintUnchanged().  Set
         1087  +** bit 0x01 of pWalker->eCode if
         1088  +** pWalker->eCode to 0 if this expression node references any of the
         1089  +** columns that are being modifed by an UPDATE statement.
         1090  +*/
         1091  +static int checkConstraintExprNode(Walker *pWalker, Expr *pExpr){
         1092  +  if( pExpr->op==TK_COLUMN ){
         1093  +    assert( pExpr->iColumn>=0 || pExpr->iColumn==-1 );
         1094  +    if( pExpr->iColumn>=0 ){
         1095  +      if( pWalker->u.aiCol[pExpr->iColumn]>=0 ){
         1096  +        pWalker->eCode |= CKCNSTRNT_COLUMN;
         1097  +      }
         1098  +    }else{
         1099  +      pWalker->eCode |= CKCNSTRNT_ROWID;
         1100  +    }
         1101  +  }
         1102  +  return WRC_Continue;
         1103  +}
         1104  +
         1105  +/*
         1106  +** pExpr is a CHECK constraint on a row that is being UPDATE-ed.  The
         1107  +** only columns that are modified by the UPDATE are those for which
         1108  +** aiChng[i]>=0, and also the ROWID is modified if chngRowid is true.
         1109  +**
         1110  +** Return true if CHECK constraint pExpr does not use any of the
         1111  +** changing columns (or the rowid if it is changing).  In other words,
         1112  +** return true if this CHECK constraint can be skipped when validating
         1113  +** the new row in the UPDATE statement.
         1114  +*/
         1115  +static int checkConstraintUnchanged(Expr *pExpr, int *aiChng, int chngRowid){
         1116  +  Walker w;
         1117  +  memset(&w, 0, sizeof(w));
         1118  +  w.eCode = 0;
         1119  +  w.xExprCallback = checkConstraintExprNode;
         1120  +  w.u.aiCol = aiChng;
         1121  +  sqlite3WalkExpr(&w, pExpr);
         1122  +  if( !chngRowid ){
         1123  +    testcase( (w.eCode & CKCNSTRNT_ROWID)!=0 );
         1124  +    w.eCode &= ~CKCNSTRNT_ROWID;
         1125  +  }
         1126  +  testcase( w.eCode==0 );
         1127  +  testcase( w.eCode==CKCNSTRNT_COLUMN );
         1128  +  testcase( w.eCode==CKCNSTRNT_ROWID );
         1129  +  testcase( w.eCode==(CKCNSTRNT_ROWID|CKCNSTRNT_COLUMN) );
         1130  +  return !w.eCode;
         1131  +}
  1079   1132   
  1080   1133   /*
  1081   1134   ** Generate code to do constraint checks prior to an INSERT or an UPDATE
  1082   1135   ** on table pTab.
  1083   1136   **
  1084   1137   ** The regNewData parameter is the first register in a range that contains
  1085   1138   ** the data to be inserted or the data after the update.  There will be
................................................................................
  1167   1220     int iDataCur,        /* Canonical data cursor (main table or PK index) */
  1168   1221     int iIdxCur,         /* First index cursor */
  1169   1222     int regNewData,      /* First register in a range holding values to insert */
  1170   1223     int regOldData,      /* Previous content.  0 for INSERTs */
  1171   1224     u8 pkChng,           /* Non-zero if the rowid or PRIMARY KEY changed */
  1172   1225     u8 overrideError,    /* Override onError to this if not OE_Default */
  1173   1226     int ignoreDest,      /* Jump to this label on an OE_Ignore resolution */
  1174         -  int *pbMayReplace    /* OUT: Set to true if constraint may cause a replace */
         1227  +  int *pbMayReplace,   /* OUT: Set to true if constraint may cause a replace */
         1228  +  int *aiChng          /* column i is unchanged if aiChng[i]<0 */
  1175   1229   ){
  1176   1230     Vdbe *v;             /* VDBE under constrution */
  1177   1231     Index *pIdx;         /* Pointer to one of the indices */
  1178   1232     Index *pPk = 0;      /* The PRIMARY KEY index */
  1179   1233     sqlite3 *db;         /* Database connection */
  1180   1234     int i;               /* loop counter */
  1181   1235     int ix;              /* Index loop counter */
................................................................................
  1213   1267     VdbeModuleComment((v, "BEGIN: GenCnstCks(%d,%d,%d,%d,%d)",
  1214   1268                        iDataCur, iIdxCur, regNewData, regOldData, pkChng));
  1215   1269   
  1216   1270     /* Test all NOT NULL constraints.
  1217   1271     */
  1218   1272     for(i=0; i<nCol; i++){
  1219   1273       if( i==pTab->iPKey ){
         1274  +      continue;        /* ROWID is never NULL */
         1275  +    }
         1276  +    if( aiChng && aiChng[i]<0 ){
         1277  +      /* Don't bother checking for NOT NULL on columns that do not change */
  1220   1278         continue;
  1221   1279       }
  1222   1280       onError = pTab->aCol[i].notNull;
  1223         -    if( onError==OE_None ) continue;
         1281  +    if( onError==OE_None ) continue;  /* This column is allowed to be NULL */
  1224   1282       if( overrideError!=OE_Default ){
  1225   1283         onError = overrideError;
  1226   1284       }else if( onError==OE_Default ){
  1227   1285         onError = OE_Abort;
  1228   1286       }
  1229   1287       if( onError==OE_Replace && pTab->aCol[i].pDflt==0 ){
  1230   1288         onError = OE_Abort;
................................................................................
  1265   1323     */
  1266   1324   #ifndef SQLITE_OMIT_CHECK
  1267   1325     if( pTab->pCheck && (db->flags & SQLITE_IgnoreChecks)==0 ){
  1268   1326       ExprList *pCheck = pTab->pCheck;
  1269   1327       pParse->ckBase = regNewData+1;
  1270   1328       onError = overrideError!=OE_Default ? overrideError : OE_Abort;
  1271   1329       for(i=0; i<pCheck->nExpr; i++){
  1272         -      int allOk = sqlite3VdbeMakeLabel(v);
  1273         -      sqlite3ExprIfTrue(pParse, pCheck->a[i].pExpr, allOk, SQLITE_JUMPIFNULL);
         1330  +      int allOk;
         1331  +      Expr *pExpr = pCheck->a[i].pExpr;
         1332  +      if( aiChng && checkConstraintUnchanged(pExpr, aiChng, pkChng) ) continue;
         1333  +      allOk = sqlite3VdbeMakeLabel(v);
         1334  +      sqlite3ExprIfTrue(pParse, pExpr, allOk, SQLITE_JUMPIFNULL);
  1274   1335         if( onError==OE_Ignore ){
  1275   1336           sqlite3VdbeGoto(v, ignoreDest);
  1276   1337         }else{
  1277   1338           char *zName = pCheck->a[i].zName;
  1278   1339           if( zName==0 ) zName = pTab->zName;
  1279   1340           if( onError==OE_Replace ) onError = OE_Abort; /* IMP: R-15569-63625 */
  1280   1341           sqlite3HaltConstraint(pParse, SQLITE_CONSTRAINT_CHECK,

Changes to src/os.c.

    13     13   ** This file contains OS interface code that is common to all
    14     14   ** architectures.
    15     15   */
    16     16   #define _SQLITE_OS_C_ 1
    17     17   #include "sqliteInt.h"
    18     18   #undef _SQLITE_OS_C_
    19     19   
           20  +/*
           21  +** If we compile with the SQLITE_TEST macro set, then the following block
           22  +** of code will give us the ability to simulate a disk I/O error.  This
           23  +** is used for testing the I/O recovery logic.
           24  +*/
           25  +#if defined(SQLITE_TEST)
           26  +int sqlite3_io_error_hit = 0;            /* Total number of I/O Errors */
           27  +int sqlite3_io_error_hardhit = 0;        /* Number of non-benign errors */
           28  +int sqlite3_io_error_pending = 0;        /* Count down to first I/O error */
           29  +int sqlite3_io_error_persist = 0;        /* True if I/O errors persist */
           30  +int sqlite3_io_error_benign = 0;         /* True if errors are benign */
           31  +int sqlite3_diskfull_pending = 0;
           32  +int sqlite3_diskfull = 0;
           33  +#endif /* defined(SQLITE_TEST) */
           34  +
           35  +/*
           36  +** When testing, also keep a count of the number of open files.
           37  +*/
           38  +#if defined(SQLITE_TEST)
           39  +int sqlite3_open_file_count = 0;
           40  +#endif /* defined(SQLITE_TEST) */
           41  +
    20     42   /*
    21     43   ** The default SQLite sqlite3_vfs implementations do not allocate
    22     44   ** memory (actually, os_unix.c allocates a small amount of memory
    23     45   ** from within OsOpen()), but some third-party implementations may.
    24     46   ** So we test the effects of a malloc() failing and the sqlite3OsXXX()
    25     47   ** function returning SQLITE_IOERR_NOMEM using the DO_OS_MALLOC_TEST macro.
    26     48   **
    27         -** The following functions are instrumented for malloc() failure 
           49  +** The following functions are instrumented for malloc() failure
    28     50   ** testing:
    29     51   **
    30     52   **     sqlite3OsRead()
    31     53   **     sqlite3OsWrite()
    32     54   **     sqlite3OsSync()
    33     55   **     sqlite3OsFileSize()
    34     56   **     sqlite3OsLock()
................................................................................
   106    128   ** is only a hint and can be safely ignored.  The sqlite3OsFileControlHint()
   107    129   ** routine has no return value since the return value would be meaningless.
   108    130   */
   109    131   int sqlite3OsFileControl(sqlite3_file *id, int op, void *pArg){
   110    132   #ifdef SQLITE_TEST
   111    133     if( op!=SQLITE_FCNTL_COMMIT_PHASETWO ){
   112    134       /* Faults are not injected into COMMIT_PHASETWO because, assuming SQLite
   113         -    ** is using a regular VFS, it is called after the corresponding 
   114         -    ** transaction has been committed. Injecting a fault at this point 
          135  +    ** is using a regular VFS, it is called after the corresponding
          136  +    ** transaction has been committed. Injecting a fault at this point
   115    137       ** confuses the test scripts - the COMMIT comand returns SQLITE_NOMEM
   116    138       ** but the transaction is committed anyway.
   117    139       **
   118    140       ** The core must call OsFileControl() though, not OsFileControlHint(),
   119    141       ** as if a custom VFS (e.g. zipvfs) returns an error here, it probably
   120    142       ** means the commit really has failed and an error should be returned
   121    143       ** to the user.  */
................................................................................
   176    198   #endif
   177    199   
   178    200   /*
   179    201   ** The next group of routines are convenience wrappers around the
   180    202   ** VFS methods.
   181    203   */
   182    204   int sqlite3OsOpen(
   183         -  sqlite3_vfs *pVfs, 
   184         -  const char *zPath, 
   185         -  sqlite3_file *pFile, 
   186         -  int flags, 
          205  +  sqlite3_vfs *pVfs,
          206  +  const char *zPath,
          207  +  sqlite3_file *pFile,
          208  +  int flags,
   187    209     int *pFlagsOut
   188    210   ){
   189    211     int rc;
   190    212     int openFlags;
   191    213     DO_OS_MALLOC_TEST(0);
   192    214     /* 0x87f7f is a mask of SQLITE_OPEN_ flags that are valid to be passed
   193    215     ** down into the VFS layer.  Some SQLITE_OPEN_ flags (for example,
................................................................................
   204    226   }
   205    227   int sqlite3OsDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
   206    228     DO_OS_MALLOC_TEST(0);
   207    229     assert( dirSync==0 || dirSync==1 );
   208    230     return pVfs->xDelete(pVfs, zPath, dirSync);
   209    231   }
   210    232   int sqlite3OsAccess(
   211         -  sqlite3_vfs *pVfs, 
   212         -  const char *zPath, 
   213         -  int flags, 
          233  +  sqlite3_vfs *pVfs,
          234  +  const char *zPath,
          235  +  int flags,
   214    236     int *pResOut
   215    237   ){
   216    238     DO_OS_MALLOC_TEST(0);
   217    239     return pVfs->xAccess(pVfs, zPath, flags, pResOut);
   218    240   }
   219    241   int sqlite3OsFullPathname(
   220         -  sqlite3_vfs *pVfs, 
   221         -  const char *zPath, 
   222         -  int nPathOut, 
          242  +  sqlite3_vfs *pVfs,
          243  +  const char *zPath,
          244  +  int nPathOut,
   223    245     char *zPathOut
   224    246   ){
   225    247     DO_OS_MALLOC_TEST(0);
   226    248     zPathOut[0] = 0;
   227    249     return pVfs->xFullPathname(pVfs, zPath, nPathOut, zPathOut);
   228    250   }
   229    251   #ifndef SQLITE_OMIT_LOAD_EXTENSION
................................................................................
   261    283       rc = pVfs->xCurrentTime(pVfs, &r);
   262    284       *pTimeOut = (sqlite3_int64)(r*86400000.0);
   263    285     }
   264    286     return rc;
   265    287   }
   266    288   
   267    289   int sqlite3OsOpenMalloc(
   268         -  sqlite3_vfs *pVfs, 
   269         -  const char *zFile, 
   270         -  sqlite3_file **ppFile, 
          290  +  sqlite3_vfs *pVfs,
          291  +  const char *zFile,
          292  +  sqlite3_file **ppFile,
   271    293     int flags,
   272    294     int *pOutFlags
   273    295   ){
   274    296     int rc = SQLITE_NOMEM;
   275    297     sqlite3_file *pFile;
   276    298     pFile = (sqlite3_file *)sqlite3MallocZero(pVfs->szOsFile);
   277    299     if( pFile ){

Changes to src/os_common.h.

    31     31   
    32     32   /*
    33     33   ** Macros for performance tracing.  Normally turned off.  Only works
    34     34   ** on i486 hardware.
    35     35   */
    36     36   #ifdef SQLITE_PERFORMANCE_TRACE
    37     37   
    38         -/* 
    39         -** hwtime.h contains inline assembler code for implementing 
           38  +/*
           39  +** hwtime.h contains inline assembler code for implementing
    40     40   ** high-performance timing routines.
    41     41   */
    42     42   #include "hwtime.h"
    43     43   
    44     44   static sqlite_uint64 g_start;
    45     45   static sqlite_uint64 g_elapsed;
    46     46   #define TIMER_START       g_start=sqlite3Hwtime()
................................................................................
    53     53   #endif
    54     54   
    55     55   /*
    56     56   ** If we compile with the SQLITE_TEST macro set, then the following block
    57     57   ** of code will give us the ability to simulate a disk I/O error.  This
    58     58   ** is used for testing the I/O recovery logic.
    59     59   */
    60         -#ifdef SQLITE_TEST
    61         -int sqlite3_io_error_hit = 0;            /* Total number of I/O Errors */
    62         -int sqlite3_io_error_hardhit = 0;        /* Number of non-benign errors */
    63         -int sqlite3_io_error_pending = 0;        /* Count down to first I/O error */
    64         -int sqlite3_io_error_persist = 0;        /* True if I/O errors persist */
    65         -int sqlite3_io_error_benign = 0;         /* True if errors are benign */
    66         -int sqlite3_diskfull_pending = 0;
    67         -int sqlite3_diskfull = 0;
           60  +#if defined(SQLITE_TEST)
           61  +extern int sqlite3_io_error_hit;
           62  +extern int sqlite3_io_error_hardhit;
           63  +extern int sqlite3_io_error_pending;
           64  +extern int sqlite3_io_error_persist;
           65  +extern int sqlite3_io_error_benign;
           66  +extern int sqlite3_diskfull_pending;
           67  +extern int sqlite3_diskfull;
    68     68   #define SimulateIOErrorBenign(X) sqlite3_io_error_benign=(X)
    69     69   #define SimulateIOError(CODE)  \
    70     70     if( (sqlite3_io_error_persist && sqlite3_io_error_hit) \
    71     71          || sqlite3_io_error_pending-- == 1 )  \
    72     72                 { local_ioerr(); CODE; }
    73     73   static void local_ioerr(){
    74     74     IOTRACE(("IOERR\n"));
................................................................................
    86     86          sqlite3_diskfull_pending--; \
    87     87        } \
    88     88      }
    89     89   #else
    90     90   #define SimulateIOErrorBenign(X)
    91     91   #define SimulateIOError(A)
    92     92   #define SimulateDiskfullError(A)
    93         -#endif
           93  +#endif /* defined(SQLITE_TEST) */
    94     94   
    95     95   /*
    96     96   ** When testing, keep a count of the number of open files.
    97     97   */
    98         -#ifdef SQLITE_TEST
    99         -int sqlite3_open_file_count = 0;
           98  +#if defined(SQLITE_TEST)
           99  +extern int sqlite3_open_file_count;
   100    100   #define OpenCounter(X)  sqlite3_open_file_count+=(X)
   101    101   #else
   102    102   #define OpenCounter(X)
   103         -#endif
          103  +#endif /* defined(SQLITE_TEST) */
   104    104   
   105    105   #endif /* !defined(_OS_COMMON_H_) */

Changes to src/shell.c.

   588    588   ** State information about the database connection is contained in an
   589    589   ** instance of the following structure.
   590    590   */
   591    591   typedef struct ShellState ShellState;
   592    592   struct ShellState {
   593    593     sqlite3 *db;           /* The database */
   594    594     int echoOn;            /* True to echo input commands */
          595  +  int autoExplain;       /* Automatically turn on .explain mode */
   595    596     int autoEQP;           /* Run EXPLAIN QUERY PLAN prior to seach SQL stmt */
   596    597     int statsOn;           /* True to display memory stats before each finalize */
   597    598     int scanstatsOn;       /* True to display scan stats before each finalize */
   598    599     int countChanges;      /* True to display change counts */
   599    600     int backslashOn;       /* Resolve C-style \x escapes in SQL input text */
   600    601     int outCount;          /* Revert to stdout when reaching zero */
   601    602     int cnt;               /* Number of records displayed so far */
   602    603     FILE *out;             /* Write results here */
   603    604     FILE *traceOut;        /* Output for sqlite3_trace() */
   604    605     int nErr;              /* Number of errors seen */
   605    606     int mode;              /* An output mode setting */
          607  +  int cMode;             /* temporary output mode for the current query */
          608  +  int normalMode;        /* Output mode before ".explain on" */
   606    609     int writableSchema;    /* True if PRAGMA writable_schema=ON */
   607    610     int showHeader;        /* True to show column names in List or Column mode */
   608    611     unsigned shellFlgs;    /* Various flags */
   609    612     char *zDestTable;      /* Name of destination table when MODE_Insert */
   610    613     char colSeparator[20]; /* Column separator character for several modes */
   611    614     char rowSeparator[20]; /* Row separator character for MODE_Ascii */
   612    615     int colWidth[100];     /* Requested width of each column when in column mode*/
   613    616     int actualWidth[100];  /* Actual width of each column */
   614    617     char nullValue[20];    /* The text to print when a NULL comes back from
   615    618                            ** the database */
   616         -  SavedModeInfo normalMode;/* Holds the mode just before .explain ON */
   617    619     char outfile[FILENAME_MAX]; /* Filename for *out */
   618    620     const char *zDbFilename;    /* name of the database file */
   619    621     char *zFreeOnClose;         /* Filename to free when closing */
   620    622     const char *zVfs;           /* Name of VFS to use */
   621    623     sqlite3_stmt *pStmt;   /* Current statement if any. */
   622    624     FILE *pLog;            /* Write log output here */
   623    625     int *aiIndent;         /* Array of indents used in MODE_Explain */
................................................................................
   878    880     char **azArg,    /* Text of each result column */
   879    881     char **azCol,    /* Column names */
   880    882     int *aiType      /* Column types */
   881    883   ){
   882    884     int i;
   883    885     ShellState *p = (ShellState*)pArg;
   884    886   
   885         -  switch( p->mode ){
          887  +  switch( p->cMode ){
   886    888       case MODE_Line: {
   887    889         int w = 5;
   888    890         if( azArg==0 ) break;
   889    891         for(i=0; i<nArg; i++){
   890    892           int len = strlen30(azCol[i] ? azCol[i] : "");
   891    893           if( len>w ) w = len;
   892    894         }
................................................................................
   895    897           utf8_printf(p->out,"%*s = %s%s", w, azCol[i],
   896    898                   azArg[i] ? azArg[i] : p->nullValue, p->rowSeparator);
   897    899         }
   898    900         break;
   899    901       }
   900    902       case MODE_Explain:
   901    903       case MODE_Column: {
          904  +      static const int aExplainWidths[] = {4, 13, 4, 4, 4, 13, 2, 13};
          905  +      const int *colWidth;
          906  +      int showHdr;
          907  +      char *rowSep;
          908  +      if( p->cMode==MODE_Column ){
          909  +        colWidth = p->colWidth;
          910  +        showHdr = p->showHeader;
          911  +        rowSep = p->rowSeparator;
          912  +      }else{
          913  +        colWidth = aExplainWidths;
          914  +        showHdr = 1;
          915  +        rowSep = SEP_Row;
          916  +      }
   902    917         if( p->cnt++==0 ){
   903    918           for(i=0; i<nArg; i++){
   904    919             int w, n;
   905    920             if( i<ArraySize(p->colWidth) ){
   906         -            w = p->colWidth[i];
          921  +            w = colWidth[i];
   907    922             }else{
   908    923               w = 0;
   909    924             }
   910    925             if( w==0 ){
   911    926               w = strlen30(azCol[i] ? azCol[i] : "");
   912    927               if( w<10 ) w = 10;
   913    928               n = strlen30(azArg && azArg[i] ? azArg[i] : p->nullValue);
   914    929               if( w<n ) w = n;
   915    930             }
   916    931             if( i<ArraySize(p->actualWidth) ){
   917    932               p->actualWidth[i] = w;
   918    933             }
   919         -          if( p->showHeader ){
          934  +          if( showHdr ){
   920    935               if( w<0 ){
   921    936                 utf8_printf(p->out,"%*.*s%s",-w,-w,azCol[i],
   922         -                      i==nArg-1 ? p->rowSeparator : "  ");
          937  +                      i==nArg-1 ? rowSep : "  ");
   923    938               }else{
   924    939                 utf8_printf(p->out,"%-*.*s%s",w,w,azCol[i],
   925         -                      i==nArg-1 ? p->rowSeparator : "  ");
          940  +                      i==nArg-1 ? rowSep : "  ");
   926    941               }
   927    942             }
   928    943           }
   929         -        if( p->showHeader ){
          944  +        if( showHdr ){
   930    945             for(i=0; i<nArg; i++){
   931    946               int w;
   932    947               if( i<ArraySize(p->actualWidth) ){
   933    948                  w = p->actualWidth[i];
   934    949                  if( w<0 ) w = -w;
   935    950               }else{
   936    951                  w = 10;
   937    952               }
   938    953               utf8_printf(p->out,"%-*.*s%s",w,w,
   939    954                      "----------------------------------------------------------"
   940    955                      "----------------------------------------------------------",
   941         -                    i==nArg-1 ? p->rowSeparator : "  ");
          956  +                    i==nArg-1 ? rowSep : "  ");
   942    957             }
   943    958           }
   944    959         }
   945    960         if( azArg==0 ) break;
   946    961         for(i=0; i<nArg; i++){
   947    962           int w;
   948    963           if( i<ArraySize(p->actualWidth) ){
   949    964              w = p->actualWidth[i];
   950    965           }else{
   951    966              w = 10;
   952    967           }
   953         -        if( p->mode==MODE_Explain && azArg[i] && strlen30(azArg[i])>w ){
          968  +        if( p->cMode==MODE_Explain && azArg[i] && strlen30(azArg[i])>w ){
   954    969             w = strlen30(azArg[i]);
   955    970           }
   956    971           if( i==1 && p->aiIndent && p->pStmt ){
   957    972             if( p->iIndent<p->nIndent ){
   958    973               utf8_printf(p->out, "%*.s", p->aiIndent[p->iIndent], "");
   959    974             }
   960    975             p->iIndent++;
   961    976           }
   962    977           if( w<0 ){
   963    978             utf8_printf(p->out,"%*.*s%s",-w,-w,
   964    979                 azArg[i] ? azArg[i] : p->nullValue,
   965         -              i==nArg-1 ? p->rowSeparator : "  ");
          980  +              i==nArg-1 ? rowSep : "  ");
   966    981           }else{
   967    982             utf8_printf(p->out,"%-*.*s%s",w,w,
   968    983                 azArg[i] ? azArg[i] : p->nullValue,
   969         -              i==nArg-1 ? p->rowSeparator : "  ");
          984  +              i==nArg-1 ? rowSep : "  ");
   970    985           }
   971    986         }
   972    987         break;
   973    988       }
   974    989       case MODE_Semi:
   975    990       case MODE_List: {
   976    991         if( p->cnt++==0 && p->showHeader ){
................................................................................
   982    997         if( azArg==0 ) break;
   983    998         for(i=0; i<nArg; i++){
   984    999           char *z = azArg[i];
   985   1000           if( z==0 ) z = p->nullValue;
   986   1001           utf8_printf(p->out, "%s", z);
   987   1002           if( i<nArg-1 ){
   988   1003             utf8_printf(p->out, "%s", p->colSeparator);
   989         -        }else if( p->mode==MODE_Semi ){
         1004  +        }else if( p->cMode==MODE_Semi ){
   990   1005             utf8_printf(p->out, ";%s", p->rowSeparator);
   991   1006           }else{
   992   1007             utf8_printf(p->out, "%s", p->rowSeparator);
   993   1008           }
   994   1009         }
   995   1010         break;
   996   1011       }
................................................................................
  1487   1502                              "NextIfOpen", "PrevIfOpen", 0 };
  1488   1503     const char *azYield[] = { "Yield", "SeekLT", "SeekGT", "RowSetRead",
  1489   1504                               "Rewind", 0 };
  1490   1505     const char *azGoto[] = { "Goto", 0 };
  1491   1506   
  1492   1507     /* Try to figure out if this is really an EXPLAIN statement. If this
  1493   1508     ** cannot be verified, return early.  */
         1509  +  if( sqlite3_column_count(pSql)!=8 ){
         1510  +    p->cMode = p->mode;
         1511  +    return;
         1512  +  }
  1494   1513     zSql = sqlite3_sql(pSql);
  1495   1514     if( zSql==0 ) return;
  1496   1515     for(z=zSql; *z==' ' || *z=='\t' || *z=='\n' || *z=='\f' || *z=='\r'; z++);
  1497         -  if( sqlite3_strnicmp(z, "explain", 7) ) return;
         1516  +  if( sqlite3_strnicmp(z, "explain", 7) ){
         1517  +    p->cMode = p->mode;
         1518  +    return;
         1519  +  }
  1498   1520   
  1499   1521     for(iOp=0; SQLITE_ROW==sqlite3_step(pSql); iOp++){
  1500   1522       int i;
  1501   1523       int iAddr = sqlite3_column_int(pSql, 0);
  1502   1524       const char *zOp = (const char*)sqlite3_column_text(pSql, 1);
  1503   1525   
  1504   1526       /* Set p2 to the P2 field of the current opcode. Then, assuming that
................................................................................
  1507   1529       ** the current instruction is part of a sub-program generated by an
  1508   1530       ** SQL trigger or foreign key.  */
  1509   1531       int p2 = sqlite3_column_int(pSql, 3);
  1510   1532       int p2op = (p2 + (iOp-iAddr));
  1511   1533   
  1512   1534       /* Grow the p->aiIndent array as required */
  1513   1535       if( iOp>=nAlloc ){
         1536  +      if( iOp==0 ){
         1537  +        /* Do further verfication that this is explain output.  Abort if
         1538  +        ** it is not */
         1539  +        static const char *explainCols[] = {
         1540  +           "addr", "opcode", "p1", "p2", "p3", "p4", "p5", "comment" };
         1541  +        int jj;
         1542  +        for(jj=0; jj<ArraySize(explainCols); jj++){
         1543  +          if( strcmp(sqlite3_column_name(pSql,jj),explainCols[jj])!=0 ){
         1544  +            p->cMode = p->mode;
         1545  +            sqlite3_reset(pSql);
         1546  +            return;
         1547  +          }
         1548  +        }
         1549  +      }
  1514   1550         nAlloc += 100;
  1515   1551         p->aiIndent = (int*)sqlite3_realloc64(p->aiIndent, nAlloc*sizeof(int));
  1516   1552         abYield = (int*)sqlite3_realloc64(abYield, nAlloc*sizeof(int));
  1517   1553       }
  1518   1554       abYield[iOp] = str_in_array(zOp, azYield);
  1519   1555       p->aiIndent[iOp] = 0;
  1520   1556       p->nIndent = iOp+1;
................................................................................
  1610   1646               utf8_printf(pArg->out,"%s\n", sqlite3_column_text(pExplain, 3));
  1611   1647             }
  1612   1648           }
  1613   1649           sqlite3_finalize(pExplain);
  1614   1650           sqlite3_free(zEQP);
  1615   1651         }
  1616   1652   
  1617         -      /* If the shell is currently in ".explain" mode, gather the extra
  1618         -      ** data required to add indents to the output.*/
  1619         -      if( pArg && pArg->mode==MODE_Explain ){
  1620         -        explain_data_prepare(pArg, pStmt);
         1653  +      if( pArg ){
         1654  +        pArg->cMode = pArg->mode;
         1655  +        if( pArg->autoExplain
         1656  +         && sqlite3_column_count(pStmt)==8
         1657  +         && sqlite3_strlike("%EXPLAIN%", sqlite3_sql(pStmt),0)==0
         1658  +        ){
         1659  +          pArg->cMode = MODE_Explain;
         1660  +        }
         1661  +      
         1662  +        /* If the shell is currently in ".explain" mode, gather the extra
         1663  +        ** data required to add indents to the output.*/
         1664  +        if( pArg->cMode==MODE_Explain ){
         1665  +          explain_data_prepare(pArg, pStmt);
         1666  +        }
  1621   1667         }
  1622   1668   
  1623   1669         /* perform the first step.  this will tell us if we
  1624   1670         ** have a result set or not and how wide it is.
  1625   1671         */
  1626   1672         rc = sqlite3_step(pStmt);
  1627   1673         /* if we have a result set... */
................................................................................
  1643   1689               for(i=0; i<nCol; i++){
  1644   1690                 azCols[i] = (char *)sqlite3_column_name(pStmt, i);
  1645   1691               }
  1646   1692               do{
  1647   1693                 /* extract the data and data types */
  1648   1694                 for(i=0; i<nCol; i++){
  1649   1695                   aiTypes[i] = x = sqlite3_column_type(pStmt, i);
  1650         -                if( x==SQLITE_BLOB && pArg && pArg->mode==MODE_Insert ){
         1696  +                if( x==SQLITE_BLOB && pArg && pArg->cMode==MODE_Insert ){
  1651   1697                     azVals[i] = "";
  1652   1698                   }else{
  1653   1699                     azVals[i] = (char*)sqlite3_column_text(pStmt, i);
  1654   1700                   }
  1655   1701                   if( !azVals[i] && (aiTypes[i]!=SQLITE_NULL) ){
  1656   1702                     rc = SQLITE_NOMEM;
  1657   1703                     break; /* from for */
................................................................................
  1863   1909     ".dbinfo ?DB?           Show status information about the database\n"
  1864   1910     ".dump ?TABLE? ...      Dump the database in an SQL text format\n"
  1865   1911     "                         If TABLE specified, only dump tables matching\n"
  1866   1912     "                         LIKE pattern TABLE.\n"
  1867   1913     ".echo on|off           Turn command echo on or off\n"
  1868   1914     ".eqp on|off            Enable or disable automatic EXPLAIN QUERY PLAN\n"
  1869   1915     ".exit                  Exit this program\n"
  1870         -  ".explain ?on|off?      Turn output mode suitable for EXPLAIN on or off.\n"
  1871         -  "                         With no args, it turns EXPLAIN on.\n"
         1916  +  ".explain ?on|off|auto? Turn EXPLAIN output mode on or off or to automatic\n"
  1872   1917     ".fullschema            Show schema and the content of sqlite_stat tables\n"
  1873   1918     ".headers on|off        Turn display of headers on or off\n"
  1874   1919     ".help                  Show this message\n"
  1875   1920     ".import FILE TABLE     Import data from FILE into TABLE\n"
  1876   1921     ".indexes ?TABLE?       Show names of all indexes\n"
  1877   1922     "                         If TABLE specified, only show indexes for tables\n"
  1878   1923     "                         matching LIKE pattern TABLE.\n"
................................................................................
  2851   2896   
  2852   2897     if( c=='d' && n>1 && strncmp(azArg[0], "databases", n)==0 ){
  2853   2898       ShellState data;
  2854   2899       char *zErrMsg = 0;
  2855   2900       open_db(p, 0);
  2856   2901       memcpy(&data, p, sizeof(data));
  2857   2902       data.showHeader = 1;
  2858         -    data.mode = MODE_Column;
         2903  +    data.cMode = data.mode = MODE_Column;
  2859   2904       data.colWidth[0] = 3;
  2860   2905       data.colWidth[1] = 15;
  2861   2906       data.colWidth[2] = 58;
  2862   2907       data.cnt = 0;
  2863   2908       sqlite3_exec(p->db, "PRAGMA database_list; ", callback, &data, &zErrMsg);
  2864   2909       if( zErrMsg ){
  2865   2910         utf8_printf(stderr,"Error: %s\n", zErrMsg);
................................................................................
  2946   2991   
  2947   2992     if( c=='e' && strncmp(azArg[0], "exit", n)==0 ){
  2948   2993       if( nArg>1 && (rc = (int)integerValue(azArg[1]))!=0 ) exit(rc);
  2949   2994       rc = 2;
  2950   2995     }else
  2951   2996   
  2952   2997     if( c=='e' && strncmp(azArg[0], "explain", n)==0 ){
  2953         -    int val = nArg>=2 ? booleanValue(azArg[1]) : 1;
  2954         -    if(val == 1) {
  2955         -      if(!p->normalMode.valid) {
  2956         -        p->normalMode.valid = 1;
  2957         -        p->normalMode.mode = p->mode;
  2958         -        p->normalMode.showHeader = p->showHeader;
  2959         -        memcpy(p->normalMode.colWidth,p->colWidth,sizeof(p->colWidth));
         2998  +    int val = 1;
         2999  +    if( nArg>=2 ){
         3000  +      if( strcmp(azArg[1],"auto")==0 ){
         3001  +        val = 99;
         3002  +      }else{
         3003  +        val =  booleanValue(azArg[1]);
  2960   3004         }
  2961         -      /* We could put this code under the !p->explainValid
  2962         -      ** condition so that it does not execute if we are already in
  2963         -      ** explain mode. However, always executing it allows us an easy
  2964         -      ** was to reset to explain mode in case the user previously
  2965         -      ** did an .explain followed by a .width, .mode or .header
  2966         -      ** command.
  2967         -      */
         3005  +    }
         3006  +    if( val==1 && p->mode!=MODE_Explain ){
         3007  +      p->normalMode = p->mode;
  2968   3008         p->mode = MODE_Explain;
  2969         -      p->showHeader = 1;
  2970         -      memset(p->colWidth,0,sizeof(p->colWidth));
  2971         -      p->colWidth[0] = 4;                  /* addr */
  2972         -      p->colWidth[1] = 13;                 /* opcode */
  2973         -      p->colWidth[2] = 4;                  /* P1 */
  2974         -      p->colWidth[3] = 4;                  /* P2 */
  2975         -      p->colWidth[4] = 4;                  /* P3 */
  2976         -      p->colWidth[5] = 13;                 /* P4 */
  2977         -      p->colWidth[6] = 2;                  /* P5 */
  2978         -      p->colWidth[7] = 13;                  /* Comment */
  2979         -    }else if (p->normalMode.valid) {
  2980         -      p->normalMode.valid = 0;
  2981         -      p->mode = p->normalMode.mode;
  2982         -      p->showHeader = p->normalMode.showHeader;
  2983         -      memcpy(p->colWidth,p->normalMode.colWidth,sizeof(p->colWidth));
         3009  +      p->autoExplain = 0;
         3010  +    }else if( val==0 ){
         3011  +      if( p->mode==MODE_Explain ) p->mode = p->normalMode;
         3012  +      p->autoExplain = 0;
         3013  +    }else if( val==99 ){
         3014  +      if( p->mode==MODE_Explain ) p->mode = p->normalMode;
         3015  +      p->autoExplain = 1;
  2984   3016       }
  2985   3017     }else
  2986   3018   
  2987   3019     if( c=='f' && strncmp(azArg[0], "fullschema", n)==0 ){
  2988   3020       ShellState data;
  2989   3021       char *zErrMsg = 0;
  2990   3022       int doStats = 0;
................................................................................
  2992   3024         raw_printf(stderr, "Usage: .fullschema\n");
  2993   3025         rc = 1;
  2994   3026         goto meta_command_exit;
  2995   3027       }
  2996   3028       open_db(p, 0);
  2997   3029       memcpy(&data, p, sizeof(data));
  2998   3030       data.showHeader = 0;
  2999         -    data.mode = MODE_Semi;
         3031  +    data.cMode = data.mode = MODE_Semi;
  3000   3032       rc = sqlite3_exec(p->db,
  3001   3033          "SELECT sql FROM"
  3002   3034          "  (SELECT sql sql, type type, tbl_name tbl_name, name name, rowid x"
  3003   3035          "     FROM sqlite_master UNION ALL"
  3004   3036          "   SELECT sql, type, tbl_name, name, rowid FROM sqlite_temp_master) "
  3005   3037          "WHERE type!='meta' AND sql NOTNULL AND name NOT LIKE 'sqlite_%' "
  3006   3038          "ORDER BY rowid",
................................................................................
  3017   3049       }
  3018   3050       if( doStats==0 ){
  3019   3051         raw_printf(p->out, "/* No STAT tables available */\n");
  3020   3052       }else{
  3021   3053         raw_printf(p->out, "ANALYZE sqlite_master;\n");
  3022   3054         sqlite3_exec(p->db, "SELECT 'ANALYZE sqlite_master'",
  3023   3055                      callback, &data, &zErrMsg);
  3024         -      data.mode = MODE_Insert;
         3056  +      data.cMode = data.mode = MODE_Insert;
  3025   3057         data.zDestTable = "sqlite_stat1";
  3026   3058         shell_exec(p->db, "SELECT * FROM sqlite_stat1",
  3027   3059                    shell_callback, &data,&zErrMsg);
  3028   3060         data.zDestTable = "sqlite_stat3";
  3029   3061         shell_exec(p->db, "SELECT * FROM sqlite_stat3",
  3030   3062                    shell_callback, &data,&zErrMsg);
  3031   3063         data.zDestTable = "sqlite_stat4";
................................................................................
  3249   3281     if( c=='i' && (strncmp(azArg[0], "indices", n)==0
  3250   3282                    || strncmp(azArg[0], "indexes", n)==0) ){
  3251   3283       ShellState data;
  3252   3284       char *zErrMsg = 0;
  3253   3285       open_db(p, 0);
  3254   3286       memcpy(&data, p, sizeof(data));
  3255   3287       data.showHeader = 0;
  3256         -    data.mode = MODE_List;
         3288  +    data.cMode = data.mode = MODE_List;
  3257   3289       if( nArg==1 ){
  3258   3290         rc = sqlite3_exec(p->db,
  3259   3291           "SELECT name FROM sqlite_master "
  3260   3292           "WHERE type='index' AND name NOT LIKE 'sqlite_%' "
  3261   3293           "UNION ALL "
  3262   3294           "SELECT name FROM sqlite_temp_master "
  3263   3295           "WHERE type='index' "
................................................................................
  3435   3467         sqlite3_snprintf(sizeof(p->colSeparator), p->colSeparator, SEP_Unit);
  3436   3468         sqlite3_snprintf(sizeof(p->rowSeparator), p->rowSeparator, SEP_Record);
  3437   3469       }else {
  3438   3470         raw_printf(stderr, "Error: mode should be one of: "
  3439   3471            "ascii column csv html insert line list tabs tcl\n");
  3440   3472         rc = 1;
  3441   3473       }
         3474  +    p->cMode = p->mode;
  3442   3475     }else
  3443   3476   
  3444   3477     if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 ){
  3445   3478       if( nArg==2 ){
  3446   3479         sqlite3_snprintf(sizeof(p->nullValue), p->nullValue,
  3447   3480                          "%.*s", (int)ArraySize(p->nullValue)-1, azArg[1]);
  3448   3481       }else{
................................................................................
  3624   3657   
  3625   3658     if( c=='s' && strncmp(azArg[0], "schema", n)==0 ){
  3626   3659       ShellState data;
  3627   3660       char *zErrMsg = 0;
  3628   3661       open_db(p, 0);
  3629   3662       memcpy(&data, p, sizeof(data));
  3630   3663       data.showHeader = 0;
  3631         -    data.mode = MODE_Semi;
         3664  +    data.cMode = data.mode = MODE_Semi;
  3632   3665       if( nArg==2 ){
  3633   3666         int i;
  3634   3667         for(i=0; azArg[1][i]; i++) azArg[1][i] = ToLower(azArg[1][i]);
  3635   3668         if( strcmp(azArg[1],"sqlite_master")==0 ){
  3636   3669           char *new_argv[2], *new_colv[2];
  3637   3670           new_argv[0] = "CREATE TABLE sqlite_master (\n"
  3638   3671                         "  type text,\n"
................................................................................
  3772   3805       if( nArg!=1 ){
  3773   3806         raw_printf(stderr, "Usage: .show\n");
  3774   3807         rc = 1;
  3775   3808         goto meta_command_exit;
  3776   3809       }
  3777   3810       utf8_printf(p->out, "%12.12s: %s\n","echo", p->echoOn ? "on" : "off");
  3778   3811       utf8_printf(p->out, "%12.12s: %s\n","eqp", p->autoEQP ? "on" : "off");
  3779         -    utf8_printf(p->out,"%9.9s: %s\n","explain",p->normalMode.valid?"on":"off");
         3812  +    utf8_printf(p->out, "%12.12s: %s\n","explain",
         3813  +         p->mode==MODE_Explain ? "on" : p->autoExplain ? "auto" : "off");
  3780   3814       utf8_printf(p->out,"%12.12s: %s\n","headers", p->showHeader ? "on" : "off");
  3781   3815       utf8_printf(p->out, "%12.12s: %s\n","mode", modeDescr[p->mode]);
  3782   3816       utf8_printf(p->out, "%12.12s: ", "nullvalue");
  3783   3817         output_c_string(p->out, p->nullValue);
  3784   3818         raw_printf(p->out, "\n");
  3785   3819       utf8_printf(p->out,"%12.12s: %s\n","output",
  3786   3820               strlen30(p->outfile) ? p->outfile : "stdout");
................................................................................
  4571   4605   }
  4572   4606   
  4573   4607   /*
  4574   4608   ** Initialize the state information in data
  4575   4609   */
  4576   4610   static void main_init(ShellState *data) {
  4577   4611     memset(data, 0, sizeof(*data));
  4578         -  data->mode = MODE_List;
         4612  +  data->normalMode = data->cMode = data->mode = MODE_List;
         4613  +  data->autoExplain = 1;
  4579   4614     memcpy(data->colSeparator,SEP_Column, 2);
  4580   4615     memcpy(data->rowSeparator,SEP_Row, 2);
  4581   4616     data->showHeader = 0;
  4582   4617     data->shellFlgs = SHFLG_Lookaside;
  4583   4618     sqlite3_config(SQLITE_CONFIG_URI, 1);
  4584   4619     sqlite3_config(SQLITE_CONFIG_LOG, shellLog, data);
  4585   4620     sqlite3_config(SQLITE_CONFIG_MULTITHREAD);
................................................................................
  4904   4939           }
  4905   4940         }
  4906   4941       }else{
  4907   4942         utf8_printf(stderr,"%s: Error: unknown option: %s\n", Argv0, z);
  4908   4943         raw_printf(stderr,"Use -help for a list of options.\n");
  4909   4944         return 1;
  4910   4945       }
         4946  +    data.cMode = data.mode;
  4911   4947     }
  4912   4948   
  4913   4949     if( !readStdin ){
  4914   4950       /* Run all arguments that do not begin with '-' as if they were separate
  4915   4951       ** command-line inputs, except for the argToSkip argument which contains
  4916   4952       ** the database filename.
  4917   4953       */

Changes to src/sqlite.h.in.

   343    343   ** ^If an error occurs while evaluating the SQL statements passed into
   344    344   ** sqlite3_exec(), then execution of the current statement stops and
   345    345   ** subsequent statements are skipped.  ^If the 5th parameter to sqlite3_exec()
   346    346   ** is not NULL then any error message is written into memory obtained
   347    347   ** from [sqlite3_malloc()] and passed back through the 5th parameter.
   348    348   ** To avoid memory leaks, the application should invoke [sqlite3_free()]
   349    349   ** on error message strings returned through the 5th parameter of
   350         -** of sqlite3_exec() after the error message string is no longer needed.
          350  +** sqlite3_exec() after the error message string is no longer needed.
   351    351   ** ^If the 5th parameter to sqlite3_exec() is not NULL and no errors
   352    352   ** occur, then sqlite3_exec() sets the pointer in its 5th parameter to
   353    353   ** NULL before returning.
   354    354   **
   355    355   ** ^If an sqlite3_exec() callback returns non-zero, the sqlite3_exec()
   356    356   ** routine returns SQLITE_ABORT without invoking the callback again and
   357    357   ** without running any subsequent SQL statements.

Changes to src/sqliteInt.h.

  3106   3106     union {                                   /* Extra data for callback */
  3107   3107       NameContext *pNC;                          /* Naming context */
  3108   3108       int n;                                     /* A counter */
  3109   3109       int iCur;                                  /* A cursor number */
  3110   3110       SrcList *pSrcList;                         /* FROM clause */
  3111   3111       struct SrcCount *pSrcCount;                /* Counting column references */
  3112   3112       struct CCurHint *pCCurHint;                /* Used by codeCursorHint() */
         3113  +    int *aiCol;                                /* array of column indexes */
  3113   3114     } u;
  3114   3115   };
  3115   3116   
  3116   3117   /* Forward declarations */
  3117   3118   int sqlite3WalkExpr(Walker*, Expr*);
  3118   3119   int sqlite3WalkExprList(Walker*, ExprList*);
  3119   3120   int sqlite3WalkSelect(Walker*, Select*);
................................................................................
  3175   3176   int sqlite3CorruptError(int);
  3176   3177   int sqlite3MisuseError(int);
  3177   3178   int sqlite3CantopenError(int);
  3178   3179   #define SQLITE_CORRUPT_BKPT sqlite3CorruptError(__LINE__)
  3179   3180   #define SQLITE_MISUSE_BKPT sqlite3MisuseError(__LINE__)
  3180   3181   #define SQLITE_CANTOPEN_BKPT sqlite3CantopenError(__LINE__)
  3181   3182   
         3183  +/*
         3184  +** FTS3 and FTS4 both require virtual table support
         3185  +*/
         3186  +#if defined(SQLITE_OMIT_VIRTUALTABLE)
         3187  +# undef SQLITE_ENABLE_FTS3
         3188  +# undef SQLITE_ENABLE_FTS4
         3189  +#endif
  3182   3190   
  3183   3191   /*
  3184   3192   ** FTS4 is really an extension for FTS3.  It is enabled using the
  3185   3193   ** SQLITE_ENABLE_FTS3 macro.  But to avoid confusion we also call
  3186   3194   ** the SQLITE_ENABLE_FTS4 macro to serve as an alias for SQLITE_ENABLE_FTS3.
  3187   3195   */
  3188   3196   #if defined(SQLITE_ENABLE_FTS4) && !defined(SQLITE_ENABLE_FTS3)
................................................................................
  3551   3559   int sqlite3IsRowid(const char*);
  3552   3560   void sqlite3GenerateRowDelete(
  3553   3561       Parse*,Table*,Trigger*,int,int,int,i16,u8,u8,u8,int);
  3554   3562   void sqlite3GenerateRowIndexDelete(Parse*, Table*, int, int, int*, int);
  3555   3563   int sqlite3GenerateIndexKey(Parse*, Index*, int, int, int, int*,Index*,int);
  3556   3564   void sqlite3ResolvePartIdxLabel(Parse*,int);
  3557   3565   void sqlite3GenerateConstraintChecks(Parse*,Table*,int*,int,int,int,int,
  3558         -                                     u8,u8,int,int*);
         3566  +                                     u8,u8,int,int*,int*);
  3559   3567   void sqlite3CompleteInsertion(Parse*,Table*,int,int,int,int*,int,int,int);
  3560   3568   int sqlite3OpenTableAndIndices(Parse*, Table*, int, u8, int, u8*, int*, int*);
  3561   3569   void sqlite3BeginWriteOperation(Parse*, int, int);
  3562   3570   void sqlite3MultiWrite(Parse*);
  3563   3571   void sqlite3MayAbort(Parse*);
  3564   3572   void sqlite3HaltConstraint(Parse*, int, int, char*, i8, u8);
  3565   3573   void sqlite3UniqueConstraint(Parse*, int, Index*);
................................................................................
  3770   3778   int sqlite3FindDb(sqlite3*, Token*);
  3771   3779   int sqlite3FindDbName(sqlite3 *, const char *);
  3772   3780   int sqlite3AnalysisLoad(sqlite3*,int iDB);
  3773   3781   void sqlite3DeleteIndexSamples(sqlite3*,Index*);
  3774   3782   void sqlite3DefaultRowEst(Index*);
  3775   3783   void sqlite3RegisterLikeFunctions(sqlite3*, int);
  3776   3784   int sqlite3IsLikeFunction(sqlite3*,Expr*,int*,char*);
  3777         -void sqlite3MinimumFileFormat(Parse*, int, int);
  3778   3785   void sqlite3SchemaClear(void *);
  3779   3786   Schema *sqlite3SchemaGet(sqlite3 *, Btree *);
  3780   3787   int sqlite3SchemaToIndex(sqlite3 *db, Schema *);
  3781   3788   KeyInfo *sqlite3KeyInfoAlloc(sqlite3*,int,int);
  3782   3789   void sqlite3KeyInfoUnref(KeyInfo*);
  3783   3790   KeyInfo *sqlite3KeyInfoRef(KeyInfo*);
  3784   3791   KeyInfo *sqlite3KeyInfoOfIndex(Parse*, Index*);

Changes to src/update.c.

   568    568     if( !isView ){
   569    569       int addr1 = 0;        /* Address of jump instruction */
   570    570       int bReplace = 0;     /* True if REPLACE conflict resolution might happen */
   571    571   
   572    572       /* Do constraint checks. */
   573    573       assert( regOldRowid>0 );
   574    574       sqlite3GenerateConstraintChecks(pParse, pTab, aRegIdx, iDataCur, iIdxCur,
   575         -        regNewRowid, regOldRowid, chngKey, onError, labelContinue, &bReplace);
          575  +        regNewRowid, regOldRowid, chngKey, onError, labelContinue, &bReplace,
          576  +        aXRef);
   576    577   
   577    578       /* Do FK constraint checks. */
   578    579       if( hasFK ){
   579    580         sqlite3FkCheck(pParse, pTab, regOldRowid, 0, aXRef, chngKey);
   580    581       }
   581    582   
   582    583       /* Delete the index entries associated with the current record.  */

Changes to src/where.c.

  3434   3434   
  3435   3435   /*
  3436   3436   ** Return the cost of sorting nRow rows, assuming that the keys have 
  3437   3437   ** nOrderby columns and that the first nSorted columns are already in
  3438   3438   ** order.
  3439   3439   */
  3440   3440   static LogEst whereSortingCost(
  3441         -  WhereInfo *pWInfo,
  3442   3441     LogEst nRow,
  3443   3442     int nOrderBy,
  3444   3443     int nSorted
  3445   3444   ){
  3446   3445     /* TUNING: Estimated cost of a full external sort, where N is 
  3447   3446     ** the number of rows to sort is:
  3448   3447     **
................................................................................
  3456   3455     **
  3457   3456     ** The (Y/X) term is implemented using stack variable rScale
  3458   3457     ** below.  */
  3459   3458     LogEst rScale, rSortCost;
  3460   3459     assert( nOrderBy>0 && 66==sqlite3LogEst(100) );
  3461   3460     rScale = sqlite3LogEst((nOrderBy-nSorted)*100/nOrderBy) - 66;
  3462   3461     rSortCost = nRow + estLog(nRow) + rScale + 16;
  3463         -
  3464         -  /* TUNING: The cost of implementing DISTINCT using a B-TREE is
  3465         -  ** similar but with a larger constant of proportionality. 
  3466         -  ** Multiply by an additional factor of 3.0.  */
  3467         -  if( pWInfo->wctrlFlags & WHERE_WANT_DISTINCT ){
  3468         -    rSortCost += 16;
  3469         -  }
  3470         -
  3471   3462     return rSortCost;
  3472   3463   }
  3473   3464   
  3474   3465   /*
  3475   3466   ** Given the list of WhereLoop objects at pWInfo->pLoops, this routine
  3476   3467   ** attempts to find the lowest cost path that visits each WhereLoop
  3477   3468   ** once.  This path is then loaded into the pWInfo->a[].pWLoop fields.
................................................................................
  3597   3588                          iLoop, pWLoop, &revMask);
  3598   3589           }else{
  3599   3590             revMask = pFrom->revLoop;
  3600   3591           }
  3601   3592           if( isOrdered>=0 && isOrdered<nOrderBy ){
  3602   3593             if( aSortCost[isOrdered]==0 ){
  3603   3594               aSortCost[isOrdered] = whereSortingCost(
  3604         -                pWInfo, nRowEst, nOrderBy, isOrdered
         3595  +                nRowEst, nOrderBy, isOrdered
  3605   3596               );
  3606   3597             }
  3607   3598             rCost = sqlite3LogEstAdd(rUnsorted, aSortCost[isOrdered]);
  3608   3599   
  3609   3600             WHERETRACE(0x002,
  3610   3601                 ("---- sort cost=%-3d (%d/%d) increases cost %3d to %-3d\n",
  3611   3602                  aSortCost[isOrdered], (nOrderBy-isOrdered), nOrderBy, 

Changes to test/alter3.test.

   180    180       ALTER TABLE t1 ADD c;
   181    181       SELECT * FROM t1;
   182    182     }
   183    183   } {1 100 {} 2 300 {}}
   184    184   if {!$has_codec} {
   185    185     do_test alter3-3.3 {
   186    186       get_file_format
   187         -  } {3}
          187  +  } {4}
   188    188   }
   189    189   ifcapable schema_version {
   190    190     do_test alter3-3.4 {
   191    191       execsql {
   192    192         PRAGMA schema_version;
   193    193       }
   194    194     } {11}
................................................................................
   216    216       ALTER TABLE t1 ADD c DEFAULT 'hello world';
   217    217       SELECT * FROM t1;
   218    218     }
   219    219   } {1 100 {hello world} 2 300 {hello world}}
   220    220   if {!$has_codec} {
   221    221     do_test alter3-4.3 {
   222    222       get_file_format
   223         -  } {3}
          223  +  } {4}
   224    224   }
   225    225   ifcapable schema_version {
   226    226     do_test alter3-4.4 {
   227    227       execsql {
   228    228         PRAGMA schema_version;
   229    229       }
   230    230     } {21}
................................................................................
   266    266           PRAGMA aux.schema_version;
   267    267         }
   268    268       } {31}
   269    269     }
   270    270     if {!$has_codec} {
   271    271       do_test alter3-5.5 {
   272    272         list [get_file_format test2.db] [get_file_format]
   273         -    } {2 3}
          273  +    } {4 4}
   274    274     }
   275    275     do_test alter3-5.6 {
   276    276       execsql {
   277    277         ALTER TABLE aux.t1 ADD COLUMN d DEFAULT 1000;
   278    278         SELECT sql FROM aux.sqlite_master;
   279    279       }
   280    280     } {{CREATE TABLE t1(a,b, c VARCHAR(128), d DEFAULT 1000)}}
................................................................................
   343    343       } {1}
   344    344       do_test alter3-7.2 {
   345    345         execsql {
   346    346           CREATE TABLE abc(a, b, c);
   347    347           ALTER TABLE abc ADD d DEFAULT NULL;
   348    348         }
   349    349         get_file_format
   350         -    } {2}
          350  +    } {4}
   351    351       do_test alter3-7.3 {
   352    352         execsql {
   353    353           ALTER TABLE abc ADD e DEFAULT 10;
   354    354         }
   355    355         get_file_format
   356         -    } {3}
          356  +    } {4}
   357    357       do_test alter3-7.4 {
   358    358         execsql {
   359    359           ALTER TABLE abc ADD f DEFAULT NULL;
   360    360         }
   361    361         get_file_format
   362         -    } {3}
          362  +    } {4}
   363    363       do_test alter3-7.5 {
   364    364         execsql {
   365    365           VACUUM;
   366    366         }
   367    367         get_file_format
   368    368       } {1}
   369    369     }

Changes to test/check.test.

   454    454   
   455    455   # 2013-08-02:  Silently ignore database name qualifiers in CHECK constraints.
   456    456   #
   457    457   do_execsql_test 8.1 {
   458    458     CREATE TABLE t810(a, CHECK( main.t810.a>0 ));
   459    459     CREATE TABLE t811(b, CHECK( xyzzy.t811.b BETWEEN 5 AND 10 ));
   460    460   } {}
          461  +
          462  +# Make sure check constraints involving the ROWID are not ignored
          463  +#
          464  +do_execsql_test 9.1 {
          465  +  CREATE TABLE t1(
          466  +    a INTEGER PRIMARY KEY,
          467  +    b INTEGER NOT NULL CONSTRAINT 'b-check' CHECK( b>a ),
          468  +    c INTEGER NOT NULL CONSTRAINT 'c-check' CHECK( c>rowid*2 ),
          469  +    d INTEGER NOT NULL CONSTRAINT 'd-check' CHECK( d BETWEEN b AND c )
          470  +  );
          471  +  INSERT INTO t1(a,b,c,d) VALUES(1,2,4,3),(2,4,6,5),(3,10,30,20);
          472  +} {}
          473  +do_catchsql_test 9.2 {
          474  +  UPDATE t1 SET b=0 WHERE a=1;
          475  +} {1 {CHECK constraint failed: b-check}}
          476  +do_catchsql_test 9.3 {
          477  +  UPDATE t1 SET c=a*2 WHERE a=1;
          478  +} {1 {CHECK constraint failed: c-check}}
          479  +
          480  +
   461    481   
   462    482   finish_test

Changes to tool/mkautoconfamal.sh.

    18     18   # may fail for old /bin/sh interpreters.
    19     19   #
    20     20   set -e
    21     21   set -u
    22     22   
    23     23   TMPSPACE=./mkpkg_tmp_dir
    24     24   VERSION=`cat $TOP/VERSION`
           25  +HASH=`sed 's/^\(..........\).*/\1/' $TOP/manifest.uuid`
           26  +DATETIME=`grep '^D' $TOP/manifest | sed -e 's/[^0-9]//g' -e 's/\(............\).*/\1/'`
    25     27   
    26         -# Set global variable $ARTIFACT to the "3xxyyzz" string incorporated 
    27         -# into artifact filenames. And $VERSION2 to the "3.x.y[.z]" form.
    28         -xx=`echo $VERSION|sed 's/3\.\([0-9]*\)\..*/\1/'`
    29         -yy=`echo $VERSION|sed 's/3\.[^.]*\.\([0-9]*\).*/\1/'`
    30         -zz=0
    31         -set +e
    32         -  zz=`echo $VERSION|sed 's/3\.[^.]*\.[^.]*\.\([0-9]*\).*/\1/'|grep -v '\.'`
    33         -set -e
    34         -ARTIFACT=`printf "3%.2d%.2d%.2d" $xx $yy $zz`
           28  +# If this script is given an argument of --snapshot, then generate a
           29  +# snapshot tarball named for the current checkout SHA1 hash, rather than
           30  +# the version number.
           31  +#
           32  +if test "$#" -ge 1 -a x$1 != x--snapshot
           33  +then
           34  +  # Set global variable $ARTIFACT to the "3xxyyzz" string incorporated 
           35  +  # into artifact filenames. And $VERSION2 to the "3.x.y[.z]" form.
           36  +  xx=`echo $VERSION|sed 's/3\.\([0-9]*\)\..*/\1/'`
           37  +  yy=`echo $VERSION|sed 's/3\.[^.]*\.\([0-9]*\).*/\1/'`
           38  +  zz=0
           39  +  set +e
           40  +    zz=`echo $VERSION|sed 's/3\.[^.]*\.[^.]*\.\([0-9]*\).*/\1/'|grep -v '\.'`
           41  +  set -e
           42  +  TARBALLNAME=`printf "sqlite-autoconf-3%.2d%.2d%.2d" $xx $yy $zz`
           43  +else
           44  +  TARBALLNAME=sqlite-snapshot-$DATETIME
           45  +fi
    35     46   
    36     47   rm -rf $TMPSPACE
    37     48   cp -R $TOP/autoconf       $TMPSPACE
    38     49   cp sqlite3.c              $TMPSPACE
    39     50   cp sqlite3.h              $TMPSPACE
    40     51   cp sqlite3ext.h           $TMPSPACE
    41     52   cp $TOP/sqlite3.1         $TMPSPACE
................................................................................
    69     80   cd tea
    70     81   autoconf
    71     82   rm -rf autom4te.cache
    72     83   
    73     84   cd ../
    74     85   ./configure && make dist
    75     86   tar -xzf sqlite-$VERSION.tar.gz
    76         -mv sqlite-$VERSION sqlite-autoconf-$ARTIFACT
    77         -tar -czf sqlite-autoconf-$ARTIFACT.tar.gz sqlite-autoconf-$ARTIFACT
    78         -mv sqlite-autoconf-$ARTIFACT.tar.gz ..
           87  +mv sqlite-$VERSION $TARBALLNAME
           88  +tar -czf $TARBALLNAME.tar.gz $TARBALLNAME
           89  +mv $TARBALLNAME.tar.gz ..
           90  +cd ..
           91  +ls -l $TARBALLNAME.tar.gz

Changes to tool/mkvsix.tcl.

   385    385   set shortNames(WinRT,2013) SQLite.WinRT.2013
   386    386   set shortNames(WinRT81,2013) SQLite.WinRT81
   387    387   set shortNames(WP80,2012) SQLite.WP80
   388    388   set shortNames(WP80,2013) SQLite.WP80.2013
   389    389   set shortNames(WP81,2013) SQLite.WP81
   390    390   set shortNames(Win32,2012) SQLite.Win32
   391    391   set shortNames(Win32,2013) SQLite.Win32.2013
   392         -set shortNames(UAP,2015) SQLite.UAP.2015
          392  +set shortNames(UWP,2015) SQLite.UWP.2015
   393    393   
   394    394   set displayNames(WinRT,2012) "SQLite for Windows Runtime"
   395    395   set displayNames(WinRT,2013) "SQLite for Windows Runtime"
   396    396   set displayNames(WinRT81,2013) "SQLite for Windows Runtime (Windows 8.1)"
   397    397   set displayNames(WP80,2012) "SQLite for Windows Phone"
   398    398   set displayNames(WP80,2013) "SQLite for Windows Phone"
   399    399   set displayNames(WP81,2013) "SQLite for Windows Phone 8.1"
   400    400   set displayNames(Win32,2012) "SQLite for Windows"
   401    401   set displayNames(Win32,2013) "SQLite for Windows"
   402         -set displayNames(UAP,2015) "SQLite for Universal App Platform"
          402  +set displayNames(UWP,2015) "SQLite for Universal Windows Platform"
   403    403   
   404    404   if {[string equal $packageFlavor WinRT]} then {
   405    405     set shortName $shortNames($packageFlavor,$vsVersion)
   406    406     set displayName $displayNames($packageFlavor,$vsVersion)
   407    407     set targetPlatformIdentifier Windows
   408    408     set targetPlatformVersion v8.0
   409    409     set minVsVersion [getMinVsVersionXmlChunk $vsVersion]
................................................................................
   451    451     set targetPlatformVersion v8.1
   452    452     set minVsVersion [getMinVsVersionXmlChunk $vsVersion]
   453    453     set maxPlatformVersion \
   454    454         [getMaxPlatformVersionXmlChunk $packageFlavor $vsVersion]
   455    455     set extraSdkPath "\\..\\$targetPlatformIdentifier"
   456    456     set extraFileListAttributes \
   457    457         [getExtraFileListXmlChunk $packageFlavor $vsVersion]
   458         -} elseif {[string equal $packageFlavor UAP]} then {
          458  +} elseif {[string equal $packageFlavor UWP]} then {
   459    459     if {$vsVersion ne "2015"} then {
   460    460       fail [appendArgs \
   461    461           "unsupported combination, package flavor " $packageFlavor \
   462    462           " is only supported with Visual Studio 2015"]
   463    463     }
   464    464     set shortName $shortNames($packageFlavor,$vsVersion)
   465    465     set displayName $displayNames($packageFlavor,$vsVersion)
   466         -  set targetPlatformIdentifier UAP
          466  +  set targetPlatformIdentifier UWP
   467    467     set targetPlatformVersion v0.8.0.0
   468    468     set minVsVersion [getMinVsVersionXmlChunk $vsVersion]
   469    469     set maxPlatformVersion \
   470    470         [getMaxPlatformVersionXmlChunk $packageFlavor $vsVersion]
   471    471     set extraSdkPath "\\..\\$targetPlatformIdentifier"
   472    472     set extraFileListAttributes \
   473    473         [getExtraFileListXmlChunk $packageFlavor $vsVersion]
................................................................................
   481    481         [getMaxPlatformVersionXmlChunk $packageFlavor $vsVersion]
   482    482     set extraSdkPath ""
   483    483     set extraFileListAttributes \
   484    484         [getExtraFileListXmlChunk $packageFlavor $vsVersion]
   485    485   } else {
   486    486     fail [appendArgs \
   487    487         "unsupported package flavor, must be one of: " \
   488         -      [list WinRT WinRT81 WP80 WP81 UAP Win32]]
          488  +      [list WinRT WinRT81 WP80 WP81 UWP Win32]]
   489    489   }
   490    490   
   491    491   ###############################################################################
   492    492   
   493    493   #
   494    494   # NOTE: Evaluate the user-specific customizations file, if it exists.
   495    495   #

Changes to tool/warnings.sh.

     1      1   #/bin/sh
     2      2   #
     3      3   # Run this script in a directory with a working makefile to check for 
     4      4   # compiler warnings in SQLite.
     5      5   #
     6      6   rm -f sqlite3.c
     7      7   make sqlite3.c
     8         -echo '********** No optimizations.  Includes FTS4 and RTREE *********'
            8  +echo '********** No optimizations.  Includes FTS4/5, RTREE, JSON1 ***'
     9      9   gcc -c -Wshadow -Wall -Wextra -pedantic-errors -Wno-long-long -std=c89 \
    10     10         -ansi -DHAVE_STDINT_H -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_RTREE \
           11  +      -DSQLITE_ENABLE_FTS5 -DSQLITE_ENABLE_JSON1 \
    11     12         sqlite3.c
    12     13   echo '********** Android configuration ******************************'
    13     14   gcc -c \
    14     15     -DHAVE_USLEEP=1 \
    15     16     -DSQLITE_HAVE_ISNAN \
    16     17     -DSQLITE_DEFAULT_JOURNAL_SIZE_LIMIT=1048576 \
    17     18     -DSQLITE_THREADSAFE=2 \
................................................................................
    31     32     -DUSE_PREAD64 \
    32     33     -Wshadow -Wall -Wextra \
    33     34     -Os sqlite3.c shell.c
    34     35   echo '********** No optimizations. ENABLE_STAT4. THREADSAFE=0 *******'
    35     36   gcc -c -Wshadow -Wall -Wextra -pedantic-errors -Wno-long-long -std=c89 \
    36     37         -ansi -DSQLITE_ENABLE_STAT4 -DSQLITE_THREADSAFE=0 \
    37     38         sqlite3.c
    38         -echo '********** Optimized -O3.  Includes FTS4 and RTREE ************'
           39  +echo '********** Optimized -O3.  Includes FTS4/5, RTREE, JSON1 ******'
    39     40   gcc -O3 -c -Wshadow -Wall -Wextra -pedantic-errors -Wno-long-long -std=c89 \
    40     41         -ansi -DHAVE_STDINT_H -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_RTREE \
           42  +      -DSQLITE_ENABLE_FTS5 -DSQLITE_ENABLE_JSON1 \
    41     43         sqlite3.c